@kushagradhawan/kookie-ui 0.1.121 → 0.1.123
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/sheet.d.ts +7 -6
- package/dist/cjs/components/sheet.d.ts.map +1 -1
- package/dist/cjs/components/sheet.js +1 -1
- package/dist/cjs/components/sheet.js.map +3 -3
- package/dist/esm/components/sheet.d.ts +7 -6
- package/dist/esm/components/sheet.d.ts.map +1 -1
- package/dist/esm/components/sheet.js +1 -1
- package/dist/esm/components/sheet.js.map +3 -3
- package/package.json +1 -1
- package/schemas/base-button.json +1 -1
- package/schemas/button.json +1 -1
- package/schemas/icon-button.json +1 -1
- package/schemas/index.json +6 -6
- package/schemas/toggle-button.json +1 -1
- package/schemas/toggle-icon-button.json +1 -1
- package/src/components/sheet.tsx +18 -14
|
@@ -33,7 +33,9 @@
|
|
|
33
33
|
import * as React from 'react';
|
|
34
34
|
import { Dialog as DialogPrimitive } from 'radix-ui';
|
|
35
35
|
import type { DialogContentOwnProps } from './dialog.props.js';
|
|
36
|
+
import { Text } from './text.js';
|
|
36
37
|
import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';
|
|
38
|
+
import type { HeadingProps } from './heading.js';
|
|
37
39
|
/**
|
|
38
40
|
* Supported sides for the Sheet.
|
|
39
41
|
* Aliases are normalized RTL-aware: `left` → `start`, `right` → `end`.
|
|
@@ -65,14 +67,13 @@ interface SheetContentProps extends ComponentPropsWithout<typeof DialogPrimitive
|
|
|
65
67
|
* or `aria-label`.
|
|
66
68
|
*/
|
|
67
69
|
declare const Content: React.ForwardRefExoticComponent<SheetContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
68
|
-
interface SheetTitleProps extends
|
|
70
|
+
interface SheetTitleProps extends HeadingProps {
|
|
69
71
|
}
|
|
70
|
-
/** Accessible title for the Sheet.
|
|
72
|
+
/** Accessible title for the Sheet. Renders as Heading with sensible defaults. */
|
|
71
73
|
declare const Title: React.ForwardRefExoticComponent<SheetTitleProps & React.RefAttributes<HTMLHeadingElement>>;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
declare const Description: React.ForwardRefExoticComponent<SheetDescriptionProps & React.RefAttributes<HTMLParagraphElement>>;
|
|
74
|
+
type SheetDescriptionProps = React.ComponentPropsWithoutRef<typeof Text>;
|
|
75
|
+
/** Supplementary description text for Sheet content. Renders as Text with sensible defaults. */
|
|
76
|
+
declare const Description: React.ForwardRefExoticComponent<SheetDescriptionProps & React.RefAttributes<HTMLSpanElement>>;
|
|
76
77
|
interface SheetCloseProps extends ComponentPropsWithout<typeof DialogPrimitive.Close, RemovedProps> {
|
|
77
78
|
}
|
|
78
79
|
/** Close button for the Sheet. Expects a single element child rendered via `asChild`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../../src/components/sheet.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../../src/components/sheet.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG/D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAKjC,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD;;;GAGG;AACH,KAAK,SAAS,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvE;;;GAGG;AAGH;;GAEG;AACH,UAAU,cAAe,SAAQ,qBAAqB,CAAC,OAAO,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC;CAAG;AAC/F,QAAA,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAAwD,CAAC;AAM5F,kEAAkE;AAClE,UAAU,iBACR,SAAQ,qBAAqB,CAAC,OAAO,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC;CAAG;AAChF,QAAA,MAAM,OAAO,6FAMZ,CAAC;AAMF,UAAU,iBACR,SAAQ,qBAAqB,CAAC,OAAO,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC,EACzE,qBAAqB;IACvB,iFAAiF;IACjF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,KAAK,CAAC,wBAAwB,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;CACxF;AAED;;;;GAIG;AACH,QAAA,MAAM,OAAO,0FA4JZ,CAAC;AAKF,UAAU,eAAgB,SAAQ,YAAY;CAAG;AACjD,iFAAiF;AACjF,QAAA,MAAM,KAAK,4FAMV,CAAC;AAKF,KAAK,qBAAqB,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,IAAI,CAAC,CAAC;AACzE,gGAAgG;AAChG,QAAA,MAAM,WAAW,+FAMhB,CAAC;AAIF,UAAU,eACR,SAAQ,qBAAqB,CAAC,OAAO,eAAe,CAAC,KAAK,EAAE,YAAY,CAAC;CAAG;AAC9E,yFAAyF;AACzF,QAAA,MAAM,KAAK,2FAMV,CAAC;AAGF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAC7D,YAAY,EACV,cAAc,IAAI,SAAS,EAC3B,iBAAiB,IAAI,YAAY,EACjC,iBAAiB,IAAI,YAAY,EACjC,eAAe,IAAI,UAAU,EAC7B,qBAAqB,IAAI,gBAAgB,EACzC,eAAe,IAAI,UAAU,GAC9B,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";"use client";var
|
|
1
|
+
"use strict";"use client";var G=Object.create;var c=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var X=Object.getPrototypeOf,Y=Object.prototype.hasOwnProperty;var Z=(e,t)=>{for(var r in t)c(e,r,{get:t[r],enumerable:!0})},x=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Q(t))!Y.call(e,s)&&s!==r&&c(e,s,{get:()=>t[s],enumerable:!(a=J(t,s))||a.enumerable});return e};var N=(e,t,r)=>(r=e!=null?G(X(e)):{},x(t||!e||!e.__esModule?c(r,"default",{value:e,enumerable:!0}):r,e)),$=e=>x(c({},"__esModule",{value:!0}),e);var ee={};Z(ee,{Close:()=>C,Content:()=>y,Description:()=>S,Root:()=>P,Title:()=>D,Trigger:()=>u});module.exports=$(ee);var o=N(require("react")),k=N(require("classnames")),n=require("radix-ui"),M=require("./dialog.props.js"),w=require("./theme.js"),B=require("./heading.js"),W=require("./text.js"),h=require("../helpers/extract-props.js"),g=require("../helpers/require-react-element.js"),O=require("../hooks/use-body-pointer-events-cleanup.js");const P=e=>o.createElement(n.Dialog.Root,{...e,modal:!0});P.displayName="Sheet.Root";const u=o.forwardRef(({children:e,...t},r)=>o.createElement(n.Dialog.Trigger,{...t,ref:r,asChild:!0},(0,g.requireReactElement)(e)));u.displayName="Sheet.Trigger";const y=o.forwardRef((e,t)=>{const{side:r="start",forceMount:a,container:s,className:H,panelBackground:L,material:j,...z}=e,A={left:"start",right:"end",start:"start",end:"end",top:"top",bottom:"bottom"}[r],{align:oe,panelBackground:V,material:_,...v}=M.dialogContentPropDefs,{panelBackground:d,material:T}=(0,h.extractProps)({panelBackground:L,material:j},{panelBackground:V,material:_}),E=o.useMemo(()=>T??d,[T,d]),{default:re,...K}=v.maxWidth,q={...v,maxWidth:K},{className:I,...F}=(0,h.extractProps)(z,q),R=o.useRef(null),U=o.useMemo(()=>i=>{R.current=i,typeof t=="function"?t(i):t&&(t.current=i)},[t]);return(0,O.useBodyPointerEventsCleanup)(),o.useEffect(()=>{if(typeof window>"u")return;const i=R.current;if(!i)return;const l=i.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(l.length===0)return;const p=l[0],f=l[l.length-1],b=m=>{m.key==="Tab"&&(m.shiftKey?document.activeElement===p&&(m.preventDefault(),f.focus()):document.activeElement===f&&(m.preventDefault(),p.focus()))};return i.addEventListener("keydown",b),p.focus(),()=>{i.removeEventListener("keydown",b)}},[]),o.createElement(n.Dialog.Portal,{container:s,forceMount:a},o.createElement(w.Theme,{asChild:!0},o.createElement(n.Dialog.Overlay,{className:"rt-BaseDialogOverlay rt-DialogOverlay rt-SheetOverlay"},o.createElement(n.Dialog.Content,{...F,ref:U,className:(0,k.default)("rt-BaseDialogContent","rt-SheetContent",H,I),"data-side":A,"data-material":E,"data-panel-background":E,tabIndex:-1,role:"dialog","aria-modal":"true"}))))});y.displayName="Sheet.Content";const D=o.forwardRef(({size:e="4",weight:t="medium",...r},a)=>o.createElement(n.Dialog.Title,{asChild:!0},o.createElement(B.Heading,{ref:a,size:e,weight:t,...r})));D.displayName="Sheet.Title";const S=o.forwardRef(({size:e="2",color:t="gray",...r},a)=>o.createElement(n.Dialog.Description,{asChild:!0},o.createElement(W.Text,{ref:a,size:e,color:t,...r})));S.displayName="Sheet.Description";const C=o.forwardRef(({children:e,...t},r)=>o.createElement(n.Dialog.Close,{...t,ref:r,asChild:!0},(0,g.requireReactElement)(e)));C.displayName="Sheet.Close";
|
|
2
2
|
//# sourceMappingURL=sheet.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/sheet.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client';\n\n/**\n * Sheet\n *\n * A side-placed overlay built on top of Radix Dialog. It inherits accessibility,\n * focus management, overlay behavior, and sizing scales from the base dialog, and\n * adds side placement and slide motion suited for navigation panels and drawers.\n *\n * Structure mirrors Dialog:\n * - Root, Trigger, Content, Title, Description, Close\n *\n * Notes\n * - Side: set with `side` on `Sheet.Content`. Aliases: `left` \u2192 `start`, `right` \u2192 `end`.\n * - Sizing: reuses Dialog content prop defs (width/min/max/height/size). Default Dialog\n * maxWidth clamping is removed for Sheets.\n * - Material: use `material` (solid | translucent). Deprecated `panelBackground` falls back\n * in dev with a warning.\n * - A11y: provide an accessible name via `Sheet.Title` or `aria-label` on `Sheet.Content`.\n *\n * Example\n * <Sheet.Root>\n * <Sheet.Trigger>\n * <Button>Open</Button>\n * </Sheet.Trigger>\n * <Sheet.Content side=\"end\" width={{ initial: '280px', md: '360px' }}>\n * <Sheet.Title>Details</Sheet.Title>\n * ...\n * <Sheet.Close>\n * <Button>Close</Button>\n * </Sheet.Close>\n * </Sheet.Content>\n * </Sheet.Root>\n */\n\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\n\nimport { dialogContentPropDefs } from './dialog.props.js';\nimport type { DialogContentOwnProps } from './dialog.props.js';\nimport { Theme } from './theme.js';\nimport { extractProps } from '../helpers/extract-props.js';\nimport { requireReactElement } from '../helpers/require-react-element.js';\nimport { useBodyPointerEventsCleanup } from '../hooks/use-body-pointer-events-cleanup.js';\n\nimport type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';\n\n/**\n * Supported sides for the Sheet.\n * Aliases are normalized RTL-aware: `left` \u2192 `start`, `right` \u2192 `end`.\n */\ntype SheetSide = 'start' | 'end' | 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * Sheet is a side-placed overlay built on the Dialog primitive.\n * It reuses Dialog's accessibility, focus, overlay, and size scales, while adding side placement and slide motion.\n */\n\n// Root\n/**\n * Props for `Sheet.Root` (Radix Dialog root with `modal` forced on).\n */\ninterface SheetRootProps extends ComponentPropsWithout<typeof DialogPrimitive.Root, 'modal'> {}\nconst Root: React.FC<SheetRootProps> = (props) => <DialogPrimitive.Root {...props} modal />;\nRoot.displayName = 'Sheet.Root';\n\n// Trigger\n/** Element type for `Sheet.Trigger`. */\ntype SheetTriggerElement = React.ElementRef<typeof DialogPrimitive.Trigger>;\n/** Props for `Sheet.Trigger` (expects a single element child). */\ninterface SheetTriggerProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Trigger, RemovedProps> {}\nconst Trigger = React.forwardRef<SheetTriggerElement, SheetTriggerProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Trigger {...props} ref={ref} asChild>\n {requireReactElement(children)}\n </DialogPrimitive.Trigger>\n ),\n);\nTrigger.displayName = 'Sheet.Trigger';\n\n// Content\n/** Element type for `Sheet.Content`. */\ntype SheetContentElement = React.ElementRef<typeof DialogPrimitive.Content>;\ninterface SheetContentProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Content, RemovedProps>,\n DialogContentOwnProps {\n /** Side where the Sheet should appear. `left`/`right` alias to `start`/`end`. */\n side?: SheetSide;\n /** Optional DOM container to portal into. Defaults to `document.body`. */\n container?: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Portal>['container'];\n}\n\n/**\n * Renders the Sheet panel. Normalizes left/right to logical start/end and\n * forwards dialog sizing props. Provide an accessible name via `Sheet.Title`\n * or `aria-label`.\n */\nconst Content = React.forwardRef<SheetContentElement, SheetContentProps>(\n (allProps, forwardedRef) => {\n const {\n side = 'start',\n forceMount,\n container,\n className,\n panelBackground: panelBackgroundProp,\n material: materialProp,\n ...restProps\n } = allProps;\n const normalizedSideMap: Record<SheetSide, 'start' | 'end' | 'top' | 'bottom'> = {\n left: 'start',\n right: 'end',\n start: 'start',\n end: 'end',\n top: 'top',\n bottom: 'bottom',\n };\n const normalizedSide = normalizedSideMap[side];\n // Reuse dialog content prop defs for size/width/height tokens, but handle\n // material/panelBackground explicitly to avoid forwarding unknown DOM props.\n const {\n align: _alignPropDef,\n panelBackground: panelBackgroundPropDef,\n material: materialPropDef,\n ...propDefs\n } = dialogContentPropDefs;\n\n // Extract panelBackground and material together (remove from DOM props)\n const { panelBackground: resolvedPanelBackground, material: resolvedMaterial } = extractProps(\n { panelBackground: panelBackgroundProp, material: materialProp },\n { panelBackground: panelBackgroundPropDef, material: materialPropDef },\n );\n\n const materialValue = React.useMemo(() => {\n if (resolvedPanelBackground !== undefined) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning: The `panelBackground` prop is deprecated and will be removed in a future version. Use the `material` prop instead.',\n );\n }\n }\n return resolvedMaterial ?? resolvedPanelBackground;\n }, [resolvedMaterial, resolvedPanelBackground]);\n\n // Now extract remaining props using dialog defs so size/width/height classnames are applied\n // Override dialog's default maxWidth (600px) to avoid clamping Sheet by default\n // Match dialog.tsx: extract once and avoid leaking panel/material\n const { default: _mwDefault, ...maxWidthWithoutDefault } = propDefs.maxWidth;\n const sheetPropDefs = {\n ...propDefs,\n maxWidth: maxWidthWithoutDefault,\n } as typeof propDefs;\n const { className: extractedClassName, ...contentProps } = extractProps(\n restProps,\n sheetPropDefs,\n );\n\n // Dev-only a11y guard: ensure label is provided via Title or aria-label\n if (process.env.NODE_ENV !== 'production') {\n const children = (contentProps as any).children as React.ReactNode;\n const hasAriaLabel = typeof (contentProps as any)['aria-label'] === 'string';\n let hasTitle = false;\n if (children) {\n for (const child of React.Children.toArray(children)) {\n if (React.isValidElement(child) && child.type === Title) {\n hasTitle = true;\n break;\n }\n }\n }\n if (!hasTitle && !hasAriaLabel) {\n console.warn(\n 'Sheet.Content: Missing accessible name. Include Sheet.Title as a child or provide aria-label.',\n );\n }\n }\n\n // Focus management and stuck pointer-events cleanup like Dialog\n const contentRef = React.useRef<HTMLDivElement>(null);\n const combinedRef = React.useMemo(\n () => (node: HTMLDivElement | null) => {\n contentRef.current = node;\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else if (forwardedRef) {\n (forwardedRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n },\n [forwardedRef],\n );\n\n useBodyPointerEventsCleanup();\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return;\n const content = contentRef.current;\n if (!content) return;\n\n const focusableElements = content.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0] as HTMLElement;\n const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n content.addEventListener('keydown', handleKeyDown);\n firstElement.focus();\n\n return () => {\n content.removeEventListener('keydown', handleKeyDown);\n };\n }, []);\n\n return (\n <DialogPrimitive.Portal container={container} forceMount={forceMount}>\n <Theme asChild>\n <DialogPrimitive.Overlay className=\"rt-BaseDialogOverlay rt-DialogOverlay rt-SheetOverlay\">\n <DialogPrimitive.Content\n {...contentProps}\n ref={combinedRef}\n className={classNames(\n 'rt-BaseDialogContent',\n 'rt-SheetContent',\n className,\n extractedClassName,\n )}\n data-side={normalizedSide}\n data-material={materialValue}\n data-panel-background={materialValue}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n />\n </DialogPrimitive.Overlay>\n </Theme>\n </DialogPrimitive.Portal>\n );\n },\n);\nContent.displayName = 'Sheet.Content';\n\n// Title/Description/Close re-export\ntype SheetTitleElement = React.ElementRef<typeof DialogPrimitive.Title>;\ninterface SheetTitleProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title> {}\n/** Accessible title for the Sheet. Required for non-decorative content. */\nconst Title = React.forwardRef<SheetTitleElement, SheetTitleProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Title {...props} ref={ref} asChild={false}>\n {children}\n </DialogPrimitive.Title>\n ),\n);\nTitle.displayName = 'Sheet.Title';\n\ntype SheetDescriptionElement = React.ElementRef<typeof DialogPrimitive.Description>;\ninterface SheetDescriptionProps\n extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description> {}\n/** Supplementary description text for Sheet content. */\nconst Description = React.forwardRef<SheetDescriptionElement, SheetDescriptionProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Description {...props} ref={ref} asChild={false}>\n {children}\n </DialogPrimitive.Description>\n ),\n);\nDescription.displayName = 'Sheet.Description';\n\ntype SheetCloseElement = React.ElementRef<typeof DialogPrimitive.Close>;\ninterface SheetCloseProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Close, RemovedProps> {}\n/** Close button for the Sheet. Expects a single element child rendered via `asChild`. */\nconst Close = React.forwardRef<SheetCloseElement, SheetCloseProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Close {...props} ref={ref} asChild>\n {requireReactElement(children)}\n </DialogPrimitive.Close>\n ),\n);\nClose.displayName = 'Sheet.Close';\n\nexport { Root, Trigger, Content, Title, Description, Close };\nexport type {\n SheetRootProps as RootProps,\n SheetTriggerProps as TriggerProps,\n SheetContentProps as ContentProps,\n SheetTitleProps as TitleProps,\n SheetDescriptionProps as DescriptionProps,\n SheetCloseProps as CloseProps,\n};\n"],
|
|
5
|
-
"mappings": "ukBAAA,IAAAA,
|
|
6
|
-
"names": ["sheet_exports", "__export", "Close", "Content", "Description", "Root", "Title", "Trigger", "__toCommonJS", "React", "import_classnames", "import_radix_ui", "import_dialog_props", "import_theme", "import_extract_props", "import_require_react_element", "import_use_body_pointer_events_cleanup", "props", "DialogPrimitive", "children", "ref", "allProps", "forwardedRef", "side", "forceMount", "container", "className", "panelBackgroundProp", "materialProp", "restProps", "normalizedSide", "_alignPropDef", "panelBackgroundPropDef", "materialPropDef", "propDefs", "resolvedPanelBackground", "resolvedMaterial", "materialValue", "_mwDefault", "maxWidthWithoutDefault", "sheetPropDefs", "extractedClassName", "contentProps", "contentRef", "combinedRef", "node", "content", "focusableElements", "firstElement", "lastElement", "handleKeyDown", "event", "classNames"]
|
|
4
|
+
"sourcesContent": ["'use client';\n\n/**\n * Sheet\n *\n * A side-placed overlay built on top of Radix Dialog. It inherits accessibility,\n * focus management, overlay behavior, and sizing scales from the base dialog, and\n * adds side placement and slide motion suited for navigation panels and drawers.\n *\n * Structure mirrors Dialog:\n * - Root, Trigger, Content, Title, Description, Close\n *\n * Notes\n * - Side: set with `side` on `Sheet.Content`. Aliases: `left` \u2192 `start`, `right` \u2192 `end`.\n * - Sizing: reuses Dialog content prop defs (width/min/max/height/size). Default Dialog\n * maxWidth clamping is removed for Sheets.\n * - Material: use `material` (solid | translucent). Deprecated `panelBackground` falls back\n * in dev with a warning.\n * - A11y: provide an accessible name via `Sheet.Title` or `aria-label` on `Sheet.Content`.\n *\n * Example\n * <Sheet.Root>\n * <Sheet.Trigger>\n * <Button>Open</Button>\n * </Sheet.Trigger>\n * <Sheet.Content side=\"end\" width={{ initial: '280px', md: '360px' }}>\n * <Sheet.Title>Details</Sheet.Title>\n * ...\n * <Sheet.Close>\n * <Button>Close</Button>\n * </Sheet.Close>\n * </Sheet.Content>\n * </Sheet.Root>\n */\n\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\n\nimport { dialogContentPropDefs } from './dialog.props.js';\nimport type { DialogContentOwnProps } from './dialog.props.js';\nimport { Theme } from './theme.js';\nimport { Heading } from './heading.js';\nimport { Text } from './text.js';\nimport { extractProps } from '../helpers/extract-props.js';\nimport { requireReactElement } from '../helpers/require-react-element.js';\nimport { useBodyPointerEventsCleanup } from '../hooks/use-body-pointer-events-cleanup.js';\n\nimport type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';\nimport type { HeadingProps } from './heading.js';\nimport type { TextProps } from './text.js';\n\n/**\n * Supported sides for the Sheet.\n * Aliases are normalized RTL-aware: `left` \u2192 `start`, `right` \u2192 `end`.\n */\ntype SheetSide = 'start' | 'end' | 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * Sheet is a side-placed overlay built on the Dialog primitive.\n * It reuses Dialog's accessibility, focus, overlay, and size scales, while adding side placement and slide motion.\n */\n\n// Root\n/**\n * Props for `Sheet.Root` (Radix Dialog root with `modal` forced on).\n */\ninterface SheetRootProps extends ComponentPropsWithout<typeof DialogPrimitive.Root, 'modal'> {}\nconst Root: React.FC<SheetRootProps> = (props) => <DialogPrimitive.Root {...props} modal />;\nRoot.displayName = 'Sheet.Root';\n\n// Trigger\n/** Element type for `Sheet.Trigger`. */\ntype SheetTriggerElement = React.ElementRef<typeof DialogPrimitive.Trigger>;\n/** Props for `Sheet.Trigger` (expects a single element child). */\ninterface SheetTriggerProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Trigger, RemovedProps> {}\nconst Trigger = React.forwardRef<SheetTriggerElement, SheetTriggerProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Trigger {...props} ref={ref} asChild>\n {requireReactElement(children)}\n </DialogPrimitive.Trigger>\n ),\n);\nTrigger.displayName = 'Sheet.Trigger';\n\n// Content\n/** Element type for `Sheet.Content`. */\ntype SheetContentElement = React.ElementRef<typeof DialogPrimitive.Content>;\ninterface SheetContentProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Content, RemovedProps>,\n DialogContentOwnProps {\n /** Side where the Sheet should appear. `left`/`right` alias to `start`/`end`. */\n side?: SheetSide;\n /** Optional DOM container to portal into. Defaults to `document.body`. */\n container?: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Portal>['container'];\n}\n\n/**\n * Renders the Sheet panel. Normalizes left/right to logical start/end and\n * forwards dialog sizing props. Provide an accessible name via `Sheet.Title`\n * or `aria-label`.\n */\nconst Content = React.forwardRef<SheetContentElement, SheetContentProps>(\n (allProps, forwardedRef) => {\n const {\n side = 'start',\n forceMount,\n container,\n className,\n panelBackground: panelBackgroundProp,\n material: materialProp,\n ...restProps\n } = allProps;\n const normalizedSideMap: Record<SheetSide, 'start' | 'end' | 'top' | 'bottom'> = {\n left: 'start',\n right: 'end',\n start: 'start',\n end: 'end',\n top: 'top',\n bottom: 'bottom',\n };\n const normalizedSide = normalizedSideMap[side];\n // Reuse dialog content prop defs for size/width/height tokens, but handle\n // material/panelBackground explicitly to avoid forwarding unknown DOM props.\n const {\n align: _alignPropDef,\n panelBackground: panelBackgroundPropDef,\n material: materialPropDef,\n ...propDefs\n } = dialogContentPropDefs;\n\n // Extract panelBackground and material together (remove from DOM props)\n const { panelBackground: resolvedPanelBackground, material: resolvedMaterial } = extractProps(\n { panelBackground: panelBackgroundProp, material: materialProp },\n { panelBackground: panelBackgroundPropDef, material: materialPropDef },\n );\n\n const materialValue = React.useMemo(() => {\n if (resolvedPanelBackground !== undefined) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning: The `panelBackground` prop is deprecated and will be removed in a future version. Use the `material` prop instead.',\n );\n }\n }\n return resolvedMaterial ?? resolvedPanelBackground;\n }, [resolvedMaterial, resolvedPanelBackground]);\n\n // Now extract remaining props using dialog defs so size/width/height classnames are applied\n // Override dialog's default maxWidth (600px) to avoid clamping Sheet by default\n // Match dialog.tsx: extract once and avoid leaking panel/material\n const { default: _mwDefault, ...maxWidthWithoutDefault } = propDefs.maxWidth;\n const sheetPropDefs = {\n ...propDefs,\n maxWidth: maxWidthWithoutDefault,\n } as typeof propDefs;\n const { className: extractedClassName, ...contentProps } = extractProps(\n restProps,\n sheetPropDefs,\n );\n\n // Dev-only a11y guard: ensure label is provided via Title or aria-label\n if (process.env.NODE_ENV !== 'production') {\n const children = (contentProps as any).children as React.ReactNode;\n const hasAriaLabel = typeof (contentProps as any)['aria-label'] === 'string';\n let hasTitle = false;\n if (children) {\n for (const child of React.Children.toArray(children)) {\n if (React.isValidElement(child) && child.type === Title) {\n hasTitle = true;\n break;\n }\n }\n }\n if (!hasTitle && !hasAriaLabel) {\n console.warn(\n 'Sheet.Content: Missing accessible name. Include Sheet.Title as a child or provide aria-label.',\n );\n }\n }\n\n // Focus management and stuck pointer-events cleanup like Dialog\n const contentRef = React.useRef<HTMLDivElement>(null);\n const combinedRef = React.useMemo(\n () => (node: HTMLDivElement | null) => {\n contentRef.current = node;\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else if (forwardedRef) {\n (forwardedRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n },\n [forwardedRef],\n );\n\n useBodyPointerEventsCleanup();\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return;\n const content = contentRef.current;\n if (!content) return;\n\n const focusableElements = content.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0] as HTMLElement;\n const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n content.addEventListener('keydown', handleKeyDown);\n firstElement.focus();\n\n return () => {\n content.removeEventListener('keydown', handleKeyDown);\n };\n }, []);\n\n return (\n <DialogPrimitive.Portal container={container} forceMount={forceMount}>\n <Theme asChild>\n <DialogPrimitive.Overlay className=\"rt-BaseDialogOverlay rt-DialogOverlay rt-SheetOverlay\">\n <DialogPrimitive.Content\n {...contentProps}\n ref={combinedRef}\n className={classNames(\n 'rt-BaseDialogContent',\n 'rt-SheetContent',\n className,\n extractedClassName,\n )}\n data-side={normalizedSide}\n data-material={materialValue}\n data-panel-background={materialValue}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n />\n </DialogPrimitive.Overlay>\n </Theme>\n </DialogPrimitive.Portal>\n );\n },\n);\nContent.displayName = 'Sheet.Content';\n\n// Title - renders as Heading with sensible defaults\ntype SheetTitleElement = React.ElementRef<typeof Heading>;\ninterface SheetTitleProps extends HeadingProps {}\n/** Accessible title for the Sheet. Renders as Heading with sensible defaults. */\nconst Title = React.forwardRef<SheetTitleElement, SheetTitleProps>(\n ({ size = '4', weight = 'medium', ...props }, ref) => (\n <DialogPrimitive.Title asChild>\n <Heading ref={ref} size={size} weight={weight} {...props} />\n </DialogPrimitive.Title>\n ),\n);\nTitle.displayName = 'Sheet.Title';\n\n// Description - renders as Text with sensible defaults\ntype SheetDescriptionElement = React.ElementRef<typeof Text>;\ntype SheetDescriptionProps = React.ComponentPropsWithoutRef<typeof Text>;\n/** Supplementary description text for Sheet content. Renders as Text with sensible defaults. */\nconst Description = React.forwardRef<SheetDescriptionElement, SheetDescriptionProps>(\n ({ size = '2', color = 'gray', ...rest }, ref) => (\n <DialogPrimitive.Description asChild>\n <Text ref={ref} size={size} color={color} {...rest} />\n </DialogPrimitive.Description>\n ),\n);\nDescription.displayName = 'Sheet.Description';\n\ntype SheetCloseElement = React.ElementRef<typeof DialogPrimitive.Close>;\ninterface SheetCloseProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Close, RemovedProps> {}\n/** Close button for the Sheet. Expects a single element child rendered via `asChild`. */\nconst Close = React.forwardRef<SheetCloseElement, SheetCloseProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Close {...props} ref={ref} asChild>\n {requireReactElement(children)}\n </DialogPrimitive.Close>\n ),\n);\nClose.displayName = 'Sheet.Close';\n\nexport { Root, Trigger, Content, Title, Description, Close };\nexport type {\n SheetRootProps as RootProps,\n SheetTriggerProps as TriggerProps,\n SheetContentProps as ContentProps,\n SheetTitleProps as TitleProps,\n SheetDescriptionProps as DescriptionProps,\n SheetCloseProps as CloseProps,\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["sheet_exports", "__export", "Close", "Content", "Description", "Root", "Title", "Trigger", "__toCommonJS", "React", "import_classnames", "import_radix_ui", "import_dialog_props", "import_theme", "import_heading", "import_text", "import_extract_props", "import_require_react_element", "import_use_body_pointer_events_cleanup", "props", "DialogPrimitive", "children", "ref", "allProps", "forwardedRef", "side", "forceMount", "container", "className", "panelBackgroundProp", "materialProp", "restProps", "normalizedSide", "_alignPropDef", "panelBackgroundPropDef", "materialPropDef", "propDefs", "resolvedPanelBackground", "resolvedMaterial", "materialValue", "_mwDefault", "maxWidthWithoutDefault", "sheetPropDefs", "extractedClassName", "contentProps", "contentRef", "combinedRef", "node", "content", "focusableElements", "firstElement", "lastElement", "handleKeyDown", "event", "classNames", "size", "weight", "color", "rest"]
|
|
7
7
|
}
|
|
@@ -33,7 +33,9 @@
|
|
|
33
33
|
import * as React from 'react';
|
|
34
34
|
import { Dialog as DialogPrimitive } from 'radix-ui';
|
|
35
35
|
import type { DialogContentOwnProps } from './dialog.props.js';
|
|
36
|
+
import { Text } from './text.js';
|
|
36
37
|
import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';
|
|
38
|
+
import type { HeadingProps } from './heading.js';
|
|
37
39
|
/**
|
|
38
40
|
* Supported sides for the Sheet.
|
|
39
41
|
* Aliases are normalized RTL-aware: `left` → `start`, `right` → `end`.
|
|
@@ -65,14 +67,13 @@ interface SheetContentProps extends ComponentPropsWithout<typeof DialogPrimitive
|
|
|
65
67
|
* or `aria-label`.
|
|
66
68
|
*/
|
|
67
69
|
declare const Content: React.ForwardRefExoticComponent<SheetContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
68
|
-
interface SheetTitleProps extends
|
|
70
|
+
interface SheetTitleProps extends HeadingProps {
|
|
69
71
|
}
|
|
70
|
-
/** Accessible title for the Sheet.
|
|
72
|
+
/** Accessible title for the Sheet. Renders as Heading with sensible defaults. */
|
|
71
73
|
declare const Title: React.ForwardRefExoticComponent<SheetTitleProps & React.RefAttributes<HTMLHeadingElement>>;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
declare const Description: React.ForwardRefExoticComponent<SheetDescriptionProps & React.RefAttributes<HTMLParagraphElement>>;
|
|
74
|
+
type SheetDescriptionProps = React.ComponentPropsWithoutRef<typeof Text>;
|
|
75
|
+
/** Supplementary description text for Sheet content. Renders as Text with sensible defaults. */
|
|
76
|
+
declare const Description: React.ForwardRefExoticComponent<SheetDescriptionProps & React.RefAttributes<HTMLSpanElement>>;
|
|
76
77
|
interface SheetCloseProps extends ComponentPropsWithout<typeof DialogPrimitive.Close, RemovedProps> {
|
|
77
78
|
}
|
|
78
79
|
/** Close button for the Sheet. Expects a single element child rendered via `asChild`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../../src/components/sheet.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../../src/components/sheet.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG/D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAKjC,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD;;;GAGG;AACH,KAAK,SAAS,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvE;;;GAGG;AAGH;;GAEG;AACH,UAAU,cAAe,SAAQ,qBAAqB,CAAC,OAAO,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC;CAAG;AAC/F,QAAA,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAAwD,CAAC;AAM5F,kEAAkE;AAClE,UAAU,iBACR,SAAQ,qBAAqB,CAAC,OAAO,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC;CAAG;AAChF,QAAA,MAAM,OAAO,6FAMZ,CAAC;AAMF,UAAU,iBACR,SAAQ,qBAAqB,CAAC,OAAO,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC,EACzE,qBAAqB;IACvB,iFAAiF;IACjF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,KAAK,CAAC,wBAAwB,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;CACxF;AAED;;;;GAIG;AACH,QAAA,MAAM,OAAO,0FA4JZ,CAAC;AAKF,UAAU,eAAgB,SAAQ,YAAY;CAAG;AACjD,iFAAiF;AACjF,QAAA,MAAM,KAAK,4FAMV,CAAC;AAKF,KAAK,qBAAqB,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,IAAI,CAAC,CAAC;AACzE,gGAAgG;AAChG,QAAA,MAAM,WAAW,+FAMhB,CAAC;AAIF,UAAU,eACR,SAAQ,qBAAqB,CAAC,OAAO,eAAe,CAAC,KAAK,EAAE,YAAY,CAAC;CAAG;AAC9E,yFAAyF;AACzF,QAAA,MAAM,KAAK,2FAMV,CAAC;AAGF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAC7D,YAAY,EACV,cAAc,IAAI,SAAS,EAC3B,iBAAiB,IAAI,YAAY,EACjC,iBAAiB,IAAI,YAAY,EACjC,eAAe,IAAI,UAAU,EAC7B,qBAAqB,IAAI,gBAAgB,EACzC,eAAe,IAAI,UAAU,GAC9B,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import*as e from"react";import
|
|
1
|
+
"use client";import*as e from"react";import z from"classnames";import{Dialog as n}from"radix-ui";import{dialogContentPropDefs as A}from"./dialog.props.js";import{Theme as V}from"./theme.js";import{Heading as _}from"./heading.js";import{Text as K}from"./text.js";import{extractProps as u}from"../helpers/extract-props.js";import{requireReactElement as y}from"../helpers/require-react-element.js";import{useBodyPointerEventsCleanup as q}from"../hooks/use-body-pointer-events-cleanup.js";const D=o=>e.createElement(n.Root,{...o,modal:!0});D.displayName="Sheet.Root";const S=e.forwardRef(({children:o,...t},r)=>e.createElement(n.Trigger,{...t,ref:r,asChild:!0},y(o)));S.displayName="Sheet.Trigger";const C=e.forwardRef((o,t)=>{const{side:r="start",forceMount:a,container:R,className:b,panelBackground:x,material:N,...k}=o,M={left:"start",right:"end",start:"start",end:"end",top:"top",bottom:"bottom"}[r],{align:F,panelBackground:w,material:B,...d}=A,{panelBackground:m,material:f}=u({panelBackground:x,material:N},{panelBackground:w,material:B}),h=e.useMemo(()=>f??m,[f,m]),{default:U,...W}=d.maxWidth,O={...d,maxWidth:W},{className:H,...L}=u(k,O),g=e.useRef(null),j=e.useMemo(()=>i=>{g.current=i,typeof t=="function"?t(i):t&&(t.current=i)},[t]);return q(),e.useEffect(()=>{if(typeof window>"u")return;const i=g.current;if(!i)return;const s=i.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(s.length===0)return;const l=s[0],c=s[s.length-1],P=p=>{p.key==="Tab"&&(p.shiftKey?document.activeElement===l&&(p.preventDefault(),c.focus()):document.activeElement===c&&(p.preventDefault(),l.focus()))};return i.addEventListener("keydown",P),l.focus(),()=>{i.removeEventListener("keydown",P)}},[]),e.createElement(n.Portal,{container:R,forceMount:a},e.createElement(V,{asChild:!0},e.createElement(n.Overlay,{className:"rt-BaseDialogOverlay rt-DialogOverlay rt-SheetOverlay"},e.createElement(n.Content,{...L,ref:j,className:z("rt-BaseDialogContent","rt-SheetContent",b,H),"data-side":M,"data-material":h,"data-panel-background":h,tabIndex:-1,role:"dialog","aria-modal":"true"}))))});C.displayName="Sheet.Content";const v=e.forwardRef(({size:o="4",weight:t="medium",...r},a)=>e.createElement(n.Title,{asChild:!0},e.createElement(_,{ref:a,size:o,weight:t,...r})));v.displayName="Sheet.Title";const T=e.forwardRef(({size:o="2",color:t="gray",...r},a)=>e.createElement(n.Description,{asChild:!0},e.createElement(K,{ref:a,size:o,color:t,...r})));T.displayName="Sheet.Description";const E=e.forwardRef(({children:o,...t},r)=>e.createElement(n.Close,{...t,ref:r,asChild:!0},y(o)));E.displayName="Sheet.Close";export{E as Close,C as Content,T as Description,D as Root,v as Title,S as Trigger};
|
|
2
2
|
//# sourceMappingURL=sheet.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/sheet.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client';\n\n/**\n * Sheet\n *\n * A side-placed overlay built on top of Radix Dialog. It inherits accessibility,\n * focus management, overlay behavior, and sizing scales from the base dialog, and\n * adds side placement and slide motion suited for navigation panels and drawers.\n *\n * Structure mirrors Dialog:\n * - Root, Trigger, Content, Title, Description, Close\n *\n * Notes\n * - Side: set with `side` on `Sheet.Content`. Aliases: `left` \u2192 `start`, `right` \u2192 `end`.\n * - Sizing: reuses Dialog content prop defs (width/min/max/height/size). Default Dialog\n * maxWidth clamping is removed for Sheets.\n * - Material: use `material` (solid | translucent). Deprecated `panelBackground` falls back\n * in dev with a warning.\n * - A11y: provide an accessible name via `Sheet.Title` or `aria-label` on `Sheet.Content`.\n *\n * Example\n * <Sheet.Root>\n * <Sheet.Trigger>\n * <Button>Open</Button>\n * </Sheet.Trigger>\n * <Sheet.Content side=\"end\" width={{ initial: '280px', md: '360px' }}>\n * <Sheet.Title>Details</Sheet.Title>\n * ...\n * <Sheet.Close>\n * <Button>Close</Button>\n * </Sheet.Close>\n * </Sheet.Content>\n * </Sheet.Root>\n */\n\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\n\nimport { dialogContentPropDefs } from './dialog.props.js';\nimport type { DialogContentOwnProps } from './dialog.props.js';\nimport { Theme } from './theme.js';\nimport { extractProps } from '../helpers/extract-props.js';\nimport { requireReactElement } from '../helpers/require-react-element.js';\nimport { useBodyPointerEventsCleanup } from '../hooks/use-body-pointer-events-cleanup.js';\n\nimport type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';\n\n/**\n * Supported sides for the Sheet.\n * Aliases are normalized RTL-aware: `left` \u2192 `start`, `right` \u2192 `end`.\n */\ntype SheetSide = 'start' | 'end' | 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * Sheet is a side-placed overlay built on the Dialog primitive.\n * It reuses Dialog's accessibility, focus, overlay, and size scales, while adding side placement and slide motion.\n */\n\n// Root\n/**\n * Props for `Sheet.Root` (Radix Dialog root with `modal` forced on).\n */\ninterface SheetRootProps extends ComponentPropsWithout<typeof DialogPrimitive.Root, 'modal'> {}\nconst Root: React.FC<SheetRootProps> = (props) => <DialogPrimitive.Root {...props} modal />;\nRoot.displayName = 'Sheet.Root';\n\n// Trigger\n/** Element type for `Sheet.Trigger`. */\ntype SheetTriggerElement = React.ElementRef<typeof DialogPrimitive.Trigger>;\n/** Props for `Sheet.Trigger` (expects a single element child). */\ninterface SheetTriggerProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Trigger, RemovedProps> {}\nconst Trigger = React.forwardRef<SheetTriggerElement, SheetTriggerProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Trigger {...props} ref={ref} asChild>\n {requireReactElement(children)}\n </DialogPrimitive.Trigger>\n ),\n);\nTrigger.displayName = 'Sheet.Trigger';\n\n// Content\n/** Element type for `Sheet.Content`. */\ntype SheetContentElement = React.ElementRef<typeof DialogPrimitive.Content>;\ninterface SheetContentProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Content, RemovedProps>,\n DialogContentOwnProps {\n /** Side where the Sheet should appear. `left`/`right` alias to `start`/`end`. */\n side?: SheetSide;\n /** Optional DOM container to portal into. Defaults to `document.body`. */\n container?: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Portal>['container'];\n}\n\n/**\n * Renders the Sheet panel. Normalizes left/right to logical start/end and\n * forwards dialog sizing props. Provide an accessible name via `Sheet.Title`\n * or `aria-label`.\n */\nconst Content = React.forwardRef<SheetContentElement, SheetContentProps>(\n (allProps, forwardedRef) => {\n const {\n side = 'start',\n forceMount,\n container,\n className,\n panelBackground: panelBackgroundProp,\n material: materialProp,\n ...restProps\n } = allProps;\n const normalizedSideMap: Record<SheetSide, 'start' | 'end' | 'top' | 'bottom'> = {\n left: 'start',\n right: 'end',\n start: 'start',\n end: 'end',\n top: 'top',\n bottom: 'bottom',\n };\n const normalizedSide = normalizedSideMap[side];\n // Reuse dialog content prop defs for size/width/height tokens, but handle\n // material/panelBackground explicitly to avoid forwarding unknown DOM props.\n const {\n align: _alignPropDef,\n panelBackground: panelBackgroundPropDef,\n material: materialPropDef,\n ...propDefs\n } = dialogContentPropDefs;\n\n // Extract panelBackground and material together (remove from DOM props)\n const { panelBackground: resolvedPanelBackground, material: resolvedMaterial } = extractProps(\n { panelBackground: panelBackgroundProp, material: materialProp },\n { panelBackground: panelBackgroundPropDef, material: materialPropDef },\n );\n\n const materialValue = React.useMemo(() => {\n if (resolvedPanelBackground !== undefined) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning: The `panelBackground` prop is deprecated and will be removed in a future version. Use the `material` prop instead.',\n );\n }\n }\n return resolvedMaterial ?? resolvedPanelBackground;\n }, [resolvedMaterial, resolvedPanelBackground]);\n\n // Now extract remaining props using dialog defs so size/width/height classnames are applied\n // Override dialog's default maxWidth (600px) to avoid clamping Sheet by default\n // Match dialog.tsx: extract once and avoid leaking panel/material\n const { default: _mwDefault, ...maxWidthWithoutDefault } = propDefs.maxWidth;\n const sheetPropDefs = {\n ...propDefs,\n maxWidth: maxWidthWithoutDefault,\n } as typeof propDefs;\n const { className: extractedClassName, ...contentProps } = extractProps(\n restProps,\n sheetPropDefs,\n );\n\n // Dev-only a11y guard: ensure label is provided via Title or aria-label\n if (process.env.NODE_ENV !== 'production') {\n const children = (contentProps as any).children as React.ReactNode;\n const hasAriaLabel = typeof (contentProps as any)['aria-label'] === 'string';\n let hasTitle = false;\n if (children) {\n for (const child of React.Children.toArray(children)) {\n if (React.isValidElement(child) && child.type === Title) {\n hasTitle = true;\n break;\n }\n }\n }\n if (!hasTitle && !hasAriaLabel) {\n console.warn(\n 'Sheet.Content: Missing accessible name. Include Sheet.Title as a child or provide aria-label.',\n );\n }\n }\n\n // Focus management and stuck pointer-events cleanup like Dialog\n const contentRef = React.useRef<HTMLDivElement>(null);\n const combinedRef = React.useMemo(\n () => (node: HTMLDivElement | null) => {\n contentRef.current = node;\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else if (forwardedRef) {\n (forwardedRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n },\n [forwardedRef],\n );\n\n useBodyPointerEventsCleanup();\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return;\n const content = contentRef.current;\n if (!content) return;\n\n const focusableElements = content.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0] as HTMLElement;\n const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n content.addEventListener('keydown', handleKeyDown);\n firstElement.focus();\n\n return () => {\n content.removeEventListener('keydown', handleKeyDown);\n };\n }, []);\n\n return (\n <DialogPrimitive.Portal container={container} forceMount={forceMount}>\n <Theme asChild>\n <DialogPrimitive.Overlay className=\"rt-BaseDialogOverlay rt-DialogOverlay rt-SheetOverlay\">\n <DialogPrimitive.Content\n {...contentProps}\n ref={combinedRef}\n className={classNames(\n 'rt-BaseDialogContent',\n 'rt-SheetContent',\n className,\n extractedClassName,\n )}\n data-side={normalizedSide}\n data-material={materialValue}\n data-panel-background={materialValue}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n />\n </DialogPrimitive.Overlay>\n </Theme>\n </DialogPrimitive.Portal>\n );\n },\n);\nContent.displayName = 'Sheet.Content';\n\n// Title/Description/Close re-export\ntype SheetTitleElement = React.ElementRef<typeof DialogPrimitive.Title>;\ninterface SheetTitleProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title> {}\n/** Accessible title for the Sheet. Required for non-decorative content. */\nconst Title = React.forwardRef<SheetTitleElement, SheetTitleProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Title {...props} ref={ref} asChild={false}>\n {children}\n </DialogPrimitive.Title>\n ),\n);\nTitle.displayName = 'Sheet.Title';\n\ntype SheetDescriptionElement = React.ElementRef<typeof DialogPrimitive.Description>;\ninterface SheetDescriptionProps\n extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description> {}\n/** Supplementary description text for Sheet content. */\nconst Description = React.forwardRef<SheetDescriptionElement, SheetDescriptionProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Description {...props} ref={ref} asChild={false}>\n {children}\n </DialogPrimitive.Description>\n ),\n);\nDescription.displayName = 'Sheet.Description';\n\ntype SheetCloseElement = React.ElementRef<typeof DialogPrimitive.Close>;\ninterface SheetCloseProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Close, RemovedProps> {}\n/** Close button for the Sheet. Expects a single element child rendered via `asChild`. */\nconst Close = React.forwardRef<SheetCloseElement, SheetCloseProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Close {...props} ref={ref} asChild>\n {requireReactElement(children)}\n </DialogPrimitive.Close>\n ),\n);\nClose.displayName = 'Sheet.Close';\n\nexport { Root, Trigger, Content, Title, Description, Close };\nexport type {\n SheetRootProps as RootProps,\n SheetTriggerProps as TriggerProps,\n SheetContentProps as ContentProps,\n SheetTitleProps as TitleProps,\n SheetDescriptionProps as DescriptionProps,\n SheetCloseProps as CloseProps,\n};\n"],
|
|
5
|
-
"mappings": "aAmCA,UAAYA,MAAW,QACvB,OAAOC,MAAgB,aACvB,OAAS,UAAUC,MAAuB,WAE1C,OAAS,yBAAAC,MAA6B,oBAEtC,OAAS,SAAAC,MAAa,aACtB,OAAS,gBAAAC,MAAoB,8BAC7B,OAAS,uBAAAC,MAA2B,sCACpC,OAAS,+BAAAC,MAAmC,
|
|
6
|
-
"names": ["React", "classNames", "DialogPrimitive", "dialogContentPropDefs", "Theme", "extractProps", "requireReactElement", "useBodyPointerEventsCleanup", "Root", "props", "Trigger", "children", "ref", "Content", "allProps", "forwardedRef", "side", "forceMount", "container", "className", "panelBackgroundProp", "materialProp", "restProps", "normalizedSide", "_alignPropDef", "panelBackgroundPropDef", "materialPropDef", "propDefs", "resolvedPanelBackground", "resolvedMaterial", "materialValue", "_mwDefault", "maxWidthWithoutDefault", "sheetPropDefs", "extractedClassName", "contentProps", "contentRef", "combinedRef", "node", "content", "focusableElements", "firstElement", "lastElement", "handleKeyDown", "event", "Title", "Description", "Close"]
|
|
4
|
+
"sourcesContent": ["'use client';\n\n/**\n * Sheet\n *\n * A side-placed overlay built on top of Radix Dialog. It inherits accessibility,\n * focus management, overlay behavior, and sizing scales from the base dialog, and\n * adds side placement and slide motion suited for navigation panels and drawers.\n *\n * Structure mirrors Dialog:\n * - Root, Trigger, Content, Title, Description, Close\n *\n * Notes\n * - Side: set with `side` on `Sheet.Content`. Aliases: `left` \u2192 `start`, `right` \u2192 `end`.\n * - Sizing: reuses Dialog content prop defs (width/min/max/height/size). Default Dialog\n * maxWidth clamping is removed for Sheets.\n * - Material: use `material` (solid | translucent). Deprecated `panelBackground` falls back\n * in dev with a warning.\n * - A11y: provide an accessible name via `Sheet.Title` or `aria-label` on `Sheet.Content`.\n *\n * Example\n * <Sheet.Root>\n * <Sheet.Trigger>\n * <Button>Open</Button>\n * </Sheet.Trigger>\n * <Sheet.Content side=\"end\" width={{ initial: '280px', md: '360px' }}>\n * <Sheet.Title>Details</Sheet.Title>\n * ...\n * <Sheet.Close>\n * <Button>Close</Button>\n * </Sheet.Close>\n * </Sheet.Content>\n * </Sheet.Root>\n */\n\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\n\nimport { dialogContentPropDefs } from './dialog.props.js';\nimport type { DialogContentOwnProps } from './dialog.props.js';\nimport { Theme } from './theme.js';\nimport { Heading } from './heading.js';\nimport { Text } from './text.js';\nimport { extractProps } from '../helpers/extract-props.js';\nimport { requireReactElement } from '../helpers/require-react-element.js';\nimport { useBodyPointerEventsCleanup } from '../hooks/use-body-pointer-events-cleanup.js';\n\nimport type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';\nimport type { HeadingProps } from './heading.js';\nimport type { TextProps } from './text.js';\n\n/**\n * Supported sides for the Sheet.\n * Aliases are normalized RTL-aware: `left` \u2192 `start`, `right` \u2192 `end`.\n */\ntype SheetSide = 'start' | 'end' | 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * Sheet is a side-placed overlay built on the Dialog primitive.\n * It reuses Dialog's accessibility, focus, overlay, and size scales, while adding side placement and slide motion.\n */\n\n// Root\n/**\n * Props for `Sheet.Root` (Radix Dialog root with `modal` forced on).\n */\ninterface SheetRootProps extends ComponentPropsWithout<typeof DialogPrimitive.Root, 'modal'> {}\nconst Root: React.FC<SheetRootProps> = (props) => <DialogPrimitive.Root {...props} modal />;\nRoot.displayName = 'Sheet.Root';\n\n// Trigger\n/** Element type for `Sheet.Trigger`. */\ntype SheetTriggerElement = React.ElementRef<typeof DialogPrimitive.Trigger>;\n/** Props for `Sheet.Trigger` (expects a single element child). */\ninterface SheetTriggerProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Trigger, RemovedProps> {}\nconst Trigger = React.forwardRef<SheetTriggerElement, SheetTriggerProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Trigger {...props} ref={ref} asChild>\n {requireReactElement(children)}\n </DialogPrimitive.Trigger>\n ),\n);\nTrigger.displayName = 'Sheet.Trigger';\n\n// Content\n/** Element type for `Sheet.Content`. */\ntype SheetContentElement = React.ElementRef<typeof DialogPrimitive.Content>;\ninterface SheetContentProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Content, RemovedProps>,\n DialogContentOwnProps {\n /** Side where the Sheet should appear. `left`/`right` alias to `start`/`end`. */\n side?: SheetSide;\n /** Optional DOM container to portal into. Defaults to `document.body`. */\n container?: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Portal>['container'];\n}\n\n/**\n * Renders the Sheet panel. Normalizes left/right to logical start/end and\n * forwards dialog sizing props. Provide an accessible name via `Sheet.Title`\n * or `aria-label`.\n */\nconst Content = React.forwardRef<SheetContentElement, SheetContentProps>(\n (allProps, forwardedRef) => {\n const {\n side = 'start',\n forceMount,\n container,\n className,\n panelBackground: panelBackgroundProp,\n material: materialProp,\n ...restProps\n } = allProps;\n const normalizedSideMap: Record<SheetSide, 'start' | 'end' | 'top' | 'bottom'> = {\n left: 'start',\n right: 'end',\n start: 'start',\n end: 'end',\n top: 'top',\n bottom: 'bottom',\n };\n const normalizedSide = normalizedSideMap[side];\n // Reuse dialog content prop defs for size/width/height tokens, but handle\n // material/panelBackground explicitly to avoid forwarding unknown DOM props.\n const {\n align: _alignPropDef,\n panelBackground: panelBackgroundPropDef,\n material: materialPropDef,\n ...propDefs\n } = dialogContentPropDefs;\n\n // Extract panelBackground and material together (remove from DOM props)\n const { panelBackground: resolvedPanelBackground, material: resolvedMaterial } = extractProps(\n { panelBackground: panelBackgroundProp, material: materialProp },\n { panelBackground: panelBackgroundPropDef, material: materialPropDef },\n );\n\n const materialValue = React.useMemo(() => {\n if (resolvedPanelBackground !== undefined) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning: The `panelBackground` prop is deprecated and will be removed in a future version. Use the `material` prop instead.',\n );\n }\n }\n return resolvedMaterial ?? resolvedPanelBackground;\n }, [resolvedMaterial, resolvedPanelBackground]);\n\n // Now extract remaining props using dialog defs so size/width/height classnames are applied\n // Override dialog's default maxWidth (600px) to avoid clamping Sheet by default\n // Match dialog.tsx: extract once and avoid leaking panel/material\n const { default: _mwDefault, ...maxWidthWithoutDefault } = propDefs.maxWidth;\n const sheetPropDefs = {\n ...propDefs,\n maxWidth: maxWidthWithoutDefault,\n } as typeof propDefs;\n const { className: extractedClassName, ...contentProps } = extractProps(\n restProps,\n sheetPropDefs,\n );\n\n // Dev-only a11y guard: ensure label is provided via Title or aria-label\n if (process.env.NODE_ENV !== 'production') {\n const children = (contentProps as any).children as React.ReactNode;\n const hasAriaLabel = typeof (contentProps as any)['aria-label'] === 'string';\n let hasTitle = false;\n if (children) {\n for (const child of React.Children.toArray(children)) {\n if (React.isValidElement(child) && child.type === Title) {\n hasTitle = true;\n break;\n }\n }\n }\n if (!hasTitle && !hasAriaLabel) {\n console.warn(\n 'Sheet.Content: Missing accessible name. Include Sheet.Title as a child or provide aria-label.',\n );\n }\n }\n\n // Focus management and stuck pointer-events cleanup like Dialog\n const contentRef = React.useRef<HTMLDivElement>(null);\n const combinedRef = React.useMemo(\n () => (node: HTMLDivElement | null) => {\n contentRef.current = node;\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else if (forwardedRef) {\n (forwardedRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n },\n [forwardedRef],\n );\n\n useBodyPointerEventsCleanup();\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return;\n const content = contentRef.current;\n if (!content) return;\n\n const focusableElements = content.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0] as HTMLElement;\n const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n content.addEventListener('keydown', handleKeyDown);\n firstElement.focus();\n\n return () => {\n content.removeEventListener('keydown', handleKeyDown);\n };\n }, []);\n\n return (\n <DialogPrimitive.Portal container={container} forceMount={forceMount}>\n <Theme asChild>\n <DialogPrimitive.Overlay className=\"rt-BaseDialogOverlay rt-DialogOverlay rt-SheetOverlay\">\n <DialogPrimitive.Content\n {...contentProps}\n ref={combinedRef}\n className={classNames(\n 'rt-BaseDialogContent',\n 'rt-SheetContent',\n className,\n extractedClassName,\n )}\n data-side={normalizedSide}\n data-material={materialValue}\n data-panel-background={materialValue}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n />\n </DialogPrimitive.Overlay>\n </Theme>\n </DialogPrimitive.Portal>\n );\n },\n);\nContent.displayName = 'Sheet.Content';\n\n// Title - renders as Heading with sensible defaults\ntype SheetTitleElement = React.ElementRef<typeof Heading>;\ninterface SheetTitleProps extends HeadingProps {}\n/** Accessible title for the Sheet. Renders as Heading with sensible defaults. */\nconst Title = React.forwardRef<SheetTitleElement, SheetTitleProps>(\n ({ size = '4', weight = 'medium', ...props }, ref) => (\n <DialogPrimitive.Title asChild>\n <Heading ref={ref} size={size} weight={weight} {...props} />\n </DialogPrimitive.Title>\n ),\n);\nTitle.displayName = 'Sheet.Title';\n\n// Description - renders as Text with sensible defaults\ntype SheetDescriptionElement = React.ElementRef<typeof Text>;\ntype SheetDescriptionProps = React.ComponentPropsWithoutRef<typeof Text>;\n/** Supplementary description text for Sheet content. Renders as Text with sensible defaults. */\nconst Description = React.forwardRef<SheetDescriptionElement, SheetDescriptionProps>(\n ({ size = '2', color = 'gray', ...rest }, ref) => (\n <DialogPrimitive.Description asChild>\n <Text ref={ref} size={size} color={color} {...rest} />\n </DialogPrimitive.Description>\n ),\n);\nDescription.displayName = 'Sheet.Description';\n\ntype SheetCloseElement = React.ElementRef<typeof DialogPrimitive.Close>;\ninterface SheetCloseProps\n extends ComponentPropsWithout<typeof DialogPrimitive.Close, RemovedProps> {}\n/** Close button for the Sheet. Expects a single element child rendered via `asChild`. */\nconst Close = React.forwardRef<SheetCloseElement, SheetCloseProps>(\n ({ children, ...props }, ref) => (\n <DialogPrimitive.Close {...props} ref={ref} asChild>\n {requireReactElement(children)}\n </DialogPrimitive.Close>\n ),\n);\nClose.displayName = 'Sheet.Close';\n\nexport { Root, Trigger, Content, Title, Description, Close };\nexport type {\n SheetRootProps as RootProps,\n SheetTriggerProps as TriggerProps,\n SheetContentProps as ContentProps,\n SheetTitleProps as TitleProps,\n SheetDescriptionProps as DescriptionProps,\n SheetCloseProps as CloseProps,\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["React", "classNames", "DialogPrimitive", "dialogContentPropDefs", "Theme", "Heading", "Text", "extractProps", "requireReactElement", "useBodyPointerEventsCleanup", "Root", "props", "Trigger", "children", "ref", "Content", "allProps", "forwardedRef", "side", "forceMount", "container", "className", "panelBackgroundProp", "materialProp", "restProps", "normalizedSide", "_alignPropDef", "panelBackgroundPropDef", "materialPropDef", "propDefs", "resolvedPanelBackground", "resolvedMaterial", "materialValue", "_mwDefault", "maxWidthWithoutDefault", "sheetPropDefs", "extractedClassName", "contentProps", "contentRef", "combinedRef", "node", "content", "focusableElements", "firstElement", "lastElement", "handleKeyDown", "event", "Title", "size", "weight", "Description", "color", "rest", "Close"]
|
|
7
7
|
}
|
package/package.json
CHANGED
package/schemas/base-button.json
CHANGED
|
@@ -279,6 +279,6 @@
|
|
|
279
279
|
"title": "Base-button Component Props",
|
|
280
280
|
"description": "Props schema for the base-button component in Kookie UI",
|
|
281
281
|
"version": "1.0.0",
|
|
282
|
-
"generatedAt": "2026-01-
|
|
282
|
+
"generatedAt": "2026-01-09T16:57:47.906Z",
|
|
283
283
|
"source": "Zod schema"
|
|
284
284
|
}
|
package/schemas/button.json
CHANGED
|
@@ -530,6 +530,6 @@
|
|
|
530
530
|
"title": "Button Component Props",
|
|
531
531
|
"description": "Props schema for the button component in Kookie UI",
|
|
532
532
|
"version": "1.0.0",
|
|
533
|
-
"generatedAt": "2026-01-
|
|
533
|
+
"generatedAt": "2026-01-09T16:57:47.912Z",
|
|
534
534
|
"source": "Zod schema"
|
|
535
535
|
}
|
package/schemas/icon-button.json
CHANGED
|
@@ -313,6 +313,6 @@
|
|
|
313
313
|
"title": "Icon-button Component Props",
|
|
314
314
|
"description": "Props schema for the icon-button component in Kookie UI",
|
|
315
315
|
"version": "1.0.0",
|
|
316
|
-
"generatedAt": "2026-01-
|
|
316
|
+
"generatedAt": "2026-01-09T16:57:47.913Z",
|
|
317
317
|
"source": "Zod schema"
|
|
318
318
|
}
|
package/schemas/index.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"title": "Kookie UI Button Components",
|
|
4
4
|
"description": "Complete JSON Schema collection for all button components in Kookie UI",
|
|
5
5
|
"version": "1.0.0",
|
|
6
|
-
"generatedAt": "2026-01-
|
|
6
|
+
"generatedAt": "2026-01-09T16:57:47.916Z",
|
|
7
7
|
"source": "Zod schemas",
|
|
8
8
|
"components": {
|
|
9
9
|
"base-button": {
|
|
@@ -287,7 +287,7 @@
|
|
|
287
287
|
"title": "Base-button Component Props",
|
|
288
288
|
"description": "Props schema for the base-button component in Kookie UI",
|
|
289
289
|
"version": "1.0.0",
|
|
290
|
-
"generatedAt": "2026-01-
|
|
290
|
+
"generatedAt": "2026-01-09T16:57:47.906Z",
|
|
291
291
|
"source": "Zod schema"
|
|
292
292
|
},
|
|
293
293
|
"button": {
|
|
@@ -822,7 +822,7 @@
|
|
|
822
822
|
"title": "Button Component Props",
|
|
823
823
|
"description": "Props schema for the button component in Kookie UI",
|
|
824
824
|
"version": "1.0.0",
|
|
825
|
-
"generatedAt": "2026-01-
|
|
825
|
+
"generatedAt": "2026-01-09T16:57:47.912Z",
|
|
826
826
|
"source": "Zod schema"
|
|
827
827
|
},
|
|
828
828
|
"icon-button": {
|
|
@@ -1140,7 +1140,7 @@
|
|
|
1140
1140
|
"title": "Icon-button Component Props",
|
|
1141
1141
|
"description": "Props schema for the icon-button component in Kookie UI",
|
|
1142
1142
|
"version": "1.0.0",
|
|
1143
|
-
"generatedAt": "2026-01-
|
|
1143
|
+
"generatedAt": "2026-01-09T16:57:47.913Z",
|
|
1144
1144
|
"source": "Zod schema"
|
|
1145
1145
|
},
|
|
1146
1146
|
"toggle-button": {
|
|
@@ -1683,7 +1683,7 @@
|
|
|
1683
1683
|
"title": "Toggle-button Component Props",
|
|
1684
1684
|
"description": "Props schema for the toggle-button component in Kookie UI",
|
|
1685
1685
|
"version": "1.0.0",
|
|
1686
|
-
"generatedAt": "2026-01-
|
|
1686
|
+
"generatedAt": "2026-01-09T16:57:47.915Z",
|
|
1687
1687
|
"source": "Zod schema"
|
|
1688
1688
|
},
|
|
1689
1689
|
"toggle-icon-button": {
|
|
@@ -2009,7 +2009,7 @@
|
|
|
2009
2009
|
"title": "Toggle-icon-button Component Props",
|
|
2010
2010
|
"description": "Props schema for the toggle-icon-button component in Kookie UI",
|
|
2011
2011
|
"version": "1.0.0",
|
|
2012
|
-
"generatedAt": "2026-01-
|
|
2012
|
+
"generatedAt": "2026-01-09T16:57:47.916Z",
|
|
2013
2013
|
"source": "Zod schema"
|
|
2014
2014
|
}
|
|
2015
2015
|
}
|
|
@@ -538,6 +538,6 @@
|
|
|
538
538
|
"title": "Toggle-button Component Props",
|
|
539
539
|
"description": "Props schema for the toggle-button component in Kookie UI",
|
|
540
540
|
"version": "1.0.0",
|
|
541
|
-
"generatedAt": "2026-01-
|
|
541
|
+
"generatedAt": "2026-01-09T16:57:47.915Z",
|
|
542
542
|
"source": "Zod schema"
|
|
543
543
|
}
|
|
@@ -321,6 +321,6 @@
|
|
|
321
321
|
"title": "Toggle-icon-button Component Props",
|
|
322
322
|
"description": "Props schema for the toggle-icon-button component in Kookie UI",
|
|
323
323
|
"version": "1.0.0",
|
|
324
|
-
"generatedAt": "2026-01-
|
|
324
|
+
"generatedAt": "2026-01-09T16:57:47.916Z",
|
|
325
325
|
"source": "Zod schema"
|
|
326
326
|
}
|
package/src/components/sheet.tsx
CHANGED
|
@@ -40,11 +40,15 @@ import { Dialog as DialogPrimitive } from 'radix-ui';
|
|
|
40
40
|
import { dialogContentPropDefs } from './dialog.props.js';
|
|
41
41
|
import type { DialogContentOwnProps } from './dialog.props.js';
|
|
42
42
|
import { Theme } from './theme.js';
|
|
43
|
+
import { Heading } from './heading.js';
|
|
44
|
+
import { Text } from './text.js';
|
|
43
45
|
import { extractProps } from '../helpers/extract-props.js';
|
|
44
46
|
import { requireReactElement } from '../helpers/require-react-element.js';
|
|
45
47
|
import { useBodyPointerEventsCleanup } from '../hooks/use-body-pointer-events-cleanup.js';
|
|
46
48
|
|
|
47
49
|
import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';
|
|
50
|
+
import type { HeadingProps } from './heading.js';
|
|
51
|
+
import type { TextProps } from './text.js';
|
|
48
52
|
|
|
49
53
|
/**
|
|
50
54
|
* Supported sides for the Sheet.
|
|
@@ -256,27 +260,27 @@ const Content = React.forwardRef<SheetContentElement, SheetContentProps>(
|
|
|
256
260
|
);
|
|
257
261
|
Content.displayName = 'Sheet.Content';
|
|
258
262
|
|
|
259
|
-
// Title
|
|
260
|
-
type SheetTitleElement = React.ElementRef<typeof
|
|
261
|
-
interface SheetTitleProps extends
|
|
262
|
-
/** Accessible title for the Sheet.
|
|
263
|
+
// Title - renders as Heading with sensible defaults
|
|
264
|
+
type SheetTitleElement = React.ElementRef<typeof Heading>;
|
|
265
|
+
interface SheetTitleProps extends HeadingProps {}
|
|
266
|
+
/** Accessible title for the Sheet. Renders as Heading with sensible defaults. */
|
|
263
267
|
const Title = React.forwardRef<SheetTitleElement, SheetTitleProps>(
|
|
264
|
-
({
|
|
265
|
-
<DialogPrimitive.Title
|
|
266
|
-
{
|
|
268
|
+
({ size = '4', weight = 'medium', ...props }, ref) => (
|
|
269
|
+
<DialogPrimitive.Title asChild>
|
|
270
|
+
<Heading ref={ref} size={size} weight={weight} {...props} />
|
|
267
271
|
</DialogPrimitive.Title>
|
|
268
272
|
),
|
|
269
273
|
);
|
|
270
274
|
Title.displayName = 'Sheet.Title';
|
|
271
275
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
/** Supplementary description text for Sheet content. */
|
|
276
|
+
// Description - renders as Text with sensible defaults
|
|
277
|
+
type SheetDescriptionElement = React.ElementRef<typeof Text>;
|
|
278
|
+
type SheetDescriptionProps = React.ComponentPropsWithoutRef<typeof Text>;
|
|
279
|
+
/** Supplementary description text for Sheet content. Renders as Text with sensible defaults. */
|
|
276
280
|
const Description = React.forwardRef<SheetDescriptionElement, SheetDescriptionProps>(
|
|
277
|
-
({
|
|
278
|
-
<DialogPrimitive.Description
|
|
279
|
-
{
|
|
281
|
+
({ size = '2', color = 'gray', ...rest }, ref) => (
|
|
282
|
+
<DialogPrimitive.Description asChild>
|
|
283
|
+
<Text ref={ref} size={size} color={color} {...rest} />
|
|
280
284
|
</DialogPrimitive.Description>
|
|
281
285
|
),
|
|
282
286
|
);
|