@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,7 +2,8 @@
2
2
  <div
3
3
  :id="id ?? fallbackId"
4
4
  :aria-label="t('color-picker.aria')"
5
- :class="twMerge(`color-picker
5
+ :class="twMerge(
6
+ `color-picker
6
7
  [--slider-size:calc(var(--spacing)_*_4)]
7
8
  [--contrast-dark:var(--color-neutral-100)]
8
9
  [--contrast-light:var(--color-neutral-800)]
@@ -15,15 +16,15 @@
15
16
  gap-3
16
17
  p-3
17
18
  `,
18
- invertColors && `
19
+ invertColors && `
19
20
  [--fg:rgb(var(--contrast-light))]
20
21
  [--bg:rgb(var(--contrast-dark))]
21
22
  `,
22
- border && `
23
+ border && `
23
24
  border rounded-sm border-neutral-600
24
25
  `,
25
- ($attrs as any)?.class
26
- )"
26
+ $attrs?.class
27
+ )"
27
28
  >
28
29
  <div
29
30
  :class="`color-picker--all-picker
@@ -168,37 +169,30 @@
168
169
  </div>
169
170
  </template>
170
171
 
171
- <script setup lang="ts">
172
- /* todo change to colorjsio for less dependencies */
173
- import { castType } from "@alanscodelog/utils/castType.js"
174
- import { clampNumber } from "@alanscodelog/utils/clampNumber.js"
175
- import { isArray } from "@alanscodelog/utils/isArray.js"
176
- import { unreachable } from "@alanscodelog/utils/unreachable.js"
177
- import Color from "colorjs.io"
178
- import { computed, onMounted, reactive, type Ref, ref, type UnwrapRef,useAttrs, watch } from "vue"
179
-
180
- import { safeConvertToHsva } from "./utils/safeConvertToHsva.js"
181
- import { safeConvertToRgba } from "./utils/safeConvertToRgba.js"
182
- import { toLowPrecisionRgbaString } from "./utils/toLowPrecisionRgbaString.js"
183
-
184
- import { useInjectedI18n } from "../../composables/useInjectedI18n.js"
185
- import { copy } from "../../helpers/copy.js"
186
- import type { HsvaColor, RgbaColor } from "../../types/index.js"
187
- import { twMerge } from "../../utils/twMerge.js"
188
- import aria from "../Aria/Aria.vue"
189
- import Icon from "../Icon/Icon.vue"
190
- import LibButton from "../LibButton/LibButton.vue"
191
- import LibSimpleInput from "../LibSimpleInput/LibSimpleInput.vue"
192
- import { getFallbackId, type LabelProps , type LinkableByIdProps } from "../shared/props.js"
193
-
172
+ <script setup>
173
+ import { castType } from "@alanscodelog/utils/castType";
174
+ import { clampNumber } from "@alanscodelog/utils/clampNumber";
175
+ import { isArray } from "@alanscodelog/utils/isArray";
176
+ import { unreachable } from "@alanscodelog/utils/unreachable";
177
+ import Color from "colorjs.io";
178
+ import { computed, onMounted, reactive, ref, useAttrs, watch } from "vue";
179
+ import { safeConvertToHsva } from "./utils/safeConvertToHsva.js";
180
+ import { safeConvertToRgba } from "./utils/safeConvertToRgba.js";
181
+ import { toLowPrecisionRgbaString } from "./utils/toLowPrecisionRgbaString.js";
182
+ import IFa6RegularCopy from "~icons/fa-regular/copy";
183
+ import { useInjectedI18n } from "../../composables/useInjectedI18n.js";
184
+ import { copy } from "../../helpers/copy.js";
185
+ import { twMerge } from "../../utils/twMerge.js";
186
+ import aria from "../Aria/Aria.vue";
187
+ import Icon from "../Icon/Icon.vue";
188
+ import LibButton from "../LibButton/LibButton.vue";
189
+ import LibSimpleInput from "../LibSimpleInput/LibSimpleInput.vue";
190
+ import { getFallbackId } from "../shared/props.js";
194
191
  defineOptions({
195
- name: "lib-color-picker",
196
- })
197
-
198
- const $attrs = useAttrs()
199
-
200
- const t = useInjectedI18n()
201
-
192
+ name: "lib-color-picker"
193
+ });
194
+ const $attrs = useAttrs();
195
+ const t = useInjectedI18n();
202
196
  const sliderClasses = `
203
197
  slider
204
198
  no-touch-action
@@ -206,8 +200,7 @@ const sliderClasses = `
206
200
  w-full
207
201
  relative
208
202
  flex
209
- `
210
-
203
+ `;
211
204
  const handleClasses = `
212
205
  handle
213
206
  h-[var(--slider-size)]
@@ -222,338 +215,265 @@ const handleClasses = `
222
215
  focus:border-accent-500
223
216
  active:border-accent-500
224
217
  hover:border-accent-500
225
- `
226
- const emits = defineEmits<{
227
- (e: "save", val: RgbaColor): void
228
- (e: "cancel"): void
229
- }>()
230
-
231
- const props = withDefaults(defineProps<
232
- LabelProps
233
- & LinkableByIdProps
234
- & {
235
- allowAlpha?: boolean
236
- /**
237
- * The precision of the rgba string representation of the color. Defaults to 3. Extra trailing zeros are removed for a prettier number.
238
- *
239
- * Does not affect the number saved unless the user manually edits the color.
240
- *
241
- * Ignored if `customRepresentation` is set.
242
- */
243
- stringPrecision?: number
244
- /** Allows overriding the string representation of the color. Useful for using a different representation than rgba (e.g. hex). The fromStringToHsva part is rarely needed as the colorjs.io library can normally parse the color. Returning undefined signals an error. */
245
- customRepresentation?: {
246
- fromHsvaToString: (hsva: HsvaColor, includeAlpha: boolean) => string
247
- fromStringToHsva?: (string: string) => HsvaColor | undefined
248
- }
249
- border?: boolean
250
- /** Modify what the user copies to the clipboard. */
251
- copyTransform?: (val: HsvaColor, stringVal: string) => any
252
- valid?: boolean
253
- }>(), {
254
- allowAlpha: true,
255
- border: true,
256
- stringPrecision: 3,
257
- copyTransform: (_val: HsvaColor, stringVal: string) => stringVal,
258
- customRepresentation: undefined,
259
- valid: true,
260
- })
261
-
262
-
263
- const ariaDescription = t("color-picker.aria.description")
264
- const fallbackId = getFallbackId()
265
-
266
- const $value = defineModel<RgbaColor>({ required: false, default: () => ({ r: 0, g: 0, b: 0 }) })
267
- const $tempValue = defineModel<RgbaColor | undefined>("tempValue", { required: false, default: () => (undefined) })
268
-
269
- const pickerEl = ref<HTMLCanvasElement | null>(null)
270
- const hueSliderEl = ref<HTMLCanvasElement | null>(null)
271
- const alphaSliderEl = ref<HTMLCanvasElement | null>(null)
272
-
273
- type Config = Record<string, {
274
- el: Ref<HTMLCanvasElement>
275
- xKey?: keyof HsvaColor
276
- yKey?: keyof HsvaColor
277
- xSteps?: number
278
- ySteps?: number
279
- }>
280
-
281
- const config: Config = {
282
- hue: {
283
- el: hueSliderEl as Ref<HTMLCanvasElement>,
284
- xKey: "h",
285
- xSteps: 360,
286
- },
287
- alpha: {
288
- el: alphaSliderEl as Ref<HTMLCanvasElement>,
289
- xSteps: 1,
290
- xKey: "a",
291
- },
292
- all: {
293
- el: pickerEl as Ref<HTMLCanvasElement>,
294
- xSteps: 100,
295
- ySteps: 100,
296
- xKey: "s",
297
- yKey: "v",
298
- },
299
- }
300
-
301
- const localColor = reactive<Record<"percent" | "val", HsvaColor>>({
302
- percent: {
303
- h: 0, s: 0, v: 0, a: 0,
304
- },
305
- val: {
306
- h: 0, s: 0, v: 0, a: 0,
307
- },
308
- })
309
-
310
-
218
+ `;
219
+ const emits = defineEmits(["save", "cancel"]);
220
+ const props = defineProps({
221
+ label: { type: String, required: false },
222
+ id: { type: String, required: false },
223
+ allowAlpha: { type: Boolean, required: false, default: true },
224
+ stringPrecision: { type: Number, required: false, default: 3 },
225
+ customRepresentation: { type: Object, required: false, default: void 0 },
226
+ border: { type: Boolean, required: false, default: true },
227
+ copyTransform: { type: Function, required: false, default: (_val, stringVal) => stringVal },
228
+ valid: { type: Boolean, required: false, default: true }
229
+ });
230
+ const ariaDescription = t("color-picker.aria.description");
231
+ const fallbackId = getFallbackId();
232
+ const $value = defineModel({ type: Object, ...{ required: false, default: () => ({ r: 0, g: 0, b: 0 }) } });
233
+ const $tempValue = defineModel("tempValue", { type: null, ...{ required: false, default: () => void 0 } });
234
+ const pickerEl = ref(null);
235
+ const hueSliderEl = ref(null);
236
+ const alphaSliderEl = ref(null);
237
+ const config = {
238
+ hue: {
239
+ el: hueSliderEl,
240
+ xKey: "h",
241
+ xSteps: 360
242
+ },
243
+ alpha: {
244
+ el: alphaSliderEl,
245
+ xSteps: 1,
246
+ xKey: "a"
247
+ },
248
+ all: {
249
+ el: pickerEl,
250
+ xSteps: 100,
251
+ ySteps: 100,
252
+ xKey: "s",
253
+ yKey: "v"
254
+ }
255
+ };
256
+ const localColor = reactive({
257
+ percent: {
258
+ h: 0,
259
+ s: 0,
260
+ v: 0,
261
+ a: 0
262
+ },
263
+ val: {
264
+ h: 0,
265
+ s: 0,
266
+ v: 0,
267
+ a: 0
268
+ }
269
+ });
311
270
  const asRgba = computed(() => {
312
- const rgba = safeConvertToRgba(localColor.val, props.allowAlpha)
313
- if (!rgba) unreachable()
314
- return rgba
315
- })
271
+ const rgba = safeConvertToRgba(localColor.val, props.allowAlpha);
272
+ if (!rgba) unreachable();
273
+ return rgba;
274
+ });
316
275
  const asRgbaString = computed(() => {
317
- const rgba = asRgba.value
318
- if (!rgba) unreachable()
319
- return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`
320
- })
276
+ const rgba = asRgba.value;
277
+ if (!rgba) unreachable();
278
+ return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;
279
+ });
321
280
  const localColorString = computed(() => {
322
- if (props.customRepresentation) {
323
- return props.customRepresentation.fromHsvaToString({ ...localColor.val }, props.allowAlpha)
324
- }
325
- return toLowPrecisionRgbaString(asRgba.value, props.allowAlpha, props.stringPrecision)
326
- })
327
-
328
- const localInputString = ref(localColorString.value)
329
- // fixes the localInputString not updating when the user inputs an invalid value
281
+ if (props.customRepresentation) {
282
+ return props.customRepresentation.fromHsvaToString({ ...localColor.val }, props.allowAlpha);
283
+ }
284
+ return toLowPrecisionRgbaString(asRgba.value, props.allowAlpha, props.stringPrecision);
285
+ });
286
+ const localInputString = ref(localColorString.value);
330
287
  function onBlurFixInvalidValue() {
331
- if (localInputString.value !== localColorString.value) {
332
- localInputString.value = localColorString.value
333
- }
288
+ if (localInputString.value !== localColorString.value) {
289
+ localInputString.value = localColorString.value;
290
+ }
334
291
  }
335
-
336
- function updatePicker(el: HTMLCanvasElement, hue: number): void {
337
- const ctx = el.getContext("2d")!
338
- const { height, width } = el
339
- ctx.clearRect(0, 0, width, height)
340
-
341
- const gradient = ctx.createLinearGradient(0, 0, 0, height)
342
- gradient.addColorStop(0, "white")
343
- gradient.addColorStop(1, "black")
344
- const gradientColor = ctx.createLinearGradient(0, 0, width, 0)
345
- gradientColor.addColorStop(0, `hsla(${hue} 100% 50% / 0)`)
346
- gradientColor.addColorStop(1, `hsla(${hue} 100% 50% /1)`)
347
-
348
-
349
- ctx.fillStyle = gradient
350
- ctx.fillRect(0, 0, width, height)
351
- ctx.fillStyle = gradientColor
352
- ctx.globalCompositeOperation = "multiply"
353
- ctx.fillRect(0, 0, width, height)
354
- ctx.globalCompositeOperation = "source-over"
292
+ function updatePicker(el, hue) {
293
+ const ctx = el.getContext("2d");
294
+ const { height, width } = el;
295
+ ctx.clearRect(0, 0, width, height);
296
+ const gradient = ctx.createLinearGradient(0, 0, 0, height);
297
+ gradient.addColorStop(0, "white");
298
+ gradient.addColorStop(1, "black");
299
+ const gradientColor = ctx.createLinearGradient(0, 0, width, 0);
300
+ gradientColor.addColorStop(0, `hsla(${hue} 100% 50% / 0)`);
301
+ gradientColor.addColorStop(1, `hsla(${hue} 100% 50% /1)`);
302
+ ctx.fillStyle = gradient;
303
+ ctx.fillRect(0, 0, width, height);
304
+ ctx.fillStyle = gradientColor;
305
+ ctx.globalCompositeOperation = "multiply";
306
+ ctx.fillRect(0, 0, width, height);
307
+ ctx.globalCompositeOperation = "source-over";
355
308
  }
356
-
357
- function updateSlider(el: HTMLCanvasElement, stops: ((i: number) => string) | string[], length: number = 360): void {
358
- const ctx = el.getContext("2d")!
359
- const { height, width } = el
360
- ctx.clearRect(0, 0, width, height)
361
-
362
- const end = isArray(stops) ? stops.length - 1 : length
363
-
364
- const gradient = ctx.createLinearGradient(0, 0, width, 0)
365
-
366
- for (let i = 0; i < end + 1; i++) {
367
- const stop = stops instanceof Function ? stops(i) : stops[i]
368
- if (stop === undefined) unreachable()
369
- gradient.addColorStop(i / end, stop)
370
- }
371
-
372
- ctx.fillStyle = gradient
373
- ctx.fillRect(0, 0, width, height)
309
+ function updateSlider(el, stops, length = 360) {
310
+ const ctx = el.getContext("2d");
311
+ const { height, width } = el;
312
+ ctx.clearRect(0, 0, width, height);
313
+ const end = isArray(stops) ? stops.length - 1 : length;
314
+ const gradient = ctx.createLinearGradient(0, 0, width, 0);
315
+ for (let i = 0; i < end + 1; i++) {
316
+ const stop = stops instanceof Function ? stops(i) : stops[i];
317
+ if (stop === void 0) unreachable();
318
+ gradient.addColorStop(i / end, stop);
319
+ }
320
+ ctx.fillStyle = gradient;
321
+ ctx.fillRect(0, 0, width, height);
374
322
  }
375
-
376
-
377
- function getVal(x: number, width: number, steps: number = 100, accuracy: number = 100, reverse = false): { val: number, percent: number } {
378
- const percent = (x / width)
379
- const unrounded = percent * steps
380
-
381
- const val = Math.round(unrounded * accuracy) / accuracy
382
- const percentVal = steps === accuracy ? val : Math.round(percent * 100 * accuracy) / accuracy
383
- const res = { val, percent: percentVal }
384
- if (reverse) res.val = steps - val
385
- return res
323
+ function getVal(x, width, steps = 100, accuracy = 100, reverse = false) {
324
+ const percent = x / width;
325
+ const unrounded = percent * steps;
326
+ const val = Math.round(unrounded * accuracy) / accuracy;
327
+ const percentVal = steps === accuracy ? val : Math.round(percent * 100 * accuracy) / accuracy;
328
+ const res = { val, percent: percentVal };
329
+ if (reverse) res.val = steps - val;
330
+ return res;
386
331
  }
387
-
388
- type Types = keyof UnwrapRef<Config>
389
- const elDragging = ref<Types | "">("")
390
- let dragging = false
391
-
392
- function moveHandle(e: { clientX: number, clientY: number }, type: string) {
393
- requestAnimationFrame(() => {
394
- if (type === "") return
395
- const el = config[type]?.el.value
396
- if (!el || !config[type]) return
397
- const { x, y, width, height } = el.getBoundingClientRect()
398
-
399
- const info = config[type]
400
- if (info.xKey !== undefined) {
401
- let newPosX = e.clientX - x
402
- newPosX = newPosX < 0 ? 0 : newPosX > width ? width : newPosX
403
- const newX = getVal(newPosX, width, info.xSteps ?? 100)
404
-
405
- localColor.percent[info.xKey] = newX.percent
406
- localColor.val[info.xKey] = newX.val
407
- }
408
-
409
- if (info.yKey !== undefined) {
410
- let newPosY = e.clientY - y
411
- newPosY = newPosY < 0 ? 0 : newPosY > height ? height : newPosY
412
- const newY = getVal(newPosY, height, info.ySteps ?? 100, 100, true)
413
-
414
- localColor.percent[info.yKey] = newY.percent
415
- localColor.val[info.yKey] = newY.val
416
- }
417
- })
332
+ const elDragging = ref("");
333
+ let dragging = false;
334
+ function moveHandle(e, type) {
335
+ requestAnimationFrame(() => {
336
+ if (type === "") return;
337
+ const el = config[type]?.el.value;
338
+ if (!el || !config[type]) return;
339
+ const { x, y, width, height } = el.getBoundingClientRect();
340
+ const info = config[type];
341
+ if (info.xKey !== void 0) {
342
+ let newPosX = e.clientX - x;
343
+ newPosX = newPosX < 0 ? 0 : newPosX > width ? width : newPosX;
344
+ const newX = getVal(newPosX, width, info.xSteps ?? 100);
345
+ localColor.percent[info.xKey] = newX.percent;
346
+ localColor.val[info.xKey] = newX.val;
347
+ }
348
+ if (info.yKey !== void 0) {
349
+ let newPosY = e.clientY - y;
350
+ newPosY = newPosY < 0 ? 0 : newPosY > height ? height : newPosY;
351
+ const newY = getVal(newPosY, height, info.ySteps ?? 100, 100, true);
352
+ localColor.percent[info.yKey] = newY.percent;
353
+ localColor.val[info.yKey] = newY.val;
354
+ }
355
+ });
418
356
  }
419
357
  const slider = {
420
- keydown: (e: KeyboardEvent, type: Types) => {
421
- castType<HTMLElement | undefined>(e.target)
422
- if (e.target?.getBoundingClientRect) {
423
- if (["ArrowRight", "ArrowLeft", "ArrowUp", "ArrowDown"].includes(e.key)) {
424
- e.preventDefault()
425
- const { x, y, width, height } = e.target.getBoundingClientRect()
426
- let xDiff = e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : 0
427
- let yDiff = e.key === "ArrowUp" ? -1 : e.key === "ArrowDown" ? 1 : 0
428
- if (e.shiftKey) {xDiff *= 10}
429
- if (e.shiftKey) {yDiff *= 10}
430
- moveHandle({ clientX: x + (width / 2) + xDiff, clientY: y + (height / 2) + yDiff }, type)
431
- }
432
- if (e.key === "Enter") {
433
- e.preventDefault()
434
- save()
435
- }
436
- }
437
- },
438
- pointerdown: (e: PointerEvent, type: Types) => {
439
- const focusTargetClass = `#${props.id ?? fallbackId} .color-picker--${type}-handle`
440
- const focusTarget = document.querySelector(focusTargetClass)
441
- // allows enter to work when the user drags any slider as the even will be captured by the keydown listener
442
- if (focusTarget instanceof HTMLElement) focusTarget.focus()
443
-
444
- if (dragging) return
445
- e.preventDefault()
446
- elDragging.value = type
447
- dragging = true
448
- document.addEventListener("pointermove", slider.pointermove)
449
- document.addEventListener("pointerup", slider.pointerup)
450
- moveHandle(e, elDragging.value)
451
- },
452
- pointerleave: (e: PointerEvent) => {
453
- if (dragging) {
454
- e.preventDefault()
455
- }
456
- },
457
- pointermove: (e: PointerEvent) => {
458
- e.preventDefault()
459
- moveHandle(e, elDragging.value)
460
- },
461
- pointerup: (e: PointerEvent) => {
462
- e.preventDefault()
463
- dragging = false
464
- elDragging.value = ""
465
- document.removeEventListener("pointermove", slider.pointermove)
466
- document.removeEventListener("pointerup", slider.pointerup)
467
- },
468
- }
469
- function updateSliders(_: HsvaColor): void {
470
- if (alphaSliderEl.value) {
471
- // https://colorjs.io/docs/output#get-a-displayable-css-color-value
472
- const color = new Color("hsv", [_.h, _.s, _.v], _.a).to("hsl")
473
- const hsl0 = color.clone()
474
- hsl0.alpha = 0
475
- const hsl1 = color.clone()
476
- hsl1.alpha = 1
477
- updateSlider(alphaSliderEl.value, [hsl0.toString(), hsl1.toString()])
478
- }
479
- updateSlider(hueSliderEl.value!, i => `hsl(${i} 100% 50%)`)
480
- updatePicker(pickerEl.value!, _.h)
358
+ keydown: (e, type) => {
359
+ castType(e.target);
360
+ if (e.target?.getBoundingClientRect) {
361
+ if (["ArrowRight", "ArrowLeft", "ArrowUp", "ArrowDown"].includes(e.key)) {
362
+ e.preventDefault();
363
+ const { x, y, width, height } = e.target.getBoundingClientRect();
364
+ let xDiff = e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : 0;
365
+ let yDiff = e.key === "ArrowUp" ? -1 : e.key === "ArrowDown" ? 1 : 0;
366
+ if (e.shiftKey) {
367
+ xDiff *= 10;
368
+ }
369
+ if (e.shiftKey) {
370
+ yDiff *= 10;
371
+ }
372
+ moveHandle({ clientX: x + width / 2 + xDiff, clientY: y + height / 2 + yDiff }, type);
373
+ }
374
+ if (e.key === "Enter") {
375
+ e.preventDefault();
376
+ save();
377
+ }
378
+ }
379
+ },
380
+ pointerdown: (e, type) => {
381
+ const focusTargetClass = `#${props.id ?? fallbackId} .color-picker--${type}-handle`;
382
+ const focusTarget = document.querySelector(focusTargetClass);
383
+ if (focusTarget instanceof HTMLElement) focusTarget.focus();
384
+ if (dragging) return;
385
+ e.preventDefault();
386
+ elDragging.value = type;
387
+ dragging = true;
388
+ document.addEventListener("pointermove", slider.pointermove);
389
+ document.addEventListener("pointerup", slider.pointerup);
390
+ moveHandle(e, elDragging.value);
391
+ },
392
+ pointerleave: (e) => {
393
+ if (dragging) {
394
+ e.preventDefault();
395
+ }
396
+ },
397
+ pointermove: (e) => {
398
+ e.preventDefault();
399
+ moveHandle(e, elDragging.value);
400
+ },
401
+ pointerup: (e) => {
402
+ e.preventDefault();
403
+ dragging = false;
404
+ elDragging.value = "";
405
+ document.removeEventListener("pointermove", slider.pointermove);
406
+ document.removeEventListener("pointerup", slider.pointerup);
407
+ }
408
+ };
409
+ function updateSliders(_) {
410
+ if (alphaSliderEl.value) {
411
+ const color = new Color("hsv", [_.h, _.s, _.v], _.a).to("hsl");
412
+ const hsl0 = color.clone();
413
+ hsl0.alpha = 0;
414
+ const hsl1 = color.clone();
415
+ hsl1.alpha = 1;
416
+ updateSlider(alphaSliderEl.value, [hsl0.toString(), hsl1.toString()]);
417
+ }
418
+ updateSlider(hueSliderEl.value, (i) => `hsl(${i} 100% 50%)`);
419
+ updatePicker(pickerEl.value, _.h);
481
420
  }
482
-
483
- function updateValueAndPosition(_: HsvaColor): void {
484
- localColor.percent.h = Math.round((_.h / 360) * 10000) / 100
485
- localColor.percent.s = _.s
486
- localColor.percent.v = 100 - _.v
487
- localColor.percent.a =
488
- props.allowAlpha
489
- ? _.a !== undefined
490
- ? _.a * 100
491
- : 1
492
- : 1
493
- localColor.val = { ..._, a: props.allowAlpha ? _.a : 1 }
421
+ function updateValueAndPosition(_) {
422
+ localColor.percent.h = Math.round(_.h / 360 * 1e4) / 100;
423
+ localColor.percent.s = _.s;
424
+ localColor.percent.v = 100 - _.v;
425
+ localColor.percent.a = props.allowAlpha ? _.a !== void 0 ? _.a * 100 : 1 : 1;
426
+ localColor.val = { ..._, a: props.allowAlpha ? _.a : 1 };
494
427
  }
495
-
496
- function convertAndUpdateAll(rgba: RgbaColor) {
497
- const hsva = safeConvertToHsva(rgba, props.allowAlpha)
498
- if (!hsva) return
499
- updateSliders(hsva)
500
- updateValueAndPosition(hsva)
428
+ function convertAndUpdateAll(rgba) {
429
+ const hsva = safeConvertToHsva(rgba, props.allowAlpha);
430
+ if (!hsva) return;
431
+ updateSliders(hsva);
432
+ updateValueAndPosition(hsva);
501
433
  }
502
-
503
- function save(): void {
504
- const rgba = safeConvertToRgba(localColor.val, props.allowAlpha)
505
- if (!rgba) return
506
- // update(localColor.val, { updatePosition: false, updateValue: false })
507
- $value.value = rgba
508
- $tempValue.value = undefined
509
- emits("save", rgba)
434
+ function save() {
435
+ const rgba = safeConvertToRgba(localColor.val, props.allowAlpha);
436
+ if (!rgba) return;
437
+ $value.value = rgba;
438
+ $tempValue.value = void 0;
439
+ emits("save", rgba);
510
440
  }
511
-
512
-
513
- function parseInput(e: Event): void {
514
- const val = (e.target as HTMLInputElement)?.value
515
- const converted = props.customRepresentation?.fromStringToHsva
516
- ? props.customRepresentation.fromStringToHsva(val)
517
- : safeConvertToHsva(val, props.allowAlpha)
518
- if (converted) {
519
- updateSliders(converted)
520
- updateValueAndPosition(converted)
521
- }
441
+ function parseInput(e) {
442
+ const val = e.target?.value;
443
+ const converted = props.customRepresentation?.fromStringToHsva ? props.customRepresentation.fromStringToHsva(val) : safeConvertToHsva(val, props.allowAlpha);
444
+ if (converted) {
445
+ updateSliders(converted);
446
+ updateValueAndPosition(converted);
447
+ }
522
448
  }
523
-
524
-
525
- let disableUpdateTempValue = false
526
-
449
+ let disableUpdateTempValue = false;
527
450
  onMounted(() => {
528
- convertAndUpdateAll($value.value)
529
- if ($tempValue.value !== undefined) {
530
- convertAndUpdateAll($tempValue.value)
531
- }
532
-
533
- const handle = document.querySelector(`#${props.id ?? fallbackId} .color-picker--all-handle`)
534
- if (handle instanceof HTMLElement) handle.focus()
535
- })
536
-
451
+ convertAndUpdateAll($value.value);
452
+ if ($tempValue.value !== void 0) {
453
+ convertAndUpdateAll($tempValue.value);
454
+ }
455
+ const handle = document.querySelector(`#${props.id ?? fallbackId} .color-picker--all-handle`);
456
+ if (handle instanceof HTMLElement) handle.focus();
457
+ });
537
458
  watch($value, () => {
538
- convertAndUpdateAll($value.value)
539
- })
540
-
459
+ convertAndUpdateAll($value.value);
460
+ });
541
461
  watch($tempValue, () => {
542
- if ($tempValue.value !== undefined) {
543
- disableUpdateTempValue = true
544
- convertAndUpdateAll($tempValue.value)
545
- setTimeout(() => { disableUpdateTempValue = false }, 0)
546
- }
547
- })
548
-
462
+ if ($tempValue.value !== void 0) {
463
+ disableUpdateTempValue = true;
464
+ convertAndUpdateAll($tempValue.value);
465
+ setTimeout(() => {
466
+ disableUpdateTempValue = false;
467
+ }, 0);
468
+ }
469
+ });
549
470
  watch(localColor, () => {
550
- updateSliders(localColor.val)
551
- localInputString.value = localColorString.value
552
- if (disableUpdateTempValue) return
553
- const rgba = safeConvertToRgba(localColor.val, props.allowAlpha)
554
- if (!rgba) return
555
- $tempValue.value = rgba
556
- })
557
-
558
- const invertColors = computed(() => !!(localColor.percent.v < 50 || (localColor.val.a === undefined || localColor.val.a < 0.5)))
471
+ updateSliders(localColor.val);
472
+ localInputString.value = localColorString.value;
473
+ if (disableUpdateTempValue) return;
474
+ const rgba = safeConvertToRgba(localColor.val, props.allowAlpha);
475
+ if (!rgba) return;
476
+ $tempValue.value = rgba;
477
+ });
478
+ const invertColors = computed(() => !!(localColor.percent.v < 50 || (localColor.val.a === void 0 || localColor.val.a < 0.5)));
559
479
  </script>