@onesy/ui-react
Version:
UI for React
467 lines (461 loc) • 20.6 kB
JavaScript
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
const _excluded = ["ref", "tonal", "color", "size", "parts", "lineCap", "orientation", "linePosition", "width", "height", "padding", "paddingVertical", "paddingHorizontal", "gap", "border", "background", "boundaryWidth", "lineProgress", "linesVisible", "marksVisible", "labelsVisible", "marks", "markSize", "markWidth", "labels", "additional", "textProps", "pathProps", "SvgProps", "MarkProps", "LabelProps", "BackgroundProps", "BorderProps", "LineProps", "LineMainProps", "LinesProgressProps", "LineProgressProps", "Component", "className", "style", "children"],
_excluded2 = ["size", "padding", "position"],
_excluded3 = ["value", "padding", "position"],
_excluded4 = ["x", "y", "value"];
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) { _defineProperty(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; }
import React from 'react';
import { clamp, is, parse } from '@onesy/utils';
import { classNames, style as styleMethod, useOnesyTheme } from '@onesy/style-react';
import SurfaceElement from '../Surface';
import { staticClassName } from '../utils';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const useStyle = styleMethod(theme => ({
root: {
width: '100%'
},
size_small: {
maxWidth: '180px'
},
size_regular: {
maxWidth: '240px'
},
size_large: {
maxWidth: '300px'
},
label: _objectSpread(_objectSpread({}, theme.typography.values.b2), {}, {
textAnchor: 'middle',
alignmentBaseline: 'central',
dominantBaseline: 'central'
}),
svg: {
position: 'relative',
width: '100%',
height: 'auto'
}
}), {
name: 'onesy-LinearMeter'
});
const LinearMeter = props_ => {
const theme = useOnesyTheme();
const props = _objectSpread(_objectSpread(_objectSpread({}, theme?.ui?.elements?.all?.props?.default), theme?.ui?.elements?.onesyLinearMeter?.props?.default), props_);
const Surface = theme?.elements?.Surface || SurfaceElement;
const {
ref,
tonal = true,
color = 'primary',
size = 'regular',
parts: parts_ = 1,
lineCap,
// vertical, horizontal
orientation = 'horizontal',
// start, center, end
linePosition = 'end',
width: width_,
height: height_,
padding: outsidePadding = 0,
paddingVertical,
paddingHorizontal,
gap = 0,
border = false,
background = false,
boundaryWidth = 1,
lineProgress = false,
linesVisible = true,
marksVisible = true,
labelsVisible = true,
marks: marks_ = [],
markSize = 4,
markWidth = 1,
labels: labels_ = [],
additional,
textProps,
pathProps,
SvgProps,
MarkProps,
LabelProps,
BackgroundProps,
BorderProps,
LineProps,
LineMainProps,
LinesProgressProps,
LineProgressProps,
Component = 'div',
className,
style,
children
} = props,
other = _objectWithoutProperties(props, _excluded);
const {
classes
} = useStyle();
const refs = {
root: React.useRef(undefined)
};
const styles = {
root: {}
};
let width = width_ !== undefined ? width_ : size === 'regular' ? 240 : size === 'large' ? 300 : 180;
let height = height_ !== undefined ? height_ : 100;
if (orientation === 'vertical') {
height = height_ !== undefined ? height_ : size === 'regular' ? 240 : size === 'large' ? 300 : 180;
width = width_ !== undefined ? width_ : 100;
styles.root.maxWidth = width;
} else {
styles.root.height = height;
}
const parts = clamp(parse(parts_), 1, 1000);
const paddings = {
x: paddingHorizontal !== undefined ? paddingHorizontal : outsidePadding || 0,
y: paddingVertical !== undefined ? paddingVertical : outsidePadding || 0
};
if (!['small', 'regular', 'large'].includes(size)) styles.root.maxWidth = size;
const marks = React.useMemo(() => {
const values = [];
if (marks_.length) {
let marksValues = marks_;
if (!is('array', marksValues[0])) marksValues = [marksValues];
marksValues.forEach((marksValue, index) => {
values[index] = [];
marksValue.forEach(mark => {
const {
size: size_,
padding: markPadding = 0,
position
} = mark,
other_ = _objectWithoutProperties(mark, _excluded2);
if (orientation === 'horizontal') {
const total = width - paddings.x * 2;
const x = total * (position / 100);
let y = height - paddings.y - boundaryWidth - markPadding;
let yl = y - size_;
if (linePosition === 'start') {
y = paddings.y + boundaryWidth + markPadding;
yl = y + size_;
}
if (linePosition === 'center') {
y = height / 2 - boundaryWidth / 2 - markPadding;
yl = y - size_;
}
if (linePosition === 'end') {
y = height - paddings.y - boundaryWidth - markPadding;
yl = y - size_;
}
values[index].push(_objectSpread({
d: ['M', x + paddings.x, y, 'L', x + paddings.x, yl].join(' ')
}, other_));
}
if (orientation === 'vertical') {
const total_0 = height - paddings.y * 2;
const y_0 = total_0 * (position / 100);
let x_0 = width - paddings.x - boundaryWidth - markPadding;
let xl = x_0 - size_;
if (linePosition === 'start') {
x_0 = paddings.x + boundaryWidth + markPadding;
xl = x_0 + size_;
}
if (linePosition === 'center') {
x_0 = width / 2 + boundaryWidth / 2 + markPadding;
xl = x_0 + size_;
}
if (linePosition === 'end') {
x_0 = width - paddings.y - boundaryWidth - markPadding;
xl = x_0 - size_;
}
values[index].push(_objectSpread({
d: ['M', x_0, y_0 + paddings.y, 'L', xl, y_0 + paddings.y].join(' ')
}, other_));
}
});
});
}
return values;
}, [orientation, linePosition, width, height, parts, marks_, markWidth, markSize, boundaryWidth, lineCap, paddingVertical, paddingHorizontal, outsidePadding, gap]);
const labels = React.useMemo(() => {
const values_0 = [];
if (labels_.length) {
const marksPadding = marks_?.length ? (marks_ || []).sort((a, b) => b.size - a.size)[0]?.size || markSize : 0;
let labelsValues = labels_;
if (!is('array', labelsValues[0])) labelsValues = [labelsValues];
labelsValues.forEach((labelsValue, index_0) => {
values_0[index_0] = [];
labelsValue.forEach(label => {
const {
value,
padding: labelPadding = 0,
position: position_0
} = label,
other__0 = _objectWithoutProperties(label, _excluded3);
const fontSize = label.style?.fontSize !== undefined ? label.style.fontSize : 14;
if (orientation === 'horizontal') {
const total_1 = width - paddings.x * 2;
const x_1 = total_1 * (position_0 / 100);
let y_1 = height - paddings.y - boundaryWidth - labelPadding;
if (linePosition === 'start') {
y_1 = paddings.y + boundaryWidth + labelPadding + fontSize / 2 + marksPadding;
}
if (linePosition === 'center') {
y_1 = height / 2 - boundaryWidth / 2 - labelPadding - fontSize / 2 - marksPadding;
}
if (linePosition === 'end') {
y_1 = height - paddings.y - boundaryWidth - labelPadding - fontSize / 2 - marksPadding;
}
values_0[index_0].push(_objectSpread({
x: x_1 + paddings.x,
y: y_1,
value
}, other__0));
}
if (orientation === 'vertical') {
const total_2 = height - paddings.y * 2;
const y_2 = total_2 * (position_0 / 100);
let x_2 = width - paddings.x - boundaryWidth - labelPadding;
if (linePosition === 'start') {
x_2 = paddings.x + boundaryWidth + labelPadding + fontSize / 2 + marksPadding;
}
if (linePosition === 'center') {
x_2 = width / 2 + boundaryWidth / 2 + labelPadding + fontSize / 2 + marksPadding;
}
if (linePosition === 'end') {
x_2 = width - paddings.y - boundaryWidth - labelPadding - fontSize / 2 - marksPadding;
}
values_0[index_0].push(_objectSpread({
x: x_2,
y: y_2 + paddings.y,
value
}, other));
}
});
});
}
return values_0;
}, [orientation, linePosition, width, height, parts, marks_, markWidth, markSize, boundaryWidth, lineCap, outsidePadding, gap]);
const lines = React.useMemo(() => {
const values_1 = [];
let value_0 = [];
if (orientation === 'horizontal') {
const lineCapOffset = ['round', 'square'].includes(lineCap) ? boundaryWidth / 2 : 0;
const offset = paddings.x * 2 + (lineCapOffset ? boundaryWidth * parts : 0);
const total_3 = width;
const part = (total_3 - (parts - 1) * gap - offset) / parts;
let previousValue = 0;
const x_3 = 0 + lineCapOffset + paddings.x;
let y_3 = height - boundaryWidth / 2;
if (linePosition === 'start') {
y_3 = boundaryWidth / 2;
y_3 += paddings.y;
}
if (linePosition === 'center') y_3 = height / 2;
if (linePosition === 'end') {
y_3 = height - boundaryWidth / 2;
y_3 -= paddings.y;
}
for (let i = 0; i < parts; i++) {
// move to bottom left
if (i === 0) value_0.push(
// Move to bottom left
'm', x_3, y_3);
// line
value_0.push('l', part, 0);
// Previous value with/out the gap value
if (gap > 0 && i < parts - 1) previousValue += part + gap + (lineCapOffset ? boundaryWidth : 0);else previousValue += part + (lineCapOffset ? boundaryWidth : 0);
values_1.push({
d: value_0.join(' ')
});
if (i === 0) previousValue += lineCapOffset + paddings.x;
// move for the next value
if (i < parts - 1) {
value_0 = ['m', previousValue, y_3];
}
}
}
if (orientation === 'vertical') {
const lineCapOffset_0 = ['round', 'square'].includes(lineCap) ? boundaryWidth / 2 : 0;
const offset_0 = paddings.y * 2 + (lineCapOffset_0 ? boundaryWidth * parts : 0);
const total_4 = height;
const part_0 = (total_4 - (parts - 1) * gap - offset_0) / parts;
let previousValue_0 = 0;
let x_4 = width - boundaryWidth / 2;
const y_4 = 0 + lineCapOffset_0 + paddings.y;
if (linePosition === 'start') {
x_4 = boundaryWidth / 2;
x_4 += paddings.x;
}
if (linePosition === 'center') x_4 = width / 2;
if (linePosition === 'end') {
x_4 = width - boundaryWidth / 2;
x_4 -= paddings.x;
}
for (let i_0 = 0; i_0 < parts; i_0++) {
// move to bottom left
if (i_0 === 0) value_0.push(
// Move to bottom left
'm', x_4, y_4);
// line
value_0.push('l', 0, part_0);
// Previous value with/out the gap value
if (gap > 0 && i_0 < parts - 1) previousValue_0 += part_0 + gap + (lineCapOffset_0 ? boundaryWidth : 0);else previousValue_0 += part_0 + (lineCapOffset_0 ? boundaryWidth : 0);
values_1.push({
d: value_0.join(' ')
});
if (i_0 === 0) previousValue_0 += lineCapOffset_0 + paddings.y;
// move for the next value
if (i_0 < parts - 1) {
value_0 = ['m', x_4, previousValue_0];
}
}
}
return values_1;
}, [width, height, parts, boundaryWidth, lineCap, orientation, linePosition, paddingVertical, paddingHorizontal, outsidePadding, gap]);
const pathBackground = React.useMemo(() => {
const values_2 = [];
if (orientation === 'horizontal') {
values_2.push(
// Move
'M', paddings.x, height - paddings.y, 'L', paddings.x, paddings.y, 'L', width - paddings.x, paddings.y, 'L', width - paddings.x, height - paddings.y, 'Z');
}
if (orientation === 'vertical') {
values_2.push(
// Move
'M', width - paddings.x, paddings.y, 'L', paddings.x, paddings.y, 'L', paddings.x, height - paddings.y, 'L', width - paddings.x, height - paddings.y, 'Z');
}
return values_2.join(' ');
}, [orientation, linePosition, width, height, boundaryWidth, outsidePadding, paddingVertical, paddingHorizontal]);
const pathBorder = React.useMemo(() => {
const values_3 = [];
if (orientation === 'horizontal') {
if (linePosition === 'start') {
values_3.push(
// Move
'M', paddings.x, paddings.y, 'L', paddings.x, height - paddings.y, 'L', width - paddings.x, height - paddings.y, 'L', width - paddings.x, paddings.y);
}
if (linePosition === 'center') {
values_3.push(
// Move
'M', paddings.x, height - paddings.y, 'L', paddings.x, paddings.y, 'L', width - paddings.x, paddings.y, 'L', width - paddings.x, height - paddings.y, 'Z');
}
if (linePosition === 'end') {
values_3.push(
// Move
'M', paddings.x, height - paddings.y, 'L', paddings.x, paddings.y, 'L', width - paddings.x, paddings.y, 'L', width - paddings.x, height - paddings.y);
}
}
if (orientation === 'vertical') {
if (linePosition === 'start') {
values_3.push(
// Move
'M', paddings.x, height - paddings.y, 'L', width - paddings.x, height - paddings.y, 'L', width - paddings.x, paddings.y, 'L', paddings.x, paddings.y);
}
if (linePosition === 'center') {
values_3.push(
// Move
'M', width - paddings.x, paddings.y, 'L', paddings.x, paddings.y, 'L', paddings.x, height - paddings.y, 'L', width - paddings.x, height - paddings.y, 'Z');
}
if (linePosition === 'end') {
values_3.push(
// Move
'M', width - paddings.x, paddings.y, 'L', paddings.x, paddings.y, 'L', paddings.x, height - paddings.y, 'L', width - paddings.x, height - paddings.y);
}
}
return values_3.join(' ');
}, [orientation, linePosition, width, height, boundaryWidth, outsidePadding, paddingVertical, paddingHorizontal]);
return /*#__PURE__*/_jsxs(Component, _objectSpread(_objectSpread({
ref: item => {
if (ref) {
if (is('function', ref)) ref(item);else ref.current = item;
}
refs.root.current = item;
},
className: classNames([staticClassName('LinearMeter', theme) && ['onesy-LinearMeter-root', `onesy-LinearMeter-size-${size}`], className, classes.root, classes[`size_${size}`]]),
style: _objectSpread(_objectSpread({}, styles.root), style)
}, other), {}, {
children: [additional, /*#__PURE__*/_jsx(Surface, {
tonal: tonal,
color: color,
children: ({
color: color_,
backgroundColor
}) => /*#__PURE__*/_jsxs("svg", _objectSpread(_objectSpread({
xmlns: "http://www.w3.org/2000/svg",
viewBox: `0 0 ${width || 0} ${height || 0}`
}, SvgProps), {}, {
className: classNames([staticClassName('LinearMeter', theme) && ['onesy-LinearMeter-svg'], SvgProps?.className, classes.svg]),
children: [background && /*#__PURE__*/_jsx("path", _objectSpread(_objectSpread({
d: pathBackground,
fill: backgroundColor,
stroke: "none"
}, pathProps), BackgroundProps)), border && /*#__PURE__*/_jsx("path", _objectSpread(_objectSpread({
d: pathBorder,
fill: "none",
stroke: color_,
strokeWidth: boundaryWidth
}, pathProps), BorderProps)), linesVisible && /*#__PURE__*/_jsx("g", {
className: classNames([staticClassName('LinearMeter', theme) && ['onesy-LinearMeter-arcs'], classes.arcs]),
children: lines.map((item_0, index_1) => /*#__PURE__*/_jsx("path", _objectSpread(_objectSpread(_objectSpread({
d: item_0.d,
fill: "none",
stroke: color_,
strokeWidth: boundaryWidth,
strokeLinecap: lineCap
}, pathProps), LineProps), LineMainProps), index_1))
}), linesVisible && lineProgress && /*#__PURE__*/_jsx("g", _objectSpread(_objectSpread({}, LinesProgressProps), {}, {
className: classNames([staticClassName('LinearMeter', theme) && ['onesy-LinearMeter-lines-progress'], LinesProgressProps?.className, classes.lines_progress]),
children: lines.map((item_1, index_2) => /*#__PURE__*/_jsx("path", _objectSpread(_objectSpread(_objectSpread({
d: item_1.d,
fill: "none",
stroke: color_,
strokeWidth: boundaryWidth,
strokeLinecap: lineCap
}, pathProps), LineProps), LineProgressProps), index_2))
})), children && /*#__PURE__*/_jsx("g", {
className: classNames([staticClassName('LinearMeter', theme) && ['onesy-LinearMeter-children'], classes.children]),
children: React.Children.toArray(children).map((item_2, index_3) => {
return /*#__PURE__*/React.cloneElement(item_2, {
key: index_3,
fill: item_2.props.fill !== undefined ? item_2.props.fill : color_,
stroke: item_2.props.stroke !== undefined ? item_2.props.stroke : color_,
// clean up
value: undefined,
style: _objectSpread(_objectSpread({}, item_2.props.value !== undefined ? {
transform: orientation === 'horizontal' ? `translate3d(${paddings.x + (item_2.props.value / 100 || 0) * (width - paddings.x * 2)}px, 0, 0)` : `translate3d(0, ${paddings.y + (item_2.props.value / 100 || 0) * (height - paddings.y * 2)}px, 0)`
} : undefined), item_2.props.style)
});
})
}), marksVisible && !!marks_.length && marks.map((marksValue_0, index_4) => /*#__PURE__*/_jsx("g", {
className: classNames([staticClassName('LinearMeter', theme) && ['onesy-LinearMeter-marks'], classes.marks]),
children: marksValue_0.map((item_3, index_) => /*#__PURE__*/_jsx("path", _objectSpread(_objectSpread({
d: item_3.d,
fill: "none",
stroke: color_,
strokeWidth: item_3.width !== undefined ? item_3.width : markWidth,
strokeLinecap: lineCap
}, pathProps), MarkProps), index_))
}, index_4)), labelsVisible && !!labels_.length && labels.map((labelsValue_0, index_5) => /*#__PURE__*/_jsx("g", {
className: classNames([staticClassName('LinearMeter', theme) && ['onesy-LinearMeter-labels'], classes.labels]),
children: labelsValue_0.map((item_4, index__0) => {
const {
x: x_5,
y: y_5,
value: value_1
} = item_4,
other__1 = _objectWithoutProperties(item_4, _excluded4);
return /*#__PURE__*/_jsx("text", _objectSpread(_objectSpread(_objectSpread(_objectSpread({
x: x_5,
y: y_5
}, other__1), textProps), LabelProps), {}, {
className: classNames([staticClassName('LinearMeter', theme) && ['onesy-LinearMeter-label'], other__1?.className, textProps?.className, LabelProps?.className, classes.label]),
style: _objectSpread(_objectSpread(_objectSpread({
fill: color_
}, other__1.style), textProps?.style), LabelProps?.style),
children: value_1
}), index__0);
})
}, index_5))]
}))
})]
}));
};
LinearMeter.displayName = 'onesy-LinearMeter';
export default LinearMeter;