base-ui-vue 0.3.0 → 0.5.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 (218) hide show
  1. package/dist/arrow/TooltipArrow.cjs +609 -0
  2. package/dist/arrow/TooltipArrow.cjs.map +1 -0
  3. package/dist/arrow/TooltipArrow.js +478 -0
  4. package/dist/arrow/TooltipArrow.js.map +1 -0
  5. package/dist/button/Button.cjs +5 -317
  6. package/dist/button/Button.cjs.map +1 -1
  7. package/dist/button/Button.js +3 -249
  8. package/dist/button/Button.js.map +1 -1
  9. package/dist/button/ToolbarButton.cjs +19 -6
  10. package/dist/button/ToolbarButton.cjs.map +1 -1
  11. package/dist/button/ToolbarButton.js +3 -2
  12. package/dist/button/ToolbarButton.js.map +1 -1
  13. package/dist/checkbox/index.cjs +20 -9
  14. package/dist/checkbox/index.cjs.map +1 -1
  15. package/dist/checkbox/index.js +7 -2
  16. package/dist/checkbox/index.js.map +1 -1
  17. package/dist/checkbox-group/CheckboxGroup.cjs +14 -13
  18. package/dist/checkbox-group/CheckboxGroup.cjs.map +1 -1
  19. package/dist/checkbox-group/CheckboxGroup.js +2 -1
  20. package/dist/checkbox-group/CheckboxGroup.js.map +1 -1
  21. package/dist/components/FloatingPortal.cjs +66 -0
  22. package/dist/components/FloatingPortal.cjs.map +1 -0
  23. package/dist/components/FloatingPortal.js +55 -0
  24. package/dist/components/FloatingPortal.js.map +1 -0
  25. package/dist/components/FloatingRootStore.cjs +101 -0
  26. package/dist/components/FloatingRootStore.cjs.map +1 -0
  27. package/dist/components/FloatingRootStore.js +84 -0
  28. package/dist/components/FloatingRootStore.js.map +1 -0
  29. package/dist/components/FloatingTree.cjs +33 -0
  30. package/dist/components/FloatingTree.cjs.map +1 -0
  31. package/dist/components/FloatingTree.js +22 -0
  32. package/dist/components/FloatingTree.js.map +1 -0
  33. package/dist/composite/composite.cjs +6 -0
  34. package/dist/composite/composite.js +1 -1
  35. package/dist/content/ScrollAreaContent.cjs +3 -3
  36. package/dist/content/ScrollAreaContent.cjs.map +1 -1
  37. package/dist/content/ScrollAreaContent.js +1 -1
  38. package/dist/control/FieldControl.cjs +3 -3
  39. package/dist/control/FieldControl.cjs.map +1 -1
  40. package/dist/control/FieldControl.js +1 -1
  41. package/dist/control/SliderControl.cjs +3 -3
  42. package/dist/control/SliderControl.cjs.map +1 -1
  43. package/dist/control/SliderControl.js +3 -3
  44. package/dist/corner/ScrollAreaCorner.cjs +3 -3
  45. package/dist/corner/ScrollAreaCorner.cjs.map +1 -1
  46. package/dist/corner/ScrollAreaCorner.js +1 -1
  47. package/dist/decrement/NumberFieldDecrement.cjs +868 -0
  48. package/dist/decrement/NumberFieldDecrement.cjs.map +1 -0
  49. package/dist/decrement/NumberFieldDecrement.js +701 -0
  50. package/dist/decrement/NumberFieldDecrement.js.map +1 -0
  51. package/dist/description/FieldDescription.cjs +2 -2
  52. package/dist/description/FieldDescription.cjs.map +1 -1
  53. package/dist/description/FieldDescription.js +1 -1
  54. package/dist/error/FieldError.cjs +2 -2
  55. package/dist/error/FieldError.cjs.map +1 -1
  56. package/dist/error/FieldError.js +1 -1
  57. package/dist/fallback/AvatarFallback.cjs +4 -48
  58. package/dist/fallback/AvatarFallback.cjs.map +1 -1
  59. package/dist/fallback/AvatarFallback.js +4 -42
  60. package/dist/fallback/AvatarFallback.js.map +1 -1
  61. package/dist/floating-ui-vue/index.js +638 -0
  62. package/dist/floating-ui-vue/index.js.map +1 -0
  63. package/dist/form/Form.cjs +3 -3
  64. package/dist/form/Form.cjs.map +1 -1
  65. package/dist/form/Form.js +1 -1
  66. package/dist/group/NumberFieldGroup.cjs +72 -0
  67. package/dist/group/NumberFieldGroup.cjs.map +1 -0
  68. package/dist/group/NumberFieldGroup.js +67 -0
  69. package/dist/group/NumberFieldGroup.js.map +1 -0
  70. package/dist/group/ToolbarGroup.cjs +2 -2
  71. package/dist/group/ToolbarGroup.cjs.map +1 -1
  72. package/dist/group/ToolbarGroup.js +1 -1
  73. package/dist/header/AccordionHeader.cjs +2 -2
  74. package/dist/header/AccordionHeader.cjs.map +1 -1
  75. package/dist/header/AccordionHeader.js +1 -1
  76. package/dist/hooks/useDismiss.cjs +502 -0
  77. package/dist/hooks/useDismiss.cjs.map +1 -0
  78. package/dist/hooks/useHoverFloatingInteraction.cjs +233 -0
  79. package/dist/hooks/useHoverFloatingInteraction.cjs.map +1 -0
  80. package/dist/image/AvatarImage.cjs +4 -4
  81. package/dist/image/AvatarImage.cjs.map +1 -1
  82. package/dist/image/AvatarImage.js +1 -1
  83. package/dist/increment/NumberFieldIncrement.cjs +113 -0
  84. package/dist/increment/NumberFieldIncrement.cjs.map +1 -0
  85. package/dist/increment/NumberFieldIncrement.js +108 -0
  86. package/dist/increment/NumberFieldIncrement.js.map +1 -0
  87. package/dist/index.cjs +80 -8
  88. package/dist/index.d.cts +4328 -1600
  89. package/dist/index.d.cts.map +1 -1
  90. package/dist/index.d.ts +4328 -1600
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +8 -4
  93. package/dist/index2.cjs +9435 -3236
  94. package/dist/index2.cjs.map +1 -1
  95. package/dist/index2.js +8905 -3049
  96. package/dist/index2.js.map +1 -1
  97. package/dist/rolldown-runtime.js +36 -0
  98. package/package.json +1 -1
  99. package/src/floating-ui-vue/components/FloatingPortal.ts +171 -0
  100. package/src/floating-ui-vue/components/FloatingPortal.vue +259 -0
  101. package/src/floating-ui-vue/components/FloatingRootStore.ts +83 -0
  102. package/src/floating-ui-vue/components/FloatingTree.ts +64 -0
  103. package/src/floating-ui-vue/components/FloatingTreeStore.ts +21 -0
  104. package/src/floating-ui-vue/hooks/useDismiss.ts +689 -0
  105. package/src/floating-ui-vue/hooks/useHoverFloatingInteraction.ts +244 -0
  106. package/src/floating-ui-vue/hooks/useHoverInteractionSharedState.ts +125 -0
  107. package/src/floating-ui-vue/hooks/useHoverShared.ts +53 -0
  108. package/src/floating-ui-vue/index.ts +48 -0
  109. package/src/floating-ui-vue/middleware/arrow.ts +114 -0
  110. package/src/floating-ui-vue/types.ts +117 -0
  111. package/src/floating-ui-vue/utils/composite.ts +20 -0
  112. package/src/floating-ui-vue/utils/constants.ts +2 -0
  113. package/src/floating-ui-vue/utils/createAttribute.ts +3 -0
  114. package/src/floating-ui-vue/utils/createEventEmitter.ts +20 -0
  115. package/src/floating-ui-vue/utils/element.ts +59 -0
  116. package/src/floating-ui-vue/utils/event.ts +15 -0
  117. package/src/floating-ui-vue/utils/nodes.ts +14 -0
  118. package/src/floating-ui-vue/utils/tabbable.ts +309 -0
  119. package/src/index.ts +7 -1
  120. package/src/number-field/decrement/NumberFieldDecrement.vue +109 -0
  121. package/src/number-field/group/NumberFieldGroup.vue +47 -0
  122. package/src/number-field/increment/NumberFieldIncrement.vue +109 -0
  123. package/src/number-field/index.ts +42 -0
  124. package/src/number-field/input/NumberFieldInput.vue +455 -0
  125. package/src/number-field/root/NumberFieldRoot.vue +626 -0
  126. package/src/number-field/root/NumberFieldRootContext.ts +94 -0
  127. package/src/number-field/root/useNumberFieldButton.ts +171 -0
  128. package/src/number-field/scrub-area/NumberFieldScrubArea.vue +359 -0
  129. package/src/number-field/scrub-area/NumberFieldScrubAreaContext.ts +26 -0
  130. package/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.vue +75 -0
  131. package/src/number-field/utils/constants.ts +4 -0
  132. package/src/number-field/utils/getViewportRect.ts +34 -0
  133. package/src/number-field/utils/parse.ts +248 -0
  134. package/src/number-field/utils/stateAttributesMapping.ts +9 -0
  135. package/src/number-field/utils/subscribeToVisualViewportResize.ts +27 -0
  136. package/src/number-field/utils/types.ts +24 -0
  137. package/src/number-field/utils/validate.ts +120 -0
  138. package/src/otp-field/index.ts +22 -0
  139. package/src/otp-field/input/OtpFieldInput.vue +336 -0
  140. package/src/otp-field/root/OtpFieldRoot.vue +583 -0
  141. package/src/otp-field/root/OtpFieldRootContext.ts +81 -0
  142. package/src/otp-field/utils/otp.ts +135 -0
  143. package/src/otp-field/utils/stateAttributesMapping.ts +16 -0
  144. package/src/radio/index.ts +28 -0
  145. package/src/radio/indicator/RadioIndicator.vue +90 -0
  146. package/src/radio/indicator/RadioIndicatorDataAttributes.ts +54 -0
  147. package/src/radio/root/RadioRoot.vue +544 -0
  148. package/src/radio/root/RadioRootContext.ts +18 -0
  149. package/src/radio/root/RadioRootDataAttributes.ts +46 -0
  150. package/src/radio/utils/stateAttributesMapping.ts +29 -0
  151. package/src/radio-group/RadioGroup.vue +381 -0
  152. package/src/radio-group/RadioGroupContext.ts +42 -0
  153. package/src/radio-group/RadioGroupDataAttributes.ts +6 -0
  154. package/src/radio-group/index.ts +10 -0
  155. package/src/tabs/index.ts +38 -0
  156. package/src/tabs/indicator/TabsIndicator.vue +201 -0
  157. package/src/tabs/indicator/TabsIndicatorCssVars.ts +26 -0
  158. package/src/tabs/indicator/TabsIndicatorDataAttributes.ts +12 -0
  159. package/src/tabs/indicator/prehydrationScript.min.ts +5 -0
  160. package/src/tabs/indicator/prehydrationScript.template.js +87 -0
  161. package/src/tabs/list/TabsList.vue +201 -0
  162. package/src/tabs/list/TabsListContext.ts +29 -0
  163. package/src/tabs/list/TabsListDataAttributes.ts +12 -0
  164. package/src/tabs/panel/TabsPanel.vue +167 -0
  165. package/src/tabs/panel/TabsPanelDataAttributes.ts +28 -0
  166. package/src/tabs/root/TabsRoot.vue +468 -0
  167. package/src/tabs/root/TabsRootContext.ts +56 -0
  168. package/src/tabs/root/TabsRootDataAttributes.ts +12 -0
  169. package/src/tabs/root/stateAttributesMapping.ts +9 -0
  170. package/src/tabs/tab/TabsTab.vue +274 -0
  171. package/src/tabs/tab/TabsTabDataAttributes.ts +20 -0
  172. package/src/tabs/utils/areTabValuesEqual.ts +6 -0
  173. package/src/tooltip/arrow/TooltipArrow.vue +116 -0
  174. package/src/tooltip/arrow/TooltipArrowDataAttributes.ts +31 -0
  175. package/src/tooltip/index.ts +54 -0
  176. package/src/tooltip/popup/TooltipPopup.vue +142 -0
  177. package/src/tooltip/popup/TooltipPopupDataAttributes.ts +35 -0
  178. package/src/tooltip/portal/TooltipPortal.vue +83 -0
  179. package/src/tooltip/portal/TooltipPortalContext.ts +19 -0
  180. package/src/tooltip/positioner/TooltipPositioner.vue +221 -0
  181. package/src/tooltip/positioner/TooltipPositionerContext.ts +23 -0
  182. package/src/tooltip/positioner/TooltipPositionerCssVars.ts +27 -0
  183. package/src/tooltip/positioner/TooltipPositionerDataAttributes.ts +26 -0
  184. package/src/tooltip/provider/TooltipProvider.vue +78 -0
  185. package/src/tooltip/provider/TooltipProviderContext.ts +19 -0
  186. package/src/tooltip/root/TooltipRoot.vue +401 -0
  187. package/src/tooltip/root/TooltipRootContext.ts +71 -0
  188. package/src/tooltip/store/TooltipHandle.ts +215 -0
  189. package/src/tooltip/trigger/TooltipTrigger.vue +343 -0
  190. package/src/tooltip/trigger/TooltipTriggerDataAttributes.ts +12 -0
  191. package/src/tooltip/utils/constants.ts +2 -0
  192. package/src/tooltip/viewport/TooltipViewport.vue +149 -0
  193. package/src/tooltip/viewport/TooltipViewportCssVars.ts +14 -0
  194. package/src/tooltip/viewport/TooltipViewportDataAttributes.ts +26 -0
  195. package/src/utils/FloatingPortalLite.vue +66 -0
  196. package/src/utils/FocusGuard.vue +36 -0
  197. package/src/utils/adaptiveOriginMiddleware.ts +79 -0
  198. package/src/utils/addEventListener.ts +16 -0
  199. package/src/utils/constants.ts +11 -0
  200. package/src/utils/createBaseUIEventDetails.ts +2 -0
  201. package/src/utils/detectBrowser.ts +15 -0
  202. package/src/utils/formatNumber.ts +35 -2
  203. package/src/utils/getCssDimensions.ts +19 -0
  204. package/src/utils/getDisabledMountTransitionStyles.ts +9 -0
  205. package/src/utils/hideMiddleware.ts +19 -0
  206. package/src/utils/mergeCleanups.ts +7 -0
  207. package/src/utils/platform.ts +18 -0
  208. package/src/utils/popupStateMapping.ts +103 -0
  209. package/src/utils/reasons.ts +4 -0
  210. package/src/utils/serializeValue.ts +17 -0
  211. package/src/utils/useAnchorPositioning.ts +644 -0
  212. package/src/utils/useInterval.ts +45 -0
  213. package/src/utils/usePopupAutoResize.ts +254 -0
  214. package/src/utils/usePopupViewport.ts +398 -0
  215. package/src/utils/usePositioner.ts +61 -0
  216. package/src/utils/usePressAndHold.ts +260 -0
  217. package/src/utils/useRenderElement.ts +3 -0
  218. package/src/utils/useValueChanged.ts +21 -0
@@ -0,0 +1,274 @@
1
+ <script setup lang="ts">
2
+ import type { BaseUIChangeEventDetails } from '../../utils/createBaseUIEventDetails'
3
+ import type { BaseUIComponentProps, NativeButtonProps, Orientation } from '../../utils/types'
4
+ import type { TabsRootChangeEventReason } from '../root/TabsRoot.vue'
5
+ import { computed, ref, useAttrs, watch } from 'vue'
6
+ import { ACTIVE_COMPOSITE_ITEM } from '../../composite/constants'
7
+ import { useCompositeItem } from '../../composite/item/useCompositeItem'
8
+ import { activeElement, contains } from '../../floating-ui-vue/utils'
9
+ import { mergeProps } from '../../merge-props/mergeProps'
10
+ import { useButton } from '../../use-button'
11
+ import { createChangeEventDetails } from '../../utils/createBaseUIEventDetails'
12
+ import { ownerDocument } from '../../utils/owner'
13
+ import { REASONS } from '../../utils/reasons'
14
+ import { useBaseUiId } from '../../utils/useBaseUiId'
15
+ import { useMergedRefs } from '../../utils/useMergedRefs'
16
+ import { useRenderElement } from '../../utils/useRenderElement'
17
+ import { useTabsListContext } from '../list/TabsListContext'
18
+ import { tabsStateAttributesMapping } from '../root/stateAttributesMapping'
19
+ import { useTabsRootContext } from '../root/TabsRootContext'
20
+ import { areTabValuesEqual } from '../utils/areTabValuesEqual'
21
+
22
+ export type TabsTabValue = unknown
23
+ export type TabsTabActivationDirection = 'left' | 'right' | 'up' | 'down' | 'none'
24
+
25
+ export interface TabsTabPosition {
26
+ left: number
27
+ right: number
28
+ top: number
29
+ bottom: number
30
+ }
31
+
32
+ export interface TabsTabSize {
33
+ width: number
34
+ height: number
35
+ }
36
+
37
+ export interface TabsTabMetadata {
38
+ disabled: boolean
39
+ id: string | undefined
40
+ value: TabsTabValue | undefined
41
+ }
42
+
43
+ export interface TabsTabState {
44
+ /**
45
+ * Whether the component should ignore user interaction.
46
+ */
47
+ disabled: boolean
48
+ /**
49
+ * Whether the component is active.
50
+ */
51
+ active: boolean
52
+ /**
53
+ * The component orientation.
54
+ */
55
+ orientation: Orientation
56
+ /**
57
+ * The direction used for tab activation.
58
+ */
59
+ tabActivationDirection: TabsTabActivationDirection
60
+ }
61
+
62
+ export interface TabsTabProps
63
+ extends NativeButtonProps, BaseUIComponentProps<TabsTabState> {
64
+ /**
65
+ * The value of the Tab.
66
+ */
67
+ value?: TabsTabValue
68
+ /**
69
+ * Whether the Tab is disabled.
70
+ */
71
+ disabled?: boolean
72
+ /**
73
+ * The id of the Tab element.
74
+ */
75
+ id?: string
76
+ }
77
+
78
+ /**
79
+ * An individual interactive tab button that toggles the corresponding panel.
80
+ * Renders a `<button>` element.
81
+ *
82
+ * Documentation: [Base UI Vue Tabs](https://baseui-vue.com/docs/components/tabs)
83
+ */
84
+ defineOptions({
85
+ name: 'TabsTab',
86
+ inheritAttrs: false,
87
+ })
88
+
89
+ const props = withDefaults(defineProps<TabsTabProps>(), {
90
+ as: 'button',
91
+ disabled: false,
92
+ nativeButton: true,
93
+ })
94
+
95
+ const attrs = useAttrs()
96
+ const rootCtx = useTabsRootContext()
97
+ const listCtx = useTabsListContext()
98
+
99
+ const id = useBaseUiId(props.id)
100
+ const tabMetadata = computed<TabsTabMetadata>(() => ({
101
+ disabled: props.disabled,
102
+ id,
103
+ value: props.value,
104
+ }))
105
+
106
+ const {
107
+ compositeProps,
108
+ compositeRef,
109
+ index,
110
+ } = useCompositeItem<TabsTabMetadata>({
111
+ metadata: () => tabMetadata.value,
112
+ })
113
+
114
+ const value = computed<TabsTabValue>(() => props.value ?? index.value)
115
+ const active = computed(() => areTabValuesEqual(value.value, rootCtx.value.value))
116
+ const isNavigating = ref(false)
117
+ const isPressing = ref(false)
118
+ const isMainButton = ref(false)
119
+ const tabElementRef = ref<HTMLElement | null>(null)
120
+
121
+ watch(
122
+ tabElementRef,
123
+ (tabElement, _, onCleanup) => {
124
+ if (!tabElement) {
125
+ return
126
+ }
127
+ const cleanup = listCtx.registerTabResizeObserverElement(tabElement)
128
+ onCleanup(cleanup)
129
+ },
130
+ { flush: 'post' },
131
+ )
132
+
133
+ watch(
134
+ [active, index, listCtx.highlightedTabIndex, listCtx.tabsListElement],
135
+ () => {
136
+ if (isNavigating.value) {
137
+ isNavigating.value = false
138
+ return
139
+ }
140
+
141
+ if (!(active.value && index.value > -1 && listCtx.highlightedTabIndex.value !== index.value)) {
142
+ return
143
+ }
144
+
145
+ const listElement = listCtx.tabsListElement.value
146
+ if (listElement != null) {
147
+ const doc = ownerDocument(listElement)
148
+ const focusedElement = doc ? activeElement(doc) : null
149
+ if (focusedElement && contains(listElement, focusedElement)) {
150
+ return
151
+ }
152
+ }
153
+
154
+ if (!props.disabled) {
155
+ listCtx.setHighlightedTabIndex(index.value)
156
+ }
157
+ },
158
+ { flush: 'post' },
159
+ )
160
+
161
+ const { getButtonProps, buttonRef } = useButton({
162
+ disabled: () => props.disabled,
163
+ native: () => props.nativeButton ?? true,
164
+ focusableWhenDisabled: () => true,
165
+ })
166
+
167
+ const tabPanelId = computed(() => rootCtx.getTabPanelIdByValue(value.value))
168
+
169
+ function createTabDetails(event?: Event) {
170
+ return createChangeEventDetails<TabsRootChangeEventReason, { activationDirection: TabsTabActivationDirection }>(
171
+ REASONS.none,
172
+ event,
173
+ undefined,
174
+ { activationDirection: 'none' },
175
+ ) as BaseUIChangeEventDetails<TabsRootChangeEventReason, { activationDirection: TabsTabActivationDirection }>
176
+ }
177
+
178
+ function handleClick(event: MouseEvent) {
179
+ if (event.button !== 0 || active.value || props.disabled) {
180
+ return
181
+ }
182
+
183
+ listCtx.onTabActivation(value.value, createTabDetails(event))
184
+ }
185
+
186
+ function handleFocus(event: FocusEvent) {
187
+ if (active.value) {
188
+ return
189
+ }
190
+
191
+ if (index.value > -1 && !props.disabled) {
192
+ listCtx.setHighlightedTabIndex(index.value)
193
+ }
194
+
195
+ if (props.disabled) {
196
+ return
197
+ }
198
+
199
+ if (
200
+ listCtx.activateOnFocus.value
201
+ && (!isPressing.value || (isPressing.value && isMainButton.value))
202
+ ) {
203
+ listCtx.onTabActivation(value.value, createTabDetails(event))
204
+ }
205
+ }
206
+
207
+ function handlePointerDown(event: PointerEvent) {
208
+ if (active.value || props.disabled) {
209
+ return
210
+ }
211
+
212
+ isPressing.value = true
213
+
214
+ function handlePointerUp() {
215
+ isPressing.value = false
216
+ isMainButton.value = false
217
+ }
218
+
219
+ if (!event.button || event.button === 0) {
220
+ isMainButton.value = true
221
+
222
+ const doc = ownerDocument(event.currentTarget as Element)
223
+ doc?.addEventListener('pointerup', handlePointerUp, { once: true })
224
+ }
225
+ }
226
+
227
+ const state = computed<TabsTabState>(() => ({
228
+ disabled: props.disabled,
229
+ active: active.value,
230
+ orientation: rootCtx.orientation.value,
231
+ tabActivationDirection: rootCtx.tabActivationDirection.value,
232
+ }))
233
+
234
+ function createTabProps() {
235
+ return getButtonProps(mergeProps(
236
+ compositeProps.value,
237
+ {
238
+ 'role': 'tab',
239
+ 'aria-controls': tabPanelId.value,
240
+ 'aria-selected': active.value,
241
+ id,
242
+ [ACTIVE_COMPOSITE_ITEM]: active.value ? '' : undefined,
243
+ 'onClick': handleClick,
244
+ 'onFocus': handleFocus,
245
+ 'onPointerdown': handlePointerDown,
246
+ onKeydownCapture() {
247
+ isNavigating.value = true
248
+ },
249
+ },
250
+ attrs as Record<string, any>,
251
+ ))
252
+ }
253
+
254
+ const {
255
+ tag,
256
+ mergedProps,
257
+ renderless,
258
+ ref: renderRef,
259
+ } = useRenderElement({
260
+ componentProps: props,
261
+ state,
262
+ props: computed(() => createTabProps()),
263
+ stateAttributesMapping: tabsStateAttributesMapping,
264
+ defaultTagName: 'button',
265
+ ref: useMergedRefs(buttonRef, compositeRef, tabElementRef),
266
+ })
267
+ </script>
268
+
269
+ <template>
270
+ <slot v-if="renderless" :ref="renderRef" :props="mergedProps" :state="state" />
271
+ <component :is="tag" v-else :ref="renderRef" v-bind="mergedProps">
272
+ <slot :state="state" />
273
+ </component>
274
+ </template>
@@ -0,0 +1,20 @@
1
+ export enum TabsTabDataAttributes {
2
+ /**
3
+ * Indicates the direction of the activation (based on the previous active tab).
4
+ * @type {'left' | 'right' | 'up' | 'down' | 'none'}
5
+ */
6
+ activationDirection = 'data-activation-direction',
7
+ /**
8
+ * Indicates the orientation of the tabs.
9
+ * @type {'horizontal' | 'vertical'}
10
+ */
11
+ orientation = 'data-orientation',
12
+ /**
13
+ * Present when the tab is disabled.
14
+ */
15
+ disabled = 'data-disabled',
16
+ /**
17
+ * Present when the tab is active.
18
+ */
19
+ active = 'data-active',
20
+ }
@@ -0,0 +1,6 @@
1
+ import type { TabsTabValue } from '../tab/TabsTab.vue'
2
+ import { toRaw } from 'vue'
3
+
4
+ export function areTabValuesEqual(a: TabsTabValue | undefined, b: TabsTabValue | undefined) {
5
+ return a === b || toRaw(a) === toRaw(b)
6
+ }
@@ -0,0 +1,116 @@
1
+ <script setup lang="ts">
2
+ import type { BaseUIComponentProps } from '../../utils/types'
3
+ import type { Align, Side } from '../../utils/useAnchorPositioning'
4
+ import type { TooltipInstantType } from '../root/TooltipRoot.vue'
5
+ import { computed, useAttrs } from 'vue'
6
+ import { popupStateMapping } from '../../utils/popupStateMapping'
7
+ import { useRenderElement } from '../../utils/useRenderElement'
8
+ import { useTooltipPositionerContext } from '../positioner/TooltipPositionerContext'
9
+ import { useTooltipRootContext } from '../root/TooltipRootContext'
10
+ import { TooltipArrowDataAttributes } from './TooltipArrowDataAttributes'
11
+
12
+ /**
13
+ * Displays an element positioned against the tooltip anchor.
14
+ * Renders a `<div>` element.
15
+ *
16
+ * Documentation: [Base UI Vue Tooltip](https://baseui-vue.com/docs/components/tooltip)
17
+ */
18
+ defineOptions({
19
+ name: 'TooltipArrow',
20
+ inheritAttrs: false,
21
+ })
22
+
23
+ const props = withDefaults(defineProps<TooltipArrowProps>(), {
24
+ as: 'div',
25
+ })
26
+
27
+ const attrs = useAttrs()
28
+ const ctx = useTooltipRootContext()
29
+ const positioner = useTooltipPositionerContext()
30
+
31
+ const state = computed<TooltipArrowState>(() => ({
32
+ open: ctx.open.value,
33
+ side: positioner.side.value,
34
+ align: positioner.align.value,
35
+ uncentered: positioner.arrowUncentered.value,
36
+ instant: ctx.instantType.value,
37
+ }))
38
+
39
+ const arrowStyle = computed(() => {
40
+ return positioner.arrowStyles.value
41
+ })
42
+
43
+ const arrowProps = computed(() => {
44
+ const resolvedStyle = typeof props.style === 'function'
45
+ ? props.style(state.value)
46
+ : props.style
47
+
48
+ return {
49
+ ...attrs,
50
+ 'aria-hidden': 'true',
51
+ 'style': [
52
+ arrowStyle.value,
53
+ resolvedStyle,
54
+ ],
55
+ }
56
+ })
57
+
58
+ const {
59
+ tag,
60
+ mergedProps,
61
+ renderless,
62
+ ref: renderRef,
63
+ } = useRenderElement({
64
+ componentProps: {
65
+ as: props.as,
66
+ class: props.class,
67
+ },
68
+ state,
69
+ props: arrowProps,
70
+ stateAttributesMapping: {
71
+ ...popupStateMapping,
72
+ uncentered(value) {
73
+ return value ? { [TooltipArrowDataAttributes.uncentered]: '' } : null
74
+ },
75
+ instant(value) {
76
+ return value ? { [TooltipArrowDataAttributes.instant]: value } : null
77
+ },
78
+ },
79
+ defaultTagName: 'div',
80
+ ref: positioner.arrowRef,
81
+ })
82
+ </script>
83
+
84
+ <script lang="ts">
85
+ export interface TooltipArrowState {
86
+ /**
87
+ * Whether the tooltip is currently open.
88
+ */
89
+ open: boolean
90
+ /**
91
+ * The side of the anchor the component is placed on.
92
+ */
93
+ side: Side
94
+ /**
95
+ * The alignment of the component relative to the anchor.
96
+ */
97
+ align: Align
98
+ /**
99
+ * Whether the arrow cannot be centered on the anchor.
100
+ */
101
+ uncentered: boolean
102
+ /**
103
+ * Whether transitions should be skipped.
104
+ */
105
+ instant: TooltipInstantType
106
+ }
107
+
108
+ export interface TooltipArrowProps extends BaseUIComponentProps<TooltipArrowState> {}
109
+ </script>
110
+
111
+ <template>
112
+ <slot v-if="renderless" :ref="renderRef" :props="mergedProps" :state="state" />
113
+ <component :is="tag" v-else :ref="renderRef" v-bind="mergedProps">
114
+ <slot :state="state" />
115
+ </component>
116
+ </template>
@@ -0,0 +1,31 @@
1
+ import { CommonPopupDataAttributes } from '../../utils/popupStateMapping'
2
+
3
+ export enum TooltipArrowDataAttributes {
4
+ /**
5
+ * Present when the tooltip is open.
6
+ */
7
+ open = CommonPopupDataAttributes.open,
8
+ /**
9
+ * Present when the tooltip is closed.
10
+ */
11
+ closed = CommonPopupDataAttributes.closed,
12
+ /**
13
+ * Indicates which side the popup is positioned relative to the trigger.
14
+ * @type {'top' | 'bottom' | 'left' | 'right' | 'inline-end' | 'inline-start'}
15
+ */
16
+ side = CommonPopupDataAttributes.side,
17
+ /**
18
+ * Indicates how the popup is aligned relative to specified side.
19
+ * @type {'start' | 'center' | 'end'}
20
+ */
21
+ align = CommonPopupDataAttributes.align,
22
+ /**
23
+ * Present when the tooltip arrow is uncentered.
24
+ */
25
+ uncentered = 'data-uncentered',
26
+ /**
27
+ * Present if animations should be instant.
28
+ * @type {'delay' | 'dismiss' | 'focus'}
29
+ */
30
+ instant = 'data-instant',
31
+ }
@@ -0,0 +1,54 @@
1
+ export { default as TooltipArrow } from './arrow/TooltipArrow.vue'
2
+ export type { TooltipArrowProps, TooltipArrowState } from './arrow/TooltipArrow.vue'
3
+ export { TooltipArrowDataAttributes } from './arrow/TooltipArrowDataAttributes'
4
+ export { default as TooltipPopup } from './popup/TooltipPopup.vue'
5
+ export type { TooltipPopupProps, TooltipPopupState } from './popup/TooltipPopup.vue'
6
+ export { TooltipPopupDataAttributes } from './popup/TooltipPopupDataAttributes'
7
+ export { default as TooltipPortal } from './portal/TooltipPortal.vue'
8
+ export type { TooltipPortalProps, TooltipPortalState } from './portal/TooltipPortal.vue'
9
+ export { tooltipPortalContextKey, useTooltipPortalContext } from './portal/TooltipPortalContext'
10
+ export { default as TooltipPositioner } from './positioner/TooltipPositioner.vue'
11
+ export type {
12
+ TooltipAlign,
13
+ TooltipFloatingPlacement,
14
+ TooltipPositionerInstantType,
15
+ TooltipPositionerProps,
16
+ TooltipPositionerState,
17
+ TooltipSide,
18
+ } from './positioner/TooltipPositioner.vue'
19
+ export { tooltipPositionerContextKey, useTooltipPositionerContext } from './positioner/TooltipPositionerContext'
20
+ export type { TooltipPositionerContext } from './positioner/TooltipPositionerContext'
21
+ export { TooltipPositionerCssVars } from './positioner/TooltipPositionerCssVars'
22
+ export { TooltipPositionerDataAttributes } from './positioner/TooltipPositionerDataAttributes'
23
+ export { default as TooltipProvider } from './provider/TooltipProvider.vue'
24
+ export type { TooltipProviderProps, TooltipProviderState } from './provider/TooltipProvider.vue'
25
+ export { tooltipProviderContextKey, useTooltipProviderContext } from './provider/TooltipProviderContext'
26
+ export type { TooltipProviderContext } from './provider/TooltipProviderContext'
27
+ export { default as TooltipRoot } from './root/TooltipRoot.vue'
28
+ export type {
29
+ TooltipInstantType,
30
+ TooltipRootActions,
31
+ TooltipRootChangeEventDetails,
32
+ TooltipRootChangeEventReason,
33
+ TooltipRootProps,
34
+ TooltipRootState,
35
+ TooltipTrackCursorAxis,
36
+ } from './root/TooltipRoot.vue'
37
+ export { tooltipRootContextKey, useTooltipRootContext } from './root/TooltipRootContext'
38
+ export type { TooltipRootContext } from './root/TooltipRootContext'
39
+ export {
40
+ createTooltipHandle,
41
+ TooltipHandle,
42
+ TooltipStore,
43
+ } from './store/TooltipHandle'
44
+ export type {
45
+ TooltipRootController,
46
+ TooltipTriggerRecord,
47
+ } from './store/TooltipHandle'
48
+ export { default as TooltipTrigger } from './trigger/TooltipTrigger.vue'
49
+ export type { TooltipTriggerProps, TooltipTriggerState } from './trigger/TooltipTrigger.vue'
50
+ export { TooltipTriggerDataAttributes } from './trigger/TooltipTriggerDataAttributes'
51
+ export { default as TooltipViewport } from './viewport/TooltipViewport.vue'
52
+ export type { TooltipViewportProps, TooltipViewportState } from './viewport/TooltipViewport.vue'
53
+ export { TooltipViewportCssVars } from './viewport/TooltipViewportCssVars'
54
+ export { TooltipViewportDataAttributes } from './viewport/TooltipViewportDataAttributes'
@@ -0,0 +1,142 @@
1
+ <script setup lang="ts">
2
+ import type { StateAttributesMapping } from '../../utils/getStateAttributesProps'
3
+ import type { BaseUIComponentProps } from '../../utils/types'
4
+ import type { Align, Side } from '../../utils/useAnchorPositioning'
5
+ import type { TransitionStatus } from '../../utils/useTransitionStatus'
6
+ import type { TooltipInstantType } from '../root/TooltipRoot.vue'
7
+ import { computed, shallowRef, useAttrs, watch } from 'vue'
8
+ import { useHoverFloatingInteraction } from '../../floating-ui-vue'
9
+ import { mergeProps } from '../../merge-props/mergeProps'
10
+ import { getDisabledMountTransitionStyles } from '../../utils/getDisabledMountTransitionStyles'
11
+ import { popupStateMapping } from '../../utils/popupStateMapping'
12
+ import { transitionStatusMapping } from '../../utils/stateAttributesMapping'
13
+ import { useBaseUiId } from '../../utils/useBaseUiId'
14
+ import { useMergedRefs } from '../../utils/useMergedRefs'
15
+ import { useOpenChangeComplete } from '../../utils/useOpenChangeComplete'
16
+ import { useRenderElement } from '../../utils/useRenderElement'
17
+ import { useTooltipPositionerContext } from '../positioner/TooltipPositionerContext'
18
+ import { useTooltipRootContext } from '../root/TooltipRootContext'
19
+
20
+ /**
21
+ * A container for the tooltip contents.
22
+ * Renders a `<div>` element.
23
+ *
24
+ * Documentation: [Base UI Tooltip](https://baseui-vue.com/docs/components/tooltip)
25
+ */
26
+ defineOptions({
27
+ name: 'TooltipPopup',
28
+ inheritAttrs: false,
29
+ })
30
+
31
+ const props = withDefaults(defineProps<TooltipPopupProps>(), {
32
+ as: 'div',
33
+ })
34
+
35
+ const stateAttributesMapping: StateAttributesMapping<TooltipPopupState> = {
36
+ ...popupStateMapping,
37
+ ...transitionStatusMapping,
38
+ }
39
+
40
+ const attrs = useAttrs()
41
+ const ctx = useTooltipRootContext()
42
+ const positioner = useTooltipPositionerContext()
43
+ const generatedId = useBaseUiId(props.id)
44
+ const localPopupRef = shallowRef<HTMLElement | null>(null)
45
+
46
+ const state = computed<TooltipPopupState>(() => ({
47
+ open: ctx.open.value,
48
+ side: positioner.side.value,
49
+ align: positioner.align.value,
50
+ instant: ctx.instantType.value,
51
+ transitionStatus: ctx.transitionStatus.value,
52
+ }))
53
+
54
+ watch(
55
+ () => props.id,
56
+ () => ctx.setPopupId(generatedId),
57
+ { immediate: true },
58
+ )
59
+
60
+ useOpenChangeComplete({
61
+ open: () => ctx.open.value,
62
+ ref: localPopupRef,
63
+ onComplete() {
64
+ ctx.completeOpenChange()
65
+ ctx.instantType.value = undefined
66
+ },
67
+ })
68
+
69
+ useHoverFloatingInteraction(ctx.floatingRootContext, {
70
+ enabled: () => !ctx.disabled.value && !ctx.disableHoverablePopup.value,
71
+ closeDelay: () => ctx.getCloseDelay(ctx.activeTrigger.value?.closeDelay),
72
+ })
73
+
74
+ const popupProps = computed(() => {
75
+ return mergeProps(
76
+ getDisabledMountTransitionStyles(ctx.transitionStatus.value),
77
+ ctx.dismiss?.floating,
78
+ attrs,
79
+ {
80
+ id: generatedId,
81
+ role: 'tooltip',
82
+ },
83
+ )
84
+ })
85
+
86
+ const {
87
+ tag,
88
+ mergedProps,
89
+ renderless,
90
+ ref: renderRef,
91
+ } = useRenderElement({
92
+ componentProps: {
93
+ as: props.as,
94
+ class: props.class,
95
+ style: props.style,
96
+ },
97
+ state,
98
+ props: popupProps,
99
+ stateAttributesMapping,
100
+ defaultTagName: 'div',
101
+ ref: useMergedRefs(localPopupRef, ctx.popupRef),
102
+ })
103
+ </script>
104
+
105
+ <script lang="ts">
106
+ export interface TooltipPopupState {
107
+ /**
108
+ * Whether the tooltip is currently open.
109
+ */
110
+ open: boolean
111
+ /**
112
+ * The side of the anchor the component is placed on.
113
+ */
114
+ side: Side
115
+ /**
116
+ * The alignment of the component relative to the anchor.
117
+ */
118
+ align: Align
119
+ /**
120
+ * Whether transitions should be skipped.
121
+ */
122
+ instant: TooltipInstantType
123
+ /**
124
+ * The transition status of the component.
125
+ */
126
+ transitionStatus: TransitionStatus
127
+ }
128
+
129
+ export interface TooltipPopupProps extends BaseUIComponentProps<TooltipPopupState> {
130
+ /**
131
+ * The popup id used by the trigger while open.
132
+ */
133
+ id?: string
134
+ }
135
+ </script>
136
+
137
+ <template>
138
+ <slot v-if="renderless" :ref="renderRef" :props="mergedProps" :state="state" />
139
+ <component :is="tag" v-else :ref="renderRef" v-bind="mergedProps">
140
+ <slot :state="state" />
141
+ </component>
142
+ </template>
@@ -0,0 +1,35 @@
1
+ import { CommonPopupDataAttributes } from '../../utils/popupStateMapping'
2
+
3
+ export enum TooltipPopupDataAttributes {
4
+ /**
5
+ * Present when the tooltip is open.
6
+ */
7
+ open = CommonPopupDataAttributes.open,
8
+ /**
9
+ * Present when the tooltip is closed.
10
+ */
11
+ closed = CommonPopupDataAttributes.closed,
12
+ /**
13
+ * Present when the tooltip is animating in.
14
+ */
15
+ startingStyle = CommonPopupDataAttributes.startingStyle,
16
+ /**
17
+ * Present when the tooltip is animating out.
18
+ */
19
+ endingStyle = CommonPopupDataAttributes.endingStyle,
20
+ /**
21
+ * Indicates which side the popup is positioned relative to the trigger.
22
+ * @type {'top' | 'bottom' | 'left' | 'right' | 'inline-end' | 'inline-start'}
23
+ */
24
+ side = CommonPopupDataAttributes.side,
25
+ /**
26
+ * Indicates how the popup is aligned relative to specified side.
27
+ * @type {'start' | 'center' | 'end'}
28
+ */
29
+ align = CommonPopupDataAttributes.align,
30
+ /**
31
+ * Present if animations should be instant.
32
+ * @type {'delay' | 'dismiss' | 'focus'}
33
+ */
34
+ instant = 'data-instant',
35
+ }