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(icon): type icon names #9650

Merged
merged 12 commits into from
Jul 2, 2024
3 changes: 1 addition & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/calcite-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"directory": "packages/calcite-components"
},
"dependencies": {
"@esri/calcite-ui-icons": "3.28.2",
"@floating-ui/dom": "1.6.5",
"@stencil/core": "4.18.3",
"@types/color": "3.0.6",
Expand All @@ -77,7 +78,6 @@
},
"devDependencies": {
"@esri/calcite-design-tokens": "^2.2.1-next.0",
"@esri/calcite-ui-icons": "3.28.2",
"@esri/eslint-plugin-calcite-components": "^1.2.1-next.2",
"@stencil-community/eslint-plugin": "0.7.2",
"@stencil-community/postcss": "2.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
setComponentLoaded,
setUpLoadableComponent,
} from "../../utils/loadable";
import { IconName } from "../icon/interfaces";
import { SLOTS, CSS, IDS } from "./resources";
import { RequestedItem } from "./interfaces";

Expand Down Expand Up @@ -60,10 +61,10 @@ export class AccordionItem implements ConditionalSlotComponent, LoadableComponen
@Prop() description: string;

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

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

/** Displays the `iconStart` and/or `iconEnd` as flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl: FlipContext;
Expand Down
3 changes: 2 additions & 1 deletion packages/calcite-components/src/components/alert/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
} from "../../utils/t9n";
import { Kind, Scale } from "../interfaces";
import { KindIcons } from "../resources";
import { IconName } from "../icon/interfaces";
import { AlertMessages } from "./assets/alert/t9n";
import { AlertDuration, Sync, Unregister } from "./interfaces";
import { CSS, DURATIONS, SLOTS } from "./resources";
Expand Down Expand Up @@ -102,7 +103,7 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen
* When `true`, shows a default recommended icon. Alternatively,
* pass a Calcite UI Icon name to display a specific icon.
*/
@Prop({ reflect: true }) icon: string | boolean;
@Prop({ reflect: true }) icon: IconName | boolean;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
setComponentLoaded,
setUpLoadableComponent,
} from "../../utils/loadable";
import { IconName } from "../icon/interfaces";
import { BlockSectionMessages } from "./assets/block-section/t9n";
import { BlockSectionToggleDisplay } from "./interfaces";
import { CSS, ICONS, IDS } from "./resources";
Expand All @@ -49,13 +50,13 @@ export class BlockSection implements LocalizedComponent, T9nComponent, LoadableC
// --------------------------------------------------------------------------

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

/** 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;
@Prop({ reflect: true }) iconStart: IconName;

/**
* When `true`, expands the component and its contents.
Expand Down
5 changes: 3 additions & 2 deletions packages/calcite-components/src/components/block/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
import { onToggleOpenCloseComponent, OpenCloseComponent } from "../../utils/openCloseComponent";
import { OverlayPositioning } from "../../utils/floating-ui";
import { FlipContext } from "../interfaces";
import { IconName } from "../icon/interfaces";
import { CSS, ICONS, IDS, SLOTS } from "./resources";
import { BlockMessages } from "./assets/block/t9n";

Expand Down Expand Up @@ -106,13 +107,13 @@ export class Block
@Prop({ reflect: true }) headingLevel: HeadingLevel;

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

/** 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;
@Prop({ reflect: true }) iconStart: IconName;

/**
* When `true`, a busy indicator is displayed.
Expand Down
3 changes: 2 additions & 1 deletion packages/calcite-components/src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
} from "../../utils/t9n";
import { Appearance, FlipContext, Kind, Scale, Width } from "../interfaces";
import { toAriaBoolean } from "../../utils/dom";
import { IconName } from "../icon/interfaces";
import { ButtonMessages } from "./assets/button/t9n";
import { ButtonAlignment } from "./interfaces";
import { CSS } from "./resources";
Expand Down Expand Up @@ -123,7 +124,7 @@ export class Button
@Prop({ reflect: true }) iconFlipRtl: FlipContext;

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

/**
* When `true`, a busy indicator is displayed and interaction is disabled.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import { Scale, SelectionMode, Status } from "../interfaces";
import { CSS as XButtonCSS, XButton } from "../functional/XButton";
import { componentOnReady, getIconScale } from "../../utils/component";
import { Validation } from "../functional/Validation";
import { IconName } from "../icon/interfaces";
import { ComboboxMessages } from "./assets/combobox/t9n";
import { ComboboxChildElement, SelectionDisplay } from "./interfaces";
import { ComboboxChildSelector, ComboboxItem, ComboboxItemGroup, CSS } from "./resources";
Expand Down Expand Up @@ -194,7 +195,7 @@ export class Combobox
@Prop() validationMessage: string;

/** Specifies the validation icon to display under the component. */
@Prop({ reflect: true }) validationIcon: string | boolean;
@Prop({ reflect: true }) validationIcon: IconName | boolean;

/**
* The current validation state of the component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
InteractiveContainer,
updateHostInteraction,
} from "../../utils/interactive";
import { IconName } from "../icon/interfaces";
import { CSS } from "./resources";

/**
Expand Down Expand Up @@ -59,10 +60,10 @@ export class DropdownItem implements InteractiveComponent, LoadableComponent {
@Prop({ reflect: true }) iconFlipRtl: FlipContext;

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

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

/** Accessible name for the component. */
@Prop() label: string;
Expand Down
3 changes: 2 additions & 1 deletion packages/calcite-components/src/components/fab/fab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
setUpLoadableComponent,
} from "../../utils/loadable";
import { Appearance, Kind, Scale } from "../interfaces";
import { IconName } from "../icon/interfaces";
import { CSS, ICONS } from "./resources";

@Component({
Expand Down Expand Up @@ -49,7 +50,7 @@ export class Fab implements InteractiveComponent, LoadableComponent {
*
* @default "plus"
*/
@Prop({ reflect: true }) icon: string = ICONS.plus;
@Prop({ reflect: true }) icon: IconName = ICONS.plus;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export const CSS = {

export const ICONS = {
plus: "plus",
};
} as const;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export const CSS = {
export const ICONS = {
search: "search",
close: "x",
};
} as const;

export const DEBOUNCE_TIMEOUT = 250;
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { FunctionalComponent, h } from "@stencil/core";
import { JSXBase } from "@stencil/core/internal";
import { Scale, Status } from "../interfaces";
import { IconName } from "../icon/interfaces";

interface ValidationProps extends JSXBase.HTMLAttributes {
scale: Scale;
status: Status;
icon?: string | boolean;
icon?: IconName | boolean;
message: string;
}

Expand Down
13 changes: 13 additions & 0 deletions packages/calcite-components/src/components/icon/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as icons from "@esri/calcite-ui-icons";
import { KebabCase } from "type-fest";

type ExtractBaseIcon<T> = T extends `${infer Base}${"16" | "24" | "32"}`
? Base extends `i${infer Rest}`
? Rest
: Base
: never;

type CamelCaseIcons = ExtractBaseIcon<keyof typeof icons>;
type KebabCaseIcons = KebabCase<CamelCaseIcons>;

export type IconName = KebabCaseIcons | CamelCaseIcons;
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import { guid } from "../../utils/guid";
import { getIconScale } from "../../utils/component";
import { Status } from "../interfaces";
import { Validation } from "../functional/Validation";
import { IconName } from "../icon/interfaces";
import { syncHiddenFormInput } from "../input/common/input";
import { normalizeToCurrentCentury, isTwoDigitYear } from "./utils";
import { InputDatePickerMessages } from "./assets/input-date-picker/t9n";
Expand Down Expand Up @@ -278,7 +279,7 @@ export class InputDatePicker
@Prop() validationMessage: string;

/** Specifies the validation icon to display under the component. */
@Prop({ reflect: true }) validationIcon: string | boolean;
@Prop({ reflect: true }) validationIcon: IconName | boolean;

/**
* The current validation state of the component.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component, Element, h, Host, Prop, VNode, Watch } from "@stencil/core";
import { setRequestedIcon } from "../../utils/dom";
import { Scale, Status } from "../interfaces";
import { IconName } from "../icon/interfaces";
import { StatusIconDefaults } from "./interfaces";

/**
Expand All @@ -19,7 +20,7 @@ export class InputMessage {
//--------------------------------------------------------------------------

/** Specifies an icon to display. */
@Prop({ reflect: true }) icon: boolean | string;
@Prop({ reflect: true }) icon: IconName | boolean;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import {
syncHiddenFormInput,
TextualInputComponent,
} from "../input/common/input";
import { IconName } from "../icon/interfaces";
import { CSS, SLOTS } from "./resources";
import { InputNumberMessages } from "./assets/input-number/t9n";

Expand Down Expand Up @@ -170,7 +171,7 @@ export class InputNumber
*
* @futureBreaking Remove boolean type as it is not supported.
*/
@Prop({ reflect: true }) icon: string | boolean;
@Prop({ reflect: true }) icon: IconName | boolean;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;
Expand Down Expand Up @@ -253,7 +254,7 @@ export class InputNumber
@Prop() validationMessage: string;

/** Specifies the validation icon to display under the component. */
@Prop({ reflect: true }) validationIcon: string | boolean;
@Prop({ reflect: true }) validationIcon: IconName | boolean;

/**
* The current validation state of the component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { Alignment, Scale, Status } from "../interfaces";
import { getIconScale } from "../../utils/component";
import { Validation } from "../functional/Validation";
import { syncHiddenFormInput, TextualInputComponent } from "../input/common/input";
import { IconName } from "../icon/interfaces";
import { CSS, SLOTS } from "./resources";
import { InputTextMessages } from "./assets/input-text/t9n";

Expand Down Expand Up @@ -142,7 +143,7 @@ export class InputText
*
* @futureBreaking Remove boolean type as it is not supported.
*/
@Prop({ reflect: true }) icon: string | boolean;
@Prop({ reflect: true }) icon: IconName | boolean;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;
Expand Down Expand Up @@ -180,7 +181,7 @@ export class InputText
@Prop() validationMessage: string;

/** Specifies the validation icon to display under the component. */
@Prop({ reflect: true }) validationIcon: string | boolean;
@Prop({ reflect: true }) validationIcon: IconName | boolean;

/**
* The current validation state of the component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import { decimalPlaces } from "../../utils/math";
import { getIconScale } from "../../utils/component";
import { Validation } from "../functional/Validation";
import { focusFirstTabbable } from "../../utils/dom";
import { IconName } from "../icon/interfaces";
import { syncHiddenFormInput } from "../input/common/input";
import { CSS } from "./resources";
import { InputTimePickerMessages } from "./assets/input-time-picker/t9n";
Expand Down Expand Up @@ -269,7 +270,7 @@ export class InputTimePicker
@Prop() validationMessage: string;

/** Specifies the validation icon to display under the component. */
@Prop({ reflect: true }) validationIcon: string | boolean;
@Prop({ reflect: true }) validationIcon: IconName | boolean;

/**
* The current validation state of the component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
HiddenFormInputSlot,
MutableValidityState,
} from "../../utils/form";
import { IconName } from "../icon/interfaces";
import {
createTimeZoneItems,
findTimeZoneItemByProp,
Expand Down Expand Up @@ -154,7 +155,7 @@ export class InputTimeZone
@Prop() validationMessage: string;

/** Specifies the validation icon to display under the component. */
@Prop({ reflect: true }) validationIcon: string | boolean;
@Prop({ reflect: true }) validationIcon: IconName | boolean;

/**
* The current validation state of the component.
Expand Down
5 changes: 3 additions & 2 deletions packages/calcite-components/src/components/input/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import {
} from "../../utils/t9n";
import { getIconScale } from "../../utils/component";
import { Validation } from "../functional/Validation";
import { IconName } from "../icon/interfaces";
import { InputMessages } from "./assets/input/t9n";
import { InputPlacement, NumberNudgeDirection, SetValueOrigin } from "./interfaces";
import { CSS, INPUT_TYPE_ICONS, SLOTS } from "./resources";
Expand Down Expand Up @@ -164,7 +165,7 @@ export class Input
/**
* When `true`, shows a default recommended icon. Alternatively, pass a Calcite UI Icon name to display a specific icon.
*/
@Prop({ reflect: true }) icon: string | boolean;
@Prop({ reflect: true }) icon: IconName | boolean;

/** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
@Prop({ reflect: true }) iconFlipRtl = false;
Expand Down Expand Up @@ -241,7 +242,7 @@ export class Input
@Prop() validationMessage: string;

/** Specifies the validation icon to display under the component. */
@Prop({ reflect: true }) validationIcon: string | boolean;
@Prop({ reflect: true }) validationIcon: IconName | boolean;

/**
* The current validation state of the component.
Expand Down
Loading