@witchcraft/ui 0.1.0 → 0.1.1
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 +2 -2
- package/dist/module.mjs +1 -1
- package/dist/runtime/components/Aria/Aria.vue +5 -9
- package/dist/runtime/components/Aria/Aria.vue.d.ts +5 -0
- package/dist/runtime/components/Icon/Icon.vue +10 -31
- package/dist/runtime/components/Icon/Icon.vue.d.ts +21 -0
- package/dist/runtime/components/LibButton/LibButton.vue +58 -77
- package/dist/runtime/components/LibButton/LibButton.vue.d.ts +36 -0
- package/dist/runtime/components/LibCheckbox/LibCheckbox.vue +48 -75
- package/dist/runtime/components/LibCheckbox/LibCheckbox.vue.d.ts +42 -0
- package/dist/runtime/components/LibColorInput/LibColorInput.vue +63 -108
- package/dist/runtime/components/LibColorInput/LibColorInput.vue.d.ts +63 -0
- package/dist/runtime/components/LibColorPicker/LibColorPicker.vue +271 -352
- package/dist/runtime/components/LibColorPicker/LibColorPicker.vue.d.ts +61 -0
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +32 -57
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue.d.ts +22 -0
- package/dist/runtime/components/LibDatePicker/LibDatePicker.vue +17 -38
- package/dist/runtime/components/LibDatePicker/LibDatePicker.vue.d.ts +40 -0
- package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue +53 -82
- package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue.d.ts +34 -0
- package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue +50 -67
- package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue.d.ts +34 -0
- package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue +7 -8
- package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue.d.ts +22 -0
- package/dist/runtime/components/LibDebug/LibDebug.vue +42 -70
- package/dist/runtime/components/LibDebug/LibDebug.vue.d.ts +32 -0
- package/dist/runtime/components/LibDevOnly/LibDevOnly.vue +18 -31
- package/dist/runtime/components/LibDevOnly/LibDevOnly.vue.d.ts +22 -0
- package/dist/runtime/components/LibFileInput/LibFileInput.vue +113 -157
- package/dist/runtime/components/LibFileInput/LibFileInput.vue.d.ts +43 -0
- package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue +215 -242
- package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue.d.ts +165 -0
- package/dist/runtime/components/LibLabel/LibLabel.vue +30 -46
- package/dist/runtime/components/LibLabel/LibLabel.vue.d.ts +27 -0
- package/dist/runtime/components/LibMultiValues/LibMultiValues.vue +44 -59
- package/dist/runtime/components/LibMultiValues/LibMultiValues.vue.d.ts +29 -0
- package/dist/runtime/components/LibNotifications/LibNotification.vue +32 -49
- package/dist/runtime/components/LibNotifications/LibNotification.vue.d.ts +17 -0
- package/dist/runtime/components/LibNotifications/LibNotifications.vue +63 -84
- package/dist/runtime/components/LibNotifications/LibNotifications.vue.d.ts +13 -0
- package/dist/runtime/components/LibPagination/LibPagination.vue +67 -112
- package/dist/runtime/components/LibPagination/LibPagination.vue.d.ts +104 -0
- package/dist/runtime/components/LibPalette/LibPalette.vue +20 -23
- package/dist/runtime/components/LibPalette/LibPalette.vue.d.ts +14 -0
- package/dist/runtime/components/LibPopup/LibPopup.vue +314 -352
- package/dist/runtime/components/LibPopup/LibPopup.vue.d.ts +46 -0
- package/dist/runtime/components/LibProgressBar/LibProgressBar.vue +70 -92
- package/dist/runtime/components/LibProgressBar/LibProgressBar.vue.d.ts +41 -0
- package/dist/runtime/components/LibRecorder/LibRecorder.vue +133 -178
- package/dist/runtime/components/LibRecorder/LibRecorder.vue.d.ts +77 -0
- package/dist/runtime/components/LibRoot/LibRoot.vue +73 -100
- package/dist/runtime/components/LibRoot/LibRoot.vue.d.ts +41 -0
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue +49 -78
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue.d.ts +35 -0
- package/dist/runtime/components/LibSuggestions/LibSuggestions.vue +123 -157
- package/dist/runtime/components/LibSuggestions/LibSuggestions.vue.d.ts +94 -0
- package/dist/runtime/components/LibTable/LibTable.vue +63 -100
- package/dist/runtime/components/LibTable/LibTable.vue.d.ts +45 -0
- package/dist/runtime/components/Template/NAME.vue +15 -36
- package/dist/runtime/components/Template/NAME.vue.d.ts +17 -0
- package/dist/runtime/components/TestControls/TestControls.vue +6 -9
- package/dist/runtime/components/TestControls/TestControls.vue.d.ts +5 -0
- package/dist/runtime/directives/vResizableCols.js +89 -83
- package/dist/types.d.mts +2 -6
- package/package.json +11 -11
- package/src/runtime/components/Focus.stories.ts +3 -2
- package/src/runtime/components/Icon/Icon.vue +0 -1
- package/src/runtime/components/LibButton/LibButton.vue +0 -1
- package/src/runtime/components/LibCheckbox/LibCheckbox.vue +0 -1
- package/src/runtime/components/LibColorInput/LibColorInput.vue +0 -1
- package/src/runtime/components/LibColorPicker/utils/safeConvertToHsva.ts +0 -1
- package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +0 -1
- package/src/runtime/components/LibFileInput/LibFileInput.vue +0 -1
- package/src/runtime/components/LibInputDeprecated/LibInputDeprecated.vue +0 -1
- package/src/runtime/components/LibMultiValues/LibMultiValues.vue +0 -1
- package/src/runtime/components/LibNotifications/LibNotification.vue +0 -1
- package/src/runtime/components/LibNotifications/LibNotifications.vue +0 -1
- package/src/runtime/components/LibPagination/LibPagination.vue +0 -1
- package/src/runtime/components/LibPopup/LibPopup.vue +0 -1
- package/src/runtime/components/LibProgressBar/LibProgressBar.vue +0 -1
- package/src/runtime/components/LibRecorder/LibRecorder.vue +0 -1
- package/src/runtime/components/LibSimpleInput/LibSimpleInput.vue +0 -1
- package/src/runtime/components/LibSuggestions/LibSuggestions.vue +0 -1
- package/src/runtime/components/LibTable/LibTable.vue +0 -1
- package/src/runtime/directives/vResizableCols.ts +79 -73
- package/dist/module.cjs +0 -5
- package/dist/module.d.ts +0 -36
- package/dist/runtime/components/Focus.stories.d.ts +0 -11
- package/dist/runtime/components/Focus.stories.js +0 -53
- package/dist/runtime/components/LibButton/LibButton.stories.d.ts +0 -12
- package/dist/runtime/components/LibButton/LibButton.stories.js +0 -94
- package/dist/runtime/components/LibCheckbox/LibCheckbox.stories.d.ts +0 -14
- package/dist/runtime/components/LibCheckbox/LibCheckbox.stories.js +0 -29
- package/dist/runtime/components/LibColorInput/LibColorInput.stories.d.ts +0 -7
- package/dist/runtime/components/LibColorInput/LibColorInput.stories.js +0 -58
- package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.d.ts +0 -9
- package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.js +0 -68
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.d.ts +0 -7
- package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.js +0 -36
- package/dist/runtime/components/LibDatePicker/LibDatePicker.stories.d.ts +0 -11
- package/dist/runtime/components/LibDatePicker/LibDatePicker.stories.js +0 -98
- package/dist/runtime/components/LibDebug/LibDebug.stories.d.ts +0 -9
- package/dist/runtime/components/LibDebug/LibDebug.stories.js +0 -46
- package/dist/runtime/components/LibFileInput/LibFileInput.stories.d.ts +0 -10
- package/dist/runtime/components/LibFileInput/LibFileInput.stories.js +0 -63
- package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.stories.d.ts +0 -33
- package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.stories.js +0 -384
- package/dist/runtime/components/LibLabel/LibLabel.stories.d.ts +0 -6
- package/dist/runtime/components/LibLabel/LibLabel.stories.js +0 -25
- package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.d.ts +0 -23
- package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.js +0 -61
- package/dist/runtime/components/LibNotifications/LibNotification.stories.d.ts +0 -15
- package/dist/runtime/components/LibNotifications/LibNotification.stories.js +0 -126
- package/dist/runtime/components/LibNotifications/LibNotifications.stories.d.ts +0 -6
- package/dist/runtime/components/LibNotifications/LibNotifications.stories.js +0 -109
- package/dist/runtime/components/LibPagination/LibPagination.stories.d.ts +0 -6
- package/dist/runtime/components/LibPagination/LibPagination.stories.js +0 -40
- package/dist/runtime/components/LibPalette/LibPalette.stories.d.ts +0 -6
- package/dist/runtime/components/LibPalette/LibPalette.stories.js +0 -20
- package/dist/runtime/components/LibPopup/LibPopup.stories.d.ts +0 -14
- package/dist/runtime/components/LibPopup/LibPopup.stories.js +0 -147
- package/dist/runtime/components/LibProgressBar/LibProgressBar.stories.d.ts +0 -10
- package/dist/runtime/components/LibProgressBar/LibProgressBar.stories.js +0 -81
- package/dist/runtime/components/LibRecorder/LibRecorder.stories.d.ts +0 -19
- package/dist/runtime/components/LibRecorder/LibRecorder.stories.js +0 -63
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.stories.d.ts +0 -26
- package/dist/runtime/components/LibSimpleInput/LibSimpleInput.stories.js +0 -78
- package/dist/runtime/components/LibSuggestions/LibSuggestions.stories.d.ts +0 -27
- package/dist/runtime/components/LibSuggestions/LibSuggestions.stories.js +0 -112
- package/dist/runtime/components/LibTable/LibTable.stories.d.ts +0 -16
- package/dist/runtime/components/LibTable/LibTable.stories.js +0 -156
- package/dist/runtime/components/Reset.stories.d.ts +0 -5
- package/dist/runtime/components/Reset.stories.js +0 -19
- package/dist/runtime/components/Scrolling.stories.d.ts +0 -6
- package/dist/runtime/components/Scrolling.stories.js +0 -44
- package/dist/runtime/composables/useScrollNearContainerEdges.stories.d.ts +0 -7
- package/dist/runtime/composables/useScrollNearContainerEdges.stories.js +0 -85
- package/dist/types.d.ts +0 -7
|
@@ -2,35 +2,37 @@
|
|
|
2
2
|
<div
|
|
3
3
|
v-if="$open"
|
|
4
4
|
:id="`suggestions-${id ?? fallbackId}`"
|
|
5
|
-
:class="twMerge(
|
|
5
|
+
:class="twMerge(
|
|
6
|
+
`
|
|
6
7
|
suggestions
|
|
7
8
|
bg-bg
|
|
8
9
|
dark:bg-fg
|
|
9
10
|
dark:text-bg
|
|
10
11
|
`,
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
$.attrs?.class
|
|
13
|
+
)"
|
|
13
14
|
:data-open="$open"
|
|
14
15
|
role="listbox"
|
|
15
16
|
ref="el"
|
|
16
|
-
v-bind="{...$.attrs, class:
|
|
17
|
+
v-bind="{ ...$.attrs, class: void 0 }"
|
|
17
18
|
>
|
|
18
19
|
<!-- Click event is just in case, it should not really be triggered. We can do click selections via the blur handler. -->
|
|
19
20
|
<div :id="`suggestion-${id ?? fallbackId}-${index}`"
|
|
20
21
|
role="option"
|
|
21
|
-
:class="twMerge(
|
|
22
|
+
:class="twMerge(
|
|
23
|
+
`
|
|
22
24
|
suggestions--item
|
|
23
25
|
user-select-none
|
|
24
26
|
cursor-pointer
|
|
25
27
|
px-2
|
|
26
28
|
`,
|
|
27
|
-
|
|
29
|
+
index === suggestions.active && `
|
|
28
30
|
bg-accent-200
|
|
29
31
|
dark:bg-accent-800/70
|
|
30
32
|
`,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
v-bind="{...$.itemAttrs, class:
|
|
33
|
+
$.itemAttrs?.class
|
|
34
|
+
)"
|
|
35
|
+
v-bind="{ ...$.itemAttrs, class: void 0 }"
|
|
34
36
|
:aria-selected="index === suggestions.active ? true : false"
|
|
35
37
|
:aria-label="suggestions.getLabel(item)"
|
|
36
38
|
v-for="(item, index) in suggestions.filtered"
|
|
@@ -57,159 +59,123 @@
|
|
|
57
59
|
</div>
|
|
58
60
|
</template>
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
import {
|
|
64
|
-
|
|
65
|
-
import {
|
|
66
|
-
import
|
|
67
|
-
import {
|
|
68
|
-
import { twMerge } from "../../utils/twMerge.js"
|
|
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"
|
|
71
|
-
|
|
62
|
+
<script setup>
|
|
63
|
+
import { reactive, ref } from "vue";
|
|
64
|
+
import { useDivideAttrs } from "../../composables/useDivideAttrs.js";
|
|
65
|
+
import { useSuggestions } from "../../composables/useSuggestions.js";
|
|
66
|
+
import { hasModifiers } from "../../helpers/hasModifiers.js";
|
|
67
|
+
import { twMerge } from "../../utils/twMerge.js";
|
|
68
|
+
import LibCheckbox from "../LibCheckbox/LibCheckbox.vue";
|
|
69
|
+
import { baseInteractivePropsDefaults, getFallbackId } from "../shared/props.js";
|
|
72
70
|
defineOptions({
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
71
|
+
name: "lib-suggestions",
|
|
72
|
+
inheritAttrs: false
|
|
73
|
+
});
|
|
74
|
+
const $ = useDivideAttrs(["item"]);
|
|
75
|
+
const emits = defineEmits(["submit", "update:isOpen", "update:activeSuggestion"]);
|
|
76
|
+
const fallbackId = getFallbackId();
|
|
77
|
+
const props = defineProps(/* @__PURE__ */ _mergeDefaults({
|
|
78
|
+
id: { type: String, required: false },
|
|
79
|
+
label: { type: String, required: false },
|
|
80
|
+
disabled: { type: Boolean, required: false },
|
|
81
|
+
readonly: { type: Boolean, required: false },
|
|
82
|
+
border: { type: Boolean, required: false },
|
|
83
|
+
unstyle: { type: Boolean, required: false },
|
|
84
|
+
filterKeydown: { type: Function, required: false },
|
|
85
|
+
filterBlur: { type: Function, required: false },
|
|
86
|
+
filterFocus: { type: Function, required: false },
|
|
87
|
+
suggestions: { type: Array, required: false },
|
|
88
|
+
suggestionLabel: { type: Function, required: false },
|
|
89
|
+
restrictToSuggestions: { type: Boolean, required: false },
|
|
90
|
+
updateOnlyOnSubmit: { type: Boolean, required: false },
|
|
91
|
+
suggestionsFilter: { type: Function, required: false },
|
|
92
|
+
allowOpenEmpty: { type: Boolean, required: false },
|
|
93
|
+
canOpen: { type: Boolean, required: false },
|
|
94
|
+
canClose: { type: Boolean, required: false },
|
|
95
|
+
isValid: { type: Boolean, required: false },
|
|
96
|
+
suggestionSelector: { type: Function, required: false },
|
|
97
|
+
showSelectedValues: { type: Boolean, required: false }
|
|
98
|
+
}, {
|
|
99
|
+
isValid: true,
|
|
100
|
+
canOpen: true,
|
|
101
|
+
filterKeydown: void 0,
|
|
102
|
+
...baseInteractivePropsDefaults
|
|
103
|
+
}));
|
|
104
|
+
const $modelValue = defineModel("modelValue", { type: null, ...{ required: true } });
|
|
105
|
+
const $inputValue = defineModel("inputValue", { type: String, ...{ default: "" } });
|
|
106
|
+
const $open = defineModel("open", { type: Boolean, ...{ default: false } });
|
|
105
107
|
if (typeof props.suggestions?.[0] === "object" && !props.suggestionLabel && !props.suggestionsFilter) {
|
|
106
|
-
|
|
108
|
+
throw new Error("`suggestionLabel` or `suggestionsFilter` must be passed if suggestions are objects.");
|
|
107
109
|
}
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
))
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
const inputFocusHandler = (e: FocusEvent): void => {
|
|
167
|
-
if (props.filterFocus?.(e)) return
|
|
168
|
-
suggestions.open()
|
|
169
|
-
}
|
|
170
|
-
|
|
110
|
+
const el = ref(null);
|
|
111
|
+
const suggestions = reactive(useSuggestions(
|
|
112
|
+
$inputValue,
|
|
113
|
+
$modelValue,
|
|
114
|
+
$open,
|
|
115
|
+
emits,
|
|
116
|
+
props
|
|
117
|
+
));
|
|
118
|
+
const inputKeydownHandler = (e) => {
|
|
119
|
+
if (props.filterKeydown?.(e)) return;
|
|
120
|
+
if (hasModifiers(e)) return;
|
|
121
|
+
if (e.key === "Enter") {
|
|
122
|
+
suggestions.enterSelected(!Array.isArray($modelValue));
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
} else if (e.key === "Escape") {
|
|
125
|
+
suggestions.cancel();
|
|
126
|
+
e.preventDefault();
|
|
127
|
+
} else if (!$open.value && ["ArrowDown", "ArrowUp", "PageUp", "PageDown"].includes(e.key) && suggestions.available) {
|
|
128
|
+
suggestions.open();
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
if (e.key === "PageUp") {
|
|
131
|
+
suggestions.first();
|
|
132
|
+
} else if (e.key === "PageDown") {
|
|
133
|
+
suggestions.last();
|
|
134
|
+
}
|
|
135
|
+
} else if (e.key === "ArrowUp") {
|
|
136
|
+
suggestions.prev();
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
} else if (e.key === "ArrowDown") {
|
|
139
|
+
suggestions.next();
|
|
140
|
+
e.preventDefault();
|
|
141
|
+
} else if (e.key === "PageUp") {
|
|
142
|
+
suggestions.first();
|
|
143
|
+
e.preventDefault();
|
|
144
|
+
} else if (e.key === "PageDown") {
|
|
145
|
+
suggestions.last();
|
|
146
|
+
e.preventDefault();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
const inputBlurHandler = (e) => {
|
|
150
|
+
if (props.filterBlur?.(e)) return;
|
|
151
|
+
if (!$open.value) return;
|
|
152
|
+
if (props.restrictToSuggestions) {
|
|
153
|
+
suggestions.cancel();
|
|
154
|
+
} else {
|
|
155
|
+
if (!Array.isArray($modelValue.value)) {
|
|
156
|
+
$modelValue.value = $inputValue.value;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if ($open.value) {
|
|
160
|
+
suggestions.close();
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const inputFocusHandler = (e) => {
|
|
164
|
+
if (props.filterFocus?.(e)) return;
|
|
165
|
+
suggestions.open();
|
|
166
|
+
};
|
|
171
167
|
defineExpose({
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
})
|
|
181
|
-
|
|
168
|
+
suggestions,
|
|
169
|
+
el,
|
|
170
|
+
/** A simple keydown handler that can be passed to an input to control the component while still focused inside it. */
|
|
171
|
+
inputKeydownHandler,
|
|
172
|
+
/** A blur handler for the input that controls the component. This also takes care of making clicking on a suggestion work, since otherwise if canOpen is set to false in the blur handler, no click event will fire. */
|
|
173
|
+
inputBlurHandler,
|
|
174
|
+
/** A focus handler for the input that controls the component. */
|
|
175
|
+
inputFocusHandler
|
|
176
|
+
});
|
|
182
177
|
</script>
|
|
183
178
|
|
|
184
|
-
<script
|
|
185
|
-
type WrapperTypes = Partial<WrapperProps<"item",HTMLAttributes, {
|
|
186
|
-
/** Tailwind classes. */
|
|
187
|
-
class?: string
|
|
188
|
-
}>>
|
|
189
|
-
|
|
190
|
-
type RealProps =
|
|
191
|
-
& LinkableByIdProps
|
|
192
|
-
& LabelProps
|
|
193
|
-
& BaseInteractiveProps
|
|
194
|
-
& {
|
|
195
|
-
/** Return true to prevent the keydown event from being handled. */
|
|
196
|
-
filterKeydown?: (e: KeyboardEvent) => boolean
|
|
197
|
-
/** Return true to prevent the blur event from being handled. */
|
|
198
|
-
filterBlur?: (e: MouseEvent) => boolean
|
|
199
|
-
/** Return true to prevent the focus event from being handled. */
|
|
200
|
-
filterFocus?: (e: FocusEvent) => boolean
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
interface Props
|
|
204
|
-
extends
|
|
205
|
-
/** @vue-ignore */
|
|
206
|
-
Partial<Omit<HTMLAttributes,"class" | "onSubmit"> & {
|
|
207
|
-
/** Tailwind classes. */
|
|
208
|
-
class?: string
|
|
209
|
-
}>,
|
|
210
|
-
/** @vue-ignore */
|
|
211
|
-
WrapperTypes,
|
|
212
|
-
RealProps
|
|
213
|
-
{}
|
|
179
|
+
<script>
|
|
214
180
|
|
|
215
181
|
</script>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { type HTMLAttributes } from "vue";
|
|
2
|
+
import { type BaseInteractiveProps, type LabelProps, type LinkableByIdProps, type SuggestionsEmits, type SuggestionsProps, type WrapperProps } from "../shared/props.js.js";
|
|
3
|
+
type WrapperTypes = Partial<WrapperProps<"item", HTMLAttributes, {
|
|
4
|
+
/** Tailwind classes. */
|
|
5
|
+
class?: string;
|
|
6
|
+
}>>;
|
|
7
|
+
type RealProps = LinkableByIdProps & LabelProps & BaseInteractiveProps & {
|
|
8
|
+
/** Return true to prevent the keydown event from being handled. */
|
|
9
|
+
filterKeydown?: (e: KeyboardEvent) => boolean;
|
|
10
|
+
/** Return true to prevent the blur event from being handled. */
|
|
11
|
+
filterBlur?: (e: MouseEvent) => boolean;
|
|
12
|
+
/** Return true to prevent the focus event from being handled. */
|
|
13
|
+
filterFocus?: (e: FocusEvent) => boolean;
|
|
14
|
+
};
|
|
15
|
+
interface Props extends
|
|
16
|
+
/** @vue-ignore */
|
|
17
|
+
Partial<Omit<HTMLAttributes, "class" | "onSubmit"> & {
|
|
18
|
+
/** Tailwind classes. */
|
|
19
|
+
class?: string;
|
|
20
|
+
}>,
|
|
21
|
+
/** @vue-ignore */
|
|
22
|
+
WrapperTypes, RealProps {
|
|
23
|
+
}
|
|
24
|
+
declare const _default: <TSuggestion extends string | object, TValue extends string | string[]>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
25
|
+
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
26
|
+
readonly onSubmit?: ((val: string, suggestion?: any, wasRemoved?: boolean | undefined) => any) | undefined;
|
|
27
|
+
readonly "onUpdate:isOpen"?: ((val: boolean) => any) | undefined;
|
|
28
|
+
readonly "onUpdate:activeSuggestion"?: ((val: number) => any) | undefined;
|
|
29
|
+
readonly "onUpdate:modelValue"?: ((value: TValue) => any) | undefined;
|
|
30
|
+
readonly "onUpdate:inputValue"?: ((value: string) => any) | undefined;
|
|
31
|
+
readonly "onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
32
|
+
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onSubmit" | "onUpdate:modelValue" | "onUpdate:open" | "onUpdate:isOpen" | "onUpdate:activeSuggestion" | "onUpdate:inputValue"> & (Props & SuggestionsProps<TSuggestion> & {
|
|
33
|
+
/**
|
|
34
|
+
* 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.
|
|
35
|
+
*
|
|
36
|
+
* If suggestions are objects, this will be the string returned by the `suggestionLabel` prop.
|
|
37
|
+
*/
|
|
38
|
+
modelValue: TValue;
|
|
39
|
+
/**
|
|
40
|
+
* If the element is bound to an input, this is the value that the input should be sharing.
|
|
41
|
+
*
|
|
42
|
+
* It allows the component to read even invalid output, and also to reset that invalid output when either modelValue is set to a new value, or when the component is closed via cancel.
|
|
43
|
+
*/
|
|
44
|
+
inputValue?: string;
|
|
45
|
+
open?: boolean;
|
|
46
|
+
}) & Partial<{}>> & import("vue").PublicProps;
|
|
47
|
+
expose(exposed: import("vue").ShallowUnwrapRef<{
|
|
48
|
+
suggestions: {
|
|
49
|
+
list: any[] | undefined;
|
|
50
|
+
filtered: any[] | undefined;
|
|
51
|
+
active: number;
|
|
52
|
+
available: boolean;
|
|
53
|
+
moreThanOneAvailable: boolean;
|
|
54
|
+
hasExactlyMatching: TSuggestion | undefined;
|
|
55
|
+
hasValidSuggestion: boolean;
|
|
56
|
+
openable: boolean | undefined;
|
|
57
|
+
getLabel: (item: any) => string;
|
|
58
|
+
$open: boolean;
|
|
59
|
+
open: () => void;
|
|
60
|
+
close: () => void;
|
|
61
|
+
enterSelected: (doClose?: boolean) => void;
|
|
62
|
+
enterIndex: (num: number, doClose?: boolean) => void;
|
|
63
|
+
toggle: () => void;
|
|
64
|
+
cancel: () => void;
|
|
65
|
+
select: (num: number) => void;
|
|
66
|
+
prev: () => void;
|
|
67
|
+
next: () => void;
|
|
68
|
+
first: () => void;
|
|
69
|
+
last: () => void;
|
|
70
|
+
};
|
|
71
|
+
el: import("vue").Ref<HTMLElement | null, HTMLElement | null>;
|
|
72
|
+
/** A simple keydown handler that can be passed to an input to control the component while still focused inside it. */
|
|
73
|
+
inputKeydownHandler: (e: KeyboardEvent) => void;
|
|
74
|
+
/** A blur handler for the input that controls the component. This also takes care of making clicking on a suggestion work, since otherwise if canOpen is set to false in the blur handler, no click event will fire. */
|
|
75
|
+
inputBlurHandler: (e: MouseEvent) => void;
|
|
76
|
+
/** A focus handler for the input that controls the component. */
|
|
77
|
+
inputFocusHandler: (e: FocusEvent) => void;
|
|
78
|
+
}>): void;
|
|
79
|
+
attrs: any;
|
|
80
|
+
slots: {
|
|
81
|
+
item?: (props: {
|
|
82
|
+
item: any;
|
|
83
|
+
index: any;
|
|
84
|
+
isSelected: any;
|
|
85
|
+
}) => any;
|
|
86
|
+
};
|
|
87
|
+
emit: SuggestionsEmits<false> & (((evt: "update:modelValue", value: TValue) => void) & ((evt: "update:inputValue", value: string) => void) & ((evt: "update:open", value: boolean) => void));
|
|
88
|
+
}>) => import("vue").VNode & {
|
|
89
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
90
|
+
};
|
|
91
|
+
export default _default;
|
|
92
|
+
type __VLS_PrettifyLocal<T> = {
|
|
93
|
+
[K in keyof T as K]: T[K];
|
|
94
|
+
} & {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- Assumes no scrollbars on children -->
|
|
3
|
-
<table :class="twMerge(
|
|
3
|
+
<table :class="twMerge(
|
|
4
|
+
`table
|
|
4
5
|
table-fixed
|
|
5
6
|
border-separate
|
|
6
7
|
border-spacing-0
|
|
@@ -16,12 +17,12 @@
|
|
|
16
17
|
[&.resizable-cols-error]:cursor-not-allowed
|
|
17
18
|
[&.resizable-cols-error]:user-select-none
|
|
18
19
|
`,
|
|
19
|
-
|
|
20
|
+
cellBorder && `
|
|
20
21
|
[&_td]:border-neutral-500
|
|
21
22
|
[&_td:not(.last-row)]:border-b
|
|
22
23
|
[&_td:not(.first-col)]:border-l
|
|
23
24
|
`,
|
|
24
|
-
|
|
25
|
+
border && `
|
|
25
26
|
[&_thead_td]:bg-neutral-200
|
|
26
27
|
[&_td]:border-neutral-500
|
|
27
28
|
dark:[&_thead_td]:bg-neutral-800
|
|
@@ -31,13 +32,14 @@
|
|
|
31
32
|
[&_td.last-col]:border-r
|
|
32
33
|
[&_td.first-col]:border-l
|
|
33
34
|
`,
|
|
34
|
-
|
|
35
|
+
rounded && `
|
|
35
36
|
[&_td.br]:rounded-br-sm
|
|
36
37
|
[&_td.bl]:rounded-bl-sm
|
|
37
38
|
[&_td.tr]:rounded-tr-sm
|
|
38
39
|
[&_td.tl]:rounded-tl-sm
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
`,
|
|
41
|
+
$attrs.class
|
|
42
|
+
)"
|
|
41
43
|
v-resizable-cols="resizableOptions"
|
|
42
44
|
>
|
|
43
45
|
<thead v-if="header" class="table--header">
|
|
@@ -45,25 +47,21 @@
|
|
|
45
47
|
<template v-for="col,i of cols" :key="col">
|
|
46
48
|
<slot :name="`header-${col.toString()}`"
|
|
47
49
|
:class="[
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
: ''
|
|
53
|
-
].join(' ')"
|
|
50
|
+
extraClasses[`-1-${i}`],
|
|
51
|
+
'cell table--header-cell',
|
|
52
|
+
colConfig[col]?.resizable === false ? 'no-resize' : ''
|
|
53
|
+
].join(' ')"
|
|
54
54
|
:style="`width:${widths.length > 0 ? widths[i] : ``}; `"
|
|
55
55
|
:col-key="col"
|
|
56
56
|
>
|
|
57
57
|
<td :class="[
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
: ''
|
|
63
|
-
].join(' ')"
|
|
58
|
+
extraClasses[`-1-${i}`],
|
|
59
|
+
'cell table--header-cell',
|
|
60
|
+
colConfig[col]?.resizable === false ? 'no-resize' : ''
|
|
61
|
+
].join(' ')"
|
|
64
62
|
:style="`width:${widths.length > 0 ? widths[i] : ``}; `"
|
|
65
63
|
>
|
|
66
|
-
{{
|
|
64
|
+
{{ colConfig[col]?.name ?? col }}
|
|
67
65
|
</td>
|
|
68
66
|
</slot>
|
|
69
67
|
</template>
|
|
@@ -90,88 +88,53 @@
|
|
|
90
88
|
</table>
|
|
91
89
|
</template>
|
|
92
90
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
import
|
|
96
|
-
import {
|
|
97
|
-
import {
|
|
98
|
-
|
|
99
|
-
import { vResizableCols } from "../../directives/vResizableCols.js"
|
|
100
|
-
import type { ResizableOptions, TableColConfig } from "../../types/index.js"
|
|
101
|
-
import { twMerge } from "../../utils/twMerge.js"
|
|
102
|
-
import type { TailwindClassProp } from "../shared/props.js"
|
|
103
|
-
|
|
104
|
-
|
|
91
|
+
<script setup>
|
|
92
|
+
import { keys } from "@alanscodelog/utils/keys.js";
|
|
93
|
+
import { computed, ref } from "vue";
|
|
94
|
+
import { vResizableCols } from "../../directives/vResizableCols.js";
|
|
95
|
+
import { twMerge } from "../../utils/twMerge.js";
|
|
105
96
|
defineOptions({
|
|
106
|
-
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
97
|
+
name: "lib-table"
|
|
98
|
+
});
|
|
99
|
+
const props = defineProps({
|
|
100
|
+
resizable: { type: Object, required: false, default: () => ({}) },
|
|
101
|
+
values: { type: Array, required: false, default: () => [] },
|
|
102
|
+
itemKey: { type: [String, Number, Symbol, Function], required: false, default: "" },
|
|
103
|
+
cols: { type: Array, required: false, default: () => [] },
|
|
104
|
+
rounded: { type: Boolean, required: false, default: true },
|
|
105
|
+
border: { type: Boolean, required: false, default: true },
|
|
106
|
+
cellBorder: { type: Boolean, required: false, default: true },
|
|
107
|
+
header: { type: Boolean, required: false, default: true },
|
|
108
|
+
colConfig: { type: null, required: false, default: () => ({}) }
|
|
109
|
+
});
|
|
110
|
+
const widths = ref([]);
|
|
111
|
+
const resizableOptions = computed(() => ({
|
|
112
|
+
colCount: props.cols.length,
|
|
113
|
+
widths,
|
|
114
|
+
selector: ".cell",
|
|
115
|
+
...props.resizable
|
|
116
|
+
}));
|
|
117
|
+
const getExtraClasses = (row, col, isHeader) => {
|
|
118
|
+
const res = {
|
|
119
|
+
bl: !isHeader && row === props.values.length - 1 && col === 0,
|
|
120
|
+
br: !isHeader && row === props.values.length - 1 && col === props.cols.length - 1,
|
|
121
|
+
tr: (isHeader || !props.header) && row === 0 && col === props.cols.length - 1,
|
|
122
|
+
tl: (isHeader || !props.header) && row === 0 && col === 0,
|
|
123
|
+
"first-row": (isHeader || !props.header) && row === 0,
|
|
124
|
+
"last-row": row === props.values.length - 1,
|
|
125
|
+
"first-col": col === 0,
|
|
126
|
+
"last-col": col === props.cols.length - 1
|
|
127
|
+
};
|
|
128
|
+
return keys(res).filter((key) => res[key]);
|
|
129
|
+
};
|
|
130
|
+
const extraClasses = computed(() => Object.fromEntries(
|
|
131
|
+
[...Array(props.values.length + 1).keys()].map((row) => [...Array(props.cols.length).keys()].map((col) => [
|
|
132
|
+
`${row - 1}-${col}`,
|
|
133
|
+
getExtraClasses(row <= 0 ? 0 : row - 1, col, row === 0).join(" ")
|
|
134
|
+
])).flat()
|
|
135
|
+
));
|
|
136
|
+
</script>
|
|
144
137
|
|
|
145
|
-
|
|
146
|
-
.map(row => [...Array(props.cols.length).keys()]
|
|
147
|
-
.map(col =>
|
|
148
|
-
[
|
|
149
|
-
`${row - 1}-${col}`,
|
|
150
|
-
getExtraClasses(row <= 0 ? 0 : row - 1, col, row === 0).join(" "),
|
|
151
|
-
]))
|
|
152
|
-
.flat(),
|
|
153
|
-
))
|
|
138
|
+
<script>
|
|
154
139
|
|
|
155
140
|
</script>
|
|
156
|
-
<script lang="ts">
|
|
157
|
-
// generic isn't working here :/
|
|
158
|
-
type T = any
|
|
159
|
-
|
|
160
|
-
type RealProps = {
|
|
161
|
-
resizable?: Partial<ResizableOptions>
|
|
162
|
-
values?: T[]
|
|
163
|
-
itemKey?: keyof T | ((item: T) => string)
|
|
164
|
-
/** Let's the table know the shape of the data since values might be empty. */
|
|
165
|
-
cols?: (keyof T)[]
|
|
166
|
-
rounded?: boolean
|
|
167
|
-
border?: boolean
|
|
168
|
-
cellBorder?: boolean
|
|
169
|
-
header?: boolean
|
|
170
|
-
colConfig?: TableColConfig<T>
|
|
171
|
-
}
|
|
172
|
-
interface Props
|
|
173
|
-
extends
|
|
174
|
-
/** @vue-ignore */
|
|
175
|
-
Partial<Omit<TableHTMLAttributes,"class" | "readonly" | "disabled"> & TailwindClassProp>,
|
|
176
|
-
RealProps { }
|
|
177
|
-
</script>
|