@flightlesslabs/dodo-ui 0.7.2 → 0.9.0
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/index.d.ts +18 -2
- package/dist/index.js +11 -0
- package/dist/stories/components/Form/NumericInput/Events/Events.stories.svelte +126 -0
- package/dist/stories/components/Form/NumericInput/Events/Events.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Form/NumericInput/NumericInput.stories.svelte +79 -0
- package/dist/stories/components/Form/NumericInput/NumericInput.stories.svelte.d.ts +21 -0
- package/dist/stories/components/Form/NumericInput/NumericInput.svelte +161 -0
- package/dist/stories/components/Form/NumericInput/NumericInput.svelte.d.ts +69 -0
- package/dist/stories/components/Form/NumericInput/Validation/Validation.stories.svelte +84 -0
- package/dist/stories/components/Form/NumericInput/Validation/Validation.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Form/PasswordInput/Events/Events.stories.svelte +27 -6
- package/dist/stories/components/Form/PasswordInput/PasswordInput.svelte +5 -3
- package/dist/stories/components/Form/PasswordInput/PasswordInput.svelte.d.ts +7 -1
- package/dist/stories/components/Form/Select/Customize/Customize.stories.svelte +16 -1
- package/dist/stories/components/Form/Select/DropDownArrow/DropDownArrow.stories.svelte +59 -0
- package/dist/stories/components/Form/Select/DropDownArrow/DropDownArrow.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Form/Select/Events/Events.stories.svelte +27 -0
- package/dist/stories/components/Form/Select/Positions/AutoPosition/AutoPosition.stories.svelte +54 -0
- package/dist/stories/components/Form/Select/Positions/AutoPosition/AutoPosition.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Form/Select/Positions/Positions.stories.svelte +83 -0
- package/dist/stories/components/Form/Select/Positions/Positions.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Form/Select/Select.svelte +110 -123
- package/dist/stories/components/Form/Select/Select.svelte.d.ts +22 -3
- package/dist/stories/components/Form/TextInput/Events/Events.stories.svelte +27 -0
- package/dist/stories/components/Form/TextInput/TextInput.svelte +5 -3
- package/dist/stories/components/Form/TextInput/TextInput.svelte.d.ts +10 -1
- package/dist/stories/components/Layout/Menu/DynamicMenu/Customize/Customize.stories.svelte +28 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/Customize/Customize.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.stories.svelte +51 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.stories.svelte.d.ts +22 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte +129 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte.d.ts +81 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/Events/Events.stories.svelte +46 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/Events/Events.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/KeybaordNavigation/KeybaordNavigation.stories.svelte +27 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/KeybaordNavigation/KeybaordNavigation.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Layout/Menu/DynamicMenu/Options/OptionFormat.mdx +72 -0
- package/dist/stories/components/Layout/Menu/MenuItem/MenuItem.svelte.d.ts +1 -1
- package/dist/stories/developer tools/components/DynamicInput/DynamicInput.svelte +23 -4
- package/dist/stories/developer tools/components/DynamicInput/DynamicInput.svelte.d.ts +13 -2
- package/dist/stories/developer tools/components/DynamicInput/Events/Events.stories.svelte +115 -0
- package/dist/stories/developer tools/components/DynamicInput/Events/Events.stories.svelte.d.ts +18 -0
- package/dist/stories/developer tools/helpers/Numbers/cleanNumericString/cleanNumericString.d.ts +13 -0
- package/dist/stories/developer tools/helpers/Numbers/cleanNumericString/cleanNumericString.js +26 -0
- package/dist/stories/developer tools/helpers/Numbers/cleanNumericString/index.mdx +20 -0
- package/dist/stories/developer tools/helpers/Numbers/isValidNumberValue/index.mdx +71 -0
- package/dist/stories/developer tools/helpers/Numbers/isValidNumberValue/isValidNumberValue.d.ts +51 -0
- package/dist/stories/developer tools/helpers/Numbers/isValidNumberValue/isValidNumberValue.js +96 -0
- package/dist/stories/developer tools/helpers/logger/index.mdx +63 -0
- package/dist/stories/developer tools/helpers/logger/logger.d.ts +24 -0
- package/dist/stories/developer tools/helpers/logger/logger.js +31 -0
- package/package.json +15 -17
- package/src/lib/index.ts +33 -0
- package/src/lib/stories/Home.mdx +59 -0
- package/src/lib/stories/assets/dark-theme-toggle.png +0 -0
- package/src/lib/stories/components/Form/Button/Button.stories.svelte +61 -0
- package/src/lib/stories/components/Form/Button/Color/Color.stories.svelte +43 -0
- package/src/lib/stories/components/Form/Button/Events/Events.stories.svelte +36 -0
- package/src/lib/stories/components/Form/Button/IconButton/IconButton.stories.svelte +43 -0
- package/src/lib/stories/components/Form/Button/Roundness/Roundness.stories.svelte +23 -0
- package/src/lib/stories/components/Form/Button/Size/Size.stories.svelte +16 -0
- package/src/lib/stories/components/Form/Button/Variant/Variant.stories.svelte +18 -0
- package/src/lib/stories/components/Form/FormControl/FormControl.stories.svelte +28 -0
- package/src/lib/stories/components/Form/Label/Label.stories.svelte +13 -0
- package/src/lib/stories/components/Form/Message/Color/Color.stories.svelte +36 -0
- package/src/lib/stories/components/Form/Message/Message.stories.svelte +27 -0
- package/src/lib/stories/components/Form/Message/Size/Size.stories.svelte +22 -0
- package/src/lib/stories/components/Form/NumericInput/Events/Events.stories.svelte +134 -0
- package/src/lib/stories/components/Form/NumericInput/NumericInput.stories.svelte +84 -0
- package/src/lib/stories/components/Form/NumericInput/NumericInput.svelte +286 -0
- package/src/lib/stories/components/Form/NumericInput/Validation/Validation.stories.svelte +87 -0
- package/src/lib/stories/components/Form/PasswordInput/Events/Events.stories.svelte +132 -0
- package/src/lib/stories/components/Form/PasswordInput/PasswordInput.stories.svelte +59 -0
- package/src/lib/stories/components/Form/PasswordInput/PasswordInput.svelte +15 -3
- package/src/lib/stories/components/Form/PasswordInput/Roundness/Roundness.stories.svelte +20 -0
- package/src/lib/stories/components/Form/PasswordInput/Size/Size.stories.svelte +16 -0
- package/src/lib/stories/components/Form/PasswordInput/WithIcon/WithIcon.stories.svelte +31 -0
- package/src/lib/stories/components/Form/Select/Customize/Customize.stories.svelte +139 -0
- package/src/lib/stories/components/Form/Select/DropDownArrow/DropDownArrow.stories.svelte +63 -0
- package/src/lib/stories/components/Form/Select/Events/Events.stories.svelte +174 -0
- package/src/lib/stories/components/Form/Select/Options/OptionFormat.mdx +40 -0
- package/src/lib/stories/components/Form/Select/Positions/AutoPosition/AutoPosition.stories.svelte +58 -0
- package/src/lib/stories/components/Form/Select/Positions/Positions.stories.svelte +87 -0
- package/src/lib/stories/components/Form/Select/Roundness/Roundness.stories.svelte +32 -0
- package/src/lib/stories/components/Form/Select/Select.stories.svelte +121 -0
- package/src/lib/stories/components/Form/Select/Select.svelte +166 -146
- package/src/lib/stories/components/Form/Select/Size/Size.stories.svelte +28 -0
- package/src/lib/stories/components/Form/Select/WithIcon/WithIcon.stories.svelte +43 -0
- package/src/lib/stories/components/Form/TextInput/Events/Events.stories.svelte +125 -0
- package/src/lib/stories/components/Form/TextInput/Roundness/Roundness.stories.svelte +21 -0
- package/src/lib/stories/components/Form/TextInput/Size/Size.stories.svelte +17 -0
- package/src/lib/stories/components/Form/TextInput/TextInput.stories.svelte +43 -0
- package/src/lib/stories/components/Form/TextInput/TextInput.svelte +18 -3
- package/src/lib/stories/components/Form/TextInput/WithIcon/WithIcon.stories.svelte +47 -0
- package/src/lib/stories/components/Layout/Menu/DynamicMenu/Customize/Customize.stories.svelte +30 -0
- package/src/lib/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.stories.svelte +56 -0
- package/src/lib/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte +262 -0
- package/src/lib/stories/components/Layout/Menu/DynamicMenu/Events/Events.stories.svelte +48 -0
- package/src/lib/stories/components/Layout/Menu/DynamicMenu/KeybaordNavigation/KeybaordNavigation.stories.svelte +29 -0
- package/src/lib/stories/components/Layout/Menu/DynamicMenu/Options/OptionFormat.mdx +72 -0
- package/src/lib/stories/components/Layout/Menu/Menu.stories.svelte +69 -0
- package/src/lib/stories/components/Layout/Menu/MenuItem/MenuItem.stories.svelte +34 -0
- package/src/lib/stories/components/Layout/Menu/MenuItem/MenuItem.svelte +1 -1
- package/src/lib/stories/components/Layout/Menu/MenuItem/Size/Size.stories.svelte +16 -0
- package/src/lib/stories/components/Layout/Menu/MenuItem/Type/Type.stories.svelte +21 -0
- package/src/lib/stories/components/Layout/Menu/Size/Size.stories.svelte +37 -0
- package/src/lib/stories/components/Layout/Paper/Color/Color.stories.svelte +63 -0
- package/src/lib/stories/components/Layout/Paper/Paper.stories.svelte +50 -0
- package/src/lib/stories/components/Layout/Paper/Roundness/Roundness.stories.svelte +25 -0
- package/src/lib/stories/components/Layout/Paper/Shadow/Shadow.stories.svelte +24 -0
- package/src/lib/stories/components/Layout/Separator/Color/Color.stories.svelte +19 -0
- package/src/lib/stories/components/Layout/Separator/Separator.stories.svelte +30 -0
- package/src/lib/stories/developer tools/Intro.mdx +9 -0
- package/src/lib/stories/developer tools/components/DynamicInput/DynamicInput.stories.svelte +53 -0
- package/src/lib/stories/developer tools/components/DynamicInput/DynamicInput.svelte +43 -3
- package/src/lib/stories/developer tools/components/DynamicInput/Events/Events.stories.svelte +121 -0
- package/src/lib/stories/developer tools/components/DynamicInput/Size/Size.stories.svelte +17 -0
- package/src/lib/stories/developer tools/components/InputEnclosure/InputEnclosure.stories.svelte +38 -0
- package/src/lib/stories/developer tools/components/InputEnclosure/Roundness/Roundness.stories.svelte +20 -0
- package/src/lib/stories/developer tools/components/InputEnclosure/Size/Size.stories.svelte +16 -0
- package/src/lib/stories/developer tools/components/InputEnclosure/WithIcon/WithIcon.stories.svelte +47 -0
- package/src/lib/stories/developer tools/components/Popper/Popper.stories.svelte +124 -0
- package/src/lib/stories/developer tools/components/Popper/PopperPopup/PopperPopup.stories.svelte +64 -0
- package/src/lib/stories/developer tools/components/Popper/Positions/AutoPosition/AutoPosition.stories.svelte +92 -0
- package/src/lib/stories/developer tools/components/Popper/Positions/Positions.stories.svelte +114 -0
- package/src/lib/stories/developer tools/components/UtilityButton/Size/Size.stories.svelte +25 -0
- package/src/lib/stories/developer tools/components/UtilityButton/UtilityButton.stories.svelte +30 -0
- package/src/lib/stories/developer tools/directives/clickOutside/index.mdx +25 -0
- package/src/lib/stories/developer tools/helpers/Numbers/cleanNumericString/cleanNumericString.ts +27 -0
- package/src/lib/stories/developer tools/helpers/Numbers/cleanNumericString/index.mdx +20 -0
- package/src/lib/stories/developer tools/helpers/Numbers/isValidNumberValue/index.mdx +71 -0
- package/src/lib/stories/developer tools/helpers/Numbers/isValidNumberValue/isValidNumberValue.ts +156 -0
- package/src/lib/stories/developer tools/helpers/logger/index.mdx +63 -0
- package/src/lib/stories/developer tools/helpers/logger/logger.ts +46 -0
- package/src/lib/stories/developer tools/philosophy/Colors/Colors.mdx +43 -0
- package/src/lib/stories/developer tools/philosophy/Colors/Colors.stories.svelte +22 -0
- package/src/lib/stories/developer tools/philosophy/Colors/Opacity.stories.svelte +11 -0
- package/src/lib/stories/developer tools/philosophy/Themes.mdx +23 -0
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
ClipboardEventHandler,
|
|
8
8
|
FocusEventHandler,
|
|
9
9
|
FormEventHandler,
|
|
10
|
+
KeyboardEventHandler,
|
|
10
11
|
MouseEventHandler,
|
|
11
12
|
} from 'svelte/elements';
|
|
12
13
|
|
|
@@ -16,6 +17,8 @@
|
|
|
16
17
|
disabled?: boolean;
|
|
17
18
|
};
|
|
18
19
|
|
|
20
|
+
export type SelectDropdownArrowPosition = false | 'before' | 'after';
|
|
21
|
+
|
|
19
22
|
export interface SelectProps {
|
|
20
23
|
/** How large should the button be? */
|
|
21
24
|
size?: ComponentSize;
|
|
@@ -71,12 +74,22 @@
|
|
|
71
74
|
oncopy?: ClipboardEventHandler<HTMLInputElement>;
|
|
72
75
|
/** oncut event handler */
|
|
73
76
|
oncut?: ClipboardEventHandler<HTMLInputElement>;
|
|
77
|
+
/** onkeydown event handler */
|
|
78
|
+
onkeydown?: KeyboardEventHandler<HTMLInputElement | HTMLButtonElement>;
|
|
79
|
+
/** onkeypress event handler */
|
|
80
|
+
onkeypress?: KeyboardEventHandler<HTMLInputElement | HTMLButtonElement>;
|
|
81
|
+
/** onkeyup event handler */
|
|
82
|
+
onkeyup?: KeyboardEventHandler<HTMLInputElement | HTMLButtonElement>;
|
|
74
83
|
/** custom Content Formatting for variant button */
|
|
75
84
|
customInputContent?: (val: SelectOption) => Snippet;
|
|
76
85
|
/** custom Content Formatting for variant button */
|
|
77
86
|
customMenuItemContent?: (val: SelectOption, selected: boolean) => Snippet;
|
|
78
87
|
/** Custom Popup Content */
|
|
79
|
-
customPopupContent?: (
|
|
88
|
+
customPopupContent?: (
|
|
89
|
+
options: SelectOption[],
|
|
90
|
+
selectedOption: SelectOption,
|
|
91
|
+
onselect: (val: SelectOption) => void,
|
|
92
|
+
) => Snippet;
|
|
80
93
|
/** custom Content Formatting for variant button */
|
|
81
94
|
customPlaceholderMenuItemContent?: () => Snippet;
|
|
82
95
|
/** PopperPopup Max height. Use css compatible value */
|
|
@@ -89,6 +102,18 @@
|
|
|
89
102
|
menuProps?: Partial<MenuProps>;
|
|
90
103
|
/** MenuItem: Menu component props */
|
|
91
104
|
menuItemProps?: Partial<MenuItemProps>;
|
|
105
|
+
/** Dropdown Arrow Icon */
|
|
106
|
+
customDropdownArrowIcon?: (open: boolean) => Snippet;
|
|
107
|
+
/** Select Dropdown Arrow Position */
|
|
108
|
+
dropdownArrowPosition?: SelectDropdownArrowPosition;
|
|
109
|
+
/** Popup stick horizontally */
|
|
110
|
+
popupPositionX?: PositionX;
|
|
111
|
+
/** Popup stick vertically */
|
|
112
|
+
popupPositionY?: PositionY;
|
|
113
|
+
/** Lock positions, disable auto top, bottom position based */
|
|
114
|
+
lockPoistions?: boolean;
|
|
115
|
+
/** Popper Height For Vertical Position, default 300 */
|
|
116
|
+
popperHeightForVerticalPosition?: number;
|
|
92
117
|
}
|
|
93
118
|
</script>
|
|
94
119
|
|
|
@@ -98,14 +123,16 @@
|
|
|
98
123
|
import Icon from '@iconify/svelte';
|
|
99
124
|
import {
|
|
100
125
|
DynamicInput,
|
|
101
|
-
|
|
102
|
-
MenuItem,
|
|
126
|
+
DynamicMenu,
|
|
103
127
|
Popper,
|
|
104
128
|
type DynamicInputFocusEvent,
|
|
129
|
+
type DynamicMenuItemOption,
|
|
105
130
|
type MenuItemProps,
|
|
106
131
|
type MenuProps,
|
|
107
132
|
type PaperProps,
|
|
108
133
|
type PopperProps,
|
|
134
|
+
type PositionX,
|
|
135
|
+
type PositionY,
|
|
109
136
|
} from '$lib/index.js';
|
|
110
137
|
import type { TextInputInputEvent } from '../TextInput/TextInput.svelte';
|
|
111
138
|
import type { ButtonClickEvent } from '../Button/Button.svelte';
|
|
@@ -126,6 +153,9 @@
|
|
|
126
153
|
onpaste,
|
|
127
154
|
oncopy,
|
|
128
155
|
oncut,
|
|
156
|
+
onkeydown,
|
|
157
|
+
onkeypress,
|
|
158
|
+
onkeyup,
|
|
129
159
|
before,
|
|
130
160
|
after,
|
|
131
161
|
error = false,
|
|
@@ -141,37 +171,56 @@
|
|
|
141
171
|
customMenuItemContent: customMenuItemContentInternal,
|
|
142
172
|
customPopupContent: customPopupContentInternal,
|
|
143
173
|
customPlaceholderMenuItemContent: customPlaceholderMenuItemContentInternal,
|
|
174
|
+
customDropdownArrowIcon: customDropdownArrowIconInternal,
|
|
144
175
|
popupMaxHeight = '300px',
|
|
145
176
|
paperProps,
|
|
146
177
|
popperProps,
|
|
147
178
|
menuProps,
|
|
148
179
|
menuItemProps,
|
|
149
180
|
optionsPlaceholder = 'No Options',
|
|
181
|
+
dropdownArrowPosition = 'after',
|
|
182
|
+
popupPositionX,
|
|
183
|
+
popupPositionY,
|
|
184
|
+
lockPoistions,
|
|
185
|
+
popperHeightForVerticalPosition,
|
|
150
186
|
}: SelectProps = $props();
|
|
151
187
|
|
|
188
|
+
function convertOptionsToDynamicMenuItemOptions(
|
|
189
|
+
options: SelectOption[],
|
|
190
|
+
): DynamicMenuItemOption<SelectOption>[] {
|
|
191
|
+
const newOptions: DynamicMenuItemOption<SelectOption>[] = options.map((option) => ({
|
|
192
|
+
id: `opt-${option.value}`,
|
|
193
|
+
disabled: option.disabled,
|
|
194
|
+
label: option.label,
|
|
195
|
+
meta: option,
|
|
196
|
+
type: 'button',
|
|
197
|
+
}));
|
|
198
|
+
|
|
199
|
+
return newOptions;
|
|
200
|
+
}
|
|
201
|
+
|
|
152
202
|
let open: boolean = $state(false);
|
|
153
203
|
let onInputStart: boolean = $state(false);
|
|
154
204
|
const selectedOption = $derived(value);
|
|
155
205
|
let searchTerm = $state(value?.label.trim() || '');
|
|
156
|
-
let options = $state(optionsRaw);
|
|
206
|
+
let options = $state(convertOptionsToDynamicMenuItemOptions(optionsRaw));
|
|
157
207
|
let menuRef = $state<HTMLUListElement | undefined>(undefined);
|
|
158
|
-
let menuItemIndex = $state(0);
|
|
159
208
|
|
|
160
209
|
$effect(() => {
|
|
161
210
|
if (!onInputStart) {
|
|
162
|
-
options = optionsRaw;
|
|
211
|
+
options = convertOptionsToDynamicMenuItemOptions(optionsRaw);
|
|
163
212
|
return;
|
|
164
213
|
}
|
|
165
214
|
|
|
166
215
|
const searchTermSimplified = searchTerm.trim().toLowerCase();
|
|
167
216
|
|
|
168
217
|
if (!searchTermSimplified) {
|
|
169
|
-
options = optionsRaw;
|
|
218
|
+
options = convertOptionsToDynamicMenuItemOptions(optionsRaw);
|
|
170
219
|
return;
|
|
171
220
|
}
|
|
172
221
|
|
|
173
|
-
options = optionsRaw.filter((item) =>
|
|
174
|
-
item
|
|
222
|
+
options = convertOptionsToDynamicMenuItemOptions(optionsRaw).filter((item) =>
|
|
223
|
+
item?.meta?.label.trim().toLowerCase().includes(searchTermSimplified),
|
|
175
224
|
);
|
|
176
225
|
});
|
|
177
226
|
|
|
@@ -187,23 +236,17 @@
|
|
|
187
236
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
188
237
|
let customPlaceholderMenuItemContentTyped = customPlaceholderMenuItemContentInternal as any;
|
|
189
238
|
|
|
239
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
240
|
+
let customDropdownArrowIconTyped = customDropdownArrowIconInternal as any;
|
|
241
|
+
|
|
190
242
|
function closeMenu() {
|
|
191
243
|
open = false;
|
|
192
|
-
menuItemIndex = 0;
|
|
193
244
|
|
|
194
245
|
ref?.blur();
|
|
195
246
|
}
|
|
196
247
|
|
|
197
248
|
function openMenu() {
|
|
198
249
|
open = true;
|
|
199
|
-
|
|
200
|
-
const menuItemIndexNew = options.findIndex((item) => item.value === selectedOption?.value);
|
|
201
|
-
|
|
202
|
-
if (menuItemIndexNew < 0) {
|
|
203
|
-
menuItemIndex = 0;
|
|
204
|
-
} else {
|
|
205
|
-
menuItemIndex = menuItemIndexNew;
|
|
206
|
-
}
|
|
207
250
|
}
|
|
208
251
|
|
|
209
252
|
function onfocusMod(e: DynamicInputFocusEvent) {
|
|
@@ -259,7 +302,9 @@
|
|
|
259
302
|
}
|
|
260
303
|
}
|
|
261
304
|
|
|
262
|
-
function onKeyBoardEnter(selectedItemIndex: number) {
|
|
305
|
+
function onKeyBoardEnter(e: KeyboardEvent, selectedItemIndex: number) {
|
|
306
|
+
e.preventDefault();
|
|
307
|
+
|
|
263
308
|
const targetOption = options[selectedItemIndex];
|
|
264
309
|
|
|
265
310
|
if (!targetOption) {
|
|
@@ -270,106 +315,35 @@
|
|
|
270
315
|
return;
|
|
271
316
|
}
|
|
272
317
|
|
|
273
|
-
onselectMod(targetOption);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function onKeyboardNavigation(e: KeyboardEvent) {
|
|
277
|
-
let keyHit: string | undefined = undefined;
|
|
278
|
-
|
|
279
|
-
if (!menuRef) {
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
if (!open) {
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
switch (e.key) {
|
|
288
|
-
case 'ArrowDown':
|
|
289
|
-
case 'ArrowUp':
|
|
290
|
-
case 'Enter':
|
|
291
|
-
keyHit = e.key;
|
|
292
|
-
e.preventDefault();
|
|
293
|
-
break;
|
|
294
|
-
default:
|
|
295
|
-
break;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (!keyHit) {
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
const listItems = menuRef.querySelectorAll(':scope > li.dodo-ui-MenuItem');
|
|
303
|
-
|
|
304
|
-
if (!listItems.length) {
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
for (let index = 0; index < listItems.length; index++) {
|
|
309
|
-
const element = listItems[index];
|
|
310
|
-
|
|
311
|
-
element.classList.remove('hover');
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
let newMenuItemIndex = menuItemIndex;
|
|
315
|
-
|
|
316
|
-
if (keyHit === 'ArrowDown') {
|
|
317
|
-
if (listItems[newMenuItemIndex + 1]) {
|
|
318
|
-
newMenuItemIndex = newMenuItemIndex + 1;
|
|
319
|
-
} else {
|
|
320
|
-
newMenuItemIndex = 0;
|
|
321
|
-
}
|
|
322
|
-
} else if (keyHit === 'ArrowUp') {
|
|
323
|
-
if (listItems[newMenuItemIndex - 1]) {
|
|
324
|
-
newMenuItemIndex = newMenuItemIndex - 1;
|
|
325
|
-
} else {
|
|
326
|
-
newMenuItemIndex = listItems.length - 1;
|
|
327
|
-
}
|
|
328
|
-
} else if (keyHit === 'Enter') {
|
|
329
|
-
onKeyBoardEnter(newMenuItemIndex);
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const targetItem = listItems[newMenuItemIndex] as HTMLLIElement;
|
|
334
|
-
|
|
335
|
-
targetItem.classList.add('hover');
|
|
336
|
-
|
|
337
|
-
targetItem.focus();
|
|
338
|
-
targetItem.scrollIntoView({ block: 'nearest' });
|
|
339
|
-
|
|
340
|
-
menuItemIndex = newMenuItemIndex;
|
|
318
|
+
onselectMod(targetOption.meta as SelectOption);
|
|
341
319
|
}
|
|
342
|
-
|
|
343
|
-
$effect(() => {
|
|
344
|
-
if (!menuRef) {
|
|
345
|
-
return;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
if (!open) {
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
const targetItem = menuRef.querySelector(':scope > li.dodo-ui-MenuItem.selected') as
|
|
353
|
-
| HTMLLIElement
|
|
354
|
-
| undefined;
|
|
355
|
-
|
|
356
|
-
if (targetItem) {
|
|
357
|
-
targetItem.classList.add('hover');
|
|
358
|
-
|
|
359
|
-
targetItem.focus();
|
|
360
|
-
targetItem.scrollIntoView({ block: 'nearest' });
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
window.addEventListener('keydown', onKeyboardNavigation);
|
|
364
|
-
|
|
365
|
-
return () => {
|
|
366
|
-
window.removeEventListener('keydown', onKeyboardNavigation);
|
|
367
|
-
};
|
|
368
|
-
});
|
|
369
320
|
</script>
|
|
370
321
|
|
|
322
|
+
{#snippet selectDropdownArrowIcon()}
|
|
323
|
+
<UtilityButton {size} title="Dropdown" onclick={onfocusMod}>
|
|
324
|
+
{#if customDropdownArrowIconTyped}
|
|
325
|
+
{@render customDropdownArrowIconTyped(open)}
|
|
326
|
+
{:else if open}
|
|
327
|
+
<Icon icon="material-symbols:arrow-drop-up-rounded" width="28" height="28" />
|
|
328
|
+
{:else}
|
|
329
|
+
<Icon icon="material-symbols:arrow-drop-down-rounded" width="28" height="28" />
|
|
330
|
+
{/if}
|
|
331
|
+
</UtilityButton>
|
|
332
|
+
{/snippet}
|
|
333
|
+
|
|
371
334
|
<div class={['dodo-ui-Select', className].join(' ')}>
|
|
372
|
-
<Popper
|
|
335
|
+
<Popper
|
|
336
|
+
fullWidth
|
|
337
|
+
{open}
|
|
338
|
+
{onClickOutside}
|
|
339
|
+
{...popperProps}
|
|
340
|
+
{popupMaxHeight}
|
|
341
|
+
{popupPositionX}
|
|
342
|
+
{popupPositionY}
|
|
343
|
+
{paperProps}
|
|
344
|
+
{lockPoistions}
|
|
345
|
+
{popperHeightForVerticalPosition}
|
|
346
|
+
>
|
|
373
347
|
<div
|
|
374
348
|
class:outline
|
|
375
349
|
class:disabled
|
|
@@ -392,6 +366,12 @@
|
|
|
392
366
|
{before}
|
|
393
367
|
{after}
|
|
394
368
|
>
|
|
369
|
+
{#if dropdownArrowPosition === 'before'}
|
|
370
|
+
<div class:before class:open class="DropdownArrow">
|
|
371
|
+
{@render selectDropdownArrowIcon()}
|
|
372
|
+
</div>
|
|
373
|
+
{/if}
|
|
374
|
+
|
|
395
375
|
<DynamicInput
|
|
396
376
|
type="text"
|
|
397
377
|
{name}
|
|
@@ -405,6 +385,9 @@
|
|
|
405
385
|
{onpaste}
|
|
406
386
|
{oncopy}
|
|
407
387
|
{oncut}
|
|
388
|
+
{onkeydown}
|
|
389
|
+
{onkeypress}
|
|
390
|
+
{onkeyup}
|
|
408
391
|
{placeholder}
|
|
409
392
|
value={searchable ? searchTerm : selectedOption?.label}
|
|
410
393
|
{readonly}
|
|
@@ -426,43 +409,50 @@
|
|
|
426
409
|
</UtilityButton>
|
|
427
410
|
</div>
|
|
428
411
|
{/if}
|
|
412
|
+
|
|
413
|
+
{#if dropdownArrowPosition === 'after'}
|
|
414
|
+
<div class:after class:open class="DropdownArrow">
|
|
415
|
+
{@render selectDropdownArrowIcon()}
|
|
416
|
+
</div>
|
|
417
|
+
{/if}
|
|
429
418
|
</InputEnclosure>
|
|
430
419
|
</div>
|
|
431
420
|
|
|
432
421
|
{#snippet popupChildren()}
|
|
433
422
|
{#if customPopupContentTyped}
|
|
434
|
-
{@render customPopupContentTyped(
|
|
423
|
+
{@render customPopupContentTyped(optionsRaw, selectedOption, onselectMod)}
|
|
435
424
|
{:else}
|
|
436
|
-
<
|
|
437
|
-
{
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
425
|
+
<DynamicMenu
|
|
426
|
+
bind:ref={menuRef}
|
|
427
|
+
{menuItemProps}
|
|
428
|
+
{options}
|
|
429
|
+
keyboardNavigation
|
|
430
|
+
onEnter={onKeyBoardEnter}
|
|
431
|
+
selectedOption={options.find((item) => item.meta?.value === selectedOption?.value)}
|
|
432
|
+
onclick={(_e, option: DynamicMenuItemOption) => onselectMod(option.meta as SelectOption)}
|
|
433
|
+
showOptionsPlaceholder
|
|
434
|
+
{...menuProps}
|
|
435
|
+
>
|
|
436
|
+
{#snippet customMenuItemContent(option, selectedOption)}
|
|
437
|
+
{#if customMenuItemContentTyped}
|
|
438
|
+
{@render customMenuItemContentTyped(
|
|
439
|
+
option?.meta as SelectOption,
|
|
440
|
+
(selectedOption?.meta as SelectOption).value ===
|
|
441
|
+
(option?.meta as SelectOption).value,
|
|
442
|
+
)}
|
|
443
|
+
{:else}
|
|
444
|
+
{(option?.meta as SelectOption).label}
|
|
445
|
+
{/if}
|
|
446
|
+
{/snippet}
|
|
447
|
+
|
|
448
|
+
{#snippet customPlaceholderMenuItemContent()}
|
|
449
|
+
{#if customPlaceholderMenuItemContentTyped}
|
|
450
|
+
{@render customPlaceholderMenuItemContentTyped()}
|
|
451
|
+
{:else}
|
|
452
|
+
{optionsPlaceholder}
|
|
453
|
+
{/if}
|
|
454
|
+
{/snippet}
|
|
455
|
+
</DynamicMenu>
|
|
466
456
|
{/if}
|
|
467
457
|
{/snippet}
|
|
468
458
|
</Popper>
|
|
@@ -478,6 +468,16 @@
|
|
|
478
468
|
margin-right: calc(var(--dodo-ui-space-small) * 2);
|
|
479
469
|
}
|
|
480
470
|
}
|
|
471
|
+
|
|
472
|
+
.DropdownArrow {
|
|
473
|
+
&.after {
|
|
474
|
+
margin-right: calc(var(--dodo-ui-space-small) * 2);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
&.before {
|
|
478
|
+
margin-right: calc(var(--dodo-ui-space-small) * 2);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
481
|
}
|
|
482
482
|
|
|
483
483
|
&--small {
|
|
@@ -486,6 +486,16 @@
|
|
|
486
486
|
margin-right: var(--dodo-ui-space);
|
|
487
487
|
}
|
|
488
488
|
}
|
|
489
|
+
|
|
490
|
+
.DropdownArrow {
|
|
491
|
+
&.after {
|
|
492
|
+
margin-right: var(--dodo-ui-space);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
&.before {
|
|
496
|
+
margin-right: var(--dodo-ui-space);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
489
499
|
}
|
|
490
500
|
|
|
491
501
|
&--large {
|
|
@@ -494,6 +504,16 @@
|
|
|
494
504
|
margin-right: calc(var(--dodo-ui-space) * 2);
|
|
495
505
|
}
|
|
496
506
|
}
|
|
507
|
+
|
|
508
|
+
.DropdownArrow {
|
|
509
|
+
&.after {
|
|
510
|
+
margin-right: calc(var(--dodo-ui-space) * 2);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
&.before {
|
|
514
|
+
margin-right: calc(var(--dodo-ui-space) * 2);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
497
517
|
}
|
|
498
518
|
}
|
|
499
519
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import Select, { type SelectOption } from '../Select.svelte';
|
|
4
|
+
import { selectOptions, storySelectArgTypes } from '../Select.stories.svelte';
|
|
5
|
+
|
|
6
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
7
|
+
const { Story } = defineMeta({
|
|
8
|
+
component: Select,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
argTypes: storySelectArgTypes,
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
story: {
|
|
14
|
+
height: '400px',
|
|
15
|
+
inline: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const options = selectOptions;
|
|
22
|
+
|
|
23
|
+
let value = $state<SelectOption>(options[0]);
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<Story name="Normal" args={{ options, value }} />
|
|
27
|
+
<Story name="Small" args={{ options, value, size: 'small' }} />
|
|
28
|
+
<Story name="Large" args={{ options, value, size: 'large' }} />
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import Select, { type SelectOption } from '../Select.svelte';
|
|
4
|
+
import { selectOptions, storySelectArgTypes } from '../Select.stories.svelte';
|
|
5
|
+
import Icon from '@iconify/svelte';
|
|
6
|
+
|
|
7
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
8
|
+
const { Story } = defineMeta({
|
|
9
|
+
component: Select,
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
argTypes: storySelectArgTypes,
|
|
12
|
+
parameters: {
|
|
13
|
+
docs: {
|
|
14
|
+
story: {
|
|
15
|
+
height: '400px',
|
|
16
|
+
inline: false,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const options = selectOptions;
|
|
23
|
+
|
|
24
|
+
let value = $state<SelectOption>(options[0]);
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<!-- Select icon in front. -->
|
|
28
|
+
<Story name="Icon Before" asChild>
|
|
29
|
+
<Select {value} {options}>
|
|
30
|
+
{#snippet before()}
|
|
31
|
+
<Icon icon="material-symbols:content-copy" />
|
|
32
|
+
{/snippet}
|
|
33
|
+
</Select>
|
|
34
|
+
</Story>
|
|
35
|
+
|
|
36
|
+
<!-- Select icon in front. -->
|
|
37
|
+
<Story name="Icon After" asChild>
|
|
38
|
+
<Select {value} {options}>
|
|
39
|
+
{#snippet after()}
|
|
40
|
+
<Icon icon="material-symbols:download-2" />
|
|
41
|
+
{/snippet}
|
|
42
|
+
</Select>
|
|
43
|
+
</Story>
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import TextInput, {
|
|
4
|
+
type TextInputClipboardEvent,
|
|
5
|
+
type TextInputFocusEvent,
|
|
6
|
+
type TextInputKeyboardEvent,
|
|
7
|
+
} from '../TextInput.svelte';
|
|
8
|
+
import { storyTextInputArgTypes } from '../TextInput.stories.svelte';
|
|
9
|
+
|
|
10
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
11
|
+
const { Story } = defineMeta({
|
|
12
|
+
component: TextInput,
|
|
13
|
+
tags: ['autodocs'],
|
|
14
|
+
argTypes: storyTextInputArgTypes,
|
|
15
|
+
});
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<Story
|
|
19
|
+
name="Input"
|
|
20
|
+
args={{
|
|
21
|
+
oninput: (e: Event) => {
|
|
22
|
+
const target = e.target as HTMLInputElement;
|
|
23
|
+
|
|
24
|
+
console.log('Input Event', target.value);
|
|
25
|
+
},
|
|
26
|
+
}}
|
|
27
|
+
/>
|
|
28
|
+
|
|
29
|
+
<Story
|
|
30
|
+
name="Change"
|
|
31
|
+
args={{
|
|
32
|
+
onchange: (e: Event) => {
|
|
33
|
+
const target = e.target as HTMLInputElement;
|
|
34
|
+
|
|
35
|
+
console.log('onChange Event', target.value);
|
|
36
|
+
},
|
|
37
|
+
}}
|
|
38
|
+
/>
|
|
39
|
+
|
|
40
|
+
<!-- `e: TextInputFocusEvent` -->
|
|
41
|
+
<Story
|
|
42
|
+
name="Focus"
|
|
43
|
+
args={{
|
|
44
|
+
onfocus: (e: TextInputFocusEvent) => {
|
|
45
|
+
const target = e.target as HTMLInputElement;
|
|
46
|
+
|
|
47
|
+
console.log('onfocus Event', target);
|
|
48
|
+
},
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
|
|
52
|
+
<!-- `e: TextInputFocusEvent` -->
|
|
53
|
+
<Story
|
|
54
|
+
name="Blur"
|
|
55
|
+
args={{
|
|
56
|
+
onblur: (e: TextInputFocusEvent) => {
|
|
57
|
+
const target = e.target as HTMLInputElement;
|
|
58
|
+
|
|
59
|
+
console.log('onblur Event', target);
|
|
60
|
+
},
|
|
61
|
+
}}
|
|
62
|
+
/>
|
|
63
|
+
|
|
64
|
+
<!-- `e: TextInputClipboardEvent` -->
|
|
65
|
+
<Story
|
|
66
|
+
name="Copy"
|
|
67
|
+
args={{
|
|
68
|
+
oncopy: (e: TextInputClipboardEvent) => {
|
|
69
|
+
const target = e.target as HTMLInputElement;
|
|
70
|
+
|
|
71
|
+
console.log('oncopy Event', target);
|
|
72
|
+
},
|
|
73
|
+
}}
|
|
74
|
+
/>
|
|
75
|
+
|
|
76
|
+
<!-- `e: TextInputClipboardEvent` -->
|
|
77
|
+
<Story
|
|
78
|
+
name="Cut"
|
|
79
|
+
args={{
|
|
80
|
+
oncut: (e: TextInputClipboardEvent) => {
|
|
81
|
+
const target = e.target as HTMLInputElement;
|
|
82
|
+
|
|
83
|
+
console.log('oncut Event', target);
|
|
84
|
+
},
|
|
85
|
+
}}
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
<!-- `e: TextInputClipboardEvent` -->
|
|
89
|
+
<Story
|
|
90
|
+
name="Paste"
|
|
91
|
+
args={{
|
|
92
|
+
onpaste: (e: TextInputClipboardEvent) => {
|
|
93
|
+
const target = e.target as HTMLInputElement;
|
|
94
|
+
|
|
95
|
+
console.log('onpaste Event', target);
|
|
96
|
+
},
|
|
97
|
+
}}
|
|
98
|
+
/>
|
|
99
|
+
|
|
100
|
+
<Story
|
|
101
|
+
name="KeyDown"
|
|
102
|
+
args={{
|
|
103
|
+
onkeydown: (e: TextInputKeyboardEvent) => {
|
|
104
|
+
console.log('onkeydown Event', e.key);
|
|
105
|
+
},
|
|
106
|
+
}}
|
|
107
|
+
/>
|
|
108
|
+
|
|
109
|
+
<Story
|
|
110
|
+
name="KeyPress"
|
|
111
|
+
args={{
|
|
112
|
+
onkeypress: (e: TextInputKeyboardEvent) => {
|
|
113
|
+
console.log('onkeypress Event', e.key);
|
|
114
|
+
},
|
|
115
|
+
}}
|
|
116
|
+
/>
|
|
117
|
+
|
|
118
|
+
<Story
|
|
119
|
+
name="KeyUp"
|
|
120
|
+
args={{
|
|
121
|
+
onkeyup: (e: TextInputKeyboardEvent) => {
|
|
122
|
+
console.log('onkeyup Event', e.key);
|
|
123
|
+
},
|
|
124
|
+
}}
|
|
125
|
+
/>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import TextInput from '../TextInput.svelte';
|
|
4
|
+
import { storyTextInputArgTypes } from '../TextInput.stories.svelte';
|
|
5
|
+
|
|
6
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
7
|
+
const { Story } = defineMeta({
|
|
8
|
+
component: TextInput,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
argTypes: storyTextInputArgTypes,
|
|
11
|
+
args: { value: 'Hello world!' },
|
|
12
|
+
});
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<Story name="Roundness 1" />
|
|
16
|
+
|
|
17
|
+
<Story name="Roundness 2" args={{ roundness: 2 }} />
|
|
18
|
+
|
|
19
|
+
<Story name="Roundness 3" args={{ roundness: 3 }} />
|
|
20
|
+
|
|
21
|
+
<Story name="Roundness 0" args={{ roundness: 0 }} />
|