Skip to content

Commit

Permalink
feat: add iconFlipRtl prop to all components with a convenience icon …
Browse files Browse the repository at this point in the history
…prop #5496 (#5878)

**Related Issue:** #5496

## Summary

feat: add iconFlipRtl prop to all components with a convenience icon
prop #5496
  • Loading branch information
driskull committed Dec 15, 2022
1 parent 9c479ca commit 30a080b
Show file tree
Hide file tree
Showing 13 changed files with 111 additions and 20 deletions.
22 changes: 19 additions & 3 deletions src/components/accordion-item/accordion-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from "../../utils/conditionalSlot";
import { CSS_UTILITY } from "../../utils/resources";
import { SLOTS, CSS } from "./resources";
import { Position } from "../interfaces";
import { FlipContext, Position } from "../interfaces";
import { ItemKeyEvent, RegistryEntry, RequestedItem } from "./interfaces";

/**
Expand Down Expand Up @@ -58,6 +58,9 @@ export class AccordionItem implements ConditionalSlotComponent {
/** Specifies an icon to display at the end of the component. */
@Prop({ reflect: true }) iconEnd: string;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl: FlipContext;

//--------------------------------------------------------------------------
//
// Events
Expand Down Expand Up @@ -136,12 +139,25 @@ export class AccordionItem implements ConditionalSlotComponent {
}

render(): VNode {
const { iconFlipRtl } = this;
const dir = getElementDir(this.el);
const iconStartEl = this.iconStart ? (
<calcite-icon class={CSS.iconStart} icon={this.iconStart} key="icon-start" scale="s" />
<calcite-icon
class={CSS.iconStart}
flipRtl={iconFlipRtl === "both" || iconFlipRtl === "start"}
icon={this.iconStart}
key="icon-start"
scale="s"
/>
) : null;
const iconEndEl = this.iconEnd ? (
<calcite-icon class={CSS.iconEnd} icon={this.iconEnd} key="icon-end" scale="s" />
<calcite-icon
class={CSS.iconEnd}
flipRtl={iconFlipRtl === "both" || iconFlipRtl === "end"}
icon={this.iconEnd}
key="icon-end"
scale="s"
/>
) : null;
const { description } = this;
return (
Expand Down
9 changes: 7 additions & 2 deletions src/components/action/action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ export class Action
/** Specifies an icon to display. */
@Prop() icon: string;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

/**
* When `true`, displays a visual indicator.
*/
Expand Down Expand Up @@ -235,13 +238,15 @@ export class Action
}

renderIconContainer(): VNode {
const { loading, icon, scale, el } = this;
const { loading, icon, scale, el, iconFlipRtl } = this;
const iconScale = scale === "l" ? "m" : "s";
const loaderScale = scale === "l" ? "l" : "m";
const calciteLoaderNode = loading ? (
<calcite-loader inline label={this.messages.loading} scale={loaderScale} />
) : null;
const calciteIconNode = icon ? <calcite-icon icon={icon} scale={iconScale} /> : null;
const calciteIconNode = icon ? (
<calcite-icon flipRtl={iconFlipRtl} icon={icon} scale={iconScale} />
) : null;
const iconNode = calciteLoaderNode || calciteIconNode;
const hasIconToDisplay = iconNode || el.children?.length;

Expand Down
11 changes: 9 additions & 2 deletions src/components/alert/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen
*/
@Prop({ reflect: true }) icon: string | boolean;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

/** Specifies an accessible name for the component. */
@Prop() label!: string;

Expand Down Expand Up @@ -225,7 +228,7 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen
</div>
);

const { open, autoClose, label, placement, queued, requestedIcon } = this;
const { open, autoClose, label, placement, queued, requestedIcon, iconFlipRtl } = this;
const role = autoClose ? "alert" : "alertdialog";
const hidden = !open;

Expand Down Expand Up @@ -256,7 +259,11 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen
>
{requestedIcon ? (
<div class="alert-icon">
<calcite-icon icon={requestedIcon} scale={this.scale === "l" ? "m" : "s"} />
<calcite-icon
flipRtl={iconFlipRtl}
icon={requestedIcon}
scale={this.scale === "l" ? "m" : "s"}
/>
</div>
) : null}
<div class="alert-content">
Expand Down
6 changes: 5 additions & 1 deletion src/components/combobox-item/combobox-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ export class ComboboxItem implements ConditionalSlotComponent, InteractiveCompon
/** Specifies an icon to display. */
@Prop({ reflect: true }) icon: string;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

@Watch("selected")
selectedWatchHandler(): void {
this.calciteComboboxItemChange.emit();
Expand Down Expand Up @@ -156,7 +159,7 @@ export class ComboboxItem implements ConditionalSlotComponent, InteractiveCompon
// --------------------------------------------------------------------------

renderIcon(isSingle: boolean): VNode {
const { icon, disabled, selected } = this;
const { icon, disabled, selected, iconFlipRtl } = this;
const level = `${CSS.icon}--indent`;
const defaultIcon = isSingle ? "dot" : "check";
const iconPath = disabled ? "circle-disallowed" : defaultIcon;
Expand All @@ -177,6 +180,7 @@ export class ComboboxItem implements ConditionalSlotComponent, InteractiveCompon
[CSS.iconActive]: icon && selected,
[level]: true
}}
flipRtl={iconFlipRtl}
icon={icon || iconPath}
scale="s"
/>
Expand Down
7 changes: 6 additions & 1 deletion src/components/combobox/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ export class Combobox
/** Specifies the placeholder icon for the input. */
@Prop({ reflect: true }) placeholderIcon: string;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) placeholderIconFlipRtl = false;

/** Specifies the maximum number of `calcite-combobox-item`s (including nested children) to display before displaying a scrollbar. */
@Prop({ reflect: true }) maxItems = 0;

Expand Down Expand Up @@ -1066,6 +1069,7 @@ export class Combobox
class={chipClasses}
closable
icon={item.icon}
iconFlipRtl={item.iconFlipRtl}
id={item.guid ? `${chipUidPrefix}${item.guid}` : null}
key={item.textLabel}
messageOverrides={{ dismissLabel: messages.removeTag }}
Expand Down Expand Up @@ -1169,7 +1173,7 @@ export class Combobox
}

renderIconStart(): VNode {
const { selectedItems, placeholderIcon, selectionMode } = this;
const { selectedItems, placeholderIcon, selectionMode, placeholderIconFlipRtl } = this;
const selectedItem = selectedItems[0];
const selectedIcon = selectedItem?.icon;
const singleSelectionMode = selectionMode === "single";
Expand All @@ -1184,6 +1188,7 @@ export class Combobox
<span class="icon-start">
<calcite-icon
class="selected-icon"
flipRtl={this.open && selectedItem ? selectedItem.iconFlipRtl : placeholderIconFlipRtl}
icon={!this.open && selectedItem ? selectedIcon : placeholderIcon}
scale="s"
/>
Expand Down
18 changes: 17 additions & 1 deletion src/components/fab/fab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export class Fab implements InteractiveComponent, LoadableComponent {
*/
@Prop({ reflect: true }) icon: string = ICONS.plus;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

/**
* Accessible name for the component.
*/
Expand Down Expand Up @@ -119,14 +122,27 @@ export class Fab implements InteractiveComponent, LoadableComponent {
// --------------------------------------------------------------------------

render(): VNode {
const { appearance, kind, disabled, loading, scale, textEnabled, icon, label, text } = this;
const {
appearance,
kind,
disabled,
loading,
scale,
textEnabled,
icon,
label,
text,
iconFlipRtl
} = this;

const title = !textEnabled ? label || text || null : null;

return (
<calcite-button
appearance={appearance === "solid" ? "solid" : "outline-fill"}
class={CSS.button}
disabled={disabled}
iconFlipRtl={iconFlipRtl ? "start" : null}
iconStart={icon}
kind={kind}
label={label}
Expand Down
12 changes: 11 additions & 1 deletion src/components/input-message/input-message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ export class InputMessage {
/** Specifies an icon to display. */
@Prop({ reflect: true }) icon: boolean | string;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

/** Specifies the size of the component. */
@Prop({ reflect: true, mutable: true }) scale: Scale = "m";

Expand Down Expand Up @@ -79,7 +82,14 @@ export class InputMessage {

private renderIcon(iconName: string): VNode {
if (iconName) {
return <calcite-icon class="calcite-input-message-icon" icon={iconName} scale="s" />;
return (
<calcite-icon
class="calcite-input-message-icon"
flipRtl={this.iconFlipRtl}
icon={iconName}
scale="s"
/>
);
}
}
}
9 changes: 8 additions & 1 deletion src/components/notice/notice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ export class Notice
*/
@Prop({ reflect: true }) icon: string | boolean;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

/** Specifies the size of the component. */
@Prop({ reflect: true }) scale: Scale = "m";

Expand Down Expand Up @@ -162,7 +165,11 @@ export class Notice
<div class={CSS.container}>
{this.requestedIcon ? (
<div class={CSS.icon}>
<calcite-icon icon={this.requestedIcon} scale={this.scale === "l" ? "m" : "s"} />
<calcite-icon
flipRtl={this.iconFlipRtl}
icon={this.requestedIcon}
scale={this.scale === "l" ? "m" : "s"}
/>
</div>
) : null}
<div class={CSS.content}>
Expand Down
9 changes: 7 additions & 2 deletions src/components/pick-list-item/pick-list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ export class PickListItem
*/
@Prop({ reflect: true }) icon: ICON_TYPES | null = null;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

/**
* Label and accessible name for the component. Appears next to the icon.
*/
Expand Down Expand Up @@ -308,7 +311,7 @@ export class PickListItem
// --------------------------------------------------------------------------

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

if (!icon) {
return null;
Expand All @@ -322,7 +325,9 @@ export class PickListItem
}}
onClick={this.pickListClickHandler}
>
{icon === ICON_TYPES.square ? <calcite-icon icon={ICONS.checked} scale="s" /> : null}
{icon === ICON_TYPES.square ? (
<calcite-icon flipRtl={iconFlipRtl} icon={ICONS.checked} scale="s" />
) : null}
</span>
);
}
Expand Down
7 changes: 6 additions & 1 deletion src/components/stepper-item/stepper-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ export class StepperItem implements InteractiveComponent, LocalizedComponent, Lo
/** @internal */
@Prop({ mutable: true }) icon = false;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

/** When `true`, displays the step number in the component's heading. */
/** @internal */
@Prop({ mutable: true }) numbered = false;
Expand Down Expand Up @@ -314,7 +317,9 @@ export class StepperItem implements InteractiveComponent, LocalizedComponent, Lo
? "checkCircleF"
: "circle";

return <calcite-icon class="stepper-item-icon" icon={path} scale="s" />;
return (
<calcite-icon class="stepper-item-icon" flipRtl={this.iconFlipRtl} icon={path} scale="s" />
);
}

private determineSelectedItem(): void {
Expand Down
7 changes: 6 additions & 1 deletion src/components/tile-select/tile-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ export class TileSelect implements InteractiveComponent, LoadableComponent {
/** Specifies an icon to display. */
@Prop({ reflect: true }) icon: string;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

/** Specifies the name of the component on form submission. */
@Prop({ reflect: true }) name;

Expand Down Expand Up @@ -291,7 +294,8 @@ export class TileSelect implements InteractiveComponent, LoadableComponent {
icon,
inputAlignment,
inputEnabled,
width
width,
iconFlipRtl
} = this;
return (
<div
Expand Down Expand Up @@ -320,6 +324,7 @@ export class TileSelect implements InteractiveComponent, LoadableComponent {
embed
heading={heading}
icon={icon}
iconFlipRtl={iconFlipRtl}
/>
<slot />
</div>
Expand Down
7 changes: 5 additions & 2 deletions src/components/tile/tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ export class Tile implements ConditionalSlotComponent, InteractiveComponent {
/** Specifies an icon to display. */
@Prop({ reflect: true }) icon: string;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

// --------------------------------------------------------------------------
//
// Lifecycle
Expand All @@ -98,7 +101,7 @@ export class Tile implements ConditionalSlotComponent, InteractiveComponent {
// --------------------------------------------------------------------------

renderTile(): VNode {
const { icon, el, heading, description } = this;
const { icon, el, heading, description, iconFlipRtl } = this;
const isLargeVisual = heading && icon && !description;
const iconStyle = isLargeVisual
? {
Expand All @@ -111,7 +114,7 @@ export class Tile implements ConditionalSlotComponent, InteractiveComponent {
<div class={{ container: true, "large-visual": isLargeVisual }}>
{icon && (
<div class="icon">
<calcite-icon icon={icon} scale="l" style={iconStyle} />
<calcite-icon flipRtl={iconFlipRtl} icon={icon} scale="l" style={iconStyle} />
</div>
)}
<div class="content-container">
Expand Down
7 changes: 5 additions & 2 deletions src/components/value-list-item/value-list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ export class ValueListItem
*/
@Prop({ reflect: true }) icon?: ICON_TYPES | null = null;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;

/**
* Label and accessible name for the component. Appears next to the icon.
*/
Expand Down Expand Up @@ -232,7 +235,7 @@ export class ValueListItem
}

renderHandle(): VNode {
const { icon } = this;
const { icon, iconFlipRtl } = this;
if (icon === ICON_TYPES.grip) {
return (
<span
Expand All @@ -246,7 +249,7 @@ export class ValueListItem
role="button"
tabindex="0"
>
<calcite-icon icon={ICONS.drag} scale="s" />
<calcite-icon flipRtl={iconFlipRtl} icon={ICONS.drag} scale="s" />
</span>
);
}
Expand Down

0 comments on commit 30a080b

Please sign in to comment.