Skip to content

Commit cdca471

Browse files
authored
feat: xs select component (#22036)
* feat: xs select component * fix: cleanup * fix: update snapshots * fix: remove testing stories * fix: remove testing stories
1 parent ff54a38 commit cdca471

8 files changed

Lines changed: 39 additions & 36 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
@@ -8751,6 +8751,7 @@ Map {
87518751
"size": {
87528752
"args": [
87538753
[
8754+
"xs",
87548755
"sm",
87558756
"md",
87568757
"lg",

packages/react/src/components/Select/Select.stories.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import React from 'react';
99

1010
import { WithLayer } from '../../../.storybook/templates/WithLayer';
11-
1211
import { default as Select, SelectSkeleton } from '../Select';
1312
import SelectItem from '../SelectItem';
1413
import SelectItemGroup from '../SelectItemGroup';

packages/react/src/components/Select/Select.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export interface SelectProps
124124
/**
125125
* Specify the size of the Select Input.
126126
*/
127-
size?: 'sm' | 'md' | 'lg';
127+
size?: 'xs' | 'sm' | 'md' | 'lg';
128128

129129
/**
130130
* @deprecated please use decorator instead.
@@ -208,6 +208,7 @@ const Select = forwardRef<HTMLSelectElement, SelectProps>(
208208
warn,
209209
warnText,
210210
});
211+
211212
const selectClasses = classNames({
212213
[`${prefix}--select`]: true,
213214
[`${prefix}--select--inline`]: inline,
@@ -220,14 +221,16 @@ const Select = forwardRef<HTMLSelectElement, SelectProps>(
220221
[`${prefix}--select--fluid--focus`]: isFluid && isFocused,
221222
[`${prefix}--select--slug`]: slug,
222223
[`${prefix}--select--decorator`]: decorator,
224+
[`${prefix}--select--${size}`]: size,
225+
[`${prefix}--layout--size-${size}`]: size,
223226
});
227+
224228
const labelClasses = classNames(`${prefix}--label`, {
225229
[`${prefix}--visually-hidden`]: hideLabel,
226230
[`${prefix}--label--disabled`]: normalizedProps.disabled,
227231
});
228232
const inputClasses = classNames({
229233
[`${prefix}--select-input`]: true,
230-
[`${prefix}--select-input--${size}`]: size,
231234
});
232235
const error = normalizedProps.validation;
233236
const helperTextClasses = classNames(`${prefix}--form__helper-text`, {
@@ -453,7 +456,7 @@ Select.propTypes = {
453456
/**
454457
* Specify the size of the Select Input.
455458
*/
456-
size: PropTypes.oneOf(['sm', 'md', 'lg']),
459+
size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg']),
457460

458461
slug: deprecate(
459462
PropTypes.node,

packages/react/src/components/Select/__tests__/Select-test.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,12 @@ describe('Select', () => {
304304
});
305305

306306
it('should respect size prop', () => {
307-
render(<Select id="select" labelText="Select" size="sm" />);
308-
309-
expect(screen.getByRole('combobox')).toHaveClass(
310-
`${prefix}--select-input--sm`
307+
const { container } = render(
308+
<Select id="select" labelText="Select" size="sm" />
311309
);
310+
const selectWrapper = container.querySelector(`.${prefix}--select`);
311+
expect(selectWrapper).toHaveClass(`${prefix}--select--sm`);
312+
expect(selectWrapper).toHaveClass(`${prefix}--layout--size-sm`);
312313
});
313314

314315
it('should respect warn prop', () => {

packages/styles/scss/components/select/_select.scss

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
@use '../../utilities/component-reset';
1818
@use '../../utilities/convert';
1919
@use '../../utilities/focus-outline' as *;
20+
@use '../../utilities/layout';
2021
@use '../../utilities/skeleton' as *;
2122

2223
/// Select styles
@@ -25,6 +26,7 @@
2526
@mixin select {
2627
.#{$prefix}--select {
2728
@include component-reset.reset;
29+
@include layout.use('size', $default: 'md', $min: 'xs', $max: 'lg');
2830

2931
position: relative;
3032
display: flex;
@@ -43,13 +45,15 @@
4345
.#{$prefix}--select-input {
4446
@include type-style('body-compact-01');
4547
@include focus-outline('reset');
48+
@include layout.use('size', $default: 'md', $min: 'xs', $max: 'lg');
49+
@include layout.use('density', $default: 'normal');
4650

4751
display: block;
4852
border: none;
4953
border-radius: 0;
5054
appearance: none;
5155
background-color: $field;
52-
block-size: convert.to-rem(40px);
56+
block-size: layout.size('height');
5357
border-block-end: 1px solid $border-strong;
5458
color: $text-primary;
5559
cursor: pointer;
@@ -102,16 +106,6 @@
102106
}
103107
}
104108

105-
.#{$prefix}--select-input--sm {
106-
block-size: convert.to-rem(32px);
107-
max-block-size: convert.to-rem(32px);
108-
}
109-
110-
.#{$prefix}--select-input--lg {
111-
block-size: convert.to-rem(48px);
112-
max-block-size: convert.to-rem(48px);
113-
}
114-
115109
.#{$prefix}--select--disabled .#{$prefix}--label,
116110
.#{$prefix}--select--disabled .#{$prefix}--form__helper-text {
117111
color: $text-disabled;
@@ -370,6 +364,21 @@
370364
inset-inline-end: -($divider-width);
371365
}
372366

367+
.#{$prefix}--select--decorator
368+
.#{$prefix}--select-input__wrapper
369+
.#{$prefix}--select-input
370+
~ .#{$prefix}--select__invalid-icon,
371+
.#{$prefix}--select--slug
372+
.#{$prefix}--select-input__wrapper[data-invalid]
373+
.#{$prefix}--select-input
374+
~ .#{$prefix}--select__invalid-icon,
375+
.#{$prefix}--select--slug
376+
.#{$prefix}--select-input__wrapper
377+
.#{$prefix}--select-input
378+
~ .#{$prefix}--select__invalid-icon {
379+
inset-inline-end: $spacing-11;
380+
}
381+
373382
.#{$prefix}--select--decorator
374383
.#{$prefix}--select-input:has(
375384
~ .#{$prefix}--select__inner-wrapper--decorator
@@ -421,19 +430,4 @@
421430
.#{$prefix}--slug::before {
422431
display: block;
423432
}
424-
425-
.#{$prefix}--select--decorator
426-
.#{$prefix}--select-input__wrapper
427-
.#{$prefix}--select-input
428-
~ .#{$prefix}--select__invalid-icon,
429-
.#{$prefix}--select--slug
430-
.#{$prefix}--select-input__wrapper[data-invalid]
431-
.#{$prefix}--select-input
432-
~ .#{$prefix}--select__invalid-icon,
433-
.#{$prefix}--select--slug
434-
.#{$prefix}--select-input__wrapper
435-
.#{$prefix}--select-input
436-
~ .#{$prefix}--select__invalid-icon {
437-
inset-inline-end: $spacing-11;
438-
}
439433
}

packages/web-components/src/components/select/select.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ $css--plex: true !default;
1515
@use '@carbon/styles/scss/utilities/convert' as *;
1616
@use '@carbon/styles/scss/components/fluid-select' as *;
1717
@use '@carbon/styles/scss/utilities/visually-hidden' as *;
18+
@use '@carbon/styles/scss/layout' as *;
1819

1920
$divider-width: 1px;
2021

2122
:host(#{$prefix}-select) {
2223
@extend .#{$prefix}--select;
24+
@include emit-layout-tokens();
2325

2426
outline: none;
2527

@@ -109,3 +111,5 @@ $divider-width: 1px;
109111
inset-inline-end: $spacing-09;
110112
}
111113
}
114+
115+
@include emit-layout-tokens-to-shadow-host('#{$prefix}-select');

packages/web-components/src/components/select/select.stories.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ const actions = html`
5656
`;
5757

5858
const sizes = {
59+
[`Extra small size (${INPUT_SIZE.EXTRA_SMALL})`]: INPUT_SIZE.EXTRA_SMALL,
5960
[`Small size (${INPUT_SIZE.SMALL})`]: INPUT_SIZE.SMALL,
6061
[`Medium size (${INPUT_SIZE.MEDIUM})`]: INPUT_SIZE.MEDIUM,
6162
[`Large size (${INPUT_SIZE.LARGE})`]: INPUT_SIZE.LARGE,

packages/web-components/src/components/select/select.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ class CDSSelect extends FormMixin(LitElement) {
332332
* The input box size.
333333
*/
334334
@property({ reflect: true })
335-
size = INPUT_SIZE.MEDIUM;
335+
size?: INPUT_SIZE;
336336

337337
/**
338338
* The value of the text area.
@@ -435,7 +435,7 @@ class CDSSelect extends FormMixin(LitElement) {
435435

436436
const inputClasses = classMap({
437437
[`${prefix}--select-input`]: true,
438-
[`${prefix}--select-input--${size}`]: size,
438+
[`${prefix}--select-input--${size}`]: size !== undefined,
439439
});
440440

441441
const labelClasses = classMap({

0 commit comments

Comments
 (0)