@ex-grid/sheet-mui 0.0.0-stage → 0.2.0-beta.3

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AkiraMisawa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,44 @@
1
- # Temporary Holding Version
1
+ # @ex-grid/sheet-mui
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ ExSheet for MUI: the design-system Wrapper that draws ExSheet for React's Chrome, the Sheet Toolbar, Format Cells and the Sheet Tabs among it, with MUI's components and maps its Visual Tokens onto a MUI theme made with CSS variables.
4
+
5
+ It is one of the packages of the ExGrid family: Excel-like grids, sheets, pivot tables and charts for reading
6
+ money and risk numbers, published to npm under `@ex-grid` and to NuGet for Blazor, at one shared version.
7
+
8
+ ## Install
9
+
10
+ ```sh
11
+ npm install @ex-grid/sheet-mui @emotion/react @emotion/styled @mui/material react react-dom
12
+ ```
13
+
14
+ `@emotion/react`, `@emotion/styled`, `@mui/material`, `react` and `react-dom` are peer dependencies: your application provides them, at the versions `package.json` names.
15
+
16
+ It depends on exactly the version of `@ex-grid/mui`, `@ex-grid/sheet`, `@ex-grid/sheet-engine` and `@ex-grid/sheet-react` it was built with, so upgrade the family's packages together.
17
+
18
+ What it draws reads these stylesheets. Import them once in your application, after the design system's own:
19
+
20
+ ```ts
21
+ import '@ex-grid/core/styles.css';
22
+ import '@ex-grid/sheet/styles.css';
23
+ import '@ex-grid/sheet-mui/styles.css';
24
+ ```
25
+
26
+ ## Documentation
27
+
28
+ [ExSheet on the documentation site](https://akiramisawa.github.io/ex-grid/exsheet), read for React with the switch at the top, and every
29
+ version's [Release Notes](https://akiramisawa.github.io/ex-grid/release-notes).
30
+
31
+ > **The API may still change.** While the version is `0.x`, it may change from one version to the next; each
32
+ > version's Release Notes say what changed. A prerelease, a version with a suffix such as `-rc.1`, passed every
33
+ > test layer in CI on the commit it was built from. A version without a suffix is published only once the
34
+ > project's [Definition of Done](https://github.com/AkiraMisawa/ex-grid/blob/main/docs/definition-of-done.md) is
35
+ > signed off on it.
36
+
37
+ ## Requirements
38
+
39
+ - **Chrome or Edge.** They are the supported browsers; Safari and Firefox are out of scope.
40
+ - **React 19.2.0 or a later 19.x.**
41
+
42
+ ## License
43
+
44
+ MIT
@@ -0,0 +1,43 @@
1
+ /**
2
+ * ExSheet for MUI (ADR-0390): the design-system Wrapper that draws ExSheet for React's Chrome, the Sheet Toolbar,
3
+ * Format Cells and the Sheet Tabs among it, with MUI's components, over ExGrid's MUI Wrapper for the grid the Sheet is
4
+ * drawn by.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+
9
+ import { CSSProperties } from 'react';
10
+ import type { ExSheetChrome } from '@ex-grid/sheet-react';
11
+ import { ExSheetProps } from '@ex-grid/sheet-react';
12
+ import { ReactElement } from 'react';
13
+
14
+ /**
15
+ * An Excel-like sheet with formulas drawn with MUI: the Chrome slots a `chrome` prop leaves are MUI's, the Sheet
16
+ * Toolbar, Format Cells and the Sheet Tabs among them, and the colours follow the theme and its scheme with no render.
17
+ * Needs a ThemeProvider above it whose theme is made with `createTheme({ cssVariables: true })`, and
18
+ * `@ex-grid/mui/styles.css` and `@ex-grid/sheet-mui/styles.css` loaded.
19
+ */
20
+ export declare function MuiExSheet(props: MuiExSheetProps): ReactElement;
21
+
22
+ /** A MuiExSheet's props: an ExSheet's, and the words MUI's Paper takes. */
23
+ export declare type MuiExSheetProps = ExSheetProps & {
24
+ /** The Paper's variant: `outlined`, the default here, draws a border; `elevation` a shadow, and under the dark
25
+ * scheme MUI lightens an elevated Paper with an overlay the Sheet's own Paper does not take. */
26
+ readonly variant?: 'elevation' | 'outlined';
27
+ /** The Paper's shadow depth, 0 to 24, under the `elevation` variant. */
28
+ readonly elevation?: number;
29
+ /** Square corners: the Paper's own word, and the Sheet set square in it with no inset. */
30
+ readonly square?: boolean;
31
+ /** A class for the Paper. */
32
+ readonly className?: string;
33
+ /** A style for the Paper. */
34
+ readonly style?: CSSProperties;
35
+ };
36
+
37
+ /** Every Chrome slot of a Sheet drawn in MUI's components: ExGrid's MUI Chrome for the grid's, and the Sheet's own.
38
+ * What {@link MuiExSheet} hands its Sheet. A Consumer that frames an ExSheet itself spreads it into the Sheet's
39
+ * `chrome`, inside an element of the classes `mui-ex-grid mui-ex-sheet` and a `MuiSizeContext`, under a ThemeProvider
40
+ * whose theme was made with CSS variables, as MuiExSheet draws them. */
41
+ export declare const muiSheetChrome: ExSheetChrome;
42
+
43
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,780 @@
1
+ // src/mui-ex-sheet.ts
2
+ import { createElement as createElement4, useMemo } from "react";
3
+ import { Paper as Paper2 } from "@mui/material";
4
+ import { useTheme } from "@mui/material/styles";
5
+ import { MuiSizeContext as MuiSizeContext4, muiSizeOf, refuseThemeWithoutVariables } from "@ex-grid/mui";
6
+ import { ExSheet } from "@ex-grid/sheet-react";
7
+
8
+ // src/chrome.ts
9
+ import { createElement as createElement3, useContext as useContext3 } from "react";
10
+ import { Typography as Typography2 } from "@mui/material";
11
+ import { MuiSizeContext as MuiSizeContext3, muiChrome } from "@ex-grid/mui";
12
+
13
+ // src/format-cells.ts
14
+ import { createElement, useContext, useState } from "react";
15
+ import { Button, Checkbox, FormControl, FormControlLabel, FormLabel, Radio, Tab, Tabs, TextField, Typography } from "@mui/material";
16
+ import { MuiSizeContext } from "@ex-grid/mui";
17
+ import {
18
+ formatCellsLineStroke,
19
+ formatCellsOffer,
20
+ isDisabledCategory
21
+ } from "@ex-grid/sheet";
22
+ import { useFormatCells } from "@ex-grid/sheet-react";
23
+ function paintOf(colour) {
24
+ return colour.isAutomatic ? "currentColor" : colour.toString();
25
+ }
26
+ function textVariant(size) {
27
+ return size === "small" ? "body2" : "body1";
28
+ }
29
+ function fieldset(legend, className, ...children) {
30
+ return createElement(
31
+ FormControl,
32
+ { component: "fieldset", className: ["mui-ex-sheet-fieldset", className].filter(Boolean).join(" ") },
33
+ createElement(FormLabel, { component: "legend", className: "mui-ex-sheet-legend" }, legend),
34
+ ...children
35
+ );
36
+ }
37
+ function radio(key, label, size, input) {
38
+ const { name, checked, onChange, disabled, title, ...named } = input;
39
+ return createElement(FormControlLabel, {
40
+ key,
41
+ label,
42
+ className: "mui-ex-sheet-label",
43
+ ...disabled === void 0 ? {} : { disabled },
44
+ ...title === void 0 ? {} : { title },
45
+ slotProps: { typography: { variant: textVariant(size) } },
46
+ control: createElement(Radio, { name, size, checked, onChange, slotProps: { input: named } })
47
+ });
48
+ }
49
+ function checkbox(label, size, checked, onChange) {
50
+ return createElement(FormControlLabel, {
51
+ label,
52
+ className: "mui-ex-sheet-label",
53
+ slotProps: { typography: { variant: textVariant(size) } },
54
+ control: createElement(Checkbox, { size, checked, onChange: (event) => {
55
+ onChange(event.target.checked);
56
+ } })
57
+ });
58
+ }
59
+ function nativeSelect(label, size, value, options, onChange) {
60
+ return createElement(TextField, {
61
+ select: true,
62
+ label,
63
+ size,
64
+ value,
65
+ className: "mui-ex-sheet-format-cells-dropdown",
66
+ slotProps: { select: { native: true } },
67
+ onChange: (event) => {
68
+ onChange(event.target.value);
69
+ }
70
+ }, ...options.map((option) => createElement("option", { key: option.value, value: option.value }, option.label)));
71
+ }
72
+ function DraftField({ label, value, typed, size, type = "text", className, error, input }) {
73
+ const [typing, setTyping] = useState(void 0);
74
+ return createElement(TextField, {
75
+ label,
76
+ size,
77
+ type,
78
+ className,
79
+ value: typing ?? value(),
80
+ error: error !== void 0,
81
+ ...error === void 0 ? {} : { helperText: error },
82
+ slotProps: { htmlInput: { ...input, spellCheck: false } },
83
+ onFocus: (event) => {
84
+ setTyping(event.target.value);
85
+ },
86
+ onChange: (event) => {
87
+ const text = event.target.value;
88
+ setTyping(text);
89
+ typed(text);
90
+ },
91
+ onBlur: (event) => {
92
+ if (event.target instanceof HTMLInputElement && event.target.checkValidity()) setTyping(void 0);
93
+ }
94
+ });
95
+ }
96
+ function codeList(name, legend, codes, chosen, choose, size, className) {
97
+ return createElement("div", { key: name }, fieldset(
98
+ legend,
99
+ className,
100
+ ...codes.map((code, index) => radio(index, createElement("code", null, code), size, {
101
+ name,
102
+ checked: chosen(index, code),
103
+ onChange: () => {
104
+ choose(index, code);
105
+ }
106
+ }))
107
+ ));
108
+ }
109
+ function NumberTab({ draft, words, size, set, id }) {
110
+ const { category } = draft;
111
+ const options = [];
112
+ const hint = (key, text) => createElement(Typography, { key, component: "p", variant: textVariant(size) }, text);
113
+ if (category === "general") options.push(hint("hint", words.formatCellsLabel("generalHint")));
114
+ else if (category === "text") options.push(hint("hint", words.formatCellsLabel("textHint")));
115
+ if (draft.takesDecimalPlaces) {
116
+ options.push(createElement(DraftField, {
117
+ key: `places-${category}`,
118
+ label: words.formatCellsLabel("decimalPlaces"),
119
+ size,
120
+ type: "number",
121
+ input: { min: 0, max: 30, required: true },
122
+ className: "mui-ex-sheet-format-cells-places",
123
+ value: () => String(draft.decimalPlaces),
124
+ typed: (text) => {
125
+ const value = Number(text);
126
+ if (text.trim() !== "" && Number.isInteger(value) && value >= 0 && value <= 30) set((each) => {
127
+ each.setDecimalPlaces(value);
128
+ });
129
+ }
130
+ }));
131
+ }
132
+ if (category === "number") {
133
+ options.push(createElement("div", { key: "separator" }, checkbox(
134
+ words.formatCellsLabel("thousandsSeparator"),
135
+ size,
136
+ draft.thousandsSeparator,
137
+ (checked) => {
138
+ set((each) => {
139
+ each.setThousandsSeparator(checked);
140
+ });
141
+ }
142
+ )));
143
+ }
144
+ if (category === "currency") options.push(hint("symbol", words.currencySymbolShown(draft.currencySymbol)));
145
+ if (draft.negativeNumbers.length > 0) {
146
+ options.push(codeList(
147
+ `${id}-negative`,
148
+ words.formatCellsLabel("negativeNumbers"),
149
+ draft.negativeNumbers,
150
+ (index) => draft.negativeNumber === index,
151
+ (index) => {
152
+ set((each) => {
153
+ each.setNegativeNumber(index);
154
+ });
155
+ },
156
+ size,
157
+ "mui-ex-sheet-format-cells-list"
158
+ ));
159
+ }
160
+ if (category === "custom") {
161
+ const why = draft.numberFormatRefusal;
162
+ options.push(createElement(DraftField, {
163
+ key: "code",
164
+ label: words.formatCellsLabel("type"),
165
+ size,
166
+ className: "mui-ex-sheet-format-cells-code",
167
+ value: () => draft.typeCode,
168
+ typed: (text) => {
169
+ set((each) => {
170
+ each.setType(text);
171
+ });
172
+ },
173
+ ...why === void 0 ? {} : { error: words.formatCellsRefusal(why) }
174
+ }));
175
+ }
176
+ if (draft.types.length > 0) {
177
+ options.push(codeList(
178
+ `${id}-type`,
179
+ words.formatCellsLabel(category === "custom" ? "codes" : "type"),
180
+ draft.types,
181
+ (_, code) => draft.typeCode === code,
182
+ (_, code) => {
183
+ set((each) => {
184
+ each.setType(code);
185
+ });
186
+ },
187
+ size,
188
+ "mui-ex-sheet-format-cells-list mui-ex-sheet-format-cells-types"
189
+ ));
190
+ }
191
+ return createElement(
192
+ "div",
193
+ { className: "mui-ex-sheet-format-cells-columns" },
194
+ fieldset(
195
+ words.formatCellsLabel("category"),
196
+ "mui-ex-sheet-format-cells-list",
197
+ ...formatCellsOffer.categories.flatMap(({ category: each, enabled }) => {
198
+ const reasonId = `${id}-reason-${each}`;
199
+ const choice = radio(each, words.categoryName(each), size, {
200
+ name: `${id}-category`,
201
+ checked: draft.category === each,
202
+ disabled: !enabled,
203
+ ...isDisabledCategory(each) ? { "aria-describedby": reasonId } : {},
204
+ onChange: () => {
205
+ set((one) => {
206
+ one.selectCategory(each);
207
+ });
208
+ }
209
+ });
210
+ return isDisabledCategory(each) ? [choice, createElement(Typography, {
211
+ key: `${each}-reason`,
212
+ id: reasonId,
213
+ component: "p",
214
+ variant: "caption",
215
+ color: "text.secondary",
216
+ className: "mui-ex-sheet-format-cells-reason"
217
+ }, words.categoryDisabled(each))] : [choice];
218
+ })
219
+ ),
220
+ createElement("div", { className: "mui-ex-sheet-format-cells-options" }, ...options)
221
+ );
222
+ }
223
+ function AlignmentTab({ draft, words, size, set }) {
224
+ return nativeSelect(
225
+ words.formatCellsLabel("horizontal"),
226
+ size,
227
+ draft.alignment,
228
+ formatCellsOffer.alignments.map((alignment) => ({ value: alignment, label: words.alignmentName(alignment) })),
229
+ (value) => {
230
+ const alignment = formatCellsOffer.alignments.find((each) => each === value);
231
+ if (alignment === void 0) throw new RangeError(`'${value}' is not an alignment Format Cells offers (ADR-0071).`);
232
+ set((each) => {
233
+ each.setAlignment(alignment);
234
+ });
235
+ }
236
+ );
237
+ }
238
+ function Palette({ draft, words, size, set, target, id }) {
239
+ const name = `${id}-palette-${target}`;
240
+ const isFill = target === "fill";
241
+ const chosen = draft.colourOf(target);
242
+ const swatches = (row, key) => createElement(
243
+ "div",
244
+ { key, className: "mui-ex-sheet-swatches" },
245
+ ...row.map((swatch, index) => {
246
+ const swatchName = words.swatchName(swatch);
247
+ const paint = paintOf(swatch.colour);
248
+ return createElement("input", {
249
+ key: index,
250
+ type: "radio",
251
+ name,
252
+ className: "mui-ex-sheet-swatch",
253
+ "aria-label": swatchName,
254
+ title: swatchName,
255
+ "data-rgb": paint,
256
+ style: { backgroundColor: paint },
257
+ checked: chosen !== void 0 && !chosen.isAutomatic && chosen.equals(swatch.colour),
258
+ onChange: () => {
259
+ set((each) => {
260
+ each.setColour(target, swatch.colour);
261
+ });
262
+ }
263
+ });
264
+ })
265
+ );
266
+ return createElement(
267
+ "div",
268
+ {
269
+ role: "radiogroup",
270
+ "aria-label": words.formatCellsLabel(isFill ? "backgroundColour" : "colour"),
271
+ className: "mui-ex-sheet-palette"
272
+ },
273
+ radio("first", words.formatCellsLabel(isFill ? "noColour" : "automatic"), size, {
274
+ name,
275
+ checked: isFill ? chosen === void 0 : chosen?.isAutomatic === true,
276
+ onChange: () => {
277
+ set((each) => {
278
+ each.setColour(target, void 0);
279
+ });
280
+ }
281
+ }),
282
+ swatches(formatCellsOffer.themeColours.flat(), "theme"),
283
+ swatches(formatCellsOffer.standardColours, "standard"),
284
+ createElement(DraftField, {
285
+ key: `hex-${target}`,
286
+ label: words.formatCellsLabel("moreColours"),
287
+ size,
288
+ input: { maxLength: 7, placeholder: "#RRGGBB", "data-target": target },
289
+ className: "mui-ex-sheet-more-colours",
290
+ value: () => draft.colourText(target),
291
+ typed: (text) => {
292
+ set((each) => {
293
+ each.setColourText(target, text);
294
+ });
295
+ }
296
+ })
297
+ );
298
+ }
299
+ function FontTab(props) {
300
+ const { draft, words, size, set, id } = props;
301
+ return createElement(
302
+ "div",
303
+ null,
304
+ createElement(
305
+ "div",
306
+ { className: "mui-ex-sheet-format-cells-columns" },
307
+ fieldset(
308
+ words.formatCellsLabel("fontStyle"),
309
+ "mui-ex-sheet-format-cells-list",
310
+ ...formatCellsOffer.fontStyles.map((style) => radio(style, words.fontStyleName(style), size, {
311
+ name: `${id}-font-style`,
312
+ checked: draft.fontStyle === style,
313
+ onChange: () => {
314
+ set((each) => {
315
+ each.setFontStyle(style);
316
+ });
317
+ }
318
+ }))
319
+ ),
320
+ createElement(
321
+ "div",
322
+ { className: "mui-ex-sheet-format-cells-options" },
323
+ nativeSelect(
324
+ words.formatCellsLabel("underline"),
325
+ size,
326
+ draft.underline ? "single" : "none",
327
+ [{ value: "none", label: words.formatCellsLabel("underlineNone") }, { value: "single", label: words.formatCellsLabel("underlineSingle") }],
328
+ (value) => {
329
+ const single = value === "single";
330
+ set((each) => {
331
+ each.setUnderline(single);
332
+ });
333
+ }
334
+ ),
335
+ checkbox(words.formatCellsLabel("strikethrough"), size, draft.strikethrough, (checked) => {
336
+ set((each) => {
337
+ each.setStrikethrough(checked);
338
+ });
339
+ }),
340
+ // Excel's Normal font (ADR-0071, 2026-10-02): checking it sets every part of the Font to its default; it
341
+ // shows checked while they are, so unchecking it changes nothing.
342
+ checkbox(words.formatCellsLabel("normalFont"), size, draft.isNormalFont, (checked) => {
343
+ if (checked) set((each) => {
344
+ each.setNormalFont();
345
+ });
346
+ })
347
+ )
348
+ ),
349
+ fieldset(words.formatCellsLabel("colour"), void 0, createElement(Palette, { ...props, target: "font" }))
350
+ );
351
+ }
352
+ function sampleLine(y, width, dashes) {
353
+ return createElement("line", { key: y, x1: 0, y1: y, x2: 56, y2: y, stroke: "currentColor", strokeWidth: width, strokeDasharray: dashes });
354
+ }
355
+ function lineSample(style) {
356
+ const { width, dashes } = formatCellsLineStroke(style);
357
+ const lines = style === "none" ? [] : style === "double" ? [sampleLine(2.5, width, void 0), sampleLine(5.5, width, void 0)] : [sampleLine(4, width, dashes)];
358
+ return createElement("svg", { className: "mui-ex-sheet-format-cells-line", width: 56, height: 8, "aria-hidden": true }, ...lines);
359
+ }
360
+ function preview(draft, label) {
361
+ const edges = [
362
+ ["top", 4, 4, 116, 4],
363
+ ["bottom", 4, 68, 116, 68],
364
+ ["left", 4, 4, 4, 68],
365
+ ["right", 116, 4, 116, 68]
366
+ ];
367
+ if (draft.hasInsideHorizontal) edges.push(["insideHorizontal", 4, 36, 116, 36]);
368
+ if (draft.hasInsideVertical) edges.push(["insideVertical", 60, 4, 60, 68]);
369
+ const lines = edges.flatMap(([edge, x1, y1, x2, y2]) => {
370
+ const line = draft.edgeLine(edge);
371
+ if (line?.isNone === true) return [];
372
+ if (line === void 0) {
373
+ return [createElement("line", { key: edge, x1, y1, x2, y2, "data-edge": edge, className: "mui-ex-sheet-format-cells-differs", stroke: "#808080", strokeWidth: 1, strokeDasharray: "1 2" })];
374
+ }
375
+ const { width, dashes } = formatCellsLineStroke(line.style);
376
+ return [createElement("line", { key: edge, x1, y1, x2, y2, "data-edge": edge, stroke: paintOf(line.colour), strokeWidth: width, strokeDasharray: dashes })];
377
+ });
378
+ return createElement("svg", { className: "mui-ex-sheet-format-cells-preview", width: 120, height: 72, viewBox: "0 0 120 72", role: "img", "aria-label": label }, ...lines);
379
+ }
380
+ function BorderTab(props) {
381
+ const { draft, words, size, set, id } = props;
382
+ const pressedOf = (edge) => {
383
+ const line = draft.edgeLine(edge);
384
+ if (line === void 0) return "mixed";
385
+ return line.isNone ? "false" : "true";
386
+ };
387
+ return createElement(
388
+ "div",
389
+ null,
390
+ createElement(
391
+ "div",
392
+ { className: "mui-ex-sheet-format-cells-columns" },
393
+ fieldset(
394
+ words.formatCellsLabel("lineStyle"),
395
+ void 0,
396
+ createElement(
397
+ "div",
398
+ { className: "mui-ex-sheet-format-cells-columns" },
399
+ ...formatCellsOffer.lineStyleColumns.map((column, at) => createElement(
400
+ "div",
401
+ { key: at, className: "mui-ex-sheet-format-cells-line-column" },
402
+ ...column.map((style) => radio(style, lineSample(style), size, {
403
+ name: `${id}-line-style`,
404
+ "aria-label": words.lineStyleName(style),
405
+ title: words.lineStyleName(style),
406
+ checked: draft.lineStyle === style,
407
+ onChange: () => {
408
+ set((each) => {
409
+ each.setLineStyle(style);
410
+ });
411
+ }
412
+ }))
413
+ ))
414
+ )
415
+ ),
416
+ createElement(
417
+ "div",
418
+ { className: "mui-ex-sheet-format-cells-options" },
419
+ createElement(
420
+ "div",
421
+ { role: "group", "aria-label": words.formatCellsLabel("presets"), className: "mui-ex-sheet-format-cells-buttons" },
422
+ ...formatCellsOffer.presets.map((preset) => createElement(Button, {
423
+ key: preset,
424
+ type: "button",
425
+ size,
426
+ variant: "outlined",
427
+ disabled: !draft.canApply(preset),
428
+ onClick: () => {
429
+ set((each) => {
430
+ each.applyPreset(preset);
431
+ });
432
+ }
433
+ }, words.presetName(preset)))
434
+ ),
435
+ // An edge set is contained, one unset outlined, and one whose cells' sides differ outlined in the primary.
436
+ createElement(
437
+ "div",
438
+ { role: "group", "aria-label": words.formatCellsLabel("border"), className: "mui-ex-sheet-format-cells-buttons" },
439
+ ...formatCellsOffer.edges.map((edge) => {
440
+ const pressed = pressedOf(edge);
441
+ const named = { "data-edge": edge };
442
+ return createElement(Button, {
443
+ key: edge,
444
+ type: "button",
445
+ size,
446
+ variant: pressed === "true" ? "contained" : "outlined",
447
+ color: pressed === "false" ? "inherit" : "primary",
448
+ disabled: !draft.canSet(edge),
449
+ "aria-pressed": pressed,
450
+ ...named,
451
+ onClick: () => {
452
+ set((each) => {
453
+ each.toggleEdge(edge);
454
+ });
455
+ }
456
+ }, words.edgeName(edge));
457
+ })
458
+ ),
459
+ preview(draft, words.formatCellsLabel("preview"))
460
+ )
461
+ ),
462
+ fieldset(words.formatCellsLabel("colour"), void 0, createElement(Palette, { ...props, target: "border" }))
463
+ );
464
+ }
465
+ function FillTab(props) {
466
+ return fieldset(props.words.formatCellsLabel("backgroundColour"), void 0, createElement(Palette, { ...props, target: "fill" }));
467
+ }
468
+ function tabContents(tab, props) {
469
+ switch (tab) {
470
+ case "number":
471
+ return createElement(NumberTab, props);
472
+ case "alignment":
473
+ return createElement(AlignmentTab, props);
474
+ case "font":
475
+ return createElement(FontTab, props);
476
+ case "border":
477
+ return createElement(BorderTab, props);
478
+ case "fill":
479
+ return createElement(FillTab, props);
480
+ default:
481
+ throw new RangeError(`Unknown Format Cells tab '${String(tab)}' (ADR-0071).`);
482
+ }
483
+ }
484
+ var openings = 0;
485
+ function MuiFormatCells({ context }) {
486
+ const { tab, showTab, tabControl, set, refusal, submit, cancel } = useFormatCells(context);
487
+ const { size } = useContext(MuiSizeContext);
488
+ const [id] = useState(() => {
489
+ openings += 1;
490
+ return `mui-ex-sheet-format-cells-${String(openings)}`;
491
+ });
492
+ const { draft, words } = context;
493
+ return createElement(
494
+ "form",
495
+ { className: "mui-ex-sheet-format-cells", onSubmit: submit, noValidate: true },
496
+ createElement(Tabs, {
497
+ // The arrows show the tab they reach, as the built-in Format Cells' and Mantine's do.
498
+ value: tab,
499
+ variant: "scrollable",
500
+ scrollButtons: false,
501
+ selectionFollowsFocus: true,
502
+ "aria-label": words.formatCellsLabel("tabs"),
503
+ className: "mui-ex-sheet-format-cells-tabs",
504
+ onChange: (_, value) => {
505
+ const shown = formatCellsOffer.tabs.find((each) => each === value);
506
+ if (shown === void 0) throw new RangeError(`'${String(value)}' is not a tab of Format Cells (ADR-0071).`);
507
+ showTab(shown);
508
+ }
509
+ }, ...formatCellsOffer.tabs.map((each) => createElement(Tab, {
510
+ key: each,
511
+ value: each,
512
+ label: words.tabName(each),
513
+ id: `${id}-tab-${each}`,
514
+ "aria-controls": `${id}-panel-${each}`,
515
+ className: "mui-ex-sheet-format-cells-tab",
516
+ ...each === tab ? { ref: tabControl } : {}
517
+ }))),
518
+ ...formatCellsOffer.tabs.map((each) => createElement("div", {
519
+ key: each,
520
+ role: "tabpanel",
521
+ id: `${id}-panel-${each}`,
522
+ "aria-labelledby": `${id}-tab-${each}`,
523
+ hidden: each !== tab,
524
+ className: "mui-ex-sheet-format-cells-panel",
525
+ "data-ex-tab": each
526
+ }, tabContents(each, { draft, words, size, set, id }))),
527
+ refusal === void 0 ? null : createElement(Typography, {
528
+ role: "alert",
529
+ component: "p",
530
+ color: "error",
531
+ variant: textVariant(size),
532
+ className: "mui-ex-sheet-format-cells-refusal"
533
+ }, refusal),
534
+ createElement(
535
+ "div",
536
+ { className: "mui-ex-sheet-format-cells-actions" },
537
+ createElement(Button, { type: "submit", size, variant: "contained" }, words.formatCellsLabel("ok")),
538
+ createElement(Button, { type: "button", size, variant: "outlined", onClick: cancel }, words.formatCellsLabel("cancel"))
539
+ )
540
+ );
541
+ }
542
+
543
+ // src/toolbar-item.ts
544
+ import { createElement as createElement2, useCallback, useContext as useContext2, useRef } from "react";
545
+ import { Button as Button2, IconButton, ListItemButton, Paper, Popper, ToggleButton } from "@mui/material";
546
+ import { MuiSizeContext as MuiSizeContext2 } from "@ex-grid/mui";
547
+ import { sheetToolbarPictures } from "@ex-grid/sheet";
548
+ import { useToolbarItem } from "@ex-grid/sheet-react";
549
+ function picture(icon) {
550
+ return createElement2("svg", {
551
+ className: "mui-ex-sheet-toolbar-icon",
552
+ viewBox: "0 0 16 16",
553
+ "aria-hidden": true,
554
+ focusable: false,
555
+ fill: "none",
556
+ stroke: "currentColor",
557
+ strokeLinecap: "round",
558
+ strokeLinejoin: "round",
559
+ dangerouslySetInnerHTML: { __html: sheetToolbarPictures[icon] }
560
+ });
561
+ }
562
+ function caret() {
563
+ return createElement2("svg", {
564
+ className: "mui-ex-sheet-toolbar-caret",
565
+ viewBox: "0 0 16 16",
566
+ "aria-hidden": true,
567
+ focusable: false,
568
+ fill: "none",
569
+ stroke: "currentColor",
570
+ strokeWidth: 1.5,
571
+ strokeLinecap: "round",
572
+ strokeLinejoin: "round"
573
+ }, createElement2("path", { d: "M4.5 6.5 8 10l3.5-3.5" }));
574
+ }
575
+ function OwnContent({ mount }) {
576
+ const taken = useRef(void 0);
577
+ const ref = useCallback((element) => {
578
+ taken.current?.();
579
+ taken.current = element === null ? void 0 : mount(element);
580
+ }, [mount]);
581
+ return createElement2("span", { ref, className: "mui-ex-sheet-toolbar-content" });
582
+ }
583
+ function ChoiceList({ item, size }) {
584
+ const { view, list, choice: props } = item;
585
+ const option = (index) => {
586
+ const choice = view.choices[index];
587
+ if (choice === void 0) throw new RangeError(`The list of ${view.name} has no choice ${String(index)} (ADR-0100).`);
588
+ const common = { key: index, ...props(index) };
589
+ if (choice.swatch !== void 0) {
590
+ return createElement2("button", {
591
+ ...common,
592
+ type: "button",
593
+ "aria-label": choice.label,
594
+ className: "mui-ex-sheet-swatch",
595
+ style: { backgroundColor: choice.swatch }
596
+ });
597
+ }
598
+ return createElement2(ListItemButton, {
599
+ ...common,
600
+ component: "button",
601
+ type: "button",
602
+ dense: size.dense,
603
+ selected: choice.selected,
604
+ className: "mui-ex-sheet-choice"
605
+ }, choice.label);
606
+ };
607
+ const rows = item.rows.map((row, at) => typeof row === "number" ? option(row) : createElement2("div", { key: `s${String(at)}`, className: "mui-ex-sheet-swatches", role: "none" }, ...row.map(option)));
608
+ return createElement2("div", { ...list, className: "mui-ex-sheet-choices" }, ...rows);
609
+ }
610
+ function MuiToolbarItem({ context }) {
611
+ const item = useToolbarItem(context);
612
+ const { view, open, control, toggleList } = item;
613
+ const size = useContext2(MuiSizeContext2);
614
+ const anchor = useRef(null);
615
+ const face = view.content !== void 0 ? createElement2(OwnContent, { mount: view.content }) : view.icon !== void 0 ? picture(view.icon) : view.text ?? view.name;
616
+ const press = () => {
617
+ context.invoke();
618
+ };
619
+ const listAnchor = useCallback((element) => {
620
+ anchor.current = element;
621
+ }, []);
622
+ const anchorOf = useCallback(() => {
623
+ if (anchor.current === null) throw new Error(`Internal: ${context.kind} drew no element for its list to open beneath.`);
624
+ return anchor.current;
625
+ }, [context.kind]);
626
+ const swatch = view.swatch === void 0 ? void 0 : { "--mui-ex-sheet-swatch": view.swatch };
627
+ let drawn;
628
+ switch (context.kind) {
629
+ case "toggle":
630
+ drawn = createElement2(ToggleButton, {
631
+ ...control,
632
+ value: context.id,
633
+ size: size.size,
634
+ selected: view.pressed,
635
+ color: "primary",
636
+ "aria-label": view.name,
637
+ className: "mui-ex-sheet-toolbar-toggle",
638
+ onClick: press
639
+ }, face);
640
+ break;
641
+ case "menu":
642
+ drawn = createElement2(Button2, {
643
+ ...control,
644
+ ref: listAnchor,
645
+ type: "button",
646
+ size: size.size,
647
+ variant: "text",
648
+ color: "inherit",
649
+ "aria-label": view.name,
650
+ "aria-haspopup": "menu",
651
+ "aria-expanded": open,
652
+ endIcon: caret(),
653
+ className: "mui-ex-sheet-toolbar-menu",
654
+ onClick: toggleList
655
+ }, view.text ?? view.name);
656
+ break;
657
+ case "split":
658
+ drawn = createElement2(
659
+ "span",
660
+ { ref: listAnchor, className: "mui-ex-sheet-toolbar-split", role: "group", "aria-label": view.name },
661
+ createElement2(IconButton, {
662
+ ...control,
663
+ type: "button",
664
+ size: size.size,
665
+ color: "inherit",
666
+ "aria-label": view.name,
667
+ className: "mui-ex-sheet-toolbar-face",
668
+ ...swatch === void 0 ? {} : { style: swatch },
669
+ onClick: press
670
+ }, face),
671
+ createElement2(IconButton, {
672
+ ...control,
673
+ type: "button",
674
+ size: size.size,
675
+ color: "inherit",
676
+ "aria-label": view.moreName ?? view.name,
677
+ "aria-haspopup": "menu",
678
+ "aria-expanded": open,
679
+ className: "mui-ex-sheet-toolbar-arrow",
680
+ onClick: toggleList
681
+ }, caret())
682
+ );
683
+ break;
684
+ case "button":
685
+ drawn = view.content === void 0 && view.icon !== void 0 ? createElement2(IconButton, {
686
+ ...control,
687
+ type: "button",
688
+ size: size.size,
689
+ color: "inherit",
690
+ "aria-label": view.name,
691
+ onClick: press
692
+ }, face) : createElement2(Button2, {
693
+ ...control,
694
+ type: "button",
695
+ size: size.size,
696
+ variant: "text",
697
+ color: "inherit",
698
+ "aria-label": view.name,
699
+ className: "mui-ex-sheet-toolbar-button",
700
+ onClick: press
701
+ }, face);
702
+ break;
703
+ default:
704
+ throw new RangeError(`Unknown Toolbar Item kind '${String(context.kind)}' (ADR-0100).`);
705
+ }
706
+ const classes = ["mui-ex-sheet-toolbar-item"];
707
+ if (view.active) classes.push("mui-ex-sheet-toolbar-active");
708
+ return createElement2(
709
+ "span",
710
+ { ref: item.item, className: classes.join(" ") },
711
+ drawn,
712
+ !item.hasList || !open ? null : createElement2(Popper, {
713
+ open,
714
+ anchorEl: anchorOf,
715
+ disablePortal: true,
716
+ placement: "bottom-start",
717
+ className: "mui-ex-sheet-toolbar-popper",
718
+ popperOptions: { strategy: "fixed" },
719
+ modifiers: [{ name: "offset", options: { offset: [0, 2] } }]
720
+ }, createElement2(Paper, { elevation: 8, className: "mui-ex-sheet-toolbar-list" }, createElement2(ChoiceList, { item, size })))
721
+ );
722
+ }
723
+
724
+ // src/chrome.ts
725
+ function MuiSheetTab({ context }) {
726
+ const { size } = useContext3(MuiSizeContext3);
727
+ return createElement3(Typography2, {
728
+ component: "span",
729
+ variant: size === "small" ? "body2" : "body1",
730
+ className: "mui-ex-sheet-tab-face",
731
+ ...context.selected ? { color: "primary", fontWeight: 500 } : {}
732
+ }, context.name);
733
+ }
734
+ function MuiSheetTabAdd() {
735
+ return createElement3("svg", {
736
+ className: "mui-ex-sheet-tab-add-face",
737
+ viewBox: "0 0 16 16",
738
+ "aria-hidden": true,
739
+ focusable: false,
740
+ fill: "none",
741
+ stroke: "currentColor",
742
+ strokeWidth: 1.5,
743
+ strokeLinecap: "round"
744
+ }, createElement3("path", { d: "M8 3v10M3 8h10" }));
745
+ }
746
+ var muiSheetChrome = Object.freeze({
747
+ ...muiChrome,
748
+ toolbarItem: (context) => createElement3(MuiToolbarItem, { context }),
749
+ formatCells: (context) => createElement3(MuiFormatCells, { context }),
750
+ sheetTab: (context) => createElement3(MuiSheetTab, { context }),
751
+ sheetTabAdd: () => createElement3(MuiSheetTabAdd)
752
+ });
753
+
754
+ // src/mui-ex-sheet.ts
755
+ function MuiExSheet(props) {
756
+ const { variant = "outlined", elevation, square, className, style, chrome, ...sheet } = props;
757
+ refuseThemeWithoutVariables(useTheme(), "MuiExSheet");
758
+ const density = sheet.density ?? "compact";
759
+ const merged = useMemo(() => chrome === void 0 ? muiSheetChrome : { ...muiSheetChrome, ...chrome }, [chrome]);
760
+ const classes = ["mui-ex-grid", "mui-ex-sheet"];
761
+ if (square === true) classes.push("mui-ex-grid-square");
762
+ if (sheet.viewportWidth === "stretch") classes.push("mui-ex-grid-stretch");
763
+ if (className !== void 0) classes.push(className);
764
+ return createElement4(Paper2, {
765
+ className: classes.join(" "),
766
+ variant,
767
+ ...style === void 0 ? {} : { style },
768
+ ...elevation === void 0 ? {} : { elevation },
769
+ ...square === void 0 ? {} : { square }
770
+ }, createElement4(
771
+ MuiSizeContext4.Provider,
772
+ { value: muiSizeOf(density) },
773
+ createElement4(ExSheet, { ...sheet, chrome: merged })
774
+ ));
775
+ }
776
+ export {
777
+ MuiExSheet,
778
+ muiSheetChrome
779
+ };
780
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/mui-ex-sheet.ts", "../src/chrome.ts", "../src/format-cells.ts", "../src/toolbar-item.ts"],
4
+ "sourcesContent": ["// MuiExSheet (ADR-0390, ADR-0030): ExSheet for React inside MUI's Paper, its Chrome drawn in MUI's components and its\n// Visual Tokens mapped onto the theme's CSS variables by the Wrappers' stylesheets, ExGrid's and the Sheet's. It owns\n// no geometry, no DOM inside the Sheet's element and no state. The cells keep the Sheet's own font, whose widths its\n// columns are measured in characters by (ADR-0027): a Sheet's look is its document's, so MUI's font is the Chrome's,\n// never the cells', and no font is handed the grid. A theme without CSS variables is refused, since its colours exist\n// only in script and the Chrome would be drawn in colours that are not the theme's (ADR-0390 section 5).\n\nimport { createElement, useMemo, type CSSProperties, type ReactElement } from 'react';\nimport { Paper } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { MuiSizeContext, muiSizeOf, refuseThemeWithoutVariables } from '@ex-grid/mui';\nimport { ExSheet, type ExSheetProps } from '@ex-grid/sheet-react';\nimport { muiSheetChrome } from './chrome';\n\n/** A MuiExSheet's props: an ExSheet's, and the words MUI's Paper takes. */\nexport type MuiExSheetProps = ExSheetProps & {\n /** The Paper's variant: `outlined`, the default here, draws a border; `elevation` a shadow, and under the dark\n * scheme MUI lightens an elevated Paper with an overlay the Sheet's own Paper does not take. */\n readonly variant?: 'elevation' | 'outlined';\n /** The Paper's shadow depth, 0 to 24, under the `elevation` variant. */\n readonly elevation?: number;\n /** Square corners: the Paper's own word, and the Sheet set square in it with no inset. */\n readonly square?: boolean;\n /** A class for the Paper. */\n readonly className?: string;\n /** A style for the Paper. */\n readonly style?: CSSProperties;\n};\n\n/**\n * An Excel-like sheet with formulas drawn with MUI: the Chrome slots a `chrome` prop leaves are MUI's, the Sheet\n * Toolbar, Format Cells and the Sheet Tabs among them, and the colours follow the theme and its scheme with no render.\n * Needs a ThemeProvider above it whose theme is made with `createTheme({ cssVariables: true })`, and\n * `@ex-grid/mui/styles.css` and `@ex-grid/sheet-mui/styles.css` loaded.\n */\nexport function MuiExSheet(props: MuiExSheetProps): ReactElement {\n const { variant = 'outlined', elevation, square, className, style, chrome, ...sheet } = props;\n refuseThemeWithoutVariables(useTheme(), 'MuiExSheet');\n const density = sheet.density ?? 'compact'; // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0028: an untouched Sheet is compact\n // The Consumer's slots win over the Wrapper's; one merge per chrome handed, so a render function handed again\n // keeps its mount (ADR-0390).\n const merged = useMemo(() => (chrome === undefined ? muiSheetChrome : { ...muiSheetChrome, ...chrome }), [chrome]);\n const classes = ['mui-ex-grid', 'mui-ex-sheet'];\n if (square === true) classes.push('mui-ex-grid-square');\n // A Stretch Sheet follows its container's width (ADR-0045), so the Paper round it does too.\n if (sheet.viewportWidth === 'stretch') classes.push('mui-ex-grid-stretch');\n if (className !== undefined) classes.push(className);\n return createElement(Paper, {\n className: classes.join(' '),\n variant,\n ...(style === undefined ? {} : { style }),\n ...(elevation === undefined ? {} : { elevation }),\n ...(square === undefined ? {} : { square }),\n }, createElement(MuiSizeContext.Provider, { value: muiSizeOf(density) },\n createElement(ExSheet, { ...sheet, chrome: merged })));\n}\n", "// The MUI Chrome for a Sheet (ADR-0390 section 3): ExGrid's MUI Chrome in the slots the Sheet hands its grid, and MUI's\n// components in the Sheet's own: each Toolbar Item, Format Cells, and the Sheet Tabs' faces. What each shows and means\n// is the Sheet's, reached through its slots' contexts and ExSheet for React's hooks.\n\nimport { createElement, useContext, type ReactElement } from 'react';\nimport { Typography } from '@mui/material';\nimport { MuiSizeContext, muiChrome } from '@ex-grid/mui';\nimport type { SheetFormatCellsSlotContext, SheetTabSlotContext, SheetToolbarItemSlotContext } from '@ex-grid/sheet';\nimport type { ExSheetChrome } from '@ex-grid/sheet-react';\nimport { MuiFormatCells } from './format-cells';\nimport { MuiToolbarItem } from './toolbar-item';\n\n/** A Sheet Tab's face: the Sheet's name in MUI's text, in the theme's primary on the Sheet shown, as MUI's Tabs mark\n * the tab selected. The tab around it, which takes the keyboard and hears the press, is the Sheet's. */\nfunction MuiSheetTab({ context }: { readonly context: SheetTabSlotContext }): ReactElement {\n const { size } = useContext(MuiSizeContext);\n return createElement(Typography<'span'>, {\n component: 'span', variant: size === 'small' ? 'body2' : 'body1', className: 'mui-ex-sheet-tab-face',\n ...(context.selected ? { color: 'primary', fontWeight: 500 } : {}),\n }, context.name);\n}\n\n/** The + button's face: a plus drawn in the text's colour. */\nfunction MuiSheetTabAdd(): ReactElement {\n return createElement('svg', {\n className: 'mui-ex-sheet-tab-add-face', viewBox: '0 0 16 16', 'aria-hidden': true, focusable: false, fill: 'none', stroke: 'currentColor',\n strokeWidth: 1.5, strokeLinecap: 'round',\n }, createElement('path', { d: 'M8 3v10M3 8h10' }));\n}\n\n/** Every Chrome slot of a Sheet drawn in MUI's components: ExGrid's MUI Chrome for the grid's, and the Sheet's own.\n * What {@link MuiExSheet} hands its Sheet. A Consumer that frames an ExSheet itself spreads it into the Sheet's\n * `chrome`, inside an element of the classes `mui-ex-grid mui-ex-sheet` and a `MuiSizeContext`, under a ThemeProvider\n * whose theme was made with CSS variables, as MuiExSheet draws them. */\nexport const muiSheetChrome: ExSheetChrome = Object.freeze({\n ...muiChrome,\n toolbarItem: (context: SheetToolbarItemSlotContext) => createElement(MuiToolbarItem, { context }),\n formatCells: (context: SheetFormatCellsSlotContext) => createElement(MuiFormatCells, { context }),\n sheetTab: (context: SheetTabSlotContext) => createElement(MuiSheetTab, { context }),\n sheetTabAdd: () => createElement(MuiSheetTabAdd),\n});\n", "// Format Cells in MUI's components (ADR-0071, ADR-0390): MUI's Tabs, fieldsets, Radios, Checkboxes, native selects,\n// TextFields and Buttons, inside the grid's popover frame, where the built-in Format Cells stands. What it offers is\n// `formatCellsOffer`'s, every choice is set through the Sheet's draft, and OK is the Sheet's, so the same choices set\n// the same Cell Format under either Chrome. The palette's swatches are buttons painted in the document's colours, which\n// no MUI control draws; the colour is the user's choice of data, written inline, never a token.\n//\n// A field typed into shows what is typed while it holds the keyboard, and the draft's text once it is left, so a\n// choice never writes over typing (ADR-0240 section 1); one the draft did not take stays as typed, and OK refuses it.\n\nimport { createElement, useContext, useState, type ReactElement, type ReactNode } from 'react';\nimport { Button, Checkbox, FormControl, FormControlLabel, FormLabel, Radio, Tab, Tabs, TextField, Typography } from '@mui/material';\nimport { MuiSizeContext } from '@ex-grid/mui';\nimport {\n formatCellsLineStroke, formatCellsOffer, isDisabledCategory, type ColourTarget, type FormatCellsDraft, type FormatCellsTab, type PaletteSwatch,\n type SheetFormatCellsSlotContext, type SheetWords,\n} from '@ex-grid/sheet';\nimport { useFormatCells } from '@ex-grid/sheet-react';\nimport type { BorderLineStyle, CellColour } from '@ex-grid/sheet-engine';\n\n/** The `size` MUI's controls take. */\ntype Size = 'small' | 'medium';\n\n/** What every tab is drawn with. */\ninterface TabProps {\n readonly draft: FormatCellsDraft;\n readonly words: SheetWords;\n readonly size: Size;\n readonly set: (choose: (draft: FormatCellsDraft) => void) => void;\n}\n\n/** A colour as a swatch and a preview paint it: Automatic is the Ink of the text around it. */\nfunction paintOf(colour: CellColour): string {\n return colour.isAutomatic ? 'currentColor' : colour.toString();\n}\n\n/** The body text at the size the controls are drawn at. */\nfunction textVariant(size: Size): 'body2' | 'body1' {\n return size === 'small' ? 'body2' : 'body1';\n}\n\n/** A group of controls under its legend, as MUI's forms group radios and checkboxes. */\nfunction fieldset(legend: string, className: string | undefined, ...children: ReactNode[]): ReactElement {\n return createElement(FormControl<'fieldset'>, { component: 'fieldset', className: ['mui-ex-sheet-fieldset', className].filter(Boolean).join(' ') },\n createElement(FormLabel<'legend'>, { component: 'legend', className: 'mui-ex-sheet-legend' }, legend), ...children);\n}\n\n/** A radio with its label, in the body's text at the controls' size. */\nfunction radio(key: string | number, label: ReactNode, size: Size, input: {\n readonly name: string; readonly checked: boolean; readonly onChange: () => void; readonly disabled?: boolean;\n readonly 'aria-label'?: string; readonly 'aria-describedby'?: string; readonly title?: string;\n}): ReactElement {\n const { name, checked, onChange, disabled, title, ...named } = input;\n return createElement(FormControlLabel, {\n key, label, className: 'mui-ex-sheet-label', ...(disabled === undefined ? {} : { disabled }), ...(title === undefined ? {} : { title }),\n slotProps: { typography: { variant: textVariant(size) } },\n control: createElement(Radio, { name, size, checked, onChange, slotProps: { input: named } }),\n });\n}\n\n/** A checkbox with its label. */\nfunction checkbox(label: string, size: Size, checked: boolean, onChange: (checked: boolean) => void): ReactElement {\n return createElement(FormControlLabel, {\n label, className: 'mui-ex-sheet-label', slotProps: { typography: { variant: textVariant(size) } },\n control: createElement(Checkbox, { size, checked, onChange: event => { onChange(event.target.checked); } }),\n });\n}\n\n/** A native select under its label, MUI's TextField drawing the browser's own list. */\nfunction nativeSelect(label: string, size: Size, value: string, options: readonly { readonly value: string; readonly label: string }[],\n onChange: (value: string) => void): ReactElement {\n return createElement(TextField, {\n select: true, label, size, value, className: 'mui-ex-sheet-format-cells-dropdown', slotProps: { select: { native: true } },\n onChange: event => { onChange(event.target.value); },\n }, ...options.map(option => createElement('option', { key: option.value, value: option.value }, option.label)));\n}\n\n/** A field typed into: what is typed while it is, the draft's text otherwise. */\nfunction DraftField({ label, value, typed, size, type = 'text', className, error, input }: {\n readonly label: string; readonly value: () => string; readonly typed: (text: string) => void; readonly size: Size;\n readonly type?: 'text' | 'number'; readonly className: string; readonly error?: string;\n readonly input?: {\n readonly min?: number; readonly max?: number; readonly required?: boolean; readonly maxLength?: number; readonly placeholder?: string;\n readonly 'data-target'?: string;\n };\n}): ReactElement {\n const [typing, setTyping] = useState<string | undefined>(undefined);\n return createElement(TextField, {\n label, size, type, className, value: typing ?? value(), error: error !== undefined, ...(error === undefined ? {} : { helperText: error }),\n slotProps: { htmlInput: { ...input, spellCheck: false } },\n onFocus: event => { setTyping(event.target.value); },\n onChange: event => {\n const text = event.target.value;\n setTyping(text);\n typed(text);\n },\n onBlur: event => { if (event.target instanceof HTMLInputElement && event.target.checkValidity()) setTyping(undefined); },\n });\n}\n\n/** A list of codes to choose one of: a Negative Numbers list or a category's Types. */\nfunction codeList(name: string, legend: string, codes: readonly string[], chosen: (index: number, code: string) => boolean,\n choose: (index: number, code: string) => void, size: Size, className: string): ReactElement {\n return createElement('div', { key: name }, fieldset(legend, className,\n ...codes.map((code, index) => radio(index, createElement('code', null, code), size, {\n name, checked: chosen(index, code), onChange: () => { choose(index, code); },\n }))));\n}\n\nfunction NumberTab({ draft, words, size, set, id }: TabProps & { readonly id: string }): ReactElement {\n const { category } = draft;\n const options: ReactNode[] = [];\n const hint = (key: string, text: string): ReactElement => createElement(Typography<'p'>, { key, component: 'p', variant: textVariant(size) }, text);\n if (category === 'general') options.push(hint('hint', words.formatCellsLabel('generalHint')));\n else if (category === 'text') options.push(hint('hint', words.formatCellsLabel('textHint')));\n if (draft.takesDecimalPlaces) {\n options.push(createElement(DraftField, {\n key: `places-${category}`, label: words.formatCellsLabel('decimalPlaces'), size, type: 'number', input: { min: 0, max: 30, required: true },\n className: 'mui-ex-sheet-format-cells-places', value: () => String(draft.decimalPlaces),\n typed: (text: string) => {\n const value = Number(text);\n // Only a whole number of places Excel takes is set; anything else leaves the field invalid, which OK refuses.\n if (text.trim() !== '' && Number.isInteger(value) && value >= 0 && value <= 30) set(each => { each.setDecimalPlaces(value); });\n },\n }));\n }\n if (category === 'number') {\n options.push(createElement('div', { key: 'separator' }, checkbox(words.formatCellsLabel('thousandsSeparator'), size, draft.thousandsSeparator,\n checked => { set(each => { each.setThousandsSeparator(checked); }); })));\n }\n if (category === 'currency') options.push(hint('symbol', words.currencySymbolShown(draft.currencySymbol)));\n if (draft.negativeNumbers.length > 0) {\n options.push(codeList(`${id}-negative`, words.formatCellsLabel('negativeNumbers'), draft.negativeNumbers, index => draft.negativeNumber === index,\n index => { set(each => { each.setNegativeNumber(index); }); }, size, 'mui-ex-sheet-format-cells-list'));\n }\n if (category === 'custom') {\n const why = draft.numberFormatRefusal;\n options.push(createElement(DraftField, {\n key: 'code', label: words.formatCellsLabel('type'), size, className: 'mui-ex-sheet-format-cells-code', value: () => draft.typeCode,\n typed: (text: string) => { set(each => { each.setType(text); }); }, ...(why === undefined ? {} : { error: words.formatCellsRefusal(why) }),\n }));\n }\n if (draft.types.length > 0) {\n options.push(codeList(`${id}-type`, words.formatCellsLabel(category === 'custom' ? 'codes' : 'type'), draft.types, (_, code) => draft.typeCode === code,\n (_, code) => { set(each => { each.setType(code); }); }, size, 'mui-ex-sheet-format-cells-list mui-ex-sheet-format-cells-types'));\n }\n return createElement('div', { className: 'mui-ex-sheet-format-cells-columns' },\n fieldset(words.formatCellsLabel('category'), 'mui-ex-sheet-format-cells-list',\n ...formatCellsOffer.categories.flatMap(({ category: each, enabled }) => {\n const reasonId = `${id}-reason-${each}`;\n const choice = radio(each, words.categoryName(each), size, {\n name: `${id}-category`, checked: draft.category === each, disabled: !enabled,\n ...(isDisabledCategory(each) ? { 'aria-describedby': reasonId } : {}), onChange: () => { set(one => { one.selectCategory(each); }); },\n });\n return isDisabledCategory(each)\n ? [choice, createElement(Typography<'p'>, {\n key: `${each}-reason`, id: reasonId, component: 'p', variant: 'caption', color: 'text.secondary', className: 'mui-ex-sheet-format-cells-reason',\n }, words.categoryDisabled(each))]\n : [choice];\n })),\n createElement('div', { className: 'mui-ex-sheet-format-cells-options' }, ...options));\n}\n\nfunction AlignmentTab({ draft, words, size, set }: TabProps): ReactElement {\n return nativeSelect(words.formatCellsLabel('horizontal'), size, draft.alignment,\n formatCellsOffer.alignments.map(alignment => ({ value: alignment, label: words.alignmentName(alignment) })),\n value => {\n const alignment = formatCellsOffer.alignments.find(each => each === value);\n if (alignment === undefined) throw new RangeError(`'${value}' is not an alignment Format Cells offers (ADR-0071).`);\n set(each => { each.setAlignment(alignment); });\n });\n}\n\n/** Case 23's palette as one group of radio buttons: Automatic or No Colour first, the theme's sixty and the ten\n * standard colours, each named as Excel names it, and More Colours, which takes a hex value. */\nfunction Palette({ draft, words, size, set, target, id }: TabProps & { readonly target: ColourTarget; readonly id: string }): ReactElement {\n const name = `${id}-palette-${target}`;\n const isFill = target === 'fill';\n const chosen = draft.colourOf(target);\n const swatches = (row: readonly PaletteSwatch[], key: string): ReactElement => createElement('div', { key, className: 'mui-ex-sheet-swatches' },\n ...row.map((swatch, index) => {\n const swatchName = words.swatchName(swatch);\n const paint = paintOf(swatch.colour);\n return createElement('input', {\n key: index, type: 'radio', name, className: 'mui-ex-sheet-swatch', 'aria-label': swatchName, title: swatchName, 'data-rgb': paint,\n style: { backgroundColor: paint }, checked: chosen !== undefined && !chosen.isAutomatic && chosen.equals(swatch.colour),\n onChange: () => { set(each => { each.setColour(target, swatch.colour); }); },\n });\n }));\n return createElement('div', {\n role: 'radiogroup', 'aria-label': words.formatCellsLabel(isFill ? 'backgroundColour' : 'colour'), className: 'mui-ex-sheet-palette',\n },\n radio('first', words.formatCellsLabel(isFill ? 'noColour' : 'automatic'), size, {\n name, checked: isFill ? chosen === undefined : chosen?.isAutomatic === true, onChange: () => { set(each => { each.setColour(target, undefined); }); },\n }),\n swatches(formatCellsOffer.themeColours.flat(), 'theme'),\n swatches(formatCellsOffer.standardColours, 'standard'),\n createElement(DraftField, {\n key: `hex-${target}`, label: words.formatCellsLabel('moreColours'), size, input: { maxLength: 7, placeholder: '#RRGGBB', 'data-target': target },\n className: 'mui-ex-sheet-more-colours', value: () => draft.colourText(target), typed: (text: string) => { set(each => { each.setColourText(target, text); }); },\n }));\n}\n\nfunction FontTab(props: TabProps & { readonly id: string }): ReactElement {\n const { draft, words, size, set, id } = props;\n return createElement('div', null,\n createElement('div', { className: 'mui-ex-sheet-format-cells-columns' },\n fieldset(words.formatCellsLabel('fontStyle'), 'mui-ex-sheet-format-cells-list',\n ...formatCellsOffer.fontStyles.map(style => radio(style, words.fontStyleName(style), size, {\n name: `${id}-font-style`, checked: draft.fontStyle === style, onChange: () => { set(each => { each.setFontStyle(style); }); },\n }))),\n createElement('div', { className: 'mui-ex-sheet-format-cells-options' },\n nativeSelect(words.formatCellsLabel('underline'), size, draft.underline ? 'single' : 'none',\n [{ value: 'none', label: words.formatCellsLabel('underlineNone') }, { value: 'single', label: words.formatCellsLabel('underlineSingle') }],\n value => { const single = value === 'single'; set(each => { each.setUnderline(single); }); }),\n checkbox(words.formatCellsLabel('strikethrough'), size, draft.strikethrough, checked => { set(each => { each.setStrikethrough(checked); }); }),\n // Excel's Normal font (ADR-0071, 2026-10-02): checking it sets every part of the Font to its default; it\n // shows checked while they are, so unchecking it changes nothing.\n checkbox(words.formatCellsLabel('normalFont'), size, draft.isNormalFont, checked => { if (checked) set(each => { each.setNormalFont(); }); }))),\n fieldset(words.formatCellsLabel('colour'), undefined, createElement(Palette, { ...props, target: 'font' })));\n}\n\n/** One stroke of a line style's sample, `y` down it. */\nfunction sampleLine(y: number, width: string, dashes: string | undefined): ReactElement {\n return createElement('line', { key: y, x1: 0, y1: y, x2: 56, y2: y, stroke: 'currentColor', strokeWidth: width, strokeDasharray: dashes });\n}\n\n/** A line style's sample: a stroke and its dashes. */\nfunction lineSample(style: BorderLineStyle): ReactElement {\n const { width, dashes } = formatCellsLineStroke(style);\n const lines = style === 'none' ? [] : style === 'double' ? [sampleLine(2.5, width, undefined), sampleLine(5.5, width, undefined)] : [sampleLine(4, width, dashes)];\n return createElement('svg', { className: 'mui-ex-sheet-format-cells-line', width: 56, height: 8, 'aria-hidden': true }, ...lines);\n}\n\n/** The preview: the range's edges as they will be, and an edge whose cells' sides differ as a grey dotted line. */\nfunction preview(draft: FormatCellsDraft, label: string): ReactElement {\n const edges: [Parameters<FormatCellsDraft['edgeLine']>[0], number, number, number, number][] = [\n ['top', 4, 4, 116, 4], ['bottom', 4, 68, 116, 68], ['left', 4, 4, 4, 68], ['right', 116, 4, 116, 68],\n ];\n if (draft.hasInsideHorizontal) edges.push(['insideHorizontal', 4, 36, 116, 36]);\n if (draft.hasInsideVertical) edges.push(['insideVertical', 60, 4, 60, 68]);\n const lines = edges.flatMap(([edge, x1, y1, x2, y2]) => {\n const line = draft.edgeLine(edge);\n if (line?.isNone === true) return [];\n if (line === undefined) {\n return [createElement('line', { key: edge, x1, y1, x2, y2, 'data-edge': edge, className: 'mui-ex-sheet-format-cells-differs', stroke: '#808080', strokeWidth: 1, strokeDasharray: '1 2' })];\n }\n const { width, dashes } = formatCellsLineStroke(line.style);\n return [createElement('line', { key: edge, x1, y1, x2, y2, 'data-edge': edge, stroke: paintOf(line.colour), strokeWidth: width, strokeDasharray: dashes })];\n });\n return createElement('svg', { className: 'mui-ex-sheet-format-cells-preview', width: 120, height: 72, viewBox: '0 0 120 72', role: 'img', 'aria-label': label }, ...lines);\n}\n\nfunction BorderTab(props: TabProps & { readonly id: string }): ReactElement {\n const { draft, words, size, set, id } = props;\n const pressedOf = (edge: Parameters<FormatCellsDraft['edgeLine']>[0]): 'true' | 'false' | 'mixed' => {\n const line = draft.edgeLine(edge);\n if (line === undefined) return 'mixed';\n return line.isNone ? 'false' : 'true';\n };\n return createElement('div', null,\n createElement('div', { className: 'mui-ex-sheet-format-cells-columns' },\n fieldset(words.formatCellsLabel('lineStyle'), undefined,\n createElement('div', { className: 'mui-ex-sheet-format-cells-columns' },\n ...formatCellsOffer.lineStyleColumns.map((column, at) => createElement('div', { key: at, className: 'mui-ex-sheet-format-cells-line-column' },\n ...column.map(style => radio(style, lineSample(style), size, {\n name: `${id}-line-style`, 'aria-label': words.lineStyleName(style), title: words.lineStyleName(style),\n checked: draft.lineStyle === style, onChange: () => { set(each => { each.setLineStyle(style); }); },\n })))))),\n createElement('div', { className: 'mui-ex-sheet-format-cells-options' },\n createElement('div', { role: 'group', 'aria-label': words.formatCellsLabel('presets'), className: 'mui-ex-sheet-format-cells-buttons' },\n ...formatCellsOffer.presets.map(preset => createElement(Button, {\n key: preset, type: 'button', size, variant: 'outlined', disabled: !draft.canApply(preset),\n onClick: () => { set(each => { each.applyPreset(preset); }); },\n }, words.presetName(preset)))),\n // An edge set is contained, one unset outlined, and one whose cells' sides differ outlined in the primary.\n createElement('div', { role: 'group', 'aria-label': words.formatCellsLabel('border'), className: 'mui-ex-sheet-format-cells-buttons' },\n ...formatCellsOffer.edges.map(edge => {\n const pressed = pressedOf(edge);\n const named = { 'data-edge': edge };\n return createElement(Button, {\n key: edge, type: 'button', size, variant: pressed === 'true' ? 'contained' : 'outlined', color: pressed === 'false' ? 'inherit' : 'primary',\n disabled: !draft.canSet(edge), 'aria-pressed': pressed, ...named, onClick: () => { set(each => { each.toggleEdge(edge); }); },\n }, words.edgeName(edge));\n })),\n preview(draft, words.formatCellsLabel('preview')))),\n fieldset(words.formatCellsLabel('colour'), undefined, createElement(Palette, { ...props, target: 'border' })));\n}\n\nfunction FillTab(props: TabProps & { readonly id: string }): ReactElement {\n return fieldset(props.words.formatCellsLabel('backgroundColour'), undefined, createElement(Palette, { ...props, target: 'fill' }));\n}\n\nfunction tabContents(tab: FormatCellsTab, props: TabProps & { readonly id: string }): ReactElement {\n switch (tab) {\n case 'number': return createElement(NumberTab, props);\n case 'alignment': return createElement(AlignmentTab, props);\n case 'font': return createElement(FontTab, props);\n case 'border': return createElement(BorderTab, props);\n case 'fill': return createElement(FillTab, props);\n default: throw new RangeError(`Unknown Format Cells tab '${String(tab satisfies never)}' (ADR-0071).`);\n }\n}\n\n// Unique on the page, for the radio groups' names and the tabs' ids: two Sheets' Format Cells each have their own.\nlet openings = 0;\n\n/** Format Cells in MUI's components, over the Sheet's draft. */\nexport function MuiFormatCells({ context }: { readonly context: SheetFormatCellsSlotContext }): ReactElement {\n const { tab, showTab, tabControl, set, refusal, submit, cancel } = useFormatCells(context);\n const { size } = useContext(MuiSizeContext);\n const [id] = useState(() => { openings += 1; return `mui-ex-sheet-format-cells-${String(openings)}`; });\n const { draft, words } = context;\n // OK checks its fields first, on every tab, since each tab stays drawn while another is shown (useFormatCells).\n return createElement('form', { className: 'mui-ex-sheet-format-cells', onSubmit: submit, noValidate: true },\n createElement(Tabs, {\n // The arrows show the tab they reach, as the built-in Format Cells' and Mantine's do.\n value: tab, variant: 'scrollable', scrollButtons: false, selectionFollowsFocus: true, 'aria-label': words.formatCellsLabel('tabs'), className: 'mui-ex-sheet-format-cells-tabs',\n onChange: (_: unknown, value: unknown) => {\n const shown = formatCellsOffer.tabs.find(each => each === value);\n if (shown === undefined) throw new RangeError(`'${String(value)}' is not a tab of Format Cells (ADR-0071).`);\n showTab(shown);\n },\n }, ...formatCellsOffer.tabs.map(each => createElement(Tab, {\n key: each, value: each, label: words.tabName(each), id: `${id}-tab-${each}`, 'aria-controls': `${id}-panel-${each}`,\n className: 'mui-ex-sheet-format-cells-tab', ...(each === tab ? { ref: tabControl } : {}),\n }))),\n // Every tab stays drawn, its fields as typed: a field left invalid is still refused by OK from another tab.\n ...formatCellsOffer.tabs.map(each => createElement('div', {\n key: each, role: 'tabpanel', id: `${id}-panel-${each}`, 'aria-labelledby': `${id}-tab-${each}`, hidden: each !== tab,\n className: 'mui-ex-sheet-format-cells-panel', 'data-ex-tab': each,\n }, tabContents(each, { draft, words, size, set, id }))),\n refusal === undefined ? null : createElement(Typography<'p'>, {\n role: 'alert', component: 'p', color: 'error', variant: textVariant(size), className: 'mui-ex-sheet-format-cells-refusal',\n }, refusal),\n createElement('div', { className: 'mui-ex-sheet-format-cells-actions' },\n createElement(Button, { type: 'submit', size, variant: 'contained' }, words.formatCellsLabel('ok')),\n createElement(Button, { type: 'button', size, variant: 'outlined', onClick: cancel }, words.formatCellsLabel('cancel'))));\n}\n", "// A Toolbar Item of the Sheet Toolbar in MUI's components (ADR-0100, ADR-0390): a toggle as MUI's ToggleButton,\n// selected in the theme's primary while the Focus cell has what it sets, a menu as a text Button that opens its list, a\n// split control as the face's IconButton beside an arrow's, and a Consumer's button as a text Button or IconButton. What\n// an item means, its list's opening and closing and the list's keys are ExSheet for React's `useToolbarItem`'s; this\n// draws them.\n//\n// The list is MUI's Popper on a Paper, kept inside the Sheet (no portal) so the Sheet hears its keys, and fixed to the\n// viewport so the toolbar's clipping does not cut it. MUI's Popover and Menu are not used: both are modal, trapping the\n// keyboard and putting a backdrop over the page, and Menu's MenuList answers the arrows itself. Each choice is MUI's\n// ListItemButton, as the grid's menus draw an item. MUI's Popper has no dismissal of its own; a press outside the item\n// is useToolbarItem's to hear.\n\nimport { createElement, useCallback, useContext, useRef, type CSSProperties, type ReactElement } from 'react';\nimport { Button, IconButton, ListItemButton, Paper, Popper, ToggleButton } from '@mui/material';\nimport { MuiSizeContext, type MuiExGridSize } from '@ex-grid/mui';\nimport { sheetToolbarPictures, type SheetToolbarIcon, type SheetToolbarItemSlotContext } from '@ex-grid/sheet';\nimport { useToolbarItem, type ToolbarItemHandles } from '@ex-grid/sheet-react';\n\n/** A picture of the built-in Chrome's, in the text's colour. */\nfunction picture(icon: SheetToolbarIcon): ReactElement {\n return createElement('svg', {\n className: 'mui-ex-sheet-toolbar-icon', viewBox: '0 0 16 16', 'aria-hidden': true, focusable: false, fill: 'none', stroke: 'currentColor',\n strokeLinecap: 'round', strokeLinejoin: 'round', dangerouslySetInnerHTML: { __html: sheetToolbarPictures[icon] },\n });\n}\n\n/** The arrow a list opens from. */\nfunction caret(): ReactElement {\n return createElement('svg', {\n className: 'mui-ex-sheet-toolbar-caret', viewBox: '0 0 16 16', 'aria-hidden': true, focusable: false, fill: 'none',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }, createElement('path', { d: 'M4.5 6.5 8 10l3.5-3.5' }));\n}\n\n/** A Consumer's own content, mounted into the element its callback ref is handed and taken away with it. */\nfunction OwnContent({ mount }: { readonly mount: (element: HTMLElement) => () => void }): ReactElement {\n const taken = useRef<(() => void) | undefined>(undefined);\n const ref = useCallback((element: HTMLSpanElement | null) => {\n taken.current?.();\n taken.current = element === null ? undefined : mount(element);\n }, [mount]);\n return createElement('span', { ref, className: 'mui-ex-sheet-toolbar-content' });\n}\n\n/** An item's list: its choices, words and swatches as the Sheet hands them, in the theme's look. */\nfunction ChoiceList({ item, size }: { readonly item: ToolbarItemHandles; readonly size: MuiExGridSize }): ReactElement {\n const { view, list, choice: props } = item;\n const option = (index: number): ReactElement => {\n const choice = view.choices[index];\n if (choice === undefined) throw new RangeError(`The list of ${view.name} has no choice ${String(index)} (ADR-0100).`);\n const common = { key: index, ...props(index) };\n if (choice.swatch !== undefined) {\n return createElement('button', {\n ...common, type: 'button', 'aria-label': choice.label, className: 'mui-ex-sheet-swatch', style: { backgroundColor: choice.swatch },\n });\n }\n // Not `disabled`: a choice that cannot be made keeps its title, which says why, where the pointer reaches it.\n return createElement(ListItemButton<'button'>, {\n ...common, component: 'button', type: 'button', dense: size.dense, selected: choice.selected, className: 'mui-ex-sheet-choice',\n }, choice.label);\n };\n // The choices one to a row and the swatches ten across, in the Sheet's order, as the list's keys move among them.\n const rows = item.rows.map((row, at) => (typeof row === 'number'\n ? option(row)\n : createElement('div', { key: `s${String(at)}`, className: 'mui-ex-sheet-swatches', role: 'none' }, ...row.map(option))));\n return createElement('div', { ...list, className: 'mui-ex-sheet-choices' }, ...rows);\n}\n\n/** A Toolbar Item in MUI's components, its list included. */\nexport function MuiToolbarItem({ context }: { readonly context: SheetToolbarItemSlotContext }): ReactElement {\n const item = useToolbarItem(context);\n const { view, open, control, toggleList } = item;\n const size = useContext(MuiSizeContext);\n const anchor = useRef<HTMLElement | null>(null);\n const face = view.content !== undefined\n ? createElement(OwnContent, { mount: view.content })\n : view.icon !== undefined ? picture(view.icon) : (view.text ?? view.name);\n const press = (): void => { context.invoke(); };\n // The element the list opens beneath: the menu's button, or the split control's pair.\n const listAnchor = useCallback((element: HTMLElement | null) => { anchor.current = element; }, []);\n const anchorOf = useCallback((): HTMLElement => {\n if (anchor.current === null) throw new Error(`Internal: ${context.kind} drew no element for its list to open beneath.`);\n return anchor.current;\n }, [context.kind]);\n // A colour control's face shows the colour it sets beneath its picture; the colour is the user's, written inline.\n const swatch: (CSSProperties & Readonly<Record<'--mui-ex-sheet-swatch', string>>) | undefined = view.swatch === undefined ? undefined : { '--mui-ex-sheet-swatch': view.swatch };\n let drawn: ReactElement;\n switch (context.kind) {\n case 'toggle':\n // ToggleButton writes aria-pressed from `selected` itself.\n drawn = createElement(ToggleButton, {\n ...control, value: context.id, size: size.size, selected: view.pressed, color: 'primary', 'aria-label': view.name,\n className: 'mui-ex-sheet-toolbar-toggle', onClick: press,\n }, face);\n break;\n case 'menu':\n drawn = createElement(Button, {\n ...control, ref: listAnchor, type: 'button', size: size.size, variant: 'text', color: 'inherit', 'aria-label': view.name,\n 'aria-haspopup': 'menu', 'aria-expanded': open, endIcon: caret(), className: 'mui-ex-sheet-toolbar-menu', onClick: toggleList,\n }, view.text ?? view.name);\n break;\n case 'split':\n drawn = createElement('span', { ref: listAnchor, className: 'mui-ex-sheet-toolbar-split', role: 'group', 'aria-label': view.name },\n createElement(IconButton, {\n ...control, type: 'button', size: size.size, color: 'inherit', 'aria-label': view.name, className: 'mui-ex-sheet-toolbar-face',\n ...(swatch === undefined ? {} : { style: swatch }), onClick: press,\n }, face),\n createElement(IconButton, {\n ...control, type: 'button', size: size.size, color: 'inherit', 'aria-label': view.moreName ?? view.name,\n 'aria-haspopup': 'menu', 'aria-expanded': open, className: 'mui-ex-sheet-toolbar-arrow', onClick: toggleList,\n }, caret()));\n break;\n case 'button':\n drawn = view.content === undefined && view.icon !== undefined\n ? createElement(IconButton, {\n ...control, type: 'button', size: size.size, color: 'inherit', 'aria-label': view.name, onClick: press,\n }, face)\n : createElement(Button, {\n ...control, type: 'button', size: size.size, variant: 'text', color: 'inherit', 'aria-label': view.name,\n className: 'mui-ex-sheet-toolbar-button', onClick: press,\n }, face);\n break;\n default:\n throw new RangeError(`Unknown Toolbar Item kind '${String(context.kind satisfies never)}' (ADR-0100).`);\n }\n const classes = ['mui-ex-sheet-toolbar-item'];\n if (view.active) classes.push('mui-ex-sheet-toolbar-active');\n return createElement('span', { ref: item.item, className: classes.join(' ') }, drawn,\n !item.hasList || !open ? null : createElement(Popper, {\n open, anchorEl: anchorOf, disablePortal: true, placement: 'bottom-start',\n className: 'mui-ex-sheet-toolbar-popper', popperOptions: { strategy: 'fixed' },\n modifiers: [{ name: 'offset', options: { offset: [0, 2] } }],\n }, createElement(Paper, { elevation: 8, className: 'mui-ex-sheet-toolbar-list' }, createElement(ChoiceList, { item, size }))));\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["createElement", "Paper", "MuiSizeContext", "createElement", "useContext", "Typography", "MuiSizeContext", "createElement", "useContext", "Button", "MuiSizeContext", "useContext", "MuiSizeContext", "createElement", "Typography", "createElement", "Paper", "MuiSizeContext"]
7
+ }
package/package.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@ex-grid/sheet-mui",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0-beta.3",
4
+ "description": "ExSheet for MUI: the design-system Wrapper that draws ExSheet for React's Chrome, the Sheet Toolbar, Format Cells and the Sheet Tabs among it, with MUI's components and maps its Visual Tokens onto a MUI theme made with CSS variables.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/AkiraMisawa/ex-grid.git",
9
+ "directory": "packages/sheet-mui"
10
+ },
11
+ "homepage": "https://akiramisawa.github.io/ex-grid/",
12
+ "type": "module",
13
+ "sideEffects": [
14
+ "*.css"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ },
21
+ "./styles.css": "./styles.css"
22
+ },
23
+ "files": [
24
+ "dist/index.js",
25
+ "dist/index.js.map",
26
+ "dist/index.d.ts",
27
+ "styles.css"
28
+ ],
29
+ "dependencies": {
30
+ "@ex-grid/mui": "0.2.0-beta.3",
31
+ "@ex-grid/sheet": "0.2.0-beta.3",
32
+ "@ex-grid/sheet-engine": "0.2.0-beta.3",
33
+ "@ex-grid/sheet-react": "0.2.0-beta.3"
34
+ },
35
+ "peerDependencies": {
36
+ "@emotion/react": "^11.14.0",
37
+ "@emotion/styled": "^11.14.0",
38
+ "@mui/material": "^9.5.0",
39
+ "react": "^19.2.0",
40
+ "react-dom": "^19.2.0"
41
+ }
42
+ }
package/styles.css ADDED
@@ -0,0 +1,224 @@
1
+ /* @ex-grid/sheet-mui — the Sheet Wrapper's stylesheet (ADR-0390 section 5, ADR-0030), loaded beside @ex-grid/mui's.
2
+ The grid's tokens are @ex-grid/mui's, under the Paper's .mui-ex-grid; these rules dress the Sheet's own Chrome, the
3
+ Sheet Toolbar, the Sheet Tabs and Format Cells, in the variables a MUI theme made with cssVariables writes, and lay
4
+ out the Wrapper's own elements. They set no geometry the Sheet or the grid computes with: the toolbar's rows and the
5
+ tabs' band keep the heights the Sheet writes inline (ADR-0028). The Paper and the Ink, what the cells lie on, stay
6
+ the Sheet's in every scheme, never MUI's background (ADR-0071). Every rule is scoped under .mui-ex-sheet, so it
7
+ outranks ex-sheet.css's bare-class defaults whatever order the two load in, and every variable it reads is one MUI
8
+ writes again per colour scheme, so it names no scheme selector of its own. */
9
+
10
+ /* The Sheet's Chrome is set in MUI's font: only the cells keep the Sheet's own, whose widths its columns are counted
11
+ in (ADR-0027). */
12
+ .mui-ex-sheet .ex-sheet-toolbar,
13
+ .mui-ex-sheet .ex-sheet-tab-area {
14
+ font: var(--mui-font-body2);
15
+ }
16
+
17
+ /* The Sheet Toolbar (ADR-0100): MUI's controls inside the Sheet's band, whose rows stay the Sheet's. The item the
18
+ band's keyboard stands on is outlined in the theme's primary, as MUI marks a control the keyboard is on. */
19
+ .mui-ex-sheet .mui-ex-sheet-toolbar-item {
20
+ position: relative;
21
+ display: inline-flex;
22
+ align-items: center;
23
+ height: 100%;
24
+ border-radius: var(--mui-shape-borderRadius);
25
+ }
26
+ .mui-ex-sheet .mui-ex-sheet-toolbar-active {
27
+ outline: 2px solid var(--mui-palette-primary-main);
28
+ outline-offset: -1px;
29
+ }
30
+ .mui-ex-sheet .mui-ex-sheet-toolbar-icon,
31
+ .mui-ex-sheet .mui-ex-sheet-toolbar-caret {
32
+ width: 16px;
33
+ height: 16px;
34
+ }
35
+ /* MUI takes pointer events from a disabled control, which would hide its title, the reason it cannot be pressed; the
36
+ browser still sends a disabled button no click. */
37
+ .mui-ex-sheet .mui-ex-sheet-toolbar-item .Mui-disabled {
38
+ pointer-events: auto;
39
+ cursor: default;
40
+ }
41
+ /* A toggle stands in a toolbar, not a group: no border of its own, MUI's selected shade showing it pressed. */
42
+ .mui-ex-sheet .mui-ex-sheet-toolbar-toggle {
43
+ border: 0;
44
+ padding: 4px;
45
+ }
46
+ .mui-ex-sheet .mui-ex-sheet-toolbar-item .MuiIconButton-sizeSmall {
47
+ padding: 4px;
48
+ }
49
+ .mui-ex-sheet .mui-ex-sheet-toolbar-menu,
50
+ .mui-ex-sheet .mui-ex-sheet-toolbar-button {
51
+ min-width: 0;
52
+ padding-block: 2px;
53
+ font-weight: 400;
54
+ text-transform: none;
55
+ }
56
+ .mui-ex-sheet .mui-ex-sheet-toolbar-menu .MuiButton-endIcon {
57
+ margin-left: 2px;
58
+ }
59
+ .mui-ex-sheet .mui-ex-sheet-toolbar-split {
60
+ display: inline-flex;
61
+ align-items: center;
62
+ }
63
+ .mui-ex-sheet .mui-ex-sheet-toolbar-split .mui-ex-sheet-toolbar-arrow {
64
+ padding: 4px 0;
65
+ border-radius: var(--mui-shape-borderRadius);
66
+ }
67
+ /* A colour control's face shows the colour it sets beneath its picture, as Excel's does: the colour is the user's,
68
+ written inline. */
69
+ .mui-ex-sheet .mui-ex-sheet-toolbar-face {
70
+ border-radius: var(--mui-shape-borderRadius);
71
+ box-shadow: inset 0 -3px 0 var(--mui-ex-sheet-swatch, transparent);
72
+ }
73
+ .mui-ex-sheet .mui-ex-sheet-toolbar-content {
74
+ display: inline-flex;
75
+ align-items: center;
76
+ }
77
+
78
+ /* A Toolbar Item's list, MUI's Popper on a Paper: above the page as MUI's menus are, the choices one to a row and the
79
+ swatches ten across, as Excel's palette lays them out. */
80
+ .mui-ex-sheet .mui-ex-sheet-toolbar-popper {
81
+ z-index: var(--mui-zIndex-modal);
82
+ }
83
+ .mui-ex-sheet .mui-ex-sheet-toolbar-list {
84
+ padding: 4px 0;
85
+ }
86
+ .mui-ex-sheet .mui-ex-sheet-choices {
87
+ display: flex;
88
+ flex-direction: column;
89
+ min-width: 10em;
90
+ max-height: 60vh;
91
+ overflow-y: auto;
92
+ }
93
+ /* Only the width and the text: ButtonBase already takes the button's own border and ground away, and a background set
94
+ here would tie with MUI's hover, selected and keyboard-focus shades. */
95
+ .mui-ex-sheet .mui-ex-sheet-choice {
96
+ width: 100%;
97
+ font: var(--mui-font-body2);
98
+ }
99
+ .mui-ex-sheet .mui-ex-sheet-choice[aria-disabled="true"] {
100
+ color: var(--mui-palette-text-disabled);
101
+ cursor: default;
102
+ }
103
+ .mui-ex-sheet .mui-ex-sheet-swatches {
104
+ display: grid;
105
+ grid-template-columns: repeat(10, 18px);
106
+ gap: 4px;
107
+ padding: 4px 8px;
108
+ }
109
+ .mui-ex-sheet .mui-ex-sheet-swatch {
110
+ appearance: none;
111
+ width: 18px;
112
+ height: 18px;
113
+ margin: 0;
114
+ padding: 0;
115
+ border: 1px solid var(--mui-palette-divider);
116
+ border-radius: 2px;
117
+ cursor: pointer;
118
+ }
119
+ .mui-ex-sheet .mui-ex-sheet-swatch[aria-checked="true"],
120
+ .mui-ex-sheet .mui-ex-sheet-swatch:checked {
121
+ outline: 2px solid var(--mui-palette-primary-main);
122
+ outline-offset: 1px;
123
+ }
124
+ .mui-ex-sheet .mui-ex-sheet-swatch:focus-visible {
125
+ outline: 2px solid var(--mui-palette-primary-main);
126
+ outline-offset: 3px;
127
+ }
128
+
129
+ /* The Sheet Tabs (ADR-0331 §4): the selected tab's rule in the theme's primary, as MUI's Tabs draw their indicator,
130
+ its face in MUI's text. The tabs themselves, their band and their keyboard, are the Sheet's. */
131
+ .mui-ex-sheet .ex-sheet-tab[aria-selected="true"] {
132
+ border-bottom-color: var(--mui-palette-primary-main);
133
+ }
134
+ .mui-ex-sheet .ex-sheet-tab-face {
135
+ display: inline-flex;
136
+ align-items: center;
137
+ }
138
+ .mui-ex-sheet .mui-ex-sheet-tab-add-face {
139
+ width: 14px;
140
+ height: 14px;
141
+ vertical-align: middle;
142
+ }
143
+
144
+ /* Format Cells (ADR-0071) inside the grid's popover frame, whose place and bound stay the grid's (ADR-0040). */
145
+ .mui-ex-sheet .mui-ex-sheet-format-cells {
146
+ display: flex;
147
+ flex-direction: column;
148
+ gap: 8px;
149
+ padding: 8px;
150
+ min-width: 28em;
151
+ color: var(--mui-palette-text-primary);
152
+ }
153
+ .mui-ex-sheet .mui-ex-sheet-format-cells-tabs {
154
+ border-bottom: 1px solid var(--mui-palette-divider);
155
+ }
156
+ .mui-ex-sheet .mui-ex-sheet-format-cells-tab {
157
+ text-transform: none;
158
+ }
159
+ .mui-ex-sheet .mui-ex-sheet-format-cells-panel {
160
+ min-height: 18em;
161
+ padding-top: 8px;
162
+ }
163
+ .mui-ex-sheet .mui-ex-sheet-format-cells-columns {
164
+ display: flex;
165
+ gap: 16px;
166
+ align-items: flex-start;
167
+ }
168
+ .mui-ex-sheet .mui-ex-sheet-format-cells-options {
169
+ display: flex;
170
+ flex-direction: column;
171
+ gap: 8px;
172
+ flex: 1 1 auto;
173
+ min-width: 0;
174
+ }
175
+ .mui-ex-sheet .mui-ex-sheet-legend {
176
+ margin-bottom: 4px;
177
+ font: var(--mui-font-body2);
178
+ font-weight: 500;
179
+ }
180
+ .mui-ex-sheet .mui-ex-sheet-format-cells-list,
181
+ .mui-ex-sheet .mui-ex-sheet-format-cells-line-column {
182
+ display: flex;
183
+ flex-direction: column;
184
+ }
185
+ .mui-ex-sheet .mui-ex-sheet-label {
186
+ margin-inline: 0;
187
+ }
188
+ .mui-ex-sheet .mui-ex-sheet-format-cells-reason {
189
+ margin: 0 0 4px 2.5em;
190
+ }
191
+ .mui-ex-sheet .mui-ex-sheet-format-cells-types {
192
+ max-height: 12em;
193
+ overflow-y: auto;
194
+ flex-wrap: nowrap;
195
+ }
196
+ .mui-ex-sheet .mui-ex-sheet-format-cells-dropdown,
197
+ .mui-ex-sheet .mui-ex-sheet-more-colours {
198
+ max-width: 16em;
199
+ }
200
+ .mui-ex-sheet .mui-ex-sheet-format-cells-buttons {
201
+ display: flex;
202
+ flex-wrap: wrap;
203
+ gap: 4px;
204
+ }
205
+ .mui-ex-sheet .mui-ex-sheet-format-cells-buttons .MuiButton-root {
206
+ text-transform: none;
207
+ }
208
+ .mui-ex-sheet .mui-ex-sheet-format-cells-preview {
209
+ border: 1px solid var(--mui-palette-divider);
210
+ color: var(--mui-palette-text-primary);
211
+ }
212
+ .mui-ex-sheet .mui-ex-sheet-palette {
213
+ display: flex;
214
+ flex-direction: column;
215
+ gap: 6px;
216
+ }
217
+ .mui-ex-sheet .mui-ex-sheet-palette .mui-ex-sheet-swatches {
218
+ padding: 0;
219
+ }
220
+ .mui-ex-sheet .mui-ex-sheet-format-cells-actions {
221
+ display: flex;
222
+ justify-content: flex-end;
223
+ gap: 8px;
224
+ }