analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
310 lines (306 loc) • 9.66 kB
JavaScript
import {
HtmlMathRenderer_default
} from "./chunk-FN4G43WK.mjs";
import {
Badge_default
} from "./chunk-OEW3ST4F.mjs";
import {
CheckBox_default
} from "./chunk-VDUO65VK.mjs";
import {
cn
} from "./chunk-53ICLDGS.mjs";
// src/components/MultipleChoice/MultipleChoice.tsx
import { useEffect as useEffect2, useState } from "react";
// src/components/CheckBox/CheckboxList.tsx
import {
forwardRef,
useId,
useEffect,
useRef,
Children,
cloneElement,
isValidElement
} from "react";
import { create, useStore } from "zustand";
import { jsx } from "react/jsx-runtime";
var createCheckboxListStore = (name, defaultValues, disabled, onValuesChange) => 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) => Children.map(children, (child) => {
if (!isValidElement(child)) return child;
const typedChild = child;
const shouldInject = typedChild.type === CheckboxListItem;
return cloneElement(typedChild, {
...shouldInject ? { store } : {},
...typedChild.props.children ? { children: injectStore(typedChild.props.children, store) } : {}
});
});
var CheckboxList = forwardRef(
({
values: propValues,
defaultValues = [],
onValuesChange,
name: propName,
disabled = false,
className = "",
children,
...props
}, ref) => {
const generatedId = useId();
const name = propName || `checkbox-list-${generatedId}`;
const storeRef = useRef(null);
storeRef.current ??= createCheckboxListStore(
name,
defaultValues,
disabled,
onValuesChange
);
const store = storeRef.current;
const { setValues } = useStore(store, (s) => s);
useEffect(() => {
const currentValues = store.getState().values;
if (currentValues.length > 0 && onValuesChange) {
onValuesChange(currentValues);
}
}, []);
useEffect(() => {
if (propValues !== void 0) {
setValues(propValues);
}
}, [propValues, setValues]);
useEffect(() => {
store.setState({ disabled });
}, [disabled, store]);
return /* @__PURE__ */ 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 = 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
} = useStore(store);
const generatedId = useId();
const inputId = id ?? `checkbox-item-${generatedId}`;
const isChecked = groupValues.includes(value);
const isDisabled = groupDisabled || itemDisabled;
const currentState = isDisabled ? "disabled" : state;
return /* @__PURE__ */ 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
import { CheckCircleIcon } from "@phosphor-icons/react/dist/csr/CheckCircle";
import { XCircleIcon } from "@phosphor-icons/react/dist/csr/XCircle";
import { CheckIcon } from "@phosphor-icons/react/dist/csr/Check";
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
var MultipleChoiceList = ({
disabled = false,
className = "",
choices,
name,
selectedValues,
onHandleSelectedValues,
mode = "interactive" /* INTERACTIVE */
}) => {
const [actualValue, setActualValue] = useState(selectedValues);
useEffect2(() => {
setActualValue(
(prev) => JSON.stringify(prev) === JSON.stringify(selectedValues) ? prev : selectedValues
);
}, [selectedValues]);
const getStatusBadge = (status) => {
switch (status) {
case "correct" /* CORRECT */:
return /* @__PURE__ */ jsx2(
Badge_default,
{
variant: "solid",
action: "success",
iconLeft: /* @__PURE__ */ jsx2(CheckCircleIcon, {}),
children: "Resposta correta"
}
);
case "incorrect" /* INCORRECT */:
return /* @__PURE__ */ jsx2(Badge_default, { variant: "solid", action: "error", iconLeft: /* @__PURE__ */ jsx2(XCircleIcon, {}), children: "Resposta incorreta" });
default:
return null;
}
};
const getStatusStyles = (status) => {
switch (status) {
case "correct" /* CORRECT */:
return "bg-success-background border-success-300";
case "incorrect" /* 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__ */ jsx2("div", { className: checkboxClasses, children: isSelected && /* @__PURE__ */ jsx2(CheckIcon, { size: 16, weight: "bold" }) });
};
if (mode === "readonly") {
return /* @__PURE__ */ jsx2("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__ */ 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__ */ jsxs("div", { className: "flex items-center gap-2 flex-1", children: [
renderVisualCheckbox(isSelected, choice.disabled || disabled),
/* @__PURE__ */ jsx2(
HtmlMathRenderer_default,
{
content: choice.label,
className: cn(
"flex-1",
isSelected || choice.status && choice.status != "neutral" /* NEUTRAL */ ? "text-text-950" : "text-text-600",
choice.disabled || disabled ? "cursor-not-allowed" : "cursor-default"
)
}
)
] }),
statusBadge && /* @__PURE__ */ jsx2("div", { className: "flex-shrink-0", children: statusBadge })
]
},
`readonly-${choice.value}-${i}`
);
}) });
}
return /* @__PURE__ */ jsx2(
"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__ */ jsx2(
CheckboxList_default,
{
name,
values: actualValue,
onValuesChange: (v) => {
setActualValue(v);
onHandleSelectedValues?.(v);
},
disabled,
children: choices.map((choice, i) => /* @__PURE__ */ jsxs(
"div",
{
className: "flex flex-row gap-2 items-center",
children: [
/* @__PURE__ */ jsx2(
CheckboxListItem,
{
value: choice.value,
id: `interactive-${choice.value}-${i}`,
disabled: choice.disabled || disabled
}
),
/* @__PURE__ */ jsx2(
"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: /* @__PURE__ */ jsx2(HtmlMathRenderer_default, { content: choice.label })
}
)
]
},
`interactive-${choice.value}-${i}`
))
}
)
}
);
};
export {
CheckboxListItem,
CheckboxList_default,
MultipleChoiceList
};
//# sourceMappingURL=chunk-PZ2H7EXH.mjs.map