@sproutsocial/seeds-react-drawer 2.2.8 → 2.2.10

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/drawer.css CHANGED
@@ -245,4 +245,40 @@
245
245
  .seeds-drawer-popup[data-nested-drawer-open][data-nested-drawer-swiping] > * {
246
246
  opacity: 1;
247
247
  }
248
+
249
+ /* Header ------------------------------------------------------------------ */
250
+
251
+ /* Port of the styled-components Box header (DrawerShared.tsx): flex row with
252
+ the title and close button, fixed at the top of the popup. */
253
+ .seeds-drawer-header {
254
+ display: flex;
255
+ flex: 0 0 auto;
256
+ justify-content: space-between;
257
+ align-items: center;
258
+ padding-top: var(--space-400);
259
+ padding-left: var(--space-450);
260
+ padding-right: var(--space-450);
261
+ }
262
+
263
+ /* Default title typography. `margin: 0` neutralises the user-agent <h2>
264
+ margin that the styled path's <Text> reset for us, avoiding a layout shift
265
+ between the Tailwind and styled headers. */
266
+ .seeds-drawer-header-title {
267
+ margin: 0;
268
+ font-size: var(--font-size-400);
269
+ line-height: var(--line-height-400);
270
+ font-weight: var(--font-weight-semibold);
271
+ color: var(--color-text-headline);
272
+ }
273
+
274
+ /* Content ----------------------------------------------------------------- */
275
+
276
+ /* Port of the styled-components Content (styles.ts) plus the styled-system
277
+ props it was rendered with (height/padding/color). */
278
+ .seeds-drawer-content {
279
+ height: 100%;
280
+ padding: var(--space-450);
281
+ overflow-y: auto;
282
+ color: var(--color-text-body);
283
+ }
248
284
  }
package/dist/esm/index.js CHANGED
@@ -291,6 +291,7 @@ import Icon from "@sproutsocial/seeds-react-icon";
291
291
  import Text from "@sproutsocial/seeds-react-text";
292
292
  import { useIsMobile } from "@sproutsocial/seeds-react-hooks";
293
293
  import { DisablePortalToBodyContext } from "@sproutsocial/seeds-react-portal";
294
+ import { needsStyledComponents } from "@sproutsocial/seeds-react-system-props";
294
295
  import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
295
296
  var DrawerContext = React3.createContext({
296
297
  isLocked: false,
@@ -298,6 +299,22 @@ var DrawerContext = React3.createContext({
298
299
  },
299
300
  hasActionRail: false
300
301
  });
302
+ function cn(...inputs) {
303
+ const classes = [];
304
+ for (const input of inputs) {
305
+ if (!input) continue;
306
+ if (typeof input === "string") {
307
+ classes.push(input);
308
+ } else if (typeof input === "object") {
309
+ for (const [key, value] of Object.entries(input)) {
310
+ if (value) {
311
+ classes.push(key);
312
+ }
313
+ }
314
+ }
315
+ }
316
+ return classes.join(" ");
317
+ }
301
318
  var DrawerCloseButton = (props) => {
302
319
  const drawerContext = useContext(DrawerContext);
303
320
  if (props.render) {
@@ -314,7 +331,7 @@ var DrawerCloseButton = (props) => {
314
331
  }
315
332
  );
316
333
  };
317
- var DrawerHeader = ({
334
+ var DrawerHeaderStyled = ({
318
335
  title = "",
319
336
  id = void 0,
320
337
  children,
@@ -352,7 +369,32 @@ var DrawerHeader = ({
352
369
  }
353
370
  );
354
371
  };
355
- var DrawerContent = ({
372
+ var DrawerHeaderTailwind = ({
373
+ title = "",
374
+ id = void 0,
375
+ children,
376
+ render,
377
+ ...rest
378
+ }) => {
379
+ const drawerContext = useContext(DrawerContext);
380
+ const { className, ...domRest } = rest;
381
+ return /* @__PURE__ */ jsx3("div", { className: cn("seeds-drawer-header", className), ...domRest, children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
382
+ /* @__PURE__ */ jsx3("h2", { className: "seeds-drawer-header-title", id, children: title }),
383
+ !drawerContext.hasActionRail && /* @__PURE__ */ jsx3(DrawerCloseButton, {})
384
+ ] }) });
385
+ };
386
+ var DrawerHeader = (props) => {
387
+ const drawerContext = useContext(DrawerContext);
388
+ if (props.render) {
389
+ return props.render(drawerContext);
390
+ }
391
+ const { title, id, children, render, ...rest } = props;
392
+ if (needsStyledComponents(rest)) {
393
+ return /* @__PURE__ */ jsx3(DrawerHeaderStyled, { ...props });
394
+ }
395
+ return /* @__PURE__ */ jsx3(DrawerHeaderTailwind, { ...props });
396
+ };
397
+ var DrawerContentStyled = ({
356
398
  children,
357
399
  ...rest
358
400
  }) => /* @__PURE__ */ jsx3(
@@ -366,6 +408,28 @@ var DrawerContent = ({
366
408
  children
367
409
  }
368
410
  );
411
+ var DrawerContentTailwind = ({
412
+ children,
413
+ ...rest
414
+ }) => {
415
+ const { className, ...domRest } = rest;
416
+ return /* @__PURE__ */ jsx3(
417
+ "div",
418
+ {
419
+ className: cn("seeds-drawer-content", className),
420
+ "data-drawer-content": "",
421
+ ...domRest,
422
+ children
423
+ }
424
+ );
425
+ };
426
+ var DrawerContent = (props) => {
427
+ const { children, ...rest } = props;
428
+ if (needsStyledComponents(rest)) {
429
+ return /* @__PURE__ */ jsx3(DrawerContentStyled, { ...props });
430
+ }
431
+ return /* @__PURE__ */ jsx3(DrawerContentTailwind, { ...props });
432
+ };
369
433
  DrawerHeader.displayName = "Drawer.Header";
370
434
  DrawerContent.displayName = "Drawer.Content";
371
435
  DrawerCloseButton.displayName = "Drawer.CloseButton";
@@ -545,7 +609,7 @@ var DrawerStyled_default = DrawerStyled;
545
609
  // src/DrawerTailwind.tsx
546
610
  import { Drawer as BaseDrawer3 } from "@base-ui/react/drawer";
547
611
  import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
548
- function cn(...inputs) {
612
+ function cn2(...inputs) {
549
613
  const classes = [];
550
614
  for (const input of inputs) {
551
615
  if (!input) continue;
@@ -587,7 +651,7 @@ var DrawerTailwind = (props) => {
587
651
  /* @__PURE__ */ jsx5(
588
652
  BaseDrawer3.Viewport,
589
653
  {
590
- className: cn("seeds-drawer-viewport", {
654
+ className: cn2("seeds-drawer-viewport", {
591
655
  "seeds-drawer-viewport--snap": hasSnapPoints
592
656
  }),
593
657
  children: /* @__PURE__ */ jsxs3(
@@ -597,7 +661,7 @@ var DrawerTailwind = (props) => {
597
661
  "data-qa-drawer": id,
598
662
  "data-qa-drawer-isopen": open,
599
663
  ...domRest,
600
- className: cn(
664
+ className: cn2(
601
665
  "seeds-drawer-popup",
602
666
  effectiveDirection === "bottom" ? "seeds-drawer-popup--bottom" : "seeds-drawer-popup--side",
603
667
  effectiveDirection === "right" && "seeds-drawer-popup--right",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/DrawerHybrid.tsx","../../src/DrawerStyled.tsx","../../src/styles.ts","../../src/ActionRail/ActionRail.tsx","../../src/ActionRail/ActionRailButton.tsx","../../src/DrawerShared.tsx","../../src/DrawerTailwind.tsx","../../src/Drawer.tsx","../../src/DrawerTypes.ts","../../src/index.ts"],"sourcesContent":["/**\n * Hybrid Drawer component.\n * Automatically chooses between the Tailwind shell (preferred) and the\n * styled-components shell based on props, mirroring `ButtonHybrid`. When a\n * consumer passes styled-system props (`px`, `color`, `height`, …) the styled\n * path is used so existing styling keeps working; otherwise the Tailwind path\n * renders.\n */\nimport { hasStyledProps } from \"@sproutsocial/seeds-react-system-props\";\nimport DrawerStyled from \"./DrawerStyled\";\nimport DrawerTailwind from \"./DrawerTailwind\";\nimport { DrawerHeader, DrawerContent, DrawerCloseButton } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\n\n// Props the Drawer owns semantically. They must be stripped before the\n// `hasStyledProps` check so a Drawer-specific prop never trips the styled\n// router — most importantly `width`, which `hasStyledProps` also treats as a\n// styled-system prop. Anything left in `rest` is a true pass-through/system\n// prop and is what the routing decision is based on.\nconst DRAWER_OWN_PROPS: readonly string[] = [\n \"children\",\n \"closeButtonLabel\",\n \"direction\",\n \"disableCloseOnClickOutside\",\n \"id\",\n \"modal\",\n \"open\",\n \"offset\",\n \"onClose\",\n \"zIndex\",\n \"width\",\n \"snapPoints\",\n \"defaultSnapPoint\",\n \"snapPoint\",\n \"onSnapPointChange\",\n \"snapToSequentialPoints\",\n \"actions\",\n \"actionsInHeader\",\n];\n\nconst DrawerHybrid = (props: TypeDrawerProps) => {\n const rest: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n if (!DRAWER_OWN_PROPS.includes(key)) {\n rest[key] = (props as unknown as Record<string, unknown>)[key];\n }\n }\n\n if (hasStyledProps(rest)) {\n return <DrawerStyled {...props} />;\n }\n\n // Use the Tailwind version (preferred - better performance).\n return <DrawerTailwind {...props} />;\n};\n\nDrawerHybrid.Header = DrawerHeader;\nDrawerHybrid.Content = DrawerContent;\nDrawerHybrid.CloseButton = DrawerCloseButton;\n\nexport default DrawerHybrid;\n","import { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport {\n StyledPopup,\n StyledBackdrop,\n StyledViewport,\n DragHandle,\n} from \"./styles\";\nimport { useDrawerShell, DrawerPopupContents } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\n\n/**\n * Legacy styled-components shell. Routed to by `DrawerHybrid` whenever the\n * consumer passes styled-system props (or a `styled()` extension). Renders the\n * exact styled wrappers from `styles.ts` so behaviour is unchanged.\n */\nconst DrawerStyled = (props: TypeDrawerProps) => {\n const shell = useDrawerShell(props);\n const {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n } = shell;\n\n return (\n <BaseDrawer.Root {...rootProps}>\n <BaseDrawer.Portal>\n <StyledBackdrop data-testid=\"drawer-backdrop\" />\n <StyledViewport $hasSnapPoints={hasSnapPoints}>\n <StyledPopup\n initialFocus={true}\n $width={width}\n $offset={offset}\n $direction={effectiveDirection}\n $zIndex={zIndex}\n $hasSnapPoints={hasSnapPoints}\n $hasActionRail={hasActionRail}\n data-qa-drawer={id}\n data-qa-drawer-isopen={open}\n {...rest}\n >\n {effectiveDirection === \"bottom\" && <DragHandle aria-hidden />}\n <DrawerPopupContents shell={shell} />\n </StyledPopup>\n </StyledViewport>\n </BaseDrawer.Portal>\n </BaseDrawer.Root>\n );\n};\n\nexport default DrawerStyled;\n","import { Drawer } from \"@base-ui/react/drawer\";\nimport styled from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeSystemCommonProps } from \"@sproutsocial/seeds-react-system-props\";\nimport { MOTION_DURATION_MEDIUM } from \"@sproutsocial/seeds-motion/unitless\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { RAIL_BUTTON_HEIGHT, RAIL_OFFSET } from \"./ActionRail\";\n\n// Total vertical space the action rail occupies above the popup\n// (rail height + gap between rail and popup). When the drawer animates\n// closed, the popup must translate this much further so the rail also\n// leaves the viewport instead of flashing at the bottom edge.\nconst ACTION_RAIL_OUTSET = RAIL_BUTTON_HEIGHT + RAIL_OFFSET;\n\nexport const Content = styled(Box)`\n overflow-y: auto;\n`;\n\nexport const StyledViewport = styled(Drawer.Viewport)<{\n $hasSnapPoints: boolean;\n}>`\n ${(props) =>\n props.$hasSnapPoints\n ? `\n position: fixed;\n inset: 0;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n touch-action: none;\n /* The viewport spans the whole screen but the popup only fills part of\n it. Letting clicks fall through the empty area means a nested\n snap-point drawer doesn't block selection/interaction with the\n parent drawer visible underneath. The popup re-enables events. */\n pointer-events: none;\n `\n : \"\"}\n`;\n\ninterface StyledPopupProps extends TypeSystemCommonProps {\n $width: number;\n $offset: number;\n $direction: \"left\" | \"right\" | \"bottom\";\n $zIndex: number;\n $hasSnapPoints: boolean;\n $hasActionRail: boolean;\n}\n\nexport const StyledPopup = styled(Drawer.Popup)<StyledPopupProps>`\n display: flex;\n flex-direction: column;\n position: fixed;\n background-color: ${(props) => props.theme.colors.container.background.base};\n z-index: ${(props) => props.$zIndex};\n filter: blur(0);\n transition: transform ${MOTION_DURATION_MEDIUM}s ease,\n border-radius ${MOTION_DURATION_MEDIUM}s ease,\n height ${MOTION_DURATION_MEDIUM}s ease;\n\n /* Always-on opacity transition so content fades smoothly both into and out of stacked state */\n > * {\n transition: opacity ${MOTION_DURATION_MEDIUM}s ease;\n }\n\n ${(props) => {\n if (props.$direction === \"bottom\") {\n if (props.$hasSnapPoints) {\n // Snap-points popup follows base-ui's reference layout. Critical details:\n // - box-sizing: border-box so offsetHeight ignores padding-bottom; otherwise\n // base-ui's ResizeObserver feedback (padding-bottom driven by snap offset)\n // grows popupHeight on every measurement and snap math diverges.\n // - height (not max-height) so popupHeight is large enough that base-ui's\n // snap offset = max(0, popupHeight - snapHeight) distinguishes snap points;\n // with short content + max-height it collapses to 0 for every snap.\n // - position: relative inside the flex-end Viewport so base-ui can measure\n // popupHeight vs viewportHeight for snap math.\n return `\n box-sizing: border-box;\n position: relative;\n width: 100%;\n height: calc(100dvh - 1rem);\n padding-bottom: max(0px, calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));\n overflow: visible;\n touch-action: none;\n /* Counterpart to the viewport's pointer-events: none — the popup\n itself stays interactive. */\n pointer-events: auto;\n border-radius: ${props.theme.radii[800]} ${props.theme.radii[800]} 0 0;\n box-shadow: 0px -8px 16px rgba(39,51,51,.25);\n transform: translateY(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));\n will-change: transform;\n transition:\n transform ${MOTION_DURATION_MEDIUM}s cubic-bezier(0.32, 0.72, 0, 1),\n box-shadow ${MOTION_DURATION_MEDIUM}s cubic-bezier(0.32, 0.72, 0, 1);\n `;\n }\n return `\n --bleed: 3rem;\n --stack-scale: 1;\n --translate-y: 0px;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100%;\n height: calc(90vh + var(--bleed));\n margin-bottom: calc(-1 * var(--bleed));\n border-radius: ${props.theme.radii[800]} ${props.theme.radii[800]} 0 0;\n transform: translateY(var(--translate-y)) scale(var(--stack-scale));\n transform-origin: 50% calc(100% - var(--bleed));\n box-shadow: 0px -8px 16px rgba(39,51,51,.25);\n `;\n }\n return `\n top: 0;\n height: 100%;\n width: ${props.$width}px;\n ${\n props.$direction === \"right\"\n ? `right: ${props.$offset}px;`\n : `left: ${props.$offset}px;`\n }\n box-shadow: ${props.theme.shadows.medium};\n `;\n }}\n\n &[data-starting-style],\n &[data-ending-style] {\n ${(props) => {\n if (props.$direction !== \"bottom\") {\n return `transform: translateX(${\n props.$direction === \"right\" ? \"100%\" : \"-100%\"\n });`;\n }\n // The action rail lives above the popup (position: absolute,\n // bottom: 100% + RAIL_OFFSET). Translating the popup by its own\n // height alone leaves the rail visible at the bottom of the\n // viewport during enter/exit, so we add the rail's outset here.\n const railOffset = props.$hasActionRail\n ? ` + ${ACTION_RAIL_OUTSET}px`\n : \"\";\n if (props.$hasSnapPoints) {\n return `\n transform: translateY(calc(100% + 2px${railOffset}));\n padding-bottom: 0;\n `;\n }\n return `transform: translateY(calc(100% - var(--bleed) + 2px${railOffset}));`;\n }}\n }\n\n &[data-swiping],\n &[data-nested-drawer-swiping] {\n transition-duration: 0ms;\n }\n\n &[data-nested-drawer-open] {\n border-radius: ${(props) => props.theme.radii[800]};\n\n ${(props) => {\n if (props.$direction === \"bottom\") {\n // Snap-point drawers don't participate in the stacked-bottom-sheet\n // animation: the stack math overwrites --translate-y and clips overflow,\n // which collides with base-ui's snap-offset transform.\n if (props.$hasSnapPoints) return \"\";\n return `\n --stack-step: 0.05;\n --stack-progress: clamp(0, var(--drawer-swipe-progress), 1);\n /* Override default vars; base transform rule picks them up automatically */\n --stack-scale: max(0, calc(\n 1 - (var(--nested-drawers) * var(--stack-step))\n + (var(--stack-step) * var(--stack-progress))\n ));\n --stack-shrink: calc(1 - var(--stack-scale));\n --stack-height: max(0px, calc(\n var(--drawer-frontmost-height, var(--drawer-height)) - var(--bleed)\n ));\n --stack-peek-offset: max(0px, calc(\n (var(--nested-drawers) - var(--stack-progress)) * 1rem\n ));\n --translate-y: calc(\n var(--drawer-swipe-movement-y)\n - var(--stack-peek-offset)\n - (var(--stack-shrink) * var(--stack-height))\n );\n height: calc(var(--stack-height) + var(--bleed));\n overflow: hidden;\n `;\n }\n return `\n transform: translateY(calc(var(--nested-drawers) * -20px))\n scale(calc(1 - var(--nested-drawers) * 0.08));\n transform-origin: top center;\n `;\n }}\n\n ${(props) =>\n props.$hasSnapPoints\n ? \"\"\n : `\n > * {\n opacity: 0;\n }\n `}\n }\n\n &[data-nested-drawer-open][data-nested-drawer-swiping] {\n > * {\n opacity: 1;\n }\n }\n\n ${COMMON}\n`;\n\nexport const DragHandle = styled.div`\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n width: 36px;\n height: 4px;\n border-radius: 2px;\n background-color: ${(props) => props.theme.colors.container.border.base};\n`;\n\nexport const StyledBackdrop = styled(Drawer.Backdrop)`\n position: fixed;\n inset: 0;\n background: transparent;\n pointer-events: none;\n`;\n","import * as React from \"react\";\nimport styled, { css } from \"styled-components\";\n\nexport const RAIL_BUTTON_SIZE = 44;\nexport const RAIL_BUTTON_HEIGHT = 32;\nexport const RAIL_OFFSET = 12;\nexport const RAIL_GAP = 12;\n\nconst mobileLayout = css`\n top: auto;\n bottom: calc(100% + ${RAIL_OFFSET}px);\n right: ${RAIL_OFFSET}px;\n left: auto;\n flex-direction: row-reverse;\n`;\n\nconst desktopLayout = css`\n top: ${RAIL_OFFSET}px;\n right: calc(-1 * (${RAIL_BUTTON_SIZE}px + ${RAIL_OFFSET}px));\n flex-direction: column;\n`;\n\nconst Rail = styled.div<{ $isMobile?: boolean }>`\n position: absolute;\n display: flex;\n gap: ${RAIL_GAP}px;\n z-index: 1;\n ${(props) => (props.$isMobile ? mobileLayout : desktopLayout)}\n`;\n\nexport interface TypeActionRailProps {\n children: React.ReactNode;\n /** When true, render horizontally above the parent (bottom-sheet mobile pattern). */\n isMobile?: boolean;\n /** Accessible group label for the rail. */\n \"aria-label\"?: string;\n}\n\nexport const ActionRail: React.FC<TypeActionRailProps> = ({\n children,\n isMobile,\n \"aria-label\": ariaLabel = \"Quick actions\",\n}) => {\n return (\n <Rail\n $isMobile={isMobile}\n data-slot=\"action-rail\"\n data-qa-action-rail\n aria-label={ariaLabel}\n role=\"group\"\n >\n {children}\n </Rail>\n );\n};\n\nActionRail.displayName = \"ActionRail\";\n","import * as React from \"react\";\nimport styled from \"styled-components\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport { RAIL_BUTTON_HEIGHT, RAIL_BUTTON_SIZE } from \"./ActionRail\";\n\nconst StyledButton = styled.button`\n width: ${RAIL_BUTTON_SIZE}px;\n height: ${RAIL_BUTTON_HEIGHT}px;\n display: inline-grid;\n place-items: center;\n border-radius: ${(props) => props.theme.radii.outer};\n border: none;\n background: ${(props) => props.theme.colors.button.overlay.background.base};\n color: ${(props) => props.theme.colors.button.overlay.text.base};\n cursor: pointer;\n outline: none;\n transition: all ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_inout};\n\n &:hover {\n background: ${(props) =>\n props.theme.colors.button.overlay.background.hover};\n }\n\n &:hover,\n &:active {\n transform: none;\n }\n\n &:focus-visible {\n ${focusRing}\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n`;\n\nexport type TypeActionRailButtonProps =\n React.ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport const ActionRailButton = React.forwardRef<\n HTMLButtonElement,\n TypeActionRailButtonProps\n>(({ children, ...rest }, ref) => (\n <StyledButton\n ref={ref}\n type=\"button\"\n data-slot=\"action-rail-button\"\n {...rest}\n >\n {children}\n </StyledButton>\n));\n\nActionRailButton.displayName = \"ActionRailButton\";\n","import * as React from \"react\";\nimport { useContext } from \"react\";\nimport { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\n// eslint-disable-next-line import/no-deprecated\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { useIsMobile } from \"@sproutsocial/seeds-react-hooks\";\nimport { DisablePortalToBodyContext } from \"@sproutsocial/seeds-react-portal\";\nimport { Content } from \"./styles\";\nimport { ActionRail, ActionRailButton } from \"./ActionRail\";\nimport type {\n TypeDrawerContext,\n TypeDrawerCloseButtonProps,\n TypeDrawerHeaderProps,\n TypeDrawerProps,\n TypeDrawerContentProps,\n} from \"./DrawerTypes\";\n\n/**\n * Single source of truth for the Drawer context. Both the Tailwind and the\n * styled-components shells provide this exact context, and the shared\n * sub-components (`Drawer.CloseButton`, `Drawer.Header`) consume it — so there\n * must be exactly one context identity, or the close button can't see its\n * provider.\n */\nexport const DrawerContext = React.createContext<TypeDrawerContext>({\n isLocked: false,\n setIsLocked: () => {},\n hasActionRail: false,\n});\n\nexport const DrawerCloseButton = (props: TypeDrawerCloseButtonProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext) ?? null;\n }\n\n return (\n <Button\n appearance=\"pill\"\n aria-label={drawerContext.closeButtonLabel}\n onClick={drawerContext.onClose}\n {...props}\n >\n {props.children || <Icon aria-hidden name=\"x-outline\" />}\n </Button>\n );\n};\n\nexport const DrawerHeader = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (render) {\n return render(drawerContext);\n }\n\n return (\n <Box\n display=\"flex\"\n flex=\"0 0 auto\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n pt={400}\n px={450}\n {...rest}\n >\n {children || (\n <>\n <Text\n as=\"h2\"\n fontSize={400}\n fontWeight=\"semibold\"\n color=\"text.headline\"\n id={id}\n >\n {title}\n </Text>\n {!drawerContext.hasActionRail && <DrawerCloseButton />}\n </>\n )}\n </Box>\n );\n};\n\nexport const DrawerContent = ({\n children,\n ...rest\n}: TypeDrawerContentProps) => (\n <Content\n height=\"100%\"\n p={450}\n color=\"text.body\"\n data-drawer-content=\"\"\n {...rest}\n >\n {children}\n </Content>\n);\n\nDrawerHeader.displayName = \"Drawer.Header\";\nDrawerContent.displayName = \"Drawer.Content\";\nDrawerCloseButton.displayName = \"Drawer.CloseButton\";\n\n/**\n * Root-level Drawer logic shared by both shells. Centralising it here (rather\n * than duplicating it in each shell) guarantees the two implementations stay\n * behaviourally identical — the esc-key lock and exit-freeze logic is exactly\n * what the lock/close tests exercise.\n */\nexport const useDrawerShell = (props: TypeDrawerProps) => {\n const {\n children,\n closeButtonLabel,\n direction = \"right\",\n disableCloseOnClickOutside = false,\n id,\n modal = false,\n open,\n offset = 0,\n onClose,\n zIndex = 7,\n width = 600,\n snapPoints,\n defaultSnapPoint,\n snapPoint,\n onSnapPointChange,\n snapToSequentialPoints,\n actions,\n actionsInHeader = false,\n ...rest\n } = props;\n\n const isMobile = useIsMobile();\n const effectiveDirection = isMobile ? \"bottom\" : direction;\n const effectiveSnapPoints =\n effectiveDirection === \"bottom\" ? snapPoints : undefined;\n const hasSnapPoints = !!effectiveSnapPoints && effectiveSnapPoints.length > 0;\n const hasActionRail =\n isMobile && !actionsInHeader && !!actions && actions.length > 0;\n const [isLocked, setIsLocked] = React.useState(false);\n\n const ariaLabelledBy = rest[\"aria-labelledby\"];\n const ariaLabel = rest[\"aria-label\"];\n React.useEffect(() => {\n if (process.env.NODE_ENV !== \"production\") {\n if (!ariaLabelledBy && !ariaLabel) {\n console.warn(\n \"[Drawer] Missing accessible name. Add aria-labelledby pointing to your Drawer.Header id, or aria-label, so screen readers can identify the dialog.\"\n );\n }\n }\n }, [ariaLabelledBy, ariaLabel]);\n // Keep a ref so the onOpenChange callback always sees the current isLocked\n // value without needing to be re-created on each render.\n const isLockedRef = React.useRef(isLocked);\n isLockedRef.current = isLocked;\n\n // Freeze the last-rendered children during the exit transition so consumers\n // that conditionally render content (e.g. {isOpen && <Content />}) don't\n // produce an empty drawer shell while Base UI animates the popup out.\n const prevChildrenRef = React.useRef<React.ReactNode>(null);\n if (open) {\n prevChildrenRef.current = children;\n }\n const renderedChildren = open ? children : prevChildrenRef.current;\n\n const rootProps: Omit<\n React.ComponentProps<typeof BaseDrawer.Root>,\n \"children\"\n > = {\n open,\n onOpenChange: (isOpen, eventDetails) => {\n if (!isOpen) {\n if (isLockedRef.current && eventDetails.reason === \"escape-key\") {\n return;\n }\n onClose();\n }\n },\n disablePointerDismissal: disableCloseOnClickOutside,\n swipeDirection:\n effectiveDirection === \"bottom\" ? \"down\" : effectiveDirection,\n modal,\n snapPoints: effectiveSnapPoints,\n defaultSnapPoint,\n snapPoint,\n onSnapPointChange: onSnapPointChange\n ? (sp) => onSnapPointChange(sp)\n : undefined,\n snapToSequentialPoints,\n };\n\n return {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n isLocked,\n setIsLocked,\n renderedChildren,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n closeButtonLabel,\n onClose,\n actions,\n };\n};\n\nexport type TypeDrawerShell = ReturnType<typeof useDrawerShell>;\n\n/**\n * The popup contents shared by both shells: the optional mobile action rail and\n * the context providers wrapping the rendered children. Only the popup wrapper\n * and drag handle differ between the Tailwind and styled paths — everything\n * inside the popup is identical, so it lives here.\n */\nexport const DrawerPopupContents = ({ shell }: { shell: TypeDrawerShell }) => {\n const {\n hasActionRail,\n closeButtonLabel,\n onClose,\n actions,\n isLocked,\n setIsLocked,\n renderedChildren,\n } = shell;\n\n return (\n <>\n {hasActionRail && actions && (\n <ActionRail isMobile aria-label=\"Drawer quick actions\">\n <ActionRailButton\n aria-label={closeButtonLabel}\n onClick={onClose}\n data-qa-drawer-rail-close\n >\n <Icon aria-hidden name=\"x-outline\" />\n </ActionRailButton>\n {actions.map((action, i) => (\n <ActionRailButton\n key={i}\n aria-label={action[\"aria-label\"]}\n onClick={action.onClick}\n disabled={action.disabled}\n >\n {action.iconName && <Icon aria-hidden name={action.iconName} />}\n </ActionRailButton>\n ))}\n </ActionRail>\n )}\n <DisablePortalToBodyContext.Provider value={true}>\n <DrawerContext.Provider\n value={{\n onClose,\n closeButtonLabel,\n isLocked,\n setIsLocked,\n hasActionRail,\n }}\n >\n {renderedChildren}\n </DrawerContext.Provider>\n </DisablePortalToBodyContext.Provider>\n </>\n );\n};\n","import { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport { useDrawerShell, DrawerPopupContents } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\nimport type { CSSProperties } from \"react\";\n\n// Utility for merging class names properly. Copied from ButtonTailwind.tsx —\n// `cn` is NOT exported from @sproutsocial/seeds-react-utilities, so each\n// Tailwind component carries its own copy.\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\n/**\n * Tailwind/CSS-class shell. The preferred path — routed to by `DrawerHybrid`\n * whenever the consumer passes no styled-system props. Renders the real Base UI\n * primitives (Backdrop/Viewport/Popup) with component-scoped classes from\n * `drawer.css`; the runtime numerics (`width`, `offset`, `zIndex`) are applied\n * as direct inline styles so drag/swipe/snap/portal behaviour is preserved.\n */\nconst DrawerTailwind = (props: TypeDrawerProps) => {\n const shell = useDrawerShell(props);\n const {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n } = shell;\n\n // `className` and `style` are public <div> props (TypeDrawerProps extends\n // ComponentPropsWithoutRef<\"div\">) that arrive via `rest`. Pull them out so\n // they MERGE with the popup's computed classes/geometry instead of\n // overwriting them — matching the styled-components path, where a consumer\n // className is appended to the generated class and an inline style wins over\n // the generated width.\n const { className, style, ...domRest } = rest as {\n className?: string;\n style?: CSSProperties;\n } & Record<string, unknown>;\n\n return (\n <BaseDrawer.Root {...rootProps}>\n <BaseDrawer.Portal>\n <BaseDrawer.Backdrop\n data-testid=\"drawer-backdrop\"\n className=\"seeds-drawer-backdrop\"\n />\n <BaseDrawer.Viewport\n className={cn(\"seeds-drawer-viewport\", {\n \"seeds-drawer-viewport--snap\": hasSnapPoints,\n })}\n >\n <BaseDrawer.Popup\n initialFocus\n data-qa-drawer={id}\n data-qa-drawer-isopen={open}\n {...domRest}\n className={cn(\n \"seeds-drawer-popup\",\n effectiveDirection === \"bottom\"\n ? \"seeds-drawer-popup--bottom\"\n : \"seeds-drawer-popup--side\",\n effectiveDirection === \"right\" && \"seeds-drawer-popup--right\",\n effectiveDirection === \"left\" && \"seeds-drawer-popup--left\",\n {\n \"seeds-drawer-popup--snap\": hasSnapPoints,\n \"seeds-drawer-popup--action-rail\": hasActionRail,\n },\n // Consumer className folded in last so it appends to (not\n // replaces) the component classes.\n className\n )}\n style={{\n // z-index is always inline (runtime numeric, mirrors styles.ts).\n zIndex,\n // Side drawers carry their width/offset as direct inline styles —\n // runtime numerics, and required for the jsdom `toHaveStyle`\n // assertions. Bottom drawers derive width/position from the class.\n ...(effectiveDirection === \"right\"\n ? { width: `${width}px`, right: `${offset}px` }\n : effectiveDirection === \"left\"\n ? { width: `${width}px`, left: `${offset}px` }\n : {}),\n // Consumer style folded in last so it wins over the computed\n // geometry, matching the styled-components inline-style semantics.\n ...style,\n }}\n >\n {effectiveDirection === \"bottom\" && (\n <div aria-hidden className=\"seeds-drawer-drag-handle\" />\n )}\n <DrawerPopupContents shell={shell} />\n </BaseDrawer.Popup>\n </BaseDrawer.Viewport>\n </BaseDrawer.Portal>\n </BaseDrawer.Root>\n );\n};\n\nexport default DrawerTailwind;\n","import DrawerHybrid from \"./DrawerHybrid\";\n\n/**\n * Drawer component. Automatically routes between the Tailwind implementation\n * (preferred) and the styled-components implementation (for consumers using\n * system props or a `styled()` extension). The default export carries the\n * `.Header`, `.Content`, and `.CloseButton` statics.\n */\nexport { DrawerContext } from \"./DrawerShared\";\nexport default DrawerHybrid;\n","import * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\nimport type { TypeIconName } from \"@sproutsocial/seeds-react-icon\";\n\ntype DrawerAnimationDirection = \"left\" | \"right\" | \"bottom\";\n\n/**\n * Action button shown in the mobile rail above a bottom-sheet drawer.\n * Mirrors `TypeModalActionProps` so consumers can share the same array shape.\n */\nexport type TypeDrawerActionProps = {\n /** Accessible label for the action button. */\n \"aria-label\": string;\n /** Icon name from the Seeds icon set. */\n iconName?: TypeIconName;\n /** Click handler. */\n onClick?: () => void;\n /** Disable the action. */\n disabled?: boolean;\n};\n\n/**\n * A snap point the bottom drawer can rest at.\n * - Numbers 0–1: fraction of viewport height\n * - Numbers > 1: pixels\n * - Strings: CSS lengths in `px` or `rem` (e.g. `\"480px\"`, `\"30rem\"`)\n */\nexport type TypeDrawerSnapPoint = number | string;\n\nexport interface TypeDrawerContext {\n /** Callback for close button */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClose?: () => any;\n\n /** aria-label for drawer close button */\n closeButtonLabel?: string;\n /**\n * isLocked and setIsLocked are used when a Drawer contains other components (like Menu) that also\n * listen for Escape key events. By locking the Drawer, we can prevent conflicts\n * where multiple components try to handle the same keydown event.\n */\n isLocked: boolean;\n setIsLocked: (locked: boolean) => void;\n /**\n * True when the Drawer is rendering an `ActionRail` above the popup. The\n * default `Drawer.Header` reads this to omit its built-in close button so the\n * rail can own the close affordance.\n */\n hasActionRail?: boolean;\n}\n// TODO: Should the render prop be a React.FC?\nexport interface TypeDrawerCloseButtonProps\n extends Omit<TypeButtonProps, \"children\"> {\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the on-close behavior. */\n render?: React.FC<TypeDrawerContext>;\n children?: React.ReactNode;\n}\n\nexport interface TypeDrawerHeaderProps extends TypeBoxProps {\n title?: string;\n /**\n * When children are provided, `<Drawer.CloseButton />` is NOT rendered automatically.\n * You must include it yourself inside children to preserve keyboard accessibility.\n */\n children?: React.ReactNode;\n\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the appearance of the header. */\n render?: React.FC<TypeDrawerContext>;\n}\n\nexport interface TypeDrawerProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"div\">, \"color\"> {\n children: React.ReactNode;\n\n /** Label for the close button. Usually this should be \"Close\" */\n closeButtonLabel: string;\n\n /** Whether the drawer slides in from the left or right side of the screen */\n direction?: DrawerAnimationDirection;\n\n /** In some cases, you may not want the user to be able to click outside of the drawer to close it. You can disable that with this prop. */\n disableCloseOnClickOutside?: boolean;\n\n /**\n * When true, siblings are inerted while the drawer is open — appropriate for forms or settings\n * panels where page interaction should be blocked.\n * Defaults to false to preserve the original non-modal behavior where the rest of the page\n * remains interactive (side info panels, notification slide-outs, persistent inspectors, etc.).\n */\n modal?: boolean;\n /** Optional id used for data-qa-drawer attributes */\n id?: string;\n open: boolean;\n offset?: number;\n onClose: () => void;\n zIndex?: number;\n width?: number;\n\n /**\n * Snap points the drawer can rest at when swiped. Only applied to bottom drawers.\n * Numbers 0–1 are viewport-height fractions; numbers > 1 are pixels; strings accept\n * `px`/`rem` (e.g. `\"480px\"`, `\"30rem\"`). Order matters — the last entry is the\n * \"expanded\" state and gets a `data-expanded` attribute on the popup.\n */\n snapPoints?: TypeDrawerSnapPoint[];\n\n /** Initial snap point for uncontrolled use. */\n defaultSnapPoint?: TypeDrawerSnapPoint | null;\n\n /** Controlled active snap point. Pair with `onSnapPointChange`. */\n snapPoint?: TypeDrawerSnapPoint | null;\n\n /** Fires when the active snap point changes (drag release, programmatic update, etc.). */\n onSnapPointChange?: (snapPoint: TypeDrawerSnapPoint | null) => void;\n\n /**\n * When true, fast swipes can't skip past adjacent snap points — drag distance alone\n * determines the next stop. Defaults to base-ui's `false` (velocity-based skipping).\n */\n snapToSequentialPoints?: boolean;\n\n /**\n * Action buttons shown in a floating rail above the drawer on mobile (the\n * bottom-sheet rendering). The rail also owns the close button — when this\n * prop is provided, the default `Drawer.Header` omits its built-in close\n * button so the rail can render it instead. Ignored on desktop side drawers.\n */\n actions?: TypeDrawerActionProps[];\n\n /**\n * Opt out of the floating rail and keep the actions inside `Drawer.Header`\n * (the pre-rail behavior). Useful for nested bottom sheets and snap-point\n * drawers where the rail-above placement would collide with surrounding UI\n * or fall off-screen at the highest snap point. Defaults to `false`.\n *\n * When `true`, the Drawer does NOT render the rail; consumers are\n * responsible for rendering action buttons (and the close button) inside\n * their `Drawer.Header`.\n */\n actionsInHeader?: boolean;\n}\n\nexport interface TypeDrawerContentProps extends TypeBoxProps {\n children?: React.ReactNode;\n}\n","import Drawer, { DrawerContext } from \"./Drawer\";\n\nexport default Drawer;\nexport { Drawer, DrawerContext };\nexport * from \"./DrawerTypes\";\nexport {\n ActionRail,\n ActionRailButton,\n RAIL_BUTTON_SIZE,\n RAIL_BUTTON_HEIGHT,\n RAIL_OFFSET,\n RAIL_GAP,\n} from \"./ActionRail\";\nexport type {\n TypeActionRailProps,\n TypeActionRailButtonProps,\n} from \"./ActionRail\";\n"],"mappings":"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","names":["BaseDrawer","styled","React","styled","jsx","styled","styled","React","Box","jsx","Box","jsx","jsxs","BaseDrawer","BaseDrawer","jsx","jsxs","BaseDrawer","jsx"]}
1
+ {"version":3,"sources":["../../src/DrawerHybrid.tsx","../../src/DrawerStyled.tsx","../../src/styles.ts","../../src/ActionRail/ActionRail.tsx","../../src/ActionRail/ActionRailButton.tsx","../../src/DrawerShared.tsx","../../src/DrawerTailwind.tsx","../../src/Drawer.tsx","../../src/DrawerTypes.ts","../../src/index.ts"],"sourcesContent":["/**\n * Hybrid Drawer component.\n * Automatically chooses between the Tailwind shell (preferred) and the\n * styled-components shell based on props, mirroring `ButtonHybrid`. When a\n * consumer passes styled-system props (`px`, `color`, `height`, …) the styled\n * path is used so existing styling keeps working; otherwise the Tailwind path\n * renders.\n */\nimport { hasStyledProps } from \"@sproutsocial/seeds-react-system-props\";\nimport DrawerStyled from \"./DrawerStyled\";\nimport DrawerTailwind from \"./DrawerTailwind\";\nimport { DrawerHeader, DrawerContent, DrawerCloseButton } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\n\n// Props the Drawer owns semantically. They must be stripped before the\n// `hasStyledProps` check so a Drawer-specific prop never trips the styled\n// router — most importantly `width`, which `hasStyledProps` also treats as a\n// styled-system prop. Anything left in `rest` is a true pass-through/system\n// prop and is what the routing decision is based on.\nconst DRAWER_OWN_PROPS: readonly string[] = [\n \"children\",\n \"closeButtonLabel\",\n \"direction\",\n \"disableCloseOnClickOutside\",\n \"id\",\n \"modal\",\n \"open\",\n \"offset\",\n \"onClose\",\n \"zIndex\",\n \"width\",\n \"snapPoints\",\n \"defaultSnapPoint\",\n \"snapPoint\",\n \"onSnapPointChange\",\n \"snapToSequentialPoints\",\n \"actions\",\n \"actionsInHeader\",\n];\n\nconst DrawerHybrid = (props: TypeDrawerProps) => {\n const rest: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n if (!DRAWER_OWN_PROPS.includes(key)) {\n rest[key] = (props as unknown as Record<string, unknown>)[key];\n }\n }\n\n if (hasStyledProps(rest)) {\n return <DrawerStyled {...props} />;\n }\n\n // Use the Tailwind version (preferred - better performance).\n return <DrawerTailwind {...props} />;\n};\n\nDrawerHybrid.Header = DrawerHeader;\nDrawerHybrid.Content = DrawerContent;\nDrawerHybrid.CloseButton = DrawerCloseButton;\n\nexport default DrawerHybrid;\n","import { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport {\n StyledPopup,\n StyledBackdrop,\n StyledViewport,\n DragHandle,\n} from \"./styles\";\nimport { useDrawerShell, DrawerPopupContents } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\n\n/**\n * Legacy styled-components shell. Routed to by `DrawerHybrid` whenever the\n * consumer passes styled-system props (or a `styled()` extension). Renders the\n * exact styled wrappers from `styles.ts` so behaviour is unchanged.\n */\nconst DrawerStyled = (props: TypeDrawerProps) => {\n const shell = useDrawerShell(props);\n const {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n } = shell;\n\n return (\n <BaseDrawer.Root {...rootProps}>\n <BaseDrawer.Portal>\n <StyledBackdrop data-testid=\"drawer-backdrop\" />\n <StyledViewport $hasSnapPoints={hasSnapPoints}>\n <StyledPopup\n initialFocus={true}\n $width={width}\n $offset={offset}\n $direction={effectiveDirection}\n $zIndex={zIndex}\n $hasSnapPoints={hasSnapPoints}\n $hasActionRail={hasActionRail}\n data-qa-drawer={id}\n data-qa-drawer-isopen={open}\n {...rest}\n >\n {effectiveDirection === \"bottom\" && <DragHandle aria-hidden />}\n <DrawerPopupContents shell={shell} />\n </StyledPopup>\n </StyledViewport>\n </BaseDrawer.Portal>\n </BaseDrawer.Root>\n );\n};\n\nexport default DrawerStyled;\n","import { Drawer } from \"@base-ui/react/drawer\";\nimport styled from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeSystemCommonProps } from \"@sproutsocial/seeds-react-system-props\";\nimport { MOTION_DURATION_MEDIUM } from \"@sproutsocial/seeds-motion/unitless\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { RAIL_BUTTON_HEIGHT, RAIL_OFFSET } from \"./ActionRail\";\n\n// Total vertical space the action rail occupies above the popup\n// (rail height + gap between rail and popup). When the drawer animates\n// closed, the popup must translate this much further so the rail also\n// leaves the viewport instead of flashing at the bottom edge.\nconst ACTION_RAIL_OUTSET = RAIL_BUTTON_HEIGHT + RAIL_OFFSET;\n\nexport const Content = styled(Box)`\n overflow-y: auto;\n`;\n\nexport const StyledViewport = styled(Drawer.Viewport)<{\n $hasSnapPoints: boolean;\n}>`\n ${(props) =>\n props.$hasSnapPoints\n ? `\n position: fixed;\n inset: 0;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n touch-action: none;\n /* The viewport spans the whole screen but the popup only fills part of\n it. Letting clicks fall through the empty area means a nested\n snap-point drawer doesn't block selection/interaction with the\n parent drawer visible underneath. The popup re-enables events. */\n pointer-events: none;\n `\n : \"\"}\n`;\n\ninterface StyledPopupProps extends TypeSystemCommonProps {\n $width: number;\n $offset: number;\n $direction: \"left\" | \"right\" | \"bottom\";\n $zIndex: number;\n $hasSnapPoints: boolean;\n $hasActionRail: boolean;\n}\n\nexport const StyledPopup = styled(Drawer.Popup)<StyledPopupProps>`\n display: flex;\n flex-direction: column;\n position: fixed;\n background-color: ${(props) => props.theme.colors.container.background.base};\n z-index: ${(props) => props.$zIndex};\n filter: blur(0);\n transition: transform ${MOTION_DURATION_MEDIUM}s ease,\n border-radius ${MOTION_DURATION_MEDIUM}s ease,\n height ${MOTION_DURATION_MEDIUM}s ease;\n\n /* Always-on opacity transition so content fades smoothly both into and out of stacked state */\n > * {\n transition: opacity ${MOTION_DURATION_MEDIUM}s ease;\n }\n\n ${(props) => {\n if (props.$direction === \"bottom\") {\n if (props.$hasSnapPoints) {\n // Snap-points popup follows base-ui's reference layout. Critical details:\n // - box-sizing: border-box so offsetHeight ignores padding-bottom; otherwise\n // base-ui's ResizeObserver feedback (padding-bottom driven by snap offset)\n // grows popupHeight on every measurement and snap math diverges.\n // - height (not max-height) so popupHeight is large enough that base-ui's\n // snap offset = max(0, popupHeight - snapHeight) distinguishes snap points;\n // with short content + max-height it collapses to 0 for every snap.\n // - position: relative inside the flex-end Viewport so base-ui can measure\n // popupHeight vs viewportHeight for snap math.\n return `\n box-sizing: border-box;\n position: relative;\n width: 100%;\n height: calc(100dvh - 1rem);\n padding-bottom: max(0px, calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));\n overflow: visible;\n touch-action: none;\n /* Counterpart to the viewport's pointer-events: none — the popup\n itself stays interactive. */\n pointer-events: auto;\n border-radius: ${props.theme.radii[800]} ${props.theme.radii[800]} 0 0;\n box-shadow: 0px -8px 16px rgba(39,51,51,.25);\n transform: translateY(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));\n will-change: transform;\n transition:\n transform ${MOTION_DURATION_MEDIUM}s cubic-bezier(0.32, 0.72, 0, 1),\n box-shadow ${MOTION_DURATION_MEDIUM}s cubic-bezier(0.32, 0.72, 0, 1);\n `;\n }\n return `\n --bleed: 3rem;\n --stack-scale: 1;\n --translate-y: 0px;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100%;\n height: calc(90vh + var(--bleed));\n margin-bottom: calc(-1 * var(--bleed));\n border-radius: ${props.theme.radii[800]} ${props.theme.radii[800]} 0 0;\n transform: translateY(var(--translate-y)) scale(var(--stack-scale));\n transform-origin: 50% calc(100% - var(--bleed));\n box-shadow: 0px -8px 16px rgba(39,51,51,.25);\n `;\n }\n return `\n top: 0;\n height: 100%;\n width: ${props.$width}px;\n ${\n props.$direction === \"right\"\n ? `right: ${props.$offset}px;`\n : `left: ${props.$offset}px;`\n }\n box-shadow: ${props.theme.shadows.medium};\n `;\n }}\n\n &[data-starting-style],\n &[data-ending-style] {\n ${(props) => {\n if (props.$direction !== \"bottom\") {\n return `transform: translateX(${\n props.$direction === \"right\" ? \"100%\" : \"-100%\"\n });`;\n }\n // The action rail lives above the popup (position: absolute,\n // bottom: 100% + RAIL_OFFSET). Translating the popup by its own\n // height alone leaves the rail visible at the bottom of the\n // viewport during enter/exit, so we add the rail's outset here.\n const railOffset = props.$hasActionRail\n ? ` + ${ACTION_RAIL_OUTSET}px`\n : \"\";\n if (props.$hasSnapPoints) {\n return `\n transform: translateY(calc(100% + 2px${railOffset}));\n padding-bottom: 0;\n `;\n }\n return `transform: translateY(calc(100% - var(--bleed) + 2px${railOffset}));`;\n }}\n }\n\n &[data-swiping],\n &[data-nested-drawer-swiping] {\n transition-duration: 0ms;\n }\n\n &[data-nested-drawer-open] {\n border-radius: ${(props) => props.theme.radii[800]};\n\n ${(props) => {\n if (props.$direction === \"bottom\") {\n // Snap-point drawers don't participate in the stacked-bottom-sheet\n // animation: the stack math overwrites --translate-y and clips overflow,\n // which collides with base-ui's snap-offset transform.\n if (props.$hasSnapPoints) return \"\";\n return `\n --stack-step: 0.05;\n --stack-progress: clamp(0, var(--drawer-swipe-progress), 1);\n /* Override default vars; base transform rule picks them up automatically */\n --stack-scale: max(0, calc(\n 1 - (var(--nested-drawers) * var(--stack-step))\n + (var(--stack-step) * var(--stack-progress))\n ));\n --stack-shrink: calc(1 - var(--stack-scale));\n --stack-height: max(0px, calc(\n var(--drawer-frontmost-height, var(--drawer-height)) - var(--bleed)\n ));\n --stack-peek-offset: max(0px, calc(\n (var(--nested-drawers) - var(--stack-progress)) * 1rem\n ));\n --translate-y: calc(\n var(--drawer-swipe-movement-y)\n - var(--stack-peek-offset)\n - (var(--stack-shrink) * var(--stack-height))\n );\n height: calc(var(--stack-height) + var(--bleed));\n overflow: hidden;\n `;\n }\n return `\n transform: translateY(calc(var(--nested-drawers) * -20px))\n scale(calc(1 - var(--nested-drawers) * 0.08));\n transform-origin: top center;\n `;\n }}\n\n ${(props) =>\n props.$hasSnapPoints\n ? \"\"\n : `\n > * {\n opacity: 0;\n }\n `}\n }\n\n &[data-nested-drawer-open][data-nested-drawer-swiping] {\n > * {\n opacity: 1;\n }\n }\n\n ${COMMON}\n`;\n\nexport const DragHandle = styled.div`\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n width: 36px;\n height: 4px;\n border-radius: 2px;\n background-color: ${(props) => props.theme.colors.container.border.base};\n`;\n\nexport const StyledBackdrop = styled(Drawer.Backdrop)`\n position: fixed;\n inset: 0;\n background: transparent;\n pointer-events: none;\n`;\n","import * as React from \"react\";\nimport styled, { css } from \"styled-components\";\n\nexport const RAIL_BUTTON_SIZE = 44;\nexport const RAIL_BUTTON_HEIGHT = 32;\nexport const RAIL_OFFSET = 12;\nexport const RAIL_GAP = 12;\n\nconst mobileLayout = css`\n top: auto;\n bottom: calc(100% + ${RAIL_OFFSET}px);\n right: ${RAIL_OFFSET}px;\n left: auto;\n flex-direction: row-reverse;\n`;\n\nconst desktopLayout = css`\n top: ${RAIL_OFFSET}px;\n right: calc(-1 * (${RAIL_BUTTON_SIZE}px + ${RAIL_OFFSET}px));\n flex-direction: column;\n`;\n\nconst Rail = styled.div<{ $isMobile?: boolean }>`\n position: absolute;\n display: flex;\n gap: ${RAIL_GAP}px;\n z-index: 1;\n ${(props) => (props.$isMobile ? mobileLayout : desktopLayout)}\n`;\n\nexport interface TypeActionRailProps {\n children: React.ReactNode;\n /** When true, render horizontally above the parent (bottom-sheet mobile pattern). */\n isMobile?: boolean;\n /** Accessible group label for the rail. */\n \"aria-label\"?: string;\n}\n\nexport const ActionRail: React.FC<TypeActionRailProps> = ({\n children,\n isMobile,\n \"aria-label\": ariaLabel = \"Quick actions\",\n}) => {\n return (\n <Rail\n $isMobile={isMobile}\n data-slot=\"action-rail\"\n data-qa-action-rail\n aria-label={ariaLabel}\n role=\"group\"\n >\n {children}\n </Rail>\n );\n};\n\nActionRail.displayName = \"ActionRail\";\n","import * as React from \"react\";\nimport styled from \"styled-components\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport { RAIL_BUTTON_HEIGHT, RAIL_BUTTON_SIZE } from \"./ActionRail\";\n\nconst StyledButton = styled.button`\n width: ${RAIL_BUTTON_SIZE}px;\n height: ${RAIL_BUTTON_HEIGHT}px;\n display: inline-grid;\n place-items: center;\n border-radius: ${(props) => props.theme.radii.outer};\n border: none;\n background: ${(props) => props.theme.colors.button.overlay.background.base};\n color: ${(props) => props.theme.colors.button.overlay.text.base};\n cursor: pointer;\n outline: none;\n transition: all ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_inout};\n\n &:hover {\n background: ${(props) =>\n props.theme.colors.button.overlay.background.hover};\n }\n\n &:hover,\n &:active {\n transform: none;\n }\n\n &:focus-visible {\n ${focusRing}\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n`;\n\nexport type TypeActionRailButtonProps =\n React.ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport const ActionRailButton = React.forwardRef<\n HTMLButtonElement,\n TypeActionRailButtonProps\n>(({ children, ...rest }, ref) => (\n <StyledButton\n ref={ref}\n type=\"button\"\n data-slot=\"action-rail-button\"\n {...rest}\n >\n {children}\n </StyledButton>\n));\n\nActionRailButton.displayName = \"ActionRailButton\";\n","import * as React from \"react\";\nimport { useContext } from \"react\";\nimport { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\n// eslint-disable-next-line import/no-deprecated\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { useIsMobile } from \"@sproutsocial/seeds-react-hooks\";\nimport { DisablePortalToBodyContext } from \"@sproutsocial/seeds-react-portal\";\nimport { needsStyledComponents } from \"@sproutsocial/seeds-react-system-props\";\nimport { Content } from \"./styles\";\nimport { ActionRail, ActionRailButton } from \"./ActionRail\";\nimport type {\n TypeDrawerContext,\n TypeDrawerCloseButtonProps,\n TypeDrawerHeaderProps,\n TypeDrawerProps,\n TypeDrawerContentProps,\n} from \"./DrawerTypes\";\n\n/**\n * Single source of truth for the Drawer context. Both the Tailwind and the\n * styled-components shells provide this exact context, and the shared\n * sub-components (`Drawer.CloseButton`, `Drawer.Header`) consume it — so there\n * must be exactly one context identity, or the close button can't see its\n * provider.\n */\nexport const DrawerContext = React.createContext<TypeDrawerContext>({\n isLocked: false,\n setIsLocked: () => {},\n hasActionRail: false,\n});\n\n// Utility for merging class names properly. Copied from DrawerTailwind.tsx —\n// `cn` is NOT exported from @sproutsocial/seeds-react-utilities, so each\n// Tailwind component carries its own copy.\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\nexport const DrawerCloseButton = (props: TypeDrawerCloseButtonProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext) ?? null;\n }\n\n return (\n <Button\n appearance=\"pill\"\n aria-label={drawerContext.closeButtonLabel}\n onClick={drawerContext.onClose}\n {...props}\n >\n {props.children || <Icon aria-hidden name=\"x-outline\" />}\n </Button>\n );\n};\n\n/**\n * Styled-components header — the always-styled implementation, preserved for\n * backward compatibility. The hybrid router below sends consumers here whenever\n * they pass styled-system props (e.g. `<Drawer.Header alignItems=\"center\">`) or\n * a `styled()` extension, so the full `Box` prop surface keeps working.\n */\nconst DrawerHeaderStyled = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (render) {\n return render(drawerContext);\n }\n\n return (\n <Box\n display=\"flex\"\n flex=\"0 0 auto\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n pt={400}\n px={450}\n {...rest}\n >\n {children || (\n <>\n <Text\n as=\"h2\"\n fontSize={400}\n fontWeight=\"semibold\"\n color=\"text.headline\"\n id={id}\n >\n {title}\n </Text>\n {!drawerContext.hasActionRail && <DrawerCloseButton />}\n </>\n )}\n </Box>\n );\n};\n\n/**\n * Tailwind/CSS-class header — the preferred path, routed to by the hybrid when\n * the consumer passes no styled-system props. Renders a plain `<div>` with the\n * `seeds-drawer-header` classes from `drawer.css` instead of a styled `Box`.\n * The `render` prop is handled by the hybrid before reaching here.\n */\nconst DrawerHeaderTailwind = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n const { className, ...domRest } = rest as {\n className?: string;\n } & Record<string, unknown>;\n\n return (\n <div className={cn(\"seeds-drawer-header\", className)} {...domRest}>\n {children || (\n <>\n <h2 className=\"seeds-drawer-header-title\" id={id}>\n {title}\n </h2>\n {!drawerContext.hasActionRail && <DrawerCloseButton />}\n </>\n )}\n </div>\n );\n};\n\n/**\n * Hybrid header router. Chooses the styled path when the consumer passes\n * styled-system props or a `styled()` extension, else the Tailwind path —\n * independent of the root Drawer's routing. The `render` prop short-circuits\n * before any routing, matching the original always-styled behaviour.\n */\nexport const DrawerHeader = (props: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext);\n }\n\n const { title, id, children, render, ...rest } = props;\n\n if (needsStyledComponents(rest)) {\n return <DrawerHeaderStyled {...props} />;\n }\n\n return <DrawerHeaderTailwind {...props} />;\n};\n\n/**\n * Styled-components content — the always-styled implementation, preserved for\n * backward compatibility. The hybrid router sends consumers here whenever they\n * pass styled-system props (e.g. `<Drawer.Content color=\"text.body\">`).\n */\nconst DrawerContentStyled = ({\n children,\n ...rest\n}: TypeDrawerContentProps) => (\n <Content\n height=\"100%\"\n p={450}\n color=\"text.body\"\n data-drawer-content=\"\"\n {...rest}\n >\n {children}\n </Content>\n);\n\n/**\n * Tailwind/CSS-class content — the preferred path. Renders a plain\n * `<div data-drawer-content>` with the `seeds-drawer-content` class from\n * `drawer.css` instead of a styled `Box`.\n */\nconst DrawerContentTailwind = ({\n children,\n ...rest\n}: TypeDrawerContentProps) => {\n const { className, ...domRest } = rest as {\n className?: string;\n } & Record<string, unknown>;\n\n return (\n <div\n className={cn(\"seeds-drawer-content\", className)}\n data-drawer-content=\"\"\n {...domRest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Hybrid content router. Chooses the styled path when the consumer passes\n * styled-system props or a `styled()` extension, else the Tailwind path.\n */\nexport const DrawerContent = (props: TypeDrawerContentProps) => {\n const { children, ...rest } = props;\n\n if (needsStyledComponents(rest)) {\n return <DrawerContentStyled {...props} />;\n }\n\n return <DrawerContentTailwind {...props} />;\n};\n\nDrawerHeader.displayName = \"Drawer.Header\";\nDrawerContent.displayName = \"Drawer.Content\";\nDrawerCloseButton.displayName = \"Drawer.CloseButton\";\n\n/**\n * Root-level Drawer logic shared by both shells. Centralising it here (rather\n * than duplicating it in each shell) guarantees the two implementations stay\n * behaviourally identical — the esc-key lock and exit-freeze logic is exactly\n * what the lock/close tests exercise.\n */\nexport const useDrawerShell = (props: TypeDrawerProps) => {\n const {\n children,\n closeButtonLabel,\n direction = \"right\",\n disableCloseOnClickOutside = false,\n id,\n modal = false,\n open,\n offset = 0,\n onClose,\n zIndex = 7,\n width = 600,\n snapPoints,\n defaultSnapPoint,\n snapPoint,\n onSnapPointChange,\n snapToSequentialPoints,\n actions,\n actionsInHeader = false,\n ...rest\n } = props;\n\n const isMobile = useIsMobile();\n const effectiveDirection = isMobile ? \"bottom\" : direction;\n const effectiveSnapPoints =\n effectiveDirection === \"bottom\" ? snapPoints : undefined;\n const hasSnapPoints = !!effectiveSnapPoints && effectiveSnapPoints.length > 0;\n const hasActionRail =\n isMobile && !actionsInHeader && !!actions && actions.length > 0;\n const [isLocked, setIsLocked] = React.useState(false);\n\n const ariaLabelledBy = rest[\"aria-labelledby\"];\n const ariaLabel = rest[\"aria-label\"];\n React.useEffect(() => {\n if (process.env.NODE_ENV !== \"production\") {\n if (!ariaLabelledBy && !ariaLabel) {\n console.warn(\n \"[Drawer] Missing accessible name. Add aria-labelledby pointing to your Drawer.Header id, or aria-label, so screen readers can identify the dialog.\"\n );\n }\n }\n }, [ariaLabelledBy, ariaLabel]);\n // Keep a ref so the onOpenChange callback always sees the current isLocked\n // value without needing to be re-created on each render.\n const isLockedRef = React.useRef(isLocked);\n isLockedRef.current = isLocked;\n\n // Freeze the last-rendered children during the exit transition so consumers\n // that conditionally render content (e.g. {isOpen && <Content />}) don't\n // produce an empty drawer shell while Base UI animates the popup out.\n const prevChildrenRef = React.useRef<React.ReactNode>(null);\n if (open) {\n prevChildrenRef.current = children;\n }\n const renderedChildren = open ? children : prevChildrenRef.current;\n\n const rootProps: Omit<\n React.ComponentProps<typeof BaseDrawer.Root>,\n \"children\"\n > = {\n open,\n onOpenChange: (isOpen, eventDetails) => {\n if (!isOpen) {\n if (isLockedRef.current && eventDetails.reason === \"escape-key\") {\n return;\n }\n onClose();\n }\n },\n disablePointerDismissal: disableCloseOnClickOutside,\n swipeDirection:\n effectiveDirection === \"bottom\" ? \"down\" : effectiveDirection,\n modal,\n snapPoints: effectiveSnapPoints,\n defaultSnapPoint,\n snapPoint,\n onSnapPointChange: onSnapPointChange\n ? (sp) => onSnapPointChange(sp)\n : undefined,\n snapToSequentialPoints,\n };\n\n return {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n isLocked,\n setIsLocked,\n renderedChildren,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n closeButtonLabel,\n onClose,\n actions,\n };\n};\n\nexport type TypeDrawerShell = ReturnType<typeof useDrawerShell>;\n\n/**\n * The popup contents shared by both shells: the optional mobile action rail and\n * the context providers wrapping the rendered children. Only the popup wrapper\n * and drag handle differ between the Tailwind and styled paths — everything\n * inside the popup is identical, so it lives here.\n */\nexport const DrawerPopupContents = ({ shell }: { shell: TypeDrawerShell }) => {\n const {\n hasActionRail,\n closeButtonLabel,\n onClose,\n actions,\n isLocked,\n setIsLocked,\n renderedChildren,\n } = shell;\n\n return (\n <>\n {hasActionRail && actions && (\n <ActionRail isMobile aria-label=\"Drawer quick actions\">\n <ActionRailButton\n aria-label={closeButtonLabel}\n onClick={onClose}\n data-qa-drawer-rail-close\n >\n <Icon aria-hidden name=\"x-outline\" />\n </ActionRailButton>\n {actions.map((action, i) => (\n <ActionRailButton\n key={i}\n aria-label={action[\"aria-label\"]}\n onClick={action.onClick}\n disabled={action.disabled}\n >\n {action.iconName && <Icon aria-hidden name={action.iconName} />}\n </ActionRailButton>\n ))}\n </ActionRail>\n )}\n <DisablePortalToBodyContext.Provider value={true}>\n <DrawerContext.Provider\n value={{\n onClose,\n closeButtonLabel,\n isLocked,\n setIsLocked,\n hasActionRail,\n }}\n >\n {renderedChildren}\n </DrawerContext.Provider>\n </DisablePortalToBodyContext.Provider>\n </>\n );\n};\n","import { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport { useDrawerShell, DrawerPopupContents } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\nimport type { CSSProperties } from \"react\";\n\n// Utility for merging class names properly. Copied from ButtonTailwind.tsx —\n// `cn` is NOT exported from @sproutsocial/seeds-react-utilities, so each\n// Tailwind component carries its own copy.\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\n/**\n * Tailwind/CSS-class shell. The preferred path — routed to by `DrawerHybrid`\n * whenever the consumer passes no styled-system props. Renders the real Base UI\n * primitives (Backdrop/Viewport/Popup) with component-scoped classes from\n * `drawer.css`; the runtime numerics (`width`, `offset`, `zIndex`) are applied\n * as direct inline styles so drag/swipe/snap/portal behaviour is preserved.\n */\nconst DrawerTailwind = (props: TypeDrawerProps) => {\n const shell = useDrawerShell(props);\n const {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n } = shell;\n\n // `className` and `style` are public <div> props (TypeDrawerProps extends\n // ComponentPropsWithoutRef<\"div\">) that arrive via `rest`. Pull them out so\n // they MERGE with the popup's computed classes/geometry instead of\n // overwriting them — matching the styled-components path, where a consumer\n // className is appended to the generated class and an inline style wins over\n // the generated width.\n const { className, style, ...domRest } = rest as {\n className?: string;\n style?: CSSProperties;\n } & Record<string, unknown>;\n\n return (\n <BaseDrawer.Root {...rootProps}>\n <BaseDrawer.Portal>\n <BaseDrawer.Backdrop\n data-testid=\"drawer-backdrop\"\n className=\"seeds-drawer-backdrop\"\n />\n <BaseDrawer.Viewport\n className={cn(\"seeds-drawer-viewport\", {\n \"seeds-drawer-viewport--snap\": hasSnapPoints,\n })}\n >\n <BaseDrawer.Popup\n initialFocus\n data-qa-drawer={id}\n data-qa-drawer-isopen={open}\n {...domRest}\n className={cn(\n \"seeds-drawer-popup\",\n effectiveDirection === \"bottom\"\n ? \"seeds-drawer-popup--bottom\"\n : \"seeds-drawer-popup--side\",\n effectiveDirection === \"right\" && \"seeds-drawer-popup--right\",\n effectiveDirection === \"left\" && \"seeds-drawer-popup--left\",\n {\n \"seeds-drawer-popup--snap\": hasSnapPoints,\n \"seeds-drawer-popup--action-rail\": hasActionRail,\n },\n // Consumer className folded in last so it appends to (not\n // replaces) the component classes.\n className\n )}\n style={{\n // z-index is always inline (runtime numeric, mirrors styles.ts).\n zIndex,\n // Side drawers carry their width/offset as direct inline styles —\n // runtime numerics, and required for the jsdom `toHaveStyle`\n // assertions. Bottom drawers derive width/position from the class.\n ...(effectiveDirection === \"right\"\n ? { width: `${width}px`, right: `${offset}px` }\n : effectiveDirection === \"left\"\n ? { width: `${width}px`, left: `${offset}px` }\n : {}),\n // Consumer style folded in last so it wins over the computed\n // geometry, matching the styled-components inline-style semantics.\n ...style,\n }}\n >\n {effectiveDirection === \"bottom\" && (\n <div aria-hidden className=\"seeds-drawer-drag-handle\" />\n )}\n <DrawerPopupContents shell={shell} />\n </BaseDrawer.Popup>\n </BaseDrawer.Viewport>\n </BaseDrawer.Portal>\n </BaseDrawer.Root>\n );\n};\n\nexport default DrawerTailwind;\n","import DrawerHybrid from \"./DrawerHybrid\";\n\n/**\n * Drawer component. Automatically routes between the Tailwind implementation\n * (preferred) and the styled-components implementation (for consumers using\n * system props or a `styled()` extension). The default export carries the\n * `.Header`, `.Content`, and `.CloseButton` statics.\n */\nexport { DrawerContext } from \"./DrawerShared\";\nexport default DrawerHybrid;\n","import * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\nimport type { TypeIconName } from \"@sproutsocial/seeds-react-icon\";\n\ntype DrawerAnimationDirection = \"left\" | \"right\" | \"bottom\";\n\n/**\n * Action button shown in the mobile rail above a bottom-sheet drawer.\n * Mirrors `TypeModalActionProps` so consumers can share the same array shape.\n */\nexport type TypeDrawerActionProps = {\n /** Accessible label for the action button. */\n \"aria-label\": string;\n /** Icon name from the Seeds icon set. */\n iconName?: TypeIconName;\n /** Click handler. */\n onClick?: () => void;\n /** Disable the action. */\n disabled?: boolean;\n};\n\n/**\n * A snap point the bottom drawer can rest at.\n * - Numbers 0–1: fraction of viewport height\n * - Numbers > 1: pixels\n * - Strings: CSS lengths in `px` or `rem` (e.g. `\"480px\"`, `\"30rem\"`)\n */\nexport type TypeDrawerSnapPoint = number | string;\n\nexport interface TypeDrawerContext {\n /** Callback for close button */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClose?: () => any;\n\n /** aria-label for drawer close button */\n closeButtonLabel?: string;\n /**\n * isLocked and setIsLocked are used when a Drawer contains other components (like Menu) that also\n * listen for Escape key events. By locking the Drawer, we can prevent conflicts\n * where multiple components try to handle the same keydown event.\n */\n isLocked: boolean;\n setIsLocked: (locked: boolean) => void;\n /**\n * True when the Drawer is rendering an `ActionRail` above the popup. The\n * default `Drawer.Header` reads this to omit its built-in close button so the\n * rail can own the close affordance.\n */\n hasActionRail?: boolean;\n}\n// TODO: Should the render prop be a React.FC?\nexport interface TypeDrawerCloseButtonProps\n extends Omit<TypeButtonProps, \"children\"> {\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the on-close behavior. */\n render?: React.FC<TypeDrawerContext>;\n children?: React.ReactNode;\n}\n\nexport interface TypeDrawerHeaderProps extends TypeBoxProps {\n title?: string;\n /**\n * When children are provided, `<Drawer.CloseButton />` is NOT rendered automatically.\n * You must include it yourself inside children to preserve keyboard accessibility.\n */\n children?: React.ReactNode;\n\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the appearance of the header. */\n render?: React.FC<TypeDrawerContext>;\n}\n\nexport interface TypeDrawerProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"div\">, \"color\"> {\n children: React.ReactNode;\n\n /** Label for the close button. Usually this should be \"Close\" */\n closeButtonLabel: string;\n\n /** Whether the drawer slides in from the left or right side of the screen */\n direction?: DrawerAnimationDirection;\n\n /** In some cases, you may not want the user to be able to click outside of the drawer to close it. You can disable that with this prop. */\n disableCloseOnClickOutside?: boolean;\n\n /**\n * When true, siblings are inerted while the drawer is open — appropriate for forms or settings\n * panels where page interaction should be blocked.\n * Defaults to false to preserve the original non-modal behavior where the rest of the page\n * remains interactive (side info panels, notification slide-outs, persistent inspectors, etc.).\n */\n modal?: boolean;\n /** Optional id used for data-qa-drawer attributes */\n id?: string;\n open: boolean;\n offset?: number;\n onClose: () => void;\n zIndex?: number;\n width?: number;\n\n /**\n * Snap points the drawer can rest at when swiped. Only applied to bottom drawers.\n * Numbers 0–1 are viewport-height fractions; numbers > 1 are pixels; strings accept\n * `px`/`rem` (e.g. `\"480px\"`, `\"30rem\"`). Order matters — the last entry is the\n * \"expanded\" state and gets a `data-expanded` attribute on the popup.\n */\n snapPoints?: TypeDrawerSnapPoint[];\n\n /** Initial snap point for uncontrolled use. */\n defaultSnapPoint?: TypeDrawerSnapPoint | null;\n\n /** Controlled active snap point. Pair with `onSnapPointChange`. */\n snapPoint?: TypeDrawerSnapPoint | null;\n\n /** Fires when the active snap point changes (drag release, programmatic update, etc.). */\n onSnapPointChange?: (snapPoint: TypeDrawerSnapPoint | null) => void;\n\n /**\n * When true, fast swipes can't skip past adjacent snap points — drag distance alone\n * determines the next stop. Defaults to base-ui's `false` (velocity-based skipping).\n */\n snapToSequentialPoints?: boolean;\n\n /**\n * Action buttons shown in a floating rail above the drawer on mobile (the\n * bottom-sheet rendering). The rail also owns the close button — when this\n * prop is provided, the default `Drawer.Header` omits its built-in close\n * button so the rail can render it instead. Ignored on desktop side drawers.\n */\n actions?: TypeDrawerActionProps[];\n\n /**\n * Opt out of the floating rail and keep the actions inside `Drawer.Header`\n * (the pre-rail behavior). Useful for nested bottom sheets and snap-point\n * drawers where the rail-above placement would collide with surrounding UI\n * or fall off-screen at the highest snap point. Defaults to `false`.\n *\n * When `true`, the Drawer does NOT render the rail; consumers are\n * responsible for rendering action buttons (and the close button) inside\n * their `Drawer.Header`.\n */\n actionsInHeader?: boolean;\n}\n\nexport interface TypeDrawerContentProps extends TypeBoxProps {\n children?: React.ReactNode;\n}\n","import Drawer, { DrawerContext } from \"./Drawer\";\n\nexport default Drawer;\nexport { Drawer, DrawerContext };\nexport * from \"./DrawerTypes\";\nexport {\n ActionRail,\n ActionRailButton,\n RAIL_BUTTON_SIZE,\n RAIL_BUTTON_HEIGHT,\n RAIL_OFFSET,\n RAIL_GAP,\n} from \"./ActionRail\";\nexport type {\n TypeActionRailProps,\n TypeActionRailButtonProps,\n} from \"./ActionRail\";\n"],"mappings":"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","names":["BaseDrawer","styled","React","styled","jsx","styled","styled","React","Box","jsx","Box","jsx","jsxs","BaseDrawer","BaseDrawer","jsx","jsxs","cn","BaseDrawer","jsx"]}
package/dist/index.d.mts CHANGED
@@ -127,11 +127,11 @@ interface TypeDrawerContentProps extends TypeBoxProps {
127
127
  declare const DrawerHybrid: {
128
128
  (props: TypeDrawerProps): react_jsx_runtime.JSX.Element;
129
129
  Header: {
130
- ({ title, id, children, render, ...rest }: TypeDrawerHeaderProps): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
130
+ (props: TypeDrawerHeaderProps): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
131
131
  displayName: string;
132
132
  };
133
133
  Content: {
134
- ({ children, ...rest }: TypeDrawerContentProps): react_jsx_runtime.JSX.Element;
134
+ (props: TypeDrawerContentProps): react_jsx_runtime.JSX.Element;
135
135
  displayName: string;
136
136
  };
137
137
  CloseButton: {
package/dist/index.d.ts CHANGED
@@ -127,11 +127,11 @@ interface TypeDrawerContentProps extends TypeBoxProps {
127
127
  declare const DrawerHybrid: {
128
128
  (props: TypeDrawerProps): react_jsx_runtime.JSX.Element;
129
129
  Header: {
130
- ({ title, id, children, render, ...rest }: TypeDrawerHeaderProps): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
130
+ (props: TypeDrawerHeaderProps): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
131
131
  displayName: string;
132
132
  };
133
133
  Content: {
134
- ({ children, ...rest }: TypeDrawerContentProps): react_jsx_runtime.JSX.Element;
134
+ (props: TypeDrawerContentProps): react_jsx_runtime.JSX.Element;
135
135
  displayName: string;
136
136
  };
137
137
  CloseButton: {
package/dist/index.js CHANGED
@@ -43,7 +43,7 @@ __export(index_exports, {
43
43
  module.exports = __toCommonJS(index_exports);
44
44
 
45
45
  // src/DrawerHybrid.tsx
46
- var import_seeds_react_system_props2 = require("@sproutsocial/seeds-react-system-props");
46
+ var import_seeds_react_system_props3 = require("@sproutsocial/seeds-react-system-props");
47
47
 
48
48
  // src/DrawerStyled.tsx
49
49
  var import_drawer3 = require("@base-ui/react/drawer");
@@ -335,6 +335,7 @@ var import_seeds_react_icon = __toESM(require("@sproutsocial/seeds-react-icon"))
335
335
  var import_seeds_react_text = __toESM(require("@sproutsocial/seeds-react-text"));
336
336
  var import_seeds_react_hooks = require("@sproutsocial/seeds-react-hooks");
337
337
  var import_seeds_react_portal = require("@sproutsocial/seeds-react-portal");
338
+ var import_seeds_react_system_props2 = require("@sproutsocial/seeds-react-system-props");
338
339
  var import_jsx_runtime3 = require("react/jsx-runtime");
339
340
  var DrawerContext = React3.createContext({
340
341
  isLocked: false,
@@ -342,6 +343,22 @@ var DrawerContext = React3.createContext({
342
343
  },
343
344
  hasActionRail: false
344
345
  });
346
+ function cn(...inputs) {
347
+ const classes = [];
348
+ for (const input of inputs) {
349
+ if (!input) continue;
350
+ if (typeof input === "string") {
351
+ classes.push(input);
352
+ } else if (typeof input === "object") {
353
+ for (const [key, value] of Object.entries(input)) {
354
+ if (value) {
355
+ classes.push(key);
356
+ }
357
+ }
358
+ }
359
+ }
360
+ return classes.join(" ");
361
+ }
345
362
  var DrawerCloseButton = (props) => {
346
363
  const drawerContext = (0, import_react.useContext)(DrawerContext);
347
364
  if (props.render) {
@@ -358,7 +375,7 @@ var DrawerCloseButton = (props) => {
358
375
  }
359
376
  );
360
377
  };
361
- var DrawerHeader = ({
378
+ var DrawerHeaderStyled = ({
362
379
  title = "",
363
380
  id = void 0,
364
381
  children,
@@ -396,7 +413,32 @@ var DrawerHeader = ({
396
413
  }
397
414
  );
398
415
  };
399
- var DrawerContent = ({
416
+ var DrawerHeaderTailwind = ({
417
+ title = "",
418
+ id = void 0,
419
+ children,
420
+ render,
421
+ ...rest
422
+ }) => {
423
+ const drawerContext = (0, import_react.useContext)(DrawerContext);
424
+ const { className, ...domRest } = rest;
425
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: cn("seeds-drawer-header", className), ...domRest, children: children || /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
426
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "seeds-drawer-header-title", id, children: title }),
427
+ !drawerContext.hasActionRail && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DrawerCloseButton, {})
428
+ ] }) });
429
+ };
430
+ var DrawerHeader = (props) => {
431
+ const drawerContext = (0, import_react.useContext)(DrawerContext);
432
+ if (props.render) {
433
+ return props.render(drawerContext);
434
+ }
435
+ const { title, id, children, render, ...rest } = props;
436
+ if ((0, import_seeds_react_system_props2.needsStyledComponents)(rest)) {
437
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DrawerHeaderStyled, { ...props });
438
+ }
439
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DrawerHeaderTailwind, { ...props });
440
+ };
441
+ var DrawerContentStyled = ({
400
442
  children,
401
443
  ...rest
402
444
  }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -410,6 +452,28 @@ var DrawerContent = ({
410
452
  children
411
453
  }
412
454
  );
455
+ var DrawerContentTailwind = ({
456
+ children,
457
+ ...rest
458
+ }) => {
459
+ const { className, ...domRest } = rest;
460
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
461
+ "div",
462
+ {
463
+ className: cn("seeds-drawer-content", className),
464
+ "data-drawer-content": "",
465
+ ...domRest,
466
+ children
467
+ }
468
+ );
469
+ };
470
+ var DrawerContent = (props) => {
471
+ const { children, ...rest } = props;
472
+ if ((0, import_seeds_react_system_props2.needsStyledComponents)(rest)) {
473
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DrawerContentStyled, { ...props });
474
+ }
475
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DrawerContentTailwind, { ...props });
476
+ };
413
477
  DrawerHeader.displayName = "Drawer.Header";
414
478
  DrawerContent.displayName = "Drawer.Content";
415
479
  DrawerCloseButton.displayName = "Drawer.CloseButton";
@@ -589,7 +653,7 @@ var DrawerStyled_default = DrawerStyled;
589
653
  // src/DrawerTailwind.tsx
590
654
  var import_drawer4 = require("@base-ui/react/drawer");
591
655
  var import_jsx_runtime5 = require("react/jsx-runtime");
592
- function cn(...inputs) {
656
+ function cn2(...inputs) {
593
657
  const classes = [];
594
658
  for (const input of inputs) {
595
659
  if (!input) continue;
@@ -631,7 +695,7 @@ var DrawerTailwind = (props) => {
631
695
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
632
696
  import_drawer4.Drawer.Viewport,
633
697
  {
634
- className: cn("seeds-drawer-viewport", {
698
+ className: cn2("seeds-drawer-viewport", {
635
699
  "seeds-drawer-viewport--snap": hasSnapPoints
636
700
  }),
637
701
  children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
@@ -641,7 +705,7 @@ var DrawerTailwind = (props) => {
641
705
  "data-qa-drawer": id,
642
706
  "data-qa-drawer-isopen": open,
643
707
  ...domRest,
644
- className: cn(
708
+ className: cn2(
645
709
  "seeds-drawer-popup",
646
710
  effectiveDirection === "bottom" ? "seeds-drawer-popup--bottom" : "seeds-drawer-popup--side",
647
711
  effectiveDirection === "right" && "seeds-drawer-popup--right",
@@ -706,7 +770,7 @@ var DrawerHybrid = (props) => {
706
770
  rest[key] = props[key];
707
771
  }
708
772
  }
709
- if ((0, import_seeds_react_system_props2.hasStyledProps)(rest)) {
773
+ if ((0, import_seeds_react_system_props3.hasStyledProps)(rest)) {
710
774
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DrawerStyled_default, { ...props });
711
775
  }
712
776
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DrawerTailwind_default, { ...props });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/DrawerHybrid.tsx","../src/DrawerStyled.tsx","../src/styles.ts","../src/ActionRail/ActionRail.tsx","../src/ActionRail/ActionRailButton.tsx","../src/DrawerShared.tsx","../src/DrawerTailwind.tsx","../src/Drawer.tsx","../src/DrawerTypes.ts"],"sourcesContent":["import Drawer, { DrawerContext } from \"./Drawer\";\n\nexport default Drawer;\nexport { Drawer, DrawerContext };\nexport * from \"./DrawerTypes\";\nexport {\n ActionRail,\n ActionRailButton,\n RAIL_BUTTON_SIZE,\n RAIL_BUTTON_HEIGHT,\n RAIL_OFFSET,\n RAIL_GAP,\n} from \"./ActionRail\";\nexport type {\n TypeActionRailProps,\n TypeActionRailButtonProps,\n} from \"./ActionRail\";\n","/**\n * Hybrid Drawer component.\n * Automatically chooses between the Tailwind shell (preferred) and the\n * styled-components shell based on props, mirroring `ButtonHybrid`. When a\n * consumer passes styled-system props (`px`, `color`, `height`, …) the styled\n * path is used so existing styling keeps working; otherwise the Tailwind path\n * renders.\n */\nimport { hasStyledProps } from \"@sproutsocial/seeds-react-system-props\";\nimport DrawerStyled from \"./DrawerStyled\";\nimport DrawerTailwind from \"./DrawerTailwind\";\nimport { DrawerHeader, DrawerContent, DrawerCloseButton } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\n\n// Props the Drawer owns semantically. They must be stripped before the\n// `hasStyledProps` check so a Drawer-specific prop never trips the styled\n// router — most importantly `width`, which `hasStyledProps` also treats as a\n// styled-system prop. Anything left in `rest` is a true pass-through/system\n// prop and is what the routing decision is based on.\nconst DRAWER_OWN_PROPS: readonly string[] = [\n \"children\",\n \"closeButtonLabel\",\n \"direction\",\n \"disableCloseOnClickOutside\",\n \"id\",\n \"modal\",\n \"open\",\n \"offset\",\n \"onClose\",\n \"zIndex\",\n \"width\",\n \"snapPoints\",\n \"defaultSnapPoint\",\n \"snapPoint\",\n \"onSnapPointChange\",\n \"snapToSequentialPoints\",\n \"actions\",\n \"actionsInHeader\",\n];\n\nconst DrawerHybrid = (props: TypeDrawerProps) => {\n const rest: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n if (!DRAWER_OWN_PROPS.includes(key)) {\n rest[key] = (props as unknown as Record<string, unknown>)[key];\n }\n }\n\n if (hasStyledProps(rest)) {\n return <DrawerStyled {...props} />;\n }\n\n // Use the Tailwind version (preferred - better performance).\n return <DrawerTailwind {...props} />;\n};\n\nDrawerHybrid.Header = DrawerHeader;\nDrawerHybrid.Content = DrawerContent;\nDrawerHybrid.CloseButton = DrawerCloseButton;\n\nexport default DrawerHybrid;\n","import { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport {\n StyledPopup,\n StyledBackdrop,\n StyledViewport,\n DragHandle,\n} from \"./styles\";\nimport { useDrawerShell, DrawerPopupContents } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\n\n/**\n * Legacy styled-components shell. Routed to by `DrawerHybrid` whenever the\n * consumer passes styled-system props (or a `styled()` extension). Renders the\n * exact styled wrappers from `styles.ts` so behaviour is unchanged.\n */\nconst DrawerStyled = (props: TypeDrawerProps) => {\n const shell = useDrawerShell(props);\n const {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n } = shell;\n\n return (\n <BaseDrawer.Root {...rootProps}>\n <BaseDrawer.Portal>\n <StyledBackdrop data-testid=\"drawer-backdrop\" />\n <StyledViewport $hasSnapPoints={hasSnapPoints}>\n <StyledPopup\n initialFocus={true}\n $width={width}\n $offset={offset}\n $direction={effectiveDirection}\n $zIndex={zIndex}\n $hasSnapPoints={hasSnapPoints}\n $hasActionRail={hasActionRail}\n data-qa-drawer={id}\n data-qa-drawer-isopen={open}\n {...rest}\n >\n {effectiveDirection === \"bottom\" && <DragHandle aria-hidden />}\n <DrawerPopupContents shell={shell} />\n </StyledPopup>\n </StyledViewport>\n </BaseDrawer.Portal>\n </BaseDrawer.Root>\n );\n};\n\nexport default DrawerStyled;\n","import { Drawer } from \"@base-ui/react/drawer\";\nimport styled from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeSystemCommonProps } from \"@sproutsocial/seeds-react-system-props\";\nimport { MOTION_DURATION_MEDIUM } from \"@sproutsocial/seeds-motion/unitless\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { RAIL_BUTTON_HEIGHT, RAIL_OFFSET } from \"./ActionRail\";\n\n// Total vertical space the action rail occupies above the popup\n// (rail height + gap between rail and popup). When the drawer animates\n// closed, the popup must translate this much further so the rail also\n// leaves the viewport instead of flashing at the bottom edge.\nconst ACTION_RAIL_OUTSET = RAIL_BUTTON_HEIGHT + RAIL_OFFSET;\n\nexport const Content = styled(Box)`\n overflow-y: auto;\n`;\n\nexport const StyledViewport = styled(Drawer.Viewport)<{\n $hasSnapPoints: boolean;\n}>`\n ${(props) =>\n props.$hasSnapPoints\n ? `\n position: fixed;\n inset: 0;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n touch-action: none;\n /* The viewport spans the whole screen but the popup only fills part of\n it. Letting clicks fall through the empty area means a nested\n snap-point drawer doesn't block selection/interaction with the\n parent drawer visible underneath. The popup re-enables events. */\n pointer-events: none;\n `\n : \"\"}\n`;\n\ninterface StyledPopupProps extends TypeSystemCommonProps {\n $width: number;\n $offset: number;\n $direction: \"left\" | \"right\" | \"bottom\";\n $zIndex: number;\n $hasSnapPoints: boolean;\n $hasActionRail: boolean;\n}\n\nexport const StyledPopup = styled(Drawer.Popup)<StyledPopupProps>`\n display: flex;\n flex-direction: column;\n position: fixed;\n background-color: ${(props) => props.theme.colors.container.background.base};\n z-index: ${(props) => props.$zIndex};\n filter: blur(0);\n transition: transform ${MOTION_DURATION_MEDIUM}s ease,\n border-radius ${MOTION_DURATION_MEDIUM}s ease,\n height ${MOTION_DURATION_MEDIUM}s ease;\n\n /* Always-on opacity transition so content fades smoothly both into and out of stacked state */\n > * {\n transition: opacity ${MOTION_DURATION_MEDIUM}s ease;\n }\n\n ${(props) => {\n if (props.$direction === \"bottom\") {\n if (props.$hasSnapPoints) {\n // Snap-points popup follows base-ui's reference layout. Critical details:\n // - box-sizing: border-box so offsetHeight ignores padding-bottom; otherwise\n // base-ui's ResizeObserver feedback (padding-bottom driven by snap offset)\n // grows popupHeight on every measurement and snap math diverges.\n // - height (not max-height) so popupHeight is large enough that base-ui's\n // snap offset = max(0, popupHeight - snapHeight) distinguishes snap points;\n // with short content + max-height it collapses to 0 for every snap.\n // - position: relative inside the flex-end Viewport so base-ui can measure\n // popupHeight vs viewportHeight for snap math.\n return `\n box-sizing: border-box;\n position: relative;\n width: 100%;\n height: calc(100dvh - 1rem);\n padding-bottom: max(0px, calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));\n overflow: visible;\n touch-action: none;\n /* Counterpart to the viewport's pointer-events: none — the popup\n itself stays interactive. */\n pointer-events: auto;\n border-radius: ${props.theme.radii[800]} ${props.theme.radii[800]} 0 0;\n box-shadow: 0px -8px 16px rgba(39,51,51,.25);\n transform: translateY(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));\n will-change: transform;\n transition:\n transform ${MOTION_DURATION_MEDIUM}s cubic-bezier(0.32, 0.72, 0, 1),\n box-shadow ${MOTION_DURATION_MEDIUM}s cubic-bezier(0.32, 0.72, 0, 1);\n `;\n }\n return `\n --bleed: 3rem;\n --stack-scale: 1;\n --translate-y: 0px;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100%;\n height: calc(90vh + var(--bleed));\n margin-bottom: calc(-1 * var(--bleed));\n border-radius: ${props.theme.radii[800]} ${props.theme.radii[800]} 0 0;\n transform: translateY(var(--translate-y)) scale(var(--stack-scale));\n transform-origin: 50% calc(100% - var(--bleed));\n box-shadow: 0px -8px 16px rgba(39,51,51,.25);\n `;\n }\n return `\n top: 0;\n height: 100%;\n width: ${props.$width}px;\n ${\n props.$direction === \"right\"\n ? `right: ${props.$offset}px;`\n : `left: ${props.$offset}px;`\n }\n box-shadow: ${props.theme.shadows.medium};\n `;\n }}\n\n &[data-starting-style],\n &[data-ending-style] {\n ${(props) => {\n if (props.$direction !== \"bottom\") {\n return `transform: translateX(${\n props.$direction === \"right\" ? \"100%\" : \"-100%\"\n });`;\n }\n // The action rail lives above the popup (position: absolute,\n // bottom: 100% + RAIL_OFFSET). Translating the popup by its own\n // height alone leaves the rail visible at the bottom of the\n // viewport during enter/exit, so we add the rail's outset here.\n const railOffset = props.$hasActionRail\n ? ` + ${ACTION_RAIL_OUTSET}px`\n : \"\";\n if (props.$hasSnapPoints) {\n return `\n transform: translateY(calc(100% + 2px${railOffset}));\n padding-bottom: 0;\n `;\n }\n return `transform: translateY(calc(100% - var(--bleed) + 2px${railOffset}));`;\n }}\n }\n\n &[data-swiping],\n &[data-nested-drawer-swiping] {\n transition-duration: 0ms;\n }\n\n &[data-nested-drawer-open] {\n border-radius: ${(props) => props.theme.radii[800]};\n\n ${(props) => {\n if (props.$direction === \"bottom\") {\n // Snap-point drawers don't participate in the stacked-bottom-sheet\n // animation: the stack math overwrites --translate-y and clips overflow,\n // which collides with base-ui's snap-offset transform.\n if (props.$hasSnapPoints) return \"\";\n return `\n --stack-step: 0.05;\n --stack-progress: clamp(0, var(--drawer-swipe-progress), 1);\n /* Override default vars; base transform rule picks them up automatically */\n --stack-scale: max(0, calc(\n 1 - (var(--nested-drawers) * var(--stack-step))\n + (var(--stack-step) * var(--stack-progress))\n ));\n --stack-shrink: calc(1 - var(--stack-scale));\n --stack-height: max(0px, calc(\n var(--drawer-frontmost-height, var(--drawer-height)) - var(--bleed)\n ));\n --stack-peek-offset: max(0px, calc(\n (var(--nested-drawers) - var(--stack-progress)) * 1rem\n ));\n --translate-y: calc(\n var(--drawer-swipe-movement-y)\n - var(--stack-peek-offset)\n - (var(--stack-shrink) * var(--stack-height))\n );\n height: calc(var(--stack-height) + var(--bleed));\n overflow: hidden;\n `;\n }\n return `\n transform: translateY(calc(var(--nested-drawers) * -20px))\n scale(calc(1 - var(--nested-drawers) * 0.08));\n transform-origin: top center;\n `;\n }}\n\n ${(props) =>\n props.$hasSnapPoints\n ? \"\"\n : `\n > * {\n opacity: 0;\n }\n `}\n }\n\n &[data-nested-drawer-open][data-nested-drawer-swiping] {\n > * {\n opacity: 1;\n }\n }\n\n ${COMMON}\n`;\n\nexport const DragHandle = styled.div`\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n width: 36px;\n height: 4px;\n border-radius: 2px;\n background-color: ${(props) => props.theme.colors.container.border.base};\n`;\n\nexport const StyledBackdrop = styled(Drawer.Backdrop)`\n position: fixed;\n inset: 0;\n background: transparent;\n pointer-events: none;\n`;\n","import * as React from \"react\";\nimport styled, { css } from \"styled-components\";\n\nexport const RAIL_BUTTON_SIZE = 44;\nexport const RAIL_BUTTON_HEIGHT = 32;\nexport const RAIL_OFFSET = 12;\nexport const RAIL_GAP = 12;\n\nconst mobileLayout = css`\n top: auto;\n bottom: calc(100% + ${RAIL_OFFSET}px);\n right: ${RAIL_OFFSET}px;\n left: auto;\n flex-direction: row-reverse;\n`;\n\nconst desktopLayout = css`\n top: ${RAIL_OFFSET}px;\n right: calc(-1 * (${RAIL_BUTTON_SIZE}px + ${RAIL_OFFSET}px));\n flex-direction: column;\n`;\n\nconst Rail = styled.div<{ $isMobile?: boolean }>`\n position: absolute;\n display: flex;\n gap: ${RAIL_GAP}px;\n z-index: 1;\n ${(props) => (props.$isMobile ? mobileLayout : desktopLayout)}\n`;\n\nexport interface TypeActionRailProps {\n children: React.ReactNode;\n /** When true, render horizontally above the parent (bottom-sheet mobile pattern). */\n isMobile?: boolean;\n /** Accessible group label for the rail. */\n \"aria-label\"?: string;\n}\n\nexport const ActionRail: React.FC<TypeActionRailProps> = ({\n children,\n isMobile,\n \"aria-label\": ariaLabel = \"Quick actions\",\n}) => {\n return (\n <Rail\n $isMobile={isMobile}\n data-slot=\"action-rail\"\n data-qa-action-rail\n aria-label={ariaLabel}\n role=\"group\"\n >\n {children}\n </Rail>\n );\n};\n\nActionRail.displayName = \"ActionRail\";\n","import * as React from \"react\";\nimport styled from \"styled-components\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport { RAIL_BUTTON_HEIGHT, RAIL_BUTTON_SIZE } from \"./ActionRail\";\n\nconst StyledButton = styled.button`\n width: ${RAIL_BUTTON_SIZE}px;\n height: ${RAIL_BUTTON_HEIGHT}px;\n display: inline-grid;\n place-items: center;\n border-radius: ${(props) => props.theme.radii.outer};\n border: none;\n background: ${(props) => props.theme.colors.button.overlay.background.base};\n color: ${(props) => props.theme.colors.button.overlay.text.base};\n cursor: pointer;\n outline: none;\n transition: all ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_inout};\n\n &:hover {\n background: ${(props) =>\n props.theme.colors.button.overlay.background.hover};\n }\n\n &:hover,\n &:active {\n transform: none;\n }\n\n &:focus-visible {\n ${focusRing}\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n`;\n\nexport type TypeActionRailButtonProps =\n React.ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport const ActionRailButton = React.forwardRef<\n HTMLButtonElement,\n TypeActionRailButtonProps\n>(({ children, ...rest }, ref) => (\n <StyledButton\n ref={ref}\n type=\"button\"\n data-slot=\"action-rail-button\"\n {...rest}\n >\n {children}\n </StyledButton>\n));\n\nActionRailButton.displayName = \"ActionRailButton\";\n","import * as React from \"react\";\nimport { useContext } from \"react\";\nimport { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\n// eslint-disable-next-line import/no-deprecated\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { useIsMobile } from \"@sproutsocial/seeds-react-hooks\";\nimport { DisablePortalToBodyContext } from \"@sproutsocial/seeds-react-portal\";\nimport { Content } from \"./styles\";\nimport { ActionRail, ActionRailButton } from \"./ActionRail\";\nimport type {\n TypeDrawerContext,\n TypeDrawerCloseButtonProps,\n TypeDrawerHeaderProps,\n TypeDrawerProps,\n TypeDrawerContentProps,\n} from \"./DrawerTypes\";\n\n/**\n * Single source of truth for the Drawer context. Both the Tailwind and the\n * styled-components shells provide this exact context, and the shared\n * sub-components (`Drawer.CloseButton`, `Drawer.Header`) consume it — so there\n * must be exactly one context identity, or the close button can't see its\n * provider.\n */\nexport const DrawerContext = React.createContext<TypeDrawerContext>({\n isLocked: false,\n setIsLocked: () => {},\n hasActionRail: false,\n});\n\nexport const DrawerCloseButton = (props: TypeDrawerCloseButtonProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext) ?? null;\n }\n\n return (\n <Button\n appearance=\"pill\"\n aria-label={drawerContext.closeButtonLabel}\n onClick={drawerContext.onClose}\n {...props}\n >\n {props.children || <Icon aria-hidden name=\"x-outline\" />}\n </Button>\n );\n};\n\nexport const DrawerHeader = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (render) {\n return render(drawerContext);\n }\n\n return (\n <Box\n display=\"flex\"\n flex=\"0 0 auto\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n pt={400}\n px={450}\n {...rest}\n >\n {children || (\n <>\n <Text\n as=\"h2\"\n fontSize={400}\n fontWeight=\"semibold\"\n color=\"text.headline\"\n id={id}\n >\n {title}\n </Text>\n {!drawerContext.hasActionRail && <DrawerCloseButton />}\n </>\n )}\n </Box>\n );\n};\n\nexport const DrawerContent = ({\n children,\n ...rest\n}: TypeDrawerContentProps) => (\n <Content\n height=\"100%\"\n p={450}\n color=\"text.body\"\n data-drawer-content=\"\"\n {...rest}\n >\n {children}\n </Content>\n);\n\nDrawerHeader.displayName = \"Drawer.Header\";\nDrawerContent.displayName = \"Drawer.Content\";\nDrawerCloseButton.displayName = \"Drawer.CloseButton\";\n\n/**\n * Root-level Drawer logic shared by both shells. Centralising it here (rather\n * than duplicating it in each shell) guarantees the two implementations stay\n * behaviourally identical — the esc-key lock and exit-freeze logic is exactly\n * what the lock/close tests exercise.\n */\nexport const useDrawerShell = (props: TypeDrawerProps) => {\n const {\n children,\n closeButtonLabel,\n direction = \"right\",\n disableCloseOnClickOutside = false,\n id,\n modal = false,\n open,\n offset = 0,\n onClose,\n zIndex = 7,\n width = 600,\n snapPoints,\n defaultSnapPoint,\n snapPoint,\n onSnapPointChange,\n snapToSequentialPoints,\n actions,\n actionsInHeader = false,\n ...rest\n } = props;\n\n const isMobile = useIsMobile();\n const effectiveDirection = isMobile ? \"bottom\" : direction;\n const effectiveSnapPoints =\n effectiveDirection === \"bottom\" ? snapPoints : undefined;\n const hasSnapPoints = !!effectiveSnapPoints && effectiveSnapPoints.length > 0;\n const hasActionRail =\n isMobile && !actionsInHeader && !!actions && actions.length > 0;\n const [isLocked, setIsLocked] = React.useState(false);\n\n const ariaLabelledBy = rest[\"aria-labelledby\"];\n const ariaLabel = rest[\"aria-label\"];\n React.useEffect(() => {\n if (process.env.NODE_ENV !== \"production\") {\n if (!ariaLabelledBy && !ariaLabel) {\n console.warn(\n \"[Drawer] Missing accessible name. Add aria-labelledby pointing to your Drawer.Header id, or aria-label, so screen readers can identify the dialog.\"\n );\n }\n }\n }, [ariaLabelledBy, ariaLabel]);\n // Keep a ref so the onOpenChange callback always sees the current isLocked\n // value without needing to be re-created on each render.\n const isLockedRef = React.useRef(isLocked);\n isLockedRef.current = isLocked;\n\n // Freeze the last-rendered children during the exit transition so consumers\n // that conditionally render content (e.g. {isOpen && <Content />}) don't\n // produce an empty drawer shell while Base UI animates the popup out.\n const prevChildrenRef = React.useRef<React.ReactNode>(null);\n if (open) {\n prevChildrenRef.current = children;\n }\n const renderedChildren = open ? children : prevChildrenRef.current;\n\n const rootProps: Omit<\n React.ComponentProps<typeof BaseDrawer.Root>,\n \"children\"\n > = {\n open,\n onOpenChange: (isOpen, eventDetails) => {\n if (!isOpen) {\n if (isLockedRef.current && eventDetails.reason === \"escape-key\") {\n return;\n }\n onClose();\n }\n },\n disablePointerDismissal: disableCloseOnClickOutside,\n swipeDirection:\n effectiveDirection === \"bottom\" ? \"down\" : effectiveDirection,\n modal,\n snapPoints: effectiveSnapPoints,\n defaultSnapPoint,\n snapPoint,\n onSnapPointChange: onSnapPointChange\n ? (sp) => onSnapPointChange(sp)\n : undefined,\n snapToSequentialPoints,\n };\n\n return {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n isLocked,\n setIsLocked,\n renderedChildren,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n closeButtonLabel,\n onClose,\n actions,\n };\n};\n\nexport type TypeDrawerShell = ReturnType<typeof useDrawerShell>;\n\n/**\n * The popup contents shared by both shells: the optional mobile action rail and\n * the context providers wrapping the rendered children. Only the popup wrapper\n * and drag handle differ between the Tailwind and styled paths — everything\n * inside the popup is identical, so it lives here.\n */\nexport const DrawerPopupContents = ({ shell }: { shell: TypeDrawerShell }) => {\n const {\n hasActionRail,\n closeButtonLabel,\n onClose,\n actions,\n isLocked,\n setIsLocked,\n renderedChildren,\n } = shell;\n\n return (\n <>\n {hasActionRail && actions && (\n <ActionRail isMobile aria-label=\"Drawer quick actions\">\n <ActionRailButton\n aria-label={closeButtonLabel}\n onClick={onClose}\n data-qa-drawer-rail-close\n >\n <Icon aria-hidden name=\"x-outline\" />\n </ActionRailButton>\n {actions.map((action, i) => (\n <ActionRailButton\n key={i}\n aria-label={action[\"aria-label\"]}\n onClick={action.onClick}\n disabled={action.disabled}\n >\n {action.iconName && <Icon aria-hidden name={action.iconName} />}\n </ActionRailButton>\n ))}\n </ActionRail>\n )}\n <DisablePortalToBodyContext.Provider value={true}>\n <DrawerContext.Provider\n value={{\n onClose,\n closeButtonLabel,\n isLocked,\n setIsLocked,\n hasActionRail,\n }}\n >\n {renderedChildren}\n </DrawerContext.Provider>\n </DisablePortalToBodyContext.Provider>\n </>\n );\n};\n","import { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport { useDrawerShell, DrawerPopupContents } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\nimport type { CSSProperties } from \"react\";\n\n// Utility for merging class names properly. Copied from ButtonTailwind.tsx —\n// `cn` is NOT exported from @sproutsocial/seeds-react-utilities, so each\n// Tailwind component carries its own copy.\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\n/**\n * Tailwind/CSS-class shell. The preferred path — routed to by `DrawerHybrid`\n * whenever the consumer passes no styled-system props. Renders the real Base UI\n * primitives (Backdrop/Viewport/Popup) with component-scoped classes from\n * `drawer.css`; the runtime numerics (`width`, `offset`, `zIndex`) are applied\n * as direct inline styles so drag/swipe/snap/portal behaviour is preserved.\n */\nconst DrawerTailwind = (props: TypeDrawerProps) => {\n const shell = useDrawerShell(props);\n const {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n } = shell;\n\n // `className` and `style` are public <div> props (TypeDrawerProps extends\n // ComponentPropsWithoutRef<\"div\">) that arrive via `rest`. Pull them out so\n // they MERGE with the popup's computed classes/geometry instead of\n // overwriting them — matching the styled-components path, where a consumer\n // className is appended to the generated class and an inline style wins over\n // the generated width.\n const { className, style, ...domRest } = rest as {\n className?: string;\n style?: CSSProperties;\n } & Record<string, unknown>;\n\n return (\n <BaseDrawer.Root {...rootProps}>\n <BaseDrawer.Portal>\n <BaseDrawer.Backdrop\n data-testid=\"drawer-backdrop\"\n className=\"seeds-drawer-backdrop\"\n />\n <BaseDrawer.Viewport\n className={cn(\"seeds-drawer-viewport\", {\n \"seeds-drawer-viewport--snap\": hasSnapPoints,\n })}\n >\n <BaseDrawer.Popup\n initialFocus\n data-qa-drawer={id}\n data-qa-drawer-isopen={open}\n {...domRest}\n className={cn(\n \"seeds-drawer-popup\",\n effectiveDirection === \"bottom\"\n ? \"seeds-drawer-popup--bottom\"\n : \"seeds-drawer-popup--side\",\n effectiveDirection === \"right\" && \"seeds-drawer-popup--right\",\n effectiveDirection === \"left\" && \"seeds-drawer-popup--left\",\n {\n \"seeds-drawer-popup--snap\": hasSnapPoints,\n \"seeds-drawer-popup--action-rail\": hasActionRail,\n },\n // Consumer className folded in last so it appends to (not\n // replaces) the component classes.\n className\n )}\n style={{\n // z-index is always inline (runtime numeric, mirrors styles.ts).\n zIndex,\n // Side drawers carry their width/offset as direct inline styles —\n // runtime numerics, and required for the jsdom `toHaveStyle`\n // assertions. Bottom drawers derive width/position from the class.\n ...(effectiveDirection === \"right\"\n ? { width: `${width}px`, right: `${offset}px` }\n : effectiveDirection === \"left\"\n ? { width: `${width}px`, left: `${offset}px` }\n : {}),\n // Consumer style folded in last so it wins over the computed\n // geometry, matching the styled-components inline-style semantics.\n ...style,\n }}\n >\n {effectiveDirection === \"bottom\" && (\n <div aria-hidden className=\"seeds-drawer-drag-handle\" />\n )}\n <DrawerPopupContents shell={shell} />\n </BaseDrawer.Popup>\n </BaseDrawer.Viewport>\n </BaseDrawer.Portal>\n </BaseDrawer.Root>\n );\n};\n\nexport default DrawerTailwind;\n","import DrawerHybrid from \"./DrawerHybrid\";\n\n/**\n * Drawer component. Automatically routes between the Tailwind implementation\n * (preferred) and the styled-components implementation (for consumers using\n * system props or a `styled()` extension). The default export carries the\n * `.Header`, `.Content`, and `.CloseButton` statics.\n */\nexport { DrawerContext } from \"./DrawerShared\";\nexport default DrawerHybrid;\n","import * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\nimport type { TypeIconName } from \"@sproutsocial/seeds-react-icon\";\n\ntype DrawerAnimationDirection = \"left\" | \"right\" | \"bottom\";\n\n/**\n * Action button shown in the mobile rail above a bottom-sheet drawer.\n * Mirrors `TypeModalActionProps` so consumers can share the same array shape.\n */\nexport type TypeDrawerActionProps = {\n /** Accessible label for the action button. */\n \"aria-label\": string;\n /** Icon name from the Seeds icon set. */\n iconName?: TypeIconName;\n /** Click handler. */\n onClick?: () => void;\n /** Disable the action. */\n disabled?: boolean;\n};\n\n/**\n * A snap point the bottom drawer can rest at.\n * - Numbers 0–1: fraction of viewport height\n * - Numbers > 1: pixels\n * - Strings: CSS lengths in `px` or `rem` (e.g. `\"480px\"`, `\"30rem\"`)\n */\nexport type TypeDrawerSnapPoint = number | string;\n\nexport interface TypeDrawerContext {\n /** Callback for close button */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClose?: () => any;\n\n /** aria-label for drawer close button */\n closeButtonLabel?: string;\n /**\n * isLocked and setIsLocked are used when a Drawer contains other components (like Menu) that also\n * listen for Escape key events. By locking the Drawer, we can prevent conflicts\n * where multiple components try to handle the same keydown event.\n */\n isLocked: boolean;\n setIsLocked: (locked: boolean) => void;\n /**\n * True when the Drawer is rendering an `ActionRail` above the popup. The\n * default `Drawer.Header` reads this to omit its built-in close button so the\n * rail can own the close affordance.\n */\n hasActionRail?: boolean;\n}\n// TODO: Should the render prop be a React.FC?\nexport interface TypeDrawerCloseButtonProps\n extends Omit<TypeButtonProps, \"children\"> {\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the on-close behavior. */\n render?: React.FC<TypeDrawerContext>;\n children?: React.ReactNode;\n}\n\nexport interface TypeDrawerHeaderProps extends TypeBoxProps {\n title?: string;\n /**\n * When children are provided, `<Drawer.CloseButton />` is NOT rendered automatically.\n * You must include it yourself inside children to preserve keyboard accessibility.\n */\n children?: React.ReactNode;\n\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the appearance of the header. */\n render?: React.FC<TypeDrawerContext>;\n}\n\nexport interface TypeDrawerProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"div\">, \"color\"> {\n children: React.ReactNode;\n\n /** Label for the close button. Usually this should be \"Close\" */\n closeButtonLabel: string;\n\n /** Whether the drawer slides in from the left or right side of the screen */\n direction?: DrawerAnimationDirection;\n\n /** In some cases, you may not want the user to be able to click outside of the drawer to close it. You can disable that with this prop. */\n disableCloseOnClickOutside?: boolean;\n\n /**\n * When true, siblings are inerted while the drawer is open — appropriate for forms or settings\n * panels where page interaction should be blocked.\n * Defaults to false to preserve the original non-modal behavior where the rest of the page\n * remains interactive (side info panels, notification slide-outs, persistent inspectors, etc.).\n */\n modal?: boolean;\n /** Optional id used for data-qa-drawer attributes */\n id?: string;\n open: boolean;\n offset?: number;\n onClose: () => void;\n zIndex?: number;\n width?: number;\n\n /**\n * Snap points the drawer can rest at when swiped. Only applied to bottom drawers.\n * Numbers 0–1 are viewport-height fractions; numbers > 1 are pixels; strings accept\n * `px`/`rem` (e.g. `\"480px\"`, `\"30rem\"`). Order matters — the last entry is the\n * \"expanded\" state and gets a `data-expanded` attribute on the popup.\n */\n snapPoints?: TypeDrawerSnapPoint[];\n\n /** Initial snap point for uncontrolled use. */\n defaultSnapPoint?: TypeDrawerSnapPoint | null;\n\n /** Controlled active snap point. Pair with `onSnapPointChange`. */\n snapPoint?: TypeDrawerSnapPoint | null;\n\n /** Fires when the active snap point changes (drag release, programmatic update, etc.). */\n onSnapPointChange?: (snapPoint: TypeDrawerSnapPoint | null) => void;\n\n /**\n * When true, fast swipes can't skip past adjacent snap points — drag distance alone\n * determines the next stop. Defaults to base-ui's `false` (velocity-based skipping).\n */\n snapToSequentialPoints?: boolean;\n\n /**\n * Action buttons shown in a floating rail above the drawer on mobile (the\n * bottom-sheet rendering). The rail also owns the close button — when this\n * prop is provided, the default `Drawer.Header` omits its built-in close\n * button so the rail can render it instead. Ignored on desktop side drawers.\n */\n actions?: TypeDrawerActionProps[];\n\n /**\n * Opt out of the floating rail and keep the actions inside `Drawer.Header`\n * (the pre-rail behavior). Useful for nested bottom sheets and snap-point\n * drawers where the rail-above placement would collide with surrounding UI\n * or fall off-screen at the highest snap point. Defaults to `false`.\n *\n * When `true`, the Drawer does NOT render the rail; consumers are\n * responsible for rendering action buttons (and the close button) inside\n * their `Drawer.Header`.\n */\n actionsInHeader?: boolean;\n}\n\nexport interface TypeDrawerContentProps extends TypeBoxProps {\n children?: React.ReactNode;\n}\n"],"mappings":"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","names":["import_seeds_react_system_props","import_drawer","import_styled_components","styled","React","import_styled_components","import_jsx_runtime","styled","styled","Box","React","import_drawer","import_seeds_react_box","import_jsx_runtime","Button","Icon","Box","Text","import_jsx_runtime","BaseDrawer","import_drawer","import_jsx_runtime","BaseDrawer","import_jsx_runtime","React"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/DrawerHybrid.tsx","../src/DrawerStyled.tsx","../src/styles.ts","../src/ActionRail/ActionRail.tsx","../src/ActionRail/ActionRailButton.tsx","../src/DrawerShared.tsx","../src/DrawerTailwind.tsx","../src/Drawer.tsx","../src/DrawerTypes.ts"],"sourcesContent":["import Drawer, { DrawerContext } from \"./Drawer\";\n\nexport default Drawer;\nexport { Drawer, DrawerContext };\nexport * from \"./DrawerTypes\";\nexport {\n ActionRail,\n ActionRailButton,\n RAIL_BUTTON_SIZE,\n RAIL_BUTTON_HEIGHT,\n RAIL_OFFSET,\n RAIL_GAP,\n} from \"./ActionRail\";\nexport type {\n TypeActionRailProps,\n TypeActionRailButtonProps,\n} from \"./ActionRail\";\n","/**\n * Hybrid Drawer component.\n * Automatically chooses between the Tailwind shell (preferred) and the\n * styled-components shell based on props, mirroring `ButtonHybrid`. When a\n * consumer passes styled-system props (`px`, `color`, `height`, …) the styled\n * path is used so existing styling keeps working; otherwise the Tailwind path\n * renders.\n */\nimport { hasStyledProps } from \"@sproutsocial/seeds-react-system-props\";\nimport DrawerStyled from \"./DrawerStyled\";\nimport DrawerTailwind from \"./DrawerTailwind\";\nimport { DrawerHeader, DrawerContent, DrawerCloseButton } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\n\n// Props the Drawer owns semantically. They must be stripped before the\n// `hasStyledProps` check so a Drawer-specific prop never trips the styled\n// router — most importantly `width`, which `hasStyledProps` also treats as a\n// styled-system prop. Anything left in `rest` is a true pass-through/system\n// prop and is what the routing decision is based on.\nconst DRAWER_OWN_PROPS: readonly string[] = [\n \"children\",\n \"closeButtonLabel\",\n \"direction\",\n \"disableCloseOnClickOutside\",\n \"id\",\n \"modal\",\n \"open\",\n \"offset\",\n \"onClose\",\n \"zIndex\",\n \"width\",\n \"snapPoints\",\n \"defaultSnapPoint\",\n \"snapPoint\",\n \"onSnapPointChange\",\n \"snapToSequentialPoints\",\n \"actions\",\n \"actionsInHeader\",\n];\n\nconst DrawerHybrid = (props: TypeDrawerProps) => {\n const rest: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n if (!DRAWER_OWN_PROPS.includes(key)) {\n rest[key] = (props as unknown as Record<string, unknown>)[key];\n }\n }\n\n if (hasStyledProps(rest)) {\n return <DrawerStyled {...props} />;\n }\n\n // Use the Tailwind version (preferred - better performance).\n return <DrawerTailwind {...props} />;\n};\n\nDrawerHybrid.Header = DrawerHeader;\nDrawerHybrid.Content = DrawerContent;\nDrawerHybrid.CloseButton = DrawerCloseButton;\n\nexport default DrawerHybrid;\n","import { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport {\n StyledPopup,\n StyledBackdrop,\n StyledViewport,\n DragHandle,\n} from \"./styles\";\nimport { useDrawerShell, DrawerPopupContents } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\n\n/**\n * Legacy styled-components shell. Routed to by `DrawerHybrid` whenever the\n * consumer passes styled-system props (or a `styled()` extension). Renders the\n * exact styled wrappers from `styles.ts` so behaviour is unchanged.\n */\nconst DrawerStyled = (props: TypeDrawerProps) => {\n const shell = useDrawerShell(props);\n const {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n } = shell;\n\n return (\n <BaseDrawer.Root {...rootProps}>\n <BaseDrawer.Portal>\n <StyledBackdrop data-testid=\"drawer-backdrop\" />\n <StyledViewport $hasSnapPoints={hasSnapPoints}>\n <StyledPopup\n initialFocus={true}\n $width={width}\n $offset={offset}\n $direction={effectiveDirection}\n $zIndex={zIndex}\n $hasSnapPoints={hasSnapPoints}\n $hasActionRail={hasActionRail}\n data-qa-drawer={id}\n data-qa-drawer-isopen={open}\n {...rest}\n >\n {effectiveDirection === \"bottom\" && <DragHandle aria-hidden />}\n <DrawerPopupContents shell={shell} />\n </StyledPopup>\n </StyledViewport>\n </BaseDrawer.Portal>\n </BaseDrawer.Root>\n );\n};\n\nexport default DrawerStyled;\n","import { Drawer } from \"@base-ui/react/drawer\";\nimport styled from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeSystemCommonProps } from \"@sproutsocial/seeds-react-system-props\";\nimport { MOTION_DURATION_MEDIUM } from \"@sproutsocial/seeds-motion/unitless\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { RAIL_BUTTON_HEIGHT, RAIL_OFFSET } from \"./ActionRail\";\n\n// Total vertical space the action rail occupies above the popup\n// (rail height + gap between rail and popup). When the drawer animates\n// closed, the popup must translate this much further so the rail also\n// leaves the viewport instead of flashing at the bottom edge.\nconst ACTION_RAIL_OUTSET = RAIL_BUTTON_HEIGHT + RAIL_OFFSET;\n\nexport const Content = styled(Box)`\n overflow-y: auto;\n`;\n\nexport const StyledViewport = styled(Drawer.Viewport)<{\n $hasSnapPoints: boolean;\n}>`\n ${(props) =>\n props.$hasSnapPoints\n ? `\n position: fixed;\n inset: 0;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n touch-action: none;\n /* The viewport spans the whole screen but the popup only fills part of\n it. Letting clicks fall through the empty area means a nested\n snap-point drawer doesn't block selection/interaction with the\n parent drawer visible underneath. The popup re-enables events. */\n pointer-events: none;\n `\n : \"\"}\n`;\n\ninterface StyledPopupProps extends TypeSystemCommonProps {\n $width: number;\n $offset: number;\n $direction: \"left\" | \"right\" | \"bottom\";\n $zIndex: number;\n $hasSnapPoints: boolean;\n $hasActionRail: boolean;\n}\n\nexport const StyledPopup = styled(Drawer.Popup)<StyledPopupProps>`\n display: flex;\n flex-direction: column;\n position: fixed;\n background-color: ${(props) => props.theme.colors.container.background.base};\n z-index: ${(props) => props.$zIndex};\n filter: blur(0);\n transition: transform ${MOTION_DURATION_MEDIUM}s ease,\n border-radius ${MOTION_DURATION_MEDIUM}s ease,\n height ${MOTION_DURATION_MEDIUM}s ease;\n\n /* Always-on opacity transition so content fades smoothly both into and out of stacked state */\n > * {\n transition: opacity ${MOTION_DURATION_MEDIUM}s ease;\n }\n\n ${(props) => {\n if (props.$direction === \"bottom\") {\n if (props.$hasSnapPoints) {\n // Snap-points popup follows base-ui's reference layout. Critical details:\n // - box-sizing: border-box so offsetHeight ignores padding-bottom; otherwise\n // base-ui's ResizeObserver feedback (padding-bottom driven by snap offset)\n // grows popupHeight on every measurement and snap math diverges.\n // - height (not max-height) so popupHeight is large enough that base-ui's\n // snap offset = max(0, popupHeight - snapHeight) distinguishes snap points;\n // with short content + max-height it collapses to 0 for every snap.\n // - position: relative inside the flex-end Viewport so base-ui can measure\n // popupHeight vs viewportHeight for snap math.\n return `\n box-sizing: border-box;\n position: relative;\n width: 100%;\n height: calc(100dvh - 1rem);\n padding-bottom: max(0px, calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));\n overflow: visible;\n touch-action: none;\n /* Counterpart to the viewport's pointer-events: none — the popup\n itself stays interactive. */\n pointer-events: auto;\n border-radius: ${props.theme.radii[800]} ${props.theme.radii[800]} 0 0;\n box-shadow: 0px -8px 16px rgba(39,51,51,.25);\n transform: translateY(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));\n will-change: transform;\n transition:\n transform ${MOTION_DURATION_MEDIUM}s cubic-bezier(0.32, 0.72, 0, 1),\n box-shadow ${MOTION_DURATION_MEDIUM}s cubic-bezier(0.32, 0.72, 0, 1);\n `;\n }\n return `\n --bleed: 3rem;\n --stack-scale: 1;\n --translate-y: 0px;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100%;\n height: calc(90vh + var(--bleed));\n margin-bottom: calc(-1 * var(--bleed));\n border-radius: ${props.theme.radii[800]} ${props.theme.radii[800]} 0 0;\n transform: translateY(var(--translate-y)) scale(var(--stack-scale));\n transform-origin: 50% calc(100% - var(--bleed));\n box-shadow: 0px -8px 16px rgba(39,51,51,.25);\n `;\n }\n return `\n top: 0;\n height: 100%;\n width: ${props.$width}px;\n ${\n props.$direction === \"right\"\n ? `right: ${props.$offset}px;`\n : `left: ${props.$offset}px;`\n }\n box-shadow: ${props.theme.shadows.medium};\n `;\n }}\n\n &[data-starting-style],\n &[data-ending-style] {\n ${(props) => {\n if (props.$direction !== \"bottom\") {\n return `transform: translateX(${\n props.$direction === \"right\" ? \"100%\" : \"-100%\"\n });`;\n }\n // The action rail lives above the popup (position: absolute,\n // bottom: 100% + RAIL_OFFSET). Translating the popup by its own\n // height alone leaves the rail visible at the bottom of the\n // viewport during enter/exit, so we add the rail's outset here.\n const railOffset = props.$hasActionRail\n ? ` + ${ACTION_RAIL_OUTSET}px`\n : \"\";\n if (props.$hasSnapPoints) {\n return `\n transform: translateY(calc(100% + 2px${railOffset}));\n padding-bottom: 0;\n `;\n }\n return `transform: translateY(calc(100% - var(--bleed) + 2px${railOffset}));`;\n }}\n }\n\n &[data-swiping],\n &[data-nested-drawer-swiping] {\n transition-duration: 0ms;\n }\n\n &[data-nested-drawer-open] {\n border-radius: ${(props) => props.theme.radii[800]};\n\n ${(props) => {\n if (props.$direction === \"bottom\") {\n // Snap-point drawers don't participate in the stacked-bottom-sheet\n // animation: the stack math overwrites --translate-y and clips overflow,\n // which collides with base-ui's snap-offset transform.\n if (props.$hasSnapPoints) return \"\";\n return `\n --stack-step: 0.05;\n --stack-progress: clamp(0, var(--drawer-swipe-progress), 1);\n /* Override default vars; base transform rule picks them up automatically */\n --stack-scale: max(0, calc(\n 1 - (var(--nested-drawers) * var(--stack-step))\n + (var(--stack-step) * var(--stack-progress))\n ));\n --stack-shrink: calc(1 - var(--stack-scale));\n --stack-height: max(0px, calc(\n var(--drawer-frontmost-height, var(--drawer-height)) - var(--bleed)\n ));\n --stack-peek-offset: max(0px, calc(\n (var(--nested-drawers) - var(--stack-progress)) * 1rem\n ));\n --translate-y: calc(\n var(--drawer-swipe-movement-y)\n - var(--stack-peek-offset)\n - (var(--stack-shrink) * var(--stack-height))\n );\n height: calc(var(--stack-height) + var(--bleed));\n overflow: hidden;\n `;\n }\n return `\n transform: translateY(calc(var(--nested-drawers) * -20px))\n scale(calc(1 - var(--nested-drawers) * 0.08));\n transform-origin: top center;\n `;\n }}\n\n ${(props) =>\n props.$hasSnapPoints\n ? \"\"\n : `\n > * {\n opacity: 0;\n }\n `}\n }\n\n &[data-nested-drawer-open][data-nested-drawer-swiping] {\n > * {\n opacity: 1;\n }\n }\n\n ${COMMON}\n`;\n\nexport const DragHandle = styled.div`\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n width: 36px;\n height: 4px;\n border-radius: 2px;\n background-color: ${(props) => props.theme.colors.container.border.base};\n`;\n\nexport const StyledBackdrop = styled(Drawer.Backdrop)`\n position: fixed;\n inset: 0;\n background: transparent;\n pointer-events: none;\n`;\n","import * as React from \"react\";\nimport styled, { css } from \"styled-components\";\n\nexport const RAIL_BUTTON_SIZE = 44;\nexport const RAIL_BUTTON_HEIGHT = 32;\nexport const RAIL_OFFSET = 12;\nexport const RAIL_GAP = 12;\n\nconst mobileLayout = css`\n top: auto;\n bottom: calc(100% + ${RAIL_OFFSET}px);\n right: ${RAIL_OFFSET}px;\n left: auto;\n flex-direction: row-reverse;\n`;\n\nconst desktopLayout = css`\n top: ${RAIL_OFFSET}px;\n right: calc(-1 * (${RAIL_BUTTON_SIZE}px + ${RAIL_OFFSET}px));\n flex-direction: column;\n`;\n\nconst Rail = styled.div<{ $isMobile?: boolean }>`\n position: absolute;\n display: flex;\n gap: ${RAIL_GAP}px;\n z-index: 1;\n ${(props) => (props.$isMobile ? mobileLayout : desktopLayout)}\n`;\n\nexport interface TypeActionRailProps {\n children: React.ReactNode;\n /** When true, render horizontally above the parent (bottom-sheet mobile pattern). */\n isMobile?: boolean;\n /** Accessible group label for the rail. */\n \"aria-label\"?: string;\n}\n\nexport const ActionRail: React.FC<TypeActionRailProps> = ({\n children,\n isMobile,\n \"aria-label\": ariaLabel = \"Quick actions\",\n}) => {\n return (\n <Rail\n $isMobile={isMobile}\n data-slot=\"action-rail\"\n data-qa-action-rail\n aria-label={ariaLabel}\n role=\"group\"\n >\n {children}\n </Rail>\n );\n};\n\nActionRail.displayName = \"ActionRail\";\n","import * as React from \"react\";\nimport styled from \"styled-components\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport { RAIL_BUTTON_HEIGHT, RAIL_BUTTON_SIZE } from \"./ActionRail\";\n\nconst StyledButton = styled.button`\n width: ${RAIL_BUTTON_SIZE}px;\n height: ${RAIL_BUTTON_HEIGHT}px;\n display: inline-grid;\n place-items: center;\n border-radius: ${(props) => props.theme.radii.outer};\n border: none;\n background: ${(props) => props.theme.colors.button.overlay.background.base};\n color: ${(props) => props.theme.colors.button.overlay.text.base};\n cursor: pointer;\n outline: none;\n transition: all ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_inout};\n\n &:hover {\n background: ${(props) =>\n props.theme.colors.button.overlay.background.hover};\n }\n\n &:hover,\n &:active {\n transform: none;\n }\n\n &:focus-visible {\n ${focusRing}\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n`;\n\nexport type TypeActionRailButtonProps =\n React.ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport const ActionRailButton = React.forwardRef<\n HTMLButtonElement,\n TypeActionRailButtonProps\n>(({ children, ...rest }, ref) => (\n <StyledButton\n ref={ref}\n type=\"button\"\n data-slot=\"action-rail-button\"\n {...rest}\n >\n {children}\n </StyledButton>\n));\n\nActionRailButton.displayName = \"ActionRailButton\";\n","import * as React from \"react\";\nimport { useContext } from \"react\";\nimport { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\n// eslint-disable-next-line import/no-deprecated\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { useIsMobile } from \"@sproutsocial/seeds-react-hooks\";\nimport { DisablePortalToBodyContext } from \"@sproutsocial/seeds-react-portal\";\nimport { needsStyledComponents } from \"@sproutsocial/seeds-react-system-props\";\nimport { Content } from \"./styles\";\nimport { ActionRail, ActionRailButton } from \"./ActionRail\";\nimport type {\n TypeDrawerContext,\n TypeDrawerCloseButtonProps,\n TypeDrawerHeaderProps,\n TypeDrawerProps,\n TypeDrawerContentProps,\n} from \"./DrawerTypes\";\n\n/**\n * Single source of truth for the Drawer context. Both the Tailwind and the\n * styled-components shells provide this exact context, and the shared\n * sub-components (`Drawer.CloseButton`, `Drawer.Header`) consume it — so there\n * must be exactly one context identity, or the close button can't see its\n * provider.\n */\nexport const DrawerContext = React.createContext<TypeDrawerContext>({\n isLocked: false,\n setIsLocked: () => {},\n hasActionRail: false,\n});\n\n// Utility for merging class names properly. Copied from DrawerTailwind.tsx —\n// `cn` is NOT exported from @sproutsocial/seeds-react-utilities, so each\n// Tailwind component carries its own copy.\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\nexport const DrawerCloseButton = (props: TypeDrawerCloseButtonProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext) ?? null;\n }\n\n return (\n <Button\n appearance=\"pill\"\n aria-label={drawerContext.closeButtonLabel}\n onClick={drawerContext.onClose}\n {...props}\n >\n {props.children || <Icon aria-hidden name=\"x-outline\" />}\n </Button>\n );\n};\n\n/**\n * Styled-components header — the always-styled implementation, preserved for\n * backward compatibility. The hybrid router below sends consumers here whenever\n * they pass styled-system props (e.g. `<Drawer.Header alignItems=\"center\">`) or\n * a `styled()` extension, so the full `Box` prop surface keeps working.\n */\nconst DrawerHeaderStyled = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (render) {\n return render(drawerContext);\n }\n\n return (\n <Box\n display=\"flex\"\n flex=\"0 0 auto\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n pt={400}\n px={450}\n {...rest}\n >\n {children || (\n <>\n <Text\n as=\"h2\"\n fontSize={400}\n fontWeight=\"semibold\"\n color=\"text.headline\"\n id={id}\n >\n {title}\n </Text>\n {!drawerContext.hasActionRail && <DrawerCloseButton />}\n </>\n )}\n </Box>\n );\n};\n\n/**\n * Tailwind/CSS-class header — the preferred path, routed to by the hybrid when\n * the consumer passes no styled-system props. Renders a plain `<div>` with the\n * `seeds-drawer-header` classes from `drawer.css` instead of a styled `Box`.\n * The `render` prop is handled by the hybrid before reaching here.\n */\nconst DrawerHeaderTailwind = ({\n title = \"\",\n id = undefined,\n children,\n render,\n ...rest\n}: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n const { className, ...domRest } = rest as {\n className?: string;\n } & Record<string, unknown>;\n\n return (\n <div className={cn(\"seeds-drawer-header\", className)} {...domRest}>\n {children || (\n <>\n <h2 className=\"seeds-drawer-header-title\" id={id}>\n {title}\n </h2>\n {!drawerContext.hasActionRail && <DrawerCloseButton />}\n </>\n )}\n </div>\n );\n};\n\n/**\n * Hybrid header router. Chooses the styled path when the consumer passes\n * styled-system props or a `styled()` extension, else the Tailwind path —\n * independent of the root Drawer's routing. The `render` prop short-circuits\n * before any routing, matching the original always-styled behaviour.\n */\nexport const DrawerHeader = (props: TypeDrawerHeaderProps) => {\n const drawerContext = useContext(DrawerContext);\n\n if (props.render) {\n return props.render(drawerContext);\n }\n\n const { title, id, children, render, ...rest } = props;\n\n if (needsStyledComponents(rest)) {\n return <DrawerHeaderStyled {...props} />;\n }\n\n return <DrawerHeaderTailwind {...props} />;\n};\n\n/**\n * Styled-components content — the always-styled implementation, preserved for\n * backward compatibility. The hybrid router sends consumers here whenever they\n * pass styled-system props (e.g. `<Drawer.Content color=\"text.body\">`).\n */\nconst DrawerContentStyled = ({\n children,\n ...rest\n}: TypeDrawerContentProps) => (\n <Content\n height=\"100%\"\n p={450}\n color=\"text.body\"\n data-drawer-content=\"\"\n {...rest}\n >\n {children}\n </Content>\n);\n\n/**\n * Tailwind/CSS-class content — the preferred path. Renders a plain\n * `<div data-drawer-content>` with the `seeds-drawer-content` class from\n * `drawer.css` instead of a styled `Box`.\n */\nconst DrawerContentTailwind = ({\n children,\n ...rest\n}: TypeDrawerContentProps) => {\n const { className, ...domRest } = rest as {\n className?: string;\n } & Record<string, unknown>;\n\n return (\n <div\n className={cn(\"seeds-drawer-content\", className)}\n data-drawer-content=\"\"\n {...domRest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Hybrid content router. Chooses the styled path when the consumer passes\n * styled-system props or a `styled()` extension, else the Tailwind path.\n */\nexport const DrawerContent = (props: TypeDrawerContentProps) => {\n const { children, ...rest } = props;\n\n if (needsStyledComponents(rest)) {\n return <DrawerContentStyled {...props} />;\n }\n\n return <DrawerContentTailwind {...props} />;\n};\n\nDrawerHeader.displayName = \"Drawer.Header\";\nDrawerContent.displayName = \"Drawer.Content\";\nDrawerCloseButton.displayName = \"Drawer.CloseButton\";\n\n/**\n * Root-level Drawer logic shared by both shells. Centralising it here (rather\n * than duplicating it in each shell) guarantees the two implementations stay\n * behaviourally identical — the esc-key lock and exit-freeze logic is exactly\n * what the lock/close tests exercise.\n */\nexport const useDrawerShell = (props: TypeDrawerProps) => {\n const {\n children,\n closeButtonLabel,\n direction = \"right\",\n disableCloseOnClickOutside = false,\n id,\n modal = false,\n open,\n offset = 0,\n onClose,\n zIndex = 7,\n width = 600,\n snapPoints,\n defaultSnapPoint,\n snapPoint,\n onSnapPointChange,\n snapToSequentialPoints,\n actions,\n actionsInHeader = false,\n ...rest\n } = props;\n\n const isMobile = useIsMobile();\n const effectiveDirection = isMobile ? \"bottom\" : direction;\n const effectiveSnapPoints =\n effectiveDirection === \"bottom\" ? snapPoints : undefined;\n const hasSnapPoints = !!effectiveSnapPoints && effectiveSnapPoints.length > 0;\n const hasActionRail =\n isMobile && !actionsInHeader && !!actions && actions.length > 0;\n const [isLocked, setIsLocked] = React.useState(false);\n\n const ariaLabelledBy = rest[\"aria-labelledby\"];\n const ariaLabel = rest[\"aria-label\"];\n React.useEffect(() => {\n if (process.env.NODE_ENV !== \"production\") {\n if (!ariaLabelledBy && !ariaLabel) {\n console.warn(\n \"[Drawer] Missing accessible name. Add aria-labelledby pointing to your Drawer.Header id, or aria-label, so screen readers can identify the dialog.\"\n );\n }\n }\n }, [ariaLabelledBy, ariaLabel]);\n // Keep a ref so the onOpenChange callback always sees the current isLocked\n // value without needing to be re-created on each render.\n const isLockedRef = React.useRef(isLocked);\n isLockedRef.current = isLocked;\n\n // Freeze the last-rendered children during the exit transition so consumers\n // that conditionally render content (e.g. {isOpen && <Content />}) don't\n // produce an empty drawer shell while Base UI animates the popup out.\n const prevChildrenRef = React.useRef<React.ReactNode>(null);\n if (open) {\n prevChildrenRef.current = children;\n }\n const renderedChildren = open ? children : prevChildrenRef.current;\n\n const rootProps: Omit<\n React.ComponentProps<typeof BaseDrawer.Root>,\n \"children\"\n > = {\n open,\n onOpenChange: (isOpen, eventDetails) => {\n if (!isOpen) {\n if (isLockedRef.current && eventDetails.reason === \"escape-key\") {\n return;\n }\n onClose();\n }\n },\n disablePointerDismissal: disableCloseOnClickOutside,\n swipeDirection:\n effectiveDirection === \"bottom\" ? \"down\" : effectiveDirection,\n modal,\n snapPoints: effectiveSnapPoints,\n defaultSnapPoint,\n snapPoint,\n onSnapPointChange: onSnapPointChange\n ? (sp) => onSnapPointChange(sp)\n : undefined,\n snapToSequentialPoints,\n };\n\n return {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n isLocked,\n setIsLocked,\n renderedChildren,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n closeButtonLabel,\n onClose,\n actions,\n };\n};\n\nexport type TypeDrawerShell = ReturnType<typeof useDrawerShell>;\n\n/**\n * The popup contents shared by both shells: the optional mobile action rail and\n * the context providers wrapping the rendered children. Only the popup wrapper\n * and drag handle differ between the Tailwind and styled paths — everything\n * inside the popup is identical, so it lives here.\n */\nexport const DrawerPopupContents = ({ shell }: { shell: TypeDrawerShell }) => {\n const {\n hasActionRail,\n closeButtonLabel,\n onClose,\n actions,\n isLocked,\n setIsLocked,\n renderedChildren,\n } = shell;\n\n return (\n <>\n {hasActionRail && actions && (\n <ActionRail isMobile aria-label=\"Drawer quick actions\">\n <ActionRailButton\n aria-label={closeButtonLabel}\n onClick={onClose}\n data-qa-drawer-rail-close\n >\n <Icon aria-hidden name=\"x-outline\" />\n </ActionRailButton>\n {actions.map((action, i) => (\n <ActionRailButton\n key={i}\n aria-label={action[\"aria-label\"]}\n onClick={action.onClick}\n disabled={action.disabled}\n >\n {action.iconName && <Icon aria-hidden name={action.iconName} />}\n </ActionRailButton>\n ))}\n </ActionRail>\n )}\n <DisablePortalToBodyContext.Provider value={true}>\n <DrawerContext.Provider\n value={{\n onClose,\n closeButtonLabel,\n isLocked,\n setIsLocked,\n hasActionRail,\n }}\n >\n {renderedChildren}\n </DrawerContext.Provider>\n </DisablePortalToBodyContext.Provider>\n </>\n );\n};\n","import { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport { useDrawerShell, DrawerPopupContents } from \"./DrawerShared\";\nimport type { TypeDrawerProps } from \"./DrawerTypes\";\nimport type { CSSProperties } from \"react\";\n\n// Utility for merging class names properly. Copied from ButtonTailwind.tsx —\n// `cn` is NOT exported from @sproutsocial/seeds-react-utilities, so each\n// Tailwind component carries its own copy.\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\n/**\n * Tailwind/CSS-class shell. The preferred path — routed to by `DrawerHybrid`\n * whenever the consumer passes no styled-system props. Renders the real Base UI\n * primitives (Backdrop/Viewport/Popup) with component-scoped classes from\n * `drawer.css`; the runtime numerics (`width`, `offset`, `zIndex`) are applied\n * as direct inline styles so drag/swipe/snap/portal behaviour is preserved.\n */\nconst DrawerTailwind = (props: TypeDrawerProps) => {\n const shell = useDrawerShell(props);\n const {\n effectiveDirection,\n hasSnapPoints,\n hasActionRail,\n rootProps,\n rest,\n width,\n offset,\n zIndex,\n id,\n open,\n } = shell;\n\n // `className` and `style` are public <div> props (TypeDrawerProps extends\n // ComponentPropsWithoutRef<\"div\">) that arrive via `rest`. Pull them out so\n // they MERGE with the popup's computed classes/geometry instead of\n // overwriting them — matching the styled-components path, where a consumer\n // className is appended to the generated class and an inline style wins over\n // the generated width.\n const { className, style, ...domRest } = rest as {\n className?: string;\n style?: CSSProperties;\n } & Record<string, unknown>;\n\n return (\n <BaseDrawer.Root {...rootProps}>\n <BaseDrawer.Portal>\n <BaseDrawer.Backdrop\n data-testid=\"drawer-backdrop\"\n className=\"seeds-drawer-backdrop\"\n />\n <BaseDrawer.Viewport\n className={cn(\"seeds-drawer-viewport\", {\n \"seeds-drawer-viewport--snap\": hasSnapPoints,\n })}\n >\n <BaseDrawer.Popup\n initialFocus\n data-qa-drawer={id}\n data-qa-drawer-isopen={open}\n {...domRest}\n className={cn(\n \"seeds-drawer-popup\",\n effectiveDirection === \"bottom\"\n ? \"seeds-drawer-popup--bottom\"\n : \"seeds-drawer-popup--side\",\n effectiveDirection === \"right\" && \"seeds-drawer-popup--right\",\n effectiveDirection === \"left\" && \"seeds-drawer-popup--left\",\n {\n \"seeds-drawer-popup--snap\": hasSnapPoints,\n \"seeds-drawer-popup--action-rail\": hasActionRail,\n },\n // Consumer className folded in last so it appends to (not\n // replaces) the component classes.\n className\n )}\n style={{\n // z-index is always inline (runtime numeric, mirrors styles.ts).\n zIndex,\n // Side drawers carry their width/offset as direct inline styles —\n // runtime numerics, and required for the jsdom `toHaveStyle`\n // assertions. Bottom drawers derive width/position from the class.\n ...(effectiveDirection === \"right\"\n ? { width: `${width}px`, right: `${offset}px` }\n : effectiveDirection === \"left\"\n ? { width: `${width}px`, left: `${offset}px` }\n : {}),\n // Consumer style folded in last so it wins over the computed\n // geometry, matching the styled-components inline-style semantics.\n ...style,\n }}\n >\n {effectiveDirection === \"bottom\" && (\n <div aria-hidden className=\"seeds-drawer-drag-handle\" />\n )}\n <DrawerPopupContents shell={shell} />\n </BaseDrawer.Popup>\n </BaseDrawer.Viewport>\n </BaseDrawer.Portal>\n </BaseDrawer.Root>\n );\n};\n\nexport default DrawerTailwind;\n","import DrawerHybrid from \"./DrawerHybrid\";\n\n/**\n * Drawer component. Automatically routes between the Tailwind implementation\n * (preferred) and the styled-components implementation (for consumers using\n * system props or a `styled()` extension). The default export carries the\n * `.Header`, `.Content`, and `.CloseButton` statics.\n */\nexport { DrawerContext } from \"./DrawerShared\";\nexport default DrawerHybrid;\n","import * as React from \"react\";\nimport type {\n TypeSystemCommonProps,\n TypeStyledComponentsCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\nimport type { TypeIconName } from \"@sproutsocial/seeds-react-icon\";\n\ntype DrawerAnimationDirection = \"left\" | \"right\" | \"bottom\";\n\n/**\n * Action button shown in the mobile rail above a bottom-sheet drawer.\n * Mirrors `TypeModalActionProps` so consumers can share the same array shape.\n */\nexport type TypeDrawerActionProps = {\n /** Accessible label for the action button. */\n \"aria-label\": string;\n /** Icon name from the Seeds icon set. */\n iconName?: TypeIconName;\n /** Click handler. */\n onClick?: () => void;\n /** Disable the action. */\n disabled?: boolean;\n};\n\n/**\n * A snap point the bottom drawer can rest at.\n * - Numbers 0–1: fraction of viewport height\n * - Numbers > 1: pixels\n * - Strings: CSS lengths in `px` or `rem` (e.g. `\"480px\"`, `\"30rem\"`)\n */\nexport type TypeDrawerSnapPoint = number | string;\n\nexport interface TypeDrawerContext {\n /** Callback for close button */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClose?: () => any;\n\n /** aria-label for drawer close button */\n closeButtonLabel?: string;\n /**\n * isLocked and setIsLocked are used when a Drawer contains other components (like Menu) that also\n * listen for Escape key events. By locking the Drawer, we can prevent conflicts\n * where multiple components try to handle the same keydown event.\n */\n isLocked: boolean;\n setIsLocked: (locked: boolean) => void;\n /**\n * True when the Drawer is rendering an `ActionRail` above the popup. The\n * default `Drawer.Header` reads this to omit its built-in close button so the\n * rail can own the close affordance.\n */\n hasActionRail?: boolean;\n}\n// TODO: Should the render prop be a React.FC?\nexport interface TypeDrawerCloseButtonProps\n extends Omit<TypeButtonProps, \"children\"> {\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the on-close behavior. */\n render?: React.FC<TypeDrawerContext>;\n children?: React.ReactNode;\n}\n\nexport interface TypeDrawerHeaderProps extends TypeBoxProps {\n title?: string;\n /**\n * When children are provided, `<Drawer.CloseButton />` is NOT rendered automatically.\n * You must include it yourself inside children to preserve keyboard accessibility.\n */\n children?: React.ReactNode;\n\n /** An optional function that receives the context of the parent drawer as an argument. Can be used to customize the appearance of the header. */\n render?: React.FC<TypeDrawerContext>;\n}\n\nexport interface TypeDrawerProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<React.ComponentPropsWithoutRef<\"div\">, \"color\"> {\n children: React.ReactNode;\n\n /** Label for the close button. Usually this should be \"Close\" */\n closeButtonLabel: string;\n\n /** Whether the drawer slides in from the left or right side of the screen */\n direction?: DrawerAnimationDirection;\n\n /** In some cases, you may not want the user to be able to click outside of the drawer to close it. You can disable that with this prop. */\n disableCloseOnClickOutside?: boolean;\n\n /**\n * When true, siblings are inerted while the drawer is open — appropriate for forms or settings\n * panels where page interaction should be blocked.\n * Defaults to false to preserve the original non-modal behavior where the rest of the page\n * remains interactive (side info panels, notification slide-outs, persistent inspectors, etc.).\n */\n modal?: boolean;\n /** Optional id used for data-qa-drawer attributes */\n id?: string;\n open: boolean;\n offset?: number;\n onClose: () => void;\n zIndex?: number;\n width?: number;\n\n /**\n * Snap points the drawer can rest at when swiped. Only applied to bottom drawers.\n * Numbers 0–1 are viewport-height fractions; numbers > 1 are pixels; strings accept\n * `px`/`rem` (e.g. `\"480px\"`, `\"30rem\"`). Order matters — the last entry is the\n * \"expanded\" state and gets a `data-expanded` attribute on the popup.\n */\n snapPoints?: TypeDrawerSnapPoint[];\n\n /** Initial snap point for uncontrolled use. */\n defaultSnapPoint?: TypeDrawerSnapPoint | null;\n\n /** Controlled active snap point. Pair with `onSnapPointChange`. */\n snapPoint?: TypeDrawerSnapPoint | null;\n\n /** Fires when the active snap point changes (drag release, programmatic update, etc.). */\n onSnapPointChange?: (snapPoint: TypeDrawerSnapPoint | null) => void;\n\n /**\n * When true, fast swipes can't skip past adjacent snap points — drag distance alone\n * determines the next stop. Defaults to base-ui's `false` (velocity-based skipping).\n */\n snapToSequentialPoints?: boolean;\n\n /**\n * Action buttons shown in a floating rail above the drawer on mobile (the\n * bottom-sheet rendering). The rail also owns the close button — when this\n * prop is provided, the default `Drawer.Header` omits its built-in close\n * button so the rail can render it instead. Ignored on desktop side drawers.\n */\n actions?: TypeDrawerActionProps[];\n\n /**\n * Opt out of the floating rail and keep the actions inside `Drawer.Header`\n * (the pre-rail behavior). Useful for nested bottom sheets and snap-point\n * drawers where the rail-above placement would collide with surrounding UI\n * or fall off-screen at the highest snap point. Defaults to `false`.\n *\n * When `true`, the Drawer does NOT render the rail; consumers are\n * responsible for rendering action buttons (and the close button) inside\n * their `Drawer.Header`.\n */\n actionsInHeader?: boolean;\n}\n\nexport interface TypeDrawerContentProps extends TypeBoxProps {\n children?: React.ReactNode;\n}\n"],"mappings":"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","names":["import_seeds_react_system_props","import_drawer","import_styled_components","styled","React","import_styled_components","import_jsx_runtime","styled","styled","Box","React","import_drawer","import_seeds_react_box","import_seeds_react_system_props","import_jsx_runtime","Button","Icon","Box","Text","import_jsx_runtime","BaseDrawer","import_drawer","import_jsx_runtime","cn","BaseDrawer","import_jsx_runtime","React"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-drawer",
3
- "version": "2.2.8",
3
+ "version": "2.2.10",
4
4
  "description": "Seeds React Drawer",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -30,13 +30,13 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@base-ui/react": "^1.3.0",
33
- "@sproutsocial/seeds-react-theme": "^4.1.1",
33
+ "@sproutsocial/seeds-react-theme": "^4.2.0",
34
34
  "@sproutsocial/seeds-react-system-props": "^3.1.1",
35
- "@sproutsocial/seeds-react-box": "^1.1.22",
36
- "@sproutsocial/seeds-react-button": "^2.2.2",
37
- "@sproutsocial/seeds-react-icon": "^2.4.1",
38
- "@sproutsocial/seeds-react-mixins": "^4.3.8",
39
- "@sproutsocial/seeds-react-text": "^1.4.3",
35
+ "@sproutsocial/seeds-react-box": "^1.1.23",
36
+ "@sproutsocial/seeds-react-button": "^2.2.3",
37
+ "@sproutsocial/seeds-react-icon": "^2.4.2",
38
+ "@sproutsocial/seeds-react-mixins": "^4.3.9",
39
+ "@sproutsocial/seeds-react-text": "^1.5.0",
40
40
  "@sproutsocial/seeds-motion": "^1.8.2",
41
41
  "@sproutsocial/seeds-react-portal": "*",
42
42
  "@sproutsocial/seeds-react-hooks": "*"