analytica-frontend-lib 1.0.55 → 1.0.57
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/Badge/index.js +1 -1
- package/dist/Badge/index.js.map +1 -1
- package/dist/Badge/index.mjs +1 -1
- package/dist/Badge/index.mjs.map +1 -1
- package/dist/Card/index.d.mts +1 -1
- package/dist/Card/index.d.ts +1 -1
- package/dist/Card/index.js +2 -2
- package/dist/Card/index.js.map +1 -1
- package/dist/Card/index.mjs +2 -2
- package/dist/Card/index.mjs.map +1 -1
- package/dist/DropdownMenu/index.d.mts +2 -2
- package/dist/DropdownMenu/index.d.ts +2 -2
- package/dist/DropdownMenu/index.js +1 -2
- package/dist/DropdownMenu/index.js.map +1 -1
- package/dist/DropdownMenu/index.mjs +1 -2
- package/dist/DropdownMenu/index.mjs.map +1 -1
- package/dist/Menu/index.js +3 -2
- package/dist/Menu/index.js.map +1 -1
- package/dist/Menu/index.mjs +3 -2
- package/dist/Menu/index.mjs.map +1 -1
- package/dist/index.css +7 -0
- package/dist/index.css.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +7 -0
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/DropdownMenu/DropdownMenu.tsx","../../src/components/Button/Button.tsx"],"sourcesContent":["import { SignOut, User } from 'phosphor-react';\nimport {\n forwardRef,\n ReactNode,\n ButtonHTMLAttributes,\n useEffect,\n useRef,\n HTMLAttributes,\n MouseEvent,\n KeyboardEvent,\n isValidElement,\n Children,\n cloneElement,\n ReactElement,\n useState,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport Button from '../Button/Button';\n\ninterface DropdownStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n}\n\ntype DropdownStoreApi = StoreApi<DropdownStore>;\n\nexport function createDropdownStore(): DropdownStoreApi {\n return create<DropdownStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n }));\n}\n\nexport const useDropdownStore = (externalStore?: DropdownStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a DropdownMenu (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nconst injectStore = (\n children: ReactNode,\n store: DropdownStoreApi\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: DropdownStoreApi;\n children?: ReactNode;\n }>;\n\n const newProps: Partial<{\n store: DropdownStoreApi;\n children: ReactNode;\n }> = {\n store,\n };\n\n if (typedChild.props.children) {\n newProps.children = injectStore(typedChild.props.children, store);\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\ninterface DropdownMenuProps {\n children: ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nconst DropdownMenu = ({\n children,\n open: propOpen,\n onOpenChange,\n}: DropdownMenuProps) => {\n const storeRef = useRef<DropdownStoreApi | null>(null);\n storeRef.current ??= createDropdownStore();\n const store = storeRef.current;\n const { open, setOpen: storeSetOpen } = useStore(store, (s) => s);\n\n const setOpen = (newOpen: boolean) => {\n storeSetOpen(newOpen);\n };\n\n const menuRef = useRef<HTMLDivElement | null>(null);\n\n const handleArrowDownOrArrowUp = (event: globalThis.KeyboardEvent) => {\n const menuContent = menuRef.current?.querySelector('[role=\"menu\"]');\n if (menuContent) {\n event.preventDefault();\n\n const items = Array.from(\n menuContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n if (items.length === 0) return;\n\n const focusedItem = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focusedItem);\n\n let nextIndex;\n if (event.key === 'ArrowDown') {\n nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n // ArrowUp\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n\n items[nextIndex]?.focus();\n }\n };\n\n const handleDownkey = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false);\n } else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n handleArrowDownOrArrowUp(event);\n }\n };\n\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n };\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleDownkey);\n }\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleDownkey);\n };\n }, [open]);\n\n useEffect(() => {\n setOpen(open);\n onOpenChange?.(open);\n }, [open, onOpenChange]);\n\n useEffect(() => {\n if (propOpen) {\n setOpen(propOpen);\n }\n }, [propOpen]);\n\n return (\n <div className=\"relative\" ref={menuRef}>\n {injectStore(children, store)}\n </div>\n );\n};\n\n// Componentes genéricos do DropdownMenu\nconst DropdownMenuTrigger = ({\n className,\n children,\n onClick,\n store: externalStore,\n ...props\n}: HTMLAttributes<HTMLButtonElement> & {\n disabled?: boolean;\n store?: DropdownStoreApi;\n}) => {\n const store = useDropdownStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n return (\n <Button\n variant=\"outline\"\n onClick={(e) => {\n e.stopPropagation();\n toggleOpen();\n if (onClick) onClick(e);\n }}\n aria-expanded={open}\n className={`${className}`}\n {...props}\n >\n {children}\n </Button>\n );\n};\nDropdownMenuTrigger.displayName = 'DropdownMenuTrigger';\n\nconst ITEM_SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full',\n right: 'top-full',\n bottom: 'top-full',\n left: 'top-full',\n};\n\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\nconst MENUCONTENT_VARIANT_CLASSES = {\n menu: 'p-1',\n profile: 'p-6',\n};\n\nconst MenuLabel = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n inset?: boolean;\n store?: DropdownStoreApi;\n }\n>(({ className, inset, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={`text-sm w-full ${inset ? 'pl-8' : ''} ${className ?? ''}`}\n {...props}\n />\n );\n});\nMenuLabel.displayName = 'MenuLabel';\n\nconst DropdownMenuContent = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n variant?: 'menu' | 'profile';\n sideOffset?: number;\n store?: DropdownStoreApi;\n }\n>(\n (\n {\n className,\n align = 'start',\n side = 'bottom',\n variant = 'menu',\n sideOffset = 4,\n children,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useDropdownStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const [isVisible, setIsVisible] = useState(open);\n\n useEffect(() => {\n if (open) {\n setIsVisible(true);\n } else {\n const timer = setTimeout(() => setIsVisible(false), 200);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n if (!isVisible) return null;\n\n const getPositionClasses = () => {\n const vertical = SIDE_CLASSES[side];\n const horizontal = ALIGN_CLASSES[align];\n\n return `absolute ${vertical} ${horizontal}`;\n };\n\n const variantClasses = MENUCONTENT_VARIANT_CLASSES[variant];\n return (\n <div\n ref={ref}\n role=\"menu\"\n className={`\n bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md border-border-100\n ${open ? 'animate-in fade-in-0 zoom-in-95' : 'animate-out fade-out-0 zoom-out-95'}\n ${getPositionClasses()}\n ${variantClasses}\n ${className}\n `}\n style={{\n marginTop: side === 'bottom' ? sideOffset : undefined,\n marginBottom: side === 'top' ? sideOffset : undefined,\n marginLeft: side === 'right' ? sideOffset : undefined,\n marginRight: side === 'left' ? sideOffset : undefined,\n }}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nDropdownMenuContent.displayName = 'DropdownMenuContent';\n\nconst DropdownMenuItem = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n inset?: boolean;\n size?: 'small' | 'medium';\n iconLeft?: ReactNode;\n iconRight?: ReactNode;\n disabled?: boolean;\n variant?: 'profile' | 'menu';\n store?: DropdownStoreApi;\n }\n>(\n (\n {\n className,\n size = 'small',\n children,\n iconRight,\n iconLeft,\n disabled = false,\n onClick,\n variant = 'menu',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useDropdownStore(externalStore);\n const setOpen = useStore(store, (s) => s.setOpen);\n const sizeClasses = ITEM_SIZE_CLASSES[size];\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n onClick?.(e as MouseEvent<HTMLDivElement>);\n setOpen(false);\n };\n\n const getVariantClasses = () => {\n if (variant === 'profile') {\n return 'relative flex flex-row justify-between select-none items-center gap-2 rounded-sm p-4 text-sm outline-none transition-colors [&>svg]:size-6 [&>svg]:shrink-0';\n }\n return 'relative flex select-none items-center gap-2 rounded-sm p-3 text-sm outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0';\n };\n\n const getVariantProps = () => {\n return variant === 'profile' ? { 'data-variant': 'profile' } : {};\n };\n\n return (\n <div\n ref={ref}\n role=\"menuitem\"\n {...getVariantProps()}\n aria-disabled={disabled}\n className={`\n focus-visible:bg-background-50\n ${getVariantClasses()}\n ${sizeClasses}\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n {iconLeft}\n <span className=\"w-full text-md\">{children}</span>\n {iconRight}\n </div>\n );\n }\n);\nDropdownMenuItem.displayName = 'DropdownMenuItem';\n\nconst DropdownMenuSeparator = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }\n>(({ className, store: _store, ...props }, ref) => (\n <div\n ref={ref}\n className={`my-1 h-px bg-border-200 ${className}`}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName = 'DropdownMenuSeparator';\n\n// Componentes específicos do ProfileMenu\nconst ProfileMenuTrigger = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & { store?: DropdownStoreApi }\n>(({ className, onClick, store: externalStore, ...props }, ref) => {\n const store = useDropdownStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n return (\n <button\n ref={ref}\n className={`rounded-lg size-10 bg-background-50 flex items-center justify-center ${className}`}\n onClick={(e) => {\n e.stopPropagation();\n toggleOpen();\n onClick?.(e);\n }}\n aria-expanded={open}\n {...props}\n >\n <span className=\"size-6 rounded-full bg-background-100 flex items-center justify-center\">\n <User className=\"text-background-950\" size={18} />\n </span>\n </button>\n );\n});\nProfileMenuTrigger.displayName = 'ProfileMenuTrigger';\n\nconst ProfileMenuHeader = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n name: string;\n email: string;\n store?: DropdownStoreApi;\n }\n>(({ className, name, email, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-component=\"ProfileMenuHeader\"\n className={`\n flex flex-row gap-4 items-center\n ${className}\n `}\n {...props}\n >\n <span className=\"size-16 bg-background-100 rounded-full flex items-center justify-center\">\n <User size={34} className=\"text-background-950\" />\n </span>\n <div className=\"flex flex-col \">\n <p className=\"text-xl font-bold text-text-950\">{name}</p>\n <p className=\"text-md text-text-600\">{email}</p>\n </div>\n </div>\n );\n});\nProfileMenuHeader.displayName = 'ProfileMenuHeader';\n\nconst ProfileMenuSection = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }\n>(({ className, children, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={`\n flex flex-col p-2\n ${className}\n `}\n {...props}\n >\n {children}\n </div>\n );\n});\nProfileMenuSection.displayName = 'ProfileMenuSection';\n\nconst ProfileMenuFooter = ({\n className,\n disabled = false,\n onClick,\n store: externalStore,\n ...props\n}: HTMLAttributes<HTMLButtonElement> & {\n disabled?: boolean;\n store?: DropdownStoreApi;\n}) => {\n const store = useDropdownStore(externalStore);\n const setOpen = useStore(store, (s) => s.setOpen);\n\n return (\n <Button\n variant=\"outline\"\n className={`w-full ${className}`}\n disabled={disabled}\n onClick={(e) => {\n setOpen(false);\n onClick?.(e);\n }}\n {...props}\n >\n <span className=\"mr-2 flex items-center\">\n <SignOut />\n </span>\n <span>Sair</span>\n </Button>\n );\n};\nProfileMenuFooter.displayName = 'ProfileMenuFooter';\n\n// Exportações\nexport default DropdownMenu;\nexport {\n // Componentes genéricos\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n MenuLabel,\n DropdownMenuSeparator,\n\n // Componentes específicos do ProfileMenu\n ProfileMenuTrigger,\n ProfileMenuHeader,\n ProfileMenuSection,\n ProfileMenuFooter,\n};\n","import { ButtonHTMLAttributes, ReactNode } from 'react';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={`${baseClasses} ${variantClasses} ${sizeClasses} ${className}`}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n"],"mappings":"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","names":["jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/DropdownMenu/DropdownMenu.tsx","../../src/components/Button/Button.tsx"],"sourcesContent":["import { SignOut, User } from 'phosphor-react';\nimport {\n forwardRef,\n ReactNode,\n ButtonHTMLAttributes,\n useEffect,\n useRef,\n HTMLAttributes,\n MouseEvent,\n KeyboardEvent,\n isValidElement,\n Children,\n cloneElement,\n ReactElement,\n useState,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport Button from '../Button/Button';\n\ninterface DropdownStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n}\n\ntype DropdownStoreApi = StoreApi<DropdownStore>;\n\nexport function createDropdownStore(): DropdownStoreApi {\n return create<DropdownStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n }));\n}\n\nexport const useDropdownStore = (externalStore?: DropdownStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a DropdownMenu (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nconst injectStore = (\n children: ReactNode,\n store: DropdownStoreApi\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: DropdownStoreApi;\n children?: ReactNode;\n }>;\n\n const newProps: Partial<{\n store: DropdownStoreApi;\n children: ReactNode;\n }> = {\n store,\n };\n\n if (typedChild.props.children) {\n newProps.children = injectStore(typedChild.props.children, store);\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\ninterface DropdownMenuProps {\n children: ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nconst DropdownMenu = ({\n children,\n open: propOpen,\n onOpenChange,\n}: DropdownMenuProps) => {\n const storeRef = useRef<DropdownStoreApi | null>(null);\n storeRef.current ??= createDropdownStore();\n const store = storeRef.current;\n const { open, setOpen: storeSetOpen } = useStore(store, (s) => s);\n\n const setOpen = (newOpen: boolean) => {\n storeSetOpen(newOpen);\n };\n\n const menuRef = useRef<HTMLDivElement | null>(null);\n\n const handleArrowDownOrArrowUp = (event: globalThis.KeyboardEvent) => {\n const menuContent = menuRef.current?.querySelector('[role=\"menu\"]');\n if (menuContent) {\n event.preventDefault();\n\n const items = Array.from(\n menuContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n if (items.length === 0) return;\n\n const focusedItem = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focusedItem);\n\n let nextIndex;\n if (event.key === 'ArrowDown') {\n nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n // ArrowUp\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n\n items[nextIndex]?.focus();\n }\n };\n\n const handleDownkey = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false);\n } else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n handleArrowDownOrArrowUp(event);\n }\n };\n\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n };\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleDownkey);\n }\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleDownkey);\n };\n }, [open]);\n\n useEffect(() => {\n setOpen(open);\n onOpenChange?.(open);\n }, [open, onOpenChange]);\n\n useEffect(() => {\n if (propOpen) {\n setOpen(propOpen);\n }\n }, [propOpen]);\n\n return (\n <div className=\"relative\" ref={menuRef}>\n {injectStore(children, store)}\n </div>\n );\n};\n\n// Componentes genéricos do DropdownMenu\nconst DropdownMenuTrigger = ({\n className,\n children,\n onClick,\n store: externalStore,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & {\n disabled?: boolean;\n store?: DropdownStoreApi;\n}) => {\n const store = useDropdownStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n return (\n <button\n onClick={(e) => {\n e.stopPropagation();\n toggleOpen();\n if (onClick) onClick(e);\n }}\n aria-expanded={open}\n className={`${className}`}\n {...props}\n >\n {children}\n </button>\n );\n};\nDropdownMenuTrigger.displayName = 'DropdownMenuTrigger';\n\nconst ITEM_SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full',\n right: 'top-full',\n bottom: 'top-full',\n left: 'top-full',\n};\n\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\nconst MENUCONTENT_VARIANT_CLASSES = {\n menu: 'p-1',\n profile: 'p-6',\n};\n\nconst MenuLabel = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n inset?: boolean;\n store?: DropdownStoreApi;\n }\n>(({ className, inset, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={`text-sm w-full ${inset ? 'pl-8' : ''} ${className ?? ''}`}\n {...props}\n />\n );\n});\nMenuLabel.displayName = 'MenuLabel';\n\nconst DropdownMenuContent = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n variant?: 'menu' | 'profile';\n sideOffset?: number;\n store?: DropdownStoreApi;\n }\n>(\n (\n {\n className,\n align = 'start',\n side = 'bottom',\n variant = 'menu',\n sideOffset = 4,\n children,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useDropdownStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const [isVisible, setIsVisible] = useState(open);\n\n useEffect(() => {\n if (open) {\n setIsVisible(true);\n } else {\n const timer = setTimeout(() => setIsVisible(false), 200);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n if (!isVisible) return null;\n\n const getPositionClasses = () => {\n const vertical = SIDE_CLASSES[side];\n const horizontal = ALIGN_CLASSES[align];\n\n return `absolute ${vertical} ${horizontal}`;\n };\n\n const variantClasses = MENUCONTENT_VARIANT_CLASSES[variant];\n return (\n <div\n ref={ref}\n role=\"menu\"\n className={`\n bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md border-border-100\n ${open ? 'animate-in fade-in-0 zoom-in-95' : 'animate-out fade-out-0 zoom-out-95'}\n ${getPositionClasses()}\n ${variantClasses}\n ${className}\n `}\n style={{\n marginTop: side === 'bottom' ? sideOffset : undefined,\n marginBottom: side === 'top' ? sideOffset : undefined,\n marginLeft: side === 'right' ? sideOffset : undefined,\n marginRight: side === 'left' ? sideOffset : undefined,\n }}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nDropdownMenuContent.displayName = 'DropdownMenuContent';\n\nconst DropdownMenuItem = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n inset?: boolean;\n size?: 'small' | 'medium';\n iconLeft?: ReactNode;\n iconRight?: ReactNode;\n disabled?: boolean;\n variant?: 'profile' | 'menu';\n store?: DropdownStoreApi;\n }\n>(\n (\n {\n className,\n size = 'small',\n children,\n iconRight,\n iconLeft,\n disabled = false,\n onClick,\n variant = 'menu',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useDropdownStore(externalStore);\n const setOpen = useStore(store, (s) => s.setOpen);\n const sizeClasses = ITEM_SIZE_CLASSES[size];\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n onClick?.(e as MouseEvent<HTMLDivElement>);\n setOpen(false);\n };\n\n const getVariantClasses = () => {\n if (variant === 'profile') {\n return 'relative flex flex-row justify-between select-none items-center gap-2 rounded-sm p-4 text-sm outline-none transition-colors [&>svg]:size-6 [&>svg]:shrink-0';\n }\n return 'relative flex select-none items-center gap-2 rounded-sm p-3 text-sm outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0';\n };\n\n const getVariantProps = () => {\n return variant === 'profile' ? { 'data-variant': 'profile' } : {};\n };\n\n return (\n <div\n ref={ref}\n role=\"menuitem\"\n {...getVariantProps()}\n aria-disabled={disabled}\n className={`\n focus-visible:bg-background-50\n ${getVariantClasses()}\n ${sizeClasses}\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n {iconLeft}\n <span className=\"w-full text-md\">{children}</span>\n {iconRight}\n </div>\n );\n }\n);\nDropdownMenuItem.displayName = 'DropdownMenuItem';\n\nconst DropdownMenuSeparator = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }\n>(({ className, store: _store, ...props }, ref) => (\n <div\n ref={ref}\n className={`my-1 h-px bg-border-200 ${className}`}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName = 'DropdownMenuSeparator';\n\n// Componentes específicos do ProfileMenu\nconst ProfileMenuTrigger = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & { store?: DropdownStoreApi }\n>(({ className, onClick, store: externalStore, ...props }, ref) => {\n const store = useDropdownStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n return (\n <button\n ref={ref}\n className={`rounded-lg size-10 bg-background-50 flex items-center justify-center ${className}`}\n onClick={(e) => {\n e.stopPropagation();\n toggleOpen();\n onClick?.(e);\n }}\n aria-expanded={open}\n {...props}\n >\n <span className=\"size-6 rounded-full bg-background-100 flex items-center justify-center\">\n <User className=\"text-background-950\" size={18} />\n </span>\n </button>\n );\n});\nProfileMenuTrigger.displayName = 'ProfileMenuTrigger';\n\nconst ProfileMenuHeader = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n name: string;\n email: string;\n store?: DropdownStoreApi;\n }\n>(({ className, name, email, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-component=\"ProfileMenuHeader\"\n className={`\n flex flex-row gap-4 items-center\n ${className}\n `}\n {...props}\n >\n <span className=\"size-16 bg-background-100 rounded-full flex items-center justify-center\">\n <User size={34} className=\"text-background-950\" />\n </span>\n <div className=\"flex flex-col \">\n <p className=\"text-xl font-bold text-text-950\">{name}</p>\n <p className=\"text-md text-text-600\">{email}</p>\n </div>\n </div>\n );\n});\nProfileMenuHeader.displayName = 'ProfileMenuHeader';\n\nconst ProfileMenuSection = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }\n>(({ className, children, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={`\n flex flex-col p-2\n ${className}\n `}\n {...props}\n >\n {children}\n </div>\n );\n});\nProfileMenuSection.displayName = 'ProfileMenuSection';\n\nconst ProfileMenuFooter = ({\n className,\n disabled = false,\n onClick,\n store: externalStore,\n ...props\n}: HTMLAttributes<HTMLButtonElement> & {\n disabled?: boolean;\n store?: DropdownStoreApi;\n}) => {\n const store = useDropdownStore(externalStore);\n const setOpen = useStore(store, (s) => s.setOpen);\n\n return (\n <Button\n variant=\"outline\"\n className={`w-full ${className}`}\n disabled={disabled}\n onClick={(e) => {\n setOpen(false);\n onClick?.(e);\n }}\n {...props}\n >\n <span className=\"mr-2 flex items-center\">\n <SignOut />\n </span>\n <span>Sair</span>\n </Button>\n );\n};\nProfileMenuFooter.displayName = 'ProfileMenuFooter';\n\n// Exportações\nexport default DropdownMenu;\nexport {\n // Componentes genéricos\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n MenuLabel,\n DropdownMenuSeparator,\n\n // Componentes específicos do ProfileMenu\n ProfileMenuTrigger,\n ProfileMenuHeader,\n ProfileMenuSection,\n ProfileMenuFooter,\n};\n","import { ButtonHTMLAttributes, ReactNode } from 'react';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={`${baseClasses} ${variantClasses} ${sizeClasses} ${className}`}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n"],"mappings":"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","names":["jsx","jsxs"]}
|
package/dist/Menu/index.js
CHANGED
|
@@ -159,9 +159,10 @@ var MenuItem = (0, import_react.forwardRef)(
|
|
|
159
159
|
{
|
|
160
160
|
"data-variant": "menu2",
|
|
161
161
|
className: `
|
|
162
|
-
flex flex-row items-center p-4 gap-2 border-b-
|
|
162
|
+
w-full flex flex-row items-center p-4 gap-2 border-b-4 border-transparent text-text-950 text-sx font-bold cursor-pointer focus:rounded-sm
|
|
163
163
|
focus:outline-none focus:border-indicator-info focus:border-2
|
|
164
164
|
${selectedValue === value ? "border-b-primary-950" : ""}
|
|
165
|
+
${className ?? ""}
|
|
165
166
|
`,
|
|
166
167
|
...commonProps,
|
|
167
168
|
children
|
|
@@ -172,7 +173,7 @@ var MenuItem = (0, import_react.forwardRef)(
|
|
|
172
173
|
{
|
|
173
174
|
"data-variant": "breadcrumb",
|
|
174
175
|
className: `
|
|
175
|
-
p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs
|
|
176
|
+
w-full p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs
|
|
176
177
|
focus:outline-none focus:border-indicator-info focus:border-2
|
|
177
178
|
${selectedValue === value ? "text-primary-950" : "text-text-600"}
|
|
178
179
|
${className ?? ""}
|
package/dist/Menu/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Menu/Menu.tsx"],"sourcesContent":["import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useState,\n} from 'react';\nimport { CaretLeft, CaretRight } from 'phosphor-react';\n\ntype MenuVariant = 'menu' | 'menu2' | 'breadcrumb';\n\ninterface MenuStore {\n value: string;\n setValue: (value: string) => void;\n}\n\ntype MenuStoreApi = StoreApi<MenuStore>;\n\nconst createMenuStore = (): MenuStoreApi =>\n create<MenuStore>((set) => ({\n value: '',\n setValue: (value) => set({ value }),\n }));\n\nexport const useMenuStore = (externalStore?: MenuStoreApi) => {\n if (!externalStore) throw new Error('MenuItem must be inside Menu');\n return externalStore;\n};\n\ninterface MenuProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n defaultValue: string;\n value?: string;\n variant?: MenuVariant;\n onValueChange?: (value: string) => void;\n}\n\nconst VARIANT_CLASSES = {\n menu: 'bg-background shadow-soft-shadow-1',\n menu2: '',\n breadcrumb: '',\n};\n\nconst Menu = forwardRef<HTMLDivElement, MenuProps>(\n (\n {\n className,\n children,\n defaultValue,\n value: propValue,\n variant = 'menu',\n onValueChange,\n ...props\n },\n ref\n ) => {\n const storeRef = useRef<MenuStoreApi>(null);\n storeRef.current ??= createMenuStore();\n const store = storeRef.current;\n const { setValue, value } = useStore(store, (s) => s);\n\n useEffect(() => {\n setValue(propValue ?? defaultValue);\n }, [defaultValue, propValue, setValue]);\n\n useEffect(() => {\n onValueChange?.(value);\n }, [value, onValueChange]);\n\n const baseClasses =\n 'w-full py-2 px-6 flex flex-row items-center justify-center';\n const variantClasses = VARIANT_CLASSES[variant];\n\n return (\n <div\n ref={ref}\n className={`\n ${baseClasses}\n ${variantClasses}\n ${className ?? ''}\n `}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\nMenu.displayName = 'Menu';\n\ninterface MenuContentProps extends HTMLAttributes<HTMLUListElement> {\n children: ReactNode;\n variant?: MenuVariant;\n}\n\nconst MenuContent = forwardRef<HTMLUListElement, MenuContentProps>(\n ({ className, children, variant = 'menu', ...props }, ref) => {\n const baseClasses = 'w-full flex flex-row items-center gap-2';\n\n const variantClasses =\n variant === 'menu2' ? 'overflow-x-auto scroll-smooth' : '';\n\n return (\n <ul\n ref={ref}\n className={`\n ${baseClasses}\n ${variantClasses}\n ${className ?? ''}\n `}\n style={\n variant === 'menu2'\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n {...props}\n >\n {children}\n </ul>\n );\n }\n);\nMenuContent.displayName = 'MenuContent';\n\ninterface MenuItemProps extends HTMLAttributes<HTMLLIElement> {\n value: string;\n disabled?: boolean;\n store?: MenuStoreApi;\n variant?: MenuVariant;\n}\n\nconst MenuItem = forwardRef<HTMLLIElement, MenuItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n variant = 'menu',\n ...props\n },\n ref\n ) => {\n const store = useMenuStore(externalStore);\n const { value: selectedValue, setValue } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLLIElement> | KeyboardEvent<HTMLLIElement>\n ) => {\n if (!disabled) setValue(value);\n props.onClick?.(e as MouseEvent<HTMLLIElement>);\n };\n\n const commonProps = {\n role: 'menuitem',\n 'aria-disabled': disabled,\n ref,\n onClick: handleClick,\n onKeyDown: (e: KeyboardEvent<HTMLLIElement>) => {\n if (['Enter', ' '].includes(e.key)) handleClick(e);\n },\n tabIndex: disabled ? -1 : 0,\n onMouseDown: (e: MouseEvent<HTMLLIElement>) => {\n e.preventDefault();\n },\n ...props,\n };\n\n const variants: Record<string, ReactNode> = {\n menu: (\n <li\n data-variant=\"menu\"\n className={`\n w-full flex flex-col gap-0.5 items-center py-1 px-2 rounded-sm font-medium text-xs\n [&>svg]:size-6 cursor-pointer hover:bg-primary-600 hover:text-text\n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'bg-primary-50 text-primary-950' : 'text-text-950'}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n {children}\n </li>\n ),\n menu2: (\n <li\n data-variant=\"menu2\"\n className={`\n flex flex-row items-center p-4 gap-2 border-b-2 border-transparent text-text-950 text-sx font-bold cursor-pointer focus:rounded-sm\n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'border-b-primary-950' : ''}\n `}\n {...commonProps}\n >\n {children}\n </li>\n ),\n breadcrumb: (\n <li\n data-variant=\"breadcrumb\"\n className={`\n p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs \n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'text-primary-950' : 'text-text-600'}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n <span\n className={`\n border-b border-text-600 hover:border-primary-600 text-inherit\n ${selectedValue === value ? 'border-b-primary-950' : 'border-b-primary-600'}\n `}\n >\n {children}\n </span>\n </li>\n ),\n };\n\n return variants[variant] ?? variants['menu'];\n }\n);\nMenuItem.displayName = 'MenuItem';\n\nconst MenuItemIcon = ({\n className,\n icon,\n ...props\n}: HTMLAttributes<HTMLSpanElement> & { icon: ReactNode }) => (\n <span\n className={`\n bg-background-500 w-[21px] h-[21px] flex items-center justify-center\n [&>svg]:w-[17px] [&>svg]:h-[17px] rounded-sm ${className ?? ''}\n `}\n {...props}\n >\n {icon}\n </span>\n);\n\nconst MenuSeparator = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(\n ({ className, children, ...props }, ref) => (\n <li\n ref={ref}\n aria-hidden=\"true\"\n className={`[&>svg]:w-4 [&>svg]:h-4 text-text-600 ${className ?? ''}`}\n {...props}\n >\n {children ?? <CaretRight />}\n </li>\n )\n);\nMenuSeparator.displayName = 'MenuSeparator';\n\nexport const internalScroll = (\n container: HTMLUListElement | null,\n direction: 'left' | 'right'\n) => {\n if (!container) return;\n container.scrollBy({\n left: direction === 'left' ? -150 : 150,\n behavior: 'smooth',\n });\n};\n\nexport const internalCheckScroll = (\n container: HTMLUListElement | null,\n setShowLeftArrow: (v: boolean) => void,\n setShowRightArrow: (v: boolean) => void\n) => {\n if (!container) return;\n const { scrollLeft, scrollWidth, clientWidth } = container;\n setShowLeftArrow(scrollLeft > 0);\n setShowRightArrow(scrollLeft + clientWidth < scrollWidth);\n};\n\ninterface MenuOverflowProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n defaultValue: string;\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nconst MenuOverflow = ({\n children,\n className,\n defaultValue,\n value,\n onValueChange,\n ...props\n}: MenuOverflowProps) => {\n const containerRef = useRef<HTMLUListElement>(null);\n const [showLeftArrow, setShowLeftArrow] = useState(false);\n const [showRightArrow, setShowRightArrow] = useState(false);\n\n useEffect(() => {\n const checkScroll = () =>\n internalCheckScroll(\n containerRef.current,\n setShowLeftArrow,\n setShowRightArrow\n );\n checkScroll();\n const container = containerRef.current;\n container?.addEventListener('scroll', checkScroll);\n window.addEventListener('resize', checkScroll);\n return () => {\n container?.removeEventListener('scroll', checkScroll);\n window.removeEventListener('resize', checkScroll);\n };\n }, []);\n\n return (\n <div\n data-testid=\"menu-overflow-wrapper\"\n className={`relative w-full overflow-hidden ${className ?? ''}`}\n >\n {showLeftArrow && (\n <button\n onClick={() => internalScroll(containerRef.current, 'left')}\n className=\"absolute left-0 top-1/2 -translate-y-1/2 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-md cursor-pointer\"\n data-testid=\"scroll-left-button\"\n >\n <CaretLeft size={16} />\n <span className=\"sr-only\">Scroll left</span>\n </button>\n )}\n\n <Menu\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n value={value}\n variant=\"menu2\"\n {...props}\n >\n <MenuContent ref={containerRef} variant=\"menu2\">\n {children}\n </MenuContent>\n </Menu>\n\n {showRightArrow && (\n <button\n onClick={() => internalScroll(containerRef.current, 'right')}\n className=\"absolute right-0 top-1/2 -translate-y-1/2 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-md cursor-pointer\"\n data-testid=\"scroll-right-button\"\n >\n <CaretRight size={16} />\n <span className=\"sr-only\">Scroll right</span>\n </button>\n )}\n </div>\n );\n};\n\nconst injectStore = (children: ReactNode, store: MenuStoreApi): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n const typedChild = child as ReactElement<any>;\n const shouldInject = typedChild.type === MenuItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\nexport default Menu;\nexport {\n Menu,\n MenuContent,\n MenuItem,\n MenuSeparator,\n MenuOverflow,\n MenuItemIcon,\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/Menu/Menu.tsx"],"sourcesContent":["import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useState,\n} from 'react';\nimport { CaretLeft, CaretRight } from 'phosphor-react';\n\ntype MenuVariant = 'menu' | 'menu2' | 'breadcrumb';\n\ninterface MenuStore {\n value: string;\n setValue: (value: string) => void;\n}\n\ntype MenuStoreApi = StoreApi<MenuStore>;\n\nconst createMenuStore = (): MenuStoreApi =>\n create<MenuStore>((set) => ({\n value: '',\n setValue: (value) => set({ value }),\n }));\n\nexport const useMenuStore = (externalStore?: MenuStoreApi) => {\n if (!externalStore) throw new Error('MenuItem must be inside Menu');\n return externalStore;\n};\n\ninterface MenuProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n defaultValue: string;\n value?: string;\n variant?: MenuVariant;\n onValueChange?: (value: string) => void;\n}\n\nconst VARIANT_CLASSES = {\n menu: 'bg-background shadow-soft-shadow-1',\n menu2: '',\n breadcrumb: '',\n};\n\nconst Menu = forwardRef<HTMLDivElement, MenuProps>(\n (\n {\n className,\n children,\n defaultValue,\n value: propValue,\n variant = 'menu',\n onValueChange,\n ...props\n },\n ref\n ) => {\n const storeRef = useRef<MenuStoreApi>(null);\n storeRef.current ??= createMenuStore();\n const store = storeRef.current;\n const { setValue, value } = useStore(store, (s) => s);\n\n useEffect(() => {\n setValue(propValue ?? defaultValue);\n }, [defaultValue, propValue, setValue]);\n\n useEffect(() => {\n onValueChange?.(value);\n }, [value, onValueChange]);\n\n const baseClasses =\n 'w-full py-2 px-6 flex flex-row items-center justify-center';\n const variantClasses = VARIANT_CLASSES[variant];\n\n return (\n <div\n ref={ref}\n className={`\n ${baseClasses}\n ${variantClasses}\n ${className ?? ''}\n `}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\nMenu.displayName = 'Menu';\n\ninterface MenuContentProps extends HTMLAttributes<HTMLUListElement> {\n children: ReactNode;\n variant?: MenuVariant;\n}\n\nconst MenuContent = forwardRef<HTMLUListElement, MenuContentProps>(\n ({ className, children, variant = 'menu', ...props }, ref) => {\n const baseClasses = 'w-full flex flex-row items-center gap-2';\n\n const variantClasses =\n variant === 'menu2' ? 'overflow-x-auto scroll-smooth' : '';\n\n return (\n <ul\n ref={ref}\n className={`\n ${baseClasses}\n ${variantClasses}\n ${className ?? ''}\n `}\n style={\n variant === 'menu2'\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n {...props}\n >\n {children}\n </ul>\n );\n }\n);\nMenuContent.displayName = 'MenuContent';\n\ninterface MenuItemProps extends HTMLAttributes<HTMLLIElement> {\n value: string;\n disabled?: boolean;\n store?: MenuStoreApi;\n variant?: MenuVariant;\n}\n\nconst MenuItem = forwardRef<HTMLLIElement, MenuItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n variant = 'menu',\n ...props\n },\n ref\n ) => {\n const store = useMenuStore(externalStore);\n const { value: selectedValue, setValue } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLLIElement> | KeyboardEvent<HTMLLIElement>\n ) => {\n if (!disabled) setValue(value);\n props.onClick?.(e as MouseEvent<HTMLLIElement>);\n };\n\n const commonProps = {\n role: 'menuitem',\n 'aria-disabled': disabled,\n ref,\n onClick: handleClick,\n onKeyDown: (e: KeyboardEvent<HTMLLIElement>) => {\n if (['Enter', ' '].includes(e.key)) handleClick(e);\n },\n tabIndex: disabled ? -1 : 0,\n onMouseDown: (e: MouseEvent<HTMLLIElement>) => {\n e.preventDefault();\n },\n ...props,\n };\n\n const variants: Record<string, ReactNode> = {\n menu: (\n <li\n data-variant=\"menu\"\n className={`\n w-full flex flex-col gap-0.5 items-center py-1 px-2 rounded-sm font-medium text-xs\n [&>svg]:size-6 cursor-pointer hover:bg-primary-600 hover:text-text\n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'bg-primary-50 text-primary-950' : 'text-text-950'}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n {children}\n </li>\n ),\n menu2: (\n <li\n data-variant=\"menu2\"\n className={`\n w-full flex flex-row items-center p-4 gap-2 border-b-4 border-transparent text-text-950 text-sx font-bold cursor-pointer focus:rounded-sm\n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'border-b-primary-950' : ''}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n {children}\n </li>\n ),\n breadcrumb: (\n <li\n data-variant=\"breadcrumb\"\n className={`\n w-full p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs \n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'text-primary-950' : 'text-text-600'}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n <span\n className={`\n border-b border-text-600 hover:border-primary-600 text-inherit\n ${selectedValue === value ? 'border-b-primary-950' : 'border-b-primary-600'}\n `}\n >\n {children}\n </span>\n </li>\n ),\n };\n\n return variants[variant] ?? variants['menu'];\n }\n);\nMenuItem.displayName = 'MenuItem';\n\nconst MenuItemIcon = ({\n className,\n icon,\n ...props\n}: HTMLAttributes<HTMLSpanElement> & { icon: ReactNode }) => (\n <span\n className={`\n bg-background-500 w-[21px] h-[21px] flex items-center justify-center\n [&>svg]:w-[17px] [&>svg]:h-[17px] rounded-sm ${className ?? ''}\n `}\n {...props}\n >\n {icon}\n </span>\n);\n\nconst MenuSeparator = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(\n ({ className, children, ...props }, ref) => (\n <li\n ref={ref}\n aria-hidden=\"true\"\n className={`[&>svg]:w-4 [&>svg]:h-4 text-text-600 ${className ?? ''}`}\n {...props}\n >\n {children ?? <CaretRight />}\n </li>\n )\n);\nMenuSeparator.displayName = 'MenuSeparator';\n\nexport const internalScroll = (\n container: HTMLUListElement | null,\n direction: 'left' | 'right'\n) => {\n if (!container) return;\n container.scrollBy({\n left: direction === 'left' ? -150 : 150,\n behavior: 'smooth',\n });\n};\n\nexport const internalCheckScroll = (\n container: HTMLUListElement | null,\n setShowLeftArrow: (v: boolean) => void,\n setShowRightArrow: (v: boolean) => void\n) => {\n if (!container) return;\n const { scrollLeft, scrollWidth, clientWidth } = container;\n setShowLeftArrow(scrollLeft > 0);\n setShowRightArrow(scrollLeft + clientWidth < scrollWidth);\n};\n\ninterface MenuOverflowProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n defaultValue: string;\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nconst MenuOverflow = ({\n children,\n className,\n defaultValue,\n value,\n onValueChange,\n ...props\n}: MenuOverflowProps) => {\n const containerRef = useRef<HTMLUListElement>(null);\n const [showLeftArrow, setShowLeftArrow] = useState(false);\n const [showRightArrow, setShowRightArrow] = useState(false);\n\n useEffect(() => {\n const checkScroll = () =>\n internalCheckScroll(\n containerRef.current,\n setShowLeftArrow,\n setShowRightArrow\n );\n checkScroll();\n const container = containerRef.current;\n container?.addEventListener('scroll', checkScroll);\n window.addEventListener('resize', checkScroll);\n return () => {\n container?.removeEventListener('scroll', checkScroll);\n window.removeEventListener('resize', checkScroll);\n };\n }, []);\n\n return (\n <div\n data-testid=\"menu-overflow-wrapper\"\n className={`relative w-full overflow-hidden ${className ?? ''}`}\n >\n {showLeftArrow && (\n <button\n onClick={() => internalScroll(containerRef.current, 'left')}\n className=\"absolute left-0 top-1/2 -translate-y-1/2 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-md cursor-pointer\"\n data-testid=\"scroll-left-button\"\n >\n <CaretLeft size={16} />\n <span className=\"sr-only\">Scroll left</span>\n </button>\n )}\n\n <Menu\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n value={value}\n variant=\"menu2\"\n {...props}\n >\n <MenuContent ref={containerRef} variant=\"menu2\">\n {children}\n </MenuContent>\n </Menu>\n\n {showRightArrow && (\n <button\n onClick={() => internalScroll(containerRef.current, 'right')}\n className=\"absolute right-0 top-1/2 -translate-y-1/2 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-md cursor-pointer\"\n data-testid=\"scroll-right-button\"\n >\n <CaretRight size={16} />\n <span className=\"sr-only\">Scroll right</span>\n </button>\n )}\n </div>\n );\n};\n\nconst injectStore = (children: ReactNode, store: MenuStoreApi): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n const typedChild = child as ReactElement<any>;\n const shouldInject = typedChild.type === MenuItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\nexport default Menu;\nexport {\n Menu,\n MenuContent,\n MenuItem,\n MenuSeparator,\n MenuOverflow,\n MenuItemIcon,\n};\n"],"mappings":"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","names":[]}
|
package/dist/Menu/index.mjs
CHANGED
|
@@ -134,9 +134,10 @@ var MenuItem = forwardRef(
|
|
|
134
134
|
{
|
|
135
135
|
"data-variant": "menu2",
|
|
136
136
|
className: `
|
|
137
|
-
flex flex-row items-center p-4 gap-2 border-b-
|
|
137
|
+
w-full flex flex-row items-center p-4 gap-2 border-b-4 border-transparent text-text-950 text-sx font-bold cursor-pointer focus:rounded-sm
|
|
138
138
|
focus:outline-none focus:border-indicator-info focus:border-2
|
|
139
139
|
${selectedValue === value ? "border-b-primary-950" : ""}
|
|
140
|
+
${className ?? ""}
|
|
140
141
|
`,
|
|
141
142
|
...commonProps,
|
|
142
143
|
children
|
|
@@ -147,7 +148,7 @@ var MenuItem = forwardRef(
|
|
|
147
148
|
{
|
|
148
149
|
"data-variant": "breadcrumb",
|
|
149
150
|
className: `
|
|
150
|
-
p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs
|
|
151
|
+
w-full p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs
|
|
151
152
|
focus:outline-none focus:border-indicator-info focus:border-2
|
|
152
153
|
${selectedValue === value ? "text-primary-950" : "text-text-600"}
|
|
153
154
|
${className ?? ""}
|
package/dist/Menu/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Menu/Menu.tsx"],"sourcesContent":["import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useState,\n} from 'react';\nimport { CaretLeft, CaretRight } from 'phosphor-react';\n\ntype MenuVariant = 'menu' | 'menu2' | 'breadcrumb';\n\ninterface MenuStore {\n value: string;\n setValue: (value: string) => void;\n}\n\ntype MenuStoreApi = StoreApi<MenuStore>;\n\nconst createMenuStore = (): MenuStoreApi =>\n create<MenuStore>((set) => ({\n value: '',\n setValue: (value) => set({ value }),\n }));\n\nexport const useMenuStore = (externalStore?: MenuStoreApi) => {\n if (!externalStore) throw new Error('MenuItem must be inside Menu');\n return externalStore;\n};\n\ninterface MenuProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n defaultValue: string;\n value?: string;\n variant?: MenuVariant;\n onValueChange?: (value: string) => void;\n}\n\nconst VARIANT_CLASSES = {\n menu: 'bg-background shadow-soft-shadow-1',\n menu2: '',\n breadcrumb: '',\n};\n\nconst Menu = forwardRef<HTMLDivElement, MenuProps>(\n (\n {\n className,\n children,\n defaultValue,\n value: propValue,\n variant = 'menu',\n onValueChange,\n ...props\n },\n ref\n ) => {\n const storeRef = useRef<MenuStoreApi>(null);\n storeRef.current ??= createMenuStore();\n const store = storeRef.current;\n const { setValue, value } = useStore(store, (s) => s);\n\n useEffect(() => {\n setValue(propValue ?? defaultValue);\n }, [defaultValue, propValue, setValue]);\n\n useEffect(() => {\n onValueChange?.(value);\n }, [value, onValueChange]);\n\n const baseClasses =\n 'w-full py-2 px-6 flex flex-row items-center justify-center';\n const variantClasses = VARIANT_CLASSES[variant];\n\n return (\n <div\n ref={ref}\n className={`\n ${baseClasses}\n ${variantClasses}\n ${className ?? ''}\n `}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\nMenu.displayName = 'Menu';\n\ninterface MenuContentProps extends HTMLAttributes<HTMLUListElement> {\n children: ReactNode;\n variant?: MenuVariant;\n}\n\nconst MenuContent = forwardRef<HTMLUListElement, MenuContentProps>(\n ({ className, children, variant = 'menu', ...props }, ref) => {\n const baseClasses = 'w-full flex flex-row items-center gap-2';\n\n const variantClasses =\n variant === 'menu2' ? 'overflow-x-auto scroll-smooth' : '';\n\n return (\n <ul\n ref={ref}\n className={`\n ${baseClasses}\n ${variantClasses}\n ${className ?? ''}\n `}\n style={\n variant === 'menu2'\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n {...props}\n >\n {children}\n </ul>\n );\n }\n);\nMenuContent.displayName = 'MenuContent';\n\ninterface MenuItemProps extends HTMLAttributes<HTMLLIElement> {\n value: string;\n disabled?: boolean;\n store?: MenuStoreApi;\n variant?: MenuVariant;\n}\n\nconst MenuItem = forwardRef<HTMLLIElement, MenuItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n variant = 'menu',\n ...props\n },\n ref\n ) => {\n const store = useMenuStore(externalStore);\n const { value: selectedValue, setValue } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLLIElement> | KeyboardEvent<HTMLLIElement>\n ) => {\n if (!disabled) setValue(value);\n props.onClick?.(e as MouseEvent<HTMLLIElement>);\n };\n\n const commonProps = {\n role: 'menuitem',\n 'aria-disabled': disabled,\n ref,\n onClick: handleClick,\n onKeyDown: (e: KeyboardEvent<HTMLLIElement>) => {\n if (['Enter', ' '].includes(e.key)) handleClick(e);\n },\n tabIndex: disabled ? -1 : 0,\n onMouseDown: (e: MouseEvent<HTMLLIElement>) => {\n e.preventDefault();\n },\n ...props,\n };\n\n const variants: Record<string, ReactNode> = {\n menu: (\n <li\n data-variant=\"menu\"\n className={`\n w-full flex flex-col gap-0.5 items-center py-1 px-2 rounded-sm font-medium text-xs\n [&>svg]:size-6 cursor-pointer hover:bg-primary-600 hover:text-text\n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'bg-primary-50 text-primary-950' : 'text-text-950'}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n {children}\n </li>\n ),\n menu2: (\n <li\n data-variant=\"menu2\"\n className={`\n flex flex-row items-center p-4 gap-2 border-b-2 border-transparent text-text-950 text-sx font-bold cursor-pointer focus:rounded-sm\n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'border-b-primary-950' : ''}\n `}\n {...commonProps}\n >\n {children}\n </li>\n ),\n breadcrumb: (\n <li\n data-variant=\"breadcrumb\"\n className={`\n p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs \n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'text-primary-950' : 'text-text-600'}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n <span\n className={`\n border-b border-text-600 hover:border-primary-600 text-inherit\n ${selectedValue === value ? 'border-b-primary-950' : 'border-b-primary-600'}\n `}\n >\n {children}\n </span>\n </li>\n ),\n };\n\n return variants[variant] ?? variants['menu'];\n }\n);\nMenuItem.displayName = 'MenuItem';\n\nconst MenuItemIcon = ({\n className,\n icon,\n ...props\n}: HTMLAttributes<HTMLSpanElement> & { icon: ReactNode }) => (\n <span\n className={`\n bg-background-500 w-[21px] h-[21px] flex items-center justify-center\n [&>svg]:w-[17px] [&>svg]:h-[17px] rounded-sm ${className ?? ''}\n `}\n {...props}\n >\n {icon}\n </span>\n);\n\nconst MenuSeparator = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(\n ({ className, children, ...props }, ref) => (\n <li\n ref={ref}\n aria-hidden=\"true\"\n className={`[&>svg]:w-4 [&>svg]:h-4 text-text-600 ${className ?? ''}`}\n {...props}\n >\n {children ?? <CaretRight />}\n </li>\n )\n);\nMenuSeparator.displayName = 'MenuSeparator';\n\nexport const internalScroll = (\n container: HTMLUListElement | null,\n direction: 'left' | 'right'\n) => {\n if (!container) return;\n container.scrollBy({\n left: direction === 'left' ? -150 : 150,\n behavior: 'smooth',\n });\n};\n\nexport const internalCheckScroll = (\n container: HTMLUListElement | null,\n setShowLeftArrow: (v: boolean) => void,\n setShowRightArrow: (v: boolean) => void\n) => {\n if (!container) return;\n const { scrollLeft, scrollWidth, clientWidth } = container;\n setShowLeftArrow(scrollLeft > 0);\n setShowRightArrow(scrollLeft + clientWidth < scrollWidth);\n};\n\ninterface MenuOverflowProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n defaultValue: string;\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nconst MenuOverflow = ({\n children,\n className,\n defaultValue,\n value,\n onValueChange,\n ...props\n}: MenuOverflowProps) => {\n const containerRef = useRef<HTMLUListElement>(null);\n const [showLeftArrow, setShowLeftArrow] = useState(false);\n const [showRightArrow, setShowRightArrow] = useState(false);\n\n useEffect(() => {\n const checkScroll = () =>\n internalCheckScroll(\n containerRef.current,\n setShowLeftArrow,\n setShowRightArrow\n );\n checkScroll();\n const container = containerRef.current;\n container?.addEventListener('scroll', checkScroll);\n window.addEventListener('resize', checkScroll);\n return () => {\n container?.removeEventListener('scroll', checkScroll);\n window.removeEventListener('resize', checkScroll);\n };\n }, []);\n\n return (\n <div\n data-testid=\"menu-overflow-wrapper\"\n className={`relative w-full overflow-hidden ${className ?? ''}`}\n >\n {showLeftArrow && (\n <button\n onClick={() => internalScroll(containerRef.current, 'left')}\n className=\"absolute left-0 top-1/2 -translate-y-1/2 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-md cursor-pointer\"\n data-testid=\"scroll-left-button\"\n >\n <CaretLeft size={16} />\n <span className=\"sr-only\">Scroll left</span>\n </button>\n )}\n\n <Menu\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n value={value}\n variant=\"menu2\"\n {...props}\n >\n <MenuContent ref={containerRef} variant=\"menu2\">\n {children}\n </MenuContent>\n </Menu>\n\n {showRightArrow && (\n <button\n onClick={() => internalScroll(containerRef.current, 'right')}\n className=\"absolute right-0 top-1/2 -translate-y-1/2 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-md cursor-pointer\"\n data-testid=\"scroll-right-button\"\n >\n <CaretRight size={16} />\n <span className=\"sr-only\">Scroll right</span>\n </button>\n )}\n </div>\n );\n};\n\nconst injectStore = (children: ReactNode, store: MenuStoreApi): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n const typedChild = child as ReactElement<any>;\n const shouldInject = typedChild.type === MenuItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\nexport default Menu;\nexport {\n Menu,\n MenuContent,\n MenuItem,\n MenuSeparator,\n MenuOverflow,\n MenuItemIcon,\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/Menu/Menu.tsx"],"sourcesContent":["import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useState,\n} from 'react';\nimport { CaretLeft, CaretRight } from 'phosphor-react';\n\ntype MenuVariant = 'menu' | 'menu2' | 'breadcrumb';\n\ninterface MenuStore {\n value: string;\n setValue: (value: string) => void;\n}\n\ntype MenuStoreApi = StoreApi<MenuStore>;\n\nconst createMenuStore = (): MenuStoreApi =>\n create<MenuStore>((set) => ({\n value: '',\n setValue: (value) => set({ value }),\n }));\n\nexport const useMenuStore = (externalStore?: MenuStoreApi) => {\n if (!externalStore) throw new Error('MenuItem must be inside Menu');\n return externalStore;\n};\n\ninterface MenuProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n defaultValue: string;\n value?: string;\n variant?: MenuVariant;\n onValueChange?: (value: string) => void;\n}\n\nconst VARIANT_CLASSES = {\n menu: 'bg-background shadow-soft-shadow-1',\n menu2: '',\n breadcrumb: '',\n};\n\nconst Menu = forwardRef<HTMLDivElement, MenuProps>(\n (\n {\n className,\n children,\n defaultValue,\n value: propValue,\n variant = 'menu',\n onValueChange,\n ...props\n },\n ref\n ) => {\n const storeRef = useRef<MenuStoreApi>(null);\n storeRef.current ??= createMenuStore();\n const store = storeRef.current;\n const { setValue, value } = useStore(store, (s) => s);\n\n useEffect(() => {\n setValue(propValue ?? defaultValue);\n }, [defaultValue, propValue, setValue]);\n\n useEffect(() => {\n onValueChange?.(value);\n }, [value, onValueChange]);\n\n const baseClasses =\n 'w-full py-2 px-6 flex flex-row items-center justify-center';\n const variantClasses = VARIANT_CLASSES[variant];\n\n return (\n <div\n ref={ref}\n className={`\n ${baseClasses}\n ${variantClasses}\n ${className ?? ''}\n `}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\nMenu.displayName = 'Menu';\n\ninterface MenuContentProps extends HTMLAttributes<HTMLUListElement> {\n children: ReactNode;\n variant?: MenuVariant;\n}\n\nconst MenuContent = forwardRef<HTMLUListElement, MenuContentProps>(\n ({ className, children, variant = 'menu', ...props }, ref) => {\n const baseClasses = 'w-full flex flex-row items-center gap-2';\n\n const variantClasses =\n variant === 'menu2' ? 'overflow-x-auto scroll-smooth' : '';\n\n return (\n <ul\n ref={ref}\n className={`\n ${baseClasses}\n ${variantClasses}\n ${className ?? ''}\n `}\n style={\n variant === 'menu2'\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n {...props}\n >\n {children}\n </ul>\n );\n }\n);\nMenuContent.displayName = 'MenuContent';\n\ninterface MenuItemProps extends HTMLAttributes<HTMLLIElement> {\n value: string;\n disabled?: boolean;\n store?: MenuStoreApi;\n variant?: MenuVariant;\n}\n\nconst MenuItem = forwardRef<HTMLLIElement, MenuItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n variant = 'menu',\n ...props\n },\n ref\n ) => {\n const store = useMenuStore(externalStore);\n const { value: selectedValue, setValue } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLLIElement> | KeyboardEvent<HTMLLIElement>\n ) => {\n if (!disabled) setValue(value);\n props.onClick?.(e as MouseEvent<HTMLLIElement>);\n };\n\n const commonProps = {\n role: 'menuitem',\n 'aria-disabled': disabled,\n ref,\n onClick: handleClick,\n onKeyDown: (e: KeyboardEvent<HTMLLIElement>) => {\n if (['Enter', ' '].includes(e.key)) handleClick(e);\n },\n tabIndex: disabled ? -1 : 0,\n onMouseDown: (e: MouseEvent<HTMLLIElement>) => {\n e.preventDefault();\n },\n ...props,\n };\n\n const variants: Record<string, ReactNode> = {\n menu: (\n <li\n data-variant=\"menu\"\n className={`\n w-full flex flex-col gap-0.5 items-center py-1 px-2 rounded-sm font-medium text-xs\n [&>svg]:size-6 cursor-pointer hover:bg-primary-600 hover:text-text\n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'bg-primary-50 text-primary-950' : 'text-text-950'}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n {children}\n </li>\n ),\n menu2: (\n <li\n data-variant=\"menu2\"\n className={`\n w-full flex flex-row items-center p-4 gap-2 border-b-4 border-transparent text-text-950 text-sx font-bold cursor-pointer focus:rounded-sm\n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'border-b-primary-950' : ''}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n {children}\n </li>\n ),\n breadcrumb: (\n <li\n data-variant=\"breadcrumb\"\n className={`\n w-full p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs \n focus:outline-none focus:border-indicator-info focus:border-2\n ${selectedValue === value ? 'text-primary-950' : 'text-text-600'}\n ${className ?? ''}\n `}\n {...commonProps}\n >\n <span\n className={`\n border-b border-text-600 hover:border-primary-600 text-inherit\n ${selectedValue === value ? 'border-b-primary-950' : 'border-b-primary-600'}\n `}\n >\n {children}\n </span>\n </li>\n ),\n };\n\n return variants[variant] ?? variants['menu'];\n }\n);\nMenuItem.displayName = 'MenuItem';\n\nconst MenuItemIcon = ({\n className,\n icon,\n ...props\n}: HTMLAttributes<HTMLSpanElement> & { icon: ReactNode }) => (\n <span\n className={`\n bg-background-500 w-[21px] h-[21px] flex items-center justify-center\n [&>svg]:w-[17px] [&>svg]:h-[17px] rounded-sm ${className ?? ''}\n `}\n {...props}\n >\n {icon}\n </span>\n);\n\nconst MenuSeparator = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(\n ({ className, children, ...props }, ref) => (\n <li\n ref={ref}\n aria-hidden=\"true\"\n className={`[&>svg]:w-4 [&>svg]:h-4 text-text-600 ${className ?? ''}`}\n {...props}\n >\n {children ?? <CaretRight />}\n </li>\n )\n);\nMenuSeparator.displayName = 'MenuSeparator';\n\nexport const internalScroll = (\n container: HTMLUListElement | null,\n direction: 'left' | 'right'\n) => {\n if (!container) return;\n container.scrollBy({\n left: direction === 'left' ? -150 : 150,\n behavior: 'smooth',\n });\n};\n\nexport const internalCheckScroll = (\n container: HTMLUListElement | null,\n setShowLeftArrow: (v: boolean) => void,\n setShowRightArrow: (v: boolean) => void\n) => {\n if (!container) return;\n const { scrollLeft, scrollWidth, clientWidth } = container;\n setShowLeftArrow(scrollLeft > 0);\n setShowRightArrow(scrollLeft + clientWidth < scrollWidth);\n};\n\ninterface MenuOverflowProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n defaultValue: string;\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nconst MenuOverflow = ({\n children,\n className,\n defaultValue,\n value,\n onValueChange,\n ...props\n}: MenuOverflowProps) => {\n const containerRef = useRef<HTMLUListElement>(null);\n const [showLeftArrow, setShowLeftArrow] = useState(false);\n const [showRightArrow, setShowRightArrow] = useState(false);\n\n useEffect(() => {\n const checkScroll = () =>\n internalCheckScroll(\n containerRef.current,\n setShowLeftArrow,\n setShowRightArrow\n );\n checkScroll();\n const container = containerRef.current;\n container?.addEventListener('scroll', checkScroll);\n window.addEventListener('resize', checkScroll);\n return () => {\n container?.removeEventListener('scroll', checkScroll);\n window.removeEventListener('resize', checkScroll);\n };\n }, []);\n\n return (\n <div\n data-testid=\"menu-overflow-wrapper\"\n className={`relative w-full overflow-hidden ${className ?? ''}`}\n >\n {showLeftArrow && (\n <button\n onClick={() => internalScroll(containerRef.current, 'left')}\n className=\"absolute left-0 top-1/2 -translate-y-1/2 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-md cursor-pointer\"\n data-testid=\"scroll-left-button\"\n >\n <CaretLeft size={16} />\n <span className=\"sr-only\">Scroll left</span>\n </button>\n )}\n\n <Menu\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n value={value}\n variant=\"menu2\"\n {...props}\n >\n <MenuContent ref={containerRef} variant=\"menu2\">\n {children}\n </MenuContent>\n </Menu>\n\n {showRightArrow && (\n <button\n onClick={() => internalScroll(containerRef.current, 'right')}\n className=\"absolute right-0 top-1/2 -translate-y-1/2 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-md cursor-pointer\"\n data-testid=\"scroll-right-button\"\n >\n <CaretRight size={16} />\n <span className=\"sr-only\">Scroll right</span>\n </button>\n )}\n </div>\n );\n};\n\nconst injectStore = (children: ReactNode, store: MenuStoreApi): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n const typedChild = child as ReactElement<any>;\n const shouldInject = typedChild.type === MenuItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\nexport default Menu;\nexport {\n Menu,\n MenuContent,\n MenuItem,\n MenuSeparator,\n MenuOverflow,\n MenuItemIcon,\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.css
CHANGED
|
@@ -1178,6 +1178,10 @@
|
|
|
1178
1178
|
border-bottom-style: var(--tw-border-style);
|
|
1179
1179
|
border-bottom-width: 2px;
|
|
1180
1180
|
}
|
|
1181
|
+
.border-b-4 {
|
|
1182
|
+
border-bottom-style: var(--tw-border-style);
|
|
1183
|
+
border-bottom-width: 4px;
|
|
1184
|
+
}
|
|
1181
1185
|
.border-none {
|
|
1182
1186
|
--tw-border-style: none;
|
|
1183
1187
|
border-style: none;
|
|
@@ -1737,6 +1741,9 @@
|
|
|
1737
1741
|
.text-blue-500 {
|
|
1738
1742
|
color: var(--color-blue-500);
|
|
1739
1743
|
}
|
|
1744
|
+
.text-current {
|
|
1745
|
+
color: currentcolor;
|
|
1746
|
+
}
|
|
1740
1747
|
.text-error-300 {
|
|
1741
1748
|
color: var(--color-error-300);
|
|
1742
1749
|
}
|