@ngrok/mantle 0.66.0 → 0.66.1
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/dist/accordion.d.ts +158 -154
- package/dist/accordion.js +1 -1
- package/dist/accordion.js.map +1 -1
- package/dist/alert-dialog.d.ts +282 -277
- package/dist/alert-dialog.js +1 -1
- package/dist/alert-dialog.js.map +1 -1
- package/dist/alert.d.ts +145 -138
- package/dist/alert.js +1 -1
- package/dist/alert.js.map +1 -1
- package/dist/anchor.d.ts +25 -22
- package/dist/anchor.js +1 -1
- package/dist/anchor.js.map +1 -1
- package/dist/as-child-XMVTepJu.d.ts +31 -0
- package/dist/badge.d.ts +29 -19
- package/dist/badge.js +1 -1
- package/dist/badge.js.map +1 -1
- package/dist/booleanish-CBGdPL3Q.js +2 -0
- package/dist/booleanish-CBGdPL3Q.js.map +1 -0
- package/dist/browser-only-jrBUqioz.js +2 -0
- package/dist/browser-only-jrBUqioz.js.map +1 -0
- package/dist/browser-only.d.ts +20 -15
- package/dist/browser-only.js +1 -2
- package/dist/button-CKL-3sIr.d.ts +175 -0
- package/dist/button-CRRPesae.js +2 -0
- package/dist/button-CRRPesae.js.map +1 -0
- package/dist/button-DA2p0_5F.js +2 -0
- package/dist/button-DA2p0_5F.js.map +1 -0
- package/dist/button.d.ts +4 -9
- package/dist/button.js +1 -2
- package/dist/calendar.d.ts +14 -8
- package/dist/calendar.js +1 -1
- package/dist/calendar.js.map +1 -1
- package/dist/card.d.ts +99 -97
- package/dist/card.js +1 -1
- package/dist/card.js.map +1 -1
- package/dist/checkbox.d.ts +14 -12
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/code-block.d.ts +254 -237
- package/dist/code-block.js +3 -3
- package/dist/code-block.js.map +1 -1
- package/dist/code.d.ts +5 -3
- package/dist/code.js +1 -1
- package/dist/code.js.map +1 -1
- package/dist/color.d.ts +2 -38
- package/dist/color.js +1 -1
- package/dist/color.js.map +1 -1
- package/dist/combobox.d.ts +172 -167
- package/dist/combobox.js +1 -1
- package/dist/combobox.js.map +1 -1
- package/dist/command.d.ts +234 -227
- package/dist/command.js +1 -1
- package/dist/command.js.map +1 -1
- package/dist/compose-refs-DeIsFv68.js +2 -0
- package/dist/compose-refs-DeIsFv68.js.map +1 -0
- package/dist/cx-bKromGBh.js +2 -0
- package/dist/cx-bKromGBh.js.map +1 -0
- package/dist/cx.d.ts +4 -2
- package/dist/cx.js +1 -2
- package/dist/data-table.d.ts +211 -184
- package/dist/data-table.js +1 -1
- package/dist/data-table.js.map +1 -1
- package/dist/deep-non-nullable-BLM3Gz0I.d.ts +8 -0
- package/dist/description-list.d.ts +61 -59
- package/dist/description-list.js +1 -1
- package/dist/description-list.js.map +1 -1
- package/dist/dialog-BuD_JQf_.d.ts +422 -0
- package/dist/dialog-CGBjHvo_.js +2 -0
- package/dist/dialog-CGBjHvo_.js.map +1 -0
- package/dist/dialog.d.ts +3 -410
- package/dist/dialog.js +1 -2
- package/dist/direction-DfrtFTny.js +2 -0
- package/dist/direction-DfrtFTny.js.map +1 -0
- package/dist/{direction-DHheuUag.d.ts → direction-deXpJFDZ.d.ts} +9 -7
- package/dist/dropdown-menu-CjOaj-Ap.js +2 -0
- package/dist/dropdown-menu-CjOaj-Ap.js.map +1 -0
- package/dist/dropdown-menu-D_ZoY1AH.d.ts +330 -0
- package/dist/dropdown-menu.d.ts +2 -325
- package/dist/dropdown-menu.js +1 -2
- package/dist/flag.d.ts +31 -22
- package/dist/flag.js +1 -1
- package/dist/flag.js.map +1 -1
- package/dist/hooks.d.ts +72 -59
- package/dist/hooks.js +1 -1
- package/dist/hooks.js.map +1 -1
- package/dist/hover-card.d.ts +97 -91
- package/dist/hover-card.js +1 -1
- package/dist/hover-card.js.map +1 -1
- package/dist/{icon-DXTMiV1L.d.ts → icon-B1XLv02t.d.ts} +11 -9
- package/dist/icon-B5oNYYrJ.js +2 -0
- package/dist/icon-B5oNYYrJ.js.map +1 -0
- package/dist/icon-button-2r6S3HVA.d.ts +98 -0
- package/dist/icon-button-D4e9-dq-.js +2 -0
- package/dist/icon-button-D4e9-dq-.js.map +1 -0
- package/dist/icon.d.ts +4 -4
- package/dist/icon.js +1 -2
- package/dist/icons.d.ts +54 -41
- package/dist/icons.js +1 -1
- package/dist/icons.js.map +1 -1
- package/dist/{in-view-aHeQHaUj.d.ts → in-view-CTQRT44m.d.ts} +29 -22
- package/dist/in-view-bPnaWEL4.js +2 -0
- package/dist/in-view-bPnaWEL4.js.map +1 -0
- package/dist/index-BLCvtjLi.d.ts +40 -0
- package/dist/index-DWqhfw9n.d.ts +103 -0
- package/dist/{button-group-BFnqgdtl.d.ts → index-ViSCOUrU.d.ts} +10 -8
- package/dist/index-s8rMcilU.d.ts +47 -0
- package/dist/input.d.ts +3 -100
- package/dist/input.js +1 -1
- package/dist/input.js.map +1 -1
- package/dist/is-input-BFR8yMM7.js +2 -0
- package/dist/is-input-BFR8yMM7.js.map +1 -0
- package/dist/kbd-pyj32aN4.js +2 -0
- package/dist/kbd-pyj32aN4.js.map +1 -0
- package/dist/kbd.d.ts +10 -4
- package/dist/kbd.js +1 -2
- package/dist/label.d.ts +8 -6
- package/dist/label.js +1 -1
- package/dist/label.js.map +1 -1
- package/dist/media-object.d.ts +70 -68
- package/dist/media-object.js +1 -1
- package/dist/media-object.js.map +1 -1
- package/dist/multi-select.d.ts +226 -218
- package/dist/multi-select.js +1 -1
- package/dist/multi-select.js.map +1 -1
- package/dist/pagination.d.ts +168 -164
- package/dist/pagination.js +1 -1
- package/dist/pagination.js.map +1 -1
- package/dist/popover.d.ts +119 -117
- package/dist/popover.js +1 -1
- package/dist/popover.js.map +1 -1
- package/dist/primitive-W5Izf14l.js +2 -0
- package/dist/primitive-W5Izf14l.js.map +1 -0
- package/dist/primitive-tuHqhoRE.d.ts +16 -0
- package/dist/progress.d.ts +175 -150
- package/dist/progress.js +1 -1
- package/dist/progress.js.map +1 -1
- package/dist/radio-group.d.ts +246 -230
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.js.map +1 -1
- package/dist/sandboxed-on-click.d.ts +36 -31
- package/dist/sandboxed-on-click.js +1 -1
- package/dist/sandboxed-on-click.js.map +1 -1
- package/dist/select-39Jfc1Cb.d.ts +265 -0
- package/dist/select-DZ2ztBkI.js +2 -0
- package/dist/select-DZ2ztBkI.js.map +1 -0
- package/dist/select.d.ts +2 -263
- package/dist/select.js +1 -2
- package/dist/separator-BcCNbHBg.js +2 -0
- package/dist/separator-BcCNbHBg.js.map +1 -0
- package/dist/separator.d.ts +28 -21
- package/dist/separator.js +1 -2
- package/dist/sheet.d.ts +319 -305
- package/dist/sheet.js +1 -1
- package/dist/sheet.js.map +1 -1
- package/dist/skeleton.d.ts +8 -6
- package/dist/skeleton.js +1 -1
- package/dist/skeleton.js.map +1 -1
- package/dist/slider.d.ts +48 -35
- package/dist/slider.js +1 -1
- package/dist/slider.js.map +1 -1
- package/dist/slot-DdnjeV2n.js +2 -0
- package/dist/slot-DdnjeV2n.js.map +1 -0
- package/dist/slot.d.ts +6 -4
- package/dist/slot.js +1 -2
- package/dist/sort-CfPsu1Gs.js +2 -0
- package/dist/sort-CfPsu1Gs.js.map +1 -0
- package/dist/split-button.d.ts +158 -162
- package/dist/split-button.js +1 -1
- package/dist/split-button.js.map +1 -1
- package/dist/svg-only-BVLlbQ4e.js +2 -0
- package/dist/svg-only-BVLlbQ4e.js.map +1 -0
- package/dist/{svg-only-Cp8Mu_sh.d.ts → svg-only-Dti1FvNV.d.ts} +11 -9
- package/dist/switch.d.ts +10 -8
- package/dist/switch.js +1 -1
- package/dist/switch.js.map +1 -1
- package/dist/table-BWMp12sl.js +2 -0
- package/dist/table-BWMp12sl.js.map +1 -0
- package/dist/table-Dpt192qt.d.ts +398 -0
- package/dist/table.d.ts +2 -396
- package/dist/table.js +1 -2
- package/dist/tabs.d.ts +110 -104
- package/dist/tabs.js +1 -1
- package/dist/tabs.js.map +1 -1
- package/dist/text-area.d.ts +10 -8
- package/dist/text-area.js +1 -1
- package/dist/text-area.js.map +1 -1
- package/dist/theme-provider-CbzLgte1.js +2 -0
- package/dist/theme-provider-CbzLgte1.js.map +1 -0
- package/dist/theme.d.ts +65 -38
- package/dist/theme.js +1 -2
- package/dist/{themes-Bi46K9ZW.d.ts → themes-ClppRAGt.d.ts} +4 -2
- package/dist/toast-B4gxB8U0.js +2 -0
- package/dist/toast-B4gxB8U0.js.map +1 -0
- package/dist/toast.d.ts +95 -87
- package/dist/toast.js +1 -2
- package/dist/tooltip.d.ts +78 -73
- package/dist/tooltip.js +1 -1
- package/dist/tooltip.js.map +1 -1
- package/dist/{chunk-W2YQRWR5.js → traffic-policy-file-QnF-2YkY.js} +2 -2
- package/dist/traffic-policy-file-QnF-2YkY.js.map +1 -0
- package/dist/types-884RJJqm.js +2 -0
- package/dist/types-884RJJqm.js.map +1 -0
- package/dist/{types-DehRoXC5.d.ts → types-DgXUgkpc.d.ts} +38 -36
- package/dist/types-Dh4BVhXC.d.ts +9 -0
- package/dist/types.d.ts +6 -49
- package/dist/types.js +1 -2
- package/dist/use-copy-to-clipboard-BEbQOKHc.js +2 -0
- package/dist/use-copy-to-clipboard-BEbQOKHc.js.map +1 -0
- package/dist/use-matches-media-query-BxTQ5f4i.js +2 -0
- package/dist/use-matches-media-query-BxTQ5f4i.js.map +1 -0
- package/dist/use-prefers-reduced-motion-BPlsKyCJ.js +2 -0
- package/dist/use-prefers-reduced-motion-BPlsKyCJ.js.map +1 -0
- package/dist/utils.d.ts +6 -5
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/dist/variant-props-UE-phTwh.d.ts +13 -0
- package/dist/with-style-props-D1QFTzj6.d.ts +29 -0
- package/package.json +6 -6
- package/dist/as-child-DJ7x3JFV.d.ts +0 -21
- package/dist/browser-only.js.map +0 -1
- package/dist/button-DLUUf_c-.d.ts +0 -173
- package/dist/button.js.map +0 -1
- package/dist/chunk-2FYR6IJV.js +0 -2
- package/dist/chunk-2FYR6IJV.js.map +0 -1
- package/dist/chunk-5VDCC3YW.js +0 -2
- package/dist/chunk-5VDCC3YW.js.map +0 -1
- package/dist/chunk-63ZAW25Z.js +0 -2
- package/dist/chunk-63ZAW25Z.js.map +0 -1
- package/dist/chunk-6J7D73WA.js +0 -2
- package/dist/chunk-6J7D73WA.js.map +0 -1
- package/dist/chunk-72TJUKMV.js +0 -1
- package/dist/chunk-72TJUKMV.js.map +0 -1
- package/dist/chunk-7MJQGBE4.js +0 -2
- package/dist/chunk-7MJQGBE4.js.map +0 -1
- package/dist/chunk-7YLII2US.js +0 -2
- package/dist/chunk-7YLII2US.js.map +0 -1
- package/dist/chunk-ADF5DAYG.js +0 -2
- package/dist/chunk-ADF5DAYG.js.map +0 -1
- package/dist/chunk-CBRSMQ26.js +0 -2
- package/dist/chunk-CBRSMQ26.js.map +0 -1
- package/dist/chunk-COQIVAQH.js +0 -2
- package/dist/chunk-COQIVAQH.js.map +0 -1
- package/dist/chunk-ELZLLG6G.js +0 -2
- package/dist/chunk-ELZLLG6G.js.map +0 -1
- package/dist/chunk-EVU5XGB4.js +0 -2
- package/dist/chunk-EVU5XGB4.js.map +0 -1
- package/dist/chunk-EYZYDUS2.js +0 -2
- package/dist/chunk-EYZYDUS2.js.map +0 -1
- package/dist/chunk-HKSO72E5.js +0 -2
- package/dist/chunk-HKSO72E5.js.map +0 -1
- package/dist/chunk-HL2HWYKP.js +0 -2
- package/dist/chunk-HL2HWYKP.js.map +0 -1
- package/dist/chunk-IVQ626TU.js +0 -2
- package/dist/chunk-IVQ626TU.js.map +0 -1
- package/dist/chunk-JQ5D5YZR.js +0 -2
- package/dist/chunk-JQ5D5YZR.js.map +0 -1
- package/dist/chunk-LBO5LEYM.js +0 -2
- package/dist/chunk-LBO5LEYM.js.map +0 -1
- package/dist/chunk-MLXONRJD.js +0 -2
- package/dist/chunk-MLXONRJD.js.map +0 -1
- package/dist/chunk-OHPGAB7U.js +0 -2
- package/dist/chunk-OHPGAB7U.js.map +0 -1
- package/dist/chunk-OP6JMBKJ.js +0 -2
- package/dist/chunk-OP6JMBKJ.js.map +0 -1
- package/dist/chunk-PFXFESEN.js +0 -2
- package/dist/chunk-PFXFESEN.js.map +0 -1
- package/dist/chunk-PNL7JOXI.js +0 -2
- package/dist/chunk-PNL7JOXI.js.map +0 -1
- package/dist/chunk-RED6SFAV.js +0 -2
- package/dist/chunk-RED6SFAV.js.map +0 -1
- package/dist/chunk-SBQHQ2SJ.js +0 -2
- package/dist/chunk-SBQHQ2SJ.js.map +0 -1
- package/dist/chunk-SGGOH2WW.js +0 -2
- package/dist/chunk-SGGOH2WW.js.map +0 -1
- package/dist/chunk-W2YQRWR5.js.map +0 -1
- package/dist/chunk-W5A5HSFE.js +0 -2
- package/dist/chunk-W5A5HSFE.js.map +0 -1
- package/dist/chunk-YPAUKPCE.js +0 -2
- package/dist/chunk-YPAUKPCE.js.map +0 -1
- package/dist/cx.js.map +0 -1
- package/dist/deep-non-nullable-SmpSvoSd.d.ts +0 -8
- package/dist/dialog.js.map +0 -1
- package/dist/dropdown-menu.js.map +0 -1
- package/dist/icon-button-CT71Ti9V.d.ts +0 -96
- package/dist/icon.js.map +0 -1
- package/dist/kbd.js.map +0 -1
- package/dist/primitive-CBR_XmVa.d.ts +0 -14
- package/dist/select.js.map +0 -1
- package/dist/separator.js.map +0 -1
- package/dist/slot.js.map +0 -1
- package/dist/table.js.map +0 -1
- package/dist/theme.js.map +0 -1
- package/dist/toast.js.map +0 -1
- package/dist/types-BuKAGhC-.d.ts +0 -7
- package/dist/types.js.map +0 -1
- package/dist/variant-props-oDo2u-We.d.ts +0 -11
- package/dist/with-style-props-VnLWm0Yd.d.ts +0 -27
package/dist/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-breakpoint.tsx","../src/hooks/use-callback-ref.tsx","../src/hooks/use-debounced-callback.tsx","../src/hooks/use-isomorphic-layout-effect.tsx","../src/hooks/use-random-stable-id.tsx","../src/hooks/use-scroll-behavior.tsx","../src/hooks/use-in-view.tsx","../src/hooks/use-undo-redo.tsx"],"sourcesContent":["import { useSyncExternalStore } from \"react\";\n\n/**\n * Tailwind CSS breakpoints in descending order (largest → smallest).\n *\n * These correspond to Tailwind’s default `theme.screens` config and are used\n * to determine the current viewport size.\n *\n * @see https://tailwindcss.com/docs/screens\n *\n * @example\n * \"2xl\" // ≥96rem (1536px)\n * \"xl\" // ≥80rem (1280px)\n * \"lg\" // ≥64rem (1024px)\n * \"md\" // ≥48rem (768px)\n * \"sm\" // ≥40rem (640px)\n * \"xs\" // ≥30rem (480px)\n * \"2xs\" // ≥22.5rem (360px)\n */\nconst tailwindBreakpoints = [\"2xl\", \"xl\", \"lg\", \"md\", \"sm\", \"xs\", \"2xs\"] as const;\n\n/**\n * A valid Tailwind CSS breakpoint identifier.\n *\n * @example\n * const bp: TailwindBreakpoint = \"md\"; // ≥48rem (768px)\n *\n * @example\n * \"2xl\" // ≥96rem (1536px)\n * \"xl\" // ≥80rem (1280px)\n * \"lg\" // ≥64rem (1024px)\n * \"md\" // ≥48rem (768px)\n * \"sm\" // ≥40rem (640px)\n * \"xs\" // ≥30rem (480px)\n * \"2xs\" // ≥22.5rem (360px)\n */\ntype TailwindBreakpoint = (typeof tailwindBreakpoints)[number];\n\n/**\n * Mantle’s breakpoint set, extending Tailwind’s with `\"default\"`.\n *\n * `\"default\"` represents the base (0px and up) viewport,\n * useful for defining fallbacks or mobile-first styles.\n *\n * @example\n * \"default\" // ≥0rem (0px)\n * \"2xs\" // ≥22.5rem (360px)\n * \"xs\" // ≥30rem (480px)\n * \"sm\" // ≥40rem (640px)\n * \"md\" // ≥48rem (768px)\n * \"lg\" // ≥64rem (1024px)\n * \"xl\" // ≥80rem (1280px)\n * \"2xl\" // ≥96rem (1536px)\n */\nconst breakpoints = [\"default\", ...tailwindBreakpoints] as const;\n\n/**\n * A valid Mantle breakpoint identifier.\n *\n * Includes Tailwind’s standard breakpoints plus `\"default\"` for 0px+.\n *\n * @example\n * const bp: Breakpoint = \"default\"; // ≥0px\n *\n * @example\n * \"default\" // ≥0rem (0px)\n * \"2xs\" // ≥22.5rem (360px)\n * \"xs\" // ≥30rem (480px)\n * \"sm\" // ≥40rem (640px)\n * \"md\" // ≥48rem (768px)\n * \"lg\" // ≥64rem (1024px)\n * \"xl\" // ≥80rem (1280px)\n * \"2xl\" // ≥96rem (1536px)\n */\ntype Breakpoint = (typeof breakpoints)[number];\n\n/**\n * React hook that returns the current breakpoint based on the viewport width.\n *\n * Uses a singleton subscription to a set of min-width media queries and returns\n * the largest matching breakpoint. Designed for React 18+ with\n * `useSyncExternalStore`.\n *\n * @returns {Breakpoint} The current breakpoint that matches the viewport width.\n *\n * @example\n * const breakpoint = useBreakpoint();\n * if (breakpoint === \"lg\") {\n * // Do something for large screens and above\n * }\n */\nfunction useBreakpoint(): Breakpoint {\n\treturn useSyncExternalStore(\n\t\tsubscribeToBreakpointChanges,\n\t\tgetCurrentBreakpointSnapshot,\n\t\t() => \"default\", // SSR fallback\n\t);\n}\n\n/**\n * React hook that returns true if the current viewport width is below the specified breakpoint.\n *\n * This hook uses `window.matchMedia` with a max-width media query and leverages\n * `useSyncExternalStore` to stay compliant with React's concurrent rendering model.\n *\n * @param {TailwindBreakpoint} breakpoint - The breakpoint to check against (e.g., \"md\", \"lg\").\n *\n * @returns {boolean} `true` if the viewport width is below the breakpoint, otherwise `false`.\n *\n * @example\n * // Check if viewport is below medium (768px)\n * const isBelowMd = useIsBelowBreakpoint(\"md\");\n */\nfunction useIsBelowBreakpoint(breakpoint: TailwindBreakpoint): boolean {\n\treturn useSyncExternalStore(\n\t\tcreateBelowBreakpointSubscribe(breakpoint),\n\t\tcreateBelowBreakpointGetSnapshot(breakpoint),\n\t\t() => false, // SSR fallback - assume desktop\n\t);\n}\n\nexport {\n\t//,\n\tbreakpoints,\n\tuseBreakpoint,\n\tuseIsBelowBreakpoint,\n};\n\nexport type {\n\t//,\n\tBreakpoint,\n\tTailwindBreakpoint,\n};\n\n/**\n * A CSS media query string representing a minimum width in `rem` units.\n *\n * @example\n * const query: MinWidthQuery = \"(min-width: 48rem)\";\n *\n * @private\n */\ntype MinWidthQuery = `(min-width: ${number}rem)`;\n\n/**\n * A CSS media query string representing a maximum width in `rem` units.\n *\n * @example\n * const query: MaxWidthQuery = \"(max-width: 47.99rem)\";\n *\n * @private\n */\ntype MaxWidthQuery = `(max-width: ${number}rem)`;\n\n/**\n * Precomputed min-width media query strings for each Tailwind breakpoint.\n *\n * Using constants avoids template string work in hot paths and ensures type\n * safety against the `MinWidthQuery` template literal type.\n *\n * @remarks\n * These are expressed in `rem`. If your CSS breakpoints are in `px`, consider\n * aligning units to avoid JS/CSS drift when `html{font-size}` changes.\n *\n * @private\n */\nconst breakpointQueries = {\n\t\"2xl\": \"(min-width: 96rem)\" as const,\n\txl: \"(min-width: 80rem)\" as const,\n\tlg: \"(min-width: 64rem)\" as const,\n\tmd: \"(min-width: 48rem)\" as const,\n\tsm: \"(min-width: 40rem)\" as const,\n\txs: \"(min-width: 30rem)\" as const,\n\t\"2xs\": \"(min-width: 22.5rem)\" as const,\n} as const satisfies Record<TailwindBreakpoint, MinWidthQuery>;\n\n/**\n * Precomputed max-width media query strings used by `useIsBelowBreakpoint`.\n *\n * The `-0.01rem` offset avoids overlap at exact boundaries.\n *\n * @private\n */\nconst belowBreakpointQueries = {\n\t\"2xl\": \"(max-width: 95.99rem)\" as const, // 96 - 0.01\n\txl: \"(max-width: 79.99rem)\" as const, // 80 - 0.01\n\tlg: \"(max-width: 63.99rem)\" as const, // 64 - 0.01\n\tmd: \"(max-width: 47.99rem)\" as const, // 48 - 0.01\n\tsm: \"(max-width: 39.99rem)\" as const, // 40 - 0.01\n\txs: \"(max-width: 29.99rem)\" as const, // 30 - 0.01\n\t\"2xs\": \"(max-width: 22.49rem)\" as const, // 22.5 - 0.01\n} as const satisfies Record<TailwindBreakpoint, MaxWidthQuery>;\n\n/**\n * Lazily-initialized cache of `MediaQueryList` objects for min-width queries.\n *\n * Initialized on first access to remain SSR-safe (no `window` at import time).\n *\n * @private\n */\nlet minWidthMQLs: Record<TailwindBreakpoint, MediaQueryList> | null = null;\n\n/**\n * Lazily-initialized cache of `MediaQueryList` objects for max-width queries.\n *\n * Used by `useIsBelowBreakpoint`. Also SSR-safe by lazy access.\n *\n * @private\n */\nlet maxWidthMQLs: Record<TailwindBreakpoint, MediaQueryList> | null = null;\n\n/**\n * Get (and lazily create) the cached `MediaQueryList` objects for min-width queries.\n *\n * @returns A record of `MediaQueryList` keyed by Tailwind breakpoint.\n * @private\n */\nfunction getMinWidthMQLs(): Record<TailwindBreakpoint, MediaQueryList> {\n\tif (!minWidthMQLs) {\n\t\tminWidthMQLs = {\n\t\t\t\"2xl\": window.matchMedia(breakpointQueries[\"2xl\"]),\n\t\t\txl: window.matchMedia(breakpointQueries.xl),\n\t\t\tlg: window.matchMedia(breakpointQueries.lg),\n\t\t\tmd: window.matchMedia(breakpointQueries.md),\n\t\t\tsm: window.matchMedia(breakpointQueries.sm),\n\t\t\txs: window.matchMedia(breakpointQueries.xs),\n\t\t\t\"2xs\": window.matchMedia(breakpointQueries[\"2xs\"]),\n\t\t};\n\t}\n\treturn minWidthMQLs;\n}\n\n/**\n * Get (and lazily create) the cached `MediaQueryList` for a specific max-width breakpoint.\n *\n * @param breakpoint - Tailwind breakpoint identifier (e.g., \"md\").\n * @returns The corresponding `MediaQueryList`.\n * @private\n */\nfunction getMaxWidthMQL(breakpoint: TailwindBreakpoint): MediaQueryList {\n\tif (!maxWidthMQLs) {\n\t\tmaxWidthMQLs = {\n\t\t\t\"2xl\": window.matchMedia(belowBreakpointQueries[\"2xl\"]),\n\t\t\txl: window.matchMedia(belowBreakpointQueries.xl),\n\t\t\tlg: window.matchMedia(belowBreakpointQueries.lg),\n\t\t\tmd: window.matchMedia(belowBreakpointQueries.md),\n\t\t\tsm: window.matchMedia(belowBreakpointQueries.sm),\n\t\t\txs: window.matchMedia(belowBreakpointQueries.xs),\n\t\t\t\"2xs\": window.matchMedia(belowBreakpointQueries[\"2xs\"]),\n\t\t};\n\t}\n\treturn maxWidthMQLs[breakpoint];\n}\n\n/**\n * Current breakpoint value used by the singleton store backing `useBreakpoint`.\n *\n * Initialized to `\"default\"` and updated on media-query change events.\n *\n * @private\n */\nlet currentBreakpointValue: Breakpoint = \"default\";\n\n/**\n * Set of component listeners subscribed to the singleton breakpoint store.\n *\n * Each listener is invoked when the current breakpoint value changes.\n *\n * @private\n */\nconst breakpointListeners = new Set<() => void>();\n\n/**\n * Flag indicating whether global media-query listeners are currently attached.\n *\n * Prevents duplicate registrations and enables full teardown when unused.\n *\n * @private\n */\nlet breakpointSubscriptionActive = false;\n\n/**\n * Compute the current breakpoint by checking cached min-width MQLs\n * from largest to smallest.\n *\n * @returns {Breakpoint} The largest matching breakpoint, or `\"default\"`.\n * @private\n */\nfunction getCurrentBreakpoint(): Breakpoint {\n\tconst mqls = getMinWidthMQLs();\n\tfor (const breakpoint of tailwindBreakpoints) {\n\t\tif (mqls[breakpoint].matches) {\n\t\t\treturn breakpoint;\n\t\t}\n\t}\n\treturn \"default\";\n}\n\n/**\n * Update the current breakpoint value and notify all listeners.\n *\n * Uses `requestAnimationFrame` to coalesce rapid resize events and minimize\n * re-renders during active window resizing.\n *\n * @private\n */\nlet breakpointUpdatePending = false;\nfunction updateCurrentBreakpoint() {\n\tif (!breakpointUpdatePending) {\n\t\tbreakpointUpdatePending = true;\n\t\trequestAnimationFrame(() => {\n\t\t\tbreakpointUpdatePending = false;\n\t\t\tconst newBreakpoint = getCurrentBreakpoint();\n\t\t\tif (newBreakpoint !== currentBreakpointValue) {\n\t\t\t\tcurrentBreakpointValue = newBreakpoint;\n\t\t\t\tfor (const listener of breakpointListeners) {\n\t\t\t\t\tlistener();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * Subscribe a component to breakpoint changes (singleton pattern).\n *\n * Ensures only one set of MQL listeners exists app-wide. Also reconciles the\n * `useSyncExternalStore` initial snapshot/subscribe race by invoking the\n * subscriber once on mount.\n *\n * @param callback - Listener invoked when the breakpoint value may have changed.\n * @returns Cleanup function to unsubscribe the listener.\n * @private\n */\nfunction subscribeToBreakpointChanges(callback: () => void) {\n\tbreakpointListeners.add(callback);\n\n\t// Attach global listeners once\n\tif (!breakpointSubscriptionActive) {\n\t\tbreakpointSubscriptionActive = true;\n\t\tconst mqls = getMinWidthMQLs();\n\n\t\t// Initialize current value synchronously\n\t\tcurrentBreakpointValue = getCurrentBreakpoint();\n\n\t\t// Attach listeners to all breakpoint MQLs\n\t\tfor (const mql of Object.values(mqls)) {\n\t\t\tmql.addEventListener(\"change\", updateCurrentBreakpoint);\n\t\t}\n\t}\n\n\t// Reconcile initial getSnapshot vs subscribe ordering\n\tcallback();\n\n\t// Cleanup\n\treturn () => {\n\t\tbreakpointListeners.delete(callback);\n\n\t\t// Tear down global listeners when no one is listening\n\t\tif (breakpointListeners.size === 0 && breakpointSubscriptionActive) {\n\t\t\tbreakpointSubscriptionActive = false;\n\t\t\tconst mqls = getMinWidthMQLs();\n\t\t\tfor (const mql of Object.values(mqls)) {\n\t\t\t\tmql.removeEventListener(\"change\", updateCurrentBreakpoint);\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Return the current breakpoint value from the singleton store.\n *\n * Used as the `getSnapshot` for `useSyncExternalStore`.\n *\n * @returns {Breakpoint} The latest computed breakpoint.\n * @private\n */\nfunction getCurrentBreakpointSnapshot(): Breakpoint {\n\treturn currentBreakpointValue;\n}\n\n/**\n * Cached `subscribe` functions keyed by breakpoint.\n *\n * Without caching, `useSyncExternalStore` receives a new function reference on\n * every render, causing it to tear down and re-attach the MQL listener each\n * time — the primary source of resize sluggishness.\n *\n * @private\n */\nconst belowBreakpointSubscribeCache = new Map<\n\tTailwindBreakpoint,\n\t(callback: () => void) => () => void\n>();\n\n/**\n * Get (or create and cache) a `subscribe` function for a specific \"below\" breakpoint.\n *\n * Uses a cached `MediaQueryList` and rAF-throttled change handler to avoid\n * bursty updates during resize.\n *\n * @param breakpoint - Tailwind breakpoint identifier (e.g., \"lg\").\n * @returns A stable `subscribe` function suitable for `useSyncExternalStore`.\n * @private\n */\nfunction createBelowBreakpointSubscribe(breakpoint: TailwindBreakpoint) {\n\tlet cached = belowBreakpointSubscribeCache.get(breakpoint);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\tcached = (callback: () => void) => {\n\t\tconst mediaQuery = getMaxWidthMQL(breakpoint);\n\n\t\t// rAF throttle the change callback during active resize\n\t\tlet pending = false;\n\t\tconst onChange = () => {\n\t\t\tif (!pending) {\n\t\t\t\tpending = true;\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tpending = false;\n\t\t\t\t\tcallback();\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tmediaQuery.addEventListener(\"change\", onChange);\n\t\treturn () => {\n\t\t\tmediaQuery.removeEventListener(\"change\", onChange);\n\t\t};\n\t};\n\n\tbelowBreakpointSubscribeCache.set(breakpoint, cached);\n\treturn cached;\n}\n\n/**\n * Cached `getSnapshot` functions keyed by breakpoint.\n *\n * Ensures `useSyncExternalStore` receives a referentially stable function,\n * preventing unnecessary subscription churn.\n *\n * @private\n */\nconst belowBreakpointSnapshotCache = new Map<TailwindBreakpoint, () => boolean>();\n\n/**\n * Get (or create and cache) a `getSnapshot` function for a specific \"below\" breakpoint.\n *\n * Uses the cached `MediaQueryList` for the target breakpoint.\n *\n * @param breakpoint - Tailwind breakpoint identifier (e.g., \"lg\").\n * @returns A stable function that returns `true` when the viewport is below the breakpoint.\n * @private\n */\nfunction createBelowBreakpointGetSnapshot(breakpoint: TailwindBreakpoint) {\n\tlet cached = belowBreakpointSnapshotCache.get(breakpoint);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\tcached = () => {\n\t\tconst mediaQuery = getMaxWidthMQL(breakpoint);\n\t\treturn mediaQuery.matches;\n\t};\n\n\tbelowBreakpointSnapshotCache.set(breakpoint, cached);\n\treturn cached;\n}\n","import { useEffect, useMemo, useRef } from \"react\";\n\n/**\n * Returns a memoized callback that will always refer to the latest callback\n * passed to the hook.\n *\n * This is useful when you want to pass a callback which may or may not be\n * memoized (have a stable identity) to a child component that will be updated\n * without causing the child component to re-render.\n */\nfunction useCallbackRef<T extends (...args: unknown[]) => unknown>(callback: T | undefined): T {\n\tconst callbackRef = useRef(callback);\n\n\tuseEffect(() => {\n\t\tcallbackRef.current = callback;\n\t});\n\n\treturn useMemo(() => ((...args) => callbackRef.current?.(...args)) as T, []);\n}\n\nexport {\n\t//,\n\tuseCallbackRef,\n};\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { useCallbackRef } from \"./use-callback-ref.js\";\n\ntype Options = {\n\t/**\n\t * The delay in milliseconds to wait before calling the callback.\n\t */\n\twaitMs: number;\n};\n\n/**\n * Create a debounced version of a callback function.\n *\n * It allows you to delay the execution of a function until a certain period of\n * inactivity has passed (the `options.waitMs`), which can be useful for limiting rapid\n * invocations of a function (like in search inputs or button clicks)\n *\n * Note: The debounced callback will always refer to the latest callback passed\n * even without memoization, so it's stable and safe to use in dependency arrays.\n */\nfunction useDebouncedCallback<T extends (...args: unknown[]) => unknown>(\n\tcallbackFn: T,\n\toptions: Options,\n) {\n\tconst stableCallbackFn = useCallbackRef(callbackFn);\n\tconst debounceTimerRef = useRef(0);\n\tuseEffect(() => () => window.clearTimeout(debounceTimerRef.current), []);\n\n\treturn useCallback(\n\t\t(...args: Parameters<T>) => {\n\t\t\twindow.clearTimeout(debounceTimerRef.current);\n\t\t\tdebounceTimerRef.current = window.setTimeout(() => stableCallbackFn(...args), options.waitMs);\n\t\t},\n\t\t[stableCallbackFn, options.waitMs],\n\t);\n}\n\nexport {\n\t//,\n\tuseDebouncedCallback,\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\n/**\n * useIsomorphicLayoutEffect is a hook that uses useLayoutEffect on the client and useEffect on the server.\n */\nexport const useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n","import { useMemo } from \"react\";\n\n/**\n * Hook to generate a random, stable id.\n * This is similar to `useId`, but generates a stable id client side which can also\n * be used for css selectors and element ids.\n */\nconst useRandomStableId = (prefix = \"mantle\") => useMemo(() => randomStableId(prefix), [prefix]);\n\nexport {\n\t//,\n\tuseRandomStableId,\n};\n\nfunction randomStableId(prefix = \"mantle\") {\n\tconst _prefix = prefix.trim() || \"mantle\";\n\treturn [_prefix, randomPostfix()].join(\"-\");\n}\n\nfunction randomPostfix() {\n\treturn Math.random().toString(36).substring(2, 9);\n}\n","import { useMemo } from \"react\";\nimport { usePrefersReducedMotion } from \"./use-prefers-reduced-motion.js\";\n\n/**\n * `scroll-behavior` values:\n *\n * - `\"auto\"` — scrolling happens instantly (no animation).\n * - `\"smooth\"` — scrolling animates smoothly using a user-agent–defined easing and duration.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior#values\n */\ntype ScrollBehavior = \"auto\" | \"smooth\";\n\n/**\n * Returns a `ScrollBehavior` that respects the user's motion preference via `usePrefersReducedMotion`.\n *\n * - When `usePrefersReducedMotion()` is `true`, returns `\"auto\"` (no animated scroll).\n * - Otherwise returns `\"smooth\"`.\n *\n * Use this with `window.scrollTo`, `Element.scrollIntoView`, etc. It prevents\n * smooth-scrolling for users who opt out of motion and avoids SSR “first paint”\n * animations thanks to the hook’s conservative server default.\n *\n * @example\n * // Scroll to top\n * const behavior = useScrollBehavior();\n * window.scrollTo({ top: 0, behavior });\n *\n * @example\n * // Bring a section into view\n * const behavior = useScrollBehavior();\n * sectionRef.current?.scrollIntoView({ behavior, block: \"start\" });\n *\n * @see {@link usePrefersReducedMotion}\n * @see CSS `scroll-behavior` property (values: `\"auto\"`, `\"smooth\"`).\n */\nexport function useScrollBehavior(): ScrollBehavior {\n\tconst prefersReducedMotion = usePrefersReducedMotion();\n\n\treturn useMemo(() => (prefersReducedMotion ? \"auto\" : \"smooth\"), [prefersReducedMotion]);\n}\n","\"use client\";\n\nimport { type RefObject, useEffect, useState } from \"react\";\nimport type { InViewOptions, MarginType } from \"../utils/in-view.js\";\nimport { inView } from \"../utils/in-view.js\";\n\n/**\n * Options for the `useInView` hook.\n */\ntype UseInViewOptions = {\n\t/**\n\t * A ref to a scrollable container element to use as the intersection root.\n\t * Defaults to the browser viewport.\n\t */\n\troot?: RefObject<Element | null>;\n\n\t/**\n\t * Expand or contract the detected area from each side of the root's bounding box.\n\t * Uses the same syntax as the CSS `margin` shorthand (e.g. `\"10px\"`, `\"10% 20px\"`).\n\t */\n\tmargin?: MarginType;\n\n\t/**\n\t * How much of the element must be visible before it is considered in view.\n\t * - `\"some\"` (default): Any part of the element is visible.\n\t * - `\"all\"`: The entire element is visible.\n\t * - `number`: An intersection ratio between `0` and `1` (e.g. `0.5` for 50%).\n\t */\n\tamount?: \"some\" | \"all\" | number;\n\n\t/**\n\t * If `true`, stop observing once the element enters the viewport for the\n\t * first time. Useful for one-shot entrance animations.\n\t * Defaults to `false`.\n\t */\n\tonce?: boolean;\n\n\t/**\n\t * The initial visibility state returned before the observer has attached.\n\t * Defaults to `false`.\n\t */\n\tinitial?: boolean;\n};\n\n/**\n * React hook that tracks whether a DOM element is visible within the viewport\n * (or a scrollable container) using the `IntersectionObserver` API.\n *\n * @param ref - A ref attached to the element to observe.\n * @param options - Options controlling the scroll root, margin, threshold,\n * initial state, and one-time detection.\n * @returns `true` if the element is currently in view, otherwise `false`.\n *\n * @example\n * // Basic usage\n * const ref = useRef<HTMLDivElement>(null);\n * const isInView = useInView(ref);\n *\n * return <div ref={ref}>{isInView ? \"Visible!\" : \"Hidden\"}</div>;\n *\n * @example\n * // Trigger once when the element first enters the viewport\n * const ref = useRef<HTMLDivElement>(null);\n * const isInView = useInView(ref, { once: true });\n *\n * return (\n * <div\n * ref={ref}\n * style={{ opacity: isInView ? 1 : 0, transition: \"opacity 0.5s\" }}\n * />\n * );\n *\n * @example\n * // Require 50% of the element to be visible\n * const ref = useRef<HTMLDivElement>(null);\n * const isInView = useInView(ref, { amount: 0.5 });\n */\nfunction useInView(\n\tref: RefObject<Element | null>,\n\t{ root, margin, amount, once = false, initial = false }: UseInViewOptions = {},\n): boolean {\n\tconst [isInView, setInView] = useState(initial);\n\n\tuseEffect(() => {\n\t\tif (!ref.current || (once && isInView)) {\n\t\t\treturn;\n\t\t}\n\n\t\tfunction onEnter() {\n\t\t\tsetInView(true);\n\t\t\treturn once ? undefined : () => setInView(false);\n\t\t}\n\n\t\tconst options: InViewOptions = {\n\t\t\troot: (root && root.current) || undefined,\n\t\t\tmargin,\n\t\t\tamount,\n\t\t};\n\n\t\treturn inView(ref.current, onEnter, options);\n\t\t/**\n\t\t * Intentionally omit `isInView` from deps. The effect must only re-run\n\t\t * when the observation parameters change, not when visibility changes.\n\t\t * Including `isInView` would restart the observer (disconnect + reconnect)\n\t\t * on every enter/leave event, causing wasteful churn for the common\n\t\t * `once=false` case.\n\t\t */\n\t\t// oxlint-disable-next-line react-hooks/exhaustive-deps\n\t}, [root, ref, margin, once, amount]);\n\n\treturn isInView;\n}\n\nexport { useInView };\nexport type { UseInViewOptions };\n","import { useCallback, useMemo, useReducer } from \"react\";\n\ntype UndoRedoState<T> = {\n\tundoStack: T[];\n\tredoStack: T[];\n};\n\ntype UndoRedoAction<T> =\n\t| { type: \"push\"; snapshot: T }\n\t| { type: \"undo\"; current: T }\n\t| { type: \"redo\"; current: T };\n\nfunction undoRedoReducer<T>(state: UndoRedoState<T>, action: UndoRedoAction<T>): UndoRedoState<T> {\n\tswitch (action.type) {\n\t\tcase \"push\": {\n\t\t\treturn {\n\t\t\t\tundoStack: [...state.undoStack, action.snapshot],\n\t\t\t\tredoStack: [],\n\t\t\t};\n\t\t}\n\t\tcase \"undo\": {\n\t\t\tif (state.undoStack.length === 0) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\tconst undoStack = state.undoStack.slice(0, -1);\n\t\t\tconst previous = state.undoStack[state.undoStack.length - 1];\n\t\t\tif (previous === undefined) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tundoStack,\n\t\t\t\tredoStack: [...state.redoStack, action.current],\n\t\t\t};\n\t\t}\n\t\tcase \"redo\": {\n\t\t\tif (state.redoStack.length === 0) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\tconst redoStack = state.redoStack.slice(0, -1);\n\t\t\tconst next = state.redoStack[state.redoStack.length - 1];\n\t\t\tif (next === undefined) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tundoStack: [...state.undoStack, action.current],\n\t\t\t\tredoStack,\n\t\t\t};\n\t\t}\n\t}\n}\n\ntype UseUndoRedoReturn<T> = {\n\t/** Whether there are actions to undo. */\n\tcanUndo: boolean;\n\t/** Whether there are actions to redo. */\n\tcanRedo: boolean;\n\t/** Push a snapshot onto the undo stack. Clears the redo stack. */\n\tpush: (snapshot: T) => void;\n\t/** Pop the last snapshot from the undo stack. Returns `undefined` if empty. */\n\tundo: (current: T) => T | undefined;\n\t/** Pop the last snapshot from the redo stack. Returns `undefined` if empty. */\n\tredo: (current: T) => T | undefined;\n};\n\n/**\n * A generic undo/redo hook backed by a reducer.\n *\n * Maintains two stacks (undo and redo). Call `push` before mutating state\n * to snapshot the current value. Call `undo`/`redo` with the current value\n * to swap it with the previous/next snapshot.\n *\n * @example\n * ```tsx\n * const { push, undo, redo, canUndo, canRedo } = useUndoRedo<string[]>();\n *\n * function removeItem(item: string) {\n * push([...items]); // snapshot before mutation\n * setItems(items.filter((i) => i !== item));\n * }\n *\n * function handleKeyDown(event: KeyboardEvent) {\n * if ((event.metaKey || event.ctrlKey) && event.key === \"z\" && !event.shiftKey) {\n * const previous = undo(items);\n * if (previous) setItems(previous);\n * }\n * if ((event.metaKey || event.ctrlKey) && (event.shiftKey && event.key === \"z\" || event.key === \"y\")) {\n * const next = redo(items);\n * if (next) setItems(next);\n * }\n * }\n * ```\n */\nfunction useUndoRedo<T>(): UseUndoRedoReturn<T> {\n\tconst [state, dispatch] = useReducer(undoRedoReducer<T>, {\n\t\tundoStack: [],\n\t\tredoStack: [],\n\t});\n\n\tconst push = useCallback((snapshot: T) => {\n\t\tdispatch({ type: \"push\", snapshot });\n\t}, []);\n\n\tconst undo = useCallback(\n\t\t(current: T): T | undefined => {\n\t\t\tconst previous = state.undoStack[state.undoStack.length - 1];\n\t\t\tif (previous === undefined) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tdispatch({ type: \"undo\", current });\n\t\t\treturn previous;\n\t\t},\n\t\t[state.undoStack],\n\t);\n\n\tconst redo = useCallback(\n\t\t(current: T): T | undefined => {\n\t\t\tconst next = state.redoStack[state.redoStack.length - 1];\n\t\t\tif (next === undefined) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tdispatch({ type: \"redo\", current });\n\t\t\treturn next;\n\t\t},\n\t\t[state.redoStack],\n\t);\n\n\treturn useMemo(\n\t\t() => ({\n\t\t\tcanUndo: state.undoStack.length > 0,\n\t\t\tcanRedo: state.redoStack.length > 0,\n\t\t\tpush,\n\t\t\tundo,\n\t\t\tredo,\n\t\t}),\n\t\t[state.undoStack.length, state.redoStack.length, push, undo, redo],\n\t);\n}\n\nexport {\n\t//,\n\tuseUndoRedo,\n};\n\nexport type {\n\t//,\n\tUseUndoRedoReturn,\n};\n"],"mappings":"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","names":["useSyncExternalStore","tailwindBreakpoints","breakpoints","useBreakpoint","subscribeToBreakpointChanges","getCurrentBreakpointSnapshot","useIsBelowBreakpoint","breakpoint","createBelowBreakpointSubscribe","createBelowBreakpointGetSnapshot","breakpointQueries","belowBreakpointQueries","minWidthMQLs","maxWidthMQLs","getMinWidthMQLs","getMaxWidthMQL","breakpoint","currentBreakpointValue","breakpointListeners","breakpointSubscriptionActive","getCurrentBreakpoint","mqls","tailwindBreakpoints","breakpointUpdatePending","updateCurrentBreakpoint","newBreakpoint","listener","subscribeToBreakpointChanges","callback","mql","getCurrentBreakpointSnapshot","belowBreakpointSubscribeCache","createBelowBreakpointSubscribe","cached","mediaQuery","pending","onChange","belowBreakpointSnapshotCache","createBelowBreakpointGetSnapshot","useEffect","useMemo","useRef","useCallbackRef","callback","callbackRef","args","useCallback","useEffect","useRef","useDebouncedCallback","callbackFn","options","stableCallbackFn","useCallbackRef","debounceTimerRef","useRef","useEffect","useCallback","args","useEffect","useLayoutEffect","useIsomorphicLayoutEffect","useMemo","useRandomStableId","prefix","randomStableId","randomStableId","prefix","randomPostfix","useMemo","useScrollBehavior","prefersReducedMotion","usePrefersReducedMotion","useMemo","useEffect","useState","useInView","ref","root","margin","amount","once","initial","isInView","setInView","useState","useEffect","onEnter","options","inView","useCallback","useMemo","useReducer","undoRedoReducer","state","action","undoStack","redoStack","useUndoRedo","dispatch","push","snapshot","undo","current","previous","redo","next"]}
|
|
1
|
+
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks/use-breakpoint.tsx","../src/hooks/use-callback-ref.tsx","../src/hooks/use-debounced-callback.tsx","../src/hooks/use-isomorphic-layout-effect.tsx","../src/hooks/use-random-stable-id.tsx","../src/hooks/use-scroll-behavior.tsx","../src/hooks/use-in-view.tsx","../src/hooks/use-undo-redo.tsx"],"sourcesContent":["import { useSyncExternalStore } from \"react\";\n\n/**\n * Tailwind CSS breakpoints in descending order (largest → smallest).\n *\n * These correspond to Tailwind’s default `theme.screens` config and are used\n * to determine the current viewport size.\n *\n * @see https://tailwindcss.com/docs/screens\n *\n * @example\n * \"2xl\" // ≥96rem (1536px)\n * \"xl\" // ≥80rem (1280px)\n * \"lg\" // ≥64rem (1024px)\n * \"md\" // ≥48rem (768px)\n * \"sm\" // ≥40rem (640px)\n * \"xs\" // ≥30rem (480px)\n * \"2xs\" // ≥22.5rem (360px)\n */\nconst tailwindBreakpoints = [\"2xl\", \"xl\", \"lg\", \"md\", \"sm\", \"xs\", \"2xs\"] as const;\n\n/**\n * A valid Tailwind CSS breakpoint identifier.\n *\n * @example\n * const bp: TailwindBreakpoint = \"md\"; // ≥48rem (768px)\n *\n * @example\n * \"2xl\" // ≥96rem (1536px)\n * \"xl\" // ≥80rem (1280px)\n * \"lg\" // ≥64rem (1024px)\n * \"md\" // ≥48rem (768px)\n * \"sm\" // ≥40rem (640px)\n * \"xs\" // ≥30rem (480px)\n * \"2xs\" // ≥22.5rem (360px)\n */\ntype TailwindBreakpoint = (typeof tailwindBreakpoints)[number];\n\n/**\n * Mantle’s breakpoint set, extending Tailwind’s with `\"default\"`.\n *\n * `\"default\"` represents the base (0px and up) viewport,\n * useful for defining fallbacks or mobile-first styles.\n *\n * @example\n * \"default\" // ≥0rem (0px)\n * \"2xs\" // ≥22.5rem (360px)\n * \"xs\" // ≥30rem (480px)\n * \"sm\" // ≥40rem (640px)\n * \"md\" // ≥48rem (768px)\n * \"lg\" // ≥64rem (1024px)\n * \"xl\" // ≥80rem (1280px)\n * \"2xl\" // ≥96rem (1536px)\n */\nconst breakpoints = [\"default\", ...tailwindBreakpoints] as const;\n\n/**\n * A valid Mantle breakpoint identifier.\n *\n * Includes Tailwind’s standard breakpoints plus `\"default\"` for 0px+.\n *\n * @example\n * const bp: Breakpoint = \"default\"; // ≥0px\n *\n * @example\n * \"default\" // ≥0rem (0px)\n * \"2xs\" // ≥22.5rem (360px)\n * \"xs\" // ≥30rem (480px)\n * \"sm\" // ≥40rem (640px)\n * \"md\" // ≥48rem (768px)\n * \"lg\" // ≥64rem (1024px)\n * \"xl\" // ≥80rem (1280px)\n * \"2xl\" // ≥96rem (1536px)\n */\ntype Breakpoint = (typeof breakpoints)[number];\n\n/**\n * React hook that returns the current breakpoint based on the viewport width.\n *\n * Uses a singleton subscription to a set of min-width media queries and returns\n * the largest matching breakpoint. Designed for React 18+ with\n * `useSyncExternalStore`.\n *\n * @returns {Breakpoint} The current breakpoint that matches the viewport width.\n *\n * @example\n * const breakpoint = useBreakpoint();\n * if (breakpoint === \"lg\") {\n * // Do something for large screens and above\n * }\n */\nfunction useBreakpoint(): Breakpoint {\n\treturn useSyncExternalStore(\n\t\tsubscribeToBreakpointChanges,\n\t\tgetCurrentBreakpointSnapshot,\n\t\t() => \"default\", // SSR fallback\n\t);\n}\n\n/**\n * React hook that returns true if the current viewport width is below the specified breakpoint.\n *\n * This hook uses `window.matchMedia` with a max-width media query and leverages\n * `useSyncExternalStore` to stay compliant with React's concurrent rendering model.\n *\n * @param {TailwindBreakpoint} breakpoint - The breakpoint to check against (e.g., \"md\", \"lg\").\n *\n * @returns {boolean} `true` if the viewport width is below the breakpoint, otherwise `false`.\n *\n * @example\n * // Check if viewport is below medium (768px)\n * const isBelowMd = useIsBelowBreakpoint(\"md\");\n */\nfunction useIsBelowBreakpoint(breakpoint: TailwindBreakpoint): boolean {\n\treturn useSyncExternalStore(\n\t\tcreateBelowBreakpointSubscribe(breakpoint),\n\t\tcreateBelowBreakpointGetSnapshot(breakpoint),\n\t\t() => false, // SSR fallback - assume desktop\n\t);\n}\n\nexport {\n\t//,\n\tbreakpoints,\n\tuseBreakpoint,\n\tuseIsBelowBreakpoint,\n};\n\nexport type {\n\t//,\n\tBreakpoint,\n\tTailwindBreakpoint,\n};\n\n/**\n * A CSS media query string representing a minimum width in `rem` units.\n *\n * @example\n * const query: MinWidthQuery = \"(min-width: 48rem)\";\n *\n * @private\n */\ntype MinWidthQuery = `(min-width: ${number}rem)`;\n\n/**\n * A CSS media query string representing a maximum width in `rem` units.\n *\n * @example\n * const query: MaxWidthQuery = \"(max-width: 47.99rem)\";\n *\n * @private\n */\ntype MaxWidthQuery = `(max-width: ${number}rem)`;\n\n/**\n * Precomputed min-width media query strings for each Tailwind breakpoint.\n *\n * Using constants avoids template string work in hot paths and ensures type\n * safety against the `MinWidthQuery` template literal type.\n *\n * @remarks\n * These are expressed in `rem`. If your CSS breakpoints are in `px`, consider\n * aligning units to avoid JS/CSS drift when `html{font-size}` changes.\n *\n * @private\n */\nconst breakpointQueries = {\n\t\"2xl\": \"(min-width: 96rem)\" as const,\n\txl: \"(min-width: 80rem)\" as const,\n\tlg: \"(min-width: 64rem)\" as const,\n\tmd: \"(min-width: 48rem)\" as const,\n\tsm: \"(min-width: 40rem)\" as const,\n\txs: \"(min-width: 30rem)\" as const,\n\t\"2xs\": \"(min-width: 22.5rem)\" as const,\n} as const satisfies Record<TailwindBreakpoint, MinWidthQuery>;\n\n/**\n * Precomputed max-width media query strings used by `useIsBelowBreakpoint`.\n *\n * The `-0.01rem` offset avoids overlap at exact boundaries.\n *\n * @private\n */\nconst belowBreakpointQueries = {\n\t\"2xl\": \"(max-width: 95.99rem)\" as const, // 96 - 0.01\n\txl: \"(max-width: 79.99rem)\" as const, // 80 - 0.01\n\tlg: \"(max-width: 63.99rem)\" as const, // 64 - 0.01\n\tmd: \"(max-width: 47.99rem)\" as const, // 48 - 0.01\n\tsm: \"(max-width: 39.99rem)\" as const, // 40 - 0.01\n\txs: \"(max-width: 29.99rem)\" as const, // 30 - 0.01\n\t\"2xs\": \"(max-width: 22.49rem)\" as const, // 22.5 - 0.01\n} as const satisfies Record<TailwindBreakpoint, MaxWidthQuery>;\n\n/**\n * Lazily-initialized cache of `MediaQueryList` objects for min-width queries.\n *\n * Initialized on first access to remain SSR-safe (no `window` at import time).\n *\n * @private\n */\nlet minWidthMQLs: Record<TailwindBreakpoint, MediaQueryList> | null = null;\n\n/**\n * Lazily-initialized cache of `MediaQueryList` objects for max-width queries.\n *\n * Used by `useIsBelowBreakpoint`. Also SSR-safe by lazy access.\n *\n * @private\n */\nlet maxWidthMQLs: Record<TailwindBreakpoint, MediaQueryList> | null = null;\n\n/**\n * Get (and lazily create) the cached `MediaQueryList` objects for min-width queries.\n *\n * @returns A record of `MediaQueryList` keyed by Tailwind breakpoint.\n * @private\n */\nfunction getMinWidthMQLs(): Record<TailwindBreakpoint, MediaQueryList> {\n\tif (!minWidthMQLs) {\n\t\tminWidthMQLs = {\n\t\t\t\"2xl\": window.matchMedia(breakpointQueries[\"2xl\"]),\n\t\t\txl: window.matchMedia(breakpointQueries.xl),\n\t\t\tlg: window.matchMedia(breakpointQueries.lg),\n\t\t\tmd: window.matchMedia(breakpointQueries.md),\n\t\t\tsm: window.matchMedia(breakpointQueries.sm),\n\t\t\txs: window.matchMedia(breakpointQueries.xs),\n\t\t\t\"2xs\": window.matchMedia(breakpointQueries[\"2xs\"]),\n\t\t};\n\t}\n\treturn minWidthMQLs;\n}\n\n/**\n * Get (and lazily create) the cached `MediaQueryList` for a specific max-width breakpoint.\n *\n * @param breakpoint - Tailwind breakpoint identifier (e.g., \"md\").\n * @returns The corresponding `MediaQueryList`.\n * @private\n */\nfunction getMaxWidthMQL(breakpoint: TailwindBreakpoint): MediaQueryList {\n\tif (!maxWidthMQLs) {\n\t\tmaxWidthMQLs = {\n\t\t\t\"2xl\": window.matchMedia(belowBreakpointQueries[\"2xl\"]),\n\t\t\txl: window.matchMedia(belowBreakpointQueries.xl),\n\t\t\tlg: window.matchMedia(belowBreakpointQueries.lg),\n\t\t\tmd: window.matchMedia(belowBreakpointQueries.md),\n\t\t\tsm: window.matchMedia(belowBreakpointQueries.sm),\n\t\t\txs: window.matchMedia(belowBreakpointQueries.xs),\n\t\t\t\"2xs\": window.matchMedia(belowBreakpointQueries[\"2xs\"]),\n\t\t};\n\t}\n\treturn maxWidthMQLs[breakpoint];\n}\n\n/**\n * Current breakpoint value used by the singleton store backing `useBreakpoint`.\n *\n * Initialized to `\"default\"` and updated on media-query change events.\n *\n * @private\n */\nlet currentBreakpointValue: Breakpoint = \"default\";\n\n/**\n * Set of component listeners subscribed to the singleton breakpoint store.\n *\n * Each listener is invoked when the current breakpoint value changes.\n *\n * @private\n */\nconst breakpointListeners = new Set<() => void>();\n\n/**\n * Flag indicating whether global media-query listeners are currently attached.\n *\n * Prevents duplicate registrations and enables full teardown when unused.\n *\n * @private\n */\nlet breakpointSubscriptionActive = false;\n\n/**\n * Compute the current breakpoint by checking cached min-width MQLs\n * from largest to smallest.\n *\n * @returns {Breakpoint} The largest matching breakpoint, or `\"default\"`.\n * @private\n */\nfunction getCurrentBreakpoint(): Breakpoint {\n\tconst mqls = getMinWidthMQLs();\n\tfor (const breakpoint of tailwindBreakpoints) {\n\t\tif (mqls[breakpoint].matches) {\n\t\t\treturn breakpoint;\n\t\t}\n\t}\n\treturn \"default\";\n}\n\n/**\n * Update the current breakpoint value and notify all listeners.\n *\n * Uses `requestAnimationFrame` to coalesce rapid resize events and minimize\n * re-renders during active window resizing.\n *\n * @private\n */\nlet breakpointUpdatePending = false;\nfunction updateCurrentBreakpoint() {\n\tif (!breakpointUpdatePending) {\n\t\tbreakpointUpdatePending = true;\n\t\trequestAnimationFrame(() => {\n\t\t\tbreakpointUpdatePending = false;\n\t\t\tconst newBreakpoint = getCurrentBreakpoint();\n\t\t\tif (newBreakpoint !== currentBreakpointValue) {\n\t\t\t\tcurrentBreakpointValue = newBreakpoint;\n\t\t\t\tfor (const listener of breakpointListeners) {\n\t\t\t\t\tlistener();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * Subscribe a component to breakpoint changes (singleton pattern).\n *\n * Ensures only one set of MQL listeners exists app-wide. Also reconciles the\n * `useSyncExternalStore` initial snapshot/subscribe race by invoking the\n * subscriber once on mount.\n *\n * @param callback - Listener invoked when the breakpoint value may have changed.\n * @returns Cleanup function to unsubscribe the listener.\n * @private\n */\nfunction subscribeToBreakpointChanges(callback: () => void) {\n\tbreakpointListeners.add(callback);\n\n\t// Attach global listeners once\n\tif (!breakpointSubscriptionActive) {\n\t\tbreakpointSubscriptionActive = true;\n\t\tconst mqls = getMinWidthMQLs();\n\n\t\t// Initialize current value synchronously\n\t\tcurrentBreakpointValue = getCurrentBreakpoint();\n\n\t\t// Attach listeners to all breakpoint MQLs\n\t\tfor (const mql of Object.values(mqls)) {\n\t\t\tmql.addEventListener(\"change\", updateCurrentBreakpoint);\n\t\t}\n\t}\n\n\t// Reconcile initial getSnapshot vs subscribe ordering\n\tcallback();\n\n\t// Cleanup\n\treturn () => {\n\t\tbreakpointListeners.delete(callback);\n\n\t\t// Tear down global listeners when no one is listening\n\t\tif (breakpointListeners.size === 0 && breakpointSubscriptionActive) {\n\t\t\tbreakpointSubscriptionActive = false;\n\t\t\tconst mqls = getMinWidthMQLs();\n\t\t\tfor (const mql of Object.values(mqls)) {\n\t\t\t\tmql.removeEventListener(\"change\", updateCurrentBreakpoint);\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Return the current breakpoint value from the singleton store.\n *\n * Used as the `getSnapshot` for `useSyncExternalStore`.\n *\n * @returns {Breakpoint} The latest computed breakpoint.\n * @private\n */\nfunction getCurrentBreakpointSnapshot(): Breakpoint {\n\treturn currentBreakpointValue;\n}\n\n/**\n * Cached `subscribe` functions keyed by breakpoint.\n *\n * Without caching, `useSyncExternalStore` receives a new function reference on\n * every render, causing it to tear down and re-attach the MQL listener each\n * time — the primary source of resize sluggishness.\n *\n * @private\n */\nconst belowBreakpointSubscribeCache = new Map<\n\tTailwindBreakpoint,\n\t(callback: () => void) => () => void\n>();\n\n/**\n * Get (or create and cache) a `subscribe` function for a specific \"below\" breakpoint.\n *\n * Uses a cached `MediaQueryList` and rAF-throttled change handler to avoid\n * bursty updates during resize.\n *\n * @param breakpoint - Tailwind breakpoint identifier (e.g., \"lg\").\n * @returns A stable `subscribe` function suitable for `useSyncExternalStore`.\n * @private\n */\nfunction createBelowBreakpointSubscribe(breakpoint: TailwindBreakpoint) {\n\tlet cached = belowBreakpointSubscribeCache.get(breakpoint);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\tcached = (callback: () => void) => {\n\t\tconst mediaQuery = getMaxWidthMQL(breakpoint);\n\n\t\t// rAF throttle the change callback during active resize\n\t\tlet pending = false;\n\t\tconst onChange = () => {\n\t\t\tif (!pending) {\n\t\t\t\tpending = true;\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tpending = false;\n\t\t\t\t\tcallback();\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tmediaQuery.addEventListener(\"change\", onChange);\n\t\treturn () => {\n\t\t\tmediaQuery.removeEventListener(\"change\", onChange);\n\t\t};\n\t};\n\n\tbelowBreakpointSubscribeCache.set(breakpoint, cached);\n\treturn cached;\n}\n\n/**\n * Cached `getSnapshot` functions keyed by breakpoint.\n *\n * Ensures `useSyncExternalStore` receives a referentially stable function,\n * preventing unnecessary subscription churn.\n *\n * @private\n */\nconst belowBreakpointSnapshotCache = new Map<TailwindBreakpoint, () => boolean>();\n\n/**\n * Get (or create and cache) a `getSnapshot` function for a specific \"below\" breakpoint.\n *\n * Uses the cached `MediaQueryList` for the target breakpoint.\n *\n * @param breakpoint - Tailwind breakpoint identifier (e.g., \"lg\").\n * @returns A stable function that returns `true` when the viewport is below the breakpoint.\n * @private\n */\nfunction createBelowBreakpointGetSnapshot(breakpoint: TailwindBreakpoint) {\n\tlet cached = belowBreakpointSnapshotCache.get(breakpoint);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\tcached = () => {\n\t\tconst mediaQuery = getMaxWidthMQL(breakpoint);\n\t\treturn mediaQuery.matches;\n\t};\n\n\tbelowBreakpointSnapshotCache.set(breakpoint, cached);\n\treturn cached;\n}\n","import { useEffect, useMemo, useRef } from \"react\";\n\n/**\n * Returns a memoized callback that will always refer to the latest callback\n * passed to the hook.\n *\n * This is useful when you want to pass a callback which may or may not be\n * memoized (have a stable identity) to a child component that will be updated\n * without causing the child component to re-render.\n */\nfunction useCallbackRef<T extends (...args: unknown[]) => unknown>(callback: T | undefined): T {\n\tconst callbackRef = useRef(callback);\n\n\tuseEffect(() => {\n\t\tcallbackRef.current = callback;\n\t});\n\n\treturn useMemo(() => ((...args) => callbackRef.current?.(...args)) as T, []);\n}\n\nexport {\n\t//,\n\tuseCallbackRef,\n};\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { useCallbackRef } from \"./use-callback-ref.js\";\n\ntype Options = {\n\t/**\n\t * The delay in milliseconds to wait before calling the callback.\n\t */\n\twaitMs: number;\n};\n\n/**\n * Create a debounced version of a callback function.\n *\n * It allows you to delay the execution of a function until a certain period of\n * inactivity has passed (the `options.waitMs`), which can be useful for limiting rapid\n * invocations of a function (like in search inputs or button clicks)\n *\n * Note: The debounced callback will always refer to the latest callback passed\n * even without memoization, so it's stable and safe to use in dependency arrays.\n */\nfunction useDebouncedCallback<T extends (...args: unknown[]) => unknown>(\n\tcallbackFn: T,\n\toptions: Options,\n) {\n\tconst stableCallbackFn = useCallbackRef(callbackFn);\n\tconst debounceTimerRef = useRef(0);\n\tuseEffect(() => () => window.clearTimeout(debounceTimerRef.current), []);\n\n\treturn useCallback(\n\t\t(...args: Parameters<T>) => {\n\t\t\twindow.clearTimeout(debounceTimerRef.current);\n\t\t\tdebounceTimerRef.current = window.setTimeout(() => stableCallbackFn(...args), options.waitMs);\n\t\t},\n\t\t[stableCallbackFn, options.waitMs],\n\t);\n}\n\nexport {\n\t//,\n\tuseDebouncedCallback,\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\n/**\n * useIsomorphicLayoutEffect is a hook that uses useLayoutEffect on the client and useEffect on the server.\n */\nexport const useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n","import { useMemo } from \"react\";\n\n/**\n * Hook to generate a random, stable id.\n * This is similar to `useId`, but generates a stable id client side which can also\n * be used for css selectors and element ids.\n */\nconst useRandomStableId = (prefix = \"mantle\") => useMemo(() => randomStableId(prefix), [prefix]);\n\nexport {\n\t//,\n\tuseRandomStableId,\n};\n\nfunction randomStableId(prefix = \"mantle\") {\n\tconst _prefix = prefix.trim() || \"mantle\";\n\treturn [_prefix, randomPostfix()].join(\"-\");\n}\n\nfunction randomPostfix() {\n\treturn Math.random().toString(36).substring(2, 9);\n}\n","import { useMemo } from \"react\";\nimport { usePrefersReducedMotion } from \"./use-prefers-reduced-motion.js\";\n\n/**\n * `scroll-behavior` values:\n *\n * - `\"auto\"` — scrolling happens instantly (no animation).\n * - `\"smooth\"` — scrolling animates smoothly using a user-agent–defined easing and duration.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior#values\n */\ntype ScrollBehavior = \"auto\" | \"smooth\";\n\n/**\n * Returns a `ScrollBehavior` that respects the user's motion preference via `usePrefersReducedMotion`.\n *\n * - When `usePrefersReducedMotion()` is `true`, returns `\"auto\"` (no animated scroll).\n * - Otherwise returns `\"smooth\"`.\n *\n * Use this with `window.scrollTo`, `Element.scrollIntoView`, etc. It prevents\n * smooth-scrolling for users who opt out of motion and avoids SSR “first paint”\n * animations thanks to the hook’s conservative server default.\n *\n * @example\n * // Scroll to top\n * const behavior = useScrollBehavior();\n * window.scrollTo({ top: 0, behavior });\n *\n * @example\n * // Bring a section into view\n * const behavior = useScrollBehavior();\n * sectionRef.current?.scrollIntoView({ behavior, block: \"start\" });\n *\n * @see {@link usePrefersReducedMotion}\n * @see CSS `scroll-behavior` property (values: `\"auto\"`, `\"smooth\"`).\n */\nexport function useScrollBehavior(): ScrollBehavior {\n\tconst prefersReducedMotion = usePrefersReducedMotion();\n\n\treturn useMemo(() => (prefersReducedMotion ? \"auto\" : \"smooth\"), [prefersReducedMotion]);\n}\n","\"use client\";\n\nimport { type RefObject, useEffect, useState } from \"react\";\nimport type { InViewOptions, MarginType } from \"../utils/in-view.js\";\nimport { inView } from \"../utils/in-view.js\";\n\n/**\n * Options for the `useInView` hook.\n */\ntype UseInViewOptions = {\n\t/**\n\t * A ref to a scrollable container element to use as the intersection root.\n\t * Defaults to the browser viewport.\n\t */\n\troot?: RefObject<Element | null>;\n\n\t/**\n\t * Expand or contract the detected area from each side of the root's bounding box.\n\t * Uses the same syntax as the CSS `margin` shorthand (e.g. `\"10px\"`, `\"10% 20px\"`).\n\t */\n\tmargin?: MarginType;\n\n\t/**\n\t * How much of the element must be visible before it is considered in view.\n\t * - `\"some\"` (default): Any part of the element is visible.\n\t * - `\"all\"`: The entire element is visible.\n\t * - `number`: An intersection ratio between `0` and `1` (e.g. `0.5` for 50%).\n\t */\n\tamount?: \"some\" | \"all\" | number;\n\n\t/**\n\t * If `true`, stop observing once the element enters the viewport for the\n\t * first time. Useful for one-shot entrance animations.\n\t * Defaults to `false`.\n\t */\n\tonce?: boolean;\n\n\t/**\n\t * The initial visibility state returned before the observer has attached.\n\t * Defaults to `false`.\n\t */\n\tinitial?: boolean;\n};\n\n/**\n * React hook that tracks whether a DOM element is visible within the viewport\n * (or a scrollable container) using the `IntersectionObserver` API.\n *\n * @param ref - A ref attached to the element to observe.\n * @param options - Options controlling the scroll root, margin, threshold,\n * initial state, and one-time detection.\n * @returns `true` if the element is currently in view, otherwise `false`.\n *\n * @example\n * // Basic usage\n * const ref = useRef<HTMLDivElement>(null);\n * const isInView = useInView(ref);\n *\n * return <div ref={ref}>{isInView ? \"Visible!\" : \"Hidden\"}</div>;\n *\n * @example\n * // Trigger once when the element first enters the viewport\n * const ref = useRef<HTMLDivElement>(null);\n * const isInView = useInView(ref, { once: true });\n *\n * return (\n * <div\n * ref={ref}\n * style={{ opacity: isInView ? 1 : 0, transition: \"opacity 0.5s\" }}\n * />\n * );\n *\n * @example\n * // Require 50% of the element to be visible\n * const ref = useRef<HTMLDivElement>(null);\n * const isInView = useInView(ref, { amount: 0.5 });\n */\nfunction useInView(\n\tref: RefObject<Element | null>,\n\t{ root, margin, amount, once = false, initial = false }: UseInViewOptions = {},\n): boolean {\n\tconst [isInView, setInView] = useState(initial);\n\n\tuseEffect(() => {\n\t\tif (!ref.current || (once && isInView)) {\n\t\t\treturn;\n\t\t}\n\n\t\tfunction onEnter() {\n\t\t\tsetInView(true);\n\t\t\treturn once ? undefined : () => setInView(false);\n\t\t}\n\n\t\tconst options: InViewOptions = {\n\t\t\troot: (root && root.current) || undefined,\n\t\t\tmargin,\n\t\t\tamount,\n\t\t};\n\n\t\treturn inView(ref.current, onEnter, options);\n\t\t/**\n\t\t * Intentionally omit `isInView` from deps. The effect must only re-run\n\t\t * when the observation parameters change, not when visibility changes.\n\t\t * Including `isInView` would restart the observer (disconnect + reconnect)\n\t\t * on every enter/leave event, causing wasteful churn for the common\n\t\t * `once=false` case.\n\t\t */\n\t\t// oxlint-disable-next-line react-hooks/exhaustive-deps\n\t}, [root, ref, margin, once, amount]);\n\n\treturn isInView;\n}\n\nexport { useInView };\nexport type { UseInViewOptions };\n","import { useCallback, useMemo, useReducer } from \"react\";\n\ntype UndoRedoState<T> = {\n\tundoStack: T[];\n\tredoStack: T[];\n};\n\ntype UndoRedoAction<T> =\n\t| { type: \"push\"; snapshot: T }\n\t| { type: \"undo\"; current: T }\n\t| { type: \"redo\"; current: T };\n\nfunction undoRedoReducer<T>(state: UndoRedoState<T>, action: UndoRedoAction<T>): UndoRedoState<T> {\n\tswitch (action.type) {\n\t\tcase \"push\": {\n\t\t\treturn {\n\t\t\t\tundoStack: [...state.undoStack, action.snapshot],\n\t\t\t\tredoStack: [],\n\t\t\t};\n\t\t}\n\t\tcase \"undo\": {\n\t\t\tif (state.undoStack.length === 0) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\tconst undoStack = state.undoStack.slice(0, -1);\n\t\t\tconst previous = state.undoStack[state.undoStack.length - 1];\n\t\t\tif (previous === undefined) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tundoStack,\n\t\t\t\tredoStack: [...state.redoStack, action.current],\n\t\t\t};\n\t\t}\n\t\tcase \"redo\": {\n\t\t\tif (state.redoStack.length === 0) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\tconst redoStack = state.redoStack.slice(0, -1);\n\t\t\tconst next = state.redoStack[state.redoStack.length - 1];\n\t\t\tif (next === undefined) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tundoStack: [...state.undoStack, action.current],\n\t\t\t\tredoStack,\n\t\t\t};\n\t\t}\n\t}\n}\n\ntype UseUndoRedoReturn<T> = {\n\t/** Whether there are actions to undo. */\n\tcanUndo: boolean;\n\t/** Whether there are actions to redo. */\n\tcanRedo: boolean;\n\t/** Push a snapshot onto the undo stack. Clears the redo stack. */\n\tpush: (snapshot: T) => void;\n\t/** Pop the last snapshot from the undo stack. Returns `undefined` if empty. */\n\tundo: (current: T) => T | undefined;\n\t/** Pop the last snapshot from the redo stack. Returns `undefined` if empty. */\n\tredo: (current: T) => T | undefined;\n};\n\n/**\n * A generic undo/redo hook backed by a reducer.\n *\n * Maintains two stacks (undo and redo). Call `push` before mutating state\n * to snapshot the current value. Call `undo`/`redo` with the current value\n * to swap it with the previous/next snapshot.\n *\n * @example\n * ```tsx\n * const { push, undo, redo, canUndo, canRedo } = useUndoRedo<string[]>();\n *\n * function removeItem(item: string) {\n * push([...items]); // snapshot before mutation\n * setItems(items.filter((i) => i !== item));\n * }\n *\n * function handleKeyDown(event: KeyboardEvent) {\n * if ((event.metaKey || event.ctrlKey) && event.key === \"z\" && !event.shiftKey) {\n * const previous = undo(items);\n * if (previous) setItems(previous);\n * }\n * if ((event.metaKey || event.ctrlKey) && (event.shiftKey && event.key === \"z\" || event.key === \"y\")) {\n * const next = redo(items);\n * if (next) setItems(next);\n * }\n * }\n * ```\n */\nfunction useUndoRedo<T>(): UseUndoRedoReturn<T> {\n\tconst [state, dispatch] = useReducer(undoRedoReducer<T>, {\n\t\tundoStack: [],\n\t\tredoStack: [],\n\t});\n\n\tconst push = useCallback((snapshot: T) => {\n\t\tdispatch({ type: \"push\", snapshot });\n\t}, []);\n\n\tconst undo = useCallback(\n\t\t(current: T): T | undefined => {\n\t\t\tconst previous = state.undoStack[state.undoStack.length - 1];\n\t\t\tif (previous === undefined) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tdispatch({ type: \"undo\", current });\n\t\t\treturn previous;\n\t\t},\n\t\t[state.undoStack],\n\t);\n\n\tconst redo = useCallback(\n\t\t(current: T): T | undefined => {\n\t\t\tconst next = state.redoStack[state.redoStack.length - 1];\n\t\t\tif (next === undefined) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tdispatch({ type: \"redo\", current });\n\t\t\treturn next;\n\t\t},\n\t\t[state.redoStack],\n\t);\n\n\treturn useMemo(\n\t\t() => ({\n\t\t\tcanUndo: state.undoStack.length > 0,\n\t\t\tcanRedo: state.redoStack.length > 0,\n\t\t\tpush,\n\t\t\tundo,\n\t\t\tredo,\n\t\t}),\n\t\t[state.undoStack.length, state.redoStack.length, push, undo, redo],\n\t);\n}\n\nexport {\n\t//,\n\tuseUndoRedo,\n};\n\nexport type {\n\t//,\n\tUseUndoRedoReturn,\n};\n"],"mappings":"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"}
|
package/dist/hover-card.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import * as react from
|
|
2
|
-
import { ComponentPropsWithoutRef } from
|
|
3
|
-
import * as
|
|
4
|
-
import * as HoverCardPrimitive from
|
|
1
|
+
import * as react from "react";
|
|
2
|
+
import { ComponentPropsWithoutRef } from "react";
|
|
3
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
|
+
import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
|
|
5
5
|
|
|
6
|
+
//#region src/components/hover-card/hover-card.d.ts
|
|
6
7
|
/**
|
|
7
8
|
* A floating card that appears when a user hovers over a trigger element.
|
|
8
9
|
*
|
|
@@ -23,92 +24,97 @@ import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
|
|
|
23
24
|
* ```
|
|
24
25
|
*/
|
|
25
26
|
declare const HoverCard: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
27
|
+
/**
|
|
28
|
+
* The root, stateful component that manages the open/closed state of the hover card.
|
|
29
|
+
*
|
|
30
|
+
* @see https://mantle.ngrok.com/components/hover-card#hovercardroot
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* <HoverCard.Root>
|
|
35
|
+
* <HoverCard.Trigger asChild>
|
|
36
|
+
* <Button>Hover me</Button>
|
|
37
|
+
* </HoverCard.Trigger>
|
|
38
|
+
* <HoverCard.Content>
|
|
39
|
+
* <p>This is the hover card content.</p>
|
|
40
|
+
* </HoverCard.Content>
|
|
41
|
+
* </HoverCard.Root>
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
readonly Root: {
|
|
45
|
+
({
|
|
46
|
+
closeDelay,
|
|
47
|
+
openDelay,
|
|
48
|
+
...props
|
|
49
|
+
}: ComponentPropsWithoutRef<typeof HoverCardPrimitive.Root>): react_jsx_runtime0.JSX.Element;
|
|
50
|
+
displayName: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* The content to render inside the hover card. Appears in a portal with rich styling and animations.
|
|
54
|
+
*
|
|
55
|
+
* @see https://mantle.ngrok.com/components/hover-card#hovercardcontent
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* <HoverCard.Root>
|
|
60
|
+
* <HoverCard.Trigger asChild>
|
|
61
|
+
* <Button type="button" variant="link">@username</Button>
|
|
62
|
+
* </HoverCard.Trigger>
|
|
63
|
+
* <HoverCard.Content side="top">
|
|
64
|
+
* <div className="space-y-2">
|
|
65
|
+
* <Text weight="strong">User Profile</Text>
|
|
66
|
+
* <Text>Additional information about the user.</Text>
|
|
67
|
+
* <Button type="button" size="sm">Follow</Button>
|
|
68
|
+
* </div>
|
|
69
|
+
* </HoverCard.Content>
|
|
70
|
+
* </HoverCard.Root>
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
readonly Content: react.ForwardRefExoticComponent<Omit<HoverCardPrimitive.HoverCardContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
74
|
+
/**
|
|
75
|
+
* The portal container for rendering hover card content outside the normal DOM tree.
|
|
76
|
+
*
|
|
77
|
+
* @see https://mantle.ngrok.com/components/hover-card#api-reference
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```tsx
|
|
81
|
+
* <HoverCard.Root>
|
|
82
|
+
* <HoverCard.Trigger asChild>
|
|
83
|
+
* <Text>Hover over me</Text>
|
|
84
|
+
* </HoverCard.Trigger>
|
|
85
|
+
* <HoverCard.Portal>
|
|
86
|
+
* <HoverCard.Content>
|
|
87
|
+
* <Text>This content is rendered in a portal.</Text>
|
|
88
|
+
* </HoverCard.Content>
|
|
89
|
+
* </HoverCard.Portal>
|
|
90
|
+
* </HoverCard.Root>
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
readonly Portal: react.FC<HoverCardPrimitive.HoverCardPortalProps>;
|
|
94
|
+
/**
|
|
95
|
+
* The trigger element that opens the hover card when hovered.
|
|
96
|
+
*
|
|
97
|
+
* @see https://mantle.ngrok.com/components/hover-card#hovercardtrigger
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```tsx
|
|
101
|
+
* <HoverCard.Root>
|
|
102
|
+
* <HoverCard.Trigger asChild>
|
|
103
|
+
* <Button type="button" variant="ghost">
|
|
104
|
+
* Hover for details
|
|
105
|
+
* </Button>
|
|
106
|
+
* </HoverCard.Trigger>
|
|
107
|
+
* <HoverCard.Content>
|
|
108
|
+
* <div className="space-y-1">
|
|
109
|
+
* <Text weight="strong">Quick Info</Text>
|
|
110
|
+
* <Text>This appears when you hover over the trigger.</Text>
|
|
111
|
+
* </div>
|
|
112
|
+
* </HoverCard.Content>
|
|
113
|
+
* </HoverCard.Root>
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
readonly Trigger: react.ForwardRefExoticComponent<HoverCardPrimitive.HoverCardTriggerProps & react.RefAttributes<HTMLAnchorElement>>;
|
|
112
117
|
};
|
|
113
|
-
|
|
118
|
+
//#endregion
|
|
114
119
|
export { HoverCard };
|
|
120
|
+
//# sourceMappingURL=hover-card.d.ts.map
|
package/dist/hover-card.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as e}from"./cx-bKromGBh.js";import{forwardRef as t}from"react";import{jsx as n}from"react/jsx-runtime";import*as r from"@radix-ui/react-hover-card";const i=({closeDelay:e=300,openDelay:t=100,...i})=>n(r.Root,{closeDelay:e,openDelay:t,...i});i.displayName=`HoverCard`;const a=r.Trigger;a.displayName=`HoverCardTrigger`;const o=r.Portal;o.displayName=`HoverCardPortal`;const s=t(({className:t,onClick:i,align:a=`center`,sideOffset:s=4,...c},l)=>n(o,{children:n(r.Content,{ref:l,align:a,sideOffset:s,className:e(`bg-popover border-popover z-50 w-64 rounded-md border p-4 shadow-md outline-hidden`,`data-state-open:animate-in data-state-closed:animate-out data-state-closed:fade-out-0 data-state-open:fade-in-0 data-state-closed:zoom-out-95 data-state-open:zoom-in-95 data-side-bottom:slide-in-from-top-2 data-side-left:slide-in-from-right-2 data-side-right:slide-in-from-left-2 data-side-top:slide-in-from-bottom-2`,t),onClick:e=>{e.stopPropagation(),i?.(e)},...c})}));s.displayName=r.Content.displayName;const c={Root:i,Content:s,Portal:o,Trigger:a};export{c as HoverCard};
|
|
2
2
|
//# sourceMappingURL=hover-card.js.map
|
package/dist/hover-card.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/hover-card/hover-card.tsx"],"sourcesContent":["\"use client\";\n\nimport * as HoverCardPrimitive from \"@radix-ui/react-hover-card\";\nimport { forwardRef } from \"react\";\nimport type { ComponentPropsWithoutRef, ComponentRef } from \"react\";\nimport { cx } from \"../../utils/cx/cx.js\";\n\n/**\n * A floating card that appears when a user hovers over a trigger element.\n * This is the root, stateful component that manages the open/closed state of the hover card.\n *\n * @see https://mantle.ngrok.com/components/hover-card#hovercardroot\n *\n * @example\n * ```tsx\n * <HoverCard.Root>\n * <HoverCard.Trigger asChild>\n * <Button type=\"button\" appearance=\"outlined\">\n * Hover me\n * </Button>\n * </HoverCard.Trigger>\n * <HoverCard.Content>\n * <p>This is the hover card content.</p>\n * </HoverCard.Content>\n * </HoverCard.Root>\n * ```\n */\nconst Root = ({\n\tcloseDelay = 300,\n\topenDelay = 100,\n\t...props\n}: ComponentPropsWithoutRef<typeof HoverCardPrimitive.Root>) => (\n\t<HoverCardPrimitive.Root closeDelay={closeDelay} openDelay={openDelay} {...props} />\n);\nRoot.displayName = \"HoverCard\";\n\n/**\n * The trigger element that opens the hover card when hovered.\n *\n * @see https://mantle.ngrok.com/components/hover-card#hovercardtrigger\n *\n * @example\n * ```tsx\n * <HoverCard.Root>\n * <HoverCard.Trigger asChild>\n * <Button type=\"button\" appearance=\"outlined\">\n * Hover me\n * </Button>\n * </HoverCard.Trigger>\n * <HoverCard.Content>\n * <p>This is the hover card content.</p>\n * </HoverCard.Content>\n * </HoverCard.Root>\n * ```\n */\nconst Trigger = HoverCardPrimitive.Trigger;\nTrigger.displayName = \"HoverCardTrigger\";\n\n/**\n * The portal for a HoverCard. Should be rendered as a child of the `HoverCard` component.\n * Renders a portal that the `HoverCard.Content` is rendered into.\n *\n * You likely don't need to use this component directly, as it is used internally by the `HoverCard.Content` component.\n */\nconst Portal = HoverCardPrimitive.Portal;\nPortal.displayName = \"HoverCardPortal\";\n\n/**\n * The content to render inside the hover card.\n *\n * @see https://mantle.ngrok.com/components/hover-card#hovercardcontent\n *\n * @example\n * ```tsx\n * <HoverCard.Root>\n * <HoverCard.Trigger asChild>\n * <Button type=\"button\" appearance=\"outlined\">\n * Hover me\n * </Button>\n * </HoverCard.Trigger>\n * <HoverCard.Content>\n * <p>This is the hover card content.</p>\n * </HoverCard.Content>\n * </HoverCard.Root>\n * ```\n */\nconst Content = forwardRef<\n\tComponentRef<typeof HoverCardPrimitive.Content>,\n\tComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>\n>(({ className, onClick, align = \"center\", sideOffset = 4, ...props }, ref) => (\n\t<Portal>\n\t\t<HoverCardPrimitive.Content\n\t\t\tref={ref}\n\t\t\talign={align}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={cx(\n\t\t\t\t\"bg-popover border-popover z-50 w-64 rounded-md border p-4 shadow-md outline-hidden\",\n\t\t\t\t\"data-state-open:animate-in data-state-closed:animate-out data-state-closed:fade-out-0 data-state-open:fade-in-0 data-state-closed:zoom-out-95 data-state-open:zoom-in-95 data-side-bottom:slide-in-from-top-2 data-side-left:slide-in-from-right-2 data-side-right:slide-in-from-left-2 data-side-top:slide-in-from-bottom-2\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tonClick={(event) => {\n\t\t\t\t/**\n\t\t\t\t * Prevent the click event from propagating up to parent/containing elements\n\t\t\t\t */\n\t\t\t\tevent.stopPropagation();\n\t\t\t\tonClick?.(event);\n\t\t\t}}\n\t\t\t{...props}\n\t\t/>\n\t</Portal>\n));\nContent.displayName = HoverCardPrimitive.Content.displayName;\n\n/**\n * A floating card that appears when a user hovers over a trigger element.\n *\n * @see https://mantle.ngrok.com/components/hover-card\n *\n * @example\n * ```tsx\n * <HoverCard.Root>\n * <HoverCard.Trigger asChild>\n * <Button type=\"button\" appearance=\"outlined\">\n * Hover me\n * </Button>\n * </HoverCard.Trigger>\n * <HoverCard.Content>\n * <p>This is the hover card content.</p>\n * </HoverCard.Content>\n * </HoverCard.Root>\n * ```\n */\nconst HoverCard = {\n\t/**\n\t * The root, stateful component that manages the open/closed state of the hover card.\n\t *\n\t * @see https://mantle.ngrok.com/components/hover-card#hovercardroot\n\t *\n\t * @example\n\t * ```tsx\n\t * <HoverCard.Root>\n\t * <HoverCard.Trigger asChild>\n\t * <Button>Hover me</Button>\n\t * </HoverCard.Trigger>\n\t * <HoverCard.Content>\n\t * <p>This is the hover card content.</p>\n\t * </HoverCard.Content>\n\t * </HoverCard.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * The content to render inside the hover card. Appears in a portal with rich styling and animations.\n\t *\n\t * @see https://mantle.ngrok.com/components/hover-card#hovercardcontent\n\t *\n\t * @example\n\t * ```tsx\n\t * <HoverCard.Root>\n\t * <HoverCard.Trigger asChild>\n\t * <Button type=\"button\" variant=\"link\">@username</Button>\n\t * </HoverCard.Trigger>\n\t * <HoverCard.Content side=\"top\">\n\t * <div className=\"space-y-2\">\n\t * <Text weight=\"strong\">User Profile</Text>\n\t * <Text>Additional information about the user.</Text>\n\t * <Button type=\"button\" size=\"sm\">Follow</Button>\n\t * </div>\n\t * </HoverCard.Content>\n\t * </HoverCard.Root>\n\t * ```\n\t */\n\tContent,\n\t/**\n\t * The portal container for rendering hover card content outside the normal DOM tree.\n\t *\n\t * @see https://mantle.ngrok.com/components/hover-card#api-reference\n\t *\n\t * @example\n\t * ```tsx\n\t * <HoverCard.Root>\n\t * <HoverCard.Trigger asChild>\n\t * <Text>Hover over me</Text>\n\t * </HoverCard.Trigger>\n\t * <HoverCard.Portal>\n\t * <HoverCard.Content>\n\t * <Text>This content is rendered in a portal.</Text>\n\t * </HoverCard.Content>\n\t * </HoverCard.Portal>\n\t * </HoverCard.Root>\n\t * ```\n\t */\n\tPortal,\n\t/**\n\t * The trigger element that opens the hover card when hovered.\n\t *\n\t * @see https://mantle.ngrok.com/components/hover-card#hovercardtrigger\n\t *\n\t * @example\n\t * ```tsx\n\t * <HoverCard.Root>\n\t * <HoverCard.Trigger asChild>\n\t * <Button type=\"button\" variant=\"ghost\">\n\t * Hover for details\n\t * </Button>\n\t * </HoverCard.Trigger>\n\t * <HoverCard.Content>\n\t * <div className=\"space-y-1\">\n\t * <Text weight=\"strong\">Quick Info</Text>\n\t * <Text>This appears when you hover over the trigger.</Text>\n\t * </div>\n\t * </HoverCard.Content>\n\t * </HoverCard.Root>\n\t * ```\n\t */\n\tTrigger,\n} as const;\n\nexport {\n\t//,\n\tHoverCard,\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"hover-card.js","names":[],"sources":["../src/components/hover-card/hover-card.tsx"],"sourcesContent":["\"use client\";\n\nimport * as HoverCardPrimitive from \"@radix-ui/react-hover-card\";\nimport { forwardRef } from \"react\";\nimport type { ComponentPropsWithoutRef, ComponentRef } from \"react\";\nimport { cx } from \"../../utils/cx/cx.js\";\n\n/**\n * A floating card that appears when a user hovers over a trigger element.\n * This is the root, stateful component that manages the open/closed state of the hover card.\n *\n * @see https://mantle.ngrok.com/components/hover-card#hovercardroot\n *\n * @example\n * ```tsx\n * <HoverCard.Root>\n * <HoverCard.Trigger asChild>\n * <Button type=\"button\" appearance=\"outlined\">\n * Hover me\n * </Button>\n * </HoverCard.Trigger>\n * <HoverCard.Content>\n * <p>This is the hover card content.</p>\n * </HoverCard.Content>\n * </HoverCard.Root>\n * ```\n */\nconst Root = ({\n\tcloseDelay = 300,\n\topenDelay = 100,\n\t...props\n}: ComponentPropsWithoutRef<typeof HoverCardPrimitive.Root>) => (\n\t<HoverCardPrimitive.Root closeDelay={closeDelay} openDelay={openDelay} {...props} />\n);\nRoot.displayName = \"HoverCard\";\n\n/**\n * The trigger element that opens the hover card when hovered.\n *\n * @see https://mantle.ngrok.com/components/hover-card#hovercardtrigger\n *\n * @example\n * ```tsx\n * <HoverCard.Root>\n * <HoverCard.Trigger asChild>\n * <Button type=\"button\" appearance=\"outlined\">\n * Hover me\n * </Button>\n * </HoverCard.Trigger>\n * <HoverCard.Content>\n * <p>This is the hover card content.</p>\n * </HoverCard.Content>\n * </HoverCard.Root>\n * ```\n */\nconst Trigger = HoverCardPrimitive.Trigger;\nTrigger.displayName = \"HoverCardTrigger\";\n\n/**\n * The portal for a HoverCard. Should be rendered as a child of the `HoverCard` component.\n * Renders a portal that the `HoverCard.Content` is rendered into.\n *\n * You likely don't need to use this component directly, as it is used internally by the `HoverCard.Content` component.\n */\nconst Portal = HoverCardPrimitive.Portal;\nPortal.displayName = \"HoverCardPortal\";\n\n/**\n * The content to render inside the hover card.\n *\n * @see https://mantle.ngrok.com/components/hover-card#hovercardcontent\n *\n * @example\n * ```tsx\n * <HoverCard.Root>\n * <HoverCard.Trigger asChild>\n * <Button type=\"button\" appearance=\"outlined\">\n * Hover me\n * </Button>\n * </HoverCard.Trigger>\n * <HoverCard.Content>\n * <p>This is the hover card content.</p>\n * </HoverCard.Content>\n * </HoverCard.Root>\n * ```\n */\nconst Content = forwardRef<\n\tComponentRef<typeof HoverCardPrimitive.Content>,\n\tComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>\n>(({ className, onClick, align = \"center\", sideOffset = 4, ...props }, ref) => (\n\t<Portal>\n\t\t<HoverCardPrimitive.Content\n\t\t\tref={ref}\n\t\t\talign={align}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={cx(\n\t\t\t\t\"bg-popover border-popover z-50 w-64 rounded-md border p-4 shadow-md outline-hidden\",\n\t\t\t\t\"data-state-open:animate-in data-state-closed:animate-out data-state-closed:fade-out-0 data-state-open:fade-in-0 data-state-closed:zoom-out-95 data-state-open:zoom-in-95 data-side-bottom:slide-in-from-top-2 data-side-left:slide-in-from-right-2 data-side-right:slide-in-from-left-2 data-side-top:slide-in-from-bottom-2\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tonClick={(event) => {\n\t\t\t\t/**\n\t\t\t\t * Prevent the click event from propagating up to parent/containing elements\n\t\t\t\t */\n\t\t\t\tevent.stopPropagation();\n\t\t\t\tonClick?.(event);\n\t\t\t}}\n\t\t\t{...props}\n\t\t/>\n\t</Portal>\n));\nContent.displayName = HoverCardPrimitive.Content.displayName;\n\n/**\n * A floating card that appears when a user hovers over a trigger element.\n *\n * @see https://mantle.ngrok.com/components/hover-card\n *\n * @example\n * ```tsx\n * <HoverCard.Root>\n * <HoverCard.Trigger asChild>\n * <Button type=\"button\" appearance=\"outlined\">\n * Hover me\n * </Button>\n * </HoverCard.Trigger>\n * <HoverCard.Content>\n * <p>This is the hover card content.</p>\n * </HoverCard.Content>\n * </HoverCard.Root>\n * ```\n */\nconst HoverCard = {\n\t/**\n\t * The root, stateful component that manages the open/closed state of the hover card.\n\t *\n\t * @see https://mantle.ngrok.com/components/hover-card#hovercardroot\n\t *\n\t * @example\n\t * ```tsx\n\t * <HoverCard.Root>\n\t * <HoverCard.Trigger asChild>\n\t * <Button>Hover me</Button>\n\t * </HoverCard.Trigger>\n\t * <HoverCard.Content>\n\t * <p>This is the hover card content.</p>\n\t * </HoverCard.Content>\n\t * </HoverCard.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * The content to render inside the hover card. Appears in a portal with rich styling and animations.\n\t *\n\t * @see https://mantle.ngrok.com/components/hover-card#hovercardcontent\n\t *\n\t * @example\n\t * ```tsx\n\t * <HoverCard.Root>\n\t * <HoverCard.Trigger asChild>\n\t * <Button type=\"button\" variant=\"link\">@username</Button>\n\t * </HoverCard.Trigger>\n\t * <HoverCard.Content side=\"top\">\n\t * <div className=\"space-y-2\">\n\t * <Text weight=\"strong\">User Profile</Text>\n\t * <Text>Additional information about the user.</Text>\n\t * <Button type=\"button\" size=\"sm\">Follow</Button>\n\t * </div>\n\t * </HoverCard.Content>\n\t * </HoverCard.Root>\n\t * ```\n\t */\n\tContent,\n\t/**\n\t * The portal container for rendering hover card content outside the normal DOM tree.\n\t *\n\t * @see https://mantle.ngrok.com/components/hover-card#api-reference\n\t *\n\t * @example\n\t * ```tsx\n\t * <HoverCard.Root>\n\t * <HoverCard.Trigger asChild>\n\t * <Text>Hover over me</Text>\n\t * </HoverCard.Trigger>\n\t * <HoverCard.Portal>\n\t * <HoverCard.Content>\n\t * <Text>This content is rendered in a portal.</Text>\n\t * </HoverCard.Content>\n\t * </HoverCard.Portal>\n\t * </HoverCard.Root>\n\t * ```\n\t */\n\tPortal,\n\t/**\n\t * The trigger element that opens the hover card when hovered.\n\t *\n\t * @see https://mantle.ngrok.com/components/hover-card#hovercardtrigger\n\t *\n\t * @example\n\t * ```tsx\n\t * <HoverCard.Root>\n\t * <HoverCard.Trigger asChild>\n\t * <Button type=\"button\" variant=\"ghost\">\n\t * Hover for details\n\t * </Button>\n\t * </HoverCard.Trigger>\n\t * <HoverCard.Content>\n\t * <div className=\"space-y-1\">\n\t * <Text weight=\"strong\">Quick Info</Text>\n\t * <Text>This appears when you hover over the trigger.</Text>\n\t * </div>\n\t * </HoverCard.Content>\n\t * </HoverCard.Root>\n\t * ```\n\t */\n\tTrigger,\n} as const;\n\nexport {\n\t//,\n\tHoverCard,\n};\n"],"mappings":"6JA2BA,MAAM,GAAQ,CACb,aAAa,IACb,YAAY,IACZ,GAAG,KAEH,EAAC,EAAmB,KAApB,CAAqC,aAAuB,YAAW,GAAI,EAAS,CAAA,CAErF,EAAK,YAAc,YAqBnB,MAAM,EAAU,EAAmB,QACnC,EAAQ,YAAc,mBAQtB,MAAM,EAAS,EAAmB,OAClC,EAAO,YAAc,kBAqBrB,MAAM,EAAU,GAGb,CAAE,YAAW,UAAS,QAAQ,SAAU,aAAa,EAAG,GAAG,GAAS,IACtE,EAAC,EAAD,CAAA,SACC,EAAC,EAAmB,QAApB,CACM,MACE,QACK,aACZ,UAAW,EACV,qFACA,+TACA,EACA,CACD,QAAU,GAAU,CAInB,EAAM,iBAAiB,CACvB,IAAU,EAAM,EAEjB,GAAI,EACH,CAAA,CACM,CAAA,CACR,CACF,EAAQ,YAAc,EAAmB,QAAQ,YAqBjD,MAAM,EAAY,CAkBjB,OAsBA,UAoBA,SAuBA,UACA"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import { t as SvgAttributes } from "./types-Dh4BVhXC.js";
|
|
2
|
+
import * as react from "react";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
4
|
|
|
5
|
+
//#region src/components/icon/icon.d.ts
|
|
5
6
|
type IconProps = Omit<SvgAttributes, "children"> & {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
/**
|
|
8
|
+
* A single SVG icon element.
|
|
9
|
+
*/
|
|
10
|
+
svg: ReactNode;
|
|
10
11
|
};
|
|
11
12
|
/**
|
|
12
13
|
* Decorates an svg icon with automatic sizing styles and a `shrink-0` class.
|
|
@@ -21,5 +22,6 @@ type IconProps = Omit<SvgAttributes, "children"> & {
|
|
|
21
22
|
* ```
|
|
22
23
|
*/
|
|
23
24
|
declare const Icon: react.ForwardRefExoticComponent<Omit<IconProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
|
|
24
|
-
|
|
25
|
-
export {
|
|
25
|
+
//#endregion
|
|
26
|
+
export { IconProps as n, Icon as t };
|
|
27
|
+
//# sourceMappingURL=icon-B1XLv02t.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./cx-bKromGBh.js";import{t}from"./svg-only-BVLlbQ4e.js";import{forwardRef as n}from"react";import{jsx as r}from"react/jsx-runtime";const i=n(({className:n,style:i,svg:a,...o},s)=>r(t,{ref:s,className:e(`size-5`,n),style:i,svg:a,...o}));i.displayName=`Icon`;export{i as t};
|
|
2
|
+
//# sourceMappingURL=icon-B5oNYYrJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon-B5oNYYrJ.js","names":[],"sources":["../src/components/icon/icon.tsx"],"sourcesContent":["import { type ComponentRef, type ReactNode, forwardRef } from \"react\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { SvgOnly } from \"./svg-only.js\";\nimport type { SvgAttributes } from \"./types.js\";\n\ntype IconProps = Omit<SvgAttributes, \"children\"> & {\n\t/**\n\t * A single SVG icon element.\n\t */\n\tsvg: ReactNode;\n};\n\n/**\n * Decorates an svg icon with automatic sizing styles and a `shrink-0` class.\n *\n * @see https://mantle.ngrok.com/components/icon\n *\n * @example\n * ```tsx\n * import { ShrimpIcon } from \"@phosphor-icons/react/Shrimp\";\n *\n * <Icon svg={<ShrimpIcon />} />\n * ```\n */\nconst Icon = forwardRef<ComponentRef<\"svg\">, IconProps>(\n\t({ className, style, svg, ...props }, ref) => (\n\t\t<SvgOnly ref={ref} className={cx(\"size-5\", className)} style={style} svg={svg} {...props} />\n\t),\n);\nIcon.displayName = \"Icon\";\n\nexport {\n\t//,\n\tIcon,\n};\n\nexport type {\n\t//,\n\tIconProps,\n};\n"],"mappings":"sJAwBA,MAAM,EAAO,GACX,CAAE,YAAW,QAAO,MAAK,GAAG,GAAS,IACrC,EAAC,EAAD,CAAc,MAAK,UAAW,EAAG,SAAU,EAAU,CAAS,QAAY,MAAK,GAAI,EAAS,CAAA,CAE7F,CACD,EAAK,YAAc"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { t as WithAsChild } from "./as-child-XMVTepJu.js";
|
|
2
|
+
import { t as VariantProps } from "./variant-props-UE-phTwh.js";
|
|
3
|
+
import * as react from "react";
|
|
4
|
+
import { ButtonHTMLAttributes, ReactNode } from "react";
|
|
5
|
+
import * as class_variance_authority_types0 from "class-variance-authority/types";
|
|
6
|
+
|
|
7
|
+
//#region src/components/button/icon-button.d.ts
|
|
8
|
+
declare const iconButtonVariants: (props?: ({
|
|
9
|
+
appearance?: "ghost" | "outlined" | null | undefined;
|
|
10
|
+
isLoading?: boolean | null | undefined;
|
|
11
|
+
size?: "xs" | "sm" | "md" | null | undefined;
|
|
12
|
+
} & class_variance_authority_types0.ClassProp) | undefined) => string;
|
|
13
|
+
type IconButtonVariants = VariantProps<typeof iconButtonVariants>;
|
|
14
|
+
/**
|
|
15
|
+
* The props for the `Button` component.
|
|
16
|
+
*/
|
|
17
|
+
type IconButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & WithAsChild & IconButtonVariants & {
|
|
18
|
+
/**
|
|
19
|
+
* The accessible label for the icon. This label will be visually hidden but announced to screen reader users, similar to alt text for img tags.
|
|
20
|
+
*/
|
|
21
|
+
label: string;
|
|
22
|
+
/**
|
|
23
|
+
* An icon to render inside the button. If the `state` is `"pending"`, then
|
|
24
|
+
* the icon will automatically be replaced with a spinner.
|
|
25
|
+
*/
|
|
26
|
+
icon: ReactNode;
|
|
27
|
+
} & ({
|
|
28
|
+
/**
|
|
29
|
+
* Use the `asChild` prop to compose Radix's functionality onto alternative
|
|
30
|
+
* element types or your own React components.
|
|
31
|
+
*
|
|
32
|
+
* When `asChild` is set to `true`, mantle will not render a default DOM
|
|
33
|
+
* element, instead cloning the component's child and passing it the props and
|
|
34
|
+
* behavior required to make it functional.
|
|
35
|
+
*
|
|
36
|
+
* asChild can be used as deeply as you need to. This means it is a great way
|
|
37
|
+
* to compose multiple primitive's behavior together.
|
|
38
|
+
*
|
|
39
|
+
* @see https://www.radix-ui.com/docs/primitives/guides/composition#composition
|
|
40
|
+
*/
|
|
41
|
+
asChild: true;
|
|
42
|
+
/**
|
|
43
|
+
* The default behavior of the button. Possible values are: `"button"`, `"submit"`, and `"reset"`.
|
|
44
|
+
*
|
|
45
|
+
* if `asChild` is NOT used: Unlike the native `<button>` element, this prop is required and has no default value.
|
|
46
|
+
*
|
|
47
|
+
* If `asChild` IS used: This prop HAS NO EFFECT, is REMOVED, and has no default value. This is because we do not want the `button` `type` to automatically merge with any child anchor `type` attribute because the `anchor` `type` is _strictly different_ than the `button` type, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#type
|
|
48
|
+
*
|
|
49
|
+
* @enum
|
|
50
|
+
* - `"button"`: The button has no default behavior, and does nothing when pressed by default. It can have client-side scripts listen to the element's events, which are triggered when the events occur.
|
|
51
|
+
* - `"reset"`: The button resets all the controls to their initial values.
|
|
52
|
+
* - `"submit"`: The button submits the form data to the server.
|
|
53
|
+
*
|
|
54
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#type
|
|
55
|
+
*/
|
|
56
|
+
type?: ButtonHTMLAttributes<HTMLButtonElement>["type"];
|
|
57
|
+
} | {
|
|
58
|
+
asChild?: false | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* The default behavior of the button. Possible values are: `"button"`, `"submit"`, and `"reset"`.
|
|
61
|
+
*
|
|
62
|
+
* if `asChild` is NOT used: Unlike the native `<button>` element, this prop is required and has no default value.
|
|
63
|
+
*
|
|
64
|
+
* If `asChild` IS used: This prop HAS NO EFFECT, is REMOVED, and has no default value. This is because we do not want the `button` `type` to automatically merge with any child anchor `type` attribute because the `anchor` `type` is _strictly different_ than the `button` type, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#type
|
|
65
|
+
*
|
|
66
|
+
* @enum
|
|
67
|
+
* - `"button"`: The button has no default behavior, and does nothing when pressed by default. It can have client-side scripts listen to the element's events, which are triggered when the events occur.
|
|
68
|
+
* - `"reset"`: The button resets all the controls to their initial values.
|
|
69
|
+
* - `"submit"`: The button submits the form data to the server.
|
|
70
|
+
*
|
|
71
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#type
|
|
72
|
+
*/
|
|
73
|
+
type: Exclude<ButtonHTMLAttributes<HTMLButtonElement>["type"], undefined>;
|
|
74
|
+
});
|
|
75
|
+
/**
|
|
76
|
+
* Renders a button or a component that looks like a button, an interactive
|
|
77
|
+
* element activated by a user with a mouse, keyboard, finger, voice command, or
|
|
78
|
+
* other assistive technology. Once activated, it then performs an action, such
|
|
79
|
+
* as submitting a form or opening a dialog.
|
|
80
|
+
* Renders only a single icon as children with an accessible, screen-reader-only label.
|
|
81
|
+
*
|
|
82
|
+
* @see https://mantle.ngrok.com/components/button
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```tsx
|
|
86
|
+
* <IconButton
|
|
87
|
+
* type="button"
|
|
88
|
+
* icon={<TrashIcon />}
|
|
89
|
+
* label="Delete item"
|
|
90
|
+
* appearance="ghost"
|
|
91
|
+
* size="sm"
|
|
92
|
+
* />
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
96
|
+
//#endregion
|
|
97
|
+
export { IconButtonProps as n, IconButton as t };
|
|
98
|
+
//# sourceMappingURL=icon-button-2r6S3HVA.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./cx-bKromGBh.js";import{t}from"./icon-B5oNYYrJ.js";import{t as n}from"./booleanish-CBGdPL3Q.js";import{t as r}from"./slot-DdnjeV2n.js";import{Children as i,cloneElement as a,forwardRef as o,isValidElement as s}from"react";import c from"tiny-invariant";import{Fragment as l,jsx as u,jsxs as d}from"react/jsx-runtime";import{cva as f}from"class-variance-authority";import{CircleNotchIcon as p}from"@phosphor-icons/react/CircleNotch";const m=e(`icon-button`,`inline-flex shrink-0 items-center justify-center rounded-[var(--icon-button-border-radius,0.375rem)] border`,`focus:outline-hidden focus-visible:ring-4`,`disabled:cursor-default disabled:opacity-50`,`not-disabled:active:scale-97 ease-out transition-transform duration-150`),h=f(m,{variants:{appearance:{ghost:`text-strong focus-visible:ring-focus-accent not-disabled:hover:bg-neutral-500/10 not-disabled:hover:text-strong not-disabled:active:bg-neutral-500/15 not-disabled:active:text-strong border-transparent`,outlined:`border-form bg-form text-strong focus-visible:border-accent-600 focus-visible:ring-focus-accent not-disabled:hover:border-neutral-400 not-disabled:hover:bg-form-hover not-disabled:hover:text-strong not-disabled:active:border-neutral-400 not-disabled:active:bg-neutral-500/10 not-disabled:active:text-strong focus-visible:not-disabled:hover:border-accent-600 focus-visible:not-disabled:active:border-accent-600`},isLoading:{false:``,true:`opacity-50`},size:{xs:`size-6`,sm:`size-7`,md:`size-9`}},defaultVariants:{appearance:`outlined`,size:`md`}}),g=o(({"aria-disabled":o,appearance:f,asChild:m=!1,children:g,className:_,disabled:v,icon:y,isLoading:b=!1,label:x,size:S,type:C,...w},T)=>{let E=n(o??v??b),D=b?u(p,{className:`animate-spin`}):y,O={"aria-disabled":E,className:e(h({appearance:f,isLoading:b,size:S}),_),"data-appearance":f,"data-disabled":E,"data-icon-button":!0,"data-loading":b,"data-size":S,disabled:E,ref:T,...w},k=d(l,{children:[u(`span`,{className:`sr-only`,children:x}),u(t,{svg:D})]});return m?(c(s(g)&&i.only(g),"When using `asChild`, IconButton must be passed a single child as a JSX tag."),u(r,{...O,children:a(g,{},k)})):u(`button`,{...O,type:C,children:k})});g.displayName=`IconButton`;export{m as n,h as r,g as t};
|
|
2
|
+
//# sourceMappingURL=icon-button-D4e9-dq-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon-button-D4e9-dq-.js","names":[],"sources":["../src/components/button/icon-button.tsx"],"sourcesContent":["import { CircleNotchIcon } from \"@phosphor-icons/react/CircleNotch\";\nimport { cva } from \"class-variance-authority\";\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { Children, cloneElement, forwardRef, isValidElement } from \"react\";\nimport invariant from \"tiny-invariant\";\nimport type { VariantProps, WithAsChild } from \"../../types/index.js\";\nimport { parseBooleanish } from \"../../types/index.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { Icon } from \"../icon/index.js\";\nimport { Slot } from \"../slot/index.js\";\n\nconst baseIconButtonClasses = cx(\n\t\"icon-button\",\n\t\"inline-flex shrink-0 items-center justify-center rounded-[var(--icon-button-border-radius,0.375rem)] border\",\n\t\"focus:outline-hidden focus-visible:ring-4\",\n\t\"disabled:cursor-default disabled:opacity-50\",\n\t\"not-disabled:active:scale-97 ease-out transition-transform duration-150\",\n);\n\nconst iconButtonVariants = cva(baseIconButtonClasses, {\n\tvariants: {\n\t\t/**\n\t\t * Defines the visual style of the Button.\n\t\t */\n\t\tappearance: {\n\t\t\tghost:\n\t\t\t\t\"text-strong focus-visible:ring-focus-accent not-disabled:hover:bg-neutral-500/10 not-disabled:hover:text-strong not-disabled:active:bg-neutral-500/15 not-disabled:active:text-strong border-transparent\",\n\t\t\toutlined:\n\t\t\t\t\"border-form bg-form text-strong focus-visible:border-accent-600 focus-visible:ring-focus-accent not-disabled:hover:border-neutral-400 not-disabled:hover:bg-form-hover not-disabled:hover:text-strong not-disabled:active:border-neutral-400 not-disabled:active:bg-neutral-500/10 not-disabled:active:text-strong focus-visible:not-disabled:hover:border-accent-600 focus-visible:not-disabled:active:border-accent-600\",\n\t\t},\n\t\t/**\n\t\t * Whether or not the button is in a loading state, default `false`. Setting `isLoading` will\n\t\t * replace the `icon` with a spinner.\n\t\t * It will also disable user interaction with the button and set `aria-disabled`.\n\t\t */\n\t\tisLoading: {\n\t\t\tfalse: \"\",\n\t\t\ttrue: \"opacity-50\",\n\t\t},\n\t\t/**\n\t\t * The size of the IconButton.\n\t\t */\n\t\tsize: {\n\t\t\txs: \"size-6\",\n\t\t\tsm: \"size-7\",\n\t\t\tmd: \"size-9\",\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tappearance: \"outlined\",\n\t\tsize: \"md\",\n\t},\n});\n\ntype IconButtonVariants = VariantProps<typeof iconButtonVariants>;\n\n/**\n * The props for the `Button` component.\n */\ntype IconButtonProps = ButtonHTMLAttributes<HTMLButtonElement> &\n\tWithAsChild &\n\tIconButtonVariants & {\n\t\t/**\n\t\t * The accessible label for the icon. This label will be visually hidden but announced to screen reader users, similar to alt text for img tags.\n\t\t */\n\t\tlabel: string;\n\t\t/**\n\t\t * An icon to render inside the button. If the `state` is `\"pending\"`, then\n\t\t * the icon will automatically be replaced with a spinner.\n\t\t */\n\t\ticon: ReactNode;\n\t} & (\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * Use the `asChild` prop to compose Radix's functionality onto alternative\n\t\t\t\t * element types or your own React components.\n\t\t\t\t *\n\t\t\t\t * When `asChild` is set to `true`, mantle will not render a default DOM\n\t\t\t\t * element, instead cloning the component's child and passing it the props and\n\t\t\t\t * behavior required to make it functional.\n\t\t\t\t *\n\t\t\t\t * asChild can be used as deeply as you need to. This means it is a great way\n\t\t\t\t * to compose multiple primitive's behavior together.\n\t\t\t\t *\n\t\t\t\t * @see https://www.radix-ui.com/docs/primitives/guides/composition#composition\n\t\t\t\t */\n\t\t\t\tasChild: true;\n\t\t\t\t/**\n\t\t\t\t * The default behavior of the button. Possible values are: `\"button\"`, `\"submit\"`, and `\"reset\"`.\n\t\t\t\t *\n\t\t\t\t * if `asChild` is NOT used: Unlike the native `<button>` element, this prop is required and has no default value.\n\t\t\t\t *\n\t\t\t\t * If `asChild` IS used: This prop HAS NO EFFECT, is REMOVED, and has no default value. This is because we do not want the `button` `type` to automatically merge with any child anchor `type` attribute because the `anchor` `type` is _strictly different_ than the `button` type, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#type\n\t\t\t\t *\n\t\t\t\t * @enum\n\t\t\t\t * - `\"button\"`: The button has no default behavior, and does nothing when pressed by default. It can have client-side scripts listen to the element's events, which are triggered when the events occur.\n\t\t\t\t * - `\"reset\"`: The button resets all the controls to their initial values.\n\t\t\t\t * - `\"submit\"`: The button submits the form data to the server.\n\t\t\t\t *\n\t\t\t\t * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#type\n\t\t\t\t */\n\t\t\t\ttype?: ButtonHTMLAttributes<HTMLButtonElement>[\"type\"];\n\t\t }\n\t\t| {\n\t\t\t\tasChild?: false | undefined;\n\t\t\t\t/**\n\t\t\t\t * The default behavior of the button. Possible values are: `\"button\"`, `\"submit\"`, and `\"reset\"`.\n\t\t\t\t *\n\t\t\t\t * if `asChild` is NOT used: Unlike the native `<button>` element, this prop is required and has no default value.\n\t\t\t\t *\n\t\t\t\t * If `asChild` IS used: This prop HAS NO EFFECT, is REMOVED, and has no default value. This is because we do not want the `button` `type` to automatically merge with any child anchor `type` attribute because the `anchor` `type` is _strictly different_ than the `button` type, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#type\n\t\t\t\t *\n\t\t\t\t * @enum\n\t\t\t\t * - `\"button\"`: The button has no default behavior, and does nothing when pressed by default. It can have client-side scripts listen to the element's events, which are triggered when the events occur.\n\t\t\t\t * - `\"reset\"`: The button resets all the controls to their initial values.\n\t\t\t\t * - `\"submit\"`: The button submits the form data to the server.\n\t\t\t\t *\n\t\t\t\t * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#type\n\t\t\t\t */\n\t\t\t\ttype: Exclude<ButtonHTMLAttributes<HTMLButtonElement>[\"type\"], undefined>;\n\t\t }\n\t);\n\n/**\n * Renders a button or a component that looks like a button, an interactive\n * element activated by a user with a mouse, keyboard, finger, voice command, or\n * other assistive technology. Once activated, it then performs an action, such\n * as submitting a form or opening a dialog.\n * Renders only a single icon as children with an accessible, screen-reader-only label.\n *\n * @see https://mantle.ngrok.com/components/button\n *\n * @example\n * ```tsx\n * <IconButton\n * type=\"button\"\n * icon={<TrashIcon />}\n * label=\"Delete item\"\n * appearance=\"ghost\"\n * size=\"sm\"\n * />\n * ```\n */\nconst IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(\n\t(\n\t\t{\n\t\t\t\"aria-disabled\": _ariaDisabled,\n\t\t\tappearance,\n\t\t\tasChild = false,\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tdisabled: _disabled,\n\t\t\ticon: propIcon,\n\t\t\tisLoading = false,\n\t\t\tlabel,\n\t\t\tsize,\n\t\t\ttype,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst disabled = parseBooleanish(_ariaDisabled ?? _disabled ?? isLoading);\n\t\tconst icon = isLoading ? <CircleNotchIcon className=\"animate-spin\" /> : propIcon;\n\n\t\tconst buttonProps = {\n\t\t\t\"aria-disabled\": disabled,\n\t\t\tclassName: cx(iconButtonVariants({ appearance, isLoading, size }), className),\n\t\t\t\"data-appearance\": appearance,\n\t\t\t\"data-disabled\": disabled,\n\t\t\t\"data-icon-button\": true,\n\t\t\t\"data-loading\": isLoading,\n\t\t\t\"data-size\": size,\n\t\t\tdisabled,\n\t\t\tref,\n\t\t\t...props,\n\t\t};\n\n\t\tconst innerChildren = (\n\t\t\t<>\n\t\t\t\t<span className=\"sr-only\">{label}</span>\n\t\t\t\t<Icon svg={icon} />\n\t\t\t</>\n\t\t);\n\n\t\tif (asChild) {\n\t\t\tinvariant(\n\t\t\t\tisValidElement(children) && Children.only(children),\n\t\t\t\t\"When using `asChild`, IconButton must be passed a single child as a JSX tag.\",\n\t\t\t);\n\n\t\t\treturn <Slot {...buttonProps}>{cloneElement(children, {}, innerChildren)}</Slot>;\n\t\t}\n\n\t\treturn (\n\t\t\t<button {...buttonProps} type={type}>\n\t\t\t\t{innerChildren}\n\t\t\t</button>\n\t\t);\n\t},\n);\nIconButton.displayName = \"IconButton\";\n\nexport {\n\tbaseIconButtonClasses,\n\t//,\n\tIconButton,\n\ticonButtonVariants,\n};\n\nexport type {\n\t//,\n\tIconButtonProps,\n};\n"],"mappings":"mcAWA,MAAM,EAAwB,EAC7B,cACA,8GACA,4CACA,8CACA,0EACA,CAEK,EAAqB,EAAI,EAAuB,CACrD,SAAU,CAIT,WAAY,CACX,MACC,2MACD,SACC,4ZACD,CAMD,UAAW,CACV,MAAO,GACP,KAAM,aACN,CAID,KAAM,CACL,GAAI,SACJ,GAAI,SACJ,GAAI,SACJ,CACD,CACD,gBAAiB,CAChB,WAAY,WACZ,KAAM,KACN,CACD,CAAC,CA2FI,EAAa,GAEjB,CACC,gBAAiB,EACjB,aACA,UAAU,GACV,WACA,YACA,SAAU,EACV,KAAM,EACN,YAAY,GACZ,QACA,OACA,OACA,GAAG,GAEJ,IACI,CACJ,IAAM,EAAW,EAAgB,GAAiB,GAAa,EAAU,CACnE,EAAO,EAAY,EAAC,EAAD,CAAiB,UAAU,eAAiB,CAAA,CAAG,EAElE,EAAc,CACnB,gBAAiB,EACjB,UAAW,EAAG,EAAmB,CAAE,aAAY,YAAW,OAAM,CAAC,CAAE,EAAU,CAC7E,kBAAmB,EACnB,gBAAiB,EACjB,mBAAoB,GACpB,eAAgB,EAChB,YAAa,EACb,WACA,MACA,GAAG,EACH,CAEK,EACL,EAAA,EAAA,CAAA,SAAA,CACC,EAAC,OAAD,CAAM,UAAU,mBAAW,EAAa,CAAA,CACxC,EAAC,EAAD,CAAM,IAAK,EAAQ,CAAA,CACjB,CAAA,CAAA,CAYJ,OATI,GACH,EACC,EAAe,EAAS,EAAI,EAAS,KAAK,EAAS,CACnD,+EACA,CAEM,EAAC,EAAD,CAAM,GAAI,WAAc,EAAa,EAAU,EAAE,CAAE,EAAc,CAAQ,CAAA,EAIhF,EAAC,SAAD,CAAQ,GAAI,EAAmB,gBAC7B,EACO,CAAA,EAGX,CACD,EAAW,YAAc"}
|