Skip to content

Commit cb48059

Browse files
committed
feat: align Texbox with DS + deprecations + rename WIP
1 parent f0ccbc6 commit cb48059

30 files changed

+799
-130
lines changed

src/__internal__/character-count/character-count.style.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const StyledCharacterCount = styled.div.attrs(applyBaseTheme)<{
1111
}>`
1212
text-align: left;
1313
font-size: var(--fontSizes100);
14+
line-height: 150%;
1415
margin-top: var(--spacing050);
1516
margin-bottom: var(--spacing050);
1617
color: ${({ isOverLimit }) =>

src/__internal__/form-field/form-field.component.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ interface CommonFormFieldProps extends MarginProps, ValidationProps {
5858
* @private @ignore
5959
* Flag dedicating if latest validation design should be used */
6060
validationRedesignOptIn?: boolean;
61+
/** @private @internal @ignore */
62+
inputHint?: string;
63+
/** @private @internal @ignore */
64+
inputHintId?: string;
65+
/** Size of an input */
66+
gap?: string;
67+
/** margin */
68+
labelMarginBottom?: string;
6169
}
6270

6371
export interface FormFieldProps extends CommonFormFieldProps, TagProps {
@@ -80,6 +88,8 @@ export interface FormFieldProps extends CommonFormFieldProps, TagProps {
8088
maxWidth?: string;
8189
/** @private @internal @ignore */
8290
"data-component"?: string;
91+
/** Set large font-size */
92+
isLarge?: boolean;
8393
}
8494

8595
const FormField = ({
@@ -104,13 +114,18 @@ const FormField = ({
104114
labelSpacing = 2,
105115
labelWidth,
106116
labelAs,
117+
inputHint,
118+
inputHintId,
119+
gap,
107120
id,
108121
reverse,
109122
useValidationIcon,
110123
adaptiveLabelBreakpoint,
111124
isRequired,
112125
validationIconId,
113126
validationRedesignOptIn,
127+
labelMarginBottom,
128+
isLarge,
114129
...rest
115130
}: FormFieldProps) => {
116131
const invalidValidationProp: string | undefined = useMemo(() => {
@@ -179,15 +194,19 @@ const FormField = ({
179194
return (
180195
<FormFieldStyle {...tagComponent(dataComponent, rest)} {...marginProps}>
181196
<FieldLineStyle
197+
gap={gap}
182198
data-role="field-line"
183199
inline={inlineLabel}
184200
maxWidth={maxWidth}
185201
>
186202
{reverse && children}
187203

188-
{label && (
204+
{(label || inputHint || (labelHelp && validationRedesignOptIn)) && (
189205
<Label
190206
labelId={labelId}
207+
inputHint={inputHint}
208+
inputHintId={inputHintId}
209+
labelHelp={labelHelp}
191210
align={labelAlign}
192211
disabled={disabled}
193212
error={!validationRedesignOptIn && error}
@@ -199,12 +218,14 @@ const FormField = ({
199218
helpIcon={labelHelpIcon}
200219
inline={inlineLabel}
201220
width={labelWidth}
221+
marginBttom={labelMarginBottom}
202222
useValidationIcon={useValidationIcon}
203223
pr={!reverse ? labelSpacing : undefined}
204224
pl={reverse ? labelSpacing : undefined}
205225
isRequired={isRequired}
206226
validationIconId={validationIconId}
207227
as={labelAs}
228+
isLarge={isLarge}
208229
>
209230
{label}
210231
</Label>

src/__internal__/form-field/form-field.style.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ const FormFieldStyle = styled.div.attrs(applyBaseTheme)`
1717
export interface FieldLineStyleProps {
1818
inline?: boolean;
1919
maxWidth?: string;
20+
gap?: string;
2021
}
2122
const FieldLineStyle = styled.div<FieldLineStyleProps>`
22-
${({ inline, maxWidth }) => css`
23-
display: ${inline ? "flex" : "block"};
23+
${({ inline, maxWidth, gap }) => css`
24+
${gap && `gap: ${gap};`}
25+
display: flex;
26+
flex-direction: ${inline ? "row" : "column"};
2427
${maxWidth && `max-width: ${maxWidth};`}
2528
`}
2629
`;

src/__internal__/form-field/form-field.test.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ test("should not render with `labelInline` when `adaptiveLabelBreakpoint` set an
8787
/>,
8888
);
8989

90-
expect(screen.getByTestId("field-line")).toHaveStyle("display: block");
90+
expect(screen.getByTestId("field-line")).toHaveStyle("display: flex");
91+
expect(screen.getByTestId("field-line")).toHaveStyle(
92+
"flex-direction: column",
93+
);
9194
});
9295

9396
test("should render with `labelInline` when `adaptiveLabelBreakpoint` set and screen is bigger than the breakpoint", () => {

src/__internal__/hint-text/hint-text.style.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const StyledHintText = styled.div<HintTextProps>`
1616
display: flex;
1717
align-items: center;
1818
font-size: 14px;
19+
line-height: 150%;
1920
2021
${({ isLarge }) =>
2122
isLarge &&

src/__internal__/input/input-presentation.component.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export interface CommonInputPresentationProps extends ValidationProps {
2424
* Leaving the `maxWidth` prop with no value will default the width to '100%'
2525
*/
2626
maxWidth?: string;
27+
/** When true label is inline. */
28+
labelInline?: boolean;
2729
/** If true, the component will be read-only */
2830
readOnly?: boolean;
2931
/** Size of an input */
@@ -52,6 +54,7 @@ const InputPresentation = ({
5254
info,
5355
inputWidth,
5456
maxWidth,
57+
labelInline,
5558
positionedChildren,
5659
prefix,
5760
readOnly,
@@ -75,6 +78,35 @@ const InputPresentation = ({
7578
if (onGroupMouseLeave) onGroupMouseLeave();
7679
};
7780

81+
if (validationRedesignOptIn && labelInline) {
82+
return (
83+
<>
84+
{positionedChildren}
85+
<InputPresentationStyle
86+
hasFocus={hasFocus}
87+
role="presentation"
88+
onMouseDown={onMouseDown}
89+
onMouseEnter={handleMouseEnter}
90+
onMouseLeave={handleMouseLeave}
91+
align={align}
92+
prefix={prefix}
93+
disabled={disabled}
94+
readOnly={readOnly}
95+
size={size}
96+
warning={warning}
97+
error={error}
98+
info={info}
99+
validationRedesignOptIn={validationRedesignOptIn}
100+
hasIcon={hasIcon}
101+
borderRadius={borderRadius}
102+
hideBorders={hideBorders}
103+
>
104+
{children}
105+
</InputPresentationStyle>
106+
</>
107+
);
108+
}
109+
78110
return (
79111
<StyledInputPresentationContainer
80112
inputWidth={inputWidth}

src/__internal__/input/input.component.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ export interface InputProps extends CommonInputProps {
6464
rows?: number;
6565
/** HTML type attribute of the input */
6666
type?: string;
67+
/** Set large font-size */
68+
isLarge?: boolean;
6769
}
6870

6971
function selectTextOnFocus(
@@ -112,6 +114,7 @@ const Input = React.forwardRef<
112114
validationIconId,
113115
inputBorderRadius = "borderRadius050",
114116
enterKeyHint,
117+
isLarge,
115118
...rest
116119
}: InputProps,
117120
ref,
@@ -247,6 +250,7 @@ const Input = React.forwardRef<
247250
onClick={disabled || readOnly ? undefined : handleClick}
248251
onChange={handleChange}
249252
inputBorderRadius={inputBorderRadius}
253+
isLarge={isLarge}
250254
/>
251255
);
252256
},

src/__internal__/input/input.style.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import styled, { css } from "styled-components";
2-
import { CommonInputProps } from "./input.component";
2+
import { CommonInputProps, InputProps } from "./input.component";
33

44
const StyledInput = styled.input<
5-
Pick<CommonInputProps, "align" | "disabled" | "inputBorderRadius"> & {
6-
isInputInSelect: boolean;
7-
}
5+
Pick<CommonInputProps, "align" | "disabled" | "inputBorderRadius"> &
6+
Pick<InputProps, "isLarge"> & {
7+
isInputInSelect: boolean;
8+
}
89
>`
910
${({ isInputInSelect }) => isInputInSelect && "text-overflow: ellipsis"};
1011
background: transparent;
@@ -17,6 +18,12 @@ const StyledInput = styled.input<
1718
margin: 0;
1819
width: 30px;
1920
21+
${({ isLarge }) =>
22+
isLarge &&
23+
css`
24+
font-size: var(--fontSizes200);
25+
`}
26+
2027
&:-webkit-autofill {
2128
background-clip: text;
2229
-webkit-background-clip: text;

src/__internal__/label/label.component.tsx

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { InputContext, InputGroupContext } from "../input-behaviour";
1212
import { ValidationProps } from "../validations";
1313
import { IconType } from "../../components/icon";
1414
import createGuid from "../../__internal__/utils/helpers/guid";
15+
import HintText from "../hint-text";
16+
import newValidationContext from "../../components/carbon-provider/__internal__/new-validation.context";
1517

1618
export interface LabelProps
1719
extends ValidationProps,
@@ -40,6 +42,14 @@ export interface LabelProps
4042
* @internal
4143
* Sets className for component. INTERNAL USE ONLY. */
4244
className?: string;
45+
/** @private @internal @ignore */
46+
inputHint?: string;
47+
/** @private @internal @ignore */
48+
inputHintId?: string;
49+
/** @private @internal @ignore */
50+
labelHelp?: React.ReactNode;
51+
/** @private @internal @ignore */
52+
marginBttom?: string;
4353
/** Sets aria-label for label element */
4454
"aria-label"?: string;
4555
/** Whether this component is shown against a dark background */
@@ -79,11 +89,15 @@ export const Label = ({
7989
isDarkBackground = false,
8090
isRequired,
8191
labelId,
92+
inputHint,
93+
inputHintId,
94+
labelHelp,
8295
pr,
8396
pl,
8497
tooltipId,
8598
useValidationIcon = true,
8699
validationIconId,
100+
marginBttom = "8px",
87101
warning,
88102
width = 30,
89103
className,
@@ -96,6 +110,8 @@ export const Label = ({
96110
useContext(InputGroupContext);
97111
const guid = useRef(createGuid());
98112

113+
const { validationRedesignOptIn } = useContext(newValidationContext);
114+
99115
const handleMouseEnter = () => {
100116
if (onMouseEnter) onMouseEnter();
101117
if (onGroupMouseEnter) onGroupMouseEnter();
@@ -167,26 +183,42 @@ export const Label = ({
167183
id={`label-container-${labelId ?? guid.current}`}
168184
align={alignment}
169185
inline={inline}
186+
validationRedesignOptIn={validationRedesignOptIn}
170187
width={width}
188+
marginBttom={marginBttom}
171189
pr={pr}
172190
pl={pl}
173191
className={className}
174192
>
175-
<StyledLabel
176-
data-element="label"
177-
disabled={disabled}
178-
id={labelId}
179-
{...(as === "label" ? { htmlFor } : {})}
180-
onMouseEnter={handleMouseEnter}
181-
onMouseLeave={handleMouseLeave}
182-
isRequired={isRequired}
183-
as={as}
184-
aria-label={ariaLabel}
185-
isDarkBackground={isDarkBackground}
186-
isLarge={isLarge}
187-
>
188-
{children}
189-
</StyledLabel>
193+
<div style={{ display: "flex", flexDirection: "column" }}>
194+
<StyledLabel
195+
data-element="label"
196+
disabled={disabled}
197+
id={labelId}
198+
{...(as === "label" ? { htmlFor } : {})}
199+
onMouseEnter={handleMouseEnter}
200+
onMouseLeave={handleMouseLeave}
201+
isRequired={isRequired}
202+
as={as}
203+
aria-label={ariaLabel}
204+
isDarkBackground={isDarkBackground}
205+
isLarge={isLarge}
206+
>
207+
{children}
208+
</StyledLabel>
209+
{(inputHint || (labelHelp && validationRedesignOptIn)) && (
210+
<HintText
211+
align={alignment}
212+
data-element="input-hint"
213+
id={inputHintId}
214+
marginBottom="var(--spacing000)"
215+
isLarge={isLarge}
216+
isComponentInline={inline}
217+
>
218+
{inputHint || labelHelp}
219+
</HintText>
220+
)}
221+
</div>
190222
{icon()}
191223
</StyledLabelContainer>
192224
);

src/__internal__/label/label.style.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const StyledLabel = styled.label<StyledLabelProps>`
2424
css`
2525
font-size: var(--fontSizes200);
2626
`}
27+
line-height: 150%;
2728
2829
${({ isRequired }) =>
2930
isRequired &&
@@ -54,27 +55,36 @@ export interface StyledLabelContainerProps {
5455
pl?: 1 | 2;
5556
/** Label width */
5657
width?: number;
58+
validationRedesignOptIn?: boolean;
59+
marginBttom?: string;
5760
}
5861

5962
export const StyledLabelContainer = styled.div<StyledLabelContainerProps>`
6063
display: flex;
61-
align-items: center;
62-
margin-bottom: 8px;
63-
64+
align-items: ${({ validationRedesignOptIn }) =>
65+
validationRedesignOptIn ? "top" : "center"};
66+
${({ inline }) => css`
67+
text-align: ${inline ? "right" : "left"};
68+
`}
69+
${({ marginBttom }) => css`
70+
margin-bottom: ${marginBttom};
71+
`}
6472
${({ align }) => css`
6573
justify-content: ${align !== "right" ? "flex-start" : "flex-end"};
6674
`}
6775
68-
${({ inline, pr, pl, width }) =>
76+
${({ inline, validationRedesignOptIn, pr, pl, width }) =>
6977
inline &&
7078
css`
7179
box-sizing: border-box;
7280
margin-bottom: 0;
7381
${pr &&
82+
!validationRedesignOptIn &&
7483
css`
7584
padding-right: var(${pr === 1 ? "--spacing100" : "--spacing200"});
7685
`};
7786
${pl &&
87+
!validationRedesignOptIn &&
7888
css`
7989
padding-left: var(${pl === 1 ? "--spacing100" : "--spacing200"});
8090
`};

0 commit comments

Comments
 (0)