@helsenorge/designsystem-react 11.5.0 → 11.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/Expander.js +3 -0
- package/Expander.js.map +1 -1
- package/FormGroup.js +2 -1
- package/FormGroup.js.map +1 -1
- package/Panel.js +6 -1
- package/Panel.js.map +1 -1
- package/TabList.js +1 -4
- package/TabList.js.map +1 -1
- package/components/Expander/Expander.d.ts +1 -0
- package/components/FormGroup/FormGroup.d.ts +2 -0
- package/components/NotificationPanel/NotificationPanel.d.ts +1 -1
- package/components/NotificationPanel/index.js.map +1 -1
- package/components/Panel/Panel.d.ts +2 -0
- package/components/Tabs/TabList/styles.module.scss +14 -4
- package/components/Tabs/TabList/styles.module.scss.d.ts +1 -0
- package/components/Tabs/styles.module.scss +4 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## [11.7.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv11.6.0&targetVersion=GTv11.7.0) (2025-08-13)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **notificationpanel:** propen role har status som valg ([6c93716](https://github.com/helsenorge/designsystem/commit/6c937166f6ccf35c9d91699b5c19ea5327e9103e)), closes [#357209](https://github.com/helsenorge/designsystem/issues/357209)
|
|
7
|
+
|
|
8
|
+
## [11.6.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv11.5.0&targetVersion=GTv11.6.0) (2025-08-11)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **fromgroup:** formgroup får aria-labelledby som alternativ til legend ([abf306c](https://github.com/helsenorge/designsystem/commit/abf306ca007f12a399aee5ad26c993f6a458df83)), closes [#356915](https://github.com/helsenorge/designsystem/issues/356915)
|
|
14
|
+
* **panel:** legg til controlled funksjonalitet for expandable panel ([de7ca61](https://github.com/helsenorge/designsystem/commit/de7ca612169be8e5e825a9975cbc30c79dde446c)), closes [#356603](https://github.com/helsenorge/designsystem/issues/356603)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* **tabs:** border vises rart på noen skjermer ([40c4fb5](https://github.com/helsenorge/designsystem/commit/40c4fb5c08d688dfa633573d851d3a14098a99a8)), closes [#346853](https://github.com/helsenorge/designsystem/issues/346853)
|
|
20
|
+
* **tabs:** tablist border ser riktig ut ved zooming ([d031642](https://github.com/helsenorge/designsystem/commit/d031642fff55581b845819e26e20c17da4d9c18e)), closes [#346853](https://github.com/helsenorge/designsystem/issues/346853)
|
|
21
|
+
|
|
1
22
|
## [11.5.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv11.4.1&targetVersion=GTv11.5.0) (2025-07-30)
|
|
2
23
|
|
|
3
24
|
|
package/Expander.js
CHANGED
|
@@ -18,6 +18,7 @@ var ExpanderSize = /* @__PURE__ */ ((ExpanderSize2) => {
|
|
|
18
18
|
})(ExpanderSize || {});
|
|
19
19
|
const Expander = (props) => {
|
|
20
20
|
const {
|
|
21
|
+
buttonId,
|
|
21
22
|
title,
|
|
22
23
|
children,
|
|
23
24
|
size = "small",
|
|
@@ -51,6 +52,7 @@ const Expander = (props) => {
|
|
|
51
52
|
const renderTrigger = () => /* @__PURE__ */ jsxs(
|
|
52
53
|
"button",
|
|
53
54
|
{
|
|
55
|
+
id: buttonId,
|
|
54
56
|
type: "button",
|
|
55
57
|
className: triggerClassName,
|
|
56
58
|
style: {
|
|
@@ -84,6 +86,7 @@ const Expander = (props) => {
|
|
|
84
86
|
children: /* @__PURE__ */ jsxs(
|
|
85
87
|
Button,
|
|
86
88
|
{
|
|
89
|
+
id: buttonId,
|
|
87
90
|
variant: "borderless",
|
|
88
91
|
textClassName: styles["expander__button__text"],
|
|
89
92
|
className: buttonClassName,
|
package/Expander.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Expander.js","sources":["../src/components/Expander/Expander.tsx"],"sourcesContent":["import React, { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\nimport { useExpand } from '../../hooks/useExpand';\nimport { useHover } from '../../hooks/useHover';\nimport { useSize } from '../../hooks/useSize';\nimport { PaletteNames } from '../../theme/palette';\nimport Button from '../Button';\nimport Icon, { IconSize, SvgIcon } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport { IconName } from '../Icons/IconNames';\nimport LazyIcon from '../LazyIcon';\n\nimport styles from './styles.module.scss';\n\nexport enum ExpanderSize {\n small = 'small',\n large = 'large',\n}\n\nexport type ExpanderColors = Extract<PaletteNames, 'banana' | 'blueberry' | 'cherry' | 'kiwi' | 'neutral' | 'plum' | 'white'>;\n\nexport interface ExpanderProps {\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 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 } = useHover(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 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 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'],\n { [styles['expander__content--sticky']]: isSticky },\n contentClassNames\n );\n\n return <div className={contentClassName}>{children}</div>;\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"],"names":["ExpanderSize"],"mappings":";;;;;;;;;;;;;AAkBY,IAAA,iCAAAA,kBAAL;AACLA,gBAAA,OAAQ,IAAA;AACRA,gBAAA,OAAQ,IAAA;AAFEA,SAAAA;AAAA,GAAA,gBAAA,CAAA,CAAA;
|
|
1
|
+
{"version":3,"file":"Expander.js","sources":["../src/components/Expander/Expander.tsx"],"sourcesContent":["import React, { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\nimport { useExpand } from '../../hooks/useExpand';\nimport { useHover } from '../../hooks/useHover';\nimport { useSize } from '../../hooks/useSize';\nimport { PaletteNames } from '../../theme/palette';\nimport Button from '../Button';\nimport Icon, { IconSize, SvgIcon } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport { IconName } from '../Icons/IconNames';\nimport LazyIcon from '../LazyIcon';\n\nimport styles from './styles.module.scss';\n\nexport enum ExpanderSize {\n small = 'small',\n large = 'large',\n}\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 } = useHover(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'],\n { [styles['expander__content--sticky']]: isSticky },\n contentClassNames\n );\n\n return <div className={contentClassName}>{children}</div>;\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"],"names":["ExpanderSize"],"mappings":"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"}
|
package/FormGroup.js
CHANGED
|
@@ -16,6 +16,7 @@ import { T as Title } from "./Title.js";
|
|
|
16
16
|
import formGroupStyles from "./components/FormGroup/styles.module.scss";
|
|
17
17
|
const FormGroup = React__default.forwardRef((props, ref) => {
|
|
18
18
|
const {
|
|
19
|
+
ariaLabelledBy,
|
|
19
20
|
className,
|
|
20
21
|
fieldsetClassName,
|
|
21
22
|
onColor = FormOnColor.onwhite,
|
|
@@ -115,7 +116,7 @@ const FormGroup = React__default.forwardRef((props, ref) => {
|
|
|
115
116
|
props.legend && /* @__PURE__ */ jsx("h5", { className: legendClasses, children: props.legend }),
|
|
116
117
|
React__default.Children.map(props.children, mapFormComponent)
|
|
117
118
|
] }),
|
|
118
|
-
htmlMarkup === "fieldset" && /* @__PURE__ */ jsxs("fieldset", { name: props.fieldsetName, className: fieldsetClasses, children: [
|
|
119
|
+
htmlMarkup === "fieldset" && /* @__PURE__ */ jsxs("fieldset", { "aria-labelledby": ariaLabelledBy, name: props.fieldsetName, className: fieldsetClasses, children: [
|
|
119
120
|
props.legend && /* @__PURE__ */ jsx("legend", { className: legendClasses, children: props.legend }),
|
|
120
121
|
React__default.Children.map(props.children, mapFormComponent)
|
|
121
122
|
] })
|
package/FormGroup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormGroup.js","sources":["../src/components/FormGroup/FormGroup.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, FormOnColor, FormSize } from '../../constants';\nimport { useUuid } from '../../hooks/useUuid';\nimport { isComponent } from '../../utils/component';\nimport Checkbox, { CheckboxProps } from '../Checkbox/Checkbox';\nimport ErrorWrapper from '../ErrorWrapper';\nimport FormLayout, { FormLayoutProps } from '../FormLayout';\nimport Input, { InputProps } from '../Input/Input';\nimport RadioButton, { RadioButtonProps, getRadioLabelClasses } from '../RadioButton/RadioButton';\nimport Select, { SelectProps } from '../Select';\nimport Slider, { SliderProps } from '../Slider';\nimport Textarea, { TextareaProps } from '../Textarea';\nimport Title from '../Title';\n\nimport formGroupStyles from './styles.module.scss';\n\nexport type FormGroupTags = 'fieldset' | 'div';\n\nexport interface FormGroupProps {\n /** title for the the fieldset */\n title?: string;\n /** text placed in the legend tag of the fieldset */\n legend?: string;\n /** Items in the FormGroup component */\n children?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds custom classes to the errorWrapper. */\n errorWrapperClassName?: string;\n /** Adds custom classes to the fieldset element. */\n fieldsetClassName?: string;\n /** Changes the visuals of the formgroup */\n onColor?: keyof typeof FormOnColor;\n /** Changes the visuals of the formgroup */\n size?: keyof typeof FormSize;\n /** Error message */\n error?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the data-testid attribute for the error-wrapper. */\n errorWrapperTestId?: string;\n /** Unique name for the child input element */\n name?: string;\n /** Unique name for the fieldset */\n fieldsetName?: string;\n /** Sets div instead of fieldset tag */\n htmlMarkup?: FormGroupTags;\n /** Renders the error component (Default: true) */\n renderError?: boolean;\n}\n\nexport const FormGroup = React.forwardRef((props: FormGroupProps, ref: React.ForwardedRef<HTMLDivElement>) => {\n const {\n className,\n fieldsetClassName,\n onColor = FormOnColor.onwhite,\n size = FormSize.medium,\n error,\n errorTextId,\n name,\n htmlMarkup = 'fieldset',\n renderError = true,\n errorWrapperClassName,\n errorWrapperTestId,\n } = props;\n const [checkedRadioId, setCheckedRadioId] = useState<string>();\n const radioGroupId = useUuid();\n const errorTextUuid = useUuid(errorTextId);\n const onDark = onColor === FormOnColor.ondark;\n const isLarge = size === FormSize.large;\n const formGroupWrapperClasses = classNames(formGroupStyles['form-group-wrapper'], className);\n const titleClasses = classNames({\n [formGroupStyles['form-group-wrapper__title--on-dark']]: onDark && !error,\n });\n\n const legendClasses = classNames(formGroupStyles['field-set__legend'], {\n [formGroupStyles['field-set__legend--on-dark']]: onDark && !error,\n });\n\n const fieldsetClasses = classNames(formGroupStyles['field-set'], fieldsetClassName);\n\n const mapFormComponent = (child: React.ReactNode, index: number): React.ReactNode => {\n if (isComponent<FormLayoutProps>(child, FormLayout)) {\n return React.cloneElement(child, {\n size,\n mapHelper: mapFormComponent,\n });\n } else if (isComponent<FormGroupProps>(child, FormGroup)) {\n return React.cloneElement(child, {\n onColor,\n size,\n error,\n renderError: false,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<CheckboxProps>(child, Checkbox)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n size,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<RadioButtonProps>(child, RadioButton)) {\n const radioId = typeof child.props.inputId === 'undefined' ? radioGroupId + index : child.props.inputId;\n return React.cloneElement(child, {\n inputId: radioId,\n name: name ?? child.props.name,\n onColor,\n size,\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => {\n setCheckedRadioId(event.target.id);\n child.props.onChange && child.props.onChange(event);\n },\n error: !!error,\n errorTextId: errorTextUuid,\n labelClassNames: getRadioLabelClasses(radioId, onColor as FormOnColor, isLarge, checkedRadioId),\n });\n } else if (isComponent<InputProps>(child, Input)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n size,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<TextareaProps>(child, Textarea)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<SelectProps>(child, Select)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<SliderProps>(child, Slider)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n }\n return child;\n };\n\n const formGroupContent = (): React.ReactNode => {\n return (\n <div>\n {htmlMarkup === 'div' && (\n <div className={fieldsetClasses}>\n {props.legend && <h5 className={legendClasses}>{props.legend}</h5>}\n {React.Children.map(props.children, mapFormComponent)}\n </div>\n )}\n {htmlMarkup === 'fieldset' && (\n <fieldset name={props.fieldsetName} className={fieldsetClasses}>\n {props.legend && <legend className={legendClasses}>{props.legend}</legend>}\n {React.Children.map(props.children, mapFormComponent)}\n </fieldset>\n )}\n </div>\n );\n };\n\n return (\n <div data-testid={props.testId} data-analyticsid={AnalyticsId.FormGroup} className={formGroupWrapperClasses} ref={ref} tabIndex={-1}>\n {props.title && (\n <Title className={titleClasses} htmlMarkup={'h4'} appearance={'title4'} margin={{ marginTop: 0, marginBottom: error ? 1 : 2 }}>\n {props.title}\n </Title>\n )}\n {renderError ? (\n <ErrorWrapper className={errorWrapperClassName} errorText={error} testId={errorWrapperTestId} errorTextId={errorTextUuid}>\n {formGroupContent()}\n </ErrorWrapper>\n ) : (\n formGroupContent()\n )}\n </div>\n );\n});\n\nFormGroup.displayName = 'FormGroup';\n\nexport default FormGroup;\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FormGroup.js","sources":["../src/components/FormGroup/FormGroup.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, FormOnColor, FormSize } from '../../constants';\nimport { useUuid } from '../../hooks/useUuid';\nimport { isComponent } from '../../utils/component';\nimport Checkbox, { CheckboxProps } from '../Checkbox/Checkbox';\nimport ErrorWrapper from '../ErrorWrapper';\nimport FormLayout, { FormLayoutProps } from '../FormLayout';\nimport Input, { InputProps } from '../Input/Input';\nimport RadioButton, { RadioButtonProps, getRadioLabelClasses } from '../RadioButton/RadioButton';\nimport Select, { SelectProps } from '../Select';\nimport Slider, { SliderProps } from '../Slider';\nimport Textarea, { TextareaProps } from '../Textarea';\nimport Title from '../Title';\n\nimport formGroupStyles from './styles.module.scss';\n\nexport type FormGroupTags = 'fieldset' | 'div';\n\nexport interface FormGroupProps {\n /** Can be used as a replacement text for legend in cases where the group title already exists externally */\n ariaLabelledBy?: string;\n /** title for the the fieldset */\n title?: string;\n /** text placed in the legend tag of the fieldset */\n legend?: string;\n /** Items in the FormGroup component */\n children?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds custom classes to the errorWrapper. */\n errorWrapperClassName?: string;\n /** Adds custom classes to the fieldset element. */\n fieldsetClassName?: string;\n /** Changes the visuals of the formgroup */\n onColor?: keyof typeof FormOnColor;\n /** Changes the visuals of the formgroup */\n size?: keyof typeof FormSize;\n /** Error message */\n error?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the data-testid attribute for the error-wrapper. */\n errorWrapperTestId?: string;\n /** Unique name for the child input element */\n name?: string;\n /** Unique name for the fieldset */\n fieldsetName?: string;\n /** Sets div instead of fieldset tag */\n htmlMarkup?: FormGroupTags;\n /** Renders the error component (Default: true) */\n renderError?: boolean;\n}\n\nexport const FormGroup = React.forwardRef((props: FormGroupProps, ref: React.ForwardedRef<HTMLDivElement>) => {\n const {\n ariaLabelledBy,\n className,\n fieldsetClassName,\n onColor = FormOnColor.onwhite,\n size = FormSize.medium,\n error,\n errorTextId,\n name,\n htmlMarkup = 'fieldset',\n renderError = true,\n errorWrapperClassName,\n errorWrapperTestId,\n } = props;\n const [checkedRadioId, setCheckedRadioId] = useState<string>();\n const radioGroupId = useUuid();\n const errorTextUuid = useUuid(errorTextId);\n const onDark = onColor === FormOnColor.ondark;\n const isLarge = size === FormSize.large;\n const formGroupWrapperClasses = classNames(formGroupStyles['form-group-wrapper'], className);\n const titleClasses = classNames({\n [formGroupStyles['form-group-wrapper__title--on-dark']]: onDark && !error,\n });\n\n const legendClasses = classNames(formGroupStyles['field-set__legend'], {\n [formGroupStyles['field-set__legend--on-dark']]: onDark && !error,\n });\n\n const fieldsetClasses = classNames(formGroupStyles['field-set'], fieldsetClassName);\n\n const mapFormComponent = (child: React.ReactNode, index: number): React.ReactNode => {\n if (isComponent<FormLayoutProps>(child, FormLayout)) {\n return React.cloneElement(child, {\n size,\n mapHelper: mapFormComponent,\n });\n } else if (isComponent<FormGroupProps>(child, FormGroup)) {\n return React.cloneElement(child, {\n onColor,\n size,\n error,\n renderError: false,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<CheckboxProps>(child, Checkbox)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n size,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<RadioButtonProps>(child, RadioButton)) {\n const radioId = typeof child.props.inputId === 'undefined' ? radioGroupId + index : child.props.inputId;\n return React.cloneElement(child, {\n inputId: radioId,\n name: name ?? child.props.name,\n onColor,\n size,\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => {\n setCheckedRadioId(event.target.id);\n child.props.onChange && child.props.onChange(event);\n },\n error: !!error,\n errorTextId: errorTextUuid,\n labelClassNames: getRadioLabelClasses(radioId, onColor as FormOnColor, isLarge, checkedRadioId),\n });\n } else if (isComponent<InputProps>(child, Input)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n size,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<TextareaProps>(child, Textarea)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<SelectProps>(child, Select)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<SliderProps>(child, Slider)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n }\n return child;\n };\n\n const formGroupContent = (): React.ReactNode => {\n return (\n <div>\n {htmlMarkup === 'div' && (\n <div className={fieldsetClasses}>\n {props.legend && <h5 className={legendClasses}>{props.legend}</h5>}\n {React.Children.map(props.children, mapFormComponent)}\n </div>\n )}\n {htmlMarkup === 'fieldset' && (\n <fieldset aria-labelledby={ariaLabelledBy} name={props.fieldsetName} className={fieldsetClasses}>\n {props.legend && <legend className={legendClasses}>{props.legend}</legend>}\n {React.Children.map(props.children, mapFormComponent)}\n </fieldset>\n )}\n </div>\n );\n };\n\n return (\n <div data-testid={props.testId} data-analyticsid={AnalyticsId.FormGroup} className={formGroupWrapperClasses} ref={ref} tabIndex={-1}>\n {props.title && (\n <Title className={titleClasses} htmlMarkup={'h4'} appearance={'title4'} margin={{ marginTop: 0, marginBottom: error ? 1 : 2 }}>\n {props.title}\n </Title>\n )}\n {renderError ? (\n <ErrorWrapper className={errorWrapperClassName} errorText={error} testId={errorWrapperTestId} errorTextId={errorTextUuid}>\n {formGroupContent()}\n </ErrorWrapper>\n ) : (\n formGroupContent()\n )}\n </div>\n );\n});\n\nFormGroup.displayName = 'FormGroup';\n\nexport default FormGroup;\n"],"names":["React"],"mappings":"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"}
|
package/Panel.js
CHANGED
|
@@ -2,6 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import React__default from "react";
|
|
3
3
|
import classNames from "classnames";
|
|
4
4
|
import { LanguageLocales, IconSize } from "./constants.js";
|
|
5
|
+
import { useExpand } from "./hooks/useExpand.js";
|
|
5
6
|
import { B as Button } from "./Button.js";
|
|
6
7
|
import { I as Icon } from "./Icon.js";
|
|
7
8
|
import { P as PanelTitle } from "./PanelTitle.js";
|
|
@@ -85,6 +86,7 @@ const PanelRoot = React__default.forwardRef(function PanelForwardedRef({
|
|
|
85
86
|
stacking = "default",
|
|
86
87
|
testId,
|
|
87
88
|
children,
|
|
89
|
+
expanded = false,
|
|
88
90
|
status = "none",
|
|
89
91
|
buttonBottomAriaLabel,
|
|
90
92
|
buttonBottomOnClick,
|
|
@@ -99,7 +101,7 @@ const PanelRoot = React__default.forwardRef(function PanelForwardedRef({
|
|
|
99
101
|
const [content, setContent] = React__default.useState([]);
|
|
100
102
|
const [expandableContent, setExpandableContent] = React__default.useState([]);
|
|
101
103
|
const [hasIcon, setHasIcon] = React__default.useState(false);
|
|
102
|
-
const [isExpanded, setIsExpanded] =
|
|
104
|
+
const [isExpanded, setIsExpanded] = useExpand(expanded, onExpand);
|
|
103
105
|
const localRef = React__default.useRef(null);
|
|
104
106
|
const panelRef = ref ?? localRef;
|
|
105
107
|
const expandedContentRef = React__default.useRef(null);
|
|
@@ -141,6 +143,9 @@ const PanelRoot = React__default.forwardRef(function PanelForwardedRef({
|
|
|
141
143
|
setHasIcon(localHasIcon);
|
|
142
144
|
}, [children]);
|
|
143
145
|
React__default.useEffect(() => {
|
|
146
|
+
if (expanded) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
144
149
|
if (isExpanded) {
|
|
145
150
|
if ("current" in panelRef && panelRef.current && expandedContentRef.current) {
|
|
146
151
|
const panelRect = panelRef.current.getBoundingClientRect();
|
package/Panel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Panel.js","sources":["../src/components/Panel/resourceHelper.ts","../src/components/Panel/Panel.tsx"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Panel.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Panel.nb-NO.json';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemPanel => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { LanguageLocales } from '../../constants';\nimport { PaletteNames } from '../../theme/palette';\nimport Button from '../Button';\nimport Icon, { IconSize } from '../Icon';\nimport PanelTitle, { PanelTitleProps } from './PanelTitle';\nimport { getResources } from './resourceHelper';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\nimport { useLanguage } from '../../utils/language';\nimport Highlighter from '../Highlighter';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronRight from '../Icons/ChevronRight';\nimport ChevronUp from '../Icons/ChevronUp';\n\nimport styles from './styles.module.scss';\n\nexport enum PanelLayout {\n vertical = 'vertical',\n horizontal = 'horizontal',\n combined = 'combined',\n bAsRightCol = 'bAsRightCol',\n}\n\nexport type PanelColors = Extract<PaletteNames, 'white' | 'neutral'>;\n\nexport enum PanelVariant {\n fill = 'fill',\n line = 'line',\n outline = 'outline',\n}\n\nexport enum PanelStacking {\n default = 'default',\n bFirst = 'bFirst',\n}\n\nexport enum PanelStatus {\n none = 'none',\n new = 'new',\n error = 'error',\n draft = 'draft',\n}\n\nexport interface PanelProps {\n /** Aria label on call to action button */\n buttonBottomAriaLabel?: string;\n /** Sets the text on the bottom call to action button */\n buttonBottomText?: string;\n /** Sets the action on the bottom call to action button */\n buttonBottomOnClick?: () => void;\n /** Sets the layout and order of the content boxes */\n layout?: PanelLayout;\n /** Sets the visual variant of panel */\n variant?: PanelVariant;\n /** Sets the color for panel if it has variant fill */\n color?: PanelColors;\n /** Sets classes on the outermost container of the panel */\n className?: string;\n /** Action called when toggling expansion of ExpandedContent */\n onExpand?: () => void;\n /** Sets the stacking order of the content boxes */\n stacking?: PanelStacking;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Children elements to be rendered inside the panel */\n children?: React.ReactNode;\n /** Displays a status on the left side: default normal */\n status?: PanelStatus;\n /** Resources for component */\n resources?: Partial<HNDesignsystemPanel>;\n /** Highlights text in title and content. Used for search results */\n highlightText?: string;\n}\n\nconst ExpandButton = ({\n onClick,\n isExpanded,\n resources,\n}: {\n onClick: () => void;\n isExpanded: boolean | undefined;\n resources: Partial<HNDesignsystemPanel>;\n}): React.JSX.Element => {\n const buttonClassName = classNames(styles['expander__button'], isExpanded && styles['expander__button--expanded']);\n\n return (\n <Button\n variant=\"borderless\"\n textClassName={styles['expander__button__text']}\n wrapperClassName={buttonClassName}\n aria-expanded={isExpanded}\n onClick={onClick}\n >\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} />\n <span>{isExpanded ? resources.expandButtonClose : resources.expandButtonOpen}</span>\n </Button>\n );\n};\nconst PanelRoot = React.forwardRef(function PanelForwardedRef(\n {\n layout = PanelLayout.vertical,\n variant = PanelVariant.fill,\n color = 'neutral',\n stacking = PanelStacking.default,\n testId,\n children,\n status = PanelStatus.none,\n buttonBottomAriaLabel,\n buttonBottomOnClick,\n buttonBottomText,\n className,\n resources,\n onExpand,\n highlightText,\n }: PanelProps,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const [preContainer, setPreContainer] = React.useState<React.ReactNode[]>([]);\n const [title, setTitle] = React.useState<React.ReactNode[]>([]);\n const [content, setContent] = React.useState<React.ReactNode[]>([]);\n const [expandableContent, setExpandableContent] = React.useState<React.ReactNode[]>([]);\n const [hasIcon, setHasIcon] = React.useState(false);\n const [isExpanded, setIsExpanded] = React.useState(false);\n const localRef = React.useRef<HTMLDivElement>(null);\n const panelRef = ref ?? localRef;\n const expandedContentRef = React.useRef<HTMLDivElement>(null);\n const defaultScroll = 100;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemPanel = {\n ...defaultResources,\n ...resources,\n };\n\n React.useEffect(() => {\n let localHasIcon = false;\n const newPreContainer: React.ReactNode[] = [];\n const newTitle: React.ReactNode[] = [];\n const newContent: React.ReactNode[] = [];\n const newExpandableContent: React.ReactNode[] = [];\n\n React.Children.forEach(children, child => {\n if (React.isValidElement(child)) {\n if (child.type === PreContainer) {\n newPreContainer.push(child);\n } else if (child.type === PanelTitle) {\n newTitle.push(\n React.cloneElement(child as React.ReactElement<PanelTitleProps>, { highlightText: child.props.highlightText || highlightText })\n );\n if (child.props.icon) {\n localHasIcon = true;\n }\n } else if (child.type === A || child.type === B || child.type === C) {\n newContent.push(child);\n } else if (child.type === ExpandedContent) {\n newExpandableContent.push(child);\n }\n }\n });\n\n setPreContainer(newPreContainer);\n setTitle(newTitle);\n setContent(newContent);\n setExpandableContent(newExpandableContent);\n setHasIcon(localHasIcon);\n }, [children]);\n\n React.useEffect(() => {\n // Scroller oppover når expanded content åpnes\n if (isExpanded) {\n if ('current' in panelRef && panelRef.current && expandedContentRef.current) {\n const panelRect = panelRef.current.getBoundingClientRect();\n const expandedContentRect = expandedContentRef.current.getBoundingClientRect();\n\n const scrollAmount = Math.min(defaultScroll, panelRect.top - 20);\n\n // Scroller kun oppover, og kun dersom expandedContent havner utenfor skjermen når åpnet\n if (scrollAmount > 0 && expandedContentRect.bottom > window.innerHeight) {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n return;\n }\n window.scrollBy({\n top: scrollAmount,\n behavior: 'smooth',\n });\n }\n }\n }\n }, [isExpanded]);\n\n const colorScheme = variant === PanelVariant.fill ? color : 'white';\n\n const outerClassnames = classNames(className, {\n [styles['panel__border--outline--outer']]: variant === PanelVariant.outline,\n [styles['panel__border--line']]: variant === PanelVariant.line,\n [styles['panel__border--fill--neutral']]: variant === PanelVariant.fill && colorScheme === 'neutral',\n [styles['panel__border--fill--new']]: variant === PanelVariant.fill && status === PanelStatus.new,\n [styles['panel__border--fill--status']]: variant === PanelVariant.fill && status !== PanelStatus.none,\n });\n const panelClassnames = classNames(styles['panel'], styles[`panel--${colorScheme}`], styles['panel--status'], {\n [styles['panel--line']]: variant === PanelVariant.line,\n [styles['panel--new']]: status === PanelStatus.new,\n [styles['panel--draft']]: status === PanelStatus.draft,\n [styles['panel--error']]: status === PanelStatus.error,\n [styles['panel--icon']]: hasIcon,\n });\n const contentContainerLayout = classNames(styles['panel__content'], styles[`panel__content--${layout}`], {\n [styles[`panel__content--b-first`]]: stacking === PanelStacking.bFirst,\n });\n const expanderBorderLayout = classNames({\n [styles['panel__expander__border--expanded']]: isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--${colorScheme}`]]: !isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--line`]]: !isExpanded && status === PanelStatus.none && variant === PanelVariant.line,\n });\n\n const handleExpandClick = (): void => {\n setIsExpanded(!isExpanded);\n onExpand && onExpand();\n };\n\n return expandableContent.length > 0 ? (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={expanderBorderLayout}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n <ExpandButton onClick={handleExpandClick} isExpanded={isExpanded} resources={mergedResources} />\n {isExpanded && (\n <div ref={expandedContentRef} data-testid={testId + '-details'}>\n <div className={styles['panel__expander__separator']} />\n <Highlighter searchText={highlightText}>{expandableContent}</Highlighter>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n ) : (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n {buttonBottomText && buttonBottomOnClick && (\n <div className={styles['panel__button-bottom']}>\n <Button variant=\"borderless\" type=\"button\" size=\"medium\" onClick={buttonBottomOnClick} aria-label={buttonBottomAriaLabel}>\n {buttonBottomText}\n <Icon svgIcon={ChevronRight} size={IconSize.XSmall} />\n </Button>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nexport interface ContentProps {\n /** Children elements to be rendered inside the content box */\n children?: React.ReactNode;\n}\n\nexport const PreContainer: React.FC<ContentProps> = ({ children }) => {\n return <div className={styles['panel__pre-container']}>{children}</div>;\n};\n\nexport const A: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--a']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const B: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--b']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const C: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--c']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const ExpandedContent: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__expander__content']);\n return <div className={styling}>{children}</div>;\n};\n\ntype PanelComponent = typeof PanelRoot & {\n PreContainer: React.FC<ContentProps>;\n Title: React.FC<PanelTitleProps>;\n A: React.FC<ContentProps>;\n B: React.FC<ContentProps>;\n C: React.FC<ContentProps>;\n ExpandedContent: React.FC<ContentProps>;\n};\nPanelRoot.displayName = 'Panel';\nconst Panel = PanelRoot as PanelComponent;\nPanel.PreContainer = PreContainer;\nPanel.Title = PanelTitle;\nPanel.A = A;\nPanel.B = B;\nPanel.C = C;\nPanel.ExpandedContent = ExpandedContent;\n\nexport default Panel;\n"],"names":["PanelLayout","PanelVariant","PanelStacking","PanelStatus","React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Panel.js","sources":["../src/components/Panel/resourceHelper.ts","../src/components/Panel/Panel.tsx"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Panel.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Panel.nb-NO.json';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemPanel => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { LanguageLocales } from '../../constants';\nimport { useExpand } from '../../hooks/useExpand';\nimport { PaletteNames } from '../../theme/palette';\nimport Button from '../Button';\nimport Icon, { IconSize } from '../Icon';\nimport PanelTitle, { PanelTitleProps } from './PanelTitle';\nimport { getResources } from './resourceHelper';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\nimport { useLanguage } from '../../utils/language';\nimport Highlighter from '../Highlighter';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronRight from '../Icons/ChevronRight';\nimport ChevronUp from '../Icons/ChevronUp';\n\nimport styles from './styles.module.scss';\n\nexport enum PanelLayout {\n vertical = 'vertical',\n horizontal = 'horizontal',\n combined = 'combined',\n bAsRightCol = 'bAsRightCol',\n}\n\nexport type PanelColors = Extract<PaletteNames, 'white' | 'neutral'>;\n\nexport enum PanelVariant {\n fill = 'fill',\n line = 'line',\n outline = 'outline',\n}\n\nexport enum PanelStacking {\n default = 'default',\n bFirst = 'bFirst',\n}\n\nexport enum PanelStatus {\n none = 'none',\n new = 'new',\n error = 'error',\n draft = 'draft',\n}\n\nexport interface PanelProps {\n /** Aria label on call to action button */\n buttonBottomAriaLabel?: string;\n /** Sets the text on the bottom call to action button */\n buttonBottomText?: string;\n /** Sets the action on the bottom call to action button */\n buttonBottomOnClick?: () => void;\n /** Expands or collapses the panel. Only applicable when ExpandedContent is used */\n expanded?: boolean;\n /** Sets the layout and order of the content boxes */\n layout?: PanelLayout;\n /** Sets the visual variant of panel */\n variant?: PanelVariant;\n /** Sets the color for panel if it has variant fill */\n color?: PanelColors;\n /** Sets classes on the outermost container of the panel */\n className?: string;\n /** Action called when toggling expansion of ExpandedContent */\n onExpand?: () => void;\n /** Sets the stacking order of the content boxes */\n stacking?: PanelStacking;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Children elements to be rendered inside the panel */\n children?: React.ReactNode;\n /** Displays a status on the left side: default normal */\n status?: PanelStatus;\n /** Resources for component */\n resources?: Partial<HNDesignsystemPanel>;\n /** Highlights text in title and content. Used for search results */\n highlightText?: string;\n}\n\nconst ExpandButton = ({\n onClick,\n isExpanded,\n resources,\n}: {\n onClick: () => void;\n isExpanded: boolean | undefined;\n resources: Partial<HNDesignsystemPanel>;\n}): React.JSX.Element => {\n const buttonClassName = classNames(styles['expander__button'], isExpanded && styles['expander__button--expanded']);\n\n return (\n <Button\n variant=\"borderless\"\n textClassName={styles['expander__button__text']}\n wrapperClassName={buttonClassName}\n aria-expanded={isExpanded}\n onClick={onClick}\n >\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} />\n <span>{isExpanded ? resources.expandButtonClose : resources.expandButtonOpen}</span>\n </Button>\n );\n};\nconst PanelRoot = React.forwardRef(function PanelForwardedRef(\n {\n layout = PanelLayout.vertical,\n variant = PanelVariant.fill,\n color = 'neutral',\n stacking = PanelStacking.default,\n testId,\n children,\n expanded = false,\n status = PanelStatus.none,\n buttonBottomAriaLabel,\n buttonBottomOnClick,\n buttonBottomText,\n className,\n resources,\n onExpand,\n highlightText,\n }: PanelProps,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const [preContainer, setPreContainer] = React.useState<React.ReactNode[]>([]);\n const [title, setTitle] = React.useState<React.ReactNode[]>([]);\n const [content, setContent] = React.useState<React.ReactNode[]>([]);\n const [expandableContent, setExpandableContent] = React.useState<React.ReactNode[]>([]);\n const [hasIcon, setHasIcon] = React.useState(false);\n const [isExpanded, setIsExpanded] = useExpand(expanded, onExpand);\n const localRef = React.useRef<HTMLDivElement>(null);\n const panelRef = ref ?? localRef;\n const expandedContentRef = React.useRef<HTMLDivElement>(null);\n const defaultScroll = 100;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemPanel = {\n ...defaultResources,\n ...resources,\n };\n\n React.useEffect(() => {\n let localHasIcon = false;\n const newPreContainer: React.ReactNode[] = [];\n const newTitle: React.ReactNode[] = [];\n const newContent: React.ReactNode[] = [];\n const newExpandableContent: React.ReactNode[] = [];\n\n React.Children.forEach(children, child => {\n if (React.isValidElement(child)) {\n if (child.type === PreContainer) {\n newPreContainer.push(child);\n } else if (child.type === PanelTitle) {\n newTitle.push(\n React.cloneElement(child as React.ReactElement<PanelTitleProps>, { highlightText: child.props.highlightText || highlightText })\n );\n if (child.props.icon) {\n localHasIcon = true;\n }\n } else if (child.type === A || child.type === B || child.type === C) {\n newContent.push(child);\n } else if (child.type === ExpandedContent) {\n newExpandableContent.push(child);\n }\n }\n });\n\n setPreContainer(newPreContainer);\n setTitle(newTitle);\n setContent(newContent);\n setExpandableContent(newExpandableContent);\n setHasIcon(localHasIcon);\n }, [children]);\n\n React.useEffect(() => {\n if (expanded) {\n // Hvis panel åpnes controlled skal ikke scroll skje\n return;\n }\n // Scroller oppover når expanded content åpnes uncontrolled\n if (isExpanded) {\n if ('current' in panelRef && panelRef.current && expandedContentRef.current) {\n const panelRect = panelRef.current.getBoundingClientRect();\n const expandedContentRect = expandedContentRef.current.getBoundingClientRect();\n\n const scrollAmount = Math.min(defaultScroll, panelRect.top - 20);\n\n // Scroller kun oppover, og kun dersom expandedContent havner utenfor skjermen når åpnet\n if (scrollAmount > 0 && expandedContentRect.bottom > window.innerHeight) {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n return;\n }\n window.scrollBy({\n top: scrollAmount,\n behavior: 'smooth',\n });\n }\n }\n }\n }, [isExpanded]);\n\n const colorScheme = variant === PanelVariant.fill ? color : 'white';\n\n const outerClassnames = classNames(className, {\n [styles['panel__border--outline--outer']]: variant === PanelVariant.outline,\n [styles['panel__border--line']]: variant === PanelVariant.line,\n [styles['panel__border--fill--neutral']]: variant === PanelVariant.fill && colorScheme === 'neutral',\n [styles['panel__border--fill--new']]: variant === PanelVariant.fill && status === PanelStatus.new,\n [styles['panel__border--fill--status']]: variant === PanelVariant.fill && status !== PanelStatus.none,\n });\n const panelClassnames = classNames(styles['panel'], styles[`panel--${colorScheme}`], styles['panel--status'], {\n [styles['panel--line']]: variant === PanelVariant.line,\n [styles['panel--new']]: status === PanelStatus.new,\n [styles['panel--draft']]: status === PanelStatus.draft,\n [styles['panel--error']]: status === PanelStatus.error,\n [styles['panel--icon']]: hasIcon,\n });\n const contentContainerLayout = classNames(styles['panel__content'], styles[`panel__content--${layout}`], {\n [styles[`panel__content--b-first`]]: stacking === PanelStacking.bFirst,\n });\n const expanderBorderLayout = classNames({\n [styles['panel__expander__border--expanded']]: isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--${colorScheme}`]]: !isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--line`]]: !isExpanded && status === PanelStatus.none && variant === PanelVariant.line,\n });\n\n const handleExpandClick = (): void => {\n setIsExpanded(!isExpanded);\n onExpand && onExpand();\n };\n\n return expandableContent.length > 0 ? (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={expanderBorderLayout}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n <ExpandButton onClick={handleExpandClick} isExpanded={isExpanded} resources={mergedResources} />\n {isExpanded && (\n <div ref={expandedContentRef} data-testid={testId + '-details'}>\n <div className={styles['panel__expander__separator']} />\n <Highlighter searchText={highlightText}>{expandableContent}</Highlighter>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n ) : (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n {buttonBottomText && buttonBottomOnClick && (\n <div className={styles['panel__button-bottom']}>\n <Button variant=\"borderless\" type=\"button\" size=\"medium\" onClick={buttonBottomOnClick} aria-label={buttonBottomAriaLabel}>\n {buttonBottomText}\n <Icon svgIcon={ChevronRight} size={IconSize.XSmall} />\n </Button>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nexport interface ContentProps {\n /** Children elements to be rendered inside the content box */\n children?: React.ReactNode;\n}\n\nexport const PreContainer: React.FC<ContentProps> = ({ children }) => {\n return <div className={styles['panel__pre-container']}>{children}</div>;\n};\n\nexport const A: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--a']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const B: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--b']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const C: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--c']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const ExpandedContent: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__expander__content']);\n return <div className={styling}>{children}</div>;\n};\n\ntype PanelComponent = typeof PanelRoot & {\n PreContainer: React.FC<ContentProps>;\n Title: React.FC<PanelTitleProps>;\n A: React.FC<ContentProps>;\n B: React.FC<ContentProps>;\n C: React.FC<ContentProps>;\n ExpandedContent: React.FC<ContentProps>;\n};\nPanelRoot.displayName = 'Panel';\nconst Panel = PanelRoot as PanelComponent;\nPanel.PreContainer = PreContainer;\nPanel.Title = PanelTitle;\nPanel.A = A;\nPanel.B = B;\nPanel.C = C;\nPanel.ExpandedContent = ExpandedContent;\n\nexport default Panel;\n"],"names":["PanelLayout","PanelVariant","PanelStacking","PanelStatus","React"],"mappings":"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"}
|
package/TabList.js
CHANGED
|
@@ -48,9 +48,6 @@ const TabItem = (props) => {
|
|
|
48
48
|
className: tabButtonClasses,
|
|
49
49
|
"data-testid": testId,
|
|
50
50
|
ref: currentRef,
|
|
51
|
-
style: {
|
|
52
|
-
borderBottom: isSelected ? `2px solid var(--color-base-background-${props.color})` : "1px solid var(--color-action-border-onlight-focus)"
|
|
53
|
-
},
|
|
54
51
|
children: /* @__PURE__ */ jsxs("span", { className: styles["tab-list__tab__title-and-icon"], children: [
|
|
55
52
|
icon && (typeof icon === "string" ? /* @__PURE__ */ jsx(
|
|
56
53
|
LazyIcon,
|
|
@@ -122,7 +119,7 @@ const TabList = (props) => {
|
|
|
122
119
|
}
|
|
123
120
|
}
|
|
124
121
|
};
|
|
125
|
-
return /* @__PURE__ */ jsxs("div", { children: [
|
|
122
|
+
return /* @__PURE__ */ jsxs("div", { className: styles["tab-list-wrapper"], children: [
|
|
126
123
|
shouldShowFadeStart() && /* @__PURE__ */ jsxs("div", { className: classNames(styles["tab-list__start-wrapper"]), children: [
|
|
127
124
|
/* @__PURE__ */ jsx(
|
|
128
125
|
TabChevron,
|
package/TabList.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabList.js","sources":["../src/components/Tabs/Tab.tsx","../src/components/Tabs/TabList/TabItem.tsx","../src/components/Tabs/TabList/TabChevron.tsx","../src/components/Tabs/TabList/TabList.tsx"],"sourcesContent":["import React from 'react';\n\nimport { SvgIcon } from '../Icon';\nimport { IconName } from '../Icons/IconNames';\n\nexport interface TabProps {\n /** Sets the tab panel content */\n children?: React.ReactNode;\n /** Optional icon on the tab */\n icon?: SvgIcon | IconName;\n /** Called when tab is selected */\n onTabClick?: (index: number) => void;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Title on the tab */\n title?: string;\n}\n\nconst Tab: React.FC<TabProps> = props => {\n return <>{props.children ?? null}</>;\n};\n\nexport default Tab;\n","import React, { useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport { palette } from '../../../theme/palette';\nimport Icon, { IconSize } from '../../Icon';\nimport { IconName } from '../../Icons/IconNames';\nimport LazyIcon from '../../LazyIcon';\nimport { TabProps } from '../Tab';\nimport { TabsColors } from '../Tabs';\n\nimport styles from './styles.module.scss';\n\ninterface TabItemProps {\n tabProps: TabProps;\n index: number;\n color: TabsColors;\n selectedTab: number;\n tabRefs: React.MutableRefObject<React.RefObject<HTMLButtonElement>[] | null | undefined>;\n tabListVisible: boolean;\n onTabListClick: (index: number) => void;\n}\n\nconst TabItem: React.FC<TabItemProps> = props => {\n const isSelected = props.index === props.selectedTab;\n const { title, onTabClick, icon, testId } = props.tabProps;\n const handleClick = (): void => {\n onTabClick && onTabClick(props.index);\n props.onTabListClick(props.index);\n scrollToTab(props.index);\n };\n const tabButtonClasses = classNames(styles['tab-list__tab'], styles[`tab-list__tab--${props.color}`], {\n [styles['tab-list__tab--selected']]: isSelected,\n [styles['tab-list__tab--not-selected']]: !isSelected,\n });\n\n const currentRef = props.tabRefs.current && props.tabRefs.current[props.index];\n\n const scrollToTab = (index: number): void => {\n const currentRef = props.tabRefs.current && props.tabRefs.current[index];\n currentRef?.current?.scrollIntoView && currentRef?.current?.scrollIntoView({ behavior: 'smooth', inline: 'nearest', block: 'nearest' });\n };\n\n const itemRef = useRef<HTMLLIElement>(null);\n\n useEffect(() => {\n if (isSelected && props.tabListVisible) {\n scrollToTab(props.index);\n }\n }, [isSelected]);\n\n return (\n <li role=\"presentation\" ref={itemRef}>\n <button\n role=\"tab\"\n aria-selected={isSelected}\n onClick={handleClick}\n className={tabButtonClasses}\n data-testid={testId}\n ref={currentRef as React.RefObject<HTMLButtonElement>}\n style={{\n borderBottom: isSelected\n ? `2px solid var(--color-base-background-${props.color})`\n : '1px solid var(--color-action-border-onlight-focus)',\n }}\n >\n <span className={styles['tab-list__tab__title-and-icon']}>\n {icon &&\n (typeof icon === 'string' ? (\n <LazyIcon\n iconName={icon as IconName}\n size={IconSize.XSmall}\n color={isSelected ? palette[`black`] : palette['blueberry500']}\n />\n ) : (\n <Icon svgIcon={icon} size={IconSize.XSmall} color={isSelected ? palette[`black`] : palette['blueberry500']} />\n ))}\n {title}\n </span>\n </button>\n </li>\n );\n};\n\nexport default TabItem;\n","import React from 'react';\n\nimport { useHover } from '../../../hooks/useHover';\nimport Icon, { IconSize } from '../../Icon';\nimport ChevronLeft from '../../Icons/ChevronLeft';\nimport ChevronRight from '../../Icons/ChevronRight';\n\nimport styles from './styles.module.scss';\n\ninterface TabChevronProps {\n direction: 'left' | 'right';\n onClick: () => void;\n backgroundColor?: string;\n ariaLabel?: string;\n}\n\nconst TabChevron: React.FC<TabChevronProps> = ({ direction, onClick, backgroundColor, ariaLabel }) => {\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const { isHovered } = useHover<HTMLButtonElement>(buttonRef);\n\n return (\n <button\n type=\"button\"\n ref={buttonRef}\n className={styles['tab-list__button']}\n onClick={onClick}\n aria-label={ariaLabel}\n style={{ backgroundColor: backgroundColor }}\n >\n {direction === 'left' ? (\n <Icon color={'var(--color-action-graphics-onlight)'} isHovered={isHovered} svgIcon={ChevronLeft} size={IconSize.XSmall} />\n ) : (\n <Icon color={'var(--color-action-graphics-onlight)'} isHovered={isHovered} svgIcon={ChevronRight} size={IconSize.XSmall} />\n )}\n </button>\n );\n};\n\nexport default TabChevron;\n","import React, { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport TabItem from './TabItem';\nimport { useIsVisible } from '../../../hooks/useIsVisible';\nimport { useRovingFocus } from '../../../hooks/useRovingFocus';\nimport { isComponent } from '../../../utils/component';\nimport Tab, { TabProps } from '../Tab';\nimport { TabsColors, TabsOnColor } from '../Tabs';\nimport TabChevron from './TabChevron';\n\nimport styles from './styles.module.scss';\ninterface TabListProps {\n children: React.ReactNode;\n onTabListClick: (index: number) => void;\n selectedTab: number;\n color: TabsColors;\n onColor: TabsOnColor;\n ariaLabelRightButton?: string;\n ariaLabelLeftButton?: string;\n}\n\nconst TabList: React.FC<TabListProps> = props => {\n const { selectedTab, onTabListClick, children, color, onColor, ariaLabelLeftButton, ariaLabelRightButton } = props;\n\n const listRef = useRef<HTMLUListElement>(null);\n\n const tabRefs = useRef(React.Children.map(children, () => React.createRef<HTMLButtonElement>()) || []);\n useRovingFocus(onTabListClick, tabRefs, listRef, true);\n\n const tablistClasses = classNames(styles['tab-list'], styles[`tab-list--${onColor}`]);\n\n const getBackgroundColor = (onColor: TabsOnColor): string => {\n switch (onColor) {\n case 'onwhite':\n return 'var(--color-base-background-white)';\n case 'onblueberry':\n return 'var(--color-base-background-blueberry)';\n case 'onneutral':\n return 'var(--color-base-background-neutral)';\n }\n };\n const firstTab = tabRefs.current && tabRefs.current[0];\n const lastTab = tabRefs.current && tabRefs.current[tabRefs.current.length - 1];\n\n const firstTabVisible = useIsVisible(firstTab);\n const lastTabVisible = useIsVisible(lastTab);\n const tabListVisible = useIsVisible(listRef);\n\n const shouldShowFadeStart = (): boolean => {\n return !firstTabVisible;\n };\n\n const shouldShowFadeEnd = (): boolean => {\n return !lastTabVisible;\n };\n\n const scrollInList = (direction: string): void => {\n if (listRef.current) {\n const listWidth = listRef.current.clientWidth;\n const listScrollLeft = listRef.current.scrollLeft;\n const maxScrollLeft = listRef.current.scrollWidth - listWidth;\n\n if (direction === 'right' && !lastTabVisible) {\n const scrollAmount = Math.min(listWidth / 2, maxScrollLeft - listScrollLeft);\n listRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' });\n } else if (direction === 'left' && !firstTabVisible) {\n const scrollAmount = -Math.min(listWidth / 2, listScrollLeft);\n listRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' });\n }\n }\n };\n\n return (\n <div>\n {shouldShowFadeStart() && (\n <div className={classNames(styles['tab-list__start-wrapper'])}>\n <TabChevron\n onClick={() => scrollInList('left')}\n direction=\"left\"\n backgroundColor={`${getBackgroundColor(onColor)}`}\n ariaLabel={ariaLabelLeftButton}\n />\n <div\n className={classNames(styles['tab-list__fade-start'])}\n style={{\n backgroundColor: `${getBackgroundColor(onColor)}`,\n }}\n ></div>\n </div>\n )}\n <ul className={tablistClasses} ref={listRef} role=\"tablist\" aria-orientation=\"horizontal\">\n {React.Children.map(children, (child, index) => {\n if (isComponent<TabProps>(child, Tab)) {\n return (\n <TabItem\n tabRefs={tabRefs}\n tabListVisible={tabListVisible}\n key={child.props.title}\n index={index}\n selectedTab={selectedTab}\n onTabListClick={onTabListClick}\n tabProps={child.props}\n color={color}\n />\n );\n }\n return null;\n })}\n </ul>\n {shouldShowFadeEnd() && (\n <div className={classNames(styles['tab-list__end-wrapper'])}>\n <div\n className={classNames(styles['tab-list__fade-end'])}\n style={{\n backgroundColor: `${getBackgroundColor(onColor)}`,\n }}\n ></div>\n <TabChevron\n onClick={() => scrollInList('right')}\n direction=\"right\"\n backgroundColor={`${getBackgroundColor(onColor)}`}\n ariaLabel={ariaLabelRightButton}\n />\n </div>\n )}\n <div className={classNames(styles['tab-list__border'])}></div>\n </div>\n );\n};\n\nexport default TabList;\n"],"names":["currentRef","React","onColor"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TabList.js","sources":["../src/components/Tabs/Tab.tsx","../src/components/Tabs/TabList/TabItem.tsx","../src/components/Tabs/TabList/TabChevron.tsx","../src/components/Tabs/TabList/TabList.tsx"],"sourcesContent":["import React from 'react';\n\nimport { SvgIcon } from '../Icon';\nimport { IconName } from '../Icons/IconNames';\n\nexport interface TabProps {\n /** Sets the tab panel content */\n children?: React.ReactNode;\n /** Optional icon on the tab */\n icon?: SvgIcon | IconName;\n /** Called when tab is selected */\n onTabClick?: (index: number) => void;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Title on the tab */\n title?: string;\n}\n\nconst Tab: React.FC<TabProps> = props => {\n return <>{props.children ?? null}</>;\n};\n\nexport default Tab;\n","import React, { useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport { palette } from '../../../theme/palette';\nimport Icon, { IconSize } from '../../Icon';\nimport { IconName } from '../../Icons/IconNames';\nimport LazyIcon from '../../LazyIcon';\nimport { TabProps } from '../Tab';\nimport { TabsColors } from '../Tabs';\n\nimport styles from './styles.module.scss';\n\ninterface TabItemProps {\n tabProps: TabProps;\n index: number;\n color: TabsColors;\n selectedTab: number;\n tabRefs: React.MutableRefObject<React.RefObject<HTMLButtonElement>[] | null | undefined>;\n tabListVisible: boolean;\n onTabListClick: (index: number) => void;\n}\n\nconst TabItem: React.FC<TabItemProps> = props => {\n const isSelected = props.index === props.selectedTab;\n const { title, onTabClick, icon, testId } = props.tabProps;\n const handleClick = (): void => {\n onTabClick && onTabClick(props.index);\n props.onTabListClick(props.index);\n scrollToTab(props.index);\n };\n const tabButtonClasses = classNames(styles['tab-list__tab'], styles[`tab-list__tab--${props.color}`], {\n [styles['tab-list__tab--selected']]: isSelected,\n [styles['tab-list__tab--not-selected']]: !isSelected,\n });\n\n const currentRef = props.tabRefs.current && props.tabRefs.current[props.index];\n\n const scrollToTab = (index: number): void => {\n const currentRef = props.tabRefs.current && props.tabRefs.current[index];\n currentRef?.current?.scrollIntoView && currentRef?.current?.scrollIntoView({ behavior: 'smooth', inline: 'nearest', block: 'nearest' });\n };\n\n const itemRef = useRef<HTMLLIElement>(null);\n\n useEffect(() => {\n if (isSelected && props.tabListVisible) {\n scrollToTab(props.index);\n }\n }, [isSelected]);\n\n return (\n <li role=\"presentation\" ref={itemRef}>\n <button\n role=\"tab\"\n aria-selected={isSelected}\n onClick={handleClick}\n className={tabButtonClasses}\n data-testid={testId}\n ref={currentRef as React.RefObject<HTMLButtonElement>}\n >\n <span className={styles['tab-list__tab__title-and-icon']}>\n {icon &&\n (typeof icon === 'string' ? (\n <LazyIcon\n iconName={icon as IconName}\n size={IconSize.XSmall}\n color={isSelected ? palette[`black`] : palette['blueberry500']}\n />\n ) : (\n <Icon svgIcon={icon} size={IconSize.XSmall} color={isSelected ? palette[`black`] : palette['blueberry500']} />\n ))}\n {title}\n </span>\n </button>\n </li>\n );\n};\n\nexport default TabItem;\n","import React from 'react';\n\nimport { useHover } from '../../../hooks/useHover';\nimport Icon, { IconSize } from '../../Icon';\nimport ChevronLeft from '../../Icons/ChevronLeft';\nimport ChevronRight from '../../Icons/ChevronRight';\n\nimport styles from './styles.module.scss';\n\ninterface TabChevronProps {\n direction: 'left' | 'right';\n onClick: () => void;\n backgroundColor?: string;\n ariaLabel?: string;\n}\n\nconst TabChevron: React.FC<TabChevronProps> = ({ direction, onClick, backgroundColor, ariaLabel }) => {\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const { isHovered } = useHover<HTMLButtonElement>(buttonRef);\n\n return (\n <button\n type=\"button\"\n ref={buttonRef}\n className={styles['tab-list__button']}\n onClick={onClick}\n aria-label={ariaLabel}\n style={{ backgroundColor: backgroundColor }}\n >\n {direction === 'left' ? (\n <Icon color={'var(--color-action-graphics-onlight)'} isHovered={isHovered} svgIcon={ChevronLeft} size={IconSize.XSmall} />\n ) : (\n <Icon color={'var(--color-action-graphics-onlight)'} isHovered={isHovered} svgIcon={ChevronRight} size={IconSize.XSmall} />\n )}\n </button>\n );\n};\n\nexport default TabChevron;\n","import React, { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport TabItem from './TabItem';\nimport { useIsVisible } from '../../../hooks/useIsVisible';\nimport { useRovingFocus } from '../../../hooks/useRovingFocus';\nimport { isComponent } from '../../../utils/component';\nimport Tab, { TabProps } from '../Tab';\nimport { TabsColors, TabsOnColor } from '../Tabs';\nimport TabChevron from './TabChevron';\n\nimport styles from './styles.module.scss';\ninterface TabListProps {\n children: React.ReactNode;\n onTabListClick: (index: number) => void;\n selectedTab: number;\n color: TabsColors;\n onColor: TabsOnColor;\n ariaLabelRightButton?: string;\n ariaLabelLeftButton?: string;\n}\n\nconst TabList: React.FC<TabListProps> = props => {\n const { selectedTab, onTabListClick, children, color, onColor, ariaLabelLeftButton, ariaLabelRightButton } = props;\n\n const listRef = useRef<HTMLUListElement>(null);\n\n const tabRefs = useRef(React.Children.map(children, () => React.createRef<HTMLButtonElement>()) || []);\n useRovingFocus(onTabListClick, tabRefs, listRef, true);\n\n const tablistClasses = classNames(styles['tab-list'], styles[`tab-list--${onColor}`]);\n\n const getBackgroundColor = (onColor: TabsOnColor): string => {\n switch (onColor) {\n case 'onwhite':\n return 'var(--color-base-background-white)';\n case 'onblueberry':\n return 'var(--color-base-background-blueberry)';\n case 'onneutral':\n return 'var(--color-base-background-neutral)';\n }\n };\n const firstTab = tabRefs.current && tabRefs.current[0];\n const lastTab = tabRefs.current && tabRefs.current[tabRefs.current.length - 1];\n\n const firstTabVisible = useIsVisible(firstTab);\n const lastTabVisible = useIsVisible(lastTab);\n const tabListVisible = useIsVisible(listRef);\n\n const shouldShowFadeStart = (): boolean => {\n return !firstTabVisible;\n };\n\n const shouldShowFadeEnd = (): boolean => {\n return !lastTabVisible;\n };\n\n const scrollInList = (direction: string): void => {\n if (listRef.current) {\n const listWidth = listRef.current.clientWidth;\n const listScrollLeft = listRef.current.scrollLeft;\n const maxScrollLeft = listRef.current.scrollWidth - listWidth;\n\n if (direction === 'right' && !lastTabVisible) {\n const scrollAmount = Math.min(listWidth / 2, maxScrollLeft - listScrollLeft);\n listRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' });\n } else if (direction === 'left' && !firstTabVisible) {\n const scrollAmount = -Math.min(listWidth / 2, listScrollLeft);\n listRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' });\n }\n }\n };\n\n return (\n <div className={styles['tab-list-wrapper']}>\n {shouldShowFadeStart() && (\n <div className={classNames(styles['tab-list__start-wrapper'])}>\n <TabChevron\n onClick={() => scrollInList('left')}\n direction=\"left\"\n backgroundColor={`${getBackgroundColor(onColor)}`}\n ariaLabel={ariaLabelLeftButton}\n />\n <div\n className={classNames(styles['tab-list__fade-start'])}\n style={{\n backgroundColor: `${getBackgroundColor(onColor)}`,\n }}\n ></div>\n </div>\n )}\n <ul className={tablistClasses} ref={listRef} role=\"tablist\" aria-orientation=\"horizontal\">\n {React.Children.map(children, (child, index) => {\n if (isComponent<TabProps>(child, Tab)) {\n return (\n <TabItem\n tabRefs={tabRefs}\n tabListVisible={tabListVisible}\n key={child.props.title}\n index={index}\n selectedTab={selectedTab}\n onTabListClick={onTabListClick}\n tabProps={child.props}\n color={color}\n />\n );\n }\n return null;\n })}\n </ul>\n {shouldShowFadeEnd() && (\n <div className={classNames(styles['tab-list__end-wrapper'])}>\n <div\n className={classNames(styles['tab-list__fade-end'])}\n style={{\n backgroundColor: `${getBackgroundColor(onColor)}`,\n }}\n ></div>\n <TabChevron\n onClick={() => scrollInList('right')}\n direction=\"right\"\n backgroundColor={`${getBackgroundColor(onColor)}`}\n ariaLabel={ariaLabelRightButton}\n />\n </div>\n )}\n <div className={classNames(styles['tab-list__border'])}></div>\n </div>\n );\n};\n\nexport default TabList;\n"],"names":["currentRef","React","onColor"],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ export declare enum ExpanderSize {
|
|
|
8
8
|
}
|
|
9
9
|
export type ExpanderColors = Extract<PaletteNames, 'banana' | 'blueberry' | 'cherry' | 'kiwi' | 'neutral' | 'plum' | 'white'>;
|
|
10
10
|
export interface ExpanderProps {
|
|
11
|
+
buttonId?: string;
|
|
11
12
|
/** Sets the trigger title */
|
|
12
13
|
title: string;
|
|
13
14
|
/** Sets the expanded content */
|
|
@@ -2,6 +2,8 @@ import { default as React } from 'react';
|
|
|
2
2
|
import { FormOnColor, FormSize } from '../../constants';
|
|
3
3
|
export type FormGroupTags = 'fieldset' | 'div';
|
|
4
4
|
export interface FormGroupProps {
|
|
5
|
+
/** Can be used as a replacement text for legend in cases where the group title already exists externally */
|
|
6
|
+
ariaLabelledBy?: string;
|
|
5
7
|
/** title for the the fieldset */
|
|
6
8
|
title?: string;
|
|
7
9
|
/** text placed in the legend tag of the fieldset */
|
|
@@ -37,7 +37,7 @@ export interface NotificationPanelProps {
|
|
|
37
37
|
/** Custom id for the label */
|
|
38
38
|
labelId?: string;
|
|
39
39
|
/** Custom role for the panel. Default is no role. If variant is alert or crisis, the aria role will be set to "alert" unless the role-prop is also set. */
|
|
40
|
-
role?: 'region' | 'alert';
|
|
40
|
+
role?: 'region' | 'alert' | 'status';
|
|
41
41
|
/** Sets the data-testid attribute. */
|
|
42
42
|
testId?: string;
|
|
43
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/NotificationPanel/NotificationPanel.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, IconSize } from '../../constants';\nimport { useUuid } from '../../hooks/useUuid';\nimport { getColor } from '../../theme/currys';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport NotificationBadge from '../Badge/NotificationBadge';\nimport Close from '../Close';\nimport Expander from '../Expander';\n\nimport styles from './styles.module.scss';\n\nexport type NotificationPanelVariants = 'info' | 'warn' | 'error' | 'success';\nexport type NotificationCompactVariants = 'basic' | 'outline';\nexport type NotificationPanelSizes = 'small' | 'medium' | 'large';\nexport type LabelTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'span';\n\nexport interface NotificationPanelProps {\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds inner child elements. */\n children?: React.ReactNode;\n /** Adds inner expander elements. */\n expanderChildren?: React.ReactNode;\n /** Text for expanderButton. */\n expanderButtonText?: string;\n /** Text for expanderButton when closed. */\n expanderButtonClosedText?: string;\n /** Makes expander be open from start. */\n expanderOpenFromStart?: boolean;\n /** Changes the visual representation of the notification panel. */\n variant?: NotificationPanelVariants;\n /** Makes the panel more compact. Available in basic and outline. */\n compactVariant?: NotificationCompactVariants;\n /** Sets a fixed size for the content container. */\n size?: NotificationPanelSizes;\n /** Used in combination with dismissiable property to close the notification panel. */\n onClick?: (e?: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n /** Toggles the close button in the top right corner. */\n dismissable?: boolean;\n /** Enables a fluid outer container that spans the entire width of parent. */\n fluid?: boolean;\n /** Sets a label for the notification panel. */\n label?: string;\n /** Changes the underlying element of the label. */\n labelHtmlMarkup?: LabelTags;\n /** Close button aria-label */\n ariaLabelCloseBtn?: string;\n /** Custom id for the label */\n labelId?: string;\n /** Custom role for the panel. Default is no role. If variant is alert or crisis, the aria role will be set to \"alert\" unless the role-prop is also set. */\n role?: 'region' | 'alert';\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\ntype WrapFluidProps = Pick<NotificationPanelProps, 'fluid'> & {\n children: React.ReactElement;\n};\n\nconst FluidWrapper: React.FC<WrapFluidProps> = ({ fluid, children }) => {\n if (fluid) {\n const fluidClasses = classNames(styles['fluid-wrapper']);\n\n return <div className={fluidClasses}>{children}</div>;\n }\n return children;\n};\n\nconst NotificationPanel = React.forwardRef<HTMLDivElement, NotificationPanelProps>((props, ref) => {\n const {\n children,\n variant = 'info',\n dismissable = false,\n onClick,\n expanderChildren,\n expanderButtonText,\n expanderButtonClosedText,\n expanderOpenFromStart = false,\n compactVariant,\n label,\n labelHtmlMarkup = 'h1',\n fluid = false,\n size,\n className,\n labelId,\n role,\n testId,\n } = props;\n const uuid = useUuid(labelId);\n const renderContent = (): JSX.Element => {\n const outlineVariant = compactVariant === 'outline';\n const contentClasses = classNames(styles['notification-panel__content']);\n const labelClasses = classNames(styles['notification-panel__label'], {\n [styles['notification-panel__label--no-content']]: !children && !expanderChildren,\n [styles['notification-panel__label--compact']]: !!compactVariant,\n [styles['notification-panel__label--outline']]: outlineVariant,\n });\n const childrenClasses = classNames(styles['notification-panel__children'], {\n [styles['notification-panel__children--with-label']]: label,\n [styles['notification-panel__children--expander-no-label']]: expanderChildren && !label,\n [styles['notification-panel__children--outline']]: outlineVariant,\n });\n const CustomTag = labelHtmlMarkup;\n\n const [expanderOpen, setExpanderOpen] = React.useState(expanderOpenFromStart);\n return (\n <div className={contentClasses} id={!label ? uuid : undefined}>\n {label && (\n <CustomTag className={labelClasses} id={uuid}>\n {label}\n </CustomTag>\n )}\n {children && <div className={childrenClasses}>{children}</div>}\n {expanderChildren && expanderButtonText && expanderButtonClosedText && !compactVariant && (\n <Expander\n title={expanderOpen ? expanderButtonText : expanderButtonClosedText}\n onExpand={setExpanderOpen}\n expanded={expanderOpen}\n testId=\"expand\"\n >\n {expanderChildren}\n </Expander>\n )}\n </div>\n );\n };\n\n const notificationPanelClasses = classNames(\n styles['notification-panel'],\n styles[`notification-panel--${variant}`],\n size && styles[`notification-panel--${size}`],\n {\n [styles['notification-panel--compact']]: !!compactVariant,\n [styles['notification-panel--compact--basic']]: compactVariant === 'basic',\n [styles['notification-panel--compact--outline']]: compactVariant === 'outline',\n [styles['notification-panel--with-content']]: expanderChildren || (label && children),\n [styles['notification-panel--dismissable']]: dismissable,\n },\n className\n );\n\n const ariaRole = role || (variant === 'error' && 'alert') || undefined;\n const ariaLabelAttributes = ariaRole ? getAriaLabelAttributes({ label, id: uuid }) : undefined;\n\n return (\n <FluidWrapper fluid={fluid}>\n <div\n ref={ref}\n role={ariaRole}\n data-testid={testId}\n data-analyticsid={AnalyticsId.NotificationPanel}\n className={notificationPanelClasses}\n {...ariaLabelAttributes}\n >\n <NotificationBadge\n variant={variant}\n size={compactVariant ? IconSize.XSmall : IconSize.Small}\n className={styles['notification-panel__icon']}\n />\n {dismissable && (\n <span className={styles['notification-panel__close']}>\n <Close ariaLabel={props.ariaLabelCloseBtn} onClick={onClick} color={getColor('black')} />\n </span>\n )}\n {renderContent()}\n </div>\n </FluidWrapper>\n );\n});\n\nexport default NotificationPanel;\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/NotificationPanel/NotificationPanel.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, IconSize } from '../../constants';\nimport { useUuid } from '../../hooks/useUuid';\nimport { getColor } from '../../theme/currys';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport NotificationBadge from '../Badge/NotificationBadge';\nimport Close from '../Close';\nimport Expander from '../Expander';\n\nimport styles from './styles.module.scss';\n\nexport type NotificationPanelVariants = 'info' | 'warn' | 'error' | 'success';\nexport type NotificationCompactVariants = 'basic' | 'outline';\nexport type NotificationPanelSizes = 'small' | 'medium' | 'large';\nexport type LabelTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'span';\n\nexport interface NotificationPanelProps {\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds inner child elements. */\n children?: React.ReactNode;\n /** Adds inner expander elements. */\n expanderChildren?: React.ReactNode;\n /** Text for expanderButton. */\n expanderButtonText?: string;\n /** Text for expanderButton when closed. */\n expanderButtonClosedText?: string;\n /** Makes expander be open from start. */\n expanderOpenFromStart?: boolean;\n /** Changes the visual representation of the notification panel. */\n variant?: NotificationPanelVariants;\n /** Makes the panel more compact. Available in basic and outline. */\n compactVariant?: NotificationCompactVariants;\n /** Sets a fixed size for the content container. */\n size?: NotificationPanelSizes;\n /** Used in combination with dismissiable property to close the notification panel. */\n onClick?: (e?: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n /** Toggles the close button in the top right corner. */\n dismissable?: boolean;\n /** Enables a fluid outer container that spans the entire width of parent. */\n fluid?: boolean;\n /** Sets a label for the notification panel. */\n label?: string;\n /** Changes the underlying element of the label. */\n labelHtmlMarkup?: LabelTags;\n /** Close button aria-label */\n ariaLabelCloseBtn?: string;\n /** Custom id for the label */\n labelId?: string;\n /** Custom role for the panel. Default is no role. If variant is alert or crisis, the aria role will be set to \"alert\" unless the role-prop is also set. */\n role?: 'region' | 'alert' | 'status';\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\ntype WrapFluidProps = Pick<NotificationPanelProps, 'fluid'> & {\n children: React.ReactElement;\n};\n\nconst FluidWrapper: React.FC<WrapFluidProps> = ({ fluid, children }) => {\n if (fluid) {\n const fluidClasses = classNames(styles['fluid-wrapper']);\n\n return <div className={fluidClasses}>{children}</div>;\n }\n return children;\n};\n\nconst NotificationPanel = React.forwardRef<HTMLDivElement, NotificationPanelProps>((props, ref) => {\n const {\n children,\n variant = 'info',\n dismissable = false,\n onClick,\n expanderChildren,\n expanderButtonText,\n expanderButtonClosedText,\n expanderOpenFromStart = false,\n compactVariant,\n label,\n labelHtmlMarkup = 'h1',\n fluid = false,\n size,\n className,\n labelId,\n role,\n testId,\n } = props;\n const uuid = useUuid(labelId);\n const renderContent = (): JSX.Element => {\n const outlineVariant = compactVariant === 'outline';\n const contentClasses = classNames(styles['notification-panel__content']);\n const labelClasses = classNames(styles['notification-panel__label'], {\n [styles['notification-panel__label--no-content']]: !children && !expanderChildren,\n [styles['notification-panel__label--compact']]: !!compactVariant,\n [styles['notification-panel__label--outline']]: outlineVariant,\n });\n const childrenClasses = classNames(styles['notification-panel__children'], {\n [styles['notification-panel__children--with-label']]: label,\n [styles['notification-panel__children--expander-no-label']]: expanderChildren && !label,\n [styles['notification-panel__children--outline']]: outlineVariant,\n });\n const CustomTag = labelHtmlMarkup;\n\n const [expanderOpen, setExpanderOpen] = React.useState(expanderOpenFromStart);\n return (\n <div className={contentClasses} id={!label ? uuid : undefined}>\n {label && (\n <CustomTag className={labelClasses} id={uuid}>\n {label}\n </CustomTag>\n )}\n {children && <div className={childrenClasses}>{children}</div>}\n {expanderChildren && expanderButtonText && expanderButtonClosedText && !compactVariant && (\n <Expander\n title={expanderOpen ? expanderButtonText : expanderButtonClosedText}\n onExpand={setExpanderOpen}\n expanded={expanderOpen}\n testId=\"expand\"\n >\n {expanderChildren}\n </Expander>\n )}\n </div>\n );\n };\n\n const notificationPanelClasses = classNames(\n styles['notification-panel'],\n styles[`notification-panel--${variant}`],\n size && styles[`notification-panel--${size}`],\n {\n [styles['notification-panel--compact']]: !!compactVariant,\n [styles['notification-panel--compact--basic']]: compactVariant === 'basic',\n [styles['notification-panel--compact--outline']]: compactVariant === 'outline',\n [styles['notification-panel--with-content']]: expanderChildren || (label && children),\n [styles['notification-panel--dismissable']]: dismissable,\n },\n className\n );\n\n const ariaRole = role || (variant === 'error' && 'alert') || undefined;\n const ariaLabelAttributes = ariaRole ? getAriaLabelAttributes({ label, id: uuid }) : undefined;\n\n return (\n <FluidWrapper fluid={fluid}>\n <div\n ref={ref}\n role={ariaRole}\n data-testid={testId}\n data-analyticsid={AnalyticsId.NotificationPanel}\n className={notificationPanelClasses}\n {...ariaLabelAttributes}\n >\n <NotificationBadge\n variant={variant}\n size={compactVariant ? IconSize.XSmall : IconSize.Small}\n className={styles['notification-panel__icon']}\n />\n {dismissable && (\n <span className={styles['notification-panel__close']}>\n <Close ariaLabel={props.ariaLabelCloseBtn} onClick={onClick} color={getColor('black')} />\n </span>\n )}\n {renderContent()}\n </div>\n </FluidWrapper>\n );\n});\n\nexport default NotificationPanel;\n"],"names":["React"],"mappings":"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"}
|
|
@@ -31,6 +31,8 @@ export interface PanelProps {
|
|
|
31
31
|
buttonBottomText?: string;
|
|
32
32
|
/** Sets the action on the bottom call to action button */
|
|
33
33
|
buttonBottomOnClick?: () => void;
|
|
34
|
+
/** Expands or collapses the panel. Only applicable when ExpandedContent is used */
|
|
35
|
+
expanded?: boolean;
|
|
34
36
|
/** Sets the layout and order of the content boxes */
|
|
35
37
|
layout?: PanelLayout;
|
|
36
38
|
/** Sets the visual variant of panel */
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
@use '../../../scss/breakpoints' as breakpoints;
|
|
3
3
|
@import '../../../scss/supernova/styles/colors';
|
|
4
4
|
|
|
5
|
+
.tab-list-wrapper {
|
|
6
|
+
position: relative;
|
|
7
|
+
}
|
|
8
|
+
|
|
5
9
|
.tab-list {
|
|
6
10
|
$tab-list: &;
|
|
7
11
|
$colors: 'blueberry', 'neutral', 'white';
|
|
@@ -68,14 +72,16 @@
|
|
|
68
72
|
border-bottom: 0;
|
|
69
73
|
border-radius: 0.5rem 0.5rem 0 0;
|
|
70
74
|
position: relative;
|
|
75
|
+
|
|
76
|
+
// Z-index brukes til å flytte tab bak/foran bottom border til tab-list__border
|
|
71
77
|
z-index: 0;
|
|
72
78
|
|
|
73
79
|
&--selected {
|
|
74
80
|
overflow: visible;
|
|
75
|
-
z-index: 1;
|
|
76
81
|
border-color: var(--color-action-border-onlight-focus);
|
|
77
82
|
color: var(--color-base-text-onlight);
|
|
78
83
|
background-color: var(--color-base-background-white);
|
|
84
|
+
z-index: 2;
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
&__title-and-icon {
|
|
@@ -152,8 +158,12 @@
|
|
|
152
158
|
}
|
|
153
159
|
|
|
154
160
|
&__border {
|
|
155
|
-
position:
|
|
156
|
-
|
|
157
|
-
|
|
161
|
+
position: absolute;
|
|
162
|
+
z-index: 1;
|
|
163
|
+
pointer-events: none;
|
|
164
|
+
top: 0;
|
|
165
|
+
width: 100%;
|
|
166
|
+
height: 100%;
|
|
167
|
+
border-bottom: 1px solid var(--color-action-border-onlight-focus);
|
|
158
168
|
}
|
|
159
169
|
}
|
|
@@ -22,9 +22,11 @@
|
|
|
22
22
|
height: 50px;
|
|
23
23
|
|
|
24
24
|
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
25
|
-
border-right: 1px solid var(--color-action-border-onlight-focus);
|
|
26
|
-
border-left: 1px solid var(--color-action-border-onlight-focus);
|
|
27
25
|
height: 50px;
|
|
26
|
+
|
|
27
|
+
/* Disse to linjene passer på at den hvite gradienten ikke går over border til den ytre diven */
|
|
28
|
+
width: auto;
|
|
29
|
+
margin: 0 2px;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
@each $color in $colors {
|