Skip to content
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

Better Skeleton #159

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e2d3caf
Refactor Skeleton to use TW classes, has better animation and ability…
rushi Aug 6, 2022
b4e95e8
#150 Skeleton with an icon so we can show placeholder images
rushi Aug 9, 2022
185d205
Add ability to override the horiz and vert skeletons
rushi Aug 9, 2022
72f5ea1
Merge branch 'master' of github.com:xola/ui-kit into skeleton-upgrade
rushi Sep 3, 2022
b50fb2d
Go back to the original skeleton shimmer
rushi Sep 3, 2022
52f57f2
Allow user to override entire content
rushi Sep 3, 2022
4ed66e7
Stabilize Skeleton arch
rushi Sep 3, 2022
05f7975
Merge branch 'master' of github.com:xola/ui-kit into skeleton-upgrade
rushi Sep 19, 2022
44f06ab
Merge branch 'master' into skeleton-upgrade
rushi Sep 21, 2022
d5497af
Merge branch 'master' of github.com:xola/ui-kit into skeleton-upgrade
rushi Sep 24, 2022
8ecd4a6
Merge branch 'master' into skeleton-upgrade
rushi Nov 7, 2022
c0186ce
Merge branch 'master' of github.com:xola/ui-kit into skeleton-upgrade
rushi Nov 12, 2022
a325403
Merge branch 'skeleton-upgrade' of github.com:rushi/ui-kit into skele…
rushi Nov 12, 2022
847cfb7
Merge branch 'master' of github.com:xola/ui-kit into skeleton-upgrade
rushi Nov 12, 2022
997b7ae
Merge branch 'master' of github.com:xola/ui-kit into skeleton-upgrade
rushi Nov 12, 2022
26c0bf6
Merge branch 'master' of github.com:xola/ui-kit into skeleton-upgrade
rushi Nov 12, 2022
d0b2f1b
Merge branch 'master' into skeleton-upgrade
rushi Nov 12, 2022
7732adc
Merge branch 'master' into skeleton-upgrade
rushi Nov 12, 2022
b8b4ed4
Merge branch 'master' into skeleton-upgrade
rushi Nov 12, 2022
e1ec264
Merge branch 'master' into skeleton-upgrade
rushi Nov 13, 2022
ed24fec
Rename component that's not actually an icon
rushi Nov 13, 2022
ea9b034
🧹 Lint
rushi Nov 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 80 additions & 11 deletions src/components/Skeleton.jsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,100 @@
import clsx from "clsx";
import { range } from "lodash";
import PropTypes from "prop-types";
import React from "react";
import styles from "./Skeleton.module.css";

export const Skeleton = ({ style, height = 300, shouldAnimate = true, children, classNames = {}, ...rest }) => {
export const Skeleton = ({ height = "h-full", text, children, className, classNames = {}, ...rest }) => {
return (
<div
className={clsx(
"ui-skeleton",
"relative flex items-center justify-center overflow-hidden rounded border border-gray-lighter bg-gray-lighter",
classNames.container,
height,
className,
)}
style={{ height, ...style }}
{...rest}
>
{shouldAnimate ? (
<div className={clsx(styles.shimmer, "absolute h-full w-full", classNames.shimmer)} />
) : null}
<div className={clsx("text-gray", classNames.text)}>{children}</div>
<div className={clsx("absolute h-full w-full", styles.shimmer, classNames.shimmer)} />
{children ?? (
<div className={clsx("flex h-full w-full items-center justify-center text-gray", classNames.content)}>
{text ?? ""}
</div>
)}
</div>
);
};

Skeleton.propTypes = {
style: PropTypes.object,
height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
shouldAnimate: PropTypes.bool,
classNames: PropTypes.object,
height: PropTypes.string,
className: PropTypes.string,
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
};

const gridHorizontal = {
1: "grid-cols-1",
2: "grid-cols-2",
3: "grid-cols-3",
4: "grid-cols-4",
5: "grid-cols-5",
6: "grid-cols-6",
7: "grid-cols-7",
8: "grid-cols-8",
};

const gridVertical = {
1: "grid-rows-1",
2: "grid-rows-2",
3: "grid-rows-3",
4: "grid-rows-4",
5: "grid-rows-5",
6: "grid-rows-6",
7: "grid-rows-7",
8: "grid-rows-8",
};

export const SkeletonGrid = ({
grid = [3, 2],
className = "h-full",
classNames = { horizontalContainer: "", verticalContainer: "", horizontal: "!h-10", vertical: "!h-10" },
}) => {
const [horizontalCount, verticalCount] = grid;
const horizontalClasses = clsx("grid gap-x-2", gridHorizontal[horizontalCount] ?? `grid-cols-${horizontalCount}`);
const verticalClasses = clsx("grid gap-y-2", gridVertical[verticalCount] ?? `grid-rows-${verticalCount}`);

return (
<div className={clsx("flex flex-col space-y-1", className)}>
<SkeletonPerCount
count={horizontalCount}
className={clsx(horizontalClasses, classNames.horizontalContainer)} // Container
classNames={{ skeleton: classNames.horizontal }} // Skeleton
/>
<SkeletonPerCount
count={verticalCount - 1}
className={clsx(verticalClasses, classNames.verticalContainer)} // Container
classNames={{ skeleton: classNames.vertical }} // Skeleton
/>
</div>
);
};

const SkeletonPerCount = ({ count, className, classNames = {} }) => {
return (
count > 0 && (
<div className={className}>
{range(0, count).map((index) => (
<Skeleton key={index} className={classNames.skeleton} />
))}
</div>
)
);
};

export const SkeletonIconOnly = ({ icon, classNames = { skeleton: "h-28 w-28", icon: "h-1/2 w-1/2 text-gray" } }) => {
if (!icon) {
return null;
}

const adjustedIcon = React.cloneElement(icon, { className: classNames.icon });
return <Skeleton className={classNames.skeleton}>{adjustedIcon}</Skeleton>;
};
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export { Label } from "./components/Forms/Label";
export { RangeSlider } from "./components/Forms/RangeSlider";
export { HeaderToolbar } from "./components/HeaderToolbar";
export { Tabs } from "./components/Tabs";
export { Skeleton } from "./components/Skeleton";
export { Skeleton, SkeletonGrid, SkeletonIconOnly } from "./components/Skeleton";
export { Drawer } from "./components/Drawer";
export { Key } from "./components/Key";
export { Login } from "./components/Screens/Login";
Expand Down
57 changes: 51 additions & 6 deletions src/stories/DataDisplay/Skeleton.stories.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,66 @@
import React from "react";
import { Skeleton } from "../..";
import { Skeleton, SkeletonGrid, SkeletonIconOnly, ImageIcon, BarGraphIcon, MountainIcon } from "../..";

const SkeletonStories = {
title: "Data Display/Skeleton",
component: Skeleton,
};

export const Default = () => {
return <Skeleton>Loading...</Skeleton>;
return (
<div className="h-75 w-full space-y-4">
<p>
Parent div set with <code>w-full</code> and <code>h-75</code> (300px). No children specified
</p>
<Skeleton text="Loading..." />
</div>
);
};

export const WithoutAnimation = () => {
export const CustomHeight = () => {
return (
<Skeleton classes={{ container: "w-1/2" }} shouldAnimate={false}>
Not Available
<Skeleton height="h-40">
Height given directly to Skeleton using <code className="mx-1">height</code> attribute
</Skeleton>
);
};

export const MultipleSkeletons = () => {
return (
<div className="space-y-5">
<p>Quickly create multiple Skeleton children</p>
<div className="space-y-2">
<p>
A grid of <code>4x2</code> by passing in <code>grid=&#123;[4x2]&#125;</code>
</p>
<SkeletonGrid grid={[4, 2]} />
</div>
<div className="space-y-2">
<p>
A grid of <code>2x4</code> by passing in <code>grid=&#123;[2x4]&#125;</code>
</p>
<SkeletonGrid grid={[2, 4]} />
</div>
</div>
);
};

export const WithIcons = () => {
return (
<div className="flex flex-row space-x-10 text-gray-dark ">
<div>
Generic Image
<SkeletonIconOnly icon={<ImageIcon />} />
</div>
<div>
Experience Image
<SkeletonIconOnly icon={<MountainIcon />} />
</div>
<div>
Bar Graph
<SkeletonIconOnly icon={<BarGraphIcon />} />
</div>
</div>
);
};

export default SkeletonStories;
8 changes: 8 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ module.exports = {

spacing,

keyframes: {
shimmer: {
"100%": {
transform: "translateX(100%)",
},
},
},

// Figma: https://www.figma.com/file/tL2vrxuBIzujkDfYvVjUhs/%F0%9F%9B%A0-Xola-DS-Desktop-Master-%F0%9F%9B%A0?node-id=1885%3A51905
fontSize: {
xs: "10px",
Expand Down