@reykjavik/hanna-react 0.10.111 → 0.10.113
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/Alert.js +1 -1
- package/BasicTable.js +4 -4
- package/CHANGELOG.md +34 -1
- package/ContactBubble.js +8 -3
- package/Datepicker.d.ts +1 -0
- package/Datepicker.js +51 -13
- package/{_abstract/_FocusTrap.d.ts → FocusTrap.d.ts} +5 -1
- package/{_abstract/_FocusTrap.js → FocusTrap.js} +5 -1
- package/Layout.d.ts +7 -3
- package/Layout.js +7 -26
- package/MainMenu.d.ts +52 -20
- package/MainMenu.js +27 -6
- package/MainMenu2.d.ts +114 -0
- package/MainMenu2.js +235 -0
- package/MobileMenuToggler/_useMobileMenuToggling.d.ts +21 -0
- package/{utils/useMenuToggling.js → MobileMenuToggler/_useMobileMenuToggling.js} +34 -14
- package/MobileMenuToggler.d.ts +21 -0
- package/MobileMenuToggler.js +43 -0
- package/Multiselect.js +13 -6
- package/TagPill.d.ts +2 -0
- package/_abstract/_AbstractModal.js +9 -4
- package/_abstract/_Button.d.ts +3 -3
- package/_abstract/_Button.js +3 -3
- package/_abstract/_Table.d.ts +3 -3
- package/_abstract/_Table.js +1 -1
- package/esm/Alert.js +1 -1
- package/esm/BasicTable.js +4 -4
- package/esm/ContactBubble.js +8 -3
- package/esm/Datepicker.d.ts +1 -0
- package/esm/Datepicker.js +51 -13
- package/esm/{_abstract/_FocusTrap.d.ts → FocusTrap.d.ts} +5 -1
- package/esm/{_abstract/_FocusTrap.js → FocusTrap.js} +5 -1
- package/esm/Layout.d.ts +7 -3
- package/esm/Layout.js +8 -27
- package/esm/MainMenu.d.ts +52 -20
- package/esm/MainMenu.js +27 -7
- package/esm/MainMenu2.d.ts +114 -0
- package/esm/MainMenu2.js +230 -0
- package/esm/MobileMenuToggler/_useMobileMenuToggling.d.ts +21 -0
- package/esm/{utils/useMenuToggling.js → MobileMenuToggler/_useMobileMenuToggling.js} +32 -13
- package/esm/MobileMenuToggler.d.ts +21 -0
- package/esm/MobileMenuToggler.js +37 -0
- package/esm/Multiselect.js +12 -5
- package/esm/TagPill.d.ts +2 -0
- package/esm/_abstract/_AbstractModal.js +7 -2
- package/esm/_abstract/_Button.d.ts +3 -3
- package/esm/_abstract/_Button.js +3 -3
- package/esm/_abstract/_Table.d.ts +3 -3
- package/esm/_abstract/_Table.js +1 -1
- package/esm/index.d.ts +3 -0
- package/esm/utils/a11yHelpers.d.ts +2 -0
- package/esm/utils/a11yHelpers.js +11 -0
- package/esm/utils/types.d.ts +4 -0
- package/esm/utils/useFormatMonitor.d.ts +4 -11
- package/esm/utils/useFormatMonitor.js +0 -10
- package/esm/utils.d.ts +7 -2
- package/esm/utils.js +8 -2
- package/index.d.ts +3 -0
- package/package.json +13 -1
- package/utils/a11yHelpers.d.ts +2 -0
- package/utils/a11yHelpers.js +15 -0
- package/utils/types.d.ts +4 -0
- package/utils/useFormatMonitor.d.ts +4 -11
- package/utils/useFormatMonitor.js +0 -10
- package/utils.d.ts +7 -2
- package/utils.js +9 -5
- package/esm/utils/HannaUIState.d.ts +0 -7
- package/esm/utils/HannaUIState.js +0 -7
- package/esm/utils/useMenuToggling.d.ts +0 -10
- package/utils/HannaUIState.d.ts +0 -7
- package/utils/HannaUIState.js +0 -11
- package/utils/useMenuToggling.d.ts +0 -10
package/Alert.js
CHANGED
|
@@ -52,8 +52,8 @@ const Alert = (props) => {
|
|
|
52
52
|
closeUrl, closable = !!(onClose || closeUrl != null), ssr, onClosed, wrapperProps, } = props;
|
|
53
53
|
const autoClose = Math.max(props.autoClose || 0, 0);
|
|
54
54
|
const closing = (0, react_1.useRef)();
|
|
55
|
-
const [open, setOpen] = (0, react_1.useState)(!!ssr);
|
|
56
55
|
const isBrowser = (0, utils_js_1.useIsBrowserSide)(ssr);
|
|
56
|
+
const [open, setOpen] = (0, react_1.useState)(!isBrowser);
|
|
57
57
|
const showCloseButton = closable && (isBrowser || closeUrl != null);
|
|
58
58
|
const { closeLabel, closeLabelLong } = (0, i18n_1.getTexts)(props, exports.defaultAlertTexts);
|
|
59
59
|
(0, react_1.useEffect)(() => {
|
package/BasicTable.js
CHANGED
|
@@ -12,7 +12,7 @@ const tableTypes = {
|
|
|
12
12
|
};
|
|
13
13
|
const BasicTable = (props) => {
|
|
14
14
|
// eslint-disable-next-line deprecation/deprecation
|
|
15
|
-
const { align, fullWidth, type, tbody, tbodies, modifier } = props;
|
|
15
|
+
const { align, fullWidth, type, tbody, tbodies, modifier, thead, tfoot, tableProps, caption, rowProps, compact, cols, wrapperProps, } = props;
|
|
16
16
|
return (react_1.default.createElement(_ScrollWrapper_js_1.ScrollWrapper, { bem: "TableWrapper", modifier: [
|
|
17
17
|
'BasicTable',
|
|
18
18
|
modifier && 'BasicTable--' + modifier,
|
|
@@ -21,12 +21,12 @@ const BasicTable = (props) => {
|
|
|
21
21
|
: align === 'right'
|
|
22
22
|
? 'BasicTable--align--' + align
|
|
23
23
|
: undefined,
|
|
24
|
-
], wrapperProps:
|
|
24
|
+
], wrapperProps: wrapperProps },
|
|
25
25
|
react_1.default.createElement(_Table_js_1.Table, Object.assign({ className: (0, classUtils_1.modifiedClass)('BasicTable', [
|
|
26
|
-
|
|
26
|
+
compact && 'compact',
|
|
27
27
|
type && tableTypes[type],
|
|
28
28
|
modifier,
|
|
29
|
-
]), cols:
|
|
29
|
+
]), cols: cols, caption: caption, thead: thead, tfoot: tfoot }, (tbody ? { tbody } : { tbodies }), { rowProps: rowProps, wrapperProps: tableProps }))));
|
|
30
30
|
};
|
|
31
31
|
exports.BasicTable = BasicTable;
|
|
32
32
|
exports.default = exports.BasicTable;
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,39 @@
|
|
|
4
4
|
|
|
5
5
|
- ... <!-- Add new lines here. -->
|
|
6
6
|
|
|
7
|
+
## 0.10.113
|
|
8
|
+
|
|
9
|
+
_2023-12-08_
|
|
10
|
+
|
|
11
|
+
- feat: Add component `MainMenu2`
|
|
12
|
+
- feat: Make `Datepicker` more flexible when parsing manual input strings –
|
|
13
|
+
adds several, localized default formats.
|
|
14
|
+
- feat: Add accessibility helper component `FocusTrap`
|
|
15
|
+
- Decouple all mobile-menu toggling logic from the `Layout` component
|
|
16
|
+
- feat: Deprecate `useFormatMonitor` media flags `*Hamburger`, `*Topmenu`
|
|
17
|
+
- feat: Deprecate `useMenuToggling` hook
|
|
18
|
+
- feat: Add `.Layout__header__navlink`
|
|
19
|
+
- feat: Make `MainMenu` define its own toggler button and "Hamburger" mode
|
|
20
|
+
- feat: Add standalone `MobileMenuToggler` component
|
|
21
|
+
- `Multiselect`:
|
|
22
|
+
- fix: Suppress required asterisks on individual options
|
|
23
|
+
- fix: Deduplicate the currentvalues list
|
|
24
|
+
- fix: Manage focus after clicking remove buttons on currentvalues
|
|
25
|
+
- `BasicTable`:
|
|
26
|
+
- feat: Pass `rowData` as 3rd param to `rowProps` callbacks
|
|
27
|
+
- fix: Actually apply `rowProps` to the `<tr/>`s. (Awk)
|
|
28
|
+
- `ButtonPrimary`, `ButtonSecondary`, `ButtonTertiary`, `ButtonBack`,
|
|
29
|
+
`TextButton`:
|
|
30
|
+
- feat: Allow props `className` and `style`
|
|
31
|
+
- feat: Tweak `ContactBubble`'s show/hide scroll-distance thresholds
|
|
32
|
+
- fix: Suppress `MainMenu` server-rendering no-op `<button/>` elements
|
|
33
|
+
|
|
34
|
+
## 0.10.112
|
|
35
|
+
|
|
36
|
+
_2023-11-17_
|
|
37
|
+
|
|
38
|
+
- fix: `Modal` not reoppening when `open` prop is toggled
|
|
39
|
+
|
|
7
40
|
## 0.10.110 – 0.10.111
|
|
8
41
|
|
|
9
42
|
_2023-11-10_
|
|
@@ -150,7 +183,7 @@ _2023-07-26_
|
|
|
150
183
|
_2023-07-25_
|
|
151
184
|
|
|
152
185
|
- feat: Add optional `altText` parameter to `useGetSVGtext()`
|
|
153
|
-
- feat: Export `useMenuToggling` from
|
|
186
|
+
- feat: Export `useMenuToggling` from `utils` module
|
|
154
187
|
- feat: Export `SSRSupportProps` type
|
|
155
188
|
- perf: Reduce render thrashing of `Layout`'s navChildren
|
|
156
189
|
- fix: `Layout` components set `alt="Reykjavík"` text on their header logo
|
package/ContactBubble.js
CHANGED
|
@@ -59,7 +59,9 @@ const ContactBubble = (props) => {
|
|
|
59
59
|
onToggle && onToggle(false);
|
|
60
60
|
setFocus !== false && (0, focusElm_1.focusElm)(wrapperRef.current);
|
|
61
61
|
},
|
|
62
|
-
}),
|
|
62
|
+
}),
|
|
63
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
64
|
+
[useLocalState, onToggle]);
|
|
63
65
|
(0, react_1.useEffect)(() => {
|
|
64
66
|
const wrapperElm = wrapperRef.current;
|
|
65
67
|
if (!wrapperElm) {
|
|
@@ -77,7 +79,8 @@ const ContactBubble = (props) => {
|
|
|
77
79
|
const scrollLength = scrollHeight - clientHeight;
|
|
78
80
|
// const f = scrollLength > 600 ? 1 : (scrollLength - 200) / 600;
|
|
79
81
|
const f = 1;
|
|
80
|
-
const show = scrollTop > f *
|
|
82
|
+
const show = scrollTop > f * 130 && // minimum distance from the top
|
|
83
|
+
scrollLength - scrollTop > f * 200; // ...and bottom
|
|
81
84
|
wrapperElm.dataset.show = String(show);
|
|
82
85
|
!show && closeBubble(false);
|
|
83
86
|
pending = 0;
|
|
@@ -98,7 +101,9 @@ const ContactBubble = (props) => {
|
|
|
98
101
|
document.removeEventListener('scroll', checkScroll);
|
|
99
102
|
document.documentElement.removeEventListener('scroll', checkScroll);
|
|
100
103
|
};
|
|
101
|
-
},
|
|
104
|
+
},
|
|
105
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
106
|
+
[isBrowser, alwaysShow, closeBubble]);
|
|
102
107
|
(0, react_1.useEffect)(() => {
|
|
103
108
|
const escHandler = (e) => e.key === 'Escape' && closeBubble();
|
|
104
109
|
const outsideClickHandler = (e) => {
|
package/Datepicker.d.ts
CHANGED
package/Datepicker.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Datepicker = exports.getDateDiff = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const react_1 = tslib_1.
|
|
5
|
+
const react_1 = tslib_1.__importStar(require("react"));
|
|
6
6
|
const i18n_1 = require("@reykjavik/hanna-utils/i18n");
|
|
7
7
|
// For more info on localization see: https://stackoverflow.com/questions/54399084/change-locale-in-react-datepicker/58306958#58306958
|
|
8
8
|
const index_js_1 = tslib_1.__importDefault(require("date-fns/locale/is/index.js"));
|
|
@@ -40,6 +40,16 @@ const defaultDatepickerTexts = {
|
|
|
40
40
|
monthAriaLabelPrefix: 'Mánuður:',
|
|
41
41
|
chooseDayAriaLabelPrefix: 'Veldu:',
|
|
42
42
|
disabledDayAriaLabelPrefix: 'Ekki í boði:',
|
|
43
|
+
dateFormats: [
|
|
44
|
+
'dd.MM.yyyy',
|
|
45
|
+
'dd.MM.yy',
|
|
46
|
+
'dd/MM/yyyy',
|
|
47
|
+
'dd/MM/yy',
|
|
48
|
+
'dd. MM. yyyy',
|
|
49
|
+
'dd. MM. yy',
|
|
50
|
+
'dd MM yyyy',
|
|
51
|
+
'dd MM yy',
|
|
52
|
+
],
|
|
43
53
|
},
|
|
44
54
|
// React-datepicker has its own (default) English translation built in.
|
|
45
55
|
// No need to repeat all of it here.
|
|
@@ -59,6 +69,16 @@ const defaultDatepickerTexts = {
|
|
|
59
69
|
monthAriaLabelPrefix: 'Month:',
|
|
60
70
|
chooseDayAriaLabelPrefix: 'Choose:',
|
|
61
71
|
disabledDayAriaLabelPrefix: 'Not available:',
|
|
72
|
+
dateFormats: [
|
|
73
|
+
'MM.dd.yyyy',
|
|
74
|
+
'MM.dd.yy',
|
|
75
|
+
'MM/dd/yyyy',
|
|
76
|
+
'MM/dd/yy',
|
|
77
|
+
'MM. dd. yyyy',
|
|
78
|
+
'MM. dd. yy',
|
|
79
|
+
'MM dd yyyy',
|
|
80
|
+
'MM dd yy',
|
|
81
|
+
],
|
|
62
82
|
},
|
|
63
83
|
pl: {
|
|
64
84
|
ariaLabelClose: 'Zamknij',
|
|
@@ -76,6 +96,16 @@ const defaultDatepickerTexts = {
|
|
|
76
96
|
monthAriaLabelPrefix: 'Miesiąc:',
|
|
77
97
|
chooseDayAriaLabelPrefix: 'Wybierać:',
|
|
78
98
|
disabledDayAriaLabelPrefix: 'Niedostępna:',
|
|
99
|
+
dateFormats: [
|
|
100
|
+
'dd.MM.yyyy',
|
|
101
|
+
'dd.MM.yy',
|
|
102
|
+
'dd/MM/yyyy',
|
|
103
|
+
'dd/MM/yy',
|
|
104
|
+
'dd. MM. yyyy',
|
|
105
|
+
'dd. MM. yy',
|
|
106
|
+
'dd MM yyyy',
|
|
107
|
+
'dd MM yy',
|
|
108
|
+
],
|
|
79
109
|
},
|
|
80
110
|
};
|
|
81
111
|
/**
|
|
@@ -84,7 +114,7 @@ const defaultDatepickerTexts = {
|
|
|
84
114
|
* Internally, this component uses the [`react-datepicker`](https://reactdatepicker.com/) component.
|
|
85
115
|
*/
|
|
86
116
|
const Datepicker = (props) => {
|
|
87
|
-
const { placeholder, dateFormat
|
|
117
|
+
const { placeholder, dateFormat, name, startDate, endDate, minDate, maxDate, isStartDate = false, isEndDate = false, onChange, datepickerExtraProps, inputRef, isoMode, texts, lang = props.localeCode, fieldWrapperProps, } = (0, FormField_js_1.groupFormFieldWrapperProps)(props);
|
|
88
118
|
const [value, setValue] = utils_js_1.useMixedControlState.raw(props.value || props.initialDate, // eslint-disable-line deprecation/deprecation
|
|
89
119
|
props.defaultValue, 'value');
|
|
90
120
|
/*
|
|
@@ -96,6 +126,24 @@ const Datepicker = (props) => {
|
|
|
96
126
|
const txts = (0, i18n_1.getTexts)({ texts, lang }, defaultDatepickerTexts);
|
|
97
127
|
const filled = !!value;
|
|
98
128
|
const empty = !filled && !placeholder;
|
|
129
|
+
const normalizedDateFormats = (0, react_1.useMemo)(() => {
|
|
130
|
+
const dateFormatProp = !dateFormat
|
|
131
|
+
? ['d.M.yyyy']
|
|
132
|
+
: typeof dateFormat === 'string'
|
|
133
|
+
? [dateFormat]
|
|
134
|
+
: dateFormat.slice(0);
|
|
135
|
+
// NOTE: Force all dateFormat values into Array<string> to temporarily work around
|
|
136
|
+
// a bug in the current version of react-datepicker where invalid `string` values
|
|
137
|
+
// are re-parsed with `new Date()`, causing surprising (weird) false positives
|
|
138
|
+
// AND where Arrayed formats get parsed in order of "increasing priority".
|
|
139
|
+
//
|
|
140
|
+
// TODO: Revert back to the plain `dateFormat={dateFormat}` pass-through once
|
|
141
|
+
// https://github.com/Hacker0x01/react-datepicker/pull/3988 has been accepted and released.
|
|
142
|
+
return dateFormatProp
|
|
143
|
+
.concat(['yyyy-MM-dd'])
|
|
144
|
+
.concat(txts.dateFormats)
|
|
145
|
+
.concat(['P', 'PP', 'PPP']);
|
|
146
|
+
}, [dateFormat, txts]);
|
|
99
147
|
return (react_1.default.createElement(FormField_js_1.FormField, Object.assign({ extraClassName: "Datepicker", filled: filled, empty: empty }, fieldWrapperProps, { renderInput: (className, inputProps, addFocusProps) => {
|
|
100
148
|
return (react_1.default.createElement("div", Object.assign({ className: className.input, onClick: ({ target, currentTarget }) => { var _a; return target === currentTarget && ((_a = currentTarget.querySelector('input')) === null || _a === void 0 ? void 0 : _a.focus()); }, ref: inputRef &&
|
|
101
149
|
((elm) => {
|
|
@@ -104,17 +152,7 @@ const Datepicker = (props) => {
|
|
|
104
152
|
return elm;
|
|
105
153
|
}) }, addFocusProps()),
|
|
106
154
|
isoMode && (react_1.default.createElement("input", { type: "hidden", name: name, value: value === null || value === void 0 ? void 0 : value.toISOString().slice(0, 10) })),
|
|
107
|
-
react_1.default.createElement(ReactDatepicker_js_1.ReactDatePicker, Object.assign({ id: domid, required: inputProps.required, disabled: inputProps.disabled, readOnly: inputProps.readOnly, selected: value, name: isoMode ? undefined : name, locale: lang, dateFormat:
|
|
108
|
-
// NOTE: Force all dateFormat values into Array<string> to temporarily work around
|
|
109
|
-
// a bug in the current version of react-datepicker where invalid `string` values
|
|
110
|
-
// are re-parsed with `new Date()`, causing surprising (weird) false positives
|
|
111
|
-
// AND where Arrayed formats get parsed in order of "increasing priority".
|
|
112
|
-
//
|
|
113
|
-
// TODO: Revert back to the plain `dateFormat={dateFormat}` pass-through once
|
|
114
|
-
// https://github.com/Hacker0x01/react-datepicker/pull/3988 has been accepted and released.
|
|
115
|
-
typeof dateFormat === 'string'
|
|
116
|
-
? [dateFormat]
|
|
117
|
-
: dateFormat.slice(0).reverse(), onChange: (date) => {
|
|
155
|
+
react_1.default.createElement(ReactDatepicker_js_1.ReactDatePicker, Object.assign({ id: domid, required: inputProps.required, disabled: inputProps.disabled, readOnly: inputProps.readOnly, selected: value, name: isoMode ? undefined : name, locale: lang, dateFormat: normalizedDateFormats, onChange: (date) => {
|
|
118
156
|
date = date || undefined;
|
|
119
157
|
setValue(date);
|
|
120
158
|
onChange && onChange(date);
|
|
@@ -10,5 +10,9 @@ export type FocusTrapProps = {
|
|
|
10
10
|
*/
|
|
11
11
|
depth?: number;
|
|
12
12
|
};
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* A focus trap element that can be used to keep keyboard focus within a container block.
|
|
15
|
+
*
|
|
16
|
+
* Make sure you only trap focus when a modal or
|
|
17
|
+
*/
|
|
14
18
|
export declare const FocusTrap: (props: FocusTrapProps) => JSX.Element;
|
|
@@ -3,7 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.FocusTrap = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* A focus trap element that can be used to keep keyboard focus within a container block.
|
|
8
|
+
*
|
|
9
|
+
* Make sure you only trap focus when a modal or
|
|
10
|
+
*/
|
|
7
11
|
const FocusTrap = (props) => {
|
|
8
12
|
const Tag = props.Tag || 'span';
|
|
9
13
|
return (react_1.default.createElement(Tag, { tabIndex: 0, onFocus: (e) => {
|
package/Layout.d.ts
CHANGED
|
@@ -3,10 +3,12 @@ import type { HannaColorTheme } from '@reykjavik/hanna-css';
|
|
|
3
3
|
import { EitherObj } from '@reykjavik/hanna-utils';
|
|
4
4
|
import { DefaultTexts, HannaLang } from '@reykjavik/hanna-utils/i18n';
|
|
5
5
|
import { BemModifierProps } from './utils/types.js';
|
|
6
|
-
import {
|
|
6
|
+
import { SSRSupport, WrapperElmProps } from './utils.js';
|
|
7
7
|
export type LayoutI18n = {
|
|
8
8
|
skipLinkLabel: string;
|
|
9
|
-
|
|
9
|
+
/** @deprecated Not used (Will be removed in v0.11) */
|
|
10
|
+
closeMenuLabel?: string;
|
|
11
|
+
/** @deprecated Not used (Will be removed in v0.11) */
|
|
10
12
|
closeMenuLabelLong?: string;
|
|
11
13
|
/** @deprecated Not used (Will be removed in v0.11) */
|
|
12
14
|
lang?: string;
|
|
@@ -21,7 +23,9 @@ type LayoutProps = {
|
|
|
21
23
|
siteName?: string;
|
|
22
24
|
texts?: LayoutI18n;
|
|
23
25
|
lang?: HannaLang;
|
|
24
|
-
|
|
26
|
+
/** @deprecated Not used (Will be removed in v0.11) */
|
|
27
|
+
ssr?: SSRSupport;
|
|
28
|
+
} & WrapperElmProps & BemModifierProps & EitherObj<{
|
|
25
29
|
mainChildren: ReactNode;
|
|
26
30
|
}, {
|
|
27
31
|
children: ReactNode;
|
package/Layout.js
CHANGED
|
@@ -6,30 +6,17 @@ const react_1 = tslib_1.__importDefault(require("react"));
|
|
|
6
6
|
const classUtils_1 = require("@hugsmidjan/qj/classUtils");
|
|
7
7
|
const i18n_1 = require("@reykjavik/hanna-utils/i18n");
|
|
8
8
|
const _Layouts_js_1 = require("./_abstract/_Layouts.js");
|
|
9
|
-
const
|
|
9
|
+
const a11yHelpers_js_1 = require("./utils/a11yHelpers.js");
|
|
10
10
|
const utils_js_1 = require("./utils.js");
|
|
11
11
|
exports.defaultLayoutTexts = {
|
|
12
|
-
is: {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
closeMenuLabelLong: 'Loka valmynd',
|
|
16
|
-
},
|
|
17
|
-
en: {
|
|
18
|
-
skipLinkLabel: 'Skip to navigation',
|
|
19
|
-
closeMenuLabel: 'Close',
|
|
20
|
-
closeMenuLabelLong: 'Close menu',
|
|
21
|
-
},
|
|
22
|
-
pl: {
|
|
23
|
-
skipLinkLabel: 'Przejdź do nawigacji',
|
|
24
|
-
closeMenuLabel: 'Zamknij',
|
|
25
|
-
closeMenuLabelLong: 'Zamknij menu',
|
|
26
|
-
},
|
|
12
|
+
is: { skipLinkLabel: 'Fara í leiðakerfi' },
|
|
13
|
+
en: { skipLinkLabel: 'Skip to navigation' },
|
|
14
|
+
pl: { skipLinkLabel: 'Przejdź do nawigacji' },
|
|
27
15
|
};
|
|
28
16
|
const Layout = (props) => {
|
|
29
17
|
(0, utils_js_1.useScrollbarWidthCSSVar)();
|
|
30
|
-
const {
|
|
18
|
+
const { globalAlerts, mainChildren, navChildren, footerChildren, colorTheme, children, siteName, logoLink = '/', wrapperProps, } = props;
|
|
31
19
|
(0, _Layouts_js_1.issueSiteNameWarningInDev)(props);
|
|
32
|
-
const { isMenuActive, uiState, closeMenu, toggleMenu } = (0, utils_js_1.useMenuToggling)(ssr !== 'ssr-only');
|
|
33
20
|
const txt = (0, i18n_1.getTexts)(props, exports.defaultLayoutTexts);
|
|
34
21
|
return (react_1.default.createElement("div", Object.assign({}, wrapperProps, { className: (0, classUtils_1.modifiedClass)('Layout', props.modifier, (wrapperProps || {}).className), "data-color-theme": colorTheme }),
|
|
35
22
|
globalAlerts && (react_1.default.createElement("div", { className: "Layout__alerts", role: "alert" }, globalAlerts)),
|
|
@@ -37,15 +24,9 @@ const Layout = (props) => {
|
|
|
37
24
|
react_1.default.createElement("div", { className: "Layout__header", role: "banner" },
|
|
38
25
|
(0, _Layouts_js_1.renderLayoutHomeLink)('Layout', logoLink, siteName),
|
|
39
26
|
' ',
|
|
40
|
-
navChildren && (react_1.default.createElement(
|
|
41
|
-
((e) => {
|
|
42
|
-
e.preventDefault();
|
|
43
|
-
toggleMenu();
|
|
44
|
-
}), "aria-label": txt.skipLinkLabel }, txt.skipLinkLabel))),
|
|
27
|
+
navChildren && (react_1.default.createElement("a", { className: "Layout__header__navlink", href: "#pagenav", onClick: a11yHelpers_js_1.handleAnchorLinkClick, "aria-label": txt.skipLinkLabel }, txt.skipLinkLabel))),
|
|
45
28
|
react_1.default.createElement("div", { className: "Layout__main", role: "main" }, mainChildren || children),
|
|
46
|
-
navChildren && (react_1.default.createElement("div", { className: "Layout__nav", id: "pagenav", role: "navigation" },
|
|
47
|
-
react_1.default.createElement(utils_js_1.HannaUIState, { value: uiState }, navChildren),
|
|
48
|
-
isMenuActive && (react_1.default.createElement("button", { className: "Layout__nav__closebutton", onClick: closeMenu, "aria-label": txt.closeMenuLabelLong, type: "button" }, txt.closeMenuLabel)))),
|
|
29
|
+
navChildren && (react_1.default.createElement("div", { className: "Layout__nav", id: "pagenav", tabIndex: -1, role: "navigation" }, navChildren)),
|
|
49
30
|
react_1.default.createElement("div", { className: "Layout__footer", role: "complementary" }, footerChildren))));
|
|
50
31
|
};
|
|
51
32
|
exports.Layout = Layout;
|
package/MainMenu.d.ts
CHANGED
|
@@ -1,48 +1,81 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { ReactElement } from 'react';
|
|
2
2
|
import { Modifiers } from '@hugsmidjan/qj/classUtils';
|
|
3
|
-
import { Cleanup } from '@reykjavik/hanna-utils';
|
|
4
|
-
import { DefaultTexts, HannaLang } from '@reykjavik/hanna-utils/i18n';
|
|
3
|
+
import { Cleanup, EitherObj } from '@reykjavik/hanna-utils';
|
|
5
4
|
import { AuxilaryPanelIllustration, AuxiliaryPanelProps } from './MainMenu/_Auxiliary.js';
|
|
6
5
|
import { MegaMenuItem, MegaMenuItemList, MegaMenuPanel, PrimaryPanelI18n } from './MainMenu/_PrimaryPanel.js';
|
|
6
|
+
import { I18NProps } from './utils/types.js';
|
|
7
|
+
import { MobileMenuTogglerI18n } from './MobileMenuToggler.js';
|
|
7
8
|
import { SSRSupportProps, WrapperElmProps } from './utils.js';
|
|
8
9
|
export type MainMenuI18n = Cleanup<{
|
|
9
10
|
homeLabel?: string;
|
|
10
11
|
title: string;
|
|
11
12
|
/** @deprecated Not used (Will be removed in v0.11) */
|
|
12
13
|
lang?: string;
|
|
13
|
-
} & PrimaryPanelI18n
|
|
14
|
-
export declare const defaultMainMenuTexts:
|
|
14
|
+
} & PrimaryPanelI18n & EitherObj<MobileMenuTogglerI18n, {}>>;
|
|
15
|
+
export declare const defaultMainMenuTexts: {
|
|
16
|
+
is: {
|
|
17
|
+
title: string;
|
|
18
|
+
homeLabel: string;
|
|
19
|
+
backToMenu: string;
|
|
20
|
+
backToMenuLong: string;
|
|
21
|
+
};
|
|
22
|
+
en: {
|
|
23
|
+
title: string;
|
|
24
|
+
homeLabel: string;
|
|
25
|
+
backToMenu: string;
|
|
26
|
+
backToMenuLong: string;
|
|
27
|
+
};
|
|
28
|
+
pl: {
|
|
29
|
+
title: string;
|
|
30
|
+
homeLabel: string;
|
|
31
|
+
backToMenu: string;
|
|
32
|
+
backToMenuLong: string;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
15
35
|
export type { AuxilaryPanelIllustration, AuxiliaryPanelProps, MegaMenuItem, MegaMenuItemList, MegaMenuPanel, };
|
|
16
36
|
export type MainMenuItem = {
|
|
37
|
+
/** Visible label text */
|
|
17
38
|
label: string;
|
|
39
|
+
/** Un-abbreviated label set as `title=""` and `aria-label=""` */
|
|
18
40
|
labelLong?: string;
|
|
41
|
+
/** Language of the link label */
|
|
19
42
|
lang?: string;
|
|
43
|
+
/** Languge of the linked resource */
|
|
20
44
|
hrefLang?: string;
|
|
21
45
|
/**
|
|
22
|
-
* Puts a modifier className
|
|
23
|
-
*
|
|
24
|
-
* Example:
|
|
25
|
-
*
|
|
26
|
-
* ```html
|
|
27
|
-
* <li class="MainMenu__item MainMenu__item--${modifier}">
|
|
28
|
-
* ```
|
|
46
|
+
* Puts a modifier className for the menu __item <li/> element.
|
|
29
47
|
* */
|
|
30
48
|
modifier?: Modifiers;
|
|
49
|
+
/** Signifies if the menu item is part of the page's breadcrumb trail */
|
|
31
50
|
current?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* The URL the link points to.
|
|
53
|
+
*
|
|
54
|
+
* If neither `href` nor `onClick` is passed, then the item is not rendered
|
|
55
|
+
* at all.
|
|
56
|
+
*/
|
|
32
57
|
href?: string;
|
|
58
|
+
/** Sets `target=""` on anchor tags with a `href` attribute. */
|
|
59
|
+
target?: React.HTMLAttributeAnchorTarget;
|
|
33
60
|
/**
|
|
34
|
-
* Adding `onClick` automatically results in a <button/> element being
|
|
61
|
+
* Adding `onClick` automatically results in a <button/> element being
|
|
62
|
+
* rendered. If `href` is also passed, then a <a href/> element is rendered
|
|
63
|
+
* during initial (server-side) render, which then gets replaced by a
|
|
64
|
+
* <button/> element during the first client-side render.
|
|
35
65
|
*
|
|
36
|
-
* NOTE: Clicking a
|
|
66
|
+
* NOTE: Clicking a menu item will automatically close HannaUIState's
|
|
37
67
|
* "Hamburger menu" (a.k.a. "Mobile menu")
|
|
38
68
|
* … unless the `onClick` function explicitly returns `false`.
|
|
39
69
|
*/
|
|
40
70
|
onClick?: (index: number, item: MainMenuItem) => void | boolean;
|
|
71
|
+
/** Sets `aria-controls=""` on `<button/>`s with `onClick` */
|
|
41
72
|
controlsId?: string;
|
|
42
|
-
target?: React.HTMLAttributeAnchorTarget;
|
|
43
73
|
};
|
|
74
|
+
/** String token that hints that a flexible space should be inserted at this
|
|
75
|
+
* point in the menu item list.
|
|
76
|
+
*/
|
|
44
77
|
export type MainMenuSeparator = '---';
|
|
45
|
-
export type MainMenuItemList = Array<MainMenuItem | MainMenuSeparator | (() =>
|
|
78
|
+
export type MainMenuItemList = Array<MainMenuItem | MainMenuSeparator | (() => ReactElement)>;
|
|
46
79
|
export type MainMenuProps = {
|
|
47
80
|
/**
|
|
48
81
|
* Top-level screen-reader headline/label for the whole menu.
|
|
@@ -64,8 +97,7 @@ export type MainMenuProps = {
|
|
|
64
97
|
*/
|
|
65
98
|
onItemClick?: (index: number, item: MainMenuItem) => void | boolean;
|
|
66
99
|
activePanelId?: string;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
export declare const MainMenu: (props: MainMenuProps) => JSX.Element | null;
|
|
100
|
+
} & SSRSupportProps & I18NProps<MainMenuI18n> & WrapperElmProps<null, 'aria-label'>;
|
|
101
|
+
export declare const _MainMenu: (props: MainMenuProps) => JSX.Element | null;
|
|
102
|
+
export declare const MainMenu: (props: MainMenuProps) => JSX.Element;
|
|
71
103
|
export default MainMenu;
|
package/MainMenu.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MainMenu = exports.defaultMainMenuTexts = void 0;
|
|
3
|
+
exports.MainMenu = exports._MainMenu = exports.defaultMainMenuTexts = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
6
6
|
const classUtils_1 = require("@hugsmidjan/qj/classUtils");
|
|
@@ -9,11 +9,13 @@ const i18n_1 = require("@reykjavik/hanna-utils/i18n");
|
|
|
9
9
|
const _Link_js_1 = require("./_abstract/_Link.js");
|
|
10
10
|
const _Auxiliary_js_1 = require("./MainMenu/_Auxiliary.js");
|
|
11
11
|
const _PrimaryPanel_js_1 = require("./MainMenu/_PrimaryPanel.js");
|
|
12
|
-
const HannaUIState_js_1 = require("./utils/HannaUIState.js");
|
|
13
12
|
const useFormatMonitor_js_1 = require("./utils/useFormatMonitor.js");
|
|
14
13
|
const useShortState_js_1 = require("./utils/useShortState.js");
|
|
14
|
+
const MobileMenuToggler_js_1 = require("./MobileMenuToggler.js");
|
|
15
15
|
const utils_js_1 = require("./utils.js");
|
|
16
16
|
const findActivePanel = (megaPanels, activeId) => activeId ? megaPanels.find((panel) => activeId === panel.id) : undefined;
|
|
17
|
+
// const HamburgerMedias: Record<string, 1> = { phone: 1, phablet: 1, tablet: 1 };
|
|
18
|
+
const TopmenuMedias = { netbook: 1, wide: 1 };
|
|
17
19
|
exports.defaultMainMenuTexts = {
|
|
18
20
|
is: {
|
|
19
21
|
title: 'Aðalvalmynd',
|
|
@@ -80,11 +82,19 @@ const normalizeMenuItems = (itemsProp, megaPanels, homeLink, texts) => {
|
|
|
80
82
|
};
|
|
81
83
|
// ---------------------------------------------------------------------------
|
|
82
84
|
const emptyPanelList = [];
|
|
83
|
-
|
|
85
|
+
/*
|
|
86
|
+
NOTE:
|
|
87
|
+
This is made into sub-component to allow using the `useMobileMenuTogglerState`
|
|
88
|
+
hook. This MainMenu component will eventually be deprecated, and we're
|
|
89
|
+
maintaining a bunch of already deprecated legacy hook/utils exports,
|
|
90
|
+
so it doesn't seem worth the effort to refactor this into something slightly
|
|
91
|
+
"cleaner", cecause that would increase more complexity for the legacy exports.
|
|
92
|
+
*/
|
|
93
|
+
const _MainMenu = (props) => {
|
|
84
94
|
const { megaPanels = emptyPanelList, onItemClick, ssr, auxiliaryPanel, wrapperProps = {}, } = props;
|
|
85
95
|
const texts = (0, i18n_1.getTexts)(props, exports.defaultMainMenuTexts);
|
|
86
96
|
const title = props.title || texts.title;
|
|
87
|
-
const { closeHamburgerMenu } = (0,
|
|
97
|
+
const { closeHamburgerMenu } = (0, MobileMenuToggler_js_1.useMobileMenuTogglerState)();
|
|
88
98
|
const isBrowser = (0, utils_js_1.useIsBrowserSide)(ssr);
|
|
89
99
|
const _menuElmRef = (0, react_1.useRef)(null);
|
|
90
100
|
const menuElmRef = wrapperProps.ref || _menuElmRef;
|
|
@@ -132,7 +142,8 @@ const MainMenu = (props) => {
|
|
|
132
142
|
}
|
|
133
143
|
: () => undefined, [setLaggyActivePanel, isBrowser]);
|
|
134
144
|
(0, useFormatMonitor_js_1.useFormatMonitor)((media) => {
|
|
135
|
-
|
|
145
|
+
const leftTopmenu = !TopmenuMedias[media.is] && TopmenuMedias[media.was || ''];
|
|
146
|
+
if (leftTopmenu) {
|
|
136
147
|
setActivePanel(undefined);
|
|
137
148
|
}
|
|
138
149
|
});
|
|
@@ -190,7 +201,7 @@ const MainMenu = (props) => {
|
|
|
190
201
|
}
|
|
191
202
|
const { label, labelLong, lang, controlsId, onClick } = item;
|
|
192
203
|
const pressed = (activePanel && controlsId === activePanel.id) || undefined;
|
|
193
|
-
return (react_1.default.createElement("li", { key: i, className: (0, classUtils_1.modifiedClass)('MainMenu__item', item.modifier), "aria-current": item.current || undefined },
|
|
204
|
+
return (react_1.default.createElement("li", { key: i, className: (0, classUtils_1.modifiedClass)('MainMenu__item', item.modifier), "aria-current": item.current || undefined }, isBrowser && !!(item.megaPanel || onClick) ? (
|
|
194
205
|
// only print script-driven buttons in the browser
|
|
195
206
|
react_1.default.createElement("button", { className: "MainMenu__link", onClick: () => {
|
|
196
207
|
const keepOpen1 = onClick && onClick(i, item) === false;
|
|
@@ -223,5 +234,15 @@ const MainMenu = (props) => {
|
|
|
223
234
|
}),
|
|
224
235
|
auxiliaryPanel && react_1.default.createElement(_Auxiliary_js_1.AuxiliaryPanel, Object.assign({}, auxiliaryPanel)))))));
|
|
225
236
|
};
|
|
237
|
+
exports._MainMenu = _MainMenu;
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
const MainMenu = (props) => {
|
|
240
|
+
const _wrapperProps = props.wrapperProps;
|
|
241
|
+
const id = (0, utils_js_1.useDomid)(_wrapperProps && _wrapperProps.id);
|
|
242
|
+
const wrapperProps = _wrapperProps ? Object.assign(Object.assign({}, _wrapperProps), { id }) : { id };
|
|
243
|
+
const texts = (0, i18n_1.getTexts)(props, exports.defaultMainMenuTexts);
|
|
244
|
+
return (react_1.default.createElement(MobileMenuToggler_js_1.MobileMenuToggler, { ssr: props.ssr, lang: props.lang, texts: texts.togglerLabel ? texts : undefined, controlsId: id },
|
|
245
|
+
react_1.default.createElement(exports._MainMenu, Object.assign({}, props, { wrapperProps: wrapperProps }))));
|
|
246
|
+
};
|
|
226
247
|
exports.MainMenu = MainMenu;
|
|
227
248
|
exports.default = exports.MainMenu;
|
package/MainMenu2.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import React, { ReactElement } from 'react';
|
|
2
|
+
import { Modifiers } from '@hugsmidjan/qj/classUtils';
|
|
3
|
+
import { Cleanup, EitherObj } from '@reykjavik/hanna-utils';
|
|
4
|
+
import { Illustration } from '@reykjavik/hanna-utils/assets';
|
|
5
|
+
import { DefaultTexts } from '@reykjavik/hanna-utils/i18n';
|
|
6
|
+
import { I18NProps } from './utils/types.js';
|
|
7
|
+
import { SSRSupportProps, WrapperElmProps } from './utils.js';
|
|
8
|
+
export type MainMenu2I18n = {
|
|
9
|
+
title: string;
|
|
10
|
+
homeLink: string;
|
|
11
|
+
openMenu: string;
|
|
12
|
+
openMenuLong: string;
|
|
13
|
+
closeMenu: string;
|
|
14
|
+
closeMenuLong: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const defaultMainMenu2Texts: DefaultTexts<MainMenu2I18n>;
|
|
17
|
+
export type MainMenu2Item = {
|
|
18
|
+
/** Visible label text */
|
|
19
|
+
label: string;
|
|
20
|
+
/** Un-abbreviated label set as `title=""` and `aria-label=""` */
|
|
21
|
+
labelLong?: string;
|
|
22
|
+
/** Language of the link label */
|
|
23
|
+
lang?: string;
|
|
24
|
+
/** Languge of the linked resource */
|
|
25
|
+
hrefLang?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Puts a modifier className for the menu __item <li/> element.
|
|
28
|
+
* */
|
|
29
|
+
modifier?: Modifiers;
|
|
30
|
+
/** Signifies if the menu item is part of the page's breadcrumb trail */
|
|
31
|
+
current?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* The URL the link points to.
|
|
34
|
+
*
|
|
35
|
+
* If neither `href` nor `onClick` is passed, then the item is not rendered
|
|
36
|
+
* at all.
|
|
37
|
+
*/
|
|
38
|
+
href?: string;
|
|
39
|
+
/** Sets `target=""` on anchor tags with a `href` attribute. */
|
|
40
|
+
target?: React.HTMLAttributeAnchorTarget;
|
|
41
|
+
/**
|
|
42
|
+
* Adding `onClick` automatically results in a <button/> element being
|
|
43
|
+
* rendered. If `href` is also passed, then a <a href/> element is rendered
|
|
44
|
+
* during initial (server-side) render, which then gets replaced by a
|
|
45
|
+
* <button/> element during the first client-side
|
|
46
|
+
*
|
|
47
|
+
* NOTE: Clicking a menu item will automatically close HannaUIState's
|
|
48
|
+
* "Hamburger menu" (a.k.a. "Mobile menu")
|
|
49
|
+
* … unless the `onClick` function explicitly returns `false`.
|
|
50
|
+
*/
|
|
51
|
+
onClick?: (item: MainMenu2Item) => void | boolean;
|
|
52
|
+
/** Sets `aria-controls=""` on `<button/>`s with `onClick` */
|
|
53
|
+
controlsId?: string;
|
|
54
|
+
};
|
|
55
|
+
export type MainMenu2ButtonItem = MainMenu2Item & {
|
|
56
|
+
icon?: 'search' | 'user' | 'alert' | 'globe';
|
|
57
|
+
};
|
|
58
|
+
export type MainMenu2CustomItem = (props: {
|
|
59
|
+
closeMenu: () => void;
|
|
60
|
+
}) => ReactElement;
|
|
61
|
+
export type MainMenu2SubMenuItem = MainMenu2Item & {
|
|
62
|
+
descr?: string;
|
|
63
|
+
};
|
|
64
|
+
export type MainMenu2SubMenu = {
|
|
65
|
+
title: string;
|
|
66
|
+
current?: boolean;
|
|
67
|
+
subItems: Array<MainMenu2SubMenuItem | MainMenu2CustomItem>;
|
|
68
|
+
};
|
|
69
|
+
export type MainMenu2ItemList = Array<MainMenu2Item | MainMenu2CustomItem>;
|
|
70
|
+
export type MainMenu2ButtonItemList = Array<MainMenu2ButtonItem | MainMenu2CustomItem>;
|
|
71
|
+
export type MainMenu2SubMenuItemList = Array<MainMenu2SubMenuItem | MainMenu2CustomItem>;
|
|
72
|
+
export type MainMenu2Props = {
|
|
73
|
+
/**
|
|
74
|
+
* URL for the mandatory (usually screen-reader-only) homepage Link.
|
|
75
|
+
*
|
|
76
|
+
* Default: `"/"`
|
|
77
|
+
*
|
|
78
|
+
* NOTE: The link's label is by default "Forsíða"/"Home Page"/"Strona główna"
|
|
79
|
+
* (depending on your page language) but it can be custom-translated via the
|
|
80
|
+
* `props.texts` translation prop.
|
|
81
|
+
*/
|
|
82
|
+
homeLink?: string | Cleanup<Omit<MainMenu2Item, 'modifier' | 'controlsId'> & {
|
|
83
|
+
href: string;
|
|
84
|
+
}>;
|
|
85
|
+
items: {
|
|
86
|
+
/**
|
|
87
|
+
* The "Main" menu items that appear once the menu is open.
|
|
88
|
+
*
|
|
89
|
+
* Each of these items normally contains a list of `subItems` and a title,
|
|
90
|
+
* but it can also be a direct link/button (or even a custom component).
|
|
91
|
+
*/
|
|
92
|
+
main?: Array<MainMenu2SubMenu | MainMenu2Item | MainMenu2CustomItem>;
|
|
93
|
+
/**
|
|
94
|
+
* The always-visible items that appear at the top of the page next the
|
|
95
|
+
* "Open Menu" button. Make sure to only use 2–3 items, and remember that
|
|
96
|
+
* they may be hidden on smaller screens.
|
|
97
|
+
*/
|
|
98
|
+
hot?: MainMenu2ButtonItemList;
|
|
99
|
+
extra?: MainMenu2ButtonItemList;
|
|
100
|
+
relatedTitle?: string;
|
|
101
|
+
related?: MainMenu2ItemList;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* NOTE: Clicking a MainMenu2 item will automatically close HannaUIState's
|
|
105
|
+
* "Hamburger menu" (a.k.a. "Mobile menu")
|
|
106
|
+
* … unless the `onItemClick` function explicitly returns `false`.
|
|
107
|
+
*/
|
|
108
|
+
onItemClick?: (item: MainMenu2Item) => void | boolean;
|
|
109
|
+
} & EitherObj<{
|
|
110
|
+
illustration?: Illustration;
|
|
111
|
+
}, {
|
|
112
|
+
imageUrl?: string;
|
|
113
|
+
}> & WrapperElmProps & I18NProps<MainMenu2I18n> & SSRSupportProps;
|
|
114
|
+
export declare const MainMenu2: (props: MainMenu2Props) => JSX.Element;
|