Skip to content

Commit 8215314

Browse files
anveshmekalabenelan
authored andcommitted
feat(combobox, combobox-item-group): add component tokens (#11623)
**Related Issue:** #7180 ## Summary Adds following tokens in `combobox` component : `--calcite-combobox-icon-color`: Specifies the component's icon color. `--calcite-combobox-icon-color-hover`: Specifies the component's icon color when hovered. `--calcite-combobox-background-color`: Specifies the background color of the component's listbox. `--calcite-combobox-input-border-color`: Specifies the border color of the component's input. `--calcite-combobox-input-background-color`: Specifies the background color of the component's input. `--calcite-combobox-input-height`: Specifies the height of the component's input. `--calcite-combobox-input-text-color`: Specifies the text color of the component's input. Adds following tokens in `combobox-item-group` component: `--calcite-combobox-item-group-text-color`: Specifies the text color of the component. `--calcite-combobox-item-group-border-color`: Specifies the border color of the component.
1 parent 08c767b commit 8215314

File tree

8 files changed

+238
-59
lines changed

8 files changed

+238
-59
lines changed

packages/calcite-components/src/components/combobox-item-group/combobox-item-group.scss

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
/**
2+
* CSS Custom Properties
3+
*
4+
* These properties can be overridden using the component's tag as selector.
5+
*
6+
* @prop --calcite-combobox-item-group-text-color: Specifies the text color of the component.
7+
* @prop --calcite-combobox-item-group-border-color: Specifies the border color of the component.
8+
*/
9+
110
.scale--s {
211
@apply text-n2h;
312
--calcite-combobox-item-spacing-unit: theme("spacing.2");
@@ -24,23 +33,23 @@
2433
}
2534

2635
.label {
27-
@apply text-color-3 box-border flex w-full min-w-0 max-w-full;
36+
@apply box-border flex w-full min-w-0 max-w-full;
2837
}
2938

3039
.title {
3140
--calcite-combobox-item-indent-value: calc(
3241
var(--calcite-combobox-item-spacing-unit) * var(--calcite-combobox-item-spacing-indent-multiplier)
3342
);
3443
border: 0 solid;
35-
@apply border-b-color-3
36-
text-color-2
37-
word-break
44+
@apply word-break
3845
block
3946
flex-1
4047
border-b
4148
font-bold;
4249
padding: var(--calcite-combobox-item-spacing-unit);
4350
margin-inline-start: var(--calcite-combobox-item-indent-value);
51+
color: var(--calcite-combobox-item-group-text-color, var(--calcite-color-text-2));
52+
border-block-end-color: var(--calcite-combobox-item-group-border-color, var(--calcite-color-border-3));
4453
}
4554

4655
::slotted(calcite-combobox-item-group:not([after-empty-group])) {

packages/calcite-components/src/components/combobox/combobox.e2e.ts

+106-6
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ import {
2222
createEventTimePropValuesAsserter,
2323
findAll,
2424
getElementXY,
25+
isElementFocused,
2526
newProgrammaticE2EPage,
2627
skipAnimations,
2728
} from "../../tests/utils";
2829
import { DEBOUNCE } from "../../utils/resources";
30+
import { ComponentTestTokens, themed } from "../../tests/commonTests/themed";
2931
import { CSS } from "./resources";
3032
import { Combobox } from "./combobox";
3133

@@ -1869,14 +1871,10 @@ describe("calcite-combobox", () => {
18691871
await page.waitForChanges();
18701872

18711873
await element.press("ArrowLeft");
1872-
expect(chips[0]).not.toHaveClass("chip--active");
1873-
expect(chips[1]).not.toHaveClass("chip--active");
1874-
expect(chips[2]).toHaveClass("chip--active");
1874+
expect(await isElementFocused(page, `calcite-chip[data-test-id="chip-2"]`, { shadowed: true })).toBe(true);
18751875

18761876
await element.press("ArrowLeft");
1877-
expect(chips[0]).not.toHaveClass("chip--active");
1878-
expect(chips[1]).toHaveClass("chip--active");
1879-
expect(chips[2]).not.toHaveClass("chip--active");
1877+
expect(await isElementFocused(page, `calcite-chip[data-test-id="chip-1"]`, { shadowed: true })).toBe(true);
18801878

18811879
await element.press("Delete");
18821880
chips = await findAll(page, "#myCombobox >>> calcite-chip");
@@ -2976,4 +2974,106 @@ describe("calcite-combobox", () => {
29762974
const combobox = await page.find("calcite-combobox");
29772975
expect((await combobox.getProperty("selectedItems")).length).toBe(1);
29782976
});
2977+
2978+
describe("theme", () => {
2979+
describe("default", () => {
2980+
const comboboxHTML = html`<calcite-combobox label="test" max-items="6" open>
2981+
<calcite-combobox-item-group value="Trees" label="Trees">
2982+
<calcite-combobox-item value="Pine" text-label="Pine">
2983+
<calcite-combobox-item value="Pine Nested" text-label="Pine Nested"></calcite-combobox-item>
2984+
</calcite-combobox-item>
2985+
</calcite-combobox-item-group>
2986+
<calcite-combobox-item value="Sequoia" disabled text-label="Sequoia"></calcite-combobox-item>
2987+
<calcite-combobox-item value="Douglas Fir" text-label="Douglas Fir" selected></calcite-combobox-item>
2988+
</calcite-combobox>`;
2989+
2990+
const comboboxTokens: ComponentTestTokens = {
2991+
"--calcite-combobox-input-height": {
2992+
shadowSelector: `.${CSS.input}`,
2993+
selector: "calcite-combobox",
2994+
targetProp: "height",
2995+
},
2996+
"--calcite-combobox-input-background-color": {
2997+
shadowSelector: `.${CSS.wrapper}`,
2998+
selector: "calcite-combobox",
2999+
targetProp: "backgroundColor",
3000+
},
3001+
"--calcite-combobox-input-border-color": {
3002+
shadowSelector: `.${CSS.wrapper}`,
3003+
selector: "calcite-combobox",
3004+
targetProp: "borderColor",
3005+
},
3006+
"--calcite-combobox-input-text-color": {
3007+
shadowSelector: `.${CSS.wrapper}`,
3008+
selector: "calcite-combobox",
3009+
targetProp: "color",
3010+
},
3011+
"--calcite-combobox-icon-color": {
3012+
shadowSelector: `.${CSS.icon}`,
3013+
selector: "calcite-combobox",
3014+
targetProp: "color",
3015+
},
3016+
"--calcite-combobox-icon-color-hover": {
3017+
shadowSelector: `.${CSS.icon}`,
3018+
selector: "calcite-combobox",
3019+
targetProp: "color",
3020+
state: "hover",
3021+
},
3022+
"--calcite-combobox-background-color": {
3023+
shadowSelector: `.${CSS.listContainer}`,
3024+
selector: "calcite-combobox",
3025+
targetProp: "backgroundColor",
3026+
},
3027+
"--calcite-combobox-item-group-text-color": {
3028+
selector: "calcite-combobox-item-group",
3029+
shadowSelector: ".title",
3030+
targetProp: "color",
3031+
},
3032+
"--calcite-combobox-item-group-border-color": {
3033+
selector: "calcite-combobox-item-group",
3034+
shadowSelector: ".title",
3035+
targetProp: "borderBottomColor",
3036+
},
3037+
};
3038+
themed(comboboxHTML, comboboxTokens);
3039+
});
3040+
3041+
describe("placeholder icon", () => {
3042+
const comboboxWithPlaceHolderIconHTML = html` <calcite-combobox
3043+
label="test"
3044+
placeholder="select element"
3045+
placeholder-icon="layers"
3046+
>
3047+
<calcite-combobox-item value="Trees" text-label="Trees"></calcite-combobox-item>
3048+
<calcite-combobox-item value="Sequoia" disabled text-label="Sequoia"></calcite-combobox-item>
3049+
<calcite-combobox-item value="Douglas Fir" text-label="Douglas Fir"></calcite-combobox-item>
3050+
</calcite-combobox>`;
3051+
3052+
const comboboxTokens: ComponentTestTokens = {
3053+
"--calcite-combobox-icon-color": {
3054+
shadowSelector: `.${CSS.placeholderIcon}`,
3055+
selector: "calcite-combobox",
3056+
targetProp: "color",
3057+
},
3058+
};
3059+
themed(comboboxWithPlaceHolderIconHTML, comboboxTokens);
3060+
});
3061+
3062+
describe("single select", () => {
3063+
const singleSelectComboboxHTML = html` <calcite-combobox label="test" selection-mode="single">
3064+
<calcite-combobox-item value="Trees" text-label="Trees"></calcite-combobox-item>
3065+
<calcite-combobox-item value="Sequoia" disabled text-label="Sequoia"></calcite-combobox-item>
3066+
<calcite-combobox-item value="Douglas Fir" text-label="Douglas Fir" selected></calcite-combobox-item>
3067+
</calcite-combobox>`;
3068+
3069+
const comboboxTokens: ComponentTestTokens = {
3070+
"--calcite-combobox-input-text-color": {
3071+
shadowSelector: `.${CSS.wrapper}`,
3072+
selector: "calcite-combobox",
3073+
targetProp: "color",
3074+
},
3075+
};
3076+
themed(singleSelectComboboxHTML, comboboxTokens);
3077+
});
3078+
});
29793079
});

packages/calcite-components/src/components/combobox/combobox.scss

+21-43
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
*
44
* These properties can be overridden using the component's tag as selector.
55
*
6+
* @prop --calcite-combobox-icon-color: Specifies the component's icon color.
7+
* @prop --calcite-combobox-icon-color-hover: Specifies the component's icon color when hovered.
8+
* @prop --calcite-combobox-background-color: Specifies the background color of the component's listbox.
9+
* @prop --calcite-combobox-input-border-color: Specifies the border color of the component's input.
10+
* @prop --calcite-combobox-input-background-color: Specifies the background color of the component's input.
611
* @prop --calcite-combobox-input-height: Specifies the height of the component's input.
12+
* @prop --calcite-combobox-input-text-color: Specifies the text color of the component's input.
713
*/
814

915
:host {
@@ -50,19 +56,17 @@
5056
}
5157

5258
.wrapper {
53-
@apply bg-foreground-1
54-
text-color-1
55-
focus-base
56-
flex
57-
border-color-input
58-
border
59-
border-solid;
59+
@apply focus-base flex border border-solid;
6060
padding-block: calc(var(--calcite-combobox-item-spacing-unit-s) / 4);
6161
padding-inline: var(--calcite-combobox-item-spacing-unit-l);
6262

63+
background-color: var(--calcite-combobox-input-background-color, var(--calcite-color-foreground-1));
64+
color: var(--calcite-combobox-input-text-color, var(--calcite-color-text-1));
65+
border-color: var(--calcite-combobox-input-border-color, var(--calcite-color-border-input));
66+
6367
&:hover {
6468
.icon {
65-
color: var(--calcite-color-text-1);
69+
color: var(--calcite-combobox-icon-color-hover, var(--calcite-color-text-1));
6670
}
6771
}
6872
}
@@ -97,13 +101,7 @@
97101
}
98102

99103
.grid-input {
100-
@apply flex
101-
flex-grow
102-
flex-wrap
103-
items-center
104-
relative
105-
truncate
106-
p-0;
104+
@apply flex flex-grow flex-wrap items-center relative truncate p-0;
107105

108106
gap: var(--calcite-combobox-item-spacing-unit-s);
109107
margin-inline-end: var(--calcite-combobox-item-spacing-unit-s);
@@ -115,21 +113,14 @@
115113
}
116114

117115
.input {
118-
@apply appearance-none
119-
bg-transparent
120-
border-none
121-
flex-grow
122-
font-inherit
123-
text-color-1
124-
text-ellipsis
125-
overflow-hidden
126-
p-0;
116+
@apply appearance-none bg-transparent border-none flex-grow font-inherit text-color-1 text-ellipsis overflow-hidden p-0;
127117
font-size: inherit;
128118
block-size: var(--calcite-combobox-input-height);
129119
line-height: var(--calcite-combobox-input-height);
130120
inline-size: 100%;
131121
margin-block-end: var(--calcite-combobox-item-spacing-unit-s);
132122
min-inline-size: 4.8125rem;
123+
133124
&:focus {
134125
@apply outline-none;
135126
}
@@ -149,10 +140,7 @@
149140
}
150141

151142
.input--hidden {
152-
@apply pointer-events-none
153-
w-0
154-
min-w-0
155-
opacity-0;
143+
@apply pointer-events-none w-0 min-w-0 opacity-0;
156144
}
157145

158146
.input--icon {
@@ -161,7 +149,7 @@
161149
}
162150

163151
.placeholder-icon {
164-
color: var(--calcite-color-text-3);
152+
color: var(--calcite-combobox-icon-color, var(--calcite-color-text-3));
165153
}
166154

167155
.input-wrap {
@@ -173,12 +161,7 @@
173161
}
174162

175163
.label {
176-
@apply pointer-events-none
177-
max-w-full
178-
flex-auto
179-
truncate
180-
p-0
181-
font-normal;
164+
@apply pointer-events-none max-w-full flex-auto truncate p-0 font-normal;
182165
block-size: var(--calcite-combobox-input-height);
183166
line-height: var(--calcite-combobox-input-height);
184167
}
@@ -196,7 +179,7 @@
196179
@apply flex-none;
197180

198181
.icon {
199-
color: var(--calcite-color-text-3);
182+
color: var(--calcite-combobox-icon-color, var(--calcite-color-text-3));
200183
}
201184
}
202185

@@ -219,10 +202,9 @@
219202
}
220203

221204
.list-container {
222-
@apply bg-foreground-1
223-
max-h-menu
224-
overflow-y-auto;
205+
@apply max-h-menu overflow-y-auto;
225206
inline-size: var(--calcite-dropdown-width, 100%);
207+
background-color: var(--calcite-combobox-background-color, var(--calcite-color-foreground-1));
226208
}
227209

228210
.list {
@@ -242,10 +224,6 @@ calcite-chip {
242224
max-inline-size: 100%;
243225
}
244226

245-
.chip--active {
246-
@apply bg-foreground-3;
247-
}
248-
249227
.chip--invisible {
250228
@apply absolute invisible;
251229
}

packages/calcite-components/src/components/combobox/combobox.tsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -1418,8 +1418,7 @@ export class Combobox
14181418
const { activeChipIndex, readOnly, scale, selectionMode, messages } = this;
14191419
return this.selectedItems.map((item, i) => {
14201420
const chipClasses = {
1421-
chip: true,
1422-
"chip--active": activeChipIndex === i,
1421+
[CSS.chip]: true,
14231422
};
14241423
const ancestors = [...getItemAncestors(item)].reverse();
14251424
const itemLabel = getLabel(item);
@@ -1739,9 +1738,9 @@ export class Combobox
17391738
<div
17401739
ariaLive="polite"
17411740
class={{
1742-
wrapper: true,
1743-
"wrapper--single": singleSelectionMode || !this.selectedItems.length,
1744-
"wrapper--active": open,
1741+
[CSS.wrapper]: true,
1742+
[CSS.wrapperSingle]: singleSelectionMode || !this.selectedItems.length,
1743+
[CSS.wrapperActive]: open,
17451744
}}
17461745
onClick={this.clickHandler}
17471746
onKeyDown={this.keyDownHandler}

packages/calcite-components/src/components/combobox/resources.ts

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const AllComboboxChildrenSelector = `${ComboboxItemSelector}, ${ComboboxI
55
export const CSS = {
66
input: "input",
77
inputHidden: "input--hidden",
8+
chip: "chip",
89
chipInvisible: "chip--invisible",
910
selectionDisplayFit: "selection-display-fit",
1011
selectionDisplaySingle: "selection-display-single",
@@ -14,6 +15,9 @@ export const CSS = {
1415
selectedIcon: "selected-icon",
1516
floatingUIContainer: "floating-ui-container",
1617
screenReadersOnly: "screen-readers-only",
18+
wrapper: "wrapper",
19+
wrapperSingle: "wrapper--single",
20+
wrapperActive: "wrapper--active",
1721
};
1822

1923
export const IDS = {

packages/calcite-components/src/custom-theme.stories.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ import { navigationUserTokens, navigationUsers } from "./custom-theme/navigation
5454
import { tileTokens, tile } from "./custom-theme/tile";
5555
import { navigationTokens, navigation } from "./custom-theme/navigation";
5656
import { menuItem, menuItemTokens } from "./custom-theme/menu-item";
57+
import {
58+
comboboxTokens,
59+
comboboxWithPlaceHolderIcon,
60+
defaultCombobox,
61+
singleSelectCombobox,
62+
} from "./custom-theme/combobox";
5763
import { panel, panelTokens } from "./custom-theme/panel";
5864
import { shellPanel, shellPanelTokens } from "./custom-theme/shell-panel";
5965

@@ -133,7 +139,8 @@ const kitchenSink = (args: Record<string, string>, useTestValues = false) =>
133139
<div style="width: 40px; height: 40px;">${actionMenu}</div>
134140
${icon}
135141
</div>
136-
${inlineEditable} ${input} ${inputNumber} ${inputText} ${select}
142+
${inlineEditable} ${input} ${inputNumber} ${inputText} ${select} ${singleSelectCombobox}
143+
${comboboxWithPlaceHolderIcon} ${defaultCombobox}
137144
</div>
138145
<div class="demo-column">
139146
<div>${card}</div>
@@ -176,6 +183,7 @@ const componentTokens = {
176183
...cardTokens,
177184
...checkboxTokens,
178185
...chipTokens,
186+
...comboboxTokens,
179187
...datePickerTokens,
180188
...DropdownTokens,
181189
...DropdownItemTokens,

0 commit comments

Comments
 (0)