@witchcraft/ui 0.3.19 → 0.3.21

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 (83) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/assets/animations.css +1 -1
  3. package/dist/runtime/components/Aria/Aria.d.vue.ts +2 -1
  4. package/dist/runtime/components/Aria/Aria.vue.d.ts +2 -1
  5. package/dist/runtime/components/Icon/Icon.d.vue.ts +3 -2
  6. package/dist/runtime/components/Icon/Icon.vue.d.ts +3 -2
  7. package/dist/runtime/components/LibButton/LibButton.d.vue.ts +5 -4
  8. package/dist/runtime/components/LibButton/LibButton.vue.d.ts +5 -4
  9. package/dist/runtime/components/LibCheckbox/LibCheckbox.d.vue.ts +4 -5
  10. package/dist/runtime/components/LibCheckbox/LibCheckbox.vue.d.ts +4 -5
  11. package/dist/runtime/components/LibColorInput/LibColorInput.d.vue.ts +7 -6
  12. package/dist/runtime/components/LibColorInput/LibColorInput.vue.d.ts +7 -6
  13. package/dist/runtime/components/LibColorPicker/LibColorPicker.d.vue.ts +7 -5
  14. package/dist/runtime/components/LibColorPicker/LibColorPicker.vue.d.ts +7 -5
  15. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.d.vue.ts +10 -9
  16. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue.d.ts +10 -9
  17. package/dist/runtime/components/LibDatePicker/LibDatePicker.d.vue.ts +156 -5
  18. package/dist/runtime/components/LibDatePicker/LibDatePicker.vue.d.ts +156 -5
  19. package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.d.vue.ts +154 -6
  20. package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue +8 -4
  21. package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue.d.ts +154 -6
  22. package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.d.vue.ts +7 -5
  23. package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue.d.ts +7 -5
  24. package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.d.vue.ts +7 -6
  25. package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue.d.ts +7 -6
  26. package/dist/runtime/components/LibDebug/LibDebug.d.vue.ts +3 -2
  27. package/dist/runtime/components/LibDebug/LibDebug.vue.d.ts +3 -2
  28. package/dist/runtime/components/LibDevOnly/LibDevOnly.d.vue.ts +3 -2
  29. package/dist/runtime/components/LibDevOnly/LibDevOnly.vue.d.ts +3 -2
  30. package/dist/runtime/components/LibFileInput/LibFileInput.d.vue.ts +20 -19
  31. package/dist/runtime/components/LibFileInput/LibFileInput.vue.d.ts +20 -19
  32. package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.d.vue.ts +106 -15
  33. package/dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue.d.ts +106 -15
  34. package/dist/runtime/components/LibLabel/LibLabel.d.vue.ts +3 -2
  35. package/dist/runtime/components/LibLabel/LibLabel.vue.d.ts +3 -2
  36. package/dist/runtime/components/LibMultiValues/LibMultiValues.d.vue.ts +15 -10
  37. package/dist/runtime/components/LibMultiValues/LibMultiValues.vue.d.ts +15 -10
  38. package/dist/runtime/components/LibNotifications/LibNotification.d.vue.ts +14 -5
  39. package/dist/runtime/components/LibNotifications/LibNotification.vue +2 -2
  40. package/dist/runtime/components/LibNotifications/LibNotification.vue.d.ts +14 -5
  41. package/dist/runtime/components/LibNotifications/LibNotificationTestMessageComponent.d.vue.ts +2 -1
  42. package/dist/runtime/components/LibNotifications/LibNotificationTestMessageComponent.vue.d.ts +2 -1
  43. package/dist/runtime/components/LibNotifications/LibNotifications.d.vue.ts +3 -1
  44. package/dist/runtime/components/LibNotifications/LibNotifications.vue +34 -17
  45. package/dist/runtime/components/LibNotifications/LibNotifications.vue.d.ts +3 -1
  46. package/dist/runtime/components/LibNotifications/calculateNotificationProgress.d.ts +2 -0
  47. package/dist/runtime/components/LibNotifications/calculateNotificationProgress.js +4 -0
  48. package/dist/runtime/components/LibPagination/LibPagination.d.vue.ts +51 -50
  49. package/dist/runtime/components/LibPagination/LibPagination.vue.d.ts +51 -50
  50. package/dist/runtime/components/LibPalette/LibPalette.d.vue.ts +3 -2
  51. package/dist/runtime/components/LibPalette/LibPalette.vue.d.ts +3 -2
  52. package/dist/runtime/components/LibPopup/LibPopup.d.vue.ts +9 -3
  53. package/dist/runtime/components/LibPopup/LibPopup.vue.d.ts +9 -3
  54. package/dist/runtime/components/LibProgressBar/LibProgressBar.d.vue.ts +3 -2
  55. package/dist/runtime/components/LibProgressBar/LibProgressBar.vue.d.ts +3 -2
  56. package/dist/runtime/components/LibRecorder/LibRecorder.d.vue.ts +3 -2
  57. package/dist/runtime/components/LibRecorder/LibRecorder.vue.d.ts +3 -2
  58. package/dist/runtime/components/LibRoot/LibRoot.d.vue.ts +5 -4
  59. package/dist/runtime/components/LibRoot/LibRoot.vue.d.ts +5 -4
  60. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.d.vue.ts +18 -13
  61. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue +1 -1
  62. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue.d.ts +18 -13
  63. package/dist/runtime/components/LibSuggestions/LibSuggestions.d.vue.ts +23 -18
  64. package/dist/runtime/components/LibSuggestions/LibSuggestions.vue.d.ts +23 -18
  65. package/dist/runtime/components/LibTable/LibTable.d.vue.ts +34 -13
  66. package/dist/runtime/components/LibTable/LibTable.vue.d.ts +34 -13
  67. package/dist/runtime/components/Template/NAME.d.vue.ts +3 -2
  68. package/dist/runtime/components/Template/NAME.vue.d.ts +3 -2
  69. package/dist/runtime/components/TestControls/TestControls.d.vue.ts +2 -1
  70. package/dist/runtime/components/TestControls/TestControls.vue.d.ts +2 -1
  71. package/dist/runtime/composables/useTimeConditionally.d.ts +16 -0
  72. package/dist/runtime/composables/useTimeConditionally.js +27 -0
  73. package/package.json +50 -50
  74. package/src/runtime/assets/animations.css +52 -5
  75. package/src/runtime/components/LibCheckbox/LibCheckbox.vue +3 -1
  76. package/src/runtime/components/LibDatePicker/LibRangeDatePicker.vue +8 -4
  77. package/src/runtime/components/LibFileInput/LibFileInput.vue +13 -4
  78. package/src/runtime/components/LibInputDeprecated/LibInputDeprecated.vue +6 -1
  79. package/src/runtime/components/LibNotifications/LibNotification.vue +2 -2
  80. package/src/runtime/components/LibNotifications/LibNotifications.vue +35 -18
  81. package/src/runtime/components/LibNotifications/calculateNotificationProgress.ts +8 -0
  82. package/src/runtime/components/LibSimpleInput/LibSimpleInput.vue +2 -0
  83. package/src/runtime/composables/useTimeConditionally.ts +51 -0
@@ -1,5 +1,6 @@
1
1
  type __VLS_Props = {
2
2
  showOutline: boolean;
3
3
  };
4
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
5
6
  export default _default;
@@ -0,0 +1,16 @@
1
+ import { type Ref } from "vue";
2
+ /**
3
+ * Returns a ref with the current time if the given value ref is true or it's an array with 1 or more items.. It will update the time every 50ms (configurable) if so (within a requestAnimationFrame).
4
+ *
5
+ * When the value is anything else it will clear the interval and set the time to undefined.
6
+ *
7
+ * Useful for use with a progress bar.
8
+ *
9
+ * Updating the time all the time is expensive and not idea. This way we only set the interval if we really need it.
10
+ */
11
+ export declare function useTimeConditionally(val: Ref<any[] | boolean | any>, { refreshInterval }?: {
12
+ refreshInterval?: number;
13
+ }): {
14
+ time: Ref<undefined | number>;
15
+ refresh: () => void;
16
+ };
@@ -0,0 +1,27 @@
1
+ import { ref, watch } from "vue";
2
+ export function useTimeConditionally(val, {
3
+ refreshInterval = 50
4
+ } = {}) {
5
+ const time = ref(void 0);
6
+ let interval;
7
+ function refresh(v = val.value) {
8
+ if (v === true || Array.isArray(v) && v.length > 0) {
9
+ if (interval !== void 0) return;
10
+ time.value = Date.now();
11
+ interval = setInterval(() => {
12
+ requestAnimationFrame(() => {
13
+ time.value = Date.now();
14
+ });
15
+ }, refreshInterval);
16
+ } else {
17
+ if (interval === void 0) return;
18
+ clearInterval(interval);
19
+ interval = void 0;
20
+ }
21
+ }
22
+ watch(val, (val2) => {
23
+ refresh(val2);
24
+ });
25
+ refresh();
26
+ return { time, refresh };
27
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@witchcraft/ui",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "Vue component library.",
5
5
  "type": "module",
6
6
  "main": "./dist/runtime/main.lib.js",
@@ -49,9 +49,9 @@
49
49
  "failOnWarn": false
50
50
  },
51
51
  "peerDependencies": {
52
- "tailwindcss": "^4.1.12",
53
- "unplugin-icons": "^22.2.0",
54
- "vue": "^3.5.20"
52
+ "tailwindcss": "^4.1.18",
53
+ "unplugin-icons": "^22.5.0",
54
+ "vue": "^3.5.27"
55
55
  },
56
56
  "peerDependenciesMeta": {
57
57
  "tailwindcss": {
@@ -62,82 +62,82 @@
62
62
  }
63
63
  },
64
64
  "dependencies": {
65
- "@alanscodelog/utils": "^6.0.1",
66
- "@iconify/json": "^2.2.379",
67
- "@nuxt/kit": "^4.0.3",
68
- "@nuxt/schema": "^4.0.3",
65
+ "@alanscodelog/utils": "^6.0.2",
66
+ "@iconify/json": "^2.2.437",
67
+ "@nuxt/kit": "^4.3.1",
68
+ "@nuxt/schema": "^4.3.1",
69
69
  "@nuxt/types": "^2.18.1",
70
- "@tailwindcss/vite": "^4.1.12",
70
+ "@tailwindcss/vite": "^4.1.18",
71
71
  "@witchcraft/nuxt-utils": "^0.3.6",
72
72
  "colord": "^2.9.3",
73
73
  "colorjs.io": "0.6.0-alpha.1",
74
74
  "defu": "^6.1.4",
75
75
  "fast-glob": "^3.3.3",
76
76
  "metamorphosis": "^0.6.1",
77
- "reka-ui": "^2.5.0",
78
- "tailwind-merge": "^3.3.1",
79
- "unplugin-icons": "^22.2.0",
77
+ "reka-ui": "^2.8.0",
78
+ "tailwind-merge": "^3.4.0",
79
+ "unplugin-icons": "^22.5.0",
80
80
  "unplugin-vue-components": "^28.8.0",
81
81
  "vue-component-type-helpers": "^2.2.12"
82
82
  },
83
83
  "devDependencies": {
84
84
  "@alanscodelog/commitlint-config": "^3.1.2",
85
- "@alanscodelog/eslint-config": "^6.3.0",
86
- "@alanscodelog/semantic-release-config": "^6.0.0",
85
+ "@alanscodelog/eslint-config": "^6.3.1",
86
+ "@alanscodelog/semantic-release-config": "^6.0.2",
87
87
  "@alanscodelog/tsconfigs": "^6.2.0",
88
- "@alanscodelog/vite-config": "^0.0.6",
88
+ "@alanscodelog/vite-config": "^0.0.7",
89
89
  "@chromatic-com/storybook": "^3.2.7",
90
- "@commitlint/cli": "^19.8.1",
91
- "@internationalized/date": "^3.9.0",
92
- "@faker-js/faker": "^10.0.0",
93
- "@nuxt/eslint-config": "^1.9.0",
90
+ "@commitlint/cli": "^20.4.1",
91
+ "@internationalized/date": "^3.11.0",
92
+ "@faker-js/faker": "^10.3.0",
93
+ "@nuxt/eslint-config": "^1.14.0",
94
94
  "@nuxt/module-builder": "^1.0.2",
95
95
  "@nuxtjs/i18n": "^9.5.6",
96
- "@playwright/test": "=1.54.0",
97
- "@rollup/plugin-node-resolve": "^16.0.1",
98
- "@storybook/addon-a11y": "^8.6.14",
99
- "@storybook/addon-actions": "^8.6.14",
96
+ "@playwright/test": "^1.54.0",
97
+ "@rollup/plugin-node-resolve": "^16.0.3",
98
+ "@storybook/addon-a11y": "^8.6.15",
99
+ "@storybook/addon-actions": "^8.6.15",
100
100
  "@storybook/addon-essentials": "^8.6.14",
101
101
  "@storybook/addon-interactions": "^8.6.14",
102
- "@storybook/addon-links": "^8.6.14",
102
+ "@storybook/addon-links": "^8.6.15",
103
103
  "@storybook/addon-storysource": "^8.6.14",
104
104
  "@storybook/blocks": "^8.6.14",
105
105
  "@storybook/manager-api": "^8.6.14",
106
- "@storybook/test": "^8.6.14",
106
+ "@storybook/test": "^8.6.15",
107
107
  "@storybook/test-runner": "^0.22.1",
108
- "@storybook/vue3": "^8.6.14",
109
- "@storybook/vue3-vite": "^8.6.14",
110
- "@tanstack/vue-virtual": "^3.13.0",
111
- "@tailwindcss/cli": "^4.1.12",
112
- "@tailwindcss/postcss": "^4.1.12",
113
- "@types/node": "^24.3.0",
114
- "@vitejs/plugin-vue": "^6.0.1",
115
- "@vue/runtime-core": "^3.5.20",
116
- "@vue/runtime-dom": "^3.5.20",
117
- "@vueuse/components": "^13.8.0",
118
- "@vueuse/core": "^13.8.0",
119
- "autoprefixer": "^10.4.21",
108
+ "@storybook/vue3": "^8.6.15",
109
+ "@storybook/vue3-vite": "^8.6.15",
110
+ "@tanstack/vue-virtual": "^3.13.18",
111
+ "@tailwindcss/cli": "^4.1.18",
112
+ "@tailwindcss/postcss": "^4.1.18",
113
+ "@types/node": "^24.10.12",
114
+ "@vitejs/plugin-vue": "^6.0.4",
115
+ "@vue/runtime-core": "^3.5.27",
116
+ "@vue/runtime-dom": "^3.5.27",
117
+ "@vueuse/components": "^13.9.0",
118
+ "@vueuse/core": "^13.9.0",
119
+ "autoprefixer": "^10.4.24",
120
120
  "concurrently": "^9.2.1",
121
- "eslint": "^9.34.0",
121
+ "eslint": "^9.39.2",
122
122
  "http-server": "^14.1.1",
123
123
  "husky": "^9.1.7",
124
124
  "indexit": "2.1.0-beta.3",
125
125
  "madge": "^7.0.0",
126
- "nuxt": "^4.2.1",
127
- "playwright": "=1.54.0",
128
- "playwright-core": "=1.54.0",
129
- "semantic-release": "^24.2.7",
130
- "storybook": "^8.6.14",
126
+ "nuxt": "^4.3.1",
127
+ "playwright": "^1.54.0",
128
+ "playwright-core": "^1.54.0",
129
+ "semantic-release": "^24.2.9",
130
+ "storybook": "^8.6.15",
131
131
  "storybook-dark-mode": "^4.0.2",
132
- "tailwindcss": "^4.1.12",
132
+ "tailwindcss": "^4.1.18",
133
133
  "ts-node": "^10.9.2",
134
- "typescript": "^5.9.2",
134
+ "typescript": "^5.9.3",
135
135
  "unbuild": "^3.6.1",
136
- "vite": "^7.1.3",
137
- "vite-tsconfig-paths": "^5.1.4",
138
- "vue": "^3.5.20",
139
- "vue-tsc": "3.0.6",
140
- "wait-on": "^8.0.4"
136
+ "vite": "^7.3.1",
137
+ "vite-tsconfig-paths": "^6.1.0",
138
+ "vue": "^3.5.27",
139
+ "vue-tsc": "3.2.4",
140
+ "wait-on": "^8.0.5"
141
141
  },
142
142
  "author": "Alan <alanscodelog@gmail.com>",
143
143
  "repository": "https://github.com/witchcraftjs/ui",
@@ -1,5 +1,15 @@
1
+ @utility animate-from-* {
2
+ --animate-from: --value([length, percentage]);
3
+ --animate-from: calc(var(--spacing) * --value(integer));
4
+ }
5
+
6
+ @utility -animate-from-* {
7
+ --animate-from: --value([length, percentage]);
8
+ --animate-from: calc(var(--spacing) * -1 * --value(integer));
9
+ }
10
+
1
11
  @theme {
2
- --animate-blinkInf: blink 1s linear-infinite;
12
+ --animate-blinkInf: blink 1s linear infinite;
3
13
  @keyframes blink {
4
14
  0% {
5
15
  opacity: 0;
@@ -18,7 +28,7 @@
18
28
  }
19
29
  }
20
30
 
21
- --animate-slideBgInf: slide-bg 10s linear-infinite;
31
+ --animate-slideBgInf: slide-bg 10s ease-in-out linear-infinite;
22
32
  @keyframes slide {
23
33
  0% {
24
34
  background-position:0%;
@@ -38,10 +48,10 @@
38
48
  }
39
49
  }
40
50
 
41
- --animate-slideIn: slideIn 500ms cubic-bezier(0.16, 1, 0.3, 1);
42
- @keyframes slideIn {
51
+ --animate-slideInLeft: slideInLeft 500ms cubic-bezier(0.16, 1, 0.3, 1);
52
+ @keyframes slideInLeft {
43
53
  from {
44
- transform: translateX(100%);
54
+ transform: translateX(var(--animate-from, 100%));
45
55
  opacity: 0;
46
56
  }
47
57
  to {
@@ -50,6 +60,43 @@
50
60
  }
51
61
  }
52
62
 
63
+ --animate-slideInRight: slideInLeft 500ms cubic-bezier(0.16, 1, 0.3, 1);
64
+ @keyframes slideInRight {
65
+ from {
66
+ transform: translateX(var(--animate-from, -100%));
67
+ opacity: 0;
68
+ }
69
+ to {
70
+ transform: translateX(0);
71
+ opacity: 1;
72
+ }
73
+ }
74
+
75
+ --animate-slideInUp: slideInUp 500ms cubic-bezier(0.16, 1, 0.3, 1);
76
+ @keyframes slideInUp {
77
+ from {
78
+ transform: translateY(var(--animate-from, 100%));
79
+ opacity: 0;
80
+ }
81
+ to {
82
+ transform: translateY(0);
83
+ opacity: 1;
84
+ }
85
+ }
86
+
87
+ --animate-slideInDown: slideInDown 500ms cubic-bezier(0.16, 1, 0.3, 1);
88
+ @keyframes slideInDown {
89
+ from {
90
+ transform: translateY(var(--animate-from, -100%));
91
+ opacity: 0;
92
+ }
93
+ to {
94
+ transform: translateY(0);
95
+ opacity: 1;
96
+ }
97
+ }
98
+
99
+
53
100
  --animate-overlayShow: overlayShow 500ms cubic-bezier(0.16, 1, 0.3, 1);
54
101
  @keyframes overlayShow {
55
102
  from {
@@ -121,8 +121,10 @@ interface Props
121
121
  Partial<Omit<
122
122
  InputHTMLAttributes,
123
123
  "class" | "readonly" | "disabled" | "onSumbit"
124
+ // https://github.com/vuejs/core/pull/14237
125
+ | "autocomplete"
124
126
  > & TailwindClassProp>,
125
- /** @vue-ignore */
127
+ // /** @vue-ignore */
126
128
  WrapperTypes,
127
129
  RealProps
128
130
  {}
@@ -237,10 +237,14 @@ const locale = useInjectedLocale().timeLocale
237
237
  dark:border-neutral-700
238
238
  shadow-lg
239
239
  will-change-[transform,opacity]
240
- data-[state=open]:data-[side=top]:animate-slideDownAndFade
241
- data-[state=open]:data-[side=right]:animate-slideLeftAndFade
242
- data-[state=open]:data-[side=bottom]:animate-slideUpAndFade
243
- data-[state=open]:data-[side=left]:animate-slideRightAndFade
240
+ data-[side=top]:animate-from-3
241
+ data-[side=left]:animate-from-3
242
+ data-[side=right]:-animate-from-3
243
+ data-[side=bottom]:-animate-from-3
244
+ data-[state=open]:data-[side=top]:animate-slideInUp
245
+ data-[state=open]:data-[side=right]:animate-slideInRight
246
+ data-[state=open]:data-[side=bottom]:animate-slideInDown
247
+ data-[state=open]:data-[side=left]:animate-slideInLeft
244
248
  text-fg
245
249
  dark:text-neutral-200
246
250
  "
@@ -355,9 +355,13 @@ defineExpose({
355
355
  export default { name: "LibFileInput" }
356
356
 
357
357
  type WrapperTypes
358
- = & WrapperProps<"input", InputHTMLAttributes>
359
- & WrapperProps<"wrapper", HTMLAttributes>
360
- & WrapperProps<"previews", HTMLAttributes>
358
+ = & WrapperProps<
359
+ "input",
360
+ // https://github.com/vuejs/core/pull/14237
361
+ Omit<InputHTMLAttributes, "autocomplete">
362
+ >
363
+ & WrapperProps<"wrapper", HTMLAttributes>
364
+ & WrapperProps<"previews", HTMLAttributes>
361
365
 
362
366
  type RealProps
363
367
  = & LinkableByIdProps
@@ -375,7 +379,12 @@ type RealProps
375
379
  interface Props
376
380
  extends
377
381
  /** @vue-ignore */
378
- Partial<Omit<InputHTMLAttributes, "class" | "multiple" | "formats" | "compact"> & TailwindClassProp>,
382
+ Partial<Omit<
383
+ InputHTMLAttributes,
384
+ "class" | "multiple" | "formats" | "compact"
385
+ // https://github.com/vuejs/core/pull/14237
386
+ | "autocomplete"
387
+ > & TailwindClassProp>,
379
388
  /** @vue-ignore */
380
389
  Partial<WrapperTypes>,
381
390
  RealProps { }
@@ -407,7 +407,12 @@ type RealProps
407
407
  interface Props
408
408
  extends
409
409
  /** @vue-ignore */
410
- Partial<Omit<InputHTMLAttributes, "class" | "readonly" | "disabled" | "onSubmit"> & TailwindClassProp>,
410
+ Partial<Omit<
411
+ InputHTMLAttributes,
412
+ "class" | "readonly" | "disabled" | "onSubmit"
413
+ // https://github.com/vuejs/core/pull/14237
414
+ | "autocomplete"
415
+ > & TailwindClassProp>,
411
416
  /** @vue-ignore */
412
417
  Partial<WrapperTypes>,
413
418
  RealProps { }
@@ -3,7 +3,6 @@
3
3
  v-if="notification"
4
4
  :class="twMerge(`
5
5
  notification
6
- max-w-700px
7
6
  bg-neutral-50
8
7
  dark:bg-neutral-900
9
8
  text-fg
@@ -63,7 +62,7 @@
63
62
  </div>
64
63
  </slot>
65
64
  <div class="notification--spacer flex-1"/>
66
- <div class="actions flex">
65
+ <div class="notification--actions flex">
67
66
  <LibButton
68
67
  :border="false"
69
68
  class="
@@ -221,6 +220,7 @@ onMounted(() => {
221
220
  if (props.notification.isPaused) return
222
221
  emit("pause", props.notification)
223
222
  } else {
223
+ if (!props.notification.isPaused) return
224
224
  emit("resume", props.notification)
225
225
  }
226
226
  }, { signal: mousedownAbortController.signal })
@@ -5,17 +5,16 @@
5
5
  tag="div"
6
6
  :class="twMerge(`
7
7
  notifications
8
- [--notification-width:300px]
8
+ [--notification-width:calc(100dvw-var(--spacing)*4)]
9
+ sm:[--notification-width:300px]
9
10
  fixed
10
11
  top-0
11
12
  z-50
12
13
  right-[calc(var(--notification-width)*-1)]
13
14
  w-[calc(var(--spacing)*2+var(--notification-width)*2)]
14
- [&_.notification]:w-[var(--notification-width)]
15
15
  max-h-[100dvh]
16
16
  flex
17
17
  flex-col
18
- [&_.notification]:shrink-0
19
18
  gap-1
20
19
  list-none
21
20
  outline-none
@@ -29,7 +28,16 @@
29
28
  :handler="handler"
30
29
  tabindex="0"
31
30
  :notification="notification"
32
- class="overflow-hidden my-2 max-h-[25dvh] min-h-[300px]"
31
+ class="
32
+ overflow-hidden
33
+ my-2
34
+ max-h-[300px]
35
+ w-[var(--notification-width)]
36
+ shrink-0
37
+ max-sm:[&_.notification--button]:p-2
38
+ max-sm:[&_.notification--button]:py-1
39
+ max-sm:[&_.notification--header]:text-lg
40
+ "
33
41
  v-for="notification of notifications"
34
42
  :key="notification.id"
35
43
  @pause="handler.pause(notification)"
@@ -46,7 +54,7 @@
46
54
  -mx-[calc(var(--spacing)*2+2px)]
47
55
  rounded-none
48
56
  "
49
- :progress="100 - (((notification.isPaused ? (notification._timer.elapsedBeforePause): (notification._timer.elapsedBeforePause + (time - notification.startTime))) / notification.timeout) * 100)"
57
+ :progress="calculateNotificationProgress(notification, time!)"
50
58
  />
51
59
  </template>
52
60
  </lib-notification>
@@ -67,19 +75,27 @@
67
75
  <AlertDialogContent
68
76
  class="
69
77
  data-[state=open]:animate-contentShow
78
+ max-sm:data-[state=open]:animate-slideInUp
70
79
  fixed
71
80
  flex
81
+ max-h-[80dvh]
72
82
  top-[50%]
73
83
  left-[50%]
74
- translate-x-[-50%]
75
- translate-y-[-50%]
76
- max-h-[80dvh]
84
+ sm:translate-x-[-50%]
85
+ sm:translate-y-[-50%]
77
86
  max-w-[700px]
87
+ max-sm:bottom-2
88
+ max-sm:top-[unset]
89
+ max-sm:left-2
90
+ max-sm:right-2
91
+ max-sm:w-[calc(100%-var(--spacing)*4)]
78
92
  z-100
79
93
  "
80
94
  >
81
95
  <lib-notification
82
96
  class="
97
+ w-full
98
+ sm:max-w-[700px]
83
99
  max-w-full
84
100
  max-h-full
85
101
  top-notification
@@ -120,11 +136,13 @@ import {
120
136
  AlertDialogRoot,
121
137
  AlertDialogTitle
122
138
  } from "reka-ui"
123
- import { computed, ref } from "vue"
139
+ import { computed } from "vue"
124
140
 
141
+ import { calculateNotificationProgress } from "./calculateNotificationProgress.js"
125
142
  import LibNotification from "./LibNotification.vue"
126
143
 
127
144
  import { useNotificationHandler } from "../../composables/useNotificationHandler.js"
145
+ import { useTimeConditionally } from "../../composables/useTimeConditionally.js"
128
146
  import { NotificationHandler } from "../../helpers/NotificationHandler.js"
129
147
  import { twMerge } from "../../utils/twMerge.js"
130
148
  import LibProgressBar from "../LibProgressBar/LibProgressBar.vue"
@@ -137,18 +155,16 @@ defineOptions({
137
155
 
138
156
  const props = defineProps<Props>()
139
157
 
158
+ const handler = props.handler ?? useNotificationHandler()
159
+
140
160
  const topNotifications = computed(() => handler.queue.filter(entry => entry.requiresAction).reverse())
141
161
  const notifications = computed(() => handler.queue.filter(entry => !entry.requiresAction))
142
162
 
143
- const time = ref(Date.now())
144
- setInterval(() => {
145
- requestAnimationFrame(() => {
146
- time.value = Date.now()
147
- })
148
- }, 50)
149
-
163
+ const fetchTime = computed(() => {
164
+ return notifications.value.filter(entry => entry.timeout !== undefined && !entry.isPaused).length > 0
165
+ })
150
166
 
151
- const handler = props.handler ?? useNotificationHandler()
167
+ const { time } = useTimeConditionally(fetchTime, { refreshInterval: props.progressUpdateInterval })
152
168
  </script>
153
169
 
154
170
  <script lang="ts">
@@ -157,8 +173,9 @@ import type { HTMLAttributes } from "vue"
157
173
  type RealProps
158
174
  = & LinkableByIdProps
159
175
  & {
160
- /** If not provided, uses the global handler (this requires useNotificationHandler be called and configured). */
176
+ /** If not provided, uses the global handler (this requires useNotificationHandler be called and configured). */
161
177
  handler?: NotificationHandler
178
+ progressUpdateInterval?: number
162
179
  }
163
180
 
164
181
  interface Props
@@ -0,0 +1,8 @@
1
+ import type { NotificationEntry } from "../../helpers/NotificationHandler.js"
2
+
3
+ export function calculateNotificationProgress(notification: NotificationEntry, time: number) {
4
+ if (notification.timeout === undefined) return 0
5
+
6
+ return 100 - (((notification.isPaused ? (notification._timer.elapsedBeforePause) : (notification._timer.elapsedBeforePause + (time - notification.startTime))) / notification.timeout) * 100)
7
+ }
8
+
@@ -147,6 +147,8 @@ interface Props
147
147
  | "disabled"
148
148
  | "onSubmit"
149
149
  | "onInput"
150
+ // https://github.com/vuejs/core/pull/14237
151
+ | "autocomplete"
150
152
  > & TailwindClassProp>,
151
153
  RealProps
152
154
  {}
@@ -0,0 +1,51 @@
1
+ import { type Ref, ref, watch } from "vue"
2
+
3
+ /**
4
+ * Returns a ref with the current time if the given value ref is true or it's an array with 1 or more items.. It will update the time every 50ms (configurable) if so (within a requestAnimationFrame).
5
+ *
6
+ * When the value is anything else it will clear the interval and set the time to undefined.
7
+ *
8
+ * Useful for use with a progress bar.
9
+ *
10
+ * Updating the time all the time is expensive and not idea. This way we only set the interval if we really need it.
11
+ */
12
+ export function useTimeConditionally(
13
+ val: Ref<any[] | boolean | any>,
14
+ {
15
+ refreshInterval = 50
16
+ }: {
17
+ refreshInterval?: number
18
+ } = {}
19
+ ): {
20
+ time: Ref<undefined | number>
21
+ refresh: () => void
22
+ } {
23
+ const time = ref<undefined | number>(undefined)
24
+
25
+ let interval: ReturnType<typeof setInterval> | undefined
26
+ function refresh(
27
+ /** The value to use for the check. Do not pass unless you know what you're doing. */
28
+ v = val.value
29
+ ) {
30
+ if (v === true || (Array.isArray(v) && v.length > 0)) {
31
+ if (interval !== undefined) return
32
+ time.value = Date.now()
33
+ interval = setInterval(() => {
34
+ requestAnimationFrame(() => {
35
+ time.value = Date.now()
36
+ })
37
+ }, refreshInterval)
38
+ } else {
39
+ if (interval === undefined) return
40
+ clearInterval(interval)
41
+ interval = undefined
42
+ }
43
+ }
44
+ watch(val, val => {
45
+ refresh(val)
46
+ })
47
+
48
+ refresh()
49
+
50
+ return { time, refresh }
51
+ }