analytica-frontend-lib 1.0.37 → 1.0.39
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/README.md +1 -2
- package/dist/Alert/index.js.map +1 -1
- package/dist/Alert/index.mjs.map +1 -1
- package/dist/Badge/index.d.mts +0 -1
- package/dist/Badge/index.d.ts +0 -1
- package/dist/Badge/index.js.map +1 -1
- package/dist/Badge/index.mjs.map +1 -1
- package/dist/Button/index.d.mts +0 -1
- package/dist/Button/index.d.ts +0 -1
- package/dist/Button/index.js.map +1 -1
- package/dist/Button/index.mjs.map +1 -1
- package/dist/CheckBox/index.js +0 -1
- package/dist/CheckBox/index.js.map +1 -1
- package/dist/CheckBox/index.mjs +0 -2
- package/dist/CheckBox/index.mjs.map +1 -1
- package/dist/Chips/index.d.mts +41 -0
- package/dist/Chips/index.d.ts +41 -0
- package/dist/Chips/index.js +57 -0
- package/dist/Chips/index.js.map +1 -0
- package/dist/Chips/index.mjs +36 -0
- package/dist/Chips/index.mjs.map +1 -0
- package/dist/Divider/index.d.mts +32 -0
- package/dist/Divider/index.d.ts +32 -0
- package/dist/Divider/index.js +47 -0
- package/dist/Divider/index.js.map +1 -0
- package/dist/Divider/index.mjs +26 -0
- package/dist/Divider/index.mjs.map +1 -0
- package/dist/DropdownMenu/index.d.mts +16 -8
- package/dist/DropdownMenu/index.d.ts +16 -8
- package/dist/DropdownMenu/index.js +122 -46
- package/dist/DropdownMenu/index.js.map +1 -1
- package/dist/DropdownMenu/index.mjs +122 -47
- package/dist/DropdownMenu/index.mjs.map +1 -1
- package/dist/IconButton/index.d.mts +0 -1
- package/dist/IconButton/index.d.ts +0 -1
- package/dist/IconButton/index.js.map +1 -1
- package/dist/IconButton/index.mjs.map +1 -1
- package/dist/IconRoundedButton/index.d.mts +0 -1
- package/dist/IconRoundedButton/index.d.ts +0 -1
- package/dist/IconRoundedButton/index.js.map +1 -1
- package/dist/IconRoundedButton/index.mjs.map +1 -1
- package/dist/Input/index.d.mts +27 -0
- package/dist/Input/index.d.ts +27 -0
- package/dist/Input/index.js +184 -0
- package/dist/Input/index.js.map +1 -0
- package/dist/Input/index.mjs +168 -0
- package/dist/Input/index.mjs.map +1 -0
- package/dist/NavButton/index.d.mts +0 -1
- package/dist/NavButton/index.d.ts +0 -1
- package/dist/NavButton/index.js.map +1 -1
- package/dist/NavButton/index.mjs.map +1 -1
- package/dist/ProgressBar/index.js +0 -1
- package/dist/ProgressBar/index.js.map +1 -1
- package/dist/ProgressBar/index.mjs +0 -2
- package/dist/ProgressBar/index.mjs.map +1 -1
- package/dist/ProgressCircle/index.js +0 -1
- package/dist/ProgressCircle/index.js.map +1 -1
- package/dist/ProgressCircle/index.mjs +0 -2
- package/dist/ProgressCircle/index.mjs.map +1 -1
- package/dist/Radio/index.js +0 -1
- package/dist/Radio/index.js.map +1 -1
- package/dist/Radio/index.mjs +0 -2
- package/dist/Radio/index.mjs.map +1 -1
- package/dist/Select/index.d.mts +51 -0
- package/dist/Select/index.d.ts +51 -0
- package/dist/Select/index.js +322 -0
- package/dist/Select/index.js.map +1 -0
- package/dist/Select/index.mjs +298 -0
- package/dist/Select/index.mjs.map +1 -0
- package/dist/SelectionButton/index.d.mts +0 -1
- package/dist/SelectionButton/index.d.ts +0 -1
- package/dist/SelectionButton/index.js.map +1 -1
- package/dist/SelectionButton/index.mjs.map +1 -1
- package/dist/Text/index.d.mts +0 -1
- package/dist/Text/index.d.ts +0 -1
- package/dist/Text/index.js.map +1 -1
- package/dist/Text/index.mjs.map +1 -1
- package/dist/TextArea/index.js +0 -1
- package/dist/TextArea/index.js.map +1 -1
- package/dist/TextArea/index.mjs +0 -2
- package/dist/TextArea/index.mjs.map +1 -1
- package/dist/Toast/Toaster/index.js +0 -1
- package/dist/Toast/Toaster/index.js.map +1 -1
- package/dist/Toast/Toaster/index.mjs +0 -2
- package/dist/Toast/Toaster/index.mjs.map +1 -1
- package/dist/Toast/index.js +0 -1
- package/dist/Toast/index.js.map +1 -1
- package/dist/Toast/index.mjs +0 -2
- package/dist/Toast/index.mjs.map +1 -1
- package/dist/index.css +5 -9
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +7 -136
- package/dist/index.d.ts +7 -136
- package/dist/index.js +52 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +52 -34
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +5 -9
- package/dist/styles.css.map +1 -1
- package/package.json +1 -5
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/components/Input/Input.tsx
|
|
21
|
+
var Input_exports = {};
|
|
22
|
+
__export(Input_exports, {
|
|
23
|
+
default: () => Input_default
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(Input_exports);
|
|
26
|
+
var import_phosphor_react = require("phosphor-react");
|
|
27
|
+
var import_react = require("react");
|
|
28
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
29
|
+
var SIZE_CLASSES = {
|
|
30
|
+
small: "text-sm",
|
|
31
|
+
medium: "text-md",
|
|
32
|
+
large: "text-lg",
|
|
33
|
+
"extra-large": "text-xl"
|
|
34
|
+
};
|
|
35
|
+
var STATE_CLASSES = {
|
|
36
|
+
default: "border-border-300 placeholder:text-text-600 hover:border-border-400",
|
|
37
|
+
error: "border-2 border-indicator-error placeholder:text-text-600",
|
|
38
|
+
disabled: "border-border-300 placeholder:text-text-600 cursor-not-allowed opacity-40",
|
|
39
|
+
"read-only": "border-border-300 !text-text-600 cursor-default focus:outline-none bg-background-50"
|
|
40
|
+
};
|
|
41
|
+
var VARIANT_CLASSES = {
|
|
42
|
+
outlined: "border rounded-lg",
|
|
43
|
+
underlined: "border-0 border-b rounded-none bg-transparent focus:outline-none focus:border-primary-950 focus:border-b-2",
|
|
44
|
+
rounded: "border rounded-full"
|
|
45
|
+
};
|
|
46
|
+
var getActualState = (disabled, readOnly, errorMessage, state) => {
|
|
47
|
+
if (disabled) return "disabled";
|
|
48
|
+
if (readOnly) return "read-only";
|
|
49
|
+
if (errorMessage) return "error";
|
|
50
|
+
return state || "default";
|
|
51
|
+
};
|
|
52
|
+
var getIconSize = (size) => {
|
|
53
|
+
const iconSizeClasses = {
|
|
54
|
+
small: "w-4 h-4",
|
|
55
|
+
medium: "w-5 h-5",
|
|
56
|
+
large: "w-6 h-6",
|
|
57
|
+
"extra-large": "w-7 h-7"
|
|
58
|
+
};
|
|
59
|
+
return iconSizeClasses[size] || iconSizeClasses.medium;
|
|
60
|
+
};
|
|
61
|
+
var getPasswordToggleConfig = (type, disabled, readOnly, showPassword, iconRight) => {
|
|
62
|
+
const isPasswordType = type === "password";
|
|
63
|
+
const shouldShowPasswordToggle = isPasswordType && !disabled && !readOnly;
|
|
64
|
+
let actualIconRight = iconRight;
|
|
65
|
+
let ariaLabel;
|
|
66
|
+
if (shouldShowPasswordToggle) {
|
|
67
|
+
actualIconRight = showPassword ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_phosphor_react.EyeSlash, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_phosphor_react.Eye, {});
|
|
68
|
+
ariaLabel = showPassword ? "Ocultar senha" : "Mostrar senha";
|
|
69
|
+
}
|
|
70
|
+
return { shouldShowPasswordToggle, actualIconRight, ariaLabel };
|
|
71
|
+
};
|
|
72
|
+
var getCombinedClasses = (actualState, variant) => {
|
|
73
|
+
const stateClasses = STATE_CLASSES[actualState];
|
|
74
|
+
const variantClasses = VARIANT_CLASSES[variant];
|
|
75
|
+
if (actualState === "error" && variant === "underlined") {
|
|
76
|
+
return "border-0 border-b-2 border-indicator-error rounded-none bg-transparent focus:outline-none focus:border-primary-950 placeholder:text-text-600";
|
|
77
|
+
}
|
|
78
|
+
return `${stateClasses} ${variantClasses}`;
|
|
79
|
+
};
|
|
80
|
+
var Input = (0, import_react.forwardRef)(
|
|
81
|
+
({
|
|
82
|
+
label,
|
|
83
|
+
helperText,
|
|
84
|
+
errorMessage,
|
|
85
|
+
size = "medium",
|
|
86
|
+
variant = "outlined",
|
|
87
|
+
state = "default",
|
|
88
|
+
iconLeft,
|
|
89
|
+
iconRight,
|
|
90
|
+
className = "",
|
|
91
|
+
containerClassName = "",
|
|
92
|
+
disabled,
|
|
93
|
+
readOnly,
|
|
94
|
+
id,
|
|
95
|
+
type = "text",
|
|
96
|
+
...props
|
|
97
|
+
}, ref) => {
|
|
98
|
+
const [showPassword, setShowPassword] = (0, import_react.useState)(false);
|
|
99
|
+
const isPasswordType = type === "password";
|
|
100
|
+
const actualType = isPasswordType && showPassword ? "text" : type;
|
|
101
|
+
const actualState = getActualState(disabled, readOnly, errorMessage, state);
|
|
102
|
+
const sizeClasses = SIZE_CLASSES[size];
|
|
103
|
+
const combinedClasses = (0, import_react.useMemo)(
|
|
104
|
+
() => getCombinedClasses(actualState, variant),
|
|
105
|
+
[actualState, variant]
|
|
106
|
+
);
|
|
107
|
+
const iconSize = getIconSize(size);
|
|
108
|
+
const baseClasses = "bg-background w-full py-2 px-3 font-normal text-text-900 focus:outline-primary-950";
|
|
109
|
+
const generatedId = (0, import_react.useId)();
|
|
110
|
+
const inputId = id ?? `input-${generatedId}`;
|
|
111
|
+
const togglePasswordVisibility = () => setShowPassword(!showPassword);
|
|
112
|
+
const { shouldShowPasswordToggle, actualIconRight, ariaLabel } = getPasswordToggleConfig(
|
|
113
|
+
type,
|
|
114
|
+
disabled,
|
|
115
|
+
readOnly,
|
|
116
|
+
showPassword,
|
|
117
|
+
iconRight
|
|
118
|
+
);
|
|
119
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `${containerClassName}`, children: [
|
|
120
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
121
|
+
"label",
|
|
122
|
+
{
|
|
123
|
+
htmlFor: inputId,
|
|
124
|
+
className: `block font-bold text-text-900 mb-1.5 ${sizeClasses}`,
|
|
125
|
+
children: label
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", children: [
|
|
129
|
+
iconLeft && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
130
|
+
"span",
|
|
131
|
+
{
|
|
132
|
+
className: `${iconSize} text-text-400 flex items-center justify-center`,
|
|
133
|
+
children: iconLeft
|
|
134
|
+
}
|
|
135
|
+
) }),
|
|
136
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
137
|
+
"input",
|
|
138
|
+
{
|
|
139
|
+
ref,
|
|
140
|
+
id: inputId,
|
|
141
|
+
type: actualType,
|
|
142
|
+
className: `${baseClasses} ${sizeClasses} ${combinedClasses} ${iconLeft ? "pl-10" : ""} ${actualIconRight ? "pr-10" : ""} ${className}`,
|
|
143
|
+
disabled,
|
|
144
|
+
readOnly,
|
|
145
|
+
"aria-invalid": actualState === "error" ? "true" : void 0,
|
|
146
|
+
...props
|
|
147
|
+
}
|
|
148
|
+
),
|
|
149
|
+
actualIconRight && (shouldShowPasswordToggle ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
150
|
+
"button",
|
|
151
|
+
{
|
|
152
|
+
type: "button",
|
|
153
|
+
className: "absolute right-3 top-1/2 transform -translate-y-1/2 cursor-pointer border-0 bg-transparent p-0",
|
|
154
|
+
onClick: togglePasswordVisibility,
|
|
155
|
+
"aria-label": ariaLabel,
|
|
156
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
157
|
+
"span",
|
|
158
|
+
{
|
|
159
|
+
className: `${iconSize} text-text-400 flex items-center justify-center hover:text-text-600 transition-colors`,
|
|
160
|
+
children: actualIconRight
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
165
|
+
"span",
|
|
166
|
+
{
|
|
167
|
+
className: `${iconSize} text-text-400 flex items-center justify-center`,
|
|
168
|
+
children: actualIconRight
|
|
169
|
+
}
|
|
170
|
+
) }))
|
|
171
|
+
] }),
|
|
172
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-1.5 gap-1.5", children: [
|
|
173
|
+
helperText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-text-500", children: helperText }),
|
|
174
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "flex gap-1 items-center text-sm text-indicator-error", children: [
|
|
175
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_phosphor_react.WarningCircle, { size: 16 }),
|
|
176
|
+
" ",
|
|
177
|
+
errorMessage
|
|
178
|
+
] })
|
|
179
|
+
] })
|
|
180
|
+
] });
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
var Input_default = Input;
|
|
184
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/Input/Input.tsx"],"sourcesContent":["import { WarningCircle, Eye, EyeSlash } from 'phosphor-react';\nimport {\n InputHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n useMemo,\n} from 'react';\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-xl',\n} as const;\n\n/**\n * Lookup table for state classes\n */\nconst STATE_CLASSES = {\n default:\n 'border-border-300 placeholder:text-text-600 hover:border-border-400',\n error: 'border-2 border-indicator-error placeholder:text-text-600',\n disabled:\n 'border-border-300 placeholder:text-text-600 cursor-not-allowed opacity-40',\n 'read-only':\n 'border-border-300 !text-text-600 cursor-default focus:outline-none bg-background-50',\n} as const;\n\n/**\n * Lookup table for variant classes\n */\nconst VARIANT_CLASSES = {\n outlined: 'border rounded-lg',\n underlined:\n 'border-0 border-b rounded-none bg-transparent focus:outline-none focus:border-primary-950 focus:border-b-2',\n rounded: 'border rounded-full',\n} as const;\n\n/**\n * Input component props interface\n */\ntype InputProps = {\n /** Label text displayed above the input */\n label?: string;\n /** Helper text displayed below the input */\n helperText?: string;\n /** Error message displayed below the input */\n errorMessage?: string;\n /** Size of the input */\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the input */\n variant?: 'outlined' | 'underlined' | 'rounded';\n /** Current state of the input */\n state?: 'default' | 'error' | 'disabled' | 'read-only';\n /** Icon to display on the left side of the input */\n iconLeft?: ReactNode;\n /** Icon to display on the right side of the input */\n iconRight?: ReactNode;\n /** Additional CSS classes to apply to the input */\n className?: string;\n /** Additional CSS classes to apply to the container */\n containerClassName?: string;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size'>;\n\n/**\n * Input component for Analytica Ensino platforms\n *\n * A flexible input component with multiple sizes, states, and support for icons.\n * Includes label, helper text, and error message functionality.\n * Features automatic password visibility toggle for password inputs.\n *\n * @param label - Optional label text displayed above the input\n * @param helperText - Optional helper text displayed below the input\n * @param errorMessage - Optional error message displayed below the input\n * @param size - The size variant (small, medium, large, extra-large)\n * @param variant - The visual variant (outlined, underlined, rounded)\n * @param state - The current state (default, error, disabled, read-only)\n * @param iconLeft - Optional icon displayed on the left side\n * @param iconRight - Optional icon displayed on the right side (overridden by password toggle for password inputs)\n * @param type - Input type (text, email, password, etc.) - password type automatically includes show/hide toggle\n * @param className - Additional CSS classes for the input\n * @param containerClassName - Additional CSS classes for the container\n * @param props - All other standard input HTML attributes\n * @returns A styled input element with optional label and helper text\n *\n * @example\n * ```tsx\n * // Basic input\n * <Input\n * label=\"Email\"\n * placeholder=\"Digite seu email\"\n * helperText=\"Usaremos apenas para contato\"\n * size=\"medium\"\n * variant=\"outlined\"\n * state=\"default\"\n * />\n *\n * // Password input with automatic toggle\n * <Input\n * label=\"Senha\"\n * type=\"password\"\n * placeholder=\"Digite sua senha\"\n * helperText=\"Clique no olho para mostrar/ocultar\"\n * />\n * ```\n */\n// Helper functions to reduce cognitive complexity\nconst getActualState = (\n disabled?: boolean,\n readOnly?: boolean,\n errorMessage?: string,\n state?: string\n): keyof typeof STATE_CLASSES => {\n if (disabled) return 'disabled';\n if (readOnly) return 'read-only';\n if (errorMessage) return 'error';\n return (state as keyof typeof STATE_CLASSES) || 'default';\n};\n\nconst getIconSize = (size: string) => {\n const iconSizeClasses = {\n small: 'w-4 h-4',\n medium: 'w-5 h-5',\n large: 'w-6 h-6',\n 'extra-large': 'w-7 h-7',\n };\n return (\n iconSizeClasses[size as keyof typeof iconSizeClasses] ||\n iconSizeClasses.medium\n );\n};\n\nconst getPasswordToggleConfig = (\n type?: string,\n disabled?: boolean,\n readOnly?: boolean,\n showPassword?: boolean,\n iconRight?: ReactNode\n) => {\n const isPasswordType = type === 'password';\n const shouldShowPasswordToggle = isPasswordType && !disabled && !readOnly;\n\n let actualIconRight = iconRight;\n let ariaLabel: string | undefined;\n\n if (shouldShowPasswordToggle) {\n actualIconRight = showPassword ? <EyeSlash /> : <Eye />;\n ariaLabel = showPassword ? 'Ocultar senha' : 'Mostrar senha';\n }\n\n return { shouldShowPasswordToggle, actualIconRight, ariaLabel };\n};\n\nconst getCombinedClasses = (\n actualState: keyof typeof STATE_CLASSES,\n variant: keyof typeof VARIANT_CLASSES\n) => {\n const stateClasses = STATE_CLASSES[actualState];\n const variantClasses = VARIANT_CLASSES[variant];\n\n // Special case: error state with underlined variant\n if (actualState === 'error' && variant === 'underlined') {\n return 'border-0 border-b-2 border-indicator-error rounded-none bg-transparent focus:outline-none focus:border-primary-950 placeholder:text-text-600';\n }\n\n return `${stateClasses} ${variantClasses}`;\n};\n\nconst Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n label,\n helperText,\n errorMessage,\n size = 'medium',\n variant = 'outlined',\n state = 'default',\n iconLeft,\n iconRight,\n className = '',\n containerClassName = '',\n disabled,\n readOnly,\n id,\n type = 'text',\n ...props\n },\n ref\n ) => {\n // State for password visibility toggle\n const [showPassword, setShowPassword] = useState(false);\n const isPasswordType = type === 'password';\n const actualType = isPasswordType && showPassword ? 'text' : type;\n const actualState = getActualState(disabled, readOnly, errorMessage, state);\n\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const combinedClasses = useMemo(\n () => getCombinedClasses(actualState, variant),\n [actualState, variant]\n );\n const iconSize = getIconSize(size);\n\n const baseClasses =\n 'bg-background w-full py-2 px-3 font-normal text-text-900 focus:outline-primary-950';\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `input-${generatedId}`;\n\n // Handle password visibility toggle\n const togglePasswordVisibility = () => setShowPassword(!showPassword);\n\n // Get password toggle configuration\n const { shouldShowPasswordToggle, actualIconRight, ariaLabel } =\n getPasswordToggleConfig(\n type,\n disabled,\n readOnly,\n showPassword,\n iconRight\n );\n\n return (\n <div className={`${containerClassName}`}>\n {/* Label */}\n {label && (\n <label\n htmlFor={inputId}\n className={`block font-bold text-text-900 mb-1.5 ${sizeClasses}`}\n >\n {label}\n </label>\n )}\n\n {/* Input Container */}\n <div className=\"relative\">\n {/* Left Icon */}\n {iconLeft && (\n <div className=\"absolute left-3 top-1/2 transform -translate-y-1/2 pointer-events-none\">\n <span\n className={`${iconSize} text-text-400 flex items-center justify-center`}\n >\n {iconLeft}\n </span>\n </div>\n )}\n\n {/* Input Field */}\n <input\n ref={ref}\n id={inputId}\n type={actualType}\n className={`${baseClasses} ${sizeClasses} ${combinedClasses} ${\n iconLeft ? 'pl-10' : ''\n } ${actualIconRight ? 'pr-10' : ''} ${className}`}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={actualState === 'error' ? 'true' : undefined}\n {...props}\n />\n\n {/* Right Icon */}\n {actualIconRight &&\n (shouldShowPasswordToggle ? (\n <button\n type=\"button\"\n className=\"absolute right-3 top-1/2 transform -translate-y-1/2 cursor-pointer border-0 bg-transparent p-0\"\n onClick={togglePasswordVisibility}\n aria-label={ariaLabel}\n >\n <span\n className={`${iconSize} text-text-400 flex items-center justify-center hover:text-text-600 transition-colors`}\n >\n {actualIconRight}\n </span>\n </button>\n ) : (\n <div className=\"absolute right-3 top-1/2 transform -translate-y-1/2 pointer-events-none\">\n <span\n className={`${iconSize} text-text-400 flex items-center justify-center`}\n >\n {actualIconRight}\n </span>\n </div>\n ))}\n </div>\n\n {/* Helper Text or Error Message */}\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 </div>\n );\n }\n);\n\nexport default Input;\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// src/components/Input/Input.tsx
|
|
2
|
+
import { WarningCircle, Eye, EyeSlash } from "phosphor-react";
|
|
3
|
+
import {
|
|
4
|
+
forwardRef,
|
|
5
|
+
useState,
|
|
6
|
+
useId,
|
|
7
|
+
useMemo
|
|
8
|
+
} from "react";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
var SIZE_CLASSES = {
|
|
11
|
+
small: "text-sm",
|
|
12
|
+
medium: "text-md",
|
|
13
|
+
large: "text-lg",
|
|
14
|
+
"extra-large": "text-xl"
|
|
15
|
+
};
|
|
16
|
+
var STATE_CLASSES = {
|
|
17
|
+
default: "border-border-300 placeholder:text-text-600 hover:border-border-400",
|
|
18
|
+
error: "border-2 border-indicator-error placeholder:text-text-600",
|
|
19
|
+
disabled: "border-border-300 placeholder:text-text-600 cursor-not-allowed opacity-40",
|
|
20
|
+
"read-only": "border-border-300 !text-text-600 cursor-default focus:outline-none bg-background-50"
|
|
21
|
+
};
|
|
22
|
+
var VARIANT_CLASSES = {
|
|
23
|
+
outlined: "border rounded-lg",
|
|
24
|
+
underlined: "border-0 border-b rounded-none bg-transparent focus:outline-none focus:border-primary-950 focus:border-b-2",
|
|
25
|
+
rounded: "border rounded-full"
|
|
26
|
+
};
|
|
27
|
+
var getActualState = (disabled, readOnly, errorMessage, state) => {
|
|
28
|
+
if (disabled) return "disabled";
|
|
29
|
+
if (readOnly) return "read-only";
|
|
30
|
+
if (errorMessage) return "error";
|
|
31
|
+
return state || "default";
|
|
32
|
+
};
|
|
33
|
+
var getIconSize = (size) => {
|
|
34
|
+
const iconSizeClasses = {
|
|
35
|
+
small: "w-4 h-4",
|
|
36
|
+
medium: "w-5 h-5",
|
|
37
|
+
large: "w-6 h-6",
|
|
38
|
+
"extra-large": "w-7 h-7"
|
|
39
|
+
};
|
|
40
|
+
return iconSizeClasses[size] || iconSizeClasses.medium;
|
|
41
|
+
};
|
|
42
|
+
var getPasswordToggleConfig = (type, disabled, readOnly, showPassword, iconRight) => {
|
|
43
|
+
const isPasswordType = type === "password";
|
|
44
|
+
const shouldShowPasswordToggle = isPasswordType && !disabled && !readOnly;
|
|
45
|
+
let actualIconRight = iconRight;
|
|
46
|
+
let ariaLabel;
|
|
47
|
+
if (shouldShowPasswordToggle) {
|
|
48
|
+
actualIconRight = showPassword ? /* @__PURE__ */ jsx(EyeSlash, {}) : /* @__PURE__ */ jsx(Eye, {});
|
|
49
|
+
ariaLabel = showPassword ? "Ocultar senha" : "Mostrar senha";
|
|
50
|
+
}
|
|
51
|
+
return { shouldShowPasswordToggle, actualIconRight, ariaLabel };
|
|
52
|
+
};
|
|
53
|
+
var getCombinedClasses = (actualState, variant) => {
|
|
54
|
+
const stateClasses = STATE_CLASSES[actualState];
|
|
55
|
+
const variantClasses = VARIANT_CLASSES[variant];
|
|
56
|
+
if (actualState === "error" && variant === "underlined") {
|
|
57
|
+
return "border-0 border-b-2 border-indicator-error rounded-none bg-transparent focus:outline-none focus:border-primary-950 placeholder:text-text-600";
|
|
58
|
+
}
|
|
59
|
+
return `${stateClasses} ${variantClasses}`;
|
|
60
|
+
};
|
|
61
|
+
var Input = forwardRef(
|
|
62
|
+
({
|
|
63
|
+
label,
|
|
64
|
+
helperText,
|
|
65
|
+
errorMessage,
|
|
66
|
+
size = "medium",
|
|
67
|
+
variant = "outlined",
|
|
68
|
+
state = "default",
|
|
69
|
+
iconLeft,
|
|
70
|
+
iconRight,
|
|
71
|
+
className = "",
|
|
72
|
+
containerClassName = "",
|
|
73
|
+
disabled,
|
|
74
|
+
readOnly,
|
|
75
|
+
id,
|
|
76
|
+
type = "text",
|
|
77
|
+
...props
|
|
78
|
+
}, ref) => {
|
|
79
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
80
|
+
const isPasswordType = type === "password";
|
|
81
|
+
const actualType = isPasswordType && showPassword ? "text" : type;
|
|
82
|
+
const actualState = getActualState(disabled, readOnly, errorMessage, state);
|
|
83
|
+
const sizeClasses = SIZE_CLASSES[size];
|
|
84
|
+
const combinedClasses = useMemo(
|
|
85
|
+
() => getCombinedClasses(actualState, variant),
|
|
86
|
+
[actualState, variant]
|
|
87
|
+
);
|
|
88
|
+
const iconSize = getIconSize(size);
|
|
89
|
+
const baseClasses = "bg-background w-full py-2 px-3 font-normal text-text-900 focus:outline-primary-950";
|
|
90
|
+
const generatedId = useId();
|
|
91
|
+
const inputId = id ?? `input-${generatedId}`;
|
|
92
|
+
const togglePasswordVisibility = () => setShowPassword(!showPassword);
|
|
93
|
+
const { shouldShowPasswordToggle, actualIconRight, ariaLabel } = getPasswordToggleConfig(
|
|
94
|
+
type,
|
|
95
|
+
disabled,
|
|
96
|
+
readOnly,
|
|
97
|
+
showPassword,
|
|
98
|
+
iconRight
|
|
99
|
+
);
|
|
100
|
+
return /* @__PURE__ */ jsxs("div", { className: `${containerClassName}`, children: [
|
|
101
|
+
label && /* @__PURE__ */ jsx(
|
|
102
|
+
"label",
|
|
103
|
+
{
|
|
104
|
+
htmlFor: inputId,
|
|
105
|
+
className: `block font-bold text-text-900 mb-1.5 ${sizeClasses}`,
|
|
106
|
+
children: label
|
|
107
|
+
}
|
|
108
|
+
),
|
|
109
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
110
|
+
iconLeft && /* @__PURE__ */ jsx("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ jsx(
|
|
111
|
+
"span",
|
|
112
|
+
{
|
|
113
|
+
className: `${iconSize} text-text-400 flex items-center justify-center`,
|
|
114
|
+
children: iconLeft
|
|
115
|
+
}
|
|
116
|
+
) }),
|
|
117
|
+
/* @__PURE__ */ jsx(
|
|
118
|
+
"input",
|
|
119
|
+
{
|
|
120
|
+
ref,
|
|
121
|
+
id: inputId,
|
|
122
|
+
type: actualType,
|
|
123
|
+
className: `${baseClasses} ${sizeClasses} ${combinedClasses} ${iconLeft ? "pl-10" : ""} ${actualIconRight ? "pr-10" : ""} ${className}`,
|
|
124
|
+
disabled,
|
|
125
|
+
readOnly,
|
|
126
|
+
"aria-invalid": actualState === "error" ? "true" : void 0,
|
|
127
|
+
...props
|
|
128
|
+
}
|
|
129
|
+
),
|
|
130
|
+
actualIconRight && (shouldShowPasswordToggle ? /* @__PURE__ */ jsx(
|
|
131
|
+
"button",
|
|
132
|
+
{
|
|
133
|
+
type: "button",
|
|
134
|
+
className: "absolute right-3 top-1/2 transform -translate-y-1/2 cursor-pointer border-0 bg-transparent p-0",
|
|
135
|
+
onClick: togglePasswordVisibility,
|
|
136
|
+
"aria-label": ariaLabel,
|
|
137
|
+
children: /* @__PURE__ */ jsx(
|
|
138
|
+
"span",
|
|
139
|
+
{
|
|
140
|
+
className: `${iconSize} text-text-400 flex items-center justify-center hover:text-text-600 transition-colors`,
|
|
141
|
+
children: actualIconRight
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
) : /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ jsx(
|
|
146
|
+
"span",
|
|
147
|
+
{
|
|
148
|
+
className: `${iconSize} text-text-400 flex items-center justify-center`,
|
|
149
|
+
children: actualIconRight
|
|
150
|
+
}
|
|
151
|
+
) }))
|
|
152
|
+
] }),
|
|
153
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1.5 gap-1.5", children: [
|
|
154
|
+
helperText && /* @__PURE__ */ jsx("p", { className: "text-sm text-text-500", children: helperText }),
|
|
155
|
+
errorMessage && /* @__PURE__ */ jsxs("p", { className: "flex gap-1 items-center text-sm text-indicator-error", children: [
|
|
156
|
+
/* @__PURE__ */ jsx(WarningCircle, { size: 16 }),
|
|
157
|
+
" ",
|
|
158
|
+
errorMessage
|
|
159
|
+
] })
|
|
160
|
+
] })
|
|
161
|
+
] });
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
var Input_default = Input;
|
|
165
|
+
export {
|
|
166
|
+
Input_default as default
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/Input/Input.tsx"],"sourcesContent":["import { WarningCircle, Eye, EyeSlash } from 'phosphor-react';\nimport {\n InputHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n useMemo,\n} from 'react';\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-xl',\n} as const;\n\n/**\n * Lookup table for state classes\n */\nconst STATE_CLASSES = {\n default:\n 'border-border-300 placeholder:text-text-600 hover:border-border-400',\n error: 'border-2 border-indicator-error placeholder:text-text-600',\n disabled:\n 'border-border-300 placeholder:text-text-600 cursor-not-allowed opacity-40',\n 'read-only':\n 'border-border-300 !text-text-600 cursor-default focus:outline-none bg-background-50',\n} as const;\n\n/**\n * Lookup table for variant classes\n */\nconst VARIANT_CLASSES = {\n outlined: 'border rounded-lg',\n underlined:\n 'border-0 border-b rounded-none bg-transparent focus:outline-none focus:border-primary-950 focus:border-b-2',\n rounded: 'border rounded-full',\n} as const;\n\n/**\n * Input component props interface\n */\ntype InputProps = {\n /** Label text displayed above the input */\n label?: string;\n /** Helper text displayed below the input */\n helperText?: string;\n /** Error message displayed below the input */\n errorMessage?: string;\n /** Size of the input */\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the input */\n variant?: 'outlined' | 'underlined' | 'rounded';\n /** Current state of the input */\n state?: 'default' | 'error' | 'disabled' | 'read-only';\n /** Icon to display on the left side of the input */\n iconLeft?: ReactNode;\n /** Icon to display on the right side of the input */\n iconRight?: ReactNode;\n /** Additional CSS classes to apply to the input */\n className?: string;\n /** Additional CSS classes to apply to the container */\n containerClassName?: string;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size'>;\n\n/**\n * Input component for Analytica Ensino platforms\n *\n * A flexible input component with multiple sizes, states, and support for icons.\n * Includes label, helper text, and error message functionality.\n * Features automatic password visibility toggle for password inputs.\n *\n * @param label - Optional label text displayed above the input\n * @param helperText - Optional helper text displayed below the input\n * @param errorMessage - Optional error message displayed below the input\n * @param size - The size variant (small, medium, large, extra-large)\n * @param variant - The visual variant (outlined, underlined, rounded)\n * @param state - The current state (default, error, disabled, read-only)\n * @param iconLeft - Optional icon displayed on the left side\n * @param iconRight - Optional icon displayed on the right side (overridden by password toggle for password inputs)\n * @param type - Input type (text, email, password, etc.) - password type automatically includes show/hide toggle\n * @param className - Additional CSS classes for the input\n * @param containerClassName - Additional CSS classes for the container\n * @param props - All other standard input HTML attributes\n * @returns A styled input element with optional label and helper text\n *\n * @example\n * ```tsx\n * // Basic input\n * <Input\n * label=\"Email\"\n * placeholder=\"Digite seu email\"\n * helperText=\"Usaremos apenas para contato\"\n * size=\"medium\"\n * variant=\"outlined\"\n * state=\"default\"\n * />\n *\n * // Password input with automatic toggle\n * <Input\n * label=\"Senha\"\n * type=\"password\"\n * placeholder=\"Digite sua senha\"\n * helperText=\"Clique no olho para mostrar/ocultar\"\n * />\n * ```\n */\n// Helper functions to reduce cognitive complexity\nconst getActualState = (\n disabled?: boolean,\n readOnly?: boolean,\n errorMessage?: string,\n state?: string\n): keyof typeof STATE_CLASSES => {\n if (disabled) return 'disabled';\n if (readOnly) return 'read-only';\n if (errorMessage) return 'error';\n return (state as keyof typeof STATE_CLASSES) || 'default';\n};\n\nconst getIconSize = (size: string) => {\n const iconSizeClasses = {\n small: 'w-4 h-4',\n medium: 'w-5 h-5',\n large: 'w-6 h-6',\n 'extra-large': 'w-7 h-7',\n };\n return (\n iconSizeClasses[size as keyof typeof iconSizeClasses] ||\n iconSizeClasses.medium\n );\n};\n\nconst getPasswordToggleConfig = (\n type?: string,\n disabled?: boolean,\n readOnly?: boolean,\n showPassword?: boolean,\n iconRight?: ReactNode\n) => {\n const isPasswordType = type === 'password';\n const shouldShowPasswordToggle = isPasswordType && !disabled && !readOnly;\n\n let actualIconRight = iconRight;\n let ariaLabel: string | undefined;\n\n if (shouldShowPasswordToggle) {\n actualIconRight = showPassword ? <EyeSlash /> : <Eye />;\n ariaLabel = showPassword ? 'Ocultar senha' : 'Mostrar senha';\n }\n\n return { shouldShowPasswordToggle, actualIconRight, ariaLabel };\n};\n\nconst getCombinedClasses = (\n actualState: keyof typeof STATE_CLASSES,\n variant: keyof typeof VARIANT_CLASSES\n) => {\n const stateClasses = STATE_CLASSES[actualState];\n const variantClasses = VARIANT_CLASSES[variant];\n\n // Special case: error state with underlined variant\n if (actualState === 'error' && variant === 'underlined') {\n return 'border-0 border-b-2 border-indicator-error rounded-none bg-transparent focus:outline-none focus:border-primary-950 placeholder:text-text-600';\n }\n\n return `${stateClasses} ${variantClasses}`;\n};\n\nconst Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n label,\n helperText,\n errorMessage,\n size = 'medium',\n variant = 'outlined',\n state = 'default',\n iconLeft,\n iconRight,\n className = '',\n containerClassName = '',\n disabled,\n readOnly,\n id,\n type = 'text',\n ...props\n },\n ref\n ) => {\n // State for password visibility toggle\n const [showPassword, setShowPassword] = useState(false);\n const isPasswordType = type === 'password';\n const actualType = isPasswordType && showPassword ? 'text' : type;\n const actualState = getActualState(disabled, readOnly, errorMessage, state);\n\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const combinedClasses = useMemo(\n () => getCombinedClasses(actualState, variant),\n [actualState, variant]\n );\n const iconSize = getIconSize(size);\n\n const baseClasses =\n 'bg-background w-full py-2 px-3 font-normal text-text-900 focus:outline-primary-950';\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `input-${generatedId}`;\n\n // Handle password visibility toggle\n const togglePasswordVisibility = () => setShowPassword(!showPassword);\n\n // Get password toggle configuration\n const { shouldShowPasswordToggle, actualIconRight, ariaLabel } =\n getPasswordToggleConfig(\n type,\n disabled,\n readOnly,\n showPassword,\n iconRight\n );\n\n return (\n <div className={`${containerClassName}`}>\n {/* Label */}\n {label && (\n <label\n htmlFor={inputId}\n className={`block font-bold text-text-900 mb-1.5 ${sizeClasses}`}\n >\n {label}\n </label>\n )}\n\n {/* Input Container */}\n <div className=\"relative\">\n {/* Left Icon */}\n {iconLeft && (\n <div className=\"absolute left-3 top-1/2 transform -translate-y-1/2 pointer-events-none\">\n <span\n className={`${iconSize} text-text-400 flex items-center justify-center`}\n >\n {iconLeft}\n </span>\n </div>\n )}\n\n {/* Input Field */}\n <input\n ref={ref}\n id={inputId}\n type={actualType}\n className={`${baseClasses} ${sizeClasses} ${combinedClasses} ${\n iconLeft ? 'pl-10' : ''\n } ${actualIconRight ? 'pr-10' : ''} ${className}`}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={actualState === 'error' ? 'true' : undefined}\n {...props}\n />\n\n {/* Right Icon */}\n {actualIconRight &&\n (shouldShowPasswordToggle ? (\n <button\n type=\"button\"\n className=\"absolute right-3 top-1/2 transform -translate-y-1/2 cursor-pointer border-0 bg-transparent p-0\"\n onClick={togglePasswordVisibility}\n aria-label={ariaLabel}\n >\n <span\n className={`${iconSize} text-text-400 flex items-center justify-center hover:text-text-600 transition-colors`}\n >\n {actualIconRight}\n </span>\n </button>\n ) : (\n <div className=\"absolute right-3 top-1/2 transform -translate-y-1/2 pointer-events-none\">\n <span\n className={`${iconSize} text-text-400 flex items-center justify-center`}\n >\n {actualIconRight}\n </span>\n </div>\n ))}\n </div>\n\n {/* Helper Text or Error Message */}\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 </div>\n );\n }\n);\n\nexport default Input;\n"],"mappings":"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","names":[]}
|
|
@@ -6,7 +6,6 @@ import { ReactNode, ButtonHTMLAttributes } from 'react';
|
|
|
6
6
|
*
|
|
7
7
|
* Um botão de navegação com ícone e texto para navegação principal.
|
|
8
8
|
* Ideal para menus de navegação, sidebar, tabs de navegação, etc.
|
|
9
|
-
* Compatível com Next.js 15 e React 19.
|
|
10
9
|
* Suporta forwardRef para acesso programático ao elemento DOM.
|
|
11
10
|
*
|
|
12
11
|
* @param icon - O ícone a ser exibido no botão
|
|
@@ -6,7 +6,6 @@ import { ReactNode, ButtonHTMLAttributes } from 'react';
|
|
|
6
6
|
*
|
|
7
7
|
* Um botão de navegação com ícone e texto para navegação principal.
|
|
8
8
|
* Ideal para menus de navegação, sidebar, tabs de navegação, etc.
|
|
9
|
-
* Compatível com Next.js 15 e React 19.
|
|
10
9
|
* Suporta forwardRef para acesso programático ao elemento DOM.
|
|
11
10
|
*
|
|
12
11
|
* @param icon - O ícone a ser exibido no botão
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/NavButton/NavButton.tsx"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\n\n/**\n * NavButton component props interface\n */\ntype NavButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * NavButton component for Analytica Ensino platforms\n *\n * Um botão de navegação com ícone e texto para navegação principal.\n * Ideal para menus de navegação, sidebar, tabs de navegação, etc.\n *
|
|
1
|
+
{"version":3,"sources":["../../src/components/NavButton/NavButton.tsx"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\n\n/**\n * NavButton component props interface\n */\ntype NavButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * NavButton component for Analytica Ensino platforms\n *\n * Um botão de navegação com ícone e texto para navegação principal.\n * Ideal para menus de navegação, sidebar, tabs de navegação, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado para navegação\n *\n * @example\n * ```tsx\n * <NavButton\n * icon={<HomeIcon />}\n * label=\"Início\"\n * selected={false}\n * onClick={() => navigate('/')}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <NavButton\n * ref={buttonRef}\n * icon={<HomeIcon />}\n * label=\"Dashboard\"\n * selected={isActive}\n * onClick={() => setActiveTab('dashboard')}\n * />\n * ```\n */\nconst NavButton = forwardRef<HTMLButtonElement, NavButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'flex',\n 'flex-col',\n 'items-center',\n 'justify-center',\n 'gap-0.5',\n 'px-12',\n 'py-1',\n 'rounded-sm',\n 'cursor-pointer',\n 'text-text-950',\n 'text-xs',\n 'font-medium',\n 'hover:text-text',\n 'hover:bg-primary-600',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-offset-0',\n 'focus-visible:ring-indicator-info',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n 'disabled:pointer-events-none',\n ];\n\n const stateClasses = selected ? ['bg-primary-50', 'text-primary-950'] : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={`${allClasses} ${className}`}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-5 h-5\">{icon}</span>\n <span className=\"whitespace-nowrap\">{label}</span>\n </button>\n );\n }\n);\n\nNavButton.displayName = 'NavButton';\n\nexport default NavButton;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4D;AA6FtD;AAnCN,IAAM,gBAAY;AAAA,EAChB,CACE,EAAE,MAAM,OAAO,WAAW,OAAO,YAAY,IAAI,UAAU,GAAG,MAAM,GACpE,QACG;AAEH,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,WAAW,CAAC,iBAAiB,kBAAkB,IAAI,CAAC;AAEzE,UAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY,EAAE,KAAK,GAAG;AAE7D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW,GAAG,UAAU,IAAI,SAAS;AAAA,QACrC;AAAA,QACA,gBAAc;AAAA,QACb,GAAG;AAAA,QAEJ;AAAA,sDAAC,UAAK,WAAU,4CAA4C,gBAAK;AAAA,UACjE,4CAAC,UAAK,WAAU,qBAAqB,iBAAM;AAAA;AAAA;AAAA,IAC7C;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAExB,IAAO,oBAAQ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/NavButton/NavButton.tsx"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\n\n/**\n * NavButton component props interface\n */\ntype NavButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * NavButton component for Analytica Ensino platforms\n *\n * Um botão de navegação com ícone e texto para navegação principal.\n * Ideal para menus de navegação, sidebar, tabs de navegação, etc.\n *
|
|
1
|
+
{"version":3,"sources":["../../src/components/NavButton/NavButton.tsx"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\n\n/**\n * NavButton component props interface\n */\ntype NavButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * NavButton component for Analytica Ensino platforms\n *\n * Um botão de navegação com ícone e texto para navegação principal.\n * Ideal para menus de navegação, sidebar, tabs de navegação, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado para navegação\n *\n * @example\n * ```tsx\n * <NavButton\n * icon={<HomeIcon />}\n * label=\"Início\"\n * selected={false}\n * onClick={() => navigate('/')}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <NavButton\n * ref={buttonRef}\n * icon={<HomeIcon />}\n * label=\"Dashboard\"\n * selected={isActive}\n * onClick={() => setActiveTab('dashboard')}\n * />\n * ```\n */\nconst NavButton = forwardRef<HTMLButtonElement, NavButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'flex',\n 'flex-col',\n 'items-center',\n 'justify-center',\n 'gap-0.5',\n 'px-12',\n 'py-1',\n 'rounded-sm',\n 'cursor-pointer',\n 'text-text-950',\n 'text-xs',\n 'font-medium',\n 'hover:text-text',\n 'hover:bg-primary-600',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-offset-0',\n 'focus-visible:ring-indicator-info',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n 'disabled:pointer-events-none',\n ];\n\n const stateClasses = selected ? ['bg-primary-50', 'text-primary-950'] : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={`${allClasses} ${className}`}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-5 h-5\">{icon}</span>\n <span className=\"whitespace-nowrap\">{label}</span>\n </button>\n );\n }\n);\n\nNavButton.displayName = 'NavButton';\n\nexport default NavButton;\n"],"mappings":";AAAA,SAA0C,kBAAkB;AA6FtD,SAQE,KARF;AAnCN,IAAM,YAAY;AAAA,EAChB,CACE,EAAE,MAAM,OAAO,WAAW,OAAO,YAAY,IAAI,UAAU,GAAG,MAAM,GACpE,QACG;AAEH,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,WAAW,CAAC,iBAAiB,kBAAkB,IAAI,CAAC;AAEzE,UAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY,EAAE,KAAK,GAAG;AAE7D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW,GAAG,UAAU,IAAI,SAAS;AAAA,QACrC;AAAA,QACA,gBAAc;AAAA,QACb,GAAG;AAAA,QAEJ;AAAA,8BAAC,UAAK,WAAU,4CAA4C,gBAAK;AAAA,UACjE,oBAAC,UAAK,WAAU,qBAAqB,iBAAM;AAAA;AAAA;AAAA,IAC7C;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAExB,IAAO,oBAAQ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ProgressBar/ProgressBar.tsx","../../src/components/Text/Text.tsx"],"sourcesContent":["'use client';\n\nimport { 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 * Fully compatible with Next.js 15 and React 19.\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 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"]}
|