base-ui-vue 0.2.0 → 0.3.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/content/ScrollAreaContent.cjs +168 -0
- package/dist/content/ScrollAreaContent.cjs.map +1 -0
- package/dist/content/ScrollAreaContent.js +133 -0
- package/dist/content/ScrollAreaContent.js.map +1 -0
- package/dist/corner/ScrollAreaCorner.cjs +77 -0
- package/dist/corner/ScrollAreaCorner.cjs.map +1 -0
- package/dist/corner/ScrollAreaCorner.js +72 -0
- package/dist/corner/ScrollAreaCorner.js.map +1 -0
- package/dist/index.cjs +33 -0
- package/dist/index.d.cts +1067 -352
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1067 -352
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index2.cjs +3565 -1373
- package/dist/index2.cjs.map +1 -1
- package/dist/index2.js +3228 -1204
- package/dist/index2.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/input/Input.vue +37 -0
- package/src/input/InputDataAttributes.ts +30 -0
- package/src/input/index.ts +4 -0
- package/src/meter/index.ts +16 -0
- package/src/meter/indicator/MeterIndicator.vue +65 -0
- package/src/meter/label/MeterLabel.vue +63 -0
- package/src/meter/root/MeterRoot.vue +131 -0
- package/src/meter/root/MeterRootContext.ts +41 -0
- package/src/meter/track/MeterTrack.vue +46 -0
- package/src/meter/value/MeterValue.vue +85 -0
- package/src/progress/index.ts +23 -0
- package/src/progress/indicator/ProgressIndicator.vue +74 -0
- package/src/progress/label/ProgressLabel.vue +63 -0
- package/src/progress/root/ProgressRoot.vue +160 -0
- package/src/progress/root/ProgressRootContext.ts +51 -0
- package/src/progress/root/ProgressRootDataAttributes.ts +14 -0
- package/src/progress/root/stateAttributesMapping.ts +18 -0
- package/src/progress/track/ProgressTrack.vue +48 -0
- package/src/progress/value/ProgressValue.vue +92 -0
- package/src/scroll-area/constants.ts +2 -0
- package/src/scroll-area/content/ScrollAreaContent.vue +87 -0
- package/src/scroll-area/corner/ScrollAreaCorner.vue +64 -0
- package/src/scroll-area/index.ts +25 -0
- package/src/scroll-area/root/ScrollAreaRoot.vue +297 -0
- package/src/scroll-area/root/ScrollAreaRootContext.ts +89 -0
- package/src/scroll-area/root/ScrollAreaRootCssVars.ts +4 -0
- package/src/scroll-area/root/ScrollAreaRootDataAttributes.ts +9 -0
- package/src/scroll-area/root/stateAttributes.ts +14 -0
- package/src/scroll-area/scrollbar/ScrollAreaScrollbar.vue +263 -0
- package/src/scroll-area/scrollbar/ScrollAreaScrollbarContext.ts +20 -0
- package/src/scroll-area/scrollbar/ScrollAreaScrollbarCssVars.ts +4 -0
- package/src/scroll-area/scrollbar/ScrollAreaScrollbarDataAttributes.ts +11 -0
- package/src/scroll-area/thumb/ScrollAreaThumb.vue +120 -0
- package/src/scroll-area/thumb/ScrollAreaThumbDataAttributes.ts +3 -0
- package/src/scroll-area/utils/getOffset.ts +34 -0
- package/src/scroll-area/viewport/ScrollAreaViewport.vue +379 -0
- package/src/scroll-area/viewport/ScrollAreaViewportContext.ts +20 -0
- package/src/scroll-area/viewport/ScrollAreaViewportCssVars.ts +6 -0
- package/src/scroll-area/viewport/ScrollAreaViewportDataAttributes.ts +9 -0
- package/src/utils/formatNumber.ts +25 -0
- package/src/utils/scrollEdges.ts +33 -0
- package/src/utils/styles.ts +28 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BaseUIComponentProps } from '../../utils/types'
|
|
3
|
+
import { computed, provide, ref, useAttrs } from 'vue'
|
|
4
|
+
import { formatNumberValue } from '../../utils/formatNumber'
|
|
5
|
+
import { useRenderElement } from '../../utils/useRenderElement'
|
|
6
|
+
import { visuallyHidden } from '../../utils/visuallyHidden'
|
|
7
|
+
import { progressRootContextKey } from './ProgressRootContext'
|
|
8
|
+
import { progressStateAttributesMapping } from './stateAttributesMapping'
|
|
9
|
+
|
|
10
|
+
export type ProgressStatus = 'indeterminate' | 'progressing' | 'complete'
|
|
11
|
+
|
|
12
|
+
export interface ProgressRootState {
|
|
13
|
+
/**
|
|
14
|
+
* The current status.
|
|
15
|
+
*/
|
|
16
|
+
status: ProgressStatus
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ProgressRootProps extends BaseUIComponentProps<ProgressRootState> {
|
|
20
|
+
/**
|
|
21
|
+
* A string value that provides a user-friendly name for `aria-valuenow`.
|
|
22
|
+
* Takes precedence over `getAriaValueText`.
|
|
23
|
+
*/
|
|
24
|
+
ariaValuetext?: string
|
|
25
|
+
/**
|
|
26
|
+
* Options to format the value.
|
|
27
|
+
*/
|
|
28
|
+
format?: Intl.NumberFormatOptions
|
|
29
|
+
/**
|
|
30
|
+
* A function that returns a string value for `aria-valuetext`.
|
|
31
|
+
* Receives the formatted value (or `null` when indeterminate) and the raw
|
|
32
|
+
* value.
|
|
33
|
+
*/
|
|
34
|
+
getAriaValueText?: (formattedValue: string | null, value: number | null) => string
|
|
35
|
+
/**
|
|
36
|
+
* The locale used by `Intl.NumberFormat` when formatting the value.
|
|
37
|
+
* Defaults to the user's runtime locale.
|
|
38
|
+
*/
|
|
39
|
+
locale?: Intl.LocalesArgument
|
|
40
|
+
/**
|
|
41
|
+
* The maximum value.
|
|
42
|
+
* @default 100
|
|
43
|
+
*/
|
|
44
|
+
max?: number
|
|
45
|
+
/**
|
|
46
|
+
* The minimum value.
|
|
47
|
+
* @default 0
|
|
48
|
+
*/
|
|
49
|
+
min?: number
|
|
50
|
+
/**
|
|
51
|
+
* The current value. The component is indeterminate when value is `null`.
|
|
52
|
+
* @default null
|
|
53
|
+
*/
|
|
54
|
+
value: number | null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Groups all parts of the progress bar and provides the task completion
|
|
59
|
+
* status to screen readers.
|
|
60
|
+
* Renders a `<div>` element.
|
|
61
|
+
*
|
|
62
|
+
* Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
|
|
63
|
+
*/
|
|
64
|
+
defineOptions({
|
|
65
|
+
name: 'ProgressRoot',
|
|
66
|
+
inheritAttrs: false,
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
const props = withDefaults(defineProps<ProgressRootProps>(), {
|
|
70
|
+
as: 'div',
|
|
71
|
+
max: 100,
|
|
72
|
+
min: 0,
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
function getDefaultAriaValueText(formattedValue: string | null, value: number | null) {
|
|
76
|
+
if (value == null) {
|
|
77
|
+
return 'indeterminate progress'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return formattedValue || `${value}%`
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const attrs = useAttrs()
|
|
84
|
+
|
|
85
|
+
const labelId = ref<string | undefined>(undefined)
|
|
86
|
+
|
|
87
|
+
const status = computed<ProgressStatus>(() => {
|
|
88
|
+
if (props.value == null || !Number.isFinite(props.value)) {
|
|
89
|
+
return 'indeterminate'
|
|
90
|
+
}
|
|
91
|
+
return props.value === props.max ? 'complete' : 'progressing'
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const formattedValue = computed(() =>
|
|
95
|
+
formatNumberValue(props.value, props.locale, props.format),
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
const ariaValueText = computed(() => {
|
|
99
|
+
if (props.ariaValuetext !== undefined) {
|
|
100
|
+
return props.ariaValuetext
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const formatted = props.value == null ? null : formattedValue.value
|
|
104
|
+
|
|
105
|
+
if (props.getAriaValueText) {
|
|
106
|
+
return props.getAriaValueText(formatted, props.value)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return getDefaultAriaValueText(formatted, props.value)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
const state = computed<ProgressRootState>(() => ({
|
|
113
|
+
status: status.value,
|
|
114
|
+
}))
|
|
115
|
+
|
|
116
|
+
provide(progressRootContextKey, {
|
|
117
|
+
formattedValue,
|
|
118
|
+
max: computed(() => props.max),
|
|
119
|
+
min: computed(() => props.min),
|
|
120
|
+
value: computed(() => props.value),
|
|
121
|
+
status,
|
|
122
|
+
state,
|
|
123
|
+
setLabelId(id) {
|
|
124
|
+
labelId.value = id
|
|
125
|
+
},
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
const rootProps = computed(() => ({
|
|
129
|
+
'role': 'progressbar',
|
|
130
|
+
'aria-labelledby': labelId.value,
|
|
131
|
+
'aria-valuemax': props.max,
|
|
132
|
+
'aria-valuemin': props.min,
|
|
133
|
+
'aria-valuenow': props.value ?? undefined,
|
|
134
|
+
'aria-valuetext': ariaValueText.value,
|
|
135
|
+
...attrs,
|
|
136
|
+
}))
|
|
137
|
+
|
|
138
|
+
const {
|
|
139
|
+
tag,
|
|
140
|
+
mergedProps,
|
|
141
|
+
renderless,
|
|
142
|
+
} = useRenderElement({
|
|
143
|
+
componentProps: props,
|
|
144
|
+
state,
|
|
145
|
+
props: rootProps,
|
|
146
|
+
defaultTagName: 'div',
|
|
147
|
+
stateAttributesMapping: progressStateAttributesMapping,
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
const visuallyHiddenStyle = visuallyHidden
|
|
151
|
+
</script>
|
|
152
|
+
|
|
153
|
+
<template>
|
|
154
|
+
<slot v-if="renderless" :props="mergedProps" :state="state" />
|
|
155
|
+
<component :is="tag" v-else v-bind="mergedProps">
|
|
156
|
+
<slot :state="state" />
|
|
157
|
+
<!-- Force NVDA to read the label https://github.com/mui/base-ui/issues/4184 -->
|
|
158
|
+
<span role="presentation" :style="visuallyHiddenStyle">x</span>
|
|
159
|
+
</component>
|
|
160
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ComputedRef, InjectionKey, Ref } from 'vue'
|
|
2
|
+
import type { ProgressRootState, ProgressStatus } from './ProgressRoot.vue'
|
|
3
|
+
import { inject } from 'vue'
|
|
4
|
+
|
|
5
|
+
export interface ProgressRootContext {
|
|
6
|
+
/**
|
|
7
|
+
* The formatted current value of the progress bar.
|
|
8
|
+
* Empty string when the component is indeterminate.
|
|
9
|
+
*/
|
|
10
|
+
formattedValue: Ref<string>
|
|
11
|
+
/**
|
|
12
|
+
* The maximum allowed value of the progress bar.
|
|
13
|
+
*/
|
|
14
|
+
max: Ref<number>
|
|
15
|
+
/**
|
|
16
|
+
* The minimum allowed value of the progress bar.
|
|
17
|
+
*/
|
|
18
|
+
min: Ref<number>
|
|
19
|
+
/**
|
|
20
|
+
* The raw current value, or `null` when indeterminate.
|
|
21
|
+
*/
|
|
22
|
+
value: Ref<number | null>
|
|
23
|
+
/**
|
|
24
|
+
* Derived completion status. Used to produce `data-*` state attributes.
|
|
25
|
+
*/
|
|
26
|
+
status: ComputedRef<ProgressStatus>
|
|
27
|
+
/**
|
|
28
|
+
* The state of the root component.
|
|
29
|
+
*/
|
|
30
|
+
state: ComputedRef<ProgressRootState>
|
|
31
|
+
/**
|
|
32
|
+
* Registers the DOM id of the `<ProgressLabel>` for `aria-labelledby`.
|
|
33
|
+
*/
|
|
34
|
+
setLabelId: (id: string | undefined) => void
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const progressRootContextKey: InjectionKey<ProgressRootContext>
|
|
38
|
+
= Symbol('ProgressRootContext')
|
|
39
|
+
|
|
40
|
+
export function useProgressRootContext(optional: true): ProgressRootContext | undefined
|
|
41
|
+
export function useProgressRootContext(optional?: false): ProgressRootContext
|
|
42
|
+
export function useProgressRootContext(optional = false) {
|
|
43
|
+
const context = inject(progressRootContextKey, undefined)
|
|
44
|
+
if (!context && !optional) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
'Base UI Vue: ProgressRootContext is missing. Progress parts must be placed within <ProgressRoot>.',
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return context
|
|
51
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export enum ProgressRootDataAttributes {
|
|
2
|
+
/**
|
|
3
|
+
* Present when the progress has completed.
|
|
4
|
+
*/
|
|
5
|
+
complete = 'data-complete',
|
|
6
|
+
/**
|
|
7
|
+
* Present when the progress is in indeterminate state.
|
|
8
|
+
*/
|
|
9
|
+
indeterminate = 'data-indeterminate',
|
|
10
|
+
/**
|
|
11
|
+
* Present while the progress is progressing.
|
|
12
|
+
*/
|
|
13
|
+
progressing = 'data-progressing',
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { StateAttributesMapping } from '../../utils/getStateAttributesProps'
|
|
2
|
+
import type { ProgressRootState } from './ProgressRoot.vue'
|
|
3
|
+
import { ProgressRootDataAttributes } from './ProgressRootDataAttributes'
|
|
4
|
+
|
|
5
|
+
export const progressStateAttributesMapping: StateAttributesMapping<ProgressRootState> = {
|
|
6
|
+
status(value): Record<string, string> | null {
|
|
7
|
+
if (value === 'progressing') {
|
|
8
|
+
return { [ProgressRootDataAttributes.progressing]: '' }
|
|
9
|
+
}
|
|
10
|
+
if (value === 'complete') {
|
|
11
|
+
return { [ProgressRootDataAttributes.complete]: '' }
|
|
12
|
+
}
|
|
13
|
+
if (value === 'indeterminate') {
|
|
14
|
+
return { [ProgressRootDataAttributes.indeterminate]: '' }
|
|
15
|
+
}
|
|
16
|
+
return null
|
|
17
|
+
},
|
|
18
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BaseUIComponentProps } from '../../utils/types'
|
|
3
|
+
import type { ProgressRootState } from '../root/ProgressRoot.vue'
|
|
4
|
+
import { useAttrs } from 'vue'
|
|
5
|
+
import { useRenderElement } from '../../utils/useRenderElement'
|
|
6
|
+
import { useProgressRootContext } from '../root/ProgressRootContext'
|
|
7
|
+
import { progressStateAttributesMapping } from '../root/stateAttributesMapping'
|
|
8
|
+
|
|
9
|
+
export interface ProgressTrackState extends ProgressRootState {}
|
|
10
|
+
export interface ProgressTrackProps extends BaseUIComponentProps<ProgressTrackState> {}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Contains the progress bar indicator.
|
|
14
|
+
* Renders a `<div>` element.
|
|
15
|
+
*
|
|
16
|
+
* Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
|
|
17
|
+
*/
|
|
18
|
+
defineOptions({
|
|
19
|
+
name: 'ProgressTrack',
|
|
20
|
+
inheritAttrs: false,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const props = withDefaults(defineProps<ProgressTrackProps>(), {
|
|
24
|
+
as: 'div',
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const attrs = useAttrs()
|
|
28
|
+
const { state } = useProgressRootContext()
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
tag,
|
|
32
|
+
mergedProps,
|
|
33
|
+
renderless,
|
|
34
|
+
} = useRenderElement({
|
|
35
|
+
componentProps: props,
|
|
36
|
+
state,
|
|
37
|
+
props: attrs,
|
|
38
|
+
defaultTagName: 'div',
|
|
39
|
+
stateAttributesMapping: progressStateAttributesMapping,
|
|
40
|
+
})
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template>
|
|
44
|
+
<slot v-if="renderless" :props="mergedProps" :state="state" />
|
|
45
|
+
<component :is="tag" v-else v-bind="mergedProps">
|
|
46
|
+
<slot :state="state" />
|
|
47
|
+
</component>
|
|
48
|
+
</template>
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BaseUIComponentProps } from '../../utils/types'
|
|
3
|
+
import type { ProgressRootState } from '../root/ProgressRoot.vue'
|
|
4
|
+
import { computed, useAttrs } from 'vue'
|
|
5
|
+
import { useRenderElement } from '../../utils/useRenderElement'
|
|
6
|
+
import { useProgressRootContext } from '../root/ProgressRootContext'
|
|
7
|
+
import { progressStateAttributesMapping } from '../root/stateAttributesMapping'
|
|
8
|
+
|
|
9
|
+
export interface ProgressValueState extends ProgressRootState {}
|
|
10
|
+
export interface ProgressValueProps extends BaseUIComponentProps<ProgressValueState> {}
|
|
11
|
+
|
|
12
|
+
export interface ProgressValueSlotProps {
|
|
13
|
+
/**
|
|
14
|
+
* Formatted value. `"indeterminate"` when the root value is `null`.
|
|
15
|
+
*/
|
|
16
|
+
formattedValue: string | 'indeterminate'
|
|
17
|
+
/**
|
|
18
|
+
* Raw numeric value, or `null` when indeterminate.
|
|
19
|
+
*/
|
|
20
|
+
value: number | null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ProgressValueRenderlessSlotProps extends ProgressValueSlotProps {
|
|
24
|
+
props: Record<string, unknown>
|
|
25
|
+
state: ProgressValueState
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A text label displaying the current value.
|
|
30
|
+
* Renders a `<span>` element.
|
|
31
|
+
*
|
|
32
|
+
* Documentation: [Base UI Vue Progress](https://baseui-vue.com/docs/components/progress)
|
|
33
|
+
*/
|
|
34
|
+
defineOptions({
|
|
35
|
+
name: 'ProgressValue',
|
|
36
|
+
inheritAttrs: false,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const props = withDefaults(defineProps<ProgressValueProps>(), {
|
|
40
|
+
as: 'span',
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
defineSlots<{
|
|
44
|
+
default?: (props: ProgressValueSlotProps | ProgressValueRenderlessSlotProps) => unknown
|
|
45
|
+
}>()
|
|
46
|
+
|
|
47
|
+
const attrs = useAttrs()
|
|
48
|
+
const { value, formattedValue, state } = useProgressRootContext()
|
|
49
|
+
|
|
50
|
+
const slotFormattedValue = computed<string | 'indeterminate'>(() =>
|
|
51
|
+
value.value == null ? 'indeterminate' : formattedValue.value,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
const defaultDisplay = computed(() =>
|
|
55
|
+
value.value == null ? '' : formattedValue.value,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
const valueProps = computed(() => ({
|
|
59
|
+
'aria-hidden': true,
|
|
60
|
+
...attrs,
|
|
61
|
+
}))
|
|
62
|
+
|
|
63
|
+
const {
|
|
64
|
+
tag,
|
|
65
|
+
mergedProps,
|
|
66
|
+
renderless,
|
|
67
|
+
} = useRenderElement({
|
|
68
|
+
componentProps: props,
|
|
69
|
+
state,
|
|
70
|
+
props: valueProps,
|
|
71
|
+
defaultTagName: 'span',
|
|
72
|
+
stateAttributesMapping: progressStateAttributesMapping,
|
|
73
|
+
})
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<template>
|
|
77
|
+
<slot
|
|
78
|
+
v-if="renderless"
|
|
79
|
+
:props="mergedProps"
|
|
80
|
+
:state="state"
|
|
81
|
+
:formatted-value="slotFormattedValue"
|
|
82
|
+
:value="value"
|
|
83
|
+
/>
|
|
84
|
+
<component :is="tag" v-else v-bind="mergedProps">
|
|
85
|
+
<slot
|
|
86
|
+
:formatted-value="slotFormattedValue"
|
|
87
|
+
:value="value"
|
|
88
|
+
>
|
|
89
|
+
{{ defaultDisplay }}
|
|
90
|
+
</slot>
|
|
91
|
+
</component>
|
|
92
|
+
</template>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BaseUIComponentProps } from '../../utils/types'
|
|
3
|
+
import type { ScrollAreaRootState } from '../root/ScrollAreaRootContext'
|
|
4
|
+
import { computed, onBeforeUnmount, onMounted, shallowRef, useAttrs } from 'vue'
|
|
5
|
+
import { mergeProps } from '../../merge-props/mergeProps'
|
|
6
|
+
import { useRenderElement } from '../../utils/useRenderElement'
|
|
7
|
+
import { useScrollAreaRootContext } from '../root/ScrollAreaRootContext'
|
|
8
|
+
import { scrollAreaStateAttributesMapping } from '../root/stateAttributes'
|
|
9
|
+
import { useScrollAreaViewportContext } from '../viewport/ScrollAreaViewportContext'
|
|
10
|
+
|
|
11
|
+
export type ScrollAreaContentState = ScrollAreaRootState
|
|
12
|
+
|
|
13
|
+
export interface ScrollAreaContentProps extends BaseUIComponentProps<ScrollAreaContentState> {}
|
|
14
|
+
|
|
15
|
+
defineOptions({
|
|
16
|
+
name: 'ScrollAreaContent',
|
|
17
|
+
inheritAttrs: false,
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const props = withDefaults(defineProps<ScrollAreaContentProps>(), {
|
|
21
|
+
as: 'div',
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const attrs = useAttrs()
|
|
25
|
+
|
|
26
|
+
const contentWrapperRef = shallowRef<HTMLDivElement | null>(null)
|
|
27
|
+
const { computeThumbPosition } = useScrollAreaViewportContext()
|
|
28
|
+
const { viewportState } = useScrollAreaRootContext()
|
|
29
|
+
|
|
30
|
+
let resizeObserver: ResizeObserver | undefined
|
|
31
|
+
|
|
32
|
+
onMounted(() => {
|
|
33
|
+
if (typeof ResizeObserver === 'undefined')
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
let hasInitialized = false
|
|
37
|
+
resizeObserver = new ResizeObserver(() => {
|
|
38
|
+
if (!hasInitialized) {
|
|
39
|
+
hasInitialized = true
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
computeThumbPosition()
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
if (contentWrapperRef.value) {
|
|
46
|
+
resizeObserver.observe(contentWrapperRef.value)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
onBeforeUnmount(() => {
|
|
51
|
+
resizeObserver?.disconnect()
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const elementProps = computed(() => mergeProps(
|
|
55
|
+
attrs as Record<string, any>,
|
|
56
|
+
{
|
|
57
|
+
role: 'presentation',
|
|
58
|
+
style: { minWidth: 'fit-content' },
|
|
59
|
+
},
|
|
60
|
+
))
|
|
61
|
+
|
|
62
|
+
const {
|
|
63
|
+
tag,
|
|
64
|
+
mergedProps,
|
|
65
|
+
renderless,
|
|
66
|
+
ref: renderRef,
|
|
67
|
+
} = useRenderElement({
|
|
68
|
+
componentProps: props,
|
|
69
|
+
state: viewportState,
|
|
70
|
+
props: elementProps,
|
|
71
|
+
stateAttributesMapping: scrollAreaStateAttributesMapping,
|
|
72
|
+
defaultTagName: 'div',
|
|
73
|
+
ref: contentWrapperRef,
|
|
74
|
+
})
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<template>
|
|
78
|
+
<slot v-if="renderless" :ref="renderRef" :props="mergedProps" :state="viewportState" />
|
|
79
|
+
<component
|
|
80
|
+
:is="tag"
|
|
81
|
+
v-else
|
|
82
|
+
:ref="renderRef"
|
|
83
|
+
v-bind="mergedProps"
|
|
84
|
+
>
|
|
85
|
+
<slot />
|
|
86
|
+
</component>
|
|
87
|
+
</template>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BaseUIComponentProps } from '../../utils/types'
|
|
3
|
+
import { computed, useAttrs } from 'vue'
|
|
4
|
+
import { mergeProps } from '../../merge-props/mergeProps'
|
|
5
|
+
import { useRenderElement } from '../../utils/useRenderElement'
|
|
6
|
+
import { useScrollAreaRootContext } from '../root/ScrollAreaRootContext'
|
|
7
|
+
|
|
8
|
+
export interface ScrollAreaCornerState {}
|
|
9
|
+
|
|
10
|
+
export interface ScrollAreaCornerProps extends BaseUIComponentProps<ScrollAreaCornerState> {}
|
|
11
|
+
|
|
12
|
+
defineOptions({
|
|
13
|
+
name: 'ScrollAreaCorner',
|
|
14
|
+
inheritAttrs: false,
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const props = withDefaults(defineProps<ScrollAreaCornerProps>(), {
|
|
18
|
+
as: 'div',
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const attrs = useAttrs()
|
|
22
|
+
|
|
23
|
+
const { cornerRef, cornerSize, hiddenState } = useScrollAreaRootContext()
|
|
24
|
+
|
|
25
|
+
const state = computed<ScrollAreaCornerState>(() => ({}))
|
|
26
|
+
|
|
27
|
+
const elementProps = computed(() => mergeProps(
|
|
28
|
+
attrs as Record<string, any>,
|
|
29
|
+
{
|
|
30
|
+
style: {
|
|
31
|
+
position: 'absolute',
|
|
32
|
+
bottom: 0,
|
|
33
|
+
insetInlineEnd: 0,
|
|
34
|
+
width: cornerSize.value.width,
|
|
35
|
+
height: cornerSize.value.height,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
))
|
|
39
|
+
|
|
40
|
+
const {
|
|
41
|
+
tag,
|
|
42
|
+
mergedProps,
|
|
43
|
+
renderless,
|
|
44
|
+
ref: renderRef,
|
|
45
|
+
} = useRenderElement({
|
|
46
|
+
componentProps: props,
|
|
47
|
+
state,
|
|
48
|
+
props: elementProps,
|
|
49
|
+
defaultTagName: 'div',
|
|
50
|
+
ref: cornerRef,
|
|
51
|
+
})
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<template v-if="!hiddenState.corner">
|
|
56
|
+
<slot v-if="renderless" :ref="renderRef" :props="mergedProps" :state="state" />
|
|
57
|
+
<component
|
|
58
|
+
:is="tag"
|
|
59
|
+
v-else
|
|
60
|
+
:ref="renderRef"
|
|
61
|
+
v-bind="mergedProps"
|
|
62
|
+
/>
|
|
63
|
+
</template>
|
|
64
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export { default as ScrollAreaContent } from './content/ScrollAreaContent.vue'
|
|
2
|
+
export type { ScrollAreaContentProps, ScrollAreaContentState } from './content/ScrollAreaContent.vue'
|
|
3
|
+
export { default as ScrollAreaCorner } from './corner/ScrollAreaCorner.vue'
|
|
4
|
+
export type { ScrollAreaCornerProps, ScrollAreaCornerState } from './corner/ScrollAreaCorner.vue'
|
|
5
|
+
export { default as ScrollAreaRoot } from './root/ScrollAreaRoot.vue'
|
|
6
|
+
|
|
7
|
+
export type { ScrollAreaRootProps } from './root/ScrollAreaRoot.vue'
|
|
8
|
+
export type { ScrollAreaRootState } from './root/ScrollAreaRootContext'
|
|
9
|
+
export { ScrollAreaRootCssVars } from './root/ScrollAreaRootCssVars'
|
|
10
|
+
export { ScrollAreaRootDataAttributes } from './root/ScrollAreaRootDataAttributes'
|
|
11
|
+
|
|
12
|
+
export { default as ScrollAreaScrollbar } from './scrollbar/ScrollAreaScrollbar.vue'
|
|
13
|
+
export type { ScrollAreaScrollbarProps, ScrollAreaScrollbarState } from './scrollbar/ScrollAreaScrollbar.vue'
|
|
14
|
+
|
|
15
|
+
export { ScrollAreaScrollbarCssVars } from './scrollbar/ScrollAreaScrollbarCssVars'
|
|
16
|
+
export { ScrollAreaScrollbarDataAttributes } from './scrollbar/ScrollAreaScrollbarDataAttributes'
|
|
17
|
+
export { default as ScrollAreaThumb } from './thumb/ScrollAreaThumb.vue'
|
|
18
|
+
export type { ScrollAreaThumbProps, ScrollAreaThumbState } from './thumb/ScrollAreaThumb.vue'
|
|
19
|
+
|
|
20
|
+
export { ScrollAreaThumbDataAttributes } from './thumb/ScrollAreaThumbDataAttributes'
|
|
21
|
+
export { default as ScrollAreaViewport } from './viewport/ScrollAreaViewport.vue'
|
|
22
|
+
export type { ScrollAreaViewportProps, ScrollAreaViewportState } from './viewport/ScrollAreaViewport.vue'
|
|
23
|
+
|
|
24
|
+
export { ScrollAreaViewportCssVars } from './viewport/ScrollAreaViewportCssVars'
|
|
25
|
+
export { ScrollAreaViewportDataAttributes } from './viewport/ScrollAreaViewportDataAttributes'
|