@pearpages/pulp-react 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/accordion.css +2 -0
- package/dist/accordion.css.map +1 -1
- package/dist/accordion.js +2 -2
- package/dist/alert.css +24 -0
- package/dist/alert.css.map +1 -1
- package/dist/alert.js +7 -7
- package/dist/avatar.css +46 -0
- package/dist/avatar.css.map +1 -0
- package/dist/avatar.d.ts +41 -0
- package/dist/avatar.js +5 -0
- package/dist/avatar.js.map +1 -0
- package/dist/badge.css +39 -0
- package/dist/badge.css.map +1 -1
- package/dist/badge.d.ts +22 -5
- package/dist/badge.js +3 -2
- package/dist/button.css +22 -0
- package/dist/button.css.map +1 -1
- package/dist/button.d.ts +11 -2
- package/dist/button.js +5 -5
- package/dist/calendar.css +2 -0
- package/dist/calendar.css.map +1 -1
- package/dist/calendar.js +3 -3
- package/dist/card.css +1 -0
- package/dist/card.css.map +1 -1
- package/dist/card.js +2 -2
- package/dist/checkbox.css +2 -0
- package/dist/checkbox.css.map +1 -1
- package/dist/checkbox.js +4 -4
- package/dist/chip.css +95 -0
- package/dist/chip.css.map +1 -0
- package/dist/chip.d.ts +43 -0
- package/dist/chip.js +4 -0
- package/dist/chip.js.map +1 -0
- package/dist/{chunk-7DS4I7OJ.js → chunk-2E2ESMS2.js} +2 -2
- package/dist/chunk-2E2ESMS2.js.map +1 -0
- package/dist/{chunk-FH54XQ35.js → chunk-2IYYES7V.js} +2 -2
- package/dist/chunk-2IYYES7V.js.map +1 -0
- package/dist/{chunk-XDVS7HX7.js → chunk-2NVC3C7K.js} +3 -3
- package/dist/chunk-2NVC3C7K.js.map +1 -0
- package/dist/{chunk-IDNGNQNV.js → chunk-55QUKGK2.js} +2 -2
- package/dist/chunk-55QUKGK2.js.map +1 -0
- package/dist/{chunk-DVM37MEK.js → chunk-56RSH7GQ.js} +4 -4
- package/dist/chunk-56RSH7GQ.js.map +1 -0
- package/dist/chunk-5TYCIBLW.js +27 -0
- package/dist/chunk-5TYCIBLW.js.map +1 -0
- package/dist/chunk-7O6FTCZL.js +101 -0
- package/dist/chunk-7O6FTCZL.js.map +1 -0
- package/dist/{chunk-XXC34COT.js → chunk-A7TMFEQ2.js} +4 -4
- package/dist/chunk-A7TMFEQ2.js.map +1 -0
- package/dist/{chunk-GTTXRDXV.js → chunk-AZAI4OVR.js} +4 -4
- package/dist/chunk-AZAI4OVR.js.map +1 -0
- package/dist/{chunk-ASOQ2MVR.js → chunk-BR2EH4TK.js} +2 -2
- package/dist/chunk-BR2EH4TK.js.map +1 -0
- package/dist/{chunk-OUFAFINB.js → chunk-CLE2QGCU.js} +3 -3
- package/dist/chunk-CLE2QGCU.js.map +1 -0
- package/dist/{chunk-VSDEQHG4.js → chunk-DE67ECD7.js} +7 -5
- package/dist/chunk-DE67ECD7.js.map +1 -0
- package/dist/{chunk-YUHS5S5Y.js → chunk-DGIXNUNI.js} +2 -2
- package/dist/chunk-DGIXNUNI.js.map +1 -0
- package/dist/{chunk-T76YSNTZ.js → chunk-EDTA65L5.js} +3 -3
- package/dist/chunk-EDTA65L5.js.map +1 -0
- package/dist/{chunk-WDWTQKIJ.js → chunk-F2YI5N4L.js} +5 -5
- package/dist/chunk-F2YI5N4L.js.map +1 -0
- package/dist/{chunk-3GWESUGD.js → chunk-F3S5BHX2.js} +2 -2
- package/dist/chunk-F3S5BHX2.js.map +1 -0
- package/dist/{chunk-4DER5LHM.js → chunk-FFCEY76B.js} +10 -5
- package/dist/chunk-FFCEY76B.js.map +1 -0
- package/dist/{chunk-Y4TZA77G.js → chunk-GWTHITZO.js} +3 -3
- package/dist/chunk-GWTHITZO.js.map +1 -0
- package/dist/chunk-HDC2IQV2.js +34 -0
- package/dist/chunk-HDC2IQV2.js.map +1 -0
- package/dist/{chunk-2KG43BOT.js → chunk-HKNIEQ2V.js} +4 -4
- package/dist/chunk-HKNIEQ2V.js.map +1 -0
- package/dist/{chunk-MRQWUCBA.js → chunk-HPQ462R5.js} +3 -3
- package/dist/chunk-HPQ462R5.js.map +1 -0
- package/dist/{chunk-Z4PN6B2C.js → chunk-IB5UUE3S.js} +2 -2
- package/dist/chunk-IB5UUE3S.js.map +1 -0
- package/dist/{chunk-4HRNRTXI.js → chunk-IRNTXAA7.js} +3 -3
- package/dist/{chunk-4HRNRTXI.js.map → chunk-IRNTXAA7.js.map} +1 -1
- package/dist/{chunk-OXYP34CG.js → chunk-JOGIN4SS.js} +3 -3
- package/dist/chunk-JOGIN4SS.js.map +1 -0
- package/dist/chunk-KSLKNWWM.js +28 -0
- package/dist/chunk-KSLKNWWM.js.map +1 -0
- package/dist/{chunk-2ZP4ZBI5.js → chunk-LKWZZIRZ.js} +2 -2
- package/dist/chunk-LKWZZIRZ.js.map +1 -0
- package/dist/{chunk-ASNTNTJW.js → chunk-O5LII5XP.js} +2 -2
- package/dist/chunk-O5LII5XP.js.map +1 -0
- package/dist/chunk-OKA2PLDV.js +85 -0
- package/dist/chunk-OKA2PLDV.js.map +1 -0
- package/dist/{chunk-BBV4L5WO.js → chunk-Q6SYKNZ5.js} +3 -3
- package/dist/{chunk-BBV4L5WO.js.map → chunk-Q6SYKNZ5.js.map} +1 -1
- package/dist/chunk-QID6YYFF.js +33 -0
- package/dist/chunk-QID6YYFF.js.map +1 -0
- package/dist/{chunk-ZVDN3GRI.js → chunk-QJG5ILK5.js} +3 -3
- package/dist/{chunk-ZVDN3GRI.js.map → chunk-QJG5ILK5.js.map} +1 -1
- package/dist/chunk-QXHSA4QD.js +43 -0
- package/dist/chunk-QXHSA4QD.js.map +1 -0
- package/dist/chunk-S632WN4W.js +106 -0
- package/dist/chunk-S632WN4W.js.map +1 -0
- package/dist/{chunk-N7L66GMG.js → chunk-SDIK6VSC.js} +3 -3
- package/dist/chunk-SDIK6VSC.js.map +1 -0
- package/dist/{chunk-2PXTVZ7H.js → chunk-SXMORGSG.js} +3 -3
- package/dist/chunk-SXMORGSG.js.map +1 -0
- package/dist/{chunk-DWE374JX.js → chunk-UMK4D234.js} +3 -3
- package/dist/chunk-UMK4D234.js.map +1 -0
- package/dist/{chunk-AWQHULJC.js → chunk-VIGD7KHC.js} +2 -2
- package/dist/chunk-VIGD7KHC.js.map +1 -0
- package/dist/{chunk-TGMDOQCL.js → chunk-VS2HPJIX.js} +3 -3
- package/dist/chunk-VS2HPJIX.js.map +1 -0
- package/dist/{chunk-O6OBFL3Q.js → chunk-W2UUZ2DC.js} +3 -3
- package/dist/chunk-W2UUZ2DC.js.map +1 -0
- package/dist/{chunk-5SBKZS56.js → chunk-W6HEBHA7.js} +3 -3
- package/dist/{chunk-5SBKZS56.js.map → chunk-W6HEBHA7.js.map} +1 -1
- package/dist/{chunk-GUZMLYST.js → chunk-WDIFWMKE.js} +6 -6
- package/dist/chunk-WDIFWMKE.js.map +1 -0
- package/dist/{chunk-TVI5AXLE.js → chunk-WJDDKNE7.js} +3 -3
- package/dist/{chunk-TVI5AXLE.js.map → chunk-WJDDKNE7.js.map} +1 -1
- package/dist/{chunk-7RQQASKS.js → chunk-XGWFTFGR.js} +3 -3
- package/dist/chunk-XGWFTFGR.js.map +1 -0
- package/dist/{chunk-UX42PQLT.js → chunk-Y4YVAHD2.js} +5 -5
- package/dist/chunk-Y4YVAHD2.js.map +1 -0
- package/dist/chunk-Y7KC2FDU.js +88 -0
- package/dist/chunk-Y7KC2FDU.js.map +1 -0
- package/dist/{chunk-P5C2U5ZF.js → chunk-YBECKOVP.js} +3 -3
- package/dist/chunk-YBECKOVP.js.map +1 -0
- package/dist/{chunk-75GTNRBH.js → chunk-YK2OOM56.js} +3 -3
- package/dist/chunk-YK2OOM56.js.map +1 -0
- package/dist/{chunk-OGIQRHNF.js → chunk-ZEVQQQOA.js} +3 -3
- package/dist/chunk-ZEVQQQOA.js.map +1 -0
- package/dist/{chunk-I4KC4V6A.js → chunk-ZL5MMRLG.js} +3 -3
- package/dist/chunk-ZL5MMRLG.js.map +1 -0
- package/dist/combobox.css +9 -0
- package/dist/combobox.css.map +1 -1
- package/dist/combobox.js +7 -7
- package/dist/component-manifest.json +679 -8
- package/dist/date-picker.css +4 -0
- package/dist/date-picker.css.map +1 -1
- package/dist/date-picker.js +5 -5
- package/dist/dialog.css +1 -0
- package/dist/dialog.css.map +1 -1
- package/dist/dialog.js +1 -1
- package/dist/divider.css +37 -0
- package/dist/divider.css.map +1 -0
- package/dist/divider.d.ts +35 -0
- package/dist/divider.js +4 -0
- package/dist/divider.js.map +1 -0
- package/dist/empty-state.css +175 -0
- package/dist/empty-state.css.map +1 -0
- package/dist/empty-state.d.ts +40 -0
- package/dist/empty-state.js +7 -0
- package/dist/empty-state.js.map +1 -0
- package/dist/field.css +1 -0
- package/dist/field.css.map +1 -1
- package/dist/field.js +2 -2
- package/dist/heading.css +1 -0
- package/dist/heading.css.map +1 -1
- package/dist/heading.js +1 -1
- package/dist/icon-button.css +23 -0
- package/dist/icon-button.css.map +1 -1
- package/dist/icon-button.js +6 -6
- package/dist/icon.css +1 -0
- package/dist/icon.css.map +1 -1
- package/dist/icon.js +1 -1
- package/dist/index.css +527 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +49 -43
- package/dist/inline.css +1 -0
- package/dist/inline.css.map +1 -1
- package/dist/inline.js +1 -1
- package/dist/link.css +35 -0
- package/dist/link.css.map +1 -0
- package/dist/link.d.ts +37 -0
- package/dist/link.js +5 -0
- package/dist/link.js.map +1 -0
- package/dist/listbox.css +2 -0
- package/dist/listbox.css.map +1 -1
- package/dist/listbox.js +3 -3
- package/dist/menu.css +2 -0
- package/dist/menu.css.map +1 -1
- package/dist/menu.js +3 -3
- package/dist/pagination.css +24 -0
- package/dist/pagination.css.map +1 -1
- package/dist/pagination.js +7 -7
- package/dist/picker.css +7 -0
- package/dist/picker.css.map +1 -1
- package/dist/picker.js +5 -5
- package/dist/popover.css +1 -0
- package/dist/popover.css.map +1 -1
- package/dist/popover.js +2 -2
- package/dist/progress.css +2 -0
- package/dist/progress.css.map +1 -1
- package/dist/progress.js +2 -2
- package/dist/radio.css +2 -0
- package/dist/radio.css.map +1 -1
- package/dist/radio.js +3 -3
- package/dist/segmented-control.css +111 -0
- package/dist/segmented-control.css.map +1 -0
- package/dist/segmented-control.d.ts +90 -0
- package/dist/segmented-control.js +5 -0
- package/dist/segmented-control.js.map +1 -0
- package/dist/select.css +2 -0
- package/dist/select.css.map +1 -1
- package/dist/select.js +3 -3
- package/dist/sheet.css +30 -0
- package/dist/sheet.css.map +1 -1
- package/dist/sheet.d.ts +9 -2
- package/dist/sheet.js +2 -2
- package/dist/skeleton.css +1 -0
- package/dist/skeleton.css.map +1 -1
- package/dist/skeleton.js +1 -1
- package/dist/slider.css +2 -0
- package/dist/slider.css.map +1 -1
- package/dist/slider.js +2 -2
- package/dist/spinner.css +2 -0
- package/dist/spinner.css.map +1 -1
- package/dist/spinner.js +2 -2
- package/dist/stack.css +1 -0
- package/dist/stack.css.map +1 -1
- package/dist/stack.js +1 -1
- package/dist/switch.css +2 -0
- package/dist/switch.css.map +1 -1
- package/dist/switch.js +4 -4
- package/dist/table.css +2 -0
- package/dist/table.css.map +1 -1
- package/dist/table.js +2 -2
- package/dist/tabs.css +1 -0
- package/dist/tabs.css.map +1 -1
- package/dist/tabs.js +1 -1
- package/dist/text-field.css +65 -0
- package/dist/text-field.css.map +1 -1
- package/dist/text-field.d.ts +15 -2
- package/dist/text-field.js +3 -3
- package/dist/text.css +1 -0
- package/dist/text.css.map +1 -1
- package/dist/text.js +1 -1
- package/dist/textarea.css +2 -0
- package/dist/textarea.css.map +1 -1
- package/dist/textarea.js +3 -3
- package/dist/toast.css +25 -0
- package/dist/toast.css.map +1 -1
- package/dist/toast.d.ts +21 -3
- package/dist/toast.js +8 -8
- package/dist/tooltip.css +1 -0
- package/dist/tooltip.css.map +1 -1
- package/dist/tooltip.js +2 -2
- package/dist/visually-hidden.css +1 -0
- package/dist/visually-hidden.css.map +1 -1
- package/dist/visually-hidden.js +1 -1
- package/package.json +36 -6
- package/dist/chunk-2KG43BOT.js.map +0 -1
- package/dist/chunk-2PXTVZ7H.js.map +0 -1
- package/dist/chunk-2ZP4ZBI5.js.map +0 -1
- package/dist/chunk-3GWESUGD.js.map +0 -1
- package/dist/chunk-4DER5LHM.js.map +0 -1
- package/dist/chunk-6I26MMQF.js +0 -19
- package/dist/chunk-6I26MMQF.js.map +0 -1
- package/dist/chunk-75GTNRBH.js.map +0 -1
- package/dist/chunk-7DS4I7OJ.js.map +0 -1
- package/dist/chunk-7RQQASKS.js.map +0 -1
- package/dist/chunk-ASNTNTJW.js.map +0 -1
- package/dist/chunk-ASOQ2MVR.js.map +0 -1
- package/dist/chunk-AWQHULJC.js.map +0 -1
- package/dist/chunk-DVM37MEK.js.map +0 -1
- package/dist/chunk-DWE374JX.js.map +0 -1
- package/dist/chunk-FH54XQ35.js.map +0 -1
- package/dist/chunk-GTTXRDXV.js.map +0 -1
- package/dist/chunk-GUZMLYST.js.map +0 -1
- package/dist/chunk-I4KC4V6A.js.map +0 -1
- package/dist/chunk-IDNGNQNV.js.map +0 -1
- package/dist/chunk-MRQWUCBA.js.map +0 -1
- package/dist/chunk-MXWXJZFS.js +0 -48
- package/dist/chunk-MXWXJZFS.js.map +0 -1
- package/dist/chunk-N7L66GMG.js.map +0 -1
- package/dist/chunk-O6OBFL3Q.js.map +0 -1
- package/dist/chunk-OGIQRHNF.js.map +0 -1
- package/dist/chunk-OUFAFINB.js.map +0 -1
- package/dist/chunk-OXYP34CG.js.map +0 -1
- package/dist/chunk-P5C2U5ZF.js.map +0 -1
- package/dist/chunk-T76YSNTZ.js.map +0 -1
- package/dist/chunk-TGMDOQCL.js.map +0 -1
- package/dist/chunk-UX42PQLT.js.map +0 -1
- package/dist/chunk-VSDEQHG4.js.map +0 -1
- package/dist/chunk-WDWTQKIJ.js.map +0 -1
- package/dist/chunk-XDVS7HX7.js.map +0 -1
- package/dist/chunk-XUROYTJ7.js +0 -28
- package/dist/chunk-XUROYTJ7.js.map +0 -1
- package/dist/chunk-XXC34COT.js.map +0 -1
- package/dist/chunk-Y4TZA77G.js.map +0 -1
- package/dist/chunk-YUHS5S5Y.js.map +0 -1
- package/dist/chunk-Z4PN6B2C.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sheet/drag.ts","../src/sheet/Sheet.module.css","../src/sheet/Sheet.tsx"],"names":["content","handle"],"mappings":"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","file":"chunk-7O6FTCZL.js","sourcesContent":["/**\n * When a dragged bottom sheet should close on release. Ported from bitepals'\n * `shouldDismiss()` with its thresholds and its test cases: past a quarter of\n * the sheet's height, or a flick faster than 500 px/s, downwards only.\n */\nconst DISMISS_DISTANCE_RATIO = 0.25;\nconst DISMISS_DISTANCE_FALLBACK_PX = 120;\nconst DISMISS_VELOCITY_PX_PER_S = 500;\n\nexport interface DismissInput {\n /** How far the sheet has been dragged down, in px. Zero or negative never dismisses. */\n offsetY: number;\n /** Downward speed at release, in px/s. */\n velocityY: number;\n /** The sheet's height in px; 0 when it cannot be measured, which falls back to a fixed distance. */\n panelHeight: number;\n distanceRatio?: number;\n distanceFallbackPx?: number;\n velocityThreshold?: number;\n}\n\nexport function shouldDismiss({\n offsetY,\n velocityY,\n panelHeight,\n distanceRatio = DISMISS_DISTANCE_RATIO,\n distanceFallbackPx = DISMISS_DISTANCE_FALLBACK_PX,\n velocityThreshold = DISMISS_VELOCITY_PX_PER_S,\n}: DismissInput): boolean {\n if (offsetY <= 0) return false;\n const distanceThreshold = panelHeight > 0 ? panelHeight * distanceRatio : distanceFallbackPx;\n return offsetY > distanceThreshold || velocityY > velocityThreshold;\n}\n\n/** Speed over the last ~100 ms of samples, in px/s: the release flick, not the average of the whole drag. */\nexport function releaseVelocity(samples: ReadonlyArray<{ time: number; y: number }>, windowMs = 100): number {\n const last = samples[samples.length - 1];\n if (!last) return 0;\n const first = samples.find((sample) => last.time - sample.time <= windowMs) ?? last;\n const elapsed = last.time - first.time;\n return elapsed > 0 ? ((last.y - first.y) / elapsed) * 1000 : 0;\n}\n","/*\n * The vendor (@pearpages/modals) docks the dialog and sizes it from three variables it declares on\n * :root. This class sits on the dialog element itself, so its own declarations beat the inherited\n * :root defaults whatever the cascade layer or import order: no specificity fight with the\n * vendor's unlayered rules, which only *read* these. Colour, type and motion timing come from\n * Dialog's mapping on the portal root.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .content {\n --modal-width-sheet: var(--sheet-width);\n --modal-height-sheet: var(--sheet-height);\n --modal-animation-translate-sheet: var(--sheet-motion-translate);\n }\n\n /*\n * Drag to dismiss (bottom sheets). The vendor moves the sheet with `transform`; the drag uses\n * the separate `translate` property, so the two never fight. --_drag is set by the handle while\n * the pointer is down: the one per-instance value, like Progress's --_value.\n */\n .content[data-draggable] {\n translate: 0 var(--_drag, 0);\n transition: translate var(--sheet-handle-snap-duration) var(--motion-easing-standard);\n\n &[data-dragging] {\n transition: none;\n }\n }\n\n .handle {\n display: grid;\n flex: none;\n place-items: center;\n block-size: var(--sheet-handle-hit-height);\n cursor: grab;\n touch-action: none;\n\n &::before {\n inline-size: var(--sheet-handle-width);\n block-size: var(--sheet-handle-height);\n border-radius: var(--sheet-handle-radius);\n background: var(--sheet-handle-bg);\n content: \"\";\n }\n\n [data-dragging] > & {\n cursor: grabbing;\n }\n\n /* Following the finger is motion: without it there is no handle to offer. */\n @media (prefers-reduced-motion: reduce) {\n display: none;\n }\n }\n}\n","import { useRef, type ComponentProps, type PointerEvent } from 'react';\nimport { useModalId, useModalStack } from '@pearpages/modals';\nimport { Dialog, type DialogProps } from '../dialog';\nimport { classes } from '../internal/classes';\nimport { releaseVelocity, shouldDismiss } from './drag';\nimport styles from './Sheet.module.css';\n\nexport type SheetProps = DialogProps;\n\n/** The edge a sheet docks to. `start` and `end` follow the writing direction. */\nexport type SheetPlacement = 'start' | 'end' | 'top' | 'bottom';\n\nexport interface SheetContentProps extends Omit<ComponentProps<typeof Dialog.Content>, 'placement'> {\n /**\n * The edge the sheet docks to. `start` and `end` take `--sheet-width` and the full height;\n * `top` and `bottom` take the full width and `--sheet-height`. There is no `center`: a centred\n * sheet is a Dialog.\n * @default 'end'\n */\n placement?: SheetPlacement;\n /**\n * `placement=\"bottom\"` only: a grab handle at the top of the sheet that can be dragged down to\n * close it (past a quarter of the sheet's height, or with a flick). Pointer and touch only, and\n * off under `prefers-reduced-motion`; Escape, the backdrop and `Sheet.Close` are unchanged.\n * @default true\n */\n dragToDismiss?: boolean;\n}\n\n/**\n * A dialog docked to an edge of the viewport: a side panel for detail or settings that keeps the\n * page in view, or a bottom sheet on a phone. It is Dialog with a `placement`: the same parts\n * (`Sheet.Trigger`, `Sheet.Content`, `Sheet.Header`, `Sheet.Title`, `Sheet.Description`,\n * `Sheet.Close`, `Sheet.Body`, `Sheet.Footer`), the same focus trap, stacking and dismissal, and\n * the same colours and type, from Dialog's tokens. Only the size is Sheet's: `--sheet-width`,\n * `--sheet-height` and `--sheet-motion-translate`, the distance it slides in from its edge.\n *\n * It needs what Dialog needs: `DialogSystem` mounted once near the app root, and\n * `@pearpages/modals/styles.css` imported into the `vendor` layer.\n *\n * @status experimental\n * @category Overlays\n * @accessibility The drag handle of a bottom sheet is a pointer and touch shortcut, hidden from assistive technology and not focusable: it adds no keyboard stop, and closing by keyboard stays Escape or `Sheet.Close`, so always render a `Sheet.Close` in a sheet that can be dragged. Otherwise Dialog's: `role=\"dialog\"` with `aria-modal`, named by `Sheet.Title` and described by `Sheet.Description`; focus moves in on open, is trapped, and returns to the trigger on close; Escape and the backdrop dismiss it; the page behind is inert. Docking changes the layout only, never the semantics.\n * @do Always render a `Sheet.Title`.\n * @do Dock to `end` for detail and settings beside the page, and to `bottom` for choices on a narrow screen.\n * @dont Use it for a short confirmation; a centred Dialog reads as more urgent and takes less room.\n * @dont Put the page's primary content in a sheet: it is modal, so everything behind it is out of reach.\n */\nexport function Sheet(props: SheetProps) {\n return <Dialog {...props} />;\n}\n\n/**\n * The docked dialog element. Dialog's `Content`, with `placement` and the class that maps pulp's\n * `--sheet-*` tokens onto the vendor's sheet variables.\n */\nfunction SheetContent({ placement = 'end', dragToDismiss = true, className, children, ...rest }: SheetContentProps) {\n const draggable = placement === 'bottom' && dragToDismiss;\n return (\n <Dialog.Content {...rest} placement={placement} className={classes(styles.content, className)} data-draggable={draggable ? '' : undefined}>\n {draggable && <SheetHandle />}\n {children}\n </Dialog.Content>\n );\n}\n\n/** The grab handle. Internal: rendered by `Sheet.Content`, never on its own. */\nfunction SheetHandle() {\n const id = useModalId();\n const { close } = useModalStack();\n const drag = useRef<{ startY: number; panel: HTMLElement; samples: Array<{ time: number; y: number }> } | null>(null);\n\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n const panel = event.currentTarget.closest<HTMLElement>('[role=\"dialog\"]');\n if (!panel || event.button !== 0) return;\n // The sheet following the finger is motion; without it the handle is not offered at all (see the stylesheet).\n if (typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;\n event.currentTarget.setPointerCapture?.(event.pointerId);\n drag.current = { startY: event.clientY, panel, samples: [{ time: performance.now(), y: event.clientY }] };\n panel.dataset.dragging = '';\n };\n\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n if (!drag.current) return;\n drag.current.samples.push({ time: performance.now(), y: event.clientY });\n // The one per-instance value: how far this sheet has been pulled. A custom property, read by the stylesheet.\n drag.current.panel.style.setProperty('--_drag', `${Math.max(0, event.clientY - drag.current.startY)}px`);\n };\n\n const end = (event: PointerEvent<HTMLDivElement>, cancelled: boolean) => {\n const current = drag.current;\n if (!current) return;\n drag.current = null;\n current.samples.push({ time: performance.now(), y: event.clientY });\n delete current.panel.dataset.dragging;\n const dismiss =\n !cancelled &&\n shouldDismiss({ offsetY: event.clientY - current.startY, velocityY: releaseVelocity(current.samples), panelHeight: current.panel.offsetHeight });\n if (dismiss) {\n // The offset stays, so the sheet leaves from where it was let go instead of snapping back first.\n close(id);\n } else {\n current.panel.style.removeProperty('--_drag');\n }\n };\n\n return (\n <div\n className={styles.handle}\n aria-hidden=\"true\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={(event) => end(event, false)}\n onPointerCancel={(event) => end(event, true)}\n />\n );\n}\n\nSheet.displayName = 'Sheet';\nSheetContent.displayName = 'Sheet.Content';\nSheet.Trigger = Dialog.Trigger;\nSheet.Content = SheetContent;\nSheet.Header = Dialog.Header;\nSheet.Title = Dialog.Title;\nSheet.Description = Dialog.Description;\nSheet.Close = Dialog.Close;\nSheet.Body = Dialog.Body;\nSheet.Footer = Dialog.Footer;\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IconButton } from './chunk-
|
|
2
|
-
import { Icon } from './chunk-
|
|
1
|
+
import { IconButton } from './chunk-56RSH7GQ.js';
|
|
2
|
+
import { Icon } from './chunk-O5LII5XP.js';
|
|
3
3
|
import { classes } from './chunk-MI4QUKQS.js';
|
|
4
4
|
import { Close, Warning, Check, Info } from '@pearpages/pulp-icons';
|
|
5
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -49,5 +49,5 @@ function Alert({
|
|
|
49
49
|
Alert.displayName = "Alert";
|
|
50
50
|
|
|
51
51
|
export { Alert };
|
|
52
|
-
//# sourceMappingURL=chunk-
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
52
|
+
//# sourceMappingURL=chunk-A7TMFEQ2.js.map
|
|
53
|
+
//# sourceMappingURL=chunk-A7TMFEQ2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/alert/Alert.module.css","../src/alert/Alert.tsx"],"names":["alert","icon","body","title","content","action","dismiss"],"mappings":";;;;;;;AAAA,IAAA,aAAA,GAAA;AAAA,EAKG,KAAA,EAAAA,aAAAA;AAAA,EAyCA,IAAA,EAAAC,YAAAA;AAAA,EAKA,IAAA,EAAAC,YAAAA;AAAA,EAQA,KAAA,EAAAC,aAAAA;AAAA,EAMA,OAAA,EAAAC,eAAAA;AAAA,EAIA,MAAA,EAAAC,cAAAA;AAAA,EAOA,OAAA,EAAAC;AAAA,CAAA;AC3CH,IAAM,YAAA,GAA6C;AAAA,EACjD,IAAA,sBAAO,IAAA,EAAA,EAAK,CAAA;AAAA,EACZ,OAAA,sBAAU,KAAA,EAAA,EAAM,CAAA;AAAA,EAChB,OAAA,sBAAU,OAAA,EAAA,EAAQ,CAAA;AAAA,EAClB,KAAA,sBAAQ,OAAA,EAAA,EAAQ;AAClB,CAAA;AAeO,SAAS,KAAA,CAAM;AAAA,EACpB,IAAA,GAAO,MAAA;AAAA,EACP,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA,GAAe,SAAA;AAAA,EACf,IAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAe;AACb,EAAA,MAAM,IAAA,GAAO,IAAA,KAAS,IAAA,KAAS,OAAA,GAAU,WAAA,GAAc,QAAA,CAAA;AACvD,EAAA,MAAM,OAAO,IAAA,KAAS,KAAA,GAAQ,MAAA,GAAY,IAAA,KAAS,cAAc,OAAA,GAAU,QAAA;AAC3E,EAAA,MAAM,KAAA,GAAQ,IAAA,KAAS,MAAA,GAAY,YAAA,CAAa,IAAI,CAAA,GAAI,IAAA;AAExD,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAK,GAAG,IAAA,EAAM,GAAA,EAAU,IAAA,EAAY,SAAA,EAAW,OAAA,CAAQ,aAAA,CAAO,KAAA,EAAO,SAAS,CAAA,EAAG,aAAW,IAAA,EAC1F,QAAA,EAAA;AAAA,IAAA,KAAA,wBACE,IAAA,EAAA,EAAK,IAAA,EAAK,MAAK,SAAA,EAAW,aAAA,CAAO,MAC/B,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,oBAEF,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,aAAA,CAAO,IAAA,EACpB,QAAA,EAAA;AAAA,MAAA,KAAA,oBAAS,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAW,aAAA,CAAO,OAAQ,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,MAC5C,4BAAY,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,aAAA,CAAO,SAAU,QAAA,EAAS,CAAA;AAAA,MACtD,0BAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,aAAA,CAAO,QAAS,QAAA,EAAA,MAAA,EAAO;AAAA,KAAA,EACpD,CAAA;AAAA,IACC,6BACC,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,MAAK,IAAA,EAAK,KAAA,EAAO,YAAA,EAAc,IAAA,sBAAO,KAAA,EAAA,EAAM,CAAA,EAAI,SAAS,SAAA,EAAW,SAAA,EAAW,cAAO,OAAA,EAAS;AAAA,GAAA,EAE/H,CAAA;AAEJ;AAEA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-A7TMFEQ2.js","sourcesContent":["/* Every value is a token (--alert-*). Tone resolves into private custom properties. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .alert {\n --_bg: var(--alert-info-bg);\n --_accent: var(--alert-info-accent);\n --_title: var(--alert-info-title);\n\n display: flex;\n align-items: flex-start;\n gap: var(--alert-gap);\n padding: var(--alert-padding);\n border: var(--alert-border-width) solid var(--_accent);\n border-inline-start-width: var(--alert-accent-width);\n border-radius: var(--alert-radius);\n background-color: var(--_bg);\n color: var(--alert-fg);\n font-size: var(--alert-font-size);\n\n &[data-tone=\"info\"] {\n --_bg: var(--alert-info-bg);\n --_accent: var(--alert-info-accent);\n --_title: var(--alert-info-title);\n }\n\n &[data-tone=\"success\"] {\n --_bg: var(--alert-success-bg);\n --_accent: var(--alert-success-accent);\n --_title: var(--alert-success-title);\n }\n\n &[data-tone=\"warning\"] {\n --_bg: var(--alert-warning-bg);\n --_accent: var(--alert-warning-accent);\n --_title: var(--alert-warning-title);\n }\n\n &[data-tone=\"error\"] {\n --_bg: var(--alert-error-bg);\n --_accent: var(--alert-error-accent);\n --_title: var(--alert-error-title);\n }\n }\n\n .icon {\n flex: none;\n color: var(--_accent);\n }\n\n .body {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: var(--space-1);\n min-inline-size: 0;\n }\n\n .title {\n margin: 0;\n color: var(--_title);\n font-weight: var(--alert-title-font-weight);\n }\n\n .content {\n overflow-wrap: anywhere;\n }\n\n .action {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-2);\n margin-block-start: var(--space-1);\n }\n\n .dismiss {\n flex: none;\n margin-block: calc(-1 * var(--space-1));\n margin-inline-end: calc(-1 * var(--space-2));\n }\n}\n","import type { HTMLAttributes, ReactNode, Ref } from 'react';\nimport { Check, Close, Info, Warning } from '@pearpages/pulp-icons';\nimport { Icon } from '../icon';\nimport { IconButton } from '../icon-button';\nimport { classes } from '../internal/classes';\nimport styles from './Alert.module.css';\n\nexport type AlertTone = 'info' | 'success' | 'warning' | 'error';\nexport type AlertLive = 'polite' | 'assertive' | 'off';\n\nexport interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** @default 'info' */\n tone?: AlertTone;\n title?: ReactNode;\n /** Replaces the tone's default glyph; `null` shows none. */\n icon?: ReactNode | null;\n /** Buttons or links placed under the body. */\n action?: ReactNode;\n /** Renders a dismiss button that calls this. */\n onDismiss?: () => void;\n /** @default 'Dismiss' */\n dismissLabel?: string;\n /**\n * How assistive technology announces it: `assertive` (`role=\"alert\"`),\n * `polite` (`role=\"status\"`) or `off` (no live role, for content present at\n * page load or inside another live region). Defaults to assertive for\n * `error`, polite otherwise.\n */\n live?: AlertLive;\n ref?: Ref<HTMLDivElement>;\n children?: ReactNode;\n}\n\nconst DEFAULT_ICON: Record<AlertTone, ReactNode> = {\n info: <Info />,\n success: <Check />,\n warning: <Warning />,\n error: <Warning />,\n};\n\n/**\n * An inline message with a tone. Tint, accent and title colour come from\n * the status tokens; the body keeps the default text colour so long\n * messages stay readable. Toast renders one Alert per notification.\n *\n * @status stable\n * @category Feedback\n * @accessibility `role=\"alert\"` for `tone=\"error\"` (assertive), `role=\"status\"` otherwise (polite); `live=\"off\"` opts out. The glyph is decorative; the tone is carried by the title and text, never by colour alone.\n * @do Give it a `title` when the body is more than one sentence.\n * Use `onDismiss` for messages the user can act on and clear.\n * @dont Announce errors through both an Alert and a Toast.\n * Use it as a page-level banner for marketing copy.\n */\nexport function Alert({\n tone = 'info',\n title,\n icon,\n action,\n onDismiss,\n dismissLabel = 'Dismiss',\n live,\n className,\n ref,\n children,\n ...rest\n}: AlertProps) {\n const mode = live ?? (tone === 'error' ? 'assertive' : 'polite');\n const role = mode === 'off' ? undefined : mode === 'assertive' ? 'alert' : 'status';\n const glyph = icon === undefined ? DEFAULT_ICON[tone] : icon;\n\n return (\n <div {...rest} ref={ref} role={role} className={classes(styles.alert, className)} data-tone={tone}>\n {glyph && (\n <Icon size=\"md\" className={styles.icon}>\n {glyph}\n </Icon>\n )}\n <div className={styles.body}>\n {title && <p className={styles.title}>{title}</p>}\n {children && <div className={styles.content}>{children}</div>}\n {action && <div className={styles.action}>{action}</div>}\n </div>\n {onDismiss && (\n <IconButton variant=\"ghost\" size=\"sm\" label={dismissLabel} icon={<Close />} onClick={onDismiss} className={styles.dismiss} />\n )}\n </div>\n );\n}\n\nAlert.displayName = 'Alert';\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useRovingFocus } from './chunk-I5OZ63W7.js';
|
|
2
2
|
import { useDismiss } from './chunk-NAYFLTK6.js';
|
|
3
3
|
import { useFloatingPosition } from './chunk-U6QRAD73.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { Icon } from './chunk-O5LII5XP.js';
|
|
5
|
+
import { renderAsChild } from './chunk-QJG5ILK5.js';
|
|
6
6
|
import { classes } from './chunk-MI4QUKQS.js';
|
|
7
7
|
import { createContext, useState, useCallback, useId, useRef, useEffect, useContext } from 'react';
|
|
8
8
|
import { createPortal } from 'react-dom';
|
|
@@ -177,5 +177,5 @@ Menu.Item = MenuItem;
|
|
|
177
177
|
Menu.Separator = MenuSeparator;
|
|
178
178
|
|
|
179
179
|
export { Menu };
|
|
180
|
-
//# sourceMappingURL=chunk-
|
|
181
|
-
//# sourceMappingURL=chunk-
|
|
180
|
+
//# sourceMappingURL=chunk-AZAI4OVR.js.map
|
|
181
|
+
//# sourceMappingURL=chunk-AZAI4OVR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/menu/Menu.module.css","../src/menu/Menu.tsx"],"names":["content","item","label","separator"],"mappings":"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","file":"chunk-AZAI4OVR.js","sourcesContent":["/* Every value is a token (--menu-*). Position comes in as --_x/--_y from the floating hook. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .content {\n --_gap: var(--menu-gap);\n\n position: fixed;\n z-index: var(--menu-layer);\n inset-block-start: var(--_y);\n inset-inline-start: var(--_x);\n display: flex;\n flex-direction: column;\n min-inline-size: var(--menu-min-width);\n max-inline-size: calc(100vw - 2 * var(--space-4));\n padding: var(--menu-padding);\n border: var(--size-hairline) solid var(--menu-border);\n border-radius: var(--menu-radius);\n background-color: var(--menu-bg);\n color: var(--menu-fg);\n font-family: var(--font-family-body);\n box-shadow: var(--menu-shadow);\n animation: fade var(--menu-duration) var(--motion-easing-standard);\n\n &:focus-visible {\n outline: var(--menu-focus-ring-width) solid var(--menu-focus-ring);\n outline-offset: var(--menu-focus-ring-offset);\n }\n }\n\n .item {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n inline-size: 100%;\n padding-block: var(--menu-item-padding-block);\n padding-inline: var(--menu-item-padding-inline);\n border: none;\n border-radius: var(--menu-item-radius);\n background-color: transparent;\n color: var(--menu-item-fg);\n font-size: var(--menu-item-font-size);\n text-align: start;\n cursor: pointer;\n\n &[data-tone=\"danger\"] {\n color: var(--menu-item-fg-danger);\n }\n\n &[data-disabled] {\n color: var(--menu-item-fg-muted);\n cursor: not-allowed;\n }\n\n &:focus-visible {\n outline: none;\n background-color: var(--menu-item-bg-active);\n }\n\n &:hover:not([data-disabled]) {\n background-color: var(--menu-item-bg-active);\n }\n }\n\n .label {\n flex: 1;\n }\n\n .separator {\n block-size: var(--size-hairline);\n margin-block: var(--menu-padding);\n background-color: var(--menu-separator);\n }\n\n @keyframes fade {\n from {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .content {\n animation: none;\n }\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { Icon } from '../icon';\nimport { renderAsChild } from '../internal/asChild';\nimport { classes } from '../internal/classes';\nimport { useFloatingPosition, type FloatingPlacement } from '../internal/floating';\nimport { useDismiss } from '../internal/useDismiss';\nimport { useRovingFocus } from '../internal/useRovingFocus';\nimport styles from './Menu.module.css';\n\nexport type MenuPlacement = FloatingPlacement;\ntype FocusTarget = 'first' | 'last' | null;\n\ninterface MenuContextValue {\n open: boolean;\n setOpen: (open: boolean, focus?: FocusTarget) => void;\n focusTarget: FocusTarget;\n triggerId: string;\n contentId: string;\n floating: ReturnType<typeof useFloatingPosition>;\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null);\n\nfunction useMenu(part: string): MenuContextValue {\n const context = useContext(MenuContext);\n if (!context) throw new Error(`${part} must be rendered inside <Menu>`);\n return context;\n}\n\nexport interface MenuProps {\n open?: boolean;\n /** @default false */\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** @default 'bottom-start' */\n placement?: MenuPlacement;\n children: ReactNode;\n}\n\n/**\n * A list of actions opened from a button, following the WAI-ARIA menu\n * button pattern: Down/Up arrow on the trigger opens and focuses the first\n * or last item, arrows move with wraparound, Home and End jump, typing\n * jumps to the next item starting with that letter, Enter, Space or click\n * selects and closes, Escape and Tab close and return focus. Compose with\n * `Menu.Trigger`, `Menu.Content`, `Menu.Item` and `Menu.Separator`.\n *\n * @status stable\n * @category Overlays\n * @accessibility The WAI-ARIA menu button pattern: the trigger has `aria-haspopup=\"menu\"` and `aria-expanded`; the popup is `role=\"menu\"` named by the trigger with `menuitem` children. Down/Up opens to the first/last item, arrows wrap, Home/End jump, typing jumps, Enter/Space/click select and close, Escape and Tab close and return focus.\n * @do Use `tone=\"danger\"` for destructive items and put them after a separator.\n * @dont Put form controls or links that navigate inside a menu; those want Popover or a navigation list.\n * Use it for navigation between pages.\n */\nexport function Menu({ open, defaultOpen = false, onOpenChange, placement = 'bottom-start', children }: MenuProps) {\n const [uncontrolled, setUncontrolled] = useState(defaultOpen);\n const [focusTarget, setFocusTarget] = useState<FocusTarget>(null);\n const controlled = open !== undefined;\n const isOpen = controlled ? open : uncontrolled;\n const setOpen = useCallback(\n (next: boolean, focus: FocusTarget = null) => {\n setFocusTarget(next ? focus : null);\n if (!controlled) setUncontrolled(next);\n onOpenChange?.(next);\n },\n [controlled, onOpenChange],\n );\n const id = useId();\n const floating = useFloatingPosition({ open: isOpen, placement });\n\n return (\n <MenuContext.Provider value={{ open: isOpen, setOpen, focusTarget, triggerId: `${id}-trigger`, contentId: `${id}-menu`, floating }}>\n {children}\n </MenuContext.Provider>\n );\n}\n\nfunction mergeRefs<T>(a: Ref<T> | undefined, b: (node: T | null) => void) {\n return (node: T | null) => {\n b(node);\n if (typeof a === 'function') a(node);\n else if (a) a.current = node;\n };\n}\n\ninterface MenuTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean;\n ref?: Ref<HTMLButtonElement>;\n children: ReactNode;\n}\n\nfunction MenuTrigger({ asChild = false, onClick, onKeyDown, ref, children, ...rest }: MenuTriggerProps) {\n const menu = useMenu('Menu.Trigger');\n const props = {\n ...rest,\n id: menu.triggerId,\n 'aria-haspopup': 'menu' as const,\n 'aria-expanded': menu.open,\n 'aria-controls': menu.open ? menu.contentId : undefined,\n onClick: (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (!event.defaultPrevented) menu.setOpen(!menu.open, 'first');\n },\n onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n menu.setOpen(true, event.key === 'ArrowDown' ? 'first' : 'last');\n }\n },\n };\n const setRef = mergeRefs(ref, menu.floating.refs.setReference);\n // eslint-disable-next-line react-hooks/refs -- forwarded to the reference element, not read\n if (asChild) return renderAsChild('Menu.Trigger', children, { ...props, ref: setRef });\n return (\n <button type=\"button\" {...props} ref={setRef}>\n {children}\n </button>\n );\n}\n\ninterface MenuContentProps extends HTMLAttributes<HTMLDivElement> {\n ref?: Ref<HTMLDivElement>;\n children: ReactNode;\n}\n\nfunction MenuContent({ className, onKeyDown, ref, children, ...rest }: MenuContentProps) {\n const menu = useMenu('Menu.Content');\n const { refs, positionStyle, placement } = menu.floating;\n const contentRef = useRef<HTMLDivElement | null>(null);\n const rove = useRovingFocus({ orientation: 'vertical', selector: '[role=\"menuitem\"]' });\n\n useDismiss({\n open: menu.open,\n onDismiss: () => menu.setOpen(false),\n inside: () => [refs.reference.current as Element | null, refs.floating.current],\n });\n\n useEffect(() => {\n if (!menu.open) return;\n const content = contentRef.current;\n if (!content) return;\n const items = Array.from(content.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])'));\n const target = menu.focusTarget === 'last' ? items.at(-1) : items[0];\n (target ?? content).focus();\n return () => {\n const reference = refs.reference.current as HTMLElement | null;\n if (content.contains(document.activeElement) || document.activeElement === document.body) reference?.focus();\n };\n }, [menu.open, menu.focusTarget, refs.reference]);\n\n const typeahead = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key.length !== 1 || event.altKey || event.ctrlKey || event.metaKey) return false;\n const items = Array.from(event.currentTarget.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])'));\n const current = items.indexOf(document.activeElement as HTMLElement);\n const ordered = [...items.slice(current + 1), ...items.slice(0, current + 1)];\n const match = ordered.find((item) => item.textContent?.trim().toLowerCase().startsWith(event.key.toLowerCase()));\n if (!match) return false;\n event.preventDefault();\n match.focus();\n return true;\n };\n\n if (!menu.open) return null;\n return createPortal(\n <div\n {...rest}\n ref={mergeRefs(ref, (node) => {\n contentRef.current = node;\n refs.setFloating(node);\n })}\n id={menu.contentId}\n role=\"menu\"\n aria-labelledby={menu.triggerId}\n tabIndex={-1}\n className={classes(styles.content, className)}\n data-placement={placement}\n // eslint-disable-next-line react/forbid-dom-props -- per-instance position (--_x/--_y), see internal/floating.ts\n style={positionStyle}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (event.key === 'Tab') {\n menu.setOpen(false);\n return;\n }\n if (typeahead(event)) return;\n rove(event);\n }}\n >\n {children}\n </div>,\n document.body,\n );\n}\n\nexport type MenuItemTone = 'default' | 'danger';\n\ninterface MenuItemProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onSelect'> {\n /** Called when the item is chosen; the menu closes afterwards. */\n onSelect?: () => void;\n /** @default 'default' */\n tone?: MenuItemTone;\n /** Leading glyph, decorative. */\n icon?: ReactNode;\n ref?: Ref<HTMLButtonElement>;\n children: ReactNode;\n}\n\nfunction MenuItem({ onSelect, tone = 'default', icon, disabled, className, onClick, ref, children, ...rest }: MenuItemProps) {\n const menu = useMenu('Menu.Item');\n return (\n <button\n {...rest}\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n aria-disabled={disabled || undefined}\n className={classes(styles.item, className)}\n data-tone={tone}\n data-disabled={disabled ? '' : undefined}\n onClick={(event) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) return;\n onSelect?.();\n menu.setOpen(false);\n }}\n >\n {icon && <Icon size=\"inherit\">{icon}</Icon>}\n <span className={styles.label}>{children}</span>\n </button>\n );\n}\n\nfunction MenuSeparator({ className, ...rest }: HTMLAttributes<HTMLDivElement>) {\n return <div {...rest} role=\"separator\" className={classes(styles.separator, className)} />;\n}\n\nMenu.displayName = 'Menu';\nMenuTrigger.displayName = 'Menu.Trigger';\nMenuContent.displayName = 'Menu.Content';\nMenuItem.displayName = 'Menu.Item';\nMenuSeparator.displayName = 'Menu.Separator';\n\nMenu.Trigger = MenuTrigger;\nMenu.Content = MenuContent;\nMenu.Item = MenuItem;\nMenu.Separator = MenuSeparator;\n"]}
|
|
@@ -15,5 +15,5 @@ function Skeleton({ shape = "text", lines = 1, size = "md", className, ref, ...r
|
|
|
15
15
|
Skeleton.displayName = "Skeleton";
|
|
16
16
|
|
|
17
17
|
export { Skeleton };
|
|
18
|
-
//# sourceMappingURL=chunk-
|
|
19
|
-
//# sourceMappingURL=chunk-
|
|
18
|
+
//# sourceMappingURL=chunk-BR2EH4TK.js.map
|
|
19
|
+
//# sourceMappingURL=chunk-BR2EH4TK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/skeleton/Skeleton.module.css","../src/skeleton/Skeleton.tsx"],"names":["skeleton","lines"],"mappings":";;;;AAAA,IAAA,gBAAA,GAAA;AAAA,EAKG,QAAA,EAAAA,mBAAAA;AAAA,EAiCA,KAAA,EAAAC;AAAA,CAAA;ACPI,SAAS,QAAA,CAAS,EAAE,KAAA,GAAQ,MAAA,EAAQ,KAAA,GAAQ,CAAA,EAAG,IAAA,GAAO,IAAA,EAAM,SAAA,EAAW,GAAA,EAAK,GAAG,IAAA,EAAK,EAAkB;AAC3G,EAAA,IAAI,KAAA,KAAU,MAAA,IAAU,KAAA,GAAQ,CAAA,EAAG;AACjC,IAAA,2BACG,MAAA,EAAA,EAAM,GAAG,IAAA,EAAM,GAAA,EAAU,eAAY,MAAA,EAAO,SAAA,EAAW,OAAA,CAAQ,gBAAA,CAAO,OAAO,SAAS,CAAA,EAAG,cAAW,MAAA,EAClG,QAAA,EAAA,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,KAAA,EAAM,EAAG,CAAC,CAAA,EAAG,KAAA,yBAChC,MAAA,EAAA,EAAiB,SAAA,EAAW,iBAAO,QAAA,EAAU,YAAA,EAAW,MAAA,EAAO,WAAA,EAAW,UAAU,KAAA,GAAQ,CAAA,GAAI,KAAK,MAAA,EAAA,EAA3F,KAAsG,CAClH,CAAA,EACH,CAAA;AAAA,EAEJ;AACA,EAAA,2BAAQ,MAAA,EAAA,EAAM,GAAG,IAAA,EAAM,GAAA,EAAU,eAAY,MAAA,EAAO,SAAA,EAAW,OAAA,CAAQ,gBAAA,CAAO,UAAU,SAAS,CAAA,EAAG,YAAA,EAAY,KAAA,EAAO,aAAW,IAAA,EAAM,CAAA;AAC1I;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-BR2EH4TK.js","sourcesContent":["/* Every value is a token (--skeleton-*). Shimmer is a moving background-image; off under reduced motion. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .skeleton {\n --_size: var(--skeleton-circle-md);\n\n display: block;\n inline-size: 100%;\n border-radius: var(--skeleton-radius);\n background-color: var(--skeleton-base);\n background-image: linear-gradient(90deg, var(--skeleton-base), var(--skeleton-highlight), var(--skeleton-base));\n background-size: 200% 100%;\n animation: shimmer calc(6 * var(--skeleton-duration)) linear infinite;\n\n &[data-shape=\"text\"] {\n block-size: var(--skeleton-text-height);\n }\n\n &[data-shape=\"rect\"] {\n block-size: var(--skeleton-circle-lg);\n }\n\n &[data-shape=\"circle\"] {\n inline-size: var(--_size);\n block-size: var(--_size);\n border-radius: var(--radius-full);\n }\n\n &[data-size=\"sm\"] { --_size: var(--skeleton-circle-sm); }\n &[data-size=\"lg\"] { --_size: var(--skeleton-circle-lg); }\n\n &[data-last] {\n inline-size: 60%;\n }\n }\n\n .lines {\n display: flex;\n flex-direction: column;\n gap: var(--skeleton-gap);\n inline-size: 100%;\n }\n\n @keyframes shimmer {\n from {\n background-position: 200% 0;\n }\n\n to {\n background-position: -200% 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .skeleton {\n animation: none;\n background-image: none;\n }\n }\n}\n","import type { HTMLAttributes, Ref } from 'react';\nimport { classes } from '../internal/classes';\nimport styles from './Skeleton.module.css';\n\nexport type SkeletonShape = 'text' | 'rect' | 'circle';\nexport type SkeletonSize = 'sm' | 'md' | 'lg';\n\nexport interface SkeletonProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {\n /** @default 'text' */\n shape?: SkeletonShape;\n /** Number of text lines; the last is shorter. @default 1 */\n lines?: number;\n /** Circle diameter, from the control scale. @default 'md' */\n size?: SkeletonSize;\n ref?: Ref<HTMLSpanElement>;\n}\n\n/**\n * A placeholder for content that is loading. Decorative: hidden from\n * assistive technology, so mark the *container* `aria-busy` and announce\n * the loaded state there. Width for text and rect is the consumer's (pass\n * a `className`); the shimmer runs only when motion is allowed.\n *\n * @status stable\n * @category Feedback\n * @accessibility `aria-hidden`: a placeholder has nothing to announce. Mark the container `aria-busy` while loading and clear it when content arrives; the shimmer stops under reduced motion.\n * @do Match the shape of the content it stands in for.\n * Set `aria-busy` on the region, not on the skeleton.\n * @dont Show it for content that arrives in under a few hundred milliseconds.\n * Animate it when the user prefers reduced motion; the CSS already stops it.\n */\nexport function Skeleton({ shape = 'text', lines = 1, size = 'md', className, ref, ...rest }: SkeletonProps) {\n if (shape === 'text' && lines > 1) {\n return (\n <span {...rest} ref={ref} aria-hidden=\"true\" className={classes(styles.lines, className)} data-shape=\"text\">\n {Array.from({ length: lines }, (_, index) => (\n <span key={index} className={styles.skeleton} data-shape=\"text\" data-last={index === lines - 1 ? '' : undefined} />\n ))}\n </span>\n );\n }\n return <span {...rest} ref={ref} aria-hidden=\"true\" className={classes(styles.skeleton, className)} data-shape={shape} data-size={size} />;\n}\n\nSkeleton.displayName = 'Skeleton';\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ToggleField } from './chunk-
|
|
1
|
+
import { ToggleField } from './chunk-Q6SYKNZ5.js';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
// src/switch/Switch.module.css
|
|
@@ -41,5 +41,5 @@ function Switch({
|
|
|
41
41
|
Switch.displayName = "Switch";
|
|
42
42
|
|
|
43
43
|
export { Switch };
|
|
44
|
-
//# sourceMappingURL=chunk-
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
44
|
+
//# sourceMappingURL=chunk-CLE2QGCU.js.map
|
|
45
|
+
//# sourceMappingURL=chunk-CLE2QGCU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/switch/Switch.module.css","../src/switch/Switch.tsx"],"names":["switch","row","input"],"mappings":";;;;AAAA,IAAA,cAAA,GAAA;AAAA,EASG,MAAA,EAAAA,eAAAA;AAAA,EAWA,GAAA,EAAAC,YAAAA;AAAA,EAMA,KAAA,EAAAC;AAAA,CAAA;ACKI,SAAS,MAAA,CAAO;AAAA,EACrB,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP,QAAA;AAAA,EACA,QAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAA;AAAA,EACA,kBAAA,EAAoB,WAAA;AAAA,EACpB,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,uBACE,GAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,WAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,EAAA;AAAA,MACA,SAAA;AAAA,MACA,eAAe,cAAA,CAAO,MAAA;AAAA,MACtB,cAAc,cAAA,CAAO,GAAA;AAAA,MACrB,kBAAA,EAAkB,WAAA;AAAA,MAClB,OAAA,kBAAS,GAAA,CAAC,OAAA,EAAA,EAAO,GAAG,IAAA,EAAM,GAAA,EAAU,IAAA,EAAK,UAAA,EAAW,IAAA,EAAK,QAAA,EAAS,SAAA,EAAW,cAAA,CAAO,KAAA,EAAO;AAAA;AAAA,GAC7F;AAEJ;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-CLE2QGCU.js","sourcesContent":["/*\n * Every value is a token (--switch-*). The input is the track; its ::before\n * is the thumb. Size and invalid state resolve into private custom\n * properties on the root.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .switch {\n --_size: var(--switch-size-md);\n --_track: var(--switch-track-bg);\n\n font-family: var(--font-family-body);\n\n &[data-size=\"sm\"] { --_size: var(--switch-size-sm); }\n &[data-size=\"lg\"] { --_size: var(--switch-size-lg); }\n &[data-invalid] { --_track: var(--switch-track-invalid); }\n }\n\n .row {\n display: flex;\n align-items: center;\n gap: var(--switch-gap);\n }\n\n .input {\n --_inset: calc(2 * var(--switch-thumb-inset));\n\n position: relative;\n flex: none;\n inline-size: calc(2 * var(--_size));\n block-size: var(--_size);\n margin: 0;\n border: none;\n border-radius: var(--switch-radius);\n background-color: var(--_track);\n appearance: none;\n cursor: pointer;\n transition: background-color var(--switch-motion-duration) var(--motion-easing-standard);\n\n &::before {\n content: \"\";\n position: absolute;\n inset-block-start: var(--_inset);\n inset-inline-start: var(--_inset);\n inline-size: calc(var(--_size) - 2 * var(--_inset));\n block-size: calc(var(--_size) - 2 * var(--_inset));\n border-radius: var(--switch-radius);\n background-color: var(--switch-thumb);\n transition: translate var(--switch-motion-duration) var(--motion-easing-standard);\n }\n\n &:checked {\n background-color: var(--switch-track-bg-checked);\n\n &::before {\n translate: var(--_size) 0;\n background-color: var(--switch-thumb-checked);\n }\n }\n\n &:focus-visible {\n outline: var(--switch-focus-ring-width) solid var(--switch-focus-ring);\n outline-offset: var(--switch-focus-ring-offset);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &:hover:not(:disabled, :checked) {\n background-color: var(--switch-track-bg-hover);\n }\n\n &:hover:not(:disabled):checked {\n background-color: var(--switch-track-bg-checked-hover);\n }\n }\n}\n","import type { InputHTMLAttributes, ReactNode, Ref } from 'react';\nimport { ToggleField, type ToggleSize } from '../internal/ToggleField';\nimport styles from './Switch.module.css';\n\nexport type SwitchSize = ToggleSize;\n\nexport interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n /** Visible label beside the switch. */\n label: ReactNode;\n description?: ReactNode;\n error?: ReactNode;\n /** @default 'md' */\n size?: SwitchSize;\n /** The `<input>` element. */\n ref?: Ref<HTMLInputElement>;\n /** Applied to the wrapper, not the input. */\n className?: string;\n}\n\n/**\n * An on/off control: a native checkbox with `role=\"switch\"`, so assistive\n * technology announces on and off, and the browser handles keyboard, forms\n * and state. Use it for settings that take effect immediately; use Checkbox\n * for choices submitted with a form. Drawn with `--switch-*` tokens.\n *\n * @status stable\n * @category Forms\n * @accessibility A native checkbox with `role=\"switch\"`, so on and off are announced; Space toggles; label, description and error wire through Field.\n * @do Use it for settings that apply immediately.\n * @dont Use it inside a form that needs a submit; use Checkbox.\n */\nexport function Switch({\n label,\n description,\n error,\n size = 'md',\n required,\n disabled,\n id,\n className,\n ref,\n 'aria-describedby': describedBy,\n ...rest\n}: SwitchProps) {\n return (\n <ToggleField\n label={label}\n description={description}\n error={error}\n size={size}\n required={required}\n disabled={disabled}\n id={id}\n className={className}\n rootClassName={styles.switch}\n rowClassName={styles.row}\n aria-describedby={describedBy}\n control={<input {...rest} ref={ref} type=\"checkbox\" role=\"switch\" className={styles.input} />}\n />\n );\n}\n\nSwitch.displayName = 'Switch';\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Spinner } from './chunk-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { Spinner } from './chunk-ZL5MMRLG.js';
|
|
2
|
+
import { Icon } from './chunk-O5LII5XP.js';
|
|
3
|
+
import { renderAsChild } from './chunk-QJG5ILK5.js';
|
|
4
4
|
import { classes } from './chunk-MI4QUKQS.js';
|
|
5
5
|
import { Children, isValidElement } from 'react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -22,6 +22,7 @@ function hasText(node) {
|
|
|
22
22
|
}
|
|
23
23
|
function Button({
|
|
24
24
|
variant = "primary",
|
|
25
|
+
tone = "default",
|
|
25
26
|
size = "md",
|
|
26
27
|
loading = false,
|
|
27
28
|
iconStart,
|
|
@@ -47,6 +48,7 @@ function Button({
|
|
|
47
48
|
ref,
|
|
48
49
|
className: classes(Button_default.button, className),
|
|
49
50
|
"data-variant": variant,
|
|
51
|
+
"data-tone": tone === "danger" ? tone : void 0,
|
|
50
52
|
"data-size": size,
|
|
51
53
|
"data-loading": loading ? "" : void 0,
|
|
52
54
|
"aria-busy": loading || void 0,
|
|
@@ -73,5 +75,5 @@ function Button({
|
|
|
73
75
|
Button.displayName = "Button";
|
|
74
76
|
|
|
75
77
|
export { Button };
|
|
76
|
-
//# sourceMappingURL=chunk-
|
|
77
|
-
//# sourceMappingURL=chunk-
|
|
78
|
+
//# sourceMappingURL=chunk-DE67ECD7.js.map
|
|
79
|
+
//# sourceMappingURL=chunk-DE67ECD7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/button/Button.module.css","../src/button/Button.tsx"],"names":["button","label"],"mappings":"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","file":"chunk-DE67ECD7.js","sourcesContent":["/*\n * Every value is a token. State is expressed through data attributes so the\n * styling hooks survive a change of styling tool, and so tests and agents can\n * read state off the DOM.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--button-gap);\n min-block-size: var(--button-height-md);\n padding-block: 0;\n padding-inline: var(--button-padding-inline-md);\n border: 1px solid transparent;\n border-radius: var(--button-radius);\n font-family: var(--button-font-family);\n font-size: var(--button-font-size-md);\n font-weight: var(--button-font-weight);\n line-height: 1;\n text-decoration: none;\n white-space: nowrap;\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n transition:\n background-color var(--button-motion-duration) var(--motion-easing-standard),\n border-color var(--button-motion-duration) var(--motion-easing-standard),\n color var(--button-motion-duration) var(--motion-easing-standard);\n\n &:focus-visible {\n outline: var(--button-focus-ring-width) solid var(--button-focus-ring);\n outline-offset: var(--button-focus-ring-offset);\n }\n\n &:disabled,\n &[aria-disabled=\"true\"] {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &[data-loading] {\n cursor: progress;\n }\n\n &[data-size=\"sm\"] {\n min-block-size: var(--button-height-sm);\n padding-inline: var(--button-padding-inline-sm);\n font-size: var(--button-font-size-sm);\n }\n\n &[data-size=\"lg\"] {\n min-block-size: var(--button-height-lg);\n padding-inline: var(--button-padding-inline-lg);\n font-size: var(--button-font-size-lg);\n }\n\n &[data-variant=\"primary\"] {\n background-color: var(--button-primary-bg);\n color: var(--button-primary-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-primary-bg-hover);\n }\n\n &:active:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-primary-bg-active);\n }\n }\n\n &[data-variant=\"secondary\"] {\n background-color: var(--button-secondary-bg);\n border-color: var(--button-secondary-border);\n color: var(--button-secondary-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-secondary-bg-hover);\n }\n }\n\n &[data-variant=\"ghost\"] {\n background-color: transparent;\n color: var(--button-ghost-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-ghost-bg-hover);\n }\n }\n }\n\n /* tone=\"danger\", after the variants so it wins at equal specificity plus one attribute. */\n .button[data-tone=\"danger\"] {\n &[data-variant=\"primary\"] {\n background-color: var(--button-danger-bg);\n color: var(--button-danger-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-danger-bg-hover);\n }\n\n &:active:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-danger-bg-active);\n }\n }\n\n &:is([data-variant=\"secondary\"], [data-variant=\"ghost\"]) {\n color: var(--button-danger-text);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-danger-quiet-bg-hover);\n }\n }\n }\n\n .label {\n display: inline-block;\n }\n}\n","import { Children, isValidElement, type ButtonHTMLAttributes, type MouseEvent, type ReactNode, type Ref } from 'react';\nimport { Icon } from '../icon';\nimport { renderAsChild } from '../internal/asChild';\nimport { Spinner } from '../spinner';\nimport { classes } from '../internal/classes';\nimport styles from './Button.module.css';\n\nexport type ButtonTone = 'default' | 'danger';\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\n\nexport interface ButtonProps<E extends HTMLElement = HTMLButtonElement> extends ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Visual emphasis. One `primary` per view; `secondary` for the rest;\n * `ghost` for actions that sit inside other content.\n * @default 'primary'\n */\n variant?: ButtonVariant;\n /**\n * `danger` for an action that destroys something (delete, remove, leave). It\n * recolours whichever `variant` is in use, so emphasis and danger stay two\n * separate decisions: `variant=\"ghost\" tone=\"danger\"` is a quiet delete.\n * @default 'default'\n */\n tone?: ButtonTone;\n /** @default 'md' */\n size?: ButtonSize;\n /**\n * Shows a spinner, sets `aria-busy` and `aria-disabled`, and blocks\n * activation. The element stays focusable so focus is not lost mid-action,\n * and the label stays in place so the button keeps its width.\n * @default false\n */\n loading?: boolean;\n /** Decorative element before the label. Hidden from assistive technology. */\n iconStart?: ReactNode;\n /** Decorative element after the label. Hidden from assistive technology. */\n iconEnd?: ReactNode;\n /**\n * Render the single child element instead of a `<button>`, merging the\n * button's props into it. Use it to style a router `<Link>` or an `<a>` as a\n * button. Disabled and loading states then use `aria-disabled`, and the\n * child's own `onClick` does not run while the control is inert.\n * @default false\n */\n asChild?: boolean;\n /**\n * The rendered element. With `asChild` that is the child's element, so pass\n * the type parameter: `<Button<HTMLAnchorElement> asChild ref={anchorRef}>`.\n */\n ref?: Ref<E>;\n children: ReactNode;\n}\n\nconst BLOCK = (event: MouseEvent) => event.preventDefault();\n\nconst DEV = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';\n\n/** True when some text exists anywhere in the children tree. */\nfunction hasText(node: ReactNode): boolean {\n return Children.toArray(node).some((child) => {\n if (typeof child === 'string') return child.trim().length > 0;\n if (typeof child === 'number') return true;\n if (isValidElement<{ children?: ReactNode }>(child)) return hasText(child.props.children);\n return false;\n });\n}\n\n/**\n * The one action component. Variants map to emphasis, not colour: one\n * `primary` per view, `secondary` for the rest, `ghost` inside other content.\n * Every value comes from `--button-*` tokens, so a brand restyles it without\n * touching the component. State is exposed as `data-variant`, `data-size` and\n * `data-loading` for styling, tests and agents alike.\n *\n * @status stable\n * @category Actions\n * @accessibility A native `button` (or the child element with `asChild`). `loading` sets `aria-disabled` and `aria-busy` and keeps focus; only `disabled` removes it from the tab order. Icon-only use warns in development: use IconButton, which requires a name.\n * @do One `primary` per view.\n * Use `asChild` for links that look like buttons, keeping the `a` semantics.\n * @do Use `tone=\"danger\"` for the action that destroys, and say what it destroys in the label (\"Delete place\"), since colour alone must not carry it.\n * @dont Use `loading` on a button that is not the one that started the work.\n * Rely on colour to tell variants apart; the label carries the meaning.\n */\nexport function Button<E extends HTMLElement = HTMLButtonElement>({\n variant = 'primary',\n tone = 'default',\n size = 'md',\n loading = false,\n iconStart,\n iconEnd,\n asChild = false,\n className,\n disabled = false,\n type,\n onClick,\n ref,\n children,\n ...rest\n}: ButtonProps<E>) {\n // Inert: must not activate. `disabled` on a real <button> also removes it\n // from the tab order, which is right for \"disabled\" and wrong for \"loading\":\n // the element the user just pressed must keep focus. So loading (and every\n // asChild state) uses aria-disabled and blocks activation in the handler.\n const inert = disabled || loading;\n const nativeDisabled = !asChild && disabled;\n\n if (DEV && !hasText(asChild ? (children as { props?: { children?: ReactNode } }).props?.children : children)) {\n if (!rest['aria-label'] && !rest['aria-labelledby']) {\n console.warn('Button: no text content and no aria-label. Icon-only buttons need an accessible name.');\n }\n }\n\n const props = {\n ...rest,\n ref,\n className: classes(styles.button, className),\n 'data-variant': variant,\n 'data-tone': tone === 'danger' ? tone : undefined,\n 'data-size': size,\n 'data-loading': loading ? '' : undefined,\n 'aria-busy': loading || undefined,\n disabled: nativeDisabled || undefined,\n 'aria-disabled': inert && !nativeDisabled ? true : undefined,\n type: asChild ? undefined : (type ?? 'button'),\n onClick: inert ? BLOCK : onClick,\n };\n\n const decorate = (label: ReactNode) => (\n <>\n {loading && <Spinner decorative size=\"inherit\" tone=\"inherit\" />}\n {iconStart && <Icon size=\"inherit\">{iconStart}</Icon>}\n <span className={styles.label}>{label}</span>\n {iconEnd && <Icon size=\"inherit\">{iconEnd}</Icon>}\n </>\n );\n\n if (asChild) {\n const child = children as { props?: { children?: ReactNode } };\n // The helper merges the forwarded ref with the child's; nothing reads it.\n // eslint-disable-next-line react-hooks/refs -- forwarded, not read\n return renderAsChild('Button', children, { ...props, children: decorate(child.props?.children) }, {\n // An inert control must not run the child's handler either.\n replace: inert ? ['onClick'] : [],\n });\n }\n\n return <button {...(props as ButtonHTMLAttributes<HTMLButtonElement>)}>{decorate(children)}</button>;\n}\n\nButton.displayName = 'Button';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/AriaField.module.css"],"names":["field","label","required","description","error"],"mappings":";AAAA,IAAA,iBAAA,GAAA;AAAA,EAKG,KAAA,EAAAA,iBAAAA;AAAA,EAOA,KAAA,EAAAC,iBAAAA;AAAA,EAMA,QAAA,EAAAC,oBAAAA;AAAA,EAKA,WAAA,EAAAC,uBAAAA;AAAA,EAMA,KAAA,EAAAC;AAAA","file":"chunk-DGIXNUNI.js","sourcesContent":["/* The same --field-* tokens Field reads, on React Aria's label, description and error parts. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .field {\n display: flex;\n flex-direction: column;\n gap: var(--field-gap);\n font-family: var(--font-family-body);\n }\n\n .label {\n font-size: var(--field-label-font-size);\n font-weight: var(--field-label-font-weight);\n color: var(--field-label-fg);\n }\n\n .required {\n margin-inline-start: var(--field-required-gap);\n color: var(--field-required-fg);\n }\n\n .description {\n margin: 0;\n font-size: var(--field-description-font-size);\n color: var(--field-description-fg);\n }\n\n .error {\n margin: 0;\n font-size: var(--field-error-font-size);\n color: var(--field-error-fg);\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Icon } from './chunk-
|
|
1
|
+
import { Icon } from './chunk-O5LII5XP.js';
|
|
2
2
|
import { classes } from './chunk-MI4QUKQS.js';
|
|
3
3
|
import { ListBoxItem, Text } from 'react-aria-components';
|
|
4
4
|
import { Check } from '@pearpages/pulp-icons';
|
|
@@ -29,5 +29,5 @@ function renderEmpty(message) {
|
|
|
29
29
|
var listClass = (...extra) => classes(Listbox_default.list, ...extra);
|
|
30
30
|
|
|
31
31
|
export { listClass, renderEmpty, renderOption };
|
|
32
|
-
//# sourceMappingURL=chunk-
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
32
|
+
//# sourceMappingURL=chunk-EDTA65L5.js.map
|
|
33
|
+
//# sourceMappingURL=chunk-EDTA65L5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/listbox/Listbox.module.css","../src/listbox/ListboxOptions.tsx"],"names":["list","check","item","itemBody","itemLabel","itemDescription","empty","AriaListBoxItem","AriaText"],"mappings":";;;;;;;AAAA,IAAA,eAAA,GAAA;AAAA,EAUG,IAAA,EAAAA,cAAAA;AAAA,EAoBA,KAAA,EAAAC,eAAAA;AAAA,EAMA,IAAA,EAAAC,cAAAA;AAAA,EA8BA,QAAA,EAAAC,kBAAAA;AAAA,EAMA,SAAA,EAAAC,mBAAAA;AAAA,EAMA,eAAA,EAAAC,yBAAAA;AAAA,EAKA,KAAA,EAAAC;AAAA,CAAA;AC5DI,SAAS,aAAa,IAAA,EAAmB;AAC9C,EAAA,uBACE,IAAA,CAACC,WAAA,EAAA,EAAgB,EAAA,EAAI,IAAA,CAAK,EAAA,EAAI,SAAA,EAAW,IAAA,CAAK,KAAA,EAAO,UAAA,EAAY,IAAA,CAAK,QAAA,EAAU,SAAA,EAAW,gBAAO,IAAA,EAChG,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,MAAK,SAAA,EAAU,SAAA,EAAW,gBAAO,KAAA,EACrC,QAAA,kBAAA,GAAA,CAAC,SAAM,CAAA,EACT,CAAA;AAAA,oBACA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,eAAA,CAAO,QAAA,EACtB,QAAA,EAAA;AAAA,sBAAA,GAAA,CAACC,QAAS,IAAA,EAAK,OAAA,EAAQ,WAAW,eAAA,CAAO,SAAA,EACtC,eAAK,KAAA,EACR,CAAA;AAAA,MACC,IAAA,CAAK,WAAA,oBACJ,GAAA,CAACA,IAAA,EAAA,EAAS,IAAA,EAAK,eAAc,SAAA,EAAW,eAAA,CAAO,eAAA,EAC5C,QAAA,EAAA,IAAA,CAAK,WAAA,EACR;AAAA,KAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ;AAEO,SAAS,YAAY,OAAA,EAAoB;AAC9C,EAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,eAAA,CAAO,OAAQ,QAAA,EAAA,OAAA,EAAQ,CAAA;AAChD;AAGO,IAAM,YAAY,CAAA,GAAI,KAAA,KAAoD,QAAQ,eAAA,CAAO,IAAA,EAAM,GAAG,KAAK","file":"chunk-EDTA65L5.js","sourcesContent":["/*\n * Every value is a token (--listbox-*). React Aria writes the state:\n * data-focused (real or virtual focus), data-selected, data-disabled,\n * data-hovered, data-focus-visible, data-empty. The tick is in the DOM for\n * every option and revealed by data-selected.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .list {\n display: flex;\n flex-direction: column;\n max-block-size: var(--listbox-max-height);\n padding: var(--listbox-padding);\n overflow: auto;\n border: var(--size-hairline) solid var(--listbox-border);\n border-radius: var(--listbox-radius);\n background-color: var(--listbox-bg);\n color: var(--listbox-fg);\n font-family: var(--listbox-font-family);\n font-size: var(--listbox-font-size);\n outline: none;\n\n &[data-focus-visible] {\n outline: var(--listbox-focus-ring-width) solid var(--listbox-focus-ring);\n outline-offset: var(--listbox-focus-ring-offset);\n }\n }\n\n .check {\n flex: none;\n visibility: hidden;\n color: var(--listbox-item-check);\n }\n\n .item {\n display: flex;\n align-items: center;\n gap: var(--listbox-item-gap);\n padding-block: var(--listbox-item-padding-block);\n padding-inline: var(--listbox-item-padding-inline);\n border-radius: var(--listbox-item-radius);\n color: var(--listbox-item-fg);\n cursor: default;\n outline: none;\n\n &[data-hovered],\n &[data-focused] {\n background-color: var(--listbox-item-bg-focus);\n }\n\n &[data-selected] {\n background-color: var(--listbox-item-bg-selected);\n\n .check {\n visibility: visible;\n }\n }\n\n &[data-disabled] {\n color: var(--listbox-item-fg-disabled);\n cursor: not-allowed;\n }\n }\n\n .itemBody {\n display: flex;\n flex-direction: column;\n min-inline-size: 0;\n }\n\n .itemLabel {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .itemDescription {\n color: var(--listbox-item-fg-muted);\n font-size: var(--listbox-item-description-font-size);\n }\n\n .empty {\n padding: var(--listbox-empty-padding);\n color: var(--listbox-empty-fg);\n }\n}\n","import type { ReactNode } from 'react';\nimport { ListBoxItem as AriaListBoxItem, Text as AriaText } from 'react-aria-components';\nimport { Check } from '@pearpages/pulp-icons';\nimport { Icon } from '../icon';\nimport { classes } from '../internal/classes';\nimport styles from './Listbox.module.css';\n\n/** One option. `id` is the value; `label` is what the user sees and types against. */\nexport interface ListboxItem {\n id: string;\n label: string;\n /** A second, muted line under the label. */\n description?: string;\n /** @default false */\n disabled?: boolean;\n}\n\n/**\n * The option renderer shared by Listbox, Combobox and Picker, so the three\n * agree on what an option looks like and read the same `--listbox-item-*`\n * tokens. React Aria adds the state (`data-selected`, `data-focused`,\n * `data-disabled`); the tick is always in the DOM and shown by CSS.\n */\nexport function renderOption(item: ListboxItem) {\n return (\n <AriaListBoxItem id={item.id} textValue={item.label} isDisabled={item.disabled} className={styles.item}>\n <Icon size=\"inherit\" className={styles.check}>\n <Check />\n </Icon>\n <span className={styles.itemBody}>\n <AriaText slot=\"label\" className={styles.itemLabel}>\n {item.label}\n </AriaText>\n {item.description && (\n <AriaText slot=\"description\" className={styles.itemDescription}>\n {item.description}\n </AriaText>\n )}\n </span>\n </AriaListBoxItem>\n );\n}\n\nexport function renderEmpty(message: ReactNode) {\n return <div className={styles.empty}>{message}</div>;\n}\n\n/** The list class, for Combobox and Picker to put the list inside their popovers. */\nexport const listClass = (...extra: Array<string | false | null | undefined>) => classes(styles.list, ...extra);\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { Icon } from './chunk-
|
|
1
|
+
import { isPresent, AriaFieldLabel, AriaFieldDescription, AriaFieldError, ariaFieldClass } from './chunk-IRNTXAA7.js';
|
|
2
|
+
import { renderOption, renderEmpty, listClass } from './chunk-EDTA65L5.js';
|
|
3
|
+
import { Icon } from './chunk-O5LII5XP.js';
|
|
4
4
|
import { Select, Button, SelectValue, Popover, ListBox } from 'react-aria-components';
|
|
5
5
|
import { ChevronDown } from '@pearpages/pulp-icons';
|
|
6
6
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -63,5 +63,5 @@ function Picker({
|
|
|
63
63
|
Picker.displayName = "Picker";
|
|
64
64
|
|
|
65
65
|
export { Picker };
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
67
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-F2YI5N4L.js.map
|
|
67
|
+
//# sourceMappingURL=chunk-F2YI5N4L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/picker/Picker.module.css","../src/picker/Picker.tsx"],"names":["root","trigger","value","chevron","popover","list","AriaSelect","AriaButton","AriaSelectValue","AriaPopover","AriaListBox"],"mappings":";;;;;;;;AAAA,IAAA,cAAA,GAAA;AAAA,EASG,IAAA,EAAAA,aAAAA;AAAA,EAoBA,OAAA,EAAAC,gBAAAA;AAAA,EAkCA,KAAA,EAAAC,cAAAA;AAAA,EAWA,OAAA,EAAAC,gBAAAA;AAAA,EAKA,OAAA,EAAAC,gBAAAA;AAAA,EAUA,IAAA,EAAAC;AAAA,CAAA;AChCI,SAAS,MAAA,CAAO;AAAA,EACrB,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,cAAA;AAAA,EACd,YAAA,GAAe,YAAA;AAAA,EACf,IAAA,GAAO,IAAA;AAAA,EACP,QAAA,GAAW,KAAA;AAAA,EACX,QAAA,GAAW,KAAA;AAAA,EACX,IAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAgB;AACd,EAAA,MAAM,OAAA,GAAU,UAAU,KAAK,CAAA;AAC/B,EAAA,uBACE,IAAA;AAAA,IAACC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,cAAA,CAAe,cAAA,CAAO,IAAA,EAAM,SAAS,CAAA;AAAA,MAChD,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAa,KAAA;AAAA,MACb,kBAAA,EAAoB,YAAA;AAAA,MACpB,iBAAA,EAAmB,CAAC,GAAA,KAAQ,QAAA,GAAW,QAAQ,IAAA,GAAO,IAAA,GAAO,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,MACxE,WAAA;AAAA,MACA,UAAA,EAAY,QAAA;AAAA,MACZ,UAAA,EAAY,QAAA;AAAA,MACZ,SAAA,EAAW,OAAA;AAAA,MACX,IAAA;AAAA,MACA,SAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,UAAqB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,wBAC3C,IAAA,CAACC,MAAA,EAAA,EAAW,GAAA,EAAU,SAAA,EAAW,eAAO,OAAA,EACtC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAACC,WAAA,EAAA,EAAgB,SAAA,EAAW,cAAA,CAAO,KAAA,EAAO,CAAA;AAAA,0BAC1C,GAAA,CAAC,QAAK,IAAA,EAAK,SAAA,EAAU,WAAW,cAAA,CAAO,OAAA,EACrC,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,CAAA,EACf;AAAA,SAAA,EACF,CAAA;AAAA,wBACA,GAAA,CAAC,wBAAsB,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,wBACnC,GAAA,CAAC,kBAAgB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,wBACvB,GAAA,CAACC,WAAY,SAAA,EAAW,cAAA,CAAO,SAAS,SAAA,EAAU,cAAA,EAChD,8BAACC,OAAA,EAAA,EAAY,SAAA,EAAW,UAAU,cAAA,CAAO,IAAI,GAAG,KAAA,EAAc,gBAAA,EAAkB,MAAM,WAAA,CAAY,YAAY,CAAA,EAC3G,QAAA,EAAA,YAAA,EACH,CAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-F2YI5N4L.js","sourcesContent":["/*\n * Every value is a token (--picker-*); the options read --listbox-*. The\n * trigger is a button drawn like a text field. The popover is positioned by\n * React Aria; the gap is its own padding and --trigger-width (vendor) sizes it.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .root {\n --_height: var(--picker-height-md);\n --_font-size: var(--picker-font-size-md);\n --_border: var(--picker-border-default);\n\n font-family: var(--picker-font-family);\n\n &[data-size=\"sm\"] {\n --_height: var(--picker-height-sm);\n --_font-size: var(--picker-font-size-sm);\n }\n\n &[data-size=\"lg\"] {\n --_height: var(--picker-height-lg);\n --_font-size: var(--picker-font-size-lg);\n }\n\n &[data-invalid] { --_border: var(--picker-border-invalid); }\n }\n\n .trigger {\n display: flex;\n align-items: center;\n gap: var(--picker-gap);\n inline-size: 100%;\n min-block-size: var(--_height);\n padding-block: 0;\n padding-inline: var(--picker-padding-inline);\n border: var(--size-hairline) solid var(--_border);\n border-radius: var(--picker-radius);\n background-color: var(--picker-bg);\n color: var(--picker-fg);\n font-family: inherit;\n font-size: var(--_font-size);\n text-align: start;\n cursor: pointer;\n transition: border-color var(--picker-motion-duration) var(--motion-easing-standard);\n\n &[data-focus-visible] {\n border-color: var(--picker-border-focus);\n outline: var(--picker-focus-ring-width) solid var(--picker-focus-ring);\n outline-offset: var(--picker-focus-ring-offset);\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &[data-hovered]:not([data-focus-visible], [data-disabled]) {\n border-color: var(--picker-border-hover);\n }\n }\n\n .value {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n &[data-placeholder] {\n color: var(--picker-placeholder);\n }\n }\n\n .chevron {\n flex: none;\n color: var(--picker-icon);\n }\n\n .popover {\n inline-size: var(--trigger-width);\n padding-block-start: var(--picker-gap);\n animation: fade var(--picker-popover-duration) var(--motion-easing-standard);\n\n &[data-placement=\"top\"] {\n padding-block: 0 var(--picker-gap);\n }\n }\n\n .list {\n box-shadow: var(--picker-popover-shadow);\n }\n\n /* The shared list styles paint an inline Listbox's surface; here the list floats. Two classes, so it wins whatever the stylesheet order. */\n .popover .list {\n background-color: var(--picker-popover-bg);\n }\n\n @keyframes fade {\n from {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .popover {\n animation: none;\n }\n }\n}\n","import type { ReactNode, Ref } from 'react';\nimport { Button as AriaButton, ListBox as AriaListBox, Popover as AriaPopover, Select as AriaSelect, SelectValue as AriaSelectValue } from 'react-aria-components';\nimport { ChevronDown } from '@pearpages/pulp-icons';\nimport { Icon } from '../icon';\nimport { AriaFieldDescription, AriaFieldError, AriaFieldLabel, ariaFieldClass, isPresent } from '../internal/AriaField';\nimport { listClass, renderEmpty, renderOption, type ListboxItem } from '../listbox/ListboxOptions';\nimport styles from './Picker.module.css';\n\nexport type PickerItem = ListboxItem;\nexport type PickerSize = 'sm' | 'md' | 'lg';\n\nexport interface PickerProps {\n /** Visible label. Always rendered. */\n label: ReactNode;\n description?: ReactNode;\n /** Presence marks the control invalid and announces the message. */\n error?: ReactNode;\n /** The options. Ids are the values. */\n items: readonly PickerItem[];\n /** Selected id (controlled). `null` is \"nothing selected\". */\n value?: string | null;\n defaultValue?: string | null;\n onChange?: (value: string | null) => void;\n /** Shown in the control until a value is chosen. @default 'Select…' */\n placeholder?: string;\n /** Shown when `items` is empty. @default 'No options' */\n emptyMessage?: ReactNode;\n /** @default 'md' */\n size?: PickerSize;\n /** @default false */\n required?: boolean;\n /** @default false */\n disabled?: boolean;\n /** Submitted with a form through a hidden native select. */\n name?: string;\n autoFocus?: boolean;\n /** Applied to the field wrapper, not the button. */\n className?: string;\n /** The trigger `<button>`. */\n ref?: Ref<HTMLButtonElement>;\n}\n\n/**\n * A single-choice select with rich options (a description line, consistent\n * styling in every browser), on React Aria's select (decision record 001):\n * a button opens a listbox, arrows and typing move, Enter chooses, Escape\n * closes, and a hidden native select carries the value in forms. For a\n * plain list of words, the native `Select` is the default; for several\n * choices at once, use Listbox.\n *\n * @status experimental\n * @category Forms\n * @accessibility A `button` named by the label with `aria-haspopup=\"listbox\"` and `aria-expanded`; the popup is a `listbox` with selected and disabled options; a hidden native select carries `name` and value for forms. Arrows open and move, typing jumps, Enter chooses, Escape closes and returns focus.\n * @do Use a `description` line on options when the label alone is ambiguous.\n * Prefer the native Select for a plain list of words.\n * @dont Use `placeholder` as the only label.\n */\nexport function Picker({\n label,\n description,\n error,\n items,\n value,\n defaultValue,\n onChange,\n placeholder = 'Select…',\n emptyMessage = 'No options',\n size = 'md',\n required = false,\n disabled = false,\n name,\n autoFocus,\n className,\n ref,\n}: PickerProps) {\n const invalid = isPresent(error);\n return (\n <AriaSelect\n className={ariaFieldClass(styles.root, className)}\n data-size={size}\n selectedKey={value}\n defaultSelectedKey={defaultValue}\n onSelectionChange={(key) => onChange?.(key === null ? null : String(key))}\n placeholder={placeholder}\n isRequired={required}\n isDisabled={disabled}\n isInvalid={invalid}\n name={name}\n autoFocus={autoFocus}\n >\n <AriaFieldLabel required={required}>{label}</AriaFieldLabel>\n <AriaButton ref={ref} className={styles.trigger}>\n <AriaSelectValue className={styles.value} />\n <Icon size=\"inherit\" className={styles.chevron}>\n <ChevronDown />\n </Icon>\n </AriaButton>\n <AriaFieldDescription>{description}</AriaFieldDescription>\n <AriaFieldError>{error}</AriaFieldError>\n <AriaPopover className={styles.popover} placement=\"bottom start\">\n <AriaListBox className={listClass(styles.list)} items={items} renderEmptyState={() => renderEmpty(emptyMessage)}>\n {renderOption}\n </AriaListBox>\n </AriaPopover>\n </AriaSelect>\n );\n}\n\nPicker.displayName = 'Picker';\n"]}
|
|
@@ -24,5 +24,5 @@ function Heading({ level, size, tone = "default", className, ref, children, ...r
|
|
|
24
24
|
Heading.displayName = "Heading";
|
|
25
25
|
|
|
26
26
|
export { Heading };
|
|
27
|
-
//# sourceMappingURL=chunk-
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
27
|
+
//# sourceMappingURL=chunk-F3S5BHX2.js.map
|
|
28
|
+
//# sourceMappingURL=chunk-F3S5BHX2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/heading/Heading.module.css","../src/heading/Heading.tsx"],"names":["heading"],"mappings":";;;;AAAA,IAAA,eAAA,GAAA;AAAA,EAKG,OAAA,EAAAA;AAAA,CAAA;;;ACcH,IAAM,aAAA,GAAmD,EAAE,CAAA,EAAG,KAAA,EAAO,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,GAAG,IAAA,EAAK;AAa1G,SAAS,OAAA,CAAQ,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,GAAO,SAAA,EAAW,SAAA,EAAW,GAAA,EAAK,QAAA,EAAU,GAAG,IAAA,EAAK,EAAiB;AAC1G,EAAA,OAAO,aAAA;AAAA,IACL,IAAI,KAAK,CAAA,CAAA;AAAA,IACT;AAAA,MACE,GAAG,IAAA;AAAA,MACH,GAAA;AAAA,MACA,SAAA,EAAW,OAAA,CAAQ,eAAA,CAAO,OAAA,EAAS,SAAS,CAAA;AAAA,MAC5C,WAAA,EAAa,IAAA,IAAQ,aAAA,CAAc,KAAK,CAAA;AAAA,MACxC,WAAA,EAAa;AAAA,KACf;AAAA,IACA;AAAA,GACF;AACF;AAEA,OAAA,CAAQ,WAAA,GAAc,SAAA","file":"chunk-F3S5BHX2.js","sourcesContent":["/* Every value is a token (--heading-*). Size is a data attribute, independent of the level. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .heading {\n margin: 0;\n font-family: var(--heading-font-family);\n font-weight: var(--heading-font-weight);\n line-height: var(--heading-line-height);\n color: var(--heading-tone-default);\n text-wrap: balance;\n\n &[data-size=\"sm\"] { font-size: var(--heading-size-sm); }\n &[data-size=\"md\"] { font-size: var(--heading-size-md); }\n &[data-size=\"lg\"] { font-size: var(--heading-size-lg); }\n &[data-size=\"xl\"] { font-size: var(--heading-size-xl); }\n &[data-size=\"2xl\"] { font-size: var(--heading-size-2xl); }\n &[data-tone=\"muted\"] { color: var(--heading-tone-muted); }\n }\n}\n","import { createElement, type HTMLAttributes, type ReactNode, type Ref } from 'react';\nimport { classes } from '../internal/classes';\nimport styles from './Heading.module.css';\n\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\nexport type HeadingSize = 'sm' | 'md' | 'lg' | 'xl' | '2xl';\nexport type HeadingTone = 'default' | 'muted';\n\nexport interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {\n /** The document outline level; sets the element (`h1`–`h6`). */\n level: HeadingLevel;\n /** Visual size, decoupled from the level. Defaults by level: 1→2xl, 2→xl, 3→lg, 4→md, 5 and 6→sm. */\n size?: HeadingSize;\n /** @default 'default' */\n tone?: HeadingTone;\n ref?: Ref<HTMLHeadingElement>;\n children: ReactNode;\n}\n\nconst SIZE_BY_LEVEL: Record<HeadingLevel, HeadingSize> = { 1: '2xl', 2: 'xl', 3: 'lg', 4: 'md', 5: 'sm', 6: 'sm' };\n\n/**\n * A heading whose outline level and visual size are separate decisions, so\n * the document structure stays honest while the design stays flexible.\n * Display family and tight leading from `--heading-*` tokens.\n *\n * @status stable\n * @category Typography\n * @accessibility Renders the `h1`–`h6` element of `level`; `size` changes only the look, so the outline stays truthful.\n * @do Pick `level` from the outline, then `size` from the design.\n * @dont Skip heading levels to get a smaller size; change `size` instead.\n */\nexport function Heading({ level, size, tone = 'default', className, ref, children, ...rest }: HeadingProps) {\n return createElement(\n `h${level}`,\n {\n ...rest,\n ref,\n className: classes(styles.heading, className),\n 'data-size': size ?? SIZE_BY_LEVEL[level],\n 'data-tone': tone,\n },\n children,\n );\n}\n\nHeading.displayName = 'Heading';\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Alert } from './chunk-
|
|
2
|
-
import { Button } from './chunk-
|
|
1
|
+
import { Alert } from './chunk-A7TMFEQ2.js';
|
|
2
|
+
import { Button } from './chunk-DE67ECD7.js';
|
|
3
3
|
import { classes } from './chunk-MI4QUKQS.js';
|
|
4
4
|
import { createContext, useContext, useState, useRef, useEffect, useCallback, useMemo } from 'react';
|
|
5
5
|
import { createPortal } from 'react-dom';
|
|
@@ -19,6 +19,7 @@ var Toast_default = {
|
|
|
19
19
|
item: "Toast_item",
|
|
20
20
|
toast: "Toast_toast"
|
|
21
21
|
};
|
|
22
|
+
var UNDO_DURATION = 8e3;
|
|
22
23
|
function ToastProvider({ placement = "bottom-end", max = 5, duration = 6e3, label = "Notifications", children }) {
|
|
23
24
|
const [items, setItems] = useState([]);
|
|
24
25
|
const [paused, setPaused] = useState(false);
|
|
@@ -98,7 +99,11 @@ function ToastProvider({ placement = "bottom-end", max = 5, duration = 6e3, labe
|
|
|
98
99
|
for (const timer of map.values()) if (timer.handle !== void 0) clearTimeout(timer.handle);
|
|
99
100
|
};
|
|
100
101
|
}, []);
|
|
101
|
-
const value = useMemo(() =>
|
|
102
|
+
const value = useMemo(() => {
|
|
103
|
+
const undo = (message, onUndo, { label: label2 = "Undo", duration: ttl = UNDO_DURATION, ...options } = {}) => toast({ ...options, title: message, duration: ttl, action: { label: label2, onClick: onUndo } });
|
|
104
|
+
const api = Object.assign((options) => toast(options), { undo });
|
|
105
|
+
return { toast: api, dismiss, dismissAll };
|
|
106
|
+
}, [toast, dismiss, dismissAll]);
|
|
102
107
|
const onKeyDown = (event) => {
|
|
103
108
|
if (event.key !== "Escape") return;
|
|
104
109
|
const item = event.target.closest("[data-toast-id]");
|
|
@@ -155,5 +160,5 @@ function ToastProvider({ placement = "bottom-end", max = 5, duration = 6e3, labe
|
|
|
155
160
|
ToastProvider.displayName = "ToastProvider";
|
|
156
161
|
|
|
157
162
|
export { ToastProvider, useToast };
|
|
158
|
-
//# sourceMappingURL=chunk-
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
163
|
+
//# sourceMappingURL=chunk-FFCEY76B.js.map
|
|
164
|
+
//# sourceMappingURL=chunk-FFCEY76B.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/toast/context.ts","../src/toast/Toast.module.css","../src/toast/Toast.tsx"],"names":["region","list","item","toast","label"],"mappings":"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","file":"chunk-FFCEY76B.js","sourcesContent":["import { createContext, useContext, type ReactNode } from 'react';\nimport type { AlertTone } from '../alert';\n\nexport interface ToastOptions {\n title: ReactNode;\n description?: ReactNode;\n /** @default 'info' */\n tone?: AlertTone;\n /** Milliseconds before auto-dismiss; `Infinity` keeps it until dismissed. Errors default to `Infinity`. */\n duration?: number;\n /** One button inside the toast. Pressing it runs `onClick` and dismisses the toast. It never takes focus. */\n action?: { label: string; onClick: () => void };\n}\n\nexport interface ToastUndoOptions extends Pick<ToastOptions, 'description' | 'tone'> {\n /** The button's label, for other languages. @default 'Undo' */\n label?: string;\n /** Longer than an ordinary toast by default (8 s): there is something to read, decide and reach. */\n duration?: number;\n}\n\nexport interface ToastFunction {\n /** Shows a toast and returns its id. */\n (options: ToastOptions): string;\n /**\n * The named case for a reversible action: \"Place removed\" with an Undo\n * button. Pressing it runs `onUndo` and dismisses; letting it time out\n * does nothing, so do the work first and undo it on request.\n */\n undo: (message: ReactNode, onUndo: () => void, options?: ToastUndoOptions) => string;\n}\n\nexport interface ToastItem extends ToastOptions {\n id: string;\n}\n\nexport interface ToastContextValue {\n /** Shows a toast and returns its id. `toast.undo(message, onUndo)` is the reversible-action shorthand. */\n toast: ToastFunction;\n dismiss: (id: string) => void;\n dismissAll: () => void;\n}\n\nexport const ToastContext = createContext<ToastContextValue | null>(null);\n\n/** The toast API. Must be used inside `ToastProvider`. */\nexport function useToast(): ToastContextValue {\n const context = useContext(ToastContext);\n if (!context) throw new Error('useToast must be used inside <ToastProvider>');\n return context;\n}\n","/* Every value is a token (--toast-*). The region is fixed; placement is a data attribute. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .region {\n --_top: auto;\n --_end: var(--toast-offset);\n --_bottom: var(--toast-offset);\n --_start: auto;\n\n position: fixed;\n z-index: var(--toast-layer);\n inset: var(--_top) var(--_end) var(--_bottom) var(--_start);\n inline-size: min(var(--toast-width), 100vw);\n padding: 0;\n pointer-events: none;\n\n &[data-placement=\"top-end\"] {\n --_top: var(--toast-offset);\n --_bottom: auto;\n }\n\n &[data-placement=\"top-center\"] {\n --_top: var(--toast-offset);\n --_bottom: auto;\n --_start: 0;\n --_end: 0;\n\n margin-inline: auto;\n }\n }\n\n .list {\n display: flex;\n flex-direction: column;\n gap: var(--toast-gap);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .item {\n pointer-events: auto;\n animation: enter var(--toast-motion-duration) var(--motion-easing-standard);\n }\n\n .toast {\n border-radius: var(--toast-radius);\n box-shadow: var(--toast-shadow);\n }\n\n @keyframes enter {\n from {\n opacity: 0;\n translate: 0 var(--space-2);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .item {\n animation: none;\n }\n }\n}\n","import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Alert } from '../alert';\nimport { Button } from '../button';\nimport { classes } from '../internal/classes';\nimport { ToastContext, type ToastFunction, type ToastItem, type ToastOptions, type ToastUndoOptions } from './context';\n\n/** An undo toast asks for a decision and a reach, so it outlasts the default. */\nconst UNDO_DURATION = 8000;\nimport styles from './Toast.module.css';\n\nexport type ToastPlacement = 'bottom-end' | 'top-end' | 'top-center';\n\nexport interface ToastProviderProps {\n /** @default 'bottom-end' */\n placement?: ToastPlacement;\n /** Most toasts shown at once; the oldest is dismissed first. @default 5 */\n max?: number;\n /** Default auto-dismiss time in milliseconds. @default 6000 */\n duration?: number;\n /** Accessible name of the region. @default 'Notifications' */\n label?: string;\n children: ReactNode;\n}\n\ninterface Timer {\n remaining: number;\n startedAt: number;\n handle: ReturnType<typeof setTimeout> | undefined;\n}\n\n/**\n * Mount once near the app root. Owns a portal element with a polite live\n * region; `useToast()` adds notifications to it. Timers pause while the\n * region is hovered or holds focus, Escape dismisses the focused toast, and\n * error toasts stay until dismissed. Each toast is an Alert.\n * `toast.undo(message, onUndo)` is the shorthand for a reversible action.\n *\n * @status stable\n * @category Feedback\n * @accessibility Owns a `region` named \"Notifications\" with `aria-live=\"polite\"`; each toast is an Alert with its live role off (the region announces). Timers pause while the region is hovered or holds focus; Escape dismisses the focused toast; error toasts stay until dismissed.\n * @do Mount it once near the app root.\n * Keep messages to one sentence; put detail behind an `action`.\n * @dont Use a toast for an error the user must fix in a form; show it at the field.\n * Stack more than a few; the cap drops the oldest.\n */\nexport function ToastProvider({ placement = 'bottom-end', max = 5, duration = 6000, label = 'Notifications', children }: ToastProviderProps) {\n const [items, setItems] = useState<ToastItem[]>([]);\n const [paused, setPaused] = useState(false);\n const timers = useRef(new Map<string, Timer>());\n const counter = useRef(0);\n\n const [container] = useState<HTMLDivElement | undefined>(() => {\n if (typeof document === 'undefined') return undefined;\n const element = document.createElement('div');\n element.dataset.pulpToasts = '';\n return element;\n });\n\n useEffect(() => {\n if (!container) return;\n document.body.append(container);\n return () => container.remove();\n }, [container]);\n\n const dismiss = useCallback((id: string) => {\n const timer = timers.current.get(id);\n if (timer?.handle !== undefined) clearTimeout(timer.handle);\n timers.current.delete(id);\n setItems((current) => current.filter((item) => item.id !== id));\n }, []);\n\n const dismissAll = useCallback(() => {\n for (const timer of timers.current.values()) if (timer.handle !== undefined) clearTimeout(timer.handle);\n timers.current.clear();\n setItems([]);\n }, []);\n\n const start = useCallback(\n (id: string, remaining: number) => {\n if (!Number.isFinite(remaining)) return;\n timers.current.set(id, { remaining, startedAt: Date.now(), handle: setTimeout(() => dismiss(id), remaining) });\n },\n [dismiss],\n );\n\n const toast = useCallback(\n (options: ToastOptions) => {\n counter.current += 1;\n const id = `toast-${counter.current}`;\n const ttl = options.duration ?? (options.tone === 'error' ? Infinity : duration);\n setItems((current) => {\n const next = [...current, { ...options, id }];\n const overflow = next.length - max;\n if (overflow > 0) {\n for (const old of next.slice(0, overflow)) {\n const timer = timers.current.get(old.id);\n if (timer?.handle !== undefined) clearTimeout(timer.handle);\n timers.current.delete(old.id);\n }\n return next.slice(overflow);\n }\n return next;\n });\n if (!paused) start(id, ttl);\n else timers.current.set(id, { remaining: ttl, startedAt: Date.now(), handle: undefined });\n return id;\n },\n [duration, max, paused, start],\n );\n\n // Pause: freeze every timer with its remaining time. Resume: restart them.\n useEffect(() => {\n const map = timers.current;\n if (paused) {\n for (const [id, timer] of map) {\n if (timer.handle === undefined) continue;\n clearTimeout(timer.handle);\n map.set(id, { ...timer, remaining: Math.max(0, timer.remaining - (Date.now() - timer.startedAt)), handle: undefined });\n }\n } else {\n for (const [id, timer] of map) {\n if (timer.handle !== undefined || !Number.isFinite(timer.remaining)) continue;\n map.set(id, { ...timer, startedAt: Date.now(), handle: setTimeout(() => dismiss(id), timer.remaining) });\n }\n }\n }, [paused, dismiss]);\n\n useEffect(() => {\n const map = timers.current;\n return () => {\n for (const timer of map.values()) if (timer.handle !== undefined) clearTimeout(timer.handle);\n };\n }, []);\n\n const value = useMemo(() => {\n const undo = (message: ReactNode, onUndo: () => void, { label = 'Undo', duration: ttl = UNDO_DURATION, ...options }: ToastUndoOptions = {}) =>\n toast({ ...options, title: message, duration: ttl, action: { label, onClick: onUndo } });\n // `toast(options)` and `toast.undo(…)`: a function with a property. The rule sees callbacks that\n // touch refs being handed to a function; Object.assign only copies them, nothing runs during render.\n // eslint-disable-next-line react-hooks/refs -- composed, not called\n const api: ToastFunction = Object.assign((options: ToastOptions) => toast(options), { undo });\n return { toast: api, dismiss, dismissAll };\n }, [toast, dismiss, dismissAll]);\n\n const onKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key !== 'Escape') return;\n const item = (event.target as HTMLElement).closest<HTMLElement>('[data-toast-id]');\n if (item?.dataset.toastId) {\n event.preventDefault();\n dismiss(item.dataset.toastId);\n }\n };\n\n const region = (\n <section\n role=\"region\"\n aria-label={label}\n aria-live=\"polite\"\n className={classes(styles.region)}\n data-placement={placement}\n onMouseEnter={() => setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n onFocus={() => setPaused(true)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) setPaused(false);\n }}\n onKeyDown={onKeyDown}\n >\n <ol className={styles.list}>\n {items.map((item) => (\n <li key={item.id} className={styles.item} data-toast-id={item.id} data-tone={item.tone ?? 'info'}>\n <Alert\n tone={item.tone}\n title={item.title}\n live=\"off\"\n className={styles.toast}\n onDismiss={() => dismiss(item.id)}\n action={\n item.action && (\n <Button\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => {\n item.action?.onClick();\n dismiss(item.id);\n }}\n >\n {item.action.label}\n </Button>\n )\n }\n >\n {item.description}\n </Alert>\n </li>\n ))}\n </ol>\n </section>\n );\n\n return (\n <ToastContext.Provider value={value}>\n {children}\n {container ? createPortal(region, container) : null}\n </ToastContext.Provider>\n );\n}\n\nToastProvider.displayName = 'ToastProvider';\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useFloatingPosition } from './chunk-U6QRAD73.js';
|
|
2
|
-
import { renderAsChild } from './chunk-
|
|
2
|
+
import { renderAsChild } from './chunk-QJG5ILK5.js';
|
|
3
3
|
import { useId, useState, useRef, useCallback, useEffect } from 'react';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
5
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
@@ -53,5 +53,5 @@ function Tooltip({ content, placement = "top", delay = 300, children }) {
|
|
|
53
53
|
Tooltip.displayName = "Tooltip";
|
|
54
54
|
|
|
55
55
|
export { Tooltip };
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
56
|
+
//# sourceMappingURL=chunk-GWTHITZO.js.map
|
|
57
|
+
//# sourceMappingURL=chunk-GWTHITZO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tooltip/Tooltip.module.css","../src/tooltip/Tooltip.tsx"],"names":["tooltip"],"mappings":";;;;;;;AAAA,IAAA,eAAA,GAAA;AAAA,EAKG,OAAA,EAAAA,iBAkBY,CAAA;ACQR,SAAS,OAAA,CAAQ,EAAE,OAAA,EAAS,SAAA,GAAY,OAAO,KAAA,GAAQ,GAAA,EAAK,UAAS,EAAiB;AAC3F,EAAA,MAAM,KAAK,KAAA,EAAM;AACjB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AACtC,EAAA,MAAM,KAAA,GAAQ,OAAsC,MAAS,CAAA;AAC7D,EAAA,MAAM,EAAE,IAAA,EAAM,aAAA,EAAe,SAAA,EAAW,QAAA,KAAa,mBAAA,CAAoB,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA;AAE5F,EAAA,MAAM,IAAA,GAAO,WAAA;AAAA,IACX,CAAC,IAAA,KAAiB;AAChB,MAAA,YAAA,CAAa,MAAM,OAAO,CAAA;AAC1B,MAAA,IAAI,IAAA,KAAS,CAAA,EAAG,OAAA,CAAQ,IAAI,CAAA;AAAA,iBACjB,OAAA,GAAU,UAAA,CAAW,MAAM,OAAA,CAAQ,IAAI,GAAG,IAAI,CAAA;AAAA,IAC3D,CAAA;AAAA,IACA;AAAC,GACH;AACA,EAAA,MAAM,IAAA,GAAO,YAAY,MAAM;AAC7B,IAAA,YAAA,CAAa,MAAM,OAAO,CAAA;AAC1B,IAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,EACf,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM,MAAM,YAAA,CAAa,MAAM,OAAO,CAAA,EAAG,EAAE,CAAA;AACrD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KAAyB;AAC1C,MAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,QAAA,EAAU,IAAA,EAAK;AAAA,IACnC,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC9C,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,SAAA,EAAW,SAAS,CAAA;AAAA,EAChE,CAAA,EAAG,CAAC,IAAA,EAAM,IAAI,CAAC,CAAA;AAIf,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,SAAA,EAAW,QAAA,EAAU;AAAA,IACjD,KAAK,IAAA,CAAK,YAAA;AAAA,IACV,YAAA,EAAc,MAAM,IAAA,CAAK,KAAK,CAAA;AAAA,IAC9B,YAAA,EAAc,IAAA;AAAA,IACd,OAAA,EAAS,MAAM,IAAA,CAAK,CAAC,CAAA;AAAA,IACrB,MAAA,EAAQ,IAAA;AAAA,IACR,kBAAA,EAAoB,OAAO,EAAA,GAAK;AAAA,GACjC,CAAA;AAED,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,OAAA;AAAA,IACA,IAAA,IACC,YAAA;AAAA;AAAA,sBAEE,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,IAAA,CAAK,aAAa,EAAA,EAAQ,IAAA,EAAK,SAAA,EAAU,SAAA,EAAW,gBAAO,OAAA,EAAS,gBAAA,EAAgB,QAAA,EAAU,KAAA,EAAO,eAC5G,QAAA,EAAA,OAAA,EACH,CAAA;AAAA,MACA,QAAA,CAAS;AAAA;AACX,GAAA,EACJ,CAAA;AAEJ;AAEA,OAAA,CAAQ,WAAA,GAAc,SAAA","file":"chunk-GWTHITZO.js","sourcesContent":["/* Every value is a token (--tooltip-*). Position comes in as --_x/--_y from the floating hook. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .tooltip {\n --_gap: var(--tooltip-gap);\n\n position: fixed;\n z-index: var(--tooltip-layer);\n inset-block-start: var(--_y);\n inset-inline-start: var(--_x);\n max-inline-size: var(--tooltip-max-width);\n padding-block: var(--tooltip-padding-block);\n padding-inline: var(--tooltip-padding-inline);\n border-radius: var(--tooltip-radius);\n background-color: var(--tooltip-bg);\n color: var(--tooltip-fg);\n font-family: var(--font-family-body);\n font-size: var(--tooltip-font-size);\n line-height: var(--font-line-height-normal);\n box-shadow: var(--tooltip-shadow);\n pointer-events: none;\n animation: fade var(--tooltip-duration) var(--motion-easing-standard);\n }\n\n @keyframes fade {\n from {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .tooltip {\n animation: none;\n }\n }\n}\n","import { useCallback, useEffect, useId, useRef, useState, type ReactElement, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { renderAsChild } from '../internal/asChild';\nimport { useFloatingPosition, type FloatingPlacement } from '../internal/floating';\nimport styles from './Tooltip.module.css';\n\nexport type TooltipPlacement = FloatingPlacement;\n\nexport interface TooltipProps {\n /** The tooltip text. Supplementary only: it must not be the control's only name. */\n content: ReactNode;\n /** Preferred side; flips when there is no room. @default 'top' */\n placement?: TooltipPlacement;\n /** Hover delay in milliseconds. Focus shows immediately. @default 300 */\n delay?: number;\n /** The single element that owns the tooltip; it receives the hover, focus and `aria-describedby` wiring. */\n children: ReactElement;\n}\n\n/**\n * A short description shown on hover or focus and linked with\n * `aria-describedby` while visible. Never the only name of a control: use it\n * for extra detail, and give icon-only controls a real label. Escape hides it.\n *\n * @status stable\n * @category Overlays\n * @accessibility Shown on hover after a delay and on focus immediately; the trigger gets `aria-describedby` pointing at the `tooltip` while it is visible; Escape hides it. It is a description, never a name.\n * @do Use it for extra detail on controls that already have a name.\n * @dont Put interactive content in it.\n * Use it to name an icon-only control; use IconButton's `label`.\n */\nexport function Tooltip({ content, placement = 'top', delay = 300, children }: TooltipProps) {\n const id = useId();\n const [open, setOpen] = useState(false);\n const timer = useRef<ReturnType<typeof setTimeout>>(undefined);\n const { refs, positionStyle, placement: resolved } = useFloatingPosition({ open, placement });\n\n const show = useCallback(\n (wait: number) => {\n clearTimeout(timer.current);\n if (wait === 0) setOpen(true);\n else timer.current = setTimeout(() => setOpen(true), wait);\n },\n [],\n );\n const hide = useCallback(() => {\n clearTimeout(timer.current);\n setOpen(false);\n }, []);\n\n useEffect(() => () => clearTimeout(timer.current), []);\n useEffect(() => {\n if (!open) return;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') hide();\n };\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n }, [open, hide]);\n\n // The helper merges these handlers with the child's own and forwards the ref.\n // eslint-disable-next-line react-hooks/refs -- forwarded to the reference element, not read\n const trigger = renderAsChild('Tooltip', children, {\n ref: refs.setReference,\n onMouseEnter: () => show(delay),\n onMouseLeave: hide,\n onFocus: () => show(0),\n onBlur: hide,\n 'aria-describedby': open ? id : undefined,\n });\n\n return (\n <>\n {trigger}\n {open &&\n createPortal(\n // eslint-disable-next-line react/forbid-dom-props -- per-instance position (--_x/--_y), see internal/floating.ts\n <div ref={refs.setFloating} id={id} role=\"tooltip\" className={styles.tooltip} data-placement={resolved} style={positionStyle}>\n {content}\n </div>,\n document.body,\n )}\n </>\n );\n}\n\nTooltip.displayName = 'Tooltip';\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { renderAsChild } from './chunk-QJG5ILK5.js';
|
|
2
|
+
import { classes } from './chunk-MI4QUKQS.js';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/link/Link.module.css
|
|
6
|
+
var Link_default = {
|
|
7
|
+
link: "Link_link"
|
|
8
|
+
};
|
|
9
|
+
function Link({
|
|
10
|
+
tone = "action",
|
|
11
|
+
underline = "always",
|
|
12
|
+
asChild = false,
|
|
13
|
+
className,
|
|
14
|
+
ref,
|
|
15
|
+
children,
|
|
16
|
+
...rest
|
|
17
|
+
}) {
|
|
18
|
+
const props = {
|
|
19
|
+
...rest,
|
|
20
|
+
ref,
|
|
21
|
+
className: classes(Link_default.link, className),
|
|
22
|
+
"data-tone": tone,
|
|
23
|
+
"data-underline": underline
|
|
24
|
+
};
|
|
25
|
+
if (asChild) {
|
|
26
|
+
return renderAsChild("Link", children, props);
|
|
27
|
+
}
|
|
28
|
+
return /* @__PURE__ */ jsx("a", { ...rest, ref, className: props.className, "data-tone": tone, "data-underline": underline, children });
|
|
29
|
+
}
|
|
30
|
+
Link.displayName = "Link";
|
|
31
|
+
|
|
32
|
+
export { Link };
|
|
33
|
+
//# sourceMappingURL=chunk-HDC2IQV2.js.map
|
|
34
|
+
//# sourceMappingURL=chunk-HDC2IQV2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/link/Link.module.css","../src/link/Link.tsx"],"names":["link"],"mappings":";;;;;AAAA,IAAA,YAAA,GAAA;AAAA,EAKG,IAAA,EAAAA;AAAA,CAAA;AC+BI,SAAS,IAAA,CAAgD;AAAA,EAC9D,IAAA,GAAO,QAAA;AAAA,EACP,SAAA,GAAY,QAAA;AAAA,EACZ,OAAA,GAAU,KAAA;AAAA,EACV,SAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiB;AACf,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,GAAG,IAAA;AAAA,IACH,GAAA;AAAA,IACA,SAAA,EAAW,OAAA,CAAQ,YAAA,CAAO,IAAA,EAAM,SAAS,CAAA;AAAA,IACzC,WAAA,EAAa,IAAA;AAAA,IACb,gBAAA,EAAkB;AAAA,GACpB;AAEA,EAAA,IAAI,OAAA,EAAS;AAEX,IAAA,OAAO,aAAA,CAAc,MAAA,EAAQ,QAAA,EAAU,KAAK,CAAA;AAAA,EAC9C;AAEA,EAAA,uBACE,GAAA,CAAC,GAAA,EAAA,EAAG,GAAG,IAAA,EAAM,GAAA,EAAoC,SAAA,EAAW,KAAA,CAAM,SAAA,EAAW,WAAA,EAAW,IAAA,EAAM,gBAAA,EAAgB,SAAA,EAC3G,QAAA,EACH,CAAA;AAEJ;AAEA,IAAA,CAAK,WAAA,GAAc,MAAA","file":"chunk-HDC2IQV2.js","sourcesContent":["/* Every value is a token: --link-* in packages/tokens/tokens/component/link.json */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .link {\n border-radius: var(--link-radius);\n color: var(--link-tone-action);\n font-weight: var(--link-weight);\n text-decoration-line: underline;\n text-decoration-thickness: from-font;\n text-underline-offset: 0.2em;\n cursor: pointer;\n transition: color var(--link-duration) var(--motion-easing-standard);\n\n &[data-tone=\"default\"] { color: var(--link-tone-default); }\n &[data-tone=\"muted\"] { color: var(--link-tone-muted); }\n\n &[data-underline=\"hover\"] { text-decoration-line: none; }\n\n &:hover {\n color: var(--link-hover);\n text-decoration-line: underline;\n }\n\n &:focus-visible {\n outline: var(--link-focus-ring-width) solid var(--link-focus-ring-color);\n outline-offset: var(--link-focus-ring-offset);\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n}\n","import type { AnchorHTMLAttributes, ReactNode, Ref } from 'react';\nimport { renderAsChild } from '../internal/asChild';\nimport { classes } from '../internal/classes';\nimport styles from './Link.module.css';\n\nexport type LinkTone = 'action' | 'default' | 'muted';\nexport type LinkUnderline = 'always' | 'hover';\n\nexport interface LinkProps<E extends HTMLElement = HTMLAnchorElement> extends AnchorHTMLAttributes<HTMLAnchorElement> {\n /** `action` is the brand's link colour; `default` and `muted` take the text colours. @default 'action' */\n tone?: LinkTone;\n /**\n * `hover` drops the underline until the pointer is over it. Only for links that\n * are obviously links from where they sit (a nav, a footer list). @default 'always'\n */\n underline?: LinkUnderline;\n /** Render the single child instead of an `a`: a router's link component. @default false */\n asChild?: boolean;\n\n ref?: Ref<E>;\n children: ReactNode;\n}\n\n/**\n * A text link. Underlined by default, because colour alone must not be what\n * tells a link from the words around it. With `asChild` the styles and props\n * land on a router's own link, so client-side navigation keeps working.\n *\n * @status experimental\n * @category Typography\n * @accessibility A native `a`: focusable and activated with Enter only when it has an `href` (or the `asChild` element provides one). The focus ring comes from the semantic focus tokens. `underline=\"hover\"` removes the only non-colour cue, so it is for lists of links, never for a link inside a sentence (WCAG 1.4.1).\n * @do Use `asChild` with the router's link: `<Link asChild><NextLink href=\"/feed\">Feed</NextLink></Link>`.\n * @do Write link text that makes sense out of context; screen readers list links on their own.\n * @dont Use it for an action that does not navigate; that is a Button (`variant=\"ghost\"`).\n * @dont Use `underline=\"hover\"` for a link inside running text.\n */\nexport function Link<E extends HTMLElement = HTMLAnchorElement>({\n tone = 'action',\n underline = 'always',\n asChild = false,\n className,\n ref,\n children,\n ...rest\n}: LinkProps<E>) {\n const props = {\n ...rest,\n ref,\n className: classes(styles.link, className),\n 'data-tone': tone,\n 'data-underline': underline,\n };\n\n if (asChild) {\n // eslint-disable-next-line react-hooks/refs -- forwarded, not read\n return renderAsChild('Link', children, props);\n }\n\n return (\n <a {...rest} ref={ref as Ref<HTMLAnchorElement>} className={props.className} data-tone={tone} data-underline={underline}>\n {children}\n </a>\n );\n}\n\nLink.displayName = 'Link';\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IconButton } from './chunk-
|
|
2
|
-
import { Button } from './chunk-
|
|
1
|
+
import { IconButton } from './chunk-56RSH7GQ.js';
|
|
2
|
+
import { Button } from './chunk-DE67ECD7.js';
|
|
3
3
|
import { classes } from './chunk-MI4QUKQS.js';
|
|
4
4
|
import { ArrowLeft, ArrowRight } from '@pearpages/pulp-icons';
|
|
5
5
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
@@ -80,5 +80,5 @@ function Pagination({
|
|
|
80
80
|
Pagination.displayName = "Pagination";
|
|
81
81
|
|
|
82
82
|
export { Pagination, paginationRange };
|
|
83
|
-
//# sourceMappingURL=chunk-
|
|
84
|
-
//# sourceMappingURL=chunk-
|
|
83
|
+
//# sourceMappingURL=chunk-HKNIEQ2V.js.map
|
|
84
|
+
//# sourceMappingURL=chunk-HKNIEQ2V.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pagination/range.ts","../src/pagination/Pagination.module.css","../src/pagination/Pagination.tsx"],"names":["root","list","page","ellipsis"],"mappings":"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","file":"chunk-HKNIEQ2V.js","sourcesContent":["export type PaginationItem = number | 'start-ellipsis' | 'end-ellipsis';\n\n/** Which pages to show: boundaries at both ends, siblings around the current page, ellipses for the rest. */\nexport function paginationRange(page: number, count: number, siblings: number, boundaries: number): PaginationItem[] {\n const span = (from: number, to: number) => Array.from({ length: Math.max(0, to - from + 1) }, (_, i) => from + i);\n const total = boundaries * 2 + siblings * 2 + 3;\n if (count <= total) return span(1, count);\n const start = span(1, boundaries);\n const end = span(count - boundaries + 1, count);\n const siblingStart = Math.max(Math.min(page - siblings, count - boundaries - siblings * 2 - 1), boundaries + 2);\n const siblingEnd = Math.min(Math.max(page + siblings, boundaries + siblings * 2 + 2), count - boundaries - 1);\n return [\n ...start,\n ...(siblingStart > boundaries + 2 ? (['start-ellipsis'] as PaginationItem[]) : span(boundaries + 1, boundaries + 1)),\n ...span(siblingStart, siblingEnd),\n ...(siblingEnd < count - boundaries - 1 ? (['end-ellipsis'] as PaginationItem[]) : span(count - boundaries, count - boundaries)),\n ...end,\n ];\n}\n","/* Every value is a token (--pagination-*). The controls are Buttons; this file lays them out. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .root {\n --_size: var(--pagination-ellipsis-size-md);\n --_font-size: var(--pagination-font-size-md);\n\n font-family: var(--pagination-font-family);\n\n &[data-size=\"sm\"] {\n --_size: var(--pagination-ellipsis-size-sm);\n --_font-size: var(--pagination-font-size-sm);\n }\n }\n\n .list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--pagination-gap);\n padding: 0;\n margin: 0;\n list-style: none;\n }\n\n .page {\n min-inline-size: var(--_size);\n padding-inline: 0;\n font-variant-numeric: tabular-nums;\n }\n\n .ellipsis {\n display: grid;\n place-items: center;\n min-inline-size: var(--_size);\n block-size: var(--_size);\n color: var(--pagination-ellipsis-fg);\n font-size: var(--_font-size);\n }\n}\n","import type { HTMLAttributes, Ref } from 'react';\nimport { ArrowLeft, ArrowRight } from '@pearpages/pulp-icons';\nimport { Button } from '../button';\nimport { IconButton } from '../icon-button';\nimport { classes } from '../internal/classes';\nimport { paginationRange } from './range';\nimport styles from './Pagination.module.css';\n\nexport type PaginationSize = 'sm' | 'md';\nexport interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** The current page, 1-based. */\n page: number;\n /** Total number of pages. */\n count: number;\n onPageChange?: (page: number) => void;\n /** Pages shown on each side of the current one. @default 1 */\n siblings?: number;\n /** Pages always shown at each end. @default 1 */\n boundaries?: number;\n /** Render pages as links (server-side or router pagination) instead of buttons. */\n getHref?: (page: number) => string;\n /** @default 'md' */\n size?: PaginationSize;\n /** The landmark's name. @default 'Pagination' */\n 'aria-label'?: string;\n /** @default 'Previous page' */\n previousLabel?: string;\n /** @default 'Next page' */\n nextLabel?: string;\n /** Accessible name of a page control. @default (n) => `Page ${n}` */\n pageLabel?: (page: number) => string;\n ref?: Ref<HTMLElement>;\n}\n\n/**\n * Page controls in a `nav` landmark: previous, numbered pages with the\n * current one marked `aria-current=\"page\"`, and next. Distant pages\n * collapse into an ellipsis. Buttons by default; `getHref` renders links so\n * the pages are crawlable and open in new tabs. Built from Button and\n * IconButton, so it needs no keyboard model of its own.\n *\n * @status experimental\n * @category Navigation\n * @accessibility A `nav` landmark named by `aria-label`; the current page carries `aria-current=\"page\"`; previous and next are IconButtons with names; ellipses are hidden from assistive technology. With `getHref` the controls are links.\n * @do Use `getHref` when pages have URLs so they can be opened in new tabs and crawled.\n * Keep `siblings` at 1 on narrow screens.\n * @dont Disable the whole component while a page loads; disable only what cannot be pressed.\n */\nexport function Pagination({\n page,\n count,\n onPageChange,\n siblings = 1,\n boundaries = 1,\n getHref,\n size = 'md',\n 'aria-label': ariaLabel = 'Pagination',\n previousLabel = 'Previous page',\n nextLabel = 'Next page',\n pageLabel = (n) => `Page ${n}`,\n className,\n ref,\n ...rest\n}: PaginationProps) {\n const go = (target: number) => () => onPageChange?.(target);\n\n return (\n <nav {...rest} ref={ref} aria-label={ariaLabel} className={classes(styles.root, className)} data-size={size}>\n <ul className={styles.list}>\n <li>\n {page > 1 && getHref ? (\n <IconButton<HTMLAnchorElement> asChild label={previousLabel} icon={<ArrowLeft />} variant=\"ghost\" size={size} onClick={go(page - 1)}>\n <a href={getHref(page - 1)} />\n </IconButton>\n ) : (\n <IconButton label={previousLabel} icon={<ArrowLeft />} variant=\"ghost\" size={size} disabled={page <= 1} onClick={go(page - 1)} />\n )}\n </li>\n {paginationRange(page, count, siblings, boundaries).map((item) =>\n typeof item === 'number' ? (\n <li key={item}>\n {getHref ? (\n <Button<HTMLAnchorElement>\n asChild\n variant={item === page ? 'primary' : 'ghost'}\n size={size}\n className={styles.page}\n aria-label={pageLabel(item)}\n aria-current={item === page ? 'page' : undefined}\n onClick={go(item)}\n >\n <a href={getHref(item)}>{item}</a>\n </Button>\n ) : (\n <Button\n variant={item === page ? 'primary' : 'ghost'}\n size={size}\n className={styles.page}\n aria-label={pageLabel(item)}\n aria-current={item === page ? 'page' : undefined}\n onClick={go(item)}\n >\n {item}\n </Button>\n )}\n </li>\n ) : (\n <li key={item} className={styles.ellipsis} aria-hidden=\"true\">\n …\n </li>\n ),\n )}\n <li>\n {page < count && getHref ? (\n <IconButton<HTMLAnchorElement> asChild label={nextLabel} icon={<ArrowRight />} variant=\"ghost\" size={size} onClick={go(page + 1)}>\n <a href={getHref(page + 1)} />\n </IconButton>\n ) : (\n <IconButton label={nextLabel} icon={<ArrowRight />} variant=\"ghost\" size={size} disabled={page >= count} onClick={go(page + 1)} />\n )}\n </li>\n </ul>\n </nav>\n );\n}\n\nPagination.displayName = 'Pagination';\n"]}
|