@flightlesslabs/dodo-ui 0.7.2 → 0.8.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.
Files changed (98) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.js +3 -0
  3. package/dist/stories/components/Form/Select/Customize/Customize.stories.svelte +16 -1
  4. package/dist/stories/components/Form/Select/DropDownArrow/DropDownArrow.stories.svelte +59 -0
  5. package/dist/stories/components/Form/Select/DropDownArrow/DropDownArrow.stories.svelte.d.ts +18 -0
  6. package/dist/stories/components/Form/Select/Positions/AutoPosition/AutoPosition.stories.svelte +54 -0
  7. package/dist/stories/components/Form/Select/Positions/AutoPosition/AutoPosition.stories.svelte.d.ts +18 -0
  8. package/dist/stories/components/Form/Select/Positions/Positions.stories.svelte +83 -0
  9. package/dist/stories/components/Form/Select/Positions/Positions.stories.svelte.d.ts +18 -0
  10. package/dist/stories/components/Form/Select/Select.svelte +107 -123
  11. package/dist/stories/components/Form/Select/Select.svelte.d.ts +15 -2
  12. package/dist/stories/components/Layout/Menu/DynamicMenu/Customize/Customize.stories.svelte +28 -0
  13. package/dist/stories/components/Layout/Menu/DynamicMenu/Customize/Customize.stories.svelte.d.ts +18 -0
  14. package/dist/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.stories.svelte +51 -0
  15. package/dist/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.stories.svelte.d.ts +22 -0
  16. package/dist/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte +129 -0
  17. package/dist/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte.d.ts +81 -0
  18. package/dist/stories/components/Layout/Menu/DynamicMenu/Events/Events.stories.svelte +46 -0
  19. package/dist/stories/components/Layout/Menu/DynamicMenu/Events/Events.stories.svelte.d.ts +18 -0
  20. package/dist/stories/components/Layout/Menu/DynamicMenu/KeybaordNavigation/KeybaordNavigation.stories.svelte +27 -0
  21. package/dist/stories/components/Layout/Menu/DynamicMenu/KeybaordNavigation/KeybaordNavigation.stories.svelte.d.ts +18 -0
  22. package/dist/stories/components/Layout/Menu/DynamicMenu/Options/OptionFormat.mdx +72 -0
  23. package/dist/stories/components/Layout/Menu/MenuItem/MenuItem.svelte.d.ts +1 -1
  24. package/dist/stories/developer tools/components/DynamicInput/DynamicInput.svelte +1 -0
  25. package/package.json +15 -17
  26. package/src/lib/index.ts +13 -0
  27. package/src/lib/stories/Home.mdx +59 -0
  28. package/src/lib/stories/assets/dark-theme-toggle.png +0 -0
  29. package/src/lib/stories/components/Form/Button/Button.stories.svelte +61 -0
  30. package/src/lib/stories/components/Form/Button/Color/Color.stories.svelte +43 -0
  31. package/src/lib/stories/components/Form/Button/Events/Events.stories.svelte +36 -0
  32. package/src/lib/stories/components/Form/Button/IconButton/IconButton.stories.svelte +43 -0
  33. package/src/lib/stories/components/Form/Button/Roundness/Roundness.stories.svelte +23 -0
  34. package/src/lib/stories/components/Form/Button/Size/Size.stories.svelte +16 -0
  35. package/src/lib/stories/components/Form/Button/Variant/Variant.stories.svelte +18 -0
  36. package/src/lib/stories/components/Form/FormControl/FormControl.stories.svelte +28 -0
  37. package/src/lib/stories/components/Form/Label/Label.stories.svelte +13 -0
  38. package/src/lib/stories/components/Form/Message/Color/Color.stories.svelte +36 -0
  39. package/src/lib/stories/components/Form/Message/Message.stories.svelte +27 -0
  40. package/src/lib/stories/components/Form/Message/Size/Size.stories.svelte +22 -0
  41. package/src/lib/stories/components/Form/PasswordInput/Events/Events.stories.svelte +110 -0
  42. package/src/lib/stories/components/Form/PasswordInput/PasswordInput.stories.svelte +59 -0
  43. package/src/lib/stories/components/Form/PasswordInput/Roundness/Roundness.stories.svelte +20 -0
  44. package/src/lib/stories/components/Form/PasswordInput/Size/Size.stories.svelte +16 -0
  45. package/src/lib/stories/components/Form/PasswordInput/WithIcon/WithIcon.stories.svelte +31 -0
  46. package/src/lib/stories/components/Form/Select/Customize/Customize.stories.svelte +139 -0
  47. package/src/lib/stories/components/Form/Select/DropDownArrow/DropDownArrow.stories.svelte +63 -0
  48. package/src/lib/stories/components/Form/Select/Events/Events.stories.svelte +144 -0
  49. package/src/lib/stories/components/Form/Select/Options/OptionFormat.mdx +40 -0
  50. package/src/lib/stories/components/Form/Select/Positions/AutoPosition/AutoPosition.stories.svelte +58 -0
  51. package/src/lib/stories/components/Form/Select/Positions/Positions.stories.svelte +87 -0
  52. package/src/lib/stories/components/Form/Select/Roundness/Roundness.stories.svelte +32 -0
  53. package/src/lib/stories/components/Form/Select/Select.stories.svelte +121 -0
  54. package/src/lib/stories/components/Form/Select/Select.svelte +153 -146
  55. package/src/lib/stories/components/Form/Select/Size/Size.stories.svelte +28 -0
  56. package/src/lib/stories/components/Form/Select/WithIcon/WithIcon.stories.svelte +43 -0
  57. package/src/lib/stories/components/Form/TextInput/Events/Events.stories.svelte +97 -0
  58. package/src/lib/stories/components/Form/TextInput/Roundness/Roundness.stories.svelte +21 -0
  59. package/src/lib/stories/components/Form/TextInput/Size/Size.stories.svelte +17 -0
  60. package/src/lib/stories/components/Form/TextInput/TextInput.stories.svelte +43 -0
  61. package/src/lib/stories/components/Form/TextInput/WithIcon/WithIcon.stories.svelte +47 -0
  62. package/src/lib/stories/components/Layout/Menu/DynamicMenu/Customize/Customize.stories.svelte +30 -0
  63. package/src/lib/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.stories.svelte +56 -0
  64. package/src/lib/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte +262 -0
  65. package/src/lib/stories/components/Layout/Menu/DynamicMenu/Events/Events.stories.svelte +48 -0
  66. package/src/lib/stories/components/Layout/Menu/DynamicMenu/KeybaordNavigation/KeybaordNavigation.stories.svelte +29 -0
  67. package/src/lib/stories/components/Layout/Menu/DynamicMenu/Options/OptionFormat.mdx +72 -0
  68. package/src/lib/stories/components/Layout/Menu/Menu.stories.svelte +69 -0
  69. package/src/lib/stories/components/Layout/Menu/MenuItem/MenuItem.stories.svelte +34 -0
  70. package/src/lib/stories/components/Layout/Menu/MenuItem/MenuItem.svelte +1 -1
  71. package/src/lib/stories/components/Layout/Menu/MenuItem/Size/Size.stories.svelte +16 -0
  72. package/src/lib/stories/components/Layout/Menu/MenuItem/Type/Type.stories.svelte +21 -0
  73. package/src/lib/stories/components/Layout/Menu/Size/Size.stories.svelte +37 -0
  74. package/src/lib/stories/components/Layout/Paper/Color/Color.stories.svelte +63 -0
  75. package/src/lib/stories/components/Layout/Paper/Paper.stories.svelte +50 -0
  76. package/src/lib/stories/components/Layout/Paper/Roundness/Roundness.stories.svelte +25 -0
  77. package/src/lib/stories/components/Layout/Paper/Shadow/Shadow.stories.svelte +24 -0
  78. package/src/lib/stories/components/Layout/Separator/Color/Color.stories.svelte +19 -0
  79. package/src/lib/stories/components/Layout/Separator/Separator.stories.svelte +30 -0
  80. package/src/lib/stories/developer tools/Intro.mdx +9 -0
  81. package/src/lib/stories/developer tools/components/DynamicInput/DynamicInput.stories.svelte +53 -0
  82. package/src/lib/stories/developer tools/components/DynamicInput/DynamicInput.svelte +1 -0
  83. package/src/lib/stories/developer tools/components/DynamicInput/Size/Size.stories.svelte +17 -0
  84. package/src/lib/stories/developer tools/components/InputEnclosure/InputEnclosure.stories.svelte +38 -0
  85. package/src/lib/stories/developer tools/components/InputEnclosure/Roundness/Roundness.stories.svelte +20 -0
  86. package/src/lib/stories/developer tools/components/InputEnclosure/Size/Size.stories.svelte +16 -0
  87. package/src/lib/stories/developer tools/components/InputEnclosure/WithIcon/WithIcon.stories.svelte +47 -0
  88. package/src/lib/stories/developer tools/components/Popper/Popper.stories.svelte +124 -0
  89. package/src/lib/stories/developer tools/components/Popper/PopperPopup/PopperPopup.stories.svelte +64 -0
  90. package/src/lib/stories/developer tools/components/Popper/Positions/AutoPosition/AutoPosition.stories.svelte +92 -0
  91. package/src/lib/stories/developer tools/components/Popper/Positions/Positions.stories.svelte +114 -0
  92. package/src/lib/stories/developer tools/components/UtilityButton/Size/Size.stories.svelte +25 -0
  93. package/src/lib/stories/developer tools/components/UtilityButton/UtilityButton.stories.svelte +30 -0
  94. package/src/lib/stories/developer tools/directives/clickOutside/index.mdx +25 -0
  95. package/src/lib/stories/developer tools/philosophy/Colors/Colors.mdx +43 -0
  96. package/src/lib/stories/developer tools/philosophy/Colors/Colors.stories.svelte +22 -0
  97. package/src/lib/stories/developer tools/philosophy/Colors/Opacity.stories.svelte +11 -0
  98. package/src/lib/stories/developer tools/philosophy/Themes.mdx +23 -0
package/dist/index.d.ts CHANGED
@@ -38,6 +38,9 @@ export type { FormControlProps } from './stories/components/Form/FormControl/For
38
38
  /** Form: Message */
39
39
  export { default as Message } from './stories/components/Form/Message/Message.svelte';
40
40
  export type { MessageProps } from './stories/components/Form/Message/Message.svelte';
41
+ /** Form: Select */
42
+ export { default as Select } from './stories/components/Form/Select/Select.svelte';
43
+ export type { SelectOption, SelectDropdownArrowPosition, SelectProps, } from './stories/components/Form/Select/Select.svelte';
41
44
  /** Layout: Paper */
42
45
  export { default as Paper } from './stories/components/Layout/Paper/Paper.svelte';
43
46
  export type { PaperColor, PaperProps } from './stories/components/Layout/Paper/Paper.svelte';
@@ -49,3 +52,5 @@ export { default as Menu } from './stories/components/Layout/Menu/Menu.svelte';
49
52
  export type { MenuProps } from './stories/components/Layout/Menu/Menu.svelte';
50
53
  export { default as MenuItem } from './stories/components/Layout/Menu/MenuItem/MenuItem.svelte';
51
54
  export type { MenuItemType, MenuItemProps, } from './stories/components/Layout/Menu/MenuItem/MenuItem.svelte';
55
+ export { default as DynamicMenu } from './stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte';
56
+ export type { DynamicMenuItemOption, DynamicMenuProps, } from './stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte';
package/dist/index.js CHANGED
@@ -22,6 +22,8 @@ export { default as Label } from './stories/components/Form/Label/Label.svelte';
22
22
  export { default as FormControl } from './stories/components/Form/FormControl/FormControl.svelte';
23
23
  /** Form: Message */
24
24
  export { default as Message } from './stories/components/Form/Message/Message.svelte';
25
+ /** Form: Select */
26
+ export { default as Select } from './stories/components/Form/Select/Select.svelte';
25
27
  /** Layout: Paper */
26
28
  export { default as Paper } from './stories/components/Layout/Paper/Paper.svelte';
27
29
  /** Layout: Separator */
@@ -29,3 +31,4 @@ export { default as Separator } from './stories/components/Layout/Separator/Sepa
29
31
  /** Layout: Menu */
30
32
  export { default as Menu } from './stories/components/Layout/Menu/Menu.svelte';
31
33
  export { default as MenuItem } from './stories/components/Layout/Menu/MenuItem/MenuItem.svelte';
34
+ export { default as DynamicMenu } from './stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte';
@@ -3,6 +3,7 @@ import Select, {} from '../Select.svelte';
3
3
  import { selectOptions, storySelectArgTypes } from '../Select.stories.svelte';
4
4
  import { Menu } from '../../../../../index.js';
5
5
  import MenuItem from '../../../Layout/Menu/MenuItem/MenuItem.svelte';
6
+ import Icon from '@iconify/svelte';
6
7
  // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
7
8
  const { Story } = defineMeta({
8
9
  component: Select,
@@ -30,6 +31,19 @@ let value = $state(options[0]);
30
31
  </Select>
31
32
  </Story>
32
33
 
34
+ <!-- Format look and feel Dropdown Arrow icon -->
35
+ <Story name="CustomDropdownArrowIcon" asChild>
36
+ <Select {options} {value} onselect={(val: SelectOption) => (value = val)}>
37
+ {#snippet customDropdownArrowIcon(open)}
38
+ {#if open}
39
+ <Icon icon="mingcute:up-fill" width="24" height="24" />
40
+ {:else}
41
+ <Icon icon="mingcute:down-fill" width="24" height="24" />
42
+ {/if}
43
+ {/snippet}
44
+ </Select>
45
+ </Story>
46
+
33
47
  <!-- Format look and feel of Popper menu item. -->
34
48
  <Story name="CustomMenuItem" asChild>
35
49
  <Select {options} {value} onselect={(val: SelectOption) => (value = val)}>
@@ -51,13 +65,14 @@ let value = $state(options[0]);
51
65
  <!-- Format look and feel of Popup. -->
52
66
  <Story name="CustomPopup" asChild>
53
67
  <Select {options} {value}>
54
- {#snippet customPopupContent(options, selectedOption)}
68
+ {#snippet customPopupContent(options, selectedOption, onselect)}
55
69
  <Menu size="small" separator>
56
70
  {#each options as option (option.value)}
57
71
  <MenuItem
58
72
  type="button"
59
73
  disabled={option.disabled}
60
74
  selected={selectedOption.value === option.value}
75
+ onclick={() => onselect(option)}
61
76
  >
62
77
  <b>{option.label}</b>
63
78
  </MenuItem>
@@ -0,0 +1,59 @@
1
+ <script module lang="ts">import { defineMeta } from '@storybook/addon-svelte-csf';
2
+ import Select, {} from '../Select.svelte';
3
+ import { selectOptions, storySelectArgTypes } from '../Select.stories.svelte';
4
+ import Icon from '@iconify/svelte';
5
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
6
+ const { Story } = defineMeta({
7
+ component: Select,
8
+ tags: ['autodocs'],
9
+ argTypes: storySelectArgTypes,
10
+ parameters: {
11
+ docs: {
12
+ story: {
13
+ height: '400px',
14
+ inline: false,
15
+ },
16
+ },
17
+ },
18
+ });
19
+ const options = selectOptions;
20
+ let value = $state(options[0]);
21
+ </script>
22
+
23
+ <Story
24
+ name="PositionAfter"
25
+ args={{ options, value, onselect: (val: SelectOption) => (value = val) }}
26
+ />
27
+
28
+ <Story
29
+ name="PositionBefore"
30
+ args={{
31
+ options,
32
+ value,
33
+ onselect: (val: SelectOption) => (value = val),
34
+ dropdownArrowPosition: 'before',
35
+ }}
36
+ />
37
+
38
+ <Story
39
+ name="HideArrow"
40
+ args={{
41
+ options,
42
+ value,
43
+ onselect: (val: SelectOption) => (value = val),
44
+ dropdownArrowPosition: false,
45
+ }}
46
+ />
47
+
48
+ <!-- Format look and feel Dropdown Arrow icon -->
49
+ <Story name="CustomDropdownArrowIcon" asChild>
50
+ <Select {options} {value} onselect={(val: SelectOption) => (value = val)}>
51
+ {#snippet customDropdownArrowIcon(open)}
52
+ {#if open}
53
+ <Icon icon="mingcute:up-fill" width="24" height="24" />
54
+ {:else}
55
+ <Icon icon="mingcute:down-fill" width="24" height="24" />
56
+ {/if}
57
+ {/snippet}
58
+ </Select>
59
+ </Story>
@@ -0,0 +1,18 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const DropDownArrow: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type DropDownArrow = InstanceType<typeof DropDownArrow>;
18
+ export default DropDownArrow;
@@ -0,0 +1,54 @@
1
+ <script module lang="ts">import { defineMeta } from '@storybook/addon-svelte-csf';
2
+ import { selectOptions, storySelectArgTypes } from '../../Select.stories.svelte';
3
+ import Select, {} from '../../Select.svelte';
4
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
5
+ const { Story } = defineMeta({
6
+ component: Select,
7
+ tags: ['autodocs'],
8
+ argTypes: storySelectArgTypes,
9
+ parameters: {
10
+ docs: {
11
+ story: {
12
+ height: '200px',
13
+ inline: false,
14
+ },
15
+ },
16
+ },
17
+ });
18
+ const options = selectOptions;
19
+ let value = $state(options[0]);
20
+ </script>
21
+
22
+ <!-- Positions will auto adjust depending on the space on top and bottom -->
23
+ <Story
24
+ name="PositionAutoAdjust"
25
+ args={{
26
+ options,
27
+ value,
28
+ onselect: (val: SelectOption) => (value = val),
29
+ }}
30
+ />
31
+
32
+ <!-- Positions will not auto adjust if you use `lockPoistions` -->
33
+ <Story
34
+ name="LockPoistions"
35
+ args={{
36
+ options,
37
+ value,
38
+ onselect: (val: SelectOption) => (value = val),
39
+ popupPositionY: 'top',
40
+ lockPoistions: true,
41
+ }}
42
+ />
43
+
44
+ <!-- you can also adjust `popperHeightForVerticalPosition` to achive the same -->
45
+ <Story
46
+ name="HeightForVerticalPosition"
47
+ args={{
48
+ options,
49
+ value,
50
+ onselect: (val: SelectOption) => (value = val),
51
+ popupPositionY: 'top',
52
+ popperHeightForVerticalPosition: 3,
53
+ }}
54
+ />
@@ -0,0 +1,18 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const AutoPosition: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type AutoPosition = InstanceType<typeof AutoPosition>;
18
+ export default AutoPosition;
@@ -0,0 +1,83 @@
1
+ <script module lang="ts">import { defineMeta } from '@storybook/addon-svelte-csf';
2
+ import { selectOptions, storySelectArgTypes } from '../Select.stories.svelte';
3
+ import Select, {} from '../Select.svelte';
4
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
5
+ const { Story } = defineMeta({
6
+ component: Select,
7
+ tags: ['autodocs'],
8
+ argTypes: storySelectArgTypes,
9
+ parameters: {
10
+ layout: 'centered',
11
+ docs: {
12
+ story: {
13
+ height: '600px',
14
+ inline: false,
15
+ },
16
+ },
17
+ },
18
+ });
19
+ const options = selectOptions;
20
+ let value = $state(options[0]);
21
+ </script>
22
+
23
+ <Story
24
+ name="BottomLeft"
25
+ args={{ options, value, onselect: (val: SelectOption) => (value = val), popupMaxHeight: '200px' }}
26
+ />
27
+
28
+ <Story
29
+ name="BottomCenter"
30
+ args={{
31
+ options,
32
+ value,
33
+ onselect: (val: SelectOption) => (value = val),
34
+ popupPositionX: 'center',
35
+ popupMaxHeight: '200px',
36
+ }}
37
+ />
38
+
39
+ <Story
40
+ name="BottomRight"
41
+ args={{
42
+ options,
43
+ value,
44
+ onselect: (val: SelectOption) => (value = val),
45
+ popupPositionX: 'right',
46
+ popupMaxHeight: '200px',
47
+ }}
48
+ />
49
+
50
+ <Story
51
+ name="TopLeft"
52
+ args={{
53
+ options,
54
+ value,
55
+ onselect: (val: SelectOption) => (value = val),
56
+ popupPositionY: 'top',
57
+ popupMaxHeight: '200px',
58
+ }}
59
+ />
60
+
61
+ <Story
62
+ name="TopCenter"
63
+ args={{
64
+ options,
65
+ value,
66
+ onselect: (val: SelectOption) => (value = val),
67
+ popupPositionY: 'top',
68
+ popupPositionX: 'center',
69
+ popupMaxHeight: '200px',
70
+ }}
71
+ />
72
+
73
+ <Story
74
+ name="TopRight"
75
+ args={{
76
+ options,
77
+ value,
78
+ onselect: (val: SelectOption) => (value = val),
79
+ popupPositionY: 'top',
80
+ popupPositionX: 'right',
81
+ popupMaxHeight: '200px',
82
+ }}
83
+ />
@@ -0,0 +1,18 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const Positions: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type Positions = InstanceType<typeof Positions>;
18
+ export default Positions;
@@ -4,26 +4,35 @@
4
4
  <script lang="ts">import InputEnclosure from '../../../developer tools/components/InputEnclosure/InputEnclosure.svelte';
5
5
  import UtilityButton from '../../../developer tools/components/UtilityButton/UtilityButton.svelte';
6
6
  import Icon from '@iconify/svelte';
7
- import { DynamicInput, Menu, MenuItem, Popper, } from '../../../../index.js';
8
- let { size = 'normal', roundness = 1, outline = true, name, id, class: className = '', disabled = false, onchange, oninput, onselect, onblur, onfocus, onpaste, oncopy, oncut, before, after, error = false, value, placeholder, ref = $bindable(), readonly = false, searchable = false, clearable = false, onclear, options: optionsRaw, customInputContent: customInputContentInternal, customMenuItemContent: customMenuItemContentInternal, customPopupContent: customPopupContentInternal, customPlaceholderMenuItemContent: customPlaceholderMenuItemContentInternal, popupMaxHeight = '300px', paperProps, popperProps, menuProps, menuItemProps, optionsPlaceholder = 'No Options', } = $props();
7
+ import { DynamicInput, DynamicMenu, Popper, } from '../../../../index.js';
8
+ let { size = 'normal', roundness = 1, outline = true, name, id, class: className = '', disabled = false, onchange, oninput, onselect, onblur, onfocus, onpaste, oncopy, oncut, before, after, error = false, value, placeholder, ref = $bindable(), readonly = false, searchable = false, clearable = false, onclear, options: optionsRaw, customInputContent: customInputContentInternal, customMenuItemContent: customMenuItemContentInternal, customPopupContent: customPopupContentInternal, customPlaceholderMenuItemContent: customPlaceholderMenuItemContentInternal, customDropdownArrowIcon: customDropdownArrowIconInternal, popupMaxHeight = '300px', paperProps, popperProps, menuProps, menuItemProps, optionsPlaceholder = 'No Options', dropdownArrowPosition = 'after', popupPositionX, popupPositionY, lockPoistions, popperHeightForVerticalPosition, } = $props();
9
+ function convertOptionsToDynamicMenuItemOptions(options) {
10
+ const newOptions = options.map((option) => ({
11
+ id: `opt-${option.value}`,
12
+ disabled: option.disabled,
13
+ label: option.label,
14
+ meta: option,
15
+ type: 'button',
16
+ }));
17
+ return newOptions;
18
+ }
9
19
  let open = $state(false);
10
20
  let onInputStart = $state(false);
11
21
  const selectedOption = $derived(value);
12
22
  let searchTerm = $state(value?.label.trim() || '');
13
- let options = $state(optionsRaw);
23
+ let options = $state(convertOptionsToDynamicMenuItemOptions(optionsRaw));
14
24
  let menuRef = $state(undefined);
15
- let menuItemIndex = $state(0);
16
25
  $effect(() => {
17
26
  if (!onInputStart) {
18
- options = optionsRaw;
27
+ options = convertOptionsToDynamicMenuItemOptions(optionsRaw);
19
28
  return;
20
29
  }
21
30
  const searchTermSimplified = searchTerm.trim().toLowerCase();
22
31
  if (!searchTermSimplified) {
23
- options = optionsRaw;
32
+ options = convertOptionsToDynamicMenuItemOptions(optionsRaw);
24
33
  return;
25
34
  }
26
- options = optionsRaw.filter((item) => item.label.trim().toLowerCase().includes(searchTermSimplified));
35
+ options = convertOptionsToDynamicMenuItemOptions(optionsRaw).filter((item) => item?.meta?.label.trim().toLowerCase().includes(searchTermSimplified));
27
36
  });
28
37
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
38
  let customInputContentTyped = customInputContentInternal;
@@ -33,20 +42,14 @@ let customMenuItemContentTyped = customMenuItemContentInternal;
33
42
  let customPopupContentTyped = customPopupContentInternal;
34
43
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
44
  let customPlaceholderMenuItemContentTyped = customPlaceholderMenuItemContentInternal;
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ let customDropdownArrowIconTyped = customDropdownArrowIconInternal;
36
47
  function closeMenu() {
37
48
  open = false;
38
- menuItemIndex = 0;
39
49
  ref?.blur();
40
50
  }
41
51
  function openMenu() {
42
52
  open = true;
43
- const menuItemIndexNew = options.findIndex((item) => item.value === selectedOption?.value);
44
- if (menuItemIndexNew < 0) {
45
- menuItemIndex = 0;
46
- }
47
- else {
48
- menuItemIndex = menuItemIndexNew;
49
- }
50
53
  }
51
54
  function onfocusMod(e) {
52
55
  openMenu();
@@ -88,7 +91,8 @@ function onclearMod(e) {
88
91
  onclear(e);
89
92
  }
90
93
  }
91
- function onKeyBoardEnter(selectedItemIndex) {
94
+ function onKeyBoardEnter(e, selectedItemIndex) {
95
+ e.preventDefault();
92
96
  const targetOption = options[selectedItemIndex];
93
97
  if (!targetOption) {
94
98
  return;
@@ -96,86 +100,35 @@ function onKeyBoardEnter(selectedItemIndex) {
96
100
  if (targetOption.disabled) {
97
101
  return;
98
102
  }
99
- onselectMod(targetOption);
103
+ onselectMod(targetOption.meta);
100
104
  }
101
- function onKeyboardNavigation(e) {
102
- let keyHit = undefined;
103
- if (!menuRef) {
104
- return;
105
- }
106
- if (!open) {
107
- return;
108
- }
109
- switch (e.key) {
110
- case 'ArrowDown':
111
- case 'ArrowUp':
112
- case 'Enter':
113
- keyHit = e.key;
114
- e.preventDefault();
115
- break;
116
- default:
117
- break;
118
- }
119
- if (!keyHit) {
120
- return;
121
- }
122
- const listItems = menuRef.querySelectorAll(':scope > li.dodo-ui-MenuItem');
123
- if (!listItems.length) {
124
- return;
125
- }
126
- for (let index = 0; index < listItems.length; index++) {
127
- const element = listItems[index];
128
- element.classList.remove('hover');
129
- }
130
- let newMenuItemIndex = menuItemIndex;
131
- if (keyHit === 'ArrowDown') {
132
- if (listItems[newMenuItemIndex + 1]) {
133
- newMenuItemIndex = newMenuItemIndex + 1;
134
- }
135
- else {
136
- newMenuItemIndex = 0;
137
- }
138
- }
139
- else if (keyHit === 'ArrowUp') {
140
- if (listItems[newMenuItemIndex - 1]) {
141
- newMenuItemIndex = newMenuItemIndex - 1;
142
- }
143
- else {
144
- newMenuItemIndex = listItems.length - 1;
145
- }
146
- }
147
- else if (keyHit === 'Enter') {
148
- onKeyBoardEnter(newMenuItemIndex);
149
- return;
150
- }
151
- const targetItem = listItems[newMenuItemIndex];
152
- targetItem.classList.add('hover');
153
- targetItem.focus();
154
- targetItem.scrollIntoView({ block: 'nearest' });
155
- menuItemIndex = newMenuItemIndex;
156
- }
157
- $effect(() => {
158
- if (!menuRef) {
159
- return;
160
- }
161
- if (!open) {
162
- return;
163
- }
164
- const targetItem = menuRef.querySelector(':scope > li.dodo-ui-MenuItem.selected');
165
- if (targetItem) {
166
- targetItem.classList.add('hover');
167
- targetItem.focus();
168
- targetItem.scrollIntoView({ block: 'nearest' });
169
- }
170
- window.addEventListener('keydown', onKeyboardNavigation);
171
- return () => {
172
- window.removeEventListener('keydown', onKeyboardNavigation);
173
- };
174
- });
175
105
  </script>
176
106
 
107
+ {#snippet selectDropdownArrowIcon()}
108
+ <UtilityButton {size} title="Dropdown" onclick={onfocusMod}>
109
+ {#if customDropdownArrowIconTyped}
110
+ {@render customDropdownArrowIconTyped(open)}
111
+ {:else if open}
112
+ <Icon icon="material-symbols:arrow-drop-up-rounded" width="28" height="28" />
113
+ {:else}
114
+ <Icon icon="material-symbols:arrow-drop-down-rounded" width="28" height="28" />
115
+ {/if}
116
+ </UtilityButton>
117
+ {/snippet}
118
+
177
119
  <div class={['dodo-ui-Select', className].join(' ')}>
178
- <Popper fullWidth {open} {onClickOutside} {...popperProps} {popupMaxHeight} {paperProps}>
120
+ <Popper
121
+ fullWidth
122
+ {open}
123
+ {onClickOutside}
124
+ {...popperProps}
125
+ {popupMaxHeight}
126
+ {popupPositionX}
127
+ {popupPositionY}
128
+ {paperProps}
129
+ {lockPoistions}
130
+ {popperHeightForVerticalPosition}
131
+ >
179
132
  <div
180
133
  class:outline
181
134
  class:disabled
@@ -198,6 +151,12 @@ $effect(() => {
198
151
  {before}
199
152
  {after}
200
153
  >
154
+ {#if dropdownArrowPosition === 'before'}
155
+ <div class:before class:open class="DropdownArrow">
156
+ {@render selectDropdownArrowIcon()}
157
+ </div>
158
+ {/if}
159
+
201
160
  <DynamicInput
202
161
  type="text"
203
162
  {name}
@@ -232,43 +191,50 @@ $effect(() => {
232
191
  </UtilityButton>
233
192
  </div>
234
193
  {/if}
194
+
195
+ {#if dropdownArrowPosition === 'after'}
196
+ <div class:after class:open class="DropdownArrow">
197
+ {@render selectDropdownArrowIcon()}
198
+ </div>
199
+ {/if}
235
200
  </InputEnclosure>
236
201
  </div>
237
202
 
238
203
  {#snippet popupChildren()}
239
204
  {#if customPopupContentTyped}
240
- {@render customPopupContentTyped(options, selectedOption)}
205
+ {@render customPopupContentTyped(optionsRaw, selectedOption, onselectMod)}
241
206
  {:else}
242
- <Menu bind:ref={menuRef} {...menuProps}>
243
- {#if options.length}
244
- {#each options as option (option.value)}
245
- <MenuItem
246
- onclick={() => onselectMod(option)}
247
- type="button"
248
- disabled={option.disabled}
249
- selected={selectedOption?.value === option.value}
250
- {...menuItemProps}
251
- >
252
- {#if customMenuItemContentTyped}
253
- {@render customMenuItemContentTyped(
254
- option,
255
- selectedOption?.value === option.value,
256
- )}
257
- {:else}
258
- {option.label}
259
- {/if}
260
- </MenuItem>
261
- {/each}
262
- {:else}
263
- <MenuItem type="text" disabled={true} {...menuItemProps}>
264
- {#if customPlaceholderMenuItemContentTyped}
265
- {@render customPlaceholderMenuItemContentTyped()}
266
- {:else}
267
- {optionsPlaceholder}
268
- {/if}
269
- </MenuItem>
270
- {/if}
271
- </Menu>
207
+ <DynamicMenu
208
+ bind:ref={menuRef}
209
+ {menuItemProps}
210
+ {options}
211
+ keyboardNavigation
212
+ onEnter={onKeyBoardEnter}
213
+ selectedOption={options.find((item) => item.meta?.value === selectedOption?.value)}
214
+ onclick={(_e, option: DynamicMenuItemOption) => onselectMod(option.meta as SelectOption)}
215
+ showOptionsPlaceholder
216
+ {...menuProps}
217
+ >
218
+ {#snippet customMenuItemContent(option, selectedOption)}
219
+ {#if customMenuItemContentTyped}
220
+ {@render customMenuItemContentTyped(
221
+ option?.meta as SelectOption,
222
+ (selectedOption?.meta as SelectOption).value ===
223
+ (option?.meta as SelectOption).value,
224
+ )}
225
+ {:else}
226
+ {(option?.meta as SelectOption).label}
227
+ {/if}
228
+ {/snippet}
229
+
230
+ {#snippet customPlaceholderMenuItemContent()}
231
+ {#if customPlaceholderMenuItemContentTyped}
232
+ {@render customPlaceholderMenuItemContentTyped()}
233
+ {:else}
234
+ {optionsPlaceholder}
235
+ {/if}
236
+ {/snippet}
237
+ </DynamicMenu>
272
238
  {/if}
273
239
  {/snippet}
274
240
  </Popper>
@@ -277,9 +243,27 @@ $effect(() => {
277
243
  <style>.dodo-ui-Select .Select.size--normal .SelectClear.after {
278
244
  margin-right: calc(var(--dodo-ui-space-small) * 2);
279
245
  }
246
+ .dodo-ui-Select .Select.size--normal .DropdownArrow.after {
247
+ margin-right: calc(var(--dodo-ui-space-small) * 2);
248
+ }
249
+ .dodo-ui-Select .Select.size--normal .DropdownArrow.before {
250
+ margin-right: calc(var(--dodo-ui-space-small) * 2);
251
+ }
280
252
  .dodo-ui-Select .Select.size--small .SelectClear.after {
281
253
  margin-right: var(--dodo-ui-space);
282
254
  }
255
+ .dodo-ui-Select .Select.size--small .DropdownArrow.after {
256
+ margin-right: var(--dodo-ui-space);
257
+ }
258
+ .dodo-ui-Select .Select.size--small .DropdownArrow.before {
259
+ margin-right: var(--dodo-ui-space);
260
+ }
283
261
  .dodo-ui-Select .Select.size--large .SelectClear.after {
284
262
  margin-right: calc(var(--dodo-ui-space) * 2);
263
+ }
264
+ .dodo-ui-Select .Select.size--large .DropdownArrow.after {
265
+ margin-right: calc(var(--dodo-ui-space) * 2);
266
+ }
267
+ .dodo-ui-Select .Select.size--large .DropdownArrow.before {
268
+ margin-right: calc(var(--dodo-ui-space) * 2);
285
269
  }</style>