From 73868ac3394e825ad06a40984b726273e8b00d03 Mon Sep 17 00:00:00 2001 From: vladoseeg Date: Fri, 29 Mar 2024 19:08:54 +0300 Subject: [PATCH] feat(Overlay): implement component --- src/components/Overlay/Overlay.scss | 45 ++++++ src/components/Overlay/Overlay.tsx | 30 ++++ src/components/Overlay/README.md | 32 ++++ .../Overlay/__stories__/Overlay.scss | 24 +++ .../Overlay/__stories__/Overlay.stories.tsx | 151 ++++++++++++++++++ src/components/Overlay/__stories__/utils.tsx | 91 +++++++++++ src/components/Overlay/index.ts | 1 + src/components/index.ts | 1 + 8 files changed, 375 insertions(+) create mode 100644 src/components/Overlay/Overlay.scss create mode 100644 src/components/Overlay/Overlay.tsx create mode 100644 src/components/Overlay/README.md create mode 100644 src/components/Overlay/__stories__/Overlay.scss create mode 100644 src/components/Overlay/__stories__/Overlay.stories.tsx create mode 100644 src/components/Overlay/__stories__/utils.tsx create mode 100644 src/components/Overlay/index.ts diff --git a/src/components/Overlay/Overlay.scss b/src/components/Overlay/Overlay.scss new file mode 100644 index 0000000000..b33abdbf61 --- /dev/null +++ b/src/components/Overlay/Overlay.scss @@ -0,0 +1,45 @@ +@use '../variables'; + +$block: '.#{variables.$ns}overlay'; + +#{$block} { + position: absolute; + inset: 0; + + display: flex; + visibility: hidden; + justify-content: center; + align-items: center; + + opacity: 0; + + transition: + visibility 0.1s linear, + opacity 0.1s linear; + + &_visible { + visibility: visible; + opacity: 1; + } + + &__background { + position: absolute; + inset: 0; + + opacity: 80%; + + &_view { + &_base { + background-color: var(--g-color-base-background); + } + + &_float { + background-color: var(--g-color-base-float); + } + } + } + + &__children { + z-index: 0; + } +} diff --git a/src/components/Overlay/Overlay.tsx b/src/components/Overlay/Overlay.tsx new file mode 100644 index 0000000000..2f17b17825 --- /dev/null +++ b/src/components/Overlay/Overlay.tsx @@ -0,0 +1,30 @@ +import React from 'react'; + +import {block} from '../utils/cn'; + +import './Overlay.scss'; + +const b = block('overlay'); + +export type OverlayBackground = 'base' | 'float'; + +export interface OverlayProps { + className?: string; + view?: OverlayBackground; + visible?: boolean; + children?: React.ReactNode; +} + +export function Overlay({ + className, + view = 'base', + visible: loading = false, + children, +}: OverlayProps) { + return ( +
+
+ {children &&
{children}
} +
+ ); +} diff --git a/src/components/Overlay/README.md b/src/components/Overlay/README.md new file mode 100644 index 0000000000..29694c7503 --- /dev/null +++ b/src/components/Overlay/README.md @@ -0,0 +1,32 @@ + + +# Loader + + + +```tsx +import {Overlay} from '@gravity-ui/uikit'; +``` + +The `Overlay` component renders an overlay over the parent element with relative position. +For example, it can be used to preserve the desired layout while loading data. + +### PropTypes + +| Name | Type | Required | Default | Description | +| :-------- | :----------------- | :------: | :------ | :---------------------------------- | +| className | `String` | | | CSS class name of the root element | +| visible | `Boolean` | | `false` | Overlay visibility state | +| view | `"base"` `"float"` | | `base` | Overlay background style | +| children | `React.ReactNode` | | | Content, usually a Loader component | + +### Basic usage + +```jsx +
+
Some content to hide under overlay
+ + + +
+``` diff --git a/src/components/Overlay/__stories__/Overlay.scss b/src/components/Overlay/__stories__/Overlay.scss new file mode 100644 index 0000000000..1298b33a34 --- /dev/null +++ b/src/components/Overlay/__stories__/Overlay.scss @@ -0,0 +1,24 @@ +@use '../../variables'; + +$block: '.#{variables.$ns}overlay-showcase'; + +#{$block} { + &__content { + position: relative; + + width: fit-content; + padding: var(--g-spacing-1); + } + + &__table table { + min-width: 763px; + } + + &__button { + margin-block-start: var(--g-spacing-1); + + & + & { + margin-inline-start: var(--g-spacing-1); + } + } +} diff --git a/src/components/Overlay/__stories__/Overlay.stories.tsx b/src/components/Overlay/__stories__/Overlay.stories.tsx new file mode 100644 index 0000000000..33c47c9d84 --- /dev/null +++ b/src/components/Overlay/__stories__/Overlay.stories.tsx @@ -0,0 +1,151 @@ +import React from 'react'; + +import {ArrowsRotateRight} from '@gravity-ui/icons'; +import type {Meta, StoryFn} from '@storybook/react'; + +import {Button} from '../../Button'; +import {Dialog as DialogComponent} from '../../Dialog'; +import {Icon} from '../../Icon'; +import {Loader} from '../../Loader'; +import {Table as TableComponent} from '../../Table'; +import {block} from '../../utils/cn'; +import {Overlay} from '../Overlay'; +import type {OverlayProps} from '../Overlay'; + +import {columns, data} from './utils'; +import type {DataItem} from './utils'; + +import './Overlay.scss'; + +const b = block('overlay-showcase'); + +export default { + title: 'Components/Overlays/Overlay', + component: Overlay, +} as Meta; + +const DefaultTemplate: StoryFn = (args) => { + return ( +
+
+
Example of overlay
+
with loader
+ + + +
+
+
Example of overlay
+
with text
+ Loading... +
+
+
Example of overlay
+
with icon
+ + + +
+
+
Example of overlay
+
without children
+ +
+
+ ); +}; +export const Default = DefaultTemplate.bind({}); + +Default.args = { + visible: true, +}; + +const BackgroundTemplate: StoryFn = (args) => { + return ( +
+
+
I am an example
+
content
+ +
+ +
+
I am an example
+
content
+ +
+
+ ); +}; + +export const Background = BackgroundTemplate.bind({}); + +Background.args = { + visible: true, +}; + +const DialogTemplate: StoryFn = (args) => { + const dialogTitleId = 'app-dialog-title'; + return ( + {}} + onEnterKeyDown={() => { + alert('onEnterKeyDown'); + }} + aria-labelledby={dialogTitleId} + > +
+ + Dialog.Body + alert('onApply')} + textButtonApply="Apply" + /> + + + +
+
+ ); +}; + +export const Dialog = DialogTemplate.bind({}); + +Dialog.args = { + visible: true, +}; + +const TableTemplate: StoryFn = (args) => { + const [loading, setLoading] = React.useState(false); + const [loadedData, setData] = React.useState([]); + + return ( +
+
+ + + + +
+ + +
+ ); +}; + +export const Table = TableTemplate.bind({}); diff --git a/src/components/Overlay/__stories__/utils.tsx b/src/components/Overlay/__stories__/utils.tsx new file mode 100644 index 0000000000..9254f6342f --- /dev/null +++ b/src/components/Overlay/__stories__/utils.tsx @@ -0,0 +1,91 @@ +import React from 'react'; + +import type {TableColumnConfig} from '../../Table'; + +export interface DataItem { + name: string; + location?: {region: string; city?: string}; + phone: string; + count: number; + date: string; + disabled?: boolean; +} + +export const columns: TableColumnConfig[] = [ + { + id: 'name', + name: 'Name', + template(item, i) { + if (i % 2 === 0) { + return item.name; + } + const [name, surname] = item.name.split(' '); + return ( +
+ {name} +
+ {surname} +
+ ); + }, + }, + { + id: 'location.region', + name: 'Region', + }, + { + id: 'location.city', + name: 'City', + }, + { + id: 'phone', + name: 'Phone', + }, + { + id: 'count', + name: 'Count', + align: 'end', + }, + { + id: 'date', + name: 'Date created', + }, +]; + +export const data: DataItem[] = [ + { + name: 'Nomlanga Compton', + location: {region: 'Liguria', city: 'Erli'}, + phone: '+7 (923) 737-89-72', + count: 82, + date: '2019-03-15', + }, + { + name: 'Paul Hatfield', + location: {region: 'Trentino-Alto Adige/Südtirol', city: 'Campitello di Fassa'}, + phone: '+7 (900) 333-82-02', + count: 51, + date: '2019-11-23', + }, + { + name: 'Phelan Daniel', + location: {region: 'Piedmont', city: 'Meugliano'}, + phone: '+7 (925) 549-50-23', + count: 10, + date: '2019-05-14', + }, + { + name: 'Hiram Mayer', + phone: '+7 (950) 372-56-84', + location: {region: 'Calabria'}, + count: 54, + date: '2019-03-29', + }, + { + name: 'Madeline Puckett', + phone: '+7 (908) 582-05-91', + count: 75, + date: '2019-02-01', + disabled: true, + }, +]; diff --git a/src/components/Overlay/index.ts b/src/components/Overlay/index.ts new file mode 100644 index 0000000000..6dbcd51b81 --- /dev/null +++ b/src/components/Overlay/index.ts @@ -0,0 +1 @@ +export * from './Overlay'; diff --git a/src/components/index.ts b/src/components/index.ts index 34146e1cf1..f2c5cf58a4 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -22,6 +22,7 @@ export * from './Label'; export * from './Link'; export * from './List'; export * from './Loader'; +export * from './Overlay'; export * from './Menu'; export * from './Modal'; export * from './Pagination';