Skip to content

Commit

Permalink
Feature/wc skeleton (#811)
Browse files Browse the repository at this point in the history
  • Loading branch information
code2nguyen authored Jul 29, 2022
1 parent 4b1aea2 commit bb4d556
Show file tree
Hide file tree
Showing 13 changed files with 633 additions and 425 deletions.
12 changes: 12 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,18 @@
},
"tags": ["web-components"]
},
"skeleton": {
"root": "libs/web-components/skeleton",
"architect": {
"lint": {
"builder": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": ["libs/web-components/skeleton/src/**/*.ts"]
}
}
},
"tags": ["web-components"]
},
"skeleton-text": {
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
Expand Down
17 changes: 17 additions & 0 deletions libs/web-components/skeleton/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts"],
"parserOptions": {
"project": ["libs/web-components/skeleton/tsconfig.*?.json"]
},
"rules": {}
},
{
"files": ["*.html"],
"rules": {}
}
]
}
8 changes: 8 additions & 0 deletions libs/web-components/skeleton/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.tsbuildinfo
tsconfig.json
.eslintignore
*.tgz
images/*
test/*
*.ts
!*.d.ts
28 changes: 28 additions & 0 deletions libs/web-components/skeleton/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Skeleton

[![See it on NPM!](https://img.shields.io/npm/v/@finastra/skeleton?style=for-the-badge)](https://www.npmjs.com/package/@finastra/skeleton)
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@finastra/skeleton?style=for-the-badge)](https://bundlephobia.com/result?p=@finastra/skeleton')
[![Storybook](https://shields.io/badge/-Play%20with%20this%20web%20component-2a0481?logo=storybook&style=for-the-badge)](https://finastra.github.io/finastra-design-system/?path=/story/components-skeleton--default)
Skeleton componet used to indicate content and ui loading that will appear after its loaded. It helps to decrease perceived duration time

## Usage

### Import

```
npm i @finastra/skeleton
```

```ts
import '@finastra/skeleton';
...
<fds-skeleton></fds-skeleton>
```

### Pure HTML pages

```html
<script type="module" src="https://unpkg.com/@finastra/skeleton@latest/dist/src/skeleton.js?module"></script>

<fds-skeleton></fds-skeleton>
```
37 changes: 37 additions & 0 deletions libs/web-components/skeleton/demo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script type="module" src="node_modules/@finastra/skeleton/dist/src/skeleton.js"></script>
<style>
.skeleton-card {
display: grid;
}
.header {
display: flex;
gap: 8px;
align-items: center;
margin-bottom: 16px;
}
.content {
display: flex;
gap: 16px;
}
.info {
display: flex;
flex: 1;
flex-direction: column;
gap: 12px;
}
</style>
<div class="skeleton-card">
<div class="header">
<fds-skeleton type="circle"></fds-skeleton>
<fds-skeleton></fds-skeleton>
</div>
<div class="content">
<fds-skeleton type="rectangle"></fds-skeleton>
<div class="info">
<fds-skeleton size="h2"></fds-skeleton>
<fds-skeleton size="h3"></fds-skeleton>
<fds-skeleton size="h5"></fds-skeleton>
<fds-skeleton width="80px"></fds-skeleton>
</div>
</div>
</div>
24 changes: 24 additions & 0 deletions libs/web-components/skeleton/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@finastra/skeleton",
"displayName": "Skeleton",
"version": "0.0.36",
"description": "Skeleton Web Component",
"keywords": [
"Finastra Design System",
"Web Components",
"Skeleton"
],
"license": "MIT",
"main": "dist/src/skeleton.js",
"module": "dist/src/skeleton.js",
"scripts": {
"build:style": "node ../../../scripts/sass-to-lit-css/index.js src/styles.scss"
},
"dependencies": {
"lit": "^2.0.0",
"tslib": "^2.0.1"
},
"publishConfig": {
"access": "public"
}
}
67 changes: 67 additions & 0 deletions libs/web-components/skeleton/src/skeleton.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { html, LitElement, PropertyValues } from 'lit';
import { customElement, property } from 'lit/decorators.js';

import { styles } from './styles.css';

export const enum SKELETON_TYPE {
CIRCLE = 'circle',
TEXT = 'text',
RECTANGLE = 'rectangle'
}

/**
* @cssprop [--fds-skeleton-width=162px] - Height of the skeleton
* @cssprop [--fds-skeleton-height=162px]- Width of the skeleton
* @cssprop [--fds-skeleton-placeholder-color=var(--fds-on-surface-medium)]- Color of placeholder.
* @cssprop [--fds-skeleton-background=var(--fds-surface-selected)] - Background color of the skeleton.
*
* @attr {string} [height] - Height of the skeleton
* @attr {string} [width] - Width of the skeleton
* @attr {circle|text|rectangle} [type=text] - Define the type of skeleton
* @attr {h1|h2|h3|h4|h5|h6|small|p} [size=p] - Define the size of skeleton
*/
@customElement('fds-skeleton')
export class Skeleton extends LitElement {
static styles = styles;

@property({ type: String, reflect: true })
type: 'circle' | 'text' | 'rectangle' = 'text';

@property({ type: String, reflect: true })
size?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'small' | 'p' = 'p';

@property({ type: String })
width?: string;

@property({ type: String })
height?: string;

override connectedCallback(): void {
super.connectedCallback();
this.updateWidth();
this.updateHeight();
}

override willUpdate(_changedProperties: PropertyValues) {
if (_changedProperties.has('width')) this.updateWidth();
if (_changedProperties.has('height')) this.updateHeight();
}

updateWidth() {
if (this.width) this.style.setProperty('width', this.width);
}

updateHeight() {
if (this.height) this.style.setProperty('height', this.height);
}

render() {
return html``;
}
}

declare global {
interface HTMLElementTagNameMap {
'fds-skeleton': Skeleton;
}
}
72 changes: 72 additions & 0 deletions libs/web-components/skeleton/src/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
@use '@finastra/fds-theme' as fds;

$circle-default-size: 40px;
$rectangle-default-size: 160px;
:host {
display: block;
overflow: hidden;
width: var(--fds-skeleton-width, 162px);
height: var(--fds-skeleton-height, 162px);
--fds-skeleton-placeholder-color: var(--fds-on-surface-medium);
background-color: var(--fds-skeleton-background, var(--fds-surface-selected));
&::before {
display: inline-block;
content:"";
opacity: 0.1;
background-image: linear-gradient(90deg, transparent 0%, var(--fds-skeleton-placeholder-color, --fds-on-surface-medium) 30%, var(--fds-skeleton-placeholder-color, --fds-on-surface-medium) 70%, transparent 100%);
width: 300%;
height: 300%;
margin-bottom: 20px;
animation-duration: 1.2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: shine;
animation-timing-function: cubic-bezier(0, 0, 0.35, 1);
}
@keyframes shine {
0% {
margin-left: -500%;
}
100% {
margin-left: 500%;
}
}
}

:host([type="circle"]) {
--fds-skeleton-width : #{$circle-default-size};
--fds-skeleton-height : #{$circle-default-size};
border-radius: 50%;
}

:host([type="rectangle"]) {
--fds-skeleton-width : #{$rectangle-default-size};
--fds-skeleton-height : #{$rectangle-default-size};
}

:host([type="text"][size="h1"] ) {
--fds-skeleton-height : var(--fds-headline-1-font-size, 51px);
}
:host([type="text"][size="h2"] ) {
--fds-skeleton-height : var(--fds-headline-2-font-size, 41px);
}
:host([type="text"][size="h3"] ) {
--fds-skeleton-height : var(--fds-headline-3-font-size, 28px);
}
:host([type="text"][size="h4"] ) {
--fds-skeleton-height : var(--fds-headline-4-font-size, 21px);
}
:host([type="text"][size="h5"] ) {
--fds-skeleton-height : var(--fds-headline-5-font-size, 16px);
}
:host([type="text"][size="h6"] ) {
--fds-skeleton-height : 13px;
--fds-skeleton-height : var(--fds-headline-6-font-size, 13px);
}
:host([type="text"][size="small"] ) {
--fds-skeleton-height : 12px;
}
:host([type="text"]) {
--fds-skeleton-height : 16px;
}

67 changes: 67 additions & 0 deletions libs/web-components/skeleton/stories/skeleton.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const README = require('../README.md');
import '@finastra/skeleton';
import type { Skeleton } from '@finastra/skeleton';
import { Meta, Story } from '@storybook/web-components';
import { html } from 'lit-html';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import { argTypes, cssprops } from './sb-generated/fds-skeleton.json';
export default {
title: 'DATA DISPLAY/Skeleton',
component: 'fds-skeleton',
argTypes,
parameters: {
docs: {
description: { component: README }
},
cssprops
},
decorators: [
(story) => html`${story()}
<style>
.skeleton-card {
display: grid;
}
.header {
display: flex;
gap: 8px;
align-items: center;
margin-bottom: 16px;
}
.content {
display: flex;
gap: 16px;
}
.info {
display: flex;
flex: 1;
flex-direction: column;
gap: 12px;
}
</style> `
]
} as Meta;

const Template: Story<Skeleton> = ({ type, size, width, height }) => {
return html`<fds-skeleton type=${type} size=${ifDefined(size)} width=${ifDefined(width)} height=${ifDefined(height)}></fds-skeleton>`;
};

export const Default: Story<Skeleton> = Template.bind({});
export const Demo: Story<Skeleton> = () => {
return html`
<div class="skeleton-card">
<div class="header">
<fds-skeleton type="circle"></fds-skeleton>
<fds-skeleton></fds-skeleton>
</div>
<div class="content">
<fds-skeleton type="rectangle"></fds-skeleton>
<div class="info">
<fds-skeleton size="h2"></fds-skeleton>
<fds-skeleton size="h3"></fds-skeleton>
<fds-skeleton size="h5"></fds-skeleton>
<fds-skeleton width="80px"></fds-skeleton>
</div>
</div>
</div>
`;
};
20 changes: 20 additions & 0 deletions libs/web-components/skeleton/test/skeleton.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
import '../src/skeleton.js';
import { Skeleton } from '../src/skeleton.js';

describe('Skeleton', () => {
it('loads accessibly', async () => {
const el: Skeleton = await fixture(html`<fds-skeleton></fds-skeleton>`);

await elementUpdated(el);
await expect(el).to.be.accessible();
});

it('set with & height', async () => {
const el: Skeleton = await fixture(html`<fds-skeleton width="100px" height="100px"></fds-skeleton>`);

await elementUpdated(el);
await expect(el.getBoundingClientRect().width).to.eq(100);
await expect(el.getBoundingClientRect().height).to.eq(100);
});
});
10 changes: 10 additions & 0 deletions libs/web-components/skeleton/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"composite": true,
"rootDir": "./",
"outDir": "./dist",
"tsBuildInfoFile": "./dist/.tsbuildinfo"
},
"include": ["src/**/*.ts", "test/**/*.ts"]
}
3 changes: 3 additions & 0 deletions libs/web-components/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@
{
"path": "breadcrumb"
},
{
"path": "skeleton"
},
{
"path": "account-card"
}
Expand Down
Loading

0 comments on commit bb4d556

Please sign in to comment.