@ssa-ui-kit/core 1.1.0 → 1.1.2

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 (66) hide show
  1. package/.storybook/style.css +4 -0
  2. package/dist/components/Button/fixtures.d.ts +16 -16
  3. package/dist/components/FullscreenModeContext.d.ts +14 -0
  4. package/dist/components/Icon/icons/Maximize.d.ts +3 -0
  5. package/dist/components/Icon/icons/all.d.ts +1 -0
  6. package/dist/components/Icon/icons/iconsList.d.ts +1 -1
  7. package/dist/components/PieChart/PieChart.d.ts +4 -1
  8. package/dist/components/PieChart/PieChartBases.d.ts +5 -0
  9. package/dist/components/PieChart/PieChartHeader.d.ts +2 -0
  10. package/dist/components/PieChart/PieChartLegend.d.ts +1 -1
  11. package/dist/components/PieChart/PieChartLegendList.d.ts +2 -0
  12. package/dist/components/PieChart/PieChartLegendListItem.d.ts +13 -0
  13. package/dist/components/PieChart/PieChartLegendMarker.d.ts +1 -0
  14. package/dist/components/PieChart/stories/fixtures.d.ts +5 -0
  15. package/dist/components/PieChart/styles.d.ts +3 -0
  16. package/dist/components/PieChart/types.d.ts +10 -4
  17. package/dist/components/WidgetCard/Content.d.ts +5 -0
  18. package/dist/components/WidgetCard/Header.d.ts +9 -0
  19. package/dist/components/WidgetCard/Title.d.ts +3 -0
  20. package/dist/components/WidgetCard/WidgetCard.d.ts +2 -0
  21. package/dist/components/WidgetCard/WidgetCardBase.d.ts +6 -0
  22. package/dist/components/WidgetCard/WithWidgetCard.d.ts +4 -0
  23. package/dist/components/WidgetCard/index.d.ts +5 -0
  24. package/dist/components/WidgetCard/types.d.ts +13 -0
  25. package/dist/components/WithLink.d.ts +7 -0
  26. package/dist/components/index.d.ts +59 -56
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/types/emotion.d.ts +1 -0
  30. package/package.json +4 -4
  31. package/src/components/FullscreenModeContext.tsx +62 -0
  32. package/src/components/Icon/icons/Maximize.tsx +26 -0
  33. package/src/components/Icon/icons/all.ts +1 -0
  34. package/src/components/Pagination/components/RowsPerPageDropdown/RowsPerPageDropdown.tsx +5 -7
  35. package/src/components/PieChart/PieChart.stories.tsx +70 -2
  36. package/src/components/PieChart/PieChart.tsx +82 -30
  37. package/src/components/PieChart/PieChartBases.tsx +32 -5
  38. package/src/components/PieChart/PieChartHeader.tsx +43 -0
  39. package/src/components/PieChart/PieChartLegend.tsx +83 -20
  40. package/src/components/PieChart/PieChartLegendList.tsx +10 -6
  41. package/src/components/PieChart/PieChartLegendListItem.tsx +30 -0
  42. package/src/components/PieChart/PieChartLegendMarker.tsx +9 -3
  43. package/src/components/PieChart/colorPalettes.ts +4 -0
  44. package/src/components/PieChart/stories/fixtures.ts +53 -0
  45. package/src/components/PieChart/styles.ts +24 -0
  46. package/src/components/PieChart/types.ts +13 -4
  47. package/src/components/SegmentedPieChart/SegmentedPieChart.tsx +1 -1
  48. package/src/components/WidgetCard/Content.tsx +19 -0
  49. package/src/components/WidgetCard/Header.tsx +45 -0
  50. package/src/components/WidgetCard/Title.tsx +10 -0
  51. package/src/components/WidgetCard/WidgetCard.tsx +38 -0
  52. package/src/components/WidgetCard/WidgetCardBase.tsx +27 -0
  53. package/src/components/WidgetCard/WithWidgetCard.tsx +18 -0
  54. package/src/components/WidgetCard/index.ts +5 -0
  55. package/src/components/WidgetCard/types.ts +14 -0
  56. package/src/components/WithLink.tsx +30 -0
  57. package/src/components/index.ts +59 -56
  58. package/src/themes/main.ts +1 -0
  59. package/src/types/emotion.ts +1 -0
  60. package/tsbuildcache +1 -1
  61. package/tsconfig.build.json +2 -0
  62. /package/src/components/LinksTabBar/{LinksTabBar.spec.tsx → LinksTabBar.specBackup.tsx} +0 -0
  63. /package/src/components/WithVisibleLG/{WithVisibleLG.spec.tsx → WithVisibleLG.specBackup.tsx} +0 -0
  64. /package/src/components/WithVisibleMD/{WithVisibleMD.spec.tsx → WithVisibleMD.specBackup.tsx} +0 -0
  65. /package/src/components/WithVisibleSM/{WithVisibleSM.spec.tsx → WithVisibleSM.specBackup.tsx} +0 -0
  66. /package/src/components/WithVisibleUpToLG/{WithVisibleUpToLG.spec.tsx → WithVisibleUpToLG.specBackup.tsx} +0 -0
@@ -18,6 +18,7 @@ type Colors = MakeColors<[
18
18
  'grey',
19
19
  'grey20',
20
20
  'grey40',
21
+ 'greyShadow16',
21
22
  'greyShadow24',
22
23
  'greyDarker',
23
24
  'greyDarker40',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ssa-ui-kit/core",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "private": false,
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "devDependencies": {
36
36
  "@emotion/jest": "^11.11.0",
37
- "@nivo/line": "0.83.0",
37
+ "@nivo/line": "0.84.0",
38
38
  "@playwright/test": "^1.48.0",
39
39
  "@testing-library/jest-dom": "^5.16.5",
40
40
  "@types/testing-library__jest-dom": "^5.14.6",
@@ -54,8 +54,8 @@
54
54
  "@emotion/css": "^11.11.0",
55
55
  "@emotion/react": "^11.10.5",
56
56
  "@emotion/styled": "^11.10.5",
57
- "@nivo/core": "^0.83.0",
58
- "@nivo/pie": "0.83.0",
57
+ "@nivo/core": "^0.84.0",
58
+ "@nivo/pie": "0.84.0",
59
59
  "react": "18.x",
60
60
  "react-dom": "18.x",
61
61
  "react-hook-form": "^7.46.1",
@@ -0,0 +1,62 @@
1
+ import { createContext, useContext, useState } from 'react';
2
+
3
+ export type FullscreenModeContextType = {
4
+ isFullscreenMode: boolean;
5
+ activeId: null | number | string;
6
+ toggleFullscreenMode: () => void;
7
+ setFullscreenMode: (isFullscreenMode: boolean) => void;
8
+ setActiveId: (activeId: null | number | string) => void;
9
+ };
10
+
11
+ export const FullscreenModeContext = createContext<FullscreenModeContextType>({
12
+ isFullscreenMode: false,
13
+ activeId: null,
14
+ toggleFullscreenMode: () => {
15
+ // no-op
16
+ },
17
+ setFullscreenMode: () => {
18
+ // no-op
19
+ },
20
+ setActiveId: () => {
21
+ // no-op
22
+ },
23
+ });
24
+
25
+ export const FullscreenModeProvider = ({
26
+ children,
27
+ }: React.PropsWithChildren) => {
28
+ const [isFullscreenMode, setFullscreenMode] = useState(false);
29
+ const [activeId, setActiveId] =
30
+ useState<FullscreenModeContextType['activeId']>(null);
31
+ const toggleFullscreenMode = () => {
32
+ setFullscreenMode((prevState) => !prevState);
33
+ };
34
+ return (
35
+ <FullscreenModeContext.Provider
36
+ value={{
37
+ isFullscreenMode,
38
+ activeId,
39
+ setFullscreenMode,
40
+ toggleFullscreenMode,
41
+ setActiveId,
42
+ }}>
43
+ {children}
44
+ </FullscreenModeContext.Provider>
45
+ );
46
+ };
47
+
48
+ export const useFullscreenMode = () => useContext(FullscreenModeContext);
49
+
50
+ export const WithFullscreenMode = <T extends object>(
51
+ Component: React.ComponentType<T>,
52
+ rest?: Parameters<typeof FullscreenModeProvider>[0],
53
+ ) => {
54
+ const decoratedComp = (props: T) => (
55
+ <FullscreenModeProvider {...rest}>
56
+ <Component {...props} />
57
+ </FullscreenModeProvider>
58
+ );
59
+
60
+ decoratedComp.displayName = `WithFullscreenMode(${Component.displayName})`;
61
+ return decoratedComp;
62
+ };
@@ -0,0 +1,26 @@
1
+ import { SVGProps } from '@components/Icon/types';
2
+
3
+ export const Maximize = ({
4
+ fill = '#000',
5
+ size = 24,
6
+ tooltip = 'Maximize',
7
+ ...props
8
+ }: SVGProps) => (
9
+ <svg
10
+ width={`${size}px`}
11
+ height={`${size}px`}
12
+ viewBox="0 0 24 24"
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ xmlnsXlink="http://www.w3.org/1999/xlink"
15
+ {...props}>
16
+ <title>{tooltip}</title>
17
+ <path
18
+ fillRule="evenodd"
19
+ clipRule="evenodd"
20
+ d="M2.30005 4.00005C2.30005 3.06116 3.06116 2.30005 4.00005 2.30005H8.00005C8.38665 2.30005 8.70005 2.61345 8.70005 3.00005C8.70005 3.38665 8.38665 3.70005 8.00005 3.70005H4.00005C3.83436 3.70005 3.70005 3.83436 3.70005 4.00005V8.00005C3.70005 8.38665 3.38665 8.70005 3.00005 8.70005C2.61345 8.70005 2.30005 8.38665 2.30005 8.00005V4.00005ZM15.3 3.00005C15.3 2.61345 15.6134 2.30005 16 2.30005H20C20.9389 2.30005 21.7001 3.06116 21.7001 4.00005V8.00005C21.7001 8.38665 21.3866 8.70005 21 8.70005C20.6135 8.70005 20.3 8.38665 20.3 8.00005V4.00005C20.3 3.83436 20.1657 3.70005 20 3.70005H16C15.6134 3.70005 15.3 3.38665 15.3 3.00005ZM3.00005 15.3C3.38665 15.3 3.70005 15.6134 3.70005 16V20C3.70005 20.1657 3.83436 20.3 4.00005 20.3H8.00005C8.38665 20.3 8.70005 20.6135 8.70005 21C8.70005 21.3866 8.38665 21.7001 8.00005 21.7001H4.00005C3.06116 21.7001 2.30005 20.9389 2.30005 20V16C2.30005 15.6134 2.61345 15.3 3.00005 15.3ZM21 15.3C21.3866 15.3 21.7001 15.6134 21.7001 16V20C21.7001 20.9389 20.9389 21.7001 20 21.7001H16C15.6134 21.7001 15.3 21.3866 15.3 21C15.3 20.6135 15.6134 20.3 16 20.3H20C20.1657 20.3 20.3 20.1657 20.3 20V16C20.3 15.6134 20.6135 15.3 21 15.3Z"
21
+ fill={fill}
22
+ />
23
+ </svg>
24
+ );
25
+
26
+ export const ICON_NAME = 'maximize';
@@ -57,3 +57,4 @@ export * as Edit from './Edit';
57
57
  export * as Import from './Import';
58
58
  export * as Pages from './Pages';
59
59
  export * as Roles from './Roles';
60
+ export * as Maximize from './Maximize';
@@ -1,11 +1,9 @@
1
1
  import { useTheme } from '@emotion/react';
2
- import {
3
- DropdownOption,
4
- Typography,
5
- Wrapper,
6
- Dropdown,
7
- usePaginationContext,
8
- } from '@components';
2
+ import DropdownOption from '@components/DropdownOption/DropdownOption';
3
+ import Typography from '@components/Typography/Typography';
4
+ import Wrapper from '@components/Wrapper/Wrapper';
5
+ import Dropdown from '@components/Dropdown/Dropdown';
6
+ import { usePaginationContext } from '@components/Pagination/PaginationContext';
9
7
  import { RowsPerPageDropdownProps } from './types';
10
8
  import { DEFAULT_PER_PAGE_VALUE, ROWS_PER_PAGE_LIST } from '../../constants';
11
9
 
@@ -1,9 +1,9 @@
1
+ import { Fragment, useState } from 'react';
1
2
  import type { Meta, StoryObj } from '@storybook/react';
2
3
  import { css, useTheme } from '@emotion/react';
3
4
  import Typography from '@components/Typography';
4
-
5
5
  import { PieChart, PieChartLegend, pieChartPalettes } from './index';
6
- import { fitnessData, accountData } from './stories/fixtures';
6
+ import { fitnessData, accountData, eventsDataBig } from './stories/fixtures';
7
7
 
8
8
  export default {
9
9
  title: 'Charts/PieChart',
@@ -180,3 +180,71 @@ export const CustomColors: StoryObj<typeof PieChart> = () => {
180
180
  );
181
181
  };
182
182
  CustomColors.args = {};
183
+
184
+ export const FullscreenAndTitle: StoryObj<typeof PieChart> = () => {
185
+ const theme = useTheme();
186
+ const [isFullscreenMode, setFullscreenMode] = useState(false);
187
+ const { legendColorNames, pieChartColors } =
188
+ pieChartPalettes.getBalancePalette(theme);
189
+
190
+ return (
191
+ <PieChart
192
+ data={eventsDataBig}
193
+ onFullscreenModeChange={setFullscreenMode}
194
+ colors={pieChartColors}
195
+ activeHighlight
196
+ isInteractive
197
+ innerRadius={0}
198
+ padAngle={0}
199
+ cornerRadius={0}
200
+ css={{
201
+ padding: 20,
202
+ }}
203
+ activeInnerRadiusOffset={0}
204
+ activeOuterRadiusOffset={isFullscreenMode ? 40 : 7}
205
+ features={['header', 'fullscreenMode']}
206
+ cardProps={{
207
+ title: 'Events',
208
+ }}
209
+ tooltip={() => <Fragment></Fragment>}>
210
+ <PieChartLegend
211
+ data={eventsDataBig}
212
+ colors={legendColorNames}
213
+ activeHighlight
214
+ markerStyles={css`
215
+ width: 10px;
216
+ height: 10px;
217
+ `}
218
+ labelListStyles={css`
219
+ li {
220
+ height: ${isFullscreenMode ? 'auto' : '34px'};
221
+ }
222
+ h6 {
223
+ color: ${theme.colors.greyDarker};
224
+ line-height: 34px;
225
+ font-size: 14px;
226
+ &:nth-of-type(1) {
227
+ font-weight: 500;
228
+ }
229
+ &:nth-of-type(2) {
230
+ font-weight: 700;
231
+ font-size: 12px;
232
+ }
233
+ }
234
+ `}
235
+ valueListStyles={css`
236
+ li {
237
+ justify-content: flex-end;
238
+ height: ${isFullscreenMode ? 'auto' : '34px'};
239
+ }
240
+ h6 {
241
+ color: ${theme.colors.greyDarker};
242
+ font-weight: 700;
243
+ font-size: 12px;
244
+ }
245
+ `}
246
+ />
247
+ </PieChart>
248
+ );
249
+ };
250
+ FullscreenAndTitle.args = {};
@@ -1,44 +1,96 @@
1
+ import { useEffect } from 'react';
1
2
  import { ResponsivePie } from '@nivo/pie';
3
+ import {
4
+ useFullscreenMode,
5
+ WithFullscreenMode,
6
+ } from '@components/FullscreenModeContext';
7
+ import { WithWidgetCard } from '@components/WidgetCard';
2
8
  import { PieChartProps } from './types';
3
-
4
9
  import { PieChartBase, PieChartTextBase } from './PieChartBases';
10
+ import { PieChartHeader } from './PieChartHeader';
5
11
 
6
- export const PieChart = ({
12
+ const PieChartComponent = ({
7
13
  as,
8
14
  className,
9
15
  title,
10
16
  children,
11
- width = 400,
17
+ width = '400px',
18
+ features = [],
19
+ cardProps,
20
+ activeHighlight = false,
21
+ onFullscreenModeChange,
12
22
  ...chartProps
13
23
  }: PieChartProps) => {
24
+ const { isFullscreenMode, activeId, setActiveId } = useFullscreenMode();
25
+ const {
26
+ activeInnerRadiusOffset = 0,
27
+ activeOuterRadiusOffset = 0,
28
+ isInteractive = false,
29
+ } = chartProps;
30
+
31
+ let internalOffset = 0;
32
+ if (isInteractive) {
33
+ internalOffset = Math.max(
34
+ ...[activeInnerRadiusOffset, activeOuterRadiusOffset],
35
+ );
36
+ }
37
+
38
+ useEffect(() => {
39
+ onFullscreenModeChange?.(isFullscreenMode);
40
+ }, [isFullscreenMode]);
41
+
14
42
  return (
15
- <PieChartBase
16
- as={as}
17
- className={className}
18
- css={{
19
- width,
43
+ <WithWidgetCard
44
+ features={features}
45
+ width={`calc(${width} + ${internalOffset}px)`}
46
+ cardProps={{
47
+ headerContent: <PieChartHeader features={features} />,
48
+ ...cardProps,
20
49
  }}>
21
- <div className="pie-chart-wrapper">
22
- <ResponsivePie
23
- isInteractive={false}
24
- innerRadius={0.8}
25
- enableArcLinkLabels={false}
26
- enableArcLabels={false}
27
- padAngle={2}
28
- cornerRadius={16}
29
- activeOuterRadiusOffset={8}
30
- colors={{ datum: 'data.color' }}
31
- arcLinkLabelsSkipAngle={10}
32
- arcLinkLabelsTextColor="#333333"
33
- arcLinkLabelsThickness={2}
34
- arcLinkLabelsColor={{ from: 'color' }}
35
- arcLabelsSkipAngle={10}
36
- layers={['arcs', 'arcLinkLabels', 'arcLabels']}
37
- {...chartProps}
38
- />
39
- {title && <PieChartTextBase>{title}</PieChartTextBase>}
40
- </div>
41
- {children}
42
- </PieChartBase>
50
+ <PieChartBase
51
+ as={as}
52
+ className={className}
53
+ width={`calc(${width} + ${internalOffset}px)`}
54
+ isFullscreenMode={isFullscreenMode}>
55
+ <div className="pie-chart-wrapper">
56
+ <ResponsivePie
57
+ isInteractive={false}
58
+ margin={{
59
+ top: internalOffset,
60
+ right: internalOffset,
61
+ bottom: internalOffset,
62
+ left: internalOffset,
63
+ }}
64
+ innerRadius={0.8}
65
+ enableArcLinkLabels={false}
66
+ enableArcLabels={false}
67
+ padAngle={2}
68
+ cornerRadius={16}
69
+ activeInnerRadiusOffset={0}
70
+ activeOuterRadiusOffset={0}
71
+ colors={{ datum: 'data.color' }}
72
+ arcLinkLabelsSkipAngle={10}
73
+ arcLinkLabelsTextColor="#333333"
74
+ arcLinkLabelsThickness={2}
75
+ arcLinkLabelsColor={{ from: 'color' }}
76
+ arcLabelsSkipAngle={10}
77
+ layers={['arcs', 'arcLinkLabels', 'arcLabels']}
78
+ activeId={activeId}
79
+ onActiveIdChange={(activeId: string | number | null) => {
80
+ activeHighlight && setActiveId(activeId);
81
+ }}
82
+ {...chartProps}
83
+ />
84
+ {title && (
85
+ <PieChartTextBase isFullscreenMode={isFullscreenMode}>
86
+ {title}
87
+ </PieChartTextBase>
88
+ )}
89
+ </div>
90
+ {children}
91
+ </PieChartBase>
92
+ </WithWidgetCard>
43
93
  );
44
94
  };
95
+
96
+ export const PieChart = WithFullscreenMode(PieChartComponent);
@@ -1,19 +1,46 @@
1
1
  import styled from '@emotion/styled';
2
2
 
3
- export const PieChartBase = styled.div`
3
+ export const PieChartBase = styled.div<{
4
+ isFullscreenMode: boolean;
5
+ width?: string;
6
+ }>`
4
7
  display: flex;
5
- flex-direction: row;
6
8
  justify-content: space-between;
7
9
  align-items: center;
8
10
 
11
+ flex-direction: ${({ isFullscreenMode }) =>
12
+ isFullscreenMode ? 'column' : 'row'};
13
+
14
+ width: ${({ isFullscreenMode, width }) =>
15
+ isFullscreenMode ? '100%' : width};
16
+ height: 100%;
17
+
18
+ height: ${({ isFullscreenMode }) => (isFullscreenMode ? '100%' : 'auto')};
19
+ max-height: ${({ isFullscreenMode }) => (isFullscreenMode ? '100%' : 'none')};
20
+
9
21
  & > .pie-chart-wrapper {
10
22
  position: relative;
11
- width: 160px;
12
- height: 160px;
23
+ width: ${({ isFullscreenMode }) => (isFullscreenMode ? '100%' : '160px')};
24
+
25
+ ${({ theme }) => theme.mediaQueries.md} {
26
+ margin-bottom: 6px;
27
+ }
28
+
29
+ ${({ theme }) => theme.mediaQueries.lg} {
30
+ margin-bottom: 0;
31
+ }
32
+ height: ${({ isFullscreenMode }) => (isFullscreenMode ? '100%' : '160px')};
33
+
34
+ & > div > div {
35
+ display: ${({ isFullscreenMode }) =>
36
+ isFullscreenMode ? 'flex' : 'block'};
37
+ justify-content: ${({ isFullscreenMode }) =>
38
+ isFullscreenMode ? 'center' : 'unset'};
39
+ }
13
40
  }
14
41
  `;
15
42
 
16
- export const PieChartTextBase = styled.div`
43
+ export const PieChartTextBase = styled.div<{ isFullscreenMode: boolean }>`
17
44
  position: absolute;
18
45
  display: flex;
19
46
  align-items: center;
@@ -0,0 +1,43 @@
1
+ import { Fragment } from 'react';
2
+ import { useTheme } from '@emotion/react';
3
+ import Icon from '@components/Icon';
4
+ import Wrapper from '@components/Wrapper';
5
+ import { useFullscreenMode } from '@components/FullscreenModeContext';
6
+ import { PieChartProps } from './types';
7
+ import { PieChartButton } from './styles';
8
+
9
+ export const PieChartHeader = ({
10
+ features = [],
11
+ }: Pick<PieChartProps, 'features'>) => {
12
+ const theme = useTheme();
13
+ const { toggleFullscreenMode, isFullscreenMode } = useFullscreenMode();
14
+
15
+ const handleToggleFullscreenMode = (
16
+ event: React.MouseEvent<HTMLButtonElement>,
17
+ ) => {
18
+ event.stopPropagation();
19
+ event.preventDefault();
20
+ toggleFullscreenMode();
21
+ };
22
+
23
+ if (!features.length) {
24
+ return <Fragment></Fragment>;
25
+ }
26
+ return (
27
+ <Wrapper css={{ width: 'auto', marginLeft: 'auto' }}>
28
+ {features.includes('fullscreenMode') && (
29
+ <PieChartButton variant="tertiary" onClick={handleToggleFullscreenMode}>
30
+ <Icon
31
+ name={isFullscreenMode ? 'cross' : 'maximize'}
32
+ css={{
33
+ cursor: 'pointer',
34
+ }}
35
+ tooltip={isFullscreenMode ? 'Close' : 'Maximize'}
36
+ size={18}
37
+ color={theme.colors.greyFilterIcon}
38
+ />
39
+ </PieChartButton>
40
+ )}
41
+ </Wrapper>
42
+ );
43
+ };
@@ -1,32 +1,56 @@
1
1
  import { useTheme } from '@emotion/react';
2
- import { Fragment } from 'react';
3
2
  import Typography from '@components/Typography';
4
3
 
4
+ import { useFullscreenMode } from '@components/FullscreenModeContext';
5
+ import Wrapper from '@components/Wrapper';
5
6
  import { PieChartLegendMarker } from './PieChartLegendMarker';
6
7
  import { PieChartLegendList } from './PieChartLegendList';
7
8
  import { PieChartLegendProps } from './types';
9
+ import {
10
+ PieChartLegendListItem,
11
+ PieChartLegendListValueListItem,
12
+ } from './PieChartLegendListItem';
8
13
 
9
14
  export const PieChartLegend = ({
10
15
  data,
11
16
  colors,
12
17
  backgroundColors,
13
- renderLabel,
14
- renderValue,
15
18
  markerStyles,
16
19
  currency,
17
20
  labelListStyles,
18
21
  valueListStyles,
19
22
  variant = 'valueList',
23
+ activeHighlight = false,
24
+ renderLabel,
25
+ renderValue,
20
26
  }: PieChartLegendProps) => {
21
27
  const theme = useTheme();
22
28
  const isValueList = variant === 'valueList';
29
+ const { isFullscreenMode, activeId, setActiveId } = useFullscreenMode();
30
+ const handleActiveIdChange = (newActiveId: null | number | string) => {
31
+ if (activeHighlight) {
32
+ setActiveId(newActiveId);
33
+ }
34
+ };
23
35
  return (
24
- <Fragment>
25
- <PieChartLegendList css={labelListStyles}>
36
+ <Wrapper css={{ width: 'auto' }}>
37
+ <PieChartLegendList
38
+ css={labelListStyles}
39
+ isFullscreenMode={isFullscreenMode}>
26
40
  {data.map((item, index) => {
27
41
  const { id, label, value, legendValue } = item;
42
+ const isActive = id === activeId;
28
43
  return (
29
- <li key={`tag-${id}`}>
44
+ <PieChartLegendListItem
45
+ key={`tag-${id}`}
46
+ isActive={isActive}
47
+ isFullscreenMode={isFullscreenMode}
48
+ onMouseEnter={() => {
49
+ handleActiveIdChange(id);
50
+ }}
51
+ onMouseLeave={() => {
52
+ handleActiveIdChange(null);
53
+ }}>
30
54
  <PieChartLegendMarker
31
55
  color={
32
56
  backgroundColors ? undefined : colors?.[index] || 'purple'
@@ -36,9 +60,18 @@ export const PieChartLegend = ({
36
60
  }
37
61
  as={'span'}
38
62
  css={markerStyles}
63
+ isFullscreenMode={isFullscreenMode}
39
64
  />
40
65
  {isValueList ? (
41
- <Typography variant="h6">
66
+ <Typography
67
+ variant="h6"
68
+ css={{
69
+ alignSelf: 'start',
70
+ marginRight: 5,
71
+ height: 'auto',
72
+ lineHeight: '34px',
73
+ alignContent: 'center',
74
+ }}>
42
75
  {typeof renderLabel === 'function'
43
76
  ? renderLabel(item)
44
77
  : label}
@@ -58,23 +91,53 @@ export const PieChartLegend = ({
58
91
  </span>
59
92
  </Typography>
60
93
  )}
61
- </li>
94
+ {isValueList && isFullscreenMode && (
95
+ <Typography
96
+ variant="subtitle"
97
+ color={theme.colors.greyDarker60}
98
+ css={{
99
+ fontSize: isFullscreenMode ? '12px' : '0.833rem',
100
+ alignContent: isFullscreenMode && 'center',
101
+ }}>
102
+ {typeof renderValue === 'function'
103
+ ? renderValue(item)
104
+ : item.value}
105
+ </Typography>
106
+ )}
107
+ </PieChartLegendListItem>
62
108
  );
63
109
  })}
64
110
  </PieChartLegendList>
65
- {isValueList && (
66
- <PieChartLegendList css={valueListStyles}>
67
- {data.map((item) => (
68
- <li key={`subtitle-${item.id}`}>
69
- <Typography variant="subtitle" color={theme.colors.greyDarker60}>
70
- {typeof renderValue === 'function'
71
- ? renderValue(item)
72
- : item.value}
73
- </Typography>
74
- </li>
75
- ))}
111
+ {isValueList && !isFullscreenMode && (
112
+ <PieChartLegendList
113
+ css={valueListStyles}
114
+ isFullscreenMode={isFullscreenMode}>
115
+ {data.map((item) => {
116
+ const { id } = item;
117
+ const isActive = id === activeId;
118
+ return (
119
+ <PieChartLegendListValueListItem
120
+ key={`subtitle-${id}`}
121
+ isActive={isActive}
122
+ css={{ paddingLeft: 20 }}
123
+ onMouseEnter={() => {
124
+ handleActiveIdChange(id);
125
+ }}
126
+ onMouseLeave={() => {
127
+ handleActiveIdChange(null);
128
+ }}>
129
+ <Typography
130
+ variant="subtitle"
131
+ color={theme.colors.greyDarker60}>
132
+ {typeof renderValue === 'function'
133
+ ? renderValue(item)
134
+ : item.value}
135
+ </Typography>
136
+ </PieChartLegendListValueListItem>
137
+ );
138
+ })}
76
139
  </PieChartLegendList>
77
140
  )}
78
- </Fragment>
141
+ </Wrapper>
79
142
  );
80
143
  };
@@ -1,19 +1,23 @@
1
1
  import styled from '@emotion/styled';
2
2
 
3
- export const PieChartLegendList = styled.ul`
3
+ export const PieChartLegendList = styled.ul<{ isFullscreenMode?: boolean }>`
4
4
  display: flex;
5
- flex-flow: column;
6
5
  justify-content: center;
7
6
  list-style: none;
7
+ flex-flow: ${({ isFullscreenMode }) =>
8
+ isFullscreenMode ? 'row wrap' : 'column nowrap'};
8
9
 
9
- height: 100%;
10
10
  padding: 0;
11
- margin: 0;
12
- gap: 14px;
11
+ height: ${({ isFullscreenMode }) => (isFullscreenMode ? 'auto' : '100%')};
12
+ margin: ${({ isFullscreenMode }) => (isFullscreenMode ? '40px 0 50px' : 0)};
13
+ gap: ${({ isFullscreenMode }) => (isFullscreenMode ? '0 20px' : 0)};
13
14
 
14
15
  li {
16
+ height: 34px;
15
17
  display: flex;
16
18
  align-items: center;
17
- height: 20px;
19
+ text-align: left;
20
+ white-space: nowrap;
21
+ padding-right: ${({ isFullscreenMode }) => isFullscreenMode && '12px'};
18
22
  }
19
23
  `;
@@ -0,0 +1,30 @@
1
+ import styled from '@emotion/styled';
2
+
3
+ export const PieChartLegendListItem = styled.li<{
4
+ isFullscreenMode?: boolean;
5
+ isActive?: boolean;
6
+ }>`
7
+ display: flex;
8
+ align-items: center;
9
+ height: ${({ isFullscreenMode }) => (isFullscreenMode ? 'auto' : '22px')};
10
+ padding-right: ${({ isFullscreenMode }) => !isFullscreenMode && '5px'};
11
+ background: ${({ isActive, theme }) =>
12
+ isActive && `${theme.colors.greyLighter}`};
13
+ border-radius: ${({ isFullscreenMode, isActive }) =>
14
+ isFullscreenMode && isActive && '5px'};
15
+ border-top-left-radius: ${({ isFullscreenMode, isActive }) =>
16
+ !isFullscreenMode && isActive && '5px'};
17
+ border-bottom-left-radius: ${({ isFullscreenMode, isActive }) =>
18
+ !isFullscreenMode && isActive && '5px'};
19
+ `;
20
+
21
+ export const PieChartLegendListValueListItem = styled.li<{
22
+ isActive?: boolean;
23
+ }>`
24
+ padding: 0 12px 0 20px;
25
+ justify-content: flex-start;
26
+ background: ${({ isActive, theme }) =>
27
+ isActive && `${theme.colors.greyLighter}`};
28
+ border-top-right-radius: ${({ isActive }) => isActive && '5px'};
29
+ border-bottom-right-radius: ${({ isActive }) => isActive && '5px'};
30
+ `;