@helsenorge/designsystem-react 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/CHANGELOG.md +380 -668
  2. package/HelpBubble.js +1 -1
  3. package/HelpBubble.js.map +1 -1
  4. package/HorizontalScroll.js.map +1 -1
  5. package/Input.js +1 -1
  6. package/Input.js.map +1 -1
  7. package/ListHeader.js +1 -1
  8. package/ListHeader.js.map +1 -1
  9. package/Modal.js.map +1 -1
  10. package/PopOver.js +1 -1
  11. package/PopOver.js.map +1 -1
  12. package/RadioButton.js +1 -1
  13. package/RadioButton.js.map +1 -1
  14. package/Textarea.js +1 -1
  15. package/Textarea.js.map +1 -1
  16. package/Title.js.map +1 -1
  17. package/Tooltip.js.map +1 -1
  18. package/TooltipWord.js +1 -1
  19. package/TooltipWord.js.map +1 -1
  20. package/components/AnchorLink/styles.module.scss +11 -6
  21. package/components/Avatar/styles.module.scss +2 -2
  22. package/components/Badge/styles.module.scss +7 -1
  23. package/components/Button/styles.module.scss +35 -21
  24. package/components/Checkbox/styles.module.scss +12 -12
  25. package/components/Close/styles.module.scss +15 -7
  26. package/components/Dropdown/index.js +1 -1
  27. package/components/Dropdown/index.js.map +1 -1
  28. package/components/Dropdown/styles.module.scss +31 -10
  29. package/components/Duolist/styles.module.scss +5 -3
  30. package/components/ErrorWrapper/styles.module.scss +8 -6
  31. package/components/Expander/styles.module.scss +46 -15
  32. package/components/ExpanderHierarchy/expander.module.scss +13 -8
  33. package/components/ExpanderHierarchy/expander.module.scss.d.ts +1 -1
  34. package/components/ExpanderHierarchy/styles.module.scss +3 -3
  35. package/components/ExpanderList/index.js.map +1 -1
  36. package/components/ExpanderList/styles.module.scss +17 -6
  37. package/components/FormExample/FormExample.d.ts.map +1 -1
  38. package/components/FormExample/index.js.map +1 -1
  39. package/components/FormExample/styles.module.scss +6 -6
  40. package/components/FormGroup/styles.module.scss +5 -4
  41. package/components/FormLayout/styles.module.scss +5 -2
  42. package/components/HelpBubble/HelpBubble.d.ts +2 -2
  43. package/components/HelpBubble/HelpBubble.d.ts.map +1 -1
  44. package/components/HelpBubble/index.js +1 -1
  45. package/components/HelpBubble/styles.module.scss +10 -10
  46. package/components/HelpBubble/styles.module.scss.d.ts +0 -1
  47. package/components/HelpBubbleExample/index.js +1 -1
  48. package/components/HighlightBox/index.js.map +1 -1
  49. package/components/HighlightBox/styles.module.scss +38 -29
  50. package/components/HorizontalScroll/HorizontalScroll.d.ts.map +1 -1
  51. package/components/HorizontalScroll/styles.module.scss +10 -3
  52. package/components/Icons/SortUp.js +1 -1
  53. package/components/Icons/SortUp.js.map +1 -1
  54. package/components/Input/Input.d.ts.map +1 -1
  55. package/components/Input/styles.module.scss +8 -7
  56. package/components/LinkList/styles.module.scss +23 -5
  57. package/components/List/styles.module.scss +4 -0
  58. package/components/ListHeader/ListHeader.d.ts +9 -7
  59. package/components/ListHeader/ListHeader.d.ts.map +1 -1
  60. package/components/ListHeader/styles.module.scss +36 -11
  61. package/components/Loader/styles.module.scss +40 -18
  62. package/components/Logo/index.js.map +1 -1
  63. package/components/MaxCharacters/styles.module.scss +7 -5
  64. package/components/Modal/styles.module.scss +39 -23
  65. package/components/NotificationPanel/DetailButton/styles.module.scss +9 -5
  66. package/components/NotificationPanel/index.js.map +1 -1
  67. package/components/NotificationPanel/styles.module.scss +45 -12
  68. package/components/Panel/styles.module.scss +53 -29
  69. package/components/PanelList/styles.module.scss +6 -5
  70. package/components/PopMenu/PopMenu.d.ts.map +1 -1
  71. package/components/PopMenu/styles.module.scss +28 -7
  72. package/components/PopOver/PopOver.d.ts +5 -3
  73. package/components/PopOver/PopOver.d.ts.map +1 -1
  74. package/components/PopOver/componentdata.json +1 -1
  75. package/components/PopOver/styles.module.scss +16 -13
  76. package/components/RadioButton/RadioButton.d.ts.map +1 -1
  77. package/components/RadioButton/styles.module.scss +12 -14
  78. package/components/Select/styles.module.scss +14 -8
  79. package/components/Slider/Slider.d.ts.map +1 -1
  80. package/components/Slider/index.js +1 -1
  81. package/components/Slider/index.js.map +1 -1
  82. package/components/Slider/styles.module.scss +1 -1
  83. package/components/Spacer/styles.module.scss +13 -1
  84. package/components/StatusDot/styles.module.scss +2 -2
  85. package/components/Stepper/styles.module.scss +28 -20
  86. package/components/Table/Table.d.ts.map +1 -1
  87. package/components/Table/index.js +1 -1
  88. package/components/Table/index.js.map +1 -1
  89. package/components/Table/styles.module.scss +32 -20
  90. package/components/Tag/styles.module.scss +39 -27
  91. package/components/TagList/styles.module.scss +3 -3
  92. package/components/Textarea/Textarea.d.ts.map +1 -1
  93. package/components/Textarea/styles.module.scss +6 -5
  94. package/components/Tile/styles.module.scss +11 -6
  95. package/components/Title/Title.d.ts +1 -1
  96. package/components/Title/Title.d.ts.map +1 -1
  97. package/components/Title/styles.module.scss +5 -0
  98. package/components/Tooltip/TooltipWord/TooltipWord.d.ts +1 -1
  99. package/components/Tooltip/TooltipWord/TooltipWord.d.ts.map +1 -1
  100. package/components/Tooltip/TooltipWord/styles.module.scss +3 -3
  101. package/components/Tooltip/index.js +1 -1
  102. package/components/TooltipExample/index.js +1 -1
  103. package/components/Validation/styles.module.scss +3 -3
  104. package/hoc/withBreakpoint/withBreakpoint.d.ts +1 -1
  105. package/hoc/withBreakpoint/withBreakpoint.d.ts.map +1 -1
  106. package/hoc/withBreakpoint/withBreakpoint.js.map +1 -1
  107. package/hooks/useFocusTrap.d.ts.map +1 -1
  108. package/hooks/useFocusTrap.js.map +1 -1
  109. package/hooks/useSize.js.map +1 -1
  110. package/package.json +1 -1
  111. package/scss/_body.scss +3 -1
  112. package/scss/_breakpoints.scss +5 -8
  113. package/scss/_figma-tokens.scss +2 -2
  114. package/scss/_fonts.scss +36 -21
  115. package/scss/_grid.scss +5 -4
  116. package/scss/_input.scss +20 -11
  117. package/scss/_palette.scss +3 -11
  118. package/scss/_print.scss +58 -18
  119. package/scss/_screen-reader.scss +0 -2
  120. package/scss/_spacers.scss +17 -15
  121. package/scss/_title.scss +11 -5
  122. package/scss/helsenorge.scss +1 -1
  123. package/scss/typography.module.scss +20 -13
  124. package/utils/component.d.ts +1 -0
  125. package/utils/component.d.ts.map +1 -1
  126. package/utils/component.js +1 -1
  127. package/utils/component.js.map +1 -1
  128. package/utils/debounce.d.ts +1 -2
  129. package/utils/debounce.d.ts.map +1 -1
  130. package/utils/debounce.js +1 -1
  131. package/utils/debounce.js.map +1 -1
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 { uuid } from '../../utils/uuid';\nimport ErrorWrapper from '../ErrorWrapper';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\ninterface TextareaProps\n extends Pick<\n React.InputHTMLAttributes<HTMLTextAreaElement>,\n 'autoFocus' | 'disabled' | 'name' | 'autoComplete' | 'placeholder' | 'readOnly' | 'required' | 'defaultValue' | '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?: string;\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 /** Error text to show above the component */\n errorText?: string;\n /** Component shown after label */\n afterLabelChildren?: React.ReactNode;\n /** Component shown under label */\n belowLabelChildren?: React.ReactNode;\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,\n label,\n textareaId = uuid(),\n minRows = 3,\n maxRows = 10,\n grow,\n errorText,\n afterLabelChildren,\n belowLabelChildren,\n autoFocus,\n disabled,\n name,\n autoComplete,\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\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 || maxCharactersExceeded;\n\n const textareaWrapperClass = cn(styles.textarea, {\n [styles['textarea--gutterBottom']]: gutterBottom,\n });\n\n const labelWrapperClass = cn(styles['textarea__label-wrapper'], {\n [styles[`textarea__label-wrapper--on-dark`]]: onDark,\n });\n\n const contentWrapperClass = cn(styles['content-wrapper'], {\n [styles['content-wrapper--transparent']]: transparent,\n [styles['content-wrapper--on-blueberry']]: onBlueberry,\n [styles['content-wrapper--on-dark']]: onDark,\n [styles['content-wrapper--invalid']]: onError,\n [styles['content-wrapper--disabled']]: props.disabled,\n });\n\n const textareaClass = cn(styles['content-wrapper__input'], {\n [styles[`content-wrapper__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>) => {\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}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Textarea} className={textareaWrapperClass}>\n {label && (\n <div className={labelWrapperClass}>\n <label htmlFor={textareaId}>{label}</label>\n {afterLabelChildren && <div className={styles['textarea__after-label-children']}>{afterLabelChildren}</div>}\n </div>\n )}\n {belowLabelChildren && <div>{belowLabelChildren}</div>}\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-invalid={!!onError}\n autoFocus={autoFocus}\n disabled={disabled}\n name={name}\n autoComplete={autoComplete}\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\nexport default Textarea;\n"],"names":["getTextareaMaxWidth","characters","paddingWidth","scrollbarWidth","borderWidth","AVERAGE_CHARACTER_WIDTH_PX","Textarea","React","props","ref","maxCharacters","maxText","width","testId","defaultValue","gutterBottom","transparent","mode","label","textareaId","uuid","minRows","maxRows","grow","errorText","afterLabelChildren","belowLabelChildren","autoFocus","disabled","name","autoComplete","placeholder","readOnly","required","onChange","rest","rows","setRows","useState","textareaInput","setTextareaInput","referanse","useRef","resizeHeight","target","previousRows","currentRows","onDark","FormMode","onBlueberry","maxCharactersExceeded","onError","textareaWrapperClass","cn","styles","labelWrapperClass","contentWrapperClass","textareaClass","useEffect","_a","_b","textarea","_c","handleChange","onChangeHandler","maxWidth","ErrorWrapper","AnalyticsId","MaxCharacters","Textarea$1"],"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 { uuid } from '../../utils/uuid';\nimport ErrorWrapper from '../ErrorWrapper';\nimport MaxCharacters from '../MaxCharacters/MaxCharacters';\n\nimport styles from './styles.module.scss';\n\ninterface TextareaProps\n extends Pick<\n React.InputHTMLAttributes<HTMLTextAreaElement>,\n 'autoFocus' | 'disabled' | 'name' | 'autoComplete' | 'placeholder' | 'readOnly' | 'required' | 'defaultValue' | '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?: string;\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 /** Error text to show above the component */\n errorText?: string;\n /** Component shown after label */\n afterLabelChildren?: React.ReactNode;\n /** Component shown under label */\n belowLabelChildren?: React.ReactNode;\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,\n label,\n textareaId = uuid(),\n minRows = 3,\n maxRows = 10,\n grow,\n errorText,\n afterLabelChildren,\n belowLabelChildren,\n autoFocus,\n disabled,\n name,\n autoComplete,\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\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 || maxCharactersExceeded;\n\n const textareaWrapperClass = cn(styles.textarea, {\n [styles['textarea--gutterBottom']]: gutterBottom,\n });\n\n const labelWrapperClass = cn(styles['textarea__label-wrapper'], {\n [styles[`textarea__label-wrapper--on-dark`]]: onDark,\n });\n\n const contentWrapperClass = cn(styles['content-wrapper'], {\n [styles['content-wrapper--transparent']]: transparent,\n [styles['content-wrapper--on-blueberry']]: onBlueberry,\n [styles['content-wrapper--on-dark']]: onDark,\n [styles['content-wrapper--invalid']]: onError,\n [styles['content-wrapper--disabled']]: props.disabled,\n });\n\n const textareaClass = cn(styles['content-wrapper__input'], {\n [styles[`content-wrapper__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>) => {\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}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.Textarea} className={textareaWrapperClass}>\n {label && (\n <div className={labelWrapperClass}>\n <label htmlFor={textareaId}>{label}</label>\n {afterLabelChildren && <div className={styles['textarea__after-label-children']}>{afterLabelChildren}</div>}\n </div>\n )}\n {belowLabelChildren && <div>{belowLabelChildren}</div>}\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-invalid={!!onError}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n disabled={disabled}\n name={name}\n autoComplete={autoComplete}\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","paddingWidth","scrollbarWidth","borderWidth","AVERAGE_CHARACTER_WIDTH_PX","Textarea","React","props","ref","maxCharacters","maxText","width","testId","defaultValue","gutterBottom","transparent","mode","label","textareaId","uuid","minRows","maxRows","grow","errorText","afterLabelChildren","belowLabelChildren","autoFocus","disabled","name","autoComplete","placeholder","readOnly","required","onChange","rest","rows","setRows","useState","textareaInput","setTextareaInput","referanse","useRef","resizeHeight","target","previousRows","currentRows","onDark","FormMode","onBlueberry","maxCharactersExceeded","onError","textareaWrapperClass","cn","styles","labelWrapperClass","contentWrapperClass","textareaClass","useEffect","_a","_b","textarea","_c","handleChange","onChangeHandler","maxWidth","ErrorWrapper","AnalyticsId","MaxCharacters","Textarea$1"],"mappings":"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"}
package/Title.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Title.js","sources":["../src/components/Title/Title.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\n\nimport titleStyles from './styles.module.scss';\n\nexport type TitleTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'span';\nexport type TitleAppearances = 'titleFeature' | 'title1' | 'title2' | 'title3' | 'title4' | 'title5';\n\nexport interface TitleProps {\n children: React.ReactNode;\n /** Gives a unique id to the title */\n id?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds top and bottom margin in rem. */\n margin?: number | TitleMargin;\n /** Changes the underlying element of the title. */\n htmlMarkup?: TitleTags;\n /** Changes the appearance of the title. */\n appearance?: TitleAppearances;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const Title = React.forwardRef(function TitleForwardedRef(props: TitleProps, ref: React.ForwardedRef<HTMLHeadingElement>) {\n const { id, children, className, htmlMarkup = 'h1', appearance = 'title1', margin = 0, testId } = props;\n const titleClasses = classNames(\n titleStyles.title,\n {\n [titleStyles['title--feature']]: appearance === 'titleFeature',\n [titleStyles['title--title1']]: appearance === 'title1',\n [titleStyles['title--title2']]: appearance === 'title2',\n [titleStyles['title--title3']]: appearance === 'title3',\n [titleStyles['title--title4']]: appearance === 'title4',\n [titleStyles['title--title5']]: appearance === 'title5',\n },\n className\n );\n const CustomTag = htmlMarkup;\n\n const inlineStyle = instanceOfTitleMargin(margin)\n ? { marginTop: `${margin.marginTop}rem`, marginBottom: `${margin.marginBottom}rem` }\n : { marginTop: `${margin}rem`, marginBottom: `${margin}rem` };\n\n return (\n <CustomTag id={id} className={titleClasses} style={inlineStyle} ref={ref} data-testid={testId} data-analyticsid={AnalyticsId.Title}>\n {children}\n </CustomTag>\n );\n});\n\nexport interface TitleMargin {\n marginTop: number;\n marginBottom: number;\n}\n\nexport const instanceOfTitleMargin = (margin: any): margin is TitleMargin => {\n return Object.prototype.hasOwnProperty.call(margin, 'marginTop') && Object.prototype.hasOwnProperty.call(margin, 'marginBottom');\n};\n\nexport default Title;\n"],"names":["Title","React","props","ref","id","children","className","htmlMarkup","appearance","margin","testId","titleClasses","classNames","titleStyles","CustomTag","inlineStyle","instanceOfTitleMargin","AnalyticsId","Title$1"],"mappings":"iJA2BO,MAAMA,EAAQC,EAAM,WAAW,SAA2BC,EAAmBC,EAA6C,CACzH,KAAA,CAAE,GAAAC,EAAI,SAAAC,EAAU,UAAAC,EAAW,WAAAC,EAAa,KAAM,WAAAC,EAAa,SAAU,OAAAC,EAAS,EAAG,OAAAC,CAAA,EAAWR,EAC5FS,EAAeC,EACnBC,EAAY,MACZ,CACE,CAACA,EAAY,gBAAgB,CAAC,EAAGL,IAAe,eAChD,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,SAC/C,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,SAC/C,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,SAC/C,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,SAC/C,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,QACjD,EACAF,CAAA,EAEIQ,EAAYP,EAEZQ,EAAcC,EAAsBP,CAAM,EAC5C,CAAE,UAAW,GAAGA,EAAO,eAAgB,aAAc,GAAGA,EAAO,mBAC/D,CAAE,UAAW,GAAGA,OAAa,aAAc,GAAGA,MAAY,EAE9D,OACGR,EAAA,cAAAa,EAAA,CAAU,GAAAV,EAAQ,UAAWO,EAAc,MAAOI,EAAa,IAAAZ,EAAU,cAAaO,EAAQ,mBAAkBO,EAAY,OAC1HZ,CACH,CAEJ,CAAC,EAOYW,EAAyBP,GAC7B,OAAO,UAAU,eAAe,KAAKA,EAAQ,WAAW,GAAK,OAAO,UAAU,eAAe,KAAKA,EAAQ,cAAc,EAGjIS,EAAelB"}
1
+ {"version":3,"file":"Title.js","sources":["../src/components/Title/Title.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId } from '../../constants';\n\nimport titleStyles from './styles.module.scss';\n\nexport type TitleTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'span';\nexport type TitleAppearances = 'titleFeature' | 'title1' | 'title2' | 'title3' | 'title4' | 'title5';\n\nexport interface TitleProps {\n children: React.ReactNode;\n /** Gives a unique id to the title */\n id?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds top and bottom margin in rem. */\n margin?: number | TitleMargin;\n /** Changes the underlying element of the title. */\n htmlMarkup?: TitleTags;\n /** Changes the appearance of the title. */\n appearance?: TitleAppearances;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const Title = React.forwardRef(function TitleForwardedRef(props: TitleProps, ref: React.ForwardedRef<HTMLHeadingElement>) {\n const { id, children, className, htmlMarkup = 'h1', appearance = 'title1', margin = 0, testId } = props;\n const titleClasses = classNames(\n titleStyles.title,\n {\n [titleStyles['title--feature']]: appearance === 'titleFeature',\n [titleStyles['title--title1']]: appearance === 'title1',\n [titleStyles['title--title2']]: appearance === 'title2',\n [titleStyles['title--title3']]: appearance === 'title3',\n [titleStyles['title--title4']]: appearance === 'title4',\n [titleStyles['title--title5']]: appearance === 'title5',\n },\n className\n );\n const CustomTag = htmlMarkup;\n\n const inlineStyle = instanceOfTitleMargin(margin)\n ? { marginTop: `${margin.marginTop}rem`, marginBottom: `${margin.marginBottom}rem` }\n : { marginTop: `${margin}rem`, marginBottom: `${margin}rem` };\n\n return (\n <CustomTag id={id} className={titleClasses} style={inlineStyle} ref={ref} data-testid={testId} data-analyticsid={AnalyticsId.Title}>\n {children}\n </CustomTag>\n );\n});\n\nexport interface TitleMargin {\n marginTop: number;\n marginBottom: number;\n}\n\nexport const instanceOfTitleMargin = (margin: unknown): margin is TitleMargin => {\n return Object.prototype.hasOwnProperty.call(margin, 'marginTop') && Object.prototype.hasOwnProperty.call(margin, 'marginBottom');\n};\n\nexport default Title;\n"],"names":["Title","React","props","ref","id","children","className","htmlMarkup","appearance","margin","testId","titleClasses","classNames","titleStyles","CustomTag","inlineStyle","instanceOfTitleMargin","AnalyticsId","Title$1"],"mappings":"iJA2BO,MAAMA,EAAQC,EAAM,WAAW,SAA2BC,EAAmBC,EAA6C,CACzH,KAAA,CAAE,GAAAC,EAAI,SAAAC,EAAU,UAAAC,EAAW,WAAAC,EAAa,KAAM,WAAAC,EAAa,SAAU,OAAAC,EAAS,EAAG,OAAAC,CAAA,EAAWR,EAC5FS,EAAeC,EACnBC,EAAY,MACZ,CACE,CAACA,EAAY,gBAAgB,CAAC,EAAGL,IAAe,eAChD,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,SAC/C,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,SAC/C,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,SAC/C,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,SAC/C,CAACK,EAAY,eAAe,CAAC,EAAGL,IAAe,QACjD,EACAF,CAAA,EAEIQ,EAAYP,EAEZQ,EAAcC,EAAsBP,CAAM,EAC5C,CAAE,UAAW,GAAGA,EAAO,eAAgB,aAAc,GAAGA,EAAO,mBAC/D,CAAE,UAAW,GAAGA,OAAa,aAAc,GAAGA,MAAY,EAE9D,OACGR,EAAA,cAAAa,EAAA,CAAU,GAAAV,EAAQ,UAAWO,EAAc,MAAOI,EAAa,IAAAZ,EAAU,cAAaO,EAAQ,mBAAkBO,EAAY,OAC1HZ,CACH,CAEJ,CAAC,EAOYW,EAAyBP,GAC7B,OAAO,UAAU,eAAe,KAAKA,EAAQ,WAAW,GAAK,OAAO,UAAU,eAAe,KAAKA,EAAQ,cAAc,EAGjIS,EAAelB"}
package/Tooltip.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import React, { useContext, useState, useEffect, useRef } from 'react';\n\nimport TooltipWord from './TooltipWord';\nimport { useDelayedState } from '../../hooks/useDelayedState';\nimport { useUuid } from '../../hooks/useUuid';\nimport HelpBubble from '../HelpBubble';\n\nconst HOVER_DELAY_MS = 200;\n\nexport interface TooltipProps {\n /** Ordet som skal ha en tilhørende tooltip */\n children: string;\n /** Teksten som skal vises i tooltip */\n description: React.ReactNode;\n /** Valgfri test-id */\n testId?: string;\n}\n\nexport const Tooltip: React.FC<TooltipProps> = ({ children, description, testId }) => {\n const helpBubbleId = useUuid();\n const wordRef = useRef<HTMLSpanElement>(null);\n const { currentTooltip, setCurrentTooltip } = useContext(TooltipOpenContext);\n const [{ showTooltip, keepOpen }, setShowTooltipDelayed, setShowTooltip] = useDelayedState(\n { showTooltip: false, keepOpen: false },\n HOVER_DELAY_MS\n );\n\n useEffect(() => {\n if (!setCurrentTooltip) {\n return;\n }\n if (showTooltip) {\n setCurrentTooltip(helpBubbleId);\n } else {\n setCurrentTooltip(undefined);\n }\n }, [showTooltip]);\n\n useEffect(() => {\n if (currentTooltip !== helpBubbleId && typeof currentTooltip !== 'undefined') {\n setShowTooltip(prevState => ({ showTooltip: false, keepOpen: prevState.keepOpen }));\n }\n }, [currentTooltip]);\n\n const handleDocumentClick = (): void => {\n if (!showTooltip) {\n setShowTooltip({ showTooltip: false, keepOpen: false });\n }\n };\n\n useEffect(() => {\n document.addEventListener('mouseup', handleDocumentClick);\n return (): void => {\n document.removeEventListener('mouseup', handleDocumentClick);\n };\n }, []);\n\n const handleTooltipClick = (): void => {\n setShowTooltip(prevState => ({ showTooltip: !prevState.showTooltip, keepOpen: !prevState.keepOpen }));\n };\n\n const handleFocus = (): void => {\n if (!currentTooltip) {\n setShowTooltipDelayed(prevState => ({ showTooltip: true, keepOpen: prevState.keepOpen }));\n }\n };\n\n const handleBlur = (): void => {\n setShowTooltip(prevState => ({ showTooltip: false, keepOpen: prevState.keepOpen }));\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLSpanElement>): void => {\n if (e.key === 'Enter') {\n setShowTooltip(prevState => ({ showTooltip: !prevState.showTooltip, keepOpen: !prevState.keepOpen }));\n }\n if (e.key === 'Escape') {\n setShowTooltip({ showTooltip: false, keepOpen: false });\n }\n };\n\n return (\n <>\n <TooltipWord\n ref={wordRef}\n onClick={handleTooltipClick}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n ariaDescribedById={helpBubbleId}\n testId={testId}\n >\n {children}\n </TooltipWord>\n <HelpBubble helpBubbleId={helpBubbleId} controllerRef={wordRef} role=\"tooltip\" showBubble={showTooltip || keepOpen}>\n {description}\n </HelpBubble>\n </>\n );\n};\n\nexport type TooltipContext = {\n currentTooltip?: string;\n setCurrentTooltip?: (id?: string) => void;\n};\n\nconst TooltipOpenContext = React.createContext<TooltipContext>({\n currentTooltip: undefined,\n});\n\nexport const TooltipOpenProvider: React.FC = ({ children }) => {\n const [currentTooltip, setCurrentTooltip] = useState<string>();\n\n return <TooltipOpenContext.Provider value={{ currentTooltip, setCurrentTooltip }}>{children}</TooltipOpenContext.Provider>;\n};\n\nexport default Tooltip;\n"],"names":["HOVER_DELAY_MS","Tooltip","children","description","testId","helpBubbleId","useUuid","wordRef","useRef","currentTooltip","setCurrentTooltip","useContext","TooltipOpenContext","showTooltip","keepOpen","setShowTooltipDelayed","setShowTooltip","useDelayedState","useEffect","prevState","handleDocumentClick","handleTooltipClick","handleFocus","handleBlur","handleKeyDown","React","TooltipWord","HelpBubble","TooltipOpenProvider","useState","Tooltip$1"],"mappings":"kQAOA,MAAMA,EAAiB,IAWVC,EAAkC,CAAC,CAAE,SAAAC,EAAU,YAAAC,EAAa,OAAAC,KAAa,CACpF,MAAMC,EAAeC,IACfC,EAAUC,EAAwB,IAAI,EACtC,CAAE,eAAAC,EAAgB,kBAAAC,CAAkB,EAAIC,EAAWC,CAAkB,EACrE,CAAC,CAAE,YAAAC,EAAa,SAAAC,CAAY,EAAAC,EAAuBC,CAAc,EAAIC,EACzE,CAAE,YAAa,GAAO,SAAU,EAAM,EACtCjB,CAAA,EAGFkB,EAAU,IAAM,CACTR,GAIHA,EADEG,EACgBR,EAEA,MAFY,CAGhC,EACC,CAACQ,CAAW,CAAC,EAEhBK,EAAU,IAAM,CACVT,IAAmBJ,GAAgB,OAAOI,EAAmB,KAC/DO,MAA6B,CAAE,YAAa,GAAO,SAAUG,EAAU,QAAW,EAAA,CACpF,EACC,CAACV,CAAc,CAAC,EAEnB,MAAMW,EAAsB,IAAY,CACjCP,GACHG,EAAe,CAAE,YAAa,GAAO,SAAU,EAAO,CAAA,CACxD,EAGFE,EAAU,KACC,SAAA,iBAAiB,UAAWE,CAAmB,EACjD,IAAY,CACR,SAAA,oBAAoB,UAAWA,CAAmB,CAAA,GAE5D,CAAE,CAAA,EAEL,MAAMC,EAAqB,IAAY,CACtBL,EAAAG,IAAc,CAAE,YAAa,CAACA,EAAU,YAAa,SAAU,CAACA,EAAU,QAAA,EAAW,CAAA,EAGhGG,EAAc,IAAY,CACzBb,GACHM,MAAoC,CAAE,YAAa,GAAM,SAAUI,EAAU,QAAW,EAAA,CAC1F,EAGII,EAAa,IAAY,CAC7BP,MAA6B,CAAE,YAAa,GAAO,SAAUG,EAAU,QAAW,EAAA,CAAA,EAG9EK,EAAiB,GAAkD,CACnE,EAAE,MAAQ,SACGR,EAAAG,IAAc,CAAE,YAAa,CAACA,EAAU,YAAa,SAAU,CAACA,EAAU,QAAA,EAAW,EAElG,EAAE,MAAQ,UACZH,EAAe,CAAE,YAAa,GAAO,SAAU,EAAO,CAAA,CACxD,EAGF,OAEIS,EAAA,cAAAA,EAAA,SAAA,KAAAA,EAAA,cAACC,EAAA,CACC,IAAKnB,EACL,QAASc,EACT,QAASC,EACT,OAAQC,EACR,UAAWC,EACX,kBAAmBnB,EACnB,OAAAD,CAAA,EAECF,CAAA,EAEHuB,EAAA,cAACE,EAAW,CAAA,aAAAtB,EAA4B,cAAeE,EAAS,KAAK,UAAU,WAAYM,GAAeC,CACvG,EAAAX,CACH,CACF,CAEJ,EAOMS,EAAqBa,EAAM,cAA8B,CAC7D,eAAgB,MAClB,CAAC,EAEYG,EAAgC,CAAC,CAAE,SAAA1B,KAAe,CAC7D,KAAM,CAACO,EAAgBC,CAAiB,EAAImB,EAAiB,EAEtD,OAAAJ,EAAA,cAACb,EAAmB,SAAnB,CAA4B,MAAO,CAAE,eAAAH,EAAgB,kBAAAC,EAAkB,EAAIR,CAAS,CAC9F,EAEA4B,EAAe7B"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import React, { useContext, useState, useEffect, useRef } from 'react';\n\nimport TooltipWord from './TooltipWord';\nimport { useDelayedState } from '../../hooks/useDelayedState';\nimport { useUuid } from '../../hooks/useUuid';\nimport HelpBubble from '../HelpBubble';\n\nconst HOVER_DELAY_MS = 200;\n\nexport interface TooltipProps {\n /** Ordet som skal ha en tilhørende tooltip */\n children: string;\n /** Teksten som skal vises i tooltip */\n description: React.ReactNode;\n /** Valgfri test-id */\n testId?: string;\n}\n\nexport const Tooltip: React.FC<TooltipProps> = ({ children, description, testId }) => {\n const helpBubbleId = useUuid();\n const wordRef = useRef<HTMLButtonElement>(null);\n const { currentTooltip, setCurrentTooltip } = useContext(TooltipOpenContext);\n const [{ showTooltip, keepOpen }, setShowTooltipDelayed, setShowTooltip] = useDelayedState(\n { showTooltip: false, keepOpen: false },\n HOVER_DELAY_MS\n );\n\n useEffect(() => {\n if (!setCurrentTooltip) {\n return;\n }\n if (showTooltip) {\n setCurrentTooltip(helpBubbleId);\n } else {\n setCurrentTooltip(undefined);\n }\n }, [showTooltip]);\n\n useEffect(() => {\n if (currentTooltip !== helpBubbleId && typeof currentTooltip !== 'undefined') {\n setShowTooltip(prevState => ({ showTooltip: false, keepOpen: prevState.keepOpen }));\n }\n }, [currentTooltip]);\n\n const handleDocumentClick = (): void => {\n if (!showTooltip) {\n setShowTooltip({ showTooltip: false, keepOpen: false });\n }\n };\n\n useEffect(() => {\n document.addEventListener('mouseup', handleDocumentClick);\n return (): void => {\n document.removeEventListener('mouseup', handleDocumentClick);\n };\n }, []);\n\n const handleTooltipClick = (): void => {\n setShowTooltip(prevState => ({ showTooltip: !prevState.showTooltip, keepOpen: !prevState.keepOpen }));\n };\n\n const handleFocus = (): void => {\n if (!currentTooltip) {\n setShowTooltipDelayed(prevState => ({ showTooltip: true, keepOpen: prevState.keepOpen }));\n }\n };\n\n const handleBlur = (): void => {\n setShowTooltip(prevState => ({ showTooltip: false, keepOpen: prevState.keepOpen }));\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLSpanElement>): void => {\n if (e.key === 'Enter') {\n setShowTooltip(prevState => ({ showTooltip: !prevState.showTooltip, keepOpen: !prevState.keepOpen }));\n }\n if (e.key === 'Escape') {\n setShowTooltip({ showTooltip: false, keepOpen: false });\n }\n };\n\n return (\n <>\n <TooltipWord\n ref={wordRef}\n onClick={handleTooltipClick}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n ariaDescribedById={helpBubbleId}\n testId={testId}\n >\n {children}\n </TooltipWord>\n <HelpBubble helpBubbleId={helpBubbleId} controllerRef={wordRef} role=\"tooltip\" showBubble={showTooltip || keepOpen}>\n {description}\n </HelpBubble>\n </>\n );\n};\n\nexport type TooltipContext = {\n currentTooltip?: string;\n setCurrentTooltip?: (id?: string) => void;\n};\n\nconst TooltipOpenContext = React.createContext<TooltipContext>({\n currentTooltip: undefined,\n});\n\nexport const TooltipOpenProvider: React.FC = ({ children }) => {\n const [currentTooltip, setCurrentTooltip] = useState<string>();\n\n return <TooltipOpenContext.Provider value={{ currentTooltip, setCurrentTooltip }}>{children}</TooltipOpenContext.Provider>;\n};\n\nexport default Tooltip;\n"],"names":["HOVER_DELAY_MS","Tooltip","children","description","testId","helpBubbleId","useUuid","wordRef","useRef","currentTooltip","setCurrentTooltip","useContext","TooltipOpenContext","showTooltip","keepOpen","setShowTooltipDelayed","setShowTooltip","useDelayedState","useEffect","prevState","handleDocumentClick","handleTooltipClick","handleFocus","handleBlur","handleKeyDown","React","TooltipWord","HelpBubble","TooltipOpenProvider","useState","Tooltip$1"],"mappings":"kQAOA,MAAMA,EAAiB,IAWVC,EAAkC,CAAC,CAAE,SAAAC,EAAU,YAAAC,EAAa,OAAAC,KAAa,CACpF,MAAMC,EAAeC,IACfC,EAAUC,EAA0B,IAAI,EACxC,CAAE,eAAAC,EAAgB,kBAAAC,CAAkB,EAAIC,EAAWC,CAAkB,EACrE,CAAC,CAAE,YAAAC,EAAa,SAAAC,CAAY,EAAAC,EAAuBC,CAAc,EAAIC,EACzE,CAAE,YAAa,GAAO,SAAU,EAAM,EACtCjB,CAAA,EAGFkB,EAAU,IAAM,CACTR,GAIHA,EADEG,EACgBR,EAEA,MAFY,CAGhC,EACC,CAACQ,CAAW,CAAC,EAEhBK,EAAU,IAAM,CACVT,IAAmBJ,GAAgB,OAAOI,EAAmB,KAC/DO,MAA6B,CAAE,YAAa,GAAO,SAAUG,EAAU,QAAW,EAAA,CACpF,EACC,CAACV,CAAc,CAAC,EAEnB,MAAMW,EAAsB,IAAY,CACjCP,GACHG,EAAe,CAAE,YAAa,GAAO,SAAU,EAAO,CAAA,CACxD,EAGFE,EAAU,KACC,SAAA,iBAAiB,UAAWE,CAAmB,EACjD,IAAY,CACR,SAAA,oBAAoB,UAAWA,CAAmB,CAAA,GAE5D,CAAE,CAAA,EAEL,MAAMC,EAAqB,IAAY,CACtBL,EAAAG,IAAc,CAAE,YAAa,CAACA,EAAU,YAAa,SAAU,CAACA,EAAU,QAAA,EAAW,CAAA,EAGhGG,EAAc,IAAY,CACzBb,GACHM,MAAoC,CAAE,YAAa,GAAM,SAAUI,EAAU,QAAW,EAAA,CAC1F,EAGII,EAAa,IAAY,CAC7BP,MAA6B,CAAE,YAAa,GAAO,SAAUG,EAAU,QAAW,EAAA,CAAA,EAG9EK,EAAiB,GAAkD,CACnE,EAAE,MAAQ,SACGR,EAAAG,IAAc,CAAE,YAAa,CAACA,EAAU,YAAa,SAAU,CAACA,EAAU,QAAA,EAAW,EAElG,EAAE,MAAQ,UACZH,EAAe,CAAE,YAAa,GAAO,SAAU,EAAO,CAAA,CACxD,EAGF,OAEIS,EAAA,cAAAA,EAAA,SAAA,KAAAA,EAAA,cAACC,EAAA,CACC,IAAKnB,EACL,QAASc,EACT,QAASC,EACT,OAAQC,EACR,UAAWC,EACX,kBAAmBnB,EACnB,OAAAD,CAAA,EAECF,CAAA,EAEHuB,EAAA,cAACE,EAAW,CAAA,aAAAtB,EAA4B,cAAeE,EAAS,KAAK,UAAU,WAAYM,GAAeC,CACvG,EAAAX,CACH,CACF,CAEJ,EAOMS,EAAqBa,EAAM,cAA8B,CAC7D,eAAgB,MAClB,CAAC,EAEYG,EAAgC,CAAC,CAAE,SAAA1B,KAAe,CAC7D,KAAM,CAACO,EAAgBC,CAAiB,EAAImB,EAAiB,EAEtD,OAAAJ,EAAA,cAACb,EAAmB,SAAnB,CAA4B,MAAO,CAAE,eAAAH,EAAgB,kBAAAC,EAAkB,EAAIR,CAAS,CAC9F,EAEA4B,EAAe7B"}
package/TooltipWord.js CHANGED
@@ -1,2 +1,2 @@
1
- import a from"react";import{AnalyticsId as m}from"./constants.js";import n from"./components/Tooltip/TooltipWord/styles.module.scss";const e=a.forwardRef(({children:r,onClick:d,onFocus:o,onBlur:t,onKeyDown:i,testId:s,ariaDescribedById:p},l)=>a.createElement("span",{className:n.word,ref:l,tabIndex:0,onClick:d,onMouseEnter:o,onMouseLeave:t,onFocus:o,onBlur:t,onKeyDown:i,"aria-describedby":p,"data-testid":s,"data-analyticsid":m.Tooltip},r));e.displayName="TooltipWord";const T=e;export{T};
1
+ import a from"react";import{AnalyticsId as p}from"./constants.js";import c from"./components/Tooltip/TooltipWord/styles.module.scss";const e=a.forwardRef(({children:r,onClick:i,onFocus:o,onBlur:t,onKeyDown:d,testId:s,ariaDescribedById:l},m)=>a.createElement("button",{className:c.word,ref:m,onClick:i,onMouseEnter:o,onMouseLeave:t,onFocus:o,onBlur:t,onKeyDown:d,"aria-describedby":l,"data-testid":s,"data-analyticsid":p.Tooltip},r));e.displayName="TooltipWord";const T=e;export{T};
2
2
  //# sourceMappingURL=TooltipWord.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TooltipWord.js","sources":["../src/components/Tooltip/TooltipWord/TooltipWord.tsx"],"sourcesContent":["import React from 'react';\n\nimport { AnalyticsId } from '../../../constants';\n\nimport styles from './styles.module.scss';\n\nexport interface TooltipWordProps {\n /** Ordet som skal ha en tilhørende tooltip */\n children: string;\n /** Callback når ordet klikkes på */\n onClick: () => void;\n /** Callback når ordet får fokus eller hovres over */\n onFocus: () => void;\n /** Callback når ordet mister fokus eller hover forsvinner */\n onBlur: () => void;\n /** Callback når det skrives på tastaturet */\n onKeyDown: (e: React.KeyboardEvent<HTMLSpanElement>) => void;\n /** ID til element som beskriver ordet */\n ariaDescribedById: string;\n /** Valgfri test-id */\n testId?: string;\n}\n\nconst TooltipWord = React.forwardRef<HTMLSpanElement, TooltipWordProps>(\n ({ children, onClick, onFocus, onBlur, onKeyDown, testId, ariaDescribedById }, ref) => (\n <span\n className={styles.word}\n ref={ref}\n tabIndex={0}\n onClick={onClick}\n onMouseEnter={onFocus}\n onMouseLeave={onBlur}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n aria-describedby={ariaDescribedById}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Tooltip}\n >\n {children}\n </span>\n )\n);\n\nTooltipWord.displayName = 'TooltipWord';\n\nexport default TooltipWord;\n"],"names":["TooltipWord","React","children","onClick","onFocus","onBlur","onKeyDown","testId","ariaDescribedById","ref","styles","AnalyticsId","TooltipWord$1"],"mappings":"qIAuBA,MAAMA,EAAcC,EAAM,WACxB,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,QAAAC,EAAS,OAAAC,EAAQ,UAAAC,EAAW,OAAAC,EAAQ,kBAAAC,CAAkB,EAAGC,IAC7ER,EAAA,cAAC,OAAA,CACC,UAAWS,EAAO,KAClB,IAAAD,EACA,SAAU,EACV,QAAAN,EACA,aAAcC,EACd,aAAcC,EACd,QAAAD,EACA,OAAAC,EACA,UAAAC,EACA,mBAAkBE,EAClB,cAAaD,EACb,mBAAkBI,EAAY,OAAA,EAE7BT,CACH,CAEJ,EAEAF,EAAY,YAAc,cAE1B,MAAAY,EAAeZ"}
1
+ {"version":3,"file":"TooltipWord.js","sources":["../src/components/Tooltip/TooltipWord/TooltipWord.tsx"],"sourcesContent":["import React from 'react';\n\nimport { AnalyticsId } from '../../../constants';\n\nimport styles from './styles.module.scss';\n\nexport interface TooltipWordProps {\n /** Ordet som skal ha en tilhørende tooltip */\n children: string;\n /** Callback når ordet klikkes på */\n onClick: () => void;\n /** Callback når ordet får fokus eller hovres over */\n onFocus: () => void;\n /** Callback når ordet mister fokus eller hover forsvinner */\n onBlur: () => void;\n /** Callback når det skrives på tastaturet */\n onKeyDown: (e: React.KeyboardEvent<HTMLSpanElement>) => void;\n /** ID til element som beskriver ordet */\n ariaDescribedById: string;\n /** Valgfri test-id */\n testId?: string;\n}\n\nconst TooltipWord = React.forwardRef<HTMLButtonElement, TooltipWordProps>(\n ({ children, onClick, onFocus, onBlur, onKeyDown, testId, ariaDescribedById }, ref) => (\n <button\n className={styles.word}\n ref={ref}\n onClick={onClick}\n onMouseEnter={onFocus}\n onMouseLeave={onBlur}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n aria-describedby={ariaDescribedById}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Tooltip}\n >\n {children}\n </button>\n )\n);\n\nTooltipWord.displayName = 'TooltipWord';\n\nexport default TooltipWord;\n"],"names":["TooltipWord","React","children","onClick","onFocus","onBlur","onKeyDown","testId","ariaDescribedById","ref","styles","AnalyticsId","TooltipWord$1"],"mappings":"qIAuBA,MAAMA,EAAcC,EAAM,WACxB,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,QAAAC,EAAS,OAAAC,EAAQ,UAAAC,EAAW,OAAAC,EAAQ,kBAAAC,CAAkB,EAAGC,IAC7ER,EAAA,cAAC,SAAA,CACC,UAAWS,EAAO,KAClB,IAAAD,EACA,QAAAN,EACA,aAAcC,EACd,aAAcC,EACd,QAAAD,EACA,OAAAC,EACA,UAAAC,EACA,mBAAkBE,EAClB,cAAaD,EACb,mBAAkBI,EAAY,OAAA,EAE7BT,CACH,CAEJ,EAEAF,EAAY,YAAc,cAE1B,MAAAY,EAAeZ"}
@@ -1,6 +1,7 @@
1
- @import '../../scss/_spacers.scss';
2
- @import '../../scss/_breakpoints.scss';
3
- @import '../../scss/_palette.scss';
1
+ @use 'sass:map';
2
+ @import '../../scss/spacers';
3
+ @import '../../scss/breakpoints';
4
+ @import '../../scss/palette';
4
5
 
5
6
  $underline-width: 0.0625rem;
6
7
  $focus-width: 0.15rem;
@@ -11,6 +12,7 @@ $focus-width: 0.15rem;
11
12
  background-color: $blueberry50;
12
13
  border-bottom-color: $blueberry600;
13
14
  }
15
+
14
16
  @mixin anchorlink-focus {
15
17
  outline: none;
16
18
  border: $focus-width solid $black;
@@ -18,7 +20,6 @@ $focus-width: 0.15rem;
18
20
 
19
21
  @mixin anchorlink {
20
22
  display: inline;
21
- -webkit-box-decoration-break: clone;
22
23
  box-decoration-break: clone;
23
24
  overflow-wrap: break-word;
24
25
  word-break: break-word;
@@ -33,6 +34,7 @@ $focus-width: 0.15rem;
33
34
  &:hover {
34
35
  @include anchorlink-hover;
35
36
  }
37
+
36
38
  &:focus {
37
39
  @include anchorlink-focus;
38
40
  }
@@ -50,14 +52,15 @@ $focus-width: 0.15rem;
50
52
  font-size: 1.125rem;
51
53
  line-height: 1.875rem;
52
54
  font-weight: 400;
53
- @media (min-width: map-get($grid-breakpoints, md)) {
55
+
56
+ @media (min-width: map.get($grid-breakpoints, md)) {
54
57
  font-size: 1.25rem;
55
58
  }
56
59
  }
57
60
 
58
61
  @mixin anchorlink-icon {
59
62
  &[target='_blank'] {
60
- &:after {
63
+ &::after {
61
64
  content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='38px' height='38px' viewBox='0 0 48 48' fill='%2308667c'><polygon points='33.305,14.659,33.305,29.205,32.005,29.205,32.005,16.948,15.804,33.149,14.885,32.229,31.155,15.959,18.761,15.96,18.761,14.659' /></svg>");
62
65
  display: inline-block;
63
66
  vertical-align: bottom;
@@ -75,9 +78,11 @@ $focus-width: 0.15rem;
75
78
 
76
79
  .anchorlink-wrapper {
77
80
  all: unset;
81
+
78
82
  &:hover > span {
79
83
  @include anchorlink-hover;
80
84
  }
85
+
81
86
  &:focus > span {
82
87
  @include anchorlink-focus;
83
88
  }
@@ -1,5 +1,5 @@
1
- @import '../../scss/_palette.scss';
2
- @import '../../scss/_font-settings';
1
+ @import '../../scss/palette';
2
+ @import '../../scss/font-settings';
3
3
 
4
4
  .avatar {
5
5
  display: flex;
@@ -1,4 +1,4 @@
1
- @import '../../scss/_palette.scss';
1
+ @import '../../scss/palette';
2
2
 
3
3
  .badge {
4
4
  display: flex;
@@ -17,21 +17,27 @@
17
17
  color: $black;
18
18
  background-color: $white;
19
19
  }
20
+
20
21
  &--blueberry {
21
22
  background-color: $blueberry500;
22
23
  }
24
+
23
25
  &--banana {
24
26
  background-color: $banana500;
25
27
  }
28
+
26
29
  &--cherry {
27
30
  background-color: $cherry500;
28
31
  }
32
+
29
33
  &--kiwi {
30
34
  background-color: $kiwi500;
31
35
  }
36
+
32
37
  &--neutral {
33
38
  background-color: $neutral500;
34
39
  }
40
+
35
41
  &--plum {
36
42
  background-color: $plum500;
37
43
  }
@@ -1,13 +1,12 @@
1
- @import '../../scss/_spacers.scss';
2
- @import '../../scss/_breakpoints.scss';
3
- @import '../../scss/_palette.scss';
4
- @import '../../scss/_font-settings.scss';
5
- @import '../../scss/screen-reader.scss';
1
+ @use 'sass:map';
2
+ @import '../../scss/spacers';
3
+ @import '../../scss/breakpoints';
4
+ @import '../../scss/palette';
5
+ @import '../../scss/font-settings';
6
+ @import '../../scss/screen-reader';
6
7
 
7
8
  $dark-mode-disabled-transparrent: #ffffffb3;
8
-
9
- $with-icons:
10
- // icon-class, size-class, padding-left, padding-right, padding-left desktop, padding-right desktop, svg-margin-left, svg-margin-right, svg-margin-left desktop, svg-margin-right desktop
9
+ $with-icons: // icon-class, size-class, padding-left, padding-right, padding-left desktop, padding-right desktop, svg-margin-left, svg-margin-right, svg-margin-left desktop, svg-margin-right desktop
11
10
  'left-icon' 'normal' getSpacer(4xs) getSpacer(xs) getSpacer(xs) getSpacer(m) 0 getSpacer(3xs) 0 getSpacer(2xs),
12
11
  'right-icon' 'normal' getSpacer(xs) getSpacer(4xs) getSpacer(m) getSpacer(xs) getSpacer(3xs) 0 getSpacer(2xs) 0,
13
12
  'left-icon' 'large' getSpacer(xs) getSpacer(m) getSpacer(s) getSpacer(l) 0 getSpacer(2xs) 0 getSpacer(xs),
@@ -23,6 +22,7 @@ $with-icons:
23
22
  outline: none;
24
23
  box-shadow: 0 0 0 getSpacer(3xs) $black;
25
24
  }
25
+
26
26
  @mixin focus-shadow-on-dark {
27
27
  box-shadow: 0 0 0 getSpacer(3xs) $white;
28
28
  }
@@ -33,6 +33,7 @@ $with-icons:
33
33
  &:hover {
34
34
  background-color: $background-color;
35
35
  }
36
+
36
37
  :disabled > & {
37
38
  background-color: transparent;
38
39
  }
@@ -52,7 +53,7 @@ $with-icons:
52
53
  :disabled > & {
53
54
  outline-color: $neutral700;
54
55
 
55
- @media (min-width: map-get($grid-breakpoints, md)) {
56
+ @media (min-width: map.get($grid-breakpoints, md)) {
56
57
  outline-color: $neutral500;
57
58
  }
58
59
  }
@@ -60,14 +61,17 @@ $with-icons:
60
61
 
61
62
  @mixin outline-text($color) {
62
63
  color: $color;
64
+
63
65
  :disabled > & {
64
- @media (min-width: map-get($grid-breakpoints, md)) {
66
+ @media (min-width: map.get($grid-breakpoints, md)) {
65
67
  color: $neutral700;
66
68
  }
67
69
  }
68
70
  }
71
+
69
72
  @mixin borderless-text($color) {
70
73
  color: $color;
74
+
71
75
  :disabled > & {
72
76
  color: $neutral700;
73
77
  }
@@ -79,15 +83,18 @@ $with-icons:
79
83
  &:hover {
80
84
  box-shadow: none;
81
85
  }
86
+
82
87
  &:hover,
83
88
  :focus > & {
84
89
  background-color: $background-color;
85
90
  }
91
+
86
92
  :focus > & {
87
93
  @include focus-shadow-on-dark;
88
94
 
89
95
  &:hover {
90
96
  @include focus-shadow-on-dark;
97
+
91
98
  background-color: $white;
92
99
  }
93
100
  }
@@ -126,7 +133,7 @@ $with-icons:
126
133
  outline-color: $white;
127
134
 
128
135
  :disabled > & {
129
- @media (min-width: map-get($grid-breakpoints, md)) {
136
+ @media (min-width: map.get($grid-breakpoints, md)) {
130
137
  outline-color: $dark-mode-disabled-transparrent;
131
138
  }
132
139
  }
@@ -148,7 +155,7 @@ $with-icons:
148
155
  color: $white;
149
156
 
150
157
  :disabled > & {
151
- @media (min-width: map-get($grid-breakpoints, md)) {
158
+ @media (min-width: map.get($grid-breakpoints, md)) {
152
159
  color: $dark-mode-disabled-transparrent;
153
160
  }
154
161
  }
@@ -166,7 +173,7 @@ $with-icons:
166
173
  padding: getSpacer(2xs) 0;
167
174
  margin: getSpacer(2xs) * -1 0;
168
175
 
169
- @media (min-width: map-get($grid-breakpoints, md)) {
176
+ @media (min-width: map.get($grid-breakpoints, md)) {
170
177
  padding: 0;
171
178
  margin: 0;
172
179
  }
@@ -207,11 +214,12 @@ $with-icons:
207
214
  outline-offset: getSpacer(4xs) * -1;
208
215
  background-color: $neutral200;
209
216
  }
217
+
210
218
  :disabled > & &__text {
211
219
  color: $neutral800;
212
220
  }
213
221
 
214
- @media (min-width: map-get($grid-breakpoints, md)) {
222
+ @media (min-width: map.get($grid-breakpoints, md)) {
215
223
  min-height: 3.125rem;
216
224
  padding: 0 getSpacer(l);
217
225
  font-size: $font-size-md;
@@ -221,7 +229,7 @@ $with-icons:
221
229
  min-height: 3.625rem;
222
230
  padding: 0 getSpacer(l);
223
231
 
224
- @media (min-width: map-get($grid-breakpoints, md)) {
232
+ @media (min-width: map.get($grid-breakpoints, md)) {
225
233
  min-height: 4.5rem;
226
234
  }
227
235
  }
@@ -231,18 +239,19 @@ $with-icons:
231
239
  padding-left: $pl;
232
240
  padding-right: $pr;
233
241
 
234
- @media (min-width: map-get($grid-breakpoints, md)) {
242
+ @media (min-width: map.get($grid-breakpoints, md)) {
235
243
  padding-left: $pld;
236
244
  padding-right: $prd;
237
245
  }
238
246
  }
239
247
  }
248
+
240
249
  @each $icon-class, $size-class, $pl, $pr, $pld, $prd, $svgml, $svgmr, $svgmld, $svgmrd in $with-icons {
241
250
  &--#{$size-class} &__#{$icon-class} {
242
251
  margin-left: $svgml;
243
252
  margin-right: $svgmr;
244
253
 
245
- @media (min-width: map-get($grid-breakpoints, md)) {
254
+ @media (min-width: map.get($grid-breakpoints, md)) {
246
255
  margin-left: $svgmld;
247
256
  margin-right: $svgmrd;
248
257
  }
@@ -277,6 +286,7 @@ $with-icons:
277
286
  &--borderless:not(.button--only-icon) {
278
287
  padding: 0 getSpacer(3xs);
279
288
  }
289
+
280
290
  &--borderless {
281
291
  &:hover {
282
292
  box-shadow: none;
@@ -289,6 +299,7 @@ $with-icons:
289
299
 
290
300
  :focus > & {
291
301
  @include focus-shadow;
302
+
292
303
  &:hover {
293
304
  @include focus-shadow;
294
305
  }
@@ -298,7 +309,7 @@ $with-icons:
298
309
  color: $white;
299
310
  margin: 0 auto 0 0;
300
311
 
301
- @media (min-width: map-get($grid-breakpoints, md)) {
312
+ @media (min-width: map.get($grid-breakpoints, md)) {
302
313
  margin: 0 auto 0 0;
303
314
  }
304
315
 
@@ -308,23 +319,26 @@ $with-icons:
308
319
  text-overflow: ellipsis;
309
320
  }
310
321
  }
322
+
311
323
  &--outline &__text {
312
324
  @include outline-text($blueberry600);
313
325
  }
314
326
  &--outline#{&}--destructive &__text {
315
327
  @include outline-text($cherry600);
316
328
  }
329
+
317
330
  &--borderless &__text {
318
331
  @include borderless-text($blueberry600);
319
332
  }
320
333
  &--borderless#{&}--destructive &__text {
321
334
  @include borderless-text($cherry600);
322
335
  }
336
+
323
337
  &--only-icon &__text {
324
- @include sr-only();
338
+ @include sr-only;
325
339
  }
326
340
 
327
- @include on-dark();
341
+ @include on-dark;
328
342
  }
329
343
 
330
344
  .diagonal {
@@ -339,7 +353,7 @@ $with-icons:
339
353
  &--on-dark &__line {
340
354
  border-color: $white;
341
355
 
342
- @media (min-width: map-get($grid-breakpoints, md)) {
356
+ @media (min-width: map.get($grid-breakpoints, md)) {
343
357
  border-color: $dark-mode-disabled-transparrent;
344
358
  }
345
359
  }
@@ -1,7 +1,8 @@
1
- @import '../../scss/_spacers.scss';
2
- @import '../../scss/_breakpoints.scss';
3
- @import '../../scss/_palette.scss';
4
- @import '../../scss/font-settings.scss';
1
+ @use 'sass:map';
2
+ @import '../../scss/spacers';
3
+ @import '../../scss/breakpoints';
4
+ @import '../../scss/palette';
5
+ @import '../../scss/font-settings';
5
6
 
6
7
  .checkbox-errors {
7
8
  font-size: $font-size-sm;
@@ -18,7 +19,7 @@
18
19
  background-color: $cherry100;
19
20
  border-left: 0.25rem solid $cherry600;
20
21
 
21
- @media (min-width: map-get($grid-breakpoints, md)) {
22
+ @media (min-width: map.get($grid-breakpoints, md)) {
22
23
  padding: getSpacer(s) getSpacer(m) getSpacer(l);
23
24
  }
24
25
  }
@@ -51,7 +52,7 @@
51
52
  display: flex;
52
53
  }
53
54
 
54
- @media (min-width: map-get($grid-breakpoints, md)) {
55
+ @media (min-width: map.get($grid-breakpoints, md)) {
55
56
  font-size: $font-size-md;
56
57
  }
57
58
 
@@ -85,7 +86,7 @@
85
86
  background-color: $white;
86
87
  }
87
88
 
88
- @media (min-width: map-get($grid-breakpoints, md)) {
89
+ @media (min-width: map.get($grid-breakpoints, md)) {
89
90
  &--bigform {
90
91
  padding: 1.68rem getSpacer(l);
91
92
  }
@@ -93,12 +94,9 @@
93
94
  }
94
95
 
95
96
  .checkbox {
96
- width: 0px;
97
+ width: 0;
97
98
  margin: 0;
98
-
99
- -moz-appearance: none;
100
- -webkit-appearance: none;
101
- -o-appearance: none;
99
+ appearance: none;
102
100
 
103
101
  &__icon-wrapper {
104
102
  display: flex;
@@ -172,9 +170,11 @@
172
170
 
173
171
  &--disabled {
174
172
  color: $neutral400;
173
+
175
174
  &.checkbox__icon-wrapper--checked {
176
175
  color: $neutral400;
177
176
  }
177
+
178
178
  :hover > & {
179
179
  box-shadow: 0 0 0 getSpacer(4xs);
180
180
  background-color: transparent;
@@ -1,34 +1,42 @@
1
- @import '../../scss/_spacers.scss';
2
- @import '../../scss/_palette.scss';
3
- @import '../../scss/_breakpoints.scss';
1
+ @use 'sass:map';
2
+ @import '../../scss/spacers';
3
+ @import '../../scss/palette';
4
+ @import '../../scss/breakpoints';
5
+
4
6
  .close {
5
7
  display: flex;
6
8
  align-items: center;
7
9
  justify-content: center;
8
- @media (max-width: map-get($grid-breakpoints, sm)) {
10
+
11
+ @media (max-width: map.get($grid-breakpoints, sm)) {
9
12
  height: 2.375rem;
10
13
  width: 2.375rem;
11
14
  }
15
+
12
16
  height: 3rem;
13
17
  width: 3rem;
14
18
  padding: 0;
15
19
  border: 0;
16
20
  background-color: transparent;
17
21
  cursor: pointer;
22
+
18
23
  &:hover,
19
24
  &:active {
20
- background-color: rgba(88, 170, 187, 0.1);
25
+ background-color: rgb(88 170 187 / 10%);
21
26
  }
27
+
22
28
  &:focus {
23
- box-shadow: 0px 0px 0px 2px $black;
29
+ box-shadow: 0 0 0 2px $black;
24
30
  background-color: transparent;
25
31
  border-radius: 0;
26
32
  border: 0;
27
33
  outline: none;
28
34
  }
35
+
29
36
  &:hover {
30
- background-color: rgba(88, 170, 187, 0.1);
37
+ background-color: rgb(88 170 187 / 10%);
31
38
  }
39
+
32
40
  &--small {
33
41
  height: auto;
34
42
  width: auto;
@@ -1,2 +1,2 @@
1
- import t,{useRef as f,useState as V}from"react";import v from"classnames";import{theme as C}from"../../theme/index.js";import"../../hooks/useBreakpoint.js";import{useHover as W}from"../../hooks/useHover.js";import{useSize as X}from"../../hooks/useSize.js";import{useToggle as j}from"../../hooks/useToggle.js";import{useKeyboardEvent as q}from"../../hooks/useKeyboardEvent.js";import{useOutsideEvent as F}from"../../hooks/useOutsideEvent.js";import{useUuid as g}from"../../hooks/useUuid.js";import{KeyboardEventKey as r,AnalyticsId as G,IconSize as J}from"../../constants.js";import{B as Q}from"../../Button.js";import{Icon as Y}from"../Icons/Icon.js";import Z from"../Icons/PlusSmall.js";import e from"./styles.module.scss";import"../../theme/grid.js";import"../../theme/palette.js";import"../../theme/spacers.js";import"../../utils/debounce.js";import"../../hooks/usePrevious.js";import"../../uuid.js";import"../../utils/environment.js";import"../../hooks/useIcons.js";import"../../theme/currys/color.js";import"../Icons/ArrowRight.js";import"../Button/styles.module.scss";var M=(s=>(s.onwhite="onwhite",s.ongrey="ongrey",s.onblueberry="onblueberry",s.oncherry="oncherry",s))(M||{});const ee=s=>{const{label:R,placeholder:$,closeText:A="Lukk",noCloseButton:K=!1,onToggle:S,open:H=!1,children:_,mode:d="onwhite",transparent:O=!1,fluid:y=!1,testId:z,disabled:c}=s,p=f(null),b=f(null),{hoverRef:m,isHovered:B}=W(),{value:a,toggleValue:w}=j(!c&&H,S),i=f(t.Children.map(_,()=>t.createRef())),[h,D]=V(),{width:L}=X(m)||{},E=g(),x=g(),I=g(),N=()=>{var o;w(),(o=b.current)==null||o.focus()},u=()=>{var o;w(),(o=m.current)==null||o.focus()};q(p,o=>{var k;if(o.preventDefault(),!i.current)return;if(a){if(o.key===r.Escape&&a){u();return}}else{N();return}const l=i.current.findIndex(P=>P.current===o.target);let n=l;o.key===r.Home?n=0:o.key===r.End?n=i.current.length-1:o.key===r.ArrowDown&&l<i.current.length-1?n=l+1:o.key===r.ArrowUp&&l>0?n=l-1:o.key===r.Enter&&l!==-1&&(n=l),n!==-1&&((k=i.current[n].current)==null||k.focus(),D(n))},[r.ArrowDown,r.ArrowUp,r.End,r.Enter,r.Escape,r.Home]),F(p,()=>a&&u());const T=v(e.dropdown__toggle,!c&&{[e["dropdown__toggle--on-white"]]:d==="onwhite",[e["dropdown__toggle--on-grey"]]:d==="ongrey",[e["dropdown__toggle--on-blueberry"]]:d==="onblueberry",[e["dropdown__toggle--on-cherry"]]:d==="oncherry",[e["dropdown__toggle--transparent"]]:O,[e["dropdown__toggle--fluid"]]:y,[e["dropdown__toggle--open"]]:a}),U=v(e.dropdown__content,a&&e["dropdown__content--open"]);return t.createElement("div",{className:e.dropdown,ref:p},t.createElement("span",{id:E,className:e.dropdown__label},R),t.createElement("button",{type:"button",onClick:()=>!a&&N(),className:T,ref:m,"data-testid":z,"data-analyticsid":G.Dropdown,disabled:c,"aria-labelledby":x,"aria-haspopup":"listbox","aria-expanded":a},t.createElement("span",{id:x,className:e.dropdown__toggle__label},$),t.createElement(Y,{color:c?C.palette.neutral500:C.palette.blueberry600,svgIcon:Z,className:e.dropdown__icon,isHovered:B,size:J.XSmall})),t.createElement("div",{className:U,style:{width:y?"100%":`${L}px`}},t.createElement("ul",{className:e.dropdown__options,role:"listbox","aria-labelledby":E,tabIndex:-1,"aria-activedescendant":typeof h<"u"?`${I}-${h}`:void 0,ref:b},t.Children.map(_,(o,l)=>{var n;return t.createElement("li",{className:e.dropdown__input,role:"option",id:`${I}-${l}`},t.cloneElement(o,{ref:(n=i.current)==null?void 0:n[l]}))})),!K&&t.createElement("div",{className:e.dropdown__close},t.createElement(Q,{onClick:u,fluid:!0,"aria-expanded":a},A))))},Re=ee;export{M as DropdownMode,Re as default};
1
+ import t,{useRef as g,useState as V}from"react";import v from"classnames";import{theme as C}from"../../theme/index.js";import"../../hooks/useBreakpoint.js";import{useHover as W}from"../../hooks/useHover.js";import{useSize as X}from"../../hooks/useSize.js";import{useToggle as j}from"../../hooks/useToggle.js";import{useKeyboardEvent as q}from"../../hooks/useKeyboardEvent.js";import{useOutsideEvent as F}from"../../hooks/useOutsideEvent.js";import{useUuid as _}from"../../hooks/useUuid.js";import{KeyboardEventKey as r,AnalyticsId as G,IconSize as J}from"../../constants.js";import{B as Q}from"../../Button.js";import{Icon as Y}from"../Icons/Icon.js";import Z from"../Icons/PlusSmall.js";import e from"./styles.module.scss";import"../../theme/grid.js";import"../../theme/palette.js";import"../../theme/spacers.js";import"../../utils/debounce.js";import"../../hooks/usePrevious.js";import"../../uuid.js";import"../../utils/environment.js";import"../../hooks/useIcons.js";import"../../theme/currys/color.js";import"../Icons/ArrowRight.js";import"../Button/styles.module.scss";var M=(s=>(s.onwhite="onwhite",s.ongrey="ongrey",s.onblueberry="onblueberry",s.oncherry="oncherry",s))(M||{});const ee=s=>{const{label:R,placeholder:$,closeText:A="Lukk",noCloseButton:K=!1,onToggle:S,open:H=!1,children:y,mode:d="onwhite",transparent:O=!1,fluid:b=!1,testId:z,disabled:c}=s,p=g(null),w=g(null),{hoverRef:m,isHovered:B}=W(),{value:a,toggleValue:h}=j(!c&&H,S),i=g(t.Children.map(y,()=>t.createRef())),[u,D]=V(),{width:L}=X(m)||{},E=_(),I=_(),x=_(),N=()=>{var o;h(),(o=w.current)==null||o.focus()},f=()=>{var o;h(),(o=m.current)==null||o.focus()};q(p,o=>{var k;if(o.preventDefault(),!i.current)return;if(a){if(o.key===r.Escape&&a){f();return}}else{N();return}const n=i.current.findIndex(P=>P.current===o.target);let l=n;o.key===r.Home?l=0:o.key===r.End?l=i.current.length-1:o.key===r.ArrowDown&&n<i.current.length-1?l=n+1:o.key===r.ArrowUp&&n>0?l=n-1:o.key===r.Enter&&n!==-1&&(l=n),l!==-1&&((k=i.current[l].current)==null||k.focus(),D(l))},[r.ArrowDown,r.ArrowUp,r.End,r.Enter,r.Escape,r.Home]),F(p,()=>a&&f());const T=v(e.dropdown__toggle,!c&&{[e["dropdown__toggle--on-white"]]:d==="onwhite",[e["dropdown__toggle--on-grey"]]:d==="ongrey",[e["dropdown__toggle--on-blueberry"]]:d==="onblueberry",[e["dropdown__toggle--on-cherry"]]:d==="oncherry",[e["dropdown__toggle--transparent"]]:O,[e["dropdown__toggle--fluid"]]:b,[e["dropdown__toggle--open"]]:a}),U=v(e.dropdown__content,a&&e["dropdown__content--open"]);return t.createElement("div",{className:e.dropdown,ref:p},t.createElement("span",{id:E,className:e.dropdown__label},R),t.createElement("button",{type:"button",onClick:()=>!a&&N(),className:T,ref:m,"data-testid":z,"data-analyticsid":G.Dropdown,disabled:c,"aria-labelledby":I,"aria-haspopup":"listbox","aria-expanded":a},t.createElement("span",{id:I,className:e.dropdown__toggle__label},$),t.createElement(Y,{color:c?C.palette.neutral500:C.palette.blueberry600,svgIcon:Z,className:e.dropdown__icon,isHovered:B,size:J.XSmall})),t.createElement("div",{className:U,style:{width:b?"100%":`${L}px`}},t.createElement("ul",{className:e.dropdown__options,role:"listbox","aria-labelledby":E,tabIndex:-1,"aria-activedescendant":typeof u<"u"?`${x}-${u}`:void 0,ref:w},t.Children.map(y,(o,n)=>{var l;return t.createElement("li",{className:e.dropdown__input,role:"option",id:`${x}-${n}`,"aria-selected":n===u},t.cloneElement(o,{ref:(l=i.current)==null?void 0:l[n]}))})),!K&&t.createElement("div",{className:e.dropdown__close},t.createElement(Q,{onClick:f,fluid:!0,"aria-expanded":a},A))))},Re=ee;export{M as DropdownMode,Re as default};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["import React, { useRef, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n theme,\n useHover,\n useKeyboardEvent,\n useOutsideEvent,\n useSize,\n useToggle,\n useUuid,\n} from '../..';\nimport Button from '../Button';\nimport Icon from '../Icons';\nimport PlusSmall from '../Icons/PlusSmall';\n\nimport styles from './styles.module.scss';\n\nexport enum DropdownMode {\n onwhite = 'onwhite',\n ongrey = 'ongrey',\n onblueberry = 'onblueberry',\n oncherry = 'oncherry',\n}\n\nexport interface DropdownProps {\n /** Label for dropdown. Synlig for skjermlesere. */\n label: string;\n /** Tekst på knappen som åpner dropdownen */\n placeholder: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Close button text */\n closeText?: string;\n /** No close button */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed. */\n onToggle?: (isOpen: boolean) => void;\n /** Om dropdown er åpen */\n open?: boolean;\n /** Changes the visuals of the dropdown */\n mode?: keyof typeof DropdownMode;\n /** Makes the background transparent */\n transparent?: boolean;\n /** Makes the background transparent */\n fluid?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button. */\n testId?: string;\n}\n\nconst Dropdown: React.FC<DropdownProps> = props => {\n const {\n label,\n placeholder,\n closeText = 'Lukk',\n noCloseButton = false,\n onToggle,\n open = false,\n children,\n mode = DropdownMode.onwhite,\n transparent = false,\n fluid = false,\n testId,\n disabled,\n } = props;\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const { hoverRef: buttonRef, isHovered } = useHover<HTMLButtonElement>();\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const inputRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const [currentIndex, setCurrentIndex] = useState<number>();\n const { width: buttonWidth } = useSize(buttonRef) || {};\n const labelId = useUuid();\n const toggleLabelId = useUuid();\n const optionIdPrefix = useUuid();\n\n const handleOpen = () => {\n toggleIsOpen();\n optionsRef.current?.focus();\n };\n\n const handleClose = () => {\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n const handleKeyboardNavigation = (event: KeyboardEvent) => {\n event.preventDefault();\n\n if (!inputRefList.current) {\n return;\n }\n\n if (!isOpen) {\n handleOpen();\n return;\n } else if (event.key === KeyboardEventKey.Escape && isOpen) {\n handleClose();\n return;\n }\n\n const index = inputRefList.current.findIndex(x => x.current === event.target);\n let nextIndex = index;\n\n if (event.key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (event.key === KeyboardEventKey.End) {\n nextIndex = inputRefList.current.length - 1;\n } else if (event.key === KeyboardEventKey.ArrowDown && index < inputRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (event.key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n } else if (event.key === KeyboardEventKey.Enter && index !== -1) {\n nextIndex = index;\n }\n if (nextIndex !== -1) {\n inputRefList.current[nextIndex].current?.focus();\n setCurrentIndex(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 ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const toggleClasses = classNames(\n styles.dropdown__toggle,\n !disabled && {\n [styles['dropdown__toggle--on-white']]: mode === DropdownMode.onwhite,\n [styles['dropdown__toggle--on-grey']]: mode === DropdownMode.ongrey,\n [styles['dropdown__toggle--on-blueberry']]: mode === DropdownMode.onblueberry,\n [styles['dropdown__toggle--on-cherry']]: mode === DropdownMode.oncherry,\n [styles['dropdown__toggle--transparent']]: transparent,\n [styles['dropdown__toggle--fluid']]: fluid,\n [styles['dropdown__toggle--open']]: isOpen,\n }\n );\n\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <span id={labelId} className={styles.dropdown__label}>\n {label}\n </span>\n <button\n type=\"button\"\n onClick={() => !isOpen && handleOpen()}\n className={toggleClasses}\n ref={buttonRef}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleLabelId}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n >\n <span id={toggleLabelId} className={styles.dropdown__toggle__label}>\n {placeholder}\n </span>\n <Icon\n color={disabled ? theme.palette.neutral500 : theme.palette.blueberry600}\n svgIcon={PlusSmall}\n className={styles.dropdown__icon}\n isHovered={isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div className={contentClasses} style={{ width: fluid ? '100%' : `${buttonWidth}px` }}>\n <ul\n className={styles.dropdown__options}\n role=\"listbox\"\n aria-labelledby={labelId}\n tabIndex={-1}\n aria-activedescendant={typeof currentIndex !== 'undefined' ? `${optionIdPrefix}-${currentIndex}` : undefined}\n ref={optionsRef}\n >\n {React.Children.map(children, (child, index) => (\n <li className={styles.dropdown__input} role=\"option\" id={`${optionIdPrefix}-${index}`}>\n {React.cloneElement(child as React.ReactElement, { ref: inputRefList.current?.[index] })}\n </li>\n ))}\n </ul>\n {!noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose} fluid aria-expanded={isOpen}>\n {closeText}\n </Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default Dropdown;\n"],"names":["DropdownMode","Dropdown","props","label","placeholder","closeText","noCloseButton","onToggle","open","children","mode","transparent","fluid","testId","disabled","dropdownRef","useRef","optionsRef","buttonRef","isHovered","useHover","isOpen","toggleIsOpen","useToggle","inputRefList","React","currentIndex","setCurrentIndex","useState","buttonWidth","useSize","labelId","useUuid","toggleLabelId","optionIdPrefix","handleOpen","_a","handleClose","useKeyboardEvent","event","KeyboardEventKey","index","x","nextIndex","useOutsideEvent","toggleClasses","classNames","styles","contentClasses","AnalyticsId","Icon","theme","PlusSmall","IconSize","child","Button","Dropdown$1"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["import React, { useRef, useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n theme,\n useHover,\n useKeyboardEvent,\n useOutsideEvent,\n useSize,\n useToggle,\n useUuid,\n} from '../..';\nimport Button from '../Button';\nimport Icon from '../Icons';\nimport PlusSmall from '../Icons/PlusSmall';\n\nimport styles from './styles.module.scss';\n\nexport enum DropdownMode {\n onwhite = 'onwhite',\n ongrey = 'ongrey',\n onblueberry = 'onblueberry',\n oncherry = 'oncherry',\n}\n\nexport interface DropdownProps {\n /** Label for dropdown. Synlig for skjermlesere. */\n label: string;\n /** Tekst på knappen som åpner dropdownen */\n placeholder: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Close button text */\n closeText?: string;\n /** No close button */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed. */\n onToggle?: (isOpen: boolean) => void;\n /** Om dropdown er åpen */\n open?: boolean;\n /** Changes the visuals of the dropdown */\n mode?: keyof typeof DropdownMode;\n /** Makes the background transparent */\n transparent?: boolean;\n /** Makes the background transparent */\n fluid?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button. */\n testId?: string;\n}\n\nconst Dropdown: React.FC<DropdownProps> = props => {\n const {\n label,\n placeholder,\n closeText = 'Lukk',\n noCloseButton = false,\n onToggle,\n open = false,\n children,\n mode = DropdownMode.onwhite,\n transparent = false,\n fluid = false,\n testId,\n disabled,\n } = props;\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const { hoverRef: buttonRef, isHovered } = useHover<HTMLButtonElement>();\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const inputRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const [currentIndex, setCurrentIndex] = useState<number>();\n const { width: buttonWidth } = useSize(buttonRef) || {};\n const labelId = useUuid();\n const toggleLabelId = useUuid();\n const optionIdPrefix = useUuid();\n\n const handleOpen = () => {\n toggleIsOpen();\n optionsRef.current?.focus();\n };\n\n const handleClose = () => {\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n const handleKeyboardNavigation = (event: KeyboardEvent) => {\n event.preventDefault();\n\n if (!inputRefList.current) {\n return;\n }\n\n if (!isOpen) {\n handleOpen();\n return;\n } else if (event.key === KeyboardEventKey.Escape && isOpen) {\n handleClose();\n return;\n }\n\n const index = inputRefList.current.findIndex(x => x.current === event.target);\n let nextIndex = index;\n\n if (event.key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (event.key === KeyboardEventKey.End) {\n nextIndex = inputRefList.current.length - 1;\n } else if (event.key === KeyboardEventKey.ArrowDown && index < inputRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (event.key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n } else if (event.key === KeyboardEventKey.Enter && index !== -1) {\n nextIndex = index;\n }\n if (nextIndex !== -1) {\n inputRefList.current[nextIndex].current?.focus();\n setCurrentIndex(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 ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const toggleClasses = classNames(\n styles.dropdown__toggle,\n !disabled && {\n [styles['dropdown__toggle--on-white']]: mode === DropdownMode.onwhite,\n [styles['dropdown__toggle--on-grey']]: mode === DropdownMode.ongrey,\n [styles['dropdown__toggle--on-blueberry']]: mode === DropdownMode.onblueberry,\n [styles['dropdown__toggle--on-cherry']]: mode === DropdownMode.oncherry,\n [styles['dropdown__toggle--transparent']]: transparent,\n [styles['dropdown__toggle--fluid']]: fluid,\n [styles['dropdown__toggle--open']]: isOpen,\n }\n );\n\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <span id={labelId} className={styles.dropdown__label}>\n {label}\n </span>\n <button\n type=\"button\"\n onClick={() => !isOpen && handleOpen()}\n className={toggleClasses}\n ref={buttonRef}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleLabelId}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n >\n <span id={toggleLabelId} className={styles.dropdown__toggle__label}>\n {placeholder}\n </span>\n <Icon\n color={disabled ? theme.palette.neutral500 : theme.palette.blueberry600}\n svgIcon={PlusSmall}\n className={styles.dropdown__icon}\n isHovered={isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div className={contentClasses} style={{ width: fluid ? '100%' : `${buttonWidth}px` }}>\n <ul\n className={styles.dropdown__options}\n role=\"listbox\"\n aria-labelledby={labelId}\n tabIndex={-1}\n aria-activedescendant={typeof currentIndex !== 'undefined' ? `${optionIdPrefix}-${currentIndex}` : undefined}\n ref={optionsRef}\n >\n {React.Children.map(children, (child, index) => (\n <li className={styles.dropdown__input} role=\"option\" id={`${optionIdPrefix}-${index}`} aria-selected={index === currentIndex}>\n {React.cloneElement(child as React.ReactElement, { ref: inputRefList.current?.[index] })}\n </li>\n ))}\n </ul>\n {!noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose} fluid aria-expanded={isOpen}>\n {closeText}\n </Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default Dropdown;\n"],"names":["DropdownMode","Dropdown","props","label","placeholder","closeText","noCloseButton","onToggle","open","children","mode","transparent","fluid","testId","disabled","dropdownRef","useRef","optionsRef","buttonRef","isHovered","useHover","isOpen","toggleIsOpen","useToggle","inputRefList","React","currentIndex","setCurrentIndex","useState","buttonWidth","useSize","labelId","useUuid","toggleLabelId","optionIdPrefix","handleOpen","_a","handleClose","useKeyboardEvent","event","KeyboardEventKey","index","x","nextIndex","useOutsideEvent","toggleClasses","classNames","styles","contentClasses","AnalyticsId","Icon","theme","PlusSmall","IconSize","child","Button","Dropdown$1"],"mappings":"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"}