@witchcraft/ui 0.2.1-beta.3 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +20 -4
- package/dist/runtime/build/WitchcraftUiResolver.d.ts +2 -2
- package/dist/runtime/build/generateTheme.js +2 -2
- package/dist/runtime/components/Aria/Aria.d.vue.ts +5 -0
- package/dist/runtime/components/Aria/Aria.vue +4 -2
- package/dist/runtime/components/Aria/Aria.vue.d.ts +1 -1
- package/dist/runtime/components/Icon/Icon.d.vue.ts +21 -0
- package/dist/runtime/components/Icon/Icon.vue +3 -3
- package/dist/runtime/components/Icon/Icon.vue.d.ts +1 -1
- package/dist/runtime/components/LibButton/LibButton.d.vue.ts +36 -0
- package/dist/runtime/components/LibButton/LibButton.vue +9 -4
- package/dist/runtime/components/LibButton/LibButton.vue.d.ts +1 -1
- package/dist/runtime/components/LibCheckbox/LibCheckbox.d.vue.ts +42 -0
- package/dist/runtime/components/LibCheckbox/LibCheckbox.vue +3 -4
- package/dist/runtime/components/LibCheckbox/LibCheckbox.vue.d.ts +1 -1
- package/dist/runtime/components/LibColorInput/LibColorInput.d.vue.ts +63 -0
- package/dist/runtime/components/LibColorInput/LibColorInput.vue +15 -8
- package/dist/runtime/components/LibColorInput/LibColorInput.vue.d.ts +1 -1
- package/dist/runtime/components/LibColorPicker/LibColorPicker.d.vue.ts +61 -0
- package/dist/runtime/components/LibColorPicker/LibColorPicker.vue +10 -6
- package/dist/runtime/components/LibColorPicker/LibColorPicker.vue.d.ts +1 -1
- package/dist/runtime/components/LibColorPicker/utils/truncate.js +1 -1
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.d.vue.ts +22 -0
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +5 -2
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue.d.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibDatePicker.d.vue.ts +40 -0
- package/dist/runtime/components/LibDatePicker/LibDatePicker.vue.d.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.d.vue.ts +34 -0
- package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue +8 -6
- package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue.d.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.d.vue.ts +34 -0
- package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue +7 -5
- package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue.d.ts +1 -1
- package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.d.vue.ts +22 -0
- package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue.d.ts +1 -1
- package/dist/runtime/components/LibDebug/LibDebug.d.vue.ts +32 -0
- package/dist/runtime/components/LibDebug/LibDebug.vue +9 -4
- package/dist/runtime/components/LibDebug/LibDebug.vue.d.ts +1 -1
- package/dist/runtime/components/LibDevOnly/LibDevOnly.d.vue.ts +25 -0
- package/dist/runtime/components/LibDevOnly/LibDevOnly.vue +2 -1
- package/dist/runtime/components/LibDevOnly/LibDevOnly.vue.d.ts +4 -1
- package/dist/runtime/components/LibFileInput/LibFileInput.d.vue.ts +43 -0
- package/dist/runtime/components/LibFileInput/LibFileInput.vue +29 -13
- package/dist/runtime/components/LibFileInput/LibFileInput.vue.d.ts +2 -2
- package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.d.vue.ts +165 -0
- package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue +42 -12
- package/dist/runtime/components/LibLabel/LibLabel.d.vue.ts +26 -0
- package/dist/runtime/components/LibLabel/LibLabel.vue +2 -2
- package/dist/runtime/components/LibLabel/LibLabel.vue.d.ts +3 -3
- package/dist/runtime/components/LibMultiValues/LibMultiValues.d.vue.ts +29 -0
- package/dist/runtime/components/LibMultiValues/LibMultiValues.vue +1 -2
- package/dist/runtime/components/LibMultiValues/LibMultiValues.vue.d.ts +2 -2
- package/dist/runtime/components/LibNotifications/LibNotification.d.vue.ts +17 -0
- package/dist/runtime/components/LibNotifications/LibNotification.vue +19 -8
- package/dist/runtime/components/LibNotifications/LibNotifications.d.vue.ts +13 -0
- package/dist/runtime/components/LibNotifications/LibNotifications.vue +10 -6
- package/dist/runtime/components/LibNotifications/LibNotifications.vue.d.ts +2 -2
- package/dist/runtime/components/LibPagination/LibPagination.d.vue.ts +104 -0
- package/dist/runtime/components/LibPagination/LibPagination.vue +25 -12
- package/dist/runtime/components/LibPagination/LibPagination.vue.d.ts +2 -2
- package/dist/runtime/components/LibPalette/LibPalette.d.vue.ts +14 -0
- package/dist/runtime/components/LibPalette/LibPalette.vue +6 -5
- package/dist/runtime/components/LibPalette/LibPalette.vue.d.ts +5 -5
- package/dist/runtime/components/LibPopup/LibPopup.d.vue.ts +46 -0
- package/dist/runtime/components/LibPopup/LibPopup.vue +6 -4
- package/dist/runtime/components/LibPopup/LibPopup.vue.d.ts +3 -3
- package/dist/runtime/components/LibProgressBar/LibProgressBar.d.vue.ts +41 -0
- package/dist/runtime/components/LibProgressBar/LibProgressBar.vue +5 -3
- package/dist/runtime/components/LibProgressBar/LibProgressBar.vue.d.ts +9 -9
- package/dist/runtime/components/LibRecorder/LibRecorder.d.vue.ts +77 -0
- package/dist/runtime/components/LibRecorder/LibRecorder.vue +1 -1
- package/dist/runtime/components/LibRecorder/LibRecorder.vue.d.ts +2 -2
- package/dist/runtime/components/LibRoot/LibRoot.d.vue.ts +41 -0
- package/dist/runtime/components/LibRoot/LibRoot.vue +11 -6
- package/dist/runtime/components/LibRoot/LibRoot.vue.d.ts +1 -1
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.d.vue.ts +35 -0
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue +1 -1
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue.d.ts +1 -1
- package/dist/runtime/components/LibSuggestions/LibSuggestions.d.vue.ts +94 -0
- package/dist/runtime/components/LibSuggestions/LibSuggestions.vue +6 -4
- package/dist/runtime/components/LibSuggestions/LibSuggestions.vue.d.ts +1 -1
- package/dist/runtime/components/LibTable/LibTable.d.vue.ts +45 -0
- package/dist/runtime/components/LibTable/LibTable.vue +23 -8
- package/dist/runtime/components/LibTable/LibTable.vue.d.ts +1 -1
- package/dist/runtime/components/Template/NAME.d.vue.ts +17 -0
- package/dist/runtime/components/Template/NAME.vue +2 -3
- package/dist/runtime/components/Template/NAME.vue.d.ts +1 -1
- package/dist/runtime/components/TestControls/TestControls.d.vue.ts +5 -0
- package/dist/runtime/components/TestControls/TestControls.vue +4 -2
- package/dist/runtime/components/TestControls/TestControls.vue.d.ts +1 -1
- package/dist/runtime/composables/useDragWithThreshold.d.ts +1 -1
- package/dist/runtime/composables/useInjectedI18n.d.ts +1 -1
- package/dist/runtime/composables/useScrollNearContainerEdges.d.ts +1 -1
- package/dist/runtime/composables/useSetupI18n.d.ts +1 -1
- package/dist/runtime/composables/useSuggestions.d.ts +2 -2
- package/dist/runtime/helpers/NotificationHandler.d.ts +1 -1
- package/dist/runtime/helpers/base64ToImg.js +2 -2
- package/dist/runtime/tailwind/themeConvertionOpts.d.ts +1 -1
- package/dist/runtime/types/index.d.ts +1 -1
- package/dist/runtime/utils/notifyIfError.d.ts +1 -1
- package/package.json +9 -10
- package/src/module.ts +41 -33
- package/src/runtime/build/WitchcraftUiResolver.ts +3 -3
- package/src/runtime/build/generateTheme.ts +3 -2
- package/src/runtime/build/unpluginIconViteOptions.ts +1 -1
- package/src/runtime/components/Aria/Aria.vue +5 -6
- package/src/runtime/components/Focus.stories.ts +11 -12
- package/src/runtime/components/Icon/Icon.vue +5 -9
- package/src/runtime/components/LibButton/LibButton.stories.ts +21 -22
- package/src/runtime/components/LibButton/LibButton.vue +23 -21
- package/src/runtime/components/LibCheckbox/LibCheckbox.stories.ts +6 -10
- package/src/runtime/components/LibCheckbox/LibCheckbox.vue +17 -19
- package/src/runtime/components/LibColorInput/LibColorInput.stories.ts +8 -13
- package/src/runtime/components/LibColorInput/LibColorInput.vue +49 -45
- package/src/runtime/components/LibColorPicker/LibColorPicker.stories.ts +14 -18
- package/src/runtime/components/LibColorPicker/LibColorPicker.vue +50 -52
- package/src/runtime/components/LibColorPicker/utils/safeConvertToHsva.ts +1 -2
- package/src/runtime/components/LibColorPicker/utils/safeConvertToRgba.ts +1 -2
- package/src/runtime/components/LibColorPicker/utils/truncate.ts +1 -2
- package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.ts +5 -8
- package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +11 -9
- package/src/runtime/components/LibDatePicker/LibDatePicker.stories.ts +14 -15
- package/src/runtime/components/LibDatePicker/LibDatePicker.vue +1 -2
- package/src/runtime/components/LibDatePicker/LibRangeDatePicker.vue +13 -13
- package/src/runtime/components/LibDatePicker/LibSingleDatePicker.vue +9 -8
- package/src/runtime/components/LibDatePicker/LibTimeZonePicker.vue +2 -1
- package/src/runtime/components/LibDatePicker/helpers.ts +0 -2
- package/src/runtime/components/LibDebug/LibDebug.stories.ts +11 -15
- package/src/runtime/components/LibDebug/LibDebug.vue +14 -11
- package/src/runtime/components/LibDevOnly/LibDevOnly.vue +8 -4
- package/src/runtime/components/LibFileInput/LibFileInput.stories.ts +12 -15
- package/src/runtime/components/LibFileInput/LibFileInput.vue +65 -47
- package/src/runtime/components/LibInputDeprecated/LibInputDeprecated.stories.ts +77 -84
- package/src/runtime/components/LibInputDeprecated/LibInputDeprecated.vue +73 -48
- package/src/runtime/components/LibLabel/LibLabel.stories.ts +4 -8
- package/src/runtime/components/LibLabel/LibLabel.vue +8 -8
- package/src/runtime/components/LibMultiValues/LibMultiValues.stories.ts +10 -15
- package/src/runtime/components/LibMultiValues/LibMultiValues.vue +14 -18
- package/src/runtime/components/LibNotifications/LibNotification.stories.ts +30 -34
- package/src/runtime/components/LibNotifications/LibNotification.vue +27 -17
- package/src/runtime/components/LibNotifications/LibNotifications.stories.ts +11 -15
- package/src/runtime/components/LibNotifications/LibNotifications.vue +21 -16
- package/src/runtime/components/LibPagination/LibPagination.stories.ts +5 -9
- package/src/runtime/components/LibPagination/LibPagination.vue +46 -32
- package/src/runtime/components/LibPalette/LibPalette.stories.ts +3 -7
- package/src/runtime/components/LibPalette/LibPalette.vue +13 -12
- package/src/runtime/components/LibPopup/LibPopup.stories.ts +19 -23
- package/src/runtime/components/LibPopup/LibPopup.vue +31 -35
- package/src/runtime/components/LibProgressBar/LibProgressBar.stories.ts +13 -17
- package/src/runtime/components/LibProgressBar/LibProgressBar.vue +36 -33
- package/src/runtime/components/LibRecorder/LibRecorder.stories.ts +11 -12
- package/src/runtime/components/LibRecorder/LibRecorder.vue +34 -34
- package/src/runtime/components/LibRoot/LibRoot.vue +16 -12
- package/src/runtime/components/LibSimpleInput/LibSimpleInput.stories.ts +20 -24
- package/src/runtime/components/LibSimpleInput/LibSimpleInput.vue +17 -21
- package/src/runtime/components/LibSuggestions/LibSuggestions.stories.ts +16 -19
- package/src/runtime/components/LibSuggestions/LibSuggestions.vue +28 -30
- package/src/runtime/components/LibTable/LibTable.stories.ts +30 -33
- package/src/runtime/components/LibTable/LibTable.vue +38 -24
- package/src/runtime/components/Reset.stories.ts +3 -6
- package/src/runtime/components/Scrolling.stories.ts +5 -8
- package/src/runtime/components/Template/NAME.vue +11 -11
- package/src/runtime/components/Template/TemplateStory.ts +9 -10
- package/src/runtime/components/TestControls/TestControls.vue +5 -5
- package/src/runtime/components/shared/props.ts +4 -6
- package/src/runtime/components/shared/storyHelpers/playInput.ts +2 -3
- package/src/runtime/components/shared/storyHelpers/playSuggestions.ts +5 -9
- package/src/runtime/composables/useAccesibilityOutline.ts +1 -1
- package/src/runtime/composables/useAriaLabel.ts +1 -1
- package/src/runtime/composables/useDarkMode.ts +15 -19
- package/src/runtime/composables/useDragWithThreshold.ts +6 -8
- package/src/runtime/composables/useGlobalResizeObserver.ts +0 -1
- package/src/runtime/composables/useInjectedDarkMode.ts +2 -2
- package/src/runtime/composables/useInjectedI18n.ts +1 -1
- package/src/runtime/composables/useInjectedLocale.ts +3 -4
- package/src/runtime/composables/useScrollNearContainerEdges.stories.ts +4 -4
- package/src/runtime/composables/useScrollNearContainerEdges.ts +12 -13
- package/src/runtime/composables/useSetupI18n.ts +4 -7
- package/src/runtime/composables/useSetupLocale.ts +3 -5
- package/src/runtime/composables/useSuggestions.ts +25 -30
- package/src/runtime/directives/vDetectFlex.ts +5 -8
- package/src/runtime/directives/vExtractRootEl.ts +1 -1
- package/src/runtime/directives/vResizableCols.ts +3 -7
- package/src/runtime/directives/vResizeObserver.ts +1 -2
- package/src/runtime/globalResizeObserver.ts +0 -1
- package/src/runtime/helpers/NotificationHandler.ts +8 -12
- package/src/runtime/helpers/base64ToImg.ts +2 -3
- package/src/runtime/helpers/createNoonUtcDate.ts +0 -1
- package/src/runtime/helpers/defaultTranslationFunction.ts +0 -1
- package/src/runtime/helpers/getTimeZoneList.ts +0 -1
- package/src/runtime/helpers/readFile.ts +2 -2
- package/src/runtime/helpers/resizeObserverWrapper.ts +0 -1
- package/src/runtime/helpers/storybook.ts +2 -3
- package/src/runtime/main.lib.ts +0 -2
- package/src/runtime/nuxt/plugins/vue-plugin.ts +4 -5
- package/src/runtime/tailwind/themeConvertionOpts.ts +3 -4
- package/src/runtime/theme.ts +0 -1
- package/src/runtime/types/index.ts +3 -4
- package/src/runtime/utils/notifyIfError.ts +2 -2
- package/src/runtime/utils/twMerge.ts +2 -2
- package/src/runtime/vue/VueComponentsPlugin.ts +1 -2
- package/src/runtime/vue/registerComponents.ts +0 -1
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
-
import {
|
|
2
|
+
import type { AnyFunction } from "@alanscodelog/utils"
|
|
3
3
|
import { isBlank } from "@alanscodelog/utils/isBlank"
|
|
4
4
|
import { isObject } from "@alanscodelog/utils/isObject"
|
|
5
5
|
import { pushIfNotIn } from "@alanscodelog/utils/pushIfNotIn"
|
|
6
6
|
import { removeIfIn } from "@alanscodelog/utils/removeIfIn"
|
|
7
7
|
import { computed, type Ref, ref, toRaw, watch } from "vue"
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
9
|
+
import type { SuggestionsEmits, SuggestionsOptions } from "../components/shared/props.js"
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* The logic for the suggestions component.
|
|
14
13
|
*
|
|
15
14
|
* Note that while object suggestions are supported, the `suggestionLabel` prop is required and $inputModel and $modelValue will still be string values (as returned by the suggestionLabel function).
|
|
16
15
|
*/
|
|
17
|
-
|
|
16
|
+
|
|
18
17
|
export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>(
|
|
19
18
|
$inputValue: Ref<string>,
|
|
20
19
|
$modelValue: Ref<TMultivalue extends true ? string[] : string>,
|
|
@@ -46,12 +45,12 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
46
45
|
const defaultSuggestionsFilter = (input: string, items: TSuggestion[]): TSuggestion[] => input === ""
|
|
47
46
|
? [...items]
|
|
48
47
|
: items.filter(item => {
|
|
49
|
-
|
|
48
|
+
if (Array.isArray($modelValue.value)) {
|
|
50
49
|
// always include selected values for unselecting
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
if ($modelValue.value.includes(getSuggestionLabel(item))) return true
|
|
51
|
+
}
|
|
52
|
+
return getSuggestionLabel(item).toLowerCase().includes(input.toLowerCase())
|
|
53
|
+
})
|
|
55
54
|
const suggestionsFilter = computed(() => opts.suggestionsFilter ?? defaultSuggestionsFilter)
|
|
56
55
|
|
|
57
56
|
const suggestionsList = computed(() => {
|
|
@@ -81,8 +80,8 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
81
80
|
|
|
82
81
|
const openable = computed(() =>
|
|
83
82
|
opts.canOpen && (
|
|
84
|
-
(isBlank($inputValue.value) && opts.allowOpenEmpty)
|
|
85
|
-
suggestionAvailable.value
|
|
83
|
+
(isBlank($inputValue.value) && opts.allowOpenEmpty)
|
|
84
|
+
|| suggestionAvailable.value
|
|
86
85
|
|
|
87
86
|
)
|
|
88
87
|
)
|
|
@@ -99,7 +98,6 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
99
98
|
return undefined
|
|
100
99
|
})
|
|
101
100
|
|
|
102
|
-
|
|
103
101
|
// methods
|
|
104
102
|
// returns true if the value was removed
|
|
105
103
|
function setValue(val: string): boolean {
|
|
@@ -135,12 +133,12 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
135
133
|
}
|
|
136
134
|
$open.value = true
|
|
137
135
|
}
|
|
138
|
-
|
|
136
|
+
|
|
139
137
|
function enterSuggestion(num: number, doClose: boolean = true): void {
|
|
140
138
|
if (num < -1 || num > (filteredSuggestions.value?.length ?? 0)) return
|
|
141
139
|
if (debug) console.log("enterSuggestion", num)
|
|
142
140
|
if (filteredSuggestions.value === undefined) return
|
|
143
|
-
|
|
141
|
+
|
|
144
142
|
const suggestion = filteredSuggestions.value[num]
|
|
145
143
|
const val = getSuggestionLabel(suggestion)
|
|
146
144
|
const wasRemoved = setValue(val)
|
|
@@ -174,7 +172,7 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
174
172
|
activeSuggestion.value = filteredSuggestions.value!.length - 1
|
|
175
173
|
}
|
|
176
174
|
}
|
|
177
|
-
|
|
175
|
+
|
|
178
176
|
function toggleSuggestions(): void {
|
|
179
177
|
$open.value ? closeSuggestions() : openSuggestions()
|
|
180
178
|
}
|
|
@@ -202,7 +200,7 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
202
200
|
function lastSuggestion(): void {
|
|
203
201
|
selectSuggestion(Infinity)
|
|
204
202
|
}
|
|
205
|
-
|
|
203
|
+
|
|
206
204
|
function cancel(): void {
|
|
207
205
|
if (Array.isArray($modelValue.value)) {
|
|
208
206
|
$inputValue.value = ""
|
|
@@ -213,30 +211,29 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
213
211
|
closeSuggestions()
|
|
214
212
|
}
|
|
215
213
|
|
|
216
|
-
|
|
217
214
|
watch(() => opts.canOpen, val => {
|
|
218
215
|
if (!val) {
|
|
219
216
|
if (debug) console.log("canOpen changed to false, closing suggestions")
|
|
220
217
|
closeSuggestions()
|
|
221
218
|
}
|
|
222
219
|
})
|
|
223
|
-
|
|
220
|
+
|
|
224
221
|
watch(openable, val => {
|
|
225
222
|
if (!val) {
|
|
226
223
|
if (debug) console.log("openable changed to false, closing suggestions")
|
|
227
224
|
closeSuggestions()
|
|
228
225
|
}
|
|
229
226
|
})
|
|
230
|
-
|
|
227
|
+
|
|
231
228
|
watch(isValidSuggestion, () => {
|
|
232
229
|
if (!isValidSuggestion.value) {
|
|
233
230
|
if (debug) console.log("isValidSuggestion changed to false, opening suggestions")
|
|
234
231
|
openSuggestions()
|
|
235
232
|
}
|
|
236
233
|
})
|
|
237
|
-
|
|
234
|
+
|
|
238
235
|
// sync vmodels and vmodel effects
|
|
239
|
-
|
|
236
|
+
|
|
240
237
|
watch($modelValue, () => {
|
|
241
238
|
if (Array.isArray($modelValue.value)) {
|
|
242
239
|
$inputValue.value = ""
|
|
@@ -272,7 +269,7 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
272
269
|
if (debug) console.log("input changed, suggestion available, opening suggestions")
|
|
273
270
|
openSuggestions()
|
|
274
271
|
}
|
|
275
|
-
|
|
272
|
+
|
|
276
273
|
if (!opts.restrictToSuggestions && !Array.isArray($modelValue.value)) {
|
|
277
274
|
if (debug) console.log("input changed, unrestricted, setting modelValue")
|
|
278
275
|
setValue($inputValue.value)
|
|
@@ -282,16 +279,15 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
282
279
|
selectSuggestion(suggestionsList.value.indexOf(exactlyMatchingSuggestion.value))
|
|
283
280
|
} else {
|
|
284
281
|
if (debug) console.log("input changed, not exactly matching, finding longest match")
|
|
285
|
-
|
|
286
|
-
const i
|
|
287
|
-
opts.suggestionSelector?.(filteredSuggestions.value ?? [], $inputValue.value)
|
|
288
|
-
|
|
282
|
+
|
|
283
|
+
const i
|
|
284
|
+
= opts.suggestionSelector?.(filteredSuggestions.value ?? [], $inputValue.value)
|
|
285
|
+
?? defaultSuggestionSelector(filteredSuggestions.value ?? [], $inputValue.value)
|
|
289
286
|
|
|
290
287
|
selectSuggestion(i)
|
|
291
288
|
}
|
|
292
289
|
})
|
|
293
290
|
|
|
294
|
-
|
|
295
291
|
return {
|
|
296
292
|
list: suggestionsList,
|
|
297
293
|
filtered: filteredSuggestions,
|
|
@@ -314,12 +310,11 @@ export function useSuggestions<TSuggestion, TMultivalue extends boolean = false>
|
|
|
314
310
|
prev: prevSuggestion,
|
|
315
311
|
next: nextSuggestion,
|
|
316
312
|
first: firstSuggestion,
|
|
317
|
-
last: lastSuggestion
|
|
313
|
+
last: lastSuggestion
|
|
318
314
|
|
|
319
315
|
}
|
|
320
316
|
}
|
|
321
317
|
|
|
322
|
-
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
323
318
|
export function useSuggestionsInputAria(
|
|
324
319
|
id: Ref<string>,
|
|
325
320
|
$open: Ref<boolean>,
|
|
@@ -331,7 +326,7 @@ export function useSuggestionsInputAria(
|
|
|
331
326
|
"aria-controls": suggestions !== undefined ? `suggestions-${id.value}` : undefined,
|
|
332
327
|
role: suggestions ? "combobox" : undefined,
|
|
333
328
|
"aria-expanded": suggestions !== undefined ? $open.value : undefined,
|
|
334
|
-
"aria-activedescendant": $open.value ? `suggestion-${id.value}-${activeSuggestion.value}` : undefined
|
|
329
|
+
"aria-activedescendant": $open.value ? `suggestion-${id.value}-${activeSuggestion.value}` : undefined
|
|
335
330
|
}))
|
|
336
331
|
return ariaInputProps
|
|
337
332
|
}
|
|
@@ -7,7 +7,6 @@ import type { Directive } from "vue"
|
|
|
7
7
|
import { globalResizeObserver } from "../globalResizeObserver.js"
|
|
8
8
|
import type { ResizeCallback } from "../types/index.js"
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
const observer = globalResizeObserver
|
|
12
11
|
/**
|
|
13
12
|
* Directive for detecting flex wrap on element. It will bind a resize-observer to the element to detect when it's children have wrapped and add a .wrapped class when they are.
|
|
@@ -56,7 +55,7 @@ function removeCallback(throttleTime: number): void {
|
|
|
56
55
|
|
|
57
56
|
function callback(_rect: DOMRectReadOnly, el: Element): void {
|
|
58
57
|
const _ = elMap.get(el as HTMLElement)
|
|
59
|
-
if (!_) {unreachable()}
|
|
58
|
+
if (!_) { unreachable() }
|
|
60
59
|
const pos = _.vertical ? "x" : "y"
|
|
61
60
|
const dimension = _.vertical ? "width" : "height"
|
|
62
61
|
|
|
@@ -78,7 +77,6 @@ function callback(_rect: DOMRectReadOnly, el: Element): void {
|
|
|
78
77
|
const firstRect = firstChild.getBoundingClientRect()
|
|
79
78
|
const lastRect = lastChild.getBoundingClientRect()
|
|
80
79
|
|
|
81
|
-
|
|
82
80
|
// should work even if the flex items are different heights
|
|
83
81
|
// only exceptions i think are if the element aligns itself below another element somehow
|
|
84
82
|
// rounded to nearest 10th since getBoundingClientRect can have rounding errors
|
|
@@ -89,14 +87,13 @@ function callback(_rect: DOMRectReadOnly, el: Element): void {
|
|
|
89
87
|
}
|
|
90
88
|
}
|
|
91
89
|
|
|
92
|
-
|
|
93
90
|
export const vDetectFlex: Directive = {
|
|
94
91
|
mounted(el: HTMLElement, { value: { condition = true, vertical = false, throttleTime = 50, ignoreSelector = ".detect-flex-ignore" } = {} }: DetectFlexOptions) {
|
|
95
92
|
const _: PrivateState = {
|
|
96
93
|
vertical,
|
|
97
94
|
lastCondition: condition,
|
|
98
95
|
lastThrottleTime: throttleTime,
|
|
99
|
-
ignoreSelector
|
|
96
|
+
ignoreSelector
|
|
100
97
|
}
|
|
101
98
|
elMap.set(el, _)
|
|
102
99
|
if (condition) {
|
|
@@ -106,7 +103,7 @@ export const vDetectFlex: Directive = {
|
|
|
106
103
|
},
|
|
107
104
|
updated(el: HTMLElement, { value: { condition = true, vertical = false, throttleTime = 50, ignoreSelector = ".detect-flex-ignore" } = {} }: DetectFlexOptions) {
|
|
108
105
|
const _ = elMap.get(el)
|
|
109
|
-
if (!_) {unreachable()}
|
|
106
|
+
if (!_) { unreachable() }
|
|
110
107
|
|
|
111
108
|
_.vertical = vertical
|
|
112
109
|
_.ignoreSelector = ignoreSelector
|
|
@@ -135,7 +132,7 @@ export const vDetectFlex: Directive = {
|
|
|
135
132
|
},
|
|
136
133
|
unmounted(el: HTMLElement, { value: { vertical = false, throttleTime = 50, ignoreSelector = ".detect-flex-ignore" } = {} }: DetectFlexOptions) {
|
|
137
134
|
const _ = elMap.get(el)
|
|
138
|
-
if (!_) {unreachable()}
|
|
135
|
+
if (!_) { unreachable() }
|
|
139
136
|
_.vertical = vertical
|
|
140
137
|
_.ignoreSelector = ignoreSelector
|
|
141
138
|
_.lastThrottleTime = throttleTime
|
|
@@ -147,7 +144,7 @@ export const vDetectFlex: Directive = {
|
|
|
147
144
|
},
|
|
148
145
|
getSSRProps() {
|
|
149
146
|
return {}
|
|
150
|
-
}
|
|
147
|
+
}
|
|
151
148
|
}
|
|
152
149
|
type DetectFlexOptions = {
|
|
153
150
|
value: {
|
|
@@ -7,7 +7,6 @@ import type { Directive, Ref } from "vue"
|
|
|
7
7
|
import { globalResizeObserver } from "../globalResizeObserver.js"
|
|
8
8
|
import type { ResizableOptions, ResizeCallback } from "../types/index.js"
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
const observer = globalResizeObserver
|
|
12
11
|
type Data = {
|
|
13
12
|
margin: number
|
|
@@ -32,7 +31,7 @@ type ResizableElement = HTMLElement
|
|
|
32
31
|
const defaultOpts: Omit<ResizableOptions, "colCount" | "widths" | "selector"> = {
|
|
33
32
|
fitWidth: true,
|
|
34
33
|
margin: "dynamic",
|
|
35
|
-
enabled: true
|
|
34
|
+
enabled: true
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
const callback: ResizeCallback = (_rect: DOMRectReadOnly, el: Element): void => {
|
|
@@ -132,10 +131,9 @@ export const vResizableCols: Directive = {
|
|
|
132
131
|
},
|
|
133
132
|
getSSRProps() {
|
|
134
133
|
return {}
|
|
135
|
-
}
|
|
134
|
+
}
|
|
136
135
|
}
|
|
137
136
|
|
|
138
|
-
|
|
139
137
|
function setWidth(col: HTMLElement, amountInPx: number, el: ResizableElement): void {
|
|
140
138
|
const $el = getElInfo(el)
|
|
141
139
|
const width = Math.max($el.margin, amountInPx)
|
|
@@ -148,7 +146,6 @@ function setWidth(col: HTMLElement, amountInPx: number, el: ResizableElement): v
|
|
|
148
146
|
}
|
|
149
147
|
}
|
|
150
148
|
|
|
151
|
-
|
|
152
149
|
function getBox(el: Element): { x: number, width: number } {
|
|
153
150
|
const rect = el.getBoundingClientRect()
|
|
154
151
|
// the numbers need to be rounded or else the columns will start to shift
|
|
@@ -228,7 +225,6 @@ function createPointerMoveHandler(el: ResizableElement) {
|
|
|
228
225
|
return
|
|
229
226
|
}
|
|
230
227
|
|
|
231
|
-
|
|
232
228
|
setWidth(col, newWidth, el)
|
|
233
229
|
setWidth(colNext!, rightBox.width + diff, el)
|
|
234
230
|
}
|
|
@@ -309,7 +305,7 @@ function setupColumns(el: ResizableElement, opts: ResizableOptions): void {
|
|
|
309
305
|
margin: opts.margin === "dynamic" ? gripWidth : opts.margin,
|
|
310
306
|
colCount: opts.colCount,
|
|
311
307
|
widths: opts.widths,
|
|
312
|
-
selector: opts.selector
|
|
308
|
+
selector: opts.selector
|
|
313
309
|
}
|
|
314
310
|
elMap.set(el, $el)
|
|
315
311
|
const els = getColEls(el)
|
|
@@ -3,7 +3,6 @@ import type { Directive } from "vue"
|
|
|
3
3
|
import { globalResizeObserver } from "../globalResizeObserver.js"
|
|
4
4
|
import type { ResizeCallback } from "../types/index.js"
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
const observer = globalResizeObserver
|
|
8
7
|
const lastCondition = Symbol("lastCondition")
|
|
9
8
|
const checkCallback = (cb: any): void => {
|
|
@@ -35,7 +34,7 @@ export const vResizeObserver: Directive = {
|
|
|
35
34
|
},
|
|
36
35
|
getSSRProps() {
|
|
37
36
|
return {}
|
|
38
|
-
}
|
|
37
|
+
}
|
|
39
38
|
}
|
|
40
39
|
type Options = {
|
|
41
40
|
value: {
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import { ResizeObserverWrapper } from "./helpers/resizeObserverWrapper.js"
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
if (typeof ResizeObserver === "undefined") {
|
|
9
8
|
// eslint-disable-next-line no-console
|
|
10
9
|
console.warn("You are using a directive that uses a ResizeObserver or are importing something that uses this resize observer in a context (e.g. the server) where ResizeObserver does not exist.")
|
|
@@ -6,10 +6,9 @@ import { isBlank } from "@alanscodelog/utils/isBlank"
|
|
|
6
6
|
import { pretty } from "@alanscodelog/utils/pretty"
|
|
7
7
|
import { setReadOnly } from "@alanscodelog/utils/setReadOnly"
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
export class NotificationHandler<
|
|
11
10
|
TRawEntry extends RawNotificationEntry<any, any> = RawNotificationEntry<any, any>,
|
|
12
|
-
TEntry extends NotificationEntry<TRawEntry> = NotificationEntry<TRawEntry
|
|
11
|
+
TEntry extends NotificationEntry<TRawEntry> = NotificationEntry<TRawEntry>
|
|
13
12
|
> {
|
|
14
13
|
timeout: number = 5000
|
|
15
14
|
|
|
@@ -30,7 +29,7 @@ export class NotificationHandler<
|
|
|
30
29
|
constructor({
|
|
31
30
|
timeout,
|
|
32
31
|
stringifier,
|
|
33
|
-
maxHistory
|
|
32
|
+
maxHistory
|
|
34
33
|
}: {
|
|
35
34
|
timeout?: NotificationHandler<TRawEntry>["timeout"]
|
|
36
35
|
stringifier?: NotificationHandler<TRawEntry>["stringifier"]
|
|
@@ -101,11 +100,10 @@ export class NotificationHandler<
|
|
|
101
100
|
timeout: rawEntry.timeout === true
|
|
102
101
|
? this.timeout
|
|
103
102
|
: rawEntry.timeout !== undefined && rawEntry.timeout !== false
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
? rawEntry.timeout
|
|
104
|
+
: undefined
|
|
106
105
|
} as any as TEntry
|
|
107
106
|
|
|
108
|
-
|
|
109
107
|
if (rawEntry.cancellable === true || (rawEntry.cancellable === undefined && entry.options?.includes("Cancel"))) {
|
|
110
108
|
entry.cancellable = "Cancel" as any
|
|
111
109
|
}
|
|
@@ -120,8 +118,8 @@ export class NotificationHandler<
|
|
|
120
118
|
|
|
121
119
|
async notify<TNotifyEntry extends RawNotificationEntry<any, any>>(rawEntry: TNotifyEntry):
|
|
122
120
|
NotificationPromise<TNotifyEntry["options"][number] extends string
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
? TNotifyEntry["options"][number]
|
|
122
|
+
: "Ok" | "Cancel"> {
|
|
125
123
|
const entry = this._createEntry(rawEntry)
|
|
126
124
|
entry.promise = new Promise(_resolve => {
|
|
127
125
|
entry.resolve = _resolve
|
|
@@ -195,7 +193,7 @@ export type NotificationPromise<TOption extends string = string> = Promise<TOpti
|
|
|
195
193
|
|
|
196
194
|
export type RawNotificationEntry<
|
|
197
195
|
TOptions extends string[] = ["Ok", "Cancel"],
|
|
198
|
-
TCancellable extends boolean | TOptions[number] = "Cancel"
|
|
196
|
+
TCancellable extends boolean | TOptions[number] = "Cancel"
|
|
199
197
|
> = {
|
|
200
198
|
message: string
|
|
201
199
|
title?: string
|
|
@@ -215,7 +213,7 @@ export type RawNotificationEntry<
|
|
|
215
213
|
}
|
|
216
214
|
|
|
217
215
|
export type NotificationEntry<
|
|
218
|
-
TRawEntry extends RawNotificationEntry<any, any> = RawNotificationEntry<any, any
|
|
216
|
+
TRawEntry extends RawNotificationEntry<any, any> = RawNotificationEntry<any, any>
|
|
219
217
|
> = Omit<MakeRequired<TRawEntry, "options" | "requiresAction" | "default" | "dangerous">, "cancellable"> & {
|
|
220
218
|
promise: NotificationPromise
|
|
221
219
|
resolve: AnyFunction
|
|
@@ -227,6 +225,4 @@ export type NotificationEntry<
|
|
|
227
225
|
|
|
228
226
|
export type NotificationListener<TEntry extends NotificationEntry<any>> = (notification: TEntry, type: "added" | "resolved" | "deleted") => void
|
|
229
227
|
|
|
230
|
-
|
|
231
228
|
export type NotificationStringifier<T extends NotificationEntry<any>> = (notification: T) => string
|
|
232
|
-
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
export const base64ToImg = async (imageSrc: string): Promise<HTMLImageElement> => {
|
|
2
2
|
const img = new Image()
|
|
3
3
|
|
|
4
|
-
const loaded = new Promise(
|
|
4
|
+
const loaded = new Promise(resolve => {
|
|
5
5
|
img.addEventListener("load", () => {
|
|
6
6
|
resolve(img)
|
|
7
7
|
})
|
|
8
|
-
})
|
|
8
|
+
}) as any as Promise<HTMLImageElement>
|
|
9
9
|
|
|
10
10
|
img.src = imageSrc // must be set after
|
|
11
11
|
await loaded
|
|
12
12
|
return img
|
|
13
13
|
}
|
|
14
|
-
|
|
@@ -5,8 +5,8 @@ export const readFile = async <TType extends "DataUrl" | "ArrayBuffer" | "Binary
|
|
|
5
5
|
):
|
|
6
6
|
Promise<
|
|
7
7
|
TType extends "ArrayBuffer"
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
? ArrayBuffer
|
|
9
|
+
: string
|
|
10
10
|
> => new Promise((resolve, reject) => {
|
|
11
11
|
const reader = new FileReader()
|
|
12
12
|
reader.addEventListener("load", () => {
|
|
@@ -2,7 +2,6 @@ import type { Ref } from "vue"
|
|
|
2
2
|
|
|
3
3
|
import { hasModifiers } from "./hasModifiers.js"
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
export const createRecorderHandler = (
|
|
7
6
|
recordingValue: Ref<string>,
|
|
8
7
|
recording: Ref<boolean>,
|
|
@@ -23,7 +22,7 @@ export const createRecorderHandler = (
|
|
|
23
22
|
recordingValue.value += ` ${e.key}`
|
|
24
23
|
},
|
|
25
24
|
mousedown(e: MouseEvent) {
|
|
26
|
-
const target =
|
|
25
|
+
const target = e.target as any
|
|
27
26
|
const el = recordingEl.value
|
|
28
27
|
if (target === el || el?.contains(target)) {
|
|
29
28
|
return
|
|
@@ -34,7 +33,7 @@ export const createRecorderHandler = (
|
|
|
34
33
|
wheel(e: WheelEvent) {
|
|
35
34
|
recordingValue.value += ` ${e.deltaY > 0 ? "↓" : "↑"}`
|
|
36
35
|
e.preventDefault()
|
|
37
|
-
}
|
|
36
|
+
}
|
|
38
37
|
})
|
|
39
38
|
|
|
40
39
|
export const createRecorderWatchEffect = (recordingValue: Ref<string>, recording: Ref<boolean>, modelValue: Ref<string>, values?: Ref<string[]>) => () => {
|
package/src/runtime/main.lib.ts
CHANGED
|
@@ -9,7 +9,6 @@ export { VueComponentsPlugin } from "./vue/VueComponentsPlugin.js"
|
|
|
9
9
|
|
|
10
10
|
import type * as components from "./components/index.js"
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
type Components = typeof components
|
|
14
13
|
|
|
15
14
|
/**
|
|
@@ -28,4 +27,3 @@ type Components = typeof components
|
|
|
28
27
|
export type GlobalComponentTypes = {
|
|
29
28
|
[key in keyof Components]: Components[key]
|
|
30
29
|
}
|
|
31
|
-
|
|
@@ -4,16 +4,15 @@ import { defineNuxtPlugin, useRuntimeConfig } from "#imports"
|
|
|
4
4
|
|
|
5
5
|
import { registerDirectives } from "../../vue/registerDirectives.js"
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
export default defineNuxtPlugin({
|
|
9
8
|
name: "components-plugin",
|
|
10
|
-
async setup(nuxtApp): Promise<void> {
|
|
9
|
+
async setup(nuxtApp: any): Promise<void> {
|
|
11
10
|
const config = useRuntimeConfig().public.witchcraftUi
|
|
12
11
|
const app = nuxtApp.vueApp
|
|
13
12
|
const directives = (isArray(config?.directives)
|
|
14
|
-
|
|
13
|
+
? (await Promise.all(config.directives.map(async (name: string) => (import(`../../directives/${name}.ts`))))).map((_: any) => Object.values(_)[0])
|
|
15
14
|
// @ts-expect-error ts filetype needed for nuxt
|
|
16
|
-
|
|
15
|
+
: await import(`../../directives/index.ts`))
|
|
17
16
|
registerDirectives(app as any, Object.values(directives))
|
|
18
|
-
}
|
|
17
|
+
}
|
|
19
18
|
})
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { themeAsTailwindCss } from "metamorphosis/tailwind"
|
|
3
2
|
|
|
4
3
|
export const themeConvertionOpts: Parameters<typeof themeAsTailwindCss>[1] = {
|
|
5
4
|
topLevel: ["number-spacing"],
|
|
@@ -10,6 +9,6 @@ export const themeConvertionOpts: Parameters<typeof themeAsTailwindCss>[1] = {
|
|
|
10
9
|
"color-warning": "500",
|
|
11
10
|
"color-ok": "500",
|
|
12
11
|
"color-error": "500",
|
|
13
|
-
"color-accent": "500"
|
|
14
|
-
}
|
|
12
|
+
"color-accent": "500"
|
|
13
|
+
}
|
|
15
14
|
}
|
package/src/runtime/theme.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ErrorW } from "@alanscodelog/utils"
|
|
2
|
-
import {
|
|
2
|
+
import type { Ref } from "vue"
|
|
3
3
|
|
|
4
4
|
export type ResizableOptions = {
|
|
5
5
|
/**
|
|
@@ -51,7 +51,6 @@ export type ResizeCallback = (_rect: DOMRectReadOnly, el: Element) => void
|
|
|
51
51
|
|
|
52
52
|
export type FileInputError = ErrorW<{ file: File, isValidMimeType: boolean, isValidExtension: boolean }>
|
|
53
53
|
|
|
54
|
-
|
|
55
54
|
/** h 0-360+ (deg), s 0-100%, v 0-100%, a 0-1 */
|
|
56
55
|
export type HsvaColor = { h: number, s: number, v: number, a?: number }
|
|
57
56
|
/** rgb 0-255, 0-1 for alpha */
|
|
@@ -60,7 +59,7 @@ export type RgbaColor = { r: number, g: number, b: number, a?: number }
|
|
|
60
59
|
export type Point = { x: number, y: number }
|
|
61
60
|
|
|
62
61
|
export type ScrollNearContainerEdgesOptions = {
|
|
63
|
-
containerEl: Ref<
|
|
62
|
+
containerEl: Ref<HTMLElement | null>
|
|
64
63
|
/** Margin inside contianer that allows scrolling. 10 by default. */
|
|
65
64
|
scrollMargin?: number
|
|
66
65
|
/** Margin around container that still allows scrolling. 0 by defualt. */
|
|
@@ -80,7 +79,7 @@ export type ScrollNearContainerEdgesOptions = {
|
|
|
80
79
|
}
|
|
81
80
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
82
81
|
export type SimpleDOMRect = Omit<DOMRect, "toJSON">
|
|
83
|
-
|
|
82
|
+
|
|
84
83
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
85
84
|
export interface IPopupReference { getBoundingClientRect: () => SimpleDOMRect }
|
|
86
85
|
export type PopupPosition = { x: number, y: number, maxWidth?: number, maxHeight?: number }
|
|
@@ -13,7 +13,7 @@ export function notifyIfError<T>(
|
|
|
13
13
|
err: T, {
|
|
14
14
|
logger,
|
|
15
15
|
ns,
|
|
16
|
-
force = false
|
|
16
|
+
force = false
|
|
17
17
|
}: {
|
|
18
18
|
logger?: { debug: (...args: any[]) => void }
|
|
19
19
|
/* Logger namespace. */
|
|
@@ -24,7 +24,7 @@ export function notifyIfError<T>(
|
|
|
24
24
|
if (force || err instanceof Error) {
|
|
25
25
|
const errMessage = {
|
|
26
26
|
message: err instanceof Error ? err.message : `Unknown error ${err as any}`,
|
|
27
|
-
code: err instanceof TypedError ? err.code : undefined
|
|
27
|
+
code: err instanceof TypedError ? err.code : undefined
|
|
28
28
|
}
|
|
29
29
|
if (logger) {
|
|
30
30
|
logger.debug({
|
|
@@ -3,8 +3,8 @@ import { extendTailwindMerge } from "tailwind-merge"
|
|
|
3
3
|
const _twMergeExtend = {
|
|
4
4
|
extend: {
|
|
5
5
|
classGroups: {
|
|
6
|
-
"focus-outline": [{ "focus-outline": ["", "no-offset", "none"]}]
|
|
7
|
-
}
|
|
6
|
+
"focus-outline": [{ "focus-outline": ["", "no-offset", "none"] }]
|
|
7
|
+
}
|
|
8
8
|
}
|
|
9
9
|
} satisfies Parameters<typeof extendTailwindMerge>[0]
|
|
10
10
|
|