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

docs(Skeleton): refactor jsx examples to tsx #2203

Merged
merged 2 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
*
*/

import React from 'react'
import React, { Suspense } from 'react'
import { createBrowserHistory } from 'history'
import ComponentBox from '../../../../shared/tags/ComponentBox'
import Context from '@dnb/eufemia/src/shared/Context'
Copy link
Contributor Author

@langz langz Apr 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to do import Context from '@dnb/eufemia/shared/Context'.
Not sure if we should be able to do so or not? 🤔
I do see multiple references to "non working/correct" jsx examples using import Context from '@dnb/eufemia/shared/Context':

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you do so?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cannot find module '@dnb/eufemia/shared/Context' or its corresponding type declarations.ts(2307)

image

I find several references in our codebase to @dnb/eufemia/shared/Context and @dnb/eufemia/src/shared/Context.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In docs we should always use it without src, while in code we always should include src. I think it should just work fine when we have a strict rule there. You screenshot looks like to have a wrong import path, in that sense, that it not includes src.

import {
Input,
H2,
Expand All @@ -13,10 +15,15 @@ import {
Skeleton,
ToggleButton,
FormRow,
Div,
} from '@dnb/eufemia/src'
import { AllComponents } from '../form-row/Examples'
import Provider from '@dnb/eufemia/src/shared/Provider'
import { Article } from '@dnb/eufemia/src/components/skeleton/figures'
import {
createSkeletonClass,
skeletonDOMAttributes,
} from '@dnb/eufemia/src/components/skeleton/SkeletonHelper'

export const SkeletonInputExample = () => (
<ComponentBox>
Expand Down Expand Up @@ -124,3 +131,86 @@ export const SkeletonVisualTests = () => {
</>
)
}

export const SkeletonInfoProvider = () => (
<ComponentBox hidePreview>
<Div id="your-app">
<Skeleton show={true}>
<Input>I'm hidden behind the skeleton</Input>
<Input>I'm hidden behind the skeleton</Input>
</Skeleton>
</Div>
</ComponentBox>
)

export const SkeletonInfoGlobalProvider = () => (
<ComponentBox scope={{ Provider }} hidePreview>
<Provider locale="nb-NO">
<Div id="your-app">
<Provider skeleton={true}>
<Input>I'm hidden behind the skeleton</Input>
<Input>I'm hidden behind the skeleton</Input>
</Provider>
</Div>
</Provider>
</ComponentBox>
)

export const SkeletonInfoExclude = () => (
<ComponentBox hidePreview>
<Skeleton show={true}>
<Input>I'm hidden behind the skeleton</Input>

<Skeleton.Exclude>
<Input>I'm NOT hidden</Input>
</Skeleton.Exclude>
</Skeleton>
</ComponentBox>
)

export const SkeletonInfoSuspense = () => (
<ComponentBox scope={{ Suspense }} hidePreview hideToolbar>
<Suspense
fallback={
<Skeleton show={true}>
<Div id="user-data" />
</Skeleton>
}
>
<Div id="user-data" />
</Suspense>
</ComponentBox>
)

export const SkeletonInfoCustom = () => (
<ComponentBox
hidePreview
hideToolbar
scope={{
createBrowserHistory,
skeletonDOMAttributes,
createSkeletonClass,
Context,
}}
>
{() => {
function Component({ skeleton = false, ...params } = {}) {
const context = React.useContext(Context)

// Handle accessibility features
skeletonDOMAttributes(params, skeleton, context)

// Handle CSS classes – use either "shape" or "font"
const className = createSkeletonClass('font', skeleton, context)

return (
<div {...params} id="my-component" className={className}>
Hello World
</div>
)
}

return <Component />
}}
</ComponentBox>
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
showTabs: true
---

import {
SkeletonInfoProvider,
SkeletonInfoGlobalProvider,
SkeletonInfoExclude,
SkeletonInfoSuspense,
SkeletonInfoCustom,
} from 'Docs/uilib/components/skeleton/Examples'

## Description

The Skeleton component is a visual building block helper. It will provide loading placeholders that display a non-interactive preview of the app’s actual UI to visually communicate that content is being processed.
Expand Down Expand Up @@ -55,95 +63,28 @@ If you use the skeleton as a provider, the [Space](/uilib/components/space) comp

But the Skeleton component also supports a set of ready-to-use figures. Use it like `figure="article"`.

```jsx
<App>
...
<Skeleton show={true}>
...
<Input>I'm hidden behind the skeleton</Input>
<Input>I'm hidden behind the skeleton</Input>
...
</Skeleton>
...
</App>
```
<SkeletonInfoProvider />

### Global Provider

You can also use the global [Eufemia Provider](/uilib/usage/customisation/provider) to enable the underlying skeletons. You can even have multiple providers wrapped.

```jsx
<Provider locale="nb-NO">
<App>
...
<Provider skeleton={true}>
...
<Input>I'm hidden behind the skeleton</Input>
<Input>I'm hidden behind the skeleton</Input>
...
</Provider>
...
</App>
</Provider>
```
<SkeletonInfoGlobalProvider />

### Exclude a part

You can easily exclude a part from being transformed to a skeleton by using `Skeleton.Exclude`.

```jsx
<Skeleton show={true}>
<Input>I'm hidden behind the skeleton</Input>

<Skeleton.Exclude>
<Input>I'm NOT hidden</Input>
</Skeleton.Exclude>
</Skeleton>
```
<SkeletonInfoExclude />

### Suspense

You can take advantage of an async component by using the React Suspense with a skeleton fallback.

```jsx
...
<Suspense
fallback={
<Skeleton show={true}>
<UserData />
</Skeleton>
}
>
<UserData />
</Suspense>
...
```
<SkeletonInfoSuspense />

### Create a custom skeleton

In order to create the same skeletons as the build-ins, you can make use of a couple of helper tools.

```jsx
import EufemiaContext from '@dnb/eufemia/shared/Context'
import {
skeletonDOMAttributes,
createSkeletonClass,
} from '@dnb/eufemia/components/skeleton/SkeletonHelper'

function Component({ className, skeleton = false, ...params } = {}) {
const context = React.useContext(EufemiaContext)

// Handle accessibility features
skeletonDOMAttributes(params, skeleton, context)

// Handle CSS classes – use either "shape" or "font"
params.className = createSkeletonClass(
'shape',
skeleton,
context,
className
)

return <my-component {...params} />
}
```
<SkeletonInfoCustom />