@waveso/ui 0.7.2 → 0.7.5

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/masonry.js CHANGED
@@ -3,7 +3,7 @@ import { cn } from "./lib/utils.js";
3
3
  import { StarIcon } from "./lib/internal-icons.js";
4
4
  import * as React from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
- import { AnimatePresence, motion } from "motion/react";
6
+ import { AnimatePresence, motion, useReducedMotion } from "motion/react";
7
7
  //#region src/masonry.tsx
8
8
  const STAGGER_STEP = .05;
9
9
  const MasonryStaggerContext = React.createContext(null);
@@ -159,12 +159,17 @@ function FeaturedBadge() {
159
159
  function MasonryItem({ className, span, children, ...props }) {
160
160
  const isSpanned = span != null && span > 1;
161
161
  const getStaggerIndex = React.useContext(MasonryStaggerContext);
162
+ const prefersReducedMotion = useReducedMotion();
162
163
  const [staggerDelay] = React.useState(() => getStaggerIndex ? getStaggerIndex() * STAGGER_STEP : 0);
163
164
  return /* @__PURE__ */ jsxs(motion.div, {
164
165
  "data-slot": "masonry-item",
165
166
  "data-span": isSpanned ? span : void 0,
166
167
  className: cn("relative", className),
167
- initial: {
168
+ initial: prefersReducedMotion ? {
169
+ opacity: 1,
170
+ y: 0,
171
+ filter: "blur(0px)"
172
+ } : {
168
173
  opacity: 0,
169
174
  y: 10,
170
175
  filter: "blur(8px)"
@@ -174,13 +179,13 @@ function MasonryItem({ className, span, children, ...props }) {
174
179
  y: 0,
175
180
  filter: "blur(0px)"
176
181
  },
177
- transition: {
182
+ transition: prefersReducedMotion ? { duration: 0 } : {
178
183
  type: "spring",
179
184
  stiffness: 100,
180
185
  damping: 10,
181
186
  delay: staggerDelay
182
187
  },
183
- exit: {
188
+ exit: prefersReducedMotion ? { opacity: 0 } : {
184
189
  opacity: 0,
185
190
  scale: 1.2,
186
191
  filter: "blur(8px)"
@@ -1 +1 @@
1
- {"version":3,"file":"masonry.js","names":[],"sources":["../src/masonry.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { AnimatePresence, type HTMLMotionProps, motion } from \"motion/react\"\n\nimport { StarIcon } from \"./lib/internal-icons\"\nimport { cn } from \"./lib/utils\"\n\nconst STAGGER_STEP = 0.05 // 50ms between each item's enter animation\n\nconst MasonryStaggerContext = React.createContext<(() => number) | null>(null)\n\ntype MasonryProps = React.ComponentProps<\"div\"> & {\n columns?: number\n columnWidth?: number\n gap?: number\n}\n\ntype MasonryItemProps = Omit<HTMLMotionProps<\"div\">, \"children\"> & {\n span?: number\n children?: React.ReactNode\n}\n\nfunction Masonry({\n columns,\n columnWidth,\n gap = 4,\n className,\n children,\n ...props\n}: MasonryProps) {\n const containerRef = React.useRef<HTMLDivElement>(null)\n const rafRef = React.useRef<number>(0)\n const staggerCounterRef = React.useRef(0)\n\n // Reset counter each render so new items in a batch get fresh 0-based indices\n staggerCounterRef.current = 0\n\n const getStaggerIndex = React.useCallback(\n () => staggerCounterRef.current++,\n [],\n )\n\n React.useLayoutEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const remPx = parseFloat(\n getComputedStyle(document.documentElement).fontSize,\n )\n const gapPx = gap * 0.25 * remPx\n\n function reflow() {\n const allChildren = Array.from(container!.children) as HTMLElement[]\n // Skip exiting items — they keep their position during exit animation\n const items = allChildren.filter((el) => el.dataset.exiting == null)\n\n if (items.length === 0) {\n container!.style.removeProperty(\"height\")\n return\n }\n\n const containerWidth = container!.clientWidth\n if (containerWidth === 0) return\n\n let colCount: number\n if (columns != null) {\n colCount = Math.max(1, columns)\n } else if (columnWidth != null) {\n colCount = Math.max(\n 1,\n Math.floor((containerWidth + gapPx) / (columnWidth + gapPx)),\n )\n } else {\n colCount = Math.max(\n 1,\n Math.floor((containerWidth + gapPx) / (240 + gapPx)),\n )\n }\n\n // Single column: use normal flow with gap\n if (colCount <= 1) {\n container!.style.removeProperty(\"height\")\n container!.style.display = \"flex\"\n container!.style.flexDirection = \"column\"\n container!.style.gap = `${gapPx}px`\n for (const item of items) {\n item.style.removeProperty(\"position\")\n item.style.removeProperty(\"top\")\n item.style.removeProperty(\"left\")\n item.style.removeProperty(\"width\")\n }\n return\n }\n\n // Multi-column: clear single-column styles\n container!.style.removeProperty(\"display\")\n container!.style.removeProperty(\"flex-direction\")\n container!.style.removeProperty(\"gap\")\n\n const colWidth = (containerWidth - (colCount - 1) * gapPx) / colCount\n const columnBottoms = new Array<number>(colCount).fill(0)\n\n // Partition items: spanning (top-pinned) vs regular\n const topItems: { el: HTMLElement; span: number }[] = []\n const regularItems: HTMLElement[] = []\n for (const item of items) {\n const raw = parseInt(item.dataset.span || \"1\", 10)\n if (raw > 1) {\n topItems.push({ el: item, span: Math.min(raw, colCount) })\n } else {\n regularItems.push(item)\n }\n }\n\n // First pass: set width on all items for correct height measurement\n for (const { el, span } of topItems) {\n el.style.position = \"absolute\"\n el.style.width = `${span * colWidth + (span - 1) * gapPx}px`\n }\n for (const item of regularItems) {\n item.style.position = \"absolute\"\n item.style.width = `${colWidth}px`\n }\n\n // Second pass: batch-read heights\n const topHeights: number[] = []\n for (const { el } of topItems) {\n topHeights.push(el.offsetHeight)\n }\n const regularHeights: number[] = []\n for (const item of regularItems) {\n regularHeights.push(item.offsetHeight)\n }\n\n // Third pass: place top items at Y=0, left-to-right\n let nextCol = 0\n for (let i = 0; i < topItems.length; i++) {\n const { el, span } = topItems[i]!\n const s = Math.min(span, colCount - nextCol)\n\n const x = nextCol * (colWidth + gapPx)\n el.style.top = \"0px\"\n el.style.left = `${x}px`\n // Recalculate width if span was clamped\n if (s !== span) {\n el.style.width = `${s * colWidth + (s - 1) * gapPx}px`\n }\n\n const bottom = topHeights[i]! + gapPx\n for (let c = nextCol; c < nextCol + s; c++) {\n columnBottoms[c] = bottom\n }\n\n nextCol += s\n }\n\n // Fourth pass: place regular items in shortest column\n for (let i = 0; i < regularItems.length; i++) {\n let shortestCol = 0\n for (let c = 1; c < colCount; c++) {\n if (columnBottoms[c]! < columnBottoms[shortestCol]!) {\n shortestCol = c\n }\n }\n\n const x = shortestCol * (colWidth + gapPx)\n const y = columnBottoms[shortestCol]!\n\n regularItems[i]!.style.top = `${y}px`\n regularItems[i]!.style.left = `${x}px`\n\n columnBottoms[shortestCol] = y + regularHeights[i]! + gapPx\n }\n\n const maxBottom = Math.max(...columnBottoms) - gapPx\n container!.style.height = `${Math.max(0, maxBottom)}px`\n }\n\n function scheduleReflow() {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = requestAnimationFrame(reflow)\n }\n\n reflow()\n\n const ro = new ResizeObserver(scheduleReflow)\n ro.observe(container)\n\n const mo = new MutationObserver(scheduleReflow)\n mo.observe(container, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"data-exiting\", \"data-span\"],\n })\n\n // Detect image/media loads that change item heights\n container.addEventListener(\"load\", scheduleReflow, true)\n\n return () => {\n cancelAnimationFrame(rafRef.current)\n ro.disconnect()\n mo.disconnect()\n container.removeEventListener(\"load\", scheduleReflow, true)\n container.style.removeProperty(\"height\")\n container.style.removeProperty(\"display\")\n container.style.removeProperty(\"flex-direction\")\n container.style.removeProperty(\"gap\")\n const items = Array.from(container.children) as HTMLElement[]\n for (const item of items) {\n item.style.removeProperty(\"position\")\n item.style.removeProperty(\"top\")\n item.style.removeProperty(\"left\")\n item.style.removeProperty(\"width\")\n }\n }\n }, [columns, columnWidth, gap])\n\n return (\n <MasonryStaggerContext.Provider value={getStaggerIndex}>\n <div\n ref={containerRef}\n data-slot=\"masonry\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <AnimatePresence>\n {children}\n </AnimatePresence>\n </div>\n </MasonryStaggerContext.Provider>\n )\n}\n\nfunction FeaturedBadge() {\n return (\n <span\n data-slot=\"masonry-badge\"\n className=\"absolute top-2 right-2 z-10 flex size-5 items-center justify-center pointer-events-none\"\n role=\"img\"\n aria-label=\"Featured\"\n >\n <StarIcon width={10} height={10} fill=\"currentColor\" aria-hidden />\n </span>\n )\n}\n\nfunction MasonryItem({\n className,\n span,\n children,\n ...props\n}: MasonryItemProps) {\n const isSpanned = span != null && span > 1\n const getStaggerIndex = React.useContext(MasonryStaggerContext)\n\n // Capture stagger index once on mount — useState initializer runs exactly once\n const [staggerDelay] = React.useState(() =>\n getStaggerIndex ? getStaggerIndex() * STAGGER_STEP : 0,\n )\n\n return (\n <motion.div\n data-slot=\"masonry-item\"\n data-span={isSpanned ? span : undefined}\n className={cn(\"relative\", className)}\n initial={{\n opacity: 0,\n y: 10,\n filter: \"blur(8px)\"\n }}\n animate={{\n opacity: 1,\n y: 0,\n filter: \"blur(0px)\"\n }}\n transition={{\n type: \"spring\",\n stiffness: 100,\n damping: 10,\n delay: staggerDelay,\n }}\n exit={{\n opacity: 0,\n scale: 1.2,\n filter: \"blur(8px)\",\n }}\n {...props}\n >\n {children}\n {isSpanned && <FeaturedBadge />}\n </motion.div>\n )\n}\n\nexport { Masonry, MasonryItem }\n"],"mappings":"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"}
1
+ {"version":3,"file":"masonry.js","names":[],"sources":["../src/masonry.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport {\n AnimatePresence,\n type HTMLMotionProps,\n motion,\n useReducedMotion,\n} from \"motion/react\"\n\nimport { StarIcon } from \"./lib/internal-icons\"\nimport { cn } from \"./lib/utils\"\n\nconst STAGGER_STEP = 0.05 // 50ms between each item's enter animation\n\nconst MasonryStaggerContext = React.createContext<(() => number) | null>(null)\n\ntype MasonryProps = React.ComponentProps<\"div\"> & {\n columns?: number\n columnWidth?: number\n gap?: number\n}\n\ntype MasonryItemProps = Omit<HTMLMotionProps<\"div\">, \"children\"> & {\n span?: number\n children?: React.ReactNode\n}\n\nfunction Masonry({\n columns,\n columnWidth,\n gap = 4,\n className,\n children,\n ...props\n}: MasonryProps) {\n const containerRef = React.useRef<HTMLDivElement>(null)\n const rafRef = React.useRef<number>(0)\n const staggerCounterRef = React.useRef(0)\n\n // Reset counter each render so new items in a batch get fresh 0-based indices\n staggerCounterRef.current = 0\n\n const getStaggerIndex = React.useCallback(\n () => staggerCounterRef.current++,\n [],\n )\n\n React.useLayoutEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const remPx = parseFloat(\n getComputedStyle(document.documentElement).fontSize,\n )\n const gapPx = gap * 0.25 * remPx\n\n function reflow() {\n const allChildren = Array.from(container!.children) as HTMLElement[]\n // Skip exiting items — they keep their position during exit animation\n const items = allChildren.filter((el) => el.dataset.exiting == null)\n\n if (items.length === 0) {\n container!.style.removeProperty(\"height\")\n return\n }\n\n const containerWidth = container!.clientWidth\n if (containerWidth === 0) return\n\n let colCount: number\n if (columns != null) {\n colCount = Math.max(1, columns)\n } else if (columnWidth != null) {\n colCount = Math.max(\n 1,\n Math.floor((containerWidth + gapPx) / (columnWidth + gapPx)),\n )\n } else {\n colCount = Math.max(\n 1,\n Math.floor((containerWidth + gapPx) / (240 + gapPx)),\n )\n }\n\n // Single column: use normal flow with gap\n if (colCount <= 1) {\n container!.style.removeProperty(\"height\")\n container!.style.display = \"flex\"\n container!.style.flexDirection = \"column\"\n container!.style.gap = `${gapPx}px`\n for (const item of items) {\n item.style.removeProperty(\"position\")\n item.style.removeProperty(\"top\")\n item.style.removeProperty(\"left\")\n item.style.removeProperty(\"width\")\n }\n return\n }\n\n // Multi-column: clear single-column styles\n container!.style.removeProperty(\"display\")\n container!.style.removeProperty(\"flex-direction\")\n container!.style.removeProperty(\"gap\")\n\n const colWidth = (containerWidth - (colCount - 1) * gapPx) / colCount\n const columnBottoms = new Array<number>(colCount).fill(0)\n\n // Partition items: spanning (top-pinned) vs regular\n const topItems: { el: HTMLElement; span: number }[] = []\n const regularItems: HTMLElement[] = []\n for (const item of items) {\n const raw = parseInt(item.dataset.span || \"1\", 10)\n if (raw > 1) {\n topItems.push({ el: item, span: Math.min(raw, colCount) })\n } else {\n regularItems.push(item)\n }\n }\n\n // First pass: set width on all items for correct height measurement\n for (const { el, span } of topItems) {\n el.style.position = \"absolute\"\n el.style.width = `${span * colWidth + (span - 1) * gapPx}px`\n }\n for (const item of regularItems) {\n item.style.position = \"absolute\"\n item.style.width = `${colWidth}px`\n }\n\n // Second pass: batch-read heights\n const topHeights: number[] = []\n for (const { el } of topItems) {\n topHeights.push(el.offsetHeight)\n }\n const regularHeights: number[] = []\n for (const item of regularItems) {\n regularHeights.push(item.offsetHeight)\n }\n\n // Third pass: place top items at Y=0, left-to-right\n let nextCol = 0\n for (let i = 0; i < topItems.length; i++) {\n const { el, span } = topItems[i]!\n const s = Math.min(span, colCount - nextCol)\n\n const x = nextCol * (colWidth + gapPx)\n el.style.top = \"0px\"\n el.style.left = `${x}px`\n // Recalculate width if span was clamped\n if (s !== span) {\n el.style.width = `${s * colWidth + (s - 1) * gapPx}px`\n }\n\n const bottom = topHeights[i]! + gapPx\n for (let c = nextCol; c < nextCol + s; c++) {\n columnBottoms[c] = bottom\n }\n\n nextCol += s\n }\n\n // Fourth pass: place regular items in shortest column\n for (let i = 0; i < regularItems.length; i++) {\n let shortestCol = 0\n for (let c = 1; c < colCount; c++) {\n if (columnBottoms[c]! < columnBottoms[shortestCol]!) {\n shortestCol = c\n }\n }\n\n const x = shortestCol * (colWidth + gapPx)\n const y = columnBottoms[shortestCol]!\n\n regularItems[i]!.style.top = `${y}px`\n regularItems[i]!.style.left = `${x}px`\n\n columnBottoms[shortestCol] = y + regularHeights[i]! + gapPx\n }\n\n const maxBottom = Math.max(...columnBottoms) - gapPx\n container!.style.height = `${Math.max(0, maxBottom)}px`\n }\n\n function scheduleReflow() {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = requestAnimationFrame(reflow)\n }\n\n reflow()\n\n const ro = new ResizeObserver(scheduleReflow)\n ro.observe(container)\n\n const mo = new MutationObserver(scheduleReflow)\n mo.observe(container, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"data-exiting\", \"data-span\"],\n })\n\n // Detect image/media loads that change item heights\n container.addEventListener(\"load\", scheduleReflow, true)\n\n return () => {\n cancelAnimationFrame(rafRef.current)\n ro.disconnect()\n mo.disconnect()\n container.removeEventListener(\"load\", scheduleReflow, true)\n container.style.removeProperty(\"height\")\n container.style.removeProperty(\"display\")\n container.style.removeProperty(\"flex-direction\")\n container.style.removeProperty(\"gap\")\n const items = Array.from(container.children) as HTMLElement[]\n for (const item of items) {\n item.style.removeProperty(\"position\")\n item.style.removeProperty(\"top\")\n item.style.removeProperty(\"left\")\n item.style.removeProperty(\"width\")\n }\n }\n }, [columns, columnWidth, gap])\n\n return (\n <MasonryStaggerContext.Provider value={getStaggerIndex}>\n <div\n ref={containerRef}\n data-slot=\"masonry\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <AnimatePresence>\n {children}\n </AnimatePresence>\n </div>\n </MasonryStaggerContext.Provider>\n )\n}\n\nfunction FeaturedBadge() {\n return (\n <span\n data-slot=\"masonry-badge\"\n className=\"absolute top-2 right-2 z-10 flex size-5 items-center justify-center pointer-events-none\"\n role=\"img\"\n aria-label=\"Featured\"\n >\n <StarIcon width={10} height={10} fill=\"currentColor\" aria-hidden />\n </span>\n )\n}\n\nfunction MasonryItem({\n className,\n span,\n children,\n ...props\n}: MasonryItemProps) {\n const isSpanned = span != null && span > 1\n const getStaggerIndex = React.useContext(MasonryStaggerContext)\n const prefersReducedMotion = useReducedMotion()\n\n // Capture stagger index once on mount — useState initializer runs exactly once\n const [staggerDelay] = React.useState(() =>\n getStaggerIndex ? getStaggerIndex() * STAGGER_STEP : 0,\n )\n\n // Reduced motion: render items in their final resting state with no\n // entrance spring, blur, or stagger — they appear immediately and exit\n // with a plain fade. Same DOM/output as the settled animated state.\n return (\n <motion.div\n data-slot=\"masonry-item\"\n data-span={isSpanned ? span : undefined}\n className={cn(\"relative\", className)}\n initial={\n prefersReducedMotion\n ? { opacity: 1, y: 0, filter: \"blur(0px)\" }\n : {\n opacity: 0,\n y: 10,\n filter: \"blur(8px)\",\n }\n }\n animate={{\n opacity: 1,\n y: 0,\n filter: \"blur(0px)\"\n }}\n transition={\n prefersReducedMotion\n ? { duration: 0 }\n : {\n type: \"spring\",\n stiffness: 100,\n damping: 10,\n delay: staggerDelay,\n }\n }\n exit={\n prefersReducedMotion\n ? { opacity: 0 }\n : {\n opacity: 0,\n scale: 1.2,\n filter: \"blur(8px)\",\n }\n }\n {...props}\n >\n {children}\n {isSpanned && <FeaturedBadge />}\n </motion.div>\n )\n}\n\nexport { Masonry, MasonryItem }\n"],"mappings":"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"}
@@ -7,7 +7,8 @@ type PaginationProps = React.ComponentProps<"nav">;
7
7
  type PaginationContentProps = React.ComponentProps<"ul">;
8
8
  type PaginationItemProps = React.ComponentProps<"li">;
9
9
  type PaginationLinkProps = {
10
- isActive?: boolean;
10
+ isActive?: boolean; /** Marks the link disabled — aria-disabled, removed from tab order, non-interactive. */
11
+ disabled?: boolean;
11
12
  } & Pick<React.ComponentProps<typeof Button>, "size"> & React.ComponentProps<"a">;
12
13
  type PaginationPreviousProps = PaginationLinkProps & {
13
14
  text?: string;
@@ -28,6 +29,7 @@ declare function PaginationItem(props: PaginationItemProps): _$react_jsx_runtime
28
29
  declare function PaginationLink({
29
30
  className,
30
31
  isActive,
32
+ disabled,
31
33
  size,
32
34
  ...props
33
35
  }: PaginationLinkProps): _$react_jsx_runtime0.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.d.ts","names":[],"sources":["../src/pagination.tsx"],"mappings":";;;;;KAWK,eAAA,GAAkB,KAAA,CAAM,cAAA;AAAA,KAExB,sBAAA,GAAyB,KAAA,CAAM,cAAA;AAAA,KAE/B,mBAAA,GAAsB,KAAA,CAAM,cAAA;AAAA,KAE5B,mBAAA;EACH,QAAA;AAAA,IACE,IAAA,CAAK,KAAA,CAAM,cAAA,QAAsB,MAAA,aACnC,KAAA,CAAM,cAAA;AAAA,KAEH,uBAAA,GAA0B,mBAAA;EAC7B,IAAA;AAAA;AAAA,KAGG,mBAAA,GAAsB,mBAAA;EACzB,IAAA;AAAA;AAAA,KAGG,uBAAA,GAA0B,KAAA,CAAM,cAAA;AAAA,iBAE5B,UAAA,CAAA;EAAa,SAAA;EAAA,GAAc;AAAA,GAAS,eAAA,GAAe,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAenD,iBAAA,CAAA;EAAoB,SAAA;EAAA,GAAc;AAAA,GAAS,sBAAA,GAAsB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAajE,cAAA,CAAe,KAAA,EAAO,mBAAA,GAAmB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAIzC,cAAA,CAAA;EACP,SAAA;EACA,QAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,mBAAA,GAAmB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAkBb,kBAAA,CAAA;EACP,SAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,uBAAA,GAAuB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAcjB,cAAA,CAAA;EACP,SAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,mBAAA,GAAmB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAcb,kBAAA,CAAA;EAAqB,SAAA;EAAA,GAAc;AAAA,GAAS,uBAAA,GAAuB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"pagination.d.ts","names":[],"sources":["../src/pagination.tsx"],"mappings":";;;;;KAWK,eAAA,GAAkB,KAAA,CAAM,cAAA;AAAA,KAExB,sBAAA,GAAyB,KAAA,CAAM,cAAA;AAAA,KAE/B,mBAAA,GAAsB,KAAA,CAAM,cAAA;AAAA,KAE5B,mBAAA;EACH,QAAA;EAEA,QAAA;AAAA,IACE,IAAA,CAAK,KAAA,CAAM,cAAA,QAAsB,MAAA,aACnC,KAAA,CAAM,cAAA;AAAA,KAEH,uBAAA,GAA0B,mBAAA;EAC7B,IAAA;AAAA;AAAA,KAGG,mBAAA,GAAsB,mBAAA;EACzB,IAAA;AAAA;AAAA,KAGG,uBAAA,GAA0B,KAAA,CAAM,cAAA;AAAA,iBAE5B,UAAA,CAAA;EAAa,SAAA;EAAA,GAAc;AAAA,GAAS,eAAA,GAAe,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAenD,iBAAA,CAAA;EAAoB,SAAA;EAAA,GAAc;AAAA,GAAS,sBAAA,GAAsB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAajE,cAAA,CAAe,KAAA,EAAO,mBAAA,GAAmB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAIzC,cAAA,CAAA;EACP,SAAA;EACA,QAAA;EACA,QAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,mBAAA,GAAmB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAoBb,kBAAA,CAAA;EACP,SAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,uBAAA,GAAuB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAcjB,cAAA,CAAA;EACP,SAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,mBAAA,GAAmB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAcb,kBAAA,CAAA;EAAqB,SAAA;EAAA,GAAc;AAAA,GAAS,uBAAA,GAAuB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -26,15 +26,17 @@ function PaginationItem(props) {
26
26
  ...props
27
27
  });
28
28
  }
29
- function PaginationLink({ className, isActive, size = "icon", ...props }) {
29
+ function PaginationLink({ className, isActive, disabled, size = "icon", ...props }) {
30
30
  return /* @__PURE__ */ jsx(Button, {
31
31
  variant: isActive ? "outline" : "ghost",
32
32
  size,
33
- className,
33
+ className: cn(disabled && "pointer-events-none opacity-50", className),
34
34
  render: /* @__PURE__ */ jsx("a", {
35
35
  "aria-current": isActive ? "page" : void 0,
36
+ "aria-disabled": disabled || void 0,
36
37
  "data-slot": "pagination-link",
37
38
  "data-active": isActive || void 0,
39
+ tabIndex: disabled ? -1 : void 0,
38
40
  ...props
39
41
  })
40
42
  });
@@ -65,7 +67,6 @@ function PaginationNext({ className, text = "Next", ...props }) {
65
67
  }
66
68
  function PaginationEllipsis({ className, ...props }) {
67
69
  return /* @__PURE__ */ jsxs("span", {
68
- "aria-hidden": true,
69
70
  "data-slot": "pagination-ellipsis",
70
71
  className: cn("flex size-8 items-center justify-center [&_svg:not([class*='size-'])]:size-4", className),
71
72
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","names":[],"sources":["../src/pagination.tsx"],"sourcesContent":["import * as React from \"react\"\n\nimport { Button } from \"./button\"\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n EllipsisIcon,\n} from \"./lib/internal-icons\"\n\nimport { cn } from \"./lib/utils\"\n\ntype PaginationProps = React.ComponentProps<\"nav\">\n\ntype PaginationContentProps = React.ComponentProps<\"ul\">\n\ntype PaginationItemProps = React.ComponentProps<\"li\">\n\ntype PaginationLinkProps = {\n isActive?: boolean\n} & Pick<React.ComponentProps<typeof Button>, \"size\"> &\n React.ComponentProps<\"a\">\n\ntype PaginationPreviousProps = PaginationLinkProps & {\n text?: string\n}\n\ntype PaginationNextProps = PaginationLinkProps & {\n text?: string\n}\n\ntype PaginationEllipsisProps = React.ComponentProps<\"span\">\n\nfunction Pagination({ className, ...props }: PaginationProps) {\n return (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n className={cn(\n \"mx-auto flex w-full justify-center\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction PaginationContent({ className, ...props }: PaginationContentProps) {\n return (\n <ul\n data-slot=\"pagination-content\"\n className={cn(\n \"flex items-center gap-0.5\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction PaginationItem(props: PaginationItemProps) {\n return <li data-slot=\"pagination-item\" {...props} />\n}\n\nfunction PaginationLink({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) {\n return (\n <Button\n variant={isActive ? \"outline\" : \"ghost\"}\n size={size}\n className={className}\n render={\n <a\n aria-current={isActive ? \"page\" : undefined}\n data-slot=\"pagination-link\"\n data-active={isActive || undefined}\n {...props}\n />\n }\n />\n )\n}\n\nfunction PaginationPrevious({\n className,\n text = \"Previous\",\n ...props\n}: PaginationPreviousProps) {\n return (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"pl-1.5!\", className)}\n {...props}\n >\n <ChevronLeftIcon data-icon=\"inline-start\" />\n <span className=\"hidden sm:block\">{text}</span>\n </PaginationLink>\n )\n}\n\nfunction PaginationNext({\n className,\n text = \"Next\",\n ...props\n}: PaginationNextProps) {\n return (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"pr-1.5!\", className)}\n {...props}\n >\n <span className=\"hidden sm:block\">{text}</span>\n <ChevronRightIcon data-icon=\"inline-end\" />\n </PaginationLink>\n )\n}\n\nfunction PaginationEllipsis({ className, ...props }: PaginationEllipsisProps) {\n return (\n <span\n aria-hidden\n data-slot=\"pagination-ellipsis\"\n className={cn(\n \"flex size-8 items-center justify-center [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n <EllipsisIcon />\n <span className=\"sr-only\">More pages</span>\n </span>\n )\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n}\n"],"mappings":";;;;;;AAgCA,SAAS,WAAW,EAAE,WAAW,GAAG,SAA0B;AAC5D,QACE,oBAAC,OAAD;EACE,MAAK;EACL,cAAW;EACX,aAAU;EACV,WAAW,GACT,sCACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,kBAAkB,EAAE,WAAW,GAAG,SAAiC;AAC1E,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,6BACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,eAAe,OAA4B;AAClD,QAAO,oBAAC,MAAD;EAAI,aAAU;EAAkB,GAAI;EAAS,CAAA;;AAGtD,SAAS,eAAe,EACtB,WACA,UACA,OAAO,QACP,GAAG,SACmB;AACtB,QACE,oBAAC,QAAD;EACE,SAAS,WAAW,YAAY;EAC1B;EACK;EACX,QACE,oBAAC,KAAD;GACE,gBAAc,WAAW,SAAS,KAAA;GAClC,aAAU;GACV,eAAa,YAAY,KAAA;GACzB,GAAI;GACJ,CAAA;EAEJ,CAAA;;AAIN,SAAS,mBAAmB,EAC1B,WACA,OAAO,YACP,GAAG,SACuB;AAC1B,QACE,qBAAC,gBAAD;EACE,cAAW;EACX,MAAK;EACL,WAAW,GAAG,WAAW,UAAU;EACnC,GAAI;YAJN,CAME,oBAAC,iBAAD,EAAiB,aAAU,gBAAiB,CAAA,EAC5C,oBAAC,QAAD;GAAM,WAAU;aAAmB;GAAY,CAAA,CAChC;;;AAIrB,SAAS,eAAe,EACtB,WACA,OAAO,QACP,GAAG,SACmB;AACtB,QACE,qBAAC,gBAAD;EACE,cAAW;EACX,MAAK;EACL,WAAW,GAAG,WAAW,UAAU;EACnC,GAAI;YAJN,CAME,oBAAC,QAAD;GAAM,WAAU;aAAmB;GAAY,CAAA,EAC/C,oBAAC,kBAAD,EAAkB,aAAU,cAAe,CAAA,CAC5B;;;AAIrB,SAAS,mBAAmB,EAAE,WAAW,GAAG,SAAkC;AAC5E,QACE,qBAAC,QAAD;EACE,eAAA;EACA,aAAU;EACV,WAAW,GACT,gFACA,UACD;EACD,GAAI;YAPN,CASE,oBAAC,cAAD,EAAgB,CAAA,EAChB,oBAAC,QAAD;GAAM,WAAU;aAAU;GAAiB,CAAA,CACtC"}
1
+ {"version":3,"file":"pagination.js","names":[],"sources":["../src/pagination.tsx"],"sourcesContent":["import * as React from \"react\"\n\nimport { Button } from \"./button\"\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n EllipsisIcon,\n} from \"./lib/internal-icons\"\n\nimport { cn } from \"./lib/utils\"\n\ntype PaginationProps = React.ComponentProps<\"nav\">\n\ntype PaginationContentProps = React.ComponentProps<\"ul\">\n\ntype PaginationItemProps = React.ComponentProps<\"li\">\n\ntype PaginationLinkProps = {\n isActive?: boolean\n /** Marks the link disabled — aria-disabled, removed from tab order, non-interactive. */\n disabled?: boolean\n} & Pick<React.ComponentProps<typeof Button>, \"size\"> &\n React.ComponentProps<\"a\">\n\ntype PaginationPreviousProps = PaginationLinkProps & {\n text?: string\n}\n\ntype PaginationNextProps = PaginationLinkProps & {\n text?: string\n}\n\ntype PaginationEllipsisProps = React.ComponentProps<\"span\">\n\nfunction Pagination({ className, ...props }: PaginationProps) {\n return (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n className={cn(\n \"mx-auto flex w-full justify-center\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction PaginationContent({ className, ...props }: PaginationContentProps) {\n return (\n <ul\n data-slot=\"pagination-content\"\n className={cn(\n \"flex items-center gap-0.5\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction PaginationItem(props: PaginationItemProps) {\n return <li data-slot=\"pagination-item\" {...props} />\n}\n\nfunction PaginationLink({\n className,\n isActive,\n disabled,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) {\n return (\n <Button\n variant={isActive ? \"outline\" : \"ghost\"}\n size={size}\n className={cn(disabled && \"pointer-events-none opacity-50\", className)}\n render={\n <a\n aria-current={isActive ? \"page\" : undefined}\n aria-disabled={disabled || undefined}\n data-slot=\"pagination-link\"\n data-active={isActive || undefined}\n tabIndex={disabled ? -1 : undefined}\n {...props}\n />\n }\n />\n )\n}\n\nfunction PaginationPrevious({\n className,\n text = \"Previous\",\n ...props\n}: PaginationPreviousProps) {\n return (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"pl-1.5!\", className)}\n {...props}\n >\n <ChevronLeftIcon data-icon=\"inline-start\" />\n <span className=\"hidden sm:block\">{text}</span>\n </PaginationLink>\n )\n}\n\nfunction PaginationNext({\n className,\n text = \"Next\",\n ...props\n}: PaginationNextProps) {\n return (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"pr-1.5!\", className)}\n {...props}\n >\n <span className=\"hidden sm:block\">{text}</span>\n <ChevronRightIcon data-icon=\"inline-end\" />\n </PaginationLink>\n )\n}\n\nfunction PaginationEllipsis({ className, ...props }: PaginationEllipsisProps) {\n return (\n <span\n data-slot=\"pagination-ellipsis\"\n className={cn(\n \"flex size-8 items-center justify-center [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n <EllipsisIcon />\n <span className=\"sr-only\">More pages</span>\n </span>\n )\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n}\n"],"mappings":";;;;;;AAkCA,SAAS,WAAW,EAAE,WAAW,GAAG,SAA0B;AAC5D,QACE,oBAAC,OAAD;EACE,MAAK;EACL,cAAW;EACX,aAAU;EACV,WAAW,GACT,sCACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,kBAAkB,EAAE,WAAW,GAAG,SAAiC;AAC1E,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,6BACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,eAAe,OAA4B;AAClD,QAAO,oBAAC,MAAD;EAAI,aAAU;EAAkB,GAAI;EAAS,CAAA;;AAGtD,SAAS,eAAe,EACtB,WACA,UACA,UACA,OAAO,QACP,GAAG,SACmB;AACtB,QACE,oBAAC,QAAD;EACE,SAAS,WAAW,YAAY;EAC1B;EACN,WAAW,GAAG,YAAY,kCAAkC,UAAU;EACtE,QACE,oBAAC,KAAD;GACE,gBAAc,WAAW,SAAS,KAAA;GAClC,iBAAe,YAAY,KAAA;GAC3B,aAAU;GACV,eAAa,YAAY,KAAA;GACzB,UAAU,WAAW,KAAK,KAAA;GAC1B,GAAI;GACJ,CAAA;EAEJ,CAAA;;AAIN,SAAS,mBAAmB,EAC1B,WACA,OAAO,YACP,GAAG,SACuB;AAC1B,QACE,qBAAC,gBAAD;EACE,cAAW;EACX,MAAK;EACL,WAAW,GAAG,WAAW,UAAU;EACnC,GAAI;YAJN,CAME,oBAAC,iBAAD,EAAiB,aAAU,gBAAiB,CAAA,EAC5C,oBAAC,QAAD;GAAM,WAAU;aAAmB;GAAY,CAAA,CAChC;;;AAIrB,SAAS,eAAe,EACtB,WACA,OAAO,QACP,GAAG,SACmB;AACtB,QACE,qBAAC,gBAAD;EACE,cAAW;EACX,MAAK;EACL,WAAW,GAAG,WAAW,UAAU;EACnC,GAAI;YAJN,CAME,oBAAC,QAAD;GAAM,WAAU;aAAmB;GAAY,CAAA,EAC/C,oBAAC,kBAAD,EAAkB,aAAU,cAAe,CAAA,CAC5B;;;AAIrB,SAAS,mBAAmB,EAAE,WAAW,GAAG,SAAkC;AAC5E,QACE,qBAAC,QAAD;EACE,aAAU;EACV,WAAW,GACT,gFACA,UACD;EACD,GAAI;YANN,CAQE,oBAAC,cAAD,EAAgB,CAAA,EAChB,oBAAC,QAAD;GAAM,WAAU;aAAU;GAAiB,CAAA,CACtC"}
package/dist/sidebar.js CHANGED
@@ -265,7 +265,7 @@ function SidebarGroup({ className, ...props }) {
265
265
  function SidebarGroupLabel({ className, render, ...props }) {
266
266
  return useRender({
267
267
  defaultTagName: "div",
268
- props: mergeProps({ className: cn("text-contrast/70 ring-focus h-8 rounded-md px-2 text-xs font-medium group-data-[collapsible=icon]:hidden focus-visible:ring-2 [&>svg]:size-4 flex shrink-0 items-center outline-hidden [&>svg]:shrink-0", className) }, props),
268
+ props: mergeProps({ className: cn("text-contrast/70 ring-focus/50 h-8 rounded-md px-2 text-xs font-medium group-data-[collapsible=icon]:hidden focus-visible:ring-3 [&>svg]:size-4 flex shrink-0 items-center outline-hidden [&>svg]:shrink-0", className) }, props),
269
269
  render,
270
270
  state: { slot: "sidebar-group-label" }
271
271
  });
@@ -273,7 +273,7 @@ function SidebarGroupLabel({ className, render, ...props }) {
273
273
  function SidebarGroupAction({ className, render, ...props }) {
274
274
  return useRender({
275
275
  defaultTagName: "button",
276
- props: mergeProps({ className: cn("text-contrast ring-focus hover:bg-primary hover:text-white absolute top-1.5 right-3 w-5 rounded-sm p-0 focus-visible:ring-2 [&>svg]:size-4 flex aspect-square items-center justify-center outline-hidden transition-transform [&>svg]:shrink-0 after:absolute after:-inset-2 md:after:hidden group-data-[collapsible=icon]:hidden", className) }, props),
276
+ props: mergeProps({ className: cn("text-contrast ring-focus/50 hover:bg-primary hover:text-white absolute top-1.5 right-3 w-5 rounded-sm p-0 focus-visible:ring-3 [&>svg]:size-4 flex aspect-square items-center justify-center outline-hidden transition-transform [&>svg]:shrink-0 after:absolute after:-inset-2 md:after:hidden group-data-[collapsible=icon]:hidden", className) }, props),
277
277
  render,
278
278
  state: { slot: "sidebar-group-action" }
279
279
  });
@@ -299,7 +299,7 @@ function SidebarMenuItem({ className, ...props }) {
299
299
  ...props
300
300
  });
301
301
  }
302
- const sidebarMenuButtonVariants = cva("ring-focus hover:bg-primary hover:text-white active:bg-primary active:text-white data-active:bg-primary data-active:text-white data-open:hover:bg-primary data-open:hover:text-white gap-2 rounded-md p-2 text-left text-sm transition-[width,height,padding] group-has-data-[slot=sidebar-menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:w-full group-data-[collapsible=icon]:aspect-square group-data-[collapsible=icon]:h-11 focus-visible:ring-2 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:shrink-0", {
302
+ const sidebarMenuButtonVariants = cva("ring-focus/50 hover:bg-primary hover:text-white active:bg-primary active:text-white data-active:bg-primary data-active:text-white data-open:hover:bg-primary data-open:hover:text-white gap-2 rounded-md p-2 text-left text-sm transition-[width,height,padding] group-has-data-[slot=sidebar-menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:w-full group-data-[collapsible=icon]:aspect-square group-data-[collapsible=icon]:h-11 focus-visible:ring-3 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:shrink-0", {
303
303
  variants: {
304
304
  variant: {
305
305
  default: "hover:bg-primary hover:text-white",
@@ -344,7 +344,7 @@ function SidebarMenuButton({ render, isActive = false, variant = "default", size
344
344
  function SidebarMenuAction({ className, render, showOnHover = false, ...props }) {
345
345
  return useRender({
346
346
  defaultTagName: "button",
347
- props: mergeProps({ className: cn("text-contrast ring-focus hover:bg-primary hover:text-white peer-hover/menu-button:text-white absolute top-1/2 -translate-y-1/2 right-1 aspect-square w-5 rounded-sm p-0 focus-visible:ring-2 [&>svg]:size-4 flex items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0", showOnHover && "peer-data-active/menu-button:text-white group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-open:opacity-100 md:opacity-0", className) }, props),
347
+ props: mergeProps({ className: cn("text-contrast ring-focus/50 hover:bg-primary hover:text-white peer-hover/menu-button:text-white absolute top-1/2 -translate-y-1/2 right-1 aspect-square w-5 rounded-sm p-0 focus-visible:ring-3 [&>svg]:size-4 flex items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0", showOnHover && "peer-data-active/menu-button:text-white group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-open:opacity-100 md:opacity-0", className) }, props),
348
348
  render,
349
349
  state: { slot: "sidebar-menu-action" }
350
350
  });
@@ -387,7 +387,7 @@ function SidebarMenuSubItem({ className, ...props }) {
387
387
  function SidebarMenuSubButton({ render, size = "md", isActive = false, className, ...props }) {
388
388
  return useRender({
389
389
  defaultTagName: "a",
390
- props: mergeProps({ className: cn("text-contrast ring-focus hover:bg-primary hover:text-white active:bg-primary active:text-white [&>svg]:text-white data-active:bg-primary data-active:text-white h-7 gap-2 rounded-md px-2 focus-visible:ring-2 data-[size=md]:text-sm data-[size=sm]:text-xs [&>svg]:size-4 flex min-w-0 -translate-x-px items-center overflow-hidden outline-hidden group-data-[collapsible=icon]:hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:shrink-0", className) }, props),
390
+ props: mergeProps({ className: cn("text-contrast ring-focus/50 hover:bg-primary hover:text-white active:bg-primary active:text-white [&>svg]:text-white data-active:bg-primary data-active:text-white h-7 gap-2 rounded-md px-2 focus-visible:ring-3 data-[size=md]:text-sm data-[size=sm]:text-xs [&>svg]:size-4 flex min-w-0 -translate-x-px items-center overflow-hidden outline-hidden group-data-[collapsible=icon]:hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:shrink-0", className) }, props),
391
391
  render,
392
392
  state: {
393
393
  slot: "sidebar-menu-sub-button",
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.js","names":["CollapsiblePrimitive"],"sources":["../src/sidebar.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Collapsible as CollapsiblePrimitive } from \"@base-ui/react/collapsible\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"./lib/utils\"\nimport { Button } from \"./button\"\nimport {\n Drawer,\n DrawerContent,\n DrawerDescription,\n DrawerHeader,\n DrawerTitle,\n} from \"./drawer\"\nimport { Input } from \"./input\"\nimport { Separator } from \"./separator\"\nimport { Skeleton } from \"./skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./tooltip\"\nimport { useIsMobile } from \"./hooks/use-mobile\"\nimport { SidebarPanelIcon } from \"./lib/internal-icons\"\n\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_DEFAULT_KEYBOARD_SHORTCUT = \"b\"\n\n// ---------------------------------------------------------------------------\n// Persistence helpers — ready-made functions for the `persist` prop.\n// ---------------------------------------------------------------------------\n\n/**\n * Persist sidebar state to a cookie.\n *\n * @param name - Cookie name. Defaults to `\"sidebar-state\"`.\n * @param maxAge - Cookie max-age in seconds. Defaults to 7 days (604 800).\n *\n * @example\n * ```tsx\n * <SidebarProvider persist={cookiePersist()}>\n * <SidebarProvider persist={cookiePersist(\"my-sidebar\", 86400)}>\n * ```\n */\nfunction cookiePersist(name = \"sidebar-state\", maxAge = 60 * 60 * 24 * 7) {\n return (open: boolean) => {\n document.cookie = `${name}=${open}; path=/; max-age=${maxAge}`\n }\n}\n\n/**\n * Persist sidebar state to localStorage.\n *\n * @param key - Storage key. Defaults to `\"sidebar-state\"`.\n *\n * @example\n * ```tsx\n * <SidebarProvider persist={localStoragePersist()}>\n * <SidebarProvider persist={localStoragePersist(\"my-sidebar\")}>\n * ```\n */\nfunction localStoragePersist(key = \"sidebar-state\") {\n return (open: boolean) => {\n try {\n localStorage.setItem(key, String(open))\n } catch {\n // Storage full or unavailable (SSR, private browsing) — silently ignore.\n }\n }\n}\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n persist,\n keyboardShortcut = SIDEBAR_DEFAULT_KEYBOARD_SHORTCUT,\n mobileBreakpoint,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n /**\n * Optional callback to persist open state. Called on every toggle.\n * Use the built-in helpers `cookiePersist()` or `localStoragePersist()`,\n * or provide a custom function (e.g. server action).\n *\n * @example\n * ```tsx\n * <SidebarProvider persist={cookiePersist()}>\n * <SidebarProvider persist={localStoragePersist(\"sidebar\")}>\n * <SidebarProvider persist={(open) => saveToServer(open)}>\n * ```\n */\n persist?: (open: boolean) => void\n /** Key for Cmd/Ctrl+key toggle shortcut. Defaults to \"b\". Pass `false` to disable. */\n keyboardShortcut?: string | false\n /** Breakpoint (px) below which the sidebar uses a mobile drawer. Defaults to 768. */\n mobileBreakpoint?: number\n}) {\n const isMobile = useIsMobile(mobileBreakpoint)\n const [openMobile, setOpenMobile] = React.useState(false)\n\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const persistRef = React.useRef(persist)\n persistRef.current = persist\n\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n persistRef.current?.(openState)\n },\n [setOpenProp, open]\n )\n\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n React.useEffect(() => {\n if (keyboardShortcut === false) return\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === keyboardShortcut &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [toggleSidebar, keyboardShortcut])\n\n // On mobile the sidebar renders as a full-width drawer, so always treat as expanded.\n const state = isMobile || open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper has-data-[variant=inset]:bg-surface flex min-h-svh w-full\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n}) {\n const { isMobile, state, open, setOpen, openMobile, setOpenMobile } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n \"bg-surface text-contrast flex h-full w-(--sidebar-width) flex-col\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Drawer\n open={openMobile}\n onOpenChange={setOpenMobile}\n swipeDirection={side}\n >\n <DrawerContent\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"bg-surface text-contrast w-(--sidebar-width) max-w-none rounded-none border-0 p-0 sm:max-w-none\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n >\n <DrawerHeader className=\"sr-only\">\n <DrawerTitle>Sidebar</DrawerTitle>\n <DrawerDescription>Displays the mobile sidebar.</DrawerDescription>\n </DrawerHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </DrawerContent>\n </Drawer>\n )\n }\n\n return (\n <CollapsiblePrimitive.Root\n open={open}\n onOpenChange={setOpen}\n className=\"group peer text-contrast hidden md:block\"\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\n side === \"left\"\n ? \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\"\n : \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) after:absolute after:inset-y-0 after:w-px after:bg-line\" + (side === \"left\" ? \" after:right-0\" : \" after:left-0\"),\n className\n )}\n {...props}\n >\n <TooltipProvider delay={0} closeDelay={300}>\n <div\n data-slot=\"sidebar-inner\"\n className=\"bg-surface group-data-[variant=floating]:ring-line group-data-[variant=floating]:rounded-md group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 flex size-full flex-col\"\n >\n {children}\n </div>\n </TooltipProvider>\n </div>\n </CollapsiblePrimitive.Root>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { toggleSidebar, open } = useSidebar()\n\n return (\n <Button\n data-slot=\"sidebar-trigger\"\n aria-expanded={open}\n variant=\"ghost\"\n size=\"icon-sm\"\n className={cn(className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <SidebarPanelIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"hover:after:bg-line absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-[left,right,transform] duration-200 ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-closed]_&]:cursor-e-resize [[data-side=right][data-closed]_&]:cursor-w-resize\",\n \"hover:group-data-[collapsible=offcanvas]:bg-surface group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"bg-foundation md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-lg md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[closed]:ml-2 relative flex min-w-0 w-full flex-1 flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n className={cn(\"bg-foundation h-8 w-full shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n className={cn(\"gap-2 p-2 flex flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n className={cn(\"gap-2 p-2 flex flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n className={cn(\"bg-line mx-2 data-[orientation=horizontal]:w-auto\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, style, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n className={cn(\n \"gap-1 flex min-h-0 flex-1 flex-col overflow-auto scrollbar-none group-data-[collapsible=icon]:overflow-x-hidden\",\n className\n )}\n style={{\n maskImage: \"linear-gradient(to bottom, black calc(100% - 44px), transparent 100%)\",\n WebkitMaskImage: \"linear-gradient(to bottom, black calc(100% - 44px), transparent 100%)\",\n ...style,\n }}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n className={cn(\n \"px-2 first:pt-2 last:pb-2 relative flex w-full min-w-0 flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"div\"> & React.ComponentProps<\"div\">) {\n return useRender({\n defaultTagName: \"div\",\n props: mergeProps<\"div\">(\n {\n className: cn(\n \"text-contrast/70 ring-focus h-8 rounded-md px-2 text-xs font-medium group-data-[collapsible=icon]:hidden focus-visible:ring-2 [&>svg]:size-4 flex shrink-0 items-center outline-hidden [&>svg]:shrink-0\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-group-label\",\n },\n })\n}\n\nfunction SidebarGroupAction({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"button\"> & React.ComponentProps<\"button\">) {\n return useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n className: cn(\n \"text-contrast ring-focus hover:bg-primary hover:text-white absolute top-1.5 right-3 w-5 rounded-sm p-0 focus-visible:ring-2 [&>svg]:size-4 flex aspect-square items-center justify-center outline-hidden transition-transform [&>svg]:shrink-0 after:absolute after:-inset-2 md:after:hidden group-data-[collapsible=icon]:hidden\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-group-action\",\n },\n })\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n className={cn(\"text-sm w-full\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n className={cn(\"gap-1 flex w-full min-w-0 flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n className={cn(\"group/menu-item relative has-data-[slot=sidebar-menu-sub]:mb-[-0.25rem]\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n \"ring-focus hover:bg-primary hover:text-white active:bg-primary active:text-white data-active:bg-primary data-active:text-white data-open:hover:bg-primary data-open:hover:text-white gap-2 rounded-md p-2 text-left text-sm transition-[width,height,padding] group-has-data-[slot=sidebar-menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:w-full group-data-[collapsible=icon]:aspect-square group-data-[collapsible=icon]:h-11 focus-visible:ring-2 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"hover:bg-primary hover:text-white\",\n outline: \"bg-foundation hover:bg-primary hover:text-white ring-1 ring-line hover:ring-focus\",\n },\n size: {\n default: \"h-11 text-sm\",\n sm: \"h-8 text-xs\",\n lg: \"h-12 text-sm\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n render,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: useRender.ComponentProps<\"button\"> &\n React.ComponentProps<\"button\"> & {\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n } & VariantProps<typeof sidebarMenuButtonVariants>) {\n const { isMobile, state } = useSidebar()\n\n if (process.env.NODE_ENV === \"development\" && tooltip && render) {\n console.warn(\n \"[SidebarMenuButton] Both `render` and `tooltip` were provided. \" +\n \"When `tooltip` is set, the button is wrapped in a TooltipTrigger and the `render` prop is ignored.\"\n )\n }\n\n const comp = useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n className: cn(sidebarMenuButtonVariants({ variant, size }), className),\n },\n props\n ),\n render: !tooltip ? render : TooltipTrigger,\n state: {\n slot: \"sidebar-menu-button\",\n size,\n active: isActive,\n },\n })\n\n if (!tooltip) {\n return comp\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n {comp}\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n render,\n showOnHover = false,\n ...props\n}: useRender.ComponentProps<\"button\"> &\n React.ComponentProps<\"button\"> & {\n showOnHover?: boolean\n }) {\n return useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n className: cn(\n \"text-contrast ring-focus hover:bg-primary hover:text-white peer-hover/menu-button:text-white absolute top-1/2 -translate-y-1/2 right-1 aspect-square w-5 rounded-sm p-0 focus-visible:ring-2 [&>svg]:size-4 flex items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0\",\n showOnHover &&\n \"peer-data-active/menu-button:text-white group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-open:opacity-100 md:opacity-0\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-menu-action\",\n },\n })\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n className={cn(\n \"text-contrast peer-hover/menu-button:text-white peer-data-active/menu-button:text-white pointer-events-none absolute right-1 top-1/2 -translate-y-1/2 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n const [width] = React.useState(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n })\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n className={cn(\"h-8 gap-2 rounded-md px-2 flex items-center\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton className=\"size-4 rounded-md\" />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n className={cn(\"border-line ml-3.5 mr-0 translate-x-px gap-0.5 border-l pl-2.5 pr-0 py-0.5 group-data-[collapsible=icon]:hidden flex min-w-0 flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n render,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: useRender.ComponentProps<\"a\"> &\n React.ComponentProps<\"a\"> & {\n size?: \"sm\" | \"md\"\n isActive?: boolean\n }) {\n return useRender({\n defaultTagName: \"a\",\n props: mergeProps<\"a\">(\n {\n className: cn(\n \"text-contrast ring-focus hover:bg-primary hover:text-white active:bg-primary active:text-white [&>svg]:text-white data-active:bg-primary data-active:text-white h-7 gap-2 rounded-md px-2 focus-visible:ring-2 data-[size=md]:text-sm data-[size=sm]:text-xs [&>svg]:size-4 flex min-w-0 -translate-x-px items-center overflow-hidden outline-hidden group-data-[collapsible=icon]:hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:shrink-0\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-menu-sub-button\",\n size,\n active: isActive,\n },\n })\n}\n\nexport {\n cookiePersist,\n localStoragePersist,\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sidebar.js","names":["CollapsiblePrimitive"],"sources":["../src/sidebar.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Collapsible as CollapsiblePrimitive } from \"@base-ui/react/collapsible\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"./lib/utils\"\nimport { Button } from \"./button\"\nimport {\n Drawer,\n DrawerContent,\n DrawerDescription,\n DrawerHeader,\n DrawerTitle,\n} from \"./drawer\"\nimport { Input } from \"./input\"\nimport { Separator } from \"./separator\"\nimport { Skeleton } from \"./skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./tooltip\"\nimport { useIsMobile } from \"./hooks/use-mobile\"\nimport { SidebarPanelIcon } from \"./lib/internal-icons\"\n\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_DEFAULT_KEYBOARD_SHORTCUT = \"b\"\n\n// ---------------------------------------------------------------------------\n// Persistence helpers — ready-made functions for the `persist` prop.\n// ---------------------------------------------------------------------------\n\n/**\n * Persist sidebar state to a cookie.\n *\n * @param name - Cookie name. Defaults to `\"sidebar-state\"`.\n * @param maxAge - Cookie max-age in seconds. Defaults to 7 days (604 800).\n *\n * @example\n * ```tsx\n * <SidebarProvider persist={cookiePersist()}>\n * <SidebarProvider persist={cookiePersist(\"my-sidebar\", 86400)}>\n * ```\n */\nfunction cookiePersist(name = \"sidebar-state\", maxAge = 60 * 60 * 24 * 7) {\n return (open: boolean) => {\n document.cookie = `${name}=${open}; path=/; max-age=${maxAge}`\n }\n}\n\n/**\n * Persist sidebar state to localStorage.\n *\n * @param key - Storage key. Defaults to `\"sidebar-state\"`.\n *\n * @example\n * ```tsx\n * <SidebarProvider persist={localStoragePersist()}>\n * <SidebarProvider persist={localStoragePersist(\"my-sidebar\")}>\n * ```\n */\nfunction localStoragePersist(key = \"sidebar-state\") {\n return (open: boolean) => {\n try {\n localStorage.setItem(key, String(open))\n } catch {\n // Storage full or unavailable (SSR, private browsing) — silently ignore.\n }\n }\n}\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n persist,\n keyboardShortcut = SIDEBAR_DEFAULT_KEYBOARD_SHORTCUT,\n mobileBreakpoint,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n /**\n * Optional callback to persist open state. Called on every toggle.\n * Use the built-in helpers `cookiePersist()` or `localStoragePersist()`,\n * or provide a custom function (e.g. server action).\n *\n * @example\n * ```tsx\n * <SidebarProvider persist={cookiePersist()}>\n * <SidebarProvider persist={localStoragePersist(\"sidebar\")}>\n * <SidebarProvider persist={(open) => saveToServer(open)}>\n * ```\n */\n persist?: (open: boolean) => void\n /** Key for Cmd/Ctrl+key toggle shortcut. Defaults to \"b\". Pass `false` to disable. */\n keyboardShortcut?: string | false\n /** Breakpoint (px) below which the sidebar uses a mobile drawer. Defaults to 768. */\n mobileBreakpoint?: number\n}) {\n const isMobile = useIsMobile(mobileBreakpoint)\n const [openMobile, setOpenMobile] = React.useState(false)\n\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const persistRef = React.useRef(persist)\n persistRef.current = persist\n\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n persistRef.current?.(openState)\n },\n [setOpenProp, open]\n )\n\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n React.useEffect(() => {\n if (keyboardShortcut === false) return\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === keyboardShortcut &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [toggleSidebar, keyboardShortcut])\n\n // On mobile the sidebar renders as a full-width drawer, so always treat as expanded.\n const state = isMobile || open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper has-data-[variant=inset]:bg-surface flex min-h-svh w-full\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n}) {\n const { isMobile, state, open, setOpen, openMobile, setOpenMobile } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n \"bg-surface text-contrast flex h-full w-(--sidebar-width) flex-col\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Drawer\n open={openMobile}\n onOpenChange={setOpenMobile}\n swipeDirection={side}\n >\n <DrawerContent\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"bg-surface text-contrast w-(--sidebar-width) max-w-none rounded-none border-0 p-0 sm:max-w-none\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n >\n <DrawerHeader className=\"sr-only\">\n <DrawerTitle>Sidebar</DrawerTitle>\n <DrawerDescription>Displays the mobile sidebar.</DrawerDescription>\n </DrawerHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </DrawerContent>\n </Drawer>\n )\n }\n\n return (\n <CollapsiblePrimitive.Root\n open={open}\n onOpenChange={setOpen}\n className=\"group peer text-contrast hidden md:block\"\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\n side === \"left\"\n ? \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\"\n : \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) after:absolute after:inset-y-0 after:w-px after:bg-line\" + (side === \"left\" ? \" after:right-0\" : \" after:left-0\"),\n className\n )}\n {...props}\n >\n <TooltipProvider delay={0} closeDelay={300}>\n <div\n data-slot=\"sidebar-inner\"\n className=\"bg-surface group-data-[variant=floating]:ring-line group-data-[variant=floating]:rounded-md group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 flex size-full flex-col\"\n >\n {children}\n </div>\n </TooltipProvider>\n </div>\n </CollapsiblePrimitive.Root>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { toggleSidebar, open } = useSidebar()\n\n return (\n <Button\n data-slot=\"sidebar-trigger\"\n aria-expanded={open}\n variant=\"ghost\"\n size=\"icon-sm\"\n className={cn(className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <SidebarPanelIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"hover:after:bg-line absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-[left,right,transform] duration-200 ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-closed]_&]:cursor-e-resize [[data-side=right][data-closed]_&]:cursor-w-resize\",\n \"hover:group-data-[collapsible=offcanvas]:bg-surface group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"bg-foundation md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-lg md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[closed]:ml-2 relative flex min-w-0 w-full flex-1 flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n className={cn(\"bg-foundation h-8 w-full shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n className={cn(\"gap-2 p-2 flex flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n className={cn(\"gap-2 p-2 flex flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n className={cn(\"bg-line mx-2 data-[orientation=horizontal]:w-auto\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, style, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n className={cn(\n \"gap-1 flex min-h-0 flex-1 flex-col overflow-auto scrollbar-none group-data-[collapsible=icon]:overflow-x-hidden\",\n className\n )}\n style={{\n maskImage: \"linear-gradient(to bottom, black calc(100% - 44px), transparent 100%)\",\n WebkitMaskImage: \"linear-gradient(to bottom, black calc(100% - 44px), transparent 100%)\",\n ...style,\n }}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n className={cn(\n \"px-2 first:pt-2 last:pb-2 relative flex w-full min-w-0 flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"div\"> & React.ComponentProps<\"div\">) {\n return useRender({\n defaultTagName: \"div\",\n props: mergeProps<\"div\">(\n {\n className: cn(\n \"text-contrast/70 ring-focus/50 h-8 rounded-md px-2 text-xs font-medium group-data-[collapsible=icon]:hidden focus-visible:ring-3 [&>svg]:size-4 flex shrink-0 items-center outline-hidden [&>svg]:shrink-0\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-group-label\",\n },\n })\n}\n\nfunction SidebarGroupAction({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"button\"> & React.ComponentProps<\"button\">) {\n return useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n className: cn(\n \"text-contrast ring-focus/50 hover:bg-primary hover:text-white absolute top-1.5 right-3 w-5 rounded-sm p-0 focus-visible:ring-3 [&>svg]:size-4 flex aspect-square items-center justify-center outline-hidden transition-transform [&>svg]:shrink-0 after:absolute after:-inset-2 md:after:hidden group-data-[collapsible=icon]:hidden\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-group-action\",\n },\n })\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n className={cn(\"text-sm w-full\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n className={cn(\"gap-1 flex w-full min-w-0 flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n className={cn(\"group/menu-item relative has-data-[slot=sidebar-menu-sub]:mb-[-0.25rem]\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n \"ring-focus/50 hover:bg-primary hover:text-white active:bg-primary active:text-white data-active:bg-primary data-active:text-white data-open:hover:bg-primary data-open:hover:text-white gap-2 rounded-md p-2 text-left text-sm transition-[width,height,padding] group-has-data-[slot=sidebar-menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:w-full group-data-[collapsible=icon]:aspect-square group-data-[collapsible=icon]:h-11 focus-visible:ring-3 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"hover:bg-primary hover:text-white\",\n outline: \"bg-foundation hover:bg-primary hover:text-white ring-1 ring-line hover:ring-focus\",\n },\n size: {\n default: \"h-11 text-sm\",\n sm: \"h-8 text-xs\",\n lg: \"h-12 text-sm\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n render,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: useRender.ComponentProps<\"button\"> &\n React.ComponentProps<\"button\"> & {\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n } & VariantProps<typeof sidebarMenuButtonVariants>) {\n const { isMobile, state } = useSidebar()\n\n if (process.env.NODE_ENV === \"development\" && tooltip && render) {\n console.warn(\n \"[SidebarMenuButton] Both `render` and `tooltip` were provided. \" +\n \"When `tooltip` is set, the button is wrapped in a TooltipTrigger and the `render` prop is ignored.\"\n )\n }\n\n const comp = useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n className: cn(sidebarMenuButtonVariants({ variant, size }), className),\n },\n props\n ),\n render: !tooltip ? render : TooltipTrigger,\n state: {\n slot: \"sidebar-menu-button\",\n size,\n active: isActive,\n },\n })\n\n if (!tooltip) {\n return comp\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n {comp}\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n render,\n showOnHover = false,\n ...props\n}: useRender.ComponentProps<\"button\"> &\n React.ComponentProps<\"button\"> & {\n showOnHover?: boolean\n }) {\n return useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n className: cn(\n \"text-contrast ring-focus/50 hover:bg-primary hover:text-white peer-hover/menu-button:text-white absolute top-1/2 -translate-y-1/2 right-1 aspect-square w-5 rounded-sm p-0 focus-visible:ring-3 [&>svg]:size-4 flex items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0\",\n showOnHover &&\n \"peer-data-active/menu-button:text-white group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-open:opacity-100 md:opacity-0\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-menu-action\",\n },\n })\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n className={cn(\n \"text-contrast peer-hover/menu-button:text-white peer-data-active/menu-button:text-white pointer-events-none absolute right-1 top-1/2 -translate-y-1/2 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n const [width] = React.useState(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n })\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n className={cn(\"h-8 gap-2 rounded-md px-2 flex items-center\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton className=\"size-4 rounded-md\" />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n className={cn(\"border-line ml-3.5 mr-0 translate-x-px gap-0.5 border-l pl-2.5 pr-0 py-0.5 group-data-[collapsible=icon]:hidden flex min-w-0 flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n render,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: useRender.ComponentProps<\"a\"> &\n React.ComponentProps<\"a\"> & {\n size?: \"sm\" | \"md\"\n isActive?: boolean\n }) {\n return useRender({\n defaultTagName: \"a\",\n props: mergeProps<\"a\">(\n {\n className: cn(\n \"text-contrast ring-focus/50 hover:bg-primary hover:text-white active:bg-primary active:text-white [&>svg]:text-white data-active:bg-primary data-active:text-white h-7 gap-2 rounded-md px-2 focus-visible:ring-3 data-[size=md]:text-sm data-[size=sm]:text-xs [&>svg]:size-4 flex min-w-0 -translate-x-px items-center overflow-hidden outline-hidden group-data-[collapsible=icon]:hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:shrink-0\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-menu-sub-button\",\n size,\n active: isActive,\n },\n })\n}\n\nexport {\n cookiePersist,\n localStoragePersist,\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n"],"mappings":"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"}
package/dist/styles.css CHANGED
@@ -640,6 +640,13 @@
640
640
  --offset-sm: 0px; --offset-md: 0px; --offset-lg: 0px;
641
641
  --stagger-sm: 0ms; --stagger-md: 0ms; --stagger-lg: 0ms;
642
642
  }
643
+
644
+ /* Token-driven recipes collapse via the vars above; a standalone keyframe
645
+ * utility that doesn't use those tokens must be stopped explicitly. (The
646
+ * `animate-spin` loader is intentionally left running — it signals activity.) */
647
+ .animate-caret-blink {
648
+ animation: none;
649
+ }
643
650
  }
644
651
 
645
652
  /* ---------------------------------------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","names":[],"sources":["../src/table.tsx"],"mappings":";;;;KAMK,UAAA,GAAa,KAAA,CAAM,cAAA;AAAA,KACnB,gBAAA,GAAmB,KAAA,CAAM,cAAA;AAAA,KACzB,cAAA,GAAiB,KAAA,CAAM,cAAA;AAAA,KACvB,gBAAA,GAAmB,KAAA,CAAM,cAAA;AAAA,KACzB,aAAA,GAAgB,KAAA,CAAM,cAAA;AAAA,KACtB,cAAA,GAAiB,KAAA,CAAM,cAAA;AAAA,KACvB,cAAA,GAAiB,KAAA,CAAM,cAAA;AAAA,KACvB,iBAAA,GAAoB,KAAA,CAAM,cAAA;AAAA,iBAEtB,KAAA,CAAA;EAAQ,SAAA;EAAA,GAAc;AAAA,GAAS,UAAA,GAAU,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAezC,WAAA,CAAA;EAAc,SAAA;EAAA,GAAc;AAAA,GAAS,gBAAA,GAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUrD,SAAA,CAAA;EAAY,SAAA;EAAA,GAAc;AAAA,GAAS,cAAA,GAAc,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUjD,WAAA,CAAA;EAAc,SAAA;EAAA,GAAc;AAAA,GAAS,gBAAA,GAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAarD,QAAA,CAAA;EAAW,SAAA;EAAA,GAAc;AAAA,GAAS,aAAA,GAAa,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAa/C,SAAA,CAAA;EAAY,SAAA;EAAA,GAAc;AAAA,GAAS,cAAA,GAAc,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAajD,SAAA,CAAA;EAAY,SAAA;EAAA,GAAc;AAAA,GAAS,cAAA,GAAc,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAajD,YAAA,CAAA;EAAe,SAAA;EAAA,GAAc;AAAA,GAAS,iBAAA,GAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"table.d.ts","names":[],"sources":["../src/table.tsx"],"mappings":";;;;KAMK,UAAA,GAAa,KAAA,CAAM,cAAA;AAAA,KACnB,gBAAA,GAAmB,KAAA,CAAM,cAAA;AAAA,KACzB,cAAA,GAAiB,KAAA,CAAM,cAAA;AAAA,KACvB,gBAAA,GAAmB,KAAA,CAAM,cAAA;AAAA,KACzB,aAAA,GAAgB,KAAA,CAAM,cAAA;AAAA,KACtB,cAAA,GAAiB,KAAA,CAAM,cAAA;AAAA,KACvB,cAAA,GAAiB,KAAA,CAAM,cAAA;AAAA,KACvB,iBAAA,GAAoB,KAAA,CAAM,cAAA;AAAA,iBAEtB,KAAA,CAAA;EAAQ,SAAA;EAAA,GAAc;AAAA,GAAS,UAAA,GAAU,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAkBzC,WAAA,CAAA;EAAc,SAAA;EAAA,GAAc;AAAA,GAAS,gBAAA,GAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUrD,SAAA,CAAA;EAAY,SAAA;EAAA,GAAc;AAAA,GAAS,cAAA,GAAc,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUjD,WAAA,CAAA;EAAc,SAAA;EAAA,GAAc;AAAA,GAAS,gBAAA,GAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAarD,QAAA,CAAA;EAAW,SAAA;EAAA,GAAc;AAAA,GAAS,aAAA,GAAa,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAa/C,SAAA,CAAA;EAAY,SAAA;EAAA,GAAc;AAAA,GAAS,cAAA,GAAc,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAajD,SAAA,CAAA;EAAY,SAAA;EAAA,GAAc;AAAA,GAAS,cAAA,GAAc,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAajD,YAAA,CAAA;EAAe,SAAA;EAAA,GAAc;AAAA,GAAS,iBAAA,GAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
package/dist/table.js CHANGED
@@ -6,7 +6,10 @@ import { jsx } from "react/jsx-runtime";
6
6
  function Table({ className, ...props }) {
7
7
  return /* @__PURE__ */ jsx("div", {
8
8
  "data-slot": "table-container",
9
- className: "relative w-full overflow-x-auto",
9
+ role: "region",
10
+ "aria-label": "Table",
11
+ tabIndex: 0,
12
+ className: "relative w-full overflow-x-auto focus-visible:outline-hidden focus-visible:ring-3 focus-visible:ring-focus/50",
10
13
  children: /* @__PURE__ */ jsx("table", {
11
14
  "data-slot": "table",
12
15
  className: cn("w-full caption-bottom text-sm", className),
package/dist/table.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","names":[],"sources":["../src/table.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype TableProps = React.ComponentProps<\"table\">\ntype TableHeaderProps = React.ComponentProps<\"thead\">\ntype TableBodyProps = React.ComponentProps<\"tbody\">\ntype TableFooterProps = React.ComponentProps<\"tfoot\">\ntype TableRowProps = React.ComponentProps<\"tr\">\ntype TableHeadProps = React.ComponentProps<\"th\">\ntype TableCellProps = React.ComponentProps<\"td\">\ntype TableCaptionProps = React.ComponentProps<\"caption\">\n\nfunction Table({ className, ...props }: TableProps) {\n return (\n <div\n data-slot=\"table-container\"\n className=\"relative w-full overflow-x-auto\"\n >\n <table\n data-slot=\"table\"\n className={cn(\"w-full caption-bottom text-sm\", className)}\n {...props}\n />\n </div>\n )\n}\n\nfunction TableHeader({ className, ...props }: TableHeaderProps) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\"[&_tr]:border-b [&_tr]:border-edge\", className)}\n {...props}\n />\n )\n}\n\nfunction TableBody({ className, ...props }: TableBodyProps) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n )\n}\n\nfunction TableFooter({ className, ...props }: TableFooterProps) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"bg-secondary/50 border-t border-edge font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableRow({ className, ...props }: TableRowProps) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n \"hover:bg-secondary/50 aria-selected:bg-secondary border-b border-edge transition-colors\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableHead({ className, ...props }: TableHeadProps) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"text-contrast h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCell({ className, ...props }: TableCellProps) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCaption({ className, ...props }: TableCaptionProps) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"text-muted mt-4 text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n}\n"],"mappings":";;;;;AAeA,SAAS,MAAM,EAAE,WAAW,GAAG,SAAqB;AAClD,QACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAU;YAEV,oBAAC,SAAD;GACE,aAAU;GACV,WAAW,GAAG,iCAAiC,UAAU;GACzD,GAAI;GACJ,CAAA;EACE,CAAA;;AAIV,SAAS,YAAY,EAAE,WAAW,GAAG,SAA2B;AAC9D,QACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,sCAAsC,UAAU;EAC9D,GAAI;EACJ,CAAA;;AAIN,SAAS,UAAU,EAAE,WAAW,GAAG,SAAyB;AAC1D,QACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,UAAU;EACtD,GAAI;EACJ,CAAA;;AAIN,SAAS,YAAY,EAAE,WAAW,GAAG,SAA2B;AAC9D,QACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GACT,2EACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,SAAS,EAAE,WAAW,GAAG,SAAwB;AACxD,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,2FACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,UAAU,EAAE,WAAW,GAAG,SAAyB;AAC1D,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,8GACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,UAAU,EAAE,WAAW,GAAG,SAAyB;AAC1D,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,oEACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,aAAa,EAAE,WAAW,GAAG,SAA4B;AAChE,QACE,oBAAC,WAAD;EACE,aAAU;EACV,WAAW,GAAG,2BAA2B,UAAU;EACnD,GAAI;EACJ,CAAA"}
1
+ {"version":3,"file":"table.js","names":[],"sources":["../src/table.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype TableProps = React.ComponentProps<\"table\">\ntype TableHeaderProps = React.ComponentProps<\"thead\">\ntype TableBodyProps = React.ComponentProps<\"tbody\">\ntype TableFooterProps = React.ComponentProps<\"tfoot\">\ntype TableRowProps = React.ComponentProps<\"tr\">\ntype TableHeadProps = React.ComponentProps<\"th\">\ntype TableCellProps = React.ComponentProps<\"td\">\ntype TableCaptionProps = React.ComponentProps<\"caption\">\n\nfunction Table({ className, ...props }: TableProps) {\n return (\n <div\n data-slot=\"table-container\"\n role=\"region\"\n aria-label=\"Table\"\n tabIndex={0}\n className=\"relative w-full overflow-x-auto focus-visible:outline-hidden focus-visible:ring-3 focus-visible:ring-focus/50\"\n >\n <table\n data-slot=\"table\"\n className={cn(\"w-full caption-bottom text-sm\", className)}\n {...props}\n />\n </div>\n )\n}\n\nfunction TableHeader({ className, ...props }: TableHeaderProps) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\"[&_tr]:border-b [&_tr]:border-edge\", className)}\n {...props}\n />\n )\n}\n\nfunction TableBody({ className, ...props }: TableBodyProps) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n )\n}\n\nfunction TableFooter({ className, ...props }: TableFooterProps) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"bg-secondary/50 border-t border-edge font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableRow({ className, ...props }: TableRowProps) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n \"hover:bg-secondary/50 aria-selected:bg-secondary border-b border-edge transition-colors\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableHead({ className, ...props }: TableHeadProps) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"text-contrast h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCell({ className, ...props }: TableCellProps) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCaption({ className, ...props }: TableCaptionProps) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"text-muted mt-4 text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n}\n"],"mappings":";;;;;AAeA,SAAS,MAAM,EAAE,WAAW,GAAG,SAAqB;AAClD,QACE,oBAAC,OAAD;EACE,aAAU;EACV,MAAK;EACL,cAAW;EACX,UAAU;EACV,WAAU;YAEV,oBAAC,SAAD;GACE,aAAU;GACV,WAAW,GAAG,iCAAiC,UAAU;GACzD,GAAI;GACJ,CAAA;EACE,CAAA;;AAIV,SAAS,YAAY,EAAE,WAAW,GAAG,SAA2B;AAC9D,QACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,sCAAsC,UAAU;EAC9D,GAAI;EACJ,CAAA;;AAIN,SAAS,UAAU,EAAE,WAAW,GAAG,SAAyB;AAC1D,QACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,UAAU;EACtD,GAAI;EACJ,CAAA;;AAIN,SAAS,YAAY,EAAE,WAAW,GAAG,SAA2B;AAC9D,QACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GACT,2EACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,SAAS,EAAE,WAAW,GAAG,SAAwB;AACxD,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,2FACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,UAAU,EAAE,WAAW,GAAG,SAAyB;AAC1D,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,8GACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,UAAU,EAAE,WAAW,GAAG,SAAyB;AAC1D,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,oEACA,UACD;EACD,GAAI;EACJ,CAAA;;AAIN,SAAS,aAAa,EAAE,WAAW,GAAG,SAA4B;AAChE,QACE,oBAAC,WAAD;EACE,aAAU;EACV,WAAW,GAAG,2BAA2B,UAAU;EACnD,GAAI;EACJ,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"toast.d.ts","names":[],"sources":["../src/toast.tsx"],"mappings":";;;;;;;cAoBM,cAAA;AAAA,cAGA,iBAAA,GAAiB,KAAA;;IAatB,iCAAA,CAAA,SAAA;AAAA,cAEK,qBAAA,GAAqB,KAAA;;IAiB1B,iCAAA,CAAA,SAAA;AAAA,KAMI,SAAA;AAAA,KAEA,YAAA;EACH,KAAA;EACA,WAAA;EACA,IAAA,GAAO,SAAA;EACP,OAAA;EACA,QAAA;EACA,WAAA,GAAc,KAAA,CAAM,wBAAA;EACpB,OAAA;EACA,QAAA;AAAA;AAAA,KAGG,eAAA;AAAA,KAQA,YAAA;EACH,QAAA,GAAW,eAAA;EACX,KAAA;EACA,OAAA;AAAA;AAAA,KAGG,UAAA,GAAa,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,IAAA;AAAA,KACxD,eAAA,GAAkB,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,KAAA;AAAA,KAC7D,qBAAA,GAAwB,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,WAAA;AAAA,KACnE,gBAAA,GAAmB,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,MAAA;AAAA,KAC9D,eAAA,GAAkB,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,KAAA;AAAA,cAM5D,YAAA,EAAkD,iBAAA,CAAtC,YAAA;AAAA,cAEZ,KAAA,IAAK,cAAA,WACiB,YAAA;2BAQD,OAAA,GAAY,IAAA,CAAK,YAAA;yBAGnB,OAAA,GAAY,IAAA,CAAK,YAAA;2BAGf,OAAA,GAAY,IAAA,CAAK,YAAA;wBAGpB,OAAA,GAAY,IAAA,CAAK,YAAA;2BAGd,OAAA,GAAY,IAAA,CAAK,YAAA;;uBAUrB,OAAA,EAAW,OAAA,CAAQ,YAAA;;;iBAmBjC,SAAA,CAAA;EAAY;AAAA;EAAU,IAAA,GAAO,SAAA;AAAA,IAAW,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUxC,KAAA,CAAA;EAAQ,SAAA;EAAA,GAAc;AAAA,GAAS,UAAA,GAAU,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAoBzC,UAAA,CAAA;EAAa,SAAA;EAAA,GAAc;AAAA,GAAS,eAAA,GAAe,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUnD,gBAAA,CAAA;EAAmB,SAAA;EAAA,GAAc;AAAA,GAAS,qBAAA,GAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAU/D,WAAA,CAAA;EAAc,SAAA;EAAA,GAAc;AAAA,GAAS,gBAAA,GAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAarD,UAAA,CAAA;EAAa,SAAA;EAAW,QAAA;EAAA,GAAa;AAAA,GAAS,eAAA,GAAe,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBA0K7D,OAAA,CAAA;EAAU,QAAA;EAAU,KAAA;EAAO;AAAA,GAAW,YAAA,GAAY,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"toast.d.ts","names":[],"sources":["../src/toast.tsx"],"mappings":";;;;;;;cAoBM,cAAA;AAAA,cAGA,iBAAA,GAAiB,KAAA;;IAatB,iCAAA,CAAA,SAAA;AAAA,cAEK,qBAAA,GAAqB,KAAA;;IAiB1B,iCAAA,CAAA,SAAA;AAAA,KAMI,SAAA;AAAA,KAEA,YAAA;EACH,KAAA;EACA,WAAA;EACA,IAAA,GAAO,SAAA;EACP,OAAA;EACA,QAAA;EACA,WAAA,GAAc,KAAA,CAAM,wBAAA;EACpB,OAAA;EACA,QAAA;AAAA;AAAA,KAGG,eAAA;AAAA,KAQA,YAAA;EACH,QAAA,GAAW,eAAA;EACX,KAAA;EACA,OAAA;AAAA;AAAA,KAGG,UAAA,GAAa,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,IAAA;AAAA,KACxD,eAAA,GAAkB,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,KAAA;AAAA,KAC7D,qBAAA,GAAwB,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,WAAA;AAAA,KACnE,gBAAA,GAAmB,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,MAAA;AAAA,KAC9D,eAAA,GAAkB,KAAA,CAAM,cAAA,QAAsB,OAAA,CAAe,KAAA;AAAA,cAM5D,YAAA,EAAkD,iBAAA,CAAtC,YAAA;AAAA,cAEZ,KAAA,IAAK,cAAA,WACiB,YAAA;2BAQD,OAAA,GAAY,IAAA,CAAK,YAAA;yBAGnB,OAAA,GAAY,IAAA,CAAK,YAAA;2BAGf,OAAA,GAAY,IAAA,CAAK,YAAA;wBAGpB,OAAA,GAAY,IAAA,CAAK,YAAA;2BAGd,OAAA,GAAY,IAAA,CAAK,YAAA;;uBAUrB,OAAA,EAAW,OAAA,CAAQ,YAAA;;;iBA2BjC,SAAA,CAAA;EAAY;AAAA;EAAU,IAAA,GAAO,SAAA;AAAA,IAAW,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAiBxC,KAAA,CAAA;EAAQ,SAAA;EAAA,GAAc;AAAA,GAAS,UAAA,GAAU,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAoBzC,UAAA,CAAA;EAAa,SAAA;EAAA,GAAc;AAAA,GAAS,eAAA,GAAe,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUnD,gBAAA,CAAA;EAAmB,SAAA;EAAA,GAAc;AAAA,GAAS,qBAAA,GAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAU/D,WAAA,CAAA;EAAc,SAAA;EAAA,GAAc;AAAA,GAAS,gBAAA,GAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAarD,UAAA,CAAA;EAAa,SAAA;EAAW,QAAA;EAAA,GAAa;AAAA,GAAS,eAAA,GAAe,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBA6K7D,OAAA,CAAA;EAAU,QAAA;EAAU,KAAA;EAAO;AAAA,GAAW,YAAA,GAAY,oBAAA,CAAA,GAAA,CAAA,OAAA"}
package/dist/toast.js CHANGED
@@ -67,10 +67,20 @@ const iconMap = {
67
67
  warning: AlertTriangleIcon,
68
68
  error: ErrorCircleIcon
69
69
  };
70
+ const toastTypeLabels = {
71
+ loading: "Loading",
72
+ success: "Success",
73
+ info: "Information",
74
+ warning: "Warning",
75
+ error: "Error"
76
+ };
70
77
  function ToastIcon({ type }) {
71
78
  if (!type) return null;
72
79
  const Icon = iconMap[type];
73
- return /* @__PURE__ */ jsx(Icon, { className: cn(toastIconVariants({ type })) });
80
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Icon, { className: cn(toastIconVariants({ type })) }), /* @__PURE__ */ jsx("span", {
81
+ className: "sr-only",
82
+ children: toastTypeLabels[type]
83
+ })] });
74
84
  }
75
85
  function Toast({ className, ...props }) {
76
86
  return /* @__PURE__ */ jsx(Toast$1.Root, {
@@ -103,14 +113,14 @@ function ToastDescription({ className, ...props }) {
103
113
  function ToastAction({ className, ...props }) {
104
114
  return /* @__PURE__ */ jsx(Toast$1.Action, {
105
115
  "data-slot": "toast-action",
106
- className: cn("hover:bg-secondary inline-flex h-7 items-center rounded-md border border-line px-2.5 text-xs font-medium transition-colors", className),
116
+ className: cn("hover:bg-secondary inline-flex h-7 items-center rounded-md border border-line px-2.5 text-xs font-medium transition-colors outline-none focus-visible:border-focus focus-visible:ring-focus/50 focus-visible:ring-3", className),
107
117
  ...props
108
118
  });
109
119
  }
110
120
  function ToastClose({ className, children, ...props }) {
111
121
  return /* @__PURE__ */ jsx(Toast$1.Close, {
112
122
  "data-slot": "toast-close",
113
- className: cn("text-muted hover:text-contrast shrink-0 rounded-md p-0.5 transition-colors", className),
123
+ className: cn("text-muted hover:text-contrast shrink-0 rounded-md p-0.5 transition-colors outline-none focus-visible:ring-focus/50 focus-visible:ring-3", className),
114
124
  ...props,
115
125
  children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(CloseIcon, { className: "size-4" }), /* @__PURE__ */ jsx("span", {
116
126
  className: "sr-only",
@@ -138,7 +148,8 @@ const STACKING_BASE = [
138
148
  "data-[ending-style]:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]",
139
149
  "data-[expanded]:data-[ending-style]:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]",
140
150
  "data-[limited]:opacity-0",
141
- "[transition:transform_0.5s_cubic-bezier(0.22,1,0.36,1),opacity_0.5s,filter_0.5s,height_0.15s]"
151
+ "[transition:transform_0.5s_cubic-bezier(0.22,1,0.36,1),opacity_0.5s,filter_0.5s,height_0.15s]",
152
+ "motion-reduce:[transition:none]"
142
153
  ].join(" ");
143
154
  const STACKING_TOP = [
144
155
  "[--toast-stack-offset-y:calc(var(--toast-offset-y)+calc(var(--toast-index)*var(--toast-gap))+var(--toast-swipe-movement-y))]",