material-plus-ui 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +8 -4
  2. package/dist/a2ui/catalog.d.ts +104 -0
  3. package/dist/a2ui/catalog.js +1 -0
  4. package/dist/a2ui/components/MPA2uiAudioPlayer.d.ts +1 -0
  5. package/dist/a2ui/components/MPA2uiAudioPlayer.js +2 -0
  6. package/dist/a2ui/components/MPA2uiButton.d.ts +1 -0
  7. package/dist/a2ui/components/MPA2uiButton.js +2 -0
  8. package/dist/a2ui/components/MPA2uiCard.d.ts +1 -0
  9. package/dist/a2ui/components/MPA2uiCard.js +2 -0
  10. package/dist/a2ui/components/MPA2uiCheckBox.d.ts +1 -0
  11. package/dist/a2ui/components/MPA2uiCheckBox.js +2 -0
  12. package/dist/a2ui/components/MPA2uiChoicePicker.d.ts +1 -0
  13. package/dist/a2ui/components/MPA2uiChoicePicker.js +2 -0
  14. package/dist/a2ui/components/MPA2uiColumn.d.ts +1 -0
  15. package/dist/a2ui/components/MPA2uiColumn.js +2 -0
  16. package/dist/a2ui/components/MPA2uiDateTimeInput.d.ts +1 -0
  17. package/dist/a2ui/components/MPA2uiDateTimeInput.js +2 -0
  18. package/dist/a2ui/components/MPA2uiDivider.d.ts +1 -0
  19. package/dist/a2ui/components/MPA2uiDivider.js +2 -0
  20. package/dist/a2ui/components/MPA2uiIcon.d.ts +1 -0
  21. package/dist/a2ui/components/MPA2uiIcon.js +2 -0
  22. package/dist/a2ui/components/MPA2uiImage.d.ts +1 -0
  23. package/dist/a2ui/components/MPA2uiImage.js +2 -0
  24. package/dist/a2ui/components/MPA2uiList.d.ts +1 -0
  25. package/dist/a2ui/components/MPA2uiList.js +2 -0
  26. package/dist/a2ui/components/MPA2uiModal.d.ts +1 -0
  27. package/dist/a2ui/components/MPA2uiModal.js +2 -0
  28. package/dist/a2ui/components/MPA2uiRow.d.ts +1 -0
  29. package/dist/a2ui/components/MPA2uiRow.js +2 -0
  30. package/dist/a2ui/components/MPA2uiSlider.d.ts +1 -0
  31. package/dist/a2ui/components/MPA2uiSlider.js +2 -0
  32. package/dist/a2ui/components/MPA2uiTabs.d.ts +1 -0
  33. package/dist/a2ui/components/MPA2uiTabs.js +2 -0
  34. package/dist/a2ui/components/MPA2uiText.d.ts +1 -0
  35. package/dist/a2ui/components/MPA2uiText.js +2 -0
  36. package/dist/a2ui/components/MPA2uiTextField.d.ts +1 -0
  37. package/dist/a2ui/components/MPA2uiTextField.js +2 -0
  38. package/dist/a2ui/components/MPA2uiVideo.d.ts +1 -0
  39. package/dist/a2ui/components/MPA2uiVideo.js +2 -0
  40. package/dist/a2ui/extended/MPA2uiBarChart.d.ts +1 -0
  41. package/dist/a2ui/extended/MPA2uiBarChart.js +2 -0
  42. package/dist/a2ui/extended/MPA2uiDataTable.d.ts +1 -0
  43. package/dist/a2ui/extended/MPA2uiDataTable.js +2 -0
  44. package/dist/a2ui/extended/MPA2uiLineChart.d.ts +1 -0
  45. package/dist/a2ui/extended/MPA2uiLineChart.js +2 -0
  46. package/dist/a2ui/extended/MPA2uiPieChart.d.ts +1 -0
  47. package/dist/a2ui/extended/MPA2uiPieChart.js +2 -0
  48. package/dist/a2ui/extended/MPA2uiStatistic.d.ts +1 -0
  49. package/dist/a2ui/extended/MPA2uiStatistic.js +2 -0
  50. package/dist/a2ui/extended/api.d.ts +1436 -0
  51. package/dist/a2ui/extended/api.js +1 -0
  52. package/dist/a2ui/extended/chart.d.ts +26 -0
  53. package/dist/a2ui/extended/chart.js +1 -0
  54. package/dist/a2ui/index.d.ts +103 -0
  55. package/dist/a2ui/index.js +1 -0
  56. package/dist/a2ui/internal/children.d.ts +28 -0
  57. package/dist/a2ui/internal/children.js +1 -0
  58. package/dist/a2ui/internal/common.d.ts +113 -0
  59. package/dist/a2ui/internal/common.js +1 -0
  60. package/dist/a2ui/internal/icons.d.ts +3 -0
  61. package/dist/a2ui/internal/icons.js +1 -0
  62. package/dist/components/alert/MPAlert.d.ts +1 -1
  63. package/dist/components/animate-grow/MPAnimateGrow.d.ts +1 -1
  64. package/dist/components/animate-slide/MPAnimateSlide.d.ts +1 -1
  65. package/dist/components/animate-zoom/MPAnimateZoom.d.ts +2 -2
  66. package/dist/components/area-chart/MPAreaChart.d.ts +18 -3
  67. package/dist/components/area-chart/MPAreaChart.js +1 -1
  68. package/dist/components/avatar/MPAvatar.d.ts +1 -1
  69. package/dist/components/bar-chart/MPBarChart.d.ts +15 -5
  70. package/dist/components/bar-chart/MPBarChart.js +1 -1
  71. package/dist/components/blockquote/MPBlockquote.d.ts +1 -1
  72. package/dist/components/box/MPBox.d.ts +1 -1
  73. package/dist/components/chip/MPChip.d.ts +1 -1
  74. package/dist/components/empty/MPEmpty.d.ts +1 -1
  75. package/dist/components/heatmap-chart/MPHeatmapChart.d.ts +12 -3
  76. package/dist/components/heatmap-chart/MPHeatmapChart.js +1 -1
  77. package/dist/components/line-chart/MPLineChart.d.ts +20 -2
  78. package/dist/components/line-chart/MPLineChart.js +1 -1
  79. package/dist/components/pie-chart/MPPieChart.d.ts +23 -1
  80. package/dist/components/pie-chart/MPPieChart.js +1 -1
  81. package/dist/components/scatter-chart/MPScatterChart.d.ts +5 -1
  82. package/dist/components/sparkline/MPSparkline.d.ts +14 -1
  83. package/dist/components/sparkline/MPSparkline.js +1 -1
  84. package/dist/components/timeline-chart/MPTimelineChart.d.ts +6 -2
  85. package/dist/components/typography/MPTypography.d.ts +1 -1
  86. package/dist/internal/ChartChrome.d.ts +63 -13
  87. package/dist/internal/ChartChrome.js +1 -1
  88. package/dist/internal/ChartFrame.d.ts +24 -4
  89. package/dist/internal/ChartFrame.js +1 -1
  90. package/dist/internal/chart.d.ts +91 -3
  91. package/dist/internal/chart.js +1 -1
  92. package/dist/internal/i18n.d.ts +4 -0
  93. package/dist/internal/messages/chart.d.ts +1 -1
  94. package/dist/internal/messages/chart.js +1 -1
  95. package/dist/locales/ar.js +1 -1
  96. package/dist/locales/de.js +1 -1
  97. package/dist/locales/es.js +1 -1
  98. package/dist/locales/fr.js +1 -1
  99. package/dist/locales/hi.js +1 -1
  100. package/dist/locales/id.js +1 -1
  101. package/dist/locales/it.js +1 -1
  102. package/dist/locales/ja.js +1 -1
  103. package/dist/locales/ko.js +1 -1
  104. package/dist/locales/nl.js +1 -1
  105. package/dist/locales/pl.js +1 -1
  106. package/dist/locales/pt.js +1 -1
  107. package/dist/locales/ru.js +1 -1
  108. package/dist/locales/th.js +1 -1
  109. package/dist/locales/tr.js +1 -1
  110. package/dist/locales/vi.js +1 -1
  111. package/dist/locales/zh-hans.js +1 -1
  112. package/dist/locales/zh-hant.js +1 -1
  113. package/dist/styles/area-chart.css +1 -1
  114. package/dist/styles/bar-chart.css +1 -1
  115. package/dist/styles/gauge-chart.css +1 -1
  116. package/dist/styles/heatmap-chart.css +1 -1
  117. package/dist/styles/line-chart.css +1 -1
  118. package/dist/styles/pie-chart.css +1 -1
  119. package/dist/styles/scatter-chart.css +1 -1
  120. package/dist/styles/sparkline.css +1 -1
  121. package/dist/styles/statistic.css +1 -1
  122. package/dist/styles/timeline-chart.css +1 -1
  123. package/dist/styles.css +1 -1
  124. package/dist/types.d.ts +208 -1
  125. package/package.json +25 -4
@@ -0,0 +1 @@
1
+ import{z as e}from"zod";import{DataBindingSchema as t,FunctionCallSchema as a,DynamicStringSchema as o}from"@a2ui/web_core/v0_9";const i=(o,i)=>e.union([e.array(o),t,a]).describe(i),r=e.enum(["primary","secondary","tertiary","error"]).describe("Which accent role this reads, out of the page's own colour scheme. Omit it to take the next slot of the chart palette, which is what keeps a set of series distinguishable."),s={accessibility:e.object({label:o.optional().describe("A short name used by assistive technologies."),description:o.optional().describe("Additional detail about the element.")}).strict().optional(),weight:e.number().describe("The relative weight of this component within a Row or Column, like CSS 'flex-grow'. Only meaningful as a direct child of one.").optional()},n=e.object({key:e.string().describe("The property this column reads from each row. Also the column's own id."),label:o.optional().describe("The column heading. Defaults to the key itself."),align:e.enum(["start","center","end"]).describe("Where the cell's contents sit. Use 'end' for a column of numbers.").optional(),sortable:e.boolean().describe("Whether the reader may sort by this column. Defaults to true.").optional(),searchable:e.boolean().describe("Whether the search box looks in this column. Defaults to true.").optional(),width:e.number().describe("The column's width in pixels. Omit to share the room.").optional()}).strict();export const DataTableApi={name:"DataTable",schema:e.object({...s,columns:e.array(n).min(1).describe("The columns, in the order they are drawn."),rows:i(e.record(e.any()),"The rows: an array of objects keyed by the columns above, or a path to one in the data model. Bind a path when the data arrives separately from the table."),rowKey:e.string().describe("The column key whose value identifies a row, used for selection. Defaults to the row's position, which is only stable while the rows are.").optional(),caption:o.optional().describe("A description of the table, read out before its contents. Use it to say what the rows are, since column headings rarely say that on their own."),searchable:e.boolean().describe("Puts a search box above the table. Defaults to false.").optional(),sortable:e.boolean().describe("Lets the reader sort by any sortable column. Defaults to true.").optional(),paged:e.boolean().describe("Splits the rows into pages. Worth it past about twenty rows.").optional(),pageSize:e.number().int().positive().describe("Rows per page. Defaults to 10.").optional(),selection:e.enum(["none","single","multiple"]).describe("Whether the reader may pick rows, and how many. 'multiple' draws a column of checkboxes and 'single' picks the row that is pressed. Bind 'selectedKeys' to read the choice back.").optional(),selectedKeys:e.union([e.array(e.string()),t]).describe("The keys of the selected rows. Bind this to a path to be told what the reader picked.").optional(),striped:e.boolean().describe("Shades alternate rows, which helps a wide table be read across.").optional()}).strict().describe("A table of rows and columns, with sorting, searching, paging and selection. Prefer this to a Row-and-Column layout whenever the data is tabular: it is announced as a table, it can be sorted, and it stays readable on a narrow screen.")};const h=e.object({name:e.string().describe("The name of this series, in the legend and the hover panel.").optional(),data:e.array(e.number().nullable()).describe("Its values, one per category, in category order. `null` is a gap, not a zero."),color:r.optional()}).strict(),l={...s,series:i(h,"The series, in the order their colours are handed out. A literal array, or a path to one in the data model."),categories:e.union([e.array(e.string()),t]).describe("The category axis' labels, one per value in each series.").optional(),label:o.optional().describe("What the chart is of, read out before it. A chart with no label is a picture assistive technology cannot describe."),xAxisLabel:o.optional().describe("A name for what the category axis counts."),yAxisLabel:o.optional().describe("A name for what the value axis measures."),height:e.number().describe("The plot height in pixels. Defaults to a size that suits the chart.").optional(),legend:e.boolean().describe("Whether to draw the legend. Defaults to on past one series.").optional()};export const BarChartApi={name:"BarChart",schema:e.object({...l,stacked:e.boolean().describe("Stacks the series into one bar per category instead of drawing them side by side.").optional(),horizontal:e.boolean().describe("Turns the bars sideways, which is what long category names need.").optional()}).strict().describe("A bar chart, for comparing a value across categories.")};export const LineChartApi={name:"LineChart",schema:e.object({...l,curve:e.enum(["linear","smooth","step"]).describe("How a line gets from one point to the next. 'step' is for a value that holds and then changes, such as a price.").optional(),markers:e.boolean().describe("Draws a dot at each point. Defaults to on while the points are few enough.").optional()}).strict().describe("A line chart, for a value that moves over a sequence — usually time.")};export const PieChartApi={name:"PieChart",schema:e.object({...s,data:i(e.number().nullable(),"One value per slice, in the order of `categories`. A literal array, or a path to one in the data model."),categories:e.union([e.array(e.string()),t]).describe("Each slice's name, in the legend and the hover panel.").optional(),shape:e.enum(["pie","donut","semi"]).describe("The shape it is drawn as. 'donut' leaves room in the middle.").optional(),label:o.optional().describe("What the chart is of, read out before it."),height:e.number().describe("The plot height in pixels.").optional(),legend:e.boolean().describe("Whether to draw the legend. Defaults to on.").optional()}).strict().describe("A pie or donut chart, for parts of one whole. Use it only when the parts add up to something — a bar chart is easier to read for anything else, and far easier past about six slices.")};export const StatisticApi={name:"Statistic",schema:e.object({...s,value:e.union([e.string(),e.number(),t,a]).describe("The figure itself. A number is formatted in the reader's locale; a string is drawn as it is."),label:o.optional().describe("What the figure is of, drawn above it."),previousValue:e.number().describe("What the figure was, which is what turns `delta` into a change.").optional(),delta:e.enum(["percent","absolute","both","none"]).describe("How the change from `previousValue` is written. Defaults to a percentage when there is a previous value.").optional(),betterWhen:e.enum(["up","down"]).describe("Which direction is good news, which decides the colour of the change. Set it on a figure where down is better, such as a cost or a bounce rate — the default assumes up.").optional(),unit:o.optional().describe("A unit after the figure, such as `ms` or `kg`."),prefix:o.optional().describe("A symbol before the figure, such as `$`."),period:o.optional().describe("What the change is measured over, such as `vs last week`."),caption:o.optional().describe("A line under the figure."),compact:e.boolean().describe("Whether a number of five digits or more is written short: 12.4K rather than 12,400. On by default, because that is what a headline figure wants; pass false for one that has to be read exactly.").optional(),align:e.enum(["start","center","end"]).describe("Where the block sits. Defaults to the start.").optional()}).strict().describe("One figure, with what it is and how it has changed. The component to reach for when the answer is a number — a chart of one point is not a chart.")};
@@ -0,0 +1,26 @@
1
+ /**
2
+ * What the three charts share, and why any of it needs checking.
3
+ *
4
+ * **A bound list is not a validated list.** The SDK's binder checks a payload
5
+ * against the schema, and a `series` the agent wrote out literally is therefore
6
+ * known to be series-shaped. A `series` bound to a path is not: the schema
7
+ * approved the *binding*, and what comes back is whatever the data model holds at
8
+ * that moment — half-written by an earlier message, replaced by a later one, or
9
+ * simply not what the agent intended. A chart handed `{ data: 'later' }` where it
10
+ * expected numbers renders nothing and throws inside the scale.
11
+ *
12
+ * So the resolved value is read rather than trusted: a list becomes a list, a
13
+ * number stays a number, and anything else becomes a gap. What that buys is a
14
+ * chart that draws what arrived and keeps drawing as the rest of it does.
15
+ */
16
+ import type { MPChartDatum, MPChartSeries } from '../../types.js';
17
+ /** A list of values, from whatever the binding resolved to. */
18
+ export declare const toData: (value: unknown) => MPChartDatum[];
19
+ /** The series, from whatever the binding resolved to. */
20
+ export declare const toSeries: (value: unknown) => MPChartSeries[];
21
+ /** The category labels, which are strings or nothing. */
22
+ export declare const toCategories: (value: unknown) => string[] | undefined;
23
+ /** An axis, only when there is something to name it. */
24
+ export declare const toAxis: (label?: string) => {
25
+ label: string;
26
+ } | undefined;
@@ -0,0 +1 @@
1
+ import{asText as o}from"../internal/common.js";const r=o=>"number"==typeof o&&Number.isFinite(o)?o:null;export const toData=o=>Array.isArray(o)?o.map(r):[];export const toSeries=r=>Array.isArray(r)?r.map(r=>{const t=r??{};return{name:o(t.name),data:toData(t.data),color:o(t.color)}}):[];export const toCategories=r=>Array.isArray(r)?r.map(r=>o(r)??""):void 0;export const toAxis=o=>o?{label:o}:void 0;
@@ -0,0 +1,103 @@
1
+ /**
2
+ * A2UI's basic catalog, drawn as Material Design 3.
3
+ *
4
+ * [A2UI](https://a2ui.org) is a protocol for an agent to describe an interface
5
+ * rather than write one: the agent sends JSON naming components from a *catalog*,
6
+ * and a renderer on the client draws them. The catalog is the contract — which
7
+ * components exist, what props each takes — and this module is an implementation
8
+ * of the protocol's own basic catalog, so an agent that already targets it gets
9
+ * Material Plus on the other end with nothing changed at its end.
10
+ *
11
+ * ```tsx
12
+ * import { A2uiSurface } from '@a2ui/react/v0_9';
13
+ * import { MessageProcessor } from '@a2ui/web_core/v0_9';
14
+ * import { mpA2uiCatalog } from 'material-plus-ui/a2ui';
15
+ * import 'material-plus-ui/styles.css';
16
+ *
17
+ * const processor = new MessageProcessor([mpA2uiCatalog]);
18
+ *
19
+ * processor.processMessages(messagesFromTheAgent);
20
+ *
21
+ * const surfaces = Array.from(processor.model.surfacesMap.values());
22
+ *
23
+ * surfaces.map((surface) => <A2uiSurface key={surface.id} surface={surface} />);
24
+ * ```
25
+ *
26
+ * ## The two packages this needs, and why they are optional
27
+ *
28
+ * `@a2ui/react` and `@a2ui/web_core` are **optional peer dependencies**: install
29
+ * them and this subpath works, leave them out and nothing else in the library
30
+ * notices. That is not tidiness. The protocol SDK brings Lit, signals, Zod, a
31
+ * date library and a Markdown parser with it, and the rest of this package
32
+ * promises two runtime dependencies — so the SDK stays behind an import that only
33
+ * a project rendering agent interfaces ever writes. Nothing in `src/` outside this
34
+ * directory imports either package, and this module is not in the main barrel.
35
+ *
36
+ * ## No stylesheet of its own
37
+ *
38
+ * Everything here draws with components from this library, which means the
39
+ * ordinary `material-plus-ui/styles.css` is all a surface needs, and the split
40
+ * per-component sheets keep working as they always did. That is also why nothing
41
+ * in this directory writes a utility class: a class used only here would be a rule
42
+ * in the whole stylesheet and in none of the split ones. Where a declaration is
43
+ * genuinely needed it is written inline, off the `--mp-sys-*` tokens, so a page
44
+ * that set `data-mp-shape` or a source colour reaches an agent's surface too.
45
+ *
46
+ * ## What the agent can and cannot do
47
+ *
48
+ * A surface is JSON from a language model, so the boundary matters:
49
+ *
50
+ * - **The catalog is the allowlist.** A component name that is not one of the
51
+ * eighteen does not resolve, and there is no path from a payload to a component
52
+ * of your own unless you registered it with `createMPA2uiCatalog`.
53
+ * - **Props are validated against the schemas** by the SDK's binder before they
54
+ * reach anything here, which is why these implementations do not re-check types.
55
+ * - **Text is text.** Markdown is rendered only when the application has
56
+ * configured a renderer through `@a2ui/react`'s Markdown context, whose contract
57
+ * requires it to sanitize; with none configured, an agent's string is drawn as
58
+ * the characters it contains. See `components/MPA2uiText.tsx`.
59
+ * - **URLs are the agent's.** `Image`, `Video` and `AudioPlayer` load what the
60
+ * payload names them, so a surface from an agent you do not control belongs
61
+ * behind a Content Security Policy that says where media may come from.
62
+ *
63
+ * ## Two catalogs, and where they stop
64
+ *
65
+ * `mpA2uiCatalog` is the eighteen, under the basic catalog's id. `mpA2uiExtendedCatalog`
66
+ * is those plus five of this library's own — a data table, a bar, line and pie
67
+ * chart, and a statistic — under an id of ours, because five components the basic
68
+ * vocabulary cannot express are a different contract and must not claim to be that
69
+ * one. Their schemas are `extended/api.ts` and are published, generated from those
70
+ * schemas, at the id itself.
71
+ *
72
+ * Twenty-three of a hundred and thirty, then. The rest — the command palette, the
73
+ * calendar, the tour, the animations — are not reachable from a payload, and a
74
+ * component only becomes reachable by being given a schema an agent can fill in
75
+ * from JSON alone. `createMPA2uiCatalog` is how a project adds its own.
76
+ */
77
+ export { A2UI_BASIC_CATALOG_ID, MP_A2UI_CATALOG_ID, MP_A2UI_COMPONENTS, MP_A2UI_EXTENDED_COMPONENTS, createMPA2uiCatalog, mpA2uiCatalog, mpA2uiExtendedCatalog } from './catalog.js';
78
+ export { MPA2uiAudioPlayer } from './components/MPA2uiAudioPlayer.js';
79
+ export { MPA2uiButton } from './components/MPA2uiButton.js';
80
+ export { MPA2uiCard } from './components/MPA2uiCard.js';
81
+ export { MPA2uiCheckBox } from './components/MPA2uiCheckBox.js';
82
+ export { MPA2uiChoicePicker } from './components/MPA2uiChoicePicker.js';
83
+ export { MPA2uiColumn } from './components/MPA2uiColumn.js';
84
+ export { MPA2uiDateTimeInput } from './components/MPA2uiDateTimeInput.js';
85
+ export { MPA2uiDivider } from './components/MPA2uiDivider.js';
86
+ export { MPA2uiIcon } from './components/MPA2uiIcon.js';
87
+ export { MPA2uiImage } from './components/MPA2uiImage.js';
88
+ export { MPA2uiList } from './components/MPA2uiList.js';
89
+ export { MPA2uiModal } from './components/MPA2uiModal.js';
90
+ export { MPA2uiRow } from './components/MPA2uiRow.js';
91
+ export { MPA2uiSlider } from './components/MPA2uiSlider.js';
92
+ export { MPA2uiTabs } from './components/MPA2uiTabs.js';
93
+ export { MPA2uiText } from './components/MPA2uiText.js';
94
+ export { MPA2uiTextField } from './components/MPA2uiTextField.js';
95
+ export { MPA2uiVideo } from './components/MPA2uiVideo.js';
96
+ export { MPA2uiBarChart } from './extended/MPA2uiBarChart.js';
97
+ export { MPA2uiDataTable } from './extended/MPA2uiDataTable.js';
98
+ export { MPA2uiLineChart } from './extended/MPA2uiLineChart.js';
99
+ export { MPA2uiPieChart } from './extended/MPA2uiPieChart.js';
100
+ export { MPA2uiStatistic } from './extended/MPA2uiStatistic.js';
101
+ export { BarChartApi, DataTableApi, LineChartApi, PieChartApi, StatisticApi } from './extended/api.js';
102
+ export { A2UI_ICONS } from './internal/icons.js';
103
+ export type { MPA2uiAccessibility } from './internal/common.js';
@@ -0,0 +1 @@
1
+ export{A2UI_BASIC_CATALOG_ID,MP_A2UI_CATALOG_ID,MP_A2UI_COMPONENTS,MP_A2UI_EXTENDED_COMPONENTS,createMPA2uiCatalog,mpA2uiCatalog,mpA2uiExtendedCatalog}from"./catalog.js";export{MPA2uiAudioPlayer}from"./components/MPA2uiAudioPlayer.js";export{MPA2uiButton}from"./components/MPA2uiButton.js";export{MPA2uiCard}from"./components/MPA2uiCard.js";export{MPA2uiCheckBox}from"./components/MPA2uiCheckBox.js";export{MPA2uiChoicePicker}from"./components/MPA2uiChoicePicker.js";export{MPA2uiColumn}from"./components/MPA2uiColumn.js";export{MPA2uiDateTimeInput}from"./components/MPA2uiDateTimeInput.js";export{MPA2uiDivider}from"./components/MPA2uiDivider.js";export{MPA2uiIcon}from"./components/MPA2uiIcon.js";export{MPA2uiImage}from"./components/MPA2uiImage.js";export{MPA2uiList}from"./components/MPA2uiList.js";export{MPA2uiModal}from"./components/MPA2uiModal.js";export{MPA2uiRow}from"./components/MPA2uiRow.js";export{MPA2uiSlider}from"./components/MPA2uiSlider.js";export{MPA2uiTabs}from"./components/MPA2uiTabs.js";export{MPA2uiText}from"./components/MPA2uiText.js";export{MPA2uiTextField}from"./components/MPA2uiTextField.js";export{MPA2uiVideo}from"./components/MPA2uiVideo.js";export{MPA2uiBarChart}from"./extended/MPA2uiBarChart.js";export{MPA2uiDataTable}from"./extended/MPA2uiDataTable.js";export{MPA2uiLineChart}from"./extended/MPA2uiLineChart.js";export{MPA2uiPieChart}from"./extended/MPA2uiPieChart.js";export{MPA2uiStatistic}from"./extended/MPA2uiStatistic.js";export{BarChartApi,DataTableApi,LineChartApi,PieChartApi,StatisticApi}from"./extended/api.js";export{A2UI_ICONS}from"./internal/icons.js";
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A `children` list, as nodes with keys.
3
+ *
4
+ * A2UI never nests components. A layout's `children` is a list of ids, and the
5
+ * renderer resolves each id against the surface — which is what `buildChild`
6
+ * does. The list arrives in one of two shapes, and both mean "these children, in
7
+ * this order":
8
+ *
9
+ * - a plain id, for a fixed child the agent wrote down;
10
+ * - an id with a `basePath`, for a child generated from a data list. The path is
11
+ * the row that child reads, so the same component definition draws once per
12
+ * row and each copy binds to its own.
13
+ *
14
+ * The key has to carry the path for the second shape. One template over five
15
+ * rows is five children of the same id, and keying on the id alone would make
16
+ * them one child that React re-mounts as the data moves.
17
+ */
18
+ import type { ResolvedChildRef } from '@a2ui/web_core/v0_9';
19
+ import type * as React from 'react';
20
+ /** What a component implementation is handed to resolve an id with. */
21
+ export type MPA2uiBuildChild = (id: string, basePath?: string) => React.ReactNode;
22
+ /** One resolved child, ready to be placed. */
23
+ export interface MPA2uiChild {
24
+ key: string;
25
+ node: React.ReactNode;
26
+ }
27
+ /** The list a layout was given, resolved in order. */
28
+ export declare const childNodes: (children: readonly (string | ResolvedChildRef)[] | undefined, buildChild: MPA2uiBuildChild) => MPA2uiChild[];
@@ -0,0 +1 @@
1
+ export const childNodes=(e,a)=>Array.isArray(e)?e.map((e,d)=>"string"==typeof e?{key:`${e}-${d}`,node:a(e)}:{key:`${e.id}-${e.basePath}`,node:a(e.id,e.basePath)}):[];
@@ -0,0 +1,113 @@
1
+ /**
2
+ * The three things the protocol asks of every component here, and the
3
+ * conversions that follow from them.
4
+ *
5
+ * A2UI's props are not React props. They arrive from an agent as JSON, the
6
+ * renderer's binder resolves them — a data binding becomes the value it points
7
+ * at, an action becomes a closure — and what reaches a component is that
8
+ * resolved object. Two of its entries are on *every* component in the basic
9
+ * catalog and correspond to nothing a Material Plus component takes:
10
+ *
11
+ * - `weight` is a flex share, meaningful only inside a Row or a Column. It is a
12
+ * number in the payload and a `style` here, because no component in this
13
+ * library has a prop for how much of a parent's main axis it should claim —
14
+ * `MPFlex` distributes, and the claim belongs to the child.
15
+ * - `accessibility` carries a label and a description for assistive technology.
16
+ *
17
+ * The rest of this file is the vocabulary gap. A2UI writes `spaceBetween` where
18
+ * `MPFlex` writes `space-between`, and its date and time values are ISO 8601
19
+ * strings where every picker in this library works in `Date`.
20
+ */
21
+ import type * as React from 'react';
22
+ import type { MPGridAlign, MPGridJustify } from '../../components/grid/MPGrid.js';
23
+ /**
24
+ * What an agent can say about a component to a screen reader.
25
+ *
26
+ * `unknown` rather than `string`, and that is the SDK's type rather than a
27
+ * looseness of ours. Its binder resolves a data binding wherever one appears,
28
+ * however deeply — so both of these are strings by the time a component runs —
29
+ * but the *type* it publishes only resolves the props at the top level. Anything
30
+ * one object further in keeps the `string | DataBinding | FunctionCall` union the
31
+ * schema declared, so what a component receives is wider than what it gets.
32
+ *
33
+ * `asText` is the one place that difference is handled.
34
+ */
35
+ export interface MPA2uiAccessibility {
36
+ /** The accessible name. */
37
+ label?: unknown;
38
+ /** The longer form, for what the name cannot carry. */
39
+ description?: unknown;
40
+ }
41
+ /**
42
+ * A resolved dynamic value, as the string it is.
43
+ *
44
+ * For the nested props described above: a `title`, an option's `label`, the two
45
+ * `accessibility` entries. Anything that is not a string is dropped rather than
46
+ * coerced, because the alternative is `String({ path: 'user.name' })` — the words
47
+ * `[object Object]` drawn in an interface, which is worse than the missing label
48
+ * it would be standing in for.
49
+ */
50
+ export declare const asText: (value: unknown) => string | undefined;
51
+ /**
52
+ * `weight` as the declaration a flex child needs.
53
+ *
54
+ * `minWidth` and `minHeight` go with it. A flex item's automatic minimum size is
55
+ * its content, so a weighted child holding a long word or a wide image refuses
56
+ * to shrink below it and the row overflows instead of dividing as asked.
57
+ */
58
+ export declare const weightStyle: (weight?: number) => React.CSSProperties | undefined;
59
+ /**
60
+ * `accessibility` as attributes an element takes.
61
+ *
62
+ * The description becomes `title` rather than `aria-description`, which is still
63
+ * a draft attribute no browser maps to anything. `title` is announced by every
64
+ * screen reader in use and shows as a tooltip besides, which is the closer
65
+ * reading of what an agent means by a description.
66
+ *
67
+ * Spread onto the element a component owns. It is *not* spread onto a labelled
68
+ * control — a text field, a checkbox, a slider — because those carry a `label`
69
+ * of their own from the payload, and an `aria-label` beside it replaces the
70
+ * label the reader can see with one they cannot.
71
+ */
72
+ export declare const accessibilityAttributes: (accessibility?: MPA2uiAccessibility) => {
73
+ 'aria-label': string | undefined;
74
+ title: string | undefined;
75
+ };
76
+ /**
77
+ * A2UI's main-axis words, in `MPFlex`'s spelling.
78
+ *
79
+ * `stretch` has no main-axis meaning in flexbox and is dropped to `start`, the
80
+ * same reading a browser gives `justify-content: stretch` on a flex container.
81
+ * The cross axis is where stretching happens, and that is `align` below.
82
+ */
83
+ export declare const FLEX_JUSTIFY: Record<string, MPGridJustify>;
84
+ /** A2UI's cross-axis words, which are `MPFlex`'s own. */
85
+ export declare const FLEX_ALIGN: Record<string, MPGridAlign>;
86
+ /**
87
+ * An ISO 8601 date, time, or date and time, as a local `Date`.
88
+ *
89
+ * Parsed by hand rather than handed to `new Date(value)`, because the two
90
+ * shapes an agent sends most are the two the constructor reads as UTC:
91
+ * `2026-03-01` is midnight in Greenwich, which is the 28th of February
92
+ * anywhere west of it, and a calendar that opens on the wrong day is the bug
93
+ * this avoids. A local `Date` is what the pickers here work in, so the value is
94
+ * read as the wall clock it plainly is.
95
+ *
96
+ * A value carrying its own offset — `...Z`, `...+09:00` — is unambiguous and
97
+ * goes to the constructor, which converts it to this machine's clock.
98
+ */
99
+ export declare const parseIsoValue: (value?: string) => Date | null;
100
+ /**
101
+ * A `Date` as the ISO 8601 string the payload holds, in the precision that was
102
+ * asked for.
103
+ *
104
+ * Local parts, never `toISOString()`: that prints UTC, and a Seoul afternoon
105
+ * written back as the previous day's UTC evening would move the value every
106
+ * time the agent read it back. The shapes are the ones an HTML date, time and
107
+ * `datetime-local` input produce, which is what the protocol's own renderer
108
+ * writes and therefore what an agent is most likely to parse.
109
+ */
110
+ export declare const formatIsoValue: (date: Date | null, { withDate, withTime }: {
111
+ withDate: boolean;
112
+ withTime: boolean;
113
+ }) => string;
@@ -0,0 +1 @@
1
+ export const asText=e=>"string"==typeof e?e:void 0;export const weightStyle=e=>{if("number"==typeof e)return{flex:String(e),minWidth:0,minHeight:0}};export const accessibilityAttributes=e=>({"aria-label":asText(e?.label),title:asText(e?.description)});export const FLEX_JUSTIFY={start:"start",center:"center",end:"end",spaceBetween:"space-between",spaceAround:"space-around",spaceEvenly:"space-evenly",stretch:"start"};export const FLEX_ALIGN={start:"start",center:"center",end:"end",stretch:"stretch"};const e=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2}))?)?/,t=/^(\d{2}):(\d{2})(?::(\d{2}(?:\.\d+)?))?$/;export const parseIsoValue=r=>{if(!r)return null;const n=t.exec(r);if(n){const e=new Date;return new Date(e.getFullYear(),e.getMonth(),e.getDate(),Number(n[1]),Number(n[2]),Number(n[3]??0))}if(/[Z+]|\d-\d{2}:\d{2}$/.test(r.slice(10))){const e=new Date(r);return Number.isNaN(e.getTime())?null:e}const s=e.exec(r);return s?new Date(Number(s[1]),Number(s[2])-1,Number(s[3]),Number(s[4]??0),Number(s[5]??0),Number(s[6]??0)):null};const r=e=>String(e).padStart(2,"0");export const formatIsoValue=(e,{withDate:t,withTime:n})=>{if(!e||Number.isNaN(e.getTime()))return"";const s=`${e.getFullYear()}-${r(e.getMonth()+1)}-${r(e.getDate())}`,a=`${r(e.getHours())}:${r(e.getMinutes())}`;return t&&n?`${s}T${a}`:n?a:s};
@@ -0,0 +1,3 @@
1
+ import type { MPIconGlyph } from '../../types.js';
2
+ /** Every name the `Icon` component accepts, and what it draws. */
3
+ export declare const A2UI_ICONS: Record<string, MPIconGlyph>;
@@ -0,0 +1 @@
1
+ import{ArrowLeft as e,ArrowRight as o,Bell as r,BellOff as a,Calendar as i,CalendarDays as t,Camera as n,Check as l,CircleAlert as s,CircleQuestionMark as c,CircleUser as f,CreditCard as p,Download as d,Ellipsis as m,EllipsisVertical as u,Eye as h,EyeOff as v,FastForward as w,Folder as O,Heart as k,HeartOff as y,House as g,Image as C,Info as F,Lock as b,LockOpen as x,Mail as H,MapPin as I,Menu as N,Paperclip as U,Pause as z,Pencil as A,Phone as B,Play as D,Plus as M,Printer as P,RefreshCw as S,Rewind as T,Search as V,Send as _,Settings as j,Share2 as q,ShoppingCart as E,SkipBack as G,SkipForward as J,Smartphone as K,Square as L,Star as Q,StarHalf as R,StarOff as W,Trash2 as X,TriangleAlert as Y,Upload as Z,User as $,Volume1 as ee,Volume2 as oe,VolumeOff as re,VolumeX as ae,X as ie}from"lucide-react";export const A2UI_ICONS={accountCircle:f,add:M,arrowBack:e,arrowForward:o,attachFile:U,calendarToday:t,call:B,camera:n,check:l,close:ie,delete:X,download:d,edit:A,event:i,error:s,fastForward:w,favorite:k,favoriteOff:y,folder:O,help:c,home:g,info:F,locationOn:I,lock:b,lockOpen:x,mail:H,menu:N,moreVert:u,moreHoriz:m,notificationsOff:a,notifications:r,pause:z,payment:p,person:$,phone:K,photo:C,play:D,print:P,refresh:S,rewind:T,search:V,send:_,settings:j,share:q,shoppingCart:E,skipNext:J,skipPrevious:G,star:Q,starHalf:R,starOff:W,stop:L,upload:Z,visibility:h,visibilityOff:v,volumeDown:ee,volumeMute:ae,volumeOff:re,volumeUp:oe,warning:Y};
@@ -118,7 +118,7 @@ export interface MPAlertProps extends Omit<React.ComponentPropsWithoutRef<'div'>
118
118
  * `transition="fade"` is the whole of what most callers want; the object form
119
119
  * takes a duration, an edge to come from, or a scale to start at. Anything
120
120
  * that has to run again — on scroll, on hover, under your own control — is an
121
- * [MPAnimateFade](../motion/animate-fade) and its siblings.
121
+ * [MPAnimateFade](../transitions/animate-fade) and its siblings.
122
122
  */
123
123
  transition?: MPTransition;
124
124
  }
@@ -38,7 +38,7 @@ export interface MPAnimateGrowProps extends MPAnimateProps, MPAnimateStaggerProp
38
38
  * library can offer it: something opens out of the place it belongs to. A panel
39
39
  * out of a toolbar, a card out of the row it sits in, a sheet out of the button
40
40
  * that summoned it — `origin` is what anchors it to that place, and it is the
41
- * whole difference between this and [MPAnimateZoom](../motion/animate-zoom).
41
+ * whole difference between this and [MPAnimateZoom](../transitions/animate-zoom).
42
42
  *
43
43
  * A Grow starts close to its final size, so the travel is short and the content
44
44
  * inside is legible for most of the animation. A Zoom starts at less than half
@@ -48,6 +48,6 @@ export interface MPAnimateSlideProps extends MPAnimateProps, MPAnimateStaggerPro
48
48
  * A slide moves the element and not the layout: this is a `translate`, so
49
49
  * nothing on the page reflows while it runs. For a much shorter travel over a
50
50
  * list of things, one after another, use
51
- * [MPAnimateAppear](../motion/animate-appear).
51
+ * [MPAnimateAppear](../transitions/animate-appear).
52
52
  */
53
53
  export declare const MPAnimateSlide: React.ForwardRefExoticComponent<MPAnimateSlideProps & React.RefAttributes<HTMLDivElement>>;
@@ -28,7 +28,7 @@ export interface MPAnimateZoomProps extends MPAnimateProps, MPAnimateStaggerProp
28
28
  /**
29
29
  * Content arriving from the middle of where it will end up.
30
30
  *
31
- * The same arithmetic as [MPAnimateGrow](../motion/animate-grow) at more than
31
+ * The same arithmetic as [MPAnimateGrow](../transitions/animate-grow) at more than
32
32
  * twice the distance, and always about the centre — which is the whole
33
33
  * difference. A grow unfolds *from* somewhere; a zoom comes at the reader.
34
34
  *
@@ -36,7 +36,7 @@ export interface MPAnimateZoomProps extends MPAnimateProps, MPAnimateStaggerProp
36
36
  * confirmation, a result, a number that has just landed. Use it once. An
37
37
  * interruption that happens three times on one screen is a layout, and the
38
38
  * effect that belongs to a set of things rather than to one is
39
- * [MPAnimateAppear](../motion/animate-appear).
39
+ * [MPAnimateAppear](../transitions/animate-appear).
40
40
  *
41
41
  * There is no `origin`, on purpose. A zoom anchored to a corner is a grow, and
42
42
  * the library does not offer two spellings of one idea.
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { type CartesianChartProps } from '../../internal/ChartFrame.js';
3
- import type { MPChartCurve, MPChartValueLabels } from '../../types.js';
3
+ import type { MPChartCurve, MPChartGaps, MPChartStack, MPChartValueLabels } from '../../types.js';
4
4
  export interface MPAreaChartProps extends CartesianChartProps {
5
5
  /**
6
6
  * How the edge of the band gets from one point to the next.
@@ -15,9 +15,13 @@ export interface MPAreaChartProps extends CartesianChartProps {
15
15
  * changes with it: unstacked areas are read against the axis one at a time,
16
16
  * and a stack is read as a composition. Only the bottom band and the total
17
17
  * are easy to read in a stack, which is the trade it makes.
18
+ *
19
+ * `'percent'` fills the plot, so the top edge is flat and what is left is the
20
+ * composition alone — the shape a share-of-traffic chart wants. A negative
21
+ * has no share of a whole and is left out of one.
18
22
  * @default false
19
23
  */
20
- stacked?: boolean;
24
+ stacked?: MPChartStack;
21
25
  /**
22
26
  * The dots on the joins. `auto` draws them on an unstacked chart with room
23
27
  * for them and never on a stack, where a vertex belongs to a boundary rather
@@ -25,6 +29,17 @@ export interface MPAreaChartProps extends CartesianChartProps {
25
29
  * @default 'auto'
26
30
  */
27
31
  markers?: boolean | 'auto';
32
+ /**
33
+ * What the band does where a series has no value.
34
+ *
35
+ * `break` leaves a hole in the fill as well as in the edge, `connect` closes
36
+ * the fill across it and draws the joining edge dashed, and `zero` draws the
37
+ * missing reading at zero — which on a band standing on the axis pinches it
38
+ * shut. The hover panel and the table still report a gap as a gap in all
39
+ * three.
40
+ * @default 'break'
41
+ */
42
+ gaps?: MPChartGaps;
28
43
  /**
29
44
  * Which values are written onto the top edge.
30
45
  * @default 'none'
@@ -76,4 +91,4 @@ export interface MPAreaChartProps extends CartesianChartProps {
76
91
  * from a series' place in the `series` array, so what changes is the height of
77
92
  * the stack and never which band is which.
78
93
  */
79
- export declare function MPAreaChart({ curve, stacked, markers, valueLabels, ...frame }: MPAreaChartProps): React.JSX.Element;
94
+ export declare function MPAreaChart({ curve, stacked, markers, gaps, valueLabels, ...frame }: MPAreaChartProps): React.JSX.Element;
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import{CartesianFrame as r}from"../../internal/ChartFrame.js";import{LINE_WIDTH as l,MARKER_RADIUS as n,MARK_GAP as a,bandPath as o,linePath as s}from"../../internal/chart.js";export function MPAreaChart({curve:u="linear",stacked:i=!1,markers:c="auto",valueLabels:h="none",...p}){return e(r,{...p,inset:!0,stacked:i,includeZero:!0,headroom:"none"===h?0:14,children:({plot:r,values:p,visible:m,colors:d,point:f,zeroPx:x,size:v,hovered:k,activeIndex:y,format:b})=>{const j=l[v],g=n[v],M=p.reduce((e,t)=>Math.max(e,t.length),0),_=M>1?r.width/(M-1):r.width,w="auto"===c?!i&&_>=6*g:c,z=p.map(()=>({top:[],base:[]}));for(let e=0;e<M;e+=1){let t=0,r=0;p.forEach((l,n)=>{const o=l[e]?.value??null;if(!m[n]||null===o)return z[n].top.push(null),void z[n].base.push(null);if(!i){const t=f(e,o);return z[n].top.push(t),void z[n].base.push({x:t.x,y:x})}const s=o>=0?t:r,u=s+o;o>=0?t=u:r=u;const c=f(e,u),h=f(e,s);z[n].top.push(c),z[n].base.push({x:h.x,y:0===s?h.y:h.y-Math.sign(o||1)*a})})}return e("g",{className:"mp-area-chart__marks",children:p.map((l,n)=>{if(!m[n])return null;const{top:a,base:c}=z[n],p=d[n];return t("g",{opacity:null!==k&&k!==n?.25:1,children:[e("path",{d:o(a,c,u),fill:p,fillOpacity:i?.85:.18,stroke:"none"}),e("path",{d:s(a,u),fill:"none",stroke:p,strokeWidth:j,strokeLinecap:"round",strokeLinejoin:"round"}),a.map((t,r)=>{if(!t)return null;const l=y===r;return w||l?e("circle",{cx:t.x,cy:t.y,r:l?g+1:g,fill:p,stroke:"var(--_mp-color-surface)",strokeWidth:2},r):null}),"none"===h?null:l.map((t,n)=>{const o=a[n];if(!o||null===t.value)return null;const s=l.filter(e=>null!==e.value),u=s.map(e=>e.value);if(!("all"===h||"last"===h&&t===s[s.length-1]||"extremes"===h&&(t.value===Math.min(...u)||t.value===Math.max(...u))))return null;const i=o.x>r.left+r.width-24?"end":o.x<r.left+24?"start":"middle";return e("text",{x:o.x,y:o.y-g-5,textAnchor:i,fill:"var(--_mp-color-on-surface)",fontSize:"xs"===v||"sm"===v?10:11,children:t.label??b(t.value)},n)})]},n)})})}})}
2
+ import{jsx as e,jsxs as l}from"react/jsx-runtime";import{CartesianFrame as t}from"../../internal/ChartFrame.js";import{BRIDGE_DASH as n,LINE_WIDTH as r,MARKER_RADIUS as a,MARK_GAP as o,bandPath as s,bridgePath as u,linePath as i,withoutGaps as c}from"../../internal/chart.js";export function MPAreaChart({curve:h="linear",stacked:p=!1,markers:d="auto",gaps:m="break",valueLabels:f="none",...x}){return e(t,{...x,inset:!0,stacked:p,includeZero:!0,headroom:"none"===f?0:14,children:({plot:t,values:x,visible:v,colors:k,labelInk:y,point:b,zeroPx:g,size:j,hovered:M,activeIndex:z,format:L,share:w})=>{const A=r[j],W=a[j],_=x.reduce((e,l)=>Math.max(e,l.length),0),C=_>1?t.width/(_-1):t.width,I="auto"===d?!p&&C>=6*W:d,P=x.map(()=>({top:[],base:[]})),$="percent"===p?Array.from({length:_},(e,l)=>x.reduce((e,t,n)=>{const r=v[n]?t[l]?.value??0:0;return e+(r>0?r:0)},0)):null,D=(e,l)=>null===$?e:e>=0&&$[l]>0?e/$[l]:null;for(let e=0;e<_;e+=1){let l=0,t=0;x.forEach((n,r)=>{const a=n[e]?.value??null,s=null===a&&"zero"===m?0:a,u=null===s?null:D(s,e);if(!v[r]||null===u)return P[r].top.push(null),void P[r].base.push(null);if(!p){const l=b(e,u);return P[r].top.push(l),void P[r].base.push({x:l.x,y:g})}const i=u>=0?l:t,c=i+u;u>=0?l=c:t=c;const h=b(e,c),d=b(e,i);P[r].top.push(h),P[r].base.push({x:d.x,y:0===i?d.y:d.y-Math.sign(u||1)*o})})}return e("g",{className:"mp-area-chart__marks",children:x.map((r,a)=>{if(!v[a])return null;const{top:o,base:d}=P[a],x=k[a];return l("g",{opacity:null!==M&&M!==a?.25:1,children:[e("path",{d:"connect"===m?s(c(o),c(d),h):s(o,d,h),fill:x,fillOpacity:p?.85:.18,stroke:"none"}),e("path",{d:i(o,h),fill:"none",stroke:x,strokeWidth:A,strokeLinecap:"round",strokeLinejoin:"round"}),"connect"===m?e("path",{d:u(o),fill:"none",stroke:x,strokeWidth:A,strokeDasharray:`${A*n} ${A*n}`,strokeLinecap:"round"}):null,o.map((l,t)=>{if(!l)return null;const n=z===t;return I||n?e("circle",{cx:l.x,cy:l.y,r:n?W+1:W,fill:x,stroke:"var(--_mp-color-surface)",strokeWidth:2},t):null}),"none"===f?null:r.map((l,n)=>{const s=o[n];if(!s||null===l.value)return null;const u=r.filter(e=>null!==e.value),i=u.map(e=>e.value);if(!("all"===f||"last"===f&&l===u[u.length-1]||"extremes"===f&&(l.value===Math.min(...i)||l.value===Math.max(...i))))return null;const c=s.x>t.left+t.width-24?"end":s.x<t.left+24?"start":"middle";return e("text",{x:s.x,y:s.y-W-5,textAnchor:c,fill:y(a),fontSize:"xs"===j||"sm"===j?10:11,children:l.label??(null===$?L(l.value):w(D(l.value,n)??0))},n)})]},a)})})}})}
@@ -92,7 +92,7 @@ export interface MPAvatarProps extends Omit<React.ComponentPropsWithoutRef<'span
92
92
  * `transition="fade"` is the whole of what most callers want; the object form
93
93
  * takes a duration, an edge to come from, or a scale to start at. Anything
94
94
  * that has to run again — on scroll, on hover, under your own control — is an
95
- * [MPAnimateFade](../motion/animate-fade) and its siblings.
95
+ * [MPAnimateFade](../transitions/animate-fade) and its siblings.
96
96
  */
97
97
  transition?: MPTransition;
98
98
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { type CartesianChartProps } from '../../internal/ChartFrame.js';
3
- import type { MPChartValueLabels } from '../../types.js';
3
+ import type { MPChartStack, MPChartValueLabels } from '../../types.js';
4
4
  export interface MPBarChartProps extends CartesianChartProps {
5
5
  /**
6
6
  * Stacks the series into one bar per category instead of standing them side
@@ -10,9 +10,13 @@ export interface MPBarChartProps extends CartesianChartProps {
10
10
  * shows what makes them up. Both cannot be true at once, and picking the
11
11
  * wrong one is the most common way a bar chart answers a question nobody
12
12
  * asked.
13
+ *
14
+ * `'percent'` fills every bar, so what is compared is the composition and the
15
+ * totals leave the picture entirely. A negative has no share of a whole and
16
+ * is left out of one, the way `MPPieChart` leaves it out.
13
17
  * @default false
14
18
  */
15
- stacked?: boolean;
19
+ stacked?: MPChartStack;
16
20
  /**
17
21
  * Turns the chart on its side, so the bars run left to right.
18
22
  *
@@ -67,8 +71,14 @@ export interface MPBarChartProps extends CartesianChartProps {
67
71
  * ## Turn it sideways for long names
68
72
  *
69
73
  * `horizontal` gives every category a row of its own, which is what a set of
70
- * names like "Onboarding flow" needs. The alternative is labels cut to a slot
71
- * the width of one bar, or an axis of words rotated forty-five degrees, which
72
- * is unreadable at a glance and takes a band of the plot to be unreadable in.
74
+ * names like "Onboarding flow" wants: a name in a row reads left to right at
75
+ * full size, and the bars beside it are still lengths being compared.
76
+ *
77
+ * Upright, the axis turns the names instead — 45° while that fits and upright
78
+ * past it — rather than cutting them to a slot the width of one bar. It is the
79
+ * better of the two answers a vertical chart has, and it is still the worse of
80
+ * the two on this page: a turned name is read slower than a level one. Reach
81
+ * for `horizontal` when every name is long, and let `xAxis.tickLabels` handle
82
+ * the chart where one of them is.
73
83
  */
74
84
  export declare function MPBarChart({ stacked, horizontal, valueLabels, ...frame }: MPBarChartProps): React.JSX.Element;
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as t,jsxs as e}from"react/jsx-runtime";import*as l from"react";import{CartesianFrame as r}from"../../internal/ChartFrame.js";import{useMPLocale as n}from"../../internal/locale.js";import{useMPSize as a}from"../../internal/config.js";import{BAR_BAND_RATIO as o,BAR_MAX_THICKNESS as i,BAR_RADIUS as u,CHART_FONT_SIZE as s,MARK_GAP as m,barPath as c,formatStatistic as h,textWidth as f,toValues as d}from"../../internal/chart.js";export function MPBarChart({stacked:x=!1,horizontal:p=!1,valueLabels:v="none",...b}){const y=a(b.size),M=n(b.locale),g=l.useMemo(()=>{const t=s[y];if("none"===v||x)return 0;if(!p)return t+8;return d(b.series).flat().reduce((e,l)=>null===l.value?e:Math.max(e,f(String(l.label??h(l.value,M,b.format,!0)),t)),0)+10},[v,x,p,y,M,b.series,b.format]);return t(r,{...b,inset:!1,stacked:x,horizontal:p,bandRatio:o,includeZero:!0,headroom:g,children:({plot:l,values:r,visible:n,colors:a,band:o,valuePx:h,categoryPx:f,zeroPx:d,hovered:b,activeIndex:M,format:g})=>{const j=r.reduce((t,e)=>Math.max(t,e.length),0),k=r.map((t,e)=>e).filter(t=>n[t]),z=x?o.band:o.band/Math.max(1,k.length),_=Math.max(1,Math.min(z-(x?0:m),i[y]));return e("g",{className:"mp-bar-chart__marks",children:[r.map((i,d)=>{if(!n[d])return null;const w=a[d],P=null!==b&&b!==d,A=k.indexOf(d);return e("g",{opacity:P?.25:1,children:[Array.from({length:j},(e,n)=>{const a=i[n]?.value??null;if(null===a)return null;let s=0,v=d;if(x){let t=0,e=0;for(const l of k){const o=r[l][n]?.value??null;null!==o&&(l===d&&(s=o>=0?t:e),o>=0?t+=o:e+=o,o>=0==a>=0&&(v=l))}}const b=h(s),y=h(a+(x?s:0)),g=x&&0!==s?b+(y>b?m:-m):b,j=Math.abs(y-g);if(j<=0||y>b!=y>g)return null;const P=(p?l.top:l.left)+f(n)-o.band/2+(x?0:A*z)+(z-_)/2,B=d!==v?"none":p?a>=0?"right":"left":a>=0?"top":"bottom",C=p?{x:Math.min(g,y),y:P,w:j,h:_}:{x:P,y:Math.min(g,y),w:_,h:j},S=M===n;return t("path",{d:c(C.x,C.y,C.w,C.h,u,B),fill:w,opacity:null===M||S?1:.55},n)}),"none"===v||x?null:i.map((e,r)=>{if(null===e.value)return null;const n=i.map(t=>t.value).filter(t=>null!==t);if(!("all"===v||"last"===v&&r===j-1||"extremes"===v&&(e.value===Math.min(...n)||e.value===Math.max(...n))))return null;const a=h(e.value),u=(p?l.top:l.left)+f(r)-o.band/2+A*z+z/2,m=e.value>=0?-6:6;return t("text",{x:p?a-m:u,y:p?u:a+m,textAnchor:p?e.value>=0?"start":"end":"middle",dominantBaseline:p?"central":"auto",fill:"var(--_mp-color-on-surface)",fontSize:s[y]-1,children:e.label??g(e.value)},r)})]},d)}),t("line",p?{x1:d,x2:d,y1:l.top,y2:l.top+l.height,stroke:"var(--_mp-color-outline)",strokeWidth:1}:{x1:l.left,x2:l.left+l.width,y1:d,y2:d,stroke:"var(--_mp-color-outline)",strokeWidth:1})]})}})}
2
+ import{jsx as t,jsxs as e}from"react/jsx-runtime";import*as l from"react";import{CartesianFrame as n}from"../../internal/ChartFrame.js";import{useMPLocale as r}from"../../internal/locale.js";import{useMPSize as a}from"../../internal/config.js";import{BAR_BAND_RATIO as o,BAR_MAX_THICKNESS as i,BAR_RADIUS as u,CHART_FONT_SIZE as s,MARK_GAP as m,barPath as c,formatStatistic as h,textWidth as f,toValues as d}from"../../internal/chart.js";export function MPBarChart({stacked:x=!1,horizontal:p=!1,valueLabels:v="none",...b}){const y=a(b.size),M=r(b.locale),g=l.useMemo(()=>{const t=s[y];if("none"===v||x)return 0;if(!p)return t+8;return d(b.series).flat().reduce((e,l)=>null===l.value?e:Math.max(e,f(String(l.label??h(l.value,M,b.format,!0)),t)),0)+10},[v,x,p,y,M,b.series,b.format]);return t(n,{...b,inset:!1,stacked:x,horizontal:p,bandRatio:o,includeZero:!0,headroom:g,children:({plot:l,values:n,visible:r,colors:a,labelInk:o,band:h,valuePx:f,categoryPx:d,zeroPx:b,hovered:M,activeIndex:g,format:k})=>{const j=n.reduce((t,e)=>Math.max(t,e.length),0),z=n.map((t,e)=>e).filter(t=>r[t]),w="percent"===x?Array.from({length:j},(t,e)=>z.reduce((t,l)=>{const r=n[l][e]?.value??0;return t+(r>0?r:0)},0)):null,P=(t,e)=>{const l=n[t][e]?.value??null;return null===l||null===w?l:l>=0&&w[e]>0?l/w[e]:null},_=x?h.band:h.band/Math.max(1,z.length),A=Math.max(1,Math.min(_-(x?0:m),i[y]));return e("g",{className:"mp-bar-chart__marks",children:[n.map((n,i)=>{if(!r[i])return null;const b=a[i],w=null!==M&&M!==i,B=z.indexOf(i);return e("g",{opacity:w?.25:1,children:[Array.from({length:j},(e,n)=>{const r=P(i,n);if(null===r)return null;let a=0,o=i;if(x){let t=0,e=0;for(const l of z){const u=P(l,n);null!==u&&(l===i&&(a=u>=0?t:e),u>=0?t+=u:e+=u,u>=0==r>=0&&(o=l))}}const s=f(a),v=f(r+(x?a:0)),y=x&&0!==a?s+(v>s?m:-m):s,M=Math.abs(v-y);if(M<=0||v>s!=v>y)return null;const k=(p?l.top:l.left)+d(n)-h.band/2+(x?0:B*_)+(_-A)/2,j=i!==o?"none":p?r>=0?"right":"left":r>=0?"top":"bottom",w=p?{x:Math.min(y,v),y:k,w:M,h:A}:{x:k,y:Math.min(y,v),w:A,h:M},C=g===n;return t("path",{d:c(w.x,w.y,w.w,w.h,u,j),fill:b,opacity:null===g||C?1:.55},n)}),"none"===v||x?null:n.map((e,r)=>{if(null===e.value)return null;const a=n.map(t=>t.value).filter(t=>null!==t);if(!("all"===v||"last"===v&&r===j-1||"extremes"===v&&(e.value===Math.min(...a)||e.value===Math.max(...a))))return null;const u=f(e.value),m=(p?l.top:l.left)+d(r)-h.band/2+B*_+_/2,c=e.value>=0?-6:6;return t("text",{x:p?u-c:m,y:p?m:u+c,textAnchor:p?e.value>=0?"start":"end":"middle",dominantBaseline:p?"central":"auto",fill:o(i),fontSize:s[y]-1,children:e.label??k(e.value)},r)})]},i)}),t("line",p?{x1:b,x2:b,y1:l.top,y2:l.top+l.height,stroke:"var(--_mp-color-outline)",strokeWidth:1}:{x1:l.left,x2:l.left+l.width,y1:b,y2:b,stroke:"var(--_mp-color-outline)",strokeWidth:1})]})}})}
@@ -54,7 +54,7 @@ export interface MPBlockquoteProps extends Omit<React.ComponentPropsWithoutRef<'
54
54
  * `transition="fade"` is the whole of what most callers want; the object form
55
55
  * takes a duration, an edge to come from, or a scale to start at. Anything
56
56
  * that has to run again — on scroll, on hover, under your own control — is an
57
- * [MPAnimateFade](../motion/animate-fade) and its siblings.
57
+ * [MPAnimateFade](../transitions/animate-fade) and its siblings.
58
58
  */
59
59
  transition?: MPTransition;
60
60
  }
@@ -54,7 +54,7 @@ export interface MPBoxProps extends React.ComponentPropsWithoutRef<'div'> {
54
54
  * `transition="fade"` is the whole of what most callers want; the object form
55
55
  * takes a duration, an edge to come from, or a scale to start at. Anything
56
56
  * that has to run again — on scroll, on hover, under your own control — is an
57
- * [MPAnimateFade](../motion/animate-fade) and its siblings, and wrapping is
57
+ * [MPAnimateFade](../transitions/animate-fade) and its siblings, and wrapping is
58
58
  * the right answer there.
59
59
  */
60
60
  transition?: MPTransition;
@@ -63,7 +63,7 @@ export interface MPChipProps extends Omit<React.ComponentPropsWithoutRef<'span'>
63
63
  * `transition="fade"` is the whole of what most callers want; the object form
64
64
  * takes a duration, an edge to come from, or a scale to start at. Anything
65
65
  * that has to run again — on scroll, on hover, under your own control — is an
66
- * [MPAnimateFade](../motion/animate-fade) and its siblings.
66
+ * [MPAnimateFade](../transitions/animate-fade) and its siblings.
67
67
  */
68
68
  transition?: MPTransition;
69
69
  }
@@ -52,7 +52,7 @@ export interface MPEmptyProps extends Omit<React.ComponentPropsWithoutRef<'div'>
52
52
  * `transition="fade"` is the whole of what most callers want; the object form
53
53
  * takes a duration, an edge to come from, or a scale to start at. Anything
54
54
  * that has to run again — on scroll, on hover, under your own control — is an
55
- * [MPAnimateFade](../motion/animate-fade) and its siblings.
55
+ * [MPAnimateFade](../transitions/animate-fade) and its siblings.
56
56
  */
57
57
  transition?: MPTransition;
58
58
  }
@@ -1,7 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { type ChartBaseProps } from '../../internal/ChartChrome.js';
3
3
  import type { MPChartAxis, MPChartCategory, MPChartSeries } from '../../types.js';
4
- export interface MPHeatmapChartProps extends ChartBaseProps {
4
+ /**
5
+ * No `labelColor`: every piece of text this chart writes sits **on** a ramp
6
+ * step, where the question is what reads against the fill underneath. There are
7
+ * no series here for an ink to name, either.
8
+ */
9
+ export interface MPHeatmapChartProps extends Omit<ChartBaseProps, 'labelColor'> {
5
10
  /**
6
11
  * The rows. Each series is one row and its `data` are that row's cells, in
7
12
  * the order `categories` names the columns.
@@ -9,9 +14,13 @@ export interface MPHeatmapChartProps extends ChartBaseProps {
9
14
  series: readonly MPChartSeries[];
10
15
  /** The column headings. */
11
16
  categories?: readonly MPChartCategory[];
12
- /** The column axis. Only `label`, `hidden` and `tickFormat` mean anything here. */
17
+ /**
18
+ * The column axis. Only `label`, `hidden`, `thickness`, `tickFormat` and
19
+ * `tickLabels` mean anything here — there is no scale to pin and no grid to
20
+ * cast when both axes are categorical.
21
+ */
13
22
  xAxis?: MPChartAxis;
14
- /** The row axis, same three. */
23
+ /** The row axis, minus `tickLabels`: a row already has a line of its own. */
15
24
  yAxis?: MPChartAxis;
16
25
  /**
17
26
  * Where the colour scale starts and ends. Taken from the data otherwise.