@helsenorge/designsystem-react 8.6.0 → 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 +27 -3
- package/Input.js.map +1 -1
- package/Textarea.js +86 -84
- package/Textarea.js.map +1 -1
- package/components/Input/Input.d.ts +1 -1
- package/components/Textarea/Textarea.d.ts +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
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
|
+
|
|
1
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
|
|
@@ -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/Textarea.js
CHANGED
|
@@ -1,110 +1,112 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { FormMode as
|
|
5
|
-
import { useUuid as
|
|
6
|
-
import { getAriaDescribedBy as
|
|
7
|
-
import { u as
|
|
8
|
-
import { E as
|
|
9
|
-
import { a as
|
|
10
|
-
import { M as
|
|
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 *
|
|
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:
|
|
16
|
-
width:
|
|
17
|
-
testId:
|
|
15
|
+
maxText: g,
|
|
16
|
+
width: w,
|
|
17
|
+
testId: N,
|
|
18
18
|
defaultValue: i,
|
|
19
|
-
marginBottom:
|
|
20
|
-
transparent:
|
|
21
|
-
mode: n =
|
|
22
|
-
label:
|
|
23
|
-
textareaId:
|
|
24
|
-
minRows:
|
|
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:
|
|
27
|
-
error:
|
|
28
|
-
errorText:
|
|
29
|
-
errorTextId:
|
|
30
|
-
autoFocus:
|
|
31
|
-
disabled:
|
|
32
|
-
name:
|
|
33
|
-
autoComplete:
|
|
34
|
-
placeholder:
|
|
35
|
-
readOnly:
|
|
36
|
-
required:
|
|
37
|
-
onChange:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
B(()
|
|
41
|
-
|
|
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
|
|
44
|
-
const
|
|
45
|
-
e.rows =
|
|
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 ===
|
|
48
|
-
},
|
|
49
|
-
[t["textarea--gutterBottom"]]:
|
|
50
|
-
}),
|
|
51
|
-
[t["input-container--transparent"]]:
|
|
52
|
-
[t["input-container--on-blueberry"]]:
|
|
53
|
-
[t["input-container--on-dark"]]:
|
|
54
|
-
[t["input-container--invalid"]]:
|
|
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
|
-
}),
|
|
57
|
+
}), Y = f(t["input-container__input"], {
|
|
57
58
|
[t["input-container__input--disabled"]]: a.disabled
|
|
58
59
|
});
|
|
59
|
-
|
|
60
|
-
var e,
|
|
61
|
-
if (
|
|
62
|
-
const r = (
|
|
63
|
-
|
|
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
|
|
67
|
-
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
},
|
|
71
|
-
return /* @__PURE__ */
|
|
72
|
-
|
|
73
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
77
|
+
...G,
|
|
78
|
+
rows: O,
|
|
77
79
|
defaultValue: i,
|
|
78
|
-
id:
|
|
79
|
-
className:
|
|
80
|
-
ref:
|
|
81
|
-
"aria-describedby":
|
|
82
|
-
"aria-invalid": !!
|
|
83
|
-
autoFocus:
|
|
84
|
-
disabled:
|
|
85
|
-
name:
|
|
86
|
-
autoComplete:
|
|
87
|
-
placeholder:
|
|
88
|
-
readOnly:
|
|
89
|
-
required:
|
|
90
|
-
onChange:
|
|
91
|
-
|
|
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__ */
|
|
95
|
-
|
|
96
|
+
o && /* @__PURE__ */ m(
|
|
97
|
+
ue,
|
|
96
98
|
{
|
|
97
99
|
maxCharacters: o,
|
|
98
|
-
length:
|
|
99
|
-
maxText:
|
|
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
|
-
|
|
108
|
+
pe.displayName = "Textarea";
|
|
107
109
|
export {
|
|
108
|
-
|
|
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. */
|
|
@@ -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 */
|