Skip to content

Commit

Permalink
[Ny komponent] Skeleton (#1821)
Browse files Browse the repository at this point in the history
  • Loading branch information
KenAJoh authored Jun 8, 2023
1 parent 35041e6 commit db8c38a
Show file tree
Hide file tree
Showing 15 changed files with 377 additions and 2 deletions.
8 changes: 8 additions & 0 deletions .changeset/wise-icons-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@navikt/ds-css": minor
"@navikt/ds-react": minor
---

:tada: Ny komponent Skeleton!

- varianter: text, circle, rounded og rectangle
1 change: 1 addition & 0 deletions @navikt/core/css/config/_mappings.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ const StyleMappings = {
{ component: "ReadMore", main: "read-more.css", dependencies: [typoCss] },
{ component: "Search", main: formCss, dependencies: [typoCss] },
{ component: "Select", main: formCss, dependencies: [typoCss] },
{ component: "Skeleton", main: "skeleton.css", dependencies: [] },
{ component: "Stepper", main: "stepper.css", dependencies: [typoCss] },
{ component: "Switch", main: formCss, dependencies: [typoCss] },
{ component: "Table", main: "table.css", dependencies: [typoCss] },
Expand Down
1 change: 1 addition & 0 deletions @navikt/core/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
@import "panel.css";
@import "link-panel.css";
@import "read-more.css";
@import "skeleton.css";
@import "stepper.css";
@import "table.css";
@import "tabs.css";
Expand Down
55 changes: 55 additions & 0 deletions @navikt/core/css/skeleton.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.navds-skeleton {
display: block;
background-color: var(--ac-skeleton-bg, var(--a-surface-neutral-moderate));
height: 1.3em;
animation: akselSkeletonAnimation 0.8s linear infinite alternate;
}

.navds-skeleton--has-children {
color: transparent;
}

.navds-skeleton--has-children > * {
visibility: hidden;
}

.navds-skeleton--has-children.navds-skeleton--no-height {
height: auto;
}

.navds-skeleton--has-children.navds-skeleton--no-width {
width: fit-content;
}

.navds-skeleton--text {
height: auto;
transform-origin: 0 55%;
transform: scale(1, 0.6);
border-radius: var(--a-border-radius-medium);
}

.navds-skeleton--text:empty::before {
content: "\00a0";
}

.navds-skeleton--circle {
border-radius: var(--a-border-radius-full);
}

.navds-skeleton--rectangle {
border-radius: 0;
}

.navds-skeleton--rounded {
border-radius: var(--a-border-radius-xlarge);
}

@keyframes akselSkeletonAnimation {
0% {
opacity: 1;
}

100% {
opacity: 0.4;
}
}
3 changes: 3 additions & 0 deletions @navikt/core/css/tokens.json
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@
"--ac-read-more-active-bg": "--a-surface-active",
"--ac-read-more-line": "--a-border-divider"
},
"skeleton": {
"--ac-skeleton-bg": "--a-surface-neutral-moderate"
},
"stepper": {
"--ac-stepper-text": "--a-surface-action",
"--ac-stepper-line": "--a-border-default",
Expand Down
1 change: 1 addition & 0 deletions @navikt/core/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export * from "./panel";
export * from "./popover";
export * from "./provider";
export * from "./read-more";
export * from "./skeleton";
export * from "./stepper";
export * from "./table";
export * from "./tabs";
Expand Down
48 changes: 48 additions & 0 deletions @navikt/core/react/src/skeleton/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { forwardRef } from "react";
import cl from "clsx";

export interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
children?: React.ReactNode;
/**
* @default text
*/
variant?: "circle" | "rectangle" | "rounded" | "text";
/**
* When not inferring height from children, you must specify height
*/
height?: number | string;
/**
* When not infering width from children, you must specify width
*/
width?: number | string;
}

export const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(
(
{ className, children, height, width, style, variant = "text", ...rest },
ref
) => {
return (
<div
{...rest}
ref={ref}
className={cl(
"navds-skeleton",
className,
`navds-skeleton--${variant}`,
{
"navds-skeleton--has-children": Boolean(children),
"navds-skeleton--no-height": !height,
"navds-skeleton--no-width": !width,
}
)}
style={{ ...style, width, height }}
aria-hidden
>
{children}
</div>
);
}
);

export default Skeleton;
2 changes: 2 additions & 0 deletions @navikt/core/react/src/skeleton/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as Skeleton } from "./Skeleton";
export type { SkeletonProps } from "./Skeleton";
118 changes: 118 additions & 0 deletions @navikt/core/react/src/skeleton/skeleton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import React from "react";
import { Skeleton } from ".";
import { Alert } from "../alert";
import { Button } from "../button";
import { Checkbox } from "../form";
import { BodyLong, Heading } from "../typography";

export default {
title: "ds-react/Skeleton",
component: Skeleton,
decorators: [
(Story) => (
<div style={{ display: "grid", gap: "0.5rem" }}>
<Story />
</div>
),
],
};

export const Default = {
render: () => (
<div>
<Skeleton>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur
voluptas sint dolore omnis quia consequatur beatae vero cum officia
debitis. Quidem debitis omnis reprehenderit nobis rerum. Nulla, magnam?
Saepe, eveniet? Test
</Skeleton>
<Skeleton>
<Alert variant="info">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur
voluptas sint dolore omnis quia consequatur beatae vero cum officia
debitis. Quidem debitis omnis reprehenderit nobis rerum. Nulla,
magnam? Saepe, eveniet?
</Alert>
</Skeleton>
<Skeleton>
<BodyLong>
Quidem debitis omnis reprehenderit nobis rerum. Nulla, magnam? Saepe,
eveniet?
</BodyLong>
<Checkbox value="test">Valg 1</Checkbox>
<Checkbox value="tes2">Valg 2</Checkbox>
<div style={{ display: "flex", gap: "2rem" }}>
<Button>Send inn</Button>
<Button>Tilbake</Button>
</div>
</Skeleton>
</div>
),
};

export const Shapes = {
render: () => (
<>
<Skeleton variant="text"></Skeleton>
<Skeleton variant="circle" width={60} height={60}></Skeleton>
<Skeleton variant="rectangle" width={200} height={40}></Skeleton>
<Skeleton variant="rounded" width={200} height={40}></Skeleton>
</>
),
};

export const WrappingComponents = {
render: () => (
<Skeleton style={{ display: "grid", gap: "0.5rem" }}>
<BodyLong>
Quidem debitis omnis reprehenderit nobis rerum. Nulla, magnam? Saepe,
eveniet?
</BodyLong>
<Checkbox value="test">Valg 1</Checkbox>
<Checkbox value="tes2">Valg 2</Checkbox>
<div style={{ display: "flex", gap: "2rem" }}>
<Button>Send inn</Button>
<Button>Tilbake</Button>
</div>
</Skeleton>
),
};

export const TextSizing = {
render: () => (
<div style={{ display: "grid", width: 300 }}>
<Skeleton>
<Heading level="1" size="xlarge">
Placeholder
</Heading>
</Skeleton>
<Skeleton>
<BodyLong>Placeholder</BodyLong>
</Skeleton>
<BodyLong as={Skeleton}>Placeholder</BodyLong>
</div>
),
};

export const NativeText = {
render: () => (
<div>
<h1>
<Skeleton>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur
voluptas sint dolore omnis quia consequatur beatae vero cum officia
debitis. Quidem debitis omnis reprehenderit nobis rerum. Nulla,
magnam? Saepe, eveniet? Test
</Skeleton>
</h1>
<Skeleton>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur
voluptas sint dolore omnis quia consequatur beatae vero cum officia
debitis. Quidem debitis omnis reprehenderit nobis rerum. Nulla,
magnam? Saepe, eveniet? Test
</p>
</Skeleton>
</div>
),
};
4 changes: 2 additions & 2 deletions aksel.nav.no/website/components/sanity-modules/TokenTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const TokenTable = ({ node }: { node: TokenTableT }) => {
key={key}
className="peer border-b border-t border-gray-300 font-mono text-sm last-of-type:rounded-b"
>
<td className="border-t border-r border-gray-300 p-2">{key}</td>
<td className="border-r border-t border-gray-300 p-2">{key}</td>
<td className="border-t border-gray-300 p-2">{val}</td>
</tr>
))}
Expand All @@ -57,7 +57,7 @@ const TokenTable = ({ node }: { node: TokenTableT }) => {
};\n`,
""
)}
className="absolute top-2 right-2 z-10"
className="absolute right-2 top-2 z-10"
/>
<Label size="small" as="span" spacing>
Hva er dette?
Expand Down
25 changes: 25 additions & 0 deletions aksel.nav.no/website/pages/eksempler/skeleton/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Skeleton } from "@navikt/ds-react";
import { withDsExample } from "components/website-modules/examples/withDsExample";

const Example = () => {
return (
<div className="shadow-medium ring-border-subtle w-56 rounded-lg p-6 ring-1">
<Skeleton variant="circle" width={60} height={60} />
<Skeleton variant="text" width="100%" />
<Skeleton variant="text" width="100%" />
<Skeleton variant="text" width="100%" />
<Skeleton variant="text" width="80%" />
</div>
);
};

export default withDsExample(Example);

/* Storybook story */
export const Demo = {
render: Example,
};

export const args = {
index: 4,
};
22 changes: 22 additions & 0 deletions aksel.nav.no/website/pages/eksempler/skeleton/children.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Button, Skeleton, TextField } from "@navikt/ds-react";
import { withDsExample } from "components/website-modules/examples/withDsExample";

const Example = () => {
return (
<Skeleton variant="rounded">
<TextField label="E-post" />
<Button>Send inn</Button>
</Skeleton>
);
};

export default withDsExample(Example);

/* Storybook story */
export const Demo = {
render: Example,
};

export const args = {
index: 3,
};
35 changes: 35 additions & 0 deletions aksel.nav.no/website/pages/eksempler/skeleton/default.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Heading, Skeleton } from "@navikt/ds-react";
import { withDsExample } from "components/website-modules/examples/withDsExample";

const Example = () => {
return (
<>
{loaded ? (
<span>Loaded</span>
) : (
<div className="w-48">
<Skeleton variant="circle" width={80} height={80} />
<Heading as={Skeleton} size="large">
Card-title
</Heading>
<Skeleton variant="text" width="100%" />
<Skeleton variant="text" width="100%" />
<Skeleton variant="text" width="80%" />
</div>
)}
</>
);
};

export default withDsExample(Example);

/* Storybook story */
export const Demo = {
render: Example,
};

export const args = {
index: 5,
};

const loaded = false;
Loading

0 comments on commit db8c38a

Please sign in to comment.