@helsenorge/designsystem-react 11.2.0-beta.0 → 11.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/Button.js +6 -8
- package/Button.js.map +1 -1
- package/CHANGELOG.md +64 -16
- package/Close.js +21 -6
- package/Close.js.map +1 -1
- package/Drawer.js +362 -0
- package/Drawer.js.map +1 -0
- package/HelpBubble.js +78 -0
- package/HelpBubble.js.map +1 -0
- package/InfoTeaser.js +75 -0
- package/InfoTeaser.js.map +1 -0
- package/LazyIcon.js +1 -1
- package/LazyIcon.js.map +1 -1
- package/LazyIllustration.js +1 -1
- package/LazyIllustration.js.map +1 -1
- package/Panel.js +38 -5
- package/Panel.js.map +1 -1
- package/PopOver.js +141 -3589
- package/PopOver.js.map +1 -1
- package/components/ArticleTeaser/ArticleTeaser.d.ts +23 -0
- package/components/ArticleTeaser/ArticleTeaser.test.d.ts +1 -0
- package/components/ArticleTeaser/index.d.ts +3 -0
- package/components/ArticleTeaser/index.js +67 -0
- package/components/ArticleTeaser/index.js.map +1 -0
- package/components/ArticleTeaser/resourceHelper.d.ts +3 -0
- package/components/ArticleTeaser/styles.module.scss +79 -0
- package/components/ArticleTeaser/styles.module.scss.d.ts +13 -0
- package/components/Close/Close.d.ts +1 -1
- package/components/Close/styles.module.scss +46 -20
- package/components/Close/styles.module.scss.d.ts +2 -0
- package/components/Drawer/Drawer.d.ts +6 -0
- package/components/Drawer/index.js +1 -348
- package/components/Drawer/index.js.map +1 -1
- package/components/Drawer/styles.module.scss +4 -0
- package/components/Drawer/styles.module.scss.d.ts +1 -0
- package/components/Dropdown/index.js +1 -3
- package/components/Dropdown/index.js.map +1 -1
- package/components/HelpBubble/HelpBubble.d.ts +9 -7
- package/components/HelpBubble/index.js +3 -47
- package/components/HelpBubble/index.js.map +1 -1
- package/components/HelpBubble/styles.module.scss +7 -5
- package/components/HelpBubble/styles.module.scss.d.ts +1 -0
- package/components/HelpDrawer/HelpDrawer.d.ts +8 -0
- package/components/HelpDrawer/HelpDrawer.test.d.ts +1 -0
- package/components/HelpDrawer/index.d.ts +3 -0
- package/components/HelpDrawer/index.js +10 -0
- package/components/HelpDrawer/index.js.map +1 -0
- package/components/HelpDrawer/styles.module.scss +16 -0
- package/components/HelpDrawer/styles.module.scss.d.ts +10 -0
- package/components/HelpPanel/styles.module.scss +2 -3
- package/components/HelpTeaser/HelpTeaser.d.ts +20 -0
- package/components/HelpTeaser/HelpTeaser.test.d.ts +1 -0
- package/components/HelpTeaser/index.d.ts +3 -0
- package/components/HelpTeaser/index.js +25 -0
- package/components/HelpTeaser/index.js.map +1 -0
- package/components/HelpTeaser/styles.module.scss +22 -0
- package/components/HelpTeaser/styles.module.scss.d.ts +10 -0
- package/components/HelpTooltip/index.js +2 -2
- package/components/HelpTooltip/index.js.map +1 -1
- package/components/HighlightPanel/styles.module.scss +0 -1
- package/components/Icons/AdditionalIconInformation.d.ts +1 -1
- package/components/Icons/AdditionalIconInformation.js +1 -1
- package/components/Icons/AdditionalIconInformation.js.map +1 -1
- package/components/Icons/IconNames.d.ts +1 -1
- package/components/Icons/IconNames.js +1 -0
- package/components/Icons/IconNames.js.map +1 -1
- package/components/Icons/Toddler.d.ts +4 -0
- package/components/Icons/Toddler.js +10 -0
- package/components/Icons/Toddler.js.map +1 -0
- package/components/Illustrations/BabyMobile.d.ts +8 -0
- package/components/Illustrations/BabyMobile.js +11 -0
- package/components/Illustrations/BabyMobile.js.map +1 -0
- package/components/Illustrations/BabyMobileMedium.d.ts +4 -0
- package/components/Illustrations/BabyMobileMedium.js +424 -0
- package/components/Illustrations/BabyMobileMedium.js.map +1 -0
- package/components/Illustrations/Child.d.ts +12 -0
- package/components/Illustrations/Child.js +11 -0
- package/components/Illustrations/Child.js.map +1 -0
- package/components/Illustrations/ChildMedium.d.ts +4 -0
- package/components/Illustrations/ChildMedium.js +185 -0
- package/components/Illustrations/ChildMedium.js.map +1 -0
- package/components/Illustrations/GiveBabyFood.d.ts +11 -0
- package/components/Illustrations/GiveBabyFood.js +11 -0
- package/components/Illustrations/GiveBabyFood.js.map +1 -0
- package/components/Illustrations/GiveBabyFoodMedium.d.ts +4 -0
- package/components/Illustrations/GiveBabyFoodMedium.js +377 -0
- package/components/Illustrations/GiveBabyFoodMedium.js.map +1 -0
- package/components/Illustrations/IllustrationNames.d.ts +1 -1
- package/components/Illustrations/IllustrationNames.js +15 -1
- package/components/Illustrations/IllustrationNames.js.map +1 -1
- package/components/Illustrations/Stroller.d.ts +12 -0
- package/components/Illustrations/Stroller.js +11 -0
- package/components/Illustrations/Stroller.js.map +1 -0
- package/components/Illustrations/StrollerMedium.d.ts +4 -0
- package/components/Illustrations/StrollerMedium.js +236 -0
- package/components/Illustrations/StrollerMedium.js.map +1 -0
- package/components/InfoTeaser/InfoTeaser.d.ts +28 -0
- package/components/InfoTeaser/InfoTeaser.test.d.ts +1 -0
- package/components/InfoTeaser/index.d.ts +3 -0
- package/components/InfoTeaser/index.js +5 -0
- package/components/InfoTeaser/index.js.map +1 -0
- package/components/InfoTeaser/resourceHelper.d.ts +3 -0
- package/components/InfoTeaser/styles.module.scss +98 -0
- package/components/InfoTeaser/styles.module.scss.d.ts +15 -0
- package/components/Panel/Panel.d.ts +3 -0
- package/components/Panel/resourceHelper.d.ts +3 -0
- package/components/Panel/styles.module.scss +6 -6
- package/components/PopMenu/index.js +24 -15
- package/components/PopMenu/index.js.map +1 -1
- package/components/PopMenu/styles.module.scss +10 -9
- package/components/PopMenu/styles.module.scss.d.ts +1 -0
- package/components/PopOver/PopOver.d.ts +5 -9
- package/components/PopOver/index.js +3 -3
- package/components/PopOver/styles.module.scss +53 -11
- package/components/PopOver/styles.module.scss.d.ts +5 -0
- package/constants.d.ts +2 -0
- package/constants.js +2 -0
- package/constants.js.map +1 -1
- package/designsystem-react.css +3 -1
- package/hooks/useBreakpoint.js +10 -28
- package/hooks/useBreakpoint.js.map +1 -1
- package/hooks/useIsMobileBreakpoint.d.ts +1 -0
- package/hooks/useIsMobileBreakpoint.js +10 -0
- package/hooks/useIsMobileBreakpoint.js.map +1 -0
- package/package.json +1 -1
- package/resources/HN.Designsystem.ArticleTeaser.en-GB.json.d.ts +7 -0
- package/resources/HN.Designsystem.ArticleTeaser.nb-NO.json.d.ts +7 -0
- package/resources/HN.Designsystem.Dropdown.nb-NO.json.d.ts +1 -2
- package/resources/HN.Designsystem.InfoTeaser.en-GB.json.d.ts +7 -0
- package/resources/HN.Designsystem.InfoTeaser.nb-NO.json.d.ts +7 -0
- package/resources/HN.Designsystem.Panel.en-GB.json.d.ts +7 -0
- package/resources/HN.Designsystem.Panel.nb-NO.json.d.ts +7 -0
- package/scss/_font-mixins.scss +0 -22
- package/scss/supernova/styles/colors.css +3 -1
- package/scss/typography.module.scss +0 -8
- package/scss/typography.module.scss.d.ts +0 -2
- package/scss/typography.stories.tsx +0 -8
package/Button.js
CHANGED
|
@@ -3,11 +3,10 @@ import React__default, { useRef, useEffect } from "react";
|
|
|
3
3
|
import classNames from "classnames";
|
|
4
4
|
import { I as Icon } from "./Icon.js";
|
|
5
5
|
import { AnalyticsId, IconSize } from "./constants.js";
|
|
6
|
-
import { useBreakpoint } from "./hooks/useBreakpoint.js";
|
|
7
6
|
import { useHover } from "./hooks/useHover.js";
|
|
8
7
|
import { useIcons } from "./hooks/useIcons.js";
|
|
8
|
+
import { useIsMobileBreakpoint } from "./hooks/useIsMobileBreakpoint.js";
|
|
9
9
|
import { getColor } from "./theme/currys/color.js";
|
|
10
|
-
import { breakpoints } from "./theme/grid.js";
|
|
11
10
|
import { isTest, isProd } from "./utils/environment.js";
|
|
12
11
|
import ArrowRight from "./components/Icons/ArrowRight.js";
|
|
13
12
|
import buttonStyles from "./components/Button/styles.module.scss";
|
|
@@ -66,12 +65,11 @@ const Button = React__default.forwardRef(function ButtonForwardedRef(props, ref)
|
|
|
66
65
|
const onlyIcon = !!(leftIcon || rightIcon) && !restChildren;
|
|
67
66
|
const bothIcons = leftIcon && (rightIcon || arrow) && !onlyIcon;
|
|
68
67
|
const onDark = onColor === "ondark";
|
|
69
|
-
const
|
|
70
|
-
const mobile = breakpoint < breakpoints.md;
|
|
68
|
+
const isMobile = useIsMobileBreakpoint();
|
|
71
69
|
const destructive = concept === "destructive" && !disabled;
|
|
72
70
|
const outlineVariant = variant === "outline";
|
|
73
71
|
const borderlessVariant = variant === "borderless";
|
|
74
|
-
const iconColor = getIconColor(variant === "fill", borderlessVariant, disabled, concept, onDark,
|
|
72
|
+
const iconColor = getIconColor(variant === "fill", borderlessVariant, disabled, concept, onDark, isMobile);
|
|
75
73
|
const hasArrow = arrow === "icon" && !borderlessVariant;
|
|
76
74
|
const large = size === "large" && !destructive && !borderlessVariant;
|
|
77
75
|
const hasUURightArrow = arrow === "accessibility-character" && !fluid && !leftIcon && !rightIcon && !hasArrow && borderlessVariant;
|
|
@@ -127,13 +125,13 @@ const Button = React__default.forwardRef(function ButtonForwardedRef(props, ref)
|
|
|
127
125
|
] });
|
|
128
126
|
};
|
|
129
127
|
const renderbuttonContentWrapper = () => /* @__PURE__ */ jsxs("span", { className: buttonClasses, children: [
|
|
130
|
-
renderIcon(leftIcon, getLargeIconSize(large,
|
|
128
|
+
renderIcon(leftIcon, getLargeIconSize(large, isMobile), !onlyIcon ? buttonStyles["button__left-icon"] : void 0),
|
|
131
129
|
renderButtonContent(),
|
|
132
130
|
hasArrow ? renderIcon(
|
|
133
131
|
/* @__PURE__ */ jsx(Icon, { svgIcon: ArrowRight }),
|
|
134
|
-
getLargeIconSize(large,
|
|
132
|
+
getLargeIconSize(large, isMobile),
|
|
135
133
|
classNames(buttonStyles["button__arrow"], { [buttonStyles["button__arrow--both-icons"]]: bothIcons })
|
|
136
|
-
) : renderIcon(rightIcon, getLargeIconSize(large,
|
|
134
|
+
) : renderIcon(rightIcon, getLargeIconSize(large, isMobile), buttonStyles["button__right-icon"]),
|
|
137
135
|
hasUURightArrow && /* @__PURE__ */ jsx("span", { style: { color: iconColor }, className: buttonStyles["button__right-unicode-arrow"], "aria-hidden": true, children: " →" })
|
|
138
136
|
] });
|
|
139
137
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
package/Button.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.js","sources":["../src/components/Button/Button.tsx"],"sourcesContent":["import React, { AriaAttributes, useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport Icon, { IconSize } from './../Icon';\nimport { HTMLButtonProps, HTMLAnchorProps, AnalyticsId } from '../../constants';\nimport { useBreakpoint } from '../../hooks/useBreakpoint';\nimport { useHover } from '../../hooks/useHover';\nimport { BaseIconElement, useIcons } from '../../hooks/useIcons';\nimport { getColor } from '../../theme/currys/color';\nimport { breakpoints } from '../../theme/grid';\nimport { isTest, isProd } from '../../utils/environment';\nimport ArrowRight from '../Icons/ArrowRight';\n\nimport buttonStyles from './styles.module.scss';\n\nexport type ButtonConcept = 'normal' | 'destructive';\nexport type ButtonVariant = 'fill' | 'outline' | 'borderless';\nexport type ButtonSize = 'medium' | 'large';\nexport type ButtonOnColor = 'onlight' | 'ondark';\nexport type ButtonTags = 'button' | 'a';\nexport type ButtonArrows = 'icon' | 'accessibility-character';\nexport type ButtonTextPosition = 'left' | 'centered';\n\nexport interface ButtonProps extends HTMLButtonProps, HTMLAnchorProps, AriaAttributes {\n /** Sets the aria-label of the button, use when the button only includes an icon */\n ariaLabel?: string;\n /** Gives a unique id to the button */\n id?: string;\n /** Sets the content of the button. */\n children: React.ReactNode;\n /** Adds custom classes to the wrapper element. */\n wrapperClassName?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Enables an arrow icon to the right inside the button (Not available in borderless variant) */\n arrow?: ButtonArrows;\n /** Changes the intent of the button. Mostly changes the color profile. */\n concept?: ButtonConcept;\n /** Disables text wrapping and enables ellipsis. */\n ellipsis?: boolean;\n /** Makes the button scale to full width of its parent element. */\n fluid?: boolean;\n /** Changes the underlying element of the button. */\n htmlMarkup?: ButtonTags;\n /** Changes the button colors for different backgrounds. */\n onColor?: ButtonOnColor;\n /** Function that is called when the Button loses focus */\n onBlur?: () => void;\n /** Function that is called when clicked */\n onClick?: (e?: React.MouseEvent<HTMLElement, MouseEvent> | React.FormEvent<{}> | React.KeyboardEvent<HTMLUListElement> | null) => void;\n /** Changes the button colors for different backgrounds. (Large not available in borderless variant) */\n size?: ButtonSize;\n /** Changes the visual representation of the button. */\n variant?: ButtonVariant;\n /** Specifies the focus order relative to the other buttons or controls on the page */\n tabIndex?: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Adds custom classes to the text */\n textClassName?: string;\n /** Sets the position of the text in the button - only applies when button is fluid */\n textPosition?: ButtonTextPosition;\n /** Button type. Default: button */\n type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];\n}\n\nconst getIconColor = (\n fill: boolean,\n borderless: boolean,\n disabled: boolean,\n concept: ButtonConcept,\n ondark: boolean,\n mobile: boolean\n): string => {\n if (mobile && disabled) {\n return !ondark || fill ? getColor('neutral', !borderless ? 700 : 500) : getColor('white');\n }\n if (disabled) {\n return !ondark || fill ? getColor('neutral', 500) : `${getColor('white')}b3`;\n }\n if ((fill && !ondark) || (!fill && ondark)) {\n return 'white';\n }\n\n return concept === 'normal' ? getColor('blueberry', 600) : getColor('cherry', 500);\n};\nconst getLargeIconSize = (large: boolean, mobile: boolean): IconSize => {\n if (mobile && large) return IconSize.Small;\n if (large) return IconSize.Medium;\n return IconSize.XSmall;\n};\n\nconst checkOnlyIconAria = (onlyIcon: boolean, ariaLabel: string | undefined, devEnv: boolean): void => {\n if (devEnv && onlyIcon && (ariaLabel === undefined || ariaLabel === '')) {\n throw new Error('Fyll inn ariaLabel prop på Button uten tekst for å opprettholde UU krav');\n }\n};\n\nconst Button = React.forwardRef(function ButtonForwardedRef(\n props: ButtonProps,\n ref: React.ForwardedRef<HTMLButtonElement | HTMLAnchorElement>\n) {\n const {\n ariaLabel,\n id,\n children,\n wrapperClassName,\n className,\n arrow,\n concept = 'normal',\n disabled = false,\n ellipsis = false,\n fluid = false,\n htmlMarkup = 'button',\n onColor = 'onlight',\n onBlur,\n onClick,\n size = 'medium',\n variant = 'fill',\n href,\n tabIndex,\n testId,\n target,\n type = 'button',\n textClassName,\n textPosition = 'left',\n ...restProps\n } = props;\n\n const [leftIcon, rightIcon, restChildren] = useIcons(React.Children.toArray(children));\n const { hoverRef, isHovered } =\n htmlMarkup === 'button'\n ? useHover<HTMLButtonElement>(ref as React.RefObject<HTMLButtonElement>)\n : useHover<HTMLAnchorElement>(ref as React.RefObject<HTMLAnchorElement>);\n const buttonContentRef = useRef<HTMLDivElement>(null);\n const onlyIcon = !!(leftIcon || rightIcon) && !restChildren;\n const bothIcons = leftIcon && (rightIcon || arrow) && !onlyIcon;\n const onDark = onColor === 'ondark';\n const breakpoint = useBreakpoint();\n const mobile = breakpoint < breakpoints.md;\n const destructive = concept === 'destructive' && !disabled;\n const outlineVariant = variant === 'outline';\n const borderlessVariant = variant === 'borderless';\n const iconColor = getIconColor(variant === 'fill', borderlessVariant, disabled, concept, onDark, mobile);\n const hasArrow = arrow === 'icon' && !borderlessVariant;\n const large = size === 'large' && !destructive && !borderlessVariant;\n const hasUURightArrow = arrow === 'accessibility-character' && !fluid && !leftIcon && !rightIcon && !hasArrow && borderlessVariant;\n const rest = { ...restProps };\n\n const buttonWrapperClasses = classNames(\n buttonStyles['button-wrapper'],\n { [buttonStyles['button-wrapper--fluid']]: fluid || ellipsis },\n wrapperClassName\n );\n const buttonClasses = classNames(\n buttonStyles.button,\n {\n [buttonStyles['button--destructive']]: destructive,\n [buttonStyles['button--normal']]: !large,\n [buttonStyles['button--large']]: large,\n [buttonStyles['button--outline']]: outlineVariant,\n [buttonStyles['button--borderless']]: borderlessVariant,\n [buttonStyles['button--left-icon']]: leftIcon && !onlyIcon,\n [buttonStyles['button--right-icon']]: rightIcon && !onlyIcon,\n [buttonStyles['button--both-icons']]: bothIcons,\n [buttonStyles['button--only-icon']]: onlyIcon,\n [buttonStyles['button--arrow']]: hasArrow,\n [buttonStyles['button--on-dark']]: onDark,\n },\n className\n );\n const buttonTextClasses = classNames(\n buttonStyles['button__text'],\n {\n [buttonStyles['button__text--ellipsis']]: ellipsis,\n [buttonStyles['button__text--centered']]: fluid && textPosition === 'centered',\n },\n textClassName\n );\n const diagonalClasses = classNames(buttonStyles['diagonal'], {\n [buttonStyles['diagonal--on-dark']]: onDark,\n });\n\n useEffect(() => {\n checkOnlyIconAria(onlyIcon, ariaLabel, !isTest() && !isProd());\n }, []);\n\n const renderIcon = (iconElement: BaseIconElement | null, iconSize: number, iconClassName?: string): BaseIconElement | null => {\n return iconElement\n ? React.cloneElement(iconElement, {\n size: iconSize,\n color: iconElement?.props.color && !disabled ? iconElement.props.color : iconColor,\n isHovered: iconElement.props.isHovered === undefined ? !disabled && isHovered : iconElement.props.isHovered,\n className: iconClassName,\n })\n : null;\n };\n\n const renderButtonContent = (): JSX.Element => {\n return (\n <span className={buttonTextClasses} ref={buttonContentRef}>\n {disabled && borderlessVariant && (\n <span className={diagonalClasses}>\n <span className={buttonStyles['diagonal__line']} />\n </span>\n )}\n <span>{onlyIcon ? ariaLabel : restChildren}</span>\n </span>\n );\n };\n\n const renderbuttonContentWrapper = (): JSX.Element => (\n <span className={buttonClasses}>\n {renderIcon(leftIcon, getLargeIconSize(large, mobile), !onlyIcon ? buttonStyles['button__left-icon'] : undefined)}\n {renderButtonContent()}\n {hasArrow\n ? renderIcon(\n <Icon svgIcon={ArrowRight} />,\n getLargeIconSize(large, mobile),\n classNames(buttonStyles['button__arrow'], { [buttonStyles['button__arrow--both-icons']]: bothIcons })\n )\n : renderIcon(rightIcon, getLargeIconSize(large, mobile), buttonStyles['button__right-icon'])}\n {hasUURightArrow && (\n <span style={{ color: iconColor }} className={buttonStyles['button__right-unicode-arrow']} aria-hidden>\n {' →'}\n </span>\n )}\n </span>\n );\n\n return (\n <>\n {htmlMarkup === 'button' && (\n <button\n id={id}\n onBlur={onBlur}\n onClick={onClick}\n disabled={disabled}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Button}\n className={buttonWrapperClasses}\n ref={hoverRef as React.ForwardedRef<HTMLButtonElement>}\n tabIndex={tabIndex}\n type={type}\n {...rest}\n >\n {renderbuttonContentWrapper()}\n </button>\n )}\n {htmlMarkup === 'a' && (\n <a\n id={id}\n onBlur={onBlur}\n onClick={onClick}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Button}\n className={buttonWrapperClasses}\n href={href}\n target={target}\n rel={target === '_blank' ? 'noopener noreferrer' : props.rel}\n ref={hoverRef as React.ForwardedRef<HTMLAnchorElement>}\n tabIndex={tabIndex}\n {...restProps}\n >\n {renderbuttonContentWrapper()}\n </a>\n )}\n </>\n );\n});\n\nexport default Button;\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Button.js","sources":["../src/components/Button/Button.tsx"],"sourcesContent":["import React, { AriaAttributes, useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport Icon, { IconSize } from './../Icon';\nimport { HTMLButtonProps, HTMLAnchorProps, AnalyticsId } from '../../constants';\nimport { useHover } from '../../hooks/useHover';\nimport { BaseIconElement, useIcons } from '../../hooks/useIcons';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { getColor } from '../../theme/currys/color';\nimport { isTest, isProd } from '../../utils/environment';\nimport ArrowRight from '../Icons/ArrowRight';\n\nimport buttonStyles from './styles.module.scss';\n\nexport type ButtonConcept = 'normal' | 'destructive';\nexport type ButtonVariant = 'fill' | 'outline' | 'borderless';\nexport type ButtonSize = 'medium' | 'large';\nexport type ButtonOnColor = 'onlight' | 'ondark';\nexport type ButtonTags = 'button' | 'a';\nexport type ButtonArrows = 'icon' | 'accessibility-character';\nexport type ButtonTextPosition = 'left' | 'centered';\n\nexport interface ButtonProps extends HTMLButtonProps, HTMLAnchorProps, AriaAttributes {\n /** Sets the aria-label of the button, use when the button only includes an icon */\n ariaLabel?: string;\n /** Gives a unique id to the button */\n id?: string;\n /** Sets the content of the button. */\n children: React.ReactNode;\n /** Adds custom classes to the wrapper element. */\n wrapperClassName?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Enables an arrow icon to the right inside the button (Not available in borderless variant) */\n arrow?: ButtonArrows;\n /** Changes the intent of the button. Mostly changes the color profile. */\n concept?: ButtonConcept;\n /** Disables text wrapping and enables ellipsis. */\n ellipsis?: boolean;\n /** Makes the button scale to full width of its parent element. */\n fluid?: boolean;\n /** Changes the underlying element of the button. */\n htmlMarkup?: ButtonTags;\n /** Changes the button colors for different backgrounds. */\n onColor?: ButtonOnColor;\n /** Function that is called when the Button loses focus */\n onBlur?: () => void;\n /** Function that is called when clicked */\n onClick?: (e?: React.MouseEvent<HTMLElement, MouseEvent> | React.FormEvent<{}> | React.KeyboardEvent<HTMLUListElement> | null) => void;\n /** Changes the button colors for different backgrounds. (Large not available in borderless variant) */\n size?: ButtonSize;\n /** Changes the visual representation of the button. */\n variant?: ButtonVariant;\n /** Specifies the focus order relative to the other buttons or controls on the page */\n tabIndex?: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Adds custom classes to the text */\n textClassName?: string;\n /** Sets the position of the text in the button - only applies when button is fluid */\n textPosition?: ButtonTextPosition;\n /** Button type. Default: button */\n type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];\n}\n\nconst getIconColor = (\n fill: boolean,\n borderless: boolean,\n disabled: boolean,\n concept: ButtonConcept,\n ondark: boolean,\n mobile: boolean\n): string => {\n if (mobile && disabled) {\n return !ondark || fill ? getColor('neutral', !borderless ? 700 : 500) : getColor('white');\n }\n if (disabled) {\n return !ondark || fill ? getColor('neutral', 500) : `${getColor('white')}b3`;\n }\n if ((fill && !ondark) || (!fill && ondark)) {\n return 'white';\n }\n\n return concept === 'normal' ? getColor('blueberry', 600) : getColor('cherry', 500);\n};\nconst getLargeIconSize = (large: boolean, mobile: boolean): IconSize => {\n if (mobile && large) return IconSize.Small;\n if (large) return IconSize.Medium;\n return IconSize.XSmall;\n};\n\nconst checkOnlyIconAria = (onlyIcon: boolean, ariaLabel: string | undefined, devEnv: boolean): void => {\n if (devEnv && onlyIcon && (ariaLabel === undefined || ariaLabel === '')) {\n throw new Error('Fyll inn ariaLabel prop på Button uten tekst for å opprettholde UU krav');\n }\n};\n\nconst Button = React.forwardRef(function ButtonForwardedRef(\n props: ButtonProps,\n ref: React.ForwardedRef<HTMLButtonElement | HTMLAnchorElement>\n) {\n const {\n ariaLabel,\n id,\n children,\n wrapperClassName,\n className,\n arrow,\n concept = 'normal',\n disabled = false,\n ellipsis = false,\n fluid = false,\n htmlMarkup = 'button',\n onColor = 'onlight',\n onBlur,\n onClick,\n size = 'medium',\n variant = 'fill',\n href,\n tabIndex,\n testId,\n target,\n type = 'button',\n textClassName,\n textPosition = 'left',\n ...restProps\n } = props;\n\n const [leftIcon, rightIcon, restChildren] = useIcons(React.Children.toArray(children));\n const { hoverRef, isHovered } =\n htmlMarkup === 'button'\n ? useHover<HTMLButtonElement>(ref as React.RefObject<HTMLButtonElement>)\n : useHover<HTMLAnchorElement>(ref as React.RefObject<HTMLAnchorElement>);\n const buttonContentRef = useRef<HTMLDivElement>(null);\n const onlyIcon = !!(leftIcon || rightIcon) && !restChildren;\n const bothIcons = leftIcon && (rightIcon || arrow) && !onlyIcon;\n const onDark = onColor === 'ondark';\n const isMobile = useIsMobileBreakpoint();\n const destructive = concept === 'destructive' && !disabled;\n const outlineVariant = variant === 'outline';\n const borderlessVariant = variant === 'borderless';\n const iconColor = getIconColor(variant === 'fill', borderlessVariant, disabled, concept, onDark, isMobile);\n const hasArrow = arrow === 'icon' && !borderlessVariant;\n const large = size === 'large' && !destructive && !borderlessVariant;\n const hasUURightArrow = arrow === 'accessibility-character' && !fluid && !leftIcon && !rightIcon && !hasArrow && borderlessVariant;\n const rest = { ...restProps };\n\n const buttonWrapperClasses = classNames(\n buttonStyles['button-wrapper'],\n { [buttonStyles['button-wrapper--fluid']]: fluid || ellipsis },\n wrapperClassName\n );\n const buttonClasses = classNames(\n buttonStyles.button,\n {\n [buttonStyles['button--destructive']]: destructive,\n [buttonStyles['button--normal']]: !large,\n [buttonStyles['button--large']]: large,\n [buttonStyles['button--outline']]: outlineVariant,\n [buttonStyles['button--borderless']]: borderlessVariant,\n [buttonStyles['button--left-icon']]: leftIcon && !onlyIcon,\n [buttonStyles['button--right-icon']]: rightIcon && !onlyIcon,\n [buttonStyles['button--both-icons']]: bothIcons,\n [buttonStyles['button--only-icon']]: onlyIcon,\n [buttonStyles['button--arrow']]: hasArrow,\n [buttonStyles['button--on-dark']]: onDark,\n },\n className\n );\n const buttonTextClasses = classNames(\n buttonStyles['button__text'],\n {\n [buttonStyles['button__text--ellipsis']]: ellipsis,\n [buttonStyles['button__text--centered']]: fluid && textPosition === 'centered',\n },\n textClassName\n );\n const diagonalClasses = classNames(buttonStyles['diagonal'], {\n [buttonStyles['diagonal--on-dark']]: onDark,\n });\n\n useEffect(() => {\n checkOnlyIconAria(onlyIcon, ariaLabel, !isTest() && !isProd());\n }, []);\n\n const renderIcon = (iconElement: BaseIconElement | null, iconSize: number, iconClassName?: string): BaseIconElement | null => {\n return iconElement\n ? React.cloneElement(iconElement, {\n size: iconSize,\n color: iconElement?.props.color && !disabled ? iconElement.props.color : iconColor,\n isHovered: iconElement.props.isHovered === undefined ? !disabled && isHovered : iconElement.props.isHovered,\n className: iconClassName,\n })\n : null;\n };\n\n const renderButtonContent = (): JSX.Element => {\n return (\n <span className={buttonTextClasses} ref={buttonContentRef}>\n {disabled && borderlessVariant && (\n <span className={diagonalClasses}>\n <span className={buttonStyles['diagonal__line']} />\n </span>\n )}\n <span>{onlyIcon ? ariaLabel : restChildren}</span>\n </span>\n );\n };\n\n const renderbuttonContentWrapper = (): JSX.Element => (\n <span className={buttonClasses}>\n {renderIcon(leftIcon, getLargeIconSize(large, isMobile), !onlyIcon ? buttonStyles['button__left-icon'] : undefined)}\n {renderButtonContent()}\n {hasArrow\n ? renderIcon(\n <Icon svgIcon={ArrowRight} />,\n getLargeIconSize(large, isMobile),\n classNames(buttonStyles['button__arrow'], { [buttonStyles['button__arrow--both-icons']]: bothIcons })\n )\n : renderIcon(rightIcon, getLargeIconSize(large, isMobile), buttonStyles['button__right-icon'])}\n {hasUURightArrow && (\n <span style={{ color: iconColor }} className={buttonStyles['button__right-unicode-arrow']} aria-hidden>\n {' →'}\n </span>\n )}\n </span>\n );\n\n return (\n <>\n {htmlMarkup === 'button' && (\n <button\n id={id}\n onBlur={onBlur}\n onClick={onClick}\n disabled={disabled}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Button}\n className={buttonWrapperClasses}\n ref={hoverRef as React.ForwardedRef<HTMLButtonElement>}\n tabIndex={tabIndex}\n type={type}\n {...rest}\n >\n {renderbuttonContentWrapper()}\n </button>\n )}\n {htmlMarkup === 'a' && (\n <a\n id={id}\n onBlur={onBlur}\n onClick={onClick}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Button}\n className={buttonWrapperClasses}\n href={href}\n target={target}\n rel={target === '_blank' ? 'noopener noreferrer' : props.rel}\n ref={hoverRef as React.ForwardedRef<HTMLAnchorElement>}\n tabIndex={tabIndex}\n {...restProps}\n >\n {renderbuttonContentWrapper()}\n </a>\n )}\n </>\n );\n});\n\nexport default Button;\n"],"names":["React"],"mappings":"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"}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,30 +1,78 @@
|
|
|
1
|
-
## 11.2.0
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
## [11.2.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv11.1.0&targetVersion=GTv11.2.0) (2025-05-27)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
- legg til active styling på nye komponenter
|
|
6
|
+
([7e01e15](https://github.com/helsenorge/designsystem/commit/7e01e15f329985cc5fdf2a3b5430e68d0a793346)), closes
|
|
7
|
+
[#350468](https://github.com/helsenorge/designsystem/issues/350468) [#351362](https://github.com/helsenorge/designsystem/issues/351362)
|
|
8
|
+
[#351368](https://github.com/helsenorge/designsystem/issues/351368)
|
|
9
|
+
- oppdaterte fargetokens ([e30d942](https://github.com/helsenorge/designsystem/commit/e30d942c4179c9ed18fe63deb9f89be435e9c08d)), closes
|
|
10
|
+
[#349793](https://github.com/helsenorge/designsystem/issues/349793)
|
|
11
|
+
- **articleteaser:** ny komponent ([3431e82](https://github.com/helsenorge/designsystem/commit/3431e8219f0e95e75547cf78a8ed5467c3972de4)),
|
|
12
|
+
closes [#351362](https://github.com/helsenorge/designsystem/issues/351362)
|
|
13
|
+
- **close:** legg til flere farger og bruk i helpdrawer
|
|
14
|
+
([c442703](https://github.com/helsenorge/designsystem/commit/c442703d95c7bf490e21fadc380161f9a1d3d82f)), closes
|
|
15
|
+
[#352915](https://github.com/helsenorge/designsystem/issues/352915)
|
|
16
|
+
- **helpdrawer:** lagt til komponent
|
|
17
|
+
([0358d95](https://github.com/helsenorge/designsystem/commit/0358d9586727ba45ece5899c39a077d2682aa976)), closes
|
|
18
|
+
[#350492](https://github.com/helsenorge/designsystem/issues/350492)
|
|
19
|
+
- **helpdrawer:** nytt komponent helpdrawer
|
|
20
|
+
([4fbd27a](https://github.com/helsenorge/designsystem/commit/4fbd27a0278bce9a79ce43ffe8debb5b7b8067d0))
|
|
21
|
+
- **helpdrawer:** nytt komponent helpdrawer"
|
|
22
|
+
([e743080](https://github.com/helsenorge/designsystem/commit/e7430809193b1bc4b0ff26046ffb2822871967f5)), closes
|
|
23
|
+
[#350492](https://github.com/helsenorge/designsystem/issues/350492)
|
|
24
|
+
- **helpteaser:** ny komponent ([806f2ab](https://github.com/helsenorge/designsystem/commit/806f2ab7eba0179a1592a4a92bcd56c020d3c6f7))
|
|
25
|
+
- **icon:** nytt ikon toddler ([4d02bb4](https://github.com/helsenorge/designsystem/commit/4d02bb437340cc1cc8833a0b44badbdf119db43f)),
|
|
26
|
+
closes [#352079](https://github.com/helsenorge/designsystem/issues/352079)
|
|
27
|
+
- **illustration:** nye illustrasjoner for småbarnsliv
|
|
28
|
+
([855cc01](https://github.com/helsenorge/designsystem/commit/855cc013f9938a1e0d56e04581990a8d30ba64e1)), closes
|
|
29
|
+
[#353036](https://github.com/helsenorge/designsystem/issues/353036)
|
|
30
|
+
- **infoteaser:** ny komponent ([8c35a84](https://github.com/helsenorge/designsystem/commit/8c35a84e94fc8e7344266ca8585a15bd2e93d2f8)),
|
|
31
|
+
closes [#351368](https://github.com/helsenorge/designsystem/issues/351368)
|
|
32
|
+
- **panel:** legg til språkstøtte og ta i bruk tokens
|
|
33
|
+
([3f21b2e](https://github.com/helsenorge/designsystem/commit/3f21b2e90041537c05e403b4237db7ffe07b5f40)), closes
|
|
34
|
+
[#349728](https://github.com/helsenorge/designsystem/issues/349728) [#349793](https://github.com/helsenorge/designsystem/issues/349793)
|
|
35
|
+
|
|
36
|
+
### Bug Fixes
|
|
37
|
+
|
|
38
|
+
- legg til manglende analytics id ([a11ea2c](https://github.com/helsenorge/designsystem/commit/a11ea2c1a21ddf7a4bb6aa2a0ca6d9edfa1f6582)),
|
|
39
|
+
closes [#351362](https://github.com/helsenorge/designsystem/issues/351362)
|
|
40
|
+
- usebreakpoint bommer når flere breakpoints trigger samtidig
|
|
41
|
+
([1dc454e](https://github.com/helsenorge/designsystem/commit/1dc454e94a73b8c82f45c86610986d4218cb9e9c)), closes
|
|
42
|
+
[#351338](https://github.com/helsenorge/designsystem/issues/351338)
|
|
43
|
+
- **articleteaser:** kun vis fokus styling på focus-visible
|
|
44
|
+
([83a0cfb](https://github.com/helsenorge/designsystem/commit/83a0cfb4b9e70614bb7bdff6313c424543fa60db))
|
|
45
|
+
- **articleteaser:** tykkelse på fokus
|
|
46
|
+
([bda2253](https://github.com/helsenorge/designsystem/commit/bda2253fe91a50ec6752557d3910c33ebbffb27b))
|
|
47
|
+
- **icon:** fiks toddler ikon ([14883df](https://github.com/helsenorge/designsystem/commit/14883df7c20d291c2a92f8c2acd80d6ce460d0ff)),
|
|
48
|
+
closes [#352079](https://github.com/helsenorge/designsystem/issues/352079)
|
|
49
|
+
- **infoteaser:** riktig focus tykkelse
|
|
50
|
+
([5de4798](https://github.com/helsenorge/designsystem/commit/5de47982951f8f07be03215c1980c68e7762e617)), closes
|
|
51
|
+
[#351368](https://github.com/helsenorge/designsystem/issues/351368)
|
|
52
|
+
|
|
53
|
+
## [11.1.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv11.0.0&targetVersion=GTv11.1.0) (2025-05-09)
|
|
54
|
+
|
|
55
|
+
### Features
|
|
56
|
+
|
|
57
|
+
- ny hook useismobilebreakpoint ([a5db7ed](https://github.com/helsenorge/designsystem/commit/a5db7ed8753af15ea29e459c2d5032b43e813856)),
|
|
58
|
+
closes [#351338](https://github.com/helsenorge/designsystem/issues/351338)
|
|
7
59
|
- spacers tokens lagt til ([40b77e4](https://github.com/helsenorge/designsystem/commit/40b77e4626971621f6645e61df2636249463c2f7)), closes
|
|
8
60
|
[#347154](https://github.com/helsenorge/designsystem/issues/347154)
|
|
9
|
-
- **
|
|
10
|
-
([
|
|
11
|
-
|
|
12
|
-
([b47870f](https://github.com/helsenorge/designsystem/commit/b47870ff5cb571d09adcc921bbfc7270e640dba0))
|
|
61
|
+
- **drawer:** mulighet til å skru av lukkekryss
|
|
62
|
+
([f486bee](https://github.com/helsenorge/designsystem/commit/f486bee62d3709e2c4b9f39d6ce9e770c4010cc4)), closes
|
|
63
|
+
[#351292](https://github.com/helsenorge/designsystem/issues/351292)
|
|
13
64
|
- **modal:** footercontent prop legges til for å kunne gi egne cta buttons
|
|
14
65
|
([f5b0519](https://github.com/helsenorge/designsystem/commit/f5b051917081f6f7d8be44ff33679ace6a6e02da)), closes
|
|
15
66
|
[#350943](https://github.com/helsenorge/designsystem/issues/350943)
|
|
16
|
-
- **popover:** bruk floating UI til å plassere popover
|
|
17
|
-
([6e9d943](https://github.com/helsenorge/designsystem/commit/6e9d9437fbd6409ed80188bf84b21906fbc23889))
|
|
18
|
-
- **typography:** nye stiler for help-text pg helt-trigger-text
|
|
19
|
-
([9ee09ba](https://github.com/helsenorge/designsystem/commit/9ee09ba5d7815b81c9fd2910f00d667c1d01bfee)), closes
|
|
20
|
-
[#350872](https://github.com/helsenorge/designsystem/issues/350872)
|
|
21
67
|
|
|
22
68
|
### Bug Fixes
|
|
23
69
|
|
|
24
|
-
- bredde på små skjermer ([148beea](https://github.com/helsenorge/designsystem/commit/148beeaeac4cc10060872715e780e6a5f1642c6a))
|
|
25
70
|
- **lightbox:** fiks problem med store knapper på ios
|
|
26
71
|
([91481f6](https://github.com/helsenorge/designsystem/commit/91481f64ad0982f579558407658747eae5a5a30e)), closes
|
|
27
72
|
[#331056](https://github.com/helsenorge/designsystem/issues/331056)
|
|
73
|
+
- **lightbox:** scrollbar vises ikke med lightbox åpen
|
|
74
|
+
([3953140](https://github.com/helsenorge/designsystem/commit/3953140a0e1411edc18161eff7e1e727933cb3c3)), closes
|
|
75
|
+
[#350843](https://github.com/helsenorge/designsystem/issues/350843)
|
|
28
76
|
|
|
29
77
|
## [11.0.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv10.8.0&targetVersion=GTv11.0.0) (2025-04-29)
|
|
30
78
|
|
package/Close.js
CHANGED
|
@@ -2,18 +2,24 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import React__default from "react";
|
|
3
3
|
import classNames from "classnames";
|
|
4
4
|
import { AnalyticsId } from "./constants.js";
|
|
5
|
-
import { useBreakpoint, Breakpoint } from "./hooks/useBreakpoint.js";
|
|
6
5
|
import { useHover } from "./hooks/useHover.js";
|
|
7
|
-
import {
|
|
6
|
+
import { useIsMobileBreakpoint } from "./hooks/useIsMobileBreakpoint.js";
|
|
8
7
|
import { mergeRefs } from "./utils/refs.js";
|
|
9
8
|
import { I as Icon } from "./Icon.js";
|
|
10
9
|
import X from "./components/Icons/X.js";
|
|
11
10
|
import styles from "./components/Close/styles.module.scss";
|
|
12
11
|
const Close = React__default.forwardRef(function ButtonForwardedRef(props, ref) {
|
|
13
|
-
const { small, testId, ariaLabel = "Lukk", onClick, className, color =
|
|
14
|
-
const breakpoint = useBreakpoint();
|
|
12
|
+
const { small, testId, ariaLabel = "Lukk", onClick, className, color = "blueberry" } = props;
|
|
15
13
|
const { hoverRef, isHovered } = useHover();
|
|
16
|
-
const iconSize =
|
|
14
|
+
const iconSize = useIsMobileBreakpoint() || small ? 38 : 48;
|
|
15
|
+
let iconColor;
|
|
16
|
+
if (color === "black") {
|
|
17
|
+
iconColor = "black";
|
|
18
|
+
} else if (color === "plum") {
|
|
19
|
+
iconColor = "var(--core-color-plum-700)";
|
|
20
|
+
} else {
|
|
21
|
+
iconColor = "var(--color-action-graphics-onlight)";
|
|
22
|
+
}
|
|
17
23
|
const closeClasses = classNames(styles.close, { [styles["close--small"]]: small }, className);
|
|
18
24
|
return /* @__PURE__ */ jsx(
|
|
19
25
|
"button",
|
|
@@ -25,7 +31,16 @@ const Close = React__default.forwardRef(function ButtonForwardedRef(props, ref)
|
|
|
25
31
|
"aria-label": ariaLabel,
|
|
26
32
|
onClick,
|
|
27
33
|
type: "button",
|
|
28
|
-
children: /* @__PURE__ */ jsx(
|
|
34
|
+
children: /* @__PURE__ */ jsx(
|
|
35
|
+
"span",
|
|
36
|
+
{
|
|
37
|
+
className: classNames(styles["close__inner-container"], {
|
|
38
|
+
[styles["close--small"]]: small,
|
|
39
|
+
[styles["close__inner-container--plum"]]: color == "plum"
|
|
40
|
+
}),
|
|
41
|
+
children: /* @__PURE__ */ jsx(Icon, { svgIcon: X, color: iconColor, size: iconSize, isHovered })
|
|
42
|
+
}
|
|
43
|
+
)
|
|
29
44
|
}
|
|
30
45
|
);
|
|
31
46
|
});
|
package/Close.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Close.js","sources":["../src/components/Close/Close.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\nimport {
|
|
1
|
+
{"version":3,"file":"Close.js","sources":["../src/components/Close/Close.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\nimport { useHover } from '../../hooks/useHover';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { mergeRefs } from '../../utils/refs';\nimport Icon from '../Icon';\nimport X from '../Icons/X';\n\nimport styles from './styles.module.scss';\n\nexport interface CloseProps {\n /** Keeps the icon small for all screen sizes */\n small?: boolean;\n /** Function is called when user clicks the button */\n onClick?: (e?: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n /** Sets the aria-label of the button */\n ariaLabel?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Gives color to the svg */\n color?: 'blueberry' | 'black' | 'plum';\n}\n\nconst Close = React.forwardRef(function ButtonForwardedRef(props: CloseProps, ref: React.ForwardedRef<HTMLButtonElement>) {\n const { small, testId, ariaLabel = 'Lukk', onClick, className, color = 'blueberry' } = props;\n const { hoverRef, isHovered } = useHover();\n\n const iconSize = useIsMobileBreakpoint() || small ? 38 : 48;\n\n let iconColor;\n if (color === 'black') {\n iconColor = 'black';\n } else if (color === 'plum') {\n iconColor = 'var(--core-color-plum-700)';\n } else {\n iconColor = 'var(--color-action-graphics-onlight)';\n }\n\n const closeClasses = classNames(styles.close, { [styles['close--small']]: small }, className);\n\n return (\n <button\n ref={mergeRefs([ref, hoverRef])}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Close}\n className={closeClasses}\n aria-label={ariaLabel}\n onClick={onClick}\n type=\"button\"\n >\n <span\n className={classNames(styles['close__inner-container'], {\n [styles['close--small']]: small,\n [styles['close__inner-container--plum']]: color == 'plum',\n })}\n >\n <Icon svgIcon={X} color={iconColor} size={iconSize} isHovered={isHovered} />\n </span>\n </button>\n );\n});\n\nexport default Close;\n"],"names":["React"],"mappings":";;;;;;;;;;AA4BA,MAAM,QAAQA,eAAM,WAAW,SAAS,mBAAmB,OAAmB,KAA4C;AAClH,QAAA,EAAE,OAAO,QAAQ,YAAY,QAAQ,SAAS,WAAW,QAAQ,YAAA,IAAgB;AACvF,QAAM,EAAE,UAAU,UAAU,IAAI,SAAS;AAEzC,QAAM,WAAW,sBAAA,KAA2B,QAAQ,KAAK;AAErD,MAAA;AACJ,MAAI,UAAU,SAAS;AACT,gBAAA;AAAA,EAAA,WACH,UAAU,QAAQ;AACf,gBAAA;AAAA,EAAA,OACP;AACO,gBAAA;AAAA,EAAA;AAGd,QAAM,eAAe,WAAW,OAAO,OAAO,EAAE,CAAC,OAAO,cAAc,CAAC,GAAG,MAAM,GAAG,SAAS;AAG1F,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK,UAAU,CAAC,KAAK,QAAQ,CAAC;AAAA,MAC9B,eAAa;AAAA,MACb,oBAAkB,YAAY;AAAA,MAC9B,WAAW;AAAA,MACX,cAAY;AAAA,MACZ;AAAA,MACA,MAAK;AAAA,MAEL,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,WAAW,OAAO,wBAAwB,GAAG;AAAA,YACtD,CAAC,OAAO,cAAc,CAAC,GAAG;AAAA,YAC1B,CAAC,OAAO,8BAA8B,CAAC,GAAG,SAAS;AAAA,UAAA,CACpD;AAAA,UAED,UAAA,oBAAC,QAAK,SAAS,GAAG,OAAO,WAAW,MAAM,UAAU,UAAsB,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAC5E;AAAA,EACF;AAEJ,CAAC;"}
|
package/Drawer.js
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { createContext, useId, useRef, useContext, useInsertionEffect, useCallback, useMemo, useEffect, Children, isValidElement, useLayoutEffect, useState } from "react";
|
|
4
|
+
import classNames from "classnames";
|
|
5
|
+
import { ZIndex, KeyboardEventKey, AnalyticsId } from "./constants.js";
|
|
6
|
+
import { useFocusTrap } from "./hooks/useFocusTrap.js";
|
|
7
|
+
import { useIsMobileBreakpoint } from "./hooks/useIsMobileBreakpoint.js";
|
|
8
|
+
import { useKeyboardEvent } from "./hooks/useKeyboardEvent.js";
|
|
9
|
+
import { useOutsideEvent } from "./hooks/useOutsideEvent.js";
|
|
10
|
+
import { useReturnFocusOnUnmount } from "./hooks/useReturnFocusOnUnmount.js";
|
|
11
|
+
import { getAriaLabelAttributes } from "./utils/accessibility.js";
|
|
12
|
+
import { u as uuid } from "./uuid.js";
|
|
13
|
+
import { B as Button } from "./Button.js";
|
|
14
|
+
import { C as Close } from "./Close.js";
|
|
15
|
+
import { T as Title } from "./Title.js";
|
|
16
|
+
import styles from "./components/Drawer/styles.module.scss";
|
|
17
|
+
import { a as useConstant, i as isBrowser, u as useAnimate } from "./use-animate.js";
|
|
18
|
+
const LayoutGroupContext = createContext({});
|
|
19
|
+
const PresenceContext = createContext(null);
|
|
20
|
+
const MotionConfigContext = createContext({
|
|
21
|
+
transformPagePoint: (p) => p,
|
|
22
|
+
isStatic: false,
|
|
23
|
+
reducedMotion: "never"
|
|
24
|
+
});
|
|
25
|
+
class PopChildMeasure extends React.Component {
|
|
26
|
+
getSnapshotBeforeUpdate(prevProps) {
|
|
27
|
+
const element = this.props.childRef.current;
|
|
28
|
+
if (element && prevProps.isPresent && !this.props.isPresent) {
|
|
29
|
+
const size = this.props.sizeRef.current;
|
|
30
|
+
size.height = element.offsetHeight || 0;
|
|
31
|
+
size.width = element.offsetWidth || 0;
|
|
32
|
+
size.top = element.offsetTop;
|
|
33
|
+
size.left = element.offsetLeft;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Required with getSnapshotBeforeUpdate to stop React complaining.
|
|
39
|
+
*/
|
|
40
|
+
componentDidUpdate() {
|
|
41
|
+
}
|
|
42
|
+
render() {
|
|
43
|
+
return this.props.children;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function PopChild({ children, isPresent }) {
|
|
47
|
+
const id = useId();
|
|
48
|
+
const ref = useRef(null);
|
|
49
|
+
const size = useRef({
|
|
50
|
+
width: 0,
|
|
51
|
+
height: 0,
|
|
52
|
+
top: 0,
|
|
53
|
+
left: 0
|
|
54
|
+
});
|
|
55
|
+
const { nonce } = useContext(MotionConfigContext);
|
|
56
|
+
useInsertionEffect(() => {
|
|
57
|
+
const { width, height, top, left } = size.current;
|
|
58
|
+
if (isPresent || !ref.current || !width || !height)
|
|
59
|
+
return;
|
|
60
|
+
ref.current.dataset.motionPopId = id;
|
|
61
|
+
const style = document.createElement("style");
|
|
62
|
+
if (nonce)
|
|
63
|
+
style.nonce = nonce;
|
|
64
|
+
document.head.appendChild(style);
|
|
65
|
+
if (style.sheet) {
|
|
66
|
+
style.sheet.insertRule(`
|
|
67
|
+
[data-motion-pop-id="${id}"] {
|
|
68
|
+
position: absolute !important;
|
|
69
|
+
width: ${width}px !important;
|
|
70
|
+
height: ${height}px !important;
|
|
71
|
+
top: ${top}px !important;
|
|
72
|
+
left: ${left}px !important;
|
|
73
|
+
}
|
|
74
|
+
`);
|
|
75
|
+
}
|
|
76
|
+
return () => {
|
|
77
|
+
document.head.removeChild(style);
|
|
78
|
+
};
|
|
79
|
+
}, [isPresent]);
|
|
80
|
+
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React.cloneElement(children, { ref }) });
|
|
81
|
+
}
|
|
82
|
+
const PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, presenceAffectsLayout, mode }) => {
|
|
83
|
+
const presenceChildren = useConstant(newChildrenMap);
|
|
84
|
+
const id = useId();
|
|
85
|
+
const memoizedOnExitComplete = useCallback((childId) => {
|
|
86
|
+
presenceChildren.set(childId, true);
|
|
87
|
+
for (const isComplete of presenceChildren.values()) {
|
|
88
|
+
if (!isComplete)
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
onExitComplete && onExitComplete();
|
|
92
|
+
}, [presenceChildren, onExitComplete]);
|
|
93
|
+
const context = useMemo(
|
|
94
|
+
() => ({
|
|
95
|
+
id,
|
|
96
|
+
initial,
|
|
97
|
+
isPresent,
|
|
98
|
+
custom,
|
|
99
|
+
onExitComplete: memoizedOnExitComplete,
|
|
100
|
+
register: (childId) => {
|
|
101
|
+
presenceChildren.set(childId, false);
|
|
102
|
+
return () => presenceChildren.delete(childId);
|
|
103
|
+
}
|
|
104
|
+
}),
|
|
105
|
+
/**
|
|
106
|
+
* If the presence of a child affects the layout of the components around it,
|
|
107
|
+
* we want to make a new context value to ensure they get re-rendered
|
|
108
|
+
* so they can detect that layout change.
|
|
109
|
+
*/
|
|
110
|
+
presenceAffectsLayout ? [Math.random(), memoizedOnExitComplete] : [isPresent, memoizedOnExitComplete]
|
|
111
|
+
);
|
|
112
|
+
useMemo(() => {
|
|
113
|
+
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
|
114
|
+
}, [isPresent]);
|
|
115
|
+
React.useEffect(() => {
|
|
116
|
+
!isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
|
|
117
|
+
}, [isPresent]);
|
|
118
|
+
if (mode === "popLayout") {
|
|
119
|
+
children = jsx(PopChild, { isPresent, children });
|
|
120
|
+
}
|
|
121
|
+
return jsx(PresenceContext.Provider, { value: context, children });
|
|
122
|
+
};
|
|
123
|
+
function newChildrenMap() {
|
|
124
|
+
return /* @__PURE__ */ new Map();
|
|
125
|
+
}
|
|
126
|
+
function usePresence(subscribe = true) {
|
|
127
|
+
const context = useContext(PresenceContext);
|
|
128
|
+
if (context === null)
|
|
129
|
+
return [true, null];
|
|
130
|
+
const { isPresent, onExitComplete, register } = context;
|
|
131
|
+
const id = useId();
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
if (subscribe)
|
|
134
|
+
register(id);
|
|
135
|
+
}, [subscribe]);
|
|
136
|
+
const safeToRemove = useCallback(() => subscribe && onExitComplete && onExitComplete(id), [id, onExitComplete, subscribe]);
|
|
137
|
+
return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
|
|
138
|
+
}
|
|
139
|
+
const getChildKey = (child) => child.key || "";
|
|
140
|
+
function onlyElements(children) {
|
|
141
|
+
const filtered = [];
|
|
142
|
+
Children.forEach(children, (child) => {
|
|
143
|
+
if (isValidElement(child))
|
|
144
|
+
filtered.push(child);
|
|
145
|
+
});
|
|
146
|
+
return filtered;
|
|
147
|
+
}
|
|
148
|
+
const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect;
|
|
149
|
+
const AnimatePresence = ({ children, custom, initial = true, onExitComplete, presenceAffectsLayout = true, mode = "sync", propagate = false }) => {
|
|
150
|
+
const [isParentPresent, safeToRemove] = usePresence(propagate);
|
|
151
|
+
const presentChildren = useMemo(() => onlyElements(children), [children]);
|
|
152
|
+
const presentKeys = propagate && !isParentPresent ? [] : presentChildren.map(getChildKey);
|
|
153
|
+
const isInitialRender = useRef(true);
|
|
154
|
+
const pendingPresentChildren = useRef(presentChildren);
|
|
155
|
+
const exitComplete = useConstant(() => /* @__PURE__ */ new Map());
|
|
156
|
+
const [diffedChildren, setDiffedChildren] = useState(presentChildren);
|
|
157
|
+
const [renderedChildren, setRenderedChildren] = useState(presentChildren);
|
|
158
|
+
useIsomorphicLayoutEffect(() => {
|
|
159
|
+
isInitialRender.current = false;
|
|
160
|
+
pendingPresentChildren.current = presentChildren;
|
|
161
|
+
for (let i = 0; i < renderedChildren.length; i++) {
|
|
162
|
+
const key = getChildKey(renderedChildren[i]);
|
|
163
|
+
if (!presentKeys.includes(key)) {
|
|
164
|
+
if (exitComplete.get(key) !== true) {
|
|
165
|
+
exitComplete.set(key, false);
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
exitComplete.delete(key);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, [renderedChildren, presentKeys.length, presentKeys.join("-")]);
|
|
172
|
+
const exitingChildren = [];
|
|
173
|
+
if (presentChildren !== diffedChildren) {
|
|
174
|
+
let nextChildren = [...presentChildren];
|
|
175
|
+
for (let i = 0; i < renderedChildren.length; i++) {
|
|
176
|
+
const child = renderedChildren[i];
|
|
177
|
+
const key = getChildKey(child);
|
|
178
|
+
if (!presentKeys.includes(key)) {
|
|
179
|
+
nextChildren.splice(i, 0, child);
|
|
180
|
+
exitingChildren.push(child);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (mode === "wait" && exitingChildren.length) {
|
|
184
|
+
nextChildren = exitingChildren;
|
|
185
|
+
}
|
|
186
|
+
setRenderedChildren(onlyElements(nextChildren));
|
|
187
|
+
setDiffedChildren(presentChildren);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (process.env.NODE_ENV !== "production" && mode === "wait" && renderedChildren.length > 1) {
|
|
191
|
+
console.warn(`You're attempting to animate multiple children within AnimatePresence, but its mode is set to "wait". This will lead to odd visual behaviour.`);
|
|
192
|
+
}
|
|
193
|
+
const { forceRender } = useContext(LayoutGroupContext);
|
|
194
|
+
return jsx(Fragment, { children: renderedChildren.map((child) => {
|
|
195
|
+
const key = getChildKey(child);
|
|
196
|
+
const isPresent = propagate && !isParentPresent ? false : presentChildren === renderedChildren || presentKeys.includes(key);
|
|
197
|
+
const onExit = () => {
|
|
198
|
+
if (exitComplete.has(key)) {
|
|
199
|
+
exitComplete.set(key, true);
|
|
200
|
+
} else {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
let isEveryExitComplete = true;
|
|
204
|
+
exitComplete.forEach((isExitComplete) => {
|
|
205
|
+
if (!isExitComplete)
|
|
206
|
+
isEveryExitComplete = false;
|
|
207
|
+
});
|
|
208
|
+
if (isEveryExitComplete) {
|
|
209
|
+
forceRender === null || forceRender === void 0 ? void 0 : forceRender();
|
|
210
|
+
setRenderedChildren(pendingPresentChildren.current);
|
|
211
|
+
propagate && (safeToRemove === null || safeToRemove === void 0 ? void 0 : safeToRemove());
|
|
212
|
+
onExitComplete && onExitComplete();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
return jsx(PresenceChild, { isPresent, initial: !isInitialRender.current || initial ? void 0 : false, custom: isPresent ? void 0 : custom, presenceAffectsLayout, mode, onExitComplete: isPresent ? void 0 : onExit, children: child }, key);
|
|
216
|
+
}) });
|
|
217
|
+
};
|
|
218
|
+
const Drawer = (props) => {
|
|
219
|
+
const { isOpen, ...rest } = props;
|
|
220
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsx(InnerDrawer, { ...rest }) });
|
|
221
|
+
};
|
|
222
|
+
const InnerDrawer = (props) => {
|
|
223
|
+
const {
|
|
224
|
+
ariaLabel,
|
|
225
|
+
ariaLabelledBy,
|
|
226
|
+
ariaLabelCloseBtn,
|
|
227
|
+
children,
|
|
228
|
+
closeColor = "blueberry",
|
|
229
|
+
desktopDirection = "left",
|
|
230
|
+
footerContent,
|
|
231
|
+
headerClasses,
|
|
232
|
+
onPrimaryAction,
|
|
233
|
+
onRequestClose,
|
|
234
|
+
onSecondaryAction,
|
|
235
|
+
primaryActionText,
|
|
236
|
+
secondaryActionText,
|
|
237
|
+
title,
|
|
238
|
+
titleHtmlMarkup = "h3",
|
|
239
|
+
titleId = uuid(),
|
|
240
|
+
zIndex = ZIndex.OverlayScreen
|
|
241
|
+
} = props;
|
|
242
|
+
const ariaLabelAttributes = getAriaLabelAttributes({ label: ariaLabel, id: ariaLabelledBy, fallbackId: titleId });
|
|
243
|
+
const overlayRef = useRef(null);
|
|
244
|
+
const containerRef = useRef(null);
|
|
245
|
+
const contentRef = useRef(null);
|
|
246
|
+
const isMobile = useIsMobileBreakpoint();
|
|
247
|
+
const [scope, animate] = useAnimate();
|
|
248
|
+
const [isPresent, safeToRemove] = usePresence();
|
|
249
|
+
const contentIsScrollable = contentRef.current && contentRef.current.scrollHeight > contentRef.current.clientHeight;
|
|
250
|
+
const headerStyling = classNames(styles.drawer__header, headerClasses);
|
|
251
|
+
const hasFooterContent = typeof footerContent !== "undefined" && footerContent || onPrimaryAction || onSecondaryAction;
|
|
252
|
+
useFocusTrap(containerRef, true);
|
|
253
|
+
useReturnFocusOnUnmount(containerRef);
|
|
254
|
+
useOutsideEvent(containerRef, () => {
|
|
255
|
+
onRequestClose && onRequestClose();
|
|
256
|
+
});
|
|
257
|
+
useKeyboardEvent(containerRef, () => onRequestClose && onRequestClose(), [KeyboardEventKey.Escape]);
|
|
258
|
+
useEffect(() => {
|
|
259
|
+
var _a;
|
|
260
|
+
(_a = containerRef.current) == null ? void 0 : _a.focus();
|
|
261
|
+
}, []);
|
|
262
|
+
useEffect(() => {
|
|
263
|
+
if (!overlayRef.current || !containerRef.current) return;
|
|
264
|
+
if (!isPresent) {
|
|
265
|
+
closeDrawer();
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (isMobile) {
|
|
269
|
+
animate(containerRef.current, { y: "0" }, { duration: 0.3, ease: "easeInOut" });
|
|
270
|
+
} else {
|
|
271
|
+
animate(containerRef.current, { x: "0" }, { duration: 0.3, ease: "easeInOut" });
|
|
272
|
+
}
|
|
273
|
+
animate(overlayRef.current, { opacity: 1, pointerEvents: "auto" }, { duration: 0.3, ease: "easeInOut" });
|
|
274
|
+
}, [isPresent]);
|
|
275
|
+
useEffect(() => {
|
|
276
|
+
}, [isPresent]);
|
|
277
|
+
const closeDrawer = () => {
|
|
278
|
+
if (!overlayRef.current || !containerRef.current) return;
|
|
279
|
+
animate(overlayRef.current, { opacity: 0, pointerEvents: "none" }, { duration: 0.3, ease: "easeInOut" });
|
|
280
|
+
if (isMobile) {
|
|
281
|
+
animate(
|
|
282
|
+
containerRef.current,
|
|
283
|
+
{ y: "100%" },
|
|
284
|
+
{
|
|
285
|
+
duration: 0.3,
|
|
286
|
+
ease: "easeInOut",
|
|
287
|
+
onComplete: () => {
|
|
288
|
+
safeToRemove && safeToRemove();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
);
|
|
292
|
+
} else {
|
|
293
|
+
animate(
|
|
294
|
+
containerRef.current,
|
|
295
|
+
{ x: desktopDirection === "left" ? "-100%" : "100%" },
|
|
296
|
+
{
|
|
297
|
+
duration: 0.3,
|
|
298
|
+
ease: "easeInOut",
|
|
299
|
+
onComplete: () => {
|
|
300
|
+
safeToRemove && safeToRemove();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
const handleCTA = (callback) => {
|
|
307
|
+
if (callback) {
|
|
308
|
+
callback();
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
return /* @__PURE__ */ jsxs("div", { className: styles.drawer, ref: scope, style: { zIndex }, "data-analyticsid": AnalyticsId.Drawer, children: [
|
|
312
|
+
/* @__PURE__ */ jsx("div", { className: styles.drawer__overlay, ref: overlayRef, "aria-hidden": "true" }),
|
|
313
|
+
/* @__PURE__ */ jsxs(
|
|
314
|
+
"div",
|
|
315
|
+
{
|
|
316
|
+
className: classNames(styles.drawer__container, {
|
|
317
|
+
[styles["drawer__container--right"]]: desktopDirection === "right"
|
|
318
|
+
}),
|
|
319
|
+
ref: containerRef,
|
|
320
|
+
role: "dialog",
|
|
321
|
+
"aria-modal": "true",
|
|
322
|
+
tabIndex: -1,
|
|
323
|
+
...ariaLabelAttributes,
|
|
324
|
+
children: [
|
|
325
|
+
/* @__PURE__ */ jsxs("div", { className: styles.drawer__container__inner, children: [
|
|
326
|
+
/* @__PURE__ */ jsxs("div", { className: headerStyling, children: [
|
|
327
|
+
/* @__PURE__ */ jsx(Title, { id: ariaLabelAttributes == null ? void 0 : ariaLabelAttributes["aria-labelledby"], htmlMarkup: titleHtmlMarkup, appearance: "title3", children: title }),
|
|
328
|
+
!props.noCloseButton && /* @__PURE__ */ jsx(
|
|
329
|
+
Close,
|
|
330
|
+
{
|
|
331
|
+
ariaLabel: ariaLabelCloseBtn,
|
|
332
|
+
color: closeColor,
|
|
333
|
+
onClick: onRequestClose,
|
|
334
|
+
className: styles["drawer__header__close-button"]
|
|
335
|
+
}
|
|
336
|
+
)
|
|
337
|
+
] }),
|
|
338
|
+
/* @__PURE__ */ jsx(
|
|
339
|
+
"div",
|
|
340
|
+
{
|
|
341
|
+
className: styles.drawer__content,
|
|
342
|
+
tabIndex: contentIsScrollable ? 0 : void 0,
|
|
343
|
+
role: contentIsScrollable ? "region" : void 0,
|
|
344
|
+
...contentIsScrollable ? ariaLabelAttributes : {},
|
|
345
|
+
ref: contentRef,
|
|
346
|
+
children
|
|
347
|
+
}
|
|
348
|
+
)
|
|
349
|
+
] }),
|
|
350
|
+
hasFooterContent && /* @__PURE__ */ jsx("div", { className: styles.drawer__footer, children: footerContent ? footerContent : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
351
|
+
onPrimaryAction && /* @__PURE__ */ jsx(Button, { onClick: () => handleCTA(onPrimaryAction), children: primaryActionText }),
|
|
352
|
+
onSecondaryAction && /* @__PURE__ */ jsx(Button, { variant: "borderless", onClick: () => handleCTA(onSecondaryAction), children: secondaryActionText })
|
|
353
|
+
] }) })
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
)
|
|
357
|
+
] });
|
|
358
|
+
};
|
|
359
|
+
export {
|
|
360
|
+
Drawer as D
|
|
361
|
+
};
|
|
362
|
+
//# sourceMappingURL=Drawer.js.map
|