UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

661 lines (651 loc) 22.4 kB
"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/MultipleChoice/MultipleChoice.tsx var MultipleChoice_exports = {}; __export(MultipleChoice_exports, { MultipleChoiceList: () => MultipleChoiceList }); module.exports = __toCommonJS(MultipleChoice_exports); var import_react3 = require("react"); // src/components/CheckBox/CheckboxList.tsx var import_react2 = require("react"); var import_zustand = require("zustand"); // src/components/CheckBox/CheckBox.tsx 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/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/CheckBox/CheckBox.tsx var import_phosphor_react = require("phosphor-react"); var import_jsx_runtime2 = require("react/jsx-runtime"); var SIZE_CLASSES = { 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_CLASSES[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_runtime2.jsx)( import_phosphor_react.Minus, { size: sizeClasses.iconSize, weight: "bold", color: "currentColor" } ); } if (checked) { return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( import_phosphor_react.Check, { size: sizeClasses.iconSize, weight: "bold", color: "currentColor" } ); } return null; }; return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col", children: [ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)( "div", { className: cn( "flex flex-row items-center", sizeClasses.spacing, disabled ? "opacity-40" : "" ), children: [ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( "input", { ref, type: "checkbox", id: inputId, checked, disabled, onChange: handleChange, className: "sr-only", ...props } ), /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { htmlFor: inputId, className: checkboxClasses, children: renderIcon() }), label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( "div", { className: cn( "flex flex-row items-center", sizeClasses.labelHeight ), children: /* @__PURE__ */ (0, import_jsx_runtime2.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_runtime2.jsx)( Text_default, { size: "sm", weight: "normal", className: "mt-1.5", color: "text-error-600", children: errorMessage } ), helperText && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime2.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_jsx_runtime3 = 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_runtime3.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_runtime3.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/MultipleChoice/MultipleChoice.tsx var import_phosphor_react3 = require("phosphor-react"); // src/components/Badge/Badge.tsx var import_phosphor_react2 = require("phosphor-react"); var import_jsx_runtime4 = require("react/jsx-runtime"); var VARIANT_ACTION_CLASSES = { 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_CLASSES[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_runtime4.jsxs)( "div", { className: cn(baseClasses, variantClasses, sizeClasses, className), ...props, children: [ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_phosphor_react2.Bell, { size: 24, className: "text-current", "aria-hidden": "true" }), notificationActive && /* @__PURE__ */ (0, import_jsx_runtime4.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_runtime4.jsxs)( "div", { className: cn(baseClasses, variantClasses, sizeClasses, className), ...props, children: [ iconLeft && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: cn(baseClassesIcon, sizeClassesIcon), children: iconLeft }), children, iconRight && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: cn(baseClassesIcon, sizeClassesIcon), children: iconRight }) ] } ); }; var Badge_default = Badge; // src/components/MultipleChoice/MultipleChoice.tsx var import_jsx_runtime5 = require("react/jsx-runtime"); var MultipleChoiceList = ({ disabled = false, className = "", choices, name, selectedValues, onHandleSelectedValues, mode = "interactive" }) => { const [actualValue, setActualValue] = (0, import_react3.useState)(selectedValues); (0, import_react3.useEffect)(() => { setActualValue(selectedValues); }, [selectedValues]); const getStatusBadge = (status) => { switch (status) { case "correct": return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Badge_default, { variant: "solid", action: "success", iconLeft: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react3.CheckCircle, {}), children: "Resposta correta" }); case "incorrect": return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Badge_default, { variant: "solid", action: "error", iconLeft: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react3.XCircle, {}), children: "Resposta incorreta" }); default: return null; } }; const getStatusStyles = (status) => { 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`; } }; const renderVisualCheckbox = (isSelected, isDisabled) => { const checkboxClasses = cn( "w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center", isSelected ? "border-primary-950 bg-primary-950 text-text" : "border-border-400 bg-background", isDisabled && "opacity-40 cursor-not-allowed" ); return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: checkboxClasses, children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_phosphor_react3.Check, { size: 16, weight: "bold" }) }); }; if (mode === "readonly") { return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn("flex flex-col gap-2", className), children: choices.map((choice, i) => { const isSelected = actualValue?.includes(choice.value) || false; const statusStyles = getStatusStyles(choice.status); const statusBadge = getStatusBadge(choice.status); return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)( "div", { className: cn( "flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all", statusStyles, choice.disabled ? "opacity-50 cursor-not-allowed" : "" ), children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2 flex-1", children: [ renderVisualCheckbox(isSelected, choice.disabled || disabled), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( "span", { className: cn( "flex-1", isSelected || choice.status && choice.status != "neutral" ? "text-text-950" : "text-text-600", choice.disabled || disabled ? "cursor-not-allowed" : "cursor-default" ), children: choice.label } ) ] }), statusBadge && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex-shrink-0", children: statusBadge }) ] }, `readonly-${choice.value}-${i}` ); }) }); } return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( "div", { className: cn( "flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all", disabled ? "opacity-50 cursor-not-allowed" : "", className ), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( CheckboxList_default, { name, values: actualValue, onValuesChange: (v) => { setActualValue(v); onHandleSelectedValues?.(v); }, disabled, children: choices.map((choice, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)( "div", { className: "flex flex-row gap-2 items-center", children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( CheckboxListItem, { value: choice.value, id: `interactive-${choice.value}-${i}`, disabled: choice.disabled || disabled } ), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( "label", { htmlFor: `interactive-${choice.value}-${i}`, className: cn( "flex-1", actualValue?.includes(choice.value) ? "text-text-950" : "text-text-600", choice.disabled || disabled ? "cursor-not-allowed" : "cursor-pointer" ), children: choice.label } ) ] }, `interactive-${choice.value}-${i}` )) } ) } ); }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { MultipleChoiceList }); //# sourceMappingURL=index.js.map