preact-arco-design
Version:
Arco Design React UI Library.
218 lines (188 loc) • 7 kB
JavaScript
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;