@helsenorge/designsystem-react 13.2.0 → 13.4.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 (53) hide show
  1. package/lib/CHANGELOG.md +33 -0
  2. package/lib/Highlighter.js +7 -7
  3. package/lib/Highlighter.js.map +1 -1
  4. package/lib/Input.js +24 -5
  5. package/lib/Input.js.map +1 -1
  6. package/lib/LazyIcon.js +3 -1
  7. package/lib/LazyIcon.js.map +1 -1
  8. package/lib/LinkList.js.map +1 -1
  9. package/lib/MaxCharacters.js +1 -1
  10. package/lib/MaxCharacters.js.map +1 -1
  11. package/lib/Panel.js +12 -5
  12. package/lib/Panel.js.map +1 -1
  13. package/lib/Slider.js +1 -1
  14. package/lib/Slider.js.map +1 -1
  15. package/lib/Textarea.js +24 -5
  16. package/lib/Textarea.js.map +1 -1
  17. package/lib/components/Dropdown/index.js +2 -1
  18. package/lib/components/Dropdown/index.js.map +1 -1
  19. package/lib/components/Dropdown/styles.module.scss +0 -6
  20. package/lib/components/ElementHeader/ElementHeaderText/index.js +1 -0
  21. package/lib/components/ElementHeader/ElementHeaderText/index.js.map +1 -1
  22. package/lib/components/FormGroup/index.js +1 -1
  23. package/lib/components/Highlighter/index.js +1 -0
  24. package/lib/components/Icons/AdditionalIconInformation.d.ts +10 -2
  25. package/lib/components/Icons/AdditionalIconInformation.js +10 -2
  26. package/lib/components/Icons/AdditionalIconInformation.js.map +1 -1
  27. package/lib/components/Icons/IconNames.d.ts +1 -1
  28. package/lib/components/Icons/IconNames.js +3 -1
  29. package/lib/components/Icons/IconNames.js.map +1 -1
  30. package/lib/components/Icons/ZoomInLeft.d.ts +4 -0
  31. package/lib/components/Icons/ZoomInLeft.js +30 -0
  32. package/lib/components/Icons/ZoomInLeft.js.map +1 -0
  33. package/lib/components/Icons/ZoomOutLeft.d.ts +4 -0
  34. package/lib/components/Icons/ZoomOutLeft.js +30 -0
  35. package/lib/components/Icons/ZoomOutLeft.js.map +1 -0
  36. package/lib/components/Input/Input.d.ts +4 -1
  37. package/lib/components/Input/index.js +1 -1
  38. package/lib/components/Input/resourceHelper.d.ts +3 -0
  39. package/lib/components/LinkList/LinkList.d.ts +1 -1
  40. package/lib/components/LinkList/styles.module.scss +0 -1
  41. package/lib/components/MaxCharacters/MaxCharacters.d.ts +1 -1
  42. package/lib/components/Panel/Panel.d.ts +2 -0
  43. package/lib/components/Panel/PanelTitle/index.js +1 -0
  44. package/lib/components/Textarea/Textarea.d.ts +4 -1
  45. package/lib/components/Textarea/resourceHelper.d.ts +3 -0
  46. package/lib/components/Validation/index.js +1 -1
  47. package/lib/resources/HN.Designsystem.Input.en-GB.json.d.ts +6 -0
  48. package/lib/resources/HN.Designsystem.Input.nb-NO.json.d.ts +6 -0
  49. package/lib/resources/HN.Designsystem.Input.nn-NO.json.d.ts +6 -0
  50. package/lib/resources/HN.Designsystem.TextArea.en-GB.json.d.ts +6 -0
  51. package/lib/resources/HN.Designsystem.TextArea.nb-NO.json.d.ts +6 -0
  52. package/lib/resources/HN.Designsystem.TextArea.nn-NO.json.d.ts +6 -0
  53. package/package.json +1 -1
package/lib/CHANGELOG.md CHANGED
@@ -1,3 +1,36 @@
1
+ ## [13.4.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv13.3.0&targetVersion=GTv13.4.0) (2025-12-18)
2
+
3
+
4
+ ### Features
5
+
6
+ * input og textarea får resources til maxcharacters tekst ([5057563](https://github.com/helsenorge/designsystem/commit/5057563de68c04df119ff8f16063041c05282562)), closes [#365224](https://github.com/helsenorge/designsystem/issues/365224)
7
+ * **formgroup:** fjerner ariadescribedby prop ([9aa55d4](https://github.com/helsenorge/designsystem/commit/9aa55d463caaeff7d715d3d604237a687c25dc1f)), closes [#367262](https://github.com/helsenorge/designsystem/issues/367262)
8
+ * **formgroup:** ny prop ariadescribedby og formfieldtag er koblet med ariadescribedby automatisk ([71569ef](https://github.com/helsenorge/designsystem/commit/71569ef9db0f955b6a06a363b137635703c2f123)), closes [#367262](https://github.com/helsenorge/designsystem/issues/367262)
9
+ * **linklist:** linkref prop kan være null ([b3bd5c1](https://github.com/helsenorge/designsystem/commit/b3bd5c1e5e786908269752cd4ccc672dd81ba88d)), closes [#367039](https://github.com/helsenorge/designsystem/issues/367039)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * **datepicker:** popup vises delvis utenfor skjerm på smal desktop ([1a06d2a](https://github.com/helsenorge/designsystem/commit/1a06d2a27b3902d4fbf89a231ed13085aa1959f6)), closes [#367051](https://github.com/helsenorge/designsystem/issues/367051)
15
+ * **slider:** onclick oppfører seg rart med validering aktivert ([fe2c93a](https://github.com/helsenorge/designsystem/commit/fe2c93a917ce0b54b5f92283fd2340918529e42d)), closes [#357082](https://github.com/helsenorge/designsystem/issues/357082)
16
+
17
+ ## [13.3.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv13.2.0&targetVersion=GTv13.3.0) (2025-12-11)
18
+
19
+
20
+ ### Features
21
+
22
+ * Nye ikon zoominleft zoomoutleft og oppdatert ikonscript ([f7a429d](https://github.com/helsenorge/designsystem/commit/f7a429d2558da965a5fb7259353c7123428b6985)), closes [#365860](https://github.com/helsenorge/designsystem/issues/365860)
23
+ * **panel:** får focusable prop ([0e35f3c](https://github.com/helsenorge/designsystem/commit/0e35f3c787acce1fd19862d069485c8f02a8f8e1)), closes [#366506](https://github.com/helsenorge/designsystem/issues/366506)
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * **dropdown:** dobbel scrollbar på windows med mange elementer ([9b740a9](https://github.com/helsenorge/designsystem/commit/9b740a99cea321edda035b3c7acda377e82ab76c)), closes [#366359](https://github.com/helsenorge/designsystem/issues/366359)
29
+ * **highlighter:** fungerer igjen med duolist ([3f31a76](https://github.com/helsenorge/designsystem/commit/3f31a76176ee73ff5d89dbf6f28c4b517f20a54a)), closes [#366784](https://github.com/helsenorge/designsystem/issues/366784)
30
+ * **highlighter:** mister keys ved bruk med duolist ([550b025](https://github.com/helsenorge/designsystem/commit/550b025486651d9389efc99a42640b7f965f022d)), closes [#366784](https://github.com/helsenorge/designsystem/issues/366784)
31
+ * **linklist:** focus styling skal ikke trigges av museklikk ([8ffc342](https://github.com/helsenorge/designsystem/commit/8ffc342d4bebd321b5c306a2c37bed835f912193)), closes [#366485](https://github.com/helsenorge/designsystem/issues/366485)
32
+ * **panel:** klager på manglende keys på underkomponenter ([611b12d](https://github.com/helsenorge/designsystem/commit/611b12d44d47fb4c35f718006f0661f54a896481)), closes [#366779](https://github.com/helsenorge/designsystem/issues/366779)
33
+
1
34
  ## [13.2.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv13.1.0&targetVersion=GTv13.2.0) (2025-12-04)
2
35
 
3
36
 
@@ -1,4 +1,5 @@
1
1
  import { n as uuid_default } from "./uuid.js";
2
+ import { t as isComponent } from "./component.js";
2
3
  import { r as DuolistGroup } from "./Duolist.js";
3
4
  import React from "react";
4
5
  import { Fragment, jsx } from "react/jsx-runtime";
@@ -22,13 +23,12 @@ const Highlighter = ({ children, searchText }) => {
22
23
  if (typeof node === "string") return replaceWithMarkTag(node);
23
24
  if (React.isValidElement(node)) {
24
25
  const { children: nodeChildren, ...props } = node.props;
25
- if (node.type === DuolistGroup) {
26
- const highlightedTerm = replaceWithMarkTag(node.props.term);
27
- const highlightedDescription = replaceWithMarkTag(node.props.description);
28
- return /* @__PURE__ */ jsx(DuolistGroup, {
29
- ...node.props,
30
- term: highlightedTerm,
31
- description: highlightedDescription
26
+ if (isComponent(node, DuolistGroup)) {
27
+ const term = replaceWithMarkTag(node.props.term);
28
+ const description = replaceWithMarkTag(node.props.description);
29
+ return React.cloneElement(node, {
30
+ term,
31
+ description
32
32
  });
33
33
  }
34
34
  if (!nodeChildren) return node;
@@ -1 +1 @@
1
- {"version":3,"file":"Highlighter.js","names":[],"sources":["../src/components/Highlighter/Highlighter.tsx","../src/components/Highlighter/index.ts"],"sourcesContent":["import React from 'react';\n\nimport uuid from '../../utils/uuid';\nimport { DuolistGroup } from '../Duolist';\n\nimport styles from './styles.module.scss';\n\ninterface HighlightProps {\n children?: React.ReactNode;\n searchText?: string;\n}\n\nexport const Highlighter = ({ children, searchText }: HighlightProps): React.ReactElement | null => {\n if (!searchText) {\n return <>{children}</>;\n }\n\n const highlightRegex = new RegExp(`(${searchText})`, 'i');\n\n const replaceWithMarkTag = (text: string): (string | React.JSX.Element)[] => {\n return text.split(highlightRegex).map(part => {\n if (highlightRegex.test(part)) {\n const id = uuid();\n return (\n <mark key={id} className={styles.highlight}>\n {part}\n </mark>\n );\n }\n return part;\n });\n };\n\n const recursivelyHighlight = (node: React.ReactNode): React.ReactNode => {\n if (typeof node === 'string') {\n return replaceWithMarkTag(node);\n }\n\n if (React.isValidElement(node)) {\n const { children: nodeChildren, ...props } = node.props;\n\n // Handle DuoList specifically\n if (node.type === DuolistGroup) {\n const highlightedTerm = replaceWithMarkTag(node.props.term as string);\n const highlightedDescription = replaceWithMarkTag(node.props.description as string);\n return <DuolistGroup {...node.props} term={highlightedTerm} description={highlightedDescription} />;\n }\n\n if (!nodeChildren) {\n return node;\n }\n\n const highlightedChildren = React.Children.toArray(nodeChildren).map(child => recursivelyHighlight(child));\n return React.cloneElement(node, props, highlightedChildren);\n }\n\n return node;\n };\n\n return <>{React.Children.map(children, recursivelyHighlight)}</>;\n};\n\nexport default Highlighter;\n","import Highlighter from './Highlighter';\nexport * from './Highlighter';\nexport default Highlighter;\n"],"mappings":";;;;;AAYA,MAAa,eAAe,EAAE,UAAU,iBAA4D;AAClG,KAAI,CAAC,WACH,QAAO,oBAAA,UAAA,EAAG,UAAA,CAAY;CAGxB,MAAM,iBAAiB,IAAI,OAAO,IAAI,WAAW,IAAI,IAAI;CAEzD,MAAM,sBAAsB,SAAiD;AAC3E,SAAO,KAAK,MAAM,eAAe,CAAC,KAAI,SAAQ;AAC5C,OAAI,eAAe,KAAK,KAAK,EAAE;IAC7B,MAAM,KAAK,cAAM;AACjB,WACE,oBAAC,QAAA;KAAc,WAAW,OAAO;eAC9B;OADQ,GAEJ;;AAGX,UAAO;IACP;;CAGJ,MAAM,wBAAwB,SAA2C;AACvE,MAAI,OAAO,SAAS,SAClB,QAAO,mBAAmB,KAAK;AAGjC,MAAI,MAAM,eAAe,KAAK,EAAE;GAC9B,MAAM,EAAE,UAAU,cAAc,GAAG,UAAU,KAAK;AAGlD,OAAI,KAAK,SAAS,cAAc;IAC9B,MAAM,kBAAkB,mBAAmB,KAAK,MAAM,KAAe;IACrE,MAAM,yBAAyB,mBAAmB,KAAK,MAAM,YAAsB;AACnF,WAAO,oBAAC,cAAA;KAAa,GAAI,KAAK;KAAO,MAAM;KAAiB,aAAa;MAA0B;;AAGrG,OAAI,CAAC,aACH,QAAO;GAGT,MAAM,sBAAsB,MAAM,SAAS,QAAQ,aAAa,CAAC,KAAI,UAAS,qBAAqB,MAAM,CAAC;AAC1G,UAAO,MAAM,aAAa,MAAM,OAAO,oBAAoB;;AAG7D,SAAO;;AAGT,QAAO,oBAAA,UAAA,EAAA,UAAG,MAAM,SAAS,IAAI,UAAU,qBAAqB,EAAA,CAAI;;ACzDlE,IAAA,wBD4De"}
1
+ {"version":3,"file":"Highlighter.js","names":[],"sources":["../src/components/Highlighter/Highlighter.tsx","../src/components/Highlighter/index.ts"],"sourcesContent":["import React from 'react';\n\nimport { isComponent } from '../../utils/component';\nimport uuid from '../../utils/uuid';\nimport { DuolistGroup, DuolistGroupProps } from '../Duolist';\n\nimport styles from './styles.module.scss';\n\ninterface HighlightProps {\n children?: React.ReactNode;\n searchText?: string;\n}\n\nexport const Highlighter = ({ children, searchText }: HighlightProps): React.ReactElement | null => {\n if (!searchText) {\n return <>{children}</>;\n }\n\n const highlightRegex = new RegExp(`(${searchText})`, 'i');\n\n const replaceWithMarkTag = (text: string): (string | React.JSX.Element)[] => {\n return text.split(highlightRegex).map(part => {\n if (highlightRegex.test(part)) {\n const id = uuid();\n return (\n <mark key={id} className={styles.highlight}>\n {part}\n </mark>\n );\n }\n return part;\n });\n };\n\n const recursivelyHighlight = (node: React.ReactNode): React.ReactNode => {\n if (typeof node === 'string') {\n return replaceWithMarkTag(node);\n }\n\n if (React.isValidElement(node)) {\n const { children: nodeChildren, ...props } = node.props;\n\n // Handle DuoList specifically\n if (isComponent<DuolistGroupProps>(node, DuolistGroup)) {\n const term = replaceWithMarkTag(node.props.term as string);\n const description = replaceWithMarkTag(node.props.description as string);\n return React.cloneElement(node, {\n term,\n description,\n });\n }\n\n if (!nodeChildren) {\n return node;\n }\n\n const highlightedChildren = React.Children.toArray(nodeChildren).map(child => recursivelyHighlight(child));\n return React.cloneElement(node, props, highlightedChildren);\n }\n\n return node;\n };\n\n return <>{React.Children.map(children, recursivelyHighlight)}</>;\n};\n\nexport default Highlighter;\n","import Highlighter from './Highlighter';\nexport * from './Highlighter';\nexport default Highlighter;\n"],"mappings":";;;;;;AAaA,MAAa,eAAe,EAAE,UAAU,iBAA4D;AAClG,KAAI,CAAC,WACH,QAAO,oBAAA,UAAA,EAAG,UAAA,CAAY;CAGxB,MAAM,iBAAiB,IAAI,OAAO,IAAI,WAAW,IAAI,IAAI;CAEzD,MAAM,sBAAsB,SAAiD;AAC3E,SAAO,KAAK,MAAM,eAAe,CAAC,KAAI,SAAQ;AAC5C,OAAI,eAAe,KAAK,KAAK,EAAE;IAC7B,MAAM,KAAK,cAAM;AACjB,WACE,oBAAC,QAAA;KAAc,WAAW,OAAO;eAC9B;OADQ,GAEJ;;AAGX,UAAO;IACP;;CAGJ,MAAM,wBAAwB,SAA2C;AACvE,MAAI,OAAO,SAAS,SAClB,QAAO,mBAAmB,KAAK;AAGjC,MAAI,MAAM,eAAe,KAAK,EAAE;GAC9B,MAAM,EAAE,UAAU,cAAc,GAAG,UAAU,KAAK;AAGlD,OAAI,YAA+B,MAAM,aAAa,EAAE;IACtD,MAAM,OAAO,mBAAmB,KAAK,MAAM,KAAe;IAC1D,MAAM,cAAc,mBAAmB,KAAK,MAAM,YAAsB;AACxE,WAAO,MAAM,aAAa,MAAM;KAC9B;KACA;KACD,CAAC;;AAGJ,OAAI,CAAC,aACH,QAAO;GAGT,MAAM,sBAAsB,MAAM,SAAS,QAAQ,aAAa,CAAC,KAAI,UAAS,qBAAqB,MAAM,CAAC;AAC1G,UAAO,MAAM,aAAa,MAAM,OAAO,oBAAoB;;AAG7D,SAAO;;AAGT,QAAO,oBAAA,UAAA,EAAA,UAAG,MAAM,SAAS,IAAI,UAAU,qBAAqB,EAAA,CAAI;;AC7DlE,IAAA,wBDgEe"}
package/lib/Input.js CHANGED
@@ -1,7 +1,8 @@
1
- import { a as IconSize, i as FormSize, n as AnalyticsId, r as FormOnColor, t as AVERAGE_CHARACTER_WIDTH_PX } from "./constants2.js";
1
+ import { a as IconSize, i as FormSize, n as AnalyticsId, r as FormOnColor, s as LanguageLocales, t as AVERAGE_CHARACTER_WIDTH_PX } from "./constants2.js";
2
2
  import { t as getColor } from "./color.js";
3
3
  import { n as mergeRefs } from "./refs.js";
4
4
  import { t as Icon_default } from "./Icon.js";
5
+ import { r as useLanguage } from "./language.js";
5
6
  import { t as LazyIcon_default } from "./LazyIcon.js";
6
7
  import { n as useBreakpoint, t as Breakpoint } from "./useBreakpoint.js";
7
8
  import { t as useIdWithFallback } from "./useIdWithFallback.js";
@@ -13,6 +14,17 @@ import React, { useEffect, useRef, useState } from "react";
13
14
  import classNames from "classnames";
14
15
  import { jsx, jsxs } from "react/jsx-runtime";
15
16
  import styles from "./components/Input/styles.module.scss";
17
+ var HN_Designsystem_Input_en_GB_default = { characters: "characters" };
18
+ var HN_Designsystem_Input_nb_NO_default = { characters: "tegn" };
19
+ var HN_Designsystem_Input_nn_NO_default = { characters: "teikn" };
20
+ const getResources = (language) => {
21
+ switch (language) {
22
+ case LanguageLocales.ENGLISH: return HN_Designsystem_Input_en_GB_default;
23
+ case LanguageLocales.NORWEGIAN_NYNORSK: return HN_Designsystem_Input_nn_NO_default;
24
+ case LanguageLocales.NORWEGIAN:
25
+ default: return HN_Designsystem_Input_nb_NO_default;
26
+ }
27
+ };
16
28
  let InputTypes = /* @__PURE__ */ function(InputTypes$1) {
17
29
  InputTypes$1["text"] = "text";
18
30
  InputTypes$1["number"] = "number";
@@ -25,13 +37,20 @@ let InputTypes = /* @__PURE__ */ function(InputTypes$1) {
25
37
  InputTypes$1["time"] = "time";
26
38
  return InputTypes$1;
27
39
  }({});
28
- var getInputMaxWidth = (characters, hasIcon, iconSize) => {
40
+ var getInputMaxWidth = (characters$3, hasIcon, iconSize) => {
29
41
  const paddingWidth = hasIcon ? "1.5rem" : "2rem";
30
42
  const iconWidth = hasIcon ? `${iconSize}px` : "0px";
31
- return `calc(${characters * 12}px + ${paddingWidth} + ${iconWidth} + 4px)`;
43
+ return `calc(${characters$3 * 12}px + ${paddingWidth} + ${iconWidth} + 4px)`;
32
44
  };
33
45
  var Input = React.forwardRef((props, ref) => {
34
- const { className, defaultValue, placeholder, type = InputTypes.text, name, transparent = false, icon, iconRight, inputWrapperRef, onColor = FormOnColor.onwhite, size, baseIncrementValue, label, error, errorText, errorTextId: errorTextIdProp, inputId: inputIdProp, errorWrapperClassName, testId, disabled, readOnly, autoComplete = "off", afterInputChildren, rightOfInput, width, required, onChange, onKeyDown, autoFocus, maxCharacters, maxText, inputContainerRef, ...rest } = props;
46
+ const { className, defaultValue, placeholder, type = InputTypes.text, name, transparent = false, icon, iconRight, inputWrapperRef, onColor = FormOnColor.onwhite, size, baseIncrementValue, label, error, errorText, errorTextId: errorTextIdProp, inputId: inputIdProp, errorWrapperClassName, testId, disabled, readOnly, autoComplete = "off", afterInputChildren, rightOfInput, width, required, onChange, onKeyDown, autoFocus, maxCharacters, maxText, inputContainerRef, resources, ...rest } = props;
47
+ const { language } = useLanguage(LanguageLocales.NORWEGIAN);
48
+ const defaultResources = getResources(language);
49
+ const mergedResources = {
50
+ ...defaultResources,
51
+ ...resources,
52
+ characters: maxText || resources?.characters || defaultResources.characters
53
+ };
35
54
  const breakpoint = useBreakpoint();
36
55
  const inputContainerRefLocal = useRef(null);
37
56
  const inputId = useIdWithFallback(inputIdProp);
@@ -157,7 +176,7 @@ var Input = React.forwardRef((props, ref) => {
157
176
  maxCharacters && /* @__PURE__ */ jsx(MaxCharacters_default, {
158
177
  maxCharacters,
159
178
  length: input.toString().length,
160
- maxText,
179
+ maxText: mergedResources.characters,
161
180
  onColor,
162
181
  maxWidth
163
182
  }),
package/lib/Input.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","names":[],"sources":["../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\n\nimport cn from 'classnames';\n\nimport { FormOnColor, FormSize, AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX } from '../../constants';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { getColor } from '../../theme/currys';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { mergeRefs } from '../../utils/refs';\nimport ErrorWrapper, { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport Icon, { IconSize, SvgIcon } from '../Icon';\nimport { IconName } from '../Icons/IconNames';\nimport { renderLabel } from '../Label';\nimport LazyIcon from '../LazyIcon';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\nexport interface InputProps\n extends ErrorWrapperClassNameProps,\n Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'disabled'\n | 'readOnly'\n | 'autoComplete'\n | 'name'\n | 'placeholder'\n | 'defaultValue'\n | 'required'\n | 'value'\n | 'min'\n | 'max'\n | 'aria-describedby'\n | 'aria-labelledby'\n | 'onBlur'\n | 'onClick'\n | 'onChange'\n | 'onFocus'\n | 'onKeyDown'\n | 'autoFocus'\n | 'inputMode'\n > {\n /** The number at which the input field starts when you increment or decrement it */\n baseIncrementValue?: number;\n /** Adds custom classes to the element. */\n className?: string;\n /** HMTL Input type */\n type?: keyof typeof InputTypes;\n /** input id */\n inputId?: string;\n /** Width of input field in characters (approximate) */\n width?: number;\n /** If true, the component will be transparent. */\n transparent?: boolean;\n /** Icon to be displayed next to the input field */\n icon?: SvgIcon | IconName;\n /** Places the icon to the right */\n iconRight?: boolean;\n /** Ref that is placed on the inputContainerRef */\n inputContainerRef?: React.RefObject<HTMLDivElement>;\n /** Ref that is placed on the inputWrapper */\n inputWrapperRef?: React.RefObject<HTMLDivElement>;\n /** Changes the color profile of the input */\n onColor?: keyof typeof FormOnColor;\n /** Changes the visuals of the input */\n size?: keyof typeof FormSize;\n /** Label of the input */\n label?: React.ReactNode;\n /** Activates Error style for the input */\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 /** Component shown after input */\n afterInputChildren?: React.ReactNode;\n /** Component shown to the right of input */\n rightOfInput?: React.ReactNode;\n /** max character limit in input */\n maxCharacters?: number;\n /** The text is displayed in the end of the text-counter */\n maxText?: string;\n}\n\nexport enum InputTypes {\n text = 'text',\n number = 'number',\n email = 'email',\n password = 'password',\n search = 'search',\n tel = 'tel',\n url = 'url',\n date = 'date',\n time = 'time',\n}\n\nconst getInputMaxWidth = (characters: number, hasIcon: boolean, iconSize: number): string => {\n const paddingWidth = hasIcon ? '1.5rem' : '2rem';\n const iconWidth = hasIcon ? `${iconSize}px` : '0px';\n const borderWidth = '4px';\n\n return `calc(${characters * AVERAGE_CHARACTER_WIDTH_PX}px + ${paddingWidth} + ${iconWidth} + ${borderWidth})`;\n};\n\nconst Input = React.forwardRef((props: InputProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n className,\n defaultValue,\n placeholder,\n type = InputTypes.text,\n name,\n transparent = false,\n icon,\n iconRight,\n inputWrapperRef,\n onColor = FormOnColor.onwhite,\n size,\n baseIncrementValue,\n label,\n error,\n errorText,\n errorTextId: errorTextIdProp,\n inputId: inputIdProp,\n errorWrapperClassName,\n testId,\n disabled,\n readOnly,\n autoComplete = 'off',\n afterInputChildren,\n rightOfInput,\n width,\n required,\n onChange,\n onKeyDown,\n autoFocus,\n maxCharacters,\n maxText,\n inputContainerRef,\n ...rest\n } = props;\n const breakpoint = useBreakpoint();\n const inputContainerRefLocal = useRef<HTMLDivElement>(null);\n const inputId = useIdWithFallback(inputIdProp);\n const [input, setInput] = useState(defaultValue || '');\n const [prevValue, setPrevValue] = useState<string | number | undefined>(undefined);\n const numKeyPressed = useRef<boolean>(false);\n const errorTextId = useIdWithFallback(errorTextIdProp);\n const numRegex = /^[0-9]$/;\n\n useEffect(() => {\n setInput(defaultValue || '');\n }, [defaultValue]);\n\n const onDark = onColor === FormOnColor.ondark;\n const onBlueberry = onColor === FormOnColor.onblueberry;\n const maxCharactersExceeded = !!maxCharacters && input.toString().length > maxCharacters;\n const onError = onColor === FormOnColor.oninvalid || !!errorText || !!error || maxCharactersExceeded;\n const isLarge = size === FormSize.large;\n const isTransparent = transparent && onColor !== FormOnColor.ondark && !onError;\n\n const inputWrapperClass = cn(styles['input-wrapper'], className);\n\n const inputContainer = cn(styles['input-container'], {\n [styles['input-container--transparent']]: isTransparent,\n [styles['input-container--on-blueberry']]: onBlueberry,\n [styles['input-container--on-dark']]: onDark,\n [styles['input-container--invalid']]: onError,\n [styles['input-container--disabled']]: disabled,\n [styles['input-container--with-icon']]: icon,\n [styles['input-container--with-icon--right']]: icon && iconRight,\n });\n\n const inputClass = cn(styles['input-container__input'], {\n [styles['input-container__input--large']]: isLarge,\n [styles['input-container__input--disabled']]: disabled,\n });\n\n const iconColor = disabled ? getColor('neutral', 700) : getColor('black');\n const iconSize = breakpoint === Breakpoint.xs || !isLarge ? IconSize.XSmall : IconSize.Small;\n\n const renderIcon = (): React.ReactNode => {\n if (!icon) {\n return;\n }\n\n if (typeof icon === 'string') {\n return <LazyIcon className={styles['input-container__input__icon']} color={iconColor} size={iconSize} iconName={icon} />;\n }\n\n return <Icon className={styles['input-container__input__icon']} color={iconColor} size={iconSize} svgIcon={icon} />;\n };\n\n // eslint-disable-next-line\n const handleClick = (e: React.MouseEvent<any>): void => {\n if (inputContainerRefLocal && inputContainerRefLocal.current && icon) {\n const selectedChild = iconRight ? 0 : 1;\n const input = inputContainerRefLocal.current.children[selectedChild] as HTMLInputElement;\n input.focus();\n\n if (props.onClick) props.onClick(e);\n }\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const newValue = getIncrementValue(e);\n\n if (onChange) {\n onChange(e);\n }\n\n setInput(newValue);\n setPrevValue(newValue);\n };\n\n // Hvis bruker endrer number value med 1 og det skal startes på en annen verdi enn 0\n const getIncrementValue = (e: React.ChangeEvent<HTMLInputElement>): string => {\n if (typeof baseIncrementValue === 'undefined' || type !== 'number') return e.target.value;\n\n const valueAsNumber = Number(e.target.value);\n\n if (!prevValue && !numKeyPressed.current && (valueAsNumber === 1 || valueAsNumber === -1)) {\n e.target.value = baseIncrementValue + '';\n }\n\n return e.target.value;\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (numRegex.test(e.key)) {\n numKeyPressed.current = true;\n }\n if (onKeyDown) onKeyDown(e);\n };\n\n const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (numRegex.test(e.key)) {\n numKeyPressed.current = false;\n }\n };\n\n const maxWidth = width ? getInputMaxWidth(width, !!icon, iconSize) : undefined;\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Input} className={inputWrapperClass} ref={inputWrapperRef}>\n {renderLabel(label, inputId, onColor as FormOnColor)}\n {/* input-elementet tillater keyboard-interaksjon */}\n <div className={styles['content-wrapper']}>\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}\n <div\n onClick={handleClick}\n ref={mergeRefs([inputContainerRefLocal, inputContainerRef])}\n className={inputContainer}\n style={{ maxWidth }}\n >\n {!iconRight && renderIcon()}\n <input\n {...rest}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n name={name}\n type={type}\n defaultValue={defaultValue}\n id={inputId}\n className={inputClass}\n ref={ref}\n aria-describedby={getAriaDescribedBy(props, errorTextId)}\n aria-invalid={!!onError}\n disabled={disabled}\n placeholder={placeholder}\n readOnly={readOnly}\n autoComplete={autoComplete || 'off'}\n required={required}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n />\n {iconRight && renderIcon()}\n </div>\n <div className={styles['content-wrapper__right-of-input']}>{rightOfInput}</div>\n </div>\n {maxCharacters && (\n <MaxCharacters\n maxCharacters={maxCharacters}\n length={input.toString().length}\n maxText={maxText}\n onColor={onColor}\n maxWidth={maxWidth}\n />\n )}\n {afterInputChildren}\n </div>\n </ErrorWrapper>\n );\n});\n\nInput.displayName = 'Input';\n\nexport default Input;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Input.js","names":["mergedResources: HNDesignsystemInput"],"sources":["../src/resources/HN.Designsystem.Input.en-GB.json","../src/resources/HN.Designsystem.Input.nb-NO.json","../src/resources/HN.Designsystem.Input.nn-NO.json","../src/components/Input/resourceHelper.ts","../src/components/Input/Input.tsx"],"sourcesContent":["{\n \"characters\": \"characters\"\n}\n","{\n \"characters\": \"tegn\"\n}\n","{\n \"characters\": \"teikn\"\n}\n","import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Input.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Input.nb-NO.json';\nimport nnNO from '../../resources/HN.Designsystem.Input.nn-NO.json';\nimport { HNDesignsystemInput } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemInput => {\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, useState } from 'react';\n\nimport cn from 'classnames';\n\nimport { getResources } from './resourceHelper';\nimport { FormOnColor, FormSize, AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX, LanguageLocales } from '../../constants';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { HNDesignsystemInput } from '../../resources/Resources';\nimport { getColor } from '../../theme/currys';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { useLanguage } from '../../utils/language';\nimport { mergeRefs } from '../../utils/refs';\nimport ErrorWrapper, { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport Icon, { IconSize, SvgIcon } from '../Icon';\nimport { IconName } from '../Icons/IconNames';\nimport { renderLabel } from '../Label';\nimport LazyIcon from '../LazyIcon';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\nexport interface InputProps\n extends ErrorWrapperClassNameProps,\n Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'disabled'\n | 'readOnly'\n | 'autoComplete'\n | 'name'\n | 'placeholder'\n | 'defaultValue'\n | 'required'\n | 'value'\n | 'min'\n | 'max'\n | 'aria-describedby'\n | 'aria-labelledby'\n | 'onBlur'\n | 'onClick'\n | 'onChange'\n | 'onFocus'\n | 'onKeyDown'\n | 'autoFocus'\n | 'inputMode'\n > {\n /** The number at which the input field starts when you increment or decrement it */\n baseIncrementValue?: number;\n /** Adds custom classes to the element. */\n className?: string;\n /** HMTL Input type */\n type?: keyof typeof InputTypes;\n /** input id */\n inputId?: string;\n /** Width of input field in characters (approximate) */\n width?: number;\n /** If true, the component will be transparent. */\n transparent?: boolean;\n /** Icon to be displayed next to the input field */\n icon?: SvgIcon | IconName;\n /** Places the icon to the right */\n iconRight?: boolean;\n /** Ref that is placed on the inputContainerRef */\n inputContainerRef?: React.RefObject<HTMLDivElement>;\n /** Ref that is placed on the inputWrapper */\n inputWrapperRef?: React.RefObject<HTMLDivElement>;\n /** Changes the color profile of the input */\n onColor?: keyof typeof FormOnColor;\n /** Changes the visuals of the input */\n size?: keyof typeof FormSize;\n /** Label of the input */\n label?: React.ReactNode;\n /** Activates Error style for the input */\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 /** Component shown after input */\n afterInputChildren?: React.ReactNode;\n /** Component shown to the right of input */\n rightOfInput?: React.ReactNode;\n /** max character limit in input */\n maxCharacters?: number;\n /** @deprecated use resources instead. The text is displayed in the end of the text-counter */\n maxText?: string;\n /** Resources for component */\n resources?: Partial<HNDesignsystemInput>;\n}\n\nexport enum InputTypes {\n text = 'text',\n number = 'number',\n email = 'email',\n password = 'password',\n search = 'search',\n tel = 'tel',\n url = 'url',\n date = 'date',\n time = 'time',\n}\n\nconst getInputMaxWidth = (characters: number, hasIcon: boolean, iconSize: number): string => {\n const paddingWidth = hasIcon ? '1.5rem' : '2rem';\n const iconWidth = hasIcon ? `${iconSize}px` : '0px';\n const borderWidth = '4px';\n\n return `calc(${characters * AVERAGE_CHARACTER_WIDTH_PX}px + ${paddingWidth} + ${iconWidth} + ${borderWidth})`;\n};\n\nconst Input = React.forwardRef((props: InputProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n className,\n defaultValue,\n placeholder,\n type = InputTypes.text,\n name,\n transparent = false,\n icon,\n iconRight,\n inputWrapperRef,\n onColor = FormOnColor.onwhite,\n size,\n baseIncrementValue,\n label,\n error,\n errorText,\n errorTextId: errorTextIdProp,\n inputId: inputIdProp,\n errorWrapperClassName,\n testId,\n disabled,\n readOnly,\n autoComplete = 'off',\n afterInputChildren,\n rightOfInput,\n width,\n required,\n onChange,\n onKeyDown,\n autoFocus,\n maxCharacters,\n maxText,\n inputContainerRef,\n resources,\n ...rest\n } = props;\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemInput = {\n ...defaultResources,\n ...resources,\n characters: maxText || resources?.characters || defaultResources.characters,\n };\n\n const breakpoint = useBreakpoint();\n const inputContainerRefLocal = useRef<HTMLDivElement>(null);\n const inputId = useIdWithFallback(inputIdProp);\n const [input, setInput] = useState(defaultValue || '');\n const [prevValue, setPrevValue] = useState<string | number | undefined>(undefined);\n const numKeyPressed = useRef<boolean>(false);\n const errorTextId = useIdWithFallback(errorTextIdProp);\n const numRegex = /^[0-9]$/;\n\n useEffect(() => {\n setInput(defaultValue || '');\n }, [defaultValue]);\n\n const onDark = onColor === FormOnColor.ondark;\n const onBlueberry = onColor === FormOnColor.onblueberry;\n const maxCharactersExceeded = !!maxCharacters && input.toString().length > maxCharacters;\n const onError = onColor === FormOnColor.oninvalid || !!errorText || !!error || maxCharactersExceeded;\n const isLarge = size === FormSize.large;\n const isTransparent = transparent && onColor !== FormOnColor.ondark && !onError;\n\n const inputWrapperClass = cn(styles['input-wrapper'], className);\n\n const inputContainer = cn(styles['input-container'], {\n [styles['input-container--transparent']]: isTransparent,\n [styles['input-container--on-blueberry']]: onBlueberry,\n [styles['input-container--on-dark']]: onDark,\n [styles['input-container--invalid']]: onError,\n [styles['input-container--disabled']]: disabled,\n [styles['input-container--with-icon']]: icon,\n [styles['input-container--with-icon--right']]: icon && iconRight,\n });\n\n const inputClass = cn(styles['input-container__input'], {\n [styles['input-container__input--large']]: isLarge,\n [styles['input-container__input--disabled']]: disabled,\n });\n\n const iconColor = disabled ? getColor('neutral', 700) : getColor('black');\n const iconSize = breakpoint === Breakpoint.xs || !isLarge ? IconSize.XSmall : IconSize.Small;\n\n const renderIcon = (): React.ReactNode => {\n if (!icon) {\n return;\n }\n\n if (typeof icon === 'string') {\n return <LazyIcon className={styles['input-container__input__icon']} color={iconColor} size={iconSize} iconName={icon} />;\n }\n\n return <Icon className={styles['input-container__input__icon']} color={iconColor} size={iconSize} svgIcon={icon} />;\n };\n\n // eslint-disable-next-line\n const handleClick = (e: React.MouseEvent<any>): void => {\n if (inputContainerRefLocal && inputContainerRefLocal.current && icon) {\n const selectedChild = iconRight ? 0 : 1;\n const input = inputContainerRefLocal.current.children[selectedChild] as HTMLInputElement;\n input.focus();\n\n if (props.onClick) props.onClick(e);\n }\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const newValue = getIncrementValue(e);\n\n if (onChange) {\n onChange(e);\n }\n\n setInput(newValue);\n setPrevValue(newValue);\n };\n\n // Hvis bruker endrer number value med 1 og det skal startes på en annen verdi enn 0\n const getIncrementValue = (e: React.ChangeEvent<HTMLInputElement>): string => {\n if (typeof baseIncrementValue === 'undefined' || type !== 'number') return e.target.value;\n\n const valueAsNumber = Number(e.target.value);\n\n if (!prevValue && !numKeyPressed.current && (valueAsNumber === 1 || valueAsNumber === -1)) {\n e.target.value = baseIncrementValue + '';\n }\n\n return e.target.value;\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (numRegex.test(e.key)) {\n numKeyPressed.current = true;\n }\n if (onKeyDown) onKeyDown(e);\n };\n\n const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (numRegex.test(e.key)) {\n numKeyPressed.current = false;\n }\n };\n\n const maxWidth = width ? getInputMaxWidth(width, !!icon, iconSize) : undefined;\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Input} className={inputWrapperClass} ref={inputWrapperRef}>\n {renderLabel(label, inputId, onColor as FormOnColor)}\n {/* input-elementet tillater keyboard-interaksjon */}\n <div className={styles['content-wrapper']}>\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}\n <div\n onClick={handleClick}\n ref={mergeRefs([inputContainerRefLocal, inputContainerRef])}\n className={inputContainer}\n style={{ maxWidth }}\n >\n {!iconRight && renderIcon()}\n <input\n {...rest}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n name={name}\n type={type}\n defaultValue={defaultValue}\n id={inputId}\n className={inputClass}\n ref={ref}\n aria-describedby={getAriaDescribedBy(props, errorTextId)}\n aria-invalid={!!onError}\n disabled={disabled}\n placeholder={placeholder}\n readOnly={readOnly}\n autoComplete={autoComplete || 'off'}\n required={required}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n />\n {iconRight && renderIcon()}\n </div>\n <div className={styles['content-wrapper__right-of-input']}>{rightOfInput}</div>\n </div>\n {maxCharacters && (\n <MaxCharacters\n maxCharacters={maxCharacters}\n length={input.toString().length}\n maxText={mergedResources.characters}\n onColor={onColor}\n maxWidth={maxWidth}\n />\n )}\n {afterInputChildren}\n </div>\n </ErrorWrapper>\n );\n});\n\nInput.displayName = 'Input';\n\nexport default Input;\n"],"mappings":"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"}
package/lib/LazyIcon.js CHANGED
@@ -342,7 +342,9 @@ const lazyLoadIcon = (iconName) => lazy(() => __rolldown_dynamic_import_helper_d
342
342
  "../Icons/XOutline.tsx": () => import("./components/Icons/XOutline.js"),
343
343
  "../Icons/XmlFile.tsx": () => import("./components/Icons/XmlFile.js"),
344
344
  "../Icons/YouTube.tsx": () => import("./components/Icons/YouTube.js"),
345
- "../Icons/Zoom.tsx": () => import("./components/Icons/Zoom.js")
345
+ "../Icons/Zoom.tsx": () => import("./components/Icons/Zoom.js"),
346
+ "../Icons/ZoomInLeft.tsx": () => import("./components/Icons/ZoomInLeft.js"),
347
+ "../Icons/ZoomOutLeft.tsx": () => import("./components/Icons/ZoomOutLeft.js")
346
348
  }, `../Icons/${iconName}.tsx`, 3));
347
349
  const LazyIcon = ({ iconName, size = IconSize.Small, ...rest }) => {
348
350
  const icon = useMemo(() => lazyLoadIcon(iconName), [iconName]);
@@ -1 +1 @@
1
- {"version":3,"file":"LazyIcon.js","names":["LazyIcon: React.FC<LazyIconProps>"],"sources":["../src/components/LazyIcon/LazyIcon.tsx","../src/components/LazyIcon/index.ts"],"sourcesContent":["import React, { lazy, Suspense, useMemo } from 'react';\n\nimport ErrorBoundary from './ErrorBoundary';\nimport { useIsServerSide } from '../../hooks/useIsServerSide';\nimport Icon, { BaseIconProps, IconSize, SvgIcon } from '../Icon';\nimport { IconName } from '../Icons/IconNames';\n\nexport interface LazyIconProps extends BaseIconProps {\n // Navnet på ikonet som skal vises. Tilsvarer filnavnet til ikonet i Icons-mappen\n iconName: IconName;\n}\n\nexport const lazyLoadIcon = (iconName: IconName): React.LazyExoticComponent<SvgIcon> =>\n lazy<SvgIcon>(() => import(`../Icons/${iconName}.tsx`));\n\nexport const LazyIcon: React.FC<LazyIconProps> = ({ iconName, size = IconSize.Small, ...rest }) => {\n const icon = useMemo(() => lazyLoadIcon(iconName), [iconName]);\n const isServerSide = useIsServerSide();\n\n if (isServerSide) {\n return null;\n }\n\n const fallback = (\n <svg\n data-testid={'fallback'}\n role={'presentation'}\n focusable={false}\n aria-hidden={true}\n viewBox=\"0 0 48 48\"\n style={{ minWidth: size, minHeight: size }}\n width={size}\n height={size}\n />\n );\n\n return (\n <ErrorBoundary fallback={fallback} reset={iconName}>\n <Suspense fallback={fallback}>\n <Icon svgIcon={icon} size={size} {...rest} />\n </Suspense>\n </ErrorBoundary>\n );\n};\n\nexport default LazyIcon;\n","import LazyIcon from './LazyIcon';\nexport * from './LazyIcon';\nexport default LazyIcon;\n"],"mappings":";;;;;;AAYA,MAAa,gBAAgB,aAC3B,WAAA,yCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAA2B,YAAY,SAAS,OAAA,EAAA,CAAO;AAEzD,MAAaA,YAAqC,EAAE,UAAU,OAAO,SAAS,OAAO,GAAG,WAAW;CACjG,MAAM,OAAO,cAAc,aAAa,SAAS,EAAE,CAAC,SAAS,CAAC;AAG9D,KAFqB,iBAAiB,CAGpC,QAAO;CAGT,MAAM,WACJ,oBAAC,OAAA;EACC,eAAa;EACb,MAAM;EACN,WAAW;EACX,eAAa;EACb,SAAQ;EACR,OAAO;GAAE,UAAU;GAAM,WAAW;GAAM;EAC1C,OAAO;EACP,QAAQ;GACR;AAGJ,QACE,oBAAC,uBAAA;EAAwB;EAAU,OAAO;YACxC,oBAAC,UAAA;GAAmB;aAClB,oBAAC,cAAA;IAAK,SAAS;IAAY;IAAM,GAAI;KAAQ;IACpC;GACG;;ACvCpB,IAAA,qBD2Ce"}
1
+ {"version":3,"file":"LazyIcon.js","names":["LazyIcon: React.FC<LazyIconProps>"],"sources":["../src/components/LazyIcon/LazyIcon.tsx","../src/components/LazyIcon/index.ts"],"sourcesContent":["import React, { lazy, Suspense, useMemo } from 'react';\n\nimport ErrorBoundary from './ErrorBoundary';\nimport { useIsServerSide } from '../../hooks/useIsServerSide';\nimport Icon, { BaseIconProps, IconSize, SvgIcon } from '../Icon';\nimport { IconName } from '../Icons/IconNames';\n\nexport interface LazyIconProps extends BaseIconProps {\n // Navnet på ikonet som skal vises. Tilsvarer filnavnet til ikonet i Icons-mappen\n iconName: IconName;\n}\n\nexport const lazyLoadIcon = (iconName: IconName): React.LazyExoticComponent<SvgIcon> =>\n lazy<SvgIcon>(() => import(`../Icons/${iconName}.tsx`));\n\nexport const LazyIcon: React.FC<LazyIconProps> = ({ iconName, size = IconSize.Small, ...rest }) => {\n const icon = useMemo(() => lazyLoadIcon(iconName), [iconName]);\n const isServerSide = useIsServerSide();\n\n if (isServerSide) {\n return null;\n }\n\n const fallback = (\n <svg\n data-testid={'fallback'}\n role={'presentation'}\n focusable={false}\n aria-hidden={true}\n viewBox=\"0 0 48 48\"\n style={{ minWidth: size, minHeight: size }}\n width={size}\n height={size}\n />\n );\n\n return (\n <ErrorBoundary fallback={fallback} reset={iconName}>\n <Suspense fallback={fallback}>\n <Icon svgIcon={icon} size={size} {...rest} />\n </Suspense>\n </ErrorBoundary>\n );\n};\n\nexport default LazyIcon;\n","import LazyIcon from './LazyIcon';\nexport * from './LazyIcon';\nexport default LazyIcon;\n"],"mappings":";;;;;;AAYA,MAAa,gBAAgB,aAC3B,WAAA,yCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAA2B,YAAY,SAAS,OAAA,EAAA,CAAO;AAEzD,MAAaA,YAAqC,EAAE,UAAU,OAAO,SAAS,OAAO,GAAG,WAAW;CACjG,MAAM,OAAO,cAAc,aAAa,SAAS,EAAE,CAAC,SAAS,CAAC;AAG9D,KAFqB,iBAAiB,CAGpC,QAAO;CAGT,MAAM,WACJ,oBAAC,OAAA;EACC,eAAa;EACb,MAAM;EACN,WAAW;EACX,eAAa;EACb,SAAQ;EACR,OAAO;GAAE,UAAU;GAAM,WAAW;GAAM;EAC1C,OAAO;EACP,QAAQ;GACR;AAGJ,QACE,oBAAC,uBAAA;EAAwB;EAAU,OAAO;YACxC,oBAAC,UAAA;GAAmB;aAClB,oBAAC,cAAA;IAAK,SAAS;IAAY;IAAM,GAAI;KAAQ;IACpC;GACG;;ACvCpB,IAAA,qBD2Ce"}
@@ -1 +1 @@
1
- {"version":3,"file":"LinkList.js","names":["Link: LinkType","mergedResources: HNDesignsystemLinkList"],"sources":["../src/resources/HN.Designsystem.LinkList.en-GB.json","../src/resources/HN.Designsystem.LinkList.nb-NO.json","../src/components/LinkList/resourceHelper.ts","../src/components/LinkList/LinkList.tsx","../src/components/LinkList/index.ts"],"sourcesContent":["{\n \"editMode_deleteButtonAriaLabel\": \"Delete\"\n}\n","{\n \"editMode_deleteButtonAriaLabel\": \"Slett\"\n}\n","import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.LinkList.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.LinkList.nb-NO.json';\nimport { HNDesignsystemLinkList } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemLinkList => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React from 'react';\n\nimport cn from 'classnames';\n\nimport { AnalyticsId, LanguageLocales } from '../../constants';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { HNDesignsystemLinkList } from '../../resources/Resources';\nimport { PaletteNames } from '../../theme/palette';\nimport { useLanguage } from '../../utils/language';\nimport { ElementHeaderType, renderElementHeader } from '../ElementHeader/ElementHeader';\nimport ChevronRight from '../Icons/ChevronRight';\nimport ListEditModeItem, { ListEditModeItemProps, listEditModeWrapperClassnames } from '../ListEditMode';\nimport { getResources } from './resourceHelper';\n\nimport LinkListStyles from './styles.module.scss';\n\nexport type LinkListSize = 'small' | 'medium' | 'large';\n\nexport type LinkListStatus = 'none' | 'new';\n\nexport type LinkAnchorTargets = '_self' | '_blank' | '_parent';\n\nexport type LinkListColors = Extract<PaletteNames, 'white' | 'blueberry' | 'cherry' | 'neutral'>;\nexport type LinkListVariant = 'line' | 'outline' | 'fill' | 'fill-negative';\n\nexport interface LinkType extends React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLLIElement>> {\n ElementHeader?: ElementHeaderType;\n}\n\nexport type LinkTags = 'button' | 'a';\nexport interface CompoundComponent extends React.ForwardRefExoticComponent<LinkListProps & React.RefAttributes<HTMLUListElement>> {\n Link: LinkType;\n}\n\nexport interface LinkListProps {\n /** Items in the LinkList */\n children: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Changes the colors of the list. */\n color?: LinkListColors;\n /** Toggles chevron icon on or off. */\n chevron?: boolean;\n /** Changes size of the LinkList. */\n size?: LinkListSize;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets visual priority */\n variant?: LinkListVariant;\n /** Highlights text. Used for search results */\n highlightText?: string;\n /**\n * @experimental This prop is experimental and may change in the future.\n * Enables ListEditMode\n */\n editMode?: boolean;\n /** Resources for component */\n resources?: Partial<HNDesignsystemLinkList>;\n}\n\ntype Modify<T, R> = Omit<T, keyof R> & R;\n\nexport type LinkProps = Modify<\n React.HTMLAttributes<HTMLAnchorElement | HTMLButtonElement>,\n {\n children: React.ReactNode;\n chevron?: boolean;\n className?: string;\n icon?: React.ReactElement;\n /** Renders the image in the LinkList header */\n image?: React.ReactElement;\n /** Displays a status on the left side: default none */\n status?: LinkListStatus;\n href?: string;\n target?: LinkAnchorTargets;\n /** HTML markup for link. Default: a */\n htmlMarkup?: LinkTags;\n /**\n * Ref for lenke/knapp\n */\n linkRef?: React.RefObject<HTMLButtonElement | HTMLAnchorElement>;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Highlights text. Override if different from list */\n highlightText?: string;\n /** Resources for component */\n resources?: Partial<HNDesignsystemLinkList>;\n /** @experimental id for content (only used in edit mode for aria-describedby) */\n contentId?: string;\n }\n> &\n Pick<LinkListProps, 'color' | 'size' | 'variant'> &\n ListEditModeItemProps;\n\nexport const Link: LinkType = React.forwardRef((props: LinkProps, ref: React.Ref<HTMLLIElement>) => {\n const {\n children,\n className = '',\n color = 'white',\n icon,\n image,\n size = 'medium',\n chevron = false,\n linkRef,\n status = 'none',\n testId,\n target,\n variant,\n htmlMarkup = 'a',\n highlightText,\n editMode = false,\n contentId,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n resources, // used by ListEditModeItem in LinkList\n ...restProps\n } = props;\n const { refObject, isHovered } = usePseudoClasses<HTMLButtonElement | HTMLAnchorElement>(linkRef);\n\n const isFill = variant === 'fill';\n const isFillNegative = variant === 'fill-negative';\n const isOutline = variant === 'outline';\n const isLine = variant === 'line';\n\n const liClasses = cn(LinkListStyles['link-list'], {\n [LinkListStyles['link-list__list-item--line']]: isLine,\n [LinkListStyles['link-list__list-item--outline']]: isOutline,\n [LinkListStyles[`link-list__list-item--outline--${color}`]]: isOutline,\n });\n const linkClasses = cn(\n LinkListStyles['link-list__anchor'],\n LinkListStyles[`link-list__anchor--${color}`],\n {\n [LinkListStyles[`link-list__anchor--line--${color}`]]: isLine,\n [LinkListStyles['link-list__anchor--fill']]: isFill,\n [LinkListStyles[`link-list__anchor--fill--${color}`]]: isFill,\n [LinkListStyles['link-list__anchor--outline']]: isOutline,\n [LinkListStyles[`link-list__anchor--outline--${color}`]]: isOutline,\n [LinkListStyles['link-list__anchor--fill-negative']]: isFillNegative,\n [LinkListStyles[`link-list__anchor--fill-negative--${color}`]]: isFillNegative,\n [LinkListStyles[`link-list__anchor--${size}`]]: size,\n [LinkListStyles['link-list__anchor--button']]: htmlMarkup === 'button',\n [LinkListStyles['link-list__anchor--new']]: status === 'new',\n },\n className\n );\n\n const statusMarkerClasses = cn(LinkListStyles['link-list__status-marker'], {\n [LinkListStyles['link-list__status-marker--new']]: status === 'new',\n });\n\n const imageContainer = <span className={LinkListStyles['link-list__image-container']}>{image}</span>;\n\n return editMode ? (\n <div id={contentId} className={liClasses} data-testid={testId} data-analyticsid={AnalyticsId.Link}>\n <div className={linkClasses}>\n <div className={statusMarkerClasses}></div>\n {renderElementHeader(children, {\n titleHtmlMarkup: 'span',\n size,\n parentType: 'linklist',\n chevronIcon: chevron ? ChevronRight : undefined,\n icon: icon ?? imageContainer,\n highlightText,\n })}\n </div>\n </div>\n ) : (\n <li className={liClasses} ref={ref} data-testid={testId} data-analyticsid={AnalyticsId.Link}>\n {htmlMarkup === 'a' ? (\n <a\n className={linkClasses}\n ref={refObject as React.RefObject<HTMLAnchorElement>}\n rel={target === '_blank' ? 'noopener noreferrer' : undefined}\n target={target}\n {...restProps}\n >\n <div className={statusMarkerClasses}></div>\n {renderElementHeader(children, {\n titleHtmlMarkup: 'span',\n isHovered,\n size,\n parentType: 'linklist',\n chevronIcon: chevron ? ChevronRight : undefined,\n icon: icon ?? imageContainer,\n highlightText,\n })}\n </a>\n ) : (\n htmlMarkup === 'button' && (\n <button className={linkClasses} ref={refObject as React.RefObject<HTMLButtonElement>} type=\"button\" {...restProps}>\n <div className={statusMarkerClasses}></div>\n {renderElementHeader(children, {\n titleHtmlMarkup: 'span',\n isHovered,\n size,\n parentType: 'linklist',\n chevronIcon: chevron ? ChevronRight : undefined,\n icon: icon ?? imageContainer,\n highlightText,\n })}\n </button>\n )\n )}\n </li>\n );\n});\n\nexport const LinkList = React.forwardRef(function LinkListForwardedRef(props: LinkListProps, ref: React.Ref<HTMLUListElement>) {\n const {\n children,\n className = '',\n chevron = false,\n size = 'medium',\n color = 'white',\n testId,\n variant = 'line',\n highlightText,\n editMode = false,\n resources,\n } = props;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemLinkList = {\n ...defaultResources,\n ...resources,\n };\n\n const listClassNames = cn(LinkListStyles['link-list'], className, {\n [LinkListStyles[`link-list--outline--${color}`]]: variant === 'outline',\n [listEditModeWrapperClassnames]: editMode,\n });\n\n return (\n <ul ref={ref} className={listClassNames} data-testid={testId} data-analyticsid={AnalyticsId.LinkList}>\n {React.Children.map(children, (child: React.ReactNode, index) => {\n if (React.isValidElement<LinkProps>(child) && child.type === Link) {\n if (editMode) {\n const childResources = child.props.resources;\n const deleteAriaLabel = childResources?.editMode_deleteButtonAriaLabel ?? mergedResources.editMode_deleteButtonAriaLabel;\n const itemId = `linklist-item-${index}`;\n\n return (\n <ListEditModeItem\n color={color}\n variant={variant}\n onDelete={child.props.onDelete}\n contentId={itemId}\n deleteButtonAriaLabel={deleteAriaLabel}\n >\n {React.cloneElement(child, {\n color,\n size,\n chevron: false,\n variant,\n highlightText: highlightText,\n editMode: true,\n contentId: itemId,\n })}\n </ListEditModeItem>\n );\n } else {\n return React.cloneElement(child, {\n color,\n size,\n chevron,\n variant,\n highlightText: highlightText,\n editMode: false,\n });\n }\n }\n return null;\n })}\n </ul>\n );\n}) as CompoundComponent;\n\nLinkList.displayName = 'LinkList';\nLinkList.Link = Link;\nLink.displayName = 'LinkList.Link';\n\nexport default LinkList;\n","import LinkList from './LinkList';\nexport * from './LinkList';\nexport default LinkList;\n"],"mappings":"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"}
1
+ {"version":3,"file":"LinkList.js","names":["Link: LinkType","mergedResources: HNDesignsystemLinkList"],"sources":["../src/resources/HN.Designsystem.LinkList.en-GB.json","../src/resources/HN.Designsystem.LinkList.nb-NO.json","../src/components/LinkList/resourceHelper.ts","../src/components/LinkList/LinkList.tsx","../src/components/LinkList/index.ts"],"sourcesContent":["{\n \"editMode_deleteButtonAriaLabel\": \"Delete\"\n}\n","{\n \"editMode_deleteButtonAriaLabel\": \"Slett\"\n}\n","import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.LinkList.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.LinkList.nb-NO.json';\nimport { HNDesignsystemLinkList } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemLinkList => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React from 'react';\n\nimport cn from 'classnames';\n\nimport { AnalyticsId, LanguageLocales } from '../../constants';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { HNDesignsystemLinkList } from '../../resources/Resources';\nimport { PaletteNames } from '../../theme/palette';\nimport { useLanguage } from '../../utils/language';\nimport { ElementHeaderType, renderElementHeader } from '../ElementHeader/ElementHeader';\nimport ChevronRight from '../Icons/ChevronRight';\nimport ListEditModeItem, { ListEditModeItemProps, listEditModeWrapperClassnames } from '../ListEditMode';\nimport { getResources } from './resourceHelper';\n\nimport LinkListStyles from './styles.module.scss';\n\nexport type LinkListSize = 'small' | 'medium' | 'large';\n\nexport type LinkListStatus = 'none' | 'new';\n\nexport type LinkAnchorTargets = '_self' | '_blank' | '_parent';\n\nexport type LinkListColors = Extract<PaletteNames, 'white' | 'blueberry' | 'cherry' | 'neutral'>;\nexport type LinkListVariant = 'line' | 'outline' | 'fill' | 'fill-negative';\n\nexport interface LinkType extends React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLLIElement>> {\n ElementHeader?: ElementHeaderType;\n}\n\nexport type LinkTags = 'button' | 'a';\nexport interface CompoundComponent extends React.ForwardRefExoticComponent<LinkListProps & React.RefAttributes<HTMLUListElement>> {\n Link: LinkType;\n}\n\nexport interface LinkListProps {\n /** Items in the LinkList */\n children: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Changes the colors of the list. */\n color?: LinkListColors;\n /** Toggles chevron icon on or off. */\n chevron?: boolean;\n /** Changes size of the LinkList. */\n size?: LinkListSize;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets visual priority */\n variant?: LinkListVariant;\n /** Highlights text. Used for search results */\n highlightText?: string;\n /**\n * @experimental This prop is experimental and may change in the future.\n * Enables ListEditMode\n */\n editMode?: boolean;\n /** Resources for component */\n resources?: Partial<HNDesignsystemLinkList>;\n}\n\ntype Modify<T, R> = Omit<T, keyof R> & R;\n\nexport type LinkProps = Modify<\n React.HTMLAttributes<HTMLAnchorElement | HTMLButtonElement>,\n {\n children: React.ReactNode;\n chevron?: boolean;\n className?: string;\n icon?: React.ReactElement;\n /** Renders the image in the LinkList header */\n image?: React.ReactElement;\n /** Displays a status on the left side: default none */\n status?: LinkListStatus;\n href?: string;\n target?: LinkAnchorTargets;\n /** HTML markup for link. Default: a */\n htmlMarkup?: LinkTags;\n /**\n * Ref for lenke/knapp\n */\n linkRef?: React.RefObject<HTMLButtonElement | HTMLAnchorElement> | null;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Highlights text. Override if different from list */\n highlightText?: string;\n /** Resources for component */\n resources?: Partial<HNDesignsystemLinkList>;\n /** @experimental id for content (only used in edit mode for aria-describedby) */\n contentId?: string;\n }\n> &\n Pick<LinkListProps, 'color' | 'size' | 'variant'> &\n ListEditModeItemProps;\n\nexport const Link: LinkType = React.forwardRef((props: LinkProps, ref: React.Ref<HTMLLIElement>) => {\n const {\n children,\n className = '',\n color = 'white',\n icon,\n image,\n size = 'medium',\n chevron = false,\n linkRef,\n status = 'none',\n testId,\n target,\n variant,\n htmlMarkup = 'a',\n highlightText,\n editMode = false,\n contentId,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n resources, // used by ListEditModeItem in LinkList\n ...restProps\n } = props;\n const { refObject, isHovered } = usePseudoClasses<HTMLButtonElement | HTMLAnchorElement>(linkRef);\n\n const isFill = variant === 'fill';\n const isFillNegative = variant === 'fill-negative';\n const isOutline = variant === 'outline';\n const isLine = variant === 'line';\n\n const liClasses = cn(LinkListStyles['link-list'], {\n [LinkListStyles['link-list__list-item--line']]: isLine,\n [LinkListStyles['link-list__list-item--outline']]: isOutline,\n [LinkListStyles[`link-list__list-item--outline--${color}`]]: isOutline,\n });\n const linkClasses = cn(\n LinkListStyles['link-list__anchor'],\n LinkListStyles[`link-list__anchor--${color}`],\n {\n [LinkListStyles[`link-list__anchor--line--${color}`]]: isLine,\n [LinkListStyles['link-list__anchor--fill']]: isFill,\n [LinkListStyles[`link-list__anchor--fill--${color}`]]: isFill,\n [LinkListStyles['link-list__anchor--outline']]: isOutline,\n [LinkListStyles[`link-list__anchor--outline--${color}`]]: isOutline,\n [LinkListStyles['link-list__anchor--fill-negative']]: isFillNegative,\n [LinkListStyles[`link-list__anchor--fill-negative--${color}`]]: isFillNegative,\n [LinkListStyles[`link-list__anchor--${size}`]]: size,\n [LinkListStyles['link-list__anchor--button']]: htmlMarkup === 'button',\n [LinkListStyles['link-list__anchor--new']]: status === 'new',\n },\n className\n );\n\n const statusMarkerClasses = cn(LinkListStyles['link-list__status-marker'], {\n [LinkListStyles['link-list__status-marker--new']]: status === 'new',\n });\n\n const imageContainer = <span className={LinkListStyles['link-list__image-container']}>{image}</span>;\n\n return editMode ? (\n <div id={contentId} className={liClasses} data-testid={testId} data-analyticsid={AnalyticsId.Link}>\n <div className={linkClasses}>\n <div className={statusMarkerClasses}></div>\n {renderElementHeader(children, {\n titleHtmlMarkup: 'span',\n size,\n parentType: 'linklist',\n chevronIcon: chevron ? ChevronRight : undefined,\n icon: icon ?? imageContainer,\n highlightText,\n })}\n </div>\n </div>\n ) : (\n <li className={liClasses} ref={ref} data-testid={testId} data-analyticsid={AnalyticsId.Link}>\n {htmlMarkup === 'a' ? (\n <a\n className={linkClasses}\n ref={refObject as React.RefObject<HTMLAnchorElement>}\n rel={target === '_blank' ? 'noopener noreferrer' : undefined}\n target={target}\n {...restProps}\n >\n <div className={statusMarkerClasses}></div>\n {renderElementHeader(children, {\n titleHtmlMarkup: 'span',\n isHovered,\n size,\n parentType: 'linklist',\n chevronIcon: chevron ? ChevronRight : undefined,\n icon: icon ?? imageContainer,\n highlightText,\n })}\n </a>\n ) : (\n htmlMarkup === 'button' && (\n <button className={linkClasses} ref={refObject as React.RefObject<HTMLButtonElement>} type=\"button\" {...restProps}>\n <div className={statusMarkerClasses}></div>\n {renderElementHeader(children, {\n titleHtmlMarkup: 'span',\n isHovered,\n size,\n parentType: 'linklist',\n chevronIcon: chevron ? ChevronRight : undefined,\n icon: icon ?? imageContainer,\n highlightText,\n })}\n </button>\n )\n )}\n </li>\n );\n});\n\nexport const LinkList = React.forwardRef(function LinkListForwardedRef(props: LinkListProps, ref: React.Ref<HTMLUListElement>) {\n const {\n children,\n className = '',\n chevron = false,\n size = 'medium',\n color = 'white',\n testId,\n variant = 'line',\n highlightText,\n editMode = false,\n resources,\n } = props;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemLinkList = {\n ...defaultResources,\n ...resources,\n };\n\n const listClassNames = cn(LinkListStyles['link-list'], className, {\n [LinkListStyles[`link-list--outline--${color}`]]: variant === 'outline',\n [listEditModeWrapperClassnames]: editMode,\n });\n\n return (\n <ul ref={ref} className={listClassNames} data-testid={testId} data-analyticsid={AnalyticsId.LinkList}>\n {React.Children.map(children, (child: React.ReactNode, index) => {\n if (React.isValidElement<LinkProps>(child) && child.type === Link) {\n if (editMode) {\n const childResources = child.props.resources;\n const deleteAriaLabel = childResources?.editMode_deleteButtonAriaLabel ?? mergedResources.editMode_deleteButtonAriaLabel;\n const itemId = `linklist-item-${index}`;\n\n return (\n <ListEditModeItem\n color={color}\n variant={variant}\n onDelete={child.props.onDelete}\n contentId={itemId}\n deleteButtonAriaLabel={deleteAriaLabel}\n >\n {React.cloneElement(child, {\n color,\n size,\n chevron: false,\n variant,\n highlightText: highlightText,\n editMode: true,\n contentId: itemId,\n })}\n </ListEditModeItem>\n );\n } else {\n return React.cloneElement(child, {\n color,\n size,\n chevron,\n variant,\n highlightText: highlightText,\n editMode: false,\n });\n }\n }\n return null;\n })}\n </ul>\n );\n}) as CompoundComponent;\n\nLinkList.displayName = 'LinkList';\nLinkList.Link = Link;\nLink.displayName = 'LinkList.Link';\n\nexport default LinkList;\n","import LinkList from './LinkList';\nexport * from './LinkList';\nexport default LinkList;\n"],"mappings":"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"}
@@ -15,7 +15,7 @@ var MaxCharacters = ({ maxCharacters, maxText, length, onColor, maxWidth }) => {
15
15
  "aria-atomic": "true",
16
16
  className: counterTextClass,
17
17
  style: { maxWidth },
18
- children: `${length}/${maxCharacters} ${maxText ? maxText : "tegn"}`
18
+ children: `${length}/${maxCharacters} ${maxText}`
19
19
  });
20
20
  };
21
21
  var MaxCharacters_default = MaxCharacters;
@@ -1 +1 @@
1
- {"version":3,"file":"MaxCharacters.js","names":["MaxCharacters: React.FC<MaxCharactersProps>"],"sources":["../src/components/MaxCharacters/MaxCharacters.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { FormOnColor } from '../../constants';\n\nimport styles from './styles.module.scss';\n\ninterface MaxCharactersProps {\n /** Current input length */\n length: number;\n /** max character limit in textarea */\n maxCharacters: number;\n /** The text is displayed in the end of the text-counter */\n maxText?: string;\n /** Changes the visuals of the textarea */\n onColor?: keyof typeof FormOnColor;\n /** Max width of the component */\n maxWidth?: string;\n}\n\nconst MaxCharacters: React.FC<MaxCharactersProps> = ({ maxCharacters, maxText, length, onColor, maxWidth }) => {\n const progress = length / maxCharacters;\n\n const counterTextClass = classNames(styles['max-characters'], {\n [styles[`max-characters--on-dark`]]: onColor === FormOnColor.ondark,\n [styles[`max-characters--invalid`]]: progress > 1,\n });\n\n const ariaLevel = progress > 0.95 ? 'polite' : 'off';\n\n return (\n <div aria-live={ariaLevel} aria-atomic={'true'} className={counterTextClass} style={{ maxWidth }}>\n {`${length}/${maxCharacters} ${maxText ? maxText : 'tegn'}`}\n </div>\n );\n};\n\nexport default MaxCharacters;\n"],"mappings":";;;;;AAqBA,IAAMA,iBAA+C,EAAE,eAAe,SAAS,QAAQ,SAAS,eAAe;CAC7G,MAAM,WAAW,SAAS;CAE1B,MAAM,mBAAmB,WAAW,OAAO,mBAAmB;GAC3D,OAAO,6BAA6B,YAAY,YAAY;GAC5D,OAAO,6BAA6B,WAAW;EACjD,CAAC;CAEF,MAAM,YAAY,WAAW,MAAO,WAAW;AAE/C,QACE,oBAAC,OAAA;EAAI,aAAW;EAAW,eAAa;EAAQ,WAAW;EAAkB,OAAO,EAAE,UAAU;YAC7F,GAAG,OAAO,GAAG,cAAc,GAAG,UAAU,UAAU;GAC/C;;AAIV,IAAA,wBAAe"}
1
+ {"version":3,"file":"MaxCharacters.js","names":["MaxCharacters: React.FC<MaxCharactersProps>"],"sources":["../src/components/MaxCharacters/MaxCharacters.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { FormOnColor } from '../../constants';\n\nimport styles from './styles.module.scss';\n\ninterface MaxCharactersProps {\n /** Current input length */\n length: number;\n /** max character limit in textarea */\n maxCharacters: number;\n /** The text is displayed in the end of the text-counter */\n maxText: string;\n /** Changes the visuals of the textarea */\n onColor?: keyof typeof FormOnColor;\n /** Max width of the component */\n maxWidth?: string;\n}\n\nconst MaxCharacters: React.FC<MaxCharactersProps> = ({ maxCharacters, maxText, length, onColor, maxWidth }) => {\n const progress = length / maxCharacters;\n\n const counterTextClass = classNames(styles['max-characters'], {\n [styles[`max-characters--on-dark`]]: onColor === FormOnColor.ondark,\n [styles[`max-characters--invalid`]]: progress > 1,\n });\n\n const ariaLevel = progress > 0.95 ? 'polite' : 'off';\n\n return (\n <div aria-live={ariaLevel} aria-atomic={'true'} className={counterTextClass} style={{ maxWidth }}>\n {`${length}/${maxCharacters} ${maxText}`}\n </div>\n );\n};\n\nexport default MaxCharacters;\n"],"mappings":";;;;;AAqBA,IAAMA,iBAA+C,EAAE,eAAe,SAAS,QAAQ,SAAS,eAAe;CAC7G,MAAM,WAAW,SAAS;CAE1B,MAAM,mBAAmB,WAAW,OAAO,mBAAmB;GAC3D,OAAO,6BAA6B,YAAY,YAAY;GAC5D,OAAO,6BAA6B,WAAW;EACjD,CAAC;CAEF,MAAM,YAAY,WAAW,MAAO,WAAW;AAE/C,QACE,oBAAC,OAAA;EAAI,aAAW;EAAW,eAAa;EAAQ,WAAW;EAAkB,OAAO,EAAE,UAAU;YAC7F,GAAG,OAAO,GAAG,cAAc,GAAG;GAC3B;;AAIV,IAAA,wBAAe"}
package/lib/Panel.js CHANGED
@@ -66,7 +66,7 @@ var ExpandButton = ({ onClick, isExpanded, resources }) => {
66
66
  }), /* @__PURE__ */ jsx("span", { children: isExpanded ? resources.expandButtonClose : resources.expandButtonOpen })]
67
67
  });
68
68
  };
69
- var PanelRoot = React.forwardRef(function PanelForwardedRef({ layout = PanelLayout.vertical, variant = PanelVariant.fill, color = "neutral", stacking = PanelStacking.default, testId, children, expanded = false, status = PanelStatus.none, buttonBottomAriaLabel, buttonBottomOnClick, buttonBottomText, className, resources, onExpand, highlightText }, ref) {
69
+ var PanelRoot = React.forwardRef(function PanelForwardedRef({ layout = PanelLayout.vertical, variant = PanelVariant.fill, color = "neutral", stacking = PanelStacking.default, testId, children, expanded = false, focusable, status = PanelStatus.none, buttonBottomAriaLabel, buttonBottomOnClick, buttonBottomText, className, resources, onExpand, highlightText }, ref) {
70
70
  const [preContainer, setPreContainer] = React.useState([]);
71
71
  const [title, setTitle] = React.useState([]);
72
72
  const [content, setContent] = React.useState([]);
@@ -83,6 +83,7 @@ var PanelRoot = React.forwardRef(function PanelForwardedRef({ layout = PanelLayo
83
83
  ...resources
84
84
  };
85
85
  React.useEffect(() => {
86
+ let index = 0;
86
87
  let localHasIcon = false;
87
88
  const newPreContainer = [];
88
89
  const newTitle = [];
@@ -90,12 +91,16 @@ var PanelRoot = React.forwardRef(function PanelForwardedRef({ layout = PanelLayo
90
91
  const newExpandableContent = [];
91
92
  React.Children.forEach(children, (child) => {
92
93
  if (React.isValidElement(child)) {
93
- if (child.type === PreContainer) newPreContainer.push(child);
94
+ const key = child.key ?? `panel-child-${index++}`;
95
+ if (child.type === PreContainer) newPreContainer.push(React.cloneElement(child, { key }));
94
96
  else if (child.type === PanelTitle_default) {
95
- newTitle.push(React.cloneElement(child, { highlightText: child.props.highlightText || highlightText }));
97
+ newTitle.push(React.cloneElement(child, {
98
+ key,
99
+ highlightText: child.props.highlightText || highlightText
100
+ }));
96
101
  if (child.props.icon) localHasIcon = true;
97
- } else if (child.type === A || child.type === B || child.type === C) newContent.push(child);
98
- else if (child.type === ExpandedContent) newExpandableContent.push(child);
102
+ } else if (child.type === A || child.type === B || child.type === C) newContent.push(React.cloneElement(child, { key }));
103
+ else if (child.type === ExpandedContent) newExpandableContent.push(React.cloneElement(child, { key }));
99
104
  }
100
105
  });
101
106
  setPreContainer(newPreContainer);
@@ -155,6 +160,7 @@ var PanelRoot = React.forwardRef(function PanelForwardedRef({ layout = PanelLayo
155
160
  className: panelClassnames,
156
161
  "data-testid": testId,
157
162
  ref: panelRef,
163
+ tabIndex: focusable ? -1 : void 0,
158
164
  children: [
159
165
  /* @__PURE__ */ jsxs(Highlighter_default, {
160
166
  searchText: highlightText,
@@ -192,6 +198,7 @@ var PanelRoot = React.forwardRef(function PanelForwardedRef({ layout = PanelLayo
192
198
  className: panelClassnames,
193
199
  "data-testid": testId,
194
200
  ref: panelRef,
201
+ tabIndex: focusable ? -1 : void 0,
195
202
  children: [
196
203
  /* @__PURE__ */ jsxs(Highlighter_default, {
197
204
  searchText: highlightText,
package/lib/Panel.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.js","names":["mergedResources: HNDesignsystemPanel","newPreContainer: React.ReactNode[]","newTitle: React.ReactNode[]","newContent: React.ReactNode[]","newExpandableContent: React.ReactNode[]","PreContainer: React.FC<ContentProps>","A: React.FC<ContentProps>","B: React.FC<ContentProps>","C: React.FC<ContentProps>","ExpandedContent: React.FC<ContentProps>"],"sources":["../src/resources/HN.Designsystem.Panel.en-GB.json","../src/resources/HN.Designsystem.Panel.nb-NO.json","../src/components/Panel/resourceHelper.ts","../src/components/Panel/Panel.tsx"],"sourcesContent":["{\n \"expandButtonOpen\": \"See details\",\n \"expandButtonClose\": \"Hide details\"\n}\n","{\n \"expandButtonOpen\": \"Se detaljer\",\n \"expandButtonClose\": \"Skjul detaljer\"\n}\n","import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Panel.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Panel.nb-NO.json';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemPanel => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { LanguageLocales } from '../../constants';\nimport { useExpand } from '../../hooks/useExpand';\nimport { PaletteNames } from '../../theme/palette';\nimport Button from '../Button';\nimport Icon, { IconSize } from '../Icon';\nimport PanelTitle, { PanelTitleProps } from './PanelTitle';\nimport { getResources } from './resourceHelper';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\nimport { useLanguage } from '../../utils/language';\nimport Highlighter from '../Highlighter';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronRight from '../Icons/ChevronRight';\nimport ChevronUp from '../Icons/ChevronUp';\n\nimport styles from './styles.module.scss';\n\nexport enum PanelLayout {\n vertical = 'vertical',\n horizontal = 'horizontal',\n combined = 'combined',\n bAsRightCol = 'bAsRightCol',\n}\n\nexport type PanelColors = Extract<PaletteNames, 'white' | 'neutral'>;\n\nexport enum PanelVariant {\n fill = 'fill',\n line = 'line',\n outline = 'outline',\n}\n\nexport enum PanelStacking {\n default = 'default',\n bFirst = 'bFirst',\n}\n\nexport enum PanelStatus {\n none = 'none',\n new = 'new',\n error = 'error',\n draft = 'draft',\n}\n\nexport interface PanelProps {\n /** Aria label on call to action button */\n buttonBottomAriaLabel?: string;\n /** Sets the text on the bottom call to action button */\n buttonBottomText?: string;\n /** Sets the action on the bottom call to action button */\n buttonBottomOnClick?: () => void;\n /** Expands or collapses the panel. Only applicable when ExpandedContent is used */\n expanded?: boolean;\n /** Sets the layout and order of the content boxes */\n layout?: PanelLayout;\n /** Sets the visual variant of panel */\n variant?: PanelVariant;\n /** Sets the color for panel if it has variant fill */\n color?: PanelColors;\n /** Sets classes on the outermost container of the panel */\n className?: string;\n /** Action called when toggling expansion of ExpandedContent */\n onExpand?: (isExpanded?: boolean) => void;\n /** Sets the stacking order of the content boxes */\n stacking?: PanelStacking;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Children elements to be rendered inside the panel */\n children?: React.ReactNode;\n /** Displays a status on the left side: default normal */\n status?: PanelStatus;\n /** Resources for component */\n resources?: Partial<HNDesignsystemPanel>;\n /** Highlights text in title and content. Used for search results */\n highlightText?: string;\n}\n\nconst ExpandButton = ({\n onClick,\n isExpanded,\n resources,\n}: {\n onClick: () => void;\n isExpanded: boolean | undefined;\n resources: Partial<HNDesignsystemPanel>;\n}): React.JSX.Element => {\n const buttonClassName = classNames(styles['expander__button'], isExpanded && styles['expander__button--expanded']);\n\n return (\n <Button\n variant=\"borderless\"\n textClassName={styles['expander__button__text']}\n wrapperClassName={buttonClassName}\n aria-expanded={isExpanded}\n onClick={onClick}\n >\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} />\n <span>{isExpanded ? resources.expandButtonClose : resources.expandButtonOpen}</span>\n </Button>\n );\n};\nconst PanelRoot = React.forwardRef(function PanelForwardedRef(\n {\n layout = PanelLayout.vertical,\n variant = PanelVariant.fill,\n color = 'neutral',\n stacking = PanelStacking.default,\n testId,\n children,\n expanded = false,\n status = PanelStatus.none,\n buttonBottomAriaLabel,\n buttonBottomOnClick,\n buttonBottomText,\n className,\n resources,\n onExpand,\n highlightText,\n }: PanelProps,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const [preContainer, setPreContainer] = React.useState<React.ReactNode[]>([]);\n const [title, setTitle] = React.useState<React.ReactNode[]>([]);\n const [content, setContent] = React.useState<React.ReactNode[]>([]);\n const [expandableContent, setExpandableContent] = React.useState<React.ReactNode[]>([]);\n const [hasIcon, setHasIcon] = React.useState(false);\n const [isExpanded, setIsExpanded] = useExpand(expanded, onExpand);\n const localRef = React.useRef<HTMLDivElement>(null);\n const panelRef = ref ?? localRef;\n const expandedContentRef = React.useRef<HTMLDivElement>(null);\n const defaultScroll = 100;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemPanel = {\n ...defaultResources,\n ...resources,\n };\n\n React.useEffect(() => {\n let localHasIcon = false;\n const newPreContainer: React.ReactNode[] = [];\n const newTitle: React.ReactNode[] = [];\n const newContent: React.ReactNode[] = [];\n const newExpandableContent: React.ReactNode[] = [];\n\n React.Children.forEach(children, child => {\n if (React.isValidElement(child)) {\n if (child.type === PreContainer) {\n newPreContainer.push(child);\n } else if (child.type === PanelTitle) {\n newTitle.push(\n React.cloneElement(child as React.ReactElement<PanelTitleProps>, { highlightText: child.props.highlightText || highlightText })\n );\n if (child.props.icon) {\n localHasIcon = true;\n }\n } else if (child.type === A || child.type === B || child.type === C) {\n newContent.push(child);\n } else if (child.type === ExpandedContent) {\n newExpandableContent.push(child);\n }\n }\n });\n\n setPreContainer(newPreContainer);\n setTitle(newTitle);\n setContent(newContent);\n setExpandableContent(newExpandableContent);\n setHasIcon(localHasIcon);\n }, [children]);\n\n React.useEffect(() => {\n if (expanded) {\n // Hvis panel åpnes controlled skal ikke scroll skje\n return;\n }\n // Scroller oppover når expanded content åpnes uncontrolled\n if (isExpanded) {\n if ('current' in panelRef && panelRef.current && expandedContentRef.current) {\n const panelRect = panelRef.current.getBoundingClientRect();\n const expandedContentRect = expandedContentRef.current.getBoundingClientRect();\n\n const scrollAmount = Math.min(defaultScroll, panelRect.top - 20);\n\n // Scroller kun oppover, og kun dersom expandedContent havner utenfor skjermen når åpnet\n if (scrollAmount > 0 && expandedContentRect.bottom > window.innerHeight) {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n return;\n }\n window.scrollBy({\n top: scrollAmount,\n behavior: 'smooth',\n });\n }\n }\n }\n }, [isExpanded]);\n\n const colorScheme = variant === PanelVariant.fill ? color : 'white';\n\n const outerClassnames = classNames(className, {\n [styles['panel__border--outline--outer']]: variant === PanelVariant.outline,\n [styles['panel__border--line']]: variant === PanelVariant.line,\n [styles['panel__border--fill--neutral']]: variant === PanelVariant.fill && colorScheme === 'neutral',\n [styles['panel__border--fill--new']]: variant === PanelVariant.fill && status === PanelStatus.new,\n [styles['panel__border--fill--status']]: variant === PanelVariant.fill && status !== PanelStatus.none,\n });\n const panelClassnames = classNames(styles['panel'], styles[`panel--${colorScheme}`], styles['panel--status'], {\n [styles['panel--line']]: variant === PanelVariant.line,\n [styles['panel--new']]: status === PanelStatus.new,\n [styles['panel--draft']]: status === PanelStatus.draft,\n [styles['panel--error']]: status === PanelStatus.error,\n [styles['panel--icon']]: hasIcon,\n });\n const contentContainerLayout = classNames(styles['panel__content'], styles[`panel__content--${layout}`], {\n [styles[`panel__content--b-first`]]: stacking === PanelStacking.bFirst,\n });\n const expanderBorderLayout = classNames({\n [styles['panel__expander__border--expanded']]: isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--${colorScheme}`]]: !isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--line`]]: !isExpanded && status === PanelStatus.none && variant === PanelVariant.line,\n });\n\n const handleExpandClick = (): void => {\n setIsExpanded(!isExpanded);\n };\n\n return expandableContent.length > 0 ? (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={expanderBorderLayout}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n <ExpandButton onClick={handleExpandClick} isExpanded={isExpanded} resources={mergedResources} />\n {isExpanded && (\n <div ref={expandedContentRef} data-testid={testId + '-details'}>\n <div className={styles['panel__expander__separator']} />\n <Highlighter searchText={highlightText}>{expandableContent}</Highlighter>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n ) : (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n {buttonBottomText && buttonBottomOnClick && (\n <div className={styles['panel__button-bottom']}>\n <Button variant=\"borderless\" type=\"button\" size=\"medium\" onClick={buttonBottomOnClick} aria-label={buttonBottomAriaLabel}>\n {buttonBottomText}\n <Icon svgIcon={ChevronRight} size={IconSize.XSmall} />\n </Button>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nexport interface ContentProps {\n /** Children elements to be rendered inside the content box */\n children?: React.ReactNode;\n}\n\nexport const PreContainer: React.FC<ContentProps> = ({ children }) => {\n return <div className={styles['panel__pre-container']}>{children}</div>;\n};\n\nexport const A: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--a']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const B: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--b']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const C: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--c']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const ExpandedContent: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__expander__content']);\n return <div className={styling}>{children}</div>;\n};\n\ntype PanelComponent = typeof PanelRoot & {\n PreContainer: React.FC<ContentProps>;\n Title: React.FC<PanelTitleProps>;\n A: React.FC<ContentProps>;\n B: React.FC<ContentProps>;\n C: React.FC<ContentProps>;\n ExpandedContent: React.FC<ContentProps>;\n};\nPanelRoot.displayName = 'Panel';\nconst Panel = PanelRoot as PanelComponent;\nPanel.PreContainer = PreContainer;\nPanel.Title = PanelTitle;\nPanel.A = A;\nPanel.B = B;\nPanel.C = C;\nPanel.ExpandedContent = ExpandedContent;\n\nexport default Panel;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AEKA,MAAa,gBAAgB,aAAmD;AAC9E,SAAQ,UAAR;EACE,KAAK,gBAAgB,QACnB,QAAO;EACT,KAAK,gBAAgB;EACrB,QACE,QAAO;;;ACSb,IAAY,cAAA,yBAAA,eAAL;AACL,eAAA,cAAA;AACA,eAAA,gBAAA;AACA,eAAA,cAAA;AACA,eAAA,iBAAA;;;AAKF,IAAY,eAAA,yBAAA,gBAAL;AACL,gBAAA,UAAA;AACA,gBAAA,UAAA;AACA,gBAAA,aAAA;;;AAGF,IAAY,gBAAA,yBAAA,iBAAL;AACL,iBAAA,aAAA;AACA,iBAAA,YAAA;;;AAGF,IAAY,cAAA,yBAAA,eAAL;AACL,eAAA,UAAA;AACA,eAAA,SAAA;AACA,eAAA,WAAA;AACA,eAAA,WAAA;;;AAoCF,IAAM,gBAAgB,EACpB,SACA,YACA,gBAKuB;CACvB,MAAM,kBAAkB,WAAW,OAAO,qBAAqB,cAAc,OAAO,8BAA8B;AAElH,QACE,qBAAC,gBAAA;EACC,SAAQ;EACR,eAAe,OAAO;EACtB,kBAAkB;EAClB,iBAAe;EACN;aAET,oBAAC,cAAA;GAAK,SAAS,aAAa,oBAAY;GAAa,MAAM,SAAS;IAAU,EAC9E,oBAAC,QAAA,EAAA,UAAM,aAAa,UAAU,oBAAoB,UAAU,kBAAA,CAAwB,CAAA;GAC7E;;AAGb,IAAM,YAAY,MAAM,WAAW,SAAS,kBAC1C,EACE,SAAS,YAAY,UACrB,UAAU,aAAa,MACvB,QAAQ,WACR,WAAW,cAAc,SACzB,QACA,UACA,WAAW,OACX,SAAS,YAAY,MACrB,uBACA,qBACA,kBACA,WACA,WACA,UACA,iBAEF,KACA;CACA,MAAM,CAAC,cAAc,mBAAmB,MAAM,SAA4B,EAAE,CAAC;CAC7E,MAAM,CAAC,OAAO,YAAY,MAAM,SAA4B,EAAE,CAAC;CAC/D,MAAM,CAAC,SAAS,cAAc,MAAM,SAA4B,EAAE,CAAC;CACnE,MAAM,CAAC,mBAAmB,wBAAwB,MAAM,SAA4B,EAAE,CAAC;CACvF,MAAM,CAAC,SAAS,cAAc,MAAM,SAAS,MAAM;CACnD,MAAM,CAAC,YAAY,iBAAiB,UAAU,UAAU,SAAS;CACjE,MAAM,WAAW,MAAM,OAAuB,KAAK;CACnD,MAAM,WAAW,OAAO;CACxB,MAAM,qBAAqB,MAAM,OAAuB,KAAK;CAC7D,MAAM,gBAAgB;CAEtB,MAAM,EAAE,aAAa,YAA6B,gBAAgB,UAAU;CAG5E,MAAMA,kBAAuC;EAC3C,GAHuB,aAAa,SAAS;EAI7C,GAAG;EACJ;AAED,OAAM,gBAAgB;EACpB,IAAI,eAAe;EACnB,MAAMC,kBAAqC,EAAE;EAC7C,MAAMC,WAA8B,EAAE;EACtC,MAAMC,aAAgC,EAAE;EACxC,MAAMC,uBAA0C,EAAE;AAElD,QAAM,SAAS,QAAQ,WAAU,UAAS;AACxC,OAAI,MAAM,eAAe,MAAM;QACzB,MAAM,SAAS,aACjB,iBAAgB,KAAK,MAAM;aAClB,MAAM,SAAS,oBAAY;AACpC,cAAS,KACP,MAAM,aAAa,OAA8C,EAAE,eAAe,MAAM,MAAM,iBAAiB,eAAe,CAAC,CAChI;AACD,SAAI,MAAM,MAAM,KACd,gBAAe;eAER,MAAM,SAAS,KAAK,MAAM,SAAS,KAAK,MAAM,SAAS,EAChE,YAAW,KAAK,MAAM;aACb,MAAM,SAAS,gBACxB,sBAAqB,KAAK,MAAM;;IAGpC;AAEF,kBAAgB,gBAAgB;AAChC,WAAS,SAAS;AAClB,aAAW,WAAW;AACtB,uBAAqB,qBAAqB;AAC1C,aAAW,aAAa;IACvB,CAAC,SAAS,CAAC;AAEd,OAAM,gBAAgB;AACpB,MAAI,SAEF;AAGF,MAAI;OACE,aAAa,YAAY,SAAS,WAAW,mBAAmB,SAAS;IAC3E,MAAM,YAAY,SAAS,QAAQ,uBAAuB;IAC1D,MAAM,sBAAsB,mBAAmB,QAAQ,uBAAuB;IAE9E,MAAM,eAAe,KAAK,IAAI,eAAe,UAAU,MAAM,GAAG;AAGhE,QAAI,eAAe,KAAK,oBAAoB,SAAS,OAAO,aAAa;AAEvE,SAD6B,OAAO,WAAW,mCAAmC,CAAC,QAEjF;AAEF,YAAO,SAAS;MACd,KAAK;MACL,UAAU;MACX,CAAC;;;;IAIP,CAAC,WAAW,CAAC;CAEhB,MAAM,cAAc,YAAY,aAAa,OAAO,QAAQ;CAE5D,MAAM,kBAAkB,WAAW,WAAW;GAC3C,OAAO,mCAAmC,YAAY,aAAa;GACnE,OAAO,yBAAyB,YAAY,aAAa;GACzD,OAAO,kCAAkC,YAAY,aAAa,QAAQ,gBAAgB;GAC1F,OAAO,8BAA8B,YAAY,aAAa,QAAQ,WAAW,YAAY;GAC7F,OAAO,iCAAiC,YAAY,aAAa,QAAQ,WAAW,YAAY;EAClG,CAAC;CACF,MAAM,kBAAkB,WAAW,OAAO,UAAU,OAAO,UAAU,gBAAgB,OAAO,kBAAkB;GAC3G,OAAO,iBAAiB,YAAY,aAAa;GACjD,OAAO,gBAAgB,WAAW,YAAY;GAC9C,OAAO,kBAAkB,WAAW,YAAY;GAChD,OAAO,kBAAkB,WAAW,YAAY;GAChD,OAAO,iBAAiB;EAC1B,CAAC;CACF,MAAM,yBAAyB,WAAW,OAAO,mBAAmB,OAAO,mBAAmB,WAAW,GACtG,OAAO,6BAA6B,aAAa,cAAc,QACjE,CAAC;CACF,MAAM,uBAAuB,WAAW;GACrC,OAAO,uCAAuC,cAAc,WAAW,YAAY;GACnF,OAAO,0CAA0C,iBAAiB,CAAC,cAAc,WAAW,YAAY;GACxG,OAAO,iDAAiD,CAAC,cAAc,WAAW,YAAY,QAAQ,YAAY,aAAa;EACjI,CAAC;CAEF,MAAM,0BAAgC;AACpC,gBAAc,CAAC,WAAW;;AAG5B,QAAO,kBAAkB,SAAS,IAChC,oBAAC,OAAA;EAAI,WAAW;YACd,oBAAC,OAAA;GAAI,WAAW,WAAW,GAAG,OAAO,mCAAmC,YAAY,aAAa,SAAS,CAAC;aACzG,oBAAC,OAAA;IAAI,WAAW;cACd,qBAAC,OAAA;KAAI,WAAW;KAAiB,eAAa;KAAQ,KAAK;;MACzD,qBAAC,qBAAA;OAAY,YAAY;kBACtB,cACA,MAAA;QACW;MACd,oBAAC,OAAA;OAAI,WAAW;iBACd,oBAAC,qBAAA;QAAY,YAAY;kBAAgB;SAAsB;QAC3D;MACN,oBAAC,cAAA;OAAa,SAAS;OAA+B;OAAY,WAAW;QAAmB;MAC/F,cACC,qBAAC,OAAA;OAAI,KAAK;OAAoB,eAAa,SAAS;kBAClD,oBAAC,OAAA,EAAI,WAAW,OAAO,+BAAA,CAAiC,EACxD,oBAAC,qBAAA;QAAY,YAAY;kBAAgB;SAAgC,CAAA;QACrE;;MAEJ;KACF;IACF;GACF,GAEN,oBAAC,OAAA;EAAI,WAAW;YACd,oBAAC,OAAA;GAAI,WAAW,WAAW,GAAG,OAAO,mCAAmC,YAAY,aAAa,SAAS,CAAC;aACzG,qBAAC,OAAA;IAAI,WAAW;IAAiB,eAAa;IAAQ,KAAK;;KACzD,qBAAC,qBAAA;MAAY,YAAY;iBACtB,cACA,MAAA;OACW;KACd,oBAAC,OAAA;MAAI,WAAW;gBACd,oBAAC,qBAAA;OAAY,YAAY;iBAAgB;QAAsB;OAC3D;KACL,oBAAoB,uBACnB,oBAAC,OAAA;MAAI,WAAW,OAAO;gBACrB,qBAAC,gBAAA;OAAO,SAAQ;OAAa,MAAK;OAAS,MAAK;OAAS,SAAS;OAAqB,cAAY;kBAChG,kBACD,oBAAC,cAAA;QAAK,SAAS;QAAc,MAAM,SAAS;SAAU,CAAA;QAC/C;OACL;;KAEJ;IACF;GACF;EAER;AAOF,MAAaC,gBAAwC,EAAE,eAAe;AACpE,QAAO,oBAAC,OAAA;EAAI,WAAW,OAAO;EAA0B;GAAe;;AAGzE,MAAaC,KAA6B,EAAE,eAAe;AAEzD,QAAO,oBAAC,OAAA;EAAI,WADI,WAAW,OAAO,yBAAyB,OAAO,2BAA2B;EAC5D;GAAe;;AAGlD,MAAaC,KAA6B,EAAE,eAAe;AAEzD,QAAO,oBAAC,OAAA;EAAI,WADI,WAAW,OAAO,yBAAyB,OAAO,2BAA2B;EAC5D;GAAe;;AAGlD,MAAaC,KAA6B,EAAE,eAAe;AAEzD,QAAO,oBAAC,OAAA;EAAI,WADI,WAAW,OAAO,yBAAyB,OAAO,2BAA2B;EAC5D;GAAe;;AAGlD,MAAaC,mBAA2C,EAAE,eAAe;AAEvE,QAAO,oBAAC,OAAA;EAAI,WADI,WAAW,OAAO,4BAA4B;EAC7B;GAAe;;AAWlD,UAAU,cAAc;AACxB,IAAM,QAAQ;AACd,MAAM,eAAe;AACrB,MAAM,QAAQ;AACd,MAAM,IAAI;AACV,MAAM,IAAI;AACV,MAAM,IAAI;AACV,MAAM,kBAAkB;AAExB,IAAA,gBAAe"}
1
+ {"version":3,"file":"Panel.js","names":["mergedResources: HNDesignsystemPanel","newPreContainer: React.ReactNode[]","newTitle: React.ReactNode[]","newContent: React.ReactNode[]","newExpandableContent: React.ReactNode[]","PreContainer: React.FC<ContentProps>","A: React.FC<ContentProps>","B: React.FC<ContentProps>","C: React.FC<ContentProps>","ExpandedContent: React.FC<ContentProps>"],"sources":["../src/resources/HN.Designsystem.Panel.en-GB.json","../src/resources/HN.Designsystem.Panel.nb-NO.json","../src/components/Panel/resourceHelper.ts","../src/components/Panel/Panel.tsx"],"sourcesContent":["{\n \"expandButtonOpen\": \"See details\",\n \"expandButtonClose\": \"Hide details\"\n}\n","{\n \"expandButtonOpen\": \"Se detaljer\",\n \"expandButtonClose\": \"Skjul detaljer\"\n}\n","import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Panel.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Panel.nb-NO.json';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemPanel => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { LanguageLocales } from '../../constants';\nimport { useExpand } from '../../hooks/useExpand';\nimport { PaletteNames } from '../../theme/palette';\nimport Button from '../Button';\nimport Icon, { IconSize } from '../Icon';\nimport PanelTitle, { PanelTitleProps } from './PanelTitle';\nimport { getResources } from './resourceHelper';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\nimport { useLanguage } from '../../utils/language';\nimport Highlighter from '../Highlighter';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronRight from '../Icons/ChevronRight';\nimport ChevronUp from '../Icons/ChevronUp';\n\nimport styles from './styles.module.scss';\n\nexport enum PanelLayout {\n vertical = 'vertical',\n horizontal = 'horizontal',\n combined = 'combined',\n bAsRightCol = 'bAsRightCol',\n}\n\nexport type PanelColors = Extract<PaletteNames, 'white' | 'neutral'>;\n\nexport enum PanelVariant {\n fill = 'fill',\n line = 'line',\n outline = 'outline',\n}\n\nexport enum PanelStacking {\n default = 'default',\n bFirst = 'bFirst',\n}\n\nexport enum PanelStatus {\n none = 'none',\n new = 'new',\n error = 'error',\n draft = 'draft',\n}\n\nexport interface PanelProps {\n /** Aria label on call to action button */\n buttonBottomAriaLabel?: string;\n /** Sets the text on the bottom call to action button */\n buttonBottomText?: string;\n /** Sets the action on the bottom call to action button */\n buttonBottomOnClick?: () => void;\n /** Expands or collapses the panel. Only applicable when ExpandedContent is used */\n expanded?: boolean;\n /** Whether the panel can be focused */\n focusable?: boolean;\n /** Sets the layout and order of the content boxes */\n layout?: PanelLayout;\n /** Sets the visual variant of panel */\n variant?: PanelVariant;\n /** Sets the color for panel if it has variant fill */\n color?: PanelColors;\n /** Sets classes on the outermost container of the panel */\n className?: string;\n /** Action called when toggling expansion of ExpandedContent */\n onExpand?: (isExpanded?: boolean) => void;\n /** Sets the stacking order of the content boxes */\n stacking?: PanelStacking;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Children elements to be rendered inside the panel */\n children?: React.ReactNode;\n /** Displays a status on the left side: default normal */\n status?: PanelStatus;\n /** Resources for component */\n resources?: Partial<HNDesignsystemPanel>;\n /** Highlights text in title and content. Used for search results */\n highlightText?: string;\n}\n\nconst ExpandButton = ({\n onClick,\n isExpanded,\n resources,\n}: {\n onClick: () => void;\n isExpanded: boolean | undefined;\n resources: Partial<HNDesignsystemPanel>;\n}): React.JSX.Element => {\n const buttonClassName = classNames(styles['expander__button'], isExpanded && styles['expander__button--expanded']);\n\n return (\n <Button\n variant=\"borderless\"\n textClassName={styles['expander__button__text']}\n wrapperClassName={buttonClassName}\n aria-expanded={isExpanded}\n onClick={onClick}\n >\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} />\n <span>{isExpanded ? resources.expandButtonClose : resources.expandButtonOpen}</span>\n </Button>\n );\n};\nconst PanelRoot = React.forwardRef(function PanelForwardedRef(\n {\n layout = PanelLayout.vertical,\n variant = PanelVariant.fill,\n color = 'neutral',\n stacking = PanelStacking.default,\n testId,\n children,\n expanded = false,\n focusable,\n status = PanelStatus.none,\n buttonBottomAriaLabel,\n buttonBottomOnClick,\n buttonBottomText,\n className,\n resources,\n onExpand,\n highlightText,\n }: PanelProps,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const [preContainer, setPreContainer] = React.useState<React.ReactNode[]>([]);\n const [title, setTitle] = React.useState<React.ReactNode[]>([]);\n const [content, setContent] = React.useState<React.ReactNode[]>([]);\n const [expandableContent, setExpandableContent] = React.useState<React.ReactNode[]>([]);\n const [hasIcon, setHasIcon] = React.useState(false);\n const [isExpanded, setIsExpanded] = useExpand(expanded, onExpand);\n const localRef = React.useRef<HTMLDivElement>(null);\n const panelRef = ref ?? localRef;\n const expandedContentRef = React.useRef<HTMLDivElement>(null);\n const defaultScroll = 100;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemPanel = {\n ...defaultResources,\n ...resources,\n };\n\n React.useEffect(() => {\n let index = 0;\n let localHasIcon = false;\n const newPreContainer: React.ReactNode[] = [];\n const newTitle: React.ReactNode[] = [];\n const newContent: React.ReactNode[] = [];\n const newExpandableContent: React.ReactNode[] = [];\n\n React.Children.forEach(children, child => {\n if (React.isValidElement(child)) {\n const key = child.key ?? `panel-child-${index++}`;\n\n if (child.type === PreContainer) {\n newPreContainer.push(React.cloneElement(child, { key }));\n } else if (child.type === PanelTitle) {\n newTitle.push(\n React.cloneElement(child as React.ReactElement<PanelTitleProps>, {\n key,\n highlightText: child.props.highlightText || highlightText,\n })\n );\n if (child.props.icon) {\n localHasIcon = true;\n }\n } else if (child.type === A || child.type === B || child.type === C) {\n newContent.push(React.cloneElement(child, { key }));\n } else if (child.type === ExpandedContent) {\n newExpandableContent.push(React.cloneElement(child, { key }));\n }\n }\n });\n\n setPreContainer(newPreContainer);\n setTitle(newTitle);\n setContent(newContent);\n setExpandableContent(newExpandableContent);\n setHasIcon(localHasIcon);\n }, [children]);\n\n React.useEffect(() => {\n if (expanded) {\n // Hvis panel åpnes controlled skal ikke scroll skje\n return;\n }\n // Scroller oppover når expanded content åpnes uncontrolled\n if (isExpanded) {\n if ('current' in panelRef && panelRef.current && expandedContentRef.current) {\n const panelRect = panelRef.current.getBoundingClientRect();\n const expandedContentRect = expandedContentRef.current.getBoundingClientRect();\n\n const scrollAmount = Math.min(defaultScroll, panelRect.top - 20);\n\n // Scroller kun oppover, og kun dersom expandedContent havner utenfor skjermen når åpnet\n if (scrollAmount > 0 && expandedContentRect.bottom > window.innerHeight) {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n return;\n }\n window.scrollBy({\n top: scrollAmount,\n behavior: 'smooth',\n });\n }\n }\n }\n }, [isExpanded]);\n\n const colorScheme = variant === PanelVariant.fill ? color : 'white';\n\n const outerClassnames = classNames(className, {\n [styles['panel__border--outline--outer']]: variant === PanelVariant.outline,\n [styles['panel__border--line']]: variant === PanelVariant.line,\n [styles['panel__border--fill--neutral']]: variant === PanelVariant.fill && colorScheme === 'neutral',\n [styles['panel__border--fill--new']]: variant === PanelVariant.fill && status === PanelStatus.new,\n [styles['panel__border--fill--status']]: variant === PanelVariant.fill && status !== PanelStatus.none,\n });\n const panelClassnames = classNames(styles['panel'], styles[`panel--${colorScheme}`], styles['panel--status'], {\n [styles['panel--line']]: variant === PanelVariant.line,\n [styles['panel--new']]: status === PanelStatus.new,\n [styles['panel--draft']]: status === PanelStatus.draft,\n [styles['panel--error']]: status === PanelStatus.error,\n [styles['panel--icon']]: hasIcon,\n });\n const contentContainerLayout = classNames(styles['panel__content'], styles[`panel__content--${layout}`], {\n [styles[`panel__content--b-first`]]: stacking === PanelStacking.bFirst,\n });\n const expanderBorderLayout = classNames({\n [styles['panel__expander__border--expanded']]: isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--${colorScheme}`]]: !isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--line`]]: !isExpanded && status === PanelStatus.none && variant === PanelVariant.line,\n });\n\n const handleExpandClick = (): void => {\n setIsExpanded(!isExpanded);\n };\n\n return expandableContent.length > 0 ? (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={expanderBorderLayout}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef} tabIndex={focusable ? -1 : undefined}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n <ExpandButton onClick={handleExpandClick} isExpanded={isExpanded} resources={mergedResources} />\n {isExpanded && (\n <div ref={expandedContentRef} data-testid={testId + '-details'}>\n <div className={styles['panel__expander__separator']} />\n <Highlighter searchText={highlightText}>{expandableContent}</Highlighter>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n ) : (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef} tabIndex={focusable ? -1 : undefined}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n {buttonBottomText && buttonBottomOnClick && (\n <div className={styles['panel__button-bottom']}>\n <Button variant=\"borderless\" type=\"button\" size=\"medium\" onClick={buttonBottomOnClick} aria-label={buttonBottomAriaLabel}>\n {buttonBottomText}\n <Icon svgIcon={ChevronRight} size={IconSize.XSmall} />\n </Button>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nexport interface ContentProps {\n /** Children elements to be rendered inside the content box */\n children?: React.ReactNode;\n}\n\nexport const PreContainer: React.FC<ContentProps> = ({ children }) => {\n return <div className={styles['panel__pre-container']}>{children}</div>;\n};\n\nexport const A: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--a']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const B: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--b']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const C: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--c']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const ExpandedContent: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__expander__content']);\n return <div className={styling}>{children}</div>;\n};\n\ntype PanelComponent = typeof PanelRoot & {\n PreContainer: React.FC<ContentProps>;\n Title: React.FC<PanelTitleProps>;\n A: React.FC<ContentProps>;\n B: React.FC<ContentProps>;\n C: React.FC<ContentProps>;\n ExpandedContent: React.FC<ContentProps>;\n};\nPanelRoot.displayName = 'Panel';\nconst Panel = PanelRoot as PanelComponent;\nPanel.PreContainer = PreContainer;\nPanel.Title = PanelTitle;\nPanel.A = A;\nPanel.B = B;\nPanel.C = C;\nPanel.ExpandedContent = ExpandedContent;\n\nexport default Panel;\n"],"mappings":"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"}
package/lib/Slider.js CHANGED
@@ -119,6 +119,7 @@ const Slider = React.forwardRef((props, ref) => {
119
119
  };
120
120
  const handlePointerDown = (e) => {
121
121
  if (disabled) return;
122
+ handleTrackClick(e);
122
123
  setIsMoving(true);
123
124
  handleSelected();
124
125
  e.preventDefault();
@@ -230,7 +231,6 @@ const Slider = React.forwardRef((props, ref) => {
230
231
  /* @__PURE__ */ jsxs("div", {
231
232
  ref: trackRef,
232
233
  className: classNames(styles["slider__track-wrapper"], disabled && styles["slider__track-wrapper--disabled"]),
233
- onClick: handleTrackClick,
234
234
  onPointerDown: handlePointerDown,
235
235
  children: [/* @__PURE__ */ jsx("div", {
236
236
  className: classNames(styles.slider__track, disabled && styles["slider__track--disabled"]),