@octanejs/aria 0.0.4 → 0.0.5
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/package.json +7 -5
- package/src/autocomplete/useAutocomplete.ts +656 -0
- package/src/collections/BaseCollection.ts +374 -0
- package/src/collections/CollectionBuilder.ts +343 -0
- package/src/collections/Document.ts +451 -0
- package/src/collections/Hidden.ts +84 -0
- package/src/collections/useCachedChildren.ts +103 -0
- package/src/components/Autocomplete.ts +124 -0
- package/src/components/Breadcrumbs.ts +170 -0
- package/src/components/Button.ts +209 -0
- package/src/components/Checkbox.ts +593 -0
- package/src/components/Collection.ts +301 -0
- package/src/components/ComboBox.ts +477 -0
- package/src/components/Dialog.ts +195 -0
- package/src/components/Disclosure.ts +322 -0
- package/src/components/DragAndDrop.ts +177 -0
- package/src/components/FieldError.ts +79 -0
- package/src/components/Form.ts +65 -0
- package/src/components/GridList.ts +1099 -0
- package/src/components/Group.ts +146 -0
- package/src/components/Header.ts +32 -0
- package/src/components/Heading.ts +45 -0
- package/src/components/Input.ts +139 -0
- package/src/components/Keyboard.ts +23 -0
- package/src/components/Label.ts +30 -0
- package/src/components/Link.ts +137 -0
- package/src/components/ListBox.ts +886 -0
- package/src/components/Menu.ts +685 -0
- package/src/components/Meter.ts +100 -0
- package/src/components/Modal.ts +352 -0
- package/src/components/NumberField.ts +221 -0
- package/src/components/OverlayArrow.ts +117 -0
- package/src/components/Popover.ts +385 -0
- package/src/components/ProgressBar.ts +112 -0
- package/src/components/RadioGroup.ts +542 -0
- package/src/components/SearchField.ts +208 -0
- package/src/components/Select.ts +505 -0
- package/src/components/SelectionIndicator.ts +52 -0
- package/src/components/Separator.ts +97 -0
- package/src/components/SharedElementTransition.ts +209 -0
- package/src/components/Slider.ts +472 -0
- package/src/components/Switch.ts +449 -0
- package/src/components/Tabs.ts +675 -0
- package/src/components/TagGroup.ts +443 -0
- package/src/components/Text.ts +27 -0
- package/src/components/TextArea.ts +92 -0
- package/src/components/TextField.ts +200 -0
- package/src/components/ToggleButton.ts +147 -0
- package/src/components/ToggleButtonGroup.ts +106 -0
- package/src/components/Toolbar.ts +74 -0
- package/src/components/Tooltip.ts +249 -0
- package/src/components/index.ts +302 -0
- package/src/components/useDragAndDrop.ts +164 -0
- package/src/components/utils.ts +521 -0
- package/src/intl/autocomplete/ar-AE.json +3 -0
- package/src/intl/autocomplete/bg-BG.json +3 -0
- package/src/intl/autocomplete/cs-CZ.json +3 -0
- package/src/intl/autocomplete/da-DK.json +3 -0
- package/src/intl/autocomplete/de-DE.json +3 -0
- package/src/intl/autocomplete/el-GR.json +3 -0
- package/src/intl/autocomplete/en-US.json +3 -0
- package/src/intl/autocomplete/es-ES.json +3 -0
- package/src/intl/autocomplete/et-EE.json +3 -0
- package/src/intl/autocomplete/fi-FI.json +3 -0
- package/src/intl/autocomplete/fr-FR.json +3 -0
- package/src/intl/autocomplete/he-IL.json +3 -0
- package/src/intl/autocomplete/hr-HR.json +3 -0
- package/src/intl/autocomplete/hu-HU.json +3 -0
- package/src/intl/autocomplete/index.ts +75 -0
- package/src/intl/autocomplete/it-IT.json +3 -0
- package/src/intl/autocomplete/ja-JP.json +3 -0
- package/src/intl/autocomplete/ko-KR.json +3 -0
- package/src/intl/autocomplete/lt-LT.json +3 -0
- package/src/intl/autocomplete/lv-LV.json +3 -0
- package/src/intl/autocomplete/nb-NO.json +3 -0
- package/src/intl/autocomplete/nl-NL.json +3 -0
- package/src/intl/autocomplete/pl-PL.json +3 -0
- package/src/intl/autocomplete/pt-BR.json +3 -0
- package/src/intl/autocomplete/pt-PT.json +3 -0
- package/src/intl/autocomplete/ro-RO.json +3 -0
- package/src/intl/autocomplete/ru-RU.json +3 -0
- package/src/intl/autocomplete/sk-SK.json +3 -0
- package/src/intl/autocomplete/sl-SI.json +3 -0
- package/src/intl/autocomplete/sr-SP.json +3 -0
- package/src/intl/autocomplete/sv-SE.json +3 -0
- package/src/intl/autocomplete/tr-TR.json +3 -0
- package/src/intl/autocomplete/uk-UA.json +3 -0
- package/src/intl/autocomplete/zh-CN.json +3 -0
- package/src/intl/autocomplete/zh-TW.json +3 -0
- package/src/stately/autocomplete/useAutocompleteState.ts +85 -0
- package/src/utils/animation.ts +149 -0
- package/src/utils/useLoadMoreSentinel.ts +78 -0
- package/src/utils/useViewportSize.ts +123 -0
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
// Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Slider.tsx).
|
|
2
|
+
// octane adaptations: `.tsx` → `.ts`, JSX → `createElement`; NO forwardRef — the forwarded ref
|
|
3
|
+
// is `props.ref`, passed into `useContextProps` explicitly and re-applied as the merged object
|
|
4
|
+
// ref (SliderThumb has no context and reads `props.ref` directly); the plain-`.ts` components
|
|
5
|
+
// use the S()/subSlot component-slot convention; `clamp` comes from the binding's stately
|
|
6
|
+
// utils port; React's HTMLAttributes/OutputHTMLAttributes prop bags → structural records.
|
|
7
|
+
// The thumb's hidden `<input type="range">` keeps upstream's native wiring (position math
|
|
8
|
+
// reads track rects, which are inert in jsdom — tests assert aria/data-* wiring, not pixels).
|
|
9
|
+
import type { HoverEvents, Orientation, RefObject } from '@react-types/shared';
|
|
10
|
+
import { createContext, createElement, useContext, useRef } from 'octane';
|
|
11
|
+
|
|
12
|
+
import { useFocusRing } from '../focus/useFocusRing';
|
|
13
|
+
import { useNumberFormatter } from '../i18n/useNumberFormatter';
|
|
14
|
+
import { useHover } from '../interactions/useHover';
|
|
15
|
+
import { S, subSlot } from '../internal';
|
|
16
|
+
import { type AriaSliderProps, useSlider } from '../slider/useSlider';
|
|
17
|
+
import { type AriaSliderThumbProps, useSliderThumb } from '../slider/useSliderThumb';
|
|
18
|
+
import { type SliderState, useSliderState } from '../stately/slider/useSliderState';
|
|
19
|
+
import { clamp } from '../stately/utils/number';
|
|
20
|
+
import { filterDOMProps } from '../utils/filterDOMProps';
|
|
21
|
+
import { mergeProps } from '../utils/mergeProps';
|
|
22
|
+
import { VisuallyHidden } from '../visually-hidden/VisuallyHidden';
|
|
23
|
+
import { LabelContext } from './Label';
|
|
24
|
+
import {
|
|
25
|
+
type ClassNameOrFunction,
|
|
26
|
+
type ContextValue,
|
|
27
|
+
dom,
|
|
28
|
+
Provider,
|
|
29
|
+
type RenderProps,
|
|
30
|
+
type SlotProps,
|
|
31
|
+
useContextProps,
|
|
32
|
+
useRenderProps,
|
|
33
|
+
useSlot,
|
|
34
|
+
useSlottedContext,
|
|
35
|
+
} from './utils';
|
|
36
|
+
|
|
37
|
+
// octane adaptations: structural bags (upstream's React attribute/handler types).
|
|
38
|
+
type GlobalDOMAttributes = Record<string, any>;
|
|
39
|
+
type HTMLAttributes = Record<string, any>;
|
|
40
|
+
type OutputHTMLAttributes = Record<string, any>;
|
|
41
|
+
|
|
42
|
+
export interface SliderProps<T = number | number[]>
|
|
43
|
+
extends
|
|
44
|
+
Omit<AriaSliderProps<T>, 'label'>,
|
|
45
|
+
RenderProps<SliderRenderProps>,
|
|
46
|
+
SlotProps,
|
|
47
|
+
GlobalDOMAttributes {
|
|
48
|
+
/**
|
|
49
|
+
* The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
|
|
50
|
+
* element. A function may be provided to compute the class based on component state.
|
|
51
|
+
*
|
|
52
|
+
* @default 'react-aria-Slider'
|
|
53
|
+
*/
|
|
54
|
+
className?: ClassNameOrFunction<SliderRenderProps>;
|
|
55
|
+
/**
|
|
56
|
+
* The display format of the value label.
|
|
57
|
+
*/
|
|
58
|
+
formatOptions?: Intl.NumberFormatOptions;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const SliderContext = createContext<ContextValue<SliderProps, HTMLDivElement>>(null);
|
|
62
|
+
export const SliderStateContext = createContext<SliderState | null>(null);
|
|
63
|
+
export const SliderTrackContext =
|
|
64
|
+
createContext<ContextValue<SliderTrackContextValue, HTMLDivElement>>(null);
|
|
65
|
+
export const SliderFillContext = createContext<ContextValue<SliderFillProps, HTMLDivElement>>(null);
|
|
66
|
+
export const SliderOutputContext =
|
|
67
|
+
createContext<ContextValue<SliderOutputContextValue, HTMLOutputElement>>(null);
|
|
68
|
+
|
|
69
|
+
export interface SliderRenderProps {
|
|
70
|
+
/**
|
|
71
|
+
* The orientation of the slider.
|
|
72
|
+
*
|
|
73
|
+
* @selector [data-orientation="horizontal | vertical"]
|
|
74
|
+
*/
|
|
75
|
+
orientation: Orientation;
|
|
76
|
+
/**
|
|
77
|
+
* Whether the slider is disabled.
|
|
78
|
+
*
|
|
79
|
+
* @selector [data-disabled]
|
|
80
|
+
*/
|
|
81
|
+
isDisabled: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* State of the slider.
|
|
84
|
+
*/
|
|
85
|
+
state: SliderState;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* A slider allows a user to select one or more values within a range.
|
|
90
|
+
*/
|
|
91
|
+
export function Slider<T extends number | number[]>(props: SliderProps<T>): any {
|
|
92
|
+
const slot = S('Slider');
|
|
93
|
+
let ref: any;
|
|
94
|
+
[props, ref] = useContextProps(props, props.ref, SliderContext, subSlot(slot, 'ctx'));
|
|
95
|
+
let trackRef = useRef<HTMLDivElement | null>(null, subSlot(slot, 'track'));
|
|
96
|
+
let numberFormatter = useNumberFormatter(props.formatOptions, subSlot(slot, 'formatter'));
|
|
97
|
+
let state = useSliderState({ ...props, numberFormatter }, subSlot(slot, 'state'));
|
|
98
|
+
let [labelRef, label] = useSlot(
|
|
99
|
+
!props['aria-label'] && !props['aria-labelledby'],
|
|
100
|
+
subSlot(slot, 'labelSlot'),
|
|
101
|
+
);
|
|
102
|
+
let { groupProps, trackProps, labelProps, outputProps } = useSlider(
|
|
103
|
+
{ ...props, label },
|
|
104
|
+
state,
|
|
105
|
+
trackRef,
|
|
106
|
+
subSlot(slot, 'slider'),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
let renderProps = useRenderProps(
|
|
110
|
+
{
|
|
111
|
+
...props,
|
|
112
|
+
values: {
|
|
113
|
+
orientation: state.orientation,
|
|
114
|
+
isDisabled: state.isDisabled,
|
|
115
|
+
state,
|
|
116
|
+
},
|
|
117
|
+
defaultClassName: 'react-aria-Slider',
|
|
118
|
+
},
|
|
119
|
+
subSlot(slot, 'render'),
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
let DOMProps = filterDOMProps(props, { global: true });
|
|
123
|
+
delete DOMProps.id;
|
|
124
|
+
|
|
125
|
+
return createElement(Provider, {
|
|
126
|
+
values: [
|
|
127
|
+
[SliderStateContext, state],
|
|
128
|
+
[SliderTrackContext, { ...trackProps, ref: trackRef }],
|
|
129
|
+
[SliderOutputContext, outputProps],
|
|
130
|
+
[LabelContext, { ...labelProps, ref: labelRef }],
|
|
131
|
+
] as any,
|
|
132
|
+
children: createElement(dom.div, {
|
|
133
|
+
...mergeProps(DOMProps, renderProps, groupProps),
|
|
134
|
+
ref,
|
|
135
|
+
slot: props.slot || undefined,
|
|
136
|
+
'data-orientation': state.orientation,
|
|
137
|
+
'data-disabled': state.isDisabled || undefined,
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface SliderOutputProps
|
|
143
|
+
extends RenderProps<SliderRenderProps, 'output'>, GlobalDOMAttributes {
|
|
144
|
+
/**
|
|
145
|
+
* The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
|
|
146
|
+
* element. A function may be provided to compute the class based on component state.
|
|
147
|
+
*
|
|
148
|
+
* @default 'react-aria-SliderOutput'
|
|
149
|
+
*/
|
|
150
|
+
className?: ClassNameOrFunction<SliderRenderProps>;
|
|
151
|
+
}
|
|
152
|
+
interface SliderOutputContextValue
|
|
153
|
+
extends Omit<OutputHTMLAttributes, 'children' | 'className' | 'style'>, SliderOutputProps {}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* A slider output displays the current value of a slider as text.
|
|
157
|
+
*/
|
|
158
|
+
export function SliderOutput(props: SliderOutputProps): any {
|
|
159
|
+
const slot = S('SliderOutput');
|
|
160
|
+
let ref: any;
|
|
161
|
+
[props, ref] = useContextProps(props, props.ref, SliderOutputContext, subSlot(slot, 'ctx'));
|
|
162
|
+
let { children, style, className, render, ...otherProps } = props;
|
|
163
|
+
let state = useContext(SliderStateContext)!;
|
|
164
|
+
let renderProps = useRenderProps(
|
|
165
|
+
{
|
|
166
|
+
className,
|
|
167
|
+
style,
|
|
168
|
+
children,
|
|
169
|
+
render,
|
|
170
|
+
defaultChildren: state.getFormattedValue(),
|
|
171
|
+
defaultClassName: 'react-aria-SliderOutput',
|
|
172
|
+
values: {
|
|
173
|
+
orientation: state.orientation,
|
|
174
|
+
isDisabled: state.isDisabled,
|
|
175
|
+
state,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
subSlot(slot, 'render'),
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
return createElement(dom.output, {
|
|
182
|
+
...otherProps,
|
|
183
|
+
...renderProps,
|
|
184
|
+
ref,
|
|
185
|
+
'data-orientation': state.orientation || undefined,
|
|
186
|
+
'data-disabled': state.isDisabled || undefined,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface SliderTrackRenderProps extends SliderRenderProps {
|
|
191
|
+
/**
|
|
192
|
+
* Whether the slider track is currently hovered with a mouse.
|
|
193
|
+
*
|
|
194
|
+
* @selector [data-hovered]
|
|
195
|
+
*/
|
|
196
|
+
isHovered: boolean;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface SliderTrackProps
|
|
200
|
+
extends HoverEvents, RenderProps<SliderTrackRenderProps>, GlobalDOMAttributes {
|
|
201
|
+
/**
|
|
202
|
+
* The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
|
|
203
|
+
* element. A function may be provided to compute the class based on component state.
|
|
204
|
+
*
|
|
205
|
+
* @default 'react-aria-SliderTrack'
|
|
206
|
+
*/
|
|
207
|
+
className?: ClassNameOrFunction<SliderTrackRenderProps>;
|
|
208
|
+
}
|
|
209
|
+
interface SliderTrackContextValue
|
|
210
|
+
extends Omit<HTMLAttributes, 'children' | 'className' | 'style'>, SliderTrackProps {}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* A slider track is a container for one or more slider thumbs.
|
|
214
|
+
*/
|
|
215
|
+
export function SliderTrack(props: SliderTrackProps): any {
|
|
216
|
+
const slot = S('SliderTrack');
|
|
217
|
+
let ref: any;
|
|
218
|
+
[props, ref] = useContextProps(props, props.ref, SliderTrackContext, subSlot(slot, 'ctx'));
|
|
219
|
+
let state = useContext(SliderStateContext)!;
|
|
220
|
+
let { onHoverStart, onHoverEnd, onHoverChange, ...otherProps } = props;
|
|
221
|
+
let { hoverProps, isHovered } = useHover(
|
|
222
|
+
{ onHoverStart, onHoverEnd, onHoverChange },
|
|
223
|
+
subSlot(slot, 'hover'),
|
|
224
|
+
);
|
|
225
|
+
let renderProps = useRenderProps(
|
|
226
|
+
{
|
|
227
|
+
...props,
|
|
228
|
+
defaultClassName: 'react-aria-SliderTrack',
|
|
229
|
+
values: {
|
|
230
|
+
orientation: state.orientation,
|
|
231
|
+
isDisabled: state.isDisabled,
|
|
232
|
+
isHovered,
|
|
233
|
+
state,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
subSlot(slot, 'render'),
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
return createElement(dom.div, {
|
|
240
|
+
...mergeProps(otherProps, hoverProps),
|
|
241
|
+
...renderProps,
|
|
242
|
+
ref,
|
|
243
|
+
'data-hovered': isHovered || undefined,
|
|
244
|
+
'data-orientation': state.orientation || undefined,
|
|
245
|
+
'data-disabled': state.isDisabled || undefined,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface SliderThumbRenderProps {
|
|
250
|
+
/**
|
|
251
|
+
* State of the slider.
|
|
252
|
+
*/
|
|
253
|
+
state: SliderState;
|
|
254
|
+
/**
|
|
255
|
+
* Whether this thumb is currently being dragged.
|
|
256
|
+
*
|
|
257
|
+
* @selector [data-dragging]
|
|
258
|
+
*/
|
|
259
|
+
isDragging: boolean;
|
|
260
|
+
/**
|
|
261
|
+
* Whether the thumb is currently hovered with a mouse.
|
|
262
|
+
*
|
|
263
|
+
* @selector [data-hovered]
|
|
264
|
+
*/
|
|
265
|
+
isHovered: boolean;
|
|
266
|
+
/**
|
|
267
|
+
* Whether the thumb is currently focused.
|
|
268
|
+
*
|
|
269
|
+
* @selector [data-focused]
|
|
270
|
+
*/
|
|
271
|
+
isFocused: boolean;
|
|
272
|
+
/**
|
|
273
|
+
* Whether the thumb is keyboard focused.
|
|
274
|
+
*
|
|
275
|
+
* @selector [data-focus-visible]
|
|
276
|
+
*/
|
|
277
|
+
isFocusVisible: boolean;
|
|
278
|
+
/**
|
|
279
|
+
* Whether the thumb is disabled.
|
|
280
|
+
*
|
|
281
|
+
* @selector [data-disabled]
|
|
282
|
+
*/
|
|
283
|
+
isDisabled: boolean;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface SliderThumbProps
|
|
287
|
+
extends
|
|
288
|
+
Omit<AriaSliderThumbProps, 'label' | 'validationState'>,
|
|
289
|
+
HoverEvents,
|
|
290
|
+
RenderProps<SliderThumbRenderProps>,
|
|
291
|
+
GlobalDOMAttributes {
|
|
292
|
+
/**
|
|
293
|
+
* The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
|
|
294
|
+
* element. A function may be provided to compute the class based on component state.
|
|
295
|
+
*
|
|
296
|
+
* @default 'react-aria-SliderThumb'
|
|
297
|
+
*/
|
|
298
|
+
className?: ClassNameOrFunction<SliderThumbRenderProps>;
|
|
299
|
+
/**
|
|
300
|
+
* A ref for the HTML input element.
|
|
301
|
+
*/
|
|
302
|
+
inputRef?: RefObject<HTMLInputElement | null>;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* A slider thumb represents an individual value that the user can adjust within a slider track.
|
|
307
|
+
*/
|
|
308
|
+
export function SliderThumb(props: SliderThumbProps): any {
|
|
309
|
+
const slot = S('SliderThumb');
|
|
310
|
+
// No thumb context upstream — the forwarded ref is read straight off props.
|
|
311
|
+
let ref = (props as any).ref;
|
|
312
|
+
let { inputRef: userInputRef = null } = props;
|
|
313
|
+
let state = useContext(SliderStateContext)!;
|
|
314
|
+
let { ref: trackRef } = useSlottedContext(SliderTrackContext)!;
|
|
315
|
+
let { index = 0 } = props;
|
|
316
|
+
let defaultInputRef = useRef<HTMLInputElement | null>(null, subSlot(slot, 'input'));
|
|
317
|
+
let inputRef = userInputRef || defaultInputRef;
|
|
318
|
+
let [labelRef, label] = useSlot(
|
|
319
|
+
!props['aria-label'] && !props['aria-labelledby'],
|
|
320
|
+
subSlot(slot, 'labelSlot'),
|
|
321
|
+
);
|
|
322
|
+
let { thumbProps, inputProps, labelProps, isDragging, isFocused, isDisabled } = useSliderThumb(
|
|
323
|
+
{
|
|
324
|
+
...props,
|
|
325
|
+
index,
|
|
326
|
+
trackRef: trackRef as RefObject<HTMLDivElement | null>,
|
|
327
|
+
inputRef,
|
|
328
|
+
label,
|
|
329
|
+
},
|
|
330
|
+
state,
|
|
331
|
+
subSlot(slot, 'thumb'),
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
let { focusProps, isFocusVisible } = useFocusRing(undefined, subSlot(slot, 'focusRing'));
|
|
335
|
+
let { hoverProps, isHovered } = useHover(props, subSlot(slot, 'hover'));
|
|
336
|
+
|
|
337
|
+
let renderProps = useRenderProps(
|
|
338
|
+
{
|
|
339
|
+
...props,
|
|
340
|
+
defaultClassName: 'react-aria-SliderThumb',
|
|
341
|
+
values: {
|
|
342
|
+
state,
|
|
343
|
+
isHovered,
|
|
344
|
+
isDragging,
|
|
345
|
+
isFocused,
|
|
346
|
+
isFocusVisible,
|
|
347
|
+
isDisabled,
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
subSlot(slot, 'render'),
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
let DOMProps = filterDOMProps(props, { global: true });
|
|
354
|
+
delete DOMProps.id;
|
|
355
|
+
|
|
356
|
+
return createElement(dom.div, {
|
|
357
|
+
...mergeProps(DOMProps, thumbProps, hoverProps),
|
|
358
|
+
...renderProps,
|
|
359
|
+
ref,
|
|
360
|
+
style: { ...thumbProps.style, ...renderProps.style },
|
|
361
|
+
'data-hovered': isHovered || undefined,
|
|
362
|
+
'data-dragging': isDragging || undefined,
|
|
363
|
+
'data-focused': isFocused || undefined,
|
|
364
|
+
'data-focus-visible': isFocusVisible || undefined,
|
|
365
|
+
'data-disabled': isDisabled || undefined,
|
|
366
|
+
// octane adaptation: keys keep the two-item child array (hidden input +
|
|
367
|
+
// provider-wrapped children) reconciling stably (upstream renders JSX siblings).
|
|
368
|
+
children: [
|
|
369
|
+
createElement(VisuallyHidden, {
|
|
370
|
+
key: 'input',
|
|
371
|
+
children: createElement('input', {
|
|
372
|
+
ref: inputRef,
|
|
373
|
+
...mergeProps(inputProps, focusProps),
|
|
374
|
+
}),
|
|
375
|
+
}),
|
|
376
|
+
createElement(Provider, {
|
|
377
|
+
key: 'children',
|
|
378
|
+
values: [[LabelContext, { ...labelProps, ref: labelRef }]] as any,
|
|
379
|
+
children: renderProps.children,
|
|
380
|
+
}),
|
|
381
|
+
],
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export interface SliderFillRenderProps extends SliderRenderProps {
|
|
386
|
+
/**
|
|
387
|
+
* Whether the slider fill is currently hovered with a mouse.
|
|
388
|
+
*
|
|
389
|
+
* @selector [data-hovered]
|
|
390
|
+
*/
|
|
391
|
+
isHovered: boolean;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export interface SliderFillProps
|
|
395
|
+
extends HoverEvents, RenderProps<SliderFillRenderProps>, GlobalDOMAttributes {
|
|
396
|
+
/**
|
|
397
|
+
* The offset from which to start the fill.
|
|
398
|
+
*
|
|
399
|
+
* @default 0
|
|
400
|
+
*/
|
|
401
|
+
offset?: number;
|
|
402
|
+
/**
|
|
403
|
+
* The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
|
|
404
|
+
* element. A function may be provided to compute the class based on component state.
|
|
405
|
+
*
|
|
406
|
+
* @default 'react-aria-SliderFill'
|
|
407
|
+
*/
|
|
408
|
+
className?: ClassNameOrFunction<SliderFillRenderProps>;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Displays the selected range.
|
|
413
|
+
*/
|
|
414
|
+
export function SliderFill(props: SliderFillProps): any {
|
|
415
|
+
const slot = S('SliderFill');
|
|
416
|
+
let ref: any;
|
|
417
|
+
[props, ref] = useContextProps(props, props.ref, SliderFillContext, subSlot(slot, 'ctx'));
|
|
418
|
+
let state = useContext(SliderStateContext)!;
|
|
419
|
+
let { onHoverStart, onHoverEnd, onHoverChange, ...otherProps } = props;
|
|
420
|
+
let { hoverProps, isHovered } = useHover(
|
|
421
|
+
{ onHoverStart, onHoverEnd, onHoverChange },
|
|
422
|
+
subSlot(slot, 'hover'),
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
let offset =
|
|
426
|
+
props.offset != null
|
|
427
|
+
? clamp(props.offset, state.getThumbMinValue(0), state.getThumbMaxValue(0))
|
|
428
|
+
: state.getThumbMinValue(0);
|
|
429
|
+
let start =
|
|
430
|
+
state.values.length > 1 ? state.getThumbPercent(0) * 100 : state.getValuePercent(offset) * 100;
|
|
431
|
+
let end = state.values.length > 0 ? state.getThumbPercent(state.values.length - 1) * 100 : 0;
|
|
432
|
+
let startPercent = Math.min(start, end);
|
|
433
|
+
let endPercent = Math.max(start, end);
|
|
434
|
+
let sizePercent = Math.max(0, endPercent - startPercent);
|
|
435
|
+
|
|
436
|
+
let renderProps = useRenderProps(
|
|
437
|
+
{
|
|
438
|
+
...props,
|
|
439
|
+
defaultClassName: 'react-aria-SliderFill',
|
|
440
|
+
defaultStyle:
|
|
441
|
+
state.orientation === 'vertical'
|
|
442
|
+
? {
|
|
443
|
+
position: 'absolute',
|
|
444
|
+
bottom: `${startPercent}%`,
|
|
445
|
+
height: `${sizePercent}%`,
|
|
446
|
+
width: '100%',
|
|
447
|
+
}
|
|
448
|
+
: {
|
|
449
|
+
position: 'absolute',
|
|
450
|
+
insetInlineStart: `${startPercent}%`,
|
|
451
|
+
width: `${sizePercent}%`,
|
|
452
|
+
height: '100%',
|
|
453
|
+
},
|
|
454
|
+
values: {
|
|
455
|
+
orientation: state.orientation,
|
|
456
|
+
isDisabled: state.isDisabled,
|
|
457
|
+
isHovered,
|
|
458
|
+
state,
|
|
459
|
+
},
|
|
460
|
+
},
|
|
461
|
+
subSlot(slot, 'render'),
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
return createElement(dom.div, {
|
|
465
|
+
...mergeProps(otherProps, hoverProps),
|
|
466
|
+
...renderProps,
|
|
467
|
+
ref,
|
|
468
|
+
'data-hovered': isHovered || undefined,
|
|
469
|
+
'data-orientation': state.orientation || undefined,
|
|
470
|
+
'data-disabled': state.isDisabled || undefined,
|
|
471
|
+
});
|
|
472
|
+
}
|