@7onic-ui/react 0.3.12 → 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/{chunk-NWFMJWGX.mjs → chunk-MUAIQGMU.mjs} +52 -5
- package/dist/chunk-MUAIQGMU.mjs.map +1 -0
- package/dist/{chunk-V5UFWYFI.mjs → chunk-WDTDGSJN.mjs} +4 -4
- package/dist/{chunk-V5UFWYFI.mjs.map → chunk-WDTDGSJN.mjs.map} +1 -1
- package/dist/components/breadcrumb.mjs +1 -1
- package/dist/components/dropdown.mjs +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +54 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/llms.txt +5 -5
- package/package.json +1 -1
- package/dist/chunk-NWFMJWGX.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -324,7 +324,7 @@ your project's `.claude/`) or copy the files from
|
|
|
324
324
|
- [x] Automated doc verification (8 checks, AST-powered, blocks publish on error)
|
|
325
325
|
- [x] Automated component verification (7 checks — hardcoded colors, tokens, dark mode, dead code)
|
|
326
326
|
- [x] Multilingual documentation — English, Japanese, Korean (powered by next-intl)
|
|
327
|
-
- [x] npm package distribution — `@7onic-ui/react` + `@7onic-ui/tokens` v0.3.
|
|
327
|
+
- [x] npm package distribution — `@7onic-ui/react` + `@7onic-ui/tokens` v0.3.14
|
|
328
328
|
- [x] AI integration — `llms.txt` standard, setup guides for Claude Code / Cursor / Copilot / ChatGPT
|
|
329
329
|
- [x] MCP server — token search, component catalog, layout recipes, `validate_code` rule checking (en/ja/ko), Claude Code plugin one-command install
|
|
330
330
|
- [x] AI Kit — `/7onic-setup` + `/7onic-design` skills and a design agent (plugin, `npx 7onic init --claude`, or manual copy)
|
|
@@ -355,5 +355,5 @@ MIT
|
|
|
355
355
|
<p align="center">
|
|
356
356
|
<strong>One JSON, every format — from Figma to production.</strong><br>
|
|
357
357
|
Independently built.<br>
|
|
358
|
-
<sub>Last updated: 2026-10-
|
|
358
|
+
<sub>Last updated: 2026-10-30 (v0.3.14)</sub>
|
|
359
359
|
</p>
|
|
@@ -40,7 +40,7 @@ var breadcrumbSizeMap = {
|
|
|
40
40
|
lg: { text: "text-md", icon: "icon-sm", gap: "gap-2" }
|
|
41
41
|
};
|
|
42
42
|
var Breadcrumb = React.forwardRef(
|
|
43
|
-
({ className, separator, size = "default", ...props }, ref) => /* @__PURE__ */ React.createElement(BreadcrumbContext.Provider, { value: { size, separator } }, /* @__PURE__ */ React.createElement(
|
|
43
|
+
({ className, separator, size = "default", maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 1, ...props }, ref) => /* @__PURE__ */ React.createElement(BreadcrumbContext.Provider, { value: { size, separator, maxItems, itemsBeforeCollapse, itemsAfterCollapse } }, /* @__PURE__ */ React.createElement(
|
|
44
44
|
"nav",
|
|
45
45
|
{
|
|
46
46
|
ref,
|
|
@@ -52,8 +52,8 @@ var Breadcrumb = React.forwardRef(
|
|
|
52
52
|
);
|
|
53
53
|
Breadcrumb.displayName = "Breadcrumb";
|
|
54
54
|
var BreadcrumbList = React.forwardRef(
|
|
55
|
-
({ className, ...props }, ref) => {
|
|
56
|
-
const { size = "default" } = useBreadcrumbContext();
|
|
55
|
+
({ className, children, ...props }, ref) => {
|
|
56
|
+
const { size = "default", maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 1 } = useBreadcrumbContext();
|
|
57
57
|
const sizeClass = breadcrumbSizeMap[size];
|
|
58
58
|
return /* @__PURE__ */ React.createElement(
|
|
59
59
|
"ol",
|
|
@@ -67,7 +67,8 @@ var BreadcrumbList = React.forwardRef(
|
|
|
67
67
|
className
|
|
68
68
|
),
|
|
69
69
|
...props
|
|
70
|
-
}
|
|
70
|
+
},
|
|
71
|
+
collapseItems(children, maxItems, itemsBeforeCollapse, itemsAfterCollapse)
|
|
71
72
|
);
|
|
72
73
|
}
|
|
73
74
|
);
|
|
@@ -151,6 +152,52 @@ var BreadcrumbEllipsis = React.forwardRef(
|
|
|
151
152
|
}
|
|
152
153
|
);
|
|
153
154
|
BreadcrumbEllipsis.displayName = "BreadcrumbEllipsis";
|
|
155
|
+
function flattenFragments(children) {
|
|
156
|
+
return React.Children.toArray(children).flatMap(
|
|
157
|
+
(node) => React.isValidElement(node) && node.type === React.Fragment ? flattenFragments(node.props.children).map(
|
|
158
|
+
(child) => (
|
|
159
|
+
// Prefix keys so children of different fragments stay unique
|
|
160
|
+
React.isValidElement(child) ? React.cloneElement(child, { key: `${node.key}${child.key}` }) : child
|
|
161
|
+
)
|
|
162
|
+
) : [node]
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
function classifyNodes(nodes) {
|
|
166
|
+
const known = nodes.map((node) => {
|
|
167
|
+
const type = React.isValidElement(node) ? node.type : null;
|
|
168
|
+
return type === BreadcrumbSeparator ? "separator" : type === BreadcrumbItem ? "item" : null;
|
|
169
|
+
});
|
|
170
|
+
if (known.every((kind) => kind === null)) {
|
|
171
|
+
return nodes.map((_, i) => i % 2 === 0 ? "item" : "separator");
|
|
172
|
+
}
|
|
173
|
+
return known.map((kind) => kind ?? "item");
|
|
174
|
+
}
|
|
175
|
+
function collapseItems(children, maxItems, before, after) {
|
|
176
|
+
if (maxItems === void 0) return children;
|
|
177
|
+
const nodes = flattenFragments(children);
|
|
178
|
+
const kinds = classifyNodes(nodes);
|
|
179
|
+
const segments = [];
|
|
180
|
+
let pendingSeparator = null;
|
|
181
|
+
nodes.forEach((node, i) => {
|
|
182
|
+
if (kinds[i] === "separator") {
|
|
183
|
+
pendingSeparator = node;
|
|
184
|
+
} else {
|
|
185
|
+
segments.push({ separator: pendingSeparator, nodes: [node] });
|
|
186
|
+
pendingSeparator = null;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
if (segments.length <= maxItems || before + after >= segments.length) return children;
|
|
190
|
+
const head = segments.slice(0, before);
|
|
191
|
+
const tail = segments.slice(segments.length - after);
|
|
192
|
+
const render = (list) => list.flatMap((seg) => seg.separator ? [seg.separator, ...seg.nodes] : seg.nodes);
|
|
193
|
+
const ellipsisSeparator = segments[before].separator;
|
|
194
|
+
return [
|
|
195
|
+
...render(head),
|
|
196
|
+
...ellipsisSeparator ? [ellipsisSeparator] : [],
|
|
197
|
+
/* @__PURE__ */ React.createElement(BreadcrumbItem, { key: "breadcrumb-collapsed" }, /* @__PURE__ */ React.createElement(BreadcrumbEllipsis, null)),
|
|
198
|
+
...render(tail)
|
|
199
|
+
];
|
|
200
|
+
}
|
|
154
201
|
|
|
155
202
|
export {
|
|
156
203
|
breadcrumbSizeMap,
|
|
@@ -162,4 +209,4 @@ export {
|
|
|
162
209
|
BreadcrumbSeparator,
|
|
163
210
|
BreadcrumbEllipsis
|
|
164
211
|
};
|
|
165
|
-
//# sourceMappingURL=chunk-
|
|
212
|
+
//# sourceMappingURL=chunk-MUAIQGMU.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/breadcrumb.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { cn } from '@/lib/utils'\n\n// ─── Context ──────────────────────────────────────────────\n\ntype BreadcrumbContextValue = {\n size?: 'sm' | 'default' | 'lg'\n separator?: React.ReactNode\n maxItems?: number\n itemsBeforeCollapse?: number\n itemsAfterCollapse?: number\n}\n\nconst BreadcrumbContext = React.createContext<BreadcrumbContextValue>({})\nconst useBreadcrumbContext = () => React.useContext(BreadcrumbContext)\n\n// ─── Default Separator Icon ───────────────────────────────\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n )\n}\n\n// ─── Ellipsis Icon ────────────────────────────────────────\n\nfunction EllipsisIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" />\n </svg>\n )\n}\n\n// ─── Breadcrumb (Root) ────────────────────────────────────\n\nconst breadcrumbSizeMap = {\n sm: { text: 'text-xs', icon: 'icon-xs', gap: 'gap-1.5' },\n default: { text: 'text-sm', icon: 'icon-xs', gap: 'gap-2' },\n lg: { text: 'text-md', icon: 'icon-sm', gap: 'gap-2' },\n} as const\n\nexport interface BreadcrumbProps extends React.ComponentPropsWithoutRef<'nav'> {\n /** Separator element between items */\n separator?: React.ReactNode\n /** Size of the breadcrumb */\n size?: 'sm' | 'default' | 'lg'\n /** Collapse the middle items into an ellipsis when there are more items than this (undefined = no collapse) */\n maxItems?: number\n /** Items kept before the ellipsis when collapsed */\n itemsBeforeCollapse?: number\n /** Items kept after the ellipsis when collapsed */\n itemsAfterCollapse?: number\n}\n\nconst Breadcrumb = React.forwardRef<HTMLElement, BreadcrumbProps>(\n ({ className, separator, size = 'default', maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 1, ...props }, ref) => (\n <BreadcrumbContext.Provider value={{ size, separator, maxItems, itemsBeforeCollapse, itemsAfterCollapse }}>\n <nav\n ref={ref}\n aria-label=\"breadcrumb\"\n className={cn('', className)}\n {...props}\n />\n </BreadcrumbContext.Provider>\n )\n)\nBreadcrumb.displayName = 'Breadcrumb'\n\n// ─── BreadcrumbList ───────────────────────────────────────\n\nconst BreadcrumbList = React.forwardRef<HTMLOListElement, React.ComponentPropsWithoutRef<'ol'>>(\n ({ className, children, ...props }, ref) => {\n const { size = 'default', maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 1 } = useBreadcrumbContext()\n const sizeClass = breadcrumbSizeMap[size]\n return (\n <ol\n ref={ref}\n className={cn(\n 'flex flex-wrap items-center',\n sizeClass.gap,\n sizeClass.text,\n 'text-text-muted',\n className\n )}\n {...props}\n >\n {collapseItems(children, maxItems, itemsBeforeCollapse, itemsAfterCollapse)}\n </ol>\n )\n }\n)\nBreadcrumbList.displayName = 'BreadcrumbList'\n\n// ─── BreadcrumbItem ───────────────────────────────────────\n\nconst BreadcrumbItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<'li'>>(\n ({ className, ...props }, ref) => (\n <li\n ref={ref}\n className={cn('inline-flex items-center gap-1.5', className)}\n {...props}\n />\n )\n)\nBreadcrumbItem.displayName = 'BreadcrumbItem'\n\n// ─── BreadcrumbLink ───────────────────────────────────────\n\nexport interface BreadcrumbLinkProps extends React.ComponentPropsWithoutRef<'a'> {\n /** Use Radix Slot to compose with custom link components */\n asChild?: boolean\n}\n\nconst BreadcrumbLink = React.forwardRef<HTMLAnchorElement, BreadcrumbLinkProps>(\n ({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : 'a'\n return (\n <Comp\n ref={ref}\n className={cn(\n 'transition-colors duration-fast hover:text-foreground',\n className\n )}\n {...props}\n />\n )\n }\n)\nBreadcrumbLink.displayName = 'BreadcrumbLink'\n\n// ─── BreadcrumbPage ───────────────────────────────────────\n\nconst BreadcrumbPage = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<'span'>>(\n ({ className, ...props }, ref) => (\n <span\n ref={ref}\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('text-foreground', className)}\n {...props}\n />\n )\n)\nBreadcrumbPage.displayName = 'BreadcrumbPage'\n\n// ─── BreadcrumbSeparator ──────────────────────────────────\n\nconst BreadcrumbSeparator = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<'li'>>(\n ({ children, className, ...props }, ref) => {\n const { separator, size = 'default' } = useBreadcrumbContext()\n const sizeClass = breadcrumbSizeMap[size]\n return (\n <li\n ref={ref}\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('flex items-center text-text-subtle', className)}\n {...props}\n >\n {children ?? separator ?? <ChevronRightIcon className={sizeClass.icon} />}\n </li>\n )\n }\n)\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator'\n\n// ─── BreadcrumbEllipsis ───────────────────────────────────\n\nexport interface BreadcrumbEllipsisProps extends React.ComponentPropsWithoutRef<'span'> {}\n\nconst BreadcrumbEllipsis = React.forwardRef<HTMLSpanElement, BreadcrumbEllipsisProps>(\n ({ className, ...props }, ref) => {\n const { size = 'default' } = useBreadcrumbContext()\n const sizeClass = breadcrumbSizeMap[size]\n return (\n <span\n ref={ref}\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('flex items-center justify-center', className)}\n {...props}\n >\n <EllipsisIcon className={sizeClass.icon} />\n <span className=\"sr-only\">More</span>\n </span>\n )\n }\n)\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis'\n\n// ─── Collapse ─────────────────────────────────────────────\n\n// Items are often rendered from a list as <Fragment>{separator}{item}</Fragment>,\n// so fragments are unwrapped before counting.\nfunction flattenFragments(children: React.ReactNode): React.ReactNode[] {\n return React.Children.toArray(children).flatMap((node) =>\n React.isValidElement<{ children?: React.ReactNode }>(node) && node.type === React.Fragment\n ? flattenFragments(node.props.children).map((child) =>\n // Prefix keys so children of different fragments stay unique\n React.isValidElement(child) ? React.cloneElement(child, { key: `${node.key}${child.key}` }) : child\n )\n : [node]\n )\n}\n\n// Children passed from a Server Component arrive with lazy element types, so\n// `node.type === BreadcrumbItem` cannot tell them apart. When no child can be\n// identified, the list is read as the alternating item / separator order every\n// breadcrumb uses. Unidentified children next to identified separators (items\n// wrapped in the caller's own component) count as items.\nfunction classifyNodes(nodes: React.ReactNode[]): ('item' | 'separator')[] {\n const known = nodes.map((node) => {\n const type = React.isValidElement(node) ? node.type : null\n return type === BreadcrumbSeparator ? 'separator' : type === BreadcrumbItem ? 'item' : null\n })\n if (known.every((kind) => kind === null)) {\n return nodes.map((_, i) => (i % 2 === 0 ? 'item' : 'separator'))\n }\n return known.map((kind) => kind ?? 'item')\n}\n\n// Groups children into segments (the separator before an item + the item),\n// then keeps the first `before` and last `after` segments around one ellipsis\n// item. The user's own separators are reused, so custom separators survive.\nfunction collapseItems(children: React.ReactNode, maxItems: number | undefined, before: number, after: number) {\n if (maxItems === undefined) return children\n\n const nodes = flattenFragments(children)\n const kinds = classifyNodes(nodes)\n const segments: { separator: React.ReactNode; nodes: React.ReactNode[] }[] = []\n let pendingSeparator: React.ReactNode = null\n nodes.forEach((node, i) => {\n if (kinds[i] === 'separator') {\n pendingSeparator = node\n } else {\n segments.push({ separator: pendingSeparator, nodes: [node] })\n pendingSeparator = null\n }\n })\n\n if (segments.length <= maxItems || before + after >= segments.length) return children\n\n const head = segments.slice(0, before)\n const tail = segments.slice(segments.length - after)\n const render = (list: typeof segments) => list.flatMap((seg) => (seg.separator ? [seg.separator, ...seg.nodes] : seg.nodes))\n const ellipsisSeparator = segments[before].separator\n\n return [\n ...render(head),\n ...(ellipsisSeparator ? [ellipsisSeparator] : []),\n <BreadcrumbItem key=\"breadcrumb-collapsed\">\n <BreadcrumbEllipsis />\n </BreadcrumbItem>,\n ...render(tail),\n ]\n}\n\n// ─── Exports ──────────────────────────────────────────────\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n breadcrumbSizeMap,\n}\n"],"mappings":"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","names":[]}
|
|
@@ -8,11 +8,11 @@ import * as React from "react";
|
|
|
8
8
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
9
9
|
var contentRadiusMap = {
|
|
10
10
|
md: "rounded-md",
|
|
11
|
-
// 6px
|
|
11
|
+
// 6px (default)
|
|
12
12
|
lg: "rounded-lg",
|
|
13
13
|
// 8px
|
|
14
14
|
xl: "rounded-xl"
|
|
15
|
-
// 12px
|
|
15
|
+
// 12px
|
|
16
16
|
};
|
|
17
17
|
var itemRadiusMap = {
|
|
18
18
|
md: "rounded",
|
|
@@ -57,7 +57,7 @@ var insetSizeMap = {
|
|
|
57
57
|
md: "pl-8",
|
|
58
58
|
lg: "pl-10"
|
|
59
59
|
};
|
|
60
|
-
var DropdownMenuStyleContext = React.createContext({ radius: "
|
|
60
|
+
var DropdownMenuStyleContext = React.createContext({ radius: "md", flush: false, size: "md" });
|
|
61
61
|
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
62
62
|
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
63
63
|
var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
@@ -252,4 +252,4 @@ export {
|
|
|
252
252
|
DropdownMenuSubContent,
|
|
253
253
|
DropdownMenuShortcut
|
|
254
254
|
};
|
|
255
|
-
//# sourceMappingURL=chunk-
|
|
255
|
+
//# sourceMappingURL=chunk-WDTDGSJN.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ui/dropdown.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport { cn } from '@/lib/utils'\n\n// Radius variants for Content and Item (concentric rounded rectangles)\ntype DropdownMenuRadius = 'md' | 'lg' | 'xl'\n\nconst contentRadiusMap: Record<DropdownMenuRadius, string> = {\n md: 'rounded-md', // 6px\n lg: 'rounded-lg', // 8px\n xl: 'rounded-xl', // 12px (default)\n}\n\nconst itemRadiusMap: Record<DropdownMenuRadius, string> = {\n md: 'rounded', // 4px — perceptual balance (67%)\n lg: 'rounded-md', // 6px — perceptual balance (75%)\n xl: 'rounded-lg', // 8px — perceptual balance (67%)\n}\n\n// Size variants\ntype DropdownMenuSize = 'sm' | 'md' | 'lg'\n\nconst itemSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'px-2 py-1.5 text-xs',\n md: 'px-2 py-1.5 text-sm',\n lg: 'px-3 py-2.5 text-md',\n}\n\nconst indicatorItemSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'py-1.5 pl-6 pr-2 text-xs',\n md: 'py-1.5 pl-8 pr-2 text-sm',\n lg: 'py-2.5 pl-10 pr-3 text-md',\n}\n\nconst indicatorSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'left-2 h-3 w-3',\n md: 'left-2 h-3.5 w-3.5',\n lg: 'left-3 h-4 w-4',\n}\n\nconst labelSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'px-2 py-1.5 text-xs',\n md: 'px-2 py-1.5 text-xs',\n lg: 'px-3 py-2.5 text-xs',\n}\n\nconst flushItemPaddingMap: Record<DropdownMenuSize, string> = {\n sm: 'px-3',\n md: 'px-3',\n lg: 'px-4',\n}\n\nconst flushIndicatorItemPaddingMap: Record<DropdownMenuSize, string> = {\n sm: 'pl-7 pr-3',\n md: 'pl-9 pr-3',\n lg: 'pl-11 pr-4',\n}\n\nconst insetSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'pl-6',\n md: 'pl-8',\n lg: 'pl-10',\n}\n\n// Style context — propagates radius, flush, size from Content to children\nconst DropdownMenuStyleContext = React.createContext<{\n radius: DropdownMenuRadius\n flush: boolean\n size: DropdownMenuSize\n}>({ radius: 'lg', flush: false, size: 'md' })\n\n// Root — state management (controlled / uncontrolled)\nconst DropdownMenu = DropdownMenuPrimitive.Root\n\n// Trigger — the element that toggles the menu\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\n\n// Group — groups related items\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\n// Sub — submenu root\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub\n\n// RadioGroup — radio selection group\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup\n\n// Content — the floating panel (rendered in a Portal)\nconst DropdownMenuContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> & {\n radius?: DropdownMenuRadius\n flush?: boolean\n size?: DropdownMenuSize\n }\n>(({ className, sideOffset = 4, radius = 'md', flush = false, size = 'md', onCloseAutoFocus, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuStyleContext.Provider value={{ radius, flush, size }}>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n onCloseAutoFocus={(e) => {\n e.preventDefault()\n onCloseAutoFocus?.(e)\n }}\n className={cn(\n 'z-popover min-w-[8rem] overflow-hidden border border-border bg-background text-foreground shadow-lg',\n flush ? 'py-1' : 'p-1',\n contentRadiusMap[radius],\n className\n )}\n {...props}\n />\n </DropdownMenuStyleContext.Provider>\n </DropdownMenuPrimitive.Portal>\n))\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\n// Item — a single menu item\nconst DropdownMenuItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => {\n const { radius, flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center outline-none',\n itemSizeMap[size],\n !flush && itemRadiusMap[radius],\n flush && flushItemPaddingMap[size],\n 'transition-colors duration-fast',\n 'focus:bg-background-muted',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && insetSizeMap[size],\n className\n )}\n {...props}\n />\n )\n})\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName\n\n// CheckboxItem — item with a checkbox indicator\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => {\n const { radius, flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center outline-none',\n indicatorItemSizeMap[size],\n !flush && itemRadiusMap[radius],\n flush && flushIndicatorItemPaddingMap[size],\n 'transition-colors duration-fast',\n 'focus:bg-background-muted',\n 'data-[state=checked]:text-foreground data-[state=checked]:font-semibold',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n checked={checked}\n {...props}\n >\n <span className={cn('absolute flex items-center justify-center', indicatorSizeMap[size])}>\n <DropdownMenuPrimitive.ItemIndicator>\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n})\nDropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName\n\n// RadioItem — item within a RadioGroup\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => {\n const { radius, flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center outline-none',\n indicatorItemSizeMap[size],\n !flush && itemRadiusMap[radius],\n flush && flushIndicatorItemPaddingMap[size],\n 'transition-colors duration-fast',\n 'focus:bg-background-muted',\n 'data-[state=checked]:text-foreground data-[state=checked]:font-semibold',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n {...props}\n >\n <span className={cn('absolute flex items-center justify-center', indicatorSizeMap[size])}>\n <DropdownMenuPrimitive.ItemIndicator>\n <svg className=\"icon-xs\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n </svg>\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n})\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName\n\n// Label — non-interactive group heading\nconst DropdownMenuLabel = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => {\n const { flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n 'font-semibold text-text-muted',\n labelSizeMap[size],\n flush && flushItemPaddingMap[size],\n inset && insetSizeMap[size],\n className\n )}\n {...props}\n />\n )\n})\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\n// Separator — visual divider between groups\nconst DropdownMenuSeparator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => {\n const { flush } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn('h-px bg-border my-1', !flush && '-mx-1', className)}\n {...props}\n />\n )\n})\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\n// SubTrigger — item that opens a submenu\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n }\n>(({ className, inset, children, ...props }, ref) => {\n const { radius, flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n 'flex cursor-default select-none items-center outline-none',\n itemSizeMap[size],\n !flush && itemRadiusMap[radius],\n flush && flushItemPaddingMap[size],\n 'focus:bg-background-muted data-[state=open]:bg-background-muted',\n inset && insetSizeMap[size],\n className\n )}\n {...props}\n >\n {children}\n <svg className=\"ml-auto icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </DropdownMenuPrimitive.SubTrigger>\n )\n})\nDropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName\n\n// SubContent — the floating panel for a submenu\nconst DropdownMenuSubContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => {\n const { radius, flush } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n 'z-popover min-w-[8rem] overflow-hidden border border-border bg-background text-foreground shadow-lg',\n flush ? 'py-1' : 'p-1',\n contentRadiusMap[radius],\n className\n )}\n {...props}\n />\n )\n})\nDropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName\n\n// Shortcut — keyboard shortcut hint text\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) {\n return (\n <span\n className={cn('ml-auto pl-4 text-xs text-text-subtle tracking-widest', className)}\n {...props}\n />\n )\n}\nDropdownMenuShortcut.displayName = 'DropdownMenuShortcut'\n\nexport type { DropdownMenuRadius, DropdownMenuSize }\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuGroup,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n DropdownMenuShortcut,\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/dropdown.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport { cn } from '@/lib/utils'\n\n// Radius variants for Content and Item (concentric rounded rectangles)\ntype DropdownMenuRadius = 'md' | 'lg' | 'xl'\n\nconst contentRadiusMap: Record<DropdownMenuRadius, string> = {\n md: 'rounded-md', // 6px (default)\n lg: 'rounded-lg', // 8px\n xl: 'rounded-xl', // 12px\n}\n\nconst itemRadiusMap: Record<DropdownMenuRadius, string> = {\n md: 'rounded', // 4px — perceptual balance (67%)\n lg: 'rounded-md', // 6px — perceptual balance (75%)\n xl: 'rounded-lg', // 8px — perceptual balance (67%)\n}\n\n// Size variants\ntype DropdownMenuSize = 'sm' | 'md' | 'lg'\n\nconst itemSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'px-2 py-1.5 text-xs',\n md: 'px-2 py-1.5 text-sm',\n lg: 'px-3 py-2.5 text-md',\n}\n\nconst indicatorItemSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'py-1.5 pl-6 pr-2 text-xs',\n md: 'py-1.5 pl-8 pr-2 text-sm',\n lg: 'py-2.5 pl-10 pr-3 text-md',\n}\n\nconst indicatorSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'left-2 h-3 w-3',\n md: 'left-2 h-3.5 w-3.5',\n lg: 'left-3 h-4 w-4',\n}\n\nconst labelSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'px-2 py-1.5 text-xs',\n md: 'px-2 py-1.5 text-xs',\n lg: 'px-3 py-2.5 text-xs',\n}\n\nconst flushItemPaddingMap: Record<DropdownMenuSize, string> = {\n sm: 'px-3',\n md: 'px-3',\n lg: 'px-4',\n}\n\nconst flushIndicatorItemPaddingMap: Record<DropdownMenuSize, string> = {\n sm: 'pl-7 pr-3',\n md: 'pl-9 pr-3',\n lg: 'pl-11 pr-4',\n}\n\nconst insetSizeMap: Record<DropdownMenuSize, string> = {\n sm: 'pl-6',\n md: 'pl-8',\n lg: 'pl-10',\n}\n\n// Style context — propagates radius, flush, size from Content to children\nconst DropdownMenuStyleContext = React.createContext<{\n radius: DropdownMenuRadius\n flush: boolean\n size: DropdownMenuSize\n}>({ radius: 'md', flush: false, size: 'md' })\n\n// Root — state management (controlled / uncontrolled)\nconst DropdownMenu = DropdownMenuPrimitive.Root\n\n// Trigger — the element that toggles the menu\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\n\n// Group — groups related items\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\n// Sub — submenu root\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub\n\n// RadioGroup — radio selection group\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup\n\n// Content — the floating panel (rendered in a Portal)\nconst DropdownMenuContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> & {\n radius?: DropdownMenuRadius\n flush?: boolean\n size?: DropdownMenuSize\n }\n>(({ className, sideOffset = 4, radius = 'md', flush = false, size = 'md', onCloseAutoFocus, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuStyleContext.Provider value={{ radius, flush, size }}>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n onCloseAutoFocus={(e) => {\n e.preventDefault()\n onCloseAutoFocus?.(e)\n }}\n className={cn(\n 'z-popover min-w-[8rem] overflow-hidden border border-border bg-background text-foreground shadow-lg',\n flush ? 'py-1' : 'p-1',\n contentRadiusMap[radius],\n className\n )}\n {...props}\n />\n </DropdownMenuStyleContext.Provider>\n </DropdownMenuPrimitive.Portal>\n))\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\n// Item — a single menu item\nconst DropdownMenuItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => {\n const { radius, flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center outline-none',\n itemSizeMap[size],\n !flush && itemRadiusMap[radius],\n flush && flushItemPaddingMap[size],\n 'transition-colors duration-fast',\n 'focus:bg-background-muted',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && insetSizeMap[size],\n className\n )}\n {...props}\n />\n )\n})\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName\n\n// CheckboxItem — item with a checkbox indicator\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => {\n const { radius, flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center outline-none',\n indicatorItemSizeMap[size],\n !flush && itemRadiusMap[radius],\n flush && flushIndicatorItemPaddingMap[size],\n 'transition-colors duration-fast',\n 'focus:bg-background-muted',\n 'data-[state=checked]:text-foreground data-[state=checked]:font-semibold',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n checked={checked}\n {...props}\n >\n <span className={cn('absolute flex items-center justify-center', indicatorSizeMap[size])}>\n <DropdownMenuPrimitive.ItemIndicator>\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n})\nDropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName\n\n// RadioItem — item within a RadioGroup\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => {\n const { radius, flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center outline-none',\n indicatorItemSizeMap[size],\n !flush && itemRadiusMap[radius],\n flush && flushIndicatorItemPaddingMap[size],\n 'transition-colors duration-fast',\n 'focus:bg-background-muted',\n 'data-[state=checked]:text-foreground data-[state=checked]:font-semibold',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n {...props}\n >\n <span className={cn('absolute flex items-center justify-center', indicatorSizeMap[size])}>\n <DropdownMenuPrimitive.ItemIndicator>\n <svg className=\"icon-xs\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n </svg>\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n})\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName\n\n// Label — non-interactive group heading\nconst DropdownMenuLabel = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => {\n const { flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n 'font-semibold text-text-muted',\n labelSizeMap[size],\n flush && flushItemPaddingMap[size],\n inset && insetSizeMap[size],\n className\n )}\n {...props}\n />\n )\n})\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\n// Separator — visual divider between groups\nconst DropdownMenuSeparator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => {\n const { flush } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn('h-px bg-border my-1', !flush && '-mx-1', className)}\n {...props}\n />\n )\n})\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\n// SubTrigger — item that opens a submenu\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n }\n>(({ className, inset, children, ...props }, ref) => {\n const { radius, flush, size } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n 'flex cursor-default select-none items-center outline-none',\n itemSizeMap[size],\n !flush && itemRadiusMap[radius],\n flush && flushItemPaddingMap[size],\n 'focus:bg-background-muted data-[state=open]:bg-background-muted',\n inset && insetSizeMap[size],\n className\n )}\n {...props}\n >\n {children}\n <svg className=\"ml-auto icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </DropdownMenuPrimitive.SubTrigger>\n )\n})\nDropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName\n\n// SubContent — the floating panel for a submenu\nconst DropdownMenuSubContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => {\n const { radius, flush } = React.useContext(DropdownMenuStyleContext)\n return (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n 'z-popover min-w-[8rem] overflow-hidden border border-border bg-background text-foreground shadow-lg',\n flush ? 'py-1' : 'p-1',\n contentRadiusMap[radius],\n className\n )}\n {...props}\n />\n )\n})\nDropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName\n\n// Shortcut — keyboard shortcut hint text\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) {\n return (\n <span\n className={cn('ml-auto pl-4 text-xs text-text-subtle tracking-widest', className)}\n {...props}\n />\n )\n}\nDropdownMenuShortcut.displayName = 'DropdownMenuShortcut'\n\nexport type { DropdownMenuRadius, DropdownMenuSize }\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuGroup,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n DropdownMenuShortcut,\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -75,11 +75,11 @@ interface BreadcrumbProps extends React.ComponentPropsWithoutRef<'nav'> {
|
|
|
75
75
|
separator?: React.ReactNode;
|
|
76
76
|
/** Size of the breadcrumb */
|
|
77
77
|
size?: 'sm' | 'default' | 'lg';
|
|
78
|
-
/**
|
|
78
|
+
/** Collapse the middle items into an ellipsis when there are more items than this (undefined = no collapse) */
|
|
79
79
|
maxItems?: number;
|
|
80
|
-
/** Items
|
|
80
|
+
/** Items kept before the ellipsis when collapsed */
|
|
81
81
|
itemsBeforeCollapse?: number;
|
|
82
|
-
/** Items
|
|
82
|
+
/** Items kept after the ellipsis when collapsed */
|
|
83
83
|
itemsAfterCollapse?: number;
|
|
84
84
|
}
|
|
85
85
|
declare const Breadcrumb: React.ForwardRefExoticComponent<BreadcrumbProps & React.RefAttributes<HTMLElement>>;
|
package/dist/index.js
CHANGED
|
@@ -465,7 +465,7 @@ var breadcrumbSizeMap = {
|
|
|
465
465
|
lg: { text: "text-md", icon: "icon-sm", gap: "gap-2" }
|
|
466
466
|
};
|
|
467
467
|
var Breadcrumb = React2.forwardRef(
|
|
468
|
-
({ className, separator, size = "default", ...props }, ref) => /* @__PURE__ */ React2.createElement(BreadcrumbContext.Provider, { value: { size, separator } }, /* @__PURE__ */ React2.createElement(
|
|
468
|
+
({ className, separator, size = "default", maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 1, ...props }, ref) => /* @__PURE__ */ React2.createElement(BreadcrumbContext.Provider, { value: { size, separator, maxItems, itemsBeforeCollapse, itemsAfterCollapse } }, /* @__PURE__ */ React2.createElement(
|
|
469
469
|
"nav",
|
|
470
470
|
{
|
|
471
471
|
ref,
|
|
@@ -477,8 +477,8 @@ var Breadcrumb = React2.forwardRef(
|
|
|
477
477
|
);
|
|
478
478
|
Breadcrumb.displayName = "Breadcrumb";
|
|
479
479
|
var BreadcrumbList = React2.forwardRef(
|
|
480
|
-
({ className, ...props }, ref) => {
|
|
481
|
-
const { size = "default" } = useBreadcrumbContext();
|
|
480
|
+
({ className, children, ...props }, ref) => {
|
|
481
|
+
const { size = "default", maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 1 } = useBreadcrumbContext();
|
|
482
482
|
const sizeClass = breadcrumbSizeMap[size];
|
|
483
483
|
return /* @__PURE__ */ React2.createElement(
|
|
484
484
|
"ol",
|
|
@@ -492,7 +492,8 @@ var BreadcrumbList = React2.forwardRef(
|
|
|
492
492
|
className
|
|
493
493
|
),
|
|
494
494
|
...props
|
|
495
|
-
}
|
|
495
|
+
},
|
|
496
|
+
collapseItems(children, maxItems, itemsBeforeCollapse, itemsAfterCollapse)
|
|
496
497
|
);
|
|
497
498
|
}
|
|
498
499
|
);
|
|
@@ -576,6 +577,52 @@ var BreadcrumbEllipsis = React2.forwardRef(
|
|
|
576
577
|
}
|
|
577
578
|
);
|
|
578
579
|
BreadcrumbEllipsis.displayName = "BreadcrumbEllipsis";
|
|
580
|
+
function flattenFragments(children) {
|
|
581
|
+
return React2.Children.toArray(children).flatMap(
|
|
582
|
+
(node) => React2.isValidElement(node) && node.type === React2.Fragment ? flattenFragments(node.props.children).map(
|
|
583
|
+
(child) => (
|
|
584
|
+
// Prefix keys so children of different fragments stay unique
|
|
585
|
+
React2.isValidElement(child) ? React2.cloneElement(child, { key: `${node.key}${child.key}` }) : child
|
|
586
|
+
)
|
|
587
|
+
) : [node]
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
function classifyNodes(nodes) {
|
|
591
|
+
const known = nodes.map((node) => {
|
|
592
|
+
const type = React2.isValidElement(node) ? node.type : null;
|
|
593
|
+
return type === BreadcrumbSeparator ? "separator" : type === BreadcrumbItem ? "item" : null;
|
|
594
|
+
});
|
|
595
|
+
if (known.every((kind) => kind === null)) {
|
|
596
|
+
return nodes.map((_, i) => i % 2 === 0 ? "item" : "separator");
|
|
597
|
+
}
|
|
598
|
+
return known.map((kind) => kind ?? "item");
|
|
599
|
+
}
|
|
600
|
+
function collapseItems(children, maxItems, before, after) {
|
|
601
|
+
if (maxItems === void 0) return children;
|
|
602
|
+
const nodes = flattenFragments(children);
|
|
603
|
+
const kinds = classifyNodes(nodes);
|
|
604
|
+
const segments = [];
|
|
605
|
+
let pendingSeparator = null;
|
|
606
|
+
nodes.forEach((node, i) => {
|
|
607
|
+
if (kinds[i] === "separator") {
|
|
608
|
+
pendingSeparator = node;
|
|
609
|
+
} else {
|
|
610
|
+
segments.push({ separator: pendingSeparator, nodes: [node] });
|
|
611
|
+
pendingSeparator = null;
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
if (segments.length <= maxItems || before + after >= segments.length) return children;
|
|
615
|
+
const head = segments.slice(0, before);
|
|
616
|
+
const tail = segments.slice(segments.length - after);
|
|
617
|
+
const render = (list) => list.flatMap((seg) => seg.separator ? [seg.separator, ...seg.nodes] : seg.nodes);
|
|
618
|
+
const ellipsisSeparator = segments[before].separator;
|
|
619
|
+
return [
|
|
620
|
+
...render(head),
|
|
621
|
+
...ellipsisSeparator ? [ellipsisSeparator] : [],
|
|
622
|
+
/* @__PURE__ */ React2.createElement(BreadcrumbItem, { key: "breadcrumb-collapsed" }, /* @__PURE__ */ React2.createElement(BreadcrumbEllipsis, null)),
|
|
623
|
+
...render(tail)
|
|
624
|
+
];
|
|
625
|
+
}
|
|
579
626
|
|
|
580
627
|
// src/components/ui/divider.tsx
|
|
581
628
|
var React3 = __toESM(require("react"));
|
|
@@ -2510,11 +2557,11 @@ var React17 = __toESM(require("react"));
|
|
|
2510
2557
|
var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"));
|
|
2511
2558
|
var contentRadiusMap = {
|
|
2512
2559
|
md: "rounded-md",
|
|
2513
|
-
// 6px
|
|
2560
|
+
// 6px (default)
|
|
2514
2561
|
lg: "rounded-lg",
|
|
2515
2562
|
// 8px
|
|
2516
2563
|
xl: "rounded-xl"
|
|
2517
|
-
// 12px
|
|
2564
|
+
// 12px
|
|
2518
2565
|
};
|
|
2519
2566
|
var itemRadiusMap = {
|
|
2520
2567
|
md: "rounded",
|
|
@@ -2559,7 +2606,7 @@ var insetSizeMap = {
|
|
|
2559
2606
|
md: "pl-8",
|
|
2560
2607
|
lg: "pl-10"
|
|
2561
2608
|
};
|
|
2562
|
-
var DropdownMenuStyleContext = React17.createContext({ radius: "
|
|
2609
|
+
var DropdownMenuStyleContext = React17.createContext({ radius: "md", flush: false, size: "md" });
|
|
2563
2610
|
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
2564
2611
|
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
2565
2612
|
var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|