analytica-frontend-lib 1.0.40 → 1.0.42
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/ProgressBar/index.js +9 -12
- package/dist/ProgressBar/index.js.map +1 -1
- package/dist/ProgressBar/index.mjs +9 -12
- package/dist/ProgressBar/index.mjs.map +1 -1
- package/dist/ProgressCircle/index.js +11 -7
- package/dist/ProgressCircle/index.js.map +1 -1
- package/dist/ProgressCircle/index.mjs +11 -7
- package/dist/ProgressCircle/index.mjs.map +1 -1
- package/dist/Radio/index.js +8 -34
- package/dist/Radio/index.js.map +1 -1
- package/dist/Radio/index.mjs +8 -34
- package/dist/Radio/index.mjs.map +1 -1
- package/dist/index.css +53 -9
- package/dist/index.css.map +1 -1
- package/dist/index.js +28 -53
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +28 -53
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +53 -9
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
|
@@ -83,7 +83,6 @@ var SIZE_CLASSES = {
|
|
|
83
83
|
// 4px height (h-1 = 4px in Tailwind)
|
|
84
84
|
bar: "h-1",
|
|
85
85
|
// 4px height for the fill bar
|
|
86
|
-
labelSize: "xs",
|
|
87
86
|
spacing: "gap-2",
|
|
88
87
|
// 8px gap between label and progress bar
|
|
89
88
|
layout: "flex-col",
|
|
@@ -96,8 +95,6 @@ var SIZE_CLASSES = {
|
|
|
96
95
|
// 8px height (h-2 = 8px in Tailwind)
|
|
97
96
|
bar: "h-2",
|
|
98
97
|
// 8px height for the fill bar
|
|
99
|
-
labelSize: "xs",
|
|
100
|
-
// 12px font size (xs in Tailwind)
|
|
101
98
|
spacing: "gap-2",
|
|
102
99
|
// 8px gap between progress bar and label
|
|
103
100
|
layout: "flex-row items-center",
|
|
@@ -139,25 +136,25 @@ var ProgressBar = ({
|
|
|
139
136
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
140
137
|
"div",
|
|
141
138
|
{
|
|
142
|
-
className: `flex ${sizeClasses.layout} ${sizeClasses.spacing} ${className}`,
|
|
139
|
+
className: `flex ${sizeClasses.layout} ${size === "medium" ? "gap-2" : sizeClasses.spacing} ${className}`,
|
|
143
140
|
children: [
|
|
144
141
|
size === "small" && (label || showPercentage) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-row items-center justify-between w-full", children: [
|
|
145
142
|
label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
146
143
|
Text_default,
|
|
147
144
|
{
|
|
148
145
|
as: "div",
|
|
149
|
-
size:
|
|
146
|
+
size: "xs",
|
|
150
147
|
weight: "medium",
|
|
151
|
-
className: `text-text-950 ${labelClassName}`,
|
|
148
|
+
className: `text-text-950 leading-none tracking-normal text-center ${labelClassName}`,
|
|
152
149
|
children: label
|
|
153
150
|
}
|
|
154
151
|
),
|
|
155
152
|
showPercentage && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
156
153
|
Text_default,
|
|
157
154
|
{
|
|
158
|
-
size:
|
|
155
|
+
size: "xs",
|
|
159
156
|
weight: "medium",
|
|
160
|
-
className: `text-text-
|
|
157
|
+
className: `text-text-950 leading-none tracking-normal text-center ${percentageClassName}`,
|
|
161
158
|
children: [
|
|
162
159
|
Math.round(percentage),
|
|
163
160
|
"%"
|
|
@@ -192,9 +189,9 @@ var ProgressBar = ({
|
|
|
192
189
|
size === "medium" && showPercentage && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
193
190
|
Text_default,
|
|
194
191
|
{
|
|
195
|
-
size:
|
|
192
|
+
size: "xs",
|
|
196
193
|
weight: "medium",
|
|
197
|
-
className: `text-text-950 text-center flex-none
|
|
194
|
+
className: `text-text-950 leading-none tracking-normal text-center flex-none ${percentageClassName}`,
|
|
198
195
|
children: [
|
|
199
196
|
Math.round(percentage),
|
|
200
197
|
"%"
|
|
@@ -205,9 +202,9 @@ var ProgressBar = ({
|
|
|
205
202
|
Text_default,
|
|
206
203
|
{
|
|
207
204
|
as: "div",
|
|
208
|
-
size:
|
|
205
|
+
size: "xs",
|
|
209
206
|
weight: "medium",
|
|
210
|
-
className: `text-text-950 flex-none ${labelClassName}`,
|
|
207
|
+
className: `text-text-950 leading-none tracking-normal text-center flex-none ${labelClassName}`,
|
|
211
208
|
children: label
|
|
212
209
|
}
|
|
213
210
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ProgressBar/ProgressBar.tsx","../../src/components/Text/Text.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport Text from '../Text/Text';\n\n/**\n * Progress bar size variants\n */\ntype ProgressBarSize = 'small' | 'medium';\n\n/**\n * Progress bar color variants\n */\ntype ProgressBarVariant = 'blue' | 'green';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'h-1', // 4px height (h-1 = 4px in Tailwind)\n bar: 'h-1', // 4px height for the fill bar\n labelSize: 'xs' as const,\n spacing: 'gap-2', // 8px gap between label and progress bar\n layout: 'flex-col', // vertical layout for small\n borderRadius: 'rounded-full', // 9999px border radius\n },\n medium: {\n container: 'h-2', // 8px height (h-2 = 8px in Tailwind)\n bar: 'h-2', // 8px height for the fill bar\n labelSize: 'xs' as const, // 12px font size (xs in Tailwind)\n spacing: 'gap-2', // 8px gap between progress bar and label\n layout: 'flex-row items-center', // horizontal layout for medium\n borderRadius: 'rounded-lg', // 8px border radius\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-primary-700', // Blue for activity progress (#2271C4)\n },\n green: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-success-200', // Green for performance (#84D3A2)\n },\n} as const;\n\n/**\n * ProgressBar component props interface\n */\nexport type ProgressBarProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress bar */\n size?: ProgressBarSize;\n /** Color variant of the progress bar */\n variant?: ProgressBarVariant;\n /** Optional label to display */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n};\n\n/**\n * ProgressBar component for Analytica Ensino platforms\n *\n * A progress bar component with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\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 progress bar\n * <ProgressBar value={65} />\n *\n * // Activity progress (blue)\n * <ProgressBar variant=\"blue\" value={45} label=\"Progress\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressBar variant=\"green\" size=\"medium\" value={85} label=\"Performance\" />\n *\n * // Small size with custom max value\n * <ProgressBar size=\"small\" value={3} max={5} showPercentage />\n * ```\n */\nconst ProgressBar = ({\n value,\n max = 100,\n size = 'medium',\n variant = 'blue',\n label,\n showPercentage = false,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n}: ProgressBarProps) => {\n // Ensure value is within bounds and handle NaN/Infinity\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n // Get size and variant classes\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n return (\n <div\n className={`flex ${sizeClasses.layout} ${sizeClasses.spacing} ${className}`}\n >\n {/* For small size: vertical layout with label/percentage on top */}\n {size === 'small' && (label || showPercentage) && (\n <div className=\"flex flex-row items-center justify-between w-full\">\n {/* Label */}\n {label && (\n <Text\n as=\"div\"\n size={sizeClasses.labelSize}\n weight=\"medium\"\n className={`text-text-950 ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n\n {/* Percentage */}\n {showPercentage && (\n <Text\n size={sizeClasses.labelSize}\n weight=\"medium\"\n className={`text-text-700 text-center ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n </div>\n )}\n\n {/* Progress bar container */}\n <div\n className={`${size === 'medium' ? 'flex-grow' : 'w-full'} ${sizeClasses.container} ${variantClasses.background} ${sizeClasses.borderRadius} overflow-hidden relative`}\n >\n {/* Native progress element for accessibility */}\n <progress\n value={clampedValue}\n max={max}\n aria-label={typeof label === 'string' ? label : 'Progress'}\n className=\"absolute inset-0 w-full h-full opacity-0\"\n />\n\n {/* Progress bar fill */}\n <div\n className={`${sizeClasses.bar} ${variantClasses.fill} ${sizeClasses.borderRadius} transition-all duration-300 ease-out shadow-hard-shadow-3`}\n style={{ width: `${percentage}%` }}\n />\n </div>\n\n {/* For medium size: horizontal layout with percentage on the right */}\n {size === 'medium' && showPercentage && (\n <Text\n size={sizeClasses.labelSize}\n weight=\"medium\"\n className={`text-text-950 text-center flex-none w-[70px] ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {/* For medium size: label below if provided */}\n {size === 'medium' && label && !showPercentage && (\n <Text\n as=\"div\"\n size={sizeClasses.labelSize}\n weight=\"medium\"\n className={`text-text-950 flex-none ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n </div>\n );\n};\n\nexport default ProgressBar;\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\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={`${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":["import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/ProgressBar/ProgressBar.tsx","../../src/components/Text/Text.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport Text from '../Text/Text';\n\n/**\n * Progress bar size variants\n */\ntype ProgressBarSize = 'small' | 'medium';\n\n/**\n * Progress bar color variants\n */\ntype ProgressBarVariant = 'blue' | 'green';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'h-1', // 4px height (h-1 = 4px in Tailwind)\n bar: 'h-1', // 4px height for the fill bar\n spacing: 'gap-2', // 8px gap between label and progress bar\n layout: 'flex-col', // vertical layout for small\n borderRadius: 'rounded-full', // 9999px border radius\n },\n medium: {\n container: 'h-2', // 8px height (h-2 = 8px in Tailwind)\n bar: 'h-2', // 8px height for the fill bar\n spacing: 'gap-2', // 8px gap between progress bar and label\n layout: 'flex-row items-center', // horizontal layout for medium\n borderRadius: 'rounded-lg', // 8px border radius\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-primary-700', // Blue for activity progress (#2271C4)\n },\n green: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-success-200', // Green for performance (#84D3A2)\n },\n} as const;\n\n/**\n * ProgressBar component props interface\n */\nexport type ProgressBarProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress bar */\n size?: ProgressBarSize;\n /** Color variant of the progress bar */\n variant?: ProgressBarVariant;\n /** Optional label to display */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n};\n\n/**\n * ProgressBar component for Analytica Ensino platforms\n *\n * A progress bar component with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\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 progress bar\n * <ProgressBar value={65} />\n *\n * // Activity progress (blue)\n * <ProgressBar variant=\"blue\" value={45} label=\"Progress\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressBar variant=\"green\" size=\"medium\" value={85} label=\"Performance\" />\n *\n * // Small size with custom max value\n * <ProgressBar size=\"small\" value={3} max={5} showPercentage />\n * ```\n */\nconst ProgressBar = ({\n value,\n max = 100,\n size = 'medium',\n variant = 'blue',\n label,\n showPercentage = false,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n}: ProgressBarProps) => {\n // Ensure value is within bounds and handle NaN/Infinity\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n // Get size and variant classes\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n return (\n <div\n className={`flex ${sizeClasses.layout} ${size === 'medium' ? 'gap-2' : sizeClasses.spacing} ${className}`}\n >\n {/* For small size: vertical layout with label/percentage on top */}\n {size === 'small' && (label || showPercentage) && (\n <div className=\"flex flex-row items-center justify-between w-full\">\n {/* Label */}\n {label && (\n <Text\n as=\"div\"\n size=\"xs\"\n weight=\"medium\"\n className={`text-text-950 leading-none tracking-normal text-center ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n\n {/* Percentage */}\n {showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={`text-text-950 leading-none tracking-normal text-center ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n </div>\n )}\n\n {/* Progress bar container */}\n <div\n className={`${size === 'medium' ? 'flex-grow' : 'w-full'} ${sizeClasses.container} ${variantClasses.background} ${sizeClasses.borderRadius} overflow-hidden relative`}\n >\n {/* Native progress element for accessibility */}\n <progress\n value={clampedValue}\n max={max}\n aria-label={typeof label === 'string' ? label : 'Progress'}\n className=\"absolute inset-0 w-full h-full opacity-0\"\n />\n\n {/* Progress bar fill */}\n <div\n className={`${sizeClasses.bar} ${variantClasses.fill} ${sizeClasses.borderRadius} transition-all duration-300 ease-out shadow-hard-shadow-3`}\n style={{ width: `${percentage}%` }}\n />\n </div>\n\n {/* For medium size: horizontal layout with percentage on the right */}\n {size === 'medium' && showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={`text-text-950 leading-none tracking-normal text-center flex-none ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {/* For medium size: label below if provided */}\n {size === 'medium' && label && !showPercentage && (\n <Text\n as=\"div\"\n size=\"xs\"\n weight=\"medium\"\n className={`text-text-950 leading-none tracking-normal text-center flex-none ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n </div>\n );\n};\n\nexport default ProgressBar;\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\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={`${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":["import_jsx_runtime"]}
|
|
@@ -57,7 +57,6 @@ var SIZE_CLASSES = {
|
|
|
57
57
|
// 4px height (h-1 = 4px in Tailwind)
|
|
58
58
|
bar: "h-1",
|
|
59
59
|
// 4px height for the fill bar
|
|
60
|
-
labelSize: "xs",
|
|
61
60
|
spacing: "gap-2",
|
|
62
61
|
// 8px gap between label and progress bar
|
|
63
62
|
layout: "flex-col",
|
|
@@ -70,8 +69,6 @@ var SIZE_CLASSES = {
|
|
|
70
69
|
// 8px height (h-2 = 8px in Tailwind)
|
|
71
70
|
bar: "h-2",
|
|
72
71
|
// 8px height for the fill bar
|
|
73
|
-
labelSize: "xs",
|
|
74
|
-
// 12px font size (xs in Tailwind)
|
|
75
72
|
spacing: "gap-2",
|
|
76
73
|
// 8px gap between progress bar and label
|
|
77
74
|
layout: "flex-row items-center",
|
|
@@ -113,25 +110,25 @@ var ProgressBar = ({
|
|
|
113
110
|
return /* @__PURE__ */ jsxs(
|
|
114
111
|
"div",
|
|
115
112
|
{
|
|
116
|
-
className: `flex ${sizeClasses.layout} ${sizeClasses.spacing} ${className}`,
|
|
113
|
+
className: `flex ${sizeClasses.layout} ${size === "medium" ? "gap-2" : sizeClasses.spacing} ${className}`,
|
|
117
114
|
children: [
|
|
118
115
|
size === "small" && (label || showPercentage) && /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-between w-full", children: [
|
|
119
116
|
label && /* @__PURE__ */ jsx2(
|
|
120
117
|
Text_default,
|
|
121
118
|
{
|
|
122
119
|
as: "div",
|
|
123
|
-
size:
|
|
120
|
+
size: "xs",
|
|
124
121
|
weight: "medium",
|
|
125
|
-
className: `text-text-950 ${labelClassName}`,
|
|
122
|
+
className: `text-text-950 leading-none tracking-normal text-center ${labelClassName}`,
|
|
126
123
|
children: label
|
|
127
124
|
}
|
|
128
125
|
),
|
|
129
126
|
showPercentage && /* @__PURE__ */ jsxs(
|
|
130
127
|
Text_default,
|
|
131
128
|
{
|
|
132
|
-
size:
|
|
129
|
+
size: "xs",
|
|
133
130
|
weight: "medium",
|
|
134
|
-
className: `text-text-
|
|
131
|
+
className: `text-text-950 leading-none tracking-normal text-center ${percentageClassName}`,
|
|
135
132
|
children: [
|
|
136
133
|
Math.round(percentage),
|
|
137
134
|
"%"
|
|
@@ -166,9 +163,9 @@ var ProgressBar = ({
|
|
|
166
163
|
size === "medium" && showPercentage && /* @__PURE__ */ jsxs(
|
|
167
164
|
Text_default,
|
|
168
165
|
{
|
|
169
|
-
size:
|
|
166
|
+
size: "xs",
|
|
170
167
|
weight: "medium",
|
|
171
|
-
className: `text-text-950 text-center flex-none
|
|
168
|
+
className: `text-text-950 leading-none tracking-normal text-center flex-none ${percentageClassName}`,
|
|
172
169
|
children: [
|
|
173
170
|
Math.round(percentage),
|
|
174
171
|
"%"
|
|
@@ -179,9 +176,9 @@ var ProgressBar = ({
|
|
|
179
176
|
Text_default,
|
|
180
177
|
{
|
|
181
178
|
as: "div",
|
|
182
|
-
size:
|
|
179
|
+
size: "xs",
|
|
183
180
|
weight: "medium",
|
|
184
|
-
className: `text-text-950 flex-none ${labelClassName}`,
|
|
181
|
+
className: `text-text-950 leading-none tracking-normal text-center flex-none ${labelClassName}`,
|
|
185
182
|
children: label
|
|
186
183
|
}
|
|
187
184
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Text/Text.tsx","../../src/components/ProgressBar/ProgressBar.tsx"],"sourcesContent":["import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\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={`${baseClasses} ${sizeClasses} ${weightClasses} ${color} ${className}`}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ReactNode } from 'react';\nimport Text from '../Text/Text';\n\n/**\n * Progress bar size variants\n */\ntype ProgressBarSize = 'small' | 'medium';\n\n/**\n * Progress bar color variants\n */\ntype ProgressBarVariant = 'blue' | 'green';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'h-1', // 4px height (h-1 = 4px in Tailwind)\n bar: 'h-1', // 4px height for the fill bar\n labelSize: 'xs' as const,\n spacing: 'gap-2', // 8px gap between label and progress bar\n layout: 'flex-col', // vertical layout for small\n borderRadius: 'rounded-full', // 9999px border radius\n },\n medium: {\n container: 'h-2', // 8px height (h-2 = 8px in Tailwind)\n bar: 'h-2', // 8px height for the fill bar\n labelSize: 'xs' as const, // 12px font size (xs in Tailwind)\n spacing: 'gap-2', // 8px gap between progress bar and label\n layout: 'flex-row items-center', // horizontal layout for medium\n borderRadius: 'rounded-lg', // 8px border radius\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-primary-700', // Blue for activity progress (#2271C4)\n },\n green: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-success-200', // Green for performance (#84D3A2)\n },\n} as const;\n\n/**\n * ProgressBar component props interface\n */\nexport type ProgressBarProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress bar */\n size?: ProgressBarSize;\n /** Color variant of the progress bar */\n variant?: ProgressBarVariant;\n /** Optional label to display */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n};\n\n/**\n * ProgressBar component for Analytica Ensino platforms\n *\n * A progress bar component with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\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 progress bar\n * <ProgressBar value={65} />\n *\n * // Activity progress (blue)\n * <ProgressBar variant=\"blue\" value={45} label=\"Progress\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressBar variant=\"green\" size=\"medium\" value={85} label=\"Performance\" />\n *\n * // Small size with custom max value\n * <ProgressBar size=\"small\" value={3} max={5} showPercentage />\n * ```\n */\nconst ProgressBar = ({\n value,\n max = 100,\n size = 'medium',\n variant = 'blue',\n label,\n showPercentage = false,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n}: ProgressBarProps) => {\n // Ensure value is within bounds and handle NaN/Infinity\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n // Get size and variant classes\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n return (\n <div\n className={`flex ${sizeClasses.layout} ${sizeClasses.spacing} ${className}`}\n >\n {/* For small size: vertical layout with label/percentage on top */}\n {size === 'small' && (label || showPercentage) && (\n <div className=\"flex flex-row items-center justify-between w-full\">\n {/* Label */}\n {label && (\n <Text\n as=\"div\"\n size={sizeClasses.labelSize}\n weight=\"medium\"\n className={`text-text-950 ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n\n {/* Percentage */}\n {showPercentage && (\n <Text\n size={sizeClasses.labelSize}\n weight=\"medium\"\n className={`text-text-700 text-center ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n </div>\n )}\n\n {/* Progress bar container */}\n <div\n className={`${size === 'medium' ? 'flex-grow' : 'w-full'} ${sizeClasses.container} ${variantClasses.background} ${sizeClasses.borderRadius} overflow-hidden relative`}\n >\n {/* Native progress element for accessibility */}\n <progress\n value={clampedValue}\n max={max}\n aria-label={typeof label === 'string' ? label : 'Progress'}\n className=\"absolute inset-0 w-full h-full opacity-0\"\n />\n\n {/* Progress bar fill */}\n <div\n className={`${sizeClasses.bar} ${variantClasses.fill} ${sizeClasses.borderRadius} transition-all duration-300 ease-out shadow-hard-shadow-3`}\n style={{ width: `${percentage}%` }}\n />\n </div>\n\n {/* For medium size: horizontal layout with percentage on the right */}\n {size === 'medium' && showPercentage && (\n <Text\n size={sizeClasses.labelSize}\n weight=\"medium\"\n className={`text-text-950 text-center flex-none w-[70px] ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {/* For medium size: label below if provided */}\n {size === 'medium' && label && !showPercentage && (\n <Text\n as=\"div\"\n size={sizeClasses.labelSize}\n weight=\"medium\"\n className={`text-text-950 flex-none ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n </div>\n );\n};\n\nexport default ProgressBar;\n"],"mappings":"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","names":["jsx"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/Text/Text.tsx","../../src/components/ProgressBar/ProgressBar.tsx"],"sourcesContent":["import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\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={`${baseClasses} ${sizeClasses} ${weightClasses} ${color} ${className}`}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ReactNode } from 'react';\nimport Text from '../Text/Text';\n\n/**\n * Progress bar size variants\n */\ntype ProgressBarSize = 'small' | 'medium';\n\n/**\n * Progress bar color variants\n */\ntype ProgressBarVariant = 'blue' | 'green';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'h-1', // 4px height (h-1 = 4px in Tailwind)\n bar: 'h-1', // 4px height for the fill bar\n spacing: 'gap-2', // 8px gap between label and progress bar\n layout: 'flex-col', // vertical layout for small\n borderRadius: 'rounded-full', // 9999px border radius\n },\n medium: {\n container: 'h-2', // 8px height (h-2 = 8px in Tailwind)\n bar: 'h-2', // 8px height for the fill bar\n spacing: 'gap-2', // 8px gap between progress bar and label\n layout: 'flex-row items-center', // horizontal layout for medium\n borderRadius: 'rounded-lg', // 8px border radius\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-primary-700', // Blue for activity progress (#2271C4)\n },\n green: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-success-200', // Green for performance (#84D3A2)\n },\n} as const;\n\n/**\n * ProgressBar component props interface\n */\nexport type ProgressBarProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress bar */\n size?: ProgressBarSize;\n /** Color variant of the progress bar */\n variant?: ProgressBarVariant;\n /** Optional label to display */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n};\n\n/**\n * ProgressBar component for Analytica Ensino platforms\n *\n * A progress bar component with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\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 progress bar\n * <ProgressBar value={65} />\n *\n * // Activity progress (blue)\n * <ProgressBar variant=\"blue\" value={45} label=\"Progress\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressBar variant=\"green\" size=\"medium\" value={85} label=\"Performance\" />\n *\n * // Small size with custom max value\n * <ProgressBar size=\"small\" value={3} max={5} showPercentage />\n * ```\n */\nconst ProgressBar = ({\n value,\n max = 100,\n size = 'medium',\n variant = 'blue',\n label,\n showPercentage = false,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n}: ProgressBarProps) => {\n // Ensure value is within bounds and handle NaN/Infinity\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n // Get size and variant classes\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n return (\n <div\n className={`flex ${sizeClasses.layout} ${size === 'medium' ? 'gap-2' : sizeClasses.spacing} ${className}`}\n >\n {/* For small size: vertical layout with label/percentage on top */}\n {size === 'small' && (label || showPercentage) && (\n <div className=\"flex flex-row items-center justify-between w-full\">\n {/* Label */}\n {label && (\n <Text\n as=\"div\"\n size=\"xs\"\n weight=\"medium\"\n className={`text-text-950 leading-none tracking-normal text-center ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n\n {/* Percentage */}\n {showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={`text-text-950 leading-none tracking-normal text-center ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n </div>\n )}\n\n {/* Progress bar container */}\n <div\n className={`${size === 'medium' ? 'flex-grow' : 'w-full'} ${sizeClasses.container} ${variantClasses.background} ${sizeClasses.borderRadius} overflow-hidden relative`}\n >\n {/* Native progress element for accessibility */}\n <progress\n value={clampedValue}\n max={max}\n aria-label={typeof label === 'string' ? label : 'Progress'}\n className=\"absolute inset-0 w-full h-full opacity-0\"\n />\n\n {/* Progress bar fill */}\n <div\n className={`${sizeClasses.bar} ${variantClasses.fill} ${sizeClasses.borderRadius} transition-all duration-300 ease-out shadow-hard-shadow-3`}\n style={{ width: `${percentage}%` }}\n />\n </div>\n\n {/* For medium size: horizontal layout with percentage on the right */}\n {size === 'medium' && showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={`text-text-950 leading-none tracking-normal text-center flex-none ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {/* For medium size: label below if provided */}\n {size === 'medium' && label && !showPercentage && (\n <Text\n as=\"div\"\n size=\"xs\"\n weight=\"medium\"\n className={`text-text-950 leading-none tracking-normal text-center flex-none ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n </div>\n );\n};\n\nexport default ProgressBar;\n"],"mappings":"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","names":["jsx"]}
|
|
@@ -88,11 +88,13 @@ var SIZE_CLASSES = {
|
|
|
88
88
|
textWeight: "medium",
|
|
89
89
|
// font-weight: 500
|
|
90
90
|
labelSize: "2xs",
|
|
91
|
-
//
|
|
91
|
+
// Will be overridden with custom 8px in className
|
|
92
92
|
labelWeight: "bold",
|
|
93
93
|
// font-weight: 700
|
|
94
|
-
spacing: "gap-
|
|
95
|
-
//
|
|
94
|
+
spacing: "gap-0",
|
|
95
|
+
// Reduced gap between percentage and label for better spacing
|
|
96
|
+
contentWidth: "max-w-[50px]"
|
|
97
|
+
// Reduced width to fit text inside circle
|
|
96
98
|
},
|
|
97
99
|
medium: {
|
|
98
100
|
container: "w-[152px] h-[152px]",
|
|
@@ -107,8 +109,10 @@ var SIZE_CLASSES = {
|
|
|
107
109
|
// 12px for status label (font-size: 12px)
|
|
108
110
|
labelWeight: "medium",
|
|
109
111
|
// font-weight: 500 (changed from bold)
|
|
110
|
-
spacing: "gap-1"
|
|
112
|
+
spacing: "gap-1",
|
|
111
113
|
// 4px gap between percentage and label
|
|
114
|
+
contentWidth: "max-w-[90px]"
|
|
115
|
+
// Reduced width to fit text inside circle
|
|
112
116
|
}
|
|
113
117
|
};
|
|
114
118
|
var VARIANT_CLASSES = {
|
|
@@ -208,14 +212,14 @@ var ProgressCircle = ({
|
|
|
208
212
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
209
213
|
"div",
|
|
210
214
|
{
|
|
211
|
-
className: `relative z-10 flex flex-col items-center justify-center ${sizeClasses.spacing}`,
|
|
215
|
+
className: `relative z-10 flex flex-col items-center justify-center ${sizeClasses.spacing} ${sizeClasses.contentWidth}`,
|
|
212
216
|
children: [
|
|
213
217
|
showPercentage && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
214
218
|
Text_default,
|
|
215
219
|
{
|
|
216
220
|
size: sizeClasses.textSize,
|
|
217
221
|
weight: sizeClasses.textWeight,
|
|
218
|
-
className: `text-center ${variantClasses.textColor} ${percentageClassName}`,
|
|
222
|
+
className: `text-center w-full ${variantClasses.textColor} ${percentageClassName}`,
|
|
219
223
|
children: [
|
|
220
224
|
Math.round(percentage),
|
|
221
225
|
"%"
|
|
@@ -228,7 +232,7 @@ var ProgressCircle = ({
|
|
|
228
232
|
as: "span",
|
|
229
233
|
size: sizeClasses.labelSize,
|
|
230
234
|
weight: sizeClasses.labelWeight,
|
|
231
|
-
className: `${variantClasses.labelColor} text-center uppercase tracking-wide ${labelClassName}`,
|
|
235
|
+
className: `${variantClasses.labelColor} text-center uppercase tracking-wide truncate w-full ${size === "small" ? "text-[8px] leading-[9px]" : ""} ${labelClassName}`,
|
|
232
236
|
children: label
|
|
233
237
|
}
|
|
234
238
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ProgressCircle/ProgressCircle.tsx","../../src/components/Text/Text.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport Text from '../Text/Text';\n\n/**\n * Progress circle size variants\n */\ntype ProgressCircleSize = 'small' | 'medium';\n\n/**\n * Progress circle color variants\n */\ntype ProgressCircleVariant = 'blue' | 'green';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'w-[90px] h-[90px]', // 90px circle from design specs\n strokeWidth: 4, // 4px stroke width - matches ProgressBar small (h-1)\n textSize: '2xl', // 24px for percentage (font-size: 24px)\n textWeight: 'medium', // font-weight: 500\n labelSize: '2xs' as const, // 10px for status label (closest to 8px design spec)\n labelWeight: 'bold', // font-weight: 700\n spacing: 'gap-1', // 4px gap between percentage and label\n },\n medium: {\n container: 'w-[152px] h-[152px]', // 151.67px ≈ 152px circle from design specs\n strokeWidth: 8, // 8px stroke width - matches ProgressBar medium (h-2)\n textSize: '2xl', // 24px for percentage (font-size: 24px)\n textWeight: 'medium', // font-weight: 500\n labelSize: 'xs' as const, // 12px for status label (font-size: 12px)\n labelWeight: 'medium', // font-weight: 500 (changed from bold)\n spacing: 'gap-1', // 4px gap between percentage and label\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'stroke-primary-100', // Light blue background (#BBDCF7)\n fill: 'stroke-primary-700', // Blue for activity progress (#2271C4)\n textColor: 'text-primary-700', // Blue text color (#2271C4)\n labelColor: 'text-text-700', // Gray text for label (#525252)\n },\n green: {\n background: 'stroke-background-300', // Gray background (#D5D4D4 - matches design)\n fill: 'stroke-success-200', // Green for performance (#84D3A2 - matches design)\n textColor: 'text-text-800', // Dark gray text (#404040 - matches design)\n labelColor: 'text-text-600', // Medium gray text for label (#737373 - matches design)\n },\n} as const;\n\n/**\n * ProgressCircle component props interface\n */\nexport type ProgressCircleProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress circle */\n size?: ProgressCircleSize;\n /** Color variant of the progress circle */\n variant?: ProgressCircleVariant;\n /** Optional label to display below percentage */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n};\n\n/**\n * ProgressCircle component for Analytica Ensino platforms\n *\n * A circular progress indicator with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\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 progress circle\n * <ProgressCircle value={65} />\n *\n * // Activity progress (blue)\n * <ProgressCircle variant=\"blue\" value={45} label=\"CONCLUÍDO\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressCircle variant=\"green\" size=\"medium\" value={85} label=\"MÉDIA\" />\n *\n * // Small size with custom max value\n * <ProgressCircle size=\"small\" value={3} max={5} showPercentage />\n * ```\n */\nconst ProgressCircle = ({\n value,\n max = 100,\n size = 'small',\n variant = 'blue',\n label,\n showPercentage = true,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n}: ProgressCircleProps) => {\n // Ensure value is within bounds and handle NaN/Infinity\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n // Get size and variant classes\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n // Calculate SVG dimensions and stroke properties\n const radius = size === 'small' ? 37 : 64; // Radius calculation based on container size\n const circumference = 2 * Math.PI * radius;\n const strokeDashoffset = circumference - (percentage / 100) * circumference;\n const center = size === 'small' ? 45 : 76; // Center point of SVG\n const svgSize = size === 'small' ? 90 : 152; // SVG viewBox size\n\n return (\n <div\n className={`relative flex flex-col items-center justify-center ${sizeClasses.container} rounded-lg ${className}`}\n >\n {/* Progress circle SVG */}\n <svg\n className=\"absolute inset-0 transform -rotate-90\"\n width={svgSize}\n height={svgSize}\n viewBox={`0 0 ${svgSize} ${svgSize}`}\n aria-hidden=\"true\"\n >\n {/* Background circle */}\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={sizeClasses.strokeWidth}\n className={`${variantClasses.background} rounded-lg`}\n />\n {/* Progress circle - SVG stroke properties require style for animation */}\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={sizeClasses.strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={strokeDashoffset}\n className={`${variantClasses.fill} transition-all duration-500 ease-out shadow-soft-shadow-3 rounded-lg`}\n />\n </svg>\n\n {/* Native progress element for accessibility */}\n <progress\n value={clampedValue}\n max={max}\n aria-label={typeof label === 'string' ? label : 'Progress'}\n className=\"absolute opacity-0 w-0 h-0\"\n />\n\n {/* Content overlay - centered content */}\n <div\n className={`relative z-10 flex flex-col items-center justify-center ${sizeClasses.spacing}`}\n >\n {/* Percentage text */}\n {showPercentage && (\n <Text\n size={sizeClasses.textSize}\n weight={sizeClasses.textWeight}\n className={`text-center ${variantClasses.textColor} ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {/* Label text */}\n {label && (\n <Text\n as=\"span\"\n size={sizeClasses.labelSize}\n weight={sizeClasses.labelWeight}\n className={`${variantClasses.labelColor} text-center uppercase tracking-wide ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n </div>\n </div>\n );\n};\n\nexport default ProgressCircle;\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\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={`${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":["import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/ProgressCircle/ProgressCircle.tsx","../../src/components/Text/Text.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport Text from '../Text/Text';\n\n/**\n * Progress circle size variants\n */\ntype ProgressCircleSize = 'small' | 'medium';\n\n/**\n * Progress circle color variants\n */\ntype ProgressCircleVariant = 'blue' | 'green';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'w-[90px] h-[90px]', // 90px circle from design specs\n strokeWidth: 4, // 4px stroke width - matches ProgressBar small (h-1)\n textSize: '2xl', // 24px for percentage (font-size: 24px)\n textWeight: 'medium', // font-weight: 500\n labelSize: '2xs' as const, // Will be overridden with custom 8px in className\n labelWeight: 'bold', // font-weight: 700\n spacing: 'gap-0', // Reduced gap between percentage and label for better spacing\n contentWidth: 'max-w-[50px]', // Reduced width to fit text inside circle\n },\n medium: {\n container: 'w-[152px] h-[152px]', // 151.67px ≈ 152px circle from design specs\n strokeWidth: 8, // 8px stroke width - matches ProgressBar medium (h-2)\n textSize: '2xl', // 24px for percentage (font-size: 24px)\n textWeight: 'medium', // font-weight: 500\n labelSize: 'xs' as const, // 12px for status label (font-size: 12px)\n labelWeight: 'medium', // font-weight: 500 (changed from bold)\n spacing: 'gap-1', // 4px gap between percentage and label\n contentWidth: 'max-w-[90px]', // Reduced width to fit text inside circle\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'stroke-primary-100', // Light blue background (#BBDCF7)\n fill: 'stroke-primary-700', // Blue for activity progress (#2271C4)\n textColor: 'text-primary-700', // Blue text color (#2271C4)\n labelColor: 'text-text-700', // Gray text for label (#525252)\n },\n green: {\n background: 'stroke-background-300', // Gray background (#D5D4D4 - matches design)\n fill: 'stroke-success-200', // Green for performance (#84D3A2 - matches design)\n textColor: 'text-text-800', // Dark gray text (#404040 - matches design)\n labelColor: 'text-text-600', // Medium gray text for label (#737373 - matches design)\n },\n} as const;\n\n/**\n * ProgressCircle component props interface\n */\nexport type ProgressCircleProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress circle */\n size?: ProgressCircleSize;\n /** Color variant of the progress circle */\n variant?: ProgressCircleVariant;\n /** Optional label to display below percentage */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n};\n\n/**\n * ProgressCircle component for Analytica Ensino platforms\n *\n * A circular progress indicator with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\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 progress circle\n * <ProgressCircle value={65} />\n *\n * // Activity progress (blue)\n * <ProgressCircle variant=\"blue\" value={45} label=\"CONCLUÍDO\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressCircle variant=\"green\" size=\"medium\" value={85} label=\"MÉDIA\" />\n *\n * // Small size with custom max value\n * <ProgressCircle size=\"small\" value={3} max={5} showPercentage />\n * ```\n */\nconst ProgressCircle = ({\n value,\n max = 100,\n size = 'small',\n variant = 'blue',\n label,\n showPercentage = true,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n}: ProgressCircleProps) => {\n // Ensure value is within bounds and handle NaN/Infinity\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n // Get size and variant classes\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n // Calculate SVG dimensions and stroke properties\n const radius = size === 'small' ? 37 : 64; // Radius calculation based on container size\n const circumference = 2 * Math.PI * radius;\n const strokeDashoffset = circumference - (percentage / 100) * circumference;\n const center = size === 'small' ? 45 : 76; // Center point of SVG\n const svgSize = size === 'small' ? 90 : 152; // SVG viewBox size\n\n return (\n <div\n className={`relative flex flex-col items-center justify-center ${sizeClasses.container} rounded-lg ${className}`}\n >\n {/* Progress circle SVG */}\n <svg\n className=\"absolute inset-0 transform -rotate-90\"\n width={svgSize}\n height={svgSize}\n viewBox={`0 0 ${svgSize} ${svgSize}`}\n aria-hidden=\"true\"\n >\n {/* Background circle */}\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={sizeClasses.strokeWidth}\n className={`${variantClasses.background} rounded-lg`}\n />\n {/* Progress circle - SVG stroke properties require style for animation */}\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={sizeClasses.strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={strokeDashoffset}\n className={`${variantClasses.fill} transition-all duration-500 ease-out shadow-soft-shadow-3 rounded-lg`}\n />\n </svg>\n\n {/* Native progress element for accessibility */}\n <progress\n value={clampedValue}\n max={max}\n aria-label={typeof label === 'string' ? label : 'Progress'}\n className=\"absolute opacity-0 w-0 h-0\"\n />\n\n {/* Content overlay - centered content */}\n <div\n className={`relative z-10 flex flex-col items-center justify-center ${sizeClasses.spacing} ${sizeClasses.contentWidth}`}\n >\n {/* Percentage text */}\n {showPercentage && (\n <Text\n size={sizeClasses.textSize}\n weight={sizeClasses.textWeight}\n className={`text-center w-full ${variantClasses.textColor} ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {/* Label text */}\n {label && (\n <Text\n as=\"span\"\n size={sizeClasses.labelSize}\n weight={sizeClasses.labelWeight}\n className={`${variantClasses.labelColor} text-center uppercase tracking-wide truncate w-full ${size === 'small' ? 'text-[8px] leading-[9px]' : ''} ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n </div>\n </div>\n );\n};\n\nexport default ProgressCircle;\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\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={`${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":["import_jsx_runtime"]}
|
|
@@ -62,11 +62,13 @@ var SIZE_CLASSES = {
|
|
|
62
62
|
textWeight: "medium",
|
|
63
63
|
// font-weight: 500
|
|
64
64
|
labelSize: "2xs",
|
|
65
|
-
//
|
|
65
|
+
// Will be overridden with custom 8px in className
|
|
66
66
|
labelWeight: "bold",
|
|
67
67
|
// font-weight: 700
|
|
68
|
-
spacing: "gap-
|
|
69
|
-
//
|
|
68
|
+
spacing: "gap-0",
|
|
69
|
+
// Reduced gap between percentage and label for better spacing
|
|
70
|
+
contentWidth: "max-w-[50px]"
|
|
71
|
+
// Reduced width to fit text inside circle
|
|
70
72
|
},
|
|
71
73
|
medium: {
|
|
72
74
|
container: "w-[152px] h-[152px]",
|
|
@@ -81,8 +83,10 @@ var SIZE_CLASSES = {
|
|
|
81
83
|
// 12px for status label (font-size: 12px)
|
|
82
84
|
labelWeight: "medium",
|
|
83
85
|
// font-weight: 500 (changed from bold)
|
|
84
|
-
spacing: "gap-1"
|
|
86
|
+
spacing: "gap-1",
|
|
85
87
|
// 4px gap between percentage and label
|
|
88
|
+
contentWidth: "max-w-[90px]"
|
|
89
|
+
// Reduced width to fit text inside circle
|
|
86
90
|
}
|
|
87
91
|
};
|
|
88
92
|
var VARIANT_CLASSES = {
|
|
@@ -182,14 +186,14 @@ var ProgressCircle = ({
|
|
|
182
186
|
/* @__PURE__ */ jsxs(
|
|
183
187
|
"div",
|
|
184
188
|
{
|
|
185
|
-
className: `relative z-10 flex flex-col items-center justify-center ${sizeClasses.spacing}`,
|
|
189
|
+
className: `relative z-10 flex flex-col items-center justify-center ${sizeClasses.spacing} ${sizeClasses.contentWidth}`,
|
|
186
190
|
children: [
|
|
187
191
|
showPercentage && /* @__PURE__ */ jsxs(
|
|
188
192
|
Text_default,
|
|
189
193
|
{
|
|
190
194
|
size: sizeClasses.textSize,
|
|
191
195
|
weight: sizeClasses.textWeight,
|
|
192
|
-
className: `text-center ${variantClasses.textColor} ${percentageClassName}`,
|
|
196
|
+
className: `text-center w-full ${variantClasses.textColor} ${percentageClassName}`,
|
|
193
197
|
children: [
|
|
194
198
|
Math.round(percentage),
|
|
195
199
|
"%"
|
|
@@ -202,7 +206,7 @@ var ProgressCircle = ({
|
|
|
202
206
|
as: "span",
|
|
203
207
|
size: sizeClasses.labelSize,
|
|
204
208
|
weight: sizeClasses.labelWeight,
|
|
205
|
-
className: `${variantClasses.labelColor} text-center uppercase tracking-wide ${labelClassName}`,
|
|
209
|
+
className: `${variantClasses.labelColor} text-center uppercase tracking-wide truncate w-full ${size === "small" ? "text-[8px] leading-[9px]" : ""} ${labelClassName}`,
|
|
206
210
|
children: label
|
|
207
211
|
}
|
|
208
212
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Text/Text.tsx","../../src/components/ProgressCircle/ProgressCircle.tsx"],"sourcesContent":["import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\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={`${baseClasses} ${sizeClasses} ${weightClasses} ${color} ${className}`}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ReactNode } from 'react';\nimport Text from '../Text/Text';\n\n/**\n * Progress circle size variants\n */\ntype ProgressCircleSize = 'small' | 'medium';\n\n/**\n * Progress circle color variants\n */\ntype ProgressCircleVariant = 'blue' | 'green';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'w-[90px] h-[90px]', // 90px circle from design specs\n strokeWidth: 4, // 4px stroke width - matches ProgressBar small (h-1)\n textSize: '2xl', // 24px for percentage (font-size: 24px)\n textWeight: 'medium', // font-weight: 500\n labelSize: '2xs' as const, // 10px for status label (closest to 8px design spec)\n labelWeight: 'bold', // font-weight: 700\n spacing: 'gap-1', // 4px gap between percentage and label\n },\n medium: {\n container: 'w-[152px] h-[152px]', // 151.67px ≈ 152px circle from design specs\n strokeWidth: 8, // 8px stroke width - matches ProgressBar medium (h-2)\n textSize: '2xl', // 24px for percentage (font-size: 24px)\n textWeight: 'medium', // font-weight: 500\n labelSize: 'xs' as const, // 12px for status label (font-size: 12px)\n labelWeight: 'medium', // font-weight: 500 (changed from bold)\n spacing: 'gap-1', // 4px gap between percentage and label\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'stroke-primary-100', // Light blue background (#BBDCF7)\n fill: 'stroke-primary-700', // Blue for activity progress (#2271C4)\n textColor: 'text-primary-700', // Blue text color (#2271C4)\n labelColor: 'text-text-700', // Gray text for label (#525252)\n },\n green: {\n background: 'stroke-background-300', // Gray background (#D5D4D4 - matches design)\n fill: 'stroke-success-200', // Green for performance (#84D3A2 - matches design)\n textColor: 'text-text-800', // Dark gray text (#404040 - matches design)\n labelColor: 'text-text-600', // Medium gray text for label (#737373 - matches design)\n },\n} as const;\n\n/**\n * ProgressCircle component props interface\n */\nexport type ProgressCircleProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress circle */\n size?: ProgressCircleSize;\n /** Color variant of the progress circle */\n variant?: ProgressCircleVariant;\n /** Optional label to display below percentage */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n};\n\n/**\n * ProgressCircle component for Analytica Ensino platforms\n *\n * A circular progress indicator with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\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 progress circle\n * <ProgressCircle value={65} />\n *\n * // Activity progress (blue)\n * <ProgressCircle variant=\"blue\" value={45} label=\"CONCLUÍDO\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressCircle variant=\"green\" size=\"medium\" value={85} label=\"MÉDIA\" />\n *\n * // Small size with custom max value\n * <ProgressCircle size=\"small\" value={3} max={5} showPercentage />\n * ```\n */\nconst ProgressCircle = ({\n value,\n max = 100,\n size = 'small',\n variant = 'blue',\n label,\n showPercentage = true,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n}: ProgressCircleProps) => {\n // Ensure value is within bounds and handle NaN/Infinity\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n // Get size and variant classes\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n // Calculate SVG dimensions and stroke properties\n const radius = size === 'small' ? 37 : 64; // Radius calculation based on container size\n const circumference = 2 * Math.PI * radius;\n const strokeDashoffset = circumference - (percentage / 100) * circumference;\n const center = size === 'small' ? 45 : 76; // Center point of SVG\n const svgSize = size === 'small' ? 90 : 152; // SVG viewBox size\n\n return (\n <div\n className={`relative flex flex-col items-center justify-center ${sizeClasses.container} rounded-lg ${className}`}\n >\n {/* Progress circle SVG */}\n <svg\n className=\"absolute inset-0 transform -rotate-90\"\n width={svgSize}\n height={svgSize}\n viewBox={`0 0 ${svgSize} ${svgSize}`}\n aria-hidden=\"true\"\n >\n {/* Background circle */}\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={sizeClasses.strokeWidth}\n className={`${variantClasses.background} rounded-lg`}\n />\n {/* Progress circle - SVG stroke properties require style for animation */}\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={sizeClasses.strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={strokeDashoffset}\n className={`${variantClasses.fill} transition-all duration-500 ease-out shadow-soft-shadow-3 rounded-lg`}\n />\n </svg>\n\n {/* Native progress element for accessibility */}\n <progress\n value={clampedValue}\n max={max}\n aria-label={typeof label === 'string' ? label : 'Progress'}\n className=\"absolute opacity-0 w-0 h-0\"\n />\n\n {/* Content overlay - centered content */}\n <div\n className={`relative z-10 flex flex-col items-center justify-center ${sizeClasses.spacing}`}\n >\n {/* Percentage text */}\n {showPercentage && (\n <Text\n size={sizeClasses.textSize}\n weight={sizeClasses.textWeight}\n className={`text-center ${variantClasses.textColor} ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {/* Label text */}\n {label && (\n <Text\n as=\"span\"\n size={sizeClasses.labelSize}\n weight={sizeClasses.labelWeight}\n className={`${variantClasses.labelColor} text-center uppercase tracking-wide ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n </div>\n </div>\n );\n};\n\nexport default ProgressCircle;\n"],"mappings":"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","names":["jsx"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/Text/Text.tsx","../../src/components/ProgressCircle/ProgressCircle.tsx"],"sourcesContent":["import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\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={`${baseClasses} ${sizeClasses} ${weightClasses} ${color} ${className}`}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ReactNode } from 'react';\nimport Text from '../Text/Text';\n\n/**\n * Progress circle size variants\n */\ntype ProgressCircleSize = 'small' | 'medium';\n\n/**\n * Progress circle color variants\n */\ntype ProgressCircleVariant = 'blue' | 'green';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'w-[90px] h-[90px]', // 90px circle from design specs\n strokeWidth: 4, // 4px stroke width - matches ProgressBar small (h-1)\n textSize: '2xl', // 24px for percentage (font-size: 24px)\n textWeight: 'medium', // font-weight: 500\n labelSize: '2xs' as const, // Will be overridden with custom 8px in className\n labelWeight: 'bold', // font-weight: 700\n spacing: 'gap-0', // Reduced gap between percentage and label for better spacing\n contentWidth: 'max-w-[50px]', // Reduced width to fit text inside circle\n },\n medium: {\n container: 'w-[152px] h-[152px]', // 151.67px ≈ 152px circle from design specs\n strokeWidth: 8, // 8px stroke width - matches ProgressBar medium (h-2)\n textSize: '2xl', // 24px for percentage (font-size: 24px)\n textWeight: 'medium', // font-weight: 500\n labelSize: 'xs' as const, // 12px for status label (font-size: 12px)\n labelWeight: 'medium', // font-weight: 500 (changed from bold)\n spacing: 'gap-1', // 4px gap between percentage and label\n contentWidth: 'max-w-[90px]', // Reduced width to fit text inside circle\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'stroke-primary-100', // Light blue background (#BBDCF7)\n fill: 'stroke-primary-700', // Blue for activity progress (#2271C4)\n textColor: 'text-primary-700', // Blue text color (#2271C4)\n labelColor: 'text-text-700', // Gray text for label (#525252)\n },\n green: {\n background: 'stroke-background-300', // Gray background (#D5D4D4 - matches design)\n fill: 'stroke-success-200', // Green for performance (#84D3A2 - matches design)\n textColor: 'text-text-800', // Dark gray text (#404040 - matches design)\n labelColor: 'text-text-600', // Medium gray text for label (#737373 - matches design)\n },\n} as const;\n\n/**\n * ProgressCircle component props interface\n */\nexport type ProgressCircleProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress circle */\n size?: ProgressCircleSize;\n /** Color variant of the progress circle */\n variant?: ProgressCircleVariant;\n /** Optional label to display below percentage */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n};\n\n/**\n * ProgressCircle component for Analytica Ensino platforms\n *\n * A circular progress indicator with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\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 progress circle\n * <ProgressCircle value={65} />\n *\n * // Activity progress (blue)\n * <ProgressCircle variant=\"blue\" value={45} label=\"CONCLUÍDO\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressCircle variant=\"green\" size=\"medium\" value={85} label=\"MÉDIA\" />\n *\n * // Small size with custom max value\n * <ProgressCircle size=\"small\" value={3} max={5} showPercentage />\n * ```\n */\nconst ProgressCircle = ({\n value,\n max = 100,\n size = 'small',\n variant = 'blue',\n label,\n showPercentage = true,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n}: ProgressCircleProps) => {\n // Ensure value is within bounds and handle NaN/Infinity\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n // Get size and variant classes\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n // Calculate SVG dimensions and stroke properties\n const radius = size === 'small' ? 37 : 64; // Radius calculation based on container size\n const circumference = 2 * Math.PI * radius;\n const strokeDashoffset = circumference - (percentage / 100) * circumference;\n const center = size === 'small' ? 45 : 76; // Center point of SVG\n const svgSize = size === 'small' ? 90 : 152; // SVG viewBox size\n\n return (\n <div\n className={`relative flex flex-col items-center justify-center ${sizeClasses.container} rounded-lg ${className}`}\n >\n {/* Progress circle SVG */}\n <svg\n className=\"absolute inset-0 transform -rotate-90\"\n width={svgSize}\n height={svgSize}\n viewBox={`0 0 ${svgSize} ${svgSize}`}\n aria-hidden=\"true\"\n >\n {/* Background circle */}\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={sizeClasses.strokeWidth}\n className={`${variantClasses.background} rounded-lg`}\n />\n {/* Progress circle - SVG stroke properties require style for animation */}\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={sizeClasses.strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={strokeDashoffset}\n className={`${variantClasses.fill} transition-all duration-500 ease-out shadow-soft-shadow-3 rounded-lg`}\n />\n </svg>\n\n {/* Native progress element for accessibility */}\n <progress\n value={clampedValue}\n max={max}\n aria-label={typeof label === 'string' ? label : 'Progress'}\n className=\"absolute opacity-0 w-0 h-0\"\n />\n\n {/* Content overlay - centered content */}\n <div\n className={`relative z-10 flex flex-col items-center justify-center ${sizeClasses.spacing} ${sizeClasses.contentWidth}`}\n >\n {/* Percentage text */}\n {showPercentage && (\n <Text\n size={sizeClasses.textSize}\n weight={sizeClasses.textWeight}\n className={`text-center w-full ${variantClasses.textColor} ${percentageClassName}`}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {/* Label text */}\n {label && (\n <Text\n as=\"span\"\n size={sizeClasses.labelSize}\n weight={sizeClasses.labelWeight}\n className={`${variantClasses.labelColor} text-center uppercase tracking-wide truncate w-full ${size === 'small' ? 'text-[8px] leading-[9px]' : ''} ${labelClassName}`}\n >\n {label}\n </Text>\n )}\n </div>\n </div>\n );\n};\n\nexport default ProgressCircle;\n"],"mappings":"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","names":["jsx"]}
|