@persona/design-system 0.10.12 → 0.10.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/dist/{CheckboxGroupField-XSVAmESI.d.mts → CheckboxGroupField-tBvP22Bo.d.mts} +2 -2
- package/dist/CheckboxGroupField.d.mts +1 -1
- package/dist/{Combobox-BNjYEAmv.mjs → Combobox-DmFQ5cAy.mjs} +63 -51
- package/dist/Combobox-DmFQ5cAy.mjs.map +1 -0
- package/dist/{Combobox-DbcSss15.d.mts → Combobox-RX4DfO5L.d.mts} +3 -3
- package/dist/Combobox.d.mts +2 -2
- package/dist/{ComboboxBase-CrFweFGi.d.mts → ComboboxBase-VIGR58Uc.d.mts} +2 -2
- package/dist/ComboboxBase.d.mts +1 -1
- package/dist/{ComboboxMultiSelect-Cp5GBGQj.d.mts → ComboboxMultiSelect-D5TWGGKZ.d.mts} +2 -2
- package/dist/ComboboxMultiSelect.d.mts +1 -1
- package/dist/{ComboboxSingleSelect-u7fK3Yvy.d.mts → ComboboxSingleSelect-D9It8t6W.d.mts} +3 -3
- package/dist/ComboboxSingleSelect.d.mts +1 -1
- package/dist/{CompactBar-BLZZWtIE.d.mts → CompactBar-tNtY2EhN.d.mts} +2 -2
- package/dist/CompactBar.d.mts +1 -1
- package/dist/{ControlBar-B3Jn8G0k.d.mts → ControlBar-CDb6b1_6.d.mts} +5 -3
- package/dist/ControlBar.d.mts +1 -1
- package/dist/{DataTable-C1mdfmQa.d.mts → DataTable-0nhT5_Fe.d.mts} +31 -7
- package/dist/{DataTable-DdSY9mzT.mjs → DataTable-6t5ryaEq.mjs} +146 -77
- package/dist/DataTable-6t5ryaEq.mjs.map +1 -0
- package/dist/DataTable.d.mts +1 -1
- package/dist/{DatePicker-DiilpYQg.mjs → DatePicker-CHVYVKB-.mjs} +2 -2
- package/dist/{DatePicker-DiilpYQg.mjs.map → DatePicker-CHVYVKB-.mjs.map} +1 -1
- package/dist/DropdownButton.d.mts +1 -1
- package/dist/{DropdownMenu-CQR0U-zM.d.mts → DropdownMenu-Db6N6ZNB.d.mts} +2 -2
- package/dist/DropdownMenu.d.mts +1 -1
- package/dist/{FloatingActionBar-BUgSKimy.d.mts → FloatingActionBar-CfgjHs81.d.mts} +5 -1
- package/dist/FloatingActionBar.d.mts +1 -1
- package/dist/{FormField-yYJFkJ6R.mjs → FormField-BfVrDOY0.mjs} +4 -4
- package/dist/{FormField-yYJFkJ6R.mjs.map → FormField-BfVrDOY0.mjs.map} +1 -1
- package/dist/{HoverCopyableField-X2XfKTTh.mjs → HoverCopyableField-CJ_p3llp.mjs} +2 -2
- package/dist/{HoverCopyableField-X2XfKTTh.mjs.map → HoverCopyableField-CJ_p3llp.mjs.map} +1 -1
- package/dist/IndexTableLayout.d.mts +3 -3
- package/dist/InlineCombobox.d.mts +1 -1
- package/dist/InlineInput.d.mts +1 -1
- package/dist/{Link-B29ZMN6m.mjs → Link-Df3zJrj2.mjs} +1 -1
- package/dist/{Link-B29ZMN6m.mjs.map → Link-Df3zJrj2.mjs.map} +1 -1
- package/dist/{ListBox-4rTgr3IJ.mjs → ListBox-BRgjgUSp.mjs} +2 -2
- package/dist/{ListBox-4rTgr3IJ.mjs.map → ListBox-BRgjgUSp.mjs.map} +1 -1
- package/dist/{ListBox-ZDaitaXR.d.mts → ListBox-l47zUDj4.d.mts} +2 -2
- package/dist/ListBox.d.mts +1 -1
- package/dist/{ListBoxField-CGvVWKyL.d.mts → ListBoxField-Di_6uD3S.d.mts} +4 -4
- package/dist/ListBoxField.d.mts +1 -1
- package/dist/{LogicRow-Bzp5o1sL.d.mts → LogicRow-7f17CKrW.d.mts} +2 -2
- package/dist/LogicRow.d.mts +1 -1
- package/dist/MaskedInput.d.mts +1 -1
- package/dist/{Menu-DviYNrFd.d.mts → Menu-DvzoR8e7.d.mts} +2 -2
- package/dist/Menu.d.mts +1 -1
- package/dist/{Modal-CiPFqr0L.mjs → Modal-C_vSgqgl.mjs} +20 -16
- package/dist/Modal-C_vSgqgl.mjs.map +1 -0
- package/dist/{Modal-CujB7DuB.d.mts → Modal-IVXc4p8Y.d.mts} +7 -2
- package/dist/Modal.d.mts +1 -1
- package/dist/{Pii-jSYND7Cn.mjs → Pii-BYPkrBuT.mjs} +1 -1
- package/dist/{Pii-jSYND7Cn.mjs.map → Pii-BYPkrBuT.mjs.map} +1 -1
- package/dist/{Popover-CVX-dfYb.mjs → Popover-DP9DXReH.mjs} +1 -1
- package/dist/{Popover-CVX-dfYb.mjs.map → Popover-DP9DXReH.mjs.map} +1 -1
- package/dist/{Select-DsVeAyZy.d.mts → Select-boZ6XP8k.d.mts} +2 -2
- package/dist/Select.d.mts +1 -1
- package/dist/SmartTextInputField.d.mts +2 -2
- package/dist/SmartTextInputListbox.d.mts +8 -3
- package/dist/{TableBox-D9NA-s9l.mjs → TableBox-RxpwflEb.mjs} +3 -3
- package/dist/{TableBox-D9NA-s9l.mjs.map → TableBox-RxpwflEb.mjs.map} +1 -1
- package/dist/TableBox.d.mts +1 -1
- package/dist/{TableBoxCell-CQOL30et.d.mts → TableBoxCell-B6Z23mby.d.mts} +4 -4
- package/dist/TableBoxCell.d.mts +1 -1
- package/dist/{TableBoxField-z0GIFeQw.d.mts → TableBoxField-6qAOW8t9.d.mts} +5 -5
- package/dist/TableBoxField.d.mts +1 -1
- package/dist/{TableBoxRow-tb9-KMr9.d.mts → TableBoxRow-CpgNWdLS.d.mts} +2 -2
- package/dist/TableBoxRow.d.mts +1 -1
- package/dist/{TableBoxRowActions-BZwulsFP.d.mts → TableBoxRowActions-BDx5naRj.d.mts} +2 -2
- package/dist/TableBoxRowActions.d.mts +1 -1
- package/dist/{TableControls-DE6eHq8h.d.mts → TableControls-BGKL7_zF.d.mts} +4 -4
- package/dist/{TableControls-BXykbUBf.mjs → TableControls-BwZl4TjJ.mjs} +31 -12
- package/dist/TableControls-BwZl4TjJ.mjs.map +1 -0
- package/dist/TableControls.d.mts +1 -1
- package/dist/{TableControlsContext-C2_2EuMh.d.mts → TableControlsContext-DhABbtVY.d.mts} +2 -2
- package/dist/TableControlsContext.d.mts +1 -1
- package/dist/{TableViewConfigurationDropdown-DE9HFXYY.d.mts → TableViewConfigurationDropdown-D76ApJ_-.d.mts} +2 -2
- package/dist/TableViewConfigurationDropdown.d.mts +1 -1
- package/dist/WizardModal.d.mts +1 -1
- package/dist/{clientFilterUtils-2TBUC31K.d.mts → clientFilterUtils-WH_Dqtv4.d.mts} +2 -2
- package/dist/clientFilterUtils.d.mts +1 -1
- package/dist/components/Combobox/index.d.mts +4 -4
- package/dist/components/Combobox/index.mjs +1 -1
- package/dist/components/DataTable/TableControls/index.d.mts +7 -7
- package/dist/components/DataTable/TableControls/index.mjs +1 -1
- package/dist/components/DataTable/index.d.mts +6 -6
- package/dist/components/DataTable/index.mjs +1 -1
- package/dist/components/DataTable/types.d.mts +1 -1
- package/dist/components/DatePicker/index.mjs +1 -1
- package/dist/components/DropdownMenu/index.d.mts +1 -1
- package/dist/components/FormField/index.d.mts +4 -4
- package/dist/components/FormField/index.mjs +1 -1
- package/dist/components/HoverCopyableField/index.mjs +1 -1
- package/dist/components/Link/index.mjs +1 -1
- package/dist/components/ListBox/index.d.mts +3 -3
- package/dist/components/ListBox/index.mjs +1 -1
- package/dist/components/Menu/index.d.mts +1 -1
- package/dist/components/Modal/index.d.mts +1 -1
- package/dist/components/Modal/index.mjs +1 -1
- package/dist/components/Pii/index.mjs +1 -1
- package/dist/components/Popover/index.mjs +1 -1
- package/dist/components/RichTextEditor/index.mjs +2 -2
- package/dist/components/Select/index.d.mts +1 -1
- package/dist/components/SmartTextInput/index.mjs +128 -59
- package/dist/components/SmartTextInput/index.mjs.map +1 -1
- package/dist/components/TableBox/index.d.mts +1 -1
- package/dist/components/TableBox/index.mjs +1 -1
- package/dist/components/VersionHistory/index.mjs +1 -1
- package/dist/fieldPickerOptions.d.mts +1 -1
- package/dist/{filters-DW7pqWv3.d.mts → filters-BXtKuft3.d.mts} +2 -2
- package/dist/filters.d.mts +1 -1
- package/dist/{helpers-BTD2kXLs.d.mts → helpers-gpO42h8t.d.mts} +5 -3
- package/dist/helpers.d.mts +1 -1
- package/dist/{index-B4tE0RxY.d.mts → index-bkzLg85W.d.mts} +3 -3
- package/dist/{inputFields-DnBb3NhK.d.mts → inputFields-B7parF2l.d.mts} +4 -4
- package/dist/inputFields.d.mts +1 -1
- package/dist/lib/PDSProvider.d.mts +2 -1
- package/dist/lib/PDSProvider.mjs +8 -3
- package/dist/lib/PDSProvider.mjs.map +1 -1
- package/dist/lib/colorMode.d.mts +18 -7
- package/dist/lib/colorMode.mjs +47 -13
- package/dist/lib/colorMode.mjs.map +1 -1
- package/dist/lib/schemaOptions.mjs +1 -1
- package/dist/lib/schemaOptions.mjs.map +1 -1
- package/dist/patterns/IndexTableLayout/index.mjs +1 -1
- package/dist/patterns/WizardModal/index.mjs +1 -1
- package/dist/{types-NO2GRlM-.d.mts → types-BvaXqjUm.d.mts} +2 -2
- package/dist/{types-Dws2XDz2.d.mts → types-CuH-sUJ2.d.mts} +6 -4
- package/dist/types5.d.mts +1 -1
- package/dist/useColumnConfiguration.d.mts +2 -2
- package/dist/useComboboxFooterAction.d.mts +1 -1
- package/dist/{useTableColumns-tITjHasE.d.mts → useTableColumns-I7StvoRs.d.mts} +17 -2
- package/dist/useTableColumns.d.mts +1 -1
- package/dist/useTruncation.d.mts +1 -1
- package/dist/utils4.d.mts +1 -1
- package/dist/withDisabledReason.d.mts +19 -0
- package/llms.txt +4 -3
- package/package.json +4 -12
- package/skills/ui-authoring/COMPONENTS.md +0 -1
- package/skills/ui-authoring/PATTERNS.md +0 -64
- package/skills/ui-authoring/TOKENS.md +14 -25
- package/dist/ChartFrame.d.mts +0 -61
- package/dist/ChartLegend.d.mts +0 -60
- package/dist/ChartPopover.d.mts +0 -155
- package/dist/Combobox-BNjYEAmv.mjs.map +0 -1
- package/dist/DataTable-DdSY9mzT.mjs.map +0 -1
- package/dist/Modal-CiPFqr0L.mjs.map +0 -1
- package/dist/TableControls-BXykbUBf.mjs.map +0 -1
- package/dist/chartColors.d.mts +0 -92
- package/dist/chartFrameLayout.d.mts +0 -46
- package/dist/components/Chart/index.d.mts +0 -9
- package/dist/components/Chart/index.mjs +0 -680
- package/dist/components/Chart/index.mjs.map +0 -1
- package/dist/useChartColors.d.mts +0 -30
- package/dist/useChartSeriesVisibility.d.mts +0 -22
- package/dist/useChartStyles.d.mts +0 -108
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["Swatch"],"sources":["../../../src/components/Chart/chartColors.ts","../../../src/components/Chart/useChartColors.ts","../../../src/components/Chart/chartFrameLayout.ts","../../../src/components/Chart/ChartFrame.tsx","../../../src/components/Chart/ChartLegend.tsx","../../../src/components/Chart/useChartSeriesVisibility.ts","../../../src/components/Chart/ChartPopover.tsx","../../../src/components/Chart/useChartStyles.ts"],"sourcesContent":["import type { Color } from '@persona/design-tokens';\n\nimport { chartingColors, type MaybeChartingTheme } from '#src/lib/semanticColor';\nimport { chartingDark, type ChartingTokens } from '#src/variables/charting';\n\n/**\n * The charting palettes a chart may use. Each maps to a `ChartingColors` palette from\n * `@persona/design-tokens` (or its dark-mode twin under a PDS colour mode):\n *\n * - `qualitative` → `Qualitative` (12): distinct, unordered series. The default; its order is\n * tuned for accessibility, so series take colours in this order.\n * - `sequentialMono` → `SequentialMono` (8): ordered magnitude in one hue.\n * - `sequentialDivergent` → `SequentialDivergent` (10): values diverging around a midpoint.\n *\n * The legacy `Sequential` and `Categorical` palettes are deliberately not offered.\n *\n * @experimental Part of the in-progress PDS charting components; the API may change.\n */\nexport type ChartPalette = 'qualitative' | 'sequentialMono' | 'sequentialDivergent';\n\n/** @experimental */\nexport const CHART_PALETTE_TOKENS = {\n qualitative: 'Qualitative',\n sequentialMono: 'SequentialMono',\n sequentialDivergent: 'SequentialDivergent',\n} as const satisfies Record<ChartPalette, keyof ChartingTokens>;\n\n/** @experimental */\nexport const DEFAULT_CHART_PALETTE: ChartPalette = 'qualitative';\n\n/** @experimental */\nexport type ChartColorMode = 'light' | 'dark';\n\n/**\n * A colour override for one series: a Persona `Color` token, or a light/dark pair of tokens.\n * `Color` is a string enum, so a raw hex string (`'#3F48FD'`) does not type-check.\n *\n * Wrap overrides in {@link chartColor} so the `pds/semantic-color` lint rule accepts the `Color.*`\n * reference.\n *\n * @experimental\n */\nexport type ChartColor = Color | { readonly light: Color; readonly dark: Color };\n\n/**\n * Marks a series colour override as a deliberate chart colour. It returns its argument unchanged;\n * its job is to type-check the override (Persona tokens only, never hex) and to tell the\n * `pds/semantic-color` lint rule that the `Color.*` inside is intended.\n *\n * ```ts\n * { key: 'fraud', label: 'Fraud', color: chartColor(Color.CoreRed600) }\n * { key: 'fraud', label: 'Fraud', color: chartColor({ light: Color.CoreRed600, dark: Color.CoreRed400 }) }\n * ```\n *\n * @experimental\n */\nexport const chartColor = <C extends ChartColor>(color: C): C => color;\n\n/** One series as far as colour resolution is concerned. @experimental */\nexport interface ChartSeriesColorInput<K extends string = string> {\n key: K;\n color?: ChartColor;\n}\n\n/** @experimental */\nexport interface ResolveSeriesColorsOptions {\n /** Palettes for the active colour mode, e.g. `chartingColors(theme)`. Defaults to light. */\n tokens?: ChartingTokens;\n /** Defaults to `'qualitative'`. */\n palette?: ChartPalette;\n /** Picks the side of a light/dark override pair. Defaults to `'light'`. */\n mode?: ChartColorMode;\n}\n\n/** The ordered colours of `palette` in `tokens`. @experimental */\nexport const chartPaletteColors = (\n tokens: ChartingTokens,\n palette: ChartPalette = DEFAULT_CHART_PALETTE,\n): readonly Color[] => tokens[CHART_PALETTE_TOKENS[palette]];\n\n/** Resolves an override to the single token for `mode`. @experimental */\nexport const resolveChartColor = (color: ChartColor, mode: ChartColorMode): Color =>\n typeof color === 'string' ? color : color[mode];\n\n/** `'dark'` when `theme` carries the dark charting palettes, else `'light'`. @experimental */\nexport const chartColorModeOf = (theme: MaybeChartingTheme | undefined): ChartColorMode =>\n theme?.charting === chartingDark ? 'dark' : 'light';\n\nconst warnedPaletteOverflow = new Set<string>();\n\n/**\n * Assigns each series a colour token, keyed by series key.\n *\n * Series without an override take the palette colour at their own index, so a series keeps its\n * colour when another is hidden or overridden. Past the end of the palette colours repeat and a\n * development warning suggests grouping the extra series (e.g. into \"Other\"): never invent colours.\n *\n * @experimental\n */\nexport function resolveSeriesColors<K extends string>(\n series: readonly ChartSeriesColorInput<K>[],\n { tokens = chartingColors(undefined), palette, mode = 'light' }: ResolveSeriesColorsOptions = {},\n): Record<K, Color> {\n const colors = chartPaletteColors(tokens, palette);\n const resolved = {} as Record<K, Color>;\n\n series.forEach(({ key, color }, index) => {\n resolved[key] = color ? resolveChartColor(color, mode) : colors[index % colors.length];\n });\n\n const overflowKey = `${palette ?? DEFAULT_CHART_PALETTE}:${series.length}`;\n if (\n process.env.NODE_ENV !== 'production' &&\n series.length > colors.length &&\n !warnedPaletteOverflow.has(overflowKey)\n ) {\n warnedPaletteOverflow.add(overflowKey);\n console.warn(\n `[PDS charts] ${series.length} series exceed the ${colors.length}-colour ` +\n `${palette ?? DEFAULT_CHART_PALETTE} palette, so colours repeat. ` +\n 'Group the extra series (for example into \"Other\") instead of adding colours.',\n );\n }\n\n return resolved;\n}\n","import { useCallback, useMemo } from 'react';\nimport { useTheme } from 'styled-components';\n\nimport type { Color } from '@persona/design-tokens';\n\nimport { chartingColors, type MaybeChartingTheme } from '#src/lib/semanticColor';\n\nimport {\n type ChartColorMode,\n chartColorModeOf,\n type ChartPalette,\n chartPaletteColors,\n type ChartSeriesColorInput,\n DEFAULT_CHART_PALETTE,\n resolveSeriesColors,\n} from './chartColors';\n\n/** @experimental */\nexport interface ChartColors {\n /** The colour mode the palettes were read for. */\n mode: ChartColorMode;\n /** The ordered colours of the selected palette for that mode. */\n colors: readonly Color[];\n /** {@link resolveSeriesColors} bound to the selected palette and mode. */\n resolve: <K extends string>(series: readonly ChartSeriesColorInput<K>[]) => Record<K, Color>;\n}\n\n/**\n * The chart colours for the current PDS colour mode. Reads the charting palettes `PDSProvider` /\n * `ColorModeScope` install on the styled-components theme, so charts follow dark mode with no\n * extra setup; without a PDS colour mode it returns the light `ChartingColors`.\n *\n * ```tsx\n * const { resolve } = useChartColors();\n * const colors = resolve([{ key: 'approved' }, { key: 'declined', color: chartColor(Color.CoreRed600) }]);\n * <Bar dataKey='approved' fill={colors.approved} />\n * ```\n *\n * @experimental\n */\nexport function useChartColors(palette: ChartPalette = DEFAULT_CHART_PALETTE): ChartColors {\n const theme = useTheme() as MaybeChartingTheme | undefined;\n const tokens = chartingColors(theme);\n const mode = chartColorModeOf(theme);\n const colors = chartPaletteColors(tokens, palette);\n\n const resolve = useCallback(\n <K extends string>(series: readonly ChartSeriesColorInput<K>[]) =>\n resolveSeriesColors(series, { tokens, palette, mode }),\n [tokens, palette, mode],\n );\n\n return useMemo(() => ({ mode, colors, resolve }), [mode, colors, resolve]);\n}\n","import { createContext, useContext } from 'react';\n\n/**\n * Where a `ChartFrame` places its legend:\n * - `'stack'` (default): left-aligned above the plot; legend items run in a wrapping row.\n * - `'right'`: inline to the right of the plot, top-aligned; legend items run in a column.\n *\n * @experimental Part of the in-progress PDS charting components; the API may change.\n */\nexport type ChartLegendPosition = 'stack' | 'right';\n\n/** @experimental */\nexport const DEFAULT_CHART_LEGEND_POSITION: ChartLegendPosition = 'stack';\n\n/**\n * Plot height in px when a `ChartFrame` is given none. The plot always fills the frame's width.\n *\n * @experimental\n */\nexport const CHART_DEFAULT_HEIGHT = 300;\n\n/**\n * Opacity of a de-emphasised series: a hidden series' legend swatch, and the series a pointer is\n * not on (its popover row and its segment in the hovered bar).\n *\n * @experimental\n */\nexport const CHART_INACTIVE_OPACITY = 0.65;\n\n/**\n * Recharts margin for a plot inside a `ChartFrame`. The frame owns the spacing around the plot\n * (`Spacing[3]` between legend and plot) and lets axis labels overflow the SVG, so the chart adds\n * no margin of its own: `<BarChart margin={CHART_PLOT_MARGIN} ...>`.\n *\n * @experimental\n */\nexport const CHART_PLOT_MARGIN = { top: 0, right: 0, bottom: 0, left: 0 } as const;\n\nconst ChartLegendPositionContext = createContext<ChartLegendPosition | undefined>(undefined);\n\n/** Provided by `ChartFrame` so its `ChartLegend` lays its items out to match. */\nexport const ChartLegendPositionProvider = ChartLegendPositionContext.Provider;\n\n/** The legend position of the enclosing `ChartFrame`, or `undefined` outside one. */\nexport const useChartLegendPosition = (): ChartLegendPosition | undefined =>\n useContext(ChartLegendPositionContext);\n","import type { ReactElement } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport {\n ChartLegendPositionProvider,\n type ChartLegendPosition,\n CHART_DEFAULT_HEIGHT,\n DEFAULT_CHART_LEGEND_POSITION,\n} from './chartFrameLayout';\nimport type { ChartLegendProps } from './ChartLegend';\n\ntype ChartFrameLabel =\n | { 'aria-label': string; 'aria-labelledby'?: never }\n | { 'aria-labelledby': string; 'aria-label'?: never };\n\n/** @experimental */\nexport type ChartFrameProps = ChartFrameLabel & {\n /**\n * The chart's legend. Pass `null` to omit it, e.g. for a single-series chart whose surrounding\n * heading already names the series.\n */\n legend: ReactElement<ChartLegendProps> | null;\n /**\n * `'stack'` (default) puts the legend left-aligned above the plot; `'right'` puts it inline to\n * the right of the plot, as wide as its longest label up to 200px (longer labels end in an\n * ellipsis). The legend and plot are `Spacing[4]` apart when stacked and `Spacing[3]` apart inline.\n */\n legendPosition?: ChartLegendPosition;\n /**\n * Plot area height in px. Defaults to 300 (`CHART_DEFAULT_HEIGHT`). The plot always fills 100%\n * of the frame's width, and the frame fills its container.\n */\n height?: number;\n /**\n * The plot: a Recharts chart, sized by the frame (e.g. wrapped in `ResponsiveContainer`). Give it\n * `margin={CHART_PLOT_MARGIN}` so the frame's spacing is the only gap around the plot.\n */\n children: ReactElement;\n /** Applied to the root `<figure>`, e.g. to position or size the frame. */\n className?: string;\n};\n\n// Legend-to-plot gap: Spacing[4] (16px) when the legend sits above the plot, Spacing[3] (12px)\n// when it is inline on the right.\nconst Frame = styled.figure<{ $position: ChartLegendPosition }>`\n display: flex;\n gap: ${({ $position }) => ($position === 'right' ? Spacing[3] : Spacing[4])};\n box-sizing: border-box;\n width: 100%;\n margin: 0;\n min-width: 0;\n ${({ $position }) =>\n $position === 'right'\n ? css`\n flex-direction: row-reverse;\n align-items: flex-start;\n `\n : css`\n flex-direction: column;\n align-items: flex-start;\n `}\n`;\n\n// Inline legend cap: no width token exists (the Spacing scale stops at 56px). Labels past it\n// truncate with an ellipsis; 33% keeps the legend from squeezing a narrow plot.\nconst INLINE_LEGEND_MAX_WIDTH = '200px';\n\nconst LegendSlot = styled.div<{ $position: ChartLegendPosition }>`\n min-width: 0;\n ${({ $position }) =>\n $position === 'right' &&\n css`\n flex: 0 0 auto;\n width: max-content; /* fits the longest label, on one line */\n max-width: min(${INLINE_LEGEND_MAX_WIDTH}, 33%);\n `}\n`;\n\nconst Plot = styled.div<{ $height: number }>`\n align-self: stretch;\n flex: 1 1 auto;\n min-width: 0;\n height: ${({ $height }) => $height}px;\n\n /* Axis labels may overflow the plot box instead of needing a Recharts margin. */\n .recharts-surface {\n overflow: visible;\n }\n`;\n\n/**\n * Lays out a chart: its legend and the plot area, `Spacing[4]` apart stacked (`Spacing[3]` inline), with the legend left-aligned\n * above the plot (`legendPosition='stack'`, the default) or inline on its right (`'right'`). The\n * frame has no header, border or surface of its own: titles, descriptions and controls belong to\n * the surrounding container (for example a `CardV2`), which also names the chart via\n * `aria-labelledby`.\n *\n * Size: the chart fills 100% of its container's width, and the plot is 300px tall\n * (`CHART_DEFAULT_HEIGHT`) unless `height` overrides it.\n *\n * @experimental Part of the in-progress PDS charting components; the API may change.\n */\nexport function ChartFrame({\n legend,\n legendPosition = DEFAULT_CHART_LEGEND_POSITION,\n height = CHART_DEFAULT_HEIGHT,\n children,\n className,\n ...label\n}: ChartFrameProps) {\n return (\n <ChartLegendPositionProvider value={legendPosition}>\n <Frame\n $position={legendPosition}\n className={className}\n data-legend-position={legendPosition}\n {...label}\n >\n {legend && <LegendSlot $position={legendPosition}>{legend}</LegendSlot>}\n <Plot $height={height}>{children}</Plot>\n </Frame>\n </ChartLegendPositionProvider>\n );\n}\n\nexport default ChartFrame;\n","import styled from 'styled-components';\n\nimport { BorderRadius, Color, Spacing } from '@persona/design-tokens';\n\nimport Stack from '#src/components/Stack';\nimport { Paragraph } from '#src/components/Text';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { focusOutline } from '#src/mixins/focus';\nimport { paragraphMixins } from '#src/mixins/text';\n\nimport { CHART_INACTIVE_OPACITY, useChartLegendPosition } from './chartFrameLayout';\n\n/** One series in a {@link ChartLegend}. @experimental */\nexport interface ChartLegendItem<K extends string = string> {\n key: K;\n label: string;\n /** The series colour, from `useChartColors().resolve(...)` or `resolveSeriesColors(...)`. */\n color: Color;\n}\n\n/** A titled set of legend items, e.g. the series sharing an axis. @experimental */\nexport interface ChartLegendGroup<K extends string = string> {\n key: string;\n /** Shown above the group's items in uppercase mono text. */\n label: string;\n items: readonly ChartLegendItem<K>[];\n}\n\n/** Either flat `items` or titled `groups`; groups are optional. @experimental */\nexport type ChartLegendContent<K extends string = string> =\n | { items: readonly ChartLegendItem<K>[]; groups?: never }\n | { groups: readonly ChartLegendGroup<K>[]; items?: never };\n\n/** @experimental */\nexport type ChartLegendProps<K extends string = string> = ChartLegendContent<K> & {\n /** Keys of the series currently hidden. Pair with {@link useChartSeriesVisibility}. */\n hidden?: readonly K[];\n /**\n * Called with a series key when its legend item is clicked. When set, every item is a toggle\n * button (`aria-pressed` is true while the series is shown); when omitted, the legend is static.\n * Every series may be hidden.\n */\n onToggle?: (key: K) => void;\n /** Names the legend for assistive tech. Defaults to \"Chart legend\". */\n 'aria-label'?: string;\n /** Applied to the legend's root element (the list, or the group wrapper with `groups`). */\n className?: string;\n};\n\n// Placeholder sizes until the Figma Legend frame (2033-22027) is available.\nconst SWATCH_SIZE = Spacing[3];\n\nconst List = styled(Stack)`\n min-width: 0;\n max-width: 100%;\n margin: 0;\n padding: 0;\n list-style: none;\n`;\n\nconst ListItem = styled.li`\n display: flex;\n min-width: 0;\n max-width: 100%;\n`;\n\n// One line: past the legend's max width (inline legend) the label ends in an ellipsis.\nconst Label = styled(Paragraph)`\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nconst Swatch = styled.span<{ $color: Color; $hidden: boolean }>`\n flex-shrink: 0;\n width: ${SWATCH_SIZE};\n height: ${SWATCH_SIZE};\n border-radius: ${BorderRadius.Sm};\n background: ${({ $color }) => $color};\n opacity: ${({ $hidden }) => ($hidden ? CHART_INACTIVE_OPACITY : 1)};\n`;\n\n// Flex rows with the TextMedium line box: the 12px swatch centres on the 20px label line.\nconst ToggleButton = styled.button`\n ${paragraphMixins.md};\n display: flex;\n align-items: center;\n gap: ${Spacing[2]};\n min-width: 0;\n max-width: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: ${BorderRadius.Sm};\n background: none;\n color: inherit;\n text-align: start;\n cursor: pointer;\n ${focusOutline}\n\n /* Hover and pressed fill, as on a text Button. The same-colour spread ring paints the fill a\n little past the item without changing the legend's layout. */\n &:hover {\n ${({ theme }) => {\n const fill = semanticColor(theme, 'ActionNeutralHover', Color.CoreSlate100);\n return `background-color: ${fill}; box-shadow: 0 0 0 ${Spacing[1]} ${fill};`;\n }}\n }\n\n &:active {\n ${({ theme }) => {\n const fill = semanticColor(theme, 'ActionNeutralActive', Color.CoreSlate200);\n return `background-color: ${fill}; box-shadow: 0 0 0 ${Spacing[1]} ${fill};`;\n }}\n }\n`;\n\nconst StaticItem = styled.span`\n ${paragraphMixins.md};\n display: flex;\n align-items: center;\n gap: ${Spacing[2]};\n min-width: 0;\n max-width: 100%;\n`;\n\nconst GroupTitle = styled.span`\n ${paragraphMixins.smMono};\n text-transform: uppercase;\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', Color.TextSecondary)};\n`;\n\ninterface LegendItemsProps<K extends string> {\n items: readonly ChartLegendItem<K>[];\n hidden: readonly K[];\n onToggle?: (key: K) => void;\n 'aria-label': string;\n vertical: boolean;\n className?: string;\n}\n\nfunction LegendItems<K extends string>({\n items,\n hidden,\n onToggle,\n 'aria-label': ariaLabel,\n vertical,\n className,\n}: LegendItemsProps<K>) {\n return (\n <List\n as='ul'\n className={className}\n aria-label={ariaLabel}\n direction={vertical ? 'vertical' : 'horizontal'}\n spacing={vertical ? Spacing[2] : Spacing[4]}\n wrap={vertical ? undefined : 'wrap'}\n align={vertical ? 'flex-start' : 'center'}\n >\n {items.map(({ key, label, color }) => {\n const isHidden = hidden.includes(key);\n const content = (\n <>\n <Swatch $color={color} $hidden={isHidden} aria-hidden />\n <Label as='span' size='md' color={isHidden ? 'tertiary' : 'primary'} title={label}>\n {label}\n </Label>\n </>\n );\n return (\n <ListItem key={key}>\n {onToggle ? (\n <ToggleButton type='button' aria-pressed={!isHidden} onClick={() => onToggle(key)}>\n {content}\n </ToggleButton>\n ) : (\n <StaticItem>{content}</StaticItem>\n )}\n </ListItem>\n );\n })}\n </List>\n );\n}\n\n/**\n * The series key for a chart: a square colour swatch and a `TextMedium` label per series, laid out\n * in a row that wraps (a column when it sits right of the plot in a `ChartFrame`). With `onToggle`,\n * each item toggles its series; a hidden series keeps a filled swatch at 65% opacity and gets a\n * muted label.\n *\n * Pass `groups` instead of `items` for a grouped legend: groups stack `Spacing[2]` apart, each with\n * an uppercase mono title `Spacing[1]` above its row of items.\n *\n * @experimental Part of the in-progress PDS charting components; the API may change.\n */\nexport function ChartLegend<K extends string>({\n items,\n groups,\n hidden = [],\n onToggle,\n 'aria-label': ariaLabel = 'Chart legend',\n className,\n}: ChartLegendProps<K>) {\n // Beside the plot (`ChartFrame legendPosition='right'`) the items run in a column.\n const vertical = useChartLegendPosition() === 'right';\n\n if (!groups) {\n return (\n <LegendItems\n items={items}\n hidden={hidden}\n onToggle={onToggle}\n aria-label={ariaLabel}\n vertical={vertical}\n className={className}\n />\n );\n }\n\n return (\n <Stack\n role='group'\n aria-label={ariaLabel}\n className={className}\n spacing={Spacing[2]}\n align='flex-start'\n >\n {groups.map((group) => (\n <Stack key={group.key} spacing={Spacing[1]} align='flex-start'>\n <GroupTitle aria-hidden>{group.label}</GroupTitle>\n <LegendItems\n items={group.items}\n hidden={hidden}\n onToggle={onToggle}\n aria-label={group.label}\n vertical={vertical}\n />\n </Stack>\n ))}\n </Stack>\n );\n}\n\nexport default ChartLegend;\n","import { useCallback, useMemo, useState } from 'react';\n\n/** @experimental */\nexport interface ChartSeriesVisibility<K extends string> {\n /** Keys of the hidden series, in series order: pass to `ChartLegend`'s `hidden`. */\n hidden: K[];\n /** Pass to `ChartLegend`'s `onToggle`. */\n toggle: (key: K) => void;\n isHidden: (key: K) => boolean;\n /** True when every series is hidden; the plot keeps its size and axes. */\n allHidden: boolean;\n}\n\n/**\n * Show/hide state for a chart's series, driven by a {@link ChartLegend}. Every series may be hidden.\n * Hide a Recharts series with its `hide` prop (`<Bar hide={isHidden(key)} />`) rather than\n * unmounting it, so colours and axes stay put.\n *\n * @experimental\n */\nexport function useChartSeriesVisibility<K extends string>(\n keys: readonly K[],\n initialHidden: readonly K[] = [],\n): ChartSeriesVisibility<K> {\n const [hiddenSet, setHiddenSet] = useState<ReadonlySet<K>>(() => new Set(initialHidden));\n\n const toggle = useCallback((key: K) => {\n setHiddenSet((current) => {\n const next = new Set(current);\n if (next.has(key)) {\n next.delete(key);\n } else {\n next.add(key);\n }\n return next;\n });\n }, []);\n\n const isHidden = useCallback((key: K) => hiddenSet.has(key), [hiddenSet]);\n\n return useMemo(() => {\n const hidden = keys.filter((key) => hiddenSet.has(key));\n return {\n hidden,\n toggle,\n isHidden,\n allHidden: keys.length > 0 && hidden.length === keys.length,\n };\n }, [keys, hiddenSet, toggle, isHidden]);\n}\n","import type { ReactNode } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { BorderRadius, Color, Spacing } from '@persona/design-tokens';\n\nimport { usePDSLocale } from '#src/lib/i18n';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { paragraphMixins } from '#src/mixins/text';\nimport { Elevation, Hairline } from '#src/variables/effect';\n\nimport { CHART_INACTIVE_OPACITY } from './chartFrameLayout';\n\n/**\n * The popover density. `'default'` is the standalone chart popover (256px wide). `'condensed'` is\n * for small charts inside table cells (210px wide): the same text, tighter padding and row gaps,\n * and never a total row.\n *\n * @experimental Part of the in-progress PDS charting components; the API may change.\n */\nexport type ChartPopoverSize = 'default' | 'condensed';\n\n/**\n * One series the popover may list. `series` sets the row order, the label and the swatch colour; a\n * Recharts payload entry is matched to a series by its `dataKey`.\n *\n * @experimental\n */\nexport interface ChartPopoverSeries<K extends string = string> {\n key: K;\n label: ReactNode;\n /** The series colour token, e.g. from `useChartColors().resolve(...)`. Falls back to the payload colour. */\n color?: Color;\n}\n\n/**\n * One Recharts tooltip payload entry, typed structurally so the same component accepts the\n * payloads of Recharts 2 (`TooltipProps`) and Recharts 3 (`TooltipContentProps`).\n *\n * @experimental\n */\nexport interface ChartPopoverPayloadEntry {\n dataKey?: unknown;\n name?: unknown;\n value?: unknown;\n color?: string;\n fill?: string;\n stroke?: string;\n /** Set by Recharts 3 for a series rendered with `hide`. */\n hide?: boolean;\n /** Set for legend-inactive series. */\n inactive?: boolean;\n /** `'none'` marks an entry Recharts itself keeps out of its tooltip. */\n type?: string;\n payload?: unknown;\n}\n\n/** One rendered row. @experimental */\nexport interface ChartPopoverRow {\n key: string;\n label: ReactNode;\n /** The swatch colour: a Persona chart colour token. */\n color?: string;\n value: number | string | null | undefined;\n}\n\ninterface ChartPopoverPanelOwnProps<K extends string = string> {\n /** The header, e.g. the formatted x-axis category. Omitted when empty. */\n label?: ReactNode;\n /** The rows, top to bottom. */\n rows: readonly ChartPopoverRow[];\n /** Formats each row value and the total. Defaults to locale number formatting. */\n valueFormatter?: (value: number | string, seriesKey: K | 'total') => ReactNode;\n /** Appends a total row summing the numeric values of the visible rows. Ignored when `condensed`. */\n showTotal?: boolean;\n /** Overrides the computed total. */\n total?: number;\n /** Label of the total row. Defaults to `'Total'`. */\n totalLabel?: ReactNode;\n /** Defaults to `'default'`. */\n size?: ChartPopoverSize;\n /**\n * Popover width in px. Defaults to 256 (`'default'`) or 210 (`'condensed'`); pass a larger number\n * for long series names. The height always follows the rows. Series names that still do not fit\n * are truncated with an ellipsis; values never truncate or wrap.\n */\n width?: number;\n /**\n * The series the pointer is on (`useChartActiveSeries().activeSeries`). Its row stays at full\n * strength and the other series rows drop to 65% opacity; the total row is unaffected.\n */\n activeSeries?: K;\n className?: string;\n}\n\n/** @experimental */\nexport type ChartPopoverPanelProps<K extends string = string> = ChartPopoverPanelOwnProps<K>;\n\n/** @experimental */\nexport interface ChartPopoverProps<K extends string = string> extends Omit<\n ChartPopoverPanelOwnProps<K>,\n 'rows' | 'label'\n> {\n /** Injected by Recharts `<Tooltip>`. */\n active?: boolean;\n /** Injected by Recharts `<Tooltip>`. */\n payload?: readonly ChartPopoverPayloadEntry[];\n /** Injected by Recharts `<Tooltip>`: the hovered category. */\n label?: unknown;\n /**\n * The chart's series, in display order. Rows follow this order and only series listed here are\n * shown. Without it, rows follow the payload order and use the payload's names and colours.\n */\n series?: readonly ChartPopoverSeries<K>[];\n /** Series keys hidden by the legend; they get no row. */\n hiddenSeries?: Iterable<K>;\n /** Formats the header from the hovered category. Defaults to the category as is. */\n labelFormatter?: (label: unknown, payload: readonly ChartPopoverPayloadEntry[]) => ReactNode;\n}\n\n/** Default popover widths in px (Figma). @experimental */\nexport const CHART_POPOVER_WIDTH: Record<ChartPopoverSize, number> = {\n default: 256,\n condensed: 210,\n};\n\n// The sizes share their text (TextMedium rows, TextMediumBold title) and differ in spacing.\nconst SPACING = {\n default: { padding: Spacing[3], gap: Spacing[2] },\n condensed: { padding: Spacing[2], gap: Spacing[1] },\n} as const satisfies Record<ChartPopoverSize, unknown>;\n\ntype SizeProps = { $size: ChartPopoverSize };\n\nconst Panel = styled.div<SizeProps>`\n ${paragraphMixins.md};\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: ${({ $size }) => SPACING[$size].gap};\n padding: ${({ $size }) => SPACING[$size].padding};\n border-radius: ${BorderRadius.Md};\n background-color: ${({ theme }) => semanticColor(theme, 'SurfacePrimary', Color.BackgroundPrimary)};\n box-shadow: ${Elevation.Mid};\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', Color.TextPrimary)};\n pointer-events: none;\n`;\n\nconst Header = styled.div`\n ${paragraphMixins.mdBold};\n`;\n\nconst Rows = styled.ul<SizeProps>`\n display: flex;\n flex-direction: column;\n gap: ${({ $size }) => SPACING[$size].gap};\n margin: 0;\n padding: 0;\n list-style: none;\n`;\n\nconst Row = styled.li<{ $dimmed?: boolean }>`\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n align-items: center;\n column-gap: ${Spacing[2]};\n opacity: ${({ $dimmed }) => ($dimmed ? CHART_INACTIVE_OPACITY : 1)};\n`;\n\nconst TotalRow = styled(Row)`\n padding-top: ${Spacing[1]};\n box-shadow: ${Hairline.Top};\n`;\n\n// PDS has no 2px radius token (BorderRadius starts at Sm = 3px); the swatch design is 2px.\nconst SWATCH_RADIUS = '2px';\n\n// The fill is the series' chart colour token, so it is set inline rather than through a semantic\n// token. 12px square in both sizes.\nconst Swatch = styled.span`\n width: ${Spacing[3]};\n height: ${Spacing[3]};\n border-radius: ${SWATCH_RADIUS};\n flex-shrink: 0;\n`;\n\nconst SeriesName = styled.span`\n overflow: hidden;\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', Color.TextSecondary)};\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\n// TextMedium like the rest of the body (proportional figures, no mono or tabular numerals).\nconst Value = styled.span`\n ${paragraphMixins.md};\n text-align: right;\n white-space: nowrap;\n`;\n\nconst isPresent = (value: unknown): value is number | string =>\n typeof value === 'number' ? !Number.isNaN(value) : typeof value === 'string' && value !== '';\n\n/**\n * The chart popover body: an optional header, one row per series (swatch, name, right-aligned\n * value) and an optional total row. Use it directly for a popover drawn outside Recharts; inside a\n * Recharts chart use {@link ChartPopover}.\n *\n * @experimental Part of the in-progress PDS charting components; the API may change.\n */\nexport function ChartPopoverPanel<K extends string = string>({\n label,\n rows,\n valueFormatter,\n showTotal = false,\n total,\n totalLabel = 'Total',\n size = 'default',\n width,\n activeSeries,\n className,\n}: ChartPopoverPanelProps<K>) {\n const locale = usePDSLocale();\n const format = (value: number | string, key: K | 'total'): ReactNode => {\n if (valueFormatter) {\n return valueFormatter(value, key);\n }\n return typeof value === 'number' ? value.toLocaleString(locale) : value;\n };\n\n const totalValue =\n total ??\n rows.reduce(\n (sum, { value }) => (typeof value === 'number' && !Number.isNaN(value) ? sum + value : sum),\n 0,\n );\n const hasLabel = label !== undefined && label !== null && label !== '';\n\n return (\n <Panel\n $size={size}\n className={className}\n data-size={size}\n data-test='chart-popover'\n style={{ width: width ?? CHART_POPOVER_WIDTH[size] }}\n >\n {hasLabel && <Header>{label}</Header>}\n <Rows $size={size}>\n {rows.map((row) => (\n <Row\n key={row.key}\n $dimmed={activeSeries !== undefined && row.key !== activeSeries}\n data-active={activeSeries === row.key || undefined}\n >\n <Swatch aria-hidden style={{ background: row.color }} />\n <SeriesName title={typeof row.label === 'string' ? row.label : undefined}>\n {row.label}\n </SeriesName>\n <Value>{isPresent(row.value) ? format(row.value, row.key as K) : '–'}</Value>\n </Row>\n ))}\n {showTotal && size !== 'condensed' && (\n <TotalRow>\n {/* An unpainted swatch keeps the total label aligned with the series names. */}\n <Swatch aria-hidden />\n <span>{totalLabel}</span>\n <Value>{format(totalValue, 'total')}</Value>\n </TotalRow>\n )}\n </Rows>\n </Panel>\n );\n}\n\nconst entryKey = ({ dataKey, name }: ChartPopoverPayloadEntry): string | undefined => {\n if (typeof dataKey === 'string' || typeof dataKey === 'number') {\n return String(dataKey);\n }\n return typeof name === 'string' || typeof name === 'number' ? String(name) : undefined;\n};\n\nconst isEntryVisible = (entry: ChartPopoverPayloadEntry): boolean =>\n !entry.hide && !entry.inactive && entry.type !== 'none';\n\n/**\n * Builds the popover rows from a Recharts tooltip payload: drops hidden and inactive series, then\n * orders, labels and colours the rest by `series` (or keeps the payload order without it).\n *\n * @experimental\n */\nexport function chartPopoverRows<K extends string>(\n payload: readonly ChartPopoverPayloadEntry[],\n series?: readonly ChartPopoverSeries<K>[],\n hiddenSeries?: Iterable<K>,\n): ChartPopoverRow[] {\n const hidden = new Set<string>(hiddenSeries ?? []);\n const visible = new Map<string, ChartPopoverPayloadEntry>();\n for (const entry of payload) {\n const key = entryKey(entry);\n if (key !== undefined && !hidden.has(key) && isEntryVisible(entry) && !visible.has(key)) {\n visible.set(key, entry);\n }\n }\n\n const payloadColor = (entry: ChartPopoverPayloadEntry) =>\n entry.color ?? entry.fill ?? entry.stroke;\n\n if (!series) {\n return [...visible].map(([key, entry]) => ({\n key,\n label: isPresent(entry.name) ? entry.name : key,\n color: payloadColor(entry),\n value: entry.value as ChartPopoverRow['value'],\n }));\n }\n\n return series.flatMap(({ key, label, color }) => {\n const entry = visible.get(key);\n return entry\n ? [\n {\n key,\n label,\n color: color ?? payloadColor(entry),\n value: entry.value as ChartPopoverRow['value'],\n },\n ]\n : [];\n });\n}\n\n/**\n * Chart popover (tooltip) content for Recharts 2 and 3. Pass it to `<Tooltip content={...} />`;\n * Recharts injects `active`, `payload` and `label`.\n *\n * ```tsx\n * const series = [{ key: 'approved', label: 'Approved', color: colors.approved }, ...];\n * <Tooltip cursor={false} content={<ChartPopover series={series} hiddenSeries={hidden} />} />\n * ```\n *\n * Renders nothing while inactive or when every series is hidden.\n *\n * @experimental Part of the in-progress PDS charting components; the API may change.\n */\nexport function ChartPopover<K extends string = string>({\n active,\n payload,\n label,\n series,\n hiddenSeries,\n labelFormatter,\n ...panelProps\n}: ChartPopoverProps<K>) {\n if (!active || !payload || payload.length === 0) {\n return null;\n }\n const rows = chartPopoverRows(payload, series, hiddenSeries);\n if (rows.length === 0) {\n return null;\n }\n const header = labelFormatter ? labelFormatter(label, payload) : (label as ReactNode);\n\n return <ChartPopoverPanel<K> {...panelProps} label={header} rows={rows} />;\n}\n","import { useCallback, useState } from 'react';\nimport { useTheme } from 'styled-components';\n\nimport { Color, Typography } from '@persona/design-tokens';\n\nimport { semanticColor } from '#src/lib/semanticColor';\nimport type { PersonaTheme } from '#src/theme';\n\nimport { CHART_INACTIVE_OPACITY } from './chartFrameLayout';\n\n// Between Recharts 3's cursor rectangle (200) and its bars (300).\nconst GRID_Z_INDEX = 250;\n\n/** Axis tick text style (TextSmall). @experimental */\nexport interface ChartTickStyle {\n fill: string;\n fontSize: string;\n fontFamily: string;\n}\n\n/** What {@link useChartStyles} returns: props to spread on Recharts components. @experimental */\nexport interface ChartStyles {\n /** The resolved semantic colours behind the props below. */\n colors: { grid: string; axis: string; text: string; surface: string; hover: string };\n grid: { vertical: false; stroke: string; zIndex: number };\n xAxis: { tick: ChartTickStyle; tickLine: false; axisLine: { stroke: string } };\n yAxis: { tick: ChartTickStyle; tickLine: false; axisLine: false };\n barCursor: { fill: string; fillOpacity: number };\n lineCursor: { stroke: string };\n segmentGap: { stroke: string; strokeWidth: number };\n activeDot: { r: number; stroke: string; strokeWidth: number };\n}\n\n/**\n * PDS styling for hand-built Recharts charts, as props to spread on Recharts' own components so a\n * custom chart (reference lines, formatters, extra children) keeps the PDS look:\n *\n * ```tsx\n * const styles = useChartStyles();\n * <BarChart data={data} margin={CHART_PLOT_MARGIN}>\n * <Tooltip cursor={styles.barCursor} content={<ChartPopover series={series} />} />\n * <CartesianGrid {...styles.grid} />\n * <XAxis dataKey='month' {...styles.xAxis} tickFormatter={formatMonth} />\n * <YAxis {...styles.yAxis} />\n * <ReferenceLine y={target} stroke={styles.colors.axis} strokeDasharray='4 4' />\n * ...\n * </BarChart>\n * ```\n *\n * Colours come from semantic tokens, so they follow light and dark mode.\n *\n * @experimental Part of the in-progress PDS charting components; the API may change.\n */\nexport function useChartStyles(): ChartStyles {\n const theme = useTheme() as PersonaTheme | undefined;\n const colors = {\n grid: semanticColor(theme, 'BorderDivider', Color.BorderHairline),\n axis: semanticColor(theme, 'BorderDefault', Color.BorderDivider),\n text: semanticColor(theme, 'FgSecondary', Color.TextSecondary),\n surface: semanticColor(theme, 'SurfacePrimary', Color.BackgroundPrimary),\n hover: semanticColor(theme, 'SurfaceHover', Color.BackgroundSecondary),\n };\n const tick: ChartTickStyle = {\n fill: colors.text,\n fontSize: Typography.TextSmall.fontSize,\n fontFamily: Typography.TextSmall.fontFamily,\n };\n return {\n colors,\n /**\n * `<CartesianGrid>`: horizontal gridlines only, drawn over the tooltip cursor band so they stay\n * visible through it. Recharts 3 layers by `zIndex` (its cursor band is 200, bars 300); Recharts 2\n * ignores `zIndex` and layers by child order, so put `<Tooltip>` before `<CartesianGrid>`.\n */\n grid: { vertical: false, stroke: colors.grid, zIndex: GRID_Z_INDEX },\n /** `<XAxis>`: no tick marks, a baseline in the default border colour. */\n xAxis: { tick, tickLine: false, axisLine: { stroke: colors.axis } },\n /** `<YAxis>`: no tick marks or axis line. */\n yAxis: { tick, tickLine: false, axisLine: false },\n /** `<Tooltip cursor>` for bar charts: a translucent band, so gridlines show through. */\n barCursor: { fill: colors.hover, fillOpacity: CHART_INACTIVE_OPACITY },\n /** `<Tooltip cursor>` for line charts: a vertical line. */\n lineCursor: { stroke: colors.axis },\n /** `<Bar>` in a stack: a 1px surface-coloured line between segments. */\n segmentGap: { stroke: colors.surface, strokeWidth: 1 },\n /** `<Line activeDot>`: the hovered point, ringed in the surface colour. */\n activeDot: { r: 4, stroke: colors.surface, strokeWidth: 2 },\n };\n}\n\n/** @experimental */\nexport interface ChartActiveSeries<K extends string> {\n /** The series under the pointer, for `ChartPopover activeSeries`. */\n activeSeries: K | undefined;\n /** Spread on each `<Bar>`: tracks which series and category the pointer is on. */\n barHandlers: (key: K) => {\n onMouseEnter: (data: unknown, index: number) => void;\n onMouseLeave: () => void;\n };\n /**\n * `fillOpacity` for a series' bar at `index` (pass it to a `<Cell>`): 0.65 for the other series in\n * the hovered category, 1 otherwise.\n */\n segmentOpacity: (key: K, index: number) => number;\n}\n\n/**\n * Hover emphasis for bars holding several series (stacked or grouped): the segment under the\n * pointer stays at full strength, the other segments of the same category drop to 65% opacity, and\n * `activeSeries` dims the matching popover rows.\n *\n * ```tsx\n * const { activeSeries, barHandlers, segmentOpacity } = useChartActiveSeries<Key>();\n * <Tooltip content={<ChartPopover series={series} activeSeries={activeSeries} />} />\n * {series.map(({ key }) => (\n * <Bar key={key} dataKey={key} {...barHandlers(key)}>\n * {data.map((_, i) => <Cell key={i} fillOpacity={segmentOpacity(key, i)} />)}\n * </Bar>\n * ))}\n * ```\n *\n * @experimental\n */\nexport function useChartActiveSeries<K extends string>(): ChartActiveSeries<K> {\n const [active, setActive] = useState<{ key: K; index: number } | null>(null);\n const barHandlers = useCallback(\n (key: K) => ({\n onMouseEnter: (_data: unknown, index: number) => setActive({ key, index }),\n onMouseLeave: () => setActive(null),\n }),\n [],\n );\n const segmentOpacity = (key: K, index: number) =>\n active && active.index === index && active.key !== key ? CHART_INACTIVE_OPACITY : 1;\n return { activeSeries: active?.key, barHandlers, segmentOpacity };\n}\n"],"mappings":"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"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { ChartColorMode, ChartPalette, ChartSeriesColorInput } from "./chartColors.mjs";
|
|
2
|
-
import { Color } from "@persona/design-tokens";
|
|
3
|
-
|
|
4
|
-
//#region src/components/Chart/useChartColors.d.ts
|
|
5
|
-
/** @experimental */
|
|
6
|
-
interface ChartColors {
|
|
7
|
-
/** The colour mode the palettes were read for. */
|
|
8
|
-
mode: ChartColorMode;
|
|
9
|
-
/** The ordered colours of the selected palette for that mode. */
|
|
10
|
-
colors: readonly Color[];
|
|
11
|
-
/** {@link resolveSeriesColors} bound to the selected palette and mode. */
|
|
12
|
-
resolve: <K extends string>(series: readonly ChartSeriesColorInput<K>[]) => Record<K, Color>;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* The chart colours for the current PDS colour mode. Reads the charting palettes `PDSProvider` /
|
|
16
|
-
* `ColorModeScope` install on the styled-components theme, so charts follow dark mode with no
|
|
17
|
-
* extra setup; without a PDS colour mode it returns the light `ChartingColors`.
|
|
18
|
-
*
|
|
19
|
-
* ```tsx
|
|
20
|
-
* const { resolve } = useChartColors();
|
|
21
|
-
* const colors = resolve([{ key: 'approved' }, { key: 'declined', color: chartColor(Color.CoreRed600) }]);
|
|
22
|
-
* <Bar dataKey='approved' fill={colors.approved} />
|
|
23
|
-
* ```
|
|
24
|
-
*
|
|
25
|
-
* @experimental
|
|
26
|
-
*/
|
|
27
|
-
declare function useChartColors(palette?: ChartPalette): ChartColors;
|
|
28
|
-
//#endregion
|
|
29
|
-
export { ChartColors, useChartColors };
|
|
30
|
-
//# sourceMappingURL=useChartColors.d.mts.map
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
//#region src/components/Chart/useChartSeriesVisibility.d.ts
|
|
2
|
-
/** @experimental */
|
|
3
|
-
interface ChartSeriesVisibility<K extends string> {
|
|
4
|
-
/** Keys of the hidden series, in series order: pass to `ChartLegend`'s `hidden`. */
|
|
5
|
-
hidden: K[];
|
|
6
|
-
/** Pass to `ChartLegend`'s `onToggle`. */
|
|
7
|
-
toggle: (key: K) => void;
|
|
8
|
-
isHidden: (key: K) => boolean;
|
|
9
|
-
/** True when every series is hidden; the plot keeps its size and axes. */
|
|
10
|
-
allHidden: boolean;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Show/hide state for a chart's series, driven by a {@link ChartLegend}. Every series may be hidden.
|
|
14
|
-
* Hide a Recharts series with its `hide` prop (`<Bar hide={isHidden(key)} />`) rather than
|
|
15
|
-
* unmounting it, so colours and axes stay put.
|
|
16
|
-
*
|
|
17
|
-
* @experimental
|
|
18
|
-
*/
|
|
19
|
-
declare function useChartSeriesVisibility<K extends string>(keys: readonly K[], initialHidden?: readonly K[]): ChartSeriesVisibility<K>;
|
|
20
|
-
//#endregion
|
|
21
|
-
export { ChartSeriesVisibility, useChartSeriesVisibility };
|
|
22
|
-
//# sourceMappingURL=useChartSeriesVisibility.d.mts.map
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
//#region src/components/Chart/useChartStyles.d.ts
|
|
2
|
-
/** Axis tick text style (TextSmall). @experimental */
|
|
3
|
-
interface ChartTickStyle {
|
|
4
|
-
fill: string;
|
|
5
|
-
fontSize: string;
|
|
6
|
-
fontFamily: string;
|
|
7
|
-
}
|
|
8
|
-
/** What {@link useChartStyles} returns: props to spread on Recharts components. @experimental */
|
|
9
|
-
interface ChartStyles {
|
|
10
|
-
/** The resolved semantic colours behind the props below. */
|
|
11
|
-
colors: {
|
|
12
|
-
grid: string;
|
|
13
|
-
axis: string;
|
|
14
|
-
text: string;
|
|
15
|
-
surface: string;
|
|
16
|
-
hover: string;
|
|
17
|
-
};
|
|
18
|
-
grid: {
|
|
19
|
-
vertical: false;
|
|
20
|
-
stroke: string;
|
|
21
|
-
zIndex: number;
|
|
22
|
-
};
|
|
23
|
-
xAxis: {
|
|
24
|
-
tick: ChartTickStyle;
|
|
25
|
-
tickLine: false;
|
|
26
|
-
axisLine: {
|
|
27
|
-
stroke: string;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
yAxis: {
|
|
31
|
-
tick: ChartTickStyle;
|
|
32
|
-
tickLine: false;
|
|
33
|
-
axisLine: false;
|
|
34
|
-
};
|
|
35
|
-
barCursor: {
|
|
36
|
-
fill: string;
|
|
37
|
-
fillOpacity: number;
|
|
38
|
-
};
|
|
39
|
-
lineCursor: {
|
|
40
|
-
stroke: string;
|
|
41
|
-
};
|
|
42
|
-
segmentGap: {
|
|
43
|
-
stroke: string;
|
|
44
|
-
strokeWidth: number;
|
|
45
|
-
};
|
|
46
|
-
activeDot: {
|
|
47
|
-
r: number;
|
|
48
|
-
stroke: string;
|
|
49
|
-
strokeWidth: number;
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* PDS styling for hand-built Recharts charts, as props to spread on Recharts' own components so a
|
|
54
|
-
* custom chart (reference lines, formatters, extra children) keeps the PDS look:
|
|
55
|
-
*
|
|
56
|
-
* ```tsx
|
|
57
|
-
* const styles = useChartStyles();
|
|
58
|
-
* <BarChart data={data} margin={CHART_PLOT_MARGIN}>
|
|
59
|
-
* <Tooltip cursor={styles.barCursor} content={<ChartPopover series={series} />} />
|
|
60
|
-
* <CartesianGrid {...styles.grid} />
|
|
61
|
-
* <XAxis dataKey='month' {...styles.xAxis} tickFormatter={formatMonth} />
|
|
62
|
-
* <YAxis {...styles.yAxis} />
|
|
63
|
-
* <ReferenceLine y={target} stroke={styles.colors.axis} strokeDasharray='4 4' />
|
|
64
|
-
* ...
|
|
65
|
-
* </BarChart>
|
|
66
|
-
* ```
|
|
67
|
-
*
|
|
68
|
-
* Colours come from semantic tokens, so they follow light and dark mode.
|
|
69
|
-
*
|
|
70
|
-
* @experimental Part of the in-progress PDS charting components; the API may change.
|
|
71
|
-
*/
|
|
72
|
-
declare function useChartStyles(): ChartStyles;
|
|
73
|
-
/** @experimental */
|
|
74
|
-
interface ChartActiveSeries<K extends string> {
|
|
75
|
-
/** The series under the pointer, for `ChartPopover activeSeries`. */
|
|
76
|
-
activeSeries: K | undefined;
|
|
77
|
-
/** Spread on each `<Bar>`: tracks which series and category the pointer is on. */
|
|
78
|
-
barHandlers: (key: K) => {
|
|
79
|
-
onMouseEnter: (data: unknown, index: number) => void;
|
|
80
|
-
onMouseLeave: () => void;
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* `fillOpacity` for a series' bar at `index` (pass it to a `<Cell>`): 0.65 for the other series in
|
|
84
|
-
* the hovered category, 1 otherwise.
|
|
85
|
-
*/
|
|
86
|
-
segmentOpacity: (key: K, index: number) => number;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Hover emphasis for bars holding several series (stacked or grouped): the segment under the
|
|
90
|
-
* pointer stays at full strength, the other segments of the same category drop to 65% opacity, and
|
|
91
|
-
* `activeSeries` dims the matching popover rows.
|
|
92
|
-
*
|
|
93
|
-
* ```tsx
|
|
94
|
-
* const { activeSeries, barHandlers, segmentOpacity } = useChartActiveSeries<Key>();
|
|
95
|
-
* <Tooltip content={<ChartPopover series={series} activeSeries={activeSeries} />} />
|
|
96
|
-
* {series.map(({ key }) => (
|
|
97
|
-
* <Bar key={key} dataKey={key} {...barHandlers(key)}>
|
|
98
|
-
* {data.map((_, i) => <Cell key={i} fillOpacity={segmentOpacity(key, i)} />)}
|
|
99
|
-
* </Bar>
|
|
100
|
-
* ))}
|
|
101
|
-
* ```
|
|
102
|
-
*
|
|
103
|
-
* @experimental
|
|
104
|
-
*/
|
|
105
|
-
declare function useChartActiveSeries<K extends string>(): ChartActiveSeries<K>;
|
|
106
|
-
//#endregion
|
|
107
|
-
export { ChartActiveSeries, ChartStyles, ChartTickStyle, useChartActiveSeries, useChartStyles };
|
|
108
|
-
//# sourceMappingURL=useChartStyles.d.mts.map
|