@yahoo/uds-create-config 2.45.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Config } from "../../framework/Config.js";
|
|
2
|
+
|
|
3
|
+
//#region src/entities/system/runtime-modules.d.ts
|
|
4
|
+
/** One npm module named by this config's runtime declarations. */
|
|
5
|
+
interface DeclaredRuntimeModule {
|
|
6
|
+
/** The bare module specifier, exactly as authored (`@ariakit/react`, `motion/react`). */
|
|
7
|
+
readonly specifier: string;
|
|
8
|
+
/** The build-pinned package version, when known. */
|
|
9
|
+
readonly version?: string;
|
|
10
|
+
/** Package exports that rendered specs can address. */
|
|
11
|
+
readonly exports?: readonly string[];
|
|
12
|
+
/** This module also supplies the members of an icon library. */
|
|
13
|
+
readonly iconLibrary?: true;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The npm modules this config itself declares at runtime.
|
|
17
|
+
*
|
|
18
|
+
* Package rows and icon-library group metadata are already Config v2's durable declarations. This
|
|
19
|
+
* projection keeps serving and vendoring code on those facts instead of introducing another module
|
|
20
|
+
* registry that could drift from them. Linked sources remain separate: callers that need their
|
|
21
|
+
* declarations walk each attached source and call this projection there.
|
|
22
|
+
*/
|
|
23
|
+
declare function declaredRuntimeModules(config: Config): DeclaredRuntimeModule[];
|
|
24
|
+
//#endregion
|
|
25
|
+
export { DeclaredRuntimeModule, declaredRuntimeModules };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Icon } from "./Icon.js";
|
|
2
|
+
//#region src/entities/system/runtime-modules.ts
|
|
3
|
+
/**
|
|
4
|
+
* The npm modules this config itself declares at runtime.
|
|
5
|
+
*
|
|
6
|
+
* Package rows and icon-library group metadata are already Config v2's durable declarations. This
|
|
7
|
+
* projection keeps serving and vendoring code on those facts instead of introducing another module
|
|
8
|
+
* registry that could drift from them. Linked sources remain separate: callers that need their
|
|
9
|
+
* declarations walk each attached source and call this projection there.
|
|
10
|
+
*/
|
|
11
|
+
function declaredRuntimeModules(config) {
|
|
12
|
+
const bySpecifier = /* @__PURE__ */ new Map();
|
|
13
|
+
for (const row of config.list("package")) {
|
|
14
|
+
const { version, exports } = row.body;
|
|
15
|
+
const exportNames = Object.keys(exports ?? {}).sort();
|
|
16
|
+
bySpecifier.set(row.path, {
|
|
17
|
+
specifier: row.path,
|
|
18
|
+
...version ? { version } : {},
|
|
19
|
+
...exportNames.length > 0 ? { exports: exportNames } : {}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
for (const group of Icon.groups(config)) {
|
|
23
|
+
const specifier = group.meta.module;
|
|
24
|
+
if (typeof specifier !== "string") continue;
|
|
25
|
+
const existing = bySpecifier.get(specifier);
|
|
26
|
+
const groupVersion = group.meta.version;
|
|
27
|
+
const version = existing?.version ?? (typeof groupVersion === "string" ? groupVersion : void 0);
|
|
28
|
+
bySpecifier.set(specifier, {
|
|
29
|
+
specifier,
|
|
30
|
+
...version ? { version } : {},
|
|
31
|
+
...existing?.exports ? { exports: existing.exports } : {},
|
|
32
|
+
iconLibrary: true
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return [...bySpecifier.values()].sort((left, right) => left.specifier.localeCompare(right.specifier));
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { declaredRuntimeModules };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DerivedColor, Gradient } from "./color.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/entities/system/style-bag.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* A style bag — what a component layer / composite / variant applies. The key is a
|
|
7
|
+
* style-prop name (open: any registered prop), but the VALUE is constrained: a literal
|
|
8
|
+
* (`'row'`, `4`), a `token(...)` ref, or a nested modifier block (`_hover: { ... }`) whose
|
|
9
|
+
* own values are style values (recursive). Typing the value instead of `z.unknown()`
|
|
10
|
+
* tightens the derived MCP tool — the AI sees token-or-literal, not "any" — and the
|
|
11
|
+
* harness's strictness checker recurses into the constrained value instead of flagging the
|
|
12
|
+
* bag as fully open.
|
|
13
|
+
*/
|
|
14
|
+
type StyleValue = string | number | boolean | {
|
|
15
|
+
readonly __ref: string;
|
|
16
|
+
} | DerivedColor | Gradient | {
|
|
17
|
+
readonly [key: string]: StyleValue;
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { StyleValue };
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { isExtendedRef, isRef, ref, refSchema, splitRef } from "../../framework/utils/refs.js";
|
|
2
|
+
import { defineSubEntity } from "../../framework/defineSubEntity.js";
|
|
3
|
+
import { derivedColor, gradient } from "./color.js";
|
|
4
|
+
import { isCssProperty, kebabCase } from "../../css/values.js";
|
|
5
|
+
import { valueSchemaOf } from "../../framework/value-domain.js";
|
|
6
|
+
import { stylePropTokenPath } from "../../framework/projections.js";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
//#region src/entities/system/style-bag.ts
|
|
9
|
+
/** The explicit type annotation breaks the `z.lazy` self-reference cycle and keeps the
|
|
10
|
+
* authored value type tight (a bare `z.lazy` infers `unknown`). */
|
|
11
|
+
const styleValue = z.lazy(() => z.union([
|
|
12
|
+
z.string(),
|
|
13
|
+
z.number(),
|
|
14
|
+
z.boolean(),
|
|
15
|
+
refSchema,
|
|
16
|
+
derivedColor,
|
|
17
|
+
gradient,
|
|
18
|
+
z.record(z.string(), styleValue)
|
|
19
|
+
]));
|
|
20
|
+
/**
|
|
21
|
+
* A style bag as a keyed COLLECTION — style-prop key → {@link styleValue}, with each key a member
|
|
22
|
+
* in its own right.
|
|
23
|
+
*
|
|
24
|
+
* Being a sub-entity is what makes a per-declaration edit addressable: setting `boxShadow` names
|
|
25
|
+
* `boxShadow`, rather than being an update of the whole bag that first has to read the current one
|
|
26
|
+
* to avoid erasing its siblings. It also gives the bag a rename that keeps a key's position, which
|
|
27
|
+
* matters because key order is declaration order in the emitted rule — for a shorthand/longhand
|
|
28
|
+
* pair, moving one changes what gets painted.
|
|
29
|
+
*/
|
|
30
|
+
const Style = defineSubEntity({
|
|
31
|
+
name: "style",
|
|
32
|
+
label: "Style",
|
|
33
|
+
labelPlural: "Styles",
|
|
34
|
+
/**
|
|
35
|
+
* A FACTORY, so a declaration's value binds like any other declared reference.
|
|
36
|
+
*
|
|
37
|
+
* The member's KEY is the style property being set, which is the declaration — so the value's domain
|
|
38
|
+
* is that property's, and `valueSchemaOf` stores the token it names as a ref. Without this a bag on a
|
|
39
|
+
* composite named its token as a bare leaf, invisible to the graph: renaming the token left the old
|
|
40
|
+
* name behind and deleting it wasn't refused.
|
|
41
|
+
*
|
|
42
|
+
* `styleValue` stays as the second arm, and it is what most keys take: a modifier block (a nested
|
|
43
|
+
* bag), a computed colour, a gradient, an off-system literal, and any key that isn't a style property
|
|
44
|
+
* at all. The union is ordered so the narrowed domain gets first refusal.
|
|
45
|
+
*/
|
|
46
|
+
fields: ({ config, parent, key }) => {
|
|
47
|
+
if (!config || key === void 0) return styleValue;
|
|
48
|
+
if (key.startsWith("_")) return openBag(config);
|
|
49
|
+
const bound = (config, declaration) => z.union([valueSchemaOf(declaration, config), styleValue]);
|
|
50
|
+
const declared = parent?.props?.[key];
|
|
51
|
+
if (isRef(declared?.value)) return bound(config, declared);
|
|
52
|
+
if (!config.resolve("style-property", key)) return styleValue;
|
|
53
|
+
return bound(config, {
|
|
54
|
+
type: "styleProperty",
|
|
55
|
+
value: ref("style-property", key)
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
/** A plain object: not an array, not a ref, so a computed colour or a gradient isn't walked as a bag. */
|
|
60
|
+
function isPlainRecord(value) {
|
|
61
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && !isRef(value);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Collect a bag and every modifier block nested in it, PARENTS FIRST.
|
|
65
|
+
*
|
|
66
|
+
* The order is part of the contract: {@link bagRewriteName} walks the result backwards so a child is
|
|
67
|
+
* written into its parent before that parent is rebuilt. A modifier block holds a bag of the same
|
|
68
|
+
* shape, so this is the only recursion either hook needs.
|
|
69
|
+
*/
|
|
70
|
+
function collectBag(bag, write, out) {
|
|
71
|
+
if (!isPlainRecord(bag)) return;
|
|
72
|
+
out.push({
|
|
73
|
+
bag,
|
|
74
|
+
write
|
|
75
|
+
});
|
|
76
|
+
for (const [key, value] of Object.entries(bag)) {
|
|
77
|
+
if (!key.startsWith("_") || !isPlainRecord(value)) continue;
|
|
78
|
+
collectBag(value, (next) => {
|
|
79
|
+
bag[key] = next;
|
|
80
|
+
}, out);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The edges a kind's bags imply by NAME — each key names a style property, and a `_`-prefixed key
|
|
85
|
+
* names the modifier whose block it opens.
|
|
86
|
+
*
|
|
87
|
+
* A key is not a ref, so `collectRefs` can't see it: nothing said a component depended on the style
|
|
88
|
+
* property its bag sets, so renaming that property left every bag keyed by a name that no longer
|
|
89
|
+
* existed and deleting one in use wasn't refused.
|
|
90
|
+
*
|
|
91
|
+
* PURE in the body it is handed, which is what lets these ride the same incremental index as
|
|
92
|
+
* ref-borne edges — see `EntityKind.nameEdges`. An edge is therefore minted for EVERY key rather than
|
|
93
|
+
* only for keys that currently resolve, and `Config.dependenciesOf` filters the outgoing direction
|
|
94
|
+
* live instead.
|
|
95
|
+
*/
|
|
96
|
+
function bagNameEdges(sites) {
|
|
97
|
+
return (data) => {
|
|
98
|
+
const edges = /* @__PURE__ */ new Set();
|
|
99
|
+
const bags = isExtendedRef(data) ? data.extend : data;
|
|
100
|
+
for (const { bag } of sites(bags)) for (const key of Object.keys(bag)) if (key.startsWith("_")) edges.add(`modifier:${key.slice(1)}`);
|
|
101
|
+
else edges.add(`style-property:${key}`);
|
|
102
|
+
return [...edges];
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Rewrite a style-property or modifier name wherever a bag holds it as a key — the cascade half of
|
|
107
|
+
* {@link bagNameEdges}.
|
|
108
|
+
*
|
|
109
|
+
* Key ORDER is preserved, because a bag's order is declaration order in the emitted rule: for a
|
|
110
|
+
* shorthand/longhand pair, moving one changes what paints. So a key is swapped in place, which needs
|
|
111
|
+
* a fresh object, which is why the walk runs bottom-up.
|
|
112
|
+
*/
|
|
113
|
+
const leafOf = (path) => path.slice(path.lastIndexOf("/") + 1);
|
|
114
|
+
function bagRewriteName(sites) {
|
|
115
|
+
return (data, from, to) => {
|
|
116
|
+
const source = splitRef(from);
|
|
117
|
+
const target = splitRef(to);
|
|
118
|
+
if (source.kind !== "style-property" && source.kind !== "modifier") return data;
|
|
119
|
+
const modifier = source.kind === "modifier";
|
|
120
|
+
const oldKey = modifier ? `_${leafOf(source.path)}` : source.qualifiedPath;
|
|
121
|
+
const newKey = modifier ? `_${leafOf(target.path)}` : target.qualifiedPath;
|
|
122
|
+
const next = structuredClone(data);
|
|
123
|
+
let changed = false;
|
|
124
|
+
for (const { bag, write } of [...sites(next)].reverse()) {
|
|
125
|
+
if (!(oldKey in bag)) continue;
|
|
126
|
+
write(Object.fromEntries(Object.entries(bag).map(([key, value]) => [key === oldKey ? newKey : key, value])));
|
|
127
|
+
changed = true;
|
|
128
|
+
}
|
|
129
|
+
return changed ? next : data;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Bind a bag's token-named values to the tokens they name — `{ bg: 'brand' }` is stored as
|
|
134
|
+
* `{ bg: { __ref: 'token:color/brand' } }`.
|
|
135
|
+
*
|
|
136
|
+
* This is the same coercion {@link conditionValue} performs on a rule's condition, for the same
|
|
137
|
+
* reason: a name in a plain string is invisible to the ref graph, so nothing a component actually
|
|
138
|
+
* USED was an edge and `dependentsOf('token', …)` answered with the declarations alone. Confidently
|
|
139
|
+
* wrong rather than missing — a model told a token has no dependents can reasonably propose deleting
|
|
140
|
+
* it (model gap 8).
|
|
141
|
+
*
|
|
142
|
+
* Per BAG rather than per prop, because the narrowed per-prop shape only exists for a layer whose
|
|
143
|
+
* element resolves to a component. A raw-tag layer (`div`) and every catchall key get the open bag,
|
|
144
|
+
* which is most of a real system's styling, so a per-prop transform would convert a minority of it
|
|
145
|
+
* and leave the graph just as wrong.
|
|
146
|
+
*
|
|
147
|
+
* Only a leaf that RESOLVES as a token converts. A keyword (`row`) names no entity, an off-scale
|
|
148
|
+
* literal (`[100%]`) isn't in the domain, and a ref to a token that doesn't exist would be a
|
|
149
|
+
* dangling edge — worse than the missing one it replaced.
|
|
150
|
+
*
|
|
151
|
+
* Returns the bag it was GIVEN when nothing converted, so an unchanged bag keeps its identity and
|
|
152
|
+
* the snapshot slice it sits in doesn't churn.
|
|
153
|
+
*/
|
|
154
|
+
function bindBagTokens(config, bag) {
|
|
155
|
+
const out = {};
|
|
156
|
+
let changed = false;
|
|
157
|
+
for (const [key, value] of Object.entries(bag)) {
|
|
158
|
+
if (key.startsWith("_") && config.resolve("modifier", key.slice(1)) && value && typeof value === "object" && !Array.isArray(value) && !isRef(value)) {
|
|
159
|
+
const inner = bindBagTokens(config, value);
|
|
160
|
+
out[key] = inner;
|
|
161
|
+
changed ||= inner !== value;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (typeof value === "string" && config.resolve("style-property", key)) {
|
|
165
|
+
const token = stylePropTokenPath(config, key, value);
|
|
166
|
+
if (token) {
|
|
167
|
+
out[key] = ref("token", token);
|
|
168
|
+
changed = true;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
out[key] = value;
|
|
173
|
+
}
|
|
174
|
+
return changed ? out : bag;
|
|
175
|
+
}
|
|
176
|
+
/** `border-radius` → `borderRadius`: the JSX spelling of a hyphenated name. */
|
|
177
|
+
const camelCase = (name) => name.replace(/-+([a-z0-9])/g, (_match, char) => char.toUpperCase());
|
|
178
|
+
/** The style property that declares this CSS property among its `properties`, if the system has one. */
|
|
179
|
+
function stylePropertyBehind(config, cssProperty) {
|
|
180
|
+
return config.list("style-property").find((entry) => {
|
|
181
|
+
const properties = entry.body.properties;
|
|
182
|
+
return Array.isArray(properties) && properties.some((property) => camelCase(String(property)) === cssProperty);
|
|
183
|
+
})?.path;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Why a bag key cannot be a style prop, or `undefined` when it can be.
|
|
187
|
+
*
|
|
188
|
+
* The emitter writes JSX, and JSX spells every attribute camelCase except `data-*` and `aria-*`, so
|
|
189
|
+
* a hyphenated key is a CSS property name written where a style-prop name belongs. The bag is open,
|
|
190
|
+
* so without this the key would pass as an element attribute and paint nothing.
|
|
191
|
+
*/
|
|
192
|
+
function bagKeyIssue(config, key, declared, { cssBehind = true } = {}) {
|
|
193
|
+
if (key.startsWith("data-") || key.startsWith("aria-")) return void 0;
|
|
194
|
+
if (key.includes("-")) {
|
|
195
|
+
const camel = camelCase(key);
|
|
196
|
+
if (config.resolve("style-property", camel)) return `\`${key}\` is not a style property; a layer key is the style-prop name, \`${camel}\`.`;
|
|
197
|
+
return `\`${key}\` is not a style property of this system, and a hyphenated key is passed to the element as an attribute, which paints nothing. Use a style-prop name (see style-property/list).`;
|
|
198
|
+
}
|
|
199
|
+
if (!cssBehind || declared?.has(key) || config.resolve("style-property", key)) return;
|
|
200
|
+
const behind = stylePropertyBehind(config, key);
|
|
201
|
+
if (behind) return `\`${key}\` is the CSS property behind the style property \`${behind}\`; a layer key is the style-prop name, \`${behind}\`.`;
|
|
202
|
+
if (isCssProperty(key)) return `\`${key}\` is a CSS property, and this system has no style property that sets it, so it would be passed to the element as an attribute and paint nothing. Declare one — \`{ "kind": "style-property", "operation": "create", "path": "${key}", "data": { "properties": ["${kebabCase(key)}"], "values": [] } }\` with keywords or a token group ref in \`values\` — expose it on the primitive as \`{ "type": "styleProperty", "value": { "__ref": "style-property:${key}" } }\`, then set it here by one of its values.`;
|
|
203
|
+
}
|
|
204
|
+
/** A registered modifier's block, which holds a bag of the same shape. */
|
|
205
|
+
function isModifierBlock(config, key, value) {
|
|
206
|
+
return key.startsWith("_") && config.resolve("modifier", key.slice(1)) !== void 0 && typeof value === "object" && value !== null && !Array.isArray(value) && !isRef(value);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Report every refused key in a bag. `nested` walks into modifier blocks; the built bag routes
|
|
210
|
+
* those through itself, so it reports its own level only and the nested bag reports the rest.
|
|
211
|
+
*/
|
|
212
|
+
function addBagKeyIssues({ config, bag, ctx, nested, declared, cssBehind = true, path = [] }) {
|
|
213
|
+
for (const [key, value] of Object.entries(bag)) {
|
|
214
|
+
const message = bagKeyIssue(config, key, declared, { cssBehind });
|
|
215
|
+
if (message) {
|
|
216
|
+
ctx.addIssue({
|
|
217
|
+
code: "custom",
|
|
218
|
+
path: [...path, key],
|
|
219
|
+
message
|
|
220
|
+
});
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (nested && isModifierBlock(config, key, value)) addBagKeyIssues({
|
|
224
|
+
config,
|
|
225
|
+
bag: value,
|
|
226
|
+
ctx,
|
|
227
|
+
nested,
|
|
228
|
+
declared,
|
|
229
|
+
cssBehind,
|
|
230
|
+
path: [...path, key]
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/** The open bag — every key a style value, with token names bound to their tokens. `cssBehind`
|
|
235
|
+
* as in {@link bagKeyIssue}: off for a bag that may reach an intrinsic element's attributes. */
|
|
236
|
+
function openBag(config, { cssBehind = true } = {}) {
|
|
237
|
+
return z.record(z.string(), styleValue).superRefine((bag, ctx) => addBagKeyIssues({
|
|
238
|
+
config,
|
|
239
|
+
bag,
|
|
240
|
+
ctx,
|
|
241
|
+
nested: true,
|
|
242
|
+
cssBehind
|
|
243
|
+
})).transform((bag) => bindBagTokens(config, bag));
|
|
244
|
+
}
|
|
245
|
+
//#endregion
|
|
246
|
+
export { Style, addBagKeyIssues, bagNameEdges, bagRewriteName, bindBagTokens, camelCase, collectBag, isPlainRecord, openBag, styleValue };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Config } from "../../framework/Config.js";
|
|
2
|
+
|
|
3
|
+
//#region src/entities/system/token-index.d.ts
|
|
4
|
+
interface TokenBinding {
|
|
5
|
+
/**
|
|
6
|
+
* The token's path — its identity AND its display label. Never split into namespace + name.
|
|
7
|
+
*
|
|
8
|
+
* QUALIFIED when the binding is borrowed (`palette/violet@ds`), because the source is half of what
|
|
9
|
+
* the ref names: the same bare path can exist in this config and in three of its sources, denoting
|
|
10
|
+
* four different colours.
|
|
11
|
+
*/
|
|
12
|
+
readonly path: string;
|
|
13
|
+
/** The slug the binding is borrowed through, or `undefined` when it is this config's own. Carried
|
|
14
|
+
* beside {@link path} so a surface can badge the provenance without re-parsing the ref. */
|
|
15
|
+
readonly source: string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* The token's own DECLARED type, when it declares one. Never inherited from a binding target.
|
|
18
|
+
*
|
|
19
|
+
* Stays declared-only because "untyped" is a state callers reason about: an untyped token is a
|
|
20
|
+
* plausible candidate for most types, so `searchTokens` offers it alongside a type filter and takes
|
|
21
|
+
* `untyped: 'exclude'` for a cell that cannot take one. Sniffing a type here would answer that
|
|
22
|
+
* question for them, and an untyped `gradient/*` would stop being offered to a colour cell.
|
|
23
|
+
*
|
|
24
|
+
* A surface CHOOSING A VISUAL wants {@link valueType} instead.
|
|
25
|
+
*/
|
|
26
|
+
readonly type: string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* The EFFECTIVE type — {@link type}, else the shape of the literal the chase ends at.
|
|
29
|
+
*
|
|
30
|
+
* What a swatch or a glyph is picked from, and the reason it exists is that every such site had to
|
|
31
|
+
* remember the fallback itself and five of six didn't. A raw palette is authored as bare hex with no
|
|
32
|
+
* `type`, so the declared tier alone is `undefined` for exactly the tokens most worth painting — the
|
|
33
|
+
* reference badge, the composite layer cell and the autocomplete rows all dropped their swatch and
|
|
34
|
+
* showed the generic hexagon.
|
|
35
|
+
*
|
|
36
|
+
* Beside `type` rather than replacing it because the two answer different questions, and the filter
|
|
37
|
+
* above genuinely wants the declared one.
|
|
38
|
+
*/
|
|
39
|
+
readonly valueType: string | undefined;
|
|
40
|
+
/** The literal with aliases chased — what a swatch paints. The base, unless the binding was read
|
|
41
|
+
* under a condition, in which case what that condition shows. */
|
|
42
|
+
readonly value: string | number | undefined;
|
|
43
|
+
}
|
|
44
|
+
/** A candidate for something the user typed. Same shape as a binding: a match IS a binding. */
|
|
45
|
+
interface TokenMatch extends TokenBinding {}
|
|
46
|
+
/**
|
|
47
|
+
* What `value` binds to, or `undefined` when it is a literal.
|
|
48
|
+
*
|
|
49
|
+
* Accepts a `Ref` (or a `kind:path` marker string) and nothing else. A `var(--…)` string is a
|
|
50
|
+
* literal here by design — see the module note.
|
|
51
|
+
*
|
|
52
|
+
* Read in the config the ref NAMES, via the same `configFor` routing every other read uses. It used to
|
|
53
|
+
* strip the `@source` and look the bare path up locally, which for a borrowed ref answers with OUR
|
|
54
|
+
* token of that path — `brand/primary` borrowing `palette/violet@ds` painted the local
|
|
55
|
+
* `palette/violet`, a confidently wrong colour with nothing to signal it, and fell back to "not a
|
|
56
|
+
* binding" when we happened to have no such token. That is the fallback `resolveFieldValue` and
|
|
57
|
+
* `configFor` both refuse for the same reason.
|
|
58
|
+
*/
|
|
59
|
+
declare function tokenBinding(config: Config, value: unknown, options?: {
|
|
60
|
+
/** The override condition the binding is read under, so `value` is what that condition shows.
|
|
61
|
+
* `null`, the default, is the base. */
|
|
62
|
+
under?: string | null;
|
|
63
|
+
}): TokenBinding | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Which token this name names EXACTLY — the token flavour of {@link matchEntities}, adding the type
|
|
66
|
+
* and the resolved literal so a caller needs no second lookup.
|
|
67
|
+
*
|
|
68
|
+
* More than one result means the name is genuinely ambiguous and the caller must disambiguate.
|
|
69
|
+
*/
|
|
70
|
+
declare function matchTokens(config: Config, query: string, opts?: {
|
|
71
|
+
type?: string;
|
|
72
|
+
limit?: number;
|
|
73
|
+
}): TokenMatch[];
|
|
74
|
+
/**
|
|
75
|
+
* Tokens a partial query might mean, best first — the token flavour of {@link searchEntities}.
|
|
76
|
+
*
|
|
77
|
+
* `untyped` is the one rule that is genuinely about tokens rather than searching: a token declaring no
|
|
78
|
+
* type of its own is usually a plausible candidate, but a colour cell offering untyped `gradient/*` and
|
|
79
|
+
* `flex/*` tokens was a real bug. `'include'` (the default) over-suggests; `'exclude'` is for a field
|
|
80
|
+
* that cannot survive a wrong one. The CALLER decides, because which value types are fussy is a
|
|
81
|
+
* property of the surface, not of the config.
|
|
82
|
+
*/
|
|
83
|
+
declare function searchTokens(config: Config, query: string, opts?: {
|
|
84
|
+
type?: string;
|
|
85
|
+
limit?: number;
|
|
86
|
+
untyped?: 'include' | 'exclude';
|
|
87
|
+
}): TokenMatch[];
|
|
88
|
+
//#endregion
|
|
89
|
+
export { TokenBinding, TokenMatch, matchTokens, searchTokens, tokenBinding };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { isRef, splitRef } from "../../framework/utils/refs.js";
|
|
2
|
+
import { resolveTokenValueUnder } from "../../framework/projections.js";
|
|
3
|
+
import { resolveValueType } from "../../css/value-type.js";
|
|
4
|
+
import { matchEntities, searchEntities } from "../../framework/entity-search.js";
|
|
5
|
+
//#region src/entities/system/token-index.ts
|
|
6
|
+
/**
|
|
7
|
+
* Token identity, in the one direction that round-trips.
|
|
8
|
+
*
|
|
9
|
+
* A token's identity is its PATH. `var(--…)` is an emit-time projection ({@link cssVarRef}) and
|
|
10
|
+
* deliberately not accepted here as a way to name a token, because the encoding is many-to-one:
|
|
11
|
+
* `cssVar` kebab-cases the group and collapses `/` and `.` in the leaf, so `spectrum/purple/9` and
|
|
12
|
+
* `spectrum/purple-9` produce the same custom property, as do `borderColor/x` and `border/color/x`.
|
|
13
|
+
* A reverse map over vars therefore cannot be correct in general — it silently answers with whichever
|
|
14
|
+
* claimant it indexed last. So there is no var→token direction here at all. Code that has to read
|
|
15
|
+
* legacy var-shaped data (a one-time migration) builds its own index at that boundary and discards
|
|
16
|
+
* it; nothing permanent should depend on an encoding that cannot express identity.
|
|
17
|
+
*
|
|
18
|
+
* So: a stored value either REFS a token (`{ __ref: 'token:<path>' }`) or is a literal. Those are the
|
|
19
|
+
* only two things a consumer has to handle. A ref may be `@source`-qualified, which decides WHERE it is
|
|
20
|
+
* read, never whether it is a ref — see {@link tokenBinding}.
|
|
21
|
+
*/
|
|
22
|
+
/** A token's own declared type, read off the stored body. */
|
|
23
|
+
function declaredTypeOf(config, path) {
|
|
24
|
+
const token = config.resolve("token", path);
|
|
25
|
+
if (!token) return void 0;
|
|
26
|
+
const type = token.toJSON().type;
|
|
27
|
+
return typeof type === "string" ? type : void 0;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A binding read in the config that ANSWERS for it.
|
|
31
|
+
*
|
|
32
|
+
* `config` is where the token lives, which for a borrowed ref is not the config that holds the ref;
|
|
33
|
+
* `label` is how the ref spells it, which is what a chip shows and what a rebind writes back. Split,
|
|
34
|
+
* because collapsing them is exactly the bug below.
|
|
35
|
+
*/
|
|
36
|
+
function bindingFor(config, path, label = path, source, under = null) {
|
|
37
|
+
if (!config.resolve("token", path)) return void 0;
|
|
38
|
+
const type = declaredTypeOf(config, path);
|
|
39
|
+
const value = resolveTokenValueUnder(config, path, under);
|
|
40
|
+
return {
|
|
41
|
+
path: label,
|
|
42
|
+
source,
|
|
43
|
+
type,
|
|
44
|
+
valueType: resolveValueType({
|
|
45
|
+
type,
|
|
46
|
+
value
|
|
47
|
+
}),
|
|
48
|
+
value
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* What `value` binds to, or `undefined` when it is a literal.
|
|
53
|
+
*
|
|
54
|
+
* Accepts a `Ref` (or a `kind:path` marker string) and nothing else. A `var(--…)` string is a
|
|
55
|
+
* literal here by design — see the module note.
|
|
56
|
+
*
|
|
57
|
+
* Read in the config the ref NAMES, via the same `configFor` routing every other read uses. It used to
|
|
58
|
+
* strip the `@source` and look the bare path up locally, which for a borrowed ref answers with OUR
|
|
59
|
+
* token of that path — `brand/primary` borrowing `palette/violet@ds` painted the local
|
|
60
|
+
* `palette/violet`, a confidently wrong colour with nothing to signal it, and fell back to "not a
|
|
61
|
+
* binding" when we happened to have no such token. That is the fallback `resolveFieldValue` and
|
|
62
|
+
* `configFor` both refuse for the same reason.
|
|
63
|
+
*/
|
|
64
|
+
function tokenBinding(config, value, options = {}) {
|
|
65
|
+
if (!isRef(value)) return void 0;
|
|
66
|
+
const { kind, path, qualifiedPath, source } = splitRef(value);
|
|
67
|
+
if (kind !== "token") return void 0;
|
|
68
|
+
const target = config.configFor(value);
|
|
69
|
+
if (!target) return void 0;
|
|
70
|
+
return bindingFor(target, path, qualifiedPath, source, options.under ?? null);
|
|
71
|
+
}
|
|
72
|
+
/** Turn paths into bindings, dropping any that no longer resolve. */
|
|
73
|
+
function bindingsFor(config, paths) {
|
|
74
|
+
const matches = [];
|
|
75
|
+
for (const path of paths) {
|
|
76
|
+
const binding = bindingFor(config, path);
|
|
77
|
+
if (binding) matches.push(binding);
|
|
78
|
+
}
|
|
79
|
+
return matches;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Which token this name names EXACTLY — the token flavour of {@link matchEntities}, adding the type
|
|
83
|
+
* and the resolved literal so a caller needs no second lookup.
|
|
84
|
+
*
|
|
85
|
+
* More than one result means the name is genuinely ambiguous and the caller must disambiguate.
|
|
86
|
+
*/
|
|
87
|
+
function matchTokens(config, query, opts) {
|
|
88
|
+
const matches = bindingsFor(config, matchEntities(config, "token", query));
|
|
89
|
+
const kept = opts?.type === void 0 ? matches : matches.filter((match) => match.type === opts.type);
|
|
90
|
+
return opts?.limit === void 0 ? kept : kept.slice(0, opts.limit);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Tokens a partial query might mean, best first — the token flavour of {@link searchEntities}.
|
|
94
|
+
*
|
|
95
|
+
* `untyped` is the one rule that is genuinely about tokens rather than searching: a token declaring no
|
|
96
|
+
* type of its own is usually a plausible candidate, but a colour cell offering untyped `gradient/*` and
|
|
97
|
+
* `flex/*` tokens was a real bug. `'include'` (the default) over-suggests; `'exclude'` is for a field
|
|
98
|
+
* that cannot survive a wrong one. The CALLER decides, because which value types are fussy is a
|
|
99
|
+
* property of the surface, not of the config.
|
|
100
|
+
*/
|
|
101
|
+
function searchTokens(config, query, opts) {
|
|
102
|
+
return bindingsFor(config, searchEntities(config, "token", query, {
|
|
103
|
+
limit: opts?.limit,
|
|
104
|
+
filter: opts?.type === void 0 ? void 0 : (path) => {
|
|
105
|
+
const type = declaredTypeOf(config, path);
|
|
106
|
+
if (type === opts.type) return true;
|
|
107
|
+
return type === void 0 && opts.untyped !== "exclude";
|
|
108
|
+
}
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
export { matchTokens, searchTokens, tokenBinding };
|