base-ui-vue 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 (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/button/Button.cjs +524 -0
  4. package/dist/button/Button.cjs.map +1 -0
  5. package/dist/button/Button.js +453 -0
  6. package/dist/button/Button.js.map +1 -0
  7. package/dist/composite/composite.cjs +56 -0
  8. package/dist/composite/composite.cjs.map +1 -0
  9. package/dist/composite/composite.js +21 -0
  10. package/dist/composite/composite.js.map +1 -0
  11. package/dist/control/FieldControl.cjs +576 -0
  12. package/dist/control/FieldControl.cjs.map +1 -0
  13. package/dist/control/FieldControl.js +511 -0
  14. package/dist/control/FieldControl.js.map +1 -0
  15. package/dist/control/FieldControlDataAttributes.cjs +42 -0
  16. package/dist/control/FieldControlDataAttributes.cjs.map +1 -0
  17. package/dist/control/FieldControlDataAttributes.js +36 -0
  18. package/dist/control/FieldControlDataAttributes.js.map +1 -0
  19. package/dist/description/FieldDescription.cjs +86 -0
  20. package/dist/description/FieldDescription.cjs.map +1 -0
  21. package/dist/description/FieldDescription.js +81 -0
  22. package/dist/description/FieldDescription.js.map +1 -0
  23. package/dist/direction-provider/DirectionContext.cjs +26 -0
  24. package/dist/direction-provider/DirectionContext.cjs.map +1 -0
  25. package/dist/direction-provider/DirectionContext.js +15 -0
  26. package/dist/direction-provider/DirectionContext.js.map +1 -0
  27. package/dist/direction-provider/DirectionProvider.cjs +37 -0
  28. package/dist/direction-provider/DirectionProvider.cjs.map +1 -0
  29. package/dist/direction-provider/DirectionProvider.js +32 -0
  30. package/dist/direction-provider/DirectionProvider.js.map +1 -0
  31. package/dist/error/FieldError.cjs +414 -0
  32. package/dist/error/FieldError.cjs.map +1 -0
  33. package/dist/error/FieldError.js +373 -0
  34. package/dist/error/FieldError.js.map +1 -0
  35. package/dist/fallback/AvatarFallback.cjs +165 -0
  36. package/dist/fallback/AvatarFallback.cjs.map +1 -0
  37. package/dist/fallback/AvatarFallback.js +136 -0
  38. package/dist/fallback/AvatarFallback.js.map +1 -0
  39. package/dist/form/Form.cjs +159 -0
  40. package/dist/form/Form.cjs.map +1 -0
  41. package/dist/form/Form.js +154 -0
  42. package/dist/form/Form.js.map +1 -0
  43. package/dist/header/AccordionHeader.cjs +189 -0
  44. package/dist/header/AccordionHeader.cjs.map +1 -0
  45. package/dist/header/AccordionHeader.js +148 -0
  46. package/dist/header/AccordionHeader.js.map +1 -0
  47. package/dist/image/AvatarImage.cjs +150 -0
  48. package/dist/image/AvatarImage.cjs.map +1 -0
  49. package/dist/image/AvatarImage.js +145 -0
  50. package/dist/image/AvatarImage.js.map +1 -0
  51. package/dist/image/AvatarImageDataAttributes.cjs +26 -0
  52. package/dist/image/AvatarImageDataAttributes.cjs.map +1 -0
  53. package/dist/image/AvatarImageDataAttributes.js +20 -0
  54. package/dist/image/AvatarImageDataAttributes.js.map +1 -0
  55. package/dist/index.cjs +64 -0
  56. package/dist/index.d.cts +1501 -0
  57. package/dist/index.d.cts.map +1 -0
  58. package/dist/index.d.ts +1501 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +15 -0
  61. package/dist/index2.cjs +2767 -0
  62. package/dist/index2.cjs.map +1 -0
  63. package/dist/index2.js +2618 -0
  64. package/dist/index2.js.map +1 -0
  65. package/package.json +77 -0
  66. package/src/accordion/accordion.types.ts +126 -0
  67. package/src/accordion/header/AccordionHeader.vue +36 -0
  68. package/src/accordion/index.ts +10 -0
  69. package/src/accordion/item/AccordionItem.vue +124 -0
  70. package/src/accordion/item/AccordionItemContext.ts +24 -0
  71. package/src/accordion/item/AccordionItemDataAttributes.ts +15 -0
  72. package/src/accordion/item/stateAttributesMapping.ts +14 -0
  73. package/src/accordion/panel/AccordionPanel.vue +156 -0
  74. package/src/accordion/panel/AccordionPanelCssVars.ts +12 -0
  75. package/src/accordion/root/AccordionRoot.vue +130 -0
  76. package/src/accordion/root/AccordionRootContext.ts +37 -0
  77. package/src/accordion/root/AccordionRootDataAttributes.ts +10 -0
  78. package/src/accordion/root/stateAttributesMapping.ts +6 -0
  79. package/src/accordion/trigger/AccordionTrigger.vue +186 -0
  80. package/src/avatar/fallback/AvatarFallback.vue +75 -0
  81. package/src/avatar/image/AvatarImage.vue +103 -0
  82. package/src/avatar/image/AvatarImageDataAttributes.ts +14 -0
  83. package/src/avatar/image/useImageLoadingStatus.ts +58 -0
  84. package/src/avatar/index.ts +19 -0
  85. package/src/avatar/root/AvatarRoot.vue +62 -0
  86. package/src/avatar/root/AvatarRootContext.ts +22 -0
  87. package/src/avatar/root/stateAttributesMapping.ts +7 -0
  88. package/src/button/Button.vue +59 -0
  89. package/src/button/ButtonDataAttributes.ts +6 -0
  90. package/src/button/button.types.ts +22 -0
  91. package/src/button/index.ts +2 -0
  92. package/src/collapsible/collapsible.types.ts +64 -0
  93. package/src/collapsible/index.ts +6 -0
  94. package/src/collapsible/panel/CollapsiblePanel.vue +145 -0
  95. package/src/collapsible/panel/CollapsiblePanelCssVars.ts +12 -0
  96. package/src/collapsible/panel/CollapsiblePanelDataAttributes.ts +18 -0
  97. package/src/collapsible/panel/useCollapsiblePanel.ts +489 -0
  98. package/src/collapsible/root/CollapsibleRoot.vue +60 -0
  99. package/src/collapsible/root/CollapsibleRootContext.ts +18 -0
  100. package/src/collapsible/root/stateAttributesMapping.ts +9 -0
  101. package/src/collapsible/root/useCollapsibleRoot.ts +252 -0
  102. package/src/collapsible/trigger/CollapsibleTrigger.vue +63 -0
  103. package/src/collapsible/trigger/CollapsibleTriggerDataAttributes.ts +6 -0
  104. package/src/composite/composite.ts +232 -0
  105. package/src/composite/constants.ts +1 -0
  106. package/src/composite/item/CompositeItem.vue +75 -0
  107. package/src/composite/item/useCompositeItem.ts +63 -0
  108. package/src/composite/list/CompositeList.vue +168 -0
  109. package/src/composite/list/CompositeListContext.ts +21 -0
  110. package/src/composite/list/useCompositeListItem.ts +130 -0
  111. package/src/composite/root/CompositeRoot.vue +106 -0
  112. package/src/composite/root/CompositeRootContext.ts +36 -0
  113. package/src/composite/root/index.ts +7 -0
  114. package/src/composite/root/useCompositeRoot.ts +418 -0
  115. package/src/direction-provider/DirectionContext.ts +29 -0
  116. package/src/direction-provider/DirectionProvider.vue +31 -0
  117. package/src/direction-provider/index.ts +8 -0
  118. package/src/field/control/FieldControl.vue +211 -0
  119. package/src/field/control/FieldControlDataAttributes.ts +30 -0
  120. package/src/field/description/FieldDescription.vue +62 -0
  121. package/src/field/description/FieldDescriptionDataAttributes.ts +30 -0
  122. package/src/field/error/FieldError.vue +159 -0
  123. package/src/field/error/FieldErrorDataAttributes.ts +38 -0
  124. package/src/field/index.ts +27 -0
  125. package/src/field/item/FieldItem.vue +63 -0
  126. package/src/field/item/FieldItemContext.ts +16 -0
  127. package/src/field/label/FieldLabel.vue +102 -0
  128. package/src/field/label/FieldLabelDataAttributes.ts +30 -0
  129. package/src/field/root/FieldRoot.vue +262 -0
  130. package/src/field/root/FieldRootContext.ts +97 -0
  131. package/src/field/root/FieldRootDataAttributes.ts +30 -0
  132. package/src/field/root/useFieldRootState.ts +81 -0
  133. package/src/field/root/useFieldValidation.ts +298 -0
  134. package/src/field/root/useFieldValidity.ts +30 -0
  135. package/src/field/useField.ts +73 -0
  136. package/src/field/utils/constants.ts +45 -0
  137. package/src/field/utils/getCombinedFieldValidityData.ts +18 -0
  138. package/src/field/validity/FieldValidity.vue +36 -0
  139. package/src/fieldset/index.ts +8 -0
  140. package/src/fieldset/legend/FieldsetLegend.vue +72 -0
  141. package/src/fieldset/root/FieldsetRoot.vue +74 -0
  142. package/src/fieldset/root/FieldsetRootContext.ts +26 -0
  143. package/src/floating-ui-vue/types.ts +4 -0
  144. package/src/floating-ui-vue/utils/composite.ts +475 -0
  145. package/src/floating-ui-vue/utils/constants.ts +4 -0
  146. package/src/floating-ui-vue/utils/event.ts +4 -0
  147. package/src/floating-ui-vue/utils.ts +2 -0
  148. package/src/form/Form.vue +188 -0
  149. package/src/form/FormContext.ts +59 -0
  150. package/src/form/index.ts +10 -0
  151. package/src/index.ts +14 -0
  152. package/src/labelable-provider/LabelableContext.ts +33 -0
  153. package/src/labelable-provider/LabelableProvider.vue +55 -0
  154. package/src/labelable-provider/index.ts +6 -0
  155. package/src/labelable-provider/useAriaLabelledBy.ts +100 -0
  156. package/src/labelable-provider/useLabelableId.ts +30 -0
  157. package/src/merge-props/index.ts +1 -0
  158. package/src/merge-props/mergeProps.ts +192 -0
  159. package/src/test/index.ts +1 -0
  160. package/src/test/utils.ts +9 -0
  161. package/src/types/index.ts +10 -0
  162. package/src/use-button/index.ts +1 -0
  163. package/src/use-button/useButton.ts +231 -0
  164. package/src/use-render/index.ts +1 -0
  165. package/src/use-render/useRender.spec.ts +90 -0
  166. package/src/use-render/useRender.ts +152 -0
  167. package/src/utils/collapsibleOpenStateMapping.ts +33 -0
  168. package/src/utils/constants.ts +1 -0
  169. package/src/utils/createBaseUIEventDetails.ts +127 -0
  170. package/src/utils/empty.ts +5 -0
  171. package/src/utils/error.ts +19 -0
  172. package/src/utils/getStateAttributesProps.ts +31 -0
  173. package/src/utils/isElementDisabled.ts +7 -0
  174. package/src/utils/noop.ts +1 -0
  175. package/src/utils/reasons.ts +69 -0
  176. package/src/utils/resolveRef.ts +9 -0
  177. package/src/utils/slot.ts +6 -0
  178. package/src/utils/stateAttributesMapping.ts +28 -0
  179. package/src/utils/transitionStatusMapping.ts +22 -0
  180. package/src/utils/types.ts +47 -0
  181. package/src/utils/useAnimationFrame.ts +130 -0
  182. package/src/utils/useAnimationsFinished.ts +101 -0
  183. package/src/utils/useBaseUiId.ts +9 -0
  184. package/src/utils/useControllableState.ts +44 -0
  185. package/src/utils/useFocusableWhenDisabled.ts +85 -0
  186. package/src/utils/useId.ts +26 -0
  187. package/src/utils/useMergedRefs.ts +91 -0
  188. package/src/utils/useOpenChangeComplete.ts +52 -0
  189. package/src/utils/useRenderElement.ts +162 -0
  190. package/src/utils/useTimeout.ts +48 -0
  191. package/src/utils/useTransitionStatus.ts +104 -0
  192. package/src/utils/warn.ts +15 -0
package/dist/index2.js ADDED
@@ -0,0 +1,2618 @@
1
+ import { EMPTY_OBJECT, mergeProps as mergeProps$1, useButton, useMergedRefs, useRenderElement } from "./button/Button.js";
2
+ import { CollapsiblePanelDataAttributes, accordionItemContextKey, accordionStateAttributesMapping, collapsibleOpenStateMapping, triggerOpenStateMapping, useAccordionItemContext } from "./header/AccordionHeader.js";
3
+ import { AnimationFrame, transitionStatusMapping, useAnimationFrame, useAnimationsFinished, useOpenChangeComplete, useTransitionStatus } from "./error/FieldError.js";
4
+ import { DEFAULT_VALIDITY_STATE, fieldRootContextKey, fieldValidityMapping, getCombinedFieldValidityData, labelableContextKey, useBaseUiId, useFieldRootContext, useFormContext, useLabelableContext } from "./control/FieldControl.js";
5
+ import { useDirection } from "./direction-provider/DirectionContext.js";
6
+ import { ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, END, HOME } from "./composite/composite.js";
7
+ import { AvatarRootContextKey, avatarStateAttributesMapping, useTimeout } from "./fallback/AvatarFallback.js";
8
+ import { computed, createBlock, createCommentVNode, defineComponent, getCurrentInstance, guardReactiveProps, inject, mergeProps, normalizeProps, onBeforeUnmount, onMounted, onUnmounted, openBlock, provide, readonly, ref, renderSlot, resolveDynamicComponent, shallowReadonly, shallowRef, toValue, unref, useAttrs, watch, watchEffect, withCtx } from "vue";
9
+
10
+ //#region src/collapsible/root/CollapsibleRootContext.ts
11
+ const collapsibleRootContextKey = Symbol("CollapsibleRootContext");
12
+ function useCollapsibleRootContext() {
13
+ const context = inject(collapsibleRootContextKey, void 0);
14
+ if (context === void 0) throw new Error("Base UI Vue: CollapsibleRootContext is missing. Collapsible parts must be placed within <CollapsibleRoot>.");
15
+ return context;
16
+ }
17
+
18
+ //#endregion
19
+ //#region src/utils/createBaseUIEventDetails.ts
20
+ /**
21
+ * Creates a Base UI event details object with the given reason and utilities
22
+ * for preventing Base UI's internal event handling.
23
+ */
24
+ function createChangeEventDetails(reason, event, trigger, customProperties) {
25
+ let canceled = false;
26
+ let propagationAllowed = false;
27
+ const custom = customProperties ?? EMPTY_OBJECT;
28
+ return {
29
+ reason,
30
+ event: event ?? new Event("base-ui"),
31
+ cancel() {
32
+ canceled = true;
33
+ },
34
+ allowPropagation() {
35
+ propagationAllowed = true;
36
+ },
37
+ get isCanceled() {
38
+ return canceled;
39
+ },
40
+ get isPropagationAllowed() {
41
+ return propagationAllowed;
42
+ },
43
+ trigger,
44
+ ...custom
45
+ };
46
+ }
47
+
48
+ //#endregion
49
+ //#region src/utils/reasons.ts
50
+ const none = "none";
51
+ const triggerPress = "trigger-press";
52
+ const triggerHover = "trigger-hover";
53
+ const triggerFocus = "trigger-focus";
54
+ const outsidePress = "outside-press";
55
+ const itemPress = "item-press";
56
+ const closePress = "close-press";
57
+ const linkPress = "link-press";
58
+ const clearPress = "clear-press";
59
+ const chipRemovePress = "chip-remove-press";
60
+ const trackPress = "track-press";
61
+ const incrementPress = "increment-press";
62
+ const decrementPress = "decrement-press";
63
+ const inputChange = "input-change";
64
+ const inputClear = "input-clear";
65
+ const inputBlur = "input-blur";
66
+ const inputPaste = "input-paste";
67
+ const inputPress = "input-press";
68
+ const focusOut = "focus-out";
69
+ const escapeKey = "escape-key";
70
+ const closeWatcher = "close-watcher";
71
+ const listNavigation = "list-navigation";
72
+ const keyboard = "keyboard";
73
+ const pointer = "pointer";
74
+ const drag = "drag";
75
+ const swipe = "swipe";
76
+ const wheel = "wheel";
77
+ const scrub = "scrub";
78
+ const cancelOpen = "cancel-open";
79
+ const siblingOpen = "sibling-open";
80
+ const disabled = "disabled";
81
+ const imperativeAction = "imperative-action";
82
+ const windowResize = "window-resize";
83
+ const REASONS = {
84
+ none,
85
+ triggerPress,
86
+ triggerHover,
87
+ triggerFocus,
88
+ outsidePress,
89
+ itemPress,
90
+ closePress,
91
+ linkPress,
92
+ clearPress,
93
+ chipRemovePress,
94
+ trackPress,
95
+ incrementPress,
96
+ decrementPress,
97
+ inputChange,
98
+ inputClear,
99
+ inputBlur,
100
+ inputPaste,
101
+ inputPress,
102
+ focusOut,
103
+ escapeKey,
104
+ closeWatcher,
105
+ listNavigation,
106
+ keyboard,
107
+ pointer,
108
+ drag,
109
+ swipe,
110
+ wheel,
111
+ scrub,
112
+ cancelOpen,
113
+ siblingOpen,
114
+ disabled,
115
+ imperativeAction,
116
+ windowResize
117
+ };
118
+
119
+ //#endregion
120
+ //#region src/utils/useControllableState.ts
121
+ /**
122
+ * Manages controlled / uncontrolled state following the same semantics as
123
+ * React's `useControlled` hook.
124
+ *
125
+ * - When `controlled()` returns a non-`undefined` value the component is
126
+ * considered **controlled** and the internal state is ignored.
127
+ * - When `controlled()` returns `undefined` the component is **uncontrolled**
128
+ * and the internal ref drives the value.
129
+ */
130
+ function useControllableState(params) {
131
+ const internalValue = ref(params.default);
132
+ const value = computed(() => {
133
+ const c = params.controlled();
134
+ return c !== void 0 ? c : internalValue.value;
135
+ });
136
+ function setValue(next) {
137
+ internalValue.value = next;
138
+ }
139
+ return {
140
+ value,
141
+ setValue
142
+ };
143
+ }
144
+
145
+ //#endregion
146
+ //#region src/collapsible/root/useCollapsibleRoot.ts
147
+ function useCollapsibleRoot(parameters) {
148
+ const { open: openParam, defaultOpen = false, onOpenChange, disabled: disabledGetter } = parameters;
149
+ const isControlled = computed(() => {
150
+ if (parameters.isOpenControlled) return parameters.isOpenControlled();
151
+ return openParam?.() !== void 0;
152
+ });
153
+ const { value: open, setValue: setOpen } = useControllableState({
154
+ controlled: () => isControlled.value ? openParam?.() : void 0,
155
+ default: defaultOpen
156
+ });
157
+ const { mounted, setMounted, transitionStatus } = useTransitionStatus(open, true, true);
158
+ const visible = ref(open.value);
159
+ const height = ref(void 0);
160
+ const width = ref(void 0);
161
+ const defaultPanelId = useBaseUiId();
162
+ const panelIdState = ref(void 0);
163
+ const panelId = computed(() => panelIdState.value ?? defaultPanelId);
164
+ const hiddenUntilFound = ref(false);
165
+ const keepMounted = ref(false);
166
+ const abortControllerRef = shallowRef(null);
167
+ const animationTypeRef = ref(null);
168
+ const transitionDimensionRef = ref(null);
169
+ const panelRef = ref(null);
170
+ const runOnceAnimationsFinish = useAnimationsFinished(panelRef, false);
171
+ const disabled = computed(() => disabledGetter());
172
+ function handleTrigger(event) {
173
+ if (disabled.value) return;
174
+ const nextOpen = !open.value;
175
+ const eventDetails = createChangeEventDetails(REASONS.triggerPress, event);
176
+ onOpenChange(nextOpen, eventDetails);
177
+ if (eventDetails.isCanceled) return;
178
+ const panel = panelRef.value;
179
+ if (nextOpen && !mounted.value) setMounted(true);
180
+ if (animationTypeRef.value === "css-animation" && panel != null) panel.style.removeProperty("animation-name");
181
+ if (!hiddenUntilFound.value && !keepMounted.value) {
182
+ if (animationTypeRef.value != null && animationTypeRef.value !== "css-animation") {
183
+ if (!mounted.value && nextOpen) setMounted(true);
184
+ }
185
+ if (animationTypeRef.value === "css-animation") {
186
+ if (!visible.value && nextOpen) visible.value = true;
187
+ if (!mounted.value && nextOpen) setMounted(true);
188
+ }
189
+ }
190
+ setOpen(nextOpen);
191
+ if (animationTypeRef.value === "none" && mounted.value && !nextOpen) setMounted(false);
192
+ }
193
+ watch(open, (isOpen) => {
194
+ if (isControlled.value && animationTypeRef.value === "none" && !keepMounted.value && !isOpen) setMounted(false);
195
+ }, { flush: "sync" });
196
+ return {
197
+ open,
198
+ disabled,
199
+ panelId,
200
+ state: computed(() => ({
201
+ open: open.value,
202
+ disabled: disabled.value,
203
+ transitionStatus: transitionStatus.value
204
+ })),
205
+ handleTrigger,
206
+ mounted,
207
+ setMounted,
208
+ transitionStatus,
209
+ height,
210
+ width,
211
+ setDimensions(dims) {
212
+ height.value = dims.height;
213
+ width.value = dims.width;
214
+ },
215
+ setOpen,
216
+ visible,
217
+ setVisible(next) {
218
+ visible.value = next;
219
+ },
220
+ keepMounted,
221
+ setKeepMounted(next) {
222
+ keepMounted.value = next;
223
+ },
224
+ hiddenUntilFound,
225
+ setHiddenUntilFound(next) {
226
+ hiddenUntilFound.value = next;
227
+ },
228
+ setPanelIdState(id) {
229
+ panelIdState.value = id;
230
+ },
231
+ animationTypeRef,
232
+ panelRef,
233
+ abortControllerRef,
234
+ transitionDimensionRef,
235
+ runOnceAnimationsFinish,
236
+ onOpenChange
237
+ };
238
+ }
239
+
240
+ //#endregion
241
+ //#region src/composite/list/CompositeListContext.ts
242
+ const compositeListContextKey = Symbol("CompositeListContext");
243
+ function useCompositeListContext() {
244
+ return inject(compositeListContextKey);
245
+ }
246
+
247
+ //#endregion
248
+ //#region src/composite/list/useCompositeListItem.ts
249
+ let IndexGuessBehavior = /* @__PURE__ */ function(IndexGuessBehavior) {
250
+ IndexGuessBehavior[IndexGuessBehavior["None"] = 0] = "None";
251
+ IndexGuessBehavior[IndexGuessBehavior["GuessFromOrder"] = 1] = "GuessFromOrder";
252
+ return IndexGuessBehavior;
253
+ }({});
254
+ /**
255
+ * Used to register a list item and its index (DOM position) in the `CompositeList`.
256
+ */
257
+ function useCompositeListItem(params = {}) {
258
+ const externalIndex = computed(() => params.index?.());
259
+ const label = computed(() => params.label?.());
260
+ const metadata = computed(() => params.metadata?.());
261
+ const textRef = computed(() => params.textRef?.());
262
+ const indexGuessBehavior = computed(() => params.indexGuessBehavior?.());
263
+ const { register, unregister, subscribeMapChange, elementsRef, labelsRef, nextIndexRef } = useCompositeListContext();
264
+ const indexRef = ref(-1);
265
+ function initializeIndex() {
266
+ if (externalIndex.value != null) return externalIndex.value;
267
+ if (indexGuessBehavior.value === IndexGuessBehavior.GuessFromOrder) {
268
+ if (indexRef.value === -1) {
269
+ const newIndex = nextIndexRef.value;
270
+ nextIndexRef.value += 1;
271
+ indexRef.value = newIndex;
272
+ }
273
+ return indexRef.value;
274
+ }
275
+ return -1;
276
+ }
277
+ const internalIndex = ref(initializeIndex());
278
+ const index = computed(() => externalIndex.value ?? internalIndex.value);
279
+ const componentRef = ref(null);
280
+ function setRef(node) {
281
+ const el = node?.$el || node;
282
+ componentRef.value = el;
283
+ if (index.value !== -1 && el !== null) {
284
+ elementsRef.value[index.value] = el;
285
+ if (labelsRef) {
286
+ const isLabelDefined = label.value !== void 0;
287
+ labelsRef.value[index.value] = isLabelDefined ? label.value : textRef.value?.value?.textContent ?? el.textContent;
288
+ }
289
+ }
290
+ }
291
+ watchEffect((onCleanup) => {
292
+ if (externalIndex.value != null) return;
293
+ const node = componentRef.value;
294
+ if (node) {
295
+ register(node, metadata.value);
296
+ onCleanup(() => {
297
+ unregister(node);
298
+ });
299
+ }
300
+ }, { flush: "post" });
301
+ watchEffect((onCleanup) => {
302
+ if (externalIndex.value != null) return;
303
+ const unsubscribe = subscribeMapChange((map) => {
304
+ const i = componentRef.value ? map.get(componentRef.value)?.index : null;
305
+ if (i != null) internalIndex.value = i;
306
+ });
307
+ onCleanup(() => {
308
+ unsubscribe();
309
+ });
310
+ }, { flush: "post" });
311
+ return {
312
+ ref: setRef,
313
+ index
314
+ };
315
+ }
316
+
317
+ //#endregion
318
+ //#region src/accordion/root/AccordionRootContext.ts
319
+ const accordionRootContextKey = Symbol("AccordionRootContext");
320
+ function useAccordionRootContext() {
321
+ const context = inject(accordionRootContextKey);
322
+ if (context === void 0) throw new Error("Base UI Vue: AccordionRootContext is missing. Accordion parts must be placed within <AccordionRoot>.");
323
+ return context;
324
+ }
325
+
326
+ //#endregion
327
+ //#region src/accordion/item/AccordionItem.vue?vue&type=script&setup=true&lang.ts
328
+ var AccordionItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
329
+ name: "AccordionItem",
330
+ inheritAttrs: false,
331
+ __name: "AccordionItem",
332
+ props: {
333
+ value: {
334
+ type: null,
335
+ required: false
336
+ },
337
+ disabled: {
338
+ type: Boolean,
339
+ required: false,
340
+ default: false
341
+ },
342
+ as: {
343
+ type: null,
344
+ required: false,
345
+ default: "div"
346
+ },
347
+ class: {
348
+ type: Function,
349
+ required: false,
350
+ skipCheck: true
351
+ },
352
+ style: {
353
+ type: [
354
+ Boolean,
355
+ null,
356
+ String,
357
+ Object,
358
+ Array,
359
+ Function
360
+ ],
361
+ required: false,
362
+ skipCheck: true
363
+ }
364
+ },
365
+ emits: ["openChange"],
366
+ setup(__props, { emit: __emit }) {
367
+ const props = __props;
368
+ const emit = __emit;
369
+ const attrs = useAttrs();
370
+ const rootCtx = useAccordionRootContext();
371
+ const { ref: listItemRef, index } = useCompositeListItem();
372
+ const fallbackValue = useBaseUiId();
373
+ const itemValue = computed(() => props.value ?? fallbackValue);
374
+ const disabled = computed(() => props.disabled || rootCtx.disabled.value);
375
+ const isOpen = computed(() => {
376
+ const values = rootCtx.value.value;
377
+ if (!values) return false;
378
+ for (let i = 0; i < values.length; i += 1) if (values[i] === itemValue.value) return true;
379
+ return false;
380
+ });
381
+ function onOpenChange(nextOpen, eventDetails) {
382
+ emit("openChange", nextOpen, eventDetails);
383
+ if (eventDetails.isCanceled) return;
384
+ rootCtx.handleValueChange(itemValue.value, nextOpen);
385
+ }
386
+ const collapsible = useCollapsibleRoot({
387
+ open: () => isOpen.value,
388
+ isOpenControlled: () => true,
389
+ defaultOpen: false,
390
+ onOpenChange,
391
+ disabled: () => disabled.value
392
+ });
393
+ const collapsibleState = computed(() => ({
394
+ open: collapsible.open.value,
395
+ disabled: collapsible.disabled.value,
396
+ transitionStatus: collapsible.transitionStatus.value
397
+ }));
398
+ const state = computed(() => ({
399
+ ...rootCtx.state.value,
400
+ index: index.value,
401
+ disabled: disabled.value,
402
+ open: isOpen.value
403
+ }));
404
+ const triggerId = ref(useBaseUiId());
405
+ function setTriggerId(id) {
406
+ triggerId.value = id;
407
+ }
408
+ provide(collapsibleRootContextKey, {
409
+ ...collapsible,
410
+ onOpenChange,
411
+ state: collapsibleState
412
+ });
413
+ provide(accordionItemContextKey, {
414
+ open: isOpen,
415
+ state,
416
+ setTriggerId,
417
+ triggerId
418
+ });
419
+ const mergedRef = useMergedRefs(ref(null), listItemRef);
420
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
421
+ componentProps: props,
422
+ state,
423
+ props: computed(() => ({ ...attrs })),
424
+ stateAttributesMapping: accordionStateAttributesMapping,
425
+ defaultTagName: "div",
426
+ ref: mergedRef
427
+ });
428
+ return (_ctx, _cache) => {
429
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
430
+ key: 0,
431
+ ref: unref(renderRef),
432
+ props: unref(mergedProps),
433
+ state: state.value
434
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
435
+ key: 1,
436
+ ref: unref(renderRef)
437
+ }, unref(mergedProps)), {
438
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
439
+ _: 3
440
+ }, 16));
441
+ };
442
+ }
443
+ });
444
+
445
+ //#endregion
446
+ //#region src/accordion/item/AccordionItem.vue
447
+ var AccordionItem_default = AccordionItem_vue_vue_type_script_setup_true_lang_default;
448
+
449
+ //#endregion
450
+ //#region src/utils/warn.ts
451
+ let set;
452
+ if (process.env.NODE_ENV !== "production") set = /* @__PURE__ */ new Set();
453
+ function warn(...messages) {
454
+ if (process.env.NODE_ENV !== "production") {
455
+ const messageKey = messages.join(" ");
456
+ if (!set.has(messageKey)) {
457
+ set.add(messageKey);
458
+ console.warn(`Base UI Vue: ${messageKey}`);
459
+ }
460
+ }
461
+ }
462
+
463
+ //#endregion
464
+ //#region src/collapsible/panel/useCollapsiblePanel.ts
465
+ function useCollapsiblePanel(parameters) {
466
+ const { abortControllerRef, animationTypeRef, height, hiddenUntilFound, keepMounted, mounted, onOpenChange, open, panelRef, runOnceAnimationsFinish, setDimensions, setMounted, setOpen, setVisible, transitionDimensionRef, visible, width, externalRef } = parameters;
467
+ const isBeforeMatchRef = ref(false);
468
+ const latestAnimationNameRef = ref(null);
469
+ const shouldCancelInitialOpenAnimationRef = ref(open.value);
470
+ const shouldCancelInitialOpenTransitionRef = ref(open.value);
471
+ const endingStyleFrame = useAnimationFrame();
472
+ /**
473
+ * When opening, the `hidden` attribute is removed immediately.
474
+ * When closing, the `hidden` attribute is set after any exit animations runs.
475
+ */
476
+ const hidden = computed(() => {
477
+ if (animationTypeRef.value === "css-animation") return !visible.value;
478
+ return !open.value && !mounted.value;
479
+ });
480
+ /**
481
+ * When `keepMounted` is `true` this runs once as soon as it exists in the DOM
482
+ * regardless of initial open state.
483
+ *
484
+ * When `keepMounted` is `false` this runs on every mount, typically every
485
+ * time it opens. If the panel is in the middle of a close transition that is
486
+ * interrupted and re-opens, this won't run as the panel was not unmounted.
487
+ */
488
+ function handlePanelRef(element) {
489
+ if (!element) return;
490
+ if (animationTypeRef.value == null || transitionDimensionRef.value == null) {
491
+ const panelStyles = getComputedStyle(element);
492
+ const hasAnimation = panelStyles.animationName !== "none" && panelStyles.animationName !== "";
493
+ const hasTransition = panelStyles.transitionDuration !== "0s" && panelStyles.transitionDuration !== "";
494
+ if (hasAnimation && hasTransition) {
495
+ if (process.env.NODE_ENV !== "production") warn("CSS transitions and CSS animations both detected on Collapsible or Accordion panel.", "Only one of either animation type should be used.");
496
+ } else if (panelStyles.animationName === "none" && panelStyles.transitionDuration !== "0s") animationTypeRef.value = "css-transition";
497
+ else if (panelStyles.animationName !== "none" && panelStyles.transitionDuration === "0s") animationTypeRef.value = "css-animation";
498
+ else animationTypeRef.value = "none";
499
+ /**
500
+ * We need to know in advance which side is being collapsed when using CSS
501
+ * transitions in order to set the value of width/height to `0px` momentarily.
502
+ * Setting both to `0px` will break layout.
503
+ */
504
+ if (element.getAttribute("data-orientation") === "horizontal" || panelStyles.transitionProperty.includes("width")) transitionDimensionRef.value = "width";
505
+ else transitionDimensionRef.value = "height";
506
+ }
507
+ if (animationTypeRef.value !== "css-transition") return;
508
+ if (height.value === void 0 || width.value === void 0) {
509
+ setDimensions({
510
+ height: element.scrollHeight,
511
+ width: element.scrollWidth
512
+ });
513
+ if (shouldCancelInitialOpenTransitionRef.value) element.style.setProperty("transition-duration", "0s");
514
+ }
515
+ let frame = -1;
516
+ let nextFrame = -1;
517
+ frame = AnimationFrame.request(() => {
518
+ shouldCancelInitialOpenTransitionRef.value = false;
519
+ nextFrame = AnimationFrame.request(() => {
520
+ /**
521
+ * This is slightly faster than another RAF and is the earliest
522
+ * opportunity to remove the temporary `transition-duration: 0s` that
523
+ * was applied to cancel opening transitions of initially open panels.
524
+ * https://nolanlawson.com/2018/09/25/accurately-measuring-layout-on-the-web/
525
+ */
526
+ setTimeout(() => {
527
+ element.style.removeProperty("transition-duration");
528
+ });
529
+ });
530
+ });
531
+ return () => {
532
+ AnimationFrame.cancel(frame);
533
+ AnimationFrame.cancel(nextFrame);
534
+ };
535
+ }
536
+ const mergedRef = useMergedRefs(externalRef ?? null, panelRef, handlePanelRef);
537
+ watch(open, (isOpen) => {
538
+ if (animationTypeRef.value !== "css-transition") return;
539
+ const panel = panelRef.value;
540
+ if (!panel) return;
541
+ if (abortControllerRef.value != null) {
542
+ abortControllerRef.value.abort();
543
+ abortControllerRef.value = null;
544
+ }
545
+ if (isOpen) {
546
+ const originalLayoutStyles = {
547
+ "justify-content": panel.style.justifyContent,
548
+ "align-items": panel.style.alignItems,
549
+ "align-content": panel.style.alignContent,
550
+ "justify-items": panel.style.justifyItems
551
+ };
552
+ Object.keys(originalLayoutStyles).forEach((key) => {
553
+ panel.style.setProperty(key, "initial", "important");
554
+ });
555
+ /**
556
+ * When `:keepMounted="false"` and the panel is initially closed, the very
557
+ * first time it opens (not any subsequent opens) `data-starting-style` is
558
+ * off or missing by a frame so we need to set it manually. Otherwise any
559
+ * CSS properties expected to transition using [data-starting-style] may
560
+ * be mis-timed and appear to be complete skipped.
561
+ */
562
+ if (!shouldCancelInitialOpenTransitionRef.value && !keepMounted) panel.setAttribute(CollapsiblePanelDataAttributes.startingStyle, "");
563
+ setDimensions({
564
+ height: panel.scrollHeight,
565
+ width: panel.scrollWidth
566
+ });
567
+ const resizeFrame = AnimationFrame.request(() => {
568
+ Object.entries(originalLayoutStyles).forEach(([key, value]) => {
569
+ if (value === "") panel.style.removeProperty(key);
570
+ else panel.style.setProperty(key, value);
571
+ });
572
+ });
573
+ return () => {
574
+ AnimationFrame.cancel(resizeFrame);
575
+ };
576
+ } else {
577
+ if (panel.scrollHeight === 0 && panel.scrollWidth === 0) return;
578
+ setDimensions({
579
+ height: panel.scrollHeight,
580
+ width: panel.scrollWidth
581
+ });
582
+ const abortController = new AbortController();
583
+ abortControllerRef.value = abortController;
584
+ const signal = abortController.signal;
585
+ let attributeObserver = null;
586
+ const endingStyleAttribute = CollapsiblePanelDataAttributes.endingStyle;
587
+ attributeObserver = new MutationObserver((mutationList) => {
588
+ if (mutationList.some((mutation) => mutation.type === "attributes" && mutation.attributeName === endingStyleAttribute)) {
589
+ attributeObserver?.disconnect();
590
+ attributeObserver = null;
591
+ runOnceAnimationsFinish(() => {
592
+ setDimensions({
593
+ height: 0,
594
+ width: 0
595
+ });
596
+ panel.style.removeProperty("content-visibility");
597
+ setMounted(false);
598
+ if (abortControllerRef.value === abortController) abortControllerRef.value = null;
599
+ }, signal);
600
+ }
601
+ });
602
+ attributeObserver.observe(panel, {
603
+ attributes: true,
604
+ attributeFilter: [endingStyleAttribute]
605
+ });
606
+ return () => {
607
+ attributeObserver?.disconnect();
608
+ endingStyleFrame.cancel();
609
+ if (abortControllerRef.value === abortController) {
610
+ abortController.abort();
611
+ abortControllerRef.value = null;
612
+ }
613
+ };
614
+ }
615
+ }, { flush: "post" });
616
+ watch(open, (isOpen) => {
617
+ if (animationTypeRef.value !== "css-animation") return;
618
+ const panel = panelRef.value;
619
+ if (!panel) return;
620
+ latestAnimationNameRef.value = panel.style.animationName || latestAnimationNameRef.value;
621
+ panel.style.setProperty("animation-name", "none");
622
+ setDimensions({
623
+ height: panel.scrollHeight,
624
+ width: panel.scrollWidth
625
+ });
626
+ if (!shouldCancelInitialOpenAnimationRef.value && !isBeforeMatchRef.value) panel.style.removeProperty("animation-name");
627
+ if (isOpen) {
628
+ if (abortControllerRef.value != null) {
629
+ abortControllerRef.value.abort();
630
+ abortControllerRef.value = null;
631
+ }
632
+ setMounted(true);
633
+ setVisible(true);
634
+ } else {
635
+ abortControllerRef.value = new AbortController();
636
+ runOnceAnimationsFinish(() => {
637
+ setMounted(false);
638
+ setVisible(false);
639
+ abortControllerRef.value = null;
640
+ }, abortControllerRef.value.signal);
641
+ }
642
+ }, { flush: "post" });
643
+ onMounted(() => {
644
+ const frame = AnimationFrame.request(() => {
645
+ shouldCancelInitialOpenAnimationRef.value = false;
646
+ });
647
+ return () => AnimationFrame.cancel(frame);
648
+ });
649
+ watch([open, () => hiddenUntilFound], ([isOpen]) => {
650
+ if (!hiddenUntilFound) return;
651
+ const panel = panelRef.value;
652
+ if (!panel) return;
653
+ if (isOpen && isBeforeMatchRef.value) {
654
+ panel.style.transitionDuration = "0s";
655
+ setDimensions({
656
+ height: panel.scrollHeight,
657
+ width: panel.scrollWidth
658
+ });
659
+ let nextFrame = -1;
660
+ const frame = AnimationFrame.request(() => {
661
+ isBeforeMatchRef.value = false;
662
+ nextFrame = AnimationFrame.request(() => {
663
+ setTimeout(() => {
664
+ panel.style.removeProperty("transition-duration");
665
+ });
666
+ });
667
+ });
668
+ return () => {
669
+ AnimationFrame.cancel(frame);
670
+ AnimationFrame.cancel(nextFrame);
671
+ };
672
+ }
673
+ }, { flush: "sync" });
674
+ watch([hidden, () => hiddenUntilFound], ([isHidden]) => {
675
+ const panel = panelRef.value;
676
+ if (!panel || !hiddenUntilFound) return;
677
+ if (isHidden) {
678
+ panel.setAttribute("hidden", "until-found");
679
+ /**
680
+ * Set data-starting-style here to persist the closed styles, this is to
681
+ * prevent transitions from starting when the `hidden` attribute changes
682
+ * to `'until-found'` as they could have different `display` properties:
683
+ * https://github.com/tailwindlabs/tailwindcss/pull/14625
684
+ */
685
+ if (animationTypeRef.value === "css-transition") panel.setAttribute(CollapsiblePanelDataAttributes.startingStyle, "");
686
+ } else panel.removeAttribute("hidden");
687
+ }, { flush: "post" });
688
+ let beforeMatchCleanup = null;
689
+ function setupBeforeMatchListener() {
690
+ beforeMatchCleanup?.();
691
+ beforeMatchCleanup = null;
692
+ const panel = panelRef.value;
693
+ if (!panel) return;
694
+ function handleBeforeMatch(event) {
695
+ isBeforeMatchRef.value = true;
696
+ setOpen(true);
697
+ onOpenChange(true, createChangeEventDetails(REASONS.none, event));
698
+ }
699
+ panel.addEventListener("beforematch", handleBeforeMatch);
700
+ beforeMatchCleanup = () => {
701
+ panel.removeEventListener("beforematch", handleBeforeMatch);
702
+ };
703
+ }
704
+ watch(panelRef, () => setupBeforeMatchListener(), { flush: "post" });
705
+ onMounted(setupBeforeMatchListener);
706
+ onUnmounted(() => {
707
+ beforeMatchCleanup?.();
708
+ endingStyleFrame.cancel();
709
+ });
710
+ return {
711
+ hidden,
712
+ panelRef: mergedRef
713
+ };
714
+ }
715
+
716
+ //#endregion
717
+ //#region src/accordion/panel/AccordionPanelCssVars.ts
718
+ let AccordionPanelCssVars = /* @__PURE__ */ function(AccordionPanelCssVars) {
719
+ /**
720
+ * The accordion panel's height.
721
+ * @type {number}
722
+ */
723
+ AccordionPanelCssVars["accordionPanelHeight"] = "--accordion-panel-height";
724
+ /**
725
+ * The accordion panel's width.
726
+ * @type {number}
727
+ */
728
+ AccordionPanelCssVars["accordionPanelWidth"] = "--accordion-panel-width";
729
+ return AccordionPanelCssVars;
730
+ }({});
731
+
732
+ //#endregion
733
+ //#region src/accordion/panel/AccordionPanel.vue?vue&type=script&setup=true&lang.ts
734
+ var AccordionPanel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
735
+ name: "AccordionPanel",
736
+ inheritAttrs: false,
737
+ __name: "AccordionPanel",
738
+ props: {
739
+ hiddenUntilFound: {
740
+ type: Boolean,
741
+ required: false
742
+ },
743
+ keepMounted: {
744
+ type: Boolean,
745
+ required: false
746
+ },
747
+ id: {
748
+ type: String,
749
+ required: false
750
+ },
751
+ as: {
752
+ type: null,
753
+ required: false,
754
+ default: "div"
755
+ },
756
+ class: {
757
+ type: Function,
758
+ required: false,
759
+ skipCheck: true
760
+ },
761
+ style: {
762
+ type: [
763
+ Boolean,
764
+ null,
765
+ String,
766
+ Object,
767
+ Array,
768
+ Function
769
+ ],
770
+ required: false,
771
+ skipCheck: true
772
+ }
773
+ },
774
+ setup(__props) {
775
+ const props = __props;
776
+ const attrs = useAttrs();
777
+ const rootCtx = useAccordionRootContext();
778
+ const collapsibleCtx = useCollapsibleRootContext();
779
+ const itemCtx = useAccordionItemContext();
780
+ const hiddenUntilFound = computed(() => rootCtx.hiddenUntilFound.value || props.hiddenUntilFound);
781
+ const keepMounted = computed(() => rootCtx.keepMounted.value || props.keepMounted);
782
+ if (process.env.NODE_ENV !== "production") watchEffect(() => {
783
+ if (keepMounted.value === false && hiddenUntilFound.value) warn("The `:keepMounted=\"false\"` prop on a AccordionPanel will be ignored when using `hiddenUntilFound` on the Panel or the Root since it requires the panel to remain mounted when closed.");
784
+ });
785
+ watch(() => props.id, (id) => {
786
+ if (id) collapsibleCtx.setPanelIdState(id);
787
+ }, {
788
+ immediate: true,
789
+ flush: "sync"
790
+ });
791
+ onBeforeUnmount(() => {
792
+ collapsibleCtx.setPanelIdState(void 0);
793
+ });
794
+ watch(hiddenUntilFound, (val) => collapsibleCtx.setHiddenUntilFound(val), { immediate: true });
795
+ watch(keepMounted, (val) => collapsibleCtx.setKeepMounted(val), { immediate: true });
796
+ useOpenChangeComplete({
797
+ open: computed(() => collapsibleCtx.open.value && collapsibleCtx.transitionStatus.value === "idle"),
798
+ ref: collapsibleCtx.panelRef,
799
+ onComplete() {
800
+ if (!collapsibleCtx.open.value) return;
801
+ collapsibleCtx.setDimensions({
802
+ width: void 0,
803
+ height: void 0
804
+ });
805
+ }
806
+ });
807
+ const { hidden, panelRef } = useCollapsiblePanel({
808
+ abortControllerRef: collapsibleCtx.abortControllerRef,
809
+ animationTypeRef: collapsibleCtx.animationTypeRef,
810
+ height: collapsibleCtx.height,
811
+ hiddenUntilFound: hiddenUntilFound.value,
812
+ id: computed(() => props.id ?? collapsibleCtx.panelId.value),
813
+ keepMounted: keepMounted.value,
814
+ mounted: collapsibleCtx.mounted,
815
+ onOpenChange: collapsibleCtx.onOpenChange,
816
+ open: collapsibleCtx.open,
817
+ panelRef: collapsibleCtx.panelRef,
818
+ runOnceAnimationsFinish: collapsibleCtx.runOnceAnimationsFinish,
819
+ setDimensions: collapsibleCtx.setDimensions,
820
+ setMounted: collapsibleCtx.setMounted,
821
+ setOpen: collapsibleCtx.setOpen,
822
+ setVisible: collapsibleCtx.setVisible,
823
+ transitionDimensionRef: collapsibleCtx.transitionDimensionRef,
824
+ visible: collapsibleCtx.visible,
825
+ width: collapsibleCtx.width
826
+ });
827
+ const panelState = computed(() => ({
828
+ ...itemCtx.state.value,
829
+ transitionStatus: collapsibleCtx.transitionStatus.value
830
+ }));
831
+ const shouldRender = computed(() => keepMounted.value || hiddenUntilFound.value || collapsibleCtx.mounted.value);
832
+ const panelProps = computed(() => {
833
+ const heightVal = collapsibleCtx.height.value;
834
+ const widthVal = collapsibleCtx.width.value;
835
+ const resolvedStyle = typeof props.style === "function" ? props.style(panelState.value) : props.style;
836
+ return {
837
+ ...attrs,
838
+ "id": collapsibleCtx.panelId.value,
839
+ "aria-labelledby": itemCtx.triggerId.value,
840
+ "role": "region",
841
+ "hidden": hiddenUntilFound.value ? void 0 : hidden.value ? true : void 0,
842
+ "style": [resolvedStyle, {
843
+ [AccordionPanelCssVars.accordionPanelHeight]: heightVal === void 0 ? "auto" : `${heightVal}px`,
844
+ [AccordionPanelCssVars.accordionPanelWidth]: widthVal === void 0 ? "auto" : `${widthVal}px`
845
+ }]
846
+ };
847
+ });
848
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
849
+ componentProps: {
850
+ as: props.as,
851
+ class: props.class
852
+ },
853
+ state: panelState,
854
+ props: panelProps,
855
+ stateAttributesMapping: accordionStateAttributesMapping,
856
+ defaultTagName: "div",
857
+ ref: panelRef
858
+ });
859
+ return (_ctx, _cache) => {
860
+ return unref(renderless) && shouldRender.value ? renderSlot(_ctx.$slots, "default", {
861
+ key: 0,
862
+ ref: unref(renderRef),
863
+ props: unref(mergedProps),
864
+ state: panelState.value
865
+ }) : shouldRender.value ? (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
866
+ key: 1,
867
+ ref: unref(renderRef)
868
+ }, unref(mergedProps)), {
869
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: panelState.value })]),
870
+ _: 3
871
+ }, 16)) : createCommentVNode("v-if", true);
872
+ };
873
+ }
874
+ });
875
+
876
+ //#endregion
877
+ //#region src/accordion/panel/AccordionPanel.vue
878
+ var AccordionPanel_default = AccordionPanel_vue_vue_type_script_setup_true_lang_default;
879
+
880
+ //#endregion
881
+ //#region src/composite/list/CompositeList.vue?vue&type=script&setup=true&lang.ts
882
+ var CompositeList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
883
+ __name: "CompositeList",
884
+ props: {
885
+ elementsRef: {
886
+ type: Object,
887
+ required: true
888
+ },
889
+ labelsRef: {
890
+ type: null,
891
+ required: false
892
+ },
893
+ onMapChange: {
894
+ type: Function,
895
+ required: false
896
+ }
897
+ },
898
+ setup(__props) {
899
+ const props = __props;
900
+ const nextIndexRef = ref(0);
901
+ const listeners = ref(/* @__PURE__ */ new Set());
902
+ const map = shallowRef(/* @__PURE__ */ new Map());
903
+ const mapTick = ref(0);
904
+ let lastTick = 0;
905
+ function register(node, metadata) {
906
+ map.value.set(node, metadata);
907
+ lastTick += 1;
908
+ mapTick.value = lastTick;
909
+ }
910
+ function unregister(node) {
911
+ map.value.delete(node);
912
+ lastTick += 1;
913
+ mapTick.value = lastTick;
914
+ }
915
+ function sortByDocumentPosition(a, b) {
916
+ const position = a.compareDocumentPosition(b);
917
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING || position & Node.DOCUMENT_POSITION_CONTAINED_BY) return -1;
918
+ if (position & Node.DOCUMENT_POSITION_PRECEDING || position & Node.DOCUMENT_POSITION_CONTAINS) return 1;
919
+ return 0;
920
+ }
921
+ const sortedMap = computed(() => {
922
+ mapTick.value;
923
+ const newMap = /* @__PURE__ */ new Map();
924
+ Array.from(map.value.keys()).filter((node) => node.isConnected).sort(sortByDocumentPosition).forEach((node, index) => {
925
+ const metadata = map.value.get(node) ?? {};
926
+ newMap.set(node, {
927
+ ...metadata,
928
+ index
929
+ });
930
+ });
931
+ return newMap;
932
+ });
933
+ let observer = null;
934
+ watch(sortedMap, (newSortedMap) => {
935
+ if (typeof MutationObserver !== "function" || newSortedMap.size === 0) {
936
+ if (observer) {
937
+ observer.disconnect();
938
+ observer = null;
939
+ }
940
+ return;
941
+ }
942
+ if (!observer) observer = new MutationObserver((entries) => {
943
+ const diff = /* @__PURE__ */ new Set();
944
+ const updateDiff = (node) => diff.has(node) ? diff.delete(node) : diff.add(node);
945
+ entries.forEach((entry) => {
946
+ entry.removedNodes.forEach(updateDiff);
947
+ entry.addedNodes.forEach(updateDiff);
948
+ });
949
+ if (diff.size === 0) {
950
+ lastTick += 1;
951
+ mapTick.value = lastTick;
952
+ }
953
+ });
954
+ else observer.disconnect();
955
+ newSortedMap.forEach((_, node) => {
956
+ if (node.parentElement) observer.observe(node.parentElement, { childList: true });
957
+ });
958
+ }, {
959
+ immediate: true,
960
+ flush: "post"
961
+ });
962
+ onBeforeUnmount(() => {
963
+ if (observer) observer.disconnect();
964
+ });
965
+ watch(sortedMap, (newSortedMap) => {
966
+ if (lastTick === mapTick.value) {
967
+ if (props.elementsRef.value.length !== newSortedMap.size) props.elementsRef.value.length = newSortedMap.size;
968
+ if (props.labelsRef && props.labelsRef.value.length !== newSortedMap.size) props.labelsRef.value.length = newSortedMap.size;
969
+ nextIndexRef.value = newSortedMap.size;
970
+ }
971
+ if (props.onMapChange) props.onMapChange(newSortedMap);
972
+ listeners.value.forEach((l) => l(newSortedMap));
973
+ }, {
974
+ immediate: true,
975
+ flush: "post"
976
+ });
977
+ onBeforeUnmount(() => {
978
+ if (props.elementsRef) props.elementsRef.value = [];
979
+ if (props.labelsRef) props.labelsRef.value = [];
980
+ });
981
+ function subscribeMapChange(fn) {
982
+ listeners.value.add(fn);
983
+ return () => {
984
+ listeners.value.delete(fn);
985
+ };
986
+ }
987
+ provide(compositeListContextKey, {
988
+ register,
989
+ unregister,
990
+ subscribeMapChange,
991
+ elementsRef: props.elementsRef,
992
+ labelsRef: props.labelsRef,
993
+ nextIndexRef
994
+ });
995
+ return (_ctx, _cache) => {
996
+ return renderSlot(_ctx.$slots, "default");
997
+ };
998
+ }
999
+ });
1000
+
1001
+ //#endregion
1002
+ //#region src/composite/list/CompositeList.vue
1003
+ var CompositeList_default = CompositeList_vue_vue_type_script_setup_true_lang_default;
1004
+
1005
+ //#endregion
1006
+ //#region src/accordion/root/stateAttributesMapping.ts
1007
+ const rootStateAttributesMapping = { value: () => null };
1008
+
1009
+ //#endregion
1010
+ //#region src/accordion/root/AccordionRoot.vue?vue&type=script&setup=true&lang.ts
1011
+ var AccordionRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1012
+ name: "AccordionRoot",
1013
+ inheritAttrs: false,
1014
+ __name: "AccordionRoot",
1015
+ props: {
1016
+ value: {
1017
+ type: Array,
1018
+ required: false
1019
+ },
1020
+ defaultValue: {
1021
+ type: Array,
1022
+ required: false
1023
+ },
1024
+ disabled: {
1025
+ type: Boolean,
1026
+ required: false,
1027
+ default: false
1028
+ },
1029
+ hiddenUntilFound: {
1030
+ type: Boolean,
1031
+ required: false,
1032
+ default: false
1033
+ },
1034
+ keepMounted: {
1035
+ type: Boolean,
1036
+ required: false,
1037
+ default: false
1038
+ },
1039
+ loopFocus: {
1040
+ type: Boolean,
1041
+ required: false,
1042
+ default: true
1043
+ },
1044
+ multiple: {
1045
+ type: Boolean,
1046
+ required: false,
1047
+ default: false
1048
+ },
1049
+ orientation: {
1050
+ type: String,
1051
+ required: false,
1052
+ default: "vertical"
1053
+ },
1054
+ as: {
1055
+ type: null,
1056
+ required: false,
1057
+ default: "div"
1058
+ },
1059
+ class: {
1060
+ type: Function,
1061
+ required: false,
1062
+ skipCheck: true
1063
+ },
1064
+ style: {
1065
+ type: [
1066
+ Boolean,
1067
+ null,
1068
+ String,
1069
+ Object,
1070
+ Array,
1071
+ Function
1072
+ ],
1073
+ required: false,
1074
+ skipCheck: true
1075
+ }
1076
+ },
1077
+ emits: ["valueChange"],
1078
+ setup(__props, { emit: __emit }) {
1079
+ const props = __props;
1080
+ const emit = __emit;
1081
+ const attrs = useAttrs();
1082
+ const direction = useDirection();
1083
+ const instance = getCurrentInstance();
1084
+ if (process.env.NODE_ENV !== "production") watchEffect(() => {
1085
+ if (props.hiddenUntilFound && props.keepMounted === false) warn("The `:keepMounted=\"false\"` prop on a AccordionRoot will be ignored when using `hiddenUntilFound` since it requires Panels to remain mounted when closed.");
1086
+ });
1087
+ const isValueControlled = computed(() => {
1088
+ const vnodeProps = instance?.vnode.props;
1089
+ return Boolean(vnodeProps && "value" in vnodeProps);
1090
+ });
1091
+ const _compositeRefs = { elementsRef: ref([]) };
1092
+ const accordionItemRefs = _compositeRefs.elementsRef;
1093
+ const { value: openValues, setValue: setOpenValues } = useControllableState({
1094
+ controlled: () => isValueControlled.value ? props.value : void 0,
1095
+ default: props.defaultValue ?? []
1096
+ });
1097
+ function handleValueChange(newValue, nextOpen) {
1098
+ const details = createChangeEventDetails(REASONS.none);
1099
+ if (!props.multiple) {
1100
+ const nextValue = openValues.value[0] === newValue ? [] : [newValue];
1101
+ emit("valueChange", nextValue, details);
1102
+ if (details.isCanceled) return;
1103
+ setOpenValues(nextValue);
1104
+ } else if (nextOpen) {
1105
+ const nextOpenValues = openValues.value.slice();
1106
+ nextOpenValues.push(newValue);
1107
+ emit("valueChange", nextOpenValues, details);
1108
+ if (details.isCanceled) return;
1109
+ setOpenValues(nextOpenValues);
1110
+ } else {
1111
+ const nextOpenValues = openValues.value.filter((v) => v !== newValue);
1112
+ emit("valueChange", nextOpenValues, details);
1113
+ if (details.isCanceled) return;
1114
+ setOpenValues(nextOpenValues);
1115
+ }
1116
+ }
1117
+ const state = computed(() => ({
1118
+ value: openValues.value,
1119
+ disabled: props.disabled,
1120
+ orientation: props.orientation
1121
+ }));
1122
+ provide(accordionRootContextKey, {
1123
+ accordionItemRefs,
1124
+ direction,
1125
+ disabled: computed(() => props.disabled),
1126
+ handleValueChange,
1127
+ hiddenUntilFound: computed(() => props.hiddenUntilFound),
1128
+ keepMounted: computed(() => props.keepMounted),
1129
+ loopFocus: computed(() => props.loopFocus),
1130
+ orientation: computed(() => props.orientation),
1131
+ state,
1132
+ value: openValues
1133
+ });
1134
+ const { tag, mergedProps, renderless } = useRenderElement({
1135
+ componentProps: props,
1136
+ state,
1137
+ props: computed(() => ({
1138
+ ...attrs,
1139
+ dir: direction.value,
1140
+ role: "region"
1141
+ })),
1142
+ stateAttributesMapping: rootStateAttributesMapping,
1143
+ defaultTagName: "div"
1144
+ });
1145
+ return (_ctx, _cache) => {
1146
+ return openBlock(), createBlock(CompositeList_default, { "elements-ref": _compositeRefs.elementsRef }, {
1147
+ default: withCtx(() => [unref(renderless) ? renderSlot(_ctx.$slots, "default", {
1148
+ key: 0,
1149
+ props: unref(mergedProps),
1150
+ state: state.value
1151
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
1152
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
1153
+ _: 3
1154
+ }, 16))]),
1155
+ _: 3
1156
+ }, 8, ["elements-ref"]);
1157
+ };
1158
+ }
1159
+ });
1160
+
1161
+ //#endregion
1162
+ //#region src/accordion/root/AccordionRoot.vue
1163
+ var AccordionRoot_default = AccordionRoot_vue_vue_type_script_setup_true_lang_default;
1164
+
1165
+ //#endregion
1166
+ //#region src/floating-ui-vue/utils/event.ts
1167
+ function stopEvent(event) {
1168
+ event.preventDefault();
1169
+ event.stopPropagation();
1170
+ }
1171
+
1172
+ //#endregion
1173
+ //#region src/utils/isElementDisabled.ts
1174
+ function isElementDisabled(element) {
1175
+ return element == null || element.hasAttribute("disabled") || element.getAttribute("aria-disabled") === "true";
1176
+ }
1177
+
1178
+ //#endregion
1179
+ //#region src/accordion/trigger/AccordionTrigger.vue?vue&type=script&setup=true&lang.ts
1180
+ var AccordionTrigger_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1181
+ name: "AccordionTrigger",
1182
+ inheritAttrs: false,
1183
+ __name: "AccordionTrigger",
1184
+ props: {
1185
+ disabled: {
1186
+ type: Boolean,
1187
+ required: false
1188
+ },
1189
+ id: {
1190
+ type: String,
1191
+ required: false
1192
+ },
1193
+ nativeButton: {
1194
+ type: Boolean,
1195
+ required: false,
1196
+ default: true
1197
+ },
1198
+ as: {
1199
+ type: null,
1200
+ required: false,
1201
+ default: "button"
1202
+ },
1203
+ class: {
1204
+ type: Function,
1205
+ required: false,
1206
+ skipCheck: true
1207
+ },
1208
+ style: {
1209
+ type: [
1210
+ Boolean,
1211
+ null,
1212
+ String,
1213
+ Object,
1214
+ Array,
1215
+ Function
1216
+ ],
1217
+ required: false,
1218
+ skipCheck: true
1219
+ }
1220
+ },
1221
+ setup(__props) {
1222
+ const props = __props;
1223
+ const attrs = useAttrs();
1224
+ const collapsibleCtx = useCollapsibleRootContext();
1225
+ const rootCtx = useAccordionRootContext();
1226
+ const itemCtx = useAccordionItemContext();
1227
+ const disabled = computed(() => collapsibleCtx.disabled.value || props.disabled);
1228
+ const { getButtonProps, buttonRef } = useButton({
1229
+ disabled: () => disabled.value,
1230
+ focusableWhenDisabled: () => true,
1231
+ native: () => props.nativeButton ?? true
1232
+ });
1233
+ watch(() => props.id, (id) => {
1234
+ if (id) itemCtx.setTriggerId(id);
1235
+ }, { immediate: true });
1236
+ onBeforeUnmount(() => {
1237
+ itemCtx.setTriggerId(void 0);
1238
+ });
1239
+ const SUPPORTED_KEYS = new Set([
1240
+ ARROW_DOWN,
1241
+ ARROW_UP,
1242
+ ARROW_RIGHT,
1243
+ ARROW_LEFT,
1244
+ HOME,
1245
+ END
1246
+ ]);
1247
+ function getActiveTriggers() {
1248
+ const accordionItemElements = rootCtx.accordionItemRefs.value;
1249
+ const output = [];
1250
+ for (let i = 0; i < accordionItemElements.length; i += 1) {
1251
+ const section = accordionItemElements[i];
1252
+ if (!isElementDisabled(section)) {
1253
+ const trigger = section?.querySelector("[type=\"button\"], [role=\"button\"]");
1254
+ if (trigger && !isElementDisabled(trigger)) output.push(trigger);
1255
+ }
1256
+ }
1257
+ return output;
1258
+ }
1259
+ function handleKeyDown(event) {
1260
+ if (!SUPPORTED_KEYS.has(event.key)) return;
1261
+ stopEvent(event);
1262
+ const triggers = getActiveTriggers();
1263
+ const lastIndex = triggers.length - 1;
1264
+ let nextIndex = -1;
1265
+ const thisIndex = triggers.indexOf(event.target);
1266
+ const isRtl = rootCtx.direction.value === "rtl";
1267
+ const isHorizontal = rootCtx.orientation.value === "horizontal";
1268
+ const loopFocus = rootCtx.loopFocus.value;
1269
+ function toNext() {
1270
+ if (loopFocus) nextIndex = thisIndex + 1 > lastIndex ? 0 : thisIndex + 1;
1271
+ else nextIndex = Math.min(thisIndex + 1, lastIndex);
1272
+ }
1273
+ function toPrev() {
1274
+ if (loopFocus) nextIndex = thisIndex === 0 ? lastIndex : thisIndex - 1;
1275
+ else nextIndex = thisIndex - 1;
1276
+ }
1277
+ switch (event.key) {
1278
+ case ARROW_DOWN:
1279
+ if (!isHorizontal) toNext();
1280
+ break;
1281
+ case ARROW_UP:
1282
+ if (!isHorizontal) toPrev();
1283
+ break;
1284
+ case ARROW_RIGHT:
1285
+ if (isHorizontal) if (isRtl) toPrev();
1286
+ else toNext();
1287
+ break;
1288
+ case ARROW_LEFT:
1289
+ if (isHorizontal) if (isRtl) toNext();
1290
+ else toPrev();
1291
+ break;
1292
+ case HOME:
1293
+ nextIndex = 0;
1294
+ break;
1295
+ case END:
1296
+ nextIndex = lastIndex;
1297
+ break;
1298
+ default: break;
1299
+ }
1300
+ if (nextIndex > -1) triggers[nextIndex].focus();
1301
+ }
1302
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
1303
+ componentProps: props,
1304
+ state: itemCtx.state,
1305
+ props: computed(() => getButtonProps({
1306
+ ...attrs,
1307
+ "id": itemCtx.triggerId.value,
1308
+ "aria-controls": collapsibleCtx.open.value ? collapsibleCtx.panelId.value : void 0,
1309
+ "aria-expanded": collapsibleCtx.open.value,
1310
+ "onClick": collapsibleCtx.handleTrigger,
1311
+ "onKeydown": handleKeyDown
1312
+ })),
1313
+ stateAttributesMapping: triggerOpenStateMapping,
1314
+ defaultTagName: "button",
1315
+ ref: buttonRef
1316
+ });
1317
+ return (_ctx, _cache) => {
1318
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
1319
+ key: 0,
1320
+ ref: unref(renderRef),
1321
+ props: unref(mergedProps),
1322
+ state: unref(itemCtx).state
1323
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
1324
+ key: 1,
1325
+ ref: unref(renderRef)
1326
+ }, unref(mergedProps)), {
1327
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(itemCtx).state })]),
1328
+ _: 3
1329
+ }, 16));
1330
+ };
1331
+ }
1332
+ });
1333
+
1334
+ //#endregion
1335
+ //#region src/accordion/trigger/AccordionTrigger.vue
1336
+ var AccordionTrigger_default = AccordionTrigger_vue_vue_type_script_setup_true_lang_default;
1337
+
1338
+ //#endregion
1339
+ //#region src/avatar/root/AvatarRoot.vue?vue&type=script&setup=true&lang.ts
1340
+ /**
1341
+ * Displays a user's profile picture, initials, or fallback icon.
1342
+ * Renders a \`<span>\` element.
1343
+ *
1344
+ * Documentation: [Base UI Avatar](https://base-ui-vue.com/components/avatar)
1345
+ */
1346
+ var AvatarRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1347
+ name: "AvatarRoot",
1348
+ inheritAttrs: false,
1349
+ __name: "AvatarRoot",
1350
+ props: {
1351
+ as: {
1352
+ type: null,
1353
+ required: false,
1354
+ default: "span"
1355
+ },
1356
+ class: {
1357
+ type: Function,
1358
+ required: false,
1359
+ skipCheck: true
1360
+ },
1361
+ style: {
1362
+ type: [
1363
+ Boolean,
1364
+ null,
1365
+ String,
1366
+ Object,
1367
+ Array,
1368
+ Function
1369
+ ],
1370
+ required: false,
1371
+ skipCheck: true
1372
+ }
1373
+ },
1374
+ setup(__props) {
1375
+ const props = __props;
1376
+ const attrs = useAttrs();
1377
+ const imageLoadingStatus = ref("idle");
1378
+ provide(AvatarRootContextKey, {
1379
+ imageLoadingStatus,
1380
+ setImageLoadingStatus: (status) => {
1381
+ imageLoadingStatus.value = status;
1382
+ }
1383
+ });
1384
+ const state = computed(() => ({ imageLoadingStatus: imageLoadingStatus.value }));
1385
+ const { tag, mergedProps, renderless } = useRenderElement({
1386
+ componentProps: props,
1387
+ state,
1388
+ props: computed(() => ({ ...attrs })),
1389
+ stateAttributesMapping: avatarStateAttributesMapping,
1390
+ defaultTagName: "span"
1391
+ });
1392
+ return (_ctx, _cache) => {
1393
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
1394
+ key: 0,
1395
+ props: unref(mergedProps),
1396
+ state: state.value
1397
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
1398
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
1399
+ _: 3
1400
+ }, 16));
1401
+ };
1402
+ }
1403
+ });
1404
+
1405
+ //#endregion
1406
+ //#region src/avatar/root/AvatarRoot.vue
1407
+ var AvatarRoot_default = AvatarRoot_vue_vue_type_script_setup_true_lang_default;
1408
+
1409
+ //#endregion
1410
+ //#region src/collapsible/root/stateAttributesMapping.ts
1411
+ const collapsibleStateAttributesMapping = {
1412
+ ...collapsibleOpenStateMapping,
1413
+ ...transitionStatusMapping
1414
+ };
1415
+
1416
+ //#endregion
1417
+ //#region src/collapsible/panel/CollapsiblePanelCssVars.ts
1418
+ let CollapsiblePanelCssVars = /* @__PURE__ */ function(CollapsiblePanelCssVars) {
1419
+ /**
1420
+ * The collapsible panel's height.
1421
+ * @type {number}
1422
+ */
1423
+ CollapsiblePanelCssVars["collapsiblePanelHeight"] = "--collapsible-panel-height";
1424
+ /**
1425
+ * The collapsible panel's width.
1426
+ * @type {number}
1427
+ */
1428
+ CollapsiblePanelCssVars["collapsiblePanelWidth"] = "--collapsible-panel-width";
1429
+ return CollapsiblePanelCssVars;
1430
+ }({});
1431
+
1432
+ //#endregion
1433
+ //#region src/collapsible/panel/CollapsiblePanel.vue?vue&type=script&setup=true&lang.ts
1434
+ var CollapsiblePanel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1435
+ name: "CollapsiblePanel",
1436
+ inheritAttrs: false,
1437
+ __name: "CollapsiblePanel",
1438
+ props: {
1439
+ id: {
1440
+ type: String,
1441
+ required: false
1442
+ },
1443
+ keepMounted: {
1444
+ type: Boolean,
1445
+ required: false,
1446
+ default: false
1447
+ },
1448
+ hiddenUntilFound: {
1449
+ type: Boolean,
1450
+ required: false,
1451
+ default: false
1452
+ },
1453
+ as: {
1454
+ type: null,
1455
+ required: false,
1456
+ default: "div"
1457
+ },
1458
+ class: {
1459
+ type: Function,
1460
+ required: false,
1461
+ skipCheck: true
1462
+ },
1463
+ style: {
1464
+ type: [
1465
+ Boolean,
1466
+ null,
1467
+ String,
1468
+ Object,
1469
+ Array,
1470
+ Function
1471
+ ],
1472
+ required: false,
1473
+ skipCheck: true
1474
+ }
1475
+ },
1476
+ setup(__props) {
1477
+ const props = __props;
1478
+ const attrs = useAttrs();
1479
+ const ctx = useCollapsibleRootContext();
1480
+ watch(() => props.hiddenUntilFound, (val) => ctx.setHiddenUntilFound(val), { immediate: true });
1481
+ watch(() => props.keepMounted, (val) => ctx.setKeepMounted(val), { immediate: true });
1482
+ watch(() => props.id, (id) => ctx.setPanelIdState(id), {
1483
+ immediate: true,
1484
+ flush: "sync"
1485
+ });
1486
+ if (process.env.NODE_ENV !== "production") watch([() => props.hiddenUntilFound, () => props.keepMounted], ([hiddenUntilFound, keepMounted]) => {
1487
+ if (hiddenUntilFound && keepMounted === false) warn("The `:keep-mounted=\"false\"` prop on a Collapsible will be ignored when using `hidden-until-found` since it requires the Panel to remain mounted even when closed.");
1488
+ }, { immediate: true });
1489
+ const { hidden, panelRef } = useCollapsiblePanel({
1490
+ abortControllerRef: ctx.abortControllerRef,
1491
+ animationTypeRef: ctx.animationTypeRef,
1492
+ height: ctx.height,
1493
+ hiddenUntilFound: props.hiddenUntilFound,
1494
+ id: ctx.panelId,
1495
+ keepMounted: props.keepMounted,
1496
+ mounted: ctx.mounted,
1497
+ onOpenChange: ctx.onOpenChange,
1498
+ open: ctx.open,
1499
+ panelRef: ctx.panelRef,
1500
+ runOnceAnimationsFinish: ctx.runOnceAnimationsFinish,
1501
+ setDimensions: ctx.setDimensions,
1502
+ setMounted: ctx.setMounted,
1503
+ setOpen: ctx.setOpen,
1504
+ setVisible: ctx.setVisible,
1505
+ transitionDimensionRef: ctx.transitionDimensionRef,
1506
+ visible: ctx.visible,
1507
+ width: ctx.width
1508
+ });
1509
+ useOpenChangeComplete({
1510
+ open: computed(() => ctx.open.value && ctx.transitionStatus.value === "idle"),
1511
+ ref: ctx.panelRef,
1512
+ onComplete() {
1513
+ if (!ctx.open.value) return;
1514
+ ctx.setDimensions({
1515
+ height: void 0,
1516
+ width: void 0
1517
+ });
1518
+ }
1519
+ });
1520
+ const panelState = computed(() => ({
1521
+ ...ctx.state.value,
1522
+ transitionStatus: ctx.transitionStatus.value
1523
+ }));
1524
+ const shouldRender = computed(() => props.keepMounted || props.hiddenUntilFound || ctx.mounted.value);
1525
+ const panelProps = computed(() => {
1526
+ const heightVal = ctx.height.value;
1527
+ const widthVal = ctx.width.value;
1528
+ const resolvedStyle = typeof props.style === "function" ? props.style(panelState.value) : props.style;
1529
+ return {
1530
+ ...attrs,
1531
+ id: ctx.panelId.value,
1532
+ hidden: props.hiddenUntilFound ? void 0 : hidden.value ? true : void 0,
1533
+ style: [resolvedStyle, {
1534
+ [CollapsiblePanelCssVars.collapsiblePanelHeight]: heightVal === void 0 ? "auto" : `${heightVal}px`,
1535
+ [CollapsiblePanelCssVars.collapsiblePanelWidth]: widthVal === void 0 ? "auto" : `${widthVal}px`
1536
+ }]
1537
+ };
1538
+ });
1539
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
1540
+ componentProps: {
1541
+ as: props.as,
1542
+ class: props.class
1543
+ },
1544
+ state: panelState,
1545
+ props: panelProps,
1546
+ stateAttributesMapping: collapsibleStateAttributesMapping,
1547
+ defaultTagName: "div",
1548
+ ref: panelRef
1549
+ });
1550
+ return (_ctx, _cache) => {
1551
+ return unref(renderless) && shouldRender.value ? renderSlot(_ctx.$slots, "default", {
1552
+ key: 0,
1553
+ ref: unref(renderRef),
1554
+ props: unref(mergedProps),
1555
+ state: panelState.value
1556
+ }) : shouldRender.value ? (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
1557
+ key: 1,
1558
+ ref: unref(renderRef)
1559
+ }, unref(mergedProps)), {
1560
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: panelState.value })]),
1561
+ _: 3
1562
+ }, 16)) : createCommentVNode("v-if", true);
1563
+ };
1564
+ }
1565
+ });
1566
+
1567
+ //#endregion
1568
+ //#region src/collapsible/panel/CollapsiblePanel.vue
1569
+ var CollapsiblePanel_default = CollapsiblePanel_vue_vue_type_script_setup_true_lang_default;
1570
+
1571
+ //#endregion
1572
+ //#region src/collapsible/root/CollapsibleRoot.vue?vue&type=script&setup=true&lang.ts
1573
+ var CollapsibleRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1574
+ name: "CollapsibleRoot",
1575
+ inheritAttrs: false,
1576
+ __name: "CollapsibleRoot",
1577
+ props: {
1578
+ open: {
1579
+ type: Boolean,
1580
+ required: false
1581
+ },
1582
+ defaultOpen: {
1583
+ type: Boolean,
1584
+ required: false,
1585
+ default: false
1586
+ },
1587
+ disabled: {
1588
+ type: Boolean,
1589
+ required: false,
1590
+ default: false
1591
+ },
1592
+ as: {
1593
+ type: null,
1594
+ required: false,
1595
+ default: "div"
1596
+ },
1597
+ class: {
1598
+ type: Function,
1599
+ required: false,
1600
+ skipCheck: true
1601
+ },
1602
+ style: {
1603
+ type: [
1604
+ Boolean,
1605
+ null,
1606
+ String,
1607
+ Object,
1608
+ Array,
1609
+ Function
1610
+ ],
1611
+ required: false,
1612
+ skipCheck: true
1613
+ }
1614
+ },
1615
+ emits: ["openChange"],
1616
+ setup(__props, { emit: __emit }) {
1617
+ const props = __props;
1618
+ const emit = __emit;
1619
+ const attrs = useAttrs();
1620
+ const instance = getCurrentInstance();
1621
+ const isOpenControlled = computed(() => {
1622
+ const vnodeProps = instance?.vnode.props;
1623
+ return Boolean(vnodeProps && "open" in vnodeProps);
1624
+ });
1625
+ const collapsible = useCollapsibleRoot({
1626
+ open: () => props.open,
1627
+ isOpenControlled: () => isOpenControlled.value,
1628
+ defaultOpen: props.defaultOpen ?? false,
1629
+ onOpenChange: (open, details) => emit("openChange", open, details),
1630
+ disabled: () => props.disabled ?? false
1631
+ });
1632
+ const state = collapsible.state;
1633
+ provide(collapsibleRootContextKey, collapsible);
1634
+ const { tag, mergedProps, renderless } = useRenderElement({
1635
+ componentProps: props,
1636
+ state,
1637
+ props: computed(() => ({ ...attrs })),
1638
+ stateAttributesMapping: collapsibleStateAttributesMapping,
1639
+ defaultTagName: "div"
1640
+ });
1641
+ return (_ctx, _cache) => {
1642
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
1643
+ key: 0,
1644
+ props: unref(mergedProps),
1645
+ state: unref(state)
1646
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
1647
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
1648
+ _: 3
1649
+ }, 16));
1650
+ };
1651
+ }
1652
+ });
1653
+
1654
+ //#endregion
1655
+ //#region src/collapsible/root/CollapsibleRoot.vue
1656
+ var CollapsibleRoot_default = CollapsibleRoot_vue_vue_type_script_setup_true_lang_default;
1657
+
1658
+ //#endregion
1659
+ //#region src/collapsible/trigger/CollapsibleTrigger.vue?vue&type=script&setup=true&lang.ts
1660
+ var CollapsibleTrigger_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1661
+ name: "CollapsibleTrigger",
1662
+ inheritAttrs: false,
1663
+ __name: "CollapsibleTrigger",
1664
+ props: {
1665
+ disabled: {
1666
+ type: Boolean,
1667
+ required: false
1668
+ },
1669
+ nativeButton: {
1670
+ type: Boolean,
1671
+ required: false,
1672
+ default: true
1673
+ },
1674
+ as: {
1675
+ type: null,
1676
+ required: false,
1677
+ default: "button"
1678
+ },
1679
+ class: {
1680
+ type: Function,
1681
+ required: false,
1682
+ skipCheck: true
1683
+ },
1684
+ style: {
1685
+ type: [
1686
+ Boolean,
1687
+ null,
1688
+ String,
1689
+ Object,
1690
+ Array,
1691
+ Function
1692
+ ],
1693
+ required: false,
1694
+ skipCheck: true
1695
+ }
1696
+ },
1697
+ setup(__props) {
1698
+ const props = __props;
1699
+ const triggerStateAttributesMapping = {
1700
+ ...triggerOpenStateMapping,
1701
+ ...transitionStatusMapping
1702
+ };
1703
+ const attrs = useAttrs();
1704
+ const ctx = useCollapsibleRootContext();
1705
+ const disabled = computed(() => props.disabled ?? ctx.disabled.value);
1706
+ const { getButtonProps, buttonRef } = useButton({
1707
+ disabled: () => disabled.value,
1708
+ focusableWhenDisabled: () => true,
1709
+ native: () => props.nativeButton ?? true
1710
+ });
1711
+ const { tag, mergedProps, renderless, ref: renderRef } = useRenderElement({
1712
+ componentProps: props,
1713
+ state: ctx.state,
1714
+ props: computed(() => getButtonProps({
1715
+ ...attrs,
1716
+ "aria-controls": ctx.open.value ? ctx.panelId.value : void 0,
1717
+ "aria-expanded": ctx.open.value,
1718
+ "onClick": ctx.handleTrigger
1719
+ })),
1720
+ stateAttributesMapping: triggerStateAttributesMapping,
1721
+ defaultTagName: "button",
1722
+ ref: buttonRef
1723
+ });
1724
+ return (_ctx, _cache) => {
1725
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
1726
+ key: 0,
1727
+ ref: unref(renderRef),
1728
+ props: unref(mergedProps),
1729
+ state: unref(ctx).state
1730
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), mergeProps({
1731
+ key: 1,
1732
+ ref: unref(renderRef)
1733
+ }, unref(mergedProps)), {
1734
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(ctx).state })]),
1735
+ _: 3
1736
+ }, 16));
1737
+ };
1738
+ }
1739
+ });
1740
+
1741
+ //#endregion
1742
+ //#region src/collapsible/trigger/CollapsibleTrigger.vue
1743
+ var CollapsibleTrigger_default = CollapsibleTrigger_vue_vue_type_script_setup_true_lang_default;
1744
+
1745
+ //#endregion
1746
+ //#region src/labelable-provider/LabelableProvider.vue?vue&type=script&setup=true&lang.ts
1747
+ var LabelableProvider_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1748
+ name: "LabelableProvider",
1749
+ __name: "LabelableProvider",
1750
+ props: {
1751
+ controlId: {
1752
+ type: [String, null],
1753
+ required: false
1754
+ },
1755
+ labelId: {
1756
+ type: String,
1757
+ required: false
1758
+ }
1759
+ },
1760
+ setup(__props) {
1761
+ const props = __props;
1762
+ const controlId = ref(props.controlId);
1763
+ const labelId = ref(props.labelId);
1764
+ const messageIds = ref([]);
1765
+ const parent = useLabelableContext();
1766
+ function setControlId(id) {
1767
+ controlId.value = id;
1768
+ }
1769
+ function setLabelId(id) {
1770
+ labelId.value = id;
1771
+ }
1772
+ function setMessageIds(updater) {
1773
+ messageIds.value = updater(messageIds.value);
1774
+ }
1775
+ function getDescriptionProps() {
1776
+ const describedBy = parent.messageIds.value.concat(messageIds.value).join(" ") || void 0;
1777
+ return { "aria-describedby": describedBy };
1778
+ }
1779
+ provide(labelableContextKey, {
1780
+ controlId,
1781
+ setControlId,
1782
+ labelId,
1783
+ setLabelId,
1784
+ messageIds,
1785
+ setMessageIds,
1786
+ getDescriptionProps
1787
+ });
1788
+ return (_ctx, _cache) => {
1789
+ return renderSlot(_ctx.$slots, "default");
1790
+ };
1791
+ }
1792
+ });
1793
+
1794
+ //#endregion
1795
+ //#region src/labelable-provider/LabelableProvider.vue
1796
+ var LabelableProvider_default = LabelableProvider_vue_vue_type_script_setup_true_lang_default;
1797
+
1798
+ //#endregion
1799
+ //#region src/field/item/FieldItemContext.ts
1800
+ const defaultContext = { disabled: ref(false) };
1801
+ const fieldItemContextKey = Symbol("FieldItemContext");
1802
+ function useFieldItemContext() {
1803
+ return inject(fieldItemContextKey, defaultContext);
1804
+ }
1805
+
1806
+ //#endregion
1807
+ //#region src/field/item/FieldItem.vue?vue&type=script&setup=true&lang.ts
1808
+ var FieldItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1809
+ name: "FieldItem",
1810
+ inheritAttrs: false,
1811
+ __name: "FieldItem",
1812
+ props: {
1813
+ disabled: {
1814
+ type: Boolean,
1815
+ required: false,
1816
+ default: false
1817
+ },
1818
+ as: {
1819
+ type: null,
1820
+ required: false,
1821
+ default: "div"
1822
+ },
1823
+ class: {
1824
+ type: Function,
1825
+ required: false,
1826
+ skipCheck: true
1827
+ },
1828
+ style: {
1829
+ type: [
1830
+ Boolean,
1831
+ null,
1832
+ String,
1833
+ Object,
1834
+ Array,
1835
+ Function
1836
+ ],
1837
+ required: false,
1838
+ skipCheck: true
1839
+ }
1840
+ },
1841
+ setup(__props) {
1842
+ const props = __props;
1843
+ const attrs = useAttrs();
1844
+ const { state, disabled: rootDisabled } = useFieldRootContext(false);
1845
+ provide(fieldItemContextKey, { disabled: computed(() => rootDisabled.value || props.disabled) });
1846
+ const { tag, mergedProps, renderless } = useRenderElement({
1847
+ componentProps: props,
1848
+ state,
1849
+ props: computed(() => ({ ...attrs })),
1850
+ stateAttributesMapping: fieldValidityMapping,
1851
+ defaultTagName: "div"
1852
+ });
1853
+ return (_ctx, _cache) => {
1854
+ return openBlock(), createBlock(LabelableProvider_default, null, {
1855
+ default: withCtx(() => [unref(renderless) ? renderSlot(_ctx.$slots, "default", {
1856
+ key: 0,
1857
+ props: unref(mergedProps),
1858
+ state: unref(state)
1859
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
1860
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(state) })]),
1861
+ _: 3
1862
+ }, 16))]),
1863
+ _: 3
1864
+ });
1865
+ };
1866
+ }
1867
+ });
1868
+
1869
+ //#endregion
1870
+ //#region src/field/item/FieldItem.vue
1871
+ var FieldItem_default = FieldItem_vue_vue_type_script_setup_true_lang_default;
1872
+
1873
+ //#endregion
1874
+ //#region src/field/label/FieldLabel.vue?vue&type=script&setup=true&lang.ts
1875
+ var FieldLabel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
1876
+ name: "FieldLabel",
1877
+ inheritAttrs: false,
1878
+ __name: "FieldLabel",
1879
+ props: {
1880
+ id: {
1881
+ type: String,
1882
+ required: false
1883
+ },
1884
+ nativeLabel: {
1885
+ type: Boolean,
1886
+ required: false,
1887
+ default: true
1888
+ },
1889
+ as: {
1890
+ type: null,
1891
+ required: false,
1892
+ default: "label"
1893
+ },
1894
+ class: {
1895
+ type: Function,
1896
+ required: false,
1897
+ skipCheck: true
1898
+ },
1899
+ style: {
1900
+ type: [
1901
+ Boolean,
1902
+ null,
1903
+ String,
1904
+ Object,
1905
+ Array,
1906
+ Function
1907
+ ],
1908
+ required: false,
1909
+ skipCheck: true
1910
+ }
1911
+ },
1912
+ setup(__props) {
1913
+ const props = __props;
1914
+ const attrs = useAttrs();
1915
+ const fieldRootContext = useFieldRootContext(false);
1916
+ const { controlId, setLabelId, labelId: contextLabelId } = useLabelableContext();
1917
+ const generatedLabelId = useBaseUiId(props.id);
1918
+ const labelId = computed(() => props.id ?? contextLabelId.value ?? generatedLabelId);
1919
+ watchEffect((onCleanup) => {
1920
+ const id = labelId.value;
1921
+ setLabelId(id);
1922
+ onCleanup(() => setLabelId(void 0));
1923
+ });
1924
+ function handleInteraction(event) {
1925
+ if (event.target?.closest("button,input,select,textarea")) return;
1926
+ if (!event.defaultPrevented && event.detail > 1) event.preventDefault();
1927
+ if (props.nativeLabel || !controlId.value) return;
1928
+ const controlElement = document.getElementById(controlId.value);
1929
+ if (controlElement) controlElement.focus();
1930
+ }
1931
+ const { tag, mergedProps, renderless } = useRenderElement({
1932
+ componentProps: props,
1933
+ state: fieldRootContext.state,
1934
+ props: computed(() => {
1935
+ if (props.nativeLabel) return {
1936
+ ...attrs,
1937
+ id: labelId.value,
1938
+ for: controlId.value ?? void 0,
1939
+ onMousedown: handleInteraction
1940
+ };
1941
+ return {
1942
+ ...attrs,
1943
+ id: labelId.value,
1944
+ onClick: handleInteraction,
1945
+ onPointerdown: (event) => {
1946
+ event.preventDefault();
1947
+ }
1948
+ };
1949
+ }),
1950
+ stateAttributesMapping: fieldValidityMapping,
1951
+ defaultTagName: "label"
1952
+ });
1953
+ return (_ctx, _cache) => {
1954
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
1955
+ key: 0,
1956
+ props: unref(mergedProps),
1957
+ state: unref(fieldRootContext).state
1958
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
1959
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: unref(fieldRootContext).state })]),
1960
+ _: 3
1961
+ }, 16));
1962
+ };
1963
+ }
1964
+ });
1965
+
1966
+ //#endregion
1967
+ //#region src/field/label/FieldLabel.vue
1968
+ var FieldLabel_default = FieldLabel_vue_vue_type_script_setup_true_lang_default;
1969
+
1970
+ //#endregion
1971
+ //#region src/fieldset/root/FieldsetRootContext.ts
1972
+ const fieldsetRootContextKey = Symbol("FieldsetRootContext");
1973
+ function useFieldsetRootContext(optional = false) {
1974
+ const context = inject(fieldsetRootContextKey, void 0);
1975
+ if (!context && !optional) throw new Error("Base UI Vue: FieldsetRootContext is missing. Fieldset parts must be placed within <FieldsetRoot>.");
1976
+ return context;
1977
+ }
1978
+
1979
+ //#endregion
1980
+ //#region src/field/root/useFieldRootState.ts
1981
+ function useFieldRootState(params) {
1982
+ const { disabled, touchedProp, dirtyProp } = params;
1983
+ const touchedState = shallowRef(false);
1984
+ const dirtyState = shallowRef(false);
1985
+ const filled = shallowRef(false);
1986
+ const focused = shallowRef(false);
1987
+ const markedDirtyRef = shallowRef(false);
1988
+ const touched = computed(() => touchedProp.value ?? touchedState.value);
1989
+ const dirty = computed(() => dirtyProp.value ?? dirtyState.value);
1990
+ function setDirty(value) {
1991
+ if (dirtyProp.value !== void 0) return;
1992
+ if (value) markedDirtyRef.value = true;
1993
+ dirtyState.value = value;
1994
+ }
1995
+ function setTouched(value) {
1996
+ if (touchedProp.value !== void 0) return;
1997
+ touchedState.value = value;
1998
+ }
1999
+ function setFilled(value) {
2000
+ filled.value = value;
2001
+ }
2002
+ function setFocused(value) {
2003
+ focused.value = value;
2004
+ }
2005
+ return {
2006
+ touched,
2007
+ dirty,
2008
+ filled,
2009
+ focused,
2010
+ setTouched,
2011
+ setDirty,
2012
+ setFilled,
2013
+ setFocused,
2014
+ markedDirtyRef,
2015
+ stateWithoutValidity: computed(() => ({
2016
+ disabled: disabled.value,
2017
+ touched: touched.value,
2018
+ dirty: dirty.value,
2019
+ filled: filled.value,
2020
+ focused: focused.value
2021
+ }))
2022
+ };
2023
+ }
2024
+
2025
+ //#endregion
2026
+ //#region src/field/root/useFieldValidation.ts
2027
+ const validityKeys = Object.keys(DEFAULT_VALIDITY_STATE);
2028
+ function isOnlyValueMissing(state) {
2029
+ if (!state || state.valid || !state.valueMissing) return false;
2030
+ for (const key of validityKeys) {
2031
+ if (key === "valid" || key === "valueMissing") continue;
2032
+ if (state[key]) return false;
2033
+ }
2034
+ return true;
2035
+ }
2036
+ function useFieldValidation(params) {
2037
+ const { formRef, clearErrors } = useFormContext();
2038
+ const { controlId, getDescriptionProps, setValidityData, validate, validityData, validationDebounceTime, invalid, markedDirtyRef, state, name, shouldValidateOnChange } = params;
2039
+ const timeout = useTimeout();
2040
+ const inputRef = shallowRef(null);
2041
+ function setInputRef(element) {
2042
+ inputRef.value = element;
2043
+ }
2044
+ async function commit(value, revalidate = false) {
2045
+ const element = inputRef.value;
2046
+ if (!element) return;
2047
+ if (revalidate) {
2048
+ if (state.value.valid !== false) return;
2049
+ const currentNativeValidity = element.validity;
2050
+ if (!currentNativeValidity.valueMissing) {
2051
+ const nextValidityData = {
2052
+ value,
2053
+ state: {
2054
+ ...DEFAULT_VALIDITY_STATE,
2055
+ valid: true
2056
+ },
2057
+ error: "",
2058
+ errors: [],
2059
+ initialValue: validityData.value.initialValue
2060
+ };
2061
+ element.setCustomValidity("");
2062
+ const cId = controlId.value;
2063
+ if (cId) {
2064
+ const currentFieldData = formRef.value.fields.get(cId);
2065
+ if (currentFieldData) formRef.value.fields.set(cId, {
2066
+ ...currentFieldData,
2067
+ validityData: getCombinedFieldValidityData(nextValidityData, false)
2068
+ });
2069
+ }
2070
+ setValidityData(nextValidityData);
2071
+ return;
2072
+ }
2073
+ const currentNativeValidityObject = validityKeys.reduce((acc, key) => {
2074
+ acc[key] = currentNativeValidity[key];
2075
+ return acc;
2076
+ }, {});
2077
+ if (!currentNativeValidityObject.valid && !isOnlyValueMissing(currentNativeValidityObject)) return;
2078
+ }
2079
+ function getState(el) {
2080
+ const computedState = validityKeys.reduce((acc, key) => {
2081
+ acc[key] = el.validity[key];
2082
+ return acc;
2083
+ }, {});
2084
+ let hasOnlyValueMissingError = false;
2085
+ for (const key of validityKeys) {
2086
+ if (key === "valid") continue;
2087
+ if (key === "valueMissing" && computedState[key]) hasOnlyValueMissingError = true;
2088
+ else if (computedState[key]) return computedState;
2089
+ }
2090
+ if (hasOnlyValueMissingError && !markedDirtyRef.value) {
2091
+ computedState.valid = true;
2092
+ computedState.valueMissing = false;
2093
+ }
2094
+ return computedState;
2095
+ }
2096
+ timeout.clear();
2097
+ let result = null;
2098
+ let validationErrors = [];
2099
+ const nextState = getState(element);
2100
+ let defaultValidationMessage;
2101
+ const validateOnChange = shouldValidateOnChange();
2102
+ if (element.validationMessage && !validateOnChange) {
2103
+ defaultValidationMessage = element.validationMessage;
2104
+ validationErrors = [element.validationMessage];
2105
+ } else {
2106
+ const resultOrPromise = validate(value, Array.from(formRef.value.fields.values()).reduce((acc, field) => {
2107
+ if (field.name) acc[field.name] = field.getValue();
2108
+ return acc;
2109
+ }, {}));
2110
+ if (typeof resultOrPromise === "object" && resultOrPromise !== null && "then" in resultOrPromise) result = await resultOrPromise;
2111
+ else result = resultOrPromise;
2112
+ if (result !== null) {
2113
+ nextState.valid = false;
2114
+ nextState.customError = true;
2115
+ if (Array.isArray(result)) {
2116
+ validationErrors = result;
2117
+ element.setCustomValidity(result.join("\n"));
2118
+ } else if (result) {
2119
+ validationErrors = [result];
2120
+ element.setCustomValidity(result);
2121
+ }
2122
+ } else if (validateOnChange) {
2123
+ element.setCustomValidity("");
2124
+ nextState.customError = false;
2125
+ if (element.validationMessage) {
2126
+ defaultValidationMessage = element.validationMessage;
2127
+ validationErrors = [element.validationMessage];
2128
+ } else if (element.validity.valid && !nextState.valid) nextState.valid = true;
2129
+ }
2130
+ }
2131
+ const nextValidityData = {
2132
+ value,
2133
+ state: nextState,
2134
+ error: defaultValidationMessage ?? (Array.isArray(result) ? result[0] : result ?? ""),
2135
+ errors: validationErrors,
2136
+ initialValue: validityData.value.initialValue
2137
+ };
2138
+ const cId = controlId.value;
2139
+ if (cId) {
2140
+ const currentFieldData = formRef.value.fields.get(cId);
2141
+ if (currentFieldData) formRef.value.fields.set(cId, {
2142
+ ...currentFieldData,
2143
+ validityData: getCombinedFieldValidityData(nextValidityData, invalid.value)
2144
+ });
2145
+ }
2146
+ setValidityData(nextValidityData);
2147
+ }
2148
+ function getValidationProps() {
2149
+ const descProps = getDescriptionProps();
2150
+ const ariaInvalid = state.value.valid === false ? { "aria-invalid": true } : {};
2151
+ return {
2152
+ ...descProps,
2153
+ ...ariaInvalid
2154
+ };
2155
+ }
2156
+ function getInputValidationProps() {
2157
+ return {
2158
+ onInput(event) {
2159
+ const target = event.target;
2160
+ clearErrors(name.value);
2161
+ if (!shouldValidateOnChange()) {
2162
+ commit(target.value, true);
2163
+ return;
2164
+ }
2165
+ const element = target;
2166
+ if (element.value === "") {
2167
+ commit(element.value);
2168
+ return;
2169
+ }
2170
+ timeout.clear();
2171
+ if (validationDebounceTime.value) timeout.start(validationDebounceTime.value, () => {
2172
+ commit(element.value);
2173
+ });
2174
+ else commit(element.value);
2175
+ },
2176
+ ...getValidationProps()
2177
+ };
2178
+ }
2179
+ return {
2180
+ getValidationProps,
2181
+ getInputValidationProps,
2182
+ inputRef: shallowReadonly(inputRef),
2183
+ setInputRef,
2184
+ commit
2185
+ };
2186
+ }
2187
+
2188
+ //#endregion
2189
+ //#region src/field/root/useFieldValidity.ts
2190
+ function useFieldValidity(params) {
2191
+ const { invalid } = params;
2192
+ const validityData = ref({
2193
+ state: { ...DEFAULT_VALIDITY_STATE },
2194
+ error: "",
2195
+ errors: [],
2196
+ value: null,
2197
+ initialValue: null
2198
+ });
2199
+ function setValidityData(data) {
2200
+ validityData.value = data;
2201
+ }
2202
+ return {
2203
+ validityData,
2204
+ setValidityData,
2205
+ valid: computed(() => !invalid.value && validityData.value.state.valid)
2206
+ };
2207
+ }
2208
+
2209
+ //#endregion
2210
+ //#region src/field/root/FieldRoot.vue?vue&type=script&setup=true&lang.ts
2211
+ var FieldRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2212
+ name: "FieldRoot",
2213
+ inheritAttrs: false,
2214
+ __name: "FieldRoot",
2215
+ props: {
2216
+ disabled: {
2217
+ type: Boolean,
2218
+ required: false,
2219
+ default: false
2220
+ },
2221
+ name: {
2222
+ type: String,
2223
+ required: false
2224
+ },
2225
+ validate: {
2226
+ type: Function,
2227
+ required: false
2228
+ },
2229
+ validationMode: {
2230
+ type: String,
2231
+ required: false
2232
+ },
2233
+ validationDebounceTime: {
2234
+ type: Number,
2235
+ required: false,
2236
+ default: 0
2237
+ },
2238
+ invalid: {
2239
+ type: Boolean,
2240
+ required: false,
2241
+ default: void 0
2242
+ },
2243
+ dirty: {
2244
+ type: Boolean,
2245
+ required: false,
2246
+ default: void 0
2247
+ },
2248
+ touched: {
2249
+ type: Boolean,
2250
+ required: false,
2251
+ default: void 0
2252
+ },
2253
+ as: {
2254
+ type: null,
2255
+ required: false,
2256
+ default: "div"
2257
+ },
2258
+ class: {
2259
+ type: Function,
2260
+ required: false,
2261
+ skipCheck: true
2262
+ },
2263
+ style: {
2264
+ type: [
2265
+ Boolean,
2266
+ null,
2267
+ String,
2268
+ Object,
2269
+ Array,
2270
+ Function
2271
+ ],
2272
+ required: false,
2273
+ skipCheck: true
2274
+ }
2275
+ },
2276
+ setup(__props, { expose: __expose }) {
2277
+ const props = __props;
2278
+ const attrs = useAttrs();
2279
+ const { validationMode: formValidationMode, submitAttempted } = useFormContext();
2280
+ const fieldsetContext = useFieldsetRootContext(true);
2281
+ const disabledFieldset = computed(() => fieldsetContext?.disabled.value ?? false);
2282
+ const disabled = computed(() => disabledFieldset.value || props.disabled);
2283
+ const nameRef = computed(() => props.name);
2284
+ const validationModeRef = computed(() => props.validationMode ?? formValidationMode.value);
2285
+ const validationDebounceTimeRef = computed(() => props.validationDebounceTime);
2286
+ const validateFn = computed(() => props.validate ?? (() => null));
2287
+ const parentLabelable = useLabelableContext();
2288
+ const controlId = ref(void 0);
2289
+ const labelId = ref(void 0);
2290
+ const messageIds = ref([]);
2291
+ function setControlId(id) {
2292
+ controlId.value = id;
2293
+ }
2294
+ function setLabelId(id) {
2295
+ labelId.value = id;
2296
+ }
2297
+ function setMessageIds(updater) {
2298
+ messageIds.value = updater(messageIds.value);
2299
+ }
2300
+ function getDescriptionProps() {
2301
+ const describedBy = parentLabelable.messageIds.value.concat(messageIds.value).join(" ") || void 0;
2302
+ return { "aria-describedby": describedBy };
2303
+ }
2304
+ provide(labelableContextKey, {
2305
+ controlId,
2306
+ setControlId,
2307
+ labelId,
2308
+ setLabelId,
2309
+ messageIds,
2310
+ setMessageIds,
2311
+ getDescriptionProps
2312
+ });
2313
+ const { errors: formErrors } = useFormContext();
2314
+ const hasFormError = computed(() => {
2315
+ const n = props.name;
2316
+ return !!n && Object.hasOwn(formErrors.value, n) && formErrors.value[n] !== void 0;
2317
+ });
2318
+ const invalid = computed(() => props.invalid === true || hasFormError.value);
2319
+ const { validityData, setValidityData, valid } = useFieldValidity({ invalid });
2320
+ const shouldValidateOnChange = computed(() => {
2321
+ return validationModeRef.value === "onChange" || validationModeRef.value === "onSubmit" && submitAttempted.value;
2322
+ });
2323
+ const { touched, dirty, filled, focused, setTouched, setDirty, setFilled, setFocused, markedDirtyRef, stateWithoutValidity } = useFieldRootState({
2324
+ disabled,
2325
+ touchedProp: computed(() => props.touched),
2326
+ dirtyProp: computed(() => props.dirty)
2327
+ });
2328
+ const state = computed(() => ({
2329
+ valid: valid.value,
2330
+ ...stateWithoutValidity.value
2331
+ }));
2332
+ const validation = useFieldValidation({
2333
+ controlId,
2334
+ getDescriptionProps,
2335
+ setValidityData,
2336
+ validate: (value, formValues) => validateFn.value(value, formValues),
2337
+ validityData,
2338
+ validationDebounceTime: validationDebounceTimeRef,
2339
+ invalid,
2340
+ markedDirtyRef,
2341
+ state,
2342
+ name: nameRef,
2343
+ shouldValidateOnChange: () => shouldValidateOnChange.value
2344
+ });
2345
+ provide(fieldRootContextKey, {
2346
+ invalid,
2347
+ name: nameRef,
2348
+ validityData: shallowReadonly(validityData),
2349
+ setValidityData,
2350
+ disabled,
2351
+ touched,
2352
+ setTouched,
2353
+ dirty,
2354
+ setDirty,
2355
+ filled,
2356
+ setFilled,
2357
+ focused,
2358
+ setFocused,
2359
+ validate: (value, formValues) => validateFn.value(value, formValues),
2360
+ validationMode: validationModeRef,
2361
+ validationDebounceTime: validationDebounceTimeRef,
2362
+ shouldValidateOnChange: () => shouldValidateOnChange.value,
2363
+ state,
2364
+ markedDirtyRef,
2365
+ validation
2366
+ });
2367
+ function handleImperativeValidate() {
2368
+ markedDirtyRef.value = true;
2369
+ const currentValue = validation.inputRef.value?.value ?? validityData.value.value;
2370
+ validation.commit(currentValue);
2371
+ }
2372
+ __expose({ validate: handleImperativeValidate });
2373
+ const { tag, mergedProps, renderless } = useRenderElement({
2374
+ componentProps: props,
2375
+ state,
2376
+ props: computed(() => ({ ...attrs })),
2377
+ stateAttributesMapping: fieldValidityMapping,
2378
+ defaultTagName: "div"
2379
+ });
2380
+ return (_ctx, _cache) => {
2381
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
2382
+ key: 0,
2383
+ props: unref(mergedProps),
2384
+ state: state.value
2385
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
2386
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
2387
+ _: 3
2388
+ }, 16));
2389
+ };
2390
+ }
2391
+ });
2392
+
2393
+ //#endregion
2394
+ //#region src/field/root/FieldRoot.vue
2395
+ var FieldRoot_default = FieldRoot_vue_vue_type_script_setup_true_lang_default;
2396
+
2397
+ //#endregion
2398
+ //#region src/field/validity/FieldValidity.vue?vue&type=script&setup=true&lang.ts
2399
+ var FieldValidity_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2400
+ name: "FieldValidity",
2401
+ __name: "FieldValidity",
2402
+ setup(__props) {
2403
+ const { validityData, invalid } = useFieldRootContext(false);
2404
+ const combinedFieldValidityData = computed(() => getCombinedFieldValidityData(validityData.value, invalid.value));
2405
+ const { transitionStatus } = useTransitionStatus(computed(() => combinedFieldValidityData.value.state.valid === false));
2406
+ const fieldValidityState = computed(() => ({
2407
+ ...combinedFieldValidityData.value,
2408
+ validity: combinedFieldValidityData.value.state,
2409
+ transitionStatus: transitionStatus.value
2410
+ }));
2411
+ return (_ctx, _cache) => {
2412
+ return renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(fieldValidityState.value)));
2413
+ };
2414
+ }
2415
+ });
2416
+
2417
+ //#endregion
2418
+ //#region src/field/validity/FieldValidity.vue
2419
+ var FieldValidity_default = FieldValidity_vue_vue_type_script_setup_true_lang_default;
2420
+
2421
+ //#endregion
2422
+ //#region src/fieldset/legend/FieldsetLegend.vue?vue&type=script&setup=true&lang.ts
2423
+ /**
2424
+ * An accessible label that is automatically associated with the fieldset.
2425
+ * Renders a \`<div>\` element.
2426
+ *
2427
+ * Documentation: [Base UI Vue Fieldset](https://baseui-vue.com/components/fieldset)
2428
+ */
2429
+ var FieldsetLegend_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2430
+ name: "FieldsetLegend",
2431
+ inheritAttrs: false,
2432
+ __name: "FieldsetLegend",
2433
+ props: {
2434
+ id: {
2435
+ type: String,
2436
+ required: false
2437
+ },
2438
+ as: {
2439
+ type: null,
2440
+ required: false,
2441
+ default: "div"
2442
+ },
2443
+ class: {
2444
+ type: Function,
2445
+ required: false,
2446
+ skipCheck: true
2447
+ },
2448
+ style: {
2449
+ type: [
2450
+ Boolean,
2451
+ null,
2452
+ String,
2453
+ Object,
2454
+ Array,
2455
+ Function
2456
+ ],
2457
+ required: false,
2458
+ skipCheck: true
2459
+ }
2460
+ },
2461
+ setup(__props) {
2462
+ const props = __props;
2463
+ const attrs = useAttrs();
2464
+ const { disabled, legendId, setLegendId } = useFieldsetRootContext();
2465
+ const id = useBaseUiId(props.id);
2466
+ setLegendId(id);
2467
+ onBeforeUnmount(() => {
2468
+ if (legendId.value === id) setLegendId(void 0);
2469
+ });
2470
+ const state = computed(() => ({ disabled: disabled.value }));
2471
+ const { tag, mergedProps, renderless } = useRenderElement({
2472
+ componentProps: props,
2473
+ state,
2474
+ props: computed(() => ({
2475
+ ...attrs,
2476
+ id
2477
+ })),
2478
+ defaultTagName: "div"
2479
+ });
2480
+ return (_ctx, _cache) => {
2481
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
2482
+ key: 0,
2483
+ props: unref(mergedProps),
2484
+ state: state.value
2485
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
2486
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
2487
+ _: 3
2488
+ }, 16));
2489
+ };
2490
+ }
2491
+ });
2492
+
2493
+ //#endregion
2494
+ //#region src/fieldset/legend/FieldsetLegend.vue
2495
+ var FieldsetLegend_default = FieldsetLegend_vue_vue_type_script_setup_true_lang_default;
2496
+
2497
+ //#endregion
2498
+ //#region src/fieldset/root/FieldsetRoot.vue?vue&type=script&setup=true&lang.ts
2499
+ /**
2500
+ * Groups a shared legend with related controls.
2501
+ * Renders a \`<fieldset>\` element.
2502
+ *
2503
+ * Documentation: [Base UI Vue Fieldset](https://baseui-vue.com/components/fieldset)
2504
+ */
2505
+ var FieldsetRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
2506
+ name: "FieldsetRoot",
2507
+ inheritAttrs: false,
2508
+ __name: "FieldsetRoot",
2509
+ props: {
2510
+ disabled: {
2511
+ type: Boolean,
2512
+ required: false,
2513
+ default: false
2514
+ },
2515
+ as: {
2516
+ type: null,
2517
+ required: false,
2518
+ default: "fieldset"
2519
+ },
2520
+ class: {
2521
+ type: Function,
2522
+ required: false,
2523
+ skipCheck: true
2524
+ },
2525
+ style: {
2526
+ type: [
2527
+ Boolean,
2528
+ null,
2529
+ String,
2530
+ Object,
2531
+ Array,
2532
+ Function
2533
+ ],
2534
+ required: false,
2535
+ skipCheck: true
2536
+ }
2537
+ },
2538
+ setup(__props) {
2539
+ const props = __props;
2540
+ const attrs = useAttrs();
2541
+ const legendId = ref(void 0);
2542
+ function setLegendId(id) {
2543
+ legendId.value = id;
2544
+ }
2545
+ const disabled = computed(() => props.disabled ?? false);
2546
+ const state = computed(() => ({ disabled: disabled.value }));
2547
+ provide(fieldsetRootContextKey, {
2548
+ legendId,
2549
+ setLegendId,
2550
+ disabled
2551
+ });
2552
+ const { tag, mergedProps, renderless } = useRenderElement({
2553
+ componentProps: props,
2554
+ state,
2555
+ props: computed(() => ({
2556
+ ...attrs,
2557
+ "aria-labelledby": legendId.value
2558
+ })),
2559
+ defaultTagName: "fieldset"
2560
+ });
2561
+ return (_ctx, _cache) => {
2562
+ return unref(renderless) ? renderSlot(_ctx.$slots, "default", {
2563
+ key: 0,
2564
+ props: unref(mergedProps),
2565
+ state: state.value
2566
+ }) : (openBlock(), createBlock(resolveDynamicComponent(unref(tag)), normalizeProps(mergeProps({ key: 1 }, unref(mergedProps))), {
2567
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", { state: state.value })]),
2568
+ _: 3
2569
+ }, 16));
2570
+ };
2571
+ }
2572
+ });
2573
+
2574
+ //#endregion
2575
+ //#region src/fieldset/root/FieldsetRoot.vue
2576
+ var FieldsetRoot_default = FieldsetRoot_vue_vue_type_script_setup_true_lang_default;
2577
+
2578
+ //#endregion
2579
+ //#region src/use-render/useRender.ts
2580
+ /**
2581
+ * Renders a Base UI element.
2582
+ *
2583
+ * The public composable that collects `attrs` internally via `useAttrs()`,
2584
+ * merges them with explicit props, and delegates to `useRenderElement`.
2585
+ * Returns a readonly state and supports renderless mode via the `Slot` sentinel.
2586
+ *
2587
+ * @public
2588
+ */
2589
+ function useRender(params) {
2590
+ const attrs = useAttrs();
2591
+ const state = computed(() => {
2592
+ return readonly(toValue(params.state) ?? EMPTY_OBJECT);
2593
+ });
2594
+ const mergedComponentProps = useRenderElement({
2595
+ componentProps: params,
2596
+ state,
2597
+ props: computed(() => mergeProps$1(attrs, toValue(params.props))),
2598
+ stateAttributesMapping: params.stateAttributesMapping,
2599
+ defaultTagName: params.defaultTagName,
2600
+ ref: params.ref
2601
+ });
2602
+ return {
2603
+ tag: mergedComponentProps.tag,
2604
+ renderProps: mergedComponentProps.mergedProps,
2605
+ renderless: mergedComponentProps.renderless,
2606
+ state,
2607
+ ref: mergedComponentProps.ref
2608
+ };
2609
+ }
2610
+
2611
+ //#endregion
2612
+ //#region src/index.ts
2613
+ const name = "base-ui-vue";
2614
+ const version = "0.0.0";
2615
+
2616
+ //#endregion
2617
+ export { AccordionItem_default, AccordionPanel_default, AccordionRoot_default, AccordionTrigger_default, AvatarRoot_default, CollapsiblePanel_default, CollapsibleRoot_default, CollapsibleTrigger_default, FieldItem_default, FieldLabel_default, FieldRoot_default, FieldValidity_default, FieldsetLegend_default, FieldsetRoot_default, accordionRootContextKey, collapsibleRootContextKey, fieldItemContextKey, fieldsetRootContextKey, name, useAccordionRootContext, useCollapsibleRootContext, useFieldItemContext, useFieldsetRootContext, useRender, version };
2618
+ //# sourceMappingURL=index2.js.map