@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.
- package/LICENSE +201 -0
- package/README.md +7 -0
- package/package.json +52 -0
- package/src/index.d.ts +17 -0
- package/src/index.js +18 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/color-picker-tokens.d.ts +135 -0
- package/src/lib/components/color-picker-tokens.js +431 -0
- package/src/lib/components/color-picker-tokens.js.map +1 -0
- package/src/lib/components/color-picker.component.d.ts +64 -0
- package/src/lib/components/color-picker.component.js +322 -0
- package/src/lib/components/color-picker.component.js.map +1 -0
- package/src/lib/components/create-artifact-drawer.component.d.ts +100 -0
- package/src/lib/components/create-artifact-drawer.component.js +184 -0
- package/src/lib/components/create-artifact-drawer.component.js.map +1 -0
- package/src/lib/components/grid-form-template.component.d.ts +21 -0
- package/src/lib/components/grid-form-template.component.js +81 -0
- package/src/lib/components/grid-form-template.component.js.map +1 -0
- package/src/lib/components/icon-select.component.d.ts +52 -0
- package/src/lib/components/icon-select.component.js +453 -0
- package/src/lib/components/icon-select.component.js.map +1 -0
- package/src/lib/components/select.component.d.ts +58 -0
- package/src/lib/components/select.component.js +107 -0
- package/src/lib/components/select.component.js.map +1 -0
- package/src/lib/components/switch.component.d.ts +38 -0
- package/src/lib/components/switch.component.js +76 -0
- package/src/lib/components/switch.component.js.map +1 -0
- package/src/lib/components/text-field.component.d.ts +45 -0
- package/src/lib/components/text-field.component.js +77 -0
- package/src/lib/components/text-field.component.js.map +1 -0
- package/src/lib/components/textarea.component.d.ts +45 -0
- package/src/lib/components/textarea.component.js +61 -0
- package/src/lib/components/textarea.component.js.map +1 -0
- package/src/lib/components/toggle-button.component.d.ts +27 -0
- package/src/lib/components/toggle-button.component.js +116 -0
- package/src/lib/components/toggle-button.component.js.map +1 -0
- package/src/lib/constants/component-mappers.d.ts +42 -0
- package/src/lib/constants/component-mappers.js +70 -0
- package/src/lib/constants/component-mappers.js.map +1 -0
- package/src/lib/constants/dynamic-fields.d.ts +45 -0
- package/src/lib/constants/dynamic-fields.js +65 -0
- package/src/lib/constants/dynamic-fields.js.map +1 -0
- package/src/lib/constants/field-configurations.d.ts +53 -0
- package/src/lib/constants/field-configurations.js +121 -0
- package/src/lib/constants/field-configurations.js.map +1 -0
- package/src/lib/constants/flags.d.ts +72 -0
- package/src/lib/constants/flags.js +69 -0
- package/src/lib/constants/flags.js.map +1 -0
- package/src/lib/hocs/with-grid-item.d.ts +25 -0
- package/src/lib/hocs/with-grid-item.js +48 -0
- package/src/lib/hocs/with-grid-item.js.map +1 -0
- package/src/lib/jsx-forms.d.ts +41 -0
- package/src/lib/jsx-forms.js +42 -0
- package/src/lib/jsx-forms.js.map +1 -0
- package/src/lib/mapper/breakpoint-span.d.ts +73 -0
- package/src/lib/mapper/breakpoint-span.js +346 -0
- package/src/lib/mapper/breakpoint-span.js.map +1 -0
- package/src/lib/mapper/checkbox.d.ts +43 -0
- package/src/lib/mapper/checkbox.js +111 -0
- package/src/lib/mapper/checkbox.js.map +1 -0
- package/src/lib/mapper/css-border.d.ts +113 -0
- package/src/lib/mapper/css-border.js +410 -0
- package/src/lib/mapper/css-border.js.map +1 -0
- package/src/lib/mapper/css-dimension.d.ts +89 -0
- package/src/lib/mapper/css-dimension.js +327 -0
- package/src/lib/mapper/css-dimension.js.map +1 -0
- package/src/lib/mapper/css-gradient.d.ts +110 -0
- package/src/lib/mapper/css-gradient.js +720 -0
- package/src/lib/mapper/css-gradient.js.map +1 -0
- package/src/lib/mapper/data-table.d.ts +23 -0
- package/src/lib/mapper/data-table.js +296 -0
- package/src/lib/mapper/data-table.js.map +1 -0
- package/src/lib/mapper/date-picker.d.ts +26 -0
- package/src/lib/mapper/date-picker.js +69 -0
- package/src/lib/mapper/date-picker.js.map +1 -0
- package/src/lib/mapper/dual-list-select.d.ts +115 -0
- package/src/lib/mapper/dual-list-select.js +353 -0
- package/src/lib/mapper/dual-list-select.js.map +1 -0
- package/src/lib/mapper/field-array.d.ts +71 -0
- package/src/lib/mapper/field-array.js +326 -0
- package/src/lib/mapper/field-array.js.map +1 -0
- package/src/lib/mapper/form-field-grid.d.ts +155 -0
- package/src/lib/mapper/form-field-grid.js +194 -0
- package/src/lib/mapper/form-field-grid.js.map +1 -0
- package/src/lib/mapper/index.d.ts +50 -0
- package/src/lib/mapper/index.js +49 -0
- package/src/lib/mapper/index.js.map +1 -0
- package/src/lib/mapper/multiple-choice-list.d.ts +32 -0
- package/src/lib/mapper/multiple-choice-list.js +105 -0
- package/src/lib/mapper/multiple-choice-list.js.map +1 -0
- package/src/lib/mapper/plain-text.d.ts +31 -0
- package/src/lib/mapper/plain-text.js +48 -0
- package/src/lib/mapper/plain-text.js.map +1 -0
- package/src/lib/mapper/preset-choice.d.ts +106 -0
- package/src/lib/mapper/preset-choice.js +267 -0
- package/src/lib/mapper/preset-choice.js.map +1 -0
- package/src/lib/mapper/radio.d.ts +40 -0
- package/src/lib/mapper/radio.js +122 -0
- package/src/lib/mapper/radio.js.map +1 -0
- package/src/lib/mapper/select.d.ts +60 -0
- package/src/lib/mapper/select.js +203 -0
- package/src/lib/mapper/select.js.map +1 -0
- package/src/lib/mapper/slider.d.ts +45 -0
- package/src/lib/mapper/slider.js +119 -0
- package/src/lib/mapper/slider.js.map +1 -0
- package/src/lib/mapper/stored-field-value.d.ts +23 -0
- package/src/lib/mapper/stored-field-value.js +29 -0
- package/src/lib/mapper/stored-field-value.js.map +1 -0
- package/src/lib/mapper/sub-form.d.ts +39 -0
- package/src/lib/mapper/sub-form.js +108 -0
- package/src/lib/mapper/sub-form.js.map +1 -0
- package/src/lib/mapper/switch.d.ts +47 -0
- package/src/lib/mapper/switch.js +93 -0
- package/src/lib/mapper/switch.js.map +1 -0
- package/src/lib/mapper/tabs.d.ts +34 -0
- package/src/lib/mapper/tabs.js +64 -0
- package/src/lib/mapper/tabs.js.map +1 -0
- package/src/lib/mapper/text-field.d.ts +33 -0
- package/src/lib/mapper/text-field.js +88 -0
- package/src/lib/mapper/text-field.js.map +1 -0
- package/src/lib/mapper/textarea.d.ts +31 -0
- package/src/lib/mapper/textarea.js +68 -0
- package/src/lib/mapper/textarea.js.map +1 -0
- package/src/lib/mapper/theme-scale.d.ts +79 -0
- package/src/lib/mapper/theme-scale.js +162 -0
- package/src/lib/mapper/theme-scale.js.map +1 -0
- package/src/lib/mapper/time-picker.d.ts +26 -0
- package/src/lib/mapper/time-picker.js +69 -0
- package/src/lib/mapper/time-picker.js.map +1 -0
- package/src/lib/mapper/types.d.ts +43 -0
- package/src/lib/mapper/types.js +22 -0
- package/src/lib/mapper/types.js.map +1 -0
- package/src/lib/mapper/validation-error.d.ts +24 -0
- package/src/lib/mapper/validation-error.js +24 -0
- package/src/lib/mapper/validation-error.js.map +1 -0
- package/src/lib/mapper/wizard.d.ts +21 -0
- package/src/lib/mapper/wizard.js +203 -0
- package/src/lib/mapper/wizard.js.map +1 -0
- package/src/lib/types.d.ts +19 -0
- package/src/lib/types.js +18 -0
- package/src/lib/types.js.map +1 -0
- package/src/lib/utils/option-is-equal-to-value.d.ts +20 -0
- package/src/lib/utils/option-is-equal-to-value.js +21 -0
- package/src/lib/utils/option-is-equal-to-value.js.map +1 -0
- package/src/lib/utils/validation-message.d.ts +22 -0
- package/src/lib/utils/validation-message.js +24 -0
- package/src/lib/utils/validation-message.js.map +1 -0
- package/src/lib/vendor/data-driven-forms.d.ts +33 -0
- package/src/lib/vendor/data-driven-forms.js +29 -0
- 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
|