carbon-react 153.3.1 → 153.5.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/esm/__internal__/fieldset/fieldset.component.js +4 -0
- package/esm/__internal__/fieldset/fieldset.style.d.ts +1 -0
- package/esm/__internal__/fieldset/fieldset.style.js +3 -2
- package/esm/__internal__/label/label.component.js +5 -1
- package/esm/__internal__/label/label.style.d.ts +2 -0
- package/esm/__internal__/label/label.style.js +3 -2
- package/esm/components/fieldset/fieldset.component.js +5 -1
- package/esm/components/fieldset/fieldset.style.d.ts +2 -0
- package/esm/components/fieldset/fieldset.style.js +3 -2
- package/esm/components/note/note.component.js +1 -2
- package/esm/components/text-editor/__internal__/plugins/ContentEditor/content-editor.component.d.ts +3 -5
- package/esm/components/text-editor/__internal__/plugins/ContentEditor/content-editor.component.js +8 -11
- package/esm/components/text-editor/__internal__/plugins/ContentEditor/content-editor.style.d.ts +1 -0
- package/esm/components/text-editor/__internal__/plugins/ContentEditor/content-editor.style.js +8 -14
- package/esm/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.component.d.ts +3 -9
- package/esm/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.component.js +3 -15
- package/esm/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.style.d.ts +1 -5
- package/esm/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.style.js +3 -26
- package/esm/components/text-editor/__internal__/plugins/Toolbar/toolbar.component.d.ts +3 -1
- package/esm/components/text-editor/__internal__/plugins/Toolbar/toolbar.component.js +2 -0
- package/esm/components/text-editor/__internal__/plugins/Toolbar/toolbar.style.d.ts +3 -1
- package/esm/components/text-editor/__internal__/plugins/Toolbar/toolbar.style.js +9 -5
- package/esm/components/text-editor/text-editor.component.d.ts +5 -1
- package/esm/components/text-editor/text-editor.component.js +34 -10
- package/esm/components/text-editor/text-editor.context.d.ts +0 -1
- package/esm/components/text-editor/text-editor.style.d.ts +3 -0
- package/esm/components/text-editor/text-editor.style.js +10 -6
- package/esm/locales/de-de.js +21 -0
- package/esm/locales/en-gb.js +3 -0
- package/esm/locales/es-es.js +21 -0
- package/esm/locales/fr-ca.js +21 -0
- package/esm/locales/fr-fr.js +21 -0
- package/esm/locales/locale.d.ts +3 -0
- package/lib/__internal__/fieldset/fieldset.component.js +4 -0
- package/lib/__internal__/fieldset/fieldset.style.d.ts +1 -0
- package/lib/__internal__/fieldset/fieldset.style.js +3 -2
- package/lib/__internal__/label/label.component.js +5 -1
- package/lib/__internal__/label/label.style.d.ts +2 -0
- package/lib/__internal__/label/label.style.js +3 -2
- package/lib/components/fieldset/fieldset.component.js +5 -1
- package/lib/components/fieldset/fieldset.style.d.ts +2 -0
- package/lib/components/fieldset/fieldset.style.js +3 -2
- package/lib/components/note/note.component.js +1 -2
- package/lib/components/text-editor/__internal__/plugins/ContentEditor/content-editor.component.d.ts +3 -5
- package/lib/components/text-editor/__internal__/plugins/ContentEditor/content-editor.component.js +10 -11
- package/lib/components/text-editor/__internal__/plugins/ContentEditor/content-editor.style.d.ts +1 -0
- package/lib/components/text-editor/__internal__/plugins/ContentEditor/content-editor.style.js +8 -14
- package/lib/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.component.d.ts +3 -9
- package/lib/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.component.js +3 -17
- package/lib/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.style.d.ts +1 -5
- package/lib/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.style.js +4 -28
- package/lib/components/text-editor/__internal__/plugins/Toolbar/toolbar.component.d.ts +3 -1
- package/lib/components/text-editor/__internal__/plugins/Toolbar/toolbar.component.js +2 -0
- package/lib/components/text-editor/__internal__/plugins/Toolbar/toolbar.style.d.ts +3 -1
- package/lib/components/text-editor/__internal__/plugins/Toolbar/toolbar.style.js +9 -5
- package/lib/components/text-editor/text-editor.component.d.ts +5 -1
- package/lib/components/text-editor/text-editor.component.js +33 -9
- package/lib/components/text-editor/text-editor.context.d.ts +0 -1
- package/lib/components/text-editor/text-editor.style.d.ts +3 -0
- package/lib/components/text-editor/text-editor.style.js +11 -7
- package/lib/locales/de-de.js +21 -0
- package/lib/locales/en-gb.js +3 -0
- package/lib/locales/es-es.js +21 -0
- package/lib/locales/fr-ca.js +21 -0
- package/lib/locales/fr-fr.js +21 -0
- package/lib/locales/locale.d.ts +3 -0
- package/package.json +1 -1
|
@@ -7,6 +7,7 @@ import { InputGroupBehaviour, InputGroupContext } from "../input-behaviour";
|
|
|
7
7
|
import Help from "../../components/help";
|
|
8
8
|
import Typography from "../../components/typography";
|
|
9
9
|
import { filterStyledSystemMarginProps } from "../../style/utils";
|
|
10
|
+
import useLocale from "../../hooks/__internal__/useLocale";
|
|
10
11
|
const Fieldset = ({
|
|
11
12
|
legend,
|
|
12
13
|
children,
|
|
@@ -32,6 +33,8 @@ const Fieldset = ({
|
|
|
32
33
|
const marginProps = filterStyledSystemMarginProps(rest);
|
|
33
34
|
const [ref, setRef] = useState(null);
|
|
34
35
|
const [isFocused, setFocus] = useState(false);
|
|
36
|
+
const locale = useLocale();
|
|
37
|
+
const optionalLabel = locale.label.optional();
|
|
35
38
|
useEffect(() => {
|
|
36
39
|
if (ref && isRequired) {
|
|
37
40
|
Array.from(ref.querySelectorAll("input") || /* istanbul ignore next */[]).forEach(el => {
|
|
@@ -90,6 +93,7 @@ const Fieldset = ({
|
|
|
90
93
|
}), /*#__PURE__*/React.createElement(StyledLegendContent, {
|
|
91
94
|
isRequired: isRequired,
|
|
92
95
|
isOptional: isOptional,
|
|
96
|
+
optionalLabel: optionalLabel,
|
|
93
97
|
isDisabled: isDisabled
|
|
94
98
|
}, legend, !validationRedesignOptIn && tooltipIcon()))), !validationRedesignOptIn && /*#__PURE__*/React.createElement(Typography, {
|
|
95
99
|
screenReaderOnly: true,
|
|
@@ -6,6 +6,7 @@ type StyledLegendContentProps = {
|
|
|
6
6
|
isRequired?: boolean;
|
|
7
7
|
isOptional?: boolean;
|
|
8
8
|
isDisabled?: boolean;
|
|
9
|
+
optionalLabel?: string;
|
|
9
10
|
};
|
|
10
11
|
declare const StyledLegendContent: import("styled-components").StyledComponent<"span", any, StyledLegendContentProps, never>;
|
|
11
12
|
export type StyledLegendProps = {
|
|
@@ -35,10 +35,11 @@ const StyledLegendContent = styled.span`
|
|
|
35
35
|
`}
|
|
36
36
|
|
|
37
37
|
${({
|
|
38
|
-
isOptional
|
|
38
|
+
isOptional,
|
|
39
|
+
optionalLabel
|
|
39
40
|
}) => isOptional && css`
|
|
40
41
|
::after {
|
|
41
|
-
content: "(
|
|
42
|
+
content: "(${optionalLabel})";
|
|
42
43
|
color: var(--colorsUtilityYin055);
|
|
43
44
|
font-weight: var(--fontWeights400);
|
|
44
45
|
margin-left: var(--spacing050);
|
|
@@ -6,6 +6,7 @@ import ValidationIcon from "../validations/validation-icon.component";
|
|
|
6
6
|
import StyledIconWrapper from "./icon-wrapper.style";
|
|
7
7
|
import { InputContext, InputGroupContext } from "../input-behaviour";
|
|
8
8
|
import createGuid from "../../__internal__/utils/helpers/guid";
|
|
9
|
+
import useLocale from "../../hooks/__internal__/useLocale";
|
|
9
10
|
const shouldDisplayValidationIcon = ({
|
|
10
11
|
error,
|
|
11
12
|
warning,
|
|
@@ -58,6 +59,8 @@ export const Label = ({
|
|
|
58
59
|
onMouseLeave: onGroupMouseLeave
|
|
59
60
|
} = useContext(InputGroupContext);
|
|
60
61
|
const guid = useRef(createGuid());
|
|
62
|
+
const locale = useLocale();
|
|
63
|
+
const optionalLabel = locale.label.optional();
|
|
61
64
|
const handleMouseEnter = () => {
|
|
62
65
|
if (onMouseEnter) onMouseEnter();
|
|
63
66
|
if (onGroupMouseEnter) onGroupMouseEnter();
|
|
@@ -115,7 +118,8 @@ export const Label = ({
|
|
|
115
118
|
optional: optional,
|
|
116
119
|
pr: pr,
|
|
117
120
|
pl: pl,
|
|
118
|
-
className: className
|
|
121
|
+
className: className,
|
|
122
|
+
optionalLabel: optionalLabel
|
|
119
123
|
}, /*#__PURE__*/React.createElement(StyledLabel, _extends({
|
|
120
124
|
"data-element": "label",
|
|
121
125
|
disabled: disabled,
|
|
@@ -20,6 +20,8 @@ export interface StyledLabelContainerProps {
|
|
|
20
20
|
pl?: 1 | 2;
|
|
21
21
|
/** Label width */
|
|
22
22
|
width?: number;
|
|
23
|
+
/** Text used for the optional label */
|
|
24
|
+
optionalLabel?: string;
|
|
23
25
|
}
|
|
24
26
|
export declare const StyledLabelContainer: import("styled-components").StyledComponent<"div", any, StyledLabelContainerProps, never>;
|
|
25
27
|
export default StyledLabel;
|
|
@@ -54,10 +54,11 @@ export const StyledLabelContainer = styled.div`
|
|
|
54
54
|
`}
|
|
55
55
|
|
|
56
56
|
${({
|
|
57
|
-
optional
|
|
57
|
+
optional,
|
|
58
|
+
optionalLabel
|
|
58
59
|
}) => optional && css`
|
|
59
60
|
::after {
|
|
60
|
-
content: "(
|
|
61
|
+
content: "(${optionalLabel})";
|
|
61
62
|
font-weight: var(--fontWeights400);
|
|
62
63
|
margin-left: var(--spacing050);
|
|
63
64
|
color: var(--colorsUtilityYin055);
|
|
@@ -4,6 +4,7 @@ import tagComponent from "../../__internal__/utils/helpers/tags";
|
|
|
4
4
|
import { FieldsetStyle, StyledLegend } from "./fieldset.style";
|
|
5
5
|
import NewValidationContext from "../carbon-provider/__internal__/new-validation.context";
|
|
6
6
|
import { filterStyledSystemMarginProps } from "../../style/utils";
|
|
7
|
+
import useLocale from "../../hooks/__internal__/useLocale";
|
|
7
8
|
export const Fieldset = ({
|
|
8
9
|
children,
|
|
9
10
|
legend,
|
|
@@ -16,6 +17,8 @@ export const Fieldset = ({
|
|
|
16
17
|
const {
|
|
17
18
|
validationRedesignOptIn
|
|
18
19
|
} = useContext(NewValidationContext);
|
|
20
|
+
const locale = useLocale();
|
|
21
|
+
const optionalLabel = locale.label.optional();
|
|
19
22
|
useEffect(() => {
|
|
20
23
|
if (ref && required) {
|
|
21
24
|
Array.from(ref.querySelectorAll("input") || /* istanbul ignore next */[]).forEach(el => {
|
|
@@ -29,7 +32,8 @@ export const Fieldset = ({
|
|
|
29
32
|
}, rest, marginProps, tagComponent("fieldset", rest)), legend && /*#__PURE__*/React.createElement(StyledLegend, {
|
|
30
33
|
"data-element": "legend",
|
|
31
34
|
isRequired: required,
|
|
32
|
-
isOptional: isOptional
|
|
35
|
+
isOptional: isOptional,
|
|
36
|
+
optionalLabel: optionalLabel
|
|
33
37
|
}, legend), children);
|
|
34
38
|
};
|
|
35
39
|
Fieldset.displayName = "Fieldset";
|
|
@@ -7,6 +7,8 @@ export interface StyledLegendProps {
|
|
|
7
7
|
isRequired?: boolean;
|
|
8
8
|
/** Flag to configure fields as optional. */
|
|
9
9
|
isOptional?: boolean;
|
|
10
|
+
/** Text used for the optional label */
|
|
11
|
+
optionalLabel?: string;
|
|
10
12
|
}
|
|
11
13
|
declare const StyledLegend: import("styled-components").StyledComponent<"legend", any, StyledLegendProps, never>;
|
|
12
14
|
export { FieldsetStyle, StyledLegend };
|
|
@@ -56,10 +56,11 @@ const StyledLegend = styled.legend`
|
|
|
56
56
|
`}
|
|
57
57
|
|
|
58
58
|
${({
|
|
59
|
-
isOptional
|
|
59
|
+
isOptional,
|
|
60
|
+
optionalLabel
|
|
60
61
|
}) => isOptional && css`
|
|
61
62
|
::after {
|
|
62
|
-
content: "(
|
|
63
|
+
content: "(${optionalLabel})";
|
|
63
64
|
color: var(--colorsUtilityYin055);
|
|
64
65
|
font-weight: var(--fontWeights400);
|
|
65
66
|
margin-left: var(--spacing050);
|
package/esm/components/text-editor/__internal__/plugins/ContentEditor/content-editor.component.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
export interface ContentEditorProps {
|
|
3
|
-
/** The active error message of the editor */
|
|
4
|
-
error?: string;
|
|
5
3
|
/** A hint string rendered before the editor but after the label. Intended to describe the purpose or content of the input. */
|
|
6
4
|
inputHint?: string;
|
|
7
5
|
/** The namespace of the editor that this content editor belongs to */
|
|
@@ -10,8 +8,8 @@ export interface ContentEditorProps {
|
|
|
10
8
|
previews?: React.JSX.Element[];
|
|
11
9
|
/** The number of rows to render in the editor */
|
|
12
10
|
rows?: number;
|
|
13
|
-
/**
|
|
14
|
-
|
|
11
|
+
/** Whether the editor is read-only */
|
|
12
|
+
readOnly?: boolean;
|
|
15
13
|
}
|
|
16
|
-
declare const ContentEditor:
|
|
14
|
+
declare const ContentEditor: React.ForwardRefExoticComponent<ContentEditorProps & React.RefAttributes<HTMLDivElement>>;
|
|
17
15
|
export default ContentEditor;
|
package/esm/components/text-editor/__internal__/plugins/ContentEditor/content-editor.component.js
CHANGED
|
@@ -3,25 +3,24 @@
|
|
|
3
3
|
* as per their documentation. It also uses the `LinkPreviewerPlugin` to render link previews.
|
|
4
4
|
*/
|
|
5
5
|
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
|
|
6
|
-
import React from "react";
|
|
6
|
+
import React, { forwardRef } from "react";
|
|
7
7
|
import StyledContentEditable from "./content-editor.style";
|
|
8
8
|
import { LinkPreviewerPlugin, useCursorAtEnd } from "..";
|
|
9
|
-
const ContentEditor = ({
|
|
10
|
-
error,
|
|
9
|
+
const ContentEditor = /*#__PURE__*/forwardRef(({
|
|
11
10
|
inputHint,
|
|
12
11
|
namespace,
|
|
13
12
|
previews = [],
|
|
14
13
|
rows,
|
|
15
|
-
|
|
16
|
-
}) => {
|
|
14
|
+
readOnly
|
|
15
|
+
}, ref) => {
|
|
17
16
|
const focusAtEnd = useCursorAtEnd();
|
|
18
17
|
return /*#__PURE__*/React.createElement(StyledContentEditable, {
|
|
19
18
|
"data-role": `${namespace}-content-editable`,
|
|
20
|
-
error: error,
|
|
21
19
|
namespace: namespace,
|
|
22
20
|
rows: rows,
|
|
23
|
-
|
|
21
|
+
readOnly: readOnly
|
|
24
22
|
}, /*#__PURE__*/React.createElement(ContentEditable, {
|
|
23
|
+
ref: ref,
|
|
25
24
|
"aria-describedby": inputHint && `${namespace}-input-hint`,
|
|
26
25
|
"aria-labelledby": `${namespace}-label`,
|
|
27
26
|
className: `${namespace}-editable`,
|
|
@@ -37,9 +36,7 @@ const ContentEditor = ({
|
|
|
37
36
|
"aria-autocomplete": undefined,
|
|
38
37
|
"aria-readonly": undefined
|
|
39
38
|
}), /*#__PURE__*/React.createElement(LinkPreviewerPlugin, {
|
|
40
|
-
|
|
41
|
-
previews: previews,
|
|
42
|
-
warning: warning
|
|
39
|
+
previews: previews
|
|
43
40
|
}));
|
|
44
|
-
};
|
|
41
|
+
});
|
|
45
42
|
export default ContentEditor;
|
package/esm/components/text-editor/__internal__/plugins/ContentEditor/content-editor.style.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ContentEditorProps } from "./content-editor.component";
|
|
2
2
|
interface StyledContentEditableProps extends ContentEditorProps {
|
|
3
3
|
showBorders?: boolean;
|
|
4
|
+
readOnly?: boolean;
|
|
4
5
|
}
|
|
5
6
|
declare const StyledContentEditable: import("styled-components").StyledComponent<"div", any, StyledContentEditableProps, never>;
|
|
6
7
|
export default StyledContentEditable;
|
package/esm/components/text-editor/__internal__/plugins/ContentEditor/content-editor.style.js
CHANGED
|
@@ -3,28 +3,22 @@ const DEFAULT_EDITOR_HEIGHT = 210;
|
|
|
3
3
|
const FIXED_LINE_HEIGHT = 21;
|
|
4
4
|
const StyledContentEditable = styled.div`
|
|
5
5
|
${({
|
|
6
|
-
error,
|
|
7
6
|
namespace,
|
|
8
7
|
rows,
|
|
9
|
-
|
|
8
|
+
readOnly
|
|
10
9
|
}) => css`
|
|
11
10
|
.${namespace}-editable {
|
|
12
11
|
min-height: ${rows && rows > 2 ? rows * FIXED_LINE_HEIGHT : DEFAULT_EDITOR_HEIGHT}px;
|
|
13
12
|
background-color: var(--colorsUtilityYang100);
|
|
14
|
-
border-top: 1px solid var(--colorsUtilityMajor200);
|
|
15
|
-
|
|
16
|
-
border-
|
|
13
|
+
${!readOnly && "border-top: 1px solid var(--colorsUtilityMajor200);"}
|
|
14
|
+
${readOnly && `
|
|
15
|
+
border-top-left-radius: var(--borderRadius100);
|
|
16
|
+
border-top-right-radius: var(--borderRadius100);
|
|
17
|
+
`}
|
|
17
18
|
margin: 0;
|
|
18
19
|
padding: 2px 8px;
|
|
19
|
-
border-
|
|
20
|
-
border-
|
|
21
|
-
border-bottom-left-radius: 0;
|
|
22
|
-
border-bottom-right-radius: 0;
|
|
23
|
-
|
|
24
|
-
${(error || warning) && css`
|
|
25
|
-
border: none;
|
|
26
|
-
`}
|
|
27
|
-
|
|
20
|
+
border-bottom-right-radius: var(--borderRadius100);
|
|
21
|
+
border-bottom-left-radius: var(--borderRadius100);
|
|
28
22
|
:focus {
|
|
29
23
|
outline: none;
|
|
30
24
|
}
|
package/esm/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.component.d.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/** The link previews to render at the foot of the editor */
|
|
6
|
-
previews?: React.JSX.Element[];
|
|
7
|
-
/** The active warning message of the editor */
|
|
8
|
-
warning?: string;
|
|
9
|
-
}
|
|
10
|
-
declare const LinkPreviewer: ({ error, previews, warning, }: LinkPreviewerProps) => React.JSX.Element;
|
|
2
|
+
declare const LinkPreviewer: ({ previews, }: {
|
|
3
|
+
previews?: React.JSX.Element[] | undefined;
|
|
4
|
+
}) => React.JSX.Element;
|
|
11
5
|
export default LinkPreviewer;
|
package/esm/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.component.js
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import TextEditorContext from "../../../text-editor.context";
|
|
1
|
+
import React from "react";
|
|
3
2
|
import StyledLinkPreviewer from "./link-previewer.style";
|
|
4
3
|
const LinkPreviewer = ({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
warning
|
|
8
|
-
}) => {
|
|
9
|
-
const {
|
|
10
|
-
readOnly
|
|
11
|
-
} = useContext(TextEditorContext);
|
|
12
|
-
return /*#__PURE__*/React.createElement(StyledLinkPreviewer, {
|
|
13
|
-
error: error,
|
|
14
|
-
readOnly: readOnly,
|
|
15
|
-
warning: warning
|
|
16
|
-
}, previews);
|
|
17
|
-
};
|
|
4
|
+
previews = []
|
|
5
|
+
}) => /*#__PURE__*/React.createElement(StyledLinkPreviewer, null, previews);
|
|
18
6
|
export default LinkPreviewer;
|
package/esm/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.style.d.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
interface StyledLinkPreviewerProps extends LinkPreviewerProps {
|
|
3
|
-
readOnly?: boolean;
|
|
4
|
-
}
|
|
5
|
-
declare const StyledLinkPreviewer: import("styled-components").StyledComponent<"div", any, StyledLinkPreviewerProps, never>;
|
|
1
|
+
declare const StyledLinkPreviewer: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
6
2
|
export default StyledLinkPreviewer;
|
package/esm/components/text-editor/__internal__/plugins/LinkPreviewer/link-previewer.style.js
CHANGED
|
@@ -1,29 +1,6 @@
|
|
|
1
|
-
import styled
|
|
1
|
+
import styled from "styled-components";
|
|
2
2
|
const StyledLinkPreviewer = styled.div`
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
readOnly,
|
|
6
|
-
warning
|
|
7
|
-
}) => css`
|
|
8
|
-
border-bottom-left-radius: 0;
|
|
9
|
-
border-bottom-right-radius: 0;
|
|
10
|
-
background-color: var(--colorsUtilityYang100);
|
|
11
|
-
border-bottom: 1px solid var(--colorsUtilityMajor200);
|
|
12
|
-
border-left: 1px solid var(--colorsUtilityMajor200);
|
|
13
|
-
border-right: 1px solid var(--colorsUtilityMajor200);
|
|
14
|
-
margin: 0;
|
|
15
|
-
padding: 2px 8px;
|
|
16
|
-
|
|
17
|
-
${(error || warning) && css`
|
|
18
|
-
border-left: none;
|
|
19
|
-
border-right: none;
|
|
20
|
-
border-bottom: none;
|
|
21
|
-
`}
|
|
22
|
-
|
|
23
|
-
${readOnly && css`
|
|
24
|
-
border-bottom-left-radius: var(--borderWidth600);
|
|
25
|
-
border-bottom-right-radius: var(--borderWidth600);
|
|
26
|
-
`}
|
|
27
|
-
`}
|
|
3
|
+
margin: 0;
|
|
4
|
+
padding: 2px 8px;
|
|
28
5
|
`;
|
|
29
6
|
export default StyledLinkPreviewer;
|
|
@@ -3,10 +3,12 @@ import { EditorFormattedValues } from "./buttons/save.component";
|
|
|
3
3
|
interface ToolbarProps {
|
|
4
4
|
/** The namespace of the editor that this toolbar belongs to */
|
|
5
5
|
namespace: string;
|
|
6
|
+
/** Determines if the Text Editor has a header */
|
|
7
|
+
hasHeader?: boolean;
|
|
6
8
|
/** The callback to call when the cancel button is clicked */
|
|
7
9
|
onCancel?: () => void;
|
|
8
10
|
/** The callback to call when the save button is clicked */
|
|
9
11
|
onSave?: (value: EditorFormattedValues) => void;
|
|
10
12
|
}
|
|
11
|
-
declare const Toolbar: ({ namespace, onCancel, onSave }: ToolbarProps) => React.JSX.Element;
|
|
13
|
+
declare const Toolbar: ({ namespace, hasHeader, onCancel, onSave }: ToolbarProps) => React.JSX.Element;
|
|
12
14
|
export default Toolbar;
|
|
@@ -10,6 +10,7 @@ import { BoldButton, ItalicButton, ListControls } from "./buttons";
|
|
|
10
10
|
import SaveButton from "./buttons/save.component";
|
|
11
11
|
const Toolbar = ({
|
|
12
12
|
namespace,
|
|
13
|
+
hasHeader,
|
|
13
14
|
onCancel,
|
|
14
15
|
onSave
|
|
15
16
|
}) => {
|
|
@@ -80,6 +81,7 @@ const Toolbar = ({
|
|
|
80
81
|
}, [buttons]);
|
|
81
82
|
return /*#__PURE__*/React.createElement(StyledToolbar, {
|
|
82
83
|
role: "toolbar",
|
|
84
|
+
hasHeader: hasHeader,
|
|
83
85
|
"aria-label": locale.textEditor.toolbarAriaLabel(),
|
|
84
86
|
"data-role": `${namespace}-toolbar`,
|
|
85
87
|
id: `${namespace}-toolbar`,
|
|
@@ -4,7 +4,9 @@ interface FormattingButtonProps extends ButtonProps {
|
|
|
4
4
|
tabIndex?: number;
|
|
5
5
|
isActive?: boolean;
|
|
6
6
|
}
|
|
7
|
-
declare const StyledToolbar: import("styled-components").StyledComponent<"div", any, {
|
|
7
|
+
declare const StyledToolbar: import("styled-components").StyledComponent<"div", any, {
|
|
8
|
+
hasHeader?: boolean | undefined;
|
|
9
|
+
}, never>;
|
|
8
10
|
declare const FormattingButtons: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
9
11
|
declare const CommandButtons: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
10
12
|
declare const FormattingButton: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLAnchorElement | HTMLButtonElement>>, any, FormattingButtonProps, never>;
|
|
@@ -4,12 +4,16 @@ const StyledToolbar = styled.div`
|
|
|
4
4
|
display: flex;
|
|
5
5
|
flex-direction: row;
|
|
6
6
|
gap: 8px;
|
|
7
|
-
background-color: var(--
|
|
8
|
-
outline: 1px solid var(--colorsUtilityMajor200);
|
|
7
|
+
background-color: var(--colorsActionMajorYang100);
|
|
9
8
|
padding: 12px;
|
|
10
|
-
border-radius:
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
border-top-left-radius: ${({
|
|
10
|
+
hasHeader
|
|
11
|
+
}) => hasHeader ? "0" : "var(--borderRadius100)"};
|
|
12
|
+
border-top-right-radius: ${({
|
|
13
|
+
hasHeader
|
|
14
|
+
}) => hasHeader ? "0" : "var(--borderRadius100)"};
|
|
15
|
+
border-bottom-left-radius: 0;
|
|
16
|
+
border-bottom-right-radius: 0;
|
|
13
17
|
justify-content: space-between;
|
|
14
18
|
align-items: center;
|
|
15
19
|
margin-left: 1px;
|
|
@@ -8,6 +8,10 @@ export interface TextEditorProps extends MarginProps, TagProps {
|
|
|
8
8
|
characterLimit?: number;
|
|
9
9
|
/** The message to be shown when the editor is in an error state */
|
|
10
10
|
error?: string;
|
|
11
|
+
/** Custom footer content to be displayed below the editor */
|
|
12
|
+
footer?: React.ReactNode;
|
|
13
|
+
/** Custom header content to be displayed above the editor */
|
|
14
|
+
header?: React.ReactNode;
|
|
11
15
|
/** A hint string rendered before the editor but after the label. Intended to describe the purpose or content of the input. */
|
|
12
16
|
inputHint?: string;
|
|
13
17
|
/** Whether the content of the editor can be empty */
|
|
@@ -39,5 +43,5 @@ export interface TextEditorProps extends MarginProps, TagProps {
|
|
|
39
43
|
/** The initial value of the editor, as a HTML string, or JSON */
|
|
40
44
|
value?: string | undefined;
|
|
41
45
|
}
|
|
42
|
-
export declare const TextEditor: ({ characterLimit, error, inputHint, isOptional, labelText, namespace, onCancel, onChange, onLinkAdded, onSave, placeholder, previews, readOnly, required, rows, warning, value, ...rest }: TextEditorProps) => React.JSX.Element;
|
|
46
|
+
export declare const TextEditor: ({ characterLimit, error, footer, header, inputHint, isOptional, labelText, namespace, onCancel, onChange, onLinkAdded, onSave, placeholder, previews, readOnly, required, rows, warning, value, ...rest }: TextEditorProps) => React.JSX.Element;
|
|
43
47
|
export default TextEditor;
|
|
@@ -18,7 +18,7 @@ import useLocale from "../../hooks/__internal__/useLocale";
|
|
|
18
18
|
import { COMPONENT_PREFIX, markdownNodes, theme } from "./__internal__/constants";
|
|
19
19
|
import { AutoLinkerPlugin, CharacterCounterPlugin, ContentEditor, LinkMonitorPlugin, OnChangePlugin, Placeholder, ToolbarPlugin } from "./__internal__/plugins";
|
|
20
20
|
import TextEditorContext from "./text-editor.context";
|
|
21
|
-
import StyledTextEditor, { StyledEditorToolbarWrapper, StyledTextEditorWrapper, StyledValidationMessage, StyledWrapper } from "./text-editor.style";
|
|
21
|
+
import StyledTextEditor, { StyledEditorToolbarWrapper, StyledHeaderWrapper, StyledFooterWrapper, StyledTextEditorWrapper, StyledValidationMessage, StyledWrapper } from "./text-editor.style";
|
|
22
22
|
import { createEmpty } from "./utils";
|
|
23
23
|
import HintText from "../../__internal__/hint-text";
|
|
24
24
|
import { filterStyledSystemMarginProps } from "../../style/utils";
|
|
@@ -26,6 +26,8 @@ import tagComponent from "../../__internal__/utils/helpers/tags";
|
|
|
26
26
|
export const TextEditor = ({
|
|
27
27
|
characterLimit = 3000,
|
|
28
28
|
error,
|
|
29
|
+
footer,
|
|
30
|
+
header,
|
|
29
31
|
inputHint,
|
|
30
32
|
isOptional = false,
|
|
31
33
|
labelText,
|
|
@@ -46,7 +48,25 @@ export const TextEditor = ({
|
|
|
46
48
|
const editorRef = useRef(undefined);
|
|
47
49
|
const locale = useLocale();
|
|
48
50
|
const [characterLimitWarning, setCharacterLimitWarning] = useState(undefined);
|
|
51
|
+
const hasWarningOrError = Boolean(error || characterLimitWarning || warning);
|
|
52
|
+
const contentEditorRef = useRef(null);
|
|
49
53
|
const [isFocused, setIsFocused] = useState(false);
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
const editorElement = contentEditorRef?.current;
|
|
56
|
+
const handleFocus = () => {
|
|
57
|
+
setIsFocused(true);
|
|
58
|
+
};
|
|
59
|
+
const handleBlur = () => {
|
|
60
|
+
setIsFocused(false);
|
|
61
|
+
};
|
|
62
|
+
editorElement?.addEventListener("focus", handleFocus);
|
|
63
|
+
editorElement?.addEventListener("blur", handleBlur);
|
|
64
|
+
const cleanup = () => {
|
|
65
|
+
editorElement?.removeEventListener("focus", handleFocus);
|
|
66
|
+
editorElement?.removeEventListener("blur", handleBlur);
|
|
67
|
+
};
|
|
68
|
+
return cleanup;
|
|
69
|
+
}, [contentEditorRef]);
|
|
50
70
|
const [cancelTrigger, setCancelTrigger] = useState(false);
|
|
51
71
|
const debounceWaitTime = 500;
|
|
52
72
|
const initialConfig = useMemo(() => {
|
|
@@ -110,8 +130,7 @@ export const TextEditor = ({
|
|
|
110
130
|
"data-role": `${namespace}-editor-wrapper`
|
|
111
131
|
}, filterStyledSystemMarginProps(rest), tagComponent("text-editor", rest)), /*#__PURE__*/React.createElement(TextEditorContext.Provider, {
|
|
112
132
|
value: {
|
|
113
|
-
onLinkAdded
|
|
114
|
-
readOnly
|
|
133
|
+
onLinkAdded
|
|
115
134
|
}
|
|
116
135
|
}, /*#__PURE__*/React.createElement(Label, {
|
|
117
136
|
isRequired: required,
|
|
@@ -135,19 +154,22 @@ export const TextEditor = ({
|
|
|
135
154
|
}, error || characterLimitWarning || warning), /*#__PURE__*/React.createElement(StyledEditorToolbarWrapper, {
|
|
136
155
|
"data-role": `${namespace}-editor-toolbar-wrapper`,
|
|
137
156
|
id: `${namespace}-editor-toolbar-wrapper`,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
157
|
+
focused: isFocused,
|
|
158
|
+
hasWarningOrError: hasWarningOrError
|
|
159
|
+
}, header && /*#__PURE__*/React.createElement(StyledHeaderWrapper, {
|
|
160
|
+
"data-role": `${namespace}-header-wrapper`
|
|
161
|
+
}, header), !readOnly && /*#__PURE__*/React.createElement(ToolbarPlugin, _extends({
|
|
162
|
+
hasHeader: Boolean(header)
|
|
163
|
+
}, toolbarProps)), /*#__PURE__*/React.createElement(StyledTextEditor, {
|
|
142
164
|
"data-role": `${namespace}-editor`
|
|
143
165
|
}, /*#__PURE__*/React.createElement(RichTextPlugin, {
|
|
144
166
|
contentEditable: /*#__PURE__*/React.createElement(ContentEditor, {
|
|
145
|
-
|
|
167
|
+
ref: contentEditorRef,
|
|
146
168
|
inputHint: inputHint,
|
|
147
169
|
namespace: namespace,
|
|
148
170
|
previews: previews,
|
|
149
171
|
rows: rows,
|
|
150
|
-
|
|
172
|
+
readOnly: readOnly
|
|
151
173
|
}),
|
|
152
174
|
placeholder: /*#__PURE__*/React.createElement(Placeholder, {
|
|
153
175
|
namespace: namespace,
|
|
@@ -160,7 +182,9 @@ export const TextEditor = ({
|
|
|
160
182
|
validateUrl: validateUrl
|
|
161
183
|
}), /*#__PURE__*/React.createElement(ClickableLinkPlugin, {
|
|
162
184
|
newTab: true
|
|
163
|
-
}), /*#__PURE__*/React.createElement(AutoLinkerPlugin, null)),
|
|
185
|
+
}), /*#__PURE__*/React.createElement(AutoLinkerPlugin, null)), footer && /*#__PURE__*/React.createElement(StyledFooterWrapper, {
|
|
186
|
+
"data-role": `${namespace}-footer-wrapper`
|
|
187
|
+
}, footer), /*#__PURE__*/React.createElement(LinkMonitorPlugin, null)), characterLimit > 0 && !readOnly && /*#__PURE__*/React.createElement(CharacterCounterPlugin, {
|
|
164
188
|
maxChars: characterLimit,
|
|
165
189
|
namespace: namespace
|
|
166
190
|
})))));
|
|
@@ -11,10 +11,13 @@ interface StyledValidationMessageProps {
|
|
|
11
11
|
}
|
|
12
12
|
interface StyledEditorToolbarWrapperProps {
|
|
13
13
|
focused?: boolean;
|
|
14
|
+
hasWarningOrError?: boolean;
|
|
14
15
|
}
|
|
15
16
|
export declare const StyledTextEditor: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("../box").BoxProps & import("react").RefAttributes<HTMLDivElement>>, any, {}, never>;
|
|
16
17
|
export declare const StyledTextEditorWrapper: import("styled-components").StyledComponent<"div", any, StyledTextEditorWrapperProps, never>;
|
|
17
18
|
export declare const StyledWrapper: import("styled-components").StyledComponent<"div", any, StyledWrapperProps, never>;
|
|
18
19
|
export declare const StyledEditorToolbarWrapper: import("styled-components").StyledComponent<"div", any, StyledEditorToolbarWrapperProps, never>;
|
|
20
|
+
export declare const StyledHeaderWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
21
|
+
export declare const StyledFooterWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
19
22
|
export declare const StyledValidationMessage: import("styled-components").StyledComponent<"div", any, StyledValidationMessageProps, never>;
|
|
20
23
|
export default StyledTextEditor;
|
|
@@ -35,24 +35,28 @@ export const StyledWrapper = styled.div`
|
|
|
35
35
|
.${namespace}-editable, #${namespace}-toolbar {
|
|
36
36
|
outline: none;
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
#${namespace}-toolbar {
|
|
40
|
-
border-top: 1px solid var(--colorsUtilityMajor200);
|
|
41
|
-
}
|
|
42
38
|
}
|
|
43
39
|
`}
|
|
44
40
|
`};
|
|
45
41
|
`;
|
|
46
42
|
export const StyledEditorToolbarWrapper = styled.div`
|
|
47
43
|
${({
|
|
48
|
-
focused
|
|
44
|
+
focused,
|
|
45
|
+
hasWarningOrError
|
|
49
46
|
}) => css`
|
|
50
47
|
border-radius: var(--borderRadius100);
|
|
51
|
-
outline: none;
|
|
48
|
+
outline: ${hasWarningOrError ? "none" : "1px solid var(--colorsUtilityMajor200)"};
|
|
52
49
|
|
|
53
50
|
${focused && addFocusStyling()}
|
|
54
51
|
`}
|
|
55
52
|
`;
|
|
53
|
+
export const StyledHeaderWrapper = styled.div`
|
|
54
|
+
padding: var(--spacing200);
|
|
55
|
+
`;
|
|
56
|
+
export const StyledFooterWrapper = styled.div`
|
|
57
|
+
border-top: 1px solid var(--colorsUtilityMajor200);
|
|
58
|
+
padding: var(--spacing200);
|
|
59
|
+
`;
|
|
56
60
|
export const StyledValidationMessage = styled.div`
|
|
57
61
|
${({
|
|
58
62
|
error
|
package/esm/locales/de-de.js
CHANGED
|
@@ -82,6 +82,9 @@ const deDE = {
|
|
|
82
82
|
heading: {
|
|
83
83
|
backLinkAriaLabel: () => "Zurück"
|
|
84
84
|
},
|
|
85
|
+
label: {
|
|
86
|
+
optional: () => "optional"
|
|
87
|
+
},
|
|
85
88
|
link: {
|
|
86
89
|
skipLinkLabel: () => "Zum Hauptinhalt springen"
|
|
87
90
|
},
|
|
@@ -148,6 +151,24 @@ const deDE = {
|
|
|
148
151
|
pod: {
|
|
149
152
|
undo: () => "Rückgängig"
|
|
150
153
|
},
|
|
154
|
+
textEditor: {
|
|
155
|
+
boldAria: () => "Fett",
|
|
156
|
+
cancelButton: () => "Abbrechen",
|
|
157
|
+
cancelButtonAria: () => "Abbrechen",
|
|
158
|
+
characterCounter(count) {
|
|
159
|
+
return `Noch ${typeof count === "number" ? count.toString() : count} Zeichen`;
|
|
160
|
+
},
|
|
161
|
+
characterLimit(count) {
|
|
162
|
+
return `Sie sind ${count} Zeichen über dem Zeichenlimit`;
|
|
163
|
+
},
|
|
164
|
+
contentEditorAria: () => "Editor für Rich-Text-Inhalte",
|
|
165
|
+
italicAria: () => "Kursiv",
|
|
166
|
+
orderedListAria: () => "Sortierte Liste",
|
|
167
|
+
saveButton: () => "Speichern",
|
|
168
|
+
saveButtonAria: () => "Speichern",
|
|
169
|
+
toolbarAriaLabel: () => "Formatierung",
|
|
170
|
+
unorderedListAria: () => "Unsortierte Liste"
|
|
171
|
+
},
|
|
151
172
|
search: {
|
|
152
173
|
searchButtonText: () => "Suchen"
|
|
153
174
|
},
|