@helsenorge/designsystem-react 14.5.1 → 14.7.0

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.
Files changed (73) hide show
  1. package/lib/CHANGELOG.md +24 -0
  2. package/lib/Drawer.js +37 -14
  3. package/lib/Drawer.js.map +1 -1
  4. package/lib/Select.js +3 -2
  5. package/lib/Select.js.map +1 -1
  6. package/lib/Title.js +2 -1
  7. package/lib/Title.js.map +1 -1
  8. package/lib/components/Drawer/Drawer.d.ts +6 -0
  9. package/lib/components/Drawer/styles.module.scss +19 -0
  10. package/lib/components/Drawer/styles.module.scss.d.ts +1 -0
  11. package/lib/components/Dropdown/styles.module.scss +4 -4
  12. package/lib/components/Filter/DrawerNavigation/DrawerNavigation.d.ts +35 -0
  13. package/lib/components/Filter/DrawerNavigation/FinnFastlegeFlyt.example.d.ts +2 -0
  14. package/lib/components/Filter/DrawerNavigation/FinnFastlegeFlyt.module.scss +15 -0
  15. package/lib/components/Filter/DrawerNavigation/FinnFastlegeFlyt.module.scss.d.ts +11 -0
  16. package/lib/components/Filter/DrawerNavigation/index.d.ts +4 -0
  17. package/lib/components/Filter/DrawerNavigation/index.js +81 -0
  18. package/lib/components/Filter/DrawerNavigation/index.js.map +1 -0
  19. package/lib/components/Filter/DrawerNavigation/useDrawerNavigation.d.ts +7 -0
  20. package/lib/components/Filter/FilterButton/FilterButton.d.ts +7 -0
  21. package/lib/components/Filter/FilterButton/styles.module.scss +52 -0
  22. package/lib/components/Filter/FilterButton/styles.module.scss.d.ts +12 -0
  23. package/lib/components/Filter/FilterButtonAndChipsWrapper/FilterButtonAndChipsWrapper.d.ts +11 -0
  24. package/lib/components/Filter/FilterButtonAndChipsWrapper/styles.module.scss +8 -0
  25. package/lib/components/Filter/FilterButtonAndChipsWrapper/styles.module.scss.d.ts +9 -0
  26. package/lib/components/Filter/FilterDrawer/FilterDrawer.d.ts +42 -0
  27. package/lib/components/Filter/FilterDrawer/styles.module.scss +29 -0
  28. package/lib/components/Filter/FilterDrawer/styles.module.scss.d.ts +10 -0
  29. package/lib/components/Filter/FilterLinkList/FilterLinkList.d.ts +35 -0
  30. package/lib/components/Filter/FilterLinkList/FilterLinkList.module.scss +89 -0
  31. package/lib/components/Filter/FilterLinkList/FilterLinkList.module.scss.d.ts +14 -0
  32. package/lib/components/Filter/FilterOverviewLinkList/FilterOverviewLinkList.d.ts +19 -0
  33. package/lib/components/Filter/FilterOverviewSearch/FilterOverviewSearch.d.ts +9 -0
  34. package/lib/components/Filter/FilterOverviewSearch/styles.module.scss +14 -0
  35. package/lib/components/Filter/FilterOverviewSearch/styles.module.scss.d.ts +9 -0
  36. package/lib/components/Filter/FilterResultCountAndSortWrapper/FilterResultCountAndSortWrapper.d.ts +8 -0
  37. package/lib/components/Filter/FilterResultCountAndSortWrapper/styles.module.scss +17 -0
  38. package/lib/components/Filter/FilterResultCountAndSortWrapper/styles.module.scss.d.ts +11 -0
  39. package/lib/components/Filter/FilterSearch/FilterSearch.d.ts +19 -0
  40. package/lib/components/Filter/FilterSearch/styles.module.scss +181 -0
  41. package/lib/components/Filter/FilterSearch/styles.module.scss.d.ts +16 -0
  42. package/lib/components/Filter/FilterSort/FilterSort.d.ts +8 -0
  43. package/lib/components/Filter/FilterSort/styles.module.scss +29 -0
  44. package/lib/components/Filter/FilterSort/styles.module.scss.d.ts +11 -0
  45. package/lib/components/Filter/getFilterChips/getFilterChips.d.ts +17 -0
  46. package/lib/components/Filter/index.d.ts +2 -0
  47. package/lib/components/Filter/index.js +109 -0
  48. package/lib/components/Filter/index.js.map +1 -0
  49. package/lib/components/Filter/resourceHelper.d.ts +3 -0
  50. package/lib/components/Filter/resourcesMock.d.ts +41 -0
  51. package/lib/components/Filter/useFilter.d.ts +20 -0
  52. package/lib/components/Filter/useFilterDrawer.d.ts +11 -0
  53. package/lib/components/Filter/utils.d.ts +81 -0
  54. package/lib/components/Highlighter/styles.module.scss +1 -1
  55. package/lib/components/Icons/HTMLFile.js +3 -11
  56. package/lib/components/Icons/HTMLFile.js.map +1 -1
  57. package/lib/components/Label/utils.d.ts +1 -0
  58. package/lib/components/NotificationPanel/NotificationPanel.d.ts +1 -1
  59. package/lib/components/NotificationPanel/index.js +1 -1
  60. package/lib/components/NotificationPanel/index.js.map +1 -1
  61. package/lib/components/Select/Select.d.ts +2 -0
  62. package/lib/components/Select/styles.module.scss +1 -0
  63. package/lib/components/Title/Title.d.ts +2 -0
  64. package/lib/index.d.ts +1 -0
  65. package/lib/index.js +2 -1
  66. package/lib/resource.js +4 -0
  67. package/lib/resource.js.map +1 -0
  68. package/lib/resources/HN.Designsystem.Drawer.nn-NO.json.d.ts +7 -0
  69. package/lib/utils/resource.d.ts +6 -0
  70. package/lib/utils/resource.js +2 -0
  71. package/lib/utils2.js +4 -2
  72. package/lib/utils2.js.map +1 -1
  73. package/package.json +1 -1
package/lib/CHANGELOG.md CHANGED
@@ -1,4 +1,28 @@
1
1
 
2
+ ## [14.7.0](https://github.com/helsenorge/designsystem/compare/v14.6.0...v14.7.0) (2026-05-04)
3
+
4
+ ### Features
5
+
6
+ * **filter:** nytt filter ([ab9bf11](https://github.com/helsenorge/designsystem/commit/ab9bf11a0842201c19a26f776cd38a4bc214f9bb)), closes [#372994](https://github.com/helsenorge/designsystem/issues/372994) [#372995](https://github.com/helsenorge/designsystem/issues/372995) [#374423](https://github.com/helsenorge/designsystem/issues/374423) [#375591](https://github.com/helsenorge/designsystem/issues/375591)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **dateandtime:** wrapper med liten skjermbredde ([96e0c0a](https://github.com/helsenorge/designsystem/commit/96e0c0a56478fa1a4d7e41b8a6d7e5433fb05957)), closes [#377123](https://github.com/helsenorge/designsystem/issues/377123)
11
+
12
+ ## [14.6.0](https://github.com/helsenorge/designsystem/compare/v14.5.1...v14.6.0) (2026-04-30)
13
+
14
+ ### Features
15
+
16
+ * **highlighter:** legg til semibold ([5df732d](https://github.com/helsenorge/designsystem/commit/5df732d9d931794a8413682b10b00852bcd806e4)), closes [#376890](https://github.com/helsenorge/designsystem/issues/376890)
17
+ * **icon:** nytt ikon for html file ([50ceb7c](https://github.com/helsenorge/designsystem/commit/50ceb7cb48247ed38ad73bd702f7a768f7eb5d5a)), closes [#376670](https://github.com/helsenorge/designsystem/issues/376670)
18
+ * **lightbox:** legg på dropshadow på knapper ved hover og focus ([35e6f97](https://github.com/helsenorge/designsystem/commit/35e6f97dca8c164466f3e17e39ddcf90382b07b6)), closes [#376430](https://github.com/helsenorge/designsystem/issues/376430)
19
+ * **notificationpanel:** legg til mulighet for role none ([ce1d030](https://github.com/helsenorge/designsystem/commit/ce1d0302266b52ec1fe55abae80c51c12a25cd24)), closes [#375231](https://github.com/helsenorge/designsystem/issues/375231)
20
+
21
+ ### Bug Fixes
22
+
23
+ * **datepicker:** legg på bakgrunnsfarge ([6d2857b](https://github.com/helsenorge/designsystem/commit/6d2857b3dad47bb11862a157eae573e92633e714)), closes [#376737](https://github.com/helsenorge/designsystem/issues/376737)
24
+ * **dropdown:** ikke ha hoverstyling på disabled trigger ([0861b10](https://github.com/helsenorge/designsystem/commit/0861b10b3a828062e2ecf7bb923aac14ecc61da0)), closes [#373943](https://github.com/helsenorge/designsystem/issues/373943)
25
+
2
26
  ## [14.5.1](https://github.com/helsenorge/designsystem/compare/v14.5.0...v14.5.1) (2026-04-24)
3
27
 
4
28
  ### Bug Fixes
package/lib/Drawer.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { n as uuid_default } from "./uuid.js";
2
2
  import { c as ZIndex, n as AnalyticsId, o as KeyboardEventKey, s as LanguageLocales } from "./constants2.js";
3
+ import { t as Icon_default } from "./Icon.js";
3
4
  import { n as useLanguage } from "./useLanguage.js";
4
5
  import { t as useIsMobileBreakpoint } from "./useIsMobileBreakpoint.js";
5
6
  import { t as Button_default } from "./Button.js";
@@ -11,6 +12,7 @@ import { t as useOutsideEvent } from "./useOutsideEvent.js";
11
12
  import { t as Close_default } from "./Close.js";
12
13
  import { t as useReturnFocusOnUnmount } from "./useReturnFocusOnUnmount.js";
13
14
  import { n as enableBodyScroll, t as disableBodyScroll } from "./scroll.js";
15
+ import { t as ChevronLeft_default } from "./ChevronLeft.js";
14
16
  import { t as Title_default } from "./Title2.js";
15
17
  import classNames from "classnames";
16
18
  import React, { useEffect, useRef } from "react";
@@ -25,9 +27,14 @@ var HN_Designsystem_Drawer_nb_NO_default = {
25
27
  ariaLabelBackButton: "Gå tilbake",
26
28
  ariaLabelCloseBtn: "Lukk"
27
29
  };
30
+ var HN_Designsystem_Drawer_nn_NO_default = {
31
+ ariaLabelCloseBtn: "Lukk",
32
+ ariaLabelBackButton: "Gå tilbake"
33
+ };
28
34
  const getResources = (language) => {
29
35
  switch (language) {
30
36
  case LanguageLocales.ENGLISH: return HN_Designsystem_Drawer_en_GB_default;
37
+ case LanguageLocales.NORWEGIAN_NYNORSK: return HN_Designsystem_Drawer_nn_NO_default;
31
38
  case LanguageLocales.NORWEGIAN:
32
39
  default: return HN_Designsystem_Drawer_nb_NO_default;
33
40
  }
@@ -41,7 +48,7 @@ var Drawer = (props) => {
41
48
  }) });
42
49
  };
43
50
  var InnerDrawer = (props) => {
44
- const { ariaLabel, ariaLabelledBy, children, closeColor = "blueberry", desktopDirection = "left", footerContent, headerClasses, noCloseButton = false, onPrimaryAction, onRequestClose, onSecondaryAction, primaryActionText, secondaryActionText, title, titleHtmlMarkup = "h3", titleId = uuid_default(), zIndex = ZIndex.OverlayScreen, resources, isMobile } = props;
51
+ const { ariaLabel, ariaLabelledBy, children, closeColor = "blueberry", desktopDirection = "left", footerContent, headerClasses, noCloseButton = false, onPrimaryAction, onRequestClose, onSecondaryAction, primaryActionText, secondaryActionText, title, titleHtmlMarkup = "h3", titleId = uuid_default(), zIndex = ZIndex.OverlayScreen, resources, isMobile, withBackButton, onRequestBack, contentClassName } = props;
45
52
  const ariaLabelAttributes = getAriaLabelAttributes({
46
53
  label: ariaLabel,
47
54
  id: ariaLabelledBy,
@@ -54,6 +61,7 @@ var InnerDrawer = (props) => {
54
61
  const bottomContent = useRef(null);
55
62
  const headerRef = useRef(null);
56
63
  const footerRef = useRef(null);
64
+ const titleRef = useRef(null);
57
65
  const [scope, animate] = useAnimate();
58
66
  const [isPresent, safeToRemove] = usePresence();
59
67
  const [headerHeight, setHeaderHeight] = React.useState(0);
@@ -143,6 +151,9 @@ var InnerDrawer = (props) => {
143
151
  const handleCTA = (callback) => {
144
152
  if (callback) callback();
145
153
  };
154
+ useEffect(() => {
155
+ titleRef.current?.focus();
156
+ }, [title]);
146
157
  return /* @__PURE__ */ jsxs("div", {
147
158
  className: styles.drawer,
148
159
  ref: scope,
@@ -165,18 +176,30 @@ var InnerDrawer = (props) => {
165
176
  /* @__PURE__ */ jsxs("div", {
166
177
  className: headerStyling,
167
178
  ref: headerRef,
168
- children: [/* @__PURE__ */ jsx(Title_default, {
169
- id: ariaLabelAttributes?.["aria-labelledby"],
170
- className: styles["drawer__header__title"],
171
- htmlMarkup: titleHtmlMarkup,
172
- appearance: "title3",
173
- children: title
174
- }), !noCloseButton && onRequestClose != void 0 && /* @__PURE__ */ jsx(Close_default, {
175
- ariaLabel: mergedResources.ariaLabelCloseBtn,
176
- color: closeColor,
177
- onClick: onRequestClose,
178
- className: styles["drawer__header__close-button"]
179
- })]
179
+ children: [
180
+ /* @__PURE__ */ jsx(Title_default, {
181
+ id: ariaLabelAttributes?.["aria-labelledby"],
182
+ className: styles["drawer__header__title"],
183
+ htmlMarkup: titleHtmlMarkup,
184
+ appearance: "title3",
185
+ ref: titleRef,
186
+ tabIndex: -1,
187
+ children: title
188
+ }),
189
+ withBackButton && onRequestBack !== void 0 && /* @__PURE__ */ jsx(Button_default, {
190
+ ariaLabel: mergedResources.ariaLabelBackButton,
191
+ onClick: onRequestBack,
192
+ variant: "borderless",
193
+ wrapperClassName: styles["drawer__header__back-button"],
194
+ children: /* @__PURE__ */ jsx(Icon_default, { svgIcon: ChevronLeft_default })
195
+ }),
196
+ !noCloseButton && onRequestClose != void 0 && /* @__PURE__ */ jsx(Close_default, {
197
+ ariaLabel: mergedResources.ariaLabelCloseBtn,
198
+ color: closeColor,
199
+ onClick: onRequestClose,
200
+ className: styles["drawer__header__close-button"]
201
+ })
202
+ ]
180
203
  }),
181
204
  /* @__PURE__ */ jsx("div", {
182
205
  className: classNames(styles["drawer__content__shadow"], styles["drawer__content__shadow--top"]),
@@ -186,7 +209,7 @@ var InnerDrawer = (props) => {
186
209
  }
187
210
  }),
188
211
  /* @__PURE__ */ jsxs("div", {
189
- className: styles.drawer__content,
212
+ className: classNames(styles.drawer__content, contentClassName),
190
213
  tabIndex: contentIsScrollable ? 0 : void 0,
191
214
  role: contentIsScrollable ? "region" : void 0,
192
215
  ...contentIsScrollable ? ariaLabelAttributes : {},
package/lib/Drawer.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.js","names":["Drawer: React.FC<DrawerProps>","InnerDrawer: React.FC<InnerDrawerProps>","mergedResources: HNDesignsystemDrawer"],"sources":["../src/resources/HN.Designsystem.Drawer.en-GB.json","../src/resources/HN.Designsystem.Drawer.nb-NO.json","../src/components/Drawer/resourceHelper.ts","../src/components/Drawer/Drawer.tsx","../src/components/Drawer/index.ts"],"sourcesContent":["{\n \"ariaLabelBackButton\": \"Go back\",\n \"ariaLabelCloseBtn\": \"Close\"\n}\n","{\n \"ariaLabelBackButton\": \"Gå tilbake\",\n \"ariaLabelCloseBtn\": \"Lukk\"\n}\n","import type { HNDesignsystemDrawer } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Drawer.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Drawer.nb-NO.json';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemDrawer => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React, { useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\nimport { AnimatePresence, useAnimate, usePresence } from 'motion/react';\n\nimport type { HNDesignsystemDrawer } from '../../resources/Resources';\nimport type { TitleTags } from '../Title';\n\nimport { getResources } from './resourceHelper';\nimport { AnalyticsId, KeyboardEventKey, LanguageLocales, ZIndex } from '../../constants';\nimport useFocusTrap from '../../hooks/useFocusTrap';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { useIsVisible } from '../../hooks/useIsVisible';\nimport { useKeyboardEvent } from '../../hooks/useKeyboardEvent';\nimport { useLanguage } from '../../hooks/useLanguage';\nimport { useOutsideEvent } from '../../hooks/useOutsideEvent';\nimport { useReturnFocusOnUnmount } from '../../hooks/useReturnFocusOnUnmount';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport { disableBodyScroll, enableBodyScroll } from '../../utils/scroll';\nimport uuid from '../../utils/uuid';\nimport Button from '../Button';\nimport Close from '../Close';\nimport Title from '../Title';\n\nimport styles from './styles.module.scss';\n\ntype DesktopDirections = 'left' | 'right';\n\nexport interface DrawerProps extends InnerDrawerProps {\n /** Opens and closes the drawer */\n isOpen: boolean;\n}\n\nexport interface InnerDrawerProps {\n /** Sets the aria-label of the drawer */\n ariaLabel?: string;\n /** Sets the aria-labelledby of the drawer */\n ariaLabelledBy?: string;\n /** Sets the style of the Drawer Close button. Meant for use by HelpDrawer */\n closeColor?: 'blueberry' | 'plum';\n /** Direction of the drawer on desktop. Default: left */\n desktopDirection?: DesktopDirections;\n /** Sets the style of the Drawer header */\n headerClasses?: string;\n /** Title to display in the header of the drawer */\n title: string;\n /** id of the drawer title */\n titleId?: string;\n /** Changes the underlying element of the title. Default: h3 */\n titleHtmlMarkup?: TitleTags;\n /** Callback that triggers when clicking on close button or outside the drawer, update isOpen state when this triggers */\n onRequestClose?: () => void;\n /** Optional footer content that can be rendered instead of default CTA(s) */\n footerContent?: React.ReactNode;\n /** Main content of the drawer */\n children?: React.ReactNode;\n /** Hides the close button */\n noCloseButton?: boolean;\n /** Primary CTA callback */\n onPrimaryAction?: () => void;\n /** Text for primary CTA button if you want a default CTA button rendered (instead of `footerContent`) */\n primaryActionText?: string;\n /** Text for secondary CTA button if you want a default CTA button rendered (instead of `footerContent`) */\n secondaryActionText?: string;\n /** Secondary CTA callback */\n onSecondaryAction?: () => void;\n /** Customize the z-index of the drawer */\n zIndex?: number;\n /** Resources for component */\n resources?: Partial<HNDesignsystemDrawer>;\n /** Sets mobile styling and animation from outer level Drawer */\n isMobile?: boolean;\n}\n\nconst Drawer: React.FC<DrawerProps> = props => {\n const { isOpen, ...rest } = props;\n const isMobile = useIsMobileBreakpoint();\n\n return <AnimatePresence>{isOpen && <InnerDrawer {...rest} isMobile={isMobile} />}</AnimatePresence>;\n};\n\nconst InnerDrawer: React.FC<InnerDrawerProps> = props => {\n const {\n ariaLabel,\n ariaLabelledBy,\n children,\n closeColor = 'blueberry',\n desktopDirection = 'left',\n footerContent,\n headerClasses,\n noCloseButton = false,\n onPrimaryAction,\n onRequestClose,\n onSecondaryAction,\n primaryActionText,\n secondaryActionText,\n title,\n titleHtmlMarkup = 'h3',\n titleId = uuid(),\n zIndex = ZIndex.OverlayScreen,\n resources,\n isMobile,\n } = props;\n\n const ariaLabelAttributes = getAriaLabelAttributes({ label: ariaLabel, id: ariaLabelledBy, fallbackId: titleId });\n const overlayRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n // topContent and bottomContent are used to detect scroll position for shadow effects\n const topContent = useRef<HTMLDivElement>(null);\n const bottomContent = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null);\n const footerRef = useRef<HTMLDivElement>(null);\n const [scope, animate] = useAnimate();\n const [isPresent, safeToRemove] = usePresence();\n const [headerHeight, setHeaderHeight] = React.useState(0);\n const [footerHeight, setFooterHeight] = React.useState(0);\n const topContentVisible = useIsVisible(topContent);\n const bottomContentVisible = useIsVisible(bottomContent, 0);\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemDrawer = {\n ...defaultResources,\n ...resources,\n };\n\n const contentIsScrollable = contentRef.current && contentRef.current.scrollHeight > contentRef.current.clientHeight;\n const headerStyling = classNames(styles.drawer__header, headerClasses);\n const hasFooterContent = (typeof footerContent !== 'undefined' && footerContent) || onPrimaryAction || onSecondaryAction;\n\n useFocusTrap(containerRef, true);\n useReturnFocusOnUnmount(containerRef);\n useOutsideEvent(containerRef, () => {\n if (onRequestClose) onRequestClose();\n });\n useKeyboardEvent(containerRef, () => onRequestClose && onRequestClose(), [KeyboardEventKey.Escape]);\n\n // Close animasjon, vi kaller `onClose()` til slutt\n const closeDrawer = (): void => {\n if (!overlayRef.current || !containerRef.current) return;\n\n animate(overlayRef.current, { opacity: 0, pointerEvents: 'none' }, { duration: 0.3, ease: 'easeInOut' });\n\n if (isMobile) {\n animate(\n containerRef.current,\n { y: '100%' },\n {\n duration: 0.3,\n ease: 'easeInOut',\n onComplete: () => {\n if (safeToRemove) safeToRemove();\n },\n }\n );\n } else {\n animate(\n containerRef.current,\n { x: desktopDirection === 'left' ? '-100%' : '100%' },\n {\n duration: 0.3,\n ease: 'easeInOut',\n onComplete: () => {\n if (safeToRemove) safeToRemove();\n },\n }\n );\n }\n };\n\n useEffect(() => {\n containerRef.current?.focus();\n disableBodyScroll();\n\n return (): void => {\n enableBodyScroll();\n };\n }, []);\n\n // Measure header and footer heights\n useEffect(() => {\n const updateHeights = (): void => {\n if (headerRef.current) {\n setHeaderHeight(headerRef.current.offsetHeight);\n }\n if (footerRef.current) {\n setFooterHeight(footerRef.current.offsetHeight);\n }\n };\n\n updateHeights();\n\n // Update heights when content changes\n const resizeObserver = new ResizeObserver(updateHeights);\n if (headerRef.current) {\n resizeObserver.observe(headerRef.current);\n }\n if (footerRef.current) {\n resizeObserver.observe(footerRef.current);\n }\n\n return (): void => {\n resizeObserver.disconnect();\n };\n }, [hasFooterContent]);\n\n // Open animation.\n useEffect(() => {\n if (!overlayRef.current || !containerRef.current) return;\n\n if (!isPresent) {\n closeDrawer();\n return;\n }\n\n if (isMobile) {\n animate(containerRef.current, { y: '0' }, { duration: 0.3, ease: 'easeInOut' });\n } else {\n animate(containerRef.current, { x: '0' }, { duration: 0.3, ease: 'easeInOut' });\n }\n\n animate(overlayRef.current, { opacity: 1, pointerEvents: 'auto' }, { duration: 0.3, ease: 'easeInOut' });\n }, [isPresent]);\n\n const handleCTA = (callback?: () => void): void => {\n if (callback) {\n callback();\n }\n };\n\n return (\n <div className={styles.drawer} ref={scope} style={{ zIndex }} data-analyticsid={AnalyticsId.Drawer}>\n <div className={styles.drawer__overlay} ref={overlayRef} aria-hidden=\"true\" />\n <div\n className={classNames(styles.drawer__container, {\n [styles['drawer__container--right']]: desktopDirection === 'right',\n })}\n ref={containerRef}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n {...ariaLabelAttributes}\n >\n <div className={styles.drawer__container__inner}>\n <div className={headerStyling} ref={headerRef}>\n <Title\n id={ariaLabelAttributes?.['aria-labelledby']}\n className={styles['drawer__header__title']}\n htmlMarkup={titleHtmlMarkup}\n appearance=\"title3\"\n >\n {title}\n </Title>\n {!noCloseButton && onRequestClose != undefined && (\n <Close\n ariaLabel={mergedResources.ariaLabelCloseBtn}\n color={closeColor}\n onClick={onRequestClose}\n className={styles['drawer__header__close-button']}\n />\n )}\n </div>\n <div\n className={classNames(styles['drawer__content__shadow'], styles['drawer__content__shadow--top'])}\n style={{\n opacity: !topContentVisible && contentIsScrollable ? 1 : 0,\n top: headerHeight,\n }}\n />\n <div\n className={styles.drawer__content}\n tabIndex={contentIsScrollable ? 0 : undefined}\n role={contentIsScrollable ? 'region' : undefined}\n {...(contentIsScrollable ? ariaLabelAttributes : {})}\n ref={contentRef}\n >\n <div ref={topContent} />\n <div className={styles['drawer__content__children']}>{children}</div>\n <div ref={bottomContent} style={{ height: '1px' }} />\n </div>\n <div\n className={classNames(styles['drawer__content__shadow'], styles['drawer__content__shadow--bottom'])}\n style={{\n opacity: !bottomContentVisible && contentIsScrollable ? 1 : 0,\n bottom: hasFooterContent ? footerHeight : 0,\n }}\n />\n </div>\n {hasFooterContent && (\n <div className={styles.drawer__footer} ref={footerRef}>\n {footerContent ? (\n footerContent\n ) : (\n <>\n {onPrimaryAction && <Button onClick={() => handleCTA(onPrimaryAction)}>{primaryActionText}</Button>}\n {onSecondaryAction && (\n <Button variant=\"borderless\" onClick={() => handleCTA(onSecondaryAction)}>\n {secondaryActionText}\n </Button>\n )}\n </>\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default Drawer;\n","import Drawer from './Drawer';\nexport * from './Drawer';\nexport default Drawer;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Drawer.js","names":["Drawer: React.FC<DrawerProps>","InnerDrawer: React.FC<InnerDrawerProps>","mergedResources: HNDesignsystemDrawer"],"sources":["../src/resources/HN.Designsystem.Drawer.en-GB.json","../src/resources/HN.Designsystem.Drawer.nb-NO.json","../src/resources/HN.Designsystem.Drawer.nn-NO.json","../src/components/Drawer/resourceHelper.ts","../src/components/Drawer/Drawer.tsx","../src/components/Drawer/index.ts"],"sourcesContent":["{\n \"ariaLabelBackButton\": \"Go back\",\n \"ariaLabelCloseBtn\": \"Close\"\n}\n","{\n \"ariaLabelBackButton\": \"Gå tilbake\",\n \"ariaLabelCloseBtn\": \"Lukk\"\n}\n","{\n \"ariaLabelCloseBtn\": \"Lukk\",\n \"ariaLabelBackButton\": \"Gå tilbake\"\n}\n","import type { HNDesignsystemDrawer } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Drawer.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Drawer.nb-NO.json';\nimport nnNO from '../../resources/HN.Designsystem.Drawer.nn-NO.json';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemDrawer => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN_NYNORSK:\n return nnNO;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React, { useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\nimport { AnimatePresence, useAnimate, usePresence } from 'motion/react';\n\nimport type { HNDesignsystemDrawer } from '../../resources/Resources';\nimport type { TitleTags } from '../Title';\n\nimport { getResources } from './resourceHelper';\nimport { AnalyticsId, KeyboardEventKey, LanguageLocales, ZIndex } from '../../constants';\nimport useFocusTrap from '../../hooks/useFocusTrap';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { useIsVisible } from '../../hooks/useIsVisible';\nimport { useKeyboardEvent } from '../../hooks/useKeyboardEvent';\nimport { useLanguage } from '../../hooks/useLanguage';\nimport { useOutsideEvent } from '../../hooks/useOutsideEvent';\nimport { useReturnFocusOnUnmount } from '../../hooks/useReturnFocusOnUnmount';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport { disableBodyScroll, enableBodyScroll } from '../../utils/scroll';\nimport uuid from '../../utils/uuid';\nimport Button from '../Button';\nimport Close from '../Close';\nimport Icon from '../Icon';\nimport ChevronLeft from '../Icons/ChevronLeft';\nimport Title from '../Title';\n\nimport styles from './styles.module.scss';\n\ntype DesktopDirections = 'left' | 'right';\n\nexport interface DrawerProps extends InnerDrawerProps {\n /** Opens and closes the drawer */\n isOpen: boolean;\n}\n\nexport interface InnerDrawerProps {\n /** Sets the aria-label of the drawer */\n ariaLabel?: string;\n /** Sets the aria-labelledby of the drawer */\n ariaLabelledBy?: string;\n /** Sets the style of the Drawer Close button. Meant for use by HelpDrawer */\n closeColor?: 'blueberry' | 'plum';\n /** Direction of the drawer on desktop. Default: left */\n desktopDirection?: DesktopDirections;\n /** Sets the style of the Drawer header */\n headerClasses?: string;\n /** Title to display in the header of the drawer */\n title: string;\n /** id of the drawer title */\n titleId?: string;\n /** Changes the underlying element of the title. Default: h3 */\n titleHtmlMarkup?: TitleTags;\n /** Callback that triggers when clicking on close button or outside the drawer, update isOpen state when this triggers */\n onRequestClose?: () => void;\n /** Optional footer content that can be rendered instead of default CTA(s) */\n footerContent?: React.ReactNode;\n /** Main content of the drawer */\n children?: React.ReactNode;\n /** Hides the close button */\n noCloseButton?: boolean;\n /** Primary CTA callback */\n onPrimaryAction?: () => void;\n /** Text for primary CTA button if you want a default CTA button rendered (instead of `footerContent`) */\n primaryActionText?: string;\n /** Text for secondary CTA button if you want a default CTA button rendered (instead of `footerContent`) */\n secondaryActionText?: string;\n /** Secondary CTA callback */\n onSecondaryAction?: () => void;\n /** Customize the z-index of the drawer */\n zIndex?: number;\n /** Resources for component */\n resources?: Partial<HNDesignsystemDrawer>;\n /** Sets mobile styling and animation from outer level Drawer */\n isMobile?: boolean;\n /** Shows a back button to the left of title */\n withBackButton?: boolean;\n /** Callback for the back button */\n onRequestBack?: () => void;\n /** Sets classname for content part in Drawer */\n contentClassName?: string;\n}\n\nconst Drawer: React.FC<DrawerProps> = props => {\n const { isOpen, ...rest } = props;\n const isMobile = useIsMobileBreakpoint();\n\n return <AnimatePresence>{isOpen && <InnerDrawer {...rest} isMobile={isMobile} />}</AnimatePresence>;\n};\n\nconst InnerDrawer: React.FC<InnerDrawerProps> = props => {\n const {\n ariaLabel,\n ariaLabelledBy,\n children,\n closeColor = 'blueberry',\n desktopDirection = 'left',\n footerContent,\n headerClasses,\n noCloseButton = false,\n onPrimaryAction,\n onRequestClose,\n onSecondaryAction,\n primaryActionText,\n secondaryActionText,\n title,\n titleHtmlMarkup = 'h3',\n titleId = uuid(),\n zIndex = ZIndex.OverlayScreen,\n resources,\n isMobile,\n withBackButton,\n onRequestBack,\n contentClassName,\n } = props;\n\n const ariaLabelAttributes = getAriaLabelAttributes({ label: ariaLabel, id: ariaLabelledBy, fallbackId: titleId });\n const overlayRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n // topContent and bottomContent are used to detect scroll position for shadow effects\n const topContent = useRef<HTMLDivElement>(null);\n const bottomContent = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null);\n const footerRef = useRef<HTMLDivElement>(null);\n const titleRef = useRef<HTMLHeadingElement>(null);\n const [scope, animate] = useAnimate();\n const [isPresent, safeToRemove] = usePresence();\n const [headerHeight, setHeaderHeight] = React.useState(0);\n const [footerHeight, setFooterHeight] = React.useState(0);\n const topContentVisible = useIsVisible(topContent);\n const bottomContentVisible = useIsVisible(bottomContent, 0);\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemDrawer = {\n ...defaultResources,\n ...resources,\n };\n\n // eslint-disable-next-line react-hooks/refs\n const contentIsScrollable = contentRef.current && contentRef.current.scrollHeight > contentRef.current.clientHeight;\n const headerStyling = classNames(styles.drawer__header, headerClasses);\n const hasFooterContent = (typeof footerContent !== 'undefined' && footerContent) || onPrimaryAction || onSecondaryAction;\n\n useFocusTrap(containerRef, true);\n useReturnFocusOnUnmount(containerRef);\n useOutsideEvent(containerRef, () => {\n if (onRequestClose) onRequestClose();\n });\n useKeyboardEvent(containerRef, () => onRequestClose && onRequestClose(), [KeyboardEventKey.Escape]);\n\n // Close animasjon, vi kaller `onClose()` til slutt\n const closeDrawer = (): void => {\n if (!overlayRef.current || !containerRef.current) return;\n\n animate(overlayRef.current, { opacity: 0, pointerEvents: 'none' }, { duration: 0.3, ease: 'easeInOut' });\n\n if (isMobile) {\n animate(\n containerRef.current,\n { y: '100%' },\n {\n duration: 0.3,\n ease: 'easeInOut',\n onComplete: () => {\n if (safeToRemove) safeToRemove();\n },\n }\n );\n } else {\n animate(\n containerRef.current,\n { x: desktopDirection === 'left' ? '-100%' : '100%' },\n {\n duration: 0.3,\n ease: 'easeInOut',\n onComplete: () => {\n if (safeToRemove) safeToRemove();\n },\n }\n );\n }\n };\n\n useEffect(() => {\n containerRef.current?.focus();\n disableBodyScroll();\n\n return (): void => {\n enableBodyScroll();\n };\n }, []);\n\n // Measure header and footer heights\n useEffect(() => {\n const updateHeights = (): void => {\n if (headerRef.current) {\n setHeaderHeight(headerRef.current.offsetHeight);\n }\n if (footerRef.current) {\n setFooterHeight(footerRef.current.offsetHeight);\n }\n };\n\n updateHeights();\n\n // Update heights when content changes\n const resizeObserver = new ResizeObserver(updateHeights);\n if (headerRef.current) {\n resizeObserver.observe(headerRef.current);\n }\n if (footerRef.current) {\n resizeObserver.observe(footerRef.current);\n }\n\n return (): void => {\n resizeObserver.disconnect();\n };\n }, [hasFooterContent]);\n\n // Open animation.\n useEffect(() => {\n if (!overlayRef.current || !containerRef.current) return;\n\n if (!isPresent) {\n closeDrawer();\n return;\n }\n\n if (isMobile) {\n animate(containerRef.current, { y: '0' }, { duration: 0.3, ease: 'easeInOut' });\n } else {\n animate(containerRef.current, { x: '0' }, { duration: 0.3, ease: 'easeInOut' });\n }\n\n animate(overlayRef.current, { opacity: 1, pointerEvents: 'auto' }, { duration: 0.3, ease: 'easeInOut' });\n }, [isPresent]);\n\n const handleCTA = (callback?: () => void): void => {\n if (callback) {\n callback();\n }\n };\n\n useEffect(() => {\n titleRef.current?.focus();\n }, [title]);\n\n return (\n <div className={styles.drawer} ref={scope} style={{ zIndex }} data-analyticsid={AnalyticsId.Drawer}>\n <div className={styles.drawer__overlay} ref={overlayRef} aria-hidden=\"true\" />\n <div\n className={classNames(styles.drawer__container, {\n [styles['drawer__container--right']]: desktopDirection === 'right',\n })}\n ref={containerRef}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n {...ariaLabelAttributes}\n >\n <div className={styles.drawer__container__inner}>\n <div className={headerStyling} ref={headerRef}>\n <Title\n id={ariaLabelAttributes?.['aria-labelledby']}\n className={styles['drawer__header__title']}\n htmlMarkup={titleHtmlMarkup}\n appearance=\"title3\"\n ref={titleRef}\n tabIndex={-1}\n >\n {title}\n </Title>\n {withBackButton && onRequestBack !== undefined && (\n <Button\n ariaLabel={mergedResources.ariaLabelBackButton}\n onClick={onRequestBack}\n variant=\"borderless\"\n wrapperClassName={styles['drawer__header__back-button']}\n >\n <Icon svgIcon={ChevronLeft} />\n </Button>\n )}\n {!noCloseButton && onRequestClose != undefined && (\n <Close\n ariaLabel={mergedResources.ariaLabelCloseBtn}\n color={closeColor}\n onClick={onRequestClose}\n className={styles['drawer__header__close-button']}\n />\n )}\n </div>\n <div\n className={classNames(styles['drawer__content__shadow'], styles['drawer__content__shadow--top'])}\n style={{\n opacity: !topContentVisible && contentIsScrollable ? 1 : 0,\n top: headerHeight,\n }}\n />\n <div\n className={classNames(styles.drawer__content, contentClassName)}\n tabIndex={contentIsScrollable ? 0 : undefined}\n role={contentIsScrollable ? 'region' : undefined}\n {...(contentIsScrollable ? ariaLabelAttributes : {})}\n ref={contentRef}\n >\n <div ref={topContent} />\n <div className={styles['drawer__content__children']}>{children}</div>\n <div ref={bottomContent} style={{ height: '1px' }} />\n </div>\n <div\n className={classNames(styles['drawer__content__shadow'], styles['drawer__content__shadow--bottom'])}\n style={{\n opacity: !bottomContentVisible && contentIsScrollable ? 1 : 0,\n bottom: hasFooterContent ? footerHeight : 0,\n }}\n />\n </div>\n {hasFooterContent && (\n <div className={styles.drawer__footer} ref={footerRef}>\n {footerContent ? (\n footerContent\n ) : (\n <>\n {onPrimaryAction && <Button onClick={() => handleCTA(onPrimaryAction)}>{primaryActionText}</Button>}\n {onSecondaryAction && (\n <Button variant=\"borderless\" onClick={() => handleCTA(onSecondaryAction)}>\n {secondaryActionText}\n </Button>\n )}\n </>\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default Drawer;\n","import Drawer from './Drawer';\nexport * from './Drawer';\nexport default Drawer;\n"],"mappings":"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"}
package/lib/Select.js CHANGED
@@ -16,7 +16,7 @@ var getIconColor = (invalid, disabled) => {
16
16
  return disabled ? getColor("neutral", 500) : getColor(invalid ? "cherry" : "blueberry", 600);
17
17
  };
18
18
  const Select = (props) => {
19
- const { className, children, concept = "normal", disabled, error, errorText, errorTextId: errorTextIdProp, selectId: selectIdProp, errorWrapperClassName, label, name = props.selectId, onColor = FormOnColor.onwhite, testId, width, required, value, defaultValue, autoComplete = "off", wrapperClassName, ref, ...rest } = props;
19
+ const { className, children, concept = "normal", disabled, error, errorText, errorTextId: errorTextIdProp, selectId: selectIdProp, errorWrapperClassName, label, name = props.selectId, onColor = FormOnColor.onwhite, testId, width, required, value, defaultValue, autoComplete = "off", wrapperClassName, ref, labelClassName, ...rest } = props;
20
20
  const selectId = useIdWithFallback(selectIdProp);
21
21
  const errorTextId = useIdWithFallback(errorTextIdProp);
22
22
  const onBlueberry = onColor === "onblueberry";
@@ -46,7 +46,8 @@ const Select = (props) => {
46
46
  children: [renderLabel({
47
47
  label,
48
48
  inputId: selectId,
49
- onColor
49
+ onColor,
50
+ className: labelClassName
50
51
  }), /* @__PURE__ */ jsxs("div", {
51
52
  className: selectInnerWrapperClasses,
52
53
  "data-testid": testId + "-inner-wrapper",
package/lib/Select.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","names":["Select: React.FC<SelectProps>"],"sources":["../src/components/Select/Select.tsx","../src/components/Select/index.ts"],"sourcesContent":["import classNames from 'classnames';\n\nimport type { ErrorWrapperClassNameProps } from '../ErrorWrapper';\n\nimport { AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX, FormOnColor, IconSize } from '../../constants';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { getColor } from '../../theme/currys';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport ErrorWrapper from '../ErrorWrapper';\nimport Icon from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport { renderLabel } from '../Label/utils';\n\nimport selectStyles from './styles.module.scss';\n\ntype SelectConcept = 'normal' | 'transparent';\n\nexport interface SelectProps\n extends\n ErrorWrapperClassNameProps,\n Pick<\n React.SelectHTMLAttributes<HTMLSelectElement>,\n 'aria-describedby' | 'name' | 'disabled' | 'required' | 'value' | 'onChange' | 'autoComplete'\n > {\n /** Sets the content of the select element. */\n children: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Changes the visuals of the component */\n concept?: SelectConcept;\n /** The label text above the select */\n label?: React.ReactNode;\n /** Changes the visuals of the component */\n onColor?: keyof typeof FormOnColor;\n /** Activates Error style for the select component - This is can be true while errorText is empty, when in a FormGroup */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** select id of the select element */\n selectId?: string;\n /** Width of select in characters (approximate) */\n width?: number;\n /** Gives defaultvalue to the comp. Preferred over selected prop on option by react */\n defaultValue?: string | number;\n /** Adds custom classes to the wrapper tag */\n wrapperClassName?: string;\n /** Ref passed to the select element */\n ref?: React.Ref<HTMLSelectElement | null>;\n}\n\nconst getSelectMaxWidth = (characters: number): string => {\n const paddingWidth = '2rem';\n\n return `calc(${characters * AVERAGE_CHARACTER_WIDTH_PX}px + ${paddingWidth})`;\n};\n\nconst getIconColor = (invalid: boolean, disabled: boolean): string => {\n const iconColor = invalid ? 'cherry' : 'blueberry';\n return disabled ? getColor('neutral', 500) : getColor(iconColor, 600);\n};\n\nexport const Select: React.FC<SelectProps> = props => {\n const {\n className,\n children,\n concept = 'normal',\n disabled,\n error,\n errorText,\n errorTextId: errorTextIdProp,\n selectId: selectIdProp,\n errorWrapperClassName,\n label,\n name = props.selectId,\n onColor = FormOnColor.onwhite,\n testId,\n width,\n required,\n value,\n defaultValue,\n autoComplete = 'off',\n wrapperClassName,\n ref,\n ...rest\n } = props;\n\n const selectId = useIdWithFallback(selectIdProp);\n const errorTextId = useIdWithFallback(errorTextIdProp);\n const onBlueberry = onColor === 'onblueberry';\n const invalid = onColor === 'oninvalid' || !!errorText || !!error;\n const iconColor = getIconColor(invalid, !!disabled);\n const maxWidth = width ? getSelectMaxWidth(width) : undefined;\n\n const selectInnerWrapperClasses = classNames(\n selectStyles['select-inner-wrapper'],\n {\n [selectStyles['select-inner-wrapper--transparent']]: concept === 'transparent',\n [selectStyles['select-inner-wrapper--on-blueberry']]: onBlueberry,\n [selectStyles['select-inner-wrapper--invalid']]: invalid,\n [selectStyles['select-inner-wrapper--disabled']]: disabled,\n },\n className\n );\n\n const selectClasses = classNames(selectStyles.select, {\n [selectStyles['select--on-blueberry']]: onBlueberry,\n [selectStyles['select--invalid']]: invalid,\n });\n\n const selectWrapperClasses = classNames(selectStyles['select-wrapper'], wrapperClassName);\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Select} className={selectWrapperClasses} style={{ maxWidth }}>\n {renderLabel({ label: label, inputId: selectId, onColor: onColor as FormOnColor })}\n <div className={selectInnerWrapperClasses} data-testid={testId + '-inner-wrapper'}>\n <Icon\n className={selectStyles['select-arrow']}\n svgIcon={ChevronDown}\n color={iconColor}\n size={IconSize.XSmall}\n testId={testId + '-icon'}\n />\n <select\n {...rest}\n aria-invalid={!!invalid}\n id={selectId}\n name={name}\n className={selectClasses}\n disabled={disabled}\n ref={ref}\n required={required}\n aria-describedby={getAriaDescribedBy(props, errorTextId)}\n aria-required={!!required}\n value={value}\n defaultValue={defaultValue}\n autoComplete={autoComplete ? autoComplete : undefined}\n >\n {children}\n </select>\n </div>\n </div>\n </ErrorWrapper>\n );\n};\n\nexport default Select;\n","import Select from './Select';\nexport * from './Select';\nexport default Select;\n"],"mappings":";;;;;;;;;;;AAsDA,IAAM,qBAAqB,eAA+B;AAGxD,QAAO,QAAQ,aAAA,GAAwC;;AAGzD,IAAM,gBAAgB,SAAkB,aAA8B;AAEpE,QAAO,WAAW,SAAS,WAAW,IAAI,GAAG,SAD3B,UAAU,WAAW,aAC0B,IAAI;;AAGvE,MAAaA,UAAgC,UAAS;CACpD,MAAM,EACJ,WACA,UACA,UAAU,UACV,UACA,OACA,WACA,aAAa,iBACb,UAAU,cACV,uBACA,OACA,OAAO,MAAM,UACb,UAAU,YAAY,SACtB,QACA,OACA,UACA,OACA,cACA,eAAe,OACf,kBACA,KACA,GAAG,SACD;CAEJ,MAAM,WAAW,kBAAkB,aAAa;CAChD,MAAM,cAAc,kBAAkB,gBAAgB;CACtD,MAAM,cAAc,YAAY;CAChC,MAAM,UAAU,YAAY,eAAe,CAAC,CAAC,aAAa,CAAC,CAAC;CAC5D,MAAM,YAAY,aAAa,SAAS,CAAC,CAAC,SAAS;CACnD,MAAM,WAAW,QAAQ,kBAAkB,MAAM,GAAG,KAAA;CAEpD,MAAM,4BAA4B,WAChC,aAAa,yBACb;GACG,aAAa,uCAAuC,YAAY;GAChE,aAAa,wCAAwC;GACrD,aAAa,mCAAmC;GAChD,aAAa,oCAAoC;EACnD,EACD,UACD;CAED,MAAM,gBAAgB,WAAW,aAAa,QAAQ;GACnD,aAAa,0BAA0B;GACvC,aAAa,qBAAqB;EACpC,CAAC;CAEF,MAAM,uBAAuB,WAAW,aAAa,mBAAmB,iBAAiB;AAEzF,QACE,oBAAC,sBAAA;EAAa,WAAW;EAAkC;EAAwB;YACjF,qBAAC,OAAA;GAAI,eAAa;GAAQ,oBAAkB,YAAY;GAAQ,WAAW;GAAsB,OAAO,EAAE,UAAU;cACjH,YAAY;IAAS;IAAO,SAAS;IAAmB;IAAwB,CAAC,EAClF,qBAAC,OAAA;IAAI,WAAW;IAA2B,eAAa,SAAS;eAC/D,oBAAC,cAAA;KACC,WAAW,aAAa;KACxB,SAAS;KACT,OAAO;KACP,MAAM,SAAS;KACf,QAAQ,SAAS;MACjB,EACF,oBAAC,UAAA;KACC,GAAI;KACJ,gBAAc,CAAC,CAAC;KAChB,IAAI;KACE;KACN,WAAW;KACD;KACL;KACK;KACV,oBAAkB,mBAAmB,OAAO,YAAY;KACxD,iBAAe,CAAC,CAAC;KACV;KACO;KACd,cAAc,eAAe,eAAe,KAAA;KAE3C;MACM,CAAA;KACL,CAAA;IACF;GACO;;AChJnB,IAAA,mBDoJe"}
1
+ {"version":3,"file":"Select.js","names":["Select: React.FC<SelectProps>"],"sources":["../src/components/Select/Select.tsx","../src/components/Select/index.ts"],"sourcesContent":["import classNames from 'classnames';\n\nimport type { ErrorWrapperClassNameProps } from '../ErrorWrapper';\n\nimport { AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX, FormOnColor, IconSize } from '../../constants';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { getColor } from '../../theme/currys';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport ErrorWrapper from '../ErrorWrapper';\nimport Icon from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport { renderLabel } from '../Label/utils';\n\nimport selectStyles from './styles.module.scss';\n\ntype SelectConcept = 'normal' | 'transparent';\n\nexport interface SelectProps\n extends\n ErrorWrapperClassNameProps,\n Pick<\n React.SelectHTMLAttributes<HTMLSelectElement>,\n 'aria-describedby' | 'name' | 'disabled' | 'required' | 'value' | 'onChange' | 'autoComplete'\n > {\n /** Sets the content of the select element. */\n children: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Changes the visuals of the component */\n concept?: SelectConcept;\n /** The label text above the select */\n label?: React.ReactNode;\n /** Adds custom classes to the label wrapper */\n labelClassName?: string;\n /** Changes the visuals of the component */\n onColor?: keyof typeof FormOnColor;\n /** Activates Error style for the select component - This is can be true while errorText is empty, when in a FormGroup */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** select id of the select element */\n selectId?: string;\n /** Width of select in characters (approximate) */\n width?: number;\n /** Gives defaultvalue to the comp. Preferred over selected prop on option by react */\n defaultValue?: string | number;\n /** Adds custom classes to the wrapper tag */\n wrapperClassName?: string;\n /** Ref passed to the select element */\n ref?: React.Ref<HTMLSelectElement | null>;\n}\n\nconst getSelectMaxWidth = (characters: number): string => {\n const paddingWidth = '2rem';\n\n return `calc(${characters * AVERAGE_CHARACTER_WIDTH_PX}px + ${paddingWidth})`;\n};\n\nconst getIconColor = (invalid: boolean, disabled: boolean): string => {\n const iconColor = invalid ? 'cherry' : 'blueberry';\n return disabled ? getColor('neutral', 500) : getColor(iconColor, 600);\n};\n\nexport const Select: React.FC<SelectProps> = props => {\n const {\n className,\n children,\n concept = 'normal',\n disabled,\n error,\n errorText,\n errorTextId: errorTextIdProp,\n selectId: selectIdProp,\n errorWrapperClassName,\n label,\n name = props.selectId,\n onColor = FormOnColor.onwhite,\n testId,\n width,\n required,\n value,\n defaultValue,\n autoComplete = 'off',\n wrapperClassName,\n ref,\n labelClassName,\n ...rest\n } = props;\n\n const selectId = useIdWithFallback(selectIdProp);\n const errorTextId = useIdWithFallback(errorTextIdProp);\n const onBlueberry = onColor === 'onblueberry';\n const invalid = onColor === 'oninvalid' || !!errorText || !!error;\n const iconColor = getIconColor(invalid, !!disabled);\n const maxWidth = width ? getSelectMaxWidth(width) : undefined;\n\n const selectInnerWrapperClasses = classNames(\n selectStyles['select-inner-wrapper'],\n {\n [selectStyles['select-inner-wrapper--transparent']]: concept === 'transparent',\n [selectStyles['select-inner-wrapper--on-blueberry']]: onBlueberry,\n [selectStyles['select-inner-wrapper--invalid']]: invalid,\n [selectStyles['select-inner-wrapper--disabled']]: disabled,\n },\n className\n );\n\n const selectClasses = classNames(selectStyles.select, {\n [selectStyles['select--on-blueberry']]: onBlueberry,\n [selectStyles['select--invalid']]: invalid,\n });\n\n const selectWrapperClasses = classNames(selectStyles['select-wrapper'], wrapperClassName);\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Select} className={selectWrapperClasses} style={{ maxWidth }}>\n {renderLabel({ label: label, inputId: selectId, onColor: onColor as FormOnColor, className: labelClassName })}\n <div className={selectInnerWrapperClasses} data-testid={testId + '-inner-wrapper'}>\n <Icon\n className={selectStyles['select-arrow']}\n svgIcon={ChevronDown}\n color={iconColor}\n size={IconSize.XSmall}\n testId={testId + '-icon'}\n />\n <select\n {...rest}\n aria-invalid={!!invalid}\n id={selectId}\n name={name}\n className={selectClasses}\n disabled={disabled}\n ref={ref}\n required={required}\n aria-describedby={getAriaDescribedBy(props, errorTextId)}\n aria-required={!!required}\n value={value}\n defaultValue={defaultValue}\n autoComplete={autoComplete ? autoComplete : undefined}\n >\n {children}\n </select>\n </div>\n </div>\n </ErrorWrapper>\n );\n};\n\nexport default Select;\n","import Select from './Select';\nexport * from './Select';\nexport default Select;\n"],"mappings":";;;;;;;;;;;AAwDA,IAAM,qBAAqB,eAA+B;AAGxD,QAAO,QAAQ,aAAA,GAAwC;;AAGzD,IAAM,gBAAgB,SAAkB,aAA8B;AAEpE,QAAO,WAAW,SAAS,WAAW,IAAI,GAAG,SAD3B,UAAU,WAAW,aAC0B,IAAI;;AAGvE,MAAaA,UAAgC,UAAS;CACpD,MAAM,EACJ,WACA,UACA,UAAU,UACV,UACA,OACA,WACA,aAAa,iBACb,UAAU,cACV,uBACA,OACA,OAAO,MAAM,UACb,UAAU,YAAY,SACtB,QACA,OACA,UACA,OACA,cACA,eAAe,OACf,kBACA,KACA,gBACA,GAAG,SACD;CAEJ,MAAM,WAAW,kBAAkB,aAAa;CAChD,MAAM,cAAc,kBAAkB,gBAAgB;CACtD,MAAM,cAAc,YAAY;CAChC,MAAM,UAAU,YAAY,eAAe,CAAC,CAAC,aAAa,CAAC,CAAC;CAC5D,MAAM,YAAY,aAAa,SAAS,CAAC,CAAC,SAAS;CACnD,MAAM,WAAW,QAAQ,kBAAkB,MAAM,GAAG,KAAA;CAEpD,MAAM,4BAA4B,WAChC,aAAa,yBACb;GACG,aAAa,uCAAuC,YAAY;GAChE,aAAa,wCAAwC;GACrD,aAAa,mCAAmC;GAChD,aAAa,oCAAoC;EACnD,EACD,UACD;CAED,MAAM,gBAAgB,WAAW,aAAa,QAAQ;GACnD,aAAa,0BAA0B;GACvC,aAAa,qBAAqB;EACpC,CAAC;CAEF,MAAM,uBAAuB,WAAW,aAAa,mBAAmB,iBAAiB;AAEzF,QACE,oBAAC,sBAAA;EAAa,WAAW;EAAkC;EAAwB;YACjF,qBAAC,OAAA;GAAI,eAAa;GAAQ,oBAAkB,YAAY;GAAQ,WAAW;GAAsB,OAAO,EAAE,UAAU;cACjH,YAAY;IAAS;IAAO,SAAS;IAAmB;IAAwB,WAAW;IAAgB,CAAC,EAC7G,qBAAC,OAAA;IAAI,WAAW;IAA2B,eAAa,SAAS;eAC/D,oBAAC,cAAA;KACC,WAAW,aAAa;KACxB,SAAS;KACT,OAAO;KACP,MAAM,SAAS;KACf,QAAQ,SAAS;MACjB,EACF,oBAAC,UAAA;KACC,GAAI;KACJ,gBAAc,CAAC,CAAC;KAChB,IAAI;KACE;KACN,WAAW;KACD;KACL;KACK;KACV,oBAAkB,mBAAmB,OAAO,YAAY;KACxD,iBAAe,CAAC,CAAC;KACV;KACO;KACd,cAAc,eAAe,eAAe,KAAA;KAE3C;MACM,CAAA;KACL,CAAA;IACF;GACO;;ACnJnB,IAAA,mBDuJe"}
package/lib/Title.js CHANGED
@@ -6,7 +6,7 @@ const instanceOfTitleMargin = (margin) => {
6
6
  return Object.prototype.hasOwnProperty.call(margin, "marginTop") && Object.prototype.hasOwnProperty.call(margin, "marginBottom");
7
7
  };
8
8
  const Title = (props) => {
9
- const { id, children, className, htmlMarkup = "h1", appearance = "title1", margin = 0, testId, ref } = props;
9
+ const { id, children, className, htmlMarkup = "h1", appearance = "title1", margin = 0, tabIndex, testId, ref } = props;
10
10
  return /* @__PURE__ */ jsx(htmlMarkup, {
11
11
  id,
12
12
  className: classNames(titleStyles.title, {
@@ -28,6 +28,7 @@ const Title = (props) => {
28
28
  ref,
29
29
  "data-testid": testId,
30
30
  "data-analyticsid": AnalyticsId.Title,
31
+ tabIndex,
31
32
  children
32
33
  });
33
34
  };
package/lib/Title.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Title.js","names":["Title: React.FC<TitleProps>"],"sources":["../src/components/Title/utils.ts","../src/components/Title/Title.tsx"],"sourcesContent":["import type { TitleMargin } from './Title';\n\nexport const instanceOfTitleMargin = (margin: unknown): margin is TitleMargin => {\n return Object.prototype.hasOwnProperty.call(margin, 'marginTop') && Object.prototype.hasOwnProperty.call(margin, 'marginBottom');\n};\n","import classNames from 'classnames';\n\nimport { instanceOfTitleMargin } from './utils';\nimport { AnalyticsId } from '../../constants';\n\nimport titleStyles from './styles.module.scss';\n\nexport type TitleTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span';\nexport type TitleAppearances = 'titleFeature' | 'title1' | 'title2' | 'title3' | 'title4' | 'title5' | 'title6';\n\nexport interface TitleProps {\n children: React.ReactNode;\n /** Gives a unique id to the title */\n id?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds top and bottom margin in rem. */\n margin?: number | TitleMargin;\n /** Changes the underlying element of the title. */\n htmlMarkup?: TitleTags;\n /** Changes the appearance of the title. */\n appearance?: TitleAppearances;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Ref passed to the heading element */\n ref?: React.Ref<HTMLHeadingElement | null>;\n}\n\nexport const Title: React.FC<TitleProps> = (props: TitleProps) => {\n const { id, children, className, htmlMarkup = 'h1', appearance = 'title1', margin = 0, testId, ref } = props;\n const titleClasses = classNames(\n titleStyles.title,\n {\n [titleStyles['title--feature']]: appearance === 'titleFeature',\n [titleStyles['title--title1']]: appearance === 'title1',\n [titleStyles['title--title2']]: appearance === 'title2',\n [titleStyles['title--title3']]: appearance === 'title3',\n [titleStyles['title--title4']]: appearance === 'title4',\n [titleStyles['title--title5']]: appearance === 'title5',\n [titleStyles['title--title6']]: appearance === 'title6',\n },\n className\n );\n const CustomTag = htmlMarkup;\n\n const inlineStyle = instanceOfTitleMargin(margin)\n ? { marginTop: `${margin.marginTop}rem`, marginBottom: `${margin.marginBottom}rem` }\n : { marginTop: `${margin}rem`, marginBottom: `${margin}rem` };\n\n return (\n <CustomTag id={id} className={titleClasses} style={inlineStyle} ref={ref} data-testid={testId} data-analyticsid={AnalyticsId.Title}>\n {children}\n </CustomTag>\n );\n};\n\nexport interface TitleMargin {\n marginTop: number;\n marginBottom: number;\n}\n\nexport default Title;\n"],"mappings":";;;;AAEA,MAAa,yBAAyB,WAA2C;AAC/E,QAAO,OAAO,UAAU,eAAe,KAAK,QAAQ,YAAY,IAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,eAAe;;ACyBlI,MAAaA,SAA+B,UAAsB;CAChE,MAAM,EAAE,IAAI,UAAU,WAAW,aAAa,MAAM,aAAa,UAAU,SAAS,GAAG,QAAQ,QAAQ;AAoBvG,QACE,oBAPgB,YAOf;EAAc;EAAI,WApBA,WACnB,YAAY,OACZ;IACG,YAAY,oBAAoB,eAAe;IAC/C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;GAChD,EACD,UACD;EAQ6C,OAL1B,sBAAsB,OAAO,GAC7C;GAAE,WAAW,GAAG,OAAO,UAAU;GAAM,cAAc,GAAG,OAAO,aAAa;GAAM,GAClF;GAAE,WAAW,GAAG,OAAO;GAAM,cAAc,GAAG,OAAO;GAAM;EAGQ;EAAK,eAAa;EAAQ,oBAAkB,YAAY;EAC1H;GACS;;AAShB,IAAA,gBAAe"}
1
+ {"version":3,"file":"Title.js","names":["Title: React.FC<TitleProps>"],"sources":["../src/components/Title/utils.ts","../src/components/Title/Title.tsx"],"sourcesContent":["import type { TitleMargin } from './Title';\n\nexport const instanceOfTitleMargin = (margin: unknown): margin is TitleMargin => {\n return Object.prototype.hasOwnProperty.call(margin, 'marginTop') && Object.prototype.hasOwnProperty.call(margin, 'marginBottom');\n};\n","import classNames from 'classnames';\n\nimport { instanceOfTitleMargin } from './utils';\nimport { AnalyticsId } from '../../constants';\n\nimport titleStyles from './styles.module.scss';\n\nexport type TitleTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span';\nexport type TitleAppearances = 'titleFeature' | 'title1' | 'title2' | 'title3' | 'title4' | 'title5' | 'title6';\n\nexport interface TitleProps {\n children: React.ReactNode;\n /** Gives a unique id to the title */\n id?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds top and bottom margin in rem. */\n margin?: number | TitleMargin;\n /** Changes the underlying element of the title. */\n htmlMarkup?: TitleTags;\n /** Changes the appearance of the title. */\n appearance?: TitleAppearances;\n /** Sets the tabIndex. Use this with caution. */\n tabIndex?: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Ref passed to the heading element */\n ref?: React.Ref<HTMLHeadingElement | null>;\n}\n\nexport const Title: React.FC<TitleProps> = (props: TitleProps) => {\n const { id, children, className, htmlMarkup = 'h1', appearance = 'title1', margin = 0, tabIndex, testId, ref } = props;\n const titleClasses = classNames(\n titleStyles.title,\n {\n [titleStyles['title--feature']]: appearance === 'titleFeature',\n [titleStyles['title--title1']]: appearance === 'title1',\n [titleStyles['title--title2']]: appearance === 'title2',\n [titleStyles['title--title3']]: appearance === 'title3',\n [titleStyles['title--title4']]: appearance === 'title4',\n [titleStyles['title--title5']]: appearance === 'title5',\n [titleStyles['title--title6']]: appearance === 'title6',\n },\n className\n );\n const CustomTag = htmlMarkup;\n\n const inlineStyle = instanceOfTitleMargin(margin)\n ? { marginTop: `${margin.marginTop}rem`, marginBottom: `${margin.marginBottom}rem` }\n : { marginTop: `${margin}rem`, marginBottom: `${margin}rem` };\n\n return (\n <CustomTag\n id={id}\n className={titleClasses}\n style={inlineStyle}\n ref={ref}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Title}\n tabIndex={tabIndex}\n >\n {children}\n </CustomTag>\n );\n};\n\nexport interface TitleMargin {\n marginTop: number;\n marginBottom: number;\n}\n\nexport default Title;\n"],"mappings":";;;;AAEA,MAAa,yBAAyB,WAA2C;AAC/E,QAAO,OAAO,UAAU,eAAe,KAAK,QAAQ,YAAY,IAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,eAAe;;AC2BlI,MAAaA,SAA+B,UAAsB;CAChE,MAAM,EAAE,IAAI,UAAU,WAAW,aAAa,MAAM,aAAa,UAAU,SAAS,GAAG,UAAU,QAAQ,QAAQ;AAoBjH,QACE,oBAPgB,YAOf;EACK;EACJ,WAtBiB,WACnB,YAAY,OACZ;IACG,YAAY,oBAAoB,eAAe;IAC/C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;IAC9C,YAAY,mBAAmB,eAAe;GAChD,EACD,UACD;EAWG,OARgB,sBAAsB,OAAO,GAC7C;GAAE,WAAW,GAAG,OAAO,UAAU;GAAM,cAAc,GAAG,OAAO,aAAa;GAAM,GAClF;GAAE,WAAW,GAAG,OAAO;GAAM,cAAc,GAAG,OAAO;GAAM;EAOtD;EACL,eAAa;EACb,oBAAkB,YAAY;EACpB;EAET;GACS;;AAShB,IAAA,gBAAe"}
@@ -45,6 +45,12 @@ export interface InnerDrawerProps {
45
45
  resources?: Partial<HNDesignsystemDrawer>;
46
46
  /** Sets mobile styling and animation from outer level Drawer */
47
47
  isMobile?: boolean;
48
+ /** Shows a back button to the left of title */
49
+ withBackButton?: boolean;
50
+ /** Callback for the back button */
51
+ onRequestBack?: () => void;
52
+ /** Sets classname for content part in Drawer */
53
+ contentClassName?: string;
48
54
  }
49
55
  declare const Drawer: React.FC<DrawerProps>;
50
56
  export default Drawer;
@@ -84,11 +84,30 @@
84
84
 
85
85
  &__title {
86
86
  margin-top: 0.5rem !important;
87
+
88
+ &:focus,
89
+ &:focus-visible {
90
+ outline: none;
91
+ }
87
92
  }
88
93
 
89
94
  &__close-button {
90
95
  align-self: flex-start;
91
96
  }
97
+
98
+ &__back-button {
99
+ // Moves the button visually to the left but keeps it in the DOM order for screen readers and keyboard navigation
100
+ order: -1;
101
+
102
+ // Temporary fix for the back button, until we decide if we want to implement this more properly
103
+ width: 48px;
104
+ height: 48px;
105
+
106
+ svg {
107
+ width: 48px;
108
+ height: 48px;
109
+ }
110
+ }
92
111
  }
93
112
 
94
113
  &__content {
@@ -11,6 +11,7 @@ export type Styles = {
11
11
  'drawer__content__shadow--top': string;
12
12
  drawer__footer: string;
13
13
  drawer__header: string;
14
+ 'drawer__header__back-button': string;
14
15
  'drawer__header__close-button': string;
15
16
  drawer__header__title: string;
16
17
  drawer__overlay: string;
@@ -24,11 +24,11 @@
24
24
  border-color: var(--color-base-border-onlight-emphasized);
25
25
  background-color: var(--core-color-white);
26
26
 
27
- &:hover {
27
+ &:hover:not(:disabled) {
28
28
  background-color: var(--color-base-background-neutral);
29
29
  }
30
30
 
31
- &:active {
31
+ &:active:not(:disabled) {
32
32
  background-color: var(--core-color-neutral-100);
33
33
  }
34
34
 
@@ -65,11 +65,11 @@
65
65
  &--borderless {
66
66
  background-color: transparent;
67
67
 
68
- &:hover {
68
+ &:hover:not(:disabled) {
69
69
  background-color: var(--core-color-neutral-100);
70
70
  }
71
71
 
72
- &:active {
72
+ &:active:not(:disabled) {
73
73
  background-color: var(--core-color-neutral-200);
74
74
  }
75
75
  }
@@ -0,0 +1,35 @@
1
+ import { default as React } from 'react';
2
+ export interface DrawerViewProps<ViewId extends string = string> {
3
+ /** Id for the view. Important for navigation */
4
+ id: ViewId;
5
+ /** Title used for Drawer in current view */
6
+ title: string;
7
+ /** Mark this view as the home/default view */
8
+ home?: boolean;
9
+ /** Content inside the drawer for this view */
10
+ children: React.ReactNode;
11
+ /** Default onClose callback for drawer. Will override onCloseButton on parent */
12
+ onCloseButton?: () => void;
13
+ /** Content sent to footer section of Drawer. Will override footer on parent */
14
+ footer?: React.ReactNode;
15
+ /** Classname set on the content inside Drawer */
16
+ drawerContentClassname?: string;
17
+ }
18
+ declare function DrawerView<ViewId extends string>(_props: DrawerViewProps<ViewId>): React.ReactNode;
19
+ export interface DrawerNavigationProps {
20
+ /** Views and other children components inside the Drawer navigation. Views are put in stack */
21
+ children: React.ReactNode;
22
+ /** Is drawer open or closed */
23
+ isOpen: boolean;
24
+ /** Navigate to this view when the drawer opens. Defaults to home view. */
25
+ initialView?: string;
26
+ /** Default onClose callback for drawer. View onCloseButton callback will override this. */
27
+ onCloseButton?: () => void;
28
+ /** Content sent to footer section of Drawer. View footer will override this */
29
+ footer?: React.ReactNode;
30
+ }
31
+ declare function DrawerNavigation({ children, isOpen, initialView, onCloseButton, footer }: DrawerNavigationProps): React.ReactNode;
32
+ declare namespace DrawerNavigation {
33
+ var View: typeof DrawerView;
34
+ }
35
+ export default DrawerNavigation;
@@ -0,0 +1,2 @@
1
+ declare const FinnFastlegeFlytExample: () => React.ReactNode;
2
+ export default FinnFastlegeFlytExample;
@@ -0,0 +1,15 @@
1
+ .toggle {
2
+ padding-top: 0.5rem;
3
+ padding-bottom: 0.5rem;
4
+ }
5
+
6
+ .checkboxes-under-toggle {
7
+ padding-left: 1.5rem;
8
+ }
9
+
10
+ .modal-buttons {
11
+ display: flex;
12
+ flex-flow: column;
13
+ align-items: flex-start;
14
+ gap: 1rem;
15
+ }
@@ -0,0 +1,11 @@
1
+ export type Styles = {
2
+ 'checkboxes-under-toggle': string;
3
+ 'modal-buttons': string;
4
+ toggle: string;
5
+ };
6
+
7
+ export type ClassNames = keyof Styles;
8
+
9
+ declare const styles: Styles;
10
+
11
+ export default styles;
@@ -0,0 +1,4 @@
1
+ import { default as DrawerNavigation } from './DrawerNavigation';
2
+ export * from './DrawerNavigation';
3
+ export * from './useDrawerNavigation';
4
+ export default DrawerNavigation;
@@ -0,0 +1,81 @@
1
+ import { t as Drawer_default } from "../../../Drawer.js";
2
+ import { Children, createContext, isValidElement, useCallback, useContext, useMemo, useState } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ const DrawerNavigationContext = createContext(null);
5
+ function useDrawerNavigation() {
6
+ const context = useContext(DrawerNavigationContext);
7
+ if (!context) throw new Error("useDrawerNavigation must be used inside a <DrawerNavigation> component");
8
+ return context;
9
+ }
10
+ function DrawerView(_props) {
11
+ return null;
12
+ }
13
+ function parseChildren(children) {
14
+ const views = [];
15
+ const other = [];
16
+ Children.forEach(children, (child) => {
17
+ if (isValidElement(child) && child.type === DrawerView) views.push({
18
+ id: child.props.id,
19
+ title: child.props.title,
20
+ home: child.props.home,
21
+ children: child.props.children,
22
+ onCloseButton: child.props.onCloseButton,
23
+ footer: child.props.footer,
24
+ drawerContentClassname: child.props.drawerContentClassname
25
+ });
26
+ else other.push(child);
27
+ });
28
+ return {
29
+ views,
30
+ other
31
+ };
32
+ }
33
+ function DrawerNavigation({ children, isOpen, initialView, onCloseButton, footer }) {
34
+ const { views, other } = useMemo(() => parseChildren(children), [children]);
35
+ const homeView = views.find((v) => v.home) ?? views[0];
36
+ const [viewStack, setViewStack] = useState([homeView?.id]);
37
+ const goToView = useCallback((id) => {
38
+ if (views.some((v) => v.id === id)) setViewStack((stack) => [...stack, id]);
39
+ }, [views]);
40
+ const goBack = useCallback(() => {
41
+ setViewStack((stack) => stack.length > 1 ? stack.slice(0, -1) : stack);
42
+ }, []);
43
+ const goToViewAndClearStack = useCallback((id) => {
44
+ if (views.some((v) => v.id === id)) setViewStack(id === homeView?.id ? [homeView.id] : [homeView?.id, id]);
45
+ }, [views, homeView]);
46
+ const currentViewId = viewStack[viewStack.length - 1];
47
+ const currentView = views.find((v) => v.id === currentViewId);
48
+ const navigate = useMemo(() => ({
49
+ goBack,
50
+ goToView,
51
+ goToViewAndClearStack
52
+ }), [
53
+ goBack,
54
+ goToView,
55
+ goToViewAndClearStack
56
+ ]);
57
+ const [prevIsOpen, setPrevIsOpen] = useState(isOpen);
58
+ if (prevIsOpen !== isOpen) {
59
+ setPrevIsOpen(isOpen);
60
+ if (!isOpen) setViewStack([homeView?.id]);
61
+ else if (initialView && views.some((v) => v.id === initialView)) setViewStack(initialView === homeView?.id ? [homeView.id] : [homeView?.id, initialView]);
62
+ }
63
+ return /* @__PURE__ */ jsxs(DrawerNavigationContext.Provider, {
64
+ value: navigate,
65
+ children: [/* @__PURE__ */ jsx(Drawer_default, {
66
+ isOpen,
67
+ title: currentView?.title ?? "Filter",
68
+ withBackButton: viewStack.length > 1,
69
+ onRequestBack: goBack,
70
+ onRequestClose: currentView?.onCloseButton ?? onCloseButton,
71
+ footerContent: currentView?.footer ?? footer,
72
+ contentClassName: currentView?.drawerContentClassname,
73
+ children: currentView?.children
74
+ }), other]
75
+ });
76
+ }
77
+ DrawerNavigation.View = DrawerView;
78
+ var DrawerNavigation_default = DrawerNavigation;
79
+ export { DrawerNavigationContext, DrawerNavigation_default as default, useDrawerNavigation };
80
+
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["views: DrawerViewProps[]","other: React.ReactNode[]"],"sources":["../../../../src/components/Filter/DrawerNavigation/useDrawerNavigation.ts","../../../../src/components/Filter/DrawerNavigation/DrawerNavigation.tsx","../../../../src/components/Filter/DrawerNavigation/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nexport interface NavigateProps<ViewId extends string = string> {\n goToView: (id: ViewId) => void;\n goBack: () => void;\n goToViewAndClearStack: (id: ViewId) => void;\n}\n\nexport const DrawerNavigationContext = createContext<NavigateProps | null>(null);\n\nexport function useDrawerNavigation<ViewId extends string = string>(): NavigateProps<ViewId> {\n const context = useContext(DrawerNavigationContext);\n if (!context) {\n throw new Error('useDrawerNavigation must be used inside a <DrawerNavigation> component');\n }\n return context as NavigateProps<ViewId>;\n}\n","import type React from 'react';\nimport { Children, isValidElement, useCallback, useMemo, useState } from 'react';\n\nimport { type NavigateProps, DrawerNavigationContext } from './useDrawerNavigation';\nimport Drawer from '../../Drawer';\n\nexport interface DrawerViewProps<ViewId extends string = string> {\n /** Id for the view. Important for navigation */\n id: ViewId;\n /** Title used for Drawer in current view */\n title: string;\n /** Mark this view as the home/default view */\n home?: boolean;\n /** Content inside the drawer for this view */\n children: React.ReactNode;\n /** Default onClose callback for drawer. Will override onCloseButton on parent */\n onCloseButton?: () => void;\n /** Content sent to footer section of Drawer. Will override footer on parent */\n footer?: React.ReactNode;\n /** Classname set on the content inside Drawer */\n drawerContentClassname?: string;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction DrawerView<ViewId extends string>(_props: DrawerViewProps<ViewId>): React.ReactNode {\n // DrawerView is never rendered directly — DrawerNavigation reads its props\n return null;\n}\n\nexport interface DrawerNavigationProps {\n /** Views and other children components inside the Drawer navigation. Views are put in stack */\n children: React.ReactNode;\n /** Is drawer open or closed */\n isOpen: boolean;\n /** Navigate to this view when the drawer opens. Defaults to home view. */\n initialView?: string;\n /** Default onClose callback for drawer. View onCloseButton callback will override this. */\n onCloseButton?: () => void;\n /** Content sent to footer section of Drawer. View footer will override this */\n footer?: React.ReactNode;\n}\n\nfunction parseChildren(children: React.ReactNode): { views: DrawerViewProps[]; other: React.ReactNode[] } {\n const views: DrawerViewProps[] = [];\n const other: React.ReactNode[] = [];\n Children.forEach(children, child => {\n if (isValidElement<DrawerViewProps>(child) && child.type === DrawerView) {\n views.push({\n id: child.props.id,\n title: child.props.title,\n home: child.props.home,\n children: child.props.children,\n onCloseButton: child.props.onCloseButton,\n footer: child.props.footer,\n drawerContentClassname: child.props.drawerContentClassname,\n });\n } else {\n /** Added possibility of other children to support Modals that need navigation context */\n other.push(child);\n }\n });\n return { views, other };\n}\n\nfunction DrawerNavigation({ children, isOpen, initialView, onCloseButton, footer }: DrawerNavigationProps): React.ReactNode {\n const { views, other } = useMemo(() => parseChildren(children), [children]);\n\n const homeView = views.find(v => v.home) ?? views[0];\n const [viewStack, setViewStack] = useState<string[]>([homeView?.id]);\n\n const goToView = useCallback(\n (id: string): void => {\n if (views.some(v => v.id === id)) {\n setViewStack(stack => [...stack, id]);\n }\n },\n [views]\n );\n\n const goBack = useCallback((): void => {\n setViewStack(stack => (stack.length > 1 ? stack.slice(0, -1) : stack));\n }, []);\n\n const goToViewAndClearStack = useCallback(\n (id: string): void => {\n if (views.some(v => v.id === id)) {\n setViewStack(id === homeView?.id ? [homeView.id] : [homeView?.id, id]);\n }\n },\n [views, homeView]\n );\n\n const currentViewId = viewStack[viewStack.length - 1];\n const currentView = views.find(v => v.id === currentViewId);\n\n const navigate = useMemo<NavigateProps>(() => ({ goBack, goToView, goToViewAndClearStack }), [goBack, goToView, goToViewAndClearStack]);\n\n const [prevIsOpen, setPrevIsOpen] = useState(isOpen);\n if (prevIsOpen !== isOpen) {\n setPrevIsOpen(isOpen);\n if (!isOpen) {\n setViewStack([homeView?.id]);\n } else if (initialView && views.some(v => v.id === initialView)) {\n setViewStack(initialView === homeView?.id ? [homeView.id] : [homeView?.id, initialView]);\n }\n }\n\n return (\n <DrawerNavigationContext.Provider value={navigate}>\n <Drawer\n isOpen={isOpen}\n title={currentView?.title ?? 'Filter'}\n withBackButton={viewStack.length > 1}\n onRequestBack={goBack}\n onRequestClose={currentView?.onCloseButton ?? onCloseButton}\n footerContent={currentView?.footer ?? footer}\n contentClassName={currentView?.drawerContentClassname}\n >\n {currentView?.children}\n </Drawer>\n {other}\n </DrawerNavigationContext.Provider>\n );\n}\n\nDrawerNavigation.View = DrawerView;\n\nexport default DrawerNavigation;\n","import DrawerNavigation from './DrawerNavigation';\nexport * from './DrawerNavigation';\nexport * from './useDrawerNavigation';\nexport default DrawerNavigation;\n"],"mappings":";;;AAQA,MAAa,0BAA0B,cAAoC,KAAK;AAEhF,SAAgB,sBAA6E;CAC3F,MAAM,UAAU,WAAW,wBAAwB;AACnD,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,yEAAyE;AAE3F,QAAO;;ACST,SAAS,WAAkC,QAAkD;AAE3F,QAAO;;AAgBT,SAAS,cAAc,UAAmF;CACxG,MAAMA,QAA2B,EAAE;CACnC,MAAMC,QAA2B,EAAE;AACnC,UAAS,QAAQ,WAAU,UAAS;AAClC,MAAI,eAAgC,MAAM,IAAI,MAAM,SAAS,WAC3D,OAAM,KAAK;GACT,IAAI,MAAM,MAAM;GAChB,OAAO,MAAM,MAAM;GACnB,MAAM,MAAM,MAAM;GAClB,UAAU,MAAM,MAAM;GACtB,eAAe,MAAM,MAAM;GAC3B,QAAQ,MAAM,MAAM;GACpB,wBAAwB,MAAM,MAAM;GACrC,CAAC;MAGF,OAAM,KAAK,MAAM;GAEnB;AACF,QAAO;EAAE;EAAO;EAAO;;AAGzB,SAAS,iBAAiB,EAAE,UAAU,QAAQ,aAAa,eAAe,UAAkD;CAC1H,MAAM,EAAE,OAAO,UAAU,cAAc,cAAc,SAAS,EAAE,CAAC,SAAS,CAAC;CAE3E,MAAM,WAAW,MAAM,MAAK,MAAK,EAAE,KAAK,IAAI,MAAM;CAClD,MAAM,CAAC,WAAW,gBAAgB,SAAmB,CAAC,UAAU,GAAG,CAAC;CAEpE,MAAM,WAAW,aACd,OAAqB;AACpB,MAAI,MAAM,MAAK,MAAK,EAAE,OAAO,GAAG,CAC9B,eAAa,UAAS,CAAC,GAAG,OAAO,GAAG,CAAC;IAGzC,CAAC,MAAM,CACR;CAED,MAAM,SAAS,kBAAwB;AACrC,gBAAa,UAAU,MAAM,SAAS,IAAI,MAAM,MAAM,GAAG,GAAG,GAAG,MAAO;IACrE,EAAE,CAAC;CAEN,MAAM,wBAAwB,aAC3B,OAAqB;AACpB,MAAI,MAAM,MAAK,MAAK,EAAE,OAAO,GAAG,CAC9B,cAAa,OAAO,UAAU,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC;IAG1E,CAAC,OAAO,SAAS,CAClB;CAED,MAAM,gBAAgB,UAAU,UAAU,SAAS;CACnD,MAAM,cAAc,MAAM,MAAK,MAAK,EAAE,OAAO,cAAc;CAE3D,MAAM,WAAW,eAA8B;EAAE;EAAQ;EAAU;EAAuB,GAAG;EAAC;EAAQ;EAAU;EAAsB,CAAC;CAEvI,MAAM,CAAC,YAAY,iBAAiB,SAAS,OAAO;AACpD,KAAI,eAAe,QAAQ;AACzB,gBAAc,OAAO;AACrB,MAAI,CAAC,OACH,cAAa,CAAC,UAAU,GAAG,CAAC;WACnB,eAAe,MAAM,MAAK,MAAK,EAAE,OAAO,YAAY,CAC7D,cAAa,gBAAgB,UAAU,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,UAAU,IAAI,YAAY,CAAC;;AAI5F,QACE,qBAAC,wBAAwB,UAAA;EAAS,OAAO;aACvC,oBAAC,gBAAA;GACS;GACR,OAAO,aAAa,SAAS;GAC7B,gBAAgB,UAAU,SAAS;GACnC,eAAe;GACf,gBAAgB,aAAa,iBAAiB;GAC9C,eAAe,aAAa,UAAU;GACtC,kBAAkB,aAAa;aAE9B,aAAa;IACP,EACR,MAAA;GACgC;;AAIvC,iBAAiB,OAAO;AC1HxB,IAAA,2BD4He"}
@@ -0,0 +1,7 @@
1
+ export interface NavigateProps<ViewId extends string = string> {
2
+ goToView: (id: ViewId) => void;
3
+ goBack: () => void;
4
+ goToViewAndClearStack: (id: ViewId) => void;
5
+ }
6
+ export declare const DrawerNavigationContext: import('react').Context<NavigateProps<string> | null>;
7
+ export declare function useDrawerNavigation<ViewId extends string = string>(): NavigateProps<ViewId>;
@@ -0,0 +1,7 @@
1
+ import { HNDesignsystemFilter } from '../../../resources/Resources';
2
+ export interface FilterButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
3
+ /** Texts if overriding SOT */
4
+ resources?: Partial<HNDesignsystemFilter>;
5
+ }
6
+ declare const FilterButton: React.FC<FilterButtonProps>;
7
+ export default FilterButton;