Skip to content

Commit

Permalink
feat(block-section): add icon property (deprecates status) (#9194)
Browse files Browse the repository at this point in the history
**Related Issue:** #8110

## Summary
Remove the `status` property and instead add an `icon` property.

Provide a demo and screenshot coverage.
  • Loading branch information
Elijbet committed May 11, 2024
1 parent 344b2fc commit c31bf36
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 49 deletions.
26 changes: 26 additions & 0 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,18 @@ export namespace Components {
"status": Status;
}
interface CalciteBlockSection {
/**
* Specifies an icon to display at the end of the component.
*/
"iconEnd": string;
/**
* Displays the `iconStart` and/or `iconEnd` as flipped when the element direction is right-to-left (`"rtl"`).
*/
"iconFlipRtl": FlipContext;
/**
* Specifies an icon to display at the start of the component.
*/
"iconStart": string;
/**
* Use this property to override individual strings used by the component.
*/
Expand All @@ -652,6 +664,7 @@ export namespace Components {
"setFocus": () => Promise<void>;
/**
* Displays a status-related indicator icon.
* @deprecated Use `icon-start` instead.
*/
"status": Status;
/**
Expand Down Expand Up @@ -8314,6 +8327,18 @@ declare namespace LocalJSX {
"status"?: Status;
}
interface CalciteBlockSection {
/**
* Specifies an icon to display at the end of the component.
*/
"iconEnd"?: string;
/**
* Displays the `iconStart` and/or `iconEnd` as flipped when the element direction is right-to-left (`"rtl"`).
*/
"iconFlipRtl"?: FlipContext;
/**
* Specifies an icon to display at the start of the component.
*/
"iconStart"?: string;
/**
* Use this property to override individual strings used by the component.
*/
Expand All @@ -8332,6 +8357,7 @@ declare namespace LocalJSX {
"open"?: boolean;
/**
* Displays a status-related indicator icon.
* @deprecated Use `icon-start` instead.
*/
"status"?: Status;
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@
border-0
bg-transparent
font-medium;
}

.toggle--switch {
.status-icon {
margin-inline-start: theme("margin.2");
}
gap: var(--calcite-spacing-md);
}

.toggle--switch,
Expand All @@ -53,33 +49,49 @@
}
}

.section-header .status-icon {
@apply self-end;
.label {
@apply flex items-center justify-center my-1;

margin-inline-start: var(--calcite-spacing-md);
}

.section-header__text {
@apply mx-3
my-0
@apply my-0
flex-auto;

text-align: initial;
word-wrap: anywhere;
}

.toggle--switch-container {
@apply flex items-center relative bg-transparent w-full;
.toggle-container {
@apply flex items-center relative bg-transparent;
word-break: break-word;

.focus-guard {
--calcite-label-margin-bottom: 0;
@apply absolute pointer-events-none;
inset-inline-end: 0;
margin-inline-start: theme("margin.1");
.toggle--switch__content {
@apply flex flex-auto items-center;
}

.icon--end,
.icon--start {
@apply flex items-center;

color: var(--calcite-color-text-3);

&:hover {
color: var(--calcite-color-text-1);
}
}

.switch {
@apply flex items-center;

inset-block-start: 50%;
transform: translate(0, 50%);
}
}

.toggle--switch__content {
@apply flex flex-auto items-center;
.status-icon {
@apply flex items-center;
}

.status-icon.valid {
Expand All @@ -90,10 +102,8 @@
color: theme("colors.danger");
}

:host([toggle-display="switch"]) .toggle {
.toggle--switch__content {
@apply me-7;
}
.chevron-icon {
@apply flex items-center;
}

@include base-component();
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import {
VNode,
Watch,
} from "@stencil/core";
import { focusFirstTabbable, getElementDir, toAriaBoolean } from "../../utils/dom";
import { focusFirstTabbable, toAriaBoolean } from "../../utils/dom";
import { isActivationKey } from "../../utils/key";
import { connectLocalized, disconnectLocalized, LocalizedComponent } from "../../utils/locale";
import { FlipContext } from "../interfaces";
import {
connectMessages,
disconnectMessages,
Expand Down Expand Up @@ -48,13 +49,24 @@ export class BlockSection implements LocalizedComponent, T9nComponent, LoadableC
//
// --------------------------------------------------------------------------

/** Specifies an icon to display at the end of the component. */
@Prop({ reflect: true }) iconEnd: string;

/** Displays the `iconStart` and/or `iconEnd` as flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl: FlipContext;

/** Specifies an icon to display at the start of the component. */
@Prop({ reflect: true }) iconStart: string;

/**
* When `true`, expands the component and its contents.
*/
@Prop({ reflect: true, mutable: true }) open = false;

/**
* Displays a status-related indicator icon.
*
* @deprecated Use `icon-start` instead.
*/
@Prop({ reflect: true }) status: Status;

Expand Down Expand Up @@ -198,22 +210,41 @@ export class BlockSection implements LocalizedComponent, T9nComponent, LoadableC
) : null;
}

renderIcon(icon: string): VNode {
const { iconFlipRtl } = this;

if (icon === undefined) {
return null;
}

const flipRtlStart = iconFlipRtl === "both" || iconFlipRtl === "start";
const flipRtlEnd = iconFlipRtl === "both" || iconFlipRtl === "end";

const isIconStart = icon === this.iconStart;

/** Icon scale is not variable as the component does not have a scale property */
return (
<calcite-icon
class={isIconStart ? this.iconStart : this.iconEnd}
flipRtl={isIconStart ? flipRtlStart : flipRtlEnd}
icon={isIconStart ? this.iconStart : this.iconEnd}
key={isIconStart ? CSS.iconStart : CSS.iconEnd}
scale="s"
/>
);
}

render(): VNode {
const { el, messages, open, text, toggleDisplay } = this;
const dir = getElementDir(el);
const arrowIcon = open
? ICONS.menuOpen
: dir === "rtl"
? ICONS.menuClosedLeft
: ICONS.menuClosedRight;
const { messages, open, text, toggleDisplay } = this;
const arrowIcon = open ? ICONS.menuOpen : ICONS.menuClosed;

const toggleLabel = open ? messages.collapse : messages.expand;

const headerNode =
toggleDisplay === "switch" ? (
<div
class={{
[CSS.toggleSwitchContainer]: true,
[CSS.toggleContainer]: true,
}}
>
<div
Expand All @@ -230,31 +261,42 @@ export class BlockSection implements LocalizedComponent, T9nComponent, LoadableC
tabIndex={0}
title={toggleLabel}
>
{this.renderIcon(this.iconStart)}
<div class={CSS.toggleSwitchContent}>
<span class={CSS.toggleSwitchText}>{text}</span>
</div>

{this.renderIcon(this.iconEnd)}
{this.renderStatusIcon()}
{/* we use calcite-label to use a simple component that will allow us to prevent keyboard focus by setting tabindex="-1" on the host */}
</div>
{/* we use calcite-label to use a simple component that will allow us to prevent keyboard focus by setting tabindex="-1" on the host */}
<calcite-label class={CSS.focusGuard} layout="inline" tabIndex={-1}>
<calcite-switch checked={open} label={toggleLabel} scale="s" />
<calcite-label class={CSS.label} layout="inline" tabIndex={-1}>
<calcite-switch checked={open} class={CSS.switch} label={toggleLabel} scale="s" />
</calcite-label>
</div>
) : (
<button
aria-controls={IDS.content}
aria-expanded={toAriaBoolean(open)}
<div
class={{
[CSS.sectionHeader]: true,
[CSS.toggle]: true,
[CSS.toggleContainer]: true,
}}
id={IDS.toggle}
onClick={this.toggleSection}
>
<calcite-icon icon={arrowIcon} scale="s" />
<span class={CSS.sectionHeaderText}>{text}</span>
{this.renderStatusIcon()}
</button>
<button
aria-controls={IDS.content}
aria-expanded={toAriaBoolean(open)}
class={{
[CSS.sectionHeader]: true,
[CSS.toggle]: true,
}}
id={IDS.toggle}
onClick={this.toggleSection}
>
{this.renderIcon(this.iconStart)}
<span class={CSS.sectionHeaderText}>{text}</span>
{this.renderIcon(this.iconEnd)}
{this.renderStatusIcon()}
<calcite-icon class={CSS.chevronIcon} icon={arrowIcon} scale="s" />
</button>
</div>
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@ export const IDS = {
};

export const CSS = {
chevronIcon: "chevron-icon",
content: "content",
focusGuard: "focus-guard",
iconStart: "icon--start",
iconEnd: "icon--end",
invalid: "invalid",
label: "label",
sectionHeader: "section-header",
sectionHeaderText: "section-header__text",
statusIcon: "status-icon",
switch: "switch",
toggle: "toggle",
toggleSwitch: "toggle--switch",
toggleSwitchContainer: "toggle--switch-container",
toggleContainer: "toggle-container",
toggleSwitchContent: "toggle--switch__content",
toggleSwitchText: "toggle--switch__text",
valid: "valid",
};

export const ICONS = {
menuOpen: "chevron-down",
menuClosedLeft: "chevron-left",
menuClosedRight: "chevron-right",
menuOpen: "chevron-up",
menuClosed: "chevron-down",
valid: "check-circle",
invalid: "exclamation-mark-triangle",
};
26 changes: 26 additions & 0 deletions packages/calcite-components/src/components/block/block.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,29 @@ export const toggleDisplayWithLongText_TestOnly = (): string =>
</calcite-notice>
</calcite-block-section>
</calcite-block>`;

export const icons_TestOnly = (): string => html`
<calcite-block heading="Heading" description="summary" collapsible open>
<calcite-block-section
text="Planes, trains, and automobiles are some examples of modes of transportation"
open
icon-end="pen"
icon-start="pen"
toggle-display="switch"
status="valid"
>
<p>Block section content</p>
</calcite-block-section>
<calcite-block-section
text="Planes, trains, and automobiles are some examples of modes of transportation"
open
icon-end="pen"
icon-start="pen"
toggle-display="button"
status="valid"
>
<p>Block section content</p>
</calcite-block-section>
</calcite-block>
`;
39 changes: 39 additions & 0 deletions packages/calcite-components/src/demos/block.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,45 @@
</div>
</div>

<!-- icon-start/end + switch + deprecated status (shown)-->
<div class="parent">
<div class="child right-aligned-text">icon-start/end + switch + deprecated status (shown)</div>

<div class="child">
<calcite-block heading="Heading" description="summary" collapsible open>
<calcite-block-section
text="Planes, trains, and automobiles are some examples of modes of transportation"
open
icon-end="pen"
icon-start="pen"
toggle-display="switch"
text="a block-section"
status="valid"
>
</calcite-block-section>
</calcite-block>
</div>
</div>

<!-- icon-start/end + button + deprecated status -->
<div class="parent">
<div class="child right-aligned-text">icon-start/end + button + deprecated status</div>

<div class="child">
<calcite-block heading="Heading" description="summary" collapsible open>
<calcite-block-section
text="Planes, trains, and automobiles are some examples of modes of transportation"
open
icon-end="pen"
icon-start="pen"
toggle-display="button"
text="a block-section"
>
</calcite-block-section>
</calcite-block>
</div>
</div>

<!-- switch collapsible + no controls -->
<div class="parent">
<div class="child right-aligned-text">switch collapsible + no controls</div>
Expand Down

0 comments on commit c31bf36

Please sign in to comment.