@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.
- package/README.md +18 -28
- package/dist/module.d.mts +3 -1
- package/dist/module.d.ts +3 -1
- package/dist/module.json +2 -2
- package/dist/module.mjs +20 -11
- package/dist/runtime/assets/base.css +1 -1
- package/dist/runtime/assets/locales/en.json +2 -2
- package/dist/runtime/assets/tailwind.css +1 -1
- package/dist/runtime/assets/utils.css +1 -0
- package/dist/runtime/build/WitchcraftUiResolver.js +1 -1
- package/dist/runtime/components/Icon/Icon.vue +10 -5
- package/dist/runtime/components/LibButton/LibButton.vue +41 -46
- package/dist/runtime/components/LibCheckbox/LibCheckbox.vue +7 -3
- package/dist/runtime/components/LibColorInput/LibColorInput.vue +111 -36
- package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.d.ts +2 -0
- package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.js +26 -9
- package/dist/runtime/components/LibColorPicker/LibColorPicker.vue +242 -131
- package/dist/runtime/components/LibColorPicker/utils/safeConvertToHsva.d.ts +2 -0
- package/dist/runtime/components/LibColorPicker/utils/safeConvertToHsva.js +18 -0
- package/dist/runtime/components/LibColorPicker/utils/safeConvertToRgba.d.ts +2 -0
- package/dist/runtime/components/LibColorPicker/utils/safeConvertToRgba.js +17 -0
- package/dist/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.d.ts +2 -0
- package/dist/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.js +8 -0
- package/dist/runtime/components/LibColorPicker/utils/truncate.d.ts +1 -0
- package/dist/runtime/components/LibColorPicker/utils/truncate.js +5 -0
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.js +1 -1
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +11 -8
- package/dist/runtime/components/LibDatePicker/LibDatePicker.vue +4 -17
- package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue +192 -131
- package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue +183 -115
- package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue +3 -3
- package/dist/runtime/components/LibDebug/LibDebug.vue +15 -5
- package/dist/runtime/components/LibDevOnly/LibDevOnly.vue +1 -3
- package/dist/runtime/components/LibFileInput/LibFileInput.vue +54 -28
- package/dist/runtime/components/{LibInput/LibInput.stories.d.ts → LibInputDeprecated/LibInputDeprecated.stories.d.ts} +6 -6
- package/dist/runtime/components/{LibInput/LibInput.stories.js → LibInputDeprecated/LibInputDeprecated.stories.js} +64 -19
- package/{src/runtime/components/LibInput/LibInput.vue → dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue} +40 -33
- package/dist/runtime/components/LibLabel/LibLabel.vue +2 -2
- package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.d.ts +1 -1
- package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.js +5 -4
- package/dist/runtime/components/LibMultiValues/LibMultiValues.vue +11 -12
- package/dist/runtime/components/LibNotifications/LibNotification.vue +19 -10
- package/dist/runtime/components/LibNotifications/LibNotifications.stories.js +2 -2
- package/dist/runtime/components/LibNotifications/LibNotifications.vue +20 -11
- package/dist/runtime/components/LibPagination/LibPagination.stories.js +2 -2
- package/dist/runtime/components/LibPagination/LibPagination.vue +19 -19
- package/dist/runtime/components/LibPalette/LibPalette.vue +3 -3
- package/dist/runtime/components/LibPopup/LibPopup.stories.js +2 -2
- package/dist/runtime/components/LibPopup/LibPopup.vue +30 -66
- package/dist/runtime/components/LibProgressBar/LibProgressBar.vue +3 -1
- package/dist/runtime/components/LibRecorder/LibRecorder.vue +2 -2
- package/dist/runtime/components/LibRoot/LibRoot.vue +14 -1
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.stories.js +1 -1
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue +5 -7
- package/dist/runtime/components/LibSuggestions/LibSuggestions.vue +42 -25
- package/dist/runtime/components/LibTable/LibTable.vue +8 -8
- package/dist/runtime/components/Scrolling.stories.d.ts +6 -0
- package/dist/runtime/components/Scrolling.stories.js +44 -0
- package/dist/runtime/components/Template/NAME.vue +1 -1
- package/dist/runtime/components/TestControls/TestControls.vue +1 -1
- package/dist/runtime/components/index.d.ts +12 -11
- package/dist/runtime/components/index.js +12 -11
- package/dist/runtime/components/shared/props.d.ts +81 -16
- package/dist/runtime/components/shared/storyHelpers/playInput.js +5 -5
- package/dist/runtime/components/shared/storyHelpers/playSuggestions.js +15 -11
- package/dist/runtime/composables/index.d.ts +5 -0
- package/dist/runtime/composables/index.js +5 -0
- package/dist/runtime/composables/useDivideAttrs.js +1 -0
- package/dist/runtime/composables/useDragWithThreshold.d.ts +71 -0
- package/dist/runtime/composables/useDragWithThreshold.js +40 -0
- package/dist/runtime/composables/usePreHydrationValue.d.ts +12 -0
- package/dist/runtime/composables/usePreHydrationValue.js +15 -0
- package/dist/runtime/composables/useSetupI18n.d.ts +2 -0
- package/dist/runtime/composables/useSetupI18n.js +5 -1
- package/dist/runtime/composables/useSuggestions.d.ts +7 -5
- package/dist/runtime/composables/useSuggestions.js +94 -57
- package/dist/runtime/directives/vResizableCols.js +3 -1
- package/dist/runtime/helpers/NotificationHandler.d.ts +5 -0
- package/dist/runtime/helpers/index.d.ts +3 -1
- package/dist/runtime/helpers/index.js +3 -1
- package/dist/runtime/types/index.d.ts +6 -0
- package/dist/runtime/utils/notifyIfError.d.ts +14 -0
- package/dist/runtime/utils/notifyIfError.js +29 -0
- package/package.json +18 -20
- package/src/module.ts +31 -12
- package/src/runtime/assets/base.css +10 -1
- package/src/runtime/assets/locales/en.json +2 -2
- package/src/runtime/assets/tailwind.css +1 -1
- package/src/runtime/assets/{style.css → utils.css} +86 -4
- package/src/runtime/build/WitchcraftUiResolver.ts +1 -1
- package/src/runtime/components/Icon/Icon.vue +10 -5
- package/src/runtime/components/LibButton/LibButton.vue +41 -46
- package/src/runtime/components/LibCheckbox/LibCheckbox.vue +7 -3
- package/src/runtime/components/LibColorInput/LibColorInput.vue +111 -36
- package/src/runtime/components/LibColorPicker/LibColorPicker.stories.ts +25 -4
- package/src/runtime/components/LibColorPicker/LibColorPicker.vue +242 -131
- package/src/runtime/components/LibColorPicker/utils/safeConvertToHsva.ts +25 -0
- package/src/runtime/components/LibColorPicker/utils/safeConvertToRgba.ts +23 -0
- package/src/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.ts +13 -0
- package/src/runtime/components/LibColorPicker/utils/truncate.ts +6 -0
- package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.ts +1 -1
- package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +11 -8
- package/src/runtime/components/LibDatePicker/LibDatePicker.vue +4 -17
- package/src/runtime/components/LibDatePicker/LibRangeDatePicker.vue +192 -131
- package/src/runtime/components/LibDatePicker/LibSingleDatePicker.vue +183 -115
- package/src/runtime/components/LibDatePicker/LibTimeZonePicker.vue +3 -3
- package/src/runtime/components/LibDebug/LibDebug.vue +15 -5
- package/src/runtime/components/LibDevOnly/LibDevOnly.vue +1 -3
- package/src/runtime/components/LibFileInput/LibFileInput.vue +54 -28
- package/src/runtime/components/{LibInput/LibInput.stories.ts → LibInputDeprecated/LibInputDeprecated.stories.ts} +64 -19
- package/{dist/runtime/components/LibInput/LibInput.vue → src/runtime/components/LibInputDeprecated/LibInputDeprecated.vue} +40 -33
- package/src/runtime/components/LibLabel/LibLabel.vue +2 -2
- package/src/runtime/components/LibMultiValues/LibMultiValues.stories.ts +5 -4
- package/src/runtime/components/LibMultiValues/LibMultiValues.vue +11 -12
- package/src/runtime/components/LibNotifications/LibNotification.vue +19 -10
- package/src/runtime/components/LibNotifications/LibNotifications.stories.ts +2 -2
- package/src/runtime/components/LibNotifications/LibNotifications.vue +20 -11
- package/src/runtime/components/LibPagination/LibPagination.stories.ts +2 -2
- package/src/runtime/components/LibPagination/LibPagination.vue +19 -19
- package/src/runtime/components/LibPalette/LibPalette.vue +3 -3
- package/src/runtime/components/LibPopup/LibPopup.stories.ts +2 -2
- package/src/runtime/components/LibPopup/LibPopup.vue +30 -66
- package/src/runtime/components/LibProgressBar/LibProgressBar.vue +3 -1
- package/src/runtime/components/LibRecorder/LibRecorder.vue +2 -2
- package/src/runtime/components/LibRoot/LibRoot.vue +14 -1
- package/src/runtime/components/LibSimpleInput/LibSimpleInput.stories.ts +1 -1
- package/src/runtime/components/LibSimpleInput/LibSimpleInput.vue +5 -7
- package/src/runtime/components/LibSuggestions/LibSuggestions.vue +42 -25
- package/src/runtime/components/LibTable/LibTable.vue +8 -8
- package/src/runtime/components/Scrolling.stories.ts +58 -0
- package/src/runtime/components/Template/NAME.vue +1 -1
- package/src/runtime/components/TestControls/TestControls.vue +1 -1
- package/src/runtime/components/index.ts +12 -12
- package/src/runtime/components/shared/props.ts +82 -19
- package/src/runtime/components/shared/storyHelpers/playInput.ts +6 -5
- package/src/runtime/components/shared/storyHelpers/playSuggestions.ts +25 -11
- package/src/runtime/composables/index.ts +5 -0
- package/src/runtime/composables/useDarkMode.ts +2 -2
- package/src/runtime/composables/useDivideAttrs.ts +1 -0
- package/src/runtime/composables/useDragWithThreshold.ts +108 -0
- package/src/runtime/composables/usePreHydrationValue.ts +30 -0
- package/src/runtime/composables/useSetupI18n.ts +8 -2
- package/src/runtime/composables/useSuggestions.ts +92 -45
- package/src/runtime/directives/vResizableCols.ts +3 -1
- package/src/runtime/helpers/NotificationHandler.ts +5 -0
- package/src/runtime/helpers/index.ts +3 -1
- package/src/runtime/types/index.ts +5 -0
- package/src/runtime/utils/notifyIfError.ts +45 -0
- package/dist/runtime/assets/style.css +0 -1
- package/dist/runtime/helpers/addValue.d.ts +0 -1
- package/dist/runtime/helpers/addValue.js +0 -8
- package/src/runtime/helpers/addValue.ts +0 -10
- /package/dist/runtime/components/{reset.stories.d.ts → Reset.stories.d.ts} +0 -0
- /package/dist/runtime/components/{reset.stories.js → Reset.stories.js} +0 -0
- /package/src/runtime/components/{reset.stories.ts → Reset.stories.ts} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/vue3"
|
|
3
3
|
import { ref, watchEffect } from "vue"
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import LibInputDeprecated from "./LibInputDeprecated.vue"
|
|
6
6
|
|
|
7
7
|
import IconFaChevronLeft from "~icons/fa6-solid/chevron-left"
|
|
8
8
|
import IconFaChevronRight from "~icons/fa6-solid/chevron-right"
|
|
@@ -25,19 +25,22 @@ import {
|
|
|
25
25
|
} from "../shared/storyHelpers/playSuggestions.js"
|
|
26
26
|
|
|
27
27
|
const meta = {
|
|
28
|
-
component:
|
|
29
|
-
title: "Components/
|
|
28
|
+
component: LibInputDeprecated as any,
|
|
29
|
+
title: "Components/Combobox",
|
|
30
30
|
args: {
|
|
31
31
|
border: true,
|
|
32
32
|
label: "Some Label",
|
|
33
|
+
...{
|
|
34
|
+
_template: undefined,
|
|
35
|
+
} as any
|
|
33
36
|
},
|
|
34
|
-
} satisfies Meta<typeof
|
|
37
|
+
} satisfies Meta<typeof LibInputDeprecated> & Meta<{ custom: string }>
|
|
35
38
|
|
|
36
39
|
export default meta
|
|
37
|
-
type Story = StoryObj<typeof
|
|
40
|
+
type Story = StoryObj<typeof LibInputDeprecated> // & StoryObj<typeof extraArgs>
|
|
38
41
|
const allComponents = {
|
|
39
42
|
...components,
|
|
40
|
-
|
|
43
|
+
LibInputDeprecated,
|
|
41
44
|
Icon,
|
|
42
45
|
IconFaChevronRight,
|
|
43
46
|
IconFaChevronLeft,
|
|
@@ -54,6 +57,7 @@ const playAutosuggestSelectLike = async (context: { canvasElement: HTMLElement,
|
|
|
54
57
|
|
|
55
58
|
const setupModelValue = (args: any) => ({
|
|
56
59
|
modelValue: ref(args.modelValue ?? ""),
|
|
60
|
+
inputValue: ref(args.inputValue ?? ""),
|
|
57
61
|
})
|
|
58
62
|
|
|
59
63
|
const setupModelValues = (args: any) => ({
|
|
@@ -64,6 +68,7 @@ const Base: Story = {
|
|
|
64
68
|
render: args => ({
|
|
65
69
|
components: allComponents,
|
|
66
70
|
setup: () => ({
|
|
71
|
+
|
|
67
72
|
...setupModelValue(args),
|
|
68
73
|
...setupModelValues(args),
|
|
69
74
|
args: {
|
|
@@ -72,15 +77,16 @@ const Base: Story = {
|
|
|
72
77
|
},
|
|
73
78
|
}),
|
|
74
79
|
|
|
75
|
-
template: `
|
|
80
|
+
template: (args as any)._template ?? `
|
|
76
81
|
Model Value: <span class="inline-block" data-testid="model-value">{{modelValue}}</span>\n
|
|
77
|
-
<lib-input
|
|
82
|
+
<lib-simple-input-deprecated
|
|
78
83
|
v-bind="args"
|
|
79
84
|
v-model:values="values"
|
|
85
|
+
v-model:inputValue="inputValue"
|
|
80
86
|
v-model="modelValue"
|
|
81
87
|
@submit="modelValue = $event"
|
|
82
88
|
>
|
|
83
|
-
</lib-input>
|
|
89
|
+
</lib-simple-input-deprecated>
|
|
84
90
|
`,
|
|
85
91
|
}),
|
|
86
92
|
}
|
|
@@ -144,6 +150,15 @@ export const WithAutosuggest = {
|
|
|
144
150
|
},
|
|
145
151
|
play: playAutosuggestSelectLike
|
|
146
152
|
}
|
|
153
|
+
|
|
154
|
+
export const WithAutosuggestNoLabel = {
|
|
155
|
+
...Base,
|
|
156
|
+
args: {
|
|
157
|
+
label: undefined,
|
|
158
|
+
suggestions: ["A", "AB", "ABC", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"],
|
|
159
|
+
},
|
|
160
|
+
play: playAutosuggestSelectLike
|
|
161
|
+
}
|
|
147
162
|
export const WithInstantAutosuggest = {
|
|
148
163
|
...Base,
|
|
149
164
|
args: {
|
|
@@ -158,6 +173,27 @@ export const AutosuggestRestricted = {
|
|
|
158
173
|
},
|
|
159
174
|
play: playAutosuggestSelectLike
|
|
160
175
|
}
|
|
176
|
+
export const AutosuggestRestrictedWithClearOnClick = {
|
|
177
|
+
...WithAutosuggest,
|
|
178
|
+
args: {
|
|
179
|
+
...WithAutosuggest.args,
|
|
180
|
+
restrictToSuggestions: true,
|
|
181
|
+
_template: `
|
|
182
|
+
Model Value: <span class="inline-block" data-testid="model-value">{{modelValue}}</span>\n
|
|
183
|
+
Temp Value: <span class="inline-block" data-testid="temp-value">{{inputValue}}</span>\n
|
|
184
|
+
<lib-simple-input-deprecated
|
|
185
|
+
v-bind="args"
|
|
186
|
+
v-model:values="values"
|
|
187
|
+
v-model:inputValue="inputValue"
|
|
188
|
+
v-model="modelValue"
|
|
189
|
+
@submit="modelValue = $event"
|
|
190
|
+
@click="inputValue = ''"
|
|
191
|
+
>
|
|
192
|
+
</lib-simple-input-deprecated>
|
|
193
|
+
`
|
|
194
|
+
},
|
|
195
|
+
play: null,
|
|
196
|
+
}
|
|
161
197
|
export const AutosuggestSelectLikeShowAllUnrestricted = {
|
|
162
198
|
...WithAutosuggest,
|
|
163
199
|
args: {
|
|
@@ -198,7 +234,7 @@ export const Slots: Story = {
|
|
|
198
234
|
template: `
|
|
199
235
|
Model Value: <span class="inline-block" data-testid="model-value">{{modelValue}}</span>\n
|
|
200
236
|
|
|
201
|
-
<lib-input
|
|
237
|
+
<lib-simple-input-deprecated
|
|
202
238
|
v-bind="args"
|
|
203
239
|
v-model="modelValue"
|
|
204
240
|
v-model:values="values"
|
|
@@ -216,7 +252,7 @@ export const Slots: Story = {
|
|
|
216
252
|
<icon><icon-fa-chevron-right/></icon>
|
|
217
253
|
</lib-button>
|
|
218
254
|
</template>
|
|
219
|
-
</lib-input>
|
|
255
|
+
</lib-simple-input-deprecated>
|
|
220
256
|
`,
|
|
221
257
|
}),
|
|
222
258
|
}
|
|
@@ -234,17 +270,17 @@ const MultipleValuesBase: Story = {
|
|
|
234
270
|
Model Value: <span class="inline-block" data-testid="model-value">{{modelValue}}</span>\n
|
|
235
271
|
<br/>
|
|
236
272
|
Values: <span class="inline-block" data-testid="values">{{values.join(", ")}}</span>\n
|
|
237
|
-
<lib-input
|
|
273
|
+
<lib-simple-input-deprecated
|
|
238
274
|
v-bind="args"
|
|
239
275
|
v-model="modelValue"
|
|
240
276
|
v-model:values="values"
|
|
241
277
|
>
|
|
242
278
|
<template #left>
|
|
243
|
-
<lib-button class="px-0" :border="false">
|
|
279
|
+
<lib-button class="px-0" :border="false" :disabled="args.disabled || args.readonly">
|
|
244
280
|
<icon><icon-fa-solid-tags/></icon>
|
|
245
281
|
</lib-button>
|
|
246
282
|
</template>
|
|
247
|
-
</lib-input>
|
|
283
|
+
</lib-simple-input-deprecated>
|
|
248
284
|
`,
|
|
249
285
|
}),
|
|
250
286
|
args: {
|
|
@@ -266,6 +302,15 @@ export const WithMultipleValuesWithSuggestions = {
|
|
|
266
302
|
},
|
|
267
303
|
play: playAutosuggestSelectLike
|
|
268
304
|
}
|
|
305
|
+
export const WithMultipleValuesWithSuggestionsNoSelected = {
|
|
306
|
+
...MultipleValuesBase,
|
|
307
|
+
args: {
|
|
308
|
+
...MultipleValuesBase.args,
|
|
309
|
+
suggestions: ["A", "AB", "ABC", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"],
|
|
310
|
+
showSelectedValues: false,
|
|
311
|
+
},
|
|
312
|
+
play: playAutosuggestSelectLike
|
|
313
|
+
}
|
|
269
314
|
export const WithMultipleValuesDisabled = {
|
|
270
315
|
...MultipleValuesBase,
|
|
271
316
|
args: {
|
|
@@ -311,7 +356,7 @@ export const InputSlotReplacement: Story = {
|
|
|
311
356
|
Values: <span class="inline-block" data-testid="values">{{values.join(", ")}}</span>\n
|
|
312
357
|
<br/>
|
|
313
358
|
Recording: <span class="inline-block" data-testid="recording">{{recording}}</span>\n
|
|
314
|
-
<lib-input
|
|
359
|
+
<lib-simple-input-deprecated
|
|
315
360
|
v-bind="args"
|
|
316
361
|
v-model="modelValue"
|
|
317
362
|
v-model:values="values"
|
|
@@ -332,7 +377,7 @@ export const InputSlotReplacement: Story = {
|
|
|
332
377
|
<template #left>
|
|
333
378
|
<icon><icon-fa-solid-keyboard/></icon>
|
|
334
379
|
</template>
|
|
335
|
-
</lib-input>
|
|
380
|
+
</lib-simple-input-deprecated>
|
|
336
381
|
`,
|
|
337
382
|
}),
|
|
338
383
|
args: {
|
|
@@ -352,13 +397,13 @@ export const NextToButton: Story = {
|
|
|
352
397
|
|
|
353
398
|
template: `
|
|
354
399
|
<div class="flex gap-2 items-center">
|
|
355
|
-
<lib-input
|
|
400
|
+
<lib-simple-input-deprecated
|
|
356
401
|
v-bind="args"
|
|
357
402
|
v-model:values="values"
|
|
358
403
|
v-model="modelValue"
|
|
359
|
-
:label="undefined"
|
|
404
|
+
:label="undefined"
|
|
360
405
|
>
|
|
361
|
-
</lib-input>
|
|
406
|
+
</lib-simple-input-deprecated>
|
|
362
407
|
<lib-button>Button</lib-button>
|
|
363
408
|
</div>
|
|
364
409
|
`,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
:class="twMerge(`input
|
|
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:!
|
|
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
|
|
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
|
|
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
|
-
(
|
|
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
|
-
|
|
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
|
|
316
|
-
$modelValue.value = e
|
|
322
|
+
onSubmit: (e: string, suggestion?: any, wasRemoved?: boolean) => {
|
|
323
|
+
$modelValue.value = wasRemoved ? "" : e
|
|
317
324
|
emit("submit", e, suggestion)
|
|
318
|
-
|
|
319
|
-
|
|
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
|
-
|
|
335
|
-
"onUpdate:
|
|
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">
|
|
@@ -12,7 +12,7 @@ const meta = {
|
|
|
12
12
|
component: LibMultiValues as any,
|
|
13
13
|
title: "Components/MultiValues",
|
|
14
14
|
args: {
|
|
15
|
-
|
|
15
|
+
modelValue: ["A", "B", "C"],
|
|
16
16
|
border: true,
|
|
17
17
|
},
|
|
18
18
|
tags: ["!test"],
|
|
@@ -36,7 +36,7 @@ export const Primary: Story = {
|
|
|
36
36
|
const inputValue = ref("B")
|
|
37
37
|
const multiValueEl = ref<typeof LibMultiValues | null>(null)
|
|
38
38
|
const onKeydownEnter = (e: KeyboardEvent): void => {
|
|
39
|
-
if (e.key === "Enter") (args.
|
|
39
|
+
if (e.key === "Enter") (args.modelValue!).push(inputValue.value)
|
|
40
40
|
}
|
|
41
41
|
return ({
|
|
42
42
|
args,
|
|
@@ -49,7 +49,8 @@ export const Primary: Story = {
|
|
|
49
49
|
|
|
50
50
|
template: `
|
|
51
51
|
<p>Simple Input connected to multi-value.</p>
|
|
52
|
-
<p>
|
|
52
|
+
<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>
|
|
53
|
+
<p> Press enter to add value :</p>
|
|
53
54
|
<lib-simple-input
|
|
54
55
|
v-model="inputValue"
|
|
55
56
|
@keydown="onKeydownEnter"
|
|
@@ -60,7 +61,7 @@ export const Primary: Story = {
|
|
|
60
61
|
<lib-multi-values
|
|
61
62
|
ref="multiValueEl"
|
|
62
63
|
v-bind="args"
|
|
63
|
-
v-model
|
|
64
|
+
v-model="args.modelValue"
|
|
64
65
|
/>
|
|
65
66
|
</div>
|
|
66
67
|
`,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
v-if="$
|
|
3
|
+
v-if="$modelValue && $modelValue?.length > 0"
|
|
4
4
|
:class="twMerge(`
|
|
5
|
-
|
|
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
|
-
(
|
|
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="{
|
|
21
|
+
v-bind="{...$.attrs, class:undefined}"
|
|
22
22
|
>
|
|
23
23
|
<div
|
|
24
24
|
:data-border="border"
|
|
25
25
|
:class="twMerge(`
|
|
26
|
-
|
|
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 $
|
|
56
|
+
v-for="(value) of $modelValue"
|
|
57
57
|
:key="value"
|
|
58
58
|
@keydown.ctrl.c.prevent="copy(value.toString())"
|
|
59
59
|
>
|
|
60
|
-
<span class="
|
|
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
|
|
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 $
|
|
99
|
+
const $modelValue = defineModel<T[]>({ default: () => []})
|
|
100
100
|
|
|
101
101
|
const removeVal = (value: T) => {
|
|
102
102
|
if (!canEdit.value) return
|
|
103
|
-
removeIfIn($
|
|
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-
|
|
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
|
|
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="
|
|
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="
|
|
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"
|
|
@@ -100,7 +100,7 @@ export const Primary: Story = {
|
|
|
100
100
|
backgrounds: { disable: true },
|
|
101
101
|
// <lib-debug>{{args.handler}}</lib-debug>
|
|
102
102
|
template: `
|
|
103
|
-
<
|
|
103
|
+
<lib-root :outline="args.outline">
|
|
104
104
|
<lib-button :label="'Notify Timeoutable'" @click="notifyTimeoutable()"></lib-button>
|
|
105
105
|
<lib-button :label="'Notify RequiresAction'" @click="notifyRequiresAction()"></lib-button>
|
|
106
106
|
<lib-button :label="'Notify Non-Cancellable that RequiresAction'" @click="notifyNonCancellableRequiresAction()"></lib-button>
|
|
@@ -117,7 +117,7 @@ export const Primary: Story = {
|
|
|
117
117
|
<br>
|
|
118
118
|
</template>
|
|
119
119
|
</lib-debug>
|
|
120
|
-
</
|
|
120
|
+
</lib-root>
|
|
121
121
|
`,
|
|
122
122
|
}),
|
|
123
123
|
}
|