@btst/plugin-cms 1.0.0-beta.0 → 1.2.0-beta.0

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.
Files changed (76) hide show
  1. package/dist/api/getters.cjs +37 -25
  2. package/dist/api/getters.mjs +37 -25
  3. package/dist/api/index.cjs +1 -0
  4. package/dist/api/index.d.cts +17 -8
  5. package/dist/api/index.d.mts +17 -8
  6. package/dist/api/index.d.ts +17 -8
  7. package/dist/api/index.mjs +1 -1
  8. package/dist/api/mutations.cjs +46 -19
  9. package/dist/api/mutations.mjs +46 -20
  10. package/dist/api/operations.cjs +586 -177
  11. package/dist/api/operations.mjs +585 -178
  12. package/dist/api/plugin.cjs +56 -7
  13. package/dist/api/plugin.mjs +57 -8
  14. package/dist/api/publication.cjs +8 -0
  15. package/dist/api/publication.mjs +6 -0
  16. package/dist/client/components/forms/content-form.cjs +107 -1
  17. package/dist/client/components/forms/content-form.mjs +108 -2
  18. package/dist/client/components/pages/content-editor-page.internal.cjs +23 -5
  19. package/dist/client/components/pages/content-editor-page.internal.mjs +23 -5
  20. package/dist/client/components/pages/content-list-page.internal.cjs +3 -0
  21. package/dist/client/components/pages/content-list-page.internal.mjs +3 -0
  22. package/dist/client/components/pages/dashboard-page.internal.cjs +10 -30
  23. package/dist/client/components/pages/dashboard-page.internal.mjs +10 -30
  24. package/dist/client/components/revision-history.cjs +161 -0
  25. package/dist/client/components/revision-history.mjs +159 -0
  26. package/dist/client/components/shared/content-type-card.cjs +56 -0
  27. package/dist/client/components/shared/content-type-card.mjs +54 -0
  28. package/dist/client/components/shared/empty-state.cjs +18 -1
  29. package/dist/client/components/shared/empty-state.mjs +19 -2
  30. package/dist/client/hooks/cms-hooks.cjs +18 -2
  31. package/dist/client/hooks/cms-hooks.mjs +17 -3
  32. package/dist/client/hooks/index.cjs +2 -0
  33. package/dist/client/hooks/index.d.cts +306 -2
  34. package/dist/client/hooks/index.d.mts +306 -2
  35. package/dist/client/hooks/index.d.ts +306 -2
  36. package/dist/client/hooks/index.mjs +1 -1
  37. package/dist/client/index.d.cts +55 -2
  38. package/dist/client/index.d.mts +55 -2
  39. package/dist/client/index.d.ts +55 -2
  40. package/dist/db.cjs +25 -0
  41. package/dist/db.mjs +25 -0
  42. package/dist/permissions.cjs +2 -0
  43. package/dist/permissions.d.cts +1 -0
  44. package/dist/permissions.d.mts +1 -0
  45. package/dist/permissions.d.ts +1 -0
  46. package/dist/permissions.mjs +2 -0
  47. package/dist/query-keys.cjs +31 -1
  48. package/dist/query-keys.d.cts +1 -1
  49. package/dist/query-keys.d.mts +1 -1
  50. package/dist/query-keys.d.ts +1 -1
  51. package/dist/query-keys.mjs +31 -1
  52. package/dist/shared/{plugin-cms.Csx7tNDO.d.mts → plugin-cms.DAAUZ41w.d.mts} +314 -81
  53. package/dist/shared/{plugin-cms.eNW9_FO5.d.ts → plugin-cms.DJ_293QU.d.cts} +314 -81
  54. package/dist/shared/{plugin-cms.Bptwe33B.d.cts → plugin-cms.DlUSv7wz.d.ts} +314 -81
  55. package/dist/types.d.cts +38 -2
  56. package/dist/types.d.mts +38 -2
  57. package/dist/types.d.ts +38 -2
  58. package/dist/ui/src/components/auto-form/config.cjs +2 -0
  59. package/dist/ui/src/components/auto-form/config.mjs +2 -0
  60. package/dist/ui/src/components/auto-form/fields/file.cjs +68 -0
  61. package/dist/ui/src/components/auto-form/fields/file.mjs +63 -0
  62. package/dist/ui/src/components/auto-form/fields/object.cjs +9 -2
  63. package/dist/ui/src/components/auto-form/fields/object.mjs +9 -2
  64. package/dist/ui/src/components/auto-form/helpers.cjs +9 -0
  65. package/dist/ui/src/components/auto-form/helpers.mjs +9 -0
  66. package/dist/ui/src/components/auto-form/index.cjs +29 -4
  67. package/dist/ui/src/components/auto-form/index.mjs +31 -6
  68. package/dist/ui/src/components/auto-form/stepped-auto-form.cjs +34 -29
  69. package/dist/ui/src/components/auto-form/stepped-auto-form.mjs +35 -30
  70. package/dist/ui/src/components/sheet.cjs +126 -0
  71. package/dist/ui/src/components/sheet.mjs +105 -0
  72. package/dist/ui/src/lib/form-visibility.cjs +20 -0
  73. package/dist/ui/src/lib/form-visibility.mjs +18 -0
  74. package/dist/ui/src/lib/schema-converter.cjs +101 -0
  75. package/dist/ui/src/lib/schema-converter.mjs +100 -1
  76. package/package.json +5 -4
@@ -5,9 +5,11 @@ const jsxRuntime = require('react/jsx-runtime');
5
5
  const form = require('../form.cjs');
6
6
  const React = require('react');
7
7
  const reactHookForm = require('react-hook-form');
8
+ const schemaConverter = require('../../lib/schema-converter.cjs');
8
9
  require('../button.cjs');
9
10
  const utils = require('../../lib/utils.cjs');
10
11
  const zod = require('@hookform/resolvers/zod');
12
+ const file = require('./fields/file.cjs');
11
13
  const object = require('./fields/object.cjs');
12
14
  const helpers = require('./helpers.cjs');
13
15
 
@@ -34,6 +36,23 @@ function AutoForm({
34
36
  defaultValues: defaultValues ?? void 0,
35
37
  values: valuesProp
36
38
  });
39
+ const [uploadStatuses, setUploadStatuses] = React.useState({});
40
+ const reportUploadStatus = React.useCallback((name, status) => {
41
+ setUploadStatuses((previous) => {
42
+ if (previous[name] === status || !status && !(name in previous)) return previous;
43
+ const next = { ...previous };
44
+ if (status) next[name] = status;
45
+ else Reflect.deleteProperty(next, name);
46
+ return next;
47
+ });
48
+ }, []);
49
+ const uploading = Object.values(uploadStatuses).includes("uploading");
50
+ const uploadBlocked = Object.keys(uploadStatuses).length > 0;
51
+ const watchedValues = reactHookForm.useWatch({ control: form$1.control });
52
+ const metadata = formSchema.meta();
53
+ const visibility = metadata?.properties ? schemaConverter.resolveVisibleSchema(metadata, watchedValues) : void 0;
54
+ const visibleKeys = visibility ? Object.keys(visibility.schema.properties ?? {}) : null;
55
+ const visibleObjectSchema = visibleKeys ? objectFormSchema.pick(Object.fromEntries(visibleKeys.map((key) => [key, true]))) : objectFormSchema;
37
56
  const [schemaSubmitError, setSchemaSubmitError] = React.useState(null);
38
57
  function onSubmit(values) {
39
58
  setSchemaSubmitError(null);
@@ -58,18 +77,24 @@ function AutoForm({
58
77
  return () => subscription.unsubscribe();
59
78
  }, [form$1, formSchema, onValuesChangeProp, onParsedValuesChange]);
60
79
  const renderChildren = typeof children === "function" ? children(form$1.formState) : children;
61
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(form.Form, { ...form$1, children: /* @__PURE__ */ jsxRuntime.jsxs(
80
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(form.Form, { ...form$1, children: /* @__PURE__ */ jsxRuntime.jsx(
62
81
  "form",
63
82
  {
64
83
  onSubmit: (e) => {
84
+ if (uploadBlocked) {
85
+ e.preventDefault();
86
+ setSchemaSubmitError(uploading ? "Wait for the upload to finish." : "Retry the failed file upload before submitting.");
87
+ return;
88
+ }
65
89
  form$1.handleSubmit(onSubmit, () => setSchemaSubmitError(null))(e);
66
90
  },
67
91
  className: utils.cn("space-y-5", className),
68
- children: [
92
+ children: /* @__PURE__ */ jsxRuntime.jsx(file.FileUploadStatusContext.Provider, { value: reportUploadStatus, children: /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { disabled: uploading, className: "contents", children: [
69
93
  /* @__PURE__ */ jsxRuntime.jsx(
70
94
  object,
71
95
  {
72
- schema: objectFormSchema,
96
+ schema: visibleObjectSchema,
97
+ visibilityValues: visibility?.data,
73
98
  form: form$1,
74
99
  dependencies,
75
100
  fieldConfig
@@ -84,7 +109,7 @@ function AutoForm({
84
109
  }
85
110
  ) : null,
86
111
  renderChildren
87
- ]
112
+ ] }) })
88
113
  }
89
114
  ) }) });
90
115
  }
@@ -1,11 +1,13 @@
1
1
  'use client';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { Form } from '../form.mjs';
4
- import React__default, { useState } from 'react';
5
- import { useForm } from 'react-hook-form';
4
+ import React__default, { useState, useCallback } from 'react';
5
+ import { useForm, useWatch } from 'react-hook-form';
6
+ import { resolveVisibleSchema } from '../../lib/schema-converter.mjs';
6
7
  import '../button.mjs';
7
8
  import { cn } from '../../lib/utils.mjs';
8
9
  import { zodResolver } from '@hookform/resolvers/zod';
10
+ import { FileUploadStatusContext } from './fields/file.mjs';
9
11
  import AutoFormObject from './fields/object.mjs';
10
12
  import { getObjectFormSchema, getDefaultValues } from './helpers.mjs';
11
13
 
@@ -28,6 +30,23 @@ function AutoForm({
28
30
  defaultValues: defaultValues ?? void 0,
29
31
  values: valuesProp
30
32
  });
33
+ const [uploadStatuses, setUploadStatuses] = useState({});
34
+ const reportUploadStatus = useCallback((name, status) => {
35
+ setUploadStatuses((previous) => {
36
+ if (previous[name] === status || !status && !(name in previous)) return previous;
37
+ const next = { ...previous };
38
+ if (status) next[name] = status;
39
+ else Reflect.deleteProperty(next, name);
40
+ return next;
41
+ });
42
+ }, []);
43
+ const uploading = Object.values(uploadStatuses).includes("uploading");
44
+ const uploadBlocked = Object.keys(uploadStatuses).length > 0;
45
+ const watchedValues = useWatch({ control: form.control });
46
+ const metadata = formSchema.meta();
47
+ const visibility = metadata?.properties ? resolveVisibleSchema(metadata, watchedValues) : void 0;
48
+ const visibleKeys = visibility ? Object.keys(visibility.schema.properties ?? {}) : null;
49
+ const visibleObjectSchema = visibleKeys ? objectFormSchema.pick(Object.fromEntries(visibleKeys.map((key) => [key, true]))) : objectFormSchema;
31
50
  const [schemaSubmitError, setSchemaSubmitError] = useState(null);
32
51
  function onSubmit(values) {
33
52
  setSchemaSubmitError(null);
@@ -52,18 +71,24 @@ function AutoForm({
52
71
  return () => subscription.unsubscribe();
53
72
  }, [form, formSchema, onValuesChangeProp, onParsedValuesChange]);
54
73
  const renderChildren = typeof children === "function" ? children(form.formState) : children;
55
- return /* @__PURE__ */ jsx("div", { className: "w-full", children: /* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs(
74
+ return /* @__PURE__ */ jsx("div", { className: "w-full", children: /* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsx(
56
75
  "form",
57
76
  {
58
77
  onSubmit: (e) => {
78
+ if (uploadBlocked) {
79
+ e.preventDefault();
80
+ setSchemaSubmitError(uploading ? "Wait for the upload to finish." : "Retry the failed file upload before submitting.");
81
+ return;
82
+ }
59
83
  form.handleSubmit(onSubmit, () => setSchemaSubmitError(null))(e);
60
84
  },
61
85
  className: cn("space-y-5", className),
62
- children: [
86
+ children: /* @__PURE__ */ jsx(FileUploadStatusContext.Provider, { value: reportUploadStatus, children: /* @__PURE__ */ jsxs("fieldset", { disabled: uploading, className: "contents", children: [
63
87
  /* @__PURE__ */ jsx(
64
88
  AutoFormObject,
65
89
  {
66
- schema: objectFormSchema,
90
+ schema: visibleObjectSchema,
91
+ visibilityValues: visibility?.data,
67
92
  form,
68
93
  dependencies,
69
94
  fieldConfig
@@ -78,7 +103,7 @@ function AutoForm({
78
103
  }
79
104
  ) : null,
80
105
  renderChildren
81
- ]
106
+ ] }) })
82
107
  }
83
108
  ) }) });
84
109
  }
@@ -5,6 +5,9 @@ const jsxRuntime = require('react/jsx-runtime');
5
5
  const React = require('react');
6
6
  const z = require('zod');
7
7
  const index = require('./index.cjs');
8
+ const helpers = require('./helpers.cjs');
9
+ const schemaConverter = require('../../lib/schema-converter.cjs');
10
+ const formVisibility = require('../../lib/form-visibility.cjs');
8
11
  const button = require('../button.cjs');
9
12
  const separator = require('../separator.cjs');
10
13
  const utils = require('../../lib/utils.cjs');
@@ -15,7 +18,7 @@ const React__default = /*#__PURE__*/_interopDefaultCompat(React);
15
18
 
16
19
  function extractStepsFromSchema(schema) {
17
20
  try {
18
- const jsonSchema = schema.toJSONSchema();
21
+ const jsonSchema = schema.meta()?.steps ? schema.meta() : schema.toJSONSchema();
19
22
  if (jsonSchema.steps && Array.isArray(jsonSchema.steps)) {
20
23
  return jsonSchema.steps;
21
24
  }
@@ -26,7 +29,7 @@ function extractStepsFromSchema(schema) {
26
29
  function getFieldStepAssignments(schema) {
27
30
  const assignments = /* @__PURE__ */ new Map();
28
31
  try {
29
- const jsonSchema = schema.toJSONSchema();
32
+ const jsonSchema = schema.meta()?.steps ? schema.meta() : schema.toJSONSchema();
30
33
  const stepGroupMap = jsonSchema.stepGroupMap;
31
34
  if (stepGroupMap) {
32
35
  for (const [fieldName, stepGroup] of Object.entries(stepGroupMap)) {
@@ -60,21 +63,6 @@ function createStepSchema(fullSchema, stepIndex, fieldAssignments) {
60
63
  }
61
64
  return fullSchema.pick(pickObject);
62
65
  }
63
- function getObjectSchema(schema) {
64
- if (schema instanceof z.z.ZodObject) {
65
- return schema;
66
- }
67
- const schemaDef = schema._zod?.def ?? schema._def;
68
- if (schemaDef) {
69
- if (schemaDef.schema) {
70
- return getObjectSchema(schemaDef.schema);
71
- }
72
- if (schemaDef.innerType) {
73
- return getObjectSchema(schemaDef.innerType);
74
- }
75
- }
76
- return null;
77
- }
78
66
  function DefaultStepper({
79
67
  steps,
80
68
  currentStepIndex,
@@ -122,16 +110,25 @@ function SteppedAutoForm({
122
110
  StepperComponent = DefaultStepper,
123
111
  isSubmitting = false
124
112
  }) {
125
- const steps = React.useMemo(() => extractStepsFromSchema(formSchema), [formSchema]);
126
- const hasMultipleSteps = steps.length > 1;
127
- const fieldAssignments = React.useMemo(
113
+ const allSteps = React.useMemo(() => extractStepsFromSchema(formSchema), [formSchema]);
114
+ const hasMultipleSteps = allSteps.length > 1;
115
+ const originalFieldAssignments = React.useMemo(
128
116
  () => getFieldStepAssignments(formSchema),
129
117
  [formSchema]
130
118
  );
131
119
  const [currentStepIndex, setCurrentStepIndex] = React.useState(0);
132
120
  const [accumulatedValues, setAccumulatedValues] = React.useState(
133
- initialValues ?? {}
121
+ () => ({ ...helpers.getDefaultValues(helpers.getObjectFormSchema(formSchema), fieldConfig) ?? {}, ...initialValues ?? {} })
134
122
  );
123
+ const steps = React.useMemo(() => {
124
+ const metadata = formSchema.meta();
125
+ const visibleValues = metadata?.properties ? schemaConverter.resolveVisibleSchema(metadata, accumulatedValues).data : accumulatedValues;
126
+ return allSteps.map((step, originalIndex) => ({ ...step, originalIndex })).filter((step) => formVisibility.matchesShowIf(step.showIf, visibleValues));
127
+ }, [allSteps, accumulatedValues, formSchema]);
128
+ const fieldAssignments = React.useMemo(() => new Map(Array.from(originalFieldAssignments).map(([key, originalIndex]) => [key, steps.findIndex((step) => step.originalIndex === originalIndex)])), [originalFieldAssignments, steps]);
129
+ React.useEffect(() => {
130
+ setCurrentStepIndex((index) => Math.min(index, Math.max(0, steps.length - 1)));
131
+ }, [steps.length]);
135
132
  const [completedSteps, setCompletedSteps] = React.useState(/* @__PURE__ */ new Set());
136
133
  const [schemaErrors, setSchemaErrors] = React.useState(null);
137
134
  const accumulatedValuesRef = React.useRef(accumulatedValues);
@@ -152,13 +149,19 @@ function SteppedAutoForm({
152
149
  setAccumulatedValues(newValues);
153
150
  }
154
151
  }, [initialValues]);
155
- const objectSchema = React.useMemo(() => getObjectSchema(formSchema), [formSchema]);
152
+ const objectSchema = React.useMemo(() => helpers.getObjectFormSchema(formSchema), [formSchema]);
156
153
  const stepSchemas = React.useMemo(() => {
157
154
  if (!hasMultipleSteps || !objectSchema) return [];
158
- return steps.map(
159
- (_, index) => createStepSchema(objectSchema, index, fieldAssignments)
160
- );
161
- }, [hasMultipleSteps, objectSchema, steps, fieldAssignments]);
155
+ const metadata = formSchema.meta();
156
+ if (metadata?.properties) {
157
+ const visible = schemaConverter.resolveVisibleSchema(metadata, accumulatedValues).schema;
158
+ return steps.map((_, index) => {
159
+ const properties = Object.fromEntries(Object.entries(visible.properties ?? {}).filter(([key]) => fieldAssignments.get(key) === index));
160
+ return schemaConverter.formSchemaToZod({ ...visible, properties, required: visible.required?.filter((key) => key in properties), steps: void 0 });
161
+ });
162
+ }
163
+ return steps.map((_, index) => createStepSchema(objectSchema, index, fieldAssignments));
164
+ }, [hasMultipleSteps, objectSchema, steps, fieldAssignments, accumulatedValues, formSchema]);
162
165
  const currentStep = steps[currentStepIndex];
163
166
  const currentStepSchema = stepSchemas[currentStepIndex];
164
167
  const isFirst = currentStepIndex === 0;
@@ -166,14 +169,16 @@ function SteppedAutoForm({
166
169
  const currentStepFieldConfig = React.useMemo(() => {
167
170
  if (!fieldConfig) return void 0;
168
171
  const stepFields = Array.from(fieldAssignments.entries()).filter(([, step]) => step === currentStepIndex).map(([field]) => field);
172
+ const properties = formSchema.meta()?.properties;
169
173
  const filtered = {};
170
174
  for (const field of stepFields) {
171
175
  if (field in fieldConfig) {
172
- filtered[field] = fieldConfig[field];
176
+ const config = fieldConfig[field];
177
+ filtered[field] = properties?.[field]?.showIf ? { ...config, showIf: void 0 } : config;
173
178
  }
174
179
  }
175
180
  return filtered;
176
- }, [fieldConfig, fieldAssignments, currentStepIndex]);
181
+ }, [fieldConfig, fieldAssignments, currentStepIndex, formSchema]);
177
182
  const currentStepValues = React.useMemo(() => {
178
183
  const stepFields = Array.from(fieldAssignments.entries()).filter(([, step]) => step === currentStepIndex).map(([field]) => field);
179
184
  const values = {};
@@ -251,7 +256,7 @@ function SteppedAutoForm({
251
256
  setSchemaErrors(null);
252
257
  }
253
258
  }, [isFirst]);
254
- if (!hasMultipleSteps) {
259
+ if (!hasMultipleSteps || steps.length === 0) {
255
260
  return /* @__PURE__ */ jsxRuntime.jsxs(
256
261
  index,
257
262
  {
@@ -1,15 +1,18 @@
1
1
  'use client';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
- import React__default, { useMemo, useState, useRef, useEffect, useCallback } from 'react';
3
+ import React__default, { useMemo, useState, useEffect, useRef, useCallback } from 'react';
4
4
  import { z } from 'zod';
5
5
  import AutoForm from './index.mjs';
6
+ import { getDefaultValues, getObjectFormSchema } from './helpers.mjs';
7
+ import { resolveVisibleSchema, formSchemaToZod } from '../../lib/schema-converter.mjs';
8
+ import { matchesShowIf } from '../../lib/form-visibility.mjs';
6
9
  import { Button } from '../button.mjs';
7
10
  import { Separator } from '../separator.mjs';
8
11
  import { cn } from '../../lib/utils.mjs';
9
12
 
10
13
  function extractStepsFromSchema(schema) {
11
14
  try {
12
- const jsonSchema = schema.toJSONSchema();
15
+ const jsonSchema = schema.meta()?.steps ? schema.meta() : schema.toJSONSchema();
13
16
  if (jsonSchema.steps && Array.isArray(jsonSchema.steps)) {
14
17
  return jsonSchema.steps;
15
18
  }
@@ -20,7 +23,7 @@ function extractStepsFromSchema(schema) {
20
23
  function getFieldStepAssignments(schema) {
21
24
  const assignments = /* @__PURE__ */ new Map();
22
25
  try {
23
- const jsonSchema = schema.toJSONSchema();
26
+ const jsonSchema = schema.meta()?.steps ? schema.meta() : schema.toJSONSchema();
24
27
  const stepGroupMap = jsonSchema.stepGroupMap;
25
28
  if (stepGroupMap) {
26
29
  for (const [fieldName, stepGroup] of Object.entries(stepGroupMap)) {
@@ -54,21 +57,6 @@ function createStepSchema(fullSchema, stepIndex, fieldAssignments) {
54
57
  }
55
58
  return fullSchema.pick(pickObject);
56
59
  }
57
- function getObjectSchema(schema) {
58
- if (schema instanceof z.ZodObject) {
59
- return schema;
60
- }
61
- const schemaDef = schema._zod?.def ?? schema._def;
62
- if (schemaDef) {
63
- if (schemaDef.schema) {
64
- return getObjectSchema(schemaDef.schema);
65
- }
66
- if (schemaDef.innerType) {
67
- return getObjectSchema(schemaDef.innerType);
68
- }
69
- }
70
- return null;
71
- }
72
60
  function DefaultStepper({
73
61
  steps,
74
62
  currentStepIndex,
@@ -116,16 +104,25 @@ function SteppedAutoForm({
116
104
  StepperComponent = DefaultStepper,
117
105
  isSubmitting = false
118
106
  }) {
119
- const steps = useMemo(() => extractStepsFromSchema(formSchema), [formSchema]);
120
- const hasMultipleSteps = steps.length > 1;
121
- const fieldAssignments = useMemo(
107
+ const allSteps = useMemo(() => extractStepsFromSchema(formSchema), [formSchema]);
108
+ const hasMultipleSteps = allSteps.length > 1;
109
+ const originalFieldAssignments = useMemo(
122
110
  () => getFieldStepAssignments(formSchema),
123
111
  [formSchema]
124
112
  );
125
113
  const [currentStepIndex, setCurrentStepIndex] = useState(0);
126
114
  const [accumulatedValues, setAccumulatedValues] = useState(
127
- initialValues ?? {}
115
+ () => ({ ...getDefaultValues(getObjectFormSchema(formSchema), fieldConfig) ?? {}, ...initialValues ?? {} })
128
116
  );
117
+ const steps = useMemo(() => {
118
+ const metadata = formSchema.meta();
119
+ const visibleValues = metadata?.properties ? resolveVisibleSchema(metadata, accumulatedValues).data : accumulatedValues;
120
+ return allSteps.map((step, originalIndex) => ({ ...step, originalIndex })).filter((step) => matchesShowIf(step.showIf, visibleValues));
121
+ }, [allSteps, accumulatedValues, formSchema]);
122
+ const fieldAssignments = useMemo(() => new Map(Array.from(originalFieldAssignments).map(([key, originalIndex]) => [key, steps.findIndex((step) => step.originalIndex === originalIndex)])), [originalFieldAssignments, steps]);
123
+ useEffect(() => {
124
+ setCurrentStepIndex((index) => Math.min(index, Math.max(0, steps.length - 1)));
125
+ }, [steps.length]);
129
126
  const [completedSteps, setCompletedSteps] = useState(/* @__PURE__ */ new Set());
130
127
  const [schemaErrors, setSchemaErrors] = useState(null);
131
128
  const accumulatedValuesRef = useRef(accumulatedValues);
@@ -146,13 +143,19 @@ function SteppedAutoForm({
146
143
  setAccumulatedValues(newValues);
147
144
  }
148
145
  }, [initialValues]);
149
- const objectSchema = useMemo(() => getObjectSchema(formSchema), [formSchema]);
146
+ const objectSchema = useMemo(() => getObjectFormSchema(formSchema), [formSchema]);
150
147
  const stepSchemas = useMemo(() => {
151
148
  if (!hasMultipleSteps || !objectSchema) return [];
152
- return steps.map(
153
- (_, index) => createStepSchema(objectSchema, index, fieldAssignments)
154
- );
155
- }, [hasMultipleSteps, objectSchema, steps, fieldAssignments]);
149
+ const metadata = formSchema.meta();
150
+ if (metadata?.properties) {
151
+ const visible = resolveVisibleSchema(metadata, accumulatedValues).schema;
152
+ return steps.map((_, index) => {
153
+ const properties = Object.fromEntries(Object.entries(visible.properties ?? {}).filter(([key]) => fieldAssignments.get(key) === index));
154
+ return formSchemaToZod({ ...visible, properties, required: visible.required?.filter((key) => key in properties), steps: void 0 });
155
+ });
156
+ }
157
+ return steps.map((_, index) => createStepSchema(objectSchema, index, fieldAssignments));
158
+ }, [hasMultipleSteps, objectSchema, steps, fieldAssignments, accumulatedValues, formSchema]);
156
159
  const currentStep = steps[currentStepIndex];
157
160
  const currentStepSchema = stepSchemas[currentStepIndex];
158
161
  const isFirst = currentStepIndex === 0;
@@ -160,14 +163,16 @@ function SteppedAutoForm({
160
163
  const currentStepFieldConfig = useMemo(() => {
161
164
  if (!fieldConfig) return void 0;
162
165
  const stepFields = Array.from(fieldAssignments.entries()).filter(([, step]) => step === currentStepIndex).map(([field]) => field);
166
+ const properties = formSchema.meta()?.properties;
163
167
  const filtered = {};
164
168
  for (const field of stepFields) {
165
169
  if (field in fieldConfig) {
166
- filtered[field] = fieldConfig[field];
170
+ const config = fieldConfig[field];
171
+ filtered[field] = properties?.[field]?.showIf ? { ...config, showIf: void 0 } : config;
167
172
  }
168
173
  }
169
174
  return filtered;
170
- }, [fieldConfig, fieldAssignments, currentStepIndex]);
175
+ }, [fieldConfig, fieldAssignments, currentStepIndex, formSchema]);
171
176
  const currentStepValues = useMemo(() => {
172
177
  const stepFields = Array.from(fieldAssignments.entries()).filter(([, step]) => step === currentStepIndex).map(([field]) => field);
173
178
  const values = {};
@@ -245,7 +250,7 @@ function SteppedAutoForm({
245
250
  setSchemaErrors(null);
246
251
  }
247
252
  }, [isFirst]);
248
- if (!hasMultipleSteps) {
253
+ if (!hasMultipleSteps || steps.length === 0) {
249
254
  return /* @__PURE__ */ jsxs(
250
255
  AutoForm,
251
256
  {
@@ -0,0 +1,126 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const DialogPrimitive = require('@radix-ui/react-dialog');
6
+ const lucideReact = require('lucide-react');
7
+ const utils = require('../lib/utils.cjs');
8
+
9
+ function _interopNamespaceCompat(e) {
10
+ if (e && typeof e === 'object' && 'default' in e) return e;
11
+ const n = Object.create(null);
12
+ if (e) {
13
+ for (const k in e) {
14
+ n[k] = e[k];
15
+ }
16
+ }
17
+ n.default = e;
18
+ return n;
19
+ }
20
+
21
+ const DialogPrimitive__namespace = /*#__PURE__*/_interopNamespaceCompat(DialogPrimitive);
22
+
23
+ function Sheet({ ...props }) {
24
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { "data-slot": "sheet", ...props });
25
+ }
26
+ function SheetTrigger({
27
+ ...props
28
+ }) {
29
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Trigger, { "data-slot": "sheet-trigger", ...props });
30
+ }
31
+ function SheetPortal({
32
+ ...props
33
+ }) {
34
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Portal, { "data-slot": "sheet-portal", ...props });
35
+ }
36
+ function SheetOverlay({
37
+ className,
38
+ ...props
39
+ }) {
40
+ return /* @__PURE__ */ jsxRuntime.jsx(
41
+ DialogPrimitive__namespace.Overlay,
42
+ {
43
+ "data-slot": "sheet-overlay",
44
+ className: utils.cn(
45
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
46
+ className
47
+ ),
48
+ ...props
49
+ }
50
+ );
51
+ }
52
+ function SheetContent({
53
+ className,
54
+ children,
55
+ side = "right",
56
+ ...props
57
+ }) {
58
+ return /* @__PURE__ */ jsxRuntime.jsxs(SheetPortal, { children: [
59
+ /* @__PURE__ */ jsxRuntime.jsx(SheetOverlay, {}),
60
+ /* @__PURE__ */ jsxRuntime.jsxs(
61
+ DialogPrimitive__namespace.Content,
62
+ {
63
+ "data-slot": "sheet-content",
64
+ className: utils.cn(
65
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
66
+ side === "right" && "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
67
+ side === "left" && "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
68
+ side === "top" && "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
69
+ side === "bottom" && "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
70
+ className
71
+ ),
72
+ ...props,
73
+ children: [
74
+ children,
75
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none", children: [
76
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-4" }),
77
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
78
+ ] })
79
+ ]
80
+ }
81
+ )
82
+ ] });
83
+ }
84
+ function SheetHeader({ className, ...props }) {
85
+ return /* @__PURE__ */ jsxRuntime.jsx(
86
+ "div",
87
+ {
88
+ "data-slot": "sheet-header",
89
+ className: utils.cn("flex flex-col gap-1.5 p-4", className),
90
+ ...props
91
+ }
92
+ );
93
+ }
94
+ function SheetTitle({
95
+ className,
96
+ ...props
97
+ }) {
98
+ return /* @__PURE__ */ jsxRuntime.jsx(
99
+ DialogPrimitive__namespace.Title,
100
+ {
101
+ "data-slot": "sheet-title",
102
+ className: utils.cn("text-foreground font-semibold", className),
103
+ ...props
104
+ }
105
+ );
106
+ }
107
+ function SheetDescription({
108
+ className,
109
+ ...props
110
+ }) {
111
+ return /* @__PURE__ */ jsxRuntime.jsx(
112
+ DialogPrimitive__namespace.Description,
113
+ {
114
+ "data-slot": "sheet-description",
115
+ className: utils.cn("text-muted-foreground text-sm", className),
116
+ ...props
117
+ }
118
+ );
119
+ }
120
+
121
+ exports.Sheet = Sheet;
122
+ exports.SheetContent = SheetContent;
123
+ exports.SheetDescription = SheetDescription;
124
+ exports.SheetHeader = SheetHeader;
125
+ exports.SheetTitle = SheetTitle;
126
+ exports.SheetTrigger = SheetTrigger;
@@ -0,0 +1,105 @@
1
+ 'use client';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
4
+ import { XIcon } from 'lucide-react';
5
+ import { cn } from '../lib/utils.mjs';
6
+
7
+ function Sheet({ ...props }) {
8
+ return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "sheet", ...props });
9
+ }
10
+ function SheetTrigger({
11
+ ...props
12
+ }) {
13
+ return /* @__PURE__ */ jsx(DialogPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
14
+ }
15
+ function SheetPortal({
16
+ ...props
17
+ }) {
18
+ return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
19
+ }
20
+ function SheetOverlay({
21
+ className,
22
+ ...props
23
+ }) {
24
+ return /* @__PURE__ */ jsx(
25
+ DialogPrimitive.Overlay,
26
+ {
27
+ "data-slot": "sheet-overlay",
28
+ className: cn(
29
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
30
+ className
31
+ ),
32
+ ...props
33
+ }
34
+ );
35
+ }
36
+ function SheetContent({
37
+ className,
38
+ children,
39
+ side = "right",
40
+ ...props
41
+ }) {
42
+ return /* @__PURE__ */ jsxs(SheetPortal, { children: [
43
+ /* @__PURE__ */ jsx(SheetOverlay, {}),
44
+ /* @__PURE__ */ jsxs(
45
+ DialogPrimitive.Content,
46
+ {
47
+ "data-slot": "sheet-content",
48
+ className: cn(
49
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
50
+ side === "right" && "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
51
+ side === "left" && "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
52
+ side === "top" && "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
53
+ side === "bottom" && "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
54
+ className
55
+ ),
56
+ ...props,
57
+ children: [
58
+ children,
59
+ /* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none", children: [
60
+ /* @__PURE__ */ jsx(XIcon, { className: "size-4" }),
61
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
62
+ ] })
63
+ ]
64
+ }
65
+ )
66
+ ] });
67
+ }
68
+ function SheetHeader({ className, ...props }) {
69
+ return /* @__PURE__ */ jsx(
70
+ "div",
71
+ {
72
+ "data-slot": "sheet-header",
73
+ className: cn("flex flex-col gap-1.5 p-4", className),
74
+ ...props
75
+ }
76
+ );
77
+ }
78
+ function SheetTitle({
79
+ className,
80
+ ...props
81
+ }) {
82
+ return /* @__PURE__ */ jsx(
83
+ DialogPrimitive.Title,
84
+ {
85
+ "data-slot": "sheet-title",
86
+ className: cn("text-foreground font-semibold", className),
87
+ ...props
88
+ }
89
+ );
90
+ }
91
+ function SheetDescription({
92
+ className,
93
+ ...props
94
+ }) {
95
+ return /* @__PURE__ */ jsx(
96
+ DialogPrimitive.Description,
97
+ {
98
+ "data-slot": "sheet-description",
99
+ className: cn("text-muted-foreground text-sm", className),
100
+ ...props
101
+ }
102
+ );
103
+ }
104
+
105
+ export { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger };
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ function matchesShowIf(condition, values) {
4
+ if (!condition) return true;
5
+ const value = Object.hasOwn(values, condition.field) ? values[condition.field] : void 0;
6
+ switch (condition.operator) {
7
+ case "equals":
8
+ return value === condition.value;
9
+ case "notEquals":
10
+ return value !== condition.value;
11
+ case "in":
12
+ return Array.isArray(condition.value) && condition.value.includes(value);
13
+ case "isTruthy":
14
+ return Boolean(value);
15
+ default:
16
+ return false;
17
+ }
18
+ }
19
+
20
+ exports.matchesShowIf = matchesShowIf;