Skip to content

Commit

Permalink
feat(segmented-control, segmented-control-item): add component tokens (
Browse files Browse the repository at this point in the history
…#11359)

**Related Issue:** #7180

## Summary

Add `segmented-control`, `segmented-control-item` component tokens.

`--calcite-segmented-control-color`: Specifies the component's color.
`--calcite-segmented-control-background-color`: Specifies the
component's background color.
`--calcite-segmented-control-border-color`: Specifies the component's
border color.
`--calcite-segmented-control-shadow`: Specifies the component's shadow.
`--calcite-segmented-control-icon-color`: Specifies the icons's color.
  • Loading branch information
driskull authored and benelan committed Feb 8, 2025
1 parent 289a431 commit 91fcb70
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting";
import { describe, expect, it } from "vitest";
import { renders, hidden } from "../../tests/commonTests";
import { renders, hidden, themed } from "../../tests/commonTests";
import { html } from "../../../support/formatting";
import { CSS } from "./resources";

describe("calcite-segmented-control-item", () => {
Expand Down Expand Up @@ -40,15 +41,15 @@ describe("calcite-segmented-control-item", () => {
it("renders icon at start if requested", async () => {
const page = await newE2EPage();
await page.setContent(`
<calcite-segmented-control-item icon-start="car">Content</calcite-accordion-item>`);
<calcite-segmented-control-item icon-start="car">Content</calcite-segmented-control-item>`);
const icon = await page.find(`calcite-segmented-control-item >>> .${CSS.icon}`);
expect(icon).not.toBe(null);
});

it("does not render icon if not requested", async () => {
const page = await newE2EPage();
await page.setContent(`
<calcite-segmented-control-item>Content</calcite-accordion-item>`);
<calcite-segmented-control-item>Content</calcite-segmented-control-item>`);
const icon = await page.find(`calcite-segmented-control-item >>> .${CSS.icon}`);
expect(icon).toBe(null);
});
Expand Down Expand Up @@ -108,4 +109,31 @@ describe("calcite-segmented-control-item", () => {
expect(element).not.toHaveAttribute("icon-end");
});
});

describe("theme", () => {
themed("calcite-segmented-control-item", {
"--calcite-segmented-control-color": {
shadowSelector: `.${CSS.label}`,
targetProp: "color",
},
"--calcite-segmented-control-background-color": {
shadowSelector: `.${CSS.label}`,
targetProp: "backgroundColor",
},
"--calcite-segmented-control-border-color": {
shadowSelector: `.${CSS.label}`,
targetProp: "borderColor",
},
"--calcite-segmented-control-shadow": {
shadowSelector: `.${CSS.label}`,
targetProp: "boxShadow",
},
});
themed(html`<calcite-segmented-control-item icon-start="car">Content</calcite-segmented-control-item>`, {
"--calcite-segmented-control-icon-color": {
shadowSelector: `.${CSS.icon}`,
targetProp: "--calcite-icon-color",
},
});
});
});
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
/**
* CSS Custom Properties
*
* These properties can be overridden using the component's tag as selector.
*
* @prop --calcite-segmented-control-color: Specifies the component's color.
* @prop --calcite-segmented-control-background-color: Specifies the component's background color.
* @prop --calcite-segmented-control-border-color: Specifies the component's border color.
* @prop --calcite-segmented-control-shadow: Specifies the component's shadow.
* @prop --calcite-segmented-control-icon-color: Specifies the icons's color.
*/

:host {
@apply flex
cursor-pointer
self-stretch
font-normal;
font-normal
focus-base;
transition:
background-color var(--calcite-internal-animation-timing-fast) ease-in-out,
border-color var(--calcite-animation-timing) ease-in-out;
}

:host label {
@apply text-color-3
pointer-events-none
.label {
@apply pointer-events-none
m-0.5
box-border
flex
flex-1
items-center;
color: var(--calcite-segmented-control-color, var(--calcite-color-text-3));
background-color: var(--calcite-segmented-control-background-color);
box-shadow: var(--calcite-segmented-control-shadow);
border-color: var(--calcite-segmented-control-border-color);
transition:
background-color var(--calcite-internal-animation-timing-fast) ease-in-out,
border-color var(--calcite-internal-animation-timing-fast) ease-in-out,
Expand All @@ -26,10 +42,6 @@
@apply justify-center;
}

// focus styles
:host {
@apply focus-base;
}
:host(:focus) {
@apply focus-inset;
outline-offset: -1px;
Expand All @@ -49,42 +61,47 @@
@apply text-0h px-4 py-2.5;
}

:host(:hover) label {
@apply bg-foreground-2 text-color-1;
:host(:hover) .label {
background-color: var(--calcite-segmented-control-background-color, var(--calcite-color-foreground-2));
color: var(--calcite-segmented-control-color, var(--calcite-color-text-1));
}

:host(:active) label {
@apply bg-foreground-3;
:host(:active) .label {
background-color: var(--calcite-segmented-control-background-color, var(--calcite-color-foreground-3));
}

:host([checked]) label {
@apply bg-brand border-color-brand cursor-default text-color-inverse;
:host([checked]) .label {
@apply cursor-default;
background-color: var(--calcite-segmented-control-background-color, var(--calcite-color-brand));
border-color: var(--calcite-segmented-control-border-color, var(--calcite-color-brand));
color: var(--calcite-segmented-control-color, var(--calcite-color-text-inverse));
}

:host([checked]) .label--outline,
:host([checked]) .label--outline-fill {
@apply bg-foreground-1 border-color-brand;
box-shadow: inset 0 0 0 1px theme("backgroundColor.brand");
color: theme("backgroundColor.brand");
background-color: var(--calcite-segmented-control-background-color, var(--calcite-color-foreground-1));
border-color: var(--calcite-segmented-control-border-color, var(--calcite-color-brand));
box-shadow: var(--calcite-segmented-control-shadow, inset 0 0 0 1px var(--calcite-color-brand));
color: var(--calcite-segmented-control-color, var(--calcite-color-brand));
}

:host([checked]) .label--outline {
@apply bg-transparent;
background-color: var(--calcite-segmented-control-background-color, transparent);
}

::slotted(input) {
@apply hidden;
}

@media (forced-colors: active) {
:host([checked]) label {
:host([checked]) .label {
background-color: highlight;
}
:host([checked]) .label--outline,
:host([checked]) .label--outline-fill {
@apply outline-none;
}
:host([checked]) label:not([class~="label--outline"]) .icon {
:host([checked]) .label:not([class~="label--outline"]) .icon {
color: highlightText;
}
}
Expand All @@ -97,6 +114,7 @@

margin-inline-start: var(--calcite-internal-segmented-control-icon-margin-start);
margin-inline-end: var(--calcite-internal-segmented-control-icon-margin-end);
--calcite-icon-color: var(--calcite-segmented-control-icon-color);
}

:host([icon-start]) .label--scale-s {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import {
labelable,
reflects,
renders,
themed,
} from "../../tests/commonTests";
import { GlobalTestProps } from "../../tests/utils";
import type { SegmentedControl } from "./segmented-control";
import { CSS } from "./resources";

describe("calcite-segmented-control", () => {
describe("defaults", () => {
Expand Down Expand Up @@ -495,4 +497,13 @@ describe("calcite-segmented-control", () => {
);
});
});

describe("theme", () => {
themed("calcite-segmented-control", {
"--calcite-segmented-control-border-color": {
shadowSelector: `.${CSS.itemWrapper}`,
targetProp: "outlineColor",
},
});
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
/**
* CSS Custom Properties
*
* These properties can be overridden using the component's tag as selector.
*
* @prop --calcite-segmented-control-border-color: Specifies the component's border color.
*/

:host {
@apply flex flex-col;
}

.item-wrapper {
@apply bg-foreground-1 flex;
inline-size: fit-content;
outline: 1px solid var(--calcite-color-border-input);
outline: 1px solid var(--calcite-segmented-control-border-color, var(--calcite-color-border-input));
outline-offset: -1px;
}

Expand Down
3 changes: 2 additions & 1 deletion packages/calcite-components/src/custom-theme.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { notice, noticeTokens } from "./custom-theme/notice";
import { pagination, paginationTokens } from "./custom-theme/pagination";
import { popover, popoverTokens } from "./custom-theme/popover";
import { progress, progressTokens } from "./custom-theme/progress";
import { segmentedControl } from "./custom-theme/segmented-control";
import { segmentedControl, segmentedControlTokens } from "./custom-theme/segmented-control";
import { select, selectTokens } from "./custom-theme/select";
import { rating, ratingTokens } from "./custom-theme/rating";
import { slider, sliderTokens } from "./custom-theme/slider";
Expand Down Expand Up @@ -179,6 +179,7 @@ const componentTokens = {
...paginationTokens,
...popoverTokens,
...progressTokens,
...segmentedControlTokens,
...ratingTokens,
...selectTokens,
...sliderTokens,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { html } from "../../support/formatting";

export const segmentedControlTokens = {
calciteSegmentedControlColor: "",
calciteSegmentedControlBackgroundColor: "",
calciteSegmentedControlBorderColor: "",
calciteSegmentedControlShadow: "",
calciteSegmentedControlIconColor: "",
};

export const segmentedControl = html`<calcite-label>
Segmented Control
<calcite-segmented-control>
Expand Down
41 changes: 41 additions & 0 deletions packages/calcite-components/src/demos/segmented-control.html
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,47 @@
</calcite-segmented-control>
</div>
</div>

<div
class="parent-flex"
style="
--calcite-segmented-control-color: red;
--calcite-segmented-control-background-color: blue;
--calcite-segmented-control-border-color: pink;
--calcite-segmented-control-shadow: box-shadow: 5px 5px 5px orange;
--calcite-segmented-control-icon-color: yellow;
"
>
<div class="child-flex right-aligned-text">themed</div>

<!-- solid -->
<div class="child-flex">
<calcite-segmented-control scale="s">
<calcite-segmented-control-item icon-end="car" value="react" checked>React</calcite-segmented-control-item>
<calcite-segmented-control-item value="ember">Ember</calcite-segmented-control-item>
<calcite-segmented-control-item value="angular">Angular</calcite-segmented-control-item>
<calcite-segmented-control-item value="vue">Vue</calcite-segmented-control-item>
</calcite-segmented-control>
</div>

<div class="child-flex">
<calcite-segmented-control scale="m">
<calcite-segmented-control-item icon-end="car" value="react" checked>React</calcite-segmented-control-item>
<calcite-segmented-control-item value="ember">Ember</calcite-segmented-control-item>
<calcite-segmented-control-item value="angular">Angular</calcite-segmented-control-item>
<calcite-segmented-control-item value="vue">Vue</calcite-segmented-control-item>
</calcite-segmented-control>
</div>

<div class="child-flex">
<calcite-segmented-control scale="l">
<calcite-segmented-control-item icon-end="car" value="react" checked>React</calcite-segmented-control-item>
<calcite-segmented-control-item value="ember">Ember</calcite-segmented-control-item>
<calcite-segmented-control-item value="angular">Angular</calcite-segmented-control-item>
<calcite-segmented-control-item value="vue">Vue</calcite-segmented-control-item>
</calcite-segmented-control>
</div>
</div>
</demo-dom-swapper>
</body>
</html>

0 comments on commit 91fcb70

Please sign in to comment.