@fluentui/react-charts 9.3.21 → 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 (74) hide show
  1. package/CHANGELOG.md +25 -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/GroupedVerticalBarChart/GroupedVerticalBarChart.js +9 -3
  13. package/lib/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js.map +1 -1
  14. package/lib/components/HeatMapChart/HeatMapChart.js +8 -3
  15. package/lib/components/HeatMapChart/HeatMapChart.js.map +1 -1
  16. package/lib/components/HorizontalBarChart/HorizontalBarChart.js +8 -5
  17. package/lib/components/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
  18. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js +2 -2
  19. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js.map +1 -1
  20. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js +1 -1
  21. package/lib/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js.map +1 -1
  22. package/lib/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js +17 -5
  23. package/lib/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js.map +1 -1
  24. package/lib/components/Legends/Legends.js +62 -32
  25. package/lib/components/Legends/Legends.js.map +1 -1
  26. package/lib/components/Legends/OverflowMenu.js +47 -9
  27. package/lib/components/Legends/OverflowMenu.js.map +1 -1
  28. package/lib/components/SankeyChart/SankeyChart.js +13 -7
  29. package/lib/components/SankeyChart/SankeyChart.js.map +1 -1
  30. package/lib/components/ScatterChart/ScatterChart.js +3 -3
  31. package/lib/components/ScatterChart/ScatterChart.js.map +1 -1
  32. package/lib/components/VerticalBarChart/VerticalBarChart.js +19 -7
  33. package/lib/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  34. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js +16 -10
  35. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  36. package/lib/utilities/utilities.js +2 -2
  37. package/lib/utilities/utilities.js.map +1 -1
  38. package/lib-commonjs/components/DonutChart/Arc/Arc.js +3 -2
  39. package/lib-commonjs/components/DonutChart/Arc/Arc.js.map +1 -1
  40. package/lib-commonjs/components/DonutChart/Pie/Pie.js +3 -1
  41. package/lib-commonjs/components/DonutChart/Pie/Pie.js.map +1 -1
  42. package/lib-commonjs/components/FunnelChart/FunnelChart.js +14 -3
  43. package/lib-commonjs/components/FunnelChart/FunnelChart.js.map +1 -1
  44. package/lib-commonjs/components/GanttChart/GanttChart.js +5 -2
  45. package/lib-commonjs/components/GanttChart/GanttChart.js.map +1 -1
  46. package/lib-commonjs/components/GaugeChart/GaugeChart.js +6 -3
  47. package/lib-commonjs/components/GaugeChart/GaugeChart.js.map +1 -1
  48. package/lib-commonjs/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js +9 -3
  49. package/lib-commonjs/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js.map +1 -1
  50. package/lib-commonjs/components/HeatMapChart/HeatMapChart.js +8 -3
  51. package/lib-commonjs/components/HeatMapChart/HeatMapChart.js.map +1 -1
  52. package/lib-commonjs/components/HorizontalBarChart/HorizontalBarChart.js +8 -5
  53. package/lib-commonjs/components/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
  54. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js +4 -4
  55. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.js.map +1 -1
  56. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js +1 -1
  57. package/lib-commonjs/components/HorizontalBarChart/useHorizontalBarChartStyles.styles.raw.js.map +1 -1
  58. package/lib-commonjs/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js +17 -5
  59. package/lib-commonjs/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js.map +1 -1
  60. package/lib-commonjs/components/Legends/Legends.js +62 -32
  61. package/lib-commonjs/components/Legends/Legends.js.map +1 -1
  62. package/lib-commonjs/components/Legends/OverflowMenu.js +46 -8
  63. package/lib-commonjs/components/Legends/OverflowMenu.js.map +1 -1
  64. package/lib-commonjs/components/SankeyChart/SankeyChart.js +13 -7
  65. package/lib-commonjs/components/SankeyChart/SankeyChart.js.map +1 -1
  66. package/lib-commonjs/components/ScatterChart/ScatterChart.js +3 -3
  67. package/lib-commonjs/components/ScatterChart/ScatterChart.js.map +1 -1
  68. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js +19 -7
  69. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  70. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js +16 -10
  71. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  72. package/lib-commonjs/utilities/utilities.js +2 -2
  73. package/lib-commonjs/utilities/utilities.js.map +1 -1
  74. package/package.json +4 -4
@@ -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", {