-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[CL-427] Add skeleton loading components to the CL #16728
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
Merged
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
e323cb6
skeleton POC
vleague2 3559835
add helper skeleton components and docs
vleague2 1e93f4f
simplify array and improve docs
vleague2 981770f
Merge branch 'main' into uif/cl-427/skeleton
vleague2 06f5a9d
update skeleton stories and text radius
vleague2 8f59113
fix main docs page
vleague2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export * from "./skeleton.component"; | ||
| export * from "./skeleton-text.component"; | ||
| export * from "./skeleton-group.component"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| <div class="tw-flex tw-flex-row tw-justify-between tw-gap-2"> | ||
| <div class="tw-flex tw-gap-2 tw-w-full"> | ||
| <ng-content select="[slot=start]"></ng-content> | ||
| <ng-content></ng-content> | ||
| </div> | ||
| <ng-content select="[slot=end]"></ng-content> | ||
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { CommonModule } from "@angular/common"; | ||
| import { Component } from "@angular/core"; | ||
|
|
||
| /** | ||
| * Arranges skeleton loaders into a pre-arranged group that mimics the table and item components. | ||
| * | ||
| * Pass skeleton loaders into the start, default, and end content slots. The content within each slot | ||
| * is fully customizable. | ||
| */ | ||
| @Component({ | ||
| selector: "bit-skeleton-group", | ||
| templateUrl: "./skeleton-group.component.html", | ||
| imports: [CommonModule], | ||
| host: { | ||
| class: "tw-block", | ||
| }, | ||
| }) | ||
| export class SkeletonGroupComponent {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; | ||
|
|
||
| import { SharedModule } from "../shared/shared.module"; | ||
|
|
||
| import { SkeletonGroupComponent } from "./skeleton-group.component"; | ||
| import { SkeletonTextComponent } from "./skeleton-text.component"; | ||
| import { SkeletonComponent } from "./skeleton.component"; | ||
|
|
||
| export default { | ||
| title: "Component Library/Skeleton/Skeleton Group", | ||
| component: SkeletonGroupComponent, | ||
| decorators: [ | ||
| moduleMetadata({ | ||
| imports: [SharedModule, SkeletonTextComponent, SkeletonComponent], | ||
| }), | ||
| ], | ||
| } as Meta<SkeletonGroupComponent>; | ||
|
|
||
| type Story = StoryObj<SkeletonGroupComponent>; | ||
|
|
||
| export const Default: Story = { | ||
| render: (args) => ({ | ||
| props: args, | ||
| template: /*html*/ ` | ||
| <bit-skeleton-group> | ||
| <bit-skeleton class="tw-size-8" slot="start"></bit-skeleton> | ||
| <bit-skeleton-text [lines]="2" class="tw-w-1/2"></bit-skeleton-text> | ||
| <bit-skeleton-text [lines]="1" slot="end" class="tw-w-1/4"></bit-skeleton-text> | ||
| </bit-skeleton-group> | ||
| `, | ||
| }), | ||
| }; | ||
|
|
||
| export const NoEndSlot: Story = { | ||
| render: (args) => ({ | ||
| props: args, | ||
| template: /*html*/ ` | ||
| <bit-skeleton-group> | ||
| <bit-skeleton class="tw-size-8" slot="start"></bit-skeleton> | ||
| <bit-skeleton-text [lines]="2" class="tw-w-1/2"></bit-skeleton-text> | ||
| </bit-skeleton-group> | ||
| `, | ||
| }), | ||
| }; | ||
|
|
||
| export const NoStartSlot: Story = { | ||
| render: (args) => ({ | ||
| props: args, | ||
| template: /*html*/ ` | ||
| <bit-skeleton-group> | ||
| <bit-skeleton-text [lines]="2" class="tw-w-1/2"></bit-skeleton-text> | ||
| <bit-skeleton-text [lines]="1" slot="end" class="tw-w-1/4"></bit-skeleton-text> | ||
| </bit-skeleton-group> | ||
| `, | ||
| }), | ||
| }; | ||
|
|
||
| export const CustomContent: Story = { | ||
| render: (args) => ({ | ||
| props: args, | ||
| template: /*html*/ ` | ||
| <bit-skeleton-group> | ||
| <bit-skeleton class="tw-size-12" slot="start" edgeShape="circle"></bit-skeleton> | ||
| <bit-skeleton-text [lines]="3" class="tw-w-full"></bit-skeleton-text> | ||
| <div slot="end" class="tw-flex tw-flex-row tw-gap-1"> | ||
| <bit-skeleton class="tw-size-4" slot="start"></bit-skeleton> | ||
| <bit-skeleton class="tw-size-4" slot="start"></bit-skeleton> | ||
| <bit-skeleton class="tw-size-4" slot="start"></bit-skeleton> | ||
| </div> | ||
| </bit-skeleton-group> | ||
| `, | ||
| }), | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| <div class="tw-w-full tw-flex tw-flex-col tw-gap-2"> | ||
| @for (line of this.linesArray(); track $index; let last = $last, first = $first) { | ||
| <bit-skeleton | ||
| class="tw-h-3" | ||
| [ngClass]="{ | ||
| 'tw-w-full': first || !last, | ||
| 'tw-w-1/3': !first && last, | ||
| }" | ||
| ></bit-skeleton> | ||
| } | ||
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { CommonModule } from "@angular/common"; | ||
| import { Component, computed, input } from "@angular/core"; | ||
|
|
||
| import { SkeletonComponent } from "./skeleton.component"; | ||
|
|
||
| /** | ||
| * Specific skeleton component used to represent lines of text. It uses the `bit-skeleton` | ||
| * under the hood. | ||
| * | ||
| * Customize the number of lines represented with the `lines` input. Customize the width | ||
| * by applying a class to the `bit-skeleton-text` element (i.e. `tw-w-1/2`). | ||
| */ | ||
| @Component({ | ||
| selector: "bit-skeleton-text", | ||
| templateUrl: "./skeleton-text.component.html", | ||
| imports: [CommonModule, SkeletonComponent], | ||
| host: { | ||
| class: "tw-block", | ||
| }, | ||
| }) | ||
| export class SkeletonTextComponent { | ||
| /** | ||
| * The number of text lines to display | ||
| */ | ||
| readonly lines = input<number>(1); | ||
|
|
||
| /** | ||
| * Array-transformed version of the `lines` to loop over | ||
| */ | ||
| protected linesArray = computed(() => [...Array(this.lines()).keys()]); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; | ||
|
|
||
| import { SharedModule } from "../shared/shared.module"; | ||
|
|
||
| import { SkeletonTextComponent } from "./skeleton-text.component"; | ||
|
|
||
| import { formatArgsForCodeSnippet } from ".storybook/format-args-for-code-snippet"; | ||
|
|
||
| export default { | ||
| title: "Component Library/Skeleton/Skeleton Text", | ||
| component: SkeletonTextComponent, | ||
| decorators: [ | ||
| moduleMetadata({ | ||
| imports: [SharedModule], | ||
| }), | ||
| ], | ||
| args: { | ||
| lines: 1, | ||
| }, | ||
| argTypes: { | ||
| lines: { | ||
| control: { type: "number", min: 1 }, | ||
| }, | ||
| }, | ||
| } as Meta<SkeletonTextComponent>; | ||
|
|
||
| type Story = StoryObj<SkeletonTextComponent>; | ||
|
|
||
| export const Text: Story = { | ||
| render: (args) => ({ | ||
| props: args, | ||
| template: /*html*/ ` | ||
| <bit-skeleton-text ${formatArgsForCodeSnippet<SkeletonTextComponent>(args)}></bit-skeleton-text> | ||
| `, | ||
| }), | ||
| }; | ||
|
|
||
| export const TextMultiline: Story = { | ||
| render: (args) => ({ | ||
| props: args, | ||
| template: /*html*/ ` | ||
| <bit-skeleton-text ${formatArgsForCodeSnippet<SkeletonTextComponent>(args)}></bit-skeleton-text> | ||
| `, | ||
| }), | ||
| args: { | ||
| lines: 5, | ||
| }, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| <div | ||
| class="tw-size-full tw-bg-secondary-100 tw-animate-pulse" | ||
| [ngClass]="{ | ||
| 'tw-rounded': edgeShape() === 'box', | ||
| 'tw-rounded-full': edgeShape() === 'circle', | ||
| }" | ||
| aria-hidden="true" | ||
| ></div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import { CommonModule } from "@angular/common"; | ||
| import { Component, input } from "@angular/core"; | ||
|
|
||
| /** | ||
| * Basic skeleton loading component that can be used to represent content that is loading. | ||
| * Use for layout-level elements and text, not for interactive elements. | ||
| * | ||
| * Customize the shape's edges with the `edgeShape` input. Customize the shape's size by | ||
| * applying classes to the `bit-skeleton` element (i.e. `tw-w-40 tw-h-8`). | ||
| * | ||
| * If you're looking to represent lines of text, use the `bit-skeleton-text` helper component. | ||
| */ | ||
| @Component({ | ||
| selector: "bit-skeleton", | ||
| templateUrl: "./skeleton.component.html", | ||
| imports: [CommonModule], | ||
| host: { | ||
| class: "tw-block", | ||
| }, | ||
| }) | ||
| export class SkeletonComponent { | ||
| /** | ||
| * The shape of the corners of the skeleton element | ||
| */ | ||
| readonly edgeShape = input<"box" | "circle">("box"); | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make more sense for this to just be 'shape'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe! I felt like
shape="circle"would imply it's always a circle versus just the corners, but I could be overthinking itThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I guess the consumer could pass
circleand then give it differing width and heights. Might be confusing. Unless if we addedwidthandheightinputs. Then, if `shape='circle' we only take one of those values... ๐ค Do we think consumers will want full control to set styles with tailwind? Or are the width/height inputs a less complex DX?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about doing width/height inputs but it felt kind of silly when it's super simple with tailwind already, like I'd just be re-implementing classes. The designs have non-circle shapes with rounded corners so that is why I didn't want to imply the object itself being a circle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, got ya. In that case, I suppose we can't assume everything will be circular.
re width/height inputs: I'm not sure the assumption that it's easy to do with tailwind is necessarily true for everyone. We find it easy because we use tailwind every day but, some folks may not be as familiar. Explicit inputs might feel easier for them. IDK which is 'better' per se though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imo since tailwind is the standard throughout the apps, as long as it's clearly documented in Storybook how to use tailwind to apply width/height, it shouldn't be too confusing. (I think I need to work on the docs more.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BryanCunningham I added more to the docs, lmk if you think it's more clear
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!