Skip to content

Commit dbb3bfa

Browse files
authored
feat(password-input): new xs size (#22112)
* feat(password-input): new xs size * test: add tests * fix: invalid icon positioning * fix: use icon-only for fluid variant * refactor: tooltip styles * chore: rename attribute
1 parent 5bad7a3 commit dbb3bfa

12 files changed

Lines changed: 62 additions & 85 deletions

File tree

packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7983,6 +7983,7 @@ Map {
79837983
"size": {
79847984
"args": [
79857985
[
7986+
"xs",
79867987
"sm",
79877988
"md",
79887989
"lg",

packages/react/src/components/TextInput/PasswordInput.stories.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ Default.argTypes = {
113113
action: 'onClick',
114114
},
115115
size: {
116-
options: ['sm', 'md', 'lg', 'xl'],
116+
options: ['xs', 'sm', 'md', 'lg'],
117117
control: {
118118
type: 'select',
119119
},

packages/react/src/components/TextInput/PasswordInput.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ export interface PasswordInputProps
140140
showPasswordLabel?: string;
141141

142142
/**
143-
* Specify the size of the Text Input. Supports `sm`, `md`, or `lg`.
143+
* Specify the size of the Text Input. Supports `xs`, `sm`, `md`, or `lg`.
144144
*/
145-
size?: 'sm' | 'md' | 'lg';
145+
size?: 'xs' | 'sm' | 'md' | 'lg';
146146

147147
/**
148148
* Specify the alignment of the tooltip to the icon-only button.
@@ -196,7 +196,7 @@ const PasswordInput = forwardRef<unknown, PasswordInputProps>(
196196
onTogglePasswordVisibility,
197197
placeholder,
198198
readOnly,
199-
size = 'md',
199+
size,
200200
showPasswordLabel = 'Show password',
201201
tooltipPosition = 'bottom',
202202
tooltipAlignment = 'end',
@@ -234,7 +234,6 @@ const PasswordInput = forwardRef<unknown, PasswordInputProps>(
234234
[`${prefix}--text-input--invalid`]: normalizedProps.invalid,
235235
[`${prefix}--text-input--warning`]: normalizedProps.warn,
236236
[`${prefix}--text-input--${size}`]: size, // TODO: V12 - Remove this class
237-
[`${prefix}--layout--size-${size}`]: size,
238237
}
239238
);
240239
const sharedTextInputProps = {
@@ -289,6 +288,7 @@ const PasswordInput = forwardRef<unknown, PasswordInputProps>(
289288
`${prefix}--text-input__field-wrapper`,
290289
{
291290
[`${prefix}--text-input__field-wrapper--warning`]: normalizedProps.warn,
291+
[`${prefix}--layout--size-${size}`]: size,
292292
}
293293
);
294294
const iconClasses = classNames({
@@ -529,9 +529,9 @@ PasswordInput.propTypes = {
529529
showPasswordLabel: PropTypes.string,
530530

531531
/**
532-
* Specify the size of the Text Input. Supports `sm`, `md`, or `lg`.
532+
* Specify the size of the Text Input. Supports `xs`, `sm`, `md`, or `lg`.
533533
*/
534-
size: PropTypes.oneOf(['sm', 'md', 'lg']),
534+
size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg']),
535535

536536
/**
537537
* Specify the alignment of the tooltip to the icon-only button.

packages/react/src/components/TextInput/__tests__/PasswordInput-test.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2022
2+
* Copyright IBM Corp. 2022, 2026
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -222,13 +222,18 @@ describe('PasswordInput', () => {
222222
});
223223

224224
it('should respect size prop', () => {
225-
render(
225+
const { container } = render(
226226
<PasswordInput id="input-1" labelText="PasswordInput label" size="sm" />
227227
);
228228

229229
expect(screen.getByLabelText('PasswordInput label')).toHaveClass(
230230
`${prefix}--text-input--sm`
231231
);
232+
233+
const fieldWrapper = container.querySelector(
234+
`.${prefix}--text-input__field-wrapper`
235+
);
236+
expect(fieldWrapper).toHaveClass(`${prefix}--layout--size-sm`);
232237
});
233238

234239
it('should respect type prop', () => {

packages/styles/scss/components/text-input/_text-input.scss

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,7 @@
6161
}
6262

6363
.#{$prefix}--password-input {
64-
padding-inline-end: $spacing-08;
65-
}
66-
67-
.#{$prefix}--text-input--sm.#{$prefix}--password-input {
68-
padding-inline-end: $spacing-07;
69-
}
70-
71-
.#{$prefix}--text-input--lg.#{$prefix}--password-input {
72-
padding-inline-end: $spacing-09;
64+
padding-inline-end: layout.size('height');
7365
}
7466

7567
.#{$prefix}--text-input::placeholder {
@@ -123,33 +115,26 @@
123115
justify-content: center;
124116
padding: 0;
125117
border: 0;
118+
aspect-ratio: 1;
126119
background: none;
127120
block-size: 100%;
128121
cursor: pointer;
129-
inline-size: convert.to-rem(40px);
130122
inset-inline-end: 0;
131123
min-block-size: auto;
132124
transition: outline $duration-fast-01 motion(standard, productive);
133125
}
134126

135127
.#{$prefix}--toggle-password-tooltip .#{$prefix}--popover {
136-
inset-inline-start: -($spacing-08);
128+
@include layout.use('size', $default: 'md', $min: 'xs', $max: 'lg');
129+
130+
gap: $spacing-02;
131+
inset-inline-start: calc(-1 * (layout.size('height')));
137132
}
138133

139134
.#{$prefix}--toggle-password-tooltip .#{$prefix}--popover-content {
140135
min-inline-size: $spacing-08;
141136
}
142137

143-
.#{$prefix}--text-input--sm
144-
+ .#{$prefix}--btn.#{$prefix}--text-input--password__visibility__toggle.#{$prefix}--tooltip__trigger {
145-
inline-size: convert.to-rem(32px);
146-
}
147-
148-
.#{$prefix}--text-input--lg
149-
+ .#{$prefix}--btn.#{$prefix}--text-input--password__visibility__toggle.#{$prefix}--tooltip__trigger {
150-
inline-size: convert.to-rem(48px);
151-
}
152-
153138
.#{$prefix}--btn.#{$prefix}--text-input--password__visibility__toggle.#{$prefix}--tooltip__trigger
154139
svg {
155140
fill: $icon-primary;
@@ -164,17 +149,15 @@
164149
padding-inline-end: $spacing-08;
165150
}
166151

167-
.#{$prefix}--text-input--invalid.#{$prefix}--password-input {
168-
padding-inline-end: convert.to-rem(64px);
169-
}
170-
171-
.#{$prefix}--text-input--invalid
172-
+ .#{$prefix}--text-input--password__visibility__toggle {
173-
inset-inline-end: $spacing-05;
152+
.#{$prefix}--text-input--invalid.#{$prefix}--password-input,
153+
.#{$prefix}--text-input--warning.#{$prefix}--password-input {
154+
padding-inline-end: calc(layout.size('height') + 1.5rem);
174155
}
175156

176157
.#{$prefix}--password-input-wrapper .#{$prefix}--text-input__invalid-icon {
177-
inset-inline-end: $spacing-08;
158+
@include layout.use('size', $default: 'md', $min: 'xs', $max: 'lg');
159+
160+
inset-inline-end: layout.size('height');
178161
}
179162

180163
.#{$prefix}--text-input:disabled
@@ -251,10 +234,6 @@
251234
@include focus-outline('invalid');
252235

253236
box-shadow: none;
254-
255-
.#{$prefix}--text-input--password__visibility__toggle {
256-
inset-inline-end: $spacing-08;
257-
}
258237
}
259238

260239
//-----------------------------

packages/web-components/src/components/fluid-password-input/fluid-password-input.scss

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,7 @@ $css--plex: true !default;
4747
inline-size: 100%;
4848
}
4949

50-
.#{$prefix}--btn--icon-only {
51-
border: none;
52-
background-color: transparent;
53-
block-size: 100%;
54-
cursor: pointer;
55-
inline-size: 100%;
56-
57-
&:focus {
58-
@include focus-outline('outline');
59-
}
60-
}
61-
6250
.#{$prefix}--text-input--password__visibility__toggle svg {
6351
pointer-events: none;
6452
}
65-
.#{$prefix}--toggle-password-tooltip {
66-
block-size: 100%;
67-
}
6853
}

packages/web-components/src/components/password-input/__tests__/password-input-test.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2025
2+
* Copyright IBM Corp. 2025, 2026
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -147,6 +147,16 @@ describe('cds-password-input', () => {
147147
expect(
148148
Array.from(classList).some((cls) => cls.includes('--text-input--sm'))
149149
).to.be.true;
150+
151+
const fieldWrapper = el.shadowRoot.querySelector(
152+
'.cds--text-input__field-wrapper'
153+
);
154+
const fieldWrapperClassList = fieldWrapper?.classList || [];
155+
expect(
156+
Array.from(fieldWrapperClassList).some((cls) =>
157+
cls.includes('--layout--size-sm')
158+
)
159+
).to.be.true;
150160
});
151161

152162
it('should apply type attribute', async () => {

packages/web-components/src/components/password-input/defs.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2025
2+
* Copyright IBM Corp. 2025, 2026
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -11,6 +11,11 @@ export { FORM_ELEMENT_COLOR_SCHEME as INPUT_COLOR_SCHEME } from '../../globals/s
1111
* Input size.
1212
*/
1313
export enum INPUT_SIZE {
14+
/**
15+
* Extra small size.
16+
*/
17+
EXTRA_SMALL = 'xs',
18+
1419
/**
1520
* Small size.
1621
*/

packages/web-components/src/components/password-input/password-input.scss

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright IBM Corp. 2025
2+
// Copyright IBM Corp. 2025, 2026
33
//
44
// This source code is licensed under the Apache-2.0 license found in the
55
// LICENSE file in the root directory of this source tree.
@@ -20,10 +20,6 @@ $css--plex: true !default;
2020

2121
inline-size: 100%;
2222
outline: none;
23-
padding-inline-end: $spacing-08;
24-
.#{$prefix}--text-input__invalid-icon {
25-
inset-inline-end: $spacing-08;
26-
}
2723
.#{$prefix}--icon-visibility-on,
2824
.#{$prefix}--icon-visibility-off {
2925
vertical-align: middle;
@@ -44,18 +40,6 @@ $css--plex: true !default;
4440
inline-size: 100%;
4541
}
4642

47-
.#{$prefix}--btn--icon-only {
48-
border: none;
49-
background-color: transparent;
50-
block-size: 100%;
51-
cursor: pointer;
52-
inline-size: 100%;
53-
54-
&:focus {
55-
@include focus-outline('outline');
56-
}
57-
}
58-
5943
.#{$prefix}--text-input--password__visibility__toggle svg {
6044
pointer-events: none;
6145
}

packages/web-components/src/components/password-input/password-input.stories.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
} from './password-input';
1818

1919
const sizes = {
20+
[`Extra small size (${INPUT_SIZE.EXTRA_SMALL})`]: INPUT_SIZE.EXTRA_SMALL,
2021
[`Small size (${INPUT_SIZE.SMALL})`]: INPUT_SIZE.SMALL,
2122
[`Medium size (${INPUT_SIZE.MEDIUM})`]: INPUT_SIZE.MEDIUM,
2223
[`Large size (${INPUT_SIZE.LARGE})`]: INPUT_SIZE.LARGE,

0 commit comments

Comments
 (0)