@fabio.caffarello/react-design-system 3.12.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/granular/index.js +393 -389
- package/dist/granular/index.js.map +1 -1
- package/dist/granular/ui/components/Autocomplete/Autocomplete.js +103 -86
- package/dist/granular/ui/components/Autocomplete/Autocomplete.js.map +1 -1
- package/dist/granular/ui/components/Autocomplete/AutocompleteList.js +57 -47
- package/dist/granular/ui/components/Autocomplete/AutocompleteList.js.map +1 -1
- package/dist/granular/ui/components/Autocomplete/AutocompleteOption.js +21 -20
- package/dist/granular/ui/components/Autocomplete/AutocompleteOption.js.map +1 -1
- package/dist/granular/ui/components/Breadcrumb/Breadcrumb.js.map +1 -1
- package/dist/granular/ui/components/ButtonGroup/ButtonGroup.js +68 -0
- package/dist/granular/ui/components/ButtonGroup/ButtonGroup.js.map +1 -0
- package/dist/granular/ui/components/ColorPicker/ColorPicker.js.map +1 -1
- package/dist/granular/ui/components/CommandPalette/CommandPalette.js +187 -149
- package/dist/granular/ui/components/CommandPalette/CommandPalette.js.map +1 -1
- package/dist/granular/ui/components/DataGrid/DataGrid.js +92 -92
- package/dist/granular/ui/components/DataGrid/DataGrid.js.map +1 -1
- package/dist/granular/ui/components/DatePicker/DatePickerCalendar.js +154 -139
- package/dist/granular/ui/components/DatePicker/DatePickerCalendar.js.map +1 -1
- package/dist/granular/ui/components/Dialog/AlertDialog.js +73 -40
- package/dist/granular/ui/components/Dialog/AlertDialog.js.map +1 -1
- package/dist/granular/ui/components/Dialog/DialogContent.js +54 -48
- package/dist/granular/ui/components/Dialog/DialogContent.js.map +1 -1
- package/dist/granular/ui/components/Dialog/DialogDescription.js +31 -31
- package/dist/granular/ui/components/Dialog/DialogDescription.js.map +1 -1
- package/dist/granular/ui/components/Dialog/DialogTitle.js +30 -30
- package/dist/granular/ui/components/Dialog/DialogTitle.js.map +1 -1
- package/dist/granular/ui/components/Drawer/Drawer.js.map +1 -1
- package/dist/granular/ui/components/Dropdown/Dropdown.js.map +1 -1
- package/dist/granular/ui/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/granular/ui/components/FileUpload/FileUpload.js.map +1 -1
- package/dist/granular/ui/components/Form/Form.js +38 -37
- package/dist/granular/ui/components/Form/Form.js.map +1 -1
- package/dist/granular/ui/components/Form/FormField.js +28 -26
- package/dist/granular/ui/components/Form/FormField.js.map +1 -1
- package/dist/granular/ui/components/Header/Header.js.map +1 -1
- package/dist/granular/ui/components/Header/components/HeaderActions.js.map +1 -1
- package/dist/granular/ui/components/Header/components/HeaderHamburger.js.map +1 -1
- package/dist/granular/ui/components/Header/components/HeaderLogo.js.map +1 -1
- package/dist/granular/ui/components/Header/components/HeaderMobileMenu.js.map +1 -1
- package/dist/granular/ui/components/Header/components/HeaderNavigation.js.map +1 -1
- package/dist/granular/ui/components/Header/contexts/HeaderContext.js.map +1 -1
- package/dist/granular/ui/components/Menu/Menu.js.map +1 -1
- package/dist/granular/ui/components/Modal/Modal.js +98 -86
- package/dist/granular/ui/components/Modal/Modal.js.map +1 -1
- package/dist/granular/ui/components/MultiSelect/MultiSelect.js +122 -106
- package/dist/granular/ui/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/granular/ui/components/Navigation/Navigation.js.map +1 -1
- package/dist/granular/ui/components/PageHeader/PageHeader.js.map +1 -1
- package/dist/granular/ui/components/Pagination/Pagination.js.map +1 -1
- package/dist/granular/ui/components/Popover/Popover.js.map +1 -1
- package/dist/granular/ui/components/Rating/Rating.js.map +1 -1
- package/dist/granular/ui/components/SearchInput/SearchInput.js.map +1 -1
- package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarGroup.js +82 -64
- package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarGroup.js.map +1 -1
- package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarItem.js +30 -29
- package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarItem.js.map +1 -1
- package/dist/granular/ui/components/SideNavbar/components/SideNavbarResizeHandle.js +37 -35
- package/dist/granular/ui/components/SideNavbar/components/SideNavbarResizeHandle.js.map +1 -1
- package/dist/granular/ui/components/SideNavbar/providers/SideNavbarStateProvider.js +57 -57
- package/dist/granular/ui/components/SideNavbar/providers/SideNavbarStateProvider.js.map +1 -1
- package/dist/granular/ui/components/Stepper/Stepper.js +102 -94
- package/dist/granular/ui/components/Stepper/Stepper.js.map +1 -1
- package/dist/granular/ui/components/Table/Table.js +41 -35
- package/dist/granular/ui/components/Table/Table.js.map +1 -1
- package/dist/granular/ui/components/Table/TableActions/TableActions.js.map +1 -1
- package/dist/granular/ui/components/Table/TableFilters/TableFilters.js +49 -46
- package/dist/granular/ui/components/Table/TableFilters/TableFilters.js.map +1 -1
- package/dist/granular/ui/components/Table/TablePagination/TablePagination.js.map +1 -1
- package/dist/granular/ui/components/Table/TableProvider.js +82 -80
- package/dist/granular/ui/components/Table/TableProvider.js.map +1 -1
- package/dist/granular/ui/components/Table/TableRow.js +57 -53
- package/dist/granular/ui/components/Table/TableRow.js.map +1 -1
- package/dist/granular/ui/components/Table/useColumnResizing.js +53 -53
- package/dist/granular/ui/components/Table/useColumnResizing.js.map +1 -1
- package/dist/granular/ui/components/TimePicker/TimePicker.js +149 -103
- package/dist/granular/ui/components/TimePicker/TimePicker.js.map +1 -1
- package/dist/granular/ui/components/Timeline/Timeline.js.map +1 -1
- package/dist/granular/ui/hooks/useFocusRestore.js +14 -15
- package/dist/granular/ui/hooks/useFocusRestore.js.map +1 -1
- package/dist/granular/ui/primitives/Badge/Badge.js.map +1 -1
- package/dist/granular/ui/primitives/Checkbox/Checkbox.js.map +1 -1
- package/dist/granular/ui/primitives/Chip/Chip.js +91 -71
- package/dist/granular/ui/primitives/Chip/Chip.js.map +1 -1
- package/dist/granular/ui/primitives/Dot/Dot.js +99 -0
- package/dist/granular/ui/primitives/Dot/Dot.js.map +1 -0
- package/dist/granular/ui/primitives/ErrorMessage/ErrorMessage.js.map +1 -1
- package/dist/granular/ui/primitives/Input/Input.js.map +1 -1
- package/dist/granular/ui/primitives/Label/Label.js.map +1 -1
- package/dist/granular/ui/primitives/NavLink/NavLink.js.map +1 -1
- package/dist/granular/ui/primitives/Radio/Radio.js.map +1 -1
- package/dist/granular/ui/primitives/Select/Select.js.map +1 -1
- package/dist/granular/ui/primitives/Separator/Separator.js.map +1 -1
- package/dist/granular/ui/primitives/Skeleton/Skeleton.js.map +1 -1
- package/dist/granular/ui/primitives/Slider/Slider.js.map +1 -1
- package/dist/granular/ui/primitives/Spinner/Spinner.js.map +1 -1
- package/dist/granular/ui/primitives/Switch/Switch.js.map +1 -1
- package/dist/granular/ui/primitives/Tooltip/Tooltip.js.map +1 -1
- package/dist/granular/ui/providers/DialogContext.js.map +1 -1
- package/dist/granular/ui/providers/DialogProvider.js +24 -20
- package/dist/granular/ui/providers/DialogProvider.js.map +1 -1
- package/dist/index.cjs +134 -134
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5945 -5542
- package/dist/index.js.map +1 -1
- package/dist/react-design-system.css +1 -1
- package/dist/server/index.cjs +7 -7
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.js +404 -384
- package/dist/server/index.js.map +1 -1
- package/dist/ui/components/Autocomplete/AutocompleteList.d.ts +4 -0
- package/dist/ui/components/Autocomplete/AutocompleteOption.d.ts +8 -0
- package/dist/ui/components/Breadcrumb/Breadcrumb.d.ts +0 -1
- package/dist/ui/components/ButtonGroup/ButtonGroup.d.ts +2 -2
- package/dist/ui/components/ColorPicker/ColorPicker.d.ts +0 -1
- package/dist/ui/components/CommandPalette/CommandPalette.d.ts +0 -1
- package/dist/ui/components/DataGrid/DataGrid.d.ts +0 -1
- package/dist/ui/components/Dialog/DialogContent.d.ts +20 -1
- package/dist/ui/components/Drawer/Drawer.d.ts +0 -1
- package/dist/ui/components/Dropdown/Dropdown.d.ts +0 -1
- package/dist/ui/components/EmptyState/EmptyState.d.ts +0 -1
- package/dist/ui/components/FileUpload/FileUpload.d.ts +0 -1
- package/dist/ui/components/Form/FormField.d.ts +7 -0
- package/dist/ui/components/Header/Header.d.ts +1 -1
- package/dist/ui/components/Header/components/HeaderActions.d.ts +1 -1
- package/dist/ui/components/Header/components/HeaderHamburger.d.ts +1 -1
- package/dist/ui/components/Header/components/HeaderLogo.d.ts +1 -1
- package/dist/ui/components/Header/components/HeaderMobileMenu.d.ts +1 -1
- package/dist/ui/components/Header/components/HeaderNavigation.d.ts +1 -1
- package/dist/ui/components/Header/contexts/HeaderContext.d.ts +1 -1
- package/dist/ui/components/Menu/Menu.d.ts +0 -1
- package/dist/ui/components/Modal/Modal.d.ts +1 -2
- package/dist/ui/components/Navigation/Navigation.d.ts +1 -1
- package/dist/ui/components/PageHeader/PageHeader.d.ts +1 -1
- package/dist/ui/components/Pagination/Pagination.d.ts +0 -1
- package/dist/ui/components/Popover/Popover.d.ts +0 -1
- package/dist/ui/components/Rating/Rating.d.ts +0 -1
- package/dist/ui/components/SearchInput/SearchInput.d.ts +0 -1
- package/dist/ui/components/Stepper/Stepper.d.ts +0 -1
- package/dist/ui/components/Table/TableActions/TableActions.d.ts +0 -1
- package/dist/ui/components/Table/TableFilters/TableFilters.d.ts +0 -1
- package/dist/ui/components/Table/TablePagination/TablePagination.d.ts +0 -1
- package/dist/ui/components/TimePicker/TimePicker.d.ts +0 -1
- package/dist/ui/components/Timeline/Timeline.d.ts +0 -1
- package/dist/ui/components/index.d.ts +2 -0
- package/dist/ui/primitives/Checkbox/Checkbox.d.ts +0 -1
- package/dist/ui/primitives/Chip/Chip.d.ts +21 -0
- package/dist/ui/primitives/ErrorMessage/ErrorMessage.d.ts +0 -1
- package/dist/ui/primitives/Input/Input.d.ts +0 -1
- package/dist/ui/primitives/Label/Label.d.ts +0 -1
- package/dist/ui/primitives/NavLink/NavLink.d.ts +1 -1
- package/dist/ui/primitives/Radio/Radio.d.ts +0 -1
- package/dist/ui/primitives/Select/Select.d.ts +0 -1
- package/dist/ui/primitives/Skeleton/Skeleton.d.ts +0 -1
- package/dist/ui/primitives/Slider/Slider.d.ts +0 -1
- package/dist/ui/primitives/Switch/Switch.d.ts +0 -1
- package/dist/ui/primitives/Tooltip/Tooltip.d.ts +0 -1
- package/dist/ui/primitives/index.d.ts +2 -0
- package/dist/ui/providers/DialogContext.d.ts +8 -0
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.js","sources":["../../../../../src/ui/components/Popover/Popover.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useState,\n useRef,\n useEffect,\n useCallback,\n useId,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { X } from \"lucide-react\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getShadowClass } from \"../../tokens/shadows\";\nimport { getZIndexClass } from \"../../tokens/z-index\";\nimport { getAnimationClass } from \"../../tokens/animations\";\nimport {\n getTypographySize,\n getTypographyWeight,\n} from \"../../tokens/typography\";\nimport { useFocusRestore } from \"../../hooks/useFocusRestore\";\nimport Button from \"../../primitives/Button/Button\";\n\nexport type PopoverPlacement =\n | \"top\"\n | \"top-start\"\n | \"top-end\"\n | \"bottom\"\n | \"bottom-start\"\n | \"bottom-end\"\n | \"left\"\n | \"left-start\"\n | \"left-end\"\n | \"right\"\n | \"right-start\"\n | \"right-end\";\n\nexport interface PopoverProps {\n trigger: ReactNode;\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n placement?: PopoverPlacement;\n showCloseButton?: boolean;\n title?: string;\n closeOnClickOutside?: boolean;\n closeOnEscape?: boolean;\n className?: string;\n triggerClassName?: string;\n contentClassName?: string;\n}\n\n/**\n * Popover Component\n *\n * A popover component that displays content in a floating panel.\n * Supports positioning, portal rendering, and keyboard navigation.\n * Follows Atomic Design principles as an Atom component.\n *\n * @example\n * ```tsx\n * <Popover\n * trigger={<Button>Open Popover</Button>}\n * title=\"Popover Title\"\n * >\n * <p>Popover content goes here</p>\n * </Popover>\n * ```\n */\nexport default function Popover({\n trigger,\n children,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n placement = \"bottom\",\n showCloseButton = false,\n title,\n closeOnClickOutside = true,\n closeOnEscape = true,\n className = \"\",\n triggerClassName = \"\",\n contentClassName = \"\",\n}: PopoverProps) {\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const triggerRef = useRef<HTMLDivElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const [position, setPosition] = useState({ top: 0, left: 0 });\n const titleId = useId();\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n // Non-modal focus contract: restore only. Popover is explicitly\n // non-modal (aria-modal=\"false\" below), so per the WAI-ARIA disclosure\n // pattern it does NOT trap focus and does NOT auto-focus on open.\n // Users tab THROUGH the trigger / panel naturally. The single\n // obligation it does carry: when the panel closes (Escape,\n // click-outside, programmatic), focus should return to whatever had\n // it before the panel opened — typically the trigger button — so the\n // keyboard user is not stranded.\n //\n // Trigger-ref-free by design: `useFocusRestore` snapshots\n // `document.activeElement` at open time, which captures the trigger\n // wrapper or any other element that opened the popover. Avoids\n // coupling restore to a specific `triggerRef`, leaves room for\n // programmatic opens (notifications, kebab menus that reopen on\n // focus event, etc.).\n useFocusRestore(isOpen);\n\n const updatePosition = useCallback(() => {\n if (!triggerRef.current || !popoverRef.current) return;\n\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const popoverRect = popoverRef.current.getBoundingClientRect();\n const scrollY = window.scrollY;\n const scrollX = window.scrollX;\n\n let top = 0;\n let left = 0;\n\n // Calculate position based on placement\n if (placement.startsWith(\"top\")) {\n top = triggerRect.top + scrollY - popoverRect.height - 8;\n if (placement === \"top-start\") left = triggerRect.left + scrollX;\n else if (placement === \"top-end\")\n left = triggerRect.right + scrollX - popoverRect.width;\n else\n left =\n triggerRect.left +\n scrollX +\n (triggerRect.width - popoverRect.width) / 2;\n } else if (placement.startsWith(\"bottom\")) {\n top = triggerRect.bottom + scrollY + 8;\n if (placement === \"bottom-start\") left = triggerRect.left + scrollX;\n else if (placement === \"bottom-end\")\n left = triggerRect.right + scrollX - popoverRect.width;\n else\n left =\n triggerRect.left +\n scrollX +\n (triggerRect.width - popoverRect.width) / 2;\n } else if (placement.startsWith(\"left\")) {\n left = triggerRect.left + scrollX - popoverRect.width - 8;\n if (placement === \"left-start\") top = triggerRect.top + scrollY;\n else if (placement === \"left-end\")\n top = triggerRect.bottom + scrollY - popoverRect.height;\n else\n top =\n triggerRect.top +\n scrollY +\n (triggerRect.height - popoverRect.height) / 2;\n } else if (placement.startsWith(\"right\")) {\n left = triggerRect.right + scrollX + 8;\n if (placement === \"right-start\") top = triggerRect.top + scrollY;\n else if (placement === \"right-end\")\n top = triggerRect.bottom + scrollY - popoverRect.height;\n else\n top =\n triggerRect.top +\n scrollY +\n (triggerRect.height - popoverRect.height) / 2;\n }\n\n // Keep within viewport\n const padding = 8;\n top = Math.max(\n padding,\n Math.min(\n top,\n window.innerHeight + scrollY - popoverRect.height - padding,\n ),\n );\n left = Math.max(\n padding,\n Math.min(left, window.innerWidth + scrollX - popoverRect.width - padding),\n );\n\n setPosition({ top, left });\n }, [placement]);\n\n useEffect(() => {\n if (isOpen) {\n updatePosition();\n const handleResize = () => updatePosition();\n const handleScroll = () => updatePosition();\n window.addEventListener(\"resize\", handleResize);\n window.addEventListener(\"scroll\", handleScroll, true);\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n window.removeEventListener(\"scroll\", handleScroll, true);\n };\n }\n }, [isOpen, placement, updatePosition]);\n\n useEffect(() => {\n if (isOpen && popoverRef.current) {\n // Small delay to ensure DOM is ready\n setTimeout(updatePosition, 0);\n }\n }, [isOpen, updatePosition]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n if (!isControlled) {\n setInternalOpen(newOpen);\n }\n onOpenChange?.(newOpen);\n },\n [isControlled, onOpenChange],\n );\n\n const handleClose = useCallback(() => {\n handleOpenChange(false);\n }, [handleOpenChange]);\n\n useEffect(() => {\n if (isOpen && closeOnEscape) {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleEscape);\n return () => document.removeEventListener(\"keydown\", handleEscape);\n }\n }, [isOpen, closeOnEscape, handleClose]);\n\n useEffect(() => {\n if (isOpen && closeOnClickOutside) {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n popoverRef.current &&\n triggerRef.current &&\n !popoverRef.current.contains(e.target as Node) &&\n !triggerRef.current.contains(e.target as Node)\n ) {\n handleClose();\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () =>\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }\n }, [isOpen, closeOnClickOutside, handleClose]);\n\n const popoverContent = isOpen ? (\n <div\n ref={popoverRef}\n className={`\n absolute\n ${getZIndexClass(\"popover\")}\n bg-surface-overlay\n ${getRadiusClass(\"lg\")}\n ${getShadowClass(\"lg\")}\n border\n border-line-default\n min-w-48\n max-w-96\n ${getAnimationClass(\"base\")}\n ${contentClassName}\n `}\n style={{\n top: `${position.top}px`,\n left: `${position.left}px`,\n }}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={title ? titleId : undefined}\n >\n {(title || showCloseButton) && (\n <div\n className={`\n flex\n items-center\n justify-between\n ${getSpacingClass(\"base\", \"px\")}\n ${getSpacingClass(\"md\", \"py\")}\n border-b\n border-line-default\n `}\n >\n {title && (\n <h3\n id={titleId}\n className={`${getTypographySize(\"bodySmall\")} ${getTypographyWeight(\"h5\")} text-fg-primary`}\n >\n {title}\n </h3>\n )}\n {showCloseButton && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleClose}\n className={`h-auto ${getSpacingClass(\"xs\", \"p\")}`}\n aria-label=\"Close popover\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n )}\n <div\n className={`\n ${getSpacingClass(\"base\", \"p\")}\n ${title || showCloseButton ? \"\" : getSpacingClass(\"md\", \"p\")}\n `}\n >\n {children}\n </div>\n </div>\n ) : null;\n\n return (\n <div className={`inline-block ${className}`}>\n <div\n ref={triggerRef}\n className={triggerClassName}\n onClick={() => handleOpenChange(!isOpen)}\n >\n {trigger}\n </div>\n {typeof window !== \"undefined\" &&\n createPortal(popoverContent, document.body)}\n </div>\n );\n}\n"],"names":["Popover","trigger","children","controlledOpen","defaultOpen","onOpenChange","placement","showCloseButton","title","closeOnClickOutside","closeOnEscape","className","triggerClassName","contentClassName","internalOpen","setInternalOpen","useState","triggerRef","useRef","popoverRef","position","setPosition","titleId","useId","isControlled","isOpen","useFocusRestore","updatePosition","useCallback","triggerRect","popoverRect","scrollY","scrollX","top","left","padding","useEffect","handleResize","handleScroll","handleOpenChange","newOpen","handleClose","handleEscape","handleClickOutside","popoverContent","jsxs","getZIndexClass","getRadiusClass","getShadowClass","getAnimationClass","getSpacingClass","jsx","getTypographySize","getTypographyWeight","Button","X","createPortal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Popover.js","sources":["../../../../../src/ui/components/Popover/Popover.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useState,\n useRef,\n useEffect,\n useCallback,\n useId,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { X } from \"lucide-react\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getShadowClass } from \"../../tokens/shadows\";\nimport { getZIndexClass } from \"../../tokens/z-index\";\nimport { getAnimationClass } from \"../../tokens/animations\";\nimport {\n getTypographySize,\n getTypographyWeight,\n} from \"../../tokens/typography\";\nimport { useFocusRestore } from \"../../hooks/useFocusRestore\";\nimport Button from \"../../primitives/Button/Button\";\n\nexport type PopoverPlacement =\n | \"top\"\n | \"top-start\"\n | \"top-end\"\n | \"bottom\"\n | \"bottom-start\"\n | \"bottom-end\"\n | \"left\"\n | \"left-start\"\n | \"left-end\"\n | \"right\"\n | \"right-start\"\n | \"right-end\";\n\nexport interface PopoverProps {\n trigger: ReactNode;\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n placement?: PopoverPlacement;\n showCloseButton?: boolean;\n title?: string;\n closeOnClickOutside?: boolean;\n closeOnEscape?: boolean;\n className?: string;\n triggerClassName?: string;\n contentClassName?: string;\n}\n\n/**\n * Popover Component\n *\n * A popover component that displays content in a floating panel.\n * Supports positioning, portal rendering, and keyboard navigation.\n *\n * @example\n * ```tsx\n * <Popover\n * trigger={<Button>Open Popover</Button>}\n * title=\"Popover Title\"\n * >\n * <p>Popover content goes here</p>\n * </Popover>\n * ```\n */\nexport default function Popover({\n trigger,\n children,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n placement = \"bottom\",\n showCloseButton = false,\n title,\n closeOnClickOutside = true,\n closeOnEscape = true,\n className = \"\",\n triggerClassName = \"\",\n contentClassName = \"\",\n}: PopoverProps) {\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const triggerRef = useRef<HTMLDivElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const [position, setPosition] = useState({ top: 0, left: 0 });\n const titleId = useId();\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n // Non-modal focus contract: restore only. Popover is explicitly\n // non-modal (aria-modal=\"false\" below), so per the WAI-ARIA disclosure\n // pattern it does NOT trap focus and does NOT auto-focus on open.\n // Users tab THROUGH the trigger / panel naturally. The single\n // obligation it does carry: when the panel closes (Escape,\n // click-outside, programmatic), focus should return to whatever had\n // it before the panel opened — typically the trigger button — so the\n // keyboard user is not stranded.\n //\n // Trigger-ref-free by design: `useFocusRestore` snapshots\n // `document.activeElement` at open time, which captures the trigger\n // wrapper or any other element that opened the popover. Avoids\n // coupling restore to a specific `triggerRef`, leaves room for\n // programmatic opens (notifications, kebab menus that reopen on\n // focus event, etc.).\n useFocusRestore(isOpen);\n\n const updatePosition = useCallback(() => {\n if (!triggerRef.current || !popoverRef.current) return;\n\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const popoverRect = popoverRef.current.getBoundingClientRect();\n const scrollY = window.scrollY;\n const scrollX = window.scrollX;\n\n let top = 0;\n let left = 0;\n\n // Calculate position based on placement\n if (placement.startsWith(\"top\")) {\n top = triggerRect.top + scrollY - popoverRect.height - 8;\n if (placement === \"top-start\") left = triggerRect.left + scrollX;\n else if (placement === \"top-end\")\n left = triggerRect.right + scrollX - popoverRect.width;\n else\n left =\n triggerRect.left +\n scrollX +\n (triggerRect.width - popoverRect.width) / 2;\n } else if (placement.startsWith(\"bottom\")) {\n top = triggerRect.bottom + scrollY + 8;\n if (placement === \"bottom-start\") left = triggerRect.left + scrollX;\n else if (placement === \"bottom-end\")\n left = triggerRect.right + scrollX - popoverRect.width;\n else\n left =\n triggerRect.left +\n scrollX +\n (triggerRect.width - popoverRect.width) / 2;\n } else if (placement.startsWith(\"left\")) {\n left = triggerRect.left + scrollX - popoverRect.width - 8;\n if (placement === \"left-start\") top = triggerRect.top + scrollY;\n else if (placement === \"left-end\")\n top = triggerRect.bottom + scrollY - popoverRect.height;\n else\n top =\n triggerRect.top +\n scrollY +\n (triggerRect.height - popoverRect.height) / 2;\n } else if (placement.startsWith(\"right\")) {\n left = triggerRect.right + scrollX + 8;\n if (placement === \"right-start\") top = triggerRect.top + scrollY;\n else if (placement === \"right-end\")\n top = triggerRect.bottom + scrollY - popoverRect.height;\n else\n top =\n triggerRect.top +\n scrollY +\n (triggerRect.height - popoverRect.height) / 2;\n }\n\n // Keep within viewport\n const padding = 8;\n top = Math.max(\n padding,\n Math.min(\n top,\n window.innerHeight + scrollY - popoverRect.height - padding,\n ),\n );\n left = Math.max(\n padding,\n Math.min(left, window.innerWidth + scrollX - popoverRect.width - padding),\n );\n\n setPosition({ top, left });\n }, [placement]);\n\n useEffect(() => {\n if (isOpen) {\n updatePosition();\n const handleResize = () => updatePosition();\n const handleScroll = () => updatePosition();\n window.addEventListener(\"resize\", handleResize);\n window.addEventListener(\"scroll\", handleScroll, true);\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n window.removeEventListener(\"scroll\", handleScroll, true);\n };\n }\n }, [isOpen, placement, updatePosition]);\n\n useEffect(() => {\n if (isOpen && popoverRef.current) {\n // Small delay to ensure DOM is ready\n setTimeout(updatePosition, 0);\n }\n }, [isOpen, updatePosition]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n if (!isControlled) {\n setInternalOpen(newOpen);\n }\n onOpenChange?.(newOpen);\n },\n [isControlled, onOpenChange],\n );\n\n const handleClose = useCallback(() => {\n handleOpenChange(false);\n }, [handleOpenChange]);\n\n useEffect(() => {\n if (isOpen && closeOnEscape) {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleEscape);\n return () => document.removeEventListener(\"keydown\", handleEscape);\n }\n }, [isOpen, closeOnEscape, handleClose]);\n\n useEffect(() => {\n if (isOpen && closeOnClickOutside) {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n popoverRef.current &&\n triggerRef.current &&\n !popoverRef.current.contains(e.target as Node) &&\n !triggerRef.current.contains(e.target as Node)\n ) {\n handleClose();\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () =>\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }\n }, [isOpen, closeOnClickOutside, handleClose]);\n\n const popoverContent = isOpen ? (\n <div\n ref={popoverRef}\n className={`\n absolute\n ${getZIndexClass(\"popover\")}\n bg-surface-overlay\n ${getRadiusClass(\"lg\")}\n ${getShadowClass(\"lg\")}\n border\n border-line-default\n min-w-48\n max-w-96\n ${getAnimationClass(\"base\")}\n ${contentClassName}\n `}\n style={{\n top: `${position.top}px`,\n left: `${position.left}px`,\n }}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={title ? titleId : undefined}\n >\n {(title || showCloseButton) && (\n <div\n className={`\n flex\n items-center\n justify-between\n ${getSpacingClass(\"base\", \"px\")}\n ${getSpacingClass(\"md\", \"py\")}\n border-b\n border-line-default\n `}\n >\n {title && (\n <h3\n id={titleId}\n className={`${getTypographySize(\"bodySmall\")} ${getTypographyWeight(\"h5\")} text-fg-primary`}\n >\n {title}\n </h3>\n )}\n {showCloseButton && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleClose}\n className={`h-auto ${getSpacingClass(\"xs\", \"p\")}`}\n aria-label=\"Close popover\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n )}\n <div\n className={`\n ${getSpacingClass(\"base\", \"p\")}\n ${title || showCloseButton ? \"\" : getSpacingClass(\"md\", \"p\")}\n `}\n >\n {children}\n </div>\n </div>\n ) : null;\n\n return (\n <div className={`inline-block ${className}`}>\n <div\n ref={triggerRef}\n className={triggerClassName}\n onClick={() => handleOpenChange(!isOpen)}\n >\n {trigger}\n </div>\n {typeof window !== \"undefined\" &&\n createPortal(popoverContent, document.body)}\n </div>\n );\n}\n"],"names":["Popover","trigger","children","controlledOpen","defaultOpen","onOpenChange","placement","showCloseButton","title","closeOnClickOutside","closeOnEscape","className","triggerClassName","contentClassName","internalOpen","setInternalOpen","useState","triggerRef","useRef","popoverRef","position","setPosition","titleId","useId","isControlled","isOpen","useFocusRestore","updatePosition","useCallback","triggerRect","popoverRect","scrollY","scrollX","top","left","padding","useEffect","handleResize","handleScroll","handleOpenChange","newOpen","handleClose","handleEscape","handleClickOutside","popoverContent","jsxs","getZIndexClass","getRadiusClass","getShadowClass","getAnimationClass","getSpacingClass","jsx","getTypographySize","getTypographyWeight","Button","X","createPortal"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rating.js","sources":["../../../../../src/ui/components/Rating/Rating.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ReactNode } from \"react\";\nimport { Star } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport {\n getSpacingClass,\n getAnimationClass,\n getTypographySizeFromFontSize,\n} from \"../../tokens\";\n\nexport type RatingSize = \"sm\" | \"md\" | \"lg\";\nexport type RatingVariant = \"filled\" | \"outlined\";\n\nexport interface RatingProps {\n value?: number;\n defaultValue?: number;\n max?: number;\n size?: RatingSize;\n variant?: RatingVariant;\n readOnly?: boolean;\n allowHalf?: boolean;\n showValue?: boolean;\n onChange?: (value: number) => void;\n onHover?: (value: number) => void;\n className?: string;\n icon?: ReactNode;\n emptyIcon?: ReactNode;\n}\n\n/**\n * Rating Component\n *\n * A rating component for displaying and selecting ratings.\n * Supports filled and outlined variants, half ratings, and read-only mode.\n
|
|
1
|
+
{"version":3,"file":"Rating.js","sources":["../../../../../src/ui/components/Rating/Rating.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ReactNode } from \"react\";\nimport { Star } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport {\n getSpacingClass,\n getAnimationClass,\n getTypographySizeFromFontSize,\n} from \"../../tokens\";\n\nexport type RatingSize = \"sm\" | \"md\" | \"lg\";\nexport type RatingVariant = \"filled\" | \"outlined\";\n\nexport interface RatingProps {\n value?: number;\n defaultValue?: number;\n max?: number;\n size?: RatingSize;\n variant?: RatingVariant;\n readOnly?: boolean;\n allowHalf?: boolean;\n showValue?: boolean;\n onChange?: (value: number) => void;\n onHover?: (value: number) => void;\n className?: string;\n icon?: ReactNode;\n emptyIcon?: ReactNode;\n}\n\n/**\n * Rating Component\n *\n * A rating component for displaying and selecting ratings.\n * Supports filled and outlined variants, half ratings, and read-only mode.\n *\n * @example\n * ```tsx\n * <Rating value={4} max={5} onChange={(value) => console.log(value)} />\n *\n * <Rating value={3.5} readOnly showValue />\n * ```\n */\nexport default function Rating({\n value: controlledValue,\n defaultValue = 0,\n max = 5,\n size = \"md\",\n variant = \"filled\",\n readOnly = false,\n allowHalf = false,\n showValue = false,\n onChange,\n onHover,\n className = \"\",\n icon,\n emptyIcon,\n}: RatingProps) {\n const [internalValue, setInternalValue] = useState(defaultValue);\n const [hoverValue, setHoverValue] = useState<number | null>(null);\n\n const isControlled = controlledValue !== undefined;\n const displayValue =\n hoverValue ?? (isControlled ? controlledValue : internalValue);\n\n const sizeConfig = {\n sm: \"h-4 w-4\",\n md: \"h-5 w-5\",\n lg: \"h-6 w-6\",\n };\n\n const handleClick = (newValue: number) => {\n if (readOnly) return;\n\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n };\n\n const handleMouseEnter = (newValue: number) => {\n if (readOnly) return;\n setHoverValue(newValue);\n onHover?.(newValue);\n };\n\n const handleMouseLeave = () => {\n if (readOnly) return;\n setHoverValue(null);\n };\n\n const renderStar = (index: number) => {\n const starValue = index + 1;\n const isHalf =\n allowHalf && displayValue >= starValue - 0.5 && displayValue < starValue;\n const isFilled = displayValue >= starValue;\n\n const starClasses = cn(\n sizeConfig[size],\n getAnimationClass(\"base\"),\n !readOnly && \"cursor-pointer\",\n isFilled || isHalf ? \"text-fg-warning\" : \"text-fg-disabled\",\n );\n\n const CustomIcon = icon || (\n <Star className={starClasses} fill={isFilled ? \"currentColor\" : \"none\"} />\n );\n const CustomEmptyIcon = emptyIcon || (\n <Star className={starClasses} fill=\"none\" />\n );\n\n return (\n <span\n key={index}\n className=\"relative inline-block\"\n onClick={() => handleClick(starValue)}\n onMouseEnter={() => handleMouseEnter(starValue)}\n onMouseLeave={handleMouseLeave}\n role={readOnly ? undefined : \"button\"}\n tabIndex={readOnly ? undefined : 0}\n aria-label={readOnly ? undefined : `Rate ${starValue} out of ${max}`}\n onKeyDown={(e) => {\n if (!readOnly && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n handleClick(starValue);\n }\n }}\n >\n {isHalf ? (\n <span className=\"relative inline-block\">\n <span\n className=\"absolute inset-0 overflow-hidden\"\n style={{ width: \"50%\" }}\n >\n {variant === \"filled\" ? (\n <Star className={starClasses} fill=\"currentColor\" />\n ) : (\n CustomIcon\n )}\n </span>\n {variant === \"filled\" ? (\n <Star className={starClasses} fill=\"none\" />\n ) : (\n CustomEmptyIcon\n )}\n </span>\n ) : isFilled ? (\n variant === \"filled\" ? (\n <Star className={starClasses} fill=\"currentColor\" />\n ) : (\n CustomIcon\n )\n ) : variant === \"filled\" ? (\n <Star className={starClasses} fill=\"none\" />\n ) : (\n CustomEmptyIcon\n )}\n </span>\n );\n };\n\n return (\n <div\n className={cn(\n \"inline-flex\",\n \"items-center\",\n getSpacingClass(\"xs\", \"gap\"),\n className,\n )}\n >\n <div\n className={cn(\"flex\", \"items-center\")}\n role={readOnly ? \"img\" : undefined}\n aria-label={\n readOnly ? `Rating: ${displayValue} out of ${max}` : undefined\n }\n >\n {Array.from({ length: max }, (_, i) => renderStar(i))}\n </div>\n {showValue && (\n <span\n className={cn(\n getSpacingClass(\"sm\", \"ml\"),\n getTypographySizeFromFontSize(\"sm\"),\n \"text-fg-secondary\",\n )}\n >\n {displayValue.toFixed(allowHalf ? 1 : 0)}/{max}\n </span>\n )}\n </div>\n );\n}\n"],"names":["Rating","controlledValue","defaultValue","max","size","variant","readOnly","allowHalf","showValue","onChange","onHover","className","icon","emptyIcon","internalValue","setInternalValue","useState","hoverValue","setHoverValue","isControlled","displayValue","sizeConfig","handleClick","newValue","handleMouseEnter","handleMouseLeave","renderStar","index","starValue","isHalf","isFilled","starClasses","cn","getAnimationClass","CustomIcon","jsx","Star","CustomEmptyIcon","e","jsxs","getSpacingClass","_","i","getTypographySizeFromFontSize"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchInput.js","sources":["../../../../../src/ui/components/SearchInput/SearchInput.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, forwardRef } from \"react\";\nimport type { InputHTMLAttributes } from \"react\";\nimport { Search, X } from \"lucide-react\";\nimport Input from \"../../primitives/Input/Input\";\nimport Button from \"../../primitives/Button/Button\";\nimport { cn } from \"../../utils\";\nimport { getSpacingClass } from \"../../tokens\";\n\nexport interface SearchInputProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> {\n onSearch?: (value: string) => void;\n onClear?: () => void;\n loading?: boolean;\n showClearButton?: boolean;\n debounceMs?: number;\n}\n\n/**\n * SearchInput Component\n *\n * A search input component with icon, clear button, and loading state.\n
|
|
1
|
+
{"version":3,"file":"SearchInput.js","sources":["../../../../../src/ui/components/SearchInput/SearchInput.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, forwardRef } from \"react\";\nimport type { InputHTMLAttributes } from \"react\";\nimport { Search, X } from \"lucide-react\";\nimport Input from \"../../primitives/Input/Input\";\nimport Button from \"../../primitives/Button/Button\";\nimport { cn } from \"../../utils\";\nimport { getSpacingClass } from \"../../tokens\";\n\nexport interface SearchInputProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> {\n onSearch?: (value: string) => void;\n onClear?: () => void;\n loading?: boolean;\n showClearButton?: boolean;\n debounceMs?: number;\n}\n\n/**\n * SearchInput Component\n *\n * A search input component with icon, clear button, and loading state.\n *\n * @example\n * ```tsx\n * <SearchInput\n * placeholder=\"Search...\"\n * onSearch={(value) => console.log(value)}\n * />\n * ```\n */\nconst SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(\n function SearchInput(\n {\n onSearch,\n onClear,\n loading = false,\n showClearButton = true,\n debounceMs = 300,\n value: controlledValue,\n defaultValue,\n onChange,\n className = \"\",\n ...props\n },\n ref,\n ) {\n const [internalValue, setInternalValue] = useState<string>(\n typeof defaultValue === \"string\" ? defaultValue : \"\",\n );\n const [debounceTimer, setDebounceTimer] = useState<ReturnType<\n typeof setTimeout\n > | null>(null);\n\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n const hasValue =\n currentValue !== undefined &&\n currentValue !== null &&\n String(currentValue).length > 0;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n\n if (!isControlled) {\n setInternalValue(newValue);\n }\n\n onChange?.(e);\n\n // Debounce search\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n const timer = setTimeout(() => {\n onSearch?.(newValue);\n }, debounceMs);\n\n setDebounceTimer(timer);\n };\n\n const handleClear = () => {\n if (!isControlled) {\n setInternalValue(\"\");\n }\n\n // Create synthetic event for onChange\n const syntheticEvent = {\n target: { value: \"\" },\n currentTarget: { value: \"\" },\n } as React.ChangeEvent<HTMLInputElement>;\n onChange?.(syntheticEvent);\n\n onClear?.();\n onSearch?.(\"\");\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\" && onSearch) {\n onSearch(String(currentValue || \"\"));\n }\n props.onKeyDown?.(e);\n };\n\n return (\n <div className={cn(\"relative\", className)}>\n <Input\n ref={ref}\n {...props}\n type=\"search\"\n value={currentValue}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n leftIcon={\n loading ? (\n <div className=\"animate-spin\">\n <Search className=\"h-4 w-4\" />\n </div>\n ) : (\n <Search className=\"h-4 w-4\" />\n )\n }\n rightIcon={\n showClearButton && hasValue && !loading ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleClear}\n className={`h-auto ${getSpacingClass(\"xs\", \"p\")}`}\n aria-label=\"Clear search\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n ) : undefined\n }\n className={cn(getSpacingClass(\"lg\", \"pr\"))}\n />\n </div>\n );\n },\n);\n\nSearchInput.displayName = \"SearchInput\";\n\nexport default SearchInput;\n"],"names":["SearchInput","forwardRef","_a","ref","_b","onSearch","onClear","loading","showClearButton","debounceMs","controlledValue","defaultValue","onChange","className","props","__objRest","internalValue","setInternalValue","useState","debounceTimer","setDebounceTimer","isControlled","currentValue","hasValue","handleChange","e","newValue","timer","handleClear","syntheticEvent","handleKeyDown","cn","jsx","Input","__spreadProps","__spreadValues","Search","Button","getSpacingClass","X"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAMA,IAAcC;AAAA,EAClB,SACEC,GAYAC,GACA;AAbA,QAAAC,IAAAF,GACE;AAAA,gBAAAG;AAAA,MACA,SAAAC;AAAA,MACA,SAAAC,IAAU;AAAA,MACV,iBAAAC,IAAkB;AAAA,MAClB,YAAAC,IAAa;AAAA,MACb,OAAOC;AAAA,MACP,cAAAC;AAAA,MACA,UAAAC;AAAA,MACA,WAAAC,IAAY;AAAA,QATdT,GAUKU,IAAAC,EAVLX,GAUK;AAAA,MATH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAKF,UAAM,CAACY,GAAeC,CAAgB,IAAIC;AAAA,MACxC,OAAOP,KAAiB,WAAWA,IAAe;AAAA,IAAA,GAE9C,CAACQ,GAAeC,CAAgB,IAAIF,EAEhC,IAAI,GAERG,IAAeX,MAAoB,QACnCY,IAAeD,IAAeX,IAAkBM,GAChDO,IAEJD,KAAiB,QACjB,OAAOA,CAAY,EAAE,SAAS,GAE1BE,IAAe,CAACC,MAA2C;AAC/D,YAAMC,IAAWD,EAAE,OAAO;AAE1B,MAAKJ,KACHJ,EAAiBS,CAAQ,GAG3Bd,KAAA,QAAAA,EAAWa,IAGPN,KACF,aAAaA,CAAa;AAG5B,YAAMQ,IAAQ,WAAW,MAAM;AAC7B,QAAAtB,KAAA,QAAAA,EAAWqB;AAAA,MACb,GAAGjB,CAAU;AAEb,MAAAW,EAAiBO,CAAK;AAAA,IACxB,GAEMC,IAAc,MAAM;AACxB,MAAKP,KACHJ,EAAiB,EAAE;AAIrB,YAAMY,IAAiB;AAAA,QACrB,QAAQ,EAAE,OAAO,GAAA;AAAA,QACjB,eAAe,EAAE,OAAO,GAAA;AAAA,MAAG;AAE7B,MAAAjB,KAAA,QAAAA,EAAWiB,IAEXvB,KAAA,QAAAA,KACAD,KAAA,QAAAA,EAAW;AAAA,IACb,GAEMyB,IAAgB,CAACL,MAA6C;;AAClE,MAAIA,EAAE,QAAQ,WAAWpB,KACvBA,EAAS,OAAOiB,KAAgB,EAAE,CAAC,IAErCpB,IAAAY,EAAM,cAAN,QAAAZ,EAAA,KAAAY,GAAkBW;AAAA,IACpB;AAEA,6BACG,OAAA,EAAI,WAAWM,EAAG,YAAYlB,CAAS,GACtC,UAAA,gBAAAmB;AAAA,MAACC;AAAA,MAAAC,EAAAC,EAAA;AAAA,QACC,KAAAhC;AAAA,SACIW,IAFL;AAAA,QAGC,MAAK;AAAA,QACL,OAAOQ;AAAA,QACP,UAAUE;AAAA,QACV,WAAWM;AAAA,QACX,UACEvB,IACE,gBAAAyB,EAAC,OAAA,EAAI,WAAU,gBACb,UAAA,gBAAAA,EAACI,GAAA,EAAO,WAAU,WAAU,GAC9B,IAEA,gBAAAJ,EAACI,GAAA,EAAO,WAAU,WAAU;AAAA,QAGhC,WACE5B,KAAmBe,KAAY,CAAChB,IAC9B,gBAAAyB;AAAA,UAACK;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAST;AAAA,YACT,WAAW,UAAUU,EAAgB,MAAM,GAAG,CAAC;AAAA,YAC/C,cAAW;AAAA,YAEX,UAAA,gBAAAN,EAACO,GAAA,EAAE,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA,IAEvB;AAAA,QAEN,WAAWR,EAAGO,EAAgB,MAAM,IAAI,CAAC;AAAA,MAAA;AAAA,IAAA,GAE7C;AAAA,EAEJ;AACF;AAEAtC,EAAY,cAAc;"}
|
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var f = Object.prototype.hasOwnProperty,
|
|
6
|
-
var
|
|
7
|
-
for (var
|
|
8
|
-
f.call(
|
|
9
|
-
if (
|
|
10
|
-
for (var
|
|
11
|
-
|
|
2
|
+
var k = Object.defineProperty, b = Object.defineProperties;
|
|
3
|
+
var I = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var i = Object.getOwnPropertySymbols;
|
|
5
|
+
var f = Object.prototype.hasOwnProperty, x = Object.prototype.propertyIsEnumerable;
|
|
6
|
+
var d = (e, t, s) => t in e ? k(e, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : e[t] = s, h = (e, t) => {
|
|
7
|
+
for (var s in t || (t = {}))
|
|
8
|
+
f.call(t, s) && d(e, s, t[s]);
|
|
9
|
+
if (i)
|
|
10
|
+
for (var s of i(t))
|
|
11
|
+
x.call(t, s) && d(e, s, t[s]);
|
|
12
12
|
return e;
|
|
13
|
-
},
|
|
14
|
-
var
|
|
15
|
-
var
|
|
16
|
-
for (var
|
|
17
|
-
f.call(e,
|
|
18
|
-
if (e != null &&
|
|
19
|
-
for (var
|
|
20
|
-
|
|
21
|
-
return
|
|
13
|
+
}, u = (e, t) => b(e, I(t));
|
|
14
|
+
var g = (e, t) => {
|
|
15
|
+
var s = {};
|
|
16
|
+
for (var r in e)
|
|
17
|
+
f.call(e, r) && t.indexOf(r) < 0 && (s[r] = e[r]);
|
|
18
|
+
if (e != null && i)
|
|
19
|
+
for (var r of i(e))
|
|
20
|
+
t.indexOf(r) < 0 && x.call(e, r) && (s[r] = e[r]);
|
|
21
|
+
return s;
|
|
22
22
|
};
|
|
23
|
-
import { jsxs as v, jsx as
|
|
24
|
-
import { useState as j } from "react";
|
|
25
|
-
import { ChevronRight as
|
|
23
|
+
import { jsxs as v, jsx as n } from "react/jsx-runtime";
|
|
24
|
+
import { useState as j, useId as S } from "react";
|
|
25
|
+
import { ChevronRight as $, ChevronDown as D } from "lucide-react";
|
|
26
26
|
import { getSpacingClass as a } from "../../../../tokens/spacing.js";
|
|
27
|
-
import { cn as
|
|
28
|
-
function
|
|
29
|
-
var
|
|
27
|
+
import { cn as l } from "../../../../utils/cn.js";
|
|
28
|
+
function F(G) {
|
|
29
|
+
var c = G, {
|
|
30
30
|
id: e,
|
|
31
|
-
label:
|
|
32
|
-
collapsible:
|
|
33
|
-
defaultCollapsed:
|
|
34
|
-
children:
|
|
35
|
-
className:
|
|
36
|
-
} =
|
|
31
|
+
label: t,
|
|
32
|
+
collapsible: s = !1,
|
|
33
|
+
defaultCollapsed: r = !1,
|
|
34
|
+
children: N,
|
|
35
|
+
className: y
|
|
36
|
+
} = c, C = g(c, [
|
|
37
37
|
"id",
|
|
38
38
|
"label",
|
|
39
39
|
"collapsible",
|
|
@@ -41,47 +41,65 @@ function B(G) {
|
|
|
41
41
|
"children",
|
|
42
42
|
"className"
|
|
43
43
|
]);
|
|
44
|
-
const [
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
const [o, w] = j(r), p = `navbar-group-${S()}`, m = /* @__PURE__ */ v("span", { className: l("flex items-center", a("1.5", "gap")), children: [
|
|
45
|
+
s && /* @__PURE__ */ n("span", { className: "shrink-0", children: o ? /* @__PURE__ */ n(
|
|
46
|
+
$,
|
|
47
|
+
{
|
|
48
|
+
className: "w-3 h-3",
|
|
49
|
+
style: { transition: "none", transform: "none" }
|
|
50
|
+
}
|
|
51
|
+
) : /* @__PURE__ */ n(
|
|
52
|
+
D,
|
|
53
|
+
{
|
|
54
|
+
className: "w-3 h-3",
|
|
55
|
+
style: { transition: "none", transform: "none" }
|
|
56
|
+
}
|
|
57
|
+
) }),
|
|
58
|
+
/* @__PURE__ */ n("span", { children: t })
|
|
59
|
+
] });
|
|
60
|
+
return /* @__PURE__ */ v("div", u(h({ id: e, className: l("flex flex-col", y) }, C), { children: [
|
|
61
|
+
t && (s ? (
|
|
62
|
+
// Collapsible header is a real button: keyboard operable
|
|
63
|
+
// (Enter/Space activate it natively) with disclosure ARIA. The
|
|
64
|
+
// old <div onClick> was unreachable by keyboard / unlabeled to AT.
|
|
65
|
+
/* @__PURE__ */ n(
|
|
66
|
+
"button",
|
|
67
|
+
{
|
|
68
|
+
type: "button",
|
|
69
|
+
onClick: () => w(!o),
|
|
70
|
+
"aria-expanded": !o,
|
|
71
|
+
"aria-controls": o ? void 0 : p,
|
|
72
|
+
className: l(
|
|
73
|
+
a("sm", "px"),
|
|
74
|
+
a("1.5", "py"),
|
|
75
|
+
"text-xs text-fg-tertiary uppercase tracking-wider",
|
|
76
|
+
"w-full text-left cursor-pointer hover:text-fg-secondary"
|
|
77
|
+
),
|
|
78
|
+
children: m
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
) : /* @__PURE__ */ n(
|
|
47
82
|
"div",
|
|
48
83
|
{
|
|
49
|
-
className:
|
|
84
|
+
className: l(
|
|
50
85
|
a("sm", "px"),
|
|
51
86
|
a("1.5", "py"),
|
|
52
|
-
"text-xs text-fg-tertiary uppercase tracking-wider"
|
|
53
|
-
r && "cursor-pointer hover:text-fg-secondary"
|
|
87
|
+
"text-xs text-fg-tertiary uppercase tracking-wider"
|
|
54
88
|
),
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
{
|
|
65
|
-
className: "w-3 h-3",
|
|
66
|
-
style: { transition: "none", transform: "none" }
|
|
67
|
-
}
|
|
68
|
-
) : /* @__PURE__ */ t(
|
|
69
|
-
D,
|
|
70
|
-
{
|
|
71
|
-
className: "w-3 h-3",
|
|
72
|
-
style: { transition: "none", transform: "none" }
|
|
73
|
-
}
|
|
74
|
-
) }),
|
|
75
|
-
/* @__PURE__ */ t("span", { children: s })
|
|
76
|
-
]
|
|
77
|
-
}
|
|
78
|
-
)
|
|
89
|
+
children: m
|
|
90
|
+
}
|
|
91
|
+
)),
|
|
92
|
+
!o && /* @__PURE__ */ n(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
id: p,
|
|
96
|
+
className: `flex flex-col ${a("sm", "gap")}`,
|
|
97
|
+
children: N
|
|
79
98
|
}
|
|
80
|
-
)
|
|
81
|
-
!i && /* @__PURE__ */ t("div", { className: `flex flex-col ${a("sm", "gap")}`, children: g })
|
|
99
|
+
)
|
|
82
100
|
] }));
|
|
83
101
|
}
|
|
84
102
|
export {
|
|
85
|
-
|
|
103
|
+
F as NavbarGroup
|
|
86
104
|
};
|
|
87
105
|
//# sourceMappingURL=NavbarGroup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavbarGroup.js","sources":["../../../../../../../src/ui/components/SideNavbar/components/Navbar/NavbarGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../../../../utils\";\nimport { getSpacingClass } from \"../../../../tokens/spacing\";\nimport type { NavbarGroupProps } from \"../../types\";\n\n/**\n * NavbarGroup Component\n *\n * Groups navbar items with optional label and collapsible behavior.\n *\n * @example\n * ```tsx\n * <SideNavbar.Navbar>\n * <SideNavbar.Navbar.Group label=\"Main\" collapsible>\n * <SideNavbar.Navbar.Item icon={<Home />} label=\"Home\" />\n * <SideNavbar.Navbar.Item icon={<Settings />} label=\"Settings\" />\n * </SideNavbar.Navbar.Group>\n * </SideNavbar.Navbar>\n * ```\n */\nexport function NavbarGroup({\n id,\n label,\n collapsible = false,\n defaultCollapsed = false,\n children,\n className,\n ...props\n}: NavbarGroupProps) {\n const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);\n
|
|
1
|
+
{"version":3,"file":"NavbarGroup.js","sources":["../../../../../../../src/ui/components/SideNavbar/components/Navbar/NavbarGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, useId } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../../../../utils\";\nimport { getSpacingClass } from \"../../../../tokens/spacing\";\nimport type { NavbarGroupProps } from \"../../types\";\n\n/**\n * NavbarGroup Component\n *\n * Groups navbar items with optional label and collapsible behavior.\n *\n * @example\n * ```tsx\n * <SideNavbar.Navbar>\n * <SideNavbar.Navbar.Group label=\"Main\" collapsible>\n * <SideNavbar.Navbar.Item icon={<Home />} label=\"Home\" />\n * <SideNavbar.Navbar.Item icon={<Settings />} label=\"Settings\" />\n * </SideNavbar.Navbar.Group>\n * </SideNavbar.Navbar>\n * ```\n */\nexport function NavbarGroup({\n id,\n label,\n collapsible = false,\n defaultCollapsed = false,\n children,\n className,\n ...props\n}: NavbarGroupProps) {\n const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);\n const panelId = `navbar-group-${useId()}`;\n\n // Shared label content (chevron + text) for both the static and the\n // collapsible-button renderings.\n const labelContent = (\n <span className={cn(\"flex items-center\", getSpacingClass(\"1.5\", \"gap\"))}>\n {collapsible && (\n <span className=\"shrink-0\">\n {isCollapsed ? (\n <ChevronRight\n className=\"w-3 h-3\"\n style={{ transition: \"none\", transform: \"none\" }}\n />\n ) : (\n <ChevronDown\n className=\"w-3 h-3\"\n style={{ transition: \"none\", transform: \"none\" }}\n />\n )}\n </span>\n )}\n <span>{label}</span>\n </span>\n );\n\n return (\n <div id={id} className={cn(\"flex flex-col\", className)} {...props}>\n {label &&\n (collapsible ? (\n // Collapsible header is a real button: keyboard operable\n // (Enter/Space activate it natively) with disclosure ARIA. The\n // old <div onClick> was unreachable by keyboard / unlabeled to AT.\n <button\n type=\"button\"\n onClick={() => setIsCollapsed(!isCollapsed)}\n aria-expanded={!isCollapsed}\n aria-controls={isCollapsed ? undefined : panelId}\n className={cn(\n getSpacingClass(\"sm\", \"px\"),\n getSpacingClass(\"1.5\", \"py\"),\n \"text-xs text-fg-tertiary uppercase tracking-wider\",\n \"w-full text-left cursor-pointer hover:text-fg-secondary\",\n )}\n >\n {labelContent}\n </button>\n ) : (\n <div\n className={cn(\n getSpacingClass(\"sm\", \"px\"),\n getSpacingClass(\"1.5\", \"py\"),\n \"text-xs text-fg-tertiary uppercase tracking-wider\",\n )}\n >\n {labelContent}\n </div>\n ))}\n {!isCollapsed && (\n <div\n id={panelId}\n className={`flex flex-col ${getSpacingClass(\"sm\", \"gap\")}`}\n >\n {children}\n </div>\n )}\n </div>\n );\n}\n"],"names":["NavbarGroup","_a","_b","id","label","collapsible","defaultCollapsed","children","className","props","__objRest","isCollapsed","setIsCollapsed","useState","panelId","useId","labelContent","jsxs","cn","getSpacingClass","jsx","ChevronRight","ChevronDown"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBO,SAASA,EAAYC,GAQP;AARO,MAAAC,IAAAD,GAC1B;AAAA,QAAAE;AAAA,IACA,OAAAC;AAAA,IACA,aAAAC,IAAc;AAAA,IACd,kBAAAC,IAAmB;AAAA,IACnB,UAAAC;AAAA,IACA,WAAAC;AAAA,MAN0BN,GAOvBO,IAAAC,EAPuBR,GAOvB;AAAA,IANH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAM,CAACS,GAAaC,CAAc,IAAIC,EAASP,CAAgB,GACzDQ,IAAU,gBAAgBC,EAAA,CAAO,IAIjCC,IACJ,gBAAAC,EAAC,QAAA,EAAK,WAAWC,EAAG,qBAAqBC,EAAgB,OAAO,KAAK,CAAC,GACnE,UAAA;AAAA,IAAAd,KACC,gBAAAe,EAAC,QAAA,EAAK,WAAU,YACb,UAAAT,IACC,gBAAAS;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,YAAY,QAAQ,WAAW,OAAA;AAAA,MAAO;AAAA,IAAA,IAGjD,gBAAAD;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,YAAY,QAAQ,WAAW,OAAA;AAAA,MAAO;AAAA,IAAA,GAGrD;AAAA,IAEF,gBAAAF,EAAC,UAAM,UAAAhB,EAAA,CAAM;AAAA,EAAA,GACf;AAGF,SACE,gBAAAa,EAAC,aAAI,IAAAd,GAAQ,WAAWe,EAAG,iBAAiBV,CAAS,KAAOC,MACzD,UAAA;AAAA,IAAAL,MACEC;AAAA;AAAA;AAAA;AAAA,MAIC,gBAAAe;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAMR,EAAe,CAACD,CAAW;AAAA,UAC1C,iBAAe,CAACA;AAAA,UAChB,iBAAeA,IAAc,SAAYG;AAAA,UACzC,WAAWI;AAAA,YACTC,EAAgB,MAAM,IAAI;AAAA,YAC1BA,EAAgB,OAAO,IAAI;AAAA,YAC3B;AAAA,YACA;AAAA,UAAA;AAAA,UAGD,UAAAH;AAAA,QAAA;AAAA,MAAA;AAAA,QAGH,gBAAAI;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWF;AAAA,UACTC,EAAgB,MAAM,IAAI;AAAA,UAC1BA,EAAgB,OAAO,IAAI;AAAA,UAC3B;AAAA,QAAA;AAAA,QAGD,UAAAH;AAAA,MAAA;AAAA,IAAA;AAAA,IAGN,CAACL,KACA,gBAAAS;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAIN;AAAA,QACJ,WAAW,iBAAiBK,EAAgB,MAAM,KAAK,CAAC;AAAA,QAEvD,UAAAZ;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,IAEJ;AAEJ;"}
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
var W = Object.defineProperty, Y = Object.defineProperties;
|
|
3
3
|
var J = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var m = Object.getOwnPropertySymbols;
|
|
5
|
-
var
|
|
6
|
-
var
|
|
5
|
+
var A = Object.prototype.hasOwnProperty, j = Object.prototype.propertyIsEnumerable;
|
|
6
|
+
var N = (e, n, t) => n in e ? W(e, n, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[n] = t, E = (e, n) => {
|
|
7
7
|
for (var t in n || (n = {}))
|
|
8
|
-
|
|
8
|
+
A.call(n, t) && N(e, t, n[t]);
|
|
9
9
|
if (m)
|
|
10
10
|
for (var t of m(n))
|
|
11
|
-
j.call(n, t) &&
|
|
11
|
+
j.call(n, t) && N(e, t, n[t]);
|
|
12
12
|
return e;
|
|
13
13
|
}, L = (e, n) => Y(e, J(n));
|
|
14
14
|
var k = (e, n) => {
|
|
15
15
|
var t = {};
|
|
16
16
|
for (var r in e)
|
|
17
|
-
|
|
17
|
+
A.call(e, r) && n.indexOf(r) < 0 && (t[r] = e[r]);
|
|
18
18
|
if (e != null && m)
|
|
19
19
|
for (var r of m(e))
|
|
20
20
|
n.indexOf(r) < 0 && j.call(e, r) && (t[r] = e[r]);
|
|
@@ -55,7 +55,7 @@ const X = {
|
|
|
55
55
|
below: `flex-col ${l("1.5", "gap")}`
|
|
56
56
|
};
|
|
57
57
|
function fe(te) {
|
|
58
|
-
var
|
|
58
|
+
var v = te, {
|
|
59
59
|
id: e,
|
|
60
60
|
icon: n,
|
|
61
61
|
label: t,
|
|
@@ -70,9 +70,9 @@ function fe(te) {
|
|
|
70
70
|
href: x,
|
|
71
71
|
target: p,
|
|
72
72
|
onClick: g,
|
|
73
|
-
disabled:
|
|
73
|
+
disabled: o = !1,
|
|
74
74
|
className: D = ""
|
|
75
|
-
} =
|
|
75
|
+
} = v, Z = k(v, [
|
|
76
76
|
"id",
|
|
77
77
|
"icon",
|
|
78
78
|
"label",
|
|
@@ -90,18 +90,18 @@ function fe(te) {
|
|
|
90
90
|
"disabled",
|
|
91
91
|
"className"
|
|
92
92
|
]);
|
|
93
|
-
var
|
|
93
|
+
var I;
|
|
94
94
|
const {
|
|
95
95
|
activeItem: q,
|
|
96
96
|
setActiveItem: F,
|
|
97
97
|
labelMode: G
|
|
98
|
-
} = P(),
|
|
99
|
-
if (
|
|
98
|
+
} = P(), s = (I = r != null ? r : G) != null ? I : "tooltip", f = z || e && q === e, i = X[B], d = (V) => {
|
|
99
|
+
if (o) {
|
|
100
100
|
V.preventDefault();
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
103
|
e && F(e), g == null || g();
|
|
104
|
-
}, H =
|
|
104
|
+
}, H = s !== "tooltip" && $ && t && /* @__PURE__ */ c(
|
|
105
105
|
"span",
|
|
106
106
|
{
|
|
107
107
|
className: a(
|
|
@@ -110,8 +110,8 @@ function fe(te) {
|
|
|
110
110
|
// Prevenir que label encolha
|
|
111
111
|
// micro-z: label above icon within navbar item
|
|
112
112
|
"relative z-10",
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
s === "below" && "text-center",
|
|
114
|
+
s === "inline" && "truncate"
|
|
115
115
|
),
|
|
116
116
|
style: {
|
|
117
117
|
// Garantir que label não seja afetada por transformações
|
|
@@ -124,8 +124,8 @@ function fe(te) {
|
|
|
124
124
|
"relative",
|
|
125
125
|
"flex",
|
|
126
126
|
"items-center",
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
s === "inline" ? "justify-start" : "justify-center",
|
|
128
|
+
s === "below" && "flex-col",
|
|
129
129
|
_("lg"),
|
|
130
130
|
"box-border",
|
|
131
131
|
// Garantir box-sizing consistente
|
|
@@ -142,14 +142,14 @@ function fe(te) {
|
|
|
142
142
|
// Remover todas as transições que possam causar movimento
|
|
143
143
|
"[&>*]:!transition-none",
|
|
144
144
|
"[&>*]:!transform-none",
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
s === "tooltip" ? i.container : a(l("sm", "px"), l("1.5", "py")),
|
|
146
|
+
s !== "tooltip" && ee[s],
|
|
147
|
+
o ? "opacity-50 cursor-not-allowed" : "cursor-pointer",
|
|
148
148
|
D
|
|
149
149
|
), b = {
|
|
150
|
-
default: f ? "bg-surface-brand-muted text-fg-brand-emphasis" :
|
|
151
|
-
ghost: f ? "text-fg-brand-emphasis" :
|
|
152
|
-
subtle: f ? "bg-surface-active text-fg-primary" :
|
|
150
|
+
default: f ? "bg-surface-brand-muted text-fg-brand-emphasis" : o ? "text-fg-disabled" : "text-fg-secondary hover:bg-surface-active hover:text-fg-primary [&:hover]:!transform-none",
|
|
151
|
+
ghost: f ? "text-fg-brand-emphasis" : o ? "text-fg-disabled" : "text-fg-secondary hover:text-fg-primary [&:hover]:!transform-none",
|
|
152
|
+
subtle: f ? "bg-surface-active text-fg-primary" : o ? "text-fg-disabled" : "text-fg-tertiary hover:bg-surface-hover hover:text-fg-primary [&:hover]:!transform-none"
|
|
153
153
|
}, y = /* @__PURE__ */ K(O, { children: [
|
|
154
154
|
/* @__PURE__ */ c(
|
|
155
155
|
"span",
|
|
@@ -176,7 +176,7 @@ function fe(te) {
|
|
|
176
176
|
// micro-z: conditional stacking per label mode — base layer when
|
|
177
177
|
// label visible inline; 'auto' when in tooltip mode to skip
|
|
178
178
|
// stacking context creation (tooltip portals to body).
|
|
179
|
-
zIndex:
|
|
179
|
+
zIndex: s !== "tooltip" ? 0 : "auto"
|
|
180
180
|
},
|
|
181
181
|
children: n
|
|
182
182
|
}
|
|
@@ -209,23 +209,24 @@ function fe(te) {
|
|
|
209
209
|
}, S = x ? /* @__PURE__ */ c(
|
|
210
210
|
"a",
|
|
211
211
|
{
|
|
212
|
-
href: x,
|
|
212
|
+
href: o ? void 0 : x,
|
|
213
213
|
target: p,
|
|
214
214
|
rel: p === "_blank" ? "noopener noreferrer" : void 0,
|
|
215
|
-
onClick:
|
|
215
|
+
onClick: d,
|
|
216
216
|
className: a(w, b[h]),
|
|
217
217
|
style: C,
|
|
218
218
|
"aria-label": t,
|
|
219
219
|
"aria-current": f ? "page" : void 0,
|
|
220
|
-
"aria-disabled":
|
|
220
|
+
"aria-disabled": o,
|
|
221
|
+
tabIndex: o ? -1 : void 0,
|
|
221
222
|
children: y
|
|
222
223
|
}
|
|
223
224
|
) : /* @__PURE__ */ c(
|
|
224
225
|
"button",
|
|
225
226
|
L(E({
|
|
226
227
|
type: "button",
|
|
227
|
-
onClick:
|
|
228
|
-
disabled:
|
|
228
|
+
onClick: d,
|
|
229
|
+
disabled: o,
|
|
229
230
|
className: a(w, b[h]),
|
|
230
231
|
style: C,
|
|
231
232
|
"aria-label": t,
|
|
@@ -234,7 +235,7 @@ function fe(te) {
|
|
|
234
235
|
children: y
|
|
235
236
|
})
|
|
236
237
|
);
|
|
237
|
-
return
|
|
238
|
+
return s === "tooltip" && R && t && !o ? /* @__PURE__ */ c(U, { content: t, position: "right", children: S }) : S;
|
|
238
239
|
}
|
|
239
240
|
export {
|
|
240
241
|
fe as default
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavbarItem.js","sources":["../../../../../../../src/ui/components/SideNavbar/components/Navbar/NavbarItem.tsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { useNavbarRequired } from \"../../contexts/NavbarContext\";\nimport { cn } from \"../../../../utils\";\nimport { getRadiusClass } from \"../../../../tokens/radius\";\nimport { getSpacingClass } from \"../../../../tokens/spacing\";\nimport { getZIndexClass } from \"../../../../tokens/z-index\";\nimport Tooltip from \"../../../../primitives/Tooltip/Tooltip\";\nimport type { NavbarItemProps, NavbarLabelMode } from \"../../types\";\n\n/**\n * Size configuration for navbar items\n */\nconst SIZE_CLASSES = {\n sm: {\n container: \"w-8 h-8\",\n icon: \"w-4 h-4\",\n badge: \"min-w-3.5 h-3.5 text-2xs\",\n },\n md: {\n container: \"w-10 h-10\",\n icon: \"w-5 h-5\",\n badge: \"min-w-5 h-5 text-xs\",\n },\n lg: {\n container: \"w-12 h-12\",\n icon: \"w-6 h-6\",\n badge: \"min-w-5 h-5 text-xs\",\n },\n} as const;\n\n/**\n * Badge variant colors\n */\nconst BADGE_VARIANTS = {\n default: \"bg-error\",\n success: \"bg-success\",\n warning: \"bg-warning\",\n danger: \"bg-error-dark\",\n} as const;\n\n/**\n * Navigation item for the Navbar subcomponent\n *\n * Displays an icon button with optional tooltip, badge, and active state.\n * Supports multiple sizes, variants, and can render as a link when href is provided.\n *\n * @example\n * ```tsx\n * // Basic button\n * <SideNavbar.Navbar.Item\n * icon={<Home />}\n * label=\"Home\"\n * onClick={() => navigate('/')}\n * />\n *\n * // As a link\n * <SideNavbar.Navbar.Item\n * icon={<Docs />}\n * label=\"Documentation\"\n * href=\"/docs\"\n * />\n *\n * // With badge\n * <SideNavbar.Navbar.Item\n * icon={<Bell />}\n * label=\"Notifications\"\n * badge={5}\n * badgeVariant=\"danger\"\n * />\n * ```\n */\nconst LABEL_STYLES: Record<NavbarLabelMode, string> = {\n tooltip: \"\", // Uses existing tooltip behavior\n inline: `flex-row ${getSpacingClass(\"sm\", \"gap\")} w-full ${getSpacingClass(\"md\", \"px\")}`,\n below: `flex-col ${getSpacingClass(\"1.5\", \"gap\")}`,\n};\n\nexport default function NavbarItem({\n id,\n icon,\n label,\n labelMode,\n showLabel = true,\n active = false,\n showTooltip = true,\n badge,\n badgeVariant = \"default\",\n variant = \"default\",\n size = \"md\",\n href,\n target,\n onClick,\n disabled = false,\n className = \"\",\n ...props\n}: NavbarItemProps) {\n const {\n activeItem,\n setActiveItem,\n labelMode: contextLabelMode,\n } = useNavbarRequired();\n\n // Use prop labelMode or fallback to context labelMode or 'tooltip'\n const effectiveLabelMode = labelMode ?? contextLabelMode ?? \"tooltip\";\n\n const isActive = active || (id && activeItem === id);\n const sizeConfig = SIZE_CLASSES[size];\n\n const handleClick = (e: React.MouseEvent) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n if (id) {\n setActiveItem(id);\n }\n onClick?.();\n };\n\n // Label element (for inline and below modes)\n const labelElement = effectiveLabelMode !== \"tooltip\" &&\n showLabel &&\n label && (\n <span\n className={cn(\n \"text-xs\",\n \"flex-shrink-0\", // Prevenir que label encolha\n // micro-z: label above icon within navbar item\n \"relative z-10\",\n effectiveLabelMode === \"below\" && \"text-center\",\n effectiveLabelMode === \"inline\" && \"truncate\",\n )}\n style={{\n // Garantir que label não seja afetada por transformações\n willChange: \"auto\",\n transform: \"none\",\n }}\n >\n {label}\n </span>\n );\n\n // Base classes for the item\n // Removido transition-colors e duration-150 para eliminar animações\n // Adicionado box-border para estabilidade dimensional\n const baseClasses = cn(\n \"relative\",\n \"flex\",\n \"items-center\",\n effectiveLabelMode === \"inline\" ? \"justify-start\" : \"justify-center\",\n effectiveLabelMode === \"below\" && \"flex-col\",\n getRadiusClass(\"lg\"),\n \"box-border\", // Garantir box-sizing consistente\n \"focus:outline-none\",\n \"focus:ring-2\",\n \"focus:ring-line-focus\",\n \"focus:ring-offset-1\",\n \"w-full\", // Ensure full width for vertical layout\n \"flex-shrink-0\", // Prevent items from shrinking\n \"min-w-0\", // Prevent flex items from overflowing\n // Remover todas as transições que possam causar movimento\n \"[&>*]:!transition-none\",\n \"[&>*]:!transform-none\",\n effectiveLabelMode === \"tooltip\"\n ? sizeConfig.container\n : cn(getSpacingClass(\"sm\", \"px\"), getSpacingClass(\"1.5\", \"py\")),\n effectiveLabelMode !== \"tooltip\" && LABEL_STYLES[effectiveLabelMode],\n disabled ? \"opacity-50 cursor-not-allowed\" : \"cursor-pointer\",\n className,\n );\n\n // Variant-specific classes usando variáveis CSS via Tailwind arbitrary values\n // Estados hover/active sem transições para evitar movimento\n const variantClasses = {\n default: isActive\n ? \"bg-surface-brand-muted text-fg-brand-emphasis\"\n : disabled\n ? \"text-fg-disabled\"\n : \"text-fg-secondary hover:bg-surface-active hover:text-fg-primary [&:hover]:!transform-none\",\n ghost: isActive\n ? \"text-fg-brand-emphasis\"\n : disabled\n ? \"text-fg-disabled\"\n : \"text-fg-secondary hover:text-fg-primary [&:hover]:!transform-none\",\n subtle: isActive\n ? \"bg-surface-active text-fg-primary\"\n : disabled\n ? \"text-fg-disabled\"\n : \"text-fg-tertiary hover:bg-surface-hover hover:text-fg-primary [&:hover]:!transform-none\",\n };\n\n const content = (\n <>\n {/* Wrapper do ícone - sem animações, com estabilidade dimensional */}\n <span\n className={cn(\n \"flex-shrink-0\",\n sizeConfig.icon,\n \"[&>svg]:transition-none\",\n \"[&>svg]:!transform-none\",\n \"[&>svg]:!will-change-auto\",\n \"box-border\",\n \"flex items-center justify-center\",\n // Garantir que ícone não sobreponha label - z-index menor que label\n `relative ${getZIndexClass(\"base\")}`,\n )}\n style={{\n // Garantir dimensões mínimas fixas para evitar \"pular\"\n minWidth:\n sizeConfig.icon === \"w-4 h-4\"\n ? \"1rem\"\n : sizeConfig.icon === \"w-5 h-5\"\n ? \"1.25rem\"\n : \"1.5rem\",\n minHeight:\n sizeConfig.icon === \"w-4 h-4\"\n ? \"1rem\"\n : sizeConfig.icon === \"w-5 h-5\"\n ? \"1.25rem\"\n : \"1.5rem\",\n // Forçar sem animações ou transformações\n willChange: \"auto\",\n transform: \"none\",\n transition: \"none\",\n // micro-z: conditional stacking per label mode — base layer when\n // label visible inline; 'auto' when in tooltip mode to skip\n // stacking context creation (tooltip portals to body).\n zIndex: effectiveLabelMode !== \"tooltip\" ? 0 : \"auto\",\n }}\n >\n {icon}\n </span>\n\n {/* Label (for inline and below modes) - posicionada após o ícone */}\n {labelElement}\n\n {/* Badge */}\n {badge !== undefined && badge !== null && (\n <span\n className={cn(\n \"absolute\",\n \"-top-1\",\n \"-right-1\",\n \"flex\",\n \"items-center\",\n \"justify-center\",\n getSpacingClass(\"xs\", \"px\"),\n \"font-medium\",\n \"text-fg-inverse\",\n getRadiusClass(\"full\"),\n sizeConfig.badge,\n BADGE_VARIANTS[badgeVariant],\n )}\n >\n {badge}\n </span>\n )}\n </>\n );\n\n // Render as link if href is provided\n // Adicionar style inline para garantir que não há transformações em hover\n const elementStyle = {\n willChange: \"auto\",\n transform: \"none\",\n transition: \"none\",\n };\n\n const element = href ? (\n <a\n href={href}\n target={target}\n rel={target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n onClick={handleClick}\n className={cn(baseClasses, variantClasses[variant])}\n style={elementStyle}\n aria-label={label}\n aria-current={isActive ? \"page\" : undefined}\n aria-disabled={disabled}\n >\n {content}\n </a>\n ) : (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled}\n className={cn(baseClasses, variantClasses[variant])}\n style={elementStyle}\n aria-label={label}\n aria-current={isActive ? \"page\" : undefined}\n {...props}\n >\n {content}\n </button>\n );\n\n // Wrap with tooltip only if mode is 'tooltip'\n if (effectiveLabelMode === \"tooltip\" && showTooltip && label && !disabled) {\n return (\n <Tooltip content={label} position=\"right\">\n {element}\n </Tooltip>\n );\n }\n\n return element;\n}\n"],"names":["SIZE_CLASSES","BADGE_VARIANTS","LABEL_STYLES","getSpacingClass","NavbarItem","_a","_b","id","icon","label","labelMode","showLabel","active","showTooltip","badge","badgeVariant","variant","size","href","target","onClick","disabled","className","props","__objRest","activeItem","setActiveItem","contextLabelMode","useNavbarRequired","effectiveLabelMode","isActive","sizeConfig","handleClick","e","labelElement","jsx","cn","baseClasses","getRadiusClass","variantClasses","content","jsxs","Fragment","getZIndexClass","elementStyle","element","__spreadProps","__spreadValues","Tooltip"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,MAAMA,IAAe;AAAA,EACnB,IAAI;AAAA,IACF,WAAW;AAAA,IACX,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,IAAI;AAAA,IACF,WAAW;AAAA,IACX,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAET,IAAI;AAAA,IACF,WAAW;AAAA,IACX,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAEX,GAKMC,IAAiB;AAAA,EACrB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AACV,GAiCMC,KAAgD;AAAA,EACpD,SAAS;AAAA;AAAA,EACT,QAAQ,YAAYC,EAAgB,MAAM,KAAK,CAAC,WAAWA,EAAgB,MAAM,IAAI,CAAC;AAAA,EACtF,OAAO,YAAYA,EAAgB,OAAO,KAAK,CAAC;AAClD;AAEA,SAAwBC,GAAWC,IAkBf;AAlBe,MAAAC,IAAAD,IACjC;AAAA,QAAAE;AAAA,IACA,MAAAC;AAAA,IACA,OAAAC;AAAA,IACA,WAAAC;AAAA,IACA,WAAAC,IAAY;AAAA,IACZ,QAAAC,IAAS;AAAA,IACT,aAAAC,IAAc;AAAA,IACd,OAAAC;AAAA,IACA,cAAAC,IAAe;AAAA,IACf,SAAAC,IAAU;AAAA,IACV,MAAAC,IAAO;AAAA,IACP,MAAAC;AAAA,IACA,QAAAC;AAAA,IACA,SAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,WAAAC,IAAY;AAAA,MAhBqBhB,GAiB9BiB,IAAAC,EAjB8BlB,GAiB9B;AAAA,IAhBH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;;AAGA,QAAM;AAAA,IACJ,YAAAmB;AAAA,IACA,eAAAC;AAAA,IACA,WAAWC;AAAA,EAAA,IACTC,EAAA,GAGEC,KAAqBxB,IAAAK,KAAA,OAAAA,IAAaiB,MAAb,OAAAtB,IAAiC,WAEtDyB,IAAWlB,KAAWL,KAAMkB,MAAelB,GAC3CwB,IAAa/B,EAAaiB,CAAI,GAE9Be,IAAc,CAACC,MAAwB;AAC3C,QAAIZ,GAAU;AACZ,MAAAY,EAAE,eAAA;AACF;AAAA,IACF;AACA,IAAI1B,KACFmB,EAAcnB,CAAE,GAElBa,KAAA,QAAAA;AAAA,EACF,GAGMc,IAAeL,MAAuB,aAC1ClB,KACAF,KACE,gBAAA0B;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACA;AAAA;AAAA;AAAA,QAEA;AAAA,QACAP,MAAuB,WAAW;AAAA,QAClCA,MAAuB,YAAY;AAAA,MAAA;AAAA,MAErC,OAAO;AAAA;AAAA,QAEL,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAGZ,UAAApB;AAAA,IAAA;AAAA,EAAA,GAOD4B,IAAcD;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACAP,MAAuB,WAAW,kBAAkB;AAAA,IACpDA,MAAuB,WAAW;AAAA,IAClCS,EAAe,IAAI;AAAA,IACnB;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACAT,MAAuB,YACnBE,EAAW,YACXK,EAAGjC,EAAgB,MAAM,IAAI,GAAGA,EAAgB,OAAO,IAAI,CAAC;AAAA,IAChE0B,MAAuB,aAAa3B,GAAa2B,CAAkB;AAAA,IACnER,IAAW,kCAAkC;AAAA,IAC7CC;AAAA,EAAA,GAKIiB,IAAiB;AAAA,IACrB,SAAST,IACL,kDACAT,IACE,qBACA;AAAA,IACN,OAAOS,IACH,2BACAT,IACE,qBACA;AAAA,IACN,QAAQS,IACJ,sCACAT,IACE,qBACA;AAAA,EAAA,GAGFmB,IACJ,gBAAAC,EAAAC,GAAA,EAEE,UAAA;AAAA,IAAA,gBAAAP;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWC;AAAA,UACT;AAAA,UACAL,EAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UAEA,YAAYY,EAAe,MAAM,CAAC;AAAA,QAAA;AAAA,QAEpC,OAAO;AAAA;AAAA,UAEL,UACEZ,EAAW,SAAS,YAChB,SACAA,EAAW,SAAS,YAClB,YACA;AAAA,UACR,WACEA,EAAW,SAAS,YAChB,SACAA,EAAW,SAAS,YAClB,YACA;AAAA;AAAA,UAER,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,YAAY;AAAA;AAAA;AAAA;AAAA,UAIZ,QAAQF,MAAuB,YAAY,IAAI;AAAA,QAAA;AAAA,QAGhD,UAAArB;AAAA,MAAA;AAAA,IAAA;AAAA,IAIF0B;AAAA,IAGuBpB,KAAU,QAChC,gBAAAqB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWC;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACAjC,EAAgB,MAAM,IAAI;AAAA,UAC1B;AAAA,UACA;AAAA,UACAmC,EAAe,MAAM;AAAA,UACrBP,EAAW;AAAA,UACX9B,EAAec,CAAY;AAAA,QAAA;AAAA,QAG5B,UAAAD;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GAEJ,GAKI8B,IAAe;AAAA,IACnB,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,YAAY;AAAA,EAAA,GAGRC,IAAU3B,IACd,gBAAAiB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAAjB;AAAA,MACA,QAAAC;AAAA,MACA,KAAKA,MAAW,WAAW,wBAAwB;AAAA,MACnD,SAASa;AAAA,MACT,WAAWI,EAAGC,GAAaE,EAAevB,CAAO,CAAC;AAAA,MAClD,OAAO4B;AAAA,MACP,cAAYnC;AAAA,MACZ,gBAAcqB,IAAW,SAAS;AAAA,MAClC,iBAAeT;AAAA,MAEd,UAAAmB;AAAA,IAAA;AAAA,EAAA,IAGH,gBAAAL;AAAA,IAAC;AAAA,IAAAW,EAAAC,EAAA;AAAA,MACC,MAAK;AAAA,MACL,SAASf;AAAA,MACT,UAAAX;AAAA,MACA,WAAWe,EAAGC,GAAaE,EAAevB,CAAO,CAAC;AAAA,MAClD,OAAO4B;AAAA,MACP,cAAYnC;AAAA,MACZ,gBAAcqB,IAAW,SAAS;AAAA,OAC9BP,IARL;AAAA,MAUE,UAAAiB;AAAA,IAAA;AAAA,EAAA;AAKL,SAAIX,MAAuB,aAAahB,KAAeJ,KAAS,CAACY,sBAE5D2B,GAAA,EAAQ,SAASvC,GAAO,UAAS,SAC/B,UAAAoC,GACH,IAIGA;AACT;"}
|
|
1
|
+
{"version":3,"file":"NavbarItem.js","sources":["../../../../../../../src/ui/components/SideNavbar/components/Navbar/NavbarItem.tsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { useNavbarRequired } from \"../../contexts/NavbarContext\";\nimport { cn } from \"../../../../utils\";\nimport { getRadiusClass } from \"../../../../tokens/radius\";\nimport { getSpacingClass } from \"../../../../tokens/spacing\";\nimport { getZIndexClass } from \"../../../../tokens/z-index\";\nimport Tooltip from \"../../../../primitives/Tooltip/Tooltip\";\nimport type { NavbarItemProps, NavbarLabelMode } from \"../../types\";\n\n/**\n * Size configuration for navbar items\n */\nconst SIZE_CLASSES = {\n sm: {\n container: \"w-8 h-8\",\n icon: \"w-4 h-4\",\n badge: \"min-w-3.5 h-3.5 text-2xs\",\n },\n md: {\n container: \"w-10 h-10\",\n icon: \"w-5 h-5\",\n badge: \"min-w-5 h-5 text-xs\",\n },\n lg: {\n container: \"w-12 h-12\",\n icon: \"w-6 h-6\",\n badge: \"min-w-5 h-5 text-xs\",\n },\n} as const;\n\n/**\n * Badge variant colors\n */\nconst BADGE_VARIANTS = {\n default: \"bg-error\",\n success: \"bg-success\",\n warning: \"bg-warning\",\n danger: \"bg-error-dark\",\n} as const;\n\n/**\n * Navigation item for the Navbar subcomponent\n *\n * Displays an icon button with optional tooltip, badge, and active state.\n * Supports multiple sizes, variants, and can render as a link when href is provided.\n *\n * @example\n * ```tsx\n * // Basic button\n * <SideNavbar.Navbar.Item\n * icon={<Home />}\n * label=\"Home\"\n * onClick={() => navigate('/')}\n * />\n *\n * // As a link\n * <SideNavbar.Navbar.Item\n * icon={<Docs />}\n * label=\"Documentation\"\n * href=\"/docs\"\n * />\n *\n * // With badge\n * <SideNavbar.Navbar.Item\n * icon={<Bell />}\n * label=\"Notifications\"\n * badge={5}\n * badgeVariant=\"danger\"\n * />\n * ```\n */\nconst LABEL_STYLES: Record<NavbarLabelMode, string> = {\n tooltip: \"\", // Uses existing tooltip behavior\n inline: `flex-row ${getSpacingClass(\"sm\", \"gap\")} w-full ${getSpacingClass(\"md\", \"px\")}`,\n below: `flex-col ${getSpacingClass(\"1.5\", \"gap\")}`,\n};\n\nexport default function NavbarItem({\n id,\n icon,\n label,\n labelMode,\n showLabel = true,\n active = false,\n showTooltip = true,\n badge,\n badgeVariant = \"default\",\n variant = \"default\",\n size = \"md\",\n href,\n target,\n onClick,\n disabled = false,\n className = \"\",\n ...props\n}: NavbarItemProps) {\n const {\n activeItem,\n setActiveItem,\n labelMode: contextLabelMode,\n } = useNavbarRequired();\n\n // Use prop labelMode or fallback to context labelMode or 'tooltip'\n const effectiveLabelMode = labelMode ?? contextLabelMode ?? \"tooltip\";\n\n const isActive = active || (id && activeItem === id);\n const sizeConfig = SIZE_CLASSES[size];\n\n const handleClick = (e: React.MouseEvent) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n if (id) {\n setActiveItem(id);\n }\n onClick?.();\n };\n\n // Label element (for inline and below modes)\n const labelElement = effectiveLabelMode !== \"tooltip\" &&\n showLabel &&\n label && (\n <span\n className={cn(\n \"text-xs\",\n \"flex-shrink-0\", // Prevenir que label encolha\n // micro-z: label above icon within navbar item\n \"relative z-10\",\n effectiveLabelMode === \"below\" && \"text-center\",\n effectiveLabelMode === \"inline\" && \"truncate\",\n )}\n style={{\n // Garantir que label não seja afetada por transformações\n willChange: \"auto\",\n transform: \"none\",\n }}\n >\n {label}\n </span>\n );\n\n // Base classes for the item\n // Removido transition-colors e duration-150 para eliminar animações\n // Adicionado box-border para estabilidade dimensional\n const baseClasses = cn(\n \"relative\",\n \"flex\",\n \"items-center\",\n effectiveLabelMode === \"inline\" ? \"justify-start\" : \"justify-center\",\n effectiveLabelMode === \"below\" && \"flex-col\",\n getRadiusClass(\"lg\"),\n \"box-border\", // Garantir box-sizing consistente\n \"focus:outline-none\",\n \"focus:ring-2\",\n \"focus:ring-line-focus\",\n \"focus:ring-offset-1\",\n \"w-full\", // Ensure full width for vertical layout\n \"flex-shrink-0\", // Prevent items from shrinking\n \"min-w-0\", // Prevent flex items from overflowing\n // Remover todas as transições que possam causar movimento\n \"[&>*]:!transition-none\",\n \"[&>*]:!transform-none\",\n effectiveLabelMode === \"tooltip\"\n ? sizeConfig.container\n : cn(getSpacingClass(\"sm\", \"px\"), getSpacingClass(\"1.5\", \"py\")),\n effectiveLabelMode !== \"tooltip\" && LABEL_STYLES[effectiveLabelMode],\n disabled ? \"opacity-50 cursor-not-allowed\" : \"cursor-pointer\",\n className,\n );\n\n // Variant-specific classes usando variáveis CSS via Tailwind arbitrary values\n // Estados hover/active sem transições para evitar movimento\n const variantClasses = {\n default: isActive\n ? \"bg-surface-brand-muted text-fg-brand-emphasis\"\n : disabled\n ? \"text-fg-disabled\"\n : \"text-fg-secondary hover:bg-surface-active hover:text-fg-primary [&:hover]:!transform-none\",\n ghost: isActive\n ? \"text-fg-brand-emphasis\"\n : disabled\n ? \"text-fg-disabled\"\n : \"text-fg-secondary hover:text-fg-primary [&:hover]:!transform-none\",\n subtle: isActive\n ? \"bg-surface-active text-fg-primary\"\n : disabled\n ? \"text-fg-disabled\"\n : \"text-fg-tertiary hover:bg-surface-hover hover:text-fg-primary [&:hover]:!transform-none\",\n };\n\n const content = (\n <>\n {/* Wrapper do ícone - sem animações, com estabilidade dimensional */}\n <span\n className={cn(\n \"flex-shrink-0\",\n sizeConfig.icon,\n \"[&>svg]:transition-none\",\n \"[&>svg]:!transform-none\",\n \"[&>svg]:!will-change-auto\",\n \"box-border\",\n \"flex items-center justify-center\",\n // Garantir que ícone não sobreponha label - z-index menor que label\n `relative ${getZIndexClass(\"base\")}`,\n )}\n style={{\n // Garantir dimensões mínimas fixas para evitar \"pular\"\n minWidth:\n sizeConfig.icon === \"w-4 h-4\"\n ? \"1rem\"\n : sizeConfig.icon === \"w-5 h-5\"\n ? \"1.25rem\"\n : \"1.5rem\",\n minHeight:\n sizeConfig.icon === \"w-4 h-4\"\n ? \"1rem\"\n : sizeConfig.icon === \"w-5 h-5\"\n ? \"1.25rem\"\n : \"1.5rem\",\n // Forçar sem animações ou transformações\n willChange: \"auto\",\n transform: \"none\",\n transition: \"none\",\n // micro-z: conditional stacking per label mode — base layer when\n // label visible inline; 'auto' when in tooltip mode to skip\n // stacking context creation (tooltip portals to body).\n zIndex: effectiveLabelMode !== \"tooltip\" ? 0 : \"auto\",\n }}\n >\n {icon}\n </span>\n\n {/* Label (for inline and below modes) - posicionada após o ícone */}\n {labelElement}\n\n {/* Badge */}\n {badge !== undefined && badge !== null && (\n <span\n className={cn(\n \"absolute\",\n \"-top-1\",\n \"-right-1\",\n \"flex\",\n \"items-center\",\n \"justify-center\",\n getSpacingClass(\"xs\", \"px\"),\n \"font-medium\",\n \"text-fg-inverse\",\n getRadiusClass(\"full\"),\n sizeConfig.badge,\n BADGE_VARIANTS[badgeVariant],\n )}\n >\n {badge}\n </span>\n )}\n </>\n );\n\n // Render as link if href is provided\n // Adicionar style inline para garantir que não há transformações em hover\n const elementStyle = {\n willChange: \"auto\",\n transform: \"none\",\n transition: \"none\",\n };\n\n const element = href ? (\n <a\n // A disabled link must leave the tab order and stop being a\n // navigable/announced anchor — aria-disabled alone does neither.\n // Dropping href makes the <a> non-focusable; tabIndex=-1 is belt\n // and suspenders. (handleClick already no-ops when disabled.)\n href={disabled ? undefined : href}\n target={target}\n rel={target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n onClick={handleClick}\n className={cn(baseClasses, variantClasses[variant])}\n style={elementStyle}\n aria-label={label}\n aria-current={isActive ? \"page\" : undefined}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : undefined}\n >\n {content}\n </a>\n ) : (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled}\n className={cn(baseClasses, variantClasses[variant])}\n style={elementStyle}\n aria-label={label}\n aria-current={isActive ? \"page\" : undefined}\n {...props}\n >\n {content}\n </button>\n );\n\n // Wrap with tooltip only if mode is 'tooltip'\n if (effectiveLabelMode === \"tooltip\" && showTooltip && label && !disabled) {\n return (\n <Tooltip content={label} position=\"right\">\n {element}\n </Tooltip>\n );\n }\n\n return element;\n}\n"],"names":["SIZE_CLASSES","BADGE_VARIANTS","LABEL_STYLES","getSpacingClass","NavbarItem","_a","_b","id","icon","label","labelMode","showLabel","active","showTooltip","badge","badgeVariant","variant","size","href","target","onClick","disabled","className","props","__objRest","activeItem","setActiveItem","contextLabelMode","useNavbarRequired","effectiveLabelMode","isActive","sizeConfig","handleClick","e","labelElement","jsx","cn","baseClasses","getRadiusClass","variantClasses","content","jsxs","Fragment","getZIndexClass","elementStyle","element","__spreadProps","__spreadValues","Tooltip"],"mappings":"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"}
|