@yahoo/uds-create-config 2.44.0 → 3.0.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.
- package/README.md +129 -0
- package/dist/ai-lanes.d.ts +23 -0
- package/dist/ai-lanes.js +34 -0
- package/dist/authoring/define-component.d.ts +85 -0
- package/dist/configs/CanvasConfig.d.ts +3237 -0
- package/dist/configs/CanvasConfig.js +332 -0
- package/dist/configs/build-options.d.ts +10 -0
- package/dist/configs/build-options.js +68 -0
- package/dist/configs/platform.d.ts +15 -0
- package/dist/configs/platform.js +17 -0
- package/dist/configs/react-native-system.d.ts +3026 -0
- package/dist/configs/react-native-system.js +64 -0
- package/dist/configs/system.d.ts +2771 -0
- package/dist/configs/system.js +74 -0
- package/dist/css/properties.generated.d.ts +14 -0
- package/dist/css/properties.generated.js +6260 -0
- package/dist/css/value-type.d.ts +48 -0
- package/dist/css/value-type.js +131 -0
- package/dist/css/values.d.ts +33 -0
- package/dist/css/values.js +116 -0
- package/dist/entities/native/NativeModifier.d.ts +25 -0
- package/dist/entities/native/NativeModifier.js +41 -0
- package/dist/entities/native/NativeSettings.d.ts +44 -0
- package/dist/entities/native/NativeSettings.js +39 -0
- package/dist/entities/native/NativeStyleProperty.d.ts +355 -0
- package/dist/entities/native/NativeStyleProperty.js +28 -0
- package/dist/entities/native/NativeToken.d.ts +31 -0
- package/dist/entities/native/NativeToken.js +49 -0
- package/dist/entities/system/CanvasRole.d.ts +34 -0
- package/dist/entities/system/CanvasRole.js +45 -0
- package/dist/entities/system/Component.d.ts +1287 -0
- package/dist/entities/system/Component.js +1840 -0
- package/dist/entities/system/Composite.d.ts +12 -0
- package/dist/entities/system/Composite.js +26 -0
- package/dist/entities/system/Device.d.ts +11 -0
- package/dist/entities/system/Device.js +18 -0
- package/dist/entities/system/File.d.ts +72 -0
- package/dist/entities/system/File.js +136 -0
- package/dist/entities/system/Font.d.ts +48 -0
- package/dist/entities/system/Font.js +56 -0
- package/dist/entities/system/GlobalStyle.d.ts +26 -0
- package/dist/entities/system/GlobalStyle.js +54 -0
- package/dist/entities/system/Guidance.d.ts +85 -0
- package/dist/entities/system/Guidance.js +59 -0
- package/dist/entities/system/GuidanceStyle.d.ts +14 -0
- package/dist/entities/system/GuidanceStyle.js +8 -0
- package/dist/entities/system/Icon.d.ts +46 -0
- package/dist/entities/system/Icon.js +46 -0
- package/dist/entities/system/LinkedSystem.d.ts +504 -0
- package/dist/entities/system/LinkedSystem.js +814 -0
- package/dist/entities/system/Modifier.d.ts +92 -0
- package/dist/entities/system/Modifier.js +120 -0
- package/dist/entities/system/Motion.d.ts +28 -0
- package/dist/entities/system/Motion.js +48 -0
- package/dist/entities/system/Operation.d.ts +100 -0
- package/dist/entities/system/Operation.js +236 -0
- package/dist/entities/system/Package.d.ts +42 -0
- package/dist/entities/system/Package.js +75 -0
- package/dist/entities/system/Settings.d.ts +94 -0
- package/dist/entities/system/Settings.js +166 -0
- package/dist/entities/system/StyleProperty.d.ts +135 -0
- package/dist/entities/system/StyleProperty.js +438 -0
- package/dist/entities/system/Token.d.ts +67 -0
- package/dist/entities/system/Token.js +129 -0
- package/dist/entities/system/Tool.d.ts +134 -0
- package/dist/entities/system/Tool.js +124 -0
- package/dist/entities/system/color.d.ts +64 -0
- package/dist/entities/system/color.js +123 -0
- package/dist/entities/system/component-module.d.ts +63 -0
- package/dist/entities/system/component-module.js +258 -0
- package/dist/entities/system/copy-plan.d.ts +98 -0
- package/dist/entities/system/copy-plan.js +451 -0
- package/dist/entities/system/defineComponent.d.ts +428 -0
- package/dist/entities/system/defineComponent.js +337 -0
- package/dist/entities/system/element.d.ts +101 -0
- package/dist/entities/system/element.js +171 -0
- package/dist/entities/system/icon-library.d.ts +64 -0
- package/dist/entities/system/icon-library.js +112 -0
- package/dist/entities/system/icon-metadata.d.ts +72 -0
- package/dist/entities/system/icon-metadata.js +111 -0
- package/dist/entities/system/link-declaration.d.ts +27 -0
- package/dist/entities/system/link-declaration.js +64 -0
- package/dist/entities/system/link-plan.d.ts +160 -0
- package/dist/entities/system/link-plan.js +770 -0
- package/dist/entities/system/runtime-modules.d.ts +25 -0
- package/dist/entities/system/runtime-modules.js +38 -0
- package/dist/entities/system/style-bag.d.ts +20 -0
- package/dist/entities/system/style-bag.js +246 -0
- package/dist/entities/system/token-index.d.ts +89 -0
- package/dist/entities/system/token-index.js +112 -0
- package/dist/framework/Config.d.ts +2472 -0
- package/dist/framework/Config.js +5023 -0
- package/dist/framework/Entity.d.ts +127 -0
- package/dist/framework/Entity.js +125 -0
- package/dist/framework/authoring.d.ts +24 -0
- package/dist/framework/authoring.js +7 -0
- package/dist/framework/change-hooks.d.ts +119 -0
- package/dist/framework/change-hooks.js +131 -0
- package/dist/framework/changes.d.ts +88 -0
- package/dist/framework/changes.js +246 -0
- package/dist/framework/class-names.d.ts +260 -0
- package/dist/framework/class-names.js +630 -0
- package/dist/framework/coalesce.d.ts +25 -0
- package/dist/framework/coalesce.js +60 -0
- package/dist/framework/config-op.d.ts +76 -0
- package/dist/framework/config-op.js +43 -0
- package/dist/framework/config-operation-kind.d.ts +14 -0
- package/dist/framework/config-operation-kind.js +14 -0
- package/dist/framework/config-ops.d.ts +34 -0
- package/dist/framework/config-ops.js +187 -0
- package/dist/framework/defineConfig.d.ts +196 -0
- package/dist/framework/defineConfig.js +100 -0
- package/dist/framework/defineDerivedEntity.d.ts +74 -0
- package/dist/framework/defineDerivedEntity.js +83 -0
- package/dist/framework/defineEntity.d.ts +318 -0
- package/dist/framework/defineEntity.js +183 -0
- package/dist/framework/defineSubEntity.d.ts +148 -0
- package/dist/framework/defineSubEntity.js +121 -0
- package/dist/framework/derived-mutations.d.ts +20 -0
- package/dist/framework/derived-mutations.js +38 -0
- package/dist/framework/entity-search.d.ts +29 -0
- package/dist/framework/entity-search.js +117 -0
- package/dist/framework/inline-sources.d.ts +49 -0
- package/dist/framework/inline-sources.js +388 -0
- package/dist/framework/layer-styles.d.ts +25 -0
- package/dist/framework/layer-styles.js +49 -0
- package/dist/framework/memo.d.ts +48 -0
- package/dist/framework/memo.js +84 -0
- package/dist/framework/overlay.d.ts +49 -0
- package/dist/framework/overlay.js +17 -0
- package/dist/framework/plan.d.ts +49 -0
- package/dist/framework/plan.js +73 -0
- package/dist/framework/projections.d.ts +480 -0
- package/dist/framework/projections.js +974 -0
- package/dist/framework/prop-surface.d.ts +132 -0
- package/dist/framework/prop-surface.js +278 -0
- package/dist/framework/ref-graph.d.ts +71 -0
- package/dist/framework/ref-graph.js +158 -0
- package/dist/framework/ref-integrity.d.ts +55 -0
- package/dist/framework/ref-integrity.js +171 -0
- package/dist/framework/registered.d.ts +95 -0
- package/dist/framework/registry-dir.d.ts +42 -0
- package/dist/framework/registry-dir.js +48 -0
- package/dist/framework/registry.d.ts +300 -0
- package/dist/framework/registry.js +104 -0
- package/dist/framework/rejection.d.ts +58 -0
- package/dist/framework/rejection.js +111 -0
- package/dist/framework/rename-inference.d.ts +26 -0
- package/dist/framework/rename-inference.js +50 -0
- package/dist/framework/render-spec.d.ts +296 -0
- package/dist/framework/render-spec.js +809 -0
- package/dist/framework/schema-version.d.ts +140 -0
- package/dist/framework/schema-version.js +214 -0
- package/dist/framework/schemas.d.ts +109 -0
- package/dist/framework/schemas.js +615 -0
- package/dist/framework/session.d.ts +196 -0
- package/dist/framework/session.js +367 -0
- package/dist/framework/signature.d.ts +15 -0
- package/dist/framework/signature.js +83 -0
- package/dist/framework/snapshot.d.ts +115 -0
- package/dist/framework/snapshot.js +277 -0
- package/dist/framework/source-integrity.d.ts +226 -0
- package/dist/framework/source-integrity.js +478 -0
- package/dist/framework/sources.d.ts +211 -0
- package/dist/framework/sources.js +89 -0
- package/dist/framework/utils/compiled-schema.d.ts +23 -0
- package/dist/framework/utils/compiled-schema.js +46 -0
- package/dist/framework/utils/content-key.d.ts +15 -0
- package/dist/framework/utils/content-key.js +33 -0
- package/dist/framework/utils/enumerated.d.ts +13 -0
- package/dist/framework/utils/enumerated.js +19 -0
- package/dist/framework/utils/field-path.d.ts +95 -0
- package/dist/framework/utils/field-path.js +136 -0
- package/dist/framework/utils/field-schema.d.ts +55 -0
- package/dist/framework/utils/field-schema.js +183 -0
- package/dist/framework/utils/group.d.ts +37 -0
- package/dist/framework/utils/group.js +13 -0
- package/dist/framework/utils/package-path.d.ts +37 -0
- package/dist/framework/utils/package-path.js +61 -0
- package/dist/framework/utils/refs.d.ts +194 -0
- package/dist/framework/utils/refs.js +403 -0
- package/dist/framework/validate-spec.d.ts +27 -0
- package/dist/framework/validate-spec.js +45 -0
- package/dist/framework/value-domain.d.ts +26 -0
- package/dist/framework/value-domain.js +202 -0
- package/dist/framework/views-facade.d.ts +15 -0
- package/dist/framework/views-facade.js +19 -0
- package/dist/index.d.ts +90 -42
- package/dist/index.js +86 -37
- package/dist/migrations/2.0.0/raw-css.d.ts +11 -0
- package/dist/migrations/2.0.0/raw-css.js +72 -0
- package/dist/migrations/2.0.0/v1-artifact.d.ts +1559 -0
- package/dist/migrations/2.0.0/v1-artifact.js +1018 -0
- package/dist/migrations/20260908171448_settings_as_kind.d.ts +22 -0
- package/dist/migrations/20260908171448_settings_as_kind.js +89 -0
- package/dist/migrations/20260908194245_visible_state_pointer.d.ts +19 -0
- package/dist/migrations/20260908194245_visible_state_pointer.js +115 -0
- package/dist/migrations/20260909183001_icon_knockout_variants.d.ts +18 -0
- package/dist/migrations/20260909183001_icon_knockout_variants.js +8 -0
- package/dist/migrations/20260910212453_linked_system_link_ops.d.ts +13 -0
- package/dist/migrations/20260910212453_linked_system_link_ops.js +8 -0
- package/dist/migrations/index.d.ts +2 -0
- package/dist/migrations/index.js +2 -0
- package/dist/react-native/style-keys.generated.d.ts +10 -0
- package/dist/react-native/style-keys.generated.js +167 -0
- package/dist/renderer/RendererErrorBoundary.d.ts +32 -5
- package/dist/renderer/RendererErrorBoundary.js +59 -10
- package/dist/renderer/UdsRenderer.d.ts +11 -10
- package/dist/renderer/UdsRenderer.js +1 -1
- package/dist/renderer/assetEntries.d.ts +37 -0
- package/dist/renderer/assetEntries.js +39 -0
- package/dist/renderer/assetRenderable.d.ts +14 -6
- package/dist/renderer/assetRenderable.js +8 -2
- package/dist/renderer/componentEntry.d.ts +58 -0
- package/dist/renderer/componentEntry.js +71 -0
- package/dist/renderer/icon-library.d.ts +20 -0
- package/dist/renderer/index.d.ts +7 -7
- package/dist/renderer/index.js +5 -5
- package/dist/renderer/primitives/SlotRenderer.d.ts +1 -1
- package/dist/renderer/primitives/SlotRenderer.js +1 -1
- package/dist/renderer/runtimeComponent.d.ts +33 -0
- package/dist/renderer/runtimeComponent.js +113 -0
- package/dist/renderer/spec-content.d.ts +43 -0
- package/dist/renderer/spec-content.js +95 -0
- package/dist/renderer/wrapRegistry.d.ts +22 -37
- package/dist/renderer/wrapRegistry.js +10 -20
- package/dist/renderer/wrappers/event-bridge.js +6 -5
- package/dist/renderer/wrappers/hex-normalize.js +6 -5
- package/dist/renderer/wrappers/html-aliases.d.ts +7 -2
- package/dist/renderer/wrappers/html-aliases.js +36 -19
- package/dist/renderer/wrappers/inline-styles.js +7 -6
- package/dist/spec/asset-jsx.d.ts +18 -5
- package/dist/spec/asset-jsx.js +27 -16
- package/dist/spec/collapse-text-labels.d.ts +5 -15
- package/dist/spec/collapse-text-labels.js +26 -19
- package/dist/spec/empty-node-slots.d.ts +56 -34
- package/dist/spec/empty-node-slots.js +87 -47
- package/dist/spec/index.d.ts +21 -10
- package/dist/spec/index.js +21 -10
- package/dist/spec/jsxToSpec.d.ts +14 -9
- package/dist/spec/jsxToSpec.js +20 -3
- package/dist/spec/preview-elements.d.ts +63 -0
- package/dist/spec/preview-elements.js +89 -0
- package/dist/spec/rewrite-refs.d.ts +58 -0
- package/dist/spec/rewrite-refs.js +250 -0
- package/dist/spec/specToJsx.js +18 -29
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +39 -52
- package/dist/AssetGroup.d.ts +0 -77
- package/dist/AssetGroup.js +0 -125
- package/dist/Component.d.ts +0 -333
- package/dist/Component.js +0 -1061
- package/dist/ComponentGroup.d.ts +0 -22
- package/dist/ComponentGroup.js +0 -51
- package/dist/CompositeStyle.d.ts +0 -30
- package/dist/CompositeStyle.js +0 -59
- package/dist/Config.d.ts +0 -528
- package/dist/Config.js +0 -1712
- package/dist/Mode.d.ts +0 -41
- package/dist/Mode.js +0 -81
- package/dist/Modifier.d.ts +0 -51
- package/dist/Modifier.js +0 -97
- package/dist/MotionDef.d.ts +0 -81
- package/dist/MotionDef.js +0 -212
- package/dist/Props.d.ts +0 -332
- package/dist/Props.js +0 -35
- package/dist/Provider.d.ts +0 -20
- package/dist/Provider.js +0 -14
- package/dist/StyleProp.d.ts +0 -145
- package/dist/StyleProp.js +0 -239
- package/dist/Token.d.ts +0 -76
- package/dist/Token.js +0 -133
- package/dist/TokenGroup.d.ts +0 -33
- package/dist/TokenGroup.js +0 -69
- package/dist/asset-kind.d.ts +0 -55
- package/dist/asset-kind.js +0 -29
- package/dist/asset-value.d.ts +0 -23
- package/dist/asset-value.js +0 -40
- package/dist/brands.d.ts +0 -30
- package/dist/brands.js +0 -20
- package/dist/captureCallerPath.d.ts +0 -48
- package/dist/captureCallerPath.js +0 -95
- package/dist/colorExpressions.d.ts +0 -131
- package/dist/colorExpressions.js +0 -148
- package/dist/component-referrers.d.ts +0 -30
- package/dist/component-referrers.js +0 -40
- package/dist/config-diagnostics.d.ts +0 -21
- package/dist/config-diagnostics.js +0 -12
- package/dist/defineAssetGroup.d.ts +0 -200
- package/dist/defineAssetGroup.js +0 -323
- package/dist/defineProvider.d.ts +0 -29
- package/dist/defineProvider.js +0 -60
- package/dist/element-marker.d.ts +0 -63
- package/dist/element-marker.js +0 -113
- package/dist/entity-utils.d.ts +0 -56
- package/dist/entity-utils.js +0 -105
- package/dist/extension.d.ts +0 -55
- package/dist/extension.js +0 -214
- package/dist/factories.d.ts +0 -863
- package/dist/factories.js +0 -475
- package/dist/font-face.d.ts +0 -25
- package/dist/font-face.js +0 -72
- package/dist/foreign-component-name.d.ts +0 -21
- package/dist/foreign-component-name.js +0 -42
- package/dist/interpolate.d.ts +0 -20
- package/dist/interpolate.js +0 -10
- package/dist/jsx/__fixtures__/cross-component-preview.d.ts +0 -3
- package/dist/jsx/__fixtures__/cross-component-preview.js +0 -15
- package/dist/jsx/jsx-dev-runtime.d.ts +0 -15
- package/dist/jsx/jsx-dev-runtime.js +0 -11
- package/dist/jsx/jsx-runtime.d.ts +0 -48
- package/dist/jsx/jsx-runtime.js +0 -305
- package/dist/linked-system-pins.d.ts +0 -30
- package/dist/linked-system-pins.js +0 -45
- package/dist/linkedNodePrefixes.d.ts +0 -73
- package/dist/linkedNodePrefixes.js +0 -99
- package/dist/markers.d.ts +0 -235
- package/dist/markers.js +0 -70
- package/dist/motion-constants.d.ts +0 -37
- package/dist/motion-constants.js +0 -61
- package/dist/native/NativeConfig.d.ts +0 -56
- package/dist/native/NativeConfig.js +0 -162
- package/dist/native/assets.d.ts +0 -20
- package/dist/native/assets.js +0 -17
- package/dist/native/components.d.ts +0 -139
- package/dist/native/components.js +0 -67
- package/dist/native/index.d.ts +0 -18
- package/dist/native/index.js +0 -17
- package/dist/native/modes.d.ts +0 -10
- package/dist/native/modes.js +0 -11
- package/dist/native/types.d.ts +0 -95
- package/dist/native/types.js +0 -0
- package/dist/native/validation.d.ts +0 -8
- package/dist/native/validation.js +0 -885
- package/dist/native/values.d.ts +0 -7
- package/dist/native/values.js +0 -15
- package/dist/native.d.ts +0 -12
- package/dist/native.js +0 -10
- package/dist/refs.d.ts +0 -204
- package/dist/refs.js +0 -129
- package/dist/registry-aliases.d.ts +0 -33
- package/dist/registry-aliases.js +0 -35
- package/dist/registry-dir.d.ts +0 -22
- package/dist/registry-dir.js +0 -10
- package/dist/renderer/makeRegistry.d.ts +0 -34
- package/dist/renderer/makeRegistry.js +0 -52
- package/dist/renderer/makeUdsRenderer.d.ts +0 -13
- package/dist/renderer/makeUdsRenderer.js +0 -51
- package/dist/renderer/wrappers/component-slots.d.ts +0 -41
- package/dist/renderer/wrappers/component-slots.js +0 -66
- package/dist/renderer/wrappers/slot-resolution.d.ts +0 -25
- package/dist/renderer/wrappers/slot-resolution.js +0 -68
- package/dist/renderer/wrappers/void-elements.d.ts +0 -37
- package/dist/renderer/wrappers/void-elements.js +0 -40
- package/dist/spec/layer-props.d.ts +0 -52
- package/dist/spec/layer-props.js +0 -149
- package/dist/spec/preview-controls.d.ts +0 -44
- package/dist/spec/preview-controls.js +0 -139
- package/dist/spec/slot-refs.d.ts +0 -39
- package/dist/spec/slot-refs.js +0 -56
- package/dist/token-override-rows.d.ts +0 -68
- package/dist/token-override-rows.js +0 -233
- package/dist/tokenValueType.d.ts +0 -34
- package/dist/tokenValueType.js +0 -138
- package/dist/types/css-properties.d.ts +0 -233
- package/dist/types/css-properties.js +0 -14
- package/dist/types/css-property-keywords.d.ts +0 -156
- package/dist/types/css-property-keywords.js +0 -616
- package/dist/types/css-values.d.ts +0 -63
- package/dist/types/css-values.js +0 -16
- package/dist/types.d.ts +0 -1138
- package/dist/types.js +0 -12
- package/dist/units.d.ts +0 -14
- package/dist/units.js +0 -16
- package/dist/utils/index.d.ts +0 -4
- package/dist/utils/index.js +0 -4
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { kindOf, pathOf } from "../framework/utils/refs.js";
|
|
2
|
+
import { childrenPolicy } from "../entities/system/element.js";
|
|
3
|
+
import { resolveComponentProps } from "../framework/projections.js";
|
|
1
4
|
//#region src/spec/collapse-text-labels.ts
|
|
2
5
|
/** Child element keys an element references through its `children` array. */
|
|
3
6
|
function childKeysOf(element) {
|
|
@@ -7,20 +10,14 @@ function childKeysOf(element) {
|
|
|
7
10
|
/**
|
|
8
11
|
* Count every parent→child edge in the spec so a wrapped Text node is only
|
|
9
12
|
* deleted when nothing *else* still points at it. Covers `children` arrays and
|
|
10
|
-
*
|
|
13
|
+
* `slots` entries (the two ways the renderer reaches an element).
|
|
11
14
|
*/
|
|
12
15
|
function countReferences(elements) {
|
|
13
16
|
const counts = /* @__PURE__ */ new Map();
|
|
14
17
|
const bump = (key) => counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
15
18
|
for (const element of Object.values(elements)) {
|
|
16
19
|
for (const child of childKeysOf(element)) bump(child);
|
|
17
|
-
|
|
18
|
-
for (const value of Object.values(element.props)) {
|
|
19
|
-
if (typeof value !== "object" || value === null || !("$slot" in value)) continue;
|
|
20
|
-
const slot = value.$slot;
|
|
21
|
-
const refs = Array.isArray(slot) ? slot : [slot];
|
|
22
|
-
for (const ref of refs) if (typeof ref === "string") bump(ref);
|
|
23
|
-
}
|
|
20
|
+
for (const fills of Object.values(element.slots ?? {})) for (const ref of fills) bump(ref);
|
|
24
21
|
}
|
|
25
22
|
return counts;
|
|
26
23
|
}
|
|
@@ -41,21 +38,32 @@ function bareLabelText(element) {
|
|
|
41
38
|
return text;
|
|
42
39
|
}
|
|
43
40
|
/**
|
|
41
|
+
* The component a spec `type` names, or `undefined` when it names something else.
|
|
42
|
+
*
|
|
43
|
+
* A spec type is `<kind>:<path>` (`component:Badge`), and only a component has children this can
|
|
44
|
+
* reason about — a `package:` member is somebody else's export, whose children are its own business,
|
|
45
|
+
* and an intrinsic tag (`'div'`) carries no kind at all and isn't in the config. Asking `resolve`
|
|
46
|
+
* with an unstripped marker finds nothing; asking it with the path of a NON-component would find a
|
|
47
|
+
* component that merely shares the name.
|
|
48
|
+
*/
|
|
49
|
+
function componentPath(type) {
|
|
50
|
+
const kind = kindOf(type);
|
|
51
|
+
if (kind !== type && kind !== "component") return void 0;
|
|
52
|
+
return pathOf(type);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
44
55
|
* Hoisting is only lossless when the wrapped child renders *nothing but* its
|
|
45
|
-
* text — a Text-like leaf whose `children`
|
|
56
|
+
* text — a Text-like leaf whose `children` forward renders directly (a scalar
|
|
46
57
|
* marker or an open/root slot). A component that forwards `children` into a
|
|
47
|
-
* named layer (Badge's `
|
|
58
|
+
* named layer (Badge's `{ type: 'forward', target: 'text/children' }`) has chrome around the label,
|
|
48
59
|
* so collapsing it would silently delete that chrome even when the element
|
|
49
60
|
* carries no other props. An unresolvable child type stays collapsible — the
|
|
50
61
|
* structural bare-leaf gate is all we can check, and generators emit known
|
|
51
62
|
* types anyway.
|
|
52
63
|
*/
|
|
53
64
|
function childCollapsible(child, config) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const children = component.derived.prop?.("children");
|
|
57
|
-
if (!children) return true;
|
|
58
|
-
return children.kind !== "slot" || children.layer === void 0;
|
|
65
|
+
const path = componentPath(child.type);
|
|
66
|
+
return (path ? resolveComponentProps(config, path).children : void 0)?.type !== "forward";
|
|
59
67
|
}
|
|
60
68
|
/**
|
|
61
69
|
* Return a copy of `spec` with every redundant Text-wrapped label folded into a
|
|
@@ -69,10 +77,9 @@ function collapseWrappedTextLabels(spec, config) {
|
|
|
69
77
|
const rewrites = /* @__PURE__ */ new Map();
|
|
70
78
|
const toDelete = /* @__PURE__ */ new Set();
|
|
71
79
|
for (const [key, element] of Object.entries(spec.elements)) {
|
|
72
|
-
const
|
|
73
|
-
if (!
|
|
74
|
-
|
|
75
|
-
if (!acceptsChildren || acceptsChildNodes) continue;
|
|
80
|
+
const path = componentPath(element.type);
|
|
81
|
+
if (!path) continue;
|
|
82
|
+
if (childrenPolicy(config, path) !== "text") continue;
|
|
76
83
|
const childKeys = childKeysOf(element);
|
|
77
84
|
if (childKeys.length !== 1) continue;
|
|
78
85
|
const existingLabel = element.props?.children;
|
|
@@ -1,21 +1,41 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Config } from "../framework/Config.js";
|
|
2
|
+
import { SlotTarget } from "../framework/render-spec.js";
|
|
2
3
|
import { Spec } from "@json-render/core";
|
|
3
4
|
|
|
4
5
|
//#region src/spec/empty-node-slots.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* The component's named node slots — `slotTargetsOf` minus text slots and
|
|
8
|
+
* minus `children`. `children` is the open content hole every container has
|
|
9
|
+
* (a structural insert, not a named fill), and a text slot is an inline-edit
|
|
10
|
+
* surface, not a place a node goes.
|
|
11
|
+
*
|
|
12
|
+
* Text-ness is checked on BOTH ends of the route: the component's own decl
|
|
13
|
+
* (`title: { type: 'slot', text: true }`) and the prop the route lands on — a
|
|
14
|
+
* `forward` into `Text#children` is typed in place, not filled with a dropped
|
|
15
|
+
* node, and only the far end says so. A route whose host component doesn't
|
|
16
|
+
* declare the landing prop is dropped too: the fill op would refuse it, so it
|
|
17
|
+
* must never be offered as a target.
|
|
18
|
+
*/
|
|
19
|
+
declare function namedSlotTargets(config: Config, componentPath: string): SlotTarget[];
|
|
5
20
|
/**
|
|
6
21
|
* Materialize every EMPTY layer-bound node slot of `spec`'s root as a `Slot`
|
|
7
|
-
* element
|
|
8
|
-
* in the spec rather than an absent
|
|
9
|
-
* target, the layers panel a row, and the inspector an "Empty" state.
|
|
10
|
-
* spec already fills are left as-is. Returns `spec` unchanged when
|
|
11
|
-
* nothing to inject (no node slots, or all of them filled).
|
|
22
|
+
* element named in the root's `slots` record, so an unfilled slot is a stable
|
|
23
|
+
* element in the spec rather than an absent entry — the studio canvas needs a
|
|
24
|
+
* drop target, the layers panel a row, and the inspector an "Empty" state.
|
|
25
|
+
* Slots the spec already fills are left as-is. Returns `spec` unchanged when
|
|
26
|
+
* there's nothing to inject (no node slots, or all of them filled).
|
|
27
|
+
*
|
|
28
|
+
* `slotNames` is the component's named node slots — {@link namedSlotTargets}'
|
|
29
|
+
* `from` names. Callers pass names rather than a props record because which
|
|
30
|
+
* props are node slots is route-dependent (a `forward` into a text prop is
|
|
31
|
+
* not one), and only the config can answer that.
|
|
12
32
|
*/
|
|
13
|
-
declare function withEmptyNodeSlots(spec: Spec,
|
|
33
|
+
declare function withEmptyNodeSlots(spec: Spec, slotNames: readonly string[]): Spec;
|
|
14
34
|
/**
|
|
15
35
|
* Predicate over a spec element's `type`: does it name a component that forwards
|
|
16
36
|
* renderable **node** children (a valid drop-*into* target)? This is the single
|
|
17
37
|
* source of truth for "is a container" — studio builds it from the live Config
|
|
18
|
-
* (`
|
|
38
|
+
* (`buildClassifyChildNodes` → `childrenPolicy`), which is
|
|
19
39
|
* namespace-aware, so both bare (`Box`) and namespaced (`uds:Box`) spec types
|
|
20
40
|
* resolve, along with any custom child-accepting component.
|
|
21
41
|
*/
|
|
@@ -27,26 +47,25 @@ type AcceptsChildNodes = (type: string | undefined) => boolean;
|
|
|
27
47
|
*/
|
|
28
48
|
type ChildNodesClassification = true | false | undefined;
|
|
29
49
|
type ClassifyChildNodes = (type: string | undefined) => ChildNodesClassification;
|
|
30
|
-
/** The slice of a `Config` the predicate needs — structural so this stays
|
|
31
|
-
* decoupled from the `Config` class (and free of an import cycle). */
|
|
32
|
-
interface ComponentResolver {
|
|
33
|
-
getComponent(type: string): {
|
|
34
|
-
derived: {
|
|
35
|
-
acceptsChildNodes: boolean;
|
|
36
|
-
};
|
|
37
|
-
} | undefined;
|
|
38
|
-
}
|
|
39
50
|
/**
|
|
40
51
|
* Build the single, namespace-aware {@link AcceptsChildNodes} predicate from a
|
|
41
52
|
* live config: an element type is a node container iff its resolved component's
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* spec carries. Returns a constant `false` when there's no config (nothing can
|
|
53
|
+
* it takes child NODES. `Component.get` resolves a path or the ref a spec carries, so the predicate
|
|
54
|
+
* matches whichever form is in hand. Returns a constant `false` when there's no config (nothing can
|
|
45
55
|
* be classified yet) — callers thread this into slot injection and drop
|
|
46
56
|
* hit-testing so every surface agrees on what accepts children.
|
|
47
57
|
*/
|
|
48
|
-
declare function buildAcceptsChildNodes(config:
|
|
49
|
-
|
|
58
|
+
declare function buildAcceptsChildNodes(config: Config | null | undefined): AcceptsChildNodes;
|
|
59
|
+
/**
|
|
60
|
+
* Whether an element type takes child NODES — `true`, `false`, or `undefined` when nothing can say.
|
|
61
|
+
*
|
|
62
|
+
* `childrenPolicy` is the answer, and it is the same answer the spec validator, the emitted module and
|
|
63
|
+
* the anatomy schema use: a void element takes nothing, a text slot takes a string, and everything
|
|
64
|
+
* else takes nodes. v1 asked a flag stamped on each component at registration (`acceptsChildNodes`),
|
|
65
|
+
* which is the same fact computed once and stored — so it could be stale, and only registration could
|
|
66
|
+
* write it.
|
|
67
|
+
*/
|
|
68
|
+
declare function buildClassifyChildNodes(config: Config | null | undefined): ClassifyChildNodes;
|
|
50
69
|
/**
|
|
51
70
|
* Pin a persistent trailing `Slot` as the last child of every container element
|
|
52
71
|
* in `spec` (tree-wide), so a container always exposes an insertion drop target
|
|
@@ -64,8 +83,8 @@ declare function buildClassifyChildNodes(config: ComponentResolver | null | unde
|
|
|
64
83
|
declare function withContainerChildSlots(spec: Spec, acceptsChildNodes: AcceptsChildNodes): Spec;
|
|
65
84
|
/**
|
|
66
85
|
* Compose both slot injections into the canvas's render view: layer-bound node
|
|
67
|
-
* slots on a component instance's root (`withEmptyNodeSlots`,
|
|
68
|
-
* component
|
|
86
|
+
* slots on a component instance's root (`withEmptyNodeSlots`, keyed by the
|
|
87
|
+
* component's `namedSlotTargets`) plus a trailing insertion `Slot` in every container,
|
|
69
88
|
* tree-wide (`withContainerChildSlots`). This is the spec the studio canvas
|
|
70
89
|
* renders so empty slots show as drop targets — it is NEVER persisted. Stored
|
|
71
90
|
* specs stay slot-free; `stripInjectedSlots` is the inverse, applied at every
|
|
@@ -73,20 +92,23 @@ declare function withContainerChildSlots(spec: Spec, acceptsChildNodes: AcceptsC
|
|
|
73
92
|
* same reference when there's nothing to add, so this is cheap and idempotent —
|
|
74
93
|
* re-running on an already-slotted spec adds nothing.
|
|
75
94
|
*/
|
|
76
|
-
declare function withRenderSlots(spec: Spec,
|
|
95
|
+
declare function withRenderSlots(spec: Spec, slotNames: readonly string[] | null | undefined, acceptsChildNodes: AcceptsChildNodes): Spec;
|
|
77
96
|
/**
|
|
78
97
|
* Inverse of `withEmptyNodeSlots` + `withContainerChildSlots`: drop every
|
|
79
98
|
* injected `Slot` element and scrub its references, so a spec carries no
|
|
80
|
-
* editing scaffolding.
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* exact reversal: a trailing `children` Slot drops out of its parent's
|
|
99
|
+
* editing scaffolding. An injected `Slot` is render-only — both injectors
|
|
100
|
+
* emit `type: 'Slot'` with no `shown` — so removing them and their references
|
|
101
|
+
* is the exact reversal: a trailing `children` Slot drops out of its parent's
|
|
84
102
|
* `children`, and an empty node slot drops both its `Slot` element and the
|
|
85
|
-
* `
|
|
86
|
-
* which is not `Slot`-typed, so it survives).
|
|
87
|
-
*
|
|
88
|
-
*
|
|
103
|
+
* `slots` entry that named it (a FILLED slot names a real element,
|
|
104
|
+
* which is not `Slot`-typed, so it survives). A `shown: true` Slot is NOT
|
|
105
|
+
* scaffolding: it is the user-enabled Placeholder `setNodeSlot` deliberately
|
|
106
|
+
* persists, so it survives the strip — without the exemption, a slot fill
|
|
107
|
+
* (which strips the whole spec before persisting) would silently delete a
|
|
108
|
+
* sibling slot's placeholder. Use at export/serialization boundaries (e.g.
|
|
109
|
+
* clipboard); the canvas re-injects fresh drop targets on load. Idempotent:
|
|
110
|
+
* returns `spec` unchanged when there are no strippable `Slot` elements.
|
|
89
111
|
*/
|
|
90
112
|
declare function stripInjectedSlots(spec: Spec): Spec;
|
|
91
113
|
//#endregion
|
|
92
|
-
export { AcceptsChildNodes, ChildNodesClassification, ClassifyChildNodes, buildAcceptsChildNodes, buildClassifyChildNodes, stripInjectedSlots, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots };
|
|
114
|
+
export { AcceptsChildNodes, ChildNodesClassification, ClassifyChildNodes, buildAcceptsChildNodes, buildClassifyChildNodes, namedSlotTargets, stripInjectedSlots, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots };
|
|
@@ -1,40 +1,71 @@
|
|
|
1
|
+
import { pathOf } from "../framework/utils/refs.js";
|
|
2
|
+
import { childrenPolicy } from "../entities/system/element.js";
|
|
3
|
+
import { resolveComponentProps } from "../framework/projections.js";
|
|
4
|
+
import { slotTargetsOf } from "../framework/render-spec.js";
|
|
5
|
+
import { Component } from "../entities/system/Component.js";
|
|
1
6
|
//#region src/spec/empty-node-slots.ts
|
|
2
7
|
const SLOT_TYPE = "Slot";
|
|
3
8
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
9
|
+
* The component's named node slots — `slotTargetsOf` minus text slots and
|
|
10
|
+
* minus `children`. `children` is the open content hole every container has
|
|
11
|
+
* (a structural insert, not a named fill), and a text slot is an inline-edit
|
|
12
|
+
* surface, not a place a node goes.
|
|
13
|
+
*
|
|
14
|
+
* Text-ness is checked on BOTH ends of the route: the component's own decl
|
|
15
|
+
* (`title: { type: 'slot', text: true }`) and the prop the route lands on — a
|
|
16
|
+
* `forward` into `Text#children` is typed in place, not filled with a dropped
|
|
17
|
+
* node, and only the far end says so. A route whose host component doesn't
|
|
18
|
+
* declare the landing prop is dropped too: the fill op would refuse it, so it
|
|
19
|
+
* must never be offered as a target.
|
|
8
20
|
*/
|
|
9
|
-
function
|
|
10
|
-
|
|
21
|
+
function namedSlotTargets(config, componentPath) {
|
|
22
|
+
const component = Component.get(config, componentPath);
|
|
23
|
+
const props = component?.props;
|
|
24
|
+
const layers = component?.layers;
|
|
25
|
+
return slotTargetsOf(config, componentPath).filter((target) => {
|
|
26
|
+
if (target.from === "children") return false;
|
|
27
|
+
const declared = props?.[target.from];
|
|
28
|
+
if (declared?.type === "slot" && declared.text === true) return false;
|
|
29
|
+
const hostRef = layers?.[target.layer];
|
|
30
|
+
if (!hostRef || !Component.get(config, hostRef)) return true;
|
|
31
|
+
const into = resolveComponentProps(config.configFor(hostRef) ?? config, pathOf(hostRef))[target.into];
|
|
32
|
+
if (!into) return false;
|
|
33
|
+
return !(into.type === "slot" && into.text === true);
|
|
34
|
+
});
|
|
11
35
|
}
|
|
12
36
|
/**
|
|
13
37
|
* Materialize every EMPTY layer-bound node slot of `spec`'s root as a `Slot`
|
|
14
|
-
* element
|
|
15
|
-
* in the spec rather than an absent
|
|
16
|
-
* target, the layers panel a row, and the inspector an "Empty" state.
|
|
17
|
-
* spec already fills are left as-is. Returns `spec` unchanged when
|
|
18
|
-
* nothing to inject (no node slots, or all of them filled).
|
|
38
|
+
* element named in the root's `slots` record, so an unfilled slot is a stable
|
|
39
|
+
* element in the spec rather than an absent entry — the studio canvas needs a
|
|
40
|
+
* drop target, the layers panel a row, and the inspector an "Empty" state.
|
|
41
|
+
* Slots the spec already fills are left as-is. Returns `spec` unchanged when
|
|
42
|
+
* there's nothing to inject (no node slots, or all of them filled).
|
|
43
|
+
*
|
|
44
|
+
* `slotNames` is the component's named node slots — {@link namedSlotTargets}'
|
|
45
|
+
* `from` names. Callers pass names rather than a props record because which
|
|
46
|
+
* props are node slots is route-dependent (a `forward` into a text prop is
|
|
47
|
+
* not one), and only the config can answer that.
|
|
19
48
|
*/
|
|
20
|
-
function withEmptyNodeSlots(spec,
|
|
21
|
-
const names =
|
|
49
|
+
function withEmptyNodeSlots(spec, slotNames) {
|
|
50
|
+
const names = slotNames;
|
|
22
51
|
if (names.length === 0) return spec;
|
|
23
52
|
const rootKey = spec.root;
|
|
24
53
|
const next = structuredClone(spec);
|
|
25
54
|
const elements = next.elements;
|
|
26
55
|
const root = elements[rootKey];
|
|
27
56
|
if (!root) return spec;
|
|
28
|
-
root.props = root.props ?? {};
|
|
29
57
|
let injected = false;
|
|
30
58
|
for (const name of names) {
|
|
31
|
-
if (root.
|
|
59
|
+
if (root.slots?.[name] !== void 0) continue;
|
|
32
60
|
const key = `${rootKey}__${name}__slot`;
|
|
33
61
|
elements[key] = {
|
|
34
62
|
type: SLOT_TYPE,
|
|
35
63
|
props: { name }
|
|
36
64
|
};
|
|
37
|
-
root.
|
|
65
|
+
root.slots = {
|
|
66
|
+
...root.slots,
|
|
67
|
+
[name]: [key]
|
|
68
|
+
};
|
|
38
69
|
injected = true;
|
|
39
70
|
}
|
|
40
71
|
return injected ? next : spec;
|
|
@@ -42,9 +73,8 @@ function withEmptyNodeSlots(spec, component) {
|
|
|
42
73
|
/**
|
|
43
74
|
* Build the single, namespace-aware {@link AcceptsChildNodes} predicate from a
|
|
44
75
|
* live config: an element type is a node container iff its resolved component's
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* spec carries. Returns a constant `false` when there's no config (nothing can
|
|
76
|
+
* it takes child NODES. `Component.get` resolves a path or the ref a spec carries, so the predicate
|
|
77
|
+
* matches whichever form is in hand. Returns a constant `false` when there's no config (nothing can
|
|
48
78
|
* be classified yet) — callers thread this into slot injection and drop
|
|
49
79
|
* hit-testing so every surface agrees on what accepts children.
|
|
50
80
|
*/
|
|
@@ -52,9 +82,23 @@ function buildAcceptsChildNodes(config) {
|
|
|
52
82
|
const classify = buildClassifyChildNodes(config);
|
|
53
83
|
return (type) => classify(type) === true;
|
|
54
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Whether an element type takes child NODES — `true`, `false`, or `undefined` when nothing can say.
|
|
87
|
+
*
|
|
88
|
+
* `childrenPolicy` is the answer, and it is the same answer the spec validator, the emitted module and
|
|
89
|
+
* the anatomy schema use: a void element takes nothing, a text slot takes a string, and everything
|
|
90
|
+
* else takes nodes. v1 asked a flag stamped on each component at registration (`acceptsChildNodes`),
|
|
91
|
+
* which is the same fact computed once and stored — so it could be stale, and only registration could
|
|
92
|
+
* write it.
|
|
93
|
+
*/
|
|
55
94
|
function buildClassifyChildNodes(config) {
|
|
56
95
|
if (!config) return () => void 0;
|
|
57
|
-
return (type) =>
|
|
96
|
+
return (type) => {
|
|
97
|
+
if (type === void 0) return void 0;
|
|
98
|
+
const component = Component.get(config, type);
|
|
99
|
+
if (!component) return void 0;
|
|
100
|
+
return childrenPolicy(config, component.path) === "nodes";
|
|
101
|
+
};
|
|
58
102
|
}
|
|
59
103
|
/**
|
|
60
104
|
* Pin a persistent trailing `Slot` as the last child of every container element
|
|
@@ -98,8 +142,8 @@ function withContainerChildSlots(spec, acceptsChildNodes) {
|
|
|
98
142
|
}
|
|
99
143
|
/**
|
|
100
144
|
* Compose both slot injections into the canvas's render view: layer-bound node
|
|
101
|
-
* slots on a component instance's root (`withEmptyNodeSlots`,
|
|
102
|
-
* component
|
|
145
|
+
* slots on a component instance's root (`withEmptyNodeSlots`, keyed by the
|
|
146
|
+
* component's `namedSlotTargets`) plus a trailing insertion `Slot` in every container,
|
|
103
147
|
* tree-wide (`withContainerChildSlots`). This is the spec the studio canvas
|
|
104
148
|
* renders so empty slots show as drop targets — it is NEVER persisted. Stored
|
|
105
149
|
* specs stay slot-free; `stripInjectedSlots` is the inverse, applied at every
|
|
@@ -107,32 +151,29 @@ function withContainerChildSlots(spec, acceptsChildNodes) {
|
|
|
107
151
|
* same reference when there's nothing to add, so this is cheap and idempotent —
|
|
108
152
|
* re-running on an already-slotted spec adds nothing.
|
|
109
153
|
*/
|
|
110
|
-
function withRenderSlots(spec,
|
|
111
|
-
return withContainerChildSlots(
|
|
112
|
-
}
|
|
113
|
-
function slotRefKeys(value) {
|
|
114
|
-
if (typeof value !== "object" || value === null || !("$slot" in value)) return;
|
|
115
|
-
const ref = value.$slot;
|
|
116
|
-
if (typeof ref === "string") return [ref];
|
|
117
|
-
return Array.isArray(ref) ? ref : void 0;
|
|
154
|
+
function withRenderSlots(spec, slotNames, acceptsChildNodes) {
|
|
155
|
+
return withContainerChildSlots(slotNames ? withEmptyNodeSlots(spec, slotNames) : spec, acceptsChildNodes);
|
|
118
156
|
}
|
|
119
157
|
/**
|
|
120
158
|
* Inverse of `withEmptyNodeSlots` + `withContainerChildSlots`: drop every
|
|
121
159
|
* injected `Slot` element and scrub its references, so a spec carries no
|
|
122
|
-
* editing scaffolding.
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* exact reversal: a trailing `children` Slot drops out of its parent's
|
|
160
|
+
* editing scaffolding. An injected `Slot` is render-only — both injectors
|
|
161
|
+
* emit `type: 'Slot'` with no `shown` — so removing them and their references
|
|
162
|
+
* is the exact reversal: a trailing `children` Slot drops out of its parent's
|
|
126
163
|
* `children`, and an empty node slot drops both its `Slot` element and the
|
|
127
|
-
* `
|
|
128
|
-
* which is not `Slot`-typed, so it survives).
|
|
129
|
-
*
|
|
130
|
-
*
|
|
164
|
+
* `slots` entry that named it (a FILLED slot names a real element,
|
|
165
|
+
* which is not `Slot`-typed, so it survives). A `shown: true` Slot is NOT
|
|
166
|
+
* scaffolding: it is the user-enabled Placeholder `setNodeSlot` deliberately
|
|
167
|
+
* persists, so it survives the strip — without the exemption, a slot fill
|
|
168
|
+
* (which strips the whole spec before persisting) would silently delete a
|
|
169
|
+
* sibling slot's placeholder. Use at export/serialization boundaries (e.g.
|
|
170
|
+
* clipboard); the canvas re-injects fresh drop targets on load. Idempotent:
|
|
171
|
+
* returns `spec` unchanged when there are no strippable `Slot` elements.
|
|
131
172
|
*/
|
|
132
173
|
function stripInjectedSlots(spec) {
|
|
133
174
|
const elements = spec.elements;
|
|
134
175
|
if (!elements || typeof elements !== "object") return spec;
|
|
135
|
-
const slotKeys = new Set(Object.keys(elements).filter((k) => elements[k]?.type === SLOT_TYPE));
|
|
176
|
+
const slotKeys = new Set(Object.keys(elements).filter((k) => elements[k]?.type === SLOT_TYPE && elements[k]?.props?.shown !== true));
|
|
136
177
|
if (slotKeys.size === 0) return spec;
|
|
137
178
|
const next = structuredClone(spec);
|
|
138
179
|
const nextEls = next.elements;
|
|
@@ -140,16 +181,15 @@ function stripInjectedSlots(spec) {
|
|
|
140
181
|
for (const el of Object.values(nextEls)) {
|
|
141
182
|
if (!el) continue;
|
|
142
183
|
if (Array.isArray(el.children)) el.children = el.children.filter((c) => !slotKeys.has(c));
|
|
143
|
-
if (!el.
|
|
144
|
-
for (const [
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
147
|
-
|
|
148
|
-
if (remaining.length === 0) delete el.props[propName];
|
|
149
|
-
else if (remaining.length !== refs.length) el.props[propName] = { $slot: remaining };
|
|
184
|
+
if (!el.slots) continue;
|
|
185
|
+
for (const [name, fills] of Object.entries(el.slots)) {
|
|
186
|
+
const remaining = fills.filter((r) => !slotKeys.has(r));
|
|
187
|
+
if (remaining.length === 0) delete el.slots[name];
|
|
188
|
+
else if (remaining.length !== fills.length) el.slots[name] = remaining;
|
|
150
189
|
}
|
|
190
|
+
if (Object.keys(el.slots).length === 0) delete el.slots;
|
|
151
191
|
}
|
|
152
192
|
return next;
|
|
153
193
|
}
|
|
154
194
|
//#endregion
|
|
155
|
-
export { buildAcceptsChildNodes, buildClassifyChildNodes, stripInjectedSlots, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots };
|
|
195
|
+
export { buildAcceptsChildNodes, buildClassifyChildNodes, namedSlotTargets, stripInjectedSlots, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots };
|
package/dist/spec/index.d.ts
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
|
+
import { AcceptsChildNodes, ChildNodesClassification, ClassifyChildNodes, buildAcceptsChildNodes, buildClassifyChildNodes, namedSlotTargets, stripInjectedSlots, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots } from "./empty-node-slots.js";
|
|
2
|
+
import { DocumentRename, RewritableSpec, SpecRewrite, rewriteSpecRefs } from "./rewrite-refs.js";
|
|
1
3
|
import { applyForcedModifiers, collectForcedModifierProps } from "./apply-forced-modifiers.js";
|
|
2
|
-
import { AssetComponentMap, AssetJsxForm, AssetNodeResolver, assetJsxForm, parseAssetType } from "./asset-jsx.js";
|
|
4
|
+
import { AssetComponentMap, AssetJsxForm, AssetNodeResolver, assetJsxForm, jsxIdentifier, parseAssetType } from "./asset-jsx.js";
|
|
3
5
|
import { CollapseTextLabelsResult, CollapsedTextLabel, collapseWrappedTextLabels } from "./collapse-text-labels.js";
|
|
4
|
-
import { AcceptsChildNodes, ChildNodesClassification, ClassifyChildNodes, buildAcceptsChildNodes, buildClassifyChildNodes, stripInjectedSlots, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots } from "./empty-node-slots.js";
|
|
5
6
|
import { JsxToSpecOptions, UNRESOLVED, hasUnresolvedProps, jsxToSpec, stripUnresolvedProps } from "./jsxToSpec.js";
|
|
6
|
-
import {
|
|
7
|
-
import { PreviewControl, PreviewControlKind, derivePreviewControls, propOptions } from "./preview-controls.js";
|
|
8
|
-
import { collectSlotRefs, isSlotRef } from "./slot-refs.js";
|
|
7
|
+
import { GraftableElement, GraftableSpec, PreviewElement, PreviewSpecNode, PreviewValue, graftPreviewElements, hasPreviewElementDeep, isPreviewElement, previewElementNodes, previewElementType } from "./preview-elements.js";
|
|
9
8
|
import { SpecToJsxOptions, SpecToJsxResult, specToJsx } from "./specToJsx.js";
|
|
10
9
|
|
|
11
10
|
//#region src/spec/index.d.ts
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
11
|
+
/**
|
|
12
|
+
* Spec-format helpers — everything that reads or rewrites a json-render Spec in the UDS dialect
|
|
13
|
+
* (slot fills, forced modifier states, JSX ⇄ spec conversion).
|
|
14
|
+
*
|
|
15
|
+
* Nearly all of these are about the SPEC alone: a spec is a document, and asking what its elements
|
|
16
|
+
* are, which of them a slot pulls in, or what its JSX form looks like needs no design system to
|
|
17
|
+
* answer. What a component's layers are STYLED with is the config's question and lives with the
|
|
18
|
+
* config ({@link layerStyles}, {@link componentRuleClasses}).
|
|
19
|
+
*
|
|
20
|
+
* The exception is {@link collapseWrappedTextLabels}, which takes a `Config` — it decides whether a
|
|
21
|
+
* Text wrapper is redundant, and that depends on what the wrapping component takes as children. It
|
|
22
|
+
* belongs here anyway because the RESULT is a rewritten spec; it just can't answer without asking.
|
|
23
|
+
*/
|
|
24
|
+
/** Stamped on the Text node that preview extraction creates for a scalar slot; the value is the slot
|
|
25
|
+
* it came from. It's what tells that generated proxy apart from an authored marker-less Text
|
|
26
|
+
* element, without changing the rendered layer hierarchy. */
|
|
16
27
|
declare const SYNTHETIC_TEXT_SLOT_PROP = "data-uds-synthetic-text-slot";
|
|
17
28
|
//#endregion
|
|
18
|
-
export { type AcceptsChildNodes, type AssetComponentMap, type AssetJsxForm, type AssetNodeResolver, type ChildNodesClassification, type ClassifyChildNodes, type CollapseTextLabelsResult, type CollapsedTextLabel, type JsxToSpecOptions, type
|
|
29
|
+
export { type AcceptsChildNodes, type AssetComponentMap, type AssetJsxForm, type AssetNodeResolver, type ChildNodesClassification, type ClassifyChildNodes, type CollapseTextLabelsResult, type CollapsedTextLabel, type DocumentRename, type GraftableElement, type GraftableSpec, type JsxToSpecOptions, type PreviewElement, type PreviewSpecNode, type PreviewValue, type RewritableSpec, SYNTHETIC_TEXT_SLOT_PROP, type SpecRewrite, type SpecToJsxOptions, type SpecToJsxResult, UNRESOLVED, applyForcedModifiers, assetJsxForm, buildAcceptsChildNodes, buildClassifyChildNodes, collapseWrappedTextLabels, collectForcedModifierProps, graftPreviewElements, hasPreviewElementDeep, hasUnresolvedProps, isPreviewElement, jsxIdentifier, jsxToSpec, namedSlotTargets, parseAssetType, previewElementNodes, previewElementType, rewriteSpecRefs, specToJsx, stripInjectedSlots, stripUnresolvedProps, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots };
|
package/dist/spec/index.js
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { graftPreviewElements, hasPreviewElementDeep, isPreviewElement, previewElementNodes, previewElementType } from "./preview-elements.js";
|
|
2
|
+
import { assetJsxForm, jsxIdentifier, parseAssetType } from "./asset-jsx.js";
|
|
3
|
+
import { buildAcceptsChildNodes, buildClassifyChildNodes, namedSlotTargets, stripInjectedSlots, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots } from "./empty-node-slots.js";
|
|
2
4
|
import { applyForcedModifiers, collectForcedModifierProps } from "./apply-forced-modifiers.js";
|
|
3
|
-
import { assetJsxForm, parseAssetType } from "./asset-jsx.js";
|
|
4
5
|
import { collapseWrappedTextLabels } from "./collapse-text-labels.js";
|
|
5
|
-
import { buildAcceptsChildNodes, buildClassifyChildNodes, stripInjectedSlots, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots } from "./empty-node-slots.js";
|
|
6
6
|
import { UNRESOLVED, hasUnresolvedProps, jsxToSpec, stripUnresolvedProps } from "./jsxToSpec.js";
|
|
7
|
-
import {
|
|
8
|
-
import { derivePreviewControls, propOptions } from "./preview-controls.js";
|
|
7
|
+
import { rewriteSpecRefs } from "./rewrite-refs.js";
|
|
9
8
|
import { specToJsx } from "./specToJsx.js";
|
|
10
9
|
//#region src/spec/index.ts
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
/**
|
|
11
|
+
* Spec-format helpers — everything that reads or rewrites a json-render Spec in the UDS dialect
|
|
12
|
+
* (slot fills, forced modifier states, JSX ⇄ spec conversion).
|
|
13
|
+
*
|
|
14
|
+
* Nearly all of these are about the SPEC alone: a spec is a document, and asking what its elements
|
|
15
|
+
* are, which of them a slot pulls in, or what its JSX form looks like needs no design system to
|
|
16
|
+
* answer. What a component's layers are STYLED with is the config's question and lives with the
|
|
17
|
+
* config ({@link layerStyles}, {@link componentRuleClasses}).
|
|
18
|
+
*
|
|
19
|
+
* The exception is {@link collapseWrappedTextLabels}, which takes a `Config` — it decides whether a
|
|
20
|
+
* Text wrapper is redundant, and that depends on what the wrapping component takes as children. It
|
|
21
|
+
* belongs here anyway because the RESULT is a rewritten spec; it just can't answer without asking.
|
|
22
|
+
*/
|
|
23
|
+
/** Stamped on the Text node that preview extraction creates for a scalar slot; the value is the slot
|
|
24
|
+
* it came from. It's what tells that generated proxy apart from an authored marker-less Text
|
|
25
|
+
* element, without changing the rendered layer hierarchy. */
|
|
15
26
|
const SYNTHETIC_TEXT_SLOT_PROP = "data-uds-synthetic-text-slot";
|
|
16
27
|
//#endregion
|
|
17
|
-
export { SYNTHETIC_TEXT_SLOT_PROP, UNRESOLVED, applyForcedModifiers, assetJsxForm, buildAcceptsChildNodes, buildClassifyChildNodes, collapseWrappedTextLabels, collectForcedModifierProps,
|
|
28
|
+
export { SYNTHETIC_TEXT_SLOT_PROP, UNRESOLVED, applyForcedModifiers, assetJsxForm, buildAcceptsChildNodes, buildClassifyChildNodes, collapseWrappedTextLabels, collectForcedModifierProps, graftPreviewElements, hasPreviewElementDeep, hasUnresolvedProps, isPreviewElement, jsxIdentifier, jsxToSpec, namedSlotTargets, parseAssetType, previewElementNodes, previewElementType, rewriteSpecRefs, specToJsx, stripInjectedSlots, stripUnresolvedProps, withContainerChildSlots, withEmptyNodeSlots, withRenderSlots };
|
package/dist/spec/jsxToSpec.d.ts
CHANGED
|
@@ -19,17 +19,22 @@ interface JsxToSpecOptions {
|
|
|
19
19
|
*/
|
|
20
20
|
moduleSource?: string;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* Every identifier a tag may name, mapped to the QUALIFIED TYPE it resolves to
|
|
23
|
+
* — `'Badge' → 'component:Badge'`, `'TrophyIcon' → 'icon:icons/TrophyIcon'`.
|
|
24
|
+
* Build it with Studio's `buildKnownComponentSet`, which walks the same
|
|
25
|
+
* components and icon libraries.
|
|
26
|
+
*
|
|
27
|
+
* It decides two things. A PascalCase tag the map doesn't know (a provider, a
|
|
28
|
+
* wrapper) is treated as a transparent fragment — its children flatten into the
|
|
29
|
+
* parent. A tag it does know emits that qualified type, so a round trip through
|
|
30
|
+
* JSX keeps the kind each element named.
|
|
26
31
|
*/
|
|
27
|
-
knownComponents?:
|
|
32
|
+
knownComponents?: ReadonlyMap<string, string>;
|
|
28
33
|
/**
|
|
29
|
-
* Reconstructs placed asset nodes from
|
|
30
|
-
* `<Icon name="Trophy" …/>` → type `
|
|
31
|
-
*
|
|
32
|
-
*
|
|
34
|
+
* Reconstructs placed asset nodes from a rendering-component tag —
|
|
35
|
+
* `<Icon name="Trophy" …/>` → type `icon:icons/Trophy`. The exact inverse of
|
|
36
|
+
* `specToJsx`'s `assetComponents` mapping; without it an `<Icon name=…/>`
|
|
37
|
+
* round-trips as a literal `Icon` component node.
|
|
33
38
|
*/
|
|
34
39
|
resolveAssetNode?: AssetNodeResolver;
|
|
35
40
|
}
|
package/dist/spec/jsxToSpec.js
CHANGED
|
@@ -6,6 +6,16 @@ import { parse } from "@babel/parser";
|
|
|
6
6
|
* and should be stripped — $bindState handles write-back automatically.
|
|
7
7
|
*/
|
|
8
8
|
const STATE_SETTER = Symbol.for("jsxToSpec.stateSetter");
|
|
9
|
+
/**
|
|
10
|
+
* Wrapper `getAttributeValue` hands back for a JSX-element prop value. The
|
|
11
|
+
* converted element is already in the context's `elements` map; the attribute
|
|
12
|
+
* loop records its key on the owning element's `slots` record instead of
|
|
13
|
+
* storing a prop.
|
|
14
|
+
*/
|
|
15
|
+
const SLOT_FILL = Symbol.for("jsxToSpec.slotFill");
|
|
16
|
+
function isSlotFill(value) {
|
|
17
|
+
return typeof value === "object" && value !== null && SLOT_FILL in value;
|
|
18
|
+
}
|
|
9
19
|
function buildModuleScope(ast) {
|
|
10
20
|
const scope = {
|
|
11
21
|
values: /* @__PURE__ */ new Map(),
|
|
@@ -270,7 +280,7 @@ function getAttributeValue(valueNode, scope, ctx) {
|
|
|
270
280
|
const expr = valueNode.expression;
|
|
271
281
|
if (ctx && (expr.type === "JSXElement" || expr.type === "JSXFragment")) {
|
|
272
282
|
const slotKey = convertJsxNode(expr, ctx);
|
|
273
|
-
if (slotKey) return {
|
|
283
|
+
if (slotKey) return { [SLOT_FILL]: slotKey };
|
|
274
284
|
return UNRESOLVED;
|
|
275
285
|
}
|
|
276
286
|
return evaluateExpression(expr, scope);
|
|
@@ -360,6 +370,7 @@ function convertElement(node, ctx) {
|
|
|
360
370
|
if (ctx.knownComponents && tagName[0] === tagName[0].toUpperCase() && !ctx.knownComponents.has(tagName)) return flattenChildrenAsFragment(node.children, ctx);
|
|
361
371
|
const key = nextKey(ctx);
|
|
362
372
|
const props = {};
|
|
373
|
+
const slots = {};
|
|
363
374
|
const onBindings = {};
|
|
364
375
|
for (const attr of node.openingElement.attributes) if (attr.type === "JSXAttribute") {
|
|
365
376
|
const jsxAttr = attr;
|
|
@@ -369,7 +380,12 @@ function convertElement(node, ctx) {
|
|
|
369
380
|
onBindings[binding.event] = binding.action;
|
|
370
381
|
continue;
|
|
371
382
|
}
|
|
372
|
-
|
|
383
|
+
const propValue = getAttributeValue(jsxAttr.value, ctx.scope, ctx);
|
|
384
|
+
if (isSlotFill(propValue)) {
|
|
385
|
+
slots[propName] = [propValue[SLOT_FILL]];
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
props[propName] = propValue;
|
|
373
389
|
} else if (attr.type === "JSXSpreadAttribute") props.__spread__ = UNRESOLVED;
|
|
374
390
|
const childKeys = [];
|
|
375
391
|
const textContent = collectTextChildren(node.children);
|
|
@@ -381,10 +397,11 @@ function convertElement(node, ctx) {
|
|
|
381
397
|
const assetType = ctx.resolveAssetNode?.(tagName, props) ?? null;
|
|
382
398
|
if (assetType) delete props.name;
|
|
383
399
|
const element = {
|
|
384
|
-
type: assetType ?? tagName,
|
|
400
|
+
type: assetType ?? ctx.knownComponents?.get(tagName) ?? tagName,
|
|
385
401
|
props
|
|
386
402
|
};
|
|
387
403
|
if (childKeys.length > 0) element.children = childKeys;
|
|
404
|
+
if (Object.keys(slots).length > 0) element.slots = slots;
|
|
388
405
|
if (Object.keys(onBindings).length > 0) element.on = onBindings;
|
|
389
406
|
ctx.elements[key] = element;
|
|
390
407
|
return key;
|