UNPKG

@amaui/ui-react

Version:
402 lines (401 loc) 24.8 kB
"use strict"; 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]; 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]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = __importDefault(require("react")); const utils_1 = require("@amaui/utils"); const style_react_1 = require("@amaui/style-react"); const Surface_1 = __importDefault(require("../Surface")); const utils_2 = require("../utils"); const useStyle = (0, style_react_1.style)(theme => ({ root: { width: '100%' }, size_small: { maxWidth: '180px' }, size_regular: { maxWidth: '240px' }, size_large: { maxWidth: '300px' }, label: Object.assign(Object.assign({}, theme.typography.values.b2), { textAnchor: 'middle', alignmentBaseline: 'central', dominantBaseline: 'central' }), svg: { position: 'relative', width: '100%', height: 'auto' } }), { name: 'amaui-LinearMeter' }); const LinearMeter = react_1.default.forwardRef((props_, ref) => { const theme = (0, style_react_1.useAmauiTheme)(); const props = react_1.default.useMemo(() => { var _a, _b, _c, _d, _e, _f, _g, _h; return (Object.assign(Object.assign(Object.assign({}, (_d = (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.default), (_h = (_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f.amauiLinearMeter) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]); const Surface = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Surface) || Surface_1.default; }, [theme]); const { 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 = __rest(props, ["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"]); const { classes } = useStyle(); const refs = { root: react_1.default.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 = (0, utils_1.clamp)((0, utils_1.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_1.default.useMemo(() => { const values = []; if (marks_.length) { let marksValues = marks_; if (!(0, utils_1.is)('array', marksValues[0])) marksValues = [marksValues]; marksValues.forEach((marksValue, index) => { values[index] = []; marksValue.forEach((mark) => { const { size: size_, padding: markPadding = 0, position } = mark, other_ = __rest(mark, ["size", "padding", "position"]); 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(Object.assign({ d: [ 'M', x + paddings.x, y, 'L', x + paddings.x, yl ].join(' ') }, other_)); } if (orientation === 'vertical') { const total = height - (paddings.y * 2); const y = total * (position / 100); let x = width - paddings.x - boundaryWidth - markPadding; let xl = x - size_; if (linePosition === 'start') { x = paddings.x + boundaryWidth + markPadding; xl = x + size_; } if (linePosition === 'center') { x = (width / 2) + (boundaryWidth / 2) + markPadding; xl = x + size_; } if (linePosition === 'end') { x = width - paddings.y - boundaryWidth - markPadding; xl = x - size_; } values[index].push(Object.assign({ d: [ 'M', x, y + paddings.y, 'L', xl, y + paddings.y ].join(' ') }, other_)); } }); }); } return values; }, [orientation, linePosition, width, height, parts, marks_, markWidth, markSize, boundaryWidth, lineCap, paddingVertical, paddingHorizontal, outsidePadding, gap]); const labels = react_1.default.useMemo(() => { var _a; const values = []; if (labels_.length) { const marksPadding = (marks_ === null || marks_ === void 0 ? void 0 : marks_.length) ? ((_a = (marks_ || []).sort((a, b) => b.size - a.size)[0]) === null || _a === void 0 ? void 0 : _a.size) || markSize : 0; let labelsValues = labels_; if (!(0, utils_1.is)('array', labelsValues[0])) labelsValues = [labelsValues]; labelsValues.forEach((labelsValue, index) => { values[index] = []; labelsValue.forEach((label) => { var _a; const { value, padding: labelPadding = 0, position } = label, other_ = __rest(label, ["value", "padding", "position"]); const fontSize = ((_a = label.style) === null || _a === void 0 ? void 0 : _a.fontSize) !== undefined ? label.style.fontSize : 14; if (orientation === 'horizontal') { const total = width - (paddings.x * 2); const x = total * (position / 100); let y = height - paddings.y - boundaryWidth - labelPadding; if (linePosition === 'start') { y = paddings.y + boundaryWidth + labelPadding + (fontSize / 2) + marksPadding; } if (linePosition === 'center') { y = (height / 2) - (boundaryWidth / 2) - labelPadding - (fontSize / 2) - marksPadding; } if (linePosition === 'end') { y = height - paddings.y - boundaryWidth - labelPadding - (fontSize / 2) - marksPadding; } values[index].push(Object.assign({ x: x + paddings.x, y, value }, other_)); } if (orientation === 'vertical') { const total = height - (paddings.y * 2); const y = total * (position / 100); let x = width - paddings.x - boundaryWidth - labelPadding; if (linePosition === 'start') { x = paddings.x + boundaryWidth + labelPadding + (fontSize / 2) + marksPadding; } if (linePosition === 'center') { x = (width / 2) + (boundaryWidth / 2) + labelPadding + (fontSize / 2) + marksPadding; } if (linePosition === 'end') { x = width - paddings.y - boundaryWidth - labelPadding - (fontSize / 2) - marksPadding; } values[index].push(Object.assign({ x, y: y + paddings.y, value }, other)); } }); }); } return values; }, [orientation, linePosition, width, height, parts, marks_, markWidth, markSize, boundaryWidth, lineCap, outsidePadding, gap]); const lines = react_1.default.useMemo(() => { const values = []; let value = []; if (orientation === 'horizontal') { const lineCapOffset = ['round', 'square'].includes(lineCap) ? boundaryWidth / 2 : 0; const offset = (paddings.x * 2) + (lineCapOffset ? boundaryWidth * parts : 0); const total = width; const part = (total - ((parts - 1) * gap) - offset) / parts; let previousValue = 0; const x = 0 + lineCapOffset + paddings.x; let y = height - (boundaryWidth / 2); if (linePosition === 'start') { y = boundaryWidth / 2; y += paddings.y; } if (linePosition === 'center') y = height / 2; if (linePosition === 'end') { y = height - (boundaryWidth / 2); y -= paddings.y; } for (let i = 0; i < parts; i++) { // move to bottom left if (i === 0) value.push( // Move to bottom left 'm', x, y); // line value.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.push({ d: value.join(' ') }); if (i === 0) previousValue += lineCapOffset + paddings.x; // move for the next value if (i < parts - 1) { value = [ 'm', previousValue, y ]; } } } if (orientation === 'vertical') { const lineCapOffset = ['round', 'square'].includes(lineCap) ? boundaryWidth / 2 : 0; const offset = (paddings.y * 2) + (lineCapOffset ? boundaryWidth * parts : 0); const total = height; const part = (total - ((parts - 1) * gap) - offset) / parts; let previousValue = 0; let x = width - (boundaryWidth / 2); const y = 0 + lineCapOffset + paddings.y; if (linePosition === 'start') { x = boundaryWidth / 2; x += paddings.x; } if (linePosition === 'center') x = width / 2; if (linePosition === 'end') { x = width - (boundaryWidth / 2); x -= paddings.x; } for (let i = 0; i < parts; i++) { // move to bottom left if (i === 0) value.push( // Move to bottom left 'm', x, y); // line value.push('l', 0, part); // 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.push({ d: value.join(' ') }); if (i === 0) previousValue += lineCapOffset + paddings.y; // move for the next value if (i < parts - 1) { value = [ 'm', x, previousValue ]; } } } return values; }, [width, height, parts, boundaryWidth, lineCap, orientation, linePosition, paddingVertical, paddingHorizontal, outsidePadding, gap]); const pathBackground = react_1.default.useMemo(() => { const values = []; if (orientation === 'horizontal') { values.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.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.join(' '); }, [orientation, linePosition, width, height, boundaryWidth, outsidePadding, paddingVertical, paddingHorizontal]); const pathBorder = react_1.default.useMemo(() => { const values = []; if (orientation === 'horizontal') { if (linePosition === 'start') { values.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.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.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.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.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.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.join(' '); }, [orientation, linePosition, width, height, boundaryWidth, outsidePadding, paddingVertical, paddingHorizontal]); return ((0, jsx_runtime_1.jsxs)(Component, Object.assign({ ref: item => { if (ref) { if ((0, utils_1.is)('function', ref)) ref(item); else ref.current = item; } refs.root.current = item; }, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('LinearMeter', theme) && [ 'amaui-LinearMeter-root', `amaui-LinearMeter-size-${size}` ], className, classes.root, classes[`size_${size}`] ]), style: Object.assign(Object.assign({}, styles.root), style) }, other, { children: [additional, (0, jsx_runtime_1.jsx)(Surface, Object.assign({ tonal: tonal, color: color }, { children: ({ color: color_, backgroundColor }) => ((0, jsx_runtime_1.jsxs)("svg", Object.assign({ xmlns: 'http://www.w3.org/2000/svg', viewBox: `0 0 ${width || 0} ${height || 0}` }, SvgProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('LinearMeter', theme) && [ 'amaui-LinearMeter-svg' ], SvgProps === null || SvgProps === void 0 ? void 0 : SvgProps.className, classes.svg ]) }, { children: [background && ((0, jsx_runtime_1.jsx)("path", Object.assign({ d: pathBackground, fill: backgroundColor, stroke: 'none' }, pathProps, BackgroundProps))), border && ((0, jsx_runtime_1.jsx)("path", Object.assign({ d: pathBorder, fill: 'none', stroke: color_, strokeWidth: boundaryWidth }, pathProps, BorderProps))), linesVisible && ((0, jsx_runtime_1.jsx)("g", Object.assign({ className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('LinearMeter', theme) && [ 'amaui-LinearMeter-arcs' ], classes.arcs ]) }, { children: (lines.map((item, index) => ((0, jsx_runtime_1.jsx)("path", Object.assign({ d: item.d, fill: 'none', stroke: color_, strokeWidth: boundaryWidth, strokeLinecap: lineCap }, pathProps, LineProps, LineMainProps), index)))) }))), linesVisible && lineProgress && ((0, jsx_runtime_1.jsx)("g", Object.assign({}, LinesProgressProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('LinearMeter', theme) && [ 'amaui-LinearMeter-lines-progress' ], LinesProgressProps === null || LinesProgressProps === void 0 ? void 0 : LinesProgressProps.className, classes.lines_progress ]) }, { children: (lines.map((item, index) => ((0, jsx_runtime_1.jsx)("path", Object.assign({ d: item.d, fill: 'none', stroke: color_, strokeWidth: boundaryWidth, strokeLinecap: lineCap }, pathProps, LineProps, LineProgressProps), index)))) }))), children && ((0, jsx_runtime_1.jsx)("g", Object.assign({ className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('LinearMeter', theme) && [ 'amaui-LinearMeter-children' ], classes.children ]) }, { children: react_1.default.Children.toArray(children).map((item, index) => { return (react_1.default.cloneElement(item, { key: index, fill: item.props.fill !== undefined ? item.props.fill : color_, stroke: item.props.stroke !== undefined ? item.props.stroke : color_, // clean up value: undefined, style: Object.assign(Object.assign({}, (item.props.value !== undefined ? { transform: orientation === 'horizontal' ? `translate3d(${paddings.x + (((item.props.value / 100) || 0) * (width - (paddings.x * 2)))}px, 0, 0)` : `translate3d(0, ${paddings.y + (((item.props.value / 100) || 0) * (height - (paddings.y * 2)))}px, 0)` } : undefined)), item.props.style) })); }) }))), marksVisible && !!marks_.length && (marks.map((marksValue, index) => ((0, jsx_runtime_1.jsx)("g", Object.assign({ className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('LinearMeter', theme) && [ 'amaui-LinearMeter-marks' ], classes.marks ]) }, { children: (marksValue.map((item, index_) => ((0, jsx_runtime_1.jsx)("path", Object.assign({ d: item.d, fill: 'none', stroke: color_, strokeWidth: item.width !== undefined ? item.width : markWidth, strokeLinecap: lineCap }, pathProps, MarkProps), index_)))) }), index)))), labelsVisible && !!labels_.length && (labels.map((labelsValue, index) => ((0, jsx_runtime_1.jsx)("g", Object.assign({ className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('LinearMeter', theme) && [ 'amaui-LinearMeter-labels' ], classes.labels ]) }, { children: (labelsValue.map((item, index_) => { const { x, y, value } = item, other_ = __rest(item, ["x", "y", "value"]); return ((0, jsx_runtime_1.jsx)("text", Object.assign({ x: x, y: y }, other_, textProps, LabelProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('LinearMeter', theme) && [ 'amaui-LinearMeter-label' ], other_ === null || other_ === void 0 ? void 0 : other_.className, textProps === null || textProps === void 0 ? void 0 : textProps.className, LabelProps === null || LabelProps === void 0 ? void 0 : LabelProps.className, classes.label ]), style: Object.assign(Object.assign(Object.assign({ fill: color_ }, other_.style), textProps === null || textProps === void 0 ? void 0 : textProps.style), LabelProps === null || LabelProps === void 0 ? void 0 : LabelProps.style) }, { children: value }), index_)); })) }), index))))] }))) }))] }))); }); LinearMeter.displayName = 'amaui-LinearMeter'; exports.default = LinearMeter;