@fluentui/react-charts 9.3.22 → 9.3.23

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 (62) hide show
  1. package/CHANGELOG.md +15 -2
  2. package/lib/components/DonutChart/Arc/Arc.js +3 -2
  3. package/lib/components/DonutChart/Arc/Arc.js.map +1 -1
  4. package/lib/components/DonutChart/Pie/Pie.js +3 -1
  5. package/lib/components/DonutChart/Pie/Pie.js.map +1 -1
  6. package/lib/components/FunnelChart/FunnelChart.js +14 -3
  7. package/lib/components/FunnelChart/FunnelChart.js.map +1 -1
  8. package/lib/components/GanttChart/GanttChart.js +5 -2
  9. package/lib/components/GanttChart/GanttChart.js.map +1 -1
  10. package/lib/components/GaugeChart/GaugeChart.js +6 -3
  11. package/lib/components/GaugeChart/GaugeChart.js.map +1 -1
  12. package/lib/components/HeatMapChart/HeatMapChart.js +8 -3
  13. package/lib/components/HeatMapChart/HeatMapChart.js.map +1 -1
  14. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js +2 -2
  15. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js.map +1 -1
  16. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js +1 -1
  17. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js.map +1 -1
  18. package/lib/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js +2 -2
  19. package/lib/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js.map +1 -1
  20. package/lib/components/Legends/Legends.js +62 -32
  21. package/lib/components/Legends/Legends.js.map +1 -1
  22. package/lib/components/Legends/OverflowMenu.js +47 -9
  23. package/lib/components/Legends/OverflowMenu.js.map +1 -1
  24. package/lib/components/SankeyChart/SankeyChart.js +13 -7
  25. package/lib/components/SankeyChart/SankeyChart.js.map +1 -1
  26. package/lib/components/ScatterChart/ScatterChart.js +3 -3
  27. package/lib/components/ScatterChart/ScatterChart.js.map +1 -1
  28. package/lib/components/VerticalBarChart/VerticalBarChart.js +6 -3
  29. package/lib/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  30. package/lib/utilities/utilities.js +2 -2
  31. package/lib/utilities/utilities.js.map +1 -1
  32. package/lib-commonjs/components/DonutChart/Arc/Arc.js +3 -2
  33. package/lib-commonjs/components/DonutChart/Arc/Arc.js.map +1 -1
  34. package/lib-commonjs/components/DonutChart/Pie/Pie.js +3 -1
  35. package/lib-commonjs/components/DonutChart/Pie/Pie.js.map +1 -1
  36. package/lib-commonjs/components/FunnelChart/FunnelChart.js +14 -3
  37. package/lib-commonjs/components/FunnelChart/FunnelChart.js.map +1 -1
  38. package/lib-commonjs/components/GanttChart/GanttChart.js +5 -2
  39. package/lib-commonjs/components/GanttChart/GanttChart.js.map +1 -1
  40. package/lib-commonjs/components/GaugeChart/GaugeChart.js +6 -3
  41. package/lib-commonjs/components/GaugeChart/GaugeChart.js.map +1 -1
  42. package/lib-commonjs/components/HeatMapChart/HeatMapChart.js +8 -3
  43. package/lib-commonjs/components/HeatMapChart/HeatMapChart.js.map +1 -1
  44. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js +4 -4
  45. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js.map +1 -1
  46. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js +1 -1
  47. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js.map +1 -1
  48. package/lib-commonjs/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js +2 -2
  49. package/lib-commonjs/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js.map +1 -1
  50. package/lib-commonjs/components/Legends/Legends.js +62 -32
  51. package/lib-commonjs/components/Legends/Legends.js.map +1 -1
  52. package/lib-commonjs/components/Legends/OverflowMenu.js +46 -8
  53. package/lib-commonjs/components/Legends/OverflowMenu.js.map +1 -1
  54. package/lib-commonjs/components/SankeyChart/SankeyChart.js +13 -7
  55. package/lib-commonjs/components/SankeyChart/SankeyChart.js.map +1 -1
  56. package/lib-commonjs/components/ScatterChart/ScatterChart.js +3 -3
  57. package/lib-commonjs/components/ScatterChart/ScatterChart.js.map +1 -1
  58. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js +6 -3
  59. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  60. package/lib-commonjs/utilities/utilities.js +2 -2
  61. package/lib-commonjs/utilities/utilities.js.map +1 -1
  62. package/package.json +3 -3
@@ -70,7 +70,7 @@ export const Legends = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
70
70
  const itemIds = dataToRender.map((_item, index)=>index.toString());
71
71
  const overflowHoverCardLegends = [];
72
72
  dataToRender.map((legend, index)=>{
73
- const hoverCardElement = _renderButton(legend, index);
73
+ const hoverCardElement = _renderButton(legend, index, true);
74
74
  overflowHoverCardLegends.push(hoverCardElement);
75
75
  });
76
76
  const overflowString = props.overflowText ? props.overflowText : 'more';
@@ -79,11 +79,6 @@ export const Legends = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
79
79
  return /*#__PURE__*/ React.createElement("div", {
80
80
  ...focusAttributes,
81
81
  ...arrowAttributes,
82
- ...allowFocusOnLegends && {
83
- role: 'listbox',
84
- 'aria-label': 'Legends',
85
- 'aria-multiselectable': canSelectMultipleLegends
86
- },
87
82
  className: classes.root,
88
83
  ref: _rootElem
89
84
  }, /*#__PURE__*/ React.createElement(Overflow, null, /*#__PURE__*/ React.createElement("div", {
@@ -91,10 +86,19 @@ export const Legends = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
91
86
  style: {
92
87
  textAlign: props.centerLegends ? 'center' : 'unset'
93
88
  }
89
+ }, /*#__PURE__*/ React.createElement("div", {
90
+ ...allowFocusOnLegends && {
91
+ role: 'listbox',
92
+ 'aria-label': 'Legends',
93
+ 'aria-multiselectable': canSelectMultipleLegends
94
+ },
95
+ style: {
96
+ display: 'contents'
97
+ }
94
98
  }, dataToRender.map((item, id)=>/*#__PURE__*/ React.createElement(OverflowItem, {
95
99
  key: id,
96
100
  id: id.toString()
97
- }, _renderButton(item))), /*#__PURE__*/ React.createElement(OverflowMenu, {
101
+ }, _renderButton(item, id)))), /*#__PURE__*/ React.createElement(OverflowMenu, {
98
102
  itemIds: itemIds,
99
103
  title: `${overflowString}`,
100
104
  items: overflowHoverCardLegends
@@ -123,10 +127,10 @@ export const Legends = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
123
127
  flexWrap: 'wrap',
124
128
  overflow: 'auto'
125
129
  }
126
- }, dataToRender.map((item)=>/*#__PURE__*/ React.createElement("div", {
130
+ }, dataToRender.map((item, id)=>/*#__PURE__*/ React.createElement("div", {
127
131
  className: mergeClasses(classes.legendContainer, item.legendAnnotation && classes.annotation),
128
132
  key: item.key
129
- }, _renderButton(item), item.legendAnnotation && /*#__PURE__*/ React.createElement("div", null, item.legendAnnotation())))));
133
+ }, _renderButton(item, id), item.legendAnnotation && /*#__PURE__*/ React.createElement("div", null, item.legendAnnotation())))));
130
134
  }
131
135
  function _generateData() {
132
136
  const { shape } = props;
@@ -217,8 +221,10 @@ export const Legends = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
217
221
  }
218
222
  }
219
223
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
220
- function _renderButton(data, index) {
224
+ function _renderButton(data, index, isOverflowItem) {
221
225
  const { allowFocusOnLegends = true } = props;
226
+ // Overflow legends are rendered inside a menu, not the listbox, so they must not carry `option` semantics.
227
+ const showListboxOption = allowFocusOnLegends && !isOverflowItem;
222
228
  const legend = {
223
229
  title: data.title,
224
230
  color: data.color,
@@ -241,38 +247,62 @@ export const Legends = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
241
247
  _onLeave(legend);
242
248
  };
243
249
  const shape = _getShape(legend, color);
250
+ const legendStyle = {
251
+ '--rect-height': legend.isLineLegendInBarChart ? '4px' : '12px',
252
+ '--rect-backgroundColor': legend.stripePattern ? '' : color,
253
+ '--rect-borderColor': legend.color ? legend.color : tokens.colorNeutralStroke1,
254
+ '--rect-content': legend.stripePattern ? `repeating-linear-gradient(135deg, transparent, transparent 3px, ${color} 1px, ${color} 4px)` : ''
255
+ };
256
+ const legendContent = /*#__PURE__*/ React.createElement(React.Fragment, null, shape, /*#__PURE__*/ React.createElement("div", {
257
+ className: classes.text,
258
+ style: {
259
+ opacity: color === tokens.colorNeutralBackground1 ? '0.67' : ''
260
+ }
261
+ }, legend.title));
262
+ // Shared by the listbox Button and the overflow div. Hover/focus handlers are included so the overflow
263
+ // menu can forward them to its item (the div itself never receives focus).
264
+ const commonProps = {
265
+ className: classes.legend,
266
+ onClick: onClickHandler,
267
+ onMouseOver: onHoverHandler,
268
+ onMouseOut: onMouseOut,
269
+ onFocus: onHoverHandler,
270
+ onBlur: onMouseOut,
271
+ style: legendStyle
272
+ };
273
+ if (isOverflowItem) {
274
+ // In the overflow menu the item itself is interactive, so keep this content a non-interactive div to
275
+ // avoid nested clickable elements. display:flex lays the swatch and label out inline (a bare div would
276
+ // stack them). data-selected / data-title are read by the overflow menu to drive its checked state.
277
+ return /*#__PURE__*/ React.createElement("div", {
278
+ key: index,
279
+ ...commonProps,
280
+ "data-selected": !!selectedLegends[legend.title],
281
+ "data-title": legend.title,
282
+ style: {
283
+ ...legendStyle,
284
+ display: 'flex',
285
+ alignItems: 'center'
286
+ }
287
+ }, legendContent);
288
+ }
244
289
  return /*#__PURE__*/ React.createElement(Button, {
245
- ...allowFocusOnLegends && {
290
+ ...showListboxOption && {
246
291
  'aria-selected': !!selectedLegends[legend.title],
247
292
  role: 'option',
248
293
  'aria-label': `${legend.title}`,
249
- 'aria-setsize': data['aria-setsize'],
250
- 'aria-posinset': data['aria-posinset']
294
+ // Full-list position so counts match the overflow menu.
295
+ 'aria-setsize': props.legends.length,
296
+ 'aria-posinset': (index !== null && index !== void 0 ? index : 0) + 1
251
297
  },
252
298
  ...data.nativeButtonProps && {
253
299
  ...data.nativeButtonProps
254
300
  },
255
301
  key: index,
256
- className: classes.legend,
257
- onClick: onClickHandler,
258
- onMouseOver: onHoverHandler,
259
- onMouseOut: onMouseOut,
260
- onFocus: onHoverHandler,
261
- onBlur: onMouseOut,
302
+ ...commonProps,
262
303
  appearance: 'outline',
263
- size: "small",
264
- style: {
265
- '--rect-height': legend.isLineLegendInBarChart ? '4px' : '12px',
266
- '--rect-backgroundColor': legend.stripePattern ? '' : color,
267
- '--rect-borderColor': legend.color ? legend.color : tokens.colorNeutralStroke1,
268
- '--rect-content': legend.stripePattern ? `repeating-linear-gradient(135deg, transparent, transparent 3px, ${color} 1px, ${color} 4px)` : ''
269
- }
270
- }, shape, /*#__PURE__*/ React.createElement("div", {
271
- className: classes.text,
272
- style: {
273
- opacity: color === tokens.colorNeutralBackground1 ? '0.67' : ''
274
- }
275
- }, legend.title));
304
+ size: "small"
305
+ }, legendContent);
276
306
  }
277
307
  function _getShape(legend, color) {
278
308
  const svgParentProps = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Legends/Legends.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { JSXElement } from '@fluentui/react-utilities';\n\nimport { Button } from '@fluentui/react-button';\nimport type { Legend, LegendsProps, LegendShape } from './Legends.types';\nimport { Shape } from './shape';\nimport { useLegendStyles } from './useLegendsStyles.styles';\nimport { Overflow, OverflowItem } from '@fluentui/react-overflow';\nimport { useFocusableGroup, useArrowNavigationGroup } from '@fluentui/react-tabster';\nimport { OverflowMenu } from './OverflowMenu';\nimport { tokens } from '@fluentui/react-theme';\nimport { cloneLegendsToSVG } from '../../utilities/image-export-utils';\nimport { mergeClasses } from '@griffel/react';\n\n// This is an internal interface used for rendering the legends with unique key\ninterface LegendItem extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n name?: string;\n title: string;\n action: VoidFunction;\n hoverAction: VoidFunction;\n onMouseOutAction: VoidFunction;\n color: string;\n shape?: LegendShape;\n key: number;\n opacity?: number;\n stripePattern?: boolean;\n isLineLegendInBarChart?: boolean;\n legendAnnotation?: () => React.ReactNode;\n}\n\ninterface LegendMap {\n [key: string]: boolean;\n}\n\nexport interface LegendState {\n activeLegend: string;\n /** Set of legends selected, both for multiple selection and single selection */\n selectedLegends: LegendMap;\n}\nexport const Legends: React.FunctionComponent<LegendsProps> = React.forwardRef<HTMLDivElement, LegendsProps>(\n (props, forwardedRef) => {\n /** Boolean variable to check if one or more legends are selected */\n let _isLegendSelected = false;\n const _rootElem = React.useRef<HTMLDivElement | null>(null);\n\n // set states separately for each instance of the component\n const [activeLegend, setActiveLegend] = React.useState('');\n const [selectedLegends, setSelectedLegends] = React.useState<LegendMap>({});\n const focusAttributes = useFocusableGroup();\n const arrowAttributes = useArrowNavigationGroup({ axis: 'horizontal', memorizeCurrent: true });\n const classes = useLegendStyles(props);\n const toSVG = React.useCallback(\n (svgWidth: number, isRTL: boolean = false) => {\n return cloneLegendsToSVG(\n props.legends,\n svgWidth,\n {\n selectedLegends,\n centerLegends: !!props.centerLegends,\n textClassName: classes.text!,\n isRTL,\n },\n _rootElem.current,\n );\n },\n [props.legends, props.centerLegends, selectedLegends, classes.text],\n );\n\n React.useImperativeHandle(props.legendRef, () => ({\n toSVG,\n }));\n\n React.useEffect(() => {\n const initialSelectedLegends = props.selectedLegends ?? props.defaultSelectedLegends;\n const initialSelectedLegend = props.selectedLegend ?? props.defaultSelectedLegend;\n let selectedLegendsState = {};\n if (props.canSelectMultipleLegends) {\n selectedLegendsState =\n (initialSelectedLegends ?? [])?.reduce(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (combineDict: any, key: any) => ({ [key]: true, ...combineDict }),\n {},\n ) || {};\n setSelectedLegends(selectedLegendsState);\n } else if (initialSelectedLegend !== undefined) {\n selectedLegendsState = { [initialSelectedLegend]: true };\n setSelectedLegends(selectedLegendsState);\n }\n }, [\n props.canSelectMultipleLegends,\n props.defaultSelectedLegend,\n props.defaultSelectedLegends,\n props.selectedLegend,\n props.selectedLegends,\n ]);\n\n _isLegendSelected = Object.keys(selectedLegends).length > 0;\n const dataToRender = _generateData();\n const { overflowStyles, allowFocusOnLegends = true, canSelectMultipleLegends = false } = props;\n const itemIds = dataToRender.map((_item, index) => index.toString());\n const overflowHoverCardLegends: JSXElement[] = [];\n dataToRender.map((legend, index) => {\n const hoverCardElement = _renderButton(legend, index);\n overflowHoverCardLegends.push(hoverCardElement);\n });\n const overflowString = props.overflowText ? props.overflowText : 'more';\n return props.enabledWrapLines ? renderWrappedLegends() : renderLegends();\n\n function renderLegends(): JSXElement {\n return (\n <div\n {...focusAttributes}\n {...arrowAttributes}\n {...(allowFocusOnLegends && {\n role: 'listbox',\n 'aria-label': 'Legends',\n 'aria-multiselectable': canSelectMultipleLegends,\n })}\n className={classes.root}\n ref={_rootElem}\n >\n <Overflow>\n <div className={classes.resizableArea} style={{ textAlign: props.centerLegends ? 'center' : 'unset' }}>\n {dataToRender.map((item, id) => (\n <OverflowItem key={id} id={id.toString()}>\n {_renderButton(item)}\n </OverflowItem>\n ))}\n <OverflowMenu itemIds={itemIds} title={`${overflowString}`} items={overflowHoverCardLegends} />\n </div>\n </Overflow>\n </div>\n );\n }\n\n function renderWrappedLegends(): JSXElement {\n return (\n <div\n {...focusAttributes}\n {...arrowAttributes}\n {...(allowFocusOnLegends && {\n role: 'listbox',\n 'aria-label': 'Legends',\n 'aria-multiselectable': canSelectMultipleLegends,\n })}\n style={{ justifyContent: props.centerLegends ? 'center' : 'unset', flexWrap: 'wrap', ...overflowStyles }}\n className={classes.root}\n ref={_rootElem}\n >\n <div className={classes.resizableArea} style={{ display: 'flex', flexWrap: 'wrap', overflow: 'auto' }}>\n {dataToRender.map(item => (\n <div\n className={mergeClasses(classes.legendContainer, item.legendAnnotation && classes.annotation)}\n key={item.key}\n >\n {_renderButton(item)}\n {item.legendAnnotation && <div>{item.legendAnnotation()}</div>}\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n function _generateData(): LegendItem[] {\n const { /*allowFocusOnLegends = true,*/ shape } = props;\n const dataItems: LegendItem[] = props.legends.map((legend: Legend, index: number) => {\n return {\n /* ...(allowFocusOnLegends && {\n nativeButtonProps: getIntrinsicElementProps(\n 'div',\n {\n legend,\n ...buttonProperties,\n },\n ['title'],\n ),\n 'aria-setsize': props.legends.length,\n 'aria-posinset': index + 1,\n }), */\n title: legend.title,\n action: legend.action!,\n hoverAction: legend.hoverAction!,\n onMouseOutAction: legend.onMouseOutAction!,\n color: legend.color,\n shape: shape ? shape : legend.shape,\n stripePattern: legend.stripePattern,\n isLineLegendInBarChart: legend.isLineLegendInBarChart,\n opacity: legend.opacity,\n key: index,\n legendAnnotation: legend.legendAnnotation,\n };\n });\n return dataItems;\n }\n\n /**\n * Determine whether the component is in \"controlled\" mode for selections, where the selected legend(s) are\n * determined entirely by props passed in from the parent component.\n */\n function _isInControlledMode(): boolean {\n return props.canSelectMultipleLegends ? props.selectedLegends !== undefined : props.selectedLegend !== undefined;\n }\n\n /**\n * Get the new selected legends based on the legend that was clicked when multi-select is enabled.\n * @param legend The legend that was clicked\n * @returns An object with the new selected legend(s) state data.\n */\n function _getNewSelectedLegendsForMultiselect(legend: Legend): { [key: string]: boolean } {\n let legendsSelected = { ...selectedLegends };\n if (legendsSelected[legend.title]) {\n // Delete entry for the deselected legend to make\n // the number of keys equal to the number of selected legends\n delete legendsSelected[legend.title];\n } else {\n legendsSelected[legend.title] = true;\n // Clear set if all legends are selected\n if (Object.keys(legendsSelected).length === props.legends.length) {\n legendsSelected = {};\n }\n }\n return legendsSelected;\n }\n\n /**\n * Get the new selected legends based on the legend that was clicked when single-select is enabled.\n * @param legend The legend that was clicked\n * @returns An object with the new selected legend state data.\n */\n function _getNewSelectedLegendsForSingleSelect(legend: Legend): { [key: string]: boolean } {\n return selectedLegends[legend.title] ? {} : { [legend.title]: true };\n }\n\n function _onClick(legend: Legend, event: React.MouseEvent<HTMLButtonElement>): void {\n const { canSelectMultipleLegends = false } = props;\n const nextSelectedLegends = canSelectMultipleLegends\n ? _getNewSelectedLegendsForMultiselect(legend)\n : _getNewSelectedLegendsForSingleSelect(legend);\n\n if (!_isInControlledMode()) {\n setSelectedLegends(nextSelectedLegends);\n }\n props.onChange?.(Object.keys(nextSelectedLegends), event, legend);\n legend.action?.();\n }\n\n function _onHoverOverLegend(legend: Legend) {\n if (legend.hoverAction) {\n setActiveLegend(legend.title);\n legend.hoverAction();\n }\n }\n\n function _onLeave(legend: Legend) {\n if (legend.onMouseOutAction) {\n setActiveLegend('');\n legend.onMouseOutAction();\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function _renderButton(data: any, index?: number) {\n const { allowFocusOnLegends = true } = props;\n const legend: Legend = {\n title: data.title,\n color: data.color,\n shape: data.shape,\n action: data.action,\n hoverAction: data.hoverAction,\n onMouseOutAction: data.onMouseOutAction,\n stripePattern: data.stripePattern,\n isLineLegendInBarChart: data.isLineLegendInBarChart,\n opacity: data.opacity,\n };\n const color = _getColor(legend.title, legend.color);\n const onClickHandler = (event: React.MouseEvent<HTMLButtonElement>) => {\n _onClick(legend, event);\n };\n const onHoverHandler = () => {\n _onHoverOverLegend(legend);\n };\n const onMouseOut = () => {\n _onLeave(legend);\n };\n const shape = _getShape(legend, color);\n return (\n <Button\n {...(allowFocusOnLegends && {\n 'aria-selected': !!selectedLegends[legend.title],\n role: 'option',\n 'aria-label': `${legend.title}`,\n 'aria-setsize': data['aria-setsize'],\n 'aria-posinset': data['aria-posinset'],\n })}\n {...(data.nativeButtonProps && { ...data.nativeButtonProps })}\n key={index}\n className={classes.legend}\n onClick={onClickHandler}\n onMouseOver={onHoverHandler}\n onMouseOut={onMouseOut}\n onFocus={onHoverHandler}\n onBlur={onMouseOut}\n appearance={'outline'}\n size=\"small\"\n style={{\n '--rect-height': legend.isLineLegendInBarChart ? '4px' : '12px',\n '--rect-backgroundColor': legend.stripePattern ? '' : color,\n '--rect-borderColor': legend.color ? legend.color : tokens.colorNeutralStroke1,\n '--rect-content': legend.stripePattern\n ? `repeating-linear-gradient(135deg, transparent, transparent 3px, ${color} 1px, ${color} 4px)`\n : '',\n }}\n >\n {shape}\n <div className={classes.text} style={{ opacity: color === tokens.colorNeutralBackground1 ? '0.67' : '' }}>\n {legend.title}\n </div>\n </Button>\n );\n }\n\n function _getShape(legend: Legend, color: string): React.ReactNode | string {\n const svgParentProps: React.SVGAttributes<SVGElement> = {\n className: classes.shape,\n };\n const svgChildProps: React.SVGAttributes<SVGElement> = {\n fill: color,\n strokeWidth: 2,\n stroke: legend.color,\n };\n return (\n <Shape\n svgProps={svgParentProps}\n pathProps={svgChildProps}\n shape={legend.shape as LegendShape}\n classNameForNonSvg={classes.rect}\n style={\n {\n height: legend.isLineLegendInBarChart ? '4px' : '12px',\n backgroundColor: legend.stripePattern ? '' : color,\n borderColor: legend.color ? legend.color : tokens.colorNeutralStroke1,\n content: legend.stripePattern\n ? `repeating-linear-gradient(135deg, transparent, transparent 3px, ${color} 1px, ${color} 4px)`\n : '',\n '--rect-content-high-contrast': `linear-gradient(to right, ${color}, ${color})`,\n '--rect-opacity-high-contrast': color === tokens.colorNeutralBackground1 ? '0.6' : '',\n } as React.CSSProperties\n }\n />\n );\n }\n\n function _getColor(title: string, color: string): string {\n let legendColor = color;\n // if one or more legends are selected\n if (_isLegendSelected) {\n // if the given legend (title) is one of the selected legends\n if (selectedLegends[title]) {\n legendColor = color;\n }\n // if the given legend is unselected\n else {\n legendColor = tokens.colorNeutralBackground1;\n }\n }\n // if no legend is selected\n else {\n // if the given legend is hovered\n // or none of the legends is hovered\n if (activeLegend === title || activeLegend === '') {\n legendColor = color;\n }\n // if there is a hovered legend but the given legend is not the one\n else {\n legendColor = tokens.colorNeutralBackground1;\n }\n }\n return legendColor;\n }\n },\n);\nLegends.displayName = 'Legends';\n"],"names":["React","Button","Shape","useLegendStyles","Overflow","OverflowItem","useFocusableGroup","useArrowNavigationGroup","OverflowMenu","tokens","cloneLegendsToSVG","mergeClasses","Legends","forwardRef","props","forwardedRef","_isLegendSelected","_rootElem","useRef","activeLegend","setActiveLegend","useState","selectedLegends","setSelectedLegends","focusAttributes","arrowAttributes","axis","memorizeCurrent","classes","toSVG","useCallback","svgWidth","isRTL","legends","centerLegends","textClassName","text","current","useImperativeHandle","legendRef","useEffect","initialSelectedLegends","defaultSelectedLegends","initialSelectedLegend","selectedLegend","defaultSelectedLegend","selectedLegendsState","canSelectMultipleLegends","reduce","combineDict","key","undefined","Object","keys","length","dataToRender","_generateData","overflowStyles","allowFocusOnLegends","itemIds","map","_item","index","toString","overflowHoverCardLegends","legend","hoverCardElement","_renderButton","push","overflowString","overflowText","enabledWrapLines","renderWrappedLegends","renderLegends","div","role","className","root","ref","resizableArea","style","textAlign","item","id","title","items","justifyContent","flexWrap","display","overflow","legendContainer","legendAnnotation","annotation","shape","dataItems","action","hoverAction","onMouseOutAction","color","stripePattern","isLineLegendInBarChart","opacity","_isInControlledMode","_getNewSelectedLegendsForMultiselect","legendsSelected","_getNewSelectedLegendsForSingleSelect","_onClick","event","nextSelectedLegends","onChange","_onHoverOverLegend","_onLeave","data","_getColor","onClickHandler","onHoverHandler","onMouseOut","_getShape","nativeButtonProps","onClick","onMouseOver","onFocus","onBlur","appearance","size","colorNeutralStroke1","colorNeutralBackground1","svgParentProps","svgChildProps","fill","strokeWidth","stroke","svgProps","pathProps","classNameForNonSvg","rect","height","backgroundColor","borderColor","content","legendColor","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/components/Legends/Legends.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { JSXElement } from '@fluentui/react-utilities';\n\nimport { Button } from '@fluentui/react-button';\nimport type { Legend, LegendsProps, LegendShape } from './Legends.types';\nimport { Shape } from './shape';\nimport { useLegendStyles } from './useLegendsStyles.styles';\nimport { Overflow, OverflowItem } from '@fluentui/react-overflow';\nimport { useFocusableGroup, useArrowNavigationGroup } from '@fluentui/react-tabster';\nimport { OverflowMenu } from './OverflowMenu';\nimport { tokens } from '@fluentui/react-theme';\nimport { cloneLegendsToSVG } from '../../utilities/image-export-utils';\nimport { mergeClasses } from '@griffel/react';\n\n// This is an internal interface used for rendering the legends with unique key\ninterface LegendItem extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n name?: string;\n title: string;\n action: VoidFunction;\n hoverAction: VoidFunction;\n onMouseOutAction: VoidFunction;\n color: string;\n shape?: LegendShape;\n key: number;\n opacity?: number;\n stripePattern?: boolean;\n isLineLegendInBarChart?: boolean;\n legendAnnotation?: () => React.ReactNode;\n}\n\ninterface LegendMap {\n [key: string]: boolean;\n}\n\nexport interface LegendState {\n activeLegend: string;\n /** Set of legends selected, both for multiple selection and single selection */\n selectedLegends: LegendMap;\n}\nexport const Legends: React.FunctionComponent<LegendsProps> = React.forwardRef<HTMLDivElement, LegendsProps>(\n (props, forwardedRef) => {\n /** Boolean variable to check if one or more legends are selected */\n let _isLegendSelected = false;\n const _rootElem = React.useRef<HTMLDivElement | null>(null);\n\n // set states separately for each instance of the component\n const [activeLegend, setActiveLegend] = React.useState('');\n const [selectedLegends, setSelectedLegends] = React.useState<LegendMap>({});\n const focusAttributes = useFocusableGroup();\n const arrowAttributes = useArrowNavigationGroup({ axis: 'horizontal', memorizeCurrent: true });\n const classes = useLegendStyles(props);\n const toSVG = React.useCallback(\n (svgWidth: number, isRTL: boolean = false) => {\n return cloneLegendsToSVG(\n props.legends,\n svgWidth,\n {\n selectedLegends,\n centerLegends: !!props.centerLegends,\n textClassName: classes.text!,\n isRTL,\n },\n _rootElem.current,\n );\n },\n [props.legends, props.centerLegends, selectedLegends, classes.text],\n );\n\n React.useImperativeHandle(props.legendRef, () => ({\n toSVG,\n }));\n\n React.useEffect(() => {\n const initialSelectedLegends = props.selectedLegends ?? props.defaultSelectedLegends;\n const initialSelectedLegend = props.selectedLegend ?? props.defaultSelectedLegend;\n let selectedLegendsState = {};\n if (props.canSelectMultipleLegends) {\n selectedLegendsState =\n (initialSelectedLegends ?? [])?.reduce(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (combineDict: any, key: any) => ({ [key]: true, ...combineDict }),\n {},\n ) || {};\n setSelectedLegends(selectedLegendsState);\n } else if (initialSelectedLegend !== undefined) {\n selectedLegendsState = { [initialSelectedLegend]: true };\n setSelectedLegends(selectedLegendsState);\n }\n }, [\n props.canSelectMultipleLegends,\n props.defaultSelectedLegend,\n props.defaultSelectedLegends,\n props.selectedLegend,\n props.selectedLegends,\n ]);\n\n _isLegendSelected = Object.keys(selectedLegends).length > 0;\n const dataToRender = _generateData();\n const { overflowStyles, allowFocusOnLegends = true, canSelectMultipleLegends = false } = props;\n const itemIds = dataToRender.map((_item, index) => index.toString());\n const overflowHoverCardLegends: JSXElement[] = [];\n dataToRender.map((legend, index) => {\n const hoverCardElement = _renderButton(legend, index, true);\n overflowHoverCardLegends.push(hoverCardElement);\n });\n const overflowString = props.overflowText ? props.overflowText : 'more';\n return props.enabledWrapLines ? renderWrappedLegends() : renderLegends();\n\n function renderLegends(): JSXElement {\n return (\n <div {...focusAttributes} {...arrowAttributes} className={classes.root} ref={_rootElem}>\n <Overflow>\n <div className={classes.resizableArea} style={{ textAlign: props.centerLegends ? 'center' : 'unset' }}>\n {/*\n Only the selectable options belong to the listbox; the overflow trigger stays a sibling so a\n menu button is not treated as a listbox child. `display: contents` keeps the options as direct\n flex participants so overflow measurement is unaffected.\n */}\n <div\n {...(allowFocusOnLegends && {\n role: 'listbox',\n 'aria-label': 'Legends',\n 'aria-multiselectable': canSelectMultipleLegends,\n })}\n style={{ display: 'contents' }}\n >\n {dataToRender.map((item, id) => (\n <OverflowItem key={id} id={id.toString()}>\n {_renderButton(item, id)}\n </OverflowItem>\n ))}\n </div>\n <OverflowMenu itemIds={itemIds} title={`${overflowString}`} items={overflowHoverCardLegends} />\n </div>\n </Overflow>\n </div>\n );\n }\n\n function renderWrappedLegends(): JSXElement {\n return (\n <div\n {...focusAttributes}\n {...arrowAttributes}\n {...(allowFocusOnLegends && {\n role: 'listbox',\n 'aria-label': 'Legends',\n 'aria-multiselectable': canSelectMultipleLegends,\n })}\n style={{ justifyContent: props.centerLegends ? 'center' : 'unset', flexWrap: 'wrap', ...overflowStyles }}\n className={classes.root}\n ref={_rootElem}\n >\n <div className={classes.resizableArea} style={{ display: 'flex', flexWrap: 'wrap', overflow: 'auto' }}>\n {dataToRender.map((item, id) => (\n <div\n className={mergeClasses(classes.legendContainer, item.legendAnnotation && classes.annotation)}\n key={item.key}\n >\n {_renderButton(item, id)}\n {item.legendAnnotation && <div>{item.legendAnnotation()}</div>}\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n function _generateData(): LegendItem[] {\n const { /*allowFocusOnLegends = true,*/ shape } = props;\n const dataItems: LegendItem[] = props.legends.map((legend: Legend, index: number) => {\n return {\n /* ...(allowFocusOnLegends && {\n nativeButtonProps: getIntrinsicElementProps(\n 'div',\n {\n legend,\n ...buttonProperties,\n },\n ['title'],\n ),\n 'aria-setsize': props.legends.length,\n 'aria-posinset': index + 1,\n }), */\n title: legend.title,\n action: legend.action!,\n hoverAction: legend.hoverAction!,\n onMouseOutAction: legend.onMouseOutAction!,\n color: legend.color,\n shape: shape ? shape : legend.shape,\n stripePattern: legend.stripePattern,\n isLineLegendInBarChart: legend.isLineLegendInBarChart,\n opacity: legend.opacity,\n key: index,\n legendAnnotation: legend.legendAnnotation,\n };\n });\n return dataItems;\n }\n\n /**\n * Determine whether the component is in \"controlled\" mode for selections, where the selected legend(s) are\n * determined entirely by props passed in from the parent component.\n */\n function _isInControlledMode(): boolean {\n return props.canSelectMultipleLegends ? props.selectedLegends !== undefined : props.selectedLegend !== undefined;\n }\n\n /**\n * Get the new selected legends based on the legend that was clicked when multi-select is enabled.\n * @param legend The legend that was clicked\n * @returns An object with the new selected legend(s) state data.\n */\n function _getNewSelectedLegendsForMultiselect(legend: Legend): { [key: string]: boolean } {\n let legendsSelected = { ...selectedLegends };\n if (legendsSelected[legend.title]) {\n // Delete entry for the deselected legend to make\n // the number of keys equal to the number of selected legends\n delete legendsSelected[legend.title];\n } else {\n legendsSelected[legend.title] = true;\n // Clear set if all legends are selected\n if (Object.keys(legendsSelected).length === props.legends.length) {\n legendsSelected = {};\n }\n }\n return legendsSelected;\n }\n\n /**\n * Get the new selected legends based on the legend that was clicked when single-select is enabled.\n * @param legend The legend that was clicked\n * @returns An object with the new selected legend state data.\n */\n function _getNewSelectedLegendsForSingleSelect(legend: Legend): { [key: string]: boolean } {\n return selectedLegends[legend.title] ? {} : { [legend.title]: true };\n }\n\n function _onClick(legend: Legend, event: React.MouseEvent<HTMLButtonElement>): void {\n const { canSelectMultipleLegends = false } = props;\n const nextSelectedLegends = canSelectMultipleLegends\n ? _getNewSelectedLegendsForMultiselect(legend)\n : _getNewSelectedLegendsForSingleSelect(legend);\n\n if (!_isInControlledMode()) {\n setSelectedLegends(nextSelectedLegends);\n }\n props.onChange?.(Object.keys(nextSelectedLegends), event, legend);\n legend.action?.();\n }\n\n function _onHoverOverLegend(legend: Legend) {\n if (legend.hoverAction) {\n setActiveLegend(legend.title);\n legend.hoverAction();\n }\n }\n\n function _onLeave(legend: Legend) {\n if (legend.onMouseOutAction) {\n setActiveLegend('');\n legend.onMouseOutAction();\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function _renderButton(data: any, index?: number, isOverflowItem?: boolean) {\n const { allowFocusOnLegends = true } = props;\n // Overflow legends are rendered inside a menu, not the listbox, so they must not carry `option` semantics.\n const showListboxOption = allowFocusOnLegends && !isOverflowItem;\n const legend: Legend = {\n title: data.title,\n color: data.color,\n shape: data.shape,\n action: data.action,\n hoverAction: data.hoverAction,\n onMouseOutAction: data.onMouseOutAction,\n stripePattern: data.stripePattern,\n isLineLegendInBarChart: data.isLineLegendInBarChart,\n opacity: data.opacity,\n };\n const color = _getColor(legend.title, legend.color);\n const onClickHandler = (event: React.MouseEvent<HTMLElement>) => {\n _onClick(legend, event as React.MouseEvent<HTMLButtonElement>);\n };\n const onHoverHandler = () => {\n _onHoverOverLegend(legend);\n };\n const onMouseOut = () => {\n _onLeave(legend);\n };\n const shape = _getShape(legend, color);\n const legendStyle = {\n '--rect-height': legend.isLineLegendInBarChart ? '4px' : '12px',\n '--rect-backgroundColor': legend.stripePattern ? '' : color,\n '--rect-borderColor': legend.color ? legend.color : tokens.colorNeutralStroke1,\n '--rect-content': legend.stripePattern\n ? `repeating-linear-gradient(135deg, transparent, transparent 3px, ${color} 1px, ${color} 4px)`\n : '',\n } as React.CSSProperties;\n const legendContent = (\n <>\n {shape}\n <div className={classes.text} style={{ opacity: color === tokens.colorNeutralBackground1 ? '0.67' : '' }}>\n {legend.title}\n </div>\n </>\n );\n // Shared by the listbox Button and the overflow div. Hover/focus handlers are included so the overflow\n // menu can forward them to its item (the div itself never receives focus).\n const commonProps: React.HTMLAttributes<HTMLElement> = {\n className: classes.legend,\n onClick: onClickHandler,\n onMouseOver: onHoverHandler,\n onMouseOut: onMouseOut,\n onFocus: onHoverHandler,\n onBlur: onMouseOut,\n style: legendStyle,\n };\n if (isOverflowItem) {\n // In the overflow menu the item itself is interactive, so keep this content a non-interactive div to\n // avoid nested clickable elements. display:flex lays the swatch and label out inline (a bare div would\n // stack them). data-selected / data-title are read by the overflow menu to drive its checked state.\n return (\n <div\n key={index}\n {...commonProps}\n data-selected={!!selectedLegends[legend.title]}\n data-title={legend.title}\n style={{ ...legendStyle, display: 'flex', alignItems: 'center' }}\n >\n {legendContent}\n </div>\n );\n }\n return (\n <Button\n {...(showListboxOption && {\n 'aria-selected': !!selectedLegends[legend.title],\n role: 'option',\n 'aria-label': `${legend.title}`,\n // Full-list position so counts match the overflow menu.\n 'aria-setsize': props.legends.length,\n 'aria-posinset': (index ?? 0) + 1,\n })}\n {...(data.nativeButtonProps && { ...data.nativeButtonProps })}\n key={index}\n {...commonProps}\n appearance={'outline'}\n size=\"small\"\n >\n {legendContent}\n </Button>\n );\n }\n\n function _getShape(legend: Legend, color: string): React.ReactNode | string {\n const svgParentProps: React.SVGAttributes<SVGElement> = {\n className: classes.shape,\n };\n const svgChildProps: React.SVGAttributes<SVGElement> = {\n fill: color,\n strokeWidth: 2,\n stroke: legend.color,\n };\n return (\n <Shape\n svgProps={svgParentProps}\n pathProps={svgChildProps}\n shape={legend.shape as LegendShape}\n classNameForNonSvg={classes.rect}\n style={\n {\n height: legend.isLineLegendInBarChart ? '4px' : '12px',\n backgroundColor: legend.stripePattern ? '' : color,\n borderColor: legend.color ? legend.color : tokens.colorNeutralStroke1,\n content: legend.stripePattern\n ? `repeating-linear-gradient(135deg, transparent, transparent 3px, ${color} 1px, ${color} 4px)`\n : '',\n '--rect-content-high-contrast': `linear-gradient(to right, ${color}, ${color})`,\n '--rect-opacity-high-contrast': color === tokens.colorNeutralBackground1 ? '0.6' : '',\n } as React.CSSProperties\n }\n />\n );\n }\n\n function _getColor(title: string, color: string): string {\n let legendColor = color;\n // if one or more legends are selected\n if (_isLegendSelected) {\n // if the given legend (title) is one of the selected legends\n if (selectedLegends[title]) {\n legendColor = color;\n }\n // if the given legend is unselected\n else {\n legendColor = tokens.colorNeutralBackground1;\n }\n }\n // if no legend is selected\n else {\n // if the given legend is hovered\n // or none of the legends is hovered\n if (activeLegend === title || activeLegend === '') {\n legendColor = color;\n }\n // if there is a hovered legend but the given legend is not the one\n else {\n legendColor = tokens.colorNeutralBackground1;\n }\n }\n return legendColor;\n }\n },\n);\nLegends.displayName = 'Legends';\n"],"names":["React","Button","Shape","useLegendStyles","Overflow","OverflowItem","useFocusableGroup","useArrowNavigationGroup","OverflowMenu","tokens","cloneLegendsToSVG","mergeClasses","Legends","forwardRef","props","forwardedRef","_isLegendSelected","_rootElem","useRef","activeLegend","setActiveLegend","useState","selectedLegends","setSelectedLegends","focusAttributes","arrowAttributes","axis","memorizeCurrent","classes","toSVG","useCallback","svgWidth","isRTL","legends","centerLegends","textClassName","text","current","useImperativeHandle","legendRef","useEffect","initialSelectedLegends","defaultSelectedLegends","initialSelectedLegend","selectedLegend","defaultSelectedLegend","selectedLegendsState","canSelectMultipleLegends","reduce","combineDict","key","undefined","Object","keys","length","dataToRender","_generateData","overflowStyles","allowFocusOnLegends","itemIds","map","_item","index","toString","overflowHoverCardLegends","legend","hoverCardElement","_renderButton","push","overflowString","overflowText","enabledWrapLines","renderWrappedLegends","renderLegends","div","className","root","ref","resizableArea","style","textAlign","role","display","item","id","title","items","justifyContent","flexWrap","overflow","legendContainer","legendAnnotation","annotation","shape","dataItems","action","hoverAction","onMouseOutAction","color","stripePattern","isLineLegendInBarChart","opacity","_isInControlledMode","_getNewSelectedLegendsForMultiselect","legendsSelected","_getNewSelectedLegendsForSingleSelect","_onClick","event","nextSelectedLegends","onChange","_onHoverOverLegend","_onLeave","data","isOverflowItem","showListboxOption","_getColor","onClickHandler","onHoverHandler","onMouseOut","_getShape","legendStyle","colorNeutralStroke1","legendContent","colorNeutralBackground1","commonProps","onClick","onMouseOver","onFocus","onBlur","data-selected","data-title","alignItems","nativeButtonProps","appearance","size","svgParentProps","svgChildProps","fill","strokeWidth","stroke","svgProps","pathProps","classNameForNonSvg","rect","height","backgroundColor","borderColor","content","legendColor","displayName"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import * as React from 'react';
3
- import { Menu, MenuTrigger, MenuPopover, MenuList, MenuItem } from '@fluentui/react-menu';
3
+ import { Menu, MenuTrigger, MenuPopover, MenuList, MenuItemCheckbox } from '@fluentui/react-menu';
4
4
  import { MenuButton } from '@fluentui/react-button';
5
5
  import { useOverflowMenu } from '@fluentui/react-overflow';
6
6
  export const OverflowMenu = ({ itemIds, title, items })=>{
@@ -11,23 +11,61 @@ export const OverflowMenu = ({ itemIds, title, items })=>{
11
11
  return null;
12
12
  }
13
13
  const remainingItemsCount = itemIds.length - overflowCount;
14
+ const checkedLegends = [];
14
15
  const menuList = [];
15
16
  for(let i = remainingItemsCount; i < itemIds.length; i++){
16
17
  const buttonElement = items[i];
17
- menuList.push(/*#__PURE__*/ React.createElement(MenuItem, {
18
- tabIndex: -1,
18
+ var _buttonElement_props_datatitle;
19
+ const value = `${(_buttonElement_props_datatitle = buttonElement.props['data-title']) !== null && _buttonElement_props_datatitle !== void 0 ? _buttonElement_props_datatitle : i}`;
20
+ if (buttonElement.props['data-selected']) {
21
+ checkedLegends.push(value);
22
+ }
23
+ menuList.push(/*#__PURE__*/ React.createElement(MenuItemCheckbox, {
19
24
  key: i,
25
+ name: "legends",
26
+ value: value,
27
+ // Full-list position so counts match the listbox.
28
+ "aria-setsize": itemIds.length,
29
+ "aria-posinset": i + 1,
30
+ // Hide the checkmark so the row matches the listbox legend; selection is conveyed via aria-checked.
31
+ checkmark: null,
20
32
  onClick: (e)=>{
21
- const button = buttonElement.props;
22
- if (button.onClick) {
23
- button.onClick(e);
24
- }
33
+ var _buttonElement_props_onClick, _buttonElement_props;
34
+ return (_buttonElement_props_onClick = (_buttonElement_props = buttonElement.props).onClick) === null || _buttonElement_props_onClick === void 0 ? void 0 : _buttonElement_props_onClick.call(_buttonElement_props, e);
35
+ },
36
+ // The content is smaller than the row, so handle hover/focus on the item to cover its full area.
37
+ onMouseEnter: ()=>{
38
+ var _buttonElement_props_onMouseOver, _buttonElement_props;
39
+ return (_buttonElement_props_onMouseOver = (_buttonElement_props = buttonElement.props).onMouseOver) === null || _buttonElement_props_onMouseOver === void 0 ? void 0 : _buttonElement_props_onMouseOver.call(_buttonElement_props);
40
+ },
41
+ onMouseLeave: ()=>{
42
+ var _buttonElement_props_onMouseOut, _buttonElement_props;
43
+ return (_buttonElement_props_onMouseOut = (_buttonElement_props = buttonElement.props).onMouseOut) === null || _buttonElement_props_onMouseOut === void 0 ? void 0 : _buttonElement_props_onMouseOut.call(_buttonElement_props);
44
+ },
45
+ onFocus: ()=>{
46
+ var _buttonElement_props_onFocus, _buttonElement_props;
47
+ return (_buttonElement_props_onFocus = (_buttonElement_props = buttonElement.props).onFocus) === null || _buttonElement_props_onFocus === void 0 ? void 0 : _buttonElement_props_onFocus.call(_buttonElement_props);
48
+ },
49
+ onBlur: ()=>{
50
+ var _buttonElement_props_onBlur, _buttonElement_props;
51
+ return (_buttonElement_props_onBlur = (_buttonElement_props = buttonElement.props).onBlur) === null || _buttonElement_props_onBlur === void 0 ? void 0 : _buttonElement_props_onBlur.call(_buttonElement_props);
25
52
  }
26
- }, buttonElement));
53
+ }, /*#__PURE__*/ React.cloneElement(buttonElement, {
54
+ onClick: undefined,
55
+ onMouseOver: undefined,
56
+ onMouseOut: undefined,
57
+ onFocus: undefined,
58
+ onBlur: undefined
59
+ })));
27
60
  }
28
61
  return /*#__PURE__*/ React.createElement(Menu, null, /*#__PURE__*/ React.createElement(MenuTrigger, {
29
62
  disableButtonEnhancement: true
30
63
  }, /*#__PURE__*/ React.createElement(MenuButton, {
31
64
  ref: ref
32
- }, displayLabel)), /*#__PURE__*/ React.createElement(MenuPopover, null, /*#__PURE__*/ React.createElement(MenuList, null, menuList)));
65
+ }, displayLabel)), /*#__PURE__*/ React.createElement(MenuPopover, null, /*#__PURE__*/ React.createElement(MenuList, {
66
+ "aria-label": "Legends",
67
+ checkedValues: {
68
+ legends: checkedLegends
69
+ }
70
+ }, menuList)));
33
71
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Legends/OverflowMenu.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { JSXElement } from '@fluentui/react-utilities';\nimport { Menu, MenuTrigger, MenuPopover, MenuList, MenuItem } from '@fluentui/react-menu';\nimport { MenuButton } from '@fluentui/react-button';\nimport { useOverflowMenu } from '@fluentui/react-overflow';\n\nexport const OverflowMenu: React.FC<{\n itemIds: string[];\n title: string;\n items: JSXElement[];\n}> = ({ itemIds, title, items }) => {\n const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();\n let displayLabel = title;\n displayLabel = title === '' ? `+${overflowCount} items` : `+${overflowCount} ${title}`;\n\n if (!isOverflowing) {\n return null;\n }\n const remainingItemsCount = itemIds.length - overflowCount;\n const menuList = [];\n for (let i = remainingItemsCount; i < itemIds.length; i++) {\n const buttonElement = items[i];\n menuList.push(\n <MenuItem\n tabIndex={-1}\n key={i}\n onClick={e => {\n const button = buttonElement.props;\n if (button.onClick) {\n button.onClick(e);\n }\n }}\n >\n {buttonElement}\n </MenuItem>,\n );\n }\n return (\n <Menu>\n <MenuTrigger disableButtonEnhancement>\n <MenuButton ref={ref}>{displayLabel}</MenuButton>\n </MenuTrigger>\n\n <MenuPopover>\n <MenuList>{menuList}</MenuList>\n </MenuPopover>\n </Menu>\n );\n};\n"],"names":["React","Menu","MenuTrigger","MenuPopover","MenuList","MenuItem","MenuButton","useOverflowMenu","OverflowMenu","itemIds","title","items","ref","overflowCount","isOverflowing","displayLabel","remainingItemsCount","length","menuList","i","buttonElement","push","tabIndex","key","onClick","e","button","props","disableButtonEnhancement"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,IAAI,EAAEC,WAAW,EAAEC,WAAW,EAAEC,QAAQ,EAAEC,QAAQ,QAAQ,uBAAuB;AAC1F,SAASC,UAAU,QAAQ,yBAAyB;AACpD,SAASC,eAAe,QAAQ,2BAA2B;AAE3D,OAAO,MAAMC,eAIR,CAAC,EAAEC,OAAO,EAAEC,KAAK,EAAEC,KAAK,EAAE;IAC7B,MAAM,EAAEC,GAAG,EAAEC,aAAa,EAAEC,aAAa,EAAE,GAAGP;IAC9C,IAAIQ,eAAeL;IACnBK,eAAeL,UAAU,KAAK,CAAC,CAAC,EAAEG,cAAc,MAAM,CAAC,GAAG,CAAC,CAAC,EAAEA,cAAc,CAAC,EAAEH,OAAO;IAEtF,IAAI,CAACI,eAAe;QAClB,OAAO;IACT;IACA,MAAME,sBAAsBP,QAAQQ,MAAM,GAAGJ;IAC7C,MAAMK,WAAW,EAAE;IACnB,IAAK,IAAIC,IAAIH,qBAAqBG,IAAIV,QAAQQ,MAAM,EAAEE,IAAK;QACzD,MAAMC,gBAAgBT,KAAK,CAACQ,EAAE;QAC9BD,SAASG,IAAI,eACX,oBAAChB;YACCiB,UAAU,CAAC;YACXC,KAAKJ;YACLK,SAASC,CAAAA;gBACP,MAAMC,SAASN,cAAcO,KAAK;gBAClC,IAAID,OAAOF,OAAO,EAAE;oBAClBE,OAAOF,OAAO,CAACC;gBACjB;YACF;WAECL;IAGP;IACA,qBACE,oBAACnB,0BACC,oBAACC;QAAY0B,0BAAAA;qBACX,oBAACtB;QAAWM,KAAKA;OAAMG,8BAGzB,oBAACZ,iCACC,oBAACC,gBAAUc;AAInB,EAAE"}
1
+ {"version":3,"sources":["../src/components/Legends/OverflowMenu.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { JSXElement } from '@fluentui/react-utilities';\nimport { Menu, MenuTrigger, MenuPopover, MenuList, MenuItemCheckbox } from '@fluentui/react-menu';\nimport { MenuButton } from '@fluentui/react-button';\nimport { useOverflowMenu } from '@fluentui/react-overflow';\n\nexport const OverflowMenu: React.FC<{\n itemIds: string[];\n title: string;\n items: JSXElement[];\n}> = ({ itemIds, title, items }) => {\n const { ref, overflowCount, isOverflowing } = useOverflowMenu<HTMLButtonElement>();\n let displayLabel = title;\n displayLabel = title === '' ? `+${overflowCount} items` : `+${overflowCount} ${title}`;\n\n if (!isOverflowing) {\n return null;\n }\n const remainingItemsCount = itemIds.length - overflowCount;\n const checkedLegends: string[] = [];\n const menuList = [];\n for (let i = remainingItemsCount; i < itemIds.length; i++) {\n const buttonElement = items[i];\n const value = `${buttonElement.props['data-title'] ?? i}`;\n if (buttonElement.props['data-selected']) {\n checkedLegends.push(value);\n }\n menuList.push(\n <MenuItemCheckbox\n key={i}\n name=\"legends\"\n value={value}\n // Full-list position so counts match the listbox.\n aria-setsize={itemIds.length}\n aria-posinset={i + 1}\n // Hide the checkmark so the row matches the listbox legend; selection is conveyed via aria-checked.\n checkmark={null}\n onClick={e => buttonElement.props.onClick?.(e)}\n // The content is smaller than the row, so handle hover/focus on the item to cover its full area.\n onMouseEnter={() => buttonElement.props.onMouseOver?.()}\n onMouseLeave={() => buttonElement.props.onMouseOut?.()}\n onFocus={() => buttonElement.props.onFocus?.()}\n onBlur={() => buttonElement.props.onBlur?.()}\n >\n {React.cloneElement(buttonElement, {\n onClick: undefined,\n onMouseOver: undefined,\n onMouseOut: undefined,\n onFocus: undefined,\n onBlur: undefined,\n })}\n </MenuItemCheckbox>,\n );\n }\n return (\n <Menu>\n <MenuTrigger disableButtonEnhancement>\n <MenuButton ref={ref}>{displayLabel}</MenuButton>\n </MenuTrigger>\n\n <MenuPopover>\n <MenuList aria-label=\"Legends\" checkedValues={{ legends: checkedLegends }}>\n {menuList}\n </MenuList>\n </MenuPopover>\n </Menu>\n );\n};\n"],"names":["React","Menu","MenuTrigger","MenuPopover","MenuList","MenuItemCheckbox","MenuButton","useOverflowMenu","OverflowMenu","itemIds","title","items","ref","overflowCount","isOverflowing","displayLabel","remainingItemsCount","length","checkedLegends","menuList","i","buttonElement","value","props","push","key","name","aria-setsize","aria-posinset","checkmark","onClick","e","onMouseEnter","onMouseOver","onMouseLeave","onMouseOut","onFocus","onBlur","cloneElement","undefined","disableButtonEnhancement","aria-label","checkedValues","legends"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,IAAI,EAAEC,WAAW,EAAEC,WAAW,EAAEC,QAAQ,EAAEC,gBAAgB,QAAQ,uBAAuB;AAClG,SAASC,UAAU,QAAQ,yBAAyB;AACpD,SAASC,eAAe,QAAQ,2BAA2B;AAE3D,OAAO,MAAMC,eAIR,CAAC,EAAEC,OAAO,EAAEC,KAAK,EAAEC,KAAK,EAAE;IAC7B,MAAM,EAAEC,GAAG,EAAEC,aAAa,EAAEC,aAAa,EAAE,GAAGP;IAC9C,IAAIQ,eAAeL;IACnBK,eAAeL,UAAU,KAAK,CAAC,CAAC,EAAEG,cAAc,MAAM,CAAC,GAAG,CAAC,CAAC,EAAEA,cAAc,CAAC,EAAEH,OAAO;IAEtF,IAAI,CAACI,eAAe;QAClB,OAAO;IACT;IACA,MAAME,sBAAsBP,QAAQQ,MAAM,GAAGJ;IAC7C,MAAMK,iBAA2B,EAAE;IACnC,MAAMC,WAAW,EAAE;IACnB,IAAK,IAAIC,IAAIJ,qBAAqBI,IAAIX,QAAQQ,MAAM,EAAEG,IAAK;QACzD,MAAMC,gBAAgBV,KAAK,CAACS,EAAE;YACbC;QAAjB,MAAMC,QAAQ,GAAGD,CAAAA,iCAAAA,cAAcE,KAAK,CAAC,aAAa,cAAjCF,4CAAAA,iCAAqCD,GAAG;QACzD,IAAIC,cAAcE,KAAK,CAAC,gBAAgB,EAAE;YACxCL,eAAeM,IAAI,CAACF;QACtB;QACAH,SAASK,IAAI,eACX,oBAACnB;YACCoB,KAAKL;YACLM,MAAK;YACLJ,OAAOA;YACP,kDAAkD;YAClDK,gBAAclB,QAAQQ,MAAM;YAC5BW,iBAAeR,IAAI;YACnB,oGAAoG;YACpGS,WAAW;YACXC,SAASC,CAAAA;oBAAKV,8BAAAA;wBAAAA,+BAAAA,CAAAA,uBAAAA,cAAcE,KAAK,EAACO,OAAO,cAA3BT,mDAAAA,kCAAAA,sBAA8BU;;YAC5C,iGAAiG;YACjGC,cAAc;oBAAMX,kCAAAA;wBAAAA,mCAAAA,CAAAA,uBAAAA,cAAcE,KAAK,EAACU,WAAW,cAA/BZ,uDAAAA,sCAAAA;;YACpBa,cAAc;oBAAMb,iCAAAA;wBAAAA,kCAAAA,CAAAA,uBAAAA,cAAcE,KAAK,EAACY,UAAU,cAA9Bd,sDAAAA,qCAAAA;;YACpBe,SAAS;oBAAMf,8BAAAA;wBAAAA,+BAAAA,CAAAA,uBAAAA,cAAcE,KAAK,EAACa,OAAO,cAA3Bf,mDAAAA,kCAAAA;;YACfgB,QAAQ;oBAAMhB,6BAAAA;wBAAAA,8BAAAA,CAAAA,uBAAAA,cAAcE,KAAK,EAACc,MAAM,cAA1BhB,kDAAAA,iCAAAA;;yBAEbrB,MAAMsC,YAAY,CAACjB,eAAe;YACjCS,SAASS;YACTN,aAAaM;YACbJ,YAAYI;YACZH,SAASG;YACTF,QAAQE;QACV;IAGN;IACA,qBACE,oBAACtC,0BACC,oBAACC;QAAYsC,0BAAAA;qBACX,oBAAClC;QAAWM,KAAKA;OAAMG,8BAGzB,oBAACZ,iCACC,oBAACC;QAASqC,cAAW;QAAUC,eAAe;YAAEC,SAASzB;QAAe;OACrEC;AAKX,EAAE"}
@@ -626,7 +626,8 @@ export const SankeyChart = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=
626
626
  const target = singleLink.target;
627
627
  // TODO: localize the aria-label string
628
628
  return /*#__PURE__*/ React.createElement("g", {
629
- key: key
629
+ key: key,
630
+ role: "presentation"
630
631
  }, /*#__PURE__*/ React.createElement("defs", null, /*#__PURE__*/ React.createElement("linearGradient", {
631
632
  id: gradientId,
632
633
  x1: "0%",
@@ -653,7 +654,7 @@ export const SankeyChart = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=
653
654
  fillOpacity: _getOpacityStream(singleLink),
654
655
  tabIndex: 0,
655
656
  "aria-label": aria,
656
- role: "img"
657
+ role: "option"
657
658
  }));
658
659
  });
659
660
  }
@@ -676,7 +677,8 @@ export const SankeyChart = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=
676
677
  }, singleNode);
677
678
  return /*#__PURE__*/ React.createElement("g", {
678
679
  key: index,
679
- id: gElementId
680
+ id: gElementId,
681
+ role: "presentation"
680
682
  }, /*#__PURE__*/ React.createElement("rect", {
681
683
  x: x0,
682
684
  y: y0,
@@ -692,7 +694,7 @@ export const SankeyChart = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=
692
694
  opacity: "1",
693
695
  tabIndex: 0,
694
696
  "aria-label": aria,
695
- role: "img"
697
+ role: "option"
696
698
  }), height > MIN_HEIGHT_FOR_TYPE && /*#__PURE__*/ React.createElement("g", {
697
699
  className: classes.nodeTextContainer
698
700
  }, /*#__PURE__*/ React.createElement("g", {
@@ -983,7 +985,9 @@ export const SankeyChart = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=
983
985
  width: width,
984
986
  height: height,
985
987
  id: _chartId,
986
- className: classes.chart
988
+ className: classes.chart,
989
+ role: "listbox",
990
+ "aria-label": `Sankey chart with ${nodes.length} nodes and ${links.length} links`
987
991
  }, !props.hideLegend && props.data.chartTitle && /*#__PURE__*/ React.createElement(ChartTitle, {
988
992
  title: props.data.chartTitle,
989
993
  x: width / 2,
@@ -995,14 +999,16 @@ export const SankeyChart = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=
995
999
  if (item.type === 'node') {
996
1000
  return /*#__PURE__*/ React.createElement("g", {
997
1001
  key: nodes[item.index].nodeId,
998
- className: classes.nodes
1002
+ className: classes.nodes,
1003
+ role: "presentation"
999
1004
  }, nodeData[item.index]);
1000
1005
  } else {
1001
1006
  return /*#__PURE__*/ React.createElement("g", {
1002
1007
  key: `${links[item.index].source.nodeId}-${links[item.index].target.nodeId}`,
1003
1008
  className: classes.links,
1004
1009
  stroke: props.pathColor ? props.pathColor : tokens.colorStrokeFocus2,
1005
- strokeOpacity: 1
1010
+ strokeOpacity: 1,
1011
+ role: "presentation"
1006
1012
  }, linkData[item.index]);
1007
1013
  }
1008
1014
  }))), calloutProps.isPopoverOpen && /*#__PURE__*/ React.createElement(ChartPopover, calloutProps), /*#__PURE__*/ React.createElement("div", {