@apipass/design-system 6.1.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/lib/charts.index.cjs +1 -1
  2. package/dist/lib/charts.index.js +7 -5
  3. package/dist/lib/charts.index.js.map +1 -1
  4. package/dist/lib/embedded-styles.js +2 -2
  5. package/dist/lib/style.css +1 -1
  6. package/dist/lib/ui/components/DataTable/DataTable.cjs +1 -1
  7. package/dist/lib/ui/components/DataTable/DataTable.cjs.map +1 -1
  8. package/dist/lib/ui/components/DataTable/DataTable.js +81 -83
  9. package/dist/lib/ui/components/DataTable/DataTable.js.map +1 -1
  10. package/dist/lib/ui/components/charts/PieChart/PieChart.cjs +1 -1
  11. package/dist/lib/ui/components/charts/PieChart/PieChart.cjs.map +1 -1
  12. package/dist/lib/ui/components/charts/PieChart/PieChart.js +39 -38
  13. package/dist/lib/ui/components/charts/PieChart/PieChart.js.map +1 -1
  14. package/dist/lib/ui/components/charts/PieChart/pie-chart-option.cjs +1 -1
  15. package/dist/lib/ui/components/charts/PieChart/pie-chart-option.cjs.map +1 -1
  16. package/dist/lib/ui/components/charts/PieChart/pie-chart-option.js +65 -71
  17. package/dist/lib/ui/components/charts/PieChart/pie-chart-option.js.map +1 -1
  18. package/dist/lib/ui/components/charts/TopList/TopList.cjs +2 -0
  19. package/dist/lib/ui/components/charts/TopList/TopList.cjs.map +1 -0
  20. package/dist/lib/ui/components/charts/TopList/TopList.js +79 -0
  21. package/dist/lib/ui/components/charts/TopList/TopList.js.map +1 -0
  22. package/dist/lib/ui/components/charts/TopList/top-list-option.cjs +2 -0
  23. package/dist/lib/ui/components/charts/TopList/top-list-option.cjs.map +1 -0
  24. package/dist/lib/ui/components/charts/TopList/top-list-option.js +178 -0
  25. package/dist/lib/ui/components/charts/TopList/top-list-option.js.map +1 -0
  26. package/dist/lib/ui/components/charts/chart-share.cjs +2 -0
  27. package/dist/lib/ui/components/charts/chart-share.cjs.map +1 -0
  28. package/dist/lib/ui/components/charts/chart-share.js +11 -0
  29. package/dist/lib/ui/components/charts/chart-share.js.map +1 -0
  30. package/dist/lib/ui/primitives/Table/Table.cjs +1 -1
  31. package/dist/lib/ui/primitives/Table/Table.cjs.map +1 -1
  32. package/dist/lib/ui/primitives/Table/Table.js +53 -55
  33. package/dist/lib/ui/primitives/Table/Table.js.map +1 -1
  34. package/dist/types/charts.index.d.ts +1 -0
  35. package/dist/types/ui/components/DataTable/DataTable.d.ts +1 -3
  36. package/dist/types/ui/components/charts/PieChart/pie-chart-option.d.ts +0 -1
  37. package/dist/types/ui/components/charts/TopList/TopList.d.ts +13 -0
  38. package/dist/types/ui/components/charts/TopList/top-list-option.d.ts +24 -0
  39. package/dist/types/ui/components/charts/chart-share.d.ts +1 -0
  40. package/dist/types/ui/primitives/Table/Table.d.ts +1 -2
  41. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"pie-chart-option.js","sources":["../../../../../../src/ui/components/charts/PieChart/pie-chart-option.ts"],"sourcesContent":["import { labelColorOnFill } from \"../chart-label-color\";\nimport type { ChartTheme } from \"../chart-theme\";\nimport type { PieSlice } from \"./pie-chart-slices\";\nimport { sliceDepth } from \"./pie-chart-slices\";\n\nexport type PieChartLabelContent = \"name\" | \"percent\" | \"value\";\n\nexport type PieChartShape = \"donut\" | \"pie\";\n\nexport interface PieChartOptionInput {\n slices: PieSlice[];\n shape: PieChartShape;\n labelContent: PieChartLabelContent[];\n theme: ChartTheme;\n valueFormatter?: (value: number) => string;\n}\n\nconst DONUT_HOLE_RADIUS_PERCENT: number = 40;\n\nconst FULL_PIE_OUTER_RADIUS_PERCENT: number = 85;\n\nconst MIN_INSIDE_LABEL_ANGLE_DEGREES: number = 8;\n\nconst RING_THICKNESS_PERCENT: number = 32;\n\nconst OUTER_RADIUS_LIMIT_PERCENT: number = 92;\n\nconst PATH_SEPARATOR: string = \" > \";\n\nconst MIN_LABELED_ANGLE_DEGREES: number = 10;\n\nconst RING_BORDER_WIDTH_PX: number = 2;\n\nconst PERCENT_LABEL: Intl.NumberFormat = new Intl.NumberFormat(undefined, {\n style: \"percent\",\n maximumFractionDigits: 1,\n});\n\nexport function formatShare(share: number): string {\n return PERCENT_LABEL.format(share);\n}\n\nfunction formatValue(input: PieChartOptionInput, value: number): string {\n return input.valueFormatter ? input.valueFormatter(value) : String(value);\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction labelText(input: PieChartOptionInput, slice: PieSlice): string {\n const parts: string[] = [];\n if (input.labelContent.includes(\"name\")) parts.push(slice.name);\n if (input.labelContent.includes(\"percent\")) parts.push(formatShare(slice.share));\n if (input.labelContent.includes(\"value\")) parts.push(formatValue(input, slice.value));\n return parts.join(\" \");\n}\n\nfunction tooltipHtml(input: PieChartOptionInput, slice: PieSlice): string {\n const path: string = escapeHtml(slice.path.join(PATH_SEPARATOR));\n const value: string = escapeHtml(formatValue(input, slice.value));\n return `<div>${path}</div><div><b>${value}</b> · ${formatShare(slice.share)}</div>`;\n}\n\ninterface DataItem {\n id: string;\n name: string;\n value: number;\n itemStyle: { color: string };\n label?: { color: string };\n labelText: string;\n tooltip: string;\n children?: DataItem[];\n}\n\nfunction toDataItem(input: PieChartOptionInput, slice: PieSlice, withChildren: boolean): DataItem {\n return {\n id: slice.id,\n name: slice.name,\n value: slice.value,\n itemStyle: { color: slice.color },\n label: { color: labelColorOnFill(slice.color) },\n labelText: labelText(input, slice),\n tooltip: tooltipHtml(input, slice),\n children: withChildren\n ? slice.children.map((child: PieSlice) => toDataItem(input, child, true))\n : undefined,\n };\n}\n\nfunction tooltipOption(input: PieChartOptionInput): Record<string, unknown> {\n const { theme } = input;\n return {\n trigger: \"item\",\n backgroundColor: theme.tooltipBackgroundColor,\n borderColor: theme.tooltipBorderColor,\n textStyle: { color: theme.labelColor },\n formatter: (params: { data: DataItem }) => params.data.tooltip,\n };\n}\n\nfunction labelFormatter(params: { data: DataItem }): string {\n return params.data.labelText;\n}\n\nfunction holeRadiusPercent(input: PieChartOptionInput): number {\n return input.shape === \"pie\" ? 0 : DONUT_HOLE_RADIUS_PERCENT;\n}\n\nfunction pieRadius(input: PieChartOptionInput): [string, string] {\n if (input.shape === \"pie\") return [\"0%\", `${FULL_PIE_OUTER_RADIUS_PERCENT}%`];\n return [\n `${DONUT_HOLE_RADIUS_PERCENT}%`,\n `${DONUT_HOLE_RADIUS_PERCENT + RING_THICKNESS_PERCENT}%`,\n ];\n}\n\nfunction pieLabel(input: PieChartOptionInput): Record<string, unknown> {\n const show: boolean = input.labelContent.length > 0;\n if (input.shape === \"pie\") {\n return { show, position: \"inside\", formatter: labelFormatter };\n }\n return { show, position: \"outside\", color: input.theme.labelColor, formatter: labelFormatter };\n}\n\nfunction pieSeries(input: PieChartOptionInput): Record<string, unknown> {\n const isFullPie: boolean = input.shape === \"pie\";\n return {\n type: \"pie\",\n radius: pieRadius(input),\n data: input.slices.map((slice: PieSlice) => {\n const { label: fillLabel, ...item } = toDataItem(input, slice, false);\n return isFullPie ? { ...item, label: fillLabel } : item;\n }),\n itemStyle: { borderColor: input.theme.tooltipBackgroundColor, borderWidth: RING_BORDER_WIDTH_PX },\n label: pieLabel(input),\n minShowLabelAngle: isFullPie ? MIN_INSIDE_LABEL_ANGLE_DEGREES : 0,\n labelLine: { show: !isFullPie && input.labelContent.length > 0 },\n labelLayout: { hideOverlap: true },\n emphasis: { scale: false },\n };\n}\n\nfunction sunburstLevels(input: PieChartOptionInput, depth: number): Array<Record<string, unknown>> {\n const hole: number = holeRadiusPercent(input);\n const evenThickness: number = (OUTER_RADIUS_LIMIT_PERCENT - hole) / depth;\n const thickness: number =\n input.shape === \"pie\" ? evenThickness : Math.min(RING_THICKNESS_PERCENT, evenThickness);\n const rings: Array<Record<string, unknown>> = Array.from(\n { length: depth },\n (_unused, ringIndex: number) => ({\n r0: `${hole + thickness * ringIndex}%`,\n r: `${hole + thickness * (ringIndex + 1)}%`,\n }),\n );\n return [{}, ...rings];\n}\n\nfunction sunburstSeries(input: PieChartOptionInput): Record<string, unknown> {\n const hasLabels: boolean = input.labelContent.length > 0;\n return {\n type: \"sunburst\",\n nodeClick: false,\n sort: null,\n radius: [`${holeRadiusPercent(input)}%`, `${OUTER_RADIUS_LIMIT_PERCENT}%`],\n data: input.slices.map((slice: PieSlice) => toDataItem(input, slice, true)),\n levels: sunburstLevels(input, sliceDepth(input.slices)),\n itemStyle: { borderColor: input.theme.tooltipBackgroundColor, borderWidth: RING_BORDER_WIDTH_PX },\n label: {\n show: hasLabels,\n rotate: \"radial\",\n minAngle: MIN_LABELED_ANGLE_DEGREES,\n formatter: labelFormatter,\n },\n emphasis: { focus: \"none\" },\n };\n}\n\nfunction isHierarchical(slices: PieSlice[]): boolean {\n return slices.some((slice: PieSlice) => slice.children.length > 0);\n}\n\nexport function buildPieChartOption(input: PieChartOptionInput): Record<string, unknown> {\n const { theme } = input;\n return {\n animation: false,\n textStyle: { fontFamily: theme.fontFamily, color: theme.labelColor },\n tooltip: tooltipOption(input),\n series: [isHierarchical(input.slices) ? sunburstSeries(input) : pieSeries(input)],\n };\n}\n"],"names":["DONUT_HOLE_RADIUS_PERCENT","FULL_PIE_OUTER_RADIUS_PERCENT","MIN_INSIDE_LABEL_ANGLE_DEGREES","RING_THICKNESS_PERCENT","OUTER_RADIUS_LIMIT_PERCENT","PATH_SEPARATOR","MIN_LABELED_ANGLE_DEGREES","RING_BORDER_WIDTH_PX","PERCENT_LABEL","formatShare","share","formatValue","input","value","escapeHtml","text","labelText","slice","parts","tooltipHtml","path","toDataItem","withChildren","labelColorOnFill","child","tooltipOption","theme","params","labelFormatter","holeRadiusPercent","pieRadius","pieLabel","show","pieSeries","isFullPie","fillLabel","item","sunburstLevels","depth","hole","evenThickness","thickness","rings","_unused","ringIndex","sunburstSeries","hasLabels","sliceDepth","isHierarchical","slices","buildPieChartOption"],"mappings":"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"}
1
+ {"version":3,"file":"pie-chart-option.js","sources":["../../../../../../src/ui/components/charts/PieChart/pie-chart-option.ts"],"sourcesContent":["import { labelColorOnFill } from \"../chart-label-color\";\nimport { formatShare } from \"../chart-share\";\nimport type { ChartTheme } from \"../chart-theme\";\nimport type { PieSlice } from \"./pie-chart-slices\";\nimport { sliceDepth } from \"./pie-chart-slices\";\n\nexport type PieChartLabelContent = \"name\" | \"percent\" | \"value\";\n\nexport type PieChartShape = \"donut\" | \"pie\";\n\nexport interface PieChartOptionInput {\n slices: PieSlice[];\n shape: PieChartShape;\n labelContent: PieChartLabelContent[];\n theme: ChartTheme;\n valueFormatter?: (value: number) => string;\n}\n\nconst DONUT_HOLE_RADIUS_PERCENT: number = 40;\n\nconst FULL_PIE_OUTER_RADIUS_PERCENT: number = 85;\n\nconst MIN_INSIDE_LABEL_ANGLE_DEGREES: number = 8;\n\nconst RING_THICKNESS_PERCENT: number = 32;\n\nconst OUTER_RADIUS_LIMIT_PERCENT: number = 92;\n\nconst PATH_SEPARATOR: string = \" > \";\n\nconst MIN_LABELED_ANGLE_DEGREES: number = 10;\n\nconst RING_BORDER_WIDTH_PX: number = 2;\n\nfunction formatValue(input: PieChartOptionInput, value: number): string {\n return input.valueFormatter ? input.valueFormatter(value) : String(value);\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction labelText(input: PieChartOptionInput, slice: PieSlice): string {\n const parts: string[] = [];\n if (input.labelContent.includes(\"name\")) parts.push(slice.name);\n if (input.labelContent.includes(\"percent\")) parts.push(formatShare(slice.share));\n if (input.labelContent.includes(\"value\")) parts.push(formatValue(input, slice.value));\n return parts.join(\" \");\n}\n\nfunction tooltipHtml(input: PieChartOptionInput, slice: PieSlice): string {\n const path: string = escapeHtml(slice.path.join(PATH_SEPARATOR));\n const value: string = escapeHtml(formatValue(input, slice.value));\n return `<div>${path}</div><div><b>${value}</b> · ${formatShare(slice.share)}</div>`;\n}\n\ninterface DataItem {\n id: string;\n name: string;\n value: number;\n itemStyle: { color: string };\n label?: { color: string };\n labelText: string;\n tooltip: string;\n children?: DataItem[];\n}\n\nfunction toDataItem(input: PieChartOptionInput, slice: PieSlice, withChildren: boolean): DataItem {\n return {\n id: slice.id,\n name: slice.name,\n value: slice.value,\n itemStyle: { color: slice.color },\n label: { color: labelColorOnFill(slice.color) },\n labelText: labelText(input, slice),\n tooltip: tooltipHtml(input, slice),\n children: withChildren\n ? slice.children.map((child: PieSlice) => toDataItem(input, child, true))\n : undefined,\n };\n}\n\nfunction tooltipOption(input: PieChartOptionInput): Record<string, unknown> {\n const { theme } = input;\n return {\n trigger: \"item\",\n backgroundColor: theme.tooltipBackgroundColor,\n borderColor: theme.tooltipBorderColor,\n textStyle: { color: theme.labelColor },\n formatter: (params: { data: DataItem }) => params.data.tooltip,\n };\n}\n\nfunction labelFormatter(params: { data: DataItem }): string {\n return params.data.labelText;\n}\n\nfunction holeRadiusPercent(input: PieChartOptionInput): number {\n return input.shape === \"pie\" ? 0 : DONUT_HOLE_RADIUS_PERCENT;\n}\n\nfunction pieRadius(input: PieChartOptionInput): [string, string] {\n if (input.shape === \"pie\") return [\"0%\", `${FULL_PIE_OUTER_RADIUS_PERCENT}%`];\n return [\n `${DONUT_HOLE_RADIUS_PERCENT}%`,\n `${DONUT_HOLE_RADIUS_PERCENT + RING_THICKNESS_PERCENT}%`,\n ];\n}\n\nfunction pieLabel(input: PieChartOptionInput): Record<string, unknown> {\n const show: boolean = input.labelContent.length > 0;\n if (input.shape === \"pie\") {\n return { show, position: \"inside\", formatter: labelFormatter };\n }\n return { show, position: \"outside\", color: input.theme.labelColor, formatter: labelFormatter };\n}\n\nfunction pieSeries(input: PieChartOptionInput): Record<string, unknown> {\n const isFullPie: boolean = input.shape === \"pie\";\n return {\n type: \"pie\",\n radius: pieRadius(input),\n data: input.slices.map((slice: PieSlice) => {\n const { label: fillLabel, ...item } = toDataItem(input, slice, false);\n return isFullPie ? { ...item, label: fillLabel } : item;\n }),\n itemStyle: { borderColor: input.theme.tooltipBackgroundColor, borderWidth: RING_BORDER_WIDTH_PX },\n label: pieLabel(input),\n minShowLabelAngle: isFullPie ? MIN_INSIDE_LABEL_ANGLE_DEGREES : 0,\n labelLine: { show: !isFullPie && input.labelContent.length > 0 },\n labelLayout: { hideOverlap: true },\n emphasis: { scale: false },\n };\n}\n\nfunction sunburstLevels(input: PieChartOptionInput, depth: number): Array<Record<string, unknown>> {\n const hole: number = holeRadiusPercent(input);\n const evenThickness: number = (OUTER_RADIUS_LIMIT_PERCENT - hole) / depth;\n const thickness: number =\n input.shape === \"pie\" ? evenThickness : Math.min(RING_THICKNESS_PERCENT, evenThickness);\n const rings: Array<Record<string, unknown>> = Array.from(\n { length: depth },\n (_unused, ringIndex: number) => ({\n r0: `${hole + thickness * ringIndex}%`,\n r: `${hole + thickness * (ringIndex + 1)}%`,\n }),\n );\n return [{}, ...rings];\n}\n\nfunction sunburstSeries(input: PieChartOptionInput): Record<string, unknown> {\n const hasLabels: boolean = input.labelContent.length > 0;\n return {\n type: \"sunburst\",\n nodeClick: false,\n sort: null,\n radius: [`${holeRadiusPercent(input)}%`, `${OUTER_RADIUS_LIMIT_PERCENT}%`],\n data: input.slices.map((slice: PieSlice) => toDataItem(input, slice, true)),\n levels: sunburstLevels(input, sliceDepth(input.slices)),\n itemStyle: { borderColor: input.theme.tooltipBackgroundColor, borderWidth: RING_BORDER_WIDTH_PX },\n label: {\n show: hasLabels,\n rotate: \"radial\",\n minAngle: MIN_LABELED_ANGLE_DEGREES,\n formatter: labelFormatter,\n },\n emphasis: { focus: \"none\" },\n };\n}\n\nfunction isHierarchical(slices: PieSlice[]): boolean {\n return slices.some((slice: PieSlice) => slice.children.length > 0);\n}\n\nexport function buildPieChartOption(input: PieChartOptionInput): Record<string, unknown> {\n const { theme } = input;\n return {\n animation: false,\n textStyle: { fontFamily: theme.fontFamily, color: theme.labelColor },\n tooltip: tooltipOption(input),\n series: [isHierarchical(input.slices) ? sunburstSeries(input) : pieSeries(input)],\n };\n}\n"],"names":["DONUT_HOLE_RADIUS_PERCENT","FULL_PIE_OUTER_RADIUS_PERCENT","MIN_INSIDE_LABEL_ANGLE_DEGREES","RING_THICKNESS_PERCENT","OUTER_RADIUS_LIMIT_PERCENT","PATH_SEPARATOR","MIN_LABELED_ANGLE_DEGREES","RING_BORDER_WIDTH_PX","formatValue","input","value","escapeHtml","text","labelText","slice","parts","formatShare","tooltipHtml","path","toDataItem","withChildren","labelColorOnFill","child","tooltipOption","theme","params","labelFormatter","holeRadiusPercent","pieRadius","pieLabel","show","pieSeries","isFullPie","fillLabel","item","sunburstLevels","depth","hole","evenThickness","thickness","rings","_unused","ringIndex","sunburstSeries","hasLabels","sliceDepth","isHierarchical","slices","buildPieChartOption"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("react/jsx-runtime"),w=require("../../../../vendor/clsx/dist/clsx.cjs"),c=require("react"),C=require("../chart-palette.cjs"),_=require("../useChartInstance.cjs"),g=require("./top-list-option.cjs");;/* empty css */const x=["value"],q=C.CHART_SERIES_COLOR_TOKENS[0];function M(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}function A(t,u){const a=new Set(t.map(e=>e.id)),o=u.filter(e=>a.has(e)),d=t.map(e=>e.id).filter(e=>!o.includes(e));return[...o,...d]}function j({items:t,sort:u="desc",total:a,valueDisplay:o=x,valueFormatter:d,colorToken:e=q,className:L,...T}){const{containerRef:f,chart:p,theme:l,resolveSeriesColor:h}=_.useChartInstance(),R=c.useRef(!1),v=c.useRef([]),[O,m]=c.useState(0);c.useEffect(()=>{const r=f.current;if(!r)return;const s=new ResizeObserver(()=>m(r.clientHeight));return s.observe(r),()=>s.disconnect()},[f]);const S=O>0,E=g.labeledRowStepFor(O,t.length),I=c.useMemo(()=>{const r=h(e),s=[];return t.forEach(i=>{const n=(i.colorToken?h(i.colorToken):void 0)??r;n&&s.push([i.id,n])}),Object.fromEntries(s)},[t,e,l,h]);return c.useEffect(()=>{if(!p||!l||!S)return;const r=R.current&&!M();v.current=A(t,v.current);const s=new Map(t.map(n=>[n.id,n])),i=v.current.map(n=>s.get(n));p.setOption(g.buildTopListOption({items:i,sort:u,total:a,valueDisplay:o,theme:l,colorsByItemId:I,animate:r,labeledRowStep:E,valueFormatter:d}),{replaceMerge:["series","yAxis"]}),R.current=!0},[p,l,t,u,a,o,I,S,E,d]),b.jsx("div",{className:w.clsx("top-list",L),...T,children:b.jsx("div",{ref:f,className:"top-list__canvas"})})}exports.TopList=j;
2
+ //# sourceMappingURL=TopList.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopList.cjs","sources":["../../../../../../src/ui/components/charts/TopList/TopList.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { type ComponentPropsWithoutRef, useEffect, useMemo, useRef, useState } from \"react\";\nimport { CHART_SERIES_COLOR_TOKENS } from \"../chart-palette\";\nimport { useChartInstance, type ChartInstance } from \"../useChartInstance\";\nimport {\n buildTopListOption,\n labeledRowStepFor,\n type TopListItem,\n type TopListSort,\n type TopListValueDisplay,\n} from \"./top-list-option\";\nimport \"./top-list.css\";\n\nexport type { TopListItem, TopListSort, TopListValueDisplay } from \"./top-list-option\";\n\nexport type TopListProps = Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> & {\n items: TopListItem[];\n sort?: TopListSort;\n total?: number;\n valueDisplay?: TopListValueDisplay[];\n valueFormatter?: (value: number) => string;\n colorToken?: string;\n};\n\nconst DEFAULT_VALUE_DISPLAY: TopListValueDisplay[] = [\"value\"];\n\nconst DEFAULT_COLOR_TOKEN: string = CHART_SERIES_COLOR_TOKENS[0];\n\nfunction prefersReducedMotion(): boolean {\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\nfunction keepFirstSeenOrder(items: TopListItem[], previousOrder: string[]): string[] {\n const currentIds: Set<string> = new Set(items.map((item: TopListItem) => item.id));\n const survivingIds: string[] = previousOrder.filter((id: string) => currentIds.has(id));\n const newIds: string[] = items\n .map((item: TopListItem) => item.id)\n .filter((id: string) => !survivingIds.includes(id));\n return [...survivingIds, ...newIds];\n}\n\nexport function TopList({\n items,\n sort = \"desc\",\n total,\n valueDisplay = DEFAULT_VALUE_DISPLAY,\n valueFormatter,\n colorToken = DEFAULT_COLOR_TOKEN,\n className,\n ...props\n}: TopListProps) {\n const { containerRef, chart, theme, resolveSeriesColor }: ChartInstance = useChartInstance();\n const hasDrawnRef = useRef<boolean>(false);\n const categoryOrderRef = useRef<string[]>([]);\n const [canvasHeightPx, setCanvasHeightPx] = useState<number>(0);\n\n useEffect(() => {\n const canvas: HTMLDivElement | null = containerRef.current;\n if (!canvas) return undefined;\n const observer: ResizeObserver = new ResizeObserver(() => setCanvasHeightPx(canvas.clientHeight));\n observer.observe(canvas);\n return () => observer.disconnect();\n }, [containerRef]);\n\n const isCanvasMeasured: boolean = canvasHeightPx > 0;\n const labeledRowStep: number = labeledRowStepFor(canvasHeightPx, items.length);\n\n const colorsByItemId: Record<string, string> = useMemo(() => {\n const defaultColor: string | undefined = resolveSeriesColor(colorToken);\n const entries: Array<[string, string]> = [];\n items.forEach((item: TopListItem) => {\n const color: string | undefined =\n (item.colorToken ? resolveSeriesColor(item.colorToken) : undefined) ?? defaultColor;\n if (color) entries.push([item.id, color]);\n });\n return Object.fromEntries(entries);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [items, colorToken, theme, resolveSeriesColor]);\n\n useEffect(() => {\n if (!chart || !theme || !isCanvasMeasured) return;\n const animate: boolean = hasDrawnRef.current && !prefersReducedMotion();\n categoryOrderRef.current = keepFirstSeenOrder(items, categoryOrderRef.current);\n const itemsById: Map<string, TopListItem> = new Map(\n items.map((item: TopListItem) => [item.id, item]),\n );\n const stableItems: TopListItem[] = categoryOrderRef.current.map(\n (id: string) => itemsById.get(id) as TopListItem,\n );\n chart.setOption(\n buildTopListOption({\n items: stableItems,\n sort,\n total,\n valueDisplay,\n theme,\n colorsByItemId,\n animate,\n labeledRowStep,\n valueFormatter,\n }),\n { replaceMerge: [\"series\", \"yAxis\"] },\n );\n hasDrawnRef.current = true;\n }, [\n chart,\n theme,\n items,\n sort,\n total,\n valueDisplay,\n colorsByItemId,\n isCanvasMeasured,\n labeledRowStep,\n valueFormatter,\n ]);\n\n return (\n <div className={clsx(\"top-list\", className)} {...props}>\n <div ref={containerRef} className=\"top-list__canvas\" />\n </div>\n );\n}\n"],"names":["DEFAULT_VALUE_DISPLAY","DEFAULT_COLOR_TOKEN","CHART_SERIES_COLOR_TOKENS","prefersReducedMotion","keepFirstSeenOrder","items","previousOrder","currentIds","item","survivingIds","id","newIds","TopList","sort","total","valueDisplay","valueFormatter","colorToken","className","props","containerRef","chart","theme","resolveSeriesColor","useChartInstance","hasDrawnRef","useRef","categoryOrderRef","canvasHeightPx","setCanvasHeightPx","useState","useEffect","canvas","observer","isCanvasMeasured","labeledRowStep","labeledRowStepFor","colorsByItemId","useMemo","defaultColor","entries","color","animate","itemsById","stableItems","buildTopListOption","jsx","clsx"],"mappings":"mUAwBA,MAAMA,EAA+C,CAAC,OAAO,EAEvDC,EAA8BC,EAAAA,0BAA0B,CAAC,EAE/D,SAASC,GAAgC,CACvC,OAAO,OAAO,WAAW,kCAAkC,EAAE,OAC/D,CAEA,SAASC,EAAmBC,EAAsBC,EAAmC,CACnF,MAAMC,EAA0B,IAAI,IAAIF,EAAM,IAAKG,GAAsBA,EAAK,EAAE,CAAC,EAC3EC,EAAyBH,EAAc,OAAQI,GAAeH,EAAW,IAAIG,CAAE,CAAC,EAChFC,EAAmBN,EACtB,IAAKG,GAAsBA,EAAK,EAAE,EAClC,OAAQE,GAAe,CAACD,EAAa,SAASC,CAAE,CAAC,EACpD,MAAO,CAAC,GAAGD,EAAc,GAAGE,CAAM,CACpC,CAEO,SAASC,EAAQ,CACtB,MAAAP,EACA,KAAAQ,EAAO,OACP,MAAAC,EACA,aAAAC,EAAef,EACf,eAAAgB,EACA,WAAAC,EAAahB,EACb,UAAAiB,EACA,GAAGC,CACL,EAAiB,CACf,KAAM,CAAE,aAAAC,EAAc,MAAAC,EAAO,MAAAC,EAAO,mBAAAC,CAAA,EAAsCC,EAAAA,iBAAA,EACpEC,EAAcC,EAAAA,OAAgB,EAAK,EACnCC,EAAmBD,EAAAA,OAAiB,EAAE,EACtC,CAACE,EAAgBC,CAAiB,EAAIC,EAAAA,SAAiB,CAAC,EAE9DC,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAgCZ,EAAa,QACnD,GAAI,CAACY,EAAQ,OACb,MAAMC,EAA2B,IAAI,eAAe,IAAMJ,EAAkBG,EAAO,YAAY,CAAC,EAChG,OAAAC,EAAS,QAAQD,CAAM,EAChB,IAAMC,EAAS,WAAA,CACxB,EAAG,CAACb,CAAY,CAAC,EAEjB,MAAMc,EAA4BN,EAAiB,EAC7CO,EAAyBC,EAAAA,kBAAkBR,EAAgBvB,EAAM,MAAM,EAEvEgC,EAAyCC,EAAAA,QAAQ,IAAM,CAC3D,MAAMC,EAAmChB,EAAmBN,CAAU,EAChEuB,EAAmC,CAAA,EACzC,OAAAnC,EAAM,QAASG,GAAsB,CACnC,MAAMiC,GACHjC,EAAK,WAAae,EAAmBf,EAAK,UAAU,EAAI,SAAc+B,EACrEE,GAAOD,EAAQ,KAAK,CAAChC,EAAK,GAAIiC,CAAK,CAAC,CAC1C,CAAC,EACM,OAAO,YAAYD,CAAO,CAEnC,EAAG,CAACnC,EAAOY,EAAYK,EAAOC,CAAkB,CAAC,EAEjDQ,OAAAA,EAAAA,UAAU,IAAM,CACd,GAAI,CAACV,GAAS,CAACC,GAAS,CAACY,EAAkB,OAC3C,MAAMQ,EAAmBjB,EAAY,SAAW,CAACtB,EAAA,EACjDwB,EAAiB,QAAUvB,EAAmBC,EAAOsB,EAAiB,OAAO,EAC7E,MAAMgB,EAAsC,IAAI,IAC9CtC,EAAM,IAAKG,GAAsB,CAACA,EAAK,GAAIA,CAAI,CAAC,CAAA,EAE5CoC,EAA6BjB,EAAiB,QAAQ,IACzDjB,GAAeiC,EAAU,IAAIjC,CAAE,CAAA,EAElCW,EAAM,UACJwB,qBAAmB,CACjB,MAAOD,EACP,KAAA/B,EACA,MAAAC,EACA,aAAAC,EACA,MAAAO,EACA,eAAAe,EACA,QAAAK,EACA,eAAAP,EACA,eAAAnB,CAAA,CACD,EACD,CAAE,aAAc,CAAC,SAAU,OAAO,CAAA,CAAE,EAEtCS,EAAY,QAAU,EACxB,EAAG,CACDJ,EACAC,EACAjB,EACAQ,EACAC,EACAC,EACAsB,EACAH,EACAC,EACAnB,CAAA,CACD,EAGC8B,EAAAA,IAAC,MAAA,CAAI,UAAWC,EAAAA,KAAK,WAAY7B,CAAS,EAAI,GAAGC,EAC/C,eAAC,MAAA,CAAI,IAAKC,EAAc,UAAU,mBAAmB,EACvD,CAEJ"}
@@ -0,0 +1,79 @@
1
+ import { jsx as I } from "react/jsx-runtime";
2
+ import { clsx as C } from "../../../../vendor/clsx/dist/clsx.js";
3
+ import { useRef as S, useState as L, useEffect as w, useMemo as T } from "react";
4
+ import { CHART_SERIES_COLOR_TOKENS as x } from "../chart-palette.js";
5
+ import { useChartInstance as A } from "../useChartInstance.js";
6
+ import { labeledRowStepFor as M, buildTopListOption as H } from "./top-list-option.js";
7
+ /* empty css */
8
+ const N = ["value"], y = x[0];
9
+ function D() {
10
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
11
+ }
12
+ function F(r, i) {
13
+ const a = new Set(r.map((e) => e.id)), s = i.filter((e) => a.has(e)), d = r.map((e) => e.id).filter((e) => !s.includes(e));
14
+ return [...s, ...d];
15
+ }
16
+ function V({
17
+ items: r,
18
+ sort: i = "desc",
19
+ total: a,
20
+ valueDisplay: s = N,
21
+ valueFormatter: d,
22
+ colorToken: e = y,
23
+ className: _,
24
+ ...b
25
+ }) {
26
+ const { containerRef: f, chart: p, theme: u, resolveSeriesColor: l } = A(), h = S(!1), m = S([]), [v, g] = L(0);
27
+ w(() => {
28
+ const t = f.current;
29
+ if (!t) return;
30
+ const n = new ResizeObserver(() => g(t.clientHeight));
31
+ return n.observe(t), () => n.disconnect();
32
+ }, [f]);
33
+ const O = v > 0, R = M(v, r.length), E = T(() => {
34
+ const t = l(e), n = [];
35
+ return r.forEach((c) => {
36
+ const o = (c.colorToken ? l(c.colorToken) : void 0) ?? t;
37
+ o && n.push([c.id, o]);
38
+ }), Object.fromEntries(n);
39
+ }, [r, e, u, l]);
40
+ return w(() => {
41
+ if (!p || !u || !O) return;
42
+ const t = h.current && !D();
43
+ m.current = F(r, m.current);
44
+ const n = new Map(
45
+ r.map((o) => [o.id, o])
46
+ ), c = m.current.map(
47
+ (o) => n.get(o)
48
+ );
49
+ p.setOption(
50
+ H({
51
+ items: c,
52
+ sort: i,
53
+ total: a,
54
+ valueDisplay: s,
55
+ theme: u,
56
+ colorsByItemId: E,
57
+ animate: t,
58
+ labeledRowStep: R,
59
+ valueFormatter: d
60
+ }),
61
+ { replaceMerge: ["series", "yAxis"] }
62
+ ), h.current = !0;
63
+ }, [
64
+ p,
65
+ u,
66
+ r,
67
+ i,
68
+ a,
69
+ s,
70
+ E,
71
+ O,
72
+ R,
73
+ d
74
+ ]), /* @__PURE__ */ I("div", { className: C("top-list", _), ...b, children: /* @__PURE__ */ I("div", { ref: f, className: "top-list__canvas" }) });
75
+ }
76
+ export {
77
+ V as TopList
78
+ };
79
+ //# sourceMappingURL=TopList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopList.js","sources":["../../../../../../src/ui/components/charts/TopList/TopList.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { type ComponentPropsWithoutRef, useEffect, useMemo, useRef, useState } from \"react\";\nimport { CHART_SERIES_COLOR_TOKENS } from \"../chart-palette\";\nimport { useChartInstance, type ChartInstance } from \"../useChartInstance\";\nimport {\n buildTopListOption,\n labeledRowStepFor,\n type TopListItem,\n type TopListSort,\n type TopListValueDisplay,\n} from \"./top-list-option\";\nimport \"./top-list.css\";\n\nexport type { TopListItem, TopListSort, TopListValueDisplay } from \"./top-list-option\";\n\nexport type TopListProps = Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> & {\n items: TopListItem[];\n sort?: TopListSort;\n total?: number;\n valueDisplay?: TopListValueDisplay[];\n valueFormatter?: (value: number) => string;\n colorToken?: string;\n};\n\nconst DEFAULT_VALUE_DISPLAY: TopListValueDisplay[] = [\"value\"];\n\nconst DEFAULT_COLOR_TOKEN: string = CHART_SERIES_COLOR_TOKENS[0];\n\nfunction prefersReducedMotion(): boolean {\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\nfunction keepFirstSeenOrder(items: TopListItem[], previousOrder: string[]): string[] {\n const currentIds: Set<string> = new Set(items.map((item: TopListItem) => item.id));\n const survivingIds: string[] = previousOrder.filter((id: string) => currentIds.has(id));\n const newIds: string[] = items\n .map((item: TopListItem) => item.id)\n .filter((id: string) => !survivingIds.includes(id));\n return [...survivingIds, ...newIds];\n}\n\nexport function TopList({\n items,\n sort = \"desc\",\n total,\n valueDisplay = DEFAULT_VALUE_DISPLAY,\n valueFormatter,\n colorToken = DEFAULT_COLOR_TOKEN,\n className,\n ...props\n}: TopListProps) {\n const { containerRef, chart, theme, resolveSeriesColor }: ChartInstance = useChartInstance();\n const hasDrawnRef = useRef<boolean>(false);\n const categoryOrderRef = useRef<string[]>([]);\n const [canvasHeightPx, setCanvasHeightPx] = useState<number>(0);\n\n useEffect(() => {\n const canvas: HTMLDivElement | null = containerRef.current;\n if (!canvas) return undefined;\n const observer: ResizeObserver = new ResizeObserver(() => setCanvasHeightPx(canvas.clientHeight));\n observer.observe(canvas);\n return () => observer.disconnect();\n }, [containerRef]);\n\n const isCanvasMeasured: boolean = canvasHeightPx > 0;\n const labeledRowStep: number = labeledRowStepFor(canvasHeightPx, items.length);\n\n const colorsByItemId: Record<string, string> = useMemo(() => {\n const defaultColor: string | undefined = resolveSeriesColor(colorToken);\n const entries: Array<[string, string]> = [];\n items.forEach((item: TopListItem) => {\n const color: string | undefined =\n (item.colorToken ? resolveSeriesColor(item.colorToken) : undefined) ?? defaultColor;\n if (color) entries.push([item.id, color]);\n });\n return Object.fromEntries(entries);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [items, colorToken, theme, resolveSeriesColor]);\n\n useEffect(() => {\n if (!chart || !theme || !isCanvasMeasured) return;\n const animate: boolean = hasDrawnRef.current && !prefersReducedMotion();\n categoryOrderRef.current = keepFirstSeenOrder(items, categoryOrderRef.current);\n const itemsById: Map<string, TopListItem> = new Map(\n items.map((item: TopListItem) => [item.id, item]),\n );\n const stableItems: TopListItem[] = categoryOrderRef.current.map(\n (id: string) => itemsById.get(id) as TopListItem,\n );\n chart.setOption(\n buildTopListOption({\n items: stableItems,\n sort,\n total,\n valueDisplay,\n theme,\n colorsByItemId,\n animate,\n labeledRowStep,\n valueFormatter,\n }),\n { replaceMerge: [\"series\", \"yAxis\"] },\n );\n hasDrawnRef.current = true;\n }, [\n chart,\n theme,\n items,\n sort,\n total,\n valueDisplay,\n colorsByItemId,\n isCanvasMeasured,\n labeledRowStep,\n valueFormatter,\n ]);\n\n return (\n <div className={clsx(\"top-list\", className)} {...props}>\n <div ref={containerRef} className=\"top-list__canvas\" />\n </div>\n );\n}\n"],"names":["DEFAULT_VALUE_DISPLAY","DEFAULT_COLOR_TOKEN","CHART_SERIES_COLOR_TOKENS","prefersReducedMotion","keepFirstSeenOrder","items","previousOrder","currentIds","item","survivingIds","id","newIds","TopList","sort","total","valueDisplay","valueFormatter","colorToken","className","props","containerRef","chart","theme","resolveSeriesColor","useChartInstance","hasDrawnRef","useRef","categoryOrderRef","canvasHeightPx","setCanvasHeightPx","useState","useEffect","canvas","observer","isCanvasMeasured","labeledRowStep","labeledRowStepFor","colorsByItemId","useMemo","defaultColor","entries","color","animate","itemsById","stableItems","buildTopListOption","jsx","clsx"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("../chart-share.cjs");require("echarts/charts");require("echarts/components");const L=require("echarts/core");require("echarts/renderers");function M(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const o=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,o.get?o:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const B=M(L),h="–",b=160,E=12,O=88,w=56,c=16,C=20,p=4,S=8,T=800,f=12,V=14,N=1e-9,X=/[{}|]/g,k="top-list-values";function u(e){return e.value??0}function v(e){const t=Math.max(...e.map(u));return t>0?t:1}function U(e){const t=[...new Set(e.map(u))].sort((o,r)=>o-r),n=t.slice(1).map((o,r)=>o-t[r]);return n.length>0?Math.min(...n):1/0}function F(e){const t=v(e)*N,n=U(e)/(e.length+1);return Math.min(t,n)}function y(e){const t=F(e);return new Map(e.map((n,o)=>[n.id,u(n)+t*(e.length-o)]))}function m(e,t){const n=y(e),o=t==="desc"?-1:1,r=[...e].sort((a,i)=>o*(n.get(a.id)-n.get(i.id)));return new Map(r.map((a,i)=>[a.id,i+1]))}function A(e,t){return t??e.reduce((n,o)=>n+u(o),0)}function x(e,t){return t===0?0:u(e)/t}function g(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function D(e){return e.replace(X," ")}function H(e,t){const n=`${f}px ${t.fontFamily}`;return D(B.format.truncateText(e,b,n,"…"))}function I(e,t){return t===null?h:e.valueFormatter?e.valueFormatter(t):String(t)}function W(e,t){return e.value===null?h:_.formatShare(x(e,t))}function $(e){const t=[];return e.includes("value")&&t.push(O),e.includes("percent")&&t.push(w),t.length===0?0:t.reduce((n,o)=>n+o,0)+S}function j(e,t,n){const o=[];return e.valueDisplay.includes("value")&&o.push(`{value|${D(I(e,t.value))}}`),e.valueDisplay.includes("percent")&&o.push(`{percent|${W(t,n)}}`),o.join("")}function q(e,t){const n=(e-2*c)/t;return Math.max(1,Math.ceil(V/n))}function P(e,t){return e===void 0||(e-1)%t===0}function G(e,t){const{items:n,sort:o,theme:r}=e,a=m(n,o),i=e.labeledRowStep;return{type:"category",data:n.map(l=>l.id),inverse:o==="desc",animationDuration:0,animationDurationUpdate:e.animate?T:0,axisLine:{show:!1},axisTick:{show:!1},axisLabel:{color:r.labelColor,fontSize:f,interval:0,align:"right",margin:E,formatter:l=>{if(!P(a.get(l),i))return"";const d=t.get(l);return d?H(d.name,r):""}}}}function z(e,t,n){return o=>{const r=t.get(o.name);if(!r)return"";const a=r.value===null?"":` · ${_.formatShare(x(r,n))}`,i=g(I(e,r.value));return`<div>${g(r.name)}</div><div><b>${i}</b>${a}</div>`}}function K(e,t,n){const{theme:o}=e,r=m(e.items,e.sort),a=e.labeledRowStep;return{show:e.valueDisplay.length>0,position:"right",distance:S,fontSize:f,formatter:i=>{if(!P(r.get(i.name),a))return"";const l=t.get(i.name);return l?j(e,l,n):""},rich:{value:{color:o.labelColor,fontWeight:600,padding:[0,8,0,0]},percent:{color:o.labelColor}}}}function Y(e){const{items:t,theme:n,colorsByItemId:o}=e,r=new Map(t.map(s=>[s.id,s])),a=A(t,e.total),i=v(t),l=y(t),d=$(e.valueDisplay),R=n.seriesColors[0];return{animation:!0,animationDuration:0,animationDurationUpdate:e.animate?T:0,animationEasing:"linear",animationEasingUpdate:"linear",textStyle:{fontFamily:n.fontFamily,color:n.labelColor},grid:{top:c,bottom:c,left:c+b+E,right:c+d,containLabel:!1},tooltip:{trigger:"item",backgroundColor:n.tooltipBackgroundColor,borderColor:n.tooltipBorderColor,textStyle:{color:n.labelColor},formatter:z(e,r,a)},xAxis:{type:"value",min:0,max:i,show:!1},yAxis:G(e,r),series:[{id:k,type:"bar",realtimeSort:!0,barMaxWidth:C,itemStyle:{borderRadius:[0,p,p,0]},data:t.map(s=>({id:s.id,name:s.id,value:[l.get(s.id),s.id],itemStyle:{color:o[s.id]??R}})),encode:{x:0,y:1},label:K(e,r,a)}]}}exports.buildTopListOption=Y;exports.labeledRowStepFor=q;exports.rankById=m;exports.resolveTotal=A;
2
+ //# sourceMappingURL=top-list-option.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top-list-option.cjs","sources":["../../../../../../src/ui/components/charts/TopList/top-list-option.ts"],"sourcesContent":["import { formatShare } from \"../chart-share\";\nimport { echarts } from \"../echarts-modules\";\nimport type { ChartTheme } from \"../chart-theme\";\n\nexport interface TopListItem {\n id: string;\n name: string;\n value: number | null;\n colorToken?: string;\n}\n\nexport type TopListSort = \"desc\" | \"asc\";\n\nexport type TopListValueDisplay = \"value\" | \"percent\";\n\nexport interface TopListOptionInput {\n items: TopListItem[];\n sort: TopListSort;\n total?: number;\n valueDisplay: TopListValueDisplay[];\n theme: ChartTheme;\n colorsByItemId: Record<string, string>;\n animate: boolean;\n labeledRowStep: number;\n valueFormatter?: (value: number) => string;\n}\n\nconst EMPTY_VALUE_TEXT: string = \"–\";\n\nconst NAME_MAX_WIDTH_PX: number = 160;\n\nconst NAME_TO_BAR_GAP_PX: number = 12;\n\nconst VALUE_COLUMN_WIDTH_PX: number = 88;\n\nconst PERCENT_COLUMN_WIDTH_PX: number = 56;\n\nconst GRID_PADDING_PX: number = 16;\n\nconst BAR_MAX_WIDTH_PX: number = 20;\n\nconst BAR_RADIUS_PX: number = 4;\n\nconst BAR_END_LABEL_DISTANCE_PX: number = 8;\n\nconst UPDATE_ANIMATION_MS: number = 800;\n\nconst LABEL_FONT_SIZE_PX: number = 12;\n\nconst MIN_LABELED_ROW_HEIGHT_PX: number = 14;\n\nconst TIE_BREAK_RELATIVE_STEP: number = 1e-9;\n\nconst RICH_TEXT_RESERVED: RegExp = /[{}|]/g;\n\nconst VALUE_SERIES_ID: string = \"top-list-values\";\n\n\nfunction valueOf(item: TopListItem): number {\n return item.value ?? 0;\n}\n\nfunction maxValueOf(items: TopListItem[]): number {\n const maxValue: number = Math.max(...items.map(valueOf));\n return maxValue > 0 ? maxValue : 1;\n}\n\nfunction smallestGapBetweenDistinctValues(items: TopListItem[]): number {\n const distinctValues: number[] = [...new Set(items.map(valueOf))].sort(\n (first: number, second: number) => first - second,\n );\n const gaps: number[] = distinctValues\n .slice(1)\n .map((value: number, index: number) => value - distinctValues[index]);\n return gaps.length > 0 ? Math.min(...gaps) : Infinity;\n}\n\nfunction tieBreakStepOf(items: TopListItem[]): number {\n const relativeStep: number = maxValueOf(items) * TIE_BREAK_RELATIVE_STEP;\n const stepThatKeepsDistinctValuesApart: number =\n smallestGapBetweenDistinctValues(items) / (items.length + 1);\n return Math.min(relativeStep, stepThatKeepsDistinctValuesApart);\n}\n\nfunction plottedValuesById(items: TopListItem[]): Map<string, number> {\n const tieBreakStep: number = tieBreakStepOf(items);\n return new Map(\n items.map((item: TopListItem, position: number) => [\n item.id,\n valueOf(item) + tieBreakStep * (items.length - position),\n ]),\n );\n}\n\nexport function rankById(items: TopListItem[], sort: TopListSort): Map<string, number> {\n const plottedValues: Map<string, number> = plottedValuesById(items);\n const direction: number = sort === \"desc\" ? -1 : 1;\n const ranked: TopListItem[] = [...items].sort(\n (first: TopListItem, second: TopListItem) =>\n direction * ((plottedValues.get(first.id) as number) - (plottedValues.get(second.id) as number)),\n );\n return new Map(ranked.map((item: TopListItem, index: number) => [item.id, index + 1]));\n}\n\nexport function resolveTotal(items: TopListItem[], total?: number): number {\n return total ?? items.reduce((sum: number, item: TopListItem) => sum + valueOf(item), 0);\n}\n\nfunction shareOf(item: TopListItem, total: number): number {\n return total === 0 ? 0 : valueOf(item) / total;\n}\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nfunction plainRichText(text: string): string {\n return text.replace(RICH_TEXT_RESERVED, \" \");\n}\n\nfunction truncatedName(name: string, theme: ChartTheme): string {\n const font: string = `${LABEL_FONT_SIZE_PX}px ${theme.fontFamily}`;\n return plainRichText(echarts.format.truncateText(name, NAME_MAX_WIDTH_PX, font, \"…\"));\n}\n\nfunction formatValueText(input: TopListOptionInput, value: number | null): string {\n if (value === null) return EMPTY_VALUE_TEXT;\n return input.valueFormatter ? input.valueFormatter(value) : String(value);\n}\n\nfunction formatShareText(item: TopListItem, total: number): string {\n return item.value === null ? EMPTY_VALUE_TEXT : formatShare(shareOf(item, total));\n}\n\nfunction barEndLabelWidthPx(valueDisplay: TopListValueDisplay[]): number {\n const widths: number[] = [];\n if (valueDisplay.includes(\"value\")) widths.push(VALUE_COLUMN_WIDTH_PX);\n if (valueDisplay.includes(\"percent\")) widths.push(PERCENT_COLUMN_WIDTH_PX);\n if (widths.length === 0) return 0;\n return widths.reduce((sum: number, width: number) => sum + width, 0) + BAR_END_LABEL_DISTANCE_PX;\n}\n\nfunction barEndLabelText(input: TopListOptionInput, item: TopListItem, total: number): string {\n const parts: string[] = [];\n if (input.valueDisplay.includes(\"value\")) {\n parts.push(`{value|${plainRichText(formatValueText(input, item.value))}}`);\n }\n if (input.valueDisplay.includes(\"percent\")) {\n parts.push(`{percent|${formatShareText(item, total)}}`);\n }\n return parts.join(\"\");\n}\n\nexport function labeledRowStepFor(canvasHeightPx: number, itemCount: number): number {\n const rowHeightPx: number = (canvasHeightPx - 2 * GRID_PADDING_PX) / itemCount;\n return Math.max(1, Math.ceil(MIN_LABELED_ROW_HEIGHT_PX / rowHeightPx));\n}\n\nfunction isRowLabeled(rank: number | undefined, step: number): boolean {\n return rank === undefined || (rank - 1) % step === 0;\n}\n\nfunction categoryAxis(\n input: TopListOptionInput,\n itemsById: Map<string, TopListItem>,\n): Record<string, unknown> {\n const { items, sort, theme } = input;\n const ranks: Map<string, number> = rankById(items, sort);\n const step: number = input.labeledRowStep;\n return {\n type: \"category\",\n data: items.map((item: TopListItem) => item.id),\n inverse: sort === \"desc\",\n animationDuration: 0,\n animationDurationUpdate: input.animate ? UPDATE_ANIMATION_MS : 0,\n axisLine: { show: false },\n axisTick: { show: false },\n axisLabel: {\n color: theme.labelColor,\n fontSize: LABEL_FONT_SIZE_PX,\n interval: 0,\n align: \"right\",\n margin: NAME_TO_BAR_GAP_PX,\n formatter: (id: string) => {\n if (!isRowLabeled(ranks.get(id), step)) return \"\";\n const item: TopListItem | undefined = itemsById.get(id);\n return item ? truncatedName(item.name, theme) : \"\";\n },\n },\n };\n}\n\nfunction tooltipFormatter(\n input: TopListOptionInput,\n itemsById: Map<string, TopListItem>,\n total: number,\n): (params: { name: string }) => string {\n return (params: { name: string }) => {\n const item: TopListItem | undefined = itemsById.get(params.name);\n if (!item) return \"\";\n const share: string = item.value === null ? \"\" : ` · ${formatShare(shareOf(item, total))}`;\n const value: string = escapeHtml(formatValueText(input, item.value));\n return `<div>${escapeHtml(item.name)}</div><div><b>${value}</b>${share}</div>`;\n };\n}\n\nfunction barEndLabel(\n input: TopListOptionInput,\n itemsById: Map<string, TopListItem>,\n total: number,\n): Record<string, unknown> {\n const { theme } = input;\n const ranks: Map<string, number> = rankById(input.items, input.sort);\n const step: number = input.labeledRowStep;\n return {\n show: input.valueDisplay.length > 0,\n position: \"right\",\n distance: BAR_END_LABEL_DISTANCE_PX,\n fontSize: LABEL_FONT_SIZE_PX,\n formatter: (params: { name: string }) => {\n if (!isRowLabeled(ranks.get(params.name), step)) return \"\";\n const item: TopListItem | undefined = itemsById.get(params.name);\n return item ? barEndLabelText(input, item, total) : \"\";\n },\n rich: {\n value: { color: theme.labelColor, fontWeight: 600, padding: [0, 8, 0, 0] },\n percent: { color: theme.labelColor },\n },\n };\n}\n\nexport function buildTopListOption(input: TopListOptionInput): Record<string, unknown> {\n const { items, theme, colorsByItemId } = input;\n const itemsById: Map<string, TopListItem> = new Map(\n items.map((item: TopListItem) => [item.id, item]),\n );\n const total: number = resolveTotal(items, input.total);\n const maxValue: number = maxValueOf(items);\n const plottedValues: Map<string, number> = plottedValuesById(items);\n const reservedRightPx: number = barEndLabelWidthPx(input.valueDisplay);\n const fallbackColor: string = theme.seriesColors[0];\n \n return {\n animation: true,\n animationDuration: 0,\n animationDurationUpdate: input.animate ? UPDATE_ANIMATION_MS : 0,\n animationEasing: \"linear\",\n animationEasingUpdate: \"linear\",\n textStyle: { fontFamily: theme.fontFamily, color: theme.labelColor },\n grid: {\n top: GRID_PADDING_PX,\n bottom: GRID_PADDING_PX,\n left: GRID_PADDING_PX + NAME_MAX_WIDTH_PX + NAME_TO_BAR_GAP_PX,\n right: GRID_PADDING_PX + reservedRightPx,\n containLabel: false,\n },\n tooltip: {\n trigger: \"item\",\n backgroundColor: theme.tooltipBackgroundColor,\n borderColor: theme.tooltipBorderColor,\n textStyle: { color: theme.labelColor },\n formatter: tooltipFormatter(input, itemsById, total),\n },\n xAxis: { type: \"value\", min: 0, max: maxValue, show: false },\n yAxis: categoryAxis(input, itemsById),\n series: [\n {\n id: VALUE_SERIES_ID,\n type: \"bar\",\n realtimeSort: true,\n barMaxWidth: BAR_MAX_WIDTH_PX,\n itemStyle: { borderRadius: [0, BAR_RADIUS_PX, BAR_RADIUS_PX, 0] },\n data: items.map((item: TopListItem) => ({\n id: item.id,\n name: item.id,\n value: [plottedValues.get(item.id) as number, item.id],\n itemStyle: { color: colorsByItemId[item.id] ?? fallbackColor },\n })),\n encode: { x: 0, y: 1 },\n label: barEndLabel(input, itemsById, total),\n },\n ],\n };\n}\n"],"names":["EMPTY_VALUE_TEXT","NAME_MAX_WIDTH_PX","NAME_TO_BAR_GAP_PX","VALUE_COLUMN_WIDTH_PX","PERCENT_COLUMN_WIDTH_PX","GRID_PADDING_PX","BAR_MAX_WIDTH_PX","BAR_RADIUS_PX","BAR_END_LABEL_DISTANCE_PX","UPDATE_ANIMATION_MS","LABEL_FONT_SIZE_PX","MIN_LABELED_ROW_HEIGHT_PX","TIE_BREAK_RELATIVE_STEP","RICH_TEXT_RESERVED","VALUE_SERIES_ID","valueOf","item","maxValueOf","items","maxValue","smallestGapBetweenDistinctValues","distinctValues","first","second","gaps","value","index","tieBreakStepOf","relativeStep","stepThatKeepsDistinctValuesApart","plottedValuesById","tieBreakStep","position","rankById","sort","plottedValues","direction","ranked","resolveTotal","total","sum","shareOf","escapeHtml","text","plainRichText","truncatedName","name","theme","font","echarts","formatValueText","input","formatShareText","formatShare","barEndLabelWidthPx","valueDisplay","widths","width","barEndLabelText","parts","labeledRowStepFor","canvasHeightPx","itemCount","rowHeightPx","isRowLabeled","rank","step","categoryAxis","itemsById","ranks","id","tooltipFormatter","params","share","barEndLabel","buildTopListOption","colorsByItemId","reservedRightPx","fallbackColor"],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ import { formatShare as _ } from "../chart-share.js";
2
+ import "echarts/charts";
3
+ import "echarts/components";
4
+ import * as L from "echarts/core";
5
+ import "echarts/renderers";
6
+ const g = "–", h = 160, E = 12, M = 88, P = 56, c = 16, B = 20, f = 4, b = 8, T = 800, m = 12, C = 14, w = 1e-9, V = /[{}|]/g, X = "top-list-values";
7
+ function u(t) {
8
+ return t.value ?? 0;
9
+ }
10
+ function v(t) {
11
+ const e = Math.max(...t.map(u));
12
+ return e > 0 ? e : 1;
13
+ }
14
+ function N(t) {
15
+ const e = [...new Set(t.map(u))].sort(
16
+ (o, a) => o - a
17
+ ), n = e.slice(1).map((o, a) => o - e[a]);
18
+ return n.length > 0 ? Math.min(...n) : 1 / 0;
19
+ }
20
+ function O(t) {
21
+ const e = v(t) * w, n = N(t) / (t.length + 1);
22
+ return Math.min(e, n);
23
+ }
24
+ function x(t) {
25
+ const e = O(t);
26
+ return new Map(
27
+ t.map((n, o) => [
28
+ n.id,
29
+ u(n) + e * (t.length - o)
30
+ ])
31
+ );
32
+ }
33
+ function A(t, e) {
34
+ const n = x(t), o = e === "desc" ? -1 : 1, a = [...t].sort(
35
+ (r, i) => o * (n.get(r.id) - n.get(i.id))
36
+ );
37
+ return new Map(a.map((r, i) => [r.id, i + 1]));
38
+ }
39
+ function U(t, e) {
40
+ return e ?? t.reduce((n, o) => n + u(o), 0);
41
+ }
42
+ function S(t, e) {
43
+ return e === 0 ? 0 : u(t) / e;
44
+ }
45
+ function p(t) {
46
+ return t.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
47
+ }
48
+ function I(t) {
49
+ return t.replace(V, " ");
50
+ }
51
+ function k(t, e) {
52
+ const n = `${m}px ${e.fontFamily}`;
53
+ return I(L.format.truncateText(t, h, n, "…"));
54
+ }
55
+ function D(t, e) {
56
+ return e === null ? g : t.valueFormatter ? t.valueFormatter(e) : String(e);
57
+ }
58
+ function H(t, e) {
59
+ return t.value === null ? g : _(S(t, e));
60
+ }
61
+ function F(t) {
62
+ const e = [];
63
+ return t.includes("value") && e.push(M), t.includes("percent") && e.push(P), e.length === 0 ? 0 : e.reduce((n, o) => n + o, 0) + b;
64
+ }
65
+ function W(t, e, n) {
66
+ const o = [];
67
+ return t.valueDisplay.includes("value") && o.push(`{value|${I(D(t, e.value))}}`), t.valueDisplay.includes("percent") && o.push(`{percent|${H(e, n)}}`), o.join("");
68
+ }
69
+ function q(t, e) {
70
+ const n = (t - 2 * c) / e;
71
+ return Math.max(1, Math.ceil(C / n));
72
+ }
73
+ function y(t, e) {
74
+ return t === void 0 || (t - 1) % e === 0;
75
+ }
76
+ function $(t, e) {
77
+ const { items: n, sort: o, theme: a } = t, r = A(n, o), i = t.labeledRowStep;
78
+ return {
79
+ type: "category",
80
+ data: n.map((l) => l.id),
81
+ inverse: o === "desc",
82
+ animationDuration: 0,
83
+ animationDurationUpdate: t.animate ? T : 0,
84
+ axisLine: { show: !1 },
85
+ axisTick: { show: !1 },
86
+ axisLabel: {
87
+ color: a.labelColor,
88
+ fontSize: m,
89
+ interval: 0,
90
+ align: "right",
91
+ margin: E,
92
+ formatter: (l) => {
93
+ if (!y(r.get(l), i)) return "";
94
+ const d = e.get(l);
95
+ return d ? k(d.name, a) : "";
96
+ }
97
+ }
98
+ };
99
+ }
100
+ function G(t, e, n) {
101
+ return (o) => {
102
+ const a = e.get(o.name);
103
+ if (!a) return "";
104
+ const r = a.value === null ? "" : ` · ${_(S(a, n))}`, i = p(D(t, a.value));
105
+ return `<div>${p(a.name)}</div><div><b>${i}</b>${r}</div>`;
106
+ };
107
+ }
108
+ function z(t, e, n) {
109
+ const { theme: o } = t, a = A(t.items, t.sort), r = t.labeledRowStep;
110
+ return {
111
+ show: t.valueDisplay.length > 0,
112
+ position: "right",
113
+ distance: b,
114
+ fontSize: m,
115
+ formatter: (i) => {
116
+ if (!y(a.get(i.name), r)) return "";
117
+ const l = e.get(i.name);
118
+ return l ? W(t, l, n) : "";
119
+ },
120
+ rich: {
121
+ value: { color: o.labelColor, fontWeight: 600, padding: [0, 8, 0, 0] },
122
+ percent: { color: o.labelColor }
123
+ }
124
+ };
125
+ }
126
+ function J(t) {
127
+ const { items: e, theme: n, colorsByItemId: o } = t, a = new Map(
128
+ e.map((s) => [s.id, s])
129
+ ), r = U(e, t.total), i = v(e), l = x(e), d = F(t.valueDisplay), R = n.seriesColors[0];
130
+ return {
131
+ animation: !0,
132
+ animationDuration: 0,
133
+ animationDurationUpdate: t.animate ? T : 0,
134
+ animationEasing: "linear",
135
+ animationEasingUpdate: "linear",
136
+ textStyle: { fontFamily: n.fontFamily, color: n.labelColor },
137
+ grid: {
138
+ top: c,
139
+ bottom: c,
140
+ left: c + h + E,
141
+ right: c + d,
142
+ containLabel: !1
143
+ },
144
+ tooltip: {
145
+ trigger: "item",
146
+ backgroundColor: n.tooltipBackgroundColor,
147
+ borderColor: n.tooltipBorderColor,
148
+ textStyle: { color: n.labelColor },
149
+ formatter: G(t, a, r)
150
+ },
151
+ xAxis: { type: "value", min: 0, max: i, show: !1 },
152
+ yAxis: $(t, a),
153
+ series: [
154
+ {
155
+ id: X,
156
+ type: "bar",
157
+ realtimeSort: !0,
158
+ barMaxWidth: B,
159
+ itemStyle: { borderRadius: [0, f, f, 0] },
160
+ data: e.map((s) => ({
161
+ id: s.id,
162
+ name: s.id,
163
+ value: [l.get(s.id), s.id],
164
+ itemStyle: { color: o[s.id] ?? R }
165
+ })),
166
+ encode: { x: 0, y: 1 },
167
+ label: z(t, a, r)
168
+ }
169
+ ]
170
+ };
171
+ }
172
+ export {
173
+ J as buildTopListOption,
174
+ q as labeledRowStepFor,
175
+ A as rankById,
176
+ U as resolveTotal
177
+ };
178
+ //# sourceMappingURL=top-list-option.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top-list-option.js","sources":["../../../../../../src/ui/components/charts/TopList/top-list-option.ts"],"sourcesContent":["import { formatShare } from \"../chart-share\";\nimport { echarts } from \"../echarts-modules\";\nimport type { ChartTheme } from \"../chart-theme\";\n\nexport interface TopListItem {\n id: string;\n name: string;\n value: number | null;\n colorToken?: string;\n}\n\nexport type TopListSort = \"desc\" | \"asc\";\n\nexport type TopListValueDisplay = \"value\" | \"percent\";\n\nexport interface TopListOptionInput {\n items: TopListItem[];\n sort: TopListSort;\n total?: number;\n valueDisplay: TopListValueDisplay[];\n theme: ChartTheme;\n colorsByItemId: Record<string, string>;\n animate: boolean;\n labeledRowStep: number;\n valueFormatter?: (value: number) => string;\n}\n\nconst EMPTY_VALUE_TEXT: string = \"–\";\n\nconst NAME_MAX_WIDTH_PX: number = 160;\n\nconst NAME_TO_BAR_GAP_PX: number = 12;\n\nconst VALUE_COLUMN_WIDTH_PX: number = 88;\n\nconst PERCENT_COLUMN_WIDTH_PX: number = 56;\n\nconst GRID_PADDING_PX: number = 16;\n\nconst BAR_MAX_WIDTH_PX: number = 20;\n\nconst BAR_RADIUS_PX: number = 4;\n\nconst BAR_END_LABEL_DISTANCE_PX: number = 8;\n\nconst UPDATE_ANIMATION_MS: number = 800;\n\nconst LABEL_FONT_SIZE_PX: number = 12;\n\nconst MIN_LABELED_ROW_HEIGHT_PX: number = 14;\n\nconst TIE_BREAK_RELATIVE_STEP: number = 1e-9;\n\nconst RICH_TEXT_RESERVED: RegExp = /[{}|]/g;\n\nconst VALUE_SERIES_ID: string = \"top-list-values\";\n\n\nfunction valueOf(item: TopListItem): number {\n return item.value ?? 0;\n}\n\nfunction maxValueOf(items: TopListItem[]): number {\n const maxValue: number = Math.max(...items.map(valueOf));\n return maxValue > 0 ? maxValue : 1;\n}\n\nfunction smallestGapBetweenDistinctValues(items: TopListItem[]): number {\n const distinctValues: number[] = [...new Set(items.map(valueOf))].sort(\n (first: number, second: number) => first - second,\n );\n const gaps: number[] = distinctValues\n .slice(1)\n .map((value: number, index: number) => value - distinctValues[index]);\n return gaps.length > 0 ? Math.min(...gaps) : Infinity;\n}\n\nfunction tieBreakStepOf(items: TopListItem[]): number {\n const relativeStep: number = maxValueOf(items) * TIE_BREAK_RELATIVE_STEP;\n const stepThatKeepsDistinctValuesApart: number =\n smallestGapBetweenDistinctValues(items) / (items.length + 1);\n return Math.min(relativeStep, stepThatKeepsDistinctValuesApart);\n}\n\nfunction plottedValuesById(items: TopListItem[]): Map<string, number> {\n const tieBreakStep: number = tieBreakStepOf(items);\n return new Map(\n items.map((item: TopListItem, position: number) => [\n item.id,\n valueOf(item) + tieBreakStep * (items.length - position),\n ]),\n );\n}\n\nexport function rankById(items: TopListItem[], sort: TopListSort): Map<string, number> {\n const plottedValues: Map<string, number> = plottedValuesById(items);\n const direction: number = sort === \"desc\" ? -1 : 1;\n const ranked: TopListItem[] = [...items].sort(\n (first: TopListItem, second: TopListItem) =>\n direction * ((plottedValues.get(first.id) as number) - (plottedValues.get(second.id) as number)),\n );\n return new Map(ranked.map((item: TopListItem, index: number) => [item.id, index + 1]));\n}\n\nexport function resolveTotal(items: TopListItem[], total?: number): number {\n return total ?? items.reduce((sum: number, item: TopListItem) => sum + valueOf(item), 0);\n}\n\nfunction shareOf(item: TopListItem, total: number): number {\n return total === 0 ? 0 : valueOf(item) / total;\n}\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nfunction plainRichText(text: string): string {\n return text.replace(RICH_TEXT_RESERVED, \" \");\n}\n\nfunction truncatedName(name: string, theme: ChartTheme): string {\n const font: string = `${LABEL_FONT_SIZE_PX}px ${theme.fontFamily}`;\n return plainRichText(echarts.format.truncateText(name, NAME_MAX_WIDTH_PX, font, \"…\"));\n}\n\nfunction formatValueText(input: TopListOptionInput, value: number | null): string {\n if (value === null) return EMPTY_VALUE_TEXT;\n return input.valueFormatter ? input.valueFormatter(value) : String(value);\n}\n\nfunction formatShareText(item: TopListItem, total: number): string {\n return item.value === null ? EMPTY_VALUE_TEXT : formatShare(shareOf(item, total));\n}\n\nfunction barEndLabelWidthPx(valueDisplay: TopListValueDisplay[]): number {\n const widths: number[] = [];\n if (valueDisplay.includes(\"value\")) widths.push(VALUE_COLUMN_WIDTH_PX);\n if (valueDisplay.includes(\"percent\")) widths.push(PERCENT_COLUMN_WIDTH_PX);\n if (widths.length === 0) return 0;\n return widths.reduce((sum: number, width: number) => sum + width, 0) + BAR_END_LABEL_DISTANCE_PX;\n}\n\nfunction barEndLabelText(input: TopListOptionInput, item: TopListItem, total: number): string {\n const parts: string[] = [];\n if (input.valueDisplay.includes(\"value\")) {\n parts.push(`{value|${plainRichText(formatValueText(input, item.value))}}`);\n }\n if (input.valueDisplay.includes(\"percent\")) {\n parts.push(`{percent|${formatShareText(item, total)}}`);\n }\n return parts.join(\"\");\n}\n\nexport function labeledRowStepFor(canvasHeightPx: number, itemCount: number): number {\n const rowHeightPx: number = (canvasHeightPx - 2 * GRID_PADDING_PX) / itemCount;\n return Math.max(1, Math.ceil(MIN_LABELED_ROW_HEIGHT_PX / rowHeightPx));\n}\n\nfunction isRowLabeled(rank: number | undefined, step: number): boolean {\n return rank === undefined || (rank - 1) % step === 0;\n}\n\nfunction categoryAxis(\n input: TopListOptionInput,\n itemsById: Map<string, TopListItem>,\n): Record<string, unknown> {\n const { items, sort, theme } = input;\n const ranks: Map<string, number> = rankById(items, sort);\n const step: number = input.labeledRowStep;\n return {\n type: \"category\",\n data: items.map((item: TopListItem) => item.id),\n inverse: sort === \"desc\",\n animationDuration: 0,\n animationDurationUpdate: input.animate ? UPDATE_ANIMATION_MS : 0,\n axisLine: { show: false },\n axisTick: { show: false },\n axisLabel: {\n color: theme.labelColor,\n fontSize: LABEL_FONT_SIZE_PX,\n interval: 0,\n align: \"right\",\n margin: NAME_TO_BAR_GAP_PX,\n formatter: (id: string) => {\n if (!isRowLabeled(ranks.get(id), step)) return \"\";\n const item: TopListItem | undefined = itemsById.get(id);\n return item ? truncatedName(item.name, theme) : \"\";\n },\n },\n };\n}\n\nfunction tooltipFormatter(\n input: TopListOptionInput,\n itemsById: Map<string, TopListItem>,\n total: number,\n): (params: { name: string }) => string {\n return (params: { name: string }) => {\n const item: TopListItem | undefined = itemsById.get(params.name);\n if (!item) return \"\";\n const share: string = item.value === null ? \"\" : ` · ${formatShare(shareOf(item, total))}`;\n const value: string = escapeHtml(formatValueText(input, item.value));\n return `<div>${escapeHtml(item.name)}</div><div><b>${value}</b>${share}</div>`;\n };\n}\n\nfunction barEndLabel(\n input: TopListOptionInput,\n itemsById: Map<string, TopListItem>,\n total: number,\n): Record<string, unknown> {\n const { theme } = input;\n const ranks: Map<string, number> = rankById(input.items, input.sort);\n const step: number = input.labeledRowStep;\n return {\n show: input.valueDisplay.length > 0,\n position: \"right\",\n distance: BAR_END_LABEL_DISTANCE_PX,\n fontSize: LABEL_FONT_SIZE_PX,\n formatter: (params: { name: string }) => {\n if (!isRowLabeled(ranks.get(params.name), step)) return \"\";\n const item: TopListItem | undefined = itemsById.get(params.name);\n return item ? barEndLabelText(input, item, total) : \"\";\n },\n rich: {\n value: { color: theme.labelColor, fontWeight: 600, padding: [0, 8, 0, 0] },\n percent: { color: theme.labelColor },\n },\n };\n}\n\nexport function buildTopListOption(input: TopListOptionInput): Record<string, unknown> {\n const { items, theme, colorsByItemId } = input;\n const itemsById: Map<string, TopListItem> = new Map(\n items.map((item: TopListItem) => [item.id, item]),\n );\n const total: number = resolveTotal(items, input.total);\n const maxValue: number = maxValueOf(items);\n const plottedValues: Map<string, number> = plottedValuesById(items);\n const reservedRightPx: number = barEndLabelWidthPx(input.valueDisplay);\n const fallbackColor: string = theme.seriesColors[0];\n \n return {\n animation: true,\n animationDuration: 0,\n animationDurationUpdate: input.animate ? UPDATE_ANIMATION_MS : 0,\n animationEasing: \"linear\",\n animationEasingUpdate: \"linear\",\n textStyle: { fontFamily: theme.fontFamily, color: theme.labelColor },\n grid: {\n top: GRID_PADDING_PX,\n bottom: GRID_PADDING_PX,\n left: GRID_PADDING_PX + NAME_MAX_WIDTH_PX + NAME_TO_BAR_GAP_PX,\n right: GRID_PADDING_PX + reservedRightPx,\n containLabel: false,\n },\n tooltip: {\n trigger: \"item\",\n backgroundColor: theme.tooltipBackgroundColor,\n borderColor: theme.tooltipBorderColor,\n textStyle: { color: theme.labelColor },\n formatter: tooltipFormatter(input, itemsById, total),\n },\n xAxis: { type: \"value\", min: 0, max: maxValue, show: false },\n yAxis: categoryAxis(input, itemsById),\n series: [\n {\n id: VALUE_SERIES_ID,\n type: \"bar\",\n realtimeSort: true,\n barMaxWidth: BAR_MAX_WIDTH_PX,\n itemStyle: { borderRadius: [0, BAR_RADIUS_PX, BAR_RADIUS_PX, 0] },\n data: items.map((item: TopListItem) => ({\n id: item.id,\n name: item.id,\n value: [plottedValues.get(item.id) as number, item.id],\n itemStyle: { color: colorsByItemId[item.id] ?? fallbackColor },\n })),\n encode: { x: 0, y: 1 },\n label: barEndLabel(input, itemsById, total),\n },\n ],\n };\n}\n"],"names":["EMPTY_VALUE_TEXT","NAME_MAX_WIDTH_PX","NAME_TO_BAR_GAP_PX","VALUE_COLUMN_WIDTH_PX","PERCENT_COLUMN_WIDTH_PX","GRID_PADDING_PX","BAR_MAX_WIDTH_PX","BAR_RADIUS_PX","BAR_END_LABEL_DISTANCE_PX","UPDATE_ANIMATION_MS","LABEL_FONT_SIZE_PX","MIN_LABELED_ROW_HEIGHT_PX","TIE_BREAK_RELATIVE_STEP","RICH_TEXT_RESERVED","VALUE_SERIES_ID","valueOf","item","maxValueOf","items","maxValue","smallestGapBetweenDistinctValues","distinctValues","first","second","gaps","value","index","tieBreakStepOf","relativeStep","stepThatKeepsDistinctValuesApart","plottedValuesById","tieBreakStep","position","rankById","sort","plottedValues","direction","ranked","resolveTotal","total","sum","shareOf","escapeHtml","text","plainRichText","truncatedName","name","theme","font","echarts","formatValueText","input","formatShareText","formatShare","barEndLabelWidthPx","valueDisplay","widths","width","barEndLabelText","parts","labeledRowStepFor","canvasHeightPx","itemCount","rowHeightPx","isRowLabeled","rank","step","categoryAxis","itemsById","ranks","id","tooltipFormatter","params","share","barEndLabel","buildTopListOption","colorsByItemId","reservedRightPx","fallbackColor"],"mappings":";;;;;AA2BA,MAAMA,IAA2B,KAE3BC,IAA4B,KAE5BC,IAA6B,IAE7BC,IAAgC,IAEhCC,IAAkC,IAElCC,IAA0B,IAE1BC,IAA2B,IAE3BC,IAAwB,GAExBC,IAAoC,GAEpCC,IAA8B,KAE9BC,IAA6B,IAE7BC,IAAoC,IAEpCC,IAAkC,MAElCC,IAA6B,UAE7BC,IAA0B;AAGhC,SAASC,EAAQC,GAA2B;AAC1C,SAAOA,EAAK,SAAS;AACvB;AAEA,SAASC,EAAWC,GAA8B;AAChD,QAAMC,IAAmB,KAAK,IAAI,GAAGD,EAAM,IAAIH,CAAO,CAAC;AACvD,SAAOI,IAAW,IAAIA,IAAW;AACnC;AAEA,SAASC,EAAiCF,GAA8B;AACtE,QAAMG,IAA2B,CAAC,GAAG,IAAI,IAAIH,EAAM,IAAIH,CAAO,CAAC,CAAC,EAAE;AAAA,IAChE,CAACO,GAAeC,MAAmBD,IAAQC;AAAA,EAAA,GAEvCC,IAAiBH,EACpB,MAAM,CAAC,EACP,IAAI,CAACI,GAAeC,MAAkBD,IAAQJ,EAAeK,CAAK,CAAC;AACtE,SAAOF,EAAK,SAAS,IAAI,KAAK,IAAI,GAAGA,CAAI,IAAI;AAC/C;AAEA,SAASG,EAAeT,GAA8B;AACpD,QAAMU,IAAuBX,EAAWC,CAAK,IAAIN,GAC3CiB,IACJT,EAAiCF,CAAK,KAAKA,EAAM,SAAS;AAC5D,SAAO,KAAK,IAAIU,GAAcC,CAAgC;AAChE;AAEA,SAASC,EAAkBZ,GAA2C;AACpE,QAAMa,IAAuBJ,EAAeT,CAAK;AACjD,SAAO,IAAI;AAAA,IACTA,EAAM,IAAI,CAACF,GAAmBgB,MAAqB;AAAA,MACjDhB,EAAK;AAAA,MACLD,EAAQC,CAAI,IAAIe,KAAgBb,EAAM,SAASc;AAAA,IAAA,CAChD;AAAA,EAAA;AAEL;AAEO,SAASC,EAASf,GAAsBgB,GAAwC;AACrF,QAAMC,IAAqCL,EAAkBZ,CAAK,GAC5DkB,IAAoBF,MAAS,SAAS,KAAK,GAC3CG,IAAwB,CAAC,GAAGnB,CAAK,EAAE;AAAA,IACvC,CAACI,GAAoBC,MACnBa,KAAcD,EAAc,IAAIb,EAAM,EAAE,IAAgBa,EAAc,IAAIZ,EAAO,EAAE;AAAA,EAAA;AAEvF,SAAO,IAAI,IAAIc,EAAO,IAAI,CAACrB,GAAmBU,MAAkB,CAACV,EAAK,IAAIU,IAAQ,CAAC,CAAC,CAAC;AACvF;AAEO,SAASY,EAAapB,GAAsBqB,GAAwB;AACzE,SAAOA,KAASrB,EAAM,OAAO,CAACsB,GAAaxB,MAAsBwB,IAAMzB,EAAQC,CAAI,GAAG,CAAC;AACzF;AAEA,SAASyB,EAAQzB,GAAmBuB,GAAuB;AACzD,SAAOA,MAAU,IAAI,IAAIxB,EAAQC,CAAI,IAAIuB;AAC3C;AAEA,SAASG,EAAWC,GAAsB;AACxC,SAAOA,EAAK,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM;AAC/E;AAEA,SAASC,EAAcD,GAAsB;AAC3C,SAAOA,EAAK,QAAQ9B,GAAoB,GAAG;AAC7C;AAEA,SAASgC,EAAcC,GAAcC,GAA2B;AAC9D,QAAMC,IAAe,GAAGtC,CAAkB,MAAMqC,EAAM,UAAU;AAChE,SAAOH,EAAcK,EAAQ,OAAO,aAAaH,GAAM7C,GAAmB+C,GAAM,GAAG,CAAC;AACtF;AAEA,SAASE,EAAgBC,GAA2B1B,GAA8B;AAChF,SAAIA,MAAU,OAAazB,IACpBmD,EAAM,iBAAiBA,EAAM,eAAe1B,CAAK,IAAI,OAAOA,CAAK;AAC1E;AAEA,SAAS2B,EAAgBpC,GAAmBuB,GAAuB;AACjE,SAAOvB,EAAK,UAAU,OAAOhB,IAAmBqD,EAAYZ,EAAQzB,GAAMuB,CAAK,CAAC;AAClF;AAEA,SAASe,EAAmBC,GAA6C;AACvE,QAAMC,IAAmB,CAAA;AAGzB,SAFID,EAAa,SAAS,OAAO,KAAGC,EAAO,KAAKrD,CAAqB,GACjEoD,EAAa,SAAS,SAAS,KAAGC,EAAO,KAAKpD,CAAuB,GACrEoD,EAAO,WAAW,IAAU,IACzBA,EAAO,OAAO,CAAChB,GAAaiB,MAAkBjB,IAAMiB,GAAO,CAAC,IAAIjD;AACzE;AAEA,SAASkD,EAAgBP,GAA2BnC,GAAmBuB,GAAuB;AAC5F,QAAMoB,IAAkB,CAAA;AACxB,SAAIR,EAAM,aAAa,SAAS,OAAO,KACrCQ,EAAM,KAAK,UAAUf,EAAcM,EAAgBC,GAAOnC,EAAK,KAAK,CAAC,CAAC,GAAG,GAEvEmC,EAAM,aAAa,SAAS,SAAS,KACvCQ,EAAM,KAAK,YAAYP,EAAgBpC,GAAMuB,CAAK,CAAC,GAAG,GAEjDoB,EAAM,KAAK,EAAE;AACtB;AAEO,SAASC,EAAkBC,GAAwBC,GAA2B;AACnF,QAAMC,KAAuBF,IAAiB,IAAIxD,KAAmByD;AACrE,SAAO,KAAK,IAAI,GAAG,KAAK,KAAKnD,IAA4BoD,CAAW,CAAC;AACvE;AAEA,SAASC,EAAaC,GAA0BC,GAAuB;AACrE,SAAOD,MAAS,WAAcA,IAAO,KAAKC,MAAS;AACrD;AAEA,SAASC,EACPhB,GACAiB,GACyB;AACzB,QAAM,EAAE,OAAAlD,GAAO,MAAAgB,GAAM,OAAAa,EAAA,IAAUI,GACzBkB,IAA6BpC,EAASf,GAAOgB,CAAI,GACjDgC,IAAef,EAAM;AAC3B,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAMjC,EAAM,IAAI,CAACF,MAAsBA,EAAK,EAAE;AAAA,IAC9C,SAASkB,MAAS;AAAA,IAClB,mBAAmB;AAAA,IACnB,yBAAyBiB,EAAM,UAAU1C,IAAsB;AAAA,IAC/D,UAAU,EAAE,MAAM,GAAA;AAAA,IAClB,UAAU,EAAE,MAAM,GAAA;AAAA,IAClB,WAAW;AAAA,MACT,OAAOsC,EAAM;AAAA,MACb,UAAUrC;AAAA,MACV,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQR;AAAA,MACR,WAAW,CAACoE,MAAe;AACzB,YAAI,CAACN,EAAaK,EAAM,IAAIC,CAAE,GAAGJ,CAAI,EAAG,QAAO;AAC/C,cAAMlD,IAAgCoD,EAAU,IAAIE,CAAE;AACtD,eAAOtD,IAAO6B,EAAc7B,EAAK,MAAM+B,CAAK,IAAI;AAAA,MAClD;AAAA,IAAA;AAAA,EACF;AAEJ;AAEA,SAASwB,EACPpB,GACAiB,GACA7B,GACsC;AACtC,SAAO,CAACiC,MAA6B;AACnC,UAAMxD,IAAgCoD,EAAU,IAAII,EAAO,IAAI;AAC/D,QAAI,CAACxD,EAAM,QAAO;AAClB,UAAMyD,IAAgBzD,EAAK,UAAU,OAAO,KAAK,MAAMqC,EAAYZ,EAAQzB,GAAMuB,CAAK,CAAC,CAAC,IAClFd,IAAgBiB,EAAWQ,EAAgBC,GAAOnC,EAAK,KAAK,CAAC;AACnE,WAAO,QAAQ0B,EAAW1B,EAAK,IAAI,CAAC,iBAAiBS,CAAK,OAAOgD,CAAK;AAAA,EACxE;AACF;AAEA,SAASC,EACPvB,GACAiB,GACA7B,GACyB;AACzB,QAAM,EAAE,OAAAQ,MAAUI,GACZkB,IAA6BpC,EAASkB,EAAM,OAAOA,EAAM,IAAI,GAC7De,IAAef,EAAM;AAC3B,SAAO;AAAA,IACL,MAAMA,EAAM,aAAa,SAAS;AAAA,IAClC,UAAU;AAAA,IACV,UAAU3C;AAAA,IACV,UAAUE;AAAA,IACV,WAAW,CAAC8D,MAA6B;AACvC,UAAI,CAACR,EAAaK,EAAM,IAAIG,EAAO,IAAI,GAAGN,CAAI,EAAG,QAAO;AACxD,YAAMlD,IAAgCoD,EAAU,IAAII,EAAO,IAAI;AAC/D,aAAOxD,IAAO0C,EAAgBP,GAAOnC,GAAMuB,CAAK,IAAI;AAAA,IACtD;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,EAAE,OAAOQ,EAAM,YAAY,YAAY,KAAK,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC,EAAA;AAAA,MACvE,SAAS,EAAE,OAAOA,EAAM,WAAA;AAAA,IAAW;AAAA,EACrC;AAEJ;AAEO,SAAS4B,EAAmBxB,GAAoD;AACrF,QAAM,EAAE,OAAAjC,GAAO,OAAA6B,GAAO,gBAAA6B,EAAA,IAAmBzB,GACnCiB,IAAsC,IAAI;AAAA,IAC9ClD,EAAM,IAAI,CAACF,MAAsB,CAACA,EAAK,IAAIA,CAAI,CAAC;AAAA,EAAA,GAE5CuB,IAAgBD,EAAapB,GAAOiC,EAAM,KAAK,GAC/ChC,IAAmBF,EAAWC,CAAK,GACnCiB,IAAqCL,EAAkBZ,CAAK,GAC5D2D,IAA0BvB,EAAmBH,EAAM,YAAY,GAC/D2B,IAAwB/B,EAAM,aAAa,CAAC;AAElD,SAAO;AAAA,IACL,WAAW;AAAA,IACX,mBAAmB;AAAA,IACnB,yBAAyBI,EAAM,UAAU1C,IAAsB;AAAA,IAC/D,iBAAiB;AAAA,IACjB,uBAAuB;AAAA,IACvB,WAAW,EAAE,YAAYsC,EAAM,YAAY,OAAOA,EAAM,WAAA;AAAA,IACxD,MAAM;AAAA,MACJ,KAAK1C;AAAA,MACL,QAAQA;AAAA,MACR,MAAMA,IAAkBJ,IAAoBC;AAAA,MAC5C,OAAOG,IAAkBwE;AAAA,MACzB,cAAc;AAAA,IAAA;AAAA,IAEhB,SAAS;AAAA,MACP,SAAS;AAAA,MACT,iBAAiB9B,EAAM;AAAA,MACvB,aAAaA,EAAM;AAAA,MACnB,WAAW,EAAE,OAAOA,EAAM,WAAA;AAAA,MAC1B,WAAWwB,EAAiBpB,GAAOiB,GAAW7B,CAAK;AAAA,IAAA;AAAA,IAErD,OAAO,EAAE,MAAM,SAAS,KAAK,GAAG,KAAKpB,GAAU,MAAM,GAAA;AAAA,IACrD,OAAOgD,EAAahB,GAAOiB,CAAS;AAAA,IACpC,QAAQ;AAAA,MACN;AAAA,QACE,IAAItD;AAAA,QACJ,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAaR;AAAA,QACb,WAAW,EAAE,cAAc,CAAC,GAAGC,GAAeA,GAAe,CAAC,EAAA;AAAA,QAC9D,MAAMW,EAAM,IAAI,CAACF,OAAuB;AAAA,UACtC,IAAIA,EAAK;AAAA,UACT,MAAMA,EAAK;AAAA,UACX,OAAO,CAACmB,EAAc,IAAInB,EAAK,EAAE,GAAaA,EAAK,EAAE;AAAA,UACrD,WAAW,EAAE,OAAO4D,EAAe5D,EAAK,EAAE,KAAK8D,EAAA;AAAA,QAAc,EAC7D;AAAA,QACF,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QACnB,OAAOJ,EAAYvB,GAAOiB,GAAW7B,CAAK;AAAA,MAAA;AAAA,IAC5C;AAAA,EACF;AAEJ;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=new Intl.NumberFormat(void 0,{style:"percent",maximumFractionDigits:1});function r(t){return e.format(t)}exports.formatShare=r;
2
+ //# sourceMappingURL=chart-share.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-share.cjs","sources":["../../../../../src/ui/components/charts/chart-share.ts"],"sourcesContent":["const SHARE_FORMAT: Intl.NumberFormat = new Intl.NumberFormat(undefined, {\n style: \"percent\",\n maximumFractionDigits: 1,\n});\n\nexport function formatShare(share: number): string {\n return SHARE_FORMAT.format(share);\n}\n"],"names":["SHARE_FORMAT","formatShare","share"],"mappings":"gFAAA,MAAMA,EAAkC,IAAI,KAAK,aAAa,OAAW,CACvE,MAAO,UACP,sBAAuB,CACzB,CAAC,EAEM,SAASC,EAAYC,EAAuB,CACjD,OAAOF,EAAa,OAAOE,CAAK,CAClC"}
@@ -0,0 +1,11 @@
1
+ const r = new Intl.NumberFormat(void 0, {
2
+ style: "percent",
3
+ maximumFractionDigits: 1
4
+ });
5
+ function e(t) {
6
+ return r.format(t);
7
+ }
8
+ export {
9
+ e as formatShare
10
+ };
11
+ //# sourceMappingURL=chart-share.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-share.js","sources":["../../../../../src/ui/components/charts/chart-share.ts"],"sourcesContent":["const SHARE_FORMAT: Intl.NumberFormat = new Intl.NumberFormat(undefined, {\n style: \"percent\",\n maximumFractionDigits: 1,\n});\n\nexport function formatShare(share: number): string {\n return SHARE_FORMAT.format(share);\n}\n"],"names":["SHARE_FORMAT","formatShare","share"],"mappings":"AAAA,MAAMA,IAAkC,IAAI,KAAK,aAAa,QAAW;AAAA,EACvE,OAAO;AAAA,EACP,uBAAuB;AACzB,CAAC;AAEM,SAASC,EAAYC,GAAuB;AACjD,SAAOF,EAAa,OAAOE,CAAK;AAClC;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("../../../vendor/clsx/dist/clsx.cjs"),m=require("react"),n=require("react-aria-components");;/* empty css */const g=require("../../icons/IconChevronDown.cjs"),f=require("../../icons/IconChevronUp.cjs"),j=require("../Checkbox/Checkbox.cjs"),p=require("../Radio/Radio.cjs"),h=m.createContext("checkbox");function v(s){const l=Number(s);return`${s}`.trim()!==""&&Number.isFinite(l)?`${l}px`:`${s}`}function y({bleed:s=!1,dense:l=!1,grid:t=!1,striped:o=!1,selectionType:i="checkbox",maxHeight:a,className:d,...r}){const b=a!==void 0,C=c.clsx(d,"table-container",s&&"table-container-bleed",b&&"table-container-scrollable"),N=b?{"--table-max-height":v(a)}:void 0,T=c.clsx("sds-table",s&&"table-bleed",l&&"table-dense",t&&"table-grid",o&&"sds-table-striped");return e.jsx("div",{className:C,style:N,children:e.jsx(h.Provider,{value:i,children:e.jsx(n.Table,{className:T,...r})})})}function x({align:s="start",className:l,...t}){const o=c.clsx(l,"table-column",`table-align-${s}`);return e.jsx(n.Column,{className:o,...t,children:({allowsSorting:i,sortDirection:a})=>e.jsx("div",{className:c.clsx("table-column-inner"),children:e.jsxs(e.Fragment,{children:[t.children,i&&e.jsx("span",{"aria-hidden":"true",className:c.clsx("sort-indicator",!a&&"sort-indicator-unsorted"),children:a==="descending"?e.jsx(g.IconChevronDown,{}):e.jsx(f.IconChevronUp,{})})]})})})}function k({className:s,...l}){return e.jsx(n.TableBody,{...l})}function q({className:s,columns:l,children:t,...o}){const{selectionBehavior:i,selectionMode:a,allowsDragging:d}=n.useTableOptions(),r=m.useContext(h),b=c.clsx(s,"table-head");return e.jsxs(n.TableHeader,{className:b,...o,children:[d&&e.jsx(x,{}),i==="toggle"&&e.jsx(x,{className:c.clsx("table-selection-col",r==="radio"&&"table-selection-col--radio"),children:a==="multiple"&&e.jsx(n.Checkbox,{slot:"selection",className:"table-selection-checkbox",children:e.jsx(j.Checkbox,{})})}),e.jsx(n.Collection,{items:l,children:t})]})}function w({id:s,columns:l,children:t,className:o,...i}){const{selectionBehavior:a,allowsDragging:d}=n.useTableOptions(),r=m.useContext(h),b=c.clsx(o,"table-row");return e.jsxs(n.Row,{id:s,...i,className:b,children:[d&&e.jsx(u,{children:e.jsx(n.Button,{slot:"drag",children:"≡"})}),a==="toggle"&&e.jsx(u,{className:c.clsx("table-selection-cell",r==="radio"&&"table-selection-cell--radio"),children:e.jsx(n.Checkbox,{slot:"selection",className:"table-selection-checkbox",children:r==="radio"?e.jsx(p.Radio,{}):e.jsx(j.Checkbox,{})})}),e.jsx(n.Collection,{items:l,children:t})]})}function u({align:s="start",className:l,...t}){const o=c.clsx(l,"table-cell",`table-align-${s}`);return e.jsx(n.Cell,{className:o,...t})}exports.Table=y;exports.TableBody=k;exports.TableCell=u;exports.TableColumn=x;exports.TableHead=q;exports.TableRow=w;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("../../../vendor/clsx/dist/clsx.cjs"),m=require("react"),n=require("react-aria-components");;/* empty css */const T=require("../../icons/IconChevronDown.cjs"),g=require("../../icons/IconChevronUp.cjs"),j=require("../Checkbox/Checkbox.cjs"),f=require("../Radio/Radio.cjs"),h=m.createContext("checkbox");function p(s){const l=Number(s);return`${s}`.trim()!==""&&Number.isFinite(l)?`${l}px`:`${s}`}function v({bleed:s=!1,dense:l=!1,striped:t=!1,selectionType:o="checkbox",maxHeight:a,className:i,...b}){const r=a!==void 0,x=c.clsx(i,"table-container",s&&"table-container-bleed",r&&"table-container-scrollable"),C=r?{"--table-max-height":p(a)}:void 0,N=c.clsx("sds-table",s&&"table-bleed",l&&"table-dense",t&&"sds-table-striped");return e.jsx("div",{className:x,style:C,children:e.jsx(h.Provider,{value:o,children:e.jsx(n.Table,{className:N,...b})})})}function d({align:s="start",className:l,...t}){const o=c.clsx(l,"table-column",`table-align-${s}`);return e.jsx(n.Column,{className:o,...t,children:({allowsSorting:a,sortDirection:i})=>e.jsx("div",{className:c.clsx("table-column-inner"),children:e.jsxs(e.Fragment,{children:[t.children,a&&e.jsx("span",{"aria-hidden":"true",className:c.clsx("sort-indicator",!i&&"sort-indicator-unsorted"),children:i==="descending"?e.jsx(T.IconChevronDown,{}):e.jsx(g.IconChevronUp,{})})]})})})}function y({className:s,...l}){return e.jsx(n.TableBody,{...l})}function k({className:s,columns:l,children:t,...o}){const{selectionBehavior:a,selectionMode:i,allowsDragging:b}=n.useTableOptions(),r=m.useContext(h),x=c.clsx(s,"table-head");return e.jsxs(n.TableHeader,{className:x,...o,children:[b&&e.jsx(d,{}),a==="toggle"&&e.jsx(d,{className:c.clsx("table-selection-col",r==="radio"&&"table-selection-col--radio"),children:i==="multiple"&&e.jsx(n.Checkbox,{slot:"selection",className:"table-selection-checkbox",children:e.jsx(j.Checkbox,{})})}),e.jsx(n.Collection,{items:l,children:t})]})}function q({id:s,columns:l,children:t,className:o,...a}){const{selectionBehavior:i,allowsDragging:b}=n.useTableOptions(),r=m.useContext(h),x=c.clsx(o,"table-row");return e.jsxs(n.Row,{id:s,...a,className:x,children:[b&&e.jsx(u,{children:e.jsx(n.Button,{slot:"drag",children:"≡"})}),i==="toggle"&&e.jsx(u,{className:c.clsx("table-selection-cell",r==="radio"&&"table-selection-cell--radio"),children:e.jsx(n.Checkbox,{slot:"selection",className:"table-selection-checkbox",children:r==="radio"?e.jsx(f.Radio,{}):e.jsx(j.Checkbox,{})})}),e.jsx(n.Collection,{items:l,children:t})]})}function u({align:s="start",className:l,...t}){const o=c.clsx(l,"table-cell",`table-align-${s}`);return e.jsx(n.Cell,{className:o,...t})}exports.Table=v;exports.TableBody=y;exports.TableCell=u;exports.TableColumn=d;exports.TableHead=k;exports.TableRow=q;
2
2
  //# sourceMappingURL=Table.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Table.cjs","sources":["../../../../../src/ui/primitives/Table/Table.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport { IconChevronDown, IconChevronUp } from \"icons\";\nimport { Checkbox, Radio } from \"primitives\";\nimport { createContext, useContext, type CSSProperties } from \"react\";\nimport {\n Button as RACButton,\n Cell as RACCell,\n Checkbox as RACSelectionCheckbox,\n Collection as RACCollection,\n Column as RACColumn,\n Row as RACRow,\n Table as RACTable,\n TableBody as RACTableBody,\n TableHeader as RACTableHeader,\n useTableOptions,\n type CellProps as RACCellProps,\n type ColumnProps as RACColumnProps,\n type RowProps as RACRowProps,\n type TableBodyProps as RACTableBodyProps,\n type TableHeaderProps as RACTableHeaderProps,\n type TableProps as RACTableProps,\n} from \"react-aria-components\";\nimport \"./table.css\";\n\ntype TableAlign = \"start\" | \"center\" | \"right\";\n\n/**\n * Visual style of the built-in selection control rendered in the selection\n * column (header \"select all\" + per-row toggle). \"radio\" is for\n * `selectionMode=\"single\"` tables where a round, single-choice control reads\n * better than a checkbox — the header never renders a control either way\n * (there is no \"select all\" for a single choice).\n */\ntype SelectionType = \"checkbox\" | \"radio\";\nconst SelectionTypeContext = createContext<SelectionType>(\"checkbox\");\n\nfunction toCssLength(value: number | string): string {\n const numericValue = Number(value);\n const isUnitlessNumber =\n `${value}`.trim() !== \"\" && Number.isFinite(numericValue);\n return isUnitlessNumber ? `${numericValue}px` : `${value}`;\n}\n\nexport type TableProps = RACTableProps & {\n bleed?: boolean;\n dense?: boolean;\n grid?: boolean;\n striped?: boolean;\n selectionType?: SelectionType;\n maxHeight?: number | string;\n};\nexport function Table({\n bleed = false,\n dense = false,\n grid = false,\n striped = false,\n selectionType = \"checkbox\",\n maxHeight,\n className,\n ...props\n}: TableProps) {\n const scrollsVertically = maxHeight !== undefined;\n const containerClassNames = clsx(\n className,\n \"table-container\",\n bleed && \"table-container-bleed\",\n scrollsVertically && \"table-container-scrollable\",\n );\n const containerStyle = scrollsVertically\n ? ({ \"--table-max-height\": toCssLength(maxHeight) } as CSSProperties)\n : undefined;\n const tableClassNames = clsx(\n \"sds-table\",\n bleed && \"table-bleed\",\n dense && \"table-dense\",\n grid && \"table-grid\",\n striped && \"sds-table-striped\",\n );\n return (\n <div className={containerClassNames} style={containerStyle}>\n <SelectionTypeContext.Provider value={selectionType}>\n <RACTable className={tableClassNames} {...props} />\n </SelectionTypeContext.Provider>\n </div>\n );\n}\n\nexport type TableColumnProps = RACColumnProps & {\n align?: TableAlign;\n};\nexport function TableColumn({\n align = \"start\",\n className,\n ...props\n}: TableColumnProps) {\n const classNames = clsx(className, \"table-column\", `table-align-${align}`);\n return (\n <RACColumn className={classNames} {...props}>\n {({ allowsSorting, sortDirection }) => (\n <div className={clsx(\"table-column-inner\")}>\n <>\n {props.children}\n {allowsSorting && (\n <span\n aria-hidden=\"true\"\n className={clsx(\n \"sort-indicator\",\n !sortDirection && \"sort-indicator-unsorted\",\n )}\n >\n {sortDirection === \"descending\" ? (\n <IconChevronDown />\n ) : (\n <IconChevronUp />\n )}\n </span>\n )}\n </>\n </div>\n )}\n </RACColumn>\n );\n}\n\nexport type TableBodyProps<T> = RACTableBodyProps<T>;\nexport function TableBody<T extends object>({\n className,\n ...props\n}: TableBodyProps<T>) {\n return <RACTableBody {...props} />;\n}\n\nexport type TableHeadProps<T> = RACTableHeaderProps<T>;\nexport function TableHead<T extends object>({\n className,\n columns,\n children,\n ...props\n}: TableHeadProps<T>) {\n const { selectionBehavior, selectionMode, allowsDragging } =\n useTableOptions();\n const selectionType = useContext(SelectionTypeContext);\n const classNames = clsx(className, \"table-head\");\n return (\n <RACTableHeader className={classNames} {...props}>\n {/* Add extra columns for drag and drop and selection. */}\n {allowsDragging && <TableColumn />}\n {selectionBehavior === \"toggle\" && (\n <TableColumn\n className={clsx(\n \"table-selection-col\",\n selectionType === \"radio\" && \"table-selection-col--radio\",\n )}\n >\n {selectionMode === \"multiple\" && (\n <RACSelectionCheckbox slot=\"selection\" className=\"table-selection-checkbox\">\n <Checkbox />\n </RACSelectionCheckbox>\n )}\n </TableColumn>\n )}\n <RACCollection items={columns}>{children}</RACCollection>\n </RACTableHeader>\n );\n}\n\nexport type TableRowProps<T> = RACRowProps<T>;\nexport function TableRow<T extends object>({\n id,\n columns,\n children,\n className,\n ...otherProps\n}: TableRowProps<T>) {\n const { selectionBehavior, allowsDragging } = useTableOptions();\n const selectionType = useContext(SelectionTypeContext);\n const classNames = clsx(className, \"table-row\");\n return (\n <RACRow id={id} {...otherProps} className={classNames}>\n {allowsDragging && (\n <TableCell>\n <RACButton slot=\"drag\">≡</RACButton>\n </TableCell>\n )}\n {selectionBehavior === \"toggle\" && (\n <TableCell\n className={clsx(\n \"table-selection-cell\",\n selectionType === \"radio\" && \"table-selection-cell--radio\",\n )}\n >\n <RACSelectionCheckbox slot=\"selection\" className=\"table-selection-checkbox\">\n {selectionType === \"radio\" ? <Radio /> : <Checkbox />}\n </RACSelectionCheckbox>\n </TableCell>\n )}\n <RACCollection items={columns}>{children}</RACCollection>\n </RACRow>\n );\n}\n\nexport type TableCellProps = RACCellProps & { align?: TableAlign };\nexport function TableCell({\n align = \"start\",\n className,\n ...props\n}: TableCellProps) {\n const classNames = clsx(className, \"table-cell\", `table-align-${align}`);\n return <RACCell className={classNames} {...props} />;\n}\n"],"names":["SelectionTypeContext","createContext","toCssLength","value","numericValue","Table","bleed","dense","grid","striped","selectionType","maxHeight","className","props","scrollsVertically","containerClassNames","clsx","containerStyle","tableClassNames","RACTable","TableColumn","align","classNames","RACColumn","allowsSorting","sortDirection","jsx","jsxs","Fragment","IconChevronDown","IconChevronUp","TableBody","RACTableBody","TableHead","columns","children","selectionBehavior","selectionMode","allowsDragging","useTableOptions","useContext","RACTableHeader","RACSelectionCheckbox","Checkbox","RACCollection","TableRow","id","otherProps","RACRow","TableCell","RACButton","Radio","RACCell"],"mappings":"0ZAkCMA,EAAuBC,EAAAA,cAA6B,UAAU,EAEpE,SAASC,EAAYC,EAAgC,CACnD,MAAMC,EAAe,OAAOD,CAAK,EAGjC,MADE,GAAGA,CAAK,GAAG,SAAW,IAAM,OAAO,SAASC,CAAY,EAChC,GAAGA,CAAY,KAAO,GAAGD,CAAK,EAC1D,CAUO,SAASE,EAAM,CACpB,MAAAC,EAAQ,GACR,MAAAC,EAAQ,GACR,KAAAC,EAAO,GACP,QAAAC,EAAU,GACV,cAAAC,EAAgB,WAChB,UAAAC,EACA,UAAAC,EACA,GAAGC,CACL,EAAe,CACb,MAAMC,EAAoBH,IAAc,OAClCI,EAAsBC,EAAAA,KAC1BJ,EACA,kBACAN,GAAS,wBACTQ,GAAqB,4BAAA,EAEjBG,EAAiBH,EAClB,CAAE,qBAAsBZ,EAAYS,CAAS,GAC9C,OACEO,EAAkBF,EAAAA,KACtB,YACAV,GAAS,cACTC,GAAS,cACTC,GAAQ,aACRC,GAAW,mBAAA,EAEb,aACG,MAAA,CAAI,UAAWM,EAAqB,MAAOE,EAC1C,eAACjB,EAAqB,SAArB,CAA8B,MAAOU,EACpC,eAACS,QAAA,CAAS,UAAWD,EAAkB,GAAGL,EAAO,EACnD,CAAA,CACF,CAEJ,CAKO,SAASO,EAAY,CAC1B,MAAAC,EAAQ,QACR,UAAAT,EACA,GAAGC,CACL,EAAqB,CACnB,MAAMS,EAAaN,EAAAA,KAAKJ,EAAW,eAAgB,eAAeS,CAAK,EAAE,EACzE,aACGE,SAAA,CAAU,UAAWD,EAAa,GAAGT,EACnC,SAAA,CAAC,CAAE,cAAAW,EAAe,cAAAC,CAAA,IACjBC,EAAAA,IAAC,MAAA,CAAI,UAAWV,OAAK,oBAAoB,EACvC,SAAAW,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAAf,EAAM,SACNW,GACCE,EAAAA,IAAC,OAAA,CACC,cAAY,OACZ,UAAWV,EAAAA,KACT,iBACA,CAACS,GAAiB,yBAAA,EAGnB,aAAkB,aACjBC,EAAAA,IAACG,EAAAA,gBAAA,EAAgB,QAEhBC,EAAAA,cAAA,CAAA,CAAc,CAAA,CAAA,CAEnB,CAAA,CAEJ,EACF,EAEJ,CAEJ,CAGO,SAASC,EAA4B,CAC1C,UAAAnB,EACA,GAAGC,CACL,EAAsB,CACpB,OAAOa,MAACM,EAAAA,UAAA,CAAc,GAAGnB,CAAA,CAAO,CAClC,CAGO,SAASoB,EAA4B,CAC1C,UAAArB,EACA,QAAAsB,EACA,SAAAC,EACA,GAAGtB,CACL,EAAsB,CACpB,KAAM,CAAE,kBAAAuB,EAAmB,cAAAC,EAAe,eAAAC,CAAA,EACxCC,EAAAA,gBAAA,EACI7B,EAAgB8B,EAAAA,WAAWxC,CAAoB,EAC/CsB,EAAaN,EAAAA,KAAKJ,EAAW,YAAY,EAC/C,OACEe,EAAAA,KAACc,EAAAA,YAAA,CAAe,UAAWnB,EAAa,GAAGT,EAExC,SAAA,CAAAyB,SAAmBlB,EAAA,EAAY,EAC/BgB,IAAsB,UACrBV,EAAAA,IAACN,EAAA,CACC,UAAWJ,EAAAA,KACT,sBACAN,IAAkB,SAAW,4BAAA,EAG9B,SAAA2B,IAAkB,YACjBX,EAAAA,IAACgB,EAAAA,SAAA,CAAqB,KAAK,YAAY,UAAU,2BAC/C,SAAAhB,EAAAA,IAACiB,EAAAA,SAAA,CAAA,CAAS,CAAA,CACZ,CAAA,CAAA,EAINjB,EAAAA,IAACkB,EAAAA,WAAA,CAAc,MAAOV,EAAU,SAAAC,CAAA,CAAS,CAAA,EAC3C,CAEJ,CAGO,SAASU,EAA2B,CACzC,GAAAC,EACA,QAAAZ,EACA,SAAAC,EACA,UAAAvB,EACA,GAAGmC,CACL,EAAqB,CACnB,KAAM,CAAE,kBAAAX,EAAmB,eAAAE,CAAA,EAAmBC,kBAAA,EACxC7B,EAAgB8B,EAAAA,WAAWxC,CAAoB,EAC/CsB,EAAaN,EAAAA,KAAKJ,EAAW,WAAW,EAC9C,cACGoC,EAAAA,IAAA,CAAO,GAAAF,EAAS,GAAGC,EAAY,UAAWzB,EACxC,SAAA,CAAAgB,SACEW,EAAA,CACC,SAAAvB,EAAAA,IAACwB,EAAAA,QAAU,KAAK,OAAO,aAAC,CAAA,CAC1B,EAEDd,IAAsB,UACrBV,EAAAA,IAACuB,EAAA,CACC,UAAWjC,EAAAA,KACT,uBACAN,IAAkB,SAAW,6BAAA,EAG/B,SAAAgB,EAAAA,IAACgB,WAAA,CAAqB,KAAK,YAAY,UAAU,2BAC9C,SAAAhC,IAAkB,QAAUgB,EAAAA,IAACyB,QAAA,CAAA,CAAM,EAAKzB,MAACiB,EAAAA,WAAS,CAAA,CACrD,CAAA,CAAA,EAGJjB,EAAAA,IAACkB,EAAAA,WAAA,CAAc,MAAOV,EAAU,SAAAC,CAAA,CAAS,CAAA,EAC3C,CAEJ,CAGO,SAASc,EAAU,CACxB,MAAA5B,EAAQ,QACR,UAAAT,EACA,GAAGC,CACL,EAAmB,CACjB,MAAMS,EAAaN,EAAAA,KAAKJ,EAAW,aAAc,eAAeS,CAAK,EAAE,EACvE,OAAOK,EAAAA,IAAC0B,EAAAA,KAAA,CAAQ,UAAW9B,EAAa,GAAGT,EAAO,CACpD"}
1
+ {"version":3,"file":"Table.cjs","sources":["../../../../../src/ui/primitives/Table/Table.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport { IconChevronDown, IconChevronUp } from \"icons\";\nimport { Checkbox, Radio } from \"primitives\";\nimport { createContext, useContext, type CSSProperties } from \"react\";\nimport {\n Button as RACButton,\n Cell as RACCell,\n Checkbox as RACSelectionCheckbox,\n Collection as RACCollection,\n Column as RACColumn,\n Row as RACRow,\n Table as RACTable,\n TableBody as RACTableBody,\n TableHeader as RACTableHeader,\n useTableOptions,\n type CellProps as RACCellProps,\n type ColumnProps as RACColumnProps,\n type RowProps as RACRowProps,\n type TableBodyProps as RACTableBodyProps,\n type TableHeaderProps as RACTableHeaderProps,\n type TableProps as RACTableProps,\n} from \"react-aria-components\";\nimport \"./table.css\";\n\ntype TableAlign = \"start\" | \"center\" | \"right\";\n\n/**\n * Visual style of the built-in selection control rendered in the selection\n * column (header \"select all\" + per-row toggle). \"radio\" is for\n * `selectionMode=\"single\"` tables where a round, single-choice control reads\n * better than a checkbox — the header never renders a control either way\n * (there is no \"select all\" for a single choice).\n */\ntype SelectionType = \"checkbox\" | \"radio\";\nconst SelectionTypeContext = createContext<SelectionType>(\"checkbox\");\n\nfunction toCssLength(value: number | string): string {\n const numericValue = Number(value);\n const isUnitlessNumber =\n `${value}`.trim() !== \"\" && Number.isFinite(numericValue);\n return isUnitlessNumber ? `${numericValue}px` : `${value}`;\n}\n\nexport type TableProps = RACTableProps & {\n bleed?: boolean;\n dense?: boolean;\n striped?: boolean;\n selectionType?: SelectionType;\n maxHeight?: number | string;\n};\nexport function Table({\n bleed = false,\n dense = false,\n striped = false,\n selectionType = \"checkbox\",\n maxHeight,\n className,\n ...props\n}: TableProps) {\n const scrollsVertically = maxHeight !== undefined;\n const containerClassNames = clsx(\n className,\n \"table-container\",\n bleed && \"table-container-bleed\",\n scrollsVertically && \"table-container-scrollable\",\n );\n const containerStyle = scrollsVertically\n ? ({ \"--table-max-height\": toCssLength(maxHeight) } as CSSProperties)\n : undefined;\n const tableClassNames = clsx(\n \"sds-table\",\n bleed && \"table-bleed\",\n dense && \"table-dense\",\n striped && \"sds-table-striped\",\n );\n return (\n <div className={containerClassNames} style={containerStyle}>\n <SelectionTypeContext.Provider value={selectionType}>\n <RACTable className={tableClassNames} {...props} />\n </SelectionTypeContext.Provider>\n </div>\n );\n}\n\nexport type TableColumnProps = RACColumnProps & {\n align?: TableAlign;\n};\nexport function TableColumn({\n align = \"start\",\n className,\n ...props\n}: TableColumnProps) {\n const classNames = clsx(className, \"table-column\", `table-align-${align}`);\n return (\n <RACColumn className={classNames} {...props}>\n {({ allowsSorting, sortDirection }) => (\n <div className={clsx(\"table-column-inner\")}>\n <>\n {props.children}\n {allowsSorting && (\n <span\n aria-hidden=\"true\"\n className={clsx(\n \"sort-indicator\",\n !sortDirection && \"sort-indicator-unsorted\",\n )}\n >\n {sortDirection === \"descending\" ? (\n <IconChevronDown />\n ) : (\n <IconChevronUp />\n )}\n </span>\n )}\n </>\n </div>\n )}\n </RACColumn>\n );\n}\n\nexport type TableBodyProps<T> = RACTableBodyProps<T>;\nexport function TableBody<T extends object>({\n className,\n ...props\n}: TableBodyProps<T>) {\n return <RACTableBody {...props} />;\n}\n\nexport type TableHeadProps<T> = RACTableHeaderProps<T>;\nexport function TableHead<T extends object>({\n className,\n columns,\n children,\n ...props\n}: TableHeadProps<T>) {\n const { selectionBehavior, selectionMode, allowsDragging } =\n useTableOptions();\n const selectionType = useContext(SelectionTypeContext);\n const classNames = clsx(className, \"table-head\");\n return (\n <RACTableHeader className={classNames} {...props}>\n {/* Add extra columns for drag and drop and selection. */}\n {allowsDragging && <TableColumn />}\n {selectionBehavior === \"toggle\" && (\n <TableColumn\n className={clsx(\n \"table-selection-col\",\n selectionType === \"radio\" && \"table-selection-col--radio\",\n )}\n >\n {selectionMode === \"multiple\" && (\n <RACSelectionCheckbox slot=\"selection\" className=\"table-selection-checkbox\">\n <Checkbox />\n </RACSelectionCheckbox>\n )}\n </TableColumn>\n )}\n <RACCollection items={columns}>{children}</RACCollection>\n </RACTableHeader>\n );\n}\n\nexport type TableRowProps<T> = RACRowProps<T>;\nexport function TableRow<T extends object>({\n id,\n columns,\n children,\n className,\n ...otherProps\n}: TableRowProps<T>) {\n const { selectionBehavior, allowsDragging } = useTableOptions();\n const selectionType = useContext(SelectionTypeContext);\n const classNames = clsx(className, \"table-row\");\n return (\n <RACRow id={id} {...otherProps} className={classNames}>\n {allowsDragging && (\n <TableCell>\n <RACButton slot=\"drag\">≡</RACButton>\n </TableCell>\n )}\n {selectionBehavior === \"toggle\" && (\n <TableCell\n className={clsx(\n \"table-selection-cell\",\n selectionType === \"radio\" && \"table-selection-cell--radio\",\n )}\n >\n <RACSelectionCheckbox slot=\"selection\" className=\"table-selection-checkbox\">\n {selectionType === \"radio\" ? <Radio /> : <Checkbox />}\n </RACSelectionCheckbox>\n </TableCell>\n )}\n <RACCollection items={columns}>{children}</RACCollection>\n </RACRow>\n );\n}\n\nexport type TableCellProps = RACCellProps & { align?: TableAlign };\nexport function TableCell({\n align = \"start\",\n className,\n ...props\n}: TableCellProps) {\n const classNames = clsx(className, \"table-cell\", `table-align-${align}`);\n return <RACCell className={classNames} {...props} />;\n}\n"],"names":["SelectionTypeContext","createContext","toCssLength","value","numericValue","Table","bleed","dense","striped","selectionType","maxHeight","className","props","scrollsVertically","containerClassNames","clsx","containerStyle","tableClassNames","RACTable","TableColumn","align","classNames","RACColumn","allowsSorting","sortDirection","jsx","jsxs","Fragment","IconChevronDown","IconChevronUp","TableBody","RACTableBody","TableHead","columns","children","selectionBehavior","selectionMode","allowsDragging","useTableOptions","useContext","RACTableHeader","RACSelectionCheckbox","Checkbox","RACCollection","TableRow","id","otherProps","RACRow","TableCell","RACButton","Radio","RACCell"],"mappings":"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"}