@esheet/builder 0.0.1

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/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # @esheet/builder
2
+
3
+ Drag-and-drop questionnaire builder for eSheet. Provides a full editing UI for creating and modifying form schemas.
4
+
5
+ ## Features
6
+
7
+ - ✅ Visual form builder with drag & drop (custom pointer-based engine)
8
+ - ✅ 19 built-in field types via `@esheet/fields`
9
+ - ✅ Section nesting with drag-into-section support
10
+ - ✅ Field editors (question text, options, matrix rows/columns, conditional logic)
11
+ - ✅ Code view with Monaco editor (JSON/YAML toggle)
12
+ - ✅ Live preview mode
13
+ - ✅ Import/Export (JSON + YAML)
14
+ - ✅ Custom field type registration
15
+ - ✅ Dark mode support
16
+ - ✅ Mobile responsive (bottom drawer for panels)
17
+ - ✅ Self-contained CSS (injected at runtime, no external stylesheet needed)
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @esheet/builder @esheet/fields @esheet/core
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Basic Example
28
+
29
+ ```tsx
30
+ import { EsheetBuilder } from '@esheet/builder';
31
+ import type { FormDefinition } from '@esheet/core';
32
+
33
+ function App() {
34
+ const handleChange = (definition: FormDefinition) => {
35
+ console.log('Form updated:', definition);
36
+ };
37
+
38
+ return <EsheetBuilder onChange={handleChange} />;
39
+ }
40
+ ```
41
+
42
+ ### With Initial Schema
43
+
44
+ ```tsx
45
+ import { EsheetBuilder } from '@esheet/builder';
46
+
47
+ const initialForm: FormDefinition = {
48
+ schemaType: 'mieforms-v1.0',
49
+ title: 'Patient Intake',
50
+ fields: [
51
+ { id: 'name', fieldType: 'text', question: 'Full Name', required: true },
52
+ { id: 'dob', fieldType: 'date', question: 'Date of Birth' },
53
+ ],
54
+ };
55
+
56
+ <EsheetBuilder initialDefinition={initialForm} onChange={handleChange} />;
57
+ ```
58
+
59
+ ### Dark Mode
60
+
61
+ ```tsx
62
+ <div className="dark">
63
+ <EsheetBuilder onChange={handleChange} />
64
+ </div>
65
+ ```
66
+
67
+ Add the `dark` class to the builder's root or any ancestor — the builder scopes all dark styles via `.ms-builder-root.dark`.
68
+
69
+ ## API
70
+
71
+ ### `<EsheetBuilder>`
72
+
73
+ **Props:**
74
+
75
+ | Prop | Type | Description |
76
+ | ------------------- | ------------------------------- | ------------------------------- |
77
+ | `initialDefinition` | `FormDefinition` | Pre-load a form schema |
78
+ | `onChange` | `(def: FormDefinition) => void` | Callback on any form change |
79
+ | `className` | `string` | Additional CSS classes for root |
80
+
81
+ ## Custom Field Types
82
+
83
+ ```tsx
84
+ import { EsheetBuilder } from '@esheet/builder';
85
+ import { registerCustomFieldTypes } from '@esheet/fields';
86
+ import { registerFieldType } from '@esheet/core';
87
+
88
+ // Register the metadata
89
+ registerFieldType({
90
+ type: 'nps',
91
+ label: 'NPS Score',
92
+ category: 'scale',
93
+ defaultProps: { question: 'How likely are you to recommend us?' },
94
+ });
95
+
96
+ // Register the component
97
+ registerCustomFieldTypes({
98
+ nps: {
99
+ component: NpsField,
100
+ meta: {
101
+ /* ... */
102
+ },
103
+ },
104
+ });
105
+
106
+ <EsheetBuilder onChange={handleChange} />;
107
+ ```
108
+
109
+ ## CSS Architecture
110
+
111
+ The builder uses Tailwind CSS v4 with `ms:` prefix. CSS is compiled via `@tailwindcss/cli` and embedded into the JS bundle at build time — consumers never need to import a stylesheet. A scoped reset on `.ms-builder-root` prevents style leakage in either direction.
112
+
113
+ ## Building
114
+
115
+ Run `nx build @esheet/builder` to build the library.
116
+
117
+ ## Running unit tests
118
+
119
+ Run `nx test @esheet/builder` to execute the unit tests via [Vitest](https://vitest.dev/).
@@ -0,0 +1,141 @@
1
+ import { BuilderMode } from '@esheet/core';
2
+ import { createUIStore } from '@esheet/core';
3
+ import { default as default_2 } from 'react';
4
+ import { EditTab } from '@esheet/core';
5
+ import { FieldComponentProps } from '@esheet/core';
6
+ import { FormDefinition } from '@esheet/core';
7
+ import { FormStore } from '@esheet/core';
8
+ import { FormStoreContext } from '@esheet/fields';
9
+ import { getFieldComponent } from '@esheet/fields';
10
+ import { getRegisteredComponentKeys } from '@esheet/fields';
11
+ import { JSX } from 'react/jsx-runtime';
12
+ import { registerCustomFieldTypes } from '@esheet/fields';
13
+ import { resetComponentRegistry } from '@esheet/fields';
14
+ import { UIContext } from '@esheet/fields';
15
+ import { UIState } from '@esheet/core';
16
+ import { UIStore } from '@esheet/core';
17
+ import { useFormStore } from '@esheet/fields';
18
+ import { useUI } from '@esheet/fields';
19
+
20
+ /**
21
+ * BuilderHeader — top bar with Build/Code/Preview mode toggle and Import/Export actions.
22
+ */
23
+ export declare function BuilderHeader({ form, ui }: BuilderHeaderProps): JSX.Element;
24
+
25
+ export declare interface BuilderHeaderProps {
26
+ form: FormStore;
27
+ ui: UIStore;
28
+ }
29
+
30
+ export { BuilderMode }
31
+
32
+ /**
33
+ * CodeView — Monaco-based JSON/YAML editor for the form definition.
34
+ *
35
+ * Serialize on mount, live-validate on edit, auto-save on unmount.
36
+ */
37
+ export declare function CodeView({ form, ui }: CodeViewProps): JSX.Element;
38
+
39
+ export declare interface CodeViewProps {
40
+ form: FormStore;
41
+ ui: UIStore;
42
+ }
43
+
44
+ export { createUIStore }
45
+
46
+ export { EditTab }
47
+
48
+ export declare function EsheetBuilder({ definition, onChange, dragEnabled, className, children, }: EsheetBuilderProps): JSX.Element;
49
+
50
+ export declare interface EsheetBuilderProps {
51
+ /** Initial form definition to load. */
52
+ definition?: FormDefinition;
53
+ /** Callback fired when the form definition changes. */
54
+ onChange?: (definition: FormDefinition) => void;
55
+ /** Whether drag-and-drop reordering is enabled (default: true). Disable for better performance on slow devices. */
56
+ dragEnabled?: boolean;
57
+ /** Additional CSS class name. */
58
+ className?: string;
59
+ /** Optional content rendered below the header (e.g. custom status/debug panels). */
60
+ children?: default_2.ReactNode;
61
+ }
62
+
63
+ export { FieldComponentProps }
64
+
65
+ /**
66
+ * FieldWrapper - Extensibility API for custom field components.
67
+ *
68
+ * Wraps a field with collapsible header, selection highlighting, edit/delete buttons, and drag handles.
69
+ * Exposes field data and tools to the render function, allowing users to create
70
+ * custom field types while getting all the built-in editor functionality.
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * <FieldWrapper fieldId={id} form={form} ui={ui}>
75
+ * {({ field, onUpdate, onRemove }) => (
76
+ * <div>
77
+ * <input
78
+ * value={field.question}
79
+ * onChange={(e) => onUpdate({ question: e.target.value })}
80
+ * />
81
+ * </div>
82
+ * )}
83
+ * </FieldWrapper>
84
+ * ```
85
+ */
86
+ export declare function FieldWrapper({ fieldId, form, ui, dragHandleRef, isSelectedOverride, onSelectOverride, selectedVariant, forceExpandVersion, children, }: FieldWrapperProps): JSX.Element | null;
87
+
88
+ export declare interface FieldWrapperProps {
89
+ /** The field ID */
90
+ fieldId: string;
91
+ /** The form store */
92
+ form: FormStore;
93
+ /** The UI store */
94
+ ui: UIStore;
95
+ /** Ref attached to the drag-handle element. */
96
+ dragHandleRef?: default_2.RefObject<HTMLDivElement | null>;
97
+ /** Optional override for selection state (used by nested section child interaction). */
98
+ isSelectedOverride?: boolean;
99
+ /** Optional override for click selection behavior. */
100
+ onSelectOverride?: (e: default_2.MouseEvent) => void;
101
+ /** Optional selected styling variant. */
102
+ selectedVariant?: 'default' | 'nested';
103
+ /** Optional signal used to force expand a field wrapper (used for section drop UX). */
104
+ forceExpandVersion?: number;
105
+ /** Render function that receives field data and tools */
106
+ children: (props: FieldWrapperRenderProps) => default_2.ReactNode;
107
+ }
108
+
109
+ /**
110
+ * Props exposed to the render function for custom field components.
111
+ * Identical to `FieldComponentProps` from core — kept as a named alias for
112
+ * backward-compatibility with existing builder consumers.
113
+ */
114
+ export declare type FieldWrapperRenderProps = FieldComponentProps;
115
+
116
+ export { FormStoreContext }
117
+
118
+ export { getFieldComponent }
119
+
120
+ export { getRegisteredComponentKeys }
121
+
122
+ export declare const InstanceIdContext: default_2.Context<string>;
123
+
124
+ export { registerCustomFieldTypes }
125
+
126
+ export { resetComponentRegistry }
127
+
128
+ export { UIContext }
129
+
130
+ export { UIState }
131
+
132
+ export { UIStore }
133
+
134
+ export { useFormStore }
135
+
136
+ /** Hook to access the per-instance ID for unique DOM element IDs. */
137
+ export declare function useInstanceId(): string;
138
+
139
+ export { useUI }
140
+
141
+ export { }