@yahoo/uds-create-config 5.47.0 → 5.48.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.
@@ -1699,7 +1699,7 @@ const componentFields = z.strictObject({
1699
1699
  /**
1700
1700
  * What the RENDER knows and a style rule keys on — the field has a value, the image loaded, the
1701
1701
  * indicator is sliding. Not props: a caller never passes one, so none is part of the component's
1702
- * API. The render passes them to `states(props, { … })` and spreads the layers it hands back;
1702
+ * API. The render passes them to `states(_props, { … })` and spreads the layers it hands back;
1703
1703
  * the rules naming one follow the values given, and the root carries each as a `data-<name>`
1704
1704
  * attribute. Studio and tests force one through the module's internal channel, never a prop.
1705
1705
  */
@@ -1707,7 +1707,7 @@ const componentFields = z.strictObject({
1707
1707
  type: z.literal("variant"),
1708
1708
  value: z.array(z.string()).min(1),
1709
1709
  default: z.string().optional()
1710
- })])).optional().describe("What the render knows and a style rule keys on, by name: `{ \"filled\": { \"type\": \"boolean\" } }`, or `{ \"phase\": { \"type\": \"variant\", \"value\": [\"idle\", \"sliding\"], \"default\": \"idle\" } }`. Not props, so not part of the component's API: the render passes its `props` and the values it knows to `const layers = states(props, { filled: value !== \"\" })` and spreads those layers (`{...layers.root}`) instead of `props`; a rule naming a state in `when` (`{ \"filled\": true }`, `{ \"phase\": \"sliding\" }`) is tested against the values given, and the root carries each as a `data-<name>` attribute. A value a caller controls is a prop instead, which the render reports the state from."),
1710
+ })])).optional().describe("What the render knows and a style rule keys on, by name: `{ \"filled\": { \"type\": \"boolean\" } }`, or `{ \"phase\": { \"type\": \"variant\", \"value\": [\"idle\", \"sliding\"], \"default\": \"idle\" } }`. Not props, so not part of the component's API: the render takes its own as `props: _props`, passes them and the values it knows to `const props = states(_props, { filled: value !== \"\" })`, and spreads those layers (`{...props.root}`); a rule naming a state in `when` (`{ \"filled\": true }`, `{ \"phase\": \"sliding\" }`) is tested against the values given, and the root carries each as a `data-<name>` attribute. A value a caller controls is a prop instead, which the render reports the state from."),
1711
1711
  /**
1712
1712
  * Which layers' element props this component also exposes — see {@link Forward}.
1713
1713
  *
@@ -432,7 +432,20 @@ type DeclaredProps<P, L extends LayerMap = LayerMap, Self = unknown, View extend
432
432
  type RoutedValueOf<L extends LayerMap, D, Self = unknown, K extends PropertyKey = never, View extends SlotView = 'consumer'> = D extends {
433
433
  type: 'forward';
434
434
  text: true;
435
- } ? string : [ForwardPath<D>] extends [never] ? ValueOf<D, Self, K, View> : ForwardPath<D> extends `${infer Layer}/${infer Prop}` ? Prop extends 'children' ? ReactNode : Layer extends keyof L ? Prop extends keyof ElementPropsOf<L[Layer]> ? ElementPropsOf<L[Layer]>[Prop] : unknown : unknown : ValueOf<D, Self, K, View>;
435
+ } ? string : [ForwardPath<D>] extends [never] ? ValueOf<D, Self, K, View> : D extends {
436
+ target: readonly (infer Path extends string)[];
437
+ } ? Unboxed<AllOf<Path extends string ? {
438
+ value: RouteValueOf<L, Path, D, Self, K, View>;
439
+ } : never>> : RouteValueOf<L, ForwardPath<D>, D, Self, K, View>;
440
+ /** What one `layer/prop` route takes: the layer element's prop, its React props for a tag and its
441
+ * declared ones for a component; content for `children`. */
442
+ type RouteValueOf<L extends LayerMap, Path, D, Self, K extends PropertyKey, View extends SlotView> = Path extends `${infer Layer}/${infer Prop}` ? Prop extends 'children' ? ReactNode : Layer extends keyof L ? Prop extends keyof ElementPropsOf<L[Layer]> ? ElementPropsOf<L[Layer]>[Prop] : unknown : unknown : ValueOf<D, Self, K, View>;
443
+ type Unboxed<Box> = Box extends {
444
+ value: infer Value;
445
+ } ? Value : never;
446
+ /** The intersection of a union's members. Each route's type is boxed (`{ value }`) before it goes in,
447
+ * so a route that takes `boolean | undefined` stays one member rather than three. */
448
+ type AllOf<U> = (U extends unknown ? (value: U) => void : never) extends ((value: infer Every) => void) ? Every : never;
436
449
  /**
437
450
  * The props the rendered ELEMENT contributes, `ref` included.
438
451
  *
@@ -676,11 +689,12 @@ type StateValues<S> = { [K in keyof S]?: S[K] extends {
676
689
  value: readonly (infer V)[];
677
690
  } ? V : boolean };
678
691
  /**
679
- * How a render reports its states — `const layers = states(props, { filled: value !== '' })` — and
680
- * spreads the bundles it hands back: `<Box {...layers.root}>`.
692
+ * How a render reports its states — `.render(({ props: _props, states }) => { const props =
693
+ * states(_props, { filled: value !== '' }); … })` — and spreads the bundles it hands back as it would
694
+ * the render's own: `<Box {...props.root}>`.
681
695
  *
682
- * A pure call, not a hook, so it can sit under a condition. It takes the render's `props` (the
683
- * bundles at rest, or as Studio or a test forced them) and returns the bundles BUILT FOR those
696
+ * A pure call, not a hook, so it can sit under a condition. It takes the bundles the render was
697
+ * handed (at rest, or as Studio or a test forced them) and returns the bundles BUILT FOR those
684
698
  * states, a fresh set: every rule naming a state, a prop a rule sets on a layer, the root's
685
699
  * `data-<name>` attribute, a portal layer and a nested instance all follow the values given. A
686
700
  * forced value still wins over them.
@@ -748,7 +762,8 @@ F extends string = never, /** The states `.states()` declared — what the rende
748
762
  * ['idle', 'sliding'], default: 'idle' } }`.
749
763
  *
750
764
  * Not props, so not part of the component's API: the render passes its `props` and the values it
751
- * knows to `const layers = states(props, { filled })` and spreads those layers in `props`' place;
765
+ * knows to `const props = states(_props, { filled })`, having taken its own as `props: _props`, and
766
+ * spreads those layers as `props`;
752
767
  * a rule naming a state in `when` follows the values given. A value a caller controls is a prop;
753
768
  * the render reports the state from it.
754
769
  */
@@ -2,7 +2,7 @@ import { isRef, pathOf } from "../../framework/utils/refs.js";
2
2
  import { createSliceMemo } from "../../framework/memo.js";
3
3
  import { isPlainRecord } from "./style-bag.js";
4
4
  import { stylePropEntries } from "../../framework/projections.js";
5
- import { forwardRoutes, intoName, routedPropIn, routesContent } from "../../framework/prop-surface.js";
5
+ import { forwardRoutes, intoName, routeEnd, routesContent } from "../../framework/prop-surface.js";
6
6
  //#region src/entities/system/forward-route-invariants.ts
7
7
  /**
8
8
  * Why a forward with several routes can't take them, or `undefined` when it can. Every route has to
@@ -21,23 +21,34 @@ function refusedRoutes(config, layers, decl) {
21
21
  }
22
22
  if (routes.some((route) => routesContent(config, layers, route))) return `A forward that carries content takes one route: the same content can't fill ${routes.map(spelled).join(" and ")}. Route a value (a variant, a string) to several layers, or give each layer its own slot.`;
23
23
  const landing = (route) => {
24
- const routed = routedPropIn(config, layers, route);
25
- if (!routed) return "attribute";
24
+ const routed = routeEnd(config, layers, route)?.decl;
25
+ if (!routed) return void 0;
26
26
  const styleProperty = routed.type === "styleProperty" && isRef(routed.value) ? pathOf(routed.value.__ref) : void 0;
27
27
  if (styleProperty !== void 0) return JSON.stringify({
28
28
  type: routed.type,
29
29
  domain: stylePropertyDomain(config, styleProperty)
30
30
  });
31
+ if (routed.type && SCALAR_TYPES.has(routed.type)) return JSON.stringify({ type: routed.type });
31
32
  return JSON.stringify({
32
33
  type: routed.type,
33
34
  value: routed.value
34
35
  });
35
36
  };
36
- const [first, ...rest] = routes;
37
+ const [first, ...rest] = routes.flatMap((route) => {
38
+ const landed = landing(route);
39
+ return landed === void 0 ? [] : [{
40
+ route,
41
+ landed
42
+ }];
43
+ });
37
44
  if (!first) return void 0;
38
- const expected = landing(first);
39
- for (const route of rest) if (landing(route) !== expected) return `${spelled(route)} takes different values than ${spelled(first)}, and a forward writes one value to every route. Route it only to props that take the same values, or declare a second prop.`;
45
+ for (const { route, landed } of rest) if (landed !== first.landed) return `${spelled(route)} takes different values than ${spelled(first.route)}, and a forward writes one value to every route. Route it only to props that take the same values, or declare a second prop.`;
40
46
  }
47
+ const SCALAR_TYPES = new Set([
48
+ "boolean",
49
+ "string",
50
+ "number"
51
+ ]);
41
52
  /**
42
53
  * What a style property takes, as one comparable value: each leaf with the token or literal it names,
43
54
  * and whether it also takes an off-scale literal. Two properties with the same domain accept exactly
@@ -544,4 +544,4 @@ function renderBoundProp(value) {
544
544
  return name.length > 0 && !name.includes("/") ? name : void 0;
545
545
  }
546
546
  //#endregion
547
- export { carriesContent, codeSlotsOf, forwardClaims, forwardRoutes, forwardedLayers, glyphVariantProp, intoName, isValueSlot, layerPropRoutes, ownTextProp, propApplies, propRegistryRef, renderBindingsOf, renderBoundProp, routedProp, routedPropIn, routesContent, routesIntoText, slotCodeForms, standsInForCode, surfaceProp, surfaceProps };
547
+ export { carriesContent, codeSlotsOf, forwardClaims, forwardRoutes, forwardedLayers, glyphVariantProp, intoName, isValueSlot, layerPropRoutes, ownTextProp, propApplies, propRegistryRef, renderBindingsOf, renderBoundProp, routeEnd, routedProp, routedPropIn, routesContent, routesIntoText, slotCodeForms, standsInForCode, surfaceProp, surfaceProps };
@@ -0,0 +1,25 @@
1
+ import * as _$react from "react";
2
+ import { ReactNode } from "react";
3
+ import { ColorValue } from "react-native";
4
+
5
+ //#region src/native/index.d.ts
6
+ /**
7
+ * Publish a container's final, resolved foreground. An absent color or `inherit` passes through
8
+ * the enclosing foreground. Resolve style arrays and interaction callbacks before calling this;
9
+ * the provider does not select tokens, modes or states, or add a native host element.
10
+ */
11
+ declare function NativeForegroundProvider({
12
+ color,
13
+ children
14
+ }: {
15
+ color?: ColorValue | null;
16
+ children?: ReactNode;
17
+ }): _$react.FunctionComponentElement<_$react.ProviderProps<ColorValue | undefined>>;
18
+ /**
19
+ * Resolve only an explicit `inherit`. Defaults, explicit colors and native opaque colors retain
20
+ * their identity. Without a provider, inheritance becomes undefined (never an invalid native
21
+ * `inherit` value). Call this in a component, not inside a Pressable render callback.
22
+ */
23
+ declare function useNativeForeground(color: ColorValue | undefined): ColorValue | undefined;
24
+ //#endregion
25
+ export { NativeForegroundProvider, useNativeForeground };
@@ -0,0 +1,23 @@
1
+ import { createContext, createElement, useContext } from "react";
2
+ //#region src/native/index.ts
3
+ const ForegroundContext = createContext(void 0);
4
+ /**
5
+ * Publish a container's final, resolved foreground. An absent color or `inherit` passes through
6
+ * the enclosing foreground. Resolve style arrays and interaction callbacks before calling this;
7
+ * the provider does not select tokens, modes or states, or add a native host element.
8
+ */
9
+ function NativeForegroundProvider({ color, children }) {
10
+ const parent = useContext(ForegroundContext);
11
+ return createElement(ForegroundContext.Provider, { value: color == null || color === "inherit" ? parent : color }, children);
12
+ }
13
+ /**
14
+ * Resolve only an explicit `inherit`. Defaults, explicit colors and native opaque colors retain
15
+ * their identity. Without a provider, inheritance becomes undefined (never an invalid native
16
+ * `inherit` value). Call this in a component, not inside a Pressable render callback.
17
+ */
18
+ function useNativeForeground(color) {
19
+ const parent = useContext(ForegroundContext);
20
+ return color === "inherit" ? parent : color;
21
+ }
22
+ //#endregion
23
+ export { NativeForegroundProvider, useNativeForeground };