Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(radio-button, radio-button-group): add component tokens #8831

Merged
merged 14 commits into from
Mar 5, 2024
13 changes: 13 additions & 0 deletions packages/calcite-components/src/assets/styles/includes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,16 @@
display: none;
}
}

@mixin outlineNone() {
outline: 2px solid transparent;
outline-offset: 2px;
}

@mixin focusOutset($outline, $outlineOffset) {
outline: var(
#{$outline},
2px solid var(--calcite-ui-focus-color, var(--calcite-color-brand-hover, var(--calcite--color-brand)))
);
outline-offset: var(#{$outlineOffset}, calc(2px * calc(1 - 2 * clamp(0, var(--calcite-offset-invert-focus), 1))));
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
:host {
@apply flex flex-col;
display: flex;
flex-direction: column;
}

:host > .item-wrapper {
@apply flex;
display: flex;
max-inline-size: 100vw;
}

:host([layout="horizontal"]) > .item-wrapper {
@apply flex-row flex-wrap;
flex-direction: row;
flex-wrap: wrap;
}

:host([layout="horizontal"][scale="s"]) > .item-wrapper {
@apply gap-x-4;
column-gap: var(--calcite-spacing-xl);
}

:host([layout="horizontal"][scale="m"]) > .item-wrapper {
@apply gap-x-5;
column-gap: var(--calcite-spacing-xxl);
}

:host([layout="horizontal"][scale="l"]) > .item-wrapper {
@apply gap-x-6;
column-gap: #{$calcite-size-24}; // TODO: need new size token for this size
}

:host([layout="vertical"]) > .item-wrapper {
@apply flex-col;
flex-direction: column;
}

:host([scale="s"]) calcite-input-message {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,92 +1,129 @@
/**
* CSS Custom Properties
*
* These properties can be overridden using the component's tag as selector.
*
* @prop --calcite-radio-button-background-color: Specifies the background color of the component.
* @prop --calcite-radio-button-border-radius: Specifies the border radius of the component.
* @prop --calcite-radio-button-shadow: Specifies the shadow of the component.
* @prop --calcite-radio-button-size: Specifies the size of the component.
* @prop --calcite-radio-focus: Specifies the focus of the component.
*/

:host {
@apply block cursor-pointer;
.container {
@apply relative outline-none;
}
.radio {
@apply bg-foreground-1 cursor-pointer focus-base rounded-full transition-default;
box-shadow: inset 0 0 0 1px var(--calcite-color-border-input);
}
display: block;
cursor: pointer;
}

:host([hovered]),
:host(:not([checked])[focused]:not([disabled])) {
.radio {
box-shadow: inset 0 0 0 2px var(--calcite-color-brand);
}
.container {
position: relative;
@include outlineNone();
}

:host([focused]) {
.radio {
@apply focus-outset;
}
.radio {
background-color: var(--calcite-radio-button-background-color, var(--calcite-color-foreground-1));
cursor: pointer;
outline-color: transparent;
border-radius: var(--calcite-radio-button-border-radius, var(--calcite-corner-radius-pill));
transition:
all var(--calcite-animation-timing) ease-in-out 0s,
outline 0s,
outline-offset 0s;
box-shadow: var(--calcite-radio-button-shadow, inset 0 0 0 1px var(--calcite-color-border-input));
}

@include disabled() {
:host([scale="s"]) .radio {
block-size: var(--calcite-radio-button-size, var(--calcite-font-size--2));
max-inline-size: var(--calcite-radio-button-size, var(--calcite-font-size--2));
min-inline-size: var(--calcite-radio-button-size, var(--calcite-font-size--2));
}

:host([scale="m"]) .radio {
block-size: var(--calcite-radio-button-size, var(--calcite-font-size--1));
max-inline-size: var(--calcite-radio-button-size, var(--calcite-font-size--1));
min-inline-size: var(--calcite-radio-button-size, var(--calcite-font-size--1));
}

:host([scale="l"]) .radio {
block-size: var(--calcite-radio-button-size, var(--calcite-font-size-0));
max-inline-size: var(--calcite-radio-button-size, var(--calcite-font-size-0));
min-inline-size: var(--calcite-radio-button-size, var(--calcite-font-size-0));
}

:host([focused]) {
.radio {
@apply opacity-disabled cursor-default;
@include focusOutset("--calcite-radio-focus", "--calcite-internal-radio-focus-offset");
}
}

:host([hovered][disabled]) {
.radio {
box-shadow: inset 0 0 0 1px var(--calcite-color-border-input);
box-shadow: var(--calcite-radio-button-shadow, inset 0 0 0 1px var(--calcite-color-border-input));
}
}

:host([scale="s"]) {
--calcite-radio-size: theme("fontSize.n2");
}
:host([scale="m"]) {
--calcite-radio-size: theme("fontSize.n1");
}
:host([scale="l"]) {
--calcite-radio-size: theme("fontSize.0");
:host([hovered]),
:host(:not([checked])[focused]:not([disabled])) {
.radio {
box-shadow: var(--calcite-radio-button-shadow, inset 0 0 0 2px var(--calcite-color-brand));
}
}

.radio {
block-size: var(--calcite-radio-size);
max-inline-size: var(--calcite-radio-size);
min-inline-size: var(--calcite-radio-size);
@include disabled() {
.radio {
opacity: var(--calcite-opacity-disabled);
cursor: default;
}
}

:host([scale="s"][checked]),
:host([hovered][scale="s"][checked][disabled]) {
.radio {
box-shadow: inset 0 0 0 4px var(--calcite-color-brand);
box-shadow: var(--calcite-radio-button-shadow, inset 0 0 0 4px var(--calcite-color-brand));
}
}

:host([scale="s"][focused][checked]:not([disabled])) {
.radio {
box-shadow:
box-shadow: var(
--calcite-radio-button-shadow,
inset 0 0 0 4px var(--calcite-color-brand),
0 0 0 2px var(--calcite-color-foreground-1);
0 0 0 2px var(--calcite-color-foreground-1)
);
}
}

:host([scale="m"][checked]),
:host([hovered][scale="m"][checked][disabled]) {
.radio {
box-shadow: inset 0 0 0 5px var(--calcite-color-brand);
box-shadow: var(--calcite-radio-button-shadow, inset 0 0 0 5px var(--calcite-color-brand));
}
}

:host([scale="m"][focused][checked]:not([disabled])) {
.radio {
box-shadow:
box-shadow: var(
--calcite-radio-button-shadow,
inset 0 0 0 5px var(--calcite-color-brand),
0 0 0 2px var(--calcite-color-foreground-1);
0 0 0 2px var(--calcite-color-foreground-1)
);
}
}

:host([scale="l"][checked]),
:host([hovered][scale="l"][checked][disabled]) {
.radio {
box-shadow: inset 0 0 0 6px var(--calcite-color-brand);
box-shadow: var(--calcite-radio-button-shadow, inset 0 0 0 6px var(--calcite-color-brand));
}
}

:host([scale="l"][focused][checked]:not([disabled])) {
.radio {
box-shadow:
box-shadow: var(
--calcite-radio-button-shadow,
inset 0 0 0 6px var(--calcite-color-brand),
0 0 0 2px var(--calcite-color-foreground-1);
0 0 0 2px var(--calcite-color-foreground-1)
);
}
}

Expand All @@ -95,12 +132,25 @@
:host([checked][disabled]) {
.radio::after {
content: "";
inline-size: var(--calcite-radio-size);
block-size: var(--calcite-radio-size);
background-color: windowText;
display: block;
}
}

:host([checked][scale="s"]) .radio::after {
inline-size: var(--calcite-radio-button-size, var(--calcite-font-size--2));
block-size: var(--calcite-radio-button-size, var(--calcite-font-size--2));
}

:host([checked][scale="m"]) .radio::after {
inline-size: var(--calcite-radio-button-size, var(--calcite-font-size--1));
block-size: var(--calcite-radio-button-size, var(--calcite-font-size--1));
}

:host([checked][scale="l"]) .radio::after {
inline-size: var(--calcite-radio-button-size, var(--calcite-font-size-0));
block-size: var(--calcite-radio-button-size, var(--calcite-font-size-0));
}
}

@include hidden-form-input();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,30 @@ export const darkModeRTL_TestOnly = (): string => html`
darkModeRTL_TestOnly.parameters = { modes: modesDarkDefault };

export const disabled_TestOnly = (): string => html`<calcite-radio-button checked disabled></calcite-radio-button>`;

export const theming_TestOnly = (): string =>
html`<style>
calcite-radio-button {
--calcite-radio-button-background-color: orange;
--calcite-radio-button-border-radius: 50%;
--calcite-radio-focus: 2px solid red;
--calcite-radio-button-shadow: 0 0 0 2px blue;
--calcite-radio-button-size: 20px;
}
</style>
<calcite-label>
Radio:
<calcite-radio-button></calcite-radio-button>
</calcite-label>
<calcite-label>
Checked radio:
<calcite-radio-button checked></calcite-radio-button>
</calcite-label>
<calcite-label>
Checked disabled radio:
<calcite-radio-button checked disabled></calcite-radio-button>
</calcite-label>
<calcite-label>
Checked focused radio:
<calcite-radio-button checked focused></calcite-radio-button>
</calcite-label> `;
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ export class RadioButton
// eslint-disable-next-line react/jsx-sort-props -- ref should be last so node attrs/props are in sync (see https://github.com/Esri/calcite-design-system/pull/6530)
ref={this.setContainerEl}
>
<div class="radio" />
<div class={CSS.radio} />
</div>
<HiddenFormInputSlot component={this} />
</InteractiveContainer>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const CSS = {
container: "container",
radio: "radio",
};
Loading