@homecode/ui 5.1.12 → 5.1.15
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.
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import cn from 'classnames';
|
|
3
3
|
import { useRef, useState, useCallback } from 'react';
|
|
4
|
+
import { Tooltip } from '../Tooltip/Tooltip.js';
|
|
4
5
|
import S from './Slider.styl.js';
|
|
5
6
|
|
|
6
7
|
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
7
|
-
|
|
8
|
+
const valueToPct = (value, min, max) => {
|
|
9
|
+
const range = max - min;
|
|
10
|
+
return range > 0 ? `${((value - min) / range) * 100}%` : '0%';
|
|
11
|
+
};
|
|
12
|
+
function Slider({ className, label, value, min = 0, max = 100, step, size = 'm', disabled = false, showGhost = false, markers, markerClassName, onMarkerClick, onChange, onInput, markerTooltipProps = {}, ...inputProps }) {
|
|
8
13
|
const trackWrapRef = useRef(null);
|
|
9
14
|
const [ghostRatio, setGhostRatio] = useState(null);
|
|
10
|
-
const
|
|
11
|
-
const progressPct = range > 0 ? `${((value - min) / range) * 100}%` : '0%';
|
|
15
|
+
const progressPct = valueToPct(value, min, max);
|
|
12
16
|
const updateGhostFromPointer = useCallback((clientX) => {
|
|
13
17
|
if (disabled || !showGhost)
|
|
14
18
|
return;
|
|
@@ -22,10 +26,19 @@ function Slider({ className, label, value, min = 0, max = 100, step, size = 'm',
|
|
|
22
26
|
}, [disabled, showGhost]);
|
|
23
27
|
const clearGhost = useCallback(() => setGhostRatio(null), []);
|
|
24
28
|
const classes = cn(S.root, S[`size-${size}`], disabled && S.disabled, label && S.hasLabel, className);
|
|
25
|
-
return (jsxs("div", { className: classes, children: [label ? jsx("span", { className: S.label, children: label }) : null, jsxs("div", { ref: trackWrapRef, className: S.trackWrap, onPointerEnter: showGhost ? e => updateGhostFromPointer(e.clientX) : undefined, onPointerMove: showGhost ? e => updateGhostFromPointer(e.clientX) : undefined, onPointerLeave: showGhost ? clearGhost : undefined, children: [jsx("input", { type: "range", className: S.control, style: { '--progress': progressPct }, value: value, min: min, max: max, step: step, disabled: disabled, onInput: e => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
return (jsxs("div", { className: classes, children: [label ? jsx("span", { className: S.label, children: label }) : null, jsxs("div", { ref: trackWrapRef, className: cn(S.trackWrap, markers?.length ? S.hasMarkers : null), onPointerEnter: showGhost ? e => updateGhostFromPointer(e.clientX) : undefined, onPointerMove: showGhost ? e => updateGhostFromPointer(e.clientX) : undefined, onPointerLeave: showGhost ? clearGhost : undefined, children: [jsxs("div", { className: S.trackRow, children: [jsx("input", { type: "range", className: S.control, style: { '--progress': progressPct }, value: value, min: min, max: max, step: step, disabled: disabled, onInput: e => {
|
|
30
|
+
onInput?.(e);
|
|
31
|
+
onChange?.(Number(e.currentTarget.value), e);
|
|
32
|
+
}, ...inputProps }), showGhost && ghostRatio !== null && !disabled ? (jsx("span", { className: S.ghost, style: { left: `${ghostRatio * 100}%` }, "aria-hidden": true })) : null] }), markers?.length ? (jsx("div", { className: S.markersRow, children: markers.map((marker, index) => {
|
|
33
|
+
const markerButton = (jsx("button", { type: "button", className: cn(S.marker, markerClassName), "aria-label": typeof marker.label === 'string' ? marker.label : undefined, disabled: disabled, onPointerDown: e => {
|
|
34
|
+
e.stopPropagation();
|
|
35
|
+
}, onClick: e => {
|
|
36
|
+
e.stopPropagation();
|
|
37
|
+
if (!disabled)
|
|
38
|
+
onMarkerClick?.(marker.value);
|
|
39
|
+
} }));
|
|
40
|
+
return (jsx("span", { className: S.markerWrap, style: { left: valueToPct(marker.value, min, max) }, children: marker.label ? (jsx(Tooltip, { direction: "bottom", ...markerTooltipProps, content: marker.label, children: markerButton })) : (markerButton) }, marker.key ?? index));
|
|
41
|
+
}) })) : null] })] }));
|
|
29
42
|
}
|
|
30
43
|
|
|
31
44
|
export { Slider };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".Slider_root__hLZtd{color:var(--accent-color);position:relative;width:100%}.Slider_disabled__jz0lx{opacity:.4;pointer-events:none}.Slider_disabled__jz0lx .Slider_control__vtxup[disabled]{opacity:1}.Slider_hasLabel__Epyqi{align-items:center;display:flex;gap:var(--p-2)}.Slider_label__Gi7GI{color:inherit;font-size:inherit;white-space:nowrap}.Slider_trackWrap__PX861{align-items:center;display:flex;
|
|
4
|
-
var S = {"root":"Slider_root__hLZtd","disabled":"Slider_disabled__jz0lx","control":"Slider_control__vtxup","hasLabel":"Slider_hasLabel__Epyqi","label":"Slider_label__Gi7GI","trackWrap":"Slider_trackWrap__PX861","ghost":"Slider_ghost__tfPtm","size-xs":"Slider_size-xs__v6UDK","size-s":"Slider_size-s__8hGSO","size-m":"Slider_size-m__Dj7LT","size-l":"Slider_size-l__Qi6tI","size-xl":"Slider_size-xl__85Gcz"};
|
|
3
|
+
var css_248z = ".Slider_root__hLZtd{color:var(--accent-color);position:relative;width:100%}.Slider_disabled__jz0lx{opacity:.4;pointer-events:none}.Slider_disabled__jz0lx .Slider_control__vtxup[disabled]{opacity:1}.Slider_hasLabel__Epyqi{align-items:center;display:flex;gap:var(--p-2)}.Slider_label__Gi7GI{color:inherit;font-size:inherit;white-space:nowrap}.Slider_trackWrap__PX861{display:flex;flex:1;flex-direction:column;min-width:0;position:relative}.Slider_hasMarkers__YfnMG{gap:var(--p-1)}.Slider_trackRow__hbQdR{align-items:center;display:flex;position:relative;width:100%}.Slider_markersRow__l-yga{flex-shrink:0;height:var(--marker-size);position:relative;width:100%}.Slider_markerWrap__6hLJN{pointer-events:auto;position:absolute;top:50%;transform:translate(-50%,-50%)}.Slider_marker__vtOv9{background:var(--accent-color);border:none;border-radius:50%;box-shadow:0 0 0 1px var(--decent-color-alpha-800);cursor:pointer;display:block;height:var(--marker-size);margin:0;padding:0;width:var(--marker-size)}.Slider_marker__vtOv9:hover{background:var(--active-color)}.Slider_marker__vtOv9:disabled{cursor:default;opacity:.5}.Slider_control__vtxup{--track-radius:50px;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;box-shadow:inset 0 0 0 2px none;box-sizing:border-box;cursor:pointer;height:var(--thumb-size);margin:0;padding:0;position:relative;transition:.2s ease-out;transition-property:background-color,box-shadow,opacity;width:100%;z-index:2}.Slider_control__vtxup:focus,.Slider_control__vtxup:hover{background-color:var(--active-color-alpha-100)}.Slider_control__vtxup[disabled]{background-color:var(--accent-color-alpha-100);opacity:.4;pointer-events:none}.Slider_control__vtxup:focus,.Slider_control__vtxup:hover{background:transparent!important}.Slider_control__vtxup:focus{box-shadow:inset 0 0 0 2px none}.Slider_control__vtxup::-webkit-slider-runnable-track{background:linear-gradient(to right,var(--active-color) 0,var(--active-color) var(--progress),var(--accent-color-alpha-100) var(--progress),var(--accent-color-alpha-100) 100%);border-radius:var(--track-radius);height:var(--track-height)}.Slider_control__vtxup::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background:var(--active-color);border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.2);cursor:pointer;height:var(--thumb-size);margin-top:calc((var(--track-height) - var(--thumb-size))/2);width:var(--thumb-size)}.Slider_control__vtxup::-moz-range-track{background:var(--accent-color-alpha-100);border-radius:var(--track-radius);height:var(--track-height)}.Slider_control__vtxup::-moz-range-progress{background:var(--active-color);border-radius:var(--track-radius);height:var(--track-height)}.Slider_control__vtxup::-moz-range-thumb{background:var(--active-color);border:none;border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.2);cursor:pointer;height:var(--thumb-size);width:var(--thumb-size)}.Slider_ghost__tfPtm{background:var(--accent-color);border-radius:50%;height:var(--ghost-size);left:0;opacity:.45;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);width:var(--ghost-size);z-index:2}.Slider_size-xs__v6UDK{--track-height:1px;--thumb-size:10px;--ghost-size:10px;--marker-size:6px;font-size:12px}.Slider_size-s__8hGSO{--track-height:2px;--thumb-size:12px;--ghost-size:12px;--marker-size:7px;font-size:14px}.Slider_size-m__Dj7LT{--track-height:8px;--thumb-size:16px;--ghost-size:16px;--marker-size:8px;font-size:16px}.Slider_size-l__Qi6tI{--track-height:12px;--thumb-size:20px;--ghost-size:20px;--marker-size:10px;font-size:18px}.Slider_size-xl__85Gcz{--track-height:16px;--thumb-size:24px;--ghost-size:24px;--marker-size:12px;font-size:20px}";
|
|
4
|
+
var S = {"root":"Slider_root__hLZtd","disabled":"Slider_disabled__jz0lx","control":"Slider_control__vtxup","hasLabel":"Slider_hasLabel__Epyqi","label":"Slider_label__Gi7GI","trackWrap":"Slider_trackWrap__PX861","hasMarkers":"Slider_hasMarkers__YfnMG","trackRow":"Slider_trackRow__hbQdR","markersRow":"Slider_markersRow__l-yga","markerWrap":"Slider_markerWrap__6hLJN","marker":"Slider_marker__vtOv9","ghost":"Slider_ghost__tfPtm","size-xs":"Slider_size-xs__v6UDK","size-s":"Slider_size-s__8hGSO","size-m":"Slider_size-m__Dj7LT","size-l":"Slider_size-l__Qi6tI","size-xl":"Slider_size-xl__85Gcz"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { S as default };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import * as T from './Slider.types';
|
|
2
2
|
export type SliderProps = T.Props;
|
|
3
|
-
export
|
|
3
|
+
export type SliderMarker = T.SliderMarker;
|
|
4
|
+
export declare function Slider({ className, label, value, min, max, step, size, disabled, showGhost, markers, markerClassName, onMarkerClick, onChange, onInput, markerTooltipProps, ...inputProps }: SliderProps): JSX.Element;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { ReactNode, ChangeEvent, FormEvent, InputHTMLAttributes } from 'react';
|
|
2
2
|
import { Size, ComponentType } from '../../types';
|
|
3
|
+
import { TooltipProps } from 'uilib';
|
|
4
|
+
export type SliderMarker = {
|
|
5
|
+
key?: string;
|
|
6
|
+
value: number;
|
|
7
|
+
label?: ReactNode;
|
|
8
|
+
};
|
|
3
9
|
export type Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size' | 'onChange' | 'value'> & ComponentType & {
|
|
4
10
|
value: number;
|
|
5
11
|
min?: number;
|
|
@@ -9,5 +15,9 @@ export type Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'
|
|
|
9
15
|
disabled?: boolean;
|
|
10
16
|
showGhost?: boolean;
|
|
11
17
|
label?: ReactNode;
|
|
18
|
+
markers?: SliderMarker[];
|
|
19
|
+
markerClassName?: string;
|
|
20
|
+
markerTooltipProps?: Partial<TooltipProps>;
|
|
21
|
+
onMarkerClick?: (value: number) => void;
|
|
12
22
|
onChange?: (value: number, e: ChangeEvent<HTMLInputElement> | FormEvent<HTMLInputElement>) => void;
|
|
13
23
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homecode/ui",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.15",
|
|
4
4
|
"description": "React UI components library",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"tests": "jest",
|
|
@@ -140,5 +140,6 @@
|
|
|
140
140
|
"webpack-cli": "^5.0.1",
|
|
141
141
|
"webpack-dev-server": "^4.11.1",
|
|
142
142
|
"webpack-merge": "^5.8.0"
|
|
143
|
-
}
|
|
143
|
+
},
|
|
144
|
+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
|
144
145
|
}
|