@helsenorge/designsystem-react 8.6.0-beta.1 → 8.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,28 @@
1
- ## 8.6.0-beta.0 (2024-09-24)
1
+ ## [8.7.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv8.6.0&targetVersion=GTv8.7.0) (2024-10-17)
2
+
3
+ ### Features
4
+
5
+ - **datetime:** får onblur prop ([31fe602](https://github.com/helsenorge/designsystem/commit/31fe602a68f12c39e48a55b5559fcd812be97785)),
6
+ closes [#334254](https://github.com/helsenorge/designsystem/issues/334254)
7
+
8
+ ## [8.6.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv8.5.1&targetVersion=GTv8.6.0) (2024-10-09)
9
+
10
+ ### Features
11
+
12
+ - **datepicker:** legg til prop for å sette posisjon på datepicker popup
13
+ ([0f392ed](https://github.com/helsenorge/designsystem/commit/0f392ed1f5fc76be0fbfdeb5262f64071cbf4dc0)), closes
14
+ [#326998](https://github.com/helsenorge/designsystem/issues/326998)
15
+ - **datetime:** value prop og defaultvalue settes riktig
16
+ ([a3d8617](https://github.com/helsenorge/designsystem/commit/a3d86173269cd5a1dd9d8cd1f13a2512b2fb87fd)), closes
17
+ [#332561](https://github.com/helsenorge/designsystem/issues/332561)
18
+ - **label:** gi mulighet for å rendre label med andre tags
19
+ ([9f952dd](https://github.com/helsenorge/designsystem/commit/9f952ddd0eac84e1426d070685998e950fa9e9f8)), closes
20
+ [#331803](https://github.com/helsenorge/designsystem/issues/331803)
21
+ - **tabs:** endre default touch behaviour til å være none
22
+ ([4101ce2](https://github.com/helsenorge/designsystem/commit/4101ce2a85f84e26b9fcfd61990ca8792f72b55c)), closes
23
+ [#331142](https://github.com/helsenorge/designsystem/issues/331142)
24
+
25
+ ## [8.5.1](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv8.5.0&targetVersion=GTv8.5.1) (2024-09-25)
2
26
 
3
27
  ### Bug Fixes
4
28
 
@@ -1781,12 +1805,12 @@ Dette er fordi vi skal kunne dynamisk importere alt som ligger i Icons, så da b
1781
1805
 
1782
1806
  ### Bug Fixes
1783
1807
 
1784
- - panel har avstand fra tittel til badge
1785
- ([09034c4](https://github.com/helsenorge/designsystem/commit/09034c4844408c7cfe8f65d7a1a0d82a7828c2ef)), closes
1786
- [#282359](https://github.com/helsenorge/designsystem/issues/282359)
1787
1808
  - økt kontrast på understreking av lenker
1788
1809
  ([50b7fa4](https://github.com/helsenorge/designsystem/commit/50b7fa47fb44cb7d75fb877bd53e2309b35e1e21)), closes
1789
1810
  [#229049](https://github.com/helsenorge/designsystem/issues/229049)
1811
+ - panel har avstand fra tittel til badge
1812
+ ([09034c4](https://github.com/helsenorge/designsystem/commit/09034c4844408c7cfe8f65d7a1a0d82a7828c2ef)), closes
1813
+ [#282359](https://github.com/helsenorge/designsystem/issues/282359)
1790
1814
 
1791
1815
  ## [1.2.2](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv1.2.1&targetVersion=GTv1.2.2) (2022-08-31)
1792
1816
 
package/Input.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\n\nimport cn from 'classnames';\n\nimport { FormMode, FormSize, AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX } from '../../constants';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { useUuid } from '../../hooks/useUuid';\nimport { getColor } from '../../theme/currys';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { mergeRefs } from '../../utils/refs';\nimport ErrorWrapper from '../ErrorWrapper';\nimport Icon, { IconSize, SvgIcon } from '../Icon';\nimport { IconName } from '../Icons/IconNames';\nimport { renderLabel } from '../Label';\nimport LazyIcon from '../LazyIcon';\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-describedby'\n | 'aria-labelledby'\n | 'onBlur'\n | 'onClick'\n | 'onChange'\n | 'onFocus'\n | 'onKeyDown'\n | 'autoFocus'\n > {\n /** The number at which the input field starts when you increment or decrement it */\n baseIncrementValue?: number;\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 /** 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 | IconName;\n /** Places the icon to the right */\n iconRight?: boolean;\n /** Ref that is placed on the inputContainerRef */\n inputContainerRef?: React.RefObject<HTMLDivElement>;\n /** Ref that is placed on the inputWrapper */\n inputWrapperRef?: React.RefObject<HTMLDivElement>;\n /** Changes the color profile of the input */\n mode?: keyof typeof FormMode;\n /** Changes the visuals of the input */\n size?: keyof typeof FormSize;\n /** Label of the input */\n label?: React.ReactNode;\n /** Activates Error style for the input */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Component shown after input */\n afterInputChildren?: React.ReactNode;\n /** Component shown to the right of input */\n rightOfInput?: 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 name,\n transparent = false,\n icon,\n iconRight,\n inputId,\n inputWrapperRef,\n mode = FormMode.onwhite,\n size,\n baseIncrementValue,\n label,\n error,\n errorText,\n errorTextId,\n testId,\n disabled,\n readOnly,\n autoComplete = 'off',\n afterInputChildren,\n rightOfInput,\n width,\n required,\n onChange,\n onKeyDown,\n autoFocus,\n maxCharacters,\n maxText,\n inputContainerRef,\n ...rest\n } = props;\n const breakpoint = useBreakpoint();\n const inputContainerRefLocal = useRef<HTMLDivElement>(null);\n const inputIdState = useUuid(inputId);\n const [input, setInput] = useState(defaultValue || '');\n const [prevValue, setPrevValue] = useState<string | number | undefined>(undefined);\n const numKeyPressed = useRef<boolean>(false);\n const errorTextUuid = useUuid(errorTextId);\n const numRegex = /^[0-9]$/;\n\n useEffect(() => {\n setInput(defaultValue || '');\n }, [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 isLarge = size === FormSize.large;\n const isTransparent = transparent && mode !== FormMode.ondark && !onError;\n\n const inputWrapperClass = cn(styles['input-wrapper'], className);\n\n const inputContainer = cn(styles['input-container'], {\n [styles['input-container--transparent']]: isTransparent,\n [styles['input-container--on-blueberry']]: onBlueberry,\n [styles['input-container--on-dark']]: onDark,\n [styles['input-container--invalid']]: onError,\n [styles['input-container--large']]: isLarge,\n [styles['input-container--disabled']]: disabled,\n [styles['input-container--with-icon']]: icon,\n });\n\n const inputClass = cn(styles['input-container__input'], {\n [styles['input-container__input--large']]: isLarge,\n [styles['input-container__input--disabled']]: disabled,\n });\n\n const iconColor = disabled ? getColor('neutral', 700) : getColor('black');\n const iconSize = breakpoint === Breakpoint.xs || !isLarge ? IconSize.XSmall : IconSize.Small;\n\n const renderIcon = (): React.ReactNode => {\n if (!icon) {\n return;\n }\n\n if (typeof icon === 'string') {\n return <LazyIcon className={styles['input-container__input__icon']} color={iconColor} size={iconSize} iconName={icon} />;\n }\n\n return <Icon className={styles['input-container__input__icon']} color={iconColor} size={iconSize} svgIcon={icon} />;\n };\n\n // eslint-disable-next-line\n const handleClick = (e: React.MouseEvent<any>): void => {\n if (inputContainerRefLocal && inputContainerRefLocal.current && icon) {\n const selectedChild = iconRight ? 0 : 1;\n const input = inputContainerRefLocal.current.children[selectedChild] as HTMLInputElement;\n input.focus();\n\n props.onClick && props.onClick(e);\n }\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const newValue = getIncrementValue(e);\n\n if (onChange) {\n onChange(e);\n }\n\n setInput(newValue);\n setPrevValue(newValue);\n };\n\n // Hvis bruker endrer number value med 1 og det skal startes på en annen verdi enn 0\n const getIncrementValue = (e: React.ChangeEvent<HTMLInputElement>): string => {\n if (typeof baseIncrementValue === 'undefined' || type !== 'number') return e.target.value;\n\n const valueAsNumber = Number(e.target.value);\n\n if (!prevValue && !numKeyPressed.current && (valueAsNumber === 1 || valueAsNumber === -1)) {\n e.target.value = baseIncrementValue + '';\n }\n\n return e.target.value;\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (numRegex.test(e.key)) {\n numKeyPressed.current = true;\n }\n onKeyDown && onKeyDown(e);\n };\n\n const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (numRegex.test(e.key)) {\n numKeyPressed.current = false;\n }\n };\n\n const maxWidth = width ? getInputMaxWidth(width, !!icon, iconSize) : undefined;\n\n return (\n <ErrorWrapper errorText={errorText} errorTextId={errorTextUuid}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Input} className={inputWrapperClass} ref={inputWrapperRef}>\n {renderLabel(label, inputIdState, mode as FormMode)}\n {/* input-elementet tillater keyboard-interaksjon */}\n <div className={styles['content-wrapper']}>\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}\n <div\n onClick={handleClick}\n ref={mergeRefs([inputContainerRefLocal, inputContainerRef])}\n className={inputContainer}\n style={{ maxWidth }}\n >\n {!iconRight && renderIcon()}\n <input\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n name={name}\n type={type}\n defaultValue={defaultValue}\n id={inputIdState}\n className={inputClass}\n ref={ref}\n aria-labelledby={props['aria-labelledby'] ?? undefined}\n aria-describedby={getAriaDescribedBy(props, errorTextUuid)}\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 <div className={styles['content-wrapper__right-of-input']}>{rightOfInput}</div>\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","AVERAGE_CHARACTER_WIDTH_PX","Input","React","props","ref","className","defaultValue","placeholder","type","name","transparent","icon","iconRight","inputId","inputWrapperRef","mode","FormMode","size","baseIncrementValue","label","error","errorText","errorTextId","testId","disabled","readOnly","autoComplete","afterInputChildren","rightOfInput","width","required","onChange","onKeyDown","autoFocus","maxCharacters","maxText","inputContainerRef","rest","breakpoint","useBreakpoint","inputContainerRefLocal","useRef","inputIdState","useUuid","input","setInput","useState","prevValue","setPrevValue","numKeyPressed","errorTextUuid","numRegex","useEffect","onDark","onBlueberry","maxCharactersExceeded","onError","isLarge","FormSize","isTransparent","inputWrapperClass","cn","styles","inputContainer","inputClass","iconColor","getColor","Breakpoint","IconSize","renderIcon","jsx","LazyIcon","Icon","handleClick","e","selectedChild","handleChange","newValue","getIncrementValue","valueAsNumber","handleKeyDown","handleKeyUp","maxWidth","ErrorWrapper","jsxs","AnalyticsId","renderLabel","mergeRefs","getAriaDescribedBy","MaxCharacters"],"mappings":"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"}
1
+ {"version":3,"file":"Input.js","sources":["../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\n\nimport cn from 'classnames';\n\nimport { FormMode, FormSize, AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX } from '../../constants';\nimport { Breakpoint, useBreakpoint } from '../../hooks/useBreakpoint';\nimport { useUuid } from '../../hooks/useUuid';\nimport { getColor } from '../../theme/currys';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { mergeRefs } from '../../utils/refs';\nimport ErrorWrapper from '../ErrorWrapper';\nimport Icon, { IconSize, SvgIcon } from '../Icon';\nimport { IconName } from '../Icons/IconNames';\nimport { renderLabel } from '../Label';\nimport LazyIcon from '../LazyIcon';\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-describedby'\n | 'aria-labelledby'\n | 'onBlur'\n | 'onClick'\n | 'onChange'\n | 'onFocus'\n | 'onKeyDown'\n | 'autoFocus'\n | 'inputMode'\n > {\n /** The number at which the input field starts when you increment or decrement it */\n baseIncrementValue?: number;\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 /** 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 | IconName;\n /** Places the icon to the right */\n iconRight?: boolean;\n /** Ref that is placed on the inputContainerRef */\n inputContainerRef?: React.RefObject<HTMLDivElement>;\n /** Ref that is placed on the inputWrapper */\n inputWrapperRef?: React.RefObject<HTMLDivElement>;\n /** Changes the color profile of the input */\n mode?: keyof typeof FormMode;\n /** Changes the visuals of the input */\n size?: keyof typeof FormSize;\n /** Label of the input */\n label?: React.ReactNode;\n /** Activates Error style for the input */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Component shown after input */\n afterInputChildren?: React.ReactNode;\n /** Component shown to the right of input */\n rightOfInput?: 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 name,\n transparent = false,\n icon,\n iconRight,\n inputId,\n inputWrapperRef,\n mode = FormMode.onwhite,\n size,\n baseIncrementValue,\n label,\n error,\n errorText,\n errorTextId,\n testId,\n disabled,\n readOnly,\n autoComplete = 'off',\n afterInputChildren,\n rightOfInput,\n width,\n required,\n onChange,\n onKeyDown,\n autoFocus,\n maxCharacters,\n maxText,\n inputContainerRef,\n ...rest\n } = props;\n const breakpoint = useBreakpoint();\n const inputContainerRefLocal = useRef<HTMLDivElement>(null);\n const inputIdState = useUuid(inputId);\n const [input, setInput] = useState(defaultValue || '');\n const [prevValue, setPrevValue] = useState<string | number | undefined>(undefined);\n const numKeyPressed = useRef<boolean>(false);\n const errorTextUuid = useUuid(errorTextId);\n const numRegex = /^[0-9]$/;\n\n useEffect(() => {\n setInput(defaultValue || '');\n }, [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 isLarge = size === FormSize.large;\n const isTransparent = transparent && mode !== FormMode.ondark && !onError;\n\n const inputWrapperClass = cn(styles['input-wrapper'], className);\n\n const inputContainer = cn(styles['input-container'], {\n [styles['input-container--transparent']]: isTransparent,\n [styles['input-container--on-blueberry']]: onBlueberry,\n [styles['input-container--on-dark']]: onDark,\n [styles['input-container--invalid']]: onError,\n [styles['input-container--large']]: isLarge,\n [styles['input-container--disabled']]: disabled,\n [styles['input-container--with-icon']]: icon,\n });\n\n const inputClass = cn(styles['input-container__input'], {\n [styles['input-container__input--large']]: isLarge,\n [styles['input-container__input--disabled']]: disabled,\n });\n\n const iconColor = disabled ? getColor('neutral', 700) : getColor('black');\n const iconSize = breakpoint === Breakpoint.xs || !isLarge ? IconSize.XSmall : IconSize.Small;\n\n const renderIcon = (): React.ReactNode => {\n if (!icon) {\n return;\n }\n\n if (typeof icon === 'string') {\n return <LazyIcon className={styles['input-container__input__icon']} color={iconColor} size={iconSize} iconName={icon} />;\n }\n\n return <Icon className={styles['input-container__input__icon']} color={iconColor} size={iconSize} svgIcon={icon} />;\n };\n\n // eslint-disable-next-line\n const handleClick = (e: React.MouseEvent<any>): void => {\n if (inputContainerRefLocal && inputContainerRefLocal.current && icon) {\n const selectedChild = iconRight ? 0 : 1;\n const input = inputContainerRefLocal.current.children[selectedChild] as HTMLInputElement;\n input.focus();\n\n props.onClick && props.onClick(e);\n }\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const newValue = getIncrementValue(e);\n\n if (onChange) {\n onChange(e);\n }\n\n setInput(newValue);\n setPrevValue(newValue);\n };\n\n // Hvis bruker endrer number value med 1 og det skal startes på en annen verdi enn 0\n const getIncrementValue = (e: React.ChangeEvent<HTMLInputElement>): string => {\n if (typeof baseIncrementValue === 'undefined' || type !== 'number') return e.target.value;\n\n const valueAsNumber = Number(e.target.value);\n\n if (!prevValue && !numKeyPressed.current && (valueAsNumber === 1 || valueAsNumber === -1)) {\n e.target.value = baseIncrementValue + '';\n }\n\n return e.target.value;\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (numRegex.test(e.key)) {\n numKeyPressed.current = true;\n }\n onKeyDown && onKeyDown(e);\n };\n\n const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (numRegex.test(e.key)) {\n numKeyPressed.current = false;\n }\n };\n\n const maxWidth = width ? getInputMaxWidth(width, !!icon, iconSize) : undefined;\n\n return (\n <ErrorWrapper errorText={errorText} errorTextId={errorTextUuid}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Input} className={inputWrapperClass} ref={inputWrapperRef}>\n {renderLabel(label, inputIdState, mode as FormMode)}\n {/* input-elementet tillater keyboard-interaksjon */}\n <div className={styles['content-wrapper']}>\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}\n <div\n onClick={handleClick}\n ref={mergeRefs([inputContainerRefLocal, inputContainerRef])}\n className={inputContainer}\n style={{ maxWidth }}\n >\n {!iconRight && renderIcon()}\n <input\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n name={name}\n type={type}\n defaultValue={defaultValue}\n id={inputIdState}\n className={inputClass}\n ref={ref}\n aria-labelledby={props['aria-labelledby'] ?? undefined}\n aria-describedby={getAriaDescribedBy(props, errorTextUuid)}\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 <div className={styles['content-wrapper__right-of-input']}>{rightOfInput}</div>\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","AVERAGE_CHARACTER_WIDTH_PX","Input","React","props","ref","className","defaultValue","placeholder","type","name","transparent","icon","iconRight","inputId","inputWrapperRef","mode","FormMode","size","baseIncrementValue","label","error","errorText","errorTextId","testId","disabled","readOnly","autoComplete","afterInputChildren","rightOfInput","width","required","onChange","onKeyDown","autoFocus","maxCharacters","maxText","inputContainerRef","rest","breakpoint","useBreakpoint","inputContainerRefLocal","useRef","inputIdState","useUuid","input","setInput","useState","prevValue","setPrevValue","numKeyPressed","errorTextUuid","numRegex","useEffect","onDark","onBlueberry","maxCharactersExceeded","onError","isLarge","FormSize","isTransparent","inputWrapperClass","cn","styles","inputContainer","inputClass","iconColor","getColor","Breakpoint","IconSize","renderIcon","jsx","LazyIcon","Icon","handleClick","e","selectedChild","handleChange","newValue","getIncrementValue","valueAsNumber","handleKeyDown","handleKeyUp","maxWidth","ErrorWrapper","jsxs","AnalyticsId","renderLabel","mergeRefs","getAriaDescribedBy","MaxCharacters"],"mappings":"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"}
package/Label.js CHANGED
@@ -1,38 +1,40 @@
1
- import { jsxs as m, Fragment as x, jsx as t } from "react/jsx-runtime";
2
- import S from "react";
3
- import y from "classnames";
4
- import { AnalyticsId as L, FormMode as u } from "./constants.js";
5
- import { S as N } from "./Spacer.js";
1
+ import { jsxs as p, Fragment as F, jsx as t } from "react/jsx-runtime";
2
+ import y from "react";
3
+ import x from "classnames";
4
+ import { AnalyticsId as v, FormMode as S } from "./constants.js";
5
+ import { S as g } from "./Spacer.js";
6
6
  import a from "./components/Label/styles.module.scss";
7
- import { isComponent as b } from "./utils/component.js";
8
- import { S as z } from "./StatusDot.js";
9
- const A = ({ className: e, id: r, mode: s, sublabelTexts: n, testId: o }) => {
10
- const l = (p) => n && n.map((c, h) => {
11
- const F = y(a.label, a["label--sublabel"], {
7
+ import { isComponent as u } from "./utils/component.js";
8
+ import { S as j } from "./StatusDot.js";
9
+ const z = ({ className: e, id: r, mode: s, sublabelTexts: n, testId: l }) => {
10
+ const o = (m) => n && n.map((c, h) => {
11
+ const b = x(a.label, a["label--sublabel"], {
12
12
  [a["label--semibold"]]: c.type === "semibold",
13
- [a["label--on-dark"]]: s === u.ondark
13
+ [a["label--on-dark"]]: s === S.ondark
14
14
  });
15
- return p === c.hideFromScreenReader && /* @__PURE__ */ t("span", { className: F, children: c.text }, h);
16
- }), i = l(), d = l(!0);
17
- return /* @__PURE__ */ m(x, { children: [
18
- /* @__PURE__ */ t(N, { size: "3xs" }),
19
- i && /* @__PURE__ */ t("div", { className: e, id: r, "data-testid": o, "data-analyticsid": L.Sublabel, children: i }),
20
- d && /* @__PURE__ */ t("div", { className: e, "data-testid": o, children: d })
15
+ return m === c.hideFromScreenReader && /* @__PURE__ */ t("span", { className: b, children: c.text }, h);
16
+ }), i = o(), d = o(!0);
17
+ return /* @__PURE__ */ p(F, { children: [
18
+ /* @__PURE__ */ t(g, { size: "3xs" }),
19
+ i && /* @__PURE__ */ t("div", { className: e, id: r, "data-testid": l, "data-analyticsid": v.Sublabel, children: i }),
20
+ d && /* @__PURE__ */ t("div", { className: e, "data-testid": l, children: d })
21
21
  ] });
22
- }, G = (e) => {
22
+ }, K = (e) => {
23
23
  let r = "";
24
- return b(e, f) && e.props.labelTexts.forEach((s) => {
24
+ return u(e, f) && e.props.labelTexts.forEach((s) => {
25
25
  r += s.hideFromScreenReader ? "" : s.text;
26
26
  }), r;
27
- }, J = (e, r, s) => /* @__PURE__ */ t(x, { children: e && b(e, f) ? S.cloneElement(e, {
27
+ }, O = (e, r, s, n) => /* @__PURE__ */ t(F, { children: e && u(e, f) ? y.cloneElement(e, {
28
28
  htmlFor: r,
29
+ htmlMarkup: n || "label",
29
30
  mode: s
30
- }) : typeof e == "string" && /* @__PURE__ */ t(f, { labelTexts: [{ text: e, type: "semibold" }], htmlFor: r, mode: s }) }), K = (e, r, s, n, o, l, i, d) => /* @__PURE__ */ t(x, { children: e && b(e, f) ? S.cloneElement(e, {
31
+ }) : typeof e == "string" && /* @__PURE__ */ t(f, { labelTexts: [{ text: e, type: "semibold" }], htmlFor: r, mode: s }) }), Q = (e, r, s, n, l, o, i, d, m) => /* @__PURE__ */ t(F, { children: e && u(e, f) ? y.cloneElement(e, {
31
32
  htmlFor: s,
32
33
  mode: n,
33
34
  children: r,
34
- labelClassName: y(o, e.props.labelClassName),
35
- labelTextClassName: l,
35
+ labelClassName: x(l, e.props.labelClassName),
36
+ labelTextClassName: o,
37
+ htmlMarkup: m || "label",
36
38
  sublabelWrapperClassName: i,
37
39
  sublabel: d ? void 0 : e.props.sublabel,
38
40
  statusDot: d ? void 0 : e.props.statusDot
@@ -42,8 +44,9 @@ const A = ({ className: e, id: r, mode: s, sublabelTexts: n, testId: o }) => {
42
44
  labelTexts: [{ text: e }],
43
45
  htmlFor: s,
44
46
  mode: n,
45
- labelClassName: o,
46
- labelTextClassName: l,
47
+ htmlMarkup: m || "label",
48
+ labelClassName: l,
49
+ labelTextClassName: o,
47
50
  sublabelWrapperClassName: i,
48
51
  children: r
49
52
  }
@@ -52,45 +55,46 @@ const A = ({ className: e, id: r, mode: s, sublabelTexts: n, testId: o }) => {
52
55
  children: r,
53
56
  className: s,
54
57
  htmlFor: n,
58
+ htmlMarkup: l = "label",
55
59
  labelClassName: o,
56
- labelTextClassName: l,
57
- labelId: i,
58
- labelTexts: d,
59
- mode: p = u.onwhite,
60
- statusDot: c,
61
- sublabel: h,
62
- sublabelWrapperClassName: F,
63
- testId: k
60
+ labelTextClassName: i,
61
+ labelId: d,
62
+ labelTexts: m,
63
+ mode: c = S.onwhite,
64
+ statusDot: h,
65
+ sublabel: b,
66
+ sublabelWrapperClassName: L,
67
+ testId: N
64
68
  }) => {
65
- const w = r && typeof r < "u", g = y(
69
+ const w = r && typeof r < "u", E = x(
66
70
  a["label-wrapper"],
67
71
  { [a["label-wrapper--no-bottom-margin"]]: w, [a["label-wrapper--after-label-children"]]: e },
68
72
  s
69
- ), E = () => d.map((v, R) => {
70
- const j = y(
73
+ ), C = () => m.map((k, M) => {
74
+ const R = x(
71
75
  a.label,
72
76
  {
73
- [a["label--semibold"]]: v.type === "semibold",
74
- [a["label--on-dark"]]: p === u.ondark
77
+ [a["label--semibold"]]: k.type === "semibold",
78
+ [a["label--on-dark"]]: c === S.ondark
75
79
  },
76
- l
80
+ i
77
81
  );
78
- return /* @__PURE__ */ t("span", { "aria-hidden": v.hideFromScreenReader, className: j, children: v.text }, R);
82
+ return /* @__PURE__ */ t("span", { "aria-hidden": k.hideFromScreenReader, className: R, children: k.text }, M);
79
83
  });
80
- return /* @__PURE__ */ m("div", { className: g, children: [
81
- /* @__PURE__ */ m("div", { children: [
82
- /* @__PURE__ */ t("label", { className: o, id: i, htmlFor: n, "data-testid": k, "data-analyticsid": L.Label, children: /* @__PURE__ */ m("span", { className: a["label-content-wrapper"], children: [
84
+ return /* @__PURE__ */ p("div", { className: E, children: [
85
+ /* @__PURE__ */ p("div", { children: [
86
+ /* @__PURE__ */ t(l, { className: o, id: d, htmlFor: n, "data-testid": N, "data-analyticsid": v.Label, children: /* @__PURE__ */ p("span", { className: a["label-content-wrapper"], children: [
83
87
  r,
84
- /* @__PURE__ */ t("span", { className: a.label__texts, children: E() })
88
+ /* @__PURE__ */ t("span", { className: a.label__texts, children: C() })
85
89
  ] }) }),
86
- /* @__PURE__ */ m("div", { className: F, children: [
87
- h && b(h, A) && S.cloneElement(h, {
88
- mode: p
90
+ /* @__PURE__ */ p("div", { className: L, children: [
91
+ b && u(b, z) && y.cloneElement(b, {
92
+ mode: c
89
93
  }),
90
- c && b(c, z) && /* @__PURE__ */ m(x, { children: [
91
- /* @__PURE__ */ t(N, { size: "3xs" }),
92
- S.cloneElement(c, {
93
- mode: p === u.ondark ? "ondark" : "onwhite"
94
+ h && u(h, j) && /* @__PURE__ */ p(F, { children: [
95
+ /* @__PURE__ */ t(g, { size: "3xs" }),
96
+ y.cloneElement(h, {
97
+ mode: c === S.ondark ? "ondark" : "onwhite"
94
98
  })
95
99
  ] })
96
100
  ] })
@@ -100,9 +104,9 @@ const A = ({ className: e, id: r, mode: s, sublabelTexts: n, testId: o }) => {
100
104
  };
101
105
  export {
102
106
  f as L,
103
- A as S,
104
- J as a,
105
- G as g,
106
- K as r
107
+ z as S,
108
+ O as a,
109
+ K as g,
110
+ Q as r
107
111
  };
108
112
  //# sourceMappingURL=Label.js.map
package/Label.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Label.js","sources":["../src/components/Label/SubLabel.tsx","../src/components/Label/Label.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport { LabelText } from './Label';\nimport { AnalyticsId, FormMode } from '../../constants';\nimport Spacer from '../Spacer';\n\nimport styles from './styles.module.scss';\n\nexport interface SublabelProps {\n /** Adds custom classes to the element. */\n className?: string;\n /** id that is placed on the wrapper */\n id: string;\n /** Array of sublabel strings. Can be of type semibold or normal */\n mode?: FormMode;\n /** Array of sublabel strings. Can be of type semibold or normal */\n sublabelTexts?: LabelText[];\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const Sublabel: React.FC<SublabelProps> = ({ className, id, mode, sublabelTexts, testId }) => {\n const mapSublabels = (hideFromScreenReader?: boolean): React.ReactNode => {\n return (\n sublabelTexts &&\n sublabelTexts.map((sublabelText, index) => {\n const labelClasses = cn(styles.label, styles['label--sublabel'], {\n [styles['label--semibold']]: sublabelText.type === 'semibold',\n [styles['label--on-dark']]: mode === FormMode.ondark,\n });\n return (\n hideFromScreenReader === sublabelText.hideFromScreenReader && (\n <span className={labelClasses} key={index}>\n {sublabelText.text}\n </span>\n )\n );\n })\n );\n };\n\n const subLabels = mapSublabels();\n const ariaHiddenSublabels = mapSublabels(true);\n\n return (\n <>\n <Spacer size={'3xs'} />\n {subLabels && (\n <div className={className} id={id} data-testid={testId} data-analyticsid={AnalyticsId.Sublabel}>\n {subLabels}\n </div>\n )}\n {ariaHiddenSublabels && (\n <div className={className} data-testid={testId}>\n {ariaHiddenSublabels}\n </div>\n )}\n </>\n );\n};\n","import React, { FunctionComponent } from 'react';\n\nimport cn from 'classnames';\n\nimport { Sublabel, SublabelProps } from './SubLabel';\nimport { AnalyticsId, FormMode } from '../../constants';\nimport { isComponent } from '../../utils/component';\nimport Spacer from '../Spacer';\nimport StatusDot, { StatusDotProps } from '../StatusDot';\n\nimport styles from './styles.module.scss';\n\nexport type LabelText = {\n hideFromScreenReader?: boolean;\n text: string;\n type?: 'semibold' | 'normal';\n};\n\nexport interface LabelProps {\n /** Component shown after label - discourage use of this */\n afterLabelChildren?: React.ReactNode;\n /** Adds custom classes to the element. */\n children?: React.ReactNode;\n /** Adds custom classes to the label tag. */\n labelClassName?: string;\n /** Adds custom classes to the label text. */\n labelTextClassName?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Id that is put on the \"for\" attribute of the label */\n htmlFor?: string;\n /** Id som plasseres på <label/> */\n labelId?: string;\n /** Array of main label strings. Can be of type semibold or normal */\n labelTexts: LabelText[];\n /** Array of sublabel strings. Can be of type semibold or normal */\n mode?: keyof typeof FormMode;\n /** StatusDot placed underneath the last sublabel */\n statusDot?: React.ReactNode;\n /** Sublabel component */\n sublabel?: React.ReactNode;\n /** Adds custom classes to the div wrapping the sublabels. */\n sublabelWrapperClassName?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const getLabelText = (label: React.ReactNode): string => {\n let allLabelText = '';\n\n if (isComponent<LabelProps>(label, Label)) {\n label.props.labelTexts.forEach(labelText => {\n allLabelText += !labelText.hideFromScreenReader ? labelText.text : '';\n });\n }\n\n return allLabelText;\n};\n\nexport const renderLabel = (label: React.ReactNode, inputId: string, mode: FormMode): React.ReactNode => {\n return (\n <>\n {label && isComponent<LabelProps>(label, Label)\n ? React.cloneElement(label, {\n htmlFor: inputId,\n mode: mode,\n })\n : typeof label === 'string' && <Label labelTexts={[{ text: label, type: 'semibold' }]} htmlFor={inputId} mode={mode} />}\n </>\n );\n};\n\nexport const renderLabelAsParent = (\n label: React.ReactNode,\n children: React.ReactNode,\n inputId: string,\n mode: FormMode,\n labelClassName?: string,\n labelTextClassName?: string,\n sublabelWrapperClassName?: string,\n large?: boolean\n): React.ReactNode => {\n return (\n <>\n {label && isComponent<LabelProps>(label, Label)\n ? React.cloneElement(label, {\n htmlFor: inputId,\n mode: mode,\n children: children,\n labelClassName: cn(labelClassName, label.props.labelClassName),\n labelTextClassName: labelTextClassName,\n sublabelWrapperClassName: sublabelWrapperClassName,\n sublabel: large ? undefined : label.props.sublabel,\n statusDot: large ? undefined : label.props.statusDot,\n })\n : typeof label === 'string' && (\n <Label\n labelTexts={[{ text: label }]}\n htmlFor={inputId}\n mode={mode}\n labelClassName={labelClassName}\n labelTextClassName={labelTextClassName}\n sublabelWrapperClassName={sublabelWrapperClassName}\n >\n {children}\n </Label>\n )}\n </>\n );\n};\n\nconst Label: FunctionComponent<LabelProps> = ({\n afterLabelChildren,\n children,\n className,\n htmlFor,\n labelClassName,\n labelTextClassName,\n labelId,\n labelTexts,\n mode = FormMode.onwhite,\n statusDot,\n sublabel,\n sublabelWrapperClassName,\n testId,\n}) => {\n const hasChildren = children && typeof children !== 'undefined';\n const labelWrapperClasses = cn(\n styles['label-wrapper'],\n { [styles['label-wrapper--no-bottom-margin']]: hasChildren, [styles['label-wrapper--after-label-children']]: afterLabelChildren },\n className\n );\n\n const mapLabels = (): React.ReactNode => {\n return labelTexts.map((labelText, index) => {\n const labelClasses = cn(\n styles.label,\n {\n [styles['label--semibold']]: labelText.type === 'semibold',\n [styles['label--on-dark']]: mode === FormMode.ondark,\n },\n labelTextClassName\n );\n return (\n <span aria-hidden={labelText.hideFromScreenReader} className={labelClasses} key={index}>\n {labelText.text}\n </span>\n );\n });\n };\n\n return (\n <div className={labelWrapperClasses}>\n <div>\n <label className={labelClassName} id={labelId} htmlFor={htmlFor} data-testid={testId} data-analyticsid={AnalyticsId.Label}>\n <span className={styles['label-content-wrapper']}>\n {children}\n <span className={styles.label__texts}>{mapLabels()}</span>\n </span>\n </label>\n <div className={sublabelWrapperClassName}>\n {sublabel &&\n isComponent<SublabelProps>(sublabel, Sublabel) &&\n React.cloneElement(sublabel, {\n mode: mode as FormMode,\n })}\n {statusDot && isComponent<StatusDotProps>(statusDot, StatusDot) && (\n <>\n <Spacer size={'3xs'} />\n {React.cloneElement(statusDot, {\n mode: mode === FormMode.ondark ? 'ondark' : 'onwhite',\n })}\n </>\n )}\n </div>\n </div>\n {afterLabelChildren && <div className={styles['after-label-children']}>{afterLabelChildren}</div>}\n </div>\n );\n};\n\nexport default Label;\n"],"names":["Sublabel","className","id","mode","sublabelTexts","testId","mapSublabels","hideFromScreenReader","sublabelText","index","labelClasses","cn","styles","FormMode","jsx","subLabels","ariaHiddenSublabels","jsxs","Fragment","Spacer","AnalyticsId","getLabelText","label","allLabelText","isComponent","Label","labelText","renderLabel","inputId","React","renderLabelAsParent","children","labelClassName","labelTextClassName","sublabelWrapperClassName","large","afterLabelChildren","htmlFor","labelId","labelTexts","statusDot","sublabel","hasChildren","labelWrapperClasses","mapLabels","StatusDot"],"mappings":"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"}
1
+ {"version":3,"file":"Label.js","sources":["../src/components/Label/SubLabel.tsx","../src/components/Label/Label.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport { LabelText } from './Label';\nimport { AnalyticsId, FormMode } from '../../constants';\nimport Spacer from '../Spacer';\n\nimport styles from './styles.module.scss';\n\nexport interface SublabelProps {\n /** Adds custom classes to the element. */\n className?: string;\n /** id that is placed on the wrapper */\n id: string;\n /** Array of sublabel strings. Can be of type semibold or normal */\n mode?: FormMode;\n /** Array of sublabel strings. Can be of type semibold or normal */\n sublabelTexts?: LabelText[];\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const Sublabel: React.FC<SublabelProps> = ({ className, id, mode, sublabelTexts, testId }) => {\n const mapSublabels = (hideFromScreenReader?: boolean): React.ReactNode => {\n return (\n sublabelTexts &&\n sublabelTexts.map((sublabelText, index) => {\n const labelClasses = cn(styles.label, styles['label--sublabel'], {\n [styles['label--semibold']]: sublabelText.type === 'semibold',\n [styles['label--on-dark']]: mode === FormMode.ondark,\n });\n return (\n hideFromScreenReader === sublabelText.hideFromScreenReader && (\n <span className={labelClasses} key={index}>\n {sublabelText.text}\n </span>\n )\n );\n })\n );\n };\n\n const subLabels = mapSublabels();\n const ariaHiddenSublabels = mapSublabels(true);\n\n return (\n <>\n <Spacer size={'3xs'} />\n {subLabels && (\n <div className={className} id={id} data-testid={testId} data-analyticsid={AnalyticsId.Sublabel}>\n {subLabels}\n </div>\n )}\n {ariaHiddenSublabels && (\n <div className={className} data-testid={testId}>\n {ariaHiddenSublabels}\n </div>\n )}\n </>\n );\n};\n","import React, { FunctionComponent } from 'react';\n\nimport cn from 'classnames';\n\nimport { Sublabel, SublabelProps } from './SubLabel';\nimport { AnalyticsId, FormMode } from '../../constants';\nimport { isComponent } from '../../utils/component';\nimport Spacer from '../Spacer';\nimport StatusDot, { StatusDotProps } from '../StatusDot';\n\nimport styles from './styles.module.scss';\n\nexport type LabelText = {\n hideFromScreenReader?: boolean;\n text: string;\n type?: 'semibold' | 'normal';\n};\n\nexport type LabelTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'span' | 'label' | 'p';\n\nexport interface LabelProps {\n /** Component shown after label - discourage use of this */\n afterLabelChildren?: React.ReactNode;\n /** Adds custom classes to the element. */\n children?: React.ReactNode;\n /** Adds custom classes to the label tag. */\n labelClassName?: string;\n /** Adds custom classes to the label text. */\n labelTextClassName?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Id that is put on the \"for\" attribute of the label */\n htmlFor?: string;\n /** Changes the underlying element of the label */\n htmlMarkup?: LabelTags;\n /** Id som plasseres på <label/> */\n labelId?: string;\n /** Array of main label strings. Can be of type semibold or normal */\n labelTexts: LabelText[];\n /** Array of sublabel strings. Can be of type semibold or normal */\n mode?: keyof typeof FormMode;\n /** StatusDot placed underneath the last sublabel */\n statusDot?: React.ReactNode;\n /** Sublabel component */\n sublabel?: React.ReactNode;\n /** Adds custom classes to the div wrapping the sublabels. */\n sublabelWrapperClassName?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const getLabelText = (label: React.ReactNode): string => {\n let allLabelText = '';\n\n if (isComponent<LabelProps>(label, Label)) {\n label.props.labelTexts.forEach(labelText => {\n allLabelText += !labelText.hideFromScreenReader ? labelText.text : '';\n });\n }\n\n return allLabelText;\n};\n\nexport const renderLabel = (label: React.ReactNode, inputId: string, mode: FormMode, markup?: LabelTags): React.ReactNode => {\n return (\n <>\n {label && isComponent<LabelProps>(label, Label)\n ? React.cloneElement(label, {\n htmlFor: inputId,\n htmlMarkup: markup || 'label',\n mode: mode,\n })\n : typeof label === 'string' && <Label labelTexts={[{ text: label, type: 'semibold' }]} htmlFor={inputId} mode={mode} />}\n </>\n );\n};\n\nexport const renderLabelAsParent = (\n label: React.ReactNode,\n children: React.ReactNode,\n inputId: string,\n mode: FormMode,\n labelClassName?: string,\n labelTextClassName?: string,\n sublabelWrapperClassName?: string,\n large?: boolean,\n markup?: LabelTags\n): React.ReactNode => {\n return (\n <>\n {label && isComponent<LabelProps>(label, Label)\n ? React.cloneElement(label, {\n htmlFor: inputId,\n mode: mode,\n children: children,\n labelClassName: cn(labelClassName, label.props.labelClassName),\n labelTextClassName: labelTextClassName,\n htmlMarkup: markup || 'label',\n sublabelWrapperClassName: sublabelWrapperClassName,\n sublabel: large ? undefined : label.props.sublabel,\n statusDot: large ? undefined : label.props.statusDot,\n })\n : typeof label === 'string' && (\n <Label\n labelTexts={[{ text: label }]}\n htmlFor={inputId}\n mode={mode}\n htmlMarkup={markup || 'label'}\n labelClassName={labelClassName}\n labelTextClassName={labelTextClassName}\n sublabelWrapperClassName={sublabelWrapperClassName}\n >\n {children}\n </Label>\n )}\n </>\n );\n};\n\nconst Label: FunctionComponent<LabelProps> = ({\n afterLabelChildren,\n children,\n className,\n htmlFor,\n htmlMarkup = 'label',\n labelClassName,\n labelTextClassName,\n labelId,\n labelTexts,\n mode = FormMode.onwhite,\n statusDot,\n sublabel,\n sublabelWrapperClassName,\n testId,\n}) => {\n const hasChildren = children && typeof children !== 'undefined';\n const labelWrapperClasses = cn(\n styles['label-wrapper'],\n { [styles['label-wrapper--no-bottom-margin']]: hasChildren, [styles['label-wrapper--after-label-children']]: afterLabelChildren },\n className\n );\n\n const mapLabels = (): React.ReactNode => {\n return labelTexts.map((labelText, index) => {\n const labelClasses = cn(\n styles.label,\n {\n [styles['label--semibold']]: labelText.type === 'semibold',\n [styles['label--on-dark']]: mode === FormMode.ondark,\n },\n labelTextClassName\n );\n return (\n <span aria-hidden={labelText.hideFromScreenReader} className={labelClasses} key={index}>\n {labelText.text}\n </span>\n );\n });\n };\n const CustomTag = htmlMarkup;\n\n return (\n <div className={labelWrapperClasses}>\n <div>\n <CustomTag className={labelClassName} id={labelId} htmlFor={htmlFor} data-testid={testId} data-analyticsid={AnalyticsId.Label}>\n <span className={styles['label-content-wrapper']}>\n {children}\n <span className={styles.label__texts}>{mapLabels()}</span>\n </span>\n </CustomTag>\n <div className={sublabelWrapperClassName}>\n {sublabel &&\n isComponent<SublabelProps>(sublabel, Sublabel) &&\n React.cloneElement(sublabel, {\n mode: mode as FormMode,\n })}\n {statusDot && isComponent<StatusDotProps>(statusDot, StatusDot) && (\n <>\n <Spacer size={'3xs'} />\n {React.cloneElement(statusDot, {\n mode: mode === FormMode.ondark ? 'ondark' : 'onwhite',\n })}\n </>\n )}\n </div>\n </div>\n {afterLabelChildren && <div className={styles['after-label-children']}>{afterLabelChildren}</div>}\n </div>\n );\n};\n\nexport default Label;\n"],"names":["Sublabel","className","id","mode","sublabelTexts","testId","mapSublabels","hideFromScreenReader","sublabelText","index","labelClasses","cn","styles","FormMode","jsx","subLabels","ariaHiddenSublabels","jsxs","Fragment","Spacer","AnalyticsId","getLabelText","label","allLabelText","isComponent","Label","labelText","renderLabel","inputId","markup","React","renderLabelAsParent","children","labelClassName","labelTextClassName","sublabelWrapperClassName","large","afterLabelChildren","htmlFor","htmlMarkup","labelId","labelTexts","statusDot","sublabel","hasChildren","labelWrapperClasses","mapLabels","StatusDot"],"mappings":"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"}
package/Textarea.js CHANGED
@@ -1,110 +1,112 @@
1
- import { jsx as l, jsxs as ee } from "react/jsx-runtime";
2
- import te, { useState as A, useRef as re, useEffect as B } from "react";
3
- import p from "classnames";
4
- import { FormMode as m, AnalyticsId as ae, AVERAGE_CHARACTER_WIDTH_PX as oe } from "./constants.js";
5
- import { useUuid as ne } from "./hooks/useUuid.js";
6
- import { getAriaDescribedBy as ie } from "./utils/accessibility.js";
7
- import { u as se } from "./uuid.js";
8
- import { E as de } from "./ErrorWrapper.js";
9
- import { a as ce } from "./Label.js";
10
- import { M as le } from "./MaxCharacters.js";
1
+ import { jsx as m, jsxs as te } from "react/jsx-runtime";
2
+ import re, { useState as B, useRef as ae, useEffect as M } from "react";
3
+ import f from "classnames";
4
+ import { FormMode as p, AnalyticsId as oe, AVERAGE_CHARACTER_WIDTH_PX as ne } from "./constants.js";
5
+ import { useUuid as ie } from "./hooks/useUuid.js";
6
+ import { getAriaDescribedBy as se } from "./utils/accessibility.js";
7
+ import { u as de } from "./uuid.js";
8
+ import { E as ce } from "./ErrorWrapper.js";
9
+ import { a as le } from "./Label.js";
10
+ import { M as ue } from "./MaxCharacters.js";
11
11
  import t from "./components/Textarea/styles.module.scss";
12
- const me = (a) => `calc(${a * oe}px + 2rem + 16px + 4px)`, ue = te.forwardRef((a, h) => {
12
+ const me = (a) => `calc(${a * ne}px + 2rem + 16px + 4px)`, pe = re.forwardRef((a, b) => {
13
13
  const {
14
14
  maxCharacters: o,
15
- maxText: x,
16
- width: f,
17
- testId: M,
15
+ maxText: g,
16
+ width: w,
17
+ testId: N,
18
18
  defaultValue: i,
19
- marginBottom: N,
20
- transparent: $,
21
- mode: n = m.onwhite,
22
- label: k,
23
- textareaId: b = se(),
24
- minRows: g = 3,
19
+ marginBottom: $,
20
+ transparent: k,
21
+ mode: n = p.onwhite,
22
+ label: D,
23
+ textareaId: C = de(),
24
+ minRows: T = 3,
25
25
  maxRows: s = 10,
26
- grow: w,
27
- error: D,
28
- errorText: C,
29
- errorTextId: L,
30
- autoFocus: S,
31
- disabled: j,
32
- name: F,
33
- autoComplete: T = "off",
34
- placeholder: U,
35
- readOnly: V,
36
- required: q,
37
- onChange: W,
38
- ...z
39
- } = a, [G, y] = A(g), [R, v] = A(i || ""), d = re(null), E = ne(L);
40
- B(() => {
41
- v(i || "");
26
+ grow: v,
27
+ error: L,
28
+ errorText: W,
29
+ errorTextId: S,
30
+ autoFocus: j,
31
+ disabled: F,
32
+ name: U,
33
+ autoComplete: y = "off",
34
+ placeholder: V,
35
+ readOnly: q,
36
+ required: z,
37
+ onChange: R,
38
+ value: d,
39
+ ...G
40
+ } = a, [O, E] = B(T), [h, c] = B(d || i || ""), l = ae(null), H = ie(S);
41
+ M(() => {
42
+ c(i || "");
42
43
  }, [i]);
43
- const H = (e) => {
44
- const c = e.rows;
45
- e.rows = g;
44
+ const I = (e) => {
45
+ const u = e.rows;
46
+ e.rows = T;
46
47
  const r = Math.floor((e.scrollHeight - 16) / 28);
47
- r === c && (e.rows = r), r >= s && (e.rows = s, e.scrollTop = e.scrollHeight), r < s ? y(r) : y(s);
48
- }, O = n === m.ondark, P = n === m.onblueberry, X = !!o && R.toString().length > o, I = n === m.oninvalid || !!C || !!D || X, J = p(t.textarea, {
49
- [t["textarea--gutterBottom"]]: N
50
- }), K = p(t["input-container"], {
51
- [t["input-container--transparent"]]: $,
52
- [t["input-container--on-blueberry"]]: P,
53
- [t["input-container--on-dark"]]: O,
54
- [t["input-container--invalid"]]: I,
48
+ r === u && (e.rows = r), r >= s && (e.rows = s, e.scrollTop = e.scrollHeight), r < s ? E(r) : E(s);
49
+ }, P = n === p.ondark, X = n === p.onblueberry, J = !!o && h.toString().length > o, _ = n === p.oninvalid || !!W || !!L || J, K = f(t.textarea, {
50
+ [t["textarea--gutterBottom"]]: $
51
+ }), Q = f(t["input-container"], {
52
+ [t["input-container--transparent"]]: k,
53
+ [t["input-container--on-blueberry"]]: X,
54
+ [t["input-container--on-dark"]]: P,
55
+ [t["input-container--invalid"]]: _,
55
56
  [t["input-container--disabled"]]: a.disabled
56
- }), Q = p(t["input-container__input"], {
57
+ }), Y = f(t["input-container__input"], {
57
58
  [t["input-container__input--disabled"]]: a.disabled
58
59
  });
59
- B(() => {
60
- var e, u, c;
61
- if (w && ((e = d.current) != null && e.children) && ((u = d.current) != null && u.children[0])) {
62
- const r = (c = d.current) == null ? void 0 : c.children[0];
63
- H(r);
60
+ M(() => {
61
+ var e, x, u;
62
+ if (d && c(d), v && ((e = l.current) != null && e.children) && ((x = l.current) != null && x.children[0])) {
63
+ const r = (u = l.current) == null ? void 0 : u.children[0];
64
+ I(r);
64
65
  }
65
- }, []);
66
- const Y = (e) => {
67
- w && H(e.target), v(e.target.value);
68
- }, Z = (e) => {
69
- W && W(e), Y(e);
70
- }, _ = f ? me(f) : void 0;
71
- return /* @__PURE__ */ l(de, { errorText: C, errorTextId: E, children: /* @__PURE__ */ ee("div", { "data-testid": M, "data-analyticsid": ae.Textarea, className: J, children: [
72
- ce(k, b, n),
73
- /* @__PURE__ */ l("div", { className: K, ref: d, style: { maxWidth: _ }, children: /* @__PURE__ */ l(
66
+ }, [d]);
67
+ const Z = (e) => {
68
+ v && I(e.target), c(e.target.value);
69
+ }, ee = (e) => {
70
+ c(e.target.value), R && R(e), Z(e);
71
+ }, A = w ? me(w) : void 0;
72
+ return /* @__PURE__ */ m(ce, { errorText: W, errorTextId: H, children: /* @__PURE__ */ te("div", { "data-testid": N, "data-analyticsid": oe.Textarea, className: K, children: [
73
+ le(D, C, n),
74
+ /* @__PURE__ */ m("div", { className: Q, ref: l, style: { maxWidth: A }, children: /* @__PURE__ */ m(
74
75
  "textarea",
75
76
  {
76
- rows: G,
77
+ ...G,
78
+ rows: O,
77
79
  defaultValue: i,
78
- id: b,
79
- className: Q,
80
- ref: h,
81
- "aria-describedby": ie(a, E),
82
- "aria-invalid": !!I,
83
- autoFocus: S,
84
- disabled: j,
85
- name: F,
86
- autoComplete: T || void 0,
87
- placeholder: U,
88
- readOnly: V,
89
- required: q,
90
- onChange: Z,
91
- ...z
80
+ id: C,
81
+ className: Y,
82
+ ref: b,
83
+ "aria-describedby": se(a, H),
84
+ "aria-invalid": !!_,
85
+ autoFocus: j,
86
+ disabled: F,
87
+ name: U,
88
+ autoComplete: y || void 0,
89
+ placeholder: V,
90
+ readOnly: q,
91
+ required: z,
92
+ onChange: ee,
93
+ value: h
92
94
  }
93
95
  ) }),
94
- o && /* @__PURE__ */ l(
95
- le,
96
+ o && /* @__PURE__ */ m(
97
+ ue,
96
98
  {
97
99
  maxCharacters: o,
98
- length: R.toString().length,
99
- maxText: x,
100
+ length: h.toString().length,
101
+ maxText: g,
100
102
  mode: n,
101
- maxWidth: _
103
+ maxWidth: A
102
104
  }
103
105
  )
104
106
  ] }) });
105
107
  });
106
- ue.displayName = "Textarea";
108
+ pe.displayName = "Textarea";
107
109
  export {
108
- ue as T
110
+ pe as T
109
111
  };
110
112
  //# sourceMappingURL=Textarea.js.map
package/Textarea.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Textarea.js","sources":["../src/components/Textarea/Textarea.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\n\nimport cn from 'classnames';\n\nimport { AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX, FormMode } from '../../constants';\nimport { useUuid } from '../../hooks/useUuid';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { uuid } from '../../utils/uuid';\nimport ErrorWrapper from '../ErrorWrapper';\nimport { renderLabel } from '../Label';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\nexport interface TextareaProps\n extends Pick<\n React.InputHTMLAttributes<HTMLTextAreaElement>,\n | 'aria-describedby'\n | 'autoFocus'\n | 'disabled'\n | 'name'\n | 'autoComplete'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'defaultValue'\n | 'onChange'\n > {\n /** max character limit in textarea */\n maxCharacters?: number;\n /** The text is displayed in the end of the text-counter */\n maxText?: string;\n /** Width of textarea in characters (approximate) */\n width?: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** If true, the component will have a bottom margin. */\n marginBottom?: boolean;\n /** If true, the component will be transparent. */\n transparent?: boolean;\n /** Changes the visuals of the textarea */\n mode?: keyof typeof FormMode;\n /** Label of the input */\n label?: React.ReactNode;\n /** id of the textarea */\n textareaId?: string;\n /** max rows */\n maxRows?: number;\n /** min rows */\n minRows?: number;\n /** auto-grows until maxRows */\n grow?: boolean;\n /** Activates Error style for the input */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Error text id */\n errorTextId?: string;\n}\n\nconst getTextareaMaxWidth = (characters: number): string => {\n const paddingWidth = '2rem';\n const scrollbarWidth = '16px';\n const borderWidth = '4px';\n\n return `calc(${characters * AVERAGE_CHARACTER_WIDTH_PX}px + ${paddingWidth} + ${scrollbarWidth} + ${borderWidth})`;\n};\n\nconst Textarea = React.forwardRef((props: TextareaProps, ref: React.Ref<HTMLTextAreaElement>) => {\n const {\n maxCharacters,\n maxText,\n width,\n testId,\n defaultValue,\n marginBottom: gutterBottom,\n transparent,\n mode = FormMode.onwhite,\n label,\n textareaId = uuid(),\n minRows = 3,\n maxRows = 10,\n grow,\n error,\n errorText,\n errorTextId,\n autoFocus,\n disabled,\n name,\n autoComplete = 'off',\n placeholder,\n readOnly,\n required,\n onChange,\n ...rest\n } = props;\n\n const [rows, setRows] = useState(minRows);\n const [textareaInput, setTextareaInput] = useState(defaultValue || '');\n const referanse = useRef<HTMLDivElement>(null);\n const errorTextUuid = useUuid(errorTextId);\n\n useEffect(() => {\n setTextareaInput(defaultValue || '');\n }, [defaultValue]);\n\n const resizeHeight = (target: HTMLTextAreaElement): void => {\n const textareaLineHeight = 28;\n\n const previousRows = target.rows;\n target.rows = minRows; // reset number of rows in textarea\n\n const currentRows = Math.floor((target.scrollHeight - 16) / textareaLineHeight); // scrollHeight - 16px of padding to calculate the rows\n\n if (currentRows === previousRows) {\n target.rows = currentRows;\n }\n\n if (currentRows >= maxRows) {\n target.rows = maxRows;\n target.scrollTop = target.scrollHeight;\n }\n\n if (currentRows < maxRows) {\n setRows(currentRows);\n } else {\n setRows(maxRows);\n }\n };\n\n const onDark = mode === FormMode.ondark;\n const onBlueberry = mode === FormMode.onblueberry;\n const maxCharactersExceeded = !!maxCharacters && textareaInput.toString().length > maxCharacters;\n const onError = mode === FormMode.oninvalid || !!errorText || !!error || maxCharactersExceeded;\n\n const textareaWrapperClass = cn(styles.textarea, {\n [styles['textarea--gutterBottom']]: gutterBottom,\n });\n\n const contentWrapperClass = cn(styles['input-container'], {\n [styles['input-container--transparent']]: transparent,\n [styles['input-container--on-blueberry']]: onBlueberry,\n [styles['input-container--on-dark']]: onDark,\n [styles['input-container--invalid']]: onError,\n [styles['input-container--disabled']]: props.disabled,\n });\n\n const textareaClass = cn(styles['input-container__input'], {\n [styles[`input-container__input--disabled`]]: props.disabled,\n });\n\n useEffect(() => {\n if (grow && referanse.current?.children && referanse.current?.children[0]) {\n const textarea = referanse.current?.children[0] as HTMLTextAreaElement;\n resizeHeight(textarea);\n }\n }, []);\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {\n if (grow) {\n resizeHeight(e.target);\n }\n setTextareaInput(e.target.value);\n };\n\n const onChangeHandler = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {\n if (onChange) {\n onChange(e);\n }\n handleChange(e);\n };\n\n const maxWidth = width ? getTextareaMaxWidth(width) : undefined;\n\n return (\n <ErrorWrapper errorText={errorText} errorTextId={errorTextUuid}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Textarea} className={textareaWrapperClass}>\n {renderLabel(label, textareaId, mode as FormMode)}\n <div className={contentWrapperClass} ref={referanse} style={{ maxWidth }}>\n <textarea\n rows={rows}\n defaultValue={defaultValue}\n id={textareaId}\n className={textareaClass}\n ref={ref}\n aria-describedby={getAriaDescribedBy(props, errorTextUuid)}\n aria-invalid={!!onError}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n disabled={disabled}\n name={name}\n autoComplete={autoComplete ? autoComplete : undefined}\n placeholder={placeholder}\n readOnly={readOnly}\n required={required}\n onChange={onChangeHandler}\n {...rest}\n />\n </div>\n {maxCharacters && (\n <MaxCharacters\n maxCharacters={maxCharacters}\n length={textareaInput.toString().length}\n maxText={maxText}\n mode={mode}\n maxWidth={maxWidth}\n />\n )}\n </div>\n </ErrorWrapper>\n );\n});\n\nTextarea.displayName = 'Textarea';\n\nexport default Textarea;\n"],"names":["getTextareaMaxWidth","characters","AVERAGE_CHARACTER_WIDTH_PX","Textarea","React","props","ref","maxCharacters","maxText","width","testId","defaultValue","gutterBottom","transparent","mode","FormMode","label","textareaId","uuid","minRows","maxRows","grow","error","errorText","errorTextId","autoFocus","disabled","name","autoComplete","placeholder","readOnly","required","onChange","rest","rows","setRows","useState","textareaInput","setTextareaInput","referanse","useRef","errorTextUuid","useUuid","useEffect","resizeHeight","target","previousRows","currentRows","onDark","onBlueberry","maxCharactersExceeded","onError","textareaWrapperClass","cn","styles","contentWrapperClass","textareaClass","_a","_b","textarea","_c","handleChange","onChangeHandler","maxWidth","jsx","ErrorWrapper","jsxs","AnalyticsId","renderLabel","getAriaDescribedBy","MaxCharacters"],"mappings":"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"}
1
+ {"version":3,"file":"Textarea.js","sources":["../src/components/Textarea/Textarea.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\n\nimport cn from 'classnames';\n\nimport { AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX, FormMode } from '../../constants';\nimport { useUuid } from '../../hooks/useUuid';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { uuid } from '../../utils/uuid';\nimport ErrorWrapper from '../ErrorWrapper';\nimport { renderLabel } from '../Label';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\nexport interface TextareaProps\n extends Pick<\n React.InputHTMLAttributes<HTMLTextAreaElement>,\n | 'aria-describedby'\n | 'autoFocus'\n | 'disabled'\n | 'name'\n | 'autoComplete'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'defaultValue'\n | 'onChange'\n | 'value'\n > {\n /** max character limit in textarea */\n maxCharacters?: number;\n /** The text is displayed in the end of the text-counter */\n maxText?: string;\n /** Width of textarea in characters (approximate) */\n width?: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** If true, the component will have a bottom margin. */\n marginBottom?: boolean;\n /** If true, the component will be transparent. */\n transparent?: boolean;\n /** Changes the visuals of the textarea */\n mode?: keyof typeof FormMode;\n /** Label of the input */\n label?: React.ReactNode;\n /** id of the textarea */\n textareaId?: string;\n /** max rows */\n maxRows?: number;\n /** min rows */\n minRows?: number;\n /** auto-grows until maxRows */\n grow?: boolean;\n /** Activates Error style for the input */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Error text id */\n errorTextId?: string;\n}\n\nconst getTextareaMaxWidth = (characters: number): string => {\n const paddingWidth = '2rem';\n const scrollbarWidth = '16px';\n const borderWidth = '4px';\n\n return `calc(${characters * AVERAGE_CHARACTER_WIDTH_PX}px + ${paddingWidth} + ${scrollbarWidth} + ${borderWidth})`;\n};\n\nconst Textarea = React.forwardRef((props: TextareaProps, ref: React.Ref<HTMLTextAreaElement>) => {\n const {\n maxCharacters,\n maxText,\n width,\n testId,\n defaultValue,\n marginBottom: gutterBottom,\n transparent,\n mode = FormMode.onwhite,\n label,\n textareaId = uuid(),\n minRows = 3,\n maxRows = 10,\n grow,\n error,\n errorText,\n errorTextId,\n autoFocus,\n disabled,\n name,\n autoComplete = 'off',\n placeholder,\n readOnly,\n required,\n onChange,\n value,\n ...rest\n } = props;\n\n const [rows, setRows] = useState(minRows);\n const [textareaInput, setTextareaInput] = useState(value || defaultValue || '');\n const referanse = useRef<HTMLDivElement>(null);\n const errorTextUuid = useUuid(errorTextId);\n\n useEffect(() => {\n setTextareaInput(defaultValue || '');\n }, [defaultValue]);\n\n const resizeHeight = (target: HTMLTextAreaElement): void => {\n const textareaLineHeight = 28;\n\n const previousRows = target.rows;\n target.rows = minRows; // reset number of rows in textarea\n\n const currentRows = Math.floor((target.scrollHeight - 16) / textareaLineHeight); // scrollHeight - 16px of padding to calculate the rows\n\n if (currentRows === previousRows) {\n target.rows = currentRows;\n }\n\n if (currentRows >= maxRows) {\n target.rows = maxRows;\n target.scrollTop = target.scrollHeight;\n }\n\n if (currentRows < maxRows) {\n setRows(currentRows);\n } else {\n setRows(maxRows);\n }\n };\n\n const onDark = mode === FormMode.ondark;\n const onBlueberry = mode === FormMode.onblueberry;\n const maxCharactersExceeded = !!maxCharacters && textareaInput.toString().length > maxCharacters;\n const onError = mode === FormMode.oninvalid || !!errorText || !!error || maxCharactersExceeded;\n\n const textareaWrapperClass = cn(styles.textarea, {\n [styles['textarea--gutterBottom']]: gutterBottom,\n });\n\n const contentWrapperClass = cn(styles['input-container'], {\n [styles['input-container--transparent']]: transparent,\n [styles['input-container--on-blueberry']]: onBlueberry,\n [styles['input-container--on-dark']]: onDark,\n [styles['input-container--invalid']]: onError,\n [styles['input-container--disabled']]: props.disabled,\n });\n\n const textareaClass = cn(styles['input-container__input'], {\n [styles[`input-container__input--disabled`]]: props.disabled,\n });\n\n useEffect(() => {\n value && setTextareaInput(value);\n\n if (grow && referanse.current?.children && referanse.current?.children[0]) {\n const textarea = referanse.current?.children[0] as HTMLTextAreaElement;\n resizeHeight(textarea);\n }\n }, [value]);\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {\n if (grow) {\n resizeHeight(e.target);\n }\n setTextareaInput(e.target.value);\n };\n\n const onChangeHandler = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {\n setTextareaInput(e.target.value);\n\n if (onChange) {\n onChange(e);\n }\n handleChange(e);\n };\n\n const maxWidth = width ? getTextareaMaxWidth(width) : undefined;\n\n return (\n <ErrorWrapper errorText={errorText} errorTextId={errorTextUuid}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Textarea} className={textareaWrapperClass}>\n {renderLabel(label, textareaId, mode as FormMode)}\n <div className={contentWrapperClass} ref={referanse} style={{ maxWidth }}>\n <textarea\n {...rest}\n rows={rows}\n defaultValue={defaultValue}\n id={textareaId}\n className={textareaClass}\n ref={ref}\n aria-describedby={getAriaDescribedBy(props, errorTextUuid)}\n aria-invalid={!!onError}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n disabled={disabled}\n name={name}\n autoComplete={autoComplete ? autoComplete : undefined}\n placeholder={placeholder}\n readOnly={readOnly}\n required={required}\n onChange={onChangeHandler}\n value={textareaInput}\n />\n </div>\n {maxCharacters && (\n <MaxCharacters\n maxCharacters={maxCharacters}\n length={textareaInput.toString().length}\n maxText={maxText}\n mode={mode}\n maxWidth={maxWidth}\n />\n )}\n </div>\n </ErrorWrapper>\n );\n});\n\nTextarea.displayName = 'Textarea';\n\nexport default Textarea;\n"],"names":["getTextareaMaxWidth","characters","AVERAGE_CHARACTER_WIDTH_PX","Textarea","React","props","ref","maxCharacters","maxText","width","testId","defaultValue","gutterBottom","transparent","mode","FormMode","label","textareaId","uuid","minRows","maxRows","grow","error","errorText","errorTextId","autoFocus","disabled","name","autoComplete","placeholder","readOnly","required","onChange","value","rest","rows","setRows","useState","textareaInput","setTextareaInput","referanse","useRef","errorTextUuid","useUuid","useEffect","resizeHeight","target","previousRows","currentRows","onDark","onBlueberry","maxCharactersExceeded","onError","textareaWrapperClass","cn","styles","contentWrapperClass","textareaClass","_a","_b","textarea","_c","handleChange","onChangeHandler","maxWidth","jsx","ErrorWrapper","jsxs","AnalyticsId","renderLabel","getAriaDescribedBy","MaxCharacters"],"mappings":"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"}
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { FormMode, FormSize } from '../../constants';
3
3
  import { SvgIcon } from '../Icon';
4
4
  import { IconName } from '../Icons/IconNames';
5
- export interface InputProps extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'disabled' | 'readOnly' | 'autoComplete' | 'name' | 'placeholder' | 'defaultValue' | 'required' | 'value' | 'min' | 'max' | 'aria-describedby' | 'aria-labelledby' | 'onBlur' | 'onClick' | 'onChange' | 'onFocus' | 'onKeyDown' | 'autoFocus'> {
5
+ export interface InputProps extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'disabled' | 'readOnly' | 'autoComplete' | 'name' | 'placeholder' | 'defaultValue' | 'required' | 'value' | 'min' | 'max' | 'aria-describedby' | 'aria-labelledby' | 'onBlur' | 'onClick' | 'onChange' | 'onFocus' | 'onKeyDown' | 'autoFocus' | 'inputMode'> {
6
6
  /** The number at which the input field starts when you increment or decrement it */
7
7
  baseIncrementValue?: number;
8
8
  /** Adds custom classes to the element. */
@@ -5,6 +5,7 @@ export type LabelText = {
5
5
  text: string;
6
6
  type?: 'semibold' | 'normal';
7
7
  };
8
+ export type LabelTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'span' | 'label' | 'p';
8
9
  export interface LabelProps {
9
10
  /** Component shown after label - discourage use of this */
10
11
  afterLabelChildren?: React.ReactNode;
@@ -18,6 +19,8 @@ export interface LabelProps {
18
19
  className?: string;
19
20
  /** Id that is put on the "for" attribute of the label */
20
21
  htmlFor?: string;
22
+ /** Changes the underlying element of the label */
23
+ htmlMarkup?: LabelTags;
21
24
  /** Id som plasseres på <label/> */
22
25
  labelId?: string;
23
26
  /** Array of main label strings. Can be of type semibold or normal */
@@ -34,7 +37,7 @@ export interface LabelProps {
34
37
  testId?: string;
35
38
  }
36
39
  export declare const getLabelText: (label: React.ReactNode) => string;
37
- export declare const renderLabel: (label: React.ReactNode, inputId: string, mode: FormMode) => React.ReactNode;
38
- export declare const renderLabelAsParent: (label: React.ReactNode, children: React.ReactNode, inputId: string, mode: FormMode, labelClassName?: string, labelTextClassName?: string, sublabelWrapperClassName?: string, large?: boolean) => React.ReactNode;
40
+ export declare const renderLabel: (label: React.ReactNode, inputId: string, mode: FormMode, markup?: LabelTags) => React.ReactNode;
41
+ export declare const renderLabelAsParent: (label: React.ReactNode, children: React.ReactNode, inputId: string, mode: FormMode, labelClassName?: string, labelTextClassName?: string, sublabelWrapperClassName?: string, large?: boolean, markup?: LabelTags) => React.ReactNode;
39
42
  declare const Label: FunctionComponent<LabelProps>;
40
43
  export default Label;
@@ -6,16 +6,16 @@ import { T as J } from "../../TabPanel.js";
6
6
  import { isMobileUA as K } from "../../utils/mobile.js";
7
7
  import c from "./styles.module.scss";
8
8
  const O = 75, Q = ({
9
- activeTab: L,
9
+ activeTab: w,
10
10
  children: l,
11
11
  className: N,
12
12
  color: f = "white",
13
13
  sticky: g = !0,
14
14
  testId: y,
15
15
  type: d = "normal",
16
- touchBehaviour: X = "swipe"
16
+ touchBehaviour: X = "none"
17
17
  }) => {
18
- const R = L !== void 0, [D, P] = i(0), [u, j] = i(0), [h, k] = i(0), [U, s] = i(0), [F, p] = i(null), x = K(), n = E(null), r = E(null), I = E(null), T = (t, a) => {
18
+ const R = w !== void 0, [D, P] = i(0), [u, j] = i(0), [h, k] = i(0), [U, s] = i(0), [F, p] = i(null), x = K(), n = E(null), r = E(null), I = E(null), T = (t, a) => {
19
19
  R || (P(t), t > a ? (s(0), q()) : t < a && (s(0), $()));
20
20
  }, $ = () => {
21
21
  x && p("right");
@@ -23,7 +23,7 @@ const O = 75, Q = ({
23
23
  x && p("left");
24
24
  }, z = () => {
25
25
  p(null);
26
- }, e = R ? L : D;
26
+ }, e = R ? w : D;
27
27
  return S(() => {
28
28
  const t = (o) => {
29
29
  j(o.touches[0].clientX);
@@ -87,11 +87,11 @@ const O = 75, Q = ({
87
87
  }
88
88
  ) })
89
89
  ] });
90
- }, w = Q;
91
- w.displayName = "Tabs";
92
- w.Tab = G;
93
- w.Tab.displayName = "Tabs.Tab";
90
+ }, L = Q;
91
+ L.displayName = "Tabs";
92
+ L.Tab = G;
93
+ L.Tab.displayName = "Tabs.Tab";
94
94
  export {
95
- w as default
95
+ L as default
96
96
  };
97
97
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport Tab from './Tab';\nimport TabList from './TabList';\nimport TabPanel from './TabPanel';\nimport { PaletteNames } from '../../theme/palette';\nimport { isMobileUA } from '../../utils/mobile';\n\nimport styles from './styles.module.scss';\n\nexport type { TabProps } from './Tab';\nexport type TabsColors = Extract<PaletteNames, 'blueberry' | 'neutral' | 'white'>;\nexport type TabsType = 'normal' | 'framed';\nexport type TabsTouchBehaviour = 'swipe' | 'none';\n\nexport interface TabsProps {\n children?: React.ReactNode;\n /** Controlled state for Tabs component */\n activeTab?: number;\n /** Adds custom classes to the element. */\n className?: string;\n /** Sets the color of the tabs. Default: white */\n color?: TabsColors;\n /** Whether the tab list should be sticky */\n sticky?: boolean;\n /** Determines how Tabs respons to touch events. */\n touchBehaviour?: TabsTouchBehaviour;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the visual type of the tabs */\n type?: TabsType;\n}\n\nconst swipeDistanceThreshold = 75;\n\nconst TabsRoot: React.FC<TabsProps> = ({\n activeTab,\n children,\n className,\n color = 'white',\n sticky = true,\n testId,\n type = 'normal',\n touchBehaviour = 'swipe',\n}) => {\n const isControlled = activeTab !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState(0);\n const [touchStartX, setTouchStartX] = useState(0);\n const [touchEndX, setTouchEndX] = useState(0);\n const [translateX, setTranslateX] = useState(0);\n const [panelAnimation, setPanelAnimation] = useState<'left' | 'right' | null>(null);\n const mobile = isMobileUA();\n const tabsRef = useRef<HTMLDivElement>(null);\n const tabPanelRef = useRef<HTMLDivElement>(null);\n const tabListRef = useRef<HTMLDivElement>(null);\n\n const onValueChange = (newValue: number, oldValue: number): void => {\n if (!isControlled) {\n setUncontrolledValue(newValue);\n if (newValue > oldValue) {\n // make sure that the translateX is reset so the animation does not go outside the screen\n setTranslateX(0);\n onLeftSwipe();\n } else if (newValue < oldValue) {\n // make sure that the translateX is reset so the animation does not go outside the screen\n setTranslateX(0);\n onRightSwipe();\n }\n }\n };\n\n const onRightSwipe = (): void => {\n mobile && setPanelAnimation('right');\n };\n\n const onLeftSwipe = (): void => {\n mobile && setPanelAnimation('left');\n };\n\n const resetAnimation = (): void => {\n setPanelAnimation(null);\n };\n\n const activeTabIndex = isControlled ? activeTab : uncontrolledValue;\n\n useEffect(() => {\n const handleTouchStart = (event: TouchEvent): void => {\n setTouchStartX(event.touches[0].clientX);\n };\n\n const handleTouchMove = (event: TouchEvent): void => {\n setTouchEndX(event.touches[0].clientX);\n const newTranslateX = event.touches[0].clientX - touchStartX;\n\n if (activeTabIndex === 0 && newTranslateX > 0) {\n setTranslateX(0);\n } else if (activeTabIndex === React.Children.count(children) - 1 && newTranslateX < 0) {\n setTranslateX(0);\n } else {\n setTranslateX(newTranslateX);\n }\n };\n\n const handleTouchEnd = (): void => {\n const swipeDistance = Math.abs(touchEndX - touchStartX);\n if (swipeDistance >= swipeDistanceThreshold) {\n if (touchEndX > touchStartX) {\n // User swiped right\n onValueChange(Math.max(0, activeTabIndex - 1), activeTabIndex);\n } else {\n // User swiped left\n onValueChange(Math.min(React.Children.count(children) - 1, activeTabIndex + 1), activeTabIndex);\n }\n }\n setTranslateX(0);\n };\n\n if (touchBehaviour === 'swipe' && tabsRef.current) {\n tabsRef.current.addEventListener('touchstart', handleTouchStart);\n tabsRef.current.addEventListener('touchmove', handleTouchMove);\n tabsRef.current.addEventListener('touchend', handleTouchEnd);\n }\n return () => {\n if (tabsRef.current) {\n tabsRef.current.removeEventListener('touchstart', handleTouchStart);\n tabsRef.current.removeEventListener('touchmove', handleTouchMove);\n tabsRef.current.removeEventListener('touchend', handleTouchEnd);\n }\n };\n }, [touchBehaviour, touchStartX, touchEndX, activeTabIndex]);\n\n useEffect(() => {\n const handleAnimationEnd = (): void => {\n resetAnimation();\n };\n\n if (tabPanelRef.current) {\n tabPanelRef.current.addEventListener('animationend', handleAnimationEnd);\n }\n\n return () => {\n if (tabPanelRef.current) {\n tabPanelRef.current.removeEventListener('animationend', handleAnimationEnd);\n }\n };\n }, []);\n\n return (\n <div className={className} data-testid={testId}>\n <div\n ref={tabListRef}\n className={classNames(styles['tab-list-wrapper'], {\n [styles['tab-list-wrapper--sticky']]: sticky,\n })}\n >\n <TabList\n onTabListClick={(index: number) => onValueChange(index, activeTabIndex)}\n selectedTab={activeTabIndex}\n color={color}\n type={type}\n >\n {children}\n </TabList>\n <div\n className={classNames(styles['panel-wrapper'], styles[`panel-wrapper--${color}`], {\n [styles['panel-wrapper--framed']]: type == 'framed',\n })}\n ></div>\n </div>\n <div ref={tabsRef} style={{ marginTop: type == 'framed' ? '-40px' : '' }}>\n <TabPanel\n ref={tabPanelRef}\n color={color}\n type={type}\n isFirst={activeTabIndex == 0}\n translateX={translateX}\n animate={panelAnimation}\n >\n {React.Children.toArray(children)[activeTabIndex]}\n </TabPanel>\n </div>\n </div>\n );\n};\n\ntype TabsComponent = typeof TabsRoot & {\n Tab: typeof Tab;\n};\nconst Tabs = TabsRoot as TabsComponent;\nTabs.displayName = 'Tabs';\nTabs.Tab = Tab;\nTabs.Tab.displayName = 'Tabs.Tab';\n\nexport default Tabs;\n"],"names":["swipeDistanceThreshold","TabsRoot","activeTab","children","className","color","sticky","testId","type","touchBehaviour","isControlled","uncontrolledValue","setUncontrolledValue","useState","touchStartX","setTouchStartX","touchEndX","setTouchEndX","translateX","setTranslateX","panelAnimation","setPanelAnimation","mobile","isMobileUA","tabsRef","useRef","tabPanelRef","tabListRef","onValueChange","newValue","oldValue","onLeftSwipe","onRightSwipe","resetAnimation","activeTabIndex","useEffect","handleTouchStart","event","handleTouchMove","newTranslateX","React","handleTouchEnd","handleAnimationEnd","jsxs","classNames","styles","jsx","TabList","index","TabPanel","Tabs","Tab"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport Tab from './Tab';\nimport TabList from './TabList';\nimport TabPanel from './TabPanel';\nimport { PaletteNames } from '../../theme/palette';\nimport { isMobileUA } from '../../utils/mobile';\n\nimport styles from './styles.module.scss';\n\nexport type { TabProps } from './Tab';\nexport type TabsColors = Extract<PaletteNames, 'blueberry' | 'neutral' | 'white'>;\nexport type TabsType = 'normal' | 'framed';\nexport type TabsTouchBehaviour = 'swipe' | 'none';\n\nexport interface TabsProps {\n children?: React.ReactNode;\n /** Controlled state for Tabs component */\n activeTab?: number;\n /** Adds custom classes to the element. */\n className?: string;\n /** Sets the color of the tabs. Default: white */\n color?: TabsColors;\n /** Whether the tab list should be sticky */\n sticky?: boolean;\n /** Determines how Tabs respons to touch events. */\n touchBehaviour?: TabsTouchBehaviour;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the visual type of the tabs */\n type?: TabsType;\n}\n\nconst swipeDistanceThreshold = 75;\n\nconst TabsRoot: React.FC<TabsProps> = ({\n activeTab,\n children,\n className,\n color = 'white',\n sticky = true,\n testId,\n type = 'normal',\n touchBehaviour = 'none',\n}) => {\n const isControlled = activeTab !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState(0);\n const [touchStartX, setTouchStartX] = useState(0);\n const [touchEndX, setTouchEndX] = useState(0);\n const [translateX, setTranslateX] = useState(0);\n const [panelAnimation, setPanelAnimation] = useState<'left' | 'right' | null>(null);\n const mobile = isMobileUA();\n const tabsRef = useRef<HTMLDivElement>(null);\n const tabPanelRef = useRef<HTMLDivElement>(null);\n const tabListRef = useRef<HTMLDivElement>(null);\n\n const onValueChange = (newValue: number, oldValue: number): void => {\n if (!isControlled) {\n setUncontrolledValue(newValue);\n if (newValue > oldValue) {\n // make sure that the translateX is reset so the animation does not go outside the screen\n setTranslateX(0);\n onLeftSwipe();\n } else if (newValue < oldValue) {\n // make sure that the translateX is reset so the animation does not go outside the screen\n setTranslateX(0);\n onRightSwipe();\n }\n }\n };\n\n const onRightSwipe = (): void => {\n mobile && setPanelAnimation('right');\n };\n\n const onLeftSwipe = (): void => {\n mobile && setPanelAnimation('left');\n };\n\n const resetAnimation = (): void => {\n setPanelAnimation(null);\n };\n\n const activeTabIndex = isControlled ? activeTab : uncontrolledValue;\n\n useEffect(() => {\n const handleTouchStart = (event: TouchEvent): void => {\n setTouchStartX(event.touches[0].clientX);\n };\n\n const handleTouchMove = (event: TouchEvent): void => {\n setTouchEndX(event.touches[0].clientX);\n const newTranslateX = event.touches[0].clientX - touchStartX;\n\n if (activeTabIndex === 0 && newTranslateX > 0) {\n setTranslateX(0);\n } else if (activeTabIndex === React.Children.count(children) - 1 && newTranslateX < 0) {\n setTranslateX(0);\n } else {\n setTranslateX(newTranslateX);\n }\n };\n\n const handleTouchEnd = (): void => {\n const swipeDistance = Math.abs(touchEndX - touchStartX);\n if (swipeDistance >= swipeDistanceThreshold) {\n if (touchEndX > touchStartX) {\n // User swiped right\n onValueChange(Math.max(0, activeTabIndex - 1), activeTabIndex);\n } else {\n // User swiped left\n onValueChange(Math.min(React.Children.count(children) - 1, activeTabIndex + 1), activeTabIndex);\n }\n }\n setTranslateX(0);\n };\n\n if (touchBehaviour === 'swipe' && tabsRef.current) {\n tabsRef.current.addEventListener('touchstart', handleTouchStart);\n tabsRef.current.addEventListener('touchmove', handleTouchMove);\n tabsRef.current.addEventListener('touchend', handleTouchEnd);\n }\n return () => {\n if (tabsRef.current) {\n tabsRef.current.removeEventListener('touchstart', handleTouchStart);\n tabsRef.current.removeEventListener('touchmove', handleTouchMove);\n tabsRef.current.removeEventListener('touchend', handleTouchEnd);\n }\n };\n }, [touchBehaviour, touchStartX, touchEndX, activeTabIndex]);\n\n useEffect(() => {\n const handleAnimationEnd = (): void => {\n resetAnimation();\n };\n\n if (tabPanelRef.current) {\n tabPanelRef.current.addEventListener('animationend', handleAnimationEnd);\n }\n\n return () => {\n if (tabPanelRef.current) {\n tabPanelRef.current.removeEventListener('animationend', handleAnimationEnd);\n }\n };\n }, []);\n\n return (\n <div className={className} data-testid={testId}>\n <div\n ref={tabListRef}\n className={classNames(styles['tab-list-wrapper'], {\n [styles['tab-list-wrapper--sticky']]: sticky,\n })}\n >\n <TabList\n onTabListClick={(index: number) => onValueChange(index, activeTabIndex)}\n selectedTab={activeTabIndex}\n color={color}\n type={type}\n >\n {children}\n </TabList>\n <div\n className={classNames(styles['panel-wrapper'], styles[`panel-wrapper--${color}`], {\n [styles['panel-wrapper--framed']]: type == 'framed',\n })}\n ></div>\n </div>\n <div ref={tabsRef} style={{ marginTop: type == 'framed' ? '-40px' : '' }}>\n <TabPanel\n ref={tabPanelRef}\n color={color}\n type={type}\n isFirst={activeTabIndex == 0}\n translateX={translateX}\n animate={panelAnimation}\n >\n {React.Children.toArray(children)[activeTabIndex]}\n </TabPanel>\n </div>\n </div>\n );\n};\n\ntype TabsComponent = typeof TabsRoot & {\n Tab: typeof Tab;\n};\nconst Tabs = TabsRoot as TabsComponent;\nTabs.displayName = 'Tabs';\nTabs.Tab = Tab;\nTabs.Tab.displayName = 'Tabs.Tab';\n\nexport default Tabs;\n"],"names":["swipeDistanceThreshold","TabsRoot","activeTab","children","className","color","sticky","testId","type","touchBehaviour","isControlled","uncontrolledValue","setUncontrolledValue","useState","touchStartX","setTouchStartX","touchEndX","setTouchEndX","translateX","setTranslateX","panelAnimation","setPanelAnimation","mobile","isMobileUA","tabsRef","useRef","tabPanelRef","tabListRef","onValueChange","newValue","oldValue","onLeftSwipe","onRightSwipe","resetAnimation","activeTabIndex","useEffect","handleTouchStart","event","handleTouchMove","newTranslateX","React","handleTouchEnd","handleAnimationEnd","jsxs","classNames","styles","jsx","TabList","index","TabPanel","Tabs","Tab"],"mappings":";;;;;;;AAmCA,MAAMA,IAAyB,IAEzBC,IAAgC,CAAC;AAAA,EACrC,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,QAAAC,IAAS;AAAA,EACT,QAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,gBAAAC,IAAiB;AACnB,MAAM;AACJ,QAAMC,IAAeR,MAAc,QAC7B,CAACS,GAAmBC,CAAoB,IAAIC,EAAS,CAAC,GACtD,CAACC,GAAaC,CAAc,IAAIF,EAAS,CAAC,GAC1C,CAACG,GAAWC,CAAY,IAAIJ,EAAS,CAAC,GACtC,CAACK,GAAYC,CAAa,IAAIN,EAAS,CAAC,GACxC,CAACO,GAAgBC,CAAiB,IAAIR,EAAkC,IAAI,GAC5ES,IAASC,KACTC,IAAUC,EAAuB,IAAI,GACrCC,IAAcD,EAAuB,IAAI,GACzCE,IAAaF,EAAuB,IAAI,GAExCG,IAAgB,CAACC,GAAkBC,MAA2B;AAClE,IAAKpB,MACHE,EAAqBiB,CAAQ,GACzBA,IAAWC,KAEbX,EAAc,CAAC,GACHY,OACHF,IAAWC,MAEpBX,EAAc,CAAC,GACFa;EAEjB,GAGIA,IAAe,MAAY;AAC/B,IAAAV,KAAUD,EAAkB,OAAO;AAAA,EAAA,GAG/BU,IAAc,MAAY;AAC9B,IAAAT,KAAUD,EAAkB,MAAM;AAAA,EAAA,GAG9BY,IAAiB,MAAY;AACjC,IAAAZ,EAAkB,IAAI;AAAA,EAAA,GAGlBa,IAAiBxB,IAAeR,IAAYS;AAElD,SAAAwB,EAAU,MAAM;AACR,UAAAC,IAAmB,CAACC,MAA4B;AACpD,MAAAtB,EAAesB,EAAM,QAAQ,CAAC,EAAE,OAAO;AAAA,IAAA,GAGnCC,IAAkB,CAACD,MAA4B;AACnD,MAAApB,EAAaoB,EAAM,QAAQ,CAAC,EAAE,OAAO;AACrC,YAAME,IAAgBF,EAAM,QAAQ,CAAC,EAAE,UAAUvB;AAE7C,MAAAoB,MAAmB,KAAKK,IAAgB,KAEjCL,MAAmBM,EAAM,SAAS,MAAMrC,CAAQ,IAAI,KAAKoC,IAAgB,IADlFpB,EAAc,CAAC,IAIfA,EAAcoB,CAAa;AAAA,IAC7B,GAGIE,IAAiB,MAAY;AAEjC,MADsB,KAAK,IAAIzB,IAAYF,CAAW,KACjCd,MACfgB,IAAYF,IAEdc,EAAc,KAAK,IAAI,GAAGM,IAAiB,CAAC,GAAGA,CAAc,IAG/CN,EAAA,KAAK,IAAIY,EAAM,SAAS,MAAMrC,CAAQ,IAAI,GAAG+B,IAAiB,CAAC,GAAGA,CAAc,IAGlGf,EAAc,CAAC;AAAA,IAAA;AAGb,WAAAV,MAAmB,WAAWe,EAAQ,YAChCA,EAAA,QAAQ,iBAAiB,cAAcY,CAAgB,GACvDZ,EAAA,QAAQ,iBAAiB,aAAac,CAAe,GACrDd,EAAA,QAAQ,iBAAiB,YAAYiB,CAAc,IAEtD,MAAM;AACX,MAAIjB,EAAQ,YACFA,EAAA,QAAQ,oBAAoB,cAAcY,CAAgB,GAC1DZ,EAAA,QAAQ,oBAAoB,aAAac,CAAe,GACxDd,EAAA,QAAQ,oBAAoB,YAAYiB,CAAc;AAAA,IAChE;AAAA,KAED,CAAChC,GAAgBK,GAAaE,GAAWkB,CAAc,CAAC,GAE3DC,EAAU,MAAM;AACd,UAAMO,IAAqB,MAAY;AACtB,MAAAT;IAAA;AAGjB,WAAIP,EAAY,WACFA,EAAA,QAAQ,iBAAiB,gBAAgBgB,CAAkB,GAGlE,MAAM;AACX,MAAIhB,EAAY,WACFA,EAAA,QAAQ,oBAAoB,gBAAgBgB,CAAkB;AAAA,IAC5E;AAAA,EAEJ,GAAG,CAAE,CAAA,GAGF,gBAAAC,EAAA,OAAA,EAAI,WAAAvC,GAAsB,eAAaG,GACtC,UAAA;AAAA,IAAA,gBAAAoC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKhB;AAAA,QACL,WAAWiB,EAAWC,EAAO,kBAAkB,GAAG;AAAA,UAChD,CAACA,EAAO,0BAA0B,CAAC,GAAGvC;AAAA,QAAA,CACvC;AAAA,QAED,UAAA;AAAA,UAAA,gBAAAwC;AAAA,YAACC;AAAA,YAAA;AAAA,cACC,gBAAgB,CAACC,MAAkBpB,EAAcoB,GAAOd,CAAc;AAAA,cACtE,aAAaA;AAAA,cACb,OAAA7B;AAAA,cACA,MAAAG;AAAA,cAEC,UAAAL;AAAA,YAAA;AAAA,UACH;AAAA,UACA,gBAAA2C;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWF,EAAWC,EAAO,eAAe,GAAGA,EAAO,kBAAkBxC,CAAK,EAAE,GAAG;AAAA,gBAChF,CAACwC,EAAO,uBAAuB,CAAC,GAAGrC,KAAQ;AAAA,cAAA,CAC5C;AAAA,YAAA;AAAA,UACF;AAAA,QAAA;AAAA,MAAA;AAAA,IACH;AAAA,IACA,gBAAAsC,EAAC,OAAI,EAAA,KAAKtB,GAAS,OAAO,EAAE,WAAWhB,KAAQ,WAAW,UAAU,GAClE,GAAA,UAAA,gBAAAsC;AAAA,MAACG;AAAA,MAAA;AAAA,QACC,KAAKvB;AAAA,QACL,OAAArB;AAAA,QACA,MAAAG;AAAA,QACA,SAAS0B,KAAkB;AAAA,QAC3B,YAAAhB;AAAA,QACA,SAASE;AAAA,QAER,UAAMoB,EAAA,SAAS,QAAQrC,CAAQ,EAAE+B,CAAc;AAAA,MAAA;AAAA,IAAA,GAEpD;AAAA,EACF,EAAA,CAAA;AAEJ,GAKMgB,IAAOjD;AACbiD,EAAK,cAAc;AACnBA,EAAK,MAAMC;AACXD,EAAK,IAAI,cAAc;"}
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { FormMode } from '../../constants';
3
- export interface TextareaProps extends Pick<React.InputHTMLAttributes<HTMLTextAreaElement>, 'aria-describedby' | 'autoFocus' | 'disabled' | 'name' | 'autoComplete' | 'placeholder' | 'readOnly' | 'required' | 'defaultValue' | 'onChange'> {
3
+ export interface TextareaProps extends Pick<React.InputHTMLAttributes<HTMLTextAreaElement>, 'aria-describedby' | 'autoFocus' | 'disabled' | 'name' | 'autoComplete' | 'placeholder' | 'readOnly' | 'required' | 'defaultValue' | 'onChange' | 'value'> {
4
4
  /** max character limit in textarea */
5
5
  maxCharacters?: number;
6
6
  /** The text is displayed in the end of the text-counter */
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "url": "git+https://github.com/helsenorge/designsystem.git"
8
8
  },
9
9
  "homepage": "https://helsenorge.design",
10
- "version": "8.6.0-beta.1",
10
+ "version": "8.8.0",
11
11
  "author": "Helsenorge",
12
12
  "license": "MIT",
13
13
  "dependencies": {