UNPKG

@frontify/fondue

Version:
128 lines (127 loc) 5.53 kB
import { jsx as l, Fragment as D, jsxs as F } from "react/jsx-runtime"; import { useAccordion as N, useAccordionItem as P } from "@react-aria/accordion"; import { useFocusRing as O } from "@react-aria/focus"; import { mergeProps as R } from "@react-aria/utils"; import { Item as T } from "@react-stately/collections"; import { useTreeState as _ } from "@react-stately/tree"; import { Children as p, useRef as w, useEffect as L, isValidElement as v } from "react"; import { FOCUS_STYLE_NO_OFFSET as U } from "../../utilities/focusStyle.es.js"; import { merge as C } from "../../utilities/merge.es.js"; import { AccordionHeader as M } from "./AccordionHeader.es.js"; import { CollapsibleWrap as S } from "../CollapsibleWrap/CollapsibleWrap.es.js"; const V = "fondue-accordion", I = "fondue-accordion-item", j = ({ item: e, state: t, header: r, padding: o = !0, divider: i = !1, headerComponent: n = M, "data-test-id": c = I }) => { var d, u; const { active: s, ...f } = r, y = w(null), { buttonProps: h, regionProps: m } = P({ item: e }, t, y), A = t.expandedKeys.has(e.key), { isFocusVisible: k, focusProps: g } = O(); return /* @__PURE__ */ F( "div", { className: C([ k ? `${U} tw-relative tw-rounded` : "", i && "tw-divide-y tw-divide-black-10" ]), children: [ /* @__PURE__ */ l( "button", { type: "button", ...R(h, g), "data-test-id": c, ref: y, onClick: (a) => { r.onClick && r.onClick(), h.onClick && h.onClick(a); }, onKeyUp: (a) => { r.onClick && a.key === "Enter" && r.onClick(), h.onKeyUp && h.onKeyUp(a); }, className: "tw-w-full focus-visible:tw-outline-none", children: /* @__PURE__ */ l(n, { isOpen: A, ...f }) } ), /* @__PURE__ */ l(S, { isOpen: A, preventInitialAnimation: s, children: /* @__PURE__ */ l("div", { ...m, className: C([o && "tw-px-8 tw-pb-6", "tw-mt-2"]), children: (u = (d = e.props).children) == null ? void 0 : u.call(d) }) }) ] }, e.key ); }, W = (e) => { const t = p.map(e, (o, i) => { const { header: n, children: c } = o.props; return /* @__PURE__ */ l(T, { textValue: n.children, children: c ? () => c : null }, i); }), r = t.map((o) => o.key).filter((o, i) => { var n, c; return o && !!((c = (n = e[i]) == null ? void 0 : n.props.header) != null && c.active); }) || []; return { children: t, defaultExpandedKeys: r }; }, H = ({ children: e }) => p.toArray(e).reduce((t, r) => v(r) && !r.props.header ? (console.warn("Use `AccordionItem` as children of `Accordion` and set the `header` prop accordingly."), t) : (v(r) && t.push(r), t), []), Y = ({ children: e }) => /* @__PURE__ */ l(D, { children: e }); Y.displayName = "FondueAccordionItem"; const $ = (e) => { var r, o, i; const t = p.toArray(e); return ((i = (o = (r = t[t.length - 1]) == null ? void 0 : r.props) == null ? void 0 : o.header) == null ? void 0 : i.active) === !0; }, q = (e) => { const { divider: t = !0, border: r = !0, "data-test-id": o = V } = e, i = H(e), n = W(i), c = w(null), s = _(n), f = w({ firstRender: !0, childLength: p.toArray(e.children).length }), y = p.toArray(e.children).length; L(() => { $(e.children) && !f.current.firstRender && p.toArray(e.children).length > f.current.childLength && s.toggleKey(n.defaultExpandedKeys[n.defaultExpandedKeys.length - 1]), f.current = { firstRender: !1, childLength: p.toArray(e.children).length }; }, [n.defaultExpandedKeys, y, e.children, s]); const { // @react-aria prevents default action for onMouseDown as implemented here: https://github.com/adobe/react-spectrum/blob/e14523fedd93ac1a4ede355aed70988af572ae74/packages/%40react-aria/selection/src/useSelectableCollection.ts#L370 // This makes it impossible to edit or select text in input fields inside the accordion // onKeydown automatically navigates away from child elements, including dropdown menus etc. // Focus should only be passed if the accordion item itself is focused // eslint-disable-next-line @typescript-eslint/no-unused-vars accordionProps: { onMouseDown: h, onKeyDown: m, ...A } // @react-aria enable by default typeahead which result in an event fired up on keypress and select the section // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore } = N({ ...n, disallowTypeAhead: !0 }, s, c), g = { ...A, onKeyDown: (d) => { const u = d.target.dataset.key, a = s.selectionManager.focusedKey === u; u && a && (m == null || m(d)); } }; return /* @__PURE__ */ l( "div", { ...g, ref: c, "data-test-id": o, className: C([ t && "tw-divide-y tw-divide-black-10", r && "tw-border-t tw-border-b tw-border-black-10" ]), children: [...s.collection].map((d, u) => { const { header: a, padding: b, headerComponent: K, divider: x, "data-test-id": E = I } = i[u].props; return /* @__PURE__ */ l( j, { item: d, state: s, divider: x, header: a, padding: b, headerComponent: K, "data-test-id": E }, d.key ); }) } ); }; q.displayName = "FondueAccordion"; export { q as Accordion, Y as AccordionItem }; //# sourceMappingURL=Accordion.es.js.map