@witchcraft/ui 0.0.1 → 0.1.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 (155) hide show
  1. package/README.md +18 -28
  2. package/dist/module.d.mts +3 -1
  3. package/dist/module.d.ts +3 -1
  4. package/dist/module.json +2 -2
  5. package/dist/module.mjs +20 -11
  6. package/dist/runtime/assets/base.css +1 -1
  7. package/dist/runtime/assets/locales/en.json +2 -2
  8. package/dist/runtime/assets/tailwind.css +1 -1
  9. package/dist/runtime/assets/utils.css +1 -0
  10. package/dist/runtime/build/WitchcraftUiResolver.js +1 -1
  11. package/dist/runtime/components/Icon/Icon.vue +10 -5
  12. package/dist/runtime/components/LibButton/LibButton.vue +41 -46
  13. package/dist/runtime/components/LibCheckbox/LibCheckbox.vue +7 -3
  14. package/dist/runtime/components/LibColorInput/LibColorInput.vue +111 -36
  15. package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.d.ts +2 -0
  16. package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.js +26 -9
  17. package/dist/runtime/components/LibColorPicker/LibColorPicker.vue +242 -131
  18. package/dist/runtime/components/LibColorPicker/utils/safeConvertToHsva.d.ts +2 -0
  19. package/dist/runtime/components/LibColorPicker/utils/safeConvertToHsva.js +18 -0
  20. package/dist/runtime/components/LibColorPicker/utils/safeConvertToRgba.d.ts +2 -0
  21. package/dist/runtime/components/LibColorPicker/utils/safeConvertToRgba.js +17 -0
  22. package/dist/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.d.ts +2 -0
  23. package/dist/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.js +8 -0
  24. package/dist/runtime/components/LibColorPicker/utils/truncate.d.ts +1 -0
  25. package/dist/runtime/components/LibColorPicker/utils/truncate.js +5 -0
  26. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.js +1 -1
  27. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +11 -8
  28. package/dist/runtime/components/LibDatePicker/LibDatePicker.vue +4 -17
  29. package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue +192 -131
  30. package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue +183 -115
  31. package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue +3 -3
  32. package/dist/runtime/components/LibDebug/LibDebug.vue +15 -5
  33. package/dist/runtime/components/LibDevOnly/LibDevOnly.vue +1 -3
  34. package/dist/runtime/components/LibFileInput/LibFileInput.vue +54 -28
  35. package/dist/runtime/components/{LibInput/LibInput.stories.d.ts → LibInputDeprecated/LibInputDeprecated.stories.d.ts} +6 -6
  36. package/dist/runtime/components/{LibInput/LibInput.stories.js → LibInputDeprecated/LibInputDeprecated.stories.js} +64 -19
  37. package/{src/runtime/components/LibInput/LibInput.vue → dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue} +40 -33
  38. package/dist/runtime/components/LibLabel/LibLabel.vue +2 -2
  39. package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.d.ts +1 -1
  40. package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.js +5 -4
  41. package/dist/runtime/components/LibMultiValues/LibMultiValues.vue +11 -12
  42. package/dist/runtime/components/LibNotifications/LibNotification.vue +19 -10
  43. package/dist/runtime/components/LibNotifications/LibNotifications.stories.js +2 -2
  44. package/dist/runtime/components/LibNotifications/LibNotifications.vue +20 -11
  45. package/dist/runtime/components/LibPagination/LibPagination.stories.js +2 -2
  46. package/dist/runtime/components/LibPagination/LibPagination.vue +19 -19
  47. package/dist/runtime/components/LibPalette/LibPalette.vue +3 -3
  48. package/dist/runtime/components/LibPopup/LibPopup.stories.js +2 -2
  49. package/dist/runtime/components/LibPopup/LibPopup.vue +30 -66
  50. package/dist/runtime/components/LibProgressBar/LibProgressBar.vue +3 -1
  51. package/dist/runtime/components/LibRecorder/LibRecorder.vue +2 -2
  52. package/dist/runtime/components/LibRoot/LibRoot.vue +14 -1
  53. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.stories.js +1 -1
  54. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue +5 -7
  55. package/dist/runtime/components/LibSuggestions/LibSuggestions.vue +42 -25
  56. package/dist/runtime/components/LibTable/LibTable.vue +8 -8
  57. package/dist/runtime/components/Scrolling.stories.d.ts +6 -0
  58. package/dist/runtime/components/Scrolling.stories.js +44 -0
  59. package/dist/runtime/components/Template/NAME.vue +1 -1
  60. package/dist/runtime/components/TestControls/TestControls.vue +1 -1
  61. package/dist/runtime/components/index.d.ts +12 -11
  62. package/dist/runtime/components/index.js +12 -11
  63. package/dist/runtime/components/shared/props.d.ts +81 -16
  64. package/dist/runtime/components/shared/storyHelpers/playInput.js +5 -5
  65. package/dist/runtime/components/shared/storyHelpers/playSuggestions.js +15 -11
  66. package/dist/runtime/composables/index.d.ts +5 -0
  67. package/dist/runtime/composables/index.js +5 -0
  68. package/dist/runtime/composables/useDivideAttrs.js +1 -0
  69. package/dist/runtime/composables/useDragWithThreshold.d.ts +71 -0
  70. package/dist/runtime/composables/useDragWithThreshold.js +40 -0
  71. package/dist/runtime/composables/usePreHydrationValue.d.ts +12 -0
  72. package/dist/runtime/composables/usePreHydrationValue.js +15 -0
  73. package/dist/runtime/composables/useSetupI18n.d.ts +2 -0
  74. package/dist/runtime/composables/useSetupI18n.js +5 -1
  75. package/dist/runtime/composables/useSuggestions.d.ts +7 -5
  76. package/dist/runtime/composables/useSuggestions.js +94 -57
  77. package/dist/runtime/directives/vResizableCols.js +3 -1
  78. package/dist/runtime/helpers/NotificationHandler.d.ts +5 -0
  79. package/dist/runtime/helpers/index.d.ts +3 -1
  80. package/dist/runtime/helpers/index.js +3 -1
  81. package/dist/runtime/types/index.d.ts +6 -0
  82. package/dist/runtime/utils/notifyIfError.d.ts +14 -0
  83. package/dist/runtime/utils/notifyIfError.js +29 -0
  84. package/package.json +18 -20
  85. package/src/module.ts +31 -12
  86. package/src/runtime/assets/base.css +10 -1
  87. package/src/runtime/assets/locales/en.json +2 -2
  88. package/src/runtime/assets/tailwind.css +1 -1
  89. package/src/runtime/assets/{style.css → utils.css} +86 -4
  90. package/src/runtime/build/WitchcraftUiResolver.ts +1 -1
  91. package/src/runtime/components/Icon/Icon.vue +10 -5
  92. package/src/runtime/components/LibButton/LibButton.vue +41 -46
  93. package/src/runtime/components/LibCheckbox/LibCheckbox.vue +7 -3
  94. package/src/runtime/components/LibColorInput/LibColorInput.vue +111 -36
  95. package/src/runtime/components/LibColorPicker/LibColorPicker.stories.ts +25 -4
  96. package/src/runtime/components/LibColorPicker/LibColorPicker.vue +242 -131
  97. package/src/runtime/components/LibColorPicker/utils/safeConvertToHsva.ts +25 -0
  98. package/src/runtime/components/LibColorPicker/utils/safeConvertToRgba.ts +23 -0
  99. package/src/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.ts +13 -0
  100. package/src/runtime/components/LibColorPicker/utils/truncate.ts +6 -0
  101. package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.ts +1 -1
  102. package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +11 -8
  103. package/src/runtime/components/LibDatePicker/LibDatePicker.vue +4 -17
  104. package/src/runtime/components/LibDatePicker/LibRangeDatePicker.vue +192 -131
  105. package/src/runtime/components/LibDatePicker/LibSingleDatePicker.vue +183 -115
  106. package/src/runtime/components/LibDatePicker/LibTimeZonePicker.vue +3 -3
  107. package/src/runtime/components/LibDebug/LibDebug.vue +15 -5
  108. package/src/runtime/components/LibDevOnly/LibDevOnly.vue +1 -3
  109. package/src/runtime/components/LibFileInput/LibFileInput.vue +54 -28
  110. package/src/runtime/components/{LibInput/LibInput.stories.ts → LibInputDeprecated/LibInputDeprecated.stories.ts} +64 -19
  111. package/{dist/runtime/components/LibInput/LibInput.vue → src/runtime/components/LibInputDeprecated/LibInputDeprecated.vue} +40 -33
  112. package/src/runtime/components/LibLabel/LibLabel.vue +2 -2
  113. package/src/runtime/components/LibMultiValues/LibMultiValues.stories.ts +5 -4
  114. package/src/runtime/components/LibMultiValues/LibMultiValues.vue +11 -12
  115. package/src/runtime/components/LibNotifications/LibNotification.vue +19 -10
  116. package/src/runtime/components/LibNotifications/LibNotifications.stories.ts +2 -2
  117. package/src/runtime/components/LibNotifications/LibNotifications.vue +20 -11
  118. package/src/runtime/components/LibPagination/LibPagination.stories.ts +2 -2
  119. package/src/runtime/components/LibPagination/LibPagination.vue +19 -19
  120. package/src/runtime/components/LibPalette/LibPalette.vue +3 -3
  121. package/src/runtime/components/LibPopup/LibPopup.stories.ts +2 -2
  122. package/src/runtime/components/LibPopup/LibPopup.vue +30 -66
  123. package/src/runtime/components/LibProgressBar/LibProgressBar.vue +3 -1
  124. package/src/runtime/components/LibRecorder/LibRecorder.vue +2 -2
  125. package/src/runtime/components/LibRoot/LibRoot.vue +14 -1
  126. package/src/runtime/components/LibSimpleInput/LibSimpleInput.stories.ts +1 -1
  127. package/src/runtime/components/LibSimpleInput/LibSimpleInput.vue +5 -7
  128. package/src/runtime/components/LibSuggestions/LibSuggestions.vue +42 -25
  129. package/src/runtime/components/LibTable/LibTable.vue +8 -8
  130. package/src/runtime/components/Scrolling.stories.ts +58 -0
  131. package/src/runtime/components/Template/NAME.vue +1 -1
  132. package/src/runtime/components/TestControls/TestControls.vue +1 -1
  133. package/src/runtime/components/index.ts +12 -12
  134. package/src/runtime/components/shared/props.ts +82 -19
  135. package/src/runtime/components/shared/storyHelpers/playInput.ts +6 -5
  136. package/src/runtime/components/shared/storyHelpers/playSuggestions.ts +25 -11
  137. package/src/runtime/composables/index.ts +5 -0
  138. package/src/runtime/composables/useDarkMode.ts +2 -2
  139. package/src/runtime/composables/useDivideAttrs.ts +1 -0
  140. package/src/runtime/composables/useDragWithThreshold.ts +108 -0
  141. package/src/runtime/composables/usePreHydrationValue.ts +30 -0
  142. package/src/runtime/composables/useSetupI18n.ts +8 -2
  143. package/src/runtime/composables/useSuggestions.ts +92 -45
  144. package/src/runtime/directives/vResizableCols.ts +3 -1
  145. package/src/runtime/helpers/NotificationHandler.ts +5 -0
  146. package/src/runtime/helpers/index.ts +3 -1
  147. package/src/runtime/types/index.ts +5 -0
  148. package/src/runtime/utils/notifyIfError.ts +45 -0
  149. package/dist/runtime/assets/style.css +0 -1
  150. package/dist/runtime/helpers/addValue.d.ts +0 -1
  151. package/dist/runtime/helpers/addValue.js +0 -8
  152. package/src/runtime/helpers/addValue.ts +0 -10
  153. /package/dist/runtime/components/{reset.stories.d.ts → Reset.stories.d.ts} +0 -0
  154. /package/dist/runtime/components/{reset.stories.js → Reset.stories.js} +0 -0
  155. /package/src/runtime/components/{reset.stories.ts → Reset.stories.ts} +0 -0
@@ -1,15 +1,12 @@
1
1
  import type { StoryObj } from "@storybook/vue3";
2
- import LibInput from "./LibInput.vue.js";
2
+ import LibInputDeprecated from "./LibInputDeprecated.vue.js";
3
3
  declare const meta: {
4
4
  component: any;
5
5
  title: string;
6
- args: {
7
- border: boolean;
8
- label: string;
9
- };
6
+ args: any;
10
7
  };
11
8
  export default meta;
12
- type Story = StoryObj<typeof LibInput>;
9
+ type Story = StoryObj<typeof LibInputDeprecated>;
13
10
  export declare const Primary: Story;
14
11
  export declare const Disabled: Story;
15
12
  export declare const Readonly: Story;
@@ -19,14 +16,17 @@ export declare const AttrsDate: Story;
19
16
  export declare const AttrsNumber: Story;
20
17
  export declare const Borderless: any;
21
18
  export declare const WithAutosuggest: any;
19
+ export declare const WithAutosuggestNoLabel: any;
22
20
  export declare const WithInstantAutosuggest: any;
23
21
  export declare const AutosuggestRestricted: any;
22
+ export declare const AutosuggestRestrictedWithClearOnClick: any;
24
23
  export declare const AutosuggestSelectLikeShowAllUnrestricted: any;
25
24
  export declare const AutosuggestObjectOptions: any;
26
25
  export declare const Slots: Story;
27
26
  /** Press enter to add a value. */
28
27
  export declare const WithMultipleValues: Story;
29
28
  export declare const WithMultipleValuesWithSuggestions: any;
29
+ export declare const WithMultipleValuesWithSuggestionsNoSelected: any;
30
30
  export declare const WithMultipleValuesDisabled: any;
31
31
  export declare const WithMultipleValuesReadonly: any;
32
32
  export declare const InputSlotReplacement: Story;
@@ -1,5 +1,5 @@
1
1
  import { ref, watchEffect } from "vue";
2
- import LibInput from "./LibInput.vue";
2
+ import LibInputDeprecated from "./LibInputDeprecated.vue";
3
3
  import IconFaChevronLeft from "~icons/fa6-solid/chevron-left";
4
4
  import IconFaChevronRight from "~icons/fa6-solid/chevron-right";
5
5
  import IconFaSolidKeyboard from "~icons/fa6-solid/keyboard";
@@ -18,17 +18,20 @@ import {
18
18
  playBasicSelect
19
19
  } from "../shared/storyHelpers/playSuggestions.js";
20
20
  const meta = {
21
- component: LibInput,
22
- title: "Components/Input",
21
+ component: LibInputDeprecated,
22
+ title: "Components/Combobox",
23
23
  args: {
24
24
  border: true,
25
- label: "Some Label"
25
+ label: "Some Label",
26
+ ...{
27
+ _template: void 0
28
+ }
26
29
  }
27
30
  };
28
31
  export default meta;
29
32
  const allComponents = {
30
33
  ...components,
31
- LibInput,
34
+ LibInputDeprecated,
32
35
  Icon,
33
36
  IconFaChevronRight,
34
37
  IconFaChevronLeft,
@@ -41,7 +44,8 @@ const playAutosuggestSelectLike = async (context) => {
41
44
  await playBasicClickSelect(context);
42
45
  };
43
46
  const setupModelValue = (args) => ({
44
- modelValue: ref(args.modelValue ?? "")
47
+ modelValue: ref(args.modelValue ?? ""),
48
+ inputValue: ref(args.inputValue ?? "")
45
49
  });
46
50
  const setupModelValues = (args) => ({
47
51
  values: ref(args.values ?? void 0)
@@ -57,16 +61,17 @@ const Base = {
57
61
  updateOnlyOnSubmit: args.suggestions !== void 0
58
62
  }
59
63
  }),
60
- template: `
64
+ template: args._template ?? `
61
65
  Model Value: <span class="inline-block" data-testid="model-value">{{modelValue}}</span>
62
66
 
63
- <lib-input
67
+ <lib-simple-input-deprecated
64
68
  v-bind="args"
65
69
  v-model:values="values"
70
+ v-model:inputValue="inputValue"
66
71
  v-model="modelValue"
67
72
  @submit="modelValue = $event"
68
73
  >
69
- </lib-input>
74
+ </lib-simple-input-deprecated>
70
75
  `
71
76
  })
72
77
  };
@@ -124,6 +129,14 @@ export const WithAutosuggest = {
124
129
  },
125
130
  play: playAutosuggestSelectLike
126
131
  };
132
+ export const WithAutosuggestNoLabel = {
133
+ ...Base,
134
+ args: {
135
+ label: void 0,
136
+ suggestions: ["A", "AB", "ABC", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
137
+ },
138
+ play: playAutosuggestSelectLike
139
+ };
127
140
  export const WithInstantAutosuggest = {
128
141
  ...Base,
129
142
  args: {
@@ -138,6 +151,29 @@ export const AutosuggestRestricted = {
138
151
  },
139
152
  play: playAutosuggestSelectLike
140
153
  };
154
+ export const AutosuggestRestrictedWithClearOnClick = {
155
+ ...WithAutosuggest,
156
+ args: {
157
+ ...WithAutosuggest.args,
158
+ restrictToSuggestions: true,
159
+ _template: `
160
+ Model Value: <span class="inline-block" data-testid="model-value">{{modelValue}}</span>
161
+
162
+ Temp Value: <span class="inline-block" data-testid="temp-value">{{inputValue}}</span>
163
+
164
+ <lib-simple-input-deprecated
165
+ v-bind="args"
166
+ v-model:values="values"
167
+ v-model:inputValue="inputValue"
168
+ v-model="modelValue"
169
+ @submit="modelValue = $event"
170
+ @click="inputValue = ''"
171
+ >
172
+ </lib-simple-input-deprecated>
173
+ `
174
+ },
175
+ play: null
176
+ };
141
177
  export const AutosuggestSelectLikeShowAllUnrestricted = {
142
178
  ...WithAutosuggest,
143
179
  args: {
@@ -177,7 +213,7 @@ export const Slots = {
177
213
  Model Value: <span class="inline-block" data-testid="model-value">{{modelValue}}</span>
178
214
 
179
215
 
180
- <lib-input
216
+ <lib-simple-input-deprecated
181
217
  v-bind="args"
182
218
  v-model="modelValue"
183
219
  v-model:values="values"
@@ -195,7 +231,7 @@ export const Slots = {
195
231
  <icon><icon-fa-chevron-right/></icon>
196
232
  </lib-button>
197
233
  </template>
198
- </lib-input>
234
+ </lib-simple-input-deprecated>
199
235
  `
200
236
  })
201
237
  };
@@ -213,17 +249,17 @@ const MultipleValuesBase = {
213
249
  <br/>
214
250
  Values: <span class="inline-block" data-testid="values">{{values.join(", ")}}</span>
215
251
 
216
- <lib-input
252
+ <lib-simple-input-deprecated
217
253
  v-bind="args"
218
254
  v-model="modelValue"
219
255
  v-model:values="values"
220
256
  >
221
257
  <template #left>
222
- <lib-button class="px-0" :border="false">
258
+ <lib-button class="px-0" :border="false" :disabled="args.disabled || args.readonly">
223
259
  <icon><icon-fa-solid-tags/></icon>
224
260
  </lib-button>
225
261
  </template>
226
- </lib-input>
262
+ </lib-simple-input-deprecated>
227
263
  `
228
264
  }),
229
265
  args: {
@@ -242,6 +278,15 @@ export const WithMultipleValuesWithSuggestions = {
242
278
  },
243
279
  play: playAutosuggestSelectLike
244
280
  };
281
+ export const WithMultipleValuesWithSuggestionsNoSelected = {
282
+ ...MultipleValuesBase,
283
+ args: {
284
+ ...MultipleValuesBase.args,
285
+ suggestions: ["A", "AB", "ABC", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"],
286
+ showSelectedValues: false
287
+ },
288
+ play: playAutosuggestSelectLike
289
+ };
245
290
  export const WithMultipleValuesDisabled = {
246
291
  ...MultipleValuesBase,
247
292
  args: {
@@ -287,7 +332,7 @@ export const InputSlotReplacement = {
287
332
  <br/>
288
333
  Recording: <span class="inline-block" data-testid="recording">{{recording}}</span>
289
334
 
290
- <lib-input
335
+ <lib-simple-input-deprecated
291
336
  v-bind="args"
292
337
  v-model="modelValue"
293
338
  v-model:values="values"
@@ -308,7 +353,7 @@ export const InputSlotReplacement = {
308
353
  <template #left>
309
354
  <icon><icon-fa-solid-keyboard/></icon>
310
355
  </template>
311
- </lib-input>
356
+ </lib-simple-input-deprecated>
312
357
  `
313
358
  }),
314
359
  args: {
@@ -325,13 +370,13 @@ export const NextToButton = {
325
370
  }),
326
371
  template: `
327
372
  <div class="flex gap-2 items-center">
328
- <lib-input
373
+ <lib-simple-input-deprecated
329
374
  v-bind="args"
330
375
  v-model:values="values"
331
376
  v-model="modelValue"
332
- :label="undefined"
377
+ :label="undefined"
333
378
  >
334
- </lib-input>
379
+ </lib-simple-input-deprecated>
335
380
  <lib-button>Button</lib-button>
336
381
  </div>
337
382
  `
@@ -1,12 +1,13 @@
1
1
  <template>
2
2
  <div
3
- :class="twMerge(`input wrapper
3
+ :class="twMerge(`input--outer-wrapper
4
4
  grow
5
5
  flex
6
6
  flex-wrap
7
7
  `,
8
8
  disabled && `
9
9
  text-neutral-400
10
+ dark:text-neutral-600
10
11
  `,
11
12
  ($.wrapperAttrs as any)?.class,
12
13
  )"
@@ -20,13 +21,14 @@
20
21
  :disabled="disabled"
21
22
  :readonly="readonly"
22
23
  :valid="valid"
24
+ class="input--label"
23
25
  >
24
26
  <slot v-bind="slotProps">
25
27
  {{ label }}
26
28
  </slot>
27
29
  </lib-label>
28
30
  <!-- Allow blurring when clicking the blank part of a label. -->
29
- <div class="flex-1"/>
31
+ <div class="input--label-spacer flex-1"/>
30
32
  </slot>
31
33
  <!-- These are mostly copies of the classes on LibSimpleInput except made to work with disabled/readonly/etc manually since a div cannot have these states. -->
32
34
  <div
@@ -36,7 +38,7 @@
36
38
  :data-read-only="readonly"
37
39
  :data-is-open="isOpen"
38
40
  v-bind="{...$['inner-wrapperAttrs'], class:undefined}"
39
- :class="twMerge(`inner-wrapper
41
+ :class="twMerge(`input--inner-wrapper
40
42
  relative
41
43
  flex
42
44
  flex-1
@@ -55,7 +57,7 @@
55
57
  isOpen && `rounded-b-none`,
56
58
  !valid && `
57
59
  border-danger-700
58
- outlined:!ring-danger-700
60
+ outlined:!outline-danger-700
59
61
  text-danger-800
60
62
  dark:text-danger-400
61
63
  dark:border-danger-600
@@ -79,7 +81,7 @@
79
81
  <slot name="input" v-bind="{ ...inputProps, ...slotProps, suggestionsIndicatorClickHandler }">
80
82
  <lib-simple-input
81
83
  :class="twMerge(
82
- `p-0`,
84
+ `input--input p-0`,
83
85
  !$slots.left && `-ml-2 pl-2`,
84
86
  !$slots.right && (!$values || $values.length === 0) && !suggestions && `-mr-2 -pr-2`,
85
87
  ($.attrs as any)?.class,
@@ -88,12 +90,11 @@
88
90
  />
89
91
  </slot>
90
92
  <slot name="indicator" v-bind="{isOpen, suggestionsIndicatorClickHandler }">
93
+ <!-- todo, convert to button for accessibility ? -->
91
94
  <div
92
95
  v-if="suggestions"
93
96
  :data-is-open="isOpen"
94
- :class="twMerge(
95
- `indicator flex flex-col justify-center`,
96
- )"
97
+ :class="twMerge(`input--indicator flex flex-col justify-center`)"
97
98
  @click="suggestionsIndicatorClickHandler"
98
99
  >
99
100
  <icon :class="isOpen && `rotate-180`"> <i-fa6-solid-chevron-up/> </icon>
@@ -106,13 +107,12 @@
106
107
  <template v-if="$values && $values.length > 0">
107
108
  <lib-multi-values
108
109
  :class="twMerge(`
110
+ input--multivalues
109
111
  grow-[9000]
110
112
  justify-space-between
111
113
  py-1
112
114
  `,
113
- !$slots.right && `
114
- -mr-1
115
- `,
115
+ !$slots.right && `-mr-1`,
116
116
  ($.multivaluesAttrs as any)?.class,
117
117
  )"
118
118
  v-bind="multivaluesProps"
@@ -125,6 +125,7 @@
125
125
  <!-- todo 1px needs to be abstracted to var -->
126
126
  <lib-suggestions
127
127
  :class="twMerge(`
128
+ input--suggestions
128
129
  absolute
129
130
  -inset-x-px
130
131
  z-10
@@ -151,32 +152,31 @@
151
152
  </template>
152
153
  <script setup lang="ts">
153
154
  import { isBlank } from "@alanscodelog/utils/isBlank.js"
155
+ import { isObject } from "@alanscodelog/utils/isObject.js"
154
156
  import { pushIfNotIn } from "@alanscodelog/utils/pushIfNotIn.js"
155
- import type { MakeRequired } from "@alanscodelog/utils/types"
156
- import { computed,type HTMLAttributes,type InputHTMLAttributes, nextTick, type PropType, ref, toRef, useSlots, watch } from "vue"
157
+ import { computed,type HTMLAttributes,type InputHTMLAttributes, nextTick, onBeforeMount, ref, toRef, useSlots, watch } from "vue"
157
158
  import type { ComponentExposed } from "vue-component-type-helpers"
158
159
 
159
160
  import { useDivideAttrs } from "../../composables/useDivideAttrs.js"
160
161
  import { useSuggestionsInputAria } from "../../composables/useSuggestions.js"
161
- import { hasModifiers } from "../../helpers/hasModifiers.js"
162
162
  import { twMerge } from "../../utils/twMerge.js"
163
163
  import Icon from "../Icon/Icon.vue"
164
164
  import LibLabel from "../LibLabel/LibLabel.vue"
165
165
  import LibMultiValues from "../LibMultiValues/LibMultiValues.vue"
166
166
  import LibSimpleInput from "../LibSimpleInput/LibSimpleInput.vue"
167
167
  import LibSuggestions from "../LibSuggestions/LibSuggestions.vue"
168
- import { type BaseInteractiveProps, baseInteractivePropsDefaults, getFallbackId,type LabelProps, type LinkableByIdProps, type MultiValueProps, type SuggestionsProps, type TailwindClassProp, type WrapperProps } from "../shared/props.js"
168
+ import { type BaseInteractiveProps, baseInteractivePropsDefaults, getFallbackId, type LabelProps, type LinkableByIdProps, type SuggestionsProps, type TailwindClassProp, type WrapperProps } from "../shared/props.js"
169
169
 
170
170
 
171
171
  /* #region base */
172
172
  defineOptions({
173
- name: "lib-input",
173
+ name: "lib-simple-input-deprecated",
174
174
  inheritAttrs: false,
175
175
  })
176
176
  const $slots = useSlots()
177
177
  const emit = defineEmits<{
178
- (e: "submit", val: string, suggestion?: any): void
179
178
  (e: "input", val: InputEvent): void
179
+ (e: "submit", val: string, suggestion?: any): void
180
180
  (e: "keydown", val: KeyboardEvent): void
181
181
  (e: "blur", val: FocusEvent): void
182
182
  (e: "focus", val: FocusEvent): void
@@ -224,9 +224,17 @@ const suggestionsIndicatorClickHandler = (e: MouseEvent) => {
224
224
 
225
225
  const handleKeydown = (e: KeyboardEvent) => {
226
226
  if (props.suggestions) {
227
- (suggestionsComponent.value as any)?.inputKeydownHandler?.(e)
227
+ if (e.key === "Enter" && activeSuggestion.value === -1 && $values.value) {
228
+ pushIfNotIn($values.value, [$inputValue.value])
229
+ $inputValue.value = ""
230
+ $modelValue.value = ""
231
+ } else {
232
+ (suggestionsComponent.value as any)?.inputKeydownHandler?.(e)
233
+ if ($values.value) {
234
+ $modelValue.value = ""
235
+ }
236
+ }
228
237
  }
229
-
230
238
  emit("keydown", e)
231
239
  }
232
240
  const handleBlur = (e: FocusEvent) => {
@@ -245,9 +253,7 @@ const handleFocus = (e: FocusEvent) => {
245
253
  function addValue(val: string) {
246
254
  if ($values.value === undefined) return
247
255
  if (isBlank(val)) return
248
- props.preventDuplicateValues
249
- ? pushIfNotIn($values.value, [val])
250
- : $values.value.push(val)
256
+ pushIfNotIn($values.value, [val])
251
257
  $inputValue.value = ""
252
258
  $modelValue.value = ""
253
259
  }
@@ -276,7 +282,7 @@ const inputProps = computed(() => ({
276
282
  },
277
283
  onSubmit: (e: string) => {
278
284
  if (!props.suggestions) {
279
- $modelValue.value = e
285
+ $modelValue.value = $values.value ? "" : e
280
286
  emit("submit", e)
281
287
  if ($values.value) {
282
288
  addValue(e)
@@ -289,7 +295,7 @@ const inputProps = computed(() => ({
289
295
  class: undefined,
290
296
  }))
291
297
 
292
- function slotSubmit(val: any): void {
298
+ function slotSubmit(val: any, _wasRemoved: boolean): void {
293
299
  emit("submit", val)
294
300
  }
295
301
  const slotProps = computed(() => ({
@@ -301,6 +307,7 @@ const slotProps = computed(() => ({
301
307
  emitSubmit: slotSubmit
302
308
  }))
303
309
 
310
+
304
311
  const suggestionProps = computed(() => ({
305
312
  id: fullId.value,
306
313
  suggestions: props.suggestions,
@@ -308,16 +315,16 @@ const suggestionProps = computed(() => ({
308
315
  restrictToSuggestions: props.restrictToSuggestions,
309
316
  suggestionLabel: props.suggestionLabel,
310
317
  suggestionsFilter: props.suggestionsFilter,
311
- modelValue: $modelValue.value.toString(),
318
+ modelValue: $values.value ?? $modelValue.value.toString(),
312
319
  inputValue: $inputValue.value,
313
320
  isValid: props.isValid,
314
321
  "onUpdate:inputValue": (e: string) => $inputValue.value = e,
315
- onSubmit: (e: string, suggestion: any) => {
316
- $modelValue.value = e
322
+ onSubmit: (e: string, suggestion?: any, wasRemoved?: boolean) => {
323
+ $modelValue.value = wasRemoved ? "" : e
317
324
  emit("submit", e, suggestion)
318
- if ($values.value) {
319
- addValue(e)
320
- }
325
+ },
326
+ "onUpdate:modelValue": (e: string | string[]) => {
327
+ $values.value &&= e as string[]
321
328
  },
322
329
  "onUpdate:isOpen": (e: boolean) => { isOpen.value = e },
323
330
  "onUpdate:activeSuggestion": (e: number) => activeSuggestion.value = e,
@@ -331,8 +338,8 @@ const multivaluesProps = computed(() => ({
331
338
  border: props.border,
332
339
  disabled: props.disabled,
333
340
  readonly: props.readonly,
334
- values: $values.value,
335
- "onUpdate:values": (e: string[]) => $values.value = e,
341
+ modelValue: $values.value,
342
+ "onUpdate:modelValue": (e: string[]) => $values.value = e,
336
343
  ...$.value.multivaluesAttrs,
337
344
  class: undefined,
338
345
  }))
@@ -342,6 +349,7 @@ defineExpose({
342
349
  suggestionsComponent,
343
350
  el: inputWrapperEl,
344
351
  })
352
+
345
353
  </script>
346
354
  <script lang="ts">
347
355
 
@@ -355,7 +363,6 @@ type RealProps =
355
363
  & LinkableByIdProps
356
364
  & LabelProps
357
365
  & BaseInteractiveProps
358
- & MultiValueProps
359
366
  & {
360
367
  suggestions?: SuggestionsProps["suggestions"]
361
368
  valid?: boolean
@@ -32,7 +32,7 @@ defineOptions({
32
32
 
33
33
  const fallbackId = getFallbackId()
34
34
 
35
-
35
+ // eslint-disable-next-line no-undef
36
36
  withDefaults(defineProps<Props>(), {
37
37
  id: "",
38
38
  unstyled: undefined,
@@ -58,7 +58,7 @@ interface Props
58
58
  /** @vue-ignore */
59
59
  Partial<Omit<LabelHTMLAttributes,"class"> & TailwindClassProp>,
60
60
  RealProps
61
- {}
61
+ { }
62
62
  </script>
63
63
 
64
64
  <script lang="ts">
@@ -4,7 +4,7 @@ declare const meta: {
4
4
  component: any;
5
5
  title: string;
6
6
  args: {
7
- values: string[];
7
+ modelValue: string[];
8
8
  border: boolean;
9
9
  };
10
10
  tags: string[];
@@ -5,7 +5,7 @@ const meta = {
5
5
  component: LibMultiValues,
6
6
  title: "Components/MultiValues",
7
7
  args: {
8
- values: ["A", "B", "C"],
8
+ modelValue: ["A", "B", "C"],
9
9
  border: true
10
10
  },
11
11
  tags: ["!test"]
@@ -18,7 +18,7 @@ export const Primary = {
18
18
  const inputValue = ref("B");
19
19
  const multiValueEl = ref(null);
20
20
  const onKeydownEnter = (e) => {
21
- if (e.key === "Enter") args.values.push(inputValue.value);
21
+ if (e.key === "Enter") args.modelValue.push(inputValue.value);
22
22
  };
23
23
  return {
24
24
  args,
@@ -29,7 +29,8 @@ export const Primary = {
29
29
  },
30
30
  template: `
31
31
  <p>Simple Input connected to multi-value.</p>
32
- <p> Press enter to add value:</p>
32
+ <p>Note: You will be able to add values, including duplicates, even to the disabled/readonly version in this test, see the Input component for a properly connected approach.</p>
33
+ <p> Press enter to add value :</p>
33
34
  <lib-simple-input
34
35
  v-model="inputValue"
35
36
  @keydown="onKeydownEnter"
@@ -40,7 +41,7 @@ export const Primary = {
40
41
  <lib-multi-values
41
42
  ref="multiValueEl"
42
43
  v-bind="args"
43
- v-model:values="args.values"
44
+ v-model="args.modelValue"
44
45
  />
45
46
  </div>
46
47
  `
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <div
3
- v-if="$values && $values?.length > 0"
3
+ v-if="$modelValue && $modelValue?.length > 0"
4
4
  :class="twMerge(`
5
- values
5
+ multivalues
6
6
  group
7
7
  flex
8
8
  flex-initial
@@ -12,18 +12,18 @@
12
12
  overflow-x-scroll
13
13
  scrollbar-hidden
14
14
  `,
15
- ($ as any)?.class)
15
+ ($.attrs as any)?.class)
16
16
  "
17
17
  :data-disabled="disabled"
18
18
  :data-read-only="readonly"
19
19
  :aria-label="`Values for ${label}`"
20
20
  :tabindex="disabled ? -1 : 0"
21
- v-bind="{...$, class:undefined}"
21
+ v-bind="{...$.attrs, class:undefined}"
22
22
  >
23
23
  <div
24
24
  :data-border="border"
25
25
  :class="twMerge(`
26
- value_wrapper
26
+ multivalues--item
27
27
  flex-basis-0
28
28
  min-w-2
29
29
  flex
@@ -53,13 +53,13 @@
53
53
  ($.itemAttrs as any)?.class
54
54
  )"
55
55
  :tabindex="canEdit ? 0 : undefined"
56
- v-for="(value) of $values"
56
+ v-for="(value) of $modelValue"
57
57
  :key="value"
58
58
  @keydown.ctrl.c.prevent="copy(value.toString())"
59
59
  >
60
- <span class="value_label truncate">{{ value }}</span>
60
+ <span class="multivalues--label truncate">{{ value }}</span>
61
61
  <lib-button
62
- class="!p-0 text-sm !leading-none"
62
+ class="multivalues--remove-button !p-0 text-sm !leading-none"
63
63
  :aria-label="`Remove ${value}`"
64
64
  :border="false"
65
65
  :disabled="disabled || readonly"
@@ -80,7 +80,7 @@ import { copy } from "../../helpers/copy.js"
80
80
  import { twMerge } from "../../utils/twMerge.js"
81
81
  import Icon from "../Icon/Icon.vue"
82
82
  import LibButton from "../LibButton/LibButton.vue"
83
- import { type BaseInteractiveProps, baseInteractivePropsDefaults,type LabelProps, type MultiValueProps, type TailwindClassProp, type WrapperProps } from "../shared/props.js"
83
+ import { type BaseInteractiveProps, baseInteractivePropsDefaults,type LabelProps, type TailwindClassProp, type WrapperProps } from "../shared/props.js"
84
84
 
85
85
 
86
86
  defineOptions({
@@ -96,11 +96,11 @@ const props = withDefaults(defineProps<Props>(), {
96
96
 
97
97
 
98
98
  const canEdit = computed(() => !props.disabled && !props.readonly)
99
- const $values = defineModel<T[]>("values", { default: () => []})
99
+ const $modelValue = defineModel<T[]>({ default: () => []})
100
100
 
101
101
  const removeVal = (value: T) => {
102
102
  if (!canEdit.value) return
103
- removeIfIn($values.value, value)
103
+ removeIfIn($modelValue.value, value)
104
104
  }
105
105
  </script>
106
106
 
@@ -110,7 +110,6 @@ type WrapperTypes = Partial<WrapperProps<"item",HTMLAttributes>>
110
110
  type RealProps =
111
111
  & LabelProps
112
112
  & BaseInteractiveProps
113
- & MultiValueProps
114
113
  & {
115
114
  border?: boolean
116
115
  }
@@ -2,7 +2,7 @@
2
2
  <div :class="twMerge(`notification
3
3
  max-w-700px
4
4
  bg-neutral-50
5
- dark:bg-neutral-950
5
+ dark:bg-neutral-900
6
6
  text-fg
7
7
  dark:text-bg
8
8
  border
@@ -19,7 +19,7 @@
19
19
  ref="notificationEl"
20
20
  @keydown.enter.self="NotificationHandler.resolveToDefault(notification)"
21
21
  >
22
- <div class="header flex-reverse flex justify-between">
22
+ <div class="notification--header flex-reverse flex justify-between">
23
23
  <div v-if="notification.title"
24
24
  tabindex="0"
25
25
  class="title
@@ -30,35 +30,44 @@
30
30
  >
31
31
  {{ notification.title }}
32
32
  </div>
33
- <div class="flex-1"/>
33
+ <div class="notification--spacer flex-1"/>
34
34
  <div class="actions flex">
35
35
  <LibButton :border="false"
36
- class="copy text-neutral-700"
36
+ class="notification--copy-button text-neutral-700"
37
37
  @click="copy(handler ? handler.stringify(notification) : JSON.stringify(notification))"
38
38
  >
39
39
  <icon><i-fa6-regular-copy/></icon>
40
40
  </LibButton>
41
- <lib-button v-if="notification.cancellable" :border="false" @click="NotificationHandler.dismiss(notification)">
41
+ <lib-button
42
+ v-if="notification.cancellable"
43
+ class="notification--cancel-button"
44
+ :border="false"
45
+ @click="NotificationHandler.dismiss(notification)"
46
+ >
42
47
  <icon><i-fa6-solid-xmark/></icon>
43
48
  </lib-button>
44
49
  </div>
45
50
  </div>
46
- <div class="message whitespace-pre-wrap" tabindex="0">
51
+ <div class="notification--message whitespace-pre-wrap" tabindex="0">
47
52
  {{ notification.message }}
48
53
  </div>
49
- <div class="bottom flex items-end justify-between">
54
+ <div class="notification--footer flex items-end justify-between">
50
55
  <div v-if="notification.code" class="code text-xs text-neutral-700 dark:text-neutral-300">
51
56
  Code: {{ notification.code }}
52
57
  </div>
53
- <div class="flex-1 py-1"/>
58
+ <div class="notification--footer-spacer flex-1 py-1"/>
54
59
  <div v-if="notification.options"
55
- class="options
60
+ class="notification--options
56
61
  flex flex-wrap justify-end
57
62
  gap-2
58
63
  "
59
64
  >
60
65
  <lib-button :label="option"
61
- :class="buttonColors[i] == 'secondary' ? 'p-0': undefined"
66
+ :class="twMerge(`
67
+ notification--option-button
68
+ `,
69
+ buttonColors[i] == 'secondary' && 'p-0'
70
+ )"
62
71
  :border="buttonColors[i] !== 'secondary'"
63
72
  :color="buttonColors[i]"
64
73
  v-for="option, i in notification.options"