@helsenorge/designsystem-react 15.1.0 → 15.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 +12 -0
- package/lib/Expander.js +4 -4
- package/lib/Expander.js.map +1 -1
- package/lib/FilterButtonAndChipsWrapper.js +15 -3
- package/lib/FilterButtonAndChipsWrapper.js.map +1 -1
- package/lib/FilterLinkList.js +3 -2
- package/lib/FilterLinkList.js.map +1 -1
- package/lib/FilterOverviewLinkList.js +10 -1
- package/lib/FilterOverviewLinkList.js.map +1 -1
- package/lib/InfoTeaser.js +1 -1
- package/lib/InfoTeaser.js.map +1 -1
- package/lib/components/Expander/Expander.d.ts +2 -0
- package/lib/components/Expander/styles.module.scss +24 -12
- package/lib/components/Expander/styles.module.scss.d.ts +2 -0
- package/lib/components/Filter/FilterButtonAndChipsWrapper/FilterButtonAndChipsWrapper.d.ts +3 -0
- package/lib/components/Filter/FilterButtonAndChipsWrapper/styles.module.scss +18 -2
- package/lib/components/Filter/FilterButtonAndChipsWrapper/styles.module.scss.d.ts +1 -0
- package/lib/components/Filter/FilterLinkList/FilterLinkList.d.ts +2 -0
- package/lib/components/Filter/FilterLinkList/FilterLinkList.module.scss +10 -0
- package/lib/components/Filter/FilterOverviewLinkList/FilterOverviewLinkList.d.ts +4 -1
- package/lib/components/InfoTeaser/InfoTeaser.d.ts +1 -1
- package/lib/components/InfoTeaser/styles.module.scss +13 -16
- package/lib/components/VisualContentgroupWithImage/VisualContentgroupWithImage.d.ts +13 -0
- package/lib/components/VisualContentgroupWithImage/index.d.ts +3 -0
- package/lib/components/VisualContentgroupWithImage/index.js +22 -0
- package/lib/components/VisualContentgroupWithImage/index.js.map +1 -0
- package/lib/components/VisualContentgroupWithImage/styles.module.scss +50 -0
- package/lib/components/VisualContentgroupWithImage/styles.module.scss.d.ts +12 -0
- package/lib/getFilterChips.js +3 -3
- package/lib/getFilterChips.js.map +1 -1
- package/package.json +1 -1
package/lib/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [15.2.0](https://github.com/helsenorge/designsystem/compare/v15.1.0...v15.2.0) (2026-06-25)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* nytt komponent visualcontentgroupwithimage ([deafe38](https://github.com/helsenorge/designsystem/commit/deafe3823a48dca3e2256cfd8d82bb701fdc5060)), closes [#376758](https://github.com/helsenorge/designsystem/issues/376758)
|
|
6
|
+
* **expander:** ny prop emphasised ([7ae7d9e](https://github.com/helsenorge/designsystem/commit/7ae7d9e4bea2253f555b6b6fb6c5a597e9e0c3eb)), closes [#380269](https://github.com/helsenorge/designsystem/issues/380269)
|
|
7
|
+
* **filter:** forbedre skjermleseroppførsel for aktive filter ([33de604](https://github.com/helsenorge/designsystem/commit/33de6047677cdc43018694e17e339e5202b0e53b)), closes [#375582](https://github.com/helsenorge/designsystem/issues/375582)
|
|
8
|
+
* **infoteaser:** title er optional ([b178185](https://github.com/helsenorge/designsystem/commit/b178185f6ad42ecb8bdadc532fe8fdff431c6486)), closes [#380754](https://github.com/helsenorge/designsystem/issues/380754)
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* **datepicker:** soft error forsvinner ikke ved popup valg ([5380c60](https://github.com/helsenorge/designsystem/commit/5380c60e6f6f75dcf798e14c128ddb458d51c8f4)), closes [#380884](https://github.com/helsenorge/designsystem/issues/380884)
|
|
1
13
|
|
|
2
14
|
## [15.1.0](https://github.com/helsenorge/designsystem/compare/v15.0.0...v15.1.0) (2026-06-16)
|
|
3
15
|
|
package/lib/Expander.js
CHANGED
|
@@ -20,7 +20,7 @@ var ExpanderSize = /* @__PURE__ */ function(ExpanderSize) {
|
|
|
20
20
|
//#endregion
|
|
21
21
|
//#region src/components/Expander/Expander.tsx
|
|
22
22
|
var Expander = (props) => {
|
|
23
|
-
const { buttonId, title, children, size = ExpanderSize.small, color, contentClassNames, svgIcon: icon, expanded = false, noNestedLine = false, sticky = false, testId, onExpand, renderChildrenWhenClosed = false, zIndex } = props;
|
|
23
|
+
const { buttonId, title, children, size = ExpanderSize.small, color, contentClassNames, svgIcon: icon, expanded = false, noNestedLine = false, emphasized = false, sticky = false, testId, onExpand, renderChildrenWhenClosed = false, zIndex } = props;
|
|
24
24
|
const [isExpanded, setIsExpanded] = useExpand(expanded, onExpand);
|
|
25
25
|
const expanderRef = useRef(null);
|
|
26
26
|
const triggerRef = useRef(null);
|
|
@@ -74,7 +74,7 @@ var Expander = (props) => {
|
|
|
74
74
|
width: isSticky && triggerSize?.width ? `${triggerSize?.width}px` : void 0,
|
|
75
75
|
height: isSticky && triggerSize?.height ? `${triggerSize?.height}px` : void 0
|
|
76
76
|
},
|
|
77
|
-
className: classNames({ [styles["expander__button-container--sticky"]]: isSticky }),
|
|
77
|
+
className: classNames(styles["expander__button-container"], { [styles["expander__button-container--sticky"]]: isSticky }),
|
|
78
78
|
children: /* @__PURE__ */ jsxs(Button_default, {
|
|
79
79
|
id: buttonId,
|
|
80
80
|
variant: "borderless",
|
|
@@ -93,9 +93,9 @@ var Expander = (props) => {
|
|
|
93
93
|
});
|
|
94
94
|
const renderContent = () => {
|
|
95
95
|
if (!renderChildrenWhenClosed && !isExpanded) return null;
|
|
96
|
-
const contentClassName = classNames(styles["expander__content"], styles[`expander__content--${size}`], size === ExpanderSize.large && styles[`expander__content--${color || "neutral"}`], size === ExpanderSize.large && icon && styles["expander__content--icon"], isExpanded && styles["expander__content--expanded"], size === ExpanderSize.small && !noNestedLine && styles["expander__content--nested-line--inner"], { [styles["expander__content--sticky"]]: isSticky }, contentClassNames);
|
|
96
|
+
const contentClassName = classNames(styles["expander__content"], styles[`expander__content--${size}`], size === ExpanderSize.large && styles[`expander__content--${color || "neutral"}`], size === ExpanderSize.large && icon && styles["expander__content--icon"], isExpanded && styles["expander__content--expanded"], size === ExpanderSize.small && !noNestedLine && styles["expander__content--nested-line--inner"], emphasized && styles["expander__content--emphasized"], { [styles["expander__content--sticky"]]: isSticky }, contentClassNames);
|
|
97
97
|
return /* @__PURE__ */ jsx("div", {
|
|
98
|
-
className: classNames(size === ExpanderSize.small && !noNestedLine && styles["expander__content--nested-line--outer"]),
|
|
98
|
+
className: classNames(size === ExpanderSize.small && !emphasized && !noNestedLine && styles["expander__content--nested-line--outer"]),
|
|
99
99
|
children: /* @__PURE__ */ jsx("div", {
|
|
100
100
|
className: contentClassName,
|
|
101
101
|
children
|
package/lib/Expander.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Expander.js","names":[],"sources":["../src/components/Expander/constants.ts","../src/components/Expander/Expander.tsx","../src/components/Expander/index.ts"],"sourcesContent":["export enum ExpanderSize {\n small = 'small',\n large = 'large',\n}\n","import { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { PaletteNames } from '../../theme/palette';\nimport type { SvgIcon } from '../Icon';\nimport type { IconName } from '../Icons/IconNames';\n\nimport { ExpanderSize } from './constants';\nimport { AnalyticsId } from '../../constants';\nimport { useExpand } from '../../hooks/useExpand';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { useSize } from '../../hooks/useSize';\nimport Button from '../Button';\nimport Icon, { IconSize } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport LazyIcon from '../LazyIcon';\n\nimport styles from './styles.module.scss';\n\nexport type ExpanderColors = Extract<PaletteNames, 'banana' | 'blueberry' | 'cherry' | 'kiwi' | 'neutral' | 'plum' | 'white'>;\n\nexport interface ExpanderProps {\n buttonId?: string;\n /** Sets the trigger title */\n title: string;\n /** Sets the expanded content */\n children?: React.ReactNode;\n /** Sets classnames on the content area */\n contentClassNames?: string;\n /** Sets the size of the expander. Default: ExpanderSize.small */\n size?: ExpanderSize;\n /** Sets the background of the expander. Requires size=ExpanderSize.large. */\n color?: ExpanderColors;\n /** Adds an icon to the expander trigger. Requires size=ExpanderSize.large. */\n svgIcon?: SvgIcon | IconName;\n /** Opens or closes the expander */\n expanded?: boolean;\n /** Removes border to the left of the content. Requires size=ExpanderSize.small. */\n noNestedLine?: boolean;\n /** Stick expander trigger to top of screen while scrolling down */\n sticky?: boolean;\n /** Called when expander is open/closed. */\n onExpand?: (isExpanded: boolean) => void;\n /** Whether to render children when closed (in which case they are hidden with CSS). Default: false */\n renderChildrenWhenClosed?: boolean;\n /** Sets the data-testid attribute on the expander button. */\n testId?: string;\n /** Overrides the default z-index of the expander header */\n zIndex?: number;\n}\n\nconst Expander: React.FC<ExpanderProps> = props => {\n const {\n buttonId,\n title,\n children,\n size = ExpanderSize.small,\n color,\n contentClassNames,\n svgIcon: icon,\n expanded = false,\n noNestedLine = false,\n sticky = false,\n testId,\n onExpand,\n renderChildrenWhenClosed = false,\n zIndex,\n } = props;\n const [isExpanded, setIsExpanded] = useExpand(expanded, onExpand);\n const expanderRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const { isHovered } = usePseudoClasses(triggerRef);\n const contentSize = useSize(expanderRef);\n const triggerSize = useSize(triggerRef);\n\n const isSticky = sticky && isExpanded;\n\n const renderChevron = (align: 'left' | 'right'): React.ReactNode => (\n <span className={classNames(styles['expander__icon'], styles[`expander__icon--${align}`])}>\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} isHovered={isHovered} />\n </span>\n );\n\n const triggerClassName = classNames(\n styles['expander__trigger'],\n size === ExpanderSize.large && styles[`expander__trigger--${size}`],\n size === ExpanderSize.large && styles[`expander__trigger--${color || 'neutral'}`],\n size === ExpanderSize.large && icon && styles['expander__trigger--icon'],\n isExpanded && styles['expander__trigger--expanded'],\n isSticky && styles['expander__trigger--sticky']\n );\n\n const renderTrigger = (): React.ReactNode => (\n <button\n id={buttonId}\n type=\"button\"\n className={triggerClassName}\n style={{\n zIndex: isHovered || isSticky ? zIndex : undefined,\n width: isSticky && contentSize?.width ? `${contentSize.width}px` : undefined,\n }}\n aria-expanded={isExpanded}\n ref={triggerRef}\n onClick={(): void => setIsExpanded(!isExpanded)}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Expander}\n >\n {size === ExpanderSize.small && renderChevron('left')}\n {icon && (\n <span className={classNames(styles['expander__icon'], styles['expander__icon--left'])}>\n {typeof icon === 'string' ? (\n <LazyIcon iconName={icon} size={IconSize.XSmall} isHovered={isHovered} />\n ) : (\n <Icon svgIcon={icon} size={IconSize.XSmall} isHovered={isHovered} />\n )}\n </span>\n )}\n {title}\n {size === ExpanderSize.large && renderChevron('right')}\n </button>\n );\n\n const buttonClassName = classNames(styles['expander__button'], isExpanded && styles['expander__button--expanded']);\n\n const renderButton = (): React.ReactNode => (\n <div\n style={{\n width: isSticky && triggerSize?.width ? `${triggerSize?.width}px` : undefined,\n height: isSticky && triggerSize?.height ? `${triggerSize?.height}px` : undefined,\n }}\n className={classNames({\n [styles['expander__button-container--sticky']]: isSticky,\n })}\n >\n <Button\n id={buttonId}\n variant=\"borderless\"\n textClassName={styles['expander__button__text']}\n className={buttonClassName}\n aria-expanded={isExpanded}\n ref={triggerRef}\n onClick={(): void => setIsExpanded(!isExpanded)}\n testId={testId}\n data-analyticsid={AnalyticsId.Expander}\n >\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} />\n {title}\n </Button>\n </div>\n );\n\n const renderContent = (): React.ReactNode => {\n if (!renderChildrenWhenClosed && !isExpanded) {\n return null;\n }\n\n const contentClassName = classNames(\n styles['expander__content'],\n styles[`expander__content--${size}`],\n size === ExpanderSize.large && styles[`expander__content--${color || 'neutral'}`],\n size === ExpanderSize.large && icon && styles['expander__content--icon'],\n isExpanded && styles['expander__content--expanded'],\n size === ExpanderSize.small && !noNestedLine && styles['expander__content--nested-line--inner'],\n { [styles['expander__content--sticky']]: isSticky },\n contentClassNames\n );\n const leftBorderClassName = classNames(size === ExpanderSize.small && !noNestedLine && styles['expander__content--nested-line--outer']);\n\n return (\n <div className={leftBorderClassName}>\n <div className={contentClassName}>{children}</div>\n </div>\n );\n };\n\n return (\n <div className={styles['expander']} ref={expanderRef}>\n {size === ExpanderSize.large ? renderTrigger() : renderButton()}\n {renderContent()}\n </div>\n );\n};\n\nexport default Expander;\n","import Expander from './Expander';\nexport { ExpanderSize } from './constants';\nexport * from './Expander';\nexport default Expander;\n"],"mappings":";;;;;;;;;;;;;;AAAA,IAAY,eAAL,yBAAA,cAAA;CACL,aAAA,WAAA;CACA,aAAA,WAAA;;AACF,EAAA,CAAA,CAAA;;;
|
|
1
|
+
{"version":3,"file":"Expander.js","names":[],"sources":["../src/components/Expander/constants.ts","../src/components/Expander/Expander.tsx","../src/components/Expander/index.ts"],"sourcesContent":["export enum ExpanderSize {\n small = 'small',\n large = 'large',\n}\n","import { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { PaletteNames } from '../../theme/palette';\nimport type { SvgIcon } from '../Icon';\nimport type { IconName } from '../Icons/IconNames';\n\nimport { ExpanderSize } from './constants';\nimport { AnalyticsId } from '../../constants';\nimport { useExpand } from '../../hooks/useExpand';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { useSize } from '../../hooks/useSize';\nimport Button from '../Button';\nimport Icon, { IconSize } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport LazyIcon from '../LazyIcon';\n\nimport styles from './styles.module.scss';\n\nexport type ExpanderColors = Extract<PaletteNames, 'banana' | 'blueberry' | 'cherry' | 'kiwi' | 'neutral' | 'plum' | 'white'>;\n\nexport interface ExpanderProps {\n buttonId?: string;\n /** Sets the trigger title */\n title: string;\n /** Sets the expanded content */\n children?: React.ReactNode;\n /** Sets classnames on the content area */\n contentClassNames?: string;\n /** Sets the size of the expander. Default: ExpanderSize.small */\n size?: ExpanderSize;\n /** Sets the background of the expander. Requires size=ExpanderSize.large. */\n color?: ExpanderColors;\n /** Adds an icon to the expander trigger. Requires size=ExpanderSize.large. */\n svgIcon?: SvgIcon | IconName;\n /** Opens or closes the expander */\n expanded?: boolean;\n /** Removes border to the left of the content. Requires size=ExpanderSize.small. */\n noNestedLine?: boolean;\n /** Emphasizes the content section. Intended for size=ExpanderSize.small. */\n emphasized?: boolean;\n /** Stick expander trigger to top of screen while scrolling down */\n sticky?: boolean;\n /** Called when expander is open/closed. */\n onExpand?: (isExpanded: boolean) => void;\n /** Whether to render children when closed (in which case they are hidden with CSS). Default: false */\n renderChildrenWhenClosed?: boolean;\n /** Sets the data-testid attribute on the expander button. */\n testId?: string;\n /** Overrides the default z-index of the expander header */\n zIndex?: number;\n}\n\nconst Expander: React.FC<ExpanderProps> = props => {\n const {\n buttonId,\n title,\n children,\n size = ExpanderSize.small,\n color,\n contentClassNames,\n svgIcon: icon,\n expanded = false,\n noNestedLine = false,\n emphasized = false,\n sticky = false,\n testId,\n onExpand,\n renderChildrenWhenClosed = false,\n zIndex,\n } = props;\n const [isExpanded, setIsExpanded] = useExpand(expanded, onExpand);\n const expanderRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const { isHovered } = usePseudoClasses(triggerRef);\n const contentSize = useSize(expanderRef);\n const triggerSize = useSize(triggerRef);\n\n const isSticky = sticky && isExpanded;\n\n const renderChevron = (align: 'left' | 'right'): React.ReactNode => (\n <span className={classNames(styles['expander__icon'], styles[`expander__icon--${align}`])}>\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} isHovered={isHovered} />\n </span>\n );\n\n const triggerClassName = classNames(\n styles['expander__trigger'],\n size === ExpanderSize.large && styles[`expander__trigger--${size}`],\n size === ExpanderSize.large && styles[`expander__trigger--${color || 'neutral'}`],\n size === ExpanderSize.large && icon && styles['expander__trigger--icon'],\n isExpanded && styles['expander__trigger--expanded'],\n isSticky && styles['expander__trigger--sticky']\n );\n\n const renderTrigger = (): React.ReactNode => (\n <button\n id={buttonId}\n type=\"button\"\n className={triggerClassName}\n style={{\n zIndex: isHovered || isSticky ? zIndex : undefined,\n width: isSticky && contentSize?.width ? `${contentSize.width}px` : undefined,\n }}\n aria-expanded={isExpanded}\n ref={triggerRef}\n onClick={(): void => setIsExpanded(!isExpanded)}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Expander}\n >\n {size === ExpanderSize.small && renderChevron('left')}\n {icon && (\n <span className={classNames(styles['expander__icon'], styles['expander__icon--left'])}>\n {typeof icon === 'string' ? (\n <LazyIcon iconName={icon} size={IconSize.XSmall} isHovered={isHovered} />\n ) : (\n <Icon svgIcon={icon} size={IconSize.XSmall} isHovered={isHovered} />\n )}\n </span>\n )}\n {title}\n {size === ExpanderSize.large && renderChevron('right')}\n </button>\n );\n\n const buttonClassName = classNames(styles['expander__button'], isExpanded && styles['expander__button--expanded']);\n\n const renderButton = (): React.ReactNode => (\n <div\n style={{\n width: isSticky && triggerSize?.width ? `${triggerSize?.width}px` : undefined,\n height: isSticky && triggerSize?.height ? `${triggerSize?.height}px` : undefined,\n }}\n className={classNames(styles['expander__button-container'], {\n [styles['expander__button-container--sticky']]: isSticky,\n })}\n >\n <Button\n id={buttonId}\n variant=\"borderless\"\n textClassName={styles['expander__button__text']}\n className={buttonClassName}\n aria-expanded={isExpanded}\n ref={triggerRef}\n onClick={(): void => setIsExpanded(!isExpanded)}\n testId={testId}\n data-analyticsid={AnalyticsId.Expander}\n >\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} />\n {title}\n </Button>\n </div>\n );\n\n const renderContent = (): React.ReactNode => {\n if (!renderChildrenWhenClosed && !isExpanded) {\n return null;\n }\n\n const contentClassName = classNames(\n styles['expander__content'],\n styles[`expander__content--${size}`],\n size === ExpanderSize.large && styles[`expander__content--${color || 'neutral'}`],\n size === ExpanderSize.large && icon && styles['expander__content--icon'],\n isExpanded && styles['expander__content--expanded'],\n size === ExpanderSize.small && !noNestedLine && styles['expander__content--nested-line--inner'],\n emphasized && styles['expander__content--emphasized'],\n { [styles['expander__content--sticky']]: isSticky },\n contentClassNames\n );\n const leftBorderClassName = classNames(\n size === ExpanderSize.small && !emphasized && !noNestedLine && styles['expander__content--nested-line--outer']\n );\n\n return (\n <div className={leftBorderClassName}>\n <div className={contentClassName}>{children}</div>\n </div>\n );\n };\n\n return (\n <div className={styles['expander']} ref={expanderRef}>\n {size === ExpanderSize.large ? renderTrigger() : renderButton()}\n {renderContent()}\n </div>\n );\n};\n\nexport default Expander;\n","import Expander from './Expander';\nexport { ExpanderSize } from './constants';\nexport * from './Expander';\nexport default Expander;\n"],"mappings":";;;;;;;;;;;;;;AAAA,IAAY,eAAL,yBAAA,cAAA;CACL,aAAA,WAAA;CACA,aAAA,WAAA;;AACF,EAAA,CAAA,CAAA;;;ACoDA,IAAM,YAAoC,UAAS;CACjD,MAAM,EACJ,UACA,OACA,UACA,OAAO,aAAa,OACpB,OACA,mBACA,SAAS,MACT,WAAW,OACX,eAAe,OACf,aAAa,OACb,SAAS,OACT,QACA,UACA,2BAA2B,OAC3B,WACE;CACJ,MAAM,CAAC,YAAY,iBAAiB,UAAU,UAAU,QAAQ;CAChE,MAAM,cAAc,OAAuB,IAAI;CAC/C,MAAM,aAAa,OAA0B,IAAI;CACjD,MAAM,EAAE,cAAc,iBAAiB,UAAU;CACjD,MAAM,cAAc,QAAQ,WAAW;CACvC,MAAM,cAAc,QAAQ,UAAU;CAEtC,MAAM,WAAW,UAAU;CAE3B,MAAM,iBAAiB,UACrB,oBAAC,QAAD;EAAM,WAAW,WAAW,OAAO,mBAAmB,OAAO,mBAAmB,QAAQ;YACtF,oBAAC,cAAD;GAAM,SAAS,aAAa,YAAY;GAAa,MAAM,SAAS;GAAmB;EAAY,CAAA;CAC/F,CAAA;CAGR,MAAM,mBAAmB,WACvB,OAAO,sBACP,SAAS,aAAa,SAAS,OAAO,sBAAsB,SAC5D,SAAS,aAAa,SAAS,OAAO,sBAAsB,SAAS,cACrE,SAAS,aAAa,SAAS,QAAQ,OAAO,4BAC9C,cAAc,OAAO,gCACrB,YAAY,OAAO,4BACrB;CAEA,MAAM,sBACJ,qBAAC,UAAD;EACE,IAAI;EACJ,MAAK;EACL,WAAW;EACX,OAAO;GACL,QAAQ,aAAa,WAAW,SAAS,KAAA;GACzC,OAAO,YAAY,aAAa,QAAQ,GAAG,YAAY,MAAM,MAAM,KAAA;EACrE;EACA,iBAAe;EACf,KAAK;EACL,eAAqB,cAAc,CAAC,UAAU;EAC9C,eAAa;EACb,oBAAkB,YAAY;YAZhC;GAcG,SAAS,aAAa,SAAS,cAAc,MAAM;GACnD,QACC,oBAAC,QAAD;IAAM,WAAW,WAAW,OAAO,mBAAmB,OAAO,uBAAuB;cACjF,OAAO,SAAS,WACf,oBAAC,kBAAD;KAAU,UAAU;KAAM,MAAM,SAAS;KAAmB;IAAY,CAAA,IAExE,oBAAC,cAAD;KAAM,SAAS;KAAM,MAAM,SAAS;KAAmB;IAAY,CAAA;GAEjE,CAAA;GAEP;GACA,SAAS,aAAa,SAAS,cAAc,OAAO;EAC/C;;CAGV,MAAM,kBAAkB,WAAW,OAAO,qBAAqB,cAAc,OAAO,6BAA6B;CAEjH,MAAM,qBACJ,oBAAC,OAAD;EACE,OAAO;GACL,OAAO,YAAY,aAAa,QAAQ,GAAG,aAAa,MAAM,MAAM,KAAA;GACpE,QAAQ,YAAY,aAAa,SAAS,GAAG,aAAa,OAAO,MAAM,KAAA;EACzE;EACA,WAAW,WAAW,OAAO,+BAA+B,GACzD,OAAO,wCAAwC,SAClD,CAAC;YAED,qBAAC,gBAAD;GACE,IAAI;GACJ,SAAQ;GACR,eAAe,OAAO;GACtB,WAAW;GACX,iBAAe;GACf,KAAK;GACL,eAAqB,cAAc,CAAC,UAAU;GACtC;GACR,oBAAkB,YAAY;aAThC,CAWE,oBAAC,cAAD;IAAM,SAAS,aAAa,YAAY;IAAa,MAAM,SAAS;GAAS,CAAA,GAC5E,KACK;;CACL,CAAA;CAGP,MAAM,sBAAuC;EAC3C,IAAI,CAAC,4BAA4B,CAAC,YAChC,OAAO;EAGT,MAAM,mBAAmB,WACvB,OAAO,sBACP,OAAO,sBAAsB,SAC7B,SAAS,aAAa,SAAS,OAAO,sBAAsB,SAAS,cACrE,SAAS,aAAa,SAAS,QAAQ,OAAO,4BAC9C,cAAc,OAAO,gCACrB,SAAS,aAAa,SAAS,CAAC,gBAAgB,OAAO,0CACvD,cAAc,OAAO,kCACrB,GAAG,OAAO,+BAA+B,SAAS,GAClD,iBACF;EAKA,OACE,oBAAC,OAAD;GAAK,WALqB,WAC1B,SAAS,aAAa,SAAS,CAAC,cAAc,CAAC,gBAAgB,OAAO,wCAItD;aACd,oBAAC,OAAD;IAAK,WAAW;IAAmB;GAAc,CAAA;EAC9C,CAAA;CAET;CAEA,OACE,qBAAC,OAAD;EAAK,WAAW,OAAO;EAAa,KAAK;YAAzC,CACG,SAAS,aAAa,QAAQ,cAAc,IAAI,aAAa,GAC7D,cAAc,CACZ;;AAET;;;AC1LA,IAAA,mBAAe"}
|
|
@@ -1,12 +1,24 @@
|
|
|
1
|
+
import { LanguageLocales } from "./constants.js";
|
|
2
|
+
import { useLanguage } from "./hooks/useLanguage.js";
|
|
3
|
+
import { t as getResources } from "./resourceHelper.js";
|
|
1
4
|
import classNames from "classnames";
|
|
2
|
-
import { jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
6
|
import styles from "./components/Filter/FilterButtonAndChipsWrapper/styles.module.scss";
|
|
4
7
|
//#region src/components/Filter/FilterButtonAndChipsWrapper/FilterButtonAndChipsWrapper.tsx
|
|
5
|
-
var FilterButtonAndChipsWrapper = ({ filterButtonComponent, filterChips, testId }) => {
|
|
8
|
+
var FilterButtonAndChipsWrapper = ({ filterButtonComponent, filterChips, testId, resources }) => {
|
|
9
|
+
const { language } = useLanguage(LanguageLocales.NORWEGIAN);
|
|
10
|
+
const mergedResources = {
|
|
11
|
+
...getResources(language),
|
|
12
|
+
...resources
|
|
13
|
+
};
|
|
6
14
|
return /* @__PURE__ */ jsxs("div", {
|
|
7
15
|
className: classNames(styles["filter-chip-bar"]),
|
|
8
16
|
"data-testid": testId,
|
|
9
|
-
children: [filterButtonComponent,
|
|
17
|
+
children: [filterButtonComponent, /* @__PURE__ */ jsx("ul", {
|
|
18
|
+
"aria-label": mergedResources.activeFiltersListLabel,
|
|
19
|
+
className: styles["filter-chip-bar__list"],
|
|
20
|
+
children: filterChips.map((activefilter, index) => /* @__PURE__ */ jsx("li", { children: activefilter }, index))
|
|
21
|
+
})]
|
|
10
22
|
});
|
|
11
23
|
};
|
|
12
24
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterButtonAndChipsWrapper.js","names":[],"sources":["../src/components/Filter/FilterButtonAndChipsWrapper/FilterButtonAndChipsWrapper.tsx","../src/components/Filter/FilterButtonAndChipsWrapper/index.ts"],"sourcesContent":["import type React from 'react';\n\nimport classNames from 'classnames';\n\nimport styles from './styles.module.scss';\n\nexport interface FilterButtonAndChipsWrapperProps {\n /** FilterButton content area */\n filterButtonComponent: React.ReactNode;\n /** Content area for rendering filter chips */\n filterChips: React.ReactNode[];\n /** test id that is placed on the wrapper */\n testId?: string;\n}\n\nconst FilterButtonAndChipsWrapper: React.FC<FilterButtonAndChipsWrapperProps> = ({
|
|
1
|
+
{"version":3,"file":"FilterButtonAndChipsWrapper.js","names":[],"sources":["../src/components/Filter/FilterButtonAndChipsWrapper/FilterButtonAndChipsWrapper.tsx","../src/components/Filter/FilterButtonAndChipsWrapper/index.ts"],"sourcesContent":["import type React from 'react';\n\nimport classNames from 'classnames';\n\nimport type { HNDesignsystemFilter } from '../../../resources/Resources';\n\nimport { LanguageLocales } from '../../../constants';\nimport { useLanguage } from '../../../hooks/useLanguage';\nimport { getResources } from '../resourceHelper';\n\nimport styles from './styles.module.scss';\n\nexport interface FilterButtonAndChipsWrapperProps {\n /** FilterButton content area */\n filterButtonComponent: React.ReactNode;\n /** Content area for rendering filter chips */\n filterChips: React.ReactNode[];\n /** test id that is placed on the wrapper */\n testId?: string;\n /** Resources for the component */\n resources?: Partial<HNDesignsystemFilter>;\n}\n\nconst FilterButtonAndChipsWrapper: React.FC<FilterButtonAndChipsWrapperProps> = ({\n filterButtonComponent,\n filterChips,\n testId,\n resources,\n}) => {\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources = {\n ...defaultResources,\n ...resources,\n };\n return (\n <div className={classNames(styles['filter-chip-bar'])} data-testid={testId}>\n {filterButtonComponent}\n <ul aria-label={mergedResources.activeFiltersListLabel} className={styles['filter-chip-bar__list']}>\n {filterChips.map((activefilter, index) => (\n <li key={index}>{activefilter}</li>\n ))}\n </ul>\n </div>\n );\n};\n\nexport default FilterButtonAndChipsWrapper;\n","import FilterButtonAndChipsWrapper from './FilterButtonAndChipsWrapper';\nexport * from './FilterButtonAndChipsWrapper';\nexport default FilterButtonAndChipsWrapper;\n"],"mappings":";;;;;;;AAuBA,IAAM,+BAA2E,EAC/E,uBACA,aACA,QACA,gBACI;CACJ,MAAM,EAAE,aAAa,YAA6B,gBAAgB,SAAS;CAG3E,MAAM,kBAAkB;EACtB,GAHuB,aAAa,QAGjC;EACH,GAAG;CACL;CACA,OACE,qBAAC,OAAD;EAAK,WAAW,WAAW,OAAO,kBAAkB;EAAG,eAAa;YAApE,CACG,uBACD,oBAAC,MAAD;GAAI,cAAY,gBAAgB;GAAwB,WAAW,OAAO;aACvE,YAAY,KAAK,cAAc,UAC9B,oBAAC,MAAD,EAAA,UAAiB,aAAiB,GAAzB,KAAyB,CACnC;EACC,CAAA,CACD;;AAET;;;AC5CA,IAAA,sCAAe"}
|
package/lib/FilterLinkList.js
CHANGED
|
@@ -24,9 +24,10 @@ var Link = (props) => {
|
|
|
24
24
|
...restProps,
|
|
25
25
|
children: [/* @__PURE__ */ jsx("div", {
|
|
26
26
|
className: styles["link-list__button__content"],
|
|
27
|
-
children: title ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", { children: title }), chips && chips.length > 0 && /* @__PURE__ */ jsx("
|
|
27
|
+
children: title ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", { children: title }), chips && chips.length > 0 && /* @__PURE__ */ jsx("ul", {
|
|
28
28
|
className: styles["link-list__chip-list"],
|
|
29
|
-
|
|
29
|
+
"aria-label": props.chipsGroupAriaLabel,
|
|
30
|
+
children: chips.map((chip) => /* @__PURE__ */ jsx("li", {
|
|
30
31
|
className: styles["link-list__chip"],
|
|
31
32
|
children: chip
|
|
32
33
|
}, chip))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterLinkList.js","names":[],"sources":["../src/components/Filter/FilterLinkList/FilterLinkList.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport { AnalyticsId, IconSize } from '../../../constants';\nimport { usePseudoClasses } from '../../../hooks/usePseudoClasses';\nimport Icon from '../../Icon';\nimport ChevronRight from '../../Icons/ChevronRight';\n\nimport styles from './FilterLinkList.module.scss';\n\nexport type LinkType = React.FC<LinkProps>;\n\nexport interface CompoundComponent extends React.FC<LinkListProps> {\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 /** Sets the data-testid attribute. */\n testId?: string;\n /** Ref passed to the ul element */\n ref?: React.Ref<HTMLUListElement | null>;\n}\n\ntype Modify<T, R> = Omit<T, keyof R> & R;\n\nexport type LinkProps = Modify<\n React.HTMLAttributes<HTMLAnchorElement | HTMLButtonElement>,\n {\n /** If needed children will be content instead of title and chips. Use only in edge cases */\n children?: React.ReactNode;\n /** Title text on link element */\n title?: string;\n /** Texts rendered inside non-interactive chips on link element */\n chips?: string[];\n /** Custom classname for link element */\n className?: string;\n /** Ref for button */\n linkRef?: React.RefObject<HTMLButtonElement | null>;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Ref passed to the list item element */\n ref?: React.Ref<HTMLLIElement | null>;\n }\n>;\n\nexport const Link: LinkType = (props: LinkProps) => {\n const { children, title, chips, className = '', linkRef, testId, ref, ...restProps } = props;\n const { refObject, isHovered } = usePseudoClasses<HTMLButtonElement | null>(linkRef);\n\n const liClasses = cn(styles['link-list__item']);\n const linkClasses = cn(styles['link-list__button'], className);\n\n return (\n <li className={liClasses} ref={ref} data-testid={testId} data-analyticsid={AnalyticsId.Link}>\n <button className={linkClasses} ref={refObject as React.RefObject<HTMLButtonElement>} type=\"button\" {...restProps}>\n <div className={styles['link-list__button__content']}>\n {title ? (\n <>\n <span>{title}</span>\n {chips && chips.length > 0 && (\n <
|
|
1
|
+
{"version":3,"file":"FilterLinkList.js","names":[],"sources":["../src/components/Filter/FilterLinkList/FilterLinkList.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport { AnalyticsId, IconSize } from '../../../constants';\nimport { usePseudoClasses } from '../../../hooks/usePseudoClasses';\nimport Icon from '../../Icon';\nimport ChevronRight from '../../Icons/ChevronRight';\n\nimport styles from './FilterLinkList.module.scss';\n\nexport type LinkType = React.FC<LinkProps>;\n\nexport interface CompoundComponent extends React.FC<LinkListProps> {\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 /** Sets the data-testid attribute. */\n testId?: string;\n /** Ref passed to the ul element */\n ref?: React.Ref<HTMLUListElement | null>;\n}\n\ntype Modify<T, R> = Omit<T, keyof R> & R;\n\nexport type LinkProps = Modify<\n React.HTMLAttributes<HTMLAnchorElement | HTMLButtonElement>,\n {\n /** If needed children will be content instead of title and chips. Use only in edge cases */\n children?: React.ReactNode;\n /** Title text on link element */\n title?: string;\n /** Texts rendered inside non-interactive chips on link element */\n chips?: string[];\n /** Aria label for the list of chips */\n chipsGroupAriaLabel?: string;\n /** Custom classname for link element */\n className?: string;\n /** Ref for button */\n linkRef?: React.RefObject<HTMLButtonElement | null>;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Ref passed to the list item element */\n ref?: React.Ref<HTMLLIElement | null>;\n }\n>;\n\nexport const Link: LinkType = (props: LinkProps) => {\n const { children, title, chips, className = '', linkRef, testId, ref, ...restProps } = props;\n const { refObject, isHovered } = usePseudoClasses<HTMLButtonElement | null>(linkRef);\n\n const liClasses = cn(styles['link-list__item']);\n const linkClasses = cn(styles['link-list__button'], className);\n\n return (\n <li className={liClasses} ref={ref} data-testid={testId} data-analyticsid={AnalyticsId.Link}>\n <button className={linkClasses} ref={refObject as React.RefObject<HTMLButtonElement>} type=\"button\" {...restProps}>\n <div className={styles['link-list__button__content']}>\n {title ? (\n <>\n <span>{title}</span>\n {chips && chips.length > 0 && (\n <ul className={styles['link-list__chip-list']} aria-label={props.chipsGroupAriaLabel}>\n {chips.map(chip => (\n <li className={styles['link-list__chip']} key={chip}>\n {chip}\n </li>\n ))}\n </ul>\n )}\n </>\n ) : (\n <>{children}</>\n )}\n </div>\n <Icon svgIcon={ChevronRight} isHovered={isHovered} size={IconSize.XSmall} color={'var(--color-action-graphics-onlight)'} />\n </button>\n </li>\n );\n};\n\nconst LinkListComponent: React.FC<LinkListProps> = (props: LinkListProps) => {\n const { children, className = '', testId, ref } = props;\n\n const listClassNames = cn(styles['link-list'], className);\n\n return (\n <ul ref={ref} className={listClassNames} data-testid={testId} data-analyticsid={AnalyticsId.LinkList}>\n {React.Children.map(children, (child: React.ReactNode) => {\n if (React.isValidElement<LinkProps>(child) && child.type === Link) {\n return React.cloneElement(child);\n }\n })}\n </ul>\n );\n};\n\nexport const FilterLinkList = LinkListComponent as CompoundComponent;\n\nFilterLinkList.displayName = 'FilterLinkList';\nFilterLinkList.Link = Link;\nLink.displayName = 'FilterLinkList.Link';\n\nexport default FilterLinkList;\n"],"mappings":";;;;;;;;;AAoDA,IAAa,QAAkB,UAAqB;CAClD,MAAM,EAAE,UAAU,OAAO,OAAO,YAAY,IAAI,SAAS,QAAQ,KAAK,GAAG,cAAc;CACvF,MAAM,EAAE,WAAW,cAAc,iBAA2C,OAAO;CAEnF,MAAM,YAAY,WAAG,OAAO,kBAAkB;CAC9C,MAAM,cAAc,WAAG,OAAO,sBAAsB,SAAS;CAE7D,OACE,oBAAC,MAAD;EAAI,WAAW;EAAgB;EAAK,eAAa;EAAQ,oBAAkB,YAAY;YACrF,qBAAC,UAAD;GAAQ,WAAW;GAAa,KAAK;GAAiD,MAAK;GAAS,GAAI;aAAxG,CACE,oBAAC,OAAD;IAAK,WAAW,OAAO;cACpB,QACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD,EAAA,UAAO,MAAY,CAAA,GAClB,SAAS,MAAM,SAAS,KACvB,oBAAC,MAAD;KAAI,WAAW,OAAO;KAAyB,cAAY,MAAM;eAC9D,MAAM,KAAI,SACT,oBAAC,MAAD;MAAI,WAAW,OAAO;gBACnB;KACC,GAF2C,IAE3C,CACL;IACC,CAAA,CAEN,EAAA,CAAA,IAEF,oBAAA,UAAA,EAAG,SAAW,CAAA;GAEb,CAAA,GACL,oBAAC,cAAD;IAAM,SAAS;IAAyB;IAAW,MAAM,SAAS;IAAQ,OAAO;GAAyC,CAAA,CACpH;;CACN,CAAA;AAER;AAEA,IAAM,qBAA8C,UAAyB;CAC3E,MAAM,EAAE,UAAU,YAAY,IAAI,QAAQ,QAAQ;CAIlD,OACE,oBAAC,MAAD;EAAS;EAAK,WAHO,WAAG,OAAO,cAAc,SAGpB;EAAgB,eAAa;EAAQ,oBAAkB,YAAY;YACzF,MAAM,SAAS,IAAI,WAAW,UAA2B;GACxD,IAAI,MAAM,eAA0B,KAAK,KAAK,MAAM,SAAS,MAC3D,OAAO,MAAM,aAAa,KAAK;EAEnC,CAAC;CACC,CAAA;AAER;AAEA,IAAa,iBAAiB;AAE9B,eAAe,cAAc;AAC7B,eAAe,OAAO;AACtB,KAAK,cAAc"}
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import { LanguageLocales } from "./constants.js";
|
|
2
|
+
import { useLanguage } from "./hooks/useLanguage.js";
|
|
1
3
|
import { r as useDrawerNavigation } from "./DrawerNavigation.js";
|
|
4
|
+
import { t as getResources } from "./resourceHelper.js";
|
|
2
5
|
import { t as FilterLinkList } from "./FilterLinkList.js";
|
|
3
6
|
import { jsx } from "react/jsx-runtime";
|
|
4
7
|
//#region src/components/Filter/FilterOverviewLinkList/FilterOverviewLinkList.tsx
|
|
5
|
-
function FilterOverviewLinkList({ filter, getLabel, links }) {
|
|
8
|
+
function FilterOverviewLinkList({ filter, getLabel, links, resources }) {
|
|
6
9
|
const { goToView } = useDrawerNavigation();
|
|
10
|
+
const { language } = useLanguage(LanguageLocales.NORWEGIAN);
|
|
11
|
+
const mergedResources = {
|
|
12
|
+
...getResources(language),
|
|
13
|
+
...resources
|
|
14
|
+
};
|
|
7
15
|
return /* @__PURE__ */ jsx(FilterLinkList, { children: links.map(({ filterKey, title, viewId }) => {
|
|
8
16
|
const raw = filter.filters[filterKey];
|
|
9
17
|
let chips;
|
|
@@ -13,6 +21,7 @@ function FilterOverviewLinkList({ filter, getLabel, links }) {
|
|
|
13
21
|
return /* @__PURE__ */ jsx(FilterLinkList.Link, {
|
|
14
22
|
title,
|
|
15
23
|
chips,
|
|
24
|
+
chipsGroupAriaLabel: mergedResources.activeFiltersListLabel,
|
|
16
25
|
onClick: () => goToView(viewId ?? filterKey)
|
|
17
26
|
}, filterKey);
|
|
18
27
|
}) });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterOverviewLinkList.js","names":[],"sources":["../src/components/Filter/FilterOverviewLinkList/FilterOverviewLinkList.tsx","../src/components/Filter/FilterOverviewLinkList/index.ts"],"sourcesContent":["import type { FilterValues, UseFilterReturn } from '../useFilter';\n\nimport { useDrawerNavigation } from '../DrawerNavigation';\nimport FilterLinkList from '../FilterLinkList/FilterLinkList';\n\nexport interface FilterOverviewLink {\n /** The filter key to read values from */\n filterKey: string;\n /** Display title for the link */\n title: string;\n /** View ID to navigate to when clicked. Defaults to filterKey */\n viewId?: string;\n}\n\nexport interface FilterOverviewLinkListProps<T extends FilterValues> {\n /** The filter instance from useFilter */\n filter: UseFilterReturn<T>;\n /** Look up the display label for a filter key + value */\n getLabel: (key: keyof T, value: unknown) => string;\n /** Configuration for which filter keys to show as links */\n links: FilterOverviewLink[];\n}\n\nfunction FilterOverviewLinkList<T extends FilterValues>({
|
|
1
|
+
{"version":3,"file":"FilterOverviewLinkList.js","names":[],"sources":["../src/components/Filter/FilterOverviewLinkList/FilterOverviewLinkList.tsx","../src/components/Filter/FilterOverviewLinkList/index.ts"],"sourcesContent":["import type { HNDesignsystemFilter } from '../../../resources/Resources';\nimport type { FilterValues, UseFilterReturn } from '../useFilter';\n\nimport { LanguageLocales } from '../../../constants';\nimport { useLanguage } from '../../../hooks/useLanguage';\nimport { useDrawerNavigation } from '../DrawerNavigation';\nimport FilterLinkList from '../FilterLinkList/FilterLinkList';\nimport { getResources } from '../resourceHelper';\n\nexport interface FilterOverviewLink {\n /** The filter key to read values from */\n filterKey: string;\n /** Display title for the link */\n title: string;\n /** View ID to navigate to when clicked. Defaults to filterKey */\n viewId?: string;\n}\n\nexport interface FilterOverviewLinkListProps<T extends FilterValues> {\n /** The filter instance from useFilter */\n filter: UseFilterReturn<T>;\n /** Look up the display label for a filter key + value */\n getLabel: (key: keyof T, value: unknown) => string;\n /** Configuration for which filter keys to show as links */\n links: FilterOverviewLink[];\n /** Resources for the component */\n resources?: Partial<HNDesignsystemFilter>;\n}\n\nfunction FilterOverviewLinkList<T extends FilterValues>({\n filter,\n getLabel,\n links,\n resources,\n}: FilterOverviewLinkListProps<T>): React.ReactNode {\n const { goToView } = useDrawerNavigation();\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n const mergedResources = {\n ...defaultResources,\n ...resources,\n };\n\n return (\n <FilterLinkList>\n {links.map(({ filterKey, title, viewId }) => {\n const raw = filter.filters[filterKey as keyof T];\n\n let chips: string[];\n if (Array.isArray(raw)) {\n chips = raw.map(v => getLabel(filterKey as keyof T, v));\n } else if (raw !== undefined && raw !== null) {\n chips = [getLabel(filterKey as keyof T, raw)];\n } else {\n chips = [];\n }\n\n return (\n <FilterLinkList.Link\n key={filterKey}\n title={title}\n chips={chips}\n chipsGroupAriaLabel={mergedResources.activeFiltersListLabel}\n onClick={() => goToView(viewId ?? filterKey)}\n />\n );\n })}\n </FilterLinkList>\n );\n}\n\nexport default FilterOverviewLinkList;\n","import FilterOverviewLinkList from './FilterOverviewLinkList';\nexport * from './FilterOverviewLinkList';\nexport default FilterOverviewLinkList;\n"],"mappings":";;;;;;;AA6BA,SAAS,uBAA+C,EACtD,QACA,UACA,OACA,aACkD;CAClD,MAAM,EAAE,aAAa,oBAAoB;CACzC,MAAM,EAAE,aAAa,YAA6B,gBAAgB,SAAS;CAE3E,MAAM,kBAAkB;EACtB,GAFuB,aAAa,QAEjC;EACH,GAAG;CACL;CAEA,OACE,oBAAC,gBAAD,EAAA,UACG,MAAM,KAAK,EAAE,WAAW,OAAO,aAAa;EAC3C,MAAM,MAAM,OAAO,QAAQ;EAE3B,IAAI;EACJ,IAAI,MAAM,QAAQ,GAAG,GACnB,QAAQ,IAAI,KAAI,MAAK,SAAS,WAAsB,CAAC,CAAC;OACjD,IAAI,QAAQ,KAAA,KAAa,QAAQ,MACtC,QAAQ,CAAC,SAAS,WAAsB,GAAG,CAAC;OAE5C,QAAQ,CAAC;EAGX,OACE,oBAAC,eAAe,MAAhB;GAES;GACA;GACP,qBAAqB,gBAAgB;GACrC,eAAe,SAAS,UAAU,SAAS;EAC5C,GALM,SAKN;CAEL,CAAC,EACa,CAAA;AAEpB;;;ACnEA,IAAA,iCAAe"}
|
package/lib/InfoTeaser.js
CHANGED
|
@@ -53,7 +53,7 @@ var InfoTeaser = (props) => {
|
|
|
53
53
|
size: IconSize.Small,
|
|
54
54
|
className: styles.infoteaser__icon
|
|
55
55
|
})),
|
|
56
|
-
/* @__PURE__ */ jsx(Title_default, {
|
|
56
|
+
title && typeof title !== "undefined" && /* @__PURE__ */ jsx(Title_default, {
|
|
57
57
|
testId: "titleId",
|
|
58
58
|
htmlMarkup: titleHtmlMarkup,
|
|
59
59
|
appearance: "title4",
|
package/lib/InfoTeaser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InfoTeaser.js","names":[],"sources":["../src/resources/HN.Designsystem.InfoTeaser.en-GB.json","../src/resources/HN.Designsystem.InfoTeaser.nb-NO.json","../src/components/InfoTeaser/resourceHelper.ts","../src/components/InfoTeaser/InfoTeaser.tsx","../src/components/InfoTeaser/index.ts"],"sourcesContent":["{\n \"expandButtonOpen\": \"Show less\",\n \"expandButtonClose\": \"Show more\"\n}\n","{\n \"expandButtonOpen\": \"Vis mindre\",\n \"expandButtonClose\": \"Vis mer\"\n}\n","import type { HNDesignsystemInfoTeaser } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.InfoTeaser.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.InfoTeaser.nb-NO.json';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemInfoTeaser => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import { useId, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { HNDesignsystemInfoTeaser } from '../../resources/Resources';\nimport type { SvgIcon } from '../Icon';\nimport type { IconName } from '../Icons/IconNames';\nimport type { TitleTags } from '../Title';\n\nimport { AnalyticsId, LanguageLocales } from '../../constants';\nimport { useLanguage } from '../../hooks/useLanguage';\nimport Icon, { IconSize } from '../Icon';\nimport LazyIcon from '../LazyIcon';\nimport Title from '../Title';\nimport { getResources } from './resourceHelper';\n\nimport styles from './styles.module.scss';\n\nexport type InfoTeaserTags = 'div' | 'section' | 'aside' | 'article';\n\nexport interface InfoTeaserProps {\n /** For overriding styling on the button */\n buttonClassName?: string;\n /** What's in the box? */\n children: React.ReactNode;\n /** Override the default max height for collapsed teaser. Default is 12.25rem */\n collapsedMaxHeight?: string;\n /** For overriding styling on infoteaser box */\n className?: string;\n /** Changes the underlying element of the wrapper */\n htmlMarkup?: InfoTeaserTags;\n /** Resources for component */\n resources?: Partial<HNDesignsystemInfoTeaser>;\n /** Adds an icon */\n svgIcon?: SvgIcon | IconName;\n /** Sets the data-testid attribute */\n testId?: string;\n /** Title on top of the component */\n title
|
|
1
|
+
{"version":3,"file":"InfoTeaser.js","names":[],"sources":["../src/resources/HN.Designsystem.InfoTeaser.en-GB.json","../src/resources/HN.Designsystem.InfoTeaser.nb-NO.json","../src/components/InfoTeaser/resourceHelper.ts","../src/components/InfoTeaser/InfoTeaser.tsx","../src/components/InfoTeaser/index.ts"],"sourcesContent":["{\n \"expandButtonOpen\": \"Show less\",\n \"expandButtonClose\": \"Show more\"\n}\n","{\n \"expandButtonOpen\": \"Vis mindre\",\n \"expandButtonClose\": \"Vis mer\"\n}\n","import type { HNDesignsystemInfoTeaser } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.InfoTeaser.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.InfoTeaser.nb-NO.json';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemInfoTeaser => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import { useId, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { HNDesignsystemInfoTeaser } from '../../resources/Resources';\nimport type { SvgIcon } from '../Icon';\nimport type { IconName } from '../Icons/IconNames';\nimport type { TitleTags } from '../Title';\n\nimport { AnalyticsId, LanguageLocales } from '../../constants';\nimport { useLanguage } from '../../hooks/useLanguage';\nimport Icon, { IconSize } from '../Icon';\nimport LazyIcon from '../LazyIcon';\nimport Title from '../Title';\nimport { getResources } from './resourceHelper';\n\nimport styles from './styles.module.scss';\n\nexport type InfoTeaserTags = 'div' | 'section' | 'aside' | 'article';\n\nexport interface InfoTeaserProps {\n /** For overriding styling on the button */\n buttonClassName?: string;\n /** What's in the box? */\n children: React.ReactNode;\n /** Override the default max height for collapsed teaser. Default is 12.25rem */\n collapsedMaxHeight?: string;\n /** For overriding styling on infoteaser box */\n className?: string;\n /** Changes the underlying element of the wrapper */\n htmlMarkup?: InfoTeaserTags;\n /** Resources for component */\n resources?: Partial<HNDesignsystemInfoTeaser>;\n /** Adds an icon */\n svgIcon?: SvgIcon | IconName;\n /** Sets the data-testid attribute */\n testId?: string;\n /** Title on top of the component */\n title?: string;\n /** Markup props for title */\n titleHtmlMarkup?: TitleTags;\n}\n\nconst InfoTeaser: React.FC<InfoTeaserProps> = props => {\n const {\n buttonClassName,\n children,\n className,\n htmlMarkup = 'div',\n resources,\n svgIcon,\n testId,\n title,\n titleHtmlMarkup = 'h2',\n collapsedMaxHeight,\n } = props;\n const [expanded, setExpanded] = useState(false);\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n const infoteaserTextId = useId();\n\n const mergedResources: HNDesignsystemInfoTeaser = {\n ...defaultResources,\n ...resources,\n };\n\n const WrapperTag = htmlMarkup;\n\n return (\n <WrapperTag className={styles.wrapper} data-testid={testId} data-analyticsid={AnalyticsId.InfoTeaser}>\n <div\n className={classNames(styles.infoteaser, className, {\n [styles['infoteaser--collapsed']]: !expanded,\n })}\n style={{ maxHeight: !expanded ? (collapsedMaxHeight ? collapsedMaxHeight : '12.25rem') : undefined }}\n >\n {svgIcon &&\n (typeof svgIcon === 'string' ? (\n <LazyIcon iconName={svgIcon} size={IconSize.Small} className={styles.infoteaser__icon} />\n ) : (\n <Icon svgIcon={svgIcon} size={IconSize.Small} className={styles.infoteaser__icon} />\n ))}\n {title && typeof title !== 'undefined' && (\n <Title testId=\"titleId\" htmlMarkup={titleHtmlMarkup} appearance=\"title4\" className={styles.infoteaser__title}>\n {title}\n </Title>\n )}\n <div className={styles.infoteaser__text} aria-hidden={expanded ? false : true} id={infoteaserTextId}>\n {children}\n </div>\n </div>\n <button\n type=\"button\"\n className={classNames(styles.infoteaser__button, buttonClassName)}\n onClick={() => {\n setExpanded(!expanded);\n }}\n aria-expanded={expanded}\n aria-controls={infoteaserTextId}\n >\n {expanded ? mergedResources.expandButtonOpen : mergedResources.expandButtonClose}\n </button>\n </WrapperTag>\n );\n};\n\nexport default InfoTeaser;\n","import InfoTeaser from './InfoTeaser';\nexport * from './InfoTeaser';\nexport default InfoTeaser;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AEMA,IAAa,gBAAgB,aAAwD;CACnF,QAAQ,UAAR;EACE,KAAK,gBAAgB,SACnB,OAAO;EACT,KAAK,gBAAgB;EACrB,SACE,OAAO;CACX;AACF;;;AC6BA,IAAM,cAAwC,UAAS;CACrD,MAAM,EACJ,iBACA,UACA,WACA,aAAa,OACb,WACA,SACA,QACA,OACA,kBAAkB,MAClB,uBACE;CACJ,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAC9C,MAAM,EAAE,aAAa,YAA6B,gBAAgB,SAAS;CAC3E,MAAM,mBAAmB,aAAa,QAAQ;CAC9C,MAAM,mBAAmB,MAAM;CAE/B,MAAM,kBAA4C;EAChD,GAAG;EACH,GAAG;CACL;CAIA,OACE,qBAAC,YAAD;EAAY,WAAW,OAAO;EAAS,eAAa;EAAQ,oBAAkB,YAAY;YAA1F,CACE,qBAAC,OAAD;GACE,WAAW,WAAW,OAAO,YAAY,WAAW,GACjD,OAAO,2BAA2B,CAAC,SACtC,CAAC;GACD,OAAO,EAAE,WAAW,CAAC,WAAY,qBAAqB,qBAAqB,aAAc,KAAA,EAAU;aAJrG;IAMG,YACE,OAAO,YAAY,WAClB,oBAAC,kBAAD;KAAU,UAAU;KAAS,MAAM,SAAS;KAAO,WAAW,OAAO;IAAmB,CAAA,IAExF,oBAAC,cAAD;KAAe;KAAS,MAAM,SAAS;KAAO,WAAW,OAAO;IAAmB,CAAA;IAEtF,SAAS,OAAO,UAAU,eACzB,oBAAC,eAAD;KAAO,QAAO;KAAU,YAAY;KAAiB,YAAW;KAAS,WAAW,OAAO;eACxF;IACI,CAAA;IAET,oBAAC,OAAD;KAAK,WAAW,OAAO;KAAkB,eAAa,WAAW,QAAQ;KAAM,IAAI;KAChF;IACE,CAAA;GACF;MACL,oBAAC,UAAD;GACE,MAAK;GACL,WAAW,WAAW,OAAO,oBAAoB,eAAe;GAChE,eAAe;IACb,YAAY,CAAC,QAAQ;GACvB;GACA,iBAAe;GACf,iBAAe;aAEd,WAAW,gBAAgB,mBAAmB,gBAAgB;EACzD,CAAA,CACE;;AAEhB;;;ACtGA,IAAA,qBAAe"}
|
|
@@ -21,6 +21,8 @@ export interface ExpanderProps {
|
|
|
21
21
|
expanded?: boolean;
|
|
22
22
|
/** Removes border to the left of the content. Requires size=ExpanderSize.small. */
|
|
23
23
|
noNestedLine?: boolean;
|
|
24
|
+
/** Emphasizes the content section. Intended for size=ExpanderSize.small. */
|
|
25
|
+
emphasized?: boolean;
|
|
24
26
|
/** Stick expander trigger to top of screen while scrolling down */
|
|
25
27
|
sticky?: boolean;
|
|
26
28
|
/** Called when expander is open/closed. */
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* stylelint-disable no-descending-specificity */
|
|
2
2
|
@use 'sass:map';
|
|
3
|
-
@use '../../scss/spacers' as spacers;
|
|
4
3
|
@use '../../scss/palette' as palette;
|
|
5
4
|
@use '../../scss/font-settings' as font-settings;
|
|
6
5
|
@use '../Button/styles.module' as button;
|
|
7
6
|
@use '../../scss/breakpoints' as breakpoints;
|
|
8
7
|
@import '../../scss/supernova/styles/colors.css';
|
|
8
|
+
@import '../../scss/supernova/styles/spacers.css';
|
|
9
9
|
|
|
10
10
|
.expander {
|
|
11
11
|
position: initial;
|
|
@@ -24,18 +24,18 @@
|
|
|
24
24
|
align-items: center;
|
|
25
25
|
|
|
26
26
|
&--left {
|
|
27
|
-
margin-right:
|
|
27
|
+
margin-right: var(--core-space-2xs);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
&--right {
|
|
31
31
|
margin-left: auto;
|
|
32
|
-
padding-left:
|
|
32
|
+
padding-left: var(--core-space-2xs);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
&__button {
|
|
37
37
|
position: relative;
|
|
38
|
-
padding-right:
|
|
38
|
+
padding-right: var(--core-space-s);
|
|
39
39
|
text-align: left;
|
|
40
40
|
|
|
41
41
|
&--expanded {
|
|
@@ -67,19 +67,19 @@
|
|
|
67
67
|
|
|
68
68
|
&--large {
|
|
69
69
|
width: 100%;
|
|
70
|
-
padding:
|
|
70
|
+
padding: var(--core-space-xs) var(--core-space-2xs) var(--core-space-xs) var(--core-space-s);
|
|
71
71
|
cursor: pointer;
|
|
72
72
|
|
|
73
73
|
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
74
|
-
padding:
|
|
74
|
+
padding: var(--core-space-xs) var(--core-space-s) var(--core-space-xs) var(--core-space-l);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
&--icon {
|
|
79
|
-
padding-left:
|
|
79
|
+
padding-left: var(--core-space-2xs);
|
|
80
80
|
|
|
81
81
|
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
82
|
-
padding-left:
|
|
82
|
+
padding-left: var(--core-space-s);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
0 0 0 1.5px palette.$neutral600,
|
|
99
99
|
inset 0 0 0 1.5px palette.$neutral600;
|
|
100
100
|
}
|
|
101
|
+
|
|
101
102
|
&#{$trigger}--expanded {
|
|
102
103
|
background-color: map.get(palette.$palette-map, #{$color}100);
|
|
103
104
|
|
|
@@ -121,6 +122,7 @@
|
|
|
121
122
|
0 0 0 1.5px palette.$neutral600,
|
|
122
123
|
inset 0 0 0 1.5px palette.$neutral600;
|
|
123
124
|
}
|
|
125
|
+
|
|
124
126
|
&#{$trigger}--expanded {
|
|
125
127
|
box-shadow: inset 0 0 0 6px palette.$neutral100;
|
|
126
128
|
|
|
@@ -135,6 +137,8 @@
|
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
&__button-container {
|
|
140
|
+
display: flex;
|
|
141
|
+
|
|
138
142
|
&--sticky {
|
|
139
143
|
background-color: palette.$white;
|
|
140
144
|
}
|
|
@@ -163,12 +167,19 @@
|
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
&--small {
|
|
166
|
-
margin-top:
|
|
170
|
+
margin-top: var(--core-space-s);
|
|
167
171
|
}
|
|
172
|
+
|
|
168
173
|
&--small#{&}--sticky {
|
|
169
174
|
margin-top: 1.25rem;
|
|
170
175
|
}
|
|
171
176
|
|
|
177
|
+
&--emphasized {
|
|
178
|
+
padding: var(--core-space-m) var(--core-space-s);
|
|
179
|
+
margin-top: var(--core-space-3xs);
|
|
180
|
+
background: var(--color-base-background-neutral, #f5f3f3);
|
|
181
|
+
}
|
|
182
|
+
|
|
172
183
|
&--nested-line {
|
|
173
184
|
&--outer {
|
|
174
185
|
padding-left: 0;
|
|
@@ -179,7 +190,7 @@
|
|
|
179
190
|
}
|
|
180
191
|
|
|
181
192
|
&--inner {
|
|
182
|
-
padding-left:
|
|
193
|
+
padding-left: var(--core-space-s);
|
|
183
194
|
border-left: solid 3px palette.$neutral200;
|
|
184
195
|
|
|
185
196
|
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
@@ -191,11 +202,12 @@
|
|
|
191
202
|
}
|
|
192
203
|
|
|
193
204
|
&--large {
|
|
194
|
-
padding:
|
|
205
|
+
padding: var(--core-space-s) var(--core-space-m) var(--core-space-l) var(--core-space-s);
|
|
195
206
|
|
|
196
207
|
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
197
|
-
padding:
|
|
208
|
+
padding: var(--core-space-m) var(--core-space-l) var(--core-space-xl);
|
|
198
209
|
}
|
|
210
|
+
|
|
199
211
|
&#{$content}--icon {
|
|
200
212
|
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
201
213
|
padding-left: 70px;
|
|
@@ -32,11 +32,13 @@ export type Styles = {
|
|
|
32
32
|
expander__button: string;
|
|
33
33
|
expander__button__text: string;
|
|
34
34
|
'expander__button--expanded': string;
|
|
35
|
+
'expander__button-container': string;
|
|
35
36
|
'expander__button-container--sticky': string;
|
|
36
37
|
expander__content: string;
|
|
37
38
|
'expander__content--banana': string;
|
|
38
39
|
'expander__content--blueberry': string;
|
|
39
40
|
'expander__content--cherry': string;
|
|
41
|
+
'expander__content--emphasized': string;
|
|
40
42
|
'expander__content--expanded': string;
|
|
41
43
|
'expander__content--icon': string;
|
|
42
44
|
'expander__content--kiwi': string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
import { HNDesignsystemFilter } from '../../../resources/Resources';
|
|
2
3
|
export interface FilterButtonAndChipsWrapperProps {
|
|
3
4
|
/** FilterButton content area */
|
|
4
5
|
filterButtonComponent: React.ReactNode;
|
|
@@ -6,6 +7,8 @@ export interface FilterButtonAndChipsWrapperProps {
|
|
|
6
7
|
filterChips: React.ReactNode[];
|
|
7
8
|
/** test id that is placed on the wrapper */
|
|
8
9
|
testId?: string;
|
|
10
|
+
/** Resources for the component */
|
|
11
|
+
resources?: Partial<HNDesignsystemFilter>;
|
|
9
12
|
}
|
|
10
13
|
declare const FilterButtonAndChipsWrapper: React.FC<FilterButtonAndChipsWrapperProps>;
|
|
11
14
|
export default FilterButtonAndChipsWrapper;
|
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
@use '../../../scss/screen-reader' as *;
|
|
1
2
|
@import '../../../scss/supernova/styles/spacers.css';
|
|
2
3
|
|
|
3
4
|
.filter-chip-bar {
|
|
4
5
|
display: flex;
|
|
5
|
-
flex-flow: row wrap;
|
|
6
6
|
column-gap: var(--core-space-xs);
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
&__list {
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
flex-flow: row wrap;
|
|
11
|
+
align-items: flex-start;
|
|
12
|
+
column-gap: var(--core-space-xs);
|
|
13
|
+
|
|
14
|
+
/* Override list styling */
|
|
15
|
+
list-style: none;
|
|
16
|
+
margin-block: 0;
|
|
17
|
+
padding-inline-start: 0;
|
|
18
|
+
|
|
19
|
+
li {
|
|
20
|
+
list-style: none;
|
|
21
|
+
display: inline;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
8
24
|
}
|
|
@@ -21,6 +21,8 @@ export type LinkProps = Modify<React.HTMLAttributes<HTMLAnchorElement | HTMLButt
|
|
|
21
21
|
title?: string;
|
|
22
22
|
/** Texts rendered inside non-interactive chips on link element */
|
|
23
23
|
chips?: string[];
|
|
24
|
+
/** Aria label for the list of chips */
|
|
25
|
+
chipsGroupAriaLabel?: string;
|
|
24
26
|
/** Custom classname for link element */
|
|
25
27
|
className?: string;
|
|
26
28
|
/** Ref for button */
|
|
@@ -59,6 +59,16 @@
|
|
|
59
59
|
display: flex;
|
|
60
60
|
flex-flow: row wrap;
|
|
61
61
|
column-gap: 0.5rem;
|
|
62
|
+
|
|
63
|
+
/* Override list styling */
|
|
64
|
+
list-style: none;
|
|
65
|
+
margin-block: 0;
|
|
66
|
+
padding-inline-start: 0;
|
|
67
|
+
|
|
68
|
+
li {
|
|
69
|
+
list-style: none;
|
|
70
|
+
display: inline;
|
|
71
|
+
}
|
|
62
72
|
}
|
|
63
73
|
|
|
64
74
|
&__chip {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HNDesignsystemFilter } from '../../../resources/Resources';
|
|
1
2
|
import { FilterValues, UseFilterReturn } from '../useFilter';
|
|
2
3
|
export interface FilterOverviewLink {
|
|
3
4
|
/** The filter key to read values from */
|
|
@@ -14,6 +15,8 @@ export interface FilterOverviewLinkListProps<T extends FilterValues> {
|
|
|
14
15
|
getLabel: (key: keyof T, value: unknown) => string;
|
|
15
16
|
/** Configuration for which filter keys to show as links */
|
|
16
17
|
links: FilterOverviewLink[];
|
|
18
|
+
/** Resources for the component */
|
|
19
|
+
resources?: Partial<HNDesignsystemFilter>;
|
|
17
20
|
}
|
|
18
|
-
declare function FilterOverviewLinkList<T extends FilterValues>({ filter, getLabel, links }: FilterOverviewLinkListProps<T>): React.ReactNode;
|
|
21
|
+
declare function FilterOverviewLinkList<T extends FilterValues>({ filter, getLabel, links, resources, }: FilterOverviewLinkListProps<T>): React.ReactNode;
|
|
19
22
|
export default FilterOverviewLinkList;
|
|
@@ -9,22 +9,13 @@
|
|
|
9
9
|
|
|
10
10
|
.infoteaser {
|
|
11
11
|
display: grid;
|
|
12
|
-
grid-template:
|
|
13
|
-
'icon title' auto
|
|
14
|
-
'. title' auto
|
|
15
|
-
'text text' min-content / auto 1fr;
|
|
12
|
+
grid-template-columns: [icon] auto [content] 1fr;
|
|
16
13
|
width: 100%;
|
|
17
14
|
overflow: hidden;
|
|
18
15
|
background-color: var(--color-base-background-blueberry);
|
|
19
16
|
border: 1px solid var(--color-base-border-blueberry);
|
|
20
17
|
padding: var(--core-space-m) var(--core-space-s) var(--core-space-l) var(--core-space-s);
|
|
21
|
-
|
|
22
|
-
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
23
|
-
grid-template:
|
|
24
|
-
'icon title' auto
|
|
25
|
-
'. title' auto
|
|
26
|
-
'. text' min-content / auto 1fr;
|
|
27
|
-
}
|
|
18
|
+
row-gap: var(--core-space-2xs);
|
|
28
19
|
|
|
29
20
|
&--collapsed {
|
|
30
21
|
&::after {
|
|
@@ -41,20 +32,26 @@
|
|
|
41
32
|
}
|
|
42
33
|
|
|
43
34
|
&__title {
|
|
44
|
-
grid-
|
|
35
|
+
grid-column: content;
|
|
36
|
+
grid-row: 1;
|
|
45
37
|
align-self: center;
|
|
46
38
|
}
|
|
47
39
|
|
|
48
40
|
&__icon {
|
|
49
|
-
grid-
|
|
41
|
+
grid-column: icon;
|
|
42
|
+
grid-row: 1;
|
|
43
|
+
align-self: center;
|
|
50
44
|
margin-right: var(--core-space-xs);
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
&__text {
|
|
54
|
-
grid-
|
|
48
|
+
grid-column: 1 / -1;
|
|
55
49
|
overflow: hidden;
|
|
56
50
|
height: inherit;
|
|
57
|
-
|
|
51
|
+
|
|
52
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
53
|
+
grid-column: content;
|
|
54
|
+
}
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
&__button {
|
|
@@ -76,7 +73,7 @@
|
|
|
76
73
|
font-size: 1rem;
|
|
77
74
|
font-style: normal;
|
|
78
75
|
font-weight: 600;
|
|
79
|
-
line-height: 120%;
|
|
76
|
+
line-height: 120%; // 1.2rem
|
|
80
77
|
|
|
81
78
|
&:hover {
|
|
82
79
|
background-color: var(--color-action-graphics-onlight-hover);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type ImageRatios = 'square' | 'landscape';
|
|
2
|
+
export interface VisualContentgroupWithImageProps {
|
|
3
|
+
/** Set the ratio of the image. */
|
|
4
|
+
imageRatio?: ImageRatios;
|
|
5
|
+
/** Content rendered inside the visualcontent area. */
|
|
6
|
+
visualContent: React.ReactNode;
|
|
7
|
+
/** Content rendered inside the component */
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
/** Sets the data-testid attribute. */
|
|
10
|
+
testId?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const VisualContentgroupWithImage: React.FC<VisualContentgroupWithImageProps>;
|
|
13
|
+
export default VisualContentgroupWithImage;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import classNames from "classnames";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import styles from "./styles.module.scss";
|
|
4
|
+
//#region src/components/VisualContentgroupWithImage/VisualContentgroupWithImage.tsx
|
|
5
|
+
var VisualContentgroupWithImage = (props) => {
|
|
6
|
+
const { imageRatio = "square", visualContent, children, testId } = props;
|
|
7
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8
|
+
"data-testid": testId,
|
|
9
|
+
className: styles["visual-contentgroup-with-image"],
|
|
10
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
11
|
+
className: classNames(styles["visual-contentgroup-with-image__frame"], { [styles[`visual-contentgroup-with-image__frame--${imageRatio}`]]: imageRatio }),
|
|
12
|
+
children: visualContent
|
|
13
|
+
}), children]
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/components/VisualContentgroupWithImage/index.ts
|
|
18
|
+
var VisualContentgroupWithImage_default = VisualContentgroupWithImage;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { VisualContentgroupWithImage_default as default };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/VisualContentgroupWithImage/VisualContentgroupWithImage.tsx","../../../src/components/VisualContentgroupWithImage/index.ts"],"sourcesContent":["import classNames from 'classnames';\n\nimport styles from './styles.module.scss';\n\nexport type ImageRatios = 'square' | 'landscape';\n\nexport interface VisualContentgroupWithImageProps {\n /** Set the ratio of the image. */\n imageRatio?: ImageRatios;\n /** Content rendered inside the visualcontent area. */\n visualContent: React.ReactNode;\n /** Content rendered inside the component */\n children: React.ReactNode;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nconst VisualContentgroupWithImage: React.FC<VisualContentgroupWithImageProps> = props => {\n const { imageRatio = 'square', visualContent, children, testId } = props;\n\n return (\n <div data-testid={testId} className={styles['visual-contentgroup-with-image']}>\n <div\n className={classNames(styles['visual-contentgroup-with-image__frame'], {\n [styles[`visual-contentgroup-with-image__frame--${imageRatio}`]]: imageRatio,\n })}\n >\n {visualContent}\n </div>\n {children}\n </div>\n );\n};\n\nexport default VisualContentgroupWithImage;\n","import VisualContentgroupWithImage from './VisualContentgroupWithImage';\nexport * from './VisualContentgroupWithImage';\nexport default VisualContentgroupWithImage;\n"],"mappings":";;;;AAiBA,IAAM,+BAA0E,UAAS;CACvF,MAAM,EAAE,aAAa,UAAU,eAAe,UAAU,WAAW;CAEnE,OACE,qBAAC,OAAD;EAAK,eAAa;EAAQ,WAAW,OAAO;YAA5C,CACE,oBAAC,OAAD;GACE,WAAW,WAAW,OAAO,0CAA0C,GACpE,OAAO,0CAA0C,gBAAgB,WACpE,CAAC;aAEA;EACE,CAAA,GACJ,QACE;;AAET;;;AC9BA,IAAA,sCAAe"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use '../../scss/breakpoints' as breakpoints;
|
|
3
|
+
@import '../../scss/supernova/styles/spacers.css';
|
|
4
|
+
|
|
5
|
+
.visual-contentgroup-with-image {
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
justify-content: start;
|
|
9
|
+
align-items: start;
|
|
10
|
+
gap: var(--core-space-l);
|
|
11
|
+
|
|
12
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, sm)) {
|
|
13
|
+
flex-direction: row-reverse;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&__frame {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
width: 100%;
|
|
22
|
+
|
|
23
|
+
> * {
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: 100%;
|
|
26
|
+
object-fit: cover;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&--square {
|
|
30
|
+
aspect-ratio: 1/1;
|
|
31
|
+
|
|
32
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, sm)) {
|
|
33
|
+
flex: 0 0 50%;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, lg)) {
|
|
37
|
+
max-width: 30rem;
|
|
38
|
+
max-height: 30rem;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&--landscape {
|
|
43
|
+
aspect-ratio: 3/2;
|
|
44
|
+
|
|
45
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, sm)) {
|
|
46
|
+
flex: 0 0 50%;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type Styles = {
|
|
2
|
+
'visual-contentgroup-with-image': string;
|
|
3
|
+
'visual-contentgroup-with-image__frame': string;
|
|
4
|
+
'visual-contentgroup-with-image__frame--landscape': string;
|
|
5
|
+
'visual-contentgroup-with-image__frame--square': string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type ClassNames = keyof Styles;
|
|
9
|
+
|
|
10
|
+
declare const styles: Styles;
|
|
11
|
+
|
|
12
|
+
export default styles;
|
package/lib/getFilterChips.js
CHANGED
|
@@ -11,7 +11,7 @@ function getFilterChips({ filter, getLabel, onChipClick, onChipRemove, onOverflo
|
|
|
11
11
|
});
|
|
12
12
|
const visibleChips = allChips.slice(0, maxVisible);
|
|
13
13
|
const overflowCount = allChips.length - maxVisible;
|
|
14
|
-
return [visibleChips.map(({ key, value: v }) => /* @__PURE__ */ jsx(Chip_default, {
|
|
14
|
+
return [...visibleChips.map(({ key, value: v }) => /* @__PURE__ */ jsx(Chip_default, {
|
|
15
15
|
onChipClick: () => onChipClick(key, v),
|
|
16
16
|
onCloseClick: () => {
|
|
17
17
|
if (onChipRemove) onChipRemove(key, v);
|
|
@@ -19,11 +19,11 @@ function getFilterChips({ filter, getLabel, onChipClick, onChipRemove, onOverflo
|
|
|
19
19
|
},
|
|
20
20
|
withCloseButton: willShowCloseButton?.(key, v),
|
|
21
21
|
children: getLabel(key, v)
|
|
22
|
-
}, `${key}-${v}`)), overflowCount > 0
|
|
22
|
+
}, `${key}-${v}`)), ...overflowCount > 0 ? [/* @__PURE__ */ jsx(Chip_default, {
|
|
23
23
|
onChipClick: onOverflowChipClick,
|
|
24
24
|
withCloseButton: false,
|
|
25
25
|
children: `+${overflowCount}`
|
|
26
|
-
}, "overflow")];
|
|
26
|
+
}, "overflow")] : []];
|
|
27
27
|
}
|
|
28
28
|
//#endregion
|
|
29
29
|
//#region src/components/Filter/getFilterChips/index.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFilterChips.js","names":[],"sources":["../src/components/Filter/getFilterChips/getFilterChips.tsx","../src/components/Filter/getFilterChips/index.ts"],"sourcesContent":["import type { FilterValues, UseFilterReturn } from '../useFilter';\n\nimport Chip from '../../Chip';\n\nexport interface GetFilterChipsArgs<T extends FilterValues> {\n /** The filter instance from useFilter */\n filter: UseFilterReturn<T>;\n /** Look up the display label for a filter key + value */\n getLabel: (key: keyof T, value: unknown) => string;\n /** Called when a chip is clicked (f.ex. to open the drawer at that filter category) */\n onChipClick: (key: keyof T, value: unknown) => void;\n /** Called when a chip's close button is clicked. If not provided, defaults to filter.removeFilter */\n onChipRemove?: (key: keyof T, value: unknown) => void;\n /** Called when the overflow chip is clicked */\n onOverflowChipClick: () => void;\n /** Function for mapping if close button is shown on chip or not */\n willShowCloseButton?: (key: keyof T, value?: unknown) => boolean;\n}\n\nfunction getFilterChips<T extends FilterValues>({\n filter,\n getLabel,\n onChipClick,\n onChipRemove,\n onOverflowChipClick,\n willShowCloseButton,\n}: GetFilterChipsArgs<T>): React.ReactNode[] {\n const maxVisible = 5;\n\n const allChips = Object.entries(filter.filters).flatMap(([key, raw]) => {\n const values = [raw ?? []].flat();\n return values.map(v => ({ key, value: v }));\n });\n\n const visibleChips = allChips.slice(0, maxVisible);\n const overflowCount = allChips.length - maxVisible;\n\n return [\n visibleChips.map(({ key, value: v }) => (\n <Chip\n key={`${key}-${v}`}\n onChipClick={() => onChipClick(key as keyof T, v)}\n onCloseClick={() => {\n if (onChipRemove) {\n onChipRemove(key as keyof T, v);\n } else {\n filter.removeFilter(key, v);\n }\n }}\n withCloseButton={willShowCloseButton?.(key, v)}\n >\n {getLabel(key as keyof T, v)}\n </Chip>\n )),\n overflowCount > 0
|
|
1
|
+
{"version":3,"file":"getFilterChips.js","names":[],"sources":["../src/components/Filter/getFilterChips/getFilterChips.tsx","../src/components/Filter/getFilterChips/index.ts"],"sourcesContent":["import type { FilterValues, UseFilterReturn } from '../useFilter';\n\nimport Chip from '../../Chip';\n\nexport interface GetFilterChipsArgs<T extends FilterValues> {\n /** The filter instance from useFilter */\n filter: UseFilterReturn<T>;\n /** Look up the display label for a filter key + value */\n getLabel: (key: keyof T, value: unknown) => string;\n /** Called when a chip is clicked (f.ex. to open the drawer at that filter category) */\n onChipClick: (key: keyof T, value: unknown) => void;\n /** Called when a chip's close button is clicked. If not provided, defaults to filter.removeFilter */\n onChipRemove?: (key: keyof T, value: unknown) => void;\n /** Called when the overflow chip is clicked */\n onOverflowChipClick: () => void;\n /** Function for mapping if close button is shown on chip or not */\n willShowCloseButton?: (key: keyof T, value?: unknown) => boolean;\n}\n\nfunction getFilterChips<T extends FilterValues>({\n filter,\n getLabel,\n onChipClick,\n onChipRemove,\n onOverflowChipClick,\n willShowCloseButton,\n}: GetFilterChipsArgs<T>): React.ReactNode[] {\n const maxVisible = 5;\n\n const allChips = Object.entries(filter.filters).flatMap(([key, raw]) => {\n const values = [raw ?? []].flat();\n return values.map(v => ({ key, value: v }));\n });\n\n const visibleChips = allChips.slice(0, maxVisible);\n const overflowCount = allChips.length - maxVisible;\n\n return [\n ...visibleChips.map(({ key, value: v }) => (\n <Chip\n key={`${key}-${v}`}\n onChipClick={() => onChipClick(key as keyof T, v)}\n onCloseClick={() => {\n if (onChipRemove) {\n onChipRemove(key as keyof T, v);\n } else {\n filter.removeFilter(key, v);\n }\n }}\n withCloseButton={willShowCloseButton?.(key, v)}\n >\n {getLabel(key as keyof T, v)}\n </Chip>\n )),\n ...(overflowCount > 0\n ? [<Chip key=\"overflow\" onChipClick={onOverflowChipClick} withCloseButton={false}>{`+${overflowCount}`}</Chip>]\n : []),\n ];\n}\n\nexport default getFilterChips;\n","import getFilterChips from './getFilterChips';\nexport * from './getFilterChips';\nexport default getFilterChips;\n"],"mappings":";;;AAmBA,SAAS,eAAuC,EAC9C,QACA,UACA,aACA,cACA,qBACA,uBAC2C;CAC3C,MAAM,aAAa;CAEnB,MAAM,WAAW,OAAO,QAAQ,OAAO,OAAO,EAAE,SAAS,CAAC,KAAK,SAAS;EAEtE,OADe,CAAC,OAAO,CAAC,CAAC,EAAE,KACpB,EAAO,KAAI,OAAM;GAAE;GAAK,OAAO;EAAE,EAAE;CAC5C,CAAC;CAED,MAAM,eAAe,SAAS,MAAM,GAAG,UAAU;CACjD,MAAM,gBAAgB,SAAS,SAAS;CAExC,OAAO,CACL,GAAG,aAAa,KAAK,EAAE,KAAK,OAAO,QACjC,oBAAC,cAAD;EAEE,mBAAmB,YAAY,KAAgB,CAAC;EAChD,oBAAoB;GAClB,IAAI,cACF,aAAa,KAAgB,CAAC;QAE9B,OAAO,aAAa,KAAK,CAAC;EAE9B;EACA,iBAAiB,sBAAsB,KAAK,CAAC;YAE5C,SAAS,KAAgB,CAAC;CACvB,GAZC,GAAG,IAAI,GAAG,GAYX,CACP,GACD,GAAI,gBAAgB,IAChB,CAAC,oBAAC,cAAD;EAAqB,aAAa;EAAqB,iBAAiB;YAAQ,IAAI;CAAsB,GAAhG,UAAgG,CAAC,IAC5G,CAAC,CACP;AACF;;;ACxDA,IAAA,yBAAe"}
|
package/package.json
CHANGED