@bloomreach/react-banana-ui 1.36.0 → 1.38.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/bloomreach-react-banana-ui.es.js +11282 -9409
- package/dist/bloomreach-react-banana-ui.es.js.map +1 -1
- package/dist/bloomreach-react-banana-ui.umd.js +19 -19
- package/dist/bloomreach-react-banana-ui.umd.js.map +1 -1
- package/dist/components/inputs/autocomplete/autocomplete.stories.d.ts +10 -0
- package/dist/components/inputs/autocomplete/autocomplete.types.d.ts +36 -0
- package/dist/components/inputs/field-label/field-label.types.d.ts +2 -2
- package/dist/components/inputs/index.d.ts +1 -0
- package/dist/components/inputs/internal.d.ts +1 -0
- package/dist/components/inputs/slider/index.d.ts +4 -0
- package/dist/components/inputs/slider/internal/components/index.d.ts +4 -0
- package/dist/components/inputs/slider/internal/components/slider-mark-list.d.ts +20 -0
- package/dist/components/inputs/slider/internal/components/slider-number-input.d.ts +32 -0
- package/dist/components/inputs/slider/internal/components/slider-thumb.d.ts +31 -0
- package/dist/components/inputs/slider/internal/components/slider-tickmarks.d.ts +13 -0
- package/dist/components/inputs/slider/internal/hooks/index.d.ts +5 -0
- package/dist/components/inputs/slider/internal/hooks/use-slider-base.d.ts +18 -0
- package/dist/components/inputs/slider/internal/hooks/use-slider-hidden-input-props.d.ts +47 -0
- package/dist/components/inputs/slider/internal/hooks/use-slider-marks.d.ts +14 -0
- package/dist/components/inputs/slider/internal/hooks/use-slider-pointer-interaction.d.ts +47 -0
- package/dist/components/inputs/slider/internal/hooks/use-slider.d.ts +17 -0
- package/dist/components/inputs/slider/internal/index.d.ts +4 -0
- package/dist/components/inputs/slider/internal/types/index.d.ts +2 -0
- package/dist/components/inputs/slider/internal/types/slider.internal-types.d.ts +97 -0
- package/dist/components/inputs/slider/internal/utils/index.d.ts +2 -0
- package/dist/components/inputs/slider/internal/utils/slider.helpers.d.ts +227 -0
- package/dist/components/inputs/slider/internal/utils/slider.utils.d.ts +190 -0
- package/dist/components/inputs/slider/slider/index.d.ts +2 -0
- package/dist/components/inputs/slider/slider/slider.d.ts +17 -0
- package/dist/components/inputs/slider/slider/slider.qa.stories.d.ts +27 -0
- package/dist/components/inputs/slider/slider/slider.stories.d.ts +33 -0
- package/dist/components/inputs/slider/slider/slider.types.d.ts +229 -0
- package/dist/components/inputs/slider/slider-field/index.d.ts +2 -0
- package/dist/components/inputs/slider/slider-field/slider-field.d.ts +27 -0
- package/dist/components/inputs/slider/slider-field/slider-field.qa.stories.d.ts +18 -0
- package/dist/components/inputs/slider/slider-field/slider-field.stories.d.ts +15 -0
- package/dist/components/inputs/slider/slider-field/slider-field.types.d.ts +24 -0
- package/dist/react-banana-ui.css +1 -1
- package/dist/utils/dom.d.ts +7 -0
- package/dist/utils/hooks/index.d.ts +2 -0
- package/dist/utils/hooks/use-event-callback.d.ts +6 -0
- package/dist/utils/hooks/use-fork-refs.d.ts +7 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/types/styles.types.d.ts +1 -1
- package/package.json +44 -43
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { InputHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import type * as React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Handler called when the user finishes a change (mouseup, touchend, blur, or keyboard commit).
|
|
5
|
+
* Use this for expensive side effects like API calls that should only run on "commit".
|
|
6
|
+
*/
|
|
7
|
+
export type SliderChangeCommittedHandler = (event: Event | React.SyntheticEvent, value: SliderValue) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Handler called continuously as the slider value changes (during drag, keyboard navigation, or input).
|
|
10
|
+
* Receives the active thumb index to support range sliders.
|
|
11
|
+
*/
|
|
12
|
+
export type SliderChangeHandler = (event: Event, value: SliderValue, activeThumb: number) => void;
|
|
13
|
+
/**
|
|
14
|
+
* HTML attributes allowed on the visible number input (`withNumberInput`).
|
|
15
|
+
* Omits attributes that are managed internally by the slider.
|
|
16
|
+
*/
|
|
17
|
+
export type SliderNumberInputAttributes = Omit<InputHTMLAttributes<HTMLInputElement>, 'defaultValue' | 'disabled' | 'max' | 'min' | 'readOnly' | 'step' | 'type' | 'value'>;
|
|
18
|
+
/** Tuple of two numbers for range sliders. */
|
|
19
|
+
export type SliderRangeValue = [number, number];
|
|
20
|
+
/** Single number, or a range tuple for dual-thumb sliders. */
|
|
21
|
+
export type SliderValue = number | SliderRangeValue;
|
|
22
|
+
/** A discrete mark position on the slider, with an optional label displayed below the track. */
|
|
23
|
+
export interface Mark {
|
|
24
|
+
/**
|
|
25
|
+
* The label to display at the mark position.
|
|
26
|
+
*/
|
|
27
|
+
label?: ReactNode;
|
|
28
|
+
/**
|
|
29
|
+
* The value at which the mark is placed.
|
|
30
|
+
*/
|
|
31
|
+
value: number;
|
|
32
|
+
}
|
|
33
|
+
/** Public props for the `Slider` component. */
|
|
34
|
+
export interface SliderProps {
|
|
35
|
+
/**
|
|
36
|
+
* The label of the slider.
|
|
37
|
+
*/
|
|
38
|
+
'aria-label'?: string;
|
|
39
|
+
/**
|
|
40
|
+
* The id of the element containing a label for the slider.
|
|
41
|
+
*/
|
|
42
|
+
'aria-labelledby'?: string;
|
|
43
|
+
/**
|
|
44
|
+
* A string value that provides a user-friendly name for the current value of the slider.
|
|
45
|
+
*/
|
|
46
|
+
'aria-valuetext'?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Custom class name for the container of the component.
|
|
49
|
+
*/
|
|
50
|
+
className?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The default value. Use when the component is not controlled.
|
|
53
|
+
* For range sliders, provide a tuple with exactly two values.
|
|
54
|
+
*/
|
|
55
|
+
defaultValue?: SliderValue;
|
|
56
|
+
/**
|
|
57
|
+
* If `true`, the component is disabled.
|
|
58
|
+
* @default false
|
|
59
|
+
*/
|
|
60
|
+
disabled?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* If `true`, the active thumb doesn't swap when moving pointer over a thumb while dragging another thumb.
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
disableSwap?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* If `true`, the slider is in an error state.
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
70
|
+
error?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Accepts a function which returns a string value that provides a user-friendly name
|
|
73
|
+
* for the thumb labels of the slider. This is important for screen reader users.
|
|
74
|
+
* @param {number} index The thumb label's index to format.
|
|
75
|
+
* @returns {string}
|
|
76
|
+
*/
|
|
77
|
+
getAriaLabel?: (index: number) => string;
|
|
78
|
+
/**
|
|
79
|
+
* Accepts a function which returns a string value that provides a user-friendly name
|
|
80
|
+
* for the current value of the slider. This is important for screen reader users.
|
|
81
|
+
* @param {number} value The thumb label's value to format.
|
|
82
|
+
* @param {number} index The thumb label's index to format.
|
|
83
|
+
* @returns {string}
|
|
84
|
+
*/
|
|
85
|
+
getAriaValueText?: (value: number, index: number) => string;
|
|
86
|
+
/**
|
|
87
|
+
* Props applied to the visible number input when `withNumberInput` is enabled.
|
|
88
|
+
* Provide a function to customize the props per thumb in range sliders.
|
|
89
|
+
* Range sliders render exactly two visible inputs when `withNumberInput` is enabled.
|
|
90
|
+
* Visible inputs keep transient text while the user edits and commit normalized values on blur or Enter.
|
|
91
|
+
*/
|
|
92
|
+
inputProps?: ((index: number) => SliderNumberInputAttributes) | SliderNumberInputAttributes;
|
|
93
|
+
/**
|
|
94
|
+
* The length of the slider along its main axis. Accepts any valid CSS value.
|
|
95
|
+
* Sets `width` for horizontal sliders and `height` for vertical sliders.
|
|
96
|
+
*/
|
|
97
|
+
length?: number | string;
|
|
98
|
+
/**
|
|
99
|
+
* Marks indicate predetermined values to which the user can move the slider.
|
|
100
|
+
* If `true` the marks are spaced according the value of the `step` prop.
|
|
101
|
+
* If an array, it should contain objects with `value` and an optional `label` keys.
|
|
102
|
+
* @default false
|
|
103
|
+
*/
|
|
104
|
+
marks?: boolean | Mark[];
|
|
105
|
+
/**
|
|
106
|
+
* The maximum allowed value of the slider.
|
|
107
|
+
* @default 100
|
|
108
|
+
*/
|
|
109
|
+
max?: number;
|
|
110
|
+
/**
|
|
111
|
+
* The minimum allowed value of the slider.
|
|
112
|
+
* @default 0
|
|
113
|
+
*/
|
|
114
|
+
min?: number;
|
|
115
|
+
/**
|
|
116
|
+
* The minimum allowed distance between adjacent thumbs in a range slider.
|
|
117
|
+
* The value uses the same unit as the slider itself.
|
|
118
|
+
* @default 0
|
|
119
|
+
*/
|
|
120
|
+
minDistance?: number;
|
|
121
|
+
/**
|
|
122
|
+
* Name attribute of the hidden `input` element.
|
|
123
|
+
* For range sliders, native form submission uses indexed names: `${name}[0]` and `${name}[1]`.
|
|
124
|
+
*/
|
|
125
|
+
name?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Callback function that is fired when the slider's value changed.
|
|
128
|
+
* @param {Event} event The event source of the callback.
|
|
129
|
+
* @param {number | number[]} value The new value.
|
|
130
|
+
* @param {number} activeThumb Index of the currently moved thumb.
|
|
131
|
+
*/
|
|
132
|
+
onChange?: SliderChangeHandler;
|
|
133
|
+
/**
|
|
134
|
+
* Callback function that is fired when the `mouseup` is triggered.
|
|
135
|
+
* @param {React.SyntheticEvent | Event} event The event source of the callback.
|
|
136
|
+
* @param {number | number[]} value The new value.
|
|
137
|
+
*/
|
|
138
|
+
onChangeCommitted?: SliderChangeCommittedHandler;
|
|
139
|
+
/**
|
|
140
|
+
* The component orientation.
|
|
141
|
+
* @default 'horizontal'
|
|
142
|
+
*/
|
|
143
|
+
orientation?: 'horizontal' | 'vertical';
|
|
144
|
+
/**
|
|
145
|
+
* If `true`, the component is read only. The slider is visible but not interactive.
|
|
146
|
+
* @default false
|
|
147
|
+
*/
|
|
148
|
+
readOnly?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* A transformation function, to change the scale of the slider.
|
|
151
|
+
* The slider still stores and submits raw values. The transformed value is used for
|
|
152
|
+
* display-oriented output such as value labels and ARIA value text.
|
|
153
|
+
* @default (x) => x
|
|
154
|
+
*/
|
|
155
|
+
scale?: (value: number) => number;
|
|
156
|
+
/**
|
|
157
|
+
* The granularity with which the slider can step through values
|
|
158
|
+
* when using Page Up/Page Down or Shift + Arrow Up/Arrow Down.
|
|
159
|
+
* @default 10
|
|
160
|
+
*/
|
|
161
|
+
shiftStep?: number;
|
|
162
|
+
/**
|
|
163
|
+
* The size of the slider.
|
|
164
|
+
* @default 'md'
|
|
165
|
+
*/
|
|
166
|
+
size?: 'md' | 'sm';
|
|
167
|
+
/**
|
|
168
|
+
* When set, the slider magnetically snaps to nearby mark positions while dragging.
|
|
169
|
+
* - `true` uses a default threshold of 2% of the total range.
|
|
170
|
+
* - A number sets a custom threshold as a percentage of the range (e.g., `5` = 5%).
|
|
171
|
+
* Only active when `marks` is an array and `step` is not `null`.
|
|
172
|
+
* @default false
|
|
173
|
+
*/
|
|
174
|
+
snapToMarks?: boolean | number;
|
|
175
|
+
/**
|
|
176
|
+
* The granularity with which the slider can step through values.
|
|
177
|
+
* When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop.
|
|
178
|
+
* @default 1
|
|
179
|
+
*/
|
|
180
|
+
step?: null | number;
|
|
181
|
+
/**
|
|
182
|
+
* Tab index attribute of the hidden `input` element.
|
|
183
|
+
*/
|
|
184
|
+
tabIndex?: number;
|
|
185
|
+
/**
|
|
186
|
+
* Number of evenly-spaced decorative tick dots to render on the slider track.
|
|
187
|
+
* When set, dots are displayed along the rail with active/inactive coloring.
|
|
188
|
+
* If marks are also provided, larger dots are shown at mark positions.
|
|
189
|
+
* Very large decorative counts may be capped to keep rendering lightweight.
|
|
190
|
+
*/
|
|
191
|
+
tickmarks?: number;
|
|
192
|
+
/**
|
|
193
|
+
* The track presentation:
|
|
194
|
+
* - `normal` the track will render a bar representing the slider value.
|
|
195
|
+
* - `inverted` the track will render a bar representing the remaining slider value.
|
|
196
|
+
* - `center` the track will render a bar from the midpoint of the range to the current value.
|
|
197
|
+
* - `false` the track will render without a bar.
|
|
198
|
+
* @default 'normal'
|
|
199
|
+
*/
|
|
200
|
+
track?: 'center' | 'inverted' | 'normal' | false;
|
|
201
|
+
/**
|
|
202
|
+
* The value of the slider. For ranged sliders, provide a tuple with exactly two values.
|
|
203
|
+
*/
|
|
204
|
+
value?: SliderValue;
|
|
205
|
+
/**
|
|
206
|
+
* Controls when the value label is displayed:
|
|
207
|
+
* - `auto` the value label will display when the thumb is hovered or focused.
|
|
208
|
+
* - `on` will display persistently.
|
|
209
|
+
* - `off` will never display.
|
|
210
|
+
* @default 'auto'
|
|
211
|
+
*/
|
|
212
|
+
valueLabelDisplay?: 'auto' | 'off' | 'on';
|
|
213
|
+
/**
|
|
214
|
+
* The format function the value label's value.
|
|
215
|
+
* @param {number} value The value label's value to format.
|
|
216
|
+
* @param {number} index The value label's index to format.
|
|
217
|
+
* @returns {React.ReactNode}
|
|
218
|
+
* @default (x) => x
|
|
219
|
+
*/
|
|
220
|
+
valueLabelFormat?: (value: number, index: number) => ReactNode;
|
|
221
|
+
/**
|
|
222
|
+
* If `true`, a number input is rendered alongside the slider for direct value entry.
|
|
223
|
+
* For range sliders, two inputs are shown (one per thumb).
|
|
224
|
+
* The visible inputs respect slider constraints such as step, marks, snapping, and minimum thumb distance.
|
|
225
|
+
* Partial text entry is preserved while typing and normalized when the input is committed.
|
|
226
|
+
* @default false
|
|
227
|
+
*/
|
|
228
|
+
withNumberInput?: boolean;
|
|
229
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SliderFieldProps } from './slider-field.types';
|
|
2
|
+
/**
|
|
3
|
+
* SliderField wraps a Slider with a label, helper text, and optional tooltip.
|
|
4
|
+
* Use this component when the slider needs to appear within a form with consistent field layout.
|
|
5
|
+
*
|
|
6
|
+
* ### Usage
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { SliderField } from '@bloomreach/react-banana-ui';
|
|
10
|
+
* import { useState } from 'react';
|
|
11
|
+
*
|
|
12
|
+
* export default function VolumeControl() {
|
|
13
|
+
* const [volume, setVolume] = useState(50);
|
|
14
|
+
*
|
|
15
|
+
* return (
|
|
16
|
+
* <SliderField
|
|
17
|
+
* label="Volume"
|
|
18
|
+
* withNumberInput
|
|
19
|
+
* value={volume}
|
|
20
|
+
* onChange={(_, value) => setVolume(value as number)}
|
|
21
|
+
* />
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare const SliderField: import('react').ForwardRefExoticComponent<SliderFieldProps & import('react').RefAttributes<HTMLSpanElement>>;
|
|
27
|
+
export default SliderField;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Meta } from '@storybook/react-vite';
|
|
2
|
+
import { Story } from './slider-field.stories';
|
|
3
|
+
declare const meta: Meta;
|
|
4
|
+
export default meta;
|
|
5
|
+
export declare const AllFieldStates: Story;
|
|
6
|
+
export declare const WithInput: Story;
|
|
7
|
+
export declare const WithInputRange: Story;
|
|
8
|
+
export declare const WithInputDisabled: Story;
|
|
9
|
+
export declare const WithInputReadOnly: Story;
|
|
10
|
+
export declare const WithInputError: Story;
|
|
11
|
+
export declare const WithoutNumberInput: Story;
|
|
12
|
+
export declare const Required: Story;
|
|
13
|
+
export declare const FullWidth: Story;
|
|
14
|
+
export declare const WithMarks: Story;
|
|
15
|
+
export declare const VerticalField: Story;
|
|
16
|
+
export declare const WithTooltip: Story;
|
|
17
|
+
export declare const ControlledFieldWithInput: Story;
|
|
18
|
+
export declare const ControlledRangeField: Story;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { default as SliderField } from '.';
|
|
2
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
+
declare const meta: Meta<typeof SliderField>;
|
|
4
|
+
export default meta;
|
|
5
|
+
export type Story = StoryObj<typeof SliderField>;
|
|
6
|
+
export declare const WithInput: Story;
|
|
7
|
+
export declare const WithInputRange: Story;
|
|
8
|
+
export declare const WithInputDisabled: Story;
|
|
9
|
+
export declare const WithInputReadOnly: Story;
|
|
10
|
+
export declare const WithInputError: Story;
|
|
11
|
+
export declare const WithoutNumberInput: Story;
|
|
12
|
+
export declare const Required: Story;
|
|
13
|
+
export declare const FullWidth: Story;
|
|
14
|
+
export declare const WithMarks: Story;
|
|
15
|
+
export declare const Vertical: Story;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SliderProps } from '../slider/slider.types';
|
|
3
|
+
export interface SliderFieldProps extends SliderProps {
|
|
4
|
+
/**
|
|
5
|
+
* If `true`, the field will take up the full width of its container.
|
|
6
|
+
*/
|
|
7
|
+
fullWidth?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* The helper text content.
|
|
10
|
+
*/
|
|
11
|
+
helperText?: ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* The label content.
|
|
14
|
+
*/
|
|
15
|
+
label?: ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* If `true`, the field will display a red asterisk next to the label to indicate it is required.
|
|
18
|
+
*/
|
|
19
|
+
required?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Tooltip to display when the field has a label.
|
|
22
|
+
*/
|
|
23
|
+
tooltip?: ReactNode;
|
|
24
|
+
}
|