Skip to content

Commit

Permalink
[PBNTR-485] Beta Skeleton Loading Kit- React (#3876)
Browse files Browse the repository at this point in the history
**What does this PR do?** A clear and concise description with your
runway ticket url.
[PBNTR-485](https://runway.powerhrg.com/backlog_items/PBNTR-485)
introduces a new beta kit, Skeleton Loading, react only for now. It
follows this
[handoff](https://huddle.powerapp.cloud/projects/630/handoffs/1342/) and
[build
plan](https://gist.github.com/nidaqg/70bfdc07132a8cf90ade05f008acf836).

**Screenshots:** Screenshots to visualize your addition/change
<img width="1341" alt="default doc ex"
src="https://github.com/user-attachments/assets/20b4e891-32be-43dd-9e0d-b993decb5c6f">
<img width="1341" alt="for pr color doc ex"
src="https://github.com/user-attachments/assets/94af22f6-85b6-4d97-a2ee-bf1feb6cbcf1">
<img width="1345" alt="layout doc ex"
src="https://github.com/user-attachments/assets/64088352-a8eb-4080-ae73-6a7a8c1eb64f">
<img width="1343" alt="border radius doc ex"
src="https://github.com/user-attachments/assets/dd54a33b-5eda-42ec-913c-1524205a4b16">
<img width="1322" alt="for pr height width doc ex"
src="https://github.com/user-attachments/assets/96cc9d5d-7986-41fc-9062-0d528ed6f7f6">
<img width="1322" alt="for pr height width 2 doc ex"
src="https://github.com/user-attachments/assets/e8d7fa62-52ea-424a-bfa8-80036460b7cf">
<img width="1342" alt="dark mode doc ex"
src="https://github.com/user-attachments/assets/fa9c9848-b2cd-450e-b826-6b278366b5b2">

**How to test?** Steps to confirm the desired behavior:
1. Go to the beta [Skeleton Loading kit
page](https://pr3876.playbook.beta.px.powerapp.cloud/kits/skeleton_loading/react)
in the review env. Note: as a beta kit, the kit should not be visible on
the Sidebar nor in the State & Progress Indicators kit category page.
2. Scroll through and review each doc example: default, color, layout,
border radius, height & width, square. Check dark mode as well.

#### Checklist:
- [x] **LABELS** Add a label: `enhancement`, `bug`, `improvement`, `new
kit`, `deprecated`, or `breaking`. See [Changelog &
Labels](https://github.com/powerhome/playbook/wiki/Changelog-&-Labels)
for details.
- [x] **DEPLOY** I have added the `milano` label to show I'm ready for a
review.
- [x] **TESTS** I have added test coverage to my code.
  • Loading branch information
ElisaShapiro authored Nov 8, 2024
1 parent d13622a commit aa29701
Show file tree
Hide file tree
Showing 23 changed files with 458 additions and 2 deletions.
5 changes: 4 additions & 1 deletion playbook-website/config/menu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ kits:
description:
status: stable
- name: drawer
platforms: *1
platforms: *1
status: beta
- category: buttons
description: Buttons are used primarily for actions, such as “Save” and “Cancel”.
Expand Down Expand Up @@ -494,6 +494,9 @@ kits:
description: The timeline kit can use two different line styles in the same timeline
- solid and dotted line styles.
status: stable
- name: skeleton_loading
platforms: *1
status: beta
- category: tags
description:
components:
Expand Down
2 changes: 2 additions & 0 deletions playbook/app/entrypoints/playbook-doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import * as SelectableCard from 'kits/pb_selectable_card/docs'
import * as SelectableCardIcon from 'kits/pb_selectable_card_icon/docs'
import * as SelectableIcon from 'kits/pb_selectable_icon/docs'
import * as SelectableList from 'kits/pb_selectable_list/docs'
import * as SkeletonLoading from 'kits/pb_skeleton_loading/docs'
import * as Source from 'kits/pb_source/docs'
import * as StarRating from 'kits/pb_star_rating/docs'
import * as StatChange from 'kits/pb_stat_change/docs'
Expand Down Expand Up @@ -197,6 +198,7 @@ WebpackerReact.registerComponents({
...SelectableCardIcon,
...SelectableIcon,
...SelectableList,
...SkeletonLoading,
...Source,
...StarRating,
...StatChange,
Expand Down
2 changes: 1 addition & 1 deletion playbook/app/entrypoints/playbook.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

@import 'kits/pb_advanced_table/advanced_table';
@import 'kits/pb_avatar/avatar';
@import 'kits/pb_avatar_action_button/avatar_action_button';
Expand Down Expand Up @@ -85,6 +84,7 @@
@import 'kits/pb_selectable_card_icon/selectable_card_icon';
@import 'kits/pb_selectable_icon/selectable_icon';
@import 'kits/pb_selectable_list/selectable_list';
@import 'kits/pb_skeleton_loading/skeleton_loading';
@import 'kits/pb_source/source';
@import 'kits/pb_star_rating/star_rating';
@import 'kits/pb_stat_change/stat_change';
Expand Down
1 change: 1 addition & 0 deletions playbook/app/javascript/kits.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export { default as SelectableCardIcon } from '../pb_kits/playbook/pb_selectable
export { default as SelectableIcon } from '../pb_kits/playbook/pb_selectable_icon/_selectable_icon'
export { default as SelectableList } from '../pb_kits/playbook/pb_selectable_list/_selectable_list'
export { default as SelectableListItem } from '../pb_kits/playbook/pb_selectable_list/_item'
export { default as SkeletonLoading} from '../pb_kits/playbook/pb_skeleton_loading/_skeleton_loading'
export { default as Source } from '../pb_kits/playbook/pb_source/_source'
export { default as StarRating } from '../pb_kits/playbook/pb_star_rating/_star_rating'
export { default as StatChange } from '../pb_kits/playbook/pb_stat_change/_stat_change'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@import 'skeleton_loading_mixins';

.pb_skeleton_loading {
display: "flex";
flex-direction: "column";
height: 100%;
.color_default {
@include skeleton-shimmer($silver);
}
.color_white {
@include skeleton-shimmer-light($white);
}
.dark {
@include skeleton-shimmer($border_dark);
}
.gap_xxs {
margin-top: 4px;
}
.gap_xs {
margin-top: 8px;
}
.gap_sm {
margin-top: 16px;
}
.gap_md {
margin-top: 24px;
}
.gap_lg {
margin-top: 32px;
}
.gap_xl {
margin-top: 40px;
}
.gap_xxl {
margin-top: 48px;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

import React from 'react'
import classnames from 'classnames'
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
import { globalProps, GlobalProps } from '../utilities/globalProps'
import { Sizes } from '../types'


type SkeletonLoadingProps = {
aria?: { [key: string]: string },
className?: string,
data?: { [key: string]: string },
id?: string,
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
height?: string,
width?: string,
borderRadius?: string,
gap?: Sizes | "none",
stack?: number,
color?: "default" | "white",
dark?: boolean,
} & GlobalProps

const SkeletonLoading = (props: SkeletonLoadingProps): React.ReactElement => {
const {
aria = {},
className,
data = {},
id,
htmlOptions = {},
height = "16px",
width = "100%",
borderRadius = "sm",
gap = "xxs",
stack = 1,
color = "default",
dark = false,
} = props

const ariaProps = buildAriaProps(aria)
const dataProps = buildDataProps(data)
const htmlProps = buildHtmlProps(htmlOptions)
const skeletonContainerCss = classnames(buildCss('pb_skeleton_loading'), globalProps(props), className)
const gapClass = gap !== 'none' ? `gap_${gap}` : ''
const innerSkeletonCss = classnames(`border_radius_${borderRadius}`,`color_${color}`, dark && 'dark', )
const innerSizeStyle = { height, width }

return (
<div
{...ariaProps}
{...dataProps}
{...htmlProps}
className={skeletonContainerCss}
id={id}
>
{Array.from({ length: Number(stack) }).map((_, index) => (
<div
className={classnames(buildCss('pb_skeleton_loading_item'), innerSkeletonCss, index > 0 && gapClass)}
key={index}
style={innerSizeStyle}
/>
))}
</div>
)
}

export default SkeletonLoading
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Animation
@keyframes wave {
0% {
background-position: -468px 0;
}
100% {
background-position: 468px 0;
}
}

// Shimmer animation and gradient mixin based on color
@mixin skeleton-shimmer($color) {
background: $color;
background-color: $color;
background-image: linear-gradient(
to left,
$color 0%,
lighten($color, 1%) 50%,
lighten($color, 1%) 60%,
$color 80%,
$color 100%
);
background-repeat: no-repeat;
animation: wave 1.5s linear infinite forwards;
}

@mixin skeleton-shimmer-light($color) {
background: $color;
background-color: $color;
background-image: linear-gradient(
to left,
$color 0%,
darken($color, 1%) 50%,
darken($color, 1%) 60%,
$color 80%,
$color 100%
);
background-repeat: no-repeat;
animation: wave 1.5s linear infinite forwards;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react'
import { Flex, SkeletonLoading } from "playbook-ui"


const SkeletonLoadingBorderRadius = (props) => (
<Flex justify="evenly">
<SkeletonLoading
borderRadius="rounded"
height="50px"
width="100px"
{...props}
/>
<SkeletonLoading
borderRadius="xl"
height="50px"
width="100px"
{...props}
/>
<SkeletonLoading
borderRadius="lg"
height="50px"
width="100px"
{...props}
/>
<SkeletonLoading
borderRadius="md"
height="50px"
width="100px"
{...props}
/>
<SkeletonLoading
height="50px"
width="100px"
{...props}
/>
<SkeletonLoading
borderRadius="xs"
height="50px"
width="100px"
{...props}
/>
<SkeletonLoading
borderRadius="none"
height="50px"
width="100px"
{...props}
/>
</Flex>
)

export default SkeletonLoadingBorderRadius
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The `borderRadius` prop accepts all of our [BorderRadius](https://playbook.powerapp.cloud/visual_guidelines/border_radius) tokens, with `sm` as default.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'
import { Card, SkeletonLoading } from "playbook-ui"


const SkeletonLoadingColor = (props) => (
<div>
<Card
borderNone
{...props}
>
<SkeletonLoading {...props}/>
</Card>
<Card
background="light"
borderNone
{...props}
>
<SkeletonLoading
color="white"
{...props}
/>
</Card>
</div>
)

export default SkeletonLoadingColor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The SkeletonLoading component has a default and a white `color` variant.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= pb_rails("skeleton_loading") %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react'
import { SkeletonLoading } from "playbook-ui"


const SkeletonLoadingDefault = (props) => (
<div>
<SkeletonLoading {...props} />
</div>
)

export default SkeletonLoadingDefault
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react'
import { Card, SkeletonLoading } from "playbook-ui"


const SkeletonLoadingHeightWidth = (props) => (
<div>
<SkeletonLoading
height="100px"
width="50%"
{...props}
/>
<SkeletonLoading
gap="md"
height="20px"
marginY="md"
stack="3"
width="50px"
{...props}
/>
<Card htmlOptions={{ style: { height: '200px', width: '100%' }}}
marginBottom="md"
padding="none"
>
<SkeletonLoading
borderRadius="md"
gap="xl"
height="50%"
width="300px"
{...props}
/>
</Card>
<Card htmlOptions={{ style: { height: '200px', width: '100%' }}}
padding="none"
>
<SkeletonLoading
borderRadius="md"
gap="xl"
height="30%"
stack="2"
width="70%"
{...props}
/>
</Card>
<SkeletonLoading
height="150px"
marginY="md"
width="150px"
{...props}
/>
<SkeletonLoading
borderRadius="rounded"
height="150px"
width="150px"
{...props}
/>
</div>
)

export default SkeletonLoadingHeightWidth
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The `height` and `width` props accept pixel and percentage values. If using a percentage for `height`, the parent container must have a set height.

Set the `height` and `width` props to the same value to make a square. A `rounded` borderRadius will make a square a circle. If using percentages to make a square, your parent container must also be a square.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
import { SkeletonLoading } from "playbook-ui"


const SkeletonLoadingLayout = (props) => (
<div>
<SkeletonLoading
stack="5"
{...props}
/>
<SkeletonLoading
gap="md"
paddingTop="xl"
stack="3"
{...props}
/>
</div>
)

export default SkeletonLoadingLayout
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Use the `stack` and `gap` props in conjunction to layer multiple Skeleton loading bars on top of each other.

`stack` accepts a number that correlates to the number of rows (1 is default), and `gap` accepts a portion of our [spacing props](https://playbook.powerapp.cloud/visual_guidelines/spacing) (`xxs` as default, `xs`, `sm`, `md`, `lg`, `xl`, `xxl`) to set the pixel distance between each row. `gap` will not do anything if there is no corresponding `stack` prop set.
Loading

0 comments on commit aa29701

Please sign in to comment.