analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
1,453 lines (1,446 loc) • 69.8 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/components/Card/Card.tsx
var Card_exports = {};
__export(Card_exports, {
CardActivitiesResults: () => CardActivitiesResults,
CardAudio: () => CardAudio,
CardBase: () => CardBase,
CardForum: () => CardForum,
CardPerformance: () => CardPerformance,
CardProgress: () => CardProgress,
CardQuestions: () => CardQuestions,
CardResults: () => CardResults,
CardSettings: () => CardSettings,
CardSimulado: () => CardSimulado,
CardSimulationHistory: () => CardSimulationHistory,
CardStatus: () => CardStatus,
CardSupport: () => CardSupport,
CardTest: () => CardTest,
CardTopic: () => CardTopic
});
module.exports = __toCommonJS(Card_exports);
var import_react = require("react");
// 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));
}
// src/components/Button/Button.tsx
var import_jsx_runtime = 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_runtime.jsxs)(
"button",
{
className: cn(baseClasses, variantClasses, sizeClasses, className),
disabled,
type,
...props,
children: [
iconLeft && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mr-2 flex items-center", children: iconLeft }),
children,
iconRight && /* @__PURE__ */ (0, import_jsx_runtime.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_runtime2 = 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_runtime2.jsxs)(
"div",
{
className: cn(baseClasses, variantClasses, sizeClasses, className),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_phosphor_react.Bell, { size: 24, className: "text-current", "aria-hidden": "true" }),
notificationActive && /* @__PURE__ */ (0, import_jsx_runtime2.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_runtime2.jsxs)(
"div",
{
className: cn(baseClasses, variantClasses, sizeClasses, className),
...props,
children: [
iconLeft && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: cn(baseClassesIcon, sizeClassesIcon), children: iconLeft }),
children,
iconRight && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: cn(baseClassesIcon, sizeClassesIcon), children: iconRight })
]
}
);
};
var Badge_default = Badge;
// src/components/Text/Text.tsx
var import_jsx_runtime3 = 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_runtime3.jsx)(
Component,
{
className: cn(baseClasses, sizeClasses, weightClasses, color, className),
...props,
children
}
);
};
var Text_default = Text;
// src/components/ProgressBar/ProgressBar.tsx
var import_jsx_runtime4 = require("react/jsx-runtime");
var SIZE_CLASSES3 = {
small: {
container: "h-1",
// 4px height (h-1 = 4px in Tailwind)
bar: "h-1",
// 4px height for the fill bar
spacing: "gap-2",
// 8px gap between label and progress bar
layout: "flex-col",
// vertical layout for small
borderRadius: "rounded-full"
// 9999px border radius
},
medium: {
container: "h-2",
// 8px height (h-2 = 8px in Tailwind)
bar: "h-2",
// 8px height for the fill bar
spacing: "gap-2",
// 8px gap between progress bar and label
layout: "flex-row items-center",
// horizontal layout for medium
borderRadius: "rounded-lg"
// 8px border radius
}
};
var VARIANT_CLASSES = {
blue: {
background: "bg-background-300",
// Background track color (#D5D4D4)
fill: "bg-primary-700"
// Blue for activity progress (#2271C4)
},
green: {
background: "bg-background-300",
// Background track color (#D5D4D4)
fill: "bg-success-200"
// Green for performance (#84D3A2)
}
};
var calculateProgressValues = (value, max) => {
const safeValue = isNaN(value) ? 0 : value;
const clampedValue = Math.max(0, Math.min(safeValue, max));
const percentage = max === 0 ? 0 : clampedValue / max * 100;
return { clampedValue, percentage };
};
var shouldShowHeader = (label, showPercentage, showHitCount) => {
return !!(label || showPercentage || showHitCount);
};
var getDisplayPriority = (showHitCount, showPercentage, label, clampedValue, max, percentage) => {
if (showHitCount) {
return {
type: "hitCount",
content: `${Math.round(clampedValue)} de ${max}`,
hasMetrics: true
};
}
if (showPercentage) {
return {
type: "percentage",
content: `${Math.round(percentage)}%`,
hasMetrics: true
};
}
return {
type: "label",
content: label,
hasMetrics: false
};
};
var getCompactLayoutConfig = ({
showPercentage,
showHitCount,
percentage,
clampedValue,
max,
label,
percentageClassName,
labelClassName
}) => {
const displayPriority = getDisplayPriority(
showHitCount,
showPercentage,
label,
clampedValue,
max,
percentage
);
return {
color: displayPriority.hasMetrics ? "text-primary-600" : "text-primary-700",
className: displayPriority.hasMetrics ? percentageClassName : labelClassName,
content: displayPriority.content
};
};
var getDefaultLayoutDisplayConfig = (size, label, showPercentage) => ({
showHeader: size === "small" && !!(label || showPercentage),
showPercentage: size === "medium" && showPercentage,
showLabel: size === "medium" && !!label && !showPercentage
// Only show label when percentage is not shown
});
var renderStackedHitCountDisplay = (showHitCount, showPercentage, clampedValue, max, percentage, percentageClassName) => {
if (!showHitCount && !showPercentage) return null;
const displayPriority = getDisplayPriority(
showHitCount,
showPercentage,
null,
// label is not relevant for stacked layout metrics display
clampedValue,
max,
percentage
);
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"div",
{
className: cn(
"text-xs font-medium leading-[14px] text-right",
percentageClassName
),
children: displayPriority.type === "hitCount" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-success-200", children: Math.round(clampedValue) }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "text-text-600", children: [
" de ",
max
] })
] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text_default, { size: "xs", weight: "medium", className: "text-success-200", children: [
Math.round(percentage),
"%"
] })
}
);
};
var ProgressBarBase = ({
clampedValue,
max,
percentage,
label,
variantClasses,
containerClassName,
fillClassName
}) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"div",
{
className: cn(
containerClassName,
variantClasses.background,
"overflow-hidden relative"
),
children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"progress",
{
value: clampedValue,
max,
"aria-label": typeof label === "string" ? `${label}: ${Math.round(percentage)}% complete` : `Progress: ${Math.round(percentage)}% of ${max}`,
className: "absolute inset-0 w-full h-full opacity-0"
}
),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"div",
{
className: cn(
fillClassName,
variantClasses.fill,
"transition-all duration-300 ease-out"
),
style: { width: `${percentage}%` }
}
)
]
}
);
var StackedLayout = ({
className,
label,
showPercentage,
showHitCount,
labelClassName,
percentageClassName,
clampedValue,
max,
percentage,
variantClasses,
dimensions
}) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"div",
{
className: cn(
"flex flex-col items-start gap-2",
dimensions.width,
dimensions.height,
className
),
children: [
shouldShowHeader(label, showPercentage, showHitCount) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-row justify-between items-center w-full h-[19px]", children: [
label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
Text_default,
{
as: "div",
size: "md",
weight: "medium",
className: cn("text-text-600 leading-[19px]", labelClassName),
children: label
}
),
renderStackedHitCountDisplay(
showHitCount,
showPercentage,
clampedValue,
max,
percentage,
percentageClassName
)
] }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
ProgressBarBase,
{
clampedValue,
max,
percentage,
label,
variantClasses,
containerClassName: "w-full h-2 rounded-lg",
fillClassName: "h-2 rounded-lg shadow-hard-shadow-3"
}
)
]
}
);
var CompactLayout = ({
className,
label,
showPercentage,
showHitCount,
labelClassName,
percentageClassName,
clampedValue,
max,
percentage,
variantClasses,
dimensions
}) => {
const {
color,
className: compactClassName,
content
} = getCompactLayoutConfig({
showPercentage,
showHitCount,
percentage,
clampedValue,
max,
label,
percentageClassName,
labelClassName
});
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"div",
{
className: cn(
"flex flex-col items-start gap-1",
dimensions.width,
dimensions.height,
className
),
children: [
shouldShowHeader(label, showPercentage, showHitCount) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
Text_default,
{
as: "div",
size: "sm",
weight: "medium",
color,
className: cn("leading-4 w-full", compactClassName),
children: content
}
),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
ProgressBarBase,
{
clampedValue,
max,
percentage,
label,
variantClasses,
containerClassName: "w-full h-1 rounded-full",
fillClassName: "h-1 rounded-full"
}
)
]
}
);
};
var DefaultLayout = ({
className,
size,
sizeClasses,
variantClasses,
label,
showPercentage,
labelClassName,
percentageClassName,
clampedValue,
max,
percentage
}) => {
const gapClass = size === "medium" ? "gap-2" : sizeClasses.spacing;
const progressBarClass = size === "medium" ? "flex-grow" : "w-full";
const displayConfig = getDefaultLayoutDisplayConfig(
size,
label,
showPercentage
);
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("flex", sizeClasses.layout, gapClass, className), children: [
displayConfig.showHeader && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-row items-center justify-between w-full", children: [
label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
Text_default,
{
as: "div",
size: "xs",
weight: "medium",
className: cn(
"text-text-950 leading-none tracking-normal text-center",
labelClassName
),
children: label
}
),
showPercentage && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
Text_default,
{
size: "xs",
weight: "medium",
className: cn(
"text-text-950 leading-none tracking-normal text-center",
percentageClassName
),
children: [
Math.round(percentage),
"%"
]
}
)
] }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
ProgressBarBase,
{
clampedValue,
max,
percentage,
label,
variantClasses,
containerClassName: cn(
progressBarClass,
sizeClasses.container,
sizeClasses.borderRadius
),
fillClassName: cn(
sizeClasses.bar,
sizeClasses.borderRadius,
"shadow-hard-shadow-3"
)
}
),
displayConfig.showPercentage && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
Text_default,
{
size: "xs",
weight: "medium",
className: cn(
"text-text-950 leading-none tracking-normal text-center flex-none",
percentageClassName
),
children: [
Math.round(percentage),
"%"
]
}
),
displayConfig.showLabel && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
Text_default,
{
as: "div",
size: "xs",
weight: "medium",
className: cn(
"text-text-950 leading-none tracking-normal text-center flex-none",
labelClassName
),
children: label
}
)
] });
};
var ProgressBar = ({
value,
max = 100,
size = "medium",
variant = "blue",
layout = "default",
label,
showPercentage = false,
showHitCount = false,
className = "",
labelClassName = "",
percentageClassName = "",
stackedWidth,
stackedHeight,
compactWidth,
compactHeight
}) => {
const { clampedValue, percentage } = calculateProgressValues(value, max);
const sizeClasses = SIZE_CLASSES3[size];
const variantClasses = VARIANT_CLASSES[variant];
if (layout === "stacked") {
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
StackedLayout,
{
className,
label,
showPercentage,
showHitCount,
labelClassName,
percentageClassName,
clampedValue,
max,
percentage,
variantClasses,
dimensions: {
width: stackedWidth ?? "w-[380px]",
height: stackedHeight ?? "h-[35px]"
}
}
);
}
if (layout === "compact") {
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
CompactLayout,
{
className,
label,
showPercentage,
showHitCount,
labelClassName,
percentageClassName,
clampedValue,
max,
percentage,
variantClasses,
dimensions: {
width: compactWidth ?? "w-[131px]",
height: compactHeight ?? "h-[24px]"
}
}
);
}
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
DefaultLayout,
{
className,
size,
sizeClasses,
variantClasses,
label,
showPercentage,
labelClassName,
percentageClassName,
clampedValue,
max,
percentage
}
);
};
var ProgressBar_default = ProgressBar;
// src/components/Card/Card.tsx
var import_phosphor_react2 = require("phosphor-react");
var import_jsx_runtime5 = require("react/jsx-runtime");
var CARD_BASE_CLASSES = {
default: "w-full bg-background border border-border-50 rounded-xl",
compact: "w-full bg-background border border-border-50 rounded-lg",
minimal: "w-full bg-background border border-border-100 rounded-md"
};
var CARD_PADDING_CLASSES = {
none: "",
small: "p-2",
medium: "p-4",
large: "p-6"
};
var CARD_MIN_HEIGHT_CLASSES = {
none: "",
small: "min-h-16",
medium: "min-h-20",
large: "min-h-24"
};
var CARD_LAYOUT_CLASSES = {
horizontal: "flex flex-row",
vertical: "flex flex-col"
};
var CARD_CURSOR_CLASSES = {
default: "",
pointer: "cursor-pointer"
};
var CardBase = (0, import_react.forwardRef)(
({
children,
variant = "default",
layout = "horizontal",
padding = "medium",
minHeight = "medium",
cursor = "default",
className = "",
...props
}, ref) => {
const baseClasses = CARD_BASE_CLASSES[variant];
const paddingClasses = CARD_PADDING_CLASSES[padding];
const minHeightClasses = CARD_MIN_HEIGHT_CLASSES[minHeight];
const layoutClasses = CARD_LAYOUT_CLASSES[layout];
const cursorClasses = CARD_CURSOR_CLASSES[cursor];
const combinedClasses = [
baseClasses,
paddingClasses,
minHeightClasses,
layoutClasses,
cursorClasses,
className
].filter(Boolean).join(" ");
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref, className: combinedClasses, ...props, children });
}
);
var ACTION_CARD_CLASSES = {
warning: "bg-warning-background",
success: "bg-success-300",
error: "bg-error-100",
info: "bg-info-background"
};
var ACTION_ICON_CLASSES = {
warning: "bg-warning-300 text-text",
success: "bg-yellow-300 text-text-950",
error: "bg-error-500 text-text",
info: "bg-info-500 text-text"
};
var ACTION_SUBTITLE_CLASSES = {
warning: "text-warning-600",
success: "text-success-700",
error: "text-error-700",
info: "text-info-700"
};
var ACTION_HEADER_CLASSES = {
warning: "text-warning-300",
success: "text-success-300",
error: "text-error-300",
info: "text-info-300"
};
var CardActivitiesResults = (0, import_react.forwardRef)(
({
icon,
title,
subTitle,
header,
extended = false,
action = "success",
description,
className,
...props
}, ref) => {
const actionCardClasses = ACTION_CARD_CLASSES[action];
const actionIconClasses = ACTION_ICON_CLASSES[action];
const actionSubTitleClasses = ACTION_SUBTITLE_CLASSES[action];
const actionHeaderClasses = ACTION_HEADER_CLASSES[action];
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
"div",
{
ref,
className: cn(
"w-full flex flex-col border border-border-50 bg-background rounded-xl",
className
),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
"div",
{
className: cn(
"flex flex-col gap-1 items-center justify-center p-4",
actionCardClasses,
extended ? "rounded-t-xl" : "rounded-xl"
),
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"span",
{
className: cn(
"size-7.5 rounded-full flex items-center justify-center",
actionIconClasses
),
children: icon
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
Text_default,
{
size: "2xs",
weight: "medium",
className: "text-text-800 uppercase truncate",
children: title
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"p",
{
className: cn("text-lg font-bold truncate", actionSubTitleClasses),
children: subTitle
}
)
]
}
),
extended && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-col items-center gap-2.5 pb-9.5 pt-2.5", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"p",
{
className: cn(
"text-2xs font-medium uppercase truncate",
actionHeaderClasses
),
children: header
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Badge_default, { size: "large", action: "info", children: description })
] })
]
}
);
}
);
var CardQuestions = (0, import_react.forwardRef)(
({
header,
state = "undone",
className,
onClickButton,
valueButton,
...props
}, ref) => {
const isDone = state === "done";
const stateLabel = isDone ? "Realizado" : "N\xE3o Realizado";
const buttonLabel = isDone ? "Ver Quest\xE3o" : "Responder";
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
CardBase,
{
ref,
layout: "horizontal",
padding: "medium",
minHeight: "medium",
className: cn("justify-between gap-4", className),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "font-bold text-xs text-text-950 truncate", children: header }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-row gap-6 items-center", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
Badge_default,
{
size: "medium",
variant: "solid",
action: isDone ? "success" : "error",
children: stateLabel
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex flex-row items-center gap-1 text-text-700 text-xs", children: [
isDone ? "Nota" : "Sem nota",
isDone && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Badge_default, { size: "medium", action: "success", children: "00" })
] })
] })
] }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
Button_default,
{
size: "extra-small",
onClick: () => onClickButton?.(valueButton),
className: "min-w-fit",
children: buttonLabel
}
) })
]
}
);
}
);
var CardProgress = (0, import_react.forwardRef)(
({
header,
subhead,
initialDate,
endDate,
progress = 0,
direction = "horizontal",
icon,
color = "#B7DFFF",
progressVariant = "blue",
showDates = true,
className,
...props
}, ref) => {
const isHorizontal = direction === "horizontal";
const contentComponent = {
horizontal: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
showDates && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-row gap-6 items-center", children: [
initialDate && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex flex-row gap-1 items-center text-2xs", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-text-800 font-semibold", children: "In\xEDcio" }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-text-600", children: initialDate })
] }),
endDate && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex flex-row gap-1 items-center text-2xs", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-text-800 font-semibold", children: "Fim" }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-text-600", children: endDate })
] })
] }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "grid grid-cols-[1fr_auto] items-center gap-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
ProgressBar_default,
{
size: "small",
value: progress,
variant: progressVariant,
"data-testid": "progress-bar"
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
Text_default,
{
size: "xs",
weight: "medium",
className: cn(
"text-text-950 leading-none tracking-normal text-center flex-none"
),
children: [
Math.round(progress),
"%"
]
}
)
] })
] }),
vertical: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-text-800", children: subhead })
};
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
CardBase,
{
ref,
layout: isHorizontal ? "horizontal" : "vertical",
padding: "none",
minHeight: "medium",
cursor: "pointer",
className: cn(isHorizontal ? "h-20" : "", className),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"div",
{
className: cn(
"flex justify-center items-center [&>svg]:size-6 text-text-950",
isHorizontal ? "min-w-[80px] min-h-[80px] rounded-l-xl" : "min-h-[50px] w-full rounded-t-xl",
!color.startsWith("#") ? `bg-${color}` : ""
),
style: color.startsWith("#") ? { backgroundColor: color } : void 0,
"data-testid": "icon-container",
children: icon
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
"div",
{
className: cn(
"p-4 flex flex-col justify-between w-full h-full",
!isHorizontal && "gap-4"
),
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text_default, { size: "sm", weight: "bold", className: "text-text-950 truncate", children: header }),
contentComponent[direction]
]
}
)
]
}
);
}
);
var CardTopic = (0, import_react.forwardRef)(
({
header,
subHead,
progress,
showPercentage = false,
progressVariant = "blue",
className = "",
...props
}, ref) => {
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
CardBase,
{
ref,
layout: "vertical",
padding: "small",
minHeight: "medium",
cursor: "pointer",
className: cn("justify-center gap-2 py-2 px-4", className),
...props,
children: [
subHead && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-text-600 text-2xs flex flex-row gap-1", children: subHead.map((text, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: text }),
index < subHead.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u2022" })
] }, `${text} - ${index}`)) }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-text-950 font-bold truncate", children: header }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "grid grid-cols-[1fr_auto] items-center gap-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
ProgressBar_default,
{
size: "small",
value: progress,
variant: progressVariant,
"data-testid": "progress-bar"
}
),
showPercentage && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
Text_default,
{
size: "xs",
weight: "medium",
className: cn(
"text-text-950 leading-none tracking-normal text-center flex-none"
),
children: [
Math.round(progress),
"%"
]
}
)
] })
]
}
);
}
);
var CardPerformance = (0, import_react.forwardRef)(
({
header,
progress,
description = "Sem dados ainda! Voc\xEA ainda n\xE3o fez um question\xE1rio neste assunto.",
actionVariant = "button",
progressVariant = "blue",
labelProgress = "",
className = "",
onClickButton,
valueButton,
...props
}, ref) => {
const hasProgress = progress !== void 0;
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
CardBase,
{
ref,
layout: "horizontal",
padding: "medium",
minHeight: "none",
className: cn(
actionVariant == "caret" ? "cursor-pointer" : "",
className
),
onClick: () => actionVariant == "caret" && onClickButton?.(valueButton),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w-full flex flex-col justify-between gap-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-row justify-between items-center gap-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-lg font-bold text-text-950 truncate flex-1 min-w-0", children: header }),
actionVariant === "button" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
Button_default,
{
variant: "outline",
size: "extra-small",
onClick: () => onClickButton?.(valueButton),
className: "min-w-fit flex-shrink-0",
children: "Ver Aula"
}
)
] }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-full", children: hasProgress ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
ProgressBar_default,
{
value: progress,
label: `${progress}% ${labelProgress}`,
variant: progressVariant
}
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-xs text-text-600 truncate", children: description }) })
] }),
actionVariant == "caret" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
import_phosphor_react2.CaretRight,
{
className: "size-4.5 text-text-800 cursor-pointer",
"data-testid": "caret-icon"
}
)
]
}
);
}
);
var CardResults = (0, import_react.forwardRef)(
({
header,
correct_answers,
incorrect_answers,
icon,
direction = "col",
color = "#B7DFFF",
className,
...props
}, ref) => {
const isRow = direction == "row";
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
CardBase,
{
ref,
layout: "horizontal",
padding: "none",
minHeight: "medium",
className: cn("items-center cursor-pointer pr-4", className),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"div",
{
className: cn(
"flex justify-center items-center [&>svg]:size-8 text-text-950 min-w-20 max-w-20 min-h-20 h-full rounded-l-xl"
),
style: {
backgroundColor: color
},
children: icon
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
"div",
{
className: cn(
"p-4 flex justify-between w-full h-full",
isRow ? "flex-row items-center gap-2" : "flex-col"
),
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm font-bold text-text-950 truncate flex-1 min-w-0", children: header }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex flex-row gap-1 items-center", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
Badge_default,
{
action: "success",
variant: "solid",
size: "large",
iconLeft: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react2.CheckCircle, {}),
children: [
correct_answers,
" Corretas"
]
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
Badge_default,
{
action: "error",
variant: "solid",
size: "large",
iconLeft: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react2.XCircle, {}),
children: [
incorrect_answers,
" Incorretas"
]
}
)
] })
]
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react2.CaretRight, { className: "min-w-6 min-h-6 text-text-800" })
]
}
);
}
);
var CardStatus = (0, import_react.forwardRef)(
({ header, className, status, label, ...props }, ref) => {
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
CardBase,
{
ref,
layout: "horizontal",
padding: "medium",
minHeight: "medium",
className: cn("items-center cursor-pointer", className),
...props,
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex justify-between w-full h-full flex-row items-center gap-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm font-bold text-text-950 truncate flex-1 min-w-0", children: header }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex flex-row gap-1 items-center flex-shrink-0", children: [
status && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
Badge_default,
{
action: status == "correct" ? "success" : "error",
variant: "solid",
size: "medium",
iconLeft: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react2.CheckCircle, {}),
children: status == "correct" ? "Correta" : "Incorreta"
}
),
label && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-text-800", children: label })
] }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react2.CaretRight, { className: "min-w-6 min-h-6 text-text-800 cursor-pointer flex-shrink-0 ml-2" })
] })
}
);
}
);
var CardSettings = (0, import_react.forwardRef)(
({ header, className, icon, ...props }, ref) => {
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
CardBase,
{
ref,
layout: "horizontal",
padding: "small",
minHeight: "none",
className: cn(
"border-none items-center gap-2 text-text-700",
className
),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "[&>svg]:size-6", children: icon }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "w-full text-sm truncate", children: header }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react2.CaretRight, { size: 24, className: "cursor-pointer" })
]
}
);
}
);
var CardSupport = (0, import_react.forwardRef)(
({ header, className, direction = "col", children, ...props }, ref) => {
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
CardBase,
{
ref,
layout: "horizontal",
padding: "medium",
minHeight: "none",
className: cn(
"border-none items-center gap-2 text-text-700",
className
),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
"div",
{
className: cn(
"w-full flex",
direction == "col" ? "flex-col" : "flex-row items-center"
),
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-text-950 font-bold truncate", children: header }) }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "flex flex-row gap-1", children })
]
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react2.CaretRight, { className: "text-text-800 cursor-pointer", size: 24 })
]
}
);
}
);
var CardForum = (0, import_react.forwardRef)(
({
title,
content,
comments,
onClickComments,
valueComments,
onClickProfile,
valueProfile,
className = "",
date,
hour,
...props
}, ref) => {
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
CardBase,
{
ref,
layout: "horizontal",
padding: "medium",
minHeight: "none",
variant: "minimal",
className: cn("w-auto h-auto gap-3", className),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"button",
{
type: "button",
"aria-label": "Ver perfil",
onClick: () => onClickProfile?.(valueProfile),
className: "min-w-8 h-8 rounded-full bg-background-950"
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-row gap-1 items-center flex-wrap", children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-xs font-semibold text-primary-700 truncate", children: title }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "text-xs text-text-600", children: [
"\u2022 ",
date,
" \u2022 ",
hour
] })
] }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-text-950 text-sm line-clamp-2 truncate", children: content }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
"button",
{
type: "button",
"aria-label": "Ver coment\xE1rios",
onClick: () => onClickComments?.(valueComments),
className: "text-text-600 flex flex-row gap-2 items-center",
children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react2.ChatCircleText, { "aria-hidden": "true", size: 16 }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "text-xs", children: [
comments,
" respostas"
] })
]
}
)
] })
]
}
);
}
);
var CardAudio = (0, import_react.forwardRef)(
({
src,
title,
onPlay,
onPause,
onEnded,
onAudioTimeUpdate,
loop = false,
preload = "metadata",
tracks,
className,
...props
}, ref) => {
const [isPlaying, setIsPlaying] = (0, import_react.useState)(false);
const [currentTime, setCurrentTime] = (0, import_react.useState)(0);
const [duration, setDuration] = (0, import_react.useState)(0);
const [volume, setVolume] = (0, import_react.useState)(1);
const [showVolumeControl, setShowVolumeControl] = (0, import_react.useState)(false);
const audioRef = (0, import_react.useRef)(null);
const formatTime = (time) => {
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60);
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
};
const handlePlayPause = () => {
if (isPlaying) {
audioRef.current?.pause();
setIsPlaying(false);
onPause?.();
} else {
audioRef.current?.play();
setIsPlaying(true);
onPlay?.();
}
};
const handleTimeUpdate = () => {
const current = audioRef.current?.currentTime ?? 0;
const total = audioRef.current?.duration ?? 0;
setCurrentTime(current);
setDuration(total);
onAudioTimeUpdate?.(current, total);
};
const handleLoadedMetadata = () => {
setDuration(audioRef.current?.duration ?? 0);
};
const handleEnded = () => {
setIsPlaying(false);
setCurrentTime(0);
onEnded?.();
};
const handleProgressClick = (e) => {
const rect = e.currentTarget.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const width = rect.