@helsenorge/designsystem-react 13.2.0 → 13.4.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/lib/CHANGELOG.md +33 -0
- package/lib/Highlighter.js +7 -7
- package/lib/Highlighter.js.map +1 -1
- package/lib/Input.js +24 -5
- package/lib/Input.js.map +1 -1
- package/lib/LazyIcon.js +3 -1
- package/lib/LazyIcon.js.map +1 -1
- package/lib/LinkList.js.map +1 -1
- package/lib/MaxCharacters.js +1 -1
- package/lib/MaxCharacters.js.map +1 -1
- package/lib/Panel.js +12 -5
- package/lib/Panel.js.map +1 -1
- package/lib/Slider.js +1 -1
- package/lib/Slider.js.map +1 -1
- package/lib/Textarea.js +24 -5
- package/lib/Textarea.js.map +1 -1
- package/lib/components/Dropdown/index.js +2 -1
- package/lib/components/Dropdown/index.js.map +1 -1
- package/lib/components/Dropdown/styles.module.scss +0 -6
- package/lib/components/ElementHeader/ElementHeaderText/index.js +1 -0
- package/lib/components/ElementHeader/ElementHeaderText/index.js.map +1 -1
- package/lib/components/FormGroup/index.js +1 -1
- package/lib/components/Highlighter/index.js +1 -0
- package/lib/components/Icons/AdditionalIconInformation.d.ts +10 -2
- package/lib/components/Icons/AdditionalIconInformation.js +10 -2
- package/lib/components/Icons/AdditionalIconInformation.js.map +1 -1
- package/lib/components/Icons/IconNames.d.ts +1 -1
- package/lib/components/Icons/IconNames.js +3 -1
- package/lib/components/Icons/IconNames.js.map +1 -1
- package/lib/components/Icons/ZoomInLeft.d.ts +4 -0
- package/lib/components/Icons/ZoomInLeft.js +30 -0
- package/lib/components/Icons/ZoomInLeft.js.map +1 -0
- package/lib/components/Icons/ZoomOutLeft.d.ts +4 -0
- package/lib/components/Icons/ZoomOutLeft.js +30 -0
- package/lib/components/Icons/ZoomOutLeft.js.map +1 -0
- package/lib/components/Input/Input.d.ts +4 -1
- package/lib/components/Input/index.js +1 -1
- package/lib/components/Input/resourceHelper.d.ts +3 -0
- package/lib/components/LinkList/LinkList.d.ts +1 -1
- package/lib/components/LinkList/styles.module.scss +0 -1
- package/lib/components/MaxCharacters/MaxCharacters.d.ts +1 -1
- package/lib/components/Panel/Panel.d.ts +2 -0
- package/lib/components/Panel/PanelTitle/index.js +1 -0
- package/lib/components/Textarea/Textarea.d.ts +4 -1
- package/lib/components/Textarea/resourceHelper.d.ts +3 -0
- package/lib/components/Validation/index.js +1 -1
- package/lib/resources/HN.Designsystem.Input.en-GB.json.d.ts +6 -0
- package/lib/resources/HN.Designsystem.Input.nb-NO.json.d.ts +6 -0
- package/lib/resources/HN.Designsystem.Input.nn-NO.json.d.ts +6 -0
- package/lib/resources/HN.Designsystem.TextArea.en-GB.json.d.ts +6 -0
- package/lib/resources/HN.Designsystem.TextArea.nb-NO.json.d.ts +6 -0
- package/lib/resources/HN.Designsystem.TextArea.nn-NO.json.d.ts +6 -0
- package/package.json +1 -1
package/lib/Slider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.js","names":["handleKeyDown: React.KeyboardEventHandler<HTMLDivElement>","handleTrackClick: React.MouseEventHandler<HTMLDivElement>","handlePointerDown: React.PointerEventHandler<HTMLDivElement>"],"sources":["../src/components/Slider/Slider.tsx","../src/components/Slider/index.ts"],"sourcesContent":["import React, { useEffect, useState, useRef, useId } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { useSize } from '../../hooks/useSize';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport { isMutableRefObject, mergeRefs } from '../../utils/refs';\nimport ErrorWrapper, { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport Title from '../Title';\n\nimport styles from './styles.module.scss';\n\nconst useSafeNumberValue = (initial: number, min: number, max: number): [number, (value: number) => void] => {\n const [value, setValue] = useState(initial);\n\n const setSafeValue = (newValue: number): void => {\n if (newValue > max) {\n setValue(max);\n } else if (newValue < min) {\n setValue(min);\n } else {\n setValue(newValue);\n }\n };\n\n useEffect(() => {\n setSafeValue(initial);\n }, [min, max]);\n\n return [value, setSafeValue];\n};\n\nexport type SliderStep = {\n label?: number | string;\n emojiUniCode?: string;\n};\n\nexport interface SliderProps\n extends ErrorWrapperClassNameProps,\n Pick<React.InputHTMLAttributes<HTMLInputElement>, 'id' | 'name' | 'onChange' | 'onBlur'> {\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 /**\tSets the title of the slider. */\n title?: string;\n /** Adds the left hand label to the element. */\n labelLeft?: string;\n /** Adds the right hand label to the element. */\n labelRight?: string;\n /**\tSets aria-label of the slider. */\n ariaLabel?: string;\n /** Disables the slider element. */\n disabled?: boolean;\n /** Sets the minimum allowed value on the slider - this overrides the use of steps prop for minValue/maxValue. */\n minValue?: number;\n /** Sets the maximum allowed value on the slider - this overrides the use of steps prop for minValue/maxValue. */\n maxValue?: number;\n /** If set to false will only trigger onChange once a user interaction has been made, updates to this prop will be taken into account - true by default */\n selected?: boolean;\n /** Sets the steps data for the slider */\n steps?: SliderStep[];\n /** Sets the step to move per point in the slider */\n step?: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the value of the slider */\n value?: number;\n}\n\nexport const Slider = React.forwardRef((props: SliderProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n title,\n ariaLabel,\n error,\n errorText,\n errorTextId: errorTextIdProp,\n errorWrapperClassName,\n labelLeft,\n labelRight,\n disabled = false,\n onChange,\n steps,\n step = 1,\n minValue = 0,\n maxValue = steps ? steps.length - 1 : 100,\n selected = true,\n testId,\n value,\n ...rest\n } = props;\n\n const [isMoving, setIsMoving] = useState(false);\n const [selectedState, setSelectedState] = useState(typeof value === 'undefined' ? selected : true);\n const [valueState, setValueState] = useSafeNumberValue(\n typeof value === 'undefined' ? (maxValue - minValue) / 2 + minValue : value,\n minValue,\n maxValue\n );\n\n const errorTextId = useIdWithFallback(errorTextIdProp);\n const baseId = useId();\n const titleId = 'title-' + baseId;\n const labelLeftId = 'label-' + baseId;\n const labelRightId = 'label-right-' + baseId;\n const trackRef = useRef<HTMLDivElement>(null);\n const { refObject, isFocused } = usePseudoClasses<HTMLInputElement>(isMutableRefObject(ref) ? ref : null);\n const mergedRefs = mergeRefs([ref, refObject]);\n\n const { width: trackWidth } = useSize(trackRef) || { width: 0 };\n const largeStep = maxValue / 10;\n const invalid = !!errorText || !!error;\n\n useEffect(() => {\n const handlePointerUp = (): void => {\n setIsMoving(false);\n };\n\n document.addEventListener('pointerup', handlePointerUp);\n\n return (): void => {\n document.removeEventListener('pointerup', handlePointerUp);\n };\n }, []);\n\n const getValueBasedOnMarkerPosition = (markerPosition: number): number => {\n const trackPosition = trackRef.current?.getBoundingClientRect().x ?? 0;\n\n // Calculate the normalized position (0 to 1) of the marker along the track\n const normalizedPosition = (markerPosition - trackPosition) / trackWidth;\n const valueRange = maxValue - minValue;\n // Calculate the value without considering the step\n let value = normalizedPosition * valueRange + minValue;\n // Adjust the value to account for the step increment\n const stepCount = Math.round(value / step);\n value = stepCount * step;\n value = Math.max(minValue, Math.min(maxValue, value));\n\n return value;\n };\n\n useEffect(() => {\n const handlePointerMove = (e: PointerEvent): void => {\n if (!disabled && isMoving) {\n const newValue = getValueBasedOnMarkerPosition(e.clientX);\n setValueState(newValue);\n }\n };\n\n document.addEventListener('pointermove', handlePointerMove);\n\n return (): void => {\n document.removeEventListener('pointermove', handlePointerMove);\n };\n }, [isMoving]);\n\n useEffect(() => {\n if (value !== valueState && typeof value !== 'undefined') {\n handleSelected();\n setValueState(value);\n }\n }, [value]);\n\n useEffect(() => {\n if (typeof value === 'undefined' && selected !== selectedState) {\n setSelectedState(selected);\n }\n }, [selected]);\n\n const handleSelected = (): void => {\n if (selectedState === false) {\n setSelectedState(true);\n }\n };\n\n const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = e => {\n if (disabled) return;\n\n let flag = false;\n\n switch (e.key) {\n case 'ArrowLeft':\n case 'ArrowDown':\n setValueState(valueState - step);\n flag = true;\n break;\n case 'PageDown':\n setValueState(valueState - largeStep);\n flag = true;\n break;\n case 'ArrowRight':\n case 'ArrowUp':\n setValueState(valueState + step);\n flag = true;\n break;\n case 'PageUp':\n setValueState(valueState + largeStep);\n flag = true;\n break;\n case 'Home':\n setValueState(minValue);\n flag = true;\n break;\n case 'End':\n setValueState(maxValue);\n flag = true;\n break;\n default:\n break;\n }\n\n if (flag) {\n handleSelected();\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleTrackClick: React.MouseEventHandler<HTMLDivElement> = e => {\n if (disabled) return;\n\n const newValue = getValueBasedOnMarkerPosition(e.clientX);\n setValueState(newValue);\n refObject.current?.focus();\n };\n\n const handlePointerDown: React.PointerEventHandler<HTMLDivElement> = e => {\n if (disabled) return;\n\n setIsMoving(true);\n handleSelected();\n\n e.preventDefault();\n e.stopPropagation();\n\n refObject.current?.focus();\n };\n\n const markerXPos = maxValue !== minValue ? (trackWidth / (maxValue - minValue)) * (valueState - minValue) : 0;\n\n const getAriaValueText = (): string | undefined => {\n const stepIndex = steps ? Math.round((valueState - minValue) / step) : null;\n\n if (steps && stepIndex !== null && stepIndex >= 0 && stepIndex < steps.length) {\n const step = steps[stepIndex];\n const emojiCode = step.emojiUniCode;\n const label = typeof step.label !== 'undefined' ? step.label.toString() : undefined;\n\n return emojiCode && label ? `${emojiCode} ${label}` : emojiCode || label;\n }\n\n return undefined;\n };\n\n const getAriaLabeledById = (): string | undefined => {\n if (title && labelLeft && labelRight) {\n return [titleId, labelLeftId, labelRightId].join(' ');\n }\n if (title && labelLeft) {\n return [titleId, labelLeftId].join(' ');\n }\n if (title && labelRight) {\n return [titleId, labelRightId].join(' ');\n }\n if (title) {\n return titleId;\n }\n };\n\n const ariaLabelAttributes = getAriaLabelAttributes({\n label: ariaLabel,\n id: getAriaLabeledById(),\n prefer: 'label',\n });\n\n const getXPositionStyling = (index: number, stepsLength: number): { left: string } => {\n return { left: `${(index / (stepsLength - 1)) * 100}%` };\n };\n\n useEffect(() => {\n if (selectedState && onChange) {\n onChange({\n target: {\n name: props.name,\n value: valueState,\n },\n } as unknown as React.ChangeEvent<HTMLInputElement>);\n }\n }, [valueState, selectedState]);\n\n const renderEmojies = (): React.ReactNode => {\n return (\n <div className={styles['slider__emoji-container']}>\n {steps?.map((step, index) => {\n return (\n step.emojiUniCode && (\n <div\n aria-hidden={true}\n key={'emoji' + index}\n className={styles['slider__emoji']}\n style={getXPositionStyling(index, steps.length)}\n >\n {step.emojiUniCode}\n </div>\n )\n );\n })}\n </div>\n );\n };\n\n const renderSteps = (): React.ReactNode => {\n return steps?.map((_step, index) => {\n return <div key={'step' + index} className={styles['slider__track__step']} style={getXPositionStyling(index, steps.length)} />;\n });\n };\n\n const renderStepLabels = (): React.ReactNode => {\n return (\n <div className={styles['slider__value-container']}>\n {steps?.map((step, index) => {\n return (\n typeof step.label !== 'undefined' && (\n <div\n aria-hidden={true}\n key={'label' + index}\n className={styles['slider__value']}\n style={getXPositionStyling(index, steps.length)}\n >\n {step.label}\n </div>\n )\n );\n })}\n </div>\n );\n };\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <input\n aria-valuetext={getAriaValueText()}\n className={styles['sr-only-slider']}\n disabled={disabled}\n min={minValue}\n max={maxValue}\n onChange={onChange}\n onKeyDown={handleKeyDown}\n value={valueState}\n ref={mergedRefs}\n type=\"range\"\n {...rest}\n {...ariaLabelAttributes}\n />\n <div className={styles.slider} data-testid={testId} data-analyticsid={AnalyticsId.Slider}>\n {title && (\n <Title className={styles['slider__title']} htmlMarkup={'h3'} margin={0} appearance={'title3'} id={titleId}>\n {title}\n </Title>\n )}\n <div className={styles['slider__content-container']}>\n {renderEmojies()}\n {/* Slider streken er klikkbar med mus/touch */}\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}\n <div\n ref={trackRef}\n className={classNames(styles['slider__track-wrapper'], disabled && styles['slider__track-wrapper--disabled'])}\n onClick={handleTrackClick}\n onPointerDown={handlePointerDown}\n >\n <div className={classNames(styles.slider__track, disabled && styles['slider__track--disabled'])}>{renderSteps()}</div>\n <div\n className={classNames(styles.slider__marker, {\n [styles['slider__marker--disabled']]: disabled,\n [styles['slider__marker--selected']]: selectedState,\n [styles['slider__marker--invalid']]: invalid,\n [styles['slider__marker--focused']]: !disabled && isFocused,\n })}\n style={{\n left: `${markerXPos}px`,\n }}\n />\n </div>\n {renderStepLabels()}\n </div>\n {(labelLeft || labelRight) && (\n <span className={styles.slider__options}>\n <span id={labelLeftId}>{labelLeft}</span>\n <span id={labelRightId}>{labelRight}</span>\n </span>\n )}\n </div>\n </ErrorWrapper>\n );\n});\n\nSlider.displayName = 'Slider';\n\nexport default Slider;\n","import Slider from './Slider';\nexport * from './Slider';\nexport default Slider;\n"],"mappings":";;;;;;;;;;;;AAeA,IAAM,sBAAsB,SAAiB,KAAa,QAAmD;CAC3G,MAAM,CAAC,OAAO,YAAY,SAAS,QAAQ;CAE3C,MAAM,gBAAgB,aAA2B;AAC/C,MAAI,WAAW,IACb,UAAS,IAAI;WACJ,WAAW,IACpB,UAAS,IAAI;MAEb,UAAS,SAAS;;AAItB,iBAAgB;AACd,eAAa,QAAQ;IACpB,CAAC,KAAK,IAAI,CAAC;AAEd,QAAO,CAAC,OAAO,aAAa;;AA2C9B,MAAa,SAAS,MAAM,YAAY,OAAoB,QAAqC;CAC/F,MAAM,EACJ,OACA,WACA,OACA,WACA,aAAa,iBACb,uBACA,WACA,YACA,WAAW,OACX,UACA,OACA,OAAO,GACP,WAAW,GACX,WAAW,QAAQ,MAAM,SAAS,IAAI,KACtC,WAAW,MACX,QACA,OACA,GAAG,SACD;CAEJ,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;CAC/C,MAAM,CAAC,eAAe,oBAAoB,SAAS,OAAO,UAAU,cAAc,WAAW,KAAK;CAClG,MAAM,CAAC,YAAY,iBAAiB,mBAClC,OAAO,UAAU,eAAe,WAAW,YAAY,IAAI,WAAW,OACtE,UACA,SACD;CAED,MAAM,cAAc,kBAAkB,gBAAgB;CACtD,MAAM,SAAS,OAAO;CACtB,MAAM,UAAU,WAAW;CAC3B,MAAM,cAAc,WAAW;CAC/B,MAAM,eAAe,iBAAiB;CACtC,MAAM,WAAW,OAAuB,KAAK;CAC7C,MAAM,EAAE,WAAW,cAAc,iBAAmC,mBAAmB,IAAI,GAAG,MAAM,KAAK;CACzG,MAAM,aAAa,UAAU,CAAC,KAAK,UAAU,CAAC;CAE9C,MAAM,EAAE,OAAO,eAAe,QAAQ,SAAS,IAAI,EAAE,OAAO,GAAG;CAC/D,MAAM,YAAY,WAAW;CAC7B,MAAM,UAAU,CAAC,CAAC,aAAa,CAAC,CAAC;AAEjC,iBAAgB;EACd,MAAM,wBAA8B;AAClC,eAAY,MAAM;;AAGpB,WAAS,iBAAiB,aAAa,gBAAgB;AAEvD,eAAmB;AACjB,YAAS,oBAAoB,aAAa,gBAAgB;;IAE3D,EAAE,CAAC;CAEN,MAAM,iCAAiC,mBAAmC;EAOxE,IAAI,WAHwB,kBAHN,SAAS,SAAS,uBAAuB,CAAC,KAAK,MAGP,cAC3C,WAAW,YAEgB;AAG9C,YADkB,KAAK,MAAM,UAAQ,KAAK,GACtB;AACpB,YAAQ,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,QAAM,CAAC;AAErD,SAAO;;AAGT,iBAAgB;EACd,MAAM,qBAAqB,MAA0B;AACnD,OAAI,CAAC,YAAY,SAEf,eADiB,8BAA8B,EAAE,QAAQ,CAClC;;AAI3B,WAAS,iBAAiB,eAAe,kBAAkB;AAE3D,eAAmB;AACjB,YAAS,oBAAoB,eAAe,kBAAkB;;IAE/D,CAAC,SAAS,CAAC;AAEd,iBAAgB;AACd,MAAI,UAAU,cAAc,OAAO,UAAU,aAAa;AACxD,mBAAgB;AAChB,iBAAc,MAAM;;IAErB,CAAC,MAAM,CAAC;AAEX,iBAAgB;AACd,MAAI,OAAO,UAAU,eAAe,aAAa,cAC/C,kBAAiB,SAAS;IAE3B,CAAC,SAAS,CAAC;CAEd,MAAM,uBAA6B;AACjC,MAAI,kBAAkB,MACpB,kBAAiB,KAAK;;CAI1B,MAAMA,iBAA4D,MAAK;AACrE,MAAI,SAAU;EAEd,IAAI,OAAO;AAEX,UAAQ,EAAE,KAAV;GACE,KAAK;GACL,KAAK;AACH,kBAAc,aAAa,KAAK;AAChC,WAAO;AACP;GACF,KAAK;AACH,kBAAc,aAAa,UAAU;AACrC,WAAO;AACP;GACF,KAAK;GACL,KAAK;AACH,kBAAc,aAAa,KAAK;AAChC,WAAO;AACP;GACF,KAAK;AACH,kBAAc,aAAa,UAAU;AACrC,WAAO;AACP;GACF,KAAK;AACH,kBAAc,SAAS;AACvB,WAAO;AACP;GACF,KAAK;AACH,kBAAc,SAAS;AACvB,WAAO;AACP;GACF,QACE;;AAGJ,MAAI,MAAM;AACR,mBAAgB;AAChB,KAAE,gBAAgB;AAClB,KAAE,iBAAiB;;;CAIvB,MAAMC,oBAA4D,MAAK;AACrE,MAAI,SAAU;AAGd,gBADiB,8BAA8B,EAAE,QAAQ,CAClC;AACvB,YAAU,SAAS,OAAO;;CAG5B,MAAMC,qBAA+D,MAAK;AACxE,MAAI,SAAU;AAEd,cAAY,KAAK;AACjB,kBAAgB;AAEhB,IAAE,gBAAgB;AAClB,IAAE,iBAAiB;AAEnB,YAAU,SAAS,OAAO;;CAG5B,MAAM,aAAa,aAAa,WAAY,cAAc,WAAW,aAAc,aAAa,YAAY;CAE5G,MAAM,yBAA6C;EACjD,MAAM,YAAY,QAAQ,KAAK,OAAO,aAAa,YAAY,KAAK,GAAG;AAEvE,MAAI,SAAS,cAAc,QAAQ,aAAa,KAAK,YAAY,MAAM,QAAQ;GAC7E,MAAM,SAAO,MAAM;GACnB,MAAM,YAAY,OAAK;GACvB,MAAM,QAAQ,OAAO,OAAK,UAAU,cAAc,OAAK,MAAM,UAAU,GAAG,KAAA;AAE1E,UAAO,aAAa,QAAQ,GAAG,UAAU,GAAG,UAAU,aAAa;;;CAMvE,MAAM,2BAA+C;AACnD,MAAI,SAAS,aAAa,WACxB,QAAO;GAAC;GAAS;GAAa;GAAa,CAAC,KAAK,IAAI;AAEvD,MAAI,SAAS,UACX,QAAO,CAAC,SAAS,YAAY,CAAC,KAAK,IAAI;AAEzC,MAAI,SAAS,WACX,QAAO,CAAC,SAAS,aAAa,CAAC,KAAK,IAAI;AAE1C,MAAI,MACF,QAAO;;CAIX,MAAM,sBAAsB,uBAAuB;EACjD,OAAO;EACP,IAAI,oBAAoB;EACxB,QAAQ;EACT,CAAC;CAEF,MAAM,uBAAuB,OAAe,gBAA0C;AACpF,SAAO,EAAE,MAAM,GAAI,SAAS,cAAc,KAAM,IAAI,IAAI;;AAG1D,iBAAgB;AACd,MAAI,iBAAiB,SACnB,UAAS,EACP,QAAQ;GACN,MAAM,MAAM;GACZ,OAAO;GACR,EACF,CAAmD;IAErD,CAAC,YAAY,cAAc,CAAC;CAE/B,MAAM,sBAAuC;AAC3C,SACE,oBAAC,OAAA;GAAI,WAAW,OAAO;aACpB,OAAO,KAAK,QAAM,UAAU;AAC3B,WACE,OAAK,gBACH,oBAAC,OAAA;KACC,eAAa;KAEb,WAAW,OAAO;KAClB,OAAO,oBAAoB,OAAO,MAAM,OAAO;eAE9C,OAAK;OAJD,UAAU,MAKX;KAGV;IACE;;CAIV,MAAM,oBAAqC;AACzC,SAAO,OAAO,KAAK,OAAO,UAAU;AAClC,UAAO,oBAAC,OAAA;IAAyB,WAAW,OAAO;IAAwB,OAAO,oBAAoB,OAAO,MAAM,OAAO;MAAzG,SAAS,MAAoG;IAC9H;;CAGJ,MAAM,yBAA0C;AAC9C,SACE,oBAAC,OAAA;GAAI,WAAW,OAAO;aACpB,OAAO,KAAK,QAAM,UAAU;AAC3B,WACE,OAAO,OAAK,UAAU,eACpB,oBAAC,OAAA;KACC,eAAa;KAEb,WAAW,OAAO;KAClB,OAAO,oBAAoB,OAAO,MAAM,OAAO;eAE9C,OAAK;OAJD,UAAU,MAKX;KAGV;IACE;;AAIV,QACE,qBAAC,sBAAA;EAAa,WAAW;EAAkC;EAAwB;aACjF,oBAAC,SAAA;GACC,kBAAgB,kBAAkB;GAClC,WAAW,OAAO;GACR;GACV,KAAK;GACL,KAAK;GACK;GACV,WAAW;GACX,OAAO;GACP,KAAK;GACL,MAAK;GACL,GAAI;GACJ,GAAI;IACJ,EACF,qBAAC,OAAA;GAAI,WAAW,OAAO;GAAQ,eAAa;GAAQ,oBAAkB,YAAY;;IAC/E,SACC,oBAAC,eAAA;KAAM,WAAW,OAAO;KAAkB,YAAY;KAAM,QAAQ;KAAG,YAAY;KAAU,IAAI;eAC/F;MACK;IAEV,qBAAC,OAAA;KAAI,WAAW,OAAO;;MACpB,eAAe;MAGhB,qBAAC,OAAA;OACC,KAAK;OACL,WAAW,WAAW,OAAO,0BAA0B,YAAY,OAAO,mCAAmC;OAC7G,SAAS;OACT,eAAe;kBAEf,oBAAC,OAAA;QAAI,WAAW,WAAW,OAAO,eAAe,YAAY,OAAO,2BAA2B;kBAAG,aAAa;SAAO,EACtH,oBAAC,OAAA;QACC,WAAW,WAAW,OAAO,gBAAgB;UAC1C,OAAO,8BAA8B;UACrC,OAAO,8BAA8B;UACrC,OAAO,6BAA6B;UACpC,OAAO,6BAA6B,CAAC,YAAY;SACnD,CAAC;QACF,OAAO,EACL,MAAM,GAAG,WAAW,KACrB;SACD,CAAA;QACE;MACL,kBAAkB;;MACf;KACJ,aAAa,eACb,qBAAC,QAAA;KAAK,WAAW,OAAO;gBACtB,oBAAC,QAAA;MAAK,IAAI;gBAAc;OAAiB,EACzC,oBAAC,QAAA;MAAK,IAAI;gBAAe;OAAkB,CAAA;MACtC;;IAEL,CAAA;GACO;EAEjB;AAEF,OAAO,cAAc;AC/YrB,IAAA,mBDiZe"}
|
|
1
|
+
{"version":3,"file":"Slider.js","names":["handleKeyDown: React.KeyboardEventHandler<HTMLDivElement>","handleTrackClick: React.MouseEventHandler<HTMLDivElement>","handlePointerDown: React.PointerEventHandler<HTMLDivElement>"],"sources":["../src/components/Slider/Slider.tsx","../src/components/Slider/index.ts"],"sourcesContent":["import React, { useEffect, useState, useRef, useId } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { useSize } from '../../hooks/useSize';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport { isMutableRefObject, mergeRefs } from '../../utils/refs';\nimport ErrorWrapper, { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport Title from '../Title';\n\nimport styles from './styles.module.scss';\n\nconst useSafeNumberValue = (initial: number, min: number, max: number): [number, (value: number) => void] => {\n const [value, setValue] = useState(initial);\n\n const setSafeValue = (newValue: number): void => {\n if (newValue > max) {\n setValue(max);\n } else if (newValue < min) {\n setValue(min);\n } else {\n setValue(newValue);\n }\n };\n\n useEffect(() => {\n setSafeValue(initial);\n }, [min, max]);\n\n return [value, setSafeValue];\n};\n\nexport type SliderStep = {\n label?: number | string;\n emojiUniCode?: string;\n};\n\nexport interface SliderProps\n extends ErrorWrapperClassNameProps,\n Pick<React.InputHTMLAttributes<HTMLInputElement>, 'id' | 'name' | 'onChange' | 'onBlur'> {\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 /**\tSets the title of the slider. */\n title?: string;\n /** Adds the left hand label to the element. */\n labelLeft?: string;\n /** Adds the right hand label to the element. */\n labelRight?: string;\n /**\tSets aria-label of the slider. */\n ariaLabel?: string;\n /** Disables the slider element. */\n disabled?: boolean;\n /** Sets the minimum allowed value on the slider - this overrides the use of steps prop for minValue/maxValue. */\n minValue?: number;\n /** Sets the maximum allowed value on the slider - this overrides the use of steps prop for minValue/maxValue. */\n maxValue?: number;\n /** If set to false will only trigger onChange once a user interaction has been made, updates to this prop will be taken into account - true by default */\n selected?: boolean;\n /** Sets the steps data for the slider */\n steps?: SliderStep[];\n /** Sets the step to move per point in the slider */\n step?: number;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the value of the slider */\n value?: number;\n}\n\nexport const Slider = React.forwardRef((props: SliderProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n title,\n ariaLabel,\n error,\n errorText,\n errorTextId: errorTextIdProp,\n errorWrapperClassName,\n labelLeft,\n labelRight,\n disabled = false,\n onChange,\n steps,\n step = 1,\n minValue = 0,\n maxValue = steps ? steps.length - 1 : 100,\n selected = true,\n testId,\n value,\n ...rest\n } = props;\n\n const [isMoving, setIsMoving] = useState(false);\n const [selectedState, setSelectedState] = useState(typeof value === 'undefined' ? selected : true);\n const [valueState, setValueState] = useSafeNumberValue(\n typeof value === 'undefined' ? (maxValue - minValue) / 2 + minValue : value,\n minValue,\n maxValue\n );\n\n const errorTextId = useIdWithFallback(errorTextIdProp);\n const baseId = useId();\n const titleId = 'title-' + baseId;\n const labelLeftId = 'label-' + baseId;\n const labelRightId = 'label-right-' + baseId;\n const trackRef = useRef<HTMLDivElement>(null);\n const { refObject, isFocused } = usePseudoClasses<HTMLInputElement>(isMutableRefObject(ref) ? ref : null);\n const mergedRefs = mergeRefs([ref, refObject]);\n\n const { width: trackWidth } = useSize(trackRef) || { width: 0 };\n const largeStep = maxValue / 10;\n const invalid = !!errorText || !!error;\n\n useEffect(() => {\n const handlePointerUp = (): void => {\n setIsMoving(false);\n };\n\n document.addEventListener('pointerup', handlePointerUp);\n\n return (): void => {\n document.removeEventListener('pointerup', handlePointerUp);\n };\n }, []);\n\n const getValueBasedOnMarkerPosition = (markerPosition: number): number => {\n const trackPosition = trackRef.current?.getBoundingClientRect().x ?? 0;\n\n // Calculate the normalized position (0 to 1) of the marker along the track\n const normalizedPosition = (markerPosition - trackPosition) / trackWidth;\n const valueRange = maxValue - minValue;\n // Calculate the value without considering the step\n let value = normalizedPosition * valueRange + minValue;\n // Adjust the value to account for the step increment\n const stepCount = Math.round(value / step);\n value = stepCount * step;\n value = Math.max(minValue, Math.min(maxValue, value));\n\n return value;\n };\n\n useEffect(() => {\n const handlePointerMove = (e: PointerEvent): void => {\n if (!disabled && isMoving) {\n const newValue = getValueBasedOnMarkerPosition(e.clientX);\n setValueState(newValue);\n }\n };\n\n document.addEventListener('pointermove', handlePointerMove);\n\n return (): void => {\n document.removeEventListener('pointermove', handlePointerMove);\n };\n }, [isMoving]);\n\n useEffect(() => {\n if (value !== valueState && typeof value !== 'undefined') {\n handleSelected();\n setValueState(value);\n }\n }, [value]);\n\n useEffect(() => {\n if (typeof value === 'undefined' && selected !== selectedState) {\n setSelectedState(selected);\n }\n }, [selected]);\n\n const handleSelected = (): void => {\n if (selectedState === false) {\n setSelectedState(true);\n }\n };\n\n const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = e => {\n if (disabled) return;\n\n let flag = false;\n\n switch (e.key) {\n case 'ArrowLeft':\n case 'ArrowDown':\n setValueState(valueState - step);\n flag = true;\n break;\n case 'PageDown':\n setValueState(valueState - largeStep);\n flag = true;\n break;\n case 'ArrowRight':\n case 'ArrowUp':\n setValueState(valueState + step);\n flag = true;\n break;\n case 'PageUp':\n setValueState(valueState + largeStep);\n flag = true;\n break;\n case 'Home':\n setValueState(minValue);\n flag = true;\n break;\n case 'End':\n setValueState(maxValue);\n flag = true;\n break;\n default:\n break;\n }\n\n if (flag) {\n handleSelected();\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleTrackClick: React.MouseEventHandler<HTMLDivElement> = e => {\n if (disabled) return;\n\n const newValue = getValueBasedOnMarkerPosition(e.clientX);\n setValueState(newValue);\n refObject.current?.focus();\n };\n\n const handlePointerDown: React.PointerEventHandler<HTMLDivElement> = e => {\n if (disabled) return;\n\n handleTrackClick(e);\n setIsMoving(true);\n handleSelected();\n\n e.preventDefault();\n e.stopPropagation();\n\n refObject.current?.focus();\n };\n\n const markerXPos = maxValue !== minValue ? (trackWidth / (maxValue - minValue)) * (valueState - minValue) : 0;\n\n const getAriaValueText = (): string | undefined => {\n const stepIndex = steps ? Math.round((valueState - minValue) / step) : null;\n\n if (steps && stepIndex !== null && stepIndex >= 0 && stepIndex < steps.length) {\n const step = steps[stepIndex];\n const emojiCode = step.emojiUniCode;\n const label = typeof step.label !== 'undefined' ? step.label.toString() : undefined;\n\n return emojiCode && label ? `${emojiCode} ${label}` : emojiCode || label;\n }\n\n return undefined;\n };\n\n const getAriaLabeledById = (): string | undefined => {\n if (title && labelLeft && labelRight) {\n return [titleId, labelLeftId, labelRightId].join(' ');\n }\n if (title && labelLeft) {\n return [titleId, labelLeftId].join(' ');\n }\n if (title && labelRight) {\n return [titleId, labelRightId].join(' ');\n }\n if (title) {\n return titleId;\n }\n };\n\n const ariaLabelAttributes = getAriaLabelAttributes({\n label: ariaLabel,\n id: getAriaLabeledById(),\n prefer: 'label',\n });\n\n const getXPositionStyling = (index: number, stepsLength: number): { left: string } => {\n return { left: `${(index / (stepsLength - 1)) * 100}%` };\n };\n\n useEffect(() => {\n if (selectedState && onChange) {\n onChange({\n target: {\n name: props.name,\n value: valueState,\n },\n } as unknown as React.ChangeEvent<HTMLInputElement>);\n }\n }, [valueState, selectedState]);\n\n const renderEmojies = (): React.ReactNode => {\n return (\n <div className={styles['slider__emoji-container']}>\n {steps?.map((step, index) => {\n return (\n step.emojiUniCode && (\n <div\n aria-hidden={true}\n key={'emoji' + index}\n className={styles['slider__emoji']}\n style={getXPositionStyling(index, steps.length)}\n >\n {step.emojiUniCode}\n </div>\n )\n );\n })}\n </div>\n );\n };\n\n const renderSteps = (): React.ReactNode => {\n return steps?.map((_step, index) => {\n return <div key={'step' + index} className={styles['slider__track__step']} style={getXPositionStyling(index, steps.length)} />;\n });\n };\n\n const renderStepLabels = (): React.ReactNode => {\n return (\n <div className={styles['slider__value-container']}>\n {steps?.map((step, index) => {\n return (\n typeof step.label !== 'undefined' && (\n <div\n aria-hidden={true}\n key={'label' + index}\n className={styles['slider__value']}\n style={getXPositionStyling(index, steps.length)}\n >\n {step.label}\n </div>\n )\n );\n })}\n </div>\n );\n };\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <input\n aria-valuetext={getAriaValueText()}\n className={styles['sr-only-slider']}\n disabled={disabled}\n min={minValue}\n max={maxValue}\n onChange={onChange}\n onKeyDown={handleKeyDown}\n value={valueState}\n ref={mergedRefs}\n type=\"range\"\n {...rest}\n {...ariaLabelAttributes}\n />\n <div className={styles.slider} data-testid={testId} data-analyticsid={AnalyticsId.Slider}>\n {title && (\n <Title className={styles['slider__title']} htmlMarkup={'h3'} margin={0} appearance={'title3'} id={titleId}>\n {title}\n </Title>\n )}\n <div className={styles['slider__content-container']}>\n {renderEmojies()}\n {/* Slider streken er klikkbar med mus/touch */}\n <div\n ref={trackRef}\n className={classNames(styles['slider__track-wrapper'], disabled && styles['slider__track-wrapper--disabled'])}\n onPointerDown={handlePointerDown}\n >\n <div className={classNames(styles.slider__track, disabled && styles['slider__track--disabled'])}>{renderSteps()}</div>\n <div\n className={classNames(styles.slider__marker, {\n [styles['slider__marker--disabled']]: disabled,\n [styles['slider__marker--selected']]: selectedState,\n [styles['slider__marker--invalid']]: invalid,\n [styles['slider__marker--focused']]: !disabled && isFocused,\n })}\n style={{\n left: `${markerXPos}px`,\n }}\n />\n </div>\n {renderStepLabels()}\n </div>\n {(labelLeft || labelRight) && (\n <span className={styles.slider__options}>\n <span id={labelLeftId}>{labelLeft}</span>\n <span id={labelRightId}>{labelRight}</span>\n </span>\n )}\n </div>\n </ErrorWrapper>\n );\n});\n\nSlider.displayName = 'Slider';\n\nexport default Slider;\n","import Slider from './Slider';\nexport * from './Slider';\nexport default Slider;\n"],"mappings":"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"}
|
package/lib/Textarea.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { t as uuid } from "./uuid.js";
|
|
2
|
-
import { n as AnalyticsId, r as FormOnColor, t as AVERAGE_CHARACTER_WIDTH_PX } from "./constants2.js";
|
|
2
|
+
import { n as AnalyticsId, r as FormOnColor, s as LanguageLocales, t as AVERAGE_CHARACTER_WIDTH_PX } from "./constants2.js";
|
|
3
|
+
import { r as useLanguage } from "./language.js";
|
|
3
4
|
import { t as useIdWithFallback } from "./useIdWithFallback.js";
|
|
4
5
|
import { t as getAriaDescribedBy } from "./accessibility.js";
|
|
5
6
|
import { t as ErrorWrapper_default } from "./ErrorWrapper.js";
|
|
@@ -9,15 +10,33 @@ import React, { useEffect, useRef, useState } from "react";
|
|
|
9
10
|
import classNames from "classnames";
|
|
10
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
12
|
import styles from "./components/Textarea/styles.module.scss";
|
|
12
|
-
var
|
|
13
|
-
|
|
13
|
+
var HN_Designsystem_TextArea_en_GB_default = { characters: "characters" };
|
|
14
|
+
var HN_Designsystem_TextArea_nb_NO_default = { characters: "tegn" };
|
|
15
|
+
var HN_Designsystem_TextArea_nn_NO_default = { characters: "teikn" };
|
|
16
|
+
const getResources = (language) => {
|
|
17
|
+
switch (language) {
|
|
18
|
+
case LanguageLocales.ENGLISH: return HN_Designsystem_TextArea_en_GB_default;
|
|
19
|
+
case LanguageLocales.NORWEGIAN_NYNORSK: return HN_Designsystem_TextArea_nn_NO_default;
|
|
20
|
+
case LanguageLocales.NORWEGIAN:
|
|
21
|
+
default: return HN_Designsystem_TextArea_nb_NO_default;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var getTextareaMaxWidth = (characters$3) => {
|
|
25
|
+
return `calc(${characters$3 * 12}px + 2rem + 16px + 4px)`;
|
|
14
26
|
};
|
|
15
27
|
var Textarea = React.forwardRef((props, ref) => {
|
|
16
|
-
const { maxCharacters, maxText, width, testId, defaultValue, marginBottom: gutterBottom, transparent, onColor = FormOnColor.onwhite, label, textareaId = uuid(), minRows = 3, maxRows = 10, grow, error, errorText, errorTextId: errorTextIdProp, errorWrapperClassName, autoFocus, disabled, name, autoComplete = "off", placeholder, readOnly, required, onChange, value, ...rest } = props;
|
|
28
|
+
const { maxCharacters, maxText, width, testId, defaultValue, marginBottom: gutterBottom, transparent, onColor = FormOnColor.onwhite, label, textareaId = uuid(), minRows = 3, maxRows = 10, grow, error, errorText, errorTextId: errorTextIdProp, errorWrapperClassName, autoFocus, disabled, name, autoComplete = "off", placeholder, readOnly, required, onChange, value, resources, ...rest } = props;
|
|
17
29
|
const [rows, setRows] = useState(minRows);
|
|
18
30
|
const [textareaInput, setTextareaInput] = useState(value || defaultValue || "");
|
|
19
31
|
const referanse = useRef(null);
|
|
20
32
|
const errorTextUuid = useIdWithFallback(errorTextIdProp);
|
|
33
|
+
const { language } = useLanguage(LanguageLocales.NORWEGIAN);
|
|
34
|
+
const defaultResources = getResources(language);
|
|
35
|
+
const mergedResources = {
|
|
36
|
+
...defaultResources,
|
|
37
|
+
...resources,
|
|
38
|
+
characters: maxText || resources?.characters || defaultResources.characters
|
|
39
|
+
};
|
|
21
40
|
useEffect(() => {
|
|
22
41
|
setTextareaInput(defaultValue || "");
|
|
23
42
|
}, [defaultValue]);
|
|
@@ -97,7 +116,7 @@ var Textarea = React.forwardRef((props, ref) => {
|
|
|
97
116
|
maxCharacters && /* @__PURE__ */ jsx(MaxCharacters_default, {
|
|
98
117
|
maxCharacters,
|
|
99
118
|
length: textareaInput.toString().length,
|
|
100
|
-
maxText,
|
|
119
|
+
maxText: mergedResources.characters,
|
|
101
120
|
onColor,
|
|
102
121
|
maxWidth
|
|
103
122
|
})
|
package/lib/Textarea.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.js","names":[],"sources":["../src/components/Textarea/Textarea.tsx","../src/components/Textarea/index.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\n\nimport cn from 'classnames';\n\nimport { AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX, FormOnColor } from '../../constants';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { uuid } from '../../utils/uuid';\nimport ErrorWrapper, { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport { renderLabel } from '../Label';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\nexport interface TextareaProps\n extends ErrorWrapperClassNameProps,\n 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 onColor?: keyof typeof FormOnColor;\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 onColor = FormOnColor.onwhite,\n label,\n textareaId = uuid(),\n minRows = 3,\n maxRows = 10,\n grow,\n error,\n errorText,\n errorTextId: errorTextIdProp,\n errorWrapperClassName,\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 = useIdWithFallback(errorTextIdProp);\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 = onColor === FormOnColor.ondark;\n const onBlueberry = onColor === FormOnColor.onblueberry;\n const maxCharactersExceeded = !!maxCharacters && textareaInput.toString().length > maxCharacters;\n const onError = onColor === FormOnColor.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 (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 onChangeHandler = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {\n setTextareaInput(e.target.value);\n\n if (onChange) {\n onChange(e);\n }\n\n if (grow) {\n resizeHeight(e.target);\n }\n };\n\n const maxWidth = width ? getTextareaMaxWidth(width) : undefined;\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextUuid}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Textarea} className={textareaWrapperClass}>\n {renderLabel(label, textareaId, onColor as FormOnColor)}\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={value}\n />\n </div>\n {maxCharacters && (\n <MaxCharacters\n maxCharacters={maxCharacters}\n length={textareaInput.toString().length}\n maxText={maxText}\n onColor={onColor}\n maxWidth={maxWidth}\n />\n )}\n </div>\n </ErrorWrapper>\n );\n});\n\nTextarea.displayName = 'Textarea';\n\nexport default Textarea;\n","import Textarea from './Textarea';\nexport * from './Textarea';\nexport default Textarea;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Textarea.js","names":["mergedResources: HNDesignsystemTextArea"],"sources":["../src/resources/HN.Designsystem.TextArea.en-GB.json","../src/resources/HN.Designsystem.TextArea.nb-NO.json","../src/resources/HN.Designsystem.TextArea.nn-NO.json","../src/components/Textarea/resourceHelper.ts","../src/components/Textarea/Textarea.tsx","../src/components/Textarea/index.tsx"],"sourcesContent":["{\n \"characters\": \"characters\"\n}\n","{\n \"characters\": \"tegn\"\n}\n","{\n \"characters\": \"teikn\"\n}\n","import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.TextArea.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.TextArea.nb-NO.json';\nimport nnNO from '../../resources/HN.Designsystem.TextArea.nn-NO.json';\nimport { HNDesignsystemTextArea } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemTextArea => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN_NYNORSK:\n return nnNO;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React, { useState, useRef, useEffect } from 'react';\n\nimport cn from 'classnames';\n\nimport { getResources } from './resourceHelper';\nimport { AnalyticsId, AVERAGE_CHARACTER_WIDTH_PX, FormOnColor, LanguageLocales } from '../../constants';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { HNDesignsystemTextArea } from '../../resources/Resources';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { useLanguage } from '../../utils/language';\nimport { uuid } from '../../utils/uuid';\nimport ErrorWrapper, { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport { renderLabel } from '../Label';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\nexport interface TextareaProps\n extends ErrorWrapperClassNameProps,\n 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 /** @deprecated use resources instead. 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 onColor?: keyof typeof FormOnColor;\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 /** Resources for component */\n resources?: Partial<HNDesignsystemTextArea>;\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 onColor = FormOnColor.onwhite,\n label,\n textareaId = uuid(),\n minRows = 3,\n maxRows = 10,\n grow,\n error,\n errorText,\n errorTextId: errorTextIdProp,\n errorWrapperClassName,\n autoFocus,\n disabled,\n name,\n autoComplete = 'off',\n placeholder,\n readOnly,\n required,\n onChange,\n value,\n resources,\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 = useIdWithFallback(errorTextIdProp);\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemTextArea = {\n ...defaultResources,\n ...resources,\n characters: maxText || resources?.characters || defaultResources.characters,\n };\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 = onColor === FormOnColor.ondark;\n const onBlueberry = onColor === FormOnColor.onblueberry;\n const maxCharactersExceeded = !!maxCharacters && textareaInput.toString().length > maxCharacters;\n const onError = onColor === FormOnColor.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 (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 onChangeHandler = (e: React.ChangeEvent<HTMLTextAreaElement>): void => {\n setTextareaInput(e.target.value);\n\n if (onChange) {\n onChange(e);\n }\n\n if (grow) {\n resizeHeight(e.target);\n }\n };\n\n const maxWidth = width ? getTextareaMaxWidth(width) : undefined;\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextUuid}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Textarea} className={textareaWrapperClass}>\n {renderLabel(label, textareaId, onColor as FormOnColor)}\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={value}\n />\n </div>\n {maxCharacters && (\n <MaxCharacters\n maxCharacters={maxCharacters}\n length={textareaInput.toString().length}\n maxText={mergedResources.characters}\n onColor={onColor}\n maxWidth={maxWidth}\n />\n )}\n </div>\n </ErrorWrapper>\n );\n});\n\nTextarea.displayName = 'Textarea';\n\nexport default Textarea;\n","import Textarea from './Textarea';\nexport * from './Textarea';\nexport default Textarea;\n"],"mappings":"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"}
|
|
@@ -81,6 +81,7 @@ const DropdownBase = (props) => {
|
|
|
81
81
|
const triggerMinWidthLimit = isMobile ? 96 : 112;
|
|
82
82
|
const dropdownFloatingPadding = 15;
|
|
83
83
|
const maxWidth = isMobile ? 384 : 400;
|
|
84
|
+
const maxHeight = isMobile ? 384 : 464;
|
|
84
85
|
const toggleTextId = useId();
|
|
85
86
|
const optionIdPrefix = useId();
|
|
86
87
|
const contentId = useId();
|
|
@@ -123,7 +124,7 @@ const DropdownBase = (props) => {
|
|
|
123
124
|
const targetW = Math.max(triggerW, minProp);
|
|
124
125
|
Object.assign(elements.floating.style, {
|
|
125
126
|
maxWidth: `${Math.min(targetW, availableWidth)}px`,
|
|
126
|
-
maxHeight: `${availableHeight}px`,
|
|
127
|
+
maxHeight: `${Math.min(maxHeight, availableHeight)}px`,
|
|
127
128
|
overflowY: "auto",
|
|
128
129
|
overflowX: "hidden"
|
|
129
130
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["DropdownBase: React.FC<DropdownProps>","mergedResources: HNDesignsystemDropdown","baseProps: { ref: React.Ref<HTMLElement> }"],"sources":["../../../src/components/Dropdown/resourceHelper.ts","../../../src/components/Dropdown/Dropdown.tsx","../../../src/components/Dropdown/index.ts"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemDropdown => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React, { useEffect, useRef, useId, ComponentType } from 'react';\n\nimport { autoUpdate, offset, shift, size, useFloating, flip } from '@floating-ui/react';\nimport classNames from 'classnames';\nimport { clamp } from 'motion/react';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n LanguageLocales,\n ZIndex,\n usePseudoClasses,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n} from '../..';\nimport { getResources } from './resourceHelper';\nimport { SingleSelectItem, SingleSelectItemProps } from './SingleSelect/SingleSelectItem';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\nimport { isComponent } from '../../utils/component';\nimport { useLanguage } from '../../utils/language';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Checkbox, { CheckboxProps } from '../Checkbox';\nimport Icon, { SvgIcon } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport { IconName } from '../Icons/IconNames';\nimport PlusSmall from '../Icons/PlusSmall';\nimport Label, { LabelProps } from '../Label';\nimport LazyIcon from '../LazyIcon';\nimport { SingleSelect } from './SingleSelect/SingleSelect';\n\nimport styles from './styles.module.scss';\n\ntype DropdownVariants = 'fill' | 'transparent' | 'borderless';\n\nexport interface DropdownProps {\n /** Text on the trigger button that opens the dropdown */\n triggerText: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Minimum width for the dropdown in pixels. Does not affect trigger button. */\n dropdownMinWidth?: number;\n /** Minimum width for the trigger in pixels. Does not apply for borderless variant */\n triggerMinWidth?: number;\n /** Disables rendring of the close button in the list */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed */\n onToggle?: (isOpen: boolean) => void;\n /** Whether the dropdown is open or not */\n open?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button */\n testId?: string;\n /** Overrides the default z-index of the DropDownContent */\n zIndex?: number;\n /** Resources for component */\n resources?: Partial<HNDesignsystemDropdown>;\n /** Adds an icon to the trigger */\n svgIcon?: SvgIcon | IconName;\n /** Sets the visual variant of the Dropdown */\n variant?: DropdownVariants;\n}\n\nexport const DropdownBase: React.FC<DropdownProps> = props => {\n const {\n triggerText,\n noCloseButton = false,\n onToggle,\n dropdownMinWidth,\n triggerMinWidth,\n open = false,\n children,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n resources,\n svgIcon,\n variant = 'fill',\n } = props;\n\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const childrenRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const { isHovered } = usePseudoClasses<HTMLButtonElement>(buttonRef);\n const openedByKeyboard = useRef<boolean>(false);\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const isMobile = useIsMobileBreakpoint();\n const triggerActualMinWidth = variant !== 'borderless' && typeof triggerMinWidth != 'undefined' ? `${triggerMinWidth}px` : 'auto';\n const triggerMinWidthLimit = isMobile ? 96 : 112;\n const dropdownFloatingPadding = 15;\n const maxWidth = isMobile ? 384 : 400;\n const toggleTextId = useId();\n const optionIdPrefix = useId();\n const contentId = useId();\n const leftIconProps = {\n className: styles['dropdown__left-icon'],\n size: IconSize.XSmall,\n isHovered: !disabled && isHovered,\n };\n\n const isSingleSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<SingleSelectItemProps>(child, SingleSelectItem)\n );\n const isMultiSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<CheckboxProps>(child, Checkbox)\n );\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n const mergedResources: HNDesignsystemDropdown = {\n ...defaultResources,\n ...resources,\n };\n\n const toggleClasses = classNames(styles.dropdown__toggle, {\n [styles['dropdown__toggle--open']]: isOpen && !disabled,\n [styles['dropdown__toggle--with-icon']]: typeof svgIcon !== 'undefined',\n [styles['dropdown__toggle--transparent']]: variant === 'transparent',\n [styles['dropdown__toggle--borderless']]: variant === 'borderless',\n });\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n const listItemClasses = classNames(styles['dropdown__list-item'], { [styles['dropdown__list-item--single-select']]: isSingleSelect });\n\n const { refs, floatingStyles } = useFloating({\n strategy: 'fixed',\n placement: 'bottom-start',\n middleware: [\n offset(8),\n // Hvis det ikke er plass på høyre side flipper vi dropdownlisten fra bottom-start til bottom-end\n flip({ mainAxis: false, fallbackPlacements: ['bottom-end'], padding: dropdownFloatingPadding }),\n // Shift fungerer som en fallback for flip og unngår at availableWidth ikke oppdaterer seg ved skjermbreddeendring\n shift({ padding: dropdownFloatingPadding }),\n // Hvis det ikke er plass på noen av sidene krymper vi bredden på listen med size\n size({\n padding: dropdownFloatingPadding,\n apply({ availableWidth, availableHeight, elements, rects }) {\n const triggerW = rects.reference.width;\n const minProp = typeof dropdownMinWidth !== 'undefined' ? clamp(0, maxWidth, dropdownMinWidth) : 0;\n const targetW = Math.max(triggerW, minProp);\n\n Object.assign(elements.floating.style, {\n maxWidth: `${Math.min(targetW, availableWidth)}px`,\n maxHeight: `${availableHeight}px`,\n overflowY: 'auto',\n overflowX: 'hidden',\n });\n },\n }),\n ],\n whileElementsMounted: isOpen ? autoUpdate : undefined,\n });\n\n const handleOpen = (isKeyboard: boolean): void => {\n openedByKeyboard.current = isKeyboard;\n toggleIsOpen();\n };\n\n const handleClose = (): void => {\n if (!isOpen) return;\n\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n useEffect(() => {\n if (isOpen && openedByKeyboard.current) {\n const firstEnabled = childrenRefList.current?.find(r => r.current && !r.current.hasAttribute('disabled'));\n firstEnabled?.current?.focus();\n openedByKeyboard.current = false;\n }\n }, [isOpen]);\n\n const focusByIndex = (nextIndex: number): void => {\n childrenRefList.current?.[nextIndex]?.current?.focus();\n };\n\n const isListNavKey = (key: string): boolean =>\n key === KeyboardEventKey.ArrowDown || key === KeyboardEventKey.ArrowUp || key === KeyboardEventKey.Home || key === KeyboardEventKey.End;\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n if (!childrenRefList.current) return;\n\n const key = event.key as KeyboardEventKey;\n\n if (key === KeyboardEventKey.Escape) {\n if (isOpen) {\n event.preventDefault();\n handleClose();\n }\n return;\n }\n\n if (!isOpen) {\n if (isListNavKey(key)) {\n event.preventDefault();\n handleOpen(true);\n }\n return;\n }\n\n if (!isListNavKey(key)) {\n return;\n }\n\n const index = childrenRefList.current.findIndex(x => x.current === (event.target as HTMLElement));\n let nextIndex = index;\n\n if (key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (key === KeyboardEventKey.End) {\n nextIndex = childrenRefList.current.length - 1;\n } else if (key === KeyboardEventKey.ArrowDown && index < childrenRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n }\n\n if (nextIndex !== -1) {\n event.preventDefault();\n focusByIndex(nextIndex);\n }\n };\n\n useKeyboardEvent(dropdownRef, handleKeyboardNavigation, [\n KeyboardEventKey.ArrowDown,\n KeyboardEventKey.ArrowUp,\n KeyboardEventKey.End,\n KeyboardEventKey.Enter,\n KeyboardEventKey.Escape,\n KeyboardEventKey.Home,\n KeyboardEventKey.Space,\n ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const renderChildren = React.Children.map(children, (child, index) => {\n return (\n <li className={listItemClasses} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(child) && childrenRefList.current && childrenRefList.current[index]\n ? ((): React.ReactElement => {\n const baseProps: { ref: React.Ref<HTMLElement> } = {\n ref: mergeRefs([child.props.ref, childrenRefList.current[index]]),\n };\n\n if (isMultiSelect) {\n const label = (child.props as CheckboxProps).label as React.ReactNode;\n if (React.isValidElement(label) && isComponent<LabelProps>(label, Label)) {\n return React.cloneElement(child as React.ReactElement<CheckboxProps>, {\n ...baseProps,\n label: React.cloneElement(label, {\n labelClassName: classNames((label.props as LabelProps)?.labelClassName, styles['dropdown__multiselect-item']),\n }),\n });\n }\n }\n\n return React.cloneElement(child as React.ReactElement<Record<string, unknown>>, baseProps);\n })()\n : child}\n </li>\n );\n });\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <button\n type=\"button\"\n onClick={(): false | void => handleOpen(false)}\n className={toggleClasses}\n ref={mergeRefs([buttonRef, refs.setReference])}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleTextId}\n aria-haspopup={true}\n aria-controls={contentId}\n aria-expanded={isOpen}\n style={{\n width: triggerActualMinWidth,\n maxWidth: '100%',\n minWidth: `${triggerMinWidthLimit}px`,\n }}\n >\n {svgIcon && (\n <>\n {typeof svgIcon === 'string' ? (\n <LazyIcon {...leftIconProps} iconName={svgIcon} />\n ) : (\n <Icon {...leftIconProps} svgIcon={svgIcon} />\n )}\n </>\n )}\n <span id={toggleTextId} className={styles.dropdown__toggle__text}>\n {triggerText}\n </span>\n <Icon\n svgIcon={!isSingleSelect ? PlusSmall : isOpen ? ChevronUp : ChevronDown}\n className={styles['dropdown__right-icon']}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div\n key={dropdownMinWidth ?? 'auto'}\n id={contentId}\n className={contentClasses}\n ref={refs.setFloating}\n style={{\n ...floatingStyles,\n zIndex: zIndex,\n }}\n >\n <ul className={styles.dropdown__options} role=\"group\" aria-labelledby={toggleTextId} tabIndex={-1} ref={optionsRef}>\n {isSingleSelect && <SingleSelect onValueChange={() => handleClose()}>{renderChildren}</SingleSelect>}\n {isMultiSelect && renderChildren}\n </ul>\n {!isSingleSelect && !noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose}>{mergedResources.closeText}</Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport interface DropdownCompound extends React.FC<DropdownProps> {\n SingleSelectItem: ComponentType<SingleSelectItemProps>;\n}\nconst Dropdown = DropdownBase as DropdownCompound;\nDropdown.SingleSelectItem = SingleSelectItem;\nDropdownBase.displayName = 'Dropdown';\n\nexport default Dropdown;\n","import Dropdown from './Dropdown';\nexport * from './Dropdown';\nexport default Dropdown;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["DropdownBase: React.FC<DropdownProps>","mergedResources: HNDesignsystemDropdown","baseProps: { ref: React.Ref<HTMLElement> }"],"sources":["../../../src/components/Dropdown/resourceHelper.ts","../../../src/components/Dropdown/Dropdown.tsx","../../../src/components/Dropdown/index.ts"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemDropdown => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React, { useEffect, useRef, useId, ComponentType } from 'react';\n\nimport { autoUpdate, offset, shift, size, useFloating, flip } from '@floating-ui/react';\nimport classNames from 'classnames';\nimport { clamp } from 'motion/react';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n LanguageLocales,\n ZIndex,\n usePseudoClasses,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n} from '../..';\nimport { getResources } from './resourceHelper';\nimport { SingleSelectItem, SingleSelectItemProps } from './SingleSelect/SingleSelectItem';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\nimport { isComponent } from '../../utils/component';\nimport { useLanguage } from '../../utils/language';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Checkbox, { CheckboxProps } from '../Checkbox';\nimport Icon, { SvgIcon } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport { IconName } from '../Icons/IconNames';\nimport PlusSmall from '../Icons/PlusSmall';\nimport Label, { LabelProps } from '../Label';\nimport LazyIcon from '../LazyIcon';\nimport { SingleSelect } from './SingleSelect/SingleSelect';\n\nimport styles from './styles.module.scss';\n\ntype DropdownVariants = 'fill' | 'transparent' | 'borderless';\n\nexport interface DropdownProps {\n /** Text on the trigger button that opens the dropdown */\n triggerText: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Minimum width for the dropdown in pixels. Does not affect trigger button. */\n dropdownMinWidth?: number;\n /** Minimum width for the trigger in pixels. Does not apply for borderless variant */\n triggerMinWidth?: number;\n /** Disables rendring of the close button in the list */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed */\n onToggle?: (isOpen: boolean) => void;\n /** Whether the dropdown is open or not */\n open?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button */\n testId?: string;\n /** Overrides the default z-index of the DropDownContent */\n zIndex?: number;\n /** Resources for component */\n resources?: Partial<HNDesignsystemDropdown>;\n /** Adds an icon to the trigger */\n svgIcon?: SvgIcon | IconName;\n /** Sets the visual variant of the Dropdown */\n variant?: DropdownVariants;\n}\n\nexport const DropdownBase: React.FC<DropdownProps> = props => {\n const {\n triggerText,\n noCloseButton = false,\n onToggle,\n dropdownMinWidth,\n triggerMinWidth,\n open = false,\n children,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n resources,\n svgIcon,\n variant = 'fill',\n } = props;\n\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const childrenRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const { isHovered } = usePseudoClasses<HTMLButtonElement>(buttonRef);\n const openedByKeyboard = useRef<boolean>(false);\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const isMobile = useIsMobileBreakpoint();\n const triggerActualMinWidth = variant !== 'borderless' && typeof triggerMinWidth != 'undefined' ? `${triggerMinWidth}px` : 'auto';\n const triggerMinWidthLimit = isMobile ? 96 : 112;\n const dropdownFloatingPadding = 15;\n const maxWidth = isMobile ? 384 : 400;\n const maxHeight = isMobile ? 384 : 464;\n const toggleTextId = useId();\n const optionIdPrefix = useId();\n const contentId = useId();\n const leftIconProps = {\n className: styles['dropdown__left-icon'],\n size: IconSize.XSmall,\n isHovered: !disabled && isHovered,\n };\n\n const isSingleSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<SingleSelectItemProps>(child, SingleSelectItem)\n );\n const isMultiSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<CheckboxProps>(child, Checkbox)\n );\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n const mergedResources: HNDesignsystemDropdown = {\n ...defaultResources,\n ...resources,\n };\n\n const toggleClasses = classNames(styles.dropdown__toggle, {\n [styles['dropdown__toggle--open']]: isOpen && !disabled,\n [styles['dropdown__toggle--with-icon']]: typeof svgIcon !== 'undefined',\n [styles['dropdown__toggle--transparent']]: variant === 'transparent',\n [styles['dropdown__toggle--borderless']]: variant === 'borderless',\n });\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n const listItemClasses = classNames(styles['dropdown__list-item'], { [styles['dropdown__list-item--single-select']]: isSingleSelect });\n\n const { refs, floatingStyles } = useFloating({\n strategy: 'fixed',\n placement: 'bottom-start',\n middleware: [\n offset(8),\n // Hvis det ikke er plass på høyre side flipper vi dropdownlisten fra bottom-start til bottom-end\n flip({ mainAxis: false, fallbackPlacements: ['bottom-end'], padding: dropdownFloatingPadding }),\n // Shift fungerer som en fallback for flip og unngår at availableWidth ikke oppdaterer seg ved skjermbreddeendring\n shift({ padding: dropdownFloatingPadding }),\n // Hvis det ikke er plass på noen av sidene krymper vi bredden på listen med size\n size({\n padding: dropdownFloatingPadding,\n apply({ availableWidth, availableHeight, elements, rects }) {\n const triggerW = rects.reference.width;\n const minProp = typeof dropdownMinWidth !== 'undefined' ? clamp(0, maxWidth, dropdownMinWidth) : 0;\n const targetW = Math.max(triggerW, minProp);\n\n Object.assign(elements.floating.style, {\n maxWidth: `${Math.min(targetW, availableWidth)}px`,\n maxHeight: `${Math.min(maxHeight, availableHeight)}px`,\n overflowY: 'auto',\n overflowX: 'hidden',\n });\n },\n }),\n ],\n whileElementsMounted: isOpen ? autoUpdate : undefined,\n });\n\n const handleOpen = (isKeyboard: boolean): void => {\n openedByKeyboard.current = isKeyboard;\n toggleIsOpen();\n };\n\n const handleClose = (): void => {\n if (!isOpen) return;\n\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n useEffect(() => {\n if (isOpen && openedByKeyboard.current) {\n const firstEnabled = childrenRefList.current?.find(r => r.current && !r.current.hasAttribute('disabled'));\n firstEnabled?.current?.focus();\n openedByKeyboard.current = false;\n }\n }, [isOpen]);\n\n const focusByIndex = (nextIndex: number): void => {\n childrenRefList.current?.[nextIndex]?.current?.focus();\n };\n\n const isListNavKey = (key: string): boolean =>\n key === KeyboardEventKey.ArrowDown || key === KeyboardEventKey.ArrowUp || key === KeyboardEventKey.Home || key === KeyboardEventKey.End;\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n if (!childrenRefList.current) return;\n\n const key = event.key as KeyboardEventKey;\n\n if (key === KeyboardEventKey.Escape) {\n if (isOpen) {\n event.preventDefault();\n handleClose();\n }\n return;\n }\n\n if (!isOpen) {\n if (isListNavKey(key)) {\n event.preventDefault();\n handleOpen(true);\n }\n return;\n }\n\n if (!isListNavKey(key)) {\n return;\n }\n\n const index = childrenRefList.current.findIndex(x => x.current === (event.target as HTMLElement));\n let nextIndex = index;\n\n if (key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (key === KeyboardEventKey.End) {\n nextIndex = childrenRefList.current.length - 1;\n } else if (key === KeyboardEventKey.ArrowDown && index < childrenRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n }\n\n if (nextIndex !== -1) {\n event.preventDefault();\n focusByIndex(nextIndex);\n }\n };\n\n useKeyboardEvent(dropdownRef, handleKeyboardNavigation, [\n KeyboardEventKey.ArrowDown,\n KeyboardEventKey.ArrowUp,\n KeyboardEventKey.End,\n KeyboardEventKey.Enter,\n KeyboardEventKey.Escape,\n KeyboardEventKey.Home,\n KeyboardEventKey.Space,\n ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const renderChildren = React.Children.map(children, (child, index) => {\n return (\n <li className={listItemClasses} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(child) && childrenRefList.current && childrenRefList.current[index]\n ? ((): React.ReactElement => {\n const baseProps: { ref: React.Ref<HTMLElement> } = {\n ref: mergeRefs([child.props.ref, childrenRefList.current[index]]),\n };\n\n if (isMultiSelect) {\n const label = (child.props as CheckboxProps).label as React.ReactNode;\n if (React.isValidElement(label) && isComponent<LabelProps>(label, Label)) {\n return React.cloneElement(child as React.ReactElement<CheckboxProps>, {\n ...baseProps,\n label: React.cloneElement(label, {\n labelClassName: classNames((label.props as LabelProps)?.labelClassName, styles['dropdown__multiselect-item']),\n }),\n });\n }\n }\n\n return React.cloneElement(child as React.ReactElement<Record<string, unknown>>, baseProps);\n })()\n : child}\n </li>\n );\n });\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <button\n type=\"button\"\n onClick={(): false | void => handleOpen(false)}\n className={toggleClasses}\n ref={mergeRefs([buttonRef, refs.setReference])}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleTextId}\n aria-haspopup={true}\n aria-controls={contentId}\n aria-expanded={isOpen}\n style={{\n width: triggerActualMinWidth,\n maxWidth: '100%',\n minWidth: `${triggerMinWidthLimit}px`,\n }}\n >\n {svgIcon && (\n <>\n {typeof svgIcon === 'string' ? (\n <LazyIcon {...leftIconProps} iconName={svgIcon} />\n ) : (\n <Icon {...leftIconProps} svgIcon={svgIcon} />\n )}\n </>\n )}\n <span id={toggleTextId} className={styles.dropdown__toggle__text}>\n {triggerText}\n </span>\n <Icon\n svgIcon={!isSingleSelect ? PlusSmall : isOpen ? ChevronUp : ChevronDown}\n className={styles['dropdown__right-icon']}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div\n key={dropdownMinWidth ?? 'auto'}\n id={contentId}\n className={contentClasses}\n ref={refs.setFloating}\n style={{\n ...floatingStyles,\n zIndex: zIndex,\n }}\n >\n <ul className={styles.dropdown__options} role=\"group\" aria-labelledby={toggleTextId} tabIndex={-1} ref={optionsRef}>\n {isSingleSelect && <SingleSelect onValueChange={() => handleClose()}>{renderChildren}</SingleSelect>}\n {isMultiSelect && renderChildren}\n </ul>\n {!isSingleSelect && !noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose}>{mergedResources.closeText}</Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport interface DropdownCompound extends React.FC<DropdownProps> {\n SingleSelectItem: ComponentType<SingleSelectItemProps>;\n}\nconst Dropdown = DropdownBase as DropdownCompound;\nDropdown.SingleSelectItem = SingleSelectItem;\nDropdownBase.displayName = 'Dropdown';\n\nexport default Dropdown;\n","import Dropdown from './Dropdown';\nexport * from './Dropdown';\nexport default Dropdown;\n"],"mappings":"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"}
|
|
@@ -128,15 +128,9 @@
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
&__options {
|
|
131
|
-
overflow: hidden auto;
|
|
132
|
-
max-height: 384px;
|
|
133
131
|
list-style: none;
|
|
134
132
|
padding: 0;
|
|
135
133
|
margin: 0;
|
|
136
|
-
|
|
137
|
-
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
138
|
-
max-height: 464px;
|
|
139
|
-
}
|
|
140
134
|
}
|
|
141
135
|
|
|
142
136
|
&__close {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ElementHeader/ElementHeaderText/index.ts"],"sourcesContent":["import ElementHeaderText from './ElementHeaderText';\nexport * from './ElementHeaderText';\nexport default ElementHeaderText;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ElementHeader/ElementHeaderText/index.ts"],"sourcesContent":["import ElementHeaderText from './ElementHeaderText';\nexport * from './ElementHeaderText';\nexport default ElementHeaderText;\n"],"mappings":";;;;;;;;;;AAEA,IAAA,4BAAe"}
|
|
@@ -47,8 +47,8 @@ import "../../Title.js";
|
|
|
47
47
|
import "../../Title2.js";
|
|
48
48
|
import "../../ChevronDown.js";
|
|
49
49
|
import "../../FormLayout.js";
|
|
50
|
-
import "../../MaxCharacters.js";
|
|
51
50
|
import "../../Input.js";
|
|
51
|
+
import "../../MaxCharacters.js";
|
|
52
52
|
import "../../RadioButton.js";
|
|
53
53
|
import "../../Select.js";
|
|
54
54
|
import "../../Slider.js";
|
|
@@ -555,7 +555,7 @@ declare const _default: {
|
|
|
555
555
|
alternativeName: string;
|
|
556
556
|
categories: string;
|
|
557
557
|
};
|
|
558
|
-
|
|
558
|
+
patientandperson: {
|
|
559
559
|
alternativeName: string;
|
|
560
560
|
categories: string;
|
|
561
561
|
};
|
|
@@ -1315,7 +1315,7 @@ declare const _default: {
|
|
|
1315
1315
|
alternativeName: string;
|
|
1316
1316
|
categories: string;
|
|
1317
1317
|
};
|
|
1318
|
-
|
|
1318
|
+
personandpatient: {
|
|
1319
1319
|
alternativeName: string;
|
|
1320
1320
|
categories: string;
|
|
1321
1321
|
};
|
|
@@ -1339,5 +1339,13 @@ declare const _default: {
|
|
|
1339
1339
|
alternativeName: string;
|
|
1340
1340
|
categories: string;
|
|
1341
1341
|
};
|
|
1342
|
+
zoominleft: {
|
|
1343
|
+
alternativeName: string;
|
|
1344
|
+
categories: string;
|
|
1345
|
+
};
|
|
1346
|
+
zoomoutleft: {
|
|
1347
|
+
alternativeName: string;
|
|
1348
|
+
categories: string;
|
|
1349
|
+
};
|
|
1342
1350
|
};
|
|
1343
1351
|
export default _default;
|
|
@@ -555,7 +555,7 @@ var AdditionalIconInformation_default = {
|
|
|
555
555
|
alternativeName: "Person med brukket arm",
|
|
556
556
|
categories: "Behandling, Personer"
|
|
557
557
|
},
|
|
558
|
-
|
|
558
|
+
patientandperson: {
|
|
559
559
|
alternativeName: "Pasient og pårørende",
|
|
560
560
|
categories: "Behandling, Personer"
|
|
561
561
|
},
|
|
@@ -1315,7 +1315,7 @@ var AdditionalIconInformation_default = {
|
|
|
1315
1315
|
alternativeName: "IngenTilgang (mørk)",
|
|
1316
1316
|
categories: "System"
|
|
1317
1317
|
},
|
|
1318
|
-
|
|
1318
|
+
personandpatient: {
|
|
1319
1319
|
alternativeName: "PårørendeOgPasient",
|
|
1320
1320
|
categories: "Behandling, Personer"
|
|
1321
1321
|
},
|
|
@@ -1338,6 +1338,14 @@ var AdditionalIconInformation_default = {
|
|
|
1338
1338
|
feedback: {
|
|
1339
1339
|
alternativeName: "Tilbakemelding",
|
|
1340
1340
|
categories: "Generisk"
|
|
1341
|
+
},
|
|
1342
|
+
zoominleft: {
|
|
1343
|
+
alternativeName: "Zoom Inn Venstre",
|
|
1344
|
+
categories: "System, Generisk"
|
|
1345
|
+
},
|
|
1346
|
+
zoomoutleft: {
|
|
1347
|
+
alternativeName: "Zoom Ut Venstre",
|
|
1348
|
+
categories: "System, Generisk"
|
|
1341
1349
|
}
|
|
1342
1350
|
};
|
|
1343
1351
|
export { AdditionalIconInformation_default as default };
|