@r2digisolutions/components 0.6.2 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/molecules/Combobox/Combobox.stories.d.ts +6 -0
- package/dist/components/molecules/Combobox/Combobox.stories.js +5 -2
- package/dist/components/molecules/Combobox/ComboboxStory.svelte +11 -2
- package/dist/components/molecules/Combobox/ComboboxStory.svelte.d.ts +1 -0
- package/dist/components/molecules/Combobox/combobox-item.svelte.d.ts +17 -0
- package/dist/components/molecules/Combobox/combobox-item.svelte.js +57 -0
- package/dist/components/molecules/ComboboxItem/ComboboxItem.svelte +20 -35
- package/dist/components/molecules/ComboboxMenuItem/ComboboxMenuItem.stories.d.ts +9 -0
- package/dist/components/molecules/ComboboxMenuItem/ComboboxMenuItem.stories.js +8 -0
- package/dist/components/molecules/ComboboxMenuItem/ComboboxMenuItem.svelte +84 -0
- package/dist/components/molecules/ComboboxMenuItem/ComboboxMenuItem.svelte.d.ts +17 -0
- package/dist/components/molecules/ComboboxMenuItem/ComboboxMenuItemStory.svelte +42 -0
- package/dist/components/molecules/ComboboxMenuItem/ComboboxMenuItemStory.svelte.d.ts +3 -0
- package/dist/components/molecules/Dock/Dock.stories.d.ts +22 -0
- package/dist/components/molecules/Dock/Dock.stories.js +14 -0
- package/dist/components/molecules/Dock/Dock.svelte +29 -0
- package/dist/components/molecules/Dock/Dock.svelte.d.ts +10 -0
- package/dist/components/molecules/Dock/DockItem.svelte +69 -0
- package/dist/components/molecules/Dock/DockItem.svelte.d.ts +16 -0
- package/dist/components/molecules/Dock/DockStory.svelte +25 -0
- package/dist/components/molecules/Dock/DockStory.svelte.d.ts +7 -0
- package/dist/components/molecules/SpeedDial/SpeedDial.stories.d.ts +1 -1
- package/dist/components/organisms/DataGrid/DataGrid.svelte.d.ts +2 -2
- package/dist/components/organisms/FileUploader/FileUploader.svelte +160 -120
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/utils/i18n.d.ts +23 -1
- package/dist/utils/i18n.js +150 -0
- package/package.json +2 -2
|
@@ -6,6 +6,7 @@ declare const meta: {
|
|
|
6
6
|
label?: string;
|
|
7
7
|
disabled?: boolean;
|
|
8
8
|
compound?: boolean;
|
|
9
|
+
menuItems?: boolean;
|
|
9
10
|
}, {}, "">;
|
|
10
11
|
tags: string[];
|
|
11
12
|
argTypes: {
|
|
@@ -18,12 +19,16 @@ declare const meta: {
|
|
|
18
19
|
compound: {
|
|
19
20
|
control: "boolean";
|
|
20
21
|
};
|
|
22
|
+
menuItems: {
|
|
23
|
+
control: "boolean";
|
|
24
|
+
};
|
|
21
25
|
};
|
|
22
26
|
args: {
|
|
23
27
|
creatable: false;
|
|
24
28
|
label: string;
|
|
25
29
|
disabled: false;
|
|
26
30
|
compound: false;
|
|
31
|
+
menuItems: false;
|
|
27
32
|
};
|
|
28
33
|
};
|
|
29
34
|
export default meta;
|
|
@@ -32,3 +37,4 @@ export declare const Default: Story;
|
|
|
32
37
|
export declare const Creatable: Story;
|
|
33
38
|
export declare const Disabled: Story;
|
|
34
39
|
export declare const WithComboboxItem: Story;
|
|
40
|
+
export declare const WithComboboxMenuItem: Story;
|
|
@@ -6,13 +6,15 @@ const meta = {
|
|
|
6
6
|
argTypes: {
|
|
7
7
|
creatable: { control: 'boolean' },
|
|
8
8
|
disabled: { control: 'boolean' },
|
|
9
|
-
compound: { control: 'boolean' }
|
|
9
|
+
compound: { control: 'boolean' },
|
|
10
|
+
menuItems: { control: 'boolean' }
|
|
10
11
|
},
|
|
11
12
|
args: {
|
|
12
13
|
creatable: false,
|
|
13
14
|
label: 'Framework',
|
|
14
15
|
disabled: false,
|
|
15
|
-
compound: false
|
|
16
|
+
compound: false,
|
|
17
|
+
menuItems: false
|
|
16
18
|
}
|
|
17
19
|
};
|
|
18
20
|
export default meta;
|
|
@@ -20,3 +22,4 @@ export const Default = {};
|
|
|
20
22
|
export const Creatable = { args: { creatable: true } };
|
|
21
23
|
export const Disabled = { args: { disabled: true } };
|
|
22
24
|
export const WithComboboxItem = { args: { compound: true } };
|
|
25
|
+
export const WithComboboxMenuItem = { args: { menuItems: true } };
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Combobox, { type ComboboxOption } from './Combobox.svelte';
|
|
3
3
|
import ComboboxItem from '../ComboboxItem/ComboboxItem.svelte';
|
|
4
|
+
import ComboboxMenuItem from '../ComboboxMenuItem/ComboboxMenuItem.svelte';
|
|
4
5
|
|
|
5
6
|
let {
|
|
6
7
|
creatable = false,
|
|
7
8
|
label = 'Framework',
|
|
8
9
|
disabled = false,
|
|
9
|
-
compound = false
|
|
10
|
+
compound = false,
|
|
11
|
+
menuItems = false
|
|
10
12
|
}: {
|
|
11
13
|
creatable?: boolean;
|
|
12
14
|
label?: string;
|
|
13
15
|
disabled?: boolean;
|
|
14
16
|
compound?: boolean;
|
|
17
|
+
menuItems?: boolean;
|
|
15
18
|
} = $props();
|
|
16
19
|
|
|
17
20
|
const options: ComboboxOption[] = [
|
|
@@ -29,7 +32,13 @@
|
|
|
29
32
|
</script>
|
|
30
33
|
|
|
31
34
|
<div class="w-80 gap-3 flex flex-col">
|
|
32
|
-
{#if
|
|
35
|
+
{#if menuItems}
|
|
36
|
+
<Combobox {label} {disabled} bind:value bind:query bind:open placeholder="Search frameworks…">
|
|
37
|
+
{#each options as option (option.value)}
|
|
38
|
+
<ComboboxMenuItem value={option.value} label={option.label} disabled={option.disabled} />
|
|
39
|
+
{/each}
|
|
40
|
+
</Combobox>
|
|
41
|
+
{:else if compound}
|
|
33
42
|
<Combobox {label} {disabled} bind:value bind:query bind:open placeholder="Search frameworks…">
|
|
34
43
|
{#each options as option (option.value)}
|
|
35
44
|
<ComboboxItem value={option.value} label={option.label} disabled={option.disabled}>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ComboboxItemInput {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
disabled: boolean;
|
|
5
|
+
keywords: string[];
|
|
6
|
+
selected: boolean | undefined;
|
|
7
|
+
highlighted: boolean | undefined;
|
|
8
|
+
register: boolean;
|
|
9
|
+
onclick?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function createComboboxItemController(getInput: () => ComboboxItemInput): {
|
|
12
|
+
readonly matchesQuery: boolean;
|
|
13
|
+
readonly isSelected: boolean;
|
|
14
|
+
readonly isHighlighted: boolean;
|
|
15
|
+
activate: () => void;
|
|
16
|
+
highlight: () => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getComboboxContext } from './combobox-context.js';
|
|
2
|
+
export function createComboboxItemController(getInput) {
|
|
3
|
+
const ctx = getComboboxContext();
|
|
4
|
+
const matchesQuery = $derived.by(() => {
|
|
5
|
+
const input = getInput();
|
|
6
|
+
if (!input.register || !ctx)
|
|
7
|
+
return true;
|
|
8
|
+
const q = ctx.getQuery().trim().toLowerCase();
|
|
9
|
+
if (!q)
|
|
10
|
+
return true;
|
|
11
|
+
const blob = [input.label, input.value, ...input.keywords].join(' ').toLowerCase();
|
|
12
|
+
return blob.includes(q);
|
|
13
|
+
});
|
|
14
|
+
const isSelected = $derived.by(() => {
|
|
15
|
+
const input = getInput();
|
|
16
|
+
return input.selected ?? (ctx ? ctx.getValue() === input.value : false);
|
|
17
|
+
});
|
|
18
|
+
const isHighlighted = $derived.by(() => {
|
|
19
|
+
const input = getInput();
|
|
20
|
+
return input.highlighted ?? (ctx ? ctx.getHighlighted() === input.value : false);
|
|
21
|
+
});
|
|
22
|
+
$effect(() => {
|
|
23
|
+
const input = getInput();
|
|
24
|
+
if (!input.register || !ctx || input.disabled || !matchesQuery)
|
|
25
|
+
return;
|
|
26
|
+
return ctx.register(input.value, input.disabled, input.label);
|
|
27
|
+
});
|
|
28
|
+
function activate() {
|
|
29
|
+
const input = getInput();
|
|
30
|
+
if (input.disabled)
|
|
31
|
+
return;
|
|
32
|
+
if (input.onclick) {
|
|
33
|
+
input.onclick();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
ctx?.select(input.value);
|
|
37
|
+
}
|
|
38
|
+
function highlight() {
|
|
39
|
+
const input = getInput();
|
|
40
|
+
if (input.disabled)
|
|
41
|
+
return;
|
|
42
|
+
ctx?.highlight(input.value);
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
get matchesQuery() {
|
|
46
|
+
return matchesQuery;
|
|
47
|
+
},
|
|
48
|
+
get isSelected() {
|
|
49
|
+
return isSelected;
|
|
50
|
+
},
|
|
51
|
+
get isHighlighted() {
|
|
52
|
+
return isHighlighted;
|
|
53
|
+
},
|
|
54
|
+
activate,
|
|
55
|
+
highlight
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import Check from '@lucide/svelte/icons/check';
|
|
4
|
-
import {
|
|
4
|
+
import { createComboboxItemController } from '../Combobox/combobox-item.svelte.js';
|
|
5
5
|
|
|
6
6
|
interface ComboboxItemProps {
|
|
7
7
|
value: string;
|
|
@@ -49,54 +49,39 @@
|
|
|
49
49
|
onhighlight
|
|
50
50
|
}: ComboboxItemProps = $props();
|
|
51
51
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const isSelected = $derived(selected ?? (ctx ? ctx.getValue() === value : false));
|
|
63
|
-
const isHighlighted = $derived(highlighted ?? (ctx ? ctx.getHighlighted() === value : false));
|
|
64
|
-
const active = $derived(!disabled && (isHighlighted || isSelected));
|
|
65
|
-
|
|
66
|
-
$effect(() => {
|
|
67
|
-
if (!register || !ctx || disabled || !matchesQuery) return;
|
|
68
|
-
return ctx.register(value, disabled, label);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
function activate() {
|
|
72
|
-
if (disabled) return;
|
|
73
|
-
if (onclick) {
|
|
74
|
-
onclick();
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
ctx?.select(value);
|
|
78
|
-
}
|
|
52
|
+
const item = createComboboxItemController(() => ({
|
|
53
|
+
value,
|
|
54
|
+
label,
|
|
55
|
+
disabled,
|
|
56
|
+
keywords,
|
|
57
|
+
selected,
|
|
58
|
+
highlighted,
|
|
59
|
+
register,
|
|
60
|
+
onclick
|
|
61
|
+
}));
|
|
79
62
|
</script>
|
|
80
63
|
|
|
81
|
-
{#if matchesQuery}
|
|
64
|
+
{#if item.matchesQuery}
|
|
82
65
|
<button
|
|
83
66
|
type="button"
|
|
84
67
|
role="option"
|
|
85
68
|
data-value={value}
|
|
86
69
|
{disabled}
|
|
87
|
-
aria-selected={isSelected}
|
|
70
|
+
aria-selected={item.isSelected}
|
|
88
71
|
aria-disabled={disabled}
|
|
89
72
|
onpointerenter={() => {
|
|
90
|
-
if (disabled) return;
|
|
91
73
|
onhighlight?.();
|
|
92
|
-
|
|
74
|
+
item.highlight();
|
|
93
75
|
}}
|
|
94
|
-
onclick={activate}
|
|
76
|
+
onclick={item.activate}
|
|
95
77
|
class={[
|
|
96
78
|
'gap-2 rounded-lg px-2.5 py-2 text-sm flex w-full items-center text-left transition-colors',
|
|
97
79
|
'focus-visible:ring-brand-500/30 focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset',
|
|
98
80
|
disabled && 'cursor-not-allowed opacity-40',
|
|
99
|
-
!disabled &&
|
|
81
|
+
!disabled &&
|
|
82
|
+
(item.isHighlighted || item.isSelected
|
|
83
|
+
? 'bg-brand-500 text-white'
|
|
84
|
+
: 'text-primary hover:bg-surface-overlay'),
|
|
100
85
|
className
|
|
101
86
|
]}
|
|
102
87
|
>
|
|
@@ -114,7 +99,7 @@
|
|
|
114
99
|
|
|
115
100
|
{#if trailing}
|
|
116
101
|
<span class="flex shrink-0 items-center">{@render trailing()}</span>
|
|
117
|
-
{:else if isSelected}
|
|
102
|
+
{:else if item.isSelected}
|
|
118
103
|
<Check class="h-4 w-4 shrink-0" strokeWidth={2.5} />
|
|
119
104
|
{/if}
|
|
120
105
|
</button>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/svelte';
|
|
2
|
+
declare const meta: {
|
|
3
|
+
title: string;
|
|
4
|
+
component: import("svelte").Component<Record<string, never>, {}, "">;
|
|
5
|
+
tags: string[];
|
|
6
|
+
};
|
|
7
|
+
export default meta;
|
|
8
|
+
type Story = StoryObj<typeof meta>;
|
|
9
|
+
export declare const Default: Story;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import Check from '@lucide/svelte/icons/check';
|
|
4
|
+
import { createComboboxItemController } from '../Combobox/combobox-item.svelte.js';
|
|
5
|
+
|
|
6
|
+
interface ComboboxMenuItemProps {
|
|
7
|
+
value: string;
|
|
8
|
+
label?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
keywords?: string[];
|
|
11
|
+
selected?: boolean;
|
|
12
|
+
highlighted?: boolean;
|
|
13
|
+
register?: boolean;
|
|
14
|
+
class?: string;
|
|
15
|
+
children?: Snippet;
|
|
16
|
+
onclick?: () => void;
|
|
17
|
+
onhighlight?: () => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let {
|
|
21
|
+
value,
|
|
22
|
+
label = '',
|
|
23
|
+
disabled = false,
|
|
24
|
+
keywords = [],
|
|
25
|
+
selected,
|
|
26
|
+
highlighted,
|
|
27
|
+
register = true,
|
|
28
|
+
class: className = '',
|
|
29
|
+
children,
|
|
30
|
+
onclick,
|
|
31
|
+
onhighlight
|
|
32
|
+
}: ComboboxMenuItemProps = $props();
|
|
33
|
+
|
|
34
|
+
const item = createComboboxItemController(() => ({
|
|
35
|
+
value,
|
|
36
|
+
label,
|
|
37
|
+
disabled,
|
|
38
|
+
keywords,
|
|
39
|
+
selected,
|
|
40
|
+
highlighted,
|
|
41
|
+
register,
|
|
42
|
+
onclick
|
|
43
|
+
}));
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
{#if item.matchesQuery}
|
|
47
|
+
<button
|
|
48
|
+
type="button"
|
|
49
|
+
role="option"
|
|
50
|
+
data-value={value}
|
|
51
|
+
{disabled}
|
|
52
|
+
aria-selected={item.isSelected}
|
|
53
|
+
aria-disabled={disabled}
|
|
54
|
+
onpointerenter={() => {
|
|
55
|
+
onhighlight?.();
|
|
56
|
+
item.highlight();
|
|
57
|
+
}}
|
|
58
|
+
onclick={item.activate}
|
|
59
|
+
class={[
|
|
60
|
+
'rounded-lg py-1.5 pr-2 pl-8 text-sm relative flex w-full cursor-default items-center text-left outline-none select-none',
|
|
61
|
+
'focus-visible:ring-brand-500/30 transition-colors focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset',
|
|
62
|
+
disabled && 'cursor-not-allowed opacity-40',
|
|
63
|
+
!disabled && item.isHighlighted && 'bg-surface-overlay',
|
|
64
|
+
!disabled && !item.isHighlighted && 'hover:bg-surface-overlay',
|
|
65
|
+
!disabled && item.isSelected && 'font-medium text-brand-600 dark:text-brand-400',
|
|
66
|
+
!disabled && !item.isSelected && 'text-primary',
|
|
67
|
+
className
|
|
68
|
+
]}
|
|
69
|
+
>
|
|
70
|
+
<span class="left-2 h-3.5 w-3.5 absolute flex items-center justify-center" aria-hidden="true">
|
|
71
|
+
{#if item.isSelected}
|
|
72
|
+
<Check class="h-3.5 w-3.5" strokeWidth={2.5} />
|
|
73
|
+
{/if}
|
|
74
|
+
</span>
|
|
75
|
+
|
|
76
|
+
<span class={['min-w-0 flex-1', !children && 'truncate']}>
|
|
77
|
+
{#if children}
|
|
78
|
+
{@render children()}
|
|
79
|
+
{:else}
|
|
80
|
+
{label || value}
|
|
81
|
+
{/if}
|
|
82
|
+
</span>
|
|
83
|
+
</button>
|
|
84
|
+
{/if}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface ComboboxMenuItemProps {
|
|
3
|
+
value: string;
|
|
4
|
+
label?: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
keywords?: string[];
|
|
7
|
+
selected?: boolean;
|
|
8
|
+
highlighted?: boolean;
|
|
9
|
+
register?: boolean;
|
|
10
|
+
class?: string;
|
|
11
|
+
children?: Snippet;
|
|
12
|
+
onclick?: () => void;
|
|
13
|
+
onhighlight?: () => void;
|
|
14
|
+
}
|
|
15
|
+
declare const ComboboxMenuItem: import("svelte").Component<ComboboxMenuItemProps, {}, "">;
|
|
16
|
+
type ComboboxMenuItem = ReturnType<typeof ComboboxMenuItem>;
|
|
17
|
+
export default ComboboxMenuItem;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ComboboxMenuItem from './ComboboxMenuItem.svelte';
|
|
3
|
+
|
|
4
|
+
let selected = $state('svelte');
|
|
5
|
+
let highlighted = $state('svelte');
|
|
6
|
+
|
|
7
|
+
const frameworks = [
|
|
8
|
+
{ value: 'svelte', label: 'Svelte' },
|
|
9
|
+
{ value: 'react', label: 'React' },
|
|
10
|
+
{ value: 'vue', label: 'Vue' },
|
|
11
|
+
{ value: 'solid', label: 'Solid' },
|
|
12
|
+
{ value: 'qwik', label: 'Qwik', disabled: true }
|
|
13
|
+
];
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<div class="max-w-sm space-y-3 w-full">
|
|
17
|
+
<div class="space-y-1">
|
|
18
|
+
<p class="text-sm font-semibold text-primary">ComboboxMenuItem</p>
|
|
19
|
+
<p class="text-xs text-secondary">
|
|
20
|
+
Fila compacta con check a la izquierda, como el combobox de selección. No pinta el fondo
|
|
21
|
+
brand.
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="rounded-xl border-border bg-surface-elevated p-1 shadow-sm border">
|
|
26
|
+
{#each frameworks as fw (fw.value)}
|
|
27
|
+
<ComboboxMenuItem
|
|
28
|
+
value={fw.value}
|
|
29
|
+
label={fw.label}
|
|
30
|
+
disabled={fw.disabled}
|
|
31
|
+
selected={selected === fw.value}
|
|
32
|
+
highlighted={highlighted === fw.value}
|
|
33
|
+
onclick={() => (selected = fw.value)}
|
|
34
|
+
onhighlight={() => (highlighted = fw.value)}
|
|
35
|
+
/>
|
|
36
|
+
{/each}
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<p class="text-xs text-muted">
|
|
40
|
+
Value: <span class="text-primary">{selected}</span>
|
|
41
|
+
</p>
|
|
42
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/svelte';
|
|
2
|
+
declare const meta: {
|
|
3
|
+
title: string;
|
|
4
|
+
component: import("svelte").Component<{
|
|
5
|
+
size?: import("./Dock.svelte.ts").DockSize;
|
|
6
|
+
}, {}, "">;
|
|
7
|
+
tags: string[];
|
|
8
|
+
argTypes: {
|
|
9
|
+
size: {
|
|
10
|
+
control: "select";
|
|
11
|
+
options: string[];
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
args: {
|
|
15
|
+
size: "sm";
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof meta>;
|
|
20
|
+
export declare const Default: Story;
|
|
21
|
+
export declare const Mini: Story;
|
|
22
|
+
export declare const Medium: Story;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import DockStory from './DockStory.svelte';
|
|
2
|
+
const meta = {
|
|
3
|
+
title: 'Molecules/Dock',
|
|
4
|
+
component: DockStory,
|
|
5
|
+
tags: ['autodocs'],
|
|
6
|
+
argTypes: {
|
|
7
|
+
size: { control: 'select', options: ['mini', 'sm', 'md'] }
|
|
8
|
+
},
|
|
9
|
+
args: { size: 'sm' }
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
export const Default = {};
|
|
13
|
+
export const Mini = { args: { size: 'mini' } };
|
|
14
|
+
export const Medium = { args: { size: 'md' } };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
export type DockSize = 'mini' | 'sm' | 'md';
|
|
5
|
+
|
|
6
|
+
interface DockProps {
|
|
7
|
+
size?: DockSize;
|
|
8
|
+
class?: string;
|
|
9
|
+
children?: Snippet;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { size = 'mini', class: className = '', children }: DockProps = $props();
|
|
13
|
+
|
|
14
|
+
const sizes: Record<DockSize, string> = {
|
|
15
|
+
mini: 'rounded-full p-0.5',
|
|
16
|
+
sm: 'rounded-full p-0.5',
|
|
17
|
+
md: 'rounded-2xl p-1'
|
|
18
|
+
};
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<div
|
|
22
|
+
class={[
|
|
23
|
+
'border-border/70 bg-surface-overlay/80 shadow-sm backdrop-blur-md isolate inline-flex items-center overflow-hidden border',
|
|
24
|
+
sizes[size],
|
|
25
|
+
className
|
|
26
|
+
]}
|
|
27
|
+
>
|
|
28
|
+
{@render children?.()}
|
|
29
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export type DockSize = 'mini' | 'sm' | 'md';
|
|
3
|
+
interface DockProps {
|
|
4
|
+
size?: DockSize;
|
|
5
|
+
class?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const Dock: import("svelte").Component<DockProps, {}, "">;
|
|
9
|
+
type Dock = ReturnType<typeof Dock>;
|
|
10
|
+
export default Dock;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { DockSize } from './Dock.svelte';
|
|
4
|
+
|
|
5
|
+
interface DockItemProps {
|
|
6
|
+
as?: 'button' | 'a';
|
|
7
|
+
href?: string;
|
|
8
|
+
onclick?: (e: MouseEvent) => void;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
active?: boolean;
|
|
11
|
+
size?: DockSize;
|
|
12
|
+
ariaLabel?: string;
|
|
13
|
+
class?: string;
|
|
14
|
+
children?: Snippet;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
as = 'button',
|
|
19
|
+
href,
|
|
20
|
+
onclick,
|
|
21
|
+
disabled = false,
|
|
22
|
+
active = false,
|
|
23
|
+
size = 'mini',
|
|
24
|
+
ariaLabel,
|
|
25
|
+
class: className = '',
|
|
26
|
+
children
|
|
27
|
+
}: DockItemProps = $props();
|
|
28
|
+
|
|
29
|
+
const sizes: Record<DockSize, string> = {
|
|
30
|
+
mini: 'h-7 px-2 text-[11px]',
|
|
31
|
+
sm: 'h-8 px-2.5 text-xs',
|
|
32
|
+
md: 'h-9 px-3 text-sm'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const classes = $derived([
|
|
36
|
+
'relative inline-flex items-center justify-center gap-1.5 whitespace-nowrap select-none font-medium transition-all duration-150',
|
|
37
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500/30',
|
|
38
|
+
sizes[size],
|
|
39
|
+
active
|
|
40
|
+
? 'bg-surface-elevated text-primary shadow-sm ring-1 ring-border'
|
|
41
|
+
: 'text-secondary hover:bg-surface-elevated/70 hover:text-primary',
|
|
42
|
+
disabled ? 'pointer-events-none opacity-50' : 'cursor-pointer',
|
|
43
|
+
'[&[data-active]:first-child]:rounded-l-full',
|
|
44
|
+
'[&[data-active]:last-child]:rounded-r-full',
|
|
45
|
+
'[&[data-active]:not(:first-child):not(:last-child)]:rounded-none',
|
|
46
|
+
'[&:not([data-active]):first-child:hover]:rounded-l-full',
|
|
47
|
+
'[&:not([data-active]):last-child:hover]:rounded-r-full',
|
|
48
|
+
'[&:not([data-active]):not(:first-child):not(:last-child):hover]:rounded-none',
|
|
49
|
+
className
|
|
50
|
+
]);
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
{#if as === 'a' || href}
|
|
54
|
+
<a {href} aria-label={ariaLabel} data-active={active || undefined} class={classes}>
|
|
55
|
+
{@render children?.()}
|
|
56
|
+
</a>
|
|
57
|
+
{:else}
|
|
58
|
+
<button
|
|
59
|
+
type="button"
|
|
60
|
+
{disabled}
|
|
61
|
+
aria-label={ariaLabel}
|
|
62
|
+
aria-pressed={active}
|
|
63
|
+
data-active={active || undefined}
|
|
64
|
+
{onclick}
|
|
65
|
+
class={classes}
|
|
66
|
+
>
|
|
67
|
+
{@render children?.()}
|
|
68
|
+
</button>
|
|
69
|
+
{/if}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { DockSize } from './Dock.svelte';
|
|
3
|
+
interface DockItemProps {
|
|
4
|
+
as?: 'button' | 'a';
|
|
5
|
+
href?: string;
|
|
6
|
+
onclick?: (e: MouseEvent) => void;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
active?: boolean;
|
|
9
|
+
size?: DockSize;
|
|
10
|
+
ariaLabel?: string;
|
|
11
|
+
class?: string;
|
|
12
|
+
children?: Snippet;
|
|
13
|
+
}
|
|
14
|
+
declare const DockItem: import("svelte").Component<DockItemProps, {}, "">;
|
|
15
|
+
type DockItem = ReturnType<typeof DockItem>;
|
|
16
|
+
export default DockItem;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Dock from './Dock.svelte';
|
|
3
|
+
import DockItem from './DockItem.svelte';
|
|
4
|
+
import type { DockSize } from './Dock.svelte';
|
|
5
|
+
|
|
6
|
+
let { size = 'sm' }: { size?: DockSize } = $props();
|
|
7
|
+
|
|
8
|
+
let value = $state('es');
|
|
9
|
+
const langs = ['es', 'en', 'ca', 'fr', 'de'];
|
|
10
|
+
const filled = new Set(['es', 'en']);
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<div class="gap-4 flex flex-col">
|
|
14
|
+
<Dock {size}>
|
|
15
|
+
{#each langs as lang (lang)}
|
|
16
|
+
<DockItem {size} active={value === lang} onclick={() => (value = lang)}>
|
|
17
|
+
{lang.toUpperCase()}
|
|
18
|
+
{#if filled.has(lang)}
|
|
19
|
+
<span class="h-1.5 w-1.5 bg-emerald-500 rounded-full" aria-hidden="true"></span>
|
|
20
|
+
{/if}
|
|
21
|
+
</DockItem>
|
|
22
|
+
{/each}
|
|
23
|
+
</Dock>
|
|
24
|
+
<p class="text-xs text-muted">Selected: {value.toUpperCase()}</p>
|
|
25
|
+
</div>
|
|
@@ -2,7 +2,7 @@ import type { StoryObj } from '@storybook/svelte';
|
|
|
2
2
|
declare const meta: {
|
|
3
3
|
title: string;
|
|
4
4
|
component: import("svelte").Component<{
|
|
5
|
-
example?: "destructive" | "
|
|
5
|
+
example?: "destructive" | "media" | "toolbar" | "compose";
|
|
6
6
|
position?: import("./SpeedDial.svelte.ts").SpeedDialPosition;
|
|
7
7
|
direction?: import("./SpeedDial.svelte.ts").SpeedDialDirection;
|
|
8
8
|
variant?: import("./SpeedDial.svelte.ts").SpeedDialVariant;
|
|
@@ -77,7 +77,7 @@ declare function $$render<T extends Record<string, unknown> = Record<string, unk
|
|
|
77
77
|
onrowdblclick?: (row: T) => void;
|
|
78
78
|
};
|
|
79
79
|
exports: {};
|
|
80
|
-
bindings: "notes" | "selection" | "marks" | "formatRules" | "filterQuery" | "columnFilters" | "expandedRows"
|
|
80
|
+
bindings: "viewMode" | "notes" | "selection" | "marks" | "formatRules" | "filterQuery" | "columnFilters" | "expandedRows";
|
|
81
81
|
slots: {};
|
|
82
82
|
events: {};
|
|
83
83
|
};
|
|
@@ -85,7 +85,7 @@ declare class __sveltets_Render<T extends Record<string, unknown> = Record<strin
|
|
|
85
85
|
props(): ReturnType<typeof $$render<T>>['props'];
|
|
86
86
|
events(): ReturnType<typeof $$render<T>>['events'];
|
|
87
87
|
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
88
|
-
bindings(): "notes" | "selection" | "marks" | "formatRules" | "filterQuery" | "columnFilters" | "expandedRows"
|
|
88
|
+
bindings(): "viewMode" | "notes" | "selection" | "marks" | "formatRules" | "filterQuery" | "columnFilters" | "expandedRows";
|
|
89
89
|
exports(): {};
|
|
90
90
|
}
|
|
91
91
|
interface $$IsomorphicComponent {
|