analytica-frontend-lib 1.1.68 → 1.1.70
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.js +3 -3
- package/dist/Accordation/index.js.map +1 -1
- package/dist/Accordation/index.mjs +3 -3
- package/dist/Accordation/index.mjs.map +1 -1
- package/dist/Alert/index.js.map +1 -1
- package/dist/Alert/index.mjs.map +1 -1
- package/dist/AlertDialog/index.js.map +1 -1
- package/dist/AlertDialog/index.mjs.map +1 -1
- package/dist/Alternative/index.js.map +1 -1
- package/dist/Alternative/index.mjs.map +1 -1
- package/dist/Badge/index.js.map +1 -1
- package/dist/Badge/index.mjs.map +1 -1
- package/dist/Button/index.js.map +1 -1
- package/dist/Button/index.mjs.map +1 -1
- package/dist/Calendar/index.js +1 -1
- package/dist/Calendar/index.js.map +1 -1
- package/dist/Calendar/index.mjs +1 -1
- package/dist/Calendar/index.mjs.map +1 -1
- package/dist/Card/index.js +3 -3
- package/dist/Card/index.js.map +1 -1
- package/dist/Card/index.mjs +3 -3
- package/dist/Card/index.mjs.map +1 -1
- package/dist/CheckBox/index.js.map +1 -1
- package/dist/CheckBox/index.mjs.map +1 -1
- package/dist/Chips/index.js.map +1 -1
- package/dist/Chips/index.mjs.map +1 -1
- package/dist/Divider/index.js.map +1 -1
- package/dist/Divider/index.mjs.map +1 -1
- package/dist/DropdownMenu/index.js +110 -75
- package/dist/DropdownMenu/index.js.map +1 -1
- package/dist/DropdownMenu/index.mjs +114 -79
- package/dist/DropdownMenu/index.mjs.map +1 -1
- package/dist/IconButton/index.js.map +1 -1
- package/dist/IconButton/index.mjs.map +1 -1
- package/dist/IconRoundedButton/index.js.map +1 -1
- package/dist/IconRoundedButton/index.mjs.map +1 -1
- package/dist/Menu/index.js.map +1 -1
- package/dist/Menu/index.mjs.map +1 -1
- package/dist/Modal/index.js.map +1 -1
- package/dist/Modal/index.mjs.map +1 -1
- package/dist/MultipleChoice/index.js.map +1 -1
- package/dist/MultipleChoice/index.mjs.map +1 -1
- package/dist/NavButton/index.js.map +1 -1
- package/dist/NavButton/index.mjs.map +1 -1
- package/dist/NotFound/index.js.map +1 -1
- package/dist/NotFound/index.mjs.map +1 -1
- package/dist/NotificationCard/index.js +112 -77
- package/dist/NotificationCard/index.js.map +1 -1
- package/dist/NotificationCard/index.mjs +123 -88
- package/dist/NotificationCard/index.mjs.map +1 -1
- package/dist/ProgressBar/index.js.map +1 -1
- package/dist/ProgressBar/index.mjs.map +1 -1
- package/dist/ProgressCircle/index.js.map +1 -1
- package/dist/ProgressCircle/index.mjs.map +1 -1
- package/dist/Quiz/index.js +4 -4
- package/dist/Quiz/index.js.map +1 -1
- package/dist/Quiz/index.mjs +4 -4
- package/dist/Quiz/index.mjs.map +1 -1
- package/dist/Radio/index.js.map +1 -1
- package/dist/Radio/index.mjs.map +1 -1
- package/dist/Search/index.js +110 -75
- package/dist/Search/index.js.map +1 -1
- package/dist/Search/index.mjs +119 -84
- package/dist/Search/index.mjs.map +1 -1
- package/dist/Select/index.js.map +1 -1
- package/dist/Select/index.mjs.map +1 -1
- package/dist/SelectionButton/index.js.map +1 -1
- package/dist/SelectionButton/index.mjs.map +1 -1
- package/dist/Skeleton/index.js.map +1 -1
- package/dist/Skeleton/index.mjs.map +1 -1
- package/dist/Stepper/index.js.map +1 -1
- package/dist/Stepper/index.mjs.map +1 -1
- package/dist/Table/index.js.map +1 -1
- package/dist/Table/index.mjs.map +1 -1
- package/dist/Text/index.js.map +1 -1
- package/dist/Text/index.mjs.map +1 -1
- package/dist/TextArea/index.js.map +1 -1
- package/dist/TextArea/index.mjs.map +1 -1
- package/dist/ThemeToggle/index.d.mts +3 -1
- package/dist/ThemeToggle/index.d.ts +3 -1
- package/dist/ThemeToggle/index.js +102 -67
- package/dist/ThemeToggle/index.js.map +1 -1
- package/dist/ThemeToggle/index.mjs +105 -70
- package/dist/ThemeToggle/index.mjs.map +1 -1
- package/dist/Toast/Toaster/index.js.map +1 -1
- package/dist/Toast/Toaster/index.mjs.map +1 -1
- package/dist/Toast/index.js.map +1 -1
- package/dist/Toast/index.mjs.map +1 -1
- package/dist/VideoPlayer/index.js.map +1 -1
- package/dist/VideoPlayer/index.mjs.map +1 -1
- package/dist/Whiteboard/index.js +1 -1
- package/dist/Whiteboard/index.js.map +1 -1
- package/dist/Whiteboard/index.mjs +1 -1
- package/dist/Whiteboard/index.mjs.map +1 -1
- package/dist/hooks/useTheme/index.d.mts +6 -2
- package/dist/hooks/useTheme/index.d.ts +6 -2
- package/dist/hooks/useTheme/index.js +102 -67
- package/dist/hooks/useTheme/index.js.map +1 -1
- package/dist/hooks/useTheme/index.mjs +103 -68
- package/dist/hooks/useTheme/index.mjs.map +1 -1
- package/dist/index.css +3 -4
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +138 -101
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +257 -221
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +3 -4
- package/dist/styles.css.map +1 -1
- package/dist/themeStore-P2X64zC-.d.mts +79 -0
- package/dist/themeStore-P2X64zC-.d.ts +79 -0
- package/dist/utils/index.d.mts +10 -1
- package/dist/utils/index.d.ts +10 -1
- package/dist/utils/index.js +24 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +22 -1
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/CheckBox/CheckBox.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx"],"sourcesContent":["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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAOO;;;ACPP,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;ACsHI;AA/CJ,IAAM,OAAO,CAA8B;AAAA,EACzC;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,MAAoB;AAClB,MAAI,cAAc;AAClB,MAAI,gBAAgB;AAGpB,QAAM,eAAe;AAAA,IACnB,OAAO;AAAA,IACP,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAEA,gBAAc,aAAa,IAAI,KAAK,aAAa;AAGjD,QAAM,iBAAiB;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,EACT;AAEA,kBAAgB,eAAe,MAAM,KAAK,eAAe;AAEzD,QAAM,cAAc;AACpB,QAAM,YAAY,MAAO;AAEzB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,aAAa,eAAe,OAAO,SAAS;AAAA,MACtE,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,IAAO,eAAQ;;;AF3Hf,4BAA6B;AA8LnB,IAAAA,sBAAA;AA9KV,IAAM,eAAe;AAAA,EACnB,OAAO;AAAA,IACL,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IACT,aAAa;AAAA,IACb,UAAU;AAAA;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IACT,aAAa;AAAA,IACb,UAAU;AAAA;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IACT,aAAa;AAAA;AAAA,IACb,UAAU;AAAA;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAKA,IAAM,wBACJ;AAKF,IAAM,gBAAgB;AAAA,EACpB,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SACE;AAAA,EACJ;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,IACP,WACE;AAAA,IACF,SACE;AAAA,EACJ;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,UAAU;AAAA,IACR,WAAW;AAAA,IACX,SACE;AAAA,EACJ;AACF;AA8CA,IAAM,eAAW;AAAA,EACf,CACE;AAAA,IACE;AAAA,IACA,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,kBAAc,oBAAM;AAC1B,UAAM,UAAU,MAAM,YAAY,WAAW;AAG7C,UAAM,CAAC,iBAAiB,kBAAkB,QAAI,uBAAS,KAAK;AAC5D,UAAM,eAAe,gBAAgB;AACrC,UAAM,UAAU,eAAe,cAAc;AAG7C,UAAM,eAAe,CAAC,UAAyC;AAC7D,UAAI,CAAC,cAAc;AACjB,2BAAmB,MAAM,OAAO,OAAO;AAAA,MACzC;AACA,iBAAW,KAAK;AAAA,IAClB;AAGA,UAAM,eAAe,WAAW,aAAa;AAG7C,UAAM,cAAc,aAAa,IAAI;AAGrC,UAAM,eAAe,WAAW,gBAAgB,YAAY;AAG5D,UAAM,iBAAiB,cAAc,YAAY,EAAE,YAAY;AAG/D,UAAM,mBACJ,UAAU,aAAc,UAAU,aAAa,SAAS,UACpD,iBACA,YAAY;AAGlB,UAAM,kBAAkB;AAAA,MACtB;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,aAAa,MAAM;AACvB,UAAI,eAAe;AACjB,eACE;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,YAAY;AAAA,YAClB,QAAO;AAAA,YACP,OAAM;AAAA;AAAA,QACR;AAAA,MAEJ;AAEA,UAAI,SAAS;AACX,eACE;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,YAAY;AAAA,YAClB,QAAO;AAAA,YACP,OAAM;AAAA;AAAA,QACR;AAAA,MAEJ;AAEA,aAAO;AAAA,IACT;AAEA,WACE,8CAAC,SAAI,WAAU,iBACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,YAAY;AAAA,YACZ,WAAW,eAAe;AAAA,UAC5B;AAAA,UAGA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA,MAAK;AAAA,gBACL,IAAI;AAAA,gBACJ;AAAA,gBACA;AAAA,gBACA,UAAU;AAAA,gBACV,WAAU;AAAA,gBACT,GAAG;AAAA;AAAA,YACN;AAAA,YAGA,6CAAC,WAAM,SAAS,SAAS,WAAW,iBAEjC,qBAAW,GACd;AAAA,YAGC,SACC;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA,YAAY;AAAA,gBACd;AAAA,gBAEA;AAAA,kBAAC;AAAA;AAAA,oBACC,IAAG;AAAA,oBACH,SAAS;AAAA,oBACT,MAAM,YAAY;AAAA,oBAClB,QAAO;AAAA,oBACP,WAAW;AAAA,sBACT;AAAA,sBACA;AAAA,oBACF;AAAA,oBAEC;AAAA;AAAA,gBACH;AAAA;AAAA,YACF;AAAA;AAAA;AAAA,MAEJ;AAAA,MAGC,gBACC;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAU;AAAA,UACV,OAAM;AAAA,UAEL;AAAA;AAAA,MACH;AAAA,MAID,cAAc,CAAC,gBACd;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAU;AAAA,UACV,OAAM;AAAA,UAEL;AAAA;AAAA,MACH;AAAA,OAEJ;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;AAEvB,IAAO,mBAAQ;","names":["import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/CheckBox/CheckBox.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx"],"sourcesContent":["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\n/**\n * Retorna a cor hexadecimal com opacidade 0.7 (b3) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.7 (b3) para cores de 6 dígitos\n resultColor = `#${color}b3`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAOO;;;ACPP,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;ACsHI;AA/CJ,IAAM,OAAO,CAA8B;AAAA,EACzC;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,MAAoB;AAClB,MAAI,cAAc;AAClB,MAAI,gBAAgB;AAGpB,QAAM,eAAe;AAAA,IACnB,OAAO;AAAA,IACP,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAEA,gBAAc,aAAa,IAAI,KAAK,aAAa;AAGjD,QAAM,iBAAiB;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,EACT;AAEA,kBAAgB,eAAe,MAAM,KAAK,eAAe;AAEzD,QAAM,cAAc;AACpB,QAAM,YAAY,MAAO;AAEzB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,aAAa,eAAe,OAAO,SAAS;AAAA,MACtE,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,IAAO,eAAQ;;;AF3Hf,4BAA6B;AA8LnB,IAAAA,sBAAA;AA9KV,IAAM,eAAe;AAAA,EACnB,OAAO;AAAA,IACL,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IACT,aAAa;AAAA,IACb,UAAU;AAAA;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IACT,aAAa;AAAA,IACb,UAAU;AAAA;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IACT,aAAa;AAAA;AAAA,IACb,UAAU;AAAA;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAKA,IAAM,wBACJ;AAKF,IAAM,gBAAgB;AAAA,EACpB,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SACE;AAAA,EACJ;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,IACP,WACE;AAAA,IACF,SACE;AAAA,EACJ;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,UAAU;AAAA,IACR,WAAW;AAAA,IACX,SACE;AAAA,EACJ;AACF;AA8CA,IAAM,eAAW;AAAA,EACf,CACE;AAAA,IACE;AAAA,IACA,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,kBAAc,oBAAM;AAC1B,UAAM,UAAU,MAAM,YAAY,WAAW;AAG7C,UAAM,CAAC,iBAAiB,kBAAkB,QAAI,uBAAS,KAAK;AAC5D,UAAM,eAAe,gBAAgB;AACrC,UAAM,UAAU,eAAe,cAAc;AAG7C,UAAM,eAAe,CAAC,UAAyC;AAC7D,UAAI,CAAC,cAAc;AACjB,2BAAmB,MAAM,OAAO,OAAO;AAAA,MACzC;AACA,iBAAW,KAAK;AAAA,IAClB;AAGA,UAAM,eAAe,WAAW,aAAa;AAG7C,UAAM,cAAc,aAAa,IAAI;AAGrC,UAAM,eAAe,WAAW,gBAAgB,YAAY;AAG5D,UAAM,iBAAiB,cAAc,YAAY,EAAE,YAAY;AAG/D,UAAM,mBACJ,UAAU,aAAc,UAAU,aAAa,SAAS,UACpD,iBACA,YAAY;AAGlB,UAAM,kBAAkB;AAAA,MACtB;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,aAAa,MAAM;AACvB,UAAI,eAAe;AACjB,eACE;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,YAAY;AAAA,YAClB,QAAO;AAAA,YACP,OAAM;AAAA;AAAA,QACR;AAAA,MAEJ;AAEA,UAAI,SAAS;AACX,eACE;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,YAAY;AAAA,YAClB,QAAO;AAAA,YACP,OAAM;AAAA;AAAA,QACR;AAAA,MAEJ;AAEA,aAAO;AAAA,IACT;AAEA,WACE,8CAAC,SAAI,WAAU,iBACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,YAAY;AAAA,YACZ,WAAW,eAAe;AAAA,UAC5B;AAAA,UAGA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA,MAAK;AAAA,gBACL,IAAI;AAAA,gBACJ;AAAA,gBACA;AAAA,gBACA,UAAU;AAAA,gBACV,WAAU;AAAA,gBACT,GAAG;AAAA;AAAA,YACN;AAAA,YAGA,6CAAC,WAAM,SAAS,SAAS,WAAW,iBAEjC,qBAAW,GACd;AAAA,YAGC,SACC;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA,YAAY;AAAA,gBACd;AAAA,gBAEA;AAAA,kBAAC;AAAA;AAAA,oBACC,IAAG;AAAA,oBACH,SAAS;AAAA,oBACT,MAAM,YAAY;AAAA,oBAClB,QAAO;AAAA,oBACP,WAAW;AAAA,sBACT;AAAA,sBACA;AAAA,oBACF;AAAA,oBAEC;AAAA;AAAA,gBACH;AAAA;AAAA,YACF;AAAA;AAAA;AAAA,MAEJ;AAAA,MAGC,gBACC;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAU;AAAA,UACV,OAAM;AAAA,UAEL;AAAA;AAAA,MACH;AAAA,MAID,cAAc,CAAC,gBACd;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAU;AAAA,UACV,OAAM;AAAA,UAEL;AAAA;AAAA,MACH;AAAA,OAEJ;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;AAEvB,IAAO,mBAAQ;","names":["import_jsx_runtime"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/CheckBox/CheckBox.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx"],"sourcesContent":["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"],"mappings":"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","names":["jsx"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/CheckBox/CheckBox.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx"],"sourcesContent":["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\n/**\n * Retorna a cor hexadecimal com opacidade 0.7 (b3) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.7 (b3) para cores de 6 dígitos\n resultColor = `#${color}b3`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\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"],"mappings":"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","names":["jsx"]}
|
package/dist/Chips/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Chips/Chips.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { Check } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for chip state classes\n */\nconst STATE_CLASSES = {\n default:\n 'bg-background text-text-950 border border-border-100 hover:bg-secondary-50 hover:border-border-300',\n selected:\n 'bg-info-background text-primary-950 border-2 border-primary-950 hover:bg-secondary-50 focus-visible:border-0',\n} as const;\n\n/**\n * Chips component props interface\n */\ntype ChipsProps = {\n /** Content to be displayed inside the chip */\n children: ReactNode;\n /** Se o chip está selecionado (mostra check automaticamente) */\n selected?: boolean;\n\n /** Additional CSS classes to apply */\n className?: string;\n} & Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'>;\n\n/**\n * Chips component for Analytica Ensino platforms\n *\n * Um componente de chip seguindo exatamente o design do Figma.\n * Suporte a dois estados principais: default (sem ícone) e selected (com ícone de check).\n * Quando selecionado, automaticamente mostra o ícone de check.\n *\n * @param children - O conteúdo a ser exibido dentro do chip\n * @param selected - Se o chip está selecionado (mostra check automaticamente)\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos padrão de button HTML\n * @returns Um elemento de chip estilizado\n *\n * @example\n * ```tsx\n * <Chips onClick={() => console.log('clicked')}>\n * Label\n * </Chips>\n *\n * <Chips selected onClick={() => console.log('selected')}>\n * Selected Label\n * </Chips>\n * ```\n */\nconst Chips = ({\n children,\n selected = false,\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ChipsProps) => {\n // Get classes from lookup tables\n const stateClasses = selected\n ? STATE_CLASSES.selected\n : STATE_CLASSES.default;\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-normal text-sm px-4 py-2 gap-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-primary-600 disabled:opacity-40 disabled:cursor-not-allowed';\n\n return (\n <button\n className={cn(baseClasses, stateClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {selected && (\n <span className={`flex items-center`}>\n <Check weight=\"bold\" size={16} />\n </span>\n )}\n\n <span className=\"flex-1\">{children}</span>\n </button>\n );\n};\n\nexport default Chips;\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;AACA,4BAAsB;;;ACDtB,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;AD+DI;AA7DJ,IAAM,gBAAgB;AAAA,EACpB,SACE;AAAA,EACF,UACE;AACJ;AAuCA,IAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,EACP,GAAG;AACL,MAAkB;AAEhB,QAAM,eAAe,WACjB,cAAc,WACd,cAAc;AAElB,QAAM,cACJ;AAEF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,cAAc,SAAS;AAAA,MAClD;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA,oBACC,4CAAC,UAAK,WAAW,qBACf,sDAAC,+BAAM,QAAO,QAAO,MAAM,IAAI,GACjC;AAAA,QAGF,4CAAC,UAAK,WAAU,UAAU,UAAS;AAAA;AAAA;AAAA,EACrC;AAEJ;AAEA,IAAO,gBAAQ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/Chips/Chips.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { Check } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for chip state classes\n */\nconst STATE_CLASSES = {\n default:\n 'bg-background text-text-950 border border-border-100 hover:bg-secondary-50 hover:border-border-300',\n selected:\n 'bg-info-background text-primary-950 border-2 border-primary-950 hover:bg-secondary-50 focus-visible:border-0',\n} as const;\n\n/**\n * Chips component props interface\n */\ntype ChipsProps = {\n /** Content to be displayed inside the chip */\n children: ReactNode;\n /** Se o chip está selecionado (mostra check automaticamente) */\n selected?: boolean;\n\n /** Additional CSS classes to apply */\n className?: string;\n} & Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'>;\n\n/**\n * Chips component for Analytica Ensino platforms\n *\n * Um componente de chip seguindo exatamente o design do Figma.\n * Suporte a dois estados principais: default (sem ícone) e selected (com ícone de check).\n * Quando selecionado, automaticamente mostra o ícone de check.\n *\n * @param children - O conteúdo a ser exibido dentro do chip\n * @param selected - Se o chip está selecionado (mostra check automaticamente)\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos padrão de button HTML\n * @returns Um elemento de chip estilizado\n *\n * @example\n * ```tsx\n * <Chips onClick={() => console.log('clicked')}>\n * Label\n * </Chips>\n *\n * <Chips selected onClick={() => console.log('selected')}>\n * Selected Label\n * </Chips>\n * ```\n */\nconst Chips = ({\n children,\n selected = false,\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ChipsProps) => {\n // Get classes from lookup tables\n const stateClasses = selected\n ? STATE_CLASSES.selected\n : STATE_CLASSES.default;\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-normal text-sm px-4 py-2 gap-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-primary-600 disabled:opacity-40 disabled:cursor-not-allowed';\n\n return (\n <button\n className={cn(baseClasses, stateClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {selected && (\n <span className={`flex items-center`}>\n <Check weight=\"bold\" size={16} />\n </span>\n )}\n\n <span className=\"flex-1\">{children}</span>\n </button>\n );\n};\n\nexport default Chips;\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\n/**\n * Retorna a cor hexadecimal com opacidade 0.7 (b3) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.7 (b3) para cores de 6 dígitos\n resultColor = `#${color}b3`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,4BAAsB;;;ACDtB,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;AD+DI;AA7DJ,IAAM,gBAAgB;AAAA,EACpB,SACE;AAAA,EACF,UACE;AACJ;AAuCA,IAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,EACP,GAAG;AACL,MAAkB;AAEhB,QAAM,eAAe,WACjB,cAAc,WACd,cAAc;AAElB,QAAM,cACJ;AAEF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,cAAc,SAAS;AAAA,MAClD;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA,oBACC,4CAAC,UAAK,WAAW,qBACf,sDAAC,+BAAM,QAAO,QAAO,MAAM,IAAI,GACjC;AAAA,QAGF,4CAAC,UAAK,WAAU,UAAU,UAAS;AAAA;AAAA;AAAA,EACrC;AAEJ;AAEA,IAAO,gBAAQ;","names":[]}
|
package/dist/Chips/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Chips/Chips.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { Check } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for chip state classes\n */\nconst STATE_CLASSES = {\n default:\n 'bg-background text-text-950 border border-border-100 hover:bg-secondary-50 hover:border-border-300',\n selected:\n 'bg-info-background text-primary-950 border-2 border-primary-950 hover:bg-secondary-50 focus-visible:border-0',\n} as const;\n\n/**\n * Chips component props interface\n */\ntype ChipsProps = {\n /** Content to be displayed inside the chip */\n children: ReactNode;\n /** Se o chip está selecionado (mostra check automaticamente) */\n selected?: boolean;\n\n /** Additional CSS classes to apply */\n className?: string;\n} & Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'>;\n\n/**\n * Chips component for Analytica Ensino platforms\n *\n * Um componente de chip seguindo exatamente o design do Figma.\n * Suporte a dois estados principais: default (sem ícone) e selected (com ícone de check).\n * Quando selecionado, automaticamente mostra o ícone de check.\n *\n * @param children - O conteúdo a ser exibido dentro do chip\n * @param selected - Se o chip está selecionado (mostra check automaticamente)\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos padrão de button HTML\n * @returns Um elemento de chip estilizado\n *\n * @example\n * ```tsx\n * <Chips onClick={() => console.log('clicked')}>\n * Label\n * </Chips>\n *\n * <Chips selected onClick={() => console.log('selected')}>\n * Selected Label\n * </Chips>\n * ```\n */\nconst Chips = ({\n children,\n selected = false,\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ChipsProps) => {\n // Get classes from lookup tables\n const stateClasses = selected\n ? STATE_CLASSES.selected\n : STATE_CLASSES.default;\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-normal text-sm px-4 py-2 gap-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-primary-600 disabled:opacity-40 disabled:cursor-not-allowed';\n\n return (\n <button\n className={cn(baseClasses, stateClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {selected && (\n <span className={`flex items-center`}>\n <Check weight=\"bold\" size={16} />\n </span>\n )}\n\n <span className=\"flex-1\">{children}</span>\n </button>\n );\n};\n\nexport default Chips;\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":";AACA,SAAS,aAAa;;;ACDtB,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;AD+DI,SAQM,KARN;AA7DJ,IAAM,gBAAgB;AAAA,EACpB,SACE;AAAA,EACF,UACE;AACJ;AAuCA,IAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,EACP,GAAG;AACL,MAAkB;AAEhB,QAAM,eAAe,WACjB,cAAc,WACd,cAAc;AAElB,QAAM,cACJ;AAEF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,cAAc,SAAS;AAAA,MAClD;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA,oBACC,oBAAC,UAAK,WAAW,qBACf,8BAAC,SAAM,QAAO,QAAO,MAAM,IAAI,GACjC;AAAA,QAGF,oBAAC,UAAK,WAAU,UAAU,UAAS;AAAA;AAAA;AAAA,EACrC;AAEJ;AAEA,IAAO,gBAAQ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/Chips/Chips.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { Check } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for chip state classes\n */\nconst STATE_CLASSES = {\n default:\n 'bg-background text-text-950 border border-border-100 hover:bg-secondary-50 hover:border-border-300',\n selected:\n 'bg-info-background text-primary-950 border-2 border-primary-950 hover:bg-secondary-50 focus-visible:border-0',\n} as const;\n\n/**\n * Chips component props interface\n */\ntype ChipsProps = {\n /** Content to be displayed inside the chip */\n children: ReactNode;\n /** Se o chip está selecionado (mostra check automaticamente) */\n selected?: boolean;\n\n /** Additional CSS classes to apply */\n className?: string;\n} & Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'>;\n\n/**\n * Chips component for Analytica Ensino platforms\n *\n * Um componente de chip seguindo exatamente o design do Figma.\n * Suporte a dois estados principais: default (sem ícone) e selected (com ícone de check).\n * Quando selecionado, automaticamente mostra o ícone de check.\n *\n * @param children - O conteúdo a ser exibido dentro do chip\n * @param selected - Se o chip está selecionado (mostra check automaticamente)\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos padrão de button HTML\n * @returns Um elemento de chip estilizado\n *\n * @example\n * ```tsx\n * <Chips onClick={() => console.log('clicked')}>\n * Label\n * </Chips>\n *\n * <Chips selected onClick={() => console.log('selected')}>\n * Selected Label\n * </Chips>\n * ```\n */\nconst Chips = ({\n children,\n selected = false,\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ChipsProps) => {\n // Get classes from lookup tables\n const stateClasses = selected\n ? STATE_CLASSES.selected\n : STATE_CLASSES.default;\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-normal text-sm px-4 py-2 gap-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-primary-600 disabled:opacity-40 disabled:cursor-not-allowed';\n\n return (\n <button\n className={cn(baseClasses, stateClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {selected && (\n <span className={`flex items-center`}>\n <Check weight=\"bold\" size={16} />\n </span>\n )}\n\n <span className=\"flex-1\">{children}</span>\n </button>\n );\n};\n\nexport default Chips;\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\n/**\n * Retorna a cor hexadecimal com opacidade 0.7 (b3) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.7 (b3) para cores de 6 dígitos\n resultColor = `#${color}b3`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":";AACA,SAAS,aAAa;;;ACDtB,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;AD+DI,SAQM,KARN;AA7DJ,IAAM,gBAAgB;AAAA,EACpB,SACE;AAAA,EACF,UACE;AACJ;AAuCA,IAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,EACP,GAAG;AACL,MAAkB;AAEhB,QAAM,eAAe,WACjB,cAAc,WACd,cAAc;AAElB,QAAM,cACJ;AAEF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,cAAc,SAAS;AAAA,MAClD;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA,oBACC,oBAAC,UAAK,WAAW,qBACf,8BAAC,SAAM,QAAO,QAAO,MAAM,IAAI,GACjC;AAAA,QAGF,oBAAC,UAAK,WAAU,UAAU,UAAS;AAAA;AAAA;AAAA,EACrC;AAEJ;AAEA,IAAO,gBAAQ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Divider/Divider.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { HTMLAttributes } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Divider component props interface\n */\ntype DividerProps = {\n /** Orientation of the divider */\n orientation?: 'horizontal' | 'vertical';\n /** Additional CSS classes to apply */\n className?: string;\n} & HTMLAttributes<HTMLHRElement>;\n\n/**\n * Divider component for Analytica Ensino platforms\n *\n * A simple divider component that creates a visual separation between content sections.\n * Can be used both horizontally and vertically.\n *\n * @param orientation - The orientation of the divider (horizontal or vertical)\n * @param className - Additional CSS classes\n * @param props - All other standard hr HTML attributes\n * @returns A styled divider element\n *\n * @example\n * ```tsx\n * <Divider orientation=\"horizontal\" />\n * <Divider orientation=\"vertical\" className=\"h-8\" />\n * ```\n */\nconst Divider = ({\n orientation = 'horizontal',\n className = '',\n ...props\n}: DividerProps) => {\n const baseClasses = 'bg-border-200 border-0';\n\n const orientationClasses = {\n horizontal: 'w-full h-px',\n vertical: 'h-full w-px',\n };\n\n return (\n <hr\n className={cn(baseClasses, orientationClasses[orientation], className)}\n aria-orientation={orientation}\n {...props}\n />\n );\n};\n\nexport default Divider;\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;;;ACAA,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;ADsCI;AAbJ,IAAM,UAAU,CAAC;AAAA,EACf,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,GAAG;AACL,MAAoB;AAClB,QAAM,cAAc;AAEpB,QAAM,qBAAqB;AAAA,IACzB,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,mBAAmB,WAAW,GAAG,SAAS;AAAA,MACrE,oBAAkB;AAAA,MACjB,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAO,kBAAQ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/Divider/Divider.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { HTMLAttributes } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Divider component props interface\n */\ntype DividerProps = {\n /** Orientation of the divider */\n orientation?: 'horizontal' | 'vertical';\n /** Additional CSS classes to apply */\n className?: string;\n} & HTMLAttributes<HTMLHRElement>;\n\n/**\n * Divider component for Analytica Ensino platforms\n *\n * A simple divider component that creates a visual separation between content sections.\n * Can be used both horizontally and vertically.\n *\n * @param orientation - The orientation of the divider (horizontal or vertical)\n * @param className - Additional CSS classes\n * @param props - All other standard hr HTML attributes\n * @returns A styled divider element\n *\n * @example\n * ```tsx\n * <Divider orientation=\"horizontal\" />\n * <Divider orientation=\"vertical\" className=\"h-8\" />\n * ```\n */\nconst Divider = ({\n orientation = 'horizontal',\n className = '',\n ...props\n}: DividerProps) => {\n const baseClasses = 'bg-border-200 border-0';\n\n const orientationClasses = {\n horizontal: 'w-full h-px',\n vertical: 'h-full w-px',\n };\n\n return (\n <hr\n className={cn(baseClasses, orientationClasses[orientation], className)}\n aria-orientation={orientation}\n {...props}\n />\n );\n};\n\nexport default Divider;\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\n/**\n * Retorna a cor hexadecimal com opacidade 0.7 (b3) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.7 (b3) para cores de 6 dígitos\n resultColor = `#${color}b3`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;ADsCI;AAbJ,IAAM,UAAU,CAAC;AAAA,EACf,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,GAAG;AACL,MAAoB;AAClB,QAAM,cAAc;AAEpB,QAAM,qBAAqB;AAAA,IACzB,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,mBAAmB,WAAW,GAAG,SAAS;AAAA,MACrE,oBAAkB;AAAA,MACjB,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAO,kBAAQ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/utils.ts","../../src/components/Divider/Divider.tsx"],"sourcesContent":["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 { HTMLAttributes } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Divider component props interface\n */\ntype DividerProps = {\n /** Orientation of the divider */\n orientation?: 'horizontal' | 'vertical';\n /** Additional CSS classes to apply */\n className?: string;\n} & HTMLAttributes<HTMLHRElement>;\n\n/**\n * Divider component for Analytica Ensino platforms\n *\n * A simple divider component that creates a visual separation between content sections.\n * Can be used both horizontally and vertically.\n *\n * @param orientation - The orientation of the divider (horizontal or vertical)\n * @param className - Additional CSS classes\n * @param props - All other standard hr HTML attributes\n * @returns A styled divider element\n *\n * @example\n * ```tsx\n * <Divider orientation=\"horizontal\" />\n * <Divider orientation=\"vertical\" className=\"h-8\" />\n * ```\n */\nconst Divider = ({\n orientation = 'horizontal',\n className = '',\n ...props\n}: DividerProps) => {\n const baseClasses = 'bg-border-200 border-0';\n\n const orientationClasses = {\n horizontal: 'w-full h-px',\n vertical: 'h-full w-px',\n };\n\n return (\n <hr\n className={cn(baseClasses, orientationClasses[orientation], className)}\n aria-orientation={orientation}\n {...props}\n />\n );\n};\n\nexport default Divider;\n"],"mappings":";AAAA,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACsCI;AAbJ,IAAM,UAAU,CAAC;AAAA,EACf,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,GAAG;AACL,MAAoB;AAClB,QAAM,cAAc;AAEpB,QAAM,qBAAqB;AAAA,IACzB,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,mBAAmB,WAAW,GAAG,SAAS;AAAA,MACrE,oBAAkB;AAAA,MACjB,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAO,kBAAQ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/utils.ts","../../src/components/Divider/Divider.tsx"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.7 (b3) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.7 (b3) para cores de 6 dígitos\n resultColor = `#${color}b3`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n","import { HTMLAttributes } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Divider component props interface\n */\ntype DividerProps = {\n /** Orientation of the divider */\n orientation?: 'horizontal' | 'vertical';\n /** Additional CSS classes to apply */\n className?: string;\n} & HTMLAttributes<HTMLHRElement>;\n\n/**\n * Divider component for Analytica Ensino platforms\n *\n * A simple divider component that creates a visual separation between content sections.\n * Can be used both horizontally and vertically.\n *\n * @param orientation - The orientation of the divider (horizontal or vertical)\n * @param className - Additional CSS classes\n * @param props - All other standard hr HTML attributes\n * @returns A styled divider element\n *\n * @example\n * ```tsx\n * <Divider orientation=\"horizontal\" />\n * <Divider orientation=\"vertical\" className=\"h-8\" />\n * ```\n */\nconst Divider = ({\n orientation = 'horizontal',\n className = '',\n ...props\n}: DividerProps) => {\n const baseClasses = 'bg-border-200 border-0';\n\n const orientationClasses = {\n horizontal: 'w-full h-px',\n vertical: 'h-full w-px',\n };\n\n return (\n <hr\n className={cn(baseClasses, orientationClasses[orientation], className)}\n aria-orientation={orientation}\n {...props}\n />\n );\n};\n\nexport default Divider;\n"],"mappings":";AAAA,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACsCI;AAbJ,IAAM,UAAU,CAAC;AAAA,EACf,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,GAAG;AACL,MAAoB;AAClB,QAAM,cAAc;AAEpB,QAAM,qBAAqB;AAAA,IACzB,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,mBAAmB,WAAW,GAAG,SAAS;AAAA,MACrE,oBAAkB;AAAA,MACjB,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAO,kBAAQ;","names":[]}
|
|
@@ -37,7 +37,7 @@ __export(DropdownMenu_exports, {
|
|
|
37
37
|
module.exports = __toCommonJS(DropdownMenu_exports);
|
|
38
38
|
var import_phosphor_react3 = require("phosphor-react");
|
|
39
39
|
var import_react5 = require("react");
|
|
40
|
-
var
|
|
40
|
+
var import_zustand2 = require("zustand");
|
|
41
41
|
|
|
42
42
|
// src/utils/utils.ts
|
|
43
43
|
var import_clsx = require("clsx");
|
|
@@ -439,82 +439,117 @@ var SelectionButton_default = SelectionButton;
|
|
|
439
439
|
|
|
440
440
|
// src/hooks/useTheme.ts
|
|
441
441
|
var import_react3 = require("react");
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
442
|
+
|
|
443
|
+
// src/store/themeStore.ts
|
|
444
|
+
var import_zustand = require("zustand");
|
|
445
|
+
var import_middleware = require("zustand/middleware");
|
|
446
|
+
var applyThemeToDOM = (mode) => {
|
|
447
|
+
const htmlElement = document.documentElement;
|
|
448
|
+
const originalTheme = htmlElement.getAttribute("data-original-theme");
|
|
449
|
+
if (mode === "dark") {
|
|
450
|
+
htmlElement.setAttribute("data-theme", "dark");
|
|
451
|
+
return true;
|
|
452
|
+
} else if (mode === "light") {
|
|
453
|
+
if (originalTheme) {
|
|
454
|
+
htmlElement.setAttribute("data-theme", originalTheme);
|
|
455
|
+
}
|
|
456
|
+
return false;
|
|
457
|
+
} else if (mode === "system") {
|
|
458
|
+
const isSystemDark = window.matchMedia(
|
|
459
|
+
"(prefers-color-scheme: dark)"
|
|
460
|
+
).matches;
|
|
461
|
+
if (isSystemDark) {
|
|
450
462
|
htmlElement.setAttribute("data-theme", "dark");
|
|
451
|
-
|
|
452
|
-
} else if (
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
}
|
|
456
|
-
setIsDark(false);
|
|
457
|
-
} else if (mode === "system") {
|
|
458
|
-
const isSystemDark = window.matchMedia(
|
|
459
|
-
"(prefers-color-scheme: dark)"
|
|
460
|
-
).matches;
|
|
461
|
-
if (isSystemDark) {
|
|
462
|
-
htmlElement.setAttribute("data-theme", "dark");
|
|
463
|
-
setIsDark(true);
|
|
464
|
-
} else if (originalTheme) {
|
|
465
|
-
htmlElement.setAttribute("data-theme", originalTheme);
|
|
466
|
-
setIsDark(false);
|
|
467
|
-
}
|
|
463
|
+
return true;
|
|
464
|
+
} else if (originalTheme) {
|
|
465
|
+
htmlElement.setAttribute("data-theme", originalTheme);
|
|
466
|
+
return false;
|
|
468
467
|
}
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
468
|
+
}
|
|
469
|
+
return false;
|
|
470
|
+
};
|
|
471
|
+
var saveOriginalTheme = () => {
|
|
472
|
+
const htmlElement = document.documentElement;
|
|
473
|
+
const currentTheme = htmlElement.getAttribute("data-theme");
|
|
474
|
+
if (currentTheme && !htmlElement.getAttribute("data-original-theme")) {
|
|
475
|
+
htmlElement.setAttribute("data-original-theme", currentTheme);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
var useThemeStore = (0, import_zustand.create)()(
|
|
479
|
+
(0, import_middleware.devtools)(
|
|
480
|
+
(0, import_middleware.persist)(
|
|
481
|
+
(set, get) => ({
|
|
482
|
+
// Initial state
|
|
483
|
+
themeMode: "system",
|
|
484
|
+
isDark: false,
|
|
485
|
+
// Actions
|
|
486
|
+
applyTheme: (mode) => {
|
|
487
|
+
const isDark = applyThemeToDOM(mode);
|
|
488
|
+
set({ isDark });
|
|
489
|
+
},
|
|
490
|
+
toggleTheme: () => {
|
|
491
|
+
const { themeMode, applyTheme } = get();
|
|
492
|
+
let newMode;
|
|
493
|
+
if (themeMode === "light") {
|
|
494
|
+
newMode = "dark";
|
|
495
|
+
} else if (themeMode === "dark") {
|
|
496
|
+
newMode = "light";
|
|
497
|
+
} else {
|
|
498
|
+
newMode = "dark";
|
|
499
|
+
}
|
|
500
|
+
set({ themeMode: newMode });
|
|
501
|
+
applyTheme(newMode);
|
|
502
|
+
},
|
|
503
|
+
setTheme: (mode) => {
|
|
504
|
+
const { applyTheme } = get();
|
|
505
|
+
set({ themeMode: mode });
|
|
506
|
+
applyTheme(mode);
|
|
507
|
+
},
|
|
508
|
+
initializeTheme: () => {
|
|
509
|
+
const { themeMode, applyTheme } = get();
|
|
510
|
+
saveOriginalTheme();
|
|
511
|
+
applyTheme(themeMode);
|
|
512
|
+
},
|
|
513
|
+
handleSystemThemeChange: () => {
|
|
514
|
+
const { themeMode, applyTheme } = get();
|
|
515
|
+
if (themeMode === "system") {
|
|
516
|
+
applyTheme("system");
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}),
|
|
520
|
+
{
|
|
521
|
+
name: "theme-store",
|
|
522
|
+
// Nome da chave no localStorage
|
|
523
|
+
partialize: (state) => ({
|
|
524
|
+
themeMode: state.themeMode
|
|
525
|
+
})
|
|
526
|
+
// Só persiste o themeMode, não o isDark
|
|
527
|
+
}
|
|
528
|
+
),
|
|
529
|
+
{
|
|
530
|
+
name: "theme-store"
|
|
478
531
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
);
|
|
532
|
+
)
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
// src/hooks/useTheme.ts
|
|
536
|
+
var useTheme = () => {
|
|
537
|
+
const {
|
|
538
|
+
themeMode,
|
|
539
|
+
isDark,
|
|
540
|
+
toggleTheme,
|
|
541
|
+
setTheme,
|
|
542
|
+
initializeTheme,
|
|
543
|
+
handleSystemThemeChange
|
|
544
|
+
} = useThemeStore();
|
|
493
545
|
(0, import_react3.useEffect)(() => {
|
|
494
|
-
|
|
495
|
-
const currentTheme = htmlElement.getAttribute("data-theme");
|
|
496
|
-
if (currentTheme && !htmlElement.getAttribute("data-original-theme")) {
|
|
497
|
-
htmlElement.setAttribute("data-original-theme", currentTheme);
|
|
498
|
-
}
|
|
499
|
-
const savedThemeMode = localStorage.getItem("theme-mode");
|
|
500
|
-
const initialMode = savedThemeMode || "system";
|
|
501
|
-
if (!savedThemeMode) {
|
|
502
|
-
localStorage.setItem("theme-mode", "system");
|
|
503
|
-
}
|
|
504
|
-
setThemeMode(initialMode);
|
|
505
|
-
themeModeRef.current = initialMode;
|
|
506
|
-
applyTheme(initialMode);
|
|
546
|
+
initializeTheme();
|
|
507
547
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
508
|
-
const handleSystemThemeChange = () => {
|
|
509
|
-
if (themeModeRef.current === "system") {
|
|
510
|
-
applyTheme("system");
|
|
511
|
-
}
|
|
512
|
-
};
|
|
513
548
|
mediaQuery.addEventListener("change", handleSystemThemeChange);
|
|
514
549
|
return () => {
|
|
515
550
|
mediaQuery.removeEventListener("change", handleSystemThemeChange);
|
|
516
551
|
};
|
|
517
|
-
}, [
|
|
552
|
+
}, [initializeTheme, handleSystemThemeChange]);
|
|
518
553
|
return {
|
|
519
554
|
themeMode,
|
|
520
555
|
isDark,
|
|
@@ -594,7 +629,7 @@ var ThemeToggle = ({
|
|
|
594
629
|
// src/components/DropdownMenu/DropdownMenu.tsx
|
|
595
630
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
596
631
|
function createDropdownStore() {
|
|
597
|
-
return (0,
|
|
632
|
+
return (0, import_zustand2.create)((set) => ({
|
|
598
633
|
open: false,
|
|
599
634
|
setOpen: (open) => set({ open })
|
|
600
635
|
}));
|
|
@@ -630,7 +665,7 @@ var DropdownMenu = ({
|
|
|
630
665
|
const storeRef = (0, import_react5.useRef)(null);
|
|
631
666
|
storeRef.current ??= createDropdownStore();
|
|
632
667
|
const store = storeRef.current;
|
|
633
|
-
const { open, setOpen: storeSetOpen } = (0,
|
|
668
|
+
const { open, setOpen: storeSetOpen } = (0, import_zustand2.useStore)(store, (s) => s);
|
|
634
669
|
const setOpen = (newOpen) => {
|
|
635
670
|
storeSetOpen(newOpen);
|
|
636
671
|
};
|
|
@@ -697,7 +732,7 @@ var DropdownMenuTrigger = ({
|
|
|
697
732
|
...props
|
|
698
733
|
}) => {
|
|
699
734
|
const store = useDropdownStore(externalStore);
|
|
700
|
-
const open = (0,
|
|
735
|
+
const open = (0, import_zustand2.useStore)(store, (s) => s.open);
|
|
701
736
|
const toggleOpen = () => store.setState({ open: !open });
|
|
702
737
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
703
738
|
"button",
|
|
@@ -757,7 +792,7 @@ var DropdownMenuContent = (0, import_react5.forwardRef)(
|
|
|
757
792
|
...props
|
|
758
793
|
}, ref) => {
|
|
759
794
|
const store = useDropdownStore(externalStore);
|
|
760
|
-
const open = (0,
|
|
795
|
+
const open = (0, import_zustand2.useStore)(store, (s) => s.open);
|
|
761
796
|
const [isVisible, setIsVisible] = (0, import_react5.useState)(open);
|
|
762
797
|
(0, import_react5.useEffect)(() => {
|
|
763
798
|
if (open) {
|
|
@@ -813,7 +848,7 @@ var DropdownMenuItem = (0, import_react5.forwardRef)(
|
|
|
813
848
|
...props
|
|
814
849
|
}, ref) => {
|
|
815
850
|
const store = useDropdownStore(externalStore);
|
|
816
|
-
const setOpen = (0,
|
|
851
|
+
const setOpen = (0, import_zustand2.useStore)(store, (s) => s.setOpen);
|
|
817
852
|
const sizeClasses = ITEM_SIZE_CLASSES[size];
|
|
818
853
|
const handleClick = (e) => {
|
|
819
854
|
if (disabled) {
|
|
@@ -874,7 +909,7 @@ var DropdownMenuSeparator = (0, import_react5.forwardRef)(({ className, store: _
|
|
|
874
909
|
DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
|
|
875
910
|
var ProfileMenuTrigger = (0, import_react5.forwardRef)(({ className, onClick, store: externalStore, ...props }, ref) => {
|
|
876
911
|
const store = useDropdownStore(externalStore);
|
|
877
|
-
const open = (0,
|
|
912
|
+
const open = (0, import_zustand2.useStore)(store, (s) => s.open);
|
|
878
913
|
const toggleOpen = () => store.setState({ open: !open });
|
|
879
914
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
880
915
|
"button",
|
|
@@ -1007,7 +1042,7 @@ var ProfileMenuFooter = ({
|
|
|
1007
1042
|
...props
|
|
1008
1043
|
}) => {
|
|
1009
1044
|
const store = useDropdownStore(externalStore);
|
|
1010
|
-
const setOpen = (0,
|
|
1045
|
+
const setOpen = (0, import_zustand2.useStore)(store, (s) => s.setOpen);
|
|
1011
1046
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1012
1047
|
Button_default,
|
|
1013
1048
|
{
|