@helsenorge/designsystem-react 13.0.2 → 13.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ ## [13.2.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv13.1.0&targetVersion=GTv13.2.0) (2025-12-04)
2
+
3
+
4
+ ### Features
5
+
6
+ * **listeditmode:** nye tokens for hover og active states og endret spacing ([040271e](https://github.com/helsenorge/designsystem/commit/040271ea24fb71319e85fb54ddab56f011476ac0)), closes [#365898](https://github.com/helsenorge/designsystem/issues/365898)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **tile:** hairline får justering for bedre kontrast ([15c2e40](https://github.com/helsenorge/designsystem/commit/15c2e40b4f4f8de92d0a8566feb89cfef389f159)), closes [#358926](https://github.com/helsenorge/designsystem/issues/358926)
12
+
13
+ ## [13.1.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv13.0.2&targetVersion=GTv13.1.0) (2025-12-02)
14
+
15
+
16
+ ### Features
17
+
18
+ * **servicemessage:** tar i bruk elementheader og får active og hover states ([b628e44](https://github.com/helsenorge/designsystem/commit/b628e442191e9bdbfee1bdbcc6aff874dd9f4845)), closes [#361065](https://github.com/helsenorge/designsystem/issues/361065) [#365204](https://github.com/helsenorge/designsystem/issues/365204)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * **elementheader:** fiks manglende håndtering av lazyicon som ikon i listeelementer ([f3714cd](https://github.com/helsenorge/designsystem/commit/f3714cd34285ac0eff789546a9c1c3c67cdf1845)), closes [#366030](https://github.com/helsenorge/designsystem/issues/366030)
24
+ * **favoritebutton:** feil farge ved hover ([5c9a9d2](https://github.com/helsenorge/designsystem/commit/5c9a9d2fcad0479567ec5ecff78f8a6514725f8a)), closes [#366027](https://github.com/helsenorge/designsystem/issues/366027)
25
+
1
26
  ## [13.0.2](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv13.0.0&targetVersion=GTv13.0.2) (2025-12-01)
2
27
 
3
28
 
@@ -139,7 +164,7 @@
139
164
 
140
165
  * lib mappen ble ikke med i den publiserte pakken ([1c5409e](https://github.com/helsenorge/designsystem/commit/1c5409eeaf05524c315650ea11a839a70b7dfaa3)), closes [#362474](https://github.com/helsenorge/designsystem/issues/362474)
141
166
 
142
- ## [12.12.2](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.12.1&targetVersion=GTv12.12.2) (2025-11-06)
167
+ ## [12.12.2](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.12.1&targetVersion=GTv12.12.2) (2025-11-07)
143
168
 
144
169
  ## [12.12.1](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.11.1&targetVersion=GTv12.12.1) (2025-11-06)
145
170
 
@@ -2,6 +2,7 @@ import { a as IconSize } from "./constants2.js";
2
2
  import { t as Icon_default } from "./Icon.js";
3
3
  import { n as AvatarSize, t as Avatar_default } from "./Avatar.js";
4
4
  import { t as Badge_default } from "./Badge.js";
5
+ import { t as LazyIcon_default } from "./LazyIcon.js";
5
6
  import { n as isComponentWithChildren, t as isComponent } from "./component.js";
6
7
  import { n as useBreakpoint, t as Breakpoint } from "./useBreakpoint.js";
7
8
  import { t as StatusDot_default } from "./StatusDot.js";
@@ -13,14 +14,15 @@ import classNames from "classnames";
13
14
  import { jsx, jsxs } from "react/jsx-runtime";
14
15
  import styles from "./components/ElementHeader/styles.module.scss";
15
16
  const renderElementHeader = (element, options) => {
16
- const { titleHtmlMarkup, isHovered, size, parentType, chevronIcon, icon, highlightText } = options;
17
+ const { titleHtmlMarkup, isHovered, size, parentType, chevronIcon, icon, highlightText, closeButton } = options;
17
18
  if (isComponent(element, ElementHeader)) return React.cloneElement(element, {
18
19
  chevronIcon,
19
20
  icon,
20
21
  isHovered,
21
22
  size,
22
23
  parentType,
23
- highlightText
24
+ highlightText,
25
+ closeButton
24
26
  });
25
27
  if (element) return /* @__PURE__ */ jsx(ElementHeader, {
26
28
  highlightText,
@@ -30,6 +32,7 @@ const renderElementHeader = (element, options) => {
30
32
  icon,
31
33
  isHovered,
32
34
  size,
35
+ closeButton,
33
36
  children: element
34
37
  });
35
38
  };
@@ -65,32 +68,43 @@ const mapChildren = (children, isJsxChild = false) => {
65
68
  if (isComponentWithChildren(remainingChildren[0])) return mapChildren(remainingChildren[0]?.props?.children, true);
66
69
  };
67
70
  const ElementHeaderRoot = (props) => {
68
- const { className = "", titleHtmlMarkup = "h2", parentType = "linklist", chevronIcon, children, icon, isHovered, size, testId, highlightText } = props;
71
+ const { className = "", titleHtmlMarkup = "h2", parentType = "linklist", chevronIcon, closeButton, children, icon, isHovered, size, testId, highlightText } = props;
69
72
  const breakpoint = useBreakpoint();
70
73
  const showIcon = size !== "small" && !!icon;
71
74
  const contentIsString = typeof children === "string";
72
75
  const mappedChildren = mapChildren(children);
73
76
  const hasStatusDots = !!mappedChildren?.statusDotChildren?.length || !!mappedChildren?.statusDotMCChild;
74
- const listLabelClasses = classNames(styles["element-header"], className);
77
+ const listLabelClasses = classNames(styles["element-header"], { [styles["element-header--compact"]]: size === "compact" }, className);
75
78
  const badgeContainerClasses = classNames(styles["element-header__badge-container"]);
76
79
  const badgeClasses = classNames(styles["element-header__badge"]);
77
80
  const statusdotContainerClasses = classNames(styles["element-header__statusdot-container"]);
78
81
  const chevronClasses = classNames(styles["element-header__chevron"]);
79
- const contentClasses = classNames(styles["element-header__content"], { [styles["element-header__content--element"]]: !contentIsString });
82
+ const contentClasses = classNames(styles["element-header__content"], {
83
+ [styles["element-header__content--element"]]: !contentIsString,
84
+ [styles["element-header__content--compact"]]: size === "compact"
85
+ });
80
86
  const iconClasses = classNames(styles["element-header__icon"], { [styles["element-header__icon--with-statusdot"]]: hasStatusDots });
81
87
  const avatarClasses = classNames(styles["element-header__avatar"], {});
82
88
  const CustomTag = titleHtmlMarkup;
83
89
  const iconPropIsIconComponent = isComponent(icon, Icon_default);
90
+ const iconPropIsLazyIconComponent = !iconPropIsIconComponent && isComponent(icon, LazyIcon_default);
91
+ let iconComponent;
92
+ if (iconPropIsIconComponent) iconComponent = React.cloneElement(icon, {
93
+ size: breakpoint < Breakpoint.md ? IconSize.XSmall : IconSize.Small,
94
+ isHovered
95
+ });
96
+ else if (iconPropIsLazyIconComponent) iconComponent = React.cloneElement(icon, {
97
+ size: breakpoint < Breakpoint.md ? IconSize.XSmall : IconSize.Small,
98
+ isHovered
99
+ });
100
+ else iconComponent = icon;
84
101
  return /* @__PURE__ */ jsxs("span", {
85
102
  "data-testid": testId,
86
103
  className: listLabelClasses,
87
104
  children: [
88
105
  showIcon && icon && /* @__PURE__ */ jsx("span", {
89
106
  className: iconClasses,
90
- children: iconPropIsIconComponent ? React.cloneElement(icon, {
91
- size: breakpoint < Breakpoint.md ? IconSize.XSmall : IconSize.Small,
92
- isHovered
93
- }) : icon
107
+ children: iconComponent
94
108
  }),
95
109
  size !== "small" && mappedChildren?.avatarChild && /* @__PURE__ */ jsx("span", {
96
110
  className: avatarClasses,
@@ -128,7 +142,7 @@ const ElementHeaderRoot = (props) => {
128
142
  }, index);
129
143
  })
130
144
  }),
131
- chevronIcon && /* @__PURE__ */ jsx("span", {
145
+ chevronIcon && typeof closeButton === "undefined" && /* @__PURE__ */ jsx("span", {
132
146
  className: chevronClasses,
133
147
  "data-parenttype": parentType,
134
148
  children: /* @__PURE__ */ jsx(Icon_default, {
@@ -136,6 +150,11 @@ const ElementHeaderRoot = (props) => {
136
150
  isHovered,
137
151
  size: IconSize.XSmall
138
152
  })
153
+ }),
154
+ closeButton && /* @__PURE__ */ jsx("span", {
155
+ className: chevronClasses,
156
+ "data-parenttype": parentType,
157
+ children: closeButton
139
158
  })
140
159
  ]
141
160
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ElementHeader.js","names":["mapChildren: ChildrenMapper","avatarChild: React.ReactElement<AvatarProps> | undefined","badgeChildren: React.ReactElement<BadgeProps>[]","statusDotChildren: React.ReactElement<StatusDotProps>[]","statusDotMCChild: React.ReactElement<StatusDotListProps> | undefined","elementHeaderTextChildren: React.ReactElement<ElementHeaderTextProps>[]","stringChildren: string[]","remainingChildren: React.ReactNode[]","ElementHeaderRoot: ElementHeaderType"],"sources":["../src/components/ElementHeader/ElementHeader.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport ElementHeaderText, { ElementHeaderTextProps, ElementHeaderTextType } from './ElementHeaderText/ElementHeaderText';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { isComponent, isComponentWithChildren } from '../../utils/component';\nimport Avatar, { AvatarProps, AvatarSize, AvatarType } from '../Avatar';\nimport Badge, { BadgeProps, BadgeType } from '../Badge';\nimport Icon, { IconProps, IconSize, SvgIcon } from '../Icon';\nimport StatusDot, { StatusDotProps, StatusDotType } from '../StatusDot';\nimport { TitleTags } from '../Title';\nimport StatusDotList from './StatusDotList';\nimport Highlighter from '../Highlighter';\nimport { StatusDotListProps, StatusDotListType } from './StatusDotList/StatusDotList';\n\nimport styles from './styles.module.scss';\n\nexport type ElementHeaderSize = 'small' | 'medium' | 'large';\nexport type ParentType = 'linklist' | 'expanderlist';\n\nexport interface ElementHeaderType extends React.FC<ElementHeaderProps> {\n Avatar?: AvatarType;\n Badge?: BadgeType;\n ElementHeaderText?: ElementHeaderTextType;\n StatusDot?: StatusDotType;\n StatusDotList?: StatusDotListType;\n}\n\nexport const renderElementHeader = (\n element: React.ReactNode,\n options: Pick<ElementHeaderProps, 'titleHtmlMarkup' | 'isHovered' | 'size' | 'parentType' | 'chevronIcon' | 'icon' | 'highlightText'>\n): React.ReactElement | undefined => {\n const { titleHtmlMarkup, isHovered, size, parentType, chevronIcon, icon, highlightText } = options;\n\n if (isComponent<ElementHeaderProps>(element, ElementHeader)) {\n return React.cloneElement(element, {\n chevronIcon,\n icon,\n isHovered,\n size,\n parentType,\n highlightText,\n });\n }\n if (element) {\n return (\n <ElementHeader\n highlightText={highlightText}\n titleHtmlMarkup={titleHtmlMarkup}\n parentType={parentType}\n chevronIcon={chevronIcon}\n icon={icon}\n isHovered={isHovered}\n size={size}\n >\n {element}\n </ElementHeader>\n );\n }\n};\n\nexport interface ElementHeaderProps {\n /** Adds custom classes to the ElementHeader element. */\n className?: string;\n /** Chevron to render inside of the ElementHeader */\n chevronIcon?: SvgIcon;\n /** Children to be rendered inside of ElementHeader */\n children: React.ReactNode;\n /** Changes the underlying element of the title. Default: h2*/\n titleHtmlMarkup?: TitleTags;\n /** icon to be rendered inside of ElementHeader */\n icon?: React.ReactElement;\n /** whether or not the parent is hovered */\n isHovered?: boolean;\n /** Adjusts styling based on parent */\n parentType?: ParentType;\n /** Changes size of the ElementHeader. */\n size?: ElementHeaderSize;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Highlights text in title. Used for search results */\n highlightText?: string;\n}\n\ninterface ElementHeaderChildren {\n avatarChild?: React.ReactElement<AvatarProps>;\n elementHeaderTextChildren: React.ReactElement<ElementHeaderTextProps>[];\n badgeChildren?: React.ReactElement<BadgeProps>[];\n statusDotChildren?: React.ReactElement<StatusDotProps>[];\n statusDotMCChild?: React.ReactElement<StatusDotListProps>;\n elementChild?: React.ReactElement;\n stringChildren: string[];\n remainingChildren: React.ReactNode[];\n}\n\ntype ChildrenMapper = (children: React.ReactNode, isJsxChild?: boolean) => ElementHeaderChildren | undefined;\n\nexport const mapChildren: ChildrenMapper = (children, isJsxChild = false) => {\n let avatarChild: React.ReactElement<AvatarProps> | undefined;\n const badgeChildren: React.ReactElement<BadgeProps>[] = [];\n const statusDotChildren: React.ReactElement<StatusDotProps>[] = [];\n let statusDotMCChild: React.ReactElement<StatusDotListProps> | undefined;\n const elementHeaderTextChildren: React.ReactElement<ElementHeaderTextProps>[] = [];\n const stringChildren: string[] = [];\n const remainingChildren: React.ReactNode[] = [];\n\n React.Children.forEach(children, child => {\n if (child === null || typeof child === 'undefined') return;\n if (isComponent<AvatarProps>(child, Avatar)) {\n avatarChild = child;\n } else if (isComponent<ElementHeaderTextProps>(child, ElementHeaderText)) {\n elementHeaderTextChildren.push(child);\n } else if (isComponent<BadgeProps>(child, Badge)) {\n badgeChildren.push(child);\n } else if (isComponent<StatusDotListProps>(child, StatusDotList)) {\n statusDotMCChild = child;\n } else if (isComponent<StatusDotProps>(child, StatusDot)) {\n statusDotChildren.push(child);\n } else if (typeof child === 'string') {\n stringChildren.push(child);\n } else {\n remainingChildren.push(child);\n }\n });\n\n // Dette og recursive mapChildren under(gjøres en gang) er for å passe på at jsx children også sjekkes for Avatar og liknende innhold.\n // Slik opprettholder vi stylingen i tilfeller hvor vertikaler har wrappet elementer i en parent span eller div.\n const hasSpecialChildren =\n avatarChild !== undefined ||\n elementHeaderTextChildren.length > 0 ||\n statusDotChildren.length > 0 ||\n statusDotMCChild !== undefined ||\n (badgeChildren !== undefined && stringChildren.length > 0);\n const noRemainingRecursiveChildren =\n remainingChildren.length === 0 ||\n (isComponentWithChildren(remainingChildren[0]) && typeof remainingChildren[0]?.props?.children === 'undefined');\n\n if (isJsxChild || hasSpecialChildren || noRemainingRecursiveChildren) {\n return {\n avatarChild,\n elementHeaderTextChildren: elementHeaderTextChildren,\n badgeChildren,\n statusDotChildren,\n statusDotMCChild,\n stringChildren,\n remainingChildren,\n };\n }\n\n if (isComponentWithChildren(remainingChildren[0])) {\n return mapChildren(remainingChildren[0]?.props?.children, true);\n }\n};\n\nexport const ElementHeaderRoot: ElementHeaderType = props => {\n const {\n className = '',\n titleHtmlMarkup = 'h2',\n parentType = 'linklist',\n chevronIcon,\n children,\n icon,\n isHovered,\n size,\n testId,\n highlightText,\n } = props;\n const breakpoint = useBreakpoint();\n const showIcon = size !== 'small' && !!icon;\n const contentIsString = typeof children === 'string';\n const mappedChildren = mapChildren(children);\n const hasStatusDots = !!mappedChildren?.statusDotChildren?.length || !!mappedChildren?.statusDotMCChild;\n\n const listLabelClasses = cn(styles['element-header'], className);\n const badgeContainerClasses = cn(styles['element-header__badge-container']);\n const badgeClasses = cn(styles['element-header__badge']);\n const statusdotContainerClasses = cn(styles['element-header__statusdot-container']);\n const chevronClasses = cn(styles['element-header__chevron']);\n const contentClasses = cn(styles['element-header__content'], {\n [styles['element-header__content--element']]: !contentIsString,\n });\n const iconClasses = cn(styles['element-header__icon'], { [styles['element-header__icon--with-statusdot']]: hasStatusDots });\n const avatarClasses = cn(styles['element-header__avatar'], {});\n const CustomTag = titleHtmlMarkup;\n const iconPropIsIconComponent = isComponent<IconProps>(icon, Icon);\n\n return (\n <span data-testid={testId} className={listLabelClasses}>\n {showIcon && icon && (\n <span className={iconClasses}>\n {iconPropIsIconComponent\n ? React.cloneElement(icon, {\n size: breakpoint < Breakpoint.md ? IconSize.XSmall : IconSize.Small,\n isHovered,\n })\n : icon}\n </span>\n )}\n {size !== 'small' && mappedChildren?.avatarChild && (\n <span className={avatarClasses}>{React.cloneElement(mappedChildren.avatarChild, { size: AvatarSize.xsmall })}</span>\n )}\n\n <span className={contentClasses} data-hasstatusdots={hasStatusDots}>\n {mappedChildren?.elementHeaderTextChildren}\n {!!mappedChildren?.stringChildren.length && (\n <CustomTag className={styles['element-header__title']}>\n <Highlighter searchText={highlightText}>{mappedChildren.stringChildren}</Highlighter>\n </CustomTag>\n )}\n <Highlighter searchText={highlightText}>{mappedChildren?.remainingChildren}</Highlighter>\n </span>\n\n {hasStatusDots && (\n <span className={statusdotContainerClasses}>\n {!!mappedChildren?.statusDotChildren && <StatusDotList>{mappedChildren.statusDotChildren}</StatusDotList>}\n {!!mappedChildren?.statusDotMCChild && mappedChildren?.statusDotMCChild}\n </span>\n )}\n\n <span className={badgeContainerClasses}>\n {mappedChildren?.badgeChildren &&\n mappedChildren.badgeChildren.map((badgeChild, index) => {\n return (\n <span key={index} className={badgeClasses} data-parenttype={parentType}>\n {badgeChild}\n </span>\n );\n })}\n </span>\n {chevronIcon && (\n <span className={chevronClasses} data-parenttype={parentType}>\n <Icon svgIcon={chevronIcon} isHovered={isHovered} size={IconSize.XSmall} />\n </span>\n )}\n </span>\n );\n};\n\ntype ElementHeaderComponent = typeof ElementHeaderRoot & {\n Text: React.FC<ElementHeaderTextProps>;\n StatusDotList: React.FC<StatusDotListProps>;\n};\nElementHeaderRoot.displayName = 'ElementHeader';\nconst ElementHeader = ElementHeaderRoot as ElementHeaderComponent;\nElementHeader.Text = ElementHeaderText;\nElementHeader.Text.displayName = 'ElementHeader.Text';\nElementHeader.StatusDotList = StatusDotList;\nElementHeader.StatusDotList.displayName = 'ElementHeader.StatusDotList';\n\nexport default ElementHeader;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ElementHeader.js","names":["mapChildren: ChildrenMapper","avatarChild: React.ReactElement<AvatarProps> | undefined","badgeChildren: React.ReactElement<BadgeProps>[]","statusDotChildren: React.ReactElement<StatusDotProps>[]","statusDotMCChild: React.ReactElement<StatusDotListProps> | undefined","elementHeaderTextChildren: React.ReactElement<ElementHeaderTextProps>[]","stringChildren: string[]","remainingChildren: React.ReactNode[]","ElementHeaderRoot: ElementHeaderType"],"sources":["../src/components/ElementHeader/ElementHeader.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport ElementHeaderText, { ElementHeaderTextProps, ElementHeaderTextType } from './ElementHeaderText/ElementHeaderText';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { isComponent, isComponentWithChildren } from '../../utils/component';\nimport Avatar, { AvatarProps, AvatarSize, AvatarType } from '../Avatar';\nimport Badge, { BadgeProps, BadgeType } from '../Badge';\nimport Icon, { IconProps, IconSize, SvgIcon } from '../Icon';\nimport StatusDot, { StatusDotProps, StatusDotType } from '../StatusDot';\nimport { TitleTags } from '../Title';\nimport StatusDotList from './StatusDotList';\nimport Highlighter from '../Highlighter';\nimport LazyIcon, { LazyIconProps } from '../LazyIcon';\nimport { StatusDotListProps, StatusDotListType } from './StatusDotList/StatusDotList';\n\nimport styles from './styles.module.scss';\n\nexport type ElementHeaderSize = 'compact' | 'small' | 'medium' | 'large';\nexport type ParentType = 'linklist' | 'expanderlist';\n\nexport interface ElementHeaderType extends React.FC<ElementHeaderProps> {\n Avatar?: AvatarType;\n Badge?: BadgeType;\n ElementHeaderText?: ElementHeaderTextType;\n StatusDot?: StatusDotType;\n StatusDotList?: StatusDotListType;\n}\n\nexport const renderElementHeader = (\n element: React.ReactNode,\n options: Pick<\n ElementHeaderProps,\n 'titleHtmlMarkup' | 'isHovered' | 'size' | 'parentType' | 'chevronIcon' | 'icon' | 'highlightText' | 'closeButton'\n >\n): React.ReactElement | undefined => {\n const { titleHtmlMarkup, isHovered, size, parentType, chevronIcon, icon, highlightText, closeButton } = options;\n\n if (isComponent<ElementHeaderProps>(element, ElementHeader)) {\n return React.cloneElement(element, {\n chevronIcon,\n icon,\n isHovered,\n size,\n parentType,\n highlightText,\n closeButton,\n });\n }\n if (element) {\n return (\n <ElementHeader\n highlightText={highlightText}\n titleHtmlMarkup={titleHtmlMarkup}\n parentType={parentType}\n chevronIcon={chevronIcon}\n icon={icon}\n isHovered={isHovered}\n size={size}\n closeButton={closeButton}\n >\n {element}\n </ElementHeader>\n );\n }\n};\n\nexport interface ElementHeaderProps {\n /** Adds custom classes to the ElementHeader element. */\n className?: string;\n /** Chevron to render inside of the ElementHeader */\n chevronIcon?: SvgIcon;\n /** Close button to be rendered inside of ElementHeader. This renders in place of chevronIcon */\n closeButton?: React.ReactElement;\n /** Children to be rendered inside of ElementHeader */\n children: React.ReactNode;\n /** Changes the underlying element of the title. Default: h2*/\n titleHtmlMarkup?: TitleTags;\n /** icon to be rendered inside of ElementHeader */\n icon?: React.ReactElement;\n /** whether or not the parent is hovered */\n isHovered?: boolean;\n /** Adjusts styling based on parent */\n parentType?: ParentType;\n /** Changes size of the ElementHeader. */\n size?: ElementHeaderSize;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Highlights text in title. Used for search results */\n highlightText?: string;\n}\n\ninterface ElementHeaderChildren {\n avatarChild?: React.ReactElement<AvatarProps>;\n elementHeaderTextChildren: React.ReactElement<ElementHeaderTextProps>[];\n badgeChildren?: React.ReactElement<BadgeProps>[];\n statusDotChildren?: React.ReactElement<StatusDotProps>[];\n statusDotMCChild?: React.ReactElement<StatusDotListProps>;\n elementChild?: React.ReactElement;\n stringChildren: string[];\n remainingChildren: React.ReactNode[];\n}\n\ntype ChildrenMapper = (children: React.ReactNode, isJsxChild?: boolean) => ElementHeaderChildren | undefined;\n\nexport const mapChildren: ChildrenMapper = (children, isJsxChild = false) => {\n let avatarChild: React.ReactElement<AvatarProps> | undefined;\n const badgeChildren: React.ReactElement<BadgeProps>[] = [];\n const statusDotChildren: React.ReactElement<StatusDotProps>[] = [];\n let statusDotMCChild: React.ReactElement<StatusDotListProps> | undefined;\n const elementHeaderTextChildren: React.ReactElement<ElementHeaderTextProps>[] = [];\n const stringChildren: string[] = [];\n const remainingChildren: React.ReactNode[] = [];\n\n React.Children.forEach(children, child => {\n if (child === null || typeof child === 'undefined') return;\n if (isComponent<AvatarProps>(child, Avatar)) {\n avatarChild = child;\n } else if (isComponent<ElementHeaderTextProps>(child, ElementHeaderText)) {\n elementHeaderTextChildren.push(child);\n } else if (isComponent<BadgeProps>(child, Badge)) {\n badgeChildren.push(child);\n } else if (isComponent<StatusDotListProps>(child, StatusDotList)) {\n statusDotMCChild = child;\n } else if (isComponent<StatusDotProps>(child, StatusDot)) {\n statusDotChildren.push(child);\n } else if (typeof child === 'string') {\n stringChildren.push(child);\n } else {\n remainingChildren.push(child);\n }\n });\n\n // Dette og recursive mapChildren under(gjøres en gang) er for å passe på at jsx children også sjekkes for Avatar og liknende innhold.\n // Slik opprettholder vi stylingen i tilfeller hvor vertikaler har wrappet elementer i en parent span eller div.\n const hasSpecialChildren =\n avatarChild !== undefined ||\n elementHeaderTextChildren.length > 0 ||\n statusDotChildren.length > 0 ||\n statusDotMCChild !== undefined ||\n (badgeChildren !== undefined && stringChildren.length > 0);\n const noRemainingRecursiveChildren =\n remainingChildren.length === 0 ||\n (isComponentWithChildren(remainingChildren[0]) && typeof remainingChildren[0]?.props?.children === 'undefined');\n\n if (isJsxChild || hasSpecialChildren || noRemainingRecursiveChildren) {\n return {\n avatarChild,\n elementHeaderTextChildren: elementHeaderTextChildren,\n badgeChildren,\n statusDotChildren,\n statusDotMCChild,\n stringChildren,\n remainingChildren,\n };\n }\n\n if (isComponentWithChildren(remainingChildren[0])) {\n return mapChildren(remainingChildren[0]?.props?.children, true);\n }\n};\n\nexport const ElementHeaderRoot: ElementHeaderType = props => {\n const {\n className = '',\n titleHtmlMarkup = 'h2',\n parentType = 'linklist',\n chevronIcon,\n closeButton,\n children,\n icon,\n isHovered,\n size,\n testId,\n highlightText,\n } = props;\n const breakpoint = useBreakpoint();\n const showIcon = size !== 'small' && !!icon;\n const contentIsString = typeof children === 'string';\n const mappedChildren = mapChildren(children);\n const hasStatusDots = !!mappedChildren?.statusDotChildren?.length || !!mappedChildren?.statusDotMCChild;\n\n const listLabelClasses = cn(styles['element-header'], { [styles['element-header--compact']]: size === 'compact' }, className);\n const badgeContainerClasses = cn(styles['element-header__badge-container']);\n const badgeClasses = cn(styles['element-header__badge']);\n const statusdotContainerClasses = cn(styles['element-header__statusdot-container']);\n const chevronClasses = cn(styles['element-header__chevron']);\n const contentClasses = cn(styles['element-header__content'], {\n [styles['element-header__content--element']]: !contentIsString,\n [styles['element-header__content--compact']]: size === 'compact',\n });\n const iconClasses = cn(styles['element-header__icon'], { [styles['element-header__icon--with-statusdot']]: hasStatusDots });\n const avatarClasses = cn(styles['element-header__avatar'], {});\n const CustomTag = titleHtmlMarkup;\n const iconPropIsIconComponent = isComponent<IconProps>(icon, Icon);\n const iconPropIsLazyIconComponent = !iconPropIsIconComponent && isComponent<LazyIconProps>(icon, LazyIcon);\n\n let iconComponent;\n if (iconPropIsIconComponent) {\n iconComponent = React.cloneElement(icon as React.ReactElement<IconProps>, {\n size: breakpoint < Breakpoint.md ? IconSize.XSmall : IconSize.Small,\n isHovered,\n });\n } else if (iconPropIsLazyIconComponent) {\n iconComponent = React.cloneElement(icon as React.ReactElement<LazyIconProps>, {\n size: breakpoint < Breakpoint.md ? IconSize.XSmall : IconSize.Small,\n isHovered,\n });\n } else {\n iconComponent = icon;\n }\n\n return (\n <span data-testid={testId} className={listLabelClasses}>\n {showIcon && icon && <span className={iconClasses}>{iconComponent}</span>}\n {size !== 'small' && mappedChildren?.avatarChild && (\n <span className={avatarClasses}>{React.cloneElement(mappedChildren.avatarChild, { size: AvatarSize.xsmall })}</span>\n )}\n\n <span className={contentClasses} data-hasstatusdots={hasStatusDots}>\n {mappedChildren?.elementHeaderTextChildren}\n {!!mappedChildren?.stringChildren.length && (\n <CustomTag className={styles['element-header__title']}>\n <Highlighter searchText={highlightText}>{mappedChildren.stringChildren}</Highlighter>\n </CustomTag>\n )}\n <Highlighter searchText={highlightText}>{mappedChildren?.remainingChildren}</Highlighter>\n </span>\n\n {hasStatusDots && (\n <span className={statusdotContainerClasses}>\n {!!mappedChildren?.statusDotChildren && <StatusDotList>{mappedChildren.statusDotChildren}</StatusDotList>}\n {!!mappedChildren?.statusDotMCChild && mappedChildren?.statusDotMCChild}\n </span>\n )}\n\n <span className={badgeContainerClasses}>\n {mappedChildren?.badgeChildren &&\n mappedChildren.badgeChildren.map((badgeChild, index) => {\n return (\n <span key={index} className={badgeClasses} data-parenttype={parentType}>\n {badgeChild}\n </span>\n );\n })}\n </span>\n {chevronIcon && typeof closeButton === 'undefined' && (\n <span className={chevronClasses} data-parenttype={parentType}>\n <Icon svgIcon={chevronIcon} isHovered={isHovered} size={IconSize.XSmall} />\n </span>\n )}\n {closeButton && (\n <span className={chevronClasses} data-parenttype={parentType}>\n {closeButton}\n </span>\n )}\n </span>\n );\n};\n\ntype ElementHeaderComponent = typeof ElementHeaderRoot & {\n Text: React.FC<ElementHeaderTextProps>;\n StatusDotList: React.FC<StatusDotListProps>;\n};\nElementHeaderRoot.displayName = 'ElementHeader';\nconst ElementHeader = ElementHeaderRoot as ElementHeaderComponent;\nElementHeader.Text = ElementHeaderText;\nElementHeader.Text.displayName = 'ElementHeader.Text';\nElementHeader.StatusDotList = StatusDotList;\nElementHeader.StatusDotList.displayName = 'ElementHeader.StatusDotList';\n\nexport default ElementHeader;\n"],"mappings":"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"}
@@ -6,7 +6,7 @@ import { SvgIcon } from '../Icon';
6
6
  import { StatusDotProps, StatusDotType } from '../StatusDot';
7
7
  import { TitleTags } from '../Title';
8
8
  import { StatusDotListProps, StatusDotListType } from './StatusDotList/StatusDotList';
9
- export type ElementHeaderSize = 'small' | 'medium' | 'large';
9
+ export type ElementHeaderSize = 'compact' | 'small' | 'medium' | 'large';
10
10
  export type ParentType = 'linklist' | 'expanderlist';
11
11
  export interface ElementHeaderType extends React.FC<ElementHeaderProps> {
12
12
  Avatar?: AvatarType;
@@ -15,12 +15,14 @@ export interface ElementHeaderType extends React.FC<ElementHeaderProps> {
15
15
  StatusDot?: StatusDotType;
16
16
  StatusDotList?: StatusDotListType;
17
17
  }
18
- export declare const renderElementHeader: (element: React.ReactNode, options: Pick<ElementHeaderProps, "titleHtmlMarkup" | "isHovered" | "size" | "parentType" | "chevronIcon" | "icon" | "highlightText">) => React.ReactElement | undefined;
18
+ export declare const renderElementHeader: (element: React.ReactNode, options: Pick<ElementHeaderProps, "titleHtmlMarkup" | "isHovered" | "size" | "parentType" | "chevronIcon" | "icon" | "highlightText" | "closeButton">) => React.ReactElement | undefined;
19
19
  export interface ElementHeaderProps {
20
20
  /** Adds custom classes to the ElementHeader element. */
21
21
  className?: string;
22
22
  /** Chevron to render inside of the ElementHeader */
23
23
  chevronIcon?: SvgIcon;
24
+ /** Close button to be rendered inside of ElementHeader. This renders in place of chevronIcon */
25
+ closeButton?: React.ReactElement;
24
26
  /** Children to be rendered inside of ElementHeader */
25
27
  children: React.ReactNode;
26
28
  /** Changes the underlying element of the title. Default: h2*/
@@ -26,6 +26,18 @@
26
26
 
27
27
  @include gridtemplate(3rem);
28
28
 
29
+ &--compact {
30
+ padding: 0 spacers.getSpacer(2xs) 0 0;
31
+
32
+ @media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
33
+ padding: 0.125rem spacers.getSpacer(2xs) 0.125rem 0;
34
+ }
35
+
36
+ @media (min-width: map.get(breakpoints.$grid-breakpoints, lg)) {
37
+ padding: 0.5rem spacers.getSpacer(2xs) 0.5rem 0;
38
+ }
39
+ }
40
+
29
41
  &__title {
30
42
  font-size: inherit;
31
43
  font-weight: inherit;
@@ -60,6 +72,18 @@
60
72
  margin-left: spacers.getSpacer(2xs);
61
73
  }
62
74
 
75
+ &--compact {
76
+ padding: 0.7rem 0 0.7rem 1rem;
77
+
78
+ @media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
79
+ padding: 0.57rem 0 0.57rem 2rem;
80
+ }
81
+
82
+ @media (min-width: map.get(breakpoints.$grid-breakpoints, lg)) {
83
+ padding: 0.57rem 0 0.57rem 1rem;
84
+ }
85
+ }
86
+
63
87
  :focus > &,
64
88
  :focus-visible > & {
65
89
  border-color: palette.$black;
@@ -78,6 +102,8 @@
78
102
  &__chevron,
79
103
  &__chevron svg {
80
104
  align-self: center;
105
+ display: flex;
106
+ align-items: center;
81
107
  }
82
108
 
83
109
  &__icon,
@@ -6,12 +6,14 @@ export type Styles = {
6
6
  'element-header__badge-container': string;
7
7
  'element-header__chevron': string;
8
8
  'element-header__content': string;
9
+ 'element-header__content--compact': string;
9
10
  'element-header__content--element': string;
10
11
  'element-header__content--spacing': string;
11
12
  'element-header__icon': string;
12
13
  'element-header__icon--with-statusdot': string;
13
14
  'element-header__statusdot-container': string;
14
15
  'element-header__title': string;
16
+ 'element-header--compact': string;
15
17
  'text-wrapper': string;
16
18
  'text-wrapper__text--emphasised': string;
17
19
  'text-wrapper--sub-level': string;
@@ -17,7 +17,7 @@ const getResources = (language) => {
17
17
  };
18
18
  var normalStroke = "var(--color-action-graphics-onlight)";
19
19
  var normalFill = "transparent";
20
- var hoverFill = "#126F8721";
20
+ var hoverFill = "var(--color-action-graphics-onlight-hover)";
21
21
  var hoverStroke = "var(--color-action-graphics-onlight-hover)";
22
22
  var activeStroke = "var(--core-color-blueberry-800)";
23
23
  var fillColor = (isChecked, isActive, isHovered) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["mergedResources: HNDesignsystemFavoriteButton"],"sources":["../../../src/resources/HN.Designsystem.FavoriteButton.nb-NO.json","../../../src/components/FavoriteButton/resourceHelper.ts","../../../src/components/FavoriteButton/StarIcon.tsx","../../../src/components/FavoriteButton/FavoriteButton.tsx","../../../src/components/FavoriteButton/index.ts"],"sourcesContent":["{\n \"ariaLabel\": \"Favorittmarkering\"\n}\n","import { LanguageLocales } from '../../constants';\nimport nbNO from '../../resources/HN.Designsystem.FavoriteButton.nb-NO.json';\nimport { HNDesignsystemFavoriteButton } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemFavoriteButton => {\n switch (language) {\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import styles from './styles.module.scss';\n\nconst normalStroke = 'var(--color-action-graphics-onlight)';\nconst normalFill = 'transparent';\nconst hoverFill = '#126F8721'; // kan ikke bruke transparent token på svg\nconst hoverStroke = 'var(--color-action-graphics-onlight-hover)';\nconst activeStroke = 'var(--core-color-blueberry-800)';\n\nconst fillColor = (isChecked: boolean, isActive: boolean, isHovered: boolean): string => {\n if (isChecked) {\n if (isActive) {\n return activeStroke;\n } else {\n if (isHovered) {\n return hoverStroke;\n } else {\n return normalStroke;\n }\n }\n } else {\n if (isHovered) {\n return hoverFill;\n } else {\n return normalFill;\n }\n }\n};\n\nconst strokeColor = (isActive: boolean, isHovered: boolean): string => {\n if (isActive) {\n return activeStroke;\n } else {\n if (isHovered) {\n return hoverStroke;\n } else {\n return normalStroke;\n }\n }\n};\n\nexport const starIconNormalMobile = (isChecked: boolean, isActive: boolean): React.JSX.Element => {\n return (\n <>\n <path\n d=\"M20.1026 31.1787L13.4007 34.7023C10.833 36.0523 7.83185 33.8719 8.32233 31.0126L9.60261 23.5492L4.17653 18.2675C2.09656 16.2428 3.24317 12.712 6.11581 12.2956L13.5982 11.2112L16.9493 4.42107C18.2332 1.81969 21.9426 1.81969 23.2265 4.42107L26.5776 11.2112L34.06 12.2956C36.9326 12.712 38.0792 16.2428 35.9993 18.2675L30.5732 23.5492L31.852 31.0044C32.3428 33.8651 29.3386 36.0456 26.7708 34.6925L20.1026 31.1787Z\"\n stroke=\"black\"\n fill=\"transparent\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n className={styles['favoritebutton__star-icon--focus']}\n display=\"block\"\n />\n <path\n d=\"M20.0961 26.5515L12.6372 30.4731L14.0621 22.1671L8.01953 16.2853L16.3582 15.0768L20.0877 7.52002L23.8171 15.0768L32.1558 16.2853L26.1133 22.1671L27.5381 30.4731L20.0961 26.5515Z\"\n stroke={strokeColor(isActive, false)}\n fill={fillColor(isChecked, isActive, false)}\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n );\n};\n\nexport const starIconHoverMobile = (isChecked: boolean, isActive: boolean): React.JSX.Element => (\n <>\n <path\n d=\"M22.2128 31.4832L16.2246 36.117C13.9303 37.8924 10.5961 36.2662 10.5826 33.3653L10.5475 25.7929L4.28665 21.5336C1.88672 19.9009 2.40278 16.2246 5.15948 15.3158L12.3399 12.9486L14.461 5.67964C15.2736 2.89484 18.9267 2.2507 20.6428 4.58962L25.1221 10.6947L32.6791 10.4633C35.5804 10.3745 37.3227 13.6526 35.6259 16.0077L31.1994 22.1514L33.7534 29.2712C34.7335 32.0033 32.1536 34.6724 29.3898 33.7857L22.2128 31.4832Z\"\n stroke=\"black\"\n fill=\"transparent\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n className={styles['favoritebutton__star-icon--focus']}\n />\n <path\n d=\"M21.4079 26.8365L14.7433 31.9937L14.7041 23.5664L7.73204 18.8233L15.7342 16.1851L18.0947 8.09555L23.0798 14.8899L31.5016 14.6321L26.5722 21.4738L29.4178 29.4062L21.4079 26.8365Z\"\n stroke={strokeColor(isActive, true)}\n fill={fillColor(isChecked, isActive, true)}\n fillOpacity={isChecked ? '1' : '0.13'}\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n);\nexport const starIconNormalDesktop = (isChecked: boolean, isActive: boolean): React.JSX.Element => (\n <>\n <path\n d=\"M30.1061 44.1854L20.3139 49.3338C17.7461 50.6838 14.745 48.5034 15.2355 45.6441L17.1061 34.7394L9.17653 27.0207C7.09656 24.9961 8.24318 21.4653 11.1158 21.0489L22.053 19.4638L26.9493 9.54278C28.2331 6.9414 31.9426 6.94139 33.2265 9.54278L38.1227 19.4638L49.06 21.0489C51.9326 21.4653 53.0792 24.9961 50.9993 27.0207L43.0697 34.7394L44.9389 45.6359C45.4296 48.4966 42.4254 50.6772 39.8576 49.324L30.1061 44.1854Z\"\n stroke=\"black\"\n fill=\"transparent\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n className={styles['favoritebutton__star-icon--focus']}\n />\n <path\n d=\"M30.0998 39.4723L19.5927 44.9966L21.5998 33.2961L13.0879 25.0106L24.8343 23.3082L30.0879 12.6632L35.3414 23.3082L47.0879 25.0106L38.576 33.2961L40.5831 44.9966L30.0998 39.4723Z\"\n stroke={strokeColor(isActive, false)}\n fill={fillColor(isChecked, isActive, false)}\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n);\n\nexport const starIconHoverDesktop = (isChecked: boolean, isActive: boolean): React.JSX.Element => (\n <>\n <path\n d=\"M33.1609 44.7458L24.4114 51.5164C22.1171 53.2918 18.783 51.6656 18.7695 48.7646L18.7181 37.7007L9.56864 31.4763C7.1687 29.8436 7.68476 26.1672 10.4415 25.2584L20.9373 21.7982L24.0364 11.1776C24.849 8.39281 28.5021 7.74867 30.2182 10.0876L36.7629 19.0077L47.8092 18.6695C50.7105 18.5807 52.4528 21.8588 50.756 24.2138L44.2872 33.1922L48.0201 43.5985C49.0002 46.3306 46.4203 48.9997 43.6565 48.113L33.1609 44.7458Z\"\n stroke=\"black\"\n fill=\"transparent\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n className={styles['favoritebutton__star-icon--focus']}\n />\n <path\n d=\"M32.3991 40.1029L23.0108 47.3678L22.9557 35.4965L13.1343 28.815L24.4067 25.0987L27.732 13.7031L34.7542 23.2741L46.6178 22.9109L39.674 32.5486L43.6823 43.7228L32.3991 40.1029Z\"\n stroke={strokeColor(isActive, true)}\n fill={fillColor(isChecked, isActive, true)}\n fillOpacity={isChecked ? '1' : '0.13'}\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n);\n","import React, { AriaAttributes } from 'react';\n\nimport classNames from 'classnames';\n\nimport { getResources } from './resourceHelper';\nimport { starIconHoverDesktop, starIconHoverMobile, starIconNormalDesktop, starIconNormalMobile } from './StarIcon';\nimport { AnalyticsId, HTMLButtonProps, LanguageLocales } from '../../constants';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { HNDesignsystemFavoriteButton } from '../../resources/Resources';\nimport { useLanguage } from '../../utils/language';\nimport { isMutableRefObject } from '../../utils/refs';\n\nimport styles from './styles.module.scss';\n\nexport interface FavoriteButtonProps extends Omit<HTMLButtonProps, 'type'>, AriaAttributes {\n /** Determines if the FavoriteButton is checked */\n checked: boolean;\n /** Gives a unique id to the button */\n id?: string;\n /** Function that is called when clicked */\n onClick: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;\n /** Resources for component */\n resources?: Partial<HNDesignsystemFavoriteButton>;\n /** Specifies the focus order relative to the other buttons or controls on the page */\n tabIndex?: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const FavoriteButton = React.forwardRef(function FavoriteButtonForwardedRef(\n props: FavoriteButtonProps,\n ref: React.ForwardedRef<HTMLButtonElement>\n) {\n const { checked, id, onClick, resources, tabIndex, testId, ...other } = props;\n\n const buttonWrapperClasses = classNames(styles.favoritebutton);\n const { refObject, isHovered, isActive } = usePseudoClasses<HTMLButtonElement>(isMutableRefObject(ref) ? ref : null);\n const breakpoint = useBreakpoint();\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemFavoriteButton = {\n ...defaultResources,\n ...resources,\n ariaLabel: other['aria-label'] || resources?.ariaLabel || defaultResources.ariaLabel,\n };\n\n const isMobile = breakpoint <= Breakpoint.sm;\n\n const starIcon = ((): React.JSX.Element => {\n if (isMobile) {\n if (isHovered) {\n return starIconHoverMobile(checked, isActive);\n } else {\n return starIconNormalMobile(checked, isActive);\n }\n } else {\n if (isHovered) {\n return starIconHoverDesktop(checked, isActive);\n } else {\n return starIconNormalDesktop(checked, isActive);\n }\n }\n })();\n\n return (\n <button\n id={id}\n onClick={onClick}\n data-testid={testId}\n data-analyticsid={AnalyticsId.FavoriteButton}\n className={buttonWrapperClasses}\n ref={refObject}\n tabIndex={tabIndex}\n role=\"switch\"\n aria-checked={checked}\n type=\"button\"\n aria-label={mergedResources.ariaLabel}\n {...other}\n >\n <svg focusable={false} overflow=\"visible\" role=\"presentation\" viewBox={isMobile ? '0 0 41 41' : '0 0 61 61'}>\n {starIcon}\n </svg>\n </button>\n );\n});\n\nFavoriteButton.displayName = 'FavoriteButton';\n\nexport default FavoriteButton;\n","export * from './FavoriteButton';\n\nimport { FavoriteButton } from './FavoriteButton';\nexport default FavoriteButton;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["mergedResources: HNDesignsystemFavoriteButton"],"sources":["../../../src/resources/HN.Designsystem.FavoriteButton.nb-NO.json","../../../src/components/FavoriteButton/resourceHelper.ts","../../../src/components/FavoriteButton/StarIcon.tsx","../../../src/components/FavoriteButton/FavoriteButton.tsx","../../../src/components/FavoriteButton/index.ts"],"sourcesContent":["{\n \"ariaLabel\": \"Favorittmarkering\"\n}\n","import { LanguageLocales } from '../../constants';\nimport nbNO from '../../resources/HN.Designsystem.FavoriteButton.nb-NO.json';\nimport { HNDesignsystemFavoriteButton } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemFavoriteButton => {\n switch (language) {\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import styles from './styles.module.scss';\n\nconst normalStroke = 'var(--color-action-graphics-onlight)';\nconst normalFill = 'transparent';\nconst hoverFill = 'var(--color-action-graphics-onlight-hover)';\nconst hoverStroke = 'var(--color-action-graphics-onlight-hover)';\nconst activeStroke = 'var(--core-color-blueberry-800)';\n\nconst fillColor = (isChecked: boolean, isActive: boolean, isHovered: boolean): string => {\n if (isChecked) {\n if (isActive) {\n return activeStroke;\n } else {\n if (isHovered) {\n return hoverStroke;\n } else {\n return normalStroke;\n }\n }\n } else {\n if (isHovered) {\n return hoverFill;\n } else {\n return normalFill;\n }\n }\n};\n\nconst strokeColor = (isActive: boolean, isHovered: boolean): string => {\n if (isActive) {\n return activeStroke;\n } else {\n if (isHovered) {\n return hoverStroke;\n } else {\n return normalStroke;\n }\n }\n};\n\nexport const starIconNormalMobile = (isChecked: boolean, isActive: boolean): React.JSX.Element => {\n return (\n <>\n <path\n d=\"M20.1026 31.1787L13.4007 34.7023C10.833 36.0523 7.83185 33.8719 8.32233 31.0126L9.60261 23.5492L4.17653 18.2675C2.09656 16.2428 3.24317 12.712 6.11581 12.2956L13.5982 11.2112L16.9493 4.42107C18.2332 1.81969 21.9426 1.81969 23.2265 4.42107L26.5776 11.2112L34.06 12.2956C36.9326 12.712 38.0792 16.2428 35.9993 18.2675L30.5732 23.5492L31.852 31.0044C32.3428 33.8651 29.3386 36.0456 26.7708 34.6925L20.1026 31.1787Z\"\n stroke=\"black\"\n fill=\"transparent\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n className={styles['favoritebutton__star-icon--focus']}\n display=\"block\"\n />\n <path\n d=\"M20.0961 26.5515L12.6372 30.4731L14.0621 22.1671L8.01953 16.2853L16.3582 15.0768L20.0877 7.52002L23.8171 15.0768L32.1558 16.2853L26.1133 22.1671L27.5381 30.4731L20.0961 26.5515Z\"\n stroke={strokeColor(isActive, false)}\n fill={fillColor(isChecked, isActive, false)}\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n );\n};\n\nexport const starIconHoverMobile = (isChecked: boolean, isActive: boolean): React.JSX.Element => (\n <>\n <path\n d=\"M22.2128 31.4832L16.2246 36.117C13.9303 37.8924 10.5961 36.2662 10.5826 33.3653L10.5475 25.7929L4.28665 21.5336C1.88672 19.9009 2.40278 16.2246 5.15948 15.3158L12.3399 12.9486L14.461 5.67964C15.2736 2.89484 18.9267 2.2507 20.6428 4.58962L25.1221 10.6947L32.6791 10.4633C35.5804 10.3745 37.3227 13.6526 35.6259 16.0077L31.1994 22.1514L33.7534 29.2712C34.7335 32.0033 32.1536 34.6724 29.3898 33.7857L22.2128 31.4832Z\"\n stroke=\"black\"\n fill=\"transparent\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n className={styles['favoritebutton__star-icon--focus']}\n />\n <path\n d=\"M21.4079 26.8365L14.7433 31.9937L14.7041 23.5664L7.73204 18.8233L15.7342 16.1851L18.0947 8.09555L23.0798 14.8899L31.5016 14.6321L26.5722 21.4738L29.4178 29.4062L21.4079 26.8365Z\"\n stroke={strokeColor(isActive, true)}\n fill={fillColor(isChecked, isActive, true)}\n fillOpacity={isChecked ? '1' : '0.13'}\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n);\nexport const starIconNormalDesktop = (isChecked: boolean, isActive: boolean): React.JSX.Element => (\n <>\n <path\n d=\"M30.1061 44.1854L20.3139 49.3338C17.7461 50.6838 14.745 48.5034 15.2355 45.6441L17.1061 34.7394L9.17653 27.0207C7.09656 24.9961 8.24318 21.4653 11.1158 21.0489L22.053 19.4638L26.9493 9.54278C28.2331 6.9414 31.9426 6.94139 33.2265 9.54278L38.1227 19.4638L49.06 21.0489C51.9326 21.4653 53.0792 24.9961 50.9993 27.0207L43.0697 34.7394L44.9389 45.6359C45.4296 48.4966 42.4254 50.6772 39.8576 49.324L30.1061 44.1854Z\"\n stroke=\"black\"\n fill=\"transparent\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n className={styles['favoritebutton__star-icon--focus']}\n />\n <path\n d=\"M30.0998 39.4723L19.5927 44.9966L21.5998 33.2961L13.0879 25.0106L24.8343 23.3082L30.0879 12.6632L35.3414 23.3082L47.0879 25.0106L38.576 33.2961L40.5831 44.9966L30.0998 39.4723Z\"\n stroke={strokeColor(isActive, false)}\n fill={fillColor(isChecked, isActive, false)}\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n);\n\nexport const starIconHoverDesktop = (isChecked: boolean, isActive: boolean): React.JSX.Element => (\n <>\n <path\n d=\"M33.1609 44.7458L24.4114 51.5164C22.1171 53.2918 18.783 51.6656 18.7695 48.7646L18.7181 37.7007L9.56864 31.4763C7.1687 29.8436 7.68476 26.1672 10.4415 25.2584L20.9373 21.7982L24.0364 11.1776C24.849 8.39281 28.5021 7.74867 30.2182 10.0876L36.7629 19.0077L47.8092 18.6695C50.7105 18.5807 52.4528 21.8588 50.756 24.2138L44.2872 33.1922L48.0201 43.5985C49.0002 46.3306 46.4203 48.9997 43.6565 48.113L33.1609 44.7458Z\"\n stroke=\"black\"\n fill=\"transparent\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n className={styles['favoritebutton__star-icon--focus']}\n />\n <path\n d=\"M32.3991 40.1029L23.0108 47.3678L22.9557 35.4965L13.1343 28.815L24.4067 25.0987L27.732 13.7031L34.7542 23.2741L46.6178 22.9109L39.674 32.5486L43.6823 43.7228L32.3991 40.1029Z\"\n stroke={strokeColor(isActive, true)}\n fill={fillColor(isChecked, isActive, true)}\n fillOpacity={isChecked ? '1' : '0.13'}\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n);\n","import React, { AriaAttributes } from 'react';\n\nimport classNames from 'classnames';\n\nimport { getResources } from './resourceHelper';\nimport { starIconHoverDesktop, starIconHoverMobile, starIconNormalDesktop, starIconNormalMobile } from './StarIcon';\nimport { AnalyticsId, HTMLButtonProps, LanguageLocales } from '../../constants';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { HNDesignsystemFavoriteButton } from '../../resources/Resources';\nimport { useLanguage } from '../../utils/language';\nimport { isMutableRefObject } from '../../utils/refs';\n\nimport styles from './styles.module.scss';\n\nexport interface FavoriteButtonProps extends Omit<HTMLButtonProps, 'type'>, AriaAttributes {\n /** Determines if the FavoriteButton is checked */\n checked: boolean;\n /** Gives a unique id to the button */\n id?: string;\n /** Function that is called when clicked */\n onClick: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;\n /** Resources for component */\n resources?: Partial<HNDesignsystemFavoriteButton>;\n /** Specifies the focus order relative to the other buttons or controls on the page */\n tabIndex?: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const FavoriteButton = React.forwardRef(function FavoriteButtonForwardedRef(\n props: FavoriteButtonProps,\n ref: React.ForwardedRef<HTMLButtonElement>\n) {\n const { checked, id, onClick, resources, tabIndex, testId, ...other } = props;\n\n const buttonWrapperClasses = classNames(styles.favoritebutton);\n const { refObject, isHovered, isActive } = usePseudoClasses<HTMLButtonElement>(isMutableRefObject(ref) ? ref : null);\n const breakpoint = useBreakpoint();\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemFavoriteButton = {\n ...defaultResources,\n ...resources,\n ariaLabel: other['aria-label'] || resources?.ariaLabel || defaultResources.ariaLabel,\n };\n\n const isMobile = breakpoint <= Breakpoint.sm;\n\n const starIcon = ((): React.JSX.Element => {\n if (isMobile) {\n if (isHovered) {\n return starIconHoverMobile(checked, isActive);\n } else {\n return starIconNormalMobile(checked, isActive);\n }\n } else {\n if (isHovered) {\n return starIconHoverDesktop(checked, isActive);\n } else {\n return starIconNormalDesktop(checked, isActive);\n }\n }\n })();\n\n return (\n <button\n id={id}\n onClick={onClick}\n data-testid={testId}\n data-analyticsid={AnalyticsId.FavoriteButton}\n className={buttonWrapperClasses}\n ref={refObject}\n tabIndex={tabIndex}\n role=\"switch\"\n aria-checked={checked}\n type=\"button\"\n aria-label={mergedResources.ariaLabel}\n {...other}\n >\n <svg focusable={false} overflow=\"visible\" role=\"presentation\" viewBox={isMobile ? '0 0 41 41' : '0 0 61 61'}>\n {starIcon}\n </svg>\n </button>\n );\n});\n\nFavoriteButton.displayName = 'FavoriteButton';\n\nexport default FavoriteButton;\n","export * from './FavoriteButton';\n\nimport { FavoriteButton } from './FavoriteButton';\nexport default FavoriteButton;\n"],"mappings":"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"}
@@ -17,9 +17,17 @@
17
17
  background-color: transparent;
18
18
  outline: none;
19
19
  padding: 0;
20
- margin: 4px;
20
+ margin: var(--core-space-3xs) 0 var(--core-space-3xs) var(--core-space-2xs);
21
21
  cursor: pointer;
22
22
 
23
+ &:hover {
24
+ background-color: var(--color-action-background-transparent-onmulticolor-hover);
25
+ }
26
+
27
+ &:active {
28
+ background-color: var(--color-action-background-transparent-onmulticolor-active);
29
+ }
30
+
23
31
  &:focus-visible {
24
32
  outline: 4px solid var(--color-action-border-onlight-focus);
25
33
  }
@@ -64,8 +72,8 @@
64
72
 
65
73
  &--fill {
66
74
  > * {
67
- margin-top: 8px !important;
68
- margin-bottom: 8px !important;
75
+ margin-top: var(--core-space-2xs) !important;
76
+ margin-bottom: var(--core-space-2xs) !important;
69
77
  }
70
78
  }
71
79
 
@@ -1,3 +1,5 @@
1
+ import "../../uuid.js";
2
+ import "../../environment.js";
1
3
  import { a as IconSize } from "../../constants2.js";
2
4
  import { t as usePseudoClasses } from "../../usePseudoClasses.js";
3
5
  import { t as breakpoints } from "../../grid.js";
@@ -9,18 +11,49 @@ import "../../spacing.js";
9
11
  import "../../currys.js";
10
12
  import "../../refs.js";
11
13
  import { t as Icon_default } from "../../Icon.js";
14
+ import "../../Check.js";
15
+ import "../../Avatar.js";
12
16
  import "../../CheckFill.js";
13
17
  import "../../ErrorSignFill.js";
14
18
  import "../../InfoSignFill.js";
15
19
  import "../../TriangleX.js";
16
20
  import { t as NotificationBadge_default } from "../../NotificationBadge.js";
21
+ import "../../Badge.js";
22
+ import "../../_rolldown_dynamic_import_helper.js";
23
+ import "../../useIsServerSide.js";
24
+ import "../../LazyIcon.js";
25
+ import "../../component.js";
17
26
  import { n as useBreakpoint } from "../../useBreakpoint.js";
18
27
  import "../../useIsMobileBreakpoint.js";
19
28
  import { n as getAriaLabelAttributes } from "../../accessibility.js";
29
+ import "../../Spacer.js";
30
+ import "../../useElementList.js";
31
+ import "../../useFocusableElements.js";
32
+ import "../../useFocusToggle.js";
33
+ import "../../focus.js";
34
+ import "../../useFocusTrap.js";
35
+ import "../../useIntersectionObserver.js";
36
+ import "../../useIsVisible.js";
37
+ import "../../debounce.js";
38
+ import "../../useLayoutEvent.js";
39
+ import "../../usePrevious.js";
40
+ import "../../useSize.js";
41
+ import "../../useResizeObserver.js";
42
+ import "../../useToggle.js";
43
+ import "../../useKeyboardEvent.js";
44
+ import "../../useOutsideEvent.js";
45
+ import "../../mobile.js";
46
+ import "../../src.js";
47
+ import "../../StatusDot.js";
20
48
  import { t as X_default } from "../../X.js";
21
49
  import { t as Close_default } from "../../Close.js";
22
50
  import { t as ChevronDown_default } from "../../ChevronDown.js";
23
51
  import { t as ChevronUp_default } from "../../ChevronUp.js";
52
+ import "../../Duolist.js";
53
+ import "../../Highlighter.js";
54
+ import "../../ElementHeaderText.js";
55
+ import "../../StatusDotList.js";
56
+ import { i as renderElementHeader } from "../../ElementHeader.js";
24
57
  import { t as Forward_default } from "../../Forward.js";
25
58
  import React, { useId, useState } from "react";
26
59
  import classNames from "classnames";
@@ -30,9 +63,26 @@ var Label = ({ label, variant, id, hasExpander, isExpanded, dismissable, onExpan
30
63
  const breakpoint = useBreakpoint();
31
64
  const { isHovered, refObject } = usePseudoClasses();
32
65
  const iconSize = breakpoint < breakpoints.lg ? IconSize.XSmall : IconSize.Small;
33
- const CustomTag = hasExpander ? "button" : "span";
66
+ const labelContainerClasses = classNames(styles["service-message__label-container"], styles[`service-message__label-container--${variant}`], hasExpander && styles[`service-message__label-container--has-expander`]);
67
+ const elementHeader = renderElementHeader(label, {
68
+ titleHtmlMarkup: "span",
69
+ isHovered,
70
+ size: "compact",
71
+ parentType: "expanderlist",
72
+ chevronIcon: hasExpander ? isExpanded ? ChevronUp_default : ChevronDown_default : void 0,
73
+ icon: /* @__PURE__ */ jsx(NotificationBadge_default, {
74
+ variant,
75
+ size: iconSize,
76
+ isHovered: hasExpander && isHovered
77
+ }),
78
+ closeButton: !hasExpander && dismissable ? /* @__PURE__ */ jsx(Close_default, {
79
+ onClick: onDismiss,
80
+ ariaLabel: closeBtnText,
81
+ className: styles["service-message__close"]
82
+ }) : void 0
83
+ });
34
84
  return /* @__PURE__ */ jsx("div", {
35
- className: classNames(styles["service-message__label-container"], hasExpander && styles[`service-message__label-container--has-expander`]),
85
+ className: labelContainerClasses,
36
86
  ref: refObject,
37
87
  children: /* @__PURE__ */ jsx("div", {
38
88
  className: styles["service-message__container"],
@@ -40,35 +90,23 @@ var Label = ({ label, variant, id, hasExpander, isExpanded, dismissable, onExpan
40
90
  className: styles["service-message__row"],
41
91
  children: /* @__PURE__ */ jsx("div", {
42
92
  className: styles["service-message__col"],
43
- children: /* @__PURE__ */ jsxs("div", {
93
+ children: /* @__PURE__ */ jsx("div", {
44
94
  className: styles["service-message__label"],
45
- children: [
46
- /* @__PURE__ */ jsx(NotificationBadge_default, {
47
- variant,
48
- size: iconSize,
49
- isHovered
50
- }),
51
- /* @__PURE__ */ jsx("h1", {
52
- className: styles["service-message__title"],
53
- id,
54
- children: /* @__PURE__ */ jsx(CustomTag, {
55
- className: styles["service-message__toggle"],
56
- onClick: hasExpander ? onExpand : void 0,
57
- "aria-expanded": hasExpander ? isExpanded : void 0,
58
- children: label
59
- })
60
- }),
61
- hasExpander && /* @__PURE__ */ jsx(Icon_default, {
62
- size: iconSize,
63
- svgIcon: isExpanded ? ChevronUp_default : ChevronDown_default,
64
- isHovered
65
- }),
66
- !hasExpander && dismissable && /* @__PURE__ */ jsx(Close_default, {
67
- onClick: onDismiss,
68
- ariaLabel: closeBtnText,
69
- className: styles["service-message__close"]
95
+ children: hasExpander ? /* @__PURE__ */ jsx("h1", {
96
+ className: styles["service-message__title"],
97
+ id,
98
+ children: /* @__PURE__ */ jsx("button", {
99
+ type: "button",
100
+ className: styles["service-message__toggle"],
101
+ onClick: onExpand,
102
+ "aria-expanded": isExpanded,
103
+ children: elementHeader
70
104
  })
71
- ]
105
+ }) : /* @__PURE__ */ jsx("h1", {
106
+ className: styles["service-message__title"],
107
+ id,
108
+ children: elementHeader
109
+ })
72
110
  })
73
111
  })
74
112
  })
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Label: React.FC<LabelProps>","Content: React.FC<ContentProps>","ServiceMessage: React.FC<ServiceMessageProps>"],"sources":["../../../src/components/ServiceMessage/ServiceMessage.tsx","../../../src/components/ServiceMessage/index.ts"],"sourcesContent":["import React, { useId, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { useBreakpoint } from '../../hooks/useBreakpoint';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { getColor } from '../../theme/currys';\nimport { breakpoints } from '../../theme/grid';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport { AnchorLinkTargets } from '../AnchorLink';\nimport NotificationBadge from '../Badge/NotificationBadge';\nimport Close from '../Close';\nimport Icon, { IconSize } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport Forward from '../Icons/Forward';\nimport X from '../Icons/X';\nimport { NotificationPanelVariants } from '../NotificationPanel';\n\nimport styles from './styles.module.scss';\n\ninterface LabelProps {\n label: string;\n variant: NotificationPanelVariants;\n id: string;\n hasExpander: boolean;\n isExpanded: boolean;\n dismissable: boolean;\n onExpand: () => void;\n onDismiss?: () => void;\n closeBtnText?: string;\n}\n\nconst Label: React.FC<LabelProps> = ({ label, variant, id, hasExpander, isExpanded, dismissable, onExpand, onDismiss, closeBtnText }) => {\n const breakpoint = useBreakpoint();\n const { isHovered, refObject } = usePseudoClasses<HTMLDivElement>();\n\n const iconSize = breakpoint < breakpoints.lg ? IconSize.XSmall : IconSize.Small;\n const CustomTag = hasExpander ? 'button' : 'span';\n\n const labelContainerClasses = classNames(\n styles['service-message__label-container'],\n hasExpander && styles[`service-message__label-container--has-expander`]\n );\n\n return (\n <div className={labelContainerClasses} ref={refObject}>\n <div className={styles['service-message__container']}>\n <div className={styles['service-message__row']}>\n <div className={styles['service-message__col']}>\n <div className={styles['service-message__label']}>\n <NotificationBadge variant={variant} size={iconSize} isHovered={isHovered} />\n <h1 className={styles['service-message__title']} id={id}>\n <CustomTag\n className={styles['service-message__toggle']}\n onClick={hasExpander ? onExpand : undefined}\n aria-expanded={hasExpander ? isExpanded : undefined}\n >\n {label}\n </CustomTag>\n </h1>\n {hasExpander && <Icon size={iconSize} svgIcon={isExpanded ? ChevronUp : ChevronDown} isHovered={isHovered} />}\n {!hasExpander && dismissable && (\n <Close onClick={onDismiss} ariaLabel={closeBtnText} className={styles['service-message__close']} />\n )}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\ninterface ContentProps {\n info?: string;\n extraInfo?: string;\n urlTitle?: string;\n url?: string;\n target?: AnchorLinkTargets;\n dismissable: boolean;\n onDismiss?: () => void;\n closeBtnText?: string;\n}\n\nconst Content: React.FC<ContentProps> = ({ info, extraInfo, urlTitle, url, target, dismissable, closeBtnText, onDismiss }) => {\n const { refObject: readMoreRef, isHovered: readMoreHoverRefIsHovered } = usePseudoClasses<HTMLAnchorElement>();\n const { refObject: closeButtonRef, isHovered: closeButtonIsHovered } = usePseudoClasses<HTMLButtonElement>();\n\n const hasUrl = url && urlTitle;\n\n return (\n <div className={styles['service-message__container']}>\n <div className={styles['service-message__row']}>\n <div className={styles['service-message__col']}>\n <div className={styles['service-message__content']}>\n {info && <p className={styles['service-message__info']}>{info}</p>}\n {extraInfo && (\n <p className={classNames(styles['service-message__info'], styles['service-message__info--extra'])}>{extraInfo}</p>\n )}\n <div className={styles['service-message__actions']}>\n {hasUrl && (\n <a className={styles['service-message__action']} href={url} ref={readMoreRef} target={target}>\n {urlTitle}\n <Icon size={IconSize.XSmall} svgIcon={Forward} color={getColor('blueberry', 700)} isHovered={readMoreHoverRefIsHovered} />\n </a>\n )}\n\n {dismissable && (\n <button\n ref={closeButtonRef}\n className={classNames(styles['service-message__action'], styles['service-message__action--close'])}\n aria-label={closeBtnText}\n onClick={onDismiss}\n >\n {closeBtnText}\n <Icon size={IconSize.XSmall} svgIcon={X} color={getColor('blueberry', 700)} isHovered={closeButtonIsHovered} />\n </button>\n )}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport interface ServiceMessageProps {\n /** Sets a label for the notification panel. */\n label: string;\n /** String displayed in service-message when expanded */\n info?: string;\n /** String displayed in service-message when expanded, with a smaller font */\n extraInfo?: string;\n /** function that runs on dismiss */\n onDismiss?: () => void;\n /** Allows for dismiss to be an option, also for ServiceMessage with only label as content */\n dismissable?: boolean;\n /** Makes expander be open from start. */\n expanderOpenFromStart?: boolean;\n /** Name that describes a url-link for the user*/\n urlTitle?: string;\n /** Url for further information*/\n url?: string;\n /** Sets target for the anchorlink to the url*/\n target?: AnchorLinkTargets;\n /** Text on close-button in service messages. */\n closeBtnText?: string;\n /** Changes the visual representation. */\n variant?: NotificationPanelVariants;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nconst ServiceMessage: React.FC<ServiceMessageProps> = ({\n label,\n dismissable = true,\n onDismiss,\n info,\n extraInfo,\n urlTitle,\n url,\n target = '_self',\n closeBtnText = 'fjern melding',\n expanderOpenFromStart = false,\n variant = 'error',\n testId,\n}) => {\n const [isExpanded, setIsExpanded] = useState<boolean>(expanderOpenFromStart);\n\n const labelId = useId();\n const hasExpander = !!info || !!extraInfo;\n\n const ariaRole = variant === 'error' ? 'alert' : 'region';\n const ariaLabelAttributes = getAriaLabelAttributes({ label, id: labelId });\n\n const handleClick = (): void => {\n if (hasExpander) setIsExpanded(!isExpanded);\n };\n\n const classes = classNames(styles['service-message'], styles[`service-message--${variant}`]);\n\n return (\n <div className={classes} role={ariaRole} {...ariaLabelAttributes} data-testid={testId}>\n <Label\n label={label}\n variant={variant}\n id={labelId}\n hasExpander={hasExpander}\n isExpanded={isExpanded}\n dismissable={dismissable}\n onExpand={handleClick}\n onDismiss={onDismiss}\n closeBtnText={closeBtnText}\n />\n {hasExpander && isExpanded && (\n <Content\n info={info}\n extraInfo={extraInfo}\n urlTitle={urlTitle}\n url={url}\n target={target}\n dismissable={dismissable}\n onDismiss={onDismiss}\n closeBtnText={closeBtnText}\n />\n )}\n </div>\n );\n};\n\nexport default ServiceMessage;\n","import ServiceMessage from './ServiceMessage';\nexport * from './ServiceMessage';\nexport default ServiceMessage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["Label: React.FC<LabelProps>","Content: React.FC<ContentProps>","ServiceMessage: React.FC<ServiceMessageProps>"],"sources":["../../../src/components/ServiceMessage/ServiceMessage.tsx","../../../src/components/ServiceMessage/index.ts"],"sourcesContent":["import React, { useId, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { useBreakpoint } from '../../hooks/useBreakpoint';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { getColor } from '../../theme/currys';\nimport { breakpoints } from '../../theme/grid';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport { AnchorLinkTargets } from '../AnchorLink';\nimport NotificationBadge from '../Badge/NotificationBadge';\nimport Close from '../Close';\nimport { renderElementHeader } from '../ElementHeader/ElementHeader';\nimport Icon, { IconSize } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport Forward from '../Icons/Forward';\nimport X from '../Icons/X';\nimport { NotificationPanelVariants } from '../NotificationPanel';\n\nimport styles from './styles.module.scss';\n\ninterface LabelProps {\n label: string;\n variant: NotificationPanelVariants;\n id: string;\n hasExpander: boolean;\n isExpanded: boolean;\n dismissable: boolean;\n onExpand: () => void;\n onDismiss?: () => void;\n closeBtnText?: string;\n}\n\nconst Label: React.FC<LabelProps> = ({ label, variant, id, hasExpander, isExpanded, dismissable, onExpand, onDismiss, closeBtnText }) => {\n const breakpoint = useBreakpoint();\n const { isHovered, refObject } = usePseudoClasses<HTMLDivElement>();\n\n const iconSize = breakpoint < breakpoints.lg ? IconSize.XSmall : IconSize.Small;\n const labelContainerClasses = classNames(\n styles['service-message__label-container'],\n styles[`service-message__label-container--${variant}`],\n hasExpander && styles[`service-message__label-container--has-expander`]\n );\n\n const elementHeader = renderElementHeader(label, {\n titleHtmlMarkup: 'span',\n isHovered,\n size: 'compact',\n parentType: 'expanderlist',\n chevronIcon: hasExpander ? (isExpanded ? ChevronUp : ChevronDown) : undefined,\n icon: <NotificationBadge variant={variant} size={iconSize} isHovered={hasExpander && isHovered} />,\n closeButton:\n !hasExpander && dismissable ? (\n <Close onClick={onDismiss} ariaLabel={closeBtnText} className={styles['service-message__close']} />\n ) : undefined,\n });\n\n return (\n <div className={labelContainerClasses} ref={refObject}>\n <div className={styles['service-message__container']}>\n <div className={styles['service-message__row']}>\n <div className={styles['service-message__col']}>\n <div className={styles['service-message__label']}>\n {hasExpander ? (\n <h1 className={styles['service-message__title']} id={id}>\n <button type=\"button\" className={styles['service-message__toggle']} onClick={onExpand} aria-expanded={isExpanded}>\n {elementHeader}\n </button>\n </h1>\n ) : (\n <h1 className={styles['service-message__title']} id={id}>\n {elementHeader}\n </h1>\n )}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\ninterface ContentProps {\n info?: string;\n extraInfo?: string;\n urlTitle?: string;\n url?: string;\n target?: AnchorLinkTargets;\n dismissable: boolean;\n onDismiss?: () => void;\n closeBtnText?: string;\n}\n\nconst Content: React.FC<ContentProps> = ({ info, extraInfo, urlTitle, url, target, dismissable, closeBtnText, onDismiss }) => {\n const { refObject: readMoreRef, isHovered: readMoreHoverRefIsHovered } = usePseudoClasses<HTMLAnchorElement>();\n const { refObject: closeButtonRef, isHovered: closeButtonIsHovered } = usePseudoClasses<HTMLButtonElement>();\n\n const hasUrl = url && urlTitle;\n\n return (\n <div className={styles['service-message__container']}>\n <div className={styles['service-message__row']}>\n <div className={styles['service-message__col']}>\n <div className={styles['service-message__content']}>\n {info && <p className={styles['service-message__info']}>{info}</p>}\n {extraInfo && (\n <p className={classNames(styles['service-message__info'], styles['service-message__info--extra'])}>{extraInfo}</p>\n )}\n <div className={styles['service-message__actions']}>\n {hasUrl && (\n <a className={styles['service-message__action']} href={url} ref={readMoreRef} target={target}>\n {urlTitle}\n <Icon size={IconSize.XSmall} svgIcon={Forward} color={getColor('blueberry', 700)} isHovered={readMoreHoverRefIsHovered} />\n </a>\n )}\n\n {dismissable && (\n <button\n ref={closeButtonRef}\n className={classNames(styles['service-message__action'], styles['service-message__action--close'])}\n aria-label={closeBtnText}\n onClick={onDismiss}\n >\n {closeBtnText}\n <Icon size={IconSize.XSmall} svgIcon={X} color={getColor('blueberry', 700)} isHovered={closeButtonIsHovered} />\n </button>\n )}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport interface ServiceMessageProps {\n /** Sets a label for the notification panel. */\n label: string;\n /** String displayed in service-message when expanded */\n info?: string;\n /** String displayed in service-message when expanded, with a smaller font */\n extraInfo?: string;\n /** function that runs on dismiss */\n onDismiss?: () => void;\n /** Allows for dismiss to be an option, also for ServiceMessage with only label as content */\n dismissable?: boolean;\n /** Makes expander be open from start. */\n expanderOpenFromStart?: boolean;\n /** Name that describes a url-link for the user*/\n urlTitle?: string;\n /** Url for further information*/\n url?: string;\n /** Sets target for the anchorlink to the url*/\n target?: AnchorLinkTargets;\n /** Text on close-button in service messages. */\n closeBtnText?: string;\n /** Changes the visual representation. */\n variant?: NotificationPanelVariants;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nconst ServiceMessage: React.FC<ServiceMessageProps> = ({\n label,\n dismissable = true,\n onDismiss,\n info,\n extraInfo,\n urlTitle,\n url,\n target = '_self',\n closeBtnText = 'fjern melding',\n expanderOpenFromStart = false,\n variant = 'error',\n testId,\n}) => {\n const [isExpanded, setIsExpanded] = useState<boolean>(expanderOpenFromStart);\n\n const labelId = useId();\n const hasExpander = !!info || !!extraInfo;\n\n const ariaRole = variant === 'error' ? 'alert' : 'region';\n const ariaLabelAttributes = getAriaLabelAttributes({ label, id: labelId });\n\n const handleClick = (): void => {\n if (hasExpander) setIsExpanded(!isExpanded);\n };\n\n const classes = classNames(styles['service-message'], styles[`service-message--${variant}`]);\n\n return (\n <div className={classes} role={ariaRole} {...ariaLabelAttributes} data-testid={testId}>\n <Label\n label={label}\n variant={variant}\n id={labelId}\n hasExpander={hasExpander}\n isExpanded={isExpanded}\n dismissable={dismissable}\n onExpand={handleClick}\n onDismiss={onDismiss}\n closeBtnText={closeBtnText}\n />\n {hasExpander && isExpanded && (\n <Content\n info={info}\n extraInfo={extraInfo}\n urlTitle={urlTitle}\n url={url}\n target={target}\n dismissable={dismissable}\n onDismiss={onDismiss}\n closeBtnText={closeBtnText}\n />\n )}\n </div>\n );\n};\n\nexport default ServiceMessage;\n","import ServiceMessage from './ServiceMessage';\nexport * from './ServiceMessage';\nexport default ServiceMessage;\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  @use 'sass:map';
2
- @use '../../scss/spacers' as spacers;
3
- @use '../../scss/palette' as palette;
4
2
  @use '../../scss/font-settings' as font-settings;
3
+ @import '../../scss/supernova/styles/colors.css';
4
+ @import '../../scss/supernova/styles/spacers.css';
5
5
  @import '../../scss/breakpoints';
6
6
  @import '../../scss/grid';
7
7
 
@@ -16,57 +16,45 @@
16
16
  }
17
17
 
18
18
  &--success {
19
- background-color: palette.$kiwi50;
20
-
21
- &:hover {
22
- background-color: rgba-to-rgb(rgba(palette.$kiwi500, 0.1), palette.$kiwi50);
23
- }
19
+ background-color: var(--color-notification-background-success);
24
20
 
25
21
  &#{$servicemessage},
26
22
  &#{$servicemessage}__label-container {
27
- border-color: palette.$kiwi900;
23
+ border-color: var(--color-notification-border-success);
28
24
  }
29
25
  }
30
26
 
31
27
  &--info {
32
- background-color: palette.$blueberry50;
33
-
34
- &:hover {
35
- background-color: rgba-to-rgb(rgba(palette.$blueberry500, 0.1), palette.$blueberry50);
36
- }
28
+ background-color: var(--color-notification-background-info);
37
29
 
38
30
  &#{$servicemessage},
39
31
  &#{$servicemessage}__label-container {
40
- border-color: palette.$blueberry700;
32
+ border-color: var(--color-notification-border-info);
41
33
  }
42
34
  }
43
35
 
44
36
  &--warn {
45
- background-color: palette.$banana50;
46
-
47
- &:hover {
48
- background-color: rgba-to-rgb(rgba(palette.$banana500, 0.1), palette.$banana50);
49
- }
37
+ background-color: var(--color-notification-background-warning);
50
38
 
51
39
  &#{$servicemessage},
52
40
  &#{$servicemessage}__label-container {
53
- border-color: palette.$banana700;
41
+ border-color: var(--color-notification-border-warning);
54
42
  }
55
43
  }
56
44
 
57
45
  &--error {
58
- background-color: palette.$cherry50;
59
-
60
- &:hover {
61
- background-color: rgba-to-rgb(rgba(palette.$cherry500, 0.1), palette.$cherry50);
62
- }
46
+ background-color: var(--color-notification-background-error);
63
47
 
64
48
  &#{$servicemessage},
65
49
  &#{$servicemessage}__label-container {
66
- border-color: palette.$cherry700;
50
+ border-color: var(--color-notification-border-error);
67
51
  }
68
52
  }
69
53
 
54
+ &__icon {
55
+ fill: var(--color-action-graphics-onlight);
56
+ }
57
+
70
58
  &__container {
71
59
  @include make-container;
72
60
  @include make-container-max-widths;
@@ -83,16 +71,53 @@
83
71
 
84
72
  &__label-container {
85
73
  position: relative;
86
- padding-top: spacers.getSpacer(3xs);
87
- padding-bottom: spacers.getSpacer(3xs);
88
74
 
89
- @media (min-width: map.get($grid-breakpoints, lg)) {
90
- padding-top: spacers.getSpacer(2xs);
91
- padding-bottom: spacers.getSpacer(2xs);
75
+ &--has-expander {
76
+ cursor: pointer;
92
77
  }
93
78
 
94
79
  &--has-expander:has(:focus-visible) {
95
- box-shadow: inset 0 0 0 2px palette.$black;
80
+ box-shadow: inset 0 0 0 4px var(--color-action-border-onlight-focus);
81
+ }
82
+
83
+ &--info#{&}--has-expander {
84
+ &:hover {
85
+ background-color: var(--color-notification-background-info-hover);
86
+ }
87
+
88
+ &:active {
89
+ background-color: var(--color-notification-background-info-active);
90
+ }
91
+ }
92
+
93
+ &--success#{&}--has-expander {
94
+ &:hover {
95
+ background-color: var(--color-notification-background-success-hover);
96
+ }
97
+
98
+ &:active {
99
+ background-color: var(--color-notification-background-success-active);
100
+ }
101
+ }
102
+
103
+ &--warn#{&}--has-expander {
104
+ &:hover {
105
+ background-color: var(--color-notification-background-warning-hover);
106
+ }
107
+
108
+ &:active {
109
+ background-color: var(--color-notification-background-warning-active);
110
+ }
111
+ }
112
+
113
+ &--error#{&}--has-expander {
114
+ &:hover {
115
+ background-color: var(--color-notification-background-error-hover);
116
+ }
117
+
118
+ &:active {
119
+ background-color: var(--color-notification-background-error-active);
120
+ }
96
121
  }
97
122
  }
98
123
 
@@ -100,18 +125,20 @@
100
125
  display: flex;
101
126
  width: 100%;
102
127
  align-items: center;
103
- gap: spacers.getSpacer(2xs);
128
+ gap: var(--core-space-2xs);
104
129
 
105
130
  @media (min-width: map.get($grid-breakpoints, md)) {
106
- gap: spacers.getSpacer(m);
131
+ gap: var(--core-space-m);
107
132
  }
108
133
  }
109
134
 
110
135
  &__title {
136
+ display: flex;
111
137
  width: 100%;
112
138
  font-weight: 700;
113
139
  font-size: font-settings.$font-size-xs;
114
- line-height: 1.25rem;
140
+ line-height: inherit;
141
+ margin: 0;
115
142
 
116
143
  @media (min-width: map.get($grid-breakpoints, md)) {
117
144
  font-size: font-settings.$font-size-sm;
@@ -120,6 +147,8 @@
120
147
 
121
148
  &__toggle {
122
149
  all: unset;
150
+ width: 100%;
151
+ box-sizing: border-box;
123
152
 
124
153
  // Triks for at hele labelen skal trigge klikk på knappen
125
154
  &::after {
@@ -127,24 +156,26 @@
127
156
  content: '';
128
157
  position: absolute;
129
158
  }
159
+
160
+ &:focus-visible {
161
+ outline: none !important;
162
+ }
130
163
  }
131
164
 
132
165
  &__content {
133
- margin-left: calc(38px + spacers.getSpacer(2xs));
134
- margin-right: calc(38px + spacers.getSpacer(2xs));
135
- padding-top: spacers.getSpacer(xs);
136
- padding-bottom: spacers.getSpacer(xs);
166
+ margin-left: 3.375rem;
167
+ margin-right: 3.375rem;
168
+ padding-top: var(--core-space-3xs);
169
+ padding-bottom: var(--core-space-2xs);
137
170
 
138
171
  @media (min-width: map.get($grid-breakpoints, md)) {
139
- margin-left: calc(38px + spacers.getSpacer(m));
140
- margin-right: calc(38px + spacers.getSpacer(m));
172
+ margin-left: 4.375rem;
173
+ margin-right: 4.375rem;
141
174
  }
142
175
 
143
176
  @media (min-width: map.get($grid-breakpoints, lg)) {
144
- margin-left: calc(48px + spacers.getSpacer(m));
145
- margin-right: calc(48px + spacers.getSpacer(m));
146
- padding-top: spacers.getSpacer(2xs);
147
- padding-bottom: spacers.getSpacer(s);
177
+ margin-left: 4rem;
178
+ margin-right: 4rem;
148
179
  }
149
180
  }
150
181
 
@@ -154,17 +185,16 @@
154
185
  margin: 0;
155
186
 
156
187
  @media (min-width: map.get($grid-breakpoints, lg)) {
157
- margin-top: spacers.getSpacer(xs);
158
188
  line-height: 1.625rem;
159
189
  font-size: font-settings.$font-size-sm;
160
190
  }
161
191
 
162
192
  &--extra {
163
193
  font-size: 0.875rem;
164
- margin-top: spacers.getSpacer(2xs);
194
+ margin-top: var(--core-space-2xs);
165
195
 
166
196
  @media (min-width: map.get($grid-breakpoints, lg)) {
167
- margin-top: spacers.getSpacer(xs);
197
+ margin-top: var(--core-space-xs);
168
198
  font-size: font-settings.$font-size-xs;
169
199
  line-height: font-settings.$lineheight-size-xs;
170
200
  }
@@ -175,32 +205,33 @@
175
205
  display: flex;
176
206
  justify-content: space-between;
177
207
  flex-flow: column wrap;
178
- gap: spacers.getSpacer(2xs);
179
- margin-top: spacers.getSpacer(2xs);
208
+ gap: var(--core-space-2xs);
209
+ margin-top: var(--core-space-2xs);
180
210
 
181
211
  @media (min-width: map.get($grid-breakpoints, sm)) {
182
212
  flex-direction: row;
183
213
  }
184
214
 
185
215
  @media (min-width: map.get($grid-breakpoints, lg)) {
186
- margin-top: spacers.getSpacer(s);
216
+ margin-top: var(--core-space-s);
187
217
  }
188
218
  }
189
219
 
190
220
  &__action {
221
+ cursor: pointer;
191
222
  display: flex;
192
223
  align-items: center;
193
224
  border: none;
194
225
  width: fit-content;
195
- color: palette.$blueberry700;
226
+ color: var(--color-action-text-onlight);
196
227
  font-weight: 600;
197
228
  font-size: font-settings.$font-size-xs;
198
229
  line-height: 1.25rem;
199
230
  background-color: transparent;
200
231
  text-decoration: none;
201
- padding: 0.5rem;
202
- margin-left: -0.5rem;
203
- gap: spacers.getSpacer(xs);
232
+ padding: var(--core-space-xs);
233
+ margin-left: calc(var(--core-space-xs) * -1);
234
+ gap: var(--core-space-xs);
204
235
 
205
236
  &:hover,
206
237
  &:active {
@@ -208,7 +239,7 @@
208
239
  }
209
240
 
210
241
  &:focus-visible {
211
- box-shadow: 0 0 0 2px palette.$black;
242
+ box-shadow: 0 0 0 4px var(--color-action-border-onlight-focus);
212
243
  background-color: transparent;
213
244
  border: 0;
214
245
  outline: none;
@@ -7,11 +7,16 @@ export type Styles = {
7
7
  'service-message__col': string;
8
8
  'service-message__container': string;
9
9
  'service-message__content': string;
10
+ 'service-message__icon': string;
10
11
  'service-message__info': string;
11
12
  'service-message__info--extra': string;
12
13
  'service-message__label': string;
13
14
  'service-message__label-container': string;
15
+ 'service-message__label-container--error': string;
14
16
  'service-message__label-container--has-expander': string;
17
+ 'service-message__label-container--info': string;
18
+ 'service-message__label-container--success': string;
19
+ 'service-message__label-container--warn': string;
15
20
  'service-message__row': string;
16
21
  'service-message__title': string;
17
22
  'service-message__toggle': string;
@@ -1,10 +1,10 @@
1
1
  @use 'sass:map';
2
2
  @use '../../scss/font-settings' as font-settings;
3
3
  @use '../../scss/palette' as palette;
4
- @use '../../scss/spacers' as spacers;
5
4
  @use '../../scss/screen-reader' as *;
6
5
  @use '../../scss/breakpoints' as breakpoints;
7
6
  @import '../../scss/supernova/styles/colors.css';
7
+ @import '../../scss/supernova/styles/spacers.css';
8
8
 
9
9
  .tile {
10
10
  // Referanse for grandparent selection i underklassene lenger nede
@@ -12,23 +12,23 @@
12
12
 
13
13
  display: flex;
14
14
  width: inherit;
15
- padding: spacers.getSpacer(2xs) spacers.getSpacer(2xs) spacers.getSpacer(xs);
15
+ padding: var(--core-space-2xs) var(--core-space-2xs) var(--core-space-xs);
16
16
  flex-direction: column;
17
17
  justify-content: center;
18
18
  background-color: var(--core-color-white);
19
- color: palette.$black;
19
+ color: var(--core-color-black);
20
20
  text-decoration: none;
21
21
  cursor: pointer;
22
- border: 1px solid var(--color-base-border-blueberry);
22
+ border: 1px solid var(--color-action-border-onlight);
23
23
  outline: none;
24
24
 
25
25
  @media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
26
- padding: spacers.getSpacer(l) spacers.getSpacer(m) spacers.getSpacer(l) spacers.getSpacer(s);
26
+ padding: var(--core-space-l) var(--core-space-m) var(--core-space-l) var(--core-space-s);
27
27
  justify-content: flex-start;
28
28
  }
29
29
 
30
30
  @media print {
31
- border: 1px solid palette.$black;
31
+ border: 1px solid var(--core-color-black);
32
32
  }
33
33
 
34
34
  &--fixed {
@@ -37,10 +37,10 @@
37
37
  }
38
38
 
39
39
  &--compact {
40
- padding: spacers.getSpacer(2xs) spacers.getSpacer(2xs) spacers.getSpacer(xs);
40
+ padding: var(--core-space-2xs) var(--core-space-2xs) var(--core-space-xs);
41
41
 
42
42
  @media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
43
- padding: spacers.getSpacer(s) spacers.getSpacer(m) spacers.getSpacer(s) spacers.getSpacer(s);
43
+ padding: var(--core-space-s) var(--core-space-m) var(--core-space-s) var(--core-space-s);
44
44
  }
45
45
  }
46
46
 
@@ -81,22 +81,22 @@
81
81
  text-align: center;
82
82
  line-height: 1.74rem;
83
83
  font-weight: 400;
84
- margin: spacers.getSpacer(3xs) 0 0;
84
+ margin: var(--core-space-3xs) 0 0;
85
85
 
86
86
  @media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
87
87
  text-align: left;
88
88
  font-weight: 600;
89
89
  font-size: font-settings.$font-size-md;
90
90
  line-height: 1.625rem;
91
- margin: spacers.getSpacer(s) 0 0 spacers.getSpacer(2xs);
91
+ margin: var(--core-space-s) 0 0 var(--core-space-2xs);
92
92
  }
93
93
 
94
94
  &--compact {
95
- margin: 0 0 0 spacers.getSpacer(3xs);
95
+ margin: 0 0 0 var(--core-space-3xs);
96
96
  text-align: left;
97
97
 
98
98
  @media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
99
- margin-left: spacers.getSpacer(2xs);
99
+ margin-left: var(--core-space-2xs);
100
100
  }
101
101
  }
102
102
  }
@@ -112,11 +112,11 @@
112
112
  &__description {
113
113
  font-size: 1.125rem;
114
114
  line-height: 1.75rem;
115
- margin: spacers.getSpacer(2xs) 0 0 spacers.getSpacer(2xs);
115
+ margin: var(--core-space-2xs) 0 0 var(--core-space-2xs);
116
116
  }
117
117
 
118
118
  &__children {
119
- margin: spacers.getSpacer(s) 0 0 spacers.getSpacer(2xs);
119
+ margin: var(--core-space-s) 0 0 var(--core-space-2xs);
120
120
  }
121
121
  }
122
122
 
@@ -136,7 +136,7 @@
136
136
  &--compact {
137
137
  flex-direction: row;
138
138
  align-items: center;
139
- padding-right: spacers.getSpacer(s);
139
+ padding-right: var(--core-space-s);
140
140
  padding-bottom: 0;
141
141
 
142
142
  svg {
@@ -129,11 +129,13 @@
129
129
  --color-action-background-onlight: #188097;
130
130
  --color-action-background-onlight-hover: #08667c;
131
131
 
132
- /* Hoverfarge for bakgrunn på interaktive elementer - onDark */
132
+ /* Hoverfarge for bakgrunn på interaktive elementer - hvor hover skal eksistere på forskjellige fargebakgrunner */
133
133
  --color-action-background-transparent-ondark-hover: #00000026;
134
+ --color-action-background-transparent-onmulticolor-hover: #00000013;
134
135
 
135
- /* Hoverfarge for bakgrunn på interaktive elementer - onDark selected */
136
+ /* Activefarge for bakgrunn på interaktive elementer - hvor hover skal eksistere på forskjellige fargebakgrunner */
136
137
  --color-action-background-transparent-ondark-hoverselected: #000000bf;
138
+ --color-action-background-transparent-onmulticolor-active: #00000026;
137
139
  --color-base-background-blueberry: #e4f7f9;
138
140
  --color-base-background-cherry: #fff2ea;
139
141
  --color-base-background-neutral: #f5f3f3;
@@ -263,4 +265,9 @@
263
265
  --color-notification-background-warning-active: #f9ea9f;
264
266
  --color-notification-background-success-hover: #c2edd6;
265
267
  --color-notification-background-success-active: #9de2bf;
266
- }/*$vite$:1*/
268
+ --color-lightbox-background-transparent-ondark-hover: #00000026;
269
+ --color-lightbox-background-transparent-ondark-hoverselected: #000000bf;
270
+ --component-lightbox-background-transparent-ondark-hover: #00000026;
271
+ --component-lightbox-background-transparent-ondark-hoverselected: #000000bf;
272
+ }
273
+ /*$vite$:1*/
@@ -129,11 +129,13 @@
129
129
  --color-action-background-onlight: #188097;
130
130
  --color-action-background-onlight-hover: #08667c;
131
131
 
132
- /* Hoverfarge for bakgrunn på interaktive elementer - onDark */
132
+ /* Hoverfarge for bakgrunn på interaktive elementer - hvor hover skal eksistere på forskjellige fargebakgrunner */
133
133
  --color-action-background-transparent-ondark-hover: #00000026;
134
+ --color-action-background-transparent-onmulticolor-hover: #00000013;
134
135
 
135
- /* Hoverfarge for bakgrunn på interaktive elementer - onDark selected */
136
+ /* Activefarge for bakgrunn på interaktive elementer - hvor hover skal eksistere på forskjellige fargebakgrunner */
136
137
  --color-action-background-transparent-ondark-hoverselected: #000000bf;
138
+ --color-action-background-transparent-onmulticolor-active: #00000026;
137
139
  --color-base-background-blueberry: #e4f7f9;
138
140
  --color-base-background-cherry: #fff2ea;
139
141
  --color-base-background-neutral: #f5f3f3;
@@ -263,4 +265,8 @@
263
265
  --color-notification-background-warning-active: #f9ea9f;
264
266
  --color-notification-background-success-hover: #c2edd6;
265
267
  --color-notification-background-success-active: #9de2bf;
266
- }
268
+ --color-lightbox-background-transparent-ondark-hover: #00000026;
269
+ --color-lightbox-background-transparent-ondark-hoverselected: #000000bf;
270
+ --component-lightbox-background-transparent-ondark-hover: #00000026;
271
+ --component-lightbox-background-transparent-ondark-hoverselected: #000000bf;
272
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@helsenorge/designsystem-react",
3
3
  "sideEffects": false,
4
4
  "private": false,
5
- "version": "13.0.2",
5
+ "version": "13.2.0",
6
6
  "description": "The official design system for Helsenorge built with React.",
7
7
  "repository": {
8
8
  "type": "git",
@@ -129,11 +129,13 @@
129
129
  --color-action-background-onlight: #188097;
130
130
  --color-action-background-onlight-hover: #08667c;
131
131
 
132
- /* Hoverfarge for bakgrunn på interaktive elementer - onDark */
132
+ /* Hoverfarge for bakgrunn på interaktive elementer - hvor hover skal eksistere på forskjellige fargebakgrunner */
133
133
  --color-action-background-transparent-ondark-hover: #00000026;
134
+ --color-action-background-transparent-onmulticolor-hover: #00000013;
134
135
 
135
- /* Hoverfarge for bakgrunn på interaktive elementer - onDark selected */
136
+ /* Activefarge for bakgrunn på interaktive elementer - hvor hover skal eksistere på forskjellige fargebakgrunner */
136
137
  --color-action-background-transparent-ondark-hoverselected: #000000bf;
138
+ --color-action-background-transparent-onmulticolor-active: #00000026;
137
139
  --color-base-background-blueberry: #e4f7f9;
138
140
  --color-base-background-cherry: #fff2ea;
139
141
  --color-base-background-neutral: #f5f3f3;
@@ -263,4 +265,8 @@
263
265
  --color-notification-background-warning-active: #f9ea9f;
264
266
  --color-notification-background-success-hover: #c2edd6;
265
267
  --color-notification-background-success-active: #9de2bf;
266
- }
268
+ --color-lightbox-background-transparent-ondark-hover: #00000026;
269
+ --color-lightbox-background-transparent-ondark-hoverselected: #000000bf;
270
+ --component-lightbox-background-transparent-ondark-hover: #00000026;
271
+ --component-lightbox-background-transparent-ondark-hoverselected: #000000bf;
272
+ }