@witchcraft/ui 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +18 -28
  2. package/dist/module.d.mts +3 -1
  3. package/dist/module.d.ts +3 -1
  4. package/dist/module.json +2 -2
  5. package/dist/module.mjs +20 -11
  6. package/dist/runtime/assets/base.css +1 -1
  7. package/dist/runtime/assets/locales/en.json +2 -2
  8. package/dist/runtime/assets/tailwind.css +1 -1
  9. package/dist/runtime/assets/utils.css +1 -0
  10. package/dist/runtime/build/WitchcraftUiResolver.js +1 -1
  11. package/dist/runtime/components/Icon/Icon.vue +10 -5
  12. package/dist/runtime/components/LibButton/LibButton.vue +41 -46
  13. package/dist/runtime/components/LibCheckbox/LibCheckbox.vue +7 -3
  14. package/dist/runtime/components/LibColorInput/LibColorInput.vue +111 -36
  15. package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.d.ts +2 -0
  16. package/dist/runtime/components/LibColorPicker/LibColorPicker.stories.js +26 -9
  17. package/dist/runtime/components/LibColorPicker/LibColorPicker.vue +242 -131
  18. package/dist/runtime/components/LibColorPicker/utils/safeConvertToHsva.d.ts +2 -0
  19. package/dist/runtime/components/LibColorPicker/utils/safeConvertToHsva.js +18 -0
  20. package/dist/runtime/components/LibColorPicker/utils/safeConvertToRgba.d.ts +2 -0
  21. package/dist/runtime/components/LibColorPicker/utils/safeConvertToRgba.js +17 -0
  22. package/dist/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.d.ts +2 -0
  23. package/dist/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.js +8 -0
  24. package/dist/runtime/components/LibColorPicker/utils/truncate.d.ts +1 -0
  25. package/dist/runtime/components/LibColorPicker/utils/truncate.js +5 -0
  26. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.js +1 -1
  27. package/dist/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +11 -8
  28. package/dist/runtime/components/LibDatePicker/LibDatePicker.vue +4 -17
  29. package/dist/runtime/components/LibDatePicker/LibRangeDatePicker.vue +192 -131
  30. package/dist/runtime/components/LibDatePicker/LibSingleDatePicker.vue +183 -115
  31. package/dist/runtime/components/LibDatePicker/LibTimeZonePicker.vue +3 -3
  32. package/dist/runtime/components/LibDebug/LibDebug.vue +15 -5
  33. package/dist/runtime/components/LibDevOnly/LibDevOnly.vue +1 -3
  34. package/dist/runtime/components/LibFileInput/LibFileInput.vue +54 -28
  35. package/dist/runtime/components/{LibInput/LibInput.stories.d.ts → LibInputDeprecated/LibInputDeprecated.stories.d.ts} +6 -6
  36. package/dist/runtime/components/{LibInput/LibInput.stories.js → LibInputDeprecated/LibInputDeprecated.stories.js} +64 -19
  37. package/{src/runtime/components/LibInput/LibInput.vue → dist/runtime/components/LibInputDeprecated/LibInputDeprecated.vue} +40 -33
  38. package/dist/runtime/components/LibLabel/LibLabel.vue +2 -2
  39. package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.d.ts +1 -1
  40. package/dist/runtime/components/LibMultiValues/LibMultiValues.stories.js +5 -4
  41. package/dist/runtime/components/LibMultiValues/LibMultiValues.vue +11 -12
  42. package/dist/runtime/components/LibNotifications/LibNotification.vue +19 -10
  43. package/dist/runtime/components/LibNotifications/LibNotifications.stories.js +2 -2
  44. package/dist/runtime/components/LibNotifications/LibNotifications.vue +20 -11
  45. package/dist/runtime/components/LibPagination/LibPagination.stories.js +2 -2
  46. package/dist/runtime/components/LibPagination/LibPagination.vue +19 -19
  47. package/dist/runtime/components/LibPalette/LibPalette.vue +3 -3
  48. package/dist/runtime/components/LibPopup/LibPopup.stories.js +2 -2
  49. package/dist/runtime/components/LibPopup/LibPopup.vue +30 -66
  50. package/dist/runtime/components/LibProgressBar/LibProgressBar.vue +3 -1
  51. package/dist/runtime/components/LibRecorder/LibRecorder.vue +2 -2
  52. package/dist/runtime/components/LibRoot/LibRoot.vue +14 -1
  53. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.stories.js +1 -1
  54. package/dist/runtime/components/LibSimpleInput/LibSimpleInput.vue +5 -7
  55. package/dist/runtime/components/LibSuggestions/LibSuggestions.vue +42 -25
  56. package/dist/runtime/components/LibTable/LibTable.vue +8 -8
  57. package/dist/runtime/components/Scrolling.stories.d.ts +6 -0
  58. package/dist/runtime/components/Scrolling.stories.js +44 -0
  59. package/dist/runtime/components/Template/NAME.vue +1 -1
  60. package/dist/runtime/components/TestControls/TestControls.vue +1 -1
  61. package/dist/runtime/components/index.d.ts +12 -11
  62. package/dist/runtime/components/index.js +12 -11
  63. package/dist/runtime/components/shared/props.d.ts +81 -16
  64. package/dist/runtime/components/shared/storyHelpers/playInput.js +5 -5
  65. package/dist/runtime/components/shared/storyHelpers/playSuggestions.js +15 -11
  66. package/dist/runtime/composables/index.d.ts +5 -0
  67. package/dist/runtime/composables/index.js +5 -0
  68. package/dist/runtime/composables/useDivideAttrs.js +1 -0
  69. package/dist/runtime/composables/useDragWithThreshold.d.ts +71 -0
  70. package/dist/runtime/composables/useDragWithThreshold.js +40 -0
  71. package/dist/runtime/composables/usePreHydrationValue.d.ts +12 -0
  72. package/dist/runtime/composables/usePreHydrationValue.js +15 -0
  73. package/dist/runtime/composables/useSetupI18n.d.ts +2 -0
  74. package/dist/runtime/composables/useSetupI18n.js +5 -1
  75. package/dist/runtime/composables/useSuggestions.d.ts +7 -5
  76. package/dist/runtime/composables/useSuggestions.js +94 -57
  77. package/dist/runtime/directives/vResizableCols.js +3 -1
  78. package/dist/runtime/helpers/NotificationHandler.d.ts +5 -0
  79. package/dist/runtime/helpers/index.d.ts +3 -1
  80. package/dist/runtime/helpers/index.js +3 -1
  81. package/dist/runtime/types/index.d.ts +6 -0
  82. package/dist/runtime/utils/notifyIfError.d.ts +14 -0
  83. package/dist/runtime/utils/notifyIfError.js +29 -0
  84. package/package.json +18 -20
  85. package/src/module.ts +31 -12
  86. package/src/runtime/assets/base.css +10 -1
  87. package/src/runtime/assets/locales/en.json +2 -2
  88. package/src/runtime/assets/tailwind.css +1 -1
  89. package/src/runtime/assets/{style.css → utils.css} +86 -4
  90. package/src/runtime/build/WitchcraftUiResolver.ts +1 -1
  91. package/src/runtime/components/Icon/Icon.vue +10 -5
  92. package/src/runtime/components/LibButton/LibButton.vue +41 -46
  93. package/src/runtime/components/LibCheckbox/LibCheckbox.vue +7 -3
  94. package/src/runtime/components/LibColorInput/LibColorInput.vue +111 -36
  95. package/src/runtime/components/LibColorPicker/LibColorPicker.stories.ts +25 -4
  96. package/src/runtime/components/LibColorPicker/LibColorPicker.vue +242 -131
  97. package/src/runtime/components/LibColorPicker/utils/safeConvertToHsva.ts +25 -0
  98. package/src/runtime/components/LibColorPicker/utils/safeConvertToRgba.ts +23 -0
  99. package/src/runtime/components/LibColorPicker/utils/toLowPrecisionRgbaString.ts +13 -0
  100. package/src/runtime/components/LibColorPicker/utils/truncate.ts +6 -0
  101. package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.stories.ts +1 -1
  102. package/src/runtime/components/LibDarkModeSwitcher/LibDarkModeSwitcher.vue +11 -8
  103. package/src/runtime/components/LibDatePicker/LibDatePicker.vue +4 -17
  104. package/src/runtime/components/LibDatePicker/LibRangeDatePicker.vue +192 -131
  105. package/src/runtime/components/LibDatePicker/LibSingleDatePicker.vue +183 -115
  106. package/src/runtime/components/LibDatePicker/LibTimeZonePicker.vue +3 -3
  107. package/src/runtime/components/LibDebug/LibDebug.vue +15 -5
  108. package/src/runtime/components/LibDevOnly/LibDevOnly.vue +1 -3
  109. package/src/runtime/components/LibFileInput/LibFileInput.vue +54 -28
  110. package/src/runtime/components/{LibInput/LibInput.stories.ts → LibInputDeprecated/LibInputDeprecated.stories.ts} +64 -19
  111. package/{dist/runtime/components/LibInput/LibInput.vue → src/runtime/components/LibInputDeprecated/LibInputDeprecated.vue} +40 -33
  112. package/src/runtime/components/LibLabel/LibLabel.vue +2 -2
  113. package/src/runtime/components/LibMultiValues/LibMultiValues.stories.ts +5 -4
  114. package/src/runtime/components/LibMultiValues/LibMultiValues.vue +11 -12
  115. package/src/runtime/components/LibNotifications/LibNotification.vue +19 -10
  116. package/src/runtime/components/LibNotifications/LibNotifications.stories.ts +2 -2
  117. package/src/runtime/components/LibNotifications/LibNotifications.vue +20 -11
  118. package/src/runtime/components/LibPagination/LibPagination.stories.ts +2 -2
  119. package/src/runtime/components/LibPagination/LibPagination.vue +19 -19
  120. package/src/runtime/components/LibPalette/LibPalette.vue +3 -3
  121. package/src/runtime/components/LibPopup/LibPopup.stories.ts +2 -2
  122. package/src/runtime/components/LibPopup/LibPopup.vue +30 -66
  123. package/src/runtime/components/LibProgressBar/LibProgressBar.vue +3 -1
  124. package/src/runtime/components/LibRecorder/LibRecorder.vue +2 -2
  125. package/src/runtime/components/LibRoot/LibRoot.vue +14 -1
  126. package/src/runtime/components/LibSimpleInput/LibSimpleInput.stories.ts +1 -1
  127. package/src/runtime/components/LibSimpleInput/LibSimpleInput.vue +5 -7
  128. package/src/runtime/components/LibSuggestions/LibSuggestions.vue +42 -25
  129. package/src/runtime/components/LibTable/LibTable.vue +8 -8
  130. package/src/runtime/components/Scrolling.stories.ts +58 -0
  131. package/src/runtime/components/Template/NAME.vue +1 -1
  132. package/src/runtime/components/TestControls/TestControls.vue +1 -1
  133. package/src/runtime/components/index.ts +12 -12
  134. package/src/runtime/components/shared/props.ts +82 -19
  135. package/src/runtime/components/shared/storyHelpers/playInput.ts +6 -5
  136. package/src/runtime/components/shared/storyHelpers/playSuggestions.ts +25 -11
  137. package/src/runtime/composables/index.ts +5 -0
  138. package/src/runtime/composables/useDarkMode.ts +2 -2
  139. package/src/runtime/composables/useDivideAttrs.ts +1 -0
  140. package/src/runtime/composables/useDragWithThreshold.ts +108 -0
  141. package/src/runtime/composables/usePreHydrationValue.ts +30 -0
  142. package/src/runtime/composables/useSetupI18n.ts +8 -2
  143. package/src/runtime/composables/useSuggestions.ts +92 -45
  144. package/src/runtime/directives/vResizableCols.ts +3 -1
  145. package/src/runtime/helpers/NotificationHandler.ts +5 -0
  146. package/src/runtime/helpers/index.ts +3 -1
  147. package/src/runtime/types/index.ts +5 -0
  148. package/src/runtime/utils/notifyIfError.ts +45 -0
  149. package/dist/runtime/assets/style.css +0 -1
  150. package/dist/runtime/helpers/addValue.d.ts +0 -1
  151. package/dist/runtime/helpers/addValue.js +0 -8
  152. package/src/runtime/helpers/addValue.ts +0 -10
  153. /package/dist/runtime/components/{reset.stories.d.ts → Reset.stories.d.ts} +0 -0
  154. /package/dist/runtime/components/{reset.stories.js → Reset.stories.js} +0 -0
  155. /package/src/runtime/components/{reset.stories.ts → Reset.stories.ts} +0 -0
@@ -2,13 +2,14 @@
2
2
  <TransitionGroup name="list"
3
3
  tag="div"
4
4
  :class="twMerge(`notifications
5
- fixed
5
+ absolute
6
6
  z-50
7
7
  inset-y-0 right-0
8
8
  w-1/3
9
9
  min-w-[300px]
10
10
  pointer-events-none
11
11
  overflow-hidden
12
+ flex flex-col
12
13
  `, ($attrs as any).class)"
13
14
  v-bind="{ ...$attrs, class: undefined }"
14
15
  >
@@ -21,22 +22,25 @@
21
22
  />
22
23
  </TransitionGroup>
23
24
  <Transition>
24
- <div v-show="topNotifications.length > 0"/>
25
+ <div
26
+ v-show="topNotifications.length > 0"
27
+ :class="twMerge(`notifications--none`, ($attrs as any).class)"
28
+ />
25
29
  </Transition>
26
30
  <Transition>
27
31
  <dialog v-show="topNotifications.length > 0"
28
32
  :id="id"
29
- class="modal
33
+ :class="twMerge(`notifications-modal
30
34
  bg-transparent
31
35
  p-0
32
36
  backdrop:bg-black/50
33
37
  backdrop:p-5
34
- "
38
+ `, ($attrs as any).class)"
35
39
  ref="dialogEl"
36
- @click.self.prevent="NotificationHandler.dismiss(topNotifications[0])"
40
+ @click.self.prevent="topNotifications[0] && NotificationHandler.dismiss(topNotifications[0])"
37
41
  >
38
42
  <form>
39
- <lib-notification v-if="topNotifications.length > 0"
43
+ <lib-notification v-if="topNotifications.length > 0 && topNotifications[0]"
40
44
  :handler="handler"
41
45
  class="top-notification"
42
46
  :notification="topNotifications[0]"
@@ -48,10 +52,11 @@
48
52
  </template>
49
53
  <script setup lang="ts">
50
54
  import { removeIfIn } from "@alanscodelog/utils/removeIfIn.js"
51
- import { type HTMLAttributes,nextTick, onBeforeUnmount, type PropType, ref, shallowReactive } from "vue"
55
+ import { type HTMLAttributes,nextTick, onBeforeUnmount, ref,shallowReactive, Transition, TransitionGroup } from "vue"
52
56
 
53
57
  import LibNotification from "./LibNotification.vue"
54
58
 
59
+ import { useNotificationHandler } from "../../composables/useNotificationHandler.js"
55
60
  import { type NotificationEntry, NotificationHandler } from "../../helpers/NotificationHandler.js"
56
61
  import { twMerge } from "../../utils/twMerge.js"
57
62
  import type { LinkableByIdProps, TailwindClassProp } from "../shared/props.js"
@@ -108,11 +113,14 @@ const notificationListener = (entry: NotificationEntry, type: "added" | "resolve
108
113
  addNotification(entry)
109
114
  }
110
115
  }
111
- props.handler.addNotificationListener(notificationListener)
112
116
 
113
- for (const entry of props.handler.queue) { addNotification(entry) }
117
+ const handler = props.handler ?? useNotificationHandler()
118
+
119
+ handler.addNotificationListener(notificationListener)
120
+
121
+ for (const entry of handler.queue) { addNotification(entry) }
114
122
  onBeforeUnmount(() => {
115
- props.handler.removeNotificationListener(notificationListener)
123
+ handler.removeNotificationListener(notificationListener)
116
124
  })
117
125
 
118
126
  </script>
@@ -121,7 +129,8 @@ onBeforeUnmount(() => {
121
129
  type RealProps =
122
130
  & LinkableByIdProps
123
131
  & {
124
- handler: NotificationHandler
132
+ /** If not provided, uses the global handler (this requires useNotificationHandler be called and configured). */
133
+ handler?: NotificationHandler
125
134
  }
126
135
 
127
136
  interface Props
@@ -44,9 +44,9 @@ export const Primary: Story = {
44
44
  <a v-bind="linkProps" @click="changePage($event, linkProps.i)">{{ linkProps.text ?? linkProps.i }}</a>
45
45
  </template>
46
46
  </lib-pagination>
47
- <lib-input :label="'Change Page'" :modelValue="num.toString()" @update:modelValue="num = parseInt($event)" type="number" min="0" :max="args.total">
47
+ <lib-simple-input :label="'Change Page'" :modelValue="num.toString()" @update:modelValue="num = parseInt($event)" type="number" min="0" :max="args.total">
48
48
 
49
- </lib-input>
49
+ </lib-simple-input>
50
50
  `,
51
51
  }),
52
52
  }
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <nav
3
3
  :class="twMerge(`
4
+ pagination--wrapper
4
5
  flex flex-wrap items-center justify-center gap-2
5
6
  `, ($attrs as any).class)"
6
7
  role="navigation"
@@ -12,33 +13,33 @@
12
13
  :href="prevLink.href"
13
14
  :text="t('pagination.previous-page')"
14
15
  :aria-label=" t('pagination.aria.go-to-previous-page',{count:prevLink.i})"
15
- :class="pageClasses"
16
+ :class="`pagination--link ${pageClasses}`"
16
17
  >
17
18
  <a
18
- :class="pageClasses"
19
+ :class="`pagination--link ${pageClasses}`"
19
20
  :href="prevLink.href"
20
21
  :aria-label=" t('pagination.aria.go-to-previous-page', {count:prevLink.i})"
21
22
  />
22
23
  </slot>
23
- <div class="flex-1"/>
24
+ <div class="pagination--spacer flex-1"/>
24
25
  <slot v-if="firstLink.i !== currentLink.i"
25
26
  name="link"
26
27
  :i="0"
27
28
  :href="firstLink.href"
28
29
  :text="firstLink.i"
29
30
  :aria-label="t('pagination.aria.go-to-page', {count:firstLink.i})"
30
- :class="pageClasses"
31
+ :class="`pagination--link pagination--first-link ${pageClasses}`"
31
32
  >
32
33
  {{ firstLink.href }}
33
34
  <a
34
- :class="pageClasses"
35
+ :class="`pagination--link pagination--first-link ${pageClasses}`"
35
36
  :href="firstLink.href"
36
37
  :aria-label="t('pagination.aria.go-to-page', {count:firstLink.i})"
37
38
  >
38
39
  {{ firstLink.i }}
39
40
  </a>
40
41
  </slot>
41
- <div v-if="prevLink.i - extraPages > firstLink.i" class="page-fill">
42
+ <div v-if="prevLink.i - extraPages > firstLink.i" class="pagination--page-fill">
42
43
  ...
43
44
  </div>
44
45
  <template
@@ -46,13 +47,13 @@
46
47
  :key="entry.i"
47
48
  >
48
49
  <slot name="link"
49
- :class="pageClasses"
50
+ :class="`pagination--link ${pageClasses}`"
50
51
  :i="entry.i"
51
52
  :href="entry.href"
52
53
  :aria-label="t('pagination.aria.go-to-page', {count:entry.i})"
53
54
  >
54
55
  <a
55
- :class="pageClasses"
56
+ :class="`pagination--link ${pageClasses}`"
56
57
  :href="entry.href"
57
58
  :aria-label="t('pagination.aria.go-to-page', {count:entry.i})"
58
59
  >
@@ -61,15 +62,14 @@
61
62
  </slot>
62
63
  </template>
63
64
  <slot name="current"
64
- :class="currentPageClasses"
65
+ :class="`pagination--link ${currentPageClasses}`"
65
66
  tabindex="0"
66
67
  :i="currentLink.i"
67
68
  :aria-label="t('pagination.aria.current-page', {count:currentLink.i})"
68
69
  :aria_current="true"
69
70
  >
70
- <div class="a"
71
+ <div :class="`pagination--current-page a ${currentPageClasses}`"
71
72
  tabindex="0"
72
- :class="currentPageClasses"
73
73
  :aria-label="t('pagination.aria.current-page', {count:currentLink.i})"
74
74
  aria-current="true"
75
75
  @click="$event.preventDefault()"
@@ -82,13 +82,13 @@
82
82
  :key="entry.i"
83
83
  >
84
84
  <slot name="link"
85
- :class="pageClasses"
85
+ :class="`pagination--link ${pageClasses}`"
86
86
  :i="entry.i"
87
87
  :href="entry.href"
88
88
  :aria-label="t('pagination.aria.go-to-page', {count:entry.i})"
89
89
  >
90
90
  <a
91
- :class="pageClasses"
91
+ :class="`pagination--link ${pageClasses}`"
92
92
  :href="entry.href"
93
93
  :aria-label="t('pagination.aria.go-to-page', {count:entry.i})"
94
94
  >
@@ -96,29 +96,29 @@
96
96
  </a>
97
97
  </slot>
98
98
  </template>
99
- <div v-if="nextLink.i + extraPages < total" class="page-fill" aria-hidden="true">
99
+ <div v-if="nextLink.i + extraPages < total" class="pagination--page-fill" aria-hidden="true">
100
100
  ...
101
101
  </div>
102
102
  <slot v-if="lastLink.i !== currentLink.i"
103
103
  name="link"
104
- :class="pageClasses"
104
+ :class="`pagination--link ${pageClasses}`"
105
105
  :i="lastLink.i"
106
106
  :href="lastLink.href"
107
107
  :text="total"
108
108
  :aria-label="t('pagination.aria.go-to-page', {count:lastLink.i})"
109
109
  >
110
110
  <a
111
- :class="pageClasses"
111
+ :class="`pagination--link ${pageClasses}`"
112
112
  :href="lastLink.href"
113
113
  :aria-label="t('pagination.aria.go-to-page', {count:lastLink.i})"
114
114
  >
115
115
  {{ total }}
116
116
  </a>
117
117
  </slot>
118
- <div class="flex-1"/>
118
+ <div class="pagination--spacer flex-1"/>
119
119
  <slot
120
120
  v-if="nextLink.i <= total && nextLink.i !== currentLink.i"
121
- :class="pageClasses"
121
+ :class="`pagination--link ${pageClasses}`"
122
122
  name="link"
123
123
  :i="nextLink.i"
124
124
  :href="nextLink.href"
@@ -126,7 +126,7 @@
126
126
  :aria-label="t('pagination.aria.go-to-next-page', {count:nextLink.i})"
127
127
  >
128
128
  <a
129
- :class="pageClasses"
129
+ :class="`pagination--link ${pageClasses}`"
130
130
  :href="nextLink.href"
131
131
  :aria-label="t('pagination.aria.go-to-next-page', {count:nextLink.i})"
132
132
  >
@@ -1,11 +1,11 @@
1
1
  <template>
2
- <div class="flex h-full flex-col items-center justify-center ">
3
- <div class="container mx-auto ">
2
+ <div class="theme-palette flex h-full flex-col items-center justify-center ">
3
+ <div class="theme-palette--container mx-auto ">
4
4
  <div class="grid grid-cols-11 gap-2 gap-y-10 px-10">
5
5
  <template v-for="color, i in colors" :key="color">
6
6
  <div
7
7
  :style="`background-color: var(${color});`"
8
- :class="`h-10 rounded-sm flex items-center justify-center text-fg dark:text-bg`"
8
+ :class="`theme-palette--item h-10 rounded-sm flex items-center justify-center text-fg dark:text-bg`"
9
9
  >
10
10
  {{ [5, 16, 27, 38, 49].includes(i) ? 'Text':'' }}
11
11
  </div>
@@ -61,14 +61,14 @@ export const Primary: Story = {
61
61
  }
62
62
  },
63
63
  template: `
64
- <lib-input
64
+ <lib-simple-input
65
65
  :suggestions="['TL', 'TR', 'BL', 'BR']"
66
66
  :restrict-to-suggestions="true"
67
67
  :suggestions-filter="(_, items) => items"
68
68
  :label="'Button Position'"
69
69
  v-model="buttonPos"
70
70
  >
71
- </lib-input>
71
+ </lib-simple-input>
72
72
  <div>
73
73
  <label>Auto Rotate Position</label>
74
74
  <input type="checkbox" v-model="autoRotatePos">
@@ -6,21 +6,30 @@
6
6
  />
7
7
  <!-- <Transition> -->
8
8
  <component
9
+ v-if="modelValue || useDialogForBackdrop"
9
10
  :id="id ?? fallbackId"
10
11
  :class="twMerge(
11
- useBackdrop && `bg-transparent
12
+ useBackdrop && useDialogForBackdrop && `
13
+ popup--backdrop
14
+ bg-transparent
12
15
  p-0
13
16
  backdrop:bg-transparent
14
17
  `,
18
+ modelValue && useBackdrop && !useDialogForBackdrop && `
19
+ popup--backdrop
20
+ z-100
21
+ fixed
22
+ inset-0
23
+ `,
15
24
  $attrs.class as any
16
25
  )"
17
26
  v-bind="{...$attrs, class:undefined}"
18
- :is="useBackdrop ? 'dialog' : 'div'"
27
+ :is="useDialogForBackdrop ? 'dialog' : 'div'"
19
28
  ref="dialogEl"
20
29
  @mousedown.self="handleMouseup"
21
30
  >
22
- <div v-if="useBackdrop || modelValue"
23
- :class="`fixed ${props.avoidRepositioning ? 'transition-[top,left]' : ''}`"
31
+ <div v-if="modelValue"
32
+ :class="`popup z-100 fixed ${props.avoidRepositioning ? 'transition-[top,left]' : ''}`"
24
33
  :style="`
25
34
  top:${pos.y}px;
26
35
  left:${pos.x}px;
@@ -41,7 +50,7 @@
41
50
  <script setup lang="ts">
42
51
  // eslint-disable-next-line simple-import-sort/imports
43
52
  import { onMounted, nextTick, ref, useAttrs, watch , type HTMLAttributes } from "vue"
44
- import { getFallbackId, type LinkableByIdProps,type TailwindClassProp } from "../shared/props.js"
53
+ import { getFallbackId, type LinkableByIdProps, type TailwindClassProp, type PopupProps } from "../shared/props.js"
45
54
 
46
55
  import { twMerge } from "../../utils/twMerge.js"
47
56
  import { castType } from "@alanscodelog/utils/castType.js"
@@ -52,13 +61,22 @@ const fallbackId = getFallbackId()
52
61
  // eslint-disable-next-line no-use-before-define
53
62
  const props = withDefaults(defineProps<Props>(), {
54
63
  useBackdrop: true,
64
+ useDialogForBackdrop: false,
55
65
  // vue is getting confused when the prop type can also be a function
56
66
  preferredHorizontal: () => ["center-most", "either"] satisfies Props["preferredHorizontal"],
57
67
  preferredVertical: () => ["top", "bottom", "either"] satisfies Props["preferredVertical"] ,
58
68
  avoidRepositioning: false,
69
+ canClose: true,
59
70
  })
60
71
  const $attrs = useAttrs()
61
- defineOptions({ name: "lib-popup" })
72
+ defineOptions({
73
+ name: "lib-popup",
74
+ inheritAttrs: false
75
+ })
76
+
77
+ const emit = defineEmits<{
78
+ (e: "close"): void
79
+ }>()
62
80
 
63
81
 
64
82
  const dialogEl = ref<HTMLDialogElement | null>(null)
@@ -97,7 +115,6 @@ const recompute = (force: boolean = false): void => {
97
115
  const canBePositionedWithoutButton =
98
116
  (horzHasCenterScreen || typeof props.preferredHorizontal === "function")
99
117
  && (vertHasCenterScreen || typeof props.preferredVertical === "function")
100
-
101
118
  if (!popupEl.value || !dialogEl.value || (!buttonEl.value && !canBePositionedWithoutButton)) {
102
119
  pos.value = {} as any
103
120
  return
@@ -310,17 +327,20 @@ const show = () => {
310
327
  if (!isOpen) {
311
328
  isOpen = true
312
329
  modelValue.value = isOpen
313
- if (props.useBackdrop) dialogEl.value?.showModal()
330
+ if (props.useBackdrop && props.useDialogForBackdrop) dialogEl.value?.showModal()
314
331
  recompute(true)
315
332
  }
316
333
  }
317
334
 
318
335
  const close = () => {
319
336
  if (isOpen) {
337
+ const res = props.canClose ?? false
338
+ emit("close")
339
+ if (res === false) return
320
340
  isOpen = false
321
341
  modelValue.value = isOpen
322
342
  pos.value.maxWidth = undefined
323
- if (props.useBackdrop) dialogEl.value?.close()
343
+ if (props.useBackdrop && props.useDialogForBackdrop) dialogEl.value?.close()
324
344
  }
325
345
  }
326
346
 
@@ -375,63 +395,7 @@ defineExpose({
375
395
 
376
396
  type RealProps =
377
397
  & LinkableByIdProps
378
- & {
379
- useBackdrop?: boolean
380
- /**
381
- * The preferred horizontal positioning of the popup. The first position in the array to fit is used.
382
- *
383
- * All elements need to have box-sizing: border-box set. Also note that while the component should work with dynamic popup sizes, in practice there's issues with the positioning being slightly off. Giving the popup element a static size is better. If you need margins around the popup, this can be done with a wrapper element + padding.
384
- *
385
- * The positions `right`/`left`/`top`/`bottom` are relative to the opposite side of the button element so as to try not to cover the triggering button.
386
- *
387
- * So positioning `right` and `left` look like this:
388
- *
389
- * ```
390
- * // right
391
- * [button]
392
- * [----popup----]
393
- *
394
- * // left
395
- * [button]
396
- * [----popup----]
397
- * ```
398
- *
399
- * Positions `*-most` try to position the popup as close to that side of the screen as possible, otherwise limiting the popup to that edge. For example:
400
- *
401
- * ```
402
- * [--------------screen---------------]
403
- * // right-most
404
- * [button]
405
- * [----popup----]
406
- * // near the edge:
407
- * [button]
408
- * [----popup----]
409
- * ```
410
- *
411
- * There is also the `center-screen` position, which centers the popup on the screen.
412
- *
413
- * These last two (`*-most` and `center-screen`) are greedy, they will always find a position that fits. Positions listed after are ignored.
414
- *
415
- * You can also specify a function instead which is given some additional information regarding the space around the button reference element. It should a number for the x position (or y, if preferredVertical).
416
- *
417
- * If you only need to slightly modify the position, you can use the `modifyPosition` option instead.
418
- */
419
- preferredHorizontal?: ("center" | "right" | "left" | "either" | "center-screen" | "right-most" | "left-most" | "center-most")[] | PopupPositioner
420
- /** See `preferredHorizontal`. */
421
- preferredVertical?: ("top" | "bottom" | "center" | "either" | "center-screen" | "top-most" | "bottom-most" | "center-most")[] | PopupPositioner
422
- /**
423
- * When the user scrolls or resizes, normally the entire popup position is recomputed, taking into account the preferred positioning.
424
- *
425
- * This can cause it to shift around.
426
- *
427
- * Set this to true to only shift the popup depending on how much the button element moved and avoid recalculating the best position.
428
- */
429
- avoidRepositioning?: boolean
430
- /**
431
- * Allows modifying the calculated position, to for example, clamp it.
432
- */
433
- modifyPosition?: PopupPositionModifier
434
- }
398
+ & PopupProps
435
399
 
436
400
  interface Props
437
401
  extends
@@ -3,6 +3,7 @@
3
3
  <div v-if="!hide"
4
4
  :id="id ?? fallbackId"
5
5
  :class="twMerge(`
6
+ progress-bar
6
7
  w-[200px]
7
8
  whitespace-nowrap
8
9
  overflow-x-scroll
@@ -47,7 +48,7 @@
47
48
  v-bind="{...$attrs, class:undefined}"
48
49
  :style="`--progress: ${clampVal(progress, clamp[0] ?? 0, clamp[1] ?? 100)}%;`"
49
50
  >
50
- <div class="label-wrapper relative flex-1">
51
+ <div class="procgress-bar--label-wrapper relative flex-1">
51
52
  <span class="before:content-vertical-holder"/>
52
53
  <Transition>
53
54
  <slot>
@@ -71,6 +72,7 @@
71
72
  <label
72
73
  v-if="!psuedoHide"
73
74
  class="
75
+ progress-bar--label
74
76
  contrast-label
75
77
  pointer-events-none
76
78
  absolute
@@ -43,7 +43,7 @@
43
43
  >
44
44
  <!-- :aria-description="recording ? recordingTitle : ''" -->
45
45
  <div
46
- :class="twMerge(`recorder-indicator
46
+ :class="twMerge(`recorder--indicator
47
47
  inline-block
48
48
  bg-red-700
49
49
  rounded-full
@@ -62,7 +62,7 @@
62
62
  )"
63
63
  ref="recorderIndicatorEl"
64
64
  />
65
- <div class="recorder-value before:content-vertical-holder truncate">
65
+ <div class="recorder--value before:content-vertical-holder truncate">
66
66
  {{ recording
67
67
  ? recordingValue ?? t("recorder.recording")
68
68
  : tempValue }}
@@ -32,6 +32,7 @@
32
32
  ($attrs as any).attrs?.class)"
33
33
  >
34
34
  <TestControls v-if="testWrapperMode" :show-outline="showOutline"/>
35
+ <Notifications v-if="useNotifications && isClientSide"/>
35
36
  <slot/>
36
37
  </div>
37
38
  </div>
@@ -44,12 +45,15 @@ import { type ComponentPublicInstance, computed, onBeforeUnmount, onMounted, ref
44
45
 
45
46
  import { useAccesibilityOutline } from "../../composables/useAccesibilityOutline.js"
46
47
  import { useDivideAttrs } from "../../composables/useDivideAttrs.js"
48
+ import { useNotificationHandler } from "../../composables/useNotificationHandler.js"
47
49
  import { useSetupDarkMode } from "../../composables/useSetupDarkMode.js"
48
50
  import { useSetupI18n } from "../../composables/useSetupI18n.js"
49
51
  import { useSetupLocale } from "../../composables/useSetupLocale.js"
50
52
  import { useShowDevOnlyKey } from "../../composables/useShowDevOnlyKey.js"
53
+ import { NotificationHandler } from "../../helpers/NotificationHandler.js"
51
54
  import { theme as defaultTheme } from "../../theme.js"
52
55
  import { twMerge } from "../../utils/twMerge.js"
56
+ import Notifications from "../LibNotifications/LibNotifications.vue"
53
57
  import TestControls from "../TestControls/TestControls.vue"
54
58
 
55
59
  const $attrs = useDivideAttrs(["wrapper"])
@@ -66,6 +70,8 @@ const props = withDefaults(defineProps<{
66
70
  /** True by default, should be passed import.meta.client if using nuxt, or false when running server side. */
67
71
  isClientSide?: boolean
68
72
  useBuiltinTranslations?: boolean
73
+ useNotifications?: boolean
74
+ notificationHandler?: NotificationHandler
69
75
  }>(), {
70
76
  theme: undefined,
71
77
  testWrapperMode: false,
@@ -74,7 +80,9 @@ const props = withDefaults(defineProps<{
74
80
  id: "app",
75
81
  getRef: undefined,
76
82
  isClientSide: true,
77
- useBuiltinTranslations: true
83
+ useBuiltinTranslations: true,
84
+ useNotifications: true,
85
+ notificationHandler: undefined
78
86
  })
79
87
 
80
88
  const el = ref<HTMLElement | null>(null)
@@ -85,6 +93,11 @@ function handleRef(_: Element | ComponentPublicInstance | null): void {
85
93
  props.getRef?.(_)
86
94
  }
87
95
 
96
+ if (props.useNotifications) {
97
+ const handler = props.notificationHandler ?? new NotificationHandler()
98
+ useNotificationHandler(handler, props.isClientSide)
99
+ }
100
+
88
101
  const autoOutline = useAccesibilityOutline(el).outline
89
102
 
90
103
  const showOutline = computed(() => (props.outline && autoOutline.value) || props.forceOutline)
@@ -7,7 +7,7 @@ import * as components from "../index.js"
7
7
 
8
8
  const meta = {
9
9
  component: components.LibSimpleInput,
10
- title: "Components/SimpleInput",
10
+ title: "Components/Input",
11
11
  args: {
12
12
  modelValue: "Value",
13
13
  placeholder: "Placeholder",
@@ -2,7 +2,7 @@
2
2
  <input
3
3
  :id="id ?? fallbackId"
4
4
  :class="twMerge(`
5
- input
5
+ simple-input
6
6
  flex-1
7
7
  grow-[999999]
8
8
  rounded-sm
@@ -48,7 +48,7 @@
48
48
  placeholder:text-danger-700
49
49
  border-danger-700
50
50
  focus:border-danger-700
51
- outlined:!ring-danger-700
51
+ outlined:!outline-danger-700
52
52
  text-danger-800
53
53
  dark:text-danger-400
54
54
  dark:placeholder:text-danger-700
@@ -71,13 +71,10 @@
71
71
 
72
72
 
73
73
  <script lang="ts" setup generic="T">
74
- import { keys } from "@alanscodelog/utils/keys.js"
75
- import { pick } from "@alanscodelog/utils/pick.js"
76
- import type { MakeRequired } from "@alanscodelog/utils/types"
77
- import { castType } from "@alanscodelog/utils/utils"
78
- import { getCurrentInstance, type InputHTMLAttributes, type InputTypeHTMLAttribute,toRef,useAttrs } from "vue"
74
+ import { type InputHTMLAttributes, useAttrs } from "vue"
79
75
 
80
76
  import { useAriaLabel } from "../../composables/useAriaLabel.js"
77
+ import { usePreHydrationValue } from "../../composables/usePreHydrationValue.js"
81
78
  import { hasModifiers } from "../../helpers/hasModifiers.js"
82
79
  import { twMerge } from "../../utils/twMerge.js"
83
80
  import { type BaseInteractiveProps, baseInteractivePropsDefaults, getFallbackId,type LabelProps, type LinkableByIdProps, type TailwindClassProp } from "../shared/props.js"
@@ -115,6 +112,7 @@ function handleKeydown(e: KeyboardEvent) {
115
112
  emit("submit", modelValue.value)
116
113
  }
117
114
  }
115
+ usePreHydrationValue(props.id ?? fallbackId, modelValue)
118
116
 
119
117
  </script>
120
118