@helsenorge/designsystem-react 12.5.0 → 12.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/FormFieldTag.js +48 -0
- package/FormFieldTag.js.map +1 -0
- package/FormGroup.js +11 -3
- package/FormGroup.js.map +1 -1
- package/Label.js +3 -0
- package/Label.js.map +1 -1
- package/components/FormFieldTag/FormFieldTag.d.ts +15 -0
- package/components/FormFieldTag/FormFieldTag.test.d.ts +1 -0
- package/components/FormFieldTag/index.d.ts +3 -0
- package/components/FormFieldTag/index.js +5 -0
- package/components/FormFieldTag/index.js.map +1 -0
- package/components/FormFieldTag/resourceHelper.d.ts +3 -0
- package/components/FormFieldTag/styles.module.scss +23 -0
- package/components/FormFieldTag/styles.module.scss.d.ts +10 -0
- package/components/FormGroup/FormGroup.d.ts +2 -0
- package/components/FormGroup/styles.module.scss +3 -0
- package/components/Label/Label.d.ts +2 -0
- package/components/StickyNote/Close.d.ts +11 -0
- package/components/StickyNote/Triangle.d.ts +5 -1
- package/components/StickyNote/index.js +100 -49
- package/components/StickyNote/index.js.map +1 -1
- package/components/StickyNote/styles.module.scss +106 -34
- package/components/StickyNote/styles.module.scss.d.ts +6 -1
- package/constants.d.ts +1 -0
- package/constants.js +1 -0
- package/constants.js.map +1 -1
- package/designsystem-react.css +136 -98
- package/package.json +1 -1
- package/resources/HN.Designsystem.FormFieldTag.nb-NO.json.d.ts +8 -0
- package/scss/supernova/styles/colors.css +136 -98
- package/scss/supernova/styles/typography.css +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
## [12.7.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.6.4&targetVersion=GTv12.7.0) (2025-10-17)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
- **formgroup:** endre prop for FormFieldTag til å være lik som i label
|
|
6
|
+
([850b4e0](https://github.com/helsenorge/designsystem/commit/850b4e0cdc5888dbe29ba894c23e460dfe9d4930)), closes
|
|
7
|
+
[#362503](https://github.com/helsenorge/designsystem/issues/362503)
|
|
8
|
+
|
|
9
|
+
## [12.6.4](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.6.3&targetVersion=GTv12.6.4) (2025-10-16)
|
|
10
|
+
|
|
11
|
+
### Reverts
|
|
12
|
+
|
|
13
|
+
- Revert "v12.6.3" ([973e6b8](https://github.com/helsenorge/designsystem/commit/973e6b8893fc765892a993adf83d93f4d5bfd5dd))
|
|
14
|
+
|
|
15
|
+
## [12.6.3](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.6.2&targetVersion=GTv12.6.3) (2025-10-16)
|
|
16
|
+
|
|
17
|
+
## [12.6.2](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.6.1&targetVersion=GTv12.6.2) (2025-10-16)
|
|
18
|
+
|
|
19
|
+
## [12.6.1](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.6.0&targetVersion=GTv12.6.1) (2025-10-16)
|
|
20
|
+
|
|
21
|
+
## [12.6.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.5.0&targetVersion=GTv12.6.0) (2025-10-16)
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
- **formfieldtag:** ny komponent for å markere obligatoriske felter
|
|
26
|
+
([43186e8](https://github.com/helsenorge/designsystem/commit/43186e85e06d6b3e34124c3afd372180ecff9af9)), closes
|
|
27
|
+
[#361861](https://github.com/helsenorge/designsystem/issues/361861)
|
|
28
|
+
- **stickynote:** justeringer etter ny figma komponent
|
|
29
|
+
([b3afb5a](https://github.com/helsenorge/designsystem/commit/b3afb5a41f1400bef0afce40b244deafcac7b505)), closes
|
|
30
|
+
[#361520](https://github.com/helsenorge/designsystem/issues/361520)
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
- **formfieldtag:** fiks display for at den holder seg i riktig størrelse
|
|
35
|
+
([1e53dc1](https://github.com/helsenorge/designsystem/commit/1e53dc1cf52215a3476a1d6d86c36f8108b0fbc1)), closes
|
|
36
|
+
[#361861](https://github.com/helsenorge/designsystem/issues/361861)
|
|
37
|
+
- **label:** bruk formfieldtag som komponent slik at man får satt id
|
|
38
|
+
([006e152](https://github.com/helsenorge/designsystem/commit/006e1520cc16b66f637c11c193902510ebd72b76)), closes
|
|
39
|
+
[#361861](https://github.com/helsenorge/designsystem/issues/361861)
|
|
40
|
+
|
|
1
41
|
## [12.5.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.4.0&targetVersion=GTv12.5.0) (2025-10-08)
|
|
2
42
|
|
|
3
43
|
### Features
|
package/FormFieldTag.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import { LanguageLocales, AnalyticsId } from "./constants.js";
|
|
4
|
+
import { useLanguage } from "./utils/language.js";
|
|
5
|
+
import styles from "./components/FormFieldTag/styles.module.scss";
|
|
6
|
+
const allRequired = "Alle felt må fylles ut";
|
|
7
|
+
const requiredField = "Må fylles ut";
|
|
8
|
+
const optional = "Valgfritt";
|
|
9
|
+
const nbNO = {
|
|
10
|
+
allRequired,
|
|
11
|
+
requiredField,
|
|
12
|
+
optional
|
|
13
|
+
};
|
|
14
|
+
const getResources = (language) => {
|
|
15
|
+
switch (language) {
|
|
16
|
+
case LanguageLocales.NORWEGIAN:
|
|
17
|
+
default:
|
|
18
|
+
return nbNO;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const FormFieldTag = (props) => {
|
|
22
|
+
const { id, level, resources, testId } = props;
|
|
23
|
+
const { language } = useLanguage(LanguageLocales.NORWEGIAN);
|
|
24
|
+
const defaultResources = getResources(language);
|
|
25
|
+
const mergedResources = {
|
|
26
|
+
...defaultResources,
|
|
27
|
+
...resources
|
|
28
|
+
};
|
|
29
|
+
const textMap = {
|
|
30
|
+
"all-required": mergedResources.allRequired,
|
|
31
|
+
"required-field": mergedResources.requiredField,
|
|
32
|
+
optional: mergedResources.optional
|
|
33
|
+
};
|
|
34
|
+
return /* @__PURE__ */ jsx(
|
|
35
|
+
"span",
|
|
36
|
+
{
|
|
37
|
+
id,
|
|
38
|
+
"data-testid": testId,
|
|
39
|
+
"data-analyticsid": AnalyticsId.FormFieldTag,
|
|
40
|
+
className: classNames(styles["form-field-tag"], { [styles["form-field-tag--optional"]]: level === "optional" }),
|
|
41
|
+
children: textMap[level]
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
FormFieldTag as F
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=FormFieldTag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormFieldTag.js","sources":["../src/components/FormFieldTag/resourceHelper.ts","../src/components/FormFieldTag/FormFieldTag.tsx"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport nbNO from '../../resources/HN.Designsystem.FormFieldTag.nb-NO.json';\nimport { HNDesignsystemFormFieldTag } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemFormFieldTag => {\n switch (language) {\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { getResources } from './resourceHelper';\nimport { AnalyticsId, LanguageLocales } from '../../constants';\nimport { HNDesignsystemFormFieldTag } from '../../resources/Resources';\nimport { useLanguage } from '../../utils/language';\n\nimport styles from './styles.module.scss';\n\nexport type FormFieldTagLevel = 'all-required' | 'required-field' | 'optional';\n\nexport interface FormFieldTagProps {\n /** Id that is placed on the component */\n id?: string;\n /** What level is the required tag, sets the styling and the text. */\n level: FormFieldTagLevel;\n /** Texts if overriding SOT */\n resources?: HNDesignsystemFormFieldTag;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nconst FormFieldTag: React.FC<FormFieldTagProps> = props => {\n const { id, level, resources, testId } = props;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemFormFieldTag = {\n ...defaultResources,\n ...resources,\n };\n\n const textMap = {\n 'all-required': mergedResources.allRequired,\n 'required-field': mergedResources.requiredField,\n optional: mergedResources.optional,\n };\n\n return (\n <span\n id={id}\n data-testid={testId}\n data-analyticsid={AnalyticsId.FormFieldTag}\n className={classNames(styles['form-field-tag'], { [styles['form-field-tag--optional']]: level === 'optional' })}\n >\n {textMap[level]}\n </span>\n );\n};\n\nexport default FormFieldTag;\n"],"names":[],"mappings":";;;;;;;;;;;;;AAIO,MAAM,eAAe,CAAC,aAA0D;AACrF,UAAQ,UAAA;AAAA,IACN,KAAK,gBAAgB;AAAA,IACrB;AACE,aAAO;AAAA,EAAA;AAEb;ACcA,MAAM,eAA4C,CAAA,UAAS;AACzD,QAAM,EAAE,IAAI,OAAO,WAAW,WAAW;AAEzC,QAAM,EAAE,SAAA,IAAa,YAA6B,gBAAgB,SAAS;AAC3E,QAAM,mBAAmB,aAAa,QAAQ;AAE9C,QAAM,kBAA8C;AAAA,IAClD,GAAG;AAAA,IACH,GAAG;AAAA,EAAA;AAGL,QAAM,UAAU;AAAA,IACd,gBAAgB,gBAAgB;AAAA,IAChC,kBAAkB,gBAAgB;AAAA,IAClC,UAAU,gBAAgB;AAAA,EAAA;AAG5B,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,eAAa;AAAA,MACb,oBAAkB,YAAY;AAAA,MAC9B,WAAW,WAAW,OAAO,gBAAgB,GAAG,EAAE,CAAC,OAAO,0BAA0B,CAAC,GAAG,UAAU,YAAY;AAAA,MAE7G,kBAAQ,KAAK;AAAA,IAAA;AAAA,EAAA;AAGpB;"}
|
package/FormGroup.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React__default, { useState } from "react";
|
|
3
3
|
import classNames from "classnames";
|
|
4
4
|
import { FormOnColor, FormSize, AnalyticsId } from "./constants.js";
|
|
@@ -6,6 +6,7 @@ import { useUuid } from "./hooks/useUuid.js";
|
|
|
6
6
|
import { isComponent } from "./utils/component.js";
|
|
7
7
|
import { C as Checkbox } from "./Checkbox.js";
|
|
8
8
|
import { E as ErrorWrapper } from "./ErrorWrapper.js";
|
|
9
|
+
import { F as FormFieldTag } from "./FormFieldTag.js";
|
|
9
10
|
import { F as FormLayout } from "./FormLayout.js";
|
|
10
11
|
import { I as Input } from "./Input.js";
|
|
11
12
|
import { R as RadioButton, g as getRadioLabelClasses } from "./RadioButton.js";
|
|
@@ -19,6 +20,7 @@ const FormGroup = React__default.forwardRef((props, ref) => {
|
|
|
19
20
|
ariaLabelledBy,
|
|
20
21
|
className,
|
|
21
22
|
fieldsetClassName,
|
|
23
|
+
formFieldTag,
|
|
22
24
|
legendClassName,
|
|
23
25
|
onColor = FormOnColor.onwhite,
|
|
24
26
|
size = FormSize.medium,
|
|
@@ -118,11 +120,17 @@ const FormGroup = React__default.forwardRef((props, ref) => {
|
|
|
118
120
|
const formGroupContent = () => {
|
|
119
121
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
120
122
|
htmlMarkup === "div" && /* @__PURE__ */ jsxs("div", { className: fieldsetClasses, children: [
|
|
121
|
-
props.legend && /* @__PURE__ */ jsx("h5", { className: legendClasses, children:
|
|
123
|
+
props.legend && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("h5", { className: legendClasses, children: [
|
|
124
|
+
props.legend,
|
|
125
|
+
formFieldTag && isComponent(formFieldTag, FormFieldTag) && React__default.cloneElement(formFieldTag)
|
|
126
|
+
] }) }),
|
|
122
127
|
React__default.Children.map(props.children, mapFormComponent)
|
|
123
128
|
] }),
|
|
124
129
|
htmlMarkup === "fieldset" && /* @__PURE__ */ jsxs("fieldset", { "aria-labelledby": ariaLabelledBy, name: props.fieldsetName, className: fieldsetClasses, children: [
|
|
125
|
-
props.legend && /* @__PURE__ */ jsx("legend", { className: legendClasses, children:
|
|
130
|
+
props.legend && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("legend", { className: legendClasses, children: [
|
|
131
|
+
props.legend,
|
|
132
|
+
formFieldTag && isComponent(formFieldTag, FormFieldTag) && React__default.cloneElement(formFieldTag)
|
|
133
|
+
] }) }),
|
|
126
134
|
React__default.Children.map(props.children, mapFormComponent)
|
|
127
135
|
] })
|
|
128
136
|
] });
|
package/FormGroup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormGroup.js","sources":["../src/components/FormGroup/FormGroup.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, FormOnColor, FormSize } from '../../constants';\nimport { useUuid } from '../../hooks/useUuid';\nimport { isComponent } from '../../utils/component';\nimport Checkbox, { CheckboxProps } from '../Checkbox/Checkbox';\nimport ErrorWrapper from '../ErrorWrapper';\nimport FormLayout, { FormLayoutProps } from '../FormLayout';\nimport Input, { InputProps } from '../Input/Input';\nimport RadioButton, { RadioButtonProps, getRadioLabelClasses } from '../RadioButton/RadioButton';\nimport Select, { SelectProps } from '../Select';\nimport Slider, { SliderProps } from '../Slider';\nimport Textarea, { TextareaProps } from '../Textarea';\nimport Title from '../Title';\n\nimport formGroupStyles from './styles.module.scss';\n\nexport type FormGroupTags = 'fieldset' | 'div';\n\nexport interface FormGroupProps {\n /** Can be used as a replacement text for legend in cases where the group title already exists externally */\n ariaLabelledBy?: string;\n /** title for the the fieldset */\n title?: string;\n /** text placed in the legend tag of the fieldset */\n legend?: string;\n /** Items in the FormGroup component */\n children?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds custom classes to the errorWrapper. */\n errorWrapperClassName?: string;\n /** Adds custom classes to the fieldset element. */\n fieldsetClassName?: string;\n /** Adds custom classes to the legend element. */\n legendClassName?: string;\n /** Changes the visuals of the formgroup */\n onColor?: keyof typeof FormOnColor;\n /** Changes the visuals of the formgroup */\n size?: keyof typeof FormSize;\n /** Error message */\n error?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the data-testid attribute for the error-wrapper. */\n errorWrapperTestId?: string;\n /** Unique name for the child input element */\n name?: string;\n /** Unique name for the fieldset */\n fieldsetName?: string;\n /** Sets div instead of fieldset tag */\n htmlMarkup?: FormGroupTags;\n /** Renders the error component (Default: true) */\n renderError?: boolean;\n}\n\nexport const FormGroup = React.forwardRef((props: FormGroupProps, ref: React.ForwardedRef<HTMLDivElement>) => {\n const {\n ariaLabelledBy,\n className,\n fieldsetClassName,\n legendClassName,\n onColor = FormOnColor.onwhite,\n size = FormSize.medium,\n error,\n errorTextId,\n name,\n htmlMarkup = 'fieldset',\n renderError = true,\n errorWrapperClassName,\n errorWrapperTestId,\n } = props;\n const [checkedRadioId, setCheckedRadioId] = useState<string>();\n const radioGroupId = useUuid();\n const errorTextUuid = useUuid(errorTextId);\n const onDark = onColor === FormOnColor.ondark;\n const isLarge = size === FormSize.large;\n const formGroupWrapperClasses = classNames(formGroupStyles['form-group-wrapper'], className);\n const titleClasses = classNames({\n [formGroupStyles['form-group-wrapper__title--on-dark']]: onDark && !error,\n });\n\n const legendClasses = classNames(\n formGroupStyles['field-set__legend'],\n {\n [formGroupStyles['field-set__legend--on-dark']]: onDark && !error,\n },\n legendClassName\n );\n\n const fieldsetClasses = classNames(formGroupStyles['field-set'], fieldsetClassName);\n\n const mapFormComponent = (child: React.ReactNode, index: number): React.ReactNode => {\n if (isComponent<FormLayoutProps>(child, FormLayout)) {\n return React.cloneElement(child, {\n size,\n mapHelper: mapFormComponent,\n });\n } else if (isComponent<FormGroupProps>(child, FormGroup)) {\n return React.cloneElement(child, {\n onColor,\n size,\n error,\n renderError: false,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<CheckboxProps>(child, Checkbox)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n size,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<RadioButtonProps>(child, RadioButton)) {\n const radioId = typeof child.props.inputId === 'undefined' ? radioGroupId + index : child.props.inputId;\n return React.cloneElement(child, {\n inputId: radioId,\n name: name ?? child.props.name,\n onColor,\n size,\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => {\n setCheckedRadioId(event.target.id);\n if (child.props.onChange) child.props.onChange(event);\n },\n error: !!error,\n errorTextId: errorTextUuid,\n labelClassNames: getRadioLabelClasses(radioId, onColor as FormOnColor, isLarge, checkedRadioId),\n });\n } else if (isComponent<InputProps>(child, Input)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n size,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<TextareaProps>(child, Textarea)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<SelectProps>(child, Select)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<SliderProps>(child, Slider)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n }\n return child;\n };\n\n const formGroupContent = (): React.ReactNode => {\n return (\n <div>\n {htmlMarkup === 'div' && (\n <div className={fieldsetClasses}>\n {props.legend && <h5 className={legendClasses}>{props.legend}</h5>}\n {React.Children.map(props.children, mapFormComponent)}\n </div>\n )}\n {htmlMarkup === 'fieldset' && (\n <fieldset aria-labelledby={ariaLabelledBy} name={props.fieldsetName} className={fieldsetClasses}>\n {props.legend && <legend className={legendClasses}>{props.legend}</legend>}\n {React.Children.map(props.children, mapFormComponent)}\n </fieldset>\n )}\n </div>\n );\n };\n\n return (\n <div data-testid={props.testId} data-analyticsid={AnalyticsId.FormGroup} className={formGroupWrapperClasses}>\n {props.title && (\n <Title className={titleClasses} htmlMarkup={'h4'} appearance={'title4'} margin={{ marginTop: 0, marginBottom: error ? 1 : 2 }}>\n {props.title}\n </Title>\n )}\n <ErrorWrapper\n className={errorWrapperClassName}\n errorText={error}\n testId={errorWrapperTestId}\n errorTextId={errorTextUuid}\n errorMessageRef={ref}\n renderError={renderError}\n >\n {formGroupContent()}\n </ErrorWrapper>\n </div>\n );\n});\n\nFormGroup.displayName = 'FormGroup';\n\nexport default FormGroup;\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FormGroup.js","sources":["../src/components/FormGroup/FormGroup.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, FormOnColor, FormSize } from '../../constants';\nimport { useUuid } from '../../hooks/useUuid';\nimport { isComponent } from '../../utils/component';\nimport Checkbox, { CheckboxProps } from '../Checkbox/Checkbox';\nimport ErrorWrapper from '../ErrorWrapper';\nimport FormFieldTag, { FormFieldTagProps } from '../FormFieldTag';\nimport FormLayout, { FormLayoutProps } from '../FormLayout';\nimport Input, { InputProps } from '../Input/Input';\nimport RadioButton, { RadioButtonProps, getRadioLabelClasses } from '../RadioButton/RadioButton';\nimport Select, { SelectProps } from '../Select';\nimport Slider, { SliderProps } from '../Slider';\nimport Textarea, { TextareaProps } from '../Textarea';\nimport Title from '../Title';\n\nimport formGroupStyles from './styles.module.scss';\n\nexport type FormGroupTags = 'fieldset' | 'div';\n\nexport interface FormGroupProps {\n /** Can be used as a replacement text for legend in cases where the group title already exists externally */\n ariaLabelledBy?: string;\n /** title for the the fieldset */\n title?: string;\n /** text placed in the legend tag of the fieldset */\n legend?: string;\n /** Items in the FormGroup component */\n children?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds custom classes to the errorWrapper. */\n errorWrapperClassName?: string;\n /** Adds custom classes to the fieldset element. */\n fieldsetClassName?: string;\n /** Sets a tag that describes whether the form group is required or optional */\n formFieldTag?: React.ReactNode;\n /** Adds custom classes to the legend element. */\n legendClassName?: string;\n /** Changes the visuals of the formgroup */\n onColor?: keyof typeof FormOnColor;\n /** Changes the visuals of the formgroup */\n size?: keyof typeof FormSize;\n /** Error message */\n error?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the data-testid attribute for the error-wrapper. */\n errorWrapperTestId?: string;\n /** Unique name for the child input element */\n name?: string;\n /** Unique name for the fieldset */\n fieldsetName?: string;\n /** Sets div instead of fieldset tag */\n htmlMarkup?: FormGroupTags;\n /** Renders the error component (Default: true) */\n renderError?: boolean;\n}\n\nexport const FormGroup = React.forwardRef((props: FormGroupProps, ref: React.ForwardedRef<HTMLDivElement>) => {\n const {\n ariaLabelledBy,\n className,\n fieldsetClassName,\n formFieldTag,\n legendClassName,\n onColor = FormOnColor.onwhite,\n size = FormSize.medium,\n error,\n errorTextId,\n name,\n htmlMarkup = 'fieldset',\n renderError = true,\n errorWrapperClassName,\n errorWrapperTestId,\n } = props;\n const [checkedRadioId, setCheckedRadioId] = useState<string>();\n const radioGroupId = useUuid();\n const errorTextUuid = useUuid(errorTextId);\n const onDark = onColor === FormOnColor.ondark;\n const isLarge = size === FormSize.large;\n const formGroupWrapperClasses = classNames(formGroupStyles['form-group-wrapper'], className);\n const titleClasses = classNames({\n [formGroupStyles['form-group-wrapper__title--on-dark']]: onDark && !error,\n });\n\n const legendClasses = classNames(\n formGroupStyles['field-set__legend'],\n {\n [formGroupStyles['field-set__legend--on-dark']]: onDark && !error,\n },\n legendClassName\n );\n\n const fieldsetClasses = classNames(formGroupStyles['field-set'], fieldsetClassName);\n\n const mapFormComponent = (child: React.ReactNode, index: number): React.ReactNode => {\n if (isComponent<FormLayoutProps>(child, FormLayout)) {\n return React.cloneElement(child, {\n size,\n mapHelper: mapFormComponent,\n });\n } else if (isComponent<FormGroupProps>(child, FormGroup)) {\n return React.cloneElement(child, {\n onColor,\n size,\n error,\n renderError: false,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<CheckboxProps>(child, Checkbox)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n size,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<RadioButtonProps>(child, RadioButton)) {\n const radioId = typeof child.props.inputId === 'undefined' ? radioGroupId + index : child.props.inputId;\n return React.cloneElement(child, {\n inputId: radioId,\n name: name ?? child.props.name,\n onColor,\n size,\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => {\n setCheckedRadioId(event.target.id);\n if (child.props.onChange) child.props.onChange(event);\n },\n error: !!error,\n errorTextId: errorTextUuid,\n labelClassNames: getRadioLabelClasses(radioId, onColor as FormOnColor, isLarge, checkedRadioId),\n });\n } else if (isComponent<InputProps>(child, Input)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n size,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<TextareaProps>(child, Textarea)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<SelectProps>(child, Select)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n onColor,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n } else if (isComponent<SliderProps>(child, Slider)) {\n return React.cloneElement(child, {\n name: name ?? child.props.name,\n error: !!error,\n errorTextId: errorTextUuid,\n });\n }\n return child;\n };\n\n const formGroupContent = (): React.ReactNode => {\n return (\n <div>\n {htmlMarkup === 'div' && (\n <div className={fieldsetClasses}>\n {props.legend && (\n <>\n <h5 className={legendClasses}>\n {props.legend}\n {formFieldTag && isComponent<FormFieldTagProps>(formFieldTag, FormFieldTag) && React.cloneElement(formFieldTag)}\n </h5>\n </>\n )}\n {React.Children.map(props.children, mapFormComponent)}\n </div>\n )}\n {htmlMarkup === 'fieldset' && (\n <fieldset aria-labelledby={ariaLabelledBy} name={props.fieldsetName} className={fieldsetClasses}>\n {props.legend && (\n <>\n <legend className={legendClasses}>\n {props.legend}\n {formFieldTag && isComponent<FormFieldTagProps>(formFieldTag, FormFieldTag) && React.cloneElement(formFieldTag)}\n </legend>\n </>\n )}\n {React.Children.map(props.children, mapFormComponent)}\n </fieldset>\n )}\n </div>\n );\n };\n\n return (\n <div data-testid={props.testId} data-analyticsid={AnalyticsId.FormGroup} className={formGroupWrapperClasses}>\n {props.title && (\n <Title className={titleClasses} htmlMarkup={'h4'} appearance={'title4'} margin={{ marginTop: 0, marginBottom: error ? 1 : 2 }}>\n {props.title}\n </Title>\n )}\n <ErrorWrapper\n className={errorWrapperClassName}\n errorText={error}\n testId={errorWrapperTestId}\n errorTextId={errorTextUuid}\n errorMessageRef={ref}\n renderError={renderError}\n >\n {formGroupContent()}\n </ErrorWrapper>\n </div>\n );\n});\n\nFormGroup.displayName = 'FormGroup';\n\nexport default FormGroup;\n"],"names":["React"],"mappings":"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"}
|
package/Label.js
CHANGED
|
@@ -5,6 +5,7 @@ import { AnalyticsId, FormOnColor } from "./constants.js";
|
|
|
5
5
|
import { S as Spacer } from "./Spacer.js";
|
|
6
6
|
import styles from "./components/Label/styles.module.scss";
|
|
7
7
|
import { isComponent } from "./utils/component.js";
|
|
8
|
+
import { F as FormFieldTag } from "./FormFieldTag.js";
|
|
8
9
|
import { S as StatusDot } from "./StatusDot.js";
|
|
9
10
|
const Sublabel = ({ children, className, id, onColor, sublabelTexts, testId }) => {
|
|
10
11
|
const mapSublabels = (hideFromScreenReader) => {
|
|
@@ -73,6 +74,7 @@ const Label = ({
|
|
|
73
74
|
afterLabelChildren,
|
|
74
75
|
children,
|
|
75
76
|
className,
|
|
77
|
+
formFieldTag,
|
|
76
78
|
htmlFor,
|
|
77
79
|
htmlMarkup = "label",
|
|
78
80
|
labelClassName,
|
|
@@ -113,6 +115,7 @@ const Label = ({
|
|
|
113
115
|
/* @__PURE__ */ jsx("span", { className: styles.label__texts, children: mapLabels() })
|
|
114
116
|
] }) }),
|
|
115
117
|
/* @__PURE__ */ jsxs("div", { className: sublabelWrapperClassName, children: [
|
|
118
|
+
formFieldTag && isComponent(formFieldTag, FormFieldTag) && React__default.cloneElement(formFieldTag),
|
|
116
119
|
sublabel && isComponent(sublabel, Sublabel) && React__default.cloneElement(sublabel, {
|
|
117
120
|
onColor
|
|
118
121
|
}),
|
package/Label.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Label.js","sources":["../src/components/Label/SubLabel.tsx","../src/components/Label/Label.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport { LabelText } from './Label';\nimport { AnalyticsId, FormOnColor } from '../../constants';\nimport Spacer from '../Spacer';\n\nimport styles from './styles.module.scss';\n\nexport interface SublabelProps {\n /** Sets the content of the Sublabel */\n children?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** id that is placed on the wrapper */\n id: string;\n /** Array of sublabel strings. Can be of type semibold or normal */\n onColor?: FormOnColor;\n /** Array of sublabel strings. Can be of type semibold or normal */\n sublabelTexts?: LabelText[];\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const Sublabel: React.FC<SublabelProps> = ({ children, className, id, onColor, sublabelTexts, testId }) => {\n const mapSublabels = (hideFromScreenReader?: boolean): React.ReactNode => {\n return (\n sublabelTexts &&\n sublabelTexts.map((sublabelText, index) => {\n const labelClasses = cn(styles.label, styles['sublabel'], {\n [styles['sublabel--subdued']]: sublabelText.type === 'subdued',\n [styles['sublabel--on-dark']]: onColor === FormOnColor.ondark,\n });\n return (\n hideFromScreenReader === sublabelText.hideFromScreenReader && (\n <span className={labelClasses} key={index}>\n {sublabelText.text}\n </span>\n )\n );\n })\n );\n };\n\n const subLabels = mapSublabels();\n const ariaHiddenSublabels = mapSublabels(true);\n\n return (\n <>\n <Spacer size={'3xs'} />\n {(subLabels || children) && (\n <div className={className} id={id} data-testid={testId} data-analyticsid={AnalyticsId.Sublabel}>\n {subLabels}\n {children}\n </div>\n )}\n {ariaHiddenSublabels && (\n <div className={className} data-testid={testId}>\n {ariaHiddenSublabels}\n </div>\n )}\n </>\n );\n};\n","import React, { FunctionComponent } from 'react';\n\nimport cn from 'classnames';\n\nimport { Sublabel, SublabelProps } from './SubLabel';\nimport { AnalyticsId, FormOnColor } from '../../constants';\nimport { isComponent } from '../../utils/component';\nimport Spacer from '../Spacer';\nimport StatusDot, { StatusDotProps } from '../StatusDot';\n\nimport styles from './styles.module.scss';\n\nexport type LabelText = {\n hideFromScreenReader?: boolean;\n text: string;\n type?: 'normal' | 'subdued';\n};\n\nexport type LabelTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | 'label' | 'p';\n\nexport interface LabelProps {\n /** Component shown after label - discourage use of this */\n afterLabelChildren?: React.ReactNode;\n /** Sets the content of the Label */\n children?: React.ReactNode;\n /** Adds custom classes to the label tag. */\n labelClassName?: string;\n /** Adds custom classes to the label text. */\n labelTextClassName?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Id that is put on the \"for\" attribute of the label */\n htmlFor?: string;\n /** Changes the underlying element of the label */\n htmlMarkup?: LabelTags;\n /** Id som plasseres på <label/> */\n labelId?: string;\n /** Array of main label strings. Can be of type semibold or normal */\n labelTexts?: LabelText[];\n /** Array of sublabel strings. Can be of type semibold or normal */\n onColor?: keyof typeof FormOnColor;\n /** StatusDot placed underneath the last sublabel */\n statusDot?: React.ReactNode;\n /** Sublabel component */\n sublabel?: React.ReactNode;\n /** Adds custom classes to the div wrapping the sublabels. */\n sublabelWrapperClassName?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const getLabelText = (label: React.ReactNode): string => {\n let allLabelText = '';\n\n if (isComponent<LabelProps>(label, Label)) {\n label.props.labelTexts?.forEach(labelText => {\n allLabelText += !labelText.hideFromScreenReader ? labelText.text : '';\n });\n }\n\n return allLabelText;\n};\n\nexport const renderLabel = (label: React.ReactNode, inputId: string, onColor: FormOnColor, markup?: LabelTags): React.ReactNode => {\n return (\n <>\n {label && isComponent<LabelProps>(label, Label)\n ? React.cloneElement(label, {\n htmlFor: inputId,\n htmlMarkup: markup || 'label',\n onColor,\n })\n : typeof label === 'string' && <Label labelTexts={[{ text: label, type: 'normal' }]} htmlFor={inputId} onColor={onColor} />}\n </>\n );\n};\n\nexport const renderLabelAsParent = (\n label: React.ReactNode,\n children: React.ReactNode,\n inputId: string,\n onColor: FormOnColor,\n labelClassName?: string,\n labelTextClassName?: string,\n sublabelWrapperClassName?: string,\n large?: boolean,\n markup?: LabelTags\n): React.ReactNode => {\n return (\n <>\n {label && isComponent<LabelProps>(label, Label)\n ? React.cloneElement(label, {\n htmlFor: inputId,\n onColor,\n children: children,\n labelClassName: cn(labelClassName, label.props.labelClassName),\n labelTextClassName: labelTextClassName,\n htmlMarkup: markup || 'label',\n sublabelWrapperClassName: sublabelWrapperClassName,\n sublabel: large ? undefined : label.props.sublabel,\n statusDot: large ? undefined : label.props.statusDot,\n })\n : typeof label === 'string' && (\n <Label\n labelTexts={[{ text: label, type: 'subdued' }]}\n htmlFor={inputId}\n onColor={onColor}\n htmlMarkup={markup || 'label'}\n labelClassName={labelClassName}\n labelTextClassName={labelTextClassName}\n sublabelWrapperClassName={sublabelWrapperClassName}\n >\n {children}\n </Label>\n )}\n </>\n );\n};\n\nconst Label: FunctionComponent<LabelProps> = ({\n afterLabelChildren,\n children,\n className,\n htmlFor,\n htmlMarkup = 'label',\n labelClassName,\n labelTextClassName,\n labelId,\n labelTexts,\n onColor = FormOnColor.onwhite,\n statusDot,\n sublabel,\n sublabelWrapperClassName,\n testId,\n}) => {\n const hasChildren = children && typeof children !== 'undefined';\n const labelWrapperClasses = cn(\n styles['label-wrapper'],\n { [styles['label-wrapper--no-bottom-margin']]: hasChildren, [styles['label-wrapper--after-label-children']]: afterLabelChildren },\n className\n );\n\n const mapLabels = (): React.ReactNode => {\n if (typeof labelTexts === 'undefined') return null;\n\n return labelTexts.map((labelText, index) => {\n const labelClasses = cn(\n styles.label,\n {\n [styles['label--subdued']]: labelText.type === 'subdued',\n [styles['label--on-dark']]: onColor === FormOnColor.ondark,\n },\n labelTextClassName\n );\n return (\n <span aria-hidden={labelText.hideFromScreenReader} className={labelClasses} key={index}>\n {labelText.text}\n </span>\n );\n });\n };\n const CustomTag = htmlMarkup;\n\n return (\n <div className={labelWrapperClasses}>\n <div>\n <CustomTag className={labelClassName} id={labelId} htmlFor={htmlFor} data-testid={testId} data-analyticsid={AnalyticsId.Label}>\n <span className={styles['label-content-wrapper']}>\n {children}\n <span className={styles.label__texts}>{mapLabels()}</span>\n </span>\n </CustomTag>\n <div className={sublabelWrapperClassName}>\n {sublabel &&\n isComponent<SublabelProps>(sublabel, Sublabel) &&\n React.cloneElement(sublabel, {\n onColor: onColor as FormOnColor,\n })}\n {statusDot && isComponent<StatusDotProps>(statusDot, StatusDot) && (\n <>\n <Spacer size={'3xs'} />\n {React.cloneElement(statusDot, {\n onColor: onColor === FormOnColor.ondark ? 'ondark' : 'onwhite',\n })}\n </>\n )}\n </div>\n </div>\n {afterLabelChildren && <div className={styles['after-label-children']}>{afterLabelChildren}</div>}\n </div>\n );\n};\n\nexport default Label;\n"],"names":["cn","React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Label.js","sources":["../src/components/Label/SubLabel.tsx","../src/components/Label/Label.tsx"],"sourcesContent":["import React from 'react';\n\nimport cn from 'classnames';\n\nimport { LabelText } from './Label';\nimport { AnalyticsId, FormOnColor } from '../../constants';\nimport Spacer from '../Spacer';\n\nimport styles from './styles.module.scss';\n\nexport interface SublabelProps {\n /** Sets the content of the Sublabel */\n children?: React.ReactNode;\n /** Adds custom classes to the element. */\n className?: string;\n /** id that is placed on the wrapper */\n id: string;\n /** Array of sublabel strings. Can be of type semibold or normal */\n onColor?: FormOnColor;\n /** Array of sublabel strings. Can be of type semibold or normal */\n sublabelTexts?: LabelText[];\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const Sublabel: React.FC<SublabelProps> = ({ children, className, id, onColor, sublabelTexts, testId }) => {\n const mapSublabels = (hideFromScreenReader?: boolean): React.ReactNode => {\n return (\n sublabelTexts &&\n sublabelTexts.map((sublabelText, index) => {\n const labelClasses = cn(styles.label, styles['sublabel'], {\n [styles['sublabel--subdued']]: sublabelText.type === 'subdued',\n [styles['sublabel--on-dark']]: onColor === FormOnColor.ondark,\n });\n return (\n hideFromScreenReader === sublabelText.hideFromScreenReader && (\n <span className={labelClasses} key={index}>\n {sublabelText.text}\n </span>\n )\n );\n })\n );\n };\n\n const subLabels = mapSublabels();\n const ariaHiddenSublabels = mapSublabels(true);\n\n return (\n <>\n <Spacer size={'3xs'} />\n {(subLabels || children) && (\n <div className={className} id={id} data-testid={testId} data-analyticsid={AnalyticsId.Sublabel}>\n {subLabels}\n {children}\n </div>\n )}\n {ariaHiddenSublabels && (\n <div className={className} data-testid={testId}>\n {ariaHiddenSublabels}\n </div>\n )}\n </>\n );\n};\n","import React, { FunctionComponent } from 'react';\n\nimport cn from 'classnames';\n\nimport { Sublabel, SublabelProps } from './SubLabel';\nimport { AnalyticsId, FormOnColor } from '../../constants';\nimport { isComponent } from '../../utils/component';\nimport FormFieldTag, { FormFieldTagProps } from '../FormFieldTag';\nimport Spacer from '../Spacer';\nimport StatusDot, { StatusDotProps } from '../StatusDot';\n\nimport styles from './styles.module.scss';\n\nexport type LabelText = {\n hideFromScreenReader?: boolean;\n text: string;\n type?: 'normal' | 'subdued';\n};\n\nexport type LabelTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | 'label' | 'p';\n\nexport interface LabelProps {\n /** Component shown after label - discourage use of this */\n afterLabelChildren?: React.ReactNode;\n /** Sets the content of the Label */\n children?: React.ReactNode;\n /** Sets a tag that describes whether the form field is required or optional */\n formFieldTag?: React.ReactNode;\n /** Adds custom classes to the label tag. */\n labelClassName?: string;\n /** Adds custom classes to the label text. */\n labelTextClassName?: string;\n /** Adds custom classes to the element. */\n className?: string;\n /** Id that is put on the \"for\" attribute of the label */\n htmlFor?: string;\n /** Changes the underlying element of the label */\n htmlMarkup?: LabelTags;\n /** Id som plasseres på <label/> */\n labelId?: string;\n /** Array of main label strings. Can be of type semibold or normal */\n labelTexts?: LabelText[];\n /** Array of sublabel strings. Can be of type semibold or normal */\n onColor?: keyof typeof FormOnColor;\n /** StatusDot placed underneath the last sublabel */\n statusDot?: React.ReactNode;\n /** Sublabel component */\n sublabel?: React.ReactNode;\n /** Adds custom classes to the div wrapping the sublabels. */\n sublabelWrapperClassName?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const getLabelText = (label: React.ReactNode): string => {\n let allLabelText = '';\n\n if (isComponent<LabelProps>(label, Label)) {\n label.props.labelTexts?.forEach(labelText => {\n allLabelText += !labelText.hideFromScreenReader ? labelText.text : '';\n });\n }\n\n return allLabelText;\n};\n\nexport const renderLabel = (label: React.ReactNode, inputId: string, onColor: FormOnColor, markup?: LabelTags): React.ReactNode => {\n return (\n <>\n {label && isComponent<LabelProps>(label, Label)\n ? React.cloneElement(label, {\n htmlFor: inputId,\n htmlMarkup: markup || 'label',\n onColor,\n })\n : typeof label === 'string' && <Label labelTexts={[{ text: label, type: 'normal' }]} htmlFor={inputId} onColor={onColor} />}\n </>\n );\n};\n\nexport const renderLabelAsParent = (\n label: React.ReactNode,\n children: React.ReactNode,\n inputId: string,\n onColor: FormOnColor,\n labelClassName?: string,\n labelTextClassName?: string,\n sublabelWrapperClassName?: string,\n large?: boolean,\n markup?: LabelTags\n): React.ReactNode => {\n return (\n <>\n {label && isComponent<LabelProps>(label, Label)\n ? React.cloneElement(label, {\n htmlFor: inputId,\n onColor,\n children: children,\n labelClassName: cn(labelClassName, label.props.labelClassName),\n labelTextClassName: labelTextClassName,\n htmlMarkup: markup || 'label',\n sublabelWrapperClassName: sublabelWrapperClassName,\n sublabel: large ? undefined : label.props.sublabel,\n statusDot: large ? undefined : label.props.statusDot,\n })\n : typeof label === 'string' && (\n <Label\n labelTexts={[{ text: label, type: 'subdued' }]}\n htmlFor={inputId}\n onColor={onColor}\n htmlMarkup={markup || 'label'}\n labelClassName={labelClassName}\n labelTextClassName={labelTextClassName}\n sublabelWrapperClassName={sublabelWrapperClassName}\n >\n {children}\n </Label>\n )}\n </>\n );\n};\n\nconst Label: FunctionComponent<LabelProps> = ({\n afterLabelChildren,\n children,\n className,\n formFieldTag,\n htmlFor,\n htmlMarkup = 'label',\n labelClassName,\n labelTextClassName,\n labelId,\n labelTexts,\n onColor = FormOnColor.onwhite,\n statusDot,\n sublabel,\n sublabelWrapperClassName,\n testId,\n}) => {\n const hasChildren = children && typeof children !== 'undefined';\n const labelWrapperClasses = cn(\n styles['label-wrapper'],\n { [styles['label-wrapper--no-bottom-margin']]: hasChildren, [styles['label-wrapper--after-label-children']]: afterLabelChildren },\n className\n );\n\n const mapLabels = (): React.ReactNode => {\n if (typeof labelTexts === 'undefined') return null;\n\n return labelTexts.map((labelText, index) => {\n const labelClasses = cn(\n styles.label,\n {\n [styles['label--subdued']]: labelText.type === 'subdued',\n [styles['label--on-dark']]: onColor === FormOnColor.ondark,\n },\n labelTextClassName\n );\n return (\n <span aria-hidden={labelText.hideFromScreenReader} className={labelClasses} key={index}>\n {labelText.text}\n </span>\n );\n });\n };\n const CustomTag = htmlMarkup;\n\n return (\n <div className={labelWrapperClasses}>\n <div>\n <CustomTag className={labelClassName} id={labelId} htmlFor={htmlFor} data-testid={testId} data-analyticsid={AnalyticsId.Label}>\n <span className={styles['label-content-wrapper']}>\n {children}\n <span className={styles.label__texts}>{mapLabels()}</span>\n </span>\n </CustomTag>\n <div className={sublabelWrapperClassName}>\n {formFieldTag && isComponent<FormFieldTagProps>(formFieldTag, FormFieldTag) && React.cloneElement(formFieldTag)}\n {sublabel &&\n isComponent<SublabelProps>(sublabel, Sublabel) &&\n React.cloneElement(sublabel, {\n onColor: onColor as FormOnColor,\n })}\n {statusDot && isComponent<StatusDotProps>(statusDot, StatusDot) && (\n <>\n <Spacer size={'3xs'} />\n {React.cloneElement(statusDot, {\n onColor: onColor === FormOnColor.ondark ? 'ondark' : 'onwhite',\n })}\n </>\n )}\n </div>\n </div>\n {afterLabelChildren && <div className={styles['after-label-children']}>{afterLabelChildren}</div>}\n </div>\n );\n};\n\nexport default Label;\n"],"names":["cn","React"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { HNDesignsystemFormFieldTag } from '../../resources/Resources';
|
|
3
|
+
export type FormFieldTagLevel = 'all-required' | 'required-field' | 'optional';
|
|
4
|
+
export interface FormFieldTagProps {
|
|
5
|
+
/** Id that is placed on the component */
|
|
6
|
+
id?: string;
|
|
7
|
+
/** What level is the required tag, sets the styling and the text. */
|
|
8
|
+
level: FormFieldTagLevel;
|
|
9
|
+
/** Texts if overriding SOT */
|
|
10
|
+
resources?: HNDesignsystemFormFieldTag;
|
|
11
|
+
/** Sets the data-testid attribute. */
|
|
12
|
+
testId?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const FormFieldTag: React.FC<FormFieldTagProps>;
|
|
15
|
+
export default FormFieldTag;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
@use '../../scss/font-mixins' as fonts;
|
|
2
|
+
@import '../../scss/supernova/styles/colors.css';
|
|
3
|
+
|
|
4
|
+
.form-field-tag {
|
|
5
|
+
@include fonts.image-caption;
|
|
6
|
+
|
|
7
|
+
font-weight: 400;
|
|
8
|
+
display: block;
|
|
9
|
+
width: fit-content;
|
|
10
|
+
background: linear-gradient(180deg, transparent 8%, var(--core-color-banana-100) 8%, var(--core-color-banana-100) 92%, transparent 92%);
|
|
11
|
+
color: var(--core-color-neutral-800);
|
|
12
|
+
padding: 0 0.1875rem;
|
|
13
|
+
|
|
14
|
+
&--optional {
|
|
15
|
+
background: linear-gradient(
|
|
16
|
+
180deg,
|
|
17
|
+
transparent 8%,
|
|
18
|
+
var(--core-color-blueberry-100) 8%,
|
|
19
|
+
var(--core-color-blueberry-100) 92%,
|
|
20
|
+
transparent 92%
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -16,6 +16,8 @@ export interface FormGroupProps {
|
|
|
16
16
|
errorWrapperClassName?: string;
|
|
17
17
|
/** Adds custom classes to the fieldset element. */
|
|
18
18
|
fieldsetClassName?: string;
|
|
19
|
+
/** Sets a tag that describes whether the form group is required or optional */
|
|
20
|
+
formFieldTag?: React.ReactNode;
|
|
19
21
|
/** Adds custom classes to the legend element. */
|
|
20
22
|
legendClassName?: string;
|
|
21
23
|
/** Changes the visuals of the formgroup */
|
|
@@ -11,6 +11,8 @@ export interface LabelProps {
|
|
|
11
11
|
afterLabelChildren?: React.ReactNode;
|
|
12
12
|
/** Sets the content of the Label */
|
|
13
13
|
children?: React.ReactNode;
|
|
14
|
+
/** Sets a tag that describes whether the form field is required or optional */
|
|
15
|
+
formFieldTag?: React.ReactNode;
|
|
14
16
|
/** Adds custom classes to the label tag. */
|
|
15
17
|
labelClassName?: string;
|
|
16
18
|
/** Adds custom classes to the label text. */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface CloseProps {
|
|
3
|
+
/** Function is called when user clicks the button */
|
|
4
|
+
onClick?: (e?: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
|
5
|
+
/** Sets the aria-label of the button */
|
|
6
|
+
ariaLabel?: string;
|
|
7
|
+
/** Sets the data-testid attribute. */
|
|
8
|
+
testId?: string;
|
|
9
|
+
}
|
|
10
|
+
declare const Close: React.ForwardRefExoticComponent<CloseProps & React.RefAttributes<HTMLButtonElement>>;
|
|
11
|
+
export default Close;
|
|
@@ -1,46 +1,107 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useRef, useLayoutEffect } from "react";
|
|
1
|
+
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React__default, { useRef, useLayoutEffect } from "react";
|
|
3
3
|
import classNames from "classnames";
|
|
4
4
|
import { useHover } from "../../hooks/useHover.js";
|
|
5
|
-
import {
|
|
5
|
+
import { useIsMobileBreakpoint } from "../../hooks/useIsMobileBreakpoint.js";
|
|
6
|
+
import { mergeRefs } from "../../utils/refs.js";
|
|
6
7
|
import { I as Icon } from "../../Icon.js";
|
|
7
|
-
import { IconSize } from "../../constants.js";
|
|
8
|
-
import { useUuid } from "../../hooks/useUuid.js";
|
|
9
|
-
import { getAriaDescribedBy } from "../../utils/accessibility.js";
|
|
10
8
|
import X from "../Icons/X.js";
|
|
11
9
|
import styles from "./styles.module.scss";
|
|
12
|
-
|
|
10
|
+
import { usePseudoClasses } from "../../hooks/usePseudoClasses.js";
|
|
11
|
+
import { useUuid } from "../../hooks/useUuid.js";
|
|
12
|
+
import { getAriaDescribedBy } from "../../utils/accessibility.js";
|
|
13
|
+
const Close = React__default.forwardRef(function ButtonForwardedRef(props, ref) {
|
|
14
|
+
const { testId, ariaLabel = "Lukk", onClick } = props;
|
|
15
|
+
const { hoverRef, isHovered } = useHover();
|
|
16
|
+
const iconSize = useIsMobileBreakpoint() ? 38 : 48;
|
|
17
|
+
const closeClasses = classNames(styles.close);
|
|
18
|
+
return /* @__PURE__ */ jsx(
|
|
19
|
+
"button",
|
|
20
|
+
{
|
|
21
|
+
ref: mergeRefs([ref, hoverRef]),
|
|
22
|
+
"data-testid": testId,
|
|
23
|
+
className: closeClasses,
|
|
24
|
+
"aria-label": ariaLabel,
|
|
25
|
+
onClick,
|
|
26
|
+
type: "button",
|
|
27
|
+
children: /* @__PURE__ */ jsx("span", { className: classNames(styles["close__inner-container"]), children: /* @__PURE__ */ jsx(Icon, { svgIcon: X, color: "black", size: iconSize, isHovered }) })
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
const Triangle = ({ isHover, isFocus, isActive, isError }) => {
|
|
13
32
|
const palette = (() => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
const colors = {
|
|
34
|
+
border: "var(--component-stickynote-border-normal)",
|
|
35
|
+
background: "var(--component-stickynote-background-fold-normal-light)"
|
|
36
|
+
};
|
|
37
|
+
if (!isError) {
|
|
38
|
+
if (isHover) {
|
|
39
|
+
colors.background = "var(--component-stickynote-background-fold-normal-medium)";
|
|
40
|
+
}
|
|
41
|
+
if (isFocus) {
|
|
42
|
+
colors.border = "var(--color-action-border-onlight-focus)";
|
|
43
|
+
colors.background = "var(--component-stickynote-background-fold-normal-medium)";
|
|
44
|
+
}
|
|
45
|
+
if (isActive) {
|
|
46
|
+
colors.background = "var(--component-stickynote-background-fold-normal-dark)";
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
colors.border = "var(--component-stickynote-border-error)";
|
|
50
|
+
colors.background = "var(--component-stickynote-background-fold-error-light)";
|
|
51
|
+
if (isHover) {
|
|
52
|
+
colors.background = "var(--component-stickynote-background-fold-error-medium)";
|
|
53
|
+
}
|
|
54
|
+
if (isFocus) {
|
|
55
|
+
colors.border = "var(--color-action-border-onlight-focus)";
|
|
56
|
+
colors.background = "var(--component-stickynote-background-fold-error-medium)";
|
|
57
|
+
}
|
|
58
|
+
if (isActive) {
|
|
59
|
+
colors.background = "var(--component-stickynote-background-fold-error-dark)";
|
|
60
|
+
}
|
|
30
61
|
}
|
|
62
|
+
return colors;
|
|
31
63
|
})();
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
/* @__PURE__ */
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
64
|
+
let svg;
|
|
65
|
+
if (isFocus) {
|
|
66
|
+
svg = /* @__PURE__ */ jsxs("svg", { width: "21", height: "21", viewBox: "0 0 21 21", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
67
|
+
/* @__PURE__ */ jsx("mask", { id: "path-1-inside-1_7753_1401", fill: "white", children: /* @__PURE__ */ jsx("path", { d: "M0.493163 20.9211L0.276366 20.9211L0.276367 0.921142L20.2764 0.921143L20.2764 1.13794L0.493163 20.9211Z" }) }),
|
|
68
|
+
/* @__PURE__ */ jsx(
|
|
69
|
+
"path",
|
|
70
|
+
{
|
|
71
|
+
d: "M0.493163 20.9211L0.276366 20.9211L0.276367 0.921142L20.2764 0.921143L20.2764 1.13794L0.493163 20.9211Z",
|
|
72
|
+
fill: palette.background
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
/* @__PURE__ */ jsx(
|
|
76
|
+
"path",
|
|
77
|
+
{
|
|
78
|
+
d: "M0.493163 20.9211L0.493163 22.9211L1.32159 22.9211L1.90738 22.3354L0.493163 20.9211ZM0.276366 20.9211L-1.72363 20.9211L-1.72363 22.9211L0.276366 22.9211L0.276366 20.9211ZM0.276367 0.921142L0.276367 -1.07886L-1.72363 -1.07886L-1.72363 0.921142L0.276367 0.921142ZM20.2764 0.921143L22.2764 0.921143L22.2764 -1.07886L20.2764 -1.07886L20.2764 0.921143ZM20.2764 1.13794L21.6906 2.55215L22.2764 1.96637L22.2764 1.13794L20.2764 1.13794ZM0.493163 20.9211L0.493163 18.9211L0.276366 18.9211L0.276366 20.9211L0.276366 22.9211L0.493163 22.9211L0.493163 20.9211ZM0.276366 20.9211L2.27637 20.9211L2.27637 0.921142L0.276367 0.921142L-1.72363 0.921142L-1.72363 20.9211L0.276366 20.9211ZM0.276367 0.921142L0.276367 2.92114L20.2764 2.92114L20.2764 0.921143L20.2764 -1.07886L0.276367 -1.07886L0.276367 0.921142ZM20.2764 0.921143L18.2764 0.921142L18.2764 1.13794L20.2764 1.13794L22.2764 1.13794L22.2764 0.921143L20.2764 0.921143ZM20.2764 1.13794L18.8622 -0.276274L-0.92105 19.5069L0.493163 20.9211L1.90738 22.3354L21.6906 2.55215L20.2764 1.13794Z",
|
|
79
|
+
fill: palette.border,
|
|
80
|
+
mask: "url(#path-1-inside-1_7753_1401)"
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
] });
|
|
84
|
+
} else {
|
|
85
|
+
svg = /* @__PURE__ */ jsxs("svg", { width: "21", height: "21", viewBox: "0 0 21 21", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
86
|
+
/* @__PURE__ */ jsx("mask", { id: "path-1-inside-1_7717_293537", fill: "white", children: /* @__PURE__ */ jsx("path", { d: "M0.923827 20.9211L0.70703 20.9211L0.707031 0.921142L20.707 0.921143L20.707 1.13794L0.923827 20.9211Z" }) }),
|
|
87
|
+
/* @__PURE__ */ jsx(
|
|
88
|
+
"path",
|
|
89
|
+
{
|
|
90
|
+
d: "M0.923827 20.9211L0.70703 20.9211L0.707031 0.921142L20.707 0.921143L20.707 1.13794L0.923827 20.9211Z",
|
|
91
|
+
fill: palette.background
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
/* @__PURE__ */ jsx(
|
|
95
|
+
"path",
|
|
96
|
+
{
|
|
97
|
+
d: "M0.923827 20.9211L0.923827 21.9211L1.33804 21.9211L1.63093 21.6282L0.923827 20.9211ZM0.70703 20.9211L-0.29297 20.9211L-0.29297 21.9211L0.70703 21.9211L0.70703 20.9211ZM0.707031 0.921142L0.707031 -0.0788582L-0.292969 -0.0788583L-0.292969 0.921142L0.707031 0.921142ZM20.707 0.921143L21.707 0.921143L21.707 -0.0788574L20.707 -0.0788574L20.707 0.921143ZM20.707 1.13794L21.4141 1.84505L21.707 1.55215L21.707 1.13794L20.707 1.13794ZM0.923827 20.9211L0.923827 19.9211L0.70703 19.9211L0.70703 20.9211L0.70703 21.9211L0.923827 21.9211L0.923827 20.9211ZM0.70703 20.9211L1.70703 20.9211L1.70703 0.921142L0.707031 0.921142L-0.292969 0.921142L-0.29297 20.9211L0.70703 20.9211ZM0.707031 0.921142L0.707031 1.92114L20.707 1.92114L20.707 0.921143L20.707 -0.0788574L0.707031 -0.0788582L0.707031 0.921142ZM20.707 0.921143L19.707 0.921143L19.707 1.13794L20.707 1.13794L21.707 1.13794L21.707 0.921143L20.707 0.921143ZM20.707 1.13794L19.9999 0.430833L0.21672 20.214L0.923827 20.9211L1.63093 21.6282L21.4141 1.84505L20.707 1.13794Z",
|
|
98
|
+
fill: palette.border,
|
|
99
|
+
mask: "url(#path-1-inside-1_7717_293537)"
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
] });
|
|
103
|
+
}
|
|
104
|
+
return /* @__PURE__ */ jsx(Fragment, { children: svg });
|
|
44
105
|
};
|
|
45
106
|
const StickyNote = (props) => {
|
|
46
107
|
const {
|
|
@@ -60,8 +121,7 @@ const StickyNote = (props) => {
|
|
|
60
121
|
const stickynoteRef = useRef(null);
|
|
61
122
|
const textareaRef = useRef(null);
|
|
62
123
|
const { isFocused: isTextareaFocused } = usePseudoClasses(textareaRef);
|
|
63
|
-
const { isHovered } =
|
|
64
|
-
const triangleType = error ? "error" : isTextareaFocused ? "active" : "default";
|
|
124
|
+
const { isHovered, isActive } = usePseudoClasses(stickynoteRef);
|
|
65
125
|
const handleWrapperClick = (event) => {
|
|
66
126
|
var _a;
|
|
67
127
|
if (event.target.closest("button")) {
|
|
@@ -99,6 +159,7 @@ const StickyNote = (props) => {
|
|
|
99
159
|
ref: stickynoteRef,
|
|
100
160
|
className: classNames(styles["sticky-note"], wrapperClassName, {
|
|
101
161
|
[styles["sticky-note--focused"]]: isTextareaFocused,
|
|
162
|
+
[styles["sticky-note--active"]]: isActive,
|
|
102
163
|
[styles["sticky-note--hovered"]]: isHovered && !isTextareaFocused && !textareaProps.disabled,
|
|
103
164
|
[styles["sticky-note--error"]]: error
|
|
104
165
|
}),
|
|
@@ -123,19 +184,9 @@ const StickyNote = (props) => {
|
|
|
123
184
|
"aria-describedby": getAriaDescribedBy(props, errorTextUuid)
|
|
124
185
|
}
|
|
125
186
|
),
|
|
126
|
-
/* @__PURE__ */ jsx(
|
|
127
|
-
"button",
|
|
128
|
-
{
|
|
129
|
-
onClick: onXButtonClick,
|
|
130
|
-
"aria-label": arialabelXButton,
|
|
131
|
-
"data-testid": "closeButton",
|
|
132
|
-
className: classNames(styles["sticky-note__x-button"]),
|
|
133
|
-
type: "button",
|
|
134
|
-
children: /* @__PURE__ */ jsx(Icon, { svgIcon: X, color: "black", size: IconSize.XXSmall })
|
|
135
|
-
}
|
|
136
|
-
),
|
|
187
|
+
/* @__PURE__ */ jsx(Close, { onClick: onXButtonClick, ariaLabel: arialabelXButton, testId: "closeButton" }),
|
|
137
188
|
/* @__PURE__ */ jsx("div", { className: classNames(styles["sticky-note__footer"]), children: footerText && /* @__PURE__ */ jsx("span", { children: footerText }) }),
|
|
138
|
-
/* @__PURE__ */ jsx("div", { className: classNames(styles["sticky-note__triangle"]), children: /* @__PURE__ */ jsx(Triangle, {
|
|
189
|
+
/* @__PURE__ */ jsx("div", { className: classNames(styles["sticky-note__triangle"]), children: /* @__PURE__ */ jsx(Triangle, { isHover: isHovered, isActive, isFocus: isTextareaFocused, isError: !!error }) })
|
|
139
190
|
]
|
|
140
191
|
}
|
|
141
192
|
),
|