etudes 0.45.0 → 0.46.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/lib/ExtractChildren.js +5 -7
- package/lib/ExtractChildren.js.map +1 -1
- package/lib/Slider.js +4 -4
- package/lib/Slider.js.map +1 -1
- package/lib/StepwiseSlider.js +4 -4
- package/lib/StepwiseSlider.js.map +1 -1
- package/package.json +1 -1
package/lib/ExtractChildren.js
CHANGED
|
@@ -44,13 +44,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
44
44
|
var react_1 = __importStar(require("react"));
|
|
45
45
|
function ExtractChildren(_a) {
|
|
46
46
|
var children = _a.children, props = __rest(_a, ["children"]);
|
|
47
|
-
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}),
|
|
53
|
-
")"));
|
|
47
|
+
return (react_1.default.createElement(react_1.default.Fragment, null, react_1.Children.map(children, function (child) {
|
|
48
|
+
if ((0, react_1.isValidElement)(child))
|
|
49
|
+
return (0, react_1.cloneElement)(child, __assign({}, props));
|
|
50
|
+
return child;
|
|
51
|
+
})));
|
|
54
52
|
}
|
|
55
53
|
exports.default = ExtractChildren;
|
|
56
54
|
//# sourceMappingURL=ExtractChildren.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExtractChildren.js","sourceRoot":"/","sources":["ExtractChildren.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAwG;AAExG,SAAwB,eAAe,CAAC,EAAsE;IAApE,IAAA,QAAQ,cAAA,EAAK,KAAK,cAApB,YAAsB,CAAF;IAC1D,OAAO,CACL
|
|
1
|
+
{"version":3,"file":"ExtractChildren.js","sourceRoot":"/","sources":["ExtractChildren.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAwG;AAExG,SAAwB,eAAe,CAAC,EAAsE;IAApE,IAAA,QAAQ,cAAA,EAAK,KAAK,cAApB,YAAsB,CAAF;IAC1D,OAAO,CACL,8DACG,gBAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAA,KAAK;QAC3B,IAAI,IAAA,sBAAc,EAAC,KAAK,CAAC;YAAE,OAAO,IAAA,oBAAY,EAAC,KAAK,eAAO,KAAK,EAAG,CAAA;QACnE,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CACD,CACJ,CAAA;AACH,CAAC;AATD,kCASC","sourcesContent":["import React, { Children, cloneElement, HTMLAttributes, isValidElement, PropsWithChildren } from 'react'\n\nexport default function ExtractChildren({ children, ...props }: PropsWithChildren<HTMLAttributes<HTMLElement>>) {\n return (\n <>\n {Children.map(children, child => {\n if (isValidElement(child)) return cloneElement(child, { ...props })\n return child\n })}\n </>\n )\n}\n"]}
|
package/lib/Slider.js
CHANGED
|
@@ -140,10 +140,10 @@ function Slider(_a) {
|
|
|
140
140
|
return (react_1.default.createElement(StyledRoot, __assign({ ref: rootRef, orientation: orientation }, props),
|
|
141
141
|
react_1.default.createElement(StyledStartingTrack, { orientation: orientation, isClickable: isTrackInteractive, css: cssStartingTrack, onClick: function (event) { return onTrackClick(event); }, style: orientation === 'vertical' ? {
|
|
142
142
|
top: 0,
|
|
143
|
-
height: "calc(".concat(naturalPosition * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
143
|
+
height: "calc(".concat(naturalPosition * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
144
144
|
} : {
|
|
145
145
|
left: 0,
|
|
146
|
-
width: "calc(".concat(naturalPosition * 100, "% - ").concat(knobWidth * .5, "px - ").concat(trackPadding, "px)"),
|
|
146
|
+
width: "calc(".concat(naturalPosition * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobWidth * .5, "px - ").concat(trackPadding, "px)"),
|
|
147
147
|
} }),
|
|
148
148
|
react_1.default.createElement(StyledKnobContainer, { ref: knobRef, style: __assign({ transform: 'translate3d(-50%, -50%, 0)' }, (orientation === 'vertical' ? {
|
|
149
149
|
left: '50%',
|
|
@@ -164,10 +164,10 @@ function Slider(_a) {
|
|
|
164
164
|
} }, labelProvider && (react_1.default.createElement(StyledLabel, { knobHeight: knobHeight, css: cssLabel }, labelProvider(position))))),
|
|
165
165
|
react_1.default.createElement(StyledEndingTrack, { orientation: orientation, isClickable: isTrackInteractive, css: cssEndingTrack, onClick: function (event) { return onTrackClick(event); }, style: orientation === 'vertical' ? {
|
|
166
166
|
bottom: 0,
|
|
167
|
-
height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
167
|
+
height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
168
168
|
} : {
|
|
169
169
|
right: 0,
|
|
170
|
-
width: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobWidth * .5, "px - ").concat(trackPadding, "px)"),
|
|
170
|
+
width: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobWidth * .5, "px - ").concat(trackPadding, "px)"),
|
|
171
171
|
} })));
|
|
172
172
|
}
|
|
173
173
|
exports.default = Slider;
|
package/lib/Slider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.js","sourceRoot":"/","sources":["Slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position change events are dispatched only when dragging ends. When disabled,\n * aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position.\n *\n * @param position - The current slider position.\n *\n * @returns The label.\n */\n labelProvider?: (position: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * The current position.\n */\n position?: number\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `position` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp\n}\n\n/**\n * A slider component supporting both horizontal and vertical orientations whose sliding position (a\n * decimal between 0.0 and 1.0, inclusive) can be two-way binded. The component consists of four\n * customizable elements: a draggable knob, a label on the knob, a scroll track before the knob and\n * a scroll track after the knob. While the width and height of the slider is inferred from its CSS\n * rules, the width and height of the knob are set via props (`knobWidth` and `knobHeight`,\n * respectively). The size of the knob does not impact the size of the slider.\n */\nexport default function Slider({\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n position: externalPosition = 0,\n labelProvider,\n onDragEnd,\n onDragStart,\n onPositionChange,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number): number {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n function onTrackClick(event: MouseEvent) {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: externalPosition,\n transform,\n onDragStart,\n onDragEnd,\n })\n\n // debug('Rendering...', 'OK')\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging || externalPosition === position) return\n\n debug('Updating drag effect value from position prop...', 'OK', `prop=${externalPosition}, effect=${position}`)\n\n setPosition(externalPosition)\n }, [externalPosition])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, isDragging)\n }, [position])\n\n useEffect(() => {\n if (isDragging || !onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, true)\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging === true,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position)}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };;\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
|
|
1
|
+
{"version":3,"file":"Slider.js","sourceRoot":"/","sources":["Slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position change events are dispatched only when dragging ends. When disabled,\n * aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position.\n *\n * @param position - The current slider position.\n *\n * @returns The label.\n */\n labelProvider?: (position: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * The current position.\n */\n position?: number\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `position` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp\n}\n\n/**\n * A slider component supporting both horizontal and vertical orientations whose sliding position (a\n * decimal between 0.0 and 1.0, inclusive) can be two-way binded. The component consists of four\n * customizable elements: a draggable knob, a label on the knob, a scroll track before the knob and\n * a scroll track after the knob. While the width and height of the slider is inferred from its CSS\n * rules, the width and height of the knob are set via props (`knobWidth` and `knobHeight`,\n * respectively). The size of the knob does not impact the size of the slider.\n */\nexport default function Slider({\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n position: externalPosition = 0,\n labelProvider,\n onDragEnd,\n onDragStart,\n onPositionChange,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number): number {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n function onTrackClick(event: MouseEvent) {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: externalPosition,\n transform,\n onDragStart,\n onDragEnd,\n })\n\n // debug('Rendering...', 'OK')\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging || externalPosition === position) return\n\n debug('Updating drag effect value from position prop...', 'OK', `prop=${externalPosition}, effect=${position}`)\n\n setPosition(externalPosition)\n }, [externalPosition])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, isDragging)\n }, [position])\n\n useEffect(() => {\n if (isDragging || !onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, true)\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging === true,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position)}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };;\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
|
package/lib/StepwiseSlider.js
CHANGED
|
@@ -219,10 +219,10 @@ function StepwiseSlider(_a) {
|
|
|
219
219
|
return (react_1.default.createElement(StyledRoot, __assign({ ref: rootRef, orientation: orientation }, props),
|
|
220
220
|
react_1.default.createElement(StyledStartingTrack, { orientation: orientation, isClickable: isTrackInteractive, css: cssStartingTrack, onClick: function (event) { return onTrackClick(event); }, style: orientation === 'vertical' ? {
|
|
221
221
|
top: 0,
|
|
222
|
-
height: "calc(".concat(naturalPosition * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
222
|
+
height: "calc(".concat(naturalPosition * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
223
223
|
} : {
|
|
224
224
|
left: 0,
|
|
225
|
-
width: "calc(".concat(naturalPosition * 100, "% - ").concat(knobWidth * .5, "px - ").concat(trackPadding, "px)"),
|
|
225
|
+
width: "calc(".concat(naturalPosition * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobWidth * .5, "px - ").concat(trackPadding, "px)"),
|
|
226
226
|
} }),
|
|
227
227
|
react_1.default.createElement(StyledKnobContainer, { ref: knobRef, style: __assign({ transform: 'translate3d(-50%, -50%, 0)' }, (orientation === 'vertical' ? {
|
|
228
228
|
left: '50%',
|
|
@@ -243,10 +243,10 @@ function StepwiseSlider(_a) {
|
|
|
243
243
|
} }, steps && labelProvider && (react_1.default.createElement(StyledLabel, { knobHeight: knobHeight, css: cssLabel }, labelProvider(position, getNearestIndexByPosition(position, steps)))))),
|
|
244
244
|
react_1.default.createElement(StyledEndingTrack, { orientation: orientation, isClickable: isTrackInteractive, css: cssEndingTrack, onClick: function (event) { return onTrackClick(event); }, style: orientation === 'vertical' ? {
|
|
245
245
|
bottom: 0,
|
|
246
|
-
height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
246
|
+
height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
247
247
|
} : {
|
|
248
248
|
right: 0,
|
|
249
|
-
width: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobWidth * .5, "px - ").concat(trackPadding, "px)"),
|
|
249
|
+
width: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobWidth * .5, "px - ").concat(trackPadding, "px)"),
|
|
250
250
|
} })));
|
|
251
251
|
}
|
|
252
252
|
exports.default = StepwiseSlider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepwiseSlider.js","sourceRoot":"/","sources":["StepwiseSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef, useState } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:stepwise-slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position/index change events are dispatched only when dragging ends. When\n * disabled, aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position and closest step\n * index (if steps are provided).\n *\n * @param position - The current slider position.\n * @param index - The nearest step index (if steps are provided), or -1 if no steps are provided.\n *\n * @returns The label.\n */\n labelProvider?: (position: number, index: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * An array of step descriptors. A step is a position (0 - 1 inclusive) on the track where the\n * knob should snap to if dragging stops near it. Ensure that there are at least two steps: one\n * for the start of the track and one for the end.\n */\n steps?: readonly number[]\n\n /**\n * The current index.\n */\n index?: number\n\n /**\n * Handler invoked when index changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right after `onPositionChange`.\n *\n * @param index - The current slider index.\n * @param isDragging - Specifies if the index change is due to dragging.\n */\n onIndexChange?: (index: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right before `onIndexChange`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp<any>\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp<any>\n}\n\n/**\n * Generates a set of steps compatible with this component.\n *\n * @param length - The number of steps. This must be at least 2 because you must include the\n * starting and ending points.\n *\n * @returns An array of steps.\n */\nexport function generateSteps(length: number): readonly number[] {\n if (length <= 1) throw new Error('`length` value must be greater than or equal to 2')\n if (Math.round(length) !== length) throw new Error('`length` value must be an integer')\n\n const interval = 1 / (length - 1)\n\n return Array(length).fill(null).map((v, i) => {\n const position = interval * i\n return position\n })\n}\n\n/**\n * Gets the index of the step of which the specified position is closest to. If for whatever\n * reason the index cannot be computed, -1 is returned.\n *\n * @param position - The position (0 - 1, inclusive).\n * @param steps - The steps.\n *\n * @returns The nearest index.\n */\nfunction getNearestIndexByPosition(position: number, steps: readonly number[]): number {\n let index = -1\n let minDelta = NaN\n\n for (let i = 0, n = steps.length; i < n; i++) {\n const step = getPositionAt(i, steps)\n\n if (isNaN(step)) continue\n\n const delta = Math.abs(position - step)\n\n if (isNaN(minDelta) || (delta < minDelta)) {\n minDelta = delta\n index = i\n }\n }\n\n return index\n}\n\n/**\n * Gets the position by step index. This value ranges between 0 - 1, inclusive.\n *\n * @param index - The step index.\n * @param steps - The steps.\n *\n * @returns The position. If for whatever reason the position cannot be determined, `NaN` is\n * returned.\n */\nfunction getPositionAt(index: number, steps: readonly number[]): number {\n if (index >= steps.length) return NaN\n return steps[index]\n}\n\n/**\n * A \"stepwise\" slider component supporting both horizontal and vertical orientations that\n * automatically snaps to a set of predefined points on the slider when dragged. These points are\n * referred to as \"steps\", indexed by an integer referred to as \"index\". This index can be two-way\n * binded. The component consists of four customizable elements: a draggable knob, a label on the\n * knob, a scroll track before the knob and a scroll track after the knob. While the width and\n * height of the slider is inferred from its CSS rules, the width and height of the knob are set via\n * props (`knobWidth` and `knobHeight`, respectively). The size of the knob does not impact the size\n * of the slider. While dragging, the slider still emits a position change event, where the position\n * is a decimal ranging between 0.0 and 1.0, inclusive.\n */\nexport default function StepwiseSlider({\n id,\n className,\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n labelProvider,\n steps = generateSteps(10),\n index: externalIndex = 0,\n onIndexChange,\n onPositionChange,\n onDragEnd,\n onDragStart,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number) {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n function onTrackClick(event: MouseEvent) {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const [index, setIndex] = useState(externalIndex)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: getPositionAt(externalIndex, steps),\n transform,\n onDragStart,\n onDragEnd,\n })\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging) return\n\n const newPosition = getPositionAt(externalIndex, steps)\n\n if (position !== newPosition) {\n debug('Updating drag effect value from index prop...', 'OK', `prop=${newPosition}, effect=${position}`)\n setPosition(newPosition)\n }\n\n if (externalIndex !== index) {\n setIndex(externalIndex)\n }\n }, [externalIndex])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n\n onPositionChange?.(position, isDragging)\n\n const newIndex = getNearestIndexByPosition(position, steps)\n if (index !== newIndex) setIndex(newIndex)\n }, [position])\n\n useEffect(() => {\n onIndexChange?.(index, isDragging)\n }, [index])\n\n useEffect(() => {\n if (isDragging) return\n\n const nearestIndex = getNearestIndexByPosition(position, steps)\n const nearestPosition = getPositionAt(nearestIndex, steps)\n\n if (nearestPosition !== position || onlyDispatchesOnDragEnd) {\n setPosition(nearestPosition)\n onPositionChange?.(nearestPosition, true)\n }\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {steps && labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position, getNearestIndexByPosition(position, steps))}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n opacity: 1;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
|
|
1
|
+
{"version":3,"file":"StepwiseSlider.js","sourceRoot":"/","sources":["StepwiseSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef, useState } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:stepwise-slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position/index change events are dispatched only when dragging ends. When\n * disabled, aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position and closest step\n * index (if steps are provided).\n *\n * @param position - The current slider position.\n * @param index - The nearest step index (if steps are provided), or -1 if no steps are provided.\n *\n * @returns The label.\n */\n labelProvider?: (position: number, index: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * An array of step descriptors. A step is a position (0 - 1 inclusive) on the track where the\n * knob should snap to if dragging stops near it. Ensure that there are at least two steps: one\n * for the start of the track and one for the end.\n */\n steps?: readonly number[]\n\n /**\n * The current index.\n */\n index?: number\n\n /**\n * Handler invoked when index changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right after `onPositionChange`.\n *\n * @param index - The current slider index.\n * @param isDragging - Specifies if the index change is due to dragging.\n */\n onIndexChange?: (index: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right before `onIndexChange`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp<any>\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp<any>\n}\n\n/**\n * Generates a set of steps compatible with this component.\n *\n * @param length - The number of steps. This must be at least 2 because you must include the\n * starting and ending points.\n *\n * @returns An array of steps.\n */\nexport function generateSteps(length: number): readonly number[] {\n if (length <= 1) throw new Error('`length` value must be greater than or equal to 2')\n if (Math.round(length) !== length) throw new Error('`length` value must be an integer')\n\n const interval = 1 / (length - 1)\n\n return Array(length).fill(null).map((v, i) => {\n const position = interval * i\n return position\n })\n}\n\n/**\n * Gets the index of the step of which the specified position is closest to. If for whatever\n * reason the index cannot be computed, -1 is returned.\n *\n * @param position - The position (0 - 1, inclusive).\n * @param steps - The steps.\n *\n * @returns The nearest index.\n */\nfunction getNearestIndexByPosition(position: number, steps: readonly number[]): number {\n let index = -1\n let minDelta = NaN\n\n for (let i = 0, n = steps.length; i < n; i++) {\n const step = getPositionAt(i, steps)\n\n if (isNaN(step)) continue\n\n const delta = Math.abs(position - step)\n\n if (isNaN(minDelta) || (delta < minDelta)) {\n minDelta = delta\n index = i\n }\n }\n\n return index\n}\n\n/**\n * Gets the position by step index. This value ranges between 0 - 1, inclusive.\n *\n * @param index - The step index.\n * @param steps - The steps.\n *\n * @returns The position. If for whatever reason the position cannot be determined, `NaN` is\n * returned.\n */\nfunction getPositionAt(index: number, steps: readonly number[]): number {\n if (index >= steps.length) return NaN\n return steps[index]\n}\n\n/**\n * A \"stepwise\" slider component supporting both horizontal and vertical orientations that\n * automatically snaps to a set of predefined points on the slider when dragged. These points are\n * referred to as \"steps\", indexed by an integer referred to as \"index\". This index can be two-way\n * binded. The component consists of four customizable elements: a draggable knob, a label on the\n * knob, a scroll track before the knob and a scroll track after the knob. While the width and\n * height of the slider is inferred from its CSS rules, the width and height of the knob are set via\n * props (`knobWidth` and `knobHeight`, respectively). The size of the knob does not impact the size\n * of the slider. While dragging, the slider still emits a position change event, where the position\n * is a decimal ranging between 0.0 and 1.0, inclusive.\n */\nexport default function StepwiseSlider({\n id,\n className,\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n labelProvider,\n steps = generateSteps(10),\n index: externalIndex = 0,\n onIndexChange,\n onPositionChange,\n onDragEnd,\n onDragStart,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number) {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n function onTrackClick(event: MouseEvent) {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const [index, setIndex] = useState(externalIndex)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: getPositionAt(externalIndex, steps),\n transform,\n onDragStart,\n onDragEnd,\n })\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging) return\n\n const newPosition = getPositionAt(externalIndex, steps)\n\n if (position !== newPosition) {\n debug('Updating drag effect value from index prop...', 'OK', `prop=${newPosition}, effect=${position}`)\n setPosition(newPosition)\n }\n\n if (externalIndex !== index) {\n setIndex(externalIndex)\n }\n }, [externalIndex])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n\n onPositionChange?.(position, isDragging)\n\n const newIndex = getNearestIndexByPosition(position, steps)\n if (index !== newIndex) setIndex(newIndex)\n }, [position])\n\n useEffect(() => {\n onIndexChange?.(index, isDragging)\n }, [index])\n\n useEffect(() => {\n if (isDragging) return\n\n const nearestIndex = getNearestIndexByPosition(position, steps)\n const nearestPosition = getPositionAt(nearestIndex, steps)\n\n if (nearestPosition !== position || onlyDispatchesOnDragEnd) {\n setPosition(nearestPosition)\n onPositionChange?.(nearestPosition, true)\n }\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {steps && labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position, getNearestIndexByPosition(position, steps))}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n opacity: 1;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
|