@entur/menu 5.2.1-beta.9 → 5.2.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.
@@ -0,0 +1,820 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const utils = require("@entur/utils");
4
+ const jsxRuntime = require("react/jsx-runtime");
5
+ const React = require("react");
6
+ const classNames = require("classnames");
7
+ const icons = require("@entur/icons");
8
+ const react = require("@floating-ui/react");
9
+ const button = require("@entur/button");
10
+ const tooltip = require("@entur/tooltip");
11
+ const tokens = require("@entur/tokens");
12
+ const a11y = require("@entur/a11y");
13
+ const typography = require("@entur/typography");
14
+ const expand = require("@entur/expand");
15
+ const BreadcrumbNavigation = ({
16
+ "aria-label": ariaLabel = "Brødsmulesti",
17
+ children
18
+ }) => {
19
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": ariaLabel, children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "eds-breadcrumbs", children: React.Children.map(children, (child, index) => {
20
+ return React.cloneElement(child, {
21
+ isCurrent: index + 1 === React.Children.count(children)
22
+ });
23
+ }) }) });
24
+ };
25
+ const defaultElement$1 = "a";
26
+ const BreadcrumbItem = ({
27
+ className,
28
+ isCurrent,
29
+ as,
30
+ ...rest
31
+ }) => {
32
+ const Element = as || defaultElement$1;
33
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
34
+ /* @__PURE__ */ jsxRuntime.jsx("li", { className: classNames("eds-breadcrumb__item", className), children: /* @__PURE__ */ jsxRuntime.jsx(
35
+ Element,
36
+ {
37
+ "aria-current": isCurrent ? "page" : void 0,
38
+ className: classNames("eds-breadcrumb__link", {
39
+ "eds-breadcrumb__link--current": isCurrent
40
+ }),
41
+ ...rest
42
+ }
43
+ ) }),
44
+ !isCurrent && /* @__PURE__ */ jsxRuntime.jsx(
45
+ icons.RightArrowIcon,
46
+ {
47
+ className: "eds-breadcrumb__separator",
48
+ inline: true,
49
+ role: "presentation"
50
+ }
51
+ )
52
+ ] });
53
+ };
54
+ function useControllableProp({
55
+ prop,
56
+ updater = () => void 0,
57
+ defaultValue
58
+ }) {
59
+ const [internalState, setInternalState] = React.useState(defaultValue);
60
+ React.useEffect(() => {
61
+ if (prop !== void 0) {
62
+ setInternalState(prop);
63
+ }
64
+ }, [prop]);
65
+ return prop === void 0 ? [internalState, setInternalState] : [prop, updater];
66
+ }
67
+ const CollapsibleSideNavigation = ({
68
+ className,
69
+ children,
70
+ size,
71
+ collapsed: collapsible,
72
+ onCollapseToggle,
73
+ collapsibleButtonPosition = "50%",
74
+ openSideMenuAriaLabel = "Åpne sidemeny",
75
+ closeSideMenuAriaLabel = "Lukk sidemeny",
76
+ ...rest
77
+ }) => {
78
+ const [collapsedMenu, setCollapsedMenu] = useControllableProp({
79
+ prop: collapsible,
80
+ defaultValue: false,
81
+ updater: onCollapseToggle
82
+ });
83
+ return /* @__PURE__ */ jsxRuntime.jsx(
84
+ SideNavigationContext.Provider,
85
+ {
86
+ value: {
87
+ isCollapsed: collapsedMenu
88
+ },
89
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
90
+ "ul",
91
+ {
92
+ className: classNames(
93
+ "eds-side-navigation",
94
+ { "eds-side-navigation--small": size === "small" },
95
+ { "eds-side-navigation--collapsed": collapsedMenu },
96
+ className
97
+ ),
98
+ ...rest,
99
+ children: [
100
+ children,
101
+ /* @__PURE__ */ jsxRuntime.jsx(
102
+ "button",
103
+ {
104
+ className: "eds-side-navigation__collapse-button",
105
+ onClick: () => setCollapsedMenu(!collapsedMenu),
106
+ style: { top: `${collapsibleButtonPosition}` },
107
+ children: collapsedMenu ? /* @__PURE__ */ jsxRuntime.jsx(icons.MenuIcon, { "aria-label": openSideMenuAriaLabel }) : /* @__PURE__ */ jsxRuntime.jsx(icons.LeftArrowIcon, { "aria-label": closeSideMenuAriaLabel })
108
+ }
109
+ )
110
+ ]
111
+ }
112
+ )
113
+ }
114
+ );
115
+ };
116
+ const SideNavigationContext = React.createContext({
117
+ isCollapsed: false
118
+ });
119
+ const useSideNavigationContext = () => {
120
+ const context = React.useContext(SideNavigationContext);
121
+ if (!context) {
122
+ console.error(
123
+ "Error reading SideNavigationContext. Please contact maintainer of @entur/menu"
124
+ );
125
+ }
126
+ return context;
127
+ };
128
+ const SelectContext = React.createContext(
129
+ {}
130
+ );
131
+ const OverflowMenu = ({
132
+ children,
133
+ className,
134
+ button: button$1,
135
+ buttonIcon,
136
+ placement = "bottom-start",
137
+ "aria-label": ariaLabel = "åpne valgmeny",
138
+ ...rest
139
+ }) => {
140
+ const [isOpen, setIsOpen] = React.useState(false);
141
+ const [activeIndex, setActiveIndex] = React.useState(null);
142
+ const listRef = React.useRef([]);
143
+ const labelsRef = React.useRef([]);
144
+ const { refs, floatingStyles, context, elements, update } = react.useFloating({
145
+ placement: tooltip.standardisePlacement(
146
+ // check for left is added for backwards compatibility
147
+ rest.position === "left" ? "bottom-end" : placement
148
+ ),
149
+ open: isOpen,
150
+ onOpenChange: setIsOpen,
151
+ middleware: [
152
+ react.offset(tokens.space.extraSmall2),
153
+ react.flip(),
154
+ react.shift({ padding: tokens.space.extraSmall })
155
+ ]
156
+ });
157
+ React.useEffect(() => {
158
+ if (isOpen && elements.reference && elements.floating) {
159
+ const cleanup = react.autoUpdate(elements.reference, elements.floating, update);
160
+ return cleanup;
161
+ }
162
+ }, [isOpen, elements, update]);
163
+ const listNav = react.useListNavigation(context, {
164
+ listRef,
165
+ activeIndex,
166
+ onNavigate: setActiveIndex
167
+ });
168
+ const typeahead = react.useTypeahead(context, {
169
+ listRef: labelsRef,
170
+ activeIndex,
171
+ onMatch: (index) => isOpen && setActiveIndex(index)
172
+ });
173
+ const role = react.useRole(context, { role: "menu" });
174
+ const { getReferenceProps, getFloatingProps, getItemProps } = react.useInteractions(
175
+ [listNav, typeahead, role]
176
+ );
177
+ const closeMenuAndReturnFocus = () => {
178
+ setIsOpen(false);
179
+ refs.reference.current?.focus?.();
180
+ };
181
+ utils.useOnClickOutside([refs.floating, refs.reference], () => setIsOpen(false));
182
+ utils.useOnEscape(refs.floating, closeMenuAndReturnFocus);
183
+ utils.useOnEscape(refs.reference, closeMenuAndReturnFocus);
184
+ const selectContext = React.useMemo(
185
+ () => ({
186
+ activeIndex,
187
+ getItemProps,
188
+ closeMenuAndReturnFocus
189
+ }),
190
+ [activeIndex, getItemProps, closeMenuAndReturnFocus]
191
+ );
192
+ const _buttonIcon = buttonIcon ?? /* @__PURE__ */ jsxRuntime.jsx(icons.VerticalDotsIcon, {});
193
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
194
+ !button$1 ? /* @__PURE__ */ jsxRuntime.jsx(
195
+ button.IconButton,
196
+ {
197
+ ref: refs.setReference,
198
+ ...getReferenceProps({
199
+ onClick: () => setIsOpen(!isOpen),
200
+ className,
201
+ "aria-label": ariaLabel,
202
+ type: "button"
203
+ }),
204
+ ...rest,
205
+ children: _buttonIcon
206
+ }
207
+ ) : React.cloneElement(button$1, {
208
+ ref: refs.setReference,
209
+ ...getReferenceProps({
210
+ onClick: () => setIsOpen(!isOpen),
211
+ className,
212
+ "aria-label": ariaLabel,
213
+ type: "button"
214
+ }),
215
+ ...rest
216
+ }),
217
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContext.Provider, { value: selectContext, children: /* @__PURE__ */ jsxRuntime.jsx(
218
+ "div",
219
+ {
220
+ ref: refs.setFloating,
221
+ style: { ...floatingStyles, display: isOpen ? "initial" : "none" },
222
+ ...getFloatingProps({
223
+ className: "eds-overflow-menu__menu-list"
224
+ }),
225
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.FloatingList, { elementsRef: listRef, labelsRef, children })
226
+ }
227
+ ) })
228
+ ] });
229
+ };
230
+ const OverflowMenuItem = ({
231
+ children,
232
+ className,
233
+ onSelect = () => void 0,
234
+ href,
235
+ disabled,
236
+ as,
237
+ ...rest
238
+ }) => {
239
+ const { activeIndex, getItemProps, closeMenuAndReturnFocus } = React.useContext(SelectContext);
240
+ const { ref: listItemRef, index } = react.useListItem({
241
+ label: !disabled ? utils.getNodeText(children) : null
242
+ });
243
+ const isHighlighted = activeIndex === index;
244
+ const isLink = href !== void 0;
245
+ const Element = as ?? (isLink ? "a" : "button");
246
+ return /* @__PURE__ */ jsxRuntime.jsx(
247
+ Element,
248
+ {
249
+ ref: listItemRef,
250
+ className: classNames(
251
+ "eds-overflow-menu__item",
252
+ {
253
+ "eds-overflow-menu__item--disabled": disabled,
254
+ "eds-overflow-menu__item--highlighted": isHighlighted
255
+ },
256
+ className
257
+ ),
258
+ role: "menuitem",
259
+ type: Element === "button" ? "button" : void 0,
260
+ "aria-disabled": disabled,
261
+ "aria-selected": isHighlighted,
262
+ ...getItemProps({
263
+ onClick: isLink || disabled ? void 0 : () => {
264
+ onSelect();
265
+ closeMenuAndReturnFocus();
266
+ },
267
+ href: disabled ? void 0 : href,
268
+ tabIndex: isHighlighted ? 0 : -1
269
+ }),
270
+ ...rest,
271
+ children
272
+ }
273
+ );
274
+ };
275
+ const OverflowMenuLink = (props) => {
276
+ return /* @__PURE__ */ jsxRuntime.jsx(OverflowMenuItem, { ...props });
277
+ };
278
+ const PaginationPage = ({
279
+ children,
280
+ className,
281
+ selected,
282
+ disabled,
283
+ onClick,
284
+ "aria-label": ariaLabel,
285
+ "aria-describedby": ariaDescribedby
286
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
287
+ "button",
288
+ {
289
+ className: classNames(
290
+ "eds-pagination__controls__page",
291
+ { "eds-pagination__controls__page--selected": selected },
292
+ { "eds-pagination__controls__page--disabled": disabled },
293
+ className
294
+ ),
295
+ disabled: selected || disabled,
296
+ type: "button",
297
+ onClick,
298
+ "aria-label": ariaLabel,
299
+ "aria-describedby": ariaDescribedby,
300
+ "aria-current": selected ? "page" : false,
301
+ children
302
+ }
303
+ );
304
+ const PaginationInput = ({
305
+ currentPage,
306
+ pageCount,
307
+ label = "Gå til side",
308
+ onPageChange
309
+ }) => {
310
+ const [input, setInput] = React.useState(String(currentPage));
311
+ React.useEffect(() => {
312
+ setInput(String(currentPage));
313
+ }, [currentPage]);
314
+ const handleSubmit = (e) => {
315
+ e.preventDefault();
316
+ e.stopPropagation();
317
+ let pageNumber = Number(input);
318
+ if (pageNumber === currentPage) {
319
+ return;
320
+ }
321
+ if (Number.isNaN(pageNumber)) {
322
+ pageNumber = currentPage;
323
+ setInput(String(currentPage));
324
+ return;
325
+ }
326
+ if (pageNumber > pageCount) {
327
+ pageNumber = pageCount;
328
+ setInput(String(pageCount));
329
+ } else if (pageNumber < 1) {
330
+ pageNumber = 1;
331
+ setInput(String(1));
332
+ }
333
+ onPageChange(pageNumber);
334
+ };
335
+ const handleChange = (e) => {
336
+ setInput(e.target.value);
337
+ };
338
+ return /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit: handleSubmit, noValidate: true, "aria-label": "form", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "eds-pagination__controls__input__wrapper", children: [
339
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "eds-pagination__controls__input__label", children: label }),
340
+ /* @__PURE__ */ jsxRuntime.jsx(
341
+ "input",
342
+ {
343
+ type: "number",
344
+ max: pageCount,
345
+ className: "eds-pagination__controls__input__field",
346
+ value: input,
347
+ onChange: handleChange
348
+ }
349
+ )
350
+ ] }) });
351
+ };
352
+ const Pagination = ({
353
+ className,
354
+ currentPage,
355
+ inputLabel,
356
+ onPageChange,
357
+ pageCount,
358
+ pageLabel = (pageNumber) => `Gå til side ${pageNumber}`,
359
+ previousPageLabel = "Gå til forrige side",
360
+ currentPageLabelForScreenreader = "Nåværende side:",
361
+ lastPageLabelForScreenreader = ", siste side",
362
+ showInput,
363
+ numberOfResults,
364
+ resultsPerPage,
365
+ resultsPerPageOptions = [10, 25, 50],
366
+ onResultsPerPageChange,
367
+ showNumberOfResultsLabel = "Vis",
368
+ nextPageLabel = "Gå til neste side",
369
+ showingResultsLabel = (minPage, maxPage, pageCount2) => `Viser resultat ${minPage}–${maxPage} av ${pageCount2}`,
370
+ changeNumberOfResultsLabelForScreenreader = `Viser ${resultsPerPage} resultater. Trykk for å endre antall. Åpner en flervalgsmeny.`,
371
+ hideNextButton = false,
372
+ hidePrevButton = false,
373
+ ...rest
374
+ }) => {
375
+ const [listedEntries, setListedEntries] = React.useState([]);
376
+ const paginationId = utils.useRandomId("eds-pagination");
377
+ const isFirstPostSelected = currentPage === 1;
378
+ const isLastPostSelected = currentPage === pageCount;
379
+ const noEllipsis = pageCount <= 7;
380
+ const onlyLeadingEllipsis = !noEllipsis && currentPage < 5;
381
+ const onlyTrailingEllipsis = !noEllipsis && pageCount - currentPage <= 3;
382
+ React.useEffect(() => {
383
+ if (pageCount < 1) return;
384
+ if (noEllipsis) {
385
+ setListedEntries(
386
+ Array(pageCount).fill(null).map((_, i) => i + 1)
387
+ );
388
+ } else if (onlyLeadingEllipsis) {
389
+ setListedEntries([1, 2, 3, 4, 5, "…", pageCount]);
390
+ } else if (onlyTrailingEllipsis) {
391
+ setListedEntries([
392
+ 1,
393
+ "…",
394
+ pageCount - 4,
395
+ pageCount - 3,
396
+ pageCount - 2,
397
+ pageCount - 1,
398
+ pageCount
399
+ ]);
400
+ } else {
401
+ setListedEntries([
402
+ 1,
403
+ "…",
404
+ currentPage - 1,
405
+ currentPage,
406
+ currentPage + 1,
407
+ "…",
408
+ pageCount
409
+ ]);
410
+ }
411
+ }, [
412
+ noEllipsis,
413
+ onlyLeadingEllipsis,
414
+ onlyTrailingEllipsis,
415
+ currentPage,
416
+ pageCount
417
+ ]);
418
+ if (pageCount < 1) {
419
+ return null;
420
+ }
421
+ return /* @__PURE__ */ jsxRuntime.jsxs(
422
+ "nav",
423
+ {
424
+ className: classNames("eds-pagination", className),
425
+ "aria-label": "Paginering",
426
+ ...rest,
427
+ children: [
428
+ resultsPerPage && numberOfResults && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "eds-pagination__results", children: [
429
+ onResultsPerPageChange && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
430
+ /* @__PURE__ */ jsxRuntime.jsx(typography.Label, { as: "p", "aria-hidden": "true", children: showNumberOfResultsLabel }),
431
+ /* @__PURE__ */ jsxRuntime.jsx(
432
+ OverflowMenu,
433
+ {
434
+ className: "eds-pagination__results__change-number-of-results",
435
+ buttonIcon: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
436
+ resultsPerPage,
437
+ " ",
438
+ /* @__PURE__ */ jsxRuntime.jsx(
439
+ icons.DownArrowIcon,
440
+ {
441
+ className: "eds-pagination__results__change-number-of-results__arrow",
442
+ "aria-hidden": "true"
443
+ }
444
+ )
445
+ ] }),
446
+ "aria-label": changeNumberOfResultsLabelForScreenreader,
447
+ placement: "bottom-end",
448
+ children: resultsPerPageOptions.map((option, key) => /* @__PURE__ */ jsxRuntime.jsx(
449
+ OverflowMenuItem,
450
+ {
451
+ onSelect: () => onResultsPerPageChange(option),
452
+ children: option
453
+ },
454
+ key
455
+ ))
456
+ }
457
+ )
458
+ ] }),
459
+ /* @__PURE__ */ jsxRuntime.jsx(typography.Label, { as: "p", children: showingResultsLabel(
460
+ (currentPage - 1) * resultsPerPage + 1,
461
+ currentPage * resultsPerPage > numberOfResults ? numberOfResults : currentPage * resultsPerPage,
462
+ numberOfResults
463
+ ) })
464
+ ] }),
465
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "eds-pagination__controls", children: [
466
+ !hidePrevButton && /* @__PURE__ */ jsxRuntime.jsx(
467
+ PaginationPage,
468
+ {
469
+ onClick: () => onPageChange(currentPage - 1),
470
+ "aria-label": previousPageLabel,
471
+ "aria-describedby": paginationId,
472
+ disabled: isFirstPostSelected,
473
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.LeftArrowIcon, { "aria-hidden": "true" })
474
+ }
475
+ ),
476
+ listedEntries.map(
477
+ (entry, index) => entry === "…" ? /* @__PURE__ */ jsxRuntime.jsx(Ellipsis, {}, `ellipsis-${index}`) : /* @__PURE__ */ jsxRuntime.jsx(
478
+ PaginationPage,
479
+ {
480
+ selected: entry === currentPage,
481
+ onClick: () => onPageChange(entry),
482
+ "aria-label": `${pageLabel(entry)}${entry === pageCount ? lastPageLabelForScreenreader : ""}`,
483
+ "aria-describedby": entry !== currentPage ? paginationId : void 0,
484
+ children: entry
485
+ },
486
+ entry
487
+ )
488
+ ),
489
+ !hideNextButton && /* @__PURE__ */ jsxRuntime.jsx(
490
+ PaginationPage,
491
+ {
492
+ onClick: () => onPageChange(currentPage + 1),
493
+ "aria-label": nextPageLabel,
494
+ "aria-describedby": paginationId,
495
+ disabled: isLastPostSelected,
496
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.RightArrowIcon, { "aria-hidden": "true" })
497
+ }
498
+ ),
499
+ showInput && /* @__PURE__ */ jsxRuntime.jsx(
500
+ PaginationInput,
501
+ {
502
+ pageCount,
503
+ currentPage,
504
+ onPageChange,
505
+ label: inputLabel
506
+ }
507
+ )
508
+ ] }),
509
+ /* @__PURE__ */ jsxRuntime.jsxs(a11y.VisuallyHidden, { id: paginationId, children: [
510
+ currentPageLabelForScreenreader,
511
+ " ",
512
+ currentPage
513
+ ] })
514
+ ]
515
+ }
516
+ );
517
+ };
518
+ const Ellipsis = () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "eds-pagination__controls__page__ellipsis", "aria-hidden": "true", children: "…" });
519
+ const SideNavigation = ({
520
+ className,
521
+ children,
522
+ size = "medium",
523
+ ...rest
524
+ }) => {
525
+ if (!children || !React.Children.count(children)) {
526
+ return null;
527
+ }
528
+ return /* @__PURE__ */ jsxRuntime.jsx(
529
+ "ul",
530
+ {
531
+ className: classNames(
532
+ "eds-side-navigation",
533
+ { "eds-side-navigation--small": size === "small" },
534
+ className
535
+ ),
536
+ ...rest,
537
+ children
538
+ }
539
+ );
540
+ };
541
+ SideNavigation.__IS_ENTUR_MENU__ = true;
542
+ const useShowDelayedLabel = (isCollapsed) => {
543
+ const [showLabel, setShowLabel] = React.useState(true);
544
+ const hideDelay = 50;
545
+ const showDelay = 200;
546
+ React.useEffect(() => {
547
+ if (isCollapsed) {
548
+ setTimeout(() => {
549
+ setShowLabel(false);
550
+ }, hideDelay);
551
+ }
552
+ if (!isCollapsed) {
553
+ setTimeout(() => {
554
+ setShowLabel(true);
555
+ }, showDelay);
556
+ }
557
+ return () => void 0;
558
+ }, [isCollapsed]);
559
+ return [showLabel];
560
+ };
561
+ function isActiveRecursively(child) {
562
+ if (!child.props) {
563
+ return false;
564
+ }
565
+ if (child.props.active) {
566
+ return true;
567
+ }
568
+ if (!child.props.children) {
569
+ return false;
570
+ }
571
+ return React.Children.toArray(child.props.children).some(
572
+ (child2) => isActiveRecursively(child2)
573
+ );
574
+ }
575
+ const defaultElementBaseItem = "a";
576
+ const BaseSideNavigationItem = React.forwardRef(
577
+ ({
578
+ className,
579
+ active = false,
580
+ subMenu,
581
+ icon,
582
+ children,
583
+ as,
584
+ ...rest
585
+ }, ref) => {
586
+ const Element = as || defaultElementBaseItem;
587
+ const { isCollapsed } = useSideNavigationContext();
588
+ const [showLabel] = useShowDelayedLabel(isCollapsed);
589
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: classNames("eds-side-navigation__item", className), children: [
590
+ /* @__PURE__ */ jsxRuntime.jsxs(
591
+ Element,
592
+ {
593
+ className: classNames("eds-side-navigation__click-target", {
594
+ "eds-side-navigation__click-target--active": active
595
+ }),
596
+ "aria-label": isCollapsed ? children : void 0,
597
+ "aria-current": active ? "page" : void 0,
598
+ ref,
599
+ ...rest,
600
+ children: [
601
+ icon,
602
+ showLabel && children
603
+ ]
604
+ }
605
+ ),
606
+ subMenu
607
+ ] });
608
+ }
609
+ );
610
+ const DisabledSideNavigationItem = React.forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
611
+ BaseSideNavigationItem,
612
+ {
613
+ as: "button",
614
+ disabled: true,
615
+ "aria-disabled": true,
616
+ ref,
617
+ type: "button",
618
+ ...rest,
619
+ children
620
+ }
621
+ ));
622
+ const defaultElementItem = "a";
623
+ const SideNavigationItem = React.forwardRef(
624
+ ({
625
+ active,
626
+ disabled,
627
+ children,
628
+ forceExpandSubMenus,
629
+ as,
630
+ ...rest
631
+ }, ref) => {
632
+ const Element = as || defaultElementItem;
633
+ const childrenArray = React.Children.toArray(children);
634
+ const subMenu = childrenArray.find(
635
+ (child) => child && child.type && child.type.__IS_ENTUR_MENU__
636
+ );
637
+ const label = subMenu ? childrenArray.filter((child) => child !== subMenu) : children;
638
+ if (disabled) {
639
+ return /* @__PURE__ */ jsxRuntime.jsx(DisabledSideNavigationItem, { ref, ...rest, children: label });
640
+ }
641
+ if (!subMenu) {
642
+ return /* @__PURE__ */ jsxRuntime.jsx(
643
+ BaseSideNavigationItem,
644
+ {
645
+ as: Element,
646
+ active,
647
+ ref,
648
+ ...rest,
649
+ children: label
650
+ }
651
+ );
652
+ }
653
+ const isExpanded = forceExpandSubMenus || isActiveRecursively({ props: { children, active } });
654
+ return /* @__PURE__ */ jsxRuntime.jsx(
655
+ BaseSideNavigationItem,
656
+ {
657
+ active,
658
+ subMenu: isExpanded && subMenu,
659
+ "aria-expanded": isExpanded,
660
+ as: Element,
661
+ ref,
662
+ ...rest,
663
+ children: label
664
+ }
665
+ );
666
+ }
667
+ );
668
+ const SideNavigationGroup = ({
669
+ defaultOpen = false,
670
+ open,
671
+ onToggle,
672
+ className,
673
+ children,
674
+ title,
675
+ icon,
676
+ ...rest
677
+ }) => {
678
+ const [isOpen, setOpen] = useControllableProp({
679
+ prop: open,
680
+ updater: onToggle,
681
+ defaultValue: defaultOpen
682
+ });
683
+ const { isCollapsed } = useSideNavigationContext();
684
+ const [showLabel] = useShowDelayedLabel(isCollapsed);
685
+ return /* @__PURE__ */ jsxRuntime.jsxs(
686
+ "div",
687
+ {
688
+ className: classNames("eds-side-navigation-group", className),
689
+ ...rest,
690
+ children: [
691
+ /* @__PURE__ */ jsxRuntime.jsxs(
692
+ "button",
693
+ {
694
+ onClick: () => setOpen(!isOpen),
695
+ type: "button",
696
+ className: "eds-side-navigation-group__trigger",
697
+ "aria-label": `${title}, utvidbar meny, ${isOpen ? "åpen" : "lukket"}`,
698
+ children: [
699
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
700
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "eds-side-navigation-group__trigger-icon", children: icon }),
701
+ showLabel && title
702
+ ] }),
703
+ showLabel && /* @__PURE__ */ jsxRuntime.jsx(
704
+ expand.ExpandArrow,
705
+ {
706
+ open: isOpen,
707
+ className: "eds-side-navigation-group__expand-icon"
708
+ }
709
+ )
710
+ ]
711
+ }
712
+ ),
713
+ /* @__PURE__ */ jsxRuntime.jsx(
714
+ expand.BaseExpand,
715
+ {
716
+ className: "eds-side-navigation-group__expand-content",
717
+ open: isOpen,
718
+ children
719
+ }
720
+ )
721
+ ]
722
+ }
723
+ );
724
+ };
725
+ const Stepper = ({
726
+ activeIndex,
727
+ className,
728
+ interactive = false,
729
+ onStepClick,
730
+ showStepperIndex = true,
731
+ steps,
732
+ ariaLabelStep = "Steg",
733
+ ariaLabelOf = "av",
734
+ ariaLabelCompleted = "fullført",
735
+ ariaLabelSummary = `Stegindikator med ${steps.length} steg, du er på steg ${activeIndex + 1} ${steps[activeIndex]},`,
736
+ ...rest
737
+ }) => {
738
+ return /* @__PURE__ */ jsxRuntime.jsx(
739
+ "ol",
740
+ {
741
+ className: classNames("eds-stepper", className),
742
+ "aria-label": ariaLabelSummary,
743
+ ...rest,
744
+ children: steps.map((step, i) => {
745
+ const isCurrent = i === activeIndex;
746
+ const isInteractive = interactive && activeIndex > i;
747
+ const Element = isInteractive ? "button" : "div";
748
+ const isCompleted = activeIndex > i;
749
+ const currentStepSummary = `${ariaLabelStep} ${i + 1} ${ariaLabelOf} ${steps.length}, ${step} ${isCompleted ? `, ${ariaLabelCompleted}` : ""}`;
750
+ const props = isInteractive ? { onClick: () => onStepClick?.(i) } : {};
751
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { className: "eds-stepper__step__wrapper", children: /* @__PURE__ */ jsxRuntime.jsxs(
752
+ Element,
753
+ {
754
+ className: classNames(
755
+ "eds-stepper__step",
756
+ { "eds-stepper__step--active": isCurrent },
757
+ { "eds-stepper__step--completed": isCompleted },
758
+ { "eds-stepper__step--interactive": isInteractive }
759
+ ),
760
+ "aria-current": isCurrent ? "step" : void 0,
761
+ type: Element === "button" ? "button" : void 0,
762
+ ...props,
763
+ children: [
764
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "eds-stepper__step__line", "aria-hidden": true }),
765
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "eds-stepper__step__label", "aria-hidden": true, children: [
766
+ showStepperIndex && i + 1 + ".",
767
+ " ",
768
+ step
769
+ ] }),
770
+ /* @__PURE__ */ jsxRuntime.jsx(a11y.VisuallyHidden, { children: currentStepSummary })
771
+ ]
772
+ }
773
+ ) }, step);
774
+ })
775
+ }
776
+ );
777
+ };
778
+ const defaultElement = "a";
779
+ const TopNavigationItem = ({
780
+ active = false,
781
+ className,
782
+ as,
783
+ ...rest
784
+ }) => {
785
+ const Element = as || defaultElement;
786
+ return /* @__PURE__ */ jsxRuntime.jsx(
787
+ Element,
788
+ {
789
+ className: classNames([
790
+ "eds-top-navigation-item",
791
+ className,
792
+ { "eds-top-navigation-item--active": active }
793
+ ]),
794
+ ...rest
795
+ }
796
+ );
797
+ };
798
+ utils.warnAboutMissingStyles(
799
+ "menu",
800
+ "expand",
801
+ "icons",
802
+ "typography",
803
+ "button",
804
+ "layout",
805
+ "a11y"
806
+ );
807
+ exports.BreadcrumbItem = BreadcrumbItem;
808
+ exports.BreadcrumbNavigation = BreadcrumbNavigation;
809
+ exports.CollapsibleSideNavigation = CollapsibleSideNavigation;
810
+ exports.OverflowMenu = OverflowMenu;
811
+ exports.OverflowMenuItem = OverflowMenuItem;
812
+ exports.OverflowMenuLink = OverflowMenuLink;
813
+ exports.Pagination = Pagination;
814
+ exports.SideNavigation = SideNavigation;
815
+ exports.SideNavigationGroup = SideNavigationGroup;
816
+ exports.SideNavigationItem = SideNavigationItem;
817
+ exports.Stepper = Stepper;
818
+ exports.TopNavigationItem = TopNavigationItem;
819
+ exports.useSideNavigationContext = useSideNavigationContext;
820
+ //# sourceMappingURL=menu.cjs.js.map