@aglyn/besigner-ui 1.0.0-beta.219 → 1.0.0-beta.220

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -83,8 +83,23 @@ import {
83
83
  } from '@aglyn/besigner-ui'
84
84
  ```
85
85
 
86
- The reference composition is the console's screen editor page in the
87
- monorepo, under
86
+ Two things have to be in place before the editor mounts, or it throws on
87
+ its first render:
88
+
89
+ - an editor app: call `initializeBesignerApp()` from `@aglyn/besigner` once;
90
+ - the console theme served as CSS variables: render the editor inside
91
+ `ThemeCssVarProvider` from `@aglyn/shared-ui-theme`, given
92
+ `{ light: consoleThemeLight, dark: consoleThemeDark }`. A plain MUI
93
+ `ThemeProvider` is not enough, because the editor's styles read the theme's
94
+ CSS variables.
95
+
96
+ The smallest working composition is the example app in the monorepo,
97
+ [`examples/consumers/besigner-ui`](https://github.com/aglyn/aglyn/tree/main/examples/consumers/besigner-ui):
98
+ a Vite app that installs these packages from npm, registers four element
99
+ types of its own, and mounts the workspace, viewport and canvas. Aglyn's CI
100
+ builds it and opens it in a browser on every release.
101
+
102
+ The full composition is the console's screen editor page, under
88
103
  `apps/console/app/(editor)/[orgSlug]/hosts/[host]/screens/[screenId]/versions/[versionId]/besigner/page.tsx`.
89
104
  It wraps the page with `withBesignerContext`, loads the document with
90
105
  `useBesignerDocument`, and lays out the workspace, viewport and panels. The
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aglyn/besigner-ui",
3
- "version": "1.0.0-beta.219",
3
+ "version": "1.0.0-beta.220",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -25,22 +25,22 @@
25
25
  "./package.json": "./package.json"
26
26
  },
27
27
  "dependencies": {
28
- "@aglyn/aglyn": "1.0.0-beta.219",
29
- "@aglyn/aglyn-markdown-editor": "1.0.0-beta.219",
30
- "@aglyn/aglyn-node-renderer": "1.0.0-beta.219",
31
- "@aglyn/besigner": "1.0.0-beta.219",
32
- "@aglyn/shared-data-enums": "1.0.0-beta.219",
33
- "@aglyn/shared-data-mdi": "1.0.0-beta.219",
34
- "@aglyn/shared-data-types": "1.0.0-beta.219",
35
- "@aglyn/shared-svg-icons": "1.0.0-beta.219",
36
- "@aglyn/shared-ui-json-editor": "1.0.0-beta.219",
37
- "@aglyn/shared-ui-jsx": "1.0.0-beta.219",
38
- "@aglyn/shared-ui-jsx-forms": "1.0.0-beta.219",
39
- "@aglyn/shared-ui-snackstack": "1.0.0-beta.219",
40
- "@aglyn/shared-ui-theme": "1.0.0-beta.219",
41
- "@aglyn/shared-util-dom": "1.0.0-beta.219",
42
- "@aglyn/shared-util-tools": "1.0.0-beta.219",
43
- "@aglyn/shared-util-vendor": "1.0.0-beta.219",
28
+ "@aglyn/aglyn": "1.0.0-beta.220",
29
+ "@aglyn/aglyn-markdown-editor": "1.0.0-beta.220",
30
+ "@aglyn/aglyn-node-renderer": "1.0.0-beta.220",
31
+ "@aglyn/besigner": "1.0.0-beta.220",
32
+ "@aglyn/shared-data-enums": "1.0.0-beta.220",
33
+ "@aglyn/shared-data-mdi": "1.0.0-beta.220",
34
+ "@aglyn/shared-data-types": "1.0.0-beta.220",
35
+ "@aglyn/shared-svg-icons": "1.0.0-beta.220",
36
+ "@aglyn/shared-ui-json-editor": "1.0.0-beta.220",
37
+ "@aglyn/shared-ui-jsx": "1.0.0-beta.220",
38
+ "@aglyn/shared-ui-jsx-forms": "1.0.0-beta.220",
39
+ "@aglyn/shared-ui-snackstack": "1.0.0-beta.220",
40
+ "@aglyn/shared-ui-theme": "1.0.0-beta.220",
41
+ "@aglyn/shared-util-dom": "1.0.0-beta.220",
42
+ "@aglyn/shared-util-tools": "1.0.0-beta.220",
43
+ "@aglyn/shared-util-vendor": "1.0.0-beta.220",
44
44
  "@dnd-kit/core": "^6.3.1",
45
45
  "@dnd-kit/utilities": "^3.2.2",
46
46
  "@react-aria/utils": "^3.34.1",
@@ -63,7 +63,7 @@
63
63
  "@mui/material": "^9.3.1",
64
64
  "@mui/system": "^9.2.0",
65
65
  "firebase": "^12.18.0",
66
- "next": "16.3.3",
66
+ "next": "^16.3.3",
67
67
  "react": "^19.2.8"
68
68
  },
69
69
  "sideEffects": false,
@@ -22,6 +22,7 @@ import { FormRenderer, FormSpy, useFormApi } from "@aglyn/shared-ui-jsx-forms";
22
22
  import { useHostThemeDocument } from "@aglyn/shared-ui-theme";
23
23
  import { Grid } from "@mui/material";
24
24
  import { useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
25
+ import { useContentStable } from "@aglyn/shared-ui-jsx/hooks/use-content-stable";
25
26
  import { MediaPickerContext } from "../contexts/media-picker-context.js";
26
27
  import useInsertTokenOptions from "../hooks/use-insert-token-options.js";
27
28
  import { buildStyleThemeScales } from "../utils/theme-scale-options.js";
@@ -47,51 +48,6 @@ import { TOKEN_TEXT_FIELD_COMPONENT } from "./token-text-field.component.js";
47
48
  return '';
48
49
  }
49
50
  }
50
- /** A stable token per function, so two keys agree only on the same function. */ const functionTokens = new WeakMap();
51
- let nextFunctionToken = 0;
52
- let nextUnkeyable = 0;
53
- /**
54
- * What a value HOLDS, as a string: plain data by value, a function by
55
- * identity, a Set by its members. A value it cannot write down — a cycle, a
56
- * React element's owner — gets a key of its own, so it only ever equals
57
- * itself.
58
- */ function contentKey(value) {
59
- try {
60
- return JSON.stringify(value, (_key, entry)=>{
61
- if (typeof entry === 'function') {
62
- let token = functionTokens.get(entry);
63
- if (token === undefined) {
64
- nextFunctionToken += 1;
65
- token = nextFunctionToken;
66
- functionTokens.set(entry, token);
67
- }
68
- return `ƒ${token}`;
69
- }
70
- if (entry instanceof Set) return {
71
- set: [
72
- ...entry
73
- ].sort()
74
- };
75
- return entry;
76
- });
77
- } catch (unused) {
78
- nextUnkeyable += 1;
79
- return `unkeyable:${nextUnkeyable}`;
80
- }
81
- }
82
- /**
83
- * `value` itself while it holds the same content as last render, else the new
84
- * one — so a caller that builds its fields inline on every render hands the
85
- * form the SAME fields while they have not changed.
86
- */ function useContentStable(value) {
87
- const held = useRef(undefined);
88
- const key = contentKey(value);
89
- if (!held.current || held.current.key !== key) held.current = {
90
- key,
91
- value
92
- };
93
- return held.current.value;
94
- }
95
51
  /** Hands the parent every change, and the form API for writes from outside. */ function AttributeFieldsFormTemplate(props) {
96
52
  const { formFields, onValues, formApiRef } = props;
97
53
  const formApi = useFormApi();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/property-values-form.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport type * as Aglyn from '@aglyn/aglyn'\nimport {\n canvas,\n components,\n EntityPickerContext,\n FieldComponentType,\n getKnownPluginInstallsVersion,\n ScreenLinkContext,\n subscribeKnownPluginInstalls,\n} from '@aglyn/aglyn'\nimport { useAglynSiteTheme } from '@aglyn/aglyn-node-renderer'\nimport {\n FormRenderer,\n FormSpy,\n type FormTemplateRenderProps,\n useFormApi,\n} from '@aglyn/shared-ui-jsx-forms'\nimport { useHostThemeDocument } from '@aglyn/shared-ui-theme'\nimport { Grid } from '@mui/material'\nimport {\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react'\n\nimport { MediaPickerContext } from '../contexts/media-picker-context'\nimport useInsertTokenOptions from '../hooks/use-insert-token-options'\nimport { buildStyleThemeScales } from '../utils/theme-scale-options'\nimport {\n type AttributeFieldResolveContext,\n buildPropertyField,\n elementPropsComponentMapper,\n entityKindsForAttributes,\n type PropertyOwnerNoun,\n resolveAttributeField,\n withNumericValueParse,\n} from './element-props-form.component'\nimport { TOKEN_TEXT_FIELD_COMPONENT } from './token-text-field.component'\n\n/**\n * Property values edited OUTSIDE the Attributes panel, with the Attributes\n * panel's own controls (AGL-2893): the Properties dialog's Default for each\n * property, a kind's settings, a condition's operand, and a screen's values\n * for the layout it renders inside.\n *\n * Each field is an attribute field — {@link buildPropertyField} for a\n * property — finished by {@link resolveAttributeField} against the same site\n * data the panel reads and drawn by `elementPropsComponentMapper`. So a Yes /\n * no is the switch, an Icon the icon picker and a Color the color picker\n * here exactly as they are on an instance, and nothing here can drift from\n * the panel into a look-alike.\n */\n\n/** The form's nothing-to-submit: every change is reported as it happens. */\nconst noop = () => undefined\n\n/** The values each change reports, compared so a re-render is not a change. */\nfunction serialize(values: unknown): string {\n try {\n return JSON.stringify(values ?? {})\n } catch {\n return ''\n }\n}\n\n/** A stable token per function, so two keys agree only on the same function. */\nconst functionTokens = new WeakMap<object, number>()\nlet nextFunctionToken = 0\nlet nextUnkeyable = 0\n\n/**\n * What a value HOLDS, as a string: plain data by value, a function by\n * identity, a Set by its members. A value it cannot write down — a cycle, a\n * React element's owner — gets a key of its own, so it only ever equals\n * itself.\n */\nfunction contentKey(value: unknown): string {\n try {\n return JSON.stringify(value, (_key, entry: unknown) => {\n if (typeof entry === 'function') {\n let token = functionTokens.get(entry)\n if (token === undefined) {\n nextFunctionToken += 1\n token = nextFunctionToken\n functionTokens.set(entry, token)\n }\n return `ƒ${token}`\n }\n if (entry instanceof Set) return { set: [...entry].sort() }\n return entry\n })\n } catch {\n nextUnkeyable += 1\n return `unkeyable:${nextUnkeyable}`\n }\n}\n\n/**\n * `value` itself while it holds the same content as last render, else the new\n * one — so a caller that builds its fields inline on every render hands the\n * form the SAME fields while they have not changed.\n */\nfunction useContentStable<T>(value: T): T {\n const held = useRef<{ key: string; value: T } | undefined>(undefined)\n const key = contentKey(value)\n if (!held.current || held.current.key !== key) held.current = { key, value }\n return held.current.value\n}\n\n/** Hands the parent every change, and the form API for writes from outside. */\nfunction AttributeFieldsFormTemplate(\n props: FormTemplateRenderProps & {\n onValues: (values: Record<string, unknown>) => void\n formApiRef: { current: ReturnType<typeof useFormApi> | undefined }\n },\n) {\n const { formFields, onValues, formApiRef } = props\n const formApi = useFormApi()\n formApiRef.current = formApi\n // The values the form opened with, so the spy's first report — the state\n // it subscribed to, not a change — is not handed on as one.\n const last = useRef(serialize(formApi.getState().values))\n return (\n <form onSubmit={(event) => event.preventDefault()} noValidate>\n <Grid container spacing={2}>\n {formFields as unknown as JSX.Node}\n </Grid>\n <FormSpy\n subscription={{ values: true }}\n onChange={({ values }: { values: Record<string, unknown> }) => {\n const next = serialize(values)\n if (next === last.current) return\n last.current = next\n onValues(values)\n }}\n />\n </form>\n )\n}\n\nexport interface AttributeFieldsFormProps {\n /**\n * Attribute fields — as a coded component would declare them, or as\n * {@link buildPropertyField} draws a property — named for paths in\n * `values`.\n */\n fields: ReadonlyArray<Record<string, unknown>>\n /** The values the form starts from. Later changes to this are not re-read. */\n values?: Record<string, unknown>\n onChange: (values: Record<string, unknown>) => void\n /** Written into the field when a media library pick lands, by field name. */\n mediaFields?: ReadonlySet<string>\n}\n\n/**\n * Attribute fields in a form of their own, resolved and drawn exactly as the\n * Attributes panel draws them, reporting every change.\n *\n * ## It renders its fields only when they change (AGL-3423)\n *\n * Every change is reported upward, and the owner typically keeps it in state:\n * the Properties dialog re-renders every row on each keystroke in any row's\n * Default, and builds each row's fields inline. Re-rendering the form with\n * them re-rendered every field in it, and a multi-answer Choice's field is a\n * multiple Autocomplete, which leaves a state update pending after every\n * commit it takes part in (see `ElementClassesChips`). Fifty-one fast\n * keystrokes in a sibling field and React refused the next one: \"Maximum\n * update depth exceeded\" (#185), thrown from the typing field's own\n * final-form subscriber. So the fields are held by CONTENT, and the rendered\n * form is reused until the resolved fields change.\n */\nexport function AttributeFieldsForm(props: AttributeFieldsFormProps) {\n const { values, onChange } = props\n const fields = useContentStable(props.fields)\n const mediaFields = useContentStable(props.mediaFields)\n const [initialValues] = useState(() => values ?? {})\n const formApiRef = useRef<ReturnType<typeof useFormApi> | undefined>(undefined)\n const onChangeRef = useRef(onChange)\n onChangeRef.current = onChange\n\n const { screens, labels } = useContext(ScreenLinkContext)\n const entityOptions = useContext(EntityPickerContext)\n const { onPickMedia } = useContext(MediaPickerContext)\n const { options: insertOptions, labelContext: tokenLabelContext } =\n useInsertTokenOptions(undefined)\n const pluginInstallsVersion = useSyncExternalStore(\n subscribeKnownPluginInstalls,\n getKnownPluginInstallsVersion,\n getKnownPluginInstallsVersion,\n )\n\n // Ask for the entity lists these fields' pickers show (AGL-703), as the\n // Attributes panel does for the element it edits.\n const requestEntities = entityOptions.request\n useEffect(() => {\n if (!requestEntities) return\n for (const kind of entityKindsForAttributes(\n fields as unknown as Aglyn.AglynAttributeSchema[],\n )) {\n requestEntities(kind)\n }\n }, [fields, requestEntities])\n\n // The canvas's elements, for element pickers.\n const wantsNodes = fields.some(\n (field) => field['component'] === FieldComponentType.NODE_SELECT,\n )\n const nodeOptions = useMemo(() => {\n if (!wantsNodes) return []\n const canvasNodes = (canvas.toJSON().nodes ?? {}) as Record<string, any>\n return Object.entries(canvasNodes)\n .filter(([id]) => Boolean(id))\n .map(([id, candidate]) => {\n const displayName =\n components.getSchema(candidate?.componentId)?.displayName ??\n candidate?.componentId ??\n 'Element'\n const text =\n typeof candidate?.props?.children === 'string'\n ? candidate.props.children.trim().slice(0, 24)\n : ''\n return {\n value: id,\n label: `${displayName}${text ? ` \"${text}\"` : ''} · ${id.slice(0, 6)}`,\n }\n })\n .sort((a, b) => a.label.localeCompare(b.label))\n }, [wantsNodes])\n\n const context = useMemo<AttributeFieldResolveContext>(\n () => ({\n screens,\n labels,\n values: initialValues,\n entityOptions,\n nodeOptions,\n insertOptions,\n tokenLabelContext,\n pluginInstallsVersion,\n }),\n [\n screens,\n labels,\n initialValues,\n entityOptions,\n nodeOptions,\n insertOptions,\n tokenLabelContext,\n pluginInstallsVersion,\n ],\n )\n\n const resolved = useMemo(\n () =>\n fields\n .map((field) => resolveAttributeField(field, context))\n .map((field) =>\n onPickMedia &&\n mediaFields?.has(String(field['name'])) &&\n field['component'] === TOKEN_TEXT_FIELD_COMPONENT\n ? {\n ...field,\n onBrowseMedia: () =>\n onPickMedia((value) =>\n formApiRef.current?.change(String(field['name']), value),\n ),\n }\n : field,\n )\n .filter((field) => String(field['component']) in elementPropsComponentMapper)\n .map(withNumericValueParse),\n [fields, context, onPickMedia, mediaFields],\n )\n\n // One component for the life of the form: a template created per render\n // would be a new component type each time, remounting every field.\n const [Template] = useState(\n () =>\n function BoundTemplate(templateProps: FormTemplateRenderProps) {\n return (\n <AttributeFieldsFormTemplate\n {...templateProps}\n formApiRef={formApiRef}\n onValues={(next) => onChangeRef.current(next)}\n />\n )\n },\n )\n\n // The same element while the resolved fields are the same, which React\n // takes as \"nothing to render here\".\n return useMemo(\n () => (\n <FormRenderer\n componentMapper={elementPropsComponentMapper}\n FormTemplate={Template}\n initialValues={initialValues}\n onSubmit={noop}\n schema={{ fields: resolved as never }}\n />\n ),\n [Template, initialValues, resolved],\n )\n}\n\nexport interface PropertyValuesFormProps {\n /** The properties the owner declares. */\n declared: readonly Aglyn.ReusableComponentProp[]\n /** Each property's value, by name. */\n values?: Record<string, unknown>\n /** Every property's value, by name, after each change. */\n onChange: (values: Record<string, unknown>) => void\n /**\n * `value` for a page setting them, with each empty field falling back to\n * the default and every condition applied; `default` for declaring those\n * defaults.\n */\n role?: 'value' | 'default'\n noun?: PropertyOwnerNoun\n /** Only these properties, by name; all of them when omitted. */\n only?: readonly string[]\n}\n\n/** The path a property's value sits at inside this form. */\nconst VALUES_KEY = 'values'\nconst pathOf = (name: string) => `${VALUES_KEY}.${name}`\n\n/**\n * A component's or layout's properties, each edited with the control its\n * kind names in the Attributes panel.\n */\nexport function PropertyValuesForm(props: PropertyValuesFormProps) {\n const { declared, values, onChange, role = 'value', noun = 'component', only } = props\n const hostThemeDoc = useHostThemeDocument()\n const siteTheme = useAglynSiteTheme({ theme: hostThemeDoc })\n const themeScales = useMemo(\n () => buildStyleThemeScales(siteTheme as any) as unknown as Record<string, unknown>,\n [siteTheme],\n )\n const shown = useMemo(\n () =>\n declared.filter(\n (prop) => Boolean(prop?.name) && (!only || only.includes(prop.name)),\n ),\n [declared, only],\n )\n const fields = useMemo(\n () =>\n shown.map((prop) =>\n buildPropertyField(prop, {\n name: pathOf(prop.name),\n role,\n declared,\n valuePath: pathOf,\n noun,\n themeScales,\n }),\n ),\n [shown, role, declared, noun, themeScales],\n )\n const mediaFields = useMemo(\n () =>\n new Set(\n shown\n .filter((prop) => prop.type === 'image')\n .map((prop) => pathOf(prop.name)),\n ),\n [shown],\n )\n const [initial] = useState(() => ({ [VALUES_KEY]: values ?? {} }))\n return (\n <AttributeFieldsForm\n fields={fields}\n values={initial}\n mediaFields={mediaFields}\n onChange={(next) =>\n onChange(\n (next?.[VALUES_KEY] as Record<string, unknown> | undefined) ?? {},\n )\n }\n />\n )\n}\n\nexport default PropertyValuesForm\n"],"names":["canvas","components","EntityPickerContext","FieldComponentType","getKnownPluginInstallsVersion","ScreenLinkContext","subscribeKnownPluginInstalls","useAglynSiteTheme","FormRenderer","FormSpy","useFormApi","useHostThemeDocument","Grid","useContext","useEffect","useMemo","useRef","useState","useSyncExternalStore","MediaPickerContext","useInsertTokenOptions","buildStyleThemeScales","buildPropertyField","elementPropsComponentMapper","entityKindsForAttributes","resolveAttributeField","withNumericValueParse","TOKEN_TEXT_FIELD_COMPONENT","noop","undefined","serialize","values","JSON","stringify","functionTokens","WeakMap","nextFunctionToken","nextUnkeyable","contentKey","value","_key","entry","token","get","set","Set","sort","useContentStable","held","key","current","AttributeFieldsFormTemplate","props","formFields","onValues","formApiRef","formApi","last","getState","form","onSubmit","event","preventDefault","noValidate","container","spacing","subscription","onChange","next","AttributeFieldsForm","fields","mediaFields","initialValues","onChangeRef","screens","labels","entityOptions","onPickMedia","options","insertOptions","labelContext","tokenLabelContext","pluginInstallsVersion","requestEntities","request","kind","wantsNodes","some","field","NODE_SELECT","nodeOptions","canvasNodes","toJSON","nodes","Object","entries","filter","id","Boolean","map","candidate","displayName","getSchema","componentId","text","children","trim","slice","label","a","b","localeCompare","context","resolved","has","String","onBrowseMedia","change","Template","BoundTemplate","templateProps","componentMapper","FormTemplate","schema","VALUES_KEY","pathOf","name","PropertyValuesForm","declared","role","noun","only","hostThemeDoc","siteTheme","theme","themeScales","shown","prop","includes","valuePath","type","initial"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/property-values-form.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport type * as Aglyn from '@aglyn/aglyn'\nimport {\n canvas,\n components,\n EntityPickerContext,\n FieldComponentType,\n getKnownPluginInstallsVersion,\n ScreenLinkContext,\n subscribeKnownPluginInstalls,\n} from '@aglyn/aglyn'\nimport { useAglynSiteTheme } from '@aglyn/aglyn-node-renderer'\nimport {\n FormRenderer,\n FormSpy,\n type FormTemplateRenderProps,\n useFormApi,\n} from '@aglyn/shared-ui-jsx-forms'\nimport { useHostThemeDocument } from '@aglyn/shared-ui-theme'\nimport { Grid } from '@mui/material'\nimport {\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react'\nimport { useContentStable } from '@aglyn/shared-ui-jsx/hooks/use-content-stable'\n\nimport { MediaPickerContext } from '../contexts/media-picker-context'\nimport useInsertTokenOptions from '../hooks/use-insert-token-options'\nimport { buildStyleThemeScales } from '../utils/theme-scale-options'\nimport {\n type AttributeFieldResolveContext,\n buildPropertyField,\n elementPropsComponentMapper,\n entityKindsForAttributes,\n type PropertyOwnerNoun,\n resolveAttributeField,\n withNumericValueParse,\n} from './element-props-form.component'\nimport { TOKEN_TEXT_FIELD_COMPONENT } from './token-text-field.component'\n\n/**\n * Property values edited OUTSIDE the Attributes panel, with the Attributes\n * panel's own controls (AGL-2893): the Properties dialog's Default for each\n * property, a kind's settings, a condition's operand, and a screen's values\n * for the layout it renders inside.\n *\n * Each field is an attribute field — {@link buildPropertyField} for a\n * property — finished by {@link resolveAttributeField} against the same site\n * data the panel reads and drawn by `elementPropsComponentMapper`. So a Yes /\n * no is the switch, an Icon the icon picker and a Color the color picker\n * here exactly as they are on an instance, and nothing here can drift from\n * the panel into a look-alike.\n */\n\n/** The form's nothing-to-submit: every change is reported as it happens. */\nconst noop = () => undefined\n\n/** The values each change reports, compared so a re-render is not a change. */\nfunction serialize(values: unknown): string {\n try {\n return JSON.stringify(values ?? {})\n } catch {\n return ''\n }\n}\n\n/** Hands the parent every change, and the form API for writes from outside. */\nfunction AttributeFieldsFormTemplate(\n props: FormTemplateRenderProps & {\n onValues: (values: Record<string, unknown>) => void\n formApiRef: { current: ReturnType<typeof useFormApi> | undefined }\n },\n) {\n const { formFields, onValues, formApiRef } = props\n const formApi = useFormApi()\n formApiRef.current = formApi\n // The values the form opened with, so the spy's first report — the state\n // it subscribed to, not a change — is not handed on as one.\n const last = useRef(serialize(formApi.getState().values))\n return (\n <form onSubmit={(event) => event.preventDefault()} noValidate>\n <Grid container spacing={2}>\n {formFields as unknown as JSX.Node}\n </Grid>\n <FormSpy\n subscription={{ values: true }}\n onChange={({ values }: { values: Record<string, unknown> }) => {\n const next = serialize(values)\n if (next === last.current) return\n last.current = next\n onValues(values)\n }}\n />\n </form>\n )\n}\n\nexport interface AttributeFieldsFormProps {\n /**\n * Attribute fields — as a coded component would declare them, or as\n * {@link buildPropertyField} draws a property — named for paths in\n * `values`.\n */\n fields: ReadonlyArray<Record<string, unknown>>\n /** The values the form starts from. Later changes to this are not re-read. */\n values?: Record<string, unknown>\n onChange: (values: Record<string, unknown>) => void\n /** Written into the field when a media library pick lands, by field name. */\n mediaFields?: ReadonlySet<string>\n}\n\n/**\n * Attribute fields in a form of their own, resolved and drawn exactly as the\n * Attributes panel draws them, reporting every change.\n *\n * ## It renders its fields only when they change (AGL-3423)\n *\n * Every change is reported upward, and the owner typically keeps it in state:\n * the Properties dialog re-renders every row on each keystroke in any row's\n * Default, and builds each row's fields inline. Re-rendering the form with\n * them re-rendered every field in it, and a multi-answer Choice's field is a\n * multiple Autocomplete, which leaves a state update pending after every\n * commit it takes part in (see `ElementClassesChips`). Fifty-one fast\n * keystrokes in a sibling field and React refused the next one: \"Maximum\n * update depth exceeded\" (#185), thrown from the typing field's own\n * final-form subscriber. So the fields are held by CONTENT, and the rendered\n * form is reused until the resolved fields change.\n */\nexport function AttributeFieldsForm(props: AttributeFieldsFormProps) {\n const { values, onChange } = props\n const fields = useContentStable(props.fields)\n const mediaFields = useContentStable(props.mediaFields)\n const [initialValues] = useState(() => values ?? {})\n const formApiRef = useRef<ReturnType<typeof useFormApi> | undefined>(undefined)\n const onChangeRef = useRef(onChange)\n onChangeRef.current = onChange\n\n const { screens, labels } = useContext(ScreenLinkContext)\n const entityOptions = useContext(EntityPickerContext)\n const { onPickMedia } = useContext(MediaPickerContext)\n const { options: insertOptions, labelContext: tokenLabelContext } =\n useInsertTokenOptions(undefined)\n const pluginInstallsVersion = useSyncExternalStore(\n subscribeKnownPluginInstalls,\n getKnownPluginInstallsVersion,\n getKnownPluginInstallsVersion,\n )\n\n // Ask for the entity lists these fields' pickers show (AGL-703), as the\n // Attributes panel does for the element it edits.\n const requestEntities = entityOptions.request\n useEffect(() => {\n if (!requestEntities) return\n for (const kind of entityKindsForAttributes(\n fields as unknown as Aglyn.AglynAttributeSchema[],\n )) {\n requestEntities(kind)\n }\n }, [fields, requestEntities])\n\n // The canvas's elements, for element pickers.\n const wantsNodes = fields.some(\n (field) => field['component'] === FieldComponentType.NODE_SELECT,\n )\n const nodeOptions = useMemo(() => {\n if (!wantsNodes) return []\n const canvasNodes = (canvas.toJSON().nodes ?? {}) as Record<string, any>\n return Object.entries(canvasNodes)\n .filter(([id]) => Boolean(id))\n .map(([id, candidate]) => {\n const displayName =\n components.getSchema(candidate?.componentId)?.displayName ??\n candidate?.componentId ??\n 'Element'\n const text =\n typeof candidate?.props?.children === 'string'\n ? candidate.props.children.trim().slice(0, 24)\n : ''\n return {\n value: id,\n label: `${displayName}${text ? ` \"${text}\"` : ''} · ${id.slice(0, 6)}`,\n }\n })\n .sort((a, b) => a.label.localeCompare(b.label))\n }, [wantsNodes])\n\n const context = useMemo<AttributeFieldResolveContext>(\n () => ({\n screens,\n labels,\n values: initialValues,\n entityOptions,\n nodeOptions,\n insertOptions,\n tokenLabelContext,\n pluginInstallsVersion,\n }),\n [\n screens,\n labels,\n initialValues,\n entityOptions,\n nodeOptions,\n insertOptions,\n tokenLabelContext,\n pluginInstallsVersion,\n ],\n )\n\n const resolved = useMemo(\n () =>\n fields\n .map((field) => resolveAttributeField(field, context))\n .map((field) =>\n onPickMedia &&\n mediaFields?.has(String(field['name'])) &&\n field['component'] === TOKEN_TEXT_FIELD_COMPONENT\n ? {\n ...field,\n onBrowseMedia: () =>\n onPickMedia((value) =>\n formApiRef.current?.change(String(field['name']), value),\n ),\n }\n : field,\n )\n .filter((field) => String(field['component']) in elementPropsComponentMapper)\n .map(withNumericValueParse),\n [fields, context, onPickMedia, mediaFields],\n )\n\n // One component for the life of the form: a template created per render\n // would be a new component type each time, remounting every field.\n const [Template] = useState(\n () =>\n function BoundTemplate(templateProps: FormTemplateRenderProps) {\n return (\n <AttributeFieldsFormTemplate\n {...templateProps}\n formApiRef={formApiRef}\n onValues={(next) => onChangeRef.current(next)}\n />\n )\n },\n )\n\n // The same element while the resolved fields are the same, which React\n // takes as \"nothing to render here\".\n return useMemo(\n () => (\n <FormRenderer\n componentMapper={elementPropsComponentMapper}\n FormTemplate={Template}\n initialValues={initialValues}\n onSubmit={noop}\n schema={{ fields: resolved as never }}\n />\n ),\n [Template, initialValues, resolved],\n )\n}\n\nexport interface PropertyValuesFormProps {\n /** The properties the owner declares. */\n declared: readonly Aglyn.ReusableComponentProp[]\n /** Each property's value, by name. */\n values?: Record<string, unknown>\n /** Every property's value, by name, after each change. */\n onChange: (values: Record<string, unknown>) => void\n /**\n * `value` for a page setting them, with each empty field falling back to\n * the default and every condition applied; `default` for declaring those\n * defaults.\n */\n role?: 'value' | 'default'\n noun?: PropertyOwnerNoun\n /** Only these properties, by name; all of them when omitted. */\n only?: readonly string[]\n}\n\n/** The path a property's value sits at inside this form. */\nconst VALUES_KEY = 'values'\nconst pathOf = (name: string) => `${VALUES_KEY}.${name}`\n\n/**\n * A component's or layout's properties, each edited with the control its\n * kind names in the Attributes panel.\n */\nexport function PropertyValuesForm(props: PropertyValuesFormProps) {\n const { declared, values, onChange, role = 'value', noun = 'component', only } = props\n const hostThemeDoc = useHostThemeDocument()\n const siteTheme = useAglynSiteTheme({ theme: hostThemeDoc })\n const themeScales = useMemo(\n () => buildStyleThemeScales(siteTheme as any) as unknown as Record<string, unknown>,\n [siteTheme],\n )\n const shown = useMemo(\n () =>\n declared.filter(\n (prop) => Boolean(prop?.name) && (!only || only.includes(prop.name)),\n ),\n [declared, only],\n )\n const fields = useMemo(\n () =>\n shown.map((prop) =>\n buildPropertyField(prop, {\n name: pathOf(prop.name),\n role,\n declared,\n valuePath: pathOf,\n noun,\n themeScales,\n }),\n ),\n [shown, role, declared, noun, themeScales],\n )\n const mediaFields = useMemo(\n () =>\n new Set(\n shown\n .filter((prop) => prop.type === 'image')\n .map((prop) => pathOf(prop.name)),\n ),\n [shown],\n )\n const [initial] = useState(() => ({ [VALUES_KEY]: values ?? {} }))\n return (\n <AttributeFieldsForm\n fields={fields}\n values={initial}\n mediaFields={mediaFields}\n onChange={(next) =>\n onChange(\n (next?.[VALUES_KEY] as Record<string, unknown> | undefined) ?? {},\n )\n }\n />\n )\n}\n\nexport default PropertyValuesForm\n"],"names":["canvas","components","EntityPickerContext","FieldComponentType","getKnownPluginInstallsVersion","ScreenLinkContext","subscribeKnownPluginInstalls","useAglynSiteTheme","FormRenderer","FormSpy","useFormApi","useHostThemeDocument","Grid","useContext","useEffect","useMemo","useRef","useState","useSyncExternalStore","useContentStable","MediaPickerContext","useInsertTokenOptions","buildStyleThemeScales","buildPropertyField","elementPropsComponentMapper","entityKindsForAttributes","resolveAttributeField","withNumericValueParse","TOKEN_TEXT_FIELD_COMPONENT","noop","undefined","serialize","values","JSON","stringify","AttributeFieldsFormTemplate","props","formFields","onValues","formApiRef","formApi","current","last","getState","form","onSubmit","event","preventDefault","noValidate","container","spacing","subscription","onChange","next","AttributeFieldsForm","fields","mediaFields","initialValues","onChangeRef","screens","labels","entityOptions","onPickMedia","options","insertOptions","labelContext","tokenLabelContext","pluginInstallsVersion","requestEntities","request","kind","wantsNodes","some","field","NODE_SELECT","nodeOptions","canvasNodes","toJSON","nodes","Object","entries","filter","id","Boolean","map","candidate","displayName","getSchema","componentId","text","children","trim","slice","value","label","sort","a","b","localeCompare","context","resolved","has","String","onBrowseMedia","change","Template","BoundTemplate","templateProps","componentMapper","FormTemplate","schema","VALUES_KEY","pathOf","name","PropertyValuesForm","declared","role","noun","only","hostThemeDoc","siteTheme","theme","themeScales","shown","prop","includes","valuePath","Set","type","initial"],"mappings":"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"}