@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
@@ -1,29 +1,27 @@
1
- <!-- Popover API WHEN :sob:
2
- #awaiting https://developer.mozilla.org/en-US/docs/Web/API/Popover_API#browser_compatibility -->
3
1
  <template>
4
2
  <slot name="button"
5
- :extract-el="(_:any)=> buttonEl = _"
3
+ :extract-el="(_) => buttonEl = _"
6
4
  />
7
5
  <!-- <Transition> -->
8
6
  <component
9
7
  v-if="modelValue || useDialogForBackdrop"
10
8
  :id="id ?? fallbackId"
11
9
  :class="twMerge(
12
- useBackdrop && useDialogForBackdrop && `
10
+ useBackdrop && useDialogForBackdrop && `
13
11
  popup--backdrop
14
12
  bg-transparent
15
13
  p-0
16
14
  backdrop:bg-transparent
17
15
  `,
18
- modelValue && useBackdrop && !useDialogForBackdrop && `
16
+ modelValue && useBackdrop && !useDialogForBackdrop && `
19
17
  popup--backdrop
20
18
  z-100
21
19
  fixed
22
20
  inset-0
23
21
  `,
24
- $attrs.class as any
25
- )"
26
- v-bind="{...$attrs, class:undefined}"
22
+ $attrs.class
23
+ )"
24
+ v-bind="{ ...$attrs, class: void 0 }"
27
25
  :is="useDialogForBackdrop ? 'dialog' : 'div'"
28
26
  ref="dialogEl"
29
27
  @mousedown.self="handleMouseup"
@@ -40,365 +38,330 @@
40
38
  <slot
41
39
  name="popup"
42
40
  :position="pos"
43
- :extract-el="(_:any) => popupEl = _"
41
+ :extract-el="(_) => popupEl = _"
44
42
  />
45
43
  </div>
46
44
  </component>
47
45
  <!-- </Transition> -->
48
46
  </template>
49
47
 
50
- <script setup lang="ts">
51
- // eslint-disable-next-line simple-import-sort/imports
52
- import { onMounted, nextTick, ref, useAttrs, watch , type HTMLAttributes } from "vue"
53
- import { getFallbackId, type LinkableByIdProps, type TailwindClassProp, type PopupProps } from "../shared/props.js"
54
-
55
- import { twMerge } from "../../utils/twMerge.js"
56
- import { castType } from "@alanscodelog/utils/castType.js"
57
- import { isArray } from "@alanscodelog/utils/isArray.js"
58
- import type { IPopupReference, PopupPosition, PopupPositioner, PopupPositionModifier, SimpleDOMRect } from "../../types/index.js"
59
-
60
- const fallbackId = getFallbackId()
61
- const props = withDefaults(defineProps<Props>(), {
62
- useBackdrop: true,
63
- useDialogForBackdrop: false,
64
- // vue is getting confused when the prop type can also be a function
65
- preferredHorizontal: () => ["center-most", "either"] satisfies Props["preferredHorizontal"],
66
- preferredVertical: () => ["top", "bottom", "either"] satisfies Props["preferredVertical"] ,
67
- avoidRepositioning: false,
68
- canClose: true,
69
- })
70
- const $attrs = useAttrs()
48
+ <script setup>
49
+ import { onMounted, nextTick, ref, useAttrs, watch } from "vue";
50
+ import { getFallbackId } from "../shared/props.js";
51
+ import { twMerge } from "../../utils/twMerge.js";
52
+ import { castType } from "@alanscodelog/utils/castType";
53
+ import { isArray } from "@alanscodelog/utils/isArray";
54
+ const fallbackId = getFallbackId();
55
+ const props = defineProps({
56
+ id: { type: String, required: false },
57
+ useDialogForBackdrop: { type: Boolean, required: false, default: false },
58
+ useBackdrop: { type: Boolean, required: false, default: true },
59
+ preferredHorizontal: { type: [Array, Function], required: false, default: () => ["center-most", "either"] },
60
+ preferredVertical: { type: [Array, Function], required: false, default: () => ["top", "bottom", "either"] },
61
+ avoidRepositioning: { type: Boolean, required: false, default: false },
62
+ modifyPosition: { type: Function, required: false },
63
+ canClose: { type: Boolean, required: false, default: true }
64
+ });
65
+ const $attrs = useAttrs();
71
66
  defineOptions({
72
- name: "lib-popup",
73
- inheritAttrs: false
74
- })
75
-
76
- const emit = defineEmits<{
77
- (e: "close"): void
78
- }>()
79
-
80
-
81
- const dialogEl = ref<HTMLDialogElement | null>(null)
82
- const popupEl = ref<IPopupReference | null>(null)
83
- const buttonEl = ref<IPopupReference | null>(null)
84
- const backgroundEl = ref<IPopupReference | null>(null)
85
-
86
- const pos = ref<PopupPosition>({} as any)
87
- const modelValue = defineModel<boolean>({ default: false })
88
- let isOpen = false
89
-
90
-
91
- /**
92
- * We don't have access to the dialog backdrop and without extra styling, it's of 0 width/height, positioned in the center of the screen, with margins taking up all the space.
93
- *
94
- * This returns a modified rect that makes more logical sense.
95
- */
96
- const getDialogBoundingRect = (): SimpleDOMRect => ({
97
- x: 0,
98
- y: 0,
99
- width: window.innerWidth,
100
- height: window.innerHeight,
101
- top: 0,
102
- bottom: 0,
103
- left: 0,
104
- right: 0,
105
- })
106
- let lastButtonElPos: SimpleDOMRect | undefined
107
- const recompute = (force: boolean = false): void => {
108
- requestAnimationFrame(() => {
109
- const horzHasCenterScreen = isArray(props.preferredHorizontal)
110
- && props.preferredHorizontal[0] === "center-screen"
111
- const vertHasCenterScreen = isArray(props.preferredVertical)
112
- && props.preferredVertical[0] === "center-screen"
113
-
114
- const canBePositionedWithoutButton =
115
- (horzHasCenterScreen || typeof props.preferredHorizontal === "function")
116
- && (vertHasCenterScreen || typeof props.preferredVertical === "function")
117
- if (!popupEl.value || !dialogEl.value || (!buttonEl.value && !canBePositionedWithoutButton)) {
118
- pos.value = {} as any
119
- return
120
- }
121
- const el = buttonEl.value?.getBoundingClientRect()
122
- const bg = backgroundEl.value?.getBoundingClientRect() ?? (
123
- props.useBackdrop
124
- ? getDialogBoundingRect()
125
- : document.body.getBoundingClientRect()
126
- )
127
- const popup = popupEl.value.getBoundingClientRect()
128
-
129
- let finalPos: { x: number, y: number, maxWidth?: number, maxHeight?: number } = {} as any
130
-
131
-
132
- if (!force && modelValue.value && props.avoidRepositioning && buttonEl.value && lastButtonElPos) {
133
- const shiftX = buttonEl.value.getBoundingClientRect().x - lastButtonElPos.x
134
- const shiftY = buttonEl.value.getBoundingClientRect().y - lastButtonElPos.y
135
-
136
- pos.value.x += shiftX
137
- pos.value.y += shiftY
138
- lastButtonElPos = el
139
- return
140
- }
141
-
142
- const space = {
143
- left: 0,
144
- right: 0,
145
- leftLeft: 0,
146
- rightRight: 0,
147
- leftFromCenter: 0,
148
- rightFromCenter: 0,
149
- topFromCenter: 0,
150
- bottomFromCenter: 0,
151
- top: 0,
152
- bottom: 0,
153
- }
154
- if (el) {
155
- space.left = (el.x + el.width) - bg.x
156
- space.leftLeft = el.x - bg.x
157
- space.right = (bg.x + bg.width) - (el.x + el.width)
158
- space.rightRight = bg.x + bg.width - el.x
159
- space.leftFromCenter = (el.x + (el.width / 2)) - bg.x
160
- space.rightFromCenter = (bg.x + bg.width) - (el.x + (el.width / 2))
161
- space.topFromCenter = (el.y + (el.height / 2)) - bg.y
162
- space.bottomFromCenter = (bg.y + bg.height) - (el.y + (el.height / 2))
163
- space.top = el.y - bg.y
164
- space.bottom = (bg.y + bg.height) - (el.y + el.height)
165
- }
166
- const { preferredHorizontal, preferredVertical } = props
167
- let maxWidth: number | undefined
168
- let maxHeight: number | undefined
169
- if (typeof preferredHorizontal === "function") {
170
- finalPos.x = preferredHorizontal(el, popup, bg, space)
171
- } else {
172
- /* eslint-disable no-labels */
173
- outerloop:
174
- for (const type of preferredHorizontal) {
175
- switch (type) {
176
- case "center-screen":
177
- if (popup.width < bg.width) {
178
- finalPos.x = (bg.width / 2) - (popup.width / 2)
179
- } else {
180
- finalPos.x = 0
181
- maxWidth = finalPos.x
182
- }
183
- break
184
- case "center-most":
185
- case "center":
186
- castType<DOMRect>(el)
187
- if (space.leftFromCenter >= (popup.width / 2) &&
188
- space.rightFromCenter >= (popup.width / 2)) {
189
- finalPos.x = el.x + (el.width / 2) - (popup.width / 2)
190
- break outerloop
191
- }
192
- // todo temp fix when it's too wide, will prefer left
193
- if (((space.rightFromCenter + space.leftFromCenter) <= popup.width)) {
194
- finalPos.x = 0
195
- break outerloop
196
- }
197
- if (type === "center-most") {
198
- if (space.leftFromCenter < space.rightFromCenter) {
199
- finalPos.x = el.x + (el.width / 2) - space.leftFromCenter; break outerloop
200
- } else {
201
- finalPos.x = el.x + (el.width / 2) + space.rightFromCenter - popup.width; break outerloop
202
- }
203
- }
204
- break
205
- case "left-most":
206
- castType<DOMRect>(el)
207
- if (space.left >= popup.width) {
208
- finalPos.x = el.x - popup.width; break outerloop
209
- } else {
210
- finalPos.x = 0; break outerloop
211
- }
212
- case "right-most":
213
- castType<DOMRect>(el)
214
- if (space.right >= popup.width) {
215
- finalPos.x = el.x + el.width; break outerloop
216
- } else {
217
- finalPos.x = bg.x + bg.width - popup.width; break outerloop
218
- }
219
-
220
- case "right":
221
- castType<DOMRect>(el)
222
- if (space.right >= popup.width) {
223
- finalPos.x = el.x; break outerloop
224
- }
225
- break
226
- case "left":
227
- castType<DOMRect>(el)
228
- if (space.left >= popup.width) {
229
- finalPos.x = (el.x + el.width) - popup.width; break outerloop
230
- }
231
- break
232
- case "either": {
233
- castType<DOMRect>(el)
234
- if (space.right >= space.left) {
235
- finalPos.x = el.x; break outerloop
236
- } else {
237
- finalPos.x = (el.x + el.width) - popup.width
238
- break outerloop
239
- }
240
- }
241
- }
242
- }
243
- }
244
- if (typeof preferredVertical === "function") {
245
- finalPos.y = preferredVertical(el, popup, bg, space)
246
- } else {
247
- outerloop:
248
- for (const type of preferredVertical) {
249
- switch (type) {
250
- case "center-screen":
251
- if (popup.height < bg.height) {
252
- finalPos.y = (bg.height / 2) - (popup.height / 2)
253
- } else {
254
- finalPos.y = 0
255
- maxHeight = finalPos.y
256
- }
257
- break
258
- case "top":
259
- castType<DOMRect>(el)
260
- if (space.top >= popup.height) {
261
- finalPos.y = el.y - popup.height; break outerloop
262
- }
263
- break
264
- case "bottom":
265
- castType<DOMRect>(el)
266
- if (space.bottom >= popup.height) {
267
- finalPos.y = el.y + el.height; break outerloop
268
- }
269
- break
270
- case "top-most":
271
- castType<DOMRect>(el)
272
- if (space.top >= popup.height) {
273
- finalPos.y = el.y - popup.height; break outerloop
274
- } else {
275
- finalPos.y = 0; break outerloop
276
- }
277
- case "bottom-most":
278
- castType<DOMRect>(el)
279
- if (space.bottom >= popup.height) {
280
- finalPos.y = el.y + el.height; break outerloop
281
- } else {
282
- finalPos.y = bg.y + bg.height - popup.height; break outerloop
283
- }
284
- case "center-most":
285
- case "center":
286
- castType<DOMRect>(el)
287
- if (space.topFromCenter >= (popup.height / 2) &&
288
- space.bottomFromCenter >= (popup.height / 2)) {
289
- finalPos.y = el.y + (el.height / 2) - (popup.height / 2)
290
- break outerloop
291
- }
292
- // todo temp fix when it's too wide, will prefer the top
293
- if (((space.bottomFromCenter + space.topFromCenter) <= popup.height)) {
294
- finalPos.y = 0
295
- break outerloop
296
- }
297
- if (type === "center-most") {
298
- if (space.topFromCenter < space.bottomFromCenter) {
299
- finalPos.y = el.y + (el.height / 2) - space.topFromCenter; break outerloop
300
- } else {
301
- finalPos.y = el.y + (el.height / 2) + space.bottomFromCenter - popup.height; break outerloop
302
- }
303
- }
304
- break
305
- case "either": {
306
- castType<DOMRect>(el)
307
- if (space.top >= space.bottom) {
308
- finalPos.y = el.y - popup.height; break outerloop
309
- } else { finalPos.y = el.y + el.height; break outerloop }
310
- }
311
- }
312
- }
313
- }
314
- finalPos.maxWidth = maxWidth ?? undefined
315
- finalPos.maxHeight = maxHeight ?? undefined
316
- /* eslint-enable no-labels */
317
- if (props.modifyPosition) {
318
- finalPos = props.modifyPosition(finalPos, el, popup, bg, space)
319
- }
320
- pos.value = finalPos
321
- lastButtonElPos = el
322
- })
323
- }
324
-
67
+ name: "lib-popup",
68
+ inheritAttrs: false
69
+ });
70
+ const emit = defineEmits(["close"]);
71
+ const dialogEl = ref(null);
72
+ const popupEl = ref(null);
73
+ const buttonEl = ref(null);
74
+ const backgroundEl = ref(null);
75
+ const pos = ref({});
76
+ const modelValue = defineModel({ type: Boolean, ...{ default: false } });
77
+ let isOpen = false;
78
+ const getDialogBoundingRect = () => ({
79
+ x: 0,
80
+ y: 0,
81
+ width: window.innerWidth,
82
+ height: window.innerHeight,
83
+ top: 0,
84
+ bottom: 0,
85
+ left: 0,
86
+ right: 0
87
+ });
88
+ let lastButtonElPos;
89
+ const recompute = (force = false) => {
90
+ requestAnimationFrame(() => {
91
+ const horzHasCenterScreen = isArray(props.preferredHorizontal) && props.preferredHorizontal[0] === "center-screen";
92
+ const vertHasCenterScreen = isArray(props.preferredVertical) && props.preferredVertical[0] === "center-screen";
93
+ const canBePositionedWithoutButton = (horzHasCenterScreen || typeof props.preferredHorizontal === "function") && (vertHasCenterScreen || typeof props.preferredVertical === "function");
94
+ if (!popupEl.value || !dialogEl.value || !buttonEl.value && !canBePositionedWithoutButton) {
95
+ pos.value = {};
96
+ return;
97
+ }
98
+ const el = buttonEl.value?.getBoundingClientRect();
99
+ const bg = backgroundEl.value?.getBoundingClientRect() ?? (props.useBackdrop ? getDialogBoundingRect() : document.body.getBoundingClientRect());
100
+ const popup = popupEl.value.getBoundingClientRect();
101
+ let finalPos = {};
102
+ if (!force && modelValue.value && props.avoidRepositioning && buttonEl.value && lastButtonElPos) {
103
+ const shiftX = buttonEl.value.getBoundingClientRect().x - lastButtonElPos.x;
104
+ const shiftY = buttonEl.value.getBoundingClientRect().y - lastButtonElPos.y;
105
+ pos.value.x += shiftX;
106
+ pos.value.y += shiftY;
107
+ lastButtonElPos = el;
108
+ return;
109
+ }
110
+ const space = {
111
+ left: 0,
112
+ right: 0,
113
+ leftLeft: 0,
114
+ rightRight: 0,
115
+ leftFromCenter: 0,
116
+ rightFromCenter: 0,
117
+ topFromCenter: 0,
118
+ bottomFromCenter: 0,
119
+ top: 0,
120
+ bottom: 0
121
+ };
122
+ if (el) {
123
+ space.left = el.x + el.width - bg.x;
124
+ space.leftLeft = el.x - bg.x;
125
+ space.right = bg.x + bg.width - (el.x + el.width);
126
+ space.rightRight = bg.x + bg.width - el.x;
127
+ space.leftFromCenter = el.x + el.width / 2 - bg.x;
128
+ space.rightFromCenter = bg.x + bg.width - (el.x + el.width / 2);
129
+ space.topFromCenter = el.y + el.height / 2 - bg.y;
130
+ space.bottomFromCenter = bg.y + bg.height - (el.y + el.height / 2);
131
+ space.top = el.y - bg.y;
132
+ space.bottom = bg.y + bg.height - (el.y + el.height);
133
+ }
134
+ const { preferredHorizontal, preferredVertical } = props;
135
+ let maxWidth;
136
+ let maxHeight;
137
+ if (typeof preferredHorizontal === "function") {
138
+ finalPos.x = preferredHorizontal(el, popup, bg, space);
139
+ } else {
140
+ outerloop:
141
+ for (const type of preferredHorizontal) {
142
+ switch (type) {
143
+ case "center-screen":
144
+ if (popup.width < bg.width) {
145
+ finalPos.x = bg.width / 2 - popup.width / 2;
146
+ } else {
147
+ finalPos.x = 0;
148
+ maxWidth = finalPos.x;
149
+ }
150
+ break;
151
+ case "center-most":
152
+ case "center":
153
+ castType(el);
154
+ if (space.leftFromCenter >= popup.width / 2 && space.rightFromCenter >= popup.width / 2) {
155
+ finalPos.x = el.x + el.width / 2 - popup.width / 2;
156
+ break outerloop;
157
+ }
158
+ if (space.rightFromCenter + space.leftFromCenter <= popup.width) {
159
+ finalPos.x = 0;
160
+ break outerloop;
161
+ }
162
+ if (type === "center-most") {
163
+ if (space.leftFromCenter < space.rightFromCenter) {
164
+ finalPos.x = el.x + el.width / 2 - space.leftFromCenter;
165
+ break outerloop;
166
+ } else {
167
+ finalPos.x = el.x + el.width / 2 + space.rightFromCenter - popup.width;
168
+ break outerloop;
169
+ }
170
+ }
171
+ break;
172
+ case "left-most":
173
+ castType(el);
174
+ if (space.left >= popup.width) {
175
+ finalPos.x = el.x - popup.width;
176
+ break outerloop;
177
+ } else {
178
+ finalPos.x = 0;
179
+ break outerloop;
180
+ }
181
+ case "right-most":
182
+ castType(el);
183
+ if (space.right >= popup.width) {
184
+ finalPos.x = el.x + el.width;
185
+ break outerloop;
186
+ } else {
187
+ finalPos.x = bg.x + bg.width - popup.width;
188
+ break outerloop;
189
+ }
190
+ case "right":
191
+ castType(el);
192
+ if (space.right >= popup.width) {
193
+ finalPos.x = el.x;
194
+ break outerloop;
195
+ }
196
+ break;
197
+ case "left":
198
+ castType(el);
199
+ if (space.left >= popup.width) {
200
+ finalPos.x = el.x + el.width - popup.width;
201
+ break outerloop;
202
+ }
203
+ break;
204
+ case "either": {
205
+ castType(el);
206
+ if (space.right >= space.left) {
207
+ finalPos.x = el.x;
208
+ break outerloop;
209
+ } else {
210
+ finalPos.x = el.x + el.width - popup.width;
211
+ break outerloop;
212
+ }
213
+ }
214
+ }
215
+ }
216
+ }
217
+ if (typeof preferredVertical === "function") {
218
+ finalPos.y = preferredVertical(el, popup, bg, space);
219
+ } else {
220
+ outerloop:
221
+ for (const type of preferredVertical) {
222
+ switch (type) {
223
+ case "center-screen":
224
+ if (popup.height < bg.height) {
225
+ finalPos.y = bg.height / 2 - popup.height / 2;
226
+ } else {
227
+ finalPos.y = 0;
228
+ maxHeight = finalPos.y;
229
+ }
230
+ break;
231
+ case "top":
232
+ castType(el);
233
+ if (space.top >= popup.height) {
234
+ finalPos.y = el.y - popup.height;
235
+ break outerloop;
236
+ }
237
+ break;
238
+ case "bottom":
239
+ castType(el);
240
+ if (space.bottom >= popup.height) {
241
+ finalPos.y = el.y + el.height;
242
+ break outerloop;
243
+ }
244
+ break;
245
+ case "top-most":
246
+ castType(el);
247
+ if (space.top >= popup.height) {
248
+ finalPos.y = el.y - popup.height;
249
+ break outerloop;
250
+ } else {
251
+ finalPos.y = 0;
252
+ break outerloop;
253
+ }
254
+ case "bottom-most":
255
+ castType(el);
256
+ if (space.bottom >= popup.height) {
257
+ finalPos.y = el.y + el.height;
258
+ break outerloop;
259
+ } else {
260
+ finalPos.y = bg.y + bg.height - popup.height;
261
+ break outerloop;
262
+ }
263
+ case "center-most":
264
+ case "center":
265
+ castType(el);
266
+ if (space.topFromCenter >= popup.height / 2 && space.bottomFromCenter >= popup.height / 2) {
267
+ finalPos.y = el.y + el.height / 2 - popup.height / 2;
268
+ break outerloop;
269
+ }
270
+ if (space.bottomFromCenter + space.topFromCenter <= popup.height) {
271
+ finalPos.y = 0;
272
+ break outerloop;
273
+ }
274
+ if (type === "center-most") {
275
+ if (space.topFromCenter < space.bottomFromCenter) {
276
+ finalPos.y = el.y + el.height / 2 - space.topFromCenter;
277
+ break outerloop;
278
+ } else {
279
+ finalPos.y = el.y + el.height / 2 + space.bottomFromCenter - popup.height;
280
+ break outerloop;
281
+ }
282
+ }
283
+ break;
284
+ case "either": {
285
+ castType(el);
286
+ if (space.top >= space.bottom) {
287
+ finalPos.y = el.y - popup.height;
288
+ break outerloop;
289
+ } else {
290
+ finalPos.y = el.y + el.height;
291
+ break outerloop;
292
+ }
293
+ }
294
+ }
295
+ }
296
+ }
297
+ finalPos.maxWidth = maxWidth ?? void 0;
298
+ finalPos.maxHeight = maxHeight ?? void 0;
299
+ if (props.modifyPosition) {
300
+ finalPos = props.modifyPosition(finalPos, el, popup, bg, space);
301
+ }
302
+ pos.value = finalPos;
303
+ lastButtonElPos = el;
304
+ });
305
+ };
325
306
  const show = () => {
326
- if (!isOpen) {
327
- isOpen = true
328
- modelValue.value = isOpen
329
- if (props.useBackdrop && props.useDialogForBackdrop) dialogEl.value?.showModal()
330
- recompute(true)
331
- }
332
- }
333
-
307
+ if (!isOpen) {
308
+ isOpen = true;
309
+ modelValue.value = isOpen;
310
+ if (props.useBackdrop && props.useDialogForBackdrop) dialogEl.value?.showModal();
311
+ recompute(true);
312
+ }
313
+ };
334
314
  const close = () => {
335
- if (isOpen) {
336
- const res = props.canClose ?? false
337
- emit("close")
338
- if (res === false) return
339
- isOpen = false
340
- modelValue.value = isOpen
341
- pos.value.maxWidth = undefined
342
- if (props.useBackdrop && props.useDialogForBackdrop) dialogEl.value?.close()
343
- }
344
- }
345
-
315
+ if (isOpen) {
316
+ const res = props.canClose ?? false;
317
+ emit("close");
318
+ if (res === false) return;
319
+ isOpen = false;
320
+ modelValue.value = isOpen;
321
+ pos.value.maxWidth = void 0;
322
+ if (props.useBackdrop && props.useDialogForBackdrop) dialogEl.value?.close();
323
+ }
324
+ };
346
325
  const toggle = () => {
347
- if (!isOpen) show()
348
- else close()
349
- }
350
-
351
- const recomputeListener = () => recompute()
352
-
326
+ if (!isOpen) show();
327
+ else close();
328
+ };
329
+ const recomputeListener = () => recompute();
353
330
  const bindListeners = () => {
354
- window.addEventListener("resize", recomputeListener)
355
- window.addEventListener("scroll", recomputeListener, true)
356
- }
331
+ window.addEventListener("resize", recomputeListener);
332
+ window.addEventListener("scroll", recomputeListener, true);
333
+ };
357
334
  const unbindListeners = () => {
358
- window.removeEventListener("resize", recomputeListener)
359
- window.removeEventListener("scroll", recomputeListener, true)
360
- }
361
-
335
+ window.removeEventListener("resize", recomputeListener);
336
+ window.removeEventListener("scroll", recomputeListener, true);
337
+ };
362
338
  watch([modelValue, popupEl], () => {
363
- if (modelValue.value) {
364
- show()
365
- bindListeners()
366
- } else {
367
- close()
368
- unbindListeners()
369
- }
370
- })
371
-
372
-
373
- const handleMouseup = ($event: MouseEvent) => {
374
- $event.preventDefault()
375
- toggle()
376
- }
339
+ if (modelValue.value) {
340
+ show();
341
+ bindListeners();
342
+ } else {
343
+ close();
344
+ unbindListeners();
345
+ }
346
+ });
347
+ const handleMouseup = ($event) => {
348
+ $event.preventDefault();
349
+ toggle();
350
+ };
377
351
  onMounted(() => {
378
- recompute()
379
- })
380
-
352
+ recompute();
353
+ });
381
354
  defineExpose({
382
- recompute,
383
- setReference: (el: IPopupReference | null) => {
384
- buttonEl.value = el
385
- },
386
- setBackground: (el: IPopupReference | null) => {
387
- backgroundEl.value = el
388
- },
389
-
390
- })
391
-
355
+ recompute,
356
+ setReference: (el) => {
357
+ buttonEl.value = el;
358
+ },
359
+ setBackground: (el) => {
360
+ backgroundEl.value = el;
361
+ }
362
+ });
392
363
  </script>
393
- <script lang="ts">
394
364
 
395
- type RealProps =
396
- & LinkableByIdProps
397
- & PopupProps
365
+ <script>
398
366
 
399
- interface Props
400
- extends
401
- /** @vue-ignore */
402
- Partial<Omit<HTMLAttributes,"class"> & TailwindClassProp>,
403
- RealProps { }
404
367
  </script>