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.
- package/dist/arrow/TooltipArrow.cjs +609 -0
- package/dist/arrow/TooltipArrow.cjs.map +1 -0
- package/dist/arrow/TooltipArrow.js +478 -0
- package/dist/arrow/TooltipArrow.js.map +1 -0
- package/dist/button/Button.cjs +5 -317
- package/dist/button/Button.cjs.map +1 -1
- package/dist/button/Button.js +3 -249
- package/dist/button/Button.js.map +1 -1
- package/dist/button/ToolbarButton.cjs +19 -6
- package/dist/button/ToolbarButton.cjs.map +1 -1
- package/dist/button/ToolbarButton.js +3 -2
- package/dist/button/ToolbarButton.js.map +1 -1
- package/dist/checkbox/index.cjs +20 -9
- package/dist/checkbox/index.cjs.map +1 -1
- package/dist/checkbox/index.js +7 -2
- package/dist/checkbox/index.js.map +1 -1
- package/dist/checkbox-group/CheckboxGroup.cjs +14 -13
- package/dist/checkbox-group/CheckboxGroup.cjs.map +1 -1
- package/dist/checkbox-group/CheckboxGroup.js +2 -1
- package/dist/checkbox-group/CheckboxGroup.js.map +1 -1
- package/dist/components/FloatingPortal.cjs +66 -0
- package/dist/components/FloatingPortal.cjs.map +1 -0
- package/dist/components/FloatingPortal.js +55 -0
- package/dist/components/FloatingPortal.js.map +1 -0
- package/dist/components/FloatingRootStore.cjs +101 -0
- package/dist/components/FloatingRootStore.cjs.map +1 -0
- package/dist/components/FloatingRootStore.js +84 -0
- package/dist/components/FloatingRootStore.js.map +1 -0
- package/dist/components/FloatingTree.cjs +33 -0
- package/dist/components/FloatingTree.cjs.map +1 -0
- package/dist/components/FloatingTree.js +22 -0
- package/dist/components/FloatingTree.js.map +1 -0
- package/dist/composite/composite.cjs +6 -0
- package/dist/composite/composite.js +1 -1
- package/dist/content/ScrollAreaContent.cjs +3 -3
- package/dist/content/ScrollAreaContent.cjs.map +1 -1
- package/dist/content/ScrollAreaContent.js +1 -1
- package/dist/control/FieldControl.cjs +3 -3
- package/dist/control/FieldControl.cjs.map +1 -1
- package/dist/control/FieldControl.js +1 -1
- package/dist/control/SliderControl.cjs +3 -3
- package/dist/control/SliderControl.cjs.map +1 -1
- package/dist/control/SliderControl.js +3 -3
- package/dist/corner/ScrollAreaCorner.cjs +3 -3
- package/dist/corner/ScrollAreaCorner.cjs.map +1 -1
- package/dist/corner/ScrollAreaCorner.js +1 -1
- package/dist/decrement/NumberFieldDecrement.cjs +868 -0
- package/dist/decrement/NumberFieldDecrement.cjs.map +1 -0
- package/dist/decrement/NumberFieldDecrement.js +701 -0
- package/dist/decrement/NumberFieldDecrement.js.map +1 -0
- package/dist/description/FieldDescription.cjs +2 -2
- package/dist/description/FieldDescription.cjs.map +1 -1
- package/dist/description/FieldDescription.js +1 -1
- package/dist/error/FieldError.cjs +2 -2
- package/dist/error/FieldError.cjs.map +1 -1
- package/dist/error/FieldError.js +1 -1
- package/dist/fallback/AvatarFallback.cjs +4 -48
- package/dist/fallback/AvatarFallback.cjs.map +1 -1
- package/dist/fallback/AvatarFallback.js +4 -42
- package/dist/fallback/AvatarFallback.js.map +1 -1
- package/dist/floating-ui-vue/index.js +638 -0
- package/dist/floating-ui-vue/index.js.map +1 -0
- package/dist/form/Form.cjs +3 -3
- package/dist/form/Form.cjs.map +1 -1
- package/dist/form/Form.js +1 -1
- package/dist/group/NumberFieldGroup.cjs +72 -0
- package/dist/group/NumberFieldGroup.cjs.map +1 -0
- package/dist/group/NumberFieldGroup.js +67 -0
- package/dist/group/NumberFieldGroup.js.map +1 -0
- package/dist/group/ToolbarGroup.cjs +2 -2
- package/dist/group/ToolbarGroup.cjs.map +1 -1
- package/dist/group/ToolbarGroup.js +1 -1
- package/dist/header/AccordionHeader.cjs +2 -2
- package/dist/header/AccordionHeader.cjs.map +1 -1
- package/dist/header/AccordionHeader.js +1 -1
- package/dist/hooks/useDismiss.cjs +502 -0
- package/dist/hooks/useDismiss.cjs.map +1 -0
- package/dist/hooks/useHoverFloatingInteraction.cjs +233 -0
- package/dist/hooks/useHoverFloatingInteraction.cjs.map +1 -0
- package/dist/image/AvatarImage.cjs +4 -4
- package/dist/image/AvatarImage.cjs.map +1 -1
- package/dist/image/AvatarImage.js +1 -1
- package/dist/increment/NumberFieldIncrement.cjs +113 -0
- package/dist/increment/NumberFieldIncrement.cjs.map +1 -0
- package/dist/increment/NumberFieldIncrement.js +108 -0
- package/dist/increment/NumberFieldIncrement.js.map +1 -0
- package/dist/index.cjs +80 -8
- package/dist/index.d.cts +4328 -1600
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +4328 -1600
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index2.cjs +9435 -3236
- package/dist/index2.cjs.map +1 -1
- package/dist/index2.js +8905 -3049
- package/dist/index2.js.map +1 -1
- package/dist/rolldown-runtime.js +36 -0
- package/package.json +1 -1
- package/src/floating-ui-vue/components/FloatingPortal.ts +171 -0
- package/src/floating-ui-vue/components/FloatingPortal.vue +259 -0
- package/src/floating-ui-vue/components/FloatingRootStore.ts +83 -0
- package/src/floating-ui-vue/components/FloatingTree.ts +64 -0
- package/src/floating-ui-vue/components/FloatingTreeStore.ts +21 -0
- package/src/floating-ui-vue/hooks/useDismiss.ts +689 -0
- package/src/floating-ui-vue/hooks/useHoverFloatingInteraction.ts +244 -0
- package/src/floating-ui-vue/hooks/useHoverInteractionSharedState.ts +125 -0
- package/src/floating-ui-vue/hooks/useHoverShared.ts +53 -0
- package/src/floating-ui-vue/index.ts +48 -0
- package/src/floating-ui-vue/middleware/arrow.ts +114 -0
- package/src/floating-ui-vue/types.ts +117 -0
- package/src/floating-ui-vue/utils/composite.ts +20 -0
- package/src/floating-ui-vue/utils/constants.ts +2 -0
- package/src/floating-ui-vue/utils/createAttribute.ts +3 -0
- package/src/floating-ui-vue/utils/createEventEmitter.ts +20 -0
- package/src/floating-ui-vue/utils/element.ts +59 -0
- package/src/floating-ui-vue/utils/event.ts +15 -0
- package/src/floating-ui-vue/utils/nodes.ts +14 -0
- package/src/floating-ui-vue/utils/tabbable.ts +309 -0
- package/src/index.ts +7 -1
- package/src/number-field/decrement/NumberFieldDecrement.vue +109 -0
- package/src/number-field/group/NumberFieldGroup.vue +47 -0
- package/src/number-field/increment/NumberFieldIncrement.vue +109 -0
- package/src/number-field/index.ts +42 -0
- package/src/number-field/input/NumberFieldInput.vue +455 -0
- package/src/number-field/root/NumberFieldRoot.vue +626 -0
- package/src/number-field/root/NumberFieldRootContext.ts +94 -0
- package/src/number-field/root/useNumberFieldButton.ts +171 -0
- package/src/number-field/scrub-area/NumberFieldScrubArea.vue +359 -0
- package/src/number-field/scrub-area/NumberFieldScrubAreaContext.ts +26 -0
- package/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.vue +75 -0
- package/src/number-field/utils/constants.ts +4 -0
- package/src/number-field/utils/getViewportRect.ts +34 -0
- package/src/number-field/utils/parse.ts +248 -0
- package/src/number-field/utils/stateAttributesMapping.ts +9 -0
- package/src/number-field/utils/subscribeToVisualViewportResize.ts +27 -0
- package/src/number-field/utils/types.ts +24 -0
- package/src/number-field/utils/validate.ts +120 -0
- package/src/otp-field/index.ts +22 -0
- package/src/otp-field/input/OtpFieldInput.vue +336 -0
- package/src/otp-field/root/OtpFieldRoot.vue +583 -0
- package/src/otp-field/root/OtpFieldRootContext.ts +81 -0
- package/src/otp-field/utils/otp.ts +135 -0
- package/src/otp-field/utils/stateAttributesMapping.ts +16 -0
- package/src/radio/index.ts +28 -0
- package/src/radio/indicator/RadioIndicator.vue +90 -0
- package/src/radio/indicator/RadioIndicatorDataAttributes.ts +54 -0
- package/src/radio/root/RadioRoot.vue +544 -0
- package/src/radio/root/RadioRootContext.ts +18 -0
- package/src/radio/root/RadioRootDataAttributes.ts +46 -0
- package/src/radio/utils/stateAttributesMapping.ts +29 -0
- package/src/radio-group/RadioGroup.vue +381 -0
- package/src/radio-group/RadioGroupContext.ts +42 -0
- package/src/radio-group/RadioGroupDataAttributes.ts +6 -0
- package/src/radio-group/index.ts +10 -0
- package/src/tabs/index.ts +38 -0
- package/src/tabs/indicator/TabsIndicator.vue +201 -0
- package/src/tabs/indicator/TabsIndicatorCssVars.ts +26 -0
- package/src/tabs/indicator/TabsIndicatorDataAttributes.ts +12 -0
- package/src/tabs/indicator/prehydrationScript.min.ts +5 -0
- package/src/tabs/indicator/prehydrationScript.template.js +87 -0
- package/src/tabs/list/TabsList.vue +201 -0
- package/src/tabs/list/TabsListContext.ts +29 -0
- package/src/tabs/list/TabsListDataAttributes.ts +12 -0
- package/src/tabs/panel/TabsPanel.vue +167 -0
- package/src/tabs/panel/TabsPanelDataAttributes.ts +28 -0
- package/src/tabs/root/TabsRoot.vue +468 -0
- package/src/tabs/root/TabsRootContext.ts +56 -0
- package/src/tabs/root/TabsRootDataAttributes.ts +12 -0
- package/src/tabs/root/stateAttributesMapping.ts +9 -0
- package/src/tabs/tab/TabsTab.vue +274 -0
- package/src/tabs/tab/TabsTabDataAttributes.ts +20 -0
- package/src/tabs/utils/areTabValuesEqual.ts +6 -0
- package/src/tooltip/arrow/TooltipArrow.vue +116 -0
- package/src/tooltip/arrow/TooltipArrowDataAttributes.ts +31 -0
- package/src/tooltip/index.ts +54 -0
- package/src/tooltip/popup/TooltipPopup.vue +142 -0
- package/src/tooltip/popup/TooltipPopupDataAttributes.ts +35 -0
- package/src/tooltip/portal/TooltipPortal.vue +83 -0
- package/src/tooltip/portal/TooltipPortalContext.ts +19 -0
- package/src/tooltip/positioner/TooltipPositioner.vue +221 -0
- package/src/tooltip/positioner/TooltipPositionerContext.ts +23 -0
- package/src/tooltip/positioner/TooltipPositionerCssVars.ts +27 -0
- package/src/tooltip/positioner/TooltipPositionerDataAttributes.ts +26 -0
- package/src/tooltip/provider/TooltipProvider.vue +78 -0
- package/src/tooltip/provider/TooltipProviderContext.ts +19 -0
- package/src/tooltip/root/TooltipRoot.vue +401 -0
- package/src/tooltip/root/TooltipRootContext.ts +71 -0
- package/src/tooltip/store/TooltipHandle.ts +215 -0
- package/src/tooltip/trigger/TooltipTrigger.vue +343 -0
- package/src/tooltip/trigger/TooltipTriggerDataAttributes.ts +12 -0
- package/src/tooltip/utils/constants.ts +2 -0
- package/src/tooltip/viewport/TooltipViewport.vue +149 -0
- package/src/tooltip/viewport/TooltipViewportCssVars.ts +14 -0
- package/src/tooltip/viewport/TooltipViewportDataAttributes.ts +26 -0
- package/src/utils/FloatingPortalLite.vue +66 -0
- package/src/utils/FocusGuard.vue +36 -0
- package/src/utils/adaptiveOriginMiddleware.ts +79 -0
- package/src/utils/addEventListener.ts +16 -0
- package/src/utils/constants.ts +11 -0
- package/src/utils/createBaseUIEventDetails.ts +2 -0
- package/src/utils/detectBrowser.ts +15 -0
- package/src/utils/formatNumber.ts +35 -2
- package/src/utils/getCssDimensions.ts +19 -0
- package/src/utils/getDisabledMountTransitionStyles.ts +9 -0
- package/src/utils/hideMiddleware.ts +19 -0
- package/src/utils/mergeCleanups.ts +7 -0
- package/src/utils/platform.ts +18 -0
- package/src/utils/popupStateMapping.ts +103 -0
- package/src/utils/reasons.ts +4 -0
- package/src/utils/serializeValue.ts +17 -0
- package/src/utils/useAnchorPositioning.ts +644 -0
- package/src/utils/useInterval.ts +45 -0
- package/src/utils/usePopupAutoResize.ts +254 -0
- package/src/utils/usePopupViewport.ts +398 -0
- package/src/utils/usePositioner.ts +61 -0
- package/src/utils/usePressAndHold.ts +260 -0
- package/src/utils/useRenderElement.ts +3 -0
- package/src/utils/useValueChanged.ts +21 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
interface OTPValidationConfig {
|
|
2
|
+
slotPattern: string
|
|
3
|
+
getRootPattern: (length: number) => string
|
|
4
|
+
regexp: RegExp
|
|
5
|
+
inputMode: 'numeric' | 'text'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type OtpValidationType = 'numeric' | 'alpha' | 'alphanumeric' | 'none'
|
|
9
|
+
|
|
10
|
+
const OTP_VALIDATION_CONFIG: Record<Exclude<OtpValidationType, 'none'>, OTPValidationConfig> = {
|
|
11
|
+
numeric: {
|
|
12
|
+
slotPattern: '\\d{1}',
|
|
13
|
+
getRootPattern: length => `\\d{${length}}`,
|
|
14
|
+
regexp: /\D/g,
|
|
15
|
+
inputMode: 'numeric',
|
|
16
|
+
},
|
|
17
|
+
alpha: {
|
|
18
|
+
slotPattern: '[a-z]{1}',
|
|
19
|
+
getRootPattern: length => `[a-z]{${length}}`,
|
|
20
|
+
regexp: /[^a-z]/gi,
|
|
21
|
+
inputMode: 'text',
|
|
22
|
+
},
|
|
23
|
+
alphanumeric: {
|
|
24
|
+
slotPattern: '[a-z0-9]{1}',
|
|
25
|
+
getRootPattern: length => `[a-z0-9]{${length}}`,
|
|
26
|
+
regexp: /[^a-z0-9]/gi,
|
|
27
|
+
inputMode: 'text',
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getOTPValidationConfig(validationType: OtpValidationType) {
|
|
32
|
+
if (validationType === 'none') {
|
|
33
|
+
return null
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return OTP_VALIDATION_CONFIG[validationType]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function stripOTPWhitespace(value: string | null | undefined) {
|
|
40
|
+
return (value ?? '').replace(/\s/g, '')
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function applyOTPValidation(value: string, validation: OTPValidationConfig | null) {
|
|
44
|
+
return validation ? value.replace(validation.regexp, '') : value
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Normalizes user-entered OTP text by stripping whitespace, applying validation and custom
|
|
49
|
+
* normalization, and clamping the final value to the configured slot count.
|
|
50
|
+
*/
|
|
51
|
+
export function normalizeOTPValueWithDetails(
|
|
52
|
+
value: string | null | undefined,
|
|
53
|
+
length: number,
|
|
54
|
+
validationType: OtpValidationType,
|
|
55
|
+
normalizeValue?: ((value: string) => string) | undefined,
|
|
56
|
+
): readonly [value: string, didRejectCharacters: boolean] {
|
|
57
|
+
const strippedValue = stripOTPWhitespace(value)
|
|
58
|
+
const validation = getOTPValidationConfig(validationType)
|
|
59
|
+
let normalizedValue = applyOTPValidation(strippedValue, validation)
|
|
60
|
+
let didRejectCharacters = strippedValue.length > normalizedValue.length
|
|
61
|
+
|
|
62
|
+
if (normalizeValue) {
|
|
63
|
+
const customNormalizedValue = normalizeValue(normalizedValue)
|
|
64
|
+
didRejectCharacters ||= normalizedValue.length > customNormalizedValue.length
|
|
65
|
+
normalizedValue = applyOTPValidation(customNormalizedValue, validation)
|
|
66
|
+
didRejectCharacters ||= customNormalizedValue.length > normalizedValue.length
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Slice by Unicode code points so multi-byte characters do not split across OTP slots.
|
|
70
|
+
const maxLength = length < 0 ? 0 : length
|
|
71
|
+
const normalizedCharacters = Array.from(normalizedValue)
|
|
72
|
+
|
|
73
|
+
return [
|
|
74
|
+
normalizedCharacters.slice(0, maxLength).join(''),
|
|
75
|
+
didRejectCharacters || normalizedCharacters.length > maxLength,
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function normalizeOTPValue(
|
|
80
|
+
value: string | null | undefined,
|
|
81
|
+
length: number,
|
|
82
|
+
validationType: OtpValidationType,
|
|
83
|
+
normalizeValue?: ((value: string) => string) | undefined,
|
|
84
|
+
) {
|
|
85
|
+
return normalizeOTPValueWithDetails(value, length, validationType, normalizeValue)[0]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function getOTPCharacters(value: string | null | undefined) {
|
|
89
|
+
return Array.from(value ?? '')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function getOTPValueLength(value: string | null | undefined) {
|
|
93
|
+
return getOTPCharacters(value).length
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function getOTPCharacter(value: string | null | undefined, index: number) {
|
|
97
|
+
return getOTPCharacters(value)[index] ?? ''
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Replaces characters starting at the provided slot index, then re-normalizes the final OTP value
|
|
102
|
+
* so paste and multi-character edits stay contiguous and length-bounded.
|
|
103
|
+
*/
|
|
104
|
+
export function replaceOTPValue(
|
|
105
|
+
currentValue: string,
|
|
106
|
+
index: number,
|
|
107
|
+
nextValue: string,
|
|
108
|
+
length: number,
|
|
109
|
+
validationType: OtpValidationType,
|
|
110
|
+
normalizeValue?: ((value: string) => string) | undefined,
|
|
111
|
+
) {
|
|
112
|
+
const normalizedValue = normalizeOTPValue(nextValue, length, validationType, normalizeValue)
|
|
113
|
+
const characters = getOTPCharacters(currentValue)
|
|
114
|
+
const replacementLength = getOTPValueLength(normalizedValue)
|
|
115
|
+
const prefix = characters.slice(0, index).join('')
|
|
116
|
+
const suffix = characters.slice(index + replacementLength).join('')
|
|
117
|
+
|
|
118
|
+
return normalizeOTPValue(
|
|
119
|
+
`${prefix}${normalizedValue}${suffix}`,
|
|
120
|
+
length,
|
|
121
|
+
validationType,
|
|
122
|
+
normalizeValue,
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function removeOTPCharacter(currentValue: string, index: number) {
|
|
127
|
+
const characters = getOTPCharacters(currentValue)
|
|
128
|
+
|
|
129
|
+
if (index < 0 || index >= characters.length) {
|
|
130
|
+
return currentValue
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
characters.splice(index, 1)
|
|
134
|
+
return characters.join('')
|
|
135
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StateAttributesMapping } from '../../utils/getStateAttributesProps'
|
|
2
|
+
import type { OtpFieldInputState } from '../input/OtpFieldInput.vue'
|
|
3
|
+
import type { OtpFieldRootState } from '../root/OtpFieldRoot.vue'
|
|
4
|
+
import { fieldValidityMapping } from '../../field/utils/constants'
|
|
5
|
+
|
|
6
|
+
export const rootStateAttributesMapping: StateAttributesMapping<OtpFieldRootState> = {
|
|
7
|
+
value: () => null,
|
|
8
|
+
length: () => null,
|
|
9
|
+
...fieldValidityMapping,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const inputStateAttributesMapping: StateAttributesMapping<OtpFieldInputState> = {
|
|
13
|
+
value: () => null,
|
|
14
|
+
index: () => null,
|
|
15
|
+
...fieldValidityMapping,
|
|
16
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import RadioIndicator from './indicator/RadioIndicator.vue'
|
|
2
|
+
import RadioRoot from './root/RadioRoot.vue'
|
|
3
|
+
|
|
4
|
+
export { radioGroupContextKey, useRadioGroupContext } from '../radio-group/RadioGroupContext'
|
|
5
|
+
export type { RadioGroupContext } from '../radio-group/RadioGroupContext'
|
|
6
|
+
export { default as RadioIndicator } from './indicator/RadioIndicator.vue'
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
RadioIndicatorProps,
|
|
10
|
+
RadioIndicatorState,
|
|
11
|
+
} from './indicator/RadioIndicator.vue'
|
|
12
|
+
export { RadioIndicatorDataAttributes } from './indicator/RadioIndicatorDataAttributes'
|
|
13
|
+
export { default as RadioRoot } from './root/RadioRoot.vue'
|
|
14
|
+
export type {
|
|
15
|
+
RadioRootChangeEventDetails,
|
|
16
|
+
RadioRootChangeEventReason,
|
|
17
|
+
RadioRootProps,
|
|
18
|
+
RadioRootState,
|
|
19
|
+
} from './root/RadioRoot.vue'
|
|
20
|
+
export { radioRootContextKey, useRadioRootContext } from './root/RadioRootContext'
|
|
21
|
+
|
|
22
|
+
export type { RadioRootContext } from './root/RadioRootContext'
|
|
23
|
+
export { RadioRootDataAttributes } from './root/RadioRootDataAttributes'
|
|
24
|
+
|
|
25
|
+
export const Radio = {
|
|
26
|
+
Root: RadioRoot,
|
|
27
|
+
Indicator: RadioIndicator,
|
|
28
|
+
} as const
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BaseUIComponentProps } from '../../utils/types'
|
|
3
|
+
import type { TransitionStatus } from '../../utils/useTransitionStatus'
|
|
4
|
+
import type { RadioRootState } from '../root/RadioRoot.vue'
|
|
5
|
+
import { computed, ref, useAttrs } from 'vue'
|
|
6
|
+
import { useOpenChangeComplete } from '../../utils/useOpenChangeComplete'
|
|
7
|
+
import { useRenderElement } from '../../utils/useRenderElement'
|
|
8
|
+
import { useTransitionStatus } from '../../utils/useTransitionStatus'
|
|
9
|
+
import { useRadioRootContext } from '../root/RadioRootContext'
|
|
10
|
+
import { stateAttributesMapping } from '../utils/stateAttributesMapping'
|
|
11
|
+
|
|
12
|
+
export interface RadioIndicatorState extends RadioRootState {
|
|
13
|
+
/**
|
|
14
|
+
* The transition status of the component.
|
|
15
|
+
*/
|
|
16
|
+
transitionStatus: TransitionStatus
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface RadioIndicatorProps extends BaseUIComponentProps<RadioIndicatorState> {
|
|
20
|
+
/**
|
|
21
|
+
* Whether to keep the HTML element in the DOM when the radio button is inactive.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
keepMounted?: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Indicates whether the radio button is selected.
|
|
29
|
+
* Renders a `<span>` element.
|
|
30
|
+
*
|
|
31
|
+
* Documentation: [Base UI Vue Radio](https://baseui-vue.com/docs/components/radio)
|
|
32
|
+
*/
|
|
33
|
+
defineOptions({
|
|
34
|
+
name: 'RadioIndicator',
|
|
35
|
+
inheritAttrs: false,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const props = withDefaults(defineProps<RadioIndicatorProps>(), {
|
|
39
|
+
as: 'span',
|
|
40
|
+
keepMounted: false,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const attrs = useAttrs()
|
|
44
|
+
const attrsObject = attrs as Record<string, any>
|
|
45
|
+
|
|
46
|
+
const rootState = useRadioRootContext()
|
|
47
|
+
const rendered = computed(() => rootState.value.checked)
|
|
48
|
+
const { mounted, transitionStatus, setMounted } = useTransitionStatus(rendered)
|
|
49
|
+
const localIndicatorRef = ref<HTMLElement | null>(null)
|
|
50
|
+
|
|
51
|
+
const state = computed<RadioIndicatorState>(() => ({
|
|
52
|
+
...rootState.value,
|
|
53
|
+
transitionStatus: transitionStatus.value,
|
|
54
|
+
}))
|
|
55
|
+
|
|
56
|
+
useOpenChangeComplete({
|
|
57
|
+
open: rendered,
|
|
58
|
+
ref: localIndicatorRef,
|
|
59
|
+
onComplete() {
|
|
60
|
+
if (!rendered.value) {
|
|
61
|
+
setMounted(false)
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const shouldRender = computed(() => props.keepMounted || mounted.value)
|
|
67
|
+
|
|
68
|
+
const {
|
|
69
|
+
tag,
|
|
70
|
+
mergedProps,
|
|
71
|
+
renderless,
|
|
72
|
+
ref: renderRef,
|
|
73
|
+
} = useRenderElement({
|
|
74
|
+
componentProps: props,
|
|
75
|
+
state,
|
|
76
|
+
props: computed(() => attrsObject),
|
|
77
|
+
stateAttributesMapping,
|
|
78
|
+
defaultTagName: 'span',
|
|
79
|
+
ref: localIndicatorRef,
|
|
80
|
+
})
|
|
81
|
+
</script>
|
|
82
|
+
|
|
83
|
+
<template>
|
|
84
|
+
<template v-if="shouldRender">
|
|
85
|
+
<slot v-if="renderless" :ref="renderRef" :props="mergedProps" :state="state" />
|
|
86
|
+
<component :is="tag" v-else :ref="renderRef" v-bind="mergedProps">
|
|
87
|
+
<slot :state="state" />
|
|
88
|
+
</component>
|
|
89
|
+
</template>
|
|
90
|
+
</template>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export enum RadioIndicatorDataAttributes {
|
|
2
|
+
/**
|
|
3
|
+
* Present when the radio is checked.
|
|
4
|
+
*/
|
|
5
|
+
checked = 'data-checked',
|
|
6
|
+
/**
|
|
7
|
+
* Present when the radio is not checked.
|
|
8
|
+
*/
|
|
9
|
+
unchecked = 'data-unchecked',
|
|
10
|
+
/**
|
|
11
|
+
* Present when the radio is disabled.
|
|
12
|
+
*/
|
|
13
|
+
disabled = 'data-disabled',
|
|
14
|
+
/**
|
|
15
|
+
* Present when the radio is readonly.
|
|
16
|
+
*/
|
|
17
|
+
readonly = 'data-readonly',
|
|
18
|
+
/**
|
|
19
|
+
* Present when the radio is required.
|
|
20
|
+
*/
|
|
21
|
+
required = 'data-required',
|
|
22
|
+
/**
|
|
23
|
+
* Present when the radio indicator is animating in.
|
|
24
|
+
*/
|
|
25
|
+
startingStyle = 'data-starting-style',
|
|
26
|
+
/**
|
|
27
|
+
* Present when the radio indicator is animating out.
|
|
28
|
+
*/
|
|
29
|
+
endingStyle = 'data-ending-style',
|
|
30
|
+
/**
|
|
31
|
+
* Present when the radio is in a valid state.
|
|
32
|
+
*/
|
|
33
|
+
valid = 'data-valid',
|
|
34
|
+
/**
|
|
35
|
+
* Present when the radio is in an invalid state.
|
|
36
|
+
*/
|
|
37
|
+
invalid = 'data-invalid',
|
|
38
|
+
/**
|
|
39
|
+
* Present when the radio has been touched.
|
|
40
|
+
*/
|
|
41
|
+
touched = 'data-touched',
|
|
42
|
+
/**
|
|
43
|
+
* Present when the radio's value has changed.
|
|
44
|
+
*/
|
|
45
|
+
dirty = 'data-dirty',
|
|
46
|
+
/**
|
|
47
|
+
* Present when the radio is checked.
|
|
48
|
+
*/
|
|
49
|
+
filled = 'data-filled',
|
|
50
|
+
/**
|
|
51
|
+
* Present when the radio is focused.
|
|
52
|
+
*/
|
|
53
|
+
focused = 'data-focused',
|
|
54
|
+
}
|