@aglyn/shared-ui-jsx-forms 1.0.0-beta.143

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.
Files changed (150) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/package.json +52 -0
  4. package/src/index.d.ts +17 -0
  5. package/src/index.js +18 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/color-picker-tokens.d.ts +135 -0
  8. package/src/lib/components/color-picker-tokens.js +431 -0
  9. package/src/lib/components/color-picker-tokens.js.map +1 -0
  10. package/src/lib/components/color-picker.component.d.ts +64 -0
  11. package/src/lib/components/color-picker.component.js +322 -0
  12. package/src/lib/components/color-picker.component.js.map +1 -0
  13. package/src/lib/components/create-artifact-drawer.component.d.ts +100 -0
  14. package/src/lib/components/create-artifact-drawer.component.js +184 -0
  15. package/src/lib/components/create-artifact-drawer.component.js.map +1 -0
  16. package/src/lib/components/grid-form-template.component.d.ts +21 -0
  17. package/src/lib/components/grid-form-template.component.js +81 -0
  18. package/src/lib/components/grid-form-template.component.js.map +1 -0
  19. package/src/lib/components/icon-select.component.d.ts +52 -0
  20. package/src/lib/components/icon-select.component.js +453 -0
  21. package/src/lib/components/icon-select.component.js.map +1 -0
  22. package/src/lib/components/select.component.d.ts +58 -0
  23. package/src/lib/components/select.component.js +107 -0
  24. package/src/lib/components/select.component.js.map +1 -0
  25. package/src/lib/components/switch.component.d.ts +38 -0
  26. package/src/lib/components/switch.component.js +76 -0
  27. package/src/lib/components/switch.component.js.map +1 -0
  28. package/src/lib/components/text-field.component.d.ts +45 -0
  29. package/src/lib/components/text-field.component.js +77 -0
  30. package/src/lib/components/text-field.component.js.map +1 -0
  31. package/src/lib/components/textarea.component.d.ts +45 -0
  32. package/src/lib/components/textarea.component.js +61 -0
  33. package/src/lib/components/textarea.component.js.map +1 -0
  34. package/src/lib/components/toggle-button.component.d.ts +27 -0
  35. package/src/lib/components/toggle-button.component.js +116 -0
  36. package/src/lib/components/toggle-button.component.js.map +1 -0
  37. package/src/lib/constants/component-mappers.d.ts +42 -0
  38. package/src/lib/constants/component-mappers.js +70 -0
  39. package/src/lib/constants/component-mappers.js.map +1 -0
  40. package/src/lib/constants/dynamic-fields.d.ts +45 -0
  41. package/src/lib/constants/dynamic-fields.js +65 -0
  42. package/src/lib/constants/dynamic-fields.js.map +1 -0
  43. package/src/lib/constants/field-configurations.d.ts +53 -0
  44. package/src/lib/constants/field-configurations.js +121 -0
  45. package/src/lib/constants/field-configurations.js.map +1 -0
  46. package/src/lib/constants/flags.d.ts +72 -0
  47. package/src/lib/constants/flags.js +69 -0
  48. package/src/lib/constants/flags.js.map +1 -0
  49. package/src/lib/hocs/with-grid-item.d.ts +25 -0
  50. package/src/lib/hocs/with-grid-item.js +48 -0
  51. package/src/lib/hocs/with-grid-item.js.map +1 -0
  52. package/src/lib/jsx-forms.d.ts +41 -0
  53. package/src/lib/jsx-forms.js +42 -0
  54. package/src/lib/jsx-forms.js.map +1 -0
  55. package/src/lib/mapper/breakpoint-span.d.ts +73 -0
  56. package/src/lib/mapper/breakpoint-span.js +346 -0
  57. package/src/lib/mapper/breakpoint-span.js.map +1 -0
  58. package/src/lib/mapper/checkbox.d.ts +43 -0
  59. package/src/lib/mapper/checkbox.js +111 -0
  60. package/src/lib/mapper/checkbox.js.map +1 -0
  61. package/src/lib/mapper/css-border.d.ts +113 -0
  62. package/src/lib/mapper/css-border.js +410 -0
  63. package/src/lib/mapper/css-border.js.map +1 -0
  64. package/src/lib/mapper/css-dimension.d.ts +89 -0
  65. package/src/lib/mapper/css-dimension.js +327 -0
  66. package/src/lib/mapper/css-dimension.js.map +1 -0
  67. package/src/lib/mapper/css-gradient.d.ts +110 -0
  68. package/src/lib/mapper/css-gradient.js +720 -0
  69. package/src/lib/mapper/css-gradient.js.map +1 -0
  70. package/src/lib/mapper/data-table.d.ts +23 -0
  71. package/src/lib/mapper/data-table.js +296 -0
  72. package/src/lib/mapper/data-table.js.map +1 -0
  73. package/src/lib/mapper/date-picker.d.ts +26 -0
  74. package/src/lib/mapper/date-picker.js +69 -0
  75. package/src/lib/mapper/date-picker.js.map +1 -0
  76. package/src/lib/mapper/dual-list-select.d.ts +115 -0
  77. package/src/lib/mapper/dual-list-select.js +353 -0
  78. package/src/lib/mapper/dual-list-select.js.map +1 -0
  79. package/src/lib/mapper/field-array.d.ts +71 -0
  80. package/src/lib/mapper/field-array.js +326 -0
  81. package/src/lib/mapper/field-array.js.map +1 -0
  82. package/src/lib/mapper/form-field-grid.d.ts +155 -0
  83. package/src/lib/mapper/form-field-grid.js +194 -0
  84. package/src/lib/mapper/form-field-grid.js.map +1 -0
  85. package/src/lib/mapper/index.d.ts +50 -0
  86. package/src/lib/mapper/index.js +49 -0
  87. package/src/lib/mapper/index.js.map +1 -0
  88. package/src/lib/mapper/multiple-choice-list.d.ts +32 -0
  89. package/src/lib/mapper/multiple-choice-list.js +105 -0
  90. package/src/lib/mapper/multiple-choice-list.js.map +1 -0
  91. package/src/lib/mapper/plain-text.d.ts +31 -0
  92. package/src/lib/mapper/plain-text.js +48 -0
  93. package/src/lib/mapper/plain-text.js.map +1 -0
  94. package/src/lib/mapper/preset-choice.d.ts +106 -0
  95. package/src/lib/mapper/preset-choice.js +267 -0
  96. package/src/lib/mapper/preset-choice.js.map +1 -0
  97. package/src/lib/mapper/radio.d.ts +40 -0
  98. package/src/lib/mapper/radio.js +122 -0
  99. package/src/lib/mapper/radio.js.map +1 -0
  100. package/src/lib/mapper/select.d.ts +60 -0
  101. package/src/lib/mapper/select.js +203 -0
  102. package/src/lib/mapper/select.js.map +1 -0
  103. package/src/lib/mapper/slider.d.ts +45 -0
  104. package/src/lib/mapper/slider.js +119 -0
  105. package/src/lib/mapper/slider.js.map +1 -0
  106. package/src/lib/mapper/stored-field-value.d.ts +23 -0
  107. package/src/lib/mapper/stored-field-value.js +29 -0
  108. package/src/lib/mapper/stored-field-value.js.map +1 -0
  109. package/src/lib/mapper/sub-form.d.ts +39 -0
  110. package/src/lib/mapper/sub-form.js +108 -0
  111. package/src/lib/mapper/sub-form.js.map +1 -0
  112. package/src/lib/mapper/switch.d.ts +47 -0
  113. package/src/lib/mapper/switch.js +93 -0
  114. package/src/lib/mapper/switch.js.map +1 -0
  115. package/src/lib/mapper/tabs.d.ts +34 -0
  116. package/src/lib/mapper/tabs.js +64 -0
  117. package/src/lib/mapper/tabs.js.map +1 -0
  118. package/src/lib/mapper/text-field.d.ts +33 -0
  119. package/src/lib/mapper/text-field.js +88 -0
  120. package/src/lib/mapper/text-field.js.map +1 -0
  121. package/src/lib/mapper/textarea.d.ts +31 -0
  122. package/src/lib/mapper/textarea.js +68 -0
  123. package/src/lib/mapper/textarea.js.map +1 -0
  124. package/src/lib/mapper/theme-scale.d.ts +79 -0
  125. package/src/lib/mapper/theme-scale.js +162 -0
  126. package/src/lib/mapper/theme-scale.js.map +1 -0
  127. package/src/lib/mapper/time-picker.d.ts +26 -0
  128. package/src/lib/mapper/time-picker.js +69 -0
  129. package/src/lib/mapper/time-picker.js.map +1 -0
  130. package/src/lib/mapper/types.d.ts +43 -0
  131. package/src/lib/mapper/types.js +22 -0
  132. package/src/lib/mapper/types.js.map +1 -0
  133. package/src/lib/mapper/validation-error.d.ts +24 -0
  134. package/src/lib/mapper/validation-error.js +24 -0
  135. package/src/lib/mapper/validation-error.js.map +1 -0
  136. package/src/lib/mapper/wizard.d.ts +21 -0
  137. package/src/lib/mapper/wizard.js +203 -0
  138. package/src/lib/mapper/wizard.js.map +1 -0
  139. package/src/lib/types.d.ts +19 -0
  140. package/src/lib/types.js +18 -0
  141. package/src/lib/types.js.map +1 -0
  142. package/src/lib/utils/option-is-equal-to-value.d.ts +20 -0
  143. package/src/lib/utils/option-is-equal-to-value.js +21 -0
  144. package/src/lib/utils/option-is-equal-to-value.js.map +1 -0
  145. package/src/lib/utils/validation-message.d.ts +22 -0
  146. package/src/lib/utils/validation-message.js +24 -0
  147. package/src/lib/utils/validation-message.js.map +1 -0
  148. package/src/lib/vendor/data-driven-forms.d.ts +33 -0
  149. package/src/lib/vendor/data-driven-forms.js +29 -0
  150. package/src/lib/vendor/data-driven-forms.js.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx-forms/src/lib/components/create-artifact-drawer.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 { ICON_VARIANT_CLOSE } from '@aglyn/shared-data-enums'\nimport { Container, MdiIcon, SrOnly } from '@aglyn/shared-ui-jsx'\nimport { NavigationDrawerComponent } from '@aglyn/shared-ui-jsx/components/navigation-drawer.component'\nimport {\n Box,\n Button,\n FormControl,\n Grid,\n IconButton,\n Typography,\n} from '@mui/material'\nimport { forwardRef, type ReactNode } from 'react'\nimport {\n FormRenderer,\n FormSpy,\n type FormTemplateRenderProps,\n useFormApi,\n} from '../vendor/data-driven-forms'\nimport { simpleComponentMapper } from '../constants/component-mappers'\n\n/**\n * THE naming step in front of Create (AGL-700), shared by every console list\n * surface that creates a record.\n *\n * ## Why it lives in a library\n *\n * It began in `apps/console`, which put it out of reach of the console pages\n * that plugins ship — a plugin's console card cannot import from the app that\n * renders it. So a plugin adding a create button had two options, both bad:\n * an inline form stacked above its table, or a second drawer that looks\n * almost but not quite like this one. Both are how a console comes to have\n * three ways of creating a record.\n *\n * The console keeps a thin wrapper at its old path so its four existing call\n * sites are untouched; it passes its own auth form template through\n * {@link CreateArtifactDrawerProps.FormTemplate}.\n *\n * A drawer rather than a dialog on purpose: creating is a drawer, picking is\n * a dialog (AGL-699). Editing is neither — it is the record's own page.\n */\nexport interface CreateArtifactDrawerProps {\n open: boolean\n onClose: () => void\n /** Drawer heading, e.g. \"Create new component\". */\n title: string\n /** Receives the collected field values; closing is the caller's job. */\n onSubmit: (values: Record<string, any>) => void | Promise<void>\n /** Extra fields appended after name and description. */\n extraFields?: any[]\n /** Rendered under the form when a submit fails. */\n errorSlot?: ReactNode\n /**\n * Whether to offer the shared Description box (AGL-2498).\n *\n * True for every artifact whose document stores one. Content collections do\n * not: `/api/hosts/collections` filters `data` through a per-kind allowlist\n * of `displayName` + `slug`, so a description typed here would be dropped\n * without a word. A field the writer silently discards is worse than a field\n * that was never offered.\n */\n includeDescription?: boolean\n /**\n * The form's own chrome — the submit button and how the fields are laid out.\n *\n * Injectable because the console's version renders an auth-aware template\n * that lives in the app and depends on the console's session hook. Defaults\n * to {@link ArtifactFormTemplate}, which is the same layout without that\n * dependency.\n */\n FormTemplate?: any\n /** Label on the submit button. */\n submitLabel?: string\n}\n\n/**\n * The default chrome: the fields in a grid and one submit button.\n *\n * No Cancel button of its own — the drawer's app bar already carries one, and\n * a second Cancel inside the form is the shape a reader has to think about.\n */\nexport const ArtifactFormTemplate = forwardRef<any, FormTemplateRenderProps>(\n (props, ref) => {\n const { formFields, schema, ...rest } = props\n const { handleSubmit } = useFormApi()\n return (\n <form ref={ref} onSubmit={handleSubmit} noValidate {...rest}>\n {schema.title}\n <Grid spacing={2} container>\n {formFields as any}\n </Grid>\n <FormSpy>\n {({ submitting }) => (\n <Box sx={{ mt: 2 }}>\n <FormControl margin=\"normal\" fullWidth>\n <Button\n color=\"primary\"\n disabled={submitting}\n type=\"submit\"\n variant=\"contained\"\n fullWidth\n >\n {(schema as { submitLabel?: string }).submitLabel ?? 'Next'}\n </Button>\n </FormControl>\n </Box>\n )}\n </FormSpy>\n </form>\n )\n },\n)\nArtifactFormTemplate.displayName = 'ArtifactFormTemplate'\n;(ArtifactFormTemplate as any).aglyn = true\n\nexport function CreateArtifactDrawer(props: CreateArtifactDrawerProps) {\n const {\n open,\n onClose,\n title,\n onSubmit,\n extraFields,\n errorSlot,\n includeDescription = true,\n FormTemplate = ArtifactFormTemplate,\n submitLabel,\n } = props\n const schema = {\n fields: [\n ...(includeDescription\n ? BASE_FIELDS\n : BASE_FIELDS.filter((field) => field.name !== 'description')),\n ...(extraFields ?? []),\n ],\n ...(submitLabel ? { submitLabel } : {}),\n }\n return (\n <NavigationDrawerComponent\n open={open}\n anchor=\"right\"\n variant=\"temporary\"\n onClose={onClose}\n AppBarProps={{ color: 'surface' }}\n appBarLeft={\n <>\n <IconButton\n color=\"inherit\"\n edge=\"start\"\n onClick={onClose}\n sx={{ mr: 2 }}\n >\n <MdiIcon path={ICON_VARIANT_CLOSE.path} />\n <SrOnly>close drawer</SrOnly>\n </IconButton>\n <Typography variant=\"h6\" component=\"div\">\n {title}\n </Typography>\n </>\n }\n appBarRight={\n <Button variant=\"outlined\" color=\"inherit\" onClick={onClose}>\n {'Cancel'}\n </Button>\n }\n >\n <Container gutterY>\n <FormRenderer\n FormTemplate={FormTemplate}\n componentMapper={simpleComponentMapper}\n onSubmit={onSubmit}\n schema={schema}\n subscription={{ values: true }}\n clearOnUnmount\n />\n {errorSlot}\n </Container>\n </NavigationDrawerComponent>\n )\n}\n\n/**\n * Same shape and limits the layouts drawer has used since AGL-473, so the\n * creates across the console validate identically.\n */\nexport const BASE_FIELDS = [\n {\n component: 'text-field',\n name: 'displayName',\n helperText: 'Friendly name for internal reference',\n type: 'text',\n label: 'Display name',\n isRequired: true,\n validate: [\n { type: 'required', message: 'Provide a display name' },\n {\n type: 'max-length',\n threshold: 25,\n message: 'Must not exceed 25 characters',\n },\n ],\n },\n {\n component: 'textarea',\n name: 'description',\n label: 'Description',\n helperText: 'Brief description for internal reference',\n validate: [\n {\n type: 'max-length',\n threshold: 80,\n message: 'Must not exceed 80 characters',\n },\n ],\n },\n]\n\nCreateArtifactDrawer.displayName = 'CreateArtifactDrawer'\n\nexport default CreateArtifactDrawer\n"],"names":["ICON_VARIANT_CLOSE","Container","MdiIcon","SrOnly","NavigationDrawerComponent","Box","Button","FormControl","Grid","IconButton","Typography","forwardRef","FormRenderer","FormSpy","useFormApi","simpleComponentMapper","ArtifactFormTemplate","props","ref","formFields","schema","rest","handleSubmit","form","onSubmit","noValidate","title","spacing","container","submitting","sx","mt","margin","fullWidth","color","disabled","type","variant","submitLabel","displayName","aglyn","CreateArtifactDrawer","open","onClose","extraFields","errorSlot","includeDescription","FormTemplate","fields","BASE_FIELDS","filter","field","name","anchor","AppBarProps","appBarLeft","edge","onClick","mr","path","component","appBarRight","gutterY","componentMapper","subscription","values","clearOnUnmount","helperText","label","isRequired","validate","message","threshold"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type FormTemplateRenderProps } from '../vendor/data-driven-forms';
18
+ export interface GridFormTemplateProps extends FormTemplateRenderProps {
19
+ }
20
+ export declare const GridFormTemplateComponent: import("react").ForwardRefExoticComponent<Omit<GridFormTemplateProps, "ref"> & import("react").RefAttributes<any>>;
21
+ export default GridFormTemplateComponent;
@@ -0,0 +1,81 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { mdiContentSave } from "@aglyn/shared-data-mdi";
18
+ import { MdiIcon } from "@aglyn/shared-ui-jsx";
19
+ import { Box, Button, FormControl, Grid } from "@mui/material";
20
+ import { forwardRef } from "react";
21
+ import { FormSpy, useFormApi } from "../vendor/data-driven-forms.js";
22
+ export const GridFormTemplateComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
23
+ const { formFields, schema } = props;
24
+ const { handleSubmit, onCancel } = useFormApi();
25
+ return /*#__PURE__*/ _jsxs("form", {
26
+ ref: ref,
27
+ onSubmit: handleSubmit,
28
+ noValidate: true,
29
+ children: [
30
+ schema.title,
31
+ /*#__PURE__*/ _jsx(Grid, {
32
+ spacing: 2,
33
+ container: true,
34
+ children: formFields
35
+ }),
36
+ /*#__PURE__*/ _jsx(FormSpy, {
37
+ children: ({ submitting, validating, pristine, valid })=>/*#__PURE__*/ _jsxs(Box, {
38
+ sx: {
39
+ mt: 2
40
+ },
41
+ children: [
42
+ /*#__PURE__*/ _jsx(FormControl, {
43
+ margin: "normal",
44
+ fullWidth: true,
45
+ children: /*#__PURE__*/ _jsx(Button, {
46
+ variant: "outlined",
47
+ onClick: onCancel,
48
+ disabled: submitting || validating,
49
+ fullWidth: true,
50
+ children: "Cancel"
51
+ })
52
+ }),
53
+ /*#__PURE__*/ _jsx(FormControl, {
54
+ margin: "normal",
55
+ fullWidth: true,
56
+ children: /*#__PURE__*/ _jsx(Button, {
57
+ color: "primary",
58
+ disabled: submitting || !valid || pristine,
59
+ startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
60
+ path: mdiContentSave.path
61
+ }),
62
+ style: {
63
+ marginRight: 8
64
+ },
65
+ type: "submit",
66
+ variant: "contained",
67
+ fullWidth: true,
68
+ children: "Continue"
69
+ })
70
+ })
71
+ ]
72
+ })
73
+ })
74
+ ]
75
+ });
76
+ });
77
+ GridFormTemplateComponent.displayName = 'GridFormTemplateComponent';
78
+ GridFormTemplateComponent.aglyn = true;
79
+ export default GridFormTemplateComponent;
80
+
81
+ //# sourceMappingURL=grid-form-template.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx-forms/src/lib/components/grid-form-template.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\nimport { mdiContentSave } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\n\nimport { Box, Button, FormControl, Grid } from '@mui/material'\nimport { forwardRef } from 'react'\n\nimport {\n FormSpy,\n type FormTemplateRenderProps,\n useFormApi,\n} from '../vendor/data-driven-forms'\n\nexport interface GridFormTemplateProps extends FormTemplateRenderProps {}\n\nexport const GridFormTemplateComponent = forwardRef<any, GridFormTemplateProps>(\n (props, ref) => {\n const { formFields, schema } = props\n const { handleSubmit, onCancel } = useFormApi()\n return (\n <form ref={ref} onSubmit={handleSubmit} noValidate>\n {schema.title}\n <Grid spacing={2} container>\n {formFields as any}\n </Grid>\n <FormSpy>\n {({ submitting, validating, pristine, valid }) => (\n <Box sx={{\n mt: 2\n }}>\n <FormControl margin=\"normal\" fullWidth>\n <Button\n variant=\"outlined\"\n onClick={onCancel}\n disabled={submitting || validating}\n fullWidth\n >\n Cancel\n </Button>\n </FormControl>\n <FormControl margin=\"normal\" fullWidth>\n <Button\n color=\"primary\"\n disabled={submitting || !valid || pristine}\n startIcon={<MdiIcon path={mdiContentSave.path} />}\n style={{ marginRight: 8 }}\n type=\"submit\"\n variant=\"contained\"\n fullWidth\n >\n Continue\n </Button>\n </FormControl>\n </Box>\n )}\n </FormSpy>\n </form>\n );\n },\n)\nGridFormTemplateComponent.displayName = 'GridFormTemplateComponent'\nGridFormTemplateComponent.aglyn = true\nexport default GridFormTemplateComponent\n"],"names":["mdiContentSave","MdiIcon","Box","Button","FormControl","Grid","forwardRef","FormSpy","useFormApi","GridFormTemplateComponent","props","ref","formFields","schema","handleSubmit","onCancel","form","onSubmit","noValidate","title","spacing","container","submitting","validating","pristine","valid","sx","mt","margin","fullWidth","variant","onClick","disabled","color","startIcon","path","style","marginRight","type","displayName","aglyn"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,cAAc,QAAQ,yBAAwB;AACvD,SAASC,OAAO,QAAQ,uBAAsB;AAE9C,SAASC,GAAG,EAAEC,MAAM,EAAEC,WAAW,EAAEC,IAAI,QAAQ,gBAAe;AAC9D,SAASC,UAAU,QAAQ,QAAO;AAElC,SACEC,OAAO,EAEPC,UAAU,QACL,iCAA6B;AAIpC,OAAO,MAAMC,0CAA4BH,WACvC,CAACI,OAAOC;IACN,MAAM,EAAEC,UAAU,EAAEC,MAAM,EAAE,GAAGH;IAC/B,MAAM,EAAEI,YAAY,EAAEC,QAAQ,EAAE,GAAGP;IACnC,qBACE,MAACQ;QAAKL,KAAKA;QAAKM,UAAUH;QAAcI,UAAU;;YAC/CL,OAAOM,KAAK;0BACb,KAACd;gBAAKe,SAAS;gBAAGC,SAAS;0BACxBT;;0BAEH,KAACL;0BACE,CAAC,EAAEe,UAAU,EAAEC,UAAU,EAAEC,QAAQ,EAAEC,KAAK,EAAE,iBAC3C,MAACvB;wBAAIwB,IAAI;4BACPC,IAAI;wBACN;;0CACE,KAACvB;gCAAYwB,QAAO;gCAASC,SAAS;0CACpC,cAAA,KAAC1B;oCACC2B,SAAQ;oCACRC,SAAShB;oCACTiB,UAAUV,cAAcC;oCACxBM,SAAS;8CACV;;;0CAIH,KAACzB;gCAAYwB,QAAO;gCAASC,SAAS;0CACpC,cAAA,KAAC1B;oCACC8B,OAAM;oCACND,UAAUV,cAAc,CAACG,SAASD;oCAClCU,yBAAW,KAACjC;wCAAQkC,MAAMnC,eAAemC,IAAI;;oCAC7CC,OAAO;wCAAEC,aAAa;oCAAE;oCACxBC,MAAK;oCACLR,SAAQ;oCACRD,SAAS;8CACV;;;;;;;;AASf,GACD;AACDpB,0BAA0B8B,WAAW,GAAG;AACxC9B,0BAA0B+B,KAAK,GAAG;AAClC,eAAe/B,0BAAyB"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type HTMLAttributes } from 'react';
18
+ declare const classKeys: import("@aglyn/shared-ui-theme").ClassKeyMap<"button" | "label" | "collapse" | "icon" | "root" | "selected" | "opener" | "preview" | "collapseInner" | "gridListWrapper" | "gridList", "AglynIconSelect">;
19
+ export interface IconSelectProps extends HTMLAttributes<HTMLDivElement> {
20
+ initialValue?: string;
21
+ classes?: Partial<typeof classKeys>;
22
+ }
23
+ export interface IconSelectControlProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
24
+ /** Picked icon id, or empty for "nothing chosen yet". */
25
+ value?: string;
26
+ onChange?: (iconId: string) => void;
27
+ label?: JSX.Node;
28
+ helperText?: JSX.Node;
29
+ GridListProps?: Record<string, unknown>;
30
+ classes?: Partial<typeof classKeys>;
31
+ }
32
+ /**
33
+ * The picker itself, with no form library attached (AGL-1193).
34
+ *
35
+ * Extracted so surfaces outside the designer can offer the SAME picker
36
+ * rather than growing a second one: the console sets a reusable
37
+ * component's icon from a plain dialog and a plain detail form, neither of
38
+ * which runs inside a data-driven-forms tree. The field below is now a
39
+ * thin adapter over this, so the two can't drift.
40
+ */
41
+ export declare const IconSelectControl: import("react").ForwardRefExoticComponent<IconSelectControlProps & import("react").RefAttributes<any>>;
42
+ /**
43
+ * The data-driven-forms field: everything form-shaped (validation message,
44
+ * helper/description precedence, the final-form input) resolved here, and
45
+ * the picking itself delegated to {@link IconSelectControl}.
46
+ *
47
+ * Sits in the same {@link FormFieldGrid} every other field does, so the corner
48
+ * controls a schema asks for — the help tip, the opt-in clear, a caller's own
49
+ * — are where they are on every other field rather than silently dropped.
50
+ */
51
+ declare const IconSelectComponent: import("react").ForwardRefExoticComponent<IconSelectProps & import("react").RefAttributes<any>>;
52
+ export default IconSelectComponent;
@@ -0,0 +1,453 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ /**
5
+ * @license
6
+ * Copyright 2026 Aglyn LLC
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */ import { DEFAULT_ICON, mdiCheck, mdiChevronDown, mdiChevronUp } from "@aglyn/shared-data-mdi";
20
+ import { CardListItem, MdiIcon } from "@aglyn/shared-ui-jsx";
21
+ import { useMdiIconsFuzzy } from "@aglyn/shared-ui-jsx/hooks/mdi-icon/use-mdi-icons-fuzzy";
22
+ import { GridList } from "@aglyn/shared-ui-jsx/components/grid-list";
23
+ import { generateComponentClassKeys, styled } from "@aglyn/shared-ui-theme";
24
+ import { useDebouncedCallback } from "@aglyn/shared-util-vendor/use-debounce";
25
+ import { Box, Button, ButtonBase, Collapse, Grid, Link as MuiLink, TextField as MuiTextField, Tooltip, Typography } from "@mui/material";
26
+ import { forwardRef, useCallback, useEffect, useMemo, useState } from "react";
27
+ import FormFieldGrid, { buildFieldClear } from "../mapper/form-field-grid.js";
28
+ import { validationMessage } from "../utils/validation-message.js";
29
+ import { useFieldApi } from "../vendor/data-driven-forms.js";
30
+ const iconUnset = _extends({}, DEFAULT_ICON, {
31
+ id: null,
32
+ name: '(none)'
33
+ });
34
+ const classKeys = generateComponentClassKeys('AglynIconSelect', [
35
+ 'root',
36
+ 'button',
37
+ 'icon',
38
+ 'label',
39
+ 'selected',
40
+ 'opener',
41
+ 'preview',
42
+ 'collapse',
43
+ 'collapseInner',
44
+ 'gridListWrapper',
45
+ 'gridList'
46
+ ]);
47
+ const StyledCollapse = styled(Collapse, {
48
+ name: 'AglynIconSelectCollapse'
49
+ })(({ theme })=>({
50
+ '& .MuiCollapse-wrapper': {
51
+ height: 412
52
+ },
53
+ '& .MuiCollapse-wrapperInner': {
54
+ paddingTop: theme.spacing(1),
55
+ display: 'flex',
56
+ flexDirection: 'column',
57
+ flexGrow: 1,
58
+ flexShrink: 0,
59
+ alignSelf: 'stretch'
60
+ }
61
+ }));
62
+ const GridListWrapper = styled('div', {
63
+ name: 'AglynIconSelectListWrapper'
64
+ })(({ theme })=>{
65
+ const tv = theme.vars || theme;
66
+ return {
67
+ height: '100%',
68
+ marginTop: theme.spacing(1),
69
+ border: `1px solid ${tv.palette.divider}`,
70
+ borderRadius: theme.shape.borderRadius,
71
+ [`& .${classKeys.gridList}`]: {
72
+ padding: theme.spacing(1)
73
+ }
74
+ };
75
+ });
76
+ /**
77
+ * The picker itself, with no form library attached (AGL-1193).
78
+ *
79
+ * Extracted so surfaces outside the designer can offer the SAME picker
80
+ * rather than growing a second one: the console sets a reusable
81
+ * component's icon from a plain dialog and a plain detail form, neither of
82
+ * which runs inside a data-driven-forms tree. The field below is now a
83
+ * thin adapter over this, so the two can't drift.
84
+ */ export const IconSelectControl = /*#__PURE__*/ forwardRef((props, ref)=>{
85
+ const { value: currentValue = '', onChange, label, helperText: helperContent, GridListProps } = props, rest = _object_without_properties_loose(props, [
86
+ "value",
87
+ "onChange",
88
+ "label",
89
+ "helperText",
90
+ "GridListProps"
91
+ ]);
92
+ const [open, setOpen] = useState(false);
93
+ const [icons, allIcons, applyFilter, clearFilter] = useMdiIconsFuzzy();
94
+ /**
95
+ * The DRAFT pick (AGL-2486). Picking is two steps: clicking an icon only
96
+ * moves this, and `Choose` is the one thing that reaches `onChange` and
97
+ * therefore the canvas.
98
+ */ const [selected, setSelected] = useState(currentValue);
99
+ /**
100
+ * Re-seeded from the live value whenever the panel opens or the value
101
+ * changes underneath. Without this an abandoned pick survived the panel
102
+ * being closed, so the NEXT `Choose` applied an icon the author had
103
+ * already walked away from.
104
+ */ useEffect(()=>{
105
+ setSelected(currentValue);
106
+ }, [
107
+ currentValue,
108
+ open
109
+ ]);
110
+ // Rendering all ~6,600 icons at once froze the panel (AGL-340): cap the
111
+ // grid and let search narrow the rest.
112
+ const MAX_RENDERED_ICONS = 240;
113
+ const visibleIcons = useMemo(()=>icons.length > MAX_RENDERED_ICONS ? icons.slice(0, MAX_RENDERED_ICONS) : icons, [
114
+ icons
115
+ ]);
116
+ const [currentIcon, selectedIcon] = useMemo(()=>{
117
+ const findIcon = (id)=>allIcons.find((icon)=>icon.id === id);
118
+ const currentIcon = currentValue && findIcon(currentValue) || iconUnset;
119
+ const selectedIcon = selected && findIcon(selected) || iconUnset;
120
+ return [
121
+ currentIcon,
122
+ selectedIcon
123
+ ];
124
+ }, [
125
+ currentValue,
126
+ selected,
127
+ allIcons
128
+ ]);
129
+ const handleButtonClick = useCallback(()=>{
130
+ setOpen((prev)=>!prev);
131
+ }, [
132
+ setOpen
133
+ ]);
134
+ /** Nothing to confirm until the draft differs from what is applied. */ const hasPendingPick = selected !== currentValue;
135
+ const handleCancelButtonClick = useCallback(()=>{
136
+ // Closing re-seeds the draft (the effect above), so this only has to
137
+ // close — but it says so explicitly, because "cancel leaves the canvas
138
+ // alone" is the guarantee, not an emergent property of an effect.
139
+ setSelected(currentValue);
140
+ setOpen(false);
141
+ }, [
142
+ currentValue
143
+ ]);
144
+ const handleChooseButtonClick = useCallback(()=>{
145
+ if (selected === currentValue) return;
146
+ onChange == null ? void 0 : onChange(selected);
147
+ setOpen(false);
148
+ }, [
149
+ onChange,
150
+ selected,
151
+ currentValue
152
+ ]);
153
+ const updateFilter = useDebouncedCallback((value)=>{
154
+ if (value) {
155
+ applyFilter(value);
156
+ } else {
157
+ clearFilter();
158
+ }
159
+ }, 300);
160
+ const handleFilterChange = useCallback((e)=>{
161
+ const target = e.currentTarget;
162
+ if (target && target.value) {
163
+ updateFilter(target.value);
164
+ } else {
165
+ updateFilter();
166
+ }
167
+ }, [
168
+ updateFilter
169
+ ]);
170
+ const handleItemClick = useCallback((e, item)=>{
171
+ setSelected(item.id);
172
+ }, [
173
+ setSelected
174
+ ]);
175
+ const renderItemContent = useCallback(function RenderItemContent(item, key) {
176
+ var _item_id;
177
+ const isSelected = Boolean(selected) && selected === item.id;
178
+ return /*#__PURE__*/ _jsx(Tooltip, {
179
+ title: item.name,
180
+ disableInteractive: true,
181
+ enterDelay: 375,
182
+ enterNextDelay: 745,
183
+ children: /*#__PURE__*/ _jsxs(CardListItem, {
184
+ item: item,
185
+ selected: isSelected,
186
+ // A real toggle, so the pick is announced and not only
187
+ // painted (AGL-2486).
188
+ role: "button",
189
+ "aria-pressed": isSelected,
190
+ onClick: (e)=>handleItemClick(e, item),
191
+ children: [
192
+ /*#__PURE__*/ _jsx("div", {
193
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
194
+ fontSize: "medium",
195
+ path: item.path
196
+ })
197
+ }),
198
+ isSelected ? // Belt and braces on the fill: a tick reads as "picked"
199
+ // even where the tint is subtle, and gives the state
200
+ // something to assert against.
201
+ /*#__PURE__*/ _jsx(Box, {
202
+ "data-aglyn-icon-selected": "",
203
+ sx: {
204
+ position: 'absolute',
205
+ top: 2,
206
+ right: 2,
207
+ lineHeight: 0,
208
+ fontSize: 14,
209
+ borderRadius: '50%',
210
+ bgcolor: 'primary.contrastText',
211
+ color: 'primary.main'
212
+ },
213
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
214
+ fontSize: "inherit",
215
+ path: mdiCheck.path
216
+ })
217
+ }) : null
218
+ ]
219
+ })
220
+ }, (_item_id = item.id) != null ? _item_id : key);
221
+ }, [
222
+ selected,
223
+ handleItemClick
224
+ ]);
225
+ return /*#__PURE__*/ _jsxs(Grid, {
226
+ ref: ref,
227
+ container: true,
228
+ children: [
229
+ /*#__PURE__*/ _jsxs(Grid, {
230
+ spacing: 2,
231
+ container: true,
232
+ sx: {
233
+ alignItems: 'center'
234
+ },
235
+ children: [
236
+ /*#__PURE__*/ _jsx(Grid, {
237
+ children: /*#__PURE__*/ _jsx(ButtonBase, {
238
+ onClick: handleButtonClick,
239
+ disableRipple: true,
240
+ sx: (theme)=>({
241
+ fontSize: theme.typography.pxToRem(38)
242
+ }),
243
+ title: currentIcon.name || 'Choose icon',
244
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
245
+ fontSize: "inherit",
246
+ path: currentIcon.path
247
+ })
248
+ })
249
+ }),
250
+ /*#__PURE__*/ _jsxs(Grid, {
251
+ size: {
252
+ sm: "grow"
253
+ },
254
+ children: [
255
+ /*#__PURE__*/ _jsx(Typography, {
256
+ component: "div",
257
+ variant: "caption",
258
+ children: label
259
+ }),
260
+ /*#__PURE__*/ _jsxs(MuiLink, {
261
+ onClick: handleButtonClick,
262
+ variant: "button",
263
+ component: "button",
264
+ color: "primary",
265
+ sx: {
266
+ display: 'flex',
267
+ flexDirection: 'row',
268
+ justifyContent: 'flex-start'
269
+ },
270
+ children: [
271
+ /*#__PURE__*/ _jsx("span", {
272
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
273
+ fontSize: "inherit",
274
+ path: open ? mdiChevronUp.path : mdiChevronDown.path
275
+ })
276
+ }),
277
+ /*#__PURE__*/ _jsx("span", {
278
+ children: currentIcon.name
279
+ })
280
+ ]
281
+ })
282
+ ]
283
+ })
284
+ ]
285
+ }),
286
+ /*#__PURE__*/ _jsx(Grid, {
287
+ size: 12,
288
+ children: /*#__PURE__*/ _jsxs(StyledCollapse, {
289
+ in: open,
290
+ children: [
291
+ /*#__PURE__*/ _jsxs(Grid, {
292
+ spacing: 2,
293
+ container: true,
294
+ sx: {
295
+ alignItems: "center"
296
+ },
297
+ children: [
298
+ /*#__PURE__*/ _jsx(Grid, {
299
+ size: 12,
300
+ children: /*#__PURE__*/ _jsx(MuiTextField, {
301
+ onChange: handleFilterChange,
302
+ placeholder: "Search icons...",
303
+ size: "small",
304
+ helperText: helperContent,
305
+ fullWidth: true
306
+ })
307
+ }),
308
+ /*#__PURE__*/ _jsxs(Grid, {
309
+ size: "grow",
310
+ children: [
311
+ /*#__PURE__*/ _jsxs(Typography, {
312
+ component: "div",
313
+ variant: "body2",
314
+ children: [
315
+ "Selected icon: ",
316
+ /*#__PURE__*/ _jsx("b", {
317
+ children: selectedIcon.name
318
+ })
319
+ ]
320
+ }),
321
+ /*#__PURE__*/ _jsx(Typography, {
322
+ component: "div",
323
+ variant: "caption",
324
+ color: "text.secondary",
325
+ children: hasPendingPick ? `Not applied yet — press Choose to replace ${currentIcon.name}.` : 'Pick an icon, then press Choose to apply it.'
326
+ })
327
+ ]
328
+ }),
329
+ /*#__PURE__*/ _jsx(Grid, {
330
+ children: /*#__PURE__*/ _jsx(Button, {
331
+ color: "inherit",
332
+ onClick: handleCancelButtonClick,
333
+ children: "Cancel"
334
+ })
335
+ }),
336
+ /*#__PURE__*/ _jsx(Grid, {
337
+ children: /*#__PURE__*/ _jsx(Button, {
338
+ color: "primary",
339
+ disabled: !hasPendingPick,
340
+ onClick: handleChooseButtonClick,
341
+ variant: "contained",
342
+ children: "Choose"
343
+ })
344
+ })
345
+ ]
346
+ }),
347
+ /*#__PURE__*/ _jsxs(GridListWrapper, {
348
+ children: [
349
+ /*#__PURE__*/ _jsx(GridList, _extends({
350
+ GridContainerProps: {
351
+ spacing: 1
352
+ },
353
+ GridItemProps: {
354
+ size: {
355
+ xs: 2
356
+ }
357
+ },
358
+ ListWrapperProps: {
359
+ className: classKeys.gridList
360
+ },
361
+ items: visibleIcons,
362
+ renderItemContent: renderItemContent
363
+ }, GridListProps)),
364
+ icons.length > visibleIcons.length ? /*#__PURE__*/ _jsx(Typography, {
365
+ variant: "caption",
366
+ color: "text.secondary",
367
+ sx: {
368
+ display: 'block',
369
+ px: 1,
370
+ pb: 1
371
+ },
372
+ children: `Showing ${visibleIcons.length} of ${icons.length} icons — search to narrow down.`
373
+ }) : null,
374
+ allIcons.length === 0 ? /*#__PURE__*/ _jsx(Typography, {
375
+ variant: "caption",
376
+ color: "text.secondary",
377
+ sx: {
378
+ display: 'block',
379
+ px: 1,
380
+ pb: 1
381
+ },
382
+ children: 'Loading icon catalog…'
383
+ }) : null
384
+ ]
385
+ })
386
+ ]
387
+ })
388
+ })
389
+ ]
390
+ });
391
+ });
392
+ IconSelectControl.displayName = 'IconSelectControl';
393
+ /**
394
+ * The data-driven-forms field: everything form-shaped (validation message,
395
+ * helper/description precedence, the final-form input) resolved here, and
396
+ * the picking itself delegated to {@link IconSelectControl}.
397
+ *
398
+ * Sits in the same {@link FormFieldGrid} every other field does, so the corner
399
+ * controls a schema asks for — the help tip, the opt-in clear, a caller's own
400
+ * — are where they are on every other field rather than silently dropped.
401
+ */ const IconSelectComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
402
+ const _useFieldApi = useFieldApi(props), { input, isReadOnly, isDisabled, placeholder, isRequired, label, helperText, description, validateOnMount, meta, inputProps, GridListProps, help, clearable, FormFieldGridProps = {} } = _useFieldApi, rest = _object_without_properties_loose(_useFieldApi, [
403
+ "input",
404
+ "isReadOnly",
405
+ "isDisabled",
406
+ "placeholder",
407
+ "isRequired",
408
+ "label",
409
+ "helperText",
410
+ "description",
411
+ "validateOnMount",
412
+ "meta",
413
+ "inputProps",
414
+ "GridListProps",
415
+ "help",
416
+ "clearable",
417
+ "FormFieldGridProps"
418
+ ]);
419
+ const invalidMessage = validationMessage(meta, validateOnMount);
420
+ const helperContent = [
421
+ invalidMessage,
422
+ (meta.touched || validateOnMount) && meta.warning,
423
+ helperText,
424
+ description
425
+ ].find((i)=>Boolean(i));
426
+ // The picker can only ever choose an icon, so without this nothing takes
427
+ // one back off again.
428
+ const clear = buildFieldClear({
429
+ clearable,
430
+ label,
431
+ hasValue: Boolean(input.value),
432
+ locked: Boolean(isDisabled || isReadOnly),
433
+ onClear: ()=>input.onChange('')
434
+ });
435
+ return /*#__PURE__*/ _jsx(FormFieldGrid, _extends({
436
+ help: help,
437
+ clear: clear
438
+ }, FormFieldGridProps, {
439
+ children: /*#__PURE__*/ _jsx(IconSelectControl, {
440
+ ref: ref,
441
+ value: input.value,
442
+ onChange: input.onChange,
443
+ label: label,
444
+ helperText: helperContent,
445
+ GridListProps: GridListProps
446
+ })
447
+ }));
448
+ });
449
+ IconSelectComponent.displayName = 'IconSelectComponent';
450
+ IconSelectComponent.aglyn = true;
451
+ export default IconSelectComponent;
452
+
453
+ //# sourceMappingURL=icon-select.component.js.map