@yahoo/uds-create-config 5.34.0 → 5.34.2

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.
@@ -861,12 +861,18 @@ type StoredContractProps<Props> = { [Key in keyof Props]: Props[Key] extends {
861
861
  } ? Omit<Props[Key], 'value'> & {
862
862
  value: { [Value in Values[number]]: Record<never, never> };
863
863
  } : Props[Key] };
864
+ /** Match the linked-body hook: a different prop type replaces the complete declaration. */
865
+ type OverlayContractProps<Base, Delta> = Omit<Base, keyof Delta> & { [Key in keyof Delta]: Key extends keyof Base ? Base[Key] extends {
866
+ type: infer Type;
867
+ } ? Delta[Key] extends {
868
+ type: Type;
869
+ } ? OverlayContract<Base[Key], Delta[Key]> : Delta[Key] : Delta[Key] : Delta[Key] };
864
870
  type ResolvedLayers<Contract, Delta> = Delta extends {
865
871
  readonly layers: infer Layers;
866
872
  } ? Layers extends LayerMap ? OverlayContract<ContractLayers<Contract>, Layers> : ContractLayers<Contract> : ContractLayers<Contract>;
867
873
  type ResolvedProps<Contract, Delta> = Delta extends {
868
874
  readonly props: infer Props;
869
- } ? Props extends PropMap ? OverlayContract<StoredContractProps<ContractProps<Contract>>, StoredContractProps<Props>> : ContractProps<Contract> : ContractProps<Contract>;
875
+ } ? Props extends PropMap ? OverlayContractProps<StoredContractProps<ContractProps<Contract>>, StoredContractProps<Props>> : ContractProps<Contract> : ContractProps<Contract>;
870
876
  type ResolvedDefaults<Contract, Delta> = Delta extends {
871
877
  readonly defaultProps: infer Defaults;
872
878
  } ? OverlayContract<Contract extends {
@@ -12,10 +12,10 @@ import { translateLinkedStyleBags } from "./linked-style-values.js";
12
12
  import { listedIn } from "../../framework/utils/enumerated.js";
13
13
  import { valueSchemaOf } from "../../framework/value-domain.js";
14
14
  import { Package } from "./Package.js";
15
- import { bindPreviewGlyphs, glyphLeafOf } from "./glyph-identity.js";
15
+ import { bindPreviewGlyphs, glyphMemberRefIn } from "./glyph-identity.js";
16
16
  import { Style, addBagKeyIssues, anatomyPropValue, bagNameEdges, bagRewriteName, bindBagTokens, collectBag, isPlainRecord, openBag, styleValue } from "./style-bag.js";
17
17
  import { storedPreview } from "../../framework/preview-store.js";
18
- import { glyphPropsOf, propOwner, propValueDomain, refListOf, resolveComponentProps, stylePropNumberUnit, stylePropValueLeaves, validateComponentProps } from "../../framework/projections.js";
18
+ import { glyphPropsOf, glyphPropsOfBody, propOwner, propValueDomain, refListOf, resolveComponentProps, stylePropNumberUnit, stylePropValueLeaves, validateComponentProps } from "../../framework/projections.js";
19
19
  import { carriesContent, intoName, isValueSlot, renderBoundProp, routedPropIn, routesContent } from "../../framework/prop-surface.js";
20
20
  import { slotAnatomyPropOf, slotTargetsOf, withoutTruthyTerm } from "../../framework/render-spec.js";
21
21
  import { listSlots, namedSlots, slotHostedBy, slotOf, slotsFor } from "../../spec/slot.js";
@@ -664,7 +664,7 @@ function canonicalWhen(when) {
664
664
  function styleBagValue({ config, declaration, name = "<prop>", glyphLibraries }) {
665
665
  const domain = valueSchemaOf(declaration, config);
666
666
  const bound = declaration?.value;
667
- if (glyphLibraries && glyphLibraries.length > 0) return z.union([glyphLeafOf({
667
+ if (glyphLibraries && glyphLibraries.length > 0) return z.union([glyphMemberRefIn({
668
668
  config,
669
669
  libraries: glyphLibraries
670
670
  }), domain]);
@@ -1131,6 +1131,10 @@ const Preview = defineSubEntity({
1131
1131
  config,
1132
1132
  owner: body,
1133
1133
  build: () => {
1134
+ const glyphProps = glyphPropsOfBody({
1135
+ config,
1136
+ body
1137
+ });
1134
1138
  const when = {};
1135
1139
  for (const [name, decl] of Object.entries(body.props ?? {})) when[name] = conditionValue(name, decl, config).optional();
1136
1140
  for (const [name, decl] of Object.entries(body.states ?? {})) when[name] = stateConditionValue(decl).optional();
@@ -1138,7 +1142,8 @@ const Preview = defineSubEntity({
1138
1142
  when: z.strictObject(when, { error: previewShapeError }).nullable().default(null),
1139
1143
  props: z.record(z.string(), z.unknown()).transform((props) => bindPreviewGlyphs({
1140
1144
  config,
1141
- props
1145
+ props,
1146
+ glyphProps
1142
1147
  }))
1143
1148
  }, { error: previewShapeError });
1144
1149
  }
@@ -1833,11 +1838,23 @@ const componentBags = (data) => {
1833
1838
  };
1834
1839
  const ComponentEntity = defineEntity({
1835
1840
  kind: "component",
1836
- rebaseLinkedBody: (args) => translateLinkedStyleBags({
1837
- ...args,
1838
- bags: componentBags,
1839
- owner: args.path
1840
- }),
1841
+ rebaseLinkedBody: (args) => {
1842
+ const body = translateLinkedStyleBags({
1843
+ ...args,
1844
+ bags: componentBags,
1845
+ owner: args.path
1846
+ });
1847
+ if (!isPlainObject(body.props) || !isPlainObject(args.extend.props)) return body;
1848
+ const props = { ...body.props };
1849
+ for (const [name, next] of Object.entries(args.extend.props)) {
1850
+ const previous = props[name];
1851
+ if (isPlainObject(previous) && isPlainObject(next) && typeof next.type === "string" && next.type !== previous.type) delete props[name];
1852
+ }
1853
+ return {
1854
+ ...body,
1855
+ props
1856
+ };
1857
+ },
1841
1858
  prepareLinkedBody: ({ body, config }) => {
1842
1859
  if (!isPlainObject(body.props)) return body;
1843
1860
  const layers = isPlainObject(body.layers) ? body.layers : void 0;
@@ -175,16 +175,30 @@ function glyphOfLibrary({ library, module, leaves }) {
175
175
  }
176
176
  /**
177
177
  * The glyph form for a key that reaches a library through a forward (`icon` → `icon/name`): the
178
- * component or its `package:` ref, answered as the bare member name. The forwarded key stores the
179
- * leaf rather than a member ref, and the emitter and the renderer resolve it through the same
180
- * libraries (`glyphPropsOf`), taking the first that holds it. Each library's arm refuses by cause,
181
- * so a glyph of a library the key does not reach says so.
178
+ * component, its `package:` ref, the member's name a surface writes, or the member ref a stored
179
+ * config already holds, answered as the member ref `icon:<library>/<name>`. The ref names its library, so a key reaching several resolves
180
+ * without a lookup. Each library's arm refuses by cause, so a glyph of a library the key does not
181
+ * reach says so.
182
182
  */
183
- function glyphLeafOf({ config, libraries }) {
184
- const arms = libraries.map((library) => glyphOfLibrary(libraryGlyphFacts({
185
- config,
186
- target: `icon:${library}`
187
- })));
183
+ function glyphMemberRefIn({ config, libraries }) {
184
+ const arms = libraries.map((library) => {
185
+ const facts = libraryGlyphFacts({
186
+ config,
187
+ target: `icon:${library}`
188
+ });
189
+ const toRef = (name) => ({ __ref: `icon:${library}/${name}` });
190
+ const memberOfRef = (value) => {
191
+ if (!isRef(value) || kindOf(value) !== "icon") return void 0;
192
+ const path = pathOf(value);
193
+ const name = path.slice(library.length + 1);
194
+ return path.startsWith(`${library}/`) && facts.leaves.includes(name) ? name : void 0;
195
+ };
196
+ return z.union([
197
+ z.custom((value) => memberOfRef(value) !== void 0).transform((value) => toRef(memberOfRef(value))),
198
+ z.string().refine((name) => facts.leaves.includes(name)).transform(toRef),
199
+ glyphOfLibrary(facts).transform((name) => toRef(name))
200
+ ]);
201
+ });
188
202
  if (arms.length === 1) return arms[0];
189
203
  return z.union(arms);
190
204
  }
@@ -204,9 +218,11 @@ function glyphMemberRefOf(config, identity) {
204
218
  * way `defaultProps` are. Once an owner is known, this pass binds each such ref to
205
219
  * `icon:<library>/<name>` through the library whose package ships it, at the top level and inside a
206
220
  * stored element's props, which is the spelling the build writes when it reads `.preview()` from
207
- * source. A `package:` ref no library claims is another package's export and stays as written.
221
+ * source. A member's name written under one of the owner's glyph props (`glyphProps`) binds through
222
+ * the first of that prop's libraries holding it. A `package:` ref no library claims is another
223
+ * package's export and stays as written.
208
224
  */
209
- function bindPreviewGlyphs({ config, props }) {
225
+ function bindPreviewGlyphs({ config, props, glyphProps = {} }) {
210
226
  const bind = (value) => {
211
227
  if (typeof value !== "object" || value === null) return value;
212
228
  if (Array.isArray(value)) return value.map(bind);
@@ -216,7 +232,14 @@ function bindPreviewGlyphs({ config, props }) {
216
232
  for (const [key, member] of Object.entries(value)) out[key] = bind(member);
217
233
  return out;
218
234
  };
219
- return bind(props);
235
+ const out = bind(props);
236
+ for (const [prop, libraries] of Object.entries(glyphProps)) {
237
+ const name = out[prop];
238
+ if (typeof name !== "string") continue;
239
+ const library = libraries.find((path) => memberLeaves(config, `icon:${path}`).includes(name));
240
+ if (library) out[prop] = { __ref: `icon:${library}/${name}` };
241
+ }
242
+ return out;
220
243
  }
221
244
  //#endregion
222
- export { bindPreviewGlyphs, glyphIdentityOf, glyphLeafOf, glyphMembersOf, glyphOfLibrary, glyphPackageRef, glyphPackageRefOf, isComponentType, libraryGlyphFacts, recordGlyphIdentities };
245
+ export { bindPreviewGlyphs, glyphIdentityOf, glyphMemberRefIn, glyphMembersOf, glyphOfLibrary, glyphPackageRef, glyphPackageRefOf, isComponentType, libraryGlyphFacts, recordGlyphIdentities };
@@ -3,7 +3,7 @@ import { composedValueSchemas } from "./composed-values.js";
3
3
  import { defineSubEntity } from "../../framework/defineSubEntity.js";
4
4
  import { isCssProperty, kebabCase } from "../../css/values.js";
5
5
  import { valueSchemaOf } from "../../framework/value-domain.js";
6
- import { glyphLeafOf, glyphPackageRef } from "./glyph-identity.js";
6
+ import { glyphMemberRefIn, glyphPackageRef } from "./glyph-identity.js";
7
7
  import { glyphPropsOfBody, isCustomPropertyKey, refListOf, stylePropTokenPath } from "../../framework/projections.js";
8
8
  import { z } from "zod";
9
9
  //#region src/entities/system/style-bag.ts
@@ -59,7 +59,7 @@ const Style = defineSubEntity({
59
59
  config,
60
60
  body: parent
61
61
  })[key];
62
- if (libraries && libraries.length > 0) return z.union([glyphLeafOf({
62
+ if (libraries && libraries.length > 0) return z.union([glyphMemberRefIn({
63
63
  config,
64
64
  libraries
65
65
  }), styleValue]);