@helsenorge/designsystem-react 10.0.0-beta.5 → 10.0.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.
package/CHANGELOG.md CHANGED
@@ -1,86 +1,24 @@
1
- ## 10.0.0-beta.4 (2025-01-10)
1
+ ## [9.7.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv9.6.0&targetVersion=GTv9.7.0) (2025-01-24)
2
2
 
3
3
  ### Features
4
4
 
5
- - **datepicker:** arialabels er et object av strings
6
- ([63bbd43](https://github.com/helsenorge/designsystem/commit/63bbd4362be32744bff0add8f37a9fb07c8fc8f5)), closes
7
- [#331806](https://github.com/helsenorge/designsystem/issues/331806)
5
+ - oppdatert spacing i expanderlist og listheader
6
+ ([57d969c](https://github.com/helsenorge/designsystem/commit/57d969c5633b4c841790ec486f003c1a6d017279)), closes
7
+ [#339057](https://github.com/helsenorge/designsystem/issues/339057)
8
+ - **stickynote:** ny komponent ([395603f](https://github.com/helsenorge/designsystem/commit/395603fc46e10432968bfef5f83a4937ecfc9440)),
9
+ closes [#341184](https://github.com/helsenorge/designsystem/issues/341184)
8
10
 
9
11
  ### Bug Fixes
10
12
 
11
- - importriktig format ([8d2a26c](https://github.com/helsenorge/designsystem/commit/8d2a26cda5d370f8b5eb7acd61c3439d902b6998)), closes
12
- [#339137](https://github.com/helsenorge/designsystem/issues/339137) [#339137](https://github.com/helsenorge/designsystem/issues/339137)
13
-
14
- ## 10.0.0-beta.3 (2024-12-20)
15
-
16
- ### Bug Fixes
17
-
18
- - label renderasparent rendrer nå subdued igjen når det passeres inn ren string
19
- ([7851865](https://github.com/helsenorge/designsystem/commit/7851865ac788f7f2390a8093f049b40f020c650b))
20
-
21
- ## 10.0.0-beta.2 (2024-12-20)
22
-
23
- ### Features
24
-
25
- - arialabels prop for og fikset disabled dager feil
26
- ([e57ba55](https://github.com/helsenorge/designsystem/commit/e57ba55e4a2be478c659ec0515290aebed28674c)), closes
27
- [#331806](https://github.com/helsenorge/designsystem/issues/331806)
28
- - **listheader:** tillat chevron på linklist size small
29
- ([9e93688](https://github.com/helsenorge/designsystem/commit/9e9368842dffb8b26c14dfd914376bc3b002c88c)), closes
30
- [#340288](https://github.com/helsenorge/designsystem/issues/340288)
31
-
32
- ## 10.0.0-beta.1 (2024-12-18)
33
-
34
- ### Bug Fixes
35
-
36
- - **emptystate:** behold bredden på illustrasjon
37
- ([058c7f9](https://github.com/helsenorge/designsystem/commit/058c7f94fa84b96ff58944c6e7696cd44af01a07)), closes
38
- [#336772](https://github.com/helsenorge/designsystem/issues/336772)
39
-
40
- ## 10.0.0-beta.0 (2024-12-17)
41
-
42
- ### Features
43
-
44
- - endret fonts ([6324729](https://github.com/helsenorge/designsystem/commit/632472942c9d83a33f5e508e3b9205193b72eeae)), closes
45
- [#332727](https://github.com/helsenorge/designsystem/issues/332727)
46
- - oppdatert pakkeversjon og startet migrering
47
- ([2a5f592](https://github.com/helsenorge/designsystem/commit/2a5f592b4f30e718a001e6a4a5b891087c85da0a))
48
- - oppdatert pakkeversjon og startet migrering"
49
- ([09b7c27](https://github.com/helsenorge/designsystem/commit/09b7c2725d5c20d8a352349f3b673b17d717d130))
50
- - **avatar:** endre variant normal til square
51
- ([8453374](https://github.com/helsenorge/designsystem/commit/8453374c0c64c8bedc005c346286f8d370c7d546)), closes
52
- [#337118](https://github.com/helsenorge/designsystem/issues/337118)
53
- - **avatar:** nye navn for props ([37c8e0b](https://github.com/helsenorge/designsystem/commit/37c8e0be9a0186ccb24dbacafef858c4f2742a06)),
54
- closes [#335338](https://github.com/helsenorge/designsystem/issues/335338)
55
- - **badge:** endre oppbygning av komponenten
56
- ([12248cb](https://github.com/helsenorge/designsystem/commit/12248cb243322d8e83fe536b51f34ef231dadad8)), closes
57
- [#339274](https://github.com/helsenorge/designsystem/issues/339274)
58
- - **datepicker:** date-fns peer-dependency satt til v4
59
- ([a53ba94](https://github.com/helsenorge/designsystem/commit/a53ba94d6c720b87c3dbf466b2e6b25acc00082b)), closes
60
- [#339137](https://github.com/helsenorge/designsystem/issues/339137)
61
- - **datepicker:** tar i bruk major 9 av reactdaypicker
62
- ([778b49e](https://github.com/helsenorge/designsystem/commit/778b49e3feb8deebd3ae32a3d3de54cda93e2a20)), closes
63
- [#331806](https://github.com/helsenorge/designsystem/issues/331806)
64
- - **emptystate:** nytt design med ny illustrasjon og flere varianter
65
- ([e14a49f](https://github.com/helsenorge/designsystem/commit/e14a49fe26a30bd06e87e5ecf35a3bf6e5539b08)), closes
66
- [#336772](https://github.com/helsenorge/designsystem/issues/336772)
67
- - **linklist:** nytt design ([43de477](https://github.com/helsenorge/designsystem/commit/43de477a3280d9ecf9aee997bc763fb82d269864)), closes
68
- [#336491](https://github.com/helsenorge/designsystem/issues/336491)
69
- - **tabs:** touchbehavior prop er fjernet
70
- ([994aded](https://github.com/helsenorge/designsystem/commit/994adeda6085664d26bf4e90ea111ef0fa6a9d78)), closes
71
- [#328640](https://github.com/helsenorge/designsystem/issues/328640)
72
-
73
- ### Bug Fixes
74
-
75
- - popover og datepicker popup kan brukes i 400 prosent zoom
76
- ([782ce70](https://github.com/helsenorge/designsystem/commit/782ce70b9b2c06a65a872ee886f742d54f5689ab)), closes
77
- [#340117](https://github.com/helsenorge/designsystem/issues/340117)
78
- - **highlightpanel:** tillat tittel selv om ikon ikke er gitt
79
- ([63322a8](https://github.com/helsenorge/designsystem/commit/63322a881857ae42aaf3039412548c6b9750abee)), closes
80
- [#332566](https://github.com/helsenorge/designsystem/issues/332566)
81
- - **tabs:** ikke scroll til fane med mindre komponenten er i view
82
- ([0c30a43](https://github.com/helsenorge/designsystem/commit/0c30a43e4fdb6acece3db8f30e6ed43468c712fd)), closes
83
- [#339921](https://github.com/helsenorge/designsystem/issues/339921)
13
+ - **dropdown:** enter lukkeknapp lukker dropdown
14
+ ([c132d0f](https://github.com/helsenorge/designsystem/commit/c132d0fca8ad94ffd9343a219239e71daad2568b)), closes
15
+ [#340820](https://github.com/helsenorge/designsystem/issues/340820)
16
+ - **modal:** fiks så styling for zoom på modal ikke vises på mobilt breakpoint
17
+ ([22aff5f](https://github.com/helsenorge/designsystem/commit/22aff5fdb82dc8438ea6e11dc6e0988e3fe61a6b)), closes
18
+ [#336560](https://github.com/helsenorge/designsystem/issues/336560)
19
+ - **validationsummary:** aria attributter tweakes
20
+ ([2316247](https://github.com/helsenorge/designsystem/commit/2316247d7f6b038cc77f25c5940ae32ee2f0bd84)), closes
21
+ [#340310](https://github.com/helsenorge/designsystem/issues/340310)
84
22
 
85
23
  ## [9.6.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv9.5.0&targetVersion=GTv9.6.0) (2025-01-08)
86
24
 
@@ -58,7 +58,6 @@ const Dropdown = (props) => {
58
58
  };
59
59
  const handleKeyboardNavigation = (event) => {
60
60
  var _a;
61
- event.preventDefault();
62
61
  if (!inputRefList.current) {
63
62
  return;
64
63
  }
@@ -83,6 +82,7 @@ const Dropdown = (props) => {
83
82
  nextIndex = index;
84
83
  }
85
84
  if (nextIndex !== -1) {
85
+ event.preventDefault();
86
86
  (_a = inputRefList.current[nextIndex].current) == null ? void 0 : _a.focus();
87
87
  setCurrentIndex(nextIndex);
88
88
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["import React, { useRef, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n ZIndex,\n theme,\n useHover,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n useUuid,\n} from '../..';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Icon from '../Icon';\nimport PlusSmall from '../Icons/PlusSmall';\n\nimport styles from './styles.module.scss';\n\nexport enum DropdownOnColor {\n onwhite = 'onwhite',\n ongrey = 'ongrey',\n onblueberry = 'onblueberry',\n oncherry = 'oncherry',\n}\n\nexport interface DropdownProps {\n /** Label for dropdown. Visible for screen readers */\n label: string;\n /** Text on the trigger button that opens the dropdown */\n placeholder: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Close button text */\n closeText?: string;\n /** No close button */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed */\n onToggle?: (isOpen: boolean) => void;\n /** Whether the dropdown is open or not */\n open?: boolean;\n /** Changes the visuals of the dropdown */\n onColor?: keyof typeof DropdownOnColor;\n /** Makes the background of the trigger transparent */\n transparent?: boolean;\n /** Makes the width of the full component adjust to its parent */\n fluid?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button */\n testId?: string;\n /** Overrides the default z-index of the DropDownContent */\n zIndex?: number;\n}\n\nconst Dropdown: React.FC<DropdownProps> = props => {\n const {\n label,\n placeholder,\n closeText = 'Lukk',\n noCloseButton = false,\n onToggle,\n open = false,\n children,\n onColor = DropdownOnColor.onwhite,\n transparent = false,\n fluid = false,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n } = props;\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const { hoverRef: buttonRef, isHovered } = useHover<HTMLButtonElement>();\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const inputRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const [currentIndex, setCurrentIndex] = useState<number>();\n const labelId = useUuid();\n const toggleLabelId = useUuid();\n const optionIdPrefix = useUuid();\n\n const handleOpen = (): void => {\n toggleIsOpen();\n optionsRef.current?.focus();\n };\n\n const handleClose = (): void => {\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n event.preventDefault();\n\n if (!inputRefList.current) {\n return;\n }\n\n if (!isOpen) {\n handleOpen();\n return;\n } else if (event.key === KeyboardEventKey.Escape && isOpen) {\n handleClose();\n return;\n }\n\n const index = inputRefList.current.findIndex(x => x.current === event.target);\n let nextIndex = index;\n\n if (event.key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (event.key === KeyboardEventKey.End) {\n nextIndex = inputRefList.current.length - 1;\n } else if (event.key === KeyboardEventKey.ArrowDown && index < inputRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (event.key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n } else if (event.key === KeyboardEventKey.Enter && index !== -1) {\n nextIndex = index;\n }\n if (nextIndex !== -1) {\n inputRefList.current[nextIndex].current?.focus();\n setCurrentIndex(nextIndex);\n }\n };\n\n useKeyboardEvent(dropdownRef, handleKeyboardNavigation, [\n KeyboardEventKey.ArrowDown,\n KeyboardEventKey.ArrowUp,\n KeyboardEventKey.End,\n KeyboardEventKey.Enter,\n KeyboardEventKey.Escape,\n KeyboardEventKey.Home,\n ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const toggleClasses = classNames(\n styles.dropdown__toggle,\n !disabled && {\n [styles['dropdown__toggle--on-white']]: onColor === DropdownOnColor.onwhite,\n [styles['dropdown__toggle--on-grey']]: onColor === DropdownOnColor.ongrey,\n [styles['dropdown__toggle--on-blueberry']]: onColor === DropdownOnColor.onblueberry,\n [styles['dropdown__toggle--on-cherry']]: onColor === DropdownOnColor.oncherry,\n [styles['dropdown__toggle--transparent']]: transparent,\n [styles['dropdown__toggle--fluid']]: fluid,\n [styles['dropdown__toggle--open']]: isOpen,\n }\n );\n\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n\n const renderChildren = React.Children.map(children, (child, index) => (\n <li className={styles.dropdown__input} role=\"option\" id={`${optionIdPrefix}-${index}`} aria-selected={index === currentIndex}>\n {React.isValidElement(child) && inputRefList.current && inputRefList.current[index]\n ? React.cloneElement(child as React.ReactElement, { ref: mergeRefs([child.props.ref, inputRefList.current[index]]) })\n : child}\n </li>\n ));\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <span id={labelId} className={styles.dropdown__label}>\n {label}\n </span>\n <button\n type=\"button\"\n onClick={(): false | void => !isOpen && handleOpen()}\n className={toggleClasses}\n ref={buttonRef}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleLabelId}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n >\n <span id={toggleLabelId} className={styles.dropdown__toggle__label}>\n {placeholder}\n </span>\n <Icon\n color={disabled ? theme.palette.neutral700 : theme.palette.blueberry600}\n svgIcon={PlusSmall}\n className={styles.dropdown__icon}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div className={contentClasses} style={{ width: fluid ? '100%' : `auto`, zIndex: zIndex }}>\n <ul\n className={styles.dropdown__options}\n role=\"listbox\"\n aria-labelledby={labelId}\n tabIndex={-1}\n aria-activedescendant={typeof currentIndex !== 'undefined' ? `${optionIdPrefix}-${currentIndex}` : undefined}\n ref={optionsRef}\n >\n {renderChildren}\n </ul>\n {!noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose} aria-expanded={isOpen}>\n {closeText}\n </Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default Dropdown;\n"],"names":["DropdownOnColor"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["import React, { useRef, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n ZIndex,\n theme,\n useHover,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n useUuid,\n} from '../..';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Icon from '../Icon';\nimport PlusSmall from '../Icons/PlusSmall';\n\nimport styles from './styles.module.scss';\n\nexport enum DropdownOnColor {\n onwhite = 'onwhite',\n ongrey = 'ongrey',\n onblueberry = 'onblueberry',\n oncherry = 'oncherry',\n}\n\nexport interface DropdownProps {\n /** Label for dropdown. Visible for screen readers */\n label: string;\n /** Text on the trigger button that opens the dropdown */\n placeholder: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Close button text */\n closeText?: string;\n /** No close button */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed */\n onToggle?: (isOpen: boolean) => void;\n /** Whether the dropdown is open or not */\n open?: boolean;\n /** Changes the visuals of the dropdown */\n onColor?: keyof typeof DropdownOnColor;\n /** Makes the background of the trigger transparent */\n transparent?: boolean;\n /** Makes the width of the full component adjust to its parent */\n fluid?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button */\n testId?: string;\n /** Overrides the default z-index of the DropDownContent */\n zIndex?: number;\n}\n\nconst Dropdown: React.FC<DropdownProps> = props => {\n const {\n label,\n placeholder,\n closeText = 'Lukk',\n noCloseButton = false,\n onToggle,\n open = false,\n children,\n onColor = DropdownOnColor.onwhite,\n transparent = false,\n fluid = false,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n } = props;\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const { hoverRef: buttonRef, isHovered } = useHover<HTMLButtonElement>();\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const inputRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const [currentIndex, setCurrentIndex] = useState<number>();\n const labelId = useUuid();\n const toggleLabelId = useUuid();\n const optionIdPrefix = useUuid();\n\n const handleOpen = (): void => {\n toggleIsOpen();\n optionsRef.current?.focus();\n };\n\n const handleClose = (): void => {\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n if (!inputRefList.current) {\n return;\n }\n\n if (!isOpen) {\n handleOpen();\n return;\n } else if (event.key === KeyboardEventKey.Escape && isOpen) {\n handleClose();\n return;\n }\n\n const index = inputRefList.current.findIndex(x => x.current === event.target);\n let nextIndex = index;\n\n if (event.key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (event.key === KeyboardEventKey.End) {\n nextIndex = inputRefList.current.length - 1;\n } else if (event.key === KeyboardEventKey.ArrowDown && index < inputRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (event.key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n } else if (event.key === KeyboardEventKey.Enter && index !== -1) {\n nextIndex = index;\n }\n\n if (nextIndex !== -1) {\n event.preventDefault();\n\n inputRefList.current[nextIndex].current?.focus();\n setCurrentIndex(nextIndex);\n }\n };\n\n useKeyboardEvent(dropdownRef, handleKeyboardNavigation, [\n KeyboardEventKey.ArrowDown,\n KeyboardEventKey.ArrowUp,\n KeyboardEventKey.End,\n KeyboardEventKey.Enter,\n KeyboardEventKey.Escape,\n KeyboardEventKey.Home,\n ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const toggleClasses = classNames(\n styles.dropdown__toggle,\n !disabled && {\n [styles['dropdown__toggle--on-white']]: onColor === DropdownOnColor.onwhite,\n [styles['dropdown__toggle--on-grey']]: onColor === DropdownOnColor.ongrey,\n [styles['dropdown__toggle--on-blueberry']]: onColor === DropdownOnColor.onblueberry,\n [styles['dropdown__toggle--on-cherry']]: onColor === DropdownOnColor.oncherry,\n [styles['dropdown__toggle--transparent']]: transparent,\n [styles['dropdown__toggle--fluid']]: fluid,\n [styles['dropdown__toggle--open']]: isOpen,\n }\n );\n\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n\n const renderChildren = React.Children.map(children, (child, index) => (\n <li className={styles.dropdown__input} role=\"option\" id={`${optionIdPrefix}-${index}`} aria-selected={index === currentIndex}>\n {React.isValidElement(child) && inputRefList.current && inputRefList.current[index]\n ? React.cloneElement(child as React.ReactElement, { ref: mergeRefs([child.props.ref, inputRefList.current[index]]) })\n : child}\n </li>\n ));\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <span id={labelId} className={styles.dropdown__label}>\n {label}\n </span>\n <button\n type=\"button\"\n onClick={(): false | void => !isOpen && handleOpen()}\n className={toggleClasses}\n ref={buttonRef}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleLabelId}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n >\n <span id={toggleLabelId} className={styles.dropdown__toggle__label}>\n {placeholder}\n </span>\n <Icon\n color={disabled ? theme.palette.neutral700 : theme.palette.blueberry600}\n svgIcon={PlusSmall}\n className={styles.dropdown__icon}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div className={contentClasses} style={{ width: fluid ? '100%' : `auto`, zIndex: zIndex }}>\n <ul\n className={styles.dropdown__options}\n role=\"listbox\"\n aria-labelledby={labelId}\n tabIndex={-1}\n aria-activedescendant={typeof currentIndex !== 'undefined' ? `${optionIdPrefix}-${currentIndex}` : undefined}\n ref={optionsRef}\n >\n {renderChildren}\n </ul>\n {!noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose} aria-expanded={isOpen}>\n {closeText}\n </Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default Dropdown;\n"],"names":["DropdownOnColor"],"mappings":"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"}
@@ -92,7 +92,7 @@
92
92
  width: 696px;
93
93
  }
94
94
 
95
- @container (max-width: 500px) {
95
+ @container (max-width: 319px) {
96
96
  padding-bottom: getSpacer(2xs);
97
97
  }
98
98
  }
@@ -175,7 +175,7 @@
175
175
  max-height: none;
176
176
  }
177
177
 
178
- @container (max-width: 500px) {
178
+ @container (max-width: 319px) {
179
179
  max-height: calc(100dvh - 4rem);
180
180
  }
181
181
 
@@ -191,7 +191,7 @@
191
191
  padding: getSpacer(xl) getSpacer(xl) getSpacer(2xs);
192
192
  }
193
193
 
194
- @container (max-width: 500px) {
194
+ @container (max-width: 319px) {
195
195
  padding: getSpacer(2xs) getSpacer(2xs) getSpacer(4xs);
196
196
  }
197
197
  }
@@ -203,7 +203,7 @@
203
203
  padding: getSpacer(xl) getSpacer(m) getSpacer(2xs);
204
204
  }
205
205
 
206
- @container (max-width: 500px) {
206
+ @container (max-width: 319px) {
207
207
  padding: getSpacer(2xs) getSpacer(3xs) getSpacer(4xs);
208
208
  }
209
209
  }
@@ -258,7 +258,7 @@
258
258
  padding: getSpacer(l) getSpacer(xl) 0;
259
259
  }
260
260
 
261
- @container (max-width: 500px) {
261
+ @container (max-width: 319px) {
262
262
  padding: getSpacer(2xs) getSpacer(2xs) 0;
263
263
  }
264
264
  }
@@ -266,7 +266,7 @@
266
266
  &--medium {
267
267
  padding: getSpacer(m) getSpacer(m) 0;
268
268
 
269
- @container (max-width: 500px) {
269
+ @container (max-width: 319px) {
270
270
  padding: getSpacer(2xs) getSpacer(2xs) 0;
271
271
  }
272
272
  }
@@ -0,0 +1,25 @@
1
+ import { default as React } from 'react';
2
+ export interface StickyNoteProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
3
+ /** Aria label for the delete/close button */
4
+ arialabelXButton: string;
5
+ /** Activates the error styling */
6
+ error?: boolean;
7
+ /** Error text to show below the note */
8
+ errorText?: string;
9
+ /** Error text id */
10
+ errorTextId?: string;
11
+ /** Text shown under the textarea */
12
+ footerText?: string;
13
+ /** Function run when clicking the delete/close button */
14
+ onXButtonClick?: () => void;
15
+ /** Function run if user clicks the component while it is disabled */
16
+ onClickWhileDisabled?: () => void;
17
+ /** Sets the data-testid attribute. */
18
+ testId?: string;
19
+ /** Timestamp shown over the textarea */
20
+ timestamp: string;
21
+ /** Classname for the outer wrapper */
22
+ wrapperClassName?: string;
23
+ }
24
+ declare const StickyNote: React.FC<StickyNoteProps>;
25
+ export default StickyNote;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ interface TriangleProps {
2
+ type: 'default' | 'active' | 'error';
3
+ }
4
+ export interface Palette {
5
+ border: string;
6
+ background: string;
7
+ }
8
+ declare const Triangle: React.FC<TriangleProps>;
9
+ export default Triangle;
@@ -0,0 +1,3 @@
1
+ import { default as StickyNote } from './StickyNote';
2
+ export * from './StickyNote';
3
+ export default StickyNote;
@@ -0,0 +1,142 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useRef, useEffect } from "react";
3
+ import classNames from "classnames";
4
+ import { useHover } from "../../hooks/useHover.js";
5
+ import { usePseudoClasses } from "../../hooks/usePseudoClasses.js";
6
+ import { I as Icon } from "../../Icon.js";
7
+ import { IconSize } from "../../constants.js";
8
+ import { useUuid } from "../../hooks/useUuid.js";
9
+ import { getAriaDescribedBy } from "../../utils/accessibility.js";
10
+ import X from "../Icons/X.js";
11
+ import styles from "./styles.module.scss";
12
+ const Triangle = ({ type }) => {
13
+ const palette = (() => {
14
+ switch (type) {
15
+ case "active":
16
+ return {
17
+ border: "#C59302",
18
+ background: "#F5E080"
19
+ };
20
+ case "error":
21
+ return {
22
+ border: "#C83521",
23
+ background: "#EEC0A5"
24
+ };
25
+ default:
26
+ return {
27
+ border: "#F5E080",
28
+ background: "#F5E080"
29
+ };
30
+ }
31
+ })();
32
+ return /* @__PURE__ */ jsxs("svg", { width: "22", height: "22", viewBox: "0 0 22 22", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
33
+ /* @__PURE__ */ jsx("mask", { id: "path-1-inside-1_1_44", fill: "white", children: /* @__PURE__ */ jsx("path", { d: "M22 0L1.80043e-06 22L2.83099e-06 -8.97354e-07L22 0Z" }) }),
34
+ /* @__PURE__ */ jsx("path", { d: "M22 0L1.80043e-06 22L2.83099e-06 -8.97354e-07L22 0Z", fill: palette.background }),
35
+ /* @__PURE__ */ jsx(
36
+ "path",
37
+ {
38
+ d: "M22 0L22.7071 0.707107L24.4142 -1L22 -1L22 0ZM1.80043e-06 22L-0.999998 22L-0.999998 24.4142L0.707109 22.7071L1.80043e-06 22ZM2.83099e-06 -8.97354e-07L2.87783e-06 -1L-0.999997 -1L-0.999997 -9.38143e-07L2.83099e-06 -8.97354e-07ZM21.2929 -0.707107L-0.707105 21.2929L0.707109 22.7071L22.7071 0.707107L21.2929 -0.707107ZM1 22L1 -8.56565e-07L-0.999997 -9.38143e-07L-0.999998 22L1 22ZM2.78414e-06 0.999999L22 1L22 -1L2.87783e-06 -1L2.78414e-06 0.999999Z",
39
+ fill: palette.border,
40
+ mask: "url(#path-1-inside-1_1_44)"
41
+ }
42
+ )
43
+ ] });
44
+ };
45
+ const StickyNote = (props) => {
46
+ const {
47
+ wrapperClassName,
48
+ timestamp,
49
+ onXButtonClick,
50
+ arialabelXButton,
51
+ footerText,
52
+ error,
53
+ errorText,
54
+ errorTextId,
55
+ onClickWhileDisabled,
56
+ testId,
57
+ ...textareaProps
58
+ } = props;
59
+ const errorTextUuid = useUuid(errorTextId);
60
+ const stickynoteRef = useRef(null);
61
+ const textareaRef = useRef(null);
62
+ const { isFocused: isTextareaFocused } = usePseudoClasses(textareaRef);
63
+ const { isHovered } = useHover(stickynoteRef);
64
+ const triangleType = error ? "error" : isTextareaFocused ? "active" : "default";
65
+ const handleWrapperClick = (event) => {
66
+ var _a;
67
+ if (event.target.closest("button")) {
68
+ return;
69
+ }
70
+ if (textareaProps.disabled) {
71
+ onClickWhileDisabled && onClickWhileDisabled();
72
+ return;
73
+ }
74
+ (_a = textareaRef.current) == null ? void 0 : _a.focus();
75
+ };
76
+ useEffect(() => {
77
+ textareaRef && textareaRef.current && resizeTextarea(textareaRef.current);
78
+ }, []);
79
+ const resizeTextarea = (target) => {
80
+ target.style.height = "inherit";
81
+ target.style.height = `${target.scrollHeight}px`;
82
+ };
83
+ const handleChange = (e) => {
84
+ const textarea = e.target;
85
+ resizeTextarea(textarea);
86
+ textareaProps.onChange && textareaProps.onChange(e);
87
+ };
88
+ return /* @__PURE__ */ jsxs("div", { children: [
89
+ /* @__PURE__ */ jsxs(
90
+ "div",
91
+ {
92
+ "data-testid": testId,
93
+ ref: stickynoteRef,
94
+ className: classNames(styles["sticky-note"], wrapperClassName, {
95
+ [styles["sticky-note--focused"]]: isTextareaFocused,
96
+ [styles["sticky-note--hovered"]]: isHovered && !isTextareaFocused && !textareaProps.disabled,
97
+ [styles["sticky-note--error"]]: error
98
+ }),
99
+ onClick: handleWrapperClick,
100
+ role: "textbox",
101
+ tabIndex: -1,
102
+ onKeyDown: (e) => {
103
+ if (e.key === "Enter" || e.key === " ") {
104
+ handleWrapperClick(e);
105
+ }
106
+ },
107
+ children: [
108
+ /* @__PURE__ */ jsx("div", { className: classNames(styles["sticky-note__header"]), children: timestamp && /* @__PURE__ */ jsx("span", { className: styles["sticky-note__header__timestamp"], children: timestamp }) }),
109
+ /* @__PURE__ */ jsx(
110
+ "textarea",
111
+ {
112
+ ref: textareaRef,
113
+ "data-testid": `${testId}-textarea`,
114
+ className: classNames(styles["sticky-note__textarea"], textareaProps.className),
115
+ ...textareaProps,
116
+ onChange: handleChange,
117
+ "aria-describedby": getAriaDescribedBy(props, errorTextUuid)
118
+ }
119
+ ),
120
+ /* @__PURE__ */ jsx(
121
+ "button",
122
+ {
123
+ onClick: onXButtonClick,
124
+ "aria-label": arialabelXButton,
125
+ "data-testid": "closeButton",
126
+ className: classNames(styles["sticky-note__x-button"]),
127
+ type: "button",
128
+ children: /* @__PURE__ */ jsx(Icon, { svgIcon: X, color: "black", size: IconSize.XXSmall })
129
+ }
130
+ ),
131
+ /* @__PURE__ */ jsx("div", { className: classNames(styles["sticky-note__footer"]), children: footerText && /* @__PURE__ */ jsx("span", { children: footerText }) }),
132
+ /* @__PURE__ */ jsx("div", { className: classNames(styles["sticky-note__triangle"]), children: /* @__PURE__ */ jsx(Triangle, { type: triangleType }) })
133
+ ]
134
+ }
135
+ ),
136
+ error && /* @__PURE__ */ jsx("p", { className: styles["sticky-note__error-text"], id: errorTextId, children: errorText })
137
+ ] });
138
+ };
139
+ export {
140
+ StickyNote as default
141
+ };
142
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/StickyNote/Triangle.tsx","../../../src/components/StickyNote/StickyNote.tsx"],"sourcesContent":["interface TriangleProps {\n type: 'default' | 'active' | 'error';\n}\n\nexport interface Palette {\n border: string;\n background: string;\n}\n\nconst Triangle: React.FC<TriangleProps> = ({ type }) => {\n const palette = ((): Palette => {\n switch (type) {\n case 'active':\n return {\n border: '#C59302',\n background: '#F5E080',\n };\n case 'error':\n return {\n border: '#C83521',\n background: '#EEC0A5',\n };\n default:\n return {\n border: '#F5E080',\n background: '#F5E080',\n };\n }\n })();\n return (\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <mask id=\"path-1-inside-1_1_44\" fill=\"white\">\n <path d=\"M22 0L1.80043e-06 22L2.83099e-06 -8.97354e-07L22 0Z\" />\n </mask>\n <path d=\"M22 0L1.80043e-06 22L2.83099e-06 -8.97354e-07L22 0Z\" fill={palette.background} />\n <path\n d=\"M22 0L22.7071 0.707107L24.4142 -1L22 -1L22 0ZM1.80043e-06 22L-0.999998 22L-0.999998 24.4142L0.707109 22.7071L1.80043e-06 22ZM2.83099e-06 -8.97354e-07L2.87783e-06 -1L-0.999997 -1L-0.999997 -9.38143e-07L2.83099e-06 -8.97354e-07ZM21.2929 -0.707107L-0.707105 21.2929L0.707109 22.7071L22.7071 0.707107L21.2929 -0.707107ZM1 22L1 -8.56565e-07L-0.999997 -9.38143e-07L-0.999998 22L1 22ZM2.78414e-06 0.999999L22 1L22 -1L2.87783e-06 -1L2.78414e-06 0.999999Z\"\n fill={palette.border}\n mask=\"url(#path-1-inside-1_1_44)\"\n />\n </svg>\n );\n};\n\nexport default Triangle;\n","import React, { useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport { useHover } from '../../hooks/useHover';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport Icon, { IconSize } from '../Icon';\nimport Triangle from './Triangle';\nimport { useUuid } from '../../hooks/useUuid';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport X from '../Icons/X';\n\nimport styles from './styles.module.scss';\n\nexport interface StickyNoteProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n /** Aria label for the delete/close button */\n arialabelXButton: string;\n /** Activates the error styling */\n error?: boolean;\n /** Error text to show below the note */\n errorText?: string;\n /** Error text id */\n errorTextId?: string;\n /** Text shown under the textarea */\n footerText?: string;\n /** Function run when clicking the delete/close button */\n onXButtonClick?: () => void;\n /** Function run if user clicks the component while it is disabled */\n onClickWhileDisabled?: () => void;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Timestamp shown over the textarea */\n timestamp: string;\n /** Classname for the outer wrapper */\n wrapperClassName?: string;\n}\n\nconst StickyNote: React.FC<StickyNoteProps> = (props: StickyNoteProps) => {\n const {\n wrapperClassName,\n timestamp,\n onXButtonClick,\n arialabelXButton,\n footerText,\n error,\n errorText,\n errorTextId,\n onClickWhileDisabled,\n testId,\n ...textareaProps\n } = props;\n const errorTextUuid = useUuid(errorTextId);\n const stickynoteRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const { isFocused: isTextareaFocused } = usePseudoClasses<HTMLTextAreaElement>(textareaRef);\n const { isHovered } = useHover<HTMLDivElement>(stickynoteRef);\n const triangleType = error ? 'error' : isTextareaFocused ? 'active' : 'default';\n\n const handleWrapperClick = (event: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>): void => {\n if ((event.target as HTMLElement).closest('button')) {\n return;\n }\n if (textareaProps.disabled) {\n onClickWhileDisabled && onClickWhileDisabled();\n return;\n }\n textareaRef.current?.focus();\n };\n\n useEffect(() => {\n // Resize textarea to fit default value\n textareaRef && textareaRef.current && resizeTextarea(textareaRef.current);\n }, []);\n\n const resizeTextarea = (target: HTMLTextAreaElement): void => {\n // Reset field height\n target.style.height = 'inherit';\n // Set new height\n target.style.height = `${target.scrollHeight}px`;\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {\n const textarea = e.target as HTMLTextAreaElement;\n resizeTextarea(textarea);\n textareaProps.onChange && textareaProps.onChange(e);\n };\n\n return (\n <div>\n <div\n data-testid={testId}\n ref={stickynoteRef}\n className={classNames(styles['sticky-note'], wrapperClassName, {\n [styles['sticky-note--focused']]: isTextareaFocused,\n [styles['sticky-note--hovered']]: isHovered && !isTextareaFocused && !textareaProps.disabled,\n [styles['sticky-note--error']]: error,\n })}\n onClick={handleWrapperClick}\n role=\"textbox\"\n tabIndex={-1}\n onKeyDown={e => {\n if (e.key === 'Enter' || e.key === ' ') {\n handleWrapperClick(e as React.KeyboardEvent<HTMLDivElement>);\n }\n }}\n >\n <div className={classNames(styles['sticky-note__header'])}>\n {timestamp && <span className={styles['sticky-note__header__timestamp']}>{timestamp}</span>}\n </div>\n <textarea\n ref={textareaRef}\n data-testid={`${testId}-textarea`}\n className={classNames(styles['sticky-note__textarea'], textareaProps.className)}\n {...textareaProps}\n onChange={handleChange}\n aria-describedby={getAriaDescribedBy(props, errorTextUuid)}\n />\n <button\n onClick={onXButtonClick}\n aria-label={arialabelXButton}\n data-testid=\"closeButton\"\n className={classNames(styles['sticky-note__x-button'])}\n type=\"button\"\n >\n <Icon svgIcon={X} color=\"black\" size={IconSize.XXSmall} />\n </button>\n <div className={classNames(styles['sticky-note__footer'])}>{footerText && <span>{footerText}</span>}</div>\n <div className={classNames(styles['sticky-note__triangle'])}>\n <Triangle type={triangleType} />\n </div>\n </div>\n {error && (\n <p className={styles['sticky-note__error-text']} id={errorTextId}>\n {errorText}\n </p>\n )}\n </div>\n );\n};\n\nexport default StickyNote;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ @use '../../scss/supernova/styles/colors' as *;
2
+ @use '../../scss/font-settings' as fonts;
3
+
4
+ .sticky-note {
5
+ position: relative;
6
+ background-color: var(--core-color-banana-50);
7
+ width: 100%;
8
+ border: var(--core-color-banana-300) 1px solid;
9
+ padding: 12px;
10
+ overflow: hidden;
11
+ clip-path: polygon(0 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%);
12
+
13
+ &--focused {
14
+ background-color: var(--core-color-banana-50);
15
+ border-color: var(--core-color-banana-600);
16
+ }
17
+
18
+ &--hovered {
19
+ background-color: var(--core-color-banana-100);
20
+ border: var(--core-color-banana-100) 1px solid;
21
+ }
22
+
23
+ &--error {
24
+ background-color: var(--core-color-cherry-50);
25
+ border: var(--core-color-cherry-300) 1px solid;
26
+ }
27
+
28
+ &__x-button {
29
+ cursor: pointer;
30
+ background-color: transparent;
31
+ color: var(--color-base-text-onlight);
32
+ border: 0;
33
+ width: 2.75rem;
34
+ height: 2.75rem;
35
+ display: flex;
36
+ justify-content: center;
37
+ align-items: center;
38
+ position: absolute;
39
+ top: 2px;
40
+ right: 2px;
41
+
42
+ &:hover {
43
+ background-color: var(--core-color-banana-200); // todo: bestem farge her
44
+ outline: 1px solid var(--core-color-banana-500); // todo: bestem farge her
45
+ }
46
+
47
+ &:focus-visible {
48
+ background-color: var(--color-action-background-transparent-onlight-hoverselected);
49
+ outline: 2px solid var(--color-action-border-onlight-focus);
50
+ }
51
+ }
52
+
53
+ &__header {
54
+ display: flex;
55
+ flex-flow: row nowrap;
56
+ justify-content: space-between;
57
+ align-items: center;
58
+
59
+ &__timestamp {
60
+ color: var(--color-placeholder-text-onlight);
61
+ font-size: 1rem;
62
+ }
63
+ }
64
+
65
+ &__textarea {
66
+ width: 100%;
67
+ height: 100%;
68
+ border: none;
69
+ resize: none;
70
+ background: transparent;
71
+ outline: none;
72
+ line-height: 28px;
73
+
74
+ &:disabled {
75
+ // Dette er for å unngå at disabled tekst ikke validerer på iOS
76
+ -webkit-text-fill-color: var(--color-base-text-onlight);
77
+ opacity: 1;
78
+ }
79
+ }
80
+
81
+ &__footer {
82
+ color: var(--color-placeholder-text-onlight);
83
+ font-size: 0.75rem;
84
+ font-style: italic;
85
+ }
86
+
87
+ &__triangle {
88
+ position: absolute;
89
+ bottom: -2px;
90
+ right: -2px;
91
+ width: 22px;
92
+ height: 22px;
93
+ }
94
+
95
+ &__error-text {
96
+ color: var(--color-notification-status-error);
97
+ line-height: 1.875rem;
98
+ font-size: fonts.$font-size-sm;
99
+ margin-top: 0.75rem;
100
+ }
101
+ }
@@ -0,0 +1,19 @@
1
+ export type Styles = {
2
+ 'sticky-note': string;
3
+ 'sticky-note__error-text': string;
4
+ 'sticky-note__footer': string;
5
+ 'sticky-note__header': string;
6
+ 'sticky-note__header__timestamp': string;
7
+ 'sticky-note__textarea': string;
8
+ 'sticky-note__triangle': string;
9
+ 'sticky-note__x-button': string;
10
+ 'sticky-note--error': string;
11
+ 'sticky-note--focused': string;
12
+ 'sticky-note--hovered': string;
13
+ };
14
+
15
+ export type ClassNames = keyof Styles;
16
+
17
+ declare const styles: Styles;
18
+
19
+ export default styles;
@@ -34,7 +34,8 @@ const ValidationSummary = (props) => {
34
34
  return /* @__PURE__ */ jsxs(
35
35
  "div",
36
36
  {
37
- role: "alert",
37
+ role: "status",
38
+ "aria-atomic": "true",
38
39
  "aria-live": "polite",
39
40
  "aria-relevant": "all",
40
41
  "aria-labelledby": hasErrors && props.errorTitle ? titleId : void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/components/Validation/ErrorListItem.tsx","../../../src/components/Validation/ErrorList.tsx","../../../src/components/Validation/ValidationSummary.tsx","../../../src/components/Validation/Validation.tsx"],"sourcesContent":["import React from 'react';\n\nimport { ErrorDetails, FocusableElement } from './types';\nimport AnchorLink, { AnchorLinkOnClickEvent } from '../AnchorLink';\n\ninterface ErrorElementProps {\n name: string;\n error: ErrorDetails;\n}\n\nconst ErrorListItem: React.FC<ErrorElementProps> = props => {\n const handleClick = (event?: AnchorLinkOnClickEvent, element?: FocusableElement): void => {\n event?.preventDefault();\n element?.focus && element?.focus();\n };\n\n if (props.error.ref) {\n return (\n <AnchorLink href={`#${props.name}`} onClick={(e): void => handleClick(e, props.error.ref)}>\n {props.error.message}\n </AnchorLink>\n );\n }\n\n return <>{props.error.message}</>;\n};\n\nexport default ErrorListItem;\n","import React from 'react';\n\nimport ErrorListItem from './ErrorListItem';\nimport { ValidationErrors } from './types';\nimport List from '../List';\n\ninterface ErrorListProps {\n errors: ValidationErrors;\n}\n\nconst ErrorList: React.FC<ErrorListProps> = props => (\n <List>\n {Object.entries(props.errors).map(([name, error]) => (\n <List.Item key={name}>\n <ErrorListItem name={name} error={error} />\n </List.Item>\n ))}\n </List>\n);\n\nexport default ErrorList;\n","import React from 'react';\n\nimport classNames from 'classnames';\n\nimport ErrorList from './ErrorList';\nimport { ValidationErrors } from './types';\nimport { useUuid } from '../../hooks/useUuid';\nimport Title, { TitleTags } from '../Title';\n\nimport styles from './styles.module.scss';\n\ninterface ValidationSummaryProps {\n /** Error summary title */\n errorTitle?: string;\n /** Error list */\n errors?: ValidationErrors;\n /** Markup props for error summary title. Default: h2 */\n errorTitleHtmlMarkup?: TitleTags;\n /** Will be shown last */\n children?: React.ReactNode;\n}\n\nconst ValidationSummary: React.FC<ValidationSummaryProps> = props => {\n const { errorTitleHtmlMarkup = 'h2' } = props;\n const titleId = useUuid();\n\n const hasErrors = !!props.errors && Object.entries(props.errors).length > 0;\n\n const summaryClasses = classNames(styles['validation__summary'], hasErrors && styles['validation__summary--visible']);\n\n return (\n <div\n role={'alert'}\n aria-live={'polite'}\n aria-relevant={'all'}\n aria-labelledby={hasErrors && props.errorTitle ? titleId : undefined}\n className={summaryClasses}\n >\n {hasErrors && (\n <>\n {props.errorTitle && (\n <Title appearance=\"title4\" id={titleId} htmlMarkup={errorTitleHtmlMarkup} margin={{ marginTop: 0, marginBottom: 1 }}>\n {props.errorTitle}\n </Title>\n )}\n <ErrorList errors={props.errors!} />\n </>\n )}\n {props.children}\n </div>\n );\n};\n\nexport default ValidationSummary;\n","import React from 'react';\n\nimport { ValidationErrors } from './types';\nimport ValidationSummary from './ValidationSummary';\nimport { AnalyticsId, FormSize } from '../../constants';\nimport { isComponent, isComponentWithDisplayName } from '../../utils/component';\nimport Checkbox, { CheckboxProps } from '../Checkbox';\nimport { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport FormGroup, { FormGroupProps } from '../FormGroup/FormGroup';\nimport Input, { InputProps } from '../Input';\nimport RadioButton, { RadioButtonProps } from '../RadioButton';\nimport Select, { SelectProps } from '../Select';\nimport Slider, { SliderProps } from '../Slider';\nimport Textarea, { TextareaProps } from '../Textarea';\n\nimport styles from './styles.module.scss';\n\ninterface ValidationProps {\n /** Error summary title */\n errorTitle?: string;\n /** Validation errors. If errors include references to HTML elements, the errors will be rendered as links with an onClick handler to focus the element. */\n errors?: ValidationErrors;\n /** Items in the Validation compontent */\n children?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Changes the visuals of the formgroup */\n size?: keyof typeof FormSize;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const Validation = React.forwardRef((props: ValidationProps, ref: React.ForwardedRef<HTMLDivElement>) => {\n const validationErrorClass = styles['validation__error-wrapper'];\n\n const cloneFormElement = <T extends ErrorWrapperClassNameProps>(child: React.ReactElement<T>): React.ReactElement<T> => {\n return React.cloneElement(child, {\n ...child.props,\n errorWrapperClassName: validationErrorClass,\n });\n };\n\n const renderChild = (child: React.ReactNode): React.ReactNode => {\n if (\n isComponent<FormGroupProps>(child, FormGroup) ||\n isComponent<CheckboxProps>(child, Checkbox) ||\n isComponent<RadioButtonProps>(child, RadioButton) ||\n isComponent<TextareaProps>(child, Textarea) ||\n isComponent<InputProps>(child, Input) ||\n isComponent<SelectProps>(child, Select) ||\n isComponent<SliderProps>(child, Slider) ||\n isComponentWithDisplayName<ErrorWrapperClassNameProps>(child, 'DateTimePickerWrapper') ||\n isComponentWithDisplayName<ErrorWrapperClassNameProps>(child, 'DatePicker') ||\n isComponentWithDisplayName<ErrorWrapperClassNameProps>(child, 'DateTime')\n ) {\n return cloneFormElement<ErrorWrapperClassNameProps>(child);\n }\n if (React.isValidElement(child) && child.type === React.Fragment) {\n return React.Children.map(child.props.children, (child: React.ReactNode) => {\n return renderChild(child);\n });\n }\n\n return child;\n };\n\n return (\n <>\n <div data-testid={props.testId} data-analyticsid={AnalyticsId.Validation} className={props.className} ref={ref}>\n {React.Children.map(props.children, (child: React.ReactNode) => renderChild(child))}\n </div>\n <ValidationSummary errorTitle={props.errorTitle} errors={props.errors} />\n </>\n );\n});\n\nValidation.displayName = 'Validation';\n\nexport default Validation;\n"],"names":["child"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/Validation/ErrorListItem.tsx","../../../src/components/Validation/ErrorList.tsx","../../../src/components/Validation/ValidationSummary.tsx","../../../src/components/Validation/Validation.tsx"],"sourcesContent":["import React from 'react';\n\nimport { ErrorDetails, FocusableElement } from './types';\nimport AnchorLink, { AnchorLinkOnClickEvent } from '../AnchorLink';\n\ninterface ErrorElementProps {\n name: string;\n error: ErrorDetails;\n}\n\nconst ErrorListItem: React.FC<ErrorElementProps> = props => {\n const handleClick = (event?: AnchorLinkOnClickEvent, element?: FocusableElement): void => {\n event?.preventDefault();\n element?.focus && element?.focus();\n };\n\n if (props.error.ref) {\n return (\n <AnchorLink href={`#${props.name}`} onClick={(e): void => handleClick(e, props.error.ref)}>\n {props.error.message}\n </AnchorLink>\n );\n }\n\n return <>{props.error.message}</>;\n};\n\nexport default ErrorListItem;\n","import React from 'react';\n\nimport ErrorListItem from './ErrorListItem';\nimport { ValidationErrors } from './types';\nimport List from '../List';\n\ninterface ErrorListProps {\n errors: ValidationErrors;\n}\n\nconst ErrorList: React.FC<ErrorListProps> = props => (\n <List>\n {Object.entries(props.errors).map(([name, error]) => (\n <List.Item key={name}>\n <ErrorListItem name={name} error={error} />\n </List.Item>\n ))}\n </List>\n);\n\nexport default ErrorList;\n","import React from 'react';\n\nimport classNames from 'classnames';\n\nimport ErrorList from './ErrorList';\nimport { ValidationErrors } from './types';\nimport { useUuid } from '../../hooks/useUuid';\nimport Title, { TitleTags } from '../Title';\n\nimport styles from './styles.module.scss';\n\ninterface ValidationSummaryProps {\n /** Error summary title */\n errorTitle?: string;\n /** Error list */\n errors?: ValidationErrors;\n /** Markup props for error summary title. Default: h2 */\n errorTitleHtmlMarkup?: TitleTags;\n /** Will be shown last */\n children?: React.ReactNode;\n}\n\nconst ValidationSummary: React.FC<ValidationSummaryProps> = props => {\n const { errorTitleHtmlMarkup = 'h2' } = props;\n const titleId = useUuid();\n\n const hasErrors = !!props.errors && Object.entries(props.errors).length > 0;\n\n const summaryClasses = classNames(styles['validation__summary'], hasErrors && styles['validation__summary--visible']);\n\n return (\n <div\n role={'status'}\n aria-atomic={'true'}\n aria-live={'polite'}\n aria-relevant={'all'}\n aria-labelledby={hasErrors && props.errorTitle ? titleId : undefined}\n className={summaryClasses}\n >\n {hasErrors && (\n <>\n {props.errorTitle && (\n <Title appearance=\"title4\" id={titleId} htmlMarkup={errorTitleHtmlMarkup} margin={{ marginTop: 0, marginBottom: 1 }}>\n {props.errorTitle}\n </Title>\n )}\n <ErrorList errors={props.errors!} />\n </>\n )}\n {props.children}\n </div>\n );\n};\n\nexport default ValidationSummary;\n","import React from 'react';\n\nimport { ValidationErrors } from './types';\nimport ValidationSummary from './ValidationSummary';\nimport { AnalyticsId, FormSize } from '../../constants';\nimport { isComponent, isComponentWithDisplayName } from '../../utils/component';\nimport Checkbox, { CheckboxProps } from '../Checkbox';\nimport { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport FormGroup, { FormGroupProps } from '../FormGroup/FormGroup';\nimport Input, { InputProps } from '../Input';\nimport RadioButton, { RadioButtonProps } from '../RadioButton';\nimport Select, { SelectProps } from '../Select';\nimport Slider, { SliderProps } from '../Slider';\nimport Textarea, { TextareaProps } from '../Textarea';\n\nimport styles from './styles.module.scss';\n\ninterface ValidationProps {\n /** Error summary title */\n errorTitle?: string;\n /** Validation errors. If errors include references to HTML elements, the errors will be rendered as links with an onClick handler to focus the element. */\n errors?: ValidationErrors;\n /** Items in the Validation compontent */\n children?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Changes the visuals of the formgroup */\n size?: keyof typeof FormSize;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const Validation = React.forwardRef((props: ValidationProps, ref: React.ForwardedRef<HTMLDivElement>) => {\n const validationErrorClass = styles['validation__error-wrapper'];\n\n const cloneFormElement = <T extends ErrorWrapperClassNameProps>(child: React.ReactElement<T>): React.ReactElement<T> => {\n return React.cloneElement(child, {\n ...child.props,\n errorWrapperClassName: validationErrorClass,\n });\n };\n\n const renderChild = (child: React.ReactNode): React.ReactNode => {\n if (\n isComponent<FormGroupProps>(child, FormGroup) ||\n isComponent<CheckboxProps>(child, Checkbox) ||\n isComponent<RadioButtonProps>(child, RadioButton) ||\n isComponent<TextareaProps>(child, Textarea) ||\n isComponent<InputProps>(child, Input) ||\n isComponent<SelectProps>(child, Select) ||\n isComponent<SliderProps>(child, Slider) ||\n isComponentWithDisplayName<ErrorWrapperClassNameProps>(child, 'DateTimePickerWrapper') ||\n isComponentWithDisplayName<ErrorWrapperClassNameProps>(child, 'DatePicker') ||\n isComponentWithDisplayName<ErrorWrapperClassNameProps>(child, 'DateTime')\n ) {\n return cloneFormElement<ErrorWrapperClassNameProps>(child);\n }\n if (React.isValidElement(child) && child.type === React.Fragment) {\n return React.Children.map(child.props.children, (child: React.ReactNode) => {\n return renderChild(child);\n });\n }\n\n return child;\n };\n\n return (\n <>\n <div data-testid={props.testId} data-analyticsid={AnalyticsId.Validation} className={props.className} ref={ref}>\n {React.Children.map(props.children, (child: React.ReactNode) => renderChild(child))}\n </div>\n <ValidationSummary errorTitle={props.errorTitle} errors={props.errors} />\n </>\n );\n});\n\nValidation.displayName = 'Validation';\n\nexport default Validation;\n"],"names":["child"],"mappings":"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"}
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "url": "git+https://github.com/helsenorge/designsystem.git"
8
8
  },
9
9
  "homepage": "https://helsenorge.design",
10
- "version": "10.0.0-beta.5",
10
+ "version": "10.0.0",
11
11
  "author": "Helsenorge",
12
12
  "license": "MIT",
13
13
  "dependencies": {