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(block-section): add icon property (deprecates status) #9194

Merged
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
34c89e7
move chevron to the right side
Elijbet Apr 24, 2024
cfd2feb
update arrow orientation to match similar components
Elijbet Apr 24, 2024
a59e66b
feat(block-section): deprecate status property, add icon property
Elijbet Apr 25, 2024
c3b1822
component tokens and themed test
Elijbet Apr 25, 2024
f7dedd1
cleanup
Elijbet Apr 25, 2024
c56c0c2
deprecate status prop
Elijbet Apr 25, 2024
bbc218a
move status icon so that chevron doesn't overlap
Elijbet Apr 25, 2024
d593ed7
switch and button alignment with regards to icon-end and status
Elijbet Apr 25, 2024
be02634
themed for button and toggle
Elijbet Apr 26, 2024
8576a7c
text no longer overlaps with icons
Elijbet Apr 26, 2024
b058e53
demo icon-start/end with switch/button and deprecated status
Elijbet Apr 26, 2024
c8d42e1
cleanup
Elijbet Apr 26, 2024
7ee0cc3
tidy up - move everything into content
Elijbet Apr 26, 2024
3042e20
remove margin
Elijbet Apr 26, 2024
8e1b7d3
add margin to switch to preserve previous setup
Elijbet Apr 26, 2024
bc0fa4b
12px gap solution
Elijbet Apr 26, 2024
d2b9ad8
cleanup
Elijbet Apr 26, 2024
6ea00d4
cleanup
Elijbet Apr 26, 2024
a0200d9
WIP
Elijbet May 2, 2024
4aacdd9
WIP
Elijbet May 6, 2024
4eb19a5
cleanup
Elijbet May 6, 2024
cebb0a9
internal vars
Elijbet May 6, 2024
cbdd375
cleanup
Elijbet May 6, 2024
99432fe
switch should not be nested
Elijbet May 6, 2024
833133a
cleanup
Elijbet May 7, 2024
f58845f
cleanup
Elijbet May 7, 2024
fea2abd
cleanup
Elijbet May 7, 2024
c9cf981
merge main
Elijbet May 11, 2024
c8d3644
cleanup
Elijbet May 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/calcite-components/conventions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Private/internal properties should be annotated accordingly to avoid exposing th

### Property values

Property values should be meaningful. Avoid using values such as "default" for default values. Instead, use a more descriptive value.
Property values should be meaningful. Avoid using values such as "default" for default values. Instead, use a more descriptive value.

For instance: `placement: "start" | "end" = "start";` is preferred to `placement: "default" | "end" = "default";`

Expand Down
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 @@ -628,6 +628,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 @@ -646,6 +658,7 @@ export namespace Components {
"setFocus": () => Promise<void>;
/**
* Displays a status-related indicator icon.
* @deprecated Use `icon-start` instead.
*/
"status": Status;
/**
Expand Down Expand Up @@ -8015,6 +8028,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 @@ -8033,6 +8058,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: theme("margin.3");
}

.toggle--switch,
Expand All @@ -51,35 +47,58 @@
&:hover {
@apply text-color-1;
}
}

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

.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 {
@apply flex items-center;

color: var(--calcite-internal-block-section-icon-end-color, var(--calcite-color-text-3));
Elijbet marked this conversation as resolved.
Show resolved Hide resolved

&:hover {
color: var(--calcite-internal-block-section-icon-end-color-hover, 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;
}

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

color: var(--calcite-internal-block-section-icon-start-color, var(--calcite-color-text-3));

&:hover {
color: var(--calcite-internal-block-section-icon-start-color-hover, var(--calcite-color-text-1));
}
}

.status-icon.valid {
Expand All @@ -90,10 +109,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
@@ -0,0 +1,31 @@
import { html } from "../../../support/formatting";

export default {
title: "Components/Block Section",
};

export const icons_TestOnly = (): string => html`
<calcite-block heading="Heading" description="summary" collapsible open>
Elijbet marked this conversation as resolved.
Show resolved Hide resolved
<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>
`;
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,37 @@ export class BlockSection implements LocalizedComponent, T9nComponent, LoadableC
) : null;
}

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

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 +257,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 */}
<calcite-label class="label" layout="inline" tabIndex={-1}>
Elijbet marked this conversation as resolved.
Show resolved Hide resolved
<calcite-switch checked={open} class={CSS.switch} label={toggleLabel} scale="s" />
</calcite-label>
</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>
</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,27 @@ export const IDS = {
};

export const CSS = {
chevronIcon: "chevron-icon",
content: "content",
focusGuard: "focus-guard",
iconStart: "icon--start",
iconEnd: "icon--end",
invalid: "invalid",
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",
};