@dnanpm/styleguide 3.6.0 → 3.7.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.
@@ -2,15 +2,33 @@ import type { ReactNode } from 'react';
2
2
  import React from 'react';
3
3
  import type { Props as ReactModalProps } from 'react-modal';
4
4
  type Size = 'small' | 'medium' | 'large';
5
+ type Variant = 'light' | 'dark';
5
6
  interface Props {
6
7
  /**
7
8
  * Allows to control the state of component
8
9
  */
9
10
  isOpen: boolean;
11
+ /**
12
+ * Allows to define title shown in the header
13
+ */
14
+ title: string;
10
15
  /**
11
16
  * Unique ID for the component
12
17
  */
13
18
  id?: string;
19
+ /**
20
+ * Allows to change the color scheme of the component
21
+ *
22
+ * @param {Variant} light Sets header background color to `theme.color.background.white.default`
23
+ * @param {Variant} dark Sets header background color to `theme.color.background.plum.E02`
24
+ *
25
+ * @default 'light'
26
+ */
27
+ variant?: Variant;
28
+ /**
29
+ * Allows to define subtitle shown in the header
30
+ */
31
+ subtitle?: string;
14
32
  /**
15
33
  * Content of the component
16
34
  */
@@ -36,6 +54,7 @@ interface Props {
36
54
  * Allows to pass a custom margin
37
55
  *
38
56
  * @default '0'
57
+ * @deprecated Will be removed in the next major version
39
58
  */
40
59
  margin?: string;
41
60
  /**
@@ -69,6 +88,10 @@ interface Props {
69
88
  * @default true
70
89
  */
71
90
  isClosable?: boolean;
91
+ /**
92
+ * Allows to display the footer content
93
+ */
94
+ footer?: ReactNode;
72
95
  /**
73
96
  * Allows to pass a custom className
74
97
  */
@@ -78,5 +101,5 @@ interface Props {
78
101
  */
79
102
  'data-testid'?: string;
80
103
  }
81
- declare const Drawer: ({ appElement, size, closeButton, isClosable, "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
104
+ declare const Drawer: ({ appElement, size, variant, padding, closeButton, isClosable, "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
82
105
  export default Drawer;
@@ -12,6 +12,8 @@ var styledUtils = require('../../utils/styledUtils.js');
12
12
  var Box = require('../Box/Box.js');
13
13
  var ButtonClose = require('../Button/ButtonClose.js');
14
14
  var Icon = require('../Icon/Icon.js');
15
+ var common = require('../../utils/common.js');
16
+ var Floater = require('../Floater/Floater.js');
15
17
 
16
18
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
17
19
 
@@ -63,7 +65,7 @@ const StyledReactModal = styled["default"](ReactModal__default["default"]) `
63
65
  width: ${sizeMap[size]};
64
66
  `};
65
67
  `;
66
- const StyledOverlay = styled["default"].div `
68
+ const StyledReactModalOverlay = styled["default"].div `
67
69
  display: flex;
68
70
  justify-content: center;
69
71
  align-items: center;
@@ -101,30 +103,89 @@ const StyledOverlay = styled["default"].div `
101
103
  }
102
104
  }
103
105
  `;
106
+ const StyledReactModalContent = styled["default"].div `
107
+ &:focus {
108
+ outline: none;
109
+ }
110
+ `;
104
111
  const StyledBox = styled["default"](Box["default"]) `
112
+ display: flex;
113
+ flex-direction: column;
114
+ justify-content: space-between;
105
115
  border-radius: 0;
106
116
  height: 100%;
107
117
  overflow-y: auto;
118
+ position: relative;
119
+ padding: 0;
120
+ border: 0 none;
108
121
  `;
109
- const StyledContent = styled["default"].div `
110
- &:focus {
111
- outline: none;
122
+ const Header = styled["default"].div `
123
+ display: flex;
124
+ flex-direction: column;
125
+ gap: 0.25rem;
126
+ border-bottom: 1px solid ${theme["default"].color.line.L03};
127
+ padding: 1.25rem;
128
+ background-color: ${({ variant }) => variant === 'light'
129
+ ? theme["default"].color.background.white.default
130
+ : theme["default"].color.background.plum.E02};
131
+ width: 100%;
132
+
133
+ h2,
134
+ p {
135
+ margin: 0;
112
136
  }
113
137
  `;
114
- const ModalOverlay = ({ ref, onClick, onMouseDown, className }, contentElement) => (React__default["default"].createElement(StyledOverlay, { ref: ref, onClick: onClick, onMouseDown: onMouseDown, className: className }, contentElement));
138
+ const Title = styled["default"].h2 `
139
+ font-size: ${({ size }) => (size === 'small' ? theme["default"].fontSize.h2S : theme["default"].fontSize.h2M)};
140
+ color: ${({ variant }) => variant === 'light' ? theme["default"].color.default.black : theme["default"].color.default.white};
141
+ `;
142
+ const Subtitle = styled["default"].p `
143
+ font-size: ${({ size }) => (size === 'small' ? theme["default"].fontSize.l : theme["default"].fontSize.xl)};
144
+ color: ${({ variant }) => variant === 'light' ? theme["default"].color.default.black : theme["default"].color.default.white};
145
+ `;
146
+ const CloseButton = styled["default"](ButtonClose["default"]) `
147
+ margin: 0;
148
+ padding: 0.625rem;
149
+ border-radius: 0 0 0 ${theme["default"].radius.default};
150
+ background-color: ${({ variant }) => variant === 'light'
151
+ ? theme["default"].color.background.sand.E01
152
+ : theme["default"].color.background.plum.default};
153
+ `;
154
+ const Content = styled["default"].div `
155
+ padding: ${({ padding }) => padding};
156
+ margin: 0;
157
+ `;
158
+ const Footer = styled["default"].div `
159
+ padding: 1.25rem;
160
+ margin: 0;
161
+ width: 100%;
162
+ border-top: 1px solid ${theme["default"].color.line.L04};
163
+ background-color: ${theme["default"].color.background.white.default};
164
+
165
+ ${common["default"]({ elevation: 'high', shadow: '1 0 0 0' })};
166
+ `;
167
+ const ModalOverlay = ({ ref, onClick, onMouseDown, className }, contentElement) => (React__default["default"].createElement(StyledReactModalOverlay, { ref: ref, onClick: onClick, onMouseDown: onMouseDown, className: className }, contentElement));
115
168
  const ModalContent = (_a, children) => {
116
- var { ref, tabIndex, role, onKeyDown, onMouseDown, onMouseUp, onClick, className } = _a, contentProps = tslib.__rest(_a, ["ref", "tabIndex", "role", "onKeyDown", "onMouseDown", "onMouseUp", "onClick", "className"]);
117
- return (React__default["default"].createElement(StyledContent, { ref: ref, tabIndex: tabIndex, role: role, onKeyDown: onKeyDown, onMouseDown: onMouseDown, onMouseUp: onMouseUp, onClick: onClick, "aria-label": contentProps['aria-label'], "aria-modal": contentProps['aria-modal'], className: className }, children));
169
+ var { id, ref, tabIndex, role, onKeyDown, onMouseDown, onMouseUp, onClick, className } = _a, contentProps = tslib.__rest(_a, ["id", "ref", "tabIndex", "role", "onKeyDown", "onMouseDown", "onMouseUp", "onClick", "className"]);
170
+ return (React__default["default"].createElement(StyledReactModalContent, { id: id, ref: ref, tabIndex: tabIndex, role: role, onKeyDown: onKeyDown, onMouseDown: onMouseDown, onMouseUp: onMouseUp, onClick: onClick, "aria-label": contentProps['aria-label'], "aria-modal": contentProps['aria-modal'], className: className }, children));
118
171
  };
119
172
  const Drawer = (_a) => {
120
- var { appElement = '#__next', size = 'medium', closeButton = true, isClosable = true, 'data-testid': dataTestId } = _a, props = tslib.__rest(_a, ["appElement", "size", "closeButton", "isClosable", 'data-testid']);
173
+ var { appElement = '#__next', size = 'medium', variant = 'light', padding = '1.25rem', closeButton = true, isClosable = true, 'data-testid': dataTestId } = _a, props = tslib.__rest(_a, ["appElement", "size", "variant", "padding", "closeButton", "isClosable", 'data-testid']);
121
174
  ReactModal__default["default"].setAppElement(appElement);
122
175
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
123
176
  React__default["default"].createElement(StyledReactModal, { id: props.id, isOpen: props.isOpen, overlayElement: ModalOverlay, contentElement: ModalContent, onRequestClose: props.onRequestClose, portalClassName: props.className, contentLabel: props.contentLabel, shouldCloseOnEsc: isClosable, shouldCloseOnOverlayClick: isClosable, closeTimeoutMS: 300, size: size },
124
- React__default["default"].createElement(StyledBox, { elevation: "extraHigh", margin: props.margin, padding: props.padding, "data-testid": dataTestId },
125
- props.children,
126
- closeButton && isClosable && (React__default["default"].createElement(ButtonClose["default"], { onClick: props.onRequestClose, "aria-label": props.closeLabel, "data-testid": dataTestId && `${dataTestId}-close-button` },
127
- React__default["default"].createElement(Icon["default"], { icon: icons.Close }))))),
177
+ React__default["default"].createElement(StyledBox, { elevation: "extraHigh", margin: props.margin, "data-testid": dataTestId },
178
+ React__default["default"].createElement("div", null,
179
+ React__default["default"].createElement(Floater["default"], null, closeButton && isClosable && (React__default["default"].createElement(CloseButton, { onClick: props.onRequestClose, "aria-label": props.closeLabel, "data-testid": dataTestId && `${dataTestId}-close-button`, variant: variant },
180
+ React__default["default"].createElement(Icon["default"], { icon: icons.Close, color: variant === 'light'
181
+ ? theme["default"].color.default.plum
182
+ : theme["default"].color.default.white })))),
183
+ React__default["default"].createElement(Header, { variant: variant, "data-testid": dataTestId && `${dataTestId}-header` },
184
+ React__default["default"].createElement(Title, { size: size, variant: variant }, props.title),
185
+ props.subtitle && (React__default["default"].createElement(Subtitle, { size: size, variant: variant }, props.subtitle))),
186
+ React__default["default"].createElement(Content, { "data-testid": dataTestId && `${dataTestId}-content`, padding: padding }, props.children)),
187
+ props.footer && (React__default["default"].createElement(Floater["default"], { position: "bottom" },
188
+ React__default["default"].createElement(Footer, { "data-testid": dataTestId && `${dataTestId}-footer` }, props.footer))))),
128
189
  React__default["default"].createElement(GlobalStyle, null)));
129
190
  };
130
191
 
@@ -89,7 +89,7 @@ const NavigationList = styled["default"](CoreULStyles) `
89
89
  `;
90
90
  const DropdownList = styled["default"](CoreULStyles) `
91
91
  position: absolute;
92
- top: ${styledUtils.getMultipliedSize(theme["default"].base.baseHeight, 5.6)};
92
+ top: ${styledUtils.getMultipliedSize(theme["default"].base.baseHeight, 6)};
93
93
  right: 0;
94
94
  z-index: 1;
95
95
  padding-bottom: 0.5rem;
@@ -100,6 +100,12 @@ const DropdownList = styled["default"](CoreULStyles) `
100
100
  clip-path: inset(0% 0% ${({ isDropdownOpen }) => (isDropdownOpen ? '0%' : '100%')} 0%);
101
101
  transition: all 0.2s ease-in-out;
102
102
 
103
+ ${styledUtils.media.md `
104
+ & > li {
105
+ margin: auto 1.25rem;
106
+ }
107
+ `}
108
+
103
109
  ${common["default"]({ elevation: 'low' })}
104
110
  `;
105
111
  const reducer = (state, action) => {
@@ -112,7 +118,10 @@ const reducer = (state, action) => {
112
118
  case 'moveItemToDropdown': {
113
119
  const lastChild = state.navigationItems[state.navigationItems.length - 1];
114
120
  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) && {
115
- lastItemWidth: [...state.lastItemWidth, action.payload.lastItem.clientWidth],
121
+ lastItemWidth: [
122
+ ...state.lastItemWidth,
123
+ action.payload.lastItem.offsetWidth + 40,
124
+ ],
116
125
  }));
117
126
  }
118
127
  case 'moveItemToNavigation': {
@@ -160,8 +169,9 @@ const PriorityNavigation = (_a) => {
160
169
  var { dropdownButtonLabel = 'Lisää', 'data-testid': dataTestId } = _a, props = tslib.__rest(_a, ["dropdownButtonLabel", 'data-testid']);
161
170
  const listsContainerRef = React.useRef(null);
162
171
  const navigationListRef = React.useRef(null);
172
+ const dropdownButtonRef = React.useRef(null);
163
173
  const { isMobile } = useWindowSize["default"](theme["default"].breakpoints.md);
164
- const { width: listsContainerWidth } = useResizeObserver["default"](listsContainerRef);
174
+ const { width: wrapperContainerWidth } = useResizeObserver["default"](listsContainerRef);
165
175
  const [isMobileNavigationOpen, setIsMobileNavigationOpen] = React.useState(false);
166
176
  const toggleMobileNavigation = () => setIsMobileNavigationOpen(!isMobileNavigationOpen);
167
177
  const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
@@ -174,10 +184,12 @@ const PriorityNavigation = (_a) => {
174
184
  };
175
185
  const [state, dispatch] = React.useReducer(reducer, initialState);
176
186
  const checkHorizontalOverflow = useDebounce["default"](() => {
187
+ var _a, _b;
177
188
  if (navigationListRef.current && listsContainerRef.current) {
178
- const listsContainerRefWidth = navigationListRef.current.scrollWidth;
189
+ const navigationListWidth = navigationListRef.current.scrollWidth;
190
+ const dropdownButtonWidth = ((_b = (_a = dropdownButtonRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) !== null && _b !== void 0 ? _b : 80) + 20;
179
191
  if (state.navigationItems.length > 0 &&
180
- listsContainerRefWidth + 80 > listsContainerWidth) {
192
+ navigationListWidth + dropdownButtonWidth > wrapperContainerWidth) {
181
193
  dispatch({
182
194
  type: 'moveItemToDropdown',
183
195
  payload: {
@@ -186,10 +198,11 @@ const PriorityNavigation = (_a) => {
186
198
  });
187
199
  }
188
200
  else if (state.dropdownItems.length > 0 &&
189
- listsContainerWidth >
190
- listsContainerRefWidth +
201
+ wrapperContainerWidth >
202
+ navigationListWidth +
191
203
  state.lastItemWidth[state.lastItemWidth.length - 1] +
192
- 100) {
204
+ dropdownButtonWidth +
205
+ 20) {
193
206
  dispatch({
194
207
  type: 'moveItemToNavigation',
195
208
  });
@@ -215,7 +228,7 @@ const PriorityNavigation = (_a) => {
215
228
  }, [
216
229
  state.navigationItems,
217
230
  state.dropdownItems,
218
- listsContainerWidth,
231
+ wrapperContainerWidth,
219
232
  checkHorizontalOverflow,
220
233
  isMobile,
221
234
  ]);
@@ -238,8 +251,10 @@ const PriorityNavigation = (_a) => {
238
251
  navigationItem.props.children,
239
252
  navigationItem.props.isActive && isMobile && (React__default["default"].createElement(Icon["default"], { icon: icons.Check, color: theme["default"].color.default.pink })))))),
240
253
  !isMobile && Boolean(state.dropdownItems.length) && (React__default["default"].createElement(React__default["default"].Fragment, null,
241
- React__default["default"].createElement(ButtonIcon["default"], { onClick: toggleDropdown, icon: isDropdownOpen ? icons.ChevronUp : icons.ChevronDown, isReversed: true }, dropdownButtonLabel),
242
- React__default["default"].createElement(DropdownList, { isDropdownOpen: isDropdownOpen }, state.dropdownItems))))));
254
+ React__default["default"].createElement("div", { ref: dropdownButtonRef },
255
+ React__default["default"].createElement(ButtonIcon["default"], { onClick: toggleDropdown, icon: isDropdownOpen ? icons.ChevronUp : icons.ChevronDown, isReversed: true }, dropdownButtonLabel)),
256
+ React__default["default"].createElement(DropdownList, { isDropdownOpen: isDropdownOpen }, state.dropdownItems.map(dropdownItem => React.isValidElement(dropdownItem) &&
257
+ dropdownItem.type === PriorityNavigationItem["default"] && (React__default["default"].createElement(PriorityNavigationItem["default"], { id: dropdownItem.props.id, key: dropdownItem.key, onClick: dropdownItem.props.onClick || props.onClick, onKeyDown: dropdownItem.props.onKeyDown || props.onKeyDown, isActive: dropdownItem.props.isActive, className: dropdownItem.props.className, "data-testid": dropdownItem.props['data-testid'] }, dropdownItem.props.children)))))))));
243
258
  };
244
259
 
245
260
  exports["default"] = PriorityNavigation;
@@ -18,7 +18,7 @@ const Element = styled["default"].li `
18
18
  justify-content: space-between;
19
19
  list-style: none;
20
20
  position: relative;
21
- padding: 1rem 1.25rem;
21
+ padding: 0.75rem 1.25rem;
22
22
  flex-shrink: 0;
23
23
 
24
24
  ${({ onClick }) => onClick &&
@@ -36,9 +36,9 @@ const Element = styled["default"].li `
36
36
  }
37
37
 
38
38
  ${({ isActive }) => styledUtils.media.md `
39
- justify-content: center;
39
+ justify-content: left;
40
40
  padding: 1rem 0;
41
- margin: auto 1.25rem;
41
+ margin: auto 1rem;
42
42
  border-top: 3px solid transparent;
43
43
  border-bottom: 3px solid ${isActive ? theme["default"].color.text.pink : 'transparent'};
44
44
  `}
@@ -53,10 +53,6 @@ const Element = styled["default"].li `
53
53
  color: ${theme["default"].color.hover.pink};
54
54
  text-decoration: none;
55
55
  }
56
-
57
- ${styledUtils.media.md `
58
- margin: auto;
59
- `}
60
56
  }
61
57
  `;
62
58
  /**
@@ -12,8 +12,8 @@ const useResizeObserver = (ref) => {
12
12
  const [size, setSize] = React.useState({ width: 0, height: 0 });
13
13
  const resizeObserver = React.useRef(null);
14
14
  const onResize = React.useCallback(entries => {
15
- const { width, height } = entries[0].contentRect;
16
- setSize({ width, height });
15
+ const { inlineSize, blockSize } = entries[0].borderBoxSize[0];
16
+ setSize({ width: inlineSize, height: blockSize });
17
17
  }, []);
18
18
  React.useEffect(() => {
19
19
  if ((ref === null || ref === void 0 ? void 0 : ref.current) && ResizeObserver) {
@@ -2,15 +2,33 @@ import type { ReactNode } from 'react';
2
2
  import React from 'react';
3
3
  import type { Props as ReactModalProps } from 'react-modal';
4
4
  type Size = 'small' | 'medium' | 'large';
5
+ type Variant = 'light' | 'dark';
5
6
  interface Props {
6
7
  /**
7
8
  * Allows to control the state of component
8
9
  */
9
10
  isOpen: boolean;
11
+ /**
12
+ * Allows to define title shown in the header
13
+ */
14
+ title: string;
10
15
  /**
11
16
  * Unique ID for the component
12
17
  */
13
18
  id?: string;
19
+ /**
20
+ * Allows to change the color scheme of the component
21
+ *
22
+ * @param {Variant} light Sets header background color to `theme.color.background.white.default`
23
+ * @param {Variant} dark Sets header background color to `theme.color.background.plum.E02`
24
+ *
25
+ * @default 'light'
26
+ */
27
+ variant?: Variant;
28
+ /**
29
+ * Allows to define subtitle shown in the header
30
+ */
31
+ subtitle?: string;
14
32
  /**
15
33
  * Content of the component
16
34
  */
@@ -36,6 +54,7 @@ interface Props {
36
54
  * Allows to pass a custom margin
37
55
  *
38
56
  * @default '0'
57
+ * @deprecated Will be removed in the next major version
39
58
  */
40
59
  margin?: string;
41
60
  /**
@@ -69,6 +88,10 @@ interface Props {
69
88
  * @default true
70
89
  */
71
90
  isClosable?: boolean;
91
+ /**
92
+ * Allows to display the footer content
93
+ */
94
+ footer?: ReactNode;
72
95
  /**
73
96
  * Allows to pass a custom className
74
97
  */
@@ -78,5 +101,5 @@ interface Props {
78
101
  */
79
102
  'data-testid'?: string;
80
103
  }
81
- declare const Drawer: ({ appElement, size, closeButton, isClosable, "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
104
+ declare const Drawer: ({ appElement, size, variant, padding, closeButton, isClosable, "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
82
105
  export default Drawer;
@@ -8,6 +8,8 @@ import { media } from '../../utils/styledUtils.js';
8
8
  import Box from '../Box/Box.js';
9
9
  import ButtonClose from '../Button/ButtonClose.js';
10
10
  import Icon from '../Icon/Icon.js';
11
+ import getElevationShadow from '../../utils/common.js';
12
+ import Floater from '../Floater/Floater.js';
11
13
 
12
14
  const sizeMap = {
13
15
  small: '375px',
@@ -54,7 +56,7 @@ const StyledReactModal = styled(ReactModal) `
54
56
  width: ${sizeMap[size]};
55
57
  `};
56
58
  `;
57
- const StyledOverlay = styled.div `
59
+ const StyledReactModalOverlay = styled.div `
58
60
  display: flex;
59
61
  justify-content: center;
60
62
  align-items: center;
@@ -92,30 +94,89 @@ const StyledOverlay = styled.div `
92
94
  }
93
95
  }
94
96
  `;
97
+ const StyledReactModalContent = styled.div `
98
+ &:focus {
99
+ outline: none;
100
+ }
101
+ `;
95
102
  const StyledBox = styled(Box) `
103
+ display: flex;
104
+ flex-direction: column;
105
+ justify-content: space-between;
96
106
  border-radius: 0;
97
107
  height: 100%;
98
108
  overflow-y: auto;
109
+ position: relative;
110
+ padding: 0;
111
+ border: 0 none;
99
112
  `;
100
- const StyledContent = styled.div `
101
- &:focus {
102
- outline: none;
113
+ const Header = styled.div `
114
+ display: flex;
115
+ flex-direction: column;
116
+ gap: 0.25rem;
117
+ border-bottom: 1px solid ${theme.color.line.L03};
118
+ padding: 1.25rem;
119
+ background-color: ${({ variant }) => variant === 'light'
120
+ ? theme.color.background.white.default
121
+ : theme.color.background.plum.E02};
122
+ width: 100%;
123
+
124
+ h2,
125
+ p {
126
+ margin: 0;
103
127
  }
104
128
  `;
105
- const ModalOverlay = ({ ref, onClick, onMouseDown, className }, contentElement) => (React__default.createElement(StyledOverlay, { ref: ref, onClick: onClick, onMouseDown: onMouseDown, className: className }, contentElement));
129
+ const Title = styled.h2 `
130
+ font-size: ${({ size }) => (size === 'small' ? theme.fontSize.h2S : theme.fontSize.h2M)};
131
+ color: ${({ variant }) => variant === 'light' ? theme.color.default.black : theme.color.default.white};
132
+ `;
133
+ const Subtitle = styled.p `
134
+ font-size: ${({ size }) => (size === 'small' ? theme.fontSize.l : theme.fontSize.xl)};
135
+ color: ${({ variant }) => variant === 'light' ? theme.color.default.black : theme.color.default.white};
136
+ `;
137
+ const CloseButton = styled(ButtonClose) `
138
+ margin: 0;
139
+ padding: 0.625rem;
140
+ border-radius: 0 0 0 ${theme.radius.default};
141
+ background-color: ${({ variant }) => variant === 'light'
142
+ ? theme.color.background.sand.E01
143
+ : theme.color.background.plum.default};
144
+ `;
145
+ const Content = styled.div `
146
+ padding: ${({ padding }) => padding};
147
+ margin: 0;
148
+ `;
149
+ const Footer = styled.div `
150
+ padding: 1.25rem;
151
+ margin: 0;
152
+ width: 100%;
153
+ border-top: 1px solid ${theme.color.line.L04};
154
+ background-color: ${theme.color.background.white.default};
155
+
156
+ ${getElevationShadow({ elevation: 'high', shadow: '1 0 0 0' })};
157
+ `;
158
+ const ModalOverlay = ({ ref, onClick, onMouseDown, className }, contentElement) => (React__default.createElement(StyledReactModalOverlay, { ref: ref, onClick: onClick, onMouseDown: onMouseDown, className: className }, contentElement));
106
159
  const ModalContent = (_a, children) => {
107
- var { ref, tabIndex, role, onKeyDown, onMouseDown, onMouseUp, onClick, className } = _a, contentProps = __rest(_a, ["ref", "tabIndex", "role", "onKeyDown", "onMouseDown", "onMouseUp", "onClick", "className"]);
108
- return (React__default.createElement(StyledContent, { ref: ref, tabIndex: tabIndex, role: role, onKeyDown: onKeyDown, onMouseDown: onMouseDown, onMouseUp: onMouseUp, onClick: onClick, "aria-label": contentProps['aria-label'], "aria-modal": contentProps['aria-modal'], className: className }, children));
160
+ var { id, ref, tabIndex, role, onKeyDown, onMouseDown, onMouseUp, onClick, className } = _a, contentProps = __rest(_a, ["id", "ref", "tabIndex", "role", "onKeyDown", "onMouseDown", "onMouseUp", "onClick", "className"]);
161
+ return (React__default.createElement(StyledReactModalContent, { id: id, ref: ref, tabIndex: tabIndex, role: role, onKeyDown: onKeyDown, onMouseDown: onMouseDown, onMouseUp: onMouseUp, onClick: onClick, "aria-label": contentProps['aria-label'], "aria-modal": contentProps['aria-modal'], className: className }, children));
109
162
  };
110
163
  const Drawer = (_a) => {
111
- var { appElement = '#__next', size = 'medium', closeButton = true, isClosable = true, 'data-testid': dataTestId } = _a, props = __rest(_a, ["appElement", "size", "closeButton", "isClosable", 'data-testid']);
164
+ var { appElement = '#__next', size = 'medium', variant = 'light', padding = '1.25rem', closeButton = true, isClosable = true, 'data-testid': dataTestId } = _a, props = __rest(_a, ["appElement", "size", "variant", "padding", "closeButton", "isClosable", 'data-testid']);
112
165
  ReactModal.setAppElement(appElement);
113
166
  return (React__default.createElement(React__default.Fragment, null,
114
167
  React__default.createElement(StyledReactModal, { id: props.id, isOpen: props.isOpen, overlayElement: ModalOverlay, contentElement: ModalContent, onRequestClose: props.onRequestClose, portalClassName: props.className, contentLabel: props.contentLabel, shouldCloseOnEsc: isClosable, shouldCloseOnOverlayClick: isClosable, closeTimeoutMS: 300, size: size },
115
- React__default.createElement(StyledBox, { elevation: "extraHigh", margin: props.margin, padding: props.padding, "data-testid": dataTestId },
116
- props.children,
117
- closeButton && isClosable && (React__default.createElement(ButtonClose, { onClick: props.onRequestClose, "aria-label": props.closeLabel, "data-testid": dataTestId && `${dataTestId}-close-button` },
118
- React__default.createElement(Icon, { icon: Close }))))),
168
+ React__default.createElement(StyledBox, { elevation: "extraHigh", margin: props.margin, "data-testid": dataTestId },
169
+ React__default.createElement("div", null,
170
+ React__default.createElement(Floater, null, closeButton && isClosable && (React__default.createElement(CloseButton, { onClick: props.onRequestClose, "aria-label": props.closeLabel, "data-testid": dataTestId && `${dataTestId}-close-button`, variant: variant },
171
+ React__default.createElement(Icon, { icon: Close, color: variant === 'light'
172
+ ? theme.color.default.plum
173
+ : theme.color.default.white })))),
174
+ React__default.createElement(Header, { variant: variant, "data-testid": dataTestId && `${dataTestId}-header` },
175
+ React__default.createElement(Title, { size: size, variant: variant }, props.title),
176
+ props.subtitle && (React__default.createElement(Subtitle, { size: size, variant: variant }, props.subtitle))),
177
+ React__default.createElement(Content, { "data-testid": dataTestId && `${dataTestId}-content`, padding: padding }, props.children)),
178
+ props.footer && (React__default.createElement(Floater, { position: "bottom" },
179
+ React__default.createElement(Footer, { "data-testid": dataTestId && `${dataTestId}-footer` }, props.footer))))),
119
180
  React__default.createElement(GlobalStyle, null)));
120
181
  };
121
182
 
@@ -81,7 +81,7 @@ const NavigationList = styled(CoreULStyles) `
81
81
  `;
82
82
  const DropdownList = styled(CoreULStyles) `
83
83
  position: absolute;
84
- top: ${getMultipliedSize(theme.base.baseHeight, 5.6)};
84
+ top: ${getMultipliedSize(theme.base.baseHeight, 6)};
85
85
  right: 0;
86
86
  z-index: 1;
87
87
  padding-bottom: 0.5rem;
@@ -92,6 +92,12 @@ const DropdownList = styled(CoreULStyles) `
92
92
  clip-path: inset(0% 0% ${({ isDropdownOpen }) => (isDropdownOpen ? '0%' : '100%')} 0%);
93
93
  transition: all 0.2s ease-in-out;
94
94
 
95
+ ${media.md `
96
+ & > li {
97
+ margin: auto 1.25rem;
98
+ }
99
+ `}
100
+
95
101
  ${getElevationShadow({ elevation: 'low' })}
96
102
  `;
97
103
  const reducer = (state, action) => {
@@ -104,7 +110,10 @@ const reducer = (state, action) => {
104
110
  case 'moveItemToDropdown': {
105
111
  const lastChild = state.navigationItems[state.navigationItems.length - 1];
106
112
  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) && {
107
- lastItemWidth: [...state.lastItemWidth, action.payload.lastItem.clientWidth],
113
+ lastItemWidth: [
114
+ ...state.lastItemWidth,
115
+ action.payload.lastItem.offsetWidth + 40,
116
+ ],
108
117
  }));
109
118
  }
110
119
  case 'moveItemToNavigation': {
@@ -152,8 +161,9 @@ const PriorityNavigation = (_a) => {
152
161
  var { dropdownButtonLabel = 'Lisää', 'data-testid': dataTestId } = _a, props = __rest(_a, ["dropdownButtonLabel", 'data-testid']);
153
162
  const listsContainerRef = useRef(null);
154
163
  const navigationListRef = useRef(null);
164
+ const dropdownButtonRef = useRef(null);
155
165
  const { isMobile } = useWindowSize(theme.breakpoints.md);
156
- const { width: listsContainerWidth } = useResizeObserver(listsContainerRef);
166
+ const { width: wrapperContainerWidth } = useResizeObserver(listsContainerRef);
157
167
  const [isMobileNavigationOpen, setIsMobileNavigationOpen] = useState(false);
158
168
  const toggleMobileNavigation = () => setIsMobileNavigationOpen(!isMobileNavigationOpen);
159
169
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
@@ -166,10 +176,12 @@ const PriorityNavigation = (_a) => {
166
176
  };
167
177
  const [state, dispatch] = useReducer(reducer, initialState);
168
178
  const checkHorizontalOverflow = useDebounce(() => {
179
+ var _a, _b;
169
180
  if (navigationListRef.current && listsContainerRef.current) {
170
- const listsContainerRefWidth = navigationListRef.current.scrollWidth;
181
+ const navigationListWidth = navigationListRef.current.scrollWidth;
182
+ const dropdownButtonWidth = ((_b = (_a = dropdownButtonRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) !== null && _b !== void 0 ? _b : 80) + 20;
171
183
  if (state.navigationItems.length > 0 &&
172
- listsContainerRefWidth + 80 > listsContainerWidth) {
184
+ navigationListWidth + dropdownButtonWidth > wrapperContainerWidth) {
173
185
  dispatch({
174
186
  type: 'moveItemToDropdown',
175
187
  payload: {
@@ -178,10 +190,11 @@ const PriorityNavigation = (_a) => {
178
190
  });
179
191
  }
180
192
  else if (state.dropdownItems.length > 0 &&
181
- listsContainerWidth >
182
- listsContainerRefWidth +
193
+ wrapperContainerWidth >
194
+ navigationListWidth +
183
195
  state.lastItemWidth[state.lastItemWidth.length - 1] +
184
- 100) {
196
+ dropdownButtonWidth +
197
+ 20) {
185
198
  dispatch({
186
199
  type: 'moveItemToNavigation',
187
200
  });
@@ -207,7 +220,7 @@ const PriorityNavigation = (_a) => {
207
220
  }, [
208
221
  state.navigationItems,
209
222
  state.dropdownItems,
210
- listsContainerWidth,
223
+ wrapperContainerWidth,
211
224
  checkHorizontalOverflow,
212
225
  isMobile,
213
226
  ]);
@@ -230,8 +243,10 @@ const PriorityNavigation = (_a) => {
230
243
  navigationItem.props.children,
231
244
  navigationItem.props.isActive && isMobile && (React__default.createElement(Icon, { icon: Check, color: theme.color.default.pink })))))),
232
245
  !isMobile && Boolean(state.dropdownItems.length) && (React__default.createElement(React__default.Fragment, null,
233
- React__default.createElement(ButtonIcon, { onClick: toggleDropdown, icon: isDropdownOpen ? ChevronUp : ChevronDown, isReversed: true }, dropdownButtonLabel),
234
- React__default.createElement(DropdownList, { isDropdownOpen: isDropdownOpen }, state.dropdownItems))))));
246
+ React__default.createElement("div", { ref: dropdownButtonRef },
247
+ React__default.createElement(ButtonIcon, { onClick: toggleDropdown, icon: isDropdownOpen ? ChevronUp : ChevronDown, isReversed: true }, dropdownButtonLabel)),
248
+ React__default.createElement(DropdownList, { isDropdownOpen: isDropdownOpen }, state.dropdownItems.map(dropdownItem => isValidElement(dropdownItem) &&
249
+ dropdownItem.type === PriorityNavigationItem && (React__default.createElement(PriorityNavigationItem, { id: dropdownItem.props.id, key: dropdownItem.key, onClick: dropdownItem.props.onClick || props.onClick, onKeyDown: dropdownItem.props.onKeyDown || props.onKeyDown, isActive: dropdownItem.props.isActive, className: dropdownItem.props.className, "data-testid": dropdownItem.props['data-testid'] }, dropdownItem.props.children)))))))));
235
250
  };
236
251
 
237
252
  export { PriorityNavigation as default };
@@ -10,7 +10,7 @@ const Element = styled.li `
10
10
  justify-content: space-between;
11
11
  list-style: none;
12
12
  position: relative;
13
- padding: 1rem 1.25rem;
13
+ padding: 0.75rem 1.25rem;
14
14
  flex-shrink: 0;
15
15
 
16
16
  ${({ onClick }) => onClick &&
@@ -28,9 +28,9 @@ const Element = styled.li `
28
28
  }
29
29
 
30
30
  ${({ isActive }) => media.md `
31
- justify-content: center;
31
+ justify-content: left;
32
32
  padding: 1rem 0;
33
- margin: auto 1.25rem;
33
+ margin: auto 1rem;
34
34
  border-top: 3px solid transparent;
35
35
  border-bottom: 3px solid ${isActive ? theme.color.text.pink : 'transparent'};
36
36
  `}
@@ -45,10 +45,6 @@ const Element = styled.li `
45
45
  color: ${theme.color.hover.pink};
46
46
  text-decoration: none;
47
47
  }
48
-
49
- ${media.md `
50
- margin: auto;
51
- `}
52
48
  }
53
49
  `;
54
50
  /**
@@ -8,8 +8,8 @@ const useResizeObserver = (ref) => {
8
8
  const [size, setSize] = useState({ width: 0, height: 0 });
9
9
  const resizeObserver = useRef(null);
10
10
  const onResize = useCallback(entries => {
11
- const { width, height } = entries[0].contentRect;
12
- setSize({ width, height });
11
+ const { inlineSize, blockSize } = entries[0].borderBoxSize[0];
12
+ setSize({ width: inlineSize, height: blockSize });
13
13
  }, []);
14
14
  useEffect(() => {
15
15
  if ((ref === null || ref === void 0 ? void 0 : ref.current) && ResizeObserver) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dnanpm/styleguide",
3
3
  "sideEffects": false,
4
- "version": "3.6.0",
4
+ "version": "3.7.1",
5
5
  "main": "build/cjs/index.js",
6
6
  "module": "build/es/index.js",
7
7
  "jsnext:main": "build/es/index.js",
@@ -93,6 +93,7 @@
93
93
  "style-loader": "^3.3.3",
94
94
  "styled-components": "^5.3.11",
95
95
  "ts-jest": "^29.1.2",
96
+ "ts-node": "^10.9.2",
96
97
  "tslib": "^2.1.0",
97
98
  "typescript": "^4.1.3",
98
99
  "webpack": "^5.88.2"
@@ -1 +0,0 @@
1
- import '@testing-library/jest-dom';
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- import '@testing-library/jest-dom';
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};