@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.
@@ -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": "1.0.0",
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": "1.0.0"
62
+ "@bug-on/md3-tokens": "2.0.0"
60
63
  },
61
64
  "devDependencies": {
62
65
  "@testing-library/jest-dom": "^6.9.1",