@x33025/sveltely 0.1.1 → 0.1.3
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/Library/AnimatedNumber/AnimatedNumber.demo.svelte +1 -1
- package/dist/components/Library/AsyncButton/AsyncButton.svelte +42 -16
- package/dist/components/Library/Button/Button.demo.svelte +5 -3
- package/dist/components/Library/Button/Button.demo.svelte.d.ts +1 -0
- package/dist/components/Library/Button/Button.svelte +21 -13
- package/dist/components/Library/Calendar/Calendar.demo.svelte +2 -14
- package/dist/components/Library/Calendar/Calendar.svelte +69 -65
- package/dist/components/Library/Checkbox/Checkbox.svelte +13 -14
- package/dist/components/Library/ChipInput/ChipInput.demo.svelte +1 -1
- package/dist/components/Library/ChipInput/ChipInput.svelte +7 -4
- package/dist/components/Library/Divider/Divider.svelte +10 -0
- package/dist/components/Library/Divider/Divider.svelte.d.ts +26 -0
- package/dist/components/Library/Divider/index.d.ts +1 -0
- package/dist/components/Library/Divider/index.js +1 -0
- package/dist/components/Library/Dropdown/Action.svelte +60 -0
- package/dist/components/Library/Dropdown/Action.svelte.d.ts +11 -0
- package/dist/components/Library/Dropdown/Divider.svelte +5 -0
- package/dist/components/Library/Dropdown/Divider.svelte.d.ts +19 -0
- package/dist/components/Library/Dropdown/Dropdown.demo.svelte +182 -65
- package/dist/components/Library/Dropdown/Dropdown.demo.svelte.d.ts +2 -1
- package/dist/components/Library/Dropdown/Dropdown.svelte +95 -250
- package/dist/components/Library/Dropdown/Dropdown.svelte.d.ts +17 -16
- package/dist/components/Library/Dropdown/Item.svelte +68 -0
- package/dist/components/Library/Dropdown/Item.svelte.d.ts +31 -0
- package/dist/components/Library/Dropdown/Section.svelte +34 -0
- package/dist/components/Library/Dropdown/Section.svelte.d.ts +8 -0
- package/dist/components/Library/Dropdown/context.d.ts +34 -0
- package/dist/components/Library/Dropdown/context.js +6 -0
- package/dist/components/Library/Dropdown/index.d.ts +13 -2
- package/dist/components/Library/Dropdown/index.js +11 -1
- package/dist/components/Library/Floating/Floating.svelte +44 -7
- package/dist/components/Library/ForEach/ForEach.svelte +14 -0
- package/dist/components/Library/ForEach/ForEach.svelte.d.ts +28 -0
- package/dist/components/Library/ForEach/index.d.ts +1 -0
- package/dist/components/Library/ForEach/index.js +1 -0
- package/dist/components/Library/Grid/Grid.svelte +74 -0
- package/dist/components/Library/Grid/Grid.svelte.d.ts +13 -0
- package/dist/components/Library/Grid/index.d.ts +1 -0
- package/dist/components/Library/Grid/index.js +1 -0
- package/dist/components/Library/GridItem/GridItem.svelte +65 -0
- package/dist/components/Library/GridItem/GridItem.svelte.d.ts +14 -0
- package/dist/components/Library/GridItem/index.d.ts +1 -0
- package/dist/components/Library/GridItem/index.js +1 -0
- package/dist/components/Library/HStack/HStack.svelte +45 -0
- package/dist/components/Library/HStack/HStack.svelte.d.ts +9 -0
- package/dist/components/Library/HStack/index.d.ts +1 -0
- package/dist/components/Library/HStack/index.js +1 -0
- package/dist/components/Library/Image/Image.demo.svelte +18 -0
- package/dist/components/Library/Image/Image.demo.svelte.d.ts +23 -0
- package/dist/components/Library/Image/Image.svelte +57 -0
- package/dist/components/Library/Image/Image.svelte.d.ts +17 -0
- package/dist/components/Library/Image/ImagePlaceholder.svelte +202 -0
- package/dist/components/Library/Image/ImagePlaceholder.svelte.d.ts +7 -0
- package/dist/components/Library/Image/index.d.ts +1 -0
- package/dist/components/Library/Image/index.js +1 -0
- package/dist/components/Library/ImageMask/BrushPreview.svelte +119 -0
- package/dist/components/Library/ImageMask/BrushPreview.svelte.d.ts +11 -0
- package/dist/components/Library/ImageMask/ImageMask.demo.svelte +117 -0
- package/dist/components/Library/ImageMask/ImageMask.demo.svelte.d.ts +10 -0
- package/dist/components/Library/ImageMask/ImageMask.svelte +46 -0
- package/dist/components/Library/ImageMask/ImageMask.svelte.d.ts +20 -0
- package/dist/components/Library/ImageMask/MaskLayer.svelte +341 -0
- package/dist/components/Library/ImageMask/MaskLayer.svelte.d.ts +12 -0
- package/dist/components/Library/ImageMask/contour.d.ts +11 -0
- package/dist/components/Library/ImageMask/contour.js +152 -0
- package/dist/components/Library/ImageMask/index.d.ts +2 -0
- package/dist/components/Library/ImageMask/index.js +1 -0
- package/dist/components/Library/ImageMask/marchingAnts.d.ts +8 -0
- package/dist/components/Library/ImageMask/marchingAnts.js +29 -0
- package/dist/components/Library/ImageMask/maskSurface.d.ts +5 -0
- package/dist/components/Library/ImageMask/maskSurface.js +94 -0
- package/dist/components/Library/ImageMask/types.d.ts +23 -0
- package/dist/components/Library/Label/Label.demo.svelte +28 -0
- package/dist/components/Library/Label/Label.demo.svelte.d.ts +9 -0
- package/dist/components/Library/Label/Label.svelte +175 -0
- package/dist/components/Library/Label/Label.svelte.d.ts +18 -0
- package/dist/components/Library/Label/index.d.ts +1 -0
- package/dist/components/Library/Label/index.js +1 -0
- package/dist/components/Library/NavigationStack/NavigationStack.svelte +17 -7
- package/dist/components/Library/NavigationStack/Toolbar.svelte +7 -2
- package/dist/components/Library/NumberField/NumberField.demo.svelte +21 -0
- package/dist/components/Library/NumberField/NumberField.demo.svelte.d.ts +8 -0
- package/dist/components/Library/NumberField/NumberField.svelte +199 -0
- package/dist/components/Library/NumberField/NumberField.svelte.d.ts +21 -0
- package/dist/components/Library/NumberField/index.d.ts +1 -0
- package/dist/components/Library/NumberField/index.js +1 -0
- package/dist/components/Library/Pagination/Pagination.svelte +16 -20
- package/dist/components/Library/Popover/Popover.demo.svelte +2 -2
- package/dist/components/Library/Popover/Popover.svelte +7 -4
- package/dist/components/Library/ScrollView/ScrollView.svelte +165 -12
- package/dist/components/Library/ScrollView/ScrollView.svelte.d.ts +32 -4
- package/dist/components/Library/ScrollView/index.d.ts +1 -0
- package/dist/components/Library/{SearchInput/SearchInput.demo.svelte → SearchField/SearchField.demo.svelte} +4 -4
- package/dist/components/Library/SearchField/SearchField.demo.svelte.d.ts +8 -0
- package/dist/components/Library/{SearchInput/SearchInput.svelte → SearchField/SearchField.svelte} +26 -30
- package/dist/components/Library/{SearchInput/SearchInput.svelte.d.ts → SearchField/SearchField.svelte.d.ts} +3 -3
- package/dist/components/Library/SearchField/index.d.ts +1 -0
- package/dist/components/Library/SearchField/index.js +1 -0
- package/dist/components/Library/SegmentedPicker/SegmentedPicker.demo.svelte +1 -1
- package/dist/components/Library/SegmentedPicker/SegmentedPicker.svelte +9 -9
- package/dist/components/Library/Sheet/Sheet.demo.svelte +1 -1
- package/dist/components/Library/Sheet/Sheet.svelte +8 -5
- package/dist/components/Library/Slider/Slider.demo.svelte +1 -1
- package/dist/components/Library/Slider/Slider.svelte +11 -10
- package/dist/components/Library/Spacer/Spacer.svelte +7 -0
- package/dist/components/Library/Spacer/Spacer.svelte.d.ts +26 -0
- package/dist/components/Library/Spacer/index.d.ts +1 -0
- package/dist/components/Library/Spacer/index.js +1 -0
- package/dist/components/Library/Spinner/Spinner.demo.svelte +1 -1
- package/dist/components/Library/Switch/Switch.svelte +6 -11
- package/dist/components/Library/TextField/TextField.demo.svelte +14 -0
- package/dist/components/Library/TextField/TextField.demo.svelte.d.ts +8 -0
- package/dist/components/Library/TextField/TextField.svelte +154 -0
- package/dist/components/Library/TextField/TextField.svelte.d.ts +19 -0
- package/dist/components/Library/TextField/index.d.ts +1 -0
- package/dist/components/Library/TextField/index.js +1 -0
- package/dist/components/Library/{TokenSearchInput/TokenSearchInput.demo.svelte → TokenSearchField/TokenSearchField.demo.svelte} +4 -4
- package/dist/components/Library/TokenSearchField/TokenSearchField.demo.svelte.d.ts +9 -0
- package/dist/components/Library/{TokenSearchInput/TokenSearchInput.svelte → TokenSearchField/TokenSearchField.svelte} +70 -66
- package/dist/components/Library/{TokenSearchInput/TokenSearchInput.svelte.d.ts → TokenSearchField/TokenSearchField.svelte.d.ts} +3 -3
- package/dist/components/Library/TokenSearchField/index.d.ts +1 -0
- package/dist/components/Library/TokenSearchField/index.js +1 -0
- package/dist/components/Library/VStack/VStack.svelte +45 -0
- package/dist/components/Library/VStack/VStack.svelte.d.ts +9 -0
- package/dist/components/Library/VStack/index.d.ts +1 -0
- package/dist/components/Library/VStack/index.js +1 -0
- package/dist/components/Library/WheelPicker/WheelColumn.svelte +4 -10
- package/dist/components/Library/WheelPicker/WheelPicker.svelte +5 -9
- package/dist/components/Local/ComponentGrid.svelte +15 -31
- package/dist/components/Local/HeroCard.svelte +30 -38
- package/dist/components/Local/HeroCard.svelte.d.ts +0 -2
- package/dist/components/Local/StyleControls.svelte +58 -27
- package/dist/components/Local/StyleControls.svelte.d.ts +3 -1
- package/dist/index.d.ts +26 -2
- package/dist/index.js +19 -2
- package/dist/style/index.css +35 -20
- package/dist/style/label.d.ts +6 -0
- package/dist/style/label.js +4 -0
- package/dist/style/layout.d.ts +57 -0
- package/dist/style/layout.js +128 -0
- package/dist/style/media.d.ts +12 -0
- package/dist/style/media.js +8 -0
- package/dist/style/scroll.d.ts +7 -0
- package/dist/style/scroll.js +5 -0
- package/dist/style/text-editor.d.ts +34 -0
- package/dist/style/text-editor.js +29 -0
- package/dist/style.css +112 -58
- package/package.json +1 -1
- package/dist/components/Library/Dropdown/types.d.ts +0 -27
- package/dist/components/Library/SearchInput/SearchInput.demo.svelte.d.ts +0 -8
- package/dist/components/Library/SearchInput/index.d.ts +0 -1
- package/dist/components/Library/SearchInput/index.js +0 -1
- package/dist/components/Library/TokenSearchInput/TokenSearchInput.demo.svelte.d.ts +0 -9
- package/dist/components/Library/TokenSearchInput/index.d.ts +0 -1
- package/dist/components/Library/TokenSearchInput/index.js +0 -1
- /package/dist/components/Library/{Dropdown → ImageMask}/types.js +0 -0
|
@@ -1,134 +1,71 @@
|
|
|
1
|
-
<script lang="ts" generics="
|
|
2
|
-
import {
|
|
1
|
+
<script lang="ts" generics="TValue = unknown">
|
|
2
|
+
import { ChevronDownIcon } from '@lucide/svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
3
4
|
import Floating from '../Floating/Floating.svelte';
|
|
4
|
-
import SearchInput from '../SearchInput';
|
|
5
5
|
import { surfaceStyle, type StyleProps } from '../../../style/surface';
|
|
6
6
|
import type { Anchor } from '../../../utils/positioning';
|
|
7
|
-
import type
|
|
8
|
-
DropdownAction,
|
|
9
|
-
DropdownEntry,
|
|
10
|
-
DropdownGroup,
|
|
11
|
-
DropdownItem,
|
|
12
|
-
DropdownSubmenu
|
|
13
|
-
} from './types';
|
|
7
|
+
import { setDropdownContext, type DropdownTriggerState } from './context';
|
|
14
8
|
|
|
15
9
|
type Props = {
|
|
16
|
-
|
|
17
|
-
value?: T | null;
|
|
10
|
+
value?: TValue | null;
|
|
18
11
|
open?: boolean;
|
|
19
12
|
label?: string;
|
|
20
13
|
placeholder?: string;
|
|
14
|
+
selectedLabel?: string | null;
|
|
21
15
|
disabled?: boolean;
|
|
22
16
|
closeOnSelect?: boolean;
|
|
23
17
|
showCheck?: boolean;
|
|
24
|
-
searchPlaceholder?: string;
|
|
25
18
|
placement?: Anchor;
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
trigger?: Snippet<[DropdownTriggerState<TValue>]>;
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
onValueChange?: (value: TValue) => void;
|
|
28
22
|
} & StyleProps;
|
|
29
23
|
|
|
30
|
-
const isGroup = (entry: DropdownEntry<T>): entry is DropdownGroup<T> =>
|
|
31
|
-
'type' in entry && entry.type === 'group';
|
|
32
|
-
const isAction = (entry: DropdownItem<T> | DropdownAction): entry is DropdownAction =>
|
|
33
|
-
'type' in entry && entry.type === 'action';
|
|
34
|
-
const isSubmenu = (entry: DropdownEntry<T>): entry is DropdownSubmenu<T> =>
|
|
35
|
-
'type' in entry && entry.type === 'submenu';
|
|
36
|
-
|
|
37
24
|
let {
|
|
38
|
-
|
|
39
|
-
value = $bindable<T | null>(null),
|
|
25
|
+
value = $bindable<TValue | null>(null),
|
|
40
26
|
open = $bindable(false),
|
|
41
27
|
label = 'Select option',
|
|
42
28
|
placeholder = 'Select option',
|
|
29
|
+
selectedLabel = null,
|
|
43
30
|
disabled = false,
|
|
44
31
|
closeOnSelect = true,
|
|
45
32
|
showCheck = true,
|
|
46
|
-
searchPlaceholder = 'Search',
|
|
47
33
|
placement = 'bottom',
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
trigger: triggerContent,
|
|
35
|
+
children,
|
|
36
|
+
onValueChange,
|
|
50
37
|
...styleProps
|
|
51
38
|
}: Props = $props();
|
|
52
39
|
|
|
53
40
|
const dropdownStyle = $derived.by(() => surfaceStyle(styleProps, 'dropdown'));
|
|
41
|
+
const triggerText = $derived(selectedLabel ?? (value === null ? placeholder : String(value)));
|
|
54
42
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const flattenItems = (
|
|
61
|
-
entries: DropdownEntry<T>[],
|
|
62
|
-
inheritedDisabled = false
|
|
63
|
-
): DropdownItem<T>[] =>
|
|
64
|
-
entries.flatMap((entry) => {
|
|
65
|
-
const nextDisabled = inheritedDisabled || !!entry.disabled;
|
|
66
|
-
if (isGroup(entry) || isSubmenu(entry)) {
|
|
67
|
-
return flattenItems(entry.items, nextDisabled);
|
|
68
|
-
}
|
|
69
|
-
if (isAction(entry)) {
|
|
70
|
-
return [];
|
|
71
|
-
}
|
|
72
|
-
return [{ ...entry, disabled: nextDisabled || entry.disabled }];
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const findFirstRenderableLabel = (entries: DropdownEntry<T>[]): string | null => {
|
|
76
|
-
for (const entry of entries) {
|
|
77
|
-
if (isGroup(entry)) {
|
|
78
|
-
const nested = findFirstRenderableLabel(entry.items);
|
|
79
|
-
if (nested) return nested;
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
return entry.label;
|
|
83
|
-
}
|
|
84
|
-
return null;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const flatItems = $derived.by(() => flattenItems(items));
|
|
88
|
-
|
|
89
|
-
const selectedItem = $derived.by(
|
|
90
|
-
() => flatItems.find((item) => item.value === value) ?? null
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
const triggerText = $derived(selectedItem?.label ?? placeholder);
|
|
94
|
-
|
|
95
|
-
const filteredItems = $derived(items);
|
|
96
|
-
|
|
97
|
-
const firstRenderableLabel = $derived.by(() => findFirstRenderableLabel(filteredItems));
|
|
98
|
-
|
|
99
|
-
const itemRadiusSourceEnabled = $derived.by(() => {
|
|
100
|
-
if (searchEnabled) return false;
|
|
101
|
-
const firstEntry = filteredItems[0];
|
|
102
|
-
if (!firstEntry) return false;
|
|
103
|
-
if (isGroup(firstEntry)) {
|
|
104
|
-
return !firstEntry.label;
|
|
105
|
-
}
|
|
106
|
-
return true;
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
function handleSelect(item: DropdownItem<T>) {
|
|
110
|
-
if (disabled || item.disabled) return;
|
|
111
|
-
value = item.value;
|
|
112
|
-
onSelect?.(item);
|
|
43
|
+
function select(nextValue: TValue) {
|
|
44
|
+
if (disabled) return;
|
|
45
|
+
value = nextValue;
|
|
46
|
+
onValueChange?.(nextValue);
|
|
113
47
|
if (closeOnSelect) open = false;
|
|
114
48
|
}
|
|
115
49
|
|
|
116
|
-
function
|
|
117
|
-
|
|
118
|
-
item.onSelect();
|
|
119
|
-
if (closeOnSelect) open = false;
|
|
50
|
+
function close() {
|
|
51
|
+
open = false;
|
|
120
52
|
}
|
|
121
53
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
54
|
+
setDropdownContext<TValue>({
|
|
55
|
+
get value() {
|
|
56
|
+
return value;
|
|
57
|
+
},
|
|
58
|
+
get disabled() {
|
|
59
|
+
return disabled;
|
|
60
|
+
},
|
|
61
|
+
get closeOnSelect() {
|
|
62
|
+
return closeOnSelect;
|
|
63
|
+
},
|
|
64
|
+
get showCheck() {
|
|
65
|
+
return showCheck;
|
|
66
|
+
},
|
|
67
|
+
select,
|
|
68
|
+
close
|
|
132
69
|
});
|
|
133
70
|
</script>
|
|
134
71
|
|
|
@@ -142,122 +79,41 @@
|
|
|
142
79
|
matchPanelRadiusToSource={true}
|
|
143
80
|
>
|
|
144
81
|
{#snippet trigger(floating)}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
<
|
|
159
|
-
|
|
82
|
+
{#if triggerContent}
|
|
83
|
+
{@render triggerContent({
|
|
84
|
+
useTrigger: floating.useTrigger,
|
|
85
|
+
open: floating.open,
|
|
86
|
+
value,
|
|
87
|
+
selectedLabel: triggerText,
|
|
88
|
+
placeholder,
|
|
89
|
+
disabled,
|
|
90
|
+
toggle: floating.toggle,
|
|
91
|
+
openPanel: floating.openPanel,
|
|
92
|
+
closePanel: floating.closePanel
|
|
93
|
+
})}
|
|
94
|
+
{:else}
|
|
95
|
+
<button
|
|
96
|
+
use:floating.useTrigger
|
|
97
|
+
type="button"
|
|
98
|
+
class="dropdown-trigger justify-between"
|
|
99
|
+
aria-label={label}
|
|
100
|
+
aria-disabled={disabled}
|
|
101
|
+
{disabled}
|
|
102
|
+
style={dropdownStyle}
|
|
103
|
+
aria-expanded={floating.open}
|
|
104
|
+
aria-haspopup="dialog"
|
|
105
|
+
onclick={floating.toggle}
|
|
106
|
+
>
|
|
107
|
+
<span class="dropdown-trigger-label">{triggerText}</span>
|
|
108
|
+
<ChevronDownIcon class="size-4 text-[var(--sveltely-secondary-color)]" />
|
|
109
|
+
</button>
|
|
110
|
+
{/if}
|
|
160
111
|
{/snippet}
|
|
161
112
|
|
|
162
|
-
<div
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
>
|
|
166
|
-
{#if searchEnabled}
|
|
167
|
-
<SearchInput
|
|
168
|
-
bind:value={query}
|
|
169
|
-
placeholder={searchPlaceholder}
|
|
170
|
-
radiusSource={true}
|
|
171
|
-
class="w-64"
|
|
172
|
-
/>
|
|
113
|
+
<div class="dropdown-content vstack" style={dropdownStyle}>
|
|
114
|
+
{#if children}
|
|
115
|
+
{@render children()}
|
|
173
116
|
{/if}
|
|
174
|
-
{#snippet renderEntries(entries: DropdownEntry<T>[], inheritedDisabled = false)}
|
|
175
|
-
{#each entries as entry, index (`${index}-${entry.type ?? 'option'}-${entry.label}`)}
|
|
176
|
-
{#if isGroup(entry)}
|
|
177
|
-
<div class="dropdown-group vstack">
|
|
178
|
-
{#if entry.label}
|
|
179
|
-
<div class="dropdown-group-label">{entry.label}</div>
|
|
180
|
-
{/if}
|
|
181
|
-
{@render renderEntries(entry.items, inheritedDisabled || !!entry.disabled)}
|
|
182
|
-
</div>
|
|
183
|
-
{:else if isSubmenu(entry)}
|
|
184
|
-
<Floating
|
|
185
|
-
placement={entry.placement ?? 'right'}
|
|
186
|
-
rootClass="dropdown-submenu-root relative w-full"
|
|
187
|
-
panelClass="dropdown-panel fixed z-50 focus:outline-none"
|
|
188
|
-
panelStyle={dropdownStyle}
|
|
189
|
-
contentStyle=""
|
|
190
|
-
matchPanelRadiusToSource={true}
|
|
191
|
-
closeOnPointerLeave={true}
|
|
192
|
-
>
|
|
193
|
-
{#snippet trigger(floating)}
|
|
194
|
-
<button
|
|
195
|
-
use:floating.useTrigger
|
|
196
|
-
type="button"
|
|
197
|
-
class="dropdown-item dropdown-submenu-trigger inline-flex items-center justify-between text-left"
|
|
198
|
-
class:dropdown-item-open={floating.open}
|
|
199
|
-
data-popover-radius-source={isRadiusSource(entry.label) ? 'true' : undefined}
|
|
200
|
-
disabled={isEntryDisabled(entry, inheritedDisabled)}
|
|
201
|
-
aria-expanded={floating.open}
|
|
202
|
-
aria-haspopup="menu"
|
|
203
|
-
onmouseenter={() => {
|
|
204
|
-
if (!isEntryDisabled(entry, inheritedDisabled)) {
|
|
205
|
-
void floating.openPanel();
|
|
206
|
-
}
|
|
207
|
-
}}
|
|
208
|
-
onclick={(event) => {
|
|
209
|
-
event.stopPropagation();
|
|
210
|
-
floating.toggle();
|
|
211
|
-
}}
|
|
212
|
-
>
|
|
213
|
-
<span>{entry.label}</span>
|
|
214
|
-
<ChevronRightIcon class="size-4 text-zinc-500" />
|
|
215
|
-
</button>
|
|
216
|
-
{/snippet}
|
|
217
|
-
|
|
218
|
-
<div
|
|
219
|
-
class="dropdown-content vstack"
|
|
220
|
-
style={`${dropdownStyle} --dropdown-item-radius: var(--sveltely-border-radius-nested);`}
|
|
221
|
-
>
|
|
222
|
-
{@render renderEntries(entry.items, inheritedDisabled || !!entry.disabled)}
|
|
223
|
-
</div>
|
|
224
|
-
</Floating>
|
|
225
|
-
{:else if isAction(entry)}
|
|
226
|
-
<button
|
|
227
|
-
type="button"
|
|
228
|
-
class="dropdown-item inline-flex items-center justify-between text-left"
|
|
229
|
-
data-popover-radius-source={isRadiusSource(entry.label) ? 'true' : undefined}
|
|
230
|
-
disabled={isEntryDisabled(entry, inheritedDisabled)}
|
|
231
|
-
onclick={() =>
|
|
232
|
-
handleAction({
|
|
233
|
-
...entry,
|
|
234
|
-
disabled: inheritedDisabled || entry.disabled
|
|
235
|
-
})}
|
|
236
|
-
>
|
|
237
|
-
<span>{entry.label}</span>
|
|
238
|
-
</button>
|
|
239
|
-
{:else}
|
|
240
|
-
<button
|
|
241
|
-
type="button"
|
|
242
|
-
class="dropdown-item inline-flex items-center justify-between text-left"
|
|
243
|
-
data-popover-radius-source={isRadiusSource(entry.label) ? 'true' : undefined}
|
|
244
|
-
disabled={isEntryDisabled(entry, inheritedDisabled)}
|
|
245
|
-
onclick={() =>
|
|
246
|
-
handleSelect({
|
|
247
|
-
...entry,
|
|
248
|
-
disabled: inheritedDisabled || entry.disabled
|
|
249
|
-
})}
|
|
250
|
-
>
|
|
251
|
-
<span>{entry.label}</span>
|
|
252
|
-
{#if showCheck && entry.value === value}
|
|
253
|
-
<CheckIcon class="size-4 text-zinc-700" />
|
|
254
|
-
{/if}
|
|
255
|
-
</button>
|
|
256
|
-
{/if}
|
|
257
|
-
{/each}
|
|
258
|
-
{/snippet}
|
|
259
|
-
|
|
260
|
-
{@render renderEntries(filteredItems)}
|
|
261
117
|
</div>
|
|
262
118
|
</Floating>
|
|
263
119
|
|
|
@@ -267,67 +123,56 @@
|
|
|
267
123
|
--sveltely-nested-inset: var(--dropdown-inset);
|
|
268
124
|
border: 1px solid var(--sveltely-border-color);
|
|
269
125
|
border-radius: var(--sveltely-border-radius);
|
|
270
|
-
background:
|
|
126
|
+
background: var(--sveltely-background-color);
|
|
271
127
|
padding: var(--dropdown-inset);
|
|
272
128
|
}
|
|
273
129
|
|
|
274
130
|
.dropdown-trigger {
|
|
275
131
|
display: inline-flex;
|
|
276
132
|
min-width: 8rem;
|
|
133
|
+
max-width: 100%;
|
|
277
134
|
align-items: center;
|
|
278
135
|
border: 1px solid var(--sveltely-border-color);
|
|
279
136
|
border-radius: var(--sveltely-border-radius);
|
|
280
|
-
background:
|
|
281
|
-
color: var(--
|
|
137
|
+
background: var(--sveltely-background-color);
|
|
138
|
+
color: var(--sveltely-primary-color);
|
|
282
139
|
gap: var(--sveltely-gap);
|
|
283
140
|
padding: calc(var(--sveltely-padding-y) * 0.67) var(--sveltely-padding-x);
|
|
284
141
|
font-size: 0.875rem;
|
|
285
142
|
line-height: 1.25rem;
|
|
286
|
-
transition:
|
|
143
|
+
transition:
|
|
144
|
+
color 150ms,
|
|
145
|
+
border-color 150ms,
|
|
146
|
+
background-color 150ms;
|
|
287
147
|
}
|
|
288
148
|
|
|
289
|
-
.dropdown-trigger
|
|
290
|
-
|
|
149
|
+
.dropdown-trigger-label {
|
|
150
|
+
min-width: 0;
|
|
151
|
+
flex: 1 1 auto;
|
|
152
|
+
overflow: hidden;
|
|
153
|
+
text-overflow: ellipsis;
|
|
154
|
+
white-space: nowrap;
|
|
291
155
|
}
|
|
292
156
|
|
|
293
|
-
.dropdown-
|
|
294
|
-
|
|
295
|
-
padding-top: 0.25rem;
|
|
296
|
-
color: var(--color-zinc-500);
|
|
297
|
-
font-size: 0.75rem;
|
|
298
|
-
line-height: 1rem;
|
|
299
|
-
font-weight: 500;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
.dropdown-content {
|
|
303
|
-
gap: var(--sveltely-inset);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
.dropdown-group {
|
|
307
|
-
gap: var(--sveltely-inset);
|
|
157
|
+
.dropdown-trigger :global(svg) {
|
|
158
|
+
flex: 0 0 auto;
|
|
308
159
|
}
|
|
309
160
|
|
|
310
|
-
.dropdown-
|
|
311
|
-
width: 100%;
|
|
312
|
-
gap: calc(var(--sveltely-inset) * 2);
|
|
313
|
-
border-radius: var(--dropdown-item-radius, var(--sveltely-border-radius-nested));
|
|
314
|
-
padding: calc(var(--sveltely-padding-y) * 0.33) calc(var(--sveltely-padding-x) * 0.67);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
.dropdown-item :global(*) {
|
|
318
|
-
border-radius: inherit;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
.dropdown-item:hover {
|
|
161
|
+
.dropdown-trigger:hover {
|
|
322
162
|
background: var(--sveltely-hover-color);
|
|
323
163
|
}
|
|
324
164
|
|
|
325
|
-
.dropdown-
|
|
326
|
-
|
|
165
|
+
.dropdown-content {
|
|
166
|
+
--dropdown-item-padding-x: calc(var(--sveltely-padding-x) * 0.67);
|
|
167
|
+
--dropdown-item-padding-y: calc(var(--sveltely-padding-y) * 0.33);
|
|
168
|
+
--dropdown-item-radius: var(--sveltely-border-radius-nested);
|
|
169
|
+
gap: var(--sveltely-inset);
|
|
327
170
|
}
|
|
328
171
|
|
|
329
|
-
.dropdown-
|
|
330
|
-
|
|
331
|
-
|
|
172
|
+
.dropdown-content :global(.divider) {
|
|
173
|
+
--divider-width: auto;
|
|
174
|
+
margin-inline: var(--dropdown-item-padding-x);
|
|
175
|
+
margin-block: calc(var(--sveltely-inset) * 0.5);
|
|
176
|
+
background: var(--sveltely-border-color);
|
|
332
177
|
}
|
|
333
178
|
</style>
|
|
@@ -1,40 +1,41 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import { type StyleProps } from '../../../style/surface';
|
|
2
3
|
import type { Anchor } from '../../../utils/positioning';
|
|
3
|
-
import
|
|
4
|
-
declare function $$render<
|
|
4
|
+
import { type DropdownTriggerState } from './context';
|
|
5
|
+
declare function $$render<TValue = unknown>(): {
|
|
5
6
|
props: {
|
|
6
|
-
|
|
7
|
-
value?: T | null;
|
|
7
|
+
value?: TValue | null;
|
|
8
8
|
open?: boolean;
|
|
9
9
|
label?: string;
|
|
10
10
|
placeholder?: string;
|
|
11
|
+
selectedLabel?: string | null;
|
|
11
12
|
disabled?: boolean;
|
|
12
13
|
closeOnSelect?: boolean;
|
|
13
14
|
showCheck?: boolean;
|
|
14
|
-
searchPlaceholder?: string;
|
|
15
15
|
placement?: Anchor;
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
trigger?: Snippet<[DropdownTriggerState<TValue>]>;
|
|
17
|
+
children?: Snippet;
|
|
18
|
+
onValueChange?: (value: TValue) => void;
|
|
18
19
|
} & StyleProps;
|
|
19
20
|
exports: {};
|
|
20
21
|
bindings: "value" | "open";
|
|
21
22
|
slots: {};
|
|
22
23
|
events: {};
|
|
23
24
|
};
|
|
24
|
-
declare class __sveltets_Render<
|
|
25
|
-
props(): ReturnType<typeof $$render<
|
|
26
|
-
events(): ReturnType<typeof $$render<
|
|
27
|
-
slots(): ReturnType<typeof $$render<
|
|
25
|
+
declare class __sveltets_Render<TValue = unknown> {
|
|
26
|
+
props(): ReturnType<typeof $$render<TValue>>['props'];
|
|
27
|
+
events(): ReturnType<typeof $$render<TValue>>['events'];
|
|
28
|
+
slots(): ReturnType<typeof $$render<TValue>>['slots'];
|
|
28
29
|
bindings(): "value" | "open";
|
|
29
30
|
exports(): {};
|
|
30
31
|
}
|
|
31
32
|
interface $$IsomorphicComponent {
|
|
32
|
-
new <
|
|
33
|
-
$$bindings?: ReturnType<__sveltets_Render<
|
|
34
|
-
} & ReturnType<__sveltets_Render<
|
|
35
|
-
<
|
|
33
|
+
new <TValue = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TValue>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TValue>['props']>, ReturnType<__sveltets_Render<TValue>['events']>, ReturnType<__sveltets_Render<TValue>['slots']>> & {
|
|
34
|
+
$$bindings?: ReturnType<__sveltets_Render<TValue>['bindings']>;
|
|
35
|
+
} & ReturnType<__sveltets_Render<TValue>['exports']>;
|
|
36
|
+
<TValue = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<TValue>['props']> & {}): ReturnType<__sveltets_Render<TValue>['exports']>;
|
|
36
37
|
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
37
38
|
}
|
|
38
39
|
declare const Dropdown: $$IsomorphicComponent;
|
|
39
|
-
type Dropdown<
|
|
40
|
+
type Dropdown<TValue = unknown> = InstanceType<typeof Dropdown<TValue>>;
|
|
40
41
|
export default Dropdown;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts" generics="TValue = unknown">
|
|
2
|
+
import { CheckIcon } from '@lucide/svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import { getDropdownContext, type DropdownItemState } from './context';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
value: TValue;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
showCheck?: boolean;
|
|
10
|
+
children?: Snippet<[DropdownItemState<TValue>]>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
let { value, disabled = false, showCheck, children }: Props = $props();
|
|
14
|
+
|
|
15
|
+
const dropdown = getDropdownContext<TValue>();
|
|
16
|
+
const selected = $derived(dropdown.value === value);
|
|
17
|
+
const resolvedDisabled = $derived(dropdown.disabled || disabled);
|
|
18
|
+
const resolvedShowCheck = $derived(showCheck ?? dropdown.showCheck);
|
|
19
|
+
|
|
20
|
+
function select() {
|
|
21
|
+
if (resolvedDisabled) return;
|
|
22
|
+
dropdown.select(value);
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<button
|
|
27
|
+
type="button"
|
|
28
|
+
class="dropdown-item inline-flex items-center justify-between text-left"
|
|
29
|
+
data-popover-radius-source
|
|
30
|
+
disabled={resolvedDisabled}
|
|
31
|
+
aria-pressed={selected}
|
|
32
|
+
onclick={select}
|
|
33
|
+
>
|
|
34
|
+
{#if children}
|
|
35
|
+
{@render children({
|
|
36
|
+
value,
|
|
37
|
+
selected,
|
|
38
|
+
disabled: resolvedDisabled,
|
|
39
|
+
close: dropdown.close,
|
|
40
|
+
select
|
|
41
|
+
})}
|
|
42
|
+
{/if}
|
|
43
|
+
{#if resolvedShowCheck && selected}
|
|
44
|
+
<CheckIcon class="size-4 text-[var(--sveltely-primary-color)]" />
|
|
45
|
+
{/if}
|
|
46
|
+
</button>
|
|
47
|
+
|
|
48
|
+
<style>
|
|
49
|
+
.dropdown-item {
|
|
50
|
+
width: 100%;
|
|
51
|
+
gap: calc(var(--sveltely-inset) * 2);
|
|
52
|
+
border-radius: var(--dropdown-item-radius, var(--sveltely-border-radius-nested));
|
|
53
|
+
padding: var(--dropdown-item-padding-y) var(--dropdown-item-padding-x);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.dropdown-item :global(*) {
|
|
57
|
+
border-radius: inherit;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.dropdown-item:hover {
|
|
61
|
+
background: var(--sveltely-hover-color);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.dropdown-item:disabled {
|
|
65
|
+
cursor: not-allowed;
|
|
66
|
+
opacity: 0.5;
|
|
67
|
+
}
|
|
68
|
+
</style>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import { type DropdownItemState } from './context';
|
|
3
|
+
declare function $$render<TValue = unknown>(): {
|
|
4
|
+
props: {
|
|
5
|
+
value: TValue;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
showCheck?: boolean;
|
|
8
|
+
children?: Snippet<[DropdownItemState<TValue>]>;
|
|
9
|
+
};
|
|
10
|
+
exports: {};
|
|
11
|
+
bindings: "";
|
|
12
|
+
slots: {};
|
|
13
|
+
events: {};
|
|
14
|
+
};
|
|
15
|
+
declare class __sveltets_Render<TValue = unknown> {
|
|
16
|
+
props(): ReturnType<typeof $$render<TValue>>['props'];
|
|
17
|
+
events(): ReturnType<typeof $$render<TValue>>['events'];
|
|
18
|
+
slots(): ReturnType<typeof $$render<TValue>>['slots'];
|
|
19
|
+
bindings(): "";
|
|
20
|
+
exports(): {};
|
|
21
|
+
}
|
|
22
|
+
interface $$IsomorphicComponent {
|
|
23
|
+
new <TValue = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TValue>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TValue>['props']>, ReturnType<__sveltets_Render<TValue>['events']>, ReturnType<__sveltets_Render<TValue>['slots']>> & {
|
|
24
|
+
$$bindings?: ReturnType<__sveltets_Render<TValue>['bindings']>;
|
|
25
|
+
} & ReturnType<__sveltets_Render<TValue>['exports']>;
|
|
26
|
+
<TValue = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<TValue>['props']> & {}): ReturnType<__sveltets_Render<TValue>['exports']>;
|
|
27
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
28
|
+
}
|
|
29
|
+
declare const Item: $$IsomorphicComponent;
|
|
30
|
+
type Item<TValue = unknown> = InstanceType<typeof Item<TValue>>;
|
|
31
|
+
export default Item;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
label?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
let { label, children }: Props = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<div class="dropdown-section vstack">
|
|
13
|
+
{#if label}
|
|
14
|
+
<div class="dropdown-section-label">{label}</div>
|
|
15
|
+
{/if}
|
|
16
|
+
{#if children}
|
|
17
|
+
{@render children()}
|
|
18
|
+
{/if}
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<style>
|
|
22
|
+
.dropdown-section {
|
|
23
|
+
gap: var(--sveltely-inset);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.dropdown-section-label {
|
|
27
|
+
padding-inline: 0.25rem;
|
|
28
|
+
padding-top: 0.25rem;
|
|
29
|
+
color: var(--sveltely-secondary-color);
|
|
30
|
+
font-size: 0.75rem;
|
|
31
|
+
line-height: 1rem;
|
|
32
|
+
font-weight: 500;
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Action } from 'svelte/action';
|
|
2
|
+
export type DropdownValue = unknown;
|
|
3
|
+
export type DropdownTriggerState<TValue = DropdownValue> = {
|
|
4
|
+
useTrigger: Action<HTMLElement>;
|
|
5
|
+
open: boolean;
|
|
6
|
+
value: TValue | null;
|
|
7
|
+
selectedLabel: string;
|
|
8
|
+
placeholder: string;
|
|
9
|
+
disabled: boolean;
|
|
10
|
+
toggle: () => void;
|
|
11
|
+
openPanel: () => Promise<void>;
|
|
12
|
+
closePanel: () => void;
|
|
13
|
+
};
|
|
14
|
+
export type DropdownItemState<TValue = DropdownValue> = {
|
|
15
|
+
value: TValue;
|
|
16
|
+
selected: boolean;
|
|
17
|
+
disabled: boolean;
|
|
18
|
+
close: () => void;
|
|
19
|
+
select: () => void;
|
|
20
|
+
};
|
|
21
|
+
export type DropdownActionState = {
|
|
22
|
+
disabled: boolean;
|
|
23
|
+
close: () => void;
|
|
24
|
+
};
|
|
25
|
+
export type DropdownContext<TValue = DropdownValue> = {
|
|
26
|
+
get value(): TValue | null;
|
|
27
|
+
get disabled(): boolean;
|
|
28
|
+
get closeOnSelect(): boolean;
|
|
29
|
+
get showCheck(): boolean;
|
|
30
|
+
select: (value: TValue) => void;
|
|
31
|
+
close: () => void;
|
|
32
|
+
};
|
|
33
|
+
export declare const setDropdownContext: <TValue>(context: DropdownContext<TValue>) => void;
|
|
34
|
+
export declare const getDropdownContext: <TValue>() => DropdownContext<TValue>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
const dropdownContextKey = Symbol('dropdown');
|
|
3
|
+
export const setDropdownContext = (context) => {
|
|
4
|
+
setContext(dropdownContextKey, context);
|
|
5
|
+
};
|
|
6
|
+
export const getDropdownContext = () => getContext(dropdownContextKey);
|
|
@@ -1,2 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import DropdownComponent from './Dropdown.svelte';
|
|
2
|
+
import Action from './Action.svelte';
|
|
3
|
+
import Divider from './Divider.svelte';
|
|
4
|
+
import Item from './Item.svelte';
|
|
5
|
+
import Section from './Section.svelte';
|
|
6
|
+
declare const Dropdown: typeof DropdownComponent & {
|
|
7
|
+
Action: typeof Action;
|
|
8
|
+
Divider: typeof Divider;
|
|
9
|
+
Item: typeof Item;
|
|
10
|
+
Section: typeof Section;
|
|
11
|
+
};
|
|
12
|
+
export default Dropdown;
|
|
13
|
+
export type { DropdownActionState, DropdownItemState, DropdownTriggerState } from './context';
|