analytica-frontend-lib 1.0.91 → 1.0.92
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/Accordation/index.d.mts +12 -0
- package/dist/Accordation/index.d.ts +12 -1
- package/dist/Accordation/index.js +1 -0
- package/dist/Accordation/index.js.map +1 -0
- package/dist/Accordation/index.mjs +1 -0
- package/dist/Accordation/index.mjs.map +1 -0
- package/dist/Alert/index.d.mts +13 -0
- package/dist/Alert/index.d.ts +13 -1
- package/dist/Alert/index.js +1 -0
- package/dist/Alert/index.js.map +1 -0
- package/dist/Alert/index.mjs +1 -0
- package/dist/Alert/index.mjs.map +1 -0
- package/dist/AlertDialog/index.d.mts +36 -0
- package/dist/AlertDialog/index.d.ts +36 -1
- package/dist/AlertDialog/index.js +1 -0
- package/dist/AlertDialog/index.js.map +1 -0
- package/dist/AlertDialog/index.mjs +1 -0
- package/dist/AlertDialog/index.mjs.map +1 -0
- package/dist/Alternative/index.d.mts +81 -0
- package/dist/Alternative/index.d.ts +81 -1
- package/dist/Alternative/index.js +1 -0
- package/dist/Alternative/index.js.map +1 -0
- package/dist/Alternative/index.mjs +1 -0
- package/dist/Alternative/index.mjs.map +1 -0
- package/dist/Auth/AuthProvider/index.d.mts +3 -0
- package/dist/Auth/AuthProvider/index.d.ts +3 -1
- package/dist/Auth/AuthProvider/index.js +1 -0
- package/dist/Auth/AuthProvider/index.js.map +1 -0
- package/dist/Auth/AuthProvider/index.mjs +1 -0
- package/dist/Auth/AuthProvider/index.mjs.map +1 -0
- package/dist/Auth/ProtectedRoute/index.d.mts +3 -0
- package/dist/Auth/ProtectedRoute/index.d.ts +3 -1
- package/dist/Auth/ProtectedRoute/index.js +1 -0
- package/dist/Auth/ProtectedRoute/index.js.map +1 -0
- package/dist/Auth/ProtectedRoute/index.mjs +1 -0
- package/dist/Auth/ProtectedRoute/index.mjs.map +1 -0
- package/dist/Auth/PublicRoute/index.d.mts +3 -0
- package/dist/Auth/PublicRoute/index.d.ts +3 -1
- package/dist/Auth/PublicRoute/index.js +1 -0
- package/dist/Auth/PublicRoute/index.js.map +1 -0
- package/dist/Auth/PublicRoute/index.mjs +1 -0
- package/dist/Auth/PublicRoute/index.mjs.map +1 -0
- package/dist/Auth/getRootDomain/index.d.mts +3 -0
- package/dist/Auth/getRootDomain/index.d.ts +3 -1
- package/dist/Auth/getRootDomain/index.js +1 -0
- package/dist/Auth/getRootDomain/index.js.map +1 -0
- package/dist/Auth/getRootDomain/index.mjs +1 -0
- package/dist/Auth/getRootDomain/index.mjs.map +1 -0
- package/dist/Auth/index.d.mts +312 -0
- package/dist/Auth/index.d.ts +312 -1
- package/dist/Auth/index.js +1 -0
- package/dist/Auth/index.js.map +1 -0
- package/dist/Auth/index.mjs +1 -0
- package/dist/Auth/index.mjs.map +1 -0
- package/dist/Auth/useApiConfig/index.d.mts +43 -0
- package/dist/Auth/useApiConfig/index.d.ts +43 -1
- package/dist/Auth/useApiConfig/index.js +1 -0
- package/dist/Auth/useApiConfig/index.js.map +1 -0
- package/dist/Auth/useApiConfig/index.mjs +1 -0
- package/dist/Auth/useApiConfig/index.mjs.map +1 -0
- package/dist/Auth/useAuth/index.d.mts +3 -0
- package/dist/Auth/useAuth/index.d.ts +3 -1
- package/dist/Auth/useAuth/index.js +1 -0
- package/dist/Auth/useAuth/index.js.map +1 -0
- package/dist/Auth/useAuth/index.mjs +1 -0
- package/dist/Auth/useAuth/index.mjs.map +1 -0
- package/dist/Auth/useAuthGuard/index.d.mts +3 -0
- package/dist/Auth/useAuthGuard/index.d.ts +3 -1
- package/dist/Auth/useAuthGuard/index.js +1 -0
- package/dist/Auth/useAuthGuard/index.js.map +1 -0
- package/dist/Auth/useAuthGuard/index.mjs +1 -0
- package/dist/Auth/useAuthGuard/index.mjs.map +1 -0
- package/dist/Auth/useRouteAuth/index.d.mts +3 -0
- package/dist/Auth/useRouteAuth/index.d.ts +3 -1
- package/dist/Auth/useRouteAuth/index.js +1 -0
- package/dist/Auth/useRouteAuth/index.js.map +1 -0
- package/dist/Auth/useRouteAuth/index.mjs +1 -0
- package/dist/Auth/useRouteAuth/index.mjs.map +1 -0
- package/dist/Auth/useUrlAuthentication/index.d.mts +58 -0
- package/dist/Auth/useUrlAuthentication/index.d.ts +58 -1
- package/dist/Auth/useUrlAuthentication/index.js +1 -0
- package/dist/Auth/useUrlAuthentication/index.js.map +1 -0
- package/dist/Auth/useUrlAuthentication/index.mjs +1 -0
- package/dist/Auth/useUrlAuthentication/index.mjs.map +1 -0
- package/dist/Auth/withAuth/index.d.mts +3 -0
- package/dist/Auth/withAuth/index.d.ts +3 -1
- package/dist/Auth/withAuth/index.js +1 -0
- package/dist/Auth/withAuth/index.js.map +1 -0
- package/dist/Auth/withAuth/index.mjs +1 -0
- package/dist/Auth/withAuth/index.mjs.map +1 -0
- package/dist/Auth/zustandAuthAdapter/index.d.mts +75 -0
- package/dist/Auth/zustandAuthAdapter/index.d.ts +75 -1
- package/dist/Auth/zustandAuthAdapter/index.js +1 -0
- package/dist/Auth/zustandAuthAdapter/index.js.map +1 -0
- package/dist/Auth/zustandAuthAdapter/index.mjs +1 -0
- package/dist/Auth/zustandAuthAdapter/index.mjs.map +1 -0
- package/dist/Badge/index.d.mts +46 -0
- package/dist/Badge/index.d.ts +46 -1
- package/dist/Badge/index.js +1 -0
- package/dist/Badge/index.js.map +1 -0
- package/dist/Badge/index.mjs +1 -0
- package/dist/Badge/index.mjs.map +1 -0
- package/dist/Button/index.d.mts +45 -0
- package/dist/Button/index.d.ts +45 -1
- package/dist/Button/index.js +1 -0
- package/dist/Button/index.js.map +1 -0
- package/dist/Button/index.mjs +1 -0
- package/dist/Button/index.mjs.map +1 -0
- package/dist/Calendar/index.d.mts +60 -0
- package/dist/Calendar/index.d.ts +60 -1
- package/dist/Calendar/index.js +1 -0
- package/dist/Calendar/index.js.map +1 -0
- package/dist/Calendar/index.mjs +1 -0
- package/dist/Calendar/index.mjs.map +1 -0
- package/dist/Card/index.d.mts +150 -0
- package/dist/Card/index.d.ts +150 -1
- package/dist/Card/index.js +1 -0
- package/dist/Card/index.js.map +1 -0
- package/dist/Card/index.mjs +1 -0
- package/dist/Card/index.mjs.map +1 -0
- package/dist/CheckBox/index.d.mts +74 -0
- package/dist/CheckBox/index.d.ts +74 -1
- package/dist/CheckBox/index.js +1 -0
- package/dist/CheckBox/index.js.map +1 -0
- package/dist/CheckBox/index.mjs +1 -0
- package/dist/CheckBox/index.mjs.map +1 -0
- package/dist/Chips/index.d.mts +41 -0
- package/dist/Chips/index.d.ts +41 -1
- package/dist/Chips/index.js +1 -0
- package/dist/Chips/index.js.map +1 -0
- package/dist/Chips/index.mjs +1 -0
- package/dist/Chips/index.mjs.map +1 -0
- package/dist/Divider/index.d.mts +32 -0
- package/dist/Divider/index.d.ts +32 -1
- package/dist/Divider/index.js +1 -0
- package/dist/Divider/index.js.map +1 -0
- package/dist/Divider/index.mjs +1 -0
- package/dist/Divider/index.mjs.map +1 -0
- package/dist/DropdownMenu/index.d.mts +68 -0
- package/dist/DropdownMenu/index.d.ts +68 -1
- package/dist/DropdownMenu/index.js +1 -0
- package/dist/DropdownMenu/index.js.map +1 -0
- package/dist/DropdownMenu/index.mjs +1 -0
- package/dist/DropdownMenu/index.mjs.map +1 -0
- package/dist/IconButton/index.d.mts +76 -0
- package/dist/IconButton/index.d.ts +76 -1
- package/dist/IconButton/index.js +1 -0
- package/dist/IconButton/index.js.map +1 -0
- package/dist/IconButton/index.mjs +1 -0
- package/dist/IconButton/index.mjs.map +1 -0
- package/dist/IconRoundedButton/index.d.mts +34 -0
- package/dist/IconRoundedButton/index.d.ts +34 -1
- package/dist/IconRoundedButton/index.js +1 -0
- package/dist/IconRoundedButton/index.js.map +1 -0
- package/dist/IconRoundedButton/index.mjs +1 -0
- package/dist/IconRoundedButton/index.mjs.map +1 -0
- package/dist/Input/index.d.mts +27 -0
- package/dist/Input/index.d.ts +27 -1
- package/dist/Input/index.js +1 -0
- package/dist/Input/index.js.map +1 -0
- package/dist/Input/index.mjs +1 -0
- package/dist/Input/index.mjs.map +1 -0
- package/dist/Menu/index.d.mts +48 -0
- package/dist/Menu/index.d.ts +48 -1
- package/dist/Menu/index.js +1 -0
- package/dist/Menu/index.js.map +1 -0
- package/dist/Menu/index.mjs +1 -0
- package/dist/Menu/index.mjs.map +1 -0
- package/dist/Modal/index.d.mts +66 -0
- package/dist/Modal/index.d.ts +66 -1
- package/dist/Modal/index.js +1 -0
- package/dist/Modal/index.js.map +1 -0
- package/dist/Modal/index.mjs +1 -0
- package/dist/Modal/index.mjs.map +1 -0
- package/dist/MultipleChoice/index.d.mts +20 -0
- package/dist/MultipleChoice/index.d.ts +20 -1
- package/dist/MultipleChoice/index.js +1 -0
- package/dist/MultipleChoice/index.js.map +1 -0
- package/dist/MultipleChoice/index.mjs +1 -0
- package/dist/MultipleChoice/index.mjs.map +1 -0
- package/dist/NavButton/index.d.mts +57 -0
- package/dist/NavButton/index.d.ts +57 -1
- package/dist/NavButton/index.js +1 -0
- package/dist/NavButton/index.js.map +1 -0
- package/dist/NavButton/index.mjs +1 -0
- package/dist/NavButton/index.mjs.map +1 -0
- package/dist/NotFound/index.d.mts +58 -0
- package/dist/NotFound/index.d.ts +58 -1
- package/dist/NotFound/index.js +1 -0
- package/dist/NotFound/index.js.map +1 -0
- package/dist/NotFound/index.mjs +1 -0
- package/dist/NotFound/index.mjs.map +1 -0
- package/dist/ProgressBar/index.d.mts +95 -0
- package/dist/ProgressBar/index.d.ts +95 -1
- package/dist/ProgressBar/index.js +1 -0
- package/dist/ProgressBar/index.js.map +1 -0
- package/dist/ProgressBar/index.mjs +1 -0
- package/dist/ProgressBar/index.mjs.map +1 -0
- package/dist/ProgressCircle/index.d.mts +60 -0
- package/dist/ProgressCircle/index.d.ts +60 -1
- package/dist/ProgressCircle/index.js +1 -0
- package/dist/ProgressCircle/index.js.map +1 -0
- package/dist/ProgressCircle/index.mjs +1 -0
- package/dist/ProgressCircle/index.mjs.map +1 -0
- package/dist/Quiz/index.d.mts +57 -0
- package/dist/Quiz/index.d.ts +57 -1
- package/dist/Quiz/index.js +3 -2
- package/dist/Quiz/index.js.map +1 -0
- package/dist/Quiz/index.mjs +3 -2
- package/dist/Quiz/index.mjs.map +1 -0
- package/dist/Quiz/useQuizStore/index.d.mts +139 -0
- package/dist/Quiz/useQuizStore/index.d.ts +139 -1
- package/dist/Quiz/useQuizStore/index.js +1 -0
- package/dist/Quiz/useQuizStore/index.js.map +1 -0
- package/dist/Quiz/useQuizStore/index.mjs +1 -0
- package/dist/Quiz/useQuizStore/index.mjs.map +1 -0
- package/dist/Radio/index.d.mts +203 -0
- package/dist/Radio/index.d.ts +203 -1
- package/dist/Radio/index.js +1 -0
- package/dist/Radio/index.js.map +1 -0
- package/dist/Radio/index.mjs +1 -0
- package/dist/Radio/index.mjs.map +1 -0
- package/dist/Select/index.d.mts +58 -0
- package/dist/Select/index.d.ts +58 -1
- package/dist/Select/index.js +1 -0
- package/dist/Select/index.js.map +1 -0
- package/dist/Select/index.mjs +1 -0
- package/dist/Select/index.mjs.map +1 -0
- package/dist/SelectionButton/index.d.mts +57 -0
- package/dist/SelectionButton/index.d.ts +57 -1
- package/dist/SelectionButton/index.js +1 -0
- package/dist/SelectionButton/index.js.map +1 -0
- package/dist/SelectionButton/index.mjs +1 -0
- package/dist/SelectionButton/index.mjs.map +1 -0
- package/dist/Skeleton/index.d.mts +40 -0
- package/dist/Skeleton/index.d.ts +40 -1
- package/dist/Skeleton/index.js +1 -0
- package/dist/Skeleton/index.js.map +1 -0
- package/dist/Skeleton/index.mjs +1 -0
- package/dist/Skeleton/index.mjs.map +1 -0
- package/dist/Stepper/index.d.mts +169 -0
- package/dist/Stepper/index.d.ts +169 -1
- package/dist/Stepper/index.js +1 -0
- package/dist/Stepper/index.js.map +1 -0
- package/dist/Stepper/index.mjs +1 -0
- package/dist/Stepper/index.mjs.map +1 -0
- package/dist/Table/index.d.mts +17 -0
- package/dist/Table/index.d.ts +17 -1
- package/dist/Table/index.js +1 -0
- package/dist/Table/index.js.map +1 -0
- package/dist/Table/index.mjs +1 -0
- package/dist/Table/index.mjs.map +1 -0
- package/dist/Text/index.d.mts +58 -0
- package/dist/Text/index.d.ts +58 -1
- package/dist/Text/index.js +1 -0
- package/dist/Text/index.js.map +1 -0
- package/dist/Text/index.mjs +1 -0
- package/dist/Text/index.mjs.map +1 -0
- package/dist/TextArea/index.d.mts +70 -0
- package/dist/TextArea/index.d.ts +70 -1
- package/dist/TextArea/index.js +1 -0
- package/dist/TextArea/index.js.map +1 -0
- package/dist/TextArea/index.mjs +1 -0
- package/dist/TextArea/index.mjs.map +1 -0
- package/dist/Toast/ToastStore/index.d.mts +19 -0
- package/dist/Toast/ToastStore/index.d.ts +19 -1
- package/dist/Toast/ToastStore/index.js +1 -0
- package/dist/Toast/ToastStore/index.js.map +1 -0
- package/dist/Toast/ToastStore/index.mjs +1 -0
- package/dist/Toast/ToastStore/index.mjs.map +1 -0
- package/dist/Toast/Toaster/index.d.mts +16 -0
- package/dist/Toast/Toaster/index.d.ts +16 -1
- package/dist/Toast/Toaster/index.js +1 -0
- package/dist/Toast/Toaster/index.js.map +1 -0
- package/dist/Toast/Toaster/index.mjs +1 -0
- package/dist/Toast/Toaster/index.mjs.map +1 -0
- package/dist/Toast/index.d.mts +17 -0
- package/dist/Toast/index.d.ts +17 -1
- package/dist/Toast/index.js +1 -0
- package/dist/Toast/index.js.map +1 -0
- package/dist/Toast/index.mjs +1 -0
- package/dist/Toast/index.mjs.map +1 -0
- package/dist/index.css +5 -4
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +42 -2142
- package/dist/index.d.ts +42 -2142
- package/dist/index.js +3 -23
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3 -20
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +5 -4
- package/dist/styles.css.map +1 -0
- package/dist/styles.d.mts +2 -0
- package/dist/styles.d.ts +2 -0
- package/package.json +4 -5
- package/dist/CheckBox/CheckboxList/index.d.ts +0 -1
- package/dist/CheckBox/CheckboxList/index.js +0 -429
- package/dist/CheckBox/CheckboxList/index.mjs +0 -415
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/Modal/Modal.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { ReactNode, MouseEvent, useEffect, KeyboardEvent } from 'react';\nimport { X } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n xs: 'max-w-[360px]',\n sm: 'max-w-[420px]',\n md: 'max-w-[510px]',\n lg: 'max-w-[640px]',\n xl: 'max-w-[970px]',\n} as const;\n\n/**\n * Modal component props interface\n */\ntype ModalProps = {\n /** Whether the modal is open */\n isOpen: boolean;\n /** Function to close the modal */\n onClose: () => void;\n /** Modal title */\n title: string;\n /** Modal description/content */\n children: ReactNode;\n /** Size of the modal */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n /** Additional CSS classes for the modal content */\n className?: string;\n /** Whether clicking the backdrop should close the modal */\n closeOnBackdropClick?: boolean;\n /** Whether pressing Escape should close the modal */\n closeOnEscape?: boolean;\n /** Footer content (typically buttons) */\n footer?: ReactNode;\n /** Hide the close button */\n hideCloseButton?: boolean;\n};\n\n/**\n * Modal component for Analytica Ensino platforms\n *\n * A flexible modal component with multiple size variants and customizable behavior.\n *\n * @param isOpen - Whether the modal is currently open\n * @param onClose - Callback function called when the modal should be closed\n * @param title - The title displayed at the top of the modal\n * @param children - The main content of the modal\n * @param size - The size variant (xs, sm, md, lg, xl)\n * @param className - Additional CSS classes for the modal content\n * @param closeOnBackdropClick - Whether clicking the backdrop closes the modal (default: true)\n * @param closeOnEscape - Whether pressing Escape closes the modal (default: true)\n * @param footer - Footer content, typically action buttons\n * @param hideCloseButton - Whether to hide the X close button (default: false)\n * @returns A modal overlay with content\n *\n * @example\n * ```tsx\n * <Modal\n * isOpen={isModalOpen}\n * onClose={() => setIsModalOpen(false)}\n * title=\"Invite your team\"\n * size=\"md\"\n * footer={\n * <div className=\"flex gap-3\">\n * <Button variant=\"outline\" onClick={() => setIsModalOpen(false)}>Cancel</Button>\n * <Button variant=\"solid\" onClick={handleExplore}>Explore</Button>\n * </div>\n * }\n * >\n * Elevate user interactions with our versatile modals.\n * </Modal>\n * ```\n */\nconst Modal = ({\n isOpen,\n onClose,\n title,\n children,\n size = 'md',\n className = '',\n closeOnBackdropClick = true,\n closeOnEscape = true,\n footer,\n hideCloseButton = false,\n}: ModalProps) => {\n // Handle escape key\n useEffect(() => {\n if (!isOpen || !closeOnEscape) return;\n\n const handleEscape = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') {\n onClose();\n }\n };\n\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isOpen, closeOnEscape, onClose]);\n\n // Handle body scroll lock\n useEffect(() => {\n const originalOverflow = document.body.style.overflow;\n if (isOpen) {\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = originalOverflow;\n }\n\n return () => {\n document.body.style.overflow = originalOverflow;\n };\n }, [isOpen]);\n\n // Handle backdrop click\n const handleBackdropClick = (event: MouseEvent<HTMLDivElement>) => {\n if (closeOnBackdropClick && event.target === event.currentTarget) {\n onClose();\n }\n };\n\n // Handle backdrop keyboard interaction\n const handleBackdropKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (closeOnBackdropClick && (event.key === 'Enter' || event.key === ' ')) {\n onClose();\n }\n };\n\n if (!isOpen) return null;\n\n const sizeClasses = SIZE_CLASSES[size];\n const baseClasses =\n 'bg-secondary-50 rounded-3xl shadow-hard-shadow-2 border border-border-100 w-full mx-4';\n // Reset dialog default styles to prevent positioning issues\n const dialogResetClasses =\n 'p-0 m-0 border-none outline-none max-h-none static';\n const modalClasses = cn(\n baseClasses,\n sizeClasses,\n dialogResetClasses,\n className\n );\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs\"\n onClick={handleBackdropClick}\n onKeyDown={handleBackdropKeyDown}\n role=\"button\"\n tabIndex={closeOnBackdropClick ? 0 : -1}\n aria-label=\"Fechar modal clicando no fundo\"\n >\n <dialog className={modalClasses} aria-labelledby=\"modal-title\" open>\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-6\">\n <h2 id=\"modal-title\" className=\"text-lg font-semibold text-text-950\">\n {title}\n </h2>\n {!hideCloseButton && (\n <button\n onClick={onClose}\n className=\"p-1 text-text-500 hover:text-text-700 hover:bg-background-50 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-indicator-info focus:ring-offset-2\"\n aria-label=\"Fechar modal\"\n >\n <X size={18} />\n </button>\n )}\n </div>\n\n {/* Content */}\n <div className=\"px-6 pb-6\">\n <div className=\"text-text-500 font-normal text-sm leading-6\">\n {children}\n </div>\n </div>\n\n {/* Footer */}\n {footer && (\n <div className=\"flex justify-end gap-3 px-6 pb-6\">{footer}</div>\n )}\n </dialog>\n </div>\n );\n};\n\nexport default Modal;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";AAAA,SAAgC,iBAAgC;AAChE,SAAS,SAAS;;;ACDlB,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ADuJQ,SACE,KADF;AArJR,IAAM,eAAe;AAAA,EACnB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AA+DA,IAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB;AAAA,EACA,kBAAkB;AACpB,MAAkB;AAEhB,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,cAAe;AAE/B,UAAM,eAAe,CAAC,UAAoC;AACxD,UAAI,MAAM,QAAQ,UAAU;AAC1B,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,aAAS,iBAAiB,WAAW,YAAY;AACjD,WAAO,MAAM,SAAS,oBAAoB,WAAW,YAAY;AAAA,EACnE,GAAG,CAAC,QAAQ,eAAe,OAAO,CAAC;AAGnC,YAAU,MAAM;AACd,UAAM,mBAAmB,SAAS,KAAK,MAAM;AAC7C,QAAI,QAAQ;AACV,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC,OAAO;AACL,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAEA,WAAO,MAAM;AACX,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,sBAAsB,CAAC,UAAsC;AACjE,QAAI,wBAAwB,MAAM,WAAW,MAAM,eAAe;AAChE,cAAQ;AAAA,IACV;AAAA,EACF;AAGA,QAAM,wBAAwB,CAAC,UAAyC;AACtE,QAAI,yBAAyB,MAAM,QAAQ,WAAW,MAAM,QAAQ,MAAM;AACxE,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,cAAc,aAAa,IAAI;AACrC,QAAM,cACJ;AAEF,QAAM,qBACJ;AACF,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,SAAS;AAAA,MACT,WAAW;AAAA,MACX,MAAK;AAAA,MACL,UAAU,uBAAuB,IAAI;AAAA,MACrC,cAAW;AAAA,MAEX,+BAAC,YAAO,WAAW,cAAc,mBAAgB,eAAc,MAAI,MAEjE;AAAA,6BAAC,SAAI,WAAU,+CACb;AAAA,8BAAC,QAAG,IAAG,eAAc,WAAU,uCAC5B,iBACH;AAAA,UACC,CAAC,mBACA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS;AAAA,cACT,WAAU;AAAA,cACV,cAAW;AAAA,cAEX,8BAAC,KAAE,MAAM,IAAI;AAAA;AAAA,UACf;AAAA,WAEJ;AAAA,QAGA,oBAAC,SAAI,WAAU,aACb,8BAAC,SAAI,WAAU,+CACZ,UACH,GACF;AAAA,QAGC,UACC,oBAAC,SAAI,WAAU,oCAAoC,kBAAO;AAAA,SAE9D;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,gBAAQ;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { HtmlHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
interface Choice {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
status?: 'correct' | 'incorrect' | 'neutral';
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {
|
|
11
|
+
choices: Choice[];
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
name?: string;
|
|
14
|
+
selectedValues?: string[];
|
|
15
|
+
onHandleSelectedValues?: (values: string[]) => void;
|
|
16
|
+
mode?: 'interactive' | 'readonly';
|
|
17
|
+
}
|
|
18
|
+
declare const MultipleChoiceList: ({ disabled, className, choices, name, selectedValues, onHandleSelectedValues, mode, }: MultipleChoiceListProps) => react_jsx_runtime.JSX.Element;
|
|
19
|
+
|
|
20
|
+
export { MultipleChoiceList };
|
|
@@ -1 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { HtmlHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
interface Choice {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
status?: 'correct' | 'incorrect' | 'neutral';
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {
|
|
11
|
+
choices: Choice[];
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
name?: string;
|
|
14
|
+
selectedValues?: string[];
|
|
15
|
+
onHandleSelectedValues?: (values: string[]) => void;
|
|
16
|
+
mode?: 'interactive' | 'readonly';
|
|
17
|
+
}
|
|
18
|
+
declare const MultipleChoiceList: ({ disabled, className, choices, name, selectedValues, onHandleSelectedValues, mode, }: MultipleChoiceListProps) => react_jsx_runtime.JSX.Element;
|
|
19
|
+
|
|
20
|
+
export { MultipleChoiceList };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/MultipleChoice/MultipleChoice.tsx","../../src/components/CheckBox/CheckboxList.tsx","../../src/components/CheckBox/CheckBox.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Badge/Badge.tsx"],"sourcesContent":["import { HtmlHTMLAttributes, useEffect, useState } from 'react';\nimport CheckboxList, { CheckboxListItem } from '../CheckBox/CheckboxList';\nimport { cn } from '@/utils/utils';\nimport { CheckCircle, XCircle, Check } from 'phosphor-react';\nimport Badge from '../Badge/Badge';\n\ninterface Choice {\n value: string;\n label: string;\n status?: 'correct' | 'incorrect' | 'neutral';\n disabled?: boolean;\n}\n\ninterface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {\n choices: Choice[];\n disabled?: boolean;\n name?: string;\n selectedValues?: string[];\n onHandleSelectedValues?: (values: string[]) => void;\n mode?: 'interactive' | 'readonly';\n}\n\nconst MultipleChoiceList = ({\n disabled = false,\n className = '',\n choices,\n name,\n selectedValues,\n onHandleSelectedValues,\n mode = 'interactive',\n}: MultipleChoiceListProps) => {\n const [actualValue, setActualValue] = useState(selectedValues);\n\n useEffect(() => {\n setActualValue(selectedValues);\n }, [selectedValues]);\n const getStatusBadge = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getStatusStyles = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100`;\n }\n };\n\n const renderVisualCheckbox = (isSelected: boolean, isDisabled: boolean) => {\n const checkboxClasses = cn(\n 'w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center',\n isSelected\n ? 'border-primary-950 bg-primary-950 text-text'\n : 'border-border-400 bg-background',\n isDisabled && 'opacity-40 cursor-not-allowed'\n );\n\n return (\n <div className={checkboxClasses}>\n {isSelected && <Check size={16} weight=\"bold\" />}\n </div>\n );\n };\n\n if (mode === 'readonly') {\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {choices.map((choice, i) => {\n const isSelected = actualValue?.includes(choice.value) || false;\n const statusStyles = getStatusStyles(choice.status);\n const statusBadge = getStatusBadge(choice.status);\n\n return (\n <div\n key={`readonly-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n choice.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n {renderVisualCheckbox(isSelected, choice.disabled || disabled)}\n <span\n className={cn(\n 'flex-1',\n isSelected || (choice.status && choice.status != 'neutral')\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-default'\n )}\n >\n {choice.label}\n </span>\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n disabled ? 'opacity-50 cursor-not-allowed' : '',\n className\n )}\n >\n <CheckboxList\n name={name}\n values={actualValue}\n onValuesChange={(v) => {\n setActualValue(v);\n onHandleSelectedValues?.(v);\n }}\n disabled={disabled}\n >\n {choices.map((choice, i) => (\n <div\n key={`interactive-${choice.value}-${i}`}\n className=\"flex flex-row gap-2 items-center\"\n >\n <CheckboxListItem\n value={choice.value}\n id={`interactive-${choice.value}-${i}`}\n disabled={choice.disabled || disabled}\n />\n\n <label\n htmlFor={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex-1',\n actualValue?.includes(choice.value)\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n {choice.label}\n </label>\n </div>\n ))}\n </CheckboxList>\n </div>\n );\n};\n\nexport { MultipleChoiceList };\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useId,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport CheckBox from './CheckBox';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckboxList size variants\n */\ntype CheckboxListSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckboxList visual state\n */\ntype CheckboxListState =\n | 'default'\n | 'hovered'\n | 'focused'\n | 'invalid'\n | 'disabled';\n\n/**\n * CheckboxList store interface\n */\ninterface CheckboxListStore {\n values: string[];\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n onValuesChange?: (values: string[]) => void;\n disabled: boolean;\n name: string;\n}\n\ntype CheckboxListStoreApi = StoreApi<CheckboxListStore>;\n\n/**\n * Create a new CheckboxList store\n */\nconst createCheckboxListStore = (\n name: string,\n defaultValues: string[],\n disabled: boolean,\n onValuesChange?: (values: string[]) => void\n): CheckboxListStoreApi =>\n create<CheckboxListStore>((set, get) => ({\n values: defaultValues,\n setValues: (values) => {\n if (!get().disabled) {\n set({ values });\n get().onValuesChange?.(values);\n }\n },\n toggleValue: (value) => {\n if (!get().disabled) {\n const currentValues = get().values;\n const newValues = currentValues.includes(value)\n ? currentValues.filter((v) => v !== value)\n : [...currentValues, value];\n set({ values: newValues });\n get().onValuesChange?.(newValues);\n }\n },\n onValuesChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access CheckboxList store\n */\nexport const useCheckboxListStore = (externalStore?: CheckboxListStoreApi) => {\n if (!externalStore) {\n throw new Error('CheckboxListItem must be used within a CheckboxList');\n }\n return externalStore;\n};\n\n/**\n * Inject store into CheckboxListItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: CheckboxListStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n const typedChild = child as ReactElement<CheckboxListItemProps>;\n const shouldInject = typedChild.type === CheckboxListItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * CheckboxList component props interface\n */\nexport type CheckboxListProps = {\n /** Current selected values */\n values?: string[];\n /** Default selected values for uncontrolled usage */\n defaultValues?: string[];\n /** Callback when selection changes */\n onValuesChange?: (values: string[]) => void;\n /** Group name for all checkboxes */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValues'>;\n\n/**\n * CheckboxList component for flexible checkbox group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with CheckboxListItem.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]} onValuesChange={setValues}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option2\" id=\"c2\" />\n * <label htmlFor=\"c2\">Option 2</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxList = forwardRef<HTMLDivElement, CheckboxListProps>(\n (\n {\n values: propValues,\n defaultValues = [],\n onValuesChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `checkbox-list-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<CheckboxListStoreApi>(null);\n storeRef.current ??= createCheckboxListStore(\n name,\n defaultValues,\n disabled,\n onValuesChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValues } = useStore(store, (s) => s);\n\n // Call onValuesChange with initial values\n useEffect(() => {\n const currentValues = store.getState().values;\n if (currentValues.length > 0 && onValuesChange) {\n onValuesChange(currentValues);\n }\n }, []);\n\n // Handle controlled values changes\n useEffect(() => {\n if (propValues !== undefined) {\n setValues(propValues);\n }\n }, [propValues, setValues]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 w-full', className)}\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nCheckboxList.displayName = 'CheckboxList';\n\n/**\n * CheckboxListItem component props interface\n */\nexport type CheckboxListItemProps = {\n /** Value for this checkbox item */\n value: string;\n /** Store reference (automatically injected by CheckboxList) */\n store?: CheckboxListStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: CheckboxListSize;\n /** Visual state */\n state?: CheckboxListState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * CheckboxListItem component for use within CheckboxList\n *\n * A checkbox without label that works within CheckboxList context.\n * Provides just the checkbox input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxListItem = forwardRef<HTMLInputElement, CheckboxListItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useCheckboxListStore(externalStore);\n const {\n values: groupValues,\n toggleValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValues.includes(value);\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard CheckBox component for consistency and simplicity\n return (\n <CheckBox\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={() => {\n if (!isDisabled) {\n toggleValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nCheckboxListItem.displayName = 'CheckboxListItem';\n\nexport default CheckboxList;\nexport { CheckboxListItem };\n","import {\n InputHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n} from 'react';\nimport Text from '../Text/Text';\nimport { Check, Minus } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckBox size variants\n */\ntype CheckBoxSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckBox visual state\n */\ntype CheckBoxState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n checkbox: 'w-4 h-4', // 16px x 16px\n textSize: 'sm' as const,\n spacing: 'gap-1.5', // 6px\n borderWidth: 'border-2',\n iconSize: 14, // pixels for Phosphor icons\n labelHeight: 'h-[21px]',\n },\n medium: {\n checkbox: 'w-5 h-5', // 20px x 20px\n textSize: 'md' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-2',\n iconSize: 16, // pixels for Phosphor icons\n labelHeight: 'h-6',\n },\n large: {\n checkbox: 'w-6 h-6', // 24px x 24px\n textSize: 'lg' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-[3px]', // 3px border\n iconSize: 20, // pixels for Phosphor icons\n labelHeight: 'h-[27px]',\n },\n} as const;\n\n/**\n * Base checkbox styling classes using design system colors\n */\nconst BASE_CHECKBOX_CLASSES =\n 'rounded border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n unchecked: 'border-border-400 bg-background hover:border-border-500',\n checked:\n 'border-primary-950 bg-primary-950 text-text hover:border-primary-800 hover:bg-primary-800',\n },\n hovered: {\n unchecked: 'border-border-500 bg-background',\n checked: 'border-primary-800 bg-primary-800 text-text',\n },\n focused: {\n unchecked:\n 'border-indicator-info bg-background ring-2 ring-indicator-info/20',\n checked:\n 'border-indicator-info bg-primary-950 text-text ring-2 ring-indicator-info/20',\n },\n invalid: {\n unchecked: 'border-error-700 bg-background hover:border-error-600',\n checked: 'border-error-700 bg-primary-950 text-text',\n },\n disabled: {\n unchecked: 'border-border-400 bg-background cursor-not-allowed opacity-40',\n checked:\n 'border-primary-600 bg-primary-600 text-text cursor-not-allowed opacity-40',\n },\n} as const;\n\n/**\n * CheckBox component props interface\n */\nexport type CheckBoxProps = {\n /** Label text to display next to the checkbox */\n label?: ReactNode;\n /** Size variant of the checkbox */\n size?: CheckBoxSize;\n /** Visual state of the checkbox */\n state?: CheckBoxState;\n /** Indeterminate state for partial selections */\n indeterminate?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperText?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'>;\n\n/**\n * CheckBox component for Analytica Ensino platforms\n *\n * A checkbox component with essential states, sizes and themes.\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic checkbox\n * <CheckBox label=\"Option\" />\n *\n * // Small size\n * <CheckBox size=\"small\" label=\"Small option\" />\n *\n * // Invalid state\n * <CheckBox state=\"invalid\" label=\"Required field\" />\n *\n * // Disabled state\n * <CheckBox disabled label=\"Disabled option\" />\n * ```\n */\nconst CheckBox = forwardRef<HTMLInputElement, CheckBoxProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n indeterminate = false,\n errorMessage,\n helperText,\n className = '',\n labelClassName = '',\n checked: checkedProp,\n disabled,\n id,\n onChange,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-${generatedId}`;\n\n // Handle controlled vs uncontrolled behavior\n const [internalChecked, setInternalChecked] = useState(false);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setInternalChecked(event.target.checked);\n }\n onChange?.(event);\n };\n\n // Determine current state based on props\n const currentState = disabled ? 'disabled' : state;\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Determine checkbox visual variant\n const checkVariant = checked || indeterminate ? 'checked' : 'unchecked';\n\n // Get styling classes\n const stylingClasses = STATE_CLASSES[currentState][checkVariant];\n\n // Special border width handling for focused/hovered states and large size\n const borderWidthClass =\n state === 'focused' || (state === 'hovered' && size === 'large')\n ? 'border-[3px]'\n : sizeClasses.borderWidth;\n\n // Get final checkbox classes\n const checkboxClasses = cn(\n BASE_CHECKBOX_CLASSES,\n sizeClasses.checkbox,\n borderWidthClass,\n stylingClasses,\n className\n );\n\n // Render appropriate icon based on state\n const renderIcon = () => {\n if (indeterminate) {\n return (\n <Minus\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n if (checked) {\n return (\n <Check\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n return null;\n };\n\n return (\n <div className=\"flex flex-col\">\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.spacing,\n disabled ? 'opacity-40' : ''\n )}\n >\n {/* Hidden native input for accessibility and form submission */}\n <input\n ref={ref}\n type=\"checkbox\"\n id={inputId}\n checked={checked}\n disabled={disabled}\n onChange={handleChange}\n className=\"sr-only\"\n {...props}\n />\n\n {/* Custom styled checkbox */}\n <label htmlFor={inputId} className={checkboxClasses}>\n {/* Show appropriate icon based on state */}\n {renderIcon()}\n </label>\n\n {/* Label text */}\n {label && (\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.labelHeight\n )}\n >\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"normal\"\n className={cn(\n 'cursor-pointer select-none leading-[150%] flex items-center font-roboto',\n labelClassName\n )}\n >\n {label}\n </Text>\n </div>\n )}\n </div>\n\n {/* Error message */}\n {errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-error-600\"\n >\n {errorMessage}\n </Text>\n )}\n\n {/* Helper text */}\n {helperText && !errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-text-500\"\n >\n {helperText}\n </Text>\n )}\n </div>\n );\n }\n);\n\nCheckBox.displayName = 'CheckBox';\n\nexport default CheckBox;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { HTMLAttributes, ReactNode } from 'react';\nimport { Bell } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n error: 'bg-error-background text-error-700 focus-visible:outline-none',\n warning: 'bg-warning text-warning-800 focus-visible:outline-none',\n success: 'bg-success text-success-800 focus-visible:outline-none',\n info: 'bg-info text-info-800 focus-visible:outline-none',\n muted: 'bg-background-muted text-background-800 focus-visible:outline-none',\n },\n outlined: {\n error:\n 'bg-error text-error-700 border border-error-300 focus-visible:outline-none',\n warning:\n 'bg-warning text-warning-800 border border-warning-300 focus-visible:outline-none',\n success:\n 'bg-success text-success-800 border border-success-300 focus-visible:outline-none',\n info: 'bg-info text-info-800 border border-info-300 focus-visible:outline-none',\n muted:\n 'bg-background-muted text-background-800 border border-border-300 focus-visible:outline-none',\n },\n exams: {\n exam1: 'bg-exam-1 text-info-700 focus-visible:outline-none',\n exam2: 'bg-exam-2 text-typography-1 focus-visible:outline-none',\n exam3: 'bg-exam-3 text-typography-2 focus-visible:outline-none',\n exam4: 'bg-exam-4 text-success-700 focus-visible:outline-none',\n },\n examsOutlined: {\n exam1:\n 'bg-exam-1 text-info-700 border border-info-700 focus-visible:outline-none',\n exam2:\n 'bg-exam-2 text-typography-1 border border-typography-1 focus-visible:outline-none',\n exam3:\n 'bg-exam-3 text-typography-2 border border-typography-2 focus-visible:outline-none',\n exam4:\n 'bg-exam-4 text-success-700 border border-success-700 focus-visible:outline-none',\n },\n resultStatus: {\n negative: 'bg-error text-error-800 focus-visible:outline-none',\n positive: 'bg-success text-success-800 focus-visible:outline-none',\n },\n notification: 'text-primary',\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n small: 'text-2xs px-2 py-1',\n medium: 'text-xs px-2 py-1',\n large: 'text-sm px-2 py-1',\n} as const;\n\nconst SIZE_CLASSES_ICON = {\n small: 'size-3',\n medium: 'size-3.5',\n large: 'size-4',\n} as const;\n\n/**\n * Badge component props interface\n */\ntype BadgeProps = {\n /** Content to be displayed inside the badge */\n children?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Size of the badge */\n size?: 'small' | 'medium' | 'large';\n /** Visual variant of the badge */\n variant?:\n | 'solid'\n | 'outlined'\n | 'exams'\n | 'examsOutlined'\n | 'resultStatus'\n | 'notification';\n /** Action type of the badge */\n action?:\n | 'error'\n | 'warning'\n | 'success'\n | 'info'\n | 'muted'\n | 'exam1'\n | 'exam2'\n | 'exam3'\n | 'exam4'\n | 'positive'\n | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n notificationActive?: boolean;\n} & HTMLAttributes<HTMLDivElement>;\n\n/**\n * Badge 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 badge\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 div HTML attributes\n * @returns A styled badge element\n *\n * @example\n * ```tsx\n * <Badge variant=\"solid\" action=\"info\" size=\"medium\">\n * Information\n * </Badge>\n * ```\n */\nconst Badge = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'error',\n className = '',\n notificationActive = false,\n ...props\n}: BadgeProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const sizeClassesIcon = SIZE_CLASSES_ICON[size];\n const variantActionMap = VARIANT_ACTION_CLASSES[variant] || {};\n const variantClasses =\n typeof variantActionMap === 'string'\n ? variantActionMap\n : ((variantActionMap as Record<string, string>)[action] ??\n (variantActionMap as Record<string, string>).muted ??\n '');\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-xs font-normal gap-1 relative';\n\n const baseClassesIcon = 'flex items-center';\n if (variant === 'notification') {\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n <Bell size={24} className=\"text-current\" aria-hidden=\"true\" />\n\n {notificationActive && (\n <span\n data-testid=\"notification-dot\"\n className=\"absolute top-[5px] right-[10px] block h-2 w-2 rounded-full bg-indicator-error ring-2 ring-white\"\n />\n )}\n </div>\n );\n }\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n {iconLeft && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>{iconLeft}</span>\n )}\n {children}\n {iconRight && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>\n {iconRight}\n </span>\n )}\n </div>\n );\n};\n\nexport default Badge;\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_phosphor_react","import_phosphor_react","import_jsx_runtime","SIZE_CLASSES","import_jsx_runtime"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/MultipleChoice/MultipleChoice.tsx","../../src/components/CheckBox/CheckboxList.tsx","../../src/components/CheckBox/CheckBox.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Badge/Badge.tsx"],"sourcesContent":["import { HtmlHTMLAttributes, useEffect, useState } from 'react';\nimport CheckboxList, { CheckboxListItem } from '../CheckBox/CheckboxList';\nimport { cn } from '@/utils/utils';\nimport { CheckCircle, XCircle, Check } from 'phosphor-react';\nimport Badge from '../Badge/Badge';\n\ninterface Choice {\n value: string;\n label: string;\n status?: 'correct' | 'incorrect' | 'neutral';\n disabled?: boolean;\n}\n\ninterface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {\n choices: Choice[];\n disabled?: boolean;\n name?: string;\n selectedValues?: string[];\n onHandleSelectedValues?: (values: string[]) => void;\n mode?: 'interactive' | 'readonly';\n}\n\nconst MultipleChoiceList = ({\n disabled = false,\n className = '',\n choices,\n name,\n selectedValues,\n onHandleSelectedValues,\n mode = 'interactive',\n}: MultipleChoiceListProps) => {\n const [actualValue, setActualValue] = useState(selectedValues);\n\n useEffect(() => {\n setActualValue(selectedValues);\n }, [selectedValues]);\n const getStatusBadge = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getStatusStyles = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100`;\n }\n };\n\n const renderVisualCheckbox = (isSelected: boolean, isDisabled: boolean) => {\n const checkboxClasses = cn(\n 'w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center',\n isSelected\n ? 'border-primary-950 bg-primary-950 text-text'\n : 'border-border-400 bg-background',\n isDisabled && 'opacity-40 cursor-not-allowed'\n );\n\n return (\n <div className={checkboxClasses}>\n {isSelected && <Check size={16} weight=\"bold\" />}\n </div>\n );\n };\n\n if (mode === 'readonly') {\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {choices.map((choice, i) => {\n const isSelected = actualValue?.includes(choice.value) || false;\n const statusStyles = getStatusStyles(choice.status);\n const statusBadge = getStatusBadge(choice.status);\n\n return (\n <div\n key={`readonly-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n choice.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n {renderVisualCheckbox(isSelected, choice.disabled || disabled)}\n <span\n className={cn(\n 'flex-1',\n isSelected || (choice.status && choice.status != 'neutral')\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-default'\n )}\n >\n {choice.label}\n </span>\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n disabled ? 'opacity-50 cursor-not-allowed' : '',\n className\n )}\n >\n <CheckboxList\n name={name}\n values={actualValue}\n onValuesChange={(v) => {\n setActualValue(v);\n onHandleSelectedValues?.(v);\n }}\n disabled={disabled}\n >\n {choices.map((choice, i) => (\n <div\n key={`interactive-${choice.value}-${i}`}\n className=\"flex flex-row gap-2 items-center\"\n >\n <CheckboxListItem\n value={choice.value}\n id={`interactive-${choice.value}-${i}`}\n disabled={choice.disabled || disabled}\n />\n\n <label\n htmlFor={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex-1',\n actualValue?.includes(choice.value)\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n {choice.label}\n </label>\n </div>\n ))}\n </CheckboxList>\n </div>\n );\n};\n\nexport { MultipleChoiceList };\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useId,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport CheckBox from './CheckBox';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckboxList size variants\n */\ntype CheckboxListSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckboxList visual state\n */\ntype CheckboxListState =\n | 'default'\n | 'hovered'\n | 'focused'\n | 'invalid'\n | 'disabled';\n\n/**\n * CheckboxList store interface\n */\ninterface CheckboxListStore {\n values: string[];\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n onValuesChange?: (values: string[]) => void;\n disabled: boolean;\n name: string;\n}\n\ntype CheckboxListStoreApi = StoreApi<CheckboxListStore>;\n\n/**\n * Create a new CheckboxList store\n */\nconst createCheckboxListStore = (\n name: string,\n defaultValues: string[],\n disabled: boolean,\n onValuesChange?: (values: string[]) => void\n): CheckboxListStoreApi =>\n create<CheckboxListStore>((set, get) => ({\n values: defaultValues,\n setValues: (values) => {\n if (!get().disabled) {\n set({ values });\n get().onValuesChange?.(values);\n }\n },\n toggleValue: (value) => {\n if (!get().disabled) {\n const currentValues = get().values;\n const newValues = currentValues.includes(value)\n ? currentValues.filter((v) => v !== value)\n : [...currentValues, value];\n set({ values: newValues });\n get().onValuesChange?.(newValues);\n }\n },\n onValuesChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access CheckboxList store\n */\nexport const useCheckboxListStore = (externalStore?: CheckboxListStoreApi) => {\n if (!externalStore) {\n throw new Error('CheckboxListItem must be used within a CheckboxList');\n }\n return externalStore;\n};\n\n/**\n * Inject store into CheckboxListItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: CheckboxListStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n const typedChild = child as ReactElement<CheckboxListItemProps>;\n const shouldInject = typedChild.type === CheckboxListItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * CheckboxList component props interface\n */\nexport type CheckboxListProps = {\n /** Current selected values */\n values?: string[];\n /** Default selected values for uncontrolled usage */\n defaultValues?: string[];\n /** Callback when selection changes */\n onValuesChange?: (values: string[]) => void;\n /** Group name for all checkboxes */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValues'>;\n\n/**\n * CheckboxList component for flexible checkbox group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with CheckboxListItem.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]} onValuesChange={setValues}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option2\" id=\"c2\" />\n * <label htmlFor=\"c2\">Option 2</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxList = forwardRef<HTMLDivElement, CheckboxListProps>(\n (\n {\n values: propValues,\n defaultValues = [],\n onValuesChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `checkbox-list-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<CheckboxListStoreApi>(null);\n storeRef.current ??= createCheckboxListStore(\n name,\n defaultValues,\n disabled,\n onValuesChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValues } = useStore(store, (s) => s);\n\n // Call onValuesChange with initial values\n useEffect(() => {\n const currentValues = store.getState().values;\n if (currentValues.length > 0 && onValuesChange) {\n onValuesChange(currentValues);\n }\n }, []);\n\n // Handle controlled values changes\n useEffect(() => {\n if (propValues !== undefined) {\n setValues(propValues);\n }\n }, [propValues, setValues]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 w-full', className)}\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nCheckboxList.displayName = 'CheckboxList';\n\n/**\n * CheckboxListItem component props interface\n */\nexport type CheckboxListItemProps = {\n /** Value for this checkbox item */\n value: string;\n /** Store reference (automatically injected by CheckboxList) */\n store?: CheckboxListStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: CheckboxListSize;\n /** Visual state */\n state?: CheckboxListState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * CheckboxListItem component for use within CheckboxList\n *\n * A checkbox without label that works within CheckboxList context.\n * Provides just the checkbox input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxListItem = forwardRef<HTMLInputElement, CheckboxListItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useCheckboxListStore(externalStore);\n const {\n values: groupValues,\n toggleValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValues.includes(value);\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard CheckBox component for consistency and simplicity\n return (\n <CheckBox\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={() => {\n if (!isDisabled) {\n toggleValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nCheckboxListItem.displayName = 'CheckboxListItem';\n\nexport default CheckboxList;\nexport { CheckboxListItem };\n","import {\n InputHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n} from 'react';\nimport Text from '../Text/Text';\nimport { Check, Minus } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckBox size variants\n */\ntype CheckBoxSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckBox visual state\n */\ntype CheckBoxState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n checkbox: 'w-4 h-4', // 16px x 16px\n textSize: 'sm' as const,\n spacing: 'gap-1.5', // 6px\n borderWidth: 'border-2',\n iconSize: 14, // pixels for Phosphor icons\n labelHeight: 'h-[21px]',\n },\n medium: {\n checkbox: 'w-5 h-5', // 20px x 20px\n textSize: 'md' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-2',\n iconSize: 16, // pixels for Phosphor icons\n labelHeight: 'h-6',\n },\n large: {\n checkbox: 'w-6 h-6', // 24px x 24px\n textSize: 'lg' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-[3px]', // 3px border\n iconSize: 20, // pixels for Phosphor icons\n labelHeight: 'h-[27px]',\n },\n} as const;\n\n/**\n * Base checkbox styling classes using design system colors\n */\nconst BASE_CHECKBOX_CLASSES =\n 'rounded border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n unchecked: 'border-border-400 bg-background hover:border-border-500',\n checked:\n 'border-primary-950 bg-primary-950 text-text hover:border-primary-800 hover:bg-primary-800',\n },\n hovered: {\n unchecked: 'border-border-500 bg-background',\n checked: 'border-primary-800 bg-primary-800 text-text',\n },\n focused: {\n unchecked:\n 'border-indicator-info bg-background ring-2 ring-indicator-info/20',\n checked:\n 'border-indicator-info bg-primary-950 text-text ring-2 ring-indicator-info/20',\n },\n invalid: {\n unchecked: 'border-error-700 bg-background hover:border-error-600',\n checked: 'border-error-700 bg-primary-950 text-text',\n },\n disabled: {\n unchecked: 'border-border-400 bg-background cursor-not-allowed opacity-40',\n checked:\n 'border-primary-600 bg-primary-600 text-text cursor-not-allowed opacity-40',\n },\n} as const;\n\n/**\n * CheckBox component props interface\n */\nexport type CheckBoxProps = {\n /** Label text to display next to the checkbox */\n label?: ReactNode;\n /** Size variant of the checkbox */\n size?: CheckBoxSize;\n /** Visual state of the checkbox */\n state?: CheckBoxState;\n /** Indeterminate state for partial selections */\n indeterminate?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperText?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'>;\n\n/**\n * CheckBox component for Analytica Ensino platforms\n *\n * A checkbox component with essential states, sizes and themes.\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic checkbox\n * <CheckBox label=\"Option\" />\n *\n * // Small size\n * <CheckBox size=\"small\" label=\"Small option\" />\n *\n * // Invalid state\n * <CheckBox state=\"invalid\" label=\"Required field\" />\n *\n * // Disabled state\n * <CheckBox disabled label=\"Disabled option\" />\n * ```\n */\nconst CheckBox = forwardRef<HTMLInputElement, CheckBoxProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n indeterminate = false,\n errorMessage,\n helperText,\n className = '',\n labelClassName = '',\n checked: checkedProp,\n disabled,\n id,\n onChange,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-${generatedId}`;\n\n // Handle controlled vs uncontrolled behavior\n const [internalChecked, setInternalChecked] = useState(false);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setInternalChecked(event.target.checked);\n }\n onChange?.(event);\n };\n\n // Determine current state based on props\n const currentState = disabled ? 'disabled' : state;\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Determine checkbox visual variant\n const checkVariant = checked || indeterminate ? 'checked' : 'unchecked';\n\n // Get styling classes\n const stylingClasses = STATE_CLASSES[currentState][checkVariant];\n\n // Special border width handling for focused/hovered states and large size\n const borderWidthClass =\n state === 'focused' || (state === 'hovered' && size === 'large')\n ? 'border-[3px]'\n : sizeClasses.borderWidth;\n\n // Get final checkbox classes\n const checkboxClasses = cn(\n BASE_CHECKBOX_CLASSES,\n sizeClasses.checkbox,\n borderWidthClass,\n stylingClasses,\n className\n );\n\n // Render appropriate icon based on state\n const renderIcon = () => {\n if (indeterminate) {\n return (\n <Minus\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n if (checked) {\n return (\n <Check\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n return null;\n };\n\n return (\n <div className=\"flex flex-col\">\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.spacing,\n disabled ? 'opacity-40' : ''\n )}\n >\n {/* Hidden native input for accessibility and form submission */}\n <input\n ref={ref}\n type=\"checkbox\"\n id={inputId}\n checked={checked}\n disabled={disabled}\n onChange={handleChange}\n className=\"sr-only\"\n {...props}\n />\n\n {/* Custom styled checkbox */}\n <label htmlFor={inputId} className={checkboxClasses}>\n {/* Show appropriate icon based on state */}\n {renderIcon()}\n </label>\n\n {/* Label text */}\n {label && (\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.labelHeight\n )}\n >\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"normal\"\n className={cn(\n 'cursor-pointer select-none leading-[150%] flex items-center font-roboto',\n labelClassName\n )}\n >\n {label}\n </Text>\n </div>\n )}\n </div>\n\n {/* Error message */}\n {errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-error-600\"\n >\n {errorMessage}\n </Text>\n )}\n\n {/* Helper text */}\n {helperText && !errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-text-500\"\n >\n {helperText}\n </Text>\n )}\n </div>\n );\n }\n);\n\nCheckBox.displayName = 'CheckBox';\n\nexport default CheckBox;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { HTMLAttributes, ReactNode } from 'react';\nimport { Bell } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n error: 'bg-error-background text-error-700 focus-visible:outline-none',\n warning: 'bg-warning text-warning-800 focus-visible:outline-none',\n success: 'bg-success text-success-800 focus-visible:outline-none',\n info: 'bg-info text-info-800 focus-visible:outline-none',\n muted: 'bg-background-muted text-background-800 focus-visible:outline-none',\n },\n outlined: {\n error:\n 'bg-error text-error-700 border border-error-300 focus-visible:outline-none',\n warning:\n 'bg-warning text-warning-800 border border-warning-300 focus-visible:outline-none',\n success:\n 'bg-success text-success-800 border border-success-300 focus-visible:outline-none',\n info: 'bg-info text-info-800 border border-info-300 focus-visible:outline-none',\n muted:\n 'bg-background-muted text-background-800 border border-border-300 focus-visible:outline-none',\n },\n exams: {\n exam1: 'bg-exam-1 text-info-700 focus-visible:outline-none',\n exam2: 'bg-exam-2 text-typography-1 focus-visible:outline-none',\n exam3: 'bg-exam-3 text-typography-2 focus-visible:outline-none',\n exam4: 'bg-exam-4 text-success-700 focus-visible:outline-none',\n },\n examsOutlined: {\n exam1:\n 'bg-exam-1 text-info-700 border border-info-700 focus-visible:outline-none',\n exam2:\n 'bg-exam-2 text-typography-1 border border-typography-1 focus-visible:outline-none',\n exam3:\n 'bg-exam-3 text-typography-2 border border-typography-2 focus-visible:outline-none',\n exam4:\n 'bg-exam-4 text-success-700 border border-success-700 focus-visible:outline-none',\n },\n resultStatus: {\n negative: 'bg-error text-error-800 focus-visible:outline-none',\n positive: 'bg-success text-success-800 focus-visible:outline-none',\n },\n notification: 'text-primary',\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n small: 'text-2xs px-2 py-1',\n medium: 'text-xs px-2 py-1',\n large: 'text-sm px-2 py-1',\n} as const;\n\nconst SIZE_CLASSES_ICON = {\n small: 'size-3',\n medium: 'size-3.5',\n large: 'size-4',\n} as const;\n\n/**\n * Badge component props interface\n */\ntype BadgeProps = {\n /** Content to be displayed inside the badge */\n children?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Size of the badge */\n size?: 'small' | 'medium' | 'large';\n /** Visual variant of the badge */\n variant?:\n | 'solid'\n | 'outlined'\n | 'exams'\n | 'examsOutlined'\n | 'resultStatus'\n | 'notification';\n /** Action type of the badge */\n action?:\n | 'error'\n | 'warning'\n | 'success'\n | 'info'\n | 'muted'\n | 'exam1'\n | 'exam2'\n | 'exam3'\n | 'exam4'\n | 'positive'\n | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n notificationActive?: boolean;\n} & HTMLAttributes<HTMLDivElement>;\n\n/**\n * Badge 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 badge\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 div HTML attributes\n * @returns A styled badge element\n *\n * @example\n * ```tsx\n * <Badge variant=\"solid\" action=\"info\" size=\"medium\">\n * Information\n * </Badge>\n * ```\n */\nconst Badge = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'error',\n className = '',\n notificationActive = false,\n ...props\n}: BadgeProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const sizeClassesIcon = SIZE_CLASSES_ICON[size];\n const variantActionMap = VARIANT_ACTION_CLASSES[variant] || {};\n const variantClasses =\n typeof variantActionMap === 'string'\n ? variantActionMap\n : ((variantActionMap as Record<string, string>)[action] ??\n (variantActionMap as Record<string, string>).muted ??\n '');\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-xs font-normal gap-1 relative';\n\n const baseClassesIcon = 'flex items-center';\n if (variant === 'notification') {\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n <Bell size={24} className=\"text-current\" aria-hidden=\"true\" />\n\n {notificationActive && (\n <span\n data-testid=\"notification-dot\"\n className=\"absolute top-[5px] right-[10px] block h-2 w-2 rounded-full bg-indicator-error ring-2 ring-white\"\n />\n )}\n </div>\n );\n }\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n {iconLeft && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>{iconLeft}</span>\n )}\n {children}\n {iconRight && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>\n {iconRight}\n </span>\n )}\n </div>\n );\n};\n\nexport default Badge;\n"],"mappings":"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","names":["useEffect","useState","forwardRef","useId","jsx","jsx","forwardRef","useId","Check","jsx","jsxs","SIZE_CLASSES","jsx","jsxs","useState","useEffect","Check"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ButtonHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* NavButton component for Analytica Ensino platforms
|
|
6
|
+
*
|
|
7
|
+
* Um botão de navegação com ícone e texto para navegação principal.
|
|
8
|
+
* Ideal para menus de navegação, sidebar, tabs de navegação, etc.
|
|
9
|
+
* Suporta forwardRef para acesso programático ao elemento DOM.
|
|
10
|
+
*
|
|
11
|
+
* @param icon - O ícone a ser exibido no botão
|
|
12
|
+
* @param label - O texto/label a ser exibido
|
|
13
|
+
* @param selected - Estado de seleção do botão
|
|
14
|
+
* @param className - Classes CSS adicionais
|
|
15
|
+
* @param props - Todos os outros atributos HTML padrão de button
|
|
16
|
+
* @returns Um elemento button estilizado para navegação
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <NavButton
|
|
21
|
+
* icon={<HomeIcon />}
|
|
22
|
+
* label="Início"
|
|
23
|
+
* selected={false}
|
|
24
|
+
* onClick={() => navigate('/')}
|
|
25
|
+
* />
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* // Usando ref para foco programático
|
|
31
|
+
* const buttonRef = useRef<HTMLButtonElement>(null);
|
|
32
|
+
*
|
|
33
|
+
* const handleFocus = () => {
|
|
34
|
+
* buttonRef.current?.focus();
|
|
35
|
+
* };
|
|
36
|
+
*
|
|
37
|
+
* <NavButton
|
|
38
|
+
* ref={buttonRef}
|
|
39
|
+
* icon={<HomeIcon />}
|
|
40
|
+
* label="Dashboard"
|
|
41
|
+
* selected={isActive}
|
|
42
|
+
* onClick={() => setActiveTab('dashboard')}
|
|
43
|
+
* />
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
declare const NavButton: react.ForwardRefExoticComponent<{
|
|
47
|
+
/** Ícone a ser exibido no botão */
|
|
48
|
+
icon: ReactNode;
|
|
49
|
+
/** Texto/label a ser exibido ao lado do ícone */
|
|
50
|
+
label: string;
|
|
51
|
+
/** Estado de seleção do botão */
|
|
52
|
+
selected?: boolean;
|
|
53
|
+
/** Additional CSS classes to apply */
|
|
54
|
+
className?: string;
|
|
55
|
+
} & ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
|
|
56
|
+
|
|
57
|
+
export { NavButton as default };
|
|
@@ -1 +1,57 @@
|
|
|
1
|
-
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ButtonHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* NavButton component for Analytica Ensino platforms
|
|
6
|
+
*
|
|
7
|
+
* Um botão de navegação com ícone e texto para navegação principal.
|
|
8
|
+
* Ideal para menus de navegação, sidebar, tabs de navegação, etc.
|
|
9
|
+
* Suporta forwardRef para acesso programático ao elemento DOM.
|
|
10
|
+
*
|
|
11
|
+
* @param icon - O ícone a ser exibido no botão
|
|
12
|
+
* @param label - O texto/label a ser exibido
|
|
13
|
+
* @param selected - Estado de seleção do botão
|
|
14
|
+
* @param className - Classes CSS adicionais
|
|
15
|
+
* @param props - Todos os outros atributos HTML padrão de button
|
|
16
|
+
* @returns Um elemento button estilizado para navegação
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <NavButton
|
|
21
|
+
* icon={<HomeIcon />}
|
|
22
|
+
* label="Início"
|
|
23
|
+
* selected={false}
|
|
24
|
+
* onClick={() => navigate('/')}
|
|
25
|
+
* />
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* // Usando ref para foco programático
|
|
31
|
+
* const buttonRef = useRef<HTMLButtonElement>(null);
|
|
32
|
+
*
|
|
33
|
+
* const handleFocus = () => {
|
|
34
|
+
* buttonRef.current?.focus();
|
|
35
|
+
* };
|
|
36
|
+
*
|
|
37
|
+
* <NavButton
|
|
38
|
+
* ref={buttonRef}
|
|
39
|
+
* icon={<HomeIcon />}
|
|
40
|
+
* label="Dashboard"
|
|
41
|
+
* selected={isActive}
|
|
42
|
+
* onClick={() => setActiveTab('dashboard')}
|
|
43
|
+
* />
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
declare const NavButton: react.ForwardRefExoticComponent<{
|
|
47
|
+
/** Ícone a ser exibido no botão */
|
|
48
|
+
icon: ReactNode;
|
|
49
|
+
/** Texto/label a ser exibido ao lado do ícone */
|
|
50
|
+
label: string;
|
|
51
|
+
/** Estado de seleção do botão */
|
|
52
|
+
selected?: boolean;
|
|
53
|
+
/** Additional CSS classes to apply */
|
|
54
|
+
className?: string;
|
|
55
|
+
} & ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
|
|
56
|
+
|
|
57
|
+
export { NavButton as default };
|
package/dist/NavButton/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/NavButton/NavButton.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * NavButton component props interface\n */\ntype NavButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * NavButton component for Analytica Ensino platforms\n *\n * Um botão de navegação com ícone e texto para navegação principal.\n * Ideal para menus de navegação, sidebar, tabs de navegação, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado para navegação\n *\n * @example\n * ```tsx\n * <NavButton\n * icon={<HomeIcon />}\n * label=\"Início\"\n * selected={false}\n * onClick={() => navigate('/')}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <NavButton\n * ref={buttonRef}\n * icon={<HomeIcon />}\n * label=\"Dashboard\"\n * selected={isActive}\n * onClick={() => setActiveTab('dashboard')}\n * />\n * ```\n */\nconst NavButton = forwardRef<HTMLButtonElement, NavButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'flex',\n 'flex-col',\n 'items-center',\n 'justify-center',\n 'gap-0.5',\n 'px-12',\n 'py-1',\n 'rounded-sm',\n 'cursor-pointer',\n 'text-text-950',\n 'text-xs',\n 'font-medium',\n 'hover:text-text',\n 'hover:bg-primary-600',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-offset-0',\n 'focus-visible:ring-indicator-info',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n 'disabled:pointer-events-none',\n ];\n\n const stateClasses = selected ? ['bg-primary-50', 'text-primary-950'] : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(allClasses, className)}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-5 h-5\">{icon}</span>\n <span className=\"whitespace-nowrap\">{label}</span>\n </button>\n );\n }\n);\n\nNavButton.displayName = 'NavButton';\n\nexport default NavButton;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4D;;;ACA5D,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;ADyFM;AAnCN,IAAM,gBAAY;AAAA,EAChB,CACE,EAAE,MAAM,OAAO,WAAW,OAAO,YAAY,IAAI,UAAU,GAAG,MAAM,GACpE,QACG;AAEH,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,WAAW,CAAC,iBAAiB,kBAAkB,IAAI,CAAC;AAEzE,UAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY,EAAE,KAAK,GAAG;AAE7D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW,GAAG,YAAY,SAAS;AAAA,QACnC;AAAA,QACA,gBAAc;AAAA,QACb,GAAG;AAAA,QAEJ;AAAA,sDAAC,UAAK,WAAU,4CAA4C,gBAAK;AAAA,UACjE,4CAAC,UAAK,WAAU,qBAAqB,iBAAM;AAAA;AAAA;AAAA,IAC7C;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAExB,IAAO,oBAAQ;","names":[]}
|
package/dist/NavButton/index.mjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/NavButton/NavButton.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * NavButton component props interface\n */\ntype NavButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * NavButton component for Analytica Ensino platforms\n *\n * Um botão de navegação com ícone e texto para navegação principal.\n * Ideal para menus de navegação, sidebar, tabs de navegação, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado para navegação\n *\n * @example\n * ```tsx\n * <NavButton\n * icon={<HomeIcon />}\n * label=\"Início\"\n * selected={false}\n * onClick={() => navigate('/')}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <NavButton\n * ref={buttonRef}\n * icon={<HomeIcon />}\n * label=\"Dashboard\"\n * selected={isActive}\n * onClick={() => setActiveTab('dashboard')}\n * />\n * ```\n */\nconst NavButton = forwardRef<HTMLButtonElement, NavButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'flex',\n 'flex-col',\n 'items-center',\n 'justify-center',\n 'gap-0.5',\n 'px-12',\n 'py-1',\n 'rounded-sm',\n 'cursor-pointer',\n 'text-text-950',\n 'text-xs',\n 'font-medium',\n 'hover:text-text',\n 'hover:bg-primary-600',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-offset-0',\n 'focus-visible:ring-indicator-info',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n 'disabled:pointer-events-none',\n ];\n\n const stateClasses = selected ? ['bg-primary-50', 'text-primary-950'] : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(allClasses, className)}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-5 h-5\">{icon}</span>\n <span className=\"whitespace-nowrap\">{label}</span>\n </button>\n );\n }\n);\n\nNavButton.displayName = 'NavButton';\n\nexport default NavButton;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";AAAA,SAA0C,kBAAkB;;;ACA5D,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ADyFM,SAQE,KARF;AAnCN,IAAM,YAAY;AAAA,EAChB,CACE,EAAE,MAAM,OAAO,WAAW,OAAO,YAAY,IAAI,UAAU,GAAG,MAAM,GACpE,QACG;AAEH,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,WAAW,CAAC,iBAAiB,kBAAkB,IAAI,CAAC;AAEzE,UAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY,EAAE,KAAK,GAAG;AAE7D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW,GAAG,YAAY,SAAS;AAAA,QACnC;AAAA,QACA,gBAAc;AAAA,QACb,GAAG;AAAA,QAEJ;AAAA,8BAAC,UAAK,WAAU,4CAA4C,gBAAK;AAAA,UACjE,oBAAC,UAAK,WAAU,qBAAqB,iBAAM;AAAA;AAAA;AAAA,IAC7C;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAExB,IAAO,oBAAQ;","names":[]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Props interface for the NotFound component
|
|
5
|
+
*
|
|
6
|
+
* @interface NotFoundProps
|
|
7
|
+
* @property {string} [title] - Custom title text (default: "Página não encontrada")
|
|
8
|
+
* @property {string} [description] - Custom description text
|
|
9
|
+
* @property {string} [buttonText] - Custom button text (default: "Voltar")
|
|
10
|
+
* @property {() => void} [onButtonClick] - Callback function for button click
|
|
11
|
+
* @property {string} [className] - Additional CSS classes for the container
|
|
12
|
+
* @property {'404' | '500' | 'custom'} [errorType] - Type of error to display (default: '404')
|
|
13
|
+
* @property {string} [customErrorCode] - Custom error code when errorType is 'custom'
|
|
14
|
+
*/
|
|
15
|
+
interface NotFoundProps {
|
|
16
|
+
title?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
buttonText?: string;
|
|
19
|
+
onButtonClick?: () => void;
|
|
20
|
+
className?: string;
|
|
21
|
+
errorType?: '404' | '500' | 'custom';
|
|
22
|
+
customErrorCode?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* NotFound component for displaying error pages
|
|
26
|
+
*
|
|
27
|
+
* A reusable component for displaying 404, 500, or custom error pages
|
|
28
|
+
* with configurable content and navigation button.
|
|
29
|
+
*
|
|
30
|
+
* @param {NotFoundProps} props - The component props
|
|
31
|
+
* @returns {JSX.Element} The NotFound component
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* // Basic 404 page
|
|
36
|
+
* <NotFound onButtonClick={() => navigate('/dashboard')} />
|
|
37
|
+
*
|
|
38
|
+
* // Custom error page
|
|
39
|
+
* <NotFound
|
|
40
|
+
* errorType="500"
|
|
41
|
+
* title="Erro interno do servidor"
|
|
42
|
+
* description="Algo deu errado. Tente novamente mais tarde."
|
|
43
|
+
* buttonText="Tentar novamente"
|
|
44
|
+
* onButtonClick={() => window.location.reload()}
|
|
45
|
+
* />
|
|
46
|
+
*
|
|
47
|
+
* // Custom error code
|
|
48
|
+
* <NotFound
|
|
49
|
+
* errorType="custom"
|
|
50
|
+
* customErrorCode="403"
|
|
51
|
+
* title="Acesso negado"
|
|
52
|
+
* description="Você não tem permissão para acessar esta página."
|
|
53
|
+
* />
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
declare const NotFound: ({ title, description, buttonText, onButtonClick, className, errorType, customErrorCode, }: NotFoundProps) => react_jsx_runtime.JSX.Element;
|
|
57
|
+
|
|
58
|
+
export { type NotFoundProps, NotFound as default };
|
package/dist/NotFound/index.d.ts
CHANGED
|
@@ -1 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Props interface for the NotFound component
|
|
5
|
+
*
|
|
6
|
+
* @interface NotFoundProps
|
|
7
|
+
* @property {string} [title] - Custom title text (default: "Página não encontrada")
|
|
8
|
+
* @property {string} [description] - Custom description text
|
|
9
|
+
* @property {string} [buttonText] - Custom button text (default: "Voltar")
|
|
10
|
+
* @property {() => void} [onButtonClick] - Callback function for button click
|
|
11
|
+
* @property {string} [className] - Additional CSS classes for the container
|
|
12
|
+
* @property {'404' | '500' | 'custom'} [errorType] - Type of error to display (default: '404')
|
|
13
|
+
* @property {string} [customErrorCode] - Custom error code when errorType is 'custom'
|
|
14
|
+
*/
|
|
15
|
+
interface NotFoundProps {
|
|
16
|
+
title?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
buttonText?: string;
|
|
19
|
+
onButtonClick?: () => void;
|
|
20
|
+
className?: string;
|
|
21
|
+
errorType?: '404' | '500' | 'custom';
|
|
22
|
+
customErrorCode?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* NotFound component for displaying error pages
|
|
26
|
+
*
|
|
27
|
+
* A reusable component for displaying 404, 500, or custom error pages
|
|
28
|
+
* with configurable content and navigation button.
|
|
29
|
+
*
|
|
30
|
+
* @param {NotFoundProps} props - The component props
|
|
31
|
+
* @returns {JSX.Element} The NotFound component
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* // Basic 404 page
|
|
36
|
+
* <NotFound onButtonClick={() => navigate('/dashboard')} />
|
|
37
|
+
*
|
|
38
|
+
* // Custom error page
|
|
39
|
+
* <NotFound
|
|
40
|
+
* errorType="500"
|
|
41
|
+
* title="Erro interno do servidor"
|
|
42
|
+
* description="Algo deu errado. Tente novamente mais tarde."
|
|
43
|
+
* buttonText="Tentar novamente"
|
|
44
|
+
* onButtonClick={() => window.location.reload()}
|
|
45
|
+
* />
|
|
46
|
+
*
|
|
47
|
+
* // Custom error code
|
|
48
|
+
* <NotFound
|
|
49
|
+
* errorType="custom"
|
|
50
|
+
* customErrorCode="403"
|
|
51
|
+
* title="Acesso negado"
|
|
52
|
+
* description="Você não tem permissão para acessar esta página."
|
|
53
|
+
* />
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
declare const NotFound: ({ title, description, buttonText, onButtonClick, className, errorType, customErrorCode, }: NotFoundProps) => react_jsx_runtime.JSX.Element;
|
|
57
|
+
|
|
58
|
+
export { type NotFoundProps, NotFound as default };
|
package/dist/NotFound/index.js
CHANGED