@structured-field/widget-editor 1.0.0 → 1.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@structured-field/widget-editor",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "A lightweight JSON Schema form builder with support for relation fields (ForeignKey, QuerySet) and autocomplete search.",
5
5
  "type": "module",
6
6
  "main": "dist/structured-widget-editor.js",
@@ -22,7 +22,6 @@
22
22
  ],
23
23
  "scripts": {
24
24
  "build": "rollup -c && node scripts/bundle-iife.mjs",
25
- "build:cdn": "rollup -c && node scripts/bundle-iife.mjs",
26
25
  "dev": "rollup -c -w",
27
26
  "test:serve": "vite --open"
28
27
  },
@@ -43,6 +42,7 @@
43
42
  "devDependencies": {
44
43
  "@rollup/plugin-commonjs": "^29.0.2",
45
44
  "@rollup/plugin-node-resolve": "^16.0.3",
45
+ "@rollup/plugin-replace": "^6.0.3",
46
46
  "@rollup/plugin-terser": "^0.4.4",
47
47
  "@vitejs/plugin-vue": "^6.0.4",
48
48
  "@vue/compiler-sfc": "^3.5.30",
@@ -62,6 +62,11 @@
62
62
  "branches": [
63
63
  "master"
64
64
  ],
65
+ "verifyConditions": [
66
+ "@semantic-release/changelog",
67
+ "@semantic-release/git",
68
+ "@semantic-release/github"
69
+ ],
65
70
  "plugins": [
66
71
  "@semantic-release/commit-analyzer",
67
72
  "@semantic-release/release-notes-generator",
@@ -24,6 +24,7 @@ export default {
24
24
  errors: { type: Object, default: () => ({}) },
25
25
  },
26
26
  emits: ['change'],
27
+ expose: ['getValue'],
27
28
  data() {
28
29
  const parsedSchema = typeof this.schema === 'string' ? JSON.parse(this.schema) : this.schema;
29
30
  const defs = parsedSchema.$defs || parsedSchema.definitions || {};
@@ -41,14 +41,18 @@
41
41
  </template>
42
42
 
43
43
  <script>
44
- import { defineAsyncComponent } from 'vue';
45
44
  import { getDefaultForSchema } from '../utils';
46
45
 
47
46
  let keyCounter = 0;
48
47
 
48
+ import SchemaEditor from './SchemaEditor.vue';
49
+
49
50
  export default {
50
51
  name: 'ArrayEditor',
51
- components: { SchemaEditor: defineAsyncComponent(() => import('./SchemaEditor.vue')) },
52
+ beforeCreate() {
53
+ if (!this.$options.components) this.$options.components = {};
54
+ this.$options.components.SchemaEditor = SchemaEditor;
55
+ },
52
56
  props: {
53
57
  schema: { type: Object, required: true },
54
58
  modelValue: { default: () => [] },
@@ -28,12 +28,16 @@
28
28
  </template>
29
29
 
30
30
  <script>
31
- import { defineAsyncComponent } from 'vue';
32
31
  import { getDefaultForSchema } from '../utils';
33
32
 
33
+ import SchemaEditor from './SchemaEditor.vue';
34
+
34
35
  export default {
35
36
  name: 'NullableEditor',
36
- components: { SchemaEditor: defineAsyncComponent(() => import('./SchemaEditor.vue')) },
37
+ beforeCreate() {
38
+ if (!this.$options.components) this.$options.components = {};
39
+ this.$options.components.SchemaEditor = SchemaEditor;
40
+ },
37
41
  props: {
38
42
  schema: { type: Object, required: true },
39
43
  modelValue: { default: null },
@@ -29,11 +29,14 @@
29
29
  </template>
30
30
 
31
31
  <script>
32
- import { defineAsyncComponent } from 'vue';
32
+ import SchemaEditor from './SchemaEditor.vue';
33
33
 
34
34
  export default {
35
35
  name: 'ObjectEditor',
36
- components: { SchemaEditor: defineAsyncComponent(() => import('./SchemaEditor.vue')) },
36
+ beforeCreate() {
37
+ if (!this.$options.components) this.$options.components = {};
38
+ this.$options.components.SchemaEditor = SchemaEditor;
39
+ },
37
40
  props: {
38
41
  schema: { type: Object, required: true },
39
42
  modelValue: { default: () => ({}) },
@@ -20,12 +20,16 @@
20
20
  </template>
21
21
 
22
22
  <script>
23
- import { defineAsyncComponent } from 'vue';
24
23
  import { getDefaultForSchema } from '../utils';
25
24
 
25
+ import SchemaEditor from './SchemaEditor.vue';
26
+
26
27
  export default {
27
28
  name: 'UnionEditor',
28
- components: { SchemaEditor: defineAsyncComponent(() => import('./SchemaEditor.vue')) },
29
+ beforeCreate() {
30
+ if (!this.$options.components) this.$options.components = {};
31
+ this.$options.components.SchemaEditor = SchemaEditor;
32
+ },
29
33
  props: {
30
34
  schema: { type: Object, required: true },
31
35
  modelValue: { default: null },
package/src/index.js CHANGED
@@ -13,140 +13,13 @@ export { default as NullableEditor } from './editors/NullableEditor.vue';
13
13
  export { default as UnionEditor } from './editors/UnionEditor.vue';
14
14
  export { default as RelationEditor } from './editors/RelationEditor.vue';
15
15
 
16
- import { createApp, h, ref, reactive } from 'vue';
16
+ import { defineCustomElement } from 'vue';
17
17
  import SchemaFormComponent from './SchemaForm.vue';
18
18
 
19
- export class SchemaFormElement extends HTMLElement {
20
- constructor() {
21
- super();
22
- this._formRef = ref(null);
23
- this._props = reactive({
24
- schema: {},
25
- initialData: undefined,
26
- errors: {},
27
- });
28
- this._app = null;
29
- this._mountPoint = null;
30
- }
31
-
32
- connectedCallback() {
33
- this._mountPoint = document.createElement('div');
34
- this.appendChild(this._mountPoint);
35
-
36
- // Read from attributes if properties haven't been set programmatically
37
- if (!this._propsSet) {
38
- const schemaAttr = this.getAttribute('schema');
39
- const dataAttr = this.getAttribute('initial-data');
40
- if (schemaAttr) this._props.schema = JSON.parse(schemaAttr);
41
- if (dataAttr) this._props.initialData = JSON.parse(dataAttr);
42
- }
43
-
44
- const formRef = this._formRef;
45
- const props = this._props;
46
-
47
- this._app = createApp({
48
- render: () => h(SchemaFormComponent, {
49
- ref: formRef,
50
- schema: props.schema,
51
- initialData: props.initialData,
52
- errors: props.errors,
53
- onChange: (val) => {
54
- this.dispatchEvent(new CustomEvent('change', { detail: val, bubbles: true }));
55
- },
56
- }),
57
- });
58
-
59
- this._app.mount(this._mountPoint);
60
- }
61
-
62
- disconnectedCallback() {
63
- if (this._app) {
64
- this._app.unmount();
65
- this._app = null;
66
- }
67
- this._mountPoint = null;
68
- }
69
-
70
- // --- Property API ---
71
-
72
- get schema() {
73
- return this._props.schema;
74
- }
75
-
76
- set schema(val) {
77
- this._propsSet = true;
78
- this._props.schema = typeof val === 'string' ? JSON.parse(val) : val;
79
- this._rerender();
80
- }
81
-
82
- get initialData() {
83
- return this._props.initialData;
84
- }
85
-
86
- set initialData(val) {
87
- this._propsSet = true;
88
- this._props.initialData = typeof val === 'string' ? JSON.parse(val) : val;
89
- this._rerender();
90
- }
91
-
92
- get errors() {
93
- return this._props.errors;
94
- }
95
-
96
- set errors(val) {
97
- this._propsSet = true;
98
- this._props.errors = typeof val === 'string' ? JSON.parse(val) : (val || {});
99
- this._rerender();
100
- }
101
-
102
- // --- Attribute reflection ---
103
-
104
- static get observedAttributes() {
105
- return ['schema', 'initial-data', 'errors'];
106
- }
107
-
108
- attributeChangedCallback(name, oldVal, newVal) {
109
- if (oldVal === newVal || this._propsSet) return;
110
- if (name === 'schema') {
111
- this._props.schema = newVal ? JSON.parse(newVal) : {};
112
- } else if (name === 'initial-data') {
113
- this._props.initialData = newVal ? JSON.parse(newVal) : undefined;
114
- } else if (name === 'errors') {
115
- this._props.errors = newVal ? JSON.parse(newVal) : {};
116
- }
117
- this._rerender();
118
- }
119
-
120
- // --- Public methods ---
121
-
122
- getValue() {
123
- return this._formRef.value?.getValue?.() ?? null;
124
- }
125
-
126
- // --- Internal ---
127
-
128
- _rerender() {
129
- if (!this._app) return;
130
- this._app.unmount();
131
- this._mountPoint.innerHTML = '';
132
- const formRef = this._formRef;
133
- const props = this._props;
134
-
135
- this._app = createApp({
136
- render: () => h(SchemaFormComponent, {
137
- ref: formRef,
138
- schema: props.schema,
139
- initialData: props.initialData,
140
- errors: props.errors,
141
- onChange: (val) => {
142
- this.dispatchEvent(new CustomEvent('change', { detail: val, bubbles: true }));
143
- },
144
- }),
145
- });
146
-
147
- this._app.mount(this._mountPoint);
148
- }
149
- }
19
+ export const SchemaFormElement = defineCustomElement({
20
+ ...SchemaFormComponent,
21
+ shadowRoot: false,
22
+ });
150
23
 
151
24
  export function registerCustomElement(tagName = 'schema-form') {
152
25
  if (!customElements.get(tagName)) {