Skip to content

Commit

Permalink
feat(combobox, checkbox, input-time-zone, select, text-area): add `st…
Browse files Browse the repository at this point in the history
…atus` property (#8304)

**Related Issue:** #8057 #3406

## Summary

Add the `status` property to additional form components in preparation
of adding internal input messages for validation. I split these changes
out from #8305, which is where the new stories are.
  • Loading branch information
benelan authored Dec 1, 2023
1 parent 1fe4cb4 commit a44e9fe
Show file tree
Hide file tree
Showing 16 changed files with 120 additions and 8 deletions.
10 changes: 10 additions & 0 deletions packages/calcite-components/src/components/checkbox/checkbox.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@
color: theme("backgroundColor.background");
}
}

:host([status="invalid"]:not([checked])) {
.check-svg {
box-shadow: inset 0 0 0 1px var(--calcite-ui-danger);
}
.toggle:focus {
@apply focus-outset-danger;
}
}

:host([checked]),
:host([indeterminate]) {
.check-svg {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const simple = (): string => html`
${boolean("disabled", false)}
${boolean("indeterminate", false)}
scale="${select("scale", ["s", "m", "l"], "m")}"
status="${select("status", ["idle", "invalid", "valid"], "idle")}"
></calcite-checkbox>
${text("label", "Checkbox")}
</calcite-label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
setComponentLoaded,
setUpLoadableComponent,
} from "../../utils/loadable";
import { Scale } from "../interfaces";
import { Scale, Status } from "../interfaces";

@Component({
tag: "calcite-checkbox",
Expand Down Expand Up @@ -96,6 +96,9 @@ export class Checkbox
/** Specifies the size of the component. */
@Prop({ reflect: true }) scale: Scale = "m";

/** Specifies the status of the input field, which determines message and icons. */
@Prop({ reflect: true }) status: Status = "idle";

/** The component's value. */
@Prop() value: any;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@
@apply focus-inset;
}

:host([status="invalid"]) .wrapper {
@apply border-color-danger;
}

:host([status="invalid"]:focus-within) .wrapper {
@apply focus-inset-danger;
}

.wrapper--single {
padding-block: 0;
padding-inline: var(--calcite-combobox-item-spacing-unit-l);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const single = (): string => html`
max-items="${number("max-items", 0)}"
placeholder="${text("placeholder", "placeholder")}"
scale="${select("scale", ["s", "m", "l"], "m")}"
status="${select("status", ["idle", "invalid", "valid"], "idle")}"
>
<calcite-combobox-item icon="altitude" value="altitude" text-label="Altitude" selected></calcite-combobox-item>
<calcite-combobox-item icon="article" value="article" text-label="Article"></calcite-combobox-item>
Expand Down Expand Up @@ -296,6 +297,7 @@ export const nestedItems = (): string => html`
${boolean("disabled", false)}
${boolean("allow-custom-values", false)}
max-items="${number("max-items", 0)}"
status="${select("status", ["idle", "invalid", "valid"], "idle")}"
>
<calcite-combobox-item value="ITEM-0-0" text-label="Level 1">
<calcite-combobox-item value="ITEM-0-1" text-label="Level 2"></calcite-combobox-item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ import {
T9nComponent,
updateMessages,
} from "../../utils/t9n";
import { Scale, SelectionMode } from "../interfaces";
import { Scale, SelectionMode, Status } from "../interfaces";
import { ComboboxMessages } from "./assets/combobox/t9n";
import { ComboboxChildElement, SelectionDisplay } from "./interfaces";
import { ComboboxChildSelector, ComboboxItem, ComboboxItemGroup, CSS } from "./resources";
Expand Down Expand Up @@ -224,6 +224,9 @@ export class Combobox
/** Specifies the size of the component. */
@Prop({ reflect: true }) scale: Scale = "m";

/** Specifies the status of the input field, which determines message and icons. */
@Prop({ reflect: true }) status: Status = "idle";

@Watch("selectionMode")
@Watch("scale")
handlePropsChange(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export const simple = (): string => html`
<calcite-input-text
scale="${select("scale", ["s", "m", "l"], "m")}"
status="${select("status", ["idle", "valid", "invalid"], "idle")}"
status="${select("status", ["idle", "invalid", "valid"], "idle")}"
alignment="${select("alignment", ["start", "end"], "start")}"
prefix-text="${text("prefix-text", "")}"
suffix-text="${text("suffix-text", "")}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const simple = (): string => html`
${boolean("disabled", false)}
mode="${select("mode", ["offset", "name"], "offset")}"
scale="${select("scale", ["s", "m", "l"], "m")}"
status="${select("status", ["idle", "invalid", "valid"], "idle")}"
></calcite-input-time-zone>
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
SupportedLocale,
} from "../../utils/locale";
import { TimeZoneItem, TimeZoneMode } from "./interfaces";
import { Scale } from "../interfaces";
import { Scale, Status } from "../interfaces";
import {
connectMessages,
disconnectMessages,
Expand Down Expand Up @@ -157,6 +157,9 @@ export class InputTimeZone
/** Specifies the size of the component. */
@Prop({ reflect: true }) scale: Scale = "m";

/** Specifies the status of the input field, which determines message and icons. */
@Prop({ reflect: true }) status: Status = "idle";

/**
* The component's value, where the value is the time zone offset or the difference, in minutes, between the selected time zone and UTC.
*
Expand Down Expand Up @@ -381,6 +384,7 @@ export class InputTimeZone
overlayPositioning={this.overlayPositioning}
scale={this.scale}
selectionMode="single-persist"
status={this.status}
// 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.setComboboxRef}
>
Expand Down
11 changes: 11 additions & 0 deletions packages/calcite-components/src/components/select/select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,17 @@ select:disabled {
border-inline-width: theme("borderWidth.0") theme("borderWidth.DEFAULT");
}

:host([status="invalid"]) {
select,
.icon-container {
@apply border-color-danger;
}
select:focus,
.icon-container:focus {
@apply focus-inset-danger;
}
}

.select:focus ~ .icon-container {
@apply border-color-transparent;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
modesDarkDefault,
} from "../../../.storybook/utils";
import { html } from "../../../support/formatting";
import { boolean, text } from "@storybook/addon-knobs";
import { select, boolean, text } from "@storybook/addon-knobs";
import selectReadme from "../select/readme.md";
import optionReadme from "../option/readme.md";
import optionGroupReadme from "../option-group/readme.md";
Expand All @@ -27,6 +27,30 @@ const createSelectAttributes: (options?: { exceptions: string[] }) => Attributes
return this;
},
},
{
name: "status",
commit(): Attribute {
this.value = select("status", ["idle", "invalid", "valid"], "idle", group);
delete this.build;
return this;
},
},
{
name: "width",
commit(): Attribute {
this.value = select("width", ["auto", "full", "half"], "auto", group);
delete this.build;
return this;
},
},
{
name: "scale",
commit(): Attribute {
this.value = select("scale", ["s", "m", "l"], "m", group);
delete this.build;
return this;
},
},
],
exceptions
);
Expand Down
8 changes: 5 additions & 3 deletions packages/calcite-components/src/components/select/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
setUpLoadableComponent,
} from "../../utils/loadable";
import { createObserver } from "../../utils/observers";
import { Scale, Width } from "../interfaces";
import { Scale, Status, Width } from "../interfaces";
import { CSS } from "./resources";
import { getIconScale } from "../../utils/component";

Expand Down Expand Up @@ -77,8 +77,7 @@ export class Select
*
* When not set, the component will be associated with its ancestor form element, if any.
*/
@Prop({ reflect: true })
form: string;
@Prop({ reflect: true }) form: string;

/**
* Accessible name for the component.
Expand All @@ -105,6 +104,9 @@ export class Select
*/
@Prop({ reflect: true }) scale: Scale = "m";

/** Specifies the status of the input field, which determines message and icons. */
@Prop({ reflect: true }) status: Status = "idle";

/** The component's `selectedOption` value. */
@Prop({ mutable: true }) value: string = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@ textarea {
}
}

:host([status="invalid"]) {
textarea {
@apply border-color-danger;
}
textarea:focus {
@apply focus-inset-danger;
}
}

.readonly {
@apply bg-background font-medium;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default {
export const simple = (): string => html`
<calcite-text-area
scale="${select("scale", ["s", "m", "l"], "m")}"
status="${select("status", ["idle", "invalid", "valid"], "idle")}"
placeholder="${text("placeholder", "Add Notes")}"
${boolean("disabled", false)}
columns="${number("columns", 20)}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
} from "../../utils/interactive";
import { CharacterLengthObj } from "./interfaces";
import { guid } from "../../utils/guid";
import { Status } from "../interfaces";

/**
* @slot - A slot for adding text.
Expand Down Expand Up @@ -176,6 +177,9 @@ export class TextArea
/** Specifies the size of the component. */
@Prop({ reflect: true }) scale: "l" | "m" | "s" = "m";

/** Specifies the status of the input field, which determines message and icons. */
@Prop({ reflect: true }) status: Status = "idle";

/** The component's value. */
@Prop({ mutable: true }) value: string;

Expand Down
30 changes: 30 additions & 0 deletions packages/calcite-components/src/demos/checkbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,36 @@ <h1 style="margin: 0 auto; text-align: center">Checkbox</h1>
</div>
</div>

<!--
**************************************************
* UNCHECKED INVALID
**************************************************
-->
<div class="parent">
<!-- small -->
<div class="child right-aligned-text">unchecked invalid</div>

<div class="child">
<calcite-label>
<calcite-checkbox name="invalid-s-unchecked" scale="s" status="invalid" required></calcite-checkbox>
</calcite-label>
</div>

<!-- medium -->
<div class="child">
<calcite-label>
<calcite-checkbox name="invalid-m-unchecked" scale="m" status="invalid" required></calcite-checkbox>
</calcite-label>
</div>

<!-- large -->
<div class="child">
<calcite-label>
<calcite-checkbox name="invalid-l-unchecked" scale="l" status="invalid" required></calcite-checkbox>
</calcite-label>
</div>
</div>

<!--
**************************************************
* CHECKED
Expand Down

0 comments on commit a44e9fe

Please sign in to comment.