@bug-on/md3-react 1.0.0 → 2.0.1
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/assets/material-symbols-self-hosted.css +3 -22
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1747 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1745 -3
- package/dist/index.mjs.map +1 -1
- package/dist/material-symbols-self-hosted.css +3 -22
- package/dist/ui/slider/hooks/useSliderMath.d.ts +101 -0
- package/dist/ui/slider/index.d.ts +9 -0
- package/dist/ui/slider/range-slider.d.ts +47 -0
- package/dist/ui/slider/slider-thumb.d.ts +33 -0
- package/dist/ui/slider/slider-track.d.ts +25 -0
- package/dist/ui/slider/slider.d.ts +60 -0
- package/dist/ui/slider/slider.tokens.d.ts +151 -0
- package/dist/ui/slider/slider.types.d.ts +259 -0
- package/package.json +5 -2
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file slider.types.ts
|
|
3
|
+
* MD3 Expressive Slider — TypeScript prop definitions.
|
|
4
|
+
* Spec: https://m3.material.io/components/sliders/overview
|
|
5
|
+
* Reference: docs/m3/sliders/Slider.kt
|
|
6
|
+
*/
|
|
7
|
+
import type * as React from "react";
|
|
8
|
+
/** Track size variants mapping to physical px values. */
|
|
9
|
+
export type SliderTrackSize = "xs" | "s" | "m" | "l" | "xl";
|
|
10
|
+
export type SliderVariant = "primary" | "secondary" | "tertiary" | "error";
|
|
11
|
+
export type SliderTrackShape = "md3" | "full" | number;
|
|
12
|
+
/** Slider layout direction. */
|
|
13
|
+
export type SliderOrientation = "horizontal" | "vertical";
|
|
14
|
+
/**
|
|
15
|
+
* Internal context shared between Slider sub-components.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export interface SliderContextValue {
|
|
19
|
+
/** Minimum allowed value. */
|
|
20
|
+
min: number;
|
|
21
|
+
/** Maximum allowed value. */
|
|
22
|
+
max: number;
|
|
23
|
+
/**
|
|
24
|
+
* Step size. When > 0, slider is discrete and snaps to multiples of step.
|
|
25
|
+
* When 0, slider is continuous.
|
|
26
|
+
*/
|
|
27
|
+
step: number;
|
|
28
|
+
/** Whether the slider is interactive. */
|
|
29
|
+
disabled: boolean;
|
|
30
|
+
/** Layout orientation. */
|
|
31
|
+
orientation: SliderOrientation;
|
|
32
|
+
/** Physical size of the track. */
|
|
33
|
+
trackSize: SliderTrackSize;
|
|
34
|
+
/** Color variant. */
|
|
35
|
+
variant: SliderVariant;
|
|
36
|
+
/**
|
|
37
|
+
* When true, active track originates from center (50%) instead of the min end.
|
|
38
|
+
* Mirrors Compose's `SliderDefaults.Track(drawCenteredTrack = true)`.
|
|
39
|
+
*/
|
|
40
|
+
isCentered: boolean;
|
|
41
|
+
/** Show the floating value tooltip on hover/drag. */
|
|
42
|
+
showValueIndicator: boolean;
|
|
43
|
+
/** Ref to the track DOM element — used for drag constraint. */
|
|
44
|
+
trackRef: React.RefObject<HTMLDivElement | null>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Props for the `<Slider>` component.
|
|
48
|
+
*
|
|
49
|
+
* Supports both controlled (`value` + `onValueChange`) and
|
|
50
|
+
* uncontrolled (`defaultValue`) usage patterns per React standards.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* // Controlled
|
|
55
|
+
* <Slider value={volume} onValueChange={setVolume} min={0} max={100} />
|
|
56
|
+
*
|
|
57
|
+
* // Uncontrolled
|
|
58
|
+
* <Slider defaultValue={50} />
|
|
59
|
+
*
|
|
60
|
+
* // Discrete (step snapping)
|
|
61
|
+
* <Slider defaultValue={0} step={10} />
|
|
62
|
+
*
|
|
63
|
+
* // Vertical orientation
|
|
64
|
+
* <Slider defaultValue={50} orientation="vertical" />
|
|
65
|
+
*
|
|
66
|
+
* // Centered active track
|
|
67
|
+
* <Slider defaultValue={0} isCentered />
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export interface SliderProps {
|
|
71
|
+
/** Controlled current value. Use with `onValueChange`. */
|
|
72
|
+
value?: number;
|
|
73
|
+
/** Initial value for uncontrolled usage. @default midpoint of min/max */
|
|
74
|
+
defaultValue?: number;
|
|
75
|
+
/** Called whenever the value changes during interaction. */
|
|
76
|
+
onValueChange?: (value: number) => void;
|
|
77
|
+
/** Called when the user finishes dragging / commits a keyboard change. */
|
|
78
|
+
onValueChangeEnd?: (value: number) => void;
|
|
79
|
+
/** Minimum value. @default 0 */
|
|
80
|
+
min?: number;
|
|
81
|
+
/** Maximum value. @default 100 */
|
|
82
|
+
max?: number;
|
|
83
|
+
/**
|
|
84
|
+
* Step size. When > 0, slider snaps to multiples of `step` from `min`
|
|
85
|
+
* and renders tick marks. When 0, slider is continuous.
|
|
86
|
+
* @default 0
|
|
87
|
+
*/
|
|
88
|
+
step?: number;
|
|
89
|
+
/** Layout orientation. @default "horizontal" */
|
|
90
|
+
orientation?: SliderOrientation;
|
|
91
|
+
/**
|
|
92
|
+
* Physical track size.
|
|
93
|
+
* Horizontal: height. Vertical: width.
|
|
94
|
+
* @default "m"
|
|
95
|
+
*/
|
|
96
|
+
trackSize?: SliderTrackSize;
|
|
97
|
+
/**
|
|
98
|
+
* Color variant.
|
|
99
|
+
* @default "primary"
|
|
100
|
+
*/
|
|
101
|
+
variant?: SliderVariant;
|
|
102
|
+
/**
|
|
103
|
+
* When true, the active track segment grows from the center (50%)
|
|
104
|
+
* outward toward the thumb position.
|
|
105
|
+
* @default false
|
|
106
|
+
*/
|
|
107
|
+
isCentered?: boolean;
|
|
108
|
+
/** Disables all interaction. @default false */
|
|
109
|
+
disabled?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* When true, shows a floating value indicator tooltip above the thumb.
|
|
112
|
+
* @default false
|
|
113
|
+
*/
|
|
114
|
+
showValueIndicator?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* When true, shows tick marks along the track.
|
|
117
|
+
* Only applicable if `step` > 0.
|
|
118
|
+
* @default false
|
|
119
|
+
*/
|
|
120
|
+
showTicks?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Track shape configuration for border radius.
|
|
123
|
+
* - "md3": Default MD3 specific border radius per size
|
|
124
|
+
* - "full": Fully rounded ends (pill shape - size/2)
|
|
125
|
+
* - number: Custom border radius in px
|
|
126
|
+
* @default "md3"
|
|
127
|
+
*/
|
|
128
|
+
trackShape?: SliderTrackShape;
|
|
129
|
+
/**
|
|
130
|
+
* Icon rendered inside the track (inset icon).
|
|
131
|
+
* MD3 spec: only valid for M, L, XL track sizes.
|
|
132
|
+
* The icon moves from the active track to the inactive track
|
|
133
|
+
* when there's not enough space at low values.
|
|
134
|
+
* Do not use with `isCentered` or `RangeSlider`.
|
|
135
|
+
*/
|
|
136
|
+
insetIcon?: React.ReactNode;
|
|
137
|
+
/**
|
|
138
|
+
* Alternate icon shown when value equals `min`.
|
|
139
|
+
* Swaps with `insetIcon` at the minimum value
|
|
140
|
+
* (e.g., a mute icon replacing a volume icon when volume = 0).
|
|
141
|
+
*/
|
|
142
|
+
insetIconAtMin?: React.ReactNode;
|
|
143
|
+
/**
|
|
144
|
+
* Icon rendered inside the track at the trailing end (right side).
|
|
145
|
+
* Only valid for track sizes >= 40dp (e.g. XL).
|
|
146
|
+
*/
|
|
147
|
+
insetIconTrailing?: React.ReactNode;
|
|
148
|
+
/**
|
|
149
|
+
* Alternate icon shown when value equals `max`.
|
|
150
|
+
* Swaps with `insetIconTrailing` at the maximum value.
|
|
151
|
+
*/
|
|
152
|
+
insetIconAtMax?: React.ReactNode;
|
|
153
|
+
/** Additional CSS class applied to the outermost wrapper. */
|
|
154
|
+
className?: string;
|
|
155
|
+
/**
|
|
156
|
+
* Accessible label for the slider when no visible label exists.
|
|
157
|
+
* Required if parent does not have a visible label.
|
|
158
|
+
*/
|
|
159
|
+
"aria-label"?: string;
|
|
160
|
+
/** ID of a visible label element. Required if `aria-label` is not provided. */
|
|
161
|
+
"aria-labelledby"?: string;
|
|
162
|
+
/**
|
|
163
|
+
* Format function for the displayed value in the value indicator tooltip.
|
|
164
|
+
* Defaults to `String(value)`.
|
|
165
|
+
*/
|
|
166
|
+
formatValue?: (value: number) => string;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Props for the `<RangeSlider>` component.
|
|
170
|
+
*
|
|
171
|
+
* Extends `SliderProps` with tuple-based value API.
|
|
172
|
+
* The two thumbs cannot cross each other.
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```tsx
|
|
176
|
+
* <RangeSlider
|
|
177
|
+
* value={[20, 80]}
|
|
178
|
+
* onValueChange={([start, end]) => setRange([start, end])}
|
|
179
|
+
* />
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export interface RangeSliderProps extends Omit<SliderProps, "value" | "defaultValue" | "onValueChange" | "onValueChangeEnd" | "isCentered"> {
|
|
183
|
+
/** Controlled [start, end] tuple. Use with `onValueChange`. */
|
|
184
|
+
value?: [number, number];
|
|
185
|
+
/** Initial [start, end] tuple for uncontrolled usage. */
|
|
186
|
+
defaultValue?: [number, number];
|
|
187
|
+
/** Called whenever [start, end] changes during interaction. */
|
|
188
|
+
onValueChange?: (value: [number, number]) => void;
|
|
189
|
+
/** Called when the user finishes dragging either thumb. */
|
|
190
|
+
onValueChangeEnd?: (value: [number, number]) => void;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Props for `<SliderTrack>`.
|
|
194
|
+
* @internal
|
|
195
|
+
*/
|
|
196
|
+
export interface SliderTrackProps {
|
|
197
|
+
/** Current thumb position as 0–1 fraction. */
|
|
198
|
+
percent: number;
|
|
199
|
+
trackSize: SliderTrackSize;
|
|
200
|
+
orientation: SliderOrientation;
|
|
201
|
+
variant: SliderVariant;
|
|
202
|
+
isCentered: boolean;
|
|
203
|
+
/** For discrete mode: step size. 0 = no ticks. */
|
|
204
|
+
step: number;
|
|
205
|
+
min: number;
|
|
206
|
+
max: number;
|
|
207
|
+
disabled: boolean;
|
|
208
|
+
trackShape?: SliderTrackShape;
|
|
209
|
+
/** Ref forwarded to the root track element for drag constraint. */
|
|
210
|
+
trackRef: React.RefObject<HTMLDivElement | null>;
|
|
211
|
+
/** onClick handler on the track for click-to-jump. */
|
|
212
|
+
onTrackPointerDown?: (e: React.PointerEvent<HTMLDivElement>) => void;
|
|
213
|
+
/**
|
|
214
|
+
* Icon rendered inside the track (inset icon).
|
|
215
|
+
* @internal — passed down from Slider after guard check.
|
|
216
|
+
*/
|
|
217
|
+
insetIcon?: React.ReactNode;
|
|
218
|
+
/** Alternate icon swapped in when value === min. @internal */
|
|
219
|
+
insetIconAtMin?: React.ReactNode;
|
|
220
|
+
/** Icon rendered at the trailing end (right side). @internal */
|
|
221
|
+
insetIconTrailing?: React.ReactNode;
|
|
222
|
+
/** Alternate icon swapped in when value === max. @internal */
|
|
223
|
+
insetIconAtMax?: React.ReactNode;
|
|
224
|
+
/** Current slider value — used for inset icon swap at min/max. @internal */
|
|
225
|
+
value?: number;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Props for `<SliderThumb>`.
|
|
229
|
+
* @internal
|
|
230
|
+
*/
|
|
231
|
+
export interface SliderThumbProps {
|
|
232
|
+
/** Current value (for ARIA). */
|
|
233
|
+
value: number;
|
|
234
|
+
/** Current 0–1 fraction (for positioning). */
|
|
235
|
+
percent: number;
|
|
236
|
+
min: number;
|
|
237
|
+
max: number;
|
|
238
|
+
step: number;
|
|
239
|
+
disabled: boolean;
|
|
240
|
+
orientation: SliderOrientation;
|
|
241
|
+
showValueIndicator: boolean;
|
|
242
|
+
/** For the drag constraint ref. */
|
|
243
|
+
trackRef: React.RefObject<HTMLDivElement | null>;
|
|
244
|
+
trackSize: SliderTrackSize;
|
|
245
|
+
variant: SliderVariant;
|
|
246
|
+
/** Called during pointer drag with new value. */
|
|
247
|
+
onValueChange: (value: number) => void;
|
|
248
|
+
/** Called on drag end / keyboard commit. */
|
|
249
|
+
onValueChangeEnd?: (value: number) => void;
|
|
250
|
+
/** Value display formatter. */
|
|
251
|
+
formatValue?: (value: number) => string;
|
|
252
|
+
/** Unique ID for ARIA. */
|
|
253
|
+
thumbId?: string;
|
|
254
|
+
/** zIndex for RangeSlider layering. */
|
|
255
|
+
zIndex?: number;
|
|
256
|
+
/** Optional accessible label for this specific thumb. */
|
|
257
|
+
"aria-label"?: string;
|
|
258
|
+
"aria-labelledby"?: string;
|
|
259
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bug-on/md3-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Material Design 3 Expressive React components",
|
|
5
5
|
"author": "Bug Ổn",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"README.md"
|
|
38
38
|
],
|
|
39
39
|
"sideEffects": false,
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
40
43
|
"peerDependencies": {
|
|
41
44
|
"motion": ">=12.0.0",
|
|
42
45
|
"react": "^19.0.0",
|
|
@@ -56,7 +59,7 @@
|
|
|
56
59
|
"class-variance-authority": "^0.7.1",
|
|
57
60
|
"clsx": "^2.1.1",
|
|
58
61
|
"tailwind-merge": "^3.3.1",
|
|
59
|
-
"@bug-on/md3-tokens": "
|
|
62
|
+
"@bug-on/md3-tokens": "2.0.0"
|
|
60
63
|
},
|
|
61
64
|
"devDependencies": {
|
|
62
65
|
"@testing-library/jest-dom": "^6.9.1",
|