@ssa-ui-kit/widgets 0.0.1-alpha → 0.0.2-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/CollapsibleNavBar/CollapsibleNavBar.d.ts +6 -0
- package/dist/components/CollapsibleNavBar/CollapsibleNavBarBase.d.ts +8 -0
- package/dist/components/CollapsibleNavBar/CollapsibleNavBarItem.d.ts +8 -0
- package/dist/components/CollapsibleNavBar/CollapsibleNavBarLink.d.ts +9 -0
- package/dist/components/CollapsibleNavBar/CollapsibleNavBarList.d.ts +8 -0
- package/dist/components/CollapsibleNavBar/CollapsibleNavBarWrapper.d.ts +8 -0
- package/dist/components/CollapsibleNavBar/CollapsibleNavContentToggle.d.ts +3 -0
- package/dist/components/CollapsibleNavBar/CollapsibleNavToggle.d.ts +2 -0
- package/dist/components/CollapsibleNavBar/CollapsibleNavToggleWrapper.d.ts +8 -0
- package/dist/components/CollapsibleNavBar/NavBarAccordionContent.d.ts +16 -0
- package/dist/components/CollapsibleNavBar/NavBarItemWithSubMenu.d.ts +5 -0
- package/dist/components/CollapsibleNavBar/NavBarItemWithoutSubMenu.d.ts +6 -0
- package/dist/components/CollapsibleNavBar/NavBarPopover.d.ts +6 -0
- package/dist/components/CollapsibleNavBar/TriggerIcon.d.ts +6 -0
- package/dist/components/CollapsibleNavBar/index.d.ts +2 -0
- package/dist/components/CollapsibleNavBar/stories/Logo.d.ts +1 -0
- package/dist/components/CollapsibleNavBar/stories/StoryComponent.d.ts +2 -0
- package/dist/components/CollapsibleNavBar/stories/consts.d.ts +2 -0
- package/dist/components/CollapsibleNavBar/stories/styles.d.ts +2 -0
- package/dist/components/CollapsibleNavBar/styles.d.ts +10 -0
- package/dist/components/CollapsibleNavBar/types.d.ts +12 -0
- package/dist/components/NavBar/types.d.ts +17 -0
- package/dist/components/TableFilters/TableFiltersAccordion.d.ts +1 -1
- package/dist/components/TableFilters/TableFiltersAccordionContent.d.ts +2 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/components/CollapsibleNavBar/CollapsibleNavBar.e2e.ts +115 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavBar.spec.tsx +54 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavBar.tsx +55 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavBarBase.ts +122 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavBarItem.ts +28 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavBarLink.ts +34 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavBarList.ts +18 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavBarWrapper.ts +23 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavContentToggle.tsx +24 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavToggle.tsx +52 -0
- package/src/components/CollapsibleNavBar/CollapsibleNavToggleWrapper.ts +16 -0
- package/src/components/CollapsibleNavBar/NavBarAccordionContent.tsx +33 -0
- package/src/components/CollapsibleNavBar/NavBarItemWithSubMenu.tsx +84 -0
- package/src/components/CollapsibleNavBar/NavBarItemWithoutSubMenu.tsx +39 -0
- package/src/components/CollapsibleNavBar/NavBarPopover.tsx +123 -0
- package/src/components/CollapsibleNavBar/TriggerIcon.tsx +35 -0
- package/src/components/CollapsibleNavBar/index.ts +2 -0
- package/src/components/CollapsibleNavBar/stories/CollapsibleNavBar.stories.tsx +57 -0
- package/src/components/CollapsibleNavBar/stories/Logo.tsx +12 -0
- package/src/components/CollapsibleNavBar/stories/StoryComponent.tsx +20 -0
- package/src/components/CollapsibleNavBar/stories/consts.ts +22 -0
- package/src/components/CollapsibleNavBar/stories/styles.ts +21 -0
- package/src/components/CollapsibleNavBar/styles.ts +119 -0
- package/src/components/CollapsibleNavBar/types.ts +14 -0
- package/src/components/ExchangeAccount/styles.ts +2 -2
- package/src/components/ExchangeAccountKeys/styles.ts +1 -0
- package/src/components/NavBar/NavBarBase.ts +2 -5
- package/src/components/NavBar/NavBarWrapper.ts +2 -2
- package/src/components/NavBar/types.ts +17 -0
- package/src/components/TableFilters/TableFiltersAccordion.tsx +1 -2
- package/src/components/TableFilters/TableFiltersAccordionContent.tsx +1 -2
- package/src/index.ts +3 -0
- package/tsbuildcache +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ssa-ui-kit/widgets",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2-alpha",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"private": false,
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"js-tokens": "^4.0.0",
|
|
30
30
|
"loose-envify": "^1.4.0",
|
|
31
31
|
"scheduler": "^0.23.0",
|
|
32
|
-
"@ssa-ui-kit/
|
|
33
|
-
"@ssa-ui-kit/
|
|
34
|
-
"@ssa-ui-kit/
|
|
32
|
+
"@ssa-ui-kit/hooks": "^0.0.1-alpha",
|
|
33
|
+
"@ssa-ui-kit/core": "^0.0.2-alpha",
|
|
34
|
+
"@ssa-ui-kit/utils": "^0.0.1-alpha"
|
|
35
35
|
},
|
|
36
36
|
"browserslist": [
|
|
37
37
|
">0.1%",
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { test, Page, expect } from '@playwright/test';
|
|
2
|
+
import { SCREEN_SIZES } from '../../consts';
|
|
3
|
+
|
|
4
|
+
test.describe.configure({ mode: 'serial' });
|
|
5
|
+
|
|
6
|
+
const WIDGETS_CUSTOM_SHOTS_PATH = './custom-shots/';
|
|
7
|
+
const SCREENSHOT_PREFIX = `${WIDGETS_CUSTOM_SHOTS_PATH}widgets-collapsiblenavbar-opened__`;
|
|
8
|
+
const MOBILE_SIZE = { width: 899, height: 1200 };
|
|
9
|
+
|
|
10
|
+
const gotoPage = (page: Page) => {
|
|
11
|
+
return page.goto(
|
|
12
|
+
'http://localhost:6007/iframe.html?args=&id=widgets-collapsiblenavbar--default&viewMode=story',
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
test.describe('Widgets: CollapsibleNavBar', () => {
|
|
17
|
+
test('[1920] Should be visible', async ({ page }) => {
|
|
18
|
+
await page.setViewportSize(SCREEN_SIZES[1920]);
|
|
19
|
+
await gotoPage(page);
|
|
20
|
+
await page.locator('nav ul');
|
|
21
|
+
await page.screenshot({
|
|
22
|
+
path: `${SCREENSHOT_PREFIX}[w1920px].png`,
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('[1920] Statistics submenu should be shown after Statistics icon hovered', async ({
|
|
27
|
+
page,
|
|
28
|
+
}) => {
|
|
29
|
+
await page.setViewportSize(SCREEN_SIZES[1920]);
|
|
30
|
+
await gotoPage(page);
|
|
31
|
+
await page.locator('ul > li:nth-of-type(3) button').first().hover();
|
|
32
|
+
await page.screenshot({
|
|
33
|
+
path: `${SCREENSHOT_PREFIX}[w1920px]_statistics_submenu_popover.png`,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('[1920] Side menu should be expanded after toggle icon clicked', async ({
|
|
38
|
+
page,
|
|
39
|
+
}) => {
|
|
40
|
+
await page.setViewportSize(SCREEN_SIZES[1920]);
|
|
41
|
+
await gotoPage(page);
|
|
42
|
+
await page.click('label[for=contentToggler]');
|
|
43
|
+
await page.screenshot({
|
|
44
|
+
path: `${SCREENSHOT_PREFIX}[w1920px]_side_menu_expanded.png`,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('[1920] Statistics submenu should be showed after Statistics item clicked (expanded state)', async ({
|
|
49
|
+
page,
|
|
50
|
+
}) => {
|
|
51
|
+
await page.setViewportSize(SCREEN_SIZES[1920]);
|
|
52
|
+
await gotoPage(page);
|
|
53
|
+
await page.click('label[for=contentToggler]');
|
|
54
|
+
await page.click('#chartstatisticsaccordion');
|
|
55
|
+
await page.screenshot({
|
|
56
|
+
path: `${SCREENSHOT_PREFIX}[w1920px]_statistics_submenu_expanded.png`,
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('[1439] Should be visible', async ({ page }) => {
|
|
61
|
+
await page.setViewportSize({ width: 1439, height: 1200 });
|
|
62
|
+
await gotoPage(page);
|
|
63
|
+
await page.locator('nav ul');
|
|
64
|
+
await page.screenshot({
|
|
65
|
+
path: `${SCREENSHOT_PREFIX}[w1439px].png`,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('[1439] Statistics submenu should be shown after Statistics icon hovered', async ({
|
|
70
|
+
page,
|
|
71
|
+
}) => {
|
|
72
|
+
await page.setViewportSize({ width: 1439, height: 1200 });
|
|
73
|
+
await gotoPage(page);
|
|
74
|
+
await page.locator('ul > li:nth-of-type(3) button').first().hover();
|
|
75
|
+
await page.screenshot({
|
|
76
|
+
path: `${SCREENSHOT_PREFIX}[w1439px]_statistics_submenu_popover.png`,
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('[899] Hamburger menu icon should be visible by default', async ({
|
|
81
|
+
page,
|
|
82
|
+
}) => {
|
|
83
|
+
await page.setViewportSize(MOBILE_SIZE);
|
|
84
|
+
await gotoPage(page);
|
|
85
|
+
await page.locator('nav ui');
|
|
86
|
+
await page.screenshot({
|
|
87
|
+
path: `${SCREENSHOT_PREFIX}[w899px]_default.png`,
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('[899] Menu content should be visible after icon clicked', async ({
|
|
92
|
+
page,
|
|
93
|
+
}) => {
|
|
94
|
+
await page.setViewportSize(MOBILE_SIZE);
|
|
95
|
+
await gotoPage(page);
|
|
96
|
+
await page.click('nav > div:nth-of-type(1) > label');
|
|
97
|
+
await expect(page.getByText('Dashboard')).toBeVisible();
|
|
98
|
+
await page.screenshot({
|
|
99
|
+
path: `${SCREENSHOT_PREFIX}[w899px]_menu_opened.png`,
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('[899] Statistics submenu should be visible after Statistics item clicked', async ({
|
|
104
|
+
page,
|
|
105
|
+
}) => {
|
|
106
|
+
await page.setViewportSize(MOBILE_SIZE);
|
|
107
|
+
await gotoPage(page);
|
|
108
|
+
await page.click('nav > div:nth-of-type(1) > label');
|
|
109
|
+
await page.getByText('Statistics').click();
|
|
110
|
+
await expect(page.getByText('Max in Work')).toBeVisible();
|
|
111
|
+
await page.screenshot({
|
|
112
|
+
path: `${SCREENSHOT_PREFIX}[w899px]_statistics_submenu.png`,
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { fireEvent } from '@testing-library/dom';
|
|
2
|
+
import { ITEMS } from './stories/consts';
|
|
3
|
+
import { StoryComponent } from './stories/StoryComponent';
|
|
4
|
+
import { Logo } from './stories/Logo';
|
|
5
|
+
|
|
6
|
+
describe('CollapsibleNavBar', () => {
|
|
7
|
+
it('Should be correctly rendered', () => {
|
|
8
|
+
const { queryByText, getAllByText } = render(
|
|
9
|
+
<StoryComponent items={ITEMS} renderLogo={<Logo />} />,
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
queryByText('Dashboard');
|
|
13
|
+
queryByText('Bots');
|
|
14
|
+
queryByText('Statistics');
|
|
15
|
+
queryByText('Max in Work');
|
|
16
|
+
queryByText('History');
|
|
17
|
+
getAllByText('Settings');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('Should expand the group', () => {
|
|
21
|
+
const { container } = render(
|
|
22
|
+
<StoryComponent items={ITEMS} renderLogo={<Logo />} />,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const statisticsArrow = container.querySelector(
|
|
26
|
+
'button#chartstatisticsaccordion',
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(statisticsArrow as Node).toHaveAttribute('aria-expanded', 'false');
|
|
30
|
+
|
|
31
|
+
fireEvent.click(statisticsArrow as Node);
|
|
32
|
+
|
|
33
|
+
expect(statisticsArrow as Node).toHaveAttribute('aria-expanded', 'true');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('Should be expanded', () => {
|
|
37
|
+
const { container } = render(
|
|
38
|
+
<StoryComponent items={ITEMS} renderLogo={<Logo />} />,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const contentToggler = container.querySelector('label[for=contentToggler]');
|
|
42
|
+
const arrow = contentToggler?.querySelector('title');
|
|
43
|
+
|
|
44
|
+
expect(arrow?.textContent).toEqual('Carrot right');
|
|
45
|
+
|
|
46
|
+
fireEvent.click(contentToggler as Node);
|
|
47
|
+
|
|
48
|
+
expect(
|
|
49
|
+
container
|
|
50
|
+
.querySelector('label[for=contentToggler]')
|
|
51
|
+
?.querySelector('title')?.textContent,
|
|
52
|
+
).toEqual('Carrot left');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useLocation } from 'react-router-dom';
|
|
2
|
+
import { Wrapper } from '@ssa-ui-kit/core';
|
|
3
|
+
import * as S from './styles';
|
|
4
|
+
|
|
5
|
+
import CollapsibleNavBarBase from './CollapsibleNavBarBase';
|
|
6
|
+
import CollapsibleNavBarWrapper from './CollapsibleNavBarWrapper';
|
|
7
|
+
import CollapsibleNavBarList from './CollapsibleNavBarList';
|
|
8
|
+
import CollapsibleNavToggle from './CollapsibleNavToggle';
|
|
9
|
+
import { CollapsibleNavBarExtendedProps } from './types';
|
|
10
|
+
import { NavContentToggle } from './CollapsibleNavContentToggle';
|
|
11
|
+
import { NavBarItemWithSubMenu } from './NavBarItemWithSubMenu';
|
|
12
|
+
import { NavBarItemWithoutSubMenu } from './NavBarItemWithoutSubMenu';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* UI Component that shows the collapsible navigation bar
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
export const CollapsibleNavBar = ({
|
|
19
|
+
items,
|
|
20
|
+
renderLogo,
|
|
21
|
+
}: CollapsibleNavBarExtendedProps) => {
|
|
22
|
+
const { pathname } = useLocation();
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<CollapsibleNavBarBase>
|
|
26
|
+
<CollapsibleNavToggle />
|
|
27
|
+
|
|
28
|
+
<CollapsibleNavBarWrapper>
|
|
29
|
+
<Wrapper css={S.LogoWrapper}>
|
|
30
|
+
{renderLogo}
|
|
31
|
+
<NavContentToggle id={'contentToggler'} />
|
|
32
|
+
</Wrapper>
|
|
33
|
+
<CollapsibleNavBarList>
|
|
34
|
+
{items.map((item) => {
|
|
35
|
+
const { iconName, title } = item;
|
|
36
|
+
const keyName = iconName + title.replace(' ', '').toLowerCase();
|
|
37
|
+
return 'items' in item ? (
|
|
38
|
+
<NavBarItemWithSubMenu
|
|
39
|
+
item={item}
|
|
40
|
+
pathname={pathname}
|
|
41
|
+
key={keyName}
|
|
42
|
+
/>
|
|
43
|
+
) : (
|
|
44
|
+
<NavBarItemWithoutSubMenu
|
|
45
|
+
item={item}
|
|
46
|
+
pathname={pathname}
|
|
47
|
+
key={keyName}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
})}
|
|
51
|
+
</CollapsibleNavBarList>
|
|
52
|
+
</CollapsibleNavBarWrapper>
|
|
53
|
+
</CollapsibleNavBarBase>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import styled from '@emotion/styled';
|
|
2
|
+
import NavBarBase from '@components/NavBar/NavBarBase';
|
|
3
|
+
import { css } from '@emotion/react';
|
|
4
|
+
|
|
5
|
+
const popupIconsToggle = (isVisible: boolean) => css`
|
|
6
|
+
& a > button {
|
|
7
|
+
display: ${isVisible ? 'block' : 'none'};
|
|
8
|
+
}
|
|
9
|
+
& > div > div > div > div:first-of-type {
|
|
10
|
+
display: ${isVisible ? 'block' : 'none'};
|
|
11
|
+
& > button {
|
|
12
|
+
display: ${isVisible ? 'block' : 'none'};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
const staticIconsToggle = (isVisible: boolean) => css`
|
|
18
|
+
& a > div {
|
|
19
|
+
display: ${isVisible ? 'flex' : 'none'};
|
|
20
|
+
}
|
|
21
|
+
& > div > div > div > div:nth-of-type(2) {
|
|
22
|
+
display: ${isVisible ? 'block' : 'none'};
|
|
23
|
+
}
|
|
24
|
+
& > div > div > div:nth-of-type(2) {
|
|
25
|
+
display: ${isVisible ? 'block' : 'none'};
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
const CollapsibleNavBarBase = styled(NavBarBase)`
|
|
30
|
+
padding: 15px 0 0 15px;
|
|
31
|
+
position: absolute;
|
|
32
|
+
|
|
33
|
+
& li {
|
|
34
|
+
${popupIconsToggle(false)}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&:has(> input[type='checkbox']:checked) {
|
|
38
|
+
position: static;
|
|
39
|
+
background: linear-gradient(
|
|
40
|
+
108.3deg,
|
|
41
|
+
${({ theme }) => theme.colors.greyDarker} -0.36%,
|
|
42
|
+
${({ theme }) => theme.colors.greyDarker} 100%
|
|
43
|
+
);
|
|
44
|
+
height: 100%;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
& > input[type='checkbox'] {
|
|
48
|
+
&:checked {
|
|
49
|
+
& ~ div:first-of-type {
|
|
50
|
+
background-color: #4a4d51;
|
|
51
|
+
|
|
52
|
+
& label span {
|
|
53
|
+
opacity: 1;
|
|
54
|
+
transform: rotate(45deg) translate(-5px, -9px);
|
|
55
|
+
background: ${({ theme }) => theme.colors.white};
|
|
56
|
+
|
|
57
|
+
&:nth-last-of-type(3) {
|
|
58
|
+
opacity: 0;
|
|
59
|
+
transform: rotate(0deg) scale(0.2, 0.2);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&:nth-last-of-type(2) {
|
|
63
|
+
transform: rotate(-45deg) translate(-2px, 8px);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
& ~ div:nth-of-type(2) {
|
|
69
|
+
opacity: 1;
|
|
70
|
+
border-radius: 12px 12px 0 0;
|
|
71
|
+
height: calc(100vh - 60px);
|
|
72
|
+
|
|
73
|
+
${({ theme }) => theme.mediaQueries.xlg} {
|
|
74
|
+
border-radius: 0;
|
|
75
|
+
height: 100vh;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
${({ theme }) => theme.mediaQueries.md} {
|
|
82
|
+
width: 85px;
|
|
83
|
+
padding: 0;
|
|
84
|
+
height: 100%;
|
|
85
|
+
& li {
|
|
86
|
+
${staticIconsToggle(false)}
|
|
87
|
+
${popupIconsToggle(true)}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
${({ theme }) => theme.mediaQueries.lg} {
|
|
92
|
+
&:has(#contentToggler:checked) {
|
|
93
|
+
width: 240px;
|
|
94
|
+
|
|
95
|
+
& > div:nth-of-type(2) {
|
|
96
|
+
width: 240px;
|
|
97
|
+
padding-left: 31px;
|
|
98
|
+
& img {
|
|
99
|
+
margin-left: 0;
|
|
100
|
+
}
|
|
101
|
+
& li {
|
|
102
|
+
justify-content: flex-start;
|
|
103
|
+
& button {
|
|
104
|
+
display: flex;
|
|
105
|
+
}
|
|
106
|
+
${staticIconsToggle(true)}
|
|
107
|
+
${popupIconsToggle(false)}
|
|
108
|
+
|
|
109
|
+
& > a > span {
|
|
110
|
+
display: block;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
& div > div > div:nth-of-type(2) {
|
|
114
|
+
display: flex;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
export default CollapsibleNavBarBase;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import styled from '@emotion/styled';
|
|
2
|
+
import NavBarItem from '@components/NavBar/NavBarItem';
|
|
3
|
+
|
|
4
|
+
const CollapsibleNavBarItem = styled(NavBarItem)`
|
|
5
|
+
align-items: flex-start;
|
|
6
|
+
justify-content: flex-start;
|
|
7
|
+
|
|
8
|
+
height: auto;
|
|
9
|
+
min-height: 24px;
|
|
10
|
+
padding: 12px 0;
|
|
11
|
+
&:first-of-type {
|
|
12
|
+
padding-top: 0;
|
|
13
|
+
}
|
|
14
|
+
&:last-of-type {
|
|
15
|
+
padding-bottom: 0;
|
|
16
|
+
}
|
|
17
|
+
width: 100%;
|
|
18
|
+
& > a {
|
|
19
|
+
height: 26px;
|
|
20
|
+
}
|
|
21
|
+
${({ theme }) => theme.mediaQueries.md} {
|
|
22
|
+
justify-content: center;
|
|
23
|
+
padding: 20px 0;
|
|
24
|
+
width: 100%;
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
export default CollapsibleNavBarItem;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import styled from '@emotion/styled';
|
|
2
|
+
import NavBarLink from '@components/NavBar/NavBarLink';
|
|
3
|
+
import * as S from './styles';
|
|
4
|
+
|
|
5
|
+
const CollapsibleNavBarLink = styled(NavBarLink)<{ active?: boolean }>`
|
|
6
|
+
text-decoration: none;
|
|
7
|
+
display: inline-flex;
|
|
8
|
+
gap: 20px;
|
|
9
|
+
color: ${({ theme }) => theme.colors.white80};
|
|
10
|
+
|
|
11
|
+
${({ theme }) => S.SVGMainStyle(theme)};
|
|
12
|
+
&:hover {
|
|
13
|
+
svg {
|
|
14
|
+
filter: ${({ theme }) =>
|
|
15
|
+
`drop-shadow(-4px 4px 14px ${theme.colors.white})`};
|
|
16
|
+
& path {
|
|
17
|
+
fill: ${({ theme }) => theme.colors.white};
|
|
18
|
+
}
|
|
19
|
+
& circle {
|
|
20
|
+
stroke: ${({ theme }) => theme.colors.white};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
& > span {
|
|
26
|
+
color: ${({ theme }) => theme.colors.white80};
|
|
27
|
+
|
|
28
|
+
${({ theme }) => theme.mediaQueries.md} {
|
|
29
|
+
display: none;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
export default CollapsibleNavBarLink;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import styled from '@emotion/styled';
|
|
2
|
+
import NavBarList from '@components/NavBar/NavBarList';
|
|
3
|
+
|
|
4
|
+
const CollapsibleNavBarList = styled(NavBarList)`
|
|
5
|
+
height: auto;
|
|
6
|
+
padding: 0 0 0 15px;
|
|
7
|
+
margin: 14px 0 0 0;
|
|
8
|
+
${({ theme }) => theme.mediaQueries.md} {
|
|
9
|
+
margin-top: 90px;
|
|
10
|
+
width: 100%;
|
|
11
|
+
padding: 0;
|
|
12
|
+
}
|
|
13
|
+
${({ theme }) => theme.mediaQueries.lg} {
|
|
14
|
+
margin-top: 84px;
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export default CollapsibleNavBarList;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import styled from '@emotion/styled';
|
|
2
|
+
import NavBarWrapper from '@components/NavBar/NavBarWrapper';
|
|
3
|
+
|
|
4
|
+
const CollapsibleNavBarWrapper = styled(NavBarWrapper)`
|
|
5
|
+
transform: none;
|
|
6
|
+
transition: unset;
|
|
7
|
+
|
|
8
|
+
opacity: 0;
|
|
9
|
+
width: 100%;
|
|
10
|
+
${({ theme }) => theme.mediaQueries.md} {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
align-items: center;
|
|
14
|
+
opacity: 1;
|
|
15
|
+
height: 100%;
|
|
16
|
+
width: 85px;
|
|
17
|
+
top: auto;
|
|
18
|
+
border-radius: 0;
|
|
19
|
+
padding-top: 35px;
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
export default CollapsibleNavBarWrapper;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Icon } from '@ssa-ui-kit/core';
|
|
2
|
+
import * as S from './styles';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
export const NavContentToggle = ({ id }: { id: string }) => {
|
|
6
|
+
const [checked, setChecked] = useState(false);
|
|
7
|
+
return (
|
|
8
|
+
<div css={S.ContentToggle}>
|
|
9
|
+
<input type="checkbox" id={id} onChange={() => setChecked(!checked)} />
|
|
10
|
+
<label
|
|
11
|
+
htmlFor={id}
|
|
12
|
+
css={{
|
|
13
|
+
width: '100%',
|
|
14
|
+
height: '100%',
|
|
15
|
+
display: 'flex',
|
|
16
|
+
alignItems: 'center',
|
|
17
|
+
justifyContent: 'center',
|
|
18
|
+
cursor: 'pointer',
|
|
19
|
+
}}>
|
|
20
|
+
<Icon name={checked ? 'carrot-left' : 'carrot-right'} size={14} />
|
|
21
|
+
</label>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React, { useId } from 'react';
|
|
2
|
+
import { css } from '@emotion/react';
|
|
3
|
+
|
|
4
|
+
import CollapsibleNavToggleWrapper from './CollapsibleNavToggleWrapper';
|
|
5
|
+
|
|
6
|
+
const CollapsibleNavToggle = () => {
|
|
7
|
+
const id = useId();
|
|
8
|
+
return (
|
|
9
|
+
<>
|
|
10
|
+
<input type="checkbox" id={id} />
|
|
11
|
+
|
|
12
|
+
<CollapsibleNavToggleWrapper>
|
|
13
|
+
<label
|
|
14
|
+
htmlFor={id}
|
|
15
|
+
css={css`
|
|
16
|
+
cursor: pointer;
|
|
17
|
+
|
|
18
|
+
height: 20px;
|
|
19
|
+
width: 20px;
|
|
20
|
+
|
|
21
|
+
transform: scale(-1, 1);
|
|
22
|
+
|
|
23
|
+
span {
|
|
24
|
+
height: 2px;
|
|
25
|
+
width: 100%;
|
|
26
|
+
background: black;
|
|
27
|
+
display: block;
|
|
28
|
+
margin: 4px 0;
|
|
29
|
+
transform-origin: 4px 0;
|
|
30
|
+
transition: transform 0.3s cubic-bezier(0.77, 0.2, 0.05, 1),
|
|
31
|
+
background 0.3s cubic-bezier(0.77, 0.2, 0.05, 1),
|
|
32
|
+
opacity 0.35s ease;
|
|
33
|
+
|
|
34
|
+
&:first-of-type {
|
|
35
|
+
transform-origin: 0% 0%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:nth-last-of-type(2) {
|
|
39
|
+
transform-origin: 0% 100%;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`}>
|
|
43
|
+
<span></span>
|
|
44
|
+
<span></span>
|
|
45
|
+
<span></span>
|
|
46
|
+
</label>
|
|
47
|
+
</CollapsibleNavToggleWrapper>
|
|
48
|
+
</>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default CollapsibleNavToggle;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import styled from '@emotion/styled';
|
|
2
|
+
import NavToggleWrapper from '@components/NavBar/NavToggleWrapper';
|
|
3
|
+
|
|
4
|
+
const CollapsibleNavToggleWrapper = styled(NavToggleWrapper)`
|
|
5
|
+
border-radius: 50%;
|
|
6
|
+
background: ${({ theme }) => theme.colors.greyLighter};
|
|
7
|
+
|
|
8
|
+
height: 40px;
|
|
9
|
+
width: 40px;
|
|
10
|
+
|
|
11
|
+
${({ theme }) => theme.mediaQueries.md} {
|
|
12
|
+
display: none;
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
export default CollapsibleNavToggleWrapper;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AccordionContent, RenderContentProps } from '@ssa-ui-kit/core';
|
|
2
|
+
import CollapsibleNavBarLink from './CollapsibleNavBarLink';
|
|
3
|
+
import * as S from './styles';
|
|
4
|
+
|
|
5
|
+
export const NavBarAccordionContent = ({
|
|
6
|
+
items,
|
|
7
|
+
accordionUniqueName,
|
|
8
|
+
prefix,
|
|
9
|
+
pathname,
|
|
10
|
+
isPopover,
|
|
11
|
+
...rest
|
|
12
|
+
}: RenderContentProps & {
|
|
13
|
+
items: Array<{ path: string; title: string }>;
|
|
14
|
+
accordionUniqueName: string;
|
|
15
|
+
prefix?: string;
|
|
16
|
+
pathname: string;
|
|
17
|
+
isPopover?: boolean;
|
|
18
|
+
}) => (
|
|
19
|
+
<AccordionContent
|
|
20
|
+
{...rest}
|
|
21
|
+
css={[S.AccordionContent, isPopover && S.AccordionContentPopover]}>
|
|
22
|
+
{items.map((subMenuItem) => (
|
|
23
|
+
<CollapsibleNavBarLink
|
|
24
|
+
key={`${accordionUniqueName}-link-${subMenuItem.title
|
|
25
|
+
.replace(' ', '')
|
|
26
|
+
.toLowerCase()}`}
|
|
27
|
+
to={'/' + prefix + subMenuItem.path}
|
|
28
|
+
active={pathname === subMenuItem.path ? true : undefined}>
|
|
29
|
+
{subMenuItem.title}
|
|
30
|
+
</CollapsibleNavBarLink>
|
|
31
|
+
))}
|
|
32
|
+
</AccordionContent>
|
|
33
|
+
);
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccordionGroupContextProvider,
|
|
3
|
+
AccordionGroup,
|
|
4
|
+
Accordion,
|
|
5
|
+
Wrapper,
|
|
6
|
+
AccordionTitle,
|
|
7
|
+
} from '@ssa-ui-kit/core';
|
|
8
|
+
import CollapsibleNavBarItem from './CollapsibleNavBarItem';
|
|
9
|
+
import { NavBarAccordionContent } from './NavBarAccordionContent';
|
|
10
|
+
import { CollapsibleNavBarPopover } from './NavBarPopover';
|
|
11
|
+
import { TriggerIcon } from './TriggerIcon';
|
|
12
|
+
import { CollapsibleNavBarGroup } from './types';
|
|
13
|
+
import * as S from './styles';
|
|
14
|
+
|
|
15
|
+
export const NavBarItemWithSubMenu = ({
|
|
16
|
+
item,
|
|
17
|
+
pathname,
|
|
18
|
+
}: {
|
|
19
|
+
item: CollapsibleNavBarGroup;
|
|
20
|
+
pathname: string;
|
|
21
|
+
}) => {
|
|
22
|
+
const { iconName, iconSize, title, items, prefix } = item;
|
|
23
|
+
const uniqName = iconName + title.replace(' ', '').toLowerCase();
|
|
24
|
+
const accordionUniqName = uniqName + 'accordion';
|
|
25
|
+
return (
|
|
26
|
+
<AccordionGroupContextProvider key={uniqName}>
|
|
27
|
+
<CollapsibleNavBarItem>
|
|
28
|
+
<AccordionGroup
|
|
29
|
+
size="small"
|
|
30
|
+
css={{
|
|
31
|
+
width: '100%',
|
|
32
|
+
}}>
|
|
33
|
+
<Accordion
|
|
34
|
+
id={accordionUniqName}
|
|
35
|
+
title={title}
|
|
36
|
+
isOpened={false}
|
|
37
|
+
ariaControls={`${accordionUniqName}-panel`}
|
|
38
|
+
css={{
|
|
39
|
+
padding: 0,
|
|
40
|
+
'& ul li:last-child': {
|
|
41
|
+
paddingBottom: 10,
|
|
42
|
+
},
|
|
43
|
+
}}
|
|
44
|
+
renderContent={(props) => (
|
|
45
|
+
<NavBarAccordionContent
|
|
46
|
+
items={items}
|
|
47
|
+
accordionUniqueName={accordionUniqName}
|
|
48
|
+
prefix={prefix}
|
|
49
|
+
pathname={pathname}
|
|
50
|
+
isPopover={false}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
)}
|
|
54
|
+
renderTitle={(data) => (
|
|
55
|
+
<Wrapper onClick={data.onClick} css={S.AccordionTitleWrapper}>
|
|
56
|
+
<div css={S.IconWrapper} className="icon-wrapper">
|
|
57
|
+
<CollapsibleNavBarPopover
|
|
58
|
+
triggerIcon={
|
|
59
|
+
<TriggerIcon iconName={iconName} iconSize={iconSize} />
|
|
60
|
+
}
|
|
61
|
+
title={data.title}
|
|
62
|
+
content={
|
|
63
|
+
<NavBarAccordionContent
|
|
64
|
+
items={items}
|
|
65
|
+
accordionUniqueName={accordionUniqName}
|
|
66
|
+
prefix={prefix}
|
|
67
|
+
pathname={pathname}
|
|
68
|
+
id={accordionUniqName}
|
|
69
|
+
isOpened
|
|
70
|
+
isPopover
|
|
71
|
+
/>
|
|
72
|
+
}
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
<TriggerIcon iconName={iconName} iconSize={iconSize} />
|
|
76
|
+
<AccordionTitle {...data} css={S.AccordionTitle} />
|
|
77
|
+
</Wrapper>
|
|
78
|
+
)}
|
|
79
|
+
/>
|
|
80
|
+
</AccordionGroup>
|
|
81
|
+
</CollapsibleNavBarItem>
|
|
82
|
+
</AccordionGroupContextProvider>
|
|
83
|
+
);
|
|
84
|
+
};
|