@moises.ai/design-system 4.18.0 → 4.18.2
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/{Sections2Icon-BqCnZLec.js → ChordGrid4Icon-2Br7uolD.js} +824 -814
- package/dist/icons.js +603 -602
- package/dist/index.js +2514 -2397
- package/package.json +1 -1
- package/src/components/Knob/Knob.jsx +181 -87
- package/src/components/Knob/Knob.stories.jsx +138 -23
- package/src/components/PanControl/PanControl.jsx +132 -66
- package/src/components/PanControl/PanControl.stories.jsx +75 -6
- package/src/components/SliderLibrary/SliderLibrary.jsx +61 -3
- package/src/components/SliderLibrary/SliderLibrary.stories.jsx +73 -8
- package/src/icons/ChordGrid4Icon.jsx +10 -0
- package/src/icons.jsx +1 -0
|
@@ -22,6 +22,9 @@ export const PanControl = ({
|
|
|
22
22
|
disabled,
|
|
23
23
|
minValue = -0.65,
|
|
24
24
|
maxValue = 0.65,
|
|
25
|
+
showTooltip = true,
|
|
26
|
+
tooltipDelayDuration = 0,
|
|
27
|
+
tooltipCloseDelay = 500,
|
|
25
28
|
}) => {
|
|
26
29
|
const containerRef = useRef(null)
|
|
27
30
|
const [isDragging, setIsDragging] = useState(false)
|
|
@@ -30,17 +33,31 @@ export const PanControl = ({
|
|
|
30
33
|
const startYRef = useRef(0)
|
|
31
34
|
const pendingNormRef = useRef(value)
|
|
32
35
|
const rafRef = useRef(0)
|
|
36
|
+
const openTimeoutRef = useRef(null)
|
|
37
|
+
const closeTimeoutRef = useRef(null)
|
|
38
|
+
const tooltipTimingRef = useRef({
|
|
39
|
+
tooltipDelayDuration,
|
|
40
|
+
tooltipCloseDelay,
|
|
41
|
+
})
|
|
42
|
+
tooltipTimingRef.current = { tooltipDelayDuration, tooltipCloseDelay }
|
|
33
43
|
|
|
34
44
|
const [knobFocused, setKnobFocused] = useState(false)
|
|
35
|
-
const [
|
|
45
|
+
const [isHovering, setIsHovering] = useState(false)
|
|
36
46
|
|
|
37
47
|
useEffect(() => {
|
|
38
48
|
if (disabled) {
|
|
39
|
-
|
|
49
|
+
setIsHovering(false)
|
|
40
50
|
setKnobFocused(false)
|
|
41
51
|
}
|
|
42
52
|
}, [disabled])
|
|
43
53
|
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
return () => {
|
|
56
|
+
if (openTimeoutRef.current != null) clearTimeout(openTimeoutRef.current)
|
|
57
|
+
if (closeTimeoutRef.current != null) clearTimeout(closeTimeoutRef.current)
|
|
58
|
+
}
|
|
59
|
+
}, [])
|
|
60
|
+
|
|
44
61
|
useEffect(() => {
|
|
45
62
|
if (isDragging) {
|
|
46
63
|
const style = document.createElement('style')
|
|
@@ -187,8 +204,107 @@ export const PanControl = ({
|
|
|
187
204
|
const displayNorm = clampNorm(denormalize(value, minValue, maxValue))
|
|
188
205
|
const ariaPanPct = Math.round(displayNorm * 100)
|
|
189
206
|
|
|
207
|
+
const clearOpenTimeout = () => {
|
|
208
|
+
if (openTimeoutRef.current != null) {
|
|
209
|
+
clearTimeout(openTimeoutRef.current)
|
|
210
|
+
openTimeoutRef.current = null
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const clearCloseTimeout = () => {
|
|
215
|
+
if (closeTimeoutRef.current != null) {
|
|
216
|
+
clearTimeout(closeTimeoutRef.current)
|
|
217
|
+
closeTimeoutRef.current = null
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const handlePointerEnter = () => {
|
|
222
|
+
if (disabled) return
|
|
223
|
+
clearCloseTimeout()
|
|
224
|
+
clearOpenTimeout()
|
|
225
|
+
const { tooltipDelayDuration: delay } = tooltipTimingRef.current
|
|
226
|
+
if (delay <= 0) {
|
|
227
|
+
setIsHovering(true)
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
openTimeoutRef.current = setTimeout(() => {
|
|
231
|
+
openTimeoutRef.current = null
|
|
232
|
+
setIsHovering(true)
|
|
233
|
+
}, delay)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const handlePointerLeave = () => {
|
|
237
|
+
clearOpenTimeout()
|
|
238
|
+
const { tooltipCloseDelay: delay } = tooltipTimingRef.current
|
|
239
|
+
if (delay <= 0) {
|
|
240
|
+
setIsHovering(false)
|
|
241
|
+
return
|
|
242
|
+
}
|
|
243
|
+
closeTimeoutRef.current = setTimeout(() => {
|
|
244
|
+
closeTimeoutRef.current = null
|
|
245
|
+
setIsHovering(false)
|
|
246
|
+
}, delay)
|
|
247
|
+
}
|
|
248
|
+
|
|
190
249
|
const tooltipOpen =
|
|
191
|
-
!disabled && (isDragging || knobFocused ||
|
|
250
|
+
!disabled && (isDragging || knobFocused || isHovering)
|
|
251
|
+
|
|
252
|
+
const pan = (
|
|
253
|
+
<div
|
|
254
|
+
role="slider"
|
|
255
|
+
tabIndex={disabled ? -1 : 0}
|
|
256
|
+
aria-label="Pan"
|
|
257
|
+
aria-valuemin={-100}
|
|
258
|
+
aria-valuemax={100}
|
|
259
|
+
aria-valuenow={ariaPanPct}
|
|
260
|
+
aria-valuetext={panValueText}
|
|
261
|
+
aria-disabled={disabled}
|
|
262
|
+
className={classNames(
|
|
263
|
+
styles.pan,
|
|
264
|
+
isDragging && styles.active,
|
|
265
|
+
disabled && styles.disabled,
|
|
266
|
+
)}
|
|
267
|
+
onPointerDown={onPointerDown}
|
|
268
|
+
onPointerMove={onPointerMove}
|
|
269
|
+
onPointerUp={onPointerUp}
|
|
270
|
+
onPointerCancel={onPointerUp}
|
|
271
|
+
onPointerEnter={handlePointerEnter}
|
|
272
|
+
onPointerLeave={handlePointerLeave}
|
|
273
|
+
onFocus={() => setKnobFocused(true)}
|
|
274
|
+
onBlur={() => setKnobFocused(false)}
|
|
275
|
+
onKeyDown={handleKnobKeyDown}
|
|
276
|
+
>
|
|
277
|
+
<svg width={20} height={20} viewBox="0 0 20 20" fill="none">
|
|
278
|
+
<circle cx={KNOB_CENTER_X} cy={KNOB_CENTER_Y} r={10} />
|
|
279
|
+
<circle
|
|
280
|
+
cx={KNOB_CENTER_X}
|
|
281
|
+
cy={KNOB_CENTER_Y}
|
|
282
|
+
r={KNOB_RADIUS}
|
|
283
|
+
stroke="#D3EDF8"
|
|
284
|
+
strokeOpacity={0.113725}
|
|
285
|
+
/>
|
|
286
|
+
{value !== 0 && (
|
|
287
|
+
<path
|
|
288
|
+
d={arcPath}
|
|
289
|
+
stroke={arcColor}
|
|
290
|
+
strokeLinecap="round"
|
|
291
|
+
strokeWidth={1}
|
|
292
|
+
fill="none"
|
|
293
|
+
/>
|
|
294
|
+
)}
|
|
295
|
+
<g
|
|
296
|
+
transform={`rotate(${pointerRotation} ${KNOB_CENTER_X} ${KNOB_CENTER_Y})`}
|
|
297
|
+
>
|
|
298
|
+
<path
|
|
299
|
+
d="M10 0.5 L10 6"
|
|
300
|
+
stroke={pointerColor}
|
|
301
|
+
strokeLinecap="round"
|
|
302
|
+
strokeWidth={1}
|
|
303
|
+
/>
|
|
304
|
+
</g>
|
|
305
|
+
</svg>
|
|
306
|
+
</div>
|
|
307
|
+
)
|
|
192
308
|
|
|
193
309
|
return (
|
|
194
310
|
<div
|
|
@@ -198,70 +314,20 @@ export const PanControl = ({
|
|
|
198
314
|
onClick={handleClick}
|
|
199
315
|
style={{ cursor: disabled ? 'default' : 'ns-resize' }}
|
|
200
316
|
>
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
sideOffset={3}
|
|
210
|
-
delayDuration={0}
|
|
211
|
-
>
|
|
212
|
-
<div
|
|
213
|
-
role="slider"
|
|
214
|
-
tabIndex={disabled ? -1 : 0}
|
|
215
|
-
aria-label="Pan"
|
|
216
|
-
aria-valuemin={-100}
|
|
217
|
-
aria-valuemax={100}
|
|
218
|
-
aria-valuenow={ariaPanPct}
|
|
219
|
-
aria-valuetext={panValueText}
|
|
220
|
-
aria-disabled={disabled}
|
|
221
|
-
className={classNames(
|
|
222
|
-
styles.pan,
|
|
223
|
-
isDragging && styles.active,
|
|
224
|
-
disabled && styles.disabled,
|
|
225
|
-
)}
|
|
226
|
-
onPointerDown={onPointerDown}
|
|
227
|
-
onPointerMove={onPointerMove}
|
|
228
|
-
onPointerUp={onPointerUp}
|
|
229
|
-
onPointerCancel={onPointerUp}
|
|
230
|
-
onFocus={() => setKnobFocused(true)}
|
|
231
|
-
onBlur={() => setKnobFocused(false)}
|
|
232
|
-
onKeyDown={handleKnobKeyDown}
|
|
317
|
+
{showTooltip ? (
|
|
318
|
+
<Tooltip
|
|
319
|
+
content={panValueText}
|
|
320
|
+
open={tooltipOpen}
|
|
321
|
+
delayDuration={tooltipDelayDuration}
|
|
322
|
+
side="bottom"
|
|
323
|
+
align="center"
|
|
324
|
+
sideOffset={3}
|
|
233
325
|
>
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
r={KNOB_RADIUS}
|
|
240
|
-
stroke="#D3EDF8"
|
|
241
|
-
strokeOpacity={0.113725}
|
|
242
|
-
/>
|
|
243
|
-
{value !== 0 && (
|
|
244
|
-
<path
|
|
245
|
-
d={arcPath}
|
|
246
|
-
stroke={arcColor}
|
|
247
|
-
strokeLinecap="round"
|
|
248
|
-
strokeWidth={1}
|
|
249
|
-
fill="none"
|
|
250
|
-
/>
|
|
251
|
-
)}
|
|
252
|
-
<g
|
|
253
|
-
transform={`rotate(${pointerRotation} ${KNOB_CENTER_X} ${KNOB_CENTER_Y})`}
|
|
254
|
-
>
|
|
255
|
-
<path
|
|
256
|
-
d="M10 0.5 L10 6"
|
|
257
|
-
stroke={pointerColor}
|
|
258
|
-
strokeLinecap="round"
|
|
259
|
-
strokeWidth={1}
|
|
260
|
-
/>
|
|
261
|
-
</g>
|
|
262
|
-
</svg>
|
|
263
|
-
</div>
|
|
264
|
-
</Tooltip>
|
|
326
|
+
{pan}
|
|
327
|
+
</Tooltip>
|
|
328
|
+
) : (
|
|
329
|
+
pan
|
|
330
|
+
)}
|
|
265
331
|
</div>
|
|
266
332
|
)
|
|
267
333
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PanControl } from './PanControl'
|
|
2
2
|
import { useState } from 'react'
|
|
3
|
-
import { Flex } from '@radix-ui/themes'
|
|
3
|
+
import { Flex, Text } from '@radix-ui/themes'
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
title: 'Components/PanControl',
|
|
@@ -20,13 +20,24 @@ export default {
|
|
|
20
20
|
' <PanControl\n' +
|
|
21
21
|
' value={panValue}\n' +
|
|
22
22
|
' onChange={setPanValue}\n' +
|
|
23
|
+
' tooltipDelayDuration={0}\n' +
|
|
24
|
+
' tooltipCloseDelay={500}\n' +
|
|
23
25
|
' />\n' +
|
|
24
26
|
' )\n' +
|
|
25
27
|
'}\n' +
|
|
26
|
-
'
|
|
28
|
+
'```\n\n' +
|
|
29
|
+
'## Tooltip\n\n' +
|
|
30
|
+
'Shows the current pan value on hover/focus/drag. Use `tooltipDelayDuration` and `tooltipCloseDelay` to control open/close timing, or `showTooltip={false}` to hide it.',
|
|
27
31
|
},
|
|
28
32
|
},
|
|
29
33
|
},
|
|
34
|
+
args: {
|
|
35
|
+
showTooltip: true,
|
|
36
|
+
tooltipDelayDuration: 0,
|
|
37
|
+
tooltipCloseDelay: 500,
|
|
38
|
+
minValue: -0.65,
|
|
39
|
+
maxValue: 0.65,
|
|
40
|
+
},
|
|
30
41
|
argTypes: {
|
|
31
42
|
value: {
|
|
32
43
|
description:
|
|
@@ -75,15 +86,35 @@ export default {
|
|
|
75
86
|
defaultValue: { summary: 0.65 },
|
|
76
87
|
},
|
|
77
88
|
},
|
|
89
|
+
showTooltip: {
|
|
90
|
+
control: 'boolean',
|
|
91
|
+
description: 'Shows the pan value tooltip on hover/focus/drag',
|
|
92
|
+
table: {
|
|
93
|
+
type: { summary: 'boolean' },
|
|
94
|
+
defaultValue: { summary: true },
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
tooltipDelayDuration: {
|
|
98
|
+
control: 'number',
|
|
99
|
+
description: 'Ms before the tooltip opens on hover',
|
|
100
|
+
table: {
|
|
101
|
+
type: { summary: 'number' },
|
|
102
|
+
defaultValue: { summary: 0 },
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
tooltipCloseDelay: {
|
|
106
|
+
control: 'number',
|
|
107
|
+
description: 'Ms the tooltip stays open after the pointer leaves',
|
|
108
|
+
table: {
|
|
109
|
+
type: { summary: 'number' },
|
|
110
|
+
defaultValue: { summary: 500 },
|
|
111
|
+
},
|
|
112
|
+
},
|
|
78
113
|
},
|
|
79
114
|
tags: ['autodocs'],
|
|
80
115
|
}
|
|
81
116
|
|
|
82
117
|
export const Default = {
|
|
83
|
-
args: {
|
|
84
|
-
minValue: -0.65,
|
|
85
|
-
maxValue: 0.65,
|
|
86
|
-
},
|
|
87
118
|
render: (args) => {
|
|
88
119
|
const [value, setValue] = useState(0)
|
|
89
120
|
return <PanControl {...args} value={value} onChange={setValue} />
|
|
@@ -98,3 +129,41 @@ export const Disabled = {
|
|
|
98
129
|
)
|
|
99
130
|
},
|
|
100
131
|
}
|
|
132
|
+
|
|
133
|
+
export const WithoutTooltip = {
|
|
134
|
+
args: {
|
|
135
|
+
showTooltip: false,
|
|
136
|
+
},
|
|
137
|
+
render: (args) => {
|
|
138
|
+
const [value, setValue] = useState(0)
|
|
139
|
+
return <PanControl {...args} value={value} onChange={setValue} />
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const TooltipTiming = {
|
|
144
|
+
name: 'Tooltip timing',
|
|
145
|
+
args: {
|
|
146
|
+
tooltipDelayDuration: 200,
|
|
147
|
+
tooltipCloseDelay: 500,
|
|
148
|
+
},
|
|
149
|
+
render: (args) => {
|
|
150
|
+
const [value, setValue] = useState(0)
|
|
151
|
+
return (
|
|
152
|
+
<Flex direction="column" align="center" gap="2">
|
|
153
|
+
<PanControl {...args} value={value} onChange={setValue} />
|
|
154
|
+
<Text size="1" color="gray">
|
|
155
|
+
Opens after {args.tooltipDelayDuration}ms · closes{' '}
|
|
156
|
+
{args.tooltipCloseDelay}ms after leave
|
|
157
|
+
</Text>
|
|
158
|
+
</Flex>
|
|
159
|
+
)
|
|
160
|
+
},
|
|
161
|
+
parameters: {
|
|
162
|
+
docs: {
|
|
163
|
+
description: {
|
|
164
|
+
story:
|
|
165
|
+
'Adjust `tooltipDelayDuration` (open) and `tooltipCloseDelay` (close grace) via controls.',
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
}
|
|
@@ -15,6 +15,10 @@ import styles from './SliderLibrary.module.css'
|
|
|
15
15
|
* @property {boolean} [disabled=false] - Disables interaction and dims the slider.
|
|
16
16
|
* @property {boolean} [showTooltip=true] - Renders the DS Tooltip below the thumb on
|
|
17
17
|
* hover/focus/drag with the current value.
|
|
18
|
+
* @property {number} [tooltipDelayDuration=0] - Time in ms from hover enter until the
|
|
19
|
+
* tooltip opens. Drag and keyboard focus open immediately.
|
|
20
|
+
* @property {number} [tooltipCloseDelay=500] - Time in ms the tooltip stays open after
|
|
21
|
+
* the pointer leaves the thumb (or re-enters within this window).
|
|
18
22
|
* @property {(value: number) => React.ReactNode} [formatValue] - Formats the value for
|
|
19
23
|
* display in the tooltip. Defaults to the raw number.
|
|
20
24
|
* @property {(value: number) => void} [onThumbDoubleClick] - Fires when the thumb is
|
|
@@ -58,6 +62,8 @@ export const SliderLibrary = forwardRef(function SliderLibrary(
|
|
|
58
62
|
step = 1,
|
|
59
63
|
disabled = false,
|
|
60
64
|
showTooltip = true,
|
|
65
|
+
tooltipDelayDuration = 0,
|
|
66
|
+
tooltipCloseDelay = 500,
|
|
61
67
|
formatValue,
|
|
62
68
|
onThumbDoubleClick,
|
|
63
69
|
className,
|
|
@@ -68,6 +74,8 @@ export const SliderLibrary = forwardRef(function SliderLibrary(
|
|
|
68
74
|
const ariaLabel = props['aria-label']
|
|
69
75
|
const internalRef = useRef(null)
|
|
70
76
|
const lastInteractionRef = useRef(null)
|
|
77
|
+
const openTimeoutRef = useRef(null)
|
|
78
|
+
const closeTimeoutRef = useRef(null)
|
|
71
79
|
const [keyboardFocus, setKeyboardFocus] = useState(false)
|
|
72
80
|
const [isHovering, setIsHovering] = useState(false)
|
|
73
81
|
const [isDragging, setIsDragging] = useState(false)
|
|
@@ -75,8 +83,21 @@ export const SliderLibrary = forwardRef(function SliderLibrary(
|
|
|
75
83
|
const stateRef = useRef({ value, min, max, step, disabled, onValueChange })
|
|
76
84
|
stateRef.current = { value, min, max, step, disabled, onValueChange }
|
|
77
85
|
|
|
86
|
+
const tooltipTimingRef = useRef({
|
|
87
|
+
tooltipDelayDuration,
|
|
88
|
+
tooltipCloseDelay,
|
|
89
|
+
})
|
|
90
|
+
tooltipTimingRef.current = { tooltipDelayDuration, tooltipCloseDelay }
|
|
91
|
+
|
|
78
92
|
const wheelRef = useRef({ accum: 0, axis: null, lastTime: 0 })
|
|
79
93
|
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
return () => {
|
|
96
|
+
if (openTimeoutRef.current != null) clearTimeout(openTimeoutRef.current)
|
|
97
|
+
if (closeTimeoutRef.current != null) clearTimeout(closeTimeoutRef.current)
|
|
98
|
+
}
|
|
99
|
+
}, [])
|
|
100
|
+
|
|
80
101
|
useEffect(() => {
|
|
81
102
|
const onKey = () => {
|
|
82
103
|
lastInteractionRef.current = 'keyboard'
|
|
@@ -181,13 +202,50 @@ export const SliderLibrary = forwardRef(function SliderLibrary(
|
|
|
181
202
|
if (!disabled) setIsDragging(true)
|
|
182
203
|
}
|
|
183
204
|
|
|
205
|
+
const clearOpenTimeout = () => {
|
|
206
|
+
if (openTimeoutRef.current != null) {
|
|
207
|
+
clearTimeout(openTimeoutRef.current)
|
|
208
|
+
openTimeoutRef.current = null
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const clearCloseTimeout = () => {
|
|
213
|
+
if (closeTimeoutRef.current != null) {
|
|
214
|
+
clearTimeout(closeTimeoutRef.current)
|
|
215
|
+
closeTimeoutRef.current = null
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
184
219
|
const handleThumbFocus = () => {
|
|
185
220
|
if (lastInteractionRef.current === 'keyboard') setKeyboardFocus(true)
|
|
186
221
|
}
|
|
187
222
|
const handleThumbBlur = () => setKeyboardFocus(false)
|
|
188
223
|
const handleThumbPointerDown = () => setKeyboardFocus(false)
|
|
189
|
-
const handleThumbPointerEnter = () =>
|
|
190
|
-
|
|
224
|
+
const handleThumbPointerEnter = () => {
|
|
225
|
+
clearCloseTimeout()
|
|
226
|
+
clearOpenTimeout()
|
|
227
|
+
const { tooltipDelayDuration: delay } = tooltipTimingRef.current
|
|
228
|
+
if (delay <= 0) {
|
|
229
|
+
setIsHovering(true)
|
|
230
|
+
return
|
|
231
|
+
}
|
|
232
|
+
openTimeoutRef.current = setTimeout(() => {
|
|
233
|
+
openTimeoutRef.current = null
|
|
234
|
+
setIsHovering(true)
|
|
235
|
+
}, delay)
|
|
236
|
+
}
|
|
237
|
+
const handleThumbPointerLeave = () => {
|
|
238
|
+
clearOpenTimeout()
|
|
239
|
+
const { tooltipCloseDelay: delay } = tooltipTimingRef.current
|
|
240
|
+
if (delay <= 0) {
|
|
241
|
+
setIsHovering(false)
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
closeTimeoutRef.current = setTimeout(() => {
|
|
245
|
+
closeTimeoutRef.current = null
|
|
246
|
+
setIsHovering(false)
|
|
247
|
+
}, delay)
|
|
248
|
+
}
|
|
191
249
|
const handleThumbDoubleClick = () => {
|
|
192
250
|
if (!disabled) onThumbDoubleClick?.(value)
|
|
193
251
|
}
|
|
@@ -230,7 +288,7 @@ export const SliderLibrary = forwardRef(function SliderLibrary(
|
|
|
230
288
|
<Tooltip
|
|
231
289
|
content={displayValue}
|
|
232
290
|
open={tooltipOpen}
|
|
233
|
-
delayDuration={
|
|
291
|
+
delayDuration={tooltipDelayDuration}
|
|
234
292
|
side="bottom"
|
|
235
293
|
sideOffset={8}
|
|
236
294
|
updatePositionStrategy="always"
|
|
@@ -7,12 +7,36 @@ export default {
|
|
|
7
7
|
parameters: {
|
|
8
8
|
layout: 'centered',
|
|
9
9
|
},
|
|
10
|
+
args: {
|
|
11
|
+
tooltipDelayDuration: 0,
|
|
12
|
+
tooltipCloseDelay: 500,
|
|
13
|
+
showTooltip: true,
|
|
14
|
+
},
|
|
10
15
|
argTypes: {
|
|
11
16
|
value: { control: { type: 'number' } },
|
|
12
17
|
min: { control: { type: 'number' } },
|
|
13
18
|
max: { control: { type: 'number' } },
|
|
14
19
|
step: { control: { type: 'number' } },
|
|
15
20
|
disabled: { control: { type: 'boolean' } },
|
|
21
|
+
showTooltip: {
|
|
22
|
+
control: { type: 'boolean' },
|
|
23
|
+
description: 'Shows the value tooltip on hover/focus/drag.',
|
|
24
|
+
},
|
|
25
|
+
tooltipDelayDuration: {
|
|
26
|
+
control: { type: 'number' },
|
|
27
|
+
description: 'Ms before the tooltip opens on hover.',
|
|
28
|
+
table: {
|
|
29
|
+
defaultValue: { summary: 0 },
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
tooltipCloseDelay: {
|
|
33
|
+
control: { type: 'number' },
|
|
34
|
+
description:
|
|
35
|
+
'Ms the tooltip stays open after the pointer leaves the thumb.',
|
|
36
|
+
table: {
|
|
37
|
+
defaultValue: { summary: 500 },
|
|
38
|
+
},
|
|
39
|
+
},
|
|
16
40
|
},
|
|
17
41
|
decorators: [
|
|
18
42
|
(Story) => (
|
|
@@ -31,10 +55,11 @@ export default {
|
|
|
31
55
|
}
|
|
32
56
|
|
|
33
57
|
export const Default = {
|
|
34
|
-
render: () => {
|
|
58
|
+
render: (args) => {
|
|
35
59
|
const [value, setValue] = useState(50)
|
|
36
60
|
return (
|
|
37
61
|
<SliderLibrary
|
|
62
|
+
{...args}
|
|
38
63
|
value={value}
|
|
39
64
|
onValueChange={setValue}
|
|
40
65
|
formatValue={(v) => `${v}%`}
|
|
@@ -45,8 +70,9 @@ export const Default = {
|
|
|
45
70
|
}
|
|
46
71
|
|
|
47
72
|
export const Disabled = {
|
|
48
|
-
render: () => (
|
|
73
|
+
render: (args) => (
|
|
49
74
|
<SliderLibrary
|
|
75
|
+
{...args}
|
|
50
76
|
value={75}
|
|
51
77
|
onValueChange={() => {}}
|
|
52
78
|
disabled
|
|
@@ -57,10 +83,11 @@ export const Disabled = {
|
|
|
57
83
|
|
|
58
84
|
export const CustomRange = {
|
|
59
85
|
name: 'Custom range (-12 to 12 dB)',
|
|
60
|
-
render: () => {
|
|
86
|
+
render: (args) => {
|
|
61
87
|
const [value, setValue] = useState(0)
|
|
62
88
|
return (
|
|
63
89
|
<SliderLibrary
|
|
90
|
+
{...args}
|
|
64
91
|
value={value}
|
|
65
92
|
onValueChange={setValue}
|
|
66
93
|
min={-12}
|
|
@@ -74,26 +101,63 @@ export const CustomRange = {
|
|
|
74
101
|
}
|
|
75
102
|
|
|
76
103
|
export const WithoutTooltip = {
|
|
77
|
-
|
|
104
|
+
args: {
|
|
105
|
+
showTooltip: false,
|
|
106
|
+
},
|
|
107
|
+
render: (args) => {
|
|
78
108
|
const [value, setValue] = useState(50)
|
|
79
109
|
return (
|
|
80
110
|
<SliderLibrary
|
|
111
|
+
{...args}
|
|
81
112
|
value={value}
|
|
82
113
|
onValueChange={setValue}
|
|
83
|
-
showTooltip={false}
|
|
84
114
|
aria-label="Volume"
|
|
85
115
|
/>
|
|
86
116
|
)
|
|
87
117
|
},
|
|
88
118
|
}
|
|
89
119
|
|
|
120
|
+
export const TooltipTiming = {
|
|
121
|
+
name: 'Tooltip timing',
|
|
122
|
+
args: {
|
|
123
|
+
tooltipDelayDuration: 200,
|
|
124
|
+
tooltipCloseDelay: 500,
|
|
125
|
+
},
|
|
126
|
+
render: (args) => {
|
|
127
|
+
const [value, setValue] = useState(50)
|
|
128
|
+
return (
|
|
129
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
|
130
|
+
<SliderLibrary
|
|
131
|
+
{...args}
|
|
132
|
+
value={value}
|
|
133
|
+
onValueChange={setValue}
|
|
134
|
+
formatValue={(v) => `${v}%`}
|
|
135
|
+
aria-label="Volume"
|
|
136
|
+
/>
|
|
137
|
+
<span style={{ color: '#a1a1a1', fontSize: 12 }}>
|
|
138
|
+
Opens after {args.tooltipDelayDuration}ms · closes {args.tooltipCloseDelay}ms
|
|
139
|
+
after leave
|
|
140
|
+
</span>
|
|
141
|
+
</div>
|
|
142
|
+
)
|
|
143
|
+
},
|
|
144
|
+
parameters: {
|
|
145
|
+
docs: {
|
|
146
|
+
description: {
|
|
147
|
+
story:
|
|
148
|
+
'Adjust `tooltipDelayDuration` (open) and `tooltipCloseDelay` (close grace) via controls.',
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
}
|
|
153
|
+
|
|
90
154
|
export const WithLabel = {
|
|
91
|
-
render: () => {
|
|
155
|
+
render: (args) => {
|
|
92
156
|
const [value, setValue] = useState(30)
|
|
93
157
|
return (
|
|
94
158
|
<label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
95
159
|
<span style={{ color: '#fff', fontSize: 14 }}>Volume</span>
|
|
96
|
-
<SliderLibrary value={value} onValueChange={setValue} />
|
|
160
|
+
<SliderLibrary {...args} value={value} onValueChange={setValue} />
|
|
97
161
|
</label>
|
|
98
162
|
)
|
|
99
163
|
},
|
|
@@ -101,12 +165,13 @@ export const WithLabel = {
|
|
|
101
165
|
|
|
102
166
|
export const ThumbDoubleClick = {
|
|
103
167
|
name: 'Thumb double-click',
|
|
104
|
-
render: () => {
|
|
168
|
+
render: (args) => {
|
|
105
169
|
const defaultValue = 0
|
|
106
170
|
const [value, setValue] = useState(35)
|
|
107
171
|
return (
|
|
108
172
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
|
109
173
|
<SliderLibrary
|
|
174
|
+
{...args}
|
|
110
175
|
value={value}
|
|
111
176
|
onValueChange={setValue}
|
|
112
177
|
onThumbDoubleClick={() => setValue(defaultValue)}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const ChordGrid4Icon = ({ width = 16, height = 16, className, ...props }) => (
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} viewBox="0 0 16 16" fill="none" className={className} {...props}>
|
|
3
|
+
<path
|
|
4
|
+
d="M6.00016 2.33337V6.66671M10.0002 2.33337V6.66671M6.00016 9.33337V13.6666M10.0002 9.33337V13.6666M3.3335 6.66671H12.6668C13.2191 6.66671 13.6668 6.21899 13.6668 5.66671V3.33337C13.6668 2.78109 13.2191 2.33337 12.6668 2.33337H3.3335C2.78121 2.33337 2.3335 2.78109 2.3335 3.33337V5.66671C2.3335 6.21899 2.78121 6.66671 3.3335 6.66671ZM3.3335 13.6666H12.6668C13.2191 13.6666 13.6668 13.2189 13.6668 12.6666V10.3334C13.6668 9.78109 13.2191 9.33337 12.6668 9.33337H3.3335C2.78121 9.33337 2.3335 9.78109 2.3335 10.3334V12.6666C2.3335 13.2189 2.78121 13.6666 3.3335 13.6666Z"
|
|
5
|
+
stroke="currentColor"
|
|
6
|
+
strokeMiterlimit="10"/>
|
|
7
|
+
</svg>
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
ChordGrid4Icon.displayName = 'ChordGrid4Icon'
|
package/src/icons.jsx
CHANGED
|
@@ -447,3 +447,4 @@ export { ChordGrid3Icon } from './icons/ChordGrid3Icon'
|
|
|
447
447
|
export { ChordDiagramGridIcon } from './icons/ChordDiagramGridIcon'
|
|
448
448
|
export { DynamicMicrophone2Icon } from './icons/DynamicMicrophone2Icon'
|
|
449
449
|
export { Sections2Icon } from './icons/Sections2Icon'
|
|
450
|
+
export { ChordGrid4Icon } from './icons/ChordGrid4Icon'
|