@cratis/scene.react 4.2.1 → 4.3.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 (51) hide show
  1. package/SceneElementView.tsx +13 -4
  2. package/core/CoreNavigationBar.tsx +53 -0
  3. package/core/coreComponents.ts +2 -0
  4. package/core/coreDescriptors.ts +75 -0
  5. package/core/corePackage.ts +3 -0
  6. package/core/index.ts +2 -0
  7. package/dist/cjs/SceneElementView.js +6 -2
  8. package/dist/cjs/SceneElementView.js.map +1 -1
  9. package/dist/cjs/core/CoreNavigationBar.js +49 -0
  10. package/dist/cjs/core/CoreNavigationBar.js.map +1 -0
  11. package/dist/cjs/core/coreComponents.js +3 -1
  12. package/dist/cjs/core/coreComponents.js.map +1 -1
  13. package/dist/cjs/core/coreDescriptors.js +162 -0
  14. package/dist/cjs/core/coreDescriptors.js.map +1 -0
  15. package/dist/cjs/core/corePackage.js +5 -2
  16. package/dist/cjs/core/corePackage.js.map +1 -1
  17. package/dist/cjs/index.js +4 -0
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/cjs/packages/ScenePackageBundle.js +33 -1
  20. package/dist/cjs/packages/ScenePackageBundle.js.map +1 -1
  21. package/dist/esm/SceneElementView.d.ts +3 -2
  22. package/dist/esm/SceneElementView.d.ts.map +1 -1
  23. package/dist/esm/SceneElementView.js +7 -3
  24. package/dist/esm/SceneElementView.js.map +1 -1
  25. package/dist/esm/core/CoreNavigationBar.d.ts +3 -0
  26. package/dist/esm/core/CoreNavigationBar.d.ts.map +1 -0
  27. package/dist/esm/core/CoreNavigationBar.js +47 -0
  28. package/dist/esm/core/CoreNavigationBar.js.map +1 -0
  29. package/dist/esm/core/coreComponents.d.ts.map +1 -1
  30. package/dist/esm/core/coreComponents.js +3 -1
  31. package/dist/esm/core/coreComponents.js.map +1 -1
  32. package/dist/esm/core/coreDescriptors.d.ts +3 -0
  33. package/dist/esm/core/coreDescriptors.d.ts.map +1 -0
  34. package/dist/esm/core/coreDescriptors.js +160 -0
  35. package/dist/esm/core/coreDescriptors.js.map +1 -0
  36. package/dist/esm/core/corePackage.d.ts.map +1 -1
  37. package/dist/esm/core/corePackage.js +5 -2
  38. package/dist/esm/core/corePackage.js.map +1 -1
  39. package/dist/esm/core/index.d.ts +2 -0
  40. package/dist/esm/core/index.d.ts.map +1 -1
  41. package/dist/esm/core/index.js +2 -0
  42. package/dist/esm/core/index.js.map +1 -1
  43. package/dist/esm/index.js +2 -0
  44. package/dist/esm/index.js.map +1 -1
  45. package/dist/esm/packages/ScenePackageBundle.d.ts +2 -1
  46. package/dist/esm/packages/ScenePackageBundle.d.ts.map +1 -1
  47. package/dist/esm/packages/ScenePackageBundle.js +33 -1
  48. package/dist/esm/packages/ScenePackageBundle.js.map +1 -1
  49. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +5 -5
  51. package/packages/ScenePackageBundle.ts +49 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/scene.react",
3
- "version": "4.2.1",
3
+ "version": "4.3.0",
4
4
  "description": "The React renderer implementing Scene.Engine's Renderer contract against real React/DOM.",
5
5
  "keywords": [
6
6
  "cratis",
@@ -51,12 +51,12 @@
51
51
  "build-storybook": "storybook build"
52
52
  },
53
53
  "dependencies": {
54
- "@cratis/scene.engine": "4.2.1",
55
- "@cratis/scene.model": "4.2.1"
54
+ "@cratis/scene.engine": "4.3.0",
55
+ "@cratis/scene.model": "4.3.0"
56
56
  },
57
57
  "devDependencies": {
58
- "@cratis/scene.engine": "4.2.1",
59
- "@cratis/scene.model": "4.2.1",
58
+ "@cratis/scene.engine": "4.3.0",
59
+ "@cratis/scene.model": "4.3.0",
60
60
  "@storybook/addon-links": "^10.6.1",
61
61
  "@storybook/react": "^10.6.1",
62
62
  "@storybook/react-vite": "^10.6.1",
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Cratis. All rights reserved.
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
 
4
- import { DialogTemplate, Layout, ScenePackage, Screen, ScreenTemplate, Theme } from '@cratis/scene.model';
4
+ import { ComponentDescriptor, DialogTemplate, Layout, PropertyValueType, ScenePackage, Screen, ScreenTemplate, Theme } from '@cratis/scene.model';
5
5
  import { ComponentRegistry } from '../renderer';
6
6
 
7
7
  /**
@@ -50,6 +50,14 @@ export interface ScenePackageBundle {
50
50
  */
51
51
  screens?: Screen[];
52
52
 
53
+ /**
54
+ * What can be edited on this package's components - one {@link ComponentDescriptor} per component that is
55
+ * editable at design time. They are data, so Studio reads them without rendering anything, and they travel with
56
+ * the components they describe rather than in a registry of their own. {@link validatePackageBundle} checks
57
+ * that every descriptor names a component the manifest declares.
58
+ */
59
+ descriptors?: ComponentDescriptor[];
60
+
53
61
  /**
54
62
  * The themes this package ships, if any.
55
63
  */
@@ -71,7 +79,8 @@ export function componentRegistryKey(packageName: string, componentName: string)
71
79
  }
72
80
 
73
81
  /**
74
- * Checks that a bundle provides everything its manifest declares, and declares everything it provides.
82
+ * Checks that a bundle provides everything its manifest declares, and declares everything it provides, and that
83
+ * every descriptor it ships is for a component it declares and is well formed.
75
84
  *
76
85
  * A manifest that promises a component the bundle does not register renders as `UnresolvedComponent` at
77
86
  * runtime — a blank box, far from where the mistake was made. A component registered but not declared is
@@ -123,6 +132,44 @@ export function validatePackageBundle(bundle: ScenePackageBundle): string[] {
123
132
  }
124
133
  }
125
134
 
135
+ problems.push(...validateDescriptors(bundle));
136
+ return problems;
137
+ }
138
+
139
+ function validateDescriptors(bundle: ScenePackageBundle): string[] {
140
+ const problems: string[] = [];
141
+ const declared = new Set(bundle.manifest.components.map((name) => componentRegistryKey(bundle.manifest.name, name)));
142
+ const described = new Set<string>();
143
+
144
+ for (const descriptor of bundle.descriptors ?? []) {
145
+ if (!declared.has(descriptor.component)) {
146
+ problems.push(`describes '${descriptor.component}', which the manifest does not declare as a component`);
147
+ }
148
+
149
+ if (described.has(descriptor.component)) {
150
+ problems.push(`describes '${descriptor.component}' more than once`);
151
+ }
152
+
153
+ described.add(descriptor.component);
154
+
155
+ const paths = new Set<string>();
156
+ for (const property of descriptor.properties) {
157
+ if (paths.has(property.path)) {
158
+ problems.push(`'${descriptor.component}' describes the property '${property.path}' more than once`);
159
+ }
160
+
161
+ paths.add(property.path);
162
+
163
+ if (property.valueType === PropertyValueType.Collection && property.item === undefined) {
164
+ problems.push(`'${descriptor.component}' describes the collection '${property.path}' without describing its items`);
165
+ }
166
+
167
+ if (property.valueType === PropertyValueType.Enum && (property.choices ?? []).length === 0) {
168
+ problems.push(`'${descriptor.component}' describes the enum '${property.path}' without choices`);
169
+ }
170
+ }
171
+ }
172
+
126
173
  return problems;
127
174
  }
128
175