najm-kit 0.0.27 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +8 -1
- package/dist/index.mjs +76 -14
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2228,9 +2228,16 @@ interface UseFormSubmissionOptions {
|
|
|
2228
2228
|
}
|
|
2229
2229
|
interface FormSubmissionState {
|
|
2230
2230
|
formDataRef: React.MutableRefObject<Record<string, any>>;
|
|
2231
|
-
handleStepSubmit: (stepData: any) => Promise<
|
|
2231
|
+
handleStepSubmit: (stepData: any) => Promise<StepSubmitResult>;
|
|
2232
2232
|
getStepDefaultValues: (stepId: string) => Record<string, any>;
|
|
2233
2233
|
}
|
|
2234
|
+
type StepSubmitResult = {
|
|
2235
|
+
ok: true;
|
|
2236
|
+
} | {
|
|
2237
|
+
ok: false;
|
|
2238
|
+
error: any;
|
|
2239
|
+
data: Record<string, any>;
|
|
2240
|
+
};
|
|
2234
2241
|
declare function useFormSubmission({ steps, schema, defaultValues, onSubmit, currentStep, isLastStep, handleNext, markStepCompleted, reset, }: UseFormSubmissionOptions): FormSubmissionState;
|
|
2235
2242
|
|
|
2236
2243
|
interface NTableClassNames {
|
package/dist/index.mjs
CHANGED
|
@@ -7709,25 +7709,41 @@ function useFormSubmission({
|
|
|
7709
7709
|
if (stepId) {
|
|
7710
7710
|
formDataRef.current = { ...formDataRef.current, ...stepData };
|
|
7711
7711
|
}
|
|
7712
|
-
markStepCompleted(currentStep - 1);
|
|
7713
7712
|
if (!isLastStep) {
|
|
7713
|
+
markStepCompleted(currentStep - 1);
|
|
7714
7714
|
handleNext();
|
|
7715
|
+
return { ok: true };
|
|
7715
7716
|
} else {
|
|
7716
7717
|
const fullData = { ...formDataRef.current };
|
|
7718
|
+
let submitData = fullData;
|
|
7717
7719
|
if (schema?.parse) {
|
|
7718
|
-
const
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7720
|
+
const result = schema.safeParse?.(fullData);
|
|
7721
|
+
if (result) {
|
|
7722
|
+
if (!result.success) {
|
|
7723
|
+
return { ok: false, error: result.error, data: fullData };
|
|
7724
|
+
}
|
|
7725
|
+
submitData = result.data;
|
|
7726
|
+
} else {
|
|
7727
|
+
submitData = schema.parse(fullData);
|
|
7728
|
+
}
|
|
7722
7729
|
}
|
|
7730
|
+
await onSubmit(submitData);
|
|
7731
|
+
markStepCompleted(currentStep - 1);
|
|
7723
7732
|
reset();
|
|
7724
|
-
formDataRef.current = {};
|
|
7733
|
+
formDataRef.current = defaultValues ?? {};
|
|
7734
|
+
return { ok: true };
|
|
7725
7735
|
}
|
|
7726
7736
|
},
|
|
7727
|
-
[steps, currentStep, isLastStep, schema, onSubmit, handleNext, markStepCompleted, reset]
|
|
7737
|
+
[steps, currentStep, isLastStep, schema, onSubmit, handleNext, markStepCompleted, reset, defaultValues]
|
|
7728
7738
|
);
|
|
7729
7739
|
return { formDataRef, handleStepSubmit, getStepDefaultValues };
|
|
7730
7740
|
}
|
|
7741
|
+
function issuePath(issue) {
|
|
7742
|
+
return issue.path?.map(String).join(".") ?? "";
|
|
7743
|
+
}
|
|
7744
|
+
function matchesFieldPath(path, field) {
|
|
7745
|
+
return path === field || path.startsWith(`${field}.`) || field.startsWith(`${path}.`);
|
|
7746
|
+
}
|
|
7731
7747
|
function WizardForm({
|
|
7732
7748
|
steps,
|
|
7733
7749
|
schema,
|
|
@@ -7765,6 +7781,15 @@ function WizardForm({
|
|
|
7765
7781
|
});
|
|
7766
7782
|
const currentStepConfig = nav.currentStepConfig;
|
|
7767
7783
|
const stepDefaults = getStepDefaultValues(currentStepConfig.id);
|
|
7784
|
+
const pendingIssuesRef = useRef(null);
|
|
7785
|
+
const getIssueStepIndex = (issue) => {
|
|
7786
|
+
const path = issuePath(issue);
|
|
7787
|
+
if (!path) return nav.currentStep - 1;
|
|
7788
|
+
const stepIndex = steps.findIndex(
|
|
7789
|
+
(step) => step.fields?.some((field) => matchesFieldPath(path, field))
|
|
7790
|
+
);
|
|
7791
|
+
return stepIndex >= 0 ? stepIndex : nav.currentStep - 1;
|
|
7792
|
+
};
|
|
7768
7793
|
const stepSchema = useMemo(() => {
|
|
7769
7794
|
if (currentStepConfig.schema) return currentStepConfig.schema;
|
|
7770
7795
|
if (currentStepConfig.fields && schema?.pick) {
|
|
@@ -7781,16 +7806,52 @@ function WizardForm({
|
|
|
7781
7806
|
const newDefaults = getStepDefaultValues(currentStepConfig.id);
|
|
7782
7807
|
form.reset(newDefaults);
|
|
7783
7808
|
}, [nav.currentStep, currentStepConfig.id]);
|
|
7809
|
+
useEffect(() => {
|
|
7810
|
+
const pending = pendingIssuesRef.current;
|
|
7811
|
+
if (!pending || pending.stepIndex !== nav.currentStep - 1) return;
|
|
7812
|
+
pendingIssuesRef.current = null;
|
|
7813
|
+
pending.issues.forEach((issue, index) => {
|
|
7814
|
+
const name = issuePath(issue) || "root";
|
|
7815
|
+
form.setError(
|
|
7816
|
+
name,
|
|
7817
|
+
{ type: "validate", message: issue.message ?? "Invalid value" },
|
|
7818
|
+
{ shouldFocus: index === 0 }
|
|
7819
|
+
);
|
|
7820
|
+
});
|
|
7821
|
+
}, [nav.currentStep, currentStepConfig.id, form]);
|
|
7784
7822
|
const handleSubmit = async (data) => {
|
|
7785
7823
|
onStepComplete?.(nav.currentStep - 1, data);
|
|
7786
|
-
await handleStepSubmit(data);
|
|
7824
|
+
const result = await handleStepSubmit(data);
|
|
7825
|
+
if (result.ok === true) return;
|
|
7826
|
+
const issues = Array.isArray(result.error?.issues) ? result.error.issues : [];
|
|
7827
|
+
if (issues.length === 0) {
|
|
7828
|
+
throw result.error;
|
|
7829
|
+
}
|
|
7830
|
+
const targetStepIndex = getIssueStepIndex(issues[0]);
|
|
7831
|
+
const targetIssues = issues.filter((issue) => getIssueStepIndex(issue) === targetStepIndex);
|
|
7832
|
+
if (targetStepIndex === nav.currentStep - 1) {
|
|
7833
|
+
pendingIssuesRef.current = { stepIndex: targetStepIndex, issues: targetIssues };
|
|
7834
|
+
const pending = pendingIssuesRef.current;
|
|
7835
|
+
pendingIssuesRef.current = null;
|
|
7836
|
+
pending.issues.forEach((issue, index) => {
|
|
7837
|
+
const name = issuePath(issue) || "root";
|
|
7838
|
+
form.setError(
|
|
7839
|
+
name,
|
|
7840
|
+
{ type: "validate", message: issue.message ?? "Invalid value" },
|
|
7841
|
+
{ shouldFocus: index === 0 }
|
|
7842
|
+
);
|
|
7843
|
+
});
|
|
7844
|
+
return;
|
|
7845
|
+
}
|
|
7846
|
+
pendingIssuesRef.current = { stepIndex: targetStepIndex, issues: targetIssues };
|
|
7847
|
+
nav.goToStep(targetStepIndex + 1);
|
|
7787
7848
|
};
|
|
7788
7849
|
return /* @__PURE__ */ jsxs(
|
|
7789
7850
|
"div",
|
|
7790
7851
|
{
|
|
7791
7852
|
"data-najm-wizard-form": "true",
|
|
7792
7853
|
"data-najm-dialog-actions": "content",
|
|
7793
|
-
className: cn("flex w-full flex-col gap-4", classNames?.root, className),
|
|
7854
|
+
className: cn("flex min-h-full w-full flex-col gap-4", classNames?.root, className),
|
|
7794
7855
|
children: [
|
|
7795
7856
|
showHeader && /* @__PURE__ */ jsx(
|
|
7796
7857
|
StepsHeader,
|
|
@@ -7807,7 +7868,7 @@ function WizardForm({
|
|
|
7807
7868
|
{
|
|
7808
7869
|
id: `step-${currentStepConfig.id}`,
|
|
7809
7870
|
onSubmit: form.handleSubmit(handleSubmit),
|
|
7810
|
-
className: cn("flex flex-col gap-4", classNames?.step),
|
|
7871
|
+
className: cn("min-h-0 flex-1 overflow-y-auto pb-4 flex flex-col gap-4", classNames?.step),
|
|
7811
7872
|
autoComplete: "off",
|
|
7812
7873
|
children: [
|
|
7813
7874
|
currentStepConfig.description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: currentStepConfig.description }),
|
|
@@ -7815,7 +7876,7 @@ function WizardForm({
|
|
|
7815
7876
|
]
|
|
7816
7877
|
}
|
|
7817
7878
|
) }) }),
|
|
7818
|
-
showFooter && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between", classNames?.footer), children: [
|
|
7879
|
+
showFooter && /* @__PURE__ */ jsxs("div", { className: cn("sticky bottom-0 z-10 mt-auto flex shrink-0 items-center justify-between border-t border-border bg-background/95 pt-3 backdrop-blur", classNames?.footer), children: [
|
|
7819
7880
|
/* @__PURE__ */ jsx("div", { children: !nav.isFirstStep && /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: nav.handlePrevious, children: previousLabel }) }),
|
|
7820
7881
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7821
7882
|
footerSlot,
|
|
@@ -7837,8 +7898,8 @@ var handler = {
|
|
|
7837
7898
|
};
|
|
7838
7899
|
useTableStore.use = new Proxy({}, handler);
|
|
7839
7900
|
var actionButtonClass = (bordered, danger) => cn(
|
|
7840
|
-
"flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors",
|
|
7841
|
-
danger ? "hover:bg-red-
|
|
7901
|
+
"flex h-7 w-7 cursor-pointer items-center justify-center rounded-md border border-transparent text-muted-foreground transition-colors",
|
|
7902
|
+
danger ? "hover:border-red-200 hover:bg-red-50 hover:text-red-500" : "hover:border-border hover:bg-muted hover:text-foreground",
|
|
7842
7903
|
bordered && "border border-muted-foreground"
|
|
7843
7904
|
);
|
|
7844
7905
|
function TableActionCell({ row, onView, onEdit, onDelete, openRowMenu, menuButton, bordered }) {
|
|
@@ -9568,7 +9629,8 @@ function NTable(props) {
|
|
|
9568
9629
|
[onRowContextMenu]
|
|
9569
9630
|
);
|
|
9570
9631
|
const autoOpenRowMenu = effectiveRowMenu ? handleOpenRowMenu : onRowContextMenu ? handleManualRowMenu : null;
|
|
9571
|
-
const
|
|
9632
|
+
const shouldCollapseActions = props.columns.length > 5;
|
|
9633
|
+
const effectiveMenuButton = Boolean(autoOpenRowMenu) && (menuButtonProp ?? shouldCollapseActions);
|
|
9572
9634
|
const store = useStoreSync({
|
|
9573
9635
|
data: props.data ?? [],
|
|
9574
9636
|
columns: props.columns ?? [],
|