@ex-grid/chart-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/chart-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
+ ExChart for MUI: the design-system Wrapper that draws ExChart for React's toolbar and context menu with MUI's components, docks the charts made from a grid's selection beside it in MUI's tabs, and maps the chart's 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/chart-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/chart`, `@ex-grid/chart-react`, `@ex-grid/core` and `@ex-grid/mui` 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/chart/styles.css';
23
+ import '@ex-grid/chart-mui/styles.css';
24
+ ```
25
+
26
+ ## Documentation
27
+
28
+ [ExChart on the documentation site](https://akiramisawa.github.io/ex-grid/exchart), 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,58 @@
1
+ /**
2
+ * ExChart for MUI (ADR-0390): `muiChartChrome` draws ExChart for React's toolbar and context menu in MUI's
3
+ * components, and `MuiChartDock` docks the charts made from a grid's selection beside the grid or below it in MUI's
4
+ * tabs. Its stylesheet, `@ex-grid/chart-mui/styles.css`, maps the chart's Visual Tokens onto a MUI theme made with
5
+ * CSS variables, so a change of scheme recolours every chart with no render.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+
10
+ import { ChartDockPlacement } from '@ex-grid/chart-react';
11
+ import { ChartDockState } from '@ex-grid/chart-react';
12
+ import { CSSProperties } from 'react';
13
+ import { ExChartChrome } from '@ex-grid/chart-react';
14
+ import type { GridChartBridge } from '@ex-grid/chart';
15
+ import type { GridDensity } from '@ex-grid/core';
16
+ import { ReactElement } from 'react';
17
+ import { ReactNode } from 'react';
18
+
19
+ /** ExChart's Chrome drawn in MUI's components: hand it as an ExChart's `chrome`, inside a ThemeProvider whose theme
20
+ * was made with `cssVariables: true` and with `@ex-grid/chart-mui/styles.css` loaded. {@link MuiChartDock} hands it
21
+ * to every chart it holds. */
22
+ export declare const muiChartChrome: ExChartChrome;
23
+
24
+ /**
25
+ * The Chart Dock (ADR-0258) drawn with MUI: the grid, and a panel of MUI's tabs beside it or below it holding the
26
+ * charts made from its selection. The context menu's "Chart selection" opens a tab directly, "Add to chart" offers
27
+ * every open tab, a refusal is said in an alert above the tabs, and a click on a point shows its cell. A tab not shown
28
+ * keeps its chart, with its range and its open Chart Filters. Needs a ThemeProvider whose theme was made with
29
+ * `cssVariables: true` above it, and `@ex-grid/chart-mui/styles.css` loaded.
30
+ */
31
+ export declare function MuiChartDock<Row>(props: MuiChartDockProps<Row>): ReactElement;
32
+
33
+ /** A MuiChartDock's props. */
34
+ export declare interface MuiChartDockProps<Row> {
35
+ /** The dock's state, from `useChartDock`, whose `bridgeOptions` the bridge was made with. */
36
+ readonly dock: ChartDockState;
37
+ /** The bridge of the grid in `children`, which draws each chart from the grid's rows. */
38
+ readonly bridge: GridChartBridge<Row>;
39
+ /** The grid, and anything to stand beside the charts. */
40
+ readonly children?: ReactNode;
41
+ /** Where the charts go: beside the grid, the default, or below it. */
42
+ readonly placement?: ChartDockPlacement;
43
+ /** Each chart's width in CSS pixels; 640 unless given. */
44
+ readonly chartWidth?: number;
45
+ /** Each chart's height in CSS pixels; 320 unless given. */
46
+ readonly chartHeight?: number;
47
+ /** The grid's Density, which picks the size the charts' toolbar, Chart Filters and menu are drawn at, as it picks
48
+ * the grid's Chrome's (ADR-0390); compact, `small` and dense, unless given. */
49
+ readonly density?: GridDensity;
50
+ /** What draws each chart's toolbar and context menu; {@link muiChartChrome} unless given. */
51
+ readonly chrome?: ExChartChrome;
52
+ /** A class for the dock's own element. */
53
+ readonly className?: string;
54
+ /** A style for the dock's own element. */
55
+ readonly style?: CSSProperties;
56
+ }
57
+
58
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,243 @@
1
+ // src/chart-chrome.ts
2
+ import { createElement, useContext } from "react";
3
+ import { Alert, Button, ButtonGroup, ListItemButton, TextField } from "@mui/material";
4
+ import { useTheme } from "@mui/material/styles";
5
+ import { chartWordIds } from "@ex-grid/chart";
6
+ import { useChartFilterText } from "@ex-grid/chart-react";
7
+ import { MuiSizeContext, refuseThemeWithoutVariables } from "@ex-grid/mui";
8
+ var downloads = /* @__PURE__ */ new Set([chartWordIds.downloadCsv, chartWordIds.downloadSvg, chartWordIds.downloadPng]);
9
+ function commandButton(command, size) {
10
+ return createElement(Button, {
11
+ key: command.id,
12
+ type: "button",
13
+ size,
14
+ variant: command.expanded === true ? "outlined" : "text",
15
+ disabled: !command.enabled,
16
+ onClick: command.invoke,
17
+ className: "mui-ex-chart-command",
18
+ ...command.expanded === void 0 ? {} : { "aria-expanded": command.expanded },
19
+ ...command.title === void 0 ? {} : { title: command.title }
20
+ }, command.label);
21
+ }
22
+ function MuiChartFilters({ context, filters }) {
23
+ const { size } = useContext(MuiSizeContext);
24
+ const typed = useChartFilterText(filters);
25
+ const end = (id, value, set) => filters.values === "labels" ? createElement(TextField, {
26
+ key: id,
27
+ size,
28
+ select: true,
29
+ label: context.label(id),
30
+ value,
31
+ className: "mui-ex-chart-end",
32
+ slotProps: { select: { native: true }, inputLabel: { shrink: true } },
33
+ onChange: (event) => {
34
+ set(event.target.value);
35
+ }
36
+ }, createElement("option", { key: "", value: "" }, ""), ...filters.labels.map((label) => createElement("option", { key: label, value: label }, label))) : createElement(TextField, {
37
+ key: id,
38
+ size,
39
+ label: context.label(id),
40
+ value,
41
+ placeholder: filters.hint,
42
+ className: "mui-ex-chart-end",
43
+ slotProps: { inputLabel: { shrink: true } },
44
+ onChange: (event) => {
45
+ set(event.target.value);
46
+ }
47
+ });
48
+ return createElement(
49
+ "div",
50
+ { className: "mui-ex-chart-filters", role: "group", "aria-label": context.label(chartWordIds.filters) },
51
+ end(chartWordIds.from, typed.from, typed.setFrom),
52
+ end(chartWordIds.to, typed.to, typed.setTo),
53
+ createElement(Button, {
54
+ type: "button",
55
+ size,
56
+ variant: "outlined",
57
+ className: "mui-ex-chart-apply",
58
+ onClick: typed.apply
59
+ }, context.label(chartWordIds.apply)),
60
+ filters.scale === void 0 ? null : createElement(
61
+ TextField,
62
+ {
63
+ size,
64
+ select: true,
65
+ label: context.label(chartWordIds.axis),
66
+ value: filters.scale,
67
+ className: "mui-ex-chart-scale",
68
+ slotProps: { select: { native: true } },
69
+ onChange: (event) => {
70
+ filters.setScale(scaleOf(event.target.value));
71
+ }
72
+ },
73
+ createElement("option", { value: "proportional" }, context.label(chartWordIds.proportional)),
74
+ createElement("option", { value: "categories" }, context.label(chartWordIds.categories))
75
+ ),
76
+ filters.error === null ? null : createElement(Alert, { severity: "error", className: "mui-ex-chart-filter-error" }, filters.error)
77
+ );
78
+ }
79
+ function scaleOf(value) {
80
+ if (value === "proportional" || value === "categories") return value;
81
+ throw new RangeError(`'${value}' is not a scale the axis switch offers (ADR-0251).`);
82
+ }
83
+ function MuiChartToolbar({ context }) {
84
+ refuseThemeWithoutVariables(useTheme(), "muiChartChrome");
85
+ const { size } = useContext(MuiSizeContext);
86
+ const { filters } = context;
87
+ return createElement(
88
+ "div",
89
+ { className: "mui-ex-chart-chrome" },
90
+ createElement(
91
+ "div",
92
+ { className: "mui-ex-chart-toolbar", role: "toolbar", "aria-label": context.name },
93
+ ...context.commands.filter((command) => !downloads.has(command.id)).map((command) => commandButton(command, size)),
94
+ // MUI's ButtonGroup is a group already, named here as the downloads.
95
+ createElement(
96
+ ButtonGroup,
97
+ { size, variant: "outlined", "aria-label": context.label(chartWordIds.downloads), className: "mui-ex-chart-downloads" },
98
+ ...context.commands.filter((command) => downloads.has(command.id)).map((command) => createElement(Button, {
99
+ key: command.id,
100
+ type: "button",
101
+ disabled: !command.enabled,
102
+ onClick: command.invoke,
103
+ ...command.title === void 0 ? {} : { title: command.title }
104
+ }, command.label))
105
+ )
106
+ ),
107
+ filters === void 0 ? null : createElement(MuiChartFilters, { context, filters })
108
+ );
109
+ }
110
+ function MuiChartMenu({ context }) {
111
+ const { dense } = useContext(MuiSizeContext);
112
+ return createElement(
113
+ "div",
114
+ { role: "none", className: "mui-ex-chart-menu" },
115
+ ...context.commands.map((command) => createElement(ListItemButton, {
116
+ key: command.id,
117
+ component: "button",
118
+ type: "button",
119
+ role: "menuitem",
120
+ dense,
121
+ disabled: !command.enabled,
122
+ onClick: command.invoke,
123
+ className: "mui-ex-chart-menu-item"
124
+ }, command.label))
125
+ );
126
+ }
127
+ var muiChartChrome = Object.freeze({
128
+ toolbar: (context) => createElement(MuiChartToolbar, { context }),
129
+ menu: (context) => createElement(MuiChartMenu, { context })
130
+ });
131
+
132
+ // src/mui-chart-dock.ts
133
+ import { createElement as createElement2, useId } from "react";
134
+ import { Alert as Alert2, IconButton, Paper, Tab, Tabs } from "@mui/material";
135
+ import { useTheme as useTheme2 } from "@mui/material/styles";
136
+ import { DockedChart, useChartDockKeyboard } from "@ex-grid/chart-react";
137
+ import { MuiSizeContext as MuiSizeContext2, muiSizeOf, refuseThemeWithoutVariables as refuseThemeWithoutVariables2 } from "@ex-grid/mui";
138
+ var refused = (why) => createElement2(Alert2, { severity: "warning", className: "mui-ex-chart-dock-refusal" }, why);
139
+ var cross = createElement2(
140
+ "svg",
141
+ { viewBox: "0 0 16 16", width: 12, height: 12, "aria-hidden": true, focusable: false },
142
+ createElement2("path", { d: "M4 4l8 8M12 4l-8 8", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round" })
143
+ );
144
+ function MuiChartDock(props) {
145
+ const {
146
+ dock,
147
+ bridge,
148
+ children,
149
+ placement = "right",
150
+ chartWidth = 640,
151
+ chartHeight = 320,
152
+ density = "compact",
153
+ chrome = muiChartChrome,
154
+ className,
155
+ style
156
+ } = props;
157
+ const ids = useId();
158
+ refuseThemeWithoutVariables2(useTheme2(), "MuiChartDock");
159
+ const keyboard = useChartDockKeyboard(dock);
160
+ const { charts, active, refusal } = dock;
161
+ const classes = ["mui-ex-chart", "mui-ex-chart-dock", `mui-ex-chart-dock-${placement}`];
162
+ if (className !== void 0) classes.push(className);
163
+ const panelStyle = placement === "right" ? { flex: "0 0 auto", boxSizing: "content-box", width: chartWidth } : void 0;
164
+ const tabId = (index) => `${ids}-tab-${String(index)}`;
165
+ const panelId = (index) => `${ids}-panel-${String(index)}`;
166
+ const panel = charts.length === 0 && refusal === void 0 ? null : createElement2(
167
+ Paper,
168
+ {
169
+ ref: keyboard.panel,
170
+ variant: "outlined",
171
+ className: "mui-ex-chart-dock-panel",
172
+ role: "region",
173
+ "aria-label": "Charts",
174
+ ...panelStyle === void 0 ? {} : { style: panelStyle }
175
+ },
176
+ refusal === void 0 ? null : createElement2(Alert2, {
177
+ severity: "warning",
178
+ onClose: dock.dismiss,
179
+ closeText: "Dismiss",
180
+ className: "mui-ex-chart-dock-refusal"
181
+ }, refusal),
182
+ charts.length === 0 ? null : createElement2(Tabs, {
183
+ value: active ?? false,
184
+ variant: "scrollable",
185
+ scrollButtons: "auto",
186
+ className: "mui-ex-chart-dock-tabs",
187
+ // oxlint-disable-line ex-grid/no-stand-in-default -- MUI's Tabs say "no tab" as false
188
+ onChange: (_, value) => {
189
+ if (typeof value !== "string") throw new TypeError("A Chart Dock's tab is named by its chart.");
190
+ dock.select(value);
191
+ }
192
+ }, ...charts.map(({ name }, index) => createElement2(Tab, {
193
+ key: name,
194
+ value: name,
195
+ id: tabId(index),
196
+ "aria-controls": panelId(index),
197
+ className: "mui-ex-chart-dock-tab-button",
198
+ // Delete closes the tab the keyboard is on, as the close mark does under the pointer.
199
+ onKeyDown: (event) => {
200
+ if (event.key === "Delete") keyboard.closeByKey(name);
201
+ },
202
+ label: createElement2(
203
+ "span",
204
+ { className: "mui-ex-chart-dock-label" },
205
+ name,
206
+ // A span, not a button: a button inside the tab's button is not one the browser lets stand.
207
+ createElement2(IconButton, {
208
+ component: "span",
209
+ role: "button",
210
+ size: "small",
211
+ "aria-label": `Close ${name}`,
212
+ // Off the Tab order: Delete closes from the keyboard, and a stop inside each tab's button would be one
213
+ // the tabs' own roving order does not know.
214
+ tabIndex: -1,
215
+ className: "mui-ex-chart-dock-close",
216
+ onClick: (event) => {
217
+ event.stopPropagation();
218
+ dock.close(name);
219
+ }
220
+ }, cross)
221
+ )
222
+ }))),
223
+ ...charts.map((target, index) => createElement2("div", {
224
+ key: target.name,
225
+ role: "tabpanel",
226
+ id: panelId(index),
227
+ "aria-labelledby": tabId(index),
228
+ hidden: target.name !== active,
229
+ className: "mui-ex-chart-dock-tab"
230
+ }, createElement2(DockedChart, { bridge, target, width: chartWidth, height: chartHeight, chrome, refused })))
231
+ );
232
+ return createElement2(
233
+ "div",
234
+ { className: classes.join(" "), ...style === void 0 ? {} : { style } },
235
+ createElement2("div", { ref: keyboard.content, className: "mui-ex-chart-dock-content" }, children),
236
+ createElement2(MuiSizeContext2.Provider, { value: muiSizeOf(density) }, panel)
237
+ );
238
+ }
239
+ export {
240
+ MuiChartDock,
241
+ muiChartChrome
242
+ };
243
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/chart-chrome.ts", "../src/mui-chart-dock.ts"],
4
+ "sourcesContent": ["// ExChart's Chrome under MUI (ADR-0281, ADR-0390): the toolbar, with Chart Filters' range in MUI's fields and the\n// axis switch, and the context menu's items, in MUI's components at the size the dock or the grid's density maps\n// onto. Which commands there are, what a typed range means, what is refused and where the menu opens are the chart's;\n// these components draw what the chart hands them and call back. The legend, the tooltip and the plot stay the\n// chart's own (ADR-0255). MUI's Menu and MenuList are not used: the menu's frame is the chart's, which takes the keys.\n\nimport { createElement, useContext, type ReactElement } from 'react';\nimport { Alert, Button, ButtonGroup, ListItemButton, TextField } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { chartWordIds, type AxisScale, type ChartCommand, type ChartFiltersSlotContext, type ChartMenuSlotContext, type ChartToolbarSlotContext } from '@ex-grid/chart';\nimport { useChartFilterText, type ExChartChrome } from '@ex-grid/chart-react';\nimport { MuiSizeContext, refuseThemeWithoutVariables } from '@ex-grid/mui';\n\nconst downloads: ReadonlySet<string> = new Set([chartWordIds.downloadCsv, chartWordIds.downloadSvg, chartWordIds.downloadPng]);\n\n/** One of the toolbar's commands: MUI's text button, outlined while what it opens is open. */\nfunction commandButton(command: ChartCommand, size: 'small' | 'medium'): ReactElement {\n return createElement(Button, {\n key: command.id, type: 'button', size, variant: command.expanded === true ? 'outlined' : 'text',\n disabled: !command.enabled, onClick: command.invoke, className: 'mui-ex-chart-command',\n ...(command.expanded === undefined ? {} : { 'aria-expanded': command.expanded }),\n ...(command.title === undefined ? {} : { title: command.title }),\n }, command.label);\n}\n\n/** Chart Filters: the range's ends in MUI's fields, a native select of the categories on a category axis, Apply, and\n * the axis switch, which takes effect at once. MUI has no date picker of its own (ADR-0390 section 10), so a date is\n * typed as the chart's hint shows. */\nfunction MuiChartFilters({ context, filters }: { readonly context: ChartToolbarSlotContext; readonly filters: ChartFiltersSlotContext }): ReactElement {\n const { size } = useContext(MuiSizeContext);\n const typed = useChartFilterText(filters);\n const end = (id: string, value: string, set: (text: string) => void): ReactElement => (filters.values === 'labels'\n ? createElement(TextField, {\n key: id, size, select: true, label: context.label(id), value, className: 'mui-ex-chart-end',\n slotProps: { select: { native: true }, inputLabel: { shrink: true } },\n onChange: event => { set(event.target.value); },\n }, createElement('option', { key: '', value: '' }, ''), ...filters.labels.map(label => createElement('option', { key: label, value: label }, label)))\n : createElement(TextField, {\n key: id, size, label: context.label(id), value, placeholder: filters.hint, className: 'mui-ex-chart-end',\n slotProps: { inputLabel: { shrink: true } },\n onChange: event => { set(event.target.value); },\n }));\n return createElement('div', { className: 'mui-ex-chart-filters', role: 'group', 'aria-label': context.label(chartWordIds.filters) },\n end(chartWordIds.from, typed.from, typed.setFrom),\n end(chartWordIds.to, typed.to, typed.setTo),\n createElement(Button, {\n type: 'button', size, variant: 'outlined', className: 'mui-ex-chart-apply', onClick: typed.apply,\n }, context.label(chartWordIds.apply)),\n filters.scale === undefined ? null : createElement(TextField, {\n size, select: true, label: context.label(chartWordIds.axis), value: filters.scale, className: 'mui-ex-chart-scale',\n slotProps: { select: { native: true } },\n onChange: event => { filters.setScale(scaleOf(event.target.value)); },\n },\n createElement('option', { value: 'proportional' }, context.label(chartWordIds.proportional)),\n createElement('option', { value: 'categories' }, context.label(chartWordIds.categories))),\n filters.error === null ? null : createElement(Alert, { severity: 'error', className: 'mui-ex-chart-filter-error' }, filters.error));\n}\n\n/** The scale an option names: one the chart offered, never one a changed option claims. */\nfunction scaleOf(value: string): AxisScale {\n if (value === 'proportional' || value === 'categories') return value;\n throw new RangeError(`'${value}' is not a scale the axis switch offers (ADR-0251).`);\n}\n\n/** The toolbar: the chart's commands in its order, the downloads as one button group, then Chart Filters while it is\n * open. */\nfunction MuiChartToolbar({ context }: { readonly context: ChartToolbarSlotContext }): ReactElement {\n refuseThemeWithoutVariables(useTheme(), 'muiChartChrome');\n const { size } = useContext(MuiSizeContext);\n const { filters } = context;\n return createElement('div', { className: 'mui-ex-chart-chrome' },\n createElement('div', { className: 'mui-ex-chart-toolbar', role: 'toolbar', 'aria-label': context.name },\n ...context.commands.filter(command => !downloads.has(command.id)).map(command => commandButton(command, size)),\n // MUI's ButtonGroup is a group already, named here as the downloads.\n createElement(ButtonGroup, { size, variant: 'outlined', 'aria-label': context.label(chartWordIds.downloads), className: 'mui-ex-chart-downloads' },\n ...context.commands.filter(command => downloads.has(command.id)).map(command => createElement(Button, {\n key: command.id, type: 'button', disabled: !command.enabled, onClick: command.invoke,\n ...(command.title === undefined ? {} : { title: command.title }),\n }, command.label)))),\n filters === undefined ? null : createElement(MuiChartFilters, { context, filters }));\n}\n\n/** The context menu's items: MUI's list item buttons, as its Menu draws an item, inside the chart's frame. MUI's\n * MenuItem is not used: it stands only inside MUI's MenuList, which answers the arrows itself. */\nfunction MuiChartMenu({ context }: { readonly context: ChartMenuSlotContext }): ReactElement {\n const { dense } = useContext(MuiSizeContext);\n return createElement('div', { role: 'none', className: 'mui-ex-chart-menu' },\n ...context.commands.map(command => createElement(ListItemButton<'button'>, {\n key: command.id, component: 'button', type: 'button', role: 'menuitem', dense,\n disabled: !command.enabled, onClick: command.invoke, className: 'mui-ex-chart-menu-item',\n }, command.label)));\n}\n\n/** ExChart's Chrome drawn in MUI's components: hand it as an ExChart's `chrome`, inside a ThemeProvider whose theme\n * was made with `cssVariables: true` and with `@ex-grid/chart-mui/styles.css` loaded. {@link MuiChartDock} hands it\n * to every chart it holds. */\nexport const muiChartChrome: ExChartChrome = Object.freeze({\n toolbar: (context: ChartToolbarSlotContext) => createElement(MuiChartToolbar, { context }),\n menu: (context: ChartMenuSlotContext) => createElement(MuiChartMenu, { context }),\n});\n", "// The Chart Dock under MUI (ADR-0258, ADR-0281, ADR-0390): the grid it is given, and a panel beside it or below it,\n// never over it, holding the charts made from the grid's selection as MUI's tabs. What it shows is the dock's state,\n// `useChartDock`'s, which takes the bridge's events; this component draws that state and calls back.\n\nimport { createElement, useId, type CSSProperties, type KeyboardEvent, type ReactElement, type ReactNode } from 'react';\nimport { Alert, IconButton, Paper, Tab, Tabs } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport type { GridDensity } from '@ex-grid/core';\nimport type { GridChartBridge } from '@ex-grid/chart';\nimport { DockedChart, useChartDockKeyboard, type ChartDockPlacement, type ChartDockState, type ExChartChrome } from '@ex-grid/chart-react';\nimport { MuiSizeContext, muiSizeOf, refuseThemeWithoutVariables } from '@ex-grid/mui';\nimport { muiChartChrome } from './chart-chrome';\n\n// Why a tab's chart can no longer be drawn, in MUI's alert.\nconst refused = (why: string): ReactElement => createElement(Alert, { severity: 'warning', className: 'mui-ex-chart-dock-refusal' }, why);\n\n// The close mark's cross, drawn rather than written, so a tab's text is its name alone.\nconst cross = createElement('svg', { viewBox: '0 0 16 16', width: 12, height: 12, 'aria-hidden': true, focusable: false },\n createElement('path', { d: 'M4 4l8 8M12 4l-8 8', stroke: 'currentColor', strokeWidth: 1.75, strokeLinecap: 'round' }));\n\n/** A MuiChartDock's props. */\nexport interface MuiChartDockProps<Row> {\n /** The dock's state, from `useChartDock`, whose `bridgeOptions` the bridge was made with. */\n readonly dock: ChartDockState;\n /** The bridge of the grid in `children`, which draws each chart from the grid's rows. */\n readonly bridge: GridChartBridge<Row>;\n /** The grid, and anything to stand beside the charts. */\n readonly children?: ReactNode;\n /** Where the charts go: beside the grid, the default, or below it. */\n readonly placement?: ChartDockPlacement;\n /** Each chart's width in CSS pixels; 640 unless given. */\n readonly chartWidth?: number;\n /** Each chart's height in CSS pixels; 320 unless given. */\n readonly chartHeight?: number;\n /** The grid's Density, which picks the size the charts' toolbar, Chart Filters and menu are drawn at, as it picks\n * the grid's Chrome's (ADR-0390); compact, `small` and dense, unless given. */\n readonly density?: GridDensity;\n /** What draws each chart's toolbar and context menu; {@link muiChartChrome} unless given. */\n readonly chrome?: ExChartChrome;\n /** A class for the dock's own element. */\n readonly className?: string;\n /** A style for the dock's own element. */\n readonly style?: CSSProperties;\n}\n\n/**\n * The Chart Dock (ADR-0258) drawn with MUI: the grid, and a panel of MUI's tabs beside it or below it holding the\n * charts made from its selection. The context menu's \"Chart selection\" opens a tab directly, \"Add to chart\" offers\n * every open tab, a refusal is said in an alert above the tabs, and a click on a point shows its cell. A tab not shown\n * keeps its chart, with its range and its open Chart Filters. Needs a ThemeProvider whose theme was made with\n * `cssVariables: true` above it, and `@ex-grid/chart-mui/styles.css` loaded.\n */\nexport function MuiChartDock<Row>(props: MuiChartDockProps<Row>): ReactElement {\n const {\n dock, bridge, children, placement = 'right', chartWidth = 640, chartHeight = 320, density = 'compact', chrome = muiChartChrome, className, style,\n } = props;\n const ids = useId();\n refuseThemeWithoutVariables(useTheme(), 'MuiChartDock');\n const keyboard = useChartDockKeyboard(dock);\n const { charts, active, refusal } = dock;\n const classes = ['mui-ex-chart', 'mui-ex-chart-dock', `mui-ex-chart-dock-${placement}`];\n if (className !== undefined) classes.push(className);\n // Beside the grid, the panel's content is as wide as its charts and the grid takes what is left, so a chart is\n // never clipped by a narrow page. Content-box, so the stylesheet's padding is not paired here.\n const panelStyle: CSSProperties | undefined = placement === 'right' ? { flex: '0 0 auto', boxSizing: 'content-box', width: chartWidth } : undefined;\n const tabId = (index: number): string => `${ids}-tab-${String(index)}`;\n const panelId = (index: number): string => `${ids}-panel-${String(index)}`;\n const panel = charts.length === 0 && refusal === undefined ? null : createElement(Paper, {\n ref: keyboard.panel, variant: 'outlined', className: 'mui-ex-chart-dock-panel', role: 'region', 'aria-label': 'Charts',\n ...(panelStyle === undefined ? {} : { style: panelStyle }),\n },\n refusal === undefined ? null : createElement(Alert, {\n severity: 'warning', onClose: dock.dismiss, closeText: 'Dismiss', className: 'mui-ex-chart-dock-refusal',\n }, refusal),\n charts.length === 0 ? null : createElement(Tabs, {\n value: active ?? false, variant: 'scrollable', scrollButtons: 'auto', className: 'mui-ex-chart-dock-tabs', // oxlint-disable-line ex-grid/no-stand-in-default -- MUI's Tabs say \"no tab\" as false\n onChange: (_: unknown, value: unknown) => {\n if (typeof value !== 'string') throw new TypeError('A Chart Dock\\'s tab is named by its chart.');\n dock.select(value);\n },\n }, ...charts.map(({ name }, index) => createElement(Tab, {\n key: name, value: name, id: tabId(index), 'aria-controls': panelId(index), className: 'mui-ex-chart-dock-tab-button',\n // Delete closes the tab the keyboard is on, as the close mark does under the pointer.\n onKeyDown: (event: KeyboardEvent) => { if (event.key === 'Delete') keyboard.closeByKey(name); },\n label: createElement('span', { className: 'mui-ex-chart-dock-label' }, name,\n // A span, not a button: a button inside the tab's button is not one the browser lets stand.\n createElement(IconButton<'span'>, {\n component: 'span', role: 'button', size: 'small', 'aria-label': `Close ${name}`,\n // Off the Tab order: Delete closes from the keyboard, and a stop inside each tab's button would be one\n // the tabs' own roving order does not know.\n tabIndex: -1, className: 'mui-ex-chart-dock-close',\n onClick: event => { event.stopPropagation(); dock.close(name); },\n }, cross)),\n }))),\n ...charts.map((target, index) => createElement('div', {\n key: target.name, role: 'tabpanel', id: panelId(index), 'aria-labelledby': tabId(index), hidden: target.name !== active,\n className: 'mui-ex-chart-dock-tab',\n }, createElement(DockedChart<Row>, { bridge, target, width: chartWidth, height: chartHeight, chrome, refused }))));\n return createElement('div', { className: classes.join(' '), ...(style === undefined ? {} : { style }) },\n createElement('div', { ref: keyboard.content, className: 'mui-ex-chart-dock-content' }, children),\n createElement(MuiSizeContext.Provider, { value: muiSizeOf(density) }, panel));\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["createElement", "Alert", "useTheme", "MuiSizeContext", "refuseThemeWithoutVariables", "createElement", "Alert", "refuseThemeWithoutVariables", "useTheme", "MuiSizeContext"]
7
+ }
package/package.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@ex-grid/chart-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": "ExChart for MUI: the design-system Wrapper that draws ExChart for React's toolbar and context menu with MUI's components, docks the charts made from a grid's selection beside it in MUI's tabs, and maps the chart's 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/chart-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/chart": "0.2.0-beta.3",
31
+ "@ex-grid/chart-react": "0.2.0-beta.3",
32
+ "@ex-grid/core": "0.2.0-beta.3",
33
+ "@ex-grid/mui": "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,47 @@
1
+ /* @ex-grid/chart-mui — the Wrapper's stylesheet (ADR-0390 section 5, ADR-0281). It does two things and nothing else.
2
+ It maps ExChart's Visual Tokens onto the variables a MUI theme made with cssVariables writes on the page, under the
3
+ grid Wrapper's paper, .mui-ex-grid, and under the Chart Dock, .mui-ex-chart, so a chart in either follows the theme
4
+ and a change of scheme recolours it with no render anywhere (ADR-0027). And it lays out this package's own
5
+ elements, each rule scoped to its own mui-ex-chart- class. It writes no geometry ExChart computes, no rule against a
6
+ class of ExChart's own, and no font: the chart lays its labels out by the widths of its own (ADR-0027).
7
+
8
+ The colour slots: the theme's primary and secondary lead (slots 1 and 2, as MudBlazor's primary and secondary do
9
+ under ExChart.MudBlazor; MUI has no tertiary), and slots 3 to 10 keep ExChart's own palette. MUI's error, warning,
10
+ success and info are never a series' colour: on a screen of profit and risk a red series reads as an error or a
11
+ loss and a green one as good news, and info would read as a notice (ADR-0281). They stay for what they mean. */
12
+ .mui-ex-grid,
13
+ .mui-ex-chart {
14
+ --ex-chart-colour-0: var(--mui-palette-primary-main);
15
+ --ex-chart-colour-1: var(--mui-palette-secondary-main);
16
+ --ex-chart-text: var(--mui-palette-text-primary);
17
+ --ex-chart-background: var(--mui-palette-background-paper);
18
+ --ex-chart-error: var(--mui-palette-error-main);
19
+ }
20
+
21
+ /* The toolbar and Chart Filters, above the plot. */
22
+ .mui-ex-chart-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; padding-bottom: 4px; }
23
+ .mui-ex-chart-toolbar .mui-ex-chart-command { text-transform: none; }
24
+ .mui-ex-chart-downloads .MuiButton-root { text-transform: none; }
25
+ .mui-ex-chart-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 0; }
26
+ .mui-ex-chart-filters > .mui-ex-chart-end { flex: 0 1 12em; min-width: 9em; }
27
+ .mui-ex-chart-filters > .mui-ex-chart-apply { text-transform: none; }
28
+ /* The axis switch takes effect at once, so it stands apart from the range Apply commits. */
29
+ .mui-ex-chart-filters > .mui-ex-chart-scale { margin-left: 16px; min-width: 10em; }
30
+ .mui-ex-chart-filters > .mui-ex-chart-filter-error { flex-basis: 100%; }
31
+
32
+ /* The context menu's items, inside the chart's frame (.ex-chart-menu), which stays the chart's. */
33
+ .mui-ex-chart-menu { display: flex; flex-direction: column; padding: 4px 0; }
34
+ /* Only the width and the text, as the grid's menu: ButtonBase already takes the button's own border and ground away,
35
+ and a background set here would tie with MUI's hover and keyboard-focus shades and hide which item Enter runs. */
36
+ .mui-ex-chart-menu .mui-ex-chart-menu-item { width: 100%; font: var(--mui-font-body1); }
37
+ .mui-ex-chart-menu .mui-ex-chart-menu-item.MuiListItemButton-dense { font: var(--mui-font-body2); }
38
+
39
+ /* The Chart Dock (ADR-0258): the grid and a panel of charts beside it or below it, never over it. */
40
+ .mui-ex-chart-dock { display: flex; gap: 12px; align-items: flex-start; }
41
+ .mui-ex-chart-dock-bottom { flex-direction: column; align-items: stretch; }
42
+ .mui-ex-chart-dock-content { flex: 1 1 auto; min-width: 0; overflow-x: auto; }
43
+ .mui-ex-chart-dock-panel { flex: 1 1 auto; min-width: 0; padding: 4px 8px 8px; }
44
+ .mui-ex-chart-dock-tabs .mui-ex-chart-dock-tab-button { text-transform: none; }
45
+ .mui-ex-chart-dock-label { display: inline-flex; align-items: center; gap: 4px; }
46
+ .mui-ex-chart-dock-tab { padding-top: 8px; }
47
+ .mui-ex-chart-dock-refusal { margin-bottom: 8px; }