@brycks/core-front 0.3.1 → 0.3.2

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 (109) hide show
  1. package/dist/components/data/List/List.cjs +1 -1
  2. package/dist/components/data/List/List.cjs.map +1 -1
  3. package/dist/components/data/List/List.js +92 -88
  4. package/dist/components/data/List/List.js.map +1 -1
  5. package/dist/components/data/Table/Table.cjs +1 -1
  6. package/dist/components/data/Table/Table.cjs.map +1 -1
  7. package/dist/components/data/Table/Table.js +129 -125
  8. package/dist/components/data/Table/Table.js.map +1 -1
  9. package/dist/components/data/TreeView/TreeView.cjs +2 -0
  10. package/dist/components/data/TreeView/TreeView.cjs.map +1 -0
  11. package/dist/components/data/TreeView/TreeView.js +256 -0
  12. package/dist/components/data/TreeView/TreeView.js.map +1 -0
  13. package/dist/components/data/VirtualList/VirtualList.cjs +2 -0
  14. package/dist/components/data/VirtualList/VirtualList.cjs.map +1 -0
  15. package/dist/components/data/VirtualList/VirtualList.js +186 -0
  16. package/dist/components/data/VirtualList/VirtualList.js.map +1 -0
  17. package/dist/components/data.cjs +1 -1
  18. package/dist/components/data.js +21 -16
  19. package/dist/components/data.js.map +1 -1
  20. package/dist/components/feedback/Modal/Modal.cjs +1 -1
  21. package/dist/components/feedback/Modal/Modal.cjs.map +1 -1
  22. package/dist/components/feedback/Modal/Modal.js +81 -77
  23. package/dist/components/feedback/Modal/Modal.js.map +1 -1
  24. package/dist/components/form/Combobox/Combobox.cjs +7 -0
  25. package/dist/components/form/Combobox/Combobox.cjs.map +1 -0
  26. package/dist/components/form/Combobox/Combobox.js +338 -0
  27. package/dist/components/form/Combobox/Combobox.js.map +1 -0
  28. package/dist/components/form/DateRangePicker/DateRangePicker.cjs +2 -0
  29. package/dist/components/form/DateRangePicker/DateRangePicker.cjs.map +1 -0
  30. package/dist/components/form/DateRangePicker/DateRangePicker.js +372 -0
  31. package/dist/components/form/DateRangePicker/DateRangePicker.js.map +1 -0
  32. package/dist/components/form/MultiSelect/MultiSelect.cjs +2 -0
  33. package/dist/components/form/MultiSelect/MultiSelect.cjs.map +1 -0
  34. package/dist/components/form/MultiSelect/MultiSelect.js +393 -0
  35. package/dist/components/form/MultiSelect/MultiSelect.js.map +1 -0
  36. package/dist/components/form/Rating/Rating.cjs +2 -0
  37. package/dist/components/form/Rating/Rating.cjs.map +1 -0
  38. package/dist/components/form/Rating/Rating.js +163 -0
  39. package/dist/components/form/Rating/Rating.js.map +1 -0
  40. package/dist/components/form/Slider/Slider.cjs +1 -1
  41. package/dist/components/form/Slider/Slider.cjs.map +1 -1
  42. package/dist/components/form/Slider/Slider.js +120 -85
  43. package/dist/components/form/Slider/Slider.js.map +1 -1
  44. package/dist/components/form/TagInput/TagInput.cjs +2 -0
  45. package/dist/components/form/TagInput/TagInput.cjs.map +1 -0
  46. package/dist/components/form/TagInput/TagInput.js +286 -0
  47. package/dist/components/form/TagInput/TagInput.js.map +1 -0
  48. package/dist/components/form/TimePicker/TimePicker.cjs +2 -0
  49. package/dist/components/form/TimePicker/TimePicker.cjs.map +1 -0
  50. package/dist/components/form/TimePicker/TimePicker.js +328 -0
  51. package/dist/components/form/TimePicker/TimePicker.js.map +1 -0
  52. package/dist/components/form.cjs +1 -1
  53. package/dist/components/form.js +34 -22
  54. package/dist/components/form.js.map +1 -1
  55. package/dist/components/layout/Card/Card.cjs +1 -1
  56. package/dist/components/layout/Card/Card.cjs.map +1 -1
  57. package/dist/components/layout/Card/Card.js +62 -59
  58. package/dist/components/layout/Card/Card.js.map +1 -1
  59. package/dist/components/layout/Collapse/Collapse.cjs +2 -0
  60. package/dist/components/layout/Collapse/Collapse.cjs.map +1 -0
  61. package/dist/components/layout/Collapse/Collapse.js +140 -0
  62. package/dist/components/layout/Collapse/Collapse.js.map +1 -0
  63. package/dist/components/layout.cjs +1 -1
  64. package/dist/components/layout.js +27 -24
  65. package/dist/components/layout.js.map +1 -1
  66. package/dist/components/navigation/Breadcrumb/Breadcrumb.cjs +1 -1
  67. package/dist/components/navigation/Breadcrumb/Breadcrumb.cjs.map +1 -1
  68. package/dist/components/navigation/Breadcrumb/Breadcrumb.js +66 -62
  69. package/dist/components/navigation/Breadcrumb/Breadcrumb.js.map +1 -1
  70. package/dist/components/navigation/ContextMenu/ContextMenu.cjs +2 -0
  71. package/dist/components/navigation/ContextMenu/ContextMenu.cjs.map +1 -0
  72. package/dist/components/navigation/ContextMenu/ContextMenu.js +227 -0
  73. package/dist/components/navigation/ContextMenu/ContextMenu.js.map +1 -0
  74. package/dist/components/navigation/Dropdown/Dropdown.cjs +2 -2
  75. package/dist/components/navigation/Dropdown/Dropdown.cjs.map +1 -1
  76. package/dist/components/navigation/Dropdown/Dropdown.js +84 -80
  77. package/dist/components/navigation/Dropdown/Dropdown.js.map +1 -1
  78. package/dist/components/navigation/Menu/Menu.cjs +1 -1
  79. package/dist/components/navigation/Menu/Menu.cjs.map +1 -1
  80. package/dist/components/navigation/Menu/Menu.js +132 -94
  81. package/dist/components/navigation/Menu/Menu.js.map +1 -1
  82. package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
  83. package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
  84. package/dist/components/navigation/Pagination/Pagination.js +111 -107
  85. package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
  86. package/dist/components/navigation/Stepper/Stepper.cjs +2 -0
  87. package/dist/components/navigation/Stepper/Stepper.cjs.map +1 -0
  88. package/dist/components/navigation/Stepper/Stepper.js +187 -0
  89. package/dist/components/navigation/Stepper/Stepper.js.map +1 -0
  90. package/dist/components/navigation.cjs +1 -1
  91. package/dist/components/navigation.js +27 -21
  92. package/dist/components/navigation.js.map +1 -1
  93. package/dist/components/utility/Badge/Badge.cjs +1 -1
  94. package/dist/components/utility/Badge/Badge.cjs.map +1 -1
  95. package/dist/components/utility/Badge/Badge.js +38 -35
  96. package/dist/components/utility/Badge/Badge.js.map +1 -1
  97. package/dist/data.d.ts +116 -0
  98. package/dist/form.d.ts +316 -0
  99. package/dist/hooks/useInteractionState.cjs +2 -0
  100. package/dist/hooks/useInteractionState.cjs.map +1 -0
  101. package/dist/hooks/useInteractionState.js +67 -0
  102. package/dist/hooks/useInteractionState.js.map +1 -0
  103. package/dist/hooks.cjs +1 -1
  104. package/dist/hooks.d.ts +87 -0
  105. package/dist/hooks.js +16 -14
  106. package/dist/hooks.js.map +1 -1
  107. package/dist/layout.d.ts +44 -0
  108. package/dist/navigation.d.ts +88 -0
  109. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.cjs","sources":["../../../../src/components/navigation/Menu/Menu.tsx"],"sourcesContent":["/**\n * Menu Component\n *\n * A vertical navigation menu with support for nested items.\n * Suitable for sidebars and navigation panels.\n */\n\nimport {\n forwardRef,\n useState,\n createContext,\n useContext,\n type CSSProperties,\n type ReactNode,\n type HTMLAttributes,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type MenuSize = 'sm' | 'md' | 'lg'\n\ninterface MenuContextValue {\n size: MenuSize\n activeItem: string | null\n setActiveItem: (value: string | null) => void\n collapsed: boolean\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nfunction useMenuContext() {\n const context = useContext(MenuContext)\n if (!context) {\n throw new Error('Menu components must be used within a Menu')\n }\n return context\n}\n\nexport interface MenuProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Currently active item */\n activeItem?: string | null\n /** Callback when active item changes */\n onChange?: (value: string | null) => void\n /** Menu size */\n size?: MenuSize\n /** Whether the menu is collapsed (icons only) */\n collapsed?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Menu = forwardRef<HTMLElement, MenuProps>(function Menu(\n {\n activeItem: controlledActiveItem,\n onChange,\n size = 'md',\n collapsed = false,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n const [internalActiveItem, setInternalActiveItem] = useState<string | null>(null)\n const activeItem = controlledActiveItem !== undefined ? controlledActiveItem : internalActiveItem\n\n const setActiveItem = (value: string | null) => {\n if (controlledActiveItem === undefined) {\n setInternalActiveItem(value)\n }\n onChange?.(value)\n }\n\n const menuStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n padding: 8,\n ...style,\n }\n\n return (\n <MenuContext.Provider value={{ size, activeItem, setActiveItem, collapsed }}>\n <nav\n ref={ref}\n className={cx('brycks-menu', `brycks-menu--${size}`, collapsed && 'brycks-menu--collapsed', className)}\n style={menuStyle}\n data-testid={testId}\n {...props}\n >\n {children}\n </nav>\n </MenuContext.Provider>\n )\n})\n\nMenu.displayName = 'Menu'\n\n// MenuItem\nexport interface MenuItemProps extends Omit<HTMLAttributes<HTMLButtonElement>, 'onClick'> {\n /** Item value (unique identifier) */\n value: string\n /** Icon before the label */\n icon?: ReactNode\n /** Badge/count after the label */\n badge?: ReactNode\n /** Whether the item is disabled */\n disabled?: boolean\n /** Callback when clicked */\n onClick?: (value: string) => void\n /** Custom class name */\n className?: string\n}\n\nconst sizeConfig: Record<MenuSize, { height: number; fontSize: number; iconSize: number; padding: number }> = {\n sm: { height: 32, fontSize: 13, iconSize: 16, padding: 10 },\n md: { height: 40, fontSize: 14, iconSize: 18, padding: 12 },\n lg: { height: 48, fontSize: 16, iconSize: 20, padding: 14 },\n}\n\nexport const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(function MenuItem(\n { value, icon, badge, disabled = false, onClick, className, style, children, ...props },\n ref\n) {\n const { size, activeItem, setActiveItem, collapsed } = useMenuContext()\n const isActive = activeItem === value\n const config = sizeConfig[size]\n\n const handleClick = () => {\n if (disabled) return\n setActiveItem(value)\n onClick?.(value)\n }\n\n const itemStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n width: '100%',\n minHeight: config.height,\n padding: collapsed ? config.padding : `0 ${config.padding}px`,\n fontSize: config.fontSize,\n fontWeight: isActive ? 600 : 500,\n color: disabled\n ? 'var(--brycks-foreground-disabled)'\n : isActive\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-primary-50)' : 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n transition: 'all 150ms ease-out',\n textAlign: 'left',\n outline: 'none',\n justifyContent: collapsed ? 'center' : 'flex-start',\n ...style,\n }\n\n const iconStyle: CSSProperties = {\n width: config.iconSize,\n height: config.iconSize,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }\n\n const badgeStyle: CSSProperties = {\n marginLeft: 'auto',\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n disabled={disabled}\n className={cx('brycks-menu-item', isActive && 'brycks-menu-item--active', className)}\n style={itemStyle}\n onClick={handleClick}\n onMouseEnter={(e) => {\n if (!disabled && !isActive) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n title={collapsed ? String(children) : undefined}\n {...props}\n >\n {icon && <span style={iconStyle}>{icon}</span>}\n {!collapsed && <span style={{ flex: 1 }}>{children}</span>}\n {!collapsed && badge && <span style={badgeStyle}>{badge}</span>}\n </button>\n )\n})\n\nMenuItem.displayName = 'MenuItem'\n\n// MenuGroup\nexport interface MenuGroupProps extends HTMLAttributes<HTMLDivElement> {\n /** Group label */\n label?: string\n /** Custom class name */\n className?: string\n}\n\nexport const MenuGroup = forwardRef<HTMLDivElement, MenuGroupProps>(function MenuGroup(\n { label, className, style, children, ...props },\n ref\n) {\n const { collapsed } = useMenuContext()\n\n const groupStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n padding: '12px 12px 6px 12px',\n fontSize: 11,\n fontWeight: 600,\n color: 'var(--brycks-foreground-muted)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }\n\n return (\n <div ref={ref} className={cx('brycks-menu-group', className)} style={groupStyle} {...props}>\n {label && !collapsed && <div style={labelStyle}>{label}</div>}\n {children}\n </div>\n )\n})\n\nMenuGroup.displayName = 'MenuGroup'\n\n// MenuDivider\nexport interface MenuDividerProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const MenuDivider = forwardRef<HTMLDivElement, MenuDividerProps>(function MenuDivider(\n { className, style, ...props },\n ref\n) {\n const dividerStyle: CSSProperties = {\n height: 1,\n backgroundColor: 'var(--brycks-border-muted)',\n margin: '8px 0',\n ...style,\n }\n\n return (\n <div\n ref={ref}\n role=\"separator\"\n className={cx('brycks-menu-divider', className)}\n style={dividerStyle}\n {...props}\n />\n )\n})\n\nMenuDivider.displayName = 'MenuDivider'\n"],"names":["MenuContext","createContext","useMenuContext","context","useContext","Menu","forwardRef","controlledActiveItem","onChange","size","collapsed","className","style","children","testId","props","ref","internalActiveItem","setInternalActiveItem","useState","activeItem","setActiveItem","value","menuStyle","jsx","cx","sizeConfig","MenuItem","icon","badge","disabled","onClick","isActive","config","handleClick","itemStyle","iconStyle","badgeStyle","jsxs","e","MenuGroup","label","groupStyle","labelStyle","MenuDivider","dividerStyle"],"mappings":"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"}
1
+ {"version":3,"file":"Menu.cjs","sources":["../../../../src/components/navigation/Menu/Menu.tsx"],"sourcesContent":["/**\n * Menu Component\n *\n * A vertical navigation menu with support for nested items.\n * Suitable for sidebars and navigation panels.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n createContext,\n useContext,\n type CSSProperties,\n type ReactNode,\n type HTMLAttributes,\n type KeyboardEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentHeights, componentGap, componentPaddingX, componentPaddingY, iconSizes } from '../../../design-system/primitives'\n\nexport type MenuSize = 'sm' | 'md' | 'lg'\n\ninterface MenuContextValue {\n size: MenuSize\n activeItem: string | null\n setActiveItem: (value: string | null) => void\n collapsed: boolean\n focusedIndex: number\n setFocusedIndex: (index: number) => void\n registerItem: (value: string) => number\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nfunction useMenuContext() {\n const context = useContext(MenuContext)\n if (!context) {\n throw new Error('Menu components must be used within a Menu')\n }\n return context\n}\n\nexport interface MenuProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Currently active item */\n activeItem?: string | null\n /** Callback when active item changes */\n onChange?: (value: string | null) => void\n /** Menu size */\n size?: MenuSize\n /** Whether the menu is collapsed (icons only) */\n collapsed?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Menu = forwardRef<HTMLElement, MenuProps>(function Menu(\n {\n activeItem: controlledActiveItem,\n onChange,\n size = 'md',\n collapsed = false,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n const [internalActiveItem, setInternalActiveItem] = useState<string | null>(null)\n const [focusedIndex, setFocusedIndex] = useState(-1)\n const itemsRef = useRef<string[]>([])\n const menuRef = useRef<HTMLElement>(null)\n const activeItem = controlledActiveItem !== undefined ? controlledActiveItem : internalActiveItem\n\n const setActiveItem = (value: string | null) => {\n if (controlledActiveItem === undefined) {\n setInternalActiveItem(value)\n }\n onChange?.(value)\n }\n\n // Register items for keyboard navigation\n const registerItem = useCallback((value: string) => {\n const index = itemsRef.current.indexOf(value)\n if (index === -1) {\n itemsRef.current.push(value)\n return itemsRef.current.length - 1\n }\n return index\n }, [])\n\n // Keyboard navigation\n const handleKeyDown = useCallback((e: KeyboardEvent<HTMLElement>) => {\n const items = menuRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"menuitem\"]:not(:disabled)')\n if (!items?.length) return\n\n const currentIndex = focusedIndex >= 0 ? focusedIndex : 0\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n const nextIndex = (currentIndex + 1) % items.length\n setFocusedIndex(nextIndex)\n items[nextIndex]?.focus()\n break\n case 'ArrowUp':\n e.preventDefault()\n const prevIndex = (currentIndex - 1 + items.length) % items.length\n setFocusedIndex(prevIndex)\n items[prevIndex]?.focus()\n break\n case 'Home':\n e.preventDefault()\n setFocusedIndex(0)\n items[0]?.focus()\n break\n case 'End':\n e.preventDefault()\n setFocusedIndex(items.length - 1)\n items[items.length - 1]?.focus()\n break\n }\n }, [focusedIndex])\n\n const menuStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: spacing[0.5],\n padding: spacing[2],\n ...style,\n }\n\n return (\n <MenuContext.Provider value={{ size, activeItem, setActiveItem, collapsed, focusedIndex, setFocusedIndex, registerItem }}>\n <nav\n ref={(node) => {\n (menuRef as React.MutableRefObject<HTMLElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLElement | null>).current = node\n }}\n role=\"menu\"\n className={cx('brycks-menu', `brycks-menu--${size}`, collapsed && 'brycks-menu--collapsed', className)}\n style={menuStyle}\n onKeyDown={handleKeyDown}\n data-testid={testId}\n {...props}\n >\n {children}\n </nav>\n </MenuContext.Provider>\n )\n})\n\nMenu.displayName = 'Menu'\n\n// MenuItem\nexport interface MenuItemProps extends Omit<HTMLAttributes<HTMLButtonElement>, 'onClick'> {\n /** Item value (unique identifier) */\n value: string\n /** Icon before the label */\n icon?: ReactNode\n /** Badge/count after the label */\n badge?: ReactNode\n /** Whether the item is disabled */\n disabled?: boolean\n /** Callback when clicked */\n onClick?: (value: string) => void\n /** Custom class name */\n className?: string\n}\n\nconst sizeConfig: Record<MenuSize, { height: number; fontSize: number; iconSize: number; padding: number }> = {\n sm: { height: componentHeights.sm, fontSize: fontSizes.base - 1, iconSize: iconSizes.sm, padding: componentGap.lg },\n md: { height: componentHeights.md, fontSize: fontSizes.base, iconSize: iconSizes.md - 2, padding: componentPaddingX.sm },\n lg: { height: componentHeights.lg, fontSize: fontSizes.md, iconSize: iconSizes.md, padding: spacing[3.5] },\n}\n\nexport const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(function MenuItem(\n { value, icon, badge, disabled = false, onClick, className, style, children, ...props },\n ref\n) {\n const { size, activeItem, setActiveItem, collapsed, focusedIndex, setFocusedIndex, registerItem } = useMenuContext()\n const isActive = activeItem === value\n const config = sizeConfig[size]\n const itemIndex = registerItem(value)\n\n const handleClick = () => {\n if (disabled) return\n setActiveItem(value)\n onClick?.(value)\n }\n\n const handleFocus = () => {\n setFocusedIndex(itemIndex)\n }\n\n const itemStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: componentGap.lg,\n width: '100%',\n minHeight: config.height,\n padding: collapsed ? config.padding : `0 ${config.padding}px`,\n fontSize: config.fontSize,\n fontWeight: isActive ? 600 : 500,\n color: disabled\n ? 'var(--brycks-foreground-disabled)'\n : isActive\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-primary-50)' : 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n transition: `all ${durations.quick}ms ${easings.easeOut}`,\n textAlign: 'left',\n outline: 'none',\n justifyContent: collapsed ? 'center' : 'flex-start',\n ...style,\n }\n\n const iconStyle: CSSProperties = {\n width: config.iconSize,\n height: config.iconSize,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }\n\n const badgeStyle: CSSProperties = {\n marginLeft: 'auto',\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n tabIndex={focusedIndex === itemIndex ? 0 : -1}\n className={cx('brycks-menu-item', isActive && 'brycks-menu-item--active', className)}\n style={itemStyle}\n onClick={handleClick}\n onFocus={handleFocus}\n onMouseEnter={(e) => {\n if (!disabled && !isActive) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n title={collapsed ? String(children) : undefined}\n {...props}\n >\n {icon && <span style={iconStyle}>{icon}</span>}\n {!collapsed && <span style={{ flex: 1 }}>{children}</span>}\n {!collapsed && badge && <span style={badgeStyle}>{badge}</span>}\n </button>\n )\n})\n\nMenuItem.displayName = 'MenuItem'\n\n// MenuGroup\nexport interface MenuGroupProps extends HTMLAttributes<HTMLDivElement> {\n /** Group label */\n label?: string\n /** Custom class name */\n className?: string\n}\n\nexport const MenuGroup = forwardRef<HTMLDivElement, MenuGroupProps>(function MenuGroup(\n { label, className, style, children, ...props },\n ref\n) {\n const { collapsed } = useMenuContext()\n\n const groupStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: spacing[0.5],\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n padding: `${spacing[3]}px ${spacing[3]}px ${componentPaddingY.sm}px ${spacing[3]}px`,\n fontSize: fontSizes.xs,\n fontWeight: 600,\n color: 'var(--brycks-foreground-muted)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }\n\n return (\n <div ref={ref} className={cx('brycks-menu-group', className)} style={groupStyle} {...props}>\n {label && !collapsed && <div style={labelStyle}>{label}</div>}\n {children}\n </div>\n )\n})\n\nMenuGroup.displayName = 'MenuGroup'\n\n// MenuDivider\nexport interface MenuDividerProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const MenuDivider = forwardRef<HTMLDivElement, MenuDividerProps>(function MenuDivider(\n { className, style, ...props },\n ref\n) {\n const dividerStyle: CSSProperties = {\n height: 1,\n backgroundColor: 'var(--brycks-border-muted)',\n margin: `${spacing[2]}px 0`,\n ...style,\n }\n\n return (\n <div\n ref={ref}\n role=\"separator\"\n className={cx('brycks-menu-divider', className)}\n style={dividerStyle}\n {...props}\n />\n )\n})\n\nMenuDivider.displayName = 'MenuDivider'\n"],"names":["MenuContext","createContext","useMenuContext","context","useContext","Menu","forwardRef","controlledActiveItem","onChange","size","collapsed","className","style","children","testId","props","ref","internalActiveItem","setInternalActiveItem","useState","focusedIndex","setFocusedIndex","itemsRef","useRef","menuRef","activeItem","setActiveItem","value","registerItem","useCallback","index","handleKeyDown","items","currentIndex","nextIndex","prevIndex","menuStyle","spacing","jsx","node","cx","sizeConfig","componentHeights","fontSizes","iconSizes","componentGap","componentPaddingX","MenuItem","icon","badge","disabled","onClick","isActive","config","itemIndex","handleClick","handleFocus","itemStyle","durations","easings","iconStyle","badgeStyle","jsxs","e","MenuGroup","label","groupStyle","labelStyle","componentPaddingY","MenuDivider","dividerStyle"],"mappings":"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"}
@@ -1,151 +1,189 @@
1
- import { jsx as a, jsxs as k } from "react/jsx-runtime";
2
- import { forwardRef as f, useState as w, createContext as D, useContext as j } from "react";
3
- import { cx as y } from "../../../utils/styles.js";
4
- const S = D(null);
5
- function M() {
6
- const u = j(S);
7
- if (!u)
1
+ import { jsx as d, jsxs as H } from "react/jsx-runtime";
2
+ import { forwardRef as C, useState as F, useRef as G, useCallback as E, createContext as K, useContext as L } from "react";
3
+ import { cx as w } from "../../../utils/styles.js";
4
+ import { spacing as u } from "../../../design-system/tokens/spacing.js";
5
+ import { durations as O, easings as W } from "../../../design-system/tokens/motion.js";
6
+ import { iconSizes as R, componentHeights as j, componentPaddingX as U, componentGap as P, componentPaddingY as X } from "../../../design-system/primitives/sizing.js";
7
+ import { fontSizes as z } from "../../../design-system/tokens/typography.js";
8
+ const T = K(null);
9
+ function q() {
10
+ const m = L(T);
11
+ if (!m)
8
12
  throw new Error("Menu components must be used within a Menu");
9
- return u;
13
+ return m;
10
14
  }
11
- const A = f(function({
12
- activeItem: e,
15
+ const Y = C(function({
16
+ activeItem: n,
13
17
  onChange: i,
14
- size: n = "md",
15
- collapsed: t = !1,
16
- className: s,
17
- style: d,
18
- children: m,
19
- testId: l,
20
- ...p
21
- }, g) {
22
- const [v, h] = w(null), x = e !== void 0 ? e : v, c = (r) => {
23
- e === void 0 && h(r), i?.(r);
24
- }, o = {
18
+ size: s = "md",
19
+ collapsed: r = !1,
20
+ className: l,
21
+ style: x,
22
+ children: h,
23
+ testId: f,
24
+ ...b
25
+ }, p) {
26
+ const [D, $] = F(null), [g, o] = F(-1), k = G([]), v = G(null), N = n !== void 0 ? n : D, c = (e) => {
27
+ n === void 0 && $(e), i?.(e);
28
+ }, a = E((e) => {
29
+ const t = k.current.indexOf(e);
30
+ return t === -1 ? (k.current.push(e), k.current.length - 1) : t;
31
+ }, []), S = E((e) => {
32
+ const t = v.current?.querySelectorAll('[role="menuitem"]:not(:disabled)');
33
+ if (!t?.length) return;
34
+ const I = g >= 0 ? g : 0;
35
+ switch (e.key) {
36
+ case "ArrowDown":
37
+ e.preventDefault();
38
+ const M = (I + 1) % t.length;
39
+ o(M), t[M]?.focus();
40
+ break;
41
+ case "ArrowUp":
42
+ e.preventDefault();
43
+ const y = (I - 1 + t.length) % t.length;
44
+ o(y), t[y]?.focus();
45
+ break;
46
+ case "Home":
47
+ e.preventDefault(), o(0), t[0]?.focus();
48
+ break;
49
+ case "End":
50
+ e.preventDefault(), o(t.length - 1), t[t.length - 1]?.focus();
51
+ break;
52
+ }
53
+ }, [g]), A = {
25
54
  display: "flex",
26
55
  flexDirection: "column",
27
- gap: 2,
28
- padding: 8,
29
- ...d
56
+ gap: u[0.5],
57
+ padding: u[2],
58
+ ...x
30
59
  };
31
- return /* @__PURE__ */ a(S.Provider, { value: { size: n, activeItem: x, setActiveItem: c, collapsed: t }, children: /* @__PURE__ */ a(
60
+ return /* @__PURE__ */ d(T.Provider, { value: { size: s, activeItem: N, setActiveItem: c, collapsed: r, focusedIndex: g, setFocusedIndex: o, registerItem: a }, children: /* @__PURE__ */ d(
32
61
  "nav",
33
62
  {
34
- ref: g,
35
- className: y("brycks-menu", `brycks-menu--${n}`, t && "brycks-menu--collapsed", s),
36
- style: o,
37
- "data-testid": l,
38
- ...p,
39
- children: m
63
+ ref: (e) => {
64
+ v.current = e, typeof p == "function" ? p(e) : p && (p.current = e);
65
+ },
66
+ role: "menu",
67
+ className: w("brycks-menu", `brycks-menu--${s}`, r && "brycks-menu--collapsed", l),
68
+ style: A,
69
+ onKeyDown: S,
70
+ "data-testid": f,
71
+ ...b,
72
+ children: h
40
73
  }
41
74
  ) });
42
75
  });
43
- A.displayName = "Menu";
44
- const G = {
45
- sm: { height: 32, fontSize: 13, iconSize: 16, padding: 10 },
46
- md: { height: 40, fontSize: 14, iconSize: 18, padding: 12 },
47
- lg: { height: 48, fontSize: 16, iconSize: 20, padding: 14 }
48
- }, T = f(function({ value: e, icon: i, badge: n, disabled: t = !1, onClick: s, className: d, style: m, children: l, ...p }, g) {
49
- const { size: v, activeItem: h, setActiveItem: x, collapsed: c } = M(), o = h === e, r = G[v], C = () => {
50
- t || (x(e), s?.(e));
51
- }, z = {
76
+ Y.displayName = "Menu";
77
+ const B = {
78
+ sm: { height: j.sm, fontSize: z.base - 1, iconSize: R.sm, padding: P.lg },
79
+ md: { height: j.md, fontSize: z.base, iconSize: R.md - 2, padding: U.sm },
80
+ lg: { height: j.lg, fontSize: z.md, iconSize: R.md, padding: u[3.5] }
81
+ }, J = C(function({ value: n, icon: i, badge: s, disabled: r = !1, onClick: l, className: x, style: h, children: f, ...b }, p) {
82
+ const { size: D, activeItem: $, setActiveItem: g, collapsed: o, focusedIndex: k, setFocusedIndex: v, registerItem: N } = q(), c = $ === n, a = B[D], S = N(n), A = () => {
83
+ r || (g(n), l?.(n));
84
+ }, e = () => {
85
+ v(S);
86
+ }, t = {
52
87
  display: "flex",
53
88
  alignItems: "center",
54
- gap: 10,
89
+ gap: P.lg,
55
90
  width: "100%",
56
- minHeight: r.height,
57
- padding: c ? r.padding : `0 ${r.padding}px`,
58
- fontSize: r.fontSize,
59
- fontWeight: o ? 600 : 500,
60
- color: t ? "var(--brycks-foreground-disabled)" : o ? "var(--brycks-primary-default)" : "var(--brycks-foreground-default)",
61
- backgroundColor: o ? "var(--brycks-primary-50)" : "transparent",
91
+ minHeight: a.height,
92
+ padding: o ? a.padding : `0 ${a.padding}px`,
93
+ fontSize: a.fontSize,
94
+ fontWeight: c ? 600 : 500,
95
+ color: r ? "var(--brycks-foreground-disabled)" : c ? "var(--brycks-primary-default)" : "var(--brycks-foreground-default)",
96
+ backgroundColor: c ? "var(--brycks-primary-50)" : "transparent",
62
97
  border: "none",
63
98
  borderRadius: "var(--brycks-radius-md)",
64
- cursor: t ? "not-allowed" : "pointer",
65
- transition: "all 150ms ease-out",
99
+ cursor: r ? "not-allowed" : "pointer",
100
+ transition: `all ${O.quick}ms ${W.easeOut}`,
66
101
  textAlign: "left",
67
102
  outline: "none",
68
- justifyContent: c ? "center" : "flex-start",
69
- ...m
103
+ justifyContent: o ? "center" : "flex-start",
104
+ ...h
70
105
  }, I = {
71
- width: r.iconSize,
72
- height: r.iconSize,
106
+ width: a.iconSize,
107
+ height: a.iconSize,
73
108
  flexShrink: 0,
74
109
  display: "flex",
75
110
  alignItems: "center",
76
111
  justifyContent: "center"
77
- }, N = {
112
+ }, M = {
78
113
  marginLeft: "auto"
79
114
  };
80
- return /* @__PURE__ */ k(
115
+ return /* @__PURE__ */ H(
81
116
  "button",
82
117
  {
83
- ref: g,
118
+ ref: p,
84
119
  type: "button",
85
- disabled: t,
86
- className: y("brycks-menu-item", o && "brycks-menu-item--active", d),
87
- style: z,
88
- onClick: C,
89
- onMouseEnter: (b) => {
90
- !t && !o && (b.currentTarget.style.backgroundColor = "var(--brycks-background-muted)");
120
+ role: "menuitem",
121
+ disabled: r,
122
+ tabIndex: k === S ? 0 : -1,
123
+ className: w("brycks-menu-item", c && "brycks-menu-item--active", x),
124
+ style: t,
125
+ onClick: A,
126
+ onFocus: e,
127
+ onMouseEnter: (y) => {
128
+ !r && !c && (y.currentTarget.style.backgroundColor = "var(--brycks-background-muted)");
91
129
  },
92
- onMouseLeave: (b) => {
93
- o || (b.currentTarget.style.backgroundColor = "transparent");
130
+ onMouseLeave: (y) => {
131
+ c || (y.currentTarget.style.backgroundColor = "transparent");
94
132
  },
95
- title: c ? String(l) : void 0,
96
- ...p,
133
+ title: o ? String(f) : void 0,
134
+ ...b,
97
135
  children: [
98
- i && /* @__PURE__ */ a("span", { style: I, children: i }),
99
- !c && /* @__PURE__ */ a("span", { style: { flex: 1 }, children: l }),
100
- !c && n && /* @__PURE__ */ a("span", { style: N, children: n })
136
+ i && /* @__PURE__ */ d("span", { style: I, children: i }),
137
+ !o && /* @__PURE__ */ d("span", { style: { flex: 1 }, children: f }),
138
+ !o && s && /* @__PURE__ */ d("span", { style: M, children: s })
101
139
  ]
102
140
  }
103
141
  );
104
142
  });
105
- T.displayName = "MenuItem";
106
- const E = f(function({ label: e, className: i, style: n, children: t, ...s }, d) {
107
- const { collapsed: m } = M(), l = {
143
+ J.displayName = "MenuItem";
144
+ const Q = C(function({ label: n, className: i, style: s, children: r, ...l }, x) {
145
+ const { collapsed: h } = q(), f = {
108
146
  display: "flex",
109
147
  flexDirection: "column",
110
- gap: 2,
111
- ...n
112
- }, p = {
113
- padding: "12px 12px 6px 12px",
114
- fontSize: 11,
148
+ gap: u[0.5],
149
+ ...s
150
+ }, b = {
151
+ padding: `${u[3]}px ${u[3]}px ${X.sm}px ${u[3]}px`,
152
+ fontSize: z.xs,
115
153
  fontWeight: 600,
116
154
  color: "var(--brycks-foreground-muted)",
117
155
  textTransform: "uppercase",
118
156
  letterSpacing: "0.05em"
119
157
  };
120
- return /* @__PURE__ */ k("div", { ref: d, className: y("brycks-menu-group", i), style: l, ...s, children: [
121
- e && !m && /* @__PURE__ */ a("div", { style: p, children: e }),
122
- t
158
+ return /* @__PURE__ */ H("div", { ref: x, className: w("brycks-menu-group", i), style: f, ...l, children: [
159
+ n && !h && /* @__PURE__ */ d("div", { style: b, children: n }),
160
+ r
123
161
  ] });
124
162
  });
125
- E.displayName = "MenuGroup";
126
- const L = f(function({ className: e, style: i, ...n }, t) {
127
- const s = {
163
+ Q.displayName = "MenuGroup";
164
+ const V = C(function({ className: n, style: i, ...s }, r) {
165
+ const l = {
128
166
  height: 1,
129
167
  backgroundColor: "var(--brycks-border-muted)",
130
- margin: "8px 0",
168
+ margin: `${u[2]}px 0`,
131
169
  ...i
132
170
  };
133
- return /* @__PURE__ */ a(
171
+ return /* @__PURE__ */ d(
134
172
  "div",
135
173
  {
136
- ref: t,
174
+ ref: r,
137
175
  role: "separator",
138
- className: y("brycks-menu-divider", e),
139
- style: s,
140
- ...n
176
+ className: w("brycks-menu-divider", n),
177
+ style: l,
178
+ ...s
141
179
  }
142
180
  );
143
181
  });
144
- L.displayName = "MenuDivider";
182
+ V.displayName = "MenuDivider";
145
183
  export {
146
- A as Menu,
147
- L as MenuDivider,
148
- E as MenuGroup,
149
- T as MenuItem
184
+ Y as Menu,
185
+ V as MenuDivider,
186
+ Q as MenuGroup,
187
+ J as MenuItem
150
188
  };
151
189
  //# sourceMappingURL=Menu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.js","sources":["../../../../src/components/navigation/Menu/Menu.tsx"],"sourcesContent":["/**\n * Menu Component\n *\n * A vertical navigation menu with support for nested items.\n * Suitable for sidebars and navigation panels.\n */\n\nimport {\n forwardRef,\n useState,\n createContext,\n useContext,\n type CSSProperties,\n type ReactNode,\n type HTMLAttributes,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type MenuSize = 'sm' | 'md' | 'lg'\n\ninterface MenuContextValue {\n size: MenuSize\n activeItem: string | null\n setActiveItem: (value: string | null) => void\n collapsed: boolean\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nfunction useMenuContext() {\n const context = useContext(MenuContext)\n if (!context) {\n throw new Error('Menu components must be used within a Menu')\n }\n return context\n}\n\nexport interface MenuProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Currently active item */\n activeItem?: string | null\n /** Callback when active item changes */\n onChange?: (value: string | null) => void\n /** Menu size */\n size?: MenuSize\n /** Whether the menu is collapsed (icons only) */\n collapsed?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Menu = forwardRef<HTMLElement, MenuProps>(function Menu(\n {\n activeItem: controlledActiveItem,\n onChange,\n size = 'md',\n collapsed = false,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n const [internalActiveItem, setInternalActiveItem] = useState<string | null>(null)\n const activeItem = controlledActiveItem !== undefined ? controlledActiveItem : internalActiveItem\n\n const setActiveItem = (value: string | null) => {\n if (controlledActiveItem === undefined) {\n setInternalActiveItem(value)\n }\n onChange?.(value)\n }\n\n const menuStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n padding: 8,\n ...style,\n }\n\n return (\n <MenuContext.Provider value={{ size, activeItem, setActiveItem, collapsed }}>\n <nav\n ref={ref}\n className={cx('brycks-menu', `brycks-menu--${size}`, collapsed && 'brycks-menu--collapsed', className)}\n style={menuStyle}\n data-testid={testId}\n {...props}\n >\n {children}\n </nav>\n </MenuContext.Provider>\n )\n})\n\nMenu.displayName = 'Menu'\n\n// MenuItem\nexport interface MenuItemProps extends Omit<HTMLAttributes<HTMLButtonElement>, 'onClick'> {\n /** Item value (unique identifier) */\n value: string\n /** Icon before the label */\n icon?: ReactNode\n /** Badge/count after the label */\n badge?: ReactNode\n /** Whether the item is disabled */\n disabled?: boolean\n /** Callback when clicked */\n onClick?: (value: string) => void\n /** Custom class name */\n className?: string\n}\n\nconst sizeConfig: Record<MenuSize, { height: number; fontSize: number; iconSize: number; padding: number }> = {\n sm: { height: 32, fontSize: 13, iconSize: 16, padding: 10 },\n md: { height: 40, fontSize: 14, iconSize: 18, padding: 12 },\n lg: { height: 48, fontSize: 16, iconSize: 20, padding: 14 },\n}\n\nexport const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(function MenuItem(\n { value, icon, badge, disabled = false, onClick, className, style, children, ...props },\n ref\n) {\n const { size, activeItem, setActiveItem, collapsed } = useMenuContext()\n const isActive = activeItem === value\n const config = sizeConfig[size]\n\n const handleClick = () => {\n if (disabled) return\n setActiveItem(value)\n onClick?.(value)\n }\n\n const itemStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n width: '100%',\n minHeight: config.height,\n padding: collapsed ? config.padding : `0 ${config.padding}px`,\n fontSize: config.fontSize,\n fontWeight: isActive ? 600 : 500,\n color: disabled\n ? 'var(--brycks-foreground-disabled)'\n : isActive\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-primary-50)' : 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n transition: 'all 150ms ease-out',\n textAlign: 'left',\n outline: 'none',\n justifyContent: collapsed ? 'center' : 'flex-start',\n ...style,\n }\n\n const iconStyle: CSSProperties = {\n width: config.iconSize,\n height: config.iconSize,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }\n\n const badgeStyle: CSSProperties = {\n marginLeft: 'auto',\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n disabled={disabled}\n className={cx('brycks-menu-item', isActive && 'brycks-menu-item--active', className)}\n style={itemStyle}\n onClick={handleClick}\n onMouseEnter={(e) => {\n if (!disabled && !isActive) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n title={collapsed ? String(children) : undefined}\n {...props}\n >\n {icon && <span style={iconStyle}>{icon}</span>}\n {!collapsed && <span style={{ flex: 1 }}>{children}</span>}\n {!collapsed && badge && <span style={badgeStyle}>{badge}</span>}\n </button>\n )\n})\n\nMenuItem.displayName = 'MenuItem'\n\n// MenuGroup\nexport interface MenuGroupProps extends HTMLAttributes<HTMLDivElement> {\n /** Group label */\n label?: string\n /** Custom class name */\n className?: string\n}\n\nexport const MenuGroup = forwardRef<HTMLDivElement, MenuGroupProps>(function MenuGroup(\n { label, className, style, children, ...props },\n ref\n) {\n const { collapsed } = useMenuContext()\n\n const groupStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n padding: '12px 12px 6px 12px',\n fontSize: 11,\n fontWeight: 600,\n color: 'var(--brycks-foreground-muted)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }\n\n return (\n <div ref={ref} className={cx('brycks-menu-group', className)} style={groupStyle} {...props}>\n {label && !collapsed && <div style={labelStyle}>{label}</div>}\n {children}\n </div>\n )\n})\n\nMenuGroup.displayName = 'MenuGroup'\n\n// MenuDivider\nexport interface MenuDividerProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const MenuDivider = forwardRef<HTMLDivElement, MenuDividerProps>(function MenuDivider(\n { className, style, ...props },\n ref\n) {\n const dividerStyle: CSSProperties = {\n height: 1,\n backgroundColor: 'var(--brycks-border-muted)',\n margin: '8px 0',\n ...style,\n }\n\n return (\n <div\n ref={ref}\n role=\"separator\"\n className={cx('brycks-menu-divider', className)}\n style={dividerStyle}\n {...props}\n />\n )\n})\n\nMenuDivider.displayName = 'MenuDivider'\n"],"names":["MenuContext","createContext","useMenuContext","context","useContext","Menu","forwardRef","controlledActiveItem","onChange","size","collapsed","className","style","children","testId","props","ref","internalActiveItem","setInternalActiveItem","useState","activeItem","setActiveItem","value","menuStyle","jsx","cx","sizeConfig","MenuItem","icon","badge","disabled","onClick","isActive","config","handleClick","itemStyle","iconStyle","badgeStyle","jsxs","e","MenuGroup","label","groupStyle","labelStyle","MenuDivider","dividerStyle"],"mappings":"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"}
1
+ {"version":3,"file":"Menu.js","sources":["../../../../src/components/navigation/Menu/Menu.tsx"],"sourcesContent":["/**\n * Menu Component\n *\n * A vertical navigation menu with support for nested items.\n * Suitable for sidebars and navigation panels.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n createContext,\n useContext,\n type CSSProperties,\n type ReactNode,\n type HTMLAttributes,\n type KeyboardEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentHeights, componentGap, componentPaddingX, componentPaddingY, iconSizes } from '../../../design-system/primitives'\n\nexport type MenuSize = 'sm' | 'md' | 'lg'\n\ninterface MenuContextValue {\n size: MenuSize\n activeItem: string | null\n setActiveItem: (value: string | null) => void\n collapsed: boolean\n focusedIndex: number\n setFocusedIndex: (index: number) => void\n registerItem: (value: string) => number\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nfunction useMenuContext() {\n const context = useContext(MenuContext)\n if (!context) {\n throw new Error('Menu components must be used within a Menu')\n }\n return context\n}\n\nexport interface MenuProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Currently active item */\n activeItem?: string | null\n /** Callback when active item changes */\n onChange?: (value: string | null) => void\n /** Menu size */\n size?: MenuSize\n /** Whether the menu is collapsed (icons only) */\n collapsed?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Menu = forwardRef<HTMLElement, MenuProps>(function Menu(\n {\n activeItem: controlledActiveItem,\n onChange,\n size = 'md',\n collapsed = false,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n const [internalActiveItem, setInternalActiveItem] = useState<string | null>(null)\n const [focusedIndex, setFocusedIndex] = useState(-1)\n const itemsRef = useRef<string[]>([])\n const menuRef = useRef<HTMLElement>(null)\n const activeItem = controlledActiveItem !== undefined ? controlledActiveItem : internalActiveItem\n\n const setActiveItem = (value: string | null) => {\n if (controlledActiveItem === undefined) {\n setInternalActiveItem(value)\n }\n onChange?.(value)\n }\n\n // Register items for keyboard navigation\n const registerItem = useCallback((value: string) => {\n const index = itemsRef.current.indexOf(value)\n if (index === -1) {\n itemsRef.current.push(value)\n return itemsRef.current.length - 1\n }\n return index\n }, [])\n\n // Keyboard navigation\n const handleKeyDown = useCallback((e: KeyboardEvent<HTMLElement>) => {\n const items = menuRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"menuitem\"]:not(:disabled)')\n if (!items?.length) return\n\n const currentIndex = focusedIndex >= 0 ? focusedIndex : 0\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n const nextIndex = (currentIndex + 1) % items.length\n setFocusedIndex(nextIndex)\n items[nextIndex]?.focus()\n break\n case 'ArrowUp':\n e.preventDefault()\n const prevIndex = (currentIndex - 1 + items.length) % items.length\n setFocusedIndex(prevIndex)\n items[prevIndex]?.focus()\n break\n case 'Home':\n e.preventDefault()\n setFocusedIndex(0)\n items[0]?.focus()\n break\n case 'End':\n e.preventDefault()\n setFocusedIndex(items.length - 1)\n items[items.length - 1]?.focus()\n break\n }\n }, [focusedIndex])\n\n const menuStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: spacing[0.5],\n padding: spacing[2],\n ...style,\n }\n\n return (\n <MenuContext.Provider value={{ size, activeItem, setActiveItem, collapsed, focusedIndex, setFocusedIndex, registerItem }}>\n <nav\n ref={(node) => {\n (menuRef as React.MutableRefObject<HTMLElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLElement | null>).current = node\n }}\n role=\"menu\"\n className={cx('brycks-menu', `brycks-menu--${size}`, collapsed && 'brycks-menu--collapsed', className)}\n style={menuStyle}\n onKeyDown={handleKeyDown}\n data-testid={testId}\n {...props}\n >\n {children}\n </nav>\n </MenuContext.Provider>\n )\n})\n\nMenu.displayName = 'Menu'\n\n// MenuItem\nexport interface MenuItemProps extends Omit<HTMLAttributes<HTMLButtonElement>, 'onClick'> {\n /** Item value (unique identifier) */\n value: string\n /** Icon before the label */\n icon?: ReactNode\n /** Badge/count after the label */\n badge?: ReactNode\n /** Whether the item is disabled */\n disabled?: boolean\n /** Callback when clicked */\n onClick?: (value: string) => void\n /** Custom class name */\n className?: string\n}\n\nconst sizeConfig: Record<MenuSize, { height: number; fontSize: number; iconSize: number; padding: number }> = {\n sm: { height: componentHeights.sm, fontSize: fontSizes.base - 1, iconSize: iconSizes.sm, padding: componentGap.lg },\n md: { height: componentHeights.md, fontSize: fontSizes.base, iconSize: iconSizes.md - 2, padding: componentPaddingX.sm },\n lg: { height: componentHeights.lg, fontSize: fontSizes.md, iconSize: iconSizes.md, padding: spacing[3.5] },\n}\n\nexport const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(function MenuItem(\n { value, icon, badge, disabled = false, onClick, className, style, children, ...props },\n ref\n) {\n const { size, activeItem, setActiveItem, collapsed, focusedIndex, setFocusedIndex, registerItem } = useMenuContext()\n const isActive = activeItem === value\n const config = sizeConfig[size]\n const itemIndex = registerItem(value)\n\n const handleClick = () => {\n if (disabled) return\n setActiveItem(value)\n onClick?.(value)\n }\n\n const handleFocus = () => {\n setFocusedIndex(itemIndex)\n }\n\n const itemStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: componentGap.lg,\n width: '100%',\n minHeight: config.height,\n padding: collapsed ? config.padding : `0 ${config.padding}px`,\n fontSize: config.fontSize,\n fontWeight: isActive ? 600 : 500,\n color: disabled\n ? 'var(--brycks-foreground-disabled)'\n : isActive\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-primary-50)' : 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n transition: `all ${durations.quick}ms ${easings.easeOut}`,\n textAlign: 'left',\n outline: 'none',\n justifyContent: collapsed ? 'center' : 'flex-start',\n ...style,\n }\n\n const iconStyle: CSSProperties = {\n width: config.iconSize,\n height: config.iconSize,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }\n\n const badgeStyle: CSSProperties = {\n marginLeft: 'auto',\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n tabIndex={focusedIndex === itemIndex ? 0 : -1}\n className={cx('brycks-menu-item', isActive && 'brycks-menu-item--active', className)}\n style={itemStyle}\n onClick={handleClick}\n onFocus={handleFocus}\n onMouseEnter={(e) => {\n if (!disabled && !isActive) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n title={collapsed ? String(children) : undefined}\n {...props}\n >\n {icon && <span style={iconStyle}>{icon}</span>}\n {!collapsed && <span style={{ flex: 1 }}>{children}</span>}\n {!collapsed && badge && <span style={badgeStyle}>{badge}</span>}\n </button>\n )\n})\n\nMenuItem.displayName = 'MenuItem'\n\n// MenuGroup\nexport interface MenuGroupProps extends HTMLAttributes<HTMLDivElement> {\n /** Group label */\n label?: string\n /** Custom class name */\n className?: string\n}\n\nexport const MenuGroup = forwardRef<HTMLDivElement, MenuGroupProps>(function MenuGroup(\n { label, className, style, children, ...props },\n ref\n) {\n const { collapsed } = useMenuContext()\n\n const groupStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: spacing[0.5],\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n padding: `${spacing[3]}px ${spacing[3]}px ${componentPaddingY.sm}px ${spacing[3]}px`,\n fontSize: fontSizes.xs,\n fontWeight: 600,\n color: 'var(--brycks-foreground-muted)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }\n\n return (\n <div ref={ref} className={cx('brycks-menu-group', className)} style={groupStyle} {...props}>\n {label && !collapsed && <div style={labelStyle}>{label}</div>}\n {children}\n </div>\n )\n})\n\nMenuGroup.displayName = 'MenuGroup'\n\n// MenuDivider\nexport interface MenuDividerProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const MenuDivider = forwardRef<HTMLDivElement, MenuDividerProps>(function MenuDivider(\n { className, style, ...props },\n ref\n) {\n const dividerStyle: CSSProperties = {\n height: 1,\n backgroundColor: 'var(--brycks-border-muted)',\n margin: `${spacing[2]}px 0`,\n ...style,\n }\n\n return (\n <div\n ref={ref}\n role=\"separator\"\n className={cx('brycks-menu-divider', className)}\n style={dividerStyle}\n {...props}\n />\n )\n})\n\nMenuDivider.displayName = 'MenuDivider'\n"],"names":["MenuContext","createContext","useMenuContext","context","useContext","Menu","forwardRef","controlledActiveItem","onChange","size","collapsed","className","style","children","testId","props","ref","internalActiveItem","setInternalActiveItem","useState","focusedIndex","setFocusedIndex","itemsRef","useRef","menuRef","activeItem","setActiveItem","value","registerItem","useCallback","index","handleKeyDown","items","currentIndex","nextIndex","prevIndex","menuStyle","spacing","jsx","node","cx","sizeConfig","componentHeights","fontSizes","iconSizes","componentGap","componentPaddingX","MenuItem","icon","badge","disabled","onClick","isActive","config","itemIndex","handleClick","handleFocus","itemStyle","durations","easings","iconStyle","badgeStyle","jsxs","e","MenuGroup","label","groupStyle","labelStyle","componentPaddingY","MenuDivider","dividerStyle"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),g=require("react"),z=require("../../../utils/styles.cjs"),w={sm:{height:28,fontSize:12,gap:4,minWidth:28},md:{height:36,fontSize:14,gap:6,minWidth:36},lg:{height:44,fontSize:16,gap:8,minWidth:44}};function E(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M10 12L6 8l4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function I(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M6 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function R(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M11 12l-4-4 4-4M7 12l-4-4 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function B(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M5 4l4 4-4 4M9 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}const p=g.forwardRef(function({page:r,totalPages:t,onChange:b,size:f="md",variant:l="default",siblingCount:a=1,showFirstLast:y=!0,showPrevNext:k=!0,disabled:o=!1,className:x,style:j,testId:C,...v},M){const s=w[f],L=g.useMemo(()=>{if(l==="minimal"||l==="simple")return[];const n=[],u=Math.max(r-a,1),c=Math.min(r+a,t),$=u>2,m=c<t-1;if($)if(m){n.push(1),n.push("ellipsis");for(let i=u;i<=c;i++)n.push(i);n.push("ellipsis"),n.push(t)}else{n.push(1),n.push("ellipsis");for(let i=Math.max(t-2-a,1);i<=t;i++)n.push(i)}else{for(let i=1;i<=Math.min(3+a,t);i++)n.push(i);m&&(n.push("ellipsis"),n.push(t))}return n},[r,t,a,l]),S={display:"flex",alignItems:"center",gap:s.gap,...j},h=(n,u)=>({display:"inline-flex",alignItems:"center",justifyContent:"center",minWidth:s.minWidth,height:s.height,padding:`0 ${s.gap+4}px`,fontSize:s.fontSize,fontWeight:n?600:500,color:u?"var(--brycks-foreground-disabled)":n?"var(--brycks-primary-default)":"var(--brycks-foreground-default)",backgroundColor:n?"var(--brycks-primary-50)":"transparent",border:"none",borderRadius:"var(--brycks-radius-md)",cursor:u?"not-allowed":"pointer",transition:"all 150ms ease-out",outline:"none"}),W={display:"flex",alignItems:"center",justifyContent:"center",minWidth:s.minWidth,height:s.height,color:"var(--brycks-foreground-muted)",fontSize:s.fontSize},T={fontSize:s.fontSize,color:"var(--brycks-foreground-muted)",padding:`0 ${s.gap}px`},d=n=>{n>=1&&n<=t&&n!==r&&!o&&b(n)};return e.jsxs("nav",{ref:M,role:"navigation","aria-label":"Pagination",className:z.cx("brycks-pagination",`brycks-pagination--${f}`,`brycks-pagination--${l}`,x),style:S,"data-testid":C,...v,children:[y&&l!=="minimal"&&e.jsx("button",{type:"button","aria-label":"First page",disabled:r===1||o,style:h(!1,r===1||o),onClick:()=>d(1),onMouseEnter:n=>{r!==1&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:e.jsx(R,{})}),k&&e.jsx("button",{type:"button","aria-label":"Previous page",disabled:r===1||o,style:h(!1,r===1||o),onClick:()=>d(r-1),onMouseEnter:n=>{r!==1&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:e.jsx(E,{})}),l==="simple"||l==="minimal"?e.jsx("span",{style:T,children:l==="minimal"?`${r} / ${t}`:`Page ${r} of ${t}`}):L.map((n,u)=>n==="ellipsis"?e.jsx("span",{style:W,children:"..."},`ellipsis-${u}`):e.jsx("button",{type:"button","aria-label":`Page ${n}`,"aria-current":n===r?"page":void 0,disabled:o,style:h(n===r,o),onClick:()=>d(n),onMouseEnter:c=>{n!==r&&!o&&(c.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:c=>{n!==r&&(c.currentTarget.style.backgroundColor="transparent")},children:n},n)),k&&e.jsx("button",{type:"button","aria-label":"Next page",disabled:r===t||o,style:h(!1,r===t||o),onClick:()=>d(r+1),onMouseEnter:n=>{r!==t&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:e.jsx(I,{})}),y&&l!=="minimal"&&e.jsx("button",{type:"button","aria-label":"Last page",disabled:r===t||o,style:h(!1,r===t||o),onClick:()=>d(t),onMouseEnter:n=>{r!==t&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:e.jsx(B,{})})]})});p.displayName="Pagination";exports.Pagination=p;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),b=require("react"),E=require("../../../utils/styles.cjs"),u=require("../../../design-system/tokens/spacing.cjs"),g=require("../../../design-system/tokens/typography.cjs"),I=require("../../../design-system/primitives/sizing.cjs"),x=require("../../../design-system/tokens/motion.cjs"),R={sm:{height:u.spacing[7],fontSize:g.fontSizes.sm,gap:u.spacing[1],minWidth:u.spacing[7]},md:{height:u.spacing[9],fontSize:g.fontSizes.base,gap:I.componentGap.sm,minWidth:u.spacing[9]},lg:{height:u.spacing[11],fontSize:g.fontSizes.md,gap:u.spacing[2],minWidth:u.spacing[11]}};function B(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M10 12L6 8l4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function N(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M6 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function O(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M11 12l-4-4 4-4M7 12l-4-4 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function G(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M5 4l4 4-4 4M9 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}const j=b.forwardRef(function({page:r,totalPages:t,onChange:C,size:y="md",variant:c="default",siblingCount:h=1,showFirstLast:p=!0,showPrevNext:k=!0,disabled:o=!1,className:v,style:M,testId:S,...L},z){const s=R[y],W=b.useMemo(()=>{if(c==="minimal"||c==="simple")return[];const n=[],l=Math.max(r-h,1),a=Math.min(r+h,t),w=l>2,m=a<t-1;if(w)if(m){n.push(1),n.push("ellipsis");for(let i=l;i<=a;i++)n.push(i);n.push("ellipsis"),n.push(t)}else{n.push(1),n.push("ellipsis");for(let i=Math.max(t-2-h,1);i<=t;i++)n.push(i)}else{for(let i=1;i<=Math.min(3+h,t);i++)n.push(i);m&&(n.push("ellipsis"),n.push(t))}return n},[r,t,h,c]),$={display:"flex",alignItems:"center",gap:s.gap,...M},d=(n,l)=>({display:"inline-flex",alignItems:"center",justifyContent:"center",minWidth:s.minWidth,height:s.height,padding:`0 ${s.gap+4}px`,fontSize:s.fontSize,fontWeight:n?600:500,color:l?"var(--brycks-foreground-disabled)":n?"var(--brycks-primary-default)":"var(--brycks-foreground-default)",backgroundColor:n?"var(--brycks-primary-50)":"transparent",border:"none",borderRadius:"var(--brycks-radius-md)",cursor:l?"not-allowed":"pointer",transition:`all ${x.durations.quick}ms ${x.easings.easeOut}`,outline:"none"}),T={display:"flex",alignItems:"center",justifyContent:"center",minWidth:s.minWidth,height:s.height,color:"var(--brycks-foreground-muted)",fontSize:s.fontSize},q={fontSize:s.fontSize,color:"var(--brycks-foreground-muted)",padding:`0 ${s.gap}px`},f=n=>{n>=1&&n<=t&&n!==r&&!o&&C(n)};return e.jsxs("nav",{ref:z,role:"navigation","aria-label":"Pagination",className:E.cx("brycks-pagination",`brycks-pagination--${y}`,`brycks-pagination--${c}`,v),style:$,"data-testid":S,...L,children:[p&&c!=="minimal"&&e.jsx("button",{type:"button","aria-label":"First page",disabled:r===1||o,style:d(!1,r===1||o),onClick:()=>f(1),onMouseEnter:n=>{r!==1&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:e.jsx(O,{})}),k&&e.jsx("button",{type:"button","aria-label":"Previous page",disabled:r===1||o,style:d(!1,r===1||o),onClick:()=>f(r-1),onMouseEnter:n=>{r!==1&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:e.jsx(B,{})}),c==="simple"||c==="minimal"?e.jsx("span",{style:q,children:c==="minimal"?`${r} / ${t}`:`Page ${r} of ${t}`}):W.map((n,l)=>n==="ellipsis"?e.jsx("span",{style:T,children:"..."},`ellipsis-${l}`):e.jsx("button",{type:"button","aria-label":`Page ${n}`,"aria-current":n===r?"page":void 0,disabled:o,style:d(n===r,o),onClick:()=>f(n),onMouseEnter:a=>{n!==r&&!o&&(a.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:a=>{n!==r&&(a.currentTarget.style.backgroundColor="transparent")},children:n},n)),k&&e.jsx("button",{type:"button","aria-label":"Next page",disabled:r===t||o,style:d(!1,r===t||o),onClick:()=>f(r+1),onMouseEnter:n=>{r!==t&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:e.jsx(N,{})}),p&&c!=="minimal"&&e.jsx("button",{type:"button","aria-label":"Last page",disabled:r===t||o,style:d(!1,r===t||o),onClick:()=>f(t),onMouseEnter:n=>{r!==t&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:e.jsx(G,{})})]})});j.displayName="Pagination";exports.Pagination=j;
2
2
  //# sourceMappingURL=Pagination.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.cjs","sources":["../../../../src/components/navigation/Pagination/Pagination.tsx"],"sourcesContent":["/**\n * Pagination Component\n *\n * A pagination control for navigating through pages.\n * Supports different sizes and display modes.\n */\n\nimport { forwardRef, useMemo, type CSSProperties, type HTMLAttributes } from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type PaginationSize = 'sm' | 'md' | 'lg'\nexport type PaginationVariant = 'default' | 'simple' | 'minimal'\n\nexport interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Current page (1-indexed) */\n page: number\n /** Total number of pages */\n totalPages: number\n /** Callback when page changes */\n onChange: (page: number) => void\n /** Pagination size */\n size?: PaginationSize\n /** Pagination variant */\n variant?: PaginationVariant\n /** Number of sibling pages to show on each side */\n siblingCount?: number\n /** Whether to show first/last buttons */\n showFirstLast?: boolean\n /** Whether to show prev/next buttons */\n showPrevNext?: boolean\n /** Whether the component is disabled */\n disabled?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<PaginationSize, { height: number; fontSize: number; gap: number; minWidth: number }> = {\n sm: { height: 28, fontSize: 12, gap: 4, minWidth: 28 },\n md: { height: 36, fontSize: 14, gap: 6, minWidth: 36 },\n lg: { height: 44, fontSize: 16, gap: 8, minWidth: 44 },\n}\n\nfunction ChevronLeftIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M10 12L6 8l4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M6 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronsLeftIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M11 12l-4-4 4-4M7 12l-4-4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronsRightIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M5 4l4 4-4 4M9 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nexport const Pagination = forwardRef<HTMLElement, PaginationProps>(function Pagination(\n {\n page,\n totalPages,\n onChange,\n size = 'md',\n variant = 'default',\n siblingCount = 1,\n showFirstLast = true,\n showPrevNext = true,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const config = sizeConfig[size]\n\n // Generate page numbers to display\n const pages = useMemo(() => {\n if (variant === 'minimal' || variant === 'simple') {\n return []\n }\n\n const range: (number | 'ellipsis')[] = []\n const leftSibling = Math.max(page - siblingCount, 1)\n const rightSibling = Math.min(page + siblingCount, totalPages)\n\n const showLeftEllipsis = leftSibling > 2\n const showRightEllipsis = rightSibling < totalPages - 1\n\n if (!showLeftEllipsis) {\n for (let i = 1; i <= Math.min(3 + siblingCount, totalPages); i++) {\n range.push(i)\n }\n if (showRightEllipsis) {\n range.push('ellipsis')\n range.push(totalPages)\n }\n } else if (!showRightEllipsis) {\n range.push(1)\n range.push('ellipsis')\n for (let i = Math.max(totalPages - 2 - siblingCount, 1); i <= totalPages; i++) {\n range.push(i)\n }\n } else {\n range.push(1)\n range.push('ellipsis')\n for (let i = leftSibling; i <= rightSibling; i++) {\n range.push(i)\n }\n range.push('ellipsis')\n range.push(totalPages)\n }\n\n return range\n }, [page, totalPages, siblingCount, variant])\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: config.gap,\n ...style,\n }\n\n const getButtonStyle = (isActive: boolean, isDisabled: boolean): CSSProperties => ({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: config.minWidth,\n height: config.height,\n padding: `0 ${config.gap + 4}px`,\n fontSize: config.fontSize,\n fontWeight: isActive ? 600 : 500,\n color: isDisabled\n ? 'var(--brycks-foreground-disabled)'\n : isActive\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-primary-50)' : 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n transition: 'all 150ms ease-out',\n outline: 'none',\n })\n\n const ellipsisStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: config.minWidth,\n height: config.height,\n color: 'var(--brycks-foreground-muted)',\n fontSize: config.fontSize,\n }\n\n const infoStyle: CSSProperties = {\n fontSize: config.fontSize,\n color: 'var(--brycks-foreground-muted)',\n padding: `0 ${config.gap}px`,\n }\n\n const handlePageChange = (newPage: number) => {\n if (newPage >= 1 && newPage <= totalPages && newPage !== page && !disabled) {\n onChange(newPage)\n }\n }\n\n return (\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label=\"Pagination\"\n className={cx('brycks-pagination', `brycks-pagination--${size}`, `brycks-pagination--${variant}`, className)}\n style={containerStyle}\n data-testid={testId}\n {...props}\n >\n {showFirstLast && variant !== 'minimal' && (\n <button\n type=\"button\"\n aria-label=\"First page\"\n disabled={page === 1 || disabled}\n style={getButtonStyle(false, page === 1 || disabled)}\n onClick={() => handlePageChange(1)}\n onMouseEnter={(e) => {\n if (page !== 1 && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronsLeftIcon />\n </button>\n )}\n\n {showPrevNext && (\n <button\n type=\"button\"\n aria-label=\"Previous page\"\n disabled={page === 1 || disabled}\n style={getButtonStyle(false, page === 1 || disabled)}\n onClick={() => handlePageChange(page - 1)}\n onMouseEnter={(e) => {\n if (page !== 1 && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronLeftIcon />\n </button>\n )}\n\n {variant === 'simple' || variant === 'minimal' ? (\n <span style={infoStyle}>\n {variant === 'minimal' ? `${page} / ${totalPages}` : `Page ${page} of ${totalPages}`}\n </span>\n ) : (\n pages.map((p, index) =>\n p === 'ellipsis' ? (\n <span key={`ellipsis-${index}`} style={ellipsisStyle}>\n ...\n </span>\n ) : (\n <button\n key={p}\n type=\"button\"\n aria-label={`Page ${p}`}\n aria-current={p === page ? 'page' : undefined}\n disabled={disabled}\n style={getButtonStyle(p === page, disabled)}\n onClick={() => handlePageChange(p)}\n onMouseEnter={(e) => {\n if (p !== page && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (p !== page) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n {p}\n </button>\n )\n )\n )}\n\n {showPrevNext && (\n <button\n type=\"button\"\n aria-label=\"Next page\"\n disabled={page === totalPages || disabled}\n style={getButtonStyle(false, page === totalPages || disabled)}\n onClick={() => handlePageChange(page + 1)}\n onMouseEnter={(e) => {\n if (page !== totalPages && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronRightIcon />\n </button>\n )}\n\n {showFirstLast && variant !== 'minimal' && (\n <button\n type=\"button\"\n aria-label=\"Last page\"\n disabled={page === totalPages || disabled}\n style={getButtonStyle(false, page === totalPages || disabled)}\n onClick={() => handlePageChange(totalPages)}\n onMouseEnter={(e) => {\n if (page !== totalPages && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronsRightIcon />\n </button>\n )}\n </nav>\n )\n})\n\nPagination.displayName = 'Pagination'\n"],"names":["sizeConfig","ChevronLeftIcon","jsx","ChevronRightIcon","ChevronsLeftIcon","ChevronsRightIcon","Pagination","forwardRef","page","totalPages","onChange","size","variant","siblingCount","showFirstLast","showPrevNext","disabled","className","style","testId","props","ref","config","pages","useMemo","range","leftSibling","rightSibling","showLeftEllipsis","showRightEllipsis","containerStyle","getButtonStyle","isActive","isDisabled","ellipsisStyle","infoStyle","handlePageChange","newPage","jsxs","cx","e","p","index"],"mappings":"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"}
1
+ {"version":3,"file":"Pagination.cjs","sources":["../../../../src/components/navigation/Pagination/Pagination.tsx"],"sourcesContent":["/**\n * Pagination Component\n *\n * A pagination control for navigating through pages.\n * Supports different sizes and display modes.\n */\n\nimport { forwardRef, useMemo, type CSSProperties, type HTMLAttributes } from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentGap } from '../../../design-system/primitives'\n\nexport type PaginationSize = 'sm' | 'md' | 'lg'\nexport type PaginationVariant = 'default' | 'simple' | 'minimal'\n\nexport interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Current page (1-indexed) */\n page: number\n /** Total number of pages */\n totalPages: number\n /** Callback when page changes */\n onChange: (page: number) => void\n /** Pagination size */\n size?: PaginationSize\n /** Pagination variant */\n variant?: PaginationVariant\n /** Number of sibling pages to show on each side */\n siblingCount?: number\n /** Whether to show first/last buttons */\n showFirstLast?: boolean\n /** Whether to show prev/next buttons */\n showPrevNext?: boolean\n /** Whether the component is disabled */\n disabled?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<PaginationSize, { height: number; fontSize: number; gap: number; minWidth: number }> = {\n sm: { height: spacing[7], fontSize: fontSizes.sm, gap: spacing[1], minWidth: spacing[7] },\n md: { height: spacing[9], fontSize: fontSizes.base, gap: componentGap.sm, minWidth: spacing[9] },\n lg: { height: spacing[11], fontSize: fontSizes.md, gap: spacing[2], minWidth: spacing[11] },\n}\n\nfunction ChevronLeftIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M10 12L6 8l4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M6 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronsLeftIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M11 12l-4-4 4-4M7 12l-4-4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronsRightIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M5 4l4 4-4 4M9 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nexport const Pagination = forwardRef<HTMLElement, PaginationProps>(function Pagination(\n {\n page,\n totalPages,\n onChange,\n size = 'md',\n variant = 'default',\n siblingCount = 1,\n showFirstLast = true,\n showPrevNext = true,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const config = sizeConfig[size]\n\n // Generate page numbers to display\n const pages = useMemo(() => {\n if (variant === 'minimal' || variant === 'simple') {\n return []\n }\n\n const range: (number | 'ellipsis')[] = []\n const leftSibling = Math.max(page - siblingCount, 1)\n const rightSibling = Math.min(page + siblingCount, totalPages)\n\n const showLeftEllipsis = leftSibling > 2\n const showRightEllipsis = rightSibling < totalPages - 1\n\n if (!showLeftEllipsis) {\n for (let i = 1; i <= Math.min(3 + siblingCount, totalPages); i++) {\n range.push(i)\n }\n if (showRightEllipsis) {\n range.push('ellipsis')\n range.push(totalPages)\n }\n } else if (!showRightEllipsis) {\n range.push(1)\n range.push('ellipsis')\n for (let i = Math.max(totalPages - 2 - siblingCount, 1); i <= totalPages; i++) {\n range.push(i)\n }\n } else {\n range.push(1)\n range.push('ellipsis')\n for (let i = leftSibling; i <= rightSibling; i++) {\n range.push(i)\n }\n range.push('ellipsis')\n range.push(totalPages)\n }\n\n return range\n }, [page, totalPages, siblingCount, variant])\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: config.gap,\n ...style,\n }\n\n const getButtonStyle = (isActive: boolean, isDisabled: boolean): CSSProperties => ({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: config.minWidth,\n height: config.height,\n padding: `0 ${config.gap + 4}px`,\n fontSize: config.fontSize,\n fontWeight: isActive ? 600 : 500,\n color: isDisabled\n ? 'var(--brycks-foreground-disabled)'\n : isActive\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-primary-50)' : 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n transition: `all ${durations.quick}ms ${easings.easeOut}`,\n outline: 'none',\n })\n\n const ellipsisStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: config.minWidth,\n height: config.height,\n color: 'var(--brycks-foreground-muted)',\n fontSize: config.fontSize,\n }\n\n const infoStyle: CSSProperties = {\n fontSize: config.fontSize,\n color: 'var(--brycks-foreground-muted)',\n padding: `0 ${config.gap}px`,\n }\n\n const handlePageChange = (newPage: number) => {\n if (newPage >= 1 && newPage <= totalPages && newPage !== page && !disabled) {\n onChange(newPage)\n }\n }\n\n return (\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label=\"Pagination\"\n className={cx('brycks-pagination', `brycks-pagination--${size}`, `brycks-pagination--${variant}`, className)}\n style={containerStyle}\n data-testid={testId}\n {...props}\n >\n {showFirstLast && variant !== 'minimal' && (\n <button\n type=\"button\"\n aria-label=\"First page\"\n disabled={page === 1 || disabled}\n style={getButtonStyle(false, page === 1 || disabled)}\n onClick={() => handlePageChange(1)}\n onMouseEnter={(e) => {\n if (page !== 1 && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronsLeftIcon />\n </button>\n )}\n\n {showPrevNext && (\n <button\n type=\"button\"\n aria-label=\"Previous page\"\n disabled={page === 1 || disabled}\n style={getButtonStyle(false, page === 1 || disabled)}\n onClick={() => handlePageChange(page - 1)}\n onMouseEnter={(e) => {\n if (page !== 1 && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronLeftIcon />\n </button>\n )}\n\n {variant === 'simple' || variant === 'minimal' ? (\n <span style={infoStyle}>\n {variant === 'minimal' ? `${page} / ${totalPages}` : `Page ${page} of ${totalPages}`}\n </span>\n ) : (\n pages.map((p, index) =>\n p === 'ellipsis' ? (\n <span key={`ellipsis-${index}`} style={ellipsisStyle}>\n ...\n </span>\n ) : (\n <button\n key={p}\n type=\"button\"\n aria-label={`Page ${p}`}\n aria-current={p === page ? 'page' : undefined}\n disabled={disabled}\n style={getButtonStyle(p === page, disabled)}\n onClick={() => handlePageChange(p)}\n onMouseEnter={(e) => {\n if (p !== page && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (p !== page) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n {p}\n </button>\n )\n )\n )}\n\n {showPrevNext && (\n <button\n type=\"button\"\n aria-label=\"Next page\"\n disabled={page === totalPages || disabled}\n style={getButtonStyle(false, page === totalPages || disabled)}\n onClick={() => handlePageChange(page + 1)}\n onMouseEnter={(e) => {\n if (page !== totalPages && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronRightIcon />\n </button>\n )}\n\n {showFirstLast && variant !== 'minimal' && (\n <button\n type=\"button\"\n aria-label=\"Last page\"\n disabled={page === totalPages || disabled}\n style={getButtonStyle(false, page === totalPages || disabled)}\n onClick={() => handlePageChange(totalPages)}\n onMouseEnter={(e) => {\n if (page !== totalPages && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronsRightIcon />\n </button>\n )}\n </nav>\n )\n})\n\nPagination.displayName = 'Pagination'\n"],"names":["sizeConfig","spacing","fontSizes","componentGap","ChevronLeftIcon","jsx","ChevronRightIcon","ChevronsLeftIcon","ChevronsRightIcon","Pagination","forwardRef","page","totalPages","onChange","size","variant","siblingCount","showFirstLast","showPrevNext","disabled","className","style","testId","props","ref","config","pages","useMemo","range","leftSibling","rightSibling","showLeftEllipsis","showRightEllipsis","containerStyle","getButtonStyle","isActive","isDisabled","durations","easings","ellipsisStyle","infoStyle","handlePageChange","newPage","jsxs","cx","e","p","index"],"mappings":"gZAwCMA,EAA0G,CAC9G,GAAI,CAAE,OAAQC,EAAAA,QAAQ,CAAC,EAAG,SAAUC,EAAAA,UAAU,GAAI,IAAKD,EAAAA,QAAQ,CAAC,EAAG,SAAUA,EAAAA,QAAQ,CAAC,CAAA,EACtF,GAAI,CAAE,OAAQA,EAAAA,QAAQ,CAAC,EAAG,SAAUC,EAAAA,UAAU,KAAM,IAAKC,EAAAA,aAAa,GAAI,SAAUF,EAAAA,QAAQ,CAAC,CAAA,EAC7F,GAAI,CAAE,OAAQA,EAAAA,QAAQ,EAAE,EAAG,SAAUC,EAAAA,UAAU,GAAI,IAAKD,EAAAA,QAAQ,CAAC,EAAG,SAAUA,EAAAA,QAAQ,EAAE,CAAA,CAC1F,EAEA,SAASG,GAAkB,CACzB,OACEC,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OACnD,SAAAA,EAAAA,IAAC,QAAK,EAAE,iBAAiB,OAAO,eAAe,YAAY,MAAM,cAAc,QAAQ,eAAe,OAAA,CAAQ,CAAA,CAChH,CAEJ,CAEA,SAASC,GAAmB,CAC1B,OACED,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OACnD,SAAAA,EAAAA,IAAC,QAAK,EAAE,eAAe,OAAO,eAAe,YAAY,MAAM,cAAc,QAAQ,eAAe,OAAA,CAAQ,CAAA,CAC9G,CAEJ,CAEA,SAASE,GAAmB,CAC1B,OACEF,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OACnD,SAAAA,EAAAA,IAAC,QAAK,EAAE,gCAAgC,OAAO,eAAe,YAAY,MAAM,cAAc,QAAQ,eAAe,OAAA,CAAQ,CAAA,CAC/H,CAEJ,CAEA,SAASG,GAAoB,CAC3B,OACEH,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OACnD,SAAAA,EAAAA,IAAC,QAAK,EAAE,2BAA2B,OAAO,eAAe,YAAY,MAAM,cAAc,QAAQ,eAAe,OAAA,CAAQ,CAAA,CAC1H,CAEJ,CAEO,MAAMI,EAAaC,EAAAA,WAAyC,SACjE,CACE,KAAAC,EACA,WAAAC,EACA,SAAAC,EACA,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,aAAAC,EAAe,EACf,cAAAC,EAAgB,GAChB,aAAAC,EAAe,GACf,SAAAC,EAAW,GACX,UAAAC,EACA,MAAAC,EACA,OAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,MAAMC,EAASzB,EAAWc,CAAI,EAGxBY,EAAQC,EAAAA,QAAQ,IAAM,CAC1B,GAAIZ,IAAY,WAAaA,IAAY,SACvC,MAAO,CAAA,EAGT,MAAMa,EAAiC,CAAA,EACjCC,EAAc,KAAK,IAAIlB,EAAOK,EAAc,CAAC,EAC7Cc,EAAe,KAAK,IAAInB,EAAOK,EAAcJ,CAAU,EAEvDmB,EAAmBF,EAAc,EACjCG,EAAoBF,EAAelB,EAAa,EAEtD,GAAKmB,EAQL,GAAYC,EAML,CACLJ,EAAM,KAAK,CAAC,EACZA,EAAM,KAAK,UAAU,EACrB,QAAS,EAAIC,EAAa,GAAKC,EAAc,IAC3CF,EAAM,KAAK,CAAC,EAEdA,EAAM,KAAK,UAAU,EACrBA,EAAM,KAAKhB,CAAU,CACvB,KAd+B,CAC7BgB,EAAM,KAAK,CAAC,EACZA,EAAM,KAAK,UAAU,EACrB,QAAS,EAAI,KAAK,IAAIhB,EAAa,EAAII,EAAc,CAAC,EAAG,GAAKJ,EAAY,IACxEgB,EAAM,KAAK,CAAC,CAEhB,KAduB,CACrB,QAAS,EAAI,EAAG,GAAK,KAAK,IAAI,EAAIZ,EAAcJ,CAAU,EAAG,IAC3DgB,EAAM,KAAK,CAAC,EAEVI,IACFJ,EAAM,KAAK,UAAU,EACrBA,EAAM,KAAKhB,CAAU,EAEzB,CAgBA,OAAOgB,CACT,EAAG,CAACjB,EAAMC,EAAYI,EAAcD,CAAO,CAAC,EAEtCkB,EAAgC,CACpC,QAAS,OACT,WAAY,SACZ,IAAKR,EAAO,IACZ,GAAGJ,CAAA,EAGCa,EAAiB,CAACC,EAAmBC,KAAwC,CACjF,QAAS,cACT,WAAY,SACZ,eAAgB,SAChB,SAAUX,EAAO,SACjB,OAAQA,EAAO,OACf,QAAS,KAAKA,EAAO,IAAM,CAAC,KAC5B,SAAUA,EAAO,SACjB,WAAYU,EAAW,IAAM,IAC7B,MAAOC,EACH,oCACAD,EACA,gCACA,mCACJ,gBAAiBA,EAAW,2BAA6B,cACzD,OAAQ,OACR,aAAc,0BACd,OAAQC,EAAa,cAAgB,UACrC,WAAY,OAAOC,EAAAA,UAAU,KAAK,MAAMC,EAAAA,QAAQ,OAAO,GACvD,QAAS,MAAA,GAGLC,EAA+B,CACnC,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,SAAUd,EAAO,SACjB,OAAQA,EAAO,OACf,MAAO,iCACP,SAAUA,EAAO,QAAA,EAGbe,EAA2B,CAC/B,SAAUf,EAAO,SACjB,MAAO,iCACP,QAAS,KAAKA,EAAO,GAAG,IAAA,EAGpBgB,EAAoBC,GAAoB,CACxCA,GAAW,GAAKA,GAAW9B,GAAc8B,IAAY/B,GAAQ,CAACQ,GAChEN,EAAS6B,CAAO,CAEpB,EAEA,OACEC,EAAAA,KAAC,MAAA,CACC,IAAAnB,EACA,KAAK,aACL,aAAW,aACX,UAAWoB,EAAAA,GAAG,oBAAqB,sBAAsB9B,CAAI,GAAI,sBAAsBC,CAAO,GAAIK,CAAS,EAC3G,MAAOa,EACP,cAAaX,EACZ,GAAGC,EAEH,SAAA,CAAAN,GAAiBF,IAAY,WAC5BV,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,aAAW,aACX,SAAUM,IAAS,GAAKQ,EACxB,MAAOe,EAAe,GAAOvB,IAAS,GAAKQ,CAAQ,EACnD,QAAS,IAAMsB,EAAiB,CAAC,EACjC,aAAeI,GAAM,CACflC,IAAS,GAAK,CAACQ,IACjB0B,EAAE,cAAc,MAAM,gBAAkB,iCAE5C,EACA,aAAeA,GAAM,CACnBA,EAAE,cAAc,MAAM,gBAAkB,aAC1C,EAEA,eAACtC,EAAA,CAAA,CAAiB,CAAA,CAAA,EAIrBW,GACCb,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,aAAW,gBACX,SAAUM,IAAS,GAAKQ,EACxB,MAAOe,EAAe,GAAOvB,IAAS,GAAKQ,CAAQ,EACnD,QAAS,IAAMsB,EAAiB9B,EAAO,CAAC,EACxC,aAAekC,GAAM,CACflC,IAAS,GAAK,CAACQ,IACjB0B,EAAE,cAAc,MAAM,gBAAkB,iCAE5C,EACA,aAAeA,GAAM,CACnBA,EAAE,cAAc,MAAM,gBAAkB,aAC1C,EAEA,eAACzC,EAAA,CAAA,CAAgB,CAAA,CAAA,EAIpBW,IAAY,UAAYA,IAAY,gBAClC,OAAA,CAAK,MAAOyB,EACV,SAAAzB,IAAY,UAAY,GAAGJ,CAAI,MAAMC,CAAU,GAAK,QAAQD,CAAI,OAAOC,CAAU,GACpF,EAEAc,EAAM,IAAI,CAACoB,EAAGC,IACZD,IAAM,WACJzC,EAAAA,IAAC,OAAA,CAA+B,MAAOkC,EAAe,SAAA,OAA3C,YAAYQ,CAAK,EAE5B,EAEA1C,EAAAA,IAAC,SAAA,CAEC,KAAK,SACL,aAAY,QAAQyC,CAAC,GACrB,eAAcA,IAAMnC,EAAO,OAAS,OACpC,SAAAQ,EACA,MAAOe,EAAeY,IAAMnC,EAAMQ,CAAQ,EAC1C,QAAS,IAAMsB,EAAiBK,CAAC,EACjC,aAAeD,GAAM,CACfC,IAAMnC,GAAQ,CAACQ,IACjB0B,EAAE,cAAc,MAAM,gBAAkB,iCAE5C,EACA,aAAeA,GAAM,CACfC,IAAMnC,IACRkC,EAAE,cAAc,MAAM,gBAAkB,cAE5C,EAEC,SAAAC,CAAA,EAlBIA,CAAA,CAmBP,EAKL5B,GACCb,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,aAAW,YACX,SAAUM,IAASC,GAAcO,EACjC,MAAOe,EAAe,GAAOvB,IAASC,GAAcO,CAAQ,EAC5D,QAAS,IAAMsB,EAAiB9B,EAAO,CAAC,EACxC,aAAekC,GAAM,CACflC,IAASC,GAAc,CAACO,IAC1B0B,EAAE,cAAc,MAAM,gBAAkB,iCAE5C,EACA,aAAeA,GAAM,CACnBA,EAAE,cAAc,MAAM,gBAAkB,aAC1C,EAEA,eAACvC,EAAA,CAAA,CAAiB,CAAA,CAAA,EAIrBW,GAAiBF,IAAY,WAC5BV,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,aAAW,YACX,SAAUM,IAASC,GAAcO,EACjC,MAAOe,EAAe,GAAOvB,IAASC,GAAcO,CAAQ,EAC5D,QAAS,IAAMsB,EAAiB7B,CAAU,EAC1C,aAAeiC,GAAM,CACflC,IAASC,GAAc,CAACO,IAC1B0B,EAAE,cAAc,MAAM,gBAAkB,iCAE5C,EACA,aAAeA,GAAM,CACnBA,EAAE,cAAc,MAAM,gBAAkB,aAC1C,EAEA,eAACrC,EAAA,CAAA,CAAkB,CAAA,CAAA,CACrB,CAAA,CAAA,CAIR,CAAC,EAEDC,EAAW,YAAc"}