@diana-ui/slider
Advanced tools
Comparing version 0.0.37 to 1.0.0
@@ -0,28 +1,39 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var stepIntervals = [ | ||
{ | ||
value: 100, | ||
step: 1 | ||
}, | ||
{ | ||
value: 500, | ||
step: 5 | ||
}, | ||
{ | ||
value: 1000, | ||
step: 10 | ||
}, | ||
{ | ||
value: 10000, | ||
step: 100 | ||
}, | ||
{ | ||
value: 25000, | ||
step: 250 | ||
}, | ||
{ | ||
value: 50000, | ||
step: 500 | ||
} | ||
{ | ||
value: 100, | ||
step: 1 | ||
}, | ||
{ | ||
value: 500, | ||
step: 5 | ||
}, | ||
{ | ||
value: 1000, | ||
step: 10 | ||
}, | ||
{ | ||
value: 10000, | ||
step: 100 | ||
}, | ||
{ | ||
value: 25000, | ||
step: 250 | ||
}, | ||
{ | ||
value: 50000, | ||
step: 500 | ||
} | ||
]; | ||
var calculateSliderStep = function (value) { var _a; return ((_a = stepIntervals.find(function (interval) { return value < interval.value; })) === null || _a === void 0 ? void 0 : _a.step) || 1000; }; | ||
export default calculateSliderStep; | ||
var calculateSliderStep = function (value) { | ||
var _a; | ||
return ( | ||
((_a = stepIntervals.find(function (interval) { | ||
return value < interval.value; | ||
})) === null || _a === void 0 | ||
? void 0 | ||
: _a.step) || 1000 | ||
); | ||
}; | ||
exports.default = calculateSliderStep; |
@@ -1,2 +0,16 @@ | ||
export { default as Slider } from "./Slider"; | ||
export { default as LockedSlider } from "./LockedSlider"; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Slider_1 = require("./Slider"); | ||
Object.defineProperty(exports, "Slider", { | ||
enumerable: true, | ||
get: function () { | ||
return Slider_1.default; | ||
} | ||
}); | ||
var LockedSlider_1 = require("./LockedSlider"); | ||
Object.defineProperty(exports, "LockedSlider", { | ||
enumerable: true, | ||
get: function () { | ||
return LockedSlider_1.default; | ||
} | ||
}); |
@@ -1,68 +0,172 @@ | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
"use strict"; | ||
var __assign = | ||
(this && this.__assign) || | ||
function () { | ||
__assign = | ||
Object.assign || | ||
function (t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
}; | ||
var __createBinding = | ||
(this && this.__createBinding) || | ||
(Object.create | ||
? function (o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { | ||
enumerable: true, | ||
get: function () { | ||
return m[k]; | ||
} | ||
}); | ||
} | ||
: function (o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
}); | ||
var __setModuleDefault = | ||
(this && this.__setModuleDefault) || | ||
(Object.create | ||
? function (o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
} | ||
: function (o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = | ||
(this && this.__importStar) || | ||
function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) | ||
for (var k in mod) | ||
if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __rest = | ||
(this && this.__rest) || | ||
function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
for (var p in s) | ||
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
import React, { useState, useEffect, useCallback } from "react"; | ||
import { withStyles } from "@diana-ui/base"; | ||
import { Icon } from "@diana-ui/icon"; | ||
import Slider from "./Slider"; | ||
var styleSheet = function (theme) { return ({ | ||
}; | ||
var __importDefault = | ||
(this && this.__importDefault) || | ||
function (mod) { | ||
return mod && mod.__esModule ? mod : { default: mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var react_1 = __importStar(require("react")); | ||
var base_1 = require("@diana-ui/base"); | ||
var icon_1 = require("@diana-ui/icon"); | ||
var Slider_1 = __importDefault(require("./Slider")); | ||
var styleSheet = function (theme) { | ||
return { | ||
lockWrapper: { | ||
position: "relative", | ||
flexDirection: "row", | ||
display: "flex", | ||
alignItems: "center", | ||
flexGrow: 1 | ||
position: "relative", | ||
flexDirection: "row", | ||
display: "flex", | ||
alignItems: "center", | ||
flexGrow: 1 | ||
}, | ||
iconWrapper: { | ||
cursor: "pointer", | ||
marginLeft: theme.spaceUnit.md | ||
cursor: "pointer", | ||
marginLeft: theme.spaceUnit.md | ||
}, | ||
icon: { | ||
"@selectors": { | ||
"&.disabled": { | ||
fill: theme.colors.grey.grey100 | ||
} | ||
"@selectors": { | ||
"&.disabled": { | ||
fill: theme.colors.grey.grey100 | ||
} | ||
} | ||
}, | ||
disabledIcon: {} | ||
}); }; | ||
}; | ||
}; | ||
var LockedSlider = function (_a) { | ||
var cx = _a.cx, styles = _a.styles, onValueChange = _a.onValueChange, onLockChange = _a.onLockChange, locked = _a.locked, _b = _a.lockedIcon, lockedIcon = _b === void 0 ? "locked" : _b, _c = _a.unlockedIcon, unlockedIcon = _c === void 0 ? "unlocked" : _c, _d = _a.className, className = _d === void 0 ? "" : _d, disabled = _a.disabled, props = __rest(_a, ["cx", "styles", "onValueChange", "onLockChange", "locked", "lockedIcon", "unlockedIcon", "className", "disabled"]); | ||
var _e = useState(false), isLocked = _e[0], setIsLocked = _e[1]; | ||
var icon = disabled ? lockedIcon : isLocked ? lockedIcon : unlockedIcon; | ||
useEffect(function () { | ||
if (locked !== undefined) { | ||
setIsLocked(locked); | ||
var cx = _a.cx, | ||
styles = _a.styles, | ||
onValueChange = _a.onValueChange, | ||
onLockChange = _a.onLockChange, | ||
locked = _a.locked, | ||
_b = _a.lockedIcon, | ||
lockedIcon = _b === void 0 ? "locked" : _b, | ||
_c = _a.unlockedIcon, | ||
unlockedIcon = _c === void 0 ? "unlocked" : _c, | ||
_d = _a.className, | ||
className = _d === void 0 ? "" : _d, | ||
disabled = _a.disabled, | ||
props = __rest(_a, [ | ||
"cx", | ||
"styles", | ||
"onValueChange", | ||
"onLockChange", | ||
"locked", | ||
"lockedIcon", | ||
"unlockedIcon", | ||
"className", | ||
"disabled" | ||
]); | ||
var _e = react_1.useState(false), | ||
isLocked = _e[0], | ||
setIsLocked = _e[1]; | ||
var icon = disabled ? lockedIcon : isLocked ? lockedIcon : unlockedIcon; | ||
react_1.useEffect( | ||
function () { | ||
if (locked !== undefined) { | ||
setIsLocked(locked); | ||
} | ||
}, | ||
[locked] | ||
); | ||
var onLockChangeInternal = react_1.useCallback( | ||
function (newValue) { | ||
if (locked === undefined) { | ||
setIsLocked(newValue); | ||
} | ||
return onLockChange === null || onLockChange === void 0 ? void 0 : onLockChange(newValue); | ||
}, | ||
[locked, onLockChange] | ||
); | ||
return react_1.default.createElement( | ||
"div", | ||
{ className: cx("diana-locked-slider", styles.lockWrapper, className) }, | ||
react_1.default.createElement( | ||
Slider_1.default, | ||
__assign( | ||
{ | ||
disabled: isLocked || disabled, | ||
inputClassName: cx(isLocked && !disabled && "locked"), | ||
onValueChange: (!isLocked && onValueChange) || function () {} | ||
}, | ||
props | ||
) | ||
), | ||
react_1.default.createElement( | ||
"div", | ||
{ | ||
className: cx(styles.iconWrapper, disabled && styles.disabledIcon), | ||
onClick: function () { | ||
return onLockChangeInternal(!isLocked); | ||
} | ||
}, [locked]); | ||
var onLockChangeInternal = useCallback(function (newValue) { | ||
if (locked === undefined) { | ||
setIsLocked(newValue); | ||
} | ||
return onLockChange === null || onLockChange === void 0 ? void 0 : onLockChange(newValue); | ||
}, [locked, onLockChange]); | ||
return (React.createElement("div", { className: cx("diana-locked-slider", styles.lockWrapper, className) }, | ||
React.createElement(Slider, __assign({ disabled: isLocked || disabled, inputClassName: cx(isLocked && !disabled && "locked"), onValueChange: (!isLocked && onValueChange) || (function () { }) }, props)), | ||
React.createElement("div", { className: cx(styles.iconWrapper, disabled && styles.disabledIcon), onClick: function () { return onLockChangeInternal(!isLocked); } }, | ||
React.createElement(Icon, { className: cx(styles.icon, disabled && "disabled"), name: icon })))); | ||
}, | ||
react_1.default.createElement(icon_1.Icon, { | ||
className: cx(styles.icon, disabled && "disabled"), | ||
name: icon | ||
}) | ||
) | ||
); | ||
}; | ||
export default withStyles(styleSheet)(LockedSlider); | ||
exports.default = base_1.withStyles(styleSheet)(LockedSlider); |
@@ -1,11 +0,55 @@ | ||
import React, { useState, useEffect, useCallback, useMemo } from "react"; | ||
import { withStyles } from "@diana-ui/base"; | ||
import { useWindowSize } from "@diana-ui/hooks"; | ||
import { Description, Label } from "@diana-ui/typography"; | ||
import calculateSliderStep from "./helpers/calculateSliderStep"; | ||
"use strict"; | ||
var __createBinding = | ||
(this && this.__createBinding) || | ||
(Object.create | ||
? function (o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { | ||
enumerable: true, | ||
get: function () { | ||
return m[k]; | ||
} | ||
}); | ||
} | ||
: function (o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
}); | ||
var __setModuleDefault = | ||
(this && this.__setModuleDefault) || | ||
(Object.create | ||
? function (o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
} | ||
: function (o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = | ||
(this && this.__importStar) || | ||
function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) | ||
for (var k in mod) | ||
if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = | ||
(this && this.__importDefault) || | ||
function (mod) { | ||
return mod && mod.__esModule ? mod : { default: mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var react_1 = __importStar(require("react")); | ||
var base_1 = require("@diana-ui/base"); | ||
var hooks_1 = require("@diana-ui/hooks"); | ||
var typography_1 = require("@diana-ui/typography"); | ||
var calculateSliderStep_1 = __importDefault(require("./helpers/calculateSliderStep")); | ||
var thumbSizes = { | ||
sm: 21, | ||
md: 32 | ||
sm: 21, | ||
md: 32 | ||
}; | ||
var mixinThumbStyle = function (size) { return ({ | ||
var mixinThumbStyle = function (size) { | ||
return { | ||
height: thumbSizes[size], | ||
@@ -15,96 +59,170 @@ width: thumbSizes[size], | ||
marginTop: Math.round(thumbSizes[size] / -2) | ||
}); }; | ||
var styleSheet = function () { return ({ | ||
}; | ||
}; | ||
var styleSheet = function () { | ||
return { | ||
wrapper: {}, | ||
valueWrapper: {}, | ||
input: { | ||
"@selectors": { | ||
"&.disabled::-webkit-slider-thumb": {}, | ||
"&.disabled::-webkit-slider-runnable-track": {} | ||
}, | ||
"&:focus": {}, | ||
"&::-ms-track": {}, | ||
"&::-webkit-slider-runnable-track": {} | ||
"@selectors": { | ||
"&.disabled::-webkit-slider-thumb": {}, | ||
"&.disabled::-webkit-slider-runnable-track": {} | ||
}, | ||
"&:focus": {}, | ||
"&::-ms-track": {}, | ||
"&::-webkit-slider-runnable-track": {} | ||
}, | ||
sm: { | ||
height: thumbSizes.sm, | ||
"&::-webkit-slider-thumb": mixinThumbStyle("sm"), | ||
"&::-moz-range-thumb": mixinThumbStyle("sm"), | ||
"&::-ms-thumb": mixinThumbStyle("sm") | ||
height: thumbSizes.sm, | ||
"&::-webkit-slider-thumb": mixinThumbStyle("sm"), | ||
"&::-moz-range-thumb": mixinThumbStyle("sm"), | ||
"&::-ms-thumb": mixinThumbStyle("sm") | ||
}, | ||
md: { | ||
height: thumbSizes.md, | ||
"&::-webkit-slider-thumb": mixinThumbStyle("md"), | ||
"&::-moz-range-thumb": mixinThumbStyle("md"), | ||
"&::-ms-thumb": mixinThumbStyle("md") | ||
height: thumbSizes.md, | ||
"&::-webkit-slider-thumb": mixinThumbStyle("md"), | ||
"&::-moz-range-thumb": mixinThumbStyle("md"), | ||
"&::-ms-thumb": mixinThumbStyle("md") | ||
}, | ||
value: {} | ||
}); }; | ||
}; | ||
}; | ||
var Slider = function (_a) { | ||
var cx = _a.cx, styles = _a.styles, min = _a.min, max = _a.max, value = _a.value, step = _a.step, onValueChange = _a.onValueChange, _b = _a.disabled, disabled = _b === void 0 ? false : _b, _c = _a.className, className = _c === void 0 ? "" : _c, _d = _a.inputClassName, inputClassName = _d === void 0 ? "" : _d, wrappedRef = _a.wrappedRef; | ||
var width = useWindowSize()[0]; | ||
var isMobile = width <= 700; | ||
var thumbSize = isMobile ? 21 : 32; | ||
var _e = useState(9), leftSpacing = _e[0], setLeftSpacing = _e[1]; | ||
var _f = useState(value || 0), _value = _f[0], setValue = _f[1]; | ||
var ref = React.createRef(); | ||
var calculatedStep = useMemo(function () { return step !== null && step !== void 0 ? step : calculateSliderStep(max); }, [step, max]); | ||
var TextComponent = (isMobile && Label) || Description; | ||
/** | ||
* This function calculates the left space required | ||
* for the label with the value follow the thumb. | ||
* It tries to keep the number where the label is, so it rounds the number to the closest step. | ||
* The formula is as follows: | ||
* | ||
* (max - min) + 13 | ||
* this gives the diference between max and min so we can | ||
* use value 0 as the starting point in case min is higher than 0 | ||
* Having: | ||
* (sizes[size] / 2) + 2 - is the sum of half the thumb plus 2px that | ||
* correspond to slider bar that the thumb don't reach. Basically the | ||
* thumb do not touch the start / end of the bar, and that is 2px | ||
* | ||
* | ||
* this calculates the width of the span that contains the value | ||
* and divides it by 2. This will give us the distance between the | ||
* left corner and the middle on | ||
* having: | ||
* 20px as default size for letter | ||
* (`${max}`.length * 20) / 2 | ||
*/ | ||
var alignToStep = _value % calculatedStep >= calculatedStep / 2 ? calculatedStep : 0; | ||
var calculateLeftSpace = useCallback(function (totalWidth) { | ||
return ((_value - (_value % calculatedStep) + alignToStep) * totalWidth) / (max - min) + | ||
(thumbSize / 2 + 2) - | ||
(("" + max).length * 20) / 2; | ||
}, [alignToStep, _value, calculatedStep, max, min, thumbSize]); | ||
useEffect(function () { | ||
var _a; | ||
setLeftSpacing(calculateLeftSpace( | ||
/** | ||
* if ref ins't defined yet the default is 0 | ||
* in case it exists, at the total width of the input, | ||
* we subtract the thumb value since the thumb do not actually | ||
* hits the end neither the start | ||
* so half from the end + half from the end we get the full with | ||
* of the thumb | ||
*/ | ||
((_a = ref.current) === null || _a === void 0 ? void 0 : _a.clientWidth) ? ref.current.clientWidth - thumbSize : 0)); | ||
}, [ref, min, max, value, calculateLeftSpace, thumbSize]); | ||
useEffect(function () { | ||
if (value !== undefined) { | ||
setValue(value); | ||
} | ||
}, [value]); | ||
var changeValue = useCallback(function (newValue) { | ||
if (value === undefined) { | ||
setValue(newValue); | ||
} | ||
return onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(newValue); | ||
}, [value, onValueChange]); | ||
return (React.createElement("div", { className: cx("diana-slider", styles.wrapper, className), ref: wrappedRef }, | ||
React.createElement("div", { className: cx(styles.valueWrapper) }, | ||
React.createElement(TextComponent, { style: { left: leftSpacing, width: ("" + max).length * 20 }, className: cx(styles.value) }, _value)), | ||
React.createElement("input", { ref: ref, className: cx(styles.input, (isMobile && styles.sm) || styles.md, disabled && "disabled", inputClassName), type: "range", min: min, max: max, value: _value, step: calculatedStep, onChange: function (ev) { return changeValue(Number(ev.currentTarget.value)); }, disabled: disabled }))); | ||
var cx = _a.cx, | ||
styles = _a.styles, | ||
min = _a.min, | ||
max = _a.max, | ||
value = _a.value, | ||
step = _a.step, | ||
onValueChange = _a.onValueChange, | ||
_b = _a.disabled, | ||
disabled = _b === void 0 ? false : _b, | ||
_c = _a.className, | ||
className = _c === void 0 ? "" : _c, | ||
_d = _a.inputClassName, | ||
inputClassName = _d === void 0 ? "" : _d, | ||
wrappedRef = _a.wrappedRef; | ||
var width = hooks_1.useWindowSize()[0]; | ||
var isMobile = width <= 700; | ||
var thumbSize = isMobile ? 21 : 32; | ||
var _e = react_1.useState(9), | ||
leftSpacing = _e[0], | ||
setLeftSpacing = _e[1]; | ||
var _f = react_1.useState(value || 0), | ||
_value = _f[0], | ||
setValue = _f[1]; | ||
var ref = react_1.default.createRef(); | ||
var calculatedStep = react_1.useMemo( | ||
function () { | ||
return step !== null && step !== void 0 ? step : calculateSliderStep_1.default(max); | ||
}, | ||
[step, max] | ||
); | ||
var TextComponent = (isMobile && typography_1.Label) || typography_1.Description; | ||
/** | ||
* This function calculates the left space required | ||
* for the label with the value follow the thumb. | ||
* It tries to keep the number where the label is, so it rounds the number to the closest step. | ||
* The formula is as follows: | ||
* | ||
* (max - min) + 13 | ||
* this gives the diference between max and min so we can | ||
* use value 0 as the starting point in case min is higher than 0 | ||
* Having: | ||
* (sizes[size] / 2) + 2 - is the sum of half the thumb plus 2px that | ||
* correspond to slider bar that the thumb don't reach. Basically the | ||
* thumb do not touch the start / end of the bar, and that is 2px | ||
* | ||
* | ||
* this calculates the width of the span that contains the value | ||
* and divides it by 2. This will give us the distance between the | ||
* left corner and the middle on | ||
* having: | ||
* 20px as default size for letter | ||
* (`${max}`.length * 20) / 2 | ||
*/ | ||
var alignToStep = _value % calculatedStep >= calculatedStep / 2 ? calculatedStep : 0; | ||
var calculateLeftSpace = react_1.useCallback( | ||
function (totalWidth) { | ||
return ( | ||
((_value - (_value % calculatedStep) + alignToStep) * totalWidth) / (max - min) + | ||
(thumbSize / 2 + 2) - | ||
(("" + max).length * 20) / 2 | ||
); | ||
}, | ||
[alignToStep, _value, calculatedStep, max, min, thumbSize] | ||
); | ||
react_1.useEffect( | ||
function () { | ||
var _a; | ||
setLeftSpacing( | ||
calculateLeftSpace( | ||
/** | ||
* if ref ins't defined yet the default is 0 | ||
* in case it exists, at the total width of the input, | ||
* we subtract the thumb value since the thumb do not actually | ||
* hits the end neither the start | ||
* so half from the end + half from the end we get the full with | ||
* of the thumb | ||
*/ | ||
((_a = ref.current) === null || _a === void 0 ? void 0 : _a.clientWidth) | ||
? ref.current.clientWidth - thumbSize | ||
: 0 | ||
) | ||
); | ||
}, | ||
[ref, min, max, value, calculateLeftSpace, thumbSize] | ||
); | ||
react_1.useEffect( | ||
function () { | ||
if (value !== undefined) { | ||
setValue(value); | ||
} | ||
}, | ||
[value] | ||
); | ||
var changeValue = react_1.useCallback( | ||
function (newValue) { | ||
if (value === undefined) { | ||
setValue(newValue); | ||
} | ||
return onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(newValue); | ||
}, | ||
[value, onValueChange] | ||
); | ||
return react_1.default.createElement( | ||
"div", | ||
{ className: cx("diana-slider", styles.wrapper, className), ref: wrappedRef }, | ||
react_1.default.createElement( | ||
"div", | ||
{ className: cx(styles.valueWrapper) }, | ||
react_1.default.createElement( | ||
TextComponent, | ||
{ | ||
style: { left: leftSpacing, width: ("" + max).length * 20 }, | ||
className: cx(styles.value) | ||
}, | ||
_value | ||
) | ||
), | ||
react_1.default.createElement("input", { | ||
ref: ref, | ||
className: cx( | ||
styles.input, | ||
(isMobile && styles.sm) || styles.md, | ||
disabled && "disabled", | ||
inputClassName | ||
), | ||
type: "range", | ||
min: min, | ||
max: max, | ||
value: _value, | ||
step: calculatedStep, | ||
onChange: function (ev) { | ||
return changeValue(Number(ev.currentTarget.value)); | ||
}, | ||
disabled: disabled | ||
}) | ||
); | ||
}; | ||
export default withStyles(styleSheet)(Slider); | ||
exports.default = base_1.withStyles(styleSheet)(Slider); |
const stepIntervals = [ | ||
{ | ||
value: 100, | ||
step: 1 | ||
}, | ||
{ | ||
value: 500, | ||
step: 5 | ||
}, | ||
{ | ||
value: 1000, | ||
step: 10 | ||
}, | ||
{ | ||
value: 10000, | ||
step: 100 | ||
}, | ||
{ | ||
value: 25000, | ||
step: 250 | ||
}, | ||
{ | ||
value: 50000, | ||
step: 500 | ||
} | ||
{ | ||
value: 100, | ||
step: 1 | ||
}, | ||
{ | ||
value: 500, | ||
step: 5 | ||
}, | ||
{ | ||
value: 1000, | ||
step: 10 | ||
}, | ||
{ | ||
value: 10000, | ||
step: 100 | ||
}, | ||
{ | ||
value: 25000, | ||
step: 250 | ||
}, | ||
{ | ||
value: 50000, | ||
step: 500 | ||
} | ||
]; | ||
const calculateSliderStep = (value) => { var _a; return ((_a = stepIntervals.find(interval => value < interval.value)) === null || _a === void 0 ? void 0 : _a.step) || 1000; }; | ||
const calculateSliderStep = value => { | ||
var _a; | ||
return ( | ||
((_a = stepIntervals.find(interval => value < interval.value)) === null || _a === void 0 | ||
? void 0 | ||
: _a.step) || 1000 | ||
); | ||
}; | ||
export default calculateSliderStep; |
@@ -1,12 +0,14 @@ | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var __rest = | ||
(this && this.__rest) || | ||
function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
for (var p in s) | ||
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
}; | ||
import React, { useState, useEffect, useCallback } from "react"; | ||
@@ -17,42 +19,85 @@ import { withStyles } from "@diana-ui/base"; | ||
const styleSheet = theme => ({ | ||
lockWrapper: { | ||
position: "relative", | ||
flexDirection: "row", | ||
display: "flex", | ||
alignItems: "center", | ||
flexGrow: 1 | ||
lockWrapper: { | ||
position: "relative", | ||
flexDirection: "row", | ||
display: "flex", | ||
alignItems: "center", | ||
flexGrow: 1 | ||
}, | ||
iconWrapper: { | ||
cursor: "pointer", | ||
marginLeft: theme.spaceUnit.md | ||
}, | ||
icon: { | ||
"@selectors": { | ||
"&.disabled": { | ||
fill: theme.colors.grey.grey100 | ||
} | ||
} | ||
}, | ||
disabledIcon: {} | ||
}); | ||
const LockedSlider = _a => { | ||
var { | ||
cx, | ||
styles, | ||
onValueChange, | ||
onLockChange, | ||
locked, | ||
lockedIcon = "locked", | ||
unlockedIcon = "unlocked", | ||
className = "", | ||
disabled | ||
} = _a, | ||
props = __rest(_a, [ | ||
"cx", | ||
"styles", | ||
"onValueChange", | ||
"onLockChange", | ||
"locked", | ||
"lockedIcon", | ||
"unlockedIcon", | ||
"className", | ||
"disabled" | ||
]); | ||
const [isLocked, setIsLocked] = useState(false); | ||
const icon = disabled ? lockedIcon : isLocked ? lockedIcon : unlockedIcon; | ||
useEffect(() => { | ||
if (locked !== undefined) { | ||
setIsLocked(locked); | ||
} | ||
}, [locked]); | ||
const onLockChangeInternal = useCallback( | ||
newValue => { | ||
if (locked === undefined) { | ||
setIsLocked(newValue); | ||
} | ||
return onLockChange === null || onLockChange === void 0 ? void 0 : onLockChange(newValue); | ||
}, | ||
iconWrapper: { | ||
cursor: "pointer", | ||
marginLeft: theme.spaceUnit.md | ||
}, | ||
icon: { | ||
"@selectors": { | ||
"&.disabled": { | ||
fill: theme.colors.grey.grey100 | ||
} | ||
} | ||
}, | ||
disabledIcon: {} | ||
}); | ||
const LockedSlider = (_a) => { | ||
var { cx, styles, onValueChange, onLockChange, locked, lockedIcon = "locked", unlockedIcon = "unlocked", className = "", disabled } = _a, props = __rest(_a, ["cx", "styles", "onValueChange", "onLockChange", "locked", "lockedIcon", "unlockedIcon", "className", "disabled"]); | ||
const [isLocked, setIsLocked] = useState(false); | ||
const icon = disabled ? lockedIcon : isLocked ? lockedIcon : unlockedIcon; | ||
useEffect(() => { | ||
if (locked !== undefined) { | ||
setIsLocked(locked); | ||
} | ||
}, [locked]); | ||
const onLockChangeInternal = useCallback(newValue => { | ||
if (locked === undefined) { | ||
setIsLocked(newValue); | ||
} | ||
return onLockChange === null || onLockChange === void 0 ? void 0 : onLockChange(newValue); | ||
}, [locked, onLockChange]); | ||
return (React.createElement("div", { className: cx("diana-locked-slider", styles.lockWrapper, className) }, | ||
React.createElement(Slider, Object.assign({ disabled: isLocked || disabled, inputClassName: cx(isLocked && !disabled && "locked"), onValueChange: (!isLocked && onValueChange) || (() => { }) }, props)), | ||
React.createElement("div", { className: cx(styles.iconWrapper, disabled && styles.disabledIcon), onClick: () => onLockChangeInternal(!isLocked) }, | ||
React.createElement(Icon, { className: cx(styles.icon, disabled && "disabled"), name: icon })))); | ||
[locked, onLockChange] | ||
); | ||
return React.createElement( | ||
"div", | ||
{ className: cx("diana-locked-slider", styles.lockWrapper, className) }, | ||
React.createElement( | ||
Slider, | ||
Object.assign( | ||
{ | ||
disabled: isLocked || disabled, | ||
inputClassName: cx(isLocked && !disabled && "locked"), | ||
onValueChange: (!isLocked && onValueChange) || (() => {}) | ||
}, | ||
props | ||
) | ||
), | ||
React.createElement( | ||
"div", | ||
{ | ||
className: cx(styles.iconWrapper, disabled && styles.disabledIcon), | ||
onClick: () => onLockChangeInternal(!isLocked) | ||
}, | ||
React.createElement(Icon, { className: cx(styles.icon, disabled && "disabled"), name: icon }) | ||
) | ||
); | ||
}; | ||
export default withStyles(styleSheet)(LockedSlider); |
@@ -7,75 +7,95 @@ import React, { useState, useEffect, useCallback, useMemo } from "react"; | ||
const thumbSizes = { | ||
sm: 21, | ||
md: 32 | ||
sm: 21, | ||
md: 32 | ||
}; | ||
const mixinThumbStyle = (size) => ({ | ||
height: thumbSizes[size], | ||
width: thumbSizes[size], | ||
backgroundSize: `${thumbSizes[size]}px ${thumbSizes[size]}px`, | ||
marginTop: Math.round(thumbSizes[size] / -2) | ||
const mixinThumbStyle = size => ({ | ||
height: thumbSizes[size], | ||
width: thumbSizes[size], | ||
backgroundSize: `${thumbSizes[size]}px ${thumbSizes[size]}px`, | ||
marginTop: Math.round(thumbSizes[size] / -2) | ||
}); | ||
const styleSheet = () => ({ | ||
wrapper: {}, | ||
valueWrapper: {}, | ||
input: { | ||
"@selectors": { | ||
"&.disabled::-webkit-slider-thumb": {}, | ||
"&.disabled::-webkit-slider-runnable-track": {} | ||
}, | ||
"&:focus": {}, | ||
"&::-ms-track": {}, | ||
"&::-webkit-slider-runnable-track": {} | ||
wrapper: {}, | ||
valueWrapper: {}, | ||
input: { | ||
"@selectors": { | ||
"&.disabled::-webkit-slider-thumb": {}, | ||
"&.disabled::-webkit-slider-runnable-track": {} | ||
}, | ||
sm: { | ||
height: thumbSizes.sm, | ||
"&::-webkit-slider-thumb": mixinThumbStyle("sm"), | ||
"&::-moz-range-thumb": mixinThumbStyle("sm"), | ||
"&::-ms-thumb": mixinThumbStyle("sm") | ||
}, | ||
md: { | ||
height: thumbSizes.md, | ||
"&::-webkit-slider-thumb": mixinThumbStyle("md"), | ||
"&::-moz-range-thumb": mixinThumbStyle("md"), | ||
"&::-ms-thumb": mixinThumbStyle("md") | ||
}, | ||
value: {} | ||
"&:focus": {}, | ||
"&::-ms-track": {}, | ||
"&::-webkit-slider-runnable-track": {} | ||
}, | ||
sm: { | ||
height: thumbSizes.sm, | ||
"&::-webkit-slider-thumb": mixinThumbStyle("sm"), | ||
"&::-moz-range-thumb": mixinThumbStyle("sm"), | ||
"&::-ms-thumb": mixinThumbStyle("sm") | ||
}, | ||
md: { | ||
height: thumbSizes.md, | ||
"&::-webkit-slider-thumb": mixinThumbStyle("md"), | ||
"&::-moz-range-thumb": mixinThumbStyle("md"), | ||
"&::-ms-thumb": mixinThumbStyle("md") | ||
}, | ||
value: {} | ||
}); | ||
const Slider = ({ cx, styles, min, max, value, step, onValueChange, disabled = false, className = "", inputClassName = "", wrappedRef }) => { | ||
const [width] = useWindowSize(); | ||
const isMobile = width <= 700; | ||
const thumbSize = isMobile ? 21 : 32; | ||
const [leftSpacing, setLeftSpacing] = useState(9); | ||
const [_value, setValue] = useState(value || 0); | ||
const ref = React.createRef(); | ||
const calculatedStep = useMemo(() => step !== null && step !== void 0 ? step : calculateSliderStep(max), [step, max]); | ||
const TextComponent = (isMobile && Label) || Description; | ||
/** | ||
* This function calculates the left space required | ||
* for the label with the value follow the thumb. | ||
* It tries to keep the number where the label is, so it rounds the number to the closest step. | ||
* The formula is as follows: | ||
* | ||
* (max - min) + 13 | ||
* this gives the diference between max and min so we can | ||
* use value 0 as the starting point in case min is higher than 0 | ||
* Having: | ||
* (sizes[size] / 2) + 2 - is the sum of half the thumb plus 2px that | ||
* correspond to slider bar that the thumb don't reach. Basically the | ||
* thumb do not touch the start / end of the bar, and that is 2px | ||
* | ||
* | ||
* this calculates the width of the span that contains the value | ||
* and divides it by 2. This will give us the distance between the | ||
* left corner and the middle on | ||
* having: | ||
* 20px as default size for letter | ||
* (`${max}`.length * 20) / 2 | ||
*/ | ||
const alignToStep = _value % calculatedStep >= calculatedStep / 2 ? calculatedStep : 0; | ||
const calculateLeftSpace = useCallback(totalWidth => ((_value - (_value % calculatedStep) + alignToStep) * totalWidth) / (max - min) + | ||
(thumbSize / 2 + 2) - | ||
(`${max}`.length * 20) / 2, [alignToStep, _value, calculatedStep, max, min, thumbSize]); | ||
useEffect(() => { | ||
var _a; | ||
setLeftSpacing(calculateLeftSpace( | ||
const Slider = ({ | ||
cx, | ||
styles, | ||
min, | ||
max, | ||
value, | ||
step, | ||
onValueChange, | ||
disabled = false, | ||
className = "", | ||
inputClassName = "", | ||
wrappedRef | ||
}) => { | ||
const [width] = useWindowSize(); | ||
const isMobile = width <= 700; | ||
const thumbSize = isMobile ? 21 : 32; | ||
const [leftSpacing, setLeftSpacing] = useState(9); | ||
const [_value, setValue] = useState(value || 0); | ||
const ref = React.createRef(); | ||
const calculatedStep = useMemo( | ||
() => (step !== null && step !== void 0 ? step : calculateSliderStep(max)), | ||
[step, max] | ||
); | ||
const TextComponent = (isMobile && Label) || Description; | ||
/** | ||
* This function calculates the left space required | ||
* for the label with the value follow the thumb. | ||
* It tries to keep the number where the label is, so it rounds the number to the closest step. | ||
* The formula is as follows: | ||
* | ||
* (max - min) + 13 | ||
* this gives the diference between max and min so we can | ||
* use value 0 as the starting point in case min is higher than 0 | ||
* Having: | ||
* (sizes[size] / 2) + 2 - is the sum of half the thumb plus 2px that | ||
* correspond to slider bar that the thumb don't reach. Basically the | ||
* thumb do not touch the start / end of the bar, and that is 2px | ||
* | ||
* | ||
* this calculates the width of the span that contains the value | ||
* and divides it by 2. This will give us the distance between the | ||
* left corner and the middle on | ||
* having: | ||
* 20px as default size for letter | ||
* (`${max}`.length * 20) / 2 | ||
*/ | ||
const alignToStep = _value % calculatedStep >= calculatedStep / 2 ? calculatedStep : 0; | ||
const calculateLeftSpace = useCallback( | ||
totalWidth => | ||
((_value - (_value % calculatedStep) + alignToStep) * totalWidth) / (max - min) + | ||
(thumbSize / 2 + 2) - | ||
(`${max}`.length * 20) / 2, | ||
[alignToStep, _value, calculatedStep, max, min, thumbSize] | ||
); | ||
useEffect(() => { | ||
var _a; | ||
setLeftSpacing( | ||
calculateLeftSpace( | ||
/** | ||
@@ -89,20 +109,52 @@ * if ref ins't defined yet the default is 0 | ||
*/ | ||
((_a = ref.current) === null || _a === void 0 ? void 0 : _a.clientWidth) ? ref.current.clientWidth - thumbSize : 0)); | ||
}, [ref, min, max, value, calculateLeftSpace, thumbSize]); | ||
useEffect(() => { | ||
if (value !== undefined) { | ||
setValue(value); | ||
} | ||
}, [value]); | ||
const changeValue = useCallback(newValue => { | ||
if (value === undefined) { | ||
setValue(newValue); | ||
} | ||
return onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(newValue); | ||
}, [value, onValueChange]); | ||
return (React.createElement("div", { className: cx("diana-slider", styles.wrapper, className), ref: wrappedRef }, | ||
React.createElement("div", { className: cx(styles.valueWrapper) }, | ||
React.createElement(TextComponent, { style: { left: leftSpacing, width: `${max}`.length * 20 }, className: cx(styles.value) }, _value)), | ||
React.createElement("input", { ref: ref, className: cx(styles.input, (isMobile && styles.sm) || styles.md, disabled && "disabled", inputClassName), type: "range", min: min, max: max, value: _value, step: calculatedStep, onChange: ev => changeValue(Number(ev.currentTarget.value)), disabled: disabled }))); | ||
((_a = ref.current) === null || _a === void 0 ? void 0 : _a.clientWidth) | ||
? ref.current.clientWidth - thumbSize | ||
: 0 | ||
) | ||
); | ||
}, [ref, min, max, value, calculateLeftSpace, thumbSize]); | ||
useEffect(() => { | ||
if (value !== undefined) { | ||
setValue(value); | ||
} | ||
}, [value]); | ||
const changeValue = useCallback( | ||
newValue => { | ||
if (value === undefined) { | ||
setValue(newValue); | ||
} | ||
return onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(newValue); | ||
}, | ||
[value, onValueChange] | ||
); | ||
return React.createElement( | ||
"div", | ||
{ className: cx("diana-slider", styles.wrapper, className), ref: wrappedRef }, | ||
React.createElement( | ||
"div", | ||
{ className: cx(styles.valueWrapper) }, | ||
React.createElement( | ||
TextComponent, | ||
{ style: { left: leftSpacing, width: `${max}`.length * 20 }, className: cx(styles.value) }, | ||
_value | ||
) | ||
), | ||
React.createElement("input", { | ||
ref: ref, | ||
className: cx( | ||
styles.input, | ||
(isMobile && styles.sm) || styles.md, | ||
disabled && "disabled", | ||
inputClassName | ||
), | ||
type: "range", | ||
min: min, | ||
max: max, | ||
value: _value, | ||
step: calculatedStep, | ||
onChange: ev => changeValue(Number(ev.currentTarget.value)), | ||
disabled: disabled | ||
}) | ||
); | ||
}; | ||
export default withStyles(styleSheet)(Slider); |
{ | ||
"name": "@diana-ui/slider", | ||
"version": "0.0.37", | ||
"version": "1.0.0", | ||
"main": "lib/index.js", | ||
@@ -13,3 +13,3 @@ "module": "module/index.js", | ||
"build": "yarn compile:lib && yarn compile:module", | ||
"compile:lib": "tsc --target es5 --module es2015 --outDir lib", | ||
"compile:lib": "tsc --target es5 --module commonjs --outDir lib", | ||
"compile:module": "tsc --target es6 --module esnext --outDir module", | ||
@@ -21,7 +21,7 @@ "clean:files": "rimraf lib module", | ||
"dependencies": { | ||
"@diana-ui/base": "^0.1.20", | ||
"@diana-ui/hooks": "^0.1.31", | ||
"@diana-ui/icon": "^0.2.14", | ||
"@diana-ui/types": "^0.1.14", | ||
"@diana-ui/typography": "^0.1.20" | ||
"@diana-ui/base": "^1.0.0", | ||
"@diana-ui/hooks": "^1.0.0", | ||
"@diana-ui/icon": "^1.0.0", | ||
"@diana-ui/types": "^1.0.0", | ||
"@diana-ui/typography": "^1.0.0" | ||
}, | ||
@@ -48,3 +48,3 @@ "peerDependencies": { | ||
}, | ||
"gitHead": "a485bce785e7f55d945c4d79c956f8e6f8175e33" | ||
"gitHead": "96283efce9c7a9b888d256272a2d002ad86b9a35" | ||
} |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
26972
901
1
+ Added@diana-ui/assets@1.0.1(transitive)
+ Added@diana-ui/base@1.0.2(transitive)
+ Added@diana-ui/hooks@1.0.3(transitive)
+ Added@diana-ui/icon@1.0.2(transitive)
+ Added@diana-ui/tokens@1.0.2(transitive)
+ Added@diana-ui/types@1.0.2(transitive)
+ Added@diana-ui/typography@1.0.2(transitive)
- Removed@diana-ui/assets@0.0.8(transitive)
- Removed@diana-ui/base@0.1.20(transitive)
- Removed@diana-ui/hooks@0.1.31(transitive)
- Removed@diana-ui/icon@0.2.14(transitive)
- Removed@diana-ui/tokens@0.1.10(transitive)
- Removed@diana-ui/types@0.1.14(transitive)
- Removed@diana-ui/typography@0.1.20(transitive)
Updated@diana-ui/base@^1.0.0
Updated@diana-ui/hooks@^1.0.0
Updated@diana-ui/icon@^1.0.0
Updated@diana-ui/types@^1.0.0
Updated@diana-ui/typography@^1.0.0