@onesy/ui-react
Version:
UI for React
367 lines (360 loc) • 18.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _utils = require("@onesy/utils");
var _styleReact = require("@onesy/style-react");
var _IconMaterialGradeW = _interopRequireDefault(require("@onesy/icons-material-rounded-react/IconMaterialGradeW100"));
var _IconMaterialGradeW100Filled = _interopRequireDefault(require("@onesy/icons-material-rounded-react/IconMaterialGradeW100Filled"));
var _utils2 = require("../utils");
var _jsxRuntime = require("react/jsx-runtime");
const _excluded = ["ref", "tonal", "color", "colorInactive", "size", "value", "valueDefault", "valueActive", "valueActiveDefault", "onChange", "onChangeActive", "values", "precision", "onlyValue", "readOnly", "disabled", "icon", "icons", "iconInactive", "iconActive", "IconProps", "IconActiveProps", "IconInactiveProps", "Component", "className", "children"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
const useStyle = (0, _styleReact.style)(theme => ({
root: {
display: 'inline-flex',
alignItems: 'flex-start',
cursor: 'pointer',
touchAction: 'none'
},
iconWrapper: {
display: 'inline-flex',
position: 'relative',
transition: theme.methods.transitions.make('transform', {
duration: 'xs'
}),
'&:hover': {
transform: 'scale(1.14)'
}
},
iconWrapper_readOnly: {
'&:hover': {
transform: 'none'
}
},
icon: {
display: 'inline-flex'
},
active: {
display: 'inline-flex',
position: 'absolute',
inset: '0',
overflow: 'hidden',
height: '100%',
width: '0px'
},
inactive: {
opacity: theme.palette.light ? '0.24' : '0.4'
},
focus_outline: {
outline: `1px solid ${theme.palette.text.default.secondary}`
},
readOnly: {
cursor: 'default'
},
disabled: {
opacity: theme.palette.visual_contrast.default.opacity.disabled,
cursor: 'default'
}
}), {
name: 'onesy-Rating'
});
const Rating = props_ => {
var _theme$ui, _theme$ui2, _String$split$;
const theme = (0, _styleReact.useOnesyTheme)();
const props = _objectSpread(_objectSpread(_objectSpread({}, theme === null || theme === void 0 || (_theme$ui = theme.ui) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.elements) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.all) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.props) === null || _theme$ui === void 0 ? void 0 : _theme$ui.default), theme === null || theme === void 0 || (_theme$ui2 = theme.ui) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.elements) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.onesyRating) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.props) === null || _theme$ui2 === void 0 ? void 0 : _theme$ui2.default), props_);
const {
ref,
tonal = true,
color = 'primary',
colorInactive = 'default',
size = 'regular',
value: value_,
valueDefault,
valueActive: valueActive_,
valueActiveDefault,
onChange,
onChangeActive,
values = 5,
precision = 1,
onlyValue,
readOnly,
disabled,
icon,
icons,
iconInactive = /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconMaterialGradeW.default, {}),
iconActive = /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconMaterialGradeW100Filled.default, {}),
IconProps,
IconActiveProps,
IconInactiveProps,
Component = 'span',
className,
children
} = props,
other = (0, _objectWithoutProperties2.default)(props, _excluded);
const {
classes
} = useStyle();
const [init, setInit] = _react.default.useState(false);
const [value, setValue] = _react.default.useState(valueDefault !== undefined ? valueDefault : value_);
const [valueActive, setValueActive] = _react.default.useState(valueActiveDefault !== undefined ? valueActiveDefault : valueActive_);
const [hover, setHover] = _react.default.useState(false);
const [focus, setFocus] = _react.default.useState(false);
const [mouseDown, setMouseDown] = _react.default.useState(false);
const refs = {
root: _react.default.useRef(undefined),
props: _react.default.useRef(undefined),
value: _react.default.useRef(undefined),
valueActive: _react.default.useRef(undefined),
values: _react.default.useRef([]),
mouseDown: _react.default.useRef(undefined),
hover: _react.default.useRef(undefined),
direction: _react.default.useRef(undefined)
};
refs.props.current = props;
refs.value.current = value;
refs.valueActive.current = valueActive;
refs.mouseDown.current = mouseDown;
refs.hover.current = hover;
refs.direction.current = theme.direction;
const min = 0;
const max = values;
const valueDecimals = (String(precision).includes('e-') ? +String(precision).split('e-')[1] : (_String$split$ = String(precision).split('.')[1]) === null || _String$split$ === void 0 ? void 0 : _String$split$.length) || 0;
const valuePrecision = valueMouse => {
let value__ = (0, _utils.valueFromPercentageWithinRange)(valueMouse * 100, min, max);
if (refs.direction.current === 'rtl') value__ = max + min - value__;
if (value__ <= min) return min;
if (value__ >= max) return max;
// previous value
let previous = (0, _utils.clamp)(+(value__ - value__ % precision).toFixed(valueDecimals), min, max);
if (value__ < 0) previous -= precision;
// next value
const next = (0, _utils.clamp)(+(previous + precision).toFixed(valueDecimals), min, max);
const valueNew = value__ > next ? previous : next;
return valueNew;
};
_react.default.useEffect(() => {
var _refs$root$current;
const onMouseUp = () => {
if (!disabled && !readOnly) setMouseDown(false);
};
const onMouseMove = event => {
if (!refs.props.current.disabled && !refs.props.current.readOnly && (refs.mouseDown.current || refs.hover.current)) {
const valuePrevious = refs.hover.current ? refs.valueActive.current : refs.value.current;
const x = event.clientX;
const rect = refs.root.current.getBoundingClientRect();
const {
width: width_
} = rect;
// Value to the precision point value
const value___0 = valuePrecision((x - rect.x) / width_);
const valueNew_0 = value___0;
if (valueNew_0 !== valuePrevious) {
if (!props.hasOwnProperty('value')) {
// Inner controlled value
if (refs.hover.current) setValueActive(valueNew_0);else setValue(valueNew_0);
}
if (refs.hover.current) {
if ((0, _utils.is)('function', onChangeActive)) onChangeActive(valueNew_0);
} else {
if ((0, _utils.is)('function', onChange)) onChange(valueNew_0);
}
}
}
};
const onTouchMove = event_0 => {
if (!refs.props.current.disabled && !refs.props.current.readOnly && refs.mouseDown.current) {
const valuePrevious_0 = refs.hover.current ? refs.valueActive.current : refs.value.current;
const x_0 = event_0.touches[0].clientX;
const rect_0 = refs.root.current.getBoundingClientRect();
const {
width: width__0
} = rect_0;
// Value to the precision point value
const value___1 = valuePrecision((x_0 - rect_0.x) / width__0);
const valueNew_1 = value___1;
if (valueNew_1 !== valuePrevious_0) {
// Inner controlled value
if (!props.hasOwnProperty('value')) setValue(valueNew_1);
if ((0, _utils.is)('function', onChange)) onChange(valueNew_1);
}
}
};
const rootDocument = (0, _utils.isEnvironment)('browser') ? ((_refs$root$current = refs.root.current) === null || _refs$root$current === void 0 ? void 0 : _refs$root$current.ownerDocument) || window.document : undefined;
rootDocument.addEventListener('mouseup', onMouseUp);
rootDocument.addEventListener('mousemove', onMouseMove);
rootDocument.addEventListener('touchend', onMouseUp, {
passive: true
});
rootDocument.addEventListener('touchmove', onTouchMove, {
passive: true
});
setInit(true);
return () => {
rootDocument.removeEventListener('mouseup', onMouseUp);
rootDocument.removeEventListener('touchend', onMouseUp);
rootDocument.removeEventListener('mousemove', onMouseMove);
rootDocument.removeEventListener('touchmove', onTouchMove);
};
}, []);
_react.default.useEffect(() => {
if (init && value_ !== value) setValue(value_);
}, [value_]);
_react.default.useEffect(() => {
if (init && valueActive_ !== valueActive) setValueActive(valueActive_);
}, [valueActive_]);
const onMouseDown = () => {
if (!disabled && !readOnly) setMouseDown(true);
};
const onClick = event_1 => {
if (!disabled && !readOnly) {
// Make precision value
// if value is same as previous value clear
// otherwise update the value y
const x_1 = event_1.clientX;
const rect_1 = refs.root.current.getBoundingClientRect();
const {
width: width__1
} = rect_1;
const valueNew_2 = valuePrecision((x_1 - rect_1.x) / width__1);
if (value === valueNew_2) onClear();else {
if (!props.hasOwnProperty('value')) setValue(valueNew_2);
if ((0, _utils.is)('function', onChange)) onChange(valueNew_2);
}
}
};
const move = (forward_ = true) => {
const forward = theme.direction === 'ltr' ? forward_ : !forward_;
let value___2 = refs.value.current || 0;
// previous value
const previous_0 = (0, _utils.clamp)(+(value___2 - precision).toFixed(valueDecimals), min, max);
// next value
const next_0 = (0, _utils.clamp)(+(value___2 + precision).toFixed(valueDecimals), min, max);
value___2 = forward ? next_0 : previous_0;
const valueNew_3 = value___2;
if (valueNew_3 !== refs.value.current) {
if (!props.hasOwnProperty('value')) setValue(valueNew_3);
if ((0, _utils.is)('function', onChange)) onChange(valueNew_3);
}
};
const onClear = () => {
if (!props.hasOwnProperty('value')) setValue('');
if ((0, _utils.is)('function', onChange)) onChange('');
setHover(false);
};
const onKeyDown = event_2 => {
if (!disabled && !readOnly) {
if (['Enter', 'Escape', 'ArrowUp', 'ArrowRight', 'ArrowDown', 'ArrowLeft', 'Home', 'End'].includes(event_2.key)) {
// Prevent default
event_2.preventDefault();
switch (event_2.key) {
case 'End':
if (!props.hasOwnProperty('value')) setValue(0);
if ((0, _utils.is)('function', onChange)) return onChange(0);
return;
case 'Home':
if (!props.hasOwnProperty('value')) setValue(values);
if ((0, _utils.is)('function', onChange)) return onChange(values);
return;
case 'ArrowUp':
case 'ArrowRight':
return move();
case 'ArrowDown':
case 'ArrowLeft':
return move(false);
case 'Enter':
if (value === valueActive) {
if (!props.hasOwnProperty('value')) setValue('');
if ((0, _utils.is)('function', onChange)) onChange('');
}
return;
case 'Escape':
if (!props.hasOwnProperty('value')) setValue('');
if ((0, _utils.is)('function', onChange)) onChange('');
return;
default:
break;
}
}
}
};
const onFocus = event_3 => {
if (!disabled && !readOnly && !mouseDown) setFocus(true);
};
const onBlur = () => {
if (!disabled && !readOnly) setFocus(false);
};
const onMouseEnter = () => {
if (!disabled && !readOnly) setHover(true);
};
const onMouseLeave = () => {
if (!disabled && !readOnly) setHover(false);
};
const width = index => {
const value___3 = !hover ? value : valueActive;
if (value___3 > index - 1 && value___3 <= index) {
if (value___3 === index) return '100%';
return `${value___3 % 1 * 100}%`;
}
if ((0, _utils.is)('number', value___3) && index < +value___3.toFixed(1) && !onlyValue) return '100%';
};
const getIcon = (index_0, inactive = true) => {
var _icons$index_, _icons$index_2, _icons$index_3, _icons$index_4;
if (inactive) return (icons === null || icons === void 0 || (_icons$index_ = icons[index_0]) === null || _icons$index_ === void 0 ? void 0 : _icons$index_.iconInactive) || (icons === null || icons === void 0 || (_icons$index_2 = icons[index_0]) === null || _icons$index_2 === void 0 ? void 0 : _icons$index_2.icon) || icon || iconInactive;
return (icons === null || icons === void 0 || (_icons$index_3 = icons[index_0]) === null || _icons$index_3 === void 0 ? void 0 : _icons$index_3.iconActive) || (icons === null || icons === void 0 || (_icons$index_4 = icons[index_0]) === null || _icons$index_4 === void 0 ? void 0 : _icons$index_4.icon) || icon || iconActive;
};
const selected = index_1 => value > index_1 - 1 && value <= index_1;
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Component, _objectSpread(_objectSpread({
ref: item => {
if (ref) {
if ((0, _utils.is)('function', ref)) ref(item);else ref.current = ref;
}
refs.root.current = item;
},
tabIndex: !disabled && !readOnly ? 0 : undefined,
onBlur: onBlur,
onFocus: onFocus,
onMouseEnter: onMouseEnter,
onMouseLeave: onMouseLeave,
onMouseDown: onMouseDown,
onTouchStart: onMouseDown,
onKeyDown: onKeyDown,
className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('Rating', theme) && ['onesy-Rating-root', `onesy-Rating-size-${size}`, hover && `onesy-Button-hover`, mouseDown && `onesy-Button-mouse-down`, focus && [`onesy-Button-focus`, [undefined, 0].includes(value) && `onesy-Button-focus-noValue`], readOnly && `onesy-Rating-read-only`, disabled && `onesy-Rating-disabled`], className, classes.root, focus && [classes.focus, [undefined, 0].includes(value) && classes.focus_outline], readOnly && classes.readOnly, disabled && classes.disabled])
}, other), {}, {
children: new Array(values).fill(undefined).map((item_0, index_2) => {
var _IconInactive$props, _IconInactive$props2, _IconActive$props, _IconActive$props2, _IconActive$props3, _IconActive$props4, _IconActive$props5, _IconActive$props6;
const IconInactive = getIcon(index_2 + 1);
const IconActive = getIcon(index_2 + 1, false);
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
ref: item_ => refs.values.current.push(item_),
onClick: onClick,
className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('Rating', theme) && ['onesy-Rating-icon-wrapper', focus && selected(index_2 + 1) && 'onesy-Rating-focus'], classes.iconWrapper, focus && selected(index_2 + 1) && classes.focus_outline, (readOnly || disabled) && classes.iconWrapper_readOnly]),
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('Rating', theme) && ['onesy-Rating-icon', 'onesy-Rating-icon-inactive'], classes.icon, classes.inactive]),
children: /*#__PURE__*/_react.default.cloneElement(IconInactive, _objectSpread(_objectSpread({
color: colorInactive,
size: ((_IconInactive$props = IconInactive.props) === null || _IconInactive$props === void 0 ? void 0 : _IconInactive$props.size) !== undefined ? (_IconInactive$props2 = IconInactive.props) === null || _IconInactive$props2 === void 0 ? void 0 : _IconInactive$props2.size : size
}, IconProps), IconInactiveProps))
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('Rating', theme) && ['onesy-Rating-icon', 'onesy-Rating-icon-active'], classes.icon, classes.active]),
style: {
width: width(index_2 + 1)
},
children: /*#__PURE__*/_react.default.cloneElement(IconActive, _objectSpread(_objectSpread({
tonal: ((_IconActive$props = IconActive.props) === null || _IconActive$props === void 0 ? void 0 : _IconActive$props.tonal) !== undefined ? (_IconActive$props2 = IconActive.props) === null || _IconActive$props2 === void 0 ? void 0 : _IconActive$props2.tonal : tonal,
color: ((_IconActive$props3 = IconActive.props) === null || _IconActive$props3 === void 0 ? void 0 : _IconActive$props3.color) !== undefined ? (_IconActive$props4 = IconActive.props) === null || _IconActive$props4 === void 0 ? void 0 : _IconActive$props4.color : color,
size: ((_IconActive$props5 = IconActive.props) === null || _IconActive$props5 === void 0 ? void 0 : _IconActive$props5.size) !== undefined ? (_IconActive$props6 = IconActive.props) === null || _IconActive$props6 === void 0 ? void 0 : _IconActive$props6.size : size
}, IconProps), IconActiveProps))
})]
}, index_2);
})
}));
};
Rating.displayName = 'onesy-Rating';
var _default = exports.default = Rating;