Skip to content

Commit

Permalink
[@next] refactor avatar to use design tokens (#451)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeMatusz authored Jan 25, 2024
1 parent 2a82785 commit 69687ec
Show file tree
Hide file tree
Showing 20 changed files with 272 additions and 373 deletions.
6 changes: 3 additions & 3 deletions src/dev/pages/avatar/avatar.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
<div>
<h3 class="forge-typography--heading2">w/Custom Radius (10px)</h3>
<div>
<forge-avatar text="Tyler Forge" style="--forge-avatar-radius: 10px;"></forge-avatar>
<forge-avatar text="Tyler Forge" style="--forge-avatar-shape: 10px;"></forge-avatar>
</div>
</div>

<div>
<h3 class="forge-typography--heading2">w/Icon</h3>
<div>
<forge-avatar style="--forge-avatar-theme-background: black;">
<forge-avatar>
<forge-icon name="face" external></forge-icon>
</forge-avatar>
</div>
Expand All @@ -32,7 +32,7 @@
<div>
<h3 class="forge-typography--heading2">w/Custom Slotted Content and CSS Variable</h3>
<div>
<forge-avatar style="--forge-avatar-theme-background: #ff0000; --forge-avatar-size: 24px; --forge-avatar-font-size: 16px;">A</forge-avatar>
<forge-avatar style="--forge-avatar-background: #ff0000; --forge-avatar-size: 24px; --forge-avatar-font-size: 16px;">A</forge-avatar>
</div>
</div>

Expand Down
4 changes: 1 addition & 3 deletions src/dev/pages/avatar/avatar.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
page: {
title: 'Avatar',
includePath: './pages/avatar/avatar.ejs',
options: [
{ type: 'switch', label: 'Auto color', id: 'auto-color-checkbox' }
]
options: []
}
})
%>
12 changes: 0 additions & 12 deletions src/dev/pages/avatar/avatar.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
// Components
import '@tylertech/forge/avatar';
import type { AvatarComponent } from '@tylertech/forge/avatar';
import type { ISwitchComponent } from '@tylertech/forge/switch';
import '$src/shared';

function getAvatarElements(): NodeListOf<AvatarComponent> {
return document.querySelectorAll('.content forge-avatar');
}

const autoColorToggle = document.querySelector('#auto-color-checkbox') as ISwitchComponent;
autoColorToggle.addEventListener('forge-switch-change', ({ detail: selected }) => {
const avatars = getAvatarElements();
avatars.forEach(avatar => avatar.autoColor = selected);
});
38 changes: 38 additions & 0 deletions src/lib/avatar/_core.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@use '../core/styles/typography';
@use './token-utils' as *;

@forward './token-utils';

@mixin host() {
contain: content;

display: inline-block;
}

@mixin base() {
display: flex;
align-items: center;
justify-content: center;

overflow: hidden;

transition: height #{token(transition-duration)} #{token(transition-timing)},
width #{token(transition-duration)} #{token(transition-timing)};

border-radius: #{token(shape)};
box-sizing: border-box;
width: #{token(size)};
height: #{token(size)};

background-color: #{token(background)};
background-position: center;
background-repeat: no-repeat;
background-size: cover;

@include typography.style(subheading2);
color: #{token(color)};
}

@mixin base-with-image() {
background-color: inherit;
}
41 changes: 0 additions & 41 deletions src/lib/avatar/_mixins.scss

This file was deleted.

25 changes: 25 additions & 0 deletions src/lib/avatar/_token-utils.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@use '../core/styles/tokens/avatar/tokens';
@use '../core/styles/tokens/token-utils';

$_module: avatar;
$_tokens: tokens.$tokens;

@mixin provide-theme($theme) {
@include token-utils.provide-theme($_module, $_tokens, $theme);
}

@function token($name, $type: token) {
@return token-utils.token($_module, $_tokens, $name, $type);
}

@function declare($token) {
@return token-utils.declare($_module, $token);
}

@mixin override($token, $token-or-value, $type: token) {
@include token-utils.override($_module, $_tokens, $token, $token-or-value, $type);
}

@mixin tokens($includes: null, $excludes: null) {
@include token-utils.tokens($_module, $_tokens, $includes, $excludes);
}
11 changes: 0 additions & 11 deletions src/lib/avatar/_variables.scss

This file was deleted.

24 changes: 6 additions & 18 deletions src/lib/avatar/avatar-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { IAvatarComponent } from './avatar';
import { AVATAR_CONSTANTS } from './avatar-constants';

export interface IAvatarAdapter extends IBaseAdapter {
setBackgroundColor(color: string): void;
setBackgroundImageUrl(url: string): Promise<boolean>;
removeBackgroundImage(): void;
setText(value: string): void;
Expand All @@ -24,46 +23,35 @@ export class AvatarAdapter extends BaseAdapter<IAvatarComponent> implements IAva
this._defaultSlot = getShadowElement(this._component, AVATAR_CONSTANTS.selectors.DEFAULT_SLOT) as HTMLSlotElement;
}

/**
* Sets the `backgroundColor` style on the content element.
* @param {string} value The background color.
*/
public setBackgroundColor(value: string): void {
this._root.style.backgroundColor = `var(${AVATAR_CONSTANTS.strings.BACKGROUND_VARNAME}, ${value})`;
}

/**
* Sets the background image URL.
* @param url The URL.
*/
public setBackgroundImageUrl(url: string): Promise<boolean> {
const backgroundColor = this._root.style.backgroundColor;
// doing his before the promise so it doesn't flash a color before loading
this._root.style.backgroundColor = 'inherit';

const loadResult = new Promise<boolean>(resolve => {
public async setBackgroundImageUrl(url: string): Promise<boolean> {
// Set before loading image to prevent a flash of background color
this._root.classList.add('forge-avatar--image');
return new Promise<boolean>(resolve => {
const image = new Image();
image.onload = () => {
this._root.style.backgroundImage = `url(${image.src})`;
resolve(true);
};

image.onerror = () => {
this._root.style.backgroundColor = backgroundColor;
this._root.classList.remove('forge-avatar--image');
resolve(false);
};

image.src = url;
});

return loadResult;
}

/**
* Removes the background image URL.
*/
public removeBackgroundImage(): void {
this._root.style.removeProperty('background-image');
this._root.classList.remove('forge-avatar--image');
}

/**
Expand Down
17 changes: 0 additions & 17 deletions src/lib/avatar/avatar-component-delegate.ts

This file was deleted.

5 changes: 2 additions & 3 deletions src/lib/avatar/avatar-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ const elementName: keyof HTMLElementTagNameMap = `${COMPONENT_NAME_PREFIX}avatar
const attributes = {
IMAGE_URL: 'image-url',
TEXT: 'text',
LETTER_COUNT: 'letter-count',
AUTO_COLOR: 'auto-color'
LETTER_COUNT: 'letter-count'
};

const numbers = {
Expand All @@ -21,7 +20,7 @@ const selectors = {

const strings = {
DEFAULT_COLOR: COLOR_CONSTANTS.themeColors.tertiary,
BACKGROUND_VARNAME: '--forge-avatar-theme-background'
BACKGROUND_VARNAME: '--forge-avatar-background'
};

export const AVATAR_CONSTANTS = {
Expand Down
20 changes: 0 additions & 20 deletions src/lib/avatar/avatar-foundation.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { ICustomElementFoundation, isDefined, isString } from '@tylertech/forge-core';
import { getTextColor } from '../utils/color-utils';
import { IAvatarAdapter } from './avatar-adapter';
import { AVATAR_CONSTANTS } from './avatar-constants';



export interface IAvatarFoundation extends ICustomElementFoundation {
imageUrl: string;
text: string;
letterCount: number;
autoColor: boolean;
}

/**
Expand All @@ -19,7 +15,6 @@ export class AvatarFoundation implements IAvatarFoundation {
private _imageUrl: string;
private _text = '';
private _letterCount = AVATAR_CONSTANTS.numbers.DEFAULT_LETTER_COUNT;
private _autoColor = false;
private _initialized = false;

constructor(private _adapter: IAvatarAdapter) {}
Expand Down Expand Up @@ -56,9 +51,6 @@ export class AvatarFoundation implements IAvatarFoundation {
} else {
this._adapter.clearText();
}

const color = this._autoColor ? getTextColor(data) : AVATAR_CONSTANTS.strings.DEFAULT_COLOR;
this._adapter.setBackgroundColor(color);
}

/**
Expand Down Expand Up @@ -122,16 +114,4 @@ export class AvatarFoundation implements IAvatarFoundation {
}
}
}

/** Controls whether the background color set automatically based on the text value. Does not have any effect when an image URL is specified. */
public get autoColor(): boolean {
return this._autoColor;
}
public set autoColor(value: boolean) {
if (this._autoColor !== value) {
this._autoColor = value;
this._setText();
this._adapter.setHostAttribute(AVATAR_CONSTANTS.attributes.AUTO_COLOR, isDefined(this._autoColor) ? this._autoColor.toString() : '');
}
}
}
24 changes: 21 additions & 3 deletions src/lib/avatar/avatar.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
@use './mixins';
@use './core' as *;

//
// Host
//

:host {
@include mixins.host;
@include host;
}

:host([hidden]) {
display: none;
}

@include mixins.core-styles;
//
// Base
//

.forge-avatar {
@include tokens;
}

.forge-avatar {
@include base;

&--image {
@include base-with-image;
}
}
Loading

0 comments on commit 69687ec

Please sign in to comment.