diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 20763a2c1a0..ea63c18d459 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -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. */ @@ -652,6 +664,7 @@ export namespace Components { "setFocus": () => Promise; /** * Displays a status-related indicator icon. + * @deprecated Use `icon-start` instead. */ "status": Status; /** @@ -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. */ @@ -8332,6 +8357,7 @@ declare namespace LocalJSX { "open"?: boolean; /** * Displays a status-related indicator icon. + * @deprecated Use `icon-start` instead. */ "status"?: Status; /** diff --git a/packages/calcite-components/src/components/block-section/block-section.scss b/packages/calcite-components/src/components/block-section/block-section.scss index 74aafa8ce11..863ae4f77e6 100644 --- a/packages/calcite-components/src/components/block-section/block-section.scss +++ b/packages/calcite-components/src/components/block-section/block-section.scss @@ -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, @@ -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 { @@ -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(); diff --git a/packages/calcite-components/src/components/block-section/block-section.tsx b/packages/calcite-components/src/components/block-section/block-section.tsx index 8da1777686d..909834bf36f 100644 --- a/packages/calcite-components/src/components/block-section/block-section.tsx +++ b/packages/calcite-components/src/components/block-section/block-section.tsx @@ -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, @@ -48,6 +49,15 @@ 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. */ @@ -55,6 +65,8 @@ export class BlockSection implements LocalizedComponent, T9nComponent, LoadableC /** * Displays a status-related indicator icon. + * + * @deprecated Use `icon-start` instead. */ @Prop({ reflect: true }) status: Status; @@ -198,14 +210,33 @@ 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 ( + + ); + } + 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; @@ -213,7 +244,7 @@ export class BlockSection implements LocalizedComponent, T9nComponent, LoadableC toggleDisplay === "switch" ? (
+ {this.renderIcon(this.iconStart)}
{text}
+ + {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 */}
- {/* we use calcite-label to use a simple component that will allow us to prevent keyboard focus by setting tabindex="-1" on the host */} - - + +
) : ( - + + ); return ( diff --git a/packages/calcite-components/src/components/block-section/resources.ts b/packages/calcite-components/src/components/block-section/resources.ts index a33e0955350..67509fc607f 100644 --- a/packages/calcite-components/src/components/block-section/resources.ts +++ b/packages/calcite-components/src/components/block-section/resources.ts @@ -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", }; diff --git a/packages/calcite-components/src/components/block/block.stories.ts b/packages/calcite-components/src/components/block/block.stories.ts index 0450cfe1061..36e14e63e27 100644 --- a/packages/calcite-components/src/components/block/block.stories.ts +++ b/packages/calcite-components/src/components/block/block.stories.ts @@ -303,3 +303,29 @@ export const toggleDisplayWithLongText_TestOnly = (): string => `; + +export const icons_TestOnly = (): string => html` + + +

Block section content

+
+ + +

Block section content

+
+
+`; diff --git a/packages/calcite-components/src/demos/block.html b/packages/calcite-components/src/demos/block.html index 83915821656..afd8bce9dbe 100644 --- a/packages/calcite-components/src/demos/block.html +++ b/packages/calcite-components/src/demos/block.html @@ -65,6 +65,45 @@ + +
+
icon-start/end + switch + deprecated status (shown)
+ +
+ + + + +
+
+ + +
+
icon-start/end + button + deprecated status
+ +
+ + + + +
+
+
switch collapsible + no controls