@statezero/core 0.2.37 → 0.2.38
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/adaptors/vue/components/LayoutRenderer.js +166 -0
- package/dist/adaptors/vue/components/defaults/AlertElement.js +31 -0
- package/dist/adaptors/vue/components/defaults/DisplayElement.js +44 -0
- package/dist/adaptors/vue/components/defaults/DividerElement.js +10 -0
- package/dist/adaptors/vue/components/defaults/ErrorBlock.js +24 -0
- package/dist/adaptors/vue/components/defaults/GroupElement.js +41 -0
- package/dist/adaptors/vue/components/defaults/LabelElement.js +21 -0
- package/dist/adaptors/vue/components/defaults/TabsElement.js +38 -0
- package/package.json +6 -4
- package/dist/actions/backend1/django_app/calculate-hash.d.ts +0 -57
- package/dist/actions/backend1/django_app/calculate-hash.js +0 -80
- package/dist/actions/backend1/django_app/calculate-hash.schema.json +0 -148
- package/dist/actions/backend1/django_app/get-current-username.d.ts +0 -29
- package/dist/actions/backend1/django_app/get-current-username.js +0 -65
- package/dist/actions/backend1/django_app/get-current-username.schema.json +0 -47
- package/dist/actions/backend1/django_app/get-server-status.d.ts +0 -38
- package/dist/actions/backend1/django_app/get-server-status.js +0 -68
- package/dist/actions/backend1/django_app/get-server-status.schema.json +0 -93
- package/dist/actions/backend1/django_app/get-user-info.d.ts +0 -44
- package/dist/actions/backend1/django_app/get-user-info.js +0 -70
- package/dist/actions/backend1/django_app/get-user-info.schema.json +0 -127
- package/dist/actions/backend1/django_app/index.d.ts +0 -1
- package/dist/actions/backend1/django_app/index.js +0 -6
- package/dist/actions/backend1/django_app/process-data.d.ts +0 -51
- package/dist/actions/backend1/django_app/process-data.js +0 -78
- package/dist/actions/backend1/django_app/process-data.schema.json +0 -117
- package/dist/actions/backend1/django_app/send-notification.d.ts +0 -55
- package/dist/actions/backend1/django_app/send-notification.js +0 -81
- package/dist/actions/backend1/django_app/send-notification.schema.json +0 -175
- package/dist/actions/backend1/index.d.ts +0 -1
- package/dist/actions/backend1/index.js +0 -1
- package/dist/actions/default/django_app/calculate-hash.d.ts +0 -57
- package/dist/actions/default/django_app/calculate-hash.js +0 -80
- package/dist/actions/default/django_app/calculate-hash.schema.json +0 -148
- package/dist/actions/default/django_app/get-current-username.d.ts +0 -29
- package/dist/actions/default/django_app/get-current-username.js +0 -65
- package/dist/actions/default/django_app/get-current-username.schema.json +0 -47
- package/dist/actions/default/django_app/get-server-status.d.ts +0 -38
- package/dist/actions/default/django_app/get-server-status.js +0 -68
- package/dist/actions/default/django_app/get-server-status.schema.json +0 -93
- package/dist/actions/default/django_app/get-user-info.d.ts +0 -44
- package/dist/actions/default/django_app/get-user-info.js +0 -70
- package/dist/actions/default/django_app/get-user-info.schema.json +0 -127
- package/dist/actions/default/django_app/index.d.ts +0 -1
- package/dist/actions/default/django_app/index.js +0 -6
- package/dist/actions/default/django_app/process-data.d.ts +0 -51
- package/dist/actions/default/django_app/process-data.js +0 -78
- package/dist/actions/default/django_app/process-data.schema.json +0 -117
- package/dist/actions/default/django_app/send-notification.d.ts +0 -55
- package/dist/actions/default/django_app/send-notification.js +0 -81
- package/dist/actions/default/django_app/send-notification.schema.json +0 -175
- package/dist/actions/default/index.d.ts +0 -1
- package/dist/actions/default/index.js +0 -1
- package/dist/actions/index.d.ts +0 -1
- package/dist/actions/index.js +0 -5
- package/dist/adaptors/react/composables.d.ts +0 -1
- package/dist/adaptors/react/composables.js +0 -4
- package/dist/adaptors/react/index.d.ts +0 -1
- package/dist/adaptors/react/index.js +0 -1
- package/dist/adaptors/vue/components/LayoutRenderer.vue +0 -361
- package/dist/adaptors/vue/components/defaults/AlertElement.vue +0 -38
- package/dist/adaptors/vue/components/defaults/DisplayElement.vue +0 -57
- package/dist/adaptors/vue/components/defaults/DividerElement.vue +0 -13
- package/dist/adaptors/vue/components/defaults/ErrorBlock.vue +0 -28
- package/dist/adaptors/vue/components/defaults/GroupElement.vue +0 -53
- package/dist/adaptors/vue/components/defaults/LabelElement.vue +0 -25
- package/dist/adaptors/vue/components/defaults/TabsElement.vue +0 -54
- package/dist/adaptors/vue/components/defaults/index.d.ts +0 -7
- package/dist/adaptors/vue/components/defaults/index.js +0 -31
- package/dist/adaptors/vue/components/index.d.ts +0 -1
- package/dist/adaptors/vue/components/index.js +0 -7
- package/dist/adaptors/vue/composables.d.ts +0 -2
- package/dist/adaptors/vue/composables.js +0 -44
- package/dist/adaptors/vue/index.d.ts +0 -3
- package/dist/adaptors/vue/index.js +0 -4
- package/dist/adaptors/vue/reactivity.d.ts +0 -18
- package/dist/adaptors/vue/reactivity.js +0 -132
- package/dist/cli/commands/sync.d.ts +0 -6
- package/dist/cli/commands/sync.js +0 -30
- package/dist/cli/commands/syncActions.d.ts +0 -46
- package/dist/cli/commands/syncActions.js +0 -717
- package/dist/cli/commands/syncModels.d.ts +0 -132
- package/dist/cli/commands/syncModels.js +0 -1120
- package/dist/cli/configFileLoader.d.ts +0 -10
- package/dist/cli/configFileLoader.js +0 -85
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.js +0 -22
- package/dist/config.d.ts +0 -57
- package/dist/config.js +0 -273
- package/dist/core/eventReceivers.d.ts +0 -185
- package/dist/core/eventReceivers.js +0 -266
- package/dist/core/utils.d.ts +0 -8
- package/dist/core/utils.js +0 -62
- package/dist/errorHandler.d.ts +0 -21
- package/dist/errorHandler.js +0 -27
- package/dist/filtering/localFiltering.d.ts +0 -110
- package/dist/filtering/localFiltering.js +0 -1080
- package/dist/flavours/django/dates.d.ts +0 -34
- package/dist/flavours/django/dates.js +0 -113
- package/dist/flavours/django/errors.d.ts +0 -138
- package/dist/flavours/django/errors.js +0 -195
- package/dist/flavours/django/f.d.ts +0 -6
- package/dist/flavours/django/f.js +0 -91
- package/dist/flavours/django/files.d.ts +0 -62
- package/dist/flavours/django/files.js +0 -355
- package/dist/flavours/django/makeApiCall.d.ts +0 -36
- package/dist/flavours/django/makeApiCall.js +0 -169
- package/dist/flavours/django/manager.d.ts +0 -204
- package/dist/flavours/django/manager.js +0 -222
- package/dist/flavours/django/model.d.ts +0 -137
- package/dist/flavours/django/model.js +0 -366
- package/dist/flavours/django/operationFactory.d.ts +0 -73
- package/dist/flavours/django/operationFactory.js +0 -248
- package/dist/flavours/django/q.d.ts +0 -70
- package/dist/flavours/django/q.js +0 -43
- package/dist/flavours/django/queryExecutor.d.ts +0 -149
- package/dist/flavours/django/queryExecutor.js +0 -590
- package/dist/flavours/django/querySet.d.ts +0 -301
- package/dist/flavours/django/querySet.js +0 -736
- package/dist/flavours/django/serializers.d.ts +0 -39
- package/dist/flavours/django/serializers.js +0 -296
- package/dist/flavours/django/tempPk.d.ts +0 -31
- package/dist/flavours/django/tempPk.js +0 -92
- package/dist/flavours/django/utils.d.ts +0 -19
- package/dist/flavours/django/utils.js +0 -29
- package/dist/index.d.ts +0 -46
- package/dist/index.js +0 -48
- package/dist/models/backend1/django_app/comprehensivemodel.d.ts +0 -894
- package/dist/models/backend1/django_app/comprehensivemodel.js +0 -71
- package/dist/models/backend1/django_app/comprehensivemodel.schema.json +0 -870
- package/dist/models/backend1/django_app/custompkmodel.d.ts +0 -92
- package/dist/models/backend1/django_app/custompkmodel.js +0 -69
- package/dist/models/backend1/django_app/custompkmodel.schema.json +0 -71
- package/dist/models/backend1/django_app/dailyrate.d.ts +0 -230
- package/dist/models/backend1/django_app/dailyrate.js +0 -71
- package/dist/models/backend1/django_app/dailyrate.schema.json +0 -212
- package/dist/models/backend1/django_app/deepmodellevel1.d.ts +0 -140
- package/dist/models/backend1/django_app/deepmodellevel1.js +0 -72
- package/dist/models/backend1/django_app/deepmodellevel1.schema.json +0 -114
- package/dist/models/backend1/django_app/deepmodellevel2.d.ts +0 -118
- package/dist/models/backend1/django_app/deepmodellevel2.js +0 -71
- package/dist/models/backend1/django_app/deepmodellevel2.schema.json +0 -92
- package/dist/models/backend1/django_app/deepmodellevel3.d.ts +0 -92
- package/dist/models/backend1/django_app/deepmodellevel3.js +0 -69
- package/dist/models/backend1/django_app/deepmodellevel3.schema.json +0 -69
- package/dist/models/backend1/django_app/dummymodel.d.ts +0 -134
- package/dist/models/backend1/django_app/dummymodel.js +0 -71
- package/dist/models/backend1/django_app/dummymodel.schema.json +0 -109
- package/dist/models/backend1/django_app/dummyrelatedmodel.d.ts +0 -92
- package/dist/models/backend1/django_app/dummyrelatedmodel.js +0 -69
- package/dist/models/backend1/django_app/dummyrelatedmodel.schema.json +0 -69
- package/dist/models/backend1/django_app/filetest.d.ts +0 -140
- package/dist/models/backend1/django_app/filetest.js +0 -69
- package/dist/models/backend1/django_app/filetest.schema.json +0 -111
- package/dist/models/backend1/django_app/index.d.ts +0 -1
- package/dist/models/backend1/django_app/index.js +0 -21
- package/dist/models/backend1/django_app/m2mdepthtestlevel1.d.ts +0 -118
- package/dist/models/backend1/django_app/m2mdepthtestlevel1.js +0 -71
- package/dist/models/backend1/django_app/m2mdepthtestlevel1.schema.json +0 -94
- package/dist/models/backend1/django_app/m2mdepthtestlevel2.d.ts +0 -118
- package/dist/models/backend1/django_app/m2mdepthtestlevel2.js +0 -71
- package/dist/models/backend1/django_app/m2mdepthtestlevel2.schema.json +0 -94
- package/dist/models/backend1/django_app/m2mdepthtestlevel3.d.ts +0 -134
- package/dist/models/backend1/django_app/m2mdepthtestlevel3.js +0 -71
- package/dist/models/backend1/django_app/m2mdepthtestlevel3.schema.json +0 -112
- package/dist/models/backend1/django_app/modelwithcustompkrelation.d.ts +0 -118
- package/dist/models/backend1/django_app/modelwithcustompkrelation.js +0 -71
- package/dist/models/backend1/django_app/modelwithcustompkrelation.schema.json +0 -93
- package/dist/models/backend1/django_app/modelwithrestrictedfields.d.ts +0 -134
- package/dist/models/backend1/django_app/modelwithrestrictedfields.js +0 -71
- package/dist/models/backend1/django_app/modelwithrestrictedfields.schema.json +0 -111
- package/dist/models/backend1/django_app/namefiltercustompkmodel.d.ts +0 -92
- package/dist/models/backend1/django_app/namefiltercustompkmodel.js +0 -69
- package/dist/models/backend1/django_app/namefiltercustompkmodel.schema.json +0 -71
- package/dist/models/backend1/django_app/order.d.ts +0 -220
- package/dist/models/backend1/django_app/order.js +0 -71
- package/dist/models/backend1/django_app/order.schema.json +0 -203
- package/dist/models/backend1/django_app/orderitem.d.ts +0 -172
- package/dist/models/backend1/django_app/orderitem.js +0 -72
- package/dist/models/backend1/django_app/orderitem.schema.json +0 -149
- package/dist/models/backend1/django_app/product.d.ts +0 -254
- package/dist/models/backend1/django_app/product.js +0 -71
- package/dist/models/backend1/django_app/product.schema.json +0 -277
- package/dist/models/backend1/django_app/productcategory.d.ts +0 -92
- package/dist/models/backend1/django_app/productcategory.js +0 -69
- package/dist/models/backend1/django_app/productcategory.schema.json +0 -70
- package/dist/models/backend1/django_app/rateplan.d.ts +0 -92
- package/dist/models/backend1/django_app/rateplan.js +0 -69
- package/dist/models/backend1/django_app/rateplan.schema.json +0 -70
- package/dist/models/backend1/django_app/restrictedfieldrelatedmodel.d.ts +0 -108
- package/dist/models/backend1/django_app/restrictedfieldrelatedmodel.js +0 -69
- package/dist/models/backend1/django_app/restrictedfieldrelatedmodel.schema.json +0 -87
- package/dist/models/backend1/fileobject.d.ts +0 -4
- package/dist/models/backend1/fileobject.js +0 -9
- package/dist/models/backend1/index.d.ts +0 -2
- package/dist/models/backend1/index.js +0 -2
- package/dist/models/default/django_app/comprehensivemodel.d.ts +0 -894
- package/dist/models/default/django_app/comprehensivemodel.js +0 -71
- package/dist/models/default/django_app/comprehensivemodel.schema.json +0 -870
- package/dist/models/default/django_app/custompkmodel.d.ts +0 -92
- package/dist/models/default/django_app/custompkmodel.js +0 -69
- package/dist/models/default/django_app/custompkmodel.schema.json +0 -71
- package/dist/models/default/django_app/dailyrate.d.ts +0 -230
- package/dist/models/default/django_app/dailyrate.js +0 -71
- package/dist/models/default/django_app/dailyrate.schema.json +0 -212
- package/dist/models/default/django_app/deepmodellevel1.d.ts +0 -128
- package/dist/models/default/django_app/deepmodellevel1.js +0 -72
- package/dist/models/default/django_app/deepmodellevel1.schema.json +0 -102
- package/dist/models/default/django_app/deepmodellevel2.d.ts +0 -106
- package/dist/models/default/django_app/deepmodellevel2.js +0 -71
- package/dist/models/default/django_app/deepmodellevel2.schema.json +0 -80
- package/dist/models/default/django_app/deepmodellevel3.d.ts +0 -80
- package/dist/models/default/django_app/deepmodellevel3.js +0 -69
- package/dist/models/default/django_app/deepmodellevel3.schema.json +0 -57
- package/dist/models/default/django_app/dummymodel.d.ts +0 -122
- package/dist/models/default/django_app/dummymodel.js +0 -71
- package/dist/models/default/django_app/dummymodel.schema.json +0 -97
- package/dist/models/default/django_app/dummyrelatedmodel.d.ts +0 -80
- package/dist/models/default/django_app/dummyrelatedmodel.js +0 -69
- package/dist/models/default/django_app/dummyrelatedmodel.schema.json +0 -57
- package/dist/models/default/django_app/filetest.d.ts +0 -128
- package/dist/models/default/django_app/filetest.js +0 -69
- package/dist/models/default/django_app/filetest.schema.json +0 -99
- package/dist/models/default/django_app/index.d.ts +0 -1
- package/dist/models/default/django_app/index.js +0 -21
- package/dist/models/default/django_app/m2mdepthtestlevel1.d.ts +0 -118
- package/dist/models/default/django_app/m2mdepthtestlevel1.js +0 -71
- package/dist/models/default/django_app/m2mdepthtestlevel1.schema.json +0 -94
- package/dist/models/default/django_app/m2mdepthtestlevel2.d.ts +0 -118
- package/dist/models/default/django_app/m2mdepthtestlevel2.js +0 -71
- package/dist/models/default/django_app/m2mdepthtestlevel2.schema.json +0 -94
- package/dist/models/default/django_app/m2mdepthtestlevel3.d.ts +0 -134
- package/dist/models/default/django_app/m2mdepthtestlevel3.js +0 -71
- package/dist/models/default/django_app/m2mdepthtestlevel3.schema.json +0 -112
- package/dist/models/default/django_app/modelwithcustompkrelation.d.ts +0 -118
- package/dist/models/default/django_app/modelwithcustompkrelation.js +0 -71
- package/dist/models/default/django_app/modelwithcustompkrelation.schema.json +0 -93
- package/dist/models/default/django_app/modelwithrestrictedfields.d.ts +0 -134
- package/dist/models/default/django_app/modelwithrestrictedfields.js +0 -71
- package/dist/models/default/django_app/modelwithrestrictedfields.schema.json +0 -111
- package/dist/models/default/django_app/namefiltercustompkmodel.d.ts +0 -92
- package/dist/models/default/django_app/namefiltercustompkmodel.js +0 -69
- package/dist/models/default/django_app/namefiltercustompkmodel.schema.json +0 -71
- package/dist/models/default/django_app/order.d.ts +0 -220
- package/dist/models/default/django_app/order.js +0 -71
- package/dist/models/default/django_app/order.schema.json +0 -203
- package/dist/models/default/django_app/orderitem.d.ts +0 -172
- package/dist/models/default/django_app/orderitem.js +0 -72
- package/dist/models/default/django_app/orderitem.schema.json +0 -149
- package/dist/models/default/django_app/product.d.ts +0 -254
- package/dist/models/default/django_app/product.js +0 -71
- package/dist/models/default/django_app/product.schema.json +0 -277
- package/dist/models/default/django_app/productcategory.d.ts +0 -92
- package/dist/models/default/django_app/productcategory.js +0 -69
- package/dist/models/default/django_app/productcategory.schema.json +0 -70
- package/dist/models/default/django_app/rateplan.d.ts +0 -92
- package/dist/models/default/django_app/rateplan.js +0 -69
- package/dist/models/default/django_app/rateplan.schema.json +0 -70
- package/dist/models/default/django_app/restrictedfieldrelatedmodel.d.ts +0 -108
- package/dist/models/default/django_app/restrictedfieldrelatedmodel.js +0 -69
- package/dist/models/default/django_app/restrictedfieldrelatedmodel.schema.json +0 -87
- package/dist/models/default/fileobject.d.ts +0 -4
- package/dist/models/default/fileobject.js +0 -9
- package/dist/models/default/index.d.ts +0 -2
- package/dist/models/default/index.js +0 -2
- package/dist/models/index.d.ts +0 -1
- package/dist/models/index.js +0 -5
- package/dist/react-entry.d.ts +0 -2
- package/dist/react-entry.js +0 -2
- package/dist/reactiveAdaptor.d.ts +0 -24
- package/dist/reactiveAdaptor.js +0 -38
- package/dist/reset.d.ts +0 -15
- package/dist/reset.js +0 -97
- package/dist/setup.d.ts +0 -15
- package/dist/setup.js +0 -33
- package/dist/syncEngine/cache/cache.d.ts +0 -75
- package/dist/syncEngine/cache/cache.js +0 -355
- package/dist/syncEngine/metrics/metricOptCalcs.d.ts +0 -79
- package/dist/syncEngine/metrics/metricOptCalcs.js +0 -284
- package/dist/syncEngine/registries/metricRegistry.d.ts +0 -58
- package/dist/syncEngine/registries/metricRegistry.js +0 -171
- package/dist/syncEngine/registries/modelStoreRegistry.d.ts +0 -11
- package/dist/syncEngine/registries/modelStoreRegistry.js +0 -63
- package/dist/syncEngine/registries/querysetStoreGraph.d.ts +0 -41
- package/dist/syncEngine/registries/querysetStoreGraph.js +0 -174
- package/dist/syncEngine/registries/querysetStoreRegistry.d.ts +0 -72
- package/dist/syncEngine/registries/querysetStoreRegistry.js +0 -335
- package/dist/syncEngine/stores/metricStore.d.ts +0 -55
- package/dist/syncEngine/stores/metricStore.js +0 -222
- package/dist/syncEngine/stores/modelStore.d.ts +0 -53
- package/dist/syncEngine/stores/modelStore.js +0 -565
- package/dist/syncEngine/stores/operation.d.ts +0 -139
- package/dist/syncEngine/stores/operation.js +0 -291
- package/dist/syncEngine/stores/operationEventHandlers.d.ts +0 -8
- package/dist/syncEngine/stores/operationEventHandlers.js +0 -322
- package/dist/syncEngine/stores/querysetStore.d.ts +0 -60
- package/dist/syncEngine/stores/querysetStore.js +0 -294
- package/dist/syncEngine/stores/reactivity.d.ts +0 -3
- package/dist/syncEngine/stores/reactivity.js +0 -4
- package/dist/syncEngine/stores/utils.d.ts +0 -14
- package/dist/syncEngine/stores/utils.js +0 -32
- package/dist/syncEngine/sync.d.ts +0 -46
- package/dist/syncEngine/sync.js +0 -389
- package/dist/testing.d.ts +0 -63
- package/dist/testing.js +0 -175
- package/dist/vue-entry.d.ts +0 -15
- package/dist/vue-entry.js +0 -7
|
@@ -1,361 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import { computed, provide, inject, onMounted, unref } from 'vue'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* LayoutRenderer - Renders a statezero layout tree
|
|
6
|
-
*
|
|
7
|
-
* Expects a components registry with implementations for each element type.
|
|
8
|
-
* Components must follow contracts (validated at mount time).
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const props = defineProps({
|
|
12
|
-
// The layout element to render (root or nested)
|
|
13
|
-
layout: { type: Object, required: true },
|
|
14
|
-
|
|
15
|
-
// Schema with field definitions (input_properties/properties)
|
|
16
|
-
schema: { type: Object, default: () => ({}) },
|
|
17
|
-
|
|
18
|
-
// Component registry: { Control, Display, Alert, Label, Divider, Group, Tabs, ErrorBlock }
|
|
19
|
-
components: { type: Object, required: true },
|
|
20
|
-
|
|
21
|
-
// Form data (v-model for Controls)
|
|
22
|
-
formData: { type: Object, default: () => ({}) },
|
|
23
|
-
|
|
24
|
-
// Workflow context (for Display elements)
|
|
25
|
-
context: { type: Object, default: () => ({}) },
|
|
26
|
-
|
|
27
|
-
// Errors object - can be raw DRF response: { fieldName: ['error'], non_field_errors: ['global error'] }
|
|
28
|
-
// The renderer automatically extracts non_field_errors/__all__ for the ErrorBlock
|
|
29
|
-
errors: { type: Object, default: () => ({}) },
|
|
30
|
-
|
|
31
|
-
// Explicit non-field errors (optional override - if not provided, extracted from errors.non_field_errors)
|
|
32
|
-
nonFieldErrors: { type: Array, default: null },
|
|
33
|
-
|
|
34
|
-
// Whether this is the root renderer (internal)
|
|
35
|
-
isRoot: { type: Boolean, default: true }
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
const emit = defineEmits(['update:formData'])
|
|
39
|
-
|
|
40
|
-
// Extract non-field errors from the errors object (DRF format)
|
|
41
|
-
// Supports both "non_field_errors" and "__all__" keys
|
|
42
|
-
const extractedNonFieldErrors = computed(() => {
|
|
43
|
-
// If explicit nonFieldErrors prop provided, use it
|
|
44
|
-
if (props.nonFieldErrors !== null) {
|
|
45
|
-
return props.nonFieldErrors
|
|
46
|
-
}
|
|
47
|
-
// Otherwise extract from errors object
|
|
48
|
-
const nfe = props.errors?.non_field_errors || props.errors?.__all__
|
|
49
|
-
if (!nfe) return []
|
|
50
|
-
if (Array.isArray(nfe)) {
|
|
51
|
-
return nfe.map(err => {
|
|
52
|
-
if (typeof err === 'string') return err
|
|
53
|
-
if (err?.message) return err.message
|
|
54
|
-
return String(err)
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
return [String(nfe)]
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
const rootComponents = computed(() => props.components)
|
|
61
|
-
const rootSchema = computed(() => props.schema)
|
|
62
|
-
const rootFormData = computed(() => props.formData)
|
|
63
|
-
const rootContext = computed(() => props.context)
|
|
64
|
-
const rootErrors = computed(() => props.errors)
|
|
65
|
-
|
|
66
|
-
// Provide context to nested renderers
|
|
67
|
-
if (props.isRoot) {
|
|
68
|
-
provide('layoutRenderer', {
|
|
69
|
-
components: rootComponents,
|
|
70
|
-
schema: rootSchema,
|
|
71
|
-
formData: rootFormData,
|
|
72
|
-
context: rootContext,
|
|
73
|
-
errors: rootErrors,
|
|
74
|
-
updateField: (fieldName, value) => {
|
|
75
|
-
const currentFormData = unref(rootFormData) || {}
|
|
76
|
-
emit('update:formData', { ...currentFormData, [fieldName]: value })
|
|
77
|
-
}
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Inject from parent if not root
|
|
82
|
-
const injected = props.isRoot ? null : inject('layoutRenderer', null)
|
|
83
|
-
const components = computed(() => props.isRoot ? props.components : (injected ? (unref(injected.components) || props.components) : props.components))
|
|
84
|
-
const schema = computed(() => props.isRoot ? props.schema : (injected ? (unref(injected.schema) || props.schema) : props.schema))
|
|
85
|
-
const formData = computed(() => props.isRoot ? props.formData : (injected ? (unref(injected.formData) || props.formData) : props.formData))
|
|
86
|
-
const context = computed(() => props.isRoot ? props.context : (injected ? (unref(injected.context) || props.context) : props.context))
|
|
87
|
-
const errors = computed(() => props.isRoot ? props.errors : (injected ? (unref(injected.errors) || props.errors) : props.errors))
|
|
88
|
-
const updateField = props.isRoot
|
|
89
|
-
? (fieldName, value) => emit('update:formData', { ...props.formData, [fieldName]: value })
|
|
90
|
-
: injected?.updateField || (() => {})
|
|
91
|
-
|
|
92
|
-
// Contract definitions for component validation
|
|
93
|
-
//
|
|
94
|
-
// Control: Polymorphic form field component (like AutoField)
|
|
95
|
-
// - Should check element.display_component for custom component override
|
|
96
|
-
// - Should use schema (type/format) to determine default field rendering
|
|
97
|
-
// - Receives: element (includes field_name, display_component, label, extra, etc.)
|
|
98
|
-
// modelValue, errors (array), context, formData, schema (field schema)
|
|
99
|
-
// - Emits: update:modelValue
|
|
100
|
-
//
|
|
101
|
-
// Display: Read-only component for showing context values
|
|
102
|
-
// - Receives: element (includes context_path, label, display_component), context, value (resolved)
|
|
103
|
-
// - No v-model binding, just displays value
|
|
104
|
-
//
|
|
105
|
-
const CONTRACTS = {
|
|
106
|
-
Control: {
|
|
107
|
-
props: ['element', 'modelValue', 'errors', 'context', 'formData', 'schema'],
|
|
108
|
-
emits: ['update:modelValue']
|
|
109
|
-
},
|
|
110
|
-
Display: {
|
|
111
|
-
props: ['element', 'context', 'value'],
|
|
112
|
-
emits: []
|
|
113
|
-
},
|
|
114
|
-
Alert: {
|
|
115
|
-
props: ['element', 'context', 'text'],
|
|
116
|
-
emits: []
|
|
117
|
-
},
|
|
118
|
-
Label: {
|
|
119
|
-
props: ['element'],
|
|
120
|
-
emits: []
|
|
121
|
-
},
|
|
122
|
-
Divider: {
|
|
123
|
-
props: [],
|
|
124
|
-
emits: []
|
|
125
|
-
},
|
|
126
|
-
Group: {
|
|
127
|
-
props: ['element'],
|
|
128
|
-
emits: []
|
|
129
|
-
},
|
|
130
|
-
Tabs: {
|
|
131
|
-
props: ['element'],
|
|
132
|
-
emits: []
|
|
133
|
-
},
|
|
134
|
-
ErrorBlock: {
|
|
135
|
-
props: ['errors'],
|
|
136
|
-
emits: []
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Validate components on mount (dev warning only)
|
|
141
|
-
function validateComponents(comps) {
|
|
142
|
-
for (const [type, component] of Object.entries(comps)) {
|
|
143
|
-
const contract = CONTRACTS[type]
|
|
144
|
-
if (!contract) continue
|
|
145
|
-
if (!component) {
|
|
146
|
-
console.warn(`[LayoutRenderer] Missing component for type: ${type}`)
|
|
147
|
-
continue
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Get component props (handle different formats)
|
|
151
|
-
let componentProps = []
|
|
152
|
-
if (component.props) {
|
|
153
|
-
if (Array.isArray(component.props)) {
|
|
154
|
-
componentProps = component.props
|
|
155
|
-
} else if (typeof component.props === 'object') {
|
|
156
|
-
componentProps = Object.keys(component.props)
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Get component emits
|
|
161
|
-
let componentEmits = []
|
|
162
|
-
if (component.emits) {
|
|
163
|
-
if (Array.isArray(component.emits)) {
|
|
164
|
-
componentEmits = component.emits
|
|
165
|
-
} else if (typeof component.emits === 'object') {
|
|
166
|
-
componentEmits = Object.keys(component.emits)
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Check required props
|
|
171
|
-
for (const prop of contract.props) {
|
|
172
|
-
if (!componentProps.includes(prop)) {
|
|
173
|
-
console.warn(`[LayoutRenderer] ${type} component missing required prop: "${prop}"`)
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Check required emits
|
|
178
|
-
for (const emitName of contract.emits) {
|
|
179
|
-
if (!componentEmits.includes(emitName)) {
|
|
180
|
-
console.warn(`[LayoutRenderer] ${type} component missing required emit: "${emitName}"`)
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
onMounted(() => {
|
|
187
|
-
if (props.isRoot && import.meta.env?.DEV) {
|
|
188
|
-
validateComponents(props.components)
|
|
189
|
-
}
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
// Evaluate conditional expressions
|
|
193
|
-
function evalCondition(expr) {
|
|
194
|
-
try {
|
|
195
|
-
return new Function('formData', 'context', `return ${expr}`)(formData.value, context.value)
|
|
196
|
-
} catch (e) {
|
|
197
|
-
console.warn('[LayoutRenderer] Conditional eval failed:', expr, e)
|
|
198
|
-
return false
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Get field schema from schema.properties or schema.input_properties
|
|
203
|
-
function getFieldSchema(fieldName) {
|
|
204
|
-
const props = schema.value?.properties || schema.value?.input_properties || {}
|
|
205
|
-
return props[fieldName] || {}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Get errors for a specific field (excludes non_field_errors/__all__)
|
|
209
|
-
function getFieldErrors(fieldName) {
|
|
210
|
-
if (fieldName === 'non_field_errors' || fieldName === '__all__') return []
|
|
211
|
-
const fieldErrors = errors.value?.[fieldName]
|
|
212
|
-
if (!fieldErrors) return []
|
|
213
|
-
// Normalize to array of strings (DRF can return array of strings or objects with message)
|
|
214
|
-
if (Array.isArray(fieldErrors)) {
|
|
215
|
-
return fieldErrors.map(err => {
|
|
216
|
-
if (typeof err === 'string') return err
|
|
217
|
-
if (err?.message) return err.message
|
|
218
|
-
return String(err)
|
|
219
|
-
})
|
|
220
|
-
}
|
|
221
|
-
return [String(fieldErrors)]
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Resolve context path (dot notation) to value
|
|
225
|
-
function resolveContextPath(path) {
|
|
226
|
-
if (!path) return undefined
|
|
227
|
-
const parts = path.split('.')
|
|
228
|
-
let value = context.value
|
|
229
|
-
for (const part of parts) {
|
|
230
|
-
if (value === null || value === undefined) return undefined
|
|
231
|
-
value = value[part]
|
|
232
|
-
}
|
|
233
|
-
return value
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
</script>
|
|
237
|
-
|
|
238
|
-
<template>
|
|
239
|
-
<!-- ErrorBlock at root level -->
|
|
240
|
-
<component
|
|
241
|
-
v-if="isRoot && extractedNonFieldErrors.length > 0 && components.ErrorBlock"
|
|
242
|
-
:is="components.ErrorBlock"
|
|
243
|
-
:errors="extractedNonFieldErrors"
|
|
244
|
-
/>
|
|
245
|
-
|
|
246
|
-
<!-- VerticalLayout -->
|
|
247
|
-
<div
|
|
248
|
-
v-if="layout.type === 'VerticalLayout'"
|
|
249
|
-
class="sz-layout sz-layout-vertical"
|
|
250
|
-
:class="`sz-gap-${layout.gap || 'md'}`"
|
|
251
|
-
>
|
|
252
|
-
<LayoutRenderer
|
|
253
|
-
v-for="(child, i) in layout.elements"
|
|
254
|
-
:key="i"
|
|
255
|
-
:layout="child"
|
|
256
|
-
:components="components"
|
|
257
|
-
:is-root="false"
|
|
258
|
-
/>
|
|
259
|
-
</div>
|
|
260
|
-
|
|
261
|
-
<!-- HorizontalLayout -->
|
|
262
|
-
<div
|
|
263
|
-
v-else-if="layout.type === 'HorizontalLayout'"
|
|
264
|
-
class="sz-layout sz-layout-horizontal"
|
|
265
|
-
:class="[`sz-gap-${layout.gap || 'md'}`, `sz-align-${layout.align || 'start'}`]"
|
|
266
|
-
>
|
|
267
|
-
<LayoutRenderer
|
|
268
|
-
v-for="(child, i) in layout.elements"
|
|
269
|
-
:key="i"
|
|
270
|
-
:layout="child"
|
|
271
|
-
:components="components"
|
|
272
|
-
:is-root="false"
|
|
273
|
-
/>
|
|
274
|
-
</div>
|
|
275
|
-
|
|
276
|
-
<!-- Group -->
|
|
277
|
-
<component
|
|
278
|
-
v-else-if="layout.type === 'Group'"
|
|
279
|
-
:is="components.Group"
|
|
280
|
-
:element="layout"
|
|
281
|
-
>
|
|
282
|
-
<LayoutRenderer
|
|
283
|
-
v-if="layout.layout"
|
|
284
|
-
:layout="layout.layout"
|
|
285
|
-
:components="components"
|
|
286
|
-
:is-root="false"
|
|
287
|
-
/>
|
|
288
|
-
</component>
|
|
289
|
-
|
|
290
|
-
<!-- Tabs -->
|
|
291
|
-
<component
|
|
292
|
-
v-else-if="layout.type === 'Tabs'"
|
|
293
|
-
:is="components.Tabs"
|
|
294
|
-
:element="layout"
|
|
295
|
-
>
|
|
296
|
-
<template #tab="{ tab }">
|
|
297
|
-
<LayoutRenderer
|
|
298
|
-
:layout="tab.layout"
|
|
299
|
-
:components="components"
|
|
300
|
-
:is-root="false"
|
|
301
|
-
/>
|
|
302
|
-
</template>
|
|
303
|
-
</component>
|
|
304
|
-
|
|
305
|
-
<!-- Conditional -->
|
|
306
|
-
<LayoutRenderer
|
|
307
|
-
v-else-if="layout.type === 'Conditional' && evalCondition(layout.when)"
|
|
308
|
-
:layout="layout.layout"
|
|
309
|
-
:components="components"
|
|
310
|
-
:is-root="false"
|
|
311
|
-
/>
|
|
312
|
-
|
|
313
|
-
<!-- Control (form field) -->
|
|
314
|
-
<component
|
|
315
|
-
v-else-if="layout.type === 'Control'"
|
|
316
|
-
:is="components.Control"
|
|
317
|
-
:element="layout"
|
|
318
|
-
:model-value="formData[layout.field_name]"
|
|
319
|
-
:errors="getFieldErrors(layout.field_name)"
|
|
320
|
-
:context="context"
|
|
321
|
-
:form-data="formData"
|
|
322
|
-
:schema="getFieldSchema(layout.field_name)"
|
|
323
|
-
@update:model-value="updateField(layout.field_name, $event)"
|
|
324
|
-
/>
|
|
325
|
-
|
|
326
|
-
<!-- Display -->
|
|
327
|
-
<component
|
|
328
|
-
v-else-if="layout.type === 'Display'"
|
|
329
|
-
:is="components.Display"
|
|
330
|
-
:element="layout"
|
|
331
|
-
:context="context"
|
|
332
|
-
:value="resolveContextPath(layout.context_path)"
|
|
333
|
-
/>
|
|
334
|
-
|
|
335
|
-
<!-- Alert -->
|
|
336
|
-
<component
|
|
337
|
-
v-else-if="layout.type === 'Alert'"
|
|
338
|
-
:is="components.Alert"
|
|
339
|
-
:element="layout"
|
|
340
|
-
:context="context"
|
|
341
|
-
:text="layout.text || resolveContextPath(layout.context_path)"
|
|
342
|
-
/>
|
|
343
|
-
|
|
344
|
-
<!-- Label -->
|
|
345
|
-
<component
|
|
346
|
-
v-else-if="layout.type === 'Label'"
|
|
347
|
-
:is="components.Label"
|
|
348
|
-
:element="layout"
|
|
349
|
-
/>
|
|
350
|
-
|
|
351
|
-
<!-- Divider -->
|
|
352
|
-
<component
|
|
353
|
-
v-else-if="layout.type === 'Divider'"
|
|
354
|
-
:is="components.Divider"
|
|
355
|
-
/>
|
|
356
|
-
|
|
357
|
-
<!-- Unknown type warning -->
|
|
358
|
-
<div v-else class="text-red-500 text-sm">
|
|
359
|
-
[LayoutRenderer] Unknown element type: {{ layout.type }}
|
|
360
|
-
</div>
|
|
361
|
-
</template>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
/**
|
|
3
|
-
* Default Alert element for LayoutRenderer
|
|
4
|
-
*
|
|
5
|
-
* Contract:
|
|
6
|
-
* - props: element, context, text
|
|
7
|
-
* - emits: none
|
|
8
|
-
*/
|
|
9
|
-
defineProps({
|
|
10
|
-
element: { type: Object, required: true },
|
|
11
|
-
context: { type: Object, default: () => ({}) },
|
|
12
|
-
text: { type: String, default: '' }
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
const severityClasses = {
|
|
16
|
-
info: 'bg-blue-500/10 border-blue-500/20 text-blue-400',
|
|
17
|
-
warning: 'bg-yellow-500/10 border-yellow-500/20 text-yellow-400',
|
|
18
|
-
error: 'bg-red-500/10 border-red-500/20 text-red-400',
|
|
19
|
-
success: 'bg-green-500/10 border-green-500/20 text-green-400'
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const severityIcons = {
|
|
23
|
-
info: 'ℹ️',
|
|
24
|
-
warning: '⚠️',
|
|
25
|
-
error: '❌',
|
|
26
|
-
success: '✓'
|
|
27
|
-
}
|
|
28
|
-
</script>
|
|
29
|
-
|
|
30
|
-
<template>
|
|
31
|
-
<div
|
|
32
|
-
class="flex items-start gap-3 p-3 rounded-lg border"
|
|
33
|
-
:class="severityClasses[element.severity] || severityClasses.info"
|
|
34
|
-
>
|
|
35
|
-
<span class="flex-shrink-0">{{ severityIcons[element.severity] || severityIcons.info }}</span>
|
|
36
|
-
<p class="text-sm">{{ text }}</p>
|
|
37
|
-
</div>
|
|
38
|
-
</template>
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
/**
|
|
3
|
-
* Default Display element for LayoutRenderer
|
|
4
|
-
*
|
|
5
|
-
* Renders context data in a display-only format.
|
|
6
|
-
* For custom rendering, use element.display_component and register custom components.
|
|
7
|
-
*
|
|
8
|
-
* Contract:
|
|
9
|
-
* - props: element, context, value
|
|
10
|
-
* - emits: none
|
|
11
|
-
*/
|
|
12
|
-
defineProps({
|
|
13
|
-
element: { type: Object, required: true },
|
|
14
|
-
context: { type: Object, default: () => ({}) },
|
|
15
|
-
value: { default: null }
|
|
16
|
-
})
|
|
17
|
-
</script>
|
|
18
|
-
|
|
19
|
-
<template>
|
|
20
|
-
<div class="space-y-1">
|
|
21
|
-
<label v-if="element.label" class="block text-sm font-medium text-muted-foreground">
|
|
22
|
-
{{ element.label }}
|
|
23
|
-
</label>
|
|
24
|
-
<div class="text-sm">
|
|
25
|
-
<!-- Default text display -->
|
|
26
|
-
<template v-if="!element.display_component || element.display_component === 'text'">
|
|
27
|
-
<span v-if="value !== null && value !== undefined">{{ value }}</span>
|
|
28
|
-
<span v-else class="text-muted-foreground italic">—</span>
|
|
29
|
-
</template>
|
|
30
|
-
|
|
31
|
-
<!-- Code display -->
|
|
32
|
-
<template v-else-if="element.display_component === 'code'">
|
|
33
|
-
<code class="px-2 py-1 bg-muted rounded font-mono text-sm">{{ value }}</code>
|
|
34
|
-
</template>
|
|
35
|
-
|
|
36
|
-
<!-- Copy URL display -->
|
|
37
|
-
<template v-else-if="element.display_component === 'copy-url'">
|
|
38
|
-
<div class="flex items-center gap-2">
|
|
39
|
-
<code class="flex-1 px-2 py-1 bg-muted rounded font-mono text-xs truncate">{{ value }}</code>
|
|
40
|
-
<button
|
|
41
|
-
type="button"
|
|
42
|
-
class="px-2 py-1 text-xs bg-primary text-primary-foreground rounded hover:bg-primary/90"
|
|
43
|
-
@click="navigator.clipboard.writeText(value)"
|
|
44
|
-
>
|
|
45
|
-
Copy
|
|
46
|
-
</button>
|
|
47
|
-
</div>
|
|
48
|
-
</template>
|
|
49
|
-
|
|
50
|
-
<!-- Fallback for unknown display_component -->
|
|
51
|
-
<template v-else>
|
|
52
|
-
<span>{{ value }}</span>
|
|
53
|
-
<span class="text-xs text-muted-foreground ml-2">({{ element.display_component }})</span>
|
|
54
|
-
</template>
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
</template>
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
/**
|
|
3
|
-
* Default ErrorBlock element for LayoutRenderer
|
|
4
|
-
*
|
|
5
|
-
* Displays non-field errors (global form errors).
|
|
6
|
-
*
|
|
7
|
-
* Contract:
|
|
8
|
-
* - props: errors (array of error strings)
|
|
9
|
-
* - emits: none
|
|
10
|
-
*/
|
|
11
|
-
defineProps({
|
|
12
|
-
errors: { type: Array, required: true }
|
|
13
|
-
})
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<template>
|
|
17
|
-
<div
|
|
18
|
-
v-if="errors.length > 0"
|
|
19
|
-
class="flex items-start gap-3 p-3 rounded-lg border bg-red-500/10 border-red-500/20"
|
|
20
|
-
>
|
|
21
|
-
<span class="flex-shrink-0 text-red-400">❌</span>
|
|
22
|
-
<div class="space-y-1">
|
|
23
|
-
<p v-for="(error, i) in errors" :key="i" class="text-sm text-red-400">
|
|
24
|
-
{{ error }}
|
|
25
|
-
</p>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
</template>
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import { ref } from 'vue'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Default Group element for LayoutRenderer
|
|
6
|
-
*
|
|
7
|
-
* A labeled section container. Children are rendered via default slot.
|
|
8
|
-
*
|
|
9
|
-
* Contract:
|
|
10
|
-
* - props: element
|
|
11
|
-
* - emits: none
|
|
12
|
-
* - slot: default (for nested layout content)
|
|
13
|
-
*/
|
|
14
|
-
const props = defineProps({
|
|
15
|
-
element: { type: Object, required: true }
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
const isCollapsed = ref(props.element.collapsed || false)
|
|
19
|
-
|
|
20
|
-
function toggleCollapse() {
|
|
21
|
-
if (props.element.collapsible) {
|
|
22
|
-
isCollapsed.value = !isCollapsed.value
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
</script>
|
|
26
|
-
|
|
27
|
-
<template>
|
|
28
|
-
<div class="border border-border rounded-lg overflow-hidden">
|
|
29
|
-
<!-- Header -->
|
|
30
|
-
<div
|
|
31
|
-
class="px-4 py-3 bg-muted/50"
|
|
32
|
-
:class="{ 'cursor-pointer hover:bg-muted/70': element.collapsible }"
|
|
33
|
-
@click="toggleCollapse"
|
|
34
|
-
>
|
|
35
|
-
<div class="flex items-center justify-between">
|
|
36
|
-
<div>
|
|
37
|
-
<h4 class="font-medium">{{ element.label }}</h4>
|
|
38
|
-
<p v-if="element.description" class="text-sm text-muted-foreground mt-0.5">
|
|
39
|
-
{{ element.description }}
|
|
40
|
-
</p>
|
|
41
|
-
</div>
|
|
42
|
-
<span v-if="element.collapsible" class="text-muted-foreground">
|
|
43
|
-
{{ isCollapsed ? '▶' : '▼' }}
|
|
44
|
-
</span>
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
|
|
48
|
-
<!-- Content -->
|
|
49
|
-
<div v-show="!isCollapsed" class="p-4">
|
|
50
|
-
<slot />
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
</template>
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
/**
|
|
3
|
-
* Default Label element for LayoutRenderer
|
|
4
|
-
*
|
|
5
|
-
* Contract:
|
|
6
|
-
* - props: element
|
|
7
|
-
* - emits: none
|
|
8
|
-
*/
|
|
9
|
-
defineProps({
|
|
10
|
-
element: { type: Object, required: true }
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
const variantClasses = {
|
|
14
|
-
heading: 'text-lg font-semibold',
|
|
15
|
-
subheading: 'text-base font-medium text-muted-foreground',
|
|
16
|
-
body: 'text-sm',
|
|
17
|
-
caption: 'text-xs text-muted-foreground'
|
|
18
|
-
}
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
<template>
|
|
22
|
-
<p :class="variantClasses[element.variant] || variantClasses.body">
|
|
23
|
-
{{ element.text }}
|
|
24
|
-
</p>
|
|
25
|
-
</template>
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import { ref } from 'vue'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Default Tabs element for LayoutRenderer
|
|
6
|
-
*
|
|
7
|
-
* A tabbed container. Tab content is rendered via scoped slot.
|
|
8
|
-
*
|
|
9
|
-
* Contract:
|
|
10
|
-
* - props: element
|
|
11
|
-
* - emits: none
|
|
12
|
-
* - slot: #tab="{ tab }" (for rendering each tab's content)
|
|
13
|
-
*/
|
|
14
|
-
const props = defineProps({
|
|
15
|
-
element: { type: Object, required: true }
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
const activeTab = ref(props.element.default_tab || 0)
|
|
19
|
-
|
|
20
|
-
function selectTab(index) {
|
|
21
|
-
activeTab.value = index
|
|
22
|
-
}
|
|
23
|
-
</script>
|
|
24
|
-
|
|
25
|
-
<template>
|
|
26
|
-
<div>
|
|
27
|
-
<!-- Tab buttons -->
|
|
28
|
-
<div class="flex border-b border-border">
|
|
29
|
-
<button
|
|
30
|
-
v-for="(tab, index) in element.tabs"
|
|
31
|
-
:key="index"
|
|
32
|
-
type="button"
|
|
33
|
-
class="px-4 py-2 text-sm font-medium transition-colors"
|
|
34
|
-
:class="[
|
|
35
|
-
activeTab === index
|
|
36
|
-
? 'text-primary border-b-2 border-primary -mb-px'
|
|
37
|
-
: 'text-muted-foreground hover:text-foreground'
|
|
38
|
-
]"
|
|
39
|
-
@click="selectTab(index)"
|
|
40
|
-
>
|
|
41
|
-
{{ tab.label }}
|
|
42
|
-
</button>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<!-- Tab content -->
|
|
46
|
-
<div class="pt-4">
|
|
47
|
-
<template v-for="(tab, index) in element.tabs" :key="index">
|
|
48
|
-
<div v-show="activeTab === index">
|
|
49
|
-
<slot name="tab" :tab="tab" :index="index" />
|
|
50
|
-
</div>
|
|
51
|
-
</template>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
</template>
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Create a default components registry (without Control - user must provide)
|
|
3
|
-
*
|
|
4
|
-
* @param {Object} options - Override specific components
|
|
5
|
-
* @returns {Object} Components registry for LayoutRenderer
|
|
6
|
-
*/
|
|
7
|
-
export function createDefaultComponents(options?: Object): Object;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default component implementations for LayoutRenderer
|
|
3
|
-
*
|
|
4
|
-
* These are minimal, unstyled implementations that follow the contracts.
|
|
5
|
-
* Users can use these as-is or as reference for custom implementations.
|
|
6
|
-
*/
|
|
7
|
-
export { default as AlertElement } from './AlertElement.vue';
|
|
8
|
-
export { default as LabelElement } from './LabelElement.vue';
|
|
9
|
-
export { default as DividerElement } from './DividerElement.vue';
|
|
10
|
-
export { default as DisplayElement } from './DisplayElement.vue';
|
|
11
|
-
export { default as GroupElement } from './GroupElement.vue';
|
|
12
|
-
export { default as TabsElement } from './TabsElement.vue';
|
|
13
|
-
export { default as ErrorBlock } from './ErrorBlock.vue';
|
|
14
|
-
/**
|
|
15
|
-
* Create a default components registry (without Control - user must provide)
|
|
16
|
-
*
|
|
17
|
-
* @param {Object} options - Override specific components
|
|
18
|
-
* @returns {Object} Components registry for LayoutRenderer
|
|
19
|
-
*/
|
|
20
|
-
export function createDefaultComponents(options = {}) {
|
|
21
|
-
return {
|
|
22
|
-
Alert: AlertElement,
|
|
23
|
-
Label: LabelElement,
|
|
24
|
-
Divider: DividerElement,
|
|
25
|
-
Display: DisplayElement,
|
|
26
|
-
Group: GroupElement,
|
|
27
|
-
Tabs: TabsElement,
|
|
28
|
-
ErrorBlock: ErrorBlock,
|
|
29
|
-
...options
|
|
30
|
-
};
|
|
31
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { AlertElement, LabelElement, DividerElement, DisplayElement, GroupElement, TabsElement, ErrorBlock, createDefaultComponents } from "./defaults/index.js";
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vue components for StateZero
|
|
3
|
-
*/
|
|
4
|
-
// Main layout renderer
|
|
5
|
-
export { default as LayoutRenderer } from './LayoutRenderer.vue';
|
|
6
|
-
// Default component implementations
|
|
7
|
-
export { AlertElement, LabelElement, DividerElement, DisplayElement, GroupElement, TabsElement, ErrorBlock, createDefaultComponents } from './defaults/index.js';
|