@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,431 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2026 Aglyn LLC
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/ import { styled, useTheme } from "@aglyn/shared-ui-theme";
|
|
19
|
+
import { Box, Button, ButtonBase, Paper, Slider, Typography } from "@mui/material";
|
|
20
|
+
import { alpha as muiAlpha } from "@mui/material/styles";
|
|
21
|
+
import { createContext, useContext, useMemo } from "react";
|
|
22
|
+
/**
|
|
23
|
+
* The palette token paths the picker offers, with display labels.
|
|
24
|
+
*
|
|
25
|
+
* `console.theme.ts` is the source of truth for brand colour — these are
|
|
26
|
+
* references INTO it, never copies of it, so a palette change lands here for
|
|
27
|
+
* free. Anything the active palette does not define is dropped by
|
|
28
|
+
* {@link buildColorTokenOptions}, so listing a brand-only slot (`tertiary`,
|
|
29
|
+
* `surface`) costs nothing on a theme that lacks it.
|
|
30
|
+
*
|
|
31
|
+
* Every `path` must be UNIQUE — the picker keys its grid by it (AGL-1192).
|
|
32
|
+
*/ export const COLOR_PICKER_TOKEN_PATHS = [
|
|
33
|
+
{
|
|
34
|
+
path: 'primary.main',
|
|
35
|
+
label: 'Primary'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
path: 'primary.light',
|
|
39
|
+
label: 'Primary light'
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
path: 'primary.dark',
|
|
43
|
+
label: 'Primary dark'
|
|
44
|
+
},
|
|
45
|
+
// These three read `primary.*` until AGL-1206: picking "Secondary" handed
|
|
46
|
+
// back the PRIMARY colour, and the duplicate `primary.main` path also gave
|
|
47
|
+
// the grid two children with the same React key (AGL-1192).
|
|
48
|
+
{
|
|
49
|
+
path: 'secondary.main',
|
|
50
|
+
label: 'Secondary'
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
path: 'secondary.light',
|
|
54
|
+
label: 'Secondary light'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
path: 'secondary.dark',
|
|
58
|
+
label: 'Secondary dark'
|
|
59
|
+
},
|
|
60
|
+
// Brand slots beyond MUI's stock set. `tertiary` is the Aglyn slate after
|
|
61
|
+
// the AGL-1186 rotation; `surface` is a real palette entry, so "Surface"
|
|
62
|
+
// names it rather than `background.paper` (which is Paper).
|
|
63
|
+
{
|
|
64
|
+
path: 'tertiary.main',
|
|
65
|
+
label: 'Tertiary'
|
|
66
|
+
},
|
|
67
|
+
// The tertiary shades the theme has derived all along (AGL-2486).
|
|
68
|
+
// `createResponsiveTheme` runs `addShadeVariants` over `tertiary` exactly
|
|
69
|
+
// as it does over primary and secondary, so these resolve; the picker
|
|
70
|
+
// simply never offered them, and an author who wanted the accent's dark
|
|
71
|
+
// step had to hardcode a hex. `tertiary` is a FOREGROUND colour family, so
|
|
72
|
+
// its `dark` slot is the AA-checked accent-text shade rather than a naive
|
|
73
|
+
// darken — which is why the swatch resolves it out of the live palette
|
|
74
|
+
// instead of deriving a preview of its own.
|
|
75
|
+
{
|
|
76
|
+
path: 'tertiary.light',
|
|
77
|
+
label: 'Tertiary light'
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
path: 'tertiary.dark',
|
|
81
|
+
label: 'Tertiary dark'
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
path: 'surface.main',
|
|
85
|
+
label: 'Surface'
|
|
86
|
+
},
|
|
87
|
+
// The pale accent washes used as tile fills (AGL-1244). Offered right after
|
|
88
|
+
// the accent they belong to, because the pairing IS the token: a tile filled
|
|
89
|
+
// `tint.primary` carries a `primary.dark` glyph. Without these an author had
|
|
90
|
+
// no token for "pale blue panel" and reached for a hex, which then needed a
|
|
91
|
+
// hand-written `@scheme dark` slice to survive dark mode.
|
|
92
|
+
{
|
|
93
|
+
path: 'tint.primary',
|
|
94
|
+
label: 'Tint primary'
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
path: 'tint.secondary',
|
|
98
|
+
label: 'Tint secondary'
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
path: 'tint.tertiary',
|
|
102
|
+
label: 'Tint tertiary'
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
path: 'error.main',
|
|
106
|
+
label: 'Error'
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
path: 'warning.main',
|
|
110
|
+
label: 'Warning'
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
path: 'info.main',
|
|
114
|
+
label: 'Info'
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
path: 'success.main',
|
|
118
|
+
label: 'Success'
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
path: 'background.default',
|
|
122
|
+
label: 'Background'
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
path: 'background.paper',
|
|
126
|
+
label: 'Paper'
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
path: 'text.primary',
|
|
130
|
+
label: 'Text'
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
path: 'text.secondary',
|
|
134
|
+
label: 'Text secondary'
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
path: 'text.disabled',
|
|
138
|
+
label: 'Text disabled'
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
path: 'divider',
|
|
142
|
+
label: 'Divider'
|
|
143
|
+
},
|
|
144
|
+
// The neutral ramp the designs lean on for borders and muted copy, and the
|
|
145
|
+
// absolutes for on-inverse text. Without these an author had no token for
|
|
146
|
+
// "muted grey" and reached for a hardcoded hex, which then failed in dark.
|
|
147
|
+
{
|
|
148
|
+
path: 'grey.300',
|
|
149
|
+
label: 'Grey 300'
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
path: 'grey.600',
|
|
153
|
+
label: 'Grey 600'
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
path: 'grey.900',
|
|
157
|
+
label: 'Grey 900'
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
path: 'common.white',
|
|
161
|
+
label: 'White'
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
path: 'common.black',
|
|
165
|
+
label: 'Black'
|
|
166
|
+
}
|
|
167
|
+
];
|
|
168
|
+
/** Resolves a dot-separated palette token path to its color string. */ export function resolvePaletteToken(palette, path) {
|
|
169
|
+
const resolved = path.split('.').reduce((node, key)=>node && typeof node === 'object' ? node[key] : undefined, palette);
|
|
170
|
+
return typeof resolved === 'string' ? resolved : undefined;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Builds the picker's token options from a light and a dark palette so
|
|
174
|
+
* every swatch can show BOTH scheme resolutions. Tokens that resolve in
|
|
175
|
+
* neither palette are dropped.
|
|
176
|
+
*/ export function buildColorTokenOptions(lightPalette, darkPalette) {
|
|
177
|
+
const options = [];
|
|
178
|
+
// The picker keys its grid by `value`, so a repeated path would render two
|
|
179
|
+
// children with the same React key (AGL-1192). The list above is curated to
|
|
180
|
+
// be unique; this makes that a property of the builder rather than a rule
|
|
181
|
+
// someone has to remember when adding a token.
|
|
182
|
+
const seen = new Set();
|
|
183
|
+
for (const { path, label } of COLOR_PICKER_TOKEN_PATHS){
|
|
184
|
+
if (seen.has(path)) continue;
|
|
185
|
+
const light = resolvePaletteToken(lightPalette, path);
|
|
186
|
+
const dark = resolvePaletteToken(darkPalette, path);
|
|
187
|
+
if (!light && !dark) continue;
|
|
188
|
+
seen.add(path);
|
|
189
|
+
options.push({
|
|
190
|
+
value: path,
|
|
191
|
+
label,
|
|
192
|
+
light,
|
|
193
|
+
dark
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return options;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Carries site-theme-resolved token options down to every COLOR_PICKER
|
|
200
|
+
* field beneath it (styles panel, attribute forms, email blocks) with no
|
|
201
|
+
* per-form wiring. Without a provider the field falls back to resolving
|
|
202
|
+
* the token paths against the ambient MUI theme — one scheme only.
|
|
203
|
+
*/ export const ColorPickerTokensContext = /*#__PURE__*/ createContext(undefined);
|
|
204
|
+
ColorPickerTokensContext.displayName = 'ColorPickerTokensContext';
|
|
205
|
+
/**
|
|
206
|
+
* The token options a color-picker field should offer: the
|
|
207
|
+
* {@link ColorPickerTokensContext} value when provided, otherwise the
|
|
208
|
+
* default token paths resolved against the ambient theme's palette
|
|
209
|
+
* (filed under that theme's own scheme; the other scheme is unknown).
|
|
210
|
+
*/ export function useColorPickerTokenOptions() {
|
|
211
|
+
const contextOptions = useContext(ColorPickerTokensContext);
|
|
212
|
+
const theme = useTheme();
|
|
213
|
+
return useMemo(()=>{
|
|
214
|
+
if (contextOptions == null ? void 0 : contextOptions.length) return contextOptions;
|
|
215
|
+
const palette = theme == null ? void 0 : theme.palette;
|
|
216
|
+
const scheme = (palette == null ? void 0 : palette.mode) === 'dark' ? 'dark' : 'light';
|
|
217
|
+
const options = [];
|
|
218
|
+
const seen = new Set();
|
|
219
|
+
for (const { path, label } of COLOR_PICKER_TOKEN_PATHS){
|
|
220
|
+
if (seen.has(path)) continue;
|
|
221
|
+
const resolved = resolvePaletteToken(palette, path);
|
|
222
|
+
if (!resolved) continue;
|
|
223
|
+
seen.add(path);
|
|
224
|
+
options.push({
|
|
225
|
+
value: path,
|
|
226
|
+
label,
|
|
227
|
+
[scheme]: resolved
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
return options;
|
|
231
|
+
}, [
|
|
232
|
+
contextOptions,
|
|
233
|
+
theme
|
|
234
|
+
]);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* The transparency chequerboard drawn UNDER a partly transparent swatch
|
|
238
|
+
* (AGL-2486). Without it a token at 12% reads as "a very pale colour" and an
|
|
239
|
+
* author cannot tell 12% opacity from a tint token — which is the one
|
|
240
|
+
* distinction the opacity control exists to make.
|
|
241
|
+
*/ const SWATCH_CHECKER = 'repeating-conic-gradient(rgba(128, 128, 128, 0.45) 0% 25%, ' + 'transparent 0% 50%)';
|
|
242
|
+
/** Edge length of one chequerboard square, in px. */ const SWATCH_CHECKER_TILE = 8;
|
|
243
|
+
/** The colour a swatch paints, alpha applied when the author chose one. */ function swatchPaint(color, opacity) {
|
|
244
|
+
if (opacity >= 1) return color;
|
|
245
|
+
try {
|
|
246
|
+
return muiAlpha(color, opacity);
|
|
247
|
+
} catch (unused) {
|
|
248
|
+
// `alpha()` throws on anything it cannot parse (a named colour, an
|
|
249
|
+
// unresolved `var()`). A preview is not worth an exception, and the
|
|
250
|
+
// chequerboard behind still says "this is transparent".
|
|
251
|
+
return color;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Split swatch showing a token's light + dark resolutions side by side
|
|
256
|
+
* (left/light, right/dark) so authors see how the reference adapts per
|
|
257
|
+
* scheme. Falls back to a solid fill when only one scheme is known.
|
|
258
|
+
*
|
|
259
|
+
* `alpha` previews the opacity the author has chosen for the token
|
|
260
|
+
* (AGL-2486) over a chequerboard, so the swatch shows what will actually
|
|
261
|
+
* render rather than the token's opaque colour.
|
|
262
|
+
*/ export const TokenSwatch = styled('span', {
|
|
263
|
+
shouldForwardProp: (propName)=>propName !== 'light' && propName !== 'dark' && propName !== 'size' && propName !== 'alpha'
|
|
264
|
+
})(({ theme, light, dark, size = 22, alpha: opacity })=>{
|
|
265
|
+
var _ref, _ref1;
|
|
266
|
+
// `0` is a legitimate opacity and `strictNullChecks` is off repo-wide, so
|
|
267
|
+
// the default is spelled out rather than left to `??` on a falsy number.
|
|
268
|
+
const amount = typeof opacity === 'number' && Number.isFinite(opacity) ? opacity : 1;
|
|
269
|
+
const lightColor = swatchPaint((_ref = light != null ? light : dark) != null ? _ref : 'transparent', amount);
|
|
270
|
+
const darkColor = swatchPaint((_ref1 = dark != null ? dark : light) != null ? _ref1 : 'transparent', amount);
|
|
271
|
+
// Two stops on the SAME position, so the two halves meet exactly on the
|
|
272
|
+
// diameter instead of blending across a band the eye reads as a smudge
|
|
273
|
+
// at this size.
|
|
274
|
+
const paint = lightColor === darkColor ? `linear-gradient(${lightColor}, ${lightColor})` : `linear-gradient(105deg, ${lightColor} 0 50%, ${darkColor} 50% 100%)`;
|
|
275
|
+
const opaque = amount >= 1;
|
|
276
|
+
return {
|
|
277
|
+
width: size,
|
|
278
|
+
height: size,
|
|
279
|
+
flexShrink: 0,
|
|
280
|
+
display: 'inline-flex',
|
|
281
|
+
borderRadius: '50%',
|
|
282
|
+
border: `1px solid ${theme.palette.divider}`,
|
|
283
|
+
background: opaque ? paint : `${paint}, ${SWATCH_CHECKER}`,
|
|
284
|
+
// The ring is drawn INSIDE the box (border-box sizing), so a background
|
|
285
|
+
// left on its default `padding-box` origin is positioned in an area two
|
|
286
|
+
// pixels smaller than the one it paints. `repeat` fills the leftover
|
|
287
|
+
// edge bands from the neighbouring tile, where the diagonal split sits
|
|
288
|
+
// several pixels across — a wedge bitten out of a 22px circle. Anchoring
|
|
289
|
+
// the layers on the border box makes one tile cover the whole swatch;
|
|
290
|
+
// the chequerboard keeps tiling because it is sized in px, not to the
|
|
291
|
+
// element.
|
|
292
|
+
backgroundOrigin: 'border-box',
|
|
293
|
+
backgroundRepeat: opaque ? 'no-repeat' : 'no-repeat, repeat',
|
|
294
|
+
backgroundSize: opaque ? '100% 100%' : `100% 100%, ${SWATCH_CHECKER_TILE}px ${SWATCH_CHECKER_TILE}px`
|
|
295
|
+
};
|
|
296
|
+
});
|
|
297
|
+
TokenSwatch.displayName = 'AglynColorTokenSwatch';
|
|
298
|
+
/**
|
|
299
|
+
* The CSS colour string a picker value stands for. Lives here rather than
|
|
300
|
+
* inside the colour FIELD because the gradient field's stop editor commits
|
|
301
|
+
* through the same picker (AGL-1331) and must not grow a second, subtly
|
|
302
|
+
* different conversion.
|
|
303
|
+
*/ export function rgbColorToCss(value) {
|
|
304
|
+
if (typeof value === 'string') return value;
|
|
305
|
+
const { r, g, b, a } = _extends({}, value);
|
|
306
|
+
if (a < 1) return `rgba(${r || 0}, ${g || 0}, ${b || 0}, ${a || 0})`;
|
|
307
|
+
return `rgb(${r || 0}, ${g || 0}, ${b || 0})`;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Default stage of the two-stage picker (AGL-588): the site theme's palette
|
|
311
|
+
* references. Each split swatch previews the token's light and dark
|
|
312
|
+
* resolutions; selecting one stores the TOKEN PATH (not a hex), so the
|
|
313
|
+
* colour keeps adapting when the site switches schemes.
|
|
314
|
+
*
|
|
315
|
+
* Shared by the colour field and by each gradient stop (AGL-1331) — one
|
|
316
|
+
* grid, so the token list, the selected-state ring and the "Custom color…"
|
|
317
|
+
* escape hatch cannot drift between the two places an author picks a colour.
|
|
318
|
+
*/ export const ColorTokenGrid = (props)=>{
|
|
319
|
+
const { options, value, onSelect, onCustom, onClear, title = 'Theme colors', opacity, onOpacityChange } = props;
|
|
320
|
+
// Spelled out rather than `opacity ?? 1`: `0` is a legitimate opacity and
|
|
321
|
+
// `strictNullChecks` is off repo-wide.
|
|
322
|
+
const amount = typeof opacity === 'number' && Number.isFinite(opacity) ? opacity : 1;
|
|
323
|
+
return /*#__PURE__*/ _jsxs(Paper, {
|
|
324
|
+
sx: {
|
|
325
|
+
p: 1,
|
|
326
|
+
width: 248
|
|
327
|
+
},
|
|
328
|
+
children: [
|
|
329
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
330
|
+
variant: "overline",
|
|
331
|
+
component: "div",
|
|
332
|
+
color: "text.secondary",
|
|
333
|
+
sx: {
|
|
334
|
+
px: 0.5,
|
|
335
|
+
lineHeight: 2
|
|
336
|
+
},
|
|
337
|
+
children: title
|
|
338
|
+
}),
|
|
339
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
340
|
+
sx: {
|
|
341
|
+
display: 'grid',
|
|
342
|
+
gridTemplateColumns: '1fr 1fr',
|
|
343
|
+
gap: 0.25
|
|
344
|
+
},
|
|
345
|
+
children: options.map((option)=>/*#__PURE__*/ _jsxs(ButtonBase, {
|
|
346
|
+
"aria-label": option.label,
|
|
347
|
+
"aria-pressed": option.value === value,
|
|
348
|
+
onClick: (event)=>onSelect(option.value, event),
|
|
349
|
+
sx: {
|
|
350
|
+
justifyContent: 'flex-start',
|
|
351
|
+
gap: 0.75,
|
|
352
|
+
px: 0.5,
|
|
353
|
+
py: 0.5,
|
|
354
|
+
borderRadius: 1,
|
|
355
|
+
border: 1,
|
|
356
|
+
borderColor: option.value === value ? 'primary.main' : 'transparent',
|
|
357
|
+
'&:hover': {
|
|
358
|
+
backgroundColor: 'action.hover'
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
children: [
|
|
362
|
+
/*#__PURE__*/ _jsx(TokenSwatch, {
|
|
363
|
+
light: option.light,
|
|
364
|
+
dark: option.dark,
|
|
365
|
+
size: 18,
|
|
366
|
+
alpha: option.value === value ? amount : 1
|
|
367
|
+
}),
|
|
368
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
369
|
+
variant: "caption",
|
|
370
|
+
noWrap: true,
|
|
371
|
+
children: option.label
|
|
372
|
+
})
|
|
373
|
+
]
|
|
374
|
+
}, option.value))
|
|
375
|
+
}),
|
|
376
|
+
onOpacityChange ? /*#__PURE__*/ _jsxs(Box, {
|
|
377
|
+
sx: {
|
|
378
|
+
px: 0.5,
|
|
379
|
+
pt: 0.5
|
|
380
|
+
},
|
|
381
|
+
children: [
|
|
382
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
383
|
+
variant: "caption",
|
|
384
|
+
component: "label",
|
|
385
|
+
color: "text.secondary",
|
|
386
|
+
id: "aglyn-color-token-opacity",
|
|
387
|
+
sx: {
|
|
388
|
+
display: 'block'
|
|
389
|
+
},
|
|
390
|
+
children: `Opacity ${Math.round(amount * 100)}%`
|
|
391
|
+
}),
|
|
392
|
+
/*#__PURE__*/ _jsx(Slider, {
|
|
393
|
+
size: "small",
|
|
394
|
+
min: 0,
|
|
395
|
+
max: 1,
|
|
396
|
+
step: 0.01,
|
|
397
|
+
value: amount,
|
|
398
|
+
"aria-labelledby": "aglyn-color-token-opacity",
|
|
399
|
+
onChange: (_event, next)=>onOpacityChange(Array.isArray(next) ? next[0] : next),
|
|
400
|
+
sx: {
|
|
401
|
+
mt: -0.5
|
|
402
|
+
}
|
|
403
|
+
})
|
|
404
|
+
]
|
|
405
|
+
}) : null,
|
|
406
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
407
|
+
size: "small",
|
|
408
|
+
fullWidth: true,
|
|
409
|
+
sx: {
|
|
410
|
+
mt: 0.5
|
|
411
|
+
},
|
|
412
|
+
onClick: onCustom,
|
|
413
|
+
children: "Custom color…"
|
|
414
|
+
}),
|
|
415
|
+
onClear ? /*#__PURE__*/ _jsx(Button, {
|
|
416
|
+
size: "small",
|
|
417
|
+
fullWidth: true,
|
|
418
|
+
color: "inherit",
|
|
419
|
+
sx: {
|
|
420
|
+
mt: 0.25,
|
|
421
|
+
color: 'text.secondary'
|
|
422
|
+
},
|
|
423
|
+
onClick: onClear,
|
|
424
|
+
children: "Clear color"
|
|
425
|
+
}) : null
|
|
426
|
+
]
|
|
427
|
+
});
|
|
428
|
+
};
|
|
429
|
+
ColorTokenGrid.displayName = 'AglynColorTokenGrid';
|
|
430
|
+
|
|
431
|
+
//# sourceMappingURL=color-picker-tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx-forms/src/lib/components/color-picker-tokens.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 { styled, useTheme } from '@aglyn/shared-ui-theme'\nimport {\n Box,\n Button,\n ButtonBase,\n Paper,\n Slider,\n Typography,\n} from '@mui/material'\nimport { alpha as muiAlpha } from '@mui/material/styles'\nimport { createContext, useContext, useMemo } from 'react'\n\n/**\n * Theme color references for the two-stage color picker (AGL-588).\n *\n * The picker's default stage offers PALETTE TOKEN PATHS (`primary.main`,\n * `background.paper`, …) instead of resolved hex values: MUI's sx system\n * resolves palette paths against the ACTIVE theme, so a token-referenced\n * color adapts automatically when the site swaps between its light and\n * dark schemes — the fix for hardcoded light-scheme hex colors going\n * unreadable in dark mode.\n */\nexport interface ColorPickerTokenOption {\n /** Palette token path stored as the field value, e.g. 'primary.main'. */\n value: string\n label: string\n /** Swatch color resolved from the light-scheme palette. */\n light?: string\n /** Swatch color resolved from the dark-scheme palette. */\n dark?: string\n}\n\n/**\n * The palette token paths the picker offers, with display labels.\n *\n * `console.theme.ts` is the source of truth for brand colour — these are\n * references INTO it, never copies of it, so a palette change lands here for\n * free. Anything the active palette does not define is dropped by\n * {@link buildColorTokenOptions}, so listing a brand-only slot (`tertiary`,\n * `surface`) costs nothing on a theme that lacks it.\n *\n * Every `path` must be UNIQUE — the picker keys its grid by it (AGL-1192).\n */\nexport const COLOR_PICKER_TOKEN_PATHS: ReadonlyArray<{\n path: string\n label: string\n}> = [\n { path: 'primary.main', label: 'Primary' },\n { path: 'primary.light', label: 'Primary light' },\n { path: 'primary.dark', label: 'Primary dark' },\n // These three read `primary.*` until AGL-1206: picking \"Secondary\" handed\n // back the PRIMARY colour, and the duplicate `primary.main` path also gave\n // the grid two children with the same React key (AGL-1192).\n { path: 'secondary.main', label: 'Secondary' },\n { path: 'secondary.light', label: 'Secondary light' },\n { path: 'secondary.dark', label: 'Secondary dark' },\n // Brand slots beyond MUI's stock set. `tertiary` is the Aglyn slate after\n // the AGL-1186 rotation; `surface` is a real palette entry, so \"Surface\"\n // names it rather than `background.paper` (which is Paper).\n { path: 'tertiary.main', label: 'Tertiary' },\n // The tertiary shades the theme has derived all along (AGL-2486).\n // `createResponsiveTheme` runs `addShadeVariants` over `tertiary` exactly\n // as it does over primary and secondary, so these resolve; the picker\n // simply never offered them, and an author who wanted the accent's dark\n // step had to hardcode a hex. `tertiary` is a FOREGROUND colour family, so\n // its `dark` slot is the AA-checked accent-text shade rather than a naive\n // darken — which is why the swatch resolves it out of the live palette\n // instead of deriving a preview of its own.\n { path: 'tertiary.light', label: 'Tertiary light' },\n { path: 'tertiary.dark', label: 'Tertiary dark' },\n { path: 'surface.main', label: 'Surface' },\n // The pale accent washes used as tile fills (AGL-1244). Offered right after\n // the accent they belong to, because the pairing IS the token: a tile filled\n // `tint.primary` carries a `primary.dark` glyph. Without these an author had\n // no token for \"pale blue panel\" and reached for a hex, which then needed a\n // hand-written `@scheme dark` slice to survive dark mode.\n { path: 'tint.primary', label: 'Tint primary' },\n { path: 'tint.secondary', label: 'Tint secondary' },\n { path: 'tint.tertiary', label: 'Tint tertiary' },\n { path: 'error.main', label: 'Error' },\n { path: 'warning.main', label: 'Warning' },\n { path: 'info.main', label: 'Info' },\n { path: 'success.main', label: 'Success' },\n { path: 'background.default', label: 'Background' },\n { path: 'background.paper', label: 'Paper' },\n { path: 'text.primary', label: 'Text' },\n { path: 'text.secondary', label: 'Text secondary' },\n { path: 'text.disabled', label: 'Text disabled' },\n { path: 'divider', label: 'Divider' },\n // The neutral ramp the designs lean on for borders and muted copy, and the\n // absolutes for on-inverse text. Without these an author had no token for\n // \"muted grey\" and reached for a hardcoded hex, which then failed in dark.\n { path: 'grey.300', label: 'Grey 300' },\n { path: 'grey.600', label: 'Grey 600' },\n { path: 'grey.900', label: 'Grey 900' },\n { path: 'common.white', label: 'White' },\n { path: 'common.black', label: 'Black' },\n]\n\n/** Resolves a dot-separated palette token path to its color string. */\nexport function resolvePaletteToken(\n palette: Record<string, unknown> | undefined,\n path: string,\n): string | undefined {\n const resolved = path\n .split('.')\n .reduce<unknown>(\n (node, key) =>\n node && typeof node === 'object'\n ? (node as Record<string, unknown>)[key]\n : undefined,\n palette,\n )\n return typeof resolved === 'string' ? resolved : undefined\n}\n\n/**\n * Builds the picker's token options from a light and a dark palette so\n * every swatch can show BOTH scheme resolutions. Tokens that resolve in\n * neither palette are dropped.\n */\nexport function buildColorTokenOptions(\n lightPalette: Record<string, unknown> | undefined,\n darkPalette: Record<string, unknown> | undefined,\n): ColorPickerTokenOption[] {\n const options: ColorPickerTokenOption[] = []\n // The picker keys its grid by `value`, so a repeated path would render two\n // children with the same React key (AGL-1192). The list above is curated to\n // be unique; this makes that a property of the builder rather than a rule\n // someone has to remember when adding a token.\n const seen = new Set<string>()\n for (const { path, label } of COLOR_PICKER_TOKEN_PATHS) {\n if (seen.has(path)) continue\n const light = resolvePaletteToken(lightPalette, path)\n const dark = resolvePaletteToken(darkPalette, path)\n if (!light && !dark) continue\n seen.add(path)\n options.push({ value: path, label, light, dark })\n }\n return options\n}\n\n/**\n * Carries site-theme-resolved token options down to every COLOR_PICKER\n * field beneath it (styles panel, attribute forms, email blocks) with no\n * per-form wiring. Without a provider the field falls back to resolving\n * the token paths against the ambient MUI theme — one scheme only.\n */\nexport const ColorPickerTokensContext = createContext<\n ColorPickerTokenOption[] | undefined\n>(undefined)\nColorPickerTokensContext.displayName = 'ColorPickerTokensContext'\n\n/**\n * The token options a color-picker field should offer: the\n * {@link ColorPickerTokensContext} value when provided, otherwise the\n * default token paths resolved against the ambient theme's palette\n * (filed under that theme's own scheme; the other scheme is unknown).\n */\nexport function useColorPickerTokenOptions(): ColorPickerTokenOption[] {\n const contextOptions = useContext(ColorPickerTokensContext)\n const theme = useTheme() as {\n palette?: Record<string, unknown> & { mode?: string }\n } | null\n return useMemo(() => {\n if (contextOptions?.length) return contextOptions\n const palette = theme?.palette\n const scheme = palette?.mode === 'dark' ? 'dark' : 'light'\n const options: ColorPickerTokenOption[] = []\n const seen = new Set<string>()\n for (const { path, label } of COLOR_PICKER_TOKEN_PATHS) {\n if (seen.has(path)) continue\n const resolved = resolvePaletteToken(palette, path)\n if (!resolved) continue\n seen.add(path)\n options.push({ value: path, label, [scheme]: resolved })\n }\n return options\n }, [contextOptions, theme])\n}\n\n/**\n * The transparency chequerboard drawn UNDER a partly transparent swatch\n * (AGL-2486). Without it a token at 12% reads as \"a very pale colour\" and an\n * author cannot tell 12% opacity from a tint token — which is the one\n * distinction the opacity control exists to make.\n */\nconst SWATCH_CHECKER =\n 'repeating-conic-gradient(rgba(128, 128, 128, 0.45) 0% 25%, ' +\n 'transparent 0% 50%)'\n\n/** Edge length of one chequerboard square, in px. */\nconst SWATCH_CHECKER_TILE = 8\n\n/** The colour a swatch paints, alpha applied when the author chose one. */\nfunction swatchPaint(color: string, opacity: number): string {\n if (opacity >= 1) return color\n try {\n return muiAlpha(color, opacity)\n } catch {\n // `alpha()` throws on anything it cannot parse (a named colour, an\n // unresolved `var()`). A preview is not worth an exception, and the\n // chequerboard behind still says \"this is transparent\".\n return color\n }\n}\n\n/**\n * Split swatch showing a token's light + dark resolutions side by side\n * (left/light, right/dark) so authors see how the reference adapts per\n * scheme. Falls back to a solid fill when only one scheme is known.\n *\n * `alpha` previews the opacity the author has chosen for the token\n * (AGL-2486) over a chequerboard, so the swatch shows what will actually\n * render rather than the token's opaque colour.\n */\nexport const TokenSwatch = styled('span', {\n shouldForwardProp: (propName) =>\n propName !== 'light' &&\n propName !== 'dark' &&\n propName !== 'size' &&\n propName !== 'alpha',\n})<{ light?: string; dark?: string; size?: number; alpha?: number }>(({\n theme,\n light,\n dark,\n size = 22,\n alpha: opacity,\n}) => {\n // `0` is a legitimate opacity and `strictNullChecks` is off repo-wide, so\n // the default is spelled out rather than left to `??` on a falsy number.\n const amount =\n typeof opacity === 'number' && Number.isFinite(opacity) ? opacity : 1\n const lightColor = swatchPaint(light ?? dark ?? 'transparent', amount)\n const darkColor = swatchPaint(dark ?? light ?? 'transparent', amount)\n // Two stops on the SAME position, so the two halves meet exactly on the\n // diameter instead of blending across a band the eye reads as a smudge\n // at this size.\n const paint =\n lightColor === darkColor\n ? `linear-gradient(${lightColor}, ${lightColor})`\n : `linear-gradient(105deg, ${lightColor} 0 50%, ${darkColor} 50% 100%)`\n const opaque = amount >= 1\n return {\n width: size,\n height: size,\n flexShrink: 0,\n display: 'inline-flex',\n borderRadius: '50%',\n border: `1px solid ${theme.palette.divider}`,\n background: opaque ? paint : `${paint}, ${SWATCH_CHECKER}`,\n // The ring is drawn INSIDE the box (border-box sizing), so a background\n // left on its default `padding-box` origin is positioned in an area two\n // pixels smaller than the one it paints. `repeat` fills the leftover\n // edge bands from the neighbouring tile, where the diagonal split sits\n // several pixels across — a wedge bitten out of a 22px circle. Anchoring\n // the layers on the border box makes one tile cover the whole swatch;\n // the chequerboard keeps tiling because it is sized in px, not to the\n // element.\n backgroundOrigin: 'border-box',\n backgroundRepeat: opaque ? 'no-repeat' : 'no-repeat, repeat',\n backgroundSize: opaque\n ? '100% 100%'\n : `100% 100%, ${SWATCH_CHECKER_TILE}px ${SWATCH_CHECKER_TILE}px`,\n }\n})\nTokenSwatch.displayName = 'AglynColorTokenSwatch'\n\n/** The `{ r, g, b, a }` shape react-color hands back on every change. */\nexport interface RgbColorValue {\n r: number\n g: number\n b: number\n a: number\n}\n\n/**\n * The CSS colour string a picker value stands for. Lives here rather than\n * inside the colour FIELD because the gradient field's stop editor commits\n * through the same picker (AGL-1331) and must not grow a second, subtly\n * different conversion.\n */\nexport function rgbColorToCss(value: RgbColorValue | string): string {\n if (typeof value === 'string') return value\n const { r, g, b, a } = { ...value }\n if (a < 1) return `rgba(${r || 0}, ${g || 0}, ${b || 0}, ${a || 0})`\n return `rgb(${r || 0}, ${g || 0}, ${b || 0})`\n}\n\n/**\n * Default stage of the two-stage picker (AGL-588): the site theme's palette\n * references. Each split swatch previews the token's light and dark\n * resolutions; selecting one stores the TOKEN PATH (not a hex), so the\n * colour keeps adapting when the site switches schemes.\n *\n * Shared by the colour field and by each gradient stop (AGL-1331) — one\n * grid, so the token list, the selected-state ring and the \"Custom color…\"\n * escape hatch cannot drift between the two places an author picks a colour.\n */\nexport const ColorTokenGrid = (props: {\n options: ColorPickerTokenOption[]\n value: string\n onSelect: (tokenPath: string, event: unknown) => void\n onCustom: () => void\n /**\n * Takes the colour off entirely (AGL-2486). Omitted where there is\n * nothing to clear, or where the caller has no unset state to offer —\n * a gradient stop always has a colour, so it never passes this.\n */\n onClear?: () => void\n /** Overrides the \"Theme colors\" heading. */\n title?: string\n /**\n * Opacity applied to the picked token, 0–1 (AGL-2486). Omitting\n * `onOpacityChange` hides the control entirely, so a caller with nowhere to\n * store an alpha never shows one.\n */\n opacity?: number\n onOpacityChange?: (opacity: number) => void\n}) => {\n const {\n options,\n value,\n onSelect,\n onCustom,\n onClear,\n title = 'Theme colors',\n opacity,\n onOpacityChange,\n } = props\n // Spelled out rather than `opacity ?? 1`: `0` is a legitimate opacity and\n // `strictNullChecks` is off repo-wide.\n const amount =\n typeof opacity === 'number' && Number.isFinite(opacity) ? opacity : 1\n return (\n <Paper sx={{ p: 1, width: 248 }}>\n <Typography\n variant=\"overline\"\n component=\"div\"\n color=\"text.secondary\"\n sx={{ px: 0.5, lineHeight: 2 }}\n >\n {title}\n </Typography>\n <Box\n sx={{\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: 0.25,\n }}\n >\n {options.map((option) => (\n <ButtonBase\n key={option.value}\n aria-label={option.label}\n aria-pressed={option.value === value}\n onClick={(event) => onSelect(option.value, event)}\n sx={{\n justifyContent: 'flex-start',\n gap: 0.75,\n px: 0.5,\n py: 0.5,\n borderRadius: 1,\n border: 1,\n borderColor:\n option.value === value ? 'primary.main' : 'transparent',\n '&:hover': { backgroundColor: 'action.hover' },\n }}\n >\n <TokenSwatch\n light={option.light}\n dark={option.dark}\n size={18}\n alpha={option.value === value ? amount : 1}\n />\n <Typography variant=\"caption\" noWrap>\n {option.label}\n </Typography>\n </ButtonBase>\n ))}\n </Box>\n {/* Alpha ON the token, not instead of it (AGL-2486). The value stays a\n palette reference and the opacity rides alongside it, so a palette\n change still reaches a 12% wash — which is the whole reason this is\n a control here rather than a hex the author types with an alpha\n already baked in. */}\n {onOpacityChange ? (\n <Box sx={{ px: 0.5, pt: 0.5 }}>\n <Typography\n variant=\"caption\"\n component=\"label\"\n color=\"text.secondary\"\n id=\"aglyn-color-token-opacity\"\n sx={{ display: 'block' }}\n >\n {`Opacity ${Math.round(amount * 100)}%`}\n </Typography>\n <Slider\n size=\"small\"\n min={0}\n max={1}\n step={0.01}\n value={amount}\n aria-labelledby=\"aglyn-color-token-opacity\"\n onChange={(_event, next) =>\n onOpacityChange(Array.isArray(next) ? next[0] : next)\n }\n sx={{ mt: -0.5 }}\n />\n </Box>\n ) : null}\n <Button size=\"small\" fullWidth sx={{ mt: 0.5 }} onClick={onCustom}>\n Custom color…\n </Button>\n {onClear ? (\n <Button\n size=\"small\"\n fullWidth\n color=\"inherit\"\n sx={{ mt: 0.25, color: 'text.secondary' }}\n onClick={onClear}\n >\n Clear color\n </Button>\n ) : null}\n </Paper>\n )\n}\nColorTokenGrid.displayName = 'AglynColorTokenGrid'\n"],"names":["styled","useTheme","Box","Button","ButtonBase","Paper","Slider","Typography","alpha","muiAlpha","createContext","useContext","useMemo","COLOR_PICKER_TOKEN_PATHS","path","label","resolvePaletteToken","palette","resolved","split","reduce","node","key","undefined","buildColorTokenOptions","lightPalette","darkPalette","options","seen","Set","has","light","dark","add","push","value","ColorPickerTokensContext","displayName","useColorPickerTokenOptions","contextOptions","theme","length","scheme","mode","SWATCH_CHECKER","SWATCH_CHECKER_TILE","swatchPaint","color","opacity","TokenSwatch","shouldForwardProp","propName","size","amount","Number","isFinite","lightColor","darkColor","paint","opaque","width","height","flexShrink","display","borderRadius","border","divider","background","backgroundOrigin","backgroundRepeat","backgroundSize","rgbColorToCss","r","g","b","a","ColorTokenGrid","props","onSelect","onCustom","onClear","title","onOpacityChange","sx","p","variant","component","px","lineHeight","gridTemplateColumns","gap","map","option","aria-label","aria-pressed","onClick","event","justifyContent","py","borderColor","backgroundColor","noWrap","pt","id","Math","round","min","max","step","aria-labelledby","onChange","_event","next","Array","isArray","mt","fullWidth"],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 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 ColorPickerProps as AglynColorPickerProps } from '@aglyn/shared-ui-color-picker';
|
|
18
|
+
import { type FormFieldGridProps } from '../mapper';
|
|
19
|
+
import { type UseFieldApiComponentConfig } from '@data-driven-forms/react-form-renderer';
|
|
20
|
+
import { type FormControlProps as MuiFormControlProps, type GridProps, type PopperProps, type TextFieldProps } from '@mui/material';
|
|
21
|
+
type InternalColorPickerProps = Partial<TextFieldProps> & {
|
|
22
|
+
/** Contextual help tooltip, same contract as every other field. */
|
|
23
|
+
help?: FormFieldGridProps['help'];
|
|
24
|
+
FormFieldGridProps?: Partial<GridProps>;
|
|
25
|
+
ColorPickerProps?: Partial<AglynColorPickerProps>;
|
|
26
|
+
FormControlProps?: Partial<MuiFormControlProps>;
|
|
27
|
+
PopperProps?: Partial<PopperProps>;
|
|
28
|
+
presetColors?: string[];
|
|
29
|
+
/** Offer the reset-to-unset affordance (AGL-2486). */
|
|
30
|
+
clearable?: boolean;
|
|
31
|
+
};
|
|
32
|
+
export type ColorPickerProps = InternalColorPickerProps & UseFieldApiComponentConfig;
|
|
33
|
+
export declare const ColorPickerComponent: import("react").ForwardRefExoticComponent<(Omit<Partial<import("@mui/material").FilledTextFieldProps> & {
|
|
34
|
+
/** Contextual help tooltip, same contract as every other field. */
|
|
35
|
+
help?: FormFieldGridProps["help"];
|
|
36
|
+
FormFieldGridProps?: Partial<GridProps>;
|
|
37
|
+
ColorPickerProps?: Partial<AglynColorPickerProps>;
|
|
38
|
+
FormControlProps?: Partial<MuiFormControlProps>;
|
|
39
|
+
PopperProps?: Partial<PopperProps>;
|
|
40
|
+
presetColors?: string[];
|
|
41
|
+
/** Offer the reset-to-unset affordance (AGL-2486). */
|
|
42
|
+
clearable?: boolean;
|
|
43
|
+
} & UseFieldApiComponentConfig, "ref"> | Omit<Partial<import("@mui/material").StandardTextFieldProps> & {
|
|
44
|
+
/** Contextual help tooltip, same contract as every other field. */
|
|
45
|
+
help?: FormFieldGridProps["help"];
|
|
46
|
+
FormFieldGridProps?: Partial<GridProps>;
|
|
47
|
+
ColorPickerProps?: Partial<AglynColorPickerProps>;
|
|
48
|
+
FormControlProps?: Partial<MuiFormControlProps>;
|
|
49
|
+
PopperProps?: Partial<PopperProps>;
|
|
50
|
+
presetColors?: string[];
|
|
51
|
+
/** Offer the reset-to-unset affordance (AGL-2486). */
|
|
52
|
+
clearable?: boolean;
|
|
53
|
+
} & UseFieldApiComponentConfig, "ref"> | Omit<Partial<import("@mui/material").OutlinedTextFieldProps> & {
|
|
54
|
+
/** Contextual help tooltip, same contract as every other field. */
|
|
55
|
+
help?: FormFieldGridProps["help"];
|
|
56
|
+
FormFieldGridProps?: Partial<GridProps>;
|
|
57
|
+
ColorPickerProps?: Partial<AglynColorPickerProps>;
|
|
58
|
+
FormControlProps?: Partial<MuiFormControlProps>;
|
|
59
|
+
PopperProps?: Partial<PopperProps>;
|
|
60
|
+
presetColors?: string[];
|
|
61
|
+
/** Offer the reset-to-unset affordance (AGL-2486). */
|
|
62
|
+
clearable?: boolean;
|
|
63
|
+
} & UseFieldApiComponentConfig, "ref">) & import("react").RefAttributes<any>>;
|
|
64
|
+
export default ColorPickerComponent;
|