@amaui/ui-react
Version:
UI for React
323 lines (322 loc) • 18.4 kB
JavaScript
"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 IconMaterialExpandMoreW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialExpandMoreW100"));
const Checkbox_1 = __importDefault(require("../Checkbox"));
const Surface_1 = __importDefault(require("../Surface"));
const Type_1 = __importDefault(require("../Type"));
const Fade_1 = __importDefault(require("../Fade"));
const Expand_1 = __importDefault(require("../Expand"));
const Interaction_1 = __importDefault(require("../Interaction"));
const Line_1 = __importDefault(require("../Line"));
const utils_2 = require("../utils");
const useStyle = (0, style_react_1.style)(theme => ({
root: {
position: 'relative'
},
line: {
'&::before': {
content: "''",
position: 'absolute',
insetInlineStart: '-12px',
height: '100%',
width: '2px',
background: theme.palette.light ? theme.palette.color.neutral['90'] : theme.palette.color.neutral['20']
},
'&:last-of-type': {
'&::before': {
height: '2px'
}
}
},
main: {
// Reset
fontFamily: 'inherit',
background: 'transparent',
border: 'none',
fontSize: '100%',
lineHeight: '1.15',
margin: '0',
position: 'relative',
color: 'inherit',
padding: `${theme.methods.space.value(0.25, 'px')} ${theme.methods.space.value(1, 'px')}`,
borderRadius: `${theme.shape.radius.unit * 0.5}px`
},
main_line: {
'&::before': {
content: "''",
position: 'absolute',
top: 'calc(50% - 15px)',
insetInlineStart: '-12px',
width: '10px',
height: '14px',
borderLeft: '2px solid',
borderBottom: '2px solid',
borderColor: theme.palette.light ? theme.palette.color.neutral['90'] : theme.palette.color.neutral['20'],
borderBottomLeftRadius: '6px',
transform: `rotateY(${theme.direction === 'ltr' ? 0 : 180}deg)`
}
},
item: {
padding: `${theme.methods.space.value(0.25, 'px')} 0`
},
middle: {
flex: '1 1 auto'
},
indicator: {
transition: theme.methods.transitions.make('transform')
},
indicator_open: {
transform: 'rotate(-180deg)'
},
button: {
// Reset
fontFamily: 'inherit',
'-webkit-appearance': 'none',
appearance: 'none',
background: 'transparent',
border: 'none',
fontSize: '100%',
lineHeight: '1.15',
padding: '0',
margin: '0',
overflow: 'visible',
textTransform: 'none',
userSelect: 'none',
cursor: 'pointer'
},
disabled: {
pointerEvents: 'none',
cursor: 'default',
opacity: theme.palette.visual_contrast.default.opacity.disabled
}
}), { name: 'amaui-Tree' });
const TreeDelays = {
Transition: {
enter: 70
}
};
const Tree = 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.amauiTree) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]);
const Line = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Line) || Line_1.default; }, [theme]);
const Checkbox = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Checkbox) || Checkbox_1.default; }, [theme]);
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 Type = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Type) || Type_1.default; }, [theme]);
const Fade = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Fade) || Fade_1.default; }, [theme]);
const Expand = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Expand) || Expand_1.default; }, [theme]);
const Interaction = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Interaction) || Interaction_1.default; }, [theme]);
const { tonal = true, color = 'default', version = 'text', open: open_, openDefault, onChange, selected, line, indicator, arrow = true, checkbox, indicatorPosition = 'start', level = 0, icon, iconOpen, start: start_, middle, end: end_, button = true, noTransition, noExpand, noPadding, parentDisabled, disabled, ExpandProps, MainProps: MainProps_, StartProps, MiddleProps, EndProps, IndicatorProps, TransitionComponentProps: TransitionComponentProps_, TreeProps, IconArrow = IconMaterialExpandMoreW100_1.default, TransitionComponent: TransitionComponent_ = Fade, Component = 'div', className, style, children: children_ } = props, other = __rest(props, ["tonal", "color", "version", "open", "openDefault", "onChange", "selected", "line", "indicator", "arrow", "checkbox", "indicatorPosition", "level", "icon", "iconOpen", "start", "middle", "end", "button", "noTransition", "noExpand", "noPadding", "parentDisabled", "disabled", "ExpandProps", "MainProps", "StartProps", "MiddleProps", "EndProps", "IndicatorProps", "TransitionComponentProps", "TreeProps", "IconArrow", "TransitionComponent", "Component", "className", "style", "children"]);
const { classes } = useStyle();
const [init, setInit] = react_1.default.useState(false);
const [focus, setFocus] = react_1.default.useState(false);
const [open, setOpen] = react_1.default.useState(openDefault !== undefined ? openDefault : open_);
const refs = {
root: react_1.default.useRef(undefined),
ids: {
middle: react_1.default.useId()
},
inProgressTransition: react_1.default.useRef()
};
const styles = {
root: {}
};
let TransitionComponent = TransitionComponent_;
let TransitionComponentProps = Object.assign({ add: true, delay: {
enter: TreeDelays.Transition.enter
} }, TransitionComponentProps_);
react_1.default.useEffect(() => {
setInit(true);
}, []);
react_1.default.useEffect(() => {
if (init) {
if (open_ !== open)
setOpen(open_);
}
}, [open_]);
const onKeyDown = (event) => {
var _a;
const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined;
if (level === 0) {
let allElements = [];
let index = 0;
if (['ArrowUp', 'ArrowDown'].includes(event.key)) {
allElements = Array.from(refs.root.current.querySelectorAll(`[tabindex='0']`));
}
switch (event.key) {
case 'ArrowUp':
case 'ArrowDown':
index = (0, utils_1.clamp)(allElements.findIndex(item => item === rootDocument.activeElement), 0);
event.key === 'ArrowDown' ? index++ : index--;
allElements[(0, utils_1.clamp)(index, 0, allElements.length - 1)].focus();
event.preventDefault();
return;
default:
break;
}
}
};
const onClick = react_1.default.useCallback((event) => {
if ((0, utils_1.is)('function', MiddleProps === null || MiddleProps === void 0 ? void 0 : MiddleProps.onClick))
MiddleProps.onClick(event);
if (refs.inProgressTransition.current)
return;
if (!disabled && !noExpand && children_) {
const valueNew = !open;
// Update inner or controlled
if (!props.hasOwnProperty('open'))
setOpen(valueNew);
if ((0, utils_1.is)('function', onChange))
onChange(valueNew);
}
}, [open, noExpand, children_, disabled]);
if (!noTransition)
TransitionComponentProps.in = open;
else {
TransitionComponent = react_1.default.Fragment;
TransitionComponentProps = {};
}
const onBlur = react_1.default.useCallback((event) => {
if (!disabled)
setFocus(false);
}, [disabled]);
const onFocus = react_1.default.useCallback((event) => {
if (!disabled)
setFocus(true);
}, [disabled]);
const start = react_1.default.Children.toArray(start_);
// Icon
if (!open ? icon : iconOpen || icon)
start.push((!open ? icon : iconOpen || icon));
const end = react_1.default.Children.toArray(end_);
if (indicator && button && children_ && !noExpand) {
let Indicator;
if (arrow) {
Indicator = ((0, jsx_runtime_1.jsx)(IconArrow, Object.assign({ className: (0, style_react_1.classNames)([
classes.indicator,
open && classes.indicator_open
]) }, IndicatorProps)));
}
if (checkbox) {
Indicator = ((0, jsx_runtime_1.jsx)(Checkbox, Object.assign({ size: 'small', checked: open }, IndicatorProps)));
}
if (indicatorPosition === 'start')
start.unshift(Indicator);
else if (indicatorPosition === 'end')
end.push(Indicator);
}
const MainProps = Object.assign({}, MainProps_);
if (!disabled) {
MainProps.onBlur = onBlur;
MainProps.onFocus = onFocus;
}
if (level > 0 && !noPadding) {
styles.root.marginInlineStart = `${theme.space.unit * 2.5}px`;
}
const children = (react_1.default.Children.toArray(children_).map((item) => (react_1.default.cloneElement(item, {
tonal: item.props.tonal !== undefined ? item.props.tonal : tonal,
color: item.props.color !== undefined ? item.props.color : color,
version: item.props.version !== undefined ? item.props.version : version,
line: item.props.line !== undefined ? item.props.line : line,
checkbox: item.props.checkbox !== undefined ? item.props.checkbox : checkbox,
IconArrow: item.props.IconArrow !== undefined ? item.props.IconArrow : IconArrow,
indicator: item.props.indicator !== undefined ? item.props.indicator : indicator,
indicatorPosition: item.props.indicatorPosition !== undefined ? item.props.indicatorPosition : indicatorPosition,
noExpand: item.props.noExpand !== undefined ? item.props.noExpand : noExpand,
noTransition: item.props.noTransition !== undefined ? item.props.noTransition : noTransition,
parentDisabled: item.props.parentDisabled !== undefined ? item.props.parentDisabled : parentDisabled || disabled,
level: level + 1
}))));
return ((0, jsx_runtime_1.jsxs)(Surface, Object.assign({ ref: item => {
if (ref) {
if ((0, utils_1.is)('function', ref))
ref(item);
else if (ref === null || ref === void 0 ? void 0 : ref.current)
ref.current = item;
}
refs.root.current = item;
}, tonal: tonal, color: color, version: version, gap: 0, align: 'unset', justify: 'unset', onKeyDown: onKeyDown, role: level === 0 ? 'tree' : 'treeitem', "aria-labelledby": refs.ids.middle, "aria-expanded": open, "aria-selected": selected, Component: Line, AdditionalProps: {
Component
}, className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Tree', theme) && [
'amaui-Tree-root',
children ? `amaui-Tree-children` : `amaui-Tree-empty`,
parentDisabled && `amaui-Tree-parent-disabled`,
disabled && `amaui-Tree-disabled`
],
className,
classes.root,
(level > 0 && line) && classes.line,
disabled && classes.disabled
]), style: Object.assign(Object.assign({}, styles.root), style) }, other, { children: [(0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1, tabIndex: (!disabled && !parentDisabled) ? 0 : -1, onClick: onClick, direction: 'row', align: 'center', justify: 'unset', role: (button && children) ? 'button' : undefined, Component: (button && children) ? 'button' : 'div' }, MainProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Tree', theme) && [
'amaui-Tree-main'
],
MainProps === null || MainProps === void 0 ? void 0 : MainProps.className,
classes.main,
button && classes.button,
(level > 0 && line) && classes.main_line
]) }, { children: [button && ((0, jsx_runtime_1.jsx)(Interaction, { selected: selected, pulse: focus })), !!start.length && ((0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 0, direction: 'row', align: 'center', justify: 'unset' }, StartProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Tree', theme) && [
'amaui-Tree-item',
'amaui-Tree-aside',
'amaui-Tree-start'
],
StartProps === null || StartProps === void 0 ? void 0 : StartProps.className,
classes.item,
classes.aside,
classes.start
]) }, { children: start.map((item, index) => (react_1.default.cloneElement(item, {
key: index
}))) }))), middle && ((0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 0, id: refs.ids.middle, Component: (0, utils_1.is)('simple', middle) ? Type : undefined }, MiddleProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Tree', theme) && [
'amaui-Tree-item',
'amaui-Tree-middle',
'amaui-Tree-end'
],
MiddleProps === null || MiddleProps === void 0 ? void 0 : MiddleProps.className,
classes.item,
classes.middle
]) }, { children: middle }))), !!end.length && ((0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 0, direction: 'row', align: 'center', justify: 'unset' }, EndProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Tree', theme) && [
'amaui-Tree-item',
'amaui-Tree-aside',
'amaui-Tree-end'
],
EndProps === null || EndProps === void 0 ? void 0 : EndProps.className,
classes.item,
classes.aside,
classes.end
]) }, { children: end.map((item, index) => (react_1.default.cloneElement(item, {
key: index
}))) })))] })), noExpand && children, !noExpand && children && ((0, jsx_runtime_1.jsx)(Expand, Object.assign({ in: open, parent: parent || refs.root.current, onTransition: (element, status) => {
refs.inProgressTransition.current = !['entered', 'removed'].includes(status);
} }, ExpandProps, { children: (0, jsx_runtime_1.jsx)(TransitionComponent, Object.assign({}, TransitionComponentProps, { children: (0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 0, align: 'unset', justify: 'unset', role: 'group' }, TreeProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Tree', theme) && [
'amaui-Tree-tree'
],
TreeProps === null || TreeProps === void 0 ? void 0 : TreeProps.className,
classes.tree
]) }, { children: children.map((item, index) => (react_1.default.cloneElement(item, {
key: index
}))) })) })) })))] })));
});
Tree.displayName = 'amaui-Tree';
exports.default = Tree;