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