Compare commits
5 Commits
e8440bc106
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5461061e7e | |||
| 39e1f9e9ad | |||
| d75b8333e5 | |||
| a2097567a0 | |||
| 7386bff7be |
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitea.auvem.com/svelte-toolkit/sui.git"
|
"url": "https://gitea.auvem.com/svelte-toolkit/sui.git"
|
||||||
},
|
},
|
||||||
"version": "1.2.0",
|
"version": "1.3.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
"build": "vite build && pnpm run prepack",
|
"build": "vite build && pnpm run prepack",
|
||||||
|
|||||||
@@ -50,8 +50,7 @@
|
|||||||
const options: ComboboxOption[] = countries.map((country) => ({
|
const options: ComboboxOption[] = countries.map((country) => ({
|
||||||
value: country.isoCode,
|
value: country.isoCode,
|
||||||
label: `${country.name} (+${country.phonecode})`,
|
label: `${country.name} (+${country.phonecode})`,
|
||||||
preview: `+${country.phonecode}`,
|
preview: `+${country.phonecode}`
|
||||||
icon: renderIcon
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let phonecode: string = $derived.by(() => {
|
let phonecode: string = $derived.by(() => {
|
||||||
@@ -118,12 +117,6 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet renderIcon(item: ComboboxOption)}
|
|
||||||
{#if countrycodeMap[item.value]?.flag}
|
|
||||||
{countrycodeMap[item.value].flag}
|
|
||||||
{/if}
|
|
||||||
{/snippet}
|
|
||||||
|
|
||||||
<div class={classValue}>
|
<div class={classValue}>
|
||||||
{#if label}
|
{#if label}
|
||||||
<Label for={id}>{label}</Label>
|
<Label for={id}>{label}</Label>
|
||||||
@@ -149,7 +142,13 @@
|
|||||||
countriesValid = e.detail.valid;
|
countriesValid = e.detail.valid;
|
||||||
}}
|
}}
|
||||||
invalidMessage={null}
|
invalidMessage={null}
|
||||||
/>
|
>
|
||||||
|
{#snippet iconRender(opt)}
|
||||||
|
{#if countrycodeMap[opt.value]?.flag}
|
||||||
|
{countrycodeMap[opt.value].flag}
|
||||||
|
{/if}
|
||||||
|
{/snippet}
|
||||||
|
</Combobox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
|
|||||||
+9
-14
@@ -23,22 +23,17 @@
|
|||||||
activeIndex?: number;
|
activeIndex?: number;
|
||||||
/** Callback fired when the active tab changes */
|
/** Callback fired when the active tab changes */
|
||||||
onchange?: (event: { index: number; tab: TabPage }) => void;
|
onchange?: (event: { index: number; tab: TabPage }) => void;
|
||||||
/** Applies layout padding to the tab header (default: false) */
|
/**
|
||||||
padHeader?: boolean;
|
* Controls padding of content areas. True applies padding to content
|
||||||
/** Applies layout padding to the content areas (default: false) */
|
* and header, false applies no padding (default), and 'content' and
|
||||||
padContent?: 'padding' | 'margin' | 'none';
|
* 'header' apply padding to their respective areas only.
|
||||||
|
*/
|
||||||
|
padded?: boolean | 'content' | 'header';
|
||||||
/** Additional classes applied to the outer container */
|
/** Additional classes applied to the outer container */
|
||||||
class?: ClassValue | null;
|
class?: ClassValue | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let { pages, activeIndex = 0, onchange, padded = false, class: classValue }: Props = $props();
|
||||||
pages,
|
|
||||||
activeIndex = 0,
|
|
||||||
onchange,
|
|
||||||
padHeader = false,
|
|
||||||
padContent = 'none',
|
|
||||||
class: classValue
|
|
||||||
}: Props = $props();
|
|
||||||
|
|
||||||
let primaryContainerEl: HTMLDivElement;
|
let primaryContainerEl: HTMLDivElement;
|
||||||
let tabContainerEl: HTMLDivElement;
|
let tabContainerEl: HTMLDivElement;
|
||||||
@@ -109,7 +104,7 @@
|
|||||||
bind:this={tabContainerEl}
|
bind:this={tabContainerEl}
|
||||||
class={[
|
class={[
|
||||||
'border-sui-text/15 relative mb-4 flex items-center gap-5 border-b-2',
|
'border-sui-text/15 relative mb-4 flex items-center gap-5 border-b-2',
|
||||||
padHeader && 'px-layout'
|
padded === true || padded === 'header' ? 'px-layout' : ''
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{#each pages as page, i (page.title)}
|
{#each pages as page, i (page.title)}
|
||||||
@@ -144,7 +139,7 @@
|
|||||||
|
|
||||||
{#key activeIndex}
|
{#key activeIndex}
|
||||||
<div
|
<div
|
||||||
class={[padContent === 'padding' && 'px-layout', padContent === 'margin' && 'mx-layout']}
|
class={[padded === true || padded === 'content' ? 'px-layout' : '']}
|
||||||
in:flyX={{ direction: activeIndex > prevIndex ? 1 : -1, duration: 180, delay: 181 }}
|
in:flyX={{ direction: activeIndex > prevIndex ? 1 : -1, duration: 180, delay: 181 }}
|
||||||
out:flyX={{ direction: activeIndex > prevIndex ? -1 : 1, duration: 180 }}
|
out:flyX={{ direction: activeIndex > prevIndex ? -1 : 1, duration: 180 }}
|
||||||
onoutrostart={lockHeight}
|
onoutrostart={lockHeight}
|
||||||
|
|||||||
+30
-6
@@ -3,7 +3,8 @@
|
|||||||
*/
|
*/
|
||||||
export interface GraphError {
|
export interface GraphError {
|
||||||
message: string;
|
message: string;
|
||||||
path?: string[];
|
/** GraphQL response path - field names and list indexes. */
|
||||||
|
path?: ReadonlyArray<string | number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** RawError is an error that can be converted to a string by ErrorMessage */
|
/** RawError is an error that can be converted to a string by ErrorMessage */
|
||||||
@@ -15,14 +16,22 @@ export type RawError = ErrorMessage | Error | string | GraphError[];
|
|||||||
* @returns true if the error is a RawError, false otherwise
|
* @returns true if the error is a RawError, false otherwise
|
||||||
*/
|
*/
|
||||||
export const isRawError = (error: unknown): error is RawError => {
|
export const isRawError = (error: unknown): error is RawError => {
|
||||||
|
const isGraphError = (entry: unknown): entry is GraphError => {
|
||||||
|
if (!entry || typeof entry !== 'object') return false;
|
||||||
|
const candidate = entry as { message?: unknown; path?: unknown };
|
||||||
|
if (typeof candidate.message !== 'string') return false;
|
||||||
|
if (candidate.path === undefined) return true;
|
||||||
|
return (
|
||||||
|
Array.isArray(candidate.path) &&
|
||||||
|
candidate.path.every((p) => typeof p === 'string' || typeof p === 'number')
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
error instanceof ErrorMessage ||
|
error instanceof ErrorMessage ||
|
||||||
error instanceof Error ||
|
error instanceof Error ||
|
||||||
typeof error === 'string' ||
|
typeof error === 'string' ||
|
||||||
(Array.isArray(error) &&
|
(Array.isArray(error) && error.every(isGraphError))
|
||||||
error.every(
|
|
||||||
(e) => typeof e.message === 'string' && (e.path === undefined || Array.isArray(e.path))
|
|
||||||
))
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,6 +82,21 @@ export const checkGraphResponse = (
|
|||||||
export class ErrorMessage {
|
export class ErrorMessage {
|
||||||
private _lines: string[] = [];
|
private _lines: string[] = [];
|
||||||
|
|
||||||
|
/** formats a GraphQL path using dot notation for fields and brackets for indexes */
|
||||||
|
private static formatGraphPath(path: ReadonlyArray<string | number>): string {
|
||||||
|
let formatted = '';
|
||||||
|
for (const segment of path) {
|
||||||
|
if (typeof segment === 'number') {
|
||||||
|
formatted += `[${segment}]`;
|
||||||
|
} else if (formatted.length === 0) {
|
||||||
|
formatted = segment;
|
||||||
|
} else {
|
||||||
|
formatted += `.${segment}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formatted;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always creates a new ErrorMessage instance, even if there are no errors.
|
* Always creates a new ErrorMessage instance, even if there are no errors.
|
||||||
* @param errors The raw errors to convert and store, or null/undefined for no error.
|
* @param errors The raw errors to convert and store, or null/undefined for no error.
|
||||||
@@ -136,7 +160,7 @@ export class ErrorMessage {
|
|||||||
errorLines = raw.map((e) => {
|
errorLines = raw.map((e) => {
|
||||||
const messageString = e.message || 'Unknown error';
|
const messageString = e.message || 'Unknown error';
|
||||||
if (e.path && e.path.length > 0) {
|
if (e.path && e.path.length > 0) {
|
||||||
return `"${messageString}" at ${e.path.join('.')}`;
|
return `"${messageString}" at ${ErrorMessage.formatGraphPath(e.path)}`;
|
||||||
}
|
}
|
||||||
return messageString;
|
return messageString;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -448,7 +448,7 @@
|
|||||||
<p class="title">Tabs</p>
|
<p class="title">Tabs</p>
|
||||||
|
|
||||||
<Tabs
|
<Tabs
|
||||||
padded={true}
|
padded
|
||||||
pages={[
|
pages={[
|
||||||
{
|
{
|
||||||
title: 'Dashboard',
|
title: 'Dashboard',
|
||||||
|
|||||||
Reference in New Issue
Block a user