UNPKG

preact-arco-design

Version:

Arco Design React UI Library.

218 lines (188 loc) 7 kB
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]; } } return t; }; return __assign.apply(this, arguments); }; var __read = this && this.__read || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) { ar.push(r.value); } } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; import React, { forwardRef, useContext, useEffect, createContext, useRef, useMemo, useState } from "preact/compat"; import cs from "../_util/classNames"; import IconLeft from "../../icon/react-icon/IconLeft"; import IconRight from "../../icon/react-icon/IconRight"; import { ConfigContext } from "../ConfigProvider"; import ResizeBox from "../ResizeBox"; import { isArray, isNumber } from "../_util/is"; import ResponsiveObserve, { responsiveMap } from "../_util/responsiveObserve"; import useMergeValue from "../_util/hooks/useMergeValue"; export var SiderContext = createContext({ siderCollapsed: false, collapsedWidth: 64 }); var generateId = function () { var i = 0; return function (prefix) { if (prefix === void 0) { prefix = ''; } i += 1; return "".concat(prefix).concat(i); }; }(); function Sider(props, ref) { var _a; var _b; var children = props.children, className = props.className, style = props.style, _c = props.theme, theme = _c === void 0 ? 'light' : _c, trigger = props.trigger, reverseArrow = props.reverseArrow, _d = props.collapsedWidth, collapsedWidth = _d === void 0 ? 48 : _d, _e = props.width, width = _e === void 0 ? 200 : _e, collapsible = props.collapsible, resizeDirections = props.resizeDirections, onSiderMount = props.onSiderMount, onSiderUnmount = props.onSiderUnmount, breakpoint = props.breakpoint, onBreakpoint = props.onBreakpoint, onCollapse = props.onCollapse, _f = props.resizeBoxProps, resizeBoxProps = _f === void 0 ? {} : _f; var uniqueId = generateId('arco-sider-'); var getPrefixCls = useContext(ConfigContext).getPrefixCls; var prefixCls = getPrefixCls('layout-sider'); var _g = __read(useMergeValue(false, { value: props.collapsed }), 2), collapsed = _g[0], setCollapsed = _g[1]; // Parsing props width from number to string, to be used as css property value. // Using px as the default unit var propsWidth = isNumber(width) ? "".concat(width, "px") : String(width); var _h = __read(useState(propsWidth), 2), siderWidth = _h[0], setSiderWidth = _h[1]; var refResponsiveHandlerToken = useRef(null); // 提供给 ResponsiveHandler,使得其可以获得最新的 state 值 var refStateForResponsiveHandler = useRef(null); refStateForResponsiveHandler.current = { breakpoint: breakpoint, collapsed: collapsed, onCollapse: onCollapse, onBreakpoint: onBreakpoint }; useEffect(function () { onSiderMount && onSiderMount(uniqueId); if (collapsible && breakpoint in responsiveMap) { refResponsiveHandlerToken.current = ResponsiveObserve.subscribe(function (screens, breakpointChecked) { var _a = refStateForResponsiveHandler.current, breakpoint = _a.breakpoint, collapsed = _a.collapsed, onCollapse = _a.onCollapse, onBreakpoint = _a.onBreakpoint; if (!breakpointChecked || breakpointChecked === breakpoint) { var nextCollapsed = !screens[breakpoint]; if (nextCollapsed !== collapsed) { setCollapsed(nextCollapsed); onCollapse && onCollapse(nextCollapsed, 'responsive'); } onBreakpoint && onBreakpoint(nextCollapsed); } }); } return function () { onSiderUnmount && onSiderUnmount(uniqueId); if (refResponsiveHandlerToken.current) { ResponsiveObserve.unsubscribe(refResponsiveHandlerToken.current); } }; }, []); useEffect(function () { // Parsing collapsed width from number to string, to be used as css property value. // Using px as the default unit var _collapsedWidth = isNumber(collapsedWidth) ? "".concat(collapsedWidth, "px") : String(collapsedWidth); setSiderWidth(collapsed ? _collapsedWidth : propsWidth); }, [collapsed, propsWidth, collapsedWidth]); var resizable = resizeDirections && isArray(resizeDirections) || ((_b = resizeBoxProps.directions) === null || _b === void 0 ? void 0 : _b.length); var TagName = resizable ? ResizeBox : 'aside'; var renderTrigger = function renderTrigger() { var _a; var triggerIcon = trigger || (collapsed ? reverseArrow ? React.createElement(IconLeft, null) : React.createElement(IconRight, null) : reverseArrow ? React.createElement(IconRight, null) : React.createElement(IconLeft, null)); return collapsible && trigger !== null ? React.createElement("div", { style: { width: siderWidth }, className: cs("".concat(prefixCls, "-trigger"), (_a = {}, _a["".concat(prefixCls, "-trigger-light")] = theme === 'light', _a)), onClick: function onClick() { setCollapsed(!collapsed); onCollapse && onCollapse(!collapsed, 'clickTrigger'); } }, triggerIcon) : null; }; var resizeProps = useMemo(function () { if (resizable) { return __assign(__assign({ component: 'aside', onMoving: function onMoving(_, _a) { var currentWidth = _a.width; setSiderWidth(currentWidth); } }, resizeBoxProps), { width: siderWidth, directions: resizeDirections }); } return {}; }, [resizable, resizeDirections, siderWidth, resizeBoxProps]); return React.createElement(SiderContext.Provider, { value: { siderCollapsed: collapsed, collapsedWidth: collapsedWidth } }, React.createElement(TagName, __assign({ ref: ref, style: __assign({ width: siderWidth }, style), className: cs(prefixCls, (_a = {}, _a["".concat(prefixCls, "-light")] = theme === 'light', _a["".concat(prefixCls, "-has-trigger")] = trigger !== null && collapsible, _a["".concat(prefixCls, "-collapsed")] = collapsed, _a), className) }, resizeProps), React.createElement("div", { className: "".concat(prefixCls, "-children") }, children), renderTrigger())); } var SiderComponent = forwardRef(Sider); SiderComponent.defaultProps = { // private use sign: 'sider' }; SiderComponent.displayName = 'LayoutSider'; export default SiderComponent;