@dnanpm/styleguide 3.5.0 → 3.5.1

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.
@@ -1,129 +1,129 @@
1
- /* "DNA Text" font definition */
2
- @font-face {
3
- font-family: 'DNA Text';
4
- font-style: normal;
5
- font-weight: 400;
6
- font-display: swap;
7
- src: url('https://banner.dna.fi/fonts/DNAText-Regular.woff2') format('woff2'),
8
- url('https://banner.dna.fi/fonts/DNAText-Regular.woff') format('woff');
9
- }
10
-
11
- @font-face {
12
- font-family: 'DNA Text';
13
- font-style: normal;
14
- font-weight: 500;
15
- font-display: swap;
16
- src: url('https://banner.dna.fi/fonts/DNAText-Medium.woff2') format('woff2'),
17
- url('https://banner.dna.fi/fonts/DNAText-Medium.woff') format('woff');
18
- }
19
-
20
- @font-face {
21
- font-family: 'DNA Text';
22
- font-style: normal;
23
- font-weight: 700;
24
- font-display: swap;
25
- src: url('https://banner.dna.fi/fonts/DNAText-Bold.woff2') format('woff2'),
26
- url('https://banner.dna.fi/fonts/DNAText-Bold.woff') format('woff');
27
- }
28
-
29
- /* "DNA Heading" font definition */
30
- @font-face {
31
- font-family: 'DNA Heading';
32
- font-style: normal;
33
- font-weight: 600;
34
- font-display: swap;
35
- src: url('https://banner.dna.fi/fonts/DNAHeading-DemiBold.woff2') format('woff2'),
36
- url('https://banner.dna.fi/fonts/DNAHeading-DemiBold.woff') format('woff');
37
- }
38
-
39
- @font-face {
40
- font-family: 'DNA Heading';
41
- font-style: normal;
42
- font-weight: 700;
43
- font-display: swap;
44
- src: url('https://banner.dna.fi/fonts/DNAHeading-Bold.woff2') format('woff2'),
45
- url('https://banner.dna.fi/fonts/DNAHeading-Bold.woff') format('woff');
46
- }
47
-
48
- @font-face {
49
- font-family: 'DNA Heading';
50
- font-style: normal;
51
- font-weight: 900;
52
- font-display: swap;
53
- src: url('https://banner.dna.fi/fonts/DNAHeading-Black.woff2') format('woff2'),
54
- url('https://banner.dna.fi/fonts/DNAHeading-Black.woff') format('woff');
55
- }
56
-
57
- /* "DNA Numerals" font definition */
58
- @font-face {
59
- font-family: 'DNA Numerals';
60
- font-style: normal;
61
- font-weight: 700;
62
- font-display: swap;
63
- src: url('https://banner.dna.fi/fonts/DNANumerals-Bold.woff2') format('woff2'),
64
- url('https://banner.dna.fi/fonts/DNANumerals-Bold.woff') format('woff');
65
- }
66
-
67
- /* Direct definitons of DNA fonts */
68
- @font-face {
69
- font-family: 'DNA Text Regular';
70
- font-style: normal;
71
- font-weight: 400;
72
- font-display: swap;
73
- src: url('https://banner.dna.fi/fonts/DNAText-Regular.woff2') format('woff2'),
74
- url('https://banner.dna.fi/fonts/DNAText-Regular.woff') format('woff');
75
- }
76
-
77
- @font-face {
78
- font-family: 'DNA Text Medium';
79
- font-style: normal;
80
- font-weight: 500;
81
- font-display: swap;
82
- src: url('https://banner.dna.fi/fonts/DNAText-Medium.woff2') format('woff2'),
83
- url('https://banner.dna.fi/fonts/DNAText-Medium.woff') format('woff');
84
- }
85
-
86
- @font-face {
87
- font-family: 'DNA Text Bold';
88
- font-style: normal;
89
- font-weight: 700;
90
- font-display: swap;
91
- src: url('https://banner.dna.fi/fonts/DNAText-Bold.woff2') format('woff2'),
92
- url('https://banner.dna.fi/fonts/DNAText-Bold.woff') format('woff');
93
- }
94
-
95
- @font-face {
96
- font-family: 'DNA Heading Demi Bold';
97
- font-style: normal;
98
- font-weight: 600;
99
- font-display: swap;
100
- src: url('https://banner.dna.fi/fonts/DNAHeading-DemiBold.woff2') format('woff2'),
101
- url('https://banner.dna.fi/fonts/DNAHeading-DemiBold.woff') format('woff');
102
- }
103
-
104
- @font-face {
105
- font-family: 'DNA Heading Bold';
106
- font-style: normal;
107
- font-weight: 700;
108
- font-display: swap;
109
- src: url('https://banner.dna.fi/fonts/DNAHeading-Bold.woff2') format('woff2'),
110
- url('https://banner.dna.fi/fonts/DNAHeading-Bold.woff') format('woff');
111
- }
112
-
113
- @font-face {
114
- font-family: 'DNA Heading Black';
115
- font-style: normal;
116
- font-weight: 900;
117
- font-display: swap;
118
- src: url('https://banner.dna.fi/fonts/DNAHeading-Black.woff2') format('woff2'),
119
- url('https://banner.dna.fi/fonts/DNAHeading-Black.woff') format('woff');
120
- }
121
-
122
- @font-face {
123
- font-family: 'DNA Numerals Bold';
124
- font-style: normal;
125
- font-weight: 700;
126
- font-display: swap;
127
- src: url('https://banner.dna.fi/fonts/DNANumerals-Bold.woff2') format('woff2'),
128
- url('https://banner.dna.fi/fonts/DNANumerals-Bold.woff') format('woff');
129
- }
1
+ /* "DNA Text" font definition */
2
+ @font-face {
3
+ font-family: 'DNA Text';
4
+ font-style: normal;
5
+ font-weight: 400;
6
+ font-display: swap;
7
+ src: url('https://www.dna.fi/fonts/DNAText-Regular.woff2') format('woff2'),
8
+ url('https://www.dna.fi/fonts/DNAText-Regular.woff') format('woff');
9
+ }
10
+
11
+ @font-face {
12
+ font-family: 'DNA Text';
13
+ font-style: normal;
14
+ font-weight: 500;
15
+ font-display: swap;
16
+ src: url('https://www.dna.fi/fonts/DNAText-Medium.woff2') format('woff2'),
17
+ url('https://www.dna.fi/fonts/DNAText-Medium.woff') format('woff');
18
+ }
19
+
20
+ @font-face {
21
+ font-family: 'DNA Text';
22
+ font-style: normal;
23
+ font-weight: 700;
24
+ font-display: swap;
25
+ src: url('https://www.dna.fi/fonts/DNAText-Bold.woff2') format('woff2'),
26
+ url('https://www.dna.fi/fonts/DNAText-Bold.woff') format('woff');
27
+ }
28
+
29
+ /* "DNA Heading" font definition */
30
+ @font-face {
31
+ font-family: 'DNA Heading';
32
+ font-style: normal;
33
+ font-weight: 600;
34
+ font-display: swap;
35
+ src: url('https://www.dna.fi/fonts/DNAHeading-DemiBold.woff2') format('woff2'),
36
+ url('https://www.dna.fi/fonts/DNAHeading-DemiBold.woff') format('woff');
37
+ }
38
+
39
+ @font-face {
40
+ font-family: 'DNA Heading';
41
+ font-style: normal;
42
+ font-weight: 700;
43
+ font-display: swap;
44
+ src: url('https://www.dna.fi/fonts/DNAHeading-Bold.woff2') format('woff2'),
45
+ url('https://www.dna.fi/fonts/DNAHeading-Bold.woff') format('woff');
46
+ }
47
+
48
+ @font-face {
49
+ font-family: 'DNA Heading';
50
+ font-style: normal;
51
+ font-weight: 900;
52
+ font-display: swap;
53
+ src: url('https://www.dna.fi/fonts/DNAHeading-Black.woff2') format('woff2'),
54
+ url('https://www.dna.fi/fonts/DNAHeading-Black.woff') format('woff');
55
+ }
56
+
57
+ /* "DNA Numerals" font definition */
58
+ @font-face {
59
+ font-family: 'DNA Numerals';
60
+ font-style: normal;
61
+ font-weight: 700;
62
+ font-display: swap;
63
+ src: url('https://www.dna.fi/fonts/DNANumerals-Bold.woff2') format('woff2'),
64
+ url('https://www.dna.fi/fonts/DNANumerals-Bold.woff') format('woff');
65
+ }
66
+
67
+ /* Direct definitons of DNA fonts */
68
+ @font-face {
69
+ font-family: 'DNA Text Regular';
70
+ font-style: normal;
71
+ font-weight: 400;
72
+ font-display: swap;
73
+ src: url('https://www.dna.fi/fonts/DNAText-Regular.woff2') format('woff2'),
74
+ url('https://www.dna.fi/fonts/DNAText-Regular.woff') format('woff');
75
+ }
76
+
77
+ @font-face {
78
+ font-family: 'DNA Text Medium';
79
+ font-style: normal;
80
+ font-weight: 500;
81
+ font-display: swap;
82
+ src: url('https://www.dna.fi/fonts/DNAText-Medium.woff2') format('woff2'),
83
+ url('https://www.dna.fi/fonts/DNAText-Medium.woff') format('woff');
84
+ }
85
+
86
+ @font-face {
87
+ font-family: 'DNA Text Bold';
88
+ font-style: normal;
89
+ font-weight: 700;
90
+ font-display: swap;
91
+ src: url('https://www.dna.fi/fonts/DNAText-Bold.woff2') format('woff2'),
92
+ url('https://www.dna.fi/fonts/DNAText-Bold.woff') format('woff');
93
+ }
94
+
95
+ @font-face {
96
+ font-family: 'DNA Heading Demi Bold';
97
+ font-style: normal;
98
+ font-weight: 600;
99
+ font-display: swap;
100
+ src: url('https://www.dna.fi/fonts/DNAHeading-DemiBold.woff2') format('woff2'),
101
+ url('https://www.dna.fi/fonts/DNAHeading-DemiBold.woff') format('woff');
102
+ }
103
+
104
+ @font-face {
105
+ font-family: 'DNA Heading Bold';
106
+ font-style: normal;
107
+ font-weight: 700;
108
+ font-display: swap;
109
+ src: url('https://www.dna.fi/fonts/DNAHeading-Bold.woff2') format('woff2'),
110
+ url('https://www.dna.fi/fonts/DNAHeading-Bold.woff') format('woff');
111
+ }
112
+
113
+ @font-face {
114
+ font-family: 'DNA Heading Black';
115
+ font-style: normal;
116
+ font-weight: 900;
117
+ font-display: swap;
118
+ src: url('https://www.dna.fi/fonts/DNAHeading-Black.woff2') format('woff2'),
119
+ url('https://www.dna.fi/fonts/DNAHeading-Black.woff') format('woff');
120
+ }
121
+
122
+ @font-face {
123
+ font-family: 'DNA Numerals Bold';
124
+ font-style: normal;
125
+ font-weight: 700;
126
+ font-display: swap;
127
+ src: url('https://www.dna.fi/fonts/DNANumerals-Bold.woff2') format('woff2'),
128
+ url('https://www.dna.fi/fonts/DNANumerals-Bold.woff') format('woff');
129
+ }
@@ -29,6 +29,10 @@ const ButtonElement = styled__default["default"].button `
29
29
  border: 2px solid transparent;
30
30
  padding: ${styledUtils.getDividedSize(theme["default"].base.baseWidth, 5)} 0;
31
31
 
32
+ & svg {
33
+ pointer-events: none;
34
+ }
35
+
32
36
  ${({ isReversed }) => isReversed && `flex-direction: row-reverse;`}
33
37
 
34
38
  &:focus {
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import type { KeyboardEvent, MouseEvent, ReactNode } from 'react';
2
2
  import React from 'react';
3
3
  interface Props {
4
4
  /**
@@ -9,6 +9,14 @@ interface Props {
9
9
  * Content of the component
10
10
  */
11
11
  children?: ReactNode;
12
+ /**
13
+ * Allows to pass common mouse click callback to all children
14
+ */
15
+ onClick?: (e: MouseEvent<HTMLElement>) => void;
16
+ /**
17
+ * Allows to pass common keyboard key down callback to all children
18
+ */
19
+ onKeyDown?: (e: KeyboardEvent<HTMLElement>) => void;
12
20
  /**
13
21
  * Allows to define aria-label attribute for nav HTML element
14
22
  */
@@ -103,11 +103,15 @@ const DropdownList = styled["default"](CoreULStyles) `
103
103
  ${common["default"]({ elevation: 'low' })}
104
104
  `;
105
105
  const reducer = (state, action) => {
106
- var _a;
106
+ var _a, _b;
107
107
  switch (action.type) {
108
+ case 'resetNavigationState': {
109
+ const navigationItems = React.Children.toArray((_a = action === null || action === void 0 ? void 0 : action.payload) === null || _a === void 0 ? void 0 : _a.navigationItems);
110
+ return Object.assign(Object.assign({}, state), { navigationItems: navigationItems.slice(0, navigationItems.length - state.lastItemWidth.length), dropdownItems: navigationItems.slice(navigationItems.length - state.lastItemWidth.length) });
111
+ }
108
112
  case 'moveItemToDropdown': {
109
113
  const lastChild = state.navigationItems[state.navigationItems.length - 1];
110
- return Object.assign(Object.assign(Object.assign({}, state), { navigationItems: state.navigationItems.slice(0, -1), dropdownItems: [lastChild, ...state.dropdownItems] }), (((_a = action === null || action === void 0 ? void 0 : action.payload) === null || _a === void 0 ? void 0 : _a.lastItem) && {
114
+ return Object.assign(Object.assign(Object.assign({}, state), { navigationItems: state.navigationItems.slice(0, -1), dropdownItems: [lastChild, ...state.dropdownItems] }), (((_b = action === null || action === void 0 ? void 0 : action.payload) === null || _b === void 0 ? void 0 : _b.lastItem) && {
111
115
  lastItemWidth: [...state.lastItemWidth, action.payload.lastItem.clientWidth],
112
116
  }));
113
117
  }
@@ -164,7 +168,7 @@ const PriorityNavigation = (_a) => {
164
168
  const toggleDropdown = () => setIsDropdownOpen(!isDropdownOpen);
165
169
  const navigationItems = React.useRef(new Map()).current;
166
170
  const initialState = {
167
- navigationItems: props.children,
171
+ navigationItems: React.Children.toArray(props.children),
168
172
  dropdownItems: [],
169
173
  lastItemWidth: [],
170
174
  };
@@ -197,6 +201,9 @@ const PriorityNavigation = (_a) => {
197
201
  child.type === PriorityNavigationItem["default"] &&
198
202
  child.props.isActive));
199
203
  useOutsideClick["default"](listsContainerRef, () => {
204
+ if (isMobileNavigationOpen) {
205
+ setIsMobileNavigationOpen(false);
206
+ }
200
207
  if (isDropdownOpen) {
201
208
  setIsDropdownOpen(false);
202
209
  }
@@ -212,16 +219,24 @@ const PriorityNavigation = (_a) => {
212
219
  checkHorizontalOverflow,
213
220
  isMobile,
214
221
  ]);
215
- const navigationListItems = React.Children.map([...state.navigationItems, ...(isMobile ? state.dropdownItems : [])], (navigationItem, index) => React.isValidElement(navigationItem) &&
216
- navigationItem.type === PriorityNavigationItem["default"] && (React__default["default"].createElement(PriorityNavigationItem["default"], { id: navigationItem.props.id, key: navigationItem.key, isActive: navigationItem.props.isActive, className: navigationItem.props.className, "data-testid": navigationItem.props['data-testid'], innerRef: instance => instance && navigationItems.set(index, instance) },
217
- navigationItem.props.children,
218
- navigationItem.props.isActive && isMobile && (React__default["default"].createElement(Icon["default"], { icon: icons.Check, color: theme["default"].color.default.pink })))));
222
+ React.useEffect(() => {
223
+ dispatch({
224
+ type: 'resetNavigationState',
225
+ payload: {
226
+ navigationItems: props.children,
227
+ },
228
+ });
229
+ setIsMobileNavigationOpen(false);
230
+ }, [props.children]);
219
231
  return (React__default["default"].createElement(Container, { id: props.id, "aria-label": props.navigationLabel, className: props.className, "data-testid": dataTestId },
220
232
  React__default["default"].createElement(ListsContainer, { ref: listsContainerRef },
221
233
  isMobile && selectedItem && (React__default["default"].createElement(MobileDropdown, { onClick: toggleMobileNavigation },
222
234
  selectedItem,
223
235
  React__default["default"].createElement(Icon["default"], { icon: isMobileNavigationOpen ? icons.ChevronUp : icons.ChevronDown }))),
224
- React__default["default"].createElement(NavigationList, { ref: navigationListRef, isMobileNavigationOpen: isMobileNavigationOpen }, navigationListItems),
236
+ React__default["default"].createElement(NavigationList, { ref: navigationListRef, isMobileNavigationOpen: isMobileNavigationOpen }, React.Children.map([...state.navigationItems, ...(isMobile ? state.dropdownItems : [])], (navigationItem, index) => React.isValidElement(navigationItem) &&
237
+ navigationItem.type === PriorityNavigationItem["default"] && (React__default["default"].createElement(PriorityNavigationItem["default"], { id: navigationItem.props.id, key: navigationItem.key, onClick: navigationItem.props.onClick || props.onClick, onKeyDown: navigationItem.props.onKeyDown || props.onKeyDown, isActive: navigationItem.props.isActive, className: navigationItem.props.className, "data-testid": navigationItem.props['data-testid'], innerRef: instance => instance && navigationItems.set(index, instance) },
238
+ navigationItem.props.children,
239
+ navigationItem.props.isActive && isMobile && (React__default["default"].createElement(Icon["default"], { icon: icons.Check, color: theme["default"].color.default.pink })))))),
225
240
  !isMobile && Boolean(state.dropdownItems.length) && (React__default["default"].createElement(React__default["default"].Fragment, null,
226
241
  React__default["default"].createElement(ButtonIcon["default"], { onClick: toggleDropdown, icon: isDropdownOpen ? icons.ChevronUp : icons.ChevronDown, isReversed: true }, dropdownButtonLabel),
227
242
  React__default["default"].createElement(DropdownList, { isDropdownOpen: isDropdownOpen }, state.dropdownItems))))));
@@ -1,4 +1,4 @@
1
- import type { ReactNode, RefObject } from 'react';
1
+ import type { KeyboardEvent, MouseEvent, ReactNode, RefObject } from 'react';
2
2
  import React from 'react';
3
3
  export interface Props {
4
4
  /**
@@ -10,13 +10,21 @@ export interface Props {
10
10
  */
11
11
  children?: ReactNode;
12
12
  /**
13
- * A ref object, or a ref callback function
13
+ * On component mouse click callback
14
14
  */
15
- innerRef?: RefObject<HTMLLIElement> | ((instance: HTMLLIElement | null) => void) | null;
15
+ onClick?: (e: MouseEvent<HTMLElement>) => void;
16
+ /**
17
+ * On component keyboard key down callback
18
+ */
19
+ onKeyDown?: (e: KeyboardEvent<HTMLElement>) => void;
16
20
  /**
17
21
  * Allows to set component as active
18
22
  */
19
23
  isActive?: boolean;
24
+ /**
25
+ * A ref object, or a ref callback function
26
+ */
27
+ innerRef?: RefObject<HTMLLIElement> | ((instance: HTMLLIElement | null) => void) | null;
20
28
  /**
21
29
  * Allows to pass a custom className
22
30
  */
@@ -21,6 +21,20 @@ const Element = styled["default"].li `
21
21
  padding: 1rem 1.25rem;
22
22
  flex-shrink: 0;
23
23
 
24
+ ${({ onClick }) => onClick &&
25
+ `
26
+ cursor: pointer;
27
+ `};
28
+
29
+ &:focus-within {
30
+ & > * {
31
+ border-radius: ${theme["default"].radius.s};
32
+ border: 2px solid ${theme["default"].color.focus.light};
33
+ box-shadow: 0px 0px 0px 2px ${theme["default"].color.focus.dark};
34
+ outline: none;
35
+ }
36
+ }
37
+
24
38
  ${({ isActive }) => styledUtils.media.md `
25
39
  justify-content: center;
26
40
  padding: 1rem 0;
@@ -29,26 +43,20 @@ const Element = styled["default"].li `
29
43
  border-bottom: 3px solid ${isActive ? theme["default"].color.text.pink : 'transparent'};
30
44
  `}
31
45
 
32
- & a {
46
+ & > * {
33
47
  display: block;
34
48
  color: ${({ isActive }) => (isActive ? theme["default"].color.text.pink : theme["default"].color.text.black)};
35
49
  ${({ isActive }) => isActive && `font-weight: ${theme["default"].fontWeight.bold}`};
36
50
  border: 2px solid transparent;
37
51
 
38
- &:focus {
39
- border-radius: ${theme["default"].radius.s};
40
- border: 2px solid ${theme["default"].color.focus.light};
41
- box-shadow: 0px 0px 0px 2px ${theme["default"].color.focus.dark};
42
- outline: none;
52
+ &:hover {
53
+ color: ${theme["default"].color.hover.pink};
54
+ text-decoration: none;
43
55
  }
44
56
 
45
57
  ${styledUtils.media.md `
46
58
  margin: auto;
47
59
  `}
48
-
49
- &:hover {
50
- color: ${theme["default"].color.hover.pink};
51
- }
52
60
  }
53
61
  `;
54
62
  /**
@@ -56,7 +64,7 @@ const Element = styled["default"].li `
56
64
  */
57
65
  const PriorityNavigationItem = (_a) => {
58
66
  var { 'data-testid': dataTestId } = _a, props = tslib.__rest(_a, ['data-testid']);
59
- return (React__default["default"].createElement(Element, { id: props.id, ref: props.innerRef, isActive: props.isActive, className: props.className, "data-testid": dataTestId }, props.children));
67
+ return (React__default["default"].createElement(Element, { id: props.id, ref: props.innerRef, onClick: props.onClick, onKeyDown: props.onKeyDown, isActive: props.isActive, className: props.className, "data-testid": dataTestId }, props.children));
60
68
  };
61
69
 
62
70
  exports["default"] = PriorityNavigationItem;
@@ -1,129 +1,129 @@
1
- /* "DNA Text" font definition */
2
- @font-face {
3
- font-family: 'DNA Text';
4
- font-style: normal;
5
- font-weight: 400;
6
- font-display: swap;
7
- src: url('https://banner.dna.fi/fonts/DNAText-Regular.woff2') format('woff2'),
8
- url('https://banner.dna.fi/fonts/DNAText-Regular.woff') format('woff');
9
- }
10
-
11
- @font-face {
12
- font-family: 'DNA Text';
13
- font-style: normal;
14
- font-weight: 500;
15
- font-display: swap;
16
- src: url('https://banner.dna.fi/fonts/DNAText-Medium.woff2') format('woff2'),
17
- url('https://banner.dna.fi/fonts/DNAText-Medium.woff') format('woff');
18
- }
19
-
20
- @font-face {
21
- font-family: 'DNA Text';
22
- font-style: normal;
23
- font-weight: 700;
24
- font-display: swap;
25
- src: url('https://banner.dna.fi/fonts/DNAText-Bold.woff2') format('woff2'),
26
- url('https://banner.dna.fi/fonts/DNAText-Bold.woff') format('woff');
27
- }
28
-
29
- /* "DNA Heading" font definition */
30
- @font-face {
31
- font-family: 'DNA Heading';
32
- font-style: normal;
33
- font-weight: 600;
34
- font-display: swap;
35
- src: url('https://banner.dna.fi/fonts/DNAHeading-DemiBold.woff2') format('woff2'),
36
- url('https://banner.dna.fi/fonts/DNAHeading-DemiBold.woff') format('woff');
37
- }
38
-
39
- @font-face {
40
- font-family: 'DNA Heading';
41
- font-style: normal;
42
- font-weight: 700;
43
- font-display: swap;
44
- src: url('https://banner.dna.fi/fonts/DNAHeading-Bold.woff2') format('woff2'),
45
- url('https://banner.dna.fi/fonts/DNAHeading-Bold.woff') format('woff');
46
- }
47
-
48
- @font-face {
49
- font-family: 'DNA Heading';
50
- font-style: normal;
51
- font-weight: 900;
52
- font-display: swap;
53
- src: url('https://banner.dna.fi/fonts/DNAHeading-Black.woff2') format('woff2'),
54
- url('https://banner.dna.fi/fonts/DNAHeading-Black.woff') format('woff');
55
- }
56
-
57
- /* "DNA Numerals" font definition */
58
- @font-face {
59
- font-family: 'DNA Numerals';
60
- font-style: normal;
61
- font-weight: 700;
62
- font-display: swap;
63
- src: url('https://banner.dna.fi/fonts/DNANumerals-Bold.woff2') format('woff2'),
64
- url('https://banner.dna.fi/fonts/DNANumerals-Bold.woff') format('woff');
65
- }
66
-
67
- /* Direct definitons of DNA fonts */
68
- @font-face {
69
- font-family: 'DNA Text Regular';
70
- font-style: normal;
71
- font-weight: 400;
72
- font-display: swap;
73
- src: url('https://banner.dna.fi/fonts/DNAText-Regular.woff2') format('woff2'),
74
- url('https://banner.dna.fi/fonts/DNAText-Regular.woff') format('woff');
75
- }
76
-
77
- @font-face {
78
- font-family: 'DNA Text Medium';
79
- font-style: normal;
80
- font-weight: 500;
81
- font-display: swap;
82
- src: url('https://banner.dna.fi/fonts/DNAText-Medium.woff2') format('woff2'),
83
- url('https://banner.dna.fi/fonts/DNAText-Medium.woff') format('woff');
84
- }
85
-
86
- @font-face {
87
- font-family: 'DNA Text Bold';
88
- font-style: normal;
89
- font-weight: 700;
90
- font-display: swap;
91
- src: url('https://banner.dna.fi/fonts/DNAText-Bold.woff2') format('woff2'),
92
- url('https://banner.dna.fi/fonts/DNAText-Bold.woff') format('woff');
93
- }
94
-
95
- @font-face {
96
- font-family: 'DNA Heading Demi Bold';
97
- font-style: normal;
98
- font-weight: 600;
99
- font-display: swap;
100
- src: url('https://banner.dna.fi/fonts/DNAHeading-DemiBold.woff2') format('woff2'),
101
- url('https://banner.dna.fi/fonts/DNAHeading-DemiBold.woff') format('woff');
102
- }
103
-
104
- @font-face {
105
- font-family: 'DNA Heading Bold';
106
- font-style: normal;
107
- font-weight: 700;
108
- font-display: swap;
109
- src: url('https://banner.dna.fi/fonts/DNAHeading-Bold.woff2') format('woff2'),
110
- url('https://banner.dna.fi/fonts/DNAHeading-Bold.woff') format('woff');
111
- }
112
-
113
- @font-face {
114
- font-family: 'DNA Heading Black';
115
- font-style: normal;
116
- font-weight: 900;
117
- font-display: swap;
118
- src: url('https://banner.dna.fi/fonts/DNAHeading-Black.woff2') format('woff2'),
119
- url('https://banner.dna.fi/fonts/DNAHeading-Black.woff') format('woff');
120
- }
121
-
122
- @font-face {
123
- font-family: 'DNA Numerals Bold';
124
- font-style: normal;
125
- font-weight: 700;
126
- font-display: swap;
127
- src: url('https://banner.dna.fi/fonts/DNANumerals-Bold.woff2') format('woff2'),
128
- url('https://banner.dna.fi/fonts/DNANumerals-Bold.woff') format('woff');
129
- }
1
+ /* "DNA Text" font definition */
2
+ @font-face {
3
+ font-family: 'DNA Text';
4
+ font-style: normal;
5
+ font-weight: 400;
6
+ font-display: swap;
7
+ src: url('https://www.dna.fi/fonts/DNAText-Regular.woff2') format('woff2'),
8
+ url('https://www.dna.fi/fonts/DNAText-Regular.woff') format('woff');
9
+ }
10
+
11
+ @font-face {
12
+ font-family: 'DNA Text';
13
+ font-style: normal;
14
+ font-weight: 500;
15
+ font-display: swap;
16
+ src: url('https://www.dna.fi/fonts/DNAText-Medium.woff2') format('woff2'),
17
+ url('https://www.dna.fi/fonts/DNAText-Medium.woff') format('woff');
18
+ }
19
+
20
+ @font-face {
21
+ font-family: 'DNA Text';
22
+ font-style: normal;
23
+ font-weight: 700;
24
+ font-display: swap;
25
+ src: url('https://www.dna.fi/fonts/DNAText-Bold.woff2') format('woff2'),
26
+ url('https://www.dna.fi/fonts/DNAText-Bold.woff') format('woff');
27
+ }
28
+
29
+ /* "DNA Heading" font definition */
30
+ @font-face {
31
+ font-family: 'DNA Heading';
32
+ font-style: normal;
33
+ font-weight: 600;
34
+ font-display: swap;
35
+ src: url('https://www.dna.fi/fonts/DNAHeading-DemiBold.woff2') format('woff2'),
36
+ url('https://www.dna.fi/fonts/DNAHeading-DemiBold.woff') format('woff');
37
+ }
38
+
39
+ @font-face {
40
+ font-family: 'DNA Heading';
41
+ font-style: normal;
42
+ font-weight: 700;
43
+ font-display: swap;
44
+ src: url('https://www.dna.fi/fonts/DNAHeading-Bold.woff2') format('woff2'),
45
+ url('https://www.dna.fi/fonts/DNAHeading-Bold.woff') format('woff');
46
+ }
47
+
48
+ @font-face {
49
+ font-family: 'DNA Heading';
50
+ font-style: normal;
51
+ font-weight: 900;
52
+ font-display: swap;
53
+ src: url('https://www.dna.fi/fonts/DNAHeading-Black.woff2') format('woff2'),
54
+ url('https://www.dna.fi/fonts/DNAHeading-Black.woff') format('woff');
55
+ }
56
+
57
+ /* "DNA Numerals" font definition */
58
+ @font-face {
59
+ font-family: 'DNA Numerals';
60
+ font-style: normal;
61
+ font-weight: 700;
62
+ font-display: swap;
63
+ src: url('https://www.dna.fi/fonts/DNANumerals-Bold.woff2') format('woff2'),
64
+ url('https://www.dna.fi/fonts/DNANumerals-Bold.woff') format('woff');
65
+ }
66
+
67
+ /* Direct definitons of DNA fonts */
68
+ @font-face {
69
+ font-family: 'DNA Text Regular';
70
+ font-style: normal;
71
+ font-weight: 400;
72
+ font-display: swap;
73
+ src: url('https://www.dna.fi/fonts/DNAText-Regular.woff2') format('woff2'),
74
+ url('https://www.dna.fi/fonts/DNAText-Regular.woff') format('woff');
75
+ }
76
+
77
+ @font-face {
78
+ font-family: 'DNA Text Medium';
79
+ font-style: normal;
80
+ font-weight: 500;
81
+ font-display: swap;
82
+ src: url('https://www.dna.fi/fonts/DNAText-Medium.woff2') format('woff2'),
83
+ url('https://www.dna.fi/fonts/DNAText-Medium.woff') format('woff');
84
+ }
85
+
86
+ @font-face {
87
+ font-family: 'DNA Text Bold';
88
+ font-style: normal;
89
+ font-weight: 700;
90
+ font-display: swap;
91
+ src: url('https://www.dna.fi/fonts/DNAText-Bold.woff2') format('woff2'),
92
+ url('https://www.dna.fi/fonts/DNAText-Bold.woff') format('woff');
93
+ }
94
+
95
+ @font-face {
96
+ font-family: 'DNA Heading Demi Bold';
97
+ font-style: normal;
98
+ font-weight: 600;
99
+ font-display: swap;
100
+ src: url('https://www.dna.fi/fonts/DNAHeading-DemiBold.woff2') format('woff2'),
101
+ url('https://www.dna.fi/fonts/DNAHeading-DemiBold.woff') format('woff');
102
+ }
103
+
104
+ @font-face {
105
+ font-family: 'DNA Heading Bold';
106
+ font-style: normal;
107
+ font-weight: 700;
108
+ font-display: swap;
109
+ src: url('https://www.dna.fi/fonts/DNAHeading-Bold.woff2') format('woff2'),
110
+ url('https://www.dna.fi/fonts/DNAHeading-Bold.woff') format('woff');
111
+ }
112
+
113
+ @font-face {
114
+ font-family: 'DNA Heading Black';
115
+ font-style: normal;
116
+ font-weight: 900;
117
+ font-display: swap;
118
+ src: url('https://www.dna.fi/fonts/DNAHeading-Black.woff2') format('woff2'),
119
+ url('https://www.dna.fi/fonts/DNAHeading-Black.woff') format('woff');
120
+ }
121
+
122
+ @font-face {
123
+ font-family: 'DNA Numerals Bold';
124
+ font-style: normal;
125
+ font-weight: 700;
126
+ font-display: swap;
127
+ src: url('https://www.dna.fi/fonts/DNANumerals-Bold.woff2') format('woff2'),
128
+ url('https://www.dna.fi/fonts/DNANumerals-Bold.woff') format('woff');
129
+ }
@@ -20,6 +20,10 @@ const ButtonElement = styled__default.button `
20
20
  border: 2px solid transparent;
21
21
  padding: ${getDividedSize(theme.base.baseWidth, 5)} 0;
22
22
 
23
+ & svg {
24
+ pointer-events: none;
25
+ }
26
+
23
27
  ${({ isReversed }) => isReversed && `flex-direction: row-reverse;`}
24
28
 
25
29
  &:focus {
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import type { KeyboardEvent, MouseEvent, ReactNode } from 'react';
2
2
  import React from 'react';
3
3
  interface Props {
4
4
  /**
@@ -9,6 +9,14 @@ interface Props {
9
9
  * Content of the component
10
10
  */
11
11
  children?: ReactNode;
12
+ /**
13
+ * Allows to pass common mouse click callback to all children
14
+ */
15
+ onClick?: (e: MouseEvent<HTMLElement>) => void;
16
+ /**
17
+ * Allows to pass common keyboard key down callback to all children
18
+ */
19
+ onKeyDown?: (e: KeyboardEvent<HTMLElement>) => void;
12
20
  /**
13
21
  * Allows to define aria-label attribute for nav HTML element
14
22
  */
@@ -1,6 +1,6 @@
1
1
  import { __rest } from 'tslib';
2
- import { Check, ChevronUp, ChevronDown } from '@dnanpm/icons';
3
- import React__default, { useRef, useState, useReducer, isValidElement, useEffect, Children } from 'react';
2
+ import { ChevronUp, ChevronDown, Check } from '@dnanpm/icons';
3
+ import React__default, { useRef, useState, Children, useReducer, isValidElement, useEffect } from 'react';
4
4
  import useDebounce from '../../hooks/useDebounce.js';
5
5
  import useOutsideClick from '../../hooks/useOutsideClick.js';
6
6
  import useResizeObserver from '../../hooks/useResizeObserver.js';
@@ -95,11 +95,15 @@ const DropdownList = styled(CoreULStyles) `
95
95
  ${getElevationShadow({ elevation: 'low' })}
96
96
  `;
97
97
  const reducer = (state, action) => {
98
- var _a;
98
+ var _a, _b;
99
99
  switch (action.type) {
100
+ case 'resetNavigationState': {
101
+ const navigationItems = Children.toArray((_a = action === null || action === void 0 ? void 0 : action.payload) === null || _a === void 0 ? void 0 : _a.navigationItems);
102
+ return Object.assign(Object.assign({}, state), { navigationItems: navigationItems.slice(0, navigationItems.length - state.lastItemWidth.length), dropdownItems: navigationItems.slice(navigationItems.length - state.lastItemWidth.length) });
103
+ }
100
104
  case 'moveItemToDropdown': {
101
105
  const lastChild = state.navigationItems[state.navigationItems.length - 1];
102
- return Object.assign(Object.assign(Object.assign({}, state), { navigationItems: state.navigationItems.slice(0, -1), dropdownItems: [lastChild, ...state.dropdownItems] }), (((_a = action === null || action === void 0 ? void 0 : action.payload) === null || _a === void 0 ? void 0 : _a.lastItem) && {
106
+ return Object.assign(Object.assign(Object.assign({}, state), { navigationItems: state.navigationItems.slice(0, -1), dropdownItems: [lastChild, ...state.dropdownItems] }), (((_b = action === null || action === void 0 ? void 0 : action.payload) === null || _b === void 0 ? void 0 : _b.lastItem) && {
103
107
  lastItemWidth: [...state.lastItemWidth, action.payload.lastItem.clientWidth],
104
108
  }));
105
109
  }
@@ -156,7 +160,7 @@ const PriorityNavigation = (_a) => {
156
160
  const toggleDropdown = () => setIsDropdownOpen(!isDropdownOpen);
157
161
  const navigationItems = useRef(new Map()).current;
158
162
  const initialState = {
159
- navigationItems: props.children,
163
+ navigationItems: Children.toArray(props.children),
160
164
  dropdownItems: [],
161
165
  lastItemWidth: [],
162
166
  };
@@ -189,6 +193,9 @@ const PriorityNavigation = (_a) => {
189
193
  child.type === PriorityNavigationItem &&
190
194
  child.props.isActive));
191
195
  useOutsideClick(listsContainerRef, () => {
196
+ if (isMobileNavigationOpen) {
197
+ setIsMobileNavigationOpen(false);
198
+ }
192
199
  if (isDropdownOpen) {
193
200
  setIsDropdownOpen(false);
194
201
  }
@@ -204,16 +211,24 @@ const PriorityNavigation = (_a) => {
204
211
  checkHorizontalOverflow,
205
212
  isMobile,
206
213
  ]);
207
- const navigationListItems = Children.map([...state.navigationItems, ...(isMobile ? state.dropdownItems : [])], (navigationItem, index) => isValidElement(navigationItem) &&
208
- navigationItem.type === PriorityNavigationItem && (React__default.createElement(PriorityNavigationItem, { id: navigationItem.props.id, key: navigationItem.key, isActive: navigationItem.props.isActive, className: navigationItem.props.className, "data-testid": navigationItem.props['data-testid'], innerRef: instance => instance && navigationItems.set(index, instance) },
209
- navigationItem.props.children,
210
- navigationItem.props.isActive && isMobile && (React__default.createElement(Icon, { icon: Check, color: theme.color.default.pink })))));
214
+ useEffect(() => {
215
+ dispatch({
216
+ type: 'resetNavigationState',
217
+ payload: {
218
+ navigationItems: props.children,
219
+ },
220
+ });
221
+ setIsMobileNavigationOpen(false);
222
+ }, [props.children]);
211
223
  return (React__default.createElement(Container, { id: props.id, "aria-label": props.navigationLabel, className: props.className, "data-testid": dataTestId },
212
224
  React__default.createElement(ListsContainer, { ref: listsContainerRef },
213
225
  isMobile && selectedItem && (React__default.createElement(MobileDropdown, { onClick: toggleMobileNavigation },
214
226
  selectedItem,
215
227
  React__default.createElement(Icon, { icon: isMobileNavigationOpen ? ChevronUp : ChevronDown }))),
216
- React__default.createElement(NavigationList, { ref: navigationListRef, isMobileNavigationOpen: isMobileNavigationOpen }, navigationListItems),
228
+ React__default.createElement(NavigationList, { ref: navigationListRef, isMobileNavigationOpen: isMobileNavigationOpen }, Children.map([...state.navigationItems, ...(isMobile ? state.dropdownItems : [])], (navigationItem, index) => isValidElement(navigationItem) &&
229
+ navigationItem.type === PriorityNavigationItem && (React__default.createElement(PriorityNavigationItem, { id: navigationItem.props.id, key: navigationItem.key, onClick: navigationItem.props.onClick || props.onClick, onKeyDown: navigationItem.props.onKeyDown || props.onKeyDown, isActive: navigationItem.props.isActive, className: navigationItem.props.className, "data-testid": navigationItem.props['data-testid'], innerRef: instance => instance && navigationItems.set(index, instance) },
230
+ navigationItem.props.children,
231
+ navigationItem.props.isActive && isMobile && (React__default.createElement(Icon, { icon: Check, color: theme.color.default.pink })))))),
217
232
  !isMobile && Boolean(state.dropdownItems.length) && (React__default.createElement(React__default.Fragment, null,
218
233
  React__default.createElement(ButtonIcon, { onClick: toggleDropdown, icon: isDropdownOpen ? ChevronUp : ChevronDown, isReversed: true }, dropdownButtonLabel),
219
234
  React__default.createElement(DropdownList, { isDropdownOpen: isDropdownOpen }, state.dropdownItems))))));
@@ -1,4 +1,4 @@
1
- import type { ReactNode, RefObject } from 'react';
1
+ import type { KeyboardEvent, MouseEvent, ReactNode, RefObject } from 'react';
2
2
  import React from 'react';
3
3
  export interface Props {
4
4
  /**
@@ -10,13 +10,21 @@ export interface Props {
10
10
  */
11
11
  children?: ReactNode;
12
12
  /**
13
- * A ref object, or a ref callback function
13
+ * On component mouse click callback
14
14
  */
15
- innerRef?: RefObject<HTMLLIElement> | ((instance: HTMLLIElement | null) => void) | null;
15
+ onClick?: (e: MouseEvent<HTMLElement>) => void;
16
+ /**
17
+ * On component keyboard key down callback
18
+ */
19
+ onKeyDown?: (e: KeyboardEvent<HTMLElement>) => void;
16
20
  /**
17
21
  * Allows to set component as active
18
22
  */
19
23
  isActive?: boolean;
24
+ /**
25
+ * A ref object, or a ref callback function
26
+ */
27
+ innerRef?: RefObject<HTMLLIElement> | ((instance: HTMLLIElement | null) => void) | null;
20
28
  /**
21
29
  * Allows to pass a custom className
22
30
  */
@@ -13,6 +13,20 @@ const Element = styled.li `
13
13
  padding: 1rem 1.25rem;
14
14
  flex-shrink: 0;
15
15
 
16
+ ${({ onClick }) => onClick &&
17
+ `
18
+ cursor: pointer;
19
+ `};
20
+
21
+ &:focus-within {
22
+ & > * {
23
+ border-radius: ${theme.radius.s};
24
+ border: 2px solid ${theme.color.focus.light};
25
+ box-shadow: 0px 0px 0px 2px ${theme.color.focus.dark};
26
+ outline: none;
27
+ }
28
+ }
29
+
16
30
  ${({ isActive }) => media.md `
17
31
  justify-content: center;
18
32
  padding: 1rem 0;
@@ -21,26 +35,20 @@ const Element = styled.li `
21
35
  border-bottom: 3px solid ${isActive ? theme.color.text.pink : 'transparent'};
22
36
  `}
23
37
 
24
- & a {
38
+ & > * {
25
39
  display: block;
26
40
  color: ${({ isActive }) => (isActive ? theme.color.text.pink : theme.color.text.black)};
27
41
  ${({ isActive }) => isActive && `font-weight: ${theme.fontWeight.bold}`};
28
42
  border: 2px solid transparent;
29
43
 
30
- &:focus {
31
- border-radius: ${theme.radius.s};
32
- border: 2px solid ${theme.color.focus.light};
33
- box-shadow: 0px 0px 0px 2px ${theme.color.focus.dark};
34
- outline: none;
44
+ &:hover {
45
+ color: ${theme.color.hover.pink};
46
+ text-decoration: none;
35
47
  }
36
48
 
37
49
  ${media.md `
38
50
  margin: auto;
39
51
  `}
40
-
41
- &:hover {
42
- color: ${theme.color.hover.pink};
43
- }
44
52
  }
45
53
  `;
46
54
  /**
@@ -48,7 +56,7 @@ const Element = styled.li `
48
56
  */
49
57
  const PriorityNavigationItem = (_a) => {
50
58
  var { 'data-testid': dataTestId } = _a, props = __rest(_a, ['data-testid']);
51
- return (React__default.createElement(Element, { id: props.id, ref: props.innerRef, isActive: props.isActive, className: props.className, "data-testid": dataTestId }, props.children));
59
+ return (React__default.createElement(Element, { id: props.id, ref: props.innerRef, onClick: props.onClick, onKeyDown: props.onKeyDown, isActive: props.isActive, className: props.className, "data-testid": dataTestId }, props.children));
52
60
  };
53
61
 
54
62
  export { PriorityNavigationItem as default };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dnanpm/styleguide",
3
3
  "sideEffects": false,
4
- "version": "3.5.0",
4
+ "version": "3.5.1",
5
5
  "main": "build/cjs/index.js",
6
6
  "module": "build/es/index.js",
7
7
  "jsnext:main": "build/es/index.js",