@witchcraft/ui 0.1.3 → 0.2.1-beta.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.
Files changed (179) hide show
  1. package/README.md +3 -6
  2. package/dist/module.json +3 -3
  3. package/dist/module.mjs +15 -12
  4. package/dist/runtime/build/generateTheme.js +1 -1
  5. package/dist/runtime/components/Aria/Aria.vue +5 -9
  6. package/dist/runtime/components/Aria/Aria.vue.d.ts +5 -0
  7. package/dist/runtime/components/Icon/Icon.vue +10 -30
  8. package/dist/runtime/components/Icon/Icon.vue.d.ts +21 -0
  9. package/dist/runtime/components/LibButton/LibButton.vue +51 -72
  10. package/dist/runtime/components/LibButton/LibButton.vue.d.ts +36 -0
  11. package/dist/runtime/components/LibCheckbox/LibCheckbox.vue +43 -74
  12. package/dist/runtime/components/LibCheckbox/LibCheckbox.vue.d.ts +42 -0
  13. package/dist/runtime/components/LibColorInput/LibColorInput.vue +63 -107
  14. package/dist/runtime/components/LibColorInput/LibColorInput.vue.d.ts +63 -0
  15. package/dist/runtime/components/LibColorPicker/LibColorPicker.vue +272 -352
  16. package/dist/runtime/components/LibColorPicker/LibColorPicker.vue.d.ts +61 -0
  17. package/dist/runtime/components/LibColorPicker/utils/safeConvertToHsva.js +1 -1
  18. package/dist/runtime/components/LibColorPicker/utils/safeConvertToRgba.js +1 -1
  19. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +35 -69
  20. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue.d.ts +22 -0
  21. package/dist/runtime/components/LibDatePicker/LibDatePicker.vue +17 -38
  22. package/dist/runtime/components/LibDatePicker/LibDatePicker.vue.d.ts +40 -0
  23. package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue +58 -82
  24. package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue.d.ts +34 -0
  25. package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue +55 -67
  26. package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue.d.ts +34 -0
  27. package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue +7 -8
  28. package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue.d.ts +22 -0
  29. package/dist/runtime/components/LibDebug/LibDebug.vue +43 -70
  30. package/dist/runtime/components/LibDebug/LibDebug.vue.d.ts +32 -0
  31. package/dist/runtime/components/LibDevOnly/LibDevOnly.vue +18 -31
  32. package/dist/runtime/components/LibDevOnly/LibDevOnly.vue.d.ts +22 -0
  33. package/dist/runtime/components/LibFileInput/LibFileInput.vue +116 -156
  34. package/dist/runtime/components/LibFileInput/LibFileInput.vue.d.ts +43 -0
  35. package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue +211 -241
  36. package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue.d.ts +165 -0
  37. package/dist/runtime/components/LibLabel/LibLabel.vue +25 -46
  38. package/dist/runtime/components/LibLabel/LibLabel.vue.d.ts +26 -0
  39. package/dist/runtime/components/LibMultiValues/LibMultiValues.vue +43 -58
  40. package/dist/runtime/components/LibMultiValues/LibMultiValues.vue.d.ts +29 -0
  41. package/dist/runtime/components/LibNotifications/LibNotification.vue +34 -48
  42. package/dist/runtime/components/LibNotifications/LibNotification.vue.d.ts +17 -0
  43. package/dist/runtime/components/LibNotifications/LibNotifications.vue +63 -83
  44. package/dist/runtime/components/LibNotifications/LibNotifications.vue.d.ts +13 -0
  45. package/dist/runtime/components/LibPagination/LibPagination.vue +67 -111
  46. package/dist/runtime/components/LibPagination/LibPagination.vue.d.ts +104 -0
  47. package/dist/runtime/components/LibPalette/LibPalette.vue +17 -23
  48. package/dist/runtime/components/LibPalette/LibPalette.vue.d.ts +14 -0
  49. package/dist/runtime/components/LibPopup/LibPopup.vue +314 -351
  50. package/dist/runtime/components/LibPopup/LibPopup.vue.d.ts +46 -0
  51. package/dist/runtime/components/LibProgressBar/LibProgressBar.vue +65 -91
  52. package/dist/runtime/components/LibProgressBar/LibProgressBar.vue.d.ts +41 -0
  53. package/dist/runtime/components/LibRecorder/LibRecorder.vue +127 -177
  54. package/dist/runtime/components/LibRecorder/LibRecorder.vue.d.ts +77 -0
  55. package/dist/runtime/components/LibRoot/LibRoot.vue +75 -101
  56. package/dist/runtime/components/LibRoot/LibRoot.vue.d.ts +41 -0
  57. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue +42 -77
  58. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue.d.ts +35 -0
  59. package/dist/runtime/components/LibSuggestions/LibSuggestions.vue +118 -156
  60. package/dist/runtime/components/LibSuggestions/LibSuggestions.vue.d.ts +94 -0
  61. package/dist/runtime/components/LibTable/LibTable.vue +63 -99
  62. package/dist/runtime/components/LibTable/LibTable.vue.d.ts +45 -0
  63. package/dist/runtime/components/Template/NAME.vue +15 -36
  64. package/dist/runtime/components/Template/NAME.vue.d.ts +17 -0
  65. package/dist/runtime/components/TestControls/TestControls.vue +6 -9
  66. package/dist/runtime/components/TestControls/TestControls.vue.d.ts +5 -0
  67. package/dist/runtime/components/shared/props.d.ts +0 -29
  68. package/dist/runtime/components/shared/props.js +0 -12
  69. package/dist/runtime/composables/useAccesibilityOutline.js +1 -1
  70. package/dist/runtime/composables/useDivideAttrs.js +1 -1
  71. package/dist/runtime/composables/useSuggestions.js +4 -4
  72. package/dist/runtime/directives/vDetectFlex.js +4 -4
  73. package/dist/runtime/directives/vExtractRootEl.d.ts +1 -1
  74. package/dist/runtime/directives/vResizableCols.d.ts +1 -1
  75. package/dist/runtime/directives/vResizableCols.js +4 -4
  76. package/dist/runtime/helpers/NotificationHandler.js +6 -6
  77. package/dist/runtime/helpers/base64ToImg.js +2 -2
  78. package/dist/runtime/nuxt/plugins/vue-plugin.js +1 -1
  79. package/dist/runtime/tailwind/themeConvertionOpts.d.ts +1 -1
  80. package/dist/runtime/theme.d.ts +1 -1
  81. package/dist/runtime/theme.js +1 -1
  82. package/dist/runtime/utils/notifyIfError.js +1 -1
  83. package/dist/runtime/vue/registerComponents.js +1 -1
  84. package/dist/types.d.mts +2 -6
  85. package/package.json +68 -90
  86. package/src/module.ts +19 -12
  87. package/src/runtime/build/generateTheme.ts +1 -1
  88. package/src/runtime/components/LibButton/LibButton.stories.ts +1 -1
  89. package/src/runtime/components/LibButton/LibButton.vue +3 -3
  90. package/src/runtime/components/LibCheckbox/LibCheckbox.vue +3 -7
  91. package/src/runtime/components/LibColorPicker/LibColorPicker.vue +6 -4
  92. package/src/runtime/components/LibColorPicker/utils/safeConvertToHsva.ts +1 -1
  93. package/src/runtime/components/LibColorPicker/utils/safeConvertToRgba.ts +1 -1
  94. package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +8 -15
  95. package/src/runtime/components/LibDatePicker/LibRangeDatePicker.vue +6 -0
  96. package/src/runtime/components/LibDatePicker/LibSingleDatePicker.vue +6 -0
  97. package/src/runtime/components/LibDebug/LibDebug.stories.ts +1 -1
  98. package/src/runtime/components/LibDebug/LibDebug.vue +2 -0
  99. package/src/runtime/components/LibFileInput/LibFileInput.vue +4 -0
  100. package/src/runtime/components/LibInputDeprecated/LibInputDeprecated.vue +7 -5
  101. package/src/runtime/components/LibLabel/LibLabel.vue +2 -3
  102. package/src/runtime/components/LibMultiValues/LibMultiValues.vue +5 -3
  103. package/src/runtime/components/LibNotifications/LibNotification.vue +3 -0
  104. package/src/runtime/components/LibNotifications/LibNotifications.vue +1 -1
  105. package/src/runtime/components/LibPalette/LibPalette.vue +3 -3
  106. package/src/runtime/components/LibPopup/LibPopup.vue +2 -2
  107. package/src/runtime/components/LibProgressBar/LibProgressBar.vue +2 -2
  108. package/src/runtime/components/LibRecorder/LibRecorder.vue +3 -3
  109. package/src/runtime/components/LibRoot/LibRoot.vue +3 -2
  110. package/src/runtime/components/LibSimpleInput/LibSimpleInput.vue +2 -2
  111. package/src/runtime/components/LibSuggestions/LibSuggestions.vue +2 -2
  112. package/src/runtime/components/LibTable/LibTable.vue +1 -1
  113. package/src/runtime/components/Template/NAME.vue +2 -2
  114. package/src/runtime/components/shared/props.ts +8 -12
  115. package/src/runtime/composables/useAccesibilityOutline.ts +1 -1
  116. package/src/runtime/composables/useDivideAttrs.ts +1 -1
  117. package/src/runtime/composables/useSuggestions.ts +4 -4
  118. package/src/runtime/directives/vDetectFlex.ts +4 -4
  119. package/src/runtime/directives/vExtractRootEl.ts +1 -1
  120. package/src/runtime/directives/vResizableCols.ts +5 -5
  121. package/src/runtime/helpers/NotificationHandler.ts +6 -6
  122. package/src/runtime/nuxt/plugins/vue-plugin.ts +1 -1
  123. package/src/runtime/tailwind/themeConvertionOpts.ts +1 -1
  124. package/src/runtime/theme.ts +2 -2
  125. package/src/runtime/utils/notifyIfError.ts +1 -1
  126. package/src/runtime/vue/registerComponents.ts +1 -1
  127. package/dist/module.cjs +0 -5
  128. package/dist/module.d.ts +0 -36
  129. package/dist/runtime/components/Focus.stories.d.ts +0 -11
  130. package/dist/runtime/components/Focus.stories.js +0 -53
  131. package/dist/runtime/components/LibButton/LibButton.stories.d.ts +0 -12
  132. package/dist/runtime/components/LibButton/LibButton.stories.js +0 -94
  133. package/dist/runtime/components/LibCheckbox/LibCheckbox.stories.d.ts +0 -14
  134. package/dist/runtime/components/LibCheckbox/LibCheckbox.stories.js +0 -29
  135. package/dist/runtime/components/LibColorInput/LibColorInput.stories.d.ts +0 -7
  136. package/dist/runtime/components/LibColorInput/LibColorInput.stories.js +0 -58
  137. package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.d.ts +0 -9
  138. package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.js +0 -68
  139. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.d.ts +0 -7
  140. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.js +0 -36
  141. package/dist/runtime/components/LibDatePicker/LibDatePicker.stories.d.ts +0 -11
  142. package/dist/runtime/components/LibDatePicker/LibDatePicker.stories.js +0 -98
  143. package/dist/runtime/components/LibDebug/LibDebug.stories.d.ts +0 -9
  144. package/dist/runtime/components/LibDebug/LibDebug.stories.js +0 -46
  145. package/dist/runtime/components/LibFileInput/LibFileInput.stories.d.ts +0 -10
  146. package/dist/runtime/components/LibFileInput/LibFileInput.stories.js +0 -63
  147. package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.stories.d.ts +0 -33
  148. package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.stories.js +0 -384
  149. package/dist/runtime/components/LibLabel/LibLabel.stories.d.ts +0 -6
  150. package/dist/runtime/components/LibLabel/LibLabel.stories.js +0 -25
  151. package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.d.ts +0 -23
  152. package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.js +0 -61
  153. package/dist/runtime/components/LibNotifications/LibNotification.stories.d.ts +0 -15
  154. package/dist/runtime/components/LibNotifications/LibNotification.stories.js +0 -126
  155. package/dist/runtime/components/LibNotifications/LibNotifications.stories.d.ts +0 -6
  156. package/dist/runtime/components/LibNotifications/LibNotifications.stories.js +0 -109
  157. package/dist/runtime/components/LibPagination/LibPagination.stories.d.ts +0 -6
  158. package/dist/runtime/components/LibPagination/LibPagination.stories.js +0 -40
  159. package/dist/runtime/components/LibPalette/LibPalette.stories.d.ts +0 -6
  160. package/dist/runtime/components/LibPalette/LibPalette.stories.js +0 -20
  161. package/dist/runtime/components/LibPopup/LibPopup.stories.d.ts +0 -14
  162. package/dist/runtime/components/LibPopup/LibPopup.stories.js +0 -147
  163. package/dist/runtime/components/LibProgressBar/LibProgressBar.stories.d.ts +0 -10
  164. package/dist/runtime/components/LibProgressBar/LibProgressBar.stories.js +0 -81
  165. package/dist/runtime/components/LibRecorder/LibRecorder.stories.d.ts +0 -19
  166. package/dist/runtime/components/LibRecorder/LibRecorder.stories.js +0 -63
  167. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.stories.d.ts +0 -26
  168. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.stories.js +0 -78
  169. package/dist/runtime/components/LibSuggestions/LibSuggestions.stories.d.ts +0 -27
  170. package/dist/runtime/components/LibSuggestions/LibSuggestions.stories.js +0 -112
  171. package/dist/runtime/components/LibTable/LibTable.stories.d.ts +0 -16
  172. package/dist/runtime/components/LibTable/LibTable.stories.js +0 -156
  173. package/dist/runtime/components/Reset.stories.d.ts +0 -5
  174. package/dist/runtime/components/Reset.stories.js +0 -19
  175. package/dist/runtime/components/Scrolling.stories.d.ts +0 -6
  176. package/dist/runtime/components/Scrolling.stories.js +0 -44
  177. package/dist/runtime/composables/useScrollNearContainerEdges.stories.d.ts +0 -7
  178. package/dist/runtime/composables/useScrollNearContainerEdges.stories.js +0 -85
  179. 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
- ($.attrs as any)?.class
12
- )"
12
+ $.attrs?.class
13
+ )"
13
14
  :data-open="$open"
14
15
  role="listbox"
15
16
  ref="el"
16
- v-bind="{...$.attrs, class:undefined}"
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
- index=== suggestions.active && `
29
+ index === suggestions.active && `
28
30
  bg-accent-200
29
31
  dark:bg-accent-800/70
30
32
  `,
31
- ($.itemAttrs as any)?.class
32
- )"
33
- v-bind="{...$.itemAttrs, class:undefined}"
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,158 +59,118 @@
57
59
  </div>
58
60
  </template>
59
61
 
60
-
61
- <script setup lang="ts" generic="TSuggestion extends string | object, TValue extends string|string[]">
62
-
63
- import { type HTMLAttributes,reactive, ref } from "vue"
64
-
65
- import { useDivideAttrs } from "../../composables/useDivideAttrs.js"
66
- import { useSuggestions } from "../../composables/useSuggestions.js"
67
- import { hasModifiers } from "../../helpers/hasModifiers.js"
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 { getFallbackId } from "../shared/props.js";
72
70
  defineOptions({
73
- name: "lib-suggestions",
74
- inheritAttrs: false,
75
- })
76
-
77
- const $ = useDivideAttrs(["item"] as const)
78
-
79
- const emits = defineEmits<SuggestionsEmits>()
80
-
81
- const fallbackId = getFallbackId()
82
- const props = withDefaults(defineProps<Props & SuggestionsProps<TSuggestion>>(), {
83
- isValid: true,
84
- canOpen: true,
85
- filterKeydown: undefined,
86
- ...baseInteractivePropsDefaults
87
- })
88
- /**
89
- * 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.
90
- *
91
- * If suggestions are objects, this will be the string returned by the `suggestionLabel` prop.
92
- */
93
- const $modelValue = defineModel<TValue>("modelValue", { required: true })
94
- /**
95
- * If the element is bound to an input, this is the value that the input should be sharing.
96
- *
97
- * 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.
98
- */
99
- const $inputValue = defineModel<string >("inputValue", { default: "" })
100
-
101
- const $open = defineModel<boolean>("open", { default: false })
102
-
103
-
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({
78
+ id: { type: String, required: false },
79
+ label: { type: String, required: false },
80
+ disabled: { type: Boolean, required: false, default: false },
81
+ readonly: { type: Boolean, required: false, default: false },
82
+ border: { type: Boolean, required: false, default: true },
83
+ unstyle: { type: Boolean, required: false, default: false },
84
+ filterKeydown: { type: Function, required: false, default: void 0 },
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, default: true },
94
+ canClose: { type: Boolean, required: false },
95
+ isValid: { type: Boolean, required: false, default: true },
96
+ suggestionSelector: { type: Function, required: false },
97
+ showSelectedValues: { type: Boolean, required: false }
98
+ });
99
+ const $modelValue = defineModel("modelValue", { type: null, ...{ required: true } });
100
+ const $inputValue = defineModel("inputValue", { type: String, ...{ default: "" } });
101
+ const $open = defineModel("open", { type: Boolean, ...{ default: false } });
104
102
  if (typeof props.suggestions?.[0] === "object" && !props.suggestionLabel && !props.suggestionsFilter) {
105
- throw new Error("`suggestionLabel` or `suggestionsFilter` must be passed if suggestions are objects.")
103
+ throw new Error("`suggestionLabel` or `suggestionsFilter` must be passed if suggestions are objects.");
106
104
  }
107
-
108
- const el = ref<HTMLElement | null>(null)
109
-
110
- const suggestions = reactive(useSuggestions<TSuggestion, TValue extends string[] ? true : false>(
111
- $inputValue,
112
- $modelValue as any,
113
- $open,
114
- emits,
115
- props
116
- ))
117
-
118
- const inputKeydownHandler = (e: KeyboardEvent): void => {
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: MouseEvent): void => {
150
- if (props.filterBlur?.(e)) return
151
-
152
- if (!$open.value) return
153
-
154
- if (props.restrictToSuggestions) {
155
- suggestions.cancel()
156
- } else {
157
- if (!Array.isArray($modelValue.value)) {
158
- $modelValue.value = $inputValue.value as any
159
- }
160
- }
161
- if ($open.value) {
162
- suggestions.close()
163
- }
164
- }
165
- const inputFocusHandler = (e: FocusEvent): void => {
166
- if (props.filterFocus?.(e)) return
167
- suggestions.open()
168
- }
169
-
105
+ const el = ref(null);
106
+ const suggestions = reactive(useSuggestions(
107
+ $inputValue,
108
+ $modelValue,
109
+ $open,
110
+ emits,
111
+ props
112
+ ));
113
+ const inputKeydownHandler = (e) => {
114
+ if (props.filterKeydown?.(e)) return;
115
+ if (hasModifiers(e)) return;
116
+ if (e.key === "Enter") {
117
+ suggestions.enterSelected(!Array.isArray($modelValue));
118
+ e.preventDefault();
119
+ } else if (e.key === "Escape") {
120
+ suggestions.cancel();
121
+ e.preventDefault();
122
+ } else if (!$open.value && ["ArrowDown", "ArrowUp", "PageUp", "PageDown"].includes(e.key) && suggestions.available) {
123
+ suggestions.open();
124
+ e.preventDefault();
125
+ if (e.key === "PageUp") {
126
+ suggestions.first();
127
+ } else if (e.key === "PageDown") {
128
+ suggestions.last();
129
+ }
130
+ } else if (e.key === "ArrowUp") {
131
+ suggestions.prev();
132
+ e.preventDefault();
133
+ } else if (e.key === "ArrowDown") {
134
+ suggestions.next();
135
+ e.preventDefault();
136
+ } else if (e.key === "PageUp") {
137
+ suggestions.first();
138
+ e.preventDefault();
139
+ } else if (e.key === "PageDown") {
140
+ suggestions.last();
141
+ e.preventDefault();
142
+ }
143
+ };
144
+ const inputBlurHandler = (e) => {
145
+ if (props.filterBlur?.(e)) return;
146
+ if (!$open.value) return;
147
+ if (props.restrictToSuggestions) {
148
+ suggestions.cancel();
149
+ } else {
150
+ if (!Array.isArray($modelValue.value)) {
151
+ $modelValue.value = $inputValue.value;
152
+ }
153
+ }
154
+ if ($open.value) {
155
+ suggestions.close();
156
+ }
157
+ };
158
+ const inputFocusHandler = (e) => {
159
+ if (props.filterFocus?.(e)) return;
160
+ suggestions.open();
161
+ };
170
162
  defineExpose({
171
- suggestions,
172
- el,
173
- /** A simple keydown handler that can be passed to an input to control the component while still focused inside it. */
174
- inputKeydownHandler,
175
- /** 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. */
176
- inputBlurHandler,
177
- /** A focus handler for the input that controls the component. */
178
- inputFocusHandler,
179
- })
180
-
163
+ suggestions,
164
+ el,
165
+ /** A simple keydown handler that can be passed to an input to control the component while still focused inside it. */
166
+ inputKeydownHandler,
167
+ /** 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. */
168
+ inputBlurHandler,
169
+ /** A focus handler for the input that controls the component. */
170
+ inputFocusHandler
171
+ });
181
172
  </script>
182
173
 
183
- <script lang="ts">
184
- type WrapperTypes = Partial<WrapperProps<"item",HTMLAttributes, {
185
- /** Tailwind classes. */
186
- class?: string
187
- }>>
188
-
189
- type RealProps =
190
- & LinkableByIdProps
191
- & LabelProps
192
- & BaseInteractiveProps
193
- & {
194
- /** Return true to prevent the keydown event from being handled. */
195
- filterKeydown?: (e: KeyboardEvent) => boolean
196
- /** Return true to prevent the blur event from being handled. */
197
- filterBlur?: (e: MouseEvent) => boolean
198
- /** Return true to prevent the focus event from being handled. */
199
- filterFocus?: (e: FocusEvent) => boolean
200
- }
201
-
202
- interface Props
203
- extends
204
- /** @vue-ignore */
205
- Partial<Omit<HTMLAttributes,"class" | "onSubmit"> & {
206
- /** Tailwind classes. */
207
- class?: string
208
- }>,
209
- /** @vue-ignore */
210
- WrapperTypes,
211
- RealProps
212
- {}
174
+ <script>
213
175
 
214
176
  </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(`table
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
- cellBorder && `
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
- border && `
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
- rounded &&`
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
- , ($attrs as any).class)"
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
- extraClasses[`-1-${i}`],
49
- 'cell table--header-cell',
50
- (colConfig as any)[col]?.resizable === false
51
- ? 'no-resize'
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
- extraClasses[`-1-${i}`] ,
59
- 'cell table--header-cell',
60
- (colConfig as any)[col]?.resizable === false
61
- ? 'no-resize'
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
- {{ (colConfig as any)[col]?.name ?? col }}
64
+ {{ colConfig[col]?.name ?? col }}
67
65
  </td>
68
66
  </slot>
69
67
  </template>
@@ -90,87 +88,53 @@
90
88
  </table>
91
89
  </template>
92
90
 
93
- <!-- generic="T extends Record<string, any> -->"
94
- <script setup lang="ts" generic="T">
95
- import type { MakeRequired } from "@alanscodelog/utils"
96
- import { keys } from "@alanscodelog/utils/keys.js"
97
- import { computed, type PropType, ref, type TableHTMLAttributes } from "vue"
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";
93
+ import { computed, ref } from "vue";
94
+ import { vResizableCols } from "../../directives/vResizableCols.js";
95
+ import { twMerge } from "../../utils/twMerge.js";
105
96
  defineOptions({
106
- name: "lib-table",
107
- })
108
-
109
- const props = withDefaults(defineProps<Props>(), {
110
- resizable: () => ({}),
111
- values: () => [] as T[],
112
- itemKey: "",
113
- cols: () => [] as (keyof T)[],
114
- rounded: true,
115
- border: true,
116
- cellBorder: true,
117
- header: true,
118
- colConfig: () => ({}) ,
119
- })
120
-
121
- const widths = ref([])
122
- const resizableOptions = computed<MakeRequired<Partial<ResizableOptions>, "colCount" | "widths">>(() => ({
123
- colCount: props.cols.length,
124
- widths,
125
- selector: ".cell",
126
- ...props.resizable,
127
- }))
128
-
129
- /* props.values.length instead of `props.values.length - 1` because we're creating an artificial first row for the header */
130
- const getExtraClasses = (row: number, col: number, isHeader: boolean): string[] => {
131
- const res = {
132
- bl: !isHeader && row === props.values.length - 1 && col === 0,
133
- br: !isHeader && row === props.values.length - 1 && col === props.cols.length - 1,
134
- tr: (isHeader || !props.header) && row === 0 && col === props.cols.length - 1,
135
- tl: (isHeader || !props.header) && row === 0 && col === 0,
136
- "first-row": (isHeader || !props.header) && row === 0,
137
- "last-row": row === props.values.length - 1,
138
- "first-col": col === 0,
139
- "last-col": col === props.cols.length - 1,
140
- }
141
- return keys(res).filter(key => res[key])
142
- }
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: Object, 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>
143
137
 
144
- const extraClasses = computed(() => Object.fromEntries([...Array(props.values.length + 1).keys()]
145
- .map(row => [...Array(props.cols.length).keys()]
146
- .map(col =>
147
- [
148
- `${row - 1}-${col}`,
149
- getExtraClasses(row <= 0 ? 0 : row - 1, col, row === 0).join(" "),
150
- ]))
151
- .flat(),
152
- ))
138
+ <script>
153
139
 
154
140
  </script>
155
- <script lang="ts">
156
- // generic isn't working here :/
157
- type T = any
158
-
159
- type RealProps = {
160
- resizable?: Partial<ResizableOptions>
161
- values?: T[]
162
- itemKey?: keyof T | ((item: T) => string)
163
- /** Let's the table know the shape of the data since values might be empty. */
164
- cols?: (keyof T)[]
165
- rounded?: boolean
166
- border?: boolean
167
- cellBorder?: boolean
168
- header?: boolean
169
- colConfig?: TableColConfig<T>
170
- }
171
- interface Props
172
- extends
173
- /** @vue-ignore */
174
- Partial<Omit<TableHTMLAttributes,"class" | "readonly" | "disabled"> & TailwindClassProp>,
175
- RealProps { }
176
- </script>