Skip to content

Commit

Permalink
refactor: Do not create dynamic theme property (#1186)
Browse files Browse the repository at this point in the history
* Skip the creating of a dynamic theme property
when initializing a web component class instance
for components which don't need it.

* Minor cleanups in utils and rating hover
event handlers.
  • Loading branch information
rkaraivanov committed Apr 29, 2024
1 parent 9bc0371 commit 5abf935
Show file tree
Hide file tree
Showing 11 changed files with 32 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/components/button-group/toggle-button.ts
Expand Up @@ -17,7 +17,7 @@ import { styles as shared } from './themes/shared/button/button.common.css.js';
*
* @csspart toggle - The native button element.
*/
@themes(all, true)
@themes(all)
export default class IgcToggleButtonComponent extends LitElement {
public static override styles = [styles, shared];
public static readonly tagName = 'igc-toggle-button';
Expand Down
20 changes: 8 additions & 12 deletions src/components/common/util.ts
Expand Up @@ -55,24 +55,20 @@ export function isLTR(element: HTMLElement) {

/**
* Builds a string from format specifiers and replacement parameters.
* Will coerce non-string parameters to their string representations.
*
* @example
* ```typescript
* format('{0} says "{1}".', 'John', 'Hello'); // 'John says "Hello".'
* formatString('{0} says "{1}".', 'John', 'Hello'); // 'John says "Hello".'
* formatString('{1} is greater than {0}', 0, 1); // '1 is greater than 0'
* ```
*/
export function format(template: string, ...params: string[]): string {
return template.replace(/{(\d+)}/g, (match: string, index: number) => {
if (index >= params.length) {
return match;
}
export function formatString(template: string, ...params: unknown[]): string {
const length = params.length;

const value: string = params[index];
if (typeof value !== 'number' && !value) {
return '';
}
return value;
});
return template.replace(/{(\d+)}/g, (match: string, index: number) =>
index >= length ? match : `${params[index]}`
);
}

/**
Expand Down
10 changes: 5 additions & 5 deletions src/components/common/validators.ts
@@ -1,5 +1,5 @@
import validatorMessages from './localization/validation-en.js';
import { asNumber, format, isDefined } from './util.js';
import { asNumber, formatString, isDefined } from './util.js';

type ValidatorHandler<T> = (host: T) => boolean;
type ValidatorMessageFormat<T> = (host: T) => string;
Expand Down Expand Up @@ -43,7 +43,7 @@ export const minLengthValidator: Validator<{
}> = {
key: 'tooShort',
message: ({ minLength }) =>
format(validatorMessages.minLength, `${minLength}`),
formatString(validatorMessages.minLength, minLength),
isValid: ({ minLength, value }) =>
minLength ? value.length >= minLength : true,
};
Expand All @@ -54,7 +54,7 @@ export const maxLengthValidator: Validator<{
}> = {
key: 'tooLong',
message: ({ maxLength }) =>
format(validatorMessages.maxLength, `${maxLength}`),
formatString(validatorMessages.maxLength, maxLength),
isValid: ({ maxLength, value }) =>
maxLength ? value.length <= maxLength : true,
};
Expand All @@ -71,7 +71,7 @@ export const minValidator: Validator<{
value: number | string;
}> = {
key: 'rangeUnderflow',
message: ({ min }) => format(validatorMessages.min, `${min}`),
message: ({ min }) => formatString(validatorMessages.min, min),
isValid: ({ min, value }) =>
isDefined(min)
? isDefined(value) && asNumber(value) >= asNumber(min)
Expand All @@ -83,7 +83,7 @@ export const maxValidator: Validator<{
value: number | string;
}> = {
key: 'rangeOverflow',
message: ({ max }) => format(validatorMessages.max, `${max}`),
message: ({ max }) => formatString(validatorMessages.max, max),
isValid: ({ max, value }) =>
isDefined(max)
? isDefined(value) && asNumber(value) <= asNumber(max)
Expand Down
6 changes: 3 additions & 3 deletions src/components/date-time-input/date-time-input.ts
Expand Up @@ -17,7 +17,7 @@ import { registerComponent } from '../common/definitions/register.js';
import messages from '../common/localization/validation-en.js';
import type { AbstractConstructor } from '../common/mixins/constructor.js';
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
import { format, partNameMap } from '../common/util.js';
import { formatString, partNameMap } from '../common/util.js';
import type { Validator } from '../common/validators.js';
import type { IgcInputEventMap } from '../input/input-base.js';
import {
Expand Down Expand Up @@ -84,7 +84,7 @@ export default class IgcDateTimeInputComponent extends EventEmitterMixin<
},
{
key: 'rangeUnderflow',
message: () => format(messages.min, `${this.min}`),
message: () => formatString(messages.min, this.min),
isValid: () =>
this.min
? !DateTimeUtil.lessThanMinValue(
Expand All @@ -97,7 +97,7 @@ export default class IgcDateTimeInputComponent extends EventEmitterMixin<
},
{
key: 'rangeOverflow',
message: () => format(messages.max, `${this.max}`),
message: () => formatString(messages.max, this.max),
isValid: () =>
this.max
? !DateTimeUtil.greaterThanMaxValue(
Expand Down
4 changes: 2 additions & 2 deletions src/components/progress/base.ts
Expand Up @@ -7,7 +7,7 @@ import {
} from 'lit/decorators.js';

import { watch } from '../common/decorators/watch.js';
import { asPercent, clamp, format } from '../common/util.js';
import { asPercent, clamp, formatString } from '../common/util.js';

export abstract class IgcProgressBaseComponent extends LitElement {
private __internals: ElementInternals;
Expand Down Expand Up @@ -193,7 +193,7 @@ export abstract class IgcProgressBaseComponent extends LitElement {
}

protected renderLabelFormat() {
return format(this.labelFormat, `${this.value}`, `${this.max}`);
return formatString(this.labelFormat, this.value, this.max);
}

protected renderDefaultSlot() {
Expand Down
10 changes: 5 additions & 5 deletions src/components/rating/rating.ts
Expand Up @@ -26,7 +26,7 @@ import type { Constructor } from '../common/mixins/constructor.js';
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
import { FormAssociatedMixin } from '../common/mixins/form-associated.js';
import { SizableMixin } from '../common/mixins/sizable.js';
import { clamp, format, isLTR } from '../common/util.js';
import { clamp, formatString, isLTR } from '../common/util.js';
import IgcIconComponent from '../icon/icon.js';
import IgcRatingSymbolComponent from './rating-symbol.js';
import { styles } from './themes/rating.base.css.js';
Expand Down Expand Up @@ -61,7 +61,7 @@ export interface IgcRatingEventMap {
* @cssproperty --symbol-full-filter - The filter(s) used for the filled symbol.
* @cssproperty --symbol-empty-filter - The filter(s) used for the empty symbol.
*/
@themes(all, true)
@themes(all)
export default class IgcRatingComponent extends FormAssociatedMixin(
SizableMixin(
EventEmitterMixin<IgcRatingEventMap, Constructor<LitElement>>(LitElement)
Expand Down Expand Up @@ -109,7 +109,7 @@ export default class IgcRatingComponent extends FormAssociatedMixin(
// Skip IEEE 754 representation for screen readers
const value = this.round(this.value);
return this.valueFormat
? format(this.valueFormat, `${value}`, `${this.max}`)
? formatString(this.valueFormat, value, this.max)
: `${value} of ${this.max}`;
}

Expand Down Expand Up @@ -431,8 +431,8 @@ export default class IgcRatingComponent extends FormAssociatedMixin(
aria-hidden="true"
part="symbols"
@click=${this.isInteractive ? this.handleClick : nothing}
@mouseenter=${hoverActive ? () => this.handleHoverEnabled : nothing}
@mouseleave=${hoverActive ? () => this.handleHoverDisabled : nothing}
@mouseenter=${hoverActive ? this.handleHoverEnabled : nothing}
@mouseleave=${hoverActive ? this.handleHoverDisabled : nothing}
@mousemove=${hoverActive ? this.handleMouseMove : nothing}
>
<slot name="symbol" @slotchange=${this.handleSlotChange}>
Expand Down
6 changes: 4 additions & 2 deletions src/components/slider/slider-base.ts
Expand Up @@ -27,7 +27,7 @@ import {
asNumber,
asPercent,
clamp,
format,
formatString,
isDefined,
isLTR,
} from '../common/util.js';
Expand Down Expand Up @@ -378,7 +378,9 @@ export class IgcSliderBaseComponent extends LitElement {

protected formatValue(value: number) {
const strValue = value.toLocaleString(this.locale, this.valueFormatOptions);
return this.valueFormat ? format(this.valueFormat, strValue) : strValue;
return this.valueFormat
? formatString(this.valueFormat, strValue)
: strValue;
}

private normalizeByStep(value: number) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/stepper/step.ts
Expand Up @@ -44,7 +44,7 @@ import { all } from './themes/step/themes.js';
* @csspart body - Wrapper of the step's `content`.
* @csspart content - The steps `content`.
*/
@themes(all, true)
@themes(all)
export default class IgcStepComponent extends LitElement {
public static readonly tagName = 'igc-step';
public static override styles = [styles, shared];
Expand Down
2 changes: 1 addition & 1 deletion src/components/tabs/tab.ts
Expand Up @@ -22,7 +22,7 @@ import { styles } from './themes/tab.base.css.js';
* @csspart suffix - The suffix wrapper.
*/

@themes(all, true)
@themes(all)
export default class IgcTabComponent extends LitElement {
public static readonly tagName = 'igc-tab';
public static override styles = [styles, shared];
Expand Down
2 changes: 1 addition & 1 deletion src/components/tabs/tabs.ts
Expand Up @@ -56,7 +56,7 @@ export interface IgcTabsEventMap {
* @csspart end-scroll-button - The end scroll button displayed when the tabs overflow.
* @csspart content - The container for the tabs content.
*/
@themes(all, true)
@themes(all)
@blazorAdditionalDependencies('IgcTabComponent, IgcTabPanelComponent')
export default class IgcTabsComponent extends EventEmitterMixin<
IgcTabsEventMap,
Expand Down
2 changes: 1 addition & 1 deletion src/components/tree/tree-item.ts
Expand Up @@ -48,7 +48,7 @@ import type { IgcTreeSelectionService } from './tree.selection.js';
* @csspart text - The tree item displayed text.
* @csspart select - The checkbox of the tree item when selection is enabled.
*/
@themes(all, true)
@themes(all)
export default class IgcTreeItemComponent extends LitElement {
public static readonly tagName = 'igc-tree-item';
public static override styles = [styles, shared];
Expand Down

0 comments on commit 5abf935

Please sign in to comment.