analytica-frontend-lib 1.1.95 → 1.1.96

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.
@@ -69,6 +69,6 @@ declare const CheckBox: react.ForwardRefExoticComponent<{
69
69
  className?: string;
70
70
  /** Label CSS classes */
71
71
  labelClassName?: string;
72
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & react.RefAttributes<HTMLInputElement>>;
72
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
73
73
 
74
74
  export { type CheckBoxProps, CheckBox as default };
@@ -69,6 +69,6 @@ declare const CheckBox: react.ForwardRefExoticComponent<{
69
69
  className?: string;
70
70
  /** Label CSS classes */
71
71
  labelClassName?: string;
72
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & react.RefAttributes<HTMLInputElement>>;
72
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
73
73
 
74
74
  export { type CheckBoxProps, CheckBox as default };
@@ -81,7 +81,7 @@ declare const Radio: react.ForwardRefExoticComponent<{
81
81
  value?: string;
82
82
  /** Default checked state for uncontrolled radios */
83
83
  defaultChecked?: boolean;
84
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "defaultChecked" | "type"> & react.RefAttributes<HTMLInputElement>>;
84
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "defaultChecked" | "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
85
85
  /**
86
86
  * RadioGroup store interface
87
87
  */
@@ -198,6 +198,6 @@ declare const RadioGroupItem: react.ForwardRefExoticComponent<{
198
198
  state?: RadioState;
199
199
  /** Additional CSS classes */
200
200
  className?: string;
201
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "value" | "checked" | "type" | "name" | "onChange"> & react.RefAttributes<HTMLInputElement>>;
201
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "name" | "type" | "size" | "value" | "checked"> & react.RefAttributes<HTMLInputElement>>;
202
202
 
203
203
  export { RadioGroup, RadioGroupItem, type RadioGroupItemProps, type RadioGroupProps, type RadioProps, Radio as default, useRadioGroupStore };
@@ -81,7 +81,7 @@ declare const Radio: react.ForwardRefExoticComponent<{
81
81
  value?: string;
82
82
  /** Default checked state for uncontrolled radios */
83
83
  defaultChecked?: boolean;
84
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "defaultChecked" | "type"> & react.RefAttributes<HTMLInputElement>>;
84
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "defaultChecked" | "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
85
85
  /**
86
86
  * RadioGroup store interface
87
87
  */
@@ -198,6 +198,6 @@ declare const RadioGroupItem: react.ForwardRefExoticComponent<{
198
198
  state?: RadioState;
199
199
  /** Additional CSS classes */
200
200
  className?: string;
201
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "value" | "checked" | "type" | "name" | "onChange"> & react.RefAttributes<HTMLInputElement>>;
201
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "name" | "type" | "size" | "value" | "checked"> & react.RefAttributes<HTMLInputElement>>;
202
202
 
203
203
  export { RadioGroup, RadioGroupItem, type RadioGroupItemProps, type RadioGroupProps, type RadioProps, Radio as default, useRadioGroupStore };
@@ -22,6 +22,6 @@ declare const Search: react.ForwardRefExoticComponent<{
22
22
  containerClassName?: string;
23
23
  /** Callback when clear button is clicked */
24
24
  onClear?: () => void;
25
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "onSelect"> & react.RefAttributes<HTMLInputElement>>;
25
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "onSelect" | "size"> & react.RefAttributes<HTMLInputElement>>;
26
26
 
27
27
  export { Search as default };
@@ -22,6 +22,6 @@ declare const Search: react.ForwardRefExoticComponent<{
22
22
  containerClassName?: string;
23
23
  /** Callback when clear button is clicked */
24
24
  onClear?: () => void;
25
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "onSelect"> & react.RefAttributes<HTMLInputElement>>;
25
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "onSelect" | "size"> & react.RefAttributes<HTMLInputElement>>;
26
26
 
27
27
  export { Search as default };
@@ -19,6 +19,8 @@ interface StatisticsCardProps {
19
19
  title: string;
20
20
  /** Statistics data to display */
21
21
  data?: StatItem[];
22
+ /** Show placeholder "-" in values when true (for created items without data yet) */
23
+ showPlaceholder?: boolean;
22
24
  /** Message shown in empty state */
23
25
  emptyStateMessage?: string;
24
26
  /** Text for the empty state button */
@@ -72,6 +74,6 @@ interface StatisticsCardProps {
72
74
  * />
73
75
  * ```
74
76
  */
75
- declare const StatisticsCard: ({ title, data, emptyStateMessage, emptyStateButtonText, onEmptyStateButtonClick, dropdownOptions, selectedDropdownValue, onDropdownChange, selectPlaceholder, dropdownAriaLabel, className, }: StatisticsCardProps) => react_jsx_runtime.JSX.Element;
77
+ declare const StatisticsCard: ({ title, data, showPlaceholder, emptyStateMessage, emptyStateButtonText, onEmptyStateButtonClick, dropdownOptions, selectedDropdownValue, onDropdownChange, selectPlaceholder, dropdownAriaLabel, className, }: StatisticsCardProps) => react_jsx_runtime.JSX.Element;
76
78
 
77
79
  export { StatisticsCard };
@@ -19,6 +19,8 @@ interface StatisticsCardProps {
19
19
  title: string;
20
20
  /** Statistics data to display */
21
21
  data?: StatItem[];
22
+ /** Show placeholder "-" in values when true (for created items without data yet) */
23
+ showPlaceholder?: boolean;
22
24
  /** Message shown in empty state */
23
25
  emptyStateMessage?: string;
24
26
  /** Text for the empty state button */
@@ -72,6 +74,6 @@ interface StatisticsCardProps {
72
74
  * />
73
75
  * ```
74
76
  */
75
- declare const StatisticsCard: ({ title, data, emptyStateMessage, emptyStateButtonText, onEmptyStateButtonClick, dropdownOptions, selectedDropdownValue, onDropdownChange, selectPlaceholder, dropdownAriaLabel, className, }: StatisticsCardProps) => react_jsx_runtime.JSX.Element;
77
+ declare const StatisticsCard: ({ title, data, showPlaceholder, emptyStateMessage, emptyStateButtonText, onEmptyStateButtonClick, dropdownOptions, selectedDropdownValue, onDropdownChange, selectPlaceholder, dropdownAriaLabel, className, }: StatisticsCardProps) => react_jsx_runtime.JSX.Element;
76
78
 
77
79
  export { StatisticsCard };
@@ -500,7 +500,7 @@ var VALUE_TEXT_COLORS = {
500
500
  low: "text-error-700",
501
501
  total: "text-info-700"
502
502
  };
503
- var StatCard = ({ item }) => {
503
+ var StatCard = ({ item, showPlaceholder = false }) => {
504
504
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
505
505
  "div",
506
506
  {
@@ -512,7 +512,7 @@ var StatCard = ({ item }) => {
512
512
  size: "4xl",
513
513
  weight: "bold",
514
514
  className: `${VALUE_TEXT_COLORS[item.variant]} leading-[42px] tracking-[0.2px] self-stretch`,
515
- children: item.value
515
+ children: showPlaceholder ? "-" : item.value
516
516
  }
517
517
  ),
518
518
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
@@ -528,9 +528,16 @@ var StatCard = ({ item }) => {
528
528
  }
529
529
  );
530
530
  };
531
+ var getGridColumnsClass = (itemCount) => {
532
+ if (itemCount === 4) return "lg:grid-cols-4";
533
+ if (itemCount === 3) return "lg:grid-cols-3";
534
+ if (itemCount === 2) return "lg:grid-cols-2";
535
+ return "lg:grid-cols-1";
536
+ };
531
537
  var StatisticsCard = ({
532
538
  title,
533
539
  data,
540
+ showPlaceholder = false,
534
541
  emptyStateMessage,
535
542
  emptyStateButtonText,
536
543
  onEmptyStateButtonClick,
@@ -542,6 +549,7 @@ var StatisticsCard = ({
542
549
  className = ""
543
550
  }) => {
544
551
  const hasData = data && data.length > 0;
552
+ const gridColumnsClass = hasData ? getGridColumnsClass(data.length) : "";
545
553
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
546
554
  "div",
547
555
  {
@@ -569,13 +577,20 @@ var StatisticsCard = ({
569
577
  }
570
578
  ) })
571
579
  ] }),
572
- hasData ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-[13px]", children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
573
- StatCard,
580
+ hasData ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
581
+ "div",
574
582
  {
575
- item
576
- },
577
- `${item.variant}-${item.label}-${index}`
578
- )) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2", children: [
583
+ className: `grid grid-cols-1 sm:grid-cols-2 gap-[13px] ${gridColumnsClass}`,
584
+ children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
585
+ StatCard,
586
+ {
587
+ item,
588
+ showPlaceholder
589
+ },
590
+ `${item.variant}-${item.label}-${index}`
591
+ ))
592
+ }
593
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2", children: [
579
594
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
580
595
  Text_default,
581
596
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/StatisticsCard/StatisticsCard.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Button/Button.tsx","../../src/components/Select/Select.tsx"],"sourcesContent":["import Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Select, {\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n} from '../Select/Select';\nimport { Plus } from 'phosphor-react';\n\n/**\n * Statistics data item\n */\ninterface StatItem {\n /** Statistic label */\n label: string;\n /** Statistic value */\n value: string | number;\n /** Color variant */\n variant: 'high' | 'medium' | 'low' | 'total';\n}\n\n/**\n * Props for StatisticsCard component\n */\ninterface StatisticsCardProps {\n /** Title displayed at the top of the card */\n title: string;\n /** Statistics data to display */\n data?: StatItem[];\n /** Message shown in empty state */\n emptyStateMessage?: string;\n /** Text for the empty state button */\n emptyStateButtonText?: string;\n /** Callback when empty state button is clicked */\n onEmptyStateButtonClick?: () => void;\n /** Optional dropdown options for filtering */\n dropdownOptions?: Array<{\n label: string;\n value: string;\n }>;\n /** Currently selected dropdown value */\n selectedDropdownValue?: string;\n /** Callback when dropdown value changes */\n onDropdownChange?: (value: string) => void;\n /** Placeholder text for the dropdown select */\n selectPlaceholder?: string;\n /** Accessible label for the dropdown select */\n dropdownAriaLabel?: string;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Variant styles mapping\n */\nconst VARIANT_STYLES = {\n high: 'bg-success-background',\n medium: 'bg-warning-background',\n low: 'bg-error-background',\n total: 'bg-info-background',\n} as const;\n\n/**\n * Value text colors mapping\n */\nconst VALUE_TEXT_COLORS = {\n high: 'text-success-700',\n medium: 'text-warning-600',\n low: 'text-error-700',\n total: 'text-info-700',\n} as const;\n\n/**\n * Internal StatCard component\n */\ninterface StatCardProps {\n item: StatItem;\n}\n\nconst StatCard = ({ item }: StatCardProps) => {\n return (\n <div\n className={`rounded-xl py-[17px] px-6 min-h-[105px] flex flex-col justify-center items-start gap-1 ${VARIANT_STYLES[item.variant]}`}\n >\n <Text\n size=\"4xl\"\n weight=\"bold\"\n className={`${VALUE_TEXT_COLORS[item.variant]} leading-[42px] tracking-[0.2px] self-stretch`}\n >\n {item.value}\n </Text>\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"uppercase text-[8px] leading-[9px] text-text-800 self-stretch\"\n >\n {item.label}\n </Text>\n </div>\n );\n};\n\n/**\n * StatisticsCard component - displays statistics with empty state support\n *\n * @example\n * ```tsx\n * // With data\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * data={[\n * { label: 'Acertos', value: '85%', variant: 'high' },\n * { label: 'Em andamento', value: 12, variant: 'medium' },\n * { label: 'Erros', value: '15%', variant: 'low' },\n * { label: 'Concluídas', value: 24, variant: 'total' }\n * ]}\n * dropdownOptions={[\n * { label: '1 ano', value: '1year' },\n * { label: '6 meses', value: '6months' }\n * ]}\n * selectedDropdownValue=\"1year\"\n * onDropdownChange={(value) => console.log(value)}\n * />\n *\n * // Empty state\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * emptyStateMessage=\"Sem dados por enquanto. Crie uma atividade para que os resultados apareçam aqui.\"\n * emptyStateButtonText=\"Criar atividade\"\n * onEmptyStateButtonClick={() => console.log('Create activity')}\n * />\n * ```\n */\nexport const StatisticsCard = ({\n title,\n data,\n emptyStateMessage,\n emptyStateButtonText,\n onEmptyStateButtonClick,\n dropdownOptions,\n selectedDropdownValue,\n onDropdownChange,\n selectPlaceholder = 'Selecione um período',\n dropdownAriaLabel = 'Filtro de período',\n className = '',\n}: StatisticsCardProps) => {\n const hasData = data && data.length > 0;\n\n return (\n <div\n className={`bg-background rounded-xl p-4 h-auto lg:h-[185px] flex flex-col gap-2 ${className}`}\n >\n {/* Header with title and optional dropdown */}\n <div className=\"flex flex-row justify-between items-center gap-4\">\n <Text as=\"h3\" size=\"sm\" weight=\"medium\" color=\"text-text-600\">\n {title}\n </Text>\n\n {dropdownOptions && dropdownOptions.length > 0 && (\n <div className=\"w-[99px]\">\n <Select\n value={selectedDropdownValue}\n onValueChange={onDropdownChange}\n size=\"medium\"\n >\n <SelectTrigger\n className=\"border border-border-300 rounded whitespace-nowrap\"\n aria-label={dropdownAriaLabel}\n >\n <SelectValue placeholder={selectPlaceholder} />\n </SelectTrigger>\n <SelectContent>\n {dropdownOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n </div>\n\n {/* Content: Data Grid or Empty State */}\n {hasData ? (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-[13px]\">\n {data.map((item, index) => (\n <StatCard\n key={`${item.variant}-${item.label}-${index}`}\n item={item}\n />\n ))}\n </div>\n ) : (\n <div className=\"border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2\">\n <Text\n size=\"sm\"\n color=\"text-text-600\"\n className=\"text-center max-w-md\"\n >\n {emptyStateMessage}\n </Text>\n\n {onEmptyStateButtonClick && (\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"small\"\n onClick={onEmptyStateButtonClick}\n iconLeft={<Plus size={16} weight=\"bold\" />}\n >\n {emptyStateButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\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\nexport { syncDropdownState } from './dropdown';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) 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.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\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","import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n","import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nconst VARIANT_CLASSES = {\n outlined: 'border-2 rounded-lg focus:border-primary-950',\n underlined: 'border-b-2 focus:border-primary-950',\n rounded: 'border-2 rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n className?: string;\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n className,\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className={cn('w-full', className)}>\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={cn('block font-bold text-text-900 mb-1.5', sizeClasses)}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={cn('relative w-full')} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n {(helperText || errorMessage) && (\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n )}\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit flex gap-2 items-center\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={cn(\n 'flex w-full items-center justify-between border-border-300',\n heightClasses,\n paddingClasses,\n invalid &&\n `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`,\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground',\n !invalid && !disabled ? 'text-text-700' : '',\n variantClasses,\n className\n )}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={cn(\n 'h-[1em] w-[1em] opacity-50 transition-transform',\n open ? 'rotate-180' : ''\n )}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={cn(\n 'bg-secondary z-50 min-w-[210px] max-h-[300px] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md border-border-100',\n getPositionClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n // Always set the clicked value, even if it's already selected\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n bg-secondary focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","SIZE_CLASSES","children","label","import_phosphor_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/components/StatisticsCard/StatisticsCard.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Button/Button.tsx","../../src/components/Select/Select.tsx"],"sourcesContent":["import Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Select, {\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n} from '../Select/Select';\nimport { Plus } from 'phosphor-react';\n\n/**\n * Statistics data item\n */\ninterface StatItem {\n /** Statistic label */\n label: string;\n /** Statistic value */\n value: string | number;\n /** Color variant */\n variant: 'high' | 'medium' | 'low' | 'total';\n}\n\n/**\n * Props for StatisticsCard component\n */\ninterface StatisticsCardProps {\n /** Title displayed at the top of the card */\n title: string;\n /** Statistics data to display */\n data?: StatItem[];\n /** Show placeholder \"-\" in values when true (for created items without data yet) */\n showPlaceholder?: boolean;\n /** Message shown in empty state */\n emptyStateMessage?: string;\n /** Text for the empty state button */\n emptyStateButtonText?: string;\n /** Callback when empty state button is clicked */\n onEmptyStateButtonClick?: () => void;\n /** Optional dropdown options for filtering */\n dropdownOptions?: Array<{\n label: string;\n value: string;\n }>;\n /** Currently selected dropdown value */\n selectedDropdownValue?: string;\n /** Callback when dropdown value changes */\n onDropdownChange?: (value: string) => void;\n /** Placeholder text for the dropdown select */\n selectPlaceholder?: string;\n /** Accessible label for the dropdown select */\n dropdownAriaLabel?: string;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Variant styles mapping\n */\nconst VARIANT_STYLES = {\n high: 'bg-success-background',\n medium: 'bg-warning-background',\n low: 'bg-error-background',\n total: 'bg-info-background',\n} as const;\n\n/**\n * Value text colors mapping\n */\nconst VALUE_TEXT_COLORS = {\n high: 'text-success-700',\n medium: 'text-warning-600',\n low: 'text-error-700',\n total: 'text-info-700',\n} as const;\n\n/**\n * Internal StatCard component\n */\ninterface StatCardProps {\n item: StatItem;\n showPlaceholder?: boolean;\n}\n\nconst StatCard = ({ item, showPlaceholder = false }: StatCardProps) => {\n return (\n <div\n className={`rounded-xl py-[17px] px-6 min-h-[105px] flex flex-col justify-center items-start gap-1 ${VARIANT_STYLES[item.variant]}`}\n >\n <Text\n size=\"4xl\"\n weight=\"bold\"\n className={`${VALUE_TEXT_COLORS[item.variant]} leading-[42px] tracking-[0.2px] self-stretch`}\n >\n {showPlaceholder ? '-' : item.value}\n </Text>\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"uppercase text-[8px] leading-[9px] text-text-800 self-stretch\"\n >\n {item.label}\n </Text>\n </div>\n );\n};\n\n/**\n * Get grid column class based on number of items\n */\nconst getGridColumnsClass = (itemCount: number): string => {\n if (itemCount === 4) return 'lg:grid-cols-4';\n if (itemCount === 3) return 'lg:grid-cols-3';\n if (itemCount === 2) return 'lg:grid-cols-2';\n return 'lg:grid-cols-1';\n};\n\n/**\n * StatisticsCard component - displays statistics with empty state support\n *\n * @example\n * ```tsx\n * // With data\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * data={[\n * { label: 'Acertos', value: '85%', variant: 'high' },\n * { label: 'Em andamento', value: 12, variant: 'medium' },\n * { label: 'Erros', value: '15%', variant: 'low' },\n * { label: 'Concluídas', value: 24, variant: 'total' }\n * ]}\n * dropdownOptions={[\n * { label: '1 ano', value: '1year' },\n * { label: '6 meses', value: '6months' }\n * ]}\n * selectedDropdownValue=\"1year\"\n * onDropdownChange={(value) => console.log(value)}\n * />\n *\n * // Empty state\n * <StatisticsCard\n * title=\"Estatística das atividades\"\n * emptyStateMessage=\"Sem dados por enquanto. Crie uma atividade para que os resultados apareçam aqui.\"\n * emptyStateButtonText=\"Criar atividade\"\n * onEmptyStateButtonClick={() => console.log('Create activity')}\n * />\n * ```\n */\nexport const StatisticsCard = ({\n title,\n data,\n showPlaceholder = false,\n emptyStateMessage,\n emptyStateButtonText,\n onEmptyStateButtonClick,\n dropdownOptions,\n selectedDropdownValue,\n onDropdownChange,\n selectPlaceholder = 'Selecione um período',\n dropdownAriaLabel = 'Filtro de período',\n className = '',\n}: StatisticsCardProps) => {\n const hasData = data && data.length > 0;\n const gridColumnsClass = hasData ? getGridColumnsClass(data.length) : '';\n\n return (\n <div\n className={`bg-background rounded-xl p-4 h-auto lg:h-[185px] flex flex-col gap-2 ${className}`}\n >\n {/* Header with title and optional dropdown */}\n <div className=\"flex flex-row justify-between items-center gap-4\">\n <Text as=\"h3\" size=\"sm\" weight=\"medium\" color=\"text-text-600\">\n {title}\n </Text>\n\n {dropdownOptions && dropdownOptions.length > 0 && (\n <div className=\"w-[99px]\">\n <Select\n value={selectedDropdownValue}\n onValueChange={onDropdownChange}\n size=\"medium\"\n >\n <SelectTrigger\n className=\"border border-border-300 rounded whitespace-nowrap\"\n aria-label={dropdownAriaLabel}\n >\n <SelectValue placeholder={selectPlaceholder} />\n </SelectTrigger>\n <SelectContent>\n {dropdownOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n </div>\n\n {/* Content: Data Grid or Empty State */}\n {hasData ? (\n <div\n className={`grid grid-cols-1 sm:grid-cols-2 gap-[13px] ${gridColumnsClass}`}\n >\n {data.map((item, index) => (\n <StatCard\n key={`${item.variant}-${item.label}-${index}`}\n item={item}\n showPlaceholder={showPlaceholder}\n />\n ))}\n </div>\n ) : (\n <div className=\"border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2\">\n <Text\n size=\"sm\"\n color=\"text-text-600\"\n className=\"text-center max-w-md\"\n >\n {emptyStateMessage}\n </Text>\n\n {onEmptyStateButtonClick && (\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"small\"\n onClick={onEmptyStateButtonClick}\n iconLeft={<Plus size={16} weight=\"bold\" />}\n >\n {emptyStateButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\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\nexport { syncDropdownState } from './dropdown';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) 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.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\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","import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n","import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nconst VARIANT_CLASSES = {\n outlined: 'border-2 rounded-lg focus:border-primary-950',\n underlined: 'border-b-2 focus:border-primary-950',\n rounded: 'border-2 rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n className?: string;\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n className,\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className={cn('w-full', className)}>\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={cn('block font-bold text-text-900 mb-1.5', sizeClasses)}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={cn('relative w-full')} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n {(helperText || errorMessage) && (\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n )}\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit flex gap-2 items-center\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={cn(\n 'flex w-full items-center justify-between border-border-300',\n heightClasses,\n paddingClasses,\n invalid &&\n `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`,\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground',\n !invalid && !disabled ? 'text-text-700' : '',\n variantClasses,\n className\n )}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={cn(\n 'h-[1em] w-[1em] opacity-50 transition-transform',\n open ? 'rotate-180' : ''\n )}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={cn(\n 'bg-secondary z-50 min-w-[210px] max-h-[300px] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md border-border-100',\n getPositionClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n // Always set the clicked value, even if it's already selected\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n bg-secondary focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","SIZE_CLASSES","children","label","import_phosphor_react","import_jsx_runtime"]}
@@ -482,7 +482,7 @@ var VALUE_TEXT_COLORS = {
482
482
  low: "text-error-700",
483
483
  total: "text-info-700"
484
484
  };
485
- var StatCard = ({ item }) => {
485
+ var StatCard = ({ item, showPlaceholder = false }) => {
486
486
  return /* @__PURE__ */ jsxs3(
487
487
  "div",
488
488
  {
@@ -494,7 +494,7 @@ var StatCard = ({ item }) => {
494
494
  size: "4xl",
495
495
  weight: "bold",
496
496
  className: `${VALUE_TEXT_COLORS[item.variant]} leading-[42px] tracking-[0.2px] self-stretch`,
497
- children: item.value
497
+ children: showPlaceholder ? "-" : item.value
498
498
  }
499
499
  ),
500
500
  /* @__PURE__ */ jsx4(
@@ -510,9 +510,16 @@ var StatCard = ({ item }) => {
510
510
  }
511
511
  );
512
512
  };
513
+ var getGridColumnsClass = (itemCount) => {
514
+ if (itemCount === 4) return "lg:grid-cols-4";
515
+ if (itemCount === 3) return "lg:grid-cols-3";
516
+ if (itemCount === 2) return "lg:grid-cols-2";
517
+ return "lg:grid-cols-1";
518
+ };
513
519
  var StatisticsCard = ({
514
520
  title,
515
521
  data,
522
+ showPlaceholder = false,
516
523
  emptyStateMessage,
517
524
  emptyStateButtonText,
518
525
  onEmptyStateButtonClick,
@@ -524,6 +531,7 @@ var StatisticsCard = ({
524
531
  className = ""
525
532
  }) => {
526
533
  const hasData = data && data.length > 0;
534
+ const gridColumnsClass = hasData ? getGridColumnsClass(data.length) : "";
527
535
  return /* @__PURE__ */ jsxs3(
528
536
  "div",
529
537
  {
@@ -551,13 +559,20 @@ var StatisticsCard = ({
551
559
  }
552
560
  ) })
553
561
  ] }),
554
- hasData ? /* @__PURE__ */ jsx4("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-[13px]", children: data.map((item, index) => /* @__PURE__ */ jsx4(
555
- StatCard,
562
+ hasData ? /* @__PURE__ */ jsx4(
563
+ "div",
556
564
  {
557
- item
558
- },
559
- `${item.variant}-${item.label}-${index}`
560
- )) }) : /* @__PURE__ */ jsxs3("div", { className: "border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2", children: [
565
+ className: `grid grid-cols-1 sm:grid-cols-2 gap-[13px] ${gridColumnsClass}`,
566
+ children: data.map((item, index) => /* @__PURE__ */ jsx4(
567
+ StatCard,
568
+ {
569
+ item,
570
+ showPlaceholder
571
+ },
572
+ `${item.variant}-${item.label}-${index}`
573
+ ))
574
+ }
575
+ ) : /* @__PURE__ */ jsxs3("div", { className: "border border-dashed border-border-300 rounded-lg p-6 min-h-[105px] flex flex-col items-center justify-center gap-2", children: [
561
576
  /* @__PURE__ */ jsx4(
562
577
  Text_default,
563
578
  {