7onic 0.1.20 → 0.1.22

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.
Files changed (2) hide show
  1. package/dist/index.js +84 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10192,6 +10192,9 @@ import { cn } from '@/lib/utils'
10192
10192
  type BreadcrumbContextValue = {
10193
10193
  size?: 'sm' | 'default' | 'lg'
10194
10194
  separator?: React.ReactNode
10195
+ maxItems?: number
10196
+ itemsBeforeCollapse?: number
10197
+ itemsAfterCollapse?: number
10195
10198
  }
10196
10199
 
10197
10200
  const BreadcrumbContext = React.createContext<BreadcrumbContextValue>({})
@@ -10242,17 +10245,17 @@ export interface BreadcrumbProps extends React.ComponentPropsWithoutRef<'nav'> {
10242
10245
  separator?: React.ReactNode
10243
10246
  /** Size of the breadcrumb */
10244
10247
  size?: 'sm' | 'default' | 'lg'
10245
- /** Max items before collapsing (undefined = no collapse) */
10248
+ /** Collapse the middle items into an ellipsis when there are more items than this (undefined = no collapse) */
10246
10249
  maxItems?: number
10247
- /** Items visible before the ellipsis when collapsed */
10250
+ /** Items kept before the ellipsis when collapsed */
10248
10251
  itemsBeforeCollapse?: number
10249
- /** Items visible after the ellipsis when collapsed */
10252
+ /** Items kept after the ellipsis when collapsed */
10250
10253
  itemsAfterCollapse?: number
10251
10254
  }
10252
10255
 
10253
10256
  const Breadcrumb = React.forwardRef<HTMLElement, BreadcrumbProps>(
10254
- ({ className, separator, size = 'default', ...props }, ref) => (
10255
- <BreadcrumbContext.Provider value={{ size, separator }}>
10257
+ ({ className, separator, size = 'default', maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 1, ...props }, ref) => (
10258
+ <BreadcrumbContext.Provider value={{ size, separator, maxItems, itemsBeforeCollapse, itemsAfterCollapse }}>
10256
10259
  <nav
10257
10260
  ref={ref}
10258
10261
  aria-label="breadcrumb"
@@ -10267,8 +10270,8 @@ Breadcrumb.displayName = 'Breadcrumb'
10267
10270
  // \u2500\u2500\u2500 BreadcrumbList \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
10268
10271
 
10269
10272
  const BreadcrumbList = React.forwardRef<HTMLOListElement, React.ComponentPropsWithoutRef<'ol'>>(
10270
- ({ className, ...props }, ref) => {
10271
- const { size = 'default' } = useBreadcrumbContext()
10273
+ ({ className, children, ...props }, ref) => {
10274
+ const { size = 'default', maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 1 } = useBreadcrumbContext()
10272
10275
  const sizeClass = breadcrumbSizeMap[size]
10273
10276
  return (
10274
10277
  <ol
@@ -10281,7 +10284,9 @@ const BreadcrumbList = React.forwardRef<HTMLOListElement, React.ComponentPropsWi
10281
10284
  className
10282
10285
  )}
10283
10286
  {...props}
10284
- />
10287
+ >
10288
+ {collapseItems(children, maxItems, itemsBeforeCollapse, itemsAfterCollapse)}
10289
+ </ol>
10285
10290
  )
10286
10291
  }
10287
10292
  )
@@ -10385,6 +10390,73 @@ const BreadcrumbEllipsis = React.forwardRef<HTMLSpanElement, BreadcrumbEllipsisP
10385
10390
  )
10386
10391
  BreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis'
10387
10392
 
10393
+ // \u2500\u2500\u2500 Collapse \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
10394
+
10395
+ // Items are often rendered from a list as <Fragment>{separator}{item}</Fragment>,
10396
+ // so fragments are unwrapped before counting.
10397
+ function flattenFragments(children: React.ReactNode): React.ReactNode[] {
10398
+ return React.Children.toArray(children).flatMap((node) =>
10399
+ React.isValidElement<{ children?: React.ReactNode }>(node) && node.type === React.Fragment
10400
+ ? flattenFragments(node.props.children).map((child) =>
10401
+ // Prefix keys so children of different fragments stay unique
10402
+ React.isValidElement(child) ? React.cloneElement(child, { key: \`\${node.key}\${child.key}\` }) : child
10403
+ )
10404
+ : [node]
10405
+ )
10406
+ }
10407
+
10408
+ // Children passed from a Server Component arrive with lazy element types, so
10409
+ // \`node.type === BreadcrumbItem\` cannot tell them apart. When no child can be
10410
+ // identified, the list is read as the alternating item / separator order every
10411
+ // breadcrumb uses. Unidentified children next to identified separators (items
10412
+ // wrapped in the caller's own component) count as items.
10413
+ function classifyNodes(nodes: React.ReactNode[]): ('item' | 'separator')[] {
10414
+ const known = nodes.map((node) => {
10415
+ const type = React.isValidElement(node) ? node.type : null
10416
+ return type === BreadcrumbSeparator ? 'separator' : type === BreadcrumbItem ? 'item' : null
10417
+ })
10418
+ if (known.every((kind) => kind === null)) {
10419
+ return nodes.map((_, i) => (i % 2 === 0 ? 'item' : 'separator'))
10420
+ }
10421
+ return known.map((kind) => kind ?? 'item')
10422
+ }
10423
+
10424
+ // Groups children into segments (the separator before an item + the item),
10425
+ // then keeps the first \`before\` and last \`after\` segments around one ellipsis
10426
+ // item. The user's own separators are reused, so custom separators survive.
10427
+ function collapseItems(children: React.ReactNode, maxItems: number | undefined, before: number, after: number) {
10428
+ if (maxItems === undefined) return children
10429
+
10430
+ const nodes = flattenFragments(children)
10431
+ const kinds = classifyNodes(nodes)
10432
+ const segments: { separator: React.ReactNode; nodes: React.ReactNode[] }[] = []
10433
+ let pendingSeparator: React.ReactNode = null
10434
+ nodes.forEach((node, i) => {
10435
+ if (kinds[i] === 'separator') {
10436
+ pendingSeparator = node
10437
+ } else {
10438
+ segments.push({ separator: pendingSeparator, nodes: [node] })
10439
+ pendingSeparator = null
10440
+ }
10441
+ })
10442
+
10443
+ if (segments.length <= maxItems || before + after >= segments.length) return children
10444
+
10445
+ const head = segments.slice(0, before)
10446
+ const tail = segments.slice(segments.length - after)
10447
+ const render = (list: typeof segments) => list.flatMap((seg) => (seg.separator ? [seg.separator, ...seg.nodes] : seg.nodes))
10448
+ const ellipsisSeparator = segments[before].separator
10449
+
10450
+ return [
10451
+ ...render(head),
10452
+ ...(ellipsisSeparator ? [ellipsisSeparator] : []),
10453
+ <BreadcrumbItem key="breadcrumb-collapsed">
10454
+ <BreadcrumbEllipsis />
10455
+ </BreadcrumbItem>,
10456
+ ...render(tail),
10457
+ ]
10458
+ }
10459
+
10388
10460
  // \u2500\u2500\u2500 Exports \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
10389
10461
 
10390
10462
  export {
@@ -13586,9 +13658,9 @@ import { cn } from '@/lib/utils'
13586
13658
  type DropdownMenuRadius = 'md' | 'lg' | 'xl'
13587
13659
 
13588
13660
  const contentRadiusMap: Record<DropdownMenuRadius, string> = {
13589
- md: 'rounded-md', // 6px
13661
+ md: 'rounded-md', // 6px (default)
13590
13662
  lg: 'rounded-lg', // 8px
13591
- xl: 'rounded-xl', // 12px (default)
13663
+ xl: 'rounded-xl', // 12px
13592
13664
  }
13593
13665
 
13594
13666
  const itemRadiusMap: Record<DropdownMenuRadius, string> = {
@@ -13647,7 +13719,7 @@ const DropdownMenuStyleContext = React.createContext<{
13647
13719
  radius: DropdownMenuRadius
13648
13720
  flush: boolean
13649
13721
  size: DropdownMenuSize
13650
- }>({ radius: 'lg', flush: false, size: 'md' })
13722
+ }>({ radius: 'md', flush: false, size: 'md' })
13651
13723
 
13652
13724
  // Root \u2014 state management (controlled / uncontrolled)
13653
13725
  const DropdownMenu = DropdownMenuPrimitive.Root
@@ -21837,7 +21909,7 @@ function showCompanionHints(names) {
21837
21909
 
21838
21910
  // cli/src/index.ts
21839
21911
  var import_picocolors4 = __toESM(require_picocolors());
21840
- var VERSION = "0.1.20";
21912
+ var VERSION = "0.1.22";
21841
21913
  var HELP = `
21842
21914
  ${import_picocolors4.default.bold("7onic")} \u2014 Add 7onic design system components to your project
21843
21915
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "7onic",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "CLI for adding 7onic design system components to your project",
5
5
  "bin": {
6
6
  "7onic": "./dist/index.js"