@helsenorge/designsystem-react 3.0.0 → 3.0.1
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 +380 -668
- package/HelpBubble.js +1 -1
- package/HelpBubble.js.map +1 -1
- package/HorizontalScroll.js.map +1 -1
- package/Input.js +1 -1
- package/Input.js.map +1 -1
- package/ListHeader.js +1 -1
- package/ListHeader.js.map +1 -1
- package/Modal.js.map +1 -1
- package/PopOver.js +1 -1
- package/PopOver.js.map +1 -1
- package/RadioButton.js +1 -1
- package/RadioButton.js.map +1 -1
- package/Textarea.js +1 -1
- package/Textarea.js.map +1 -1
- package/Title.js.map +1 -1
- package/Tooltip.js.map +1 -1
- package/TooltipWord.js +1 -1
- package/TooltipWord.js.map +1 -1
- package/components/AnchorLink/styles.module.scss +11 -6
- package/components/Avatar/styles.module.scss +2 -2
- package/components/Badge/styles.module.scss +7 -1
- package/components/Button/styles.module.scss +35 -21
- package/components/Checkbox/styles.module.scss +12 -12
- package/components/Close/styles.module.scss +15 -7
- package/components/Dropdown/index.js +1 -1
- package/components/Dropdown/index.js.map +1 -1
- package/components/Dropdown/styles.module.scss +31 -10
- package/components/Duolist/styles.module.scss +5 -3
- package/components/ErrorWrapper/styles.module.scss +8 -6
- package/components/Expander/styles.module.scss +46 -15
- package/components/ExpanderHierarchy/expander.module.scss +13 -8
- package/components/ExpanderHierarchy/expander.module.scss.d.ts +1 -1
- package/components/ExpanderHierarchy/styles.module.scss +3 -3
- package/components/ExpanderList/index.js.map +1 -1
- package/components/ExpanderList/styles.module.scss +17 -6
- package/components/FormExample/FormExample.d.ts.map +1 -1
- package/components/FormExample/index.js.map +1 -1
- package/components/FormExample/styles.module.scss +6 -6
- package/components/FormGroup/styles.module.scss +5 -4
- package/components/FormLayout/styles.module.scss +5 -2
- package/components/HelpBubble/HelpBubble.d.ts +2 -2
- package/components/HelpBubble/HelpBubble.d.ts.map +1 -1
- package/components/HelpBubble/index.js +1 -1
- package/components/HelpBubble/styles.module.scss +10 -10
- package/components/HelpBubble/styles.module.scss.d.ts +0 -1
- package/components/HelpBubbleExample/index.js +1 -1
- package/components/HighlightBox/index.js.map +1 -1
- package/components/HighlightBox/styles.module.scss +38 -29
- package/components/HorizontalScroll/HorizontalScroll.d.ts.map +1 -1
- package/components/HorizontalScroll/styles.module.scss +10 -3
- package/components/Icons/SortUp.js +1 -1
- package/components/Icons/SortUp.js.map +1 -1
- package/components/Input/Input.d.ts.map +1 -1
- package/components/Input/styles.module.scss +8 -7
- package/components/LinkList/styles.module.scss +23 -5
- package/components/List/styles.module.scss +4 -0
- package/components/ListHeader/ListHeader.d.ts +9 -7
- package/components/ListHeader/ListHeader.d.ts.map +1 -1
- package/components/ListHeader/styles.module.scss +36 -11
- package/components/Loader/styles.module.scss +40 -18
- package/components/Logo/index.js.map +1 -1
- package/components/MaxCharacters/styles.module.scss +7 -5
- package/components/Modal/styles.module.scss +39 -23
- package/components/NotificationPanel/DetailButton/styles.module.scss +9 -5
- package/components/NotificationPanel/index.js.map +1 -1
- package/components/NotificationPanel/styles.module.scss +45 -12
- package/components/Panel/styles.module.scss +53 -29
- package/components/PanelList/styles.module.scss +6 -5
- package/components/PopMenu/PopMenu.d.ts.map +1 -1
- package/components/PopMenu/styles.module.scss +28 -7
- package/components/PopOver/PopOver.d.ts +5 -3
- package/components/PopOver/PopOver.d.ts.map +1 -1
- package/components/PopOver/componentdata.json +1 -1
- package/components/PopOver/styles.module.scss +16 -13
- package/components/RadioButton/RadioButton.d.ts.map +1 -1
- package/components/RadioButton/styles.module.scss +12 -14
- package/components/Select/styles.module.scss +14 -8
- package/components/Slider/Slider.d.ts.map +1 -1
- package/components/Slider/index.js +1 -1
- package/components/Slider/index.js.map +1 -1
- package/components/Slider/styles.module.scss +1 -1
- package/components/Spacer/styles.module.scss +13 -1
- package/components/StatusDot/styles.module.scss +2 -2
- package/components/Stepper/styles.module.scss +28 -20
- package/components/Table/Table.d.ts.map +1 -1
- package/components/Table/index.js +1 -1
- package/components/Table/index.js.map +1 -1
- package/components/Table/styles.module.scss +32 -20
- package/components/Tag/styles.module.scss +39 -27
- package/components/TagList/styles.module.scss +3 -3
- package/components/Textarea/Textarea.d.ts.map +1 -1
- package/components/Textarea/styles.module.scss +6 -5
- package/components/Tile/styles.module.scss +11 -6
- package/components/Title/Title.d.ts +1 -1
- package/components/Title/Title.d.ts.map +1 -1
- package/components/Title/styles.module.scss +5 -0
- package/components/Tooltip/TooltipWord/TooltipWord.d.ts +1 -1
- package/components/Tooltip/TooltipWord/TooltipWord.d.ts.map +1 -1
- package/components/Tooltip/TooltipWord/styles.module.scss +3 -3
- package/components/Tooltip/index.js +1 -1
- package/components/TooltipExample/index.js +1 -1
- package/components/Validation/styles.module.scss +3 -3
- package/hoc/withBreakpoint/withBreakpoint.d.ts +1 -1
- package/hoc/withBreakpoint/withBreakpoint.d.ts.map +1 -1
- package/hoc/withBreakpoint/withBreakpoint.js.map +1 -1
- package/hooks/useFocusTrap.d.ts.map +1 -1
- package/hooks/useFocusTrap.js.map +1 -1
- package/hooks/useSize.js.map +1 -1
- package/package.json +1 -1
- package/scss/_body.scss +3 -1
- package/scss/_breakpoints.scss +5 -8
- package/scss/_figma-tokens.scss +2 -2
- package/scss/_fonts.scss +36 -21
- package/scss/_grid.scss +5 -4
- package/scss/_input.scss +20 -11
- package/scss/_palette.scss +3 -11
- package/scss/_print.scss +58 -18
- package/scss/_screen-reader.scss +0 -2
- package/scss/_spacers.scss +17 -15
- package/scss/_title.scss +11 -5
- package/scss/helsenorge.scss +1 -1
- package/scss/typography.module.scss +20 -13
- package/utils/component.d.ts +1 -0
- package/utils/component.d.ts.map +1 -1
- package/utils/component.js +1 -1
- package/utils/component.js.map +1 -1
- package/utils/debounce.d.ts +1 -2
- package/utils/debounce.d.ts.map +1 -1
- package/utils/debounce.js +1 -1
- package/utils/debounce.js.map +1 -1
package/HelpBubble.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"react";import
|
|
1
|
+
import e from"react";import c from"classnames";import{AnalyticsId as y}from"./constants.js";import{A as L}from"./AnchorLink.js";import{C as A}from"./Close.js";import{P as w,a as I}from"./PopOver.js";import t from"./components/HelpBubble/styles.module.scss";const M=w,b=e.forwardRef((m,p)=>{const{children:u,className:f="",noCloseButton:o,linkText:r="Mer hjelp",linkUrl:n,onLinkClick:s,onClose:d,closeAriaLabel:h,showBubble:a,helpBubbleId:B,variant:C,controllerRef:k,role:i,testId:_}=m,l=i==="tooltip";if(!a&&!l)return null;const E=c(t.helpbubble,f),N=c(t.helpbubble__content,{[t["helpbubble__content--close"]]:!o&&!l}),v=()=>{if(!l){if(s&&r)return e.createElement("button",{className:t.helpbubble__link,onClick:s,type:"button"},r);if(n&&r)return e.createElement(L,{href:n},r)}},H=()=>{if(!(o||l))return e.createElement("div",{className:t.helpbubble__close},e.createElement(A,{small:!0,onClick:d,ariaLabel:h}))};return e.createElement(I,{id:B,variant:C,controllerRef:k,role:i,ref:p,show:l&&a,testId:_},e.createElement("div",{className:E,"data-analyticsid":y.HelpBubble},H(),e.createElement("div",{className:N},u,v())))});b.displayName="HelpBubble";const U=b;export{U as H,M as a};
|
|
2
2
|
//# sourceMappingURL=HelpBubble.js.map
|
package/HelpBubble.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HelpBubble.js","sources":["../src/components/HelpBubble/HelpBubble.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\nimport
|
|
1
|
+
{"version":3,"file":"HelpBubble.js","sources":["../src/components/HelpBubble/HelpBubble.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\nimport AnchorLink from '../AnchorLink';\nimport Close from '../Close';\nimport PopOver, { PopOverProps, PopOverVariant } from '../PopOver';\n\nimport styles from './styles.module.scss';\n\nexport const HelpBubbleVariant = PopOverVariant;\n\ntype HelpBubbleRole = 'tooltip';\n\nexport interface HelpBubbleProps extends Pick<PopOverProps, 'children' | 'variant' | 'controllerRef' | 'role'> {\n /** Id of the HelpBubble */\n helpBubbleId?: string;\n /** Content shown inside HelpBubble. Note that if role=\"tooltip\", you must not include interactive/focusable elements. */\n children: React.ReactNode;\n /** Ref for the element the HelpBubble is placed upon */\n controllerRef: React.RefObject<HTMLElement | SVGSVGElement>;\n /** Adds custom classes to the element. */\n className?: string;\n /** Determines the placement of the helpbubble. Default: automatic positioning. */\n variant?: keyof typeof HelpBubbleVariant;\n /** Show the bubble. Default: false. */\n showBubble?: boolean;\n /** Hide the close button in the bubble. Close button is never rendered if role=\"tooltip\". */\n noCloseButton?: boolean;\n /** Visible text on the link. Link is never rendered if role=\"tooltip\". */\n linkText?: string;\n /** Url the link leads to */\n linkUrl?: string;\n /** Function is called when link is clicked */\n onLinkClick?: () => void;\n /** Function is called when user clicks the button */\n onClose?: () => void;\n /** aria-label to be passed onto Close */\n closeAriaLabel?: string;\n /** Sets role of the HelpBubble element. If set to \"tooltip\", */\n role?: HelpBubbleRole;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nconst HelpBubble = React.forwardRef<HTMLDivElement | SVGSVGElement, HelpBubbleProps>((props, ref) => {\n const {\n children,\n className = '',\n noCloseButton,\n linkText = 'Mer hjelp',\n linkUrl,\n onLinkClick,\n onClose,\n closeAriaLabel,\n // Props passed on to PopOver\n showBubble,\n helpBubbleId,\n variant,\n controllerRef,\n role,\n testId,\n } = props;\n\n const isTooltip = role === 'tooltip';\n\n if (!showBubble && !isTooltip) {\n return null;\n }\n\n const helpBubbleClasses = classNames(styles.helpbubble, className);\n\n const contentClasses = classNames(styles.helpbubble__content, {\n [styles['helpbubble__content--close']]: !noCloseButton && !isTooltip,\n });\n\n const renderLink = (): JSX.Element | undefined => {\n // Det er ikke tillatt med interaktive/fokuserbare elementer i role=\"tooltip\"\n if (isTooltip) {\n return;\n }\n if (onLinkClick && linkText) {\n return (\n <button className={styles.helpbubble__link} onClick={onLinkClick} type=\"button\">\n {linkText}\n </button>\n );\n } else if (linkUrl && linkText) {\n return <AnchorLink href={linkUrl}>{linkText}</AnchorLink>;\n }\n };\n\n const renderCloseButton = (): JSX.Element | undefined => {\n if (noCloseButton || isTooltip) {\n return;\n }\n return (\n <div className={styles.helpbubble__close}>\n <Close small onClick={onClose} ariaLabel={closeAriaLabel} />\n </div>\n );\n };\n\n return (\n <PopOver\n id={helpBubbleId}\n variant={variant}\n controllerRef={controllerRef}\n role={role}\n ref={ref}\n show={isTooltip && showBubble}\n testId={testId}\n >\n <div className={helpBubbleClasses} data-analyticsid={AnalyticsId.HelpBubble}>\n {renderCloseButton()}\n <div className={contentClasses}>\n {children}\n {renderLink()}\n </div>\n </div>\n </PopOver>\n );\n});\n\nHelpBubble.displayName = 'HelpBubble';\n\nexport default HelpBubble;\n"],"names":["HelpBubbleVariant","PopOverVariant","HelpBubble","React","props","ref","children","className","noCloseButton","linkText","linkUrl","onLinkClick","onClose","closeAriaLabel","showBubble","helpBubbleId","variant","controllerRef","role","testId","isTooltip","helpBubbleClasses","classNames","styles","contentClasses","renderLink","AnchorLink","renderCloseButton","Close","PopOver","AnalyticsId","HelpBubble$1"],"mappings":"iQAWO,MAAMA,EAAoBC,EAmC3BC,EAAaC,EAAM,WAA4D,CAACC,EAAOC,IAAQ,CAC7F,KAAA,CACJ,SAAAC,EACA,UAAAC,EAAY,GACZ,cAAAC,EACA,SAAAC,EAAW,YACX,QAAAC,EACA,YAAAC,EACA,QAAAC,EACA,eAAAC,EAEA,WAAAC,EACA,aAAAC,EACA,QAAAC,EACA,cAAAC,EACA,KAAAC,EACA,OAAAC,CACE,EAAAf,EAEEgB,EAAYF,IAAS,UAEvB,GAAA,CAACJ,GAAc,CAACM,EACX,OAAA,KAGT,MAAMC,EAAoBC,EAAWC,EAAO,WAAYhB,CAAS,EAE3DiB,EAAiBF,EAAWC,EAAO,oBAAqB,CAC5D,CAACA,EAAO,4BAA4B,CAAC,EAAG,CAACf,GAAiB,CAACY,CAAA,CAC5D,EAEKK,EAAa,IAA+B,CAEhD,GAAI,CAAAL,EAGJ,IAAIT,GAAeF,EAEf,OAAAN,EAAA,cAAC,UAAO,UAAWoB,EAAO,iBAAkB,QAASZ,EAAa,KAAK,QAAA,EACpEF,CACH,EAEJ,GAAWC,GAAWD,EACpB,OAAQN,EAAA,cAAAuB,EAAA,CAAW,KAAMhB,CAAA,EAAUD,CAAS,EAC9C,EAGIkB,EAAoB,IAA+B,CACvD,GAAI,EAAAnB,GAAiBY,GAGrB,OACGjB,EAAA,cAAA,MAAA,CAAI,UAAWoB,EAAO,iBACrB,EAAApB,EAAA,cAACyB,EAAM,CAAA,MAAK,GAAC,QAAShB,EAAS,UAAWC,CAAgB,CAAA,CAC5D,CAAA,EAKF,OAAAV,EAAA,cAAC0B,EAAA,CACC,GAAId,EACJ,QAAAC,EACA,cAAAC,EACA,KAAAC,EACA,IAAAb,EACA,KAAMe,GAAaN,EACnB,OAAAK,CAAA,kBAEC,MAAI,CAAA,UAAWE,EAAmB,mBAAkBS,EAAY,YAC9DH,EACD,EAAAxB,EAAA,cAAC,OAAI,UAAWqB,GACblB,EACAmB,EAAA,CACH,CACF,CAAA,CAGN,CAAC,EAEDvB,EAAW,YAAc,aAEzB,MAAA6B,EAAe7B"}
|
package/HorizontalScroll.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HorizontalScroll.js","sources":["../src/components/HorizontalScroll/HorizontalScroll.tsx"],"sourcesContent":["import React, { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport { useIsVisible } from '../../hooks/useIsVisible';\nimport { useSize } from '../../hooks/useSize';\n\nimport styles from './styles.module.scss';\n\n// Scrolle-indikator vises/skjules når det er x px igjen til venstre eller høyre side\nconst ROOT_MARGIN_OFFSET = '3px';\n\ninterface HorizontalScrollProps {\n /**\n * Bredden på elementet som potensielt vil scrolle horisontalt i px\n */\n childWidth: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const HorizontalScroll: React.FC<HorizontalScrollProps> = ({ children, childWidth, testId }) => {\n const viewportRef = useRef<HTMLDivElement>(null);\n const leftRef = useRef<HTMLDivElement>(null);\n const rightRef = useRef<HTMLDivElement>(null);\n const leftIsVisible = useIsVisible(leftRef, 1, { root: viewportRef?.current, rootMargin: ROOT_MARGIN_OFFSET }, true);\n const rightIsVisible = useIsVisible(rightRef, 1, { root: viewportRef?.current, rootMargin: ROOT_MARGIN_OFFSET }, true);\n const { width: viewPortWidth = 0 } = useSize(viewportRef) || {};\n\n const isOverflowing = childWidth > viewPortWidth;\n const viewportClasses = classNames(styles.horizontalscroll__viewport, isOverflowing && styles['horizontalscroll__viewport--overflow']);\n\n return (\n <div className={styles.horizontalscroll} data-testid={testId}>\n <div className={viewportClasses} ref={viewportRef} tabIndex={0}>\n <div\n className={classNames(\n styles.horizontalscroll__indicator,\n styles['horizontalscroll__indicator--left'],\n !leftIsVisible && styles['horizontalscroll__indicator--visible']\n )}\n />\n <div\n className={classNames(\n styles.horizontalscroll__indicator,\n styles['horizontalscroll__indicator--right'],\n !rightIsVisible && styles['horizontalscroll__indicator--visible']\n )}\n />\n <div ref={leftRef} />\n {children}\n <div ref={rightRef} />\n </div>\n </div>\n );\n};\n\nexport default HorizontalScroll;\n"],"names":["ROOT_MARGIN_OFFSET","HorizontalScroll","children","childWidth","testId","viewportRef","useRef","leftRef","rightRef","leftIsVisible","useIsVisible","rightIsVisible","viewPortWidth","useSize","isOverflowing","viewportClasses","classNames","styles","React","HorizontalScroll$1"],"mappings":"gOAUA,MAAMA,EAAqB,MAWdC,EAAoD,CAAC,CAAE,SAAAC,EAAU,WAAAC,EAAY,OAAAC,KAAa,CAC/F,MAAAC,EAAcC,EAAuB,IAAI,EACzCC,EAAUD,EAAuB,IAAI,EACrCE,EAAWF,EAAuB,IAAI,EACtCG,EAAgBC,EAAaH,EAAS,EAAG,CAAE,KAAMF,GAAA,YAAAA,EAAa,QAAS,WAAYL,CAAmB,EAAG,EAAI,EAC7GW,EAAiBD,EAAaF,EAAU,EAAG,CAAE,KAAMH,GAAA,YAAAA,EAAa,QAAS,WAAYL,CAAmB,EAAG,EAAI,EAC/G,CAAE,MAAOY,EAAgB,GAAMC,EAAQR,CAAW,GAAK,GAEvDS,EAAgBX,EAAaS,EAC7BG,EAAkBC,EAAWC,EAAO,2BAA4BH,GAAiBG,EAAO,sCAAsC,CAAC,EAErI,OACGC,EAAA,cAAA,MAAA,CAAI,UAAWD,EAAO,iBAAkB,cAAab,
|
|
1
|
+
{"version":3,"file":"HorizontalScroll.js","sources":["../src/components/HorizontalScroll/HorizontalScroll.tsx"],"sourcesContent":["import React, { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport { useIsVisible } from '../../hooks/useIsVisible';\nimport { useSize } from '../../hooks/useSize';\n\nimport styles from './styles.module.scss';\n\n// Scrolle-indikator vises/skjules når det er x px igjen til venstre eller høyre side\nconst ROOT_MARGIN_OFFSET = '3px';\n\ninterface HorizontalScrollProps {\n /**\n * Bredden på elementet som potensielt vil scrolle horisontalt i px\n */\n childWidth: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const HorizontalScroll: React.FC<HorizontalScrollProps> = ({ children, childWidth, testId }) => {\n const viewportRef = useRef<HTMLDivElement>(null);\n const leftRef = useRef<HTMLDivElement>(null);\n const rightRef = useRef<HTMLDivElement>(null);\n const leftIsVisible = useIsVisible(leftRef, 1, { root: viewportRef?.current, rootMargin: ROOT_MARGIN_OFFSET }, true);\n const rightIsVisible = useIsVisible(rightRef, 1, { root: viewportRef?.current, rootMargin: ROOT_MARGIN_OFFSET }, true);\n const { width: viewPortWidth = 0 } = useSize(viewportRef) || {};\n\n const isOverflowing = childWidth > viewPortWidth;\n const viewportClasses = classNames(styles.horizontalscroll__viewport, isOverflowing && styles['horizontalscroll__viewport--overflow']);\n\n return (\n <div className={styles.horizontalscroll} data-testid={testId}>\n {/* viewport-diven må ta tabIndex for å løse et annet UU-problem, at div med overflow: scroll må kunne navigeres med keyboard. */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */}\n <div className={viewportClasses} ref={viewportRef} tabIndex={0}>\n <div\n className={classNames(\n styles.horizontalscroll__indicator,\n styles['horizontalscroll__indicator--left'],\n !leftIsVisible && styles['horizontalscroll__indicator--visible']\n )}\n />\n <div\n className={classNames(\n styles.horizontalscroll__indicator,\n styles['horizontalscroll__indicator--right'],\n !rightIsVisible && styles['horizontalscroll__indicator--visible']\n )}\n />\n <div ref={leftRef} />\n {children}\n <div ref={rightRef} />\n </div>\n </div>\n );\n};\n\nexport default HorizontalScroll;\n"],"names":["ROOT_MARGIN_OFFSET","HorizontalScroll","children","childWidth","testId","viewportRef","useRef","leftRef","rightRef","leftIsVisible","useIsVisible","rightIsVisible","viewPortWidth","useSize","isOverflowing","viewportClasses","classNames","styles","React","HorizontalScroll$1"],"mappings":"gOAUA,MAAMA,EAAqB,MAWdC,EAAoD,CAAC,CAAE,SAAAC,EAAU,WAAAC,EAAY,OAAAC,KAAa,CAC/F,MAAAC,EAAcC,EAAuB,IAAI,EACzCC,EAAUD,EAAuB,IAAI,EACrCE,EAAWF,EAAuB,IAAI,EACtCG,EAAgBC,EAAaH,EAAS,EAAG,CAAE,KAAMF,GAAA,YAAAA,EAAa,QAAS,WAAYL,CAAmB,EAAG,EAAI,EAC7GW,EAAiBD,EAAaF,EAAU,EAAG,CAAE,KAAMH,GAAA,YAAAA,EAAa,QAAS,WAAYL,CAAmB,EAAG,EAAI,EAC/G,CAAE,MAAOY,EAAgB,GAAMC,EAAQR,CAAW,GAAK,GAEvDS,EAAgBX,EAAaS,EAC7BG,EAAkBC,EAAWC,EAAO,2BAA4BH,GAAiBG,EAAO,sCAAsC,CAAC,EAErI,OACGC,EAAA,cAAA,MAAA,CAAI,UAAWD,EAAO,iBAAkB,cAAab,GAGnDc,EAAA,cAAA,MAAA,CAAI,UAAWH,EAAiB,IAAKV,EAAa,SAAU,GAC3Da,EAAA,cAAC,MAAA,CACC,UAAWF,EACTC,EAAO,4BACPA,EAAO,mCAAmC,EAC1C,CAACR,GAAiBQ,EAAO,sCAAsC,CACjE,CAAA,CAEF,EAAAC,EAAA,cAAC,MAAA,CACC,UAAWF,EACTC,EAAO,4BACPA,EAAO,oCAAoC,EAC3C,CAACN,GAAkBM,EAAO,sCAAsC,CAClE,CAAA,CAAA,EAEFC,EAAA,cAAC,MAAI,CAAA,IAAKX,CAAS,CAAA,EAClBL,EACDgB,EAAA,cAAC,MAAI,CAAA,IAAKV,CAAU,CAAA,CACtB,CACF,CAEJ,EAEAW,EAAelB"}
|
package/Input.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import r,{useRef as le,useState as ie}from"react";import d from"classnames";import{FormMode as m,FormVariant as ce,IconSize as y,AnalyticsId as se,AVERAGE_CHARACTER_WIDTH_PX as pe}from"./constants.js";import{useBreakpoint as de,Breakpoint as me}from"./hooks/useBreakpoint.js";import{getColor as A}from"./theme/currys/color.js";import{a as ue}from"./uuid.js";import{E as be}from"./ErrorWrapper.js";import{Icon as fe}from"./components/Icons/Icon.js";import{M as he}from"./MaxCharacters.js";import e from"./components/Input/styles.module.scss";var we=(t=>(t.text="text",t.number="number",t.email="email",t.password="password",t.search="search",t.tel="tel",t.url="url",t.date="date",t.time="time",t))(we||{});const Ce=(t,l,u)=>{const i=l?"1.5rem":"2rem",b=l?`${u}px`:"0px",f="4px";return`calc(${t*pe}px + ${i} + ${b} + ${f})`},F=r.forwardRef((t,l)=>{const{className:u,defaultValue:i,placeholder:b,type:f="text",inputId:g=ue(),labelId:M,name:z,transparent:B=!1,icon:a,iconRight:h,mode:n,variant:D,label:x,error:V,errorText:E,testId:H,disabled:o,readOnly:L,autoComplete:X,afterLabelChildren:_,afterInputChildren:q,belowLabelChildren:v,width:k,required:G,onChange:W,onKeyDown:K,autoFocus:O,maxCharacters:c,maxText:P,...j}=t,J=de(),s=le(null),[I,Q]=ie(i||""),N=n===m.ondark,U=n===m.onblueberry,Y=!!c&&I.toString().length>c,w=n===m.oninvalid||!!E||!!V||Y,C=D===ce.bigform,Z=B&&n!==m.ondark&&!w,T=d(e["input-wrapper"],u),ee=d(e["input-wrapper__label-wrapper"],{[e["input-wrapper__label-wrapper--on-dark"]]:N,[e["input-wrapper__label-wrapper--disabled"]]:o}),te=d(e["content-wrapper"],{[e["content-wrapper--transparent"]]:Z,[e["content-wrapper--on-blueberry"]]:U,[e["content-wrapper--on-dark"]]:N,[e["content-wrapper--invalid"]]:w,[e["content-wrapper--bigform"]]:C,[e["content-wrapper--disabled"]]:o,[e["content-wrapper--with-icon"]]:a}),re=d(e["content-wrapper__input"],{[e["content-wrapper__input--bigform"]]:C,[e["content-wrapper__input--disabled"]]:o}),ae=o?A("neutral",500):A("black"),R=J===me.xs||!C?y.XSmall:y.Small,S=()=>a!==void 0?r.createElement(fe,{color:ae,size:R,svgIcon:a}):null,ne=()=>{if(s&&s.current&&a){const p=h?0:1;s.current.children[p].focus()}},oe=p=>{W&&W(p),Q(p.target.value)},$=k?Ce(k,!!a,R):void 0;return r.createElement(be,{errorText:E},r.createElement("div",{"data-testid":H,"data-analyticsid":se.Input,className:T},x&&r.createElement("div",{className:ee},r.createElement("label",{id:M??void 0,htmlFor:g},x),_&&r.createElement("div",{className:e["input-wrapper__after-label-children"]},_)),v&&r.createElement("div",null,v),r.createElement("div",{onClick:ne,ref:s,className:te,style:{maxWidth:$}},!h&&S(),r.createElement("input",{onChange:oe,onKeyDown:K,name:z,type:f,defaultValue:i,id:g,className:re,ref:l,"aria-labelledby":t["aria-labelledby"]??void 0,"aria-invalid":!!w,disabled:o,placeholder:b,readOnly:L,autoComplete:X||"off",required:G,autoFocus:O,...j}),h&&S()),c&&r.createElement(he,{maxCharacters:c,length:I.toString().length,maxText:P,mode:n,maxWidth:$}),q))});F.displayName="Input";const $e=F;export{$e as I,we as a};
|
|
2
2
|
//# sourceMappingURL=Input.js.map
|
package/Input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.js","sources":["../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useRef, useState } from 'react';\n\nimport cn from 'classnames';\n\nimport { FormMode, FormVariant, AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX } from '../../constants';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { getColor } from '../../theme/currys';\nimport { uuid } from '../../utils/uuid';\nimport ErrorWrapper from '../ErrorWrapper';\nimport Icon, { IconSize, SvgIcon } from '../Icons';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\nexport interface InputProps\n extends Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'disabled'\n | 'readOnly'\n | 'autoComplete'\n | 'name'\n | 'placeholder'\n | 'defaultValue'\n | 'required'\n | 'value'\n | 'min'\n | 'max'\n | 'aria-labelledby'\n | 'onChange'\n | 'onKeyDown'\n | 'autoFocus'\n > {\n /** Adds custom classes to the element. */\n className?: string;\n /** HMTL Input type */\n type?: keyof typeof InputTypes;\n /** input id */\n inputId?: string;\n /** label id */\n labelId?: string;\n /** Width of input field in characters (approximate) */\n width?: number;\n /** If true, the component will be transparent. */\n transparent?: boolean;\n /** Icon to be displayed next to the input field */\n icon?: SvgIcon;\n /** Places the icon to the right */\n iconRight?: boolean;\n /** Changes the color profile of the input */\n mode?: keyof typeof FormMode;\n /** Changes the visuals of the input */\n variant?: keyof typeof FormVariant;\n /** Label of the input */\n label?: string;\n /** Activates Error style for the input */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Component shown after label */\n afterLabelChildren?: React.ReactNode;\n /** Component shown after input */\n afterInputChildren?: React.ReactNode;\n /** Component shown under label */\n belowLabelChildren?: React.ReactNode;\n /** max character limit in input */\n maxCharacters?: number;\n /** The text is displayed in the end of the text-counter */\n maxText?: string;\n}\n\nexport enum InputTypes {\n text = 'text',\n number = 'number',\n email = 'email',\n password = 'password',\n search = 'search',\n tel = 'tel',\n url = 'url',\n date = 'date',\n time = 'time',\n}\n\nconst getInputMaxWidth = (characters: number, hasIcon: boolean, iconSize: number): string => {\n const paddingWidth = hasIcon ? '1.5rem' : '2rem';\n const iconWidth = hasIcon ? `${iconSize}px` : '0px';\n const borderWidth = '4px';\n\n return `calc(${characters * AVERAGE_CHARACTER_WIDTH_PX}px + ${paddingWidth} + ${iconWidth} + ${borderWidth})`;\n};\n\nconst Input = React.forwardRef((props: InputProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n className,\n defaultValue,\n placeholder,\n type = InputTypes.text,\n inputId = uuid(),\n labelId,\n name,\n transparent = false,\n icon,\n iconRight,\n mode,\n variant,\n label,\n error,\n errorText,\n testId,\n disabled,\n readOnly,\n autoComplete,\n afterLabelChildren,\n afterInputChildren,\n belowLabelChildren,\n width,\n required,\n onChange,\n onKeyDown,\n autoFocus,\n maxCharacters,\n maxText,\n ...rest\n } = props;\n const breakpoint = useBreakpoint();\n const contentWrapperRef = useRef<HTMLDivElement>(null);\n const [input, setInput] = useState(defaultValue || '');\n\n const onDark = mode === FormMode.ondark;\n const onBlueberry = mode === FormMode.onblueberry;\n const maxCharactersExceeded = !!maxCharacters && input.toString().length > maxCharacters;\n const onError = mode === FormMode.oninvalid || !!errorText || !!error || maxCharactersExceeded;\n const bigForm = variant === FormVariant.bigform;\n const isTransparent = transparent && mode !== FormMode.ondark && !onError;\n\n const inputWrapperClass = cn(styles['input-wrapper'], className);\n\n const labelWrapperClass = cn(styles['input-wrapper__label-wrapper'], {\n [styles['input-wrapper__label-wrapper--on-dark']]: onDark,\n [styles['input-wrapper__label-wrapper--disabled']]: disabled,\n });\n\n const contentWrapperClass = cn(styles['content-wrapper'], {\n [styles['content-wrapper--transparent']]: isTransparent,\n [styles['content-wrapper--on-blueberry']]: onBlueberry,\n [styles['content-wrapper--on-dark']]: onDark,\n [styles['content-wrapper--invalid']]: onError,\n [styles['content-wrapper--bigform']]: bigForm,\n [styles['content-wrapper--disabled']]: disabled,\n [styles['content-wrapper--with-icon']]: icon,\n });\n\n const inputClass = cn(styles['content-wrapper__input'], {\n [styles['content-wrapper__input--bigform']]: bigForm,\n [styles['content-wrapper__input--disabled']]: disabled,\n });\n\n const iconColor = disabled ? getColor('neutral', 500) : getColor('black');\n const iconSize = breakpoint === Breakpoint.xs || !bigForm ? IconSize.XSmall : IconSize.Small;\n\n const renderIcon = () => {\n return icon !== undefined ? <Icon color={iconColor} size={iconSize} svgIcon={icon} /> : null;\n };\n\n const handleClick = (): void => {\n if (contentWrapperRef && contentWrapperRef.current && icon) {\n const selectedChild = iconRight ? 0 : 1;\n const input = contentWrapperRef.current.children[selectedChild] as HTMLInputElement;\n input.focus();\n }\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n setInput(e.target.value);\n };\n\n const onChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (onChange) {\n onChange(e);\n }\n handleChange(e);\n };\n\n const maxWidth = width ? getInputMaxWidth(width, !!icon, iconSize) : undefined;\n\n return (\n <ErrorWrapper errorText={errorText}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Input} className={inputWrapperClass}>\n {label && (\n <div className={labelWrapperClass}>\n <label id={labelId ?? undefined} htmlFor={inputId}>\n {label}\n </label>\n {afterLabelChildren && <div className={styles['input-wrapper__after-label-children']}>{afterLabelChildren}</div>}\n </div>\n )}\n {belowLabelChildren && <div>{belowLabelChildren}</div>}\n\n <div onClick={handleClick} ref={contentWrapperRef} className={contentWrapperClass} style={{ maxWidth }}>\n {!iconRight && renderIcon()}\n <input\n onChange={onChangeHandler}\n onKeyDown={onKeyDown}\n name={name}\n type={type}\n defaultValue={defaultValue}\n id={inputId}\n className={inputClass}\n ref={ref}\n aria-labelledby={props['aria-labelledby'] ?? undefined}\n aria-invalid={!!onError}\n disabled={disabled}\n placeholder={placeholder}\n readOnly={readOnly}\n autoComplete={autoComplete || 'off'}\n required={required}\n autoFocus={autoFocus}\n {...rest}\n />\n {iconRight && renderIcon()}\n </div>\n {maxCharacters && (\n <MaxCharacters maxCharacters={maxCharacters} length={input.toString().length} maxText={maxText} mode={mode} maxWidth={maxWidth} />\n )}\n {afterInputChildren}\n </div>\n </ErrorWrapper>\n );\n});\n\nexport default Input;\n"],"names":["InputTypes","getInputMaxWidth","characters","hasIcon","iconSize","paddingWidth","iconWidth","borderWidth","AVERAGE_CHARACTER_WIDTH_PX","Input","React","props","ref","className","defaultValue","placeholder","type","inputId","uuid","labelId","name","transparent","icon","iconRight","mode","variant","label","error","errorText","testId","disabled","readOnly","autoComplete","afterLabelChildren","afterInputChildren","belowLabelChildren","width","required","onChange","onKeyDown","autoFocus","maxCharacters","maxText","rest","breakpoint","useBreakpoint","contentWrapperRef","useRef","input","setInput","useState","onDark","FormMode","onBlueberry","maxCharactersExceeded","onError","bigForm","FormVariant","isTransparent","inputWrapperClass","cn","styles","labelWrapperClass","contentWrapperClass","inputClass","iconColor","getColor","Breakpoint","IconSize","renderIcon","Icon","handleClick","selectedChild","handleChange","e","onChangeHandler","maxWidth","ErrorWrapper","AnalyticsId","MaxCharacters","Input$1"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Input.js","sources":["../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useRef, useState } from 'react';\n\nimport cn from 'classnames';\n\nimport { FormMode, FormVariant, AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX } from '../../constants';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { getColor } from '../../theme/currys';\nimport { uuid } from '../../utils/uuid';\nimport ErrorWrapper from '../ErrorWrapper';\nimport Icon, { IconSize, SvgIcon } from '../Icons';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\nexport interface InputProps\n extends Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'disabled'\n | 'readOnly'\n | 'autoComplete'\n | 'name'\n | 'placeholder'\n | 'defaultValue'\n | 'required'\n | 'value'\n | 'min'\n | 'max'\n | 'aria-labelledby'\n | 'onChange'\n | 'onKeyDown'\n | 'autoFocus'\n > {\n /** Adds custom classes to the element. */\n className?: string;\n /** HMTL Input type */\n type?: keyof typeof InputTypes;\n /** input id */\n inputId?: string;\n /** label id */\n labelId?: string;\n /** Width of input field in characters (approximate) */\n width?: number;\n /** If true, the component will be transparent. */\n transparent?: boolean;\n /** Icon to be displayed next to the input field */\n icon?: SvgIcon;\n /** Places the icon to the right */\n iconRight?: boolean;\n /** Changes the color profile of the input */\n mode?: keyof typeof FormMode;\n /** Changes the visuals of the input */\n variant?: keyof typeof FormVariant;\n /** Label of the input */\n label?: string;\n /** Activates Error style for the input */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Component shown after label */\n afterLabelChildren?: React.ReactNode;\n /** Component shown after input */\n afterInputChildren?: React.ReactNode;\n /** Component shown under label */\n belowLabelChildren?: React.ReactNode;\n /** max character limit in input */\n maxCharacters?: number;\n /** The text is displayed in the end of the text-counter */\n maxText?: string;\n}\n\nexport enum InputTypes {\n text = 'text',\n number = 'number',\n email = 'email',\n password = 'password',\n search = 'search',\n tel = 'tel',\n url = 'url',\n date = 'date',\n time = 'time',\n}\n\nconst getInputMaxWidth = (characters: number, hasIcon: boolean, iconSize: number): string => {\n const paddingWidth = hasIcon ? '1.5rem' : '2rem';\n const iconWidth = hasIcon ? `${iconSize}px` : '0px';\n const borderWidth = '4px';\n\n return `calc(${characters * AVERAGE_CHARACTER_WIDTH_PX}px + ${paddingWidth} + ${iconWidth} + ${borderWidth})`;\n};\n\nconst Input = React.forwardRef((props: InputProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n className,\n defaultValue,\n placeholder,\n type = InputTypes.text,\n inputId = uuid(),\n labelId,\n name,\n transparent = false,\n icon,\n iconRight,\n mode,\n variant,\n label,\n error,\n errorText,\n testId,\n disabled,\n readOnly,\n autoComplete,\n afterLabelChildren,\n afterInputChildren,\n belowLabelChildren,\n width,\n required,\n onChange,\n onKeyDown,\n autoFocus,\n maxCharacters,\n maxText,\n ...rest\n } = props;\n const breakpoint = useBreakpoint();\n const contentWrapperRef = useRef<HTMLDivElement>(null);\n const [input, setInput] = useState(defaultValue || '');\n\n const onDark = mode === FormMode.ondark;\n const onBlueberry = mode === FormMode.onblueberry;\n const maxCharactersExceeded = !!maxCharacters && input.toString().length > maxCharacters;\n const onError = mode === FormMode.oninvalid || !!errorText || !!error || maxCharactersExceeded;\n const bigForm = variant === FormVariant.bigform;\n const isTransparent = transparent && mode !== FormMode.ondark && !onError;\n\n const inputWrapperClass = cn(styles['input-wrapper'], className);\n\n const labelWrapperClass = cn(styles['input-wrapper__label-wrapper'], {\n [styles['input-wrapper__label-wrapper--on-dark']]: onDark,\n [styles['input-wrapper__label-wrapper--disabled']]: disabled,\n });\n\n const contentWrapperClass = cn(styles['content-wrapper'], {\n [styles['content-wrapper--transparent']]: isTransparent,\n [styles['content-wrapper--on-blueberry']]: onBlueberry,\n [styles['content-wrapper--on-dark']]: onDark,\n [styles['content-wrapper--invalid']]: onError,\n [styles['content-wrapper--bigform']]: bigForm,\n [styles['content-wrapper--disabled']]: disabled,\n [styles['content-wrapper--with-icon']]: icon,\n });\n\n const inputClass = cn(styles['content-wrapper__input'], {\n [styles['content-wrapper__input--bigform']]: bigForm,\n [styles['content-wrapper__input--disabled']]: disabled,\n });\n\n const iconColor = disabled ? getColor('neutral', 500) : getColor('black');\n const iconSize = breakpoint === Breakpoint.xs || !bigForm ? IconSize.XSmall : IconSize.Small;\n\n const renderIcon = (): React.ReactNode => {\n return icon !== undefined ? <Icon color={iconColor} size={iconSize} svgIcon={icon} /> : null;\n };\n\n const handleClick = (): void => {\n if (contentWrapperRef && contentWrapperRef.current && icon) {\n const selectedChild = iconRight ? 0 : 1;\n const input = contentWrapperRef.current.children[selectedChild] as HTMLInputElement;\n input.focus();\n }\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n if (onChange) {\n onChange(e);\n }\n setInput(e.target.value);\n };\n\n const maxWidth = width ? getInputMaxWidth(width, !!icon, iconSize) : undefined;\n\n return (\n <ErrorWrapper errorText={errorText}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Input} className={inputWrapperClass}>\n {label && (\n <div className={labelWrapperClass}>\n <label id={labelId ?? undefined} htmlFor={inputId}>\n {label}\n </label>\n {afterLabelChildren && <div className={styles['input-wrapper__after-label-children']}>{afterLabelChildren}</div>}\n </div>\n )}\n {belowLabelChildren && <div>{belowLabelChildren}</div>}\n\n {/* input-elementet tillater keyboard-interaksjon */}\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}\n <div onClick={handleClick} ref={contentWrapperRef} className={contentWrapperClass} style={{ maxWidth }}>\n {!iconRight && renderIcon()}\n <input\n onChange={handleChange}\n onKeyDown={onKeyDown}\n name={name}\n type={type}\n defaultValue={defaultValue}\n id={inputId}\n className={inputClass}\n ref={ref}\n aria-labelledby={props['aria-labelledby'] ?? undefined}\n aria-invalid={!!onError}\n disabled={disabled}\n placeholder={placeholder}\n readOnly={readOnly}\n autoComplete={autoComplete || 'off'}\n required={required}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n {...rest}\n />\n {iconRight && renderIcon()}\n </div>\n {maxCharacters && (\n <MaxCharacters maxCharacters={maxCharacters} length={input.toString().length} maxText={maxText} mode={mode} maxWidth={maxWidth} />\n )}\n {afterInputChildren}\n </div>\n </ErrorWrapper>\n );\n});\n\nInput.displayName = 'Input';\n\nexport default Input;\n"],"names":["InputTypes","getInputMaxWidth","characters","hasIcon","iconSize","paddingWidth","iconWidth","borderWidth","AVERAGE_CHARACTER_WIDTH_PX","Input","React","props","ref","className","defaultValue","placeholder","type","inputId","uuid","labelId","name","transparent","icon","iconRight","mode","variant","label","error","errorText","testId","disabled","readOnly","autoComplete","afterLabelChildren","afterInputChildren","belowLabelChildren","width","required","onChange","onKeyDown","autoFocus","maxCharacters","maxText","rest","breakpoint","useBreakpoint","contentWrapperRef","useRef","input","setInput","useState","onDark","FormMode","onBlueberry","maxCharactersExceeded","onError","bigForm","FormVariant","isTransparent","inputWrapperClass","cn","styles","labelWrapperClass","contentWrapperClass","inputClass","iconColor","getColor","Breakpoint","IconSize","renderIcon","Icon","handleClick","selectedChild","handleChange","e","maxWidth","ErrorWrapper","AnalyticsId","MaxCharacters","Input$1"],"mappings":"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"}
|
package/ListHeader.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import n from"react";import h from"classnames";import{L as A}from"./ListHeaderText.js";import{useBreakpoint as k,Breakpoint as B}from"./hooks/useBreakpoint.js";import{isComponent as u,isComponentWithChildren as b}from"./utils/component.js";import{A as R,a as w}from"./Avatar.js";import{B as X}from"./Badge.js";import{Icon as M}from"./components/Icons/Icon.js";import{IconSize as C}from"./constants.js";import t from"./components/ListHeader/styles.module.scss";const P=(l,f,c,m,o,i)=>{if(u(l,E))return n.cloneElement(l,{chevronIcon:o,icon:i,isHovered:c,size:m});if(l)return n.createElement(E,{titleHtmlMarkup:f,chevronIcon:o,icon:i,isHovered:c,size:m},l)},N=(l,f=!1)=>{var d,v,_,s;let c,m;const o=[],i=[],a=[];n.Children.forEach(l,e=>{e===null||typeof e>"u"||(u(e,R)?c=e:u(e,A)?o.push(e):u(e,X)?m=e:typeof e=="string"?i.push(e):a.push(e))});const g=c!==void 0||o.length>0||m!==void 0&&i.length>0,r=a.length===0||b(a[0])&&typeof((v=(d=a[0])==null?void 0:d.props)==null?void 0:v.children)>"u";if(f||g||r)return{avatarChild:c,listHeaderTextChildren:o,badgeChild:m,stringChildren:i,remainingChildren:a};if(b(a[0]))return N((s=(_=a[0])==null?void 0:_.props)==null?void 0:s.children,!0)},E=n.forwardRef((l,f)=>{const{className:c="",titleHtmlMarkup:m="h2",chevronIcon:o,children:i,icon:a,isHovered:g,size:r,testId:d}=l,v=k(),_=r!=="small"&&!!(o||a),s=typeof i=="string",e=N(i),H=(e==null?void 0:e.avatarChild)||(e==null?void 0:e.listHeaderTextChildren)&&e.listHeaderTextChildren.length>0||(e==null?void 0:e.remainingChildren)&&(e==null?void 0:e.remainingChildren.length)>0,x=h(t["list-header"],{[t["list-header--for-element-content"]]:!s,[t["list-header--top-align-content"]]:H},c),L=h(t["list-header__badge"],{[t["list-header__badge--for-string-content"]]:s,[t["list-header__badge--right"]]:!s,[t["list-header__badge--"+r]]:!s&&r}),S=h(t["list-header__chevron"],{[t["list-header__chevron--for-string-content"]]:s,[t["list-header__chevron--"+r]]:!s&&r}),y=h(t["list-header__content"],{[t["list-header__content--string"]]:s,[t["list-header__content--element"]]:!s,[t["list-header__content--spacing"]]:!(e!=null&&e.avatarChild)&&!a}),I=h(t["list-header__icon"],{[t["list-header__icon--for-string-content"]]:s,[t["list-header__icon--for-element-content"]]:!s,[t["list-header__icon--for-element-content--"+r]]:!s&&r}),T=h(t["list-header__avatar"],{[t["list-header__avatar--for-string-content"]]:s,[t["list-header__avatar--for-element-content"]]:!s,[t["list-header__avatar--for-element-content--"+r]]:!s&&r}),z=m;return n.createElement("div",{"data-testid":d,className:x},_&&a&&n.createElement("span",{className:I},n.cloneElement(a,{size:v===B.xs?C.XSmall:C.Small,isHovered:g})),r!=="small"&&(e==null?void 0:e.avatarChild)&&n.createElement("span",{className:T},n.cloneElement(e.avatarChild,{size:w.xsmall})),n.createElement("div",{className:y},e==null?void 0:e.listHeaderTextChildren,!!(e!=null&&e.stringChildren.length)&&n.createElement(z,{className:t["list-header__title"]},e.stringChildren),e==null?void 0:e.remainingChildren),(e==null?void 0:e.badgeChild)&&n.createElement("span",{className:L},e.badgeChild),_&&o&&n.createElement("span",{className:S},n.createElement(M,{svgIcon:o,isHovered:g,size:C.XSmall})))});E.displayName="ListHeader";export{E as L,N as m,P as r};
|
|
2
2
|
//# sourceMappingURL=ListHeader.js.map
|
package/ListHeader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListHeader.js","sources":["../src/components/ListHeader/ListHeader.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport ListHeaderText, { ListHeaderTextProps, ListHeaderTextType } from './ListHeaderText/ListHeaderText';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { isComponent } from '../../utils/component';\nimport Avatar, { AvatarProps, AvatarSize, AvatarType } from '../Avatar';\nimport Badge, { BadgeProps, BadgeType } from '../Badge';\nimport Icon, { IconSize, SvgIcon } from '../Icons';\nimport { TitleTags } from '../Title';\n\nimport styles from './styles.module.scss';\n\nexport type ListHeaderSize = 'small' | 'medium' | 'large';\n\nexport interface ListHeaderType extends React.ForwardRefExoticComponent<ListHeaderProps & React.RefAttributes<HTMLLIElement>> {\n Avatar?: AvatarType;\n Badge?: BadgeType;\n ListHeaderText?: ListHeaderTextType;\n}\n\nexport const renderListHeader = (\n element: React.ReactNode,\n titleHtmlMarkup: TitleTags,\n isHovered: boolean,\n size: ListHeaderSize,\n chevronIcon?: SvgIcon,\n icon?: React.ReactElement\n): JSX.Element | undefined => {\n if (isComponent<ListHeaderProps>(element, ListHeader)) {\n return React.cloneElement(element, {\n chevronIcon,\n icon,\n isHovered,\n size,\n });\n }\n if (element) {\n return (\n <ListHeader titleHtmlMarkup={titleHtmlMarkup} chevronIcon={chevronIcon} icon={icon} isHovered={isHovered} size={size}>\n {element}\n </ListHeader>\n );\n }\n};\n\nexport interface ListHeaderProps {\n /** Adds custom classes to the ListHeader element. */\n className?: string;\n /** Chevron to render inside of the ListHeader */\n chevronIcon?: SvgIcon;\n /** Children to be rendered inside of ListHeader */\n children: React.ReactNode;\n /** Changes the underlying element of the title. Default: h2*/\n titleHtmlMarkup?: TitleTags;\n /** icon to be rendered inside of ListHeader */\n icon?: React.ReactElement;\n /** whether or not the parent is hovered */\n isHovered?: boolean;\n /** Changes size of the ListHeader. */\n size?: ListHeaderSize;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const mapChildren = (\n children: React.ReactNode,\n isJsxChild = false\n): {\n avatarChild?: React.ReactElement<AvatarProps>;\n listHeaderTextChildren: Array<React.ReactElement<ListHeaderTextProps>>;\n badgeChild?: React.ReactElement<BadgeProps>;\n stringChildren: Array<string>;\n remainingChildren: Array<any>;\n} => {\n let avatarChild: React.ReactElement<AvatarProps> | undefined;\n let badgeChild: React.ReactElement<BadgeProps> | undefined;\n const listHeaderTextChildren: Array<React.ReactElement<ListHeaderTextProps>> = [];\n const stringChildren: Array<string> = [];\n const remainingChildren: Array<any> = [];\n\n React.Children.forEach(children, child => {\n if (child === null || typeof child === 'undefined') return;\n if (isComponent<AvatarProps>(child, Avatar)) {\n avatarChild = child;\n } else if (isComponent<ListHeaderTextProps>(child, ListHeaderText)) {\n listHeaderTextChildren.push(child);\n } else if (isComponent<BadgeProps>(child, Badge)) {\n badgeChild = child;\n } else if (typeof child === 'string') {\n stringChildren.push(child);\n } else {\n remainingChildren.push(child);\n }\n });\n\n // Dette og recursive mapChildren under(gjøres en gang) er for å passe på at jsx children også sjekkes for Avatar og liknende innhold.\n // Slik opprettholder vi stylingen i tilfeller hvor vertikaler har wrappet elementer i en parent span eller div.\n const hasSpecialChildren =\n avatarChild !== undefined || listHeaderTextChildren.length > 0 || (badgeChild !== undefined && stringChildren.length > 0);\n const noRemainingRecursiveChildren = remainingChildren.length === 0 || typeof remainingChildren[0]?.props?.children === 'undefined';\n\n return isJsxChild || hasSpecialChildren || noRemainingRecursiveChildren\n ? { avatarChild, listHeaderTextChildren, badgeChild, stringChildren, remainingChildren }\n : mapChildren(remainingChildren[0]?.props?.children, true);\n};\n\nexport const ListHeader: ListHeaderType = React.forwardRef((props: ListHeaderProps, ref: React.Ref<HTMLLIElement>) => {\n const { className = '', titleHtmlMarkup = 'h2', chevronIcon, children, icon, isHovered, size, testId } = props;\n const breakpoint = useBreakpoint();\n const showChevronAndIcon = size !== 'small' && !!(chevronIcon || icon);\n const contentIsString = typeof children === 'string';\n const mappedChildren = mapChildren(children);\n const topAlignContent =\n mappedChildren.avatarChild ||\n (mappedChildren.listHeaderTextChildren && mappedChildren.listHeaderTextChildren.length > 0) ||\n (mappedChildren.remainingChildren && mappedChildren.remainingChildren.length > 0);\n\n const listLabelClasses = cn(\n styles['list-header'],\n {\n [styles['list-header--for-element-content']]: !contentIsString,\n [styles['list-header--top-align-content']]: topAlignContent,\n },\n className\n );\n const badgeClasses = cn(styles['list-header__badge'], {\n [styles['list-header__badge--for-string-content']]: contentIsString,\n [styles['list-header__badge--right']]: !contentIsString,\n [styles['list-header__badge--' + size]]: !contentIsString && size,\n });\n const chevronClasses = cn(styles['list-header__chevron'], {\n [styles['list-header__chevron--for-string-content']]: contentIsString,\n [styles['list-header__chevron--' + size]]: !contentIsString && size,\n });\n const contentClasses = cn(styles['list-header__content'], {\n [styles['list-header__content--string']]: contentIsString,\n [styles['list-header__content--element']]: !contentIsString,\n [styles['list-header__content--spacing']]: !mappedChildren.avatarChild && !icon,\n });\n const iconClasses = cn(styles['list-header__icon'], {\n [styles['list-header__icon--for-string-content']]: contentIsString,\n [styles['list-header__icon--for-element-content']]: !contentIsString,\n [styles['list-header__icon--for-element-content--' + size]]: !contentIsString && size,\n });\n const avatarClasses = cn(styles['list-header__avatar'], {\n [styles['list-header__avatar--for-string-content']]: contentIsString,\n [styles['list-header__avatar--for-element-content']]: !contentIsString,\n [styles['list-header__avatar--for-element-content--' + size]]: !contentIsString && size,\n });\n const CustomTag = titleHtmlMarkup;\n return (\n <div data-testid={testId} className={listLabelClasses}>\n {showChevronAndIcon && icon && (\n <span className={iconClasses}>\n {React.cloneElement(icon, {\n size: breakpoint === Breakpoint.xs ? IconSize.XSmall : IconSize.Small,\n isHovered,\n })}\n </span>\n )}\n {size !== 'small' && mappedChildren.avatarChild && (\n <span className={avatarClasses}>{React.cloneElement(mappedChildren.avatarChild, { size: AvatarSize.xsmall })}</span>\n )}\n <div className={contentClasses}>\n {mappedChildren.listHeaderTextChildren}\n {!!mappedChildren.stringChildren.length && (\n <CustomTag className={styles['list-header__title']}>{mappedChildren.stringChildren}</CustomTag>\n )}\n {mappedChildren.remainingChildren}\n </div>\n\n {mappedChildren.badgeChild && <span className={badgeClasses}>{mappedChildren.badgeChild}</span>}\n {showChevronAndIcon && chevronIcon && (\n <span className={chevronClasses}>\n <Icon svgIcon={chevronIcon} isHovered={isHovered} size={IconSize.XSmall} />\n </span>\n )}\n </div>\n );\n});\n\nexport default ListHeader;\n"],"names":["renderListHeader","element","titleHtmlMarkup","isHovered","size","chevronIcon","icon","isComponent","ListHeader","React","mapChildren","children","isJsxChild","avatarChild","badgeChild","listHeaderTextChildren","stringChildren","remainingChildren","child","Avatar","ListHeaderText","Badge","hasSpecialChildren","noRemainingRecursiveChildren","_b","_a","_d","_c","props","ref","className","testId","breakpoint","useBreakpoint","showChevronAndIcon","contentIsString","mappedChildren","topAlignContent","listLabelClasses","cn","styles","badgeClasses","chevronClasses","contentClasses","iconClasses","avatarClasses","CustomTag","Breakpoint","IconSize","AvatarSize","Icon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ListHeader.js","sources":["../src/components/ListHeader/ListHeader.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport ListHeaderText, { ListHeaderTextProps, ListHeaderTextType } from './ListHeaderText/ListHeaderText';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { isComponent, isComponentWithChildren } from '../../utils/component';\nimport Avatar, { AvatarProps, AvatarSize, AvatarType } from '../Avatar';\nimport Badge, { BadgeProps, BadgeType } from '../Badge';\nimport Icon, { IconSize, SvgIcon } from '../Icons';\nimport { TitleTags } from '../Title';\n\nimport styles from './styles.module.scss';\n\nexport type ListHeaderSize = 'small' | 'medium' | 'large';\n\nexport interface ListHeaderType extends React.ForwardRefExoticComponent<ListHeaderProps & React.RefAttributes<HTMLLIElement>> {\n Avatar?: AvatarType;\n Badge?: BadgeType;\n ListHeaderText?: ListHeaderTextType;\n}\n\nexport const renderListHeader = (\n element: React.ReactNode,\n titleHtmlMarkup: TitleTags,\n isHovered: boolean,\n size: ListHeaderSize,\n chevronIcon?: SvgIcon,\n icon?: React.ReactElement\n): JSX.Element | undefined => {\n if (isComponent<ListHeaderProps>(element, ListHeader)) {\n return React.cloneElement(element, {\n chevronIcon,\n icon,\n isHovered,\n size,\n });\n }\n if (element) {\n return (\n <ListHeader titleHtmlMarkup={titleHtmlMarkup} chevronIcon={chevronIcon} icon={icon} isHovered={isHovered} size={size}>\n {element}\n </ListHeader>\n );\n }\n};\n\nexport interface ListHeaderProps {\n /** Adds custom classes to the ListHeader element. */\n className?: string;\n /** Chevron to render inside of the ListHeader */\n chevronIcon?: SvgIcon;\n /** Children to be rendered inside of ListHeader */\n children: React.ReactNode;\n /** Changes the underlying element of the title. Default: h2*/\n titleHtmlMarkup?: TitleTags;\n /** icon to be rendered inside of ListHeader */\n icon?: React.ReactElement;\n /** whether or not the parent is hovered */\n isHovered?: boolean;\n /** Changes size of the ListHeader. */\n size?: ListHeaderSize;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\ninterface ListHeaderChildren {\n avatarChild?: React.ReactElement<AvatarProps>;\n listHeaderTextChildren: React.ReactElement<ListHeaderTextProps>[];\n badgeChild?: React.ReactElement<BadgeProps>;\n stringChildren: string[];\n remainingChildren: React.ReactNode[];\n}\n\ntype ChildrenMapper = (children: React.ReactNode, isJsxChild?: boolean) => ListHeaderChildren | undefined;\n\nexport const mapChildren: ChildrenMapper = (children, isJsxChild = false) => {\n let avatarChild: React.ReactElement<AvatarProps> | undefined;\n let badgeChild: React.ReactElement<BadgeProps> | undefined;\n const listHeaderTextChildren: React.ReactElement<ListHeaderTextProps>[] = [];\n const stringChildren: string[] = [];\n const remainingChildren: React.ReactNode[] = [];\n\n React.Children.forEach(children, child => {\n if (child === null || typeof child === 'undefined') return;\n if (isComponent<AvatarProps>(child, Avatar)) {\n avatarChild = child;\n } else if (isComponent<ListHeaderTextProps>(child, ListHeaderText)) {\n listHeaderTextChildren.push(child);\n } else if (isComponent<BadgeProps>(child, Badge)) {\n badgeChild = child;\n } else if (typeof child === 'string') {\n stringChildren.push(child);\n } else {\n remainingChildren.push(child);\n }\n });\n\n // Dette og recursive mapChildren under(gjøres en gang) er for å passe på at jsx children også sjekkes for Avatar og liknende innhold.\n // Slik opprettholder vi stylingen i tilfeller hvor vertikaler har wrappet elementer i en parent span eller div.\n const hasSpecialChildren =\n avatarChild !== undefined || listHeaderTextChildren.length > 0 || (badgeChild !== undefined && stringChildren.length > 0);\n const noRemainingRecursiveChildren =\n remainingChildren.length === 0 ||\n (isComponentWithChildren(remainingChildren[0]) && typeof remainingChildren[0]?.props?.children === 'undefined');\n\n if (isJsxChild || hasSpecialChildren || noRemainingRecursiveChildren) {\n return { avatarChild, listHeaderTextChildren, badgeChild, stringChildren, remainingChildren };\n }\n\n if (isComponentWithChildren(remainingChildren[0])) {\n return mapChildren(remainingChildren[0]?.props?.children, true);\n }\n};\n\nexport const ListHeader: ListHeaderType = React.forwardRef((props: ListHeaderProps, ref: React.Ref<HTMLLIElement>) => {\n const { className = '', titleHtmlMarkup = 'h2', chevronIcon, children, icon, isHovered, size, testId } = props;\n const breakpoint = useBreakpoint();\n const showChevronAndIcon = size !== 'small' && !!(chevronIcon || icon);\n const contentIsString = typeof children === 'string';\n const mappedChildren = mapChildren(children);\n const topAlignContent =\n mappedChildren?.avatarChild ||\n (mappedChildren?.listHeaderTextChildren && mappedChildren.listHeaderTextChildren.length > 0) ||\n (mappedChildren?.remainingChildren && mappedChildren?.remainingChildren.length > 0);\n\n const listLabelClasses = cn(\n styles['list-header'],\n {\n [styles['list-header--for-element-content']]: !contentIsString,\n [styles['list-header--top-align-content']]: topAlignContent,\n },\n className\n );\n const badgeClasses = cn(styles['list-header__badge'], {\n [styles['list-header__badge--for-string-content']]: contentIsString,\n [styles['list-header__badge--right']]: !contentIsString,\n [styles['list-header__badge--' + size]]: !contentIsString && size,\n });\n const chevronClasses = cn(styles['list-header__chevron'], {\n [styles['list-header__chevron--for-string-content']]: contentIsString,\n [styles['list-header__chevron--' + size]]: !contentIsString && size,\n });\n const contentClasses = cn(styles['list-header__content'], {\n [styles['list-header__content--string']]: contentIsString,\n [styles['list-header__content--element']]: !contentIsString,\n [styles['list-header__content--spacing']]: !mappedChildren?.avatarChild && !icon,\n });\n const iconClasses = cn(styles['list-header__icon'], {\n [styles['list-header__icon--for-string-content']]: contentIsString,\n [styles['list-header__icon--for-element-content']]: !contentIsString,\n [styles['list-header__icon--for-element-content--' + size]]: !contentIsString && size,\n });\n const avatarClasses = cn(styles['list-header__avatar'], {\n [styles['list-header__avatar--for-string-content']]: contentIsString,\n [styles['list-header__avatar--for-element-content']]: !contentIsString,\n [styles['list-header__avatar--for-element-content--' + size]]: !contentIsString && size,\n });\n const CustomTag = titleHtmlMarkup;\n return (\n <div data-testid={testId} className={listLabelClasses}>\n {showChevronAndIcon && icon && (\n <span className={iconClasses}>\n {React.cloneElement(icon, {\n size: breakpoint === Breakpoint.xs ? IconSize.XSmall : IconSize.Small,\n isHovered,\n })}\n </span>\n )}\n {size !== 'small' && mappedChildren?.avatarChild && (\n <span className={avatarClasses}>{React.cloneElement(mappedChildren.avatarChild, { size: AvatarSize.xsmall })}</span>\n )}\n <div className={contentClasses}>\n {mappedChildren?.listHeaderTextChildren}\n {!!mappedChildren?.stringChildren.length && (\n <CustomTag className={styles['list-header__title']}>{mappedChildren.stringChildren}</CustomTag>\n )}\n {mappedChildren?.remainingChildren}\n </div>\n\n {mappedChildren?.badgeChild && <span className={badgeClasses}>{mappedChildren.badgeChild}</span>}\n {showChevronAndIcon && chevronIcon && (\n <span className={chevronClasses}>\n <Icon svgIcon={chevronIcon} isHovered={isHovered} size={IconSize.XSmall} />\n </span>\n )}\n </div>\n );\n});\n\nListHeader.displayName = 'ListHeader';\n\nexport default ListHeader;\n"],"names":["renderListHeader","element","titleHtmlMarkup","isHovered","size","chevronIcon","icon","isComponent","ListHeader","React","mapChildren","children","isJsxChild","avatarChild","badgeChild","listHeaderTextChildren","stringChildren","remainingChildren","child","Avatar","ListHeaderText","Badge","hasSpecialChildren","noRemainingRecursiveChildren","isComponentWithChildren","_b","_a","_d","_c","props","ref","className","testId","breakpoint","useBreakpoint","showChevronAndIcon","contentIsString","mappedChildren","topAlignContent","listLabelClasses","cn","styles","badgeClasses","chevronClasses","contentClasses","iconClasses","avatarClasses","CustomTag","Breakpoint","IconSize","AvatarSize","Icon"],"mappings":"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"}
|
package/Modal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.js","sources":["../src/components/Modal/Modal.tsx"],"sourcesContent":["import React, { useEffect } from 'react';\n\nimport cn from 'classnames';\n\nimport { AnalyticsId, ZIndex } from '../../constants';\nimport useFocusTrap from '../../hooks/useFocusTrap';\nimport { useIsVisible } from '../../hooks/useIsVisible';\nimport { palette } from '../../theme/palette';\nimport { uuid } from '../../utils/uuid';\nimport Button from '../Button';\nimport Close from '../Close';\nimport Icon, { IconSize } from '../Icons';\nimport AlertSignFill from '../Icons/AlertSignFill';\nimport AlertSignStroke from '../Icons/AlertSignStroke';\nimport CheckOutline from '../Icons/CheckOutline';\nimport Portal from '../Portal';\nimport Title from '../Title/Title';\n\nimport styles from './styles.module.scss';\n\nexport enum ModalVariants {\n normal = 'normal',\n warning = 'warning',\n error = 'error',\n success = 'success',\n image = 'image',\n}\n\nexport enum ModalSize {\n large = 'large',\n medium = 'medium',\n}\n\nexport interface ModalProps {\n /** Title of the modal */\n title: string;\n /** id of the modal title */\n titleId?: string;\n /** Description of the modal. Will not render if the modal has children. */\n description?: string;\n /** Changes the visual representation of the modal */\n variant?: keyof typeof ModalVariants;\n /** Change width of the modal (default: large) */\n size?: keyof typeof ModalSize;\n /** Icon displayed in title */\n icon?: React.ReactElement;\n /** Hides the close button */\n noCloseButton?: boolean;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Primary button text */\n primaryButtonText?: string;\n /** Secondary button text */\n secondaryButtonText?: string;\n /** Sets the aria-label of the modal */\n ariaLabel?: string;\n /** Sets the aria-labelledby of the modal */\n ariaLabelledBy?: string;\n /** Close button aria-label */\n ariaLabelCloseBtn?: string;\n /** Alternative component to modal */\n children?: React.ReactNode;\n /** Component shown after title */\n afterTitleChildren?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Customize the z-index of the modal */\n zIndex?: number;\n /** Function is called when user clicks primary button */\n onSuccess?: () => void;\n /** Function is called when user clicks secondary button, clicks escape or outside the modal */\n onClose?: () => void;\n /** When enabled the component will be rendered in the bottom of document.body */\n printable?: boolean;\n /** If disabled, clicking escape or outside the modal will not close it */\n disableCloseEvents?: boolean;\n}\n\nconst defaultProps = {\n variant: ModalVariants.normal,\n primaryButtonText: 'OK',\n titleId: uuid(),\n className: '',\n size: ModalSize.large,\n zIndex: ZIndex.Modal,\n};\n\nconst getVariantIcon = (variant?: ModalProps['variant']): JSX.Element | null => {\n if (variant === ModalVariants.error) {\n return <Icon size={IconSize.Small} svgIcon={AlertSignFill} color={palette.cherry500} />;\n } else if (variant === ModalVariants.warning) {\n return <Icon size={IconSize.Small} svgIcon={AlertSignStroke} color={palette.black} />;\n } else if (variant === ModalVariants.success) {\n return <Icon size={IconSize.Small} svgIcon={CheckOutline} color={palette.kiwi900} />;\n }\n return null;\n};\n\nconst getIcon = (variant?: ModalProps['variant'], icon?: ModalProps['icon']): JSX.Element | null => {\n const variantIcon = getVariantIcon(variant);\n if (variantIcon) {\n return <div className={styles.modal__iconWrapper}>{variantIcon}</div>;\n }\n if (icon) {\n return (\n <div className={styles.modal__iconWrapper}>\n {React.cloneElement(icon, {\n size: IconSize.Small,\n })}\n </div>\n );\n }\n return null;\n};\n\nconst Modal = (props: ModalProps): JSX.Element => {\n const topContent = React.useRef<HTMLDivElement>(null);\n const modalContentRef = React.useRef<HTMLDivElement>(null);\n const dialogRef = React.useRef<HTMLDivElement>(null);\n useFocusTrap(dialogRef, true);\n const topContentVisible = useIsVisible(topContent);\n const bottomContent = React.useRef<HTMLDivElement>(null);\n const bottomContentVisible = useIsVisible(bottomContent);\n const contentIsScrollable = modalContentRef.current && modalContentRef.current.scrollHeight > modalContentRef.current.clientHeight;\n\n function handleKeyboardEvent(e: KeyboardEvent): void {\n if (e.key === 'Escape' && props.onClose) {\n e.stopPropagation();\n props.onClose();\n }\n }\n\n function handleClickEvent(event: MouseEvent): void {\n if (event.target && overlayRef.current === event.target && props.onClose) {\n event.stopPropagation();\n props.onClose();\n }\n }\n\n function disableBodyScroll(): void {\n document.body.style.overflow = 'hidden';\n }\n\n function enableBodyScroll(): void {\n document.body.style.removeProperty('overflow');\n }\n\n /* Displays a full window size modal with image */\n const imageView = props.variant === ModalVariants.image;\n\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n const showActions = (props.secondaryButtonText && props.secondaryButtonText?.length > 0) || props.onSuccess;\n\n // ariaLabelledBy prioriteres over ariaLabel, men dersom ariaLabel brukes trengs ikke ariaLabelledBy\n const ariaLabel = !props.ariaLabelledBy ? props.ariaLabel : undefined;\n const ariaLabelledBy = props.ariaLabelledBy ? props.ariaLabelledBy : !props.ariaLabel ? props.titleId : undefined;\n\n useEffect(() => {\n const overlayElement = overlayRef.current;\n disableBodyScroll();\n if (!props.disableCloseEvents && overlayElement) {\n overlayElement.addEventListener('keydown', handleKeyboardEvent);\n overlayElement.addEventListener('click', handleClickEvent);\n }\n return (): void => {\n enableBodyScroll();\n if (!props.disableCloseEvents && overlayElement) {\n overlayElement.removeEventListener('keydown', handleKeyboardEvent);\n overlayElement.removeEventListener('click', handleClickEvent);\n }\n };\n }, [props.disableCloseEvents]);\n\n useEffect(() => {\n dialogRef.current?.focus();\n }, []);\n\n const dialogClasses = cn(\n props.className,\n styles.modal,\n styles[`modal--${props.variant}`],\n styles[`modal--${props.size}`],\n contentIsScrollable && !showActions && styles['modal--no-actions']\n );\n\n const titleClasses = cn({\n [styles['modal__title--error']]: props.variant === ModalVariants.error,\n [styles['modal__title--success']]: props.variant === ModalVariants.success,\n });\n\n const Component = (\n <div data-testid=\"dialog-container\">\n <div\n ref={overlayRef}\n className={styles['modal-overlay']}\n data-testid={props.testId}\n data-analyticsid={AnalyticsId.Modal}\n style={{ zIndex: props.zIndex }}\n >\n <div className={styles.align}>\n <div\n className={dialogClasses}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n ref={dialogRef}\n >\n <div\n className={cn(styles['modal__shadow'], styles['modal__shadow--top'], {\n [styles['modal__shadow--show']]: !topContentVisible && contentIsScrollable,\n })}\n />\n <div\n className={cn(styles.modal__contentWrapper, {\n [styles['modal__contentWrapper--image']]: imageView,\n })}\n ref={modalContentRef}\n >\n {!props.noCloseButton && (\n <div className={styles.modal__closeWrapper}>\n <div className={cn(styles.modal__closeWrapper__close)}>\n <Close onClick={props.onClose} ariaLabel={props.ariaLabelCloseBtn} />\n </div>\n </div>\n )}\n <div\n className={cn(styles[`modal__contentWrapper__scroll--${props.size}`], {\n [styles['modal__contentWrapper__scroll--image']]: imageView,\n })}\n >\n <div ref={topContent} />\n <div className={styles.modal__contentWrapper__title}>\n {getIcon(props.variant, props.icon)}\n <Title id={ariaLabelledBy} htmlMarkup=\"h3\" appearance=\"title3\" className={titleClasses}>\n {props.title}\n </Title>\n {props.afterTitleChildren && <div className={styles['modal__afterTitleChildren']}>{props.afterTitleChildren}</div>}\n </div>\n {imageView && (\n <div>\n <div className={styles['modal__contentWrapper__imageWrapper']}>{props.children}</div>\n <span className={styles['modal__contentWrapper__imageDescription']}>{props.description}</span>\n </div>\n )}\n {!imageView && props.children && <div>{props.children}</div>}\n {!imageView && !props.children && <p className={styles.modal__description}>{props.description}</p>}\n <div ref={bottomContent} />\n </div>\n </div>\n <div\n className={cn(styles['modal__shadow'], styles['modal__shadow--bottom'], {\n [styles['modal__shadow--show']]: !bottomContentVisible && contentIsScrollable,\n })}\n />\n {showActions && (\n <div className={cn(styles['modal__call-to-action'], styles[`modal__call-to-action--${props.size}`])}>\n {props.onSuccess && <Button onClick={props.onSuccess}>{props.primaryButtonText}</Button>}\n {props.secondaryButtonText && props.secondaryButtonText?.length > 0 && (\n <Button variant=\"borderless\" onClick={props.onClose}>\n {props.secondaryButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n\n if (props.printable) {\n const printModal = 'print-modal';\n return (\n <Portal className={printModal} testId=\"print-modal\">\n <style media=\"print\">{`body > *:not(.${printModal}) {display: none;}`}</style>\n {Component}\n </Portal>\n );\n }\n\n return Component;\n};\n\nModal.defaultProps = defaultProps;\n\nexport default Modal;\n"],"names":["ModalVariants","ModalSize","defaultProps","uuid","ZIndex","getVariantIcon","variant","React","Icon","IconSize","AlertSignFill","palette","AlertSignStroke","CheckOutline","getIcon","icon","variantIcon","styles","Modal","props","topContent","modalContentRef","dialogRef","useFocusTrap","topContentVisible","useIsVisible","bottomContent","bottomContentVisible","contentIsScrollable","handleKeyboardEvent","e","handleClickEvent","event","overlayRef","disableBodyScroll","enableBodyScroll","imageView","showActions","_a","ariaLabel","ariaLabelledBy","useEffect","overlayElement","dialogClasses","cn","titleClasses","Component","AnalyticsId","Close","Title","Button","_b","printModal","Portal","Modal$1"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Modal.js","sources":["../src/components/Modal/Modal.tsx"],"sourcesContent":["import React, { useEffect } from 'react';\n\nimport cn from 'classnames';\n\nimport { AnalyticsId, ZIndex } from '../../constants';\nimport useFocusTrap from '../../hooks/useFocusTrap';\nimport { useIsVisible } from '../../hooks/useIsVisible';\nimport { palette } from '../../theme/palette';\nimport { uuid } from '../../utils/uuid';\nimport Button from '../Button';\nimport Close from '../Close';\nimport Icon, { IconSize } from '../Icons';\nimport AlertSignFill from '../Icons/AlertSignFill';\nimport AlertSignStroke from '../Icons/AlertSignStroke';\nimport CheckOutline from '../Icons/CheckOutline';\nimport Portal from '../Portal';\nimport Title from '../Title/Title';\n\nimport styles from './styles.module.scss';\n\nexport enum ModalVariants {\n normal = 'normal',\n warning = 'warning',\n error = 'error',\n success = 'success',\n image = 'image',\n}\n\nexport enum ModalSize {\n large = 'large',\n medium = 'medium',\n}\n\nexport interface ModalProps {\n /** Title of the modal */\n title: string;\n /** id of the modal title */\n titleId?: string;\n /** Description of the modal. Will not render if the modal has children. */\n description?: string;\n /** Changes the visual representation of the modal */\n variant?: keyof typeof ModalVariants;\n /** Change width of the modal (default: large) */\n size?: keyof typeof ModalSize;\n /** Icon displayed in title */\n icon?: React.ReactElement;\n /** Hides the close button */\n noCloseButton?: boolean;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Primary button text */\n primaryButtonText?: string;\n /** Secondary button text */\n secondaryButtonText?: string;\n /** Sets the aria-label of the modal */\n ariaLabel?: string;\n /** Sets the aria-labelledby of the modal */\n ariaLabelledBy?: string;\n /** Close button aria-label */\n ariaLabelCloseBtn?: string;\n /** Alternative component to modal */\n children?: React.ReactNode;\n /** Component shown after title */\n afterTitleChildren?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Customize the z-index of the modal */\n zIndex?: number;\n /** Function is called when user clicks primary button */\n onSuccess?: () => void;\n /** Function is called when user clicks secondary button, clicks escape or outside the modal */\n onClose?: () => void;\n /** When enabled the component will be rendered in the bottom of document.body */\n printable?: boolean;\n /** If disabled, clicking escape or outside the modal will not close it */\n disableCloseEvents?: boolean;\n}\n\nconst defaultProps = {\n variant: ModalVariants.normal,\n primaryButtonText: 'OK',\n titleId: uuid(),\n className: '',\n size: ModalSize.large,\n zIndex: ZIndex.Modal,\n};\n\nconst getVariantIcon = (variant?: ModalProps['variant']): JSX.Element | null => {\n if (variant === ModalVariants.error) {\n return <Icon size={IconSize.Small} svgIcon={AlertSignFill} color={palette.cherry500} />;\n } else if (variant === ModalVariants.warning) {\n return <Icon size={IconSize.Small} svgIcon={AlertSignStroke} color={palette.black} />;\n } else if (variant === ModalVariants.success) {\n return <Icon size={IconSize.Small} svgIcon={CheckOutline} color={palette.kiwi900} />;\n }\n return null;\n};\n\nconst getIcon = (variant?: ModalProps['variant'], icon?: ModalProps['icon']): JSX.Element | null => {\n const variantIcon = getVariantIcon(variant);\n if (variantIcon) {\n return <div className={styles.modal__iconWrapper}>{variantIcon}</div>;\n }\n if (icon) {\n return (\n <div className={styles.modal__iconWrapper}>\n {React.cloneElement(icon, {\n size: IconSize.Small,\n })}\n </div>\n );\n }\n return null;\n};\n\nconst Modal = (props: ModalProps): JSX.Element => {\n const topContent = React.useRef<HTMLDivElement>(null);\n const modalContentRef = React.useRef<HTMLDivElement>(null);\n const dialogRef = React.useRef<HTMLDivElement>(null);\n useFocusTrap(dialogRef, true);\n const topContentVisible = useIsVisible(topContent);\n const bottomContent = React.useRef<HTMLDivElement>(null);\n const bottomContentVisible = useIsVisible(bottomContent);\n const contentIsScrollable = modalContentRef.current && modalContentRef.current.scrollHeight > modalContentRef.current.clientHeight;\n\n function handleKeyboardEvent(e: KeyboardEvent): void {\n if (e.key === 'Escape' && props.onClose) {\n e.stopPropagation();\n props.onClose();\n }\n }\n\n function handleClickEvent(event: MouseEvent): void {\n if (event.target && overlayRef.current === event.target && props.onClose) {\n event.stopPropagation();\n props.onClose();\n }\n }\n\n function disableBodyScroll(): void {\n document.body.style.overflow = 'hidden';\n }\n\n function enableBodyScroll(): void {\n document.body.style.removeProperty('overflow');\n }\n\n /* Displays a full window size modal with image */\n const imageView = props.variant === ModalVariants.image;\n\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n const showActions = (props.secondaryButtonText && props.secondaryButtonText?.length > 0) || props.onSuccess;\n\n // ariaLabelledBy prioriteres over ariaLabel, men dersom ariaLabel brukes trengs ikke ariaLabelledBy\n const ariaLabel = !props.ariaLabelledBy ? props.ariaLabel : undefined;\n const ariaLabelledBy = props.ariaLabelledBy ? props.ariaLabelledBy : !props.ariaLabel ? props.titleId : undefined;\n\n useEffect(() => {\n const overlayElement = overlayRef.current;\n disableBodyScroll();\n if (!props.disableCloseEvents && overlayElement) {\n overlayElement.addEventListener('keydown', handleKeyboardEvent);\n overlayElement.addEventListener('click', handleClickEvent);\n }\n return (): void => {\n enableBodyScroll();\n if (!props.disableCloseEvents && overlayElement) {\n overlayElement.removeEventListener('keydown', handleKeyboardEvent);\n overlayElement.removeEventListener('click', handleClickEvent);\n }\n };\n }, [props.disableCloseEvents]);\n\n useEffect(() => {\n dialogRef.current?.focus();\n }, []);\n\n const dialogClasses = cn(\n props.className,\n styles.modal,\n styles[`modal--${props.variant}`],\n styles[`modal--${props.size}`],\n contentIsScrollable && !showActions && styles['modal--no-actions']\n );\n\n const titleClasses = cn({\n [styles['modal__title--error']]: props.variant === ModalVariants.error,\n [styles['modal__title--success']]: props.variant === ModalVariants.success,\n });\n\n const Component = (\n <div data-testid=\"dialog-container\">\n <div\n ref={overlayRef}\n className={styles['modal-overlay']}\n data-testid={props.testId}\n data-analyticsid={AnalyticsId.Modal}\n style={{ zIndex: props.zIndex }}\n >\n <div className={styles.align}>\n <div\n className={dialogClasses}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n ref={dialogRef}\n >\n <div\n className={cn(styles['modal__shadow'], styles['modal__shadow--top'], {\n [styles['modal__shadow--show']]: !topContentVisible && contentIsScrollable,\n })}\n />\n <div\n className={cn(styles.modal__contentWrapper, {\n [styles['modal__contentWrapper--image']]: imageView,\n })}\n ref={modalContentRef}\n >\n {!props.noCloseButton && (\n <div className={styles.modal__closeWrapper}>\n <div className={cn(styles.modal__closeWrapper__close)}>\n <Close onClick={props.onClose} ariaLabel={props.ariaLabelCloseBtn} />\n </div>\n </div>\n )}\n <div\n className={cn(styles[`modal__contentWrapper__scroll--${props.size}`], {\n [styles['modal__contentWrapper__scroll--image']]: imageView,\n })}\n >\n <div ref={topContent} />\n <div className={styles.modal__contentWrapper__title}>\n {getIcon(props.variant, props.icon)}\n <Title id={ariaLabelledBy} htmlMarkup=\"h3\" appearance=\"title3\" className={titleClasses}>\n {props.title}\n </Title>\n {props.afterTitleChildren && <div className={styles['modal__afterTitleChildren']}>{props.afterTitleChildren}</div>}\n </div>\n {imageView && (\n <div>\n <div className={styles['modal__contentWrapper__imageWrapper']}>{props.children}</div>\n <span className={styles['modal__contentWrapper__imageDescription']}>{props.description}</span>\n </div>\n )}\n {!imageView && props.children && <div>{props.children}</div>}\n {!imageView && !props.children && <p className={styles.modal__description}>{props.description}</p>}\n <div ref={bottomContent} />\n </div>\n </div>\n <div\n className={cn(styles['modal__shadow'], styles['modal__shadow--bottom'], {\n [styles['modal__shadow--show']]: !bottomContentVisible && contentIsScrollable,\n })}\n />\n {showActions && (\n <div className={cn(styles['modal__call-to-action'], styles[`modal__call-to-action--${props.size}`])}>\n {props.onSuccess && <Button onClick={props.onSuccess}>{props.primaryButtonText}</Button>}\n {props.secondaryButtonText && props.secondaryButtonText?.length > 0 && (\n <Button variant=\"borderless\" onClick={props.onClose}>\n {props.secondaryButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n\n if (props.printable) {\n const printModal = 'print-modal';\n return (\n <Portal className={printModal} testId=\"print-modal\">\n <style media=\"print\">{`body > *:not(.${printModal}) {display: none;}`}</style>\n {Component}\n </Portal>\n );\n }\n\n return Component;\n};\n\nModal.defaultProps = defaultProps;\n\nexport default Modal;\n"],"names":["ModalVariants","ModalSize","defaultProps","uuid","ZIndex","getVariantIcon","variant","React","Icon","IconSize","AlertSignFill","palette","AlertSignStroke","CheckOutline","getIcon","icon","variantIcon","styles","Modal","props","topContent","modalContentRef","dialogRef","useFocusTrap","topContentVisible","useIsVisible","bottomContent","bottomContentVisible","contentIsScrollable","handleKeyboardEvent","e","handleClickEvent","event","overlayRef","disableBodyScroll","enableBodyScroll","imageView","showActions","_a","ariaLabel","ariaLabelledBy","useEffect","overlayElement","dialogClasses","cn","titleClasses","Component","AnalyticsId","Close","Title","Button","_b","printModal","Portal","Modal$1"],"mappings":"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"}
|
package/PopOver.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import f,{useRef as B,useState as U,useEffect as Z}from"react";import E from"classnames";import{AnalyticsId as $}from"./constants.js";import{useInterval as j}from"./hooks/useInterval.js";import{useIsVisible as k}from"./hooks/useIsVisible.js";import{useLayoutEvent as q}from"./hooks/useLayoutEvent.js";import{useSize as J}from"./hooks/useSize.js";import{mergeRefs as K}from"./utils/refs.js";import u from"./components/PopOver/styles.module.scss";const Q=373,s=12,g=16,C=20,Y=4,L=12,I=(t,o,n)=>n!==r.positionautomatic?n:t.top>o.height+g?r.positionabove:r.positionbelow,W=t=>t.left+t.width/2,z=t=>document.documentElement.clientWidth-t.right+t.width/2,m=(t,o)=>W(t)-o.width/2,S=(t,o)=>m(t,o)+o.width,tt=(t,o)=>m(t,o)>s,ot=(t,o)=>S(t,o)<document.documentElement.clientWidth-s,et=(t,o)=>ot(t,o)?tt(t,o)?"floating":"left":"right",P=(t,o)=>t.top-g-o.height,w=t=>t.bottom+g,nt=()=>document.documentElement.clientWidth-s*2,it=()=>document.documentElement.clientWidth>Q+s*2,A=t=>t.top-g-Y,rt=t=>W(t)-C/2,st=t=>z(t)-C/2,lt=(t,o,n)=>{const i=et(t,o),e=I(t,o,n);return i==="left"?e===r.positionabove?"leftabove":"leftbelow":i==="right"?e===r.positionabove?"rightabove":"rightbelow":e===r.positionabove?"floatingabove":"floatingbelow"},ct=(t,o,n)=>{const i=lt(t,o,n),e=it()?void 0:nt();return i==="leftabove"?{left:s,top:P(t,o),width:e}:i==="leftbelow"?{left:s,top:w(t),width:e}:i==="rightabove"?{right:s,top:P(t,o),width:e}:i==="rightbelow"?{right:s,top:w(t),width:e}:i==="floatingbelow"?{left:m(t,o),top:w(t),width:e}:{left:m(t,o),top:P(t,o),width:e}},at=(t,o,n)=>{const i=rt(o),e=st(o),l=t.left+L,c=t.right+L;return t.right?n===r.positionabove?{right:e>c?e:c,top:A(o)}:{right:e>c?e:c,top:o.bottom}:n===r.positionabove?{left:i>l?i:l,top:A(o)}:{left:i>l?i:l,top:o.bottom}};var r=(t=>(t.positionautomatic="positionautomatic",t.positionbelow="positionbelow",t.positionabove="positionabove",t))(r||{});const O=f.forwardRef((t,o)=>{const{id:n,children:i,controllerRef:e,popOverRef:l,show:c=!1,className:N="",variant:v="positionautomatic",role:R,testId:y,arrowClassName:T}=t,x=l||B(null),F=B(null),p=J(x),[a,H]=U(),X=k(e,0),h=()=>{var _;H((_=e.current)==null?void 0:_.getBoundingClientRect())};j(h,500),q(h,["scroll","resize"],10),Z(()=>{h()},[]);const V=R==="tooltip",D=E(u.popover,{[u["popover--visible"]]:V?c:X},N),b=a&&p&&I(a,p,v),G=E(u.popover__arrow,T,{[u["popover__arrow--over"]]:b==="positionbelow",[u["popover__arrow--under"]]:b==="positionabove"}),d=a&&p&&ct(a,p,v),M=d&&a&&b&&at(d,a,b);return f.createElement(f.Fragment,null,f.createElement("div",{id:n,ref:K([o,x]),className:D,style:d,"data-testid":y,"data-analyticsid":$.PopOver,role:R},i),f.createElement("div",{ref:F,className:G,style:M}))});O.displayName="PopOver";const wt=O;export{r as P,wt as a};
|
|
2
2
|
//# sourceMappingURL=PopOver.js.map
|
package/PopOver.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PopOver.js","sources":["../src/components/PopOver/utils.ts","../src/components/PopOver/PopOver.tsx"],"sourcesContent":["import { CSSProperties } from 'react';\n\nimport { PopOverVariant } from './PopOver';\n\ntype HorizontalPosition = 'left' | 'right' | 'floating';\ntype BubblePosition = 'leftabove' | 'leftbelow' | 'rightabove' | 'rightbelow' | 'floatingabove' | 'floatingbelow';\n\n/** Bredde på hjelpeboble */\nconst BUBBLE_WIDTH_PX = 373;\n/** Hjelpeboblen skal holde avstand til venstre/høyre kant på vinduet */\nconst WINDOW_MARGIN_PX = 12;\n/** Vertikal avstand fra hjelpeboble til kontroller */\nconst BUBBLE_VERTICAL_OFFSET_PX = 16;\n/** Høyde/bredde på pil */\nconst ARROW_WIDTH_PX = 20;\n/** Avstand fra pil til hjelpeboble */\nconst ARROW_VERTICAL_OFFSET_PX = 4;\n/** Pilen skal holde avstand til venstre/høyre kant av hjelpeboblen */\nconst ARROW_HORIZONTAL_MARGIN_PX = 12;\n\n/**\n * Beregn om hjelpeboblen skal vises over eller under kontrolleren\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @param variant Ønsket plassering av hjelpeboblen (over/under/automatisk)\n * @returns Om hjelpeboblen skal vises over eller under\n */\nexport const getVerticalPosition = (\n controllerSize: DOMRect,\n bubbleSize: DOMRect,\n variant: keyof typeof PopOverVariant\n): keyof typeof PopOverVariant => {\n if (variant !== PopOverVariant.positionautomatic) {\n return variant;\n }\n if (controllerSize.top > bubbleSize.height + BUBBLE_VERTICAL_OFFSET_PX) {\n return PopOverVariant.positionabove;\n } else {\n return PopOverVariant.positionbelow;\n }\n};\n\n/**\n * Finn horisontalt midtpunkt på kontrolleren i forhold til venstre kant av vinduet\n * @param controllerSize DOMRect for controlleren\n * @returns Horisontalt senter av controlleren i px\n */\nconst getControllerLeftCenterPx = (controllerSize: DOMRect): number => controllerSize.left + controllerSize.width / 2;\n\n/**\n * Finn horisontalt midtpunkt på kontrolleren i forhold til høyre kant av vinduet\n * @param controllerSize DOMRect for controlleren\n * @returns Horisontalt senter av controlleren i px\n */\nconst getControllerRightCenterPx = (controllerSize: DOMRect): number =>\n document.documentElement.clientWidth - controllerSize.right + controllerSize.width / 2;\n\n/**\n * Finn venstre kant av hjelpeboblen i forhold til kontrolleren\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns Venstre kant av hjelpeboblen i px\n */\nconst getBubbleLeftPx = (controllerSize: DOMRect, bubbleSize: DOMRect): number => {\n const controllerHorizontalCenterPx = getControllerLeftCenterPx(controllerSize);\n\n return controllerHorizontalCenterPx - bubbleSize.width / 2;\n};\n\n/**\n * Finn høyre kant av hjelpeboblen i forhold til kontrolleren\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns Høyre kant av hjelpeboblen i px\n */\nconst getBubbleRightPx = (controllerSize: DOMRect, bubbleSize: DOMRect): number => {\n const bubbleLeftPx = getBubbleLeftPx(controllerSize, bubbleSize);\n\n return bubbleLeftPx + bubbleSize.width;\n};\n\n/**\n * Sjekk om venstre kant av hjelpeboblen er innenfor vinduet\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns true dersom venstre kant er innenfor vinduet\n */\nconst getBubbleLeftVisible = (controllerSize: DOMRect, bubbleSize: DOMRect): boolean => {\n const bubbleLeftPx = getBubbleLeftPx(controllerSize, bubbleSize);\n\n return bubbleLeftPx > WINDOW_MARGIN_PX;\n};\n\n/**\n * Sjekk om høyre kant av hjelpeboblen er innenfor vinduet\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns true dersom høyre kant er innenfor vinduet\n */\nconst getBubbleRightIsVisible = (controllerSize: DOMRect, bubbleSize: DOMRect): boolean => {\n const bubbleRightPx = getBubbleRightPx(controllerSize, bubbleSize);\n\n return bubbleRightPx < document.documentElement.clientWidth - WINDOW_MARGIN_PX;\n};\n\n/**\n * Finn riktig horisontal plassering til hjelpeboblen\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns left, right eller floating\n */\nconst getHorizontalPosition = (controllerSize: DOMRect, bubbleSize: DOMRect): HorizontalPosition => {\n if (!getBubbleRightIsVisible(controllerSize, bubbleSize)) {\n return 'right';\n }\n if (!getBubbleLeftVisible(controllerSize, bubbleSize)) {\n return 'left';\n }\n\n return 'floating';\n};\n\n/**\n * Finn vertikal plassering av hjelpeboblen når den skal vises over\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns \"Top\" for hjelpeboblen i px\n */\nconst getBubbleAbovePx = (controllerSize: DOMRect, bubbleSize: DOMRect): number =>\n controllerSize.top - BUBBLE_VERTICAL_OFFSET_PX - bubbleSize.height;\n\n/**\n * Finn vertikal plassering av hjelpeboblen når den skal vises under\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns \"Top\" for hjelpeboblen i px\n */\nconst getBubbleBelowPx = (controllerSize: DOMRect): number => controllerSize.bottom + BUBBLE_VERTICAL_OFFSET_PX;\n\n/**\n * Finn maks bredde på hjelpeboblen i forhold til vinduet\n * @returns Bredde på hjelpeboblen i px\n */\nconst getBubbleWidth = (): number => document.documentElement.clientWidth - WINDOW_MARGIN_PX * 2;\n\n/**\n * Sjekk om hjelpeboblen har plass i vinduet\n * @returns true dersom det er plass til hjelpeboblen i vinduet\n */\nconst getBubbleFitsInWindow = (): boolean => {\n return document.documentElement.clientWidth > BUBBLE_WIDTH_PX + WINDOW_MARGIN_PX * 2;\n};\n\n/**\n * Finn vertikal plassering av pilen når den skal vises over\n * @param controllerSize DOMRect for controlleren\n * @returns \"Top\" for pilen i px\n */\nconst getArrowTopxPx = (controllerSize: DOMRect): number => controllerSize.top - BUBBLE_VERTICAL_OFFSET_PX - ARROW_VERTICAL_OFFSET_PX;\n\n/**\n * Finn horisontal plassering av pilen i forhold til venstre kant av vinduet\n * @param controllerSize DOMRect for controlleren\n * @returns Venstre kant av pilen i px\n */\nconst getArrowLeftPx = (controllerSize: DOMRect): number => getControllerLeftCenterPx(controllerSize) - ARROW_WIDTH_PX / 2;\n\n/**\n * Finn horisontal plassering av pilen\n * @param controllerSize DOMRect for controlleren\n * @returns Venstre kant av pilen i px\n */\nconst getArrowRightPx = (controllerSize: DOMRect): number => getControllerRightCenterPx(controllerSize) - ARROW_WIDTH_PX / 2;\n\n/**\n * Finn riktig plassering av hjelpeboblen\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @param variant Ønsket plassering av hjelpeboblen (over/under)\n * @returns Beste mulige plassering av hjelpeboblen\n */\nconst getBubblePosition = (controllerSize: DOMRect, bubbleSize: DOMRect, variant: keyof typeof PopOverVariant): BubblePosition => {\n const horizontalPosition = getHorizontalPosition(controllerSize, bubbleSize);\n const verticalPosition = getVerticalPosition(controllerSize, bubbleSize, variant);\n\n if (horizontalPosition === 'left') {\n if (verticalPosition === PopOverVariant.positionabove) {\n return 'leftabove';\n }\n return 'leftbelow';\n }\n\n if (horizontalPosition === 'right') {\n if (verticalPosition === PopOverVariant.positionabove) {\n return 'rightabove';\n }\n return 'rightbelow';\n }\n\n if (verticalPosition === PopOverVariant.positionabove) {\n return 'floatingabove';\n }\n\n return 'floatingbelow';\n};\n\n/**\n * Finn riktig plassering av hjelpeboblen\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @param variant Ønsket plassering av hjelpeboblen (over/under)\n * @returns CSSProperties som plasserer hjelpeboblen riktig\n */\nexport const getBubbleStyle = (controllerSize: DOMRect, bubbleSize: DOMRect, variant: keyof typeof PopOverVariant): CSSProperties => {\n const bubblePosition = getBubblePosition(controllerSize, bubbleSize, variant);\n const bubbleWidth = !getBubbleFitsInWindow() ? getBubbleWidth() : undefined;\n\n if (bubblePosition === 'leftabove') {\n return {\n left: WINDOW_MARGIN_PX,\n top: getBubbleAbovePx(controllerSize, bubbleSize),\n width: bubbleWidth,\n };\n }\n if (bubblePosition === 'leftbelow') {\n return { left: WINDOW_MARGIN_PX, top: getBubbleBelowPx(controllerSize), width: bubbleWidth };\n }\n if (bubblePosition === 'rightabove') {\n return { right: WINDOW_MARGIN_PX, top: getBubbleAbovePx(controllerSize, bubbleSize), width: bubbleWidth };\n }\n if (bubblePosition === 'rightbelow') {\n return { right: WINDOW_MARGIN_PX, top: getBubbleBelowPx(controllerSize), width: bubbleWidth };\n }\n\n if (bubblePosition === 'floatingbelow') {\n return { left: getBubbleLeftPx(controllerSize, bubbleSize), top: getBubbleBelowPx(controllerSize), width: bubbleWidth };\n }\n\n return { left: getBubbleLeftPx(controllerSize, bubbleSize), top: getBubbleAbovePx(controllerSize, bubbleSize), width: bubbleWidth };\n};\n\n/**\n * Finn riktig plassering av pilen\n * @param bubbleStyle CSSProperties for hjelpeboblen\n * @param controllerSize DOMRect for kontrolleren\n * @param verticalPosition Ønsket plassering av hjelpeboblen (over/under)\n * @returns CSSProperties som plasserer pilen riktig\n */\nexport const getArrowStyle = (\n bubbleStyle: CSSProperties,\n controllerSize: DOMRect,\n verticalPosition: keyof typeof PopOverVariant\n): CSSProperties => {\n const leftPx = getArrowLeftPx(controllerSize);\n const rightPx = getArrowRightPx(controllerSize);\n const minLeftPx = (bubbleStyle.left as number) + ARROW_HORIZONTAL_MARGIN_PX;\n const minRightPx = (bubbleStyle.right as number) + ARROW_HORIZONTAL_MARGIN_PX;\n\n if (bubbleStyle.right) {\n if (verticalPosition === PopOverVariant.positionabove) {\n return {\n right: rightPx > minRightPx ? rightPx : minRightPx,\n top: getArrowTopxPx(controllerSize),\n };\n }\n\n return {\n right: rightPx > minRightPx ? rightPx : minRightPx,\n top: controllerSize.bottom,\n };\n }\n\n if (verticalPosition === PopOverVariant.positionabove) {\n return {\n left: leftPx > minLeftPx ? leftPx : minLeftPx,\n top: getArrowTopxPx(controllerSize),\n };\n }\n\n return {\n left: leftPx > minLeftPx ? leftPx : minLeftPx,\n top: controllerSize.bottom,\n };\n};\n","import React, { useEffect, useRef, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { getArrowStyle, getBubbleStyle, getVerticalPosition } from './utils';\nimport { AnalyticsId } from '../../constants';\nimport { useInterval } from '../../hooks/useInterval';\nimport { useIsVisible } from '../../hooks/useIsVisible';\nimport { useLayoutEvent } from '../../hooks/useLayoutEvent';\nimport { useSize } from '../../hooks/useSize';\nimport { mergeRefs } from '../../utils/refs';\n\nimport styles from './styles.module.scss';\n\nexport enum PopOverVariant {\n positionautomatic = 'positionautomatic',\n positionbelow = 'positionbelow',\n positionabove = 'positionabove',\n}\n\nexport type PopOverRole = 'tooltip';\n\nexport interface PopOverProps {\n /** Id of the PopOver */\n id?: string;\n /** Content shown inside PopOver. Note that if role=\"tooltip\", you must not include interactive/focusable elements. */\n children: React.ReactNode;\n /** Ref for the element the PopOver is placed upon */\n controllerRef: React.RefObject<HTMLElement | SVGSVGElement>;\n /** Ref for the element the PopOver is placed upon */\n popOverRef?: React.RefObject<HTMLDivElement>;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds custom classes to the arrow element. */\n arrowClassName?: string;\n /** Determines the placement of the popover. Default: automatic positioning. */\n variant?: keyof typeof PopOverVariant;\n /** Sets role of the PopOver element. If set to \"tooltip\", */\n role?: PopOverRole;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Closes bubble on click outside the bubble. */\n closeOnClickOutside?: boolean;\n}\n\nconst PopOver = React.forwardRef<HTMLDivElement | SVGSVGElement, PopOverProps>((props, ref) => {\n const {\n id,\n children,\n controllerRef,\n popOverRef,\n className = '',\n variant = PopOverVariant.positionautomatic,\n role,\n testId,\n arrowClassName,\n } = props;\n\n const bubbleRef = popOverRef || useRef<HTMLDivElement>(null);\n const arrowRef = useRef<HTMLDivElement>(null);\n const bubbleSize = useSize(bubbleRef);\n const [controllerSize, setControllerSize] = useState<DOMRect>();\n const controllerisVisible = useIsVisible(controllerRef, 0);\n\n const updateControllerSize = (): void => {\n setControllerSize(controllerRef.current?.getBoundingClientRect());\n };\n\n useInterval(updateControllerSize, 500);\n useLayoutEvent(updateControllerSize, ['scroll', 'resize'], 10);\n\n useEffect(() => {\n updateControllerSize();\n }, []);\n\n const isTooltip = role === 'tooltip';\n\n const popOverClasses = classNames(\n styles.popover,\n { [styles['popover--visible']]: (!isTooltip && controllerisVisible) || isTooltip },\n className\n );\n const verticalPosition = controllerSize && bubbleSize && getVerticalPosition(controllerSize, bubbleSize, variant);\n const arrowClasses = classNames(styles.popover__arrow, arrowClassName, {\n [styles['popover__arrow--over']]: verticalPosition === PopOverVariant.positionbelow,\n [styles['popover__arrow--under']]: verticalPosition === PopOverVariant.positionabove,\n });\n\n const bubbleStyle = controllerSize && bubbleSize && getBubbleStyle(controllerSize, bubbleSize, variant);\n const arrowStyle = bubbleStyle && controllerSize && verticalPosition && getArrowStyle(bubbleStyle, controllerSize, verticalPosition);\n\n return (\n <>\n <div\n id={id}\n ref={mergeRefs([ref, bubbleRef])}\n className={popOverClasses}\n style={bubbleStyle}\n data-testid={testId}\n data-analyticsid={AnalyticsId.PopOver}\n role={role}\n >\n {children}\n </div>\n <div ref={arrowRef} className={arrowClasses} style={arrowStyle} />\n </>\n );\n});\n\nPopOver.displayName = 'PopOver';\n\nexport default PopOver;\n"],"names":["BUBBLE_WIDTH_PX","WINDOW_MARGIN_PX","BUBBLE_VERTICAL_OFFSET_PX","ARROW_WIDTH_PX","ARROW_VERTICAL_OFFSET_PX","ARROW_HORIZONTAL_MARGIN_PX","getVerticalPosition","controllerSize","bubbleSize","variant","PopOverVariant","getControllerLeftCenterPx","getControllerRightCenterPx","getBubbleLeftPx","getBubbleRightPx","getBubbleLeftVisible","getBubbleRightIsVisible","getHorizontalPosition","getBubbleAbovePx","getBubbleBelowPx","getBubbleWidth","getBubbleFitsInWindow","getArrowTopxPx","getArrowLeftPx","getArrowRightPx","getBubblePosition","horizontalPosition","verticalPosition","getBubbleStyle","bubblePosition","bubbleWidth","getArrowStyle","bubbleStyle","leftPx","rightPx","minLeftPx","minRightPx","PopOver","React","props","ref","id","children","controllerRef","popOverRef","className","role","testId","arrowClassName","bubbleRef","useRef","arrowRef","useSize","setControllerSize","useState","controllerisVisible","useIsVisible","updateControllerSize","_a","useInterval","useLayoutEvent","useEffect","isTooltip","popOverClasses","classNames","styles","arrowClasses","arrowStyle","mergeRefs","AnalyticsId","PopOver$1"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PopOver.js","sources":["../src/components/PopOver/utils.ts","../src/components/PopOver/PopOver.tsx"],"sourcesContent":["import { CSSProperties } from 'react';\n\nimport { PopOverVariant } from './PopOver';\n\ntype HorizontalPosition = 'left' | 'right' | 'floating';\ntype BubblePosition = 'leftabove' | 'leftbelow' | 'rightabove' | 'rightbelow' | 'floatingabove' | 'floatingbelow';\n\n/** Bredde på hjelpeboble */\nconst BUBBLE_WIDTH_PX = 373;\n/** Hjelpeboblen skal holde avstand til venstre/høyre kant på vinduet */\nconst WINDOW_MARGIN_PX = 12;\n/** Vertikal avstand fra hjelpeboble til kontroller */\nconst BUBBLE_VERTICAL_OFFSET_PX = 16;\n/** Høyde/bredde på pil */\nconst ARROW_WIDTH_PX = 20;\n/** Avstand fra pil til hjelpeboble */\nconst ARROW_VERTICAL_OFFSET_PX = 4;\n/** Pilen skal holde avstand til venstre/høyre kant av hjelpeboblen */\nconst ARROW_HORIZONTAL_MARGIN_PX = 12;\n\n/**\n * Beregn om hjelpeboblen skal vises over eller under kontrolleren\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @param variant Ønsket plassering av hjelpeboblen (over/under/automatisk)\n * @returns Om hjelpeboblen skal vises over eller under\n */\nexport const getVerticalPosition = (\n controllerSize: DOMRect,\n bubbleSize: DOMRect,\n variant: keyof typeof PopOverVariant\n): keyof typeof PopOverVariant => {\n if (variant !== PopOverVariant.positionautomatic) {\n return variant;\n }\n if (controllerSize.top > bubbleSize.height + BUBBLE_VERTICAL_OFFSET_PX) {\n return PopOverVariant.positionabove;\n } else {\n return PopOverVariant.positionbelow;\n }\n};\n\n/**\n * Finn horisontalt midtpunkt på kontrolleren i forhold til venstre kant av vinduet\n * @param controllerSize DOMRect for controlleren\n * @returns Horisontalt senter av controlleren i px\n */\nconst getControllerLeftCenterPx = (controllerSize: DOMRect): number => controllerSize.left + controllerSize.width / 2;\n\n/**\n * Finn horisontalt midtpunkt på kontrolleren i forhold til høyre kant av vinduet\n * @param controllerSize DOMRect for controlleren\n * @returns Horisontalt senter av controlleren i px\n */\nconst getControllerRightCenterPx = (controllerSize: DOMRect): number =>\n document.documentElement.clientWidth - controllerSize.right + controllerSize.width / 2;\n\n/**\n * Finn venstre kant av hjelpeboblen i forhold til kontrolleren\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns Venstre kant av hjelpeboblen i px\n */\nconst getBubbleLeftPx = (controllerSize: DOMRect, bubbleSize: DOMRect): number => {\n const controllerHorizontalCenterPx = getControllerLeftCenterPx(controllerSize);\n\n return controllerHorizontalCenterPx - bubbleSize.width / 2;\n};\n\n/**\n * Finn høyre kant av hjelpeboblen i forhold til kontrolleren\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns Høyre kant av hjelpeboblen i px\n */\nconst getBubbleRightPx = (controllerSize: DOMRect, bubbleSize: DOMRect): number => {\n const bubbleLeftPx = getBubbleLeftPx(controllerSize, bubbleSize);\n\n return bubbleLeftPx + bubbleSize.width;\n};\n\n/**\n * Sjekk om venstre kant av hjelpeboblen er innenfor vinduet\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns true dersom venstre kant er innenfor vinduet\n */\nconst getBubbleLeftVisible = (controllerSize: DOMRect, bubbleSize: DOMRect): boolean => {\n const bubbleLeftPx = getBubbleLeftPx(controllerSize, bubbleSize);\n\n return bubbleLeftPx > WINDOW_MARGIN_PX;\n};\n\n/**\n * Sjekk om høyre kant av hjelpeboblen er innenfor vinduet\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns true dersom høyre kant er innenfor vinduet\n */\nconst getBubbleRightIsVisible = (controllerSize: DOMRect, bubbleSize: DOMRect): boolean => {\n const bubbleRightPx = getBubbleRightPx(controllerSize, bubbleSize);\n\n return bubbleRightPx < document.documentElement.clientWidth - WINDOW_MARGIN_PX;\n};\n\n/**\n * Finn riktig horisontal plassering til hjelpeboblen\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns left, right eller floating\n */\nconst getHorizontalPosition = (controllerSize: DOMRect, bubbleSize: DOMRect): HorizontalPosition => {\n if (!getBubbleRightIsVisible(controllerSize, bubbleSize)) {\n return 'right';\n }\n if (!getBubbleLeftVisible(controllerSize, bubbleSize)) {\n return 'left';\n }\n\n return 'floating';\n};\n\n/**\n * Finn vertikal plassering av hjelpeboblen når den skal vises over\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns \"Top\" for hjelpeboblen i px\n */\nconst getBubbleAbovePx = (controllerSize: DOMRect, bubbleSize: DOMRect): number =>\n controllerSize.top - BUBBLE_VERTICAL_OFFSET_PX - bubbleSize.height;\n\n/**\n * Finn vertikal plassering av hjelpeboblen når den skal vises under\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @returns \"Top\" for hjelpeboblen i px\n */\nconst getBubbleBelowPx = (controllerSize: DOMRect): number => controllerSize.bottom + BUBBLE_VERTICAL_OFFSET_PX;\n\n/**\n * Finn maks bredde på hjelpeboblen i forhold til vinduet\n * @returns Bredde på hjelpeboblen i px\n */\nconst getBubbleWidth = (): number => document.documentElement.clientWidth - WINDOW_MARGIN_PX * 2;\n\n/**\n * Sjekk om hjelpeboblen har plass i vinduet\n * @returns true dersom det er plass til hjelpeboblen i vinduet\n */\nconst getBubbleFitsInWindow = (): boolean => {\n return document.documentElement.clientWidth > BUBBLE_WIDTH_PX + WINDOW_MARGIN_PX * 2;\n};\n\n/**\n * Finn vertikal plassering av pilen når den skal vises over\n * @param controllerSize DOMRect for controlleren\n * @returns \"Top\" for pilen i px\n */\nconst getArrowTopxPx = (controllerSize: DOMRect): number => controllerSize.top - BUBBLE_VERTICAL_OFFSET_PX - ARROW_VERTICAL_OFFSET_PX;\n\n/**\n * Finn horisontal plassering av pilen i forhold til venstre kant av vinduet\n * @param controllerSize DOMRect for controlleren\n * @returns Venstre kant av pilen i px\n */\nconst getArrowLeftPx = (controllerSize: DOMRect): number => getControllerLeftCenterPx(controllerSize) - ARROW_WIDTH_PX / 2;\n\n/**\n * Finn horisontal plassering av pilen\n * @param controllerSize DOMRect for controlleren\n * @returns Venstre kant av pilen i px\n */\nconst getArrowRightPx = (controllerSize: DOMRect): number => getControllerRightCenterPx(controllerSize) - ARROW_WIDTH_PX / 2;\n\n/**\n * Finn riktig plassering av hjelpeboblen\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @param variant Ønsket plassering av hjelpeboblen (over/under)\n * @returns Beste mulige plassering av hjelpeboblen\n */\nconst getBubblePosition = (controllerSize: DOMRect, bubbleSize: DOMRect, variant: keyof typeof PopOverVariant): BubblePosition => {\n const horizontalPosition = getHorizontalPosition(controllerSize, bubbleSize);\n const verticalPosition = getVerticalPosition(controllerSize, bubbleSize, variant);\n\n if (horizontalPosition === 'left') {\n if (verticalPosition === PopOverVariant.positionabove) {\n return 'leftabove';\n }\n return 'leftbelow';\n }\n\n if (horizontalPosition === 'right') {\n if (verticalPosition === PopOverVariant.positionabove) {\n return 'rightabove';\n }\n return 'rightbelow';\n }\n\n if (verticalPosition === PopOverVariant.positionabove) {\n return 'floatingabove';\n }\n\n return 'floatingbelow';\n};\n\n/**\n * Finn riktig plassering av hjelpeboblen\n * @param controllerSize DOMRect for controlleren\n * @param bubbleSize DOMRect for hjelpeboblen\n * @param variant Ønsket plassering av hjelpeboblen (over/under)\n * @returns CSSProperties som plasserer hjelpeboblen riktig\n */\nexport const getBubbleStyle = (controllerSize: DOMRect, bubbleSize: DOMRect, variant: keyof typeof PopOverVariant): CSSProperties => {\n const bubblePosition = getBubblePosition(controllerSize, bubbleSize, variant);\n const bubbleWidth = !getBubbleFitsInWindow() ? getBubbleWidth() : undefined;\n\n if (bubblePosition === 'leftabove') {\n return {\n left: WINDOW_MARGIN_PX,\n top: getBubbleAbovePx(controllerSize, bubbleSize),\n width: bubbleWidth,\n };\n }\n if (bubblePosition === 'leftbelow') {\n return { left: WINDOW_MARGIN_PX, top: getBubbleBelowPx(controllerSize), width: bubbleWidth };\n }\n if (bubblePosition === 'rightabove') {\n return { right: WINDOW_MARGIN_PX, top: getBubbleAbovePx(controllerSize, bubbleSize), width: bubbleWidth };\n }\n if (bubblePosition === 'rightbelow') {\n return { right: WINDOW_MARGIN_PX, top: getBubbleBelowPx(controllerSize), width: bubbleWidth };\n }\n\n if (bubblePosition === 'floatingbelow') {\n return { left: getBubbleLeftPx(controllerSize, bubbleSize), top: getBubbleBelowPx(controllerSize), width: bubbleWidth };\n }\n\n return { left: getBubbleLeftPx(controllerSize, bubbleSize), top: getBubbleAbovePx(controllerSize, bubbleSize), width: bubbleWidth };\n};\n\n/**\n * Finn riktig plassering av pilen\n * @param bubbleStyle CSSProperties for hjelpeboblen\n * @param controllerSize DOMRect for kontrolleren\n * @param verticalPosition Ønsket plassering av hjelpeboblen (over/under)\n * @returns CSSProperties som plasserer pilen riktig\n */\nexport const getArrowStyle = (\n bubbleStyle: CSSProperties,\n controllerSize: DOMRect,\n verticalPosition: keyof typeof PopOverVariant\n): CSSProperties => {\n const leftPx = getArrowLeftPx(controllerSize);\n const rightPx = getArrowRightPx(controllerSize);\n const minLeftPx = (bubbleStyle.left as number) + ARROW_HORIZONTAL_MARGIN_PX;\n const minRightPx = (bubbleStyle.right as number) + ARROW_HORIZONTAL_MARGIN_PX;\n\n if (bubbleStyle.right) {\n if (verticalPosition === PopOverVariant.positionabove) {\n return {\n right: rightPx > minRightPx ? rightPx : minRightPx,\n top: getArrowTopxPx(controllerSize),\n };\n }\n\n return {\n right: rightPx > minRightPx ? rightPx : minRightPx,\n top: controllerSize.bottom,\n };\n }\n\n if (verticalPosition === PopOverVariant.positionabove) {\n return {\n left: leftPx > minLeftPx ? leftPx : minLeftPx,\n top: getArrowTopxPx(controllerSize),\n };\n }\n\n return {\n left: leftPx > minLeftPx ? leftPx : minLeftPx,\n top: controllerSize.bottom,\n };\n};\n","import React, { useEffect, useRef, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { getArrowStyle, getBubbleStyle, getVerticalPosition } from './utils';\nimport { AnalyticsId } from '../../constants';\nimport { useInterval } from '../../hooks/useInterval';\nimport { useIsVisible } from '../../hooks/useIsVisible';\nimport { useLayoutEvent } from '../../hooks/useLayoutEvent';\nimport { useSize } from '../../hooks/useSize';\nimport { mergeRefs } from '../../utils/refs';\n\nimport styles from './styles.module.scss';\n\nexport enum PopOverVariant {\n positionautomatic = 'positionautomatic',\n positionbelow = 'positionbelow',\n positionabove = 'positionabove',\n}\n\nexport type PopOverRole = 'tooltip';\n\nexport interface PopOverProps {\n /** Id of the PopOver */\n id?: string;\n /** Content shown inside PopOver. Note that if role=\"tooltip\", you must not include interactive/focusable elements. */\n children: React.ReactNode;\n /** Ref for the element the PopOver is placed upon */\n controllerRef: React.RefObject<HTMLElement | SVGSVGElement>;\n /** Ref for the element the PopOver is placed upon */\n popOverRef?: React.RefObject<HTMLDivElement>;\n /** Show the popover. Only applies when role=tooltip. Default: false. */\n show?: boolean;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds custom classes to the arrow element. */\n arrowClassName?: string;\n /** Determines the placement of the popover. Default: automatic positioning. */\n variant?: keyof typeof PopOverVariant;\n /** Sets role of the PopOver element */\n role?: PopOverRole;\n /** Closes popover on click outside the bubble. */\n closeOnClickOutside?: boolean;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nconst PopOver = React.forwardRef<HTMLDivElement | SVGSVGElement, PopOverProps>((props, ref) => {\n const {\n id,\n children,\n controllerRef,\n popOverRef,\n show = false,\n className = '',\n variant = PopOverVariant.positionautomatic,\n role,\n testId,\n arrowClassName,\n } = props;\n\n const bubbleRef = popOverRef || useRef<HTMLDivElement>(null);\n const arrowRef = useRef<HTMLDivElement>(null);\n const bubbleSize = useSize(bubbleRef);\n const [controllerSize, setControllerSize] = useState<DOMRect>();\n const controllerisVisible = useIsVisible(controllerRef, 0);\n\n const updateControllerSize = (): void => {\n setControllerSize(controllerRef.current?.getBoundingClientRect());\n };\n\n useInterval(updateControllerSize, 500);\n useLayoutEvent(updateControllerSize, ['scroll', 'resize'], 10);\n\n useEffect(() => {\n updateControllerSize();\n }, []);\n\n const isTooltip = role === 'tooltip';\n\n const popOverClasses = classNames(styles.popover, { [styles['popover--visible']]: isTooltip ? show : controllerisVisible }, className);\n const verticalPosition = controllerSize && bubbleSize && getVerticalPosition(controllerSize, bubbleSize, variant);\n const arrowClasses = classNames(styles.popover__arrow, arrowClassName, {\n [styles['popover__arrow--over']]: verticalPosition === PopOverVariant.positionbelow,\n [styles['popover__arrow--under']]: verticalPosition === PopOverVariant.positionabove,\n });\n\n const bubbleStyle = controllerSize && bubbleSize && getBubbleStyle(controllerSize, bubbleSize, variant);\n const arrowStyle = bubbleStyle && controllerSize && verticalPosition && getArrowStyle(bubbleStyle, controllerSize, verticalPosition);\n\n return (\n <>\n <div\n id={id}\n ref={mergeRefs([ref, bubbleRef])}\n className={popOverClasses}\n style={bubbleStyle}\n data-testid={testId}\n data-analyticsid={AnalyticsId.PopOver}\n role={role}\n >\n {children}\n </div>\n <div ref={arrowRef} className={arrowClasses} style={arrowStyle} />\n </>\n );\n});\n\nPopOver.displayName = 'PopOver';\n\nexport default PopOver;\n"],"names":["BUBBLE_WIDTH_PX","WINDOW_MARGIN_PX","BUBBLE_VERTICAL_OFFSET_PX","ARROW_WIDTH_PX","ARROW_VERTICAL_OFFSET_PX","ARROW_HORIZONTAL_MARGIN_PX","getVerticalPosition","controllerSize","bubbleSize","variant","PopOverVariant","getControllerLeftCenterPx","getControllerRightCenterPx","getBubbleLeftPx","getBubbleRightPx","getBubbleLeftVisible","getBubbleRightIsVisible","getHorizontalPosition","getBubbleAbovePx","getBubbleBelowPx","getBubbleWidth","getBubbleFitsInWindow","getArrowTopxPx","getArrowLeftPx","getArrowRightPx","getBubblePosition","horizontalPosition","verticalPosition","getBubbleStyle","bubblePosition","bubbleWidth","getArrowStyle","bubbleStyle","leftPx","rightPx","minLeftPx","minRightPx","PopOver","React","props","ref","id","children","controllerRef","popOverRef","show","className","role","testId","arrowClassName","bubbleRef","useRef","arrowRef","useSize","setControllerSize","useState","controllerisVisible","useIsVisible","updateControllerSize","_a","useInterval","useLayoutEvent","useEffect","isTooltip","popOverClasses","classNames","styles","arrowClasses","arrowStyle","mergeRefs","AnalyticsId","PopOver$1"],"mappings":"6bAQA,MAAMA,EAAkB,IAElBC,EAAmB,GAEnBC,EAA4B,GAE5BC,EAAiB,GAEjBC,EAA2B,EAE3BC,EAA6B,GAStBC,EAAsB,CACjCC,EACAC,EACAC,IAEIA,IAAYC,EAAe,kBACtBD,EAELF,EAAe,IAAMC,EAAW,OAASN,EACpCQ,EAAe,cAEfA,EAAe,cASpBC,EAA6BJ,GAAoCA,EAAe,KAAOA,EAAe,MAAQ,EAO9GK,EAA8BL,GAClC,SAAS,gBAAgB,YAAcA,EAAe,MAAQA,EAAe,MAAQ,EAQjFM,EAAkB,CAACN,EAAyBC,IACXG,EAA0BJ,CAAc,EAEvCC,EAAW,MAAQ,EASrDM,EAAmB,CAACP,EAAyBC,IAC5BK,EAAgBN,EAAgBC,CAAU,EAEzCA,EAAW,MAS7BO,GAAuB,CAACR,EAAyBC,IAChCK,EAAgBN,EAAgBC,CAAU,EAEzCP,EASlBe,GAA0B,CAACT,EAAyBC,IAClCM,EAAiBP,EAAgBC,CAAU,EAE1C,SAAS,gBAAgB,YAAcP,EAS1DgB,GAAwB,CAACV,EAAyBC,IACjDQ,GAAwBT,EAAgBC,CAAU,EAGlDO,GAAqBR,EAAgBC,CAAU,EAI7C,WAHE,OAHA,QAeLU,EAAmB,CAACX,EAAyBC,IACjDD,EAAe,IAAML,EAA4BM,EAAW,OAQxDW,EAAoBZ,GAAoCA,EAAe,OAASL,EAMhFkB,GAAiB,IAAc,SAAS,gBAAgB,YAAcnB,EAAmB,EAMzFoB,GAAwB,IACrB,SAAS,gBAAgB,YAAcrB,EAAkBC,EAAmB,EAQ/EqB,EAAkBf,GAAoCA,EAAe,IAAML,EAA4BE,EAOvGmB,GAAkBhB,GAAoCI,EAA0BJ,CAAc,EAAIJ,EAAiB,EAOnHqB,GAAmBjB,GAAoCK,EAA2BL,CAAc,EAAIJ,EAAiB,EASrHsB,GAAoB,CAAClB,EAAyBC,EAAqBC,IAAyD,CAC1H,MAAAiB,EAAqBT,GAAsBV,EAAgBC,CAAU,EACrEmB,EAAmBrB,EAAoBC,EAAgBC,EAAYC,CAAO,EAEhF,OAAIiB,IAAuB,OACrBC,IAAqBjB,EAAe,cAC/B,YAEF,YAGLgB,IAAuB,QACrBC,IAAqBjB,EAAe,cAC/B,aAEF,aAGLiB,IAAqBjB,EAAe,cAC/B,gBAGF,eACT,EASakB,GAAiB,CAACrB,EAAyBC,EAAqBC,IAAwD,CACnI,MAAMoB,EAAiBJ,GAAkBlB,EAAgBC,EAAYC,CAAO,EACtEqB,EAAeT,GAAsB,EAAuB,OAAnBD,GAAmB,EAElE,OAAIS,IAAmB,YACd,CACL,KAAM5B,EACN,IAAKiB,EAAiBX,EAAgBC,CAAU,EAChD,MAAOsB,CAAA,EAGPD,IAAmB,YACd,CAAE,KAAM5B,EAAkB,IAAKkB,EAAiBZ,CAAc,EAAG,MAAOuB,GAE7ED,IAAmB,aACd,CAAE,MAAO5B,EAAkB,IAAKiB,EAAiBX,EAAgBC,CAAU,EAAG,MAAOsB,GAE1FD,IAAmB,aACd,CAAE,MAAO5B,EAAkB,IAAKkB,EAAiBZ,CAAc,EAAG,MAAOuB,GAG9ED,IAAmB,gBACd,CAAE,KAAMhB,EAAgBN,EAAgBC,CAAU,EAAG,IAAKW,EAAiBZ,CAAc,EAAG,MAAOuB,CAAY,EAGjH,CAAE,KAAMjB,EAAgBN,EAAgBC,CAAU,EAAG,IAAKU,EAAiBX,EAAgBC,CAAU,EAAG,MAAOsB,CAAY,CACpI,EASaC,GAAgB,CAC3BC,EACAzB,EACAoB,IACkB,CACZ,MAAAM,EAASV,GAAehB,CAAc,EACtC2B,EAAUV,GAAgBjB,CAAc,EACxC4B,EAAaH,EAAY,KAAkB3B,EAC3C+B,EAAcJ,EAAY,MAAmB3B,EAEnD,OAAI2B,EAAY,MACVL,IAAqBjB,EAAe,cAC/B,CACL,MAAOwB,EAAUE,EAAaF,EAAUE,EACxC,IAAKd,EAAef,CAAc,CAAA,EAI/B,CACL,MAAO2B,EAAUE,EAAaF,EAAUE,EACxC,IAAK7B,EAAe,MAAA,EAIpBoB,IAAqBjB,EAAe,cAC/B,CACL,KAAMuB,EAASE,EAAYF,EAASE,EACpC,IAAKb,EAAef,CAAc,CAAA,EAI/B,CACL,KAAM0B,EAASE,EAAYF,EAASE,EACpC,IAAK5B,EAAe,MAAA,CAExB,EC7QY,IAAAG,GAAAA,IACVA,EAAA,kBAAoB,oBACpBA,EAAA,cAAgB,gBAChBA,EAAA,cAAgB,gBAHNA,IAAAA,GAAA,CAAA,CAAA,EAiCZ,MAAM2B,EAAUC,EAAM,WAAyD,CAACC,EAAOC,IAAQ,CACvF,KAAA,CACJ,GAAAC,EACA,SAAAC,EACA,cAAAC,EACA,WAAAC,EACA,KAAAC,EAAO,GACP,UAAAC,EAAY,GACZ,QAAArC,EAAU,oBACV,KAAAsC,EACA,OAAAC,EACA,eAAAC,CACE,EAAAV,EAEEW,EAAYN,GAAcO,EAAuB,IAAI,EACrDC,EAAWD,EAAuB,IAAI,EACtC3C,EAAa6C,EAAQH,CAAS,EAC9B,CAAC3C,EAAgB+C,CAAiB,EAAIC,EAAkB,EACxDC,EAAsBC,EAAad,EAAe,CAAC,EAEnDe,EAAuB,IAAY,OACrBJ,GAAAK,EAAAhB,EAAc,UAAd,YAAAgB,EAAuB,uBAAuB,CAAA,EAGlEC,EAAYF,EAAsB,GAAG,EACrCG,EAAeH,EAAsB,CAAC,SAAU,QAAQ,EAAG,EAAE,EAE7DI,EAAU,IAAM,CACOJ,GACvB,EAAG,CAAE,CAAA,EAEL,MAAMK,EAAYhB,IAAS,UAErBiB,EAAiBC,EAAWC,EAAO,QAAS,CAAE,CAACA,EAAO,kBAAkB,CAAC,EAAGH,EAAYlB,EAAOW,GAAuBV,CAAS,EAC/HnB,EAAmBpB,GAAkBC,GAAcF,EAAoBC,EAAgBC,EAAYC,CAAO,EAC1G0D,EAAeF,EAAWC,EAAO,eAAgBjB,EAAgB,CACrE,CAACiB,EAAO,sBAAsB,CAAC,EAAGvC,IAAqB,gBACvD,CAACuC,EAAO,uBAAuB,CAAC,EAAGvC,IAAqB,eAAA,CACzD,EAEKK,EAAczB,GAAkBC,GAAcoB,GAAerB,EAAgBC,EAAYC,CAAO,EAChG2D,EAAapC,GAAezB,GAAkBoB,GAAoBI,GAAcC,EAAazB,EAAgBoB,CAAgB,EAEnI,OAEIW,EAAA,cAAAA,EAAA,SAAA,KAAAA,EAAA,cAAC,MAAA,CACC,GAAAG,EACA,IAAK4B,EAAU,CAAC7B,EAAKU,CAAS,CAAC,EAC/B,UAAWc,EACX,MAAOhC,EACP,cAAagB,EACb,mBAAkBsB,EAAY,QAC9B,KAAAvB,CAAA,EAECL,CACH,kBACC,MAAI,CAAA,IAAKU,EAAU,UAAWe,EAAc,MAAOC,CAAA,CAAY,CAClE,CAEJ,CAAC,EAED/B,EAAQ,YAAc,UAEtB,MAAAkC,GAAelC"}
|
package/RadioButton.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import t from"react";import r from"classnames";import{FormMode as l,FormVariant as
|
|
1
|
+
import t from"react";import r from"classnames";import{FormMode as l,FormVariant as x,AnalyticsId as S}from"./constants.js";import{a as q}from"./uuid.js";import o from"./components/RadioButton/styles.module.scss";const c=t.forwardRef((p,f)=>{const{className:y,defaultChecked:B=!1,disabled:e,label:s,inputId:i=q(),mode:n,name:v=i,variant:N,errorText:a,error:R=!!a,value:g=s,testId:k,required:w,...C}=p,b=R||n===l.oninvalid,u=n===l.ondark,m=n===l.onblueberry,d=N===x.bigform,E=r(o["radio-button-wrapper"],{[o["radio-button-wrapper--with-error"]]:a,[o["radio-button-wrapper--bigform"]]:d}),h=r(o["radio-button-label"],{[o["radio-button-label--disabled"]]:e,[o["radio-button-label--on-dark"]]:u,[o["radio-button-label--on-blueberry"]]:m,[o["radio-button-label--invalid"]]:b,[o["radio-button-label--bigform"]]:d}),F=r(o["radio-button"],{[o["radio-button--on-dark"]]:u,[o["radio-button--disabled"]]:e,[o["radio-button--on-blueberry"]]:m,[o["radio-button--invalid"]]:b},y),I=r(o["radio-button-errors"],{[o["radio-button-errors--bigform"]]:d});return t.createElement("div",{"data-testid":k,"data-analyticsid":S.RadioButton,className:E},a&&t.createElement("p",{className:I},a),t.createElement("label",{htmlFor:i,className:h},t.createElement("input",{id:i,name:v,className:F,type:"radio",disabled:e,value:g,ref:f,defaultChecked:B,required:w,...C}),s))});c.displayName="RadioButton";const V=c;export{V as R,c as a};
|
|
2
2
|
//# sourceMappingURL=RadioButton.js.map
|
package/RadioButton.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioButton.js","sources":["../src/components/RadioButton/RadioButton.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, FormMode, FormVariant } from '../../constants';\nimport { uuid } from '../../utils/uuid';\n\nimport radioButtonStyles from './styles.module.scss';\n\nexport interface RadioButtonProps\n extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'name' | 'value' | 'disabled' | 'defaultChecked' | 'required'> {\n /** Adds custom classes to the element. */\n className?: string;\n /** The label text next to the radioButton */\n label: string;\n /** input id of the radioButton */\n inputId?: string;\n /** Changes the visuals of the radioButton */\n mode?: keyof typeof FormMode;\n /** Changes the visuals of the radioButton */\n variant?: keyof typeof FormVariant;\n /** Activates Error style for the radioButton - This is can be true while errorText is empty, when in a FormGroup */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const RadioButton = React.forwardRef((props: RadioButtonProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n className,\n defaultChecked = false,\n disabled,\n label,\n inputId = uuid(),\n mode,\n name = inputId,\n variant,\n errorText,\n error = !!errorText,\n value = label,\n testId,\n required,\n ...rest\n } = props;\n const invalid = error || mode === FormMode.oninvalid;\n const onDark = mode === FormMode.ondark;\n const onBlueberry = mode === FormMode.onblueberry;\n const bigform = variant === FormVariant.bigform;\n\n const radioButtonWrapperClasses = classNames(radioButtonStyles['radio-button-wrapper'], {\n [radioButtonStyles['radio-button-wrapper--with-error']]: errorText,\n [radioButtonStyles['radio-button-wrapper--bigform']]: bigform,\n });\n const radioButtonLabelClasses = classNames(radioButtonStyles['radio-button-label'], {\n [radioButtonStyles['radio-button-label--disabled']]: disabled,\n [radioButtonStyles['radio-button-label--on-dark']]: onDark,\n [radioButtonStyles['radio-button-label--on-blueberry']]: onBlueberry,\n [radioButtonStyles['radio-button-label--invalid']]: invalid,\n [radioButtonStyles['radio-button-label--bigform']]: bigform,\n });\n const radioButtonClasses = classNames(\n radioButtonStyles['radio-button'],\n {\n [radioButtonStyles['radio-button--on-dark']]: onDark,\n [radioButtonStyles['radio-button--disabled']]: disabled,\n [radioButtonStyles['radio-button--on-blueberry']]: onBlueberry,\n [radioButtonStyles['radio-button--invalid']]: invalid,\n },\n className\n );\n const errorStyles = classNames(radioButtonStyles['radio-button-errors'], {\n [radioButtonStyles['radio-button-errors--bigform']]: bigform,\n });\n\n return (\n <div data-testid={testId} data-analyticsid={AnalyticsId.RadioButton} className={radioButtonWrapperClasses}>\n {errorText && <p className={errorStyles}>{errorText}</p>}\n <label htmlFor={inputId} className={radioButtonLabelClasses}>\n <input\n id={inputId}\n name={name}\n className={radioButtonClasses}\n type=\"radio\"\n disabled={disabled}\n value={value}\n ref={ref}\n
|
|
1
|
+
{"version":3,"file":"RadioButton.js","sources":["../src/components/RadioButton/RadioButton.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, FormMode, FormVariant } from '../../constants';\nimport { uuid } from '../../utils/uuid';\n\nimport radioButtonStyles from './styles.module.scss';\n\nexport interface RadioButtonProps\n extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'name' | 'value' | 'disabled' | 'defaultChecked' | 'required'> {\n /** Adds custom classes to the element. */\n className?: string;\n /** The label text next to the radioButton */\n label: string;\n /** input id of the radioButton */\n inputId?: string;\n /** Changes the visuals of the radioButton */\n mode?: keyof typeof FormMode;\n /** Changes the visuals of the radioButton */\n variant?: keyof typeof FormVariant;\n /** Activates Error style for the radioButton - This is can be true while errorText is empty, when in a FormGroup */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const RadioButton = React.forwardRef((props: RadioButtonProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n className,\n defaultChecked = false,\n disabled,\n label,\n inputId = uuid(),\n mode,\n name = inputId,\n variant,\n errorText,\n error = !!errorText,\n value = label,\n testId,\n required,\n ...rest\n } = props;\n const invalid = error || mode === FormMode.oninvalid;\n const onDark = mode === FormMode.ondark;\n const onBlueberry = mode === FormMode.onblueberry;\n const bigform = variant === FormVariant.bigform;\n\n const radioButtonWrapperClasses = classNames(radioButtonStyles['radio-button-wrapper'], {\n [radioButtonStyles['radio-button-wrapper--with-error']]: errorText,\n [radioButtonStyles['radio-button-wrapper--bigform']]: bigform,\n });\n const radioButtonLabelClasses = classNames(radioButtonStyles['radio-button-label'], {\n [radioButtonStyles['radio-button-label--disabled']]: disabled,\n [radioButtonStyles['radio-button-label--on-dark']]: onDark,\n [radioButtonStyles['radio-button-label--on-blueberry']]: onBlueberry,\n [radioButtonStyles['radio-button-label--invalid']]: invalid,\n [radioButtonStyles['radio-button-label--bigform']]: bigform,\n });\n const radioButtonClasses = classNames(\n radioButtonStyles['radio-button'],\n {\n [radioButtonStyles['radio-button--on-dark']]: onDark,\n [radioButtonStyles['radio-button--disabled']]: disabled,\n [radioButtonStyles['radio-button--on-blueberry']]: onBlueberry,\n [radioButtonStyles['radio-button--invalid']]: invalid,\n },\n className\n );\n const errorStyles = classNames(radioButtonStyles['radio-button-errors'], {\n [radioButtonStyles['radio-button-errors--bigform']]: bigform,\n });\n\n return (\n <div data-testid={testId} data-analyticsid={AnalyticsId.RadioButton} className={radioButtonWrapperClasses}>\n {errorText && <p className={errorStyles}>{errorText}</p>}\n <label htmlFor={inputId} className={radioButtonLabelClasses}>\n <input\n id={inputId}\n name={name}\n className={radioButtonClasses}\n type=\"radio\"\n disabled={disabled}\n value={value}\n ref={ref}\n defaultChecked={defaultChecked}\n required={required}\n {...rest}\n />\n {label}\n </label>\n </div>\n );\n});\n\nRadioButton.displayName = 'RadioButton';\n\nexport default RadioButton;\n"],"names":["RadioButton","React","props","ref","className","defaultChecked","disabled","label","inputId","uuid","mode","name","variant","errorText","error","value","testId","required","rest","invalid","FormMode","onDark","onBlueberry","bigform","FormVariant","radioButtonWrapperClasses","classNames","radioButtonStyles","radioButtonLabelClasses","radioButtonClasses","errorStyles","AnalyticsId","RadioButton$1"],"mappings":"oNA6BO,MAAMA,EAAcC,EAAM,WAAW,CAACC,EAAyBC,IAAqC,CACnG,KAAA,CACJ,UAAAC,EACA,eAAAC,EAAiB,GACjB,SAAAC,EACA,MAAAC,EACA,QAAAC,EAAUC,EAAK,EACf,KAAAC,EACA,KAAAC,EAAOH,EACP,QAAAI,EACA,UAAAC,EACA,MAAAC,EAAQ,CAAC,CAACD,EACV,MAAAE,EAAQR,EACR,OAAAS,EACA,SAAAC,EACA,GAAGC,CACD,EAAAhB,EACEiB,EAAUL,GAASJ,IAASU,EAAS,UACrCC,EAASX,IAASU,EAAS,OAC3BE,EAAcZ,IAASU,EAAS,YAChCG,EAAUX,IAAYY,EAAY,QAElCC,EAA4BC,EAAWC,EAAkB,sBAAsB,EAAG,CACtF,CAACA,EAAkB,kCAAkC,CAAC,EAAGd,EACzD,CAACc,EAAkB,+BAA+B,CAAC,EAAGJ,CAAA,CACvD,EACKK,EAA0BF,EAAWC,EAAkB,oBAAoB,EAAG,CAClF,CAACA,EAAkB,8BAA8B,CAAC,EAAGrB,EACrD,CAACqB,EAAkB,6BAA6B,CAAC,EAAGN,EACpD,CAACM,EAAkB,kCAAkC,CAAC,EAAGL,EACzD,CAACK,EAAkB,6BAA6B,CAAC,EAAGR,EACpD,CAACQ,EAAkB,6BAA6B,CAAC,EAAGJ,CAAA,CACrD,EACKM,EAAqBH,EACzBC,EAAkB,cAAc,EAChC,CACE,CAACA,EAAkB,uBAAuB,CAAC,EAAGN,EAC9C,CAACM,EAAkB,wBAAwB,CAAC,EAAGrB,EAC/C,CAACqB,EAAkB,4BAA4B,CAAC,EAAGL,EACnD,CAACK,EAAkB,uBAAuB,CAAC,EAAGR,CAChD,EACAf,CAAA,EAEI0B,EAAcJ,EAAWC,EAAkB,qBAAqB,EAAG,CACvE,CAACA,EAAkB,8BAA8B,CAAC,EAAGJ,CAAA,CACtD,EAGC,OAAAtB,EAAA,cAAC,OAAI,cAAae,EAAQ,mBAAkBe,EAAY,YAAa,UAAWN,CAC7E,EAAAZ,mBAAc,IAAE,CAAA,UAAWiB,GAAcjB,CAAU,kBACnD,QAAM,CAAA,QAASL,EAAS,UAAWoB,CAClC,EAAA3B,EAAA,cAAC,QAAA,CACC,GAAIO,EACJ,KAAAG,EACA,UAAWkB,EACX,KAAK,QACL,SAAAvB,EACA,MAAAS,EACA,IAAAZ,EACA,eAAAE,EACA,SAAAY,EACC,GAAGC,CAAA,CAAA,EAELX,CACH,CACF,CAEJ,CAAC,EAEDP,EAAY,YAAc,cAE1B,MAAAgC,EAAehC"}
|
package/Textarea.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import a,{useState as A,useRef as ee,useEffect as te}from"react";import d from"classnames";import{FormMode as h,AnalyticsId as ae,AVERAGE_CHARACTER_WIDTH_PX as re}from"./constants.js";import{a as ne}from"./uuid.js";import{E as oe}from"./ErrorWrapper.js";import{M as se}from"./MaxCharacters.js";import t from"./components/Textarea/styles.module.scss";const le=o=>{const p="2rem",n="16px",m="4px";return`calc(${o*re}px + ${p} + ${n} + ${m})`},M=a.forwardRef((o,p)=>{const{maxCharacters:n,maxText:m,width:u,testId:$,defaultValue:f,marginBottom:k,transparent:B,mode:s,label:w,textareaId:b=ne(),minRows:E=3,maxRows:l=10,grow:g,errorText:C,afterLabelChildren:_,belowLabelChildren:T,autoFocus:L,disabled:F,name:S,autoComplete:D,placeholder:V,readOnly:q,required:z,onChange:v,...G}=o,[O,R]=A(E),[W,P]=A(f||""),c=ee(null),y=e=>{const i=e.rows;e.rows=E;const r=Math.floor((e.scrollHeight-16)/28);r===i&&(e.rows=r),r>=l&&(e.rows=l,e.scrollTop=e.scrollHeight),r<l?R(r):R(l)},H=s===h.ondark,X=s===h.onblueberry,j=!!n&&W.toString().length>n,N=s===h.oninvalid||!!C||j,J=d(t.textarea,{[t["textarea--gutterBottom"]]:k}),K=d(t["textarea__label-wrapper"],{[t["textarea__label-wrapper--on-dark"]]:H}),Q=d(t["content-wrapper"],{[t["content-wrapper--transparent"]]:B,[t["content-wrapper--on-blueberry"]]:X,[t["content-wrapper--on-dark"]]:H,[t["content-wrapper--invalid"]]:N,[t["content-wrapper--disabled"]]:o.disabled}),U=d(t["content-wrapper__input"],{[t["content-wrapper__input--disabled"]]:o.disabled});te(()=>{var e,x,i;if(g&&((e=c.current)!=null&&e.children)&&((x=c.current)!=null&&x.children[0])){const r=(i=c.current)==null?void 0:i.children[0];y(r)}},[]);const Y=e=>{g&&y(e.target),P(e.target.value)},Z=e=>{v&&v(e),Y(e)},I=u?le(u):void 0;return a.createElement(oe,{errorText:C},a.createElement("div",{"data-testid":$,"data-analyticsid":ae.Textarea,className:J},w&&a.createElement("div",{className:K},a.createElement("label",{htmlFor:b},w),_&&a.createElement("div",{className:t["textarea__after-label-children"]},_)),T&&a.createElement("div",null,T),a.createElement("div",{className:Q,ref:c,style:{maxWidth:I}},a.createElement("textarea",{rows:O,defaultValue:f,id:b,className:U,ref:p,"aria-invalid":!!N,autoFocus:L,disabled:F,name:S,autoComplete:D,placeholder:V,readOnly:q,required:z,onChange:Z,...G})),n&&a.createElement(se,{maxCharacters:n,length:W.toString().length,maxText:m,mode:s,maxWidth:I})))});M.displayName="Textarea";const ue=M;export{ue as T};
|
|
2
2
|
//# sourceMappingURL=Textarea.js.map
|