analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
1,345 lines (1,332 loc) • 67.5 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/components/ActivityCardQuestionBanks/ActivityCardQuestionBanks.tsx
var ActivityCardQuestionBanks_exports = {};
__export(ActivityCardQuestionBanks_exports, {
ActivityCardQuestionBanks: () => ActivityCardQuestionBanks
});
module.exports = __toCommonJS(ActivityCardQuestionBanks_exports);
// src/utils/utils.ts
var import_clsx = require("clsx");
var import_tailwind_merge = require("tailwind-merge");
function cn(...inputs) {
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
}
function getSubjectColorWithOpacity(hexColor, isDark) {
if (!hexColor) return void 0;
let color = hexColor.replace(/^#/, "").toLowerCase();
if (isDark) {
if (color.length === 8) {
color = color.slice(0, 6);
}
return `#${color}`;
} else {
let resultColor;
if (color.length === 6) {
resultColor = `#${color}4d`;
} else if (color.length === 8) {
resultColor = `#${color}`;
} else {
resultColor = `#${color}`;
}
return resultColor;
}
}
// src/components/Text/Text.tsx
var import_jsx_runtime = require("react/jsx-runtime");
var Text = ({
children,
size = "md",
weight = "normal",
color = "text-text-950",
as,
className = "",
...props
}) => {
let sizeClasses = "";
let weightClasses = "";
const sizeClassMap = {
"2xs": "text-2xs",
xs: "text-xs",
sm: "text-sm",
md: "text-md",
lg: "text-lg",
xl: "text-xl",
"2xl": "text-2xl",
"3xl": "text-3xl",
"4xl": "text-4xl",
"5xl": "text-5xl",
"6xl": "text-6xl"
};
sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;
const weightClassMap = {
hairline: "font-hairline",
light: "font-light",
normal: "font-normal",
medium: "font-medium",
semibold: "font-semibold",
bold: "font-bold",
extrabold: "font-extrabold",
black: "font-black"
};
weightClasses = weightClassMap[weight] ?? weightClassMap.normal;
const baseClasses = "font-primary";
const Component = as ?? "p";
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
Component,
{
className: cn(baseClasses, sizeClasses, weightClasses, color, className),
...props,
children
}
);
};
var Text_default = Text;
// src/components/Button/Button.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
var VARIANT_ACTION_CLASSES = {
solid: {
primary: "bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed",
positive: "bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed",
negative: "bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed"
},
outline: {
primary: "bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed",
positive: "bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed",
negative: "bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed"
},
link: {
primary: "bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed",
positive: "bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed",
negative: "bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed"
}
};
var SIZE_CLASSES = {
"extra-small": "text-xs px-3.5 py-2",
small: "text-sm px-4 py-2.5",
medium: "text-md px-5 py-2.5",
large: "text-lg px-6 py-3",
"extra-large": "text-lg px-7 py-3.5"
};
var Button = ({
children,
iconLeft,
iconRight,
size = "medium",
variant = "solid",
action = "primary",
className = "",
disabled,
type = "button",
...props
}) => {
const sizeClasses = SIZE_CLASSES[size];
const variantClasses = VARIANT_ACTION_CLASSES[variant][action];
const baseClasses = "inline-flex items-center justify-center rounded-full cursor-pointer font-medium";
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
"button",
{
className: cn(baseClasses, variantClasses, sizeClasses, className),
disabled,
type,
...props,
children: [
iconLeft && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "mr-2 flex items-center", children: iconLeft }),
children,
iconRight && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "ml-2 flex items-center", children: iconRight })
]
}
);
};
var Button_default = Button;
// src/components/Badge/Badge.tsx
var import_phosphor_react = require("phosphor-react");
var import_jsx_runtime3 = require("react/jsx-runtime");
var VARIANT_ACTION_CLASSES2 = {
solid: {
error: "bg-error-background text-error-700 focus-visible:outline-none",
warning: "bg-warning text-warning-800 focus-visible:outline-none",
success: "bg-success text-success-800 focus-visible:outline-none",
info: "bg-info text-info-800 focus-visible:outline-none",
muted: "bg-background-muted text-background-800 focus-visible:outline-none"
},
outlined: {
error: "bg-error text-error-700 border border-error-300 focus-visible:outline-none",
warning: "bg-warning text-warning-800 border border-warning-300 focus-visible:outline-none",
success: "bg-success text-success-800 border border-success-300 focus-visible:outline-none",
info: "bg-info text-info-800 border border-info-300 focus-visible:outline-none",
muted: "bg-background-muted text-background-800 border border-border-300 focus-visible:outline-none"
},
exams: {
exam1: "bg-exam-1 text-info-700 focus-visible:outline-none",
exam2: "bg-exam-2 text-typography-1 focus-visible:outline-none",
exam3: "bg-exam-3 text-typography-2 focus-visible:outline-none",
exam4: "bg-exam-4 text-success-700 focus-visible:outline-none"
},
examsOutlined: {
exam1: "bg-exam-1 text-info-700 border border-info-700 focus-visible:outline-none",
exam2: "bg-exam-2 text-typography-1 border border-typography-1 focus-visible:outline-none",
exam3: "bg-exam-3 text-typography-2 border border-typography-2 focus-visible:outline-none",
exam4: "bg-exam-4 text-success-700 border border-success-700 focus-visible:outline-none"
},
resultStatus: {
negative: "bg-error text-error-800 focus-visible:outline-none",
positive: "bg-success text-success-800 focus-visible:outline-none"
},
notification: "text-primary"
};
var SIZE_CLASSES2 = {
small: "text-2xs px-2 py-1",
medium: "text-xs px-2 py-1",
large: "text-sm px-2 py-1"
};
var SIZE_CLASSES_ICON = {
small: "size-3",
medium: "size-3.5",
large: "size-4"
};
var Badge = ({
children,
iconLeft,
iconRight,
size = "medium",
variant = "solid",
action = "error",
className = "",
notificationActive = false,
...props
}) => {
const sizeClasses = SIZE_CLASSES2[size];
const sizeClassesIcon = SIZE_CLASSES_ICON[size];
const variantActionMap = VARIANT_ACTION_CLASSES2[variant] || {};
const variantClasses = typeof variantActionMap === "string" ? variantActionMap : variantActionMap[action] ?? variantActionMap.muted ?? "";
const baseClasses = "inline-flex items-center justify-center rounded-xs font-normal gap-1 relative";
const baseClassesIcon = "flex items-center";
if (variant === "notification") {
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
"div",
{
className: cn(baseClasses, variantClasses, sizeClasses, className),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_phosphor_react.Bell, { size: 24, className: "text-current", "aria-hidden": "true" }),
notificationActive && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
"span",
{
"data-testid": "notification-dot",
className: "absolute top-[5px] right-[10px] block h-2 w-2 rounded-full bg-indicator-error ring-2 ring-white"
}
)
]
}
);
}
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
"div",
{
className: cn(baseClasses, variantClasses, sizeClasses, className),
...props,
children: [
iconLeft && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: cn(baseClassesIcon, sizeClassesIcon), children: iconLeft }),
children,
iconRight && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: cn(baseClassesIcon, sizeClassesIcon), children: iconRight })
]
}
);
};
var Badge_default = Badge;
// src/components/CheckBox/CheckBox.tsx
var import_react = require("react");
var import_phosphor_react2 = require("phosphor-react");
var import_jsx_runtime4 = require("react/jsx-runtime");
var SIZE_CLASSES3 = {
small: {
checkbox: "w-4 h-4",
// 16px x 16px
textSize: "sm",
spacing: "gap-1.5",
// 6px
borderWidth: "border-2",
iconSize: 14,
// pixels for Phosphor icons
labelHeight: "h-[21px]"
},
medium: {
checkbox: "w-5 h-5",
// 20px x 20px
textSize: "md",
spacing: "gap-2",
// 8px
borderWidth: "border-2",
iconSize: 16,
// pixels for Phosphor icons
labelHeight: "h-6"
},
large: {
checkbox: "w-6 h-6",
// 24px x 24px
textSize: "lg",
spacing: "gap-2",
// 8px
borderWidth: "border-[3px]",
// 3px border
iconSize: 20,
// pixels for Phosphor icons
labelHeight: "h-[27px]"
}
};
var BASE_CHECKBOX_CLASSES = "rounded border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none";
var STATE_CLASSES = {
default: {
unchecked: "border-border-400 bg-background hover:border-border-500",
checked: "border-primary-950 bg-primary-950 text-text hover:border-primary-800 hover:bg-primary-800"
},
hovered: {
unchecked: "border-border-500 bg-background",
checked: "border-primary-800 bg-primary-800 text-text"
},
focused: {
unchecked: "border-indicator-info bg-background ring-2 ring-indicator-info/20",
checked: "border-indicator-info bg-primary-950 text-text ring-2 ring-indicator-info/20"
},
invalid: {
unchecked: "border-error-700 bg-background hover:border-error-600",
checked: "border-error-700 bg-primary-950 text-text"
},
disabled: {
unchecked: "border-border-400 bg-background cursor-not-allowed opacity-40",
checked: "border-primary-600 bg-primary-600 text-text cursor-not-allowed opacity-40"
}
};
var CheckBox = (0, import_react.forwardRef)(
({
label,
size = "medium",
state = "default",
indeterminate = false,
errorMessage,
helperText,
className = "",
labelClassName = "",
checked: checkedProp,
disabled,
id,
onChange,
...props
}, ref) => {
const generatedId = (0, import_react.useId)();
const inputId = id ?? `checkbox-${generatedId}`;
const [internalChecked, setInternalChecked] = (0, import_react.useState)(false);
const isControlled = checkedProp !== void 0;
const checked = isControlled ? checkedProp : internalChecked;
const handleChange = (event) => {
if (!isControlled) {
setInternalChecked(event.target.checked);
}
onChange?.(event);
};
const currentState = disabled ? "disabled" : state;
const sizeClasses = SIZE_CLASSES3[size];
const checkVariant = checked || indeterminate ? "checked" : "unchecked";
const stylingClasses = STATE_CLASSES[currentState][checkVariant];
const borderWidthClass = state === "focused" || state === "hovered" && size === "large" ? "border-[3px]" : sizeClasses.borderWidth;
const checkboxClasses = cn(
BASE_CHECKBOX_CLASSES,
sizeClasses.checkbox,
borderWidthClass,
stylingClasses,
className
);
const renderIcon = () => {
if (indeterminate) {
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
import_phosphor_react2.Minus,
{
size: sizeClasses.iconSize,
weight: "bold",
color: "currentColor"
}
);
}
if (checked) {
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
import_phosphor_react2.Check,
{
size: sizeClasses.iconSize,
weight: "bold",
color: "currentColor"
}
);
}
return null;
};
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-col", children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"div",
{
className: cn(
"flex flex-row items-center",
sizeClasses.spacing,
disabled ? "opacity-40" : ""
),
children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"input",
{
ref,
type: "checkbox",
id: inputId,
checked,
disabled,
onChange: handleChange,
className: "sr-only",
...props
}
),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { htmlFor: inputId, className: checkboxClasses, children: renderIcon() }),
label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"div",
{
className: cn(
"flex flex-row items-center",
sizeClasses.labelHeight
),
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
Text_default,
{
as: "label",
htmlFor: inputId,
size: sizeClasses.textSize,
weight: "normal",
className: cn(
"cursor-pointer select-none leading-[150%] flex items-center font-roboto",
labelClassName
),
children: label
}
)
}
)
]
}
),
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
Text_default,
{
size: "sm",
weight: "normal",
className: "mt-1.5",
color: "text-error-600",
children: errorMessage
}
),
helperText && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
Text_default,
{
size: "sm",
weight: "normal",
className: "mt-1.5",
color: "text-text-500",
children: helperText
}
)
] });
}
);
CheckBox.displayName = "CheckBox";
var CheckBox_default = CheckBox;
// src/components/CheckBox/CheckboxList.tsx
var import_react2 = require("react");
var import_zustand = require("zustand");
var import_jsx_runtime5 = require("react/jsx-runtime");
var createCheckboxListStore = (name, defaultValues, disabled, onValuesChange) => (0, import_zustand.create)((set, get) => ({
values: defaultValues,
setValues: (values) => {
if (!get().disabled) {
set({ values });
get().onValuesChange?.(values);
}
},
toggleValue: (value) => {
if (!get().disabled) {
const currentValues = get().values;
const newValues = currentValues.includes(value) ? currentValues.filter((v) => v !== value) : [...currentValues, value];
set({ values: newValues });
get().onValuesChange?.(newValues);
}
},
onValuesChange,
disabled,
name
}));
var useCheckboxListStore = (externalStore) => {
if (!externalStore) {
throw new Error("CheckboxListItem must be used within a CheckboxList");
}
return externalStore;
};
var injectStore = (children, store) => import_react2.Children.map(children, (child) => {
if (!(0, import_react2.isValidElement)(child)) return child;
const typedChild = child;
const shouldInject = typedChild.type === CheckboxListItem;
return (0, import_react2.cloneElement)(typedChild, {
...shouldInject ? { store } : {},
...typedChild.props.children ? { children: injectStore(typedChild.props.children, store) } : {}
});
});
var CheckboxList = (0, import_react2.forwardRef)(
({
values: propValues,
defaultValues = [],
onValuesChange,
name: propName,
disabled = false,
className = "",
children,
...props
}, ref) => {
const generatedId = (0, import_react2.useId)();
const name = propName || `checkbox-list-${generatedId}`;
const storeRef = (0, import_react2.useRef)(null);
storeRef.current ??= createCheckboxListStore(
name,
defaultValues,
disabled,
onValuesChange
);
const store = storeRef.current;
const { setValues } = (0, import_zustand.useStore)(store, (s) => s);
(0, import_react2.useEffect)(() => {
const currentValues = store.getState().values;
if (currentValues.length > 0 && onValuesChange) {
onValuesChange(currentValues);
}
}, []);
(0, import_react2.useEffect)(() => {
if (propValues !== void 0) {
setValues(propValues);
}
}, [propValues, setValues]);
(0, import_react2.useEffect)(() => {
store.setState({ disabled });
}, [disabled, store]);
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"div",
{
ref,
className: cn("flex flex-col gap-2 w-full", className),
"aria-label": name,
...props,
children: injectStore(children, store)
}
);
}
);
CheckboxList.displayName = "CheckboxList";
var CheckboxListItem = (0, import_react2.forwardRef)(
({
value,
store: externalStore,
disabled: itemDisabled,
size = "medium",
state = "default",
className = "",
id,
...props
}, ref) => {
const store = useCheckboxListStore(externalStore);
const {
values: groupValues,
toggleValue,
disabled: groupDisabled,
name
} = (0, import_zustand.useStore)(store);
const generatedId = (0, import_react2.useId)();
const inputId = id ?? `checkbox-item-${generatedId}`;
const isChecked = groupValues.includes(value);
const isDisabled = groupDisabled || itemDisabled;
const currentState = isDisabled ? "disabled" : state;
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
CheckBox_default,
{
ref,
id: inputId,
name,
value,
checked: isChecked,
disabled: isDisabled,
size,
state: currentState,
className,
onChange: () => {
if (!isDisabled) {
toggleValue(value);
}
},
...props
}
);
}
);
CheckboxListItem.displayName = "CheckboxListItem";
var CheckboxList_default = CheckboxList;
// src/components/Radio/Radio.tsx
var import_react3 = require("react");
var import_zustand2 = require("zustand");
var import_jsx_runtime6 = require("react/jsx-runtime");
var SIZE_CLASSES4 = {
small: {
radio: "w-5 h-5",
textSize: "sm",
spacing: "gap-1.5",
borderWidth: "border-2",
dotSize: "w-2.5 h-2.5",
labelHeight: "h-5"
},
medium: {
radio: "w-6 h-6",
textSize: "md",
spacing: "gap-2",
borderWidth: "border-2",
dotSize: "w-3 h-3",
labelHeight: "h-6"
},
large: {
radio: "w-7 h-7",
textSize: "lg",
spacing: "gap-2",
borderWidth: "border-2",
dotSize: "w-3.5 h-3.5",
labelHeight: "h-7"
},
extraLarge: {
radio: "w-8 h-8",
textSize: "xl",
spacing: "gap-3",
borderWidth: "border-2",
dotSize: "w-4 h-4",
labelHeight: "h-8"
}
};
var BASE_RADIO_CLASSES = "rounded-full border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none";
var STATE_CLASSES2 = {
default: {
unchecked: "border-border-400 bg-background hover:border-border-500",
checked: "border-primary-950 bg-background hover:border-primary-800"
},
hovered: {
unchecked: "border-border-500 bg-background",
checked: "border-info-700 bg-background"
},
focused: {
unchecked: "border-border-400 bg-background",
checked: "border-primary-950 bg-background"
},
invalid: {
unchecked: "border-border-400 bg-background",
checked: "border-primary-950 bg-background"
},
disabled: {
unchecked: "border-border-400 bg-background cursor-not-allowed",
checked: "border-primary-950 bg-background cursor-not-allowed"
}
};
var DOT_CLASSES = {
default: "bg-primary-950",
hovered: "bg-info-700",
focused: "bg-primary-950",
invalid: "bg-primary-950",
disabled: "bg-primary-950"
};
var Radio = (0, import_react3.forwardRef)(
({
label,
size = "medium",
state = "default",
errorMessage,
helperText,
className = "",
labelClassName = "",
checked: checkedProp,
defaultChecked = false,
disabled,
id,
name,
value,
onChange,
...props
}, ref) => {
const generatedId = (0, import_react3.useId)();
const inputId = id ?? `radio-${generatedId}`;
const inputRef = (0, import_react3.useRef)(null);
const [internalChecked, setInternalChecked] = (0, import_react3.useState)(defaultChecked);
const isControlled = checkedProp !== void 0;
const checked = isControlled ? checkedProp : internalChecked;
const handleChange = (event) => {
const newChecked = event.target.checked;
if (!isControlled) {
setInternalChecked(newChecked);
}
if (event.target) {
event.target.blur();
}
onChange?.(event);
};
const currentState = disabled ? "disabled" : state;
const sizeClasses = SIZE_CLASSES4[size];
const actualRadioSize = sizeClasses.radio;
const actualDotSize = sizeClasses.dotSize;
const radioVariant = checked ? "checked" : "unchecked";
const stylingClasses = STATE_CLASSES2[currentState][radioVariant];
const getBorderWidth = () => {
if (currentState === "focused") {
return "border-2";
}
return sizeClasses.borderWidth;
};
const borderWidthClass = getBorderWidth();
const radioClasses = cn(
BASE_RADIO_CLASSES,
actualRadioSize,
borderWidthClass,
stylingClasses,
className
);
const dotClasses = cn(
actualDotSize,
"rounded-full",
DOT_CLASSES[currentState],
"transition-all duration-200"
);
const isWrapperNeeded = currentState === "focused" || currentState === "invalid";
const wrapperBorderColor = currentState === "focused" ? "border-indicator-info" : "border-indicator-error";
const getTextColor = () => {
if (currentState === "disabled") {
return checked ? "text-text-900" : "text-text-600";
}
if (currentState === "focused") {
return "text-text-900";
}
return checked ? "text-text-900" : "text-text-600";
};
const getCursorClass = () => {
return currentState === "disabled" ? "cursor-not-allowed" : "cursor-pointer";
};
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col", children: [
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
"div",
{
className: cn(
"flex flex-row items-center",
isWrapperNeeded ? cn("p-1 border-2", wrapperBorderColor, "rounded-lg gap-1.5") : sizeClasses.spacing,
disabled ? "opacity-40" : ""
),
children: [
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
"input",
{
ref: (node) => {
inputRef.current = node;
if (typeof ref === "function") ref(node);
else if (ref) ref.current = node;
},
type: "radio",
id: inputId,
checked,
disabled,
name,
value,
onChange: handleChange,
className: "sr-only",
style: {
position: "absolute",
left: "-9999px",
visibility: "hidden"
},
...props
}
),
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
"button",
{
type: "button",
className: radioClasses,
disabled,
"aria-pressed": checked,
onClick: (e) => {
e.preventDefault();
if (!disabled) {
if (inputRef.current) {
inputRef.current.click();
inputRef.current.blur();
}
}
},
onKeyDown: (e) => {
if ((e.key === "Enter" || e.key === " ") && !disabled) {
e.preventDefault();
if (inputRef.current) {
inputRef.current.click();
inputRef.current.blur();
}
}
},
children: checked && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: dotClasses })
}
),
label && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
"div",
{
className: cn(
"flex flex-row items-center",
sizeClasses.labelHeight,
"flex-1 min-w-0"
),
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
Text_default,
{
as: "label",
htmlFor: inputId,
size: sizeClasses.textSize,
weight: "normal",
className: cn(
getCursorClass(),
"select-none leading-normal flex items-center font-roboto truncate",
labelClassName
),
color: getTextColor(),
children: label
}
)
}
)
]
}
),
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
Text_default,
{
size: "sm",
weight: "normal",
className: "mt-1.5 truncate",
color: "text-error-600",
children: errorMessage
}
),
helperText && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
Text_default,
{
size: "sm",
weight: "normal",
className: "mt-1.5 truncate",
color: "text-text-500",
children: helperText
}
)
] });
}
);
Radio.displayName = "Radio";
var createRadioGroupStore = (name, defaultValue, disabled, onValueChange) => (0, import_zustand2.create)((set, get) => ({
value: defaultValue,
setValue: (value) => {
if (!get().disabled) {
set({ value });
get().onValueChange?.(value);
}
},
onValueChange,
disabled,
name
}));
var useRadioGroupStore = (externalStore) => {
if (!externalStore) {
throw new Error("RadioGroupItem must be used within a RadioGroup");
}
return externalStore;
};
var injectStore2 = (children, store) => import_react3.Children.map(children, (child) => {
if (!(0, import_react3.isValidElement)(child)) return child;
const typedChild = child;
const shouldInject = typedChild.type === RadioGroupItem;
return (0, import_react3.cloneElement)(typedChild, {
...shouldInject ? { store } : {},
...typedChild.props.children ? { children: injectStore2(typedChild.props.children, store) } : {}
});
});
var RadioGroup = (0, import_react3.forwardRef)(
({
value: propValue,
defaultValue = "",
onValueChange,
name: propName,
disabled = false,
className = "",
children,
...props
}, ref) => {
const generatedId = (0, import_react3.useId)();
const name = propName || `radio-group-${generatedId}`;
const storeRef = (0, import_react3.useRef)(null);
storeRef.current ??= createRadioGroupStore(
name,
defaultValue,
disabled,
onValueChange
);
const store = storeRef.current;
const { setValue } = (0, import_zustand2.useStore)(store, (s) => s);
(0, import_react3.useEffect)(() => {
const currentValue = store.getState().value;
if (currentValue && onValueChange) {
onValueChange(currentValue);
}
}, []);
(0, import_react3.useEffect)(() => {
if (propValue !== void 0) {
setValue(propValue);
}
}, [propValue, setValue]);
(0, import_react3.useEffect)(() => {
store.setState({ disabled });
}, [disabled, store]);
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
"div",
{
ref,
className,
role: "radiogroup",
"aria-label": name,
...props,
children: injectStore2(children, store)
}
);
}
);
RadioGroup.displayName = "RadioGroup";
var RadioGroupItem = (0, import_react3.forwardRef)(
({
value,
store: externalStore,
disabled: itemDisabled,
size = "medium",
state = "default",
className = "",
id,
...props
}, ref) => {
const store = useRadioGroupStore(externalStore);
const {
value: groupValue,
setValue,
disabled: groupDisabled,
name
} = (0, import_zustand2.useStore)(store);
const generatedId = (0, import_react3.useId)();
const inputId = id ?? `radio-item-${generatedId}`;
const isChecked = groupValue === value;
const isDisabled = groupDisabled || itemDisabled;
const currentState = isDisabled ? "disabled" : state;
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
Radio,
{
ref,
id: inputId,
name,
value,
checked: isChecked,
disabled: isDisabled,
size,
state: currentState,
className,
onChange: (e) => {
if (e.target.checked && !isDisabled) {
setValue(value);
}
},
...props
}
);
}
);
RadioGroupItem.displayName = "RadioGroupItem";
// src/components/Alternative/Alternative.tsx
var import_phosphor_react3 = require("phosphor-react");
var import_react4 = require("react");
var import_jsx_runtime7 = require("react/jsx-runtime");
var AlternativesList = ({
alternatives,
name,
defaultValue,
value,
onValueChange,
disabled = false,
layout = "default",
className = "",
mode = "interactive",
selectedValue
}) => {
const uniqueId = (0, import_react4.useId)();
const groupName = name || `alternatives-${uniqueId}`;
const [actualValue, setActualValue] = (0, import_react4.useState)(value);
const isReadonly = mode === "readonly";
const getStatusStyles = (status, isReadonly2) => {
const hoverClass = isReadonly2 ? "" : "hover:bg-background-50";
switch (status) {
case "correct":
return "bg-success-background border-success-300";
case "incorrect":
return "bg-error-background border-error-300";
default:
return `bg-background border-border-100 ${hoverClass}`;
}
};
const getStatusBadge = (status) => {
switch (status) {
case "correct":
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Badge_default, { variant: "solid", action: "success", iconLeft: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_phosphor_react3.CheckCircle, {}), children: "Resposta correta" });
case "incorrect":
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Badge_default, { variant: "solid", action: "error", iconLeft: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_phosphor_react3.XCircle, {}), children: "Resposta incorreta" });
default:
return null;
}
};
const getLayoutClasses = () => {
switch (layout) {
case "compact":
return "gap-2";
case "detailed":
return "gap-4";
default:
return "gap-3.5";
}
};
const renderReadonlyAlternative = (alternative) => {
const alternativeId = alternative.value;
const isUserSelected = selectedValue === alternative.value;
const isCorrectAnswer = alternative.status === "correct";
let displayStatus = void 0;
if (isUserSelected && !isCorrectAnswer) {
displayStatus = "incorrect";
} else if (isCorrectAnswer) {
displayStatus = "correct";
}
const statusStyles = getStatusStyles(displayStatus, true);
const statusBadge = getStatusBadge(displayStatus);
const renderRadio = () => {
const radioClasses = `w-6 h-6 rounded-full border-2 cursor-default transition-all duration-200 flex items-center justify-center ${isUserSelected ? "border-primary-950 bg-background" : "border-border-400 bg-background"}`;
const dotClasses = "w-3 h-3 rounded-full bg-primary-950 transition-all duration-200";
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: radioClasses, children: isUserSelected && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: dotClasses }) });
};
if (layout === "detailed") {
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
"div",
{
className: cn(
"border-2 rounded-lg p-4 w-full",
statusStyles,
alternative.disabled ? "opacity-50" : ""
),
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-start gap-3 flex-1", children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mt-1", children: renderRadio() }),
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex-1", children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
"p",
{
className: cn(
"block font-medium",
selectedValue === alternative.value || statusBadge ? "text-text-950" : "text-text-600"
),
children: alternative.label
}
),
alternative.description && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-sm text-text-600 mt-1", children: alternative.description })
] })
] }),
statusBadge && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex-shrink-0", children: statusBadge })
] })
},
alternativeId
);
}
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
"div",
{
className: cn(
"flex flex-row justify-between items-start gap-2 p-2 rounded-lg w-full",
statusStyles,
alternative.disabled ? "opacity-50" : ""
),
children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-2 flex-1", children: [
renderRadio(),
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
"span",
{
className: cn(
"flex-1",
selectedValue === alternative.value || statusBadge ? "text-text-950" : "text-text-600"
),
children: alternative.label
}
)
] }),
statusBadge && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex-shrink-0", children: statusBadge })
]
},
alternativeId
);
};
if (isReadonly) {
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
"div",
{
className: cn("flex flex-col", getLayoutClasses(), "w-full", className),
children: alternatives.map(
(alternative) => renderReadonlyAlternative(alternative)
)
}
);
}
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
RadioGroup,
{
name: groupName,
defaultValue,
value,
onValueChange: (value2) => {
setActualValue(value2);
onValueChange?.(value2);
},
disabled,
className: cn("flex flex-col", getLayoutClasses(), className),
children: alternatives.map((alternative, index) => {
const alternativeId = alternative.value || `alt-${index}`;
const statusStyles = getStatusStyles(alternative.status, false);
const statusBadge = getStatusBadge(alternative.status);
if (layout === "detailed") {
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
"div",
{
className: cn(
"border-2 rounded-lg p-4 transition-all",
statusStyles,
alternative.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"
),
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-start gap-3 flex-1", children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
RadioGroupItem,
{
value: alternative.value,
id: alternativeId,
disabled: alternative.disabled,
className: "mt-1"
}
),
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex-1", children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
"label",
{
htmlFor: alternativeId,
className: cn(
"block font-medium",
actualValue === alternative.value ? "text-text-950" : "text-text-600",
alternative.disabled ? "cursor-not-allowed" : "cursor-pointer"
),
children: alternative.label
}
),
alternative.description && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-sm text-text-600 mt-1", children: alternative.description })
] })
] }),
statusBadge && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex-shrink-0", children: statusBadge })
] })
},
alternativeId
);
}
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
"div",
{
className: cn(
"flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all",
statusStyles,
alternative.disabled ? "opacity-50 cursor-not-allowed" : ""
),
children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-2 flex-1", children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
RadioGroupItem,
{
value: alternative.value,
id: alternativeId,
disabled: alternative.disabled
}
),
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
"label",
{
htmlFor: alternativeId,
className: cn(
"flex-1",
actualValue === alternative.value ? "text-text-950" : "text-text-600",
alternative.disabled ? "cursor-not-allowed" : "cursor-pointer"
),
children: alternative.label
}
)
] }),
statusBadge && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex-shrink-0", children: statusBadge })
]
},
alternativeId
);
})
}
);
};
var HeaderAlternative = (0, import_react4.forwardRef)(
({ className, title, subTitle, content, ...props }, ref) => {
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
"div",
{
ref,
className: cn(
"bg-background p-4 flex flex-col gap-4 rounded-xl",
className
),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "flex flex-col", children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-text-950 font-bold text-lg", children: title }),
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-text-700 text-sm ", children: subTitle })
] }),
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-text-950 text-md", children: content })
]
}
);
}
);
// src/components/IconRender/IconRender.tsx
var import_react5 = require("react");
var PhosphorIcons = __toESM(require("phosphor-react"));
// src/assets/icons/subjects/ChatPT.tsx
var import_jsx_runtime8 = require("react/jsx-runtime");
var ChatPT = ({ size, color }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
"svg",
{
width: size,
height: size,
viewBox: "0 0 32 32",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
"path",
{
d: "M27 6H5.00004C4.4696 6 3.9609 6.21071 3.58582 6.58579C3.21075 6.96086 3.00004 7.46957 3.00004 8V28C2.99773 28.3814 3.10562 28.7553 3.31074 29.0768C3.51585 29.3984 3.80947 29.6538 4.15629 29.8125C4.42057 29.9356 4.7085 29.9995 5.00004 30C5.46954 29.9989 5.92347 29.8315 6.28129 29.5275L6.29254 29.5187L10.375 26H27C27.5305 26 28.0392 25.7893 28.4142 25.4142C28.7893 25.0391 29 24.5304 29 24V8C29 7.46957 28.7893 6.96086 28.4142 6.58579C28.0392 6.21071 27.5305 6 27 6ZM27 24H10C9.75992 24.0001 9.52787 24.0866 9.34629 24.2437L5.00004 28V8H27V24Z",
fill: color
}
),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
"path",
{
d: "M21.1758 12V20.5312H19.7168V12H21.1758ZM23.8535 12V13.1719H17.0625V12H23.8535Z",
fill: color
}
),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
"path",
{
d: "M13.2402 17.3496H11.0195V16.1836H13.2402C13.627 16.1836 13.9395 16.1211 14.1777 15.9961C14.416 15.8711 14.5898 15.6992 14.6992 15.4805C14.8125 15.2578 14.8691 15.0039 14.8691 14.7188C14.8691 14.4492 14.8125 14.1973 14.6992 13.9629C14.5898 13.7246 14.416 13.5332 14.1777 13.3887C13.9395 13.2441 13.627 13.1719 13.2402 13.1719H11.4707V20.5312H10V12H13.2402C13.9004 12 14.4609 12.1172 14.9219 12.3516C15.3867 12.582 15.7402 12.9023 15.9824 13.3125C16.2246 13.7188 16.3457 14.1836 16.3457 14.707C16.3457 15.2578 16.2246 15.7305 15.9824 16.125C15.7402 16.5195 15.3867 16.8223 14.9219 17.0332C14.4609 17.2441 13.9004 17.3496 13.2402 17.3496Z",
fill: color
}
)
]
}
);
// src/assets/icons/subjects/ChatEN.tsx
var import_jsx_runtime9 = require("react/jsx-runtime");
var ChatEN = ({ size, color }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
"svg",
{
width: size,
height: size,
viewBox: "0 0 32 32",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
children: [
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
"path",
{
d: "M27 6H5.00004C4.4696 6 3.9609 6.21071 3.58582 6.58579C3.21075 6.96086 3.00004 7.46957 3.00004 8V28C2.99773 28.3814 3.10562 28.7553 3.31074 29.0768C3.51585 29.3984 3.80947 29.6538 4.15629 29.8125C4.42057 29.9356 4.7085 29.9995 5.00004 30C5.46954 29.9989 5.92347 29.8315 6.28129 29.5275L6.29254 29.5187L10.375 26H27C27.5305 26 28.0392 25.7893 28.4142 25.4142C28.7893 25.0391 29 24.5304 29 24V8C29 7.46957 28.7893 6.96086 28.4142 6.58579C28.0392 6.21071 27.5305 6 27 6ZM27 24H10C9.75992 24.0001 9.52787 24.0866 9.34629 24.2437L5.00004 28V8H27V24Z",
fill: color
}
),
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
"path",
{
d: "M22.5488 12V20.5312H21.0781L17.252 14.4199V20.5312H15.7812V12H17.252L21.0898 18.123V12H22.5488Z",
fill: color
}
),
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
"path",
{
d: "M14.584 19.3652V20.5312H10.0547V19.3652H14.584ZM10.4707 12V20.5312H9V12H10.4707ZM13.9922 15.5625V16.7109H10.0547V15.5625H13.9922ZM14.5547 12V13.1719H10.0547V12H14.5547Z",
fill: color
}
)
]
}
);
// src/assets/icons/subjects/ChatES.tsx
var import_jsx_runtime10 = require("react/jsx-runtime");
var ChatES = ({ size, color }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
"svg",
{
width: size,
height: size,
viewBox: "0 0 32 32",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
children: [
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
"path",
{
d: "M27 6H5.00004C4.4696 6 3.9609 6.21071 3.58582 6.58579C3.21075 6.96086 3.00004 7.46957 3.00004 8V28C2.99773 28.3814 3.10562 28.7553 3.31074 29.0768C3.51585 29.3984 3.80947 29.6538 4.15629 29.8125C4.42057 29.9356 4.7085 29.9995 5.00004 30C5.46954 29.9989 5.92347 29.8315 6.28129 29.5275L6.29254 29.5187L10.375 26H27C27.5305 26 28.0392 25.7893 28.4142 25.4142C28.7893 25.0391 29 24.5304 29 24V8C29 7.46957 28.7893 6.96086 28.4142 6.58579C28.0392 6.21071 27.5305 6 27 6ZM27 24H10C9.75992 24.0001 9.52787 24.0866 9.34629 24.2437L5.00004 28V8H27V24Z",
fill: color
}
),
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
"path",
{
d: "M21.1426 17.8027C21.1426 17.627 21.1152 17.4707 21.0605 17.334C21.0098 17.1973 20.918 17.0723 20.7852 16.959C20.6523 16.8457 20.4648 16.7363 20.2227 16.6309C19.9844 16.5215 19.6797 16.4102 19.3086 16.2969C18.9023 16.1719 18.5273 16.0332 18.1836 15.8809C17.8438 15.7246 17.5469 15.5449 17.293 15.3418C17.0391 15.1348 16.8418 14.8984 16.7012 14.6328C16.5605 14.3633 16.4902 14.0527 16.4902 13.7012C16.4902 13.3535 16.5625 13.0371 16.707 12.752C16.8555 12.4668