@yahoo/uds-create-cli 5.76.0 → 5.77.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.
@@ -82268,6 +82268,10 @@ function classLeaf(leaf) {
82268
82268
  const spaced = leaf.replace(/\s+/g, "-");
82269
82269
  return /^\d+\/\d+$/.test(spaced) ? spaced : spaced.replaceAll("/", "-");
82270
82270
  }
82271
+ function arbitraryClassName({ config: config2, path: path2, value }) {
82272
+ const inner = value.slice(1, -1).replace(/\s+/g, "_");
82273
+ return `${stylePropClassBase(config2, path2)}-[${inner}]`;
82274
+ }
82271
82275
  function stylePropClasses(config2, path2) {
82272
82276
  const out = /* @__PURE__ */ new Map();
82273
82277
  for (const leaf of stylePropValueLeaves(config2, path2)) if (!out.has(leaf)) out.set(leaf, stylePropClassName(config2, path2, leaf));
@@ -86396,7 +86400,7 @@ var ComponentEntity = defineEntity({
86396
86400
  input: external_exports.object({ path: pathInput("component") }),
86397
86401
  readOnly: false,
86398
86402
  label: "Create blank",
86399
- description: 'Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio\'s "+" creates. Takes only `path`. Use it for "a new component", "a blank component" or "start a component from nothing"; `create` is for a component whose body is already known.',
86403
+ description: 'Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Create\'s "+" creates. Takes only `path`. Use it for "a new component", "a blank component" or "start a component from nothing"; `create` is for a component whose body is already known.',
86400
86404
  scope: "item",
86401
86405
  creates: true,
86402
86406
  title: (entity) => `Create blank ${entity}`,
@@ -86415,7 +86419,7 @@ var ComponentEntity = defineEntity({
86415
86419
  example: ({ config: config2 }) => forwardsCreateExample(config2)
86416
86420
  },
86417
86421
  "sub-upsert/forwards": { description: `Set what one layer forwards, added when absent and replaced whole when present. ${FORWARDS_DESCRIPTION}` },
86418
- "sub-update/forwards": { description: `Replace what one layer forwards: the member is \`'*'\` or a list, so \`data\` is the whole new value. ${FORWARDS_DESCRIPTION}` },
86422
+ "sub-update/forwards": { description: `Replace what one layer forwards: the member is a list of prop names, so \`data\` is the whole new list. ${FORWARDS_DESCRIPTION}` },
86419
86423
  /**
86420
86424
  * Add an element to a composition — a layer and the node that targets it, together.
86421
86425
  *
@@ -86714,7 +86718,7 @@ var ComponentEntity = defineEntity({
86714
86718
  }),
86715
86719
  readOnly: false,
86716
86720
  label: "Forward layer props",
86717
- description: 'Expose a layer\'s props at the component\'s top level ("forward everything from the root but icon", "also forward width"): `props` is `"*"` for every prop the layer\'s element takes, or a list added to what the layer forwards now, or that replaces it with `replace`; `except` leaves props out of either. A prop the element lacks, one the component declares itself, and one a sibling layer already forwards are refused. Read `component/get` for what a layer forwards now.',
86721
+ description: 'Expose a layer\'s props at the component\'s top level ("also forward width", "forward onClick from the root"): `props` is a list of prop names, added to what the layer forwards now, or replacing it with `replace`. A prop the element lacks, one the component declares itself, and one a sibling layer already forwards are refused. Read `component/get` for what a layer forwards now.',
86718
86722
  scope: "item",
86719
86723
  title: (entity) => `Forward ${entity} layer props`,
86720
86724
  handler: (input2, config2) => {
@@ -87667,6 +87671,200 @@ function renderBoundProp(value) {
87667
87671
  return name.length > 0 && !name.includes("/") ? name : void 0;
87668
87672
  }
87669
87673
 
87674
+ // ../config/dist/entities/system/Icon.js
87675
+ var iconVariantAs = external_exports.union([external_exports.strictObject({ prop: external_exports.string().min(1) }), external_exports.strictObject({ export: external_exports.record(external_exports.string().min(1), external_exports.string().min(1)) })]);
87676
+ var Icon = defineEntity({
87677
+ kind: "icon",
87678
+ label: "Icon",
87679
+ labelPlural: "Icons",
87680
+ fields: iconMemberMetadata,
87681
+ groupFields: external_exports.strictObject({
87682
+ /** The package the glyphs come from — a REF to the `Package` item, which owns the module
87683
+ * specifier (its path) and the pinned version. A generated module imports the glyphs it renders
87684
+ * from it, and a render that imports a member of it is placing a glyph of this set. */
87685
+ package: Package.optional().describe("The npm package the set comes from."),
87686
+ /** Where member metadata comes from and how to read it — `{ from, format }`. The build resolves
87687
+ * the source and bakes each member's fields; see `icon-metadata.ts`. */
87688
+ metadata: iconMetadataDeclaration.optional().describe("Catalogue metadata read from the package."),
87689
+ /** Named sizes the set ships (`sm: 16`).
87690
+ * @deprecated How a glyph is sized is the icon tool's component's business: the icon tool's component declares its own `size` and `variant` props, and every surface reads those. TODO: remove with a migration once no surface reads the library's copy. */
87691
+ sizes: external_exports.record(external_exports.string(), external_exports.number()).optional().describe("Deprecated. The icon tool's component declares its own `size` and `variant` props."),
87692
+ /** Weights/styles the set ships (`regular`, `fill`).
87693
+ * @deprecated Which styles a glyph takes is the icon tool's component's business: the icon tool's component declares its own `size` and `variant` props, and every surface reads those. TODO: remove with a migration once no surface reads the library's copy. */
87694
+ variants: external_exports.array(external_exports.string()).optional().describe("Deprecated. The icon tool's component declares its own `size` and `variant` props."),
87695
+ /** How a variant reaches the glyph; see {@link iconVariantAs}. Absent, a variant is dropped at
87696
+ * render.
87697
+ * @deprecated Only the framework's raw-draw path read it; the icon tool's component passes a
87698
+ * variant the way its package wants, and a set whose styles are separate exports lists them as
87699
+ * members. TODO: remove with `sizes` and `variants`. */
87700
+ variantAs: iconVariantAs.optional().describe("Deprecated. The icon tool's component passes a variant the way its package wants.")
87701
+ }),
87702
+ groupComputed: {
87703
+ /** The glyphs the set ships, by leaf name. */
87704
+ members: ({ config: config2, path: path2 }) => config2.members("icon", path2).map((member) => member.path.startsWith(`${path2}/`) ? member.path.slice(path2.length + 1) : member.path),
87705
+ /** The module the glyphs import from: the named package's path. `pathOf` drops a source
87706
+ * qualifier, so a borrowed set's module is still the bare specifier. */
87707
+ module: ({ meta: meta3 }) => isRef2(meta3.package) ? pathOf2(meta3.package) : void 0,
87708
+ /** The version the named package pins, resolved through the ref in whichever config holds the
87709
+ * package row. */
87710
+ version: ({ config: config2, meta: meta3 }) => {
87711
+ if (!isRef2(meta3.package)) return void 0;
87712
+ const pinned = config2.resolveRef(meta3.package)?.toJSON();
87713
+ return typeof pinned?.version === "string" ? pinned.version : void 0;
87714
+ }
87715
+ },
87716
+ groupInputs: {
87717
+ /**
87718
+ * The package's module namespace. The set's members are its glyph exports, named by the rule
87719
+ * the metadata format declares (`glyphExportRule`), so an alias pair is one member and the
87720
+ * package's infrastructure exports are none; `items` lays facts over members that exist, and a
87721
+ * key naming no member is refused so a typo cannot invent a glyph. Each member's identity is
87722
+ * recorded by reference, so an authored glyph (`name={StarIcon}`) is matched to its member by
87723
+ * the object rather than by anything the component says about itself, and an alias resolves to
87724
+ * the member it is. Read once while the config file is evaluated and never stored.
87725
+ */
87726
+ glyphs: ({ input: input2, body }) => {
87727
+ if (!isRef2(body.package)) throw new Error("Icon.group: `glyphs` needs `package` on the same group, since a glyph is identified as an export of that module.");
87728
+ const format = iconMetadataFormat.safeParse(body.metadata?.format);
87729
+ const members2 = glyphMembersOf({
87730
+ namespace: input2,
87731
+ format: format.success ? format.data : void 0
87732
+ });
87733
+ const overlay = body.items ?? {};
87734
+ const unknown2 = Object.keys(overlay).filter((name) => !members2.includes(name));
87735
+ if (unknown2.length > 0) throw new Error(`Icon.group: \`items\` names ${spellValues(unknown2)}, which ${unknown2.length === 1 ? "is not a glyph export" : "are not glyph exports"} of \`glyphs\`${members2.length === 0 ? " (the namespace has no glyph components; the package may not be installed)" : ""}. \`items\` lays facts over the members the package exports; it cannot add one.`);
87736
+ recordGlyphIdentities({
87737
+ namespace: input2,
87738
+ names: members2,
87739
+ specifier: pathOf2(body.package)
87740
+ });
87741
+ return { items: Object.fromEntries(members2.map((name) => [name, overlay[name] ?? {}])) };
87742
+ }
87743
+ },
87744
+ /**
87745
+ * A value bound to a library may be the glyph component itself, or the `package:` export ref the
87746
+ * open-bag pass turned it into. Either is answered as the member name when the export is one of
87747
+ * this library's and comes from the module its `package` names.
87748
+ */
87749
+ authoredValue: ({ config: config2, target: target2, leaves: leaves2 }) => glyphOfLibrary(libraryGlyphFacts({
87750
+ config: config2,
87751
+ target: target2,
87752
+ leaves: leaves2
87753
+ })),
87754
+ invariants: (config2) => iconDomainInvariants(config2)
87755
+ });
87756
+
87757
+ // ../config/dist/entities/system/icon-library.js
87758
+ var EMPTY_CATEGORIES = Object.freeze([]);
87759
+ var EMPTY_SIZES = Object.freeze({});
87760
+ var EMPTY_VARIANTS = Object.freeze([]);
87761
+ var NO_LIBRARIES = [];
87762
+ function iconLibrary(config2, path2) {
87763
+ if (!config2) return void 0;
87764
+ const cache = librariesOf(config2);
87765
+ if (cache.has(path2)) return cache.get(path2);
87766
+ const library = readIconLibrary(config2, path2);
87767
+ cache.set(path2, library);
87768
+ return library;
87769
+ }
87770
+ var librariesOf = createSliceMemo({
87771
+ kinds: [
87772
+ "icon",
87773
+ "component",
87774
+ "package"
87775
+ ],
87776
+ compute: (_config) => /* @__PURE__ */ new Map()
87777
+ });
87778
+ function readIconLibrary(config2, path2) {
87779
+ const group = Icon.groups(config2).find((entry) => entry.path === path2);
87780
+ if (!group) return void 0;
87781
+ const { items: _items, sizes, variants: variants2, ...meta3 } = group.meta;
87782
+ const set2 = setMembers({
87783
+ config: config2,
87784
+ path: path2,
87785
+ declared: variants2
87786
+ });
87787
+ return {
87788
+ ...meta3,
87789
+ path: path2,
87790
+ members: set2.members,
87791
+ sizes: sizes ?? EMPTY_SIZES,
87792
+ variants: variants2 ?? EMPTY_VARIANTS,
87793
+ ...set2.memberVariants ? { memberVariants: set2.memberVariants } : {},
87794
+ ...componentDefaults({
87795
+ config: config2,
87796
+ library: path2
87797
+ })
87798
+ };
87799
+ }
87800
+ function componentDefaults({ config: config2, library }) {
87801
+ const bound = glyphComponentOf(config2, library);
87802
+ if (!bound) return {};
87803
+ const defaults = Component.get(config2, bound.path)?.defaultProps;
87804
+ const variant = defaults?.variant;
87805
+ const size = defaults?.size;
87806
+ return {
87807
+ ...typeof variant === "string" ? { defaultVariant: variant } : {},
87808
+ ...typeof size === "string" ? { defaultSizeKey: size } : {}
87809
+ };
87810
+ }
87811
+ var membersOf = createSliceMemo({
87812
+ kinds: ["icon"],
87813
+ compute: (_config) => /* @__PURE__ */ new Map()
87814
+ });
87815
+ function setMembers({ config: config2, path: path2, declared: declared2 }) {
87816
+ const walked = membersOf(config2);
87817
+ const hit = walked.get(path2);
87818
+ if (hit) return hit;
87819
+ const members2 = [];
87820
+ const memberVariants = {};
87821
+ for (const member of config2.members("icon", path2)) {
87822
+ const leaf = member.path.startsWith(`${path2}/`) ? member.path.slice(path2.length + 1) : member.path;
87823
+ members2.push(leaf);
87824
+ const own2 = ownVariantsOf(member.body);
87825
+ if (own2 && own2.length > 0 && !sameVariants({
87826
+ own: own2,
87827
+ declared: declared2
87828
+ })) memberVariants[leaf] = own2;
87829
+ }
87830
+ const set2 = {
87831
+ members: members2,
87832
+ ...Object.keys(memberVariants).length > 0 ? { memberVariants } : {}
87833
+ };
87834
+ walked.set(path2, set2);
87835
+ return set2;
87836
+ }
87837
+ function ownVariantsOf(body) {
87838
+ const declared2 = body.variants;
87839
+ if (!Array.isArray(declared2)) return void 0;
87840
+ return declared2.filter((variant) => typeof variant === "string");
87841
+ }
87842
+ function sameVariants({ own: own2, declared: declared2 }) {
87843
+ if (!declared2 || declared2.length !== own2.length) return false;
87844
+ const set2 = new Set(declared2);
87845
+ return own2.every((variant) => set2.has(variant));
87846
+ }
87847
+ function iconLibraries(config2) {
87848
+ if (!config2) return NO_LIBRARIES;
87849
+ return allLibrariesOf(config2);
87850
+ }
87851
+ var allLibrariesOf = createSliceMemo({
87852
+ kinds: [
87853
+ "icon",
87854
+ "component",
87855
+ "package"
87856
+ ],
87857
+ compute: (config2) => Icon.groups(config2).map(({ path: path2 }) => iconLibrary(config2, path2)).filter((library) => library !== void 0)
87858
+ });
87859
+ var boundLibrariesOf = createSliceMemo({
87860
+ kinds: [
87861
+ "component",
87862
+ "icon",
87863
+ "package"
87864
+ ],
87865
+ compute: (_config) => /* @__PURE__ */ new Map()
87866
+ });
87867
+
87670
87868
  // ../config/dist/capture/captured-tree.js
87671
87869
  var CapturedNode = external_exports.lazy(() => external_exports.object({
87672
87870
  tag: external_exports.string().min(1),
@@ -87829,15 +88027,53 @@ function compound(selector3) {
87829
88027
 
87830
88028
  // ../config/dist/capture/class-grammar.js
87831
88029
  var VIEWPORT_UNIT = /\d(vh|vw|dvh|dvw|svh|svw|lvh|lvw|vmin|vmax)\b/;
88030
+ var COLOR_PROPERTY = /(^|-)(color|fill|stroke)$|^background$/;
88031
+ function isColorValue(value) {
88032
+ const v = value.trim().toLowerCase();
88033
+ if (/^(#|rgba?\(|hsla?\(|oklch\(|oklab\(|lab\(|lch\(|color\(|color-mix\()/.test(v)) return true;
88034
+ if (/^(color|colour):/.test(v)) return true;
88035
+ if (/^[-\d.]/.test(v) || /^(calc|min|max|clamp|var)\(/.test(v)) return false;
88036
+ return /^[a-z]+$/.test(v) && v !== "auto" && v !== "none";
88037
+ }
87832
88038
  function normalizeCssValue(value) {
87833
88039
  return value.trim().replace(/\s+/g, " ").replace(/(^|[\s,(])0(?:px|rem|em|%)(?=$|[\s,)])/g, "$10").toLowerCase();
87834
88040
  }
87835
88041
  function classGrammar(config2) {
87836
88042
  const styleProps = /* @__PURE__ */ new Map();
87837
- for (const entity of config2.list("style-property")) for (const [leaf, cls] of stylePropClasses(config2, entity.path)) if (!styleProps.has(cls)) styleProps.set(cls, {
87838
- path: entity.path,
87839
- leaf
87840
- });
88043
+ const arbitraryStems = /* @__PURE__ */ new Map();
88044
+ for (const entity of config2.list("style-property")) {
88045
+ for (const [leaf, cls] of stylePropClasses(config2, entity.path)) if (!styleProps.has(cls)) styleProps.set(cls, {
88046
+ path: entity.path,
88047
+ leaf
88048
+ });
88049
+ if (entity.toJSON().arbitrary) {
88050
+ const stem = arbitraryClassName({
88051
+ config: config2,
88052
+ path: entity.path,
88053
+ value: "[x]"
88054
+ }).slice(0, -3);
88055
+ arbitraryStems.set(stem, [...arbitraryStems.get(stem) ?? [], entity.path]);
88056
+ }
88057
+ }
88058
+ const arbitraryMatch = (cls) => {
88059
+ const open2 = cls.indexOf("[");
88060
+ if (open2 <= 0) return void 0;
88061
+ const close = cls.indexOf("]", open2);
88062
+ if (close === -1) return void 0;
88063
+ const rest = cls.slice(close + 1);
88064
+ if (rest !== "" && !/^\/(?:\[[^\]]+\]|[\w.-]+)$/.test(rest)) return void 0;
88065
+ const paths = arbitraryStems.get(cls.slice(0, open2)) ?? [];
88066
+ const inner = cls.slice(open2 + 1, close);
88067
+ if (!inner || paths.length === 0) return void 0;
88068
+ return {
88069
+ path: paths.length === 1 ? paths[0] : paths.find((each) => writesColor(each) === isColorValue(inner)) ?? paths[0],
88070
+ leaf: `[${inner}]`
88071
+ };
88072
+ };
88073
+ function writesColor(path2) {
88074
+ const { properties = [] } = config2.resolve("style-property", path2)?.toJSON() ?? {};
88075
+ return properties.some((property) => COLOR_PROPERTY.test(property));
88076
+ }
87841
88077
  const composites = config2.list("composite").map((entity) => ({
87842
88078
  path: entity.path,
87843
88079
  cls: className(config2, "composite", entity.path)
@@ -87950,7 +88186,7 @@ function classGrammar(config2) {
87950
88186
  };
87951
88187
  };
87952
88188
  return {
87953
- styleProp: (cls) => styleProps.get(cls),
88189
+ styleProp: (cls) => styleProps.get(cls) ?? arbitraryMatch(cls),
87954
88190
  stylePropsFor: (cssProperty2) => byCss.get(cssProperty2.toLowerCase()) ?? [],
87955
88191
  viewportLeaf(path2, leaf) {
87956
88192
  return (valuesOf(path2).get(leaf) ?? []).some((v) => VIEWPORT_UNIT.test(v));
@@ -88063,6 +88299,8 @@ function specFromCapture(options) {
88063
88299
  };
88064
88300
  }
88065
88301
  var FOLD = "data-uds-fold";
88302
+ var EMBED_SPACE_ATTR = "data-uds-embed";
88303
+ var COMPUTED_STYLE_ATTR = "data-uds-computed";
88066
88304
  var ORPHAN_LAYER = "data-uds-orphan-layer";
88067
88305
  function markOrphanLayers(tree) {
88068
88306
  const visit2 = (node2, open2) => {
@@ -88118,10 +88356,38 @@ var Converter = class {
88118
88356
  counter = 0;
88119
88357
  childCap;
88120
88358
  ruled = /* @__PURE__ */ new Map();
88359
+ /** Each component that draws a glyph by name → the prop that names it. */
88360
+ glyphDrawers;
88361
+ /** Each breakpoint's class prefix (`lg`) → whether it applied at the capture's width, and its rank. */
88362
+ breakpoints;
88363
+ /** Each modifier's class prefix (`md`) → the prop key its bag is written under (`_md`). */
88364
+ modifierKeys;
88121
88365
  constructor(options, grammar) {
88122
88366
  this.options = options;
88123
88367
  this.grammar = grammar;
88124
88368
  this.childCap = options.childCap ?? DEFAULT_CHILD_CAP;
88369
+ const drawers = /* @__PURE__ */ new Map();
88370
+ for (const library of iconLibraries(options.config)) {
88371
+ const drawer = glyphComponentOf(options.config, library.path);
88372
+ if (drawer) drawers.set(drawer.path, drawer.prop);
88373
+ }
88374
+ this.glyphDrawers = drawers;
88375
+ const width = options.width ?? DEFAULT_CAPTURE_WIDTH;
88376
+ const breakpoints = /* @__PURE__ */ new Map();
88377
+ for (const modifier of options.config.list("modifier")) {
88378
+ const { type, value } = modifier.toJSON();
88379
+ if (type !== "media-query" || typeof value !== "string") continue;
88380
+ const min2 = /min-width:\s*(\d+(?:\.\d+)?)px/.exec(value);
88381
+ const max2 = /max-width:\s*(\d+(?:\.\d+)?)px/.exec(value);
88382
+ if (!min2 && !max2) continue;
88383
+ const active = (!min2 || width >= Number(min2[1])) && (!max2 || width <= Number(max2[1]));
88384
+ breakpoints.set(modifier.leaf, {
88385
+ active,
88386
+ rank: min2 ? Number(min2[1]) : 0
88387
+ });
88388
+ }
88389
+ this.breakpoints = breakpoints;
88390
+ this.modifierKeys = new Map(options.config.list("modifier").map((modifier) => [modifier.leaf, `_${modifier.leaf}`]));
88125
88391
  }
88126
88392
  convertTop(el) {
88127
88393
  return this.convert(el);
@@ -88135,15 +88401,25 @@ var Converter = class {
88135
88401
  }
88136
88402
  return out;
88137
88403
  }
88138
- /** The components under `layer`, skipping every other layer `path` marks inside it. */
88139
- convertOutsideLayers(layer, path2) {
88404
+ /**
88405
+ * The components under `layer`, skipping every other layer `path` marks inside it. With
88406
+ * `callerMarkup`, the layer is one a slot of elements lands on, so the unmarked markup in it is
88407
+ * the caller's, kept as the plain tags it is, rather than the render's own.
88408
+ */
88409
+ convertOutsideLayers(layer, path2, callerMarkup = false) {
88140
88410
  const out = [];
88411
+ const mixed = callerMarkup && Array.from(layer.childNodes).some((node2) => isElement(node2) && visible(node2));
88141
88412
  for (let i = 0; i < layer.childNodes.length; i += 1) {
88142
88413
  if (this.childCap > 0 && out.length >= this.childCap) break;
88143
88414
  const node2 = layer.childNodes[i];
88144
- if (!isElement(node2)) continue;
88415
+ if (!isElement(node2)) {
88416
+ const text = (node2.textContent ?? "").replace(/\s+/g, " ");
88417
+ if (mixed && text.trim()) out.push(...this.plainTextRun(text, layer));
88418
+ continue;
88419
+ }
88145
88420
  if (node2.getAttribute("data-uds-component") === path2 && node2.getAttribute("data-uds-layer") !== "root") continue;
88146
88421
  if (node2.tagName.toLowerCase() === "svg" || isImage(node2) || node2.hasAttribute("data-uds-component") && node2.getAttribute("data-uds-layer") === "root") out.push(...this.convert(node2));
88422
+ else if (visible(node2) && callerMarkup) out.push(...this.plain(node2));
88147
88423
  else if (visible(node2) && framesItself(node2)) out.push(...this.frame(node2));
88148
88424
  else if (visible(node2)) out.push(...this.pinFolded(node2, this.convertOutsideLayers(node2, path2)));
88149
88425
  }
@@ -88157,64 +88433,432 @@ var Converter = class {
88157
88433
  return key2 ? [key2] : [];
88158
88434
  }
88159
88435
  if (el.tagName.toLowerCase() === "svg") return this.icon(el);
88160
- if (isImage(el)) return this.image(el);
88161
- if (isField(el)) return this.field(el);
88162
- if (framesItself(el)) return this.frame(el);
88163
- return this.pinFolded(el, this.convertChildren(el));
88436
+ if (el.hasAttribute(ORPHAN_LAYER)) return this.frame(el);
88437
+ return this.plain(el);
88164
88438
  }
88165
88439
  /**
88166
- * The content of an unmarked wrapper the capture folded, with the wrapper's measured box written
88167
- * onto it when it is one element: the wrapper's sizing (a flex share, a fixed size) no longer reaches
88168
- * the child, so the child keeps the box it had.
88440
+ * What an element inside a component holds, by the rule for a component's render: a nested
88441
+ * component is itself, and an unmarked element folds into what it holds, or is a frame when it
88442
+ * places itself, since it may be the render's own markup rather than the page's.
88169
88443
  */
88170
- pinFolded(el, keys) {
88171
- const size = el.getAttribute(FOLD)?.match(/^(\d+(?:\.\d+)?)x(\d+(?:\.\d+)?)$/);
88172
- if (!size || keys.length !== 1 || el.hasAttribute("data-uds-component")) return keys;
88173
- const element2 = this.elements[keys[0]];
88174
- const grammar = this.grammar.component(element2.type.replace(/^component:/, ""));
88175
- if (grammar) this.propsFromDeclarations([["width", `${size[1]}px`], ["height", `${size[2]}px`]], grammar, element2.props);
88176
- return keys;
88444
+ convertInside(el) {
88445
+ const out = [];
88446
+ for (let i = 0; i < el.childNodes.length; i += 1) {
88447
+ if (this.childCap > 0 && out.length >= this.childCap) break;
88448
+ const node2 = el.childNodes[i];
88449
+ if (!isElement(node2) || !visible(node2)) continue;
88450
+ if (node2.tagName.toLowerCase() === "svg" || node2.hasAttribute("data-uds-component") && node2.getAttribute("data-uds-layer") === "root") out.push(...this.convert(node2));
88451
+ else if (isImage(node2)) out.push(...this.image(node2));
88452
+ else if (isField(node2)) out.push(...this.field(node2));
88453
+ else if (framesItself(node2)) out.push(...this.frame(node2));
88454
+ else out.push(...this.pinFolded(node2, this.convertInside(node2)));
88455
+ }
88456
+ return out;
88177
88457
  }
88178
88458
  /**
88179
- * An unmarked element with an inline style, which is what the page drew it with, as the canvas's
88180
- * frame component carrying that style. One with nothing inline only groups its children and is
88181
- * folded away, and an empty one that paints nothing of its own (a portal's container) places
88182
- * nothing.
88459
+ * An unmarked element as the plain tag it is: an `img` keeps its source, a link its `href`, a field
88460
+ * its type and placeholder, and its text stays inside it. Its styling is stored as classes, the way
88461
+ * the canvas paints and the design panel edits a plain element: the classes it wears that the system
88462
+ * names, then its own inline style and the styles its stylesheets gave it written as the system's
88463
+ * classes (`16px` of gap is `gap-4`, an off-scale `13px` is `gap-[13px]`). What no style prop can
88464
+ * hold stays as an inline style. A `div` or `span` that carries nothing only groups its children and
88465
+ * folds away, as a wrapper the capture marked foldable does.
88183
88466
  */
88184
- frame(el) {
88185
- const children = this.convertChildren(el);
88186
- if (children.length === 0 && !paintsItself(el)) return [];
88187
- const role = canvasRole(this.options.config, "frame");
88188
- const grammar = role ? this.grammar.component(role.component) : void 0;
88189
- if (!role || !grammar) return children;
88190
- const props = this.orphanLayerProps(el, grammar);
88191
- this.propsFromInlineStyle(el, grammar, props);
88192
- if (Object.keys(props).length === 0) return children;
88193
- const key2 = this.key(role.component);
88467
+ plain(el, convertKids = () => this.plainChildren(el)) {
88468
+ const tag = el.tagName.toLowerCase();
88469
+ if (FORBIDDEN_TAGS.has(tag)) return [];
88470
+ if (el.hasAttribute(FOLD)) return this.pinFolded(el, convertKids());
88471
+ if ([...inlineDeclarations(el), ...declarationsOf(el.getAttribute("data-uds-computed") ?? "")].find(([property]) => property === "display")?.[1].trim() === "contents") return convertKids();
88472
+ const { className: className2, style, paints } = this.plainStyle(el);
88473
+ const attrs = plainAttributes(el);
88474
+ if (tag === "img" && !attrs.src) return [];
88475
+ const children = VOID_TAGS.has(tag) ? [] : convertKids();
88476
+ const text = children.length === 0 ? plainText(el) : "";
88477
+ if (children.length === 0 && !text && !VOID_TAGS.has(tag) && !paints && !el.hasAttribute(EMBED_SPACE_ATTR)) return [];
88478
+ if (!(className2 !== "" || Object.keys(style).length > 0 || Object.keys(attrs).length > 0) && GROUPING_TAGS.has(tag)) {
88479
+ if (text) return this.plainTextRun(text);
88480
+ return children;
88481
+ }
88482
+ const props = { ...attrs };
88483
+ if (className2) props.className = className2;
88484
+ if (Object.keys(style).length > 0) props.style = style;
88485
+ if (text) props.children = text;
88486
+ const key2 = this.key(tag);
88194
88487
  this.elements[key2] = {
88195
- type: `component:${role.component}`,
88488
+ type: tag,
88196
88489
  props,
88197
88490
  ...children.length > 0 ? { children } : {}
88198
88491
  };
88199
88492
  return [key2];
88200
88493
  }
88201
88494
  /**
88202
- * The styles the config gives an orphaned layer, as the frame's props: the rules that always apply
88203
- * and the ones its classes say are on, in authored order. Only values the frame component declares,
88204
- * spelled as an author writes them, are kept.
88495
+ * An inline SVG as itself: the `svg` and every shape in it, each with its attributes under the
88496
+ * names React takes them by. Definitions it references (a clip path, a gradient) are left out with
88497
+ * the references to them, since an id the capture copied may name nothing on the canvas.
88205
88498
  */
88206
- orphanLayerProps(el, frame2) {
88207
- const [path2, layer] = (el.getAttribute(ORPHAN_LAYER) ?? "").split("#");
88208
- if (!path2 || !layer) return {};
88209
- const active = {};
88210
- const own2 = this.grammar.component(path2);
88211
- for (const cls of classesOf(el)) Object.assign(active, own2?.conditions.get(cls));
88212
- const props = {};
88213
- const styles = Component.get(this.options.config, path2)?.styles ?? {};
88214
- for (const rule of Object.values(styles)) {
88215
- const when = rule?.when ?? {};
88216
- if (!Object.entries(when).every(([key2, value]) => active[key2] === value)) continue;
88217
- for (const [key2, value] of Object.entries(rule.layers?.[layer] ?? {})) {
88499
+ plainSvg(svg) {
88500
+ if (holdsMoreThan(svg, SVG_SHAPE_LIMIT)) {
88501
+ const covered = /* @__PURE__ */ new Set();
88502
+ const size = (attr) => {
88503
+ const value = svg.getAttribute(attr);
88504
+ return value && /^\d+(?:\.\d+)?$/.test(value) ? this.classForDeclaration(attr, `${value}px`, covered) : void 0;
88505
+ };
88506
+ const className2 = [size("width"), size("height")].filter((cls) => !!cls && cls !== "covered").join(" ");
88507
+ const key2 = this.key("div");
88508
+ this.elements[key2] = {
88509
+ type: "div",
88510
+ props: className2 ? { className: className2 } : {}
88511
+ };
88512
+ return key2;
88513
+ }
88514
+ const build2 = (el) => {
88515
+ const tag = el.tagName.toLowerCase();
88516
+ const props = { [VERBATIM_ATTRIBUTES]: true };
88517
+ const styled = [];
88518
+ for (const { name, value } of el.attributes) {
88519
+ if (SVG_SKIPPED_ATTRIBUTES.test(name)) continue;
88520
+ if (name === "class" || name === "style") continue;
88521
+ if (name === "width" || name === "height") continue;
88522
+ const prop = svgAttributeName(name);
88523
+ if (this.options.config.resolve("style-property", prop)) {
88524
+ styled.push([name, value]);
88525
+ continue;
88526
+ }
88527
+ props[prop] = value;
88528
+ }
88529
+ const { className: className2, style } = this.plainStyle(el, styled);
88530
+ if (className2) props.className = className2;
88531
+ if (Object.keys(style).length > 0) props.style = style;
88532
+ const children = [];
88533
+ let text = "";
88534
+ for (const node2 of el.childNodes) {
88535
+ if (!isElement(node2)) {
88536
+ text += node2.textContent ?? "";
88537
+ continue;
88538
+ }
88539
+ if (SVG_SKIPPED_TAGS.has(node2.tagName.toLowerCase())) continue;
88540
+ children.push(build2(node2));
88541
+ }
88542
+ if (children.length === 0 && text.trim()) props.children = text.trim();
88543
+ const key2 = this.key(SVG_TAGS.get(tag) ?? tag);
88544
+ this.elements[key2] = {
88545
+ type: SVG_TAGS.get(tag) ?? tag,
88546
+ props,
88547
+ ...children.length > 0 ? { children } : {}
88548
+ };
88549
+ return key2;
88550
+ };
88551
+ return build2(svg);
88552
+ }
88553
+ /** A plain element's content: its elements, and each run of text between them as a `span`. */
88554
+ plainChildren(el) {
88555
+ if (!Array.from(el.childNodes).some((node2) => isElement(node2) && visible(node2))) return [];
88556
+ const out = [];
88557
+ for (let i = 0; i < el.childNodes.length; i += 1) {
88558
+ if (this.childCap > 0 && out.length >= this.childCap) break;
88559
+ const node2 = el.childNodes[i];
88560
+ if (isElement(node2)) {
88561
+ out.push(...this.convert(node2));
88562
+ continue;
88563
+ }
88564
+ const text = (node2.textContent ?? "").replace(/\s+/g, " ");
88565
+ if (text.trim()) out.push(...this.plainTextRun(text));
88566
+ }
88567
+ return out;
88568
+ }
88569
+ /**
88570
+ * A run of text as a `span`. It keeps how its holder wraps (`white-space: nowrap` on a nav item),
88571
+ * which the holder, a component that takes no such prop, may have no way to say itself.
88572
+ */
88573
+ plainTextRun(text, holder) {
88574
+ const props = { children: text };
88575
+ const wraps = declarationsOf(holder?.getAttribute("data-uds-computed") ?? "").find(([property]) => property === "white-space");
88576
+ if (wraps) {
88577
+ const cls = this.classForDeclaration("white-space", normalizeCssValue(wraps[1]), /* @__PURE__ */ new Set());
88578
+ if (cls && cls !== "covered") props.className = cls;
88579
+ else props.style = { whiteSpace: wraps[1] };
88580
+ }
88581
+ const key2 = this.key("span");
88582
+ this.elements[key2] = {
88583
+ type: "span",
88584
+ props
88585
+ };
88586
+ return [key2];
88587
+ }
88588
+ /**
88589
+ * A plain element's styling as the system's classes, and what none can hold as inline style. The
88590
+ * page's own inline style painted over its classes, so it is read first and a class for a property it
88591
+ * sets is dropped; the computed styles fill only what neither says.
88592
+ */
88593
+ plainStyle(el, attributes = []) {
88594
+ const classes = [];
88595
+ const style = {};
88596
+ const covered = /* @__PURE__ */ new Set();
88597
+ let paints = false;
88598
+ const notePaint = (property) => {
88599
+ if (PAINT_PROPERTY.test(property)) paints = true;
88600
+ };
88601
+ const written = /* @__PURE__ */ new Set();
88602
+ const fromDeclarations = (declarations) => {
88603
+ for (const [property, raw] of declarations.flatMap(gridAreaLines)) {
88604
+ if (written.has(property) || written.has(LOGICAL_SIDES[property] ?? property)) continue;
88605
+ let value = normalizeCssValue(raw);
88606
+ const paintNone = value === "none" && (property === "fill" || property === "stroke");
88607
+ if (!value || SKIP_INLINE_PROPERTY.has(property) || SKIP_INLINE_VALUE.has(value) && !paintNone) continue;
88608
+ if (property === "position" && value === "fixed") value = "absolute";
88609
+ if (VIEWPORT_VALUE.test(value) && !WHOLE_VIEWPORT.test(value)) value = frameUnits(value, this.options.width, this.options.height);
88610
+ const cls = this.classForDeclaration(property, value, covered);
88611
+ if (cls === "covered") continue;
88612
+ notePaint(property);
88613
+ if (cls) {
88614
+ classes.push(cls);
88615
+ continue;
88616
+ }
88617
+ let placed = false;
88618
+ for (const [longhand, part] of gridLonghands({
88619
+ property,
88620
+ value
88621
+ })) {
88622
+ const longClass = this.classForDeclaration(longhand, part, covered);
88623
+ if (longClass && longClass !== "covered") classes.push(longClass);
88624
+ placed = placed || longClass !== void 0;
88625
+ }
88626
+ if (!placed && !(camelCase3(property) in style)) style[camelCase3(property)] = raw.trim();
88627
+ }
88628
+ };
88629
+ fromDeclarations(inlineDeclarations(el));
88630
+ fromDeclarations(attributes);
88631
+ fromDeclarations(["width", "height"].flatMap((attr) => {
88632
+ const value = el.getAttribute(attr);
88633
+ return value && /^\d+(?:\.\d+)?$/.test(value) ? [[attr, `${value}px`]] : [];
88634
+ }));
88635
+ const read = classesOf(el).flatMap((cls) => {
88636
+ const each = this.readModifiedClass(cls);
88637
+ if (!each) return [];
88638
+ if (each.modifiers.length === 0 && covered.has(each.style.path)) return [];
88639
+ const { properties = [] } = this.options.config.resolve("style-property", each.style.path)?.toJSON() ?? {};
88640
+ const atoms = atomsOf(properties);
88641
+ if (atoms.size === 0) atoms.add(`prop:${each.style.path}`);
88642
+ return [{
88643
+ ...each,
88644
+ properties,
88645
+ atoms
88646
+ }];
88647
+ });
88648
+ const winners = /* @__PURE__ */ new Map();
88649
+ for (const each of read) for (const atom of each.atoms) {
88650
+ const slot = `${each.modifiers.join(".")}|${atom}`;
88651
+ const prior = winners.get(slot);
88652
+ if (!prior || each.rank > prior.rank || each.rank === prior.rank && each.atoms.size < prior.atoms.size) winners.set(slot, each);
88653
+ }
88654
+ const painted = new Set(winners.values());
88655
+ for (const each of read) {
88656
+ if (!painted.has(each)) continue;
88657
+ if (each.modifiers.length === 0) covered.add(each.style.path);
88658
+ for (const property of each.properties) {
88659
+ notePaint(property);
88660
+ if (each.modifiers.length === 0) for (const longhand of longhandsOf(property)) written.add(longhand);
88661
+ }
88662
+ const owned = [...each.atoms].filter((atom) => winners.get(`${each.modifiers.join(".")}|${atom}`) === each);
88663
+ classes.push(...owned.length < each.atoms.size ? this.narrowed(each, new Set(owned)) : [each.bare]);
88664
+ }
88665
+ fromDeclarations(declarationsOf(el.getAttribute("data-uds-computed") ?? ""));
88666
+ return {
88667
+ className: [...new Set(classes)].join(" "),
88668
+ style,
88669
+ paints
88670
+ };
88671
+ }
88672
+ /**
88673
+ * The system's class for one declaration: the class of the leaf whose value it is, or the bracket
88674
+ * class of an off-scale value on a prop that takes one. `covered` when a prop for the property is
88675
+ * already set, so the first source to set it wins; nothing when no prop writes the property.
88676
+ */
88677
+ classForDeclaration(property, value, covered) {
88678
+ const logical = LOGICAL_SIDES[property];
88679
+ const options = [...this.grammar.stylePropsFor(property), ...logical ? this.grammar.stylePropsFor(logical) : []];
88680
+ for (const option of options) {
88681
+ if (covered.has(option.path)) return "covered";
88682
+ const css = option.negates ? negated(value) : value;
88683
+ if (css === void 0) continue;
88684
+ const leaf = equivalents({
88685
+ property,
88686
+ value: css
88687
+ }).map((spelling) => option.leafFor(spelling)).find((found) => found !== void 0);
88688
+ let cls;
88689
+ if (WHOLE_VIEWPORT.test(css) && option.fullLeaf !== void 0) cls = stylePropClassName(this.options.config, option.path, option.fullLeaf);
88690
+ else if (leaf !== void 0) cls = stylePropClassName(this.options.config, option.path, leaf);
88691
+ else if (option.arbitrary) cls = arbitraryClassName({
88692
+ config: this.options.config,
88693
+ path: option.path,
88694
+ value: `[${css.replaceAll(" ", "_")}]`
88695
+ });
88696
+ if (cls === void 0) continue;
88697
+ covered.add(option.path);
88698
+ return cls;
88699
+ }
88700
+ }
88701
+ /**
88702
+ * The content of an unmarked wrapper the capture folded, with the wrapper's measured box written
88703
+ * onto it when it is one element: the wrapper's sizing (a flex share, a fixed size) no longer reaches
88704
+ * the child, so the child keeps the box it had.
88705
+ */
88706
+ pinFolded(el, keys) {
88707
+ const size = el.getAttribute(FOLD)?.match(/^(\d+(?:\.\d+)?)x(\d+(?:\.\d+)?)$/);
88708
+ if (!size || keys.length !== 1 || el.hasAttribute("data-uds-component")) return keys;
88709
+ const element2 = this.elements[keys[0]];
88710
+ if (kindOf2(element2.type) !== "component") {
88711
+ const covered = /* @__PURE__ */ new Set();
88712
+ const sized = [this.classForDeclaration("width", `${size[1]}px`, covered), this.classForDeclaration("height", `${size[2]}px`, covered)].filter((cls) => !!cls && cls !== "covered");
88713
+ const own2 = String(element2.props.className ?? "").split(/\s+/).filter((cls) => {
88714
+ const read = cls ? this.readModifiedClass(cls) : void 0;
88715
+ if (!read || read.modifiers.length > 0) return Boolean(cls);
88716
+ const atoms = this.styleAtoms().get(read.style.path);
88717
+ return !(atoms?.has("width") || atoms?.has("height"));
88718
+ });
88719
+ element2.props.className = [...own2, ...sized].join(" ");
88720
+ return keys;
88721
+ }
88722
+ const grammar = this.grammar.component(element2.type.replace(/^component:/, ""));
88723
+ if (grammar) this.propsFromDeclarations([["width", `${size[1]}px`], ["height", `${size[2]}px`]], grammar, element2.props);
88724
+ return keys;
88725
+ }
88726
+ /**
88727
+ * An unmarked element with an inline style, which is what the page drew it with, as the canvas's
88728
+ * frame component carrying that style. One with nothing inline only groups its children and is
88729
+ * folded away, and an empty one that paints nothing of its own (a portal's container) places
88730
+ * nothing.
88731
+ */
88732
+ frame(el) {
88733
+ const children = this.convertInside(el);
88734
+ if (children.length === 0 && !paintsItself(el)) return [];
88735
+ const role = canvasRole(this.options.config, "frame");
88736
+ const grammar = role ? this.grammar.component(role.component) : void 0;
88737
+ if (!role || !grammar) return children;
88738
+ const props = this.orphanLayerProps(el, grammar);
88739
+ this.propsFromInlineStyle(el, grammar, props);
88740
+ if (Object.keys(props).length === 0) return children;
88741
+ const key2 = this.key(role.component);
88742
+ this.elements[key2] = {
88743
+ type: `component:${role.component}`,
88744
+ props,
88745
+ ...children.length > 0 ? { children } : {}
88746
+ };
88747
+ return [key2];
88748
+ }
88749
+ /**
88750
+ * The style props `classes` spell for a component with `grammar`, each class under a modifier
88751
+ * prefix written into that modifier's bag (`md:hover:flex` → `_md._hover.display`). A class whose
88752
+ * prefix names no modifier the config has, or whose prop the component does not take, is not read.
88753
+ * A value already set is kept: the first class for a prop wins, as a stamped value does.
88754
+ */
88755
+ stylePropsFromClasses(classes, grammar, props) {
88756
+ const ranks = /* @__PURE__ */ new Map();
88757
+ for (const cls of classes) {
88758
+ const read = this.readModifiedClass(cls);
88759
+ if (!read) continue;
88760
+ const prop = grammar.propForStyleProperty.get(read.style.path);
88761
+ if (!prop) continue;
88762
+ const slot = `${read.modifiers.join(".")}|${prop}`;
88763
+ const before5 = ranks.get(slot);
88764
+ if (before5 !== void 0 && before5 >= read.rank) continue;
88765
+ ranks.set(slot, read.rank);
88766
+ let bag = props;
88767
+ for (const key2 of read.modifiers) {
88768
+ const inner = bag[key2];
88769
+ if (inner && typeof inner === "object" && !Array.isArray(inner)) bag = inner;
88770
+ else if (inner === void 0) {
88771
+ const next = {};
88772
+ bag[key2] = next;
88773
+ bag = next;
88774
+ } else bag = {};
88775
+ }
88776
+ bag[prop] = this.frameValue(read.style.path, read.style.leaf);
88777
+ }
88778
+ }
88779
+ atomsByStyle;
88780
+ /** Each style property → the physical longhands it writes. */
88781
+ styleAtoms() {
88782
+ if (!this.atomsByStyle) this.atomsByStyle = new Map(this.options.config.list("style-property").map((prop) => {
88783
+ const { properties = [] } = prop.toJSON();
88784
+ return [prop.path, atomsOf(properties)];
88785
+ }));
88786
+ return this.atomsByStyle;
88787
+ }
88788
+ /**
88789
+ * A shorthand class that a narrower one overrode on some sides (`p-5` under `px-16`), as the
88790
+ * classes for the sides it still painted (`py-5`), so the canvas's stylesheet order cannot let it
88791
+ * win the others back. The class as written when the system has no narrower class at its value.
88792
+ */
88793
+ narrowed(shorthand, owned) {
88794
+ const config2 = this.options.config;
88795
+ const options = /* @__PURE__ */ new Map();
88796
+ for (const [path2, atoms] of this.styleAtoms()) {
88797
+ if (path2 === shorthand.style.path || atoms.size === 0) continue;
88798
+ if ([...atoms].every((each) => owned.has(each))) options.set(path2, atoms);
88799
+ }
88800
+ const left = new Set(owned);
88801
+ const out = [];
88802
+ for (const [path2, atoms] of [...options].sort((a, b) => b[1].size - a[1].size)) {
88803
+ if (![...atoms].every((each) => left.has(each))) continue;
88804
+ const cls = stylePropClassName(config2, path2, shorthand.style.leaf);
88805
+ if (this.grammar.styleProp(cls)?.path !== path2) continue;
88806
+ out.push(`${shorthand.prefix}${cls}`);
88807
+ for (const each of atoms) left.delete(each);
88808
+ }
88809
+ return left.size === 0 ? out : [shorthand.bare];
88810
+ }
88811
+ /** A class as the modifier keys over it and the style prop it names, or nothing for one it doesn't. */
88812
+ readModifiedClass(cls) {
88813
+ const bracket = cls.indexOf("[");
88814
+ const head = bracket === -1 ? cls : cls.slice(0, bracket);
88815
+ const at = head.lastIndexOf(":");
88816
+ const prefixes = at === -1 ? [] : head.slice(0, at).split(":");
88817
+ const modifiers = [];
88818
+ const kept = [];
88819
+ let rank = 0;
88820
+ for (const prefix2 of prefixes) {
88821
+ const breakpoint = this.breakpoints.get(prefix2);
88822
+ if (breakpoint) {
88823
+ if (!breakpoint.active) return void 0;
88824
+ rank = Math.max(rank, breakpoint.rank);
88825
+ continue;
88826
+ }
88827
+ const key2 = this.modifierKeys.get(prefix2);
88828
+ if (!key2) return void 0;
88829
+ modifiers.push(key2);
88830
+ kept.push(prefix2);
88831
+ }
88832
+ let leaf = at === -1 ? cls : cls.slice(at + 1);
88833
+ const important = /^!|!$/.test(leaf);
88834
+ if (important) leaf = leaf.replace(/^!|!$/, "");
88835
+ if (important) rank += IMPORTANT_RANK;
88836
+ const style = this.grammar.styleProp(leaf);
88837
+ return style ? {
88838
+ modifiers,
88839
+ style,
88840
+ rank,
88841
+ bare: [...kept, leaf].join(":"),
88842
+ prefix: kept.map((each) => `${each}:`).join("")
88843
+ } : void 0;
88844
+ }
88845
+ /**
88846
+ * The styles the config gives an orphaned layer, as the frame's props: the rules that always apply
88847
+ * and the ones its classes say are on, in authored order. Only values the frame component declares,
88848
+ * spelled as an author writes them, are kept.
88849
+ */
88850
+ orphanLayerProps(el, frame2) {
88851
+ const [path2, layer] = (el.getAttribute(ORPHAN_LAYER) ?? "").split("#");
88852
+ if (!path2 || !layer) return {};
88853
+ const active = {};
88854
+ const own2 = this.grammar.component(path2);
88855
+ for (const cls of classesOf(el)) Object.assign(active, own2?.conditions.get(cls));
88856
+ const props = {};
88857
+ const styles = Component.get(this.options.config, path2)?.styles ?? {};
88858
+ for (const rule of Object.values(styles)) {
88859
+ const when = rule?.when ?? {};
88860
+ if (!Object.entries(when).every(([key2, value]) => active[key2] === value)) continue;
88861
+ for (const [key2, value] of Object.entries(rule.layers?.[layer] ?? {})) {
88218
88862
  if (!(key2 in frame2.declared)) continue;
88219
88863
  const authored = authoredValue(this.options.config, key2, value);
88220
88864
  if (typeof authored === "string" || typeof authored === "boolean") props[key2] = authored;
@@ -88323,7 +88967,8 @@ var Converter = class {
88323
88967
  image(img) {
88324
88968
  const src = img.getAttribute("src");
88325
88969
  const role = canvasRole(this.options.config, "image");
88326
- if (!src || !role) return [];
88970
+ if (!src) return [];
88971
+ if (!role) return this.plain(img);
88327
88972
  const props = { ...role.defaultProps };
88328
88973
  const grammar = this.grammar.component(role.component);
88329
88974
  if (grammar) {
@@ -88378,7 +89023,7 @@ var Converter = class {
88378
89023
  const answer = this.options.icons?.resolve(svgOf(svg));
88379
89024
  if (!answer) {
88380
89025
  this.unresolvedIcons += 1;
88381
- return [];
89026
+ return [this.plainSvg(svg)];
88382
89027
  }
88383
89028
  const key2 = this.key(answer.component);
88384
89029
  this.elements[key2] = {
@@ -88396,8 +89041,16 @@ var Converter = class {
88396
89041
  const props = {};
88397
89042
  const stamped = stampedProps(el);
88398
89043
  if (grammar) this.propsFromClasses(el, grammar, props);
89044
+ if (grammar) for (const [prop, raw] of Object.entries(grammar.declared)) {
89045
+ if (stamped[prop] !== void 0) continue;
89046
+ const declared3 = raw;
89047
+ const attr = declared3?.type === "forward" && declared3.target?.__ref === "layer:root" && typeof declared3.into === "string" ? declared3.into : declared3?.type === "string" && ROOT_ATTRIBUTE_PROPS.includes(prop) ? prop : void 0;
89048
+ const value = attr ? el.getAttribute(attr) : null;
89049
+ if (value) props[prop] = value;
89050
+ }
88399
89051
  Object.assign(props, stamped);
88400
89052
  if (grammar) this.propsFromInlineStyle(el, grammar, props, path2);
89053
+ if (grammar) this.propsFromComputed(el, grammar, props, path2);
88401
89054
  const layerProps2 = stampedLayerProps({
88402
89055
  el,
88403
89056
  layers: this.layerNames(path2)
@@ -88411,9 +89064,14 @@ var Converter = class {
88411
89064
  if (answer) for (const [prop, value] of Object.entries(answer.props)) props[prop] ??= value;
88412
89065
  else if (Object.keys(stamped).length === 0) {
88413
89066
  this.unresolvedIcons += 1;
88414
- return;
89067
+ return svg ? this.plainSvg(svg) : void 0;
88415
89068
  }
88416
89069
  }
89070
+ const glyphProp = this.glyphDrawers.get(path2);
89071
+ if (glyphProp && props[glyphProp] === void 0) {
89072
+ const svg = el.tagName.toLowerCase() === "svg" ? el : el.querySelector("svg");
89073
+ if (svg) return this.plainSvg(svg);
89074
+ }
88417
89075
  const key2 = this.key(path2);
88418
89076
  const element2 = {
88419
89077
  type: `component:${path2}`,
@@ -88421,8 +89079,10 @@ var Converter = class {
88421
89079
  };
88422
89080
  const declared2 = grammar?.declared ?? {};
88423
89081
  const slots = {};
88424
- for (const layer of asArray(el.querySelectorAll("[data-uds-slot]"))) {
88425
- if (nearestRoot(layer) !== el || hiddenBetween(layer, el)) continue;
89082
+ let rootSlotted = false;
89083
+ const marked = [...el.hasAttribute("data-uds-slot") ? [el] : [], ...asArray(el.querySelectorAll("[data-uds-slot]"))];
89084
+ for (const layer of marked) {
89085
+ if (layer !== el && layer.getAttribute("data-uds-layer") === "root" || layer !== el && nearestRoot(layer) !== el || hiddenBetween(layer, el)) continue;
88426
89086
  const names = slotNames(layer).filter((slot) => !grammar || slot in declared2);
88427
89087
  const intoOf = (slot) => grammar?.layerProps.get(slot)?.into ?? "children";
88428
89088
  const ownChildren = names.filter((slot) => intoOf(slot) === "children");
@@ -88431,10 +89091,13 @@ var Converter = class {
88431
89091
  if (into === "children" && slot !== ownChildren.at(-1)) continue;
88432
89092
  const holder = into === "children" ? layer : slotLayerNamed(layer, into);
88433
89093
  if (!holder) continue;
88434
- const fills = holder === layer ? this.convertOutsideLayers(layer, path2) : this.convertChildren(holder);
89094
+ const declaration = declared2[slot];
89095
+ const callerMarkup = declaration?.type === "slot" && declaration.text !== true;
89096
+ const fills = holder === layer ? this.convertOutsideLayers(layer, path2, callerMarkup) : this.convertChildren(holder);
89097
+ if (layer === el && holder === layer) rootSlotted = true;
88435
89098
  if (fills.length > 0) slots[slot] = fills;
88436
- else if (holder !== layer) {
88437
- const text = collapse(ownText(holder));
89099
+ else {
89100
+ const text = collapse(holder === layer ? ownText(layer, /* @__PURE__ */ new Set()) : ownText(holder));
88438
89101
  if (text) props[slot] = text;
88439
89102
  }
88440
89103
  }
@@ -88476,7 +89139,7 @@ var Converter = class {
88476
89139
  }
88477
89140
  const textSlot = declared2.children;
88478
89141
  const holdsText = textSlot?.type === "slot" && textSlot.text === true;
88479
- const loose = this.looseContent({
89142
+ const loose = rootSlotted ? [] : this.looseContent({
88480
89143
  el,
88481
89144
  claimed,
88482
89145
  takesGlyphs: !renders,
@@ -88509,9 +89172,24 @@ var Converter = class {
88509
89172
  if ("checked" in declared2) props.checked = true;
88510
89173
  else if ("selected" in declared2) props.selected = true;
88511
89174
  }
88512
- if (grammar) for (const prop of Object.keys(props)) {
88513
- if (prop in declared2 || prop === "aria-label" || prop === "layerProps") continue;
88514
- delete props[prop];
89175
+ if (grammar) {
89176
+ if (props.style !== void 0 && !("style" in declared2)) {
89177
+ const bags = props["layerProps"] ?? {};
89178
+ const root = bags.root ?? {};
89179
+ bags.root = {
89180
+ ...root,
89181
+ style: {
89182
+ ...Object.fromEntries(Object.entries(props.style).map(([property, value]) => [property, inlineCss(value)])),
89183
+ ...root.style ?? {}
89184
+ }
89185
+ };
89186
+ props[LAYER_PROPS] = bags;
89187
+ delete props.style;
89188
+ }
89189
+ for (const prop of Object.keys(props)) {
89190
+ if (prop in declared2 || prop === "aria-label" || prop === "layerProps") continue;
89191
+ delete props[prop];
89192
+ }
88515
89193
  }
88516
89194
  this.elements[key2] = element2;
88517
89195
  return key2;
@@ -88528,11 +89206,7 @@ var Converter = class {
88528
89206
  props[composite.prop] = composite.value;
88529
89207
  continue;
88530
89208
  }
88531
- const style = this.grammar.styleProp(cls);
88532
- if (style) {
88533
- const prop = grammar.propForStyleProperty.get(style.path);
88534
- if (prop && props[prop] === void 0) props[prop] = this.frameValue(style.path, style.leaf);
88535
- }
89209
+ this.stylePropsFromClasses([cls], grammar, props);
88536
89210
  }
88537
89211
  }
88538
89212
  /**
@@ -88554,6 +89228,46 @@ var Converter = class {
88554
89228
  propsFromInlineStyle(el, grammar, props, path2) {
88555
89229
  this.propsFromDeclarations(inlineDeclarations(el), grammar, props, path2 === void 0 ? void 0 : this.ruledProperties(path2));
88556
89230
  }
89231
+ /**
89232
+ * The styles the page's own classes gave a component's root, from what the browser computed, for
89233
+ * the CSS properties the component does not set itself: a stack's `display` and direction are its
89234
+ * own, while the width and flex share an app's Tailwind gave it are the page's, and no prop said
89235
+ * them. A property a rule, a default or a prop already read sets is left to that.
89236
+ */
89237
+ propsFromComputed(el, grammar, props, path2) {
89238
+ const computed = el.getAttribute(COMPUTED_STYLE_ATTR);
89239
+ if (!computed) return;
89240
+ const own2 = new Set(this.ruledProperties(path2));
89241
+ const { defaultProps = {} } = Component.get(this.options.config, path2) ?? {};
89242
+ const named = new Set(Object.keys(props));
89243
+ for (const [stylePath, prop] of grammar.propForStyleProperty) {
89244
+ if (!named.has(prop)) continue;
89245
+ for (const property of StyleProperty.get(this.options.config, stylePath)?.properties ?? []) for (const each of longhandsOf(property)) own2.add(each);
89246
+ }
89247
+ const fill = {};
89248
+ const unheld = {};
89249
+ for (const declaration of declarationsOf(computed)) {
89250
+ const [property, value] = declaration;
89251
+ if (own2.has(property) || own2.has(LOGICAL_SIDES[property] ?? property)) continue;
89252
+ const before5 = Object.keys(fill).length;
89253
+ this.propsFromDeclarations([declaration], grammar, fill);
89254
+ if (Object.keys(fill).length === before5 && COMPONENT_INLINE_LAYOUT.has(property)) {
89255
+ const arbitrary = this.grammar.stylePropsFor(property).some((option) => option.arbitrary);
89256
+ unheld[camelCase3(property)] = arbitrary ? `[${normalizeCssValue(value).replaceAll(" ", "_")}]` : value;
89257
+ }
89258
+ }
89259
+ for (const [prop, value] of Object.entries(fill)) {
89260
+ if (props[prop] !== void 0 || defaultProps[prop] === value) continue;
89261
+ props[prop] = value;
89262
+ }
89263
+ if (Object.keys(unheld).length > 0) {
89264
+ const own3 = props.style ?? {};
89265
+ props.style = {
89266
+ ...unheld,
89267
+ ...own3
89268
+ };
89269
+ }
89270
+ }
88557
89271
  /** The CSS properties a component's own style rules write on its root layer. */
88558
89272
  ruledProperties(path2) {
88559
89273
  const known = this.ruled.get(path2);
@@ -88656,6 +89370,208 @@ var ARTBOARD = [
88656
89370
  ["isolation", "isolate"]
88657
89371
  ];
88658
89372
  var INPUT_LINE = [["display", "flex"], ["align-items", "center"]];
89373
+ function inlineCss(value) {
89374
+ if (typeof value !== "string" || !/^\[.*\]$/.test(value)) return value;
89375
+ return value.slice(1, -1).replace(/url\([^)]*\)|_/g, (span) => span === "_" ? " " : span);
89376
+ }
89377
+ function holdsMoreThan(el, limit) {
89378
+ let count = 0;
89379
+ const visit2 = (node2) => {
89380
+ for (const child of node2.children) {
89381
+ count += 1;
89382
+ if (count > limit || visit2(child)) return true;
89383
+ }
89384
+ return false;
89385
+ };
89386
+ return visit2(el);
89387
+ }
89388
+ var SVG_SHAPE_LIMIT = 300;
89389
+ var FORBIDDEN_TAGS = /* @__PURE__ */ new Set([
89390
+ "script",
89391
+ "style",
89392
+ "noscript",
89393
+ "template",
89394
+ "iframe",
89395
+ "object",
89396
+ "embed",
89397
+ "base",
89398
+ "link",
89399
+ "meta"
89400
+ ]);
89401
+ var SIDES = [
89402
+ "top",
89403
+ "right",
89404
+ "bottom",
89405
+ "left"
89406
+ ];
89407
+ var CORNERS = [
89408
+ "top-left",
89409
+ "top-right",
89410
+ "bottom-right",
89411
+ "bottom-left"
89412
+ ];
89413
+ var IMPORTANT_RANK = 1e6;
89414
+ function atomsOf(properties) {
89415
+ const physical = new Map(Object.entries(LOGICAL_SIDES).map(([side, logical]) => [logical, side]));
89416
+ const atoms = /* @__PURE__ */ new Set();
89417
+ for (const property of properties) for (const each of longhandsOf(property)) {
89418
+ const side = physical.get(each) ?? each;
89419
+ if (longhandsOf(side).length <= 1) atoms.add(side);
89420
+ }
89421
+ return atoms;
89422
+ }
89423
+ function longhandsOf(property) {
89424
+ const boxed = /^(padding|margin)(-inline|-block)?$/.exec(property);
89425
+ if (boxed) {
89426
+ const [, box, axis] = boxed;
89427
+ return [property, ...(axis === "-inline" ? ["left", "right"] : axis === "-block" ? ["top", "bottom"] : SIDES).flatMap((side) => [`${box}-${side}`, LOGICAL_SIDES[`${box}-${side}`] ?? ""])].filter(Boolean);
89428
+ }
89429
+ switch (property) {
89430
+ case "inset":
89431
+ return [property, ...SIDES];
89432
+ case "gap":
89433
+ return [
89434
+ property,
89435
+ "row-gap",
89436
+ "column-gap"
89437
+ ];
89438
+ case "overflow":
89439
+ return [
89440
+ property,
89441
+ "overflow-x",
89442
+ "overflow-y"
89443
+ ];
89444
+ case "border-radius":
89445
+ return [property, ...CORNERS.map((corner) => `border-${corner}-radius`)];
89446
+ case "border-width":
89447
+ case "border-color":
89448
+ case "border-style": {
89449
+ const part = property.slice(7);
89450
+ return [property, ...SIDES.map((side) => `border-${side}-${part}`)];
89451
+ }
89452
+ default:
89453
+ return [property];
89454
+ }
89455
+ }
89456
+ var LOGICAL_SIDES = {
89457
+ "padding-left": "padding-inline-start",
89458
+ "padding-right": "padding-inline-end",
89459
+ "margin-left": "margin-inline-start",
89460
+ "margin-right": "margin-inline-end",
89461
+ "border-left-width": "border-inline-start-width",
89462
+ "border-right-width": "border-inline-end-width",
89463
+ "border-left-color": "border-inline-start-color",
89464
+ "border-right-color": "border-inline-end-color",
89465
+ left: "inset-inline-start",
89466
+ right: "inset-inline-end",
89467
+ "border-top-left-radius": "border-start-start-radius",
89468
+ "border-top-right-radius": "border-start-end-radius",
89469
+ "border-bottom-left-radius": "border-end-start-radius",
89470
+ "border-bottom-right-radius": "border-end-end-radius"
89471
+ };
89472
+ var VERBATIM_ATTRIBUTES = "__verbatimAttributes";
89473
+ var SVG_SKIPPED_ATTRIBUTES = /^(on|data-|id$|clip-path$|mask$|filter$|xlink:href$|href$)/;
89474
+ var SVG_SKIPPED_TAGS = /* @__PURE__ */ new Set([
89475
+ "defs",
89476
+ "clippath",
89477
+ "mask",
89478
+ "lineargradient",
89479
+ "radialgradient",
89480
+ "filter",
89481
+ "pattern",
89482
+ "symbol",
89483
+ "script",
89484
+ "style",
89485
+ "title",
89486
+ "desc",
89487
+ "use"
89488
+ ]);
89489
+ var SVG_TAGS = /* @__PURE__ */ new Map([["foreignobject", "foreignObject"]]);
89490
+ function svgAttributeName(name) {
89491
+ if (name === "viewbox") return "viewBox";
89492
+ if (name.startsWith("aria-") || name === "role") return name;
89493
+ if (name === "xmlns" || name === "xmlns:xlink") return name === "xmlns" ? "xmlns" : "xmlnsXlink";
89494
+ return name.replace(/[-:]([a-z])/g, (_, letter) => letter.toUpperCase());
89495
+ }
89496
+ var COMPONENT_INLINE_LAYOUT = /* @__PURE__ */ new Set([
89497
+ "grid-template-columns",
89498
+ "grid-template-rows",
89499
+ "grid-column",
89500
+ "grid-row",
89501
+ "white-space",
89502
+ "aspect-ratio",
89503
+ "flex-basis",
89504
+ "flex-grow",
89505
+ "flex-shrink",
89506
+ "max-width",
89507
+ "min-width"
89508
+ ]);
89509
+ var DEFAULT_CAPTURE_WIDTH = 1600;
89510
+ var ROOT_ATTRIBUTE_PROPS = [
89511
+ "src",
89512
+ "alt",
89513
+ "href",
89514
+ "title",
89515
+ "placeholder"
89516
+ ];
89517
+ var PAINT_PROPERTY = /^(background|border-(top-|right-|bottom-|left-)?(width|color)|box-shadow|outline)/;
89518
+ var GROUPING_TAGS = /* @__PURE__ */ new Set(["div", "span"]);
89519
+ var VOID_TAGS = /* @__PURE__ */ new Set([
89520
+ "img",
89521
+ "input",
89522
+ "br",
89523
+ "hr",
89524
+ "wbr",
89525
+ "area",
89526
+ "col",
89527
+ "source",
89528
+ "track"
89529
+ ]);
89530
+ var PLAIN_ATTRIBUTES = {
89531
+ href: "href",
89532
+ src: "src",
89533
+ alt: "alt",
89534
+ title: "title",
89535
+ role: "role",
89536
+ type: "type",
89537
+ placeholder: "placeholder",
89538
+ name: "name",
89539
+ target: "target",
89540
+ rel: "rel",
89541
+ colspan: "colSpan",
89542
+ rowspan: "rowSpan",
89543
+ for: "htmlFor"
89544
+ };
89545
+ function plainAttributes(el) {
89546
+ const out = {};
89547
+ const tag = el.tagName.toLowerCase();
89548
+ for (const [attr, prop] of Object.entries(PLAIN_ATTRIBUTES)) {
89549
+ const value = el.getAttribute(attr);
89550
+ if (value === null || value === void 0) continue;
89551
+ if ((attr === "href" || attr === "src") && /^\s*javascript:/i.test(value)) continue;
89552
+ out[prop] = value;
89553
+ }
89554
+ for (const { name, value } of el.attributes) if (name.startsWith("aria-")) out[name] = value;
89555
+ if (tag === "input" || tag === "textarea") {
89556
+ const value = tag === "textarea" ? el.textContent ?? "" : el.getAttribute("value");
89557
+ if (value) out.defaultValue = value;
89558
+ }
89559
+ return out;
89560
+ }
89561
+ function plainText(el) {
89562
+ if (isField(el)) return "";
89563
+ let text = "";
89564
+ const read = (node2) => {
89565
+ for (const child of node2.childNodes) if (child.nodeType === 3) text += child.textContent ?? "";
89566
+ else if (child.nodeType === 1 && visible(child)) read(child);
89567
+ };
89568
+ read(el);
89569
+ return text.replace(/\s+/g, " ").trim();
89570
+ }
89571
+ function camelCase3(property) {
89572
+ if (property.startsWith("--")) return property;
89573
+ return property.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
89574
+ }
88659
89575
  function isImage(el) {
88660
89576
  return el.tagName.toLowerCase() === "img" && !el.hasAttribute("data-uds-component");
88661
89577
  }
@@ -88721,8 +89637,11 @@ function paintsItself(el) {
88721
89637
  });
88722
89638
  }
88723
89639
  function inlineDeclarations(el) {
89640
+ return declarationsOf(el.getAttribute("style") ?? "");
89641
+ }
89642
+ function declarationsOf(text) {
88724
89643
  const out = [];
88725
- for (const declaration of (el.getAttribute("style") ?? "").split(";")) {
89644
+ for (const declaration of text.split(";")) {
88726
89645
  const at = declaration.indexOf(":");
88727
89646
  if (at < 0) continue;
88728
89647
  const property = declaration.slice(0, at).trim().toLowerCase();
@@ -88741,6 +89660,8 @@ function negated(value) {
88741
89660
  }
88742
89661
  function equivalents({ property, value }) {
88743
89662
  if ((property === "grid-column" || property === "grid-row") && /^span \d+$/.test(value)) return [value, `${value} / ${value}`];
89663
+ const px = /^(-?(?:\d+(?:\.\d+)?|\.\d+))px$/.exec(value);
89664
+ if (px) return [value, `${Number(px[1]) / 16}rem`];
88744
89665
  return [value];
88745
89666
  }
88746
89667
  function stampedLayerProps({ el, layers }) {
@@ -88882,195 +89803,6 @@ function asArray(list) {
88882
89803
  return Array.from(list);
88883
89804
  }
88884
89805
 
88885
- // ../config/dist/entities/system/Icon.js
88886
- var iconVariantAs = external_exports.union([external_exports.strictObject({ prop: external_exports.string().min(1) }), external_exports.strictObject({ export: external_exports.record(external_exports.string().min(1), external_exports.string().min(1)) })]);
88887
- var Icon = defineEntity({
88888
- kind: "icon",
88889
- label: "Icon",
88890
- labelPlural: "Icons",
88891
- fields: iconMemberMetadata,
88892
- groupFields: external_exports.strictObject({
88893
- /** The package the glyphs come from — a REF to the `Package` item, which owns the module
88894
- * specifier (its path) and the pinned version. A generated module imports the glyphs it renders
88895
- * from it, and a render that imports a member of it is placing a glyph of this set. */
88896
- package: Package.optional().describe("The npm package the set comes from."),
88897
- /** Where member metadata comes from and how to read it — `{ from, format }`. The build resolves
88898
- * the source and bakes each member's fields; see `icon-metadata.ts`. */
88899
- metadata: iconMetadataDeclaration.optional().describe("Catalogue metadata read from the package."),
88900
- /** Named sizes the set ships (`sm: 16`).
88901
- * @deprecated How a glyph is sized is the icon tool's component's business: the icon tool's component declares its own `size` and `variant` props, and every surface reads those. TODO: remove with a migration once no surface reads the library's copy. */
88902
- sizes: external_exports.record(external_exports.string(), external_exports.number()).optional().describe("Deprecated. The icon tool's component declares its own `size` and `variant` props."),
88903
- /** Weights/styles the set ships (`regular`, `fill`).
88904
- * @deprecated Which styles a glyph takes is the icon tool's component's business: the icon tool's component declares its own `size` and `variant` props, and every surface reads those. TODO: remove with a migration once no surface reads the library's copy. */
88905
- variants: external_exports.array(external_exports.string()).optional().describe("Deprecated. The icon tool's component declares its own `size` and `variant` props."),
88906
- /** How a variant reaches the glyph; see {@link iconVariantAs}. Absent, a variant is dropped at
88907
- * render.
88908
- * @deprecated Only the framework's raw-draw path read it; the icon tool's component passes a
88909
- * variant the way its package wants, and a set whose styles are separate exports lists them as
88910
- * members. TODO: remove with `sizes` and `variants`. */
88911
- variantAs: iconVariantAs.optional().describe("Deprecated. The icon tool's component passes a variant the way its package wants.")
88912
- }),
88913
- groupComputed: {
88914
- /** The glyphs the set ships, by leaf name. */
88915
- members: ({ config: config2, path: path2 }) => config2.members("icon", path2).map((member) => member.path.startsWith(`${path2}/`) ? member.path.slice(path2.length + 1) : member.path),
88916
- /** The module the glyphs import from: the named package's path. `pathOf` drops a source
88917
- * qualifier, so a borrowed set's module is still the bare specifier. */
88918
- module: ({ meta: meta3 }) => isRef2(meta3.package) ? pathOf2(meta3.package) : void 0,
88919
- /** The version the named package pins, resolved through the ref in whichever config holds the
88920
- * package row. */
88921
- version: ({ config: config2, meta: meta3 }) => {
88922
- if (!isRef2(meta3.package)) return void 0;
88923
- const pinned = config2.resolveRef(meta3.package)?.toJSON();
88924
- return typeof pinned?.version === "string" ? pinned.version : void 0;
88925
- }
88926
- },
88927
- groupInputs: {
88928
- /**
88929
- * The package's module namespace. The set's members are its glyph exports, named by the rule
88930
- * the metadata format declares (`glyphExportRule`), so an alias pair is one member and the
88931
- * package's infrastructure exports are none; `items` lays facts over members that exist, and a
88932
- * key naming no member is refused so a typo cannot invent a glyph. Each member's identity is
88933
- * recorded by reference, so an authored glyph (`name={StarIcon}`) is matched to its member by
88934
- * the object rather than by anything the component says about itself, and an alias resolves to
88935
- * the member it is. Read once while the config file is evaluated and never stored.
88936
- */
88937
- glyphs: ({ input: input2, body }) => {
88938
- if (!isRef2(body.package)) throw new Error("Icon.group: `glyphs` needs `package` on the same group, since a glyph is identified as an export of that module.");
88939
- const format = iconMetadataFormat.safeParse(body.metadata?.format);
88940
- const members2 = glyphMembersOf({
88941
- namespace: input2,
88942
- format: format.success ? format.data : void 0
88943
- });
88944
- const overlay = body.items ?? {};
88945
- const unknown2 = Object.keys(overlay).filter((name) => !members2.includes(name));
88946
- if (unknown2.length > 0) throw new Error(`Icon.group: \`items\` names ${spellValues(unknown2)}, which ${unknown2.length === 1 ? "is not a glyph export" : "are not glyph exports"} of \`glyphs\`${members2.length === 0 ? " (the namespace has no glyph components; the package may not be installed)" : ""}. \`items\` lays facts over the members the package exports; it cannot add one.`);
88947
- recordGlyphIdentities({
88948
- namespace: input2,
88949
- names: members2,
88950
- specifier: pathOf2(body.package)
88951
- });
88952
- return { items: Object.fromEntries(members2.map((name) => [name, overlay[name] ?? {}])) };
88953
- }
88954
- },
88955
- /**
88956
- * A value bound to a library may be the glyph component itself, or the `package:` export ref the
88957
- * open-bag pass turned it into. Either is answered as the member name when the export is one of
88958
- * this library's and comes from the module its `package` names.
88959
- */
88960
- authoredValue: ({ config: config2, target: target2, leaves: leaves2 }) => glyphOfLibrary(libraryGlyphFacts({
88961
- config: config2,
88962
- target: target2,
88963
- leaves: leaves2
88964
- })),
88965
- invariants: (config2) => iconDomainInvariants(config2)
88966
- });
88967
-
88968
- // ../config/dist/entities/system/icon-library.js
88969
- var EMPTY_CATEGORIES = Object.freeze([]);
88970
- var EMPTY_SIZES = Object.freeze({});
88971
- var EMPTY_VARIANTS = Object.freeze([]);
88972
- function iconLibrary(config2, path2) {
88973
- if (!config2) return void 0;
88974
- const cache = librariesOf(config2);
88975
- if (cache.has(path2)) return cache.get(path2);
88976
- const library = readIconLibrary(config2, path2);
88977
- cache.set(path2, library);
88978
- return library;
88979
- }
88980
- var librariesOf = createSliceMemo({
88981
- kinds: [
88982
- "icon",
88983
- "component",
88984
- "package"
88985
- ],
88986
- compute: (_config) => /* @__PURE__ */ new Map()
88987
- });
88988
- function readIconLibrary(config2, path2) {
88989
- const group = Icon.groups(config2).find((entry) => entry.path === path2);
88990
- if (!group) return void 0;
88991
- const { items: _items, sizes, variants: variants2, ...meta3 } = group.meta;
88992
- const set2 = setMembers({
88993
- config: config2,
88994
- path: path2,
88995
- declared: variants2
88996
- });
88997
- return {
88998
- ...meta3,
88999
- path: path2,
89000
- members: set2.members,
89001
- sizes: sizes ?? EMPTY_SIZES,
89002
- variants: variants2 ?? EMPTY_VARIANTS,
89003
- ...set2.memberVariants ? { memberVariants: set2.memberVariants } : {},
89004
- ...componentDefaults({
89005
- config: config2,
89006
- library: path2
89007
- })
89008
- };
89009
- }
89010
- function componentDefaults({ config: config2, library }) {
89011
- const bound = glyphComponentOf(config2, library);
89012
- if (!bound) return {};
89013
- const defaults = Component.get(config2, bound.path)?.defaultProps;
89014
- const variant = defaults?.variant;
89015
- const size = defaults?.size;
89016
- return {
89017
- ...typeof variant === "string" ? { defaultVariant: variant } : {},
89018
- ...typeof size === "string" ? { defaultSizeKey: size } : {}
89019
- };
89020
- }
89021
- var membersOf = createSliceMemo({
89022
- kinds: ["icon"],
89023
- compute: (_config) => /* @__PURE__ */ new Map()
89024
- });
89025
- function setMembers({ config: config2, path: path2, declared: declared2 }) {
89026
- const walked = membersOf(config2);
89027
- const hit = walked.get(path2);
89028
- if (hit) return hit;
89029
- const members2 = [];
89030
- const memberVariants = {};
89031
- for (const member of config2.members("icon", path2)) {
89032
- const leaf = member.path.startsWith(`${path2}/`) ? member.path.slice(path2.length + 1) : member.path;
89033
- members2.push(leaf);
89034
- const own2 = ownVariantsOf(member.body);
89035
- if (own2 && own2.length > 0 && !sameVariants({
89036
- own: own2,
89037
- declared: declared2
89038
- })) memberVariants[leaf] = own2;
89039
- }
89040
- const set2 = {
89041
- members: members2,
89042
- ...Object.keys(memberVariants).length > 0 ? { memberVariants } : {}
89043
- };
89044
- walked.set(path2, set2);
89045
- return set2;
89046
- }
89047
- function ownVariantsOf(body) {
89048
- const declared2 = body.variants;
89049
- if (!Array.isArray(declared2)) return void 0;
89050
- return declared2.filter((variant) => typeof variant === "string");
89051
- }
89052
- function sameVariants({ own: own2, declared: declared2 }) {
89053
- if (!declared2 || declared2.length !== own2.length) return false;
89054
- const set2 = new Set(declared2);
89055
- return own2.every((variant) => set2.has(variant));
89056
- }
89057
- var allLibrariesOf = createSliceMemo({
89058
- kinds: [
89059
- "icon",
89060
- "component",
89061
- "package"
89062
- ],
89063
- compute: (config2) => Icon.groups(config2).map(({ path: path2 }) => iconLibrary(config2, path2)).filter((library) => library !== void 0)
89064
- });
89065
- var boundLibrariesOf = createSliceMemo({
89066
- kinds: [
89067
- "component",
89068
- "icon",
89069
- "package"
89070
- ],
89071
- compute: (_config) => /* @__PURE__ */ new Map()
89072
- });
89073
-
89074
89806
  // ../config/dist/entities/canvas/node-patches.js
89075
89807
  function attachedSystem(config2) {
89076
89808
  const [source] = config2.list("system-source");