@womp/kookie-ui 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components.css +538 -493
- package/dist/cjs/components/_internal/base-menu.utils.js +1 -1
- package/dist/cjs/components/_internal/base-menu.utils.js.map +3 -3
- package/dist/cjs/components/_internal/menu-context.js +1 -1
- package/dist/cjs/components/_internal/menu-context.js.map +3 -3
- package/dist/cjs/components/_internal/shell-bottom.d.ts +6 -7
- package/dist/cjs/components/_internal/shell-bottom.d.ts.map +1 -1
- package/dist/cjs/components/_internal/shell-bottom.js +1 -1
- package/dist/cjs/components/_internal/shell-bottom.js.map +4 -4
- package/dist/cjs/components/_internal/shell-handles.d.ts +9 -0
- package/dist/cjs/components/_internal/shell-handles.d.ts.map +1 -1
- package/dist/cjs/components/_internal/shell-handles.js +1 -1
- package/dist/cjs/components/_internal/shell-handles.js.map +3 -3
- package/dist/cjs/components/_internal/shell-inspector.d.ts +4 -6
- package/dist/cjs/components/_internal/shell-inspector.d.ts.map +1 -1
- package/dist/cjs/components/_internal/shell-inspector.js +1 -1
- package/dist/cjs/components/_internal/shell-inspector.js.map +4 -4
- package/dist/cjs/components/_internal/shell-pane.d.ts +70 -0
- package/dist/cjs/components/_internal/shell-pane.d.ts.map +1 -0
- package/dist/cjs/components/_internal/shell-pane.js +2 -0
- package/dist/cjs/components/_internal/shell-pane.js.map +7 -0
- package/dist/cjs/components/_internal/shell-resizable.d.ts +48 -0
- package/dist/cjs/components/_internal/shell-resizable.d.ts.map +1 -0
- package/dist/cjs/components/_internal/shell-resizable.js +2 -0
- package/dist/cjs/components/_internal/shell-resizable.js.map +7 -0
- package/dist/cjs/components/_internal/shell-resize.d.ts +11 -3
- package/dist/cjs/components/_internal/shell-resize.d.ts.map +1 -1
- package/dist/cjs/components/_internal/shell-resize.js +1 -1
- package/dist/cjs/components/_internal/shell-resize.js.map +2 -2
- package/dist/cjs/components/_internal/shell-rest.d.ts +27 -0
- package/dist/cjs/components/_internal/shell-rest.d.ts.map +1 -0
- package/dist/cjs/components/_internal/shell-rest.js +2 -0
- package/dist/cjs/components/_internal/shell-rest.js.map +7 -0
- package/dist/cjs/components/_internal/shell-sidebar.d.ts +7 -12
- package/dist/cjs/components/_internal/shell-sidebar.d.ts.map +1 -1
- package/dist/cjs/components/_internal/shell-sidebar.js +1 -1
- package/dist/cjs/components/_internal/shell-sidebar.js.map +4 -4
- package/dist/cjs/components/_internal/shell-store.d.ts +99 -0
- package/dist/cjs/components/_internal/shell-store.d.ts.map +1 -0
- package/dist/cjs/components/_internal/shell-store.js +2 -0
- package/dist/cjs/components/_internal/shell-store.js.map +7 -0
- package/dist/cjs/components/context-menu.js +1 -1
- package/dist/cjs/components/context-menu.js.map +3 -3
- package/dist/cjs/components/dropdown-menu.js +1 -1
- package/dist/cjs/components/dropdown-menu.js.map +3 -3
- package/dist/cjs/components/index.js +5 -5
- package/dist/cjs/components/index.js.map +4 -4
- package/dist/cjs/components/schemas/index.js +1 -1
- package/dist/cjs/components/schemas/index.js.map +3 -3
- package/dist/cjs/components/schemas/shell.schema.d.ts +277 -229
- package/dist/cjs/components/schemas/shell.schema.d.ts.map +1 -1
- package/dist/cjs/components/schemas/shell.schema.js +1 -1
- package/dist/cjs/components/schemas/shell.schema.js.map +3 -3
- package/dist/cjs/components/shell.context.d.ts +25 -114
- package/dist/cjs/components/shell.context.d.ts.map +1 -1
- package/dist/cjs/components/shell.context.js +1 -1
- package/dist/cjs/components/shell.context.js.map +4 -4
- package/dist/cjs/components/shell.d.ts +42 -21
- package/dist/cjs/components/shell.d.ts.map +1 -1
- package/dist/cjs/components/shell.hooks.d.ts +7 -23
- package/dist/cjs/components/shell.hooks.d.ts.map +1 -1
- package/dist/cjs/components/shell.hooks.js +1 -1
- package/dist/cjs/components/shell.hooks.js.map +4 -4
- package/dist/cjs/components/shell.js +1 -1
- package/dist/cjs/components/shell.js.map +4 -4
- package/dist/cjs/components/shell.types.d.ts +19 -2
- package/dist/cjs/components/shell.types.d.ts.map +1 -1
- package/dist/cjs/components/shell.types.js +1 -1
- package/dist/cjs/components/shell.types.js.map +3 -3
- package/dist/cjs/components/sidebar.js.map +3 -3
- package/dist/cjs/hooks/use-breakpoint.d.ts +5 -0
- package/dist/cjs/hooks/use-breakpoint.d.ts.map +1 -1
- package/dist/cjs/hooks/use-breakpoint.js +1 -1
- package/dist/cjs/hooks/use-breakpoint.js.map +3 -3
- package/dist/cjs/index.js +5 -5
- package/dist/cjs/index.js.map +4 -4
- package/dist/esm/{chunk-HJU4I34X.js → chunk-25X75TI7.js} +2 -2
- package/dist/esm/{chunk-4XKK32M4.js → chunk-26I257HE.js} +2 -2
- package/dist/esm/chunk-2EQWBT2S.js +2 -0
- package/dist/esm/chunk-2EQWBT2S.js.map +7 -0
- package/dist/esm/{chunk-GLERJXVS.js → chunk-2Q7BJ7YG.js} +2 -2
- package/dist/esm/{chunk-CJ27XP5Z.js → chunk-3AOFY2B4.js} +2 -2
- package/dist/esm/chunk-3J6AUDID.js +2 -0
- package/dist/esm/chunk-3J6AUDID.js.map +7 -0
- package/dist/esm/{chunk-7EWFBWBS.js → chunk-3PTSRBVY.js} +2 -2
- package/dist/esm/chunk-3XSB7YIM.js +2 -0
- package/dist/esm/{chunk-FMBECDL4.js.map → chunk-3XSB7YIM.js.map} +3 -3
- package/dist/esm/{chunk-O2U6RJTB.js → chunk-44JZYS7A.js} +2 -2
- package/dist/esm/{chunk-CTA5ODAO.js → chunk-4WU2WKUJ.js} +2 -2
- package/dist/esm/{chunk-KZWNGWIM.js → chunk-5M7STAH3.js} +2 -2
- package/dist/esm/{chunk-5WRCK4R7.js → chunk-5TAHT6VC.js} +2 -2
- package/dist/esm/{chunk-RNTCHVFI.js → chunk-6J6YX2VX.js} +2 -2
- package/dist/esm/{chunk-AGSSWWFI.js → chunk-7FKKGUHK.js} +2 -2
- package/dist/esm/{chunk-WHFJ4JUN.js → chunk-7NYODT3Z.js} +2 -2
- package/dist/esm/{chunk-NVDXXGVW.js → chunk-7PMMYHZV.js} +2 -2
- package/dist/esm/chunk-A2XVR7GL.js +2 -0
- package/dist/esm/chunk-A2XVR7GL.js.map +7 -0
- package/dist/esm/chunk-ADXZNG4F.js +2 -0
- package/dist/esm/chunk-ADXZNG4F.js.map +7 -0
- package/dist/esm/chunk-AGNIFHOE.js +2 -0
- package/dist/esm/chunk-AGNIFHOE.js.map +7 -0
- package/dist/esm/{chunk-KJUDZCYK.js → chunk-AIHQ3MVK.js} +2 -2
- package/dist/esm/{chunk-UBOOUDS4.js → chunk-AO32NT75.js} +2 -2
- package/dist/esm/chunk-BZZXXZ3O.js +2 -0
- package/dist/esm/chunk-BZZXXZ3O.js.map +7 -0
- package/dist/esm/{chunk-JDGJSNWT.js → chunk-C5RVO3C3.js} +2 -2
- package/dist/esm/{chunk-IHK3H2OM.js → chunk-CBNTPHYK.js} +2 -2
- package/dist/esm/{chunk-BBJUB52V.js → chunk-CRBOJ7N7.js} +2 -2
- package/dist/esm/{chunk-VHECAEUP.js → chunk-DCIQHXAR.js} +2 -2
- package/dist/esm/{chunk-43A5GUSI.js → chunk-EHBAK3LQ.js} +2 -2
- package/dist/esm/{chunk-K3UAS7RW.js → chunk-F3AXE27Q.js} +2 -2
- package/dist/esm/{chunk-KFR3CK24.js → chunk-FB3PD4Z3.js} +2 -2
- package/dist/esm/{chunk-MCPRXVKZ.js → chunk-FEAOFF77.js} +2 -2
- package/dist/esm/{chunk-VZSQATP6.js → chunk-G4YKBAZT.js} +2 -2
- package/dist/esm/{chunk-ECXGQQJB.js → chunk-GDAKJS64.js} +2 -2
- package/dist/esm/{chunk-VR7ZAFYN.js → chunk-GGSJXOKR.js} +2 -2
- package/dist/esm/chunk-GM7KMQDI.js +2 -0
- package/dist/esm/chunk-GMHA5CFH.js +2 -0
- package/dist/esm/chunk-GMHA5CFH.js.map +7 -0
- package/dist/esm/{chunk-CESYMTJQ.js → chunk-H4GR4262.js} +2 -2
- package/dist/esm/{chunk-WXQIIKWV.js → chunk-HBIF43PT.js} +2 -2
- package/dist/esm/chunk-HCNO7PX6.js +2 -0
- package/dist/esm/chunk-HCNO7PX6.js.map +7 -0
- package/dist/esm/{chunk-2264DHUW.js → chunk-HMSSFU6I.js} +2 -2
- package/dist/esm/chunk-HWQ3NTJP.js +2 -0
- package/dist/esm/chunk-HWQ3NTJP.js.map +7 -0
- package/dist/esm/{chunk-S5C5YRBS.js → chunk-IDUVJJYG.js} +2 -2
- package/dist/esm/{chunk-CIYF56YS.js → chunk-IK3MQHA5.js} +2 -2
- package/dist/esm/{chunk-CKMMUHKE.js → chunk-JDEBKA56.js} +2 -2
- package/dist/esm/{chunk-E67CIG6A.js → chunk-JDWCQ2XP.js} +2 -2
- package/dist/esm/{chunk-L3BWTV7I.js → chunk-JQSZF3E2.js} +2 -2
- package/dist/esm/{chunk-MEO7MJMQ.js → chunk-JQW4XYBS.js} +2 -2
- package/dist/esm/{chunk-KMPE7TJ6.js → chunk-JRFZ535T.js} +2 -2
- package/dist/esm/{chunk-CDG5WH4U.js → chunk-KEEPKI2X.js} +2 -2
- package/dist/esm/{chunk-GAV3NHYL.js → chunk-KV4SZP3F.js} +2 -2
- package/dist/esm/{chunk-FG7XM7KJ.js → chunk-LJCUPAOI.js} +2 -2
- package/dist/esm/{chunk-N4GTDLRD.js → chunk-MBCQA7UZ.js} +2 -2
- package/dist/esm/chunk-MM5IHQFM.js +2 -0
- package/dist/esm/{chunk-Y5RCH23Z.js → chunk-NQXRWBQM.js} +2 -2
- package/dist/esm/{chunk-CSKZZOI2.js → chunk-NTNMJX5M.js} +2 -2
- package/dist/esm/{chunk-V27ZAN3E.js → chunk-NV3P2CKH.js} +2 -2
- package/dist/esm/{chunk-4ME6O27S.js → chunk-O4CSXNST.js} +2 -2
- package/dist/esm/chunk-ODCVOXEV.js +2 -0
- package/dist/esm/{chunk-W2FOBR5Q.js → chunk-OEEF6KJG.js} +2 -2
- package/dist/esm/{chunk-ABSKRHVM.js → chunk-OJSOX3AX.js} +2 -2
- package/dist/esm/{chunk-JGLAE5G7.js → chunk-OQU2SKLN.js} +2 -2
- package/dist/esm/{chunk-PZ7OYATT.js → chunk-OTKQN2KY.js} +2 -2
- package/dist/esm/{chunk-QWVU2TW4.js → chunk-P27KV2LS.js} +2 -2
- package/dist/esm/{chunk-JUY7CBSL.js → chunk-PBFSBHBS.js} +2 -2
- package/dist/esm/{chunk-DSJY5RI3.js → chunk-PDUHBDFC.js} +2 -2
- package/dist/esm/{chunk-MTOLKA6S.js → chunk-POG3YABW.js} +2 -2
- package/dist/esm/chunk-PYHEBG5I.js +2 -0
- package/dist/esm/chunk-PYHEBG5I.js.map +7 -0
- package/dist/esm/{chunk-GO7OHBHW.js → chunk-PYXMGEO7.js} +2 -2
- package/dist/esm/{chunk-VNH7BJOA.js → chunk-QEGEUD4D.js} +2 -2
- package/dist/esm/chunk-QEL55MLF.js +2 -0
- package/dist/esm/{chunk-MS5J4MF6.js → chunk-QJVAS7AK.js} +2 -2
- package/dist/esm/chunk-ROSWI2CL.js +2 -0
- package/dist/esm/chunk-ROSWI2CL.js.map +7 -0
- package/dist/esm/{chunk-KCWESYMR.js → chunk-RY67WG3O.js} +2 -2
- package/dist/esm/{chunk-IFM4EMZB.js → chunk-TLGXIWAS.js} +2 -2
- package/dist/esm/{chunk-6FLLFCBU.js → chunk-UBSLEGQZ.js} +2 -2
- package/dist/esm/{chunk-VBI3AWPT.js → chunk-UNWPH3SO.js} +2 -2
- package/dist/esm/chunk-V5ZSDDVZ.js +2 -0
- package/dist/esm/chunk-V5ZSDDVZ.js.map +7 -0
- package/dist/esm/{chunk-X7V3V3W4.js → chunk-VTIL55SR.js} +2 -2
- package/dist/esm/{chunk-ALWNS44Q.js → chunk-W2LD2YE6.js} +2 -2
- package/dist/esm/{chunk-2I7QRVJ5.js → chunk-WGWUEU4K.js} +2 -2
- package/dist/esm/{chunk-EPTYNVCU.js → chunk-WIDJYVZF.js} +2 -2
- package/dist/esm/{chunk-OLAWVEAI.js → chunk-WJBOOAIO.js} +2 -2
- package/dist/esm/{chunk-7FC7HF76.js → chunk-WQCB7KSH.js} +2 -2
- package/dist/esm/{chunk-YBSRX63K.js → chunk-WZFVTC7P.js} +2 -2
- package/dist/esm/chunk-XDDKT4NF.js +2 -0
- package/dist/esm/{chunk-KFA53SVQ.js → chunk-YA5DF67M.js} +2 -2
- package/dist/esm/chunk-YA5DF67M.js.map +7 -0
- package/dist/esm/chunk-YAQBIO2B.js +2 -0
- package/dist/esm/chunk-YAQBIO2B.js.map +7 -0
- package/dist/esm/{chunk-OFUNVHZ5.js → chunk-YG66IRW4.js} +2 -2
- package/dist/esm/{chunk-WGYUWEQV.js → chunk-YVSM2LGS.js} +2 -2
- package/dist/esm/{chunk-4NTGF22C.js → chunk-Z7AZNMNX.js} +2 -2
- package/dist/esm/chunk-ZJ33QP5N.js +2 -0
- package/dist/esm/{chunk-OGXZHAQL.js → chunk-ZW26J2SA.js} +2 -2
- package/dist/esm/components/_internal/base-button.js +1 -1
- package/dist/esm/components/_internal/base-menu.utils.js +1 -1
- package/dist/esm/components/_internal/menu-context.js +1 -1
- package/dist/esm/components/_internal/shell-bottom.d.ts +6 -7
- package/dist/esm/components/_internal/shell-bottom.d.ts.map +1 -1
- package/dist/esm/components/_internal/shell-bottom.js +1 -1
- package/dist/esm/components/_internal/shell-handles.d.ts +9 -0
- package/dist/esm/components/_internal/shell-handles.d.ts.map +1 -1
- package/dist/esm/components/_internal/shell-handles.js +1 -1
- package/dist/esm/components/_internal/shell-inspector.d.ts +4 -6
- package/dist/esm/components/_internal/shell-inspector.d.ts.map +1 -1
- package/dist/esm/components/_internal/shell-inspector.js +1 -1
- package/dist/esm/components/_internal/shell-pane.d.ts +70 -0
- package/dist/esm/components/_internal/shell-pane.d.ts.map +1 -0
- package/dist/esm/components/_internal/shell-pane.js +2 -0
- package/dist/esm/components/_internal/shell-resizable.d.ts +48 -0
- package/dist/esm/components/_internal/shell-resizable.d.ts.map +1 -0
- package/dist/esm/components/_internal/shell-resizable.js +2 -0
- package/dist/esm/components/_internal/shell-resizable.js.map +7 -0
- package/dist/esm/components/_internal/shell-resize.d.ts +11 -3
- package/dist/esm/components/_internal/shell-resize.d.ts.map +1 -1
- package/dist/esm/components/_internal/shell-resize.js +1 -1
- package/dist/esm/components/_internal/shell-rest.d.ts +27 -0
- package/dist/esm/components/_internal/shell-rest.d.ts.map +1 -0
- package/dist/esm/components/_internal/shell-rest.js +2 -0
- package/dist/esm/components/_internal/shell-rest.js.map +7 -0
- package/dist/esm/components/_internal/shell-sidebar.d.ts +7 -12
- package/dist/esm/components/_internal/shell-sidebar.d.ts.map +1 -1
- package/dist/esm/components/_internal/shell-sidebar.js +1 -1
- package/dist/esm/components/_internal/shell-store.d.ts +99 -0
- package/dist/esm/components/_internal/shell-store.d.ts.map +1 -0
- package/dist/esm/components/_internal/shell-store.js +2 -0
- package/dist/esm/components/_internal/shell-store.js.map +7 -0
- package/dist/esm/components/accordion.js +1 -1
- package/dist/esm/components/alert-dialog.js +1 -1
- package/dist/esm/components/avatar.js +1 -1
- package/dist/esm/components/badge.js +1 -1
- package/dist/esm/components/blockquote.js +1 -1
- package/dist/esm/components/blockquote.props.js +1 -1
- package/dist/esm/components/box.js +1 -1
- package/dist/esm/components/button.js +1 -1
- package/dist/esm/components/callout.js +1 -1
- package/dist/esm/components/card.js +1 -1
- package/dist/esm/components/chatbar.js +1 -1
- package/dist/esm/components/checkbox-cards.js +1 -1
- package/dist/esm/components/checkbox-group.js +1 -1
- package/dist/esm/components/checkbox.js +1 -1
- package/dist/esm/components/code.js +1 -1
- package/dist/esm/components/code.props.js +1 -1
- package/dist/esm/components/combobox.js +1 -1
- package/dist/esm/components/container.js +1 -1
- package/dist/esm/components/context-menu.js +1 -1
- package/dist/esm/components/data-list.js +1 -1
- package/dist/esm/components/dialog.js +1 -1
- package/dist/esm/components/dropdown-menu.js +1 -1
- package/dist/esm/components/em.js +1 -1
- package/dist/esm/components/em.props.js +1 -1
- package/dist/esm/components/flex.js +1 -1
- package/dist/esm/components/grid.js +1 -1
- package/dist/esm/components/heading.js +1 -1
- package/dist/esm/components/heading.props.js +1 -1
- package/dist/esm/components/hover-card.js +1 -1
- package/dist/esm/components/icon-button.js +1 -1
- package/dist/esm/components/image.js +1 -1
- package/dist/esm/components/index.js +1 -1
- package/dist/esm/components/inset.js +1 -1
- package/dist/esm/components/kbd.js +1 -1
- package/dist/esm/components/link.js +1 -1
- package/dist/esm/components/link.props.js +1 -1
- package/dist/esm/components/navbar.js +1 -1
- package/dist/esm/components/popover.js +1 -1
- package/dist/esm/components/progress.js +1 -1
- package/dist/esm/components/quote.js +1 -1
- package/dist/esm/components/quote.props.js +1 -1
- package/dist/esm/components/radio-cards.js +1 -1
- package/dist/esm/components/radio-group.js +1 -1
- package/dist/esm/components/radio.js +1 -1
- package/dist/esm/components/schemas/index.js +1 -1
- package/dist/esm/components/schemas/shell.schema.d.ts +277 -229
- package/dist/esm/components/schemas/shell.schema.d.ts.map +1 -1
- package/dist/esm/components/schemas/shell.schema.js +1 -1
- package/dist/esm/components/scroll-area.js +1 -1
- package/dist/esm/components/section.js +1 -1
- package/dist/esm/components/segmented-control.js +1 -1
- package/dist/esm/components/select.js +1 -1
- package/dist/esm/components/separator.js +1 -1
- package/dist/esm/components/sheet.js +1 -1
- package/dist/esm/components/shell.context.d.ts +25 -114
- package/dist/esm/components/shell.context.d.ts.map +1 -1
- package/dist/esm/components/shell.context.js +1 -1
- package/dist/esm/components/shell.d.ts +42 -21
- package/dist/esm/components/shell.d.ts.map +1 -1
- package/dist/esm/components/shell.hooks.d.ts +7 -23
- package/dist/esm/components/shell.hooks.d.ts.map +1 -1
- package/dist/esm/components/shell.hooks.js +1 -1
- package/dist/esm/components/shell.js +1 -1
- package/dist/esm/components/shell.types.d.ts +19 -2
- package/dist/esm/components/shell.types.d.ts.map +1 -1
- package/dist/esm/components/shell.types.js +1 -1
- package/dist/esm/components/sidebar.js +1 -1
- package/dist/esm/components/skeleton.js +1 -1
- package/dist/esm/components/slider.js +1 -1
- package/dist/esm/components/spinner.js +1 -1
- package/dist/esm/components/strong.js +1 -1
- package/dist/esm/components/strong.props.js +1 -1
- package/dist/esm/components/switch.js +1 -1
- package/dist/esm/components/tab-nav.js +1 -1
- package/dist/esm/components/table.js +1 -1
- package/dist/esm/components/tabs.js +1 -1
- package/dist/esm/components/text-area.js +1 -1
- package/dist/esm/components/text-field.js +1 -1
- package/dist/esm/components/text.js +1 -1
- package/dist/esm/components/text.props.js +1 -1
- package/dist/esm/components/theme-panel.js +1 -1
- package/dist/esm/components/toggle-button.js +1 -1
- package/dist/esm/components/toggle-icon-button.js +1 -1
- package/dist/esm/components/toolbar.js +1 -1
- package/dist/esm/components/tooltip.js +1 -1
- package/dist/esm/components/user-card.js +1 -1
- package/dist/esm/components/virtual-menu.js +1 -1
- package/dist/esm/helpers/extract-props.js +1 -1
- package/dist/esm/helpers/get-margin-styles.js +1 -1
- package/dist/esm/helpers/get-responsive-styles.js +1 -1
- package/dist/esm/helpers/index.js +1 -1
- package/dist/esm/hooks/index.js +1 -1
- package/dist/esm/hooks/use-breakpoint.d.ts +5 -0
- package/dist/esm/hooks/use-breakpoint.d.ts.map +1 -1
- package/dist/esm/hooks/use-breakpoint.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/props/index.js +1 -1
- package/package.json +7 -2
- package/schemas/index.json +1655 -0
- package/schemas/shell-bottom.d.ts +2 -0
- package/schemas/shell-bottom.json +180 -76
- package/schemas/shell-content.d.ts +2 -0
- package/schemas/shell-content.json +11 -5
- package/schemas/shell-handle.d.ts +2 -0
- package/schemas/shell-handle.json +7 -5
- package/schemas/shell-header.d.ts +2 -0
- package/schemas/shell-header.json +9 -10
- package/schemas/shell-inspector.d.ts +2 -0
- package/schemas/shell-inspector.json +183 -79
- package/schemas/shell-panel.d.ts +2 -0
- package/schemas/shell-panel.json +180 -76
- package/schemas/shell-rail.d.ts +2 -0
- package/schemas/shell-rail.json +137 -64
- package/schemas/shell-root.d.ts +2 -0
- package/schemas/shell-root.json +11 -9
- package/schemas/shell-sidebar.d.ts +2 -0
- package/schemas/shell-sidebar.json +274 -85
- package/schemas/shell-trigger.d.ts +2 -0
- package/schemas/shell-trigger.json +29 -17
- package/src/components/_internal/shell-bottom.tsx +92 -361
- package/src/components/_internal/shell-handles.tsx +193 -108
- package/src/components/_internal/shell-inspector.tsx +93 -360
- package/src/components/_internal/shell-pane.tsx +283 -0
- package/src/components/_internal/shell-resizable.tsx +263 -0
- package/src/components/_internal/shell-resize.tsx +11 -3
- package/src/components/_internal/shell-rest.ts +45 -0
- package/src/components/_internal/shell-sidebar.tsx +130 -441
- package/src/components/_internal/shell-store.tsx +204 -0
- package/src/components/schemas/shell.schema.ts +162 -153
- package/src/components/shell.context.tsx +112 -124
- package/src/components/shell.css +637 -496
- package/src/components/shell.hooks.ts +12 -170
- package/src/components/shell.tsx +566 -1497
- package/src/components/shell.types.ts +22 -2
- package/src/hooks/use-breakpoint.ts +9 -0
- package/styles.css +538 -493
- package/dist/cjs/components/_internal/shell-prop-helpers.d.ts +0 -7
- package/dist/cjs/components/_internal/shell-prop-helpers.d.ts.map +0 -1
- package/dist/cjs/components/_internal/shell-prop-helpers.js +0 -2
- package/dist/cjs/components/_internal/shell-prop-helpers.js.map +0 -7
- package/dist/esm/chunk-2SZZ75RJ.js +0 -2
- package/dist/esm/chunk-2SZZ75RJ.js.map +0 -7
- package/dist/esm/chunk-4JQZUQY7.js +0 -2
- package/dist/esm/chunk-5LXFJMFB.js +0 -2
- package/dist/esm/chunk-5LXFJMFB.js.map +0 -7
- package/dist/esm/chunk-CECQNGUL.js +0 -2
- package/dist/esm/chunk-CECQNGUL.js.map +0 -7
- package/dist/esm/chunk-CEIK5U6C.js +0 -2
- package/dist/esm/chunk-CEIK5U6C.js.map +0 -7
- package/dist/esm/chunk-EE2IH2GL.js +0 -2
- package/dist/esm/chunk-EE2IH2GL.js.map +0 -7
- package/dist/esm/chunk-FMBECDL4.js +0 -2
- package/dist/esm/chunk-HSAG7C53.js +0 -2
- package/dist/esm/chunk-JJKQ7CGI.js +0 -2
- package/dist/esm/chunk-KFA53SVQ.js.map +0 -7
- package/dist/esm/chunk-KRDP5SQ7.js +0 -2
- package/dist/esm/chunk-KRDP5SQ7.js.map +0 -7
- package/dist/esm/chunk-M6DJRFJZ.js +0 -2
- package/dist/esm/chunk-M6DJRFJZ.js.map +0 -7
- package/dist/esm/chunk-MCQCG6AS.js +0 -2
- package/dist/esm/chunk-NIQT45PJ.js +0 -2
- package/dist/esm/chunk-NNO7M466.js +0 -2
- package/dist/esm/chunk-NNO7M466.js.map +0 -7
- package/dist/esm/chunk-SNHEJU2S.js +0 -2
- package/dist/esm/chunk-SNHEJU2S.js.map +0 -7
- package/dist/esm/chunk-TLWTUKKL.js +0 -2
- package/dist/esm/chunk-TLWTUKKL.js.map +0 -7
- package/dist/esm/chunk-XI5YXUCK.js +0 -2
- package/dist/esm/components/_internal/shell-prop-helpers.d.ts +0 -7
- package/dist/esm/components/_internal/shell-prop-helpers.d.ts.map +0 -1
- package/dist/esm/components/_internal/shell-prop-helpers.js +0 -2
- package/src/components/_internal/shell-prop-helpers.ts +0 -54
- /package/dist/esm/{chunk-HJU4I34X.js.map → chunk-25X75TI7.js.map} +0 -0
- /package/dist/esm/{chunk-4XKK32M4.js.map → chunk-26I257HE.js.map} +0 -0
- /package/dist/esm/{chunk-GLERJXVS.js.map → chunk-2Q7BJ7YG.js.map} +0 -0
- /package/dist/esm/{chunk-CJ27XP5Z.js.map → chunk-3AOFY2B4.js.map} +0 -0
- /package/dist/esm/{chunk-7EWFBWBS.js.map → chunk-3PTSRBVY.js.map} +0 -0
- /package/dist/esm/{chunk-O2U6RJTB.js.map → chunk-44JZYS7A.js.map} +0 -0
- /package/dist/esm/{chunk-CTA5ODAO.js.map → chunk-4WU2WKUJ.js.map} +0 -0
- /package/dist/esm/{chunk-KZWNGWIM.js.map → chunk-5M7STAH3.js.map} +0 -0
- /package/dist/esm/{chunk-5WRCK4R7.js.map → chunk-5TAHT6VC.js.map} +0 -0
- /package/dist/esm/{chunk-RNTCHVFI.js.map → chunk-6J6YX2VX.js.map} +0 -0
- /package/dist/esm/{chunk-AGSSWWFI.js.map → chunk-7FKKGUHK.js.map} +0 -0
- /package/dist/esm/{chunk-WHFJ4JUN.js.map → chunk-7NYODT3Z.js.map} +0 -0
- /package/dist/esm/{chunk-NVDXXGVW.js.map → chunk-7PMMYHZV.js.map} +0 -0
- /package/dist/esm/{chunk-KJUDZCYK.js.map → chunk-AIHQ3MVK.js.map} +0 -0
- /package/dist/esm/{chunk-UBOOUDS4.js.map → chunk-AO32NT75.js.map} +0 -0
- /package/dist/esm/{chunk-JDGJSNWT.js.map → chunk-C5RVO3C3.js.map} +0 -0
- /package/dist/esm/{chunk-IHK3H2OM.js.map → chunk-CBNTPHYK.js.map} +0 -0
- /package/dist/esm/{chunk-BBJUB52V.js.map → chunk-CRBOJ7N7.js.map} +0 -0
- /package/dist/esm/{chunk-VHECAEUP.js.map → chunk-DCIQHXAR.js.map} +0 -0
- /package/dist/esm/{chunk-43A5GUSI.js.map → chunk-EHBAK3LQ.js.map} +0 -0
- /package/dist/esm/{chunk-K3UAS7RW.js.map → chunk-F3AXE27Q.js.map} +0 -0
- /package/dist/esm/{chunk-KFR3CK24.js.map → chunk-FB3PD4Z3.js.map} +0 -0
- /package/dist/esm/{chunk-MCPRXVKZ.js.map → chunk-FEAOFF77.js.map} +0 -0
- /package/dist/esm/{chunk-VZSQATP6.js.map → chunk-G4YKBAZT.js.map} +0 -0
- /package/dist/esm/{chunk-ECXGQQJB.js.map → chunk-GDAKJS64.js.map} +0 -0
- /package/dist/esm/{chunk-VR7ZAFYN.js.map → chunk-GGSJXOKR.js.map} +0 -0
- /package/dist/esm/{chunk-4JQZUQY7.js.map → chunk-GM7KMQDI.js.map} +0 -0
- /package/dist/esm/{chunk-CESYMTJQ.js.map → chunk-H4GR4262.js.map} +0 -0
- /package/dist/esm/{chunk-WXQIIKWV.js.map → chunk-HBIF43PT.js.map} +0 -0
- /package/dist/esm/{chunk-2264DHUW.js.map → chunk-HMSSFU6I.js.map} +0 -0
- /package/dist/esm/{chunk-S5C5YRBS.js.map → chunk-IDUVJJYG.js.map} +0 -0
- /package/dist/esm/{chunk-CIYF56YS.js.map → chunk-IK3MQHA5.js.map} +0 -0
- /package/dist/esm/{chunk-CKMMUHKE.js.map → chunk-JDEBKA56.js.map} +0 -0
- /package/dist/esm/{chunk-E67CIG6A.js.map → chunk-JDWCQ2XP.js.map} +0 -0
- /package/dist/esm/{chunk-L3BWTV7I.js.map → chunk-JQSZF3E2.js.map} +0 -0
- /package/dist/esm/{chunk-MEO7MJMQ.js.map → chunk-JQW4XYBS.js.map} +0 -0
- /package/dist/esm/{chunk-KMPE7TJ6.js.map → chunk-JRFZ535T.js.map} +0 -0
- /package/dist/esm/{chunk-CDG5WH4U.js.map → chunk-KEEPKI2X.js.map} +0 -0
- /package/dist/esm/{chunk-GAV3NHYL.js.map → chunk-KV4SZP3F.js.map} +0 -0
- /package/dist/esm/{chunk-FG7XM7KJ.js.map → chunk-LJCUPAOI.js.map} +0 -0
- /package/dist/esm/{chunk-N4GTDLRD.js.map → chunk-MBCQA7UZ.js.map} +0 -0
- /package/dist/esm/{chunk-JJKQ7CGI.js.map → chunk-MM5IHQFM.js.map} +0 -0
- /package/dist/esm/{chunk-Y5RCH23Z.js.map → chunk-NQXRWBQM.js.map} +0 -0
- /package/dist/esm/{chunk-CSKZZOI2.js.map → chunk-NTNMJX5M.js.map} +0 -0
- /package/dist/esm/{chunk-V27ZAN3E.js.map → chunk-NV3P2CKH.js.map} +0 -0
- /package/dist/esm/{chunk-4ME6O27S.js.map → chunk-O4CSXNST.js.map} +0 -0
- /package/dist/esm/{chunk-HSAG7C53.js.map → chunk-ODCVOXEV.js.map} +0 -0
- /package/dist/esm/{chunk-W2FOBR5Q.js.map → chunk-OEEF6KJG.js.map} +0 -0
- /package/dist/esm/{chunk-ABSKRHVM.js.map → chunk-OJSOX3AX.js.map} +0 -0
- /package/dist/esm/{chunk-JGLAE5G7.js.map → chunk-OQU2SKLN.js.map} +0 -0
- /package/dist/esm/{chunk-PZ7OYATT.js.map → chunk-OTKQN2KY.js.map} +0 -0
- /package/dist/esm/{chunk-QWVU2TW4.js.map → chunk-P27KV2LS.js.map} +0 -0
- /package/dist/esm/{chunk-JUY7CBSL.js.map → chunk-PBFSBHBS.js.map} +0 -0
- /package/dist/esm/{chunk-DSJY5RI3.js.map → chunk-PDUHBDFC.js.map} +0 -0
- /package/dist/esm/{chunk-MTOLKA6S.js.map → chunk-POG3YABW.js.map} +0 -0
- /package/dist/esm/{chunk-GO7OHBHW.js.map → chunk-PYXMGEO7.js.map} +0 -0
- /package/dist/esm/{chunk-VNH7BJOA.js.map → chunk-QEGEUD4D.js.map} +0 -0
- /package/dist/esm/{chunk-MCQCG6AS.js.map → chunk-QEL55MLF.js.map} +0 -0
- /package/dist/esm/{chunk-MS5J4MF6.js.map → chunk-QJVAS7AK.js.map} +0 -0
- /package/dist/esm/{chunk-KCWESYMR.js.map → chunk-RY67WG3O.js.map} +0 -0
- /package/dist/esm/{chunk-IFM4EMZB.js.map → chunk-TLGXIWAS.js.map} +0 -0
- /package/dist/esm/{chunk-6FLLFCBU.js.map → chunk-UBSLEGQZ.js.map} +0 -0
- /package/dist/esm/{chunk-VBI3AWPT.js.map → chunk-UNWPH3SO.js.map} +0 -0
- /package/dist/esm/{chunk-X7V3V3W4.js.map → chunk-VTIL55SR.js.map} +0 -0
- /package/dist/esm/{chunk-ALWNS44Q.js.map → chunk-W2LD2YE6.js.map} +0 -0
- /package/dist/esm/{chunk-2I7QRVJ5.js.map → chunk-WGWUEU4K.js.map} +0 -0
- /package/dist/esm/{chunk-EPTYNVCU.js.map → chunk-WIDJYVZF.js.map} +0 -0
- /package/dist/esm/{chunk-OLAWVEAI.js.map → chunk-WJBOOAIO.js.map} +0 -0
- /package/dist/esm/{chunk-7FC7HF76.js.map → chunk-WQCB7KSH.js.map} +0 -0
- /package/dist/esm/{chunk-YBSRX63K.js.map → chunk-WZFVTC7P.js.map} +0 -0
- /package/dist/esm/{chunk-XI5YXUCK.js.map → chunk-XDDKT4NF.js.map} +0 -0
- /package/dist/esm/{chunk-OFUNVHZ5.js.map → chunk-YG66IRW4.js.map} +0 -0
- /package/dist/esm/{chunk-WGYUWEQV.js.map → chunk-YVSM2LGS.js.map} +0 -0
- /package/dist/esm/{chunk-4NTGF22C.js.map → chunk-Z7AZNMNX.js.map} +0 -0
- /package/dist/esm/{chunk-NIQT45PJ.js.map → chunk-ZJ33QP5N.js.map} +0 -0
- /package/dist/esm/{chunk-OGXZHAQL.js.map → chunk-ZW26J2SA.js.map} +0 -0
- /package/dist/esm/components/_internal/{shell-prop-helpers.js.map → shell-pane.js.map} +0 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { readBreakpoint, useBreakpoint } from '../../hooks/use-breakpoint.js';
|
|
5
|
+
import type { Breakpoint, PaneName, PresentationValue } from '../shell.types.js';
|
|
6
|
+
import {
|
|
7
|
+
constantOf,
|
|
8
|
+
notifyShellStore,
|
|
9
|
+
tableAttributes,
|
|
10
|
+
tableOf,
|
|
11
|
+
usePeeking,
|
|
12
|
+
useShellStore,
|
|
13
|
+
useStableKey,
|
|
14
|
+
warnOnce,
|
|
15
|
+
type OpenChangeReason,
|
|
16
|
+
type PaneEntry,
|
|
17
|
+
type PaneValue,
|
|
18
|
+
type Table,
|
|
19
|
+
} from './shell-store.js';
|
|
20
|
+
|
|
21
|
+
type ResponsiveValue = PaneValue | Partial<Record<Breakpoint, PaneValue>>;
|
|
22
|
+
|
|
23
|
+
export type UsePaneOptions = {
|
|
24
|
+
name: PaneName;
|
|
25
|
+
/** The component's display name, for warnings: `Inspector`, `Sidebar`, … */
|
|
26
|
+
label: string;
|
|
27
|
+
/** The prop names a warning should use: `open`/`defaultOpen`, or `state`/`defaultState`. */
|
|
28
|
+
propNames: { controlled: string; default: string };
|
|
29
|
+
id: string | undefined;
|
|
30
|
+
/** The controlled value. A responsive object is deprecated: it is resolved against the current breakpoint. */
|
|
31
|
+
controlled: ResponsiveValue | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* The uncontrolled default. A single value fixes where the pane starts. A
|
|
34
|
+
* responsive object leaves the pane untouched (`auto`), with that object as
|
|
35
|
+
* what it shows at each breakpoint.
|
|
36
|
+
*/
|
|
37
|
+
defaultValue: ResponsiveValue | undefined;
|
|
38
|
+
/** The pane's presentation at every breakpoint. Pass a memoised table. */
|
|
39
|
+
presentationTable: Table<PresentationValue>;
|
|
40
|
+
/** What an untouched pane shows where no default says otherwise. Pass a module-level function. */
|
|
41
|
+
builtIn: (presentation: PresentationValue) => PaneValue;
|
|
42
|
+
/** Reports a change a user made. Never called on mount or on a resize. */
|
|
43
|
+
onChange: ((value: PaneValue, reason: OpenChangeReason) => void) | undefined;
|
|
44
|
+
/** The value a toggle moves to. Defaults to open and closed in turn. */
|
|
45
|
+
toggleNext?: (current: PaneValue, defaultHere: PaneValue | undefined) => PaneValue;
|
|
46
|
+
onExpand: (() => void) | undefined;
|
|
47
|
+
onCollapse: (() => void) | undefined;
|
|
48
|
+
/** The pane's designed open width, published for the panes beside it. */
|
|
49
|
+
size: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type PaneController = ReturnType<typeof usePane>;
|
|
53
|
+
|
|
54
|
+
const isMap = (value: ResponsiveValue | undefined): value is Partial<Record<Breakpoint, PaneValue>> => typeof value === 'object' && value !== null;
|
|
55
|
+
|
|
56
|
+
/** The first value a responsive object states, smallest breakpoint first. */
|
|
57
|
+
function firstStated(map: Partial<Record<Breakpoint, PaneValue>>): PaneValue {
|
|
58
|
+
for (const bp of ['initial', 'xs', 'sm', 'md', 'lg', 'xl'] as const) {
|
|
59
|
+
const value = map[bp];
|
|
60
|
+
if (value !== undefined) return value;
|
|
61
|
+
}
|
|
62
|
+
return 'closed';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Everything the togglable panes share: their state, their registry entry and their callbacks. */
|
|
66
|
+
export function usePane(options: UsePaneOptions) {
|
|
67
|
+
const { name, label, propNames, presentationTable, builtIn } = options;
|
|
68
|
+
const store = useShellStore(`Shell.${label}`);
|
|
69
|
+
const generatedId = React.useId();
|
|
70
|
+
const id = options.id ?? `shell-${name}${generatedId}`;
|
|
71
|
+
|
|
72
|
+
const controlled = options.controlled !== undefined;
|
|
73
|
+
const controlledIsMap = isMap(options.controlled);
|
|
74
|
+
if (controlledIsMap) {
|
|
75
|
+
warnOnce(
|
|
76
|
+
`Shell.${label}: a responsive \`${propNames.controlled}\` is deprecated and is removed in 1.0. ` +
|
|
77
|
+
`Pass a boolean and decide it from your own state, or use \`${propNames.default}\` with a responsive object.`,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// A responsive controlled value is resolved the way a responsive default
|
|
82
|
+
// is: it becomes the table an untouched pane follows, so the stylesheet
|
|
83
|
+
// answers it at each breakpoint (right in the server HTML, with no
|
|
84
|
+
// callback on a crossing) and the app's prop is still the only writer.
|
|
85
|
+
const controlledMap = controlledIsMap ? (options.controlled as Partial<Record<Breakpoint, PaneValue>>) : undefined;
|
|
86
|
+
const autoSource = controlledMap ?? (isMap(options.defaultValue) ? options.defaultValue : undefined);
|
|
87
|
+
const autoKey = useStableKey(autoSource);
|
|
88
|
+
const [inner, setInner] = React.useState<'auto' | PaneValue>(() => (typeof options.defaultValue === 'string' ? options.defaultValue : 'auto'));
|
|
89
|
+
|
|
90
|
+
// What an untouched pane shows at each breakpoint: a responsive default
|
|
91
|
+
// where it states one, the pane's own default where it does not.
|
|
92
|
+
const autoTable = React.useMemo(
|
|
93
|
+
() => (controlledMap ? tableOf<PaneValue>(controlledMap, () => firstStated(controlledMap)) : tableOf<PaneValue>(autoSource, (bp) => builtIn(presentationTable[bp]))),
|
|
94
|
+
// `autoKey` stands for the responsive object, which is usually a new literal each render.
|
|
95
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
96
|
+
[autoKey, controlledIsMap, presentationTable, builtIn],
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
let state: 'auto' | PaneValue = inner;
|
|
100
|
+
if (controlled) state = controlledMap ? 'auto' : (options.controlled as PaneValue);
|
|
101
|
+
|
|
102
|
+
// Only a pane whose answer depends on the window subscribes to it, so a
|
|
103
|
+
// pane with one presentation and one default never re-renders on a resize.
|
|
104
|
+
const needsBreakpoint = constantOf(presentationTable) === undefined || (state === 'auto' && constantOf(autoTable) === undefined);
|
|
105
|
+
const { breakpoint, ready } = useBreakpoint(needsBreakpoint);
|
|
106
|
+
|
|
107
|
+
/** A table's value now: known without the window when it holds one value, else once the breakpoint is known. */
|
|
108
|
+
const now = <T,>(table: Table<T>): T | undefined => {
|
|
109
|
+
const constant = constantOf(table);
|
|
110
|
+
if (constant !== undefined) return constant;
|
|
111
|
+
return ready ? table[breakpoint] : undefined;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const value: PaneValue | undefined = state === 'auto' ? now(autoTable) : state;
|
|
115
|
+
const presentation = now(presentationTable);
|
|
116
|
+
const overlaying = presentation === 'overlay';
|
|
117
|
+
const shown = value === undefined ? undefined : value !== 'closed';
|
|
118
|
+
const overlayLive = shown === true && overlaying;
|
|
119
|
+
|
|
120
|
+
// Stable actions over the latest values, so the registry entry changes only
|
|
121
|
+
// when a fact it carries changes.
|
|
122
|
+
const defaultValue = options.defaultValue;
|
|
123
|
+
const latest = React.useRef({ state, value, autoTable, defaultValue, controlled, onChange: options.onChange, toggleNext: options.toggleNext });
|
|
124
|
+
React.useLayoutEffect(() => {
|
|
125
|
+
latest.current = { state, value, autoTable, defaultValue, controlled, onChange: options.onChange, toggleNext: options.toggleNext };
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* What the pane shows, and its default, at the window's breakpoint right
|
|
130
|
+
* now. Asked at the moment of an action rather than taken from the last
|
|
131
|
+
* render: a touched pane no longer follows the window, and a click can land
|
|
132
|
+
* before the mirror has resolved after hydration.
|
|
133
|
+
*/
|
|
134
|
+
const valueNow = React.useCallback((): PaneValue | undefined => {
|
|
135
|
+
const current = latest.current;
|
|
136
|
+
if (current.value !== undefined) return current.value;
|
|
137
|
+
return current.state === 'auto' ? current.autoTable[readBreakpoint()] : undefined;
|
|
138
|
+
}, []);
|
|
139
|
+
const defaultHereNow = React.useCallback((): PaneValue | undefined => {
|
|
140
|
+
const current = latest.current;
|
|
141
|
+
if (typeof current.defaultValue === 'string') return current.defaultValue;
|
|
142
|
+
return isMap(current.defaultValue) ? current.autoTable[readBreakpoint()] : undefined;
|
|
143
|
+
}, []);
|
|
144
|
+
|
|
145
|
+
const setValue = React.useCallback(
|
|
146
|
+
(next: PaneValue, reason: OpenChangeReason) => {
|
|
147
|
+
const current = latest.current;
|
|
148
|
+
if (valueNow() === next) return;
|
|
149
|
+
current.onChange?.(next, reason);
|
|
150
|
+
if (!current.controlled) setInner(next);
|
|
151
|
+
},
|
|
152
|
+
[valueNow],
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
const toggle = React.useCallback(
|
|
156
|
+
(reason: OpenChangeReason) => {
|
|
157
|
+
const current = latest.current;
|
|
158
|
+
const from = valueNow() ?? 'closed';
|
|
159
|
+
const next = current.toggleNext ? current.toggleNext(from, defaultHereNow()) : from === 'closed' ? 'open' : 'closed';
|
|
160
|
+
setValue(next, reason);
|
|
161
|
+
},
|
|
162
|
+
[setValue, valueNow, defaultHereNow],
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
// The pane's element, for the Root's containment and focus.
|
|
166
|
+
const elementRef = React.useRef<HTMLElement | null>(null);
|
|
167
|
+
const setElement = React.useCallback((node: HTMLElement | null) => {
|
|
168
|
+
elementRef.current = node;
|
|
169
|
+
}, []);
|
|
170
|
+
|
|
171
|
+
// Registration. A layout effect so a Trigger's aria attributes and the
|
|
172
|
+
// Root's containment are right before the browser paints.
|
|
173
|
+
React.useLayoutEffect(() => {
|
|
174
|
+
const entry: PaneEntry = {
|
|
175
|
+
name,
|
|
176
|
+
id,
|
|
177
|
+
el: elementRef.current,
|
|
178
|
+
value,
|
|
179
|
+
presentation,
|
|
180
|
+
presentationTable,
|
|
181
|
+
overlayLive,
|
|
182
|
+
size: options.size,
|
|
183
|
+
setValue,
|
|
184
|
+
toggle,
|
|
185
|
+
};
|
|
186
|
+
store.entries.set(name, entry);
|
|
187
|
+
notifyShellStore(store);
|
|
188
|
+
return () => {
|
|
189
|
+
if (store.entries.get(name) === entry) {
|
|
190
|
+
store.entries.delete(name);
|
|
191
|
+
notifyShellStore(store);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
}, [store, name, id, value, presentation, presentationTable, overlayLive, options.size, setValue, toggle]);
|
|
195
|
+
|
|
196
|
+
// onExpand/onCollapse fire when the pane's state changes and that changes
|
|
197
|
+
// whether it is shown: a user's toggle, or a controlled prop. Never on
|
|
198
|
+
// mount, and never because the window crossed a breakpoint.
|
|
199
|
+
const callbacks = React.useRef({ onExpand: options.onExpand, onCollapse: options.onCollapse });
|
|
200
|
+
React.useLayoutEffect(() => {
|
|
201
|
+
callbacks.current = { onExpand: options.onExpand, onCollapse: options.onCollapse };
|
|
202
|
+
});
|
|
203
|
+
const previous = React.useRef({ state, shown });
|
|
204
|
+
React.useEffect(() => {
|
|
205
|
+
const before = previous.current;
|
|
206
|
+
if (before.state !== state && before.shown !== undefined && shown !== undefined && before.shown !== shown) {
|
|
207
|
+
if (shown) callbacks.current.onExpand?.();
|
|
208
|
+
else callbacks.current.onCollapse?.();
|
|
209
|
+
}
|
|
210
|
+
previous.current = { state, shown };
|
|
211
|
+
}, [state, shown]);
|
|
212
|
+
|
|
213
|
+
// Development guards. Once per mount, not once per render.
|
|
214
|
+
React.useLayoutEffect(() => {
|
|
215
|
+
if (process.env.NODE_ENV === 'production') return;
|
|
216
|
+
if (options.controlled !== undefined && options.defaultValue !== undefined) {
|
|
217
|
+
console.error(`Shell.${label}: Do not pass both \`${propNames.controlled}\` and \`${propNames.default}\`. Choose one.`);
|
|
218
|
+
}
|
|
219
|
+
// Mount only: this is the once-per-mount guard.
|
|
220
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
221
|
+
}, []);
|
|
222
|
+
const wasControlled = React.useRef(controlled);
|
|
223
|
+
React.useEffect(() => {
|
|
224
|
+
if (process.env.NODE_ENV === 'production') return;
|
|
225
|
+
if (wasControlled.current !== controlled) {
|
|
226
|
+
console.warn(`Shell.${label}: Switching between controlled and uncontrolled \`${propNames.controlled}\` is not supported.`);
|
|
227
|
+
wasControlled.current = controlled;
|
|
228
|
+
}
|
|
229
|
+
}, [controlled, label, propNames.controlled]);
|
|
230
|
+
|
|
231
|
+
const peeking = usePeeking(store, name) && shown === false && !overlaying;
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
store,
|
|
235
|
+
id,
|
|
236
|
+
state,
|
|
237
|
+
value,
|
|
238
|
+
shown,
|
|
239
|
+
presentation,
|
|
240
|
+
overlaying,
|
|
241
|
+
overlayLive,
|
|
242
|
+
peeking,
|
|
243
|
+
ready,
|
|
244
|
+
breakpoint,
|
|
245
|
+
autoTable,
|
|
246
|
+
setValue,
|
|
247
|
+
toggle,
|
|
248
|
+
defaultHereNow,
|
|
249
|
+
setElement,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** The data attributes every togglable pane renders. */
|
|
254
|
+
export function paneAttributes(pane: PaneController, presentationAttributes: Record<string, string>) {
|
|
255
|
+
const { state, value, presentation, shown } = pane;
|
|
256
|
+
return {
|
|
257
|
+
...presentationAttributes,
|
|
258
|
+
'data-state': state === 'thin' ? 'open' : state,
|
|
259
|
+
'data-thin': state === 'thin' ? '' : undefined,
|
|
260
|
+
...(state === 'auto' ? tableAttributes('auto', pane.autoTable) : {}),
|
|
261
|
+
'data-presentation': presentation,
|
|
262
|
+
'data-mode': value === undefined ? undefined : value === 'closed' ? 'collapsed' : value === 'thin' ? 'thin' : 'expanded',
|
|
263
|
+
// Kept for stylesheets written against 0.7: set while a stacked pane is open.
|
|
264
|
+
'data-open': presentation === 'stacked' && shown ? '' : undefined,
|
|
265
|
+
'data-peek': pane.peeking ? '' : undefined,
|
|
266
|
+
} as const;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** A pane's own presentation, as a table and as the attributes the stylesheet reads. */
|
|
270
|
+
export function usePresentationTable(presentation: Parameters<typeof tableOf<PresentationValue>>[0], fallback: PresentationValue) {
|
|
271
|
+
const key = useStableKey(presentation);
|
|
272
|
+
const table = React.useMemo(
|
|
273
|
+
() => tableOf<PresentationValue>(presentation, () => fallback),
|
|
274
|
+
// `key` stands for `presentation`, which is usually a new literal each render.
|
|
275
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
276
|
+
[key, fallback],
|
|
277
|
+
);
|
|
278
|
+
// One value is the plain `data-presentation` the pane renders anyway; several
|
|
279
|
+
// are written per breakpoint, so the stylesheet can place the pane before
|
|
280
|
+
// any script runs.
|
|
281
|
+
const attributes = React.useMemo(() => (constantOf(table) === undefined ? tableAttributes('presentation', table) : ({} as Record<string, string>)), [table]);
|
|
282
|
+
return { table, attributes };
|
|
283
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { normalizeToPx } from '../../helpers/normalize-to-px.js';
|
|
5
|
+
import type { PaneName, PaneSizePersistence } from '../shell.types.js';
|
|
6
|
+
import type { PaneResizeContextValue } from './shell-resize.js';
|
|
7
|
+
|
|
8
|
+
export type SizeChangeMeta = { reason: 'init' | 'resize' | 'controlled' };
|
|
9
|
+
|
|
10
|
+
export type ResizableOptions = {
|
|
11
|
+
name: PaneName;
|
|
12
|
+
/** The pane's element id, which the handle names in `aria-controls`. */
|
|
13
|
+
elementId: string;
|
|
14
|
+
elementRef: React.RefObject<HTMLElement | null>;
|
|
15
|
+
cssVarName: string;
|
|
16
|
+
orientation: 'vertical' | 'horizontal';
|
|
17
|
+
edge: 'start' | 'end';
|
|
18
|
+
growth: (isRtl: boolean) => 1 | -1;
|
|
19
|
+
expandedSize: number;
|
|
20
|
+
minSize: number;
|
|
21
|
+
maxSize: number;
|
|
22
|
+
resizable: boolean;
|
|
23
|
+
collapsible: boolean;
|
|
24
|
+
size: number | string | undefined;
|
|
25
|
+
defaultSize: number | string | undefined;
|
|
26
|
+
onSizeChange: ((size: number, meta: SizeChangeMeta) => void) | undefined;
|
|
27
|
+
sizeUpdate: 'throttle' | 'debounce' | undefined;
|
|
28
|
+
sizeUpdateMs: number;
|
|
29
|
+
onResize: ((size: number) => void) | undefined;
|
|
30
|
+
onResizeStart: ((size: number) => void) | undefined;
|
|
31
|
+
onResizeEnd: ((size: number) => void) | undefined;
|
|
32
|
+
snapPoints: number[] | undefined;
|
|
33
|
+
snapTolerance: number | undefined;
|
|
34
|
+
collapseThreshold: number | undefined;
|
|
35
|
+
paneId: string | undefined;
|
|
36
|
+
persistence: PaneSizePersistence | undefined;
|
|
37
|
+
/** Whether the pane is presented as an overlay right now. An overlay keeps its designed size and persists nothing. */
|
|
38
|
+
overlaying: boolean;
|
|
39
|
+
/** The same question asked at effect time, for a pane whose presentation is learnt after its first render. */
|
|
40
|
+
overlayingNow: () => boolean;
|
|
41
|
+
requestCollapse: () => void;
|
|
42
|
+
requestToggle: () => void;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Clamps to [min, max]. When the two cross (an app passing a maximum computed
|
|
47
|
+
* from a narrow window below its fixed minimum), the minimum wins, as it did
|
|
48
|
+
* in 0.7.
|
|
49
|
+
*/
|
|
50
|
+
const clampTo = (value: number, min: number | undefined, max: number | undefined) => Math.max(min ?? value, Math.min(max ?? value, value));
|
|
51
|
+
|
|
52
|
+
/** Everything a resizable pane shares: size props, persistence, and the handle's context. */
|
|
53
|
+
export function useResizablePane(options: ResizableOptions): PaneResizeContextValue {
|
|
54
|
+
const { name, elementRef, cssVarName, orientation, minSize, maxSize, resizable, size, defaultSize, paneId, persistence } = options;
|
|
55
|
+
|
|
56
|
+
// The latest callbacks, so the size emitter does not change identity when a
|
|
57
|
+
// consumer passes an inline function. A controlled `size` is reported again
|
|
58
|
+
// only when the size, the minimum or the maximum changes.
|
|
59
|
+
const latest = React.useRef(options);
|
|
60
|
+
React.useLayoutEffect(() => {
|
|
61
|
+
latest.current = options;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const debounceRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
65
|
+
const throttleRef = React.useRef(0);
|
|
66
|
+
React.useEffect(
|
|
67
|
+
() => () => {
|
|
68
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
69
|
+
},
|
|
70
|
+
[],
|
|
71
|
+
);
|
|
72
|
+
const emitSizeChange = React.useCallback((value: number, meta: SizeChangeMeta) => {
|
|
73
|
+
const { onSizeChange, sizeUpdate, sizeUpdateMs } = latest.current;
|
|
74
|
+
if (!onSizeChange) return;
|
|
75
|
+
if (sizeUpdate === 'debounce') {
|
|
76
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
77
|
+
debounceRef.current = setTimeout(() => {
|
|
78
|
+
debounceRef.current = null;
|
|
79
|
+
latest.current.onSizeChange?.(value, meta);
|
|
80
|
+
}, sizeUpdateMs);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (sizeUpdate === 'throttle') {
|
|
84
|
+
const now = Date.now();
|
|
85
|
+
if (now - throttleRef.current < sizeUpdateMs) return;
|
|
86
|
+
throttleRef.current = now;
|
|
87
|
+
}
|
|
88
|
+
onSizeChange(value, meta);
|
|
89
|
+
}, []);
|
|
90
|
+
|
|
91
|
+
const toPx = React.useCallback((value: number | string | undefined) => normalizeToPx(value, orientation === 'vertical' ? 'horizontal' : 'vertical'), [orientation]);
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The one way a size reaches the pane: the size variable, and the value
|
|
95
|
+
* every handle of this pane announces. Once anything but `expandedSize` has
|
|
96
|
+
* written a size (a default, a controlled value, a persisted value or a
|
|
97
|
+
* resize), the pane owns that size and a new `expandedSize` leaves it alone.
|
|
98
|
+
*/
|
|
99
|
+
const ownedRef = React.useRef(false);
|
|
100
|
+
const writeSize = React.useCallback(
|
|
101
|
+
(value: number, own: boolean) => {
|
|
102
|
+
const el = elementRef.current;
|
|
103
|
+
if (!el) return;
|
|
104
|
+
el.style.setProperty(cssVarName, `${value}px`);
|
|
105
|
+
for (const handle of el.querySelectorAll(':scope > .rt-ShellResizer')) handle.setAttribute('aria-valuenow', String(Math.round(value)));
|
|
106
|
+
if (own) ownedRef.current = true;
|
|
107
|
+
},
|
|
108
|
+
[elementRef, cssVarName],
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
// expandedSize: the size until something else sets one. Declared first, so
|
|
112
|
+
// the effects below win on mount.
|
|
113
|
+
React.useLayoutEffect(() => {
|
|
114
|
+
if (!ownedRef.current) writeSize(options.expandedSize, false);
|
|
115
|
+
}, [options.expandedSize, writeSize]);
|
|
116
|
+
|
|
117
|
+
// defaultSize: applied once, on mount.
|
|
118
|
+
React.useLayoutEffect(() => {
|
|
119
|
+
if (size !== undefined || defaultSize === undefined) return;
|
|
120
|
+
const px = toPx(defaultSize);
|
|
121
|
+
if (typeof px !== 'number' || !Number.isFinite(px)) return;
|
|
122
|
+
const clamped = clampTo(px, minSize, maxSize);
|
|
123
|
+
writeSize(clamped, true);
|
|
124
|
+
emitSizeChange(clamped, { reason: 'init' });
|
|
125
|
+
// An uncontrolled initial value: applied on mount and never re-applied.
|
|
126
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
127
|
+
}, []);
|
|
128
|
+
|
|
129
|
+
// Controlled size. A drag stands until the app passes a different value.
|
|
130
|
+
// Not while the pane is an overlay: an overlay keeps its designed size, and
|
|
131
|
+
// an app's frame-sized limits (a maximum taken from the window) would
|
|
132
|
+
// otherwise squeeze the drawer and report the squeezed size back. The size
|
|
133
|
+
// is applied again when the pane returns to the frame.
|
|
134
|
+
React.useLayoutEffect(() => {
|
|
135
|
+
if (size === undefined || latest.current.overlayingNow()) return;
|
|
136
|
+
const px = toPx(size);
|
|
137
|
+
if (typeof px !== 'number' || !Number.isFinite(px)) return;
|
|
138
|
+
const clamped = clampTo(px, minSize, maxSize);
|
|
139
|
+
writeSize(clamped, true);
|
|
140
|
+
emitSizeChange(clamped, { reason: 'controlled' });
|
|
141
|
+
}, [size, minSize, maxSize, options.overlaying, toPx, writeSize, emitSizeChange]);
|
|
142
|
+
|
|
143
|
+
// A persistence adapter from `paneId` when none is given.
|
|
144
|
+
const adapter = React.useMemo<PaneSizePersistence | undefined>(() => {
|
|
145
|
+
if (!paneId || persistence) return persistence;
|
|
146
|
+
const key = `kookie-ui:shell:${name}:${paneId}`;
|
|
147
|
+
return {
|
|
148
|
+
load: () => {
|
|
149
|
+
if (typeof window === 'undefined') return undefined;
|
|
150
|
+
try {
|
|
151
|
+
const stored = window.localStorage.getItem(key);
|
|
152
|
+
return stored ? Number(stored) : undefined;
|
|
153
|
+
} catch (err) {
|
|
154
|
+
if (process.env.NODE_ENV !== 'production') console.warn(`Shell.${name}: failed to load persisted size`, err);
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
save: (value: number) => {
|
|
159
|
+
if (typeof window === 'undefined') return;
|
|
160
|
+
try {
|
|
161
|
+
window.localStorage.setItem(key, String(value));
|
|
162
|
+
} catch (err) {
|
|
163
|
+
if (process.env.NODE_ENV !== 'production') console.warn(`Shell.${name}: failed to save persisted size`, err);
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}, [name, paneId, persistence]);
|
|
168
|
+
|
|
169
|
+
// Persisted size, loaded in a layout effect and clamped, so a reload does
|
|
170
|
+
// not paint the default and then jump. Only where the pane is in the frame:
|
|
171
|
+
// an overlay keeps its designed size.
|
|
172
|
+
React.useLayoutEffect(() => {
|
|
173
|
+
if (!resizable || !adapter?.load || latest.current.overlayingNow()) return undefined;
|
|
174
|
+
let mounted = true;
|
|
175
|
+
const apply = (value: number | undefined) => {
|
|
176
|
+
if (!mounted || typeof value !== 'number' || !Number.isFinite(value)) return;
|
|
177
|
+
const clamped = clampTo(value, minSize, maxSize);
|
|
178
|
+
writeSize(clamped, true);
|
|
179
|
+
latest.current.onResize?.(clamped);
|
|
180
|
+
};
|
|
181
|
+
const loaded = adapter.load();
|
|
182
|
+
if (loaded instanceof Promise) {
|
|
183
|
+
loaded.then(apply).catch((err) => {
|
|
184
|
+
if (process.env.NODE_ENV !== 'production') console.warn(`Shell.${name}: failed to load persisted size`, err);
|
|
185
|
+
});
|
|
186
|
+
} else {
|
|
187
|
+
apply(loaded);
|
|
188
|
+
}
|
|
189
|
+
return () => {
|
|
190
|
+
mounted = false;
|
|
191
|
+
};
|
|
192
|
+
}, [resizable, adapter, options.overlaying, writeSize, minSize, maxSize, name]);
|
|
193
|
+
|
|
194
|
+
const onResize = React.useCallback((value: number) => latest.current.onResize?.(value), []);
|
|
195
|
+
const onResizeStart = React.useCallback((value: number) => {
|
|
196
|
+
// A resize makes the size the user's: a new expandedSize no longer moves it.
|
|
197
|
+
ownedRef.current = true;
|
|
198
|
+
latest.current.onResizeStart?.(value);
|
|
199
|
+
}, []);
|
|
200
|
+
const onResizeEnd = React.useCallback(
|
|
201
|
+
(value: number) => {
|
|
202
|
+
latest.current.onResizeEnd?.(value);
|
|
203
|
+
emitSizeChange(value, { reason: 'resize' });
|
|
204
|
+
adapter?.save?.(value);
|
|
205
|
+
},
|
|
206
|
+
[emitSizeChange, adapter],
|
|
207
|
+
);
|
|
208
|
+
const requestCollapse = React.useCallback(() => latest.current.requestCollapse(), []);
|
|
209
|
+
const requestToggle = React.useCallback(() => latest.current.requestToggle(), []);
|
|
210
|
+
|
|
211
|
+
return React.useMemo(
|
|
212
|
+
() => ({
|
|
213
|
+
containerRef: elementRef,
|
|
214
|
+
controls: options.elementId,
|
|
215
|
+
cssVarName,
|
|
216
|
+
minSize,
|
|
217
|
+
maxSize,
|
|
218
|
+
defaultSize: options.expandedSize,
|
|
219
|
+
orientation,
|
|
220
|
+
edge: options.edge,
|
|
221
|
+
growth: options.growth,
|
|
222
|
+
onResize,
|
|
223
|
+
onResizeStart,
|
|
224
|
+
onResizeEnd,
|
|
225
|
+
target: name,
|
|
226
|
+
collapsible: options.collapsible,
|
|
227
|
+
snapPoints: options.snapPoints,
|
|
228
|
+
snapTolerance: options.snapTolerance ?? 8,
|
|
229
|
+
collapseThreshold: options.collapseThreshold,
|
|
230
|
+
requestCollapse,
|
|
231
|
+
requestToggle,
|
|
232
|
+
}),
|
|
233
|
+
[
|
|
234
|
+
elementRef,
|
|
235
|
+
options.elementId,
|
|
236
|
+
cssVarName,
|
|
237
|
+
minSize,
|
|
238
|
+
maxSize,
|
|
239
|
+
options.expandedSize,
|
|
240
|
+
orientation,
|
|
241
|
+
options.edge,
|
|
242
|
+
options.growth,
|
|
243
|
+
onResize,
|
|
244
|
+
onResizeStart,
|
|
245
|
+
onResizeEnd,
|
|
246
|
+
name,
|
|
247
|
+
options.collapsible,
|
|
248
|
+
options.snapPoints,
|
|
249
|
+
options.snapTolerance,
|
|
250
|
+
options.collapseThreshold,
|
|
251
|
+
requestCollapse,
|
|
252
|
+
requestToggle,
|
|
253
|
+
],
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** Splits a pane's children into its handles and the rest. */
|
|
258
|
+
export function splitHandles(children: React.ReactNode, handleType: React.ElementType) {
|
|
259
|
+
const all = React.Children.toArray(children);
|
|
260
|
+
const handles = all.filter((el) => React.isValidElement(el) && el.type === handleType) as React.ReactElement[];
|
|
261
|
+
const content = all.filter((el) => !(React.isValidElement(el) && el.type === handleType));
|
|
262
|
+
return { handles, content };
|
|
263
|
+
}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import type { PaneName } from '../shell.types.js';
|
|
2
3
|
|
|
3
4
|
export interface PaneResizeContextValue {
|
|
4
|
-
containerRef: React.RefObject<
|
|
5
|
+
containerRef: React.RefObject<HTMLElement | null>;
|
|
6
|
+
/** The pane the handle resizes, for `aria-controls`. */
|
|
7
|
+
controls: string;
|
|
5
8
|
cssVarName: string;
|
|
6
9
|
minSize: number;
|
|
7
10
|
maxSize: number;
|
|
8
11
|
defaultSize: number;
|
|
9
12
|
orientation: 'vertical' | 'horizontal';
|
|
10
13
|
edge: 'start' | 'end';
|
|
11
|
-
|
|
14
|
+
/**
|
|
15
|
+
* +1 when moving the pointer toward the end of its axis grows the pane, -1
|
|
16
|
+
* when it shrinks it. Read once when a drag starts, with the pane's
|
|
17
|
+
* resolved direction, so no move pays for a style read.
|
|
18
|
+
*/
|
|
19
|
+
growth: (isRtl: boolean) => 1 | -1;
|
|
12
20
|
onResize?: (size: number) => void;
|
|
13
21
|
onResizeStart?: (size: number) => void;
|
|
14
22
|
onResizeEnd?: (size: number) => void;
|
|
15
|
-
target:
|
|
23
|
+
target: PaneName;
|
|
16
24
|
collapsible: boolean;
|
|
17
25
|
snapPoints?: number[];
|
|
18
26
|
snapTolerance: number;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Breakpoint, PresentationValue } from '../shell.types.js';
|
|
2
|
+
import type { PaneValue } from './shell-store.js';
|
|
3
|
+
|
|
4
|
+
type ResponsiveBoolean = boolean | Partial<Record<Breakpoint, boolean>>;
|
|
5
|
+
|
|
6
|
+
/** `open`/`defaultOpen` as the pane's own value type. */
|
|
7
|
+
export function toPaneValue(value: ResponsiveBoolean | undefined): PaneValue | Partial<Record<Breakpoint, PaneValue>> | undefined {
|
|
8
|
+
if (value === undefined) return undefined;
|
|
9
|
+
if (typeof value === 'boolean') return value ? 'open' : 'closed';
|
|
10
|
+
const map: Partial<Record<Breakpoint, PaneValue>> = {};
|
|
11
|
+
for (const [bp, open] of Object.entries(value) as Array<[Breakpoint, boolean | undefined]>) {
|
|
12
|
+
if (typeof open === 'boolean') map[bp] = open ? 'open' : 'closed';
|
|
13
|
+
}
|
|
14
|
+
return map;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Where an untouched navigation column rests: open in the frame or stacked
|
|
19
|
+
* over it, closed where it would be an overlay. An overlay is summoned,
|
|
20
|
+
* never ambient.
|
|
21
|
+
*/
|
|
22
|
+
export const navigationRest = (presentation: PresentationValue): PaneValue => (presentation === 'overlay' ? 'closed' : 'open');
|
|
23
|
+
|
|
24
|
+
/** Where an untouched detail pane rests: closed. Detail is asked for. */
|
|
25
|
+
export const detailRest = (): PaneValue => 'closed';
|
|
26
|
+
|
|
27
|
+
/** A pane anchored at the inline start grows as its end edge moves toward the inline end. */
|
|
28
|
+
export const startAnchoredGrowth = (isRtl: boolean): 1 | -1 => (isRtl ? -1 : 1);
|
|
29
|
+
|
|
30
|
+
/** A pane anchored at the inline end grows as its start edge moves toward the inline start. */
|
|
31
|
+
export const endAnchoredGrowth = (isRtl: boolean): 1 | -1 => (isRtl ? 1 : -1);
|
|
32
|
+
|
|
33
|
+
/** A pane anchored at the block end grows as its top edge moves up. */
|
|
34
|
+
export const bottomAnchoredGrowth = (): 1 | -1 => -1;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* `height` and `resizer` left PaneBaseProps in 0.8.0: no pane ever read them.
|
|
38
|
+
* A call site written against 0.7 can still pass them, so they are dropped
|
|
39
|
+
* here rather than reaching the DOM as invalid attributes.
|
|
40
|
+
*/
|
|
41
|
+
export function withoutRemovedPaneProps<T extends object>(props: T): T {
|
|
42
|
+
if (!('height' in props) && !('resizer' in props)) return props;
|
|
43
|
+
const { height: _height, resizer: _resizer, ...rest } = props as T & { height?: unknown; resizer?: unknown };
|
|
44
|
+
return rest as T;
|
|
45
|
+
}
|