Compare commits
5 Commits
e8440bc106
...
v1.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 5461061e7e | |||
| 39e1f9e9ad | |||
| d75b8333e5 | |||
| a2097567a0 | |||
| 7386bff7be |
+1
-1
@@ -4,7 +4,7 @@
|
||||
"type": "git",
|
||||
"url": "https://gitea.auvem.com/svelte-toolkit/sui.git"
|
||||
},
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.1",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build && pnpm run prepack",
|
||||
|
||||
@@ -50,8 +50,7 @@
|
||||
const options: ComboboxOption[] = countries.map((country) => ({
|
||||
value: country.isoCode,
|
||||
label: `${country.name} (+${country.phonecode})`,
|
||||
preview: `+${country.phonecode}`,
|
||||
icon: renderIcon
|
||||
preview: `+${country.phonecode}`
|
||||
}));
|
||||
|
||||
let phonecode: string = $derived.by(() => {
|
||||
@@ -118,12 +117,6 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet renderIcon(item: ComboboxOption)}
|
||||
{#if countrycodeMap[item.value]?.flag}
|
||||
{countrycodeMap[item.value].flag}
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
<div class={classValue}>
|
||||
{#if label}
|
||||
<Label for={id}>{label}</Label>
|
||||
@@ -149,7 +142,13 @@
|
||||
countriesValid = e.detail.valid;
|
||||
}}
|
||||
invalidMessage={null}
|
||||
/>
|
||||
>
|
||||
{#snippet iconRender(opt)}
|
||||
{#if countrycodeMap[opt.value]?.flag}
|
||||
{countrycodeMap[opt.value].flag}
|
||||
{/if}
|
||||
{/snippet}
|
||||
</Combobox>
|
||||
</div>
|
||||
|
||||
<div class="w-full">
|
||||
|
||||
+9
-14
@@ -23,22 +23,17 @@
|
||||
activeIndex?: number;
|
||||
/** Callback fired when the active tab changes */
|
||||
onchange?: (event: { index: number; tab: TabPage }) => void;
|
||||
/** Applies layout padding to the tab header (default: false) */
|
||||
padHeader?: boolean;
|
||||
/** Applies layout padding to the content areas (default: false) */
|
||||
padContent?: 'padding' | 'margin' | 'none';
|
||||
/**
|
||||
* Controls padding of content areas. True applies padding to content
|
||||
* and header, false applies no padding (default), and 'content' and
|
||||
* 'header' apply padding to their respective areas only.
|
||||
*/
|
||||
padded?: boolean | 'content' | 'header';
|
||||
/** Additional classes applied to the outer container */
|
||||
class?: ClassValue | null;
|
||||
}
|
||||
|
||||
let {
|
||||
pages,
|
||||
activeIndex = 0,
|
||||
onchange,
|
||||
padHeader = false,
|
||||
padContent = 'none',
|
||||
class: classValue
|
||||
}: Props = $props();
|
||||
let { pages, activeIndex = 0, onchange, padded = false, class: classValue }: Props = $props();
|
||||
|
||||
let primaryContainerEl: HTMLDivElement;
|
||||
let tabContainerEl: HTMLDivElement;
|
||||
@@ -109,7 +104,7 @@
|
||||
bind:this={tabContainerEl}
|
||||
class={[
|
||||
'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)}
|
||||
@@ -144,7 +139,7 @@
|
||||
|
||||
{#key activeIndex}
|
||||
<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 }}
|
||||
out:flyX={{ direction: activeIndex > prevIndex ? -1 : 1, duration: 180 }}
|
||||
onoutrostart={lockHeight}
|
||||
|
||||
+30
-6
@@ -3,7 +3,8 @@
|
||||
*/
|
||||
export interface GraphError {
|
||||
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 */
|
||||
@@ -15,14 +16,22 @@ export type RawError = ErrorMessage | Error | string | GraphError[];
|
||||
* @returns true if the error is a RawError, false otherwise
|
||||
*/
|
||||
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 (
|
||||
error instanceof ErrorMessage ||
|
||||
error instanceof Error ||
|
||||
typeof error === 'string' ||
|
||||
(Array.isArray(error) &&
|
||||
error.every(
|
||||
(e) => typeof e.message === 'string' && (e.path === undefined || Array.isArray(e.path))
|
||||
))
|
||||
(Array.isArray(error) && error.every(isGraphError))
|
||||
);
|
||||
};
|
||||
|
||||
@@ -73,6 +82,21 @@ export const checkGraphResponse = (
|
||||
export class ErrorMessage {
|
||||
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.
|
||||
* @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) => {
|
||||
const messageString = e.message || 'Unknown error';
|
||||
if (e.path && e.path.length > 0) {
|
||||
return `"${messageString}" at ${e.path.join('.')}`;
|
||||
return `"${messageString}" at ${ErrorMessage.formatGraphPath(e.path)}`;
|
||||
}
|
||||
return messageString;
|
||||
});
|
||||
|
||||
@@ -448,7 +448,7 @@
|
||||
<p class="title">Tabs</p>
|
||||
|
||||
<Tabs
|
||||
padded={true}
|
||||
padded
|
||||
pages={[
|
||||
{
|
||||
title: 'Dashboard',
|
||||
|
||||
Reference in New Issue
Block a user