@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
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
v-if="
|
|
3
|
+
v-if="$open"
|
|
4
4
|
:id="`suggestions-${id ?? fallbackId}`"
|
|
5
5
|
:class="twMerge(`
|
|
6
6
|
suggestions
|
|
7
7
|
bg-bg
|
|
8
8
|
dark:bg-fg
|
|
9
|
+
dark:text-bg
|
|
9
10
|
`,
|
|
10
11
|
($.attrs as any)?.class
|
|
11
12
|
)"
|
|
12
|
-
:data-open="
|
|
13
|
+
:data-open="$open"
|
|
13
14
|
role="listbox"
|
|
14
15
|
ref="el"
|
|
15
16
|
v-bind="{...$.attrs, class:undefined}"
|
|
@@ -18,12 +19,15 @@
|
|
|
18
19
|
<div :id="`suggestion-${id ?? fallbackId}-${index}`"
|
|
19
20
|
role="option"
|
|
20
21
|
:class="twMerge(`
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
index=== suggestions.active && `
|
|
22
|
+
suggestions--item
|
|
23
|
+
user-select-none
|
|
24
|
+
cursor-pointer
|
|
25
|
+
px-2
|
|
26
|
+
`,
|
|
27
|
+
index=== suggestions.active && `
|
|
28
|
+
bg-accent-200
|
|
29
|
+
dark:bg-accent-800/70
|
|
30
|
+
`,
|
|
27
31
|
($.itemAttrs as any)?.class
|
|
28
32
|
)"
|
|
29
33
|
v-bind="{...$.itemAttrs, class:undefined}"
|
|
@@ -33,17 +37,28 @@
|
|
|
33
37
|
:key="item"
|
|
34
38
|
@mouseover="suggestions.active = index"
|
|
35
39
|
@mousedown.prevent
|
|
36
|
-
@mouseup="suggestions.
|
|
40
|
+
@mouseup="suggestions.enterIndex(index, !Array.isArray($modelValue))"
|
|
37
41
|
>
|
|
38
|
-
<slot name="item"
|
|
39
|
-
|
|
42
|
+
<slot name="item"
|
|
43
|
+
:item="item"
|
|
44
|
+
:index="index"
|
|
45
|
+
:is-selected="Array.isArray($modelValue) ? $modelValue.includes(item) : $modelValue === item"
|
|
46
|
+
>
|
|
47
|
+
<div class="flex gap-2 nowrap">
|
|
48
|
+
<lib-checkbox
|
|
49
|
+
v-if="Array.isArray($modelValue) && showSelectedValues"
|
|
50
|
+
:model-value="$modelValue.includes(item)"
|
|
51
|
+
@mousedown.prevent
|
|
52
|
+
/>
|
|
53
|
+
<div> {{ item }} </div>
|
|
54
|
+
</div>
|
|
40
55
|
</slot>
|
|
41
56
|
</div>
|
|
42
57
|
</div>
|
|
43
58
|
</template>
|
|
44
59
|
|
|
45
60
|
|
|
46
|
-
<script setup lang="ts" generic="TSuggestion extends string | object">
|
|
61
|
+
<script setup lang="ts" generic="TSuggestion extends string | object, TValue extends string|string[]">
|
|
47
62
|
|
|
48
63
|
import { type HTMLAttributes,reactive, ref } from "vue"
|
|
49
64
|
|
|
@@ -51,7 +66,8 @@ import { useDivideAttrs } from "../../composables/useDivideAttrs.js"
|
|
|
51
66
|
import { useSuggestions } from "../../composables/useSuggestions.js"
|
|
52
67
|
import { hasModifiers } from "../../helpers/hasModifiers.js"
|
|
53
68
|
import { twMerge } from "../../utils/twMerge.js"
|
|
54
|
-
import
|
|
69
|
+
import LibCheckbox from "../LibCheckbox/LibCheckbox.vue"
|
|
70
|
+
import { type BaseInteractiveProps, baseInteractivePropsDefaults, getFallbackId,type LabelProps, type LinkableByIdProps, type SuggestionsEmits, type SuggestionsProps, type WrapperProps } from "../shared/props.js"
|
|
55
71
|
|
|
56
72
|
defineOptions({
|
|
57
73
|
name: "lib-suggestions",
|
|
@@ -67,17 +83,15 @@ const fallbackId = getFallbackId()
|
|
|
67
83
|
const props = withDefaults(defineProps<Props & SuggestionsProps<TSuggestion>>(), {
|
|
68
84
|
isValid: true,
|
|
69
85
|
canOpen: true,
|
|
70
|
-
values: undefined,
|
|
71
86
|
filterKeydown: undefined,
|
|
72
87
|
...baseInteractivePropsDefaults
|
|
73
88
|
})
|
|
74
|
-
|
|
75
89
|
/**
|
|
76
90
|
* The final valid value. This is *not* the value you want to share with the input. If `restrictToSuggestions` is true this will not update on any invalid values that `inputValue` might be set to.
|
|
77
91
|
*
|
|
78
92
|
* If suggestions are objects, this will be the string returned by the `suggestionLabel` prop.
|
|
79
93
|
*/
|
|
80
|
-
const $modelValue = defineModel<
|
|
94
|
+
const $modelValue = defineModel<TValue>("modelValue", { required: true })
|
|
81
95
|
/**
|
|
82
96
|
* If the element is bound to an input, this is the value that the input should be sharing.
|
|
83
97
|
*
|
|
@@ -85,17 +99,19 @@ const $modelValue = defineModel<string>("modelValue", { required: true })
|
|
|
85
99
|
*/
|
|
86
100
|
const $inputValue = defineModel<string >("inputValue", { default: "" })
|
|
87
101
|
|
|
102
|
+
const $open = defineModel<boolean>("open", { default: false })
|
|
103
|
+
|
|
88
104
|
|
|
89
105
|
if (typeof props.suggestions?.[0] === "object" && !props.suggestionLabel && !props.suggestionsFilter) {
|
|
90
106
|
throw new Error("`suggestionLabel` or `suggestionsFilter` must be passed if suggestions are objects.")
|
|
91
107
|
}
|
|
92
108
|
|
|
93
109
|
const el = ref<HTMLElement | null>(null)
|
|
94
|
-
const mousedown = ref(false)
|
|
95
110
|
|
|
96
|
-
const suggestions = reactive(useSuggestions(
|
|
111
|
+
const suggestions = reactive(useSuggestions<TSuggestion, TValue extends string[] ? true : false>(
|
|
97
112
|
$inputValue,
|
|
98
|
-
$modelValue,
|
|
113
|
+
$modelValue as any,
|
|
114
|
+
$open,
|
|
99
115
|
emits,
|
|
100
116
|
props
|
|
101
117
|
))
|
|
@@ -104,12 +120,12 @@ const inputKeydownHandler = (e: KeyboardEvent): void => {
|
|
|
104
120
|
if (props.filterKeydown?.(e)) return
|
|
105
121
|
if (hasModifiers(e)) return
|
|
106
122
|
if (e.key === "Enter") {
|
|
107
|
-
suggestions.enterSelected()
|
|
123
|
+
suggestions.enterSelected(!Array.isArray($modelValue))
|
|
108
124
|
e.preventDefault()
|
|
109
125
|
} else if (e.key === "Escape") {
|
|
110
126
|
suggestions.cancel()
|
|
111
127
|
e.preventDefault()
|
|
112
|
-
} else if (
|
|
128
|
+
} else if (!$open.value && ["ArrowDown", "ArrowUp", "PageUp", "PageDown"].includes(e.key) && suggestions.available) {
|
|
113
129
|
suggestions.open()
|
|
114
130
|
e.preventDefault()
|
|
115
131
|
if (e.key === "PageUp") {
|
|
@@ -134,14 +150,16 @@ const inputKeydownHandler = (e: KeyboardEvent): void => {
|
|
|
134
150
|
const inputBlurHandler = (e: MouseEvent): void => {
|
|
135
151
|
if (props.filterBlur?.(e)) return
|
|
136
152
|
|
|
137
|
-
if (
|
|
153
|
+
if (!$open.value) return
|
|
138
154
|
|
|
139
155
|
if (props.restrictToSuggestions) {
|
|
140
156
|
suggestions.cancel()
|
|
141
157
|
} else {
|
|
142
|
-
$modelValue.value
|
|
158
|
+
if (!Array.isArray($modelValue.value)) {
|
|
159
|
+
$modelValue.value = $inputValue.value as any
|
|
160
|
+
}
|
|
143
161
|
}
|
|
144
|
-
if (
|
|
162
|
+
if ($open.value) {
|
|
145
163
|
suggestions.close()
|
|
146
164
|
}
|
|
147
165
|
}
|
|
@@ -173,7 +191,6 @@ type RealProps =
|
|
|
173
191
|
& LinkableByIdProps
|
|
174
192
|
& LabelProps
|
|
175
193
|
& BaseInteractiveProps
|
|
176
|
-
& MultiValueProps
|
|
177
194
|
& {
|
|
178
195
|
/** Return true to prevent the keydown event from being handled. */
|
|
179
196
|
filterKeydown?: (e: KeyboardEvent) => boolean
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
, ($attrs as any).class)"
|
|
41
41
|
v-resizable-cols="resizableOptions"
|
|
42
42
|
>
|
|
43
|
-
<thead v-if="header">
|
|
44
|
-
<tr>
|
|
43
|
+
<thead v-if="header" class="table--header">
|
|
44
|
+
<tr class="table--row">
|
|
45
45
|
<template v-for="col,i of cols" :key="col">
|
|
46
46
|
<slot :name="`header-${col.toString()}`"
|
|
47
47
|
:class="[
|
|
48
48
|
extraClasses[`-1-${i}`],
|
|
49
|
-
'cell',
|
|
49
|
+
'cell table--header-cell',
|
|
50
50
|
(colConfig as any)[col]?.resizable === false
|
|
51
51
|
? 'no-resize'
|
|
52
52
|
: ''
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
>
|
|
57
57
|
<td :class="[
|
|
58
58
|
extraClasses[`-1-${i}`] ,
|
|
59
|
-
'cell',
|
|
59
|
+
'cell table--header-cell',
|
|
60
60
|
(colConfig as any)[col]?.resizable === false
|
|
61
61
|
? 'no-resize'
|
|
62
62
|
: ''
|
|
@@ -69,17 +69,17 @@
|
|
|
69
69
|
</template>
|
|
70
70
|
</tr>
|
|
71
71
|
</thead>
|
|
72
|
-
<tbody>
|
|
72
|
+
<tbody class="table--body">
|
|
73
73
|
<template v-for="item, i of values" :key="typeof itemKey === 'function' ? itemKey(item) : item[itemKey]">
|
|
74
|
-
<tr>
|
|
74
|
+
<tr class="table--row">
|
|
75
75
|
<template v-for="col, j of cols" :key="(typeof itemKey === 'function' ? itemKey(item) : item[itemKey]) + col.toString()">
|
|
76
76
|
<slot
|
|
77
77
|
:name="col"
|
|
78
78
|
:item="item"
|
|
79
79
|
:value="item[col]"
|
|
80
|
-
:class="extraClasses[`${i}-${j}`] + ' cell'"
|
|
80
|
+
:class="extraClasses[`${i}-${j}`] + 'table--cell cell'"
|
|
81
81
|
>
|
|
82
|
-
<td :class="extraClasses[`${i}-${j}`] + ' cell'">
|
|
82
|
+
<td :class="extraClasses[`${i}-${j}`] + 'table--cell cell'">
|
|
83
83
|
{{ item[col] }}
|
|
84
84
|
</td>
|
|
85
85
|
</slot>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const meta = {
|
|
2
|
+
title: "Other/Scrolling",
|
|
3
|
+
args: {}
|
|
4
|
+
};
|
|
5
|
+
export default meta;
|
|
6
|
+
export const Scrollbars = {
|
|
7
|
+
render: (args) => ({
|
|
8
|
+
setup: () => ({ args }),
|
|
9
|
+
template: `
|
|
10
|
+
<div
|
|
11
|
+
class="
|
|
12
|
+
relative
|
|
13
|
+
flex
|
|
14
|
+
flex-col
|
|
15
|
+
max-h-[300px]
|
|
16
|
+
max-w-[300px]
|
|
17
|
+
border-2
|
|
18
|
+
border-neutral-500
|
|
19
|
+
"
|
|
20
|
+
|
|
21
|
+
>
|
|
22
|
+
<div
|
|
23
|
+
class="overflow-auto"
|
|
24
|
+
>
|
|
25
|
+
<div class="h-[1000px] w-[1000px]"/>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
`
|
|
29
|
+
})
|
|
30
|
+
};
|
|
31
|
+
export const TextareaResizer = {
|
|
32
|
+
render: (args) => ({
|
|
33
|
+
setup: () => ({ args }),
|
|
34
|
+
template: `
|
|
35
|
+
<textarea class="
|
|
36
|
+
border-2
|
|
37
|
+
border-neutral-500
|
|
38
|
+
min-w-[200px]
|
|
39
|
+
min-h-[200px]
|
|
40
|
+
[resize:both]
|
|
41
|
+
" />
|
|
42
|
+
`
|
|
43
|
+
})
|
|
44
|
+
};
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
</template>
|
|
11
11
|
<script setup lang="ts">
|
|
12
12
|
|
|
13
|
-
import { computed,
|
|
13
|
+
import { computed, type HTMLAttributes, onBeforeUnmount, onMounted, type PropType, reactive, type Ref, ref, watch } from "vue"
|
|
14
14
|
|
|
15
15
|
import { twMerge } from "../../utils/twMerge.js"
|
|
16
16
|
import { baseInteractiveProps, type TailwindClassProp } from "../shared/props.js"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- Width 100% + 2xmargin in combination with the margins in LibRoot is a bit of a hack so that it looks like there's padding around the content in test mode (for storybook). We can't just absolutely position these controls or they make the container scroll. -->
|
|
3
|
-
<div class="flex gap-2 p-1 pb-10 -ml-10 w-[calc(100%_+_var(--spacing)*20)]">
|
|
3
|
+
<div class="test-controls flex gap-2 p-1 pb-10 -ml-10 w-[calc(100%_+_var(--spacing)*20)]">
|
|
4
4
|
<div class="flex-grow"/>
|
|
5
5
|
<div class="outline-indicator">{{ showOutline ? "Outline Enabled" : "Outline Disabled" }}</div>
|
|
6
6
|
<lib-dark-mode-switcher/>
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
export { default as LibTimeZonePicker } from "./LibDatePicker/LibTimeZonePicker.vue.js";
|
|
2
1
|
export { default as aria } from "./Aria/Aria.vue.js";
|
|
3
2
|
export { default as LibButton } from "./LibButton/LibButton.vue.js";
|
|
3
|
+
export { default as LibCheckbox } from "./LibCheckbox/LibCheckbox.vue.js";
|
|
4
|
+
export { default as LibColorInput } from "./LibColorInput/LibColorInput.vue.js";
|
|
5
|
+
export { default as LibColorPicker } from "./LibColorPicker/LibColorPicker.vue.js";
|
|
6
|
+
export { default as LibDarkModeSwitcher } from "./LibDarkModeSwitcher/LibDarkModeSwitcher.vue.js";
|
|
4
7
|
export { default as LibDatePicker } from "./LibDatePicker/LibDatePicker.vue.js";
|
|
5
8
|
export { default as LibDebug } from "./LibDebug/LibDebug.vue.js";
|
|
6
|
-
export { default as
|
|
7
|
-
export { default as
|
|
9
|
+
export { default as LibFileInput } from "./LibFileInput/LibFileInput.vue.js";
|
|
10
|
+
export { default as LibInputDeprecated } from "./LibInputDeprecated/LibInputDeprecated.vue.js";
|
|
11
|
+
export { default as LibLabel } from "./LibLabel/LibLabel.vue.js";
|
|
8
12
|
export { default as LibNotifications } from "./LibNotifications/LibNotifications.vue.js";
|
|
9
13
|
export { default as LibPagination } from "./LibPagination/LibPagination.vue.js";
|
|
10
|
-
export { default as LibTable } from "./LibTable/LibTable.vue.js";
|
|
11
|
-
export { default as LibColorPicker } from "./LibColorPicker/LibColorPicker.vue.js";
|
|
12
|
-
export { default as LibColorInput } from "./LibColorInput/LibColorInput.vue.js";
|
|
13
14
|
export { default as LibPopup } from "./LibPopup/LibPopup.vue.js";
|
|
14
|
-
export { default as LibSimpleInput } from "./LibSimpleInput/LibSimpleInput.vue.js";
|
|
15
|
-
export { default as LibRecorder } from "./LibRecorder/LibRecorder.vue.js";
|
|
16
|
-
export { default as LibLabel } from "./LibLabel/LibLabel.vue.js";
|
|
17
|
-
export { default as LibCheckbox } from "./LibCheckbox/LibCheckbox.vue.js";
|
|
18
|
-
export { default as LibFileInput } from "./LibFileInput/LibFileInput.vue.js";
|
|
19
15
|
export { default as LibProgressBar } from "./LibProgressBar/LibProgressBar.vue.js";
|
|
16
|
+
export { default as LibRecorder } from "./LibRecorder/LibRecorder.vue.js";
|
|
17
|
+
export { default as LibRoot } from "./LibRoot/LibRoot.vue.js";
|
|
18
|
+
export { default as LibSimpleInput } from "./LibSimpleInput/LibSimpleInput.vue.js";
|
|
19
|
+
export { default as LibTable } from "./LibTable/LibTable.vue.js";
|
|
20
|
+
export { default as LibTimeZonePicker } from "./LibDatePicker/LibTimeZonePicker.vue.js";
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
export { default as LibTimeZonePicker } from "./LibDatePicker/LibTimeZonePicker.vue";
|
|
2
1
|
export { default as aria } from "./Aria/Aria.vue";
|
|
3
2
|
export { default as LibButton } from "./LibButton/LibButton.vue";
|
|
3
|
+
export { default as LibCheckbox } from "./LibCheckbox/LibCheckbox.vue";
|
|
4
|
+
export { default as LibColorInput } from "./LibColorInput/LibColorInput.vue";
|
|
5
|
+
export { default as LibColorPicker } from "./LibColorPicker/LibColorPicker.vue";
|
|
6
|
+
export { default as LibDarkModeSwitcher } from "./LibDarkModeSwitcher/LibDarkModeSwitcher.vue";
|
|
4
7
|
export { default as LibDatePicker } from "./LibDatePicker/LibDatePicker.vue";
|
|
5
8
|
export { default as LibDebug } from "./LibDebug/LibDebug.vue";
|
|
6
|
-
export { default as
|
|
7
|
-
export { default as
|
|
9
|
+
export { default as LibFileInput } from "./LibFileInput/LibFileInput.vue";
|
|
10
|
+
export { default as LibInputDeprecated } from "./LibInputDeprecated/LibInputDeprecated.vue";
|
|
11
|
+
export { default as LibLabel } from "./LibLabel/LibLabel.vue";
|
|
8
12
|
export { default as LibNotifications } from "./LibNotifications/LibNotifications.vue";
|
|
9
13
|
export { default as LibPagination } from "./LibPagination/LibPagination.vue";
|
|
10
|
-
export { default as LibTable } from "./LibTable/LibTable.vue";
|
|
11
|
-
export { default as LibColorPicker } from "./LibColorPicker/LibColorPicker.vue";
|
|
12
|
-
export { default as LibColorInput } from "./LibColorInput/LibColorInput.vue";
|
|
13
14
|
export { default as LibPopup } from "./LibPopup/LibPopup.vue";
|
|
14
|
-
export { default as LibSimpleInput } from "./LibSimpleInput/LibSimpleInput.vue";
|
|
15
|
-
export { default as LibRecorder } from "./LibRecorder/LibRecorder.vue";
|
|
16
|
-
export { default as LibLabel } from "./LibLabel/LibLabel.vue";
|
|
17
|
-
export { default as LibCheckbox } from "./LibCheckbox/LibCheckbox.vue";
|
|
18
|
-
export { default as LibFileInput } from "./LibFileInput/LibFileInput.vue";
|
|
19
15
|
export { default as LibProgressBar } from "./LibProgressBar/LibProgressBar.vue";
|
|
16
|
+
export { default as LibRecorder } from "./LibRecorder/LibRecorder.vue";
|
|
17
|
+
export { default as LibRoot } from "./LibRoot/LibRoot.vue";
|
|
18
|
+
export { default as LibSimpleInput } from "./LibSimpleInput/LibSimpleInput.vue";
|
|
19
|
+
export { default as LibTable } from "./LibTable/LibTable.vue";
|
|
20
|
+
export { default as LibTimeZonePicker } from "./LibDatePicker/LibTimeZonePicker.vue";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type PropType } from "vue";
|
|
2
|
+
import type { PopupPositioner, PopupPositionModifier } from "../../types/index.js";
|
|
2
3
|
export interface LinkableByIdProps {
|
|
3
4
|
/**
|
|
4
5
|
* The id for the input. Uses vue's useId if none provided.
|
|
@@ -8,6 +9,11 @@ export interface LinkableByIdProps {
|
|
|
8
9
|
id?: string;
|
|
9
10
|
}
|
|
10
11
|
export declare const getFallbackId: () => string;
|
|
12
|
+
export interface ButtonProps {
|
|
13
|
+
border?: boolean;
|
|
14
|
+
color?: "warning" | "ok" | "danger" | "primary" | "secondary" | false;
|
|
15
|
+
autoTitleFromAria?: boolean;
|
|
16
|
+
}
|
|
11
17
|
export interface LabelProps {
|
|
12
18
|
/** For the label. Note the component might or might not support an actual label element. If none is supported, this is used for the `aria-label`. */
|
|
13
19
|
label?: string;
|
|
@@ -53,6 +59,8 @@ export type SuggestionsProps<T = any> = {
|
|
|
53
59
|
allowOpenEmpty?: boolean;
|
|
54
60
|
/** Whether the suggestions dropdown can be opened. Default is true. */
|
|
55
61
|
canOpen?: boolean;
|
|
62
|
+
/** Whether the suggestions dropdown can be closed. Default is true. */
|
|
63
|
+
canClose?: boolean;
|
|
56
64
|
/** Whether the input is valid. Default is true. */
|
|
57
65
|
isValid?: boolean;
|
|
58
66
|
/**
|
|
@@ -61,12 +69,81 @@ export type SuggestionsProps<T = any> = {
|
|
|
61
69
|
* You can implement custom behavior here like fuzzy matching. Note that an exactly matching selection is always picked (the function will not be called).
|
|
62
70
|
*/
|
|
63
71
|
suggestionSelector?: (suggestions: T[], input: string) => number;
|
|
72
|
+
/** In the case modelValue is an array of values, whether to show the selected values in the suggestions list. Default is true so users can deselect from the list as well. If false, the checkboxes will also not be shown. */
|
|
73
|
+
showSelectedValues?: boolean;
|
|
64
74
|
};
|
|
65
|
-
export type SuggestionsOptions<T> = SuggestionsProps<T
|
|
66
|
-
export interface SuggestionsEmits {
|
|
67
|
-
(e: "submit", val: string, suggestion?: any): void;
|
|
75
|
+
export type SuggestionsOptions<T> = SuggestionsProps<T>;
|
|
76
|
+
export interface SuggestionsEmits<TMultivalue extends boolean = false> {
|
|
77
|
+
(e: "submit", val: string, suggestion?: any, wasRemoved?: boolean): void;
|
|
68
78
|
(e: "update:isOpen", val: boolean): void;
|
|
69
|
-
(e: "update:activeSuggestion", val: number): void;
|
|
79
|
+
(e: "update:activeSuggestion", val: TMultivalue extends true ? number[] : number): void;
|
|
80
|
+
}
|
|
81
|
+
export interface PopupProps {
|
|
82
|
+
/**
|
|
83
|
+
* Whether to use the dialog element instead of a regular backdrop. While using the dialog element would be ideal, css variables won't be applied to it, tailwind themes will fail, etc, if the css variables are not applied to `::backdrop`.
|
|
84
|
+
*
|
|
85
|
+
* Using a div ends up easier to setup.
|
|
86
|
+
*
|
|
87
|
+
* The default is now false.
|
|
88
|
+
*/
|
|
89
|
+
useDialogForBackdrop?: false;
|
|
90
|
+
/** Wether to use a backdrop (clicking it will close the popup), or not (use is allowed to click elsewhere. */
|
|
91
|
+
useBackdrop?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* The preferred horizontal positioning of the popup. The first position in the array to fit is used.
|
|
94
|
+
*
|
|
95
|
+
* All elements need to have box-sizing: border-box set. Also note that while the component should work with dynamic popup sizes, in practice there's issues with the positioning being slightly off. Giving the popup element a static size is better. If you need margins around the popup, this can be done with a wrapper element + padding.
|
|
96
|
+
*
|
|
97
|
+
* The positions `right`/`left`/`top`/`bottom` are relative to the opposite side of the button element so as to try not to cover the triggering button.
|
|
98
|
+
*
|
|
99
|
+
* So positioning `right` and `left` look like this:
|
|
100
|
+
*
|
|
101
|
+
* ```
|
|
102
|
+
* // right
|
|
103
|
+
* [button]
|
|
104
|
+
* [----popup----]
|
|
105
|
+
*
|
|
106
|
+
* // left
|
|
107
|
+
* [button]
|
|
108
|
+
* [----popup----]
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* Positions `*-most` try to position the popup as close to that side of the screen as possible, otherwise limiting the popup to that edge. For example:
|
|
112
|
+
*
|
|
113
|
+
* ```
|
|
114
|
+
* [--------------screen---------------]
|
|
115
|
+
* // right-most
|
|
116
|
+
* [button]
|
|
117
|
+
* [----popup----]
|
|
118
|
+
* // near the edge:
|
|
119
|
+
* [button]
|
|
120
|
+
* [----popup----]
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* There is also the `center-screen` position, which centers the popup on the screen.
|
|
124
|
+
*
|
|
125
|
+
* These last two (`*-most` and `center-screen`) are greedy, they will always find a position that fits. Positions listed after are ignored.
|
|
126
|
+
*
|
|
127
|
+
* You can also specify a function instead which is given some additional information regarding the space around the button reference element. It should a number for the x position (or y, if preferredVertical).
|
|
128
|
+
*
|
|
129
|
+
* If you only need to slightly modify the position, you can use the `modifyPosition` option instead.
|
|
130
|
+
*/
|
|
131
|
+
preferredHorizontal?: ("center" | "right" | "left" | "either" | "center-screen" | "right-most" | "left-most" | "center-most")[] | PopupPositioner;
|
|
132
|
+
/** See `preferredHorizontal`. */
|
|
133
|
+
preferredVertical?: ("top" | "bottom" | "center" | "either" | "center-screen" | "top-most" | "bottom-most" | "center-most")[] | PopupPositioner;
|
|
134
|
+
/**
|
|
135
|
+
* When the user scrolls or resizes, normally the entire popup position is recomputed, taking into account the preferred positioning.
|
|
136
|
+
*
|
|
137
|
+
* This can cause it to shift around.
|
|
138
|
+
*
|
|
139
|
+
* Set this to true to only shift the popup depending on how much the button element moved and avoid recalculating the best position.
|
|
140
|
+
*/
|
|
141
|
+
avoidRepositioning?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Allows modifying the calculated position, to for example, clamp it.
|
|
144
|
+
*/
|
|
145
|
+
modifyPosition?: PopupPositionModifier;
|
|
146
|
+
canClose?: boolean;
|
|
70
147
|
}
|
|
71
148
|
export declare const baseInteractiveProps: {
|
|
72
149
|
readonly unstyle: {
|
|
@@ -106,18 +183,6 @@ export declare const baseInteractivePropsDefaults: {
|
|
|
106
183
|
border: boolean;
|
|
107
184
|
unstyle: boolean;
|
|
108
185
|
};
|
|
109
|
-
export type MultiValueProps = {
|
|
110
|
-
/**
|
|
111
|
-
* If values is used, for components that handle multiple values, prevents adding of duplicate values.
|
|
112
|
-
*
|
|
113
|
-
* For other components, it prevents suggesting values that have already been added.
|
|
114
|
-
*
|
|
115
|
-
* Default is true.
|
|
116
|
-
*/
|
|
117
|
-
preventDuplicateValues?: boolean;
|
|
118
|
-
/** The selected values.*/
|
|
119
|
-
values?: string[];
|
|
120
|
-
};
|
|
121
186
|
/**
|
|
122
187
|
* @internal
|
|
123
188
|
* For easily typing attributes created by useDivideAttrs. See readme.
|
|
@@ -14,13 +14,13 @@ export const playMultipleValues = async ({ canvasElement, args }) => {
|
|
|
14
14
|
await userEvent.type(input, "A");
|
|
15
15
|
await expect(canvas.getByTestId("model-value")).toHaveTextContent("A");
|
|
16
16
|
await userEvent.keyboard("{Enter}");
|
|
17
|
-
await expect(canvas.getByTestId("values").textContent).toBe([...initialValues
|
|
17
|
+
await expect(canvas.getByTestId("values").textContent).toBe([...initialValues].join(", "));
|
|
18
18
|
await expect(canvas.getByTestId("model-value")).toBeEmptyDOMElement();
|
|
19
|
-
await userEvent.type(input, "
|
|
20
|
-
await expect(canvas.getByTestId("model-value")).toHaveTextContent("
|
|
19
|
+
await userEvent.type(input, "D");
|
|
20
|
+
await expect(canvas.getByTestId("model-value")).toHaveTextContent("D");
|
|
21
21
|
await userEvent.keyboard("{Enter}");
|
|
22
|
-
await expect(canvas.getByTestId("values").textContent).toBe([...initialValues, "
|
|
22
|
+
await expect(canvas.getByTestId("values").textContent).toBe([...initialValues, "D"].join(", "));
|
|
23
23
|
await userEvent.clear(input);
|
|
24
24
|
await userEvent.keyboard("{Enter}");
|
|
25
|
-
await expect(canvas.getByTestId("values").textContent).toBe([...initialValues, "
|
|
25
|
+
await expect(canvas.getByTestId("values").textContent).toBe([...initialValues, "D"].join(", "));
|
|
26
26
|
};
|
|
@@ -18,7 +18,7 @@ export const playBasicSelect = async ({ canvasElement, args }) => {
|
|
|
18
18
|
await expect(canvas.queryByRole("option", { selected: true })).toBeInTheDocument();
|
|
19
19
|
await userEvent.clear(input);
|
|
20
20
|
await userEvent.type(input, "unmatched");
|
|
21
|
-
if (!args.suggestionsFilter) {
|
|
21
|
+
if (!args.suggestionsFilter && !args.values) {
|
|
22
22
|
await expect(canvas.queryAllByRole("option", { selected: true })).toEqual([]);
|
|
23
23
|
}
|
|
24
24
|
await userEvent.clear(input);
|
|
@@ -32,7 +32,9 @@ export const playBasicSelect = async ({ canvasElement, args }) => {
|
|
|
32
32
|
}
|
|
33
33
|
await userEvent.clear(input);
|
|
34
34
|
await userEvent.keyboard("AB{Escape}");
|
|
35
|
-
|
|
35
|
+
if (!args.values) {
|
|
36
|
+
await expect(canvas.queryByRole("listbox")).toBeNull();
|
|
37
|
+
}
|
|
36
38
|
if (args.values === void 0) {
|
|
37
39
|
if (args.restrictToSuggestions) {
|
|
38
40
|
await expect(canvas.getByTestId("model-value").textContent).toBe("A");
|
|
@@ -50,16 +52,24 @@ export const playBasicKeyboardSelect = async ({ canvasElement, args }) => {
|
|
|
50
52
|
await userEvent.keyboard("{ArrowUp}");
|
|
51
53
|
await expect(canvas.queryByRole("option", { name: "A", selected: true })).toBeInTheDocument();
|
|
52
54
|
await userEvent.keyboard("{ArrowUp}");
|
|
53
|
-
await expect(canvas.queryByRole("option", {
|
|
55
|
+
await expect(canvas.queryByRole("option", {
|
|
56
|
+
name: args.values ? "C" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
|
57
|
+
selected: true
|
|
58
|
+
})).toBeInTheDocument();
|
|
54
59
|
await userEvent.keyboard("{ArrowDown}");
|
|
55
60
|
await expect(canvas.queryByRole("option", { name: "A", selected: true })).toBeInTheDocument();
|
|
56
61
|
await userEvent.keyboard("{PageDown}");
|
|
57
|
-
await expect(canvas.queryByRole("option", {
|
|
62
|
+
await expect(canvas.queryByRole("option", {
|
|
63
|
+
name: args.values ? "C" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
|
64
|
+
selected: true
|
|
65
|
+
})).toBeInTheDocument();
|
|
58
66
|
await userEvent.keyboard("{PageUp}");
|
|
59
67
|
await expect(canvas.queryByRole("option", { name: "A", selected: true })).toBeInTheDocument();
|
|
60
68
|
const testOpen = async (key) => {
|
|
61
69
|
await userEvent.keyboard("{Escape}");
|
|
62
|
-
|
|
70
|
+
if (!args.values) {
|
|
71
|
+
await expect(canvas.queryByRole("listbox")).toBeNull();
|
|
72
|
+
}
|
|
63
73
|
await userEvent.keyboard(`{${key}}`);
|
|
64
74
|
await expect(canvas.queryByRole("listbox")).toBeInTheDocument();
|
|
65
75
|
};
|
|
@@ -74,10 +84,4 @@ export const playBasicClickSelect = async ({ canvasElement, args }) => {
|
|
|
74
84
|
await userEvent.clear(input);
|
|
75
85
|
await userEvent.type(input, "A");
|
|
76
86
|
await userEvent.click(canvas.getByRole("option", { name: "AB" }));
|
|
77
|
-
if (args.values === void 0) {
|
|
78
|
-
await expect(canvas.getByTestId("model-value").textContent).toBe("AB");
|
|
79
|
-
await expect(canvas.queryByRole("listbox")).toBeNull();
|
|
80
|
-
} else {
|
|
81
|
-
await expect(canvas.getByTestId("values")).toHaveTextContent(/AB$/);
|
|
82
|
-
}
|
|
83
87
|
};
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
export { languageLocaleInjectionKey } from "./useSetupLocale.js.js";
|
|
1
2
|
export { useAccesibilityOutline } from "./useAccesibilityOutline.js.js";
|
|
2
3
|
export { useAriaLabel } from "./useAriaLabel.js.js";
|
|
3
4
|
export { useDarkMode } from "./useDarkMode.js.js";
|
|
4
5
|
export { useDivideAttrs } from "./useDivideAttrs.js.js";
|
|
6
|
+
export { useDragWithThreshold } from "./useDragWithThreshold.js.js";
|
|
5
7
|
export { useGlobalResizeObserver } from "./useGlobalResizeObserver.js.js";
|
|
6
8
|
export { useInjectedDarkMode } from "./useInjectedDarkMode.js.js";
|
|
9
|
+
export { useInjectedI18n } from "./useInjectedI18n.js.js";
|
|
10
|
+
export { useInjectedLocale } from "./useInjectedLocale.js.js";
|
|
7
11
|
export { useNotificationHandler } from "./useNotificationHandler.js.js";
|
|
12
|
+
export { usePreHydrationValue } from "./usePreHydrationValue.js.js";
|
|
8
13
|
export { useScrollNearContainerEdges } from "./useScrollNearContainerEdges.js.js";
|
|
9
14
|
export { useSetupDarkMode } from "./useSetupDarkMode.js.js";
|
|
10
15
|
export { useShowDevOnlyKey } from "./useShowDevOnlyKey.js.js";
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
export { languageLocaleInjectionKey } from "./useSetupLocale.js";
|
|
1
2
|
export { useAccesibilityOutline } from "./useAccesibilityOutline.js";
|
|
2
3
|
export { useAriaLabel } from "./useAriaLabel.js";
|
|
3
4
|
export { useDarkMode } from "./useDarkMode.js";
|
|
4
5
|
export { useDivideAttrs } from "./useDivideAttrs.js";
|
|
6
|
+
export { useDragWithThreshold } from "./useDragWithThreshold.js";
|
|
5
7
|
export { useGlobalResizeObserver } from "./useGlobalResizeObserver.js";
|
|
6
8
|
export { useInjectedDarkMode } from "./useInjectedDarkMode.js";
|
|
9
|
+
export { useInjectedI18n } from "./useInjectedI18n.js";
|
|
10
|
+
export { useInjectedLocale } from "./useInjectedLocale.js";
|
|
7
11
|
export { useNotificationHandler } from "./useNotificationHandler.js";
|
|
12
|
+
export { usePreHydrationValue } from "./usePreHydrationValue.js";
|
|
8
13
|
export { useScrollNearContainerEdges } from "./useScrollNearContainerEdges.js";
|
|
9
14
|
export { useSetupDarkMode } from "./useSetupDarkMode.js";
|
|
10
15
|
export { useShowDevOnlyKey } from "./useShowDevOnlyKey.js";
|
|
@@ -8,6 +8,7 @@ export const useDivideAttrs = (divisionKeys) => computed(() => {
|
|
|
8
8
|
res[`${key}Attrs`] = {};
|
|
9
9
|
for (let i = 0; i < unseen.length; i++) {
|
|
10
10
|
const attrKey = unseen[i];
|
|
11
|
+
if (!attrKey) continue;
|
|
11
12
|
if (attrKey.startsWith(`${key}-`)) {
|
|
12
13
|
res[`${key}Attrs`][attrKey.slice(key.length + 1)] = attrs[attrKey];
|
|
13
14
|
unseen.splice(i, 1);
|