mirror of
https://github.com/primer/css.git
synced 2024-12-23 06:01:54 +03:00
OverlayBase ongoing stylesheets
This commit is contained in:
parent
0cca3c1e33
commit
74a4d200c3
@ -1,620 +0,0 @@
|
|||||||
import clsx from 'clsx'
|
|
||||||
import React from 'react'
|
|
||||||
import ConditionalWrapper from '../../helpers/ConditionalWrapper'
|
|
||||||
import {PatternFullBleed} from '../ActionList/ActionListFeatures.stories.jsx'
|
|
||||||
const variant = {}
|
|
||||||
export default {
|
|
||||||
title: 'UI Patterns/Overlay',
|
|
||||||
parameters: {
|
|
||||||
layout: 'padded'
|
|
||||||
},
|
|
||||||
excludeStories: ['OverlayTemplate'],
|
|
||||||
argTypes: {
|
|
||||||
|
|
||||||
// Header
|
|
||||||
|
|
||||||
title: {
|
|
||||||
name: 'title',
|
|
||||||
type: {name: 'string', required: true},
|
|
||||||
description: 'The heading element of the overlay',
|
|
||||||
defaultValue: 'Title',
|
|
||||||
table: {
|
|
||||||
category: 'Header'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
description: {
|
|
||||||
name: 'description',
|
|
||||||
type: 'string',
|
|
||||||
description: 'The sub-heading element of the overlay',
|
|
||||||
defaultValue: '',
|
|
||||||
table: {
|
|
||||||
category: 'Header'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
headerVariant: {
|
|
||||||
options: ['medium', 'large', 'custom'],
|
|
||||||
defaultValue: 'medium',
|
|
||||||
control: {
|
|
||||||
type: 'inline-radio',
|
|
||||||
},
|
|
||||||
description: 'medium title (default), large title, or custom header',
|
|
||||||
table: {
|
|
||||||
category: 'Header'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleOverlay: {
|
|
||||||
control: {type: 'boolean'},
|
|
||||||
description: 'show/hide overlay',
|
|
||||||
defaultValue: false,
|
|
||||||
table: {
|
|
||||||
category: 'Demo'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showCloseButton: {
|
|
||||||
control: {type: 'boolean'},
|
|
||||||
description: 'show/hide close button',
|
|
||||||
defaultValue: false,
|
|
||||||
table: {
|
|
||||||
category: 'Demo'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showFooterButton: {
|
|
||||||
control: {type: 'boolean'},
|
|
||||||
description: 'show/hide footer button',
|
|
||||||
defaultValue: false,
|
|
||||||
table: {
|
|
||||||
category: 'Demo'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Properties
|
|
||||||
|
|
||||||
width: {
|
|
||||||
options: ['auto', 'xsmall', 'small', 'medium', 'large', 'xlarge', 'xxlarge'],
|
|
||||||
control: {
|
|
||||||
type: 'inline-radio',
|
|
||||||
},
|
|
||||||
description: 'Width options: xsmall: 192px, small: 256px, medium: 320px, large: 480px, xlarge: 640px, xxlarge: 960px',
|
|
||||||
table: {
|
|
||||||
category: 'Properties'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
height: {
|
|
||||||
options: ['auto', 'xsmall', 'small', 'medium', 'large', 'xlarge'],
|
|
||||||
control: {
|
|
||||||
type: 'inline-radio',
|
|
||||||
},
|
|
||||||
description: 'Height options: auto: adjusts to content, xsmall: 192px, small: 256px, medium: 320px, large: 432px, xlarge: 600px',
|
|
||||||
table: {
|
|
||||||
category: 'Properties'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bodyPaddingVariant: {
|
|
||||||
options: [0, 1, 2], // iterator
|
|
||||||
mapping: ['', 'Overlay-body--paddingCondensed', 'Overlay-body--paddingNone'], // values
|
|
||||||
control: {
|
|
||||||
type: 'inline-radio',
|
|
||||||
labels: ['normal (default)', 'condensed', 'none']
|
|
||||||
},
|
|
||||||
description: 'body spacing',
|
|
||||||
table: {
|
|
||||||
category: 'CSS'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Variant
|
|
||||||
|
|
||||||
variant: {
|
|
||||||
options: ['center', 'anchor', 'side', 'full'],
|
|
||||||
type: {
|
|
||||||
name: 'select',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
description: '',
|
|
||||||
table: {
|
|
||||||
category: 'Variant'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
variantWhenNarrow: {
|
|
||||||
options: ['inherit', 'center', 'anchor', 'side', 'full'],
|
|
||||||
defaultValue: 'inherit',
|
|
||||||
type: {
|
|
||||||
name: 'select',
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
description: '',
|
|
||||||
table: {
|
|
||||||
category: 'Variant'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
placementNarrow: {
|
|
||||||
options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
|
|
||||||
mapping: [
|
|
||||||
'Overlay-backdrop--placement-top-whenNarrow',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'Overlay-backdrop--placement-bottom-whenNarrow',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'Overlay-backdrop--placement-right-whenNarrow',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'Overlay-backdrop--placement-left-whenNarrow',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
''
|
|
||||||
],
|
|
||||||
control: {
|
|
||||||
type: 'inline-radio',
|
|
||||||
labels: [
|
|
||||||
'top',
|
|
||||||
'top-start',
|
|
||||||
'top-center',
|
|
||||||
'top-end',
|
|
||||||
'bottom',
|
|
||||||
'bottom-start',
|
|
||||||
'bottom-center',
|
|
||||||
'bottom-end',
|
|
||||||
'right',
|
|
||||||
'right-start',
|
|
||||||
'right-center',
|
|
||||||
'right-end',
|
|
||||||
'left',
|
|
||||||
'left-start',
|
|
||||||
'left-center',
|
|
||||||
'left-end',
|
|
||||||
'reset'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
description: 'Positions overlay for narrow viewport range',
|
|
||||||
table: {
|
|
||||||
category: 'Placement'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
placementRegular: {
|
|
||||||
options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
|
|
||||||
mapping: [
|
|
||||||
'Overlay-backdrop--placement-top',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'Overlay-backdrop--placement-bottom',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'Overlay-backdrop--placement-right',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'Overlay-backdrop--placement-left',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
''
|
|
||||||
],
|
|
||||||
control: {
|
|
||||||
type: 'inline-radio',
|
|
||||||
labels: [
|
|
||||||
'top',
|
|
||||||
'top-start',
|
|
||||||
'top-center',
|
|
||||||
'top-end',
|
|
||||||
'bottom',
|
|
||||||
'bottom-start',
|
|
||||||
'bottom-center',
|
|
||||||
'bottom-end',
|
|
||||||
'right',
|
|
||||||
'right-start',
|
|
||||||
'right-center',
|
|
||||||
'right-end',
|
|
||||||
'left',
|
|
||||||
'left-start',
|
|
||||||
'left-center',
|
|
||||||
'left-end',
|
|
||||||
'reset'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
description: 'Positions overlay for regular viewport range',
|
|
||||||
table: {
|
|
||||||
category: 'Placement'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hasHeader: {
|
|
||||||
control: {type: 'boolean'},
|
|
||||||
description:
|
|
||||||
'A header region may be used to provide context to the user by displaying a title, description, and offering an easy-to-escape route with a Close button. Headers may also provide ways for the user to interact with the content, such as with search and tabs.',
|
|
||||||
defaultValue: true,
|
|
||||||
table: {
|
|
||||||
category: 'Header'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hasFooter: {
|
|
||||||
control: {type: 'boolean'},
|
|
||||||
description:
|
|
||||||
'The footer region may be used to show confirmation actions, navigation links, or other important elements that should appear outside of the content scrolling region.',
|
|
||||||
defaultValue: true,
|
|
||||||
table: {
|
|
||||||
category: 'Footer'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showFooterDivider: {
|
|
||||||
control: {type: 'boolean'},
|
|
||||||
defaultValue: false,
|
|
||||||
description: 'Show dividers above footer',
|
|
||||||
table: {
|
|
||||||
category: 'CSS'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showHeaderDivider: {
|
|
||||||
control: {type: 'boolean'},
|
|
||||||
defaultValue: false,
|
|
||||||
description: 'Show dividers below header',
|
|
||||||
table: {
|
|
||||||
category: 'Header'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
headerSlot: {
|
|
||||||
description: 'Slot for custom header content. Only shown if header variant is set to `custom`.',
|
|
||||||
control: {type: 'string'},
|
|
||||||
table: {
|
|
||||||
category: 'HTML'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
subHeaderSlot: {
|
|
||||||
description: 'Slot for sub header content, present below the header and before the body.',
|
|
||||||
control: {type: 'string'},
|
|
||||||
table: {
|
|
||||||
category: 'HTML'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actionContentSlot: {
|
|
||||||
description: 'Slot for additional header action',
|
|
||||||
control: {type: 'string'},
|
|
||||||
table: {
|
|
||||||
category: 'HTML'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
motion: {
|
|
||||||
options: ['auto', 'none', 'scaleFade', 'slide', 'slideFade'],
|
|
||||||
control: {
|
|
||||||
type: 'inline-radio',
|
|
||||||
},
|
|
||||||
description: 'Animation options for show/hide overlay',
|
|
||||||
table: {
|
|
||||||
category: 'Properties'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
footerContentAlign: {
|
|
||||||
options: [0, 1, 2], // iterator
|
|
||||||
mapping: ['Overlay-footer--alignStart', 'Overlay-footer--alignCenter', 'Overlay-footer--alignEnd'], // values
|
|
||||||
control: {
|
|
||||||
type: 'inline-radio',
|
|
||||||
labels: ['start', 'center', 'end']
|
|
||||||
},
|
|
||||||
description: 'Align footer contents',
|
|
||||||
table: {
|
|
||||||
category: 'Footer'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
role: {
|
|
||||||
description: 'Semantic role',
|
|
||||||
control: {type: 'string'},
|
|
||||||
table: {
|
|
||||||
category: 'HTML'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ariaLabelledy: {
|
|
||||||
description: 'aria-labelledby',
|
|
||||||
control: {type: 'string'},
|
|
||||||
table: {
|
|
||||||
category: 'HTML'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ariaDescribedby: {
|
|
||||||
description: 'aria-describedby',
|
|
||||||
control: {type: 'string'},
|
|
||||||
table: {
|
|
||||||
category: 'HTML'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dataFocusTrap: {
|
|
||||||
description: 'data-focus-trap',
|
|
||||||
control: {type: 'string'},
|
|
||||||
table: {
|
|
||||||
category: 'HTML'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
titleId: {
|
|
||||||
description: 'title id',
|
|
||||||
control: {type: 'string'},
|
|
||||||
table: {
|
|
||||||
category: 'HTML'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
descriptionId: {
|
|
||||||
description: 'description id',
|
|
||||||
control: {type: 'string'},
|
|
||||||
table: {
|
|
||||||
category: 'HTML'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const focusMethod = function getFocus() {
|
|
||||||
const dialog = document.getElementById('overlay-backdrop')[0]
|
|
||||||
dialog.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
const toggleDialog = () => {
|
|
||||||
const dialog = document.getElementById('overlay-backdrop')
|
|
||||||
dialog.classList.toggle('Overlay--hidden')
|
|
||||||
focusMethod()
|
|
||||||
}
|
|
||||||
|
|
||||||
export const OverlayTemplate = ({
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
toggleOverlay,
|
|
||||||
variantWhenNarrow,
|
|
||||||
variant,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
showFooterDivider,
|
|
||||||
showHeaderDivider,
|
|
||||||
hasHeader,
|
|
||||||
hasFooter,
|
|
||||||
headerSlot,
|
|
||||||
subHeaderSlot,
|
|
||||||
motion,
|
|
||||||
footerContentAlign,
|
|
||||||
showCloseButton,
|
|
||||||
showFooterButton,
|
|
||||||
actionContentSlot,
|
|
||||||
headerVariant,
|
|
||||||
bodyPaddingVariant,
|
|
||||||
role,
|
|
||||||
ariaLabelledby,
|
|
||||||
ariaDescribedby,
|
|
||||||
dataFocusTrap,
|
|
||||||
bodySlot,
|
|
||||||
titleId,
|
|
||||||
descriptionId,
|
|
||||||
placementNarrow,
|
|
||||||
placementRegular
|
|
||||||
}) => {
|
|
||||||
|
|
||||||
// Default values
|
|
||||||
width = width ?? 'auto';
|
|
||||||
height = height ?? 'auto';
|
|
||||||
motion = motion ?? 'auto';
|
|
||||||
variant = variant ?? 'center';
|
|
||||||
variantWhenNarrow = variantWhenNarrow ?? 'inherit';
|
|
||||||
headerVariant = headerVariant ?? 'medium';
|
|
||||||
|
|
||||||
// Inherit values
|
|
||||||
variantWhenNarrow = variantWhenNarrow === 'inherit' ? variant : variantWhenNarrow;
|
|
||||||
|
|
||||||
// Leave `null` values for states that don't require a modifier class
|
|
||||||
headerVariant = headerVariant === 'medium' ? null : headerVariant;
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<button class="btn" onClick={toggleDialog}>
|
|
||||||
<span>Open overlay</span>
|
|
||||||
</button>
|
|
||||||
<div
|
|
||||||
id="overlay-backdrop"
|
|
||||||
className={clsx(
|
|
||||||
toggleOverlay && 'Overlay--hidden',
|
|
||||||
variant && `Overlay-backdrop--${variant}`,
|
|
||||||
variantWhenNarrow && `Overlay-backdrop--${variantWhenNarrow}-whenNarrow`,
|
|
||||||
placementRegular && `${placementRegular}`,
|
|
||||||
placementNarrow && `${placementNarrow}`,
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={clsx(
|
|
||||||
'Overlay',
|
|
||||||
width && `Overlay--width-${width}`,
|
|
||||||
height && `Overlay--height-${height}`,
|
|
||||||
motion && `Overlay--motion-${motion}`,
|
|
||||||
)}
|
|
||||||
data-focus-trap={dataFocusTrap}
|
|
||||||
role={role}
|
|
||||||
aria-labelledby={ariaLabelledby}
|
|
||||||
aria-describedby={ariaDescribedby}
|
|
||||||
open
|
|
||||||
>
|
|
||||||
{hasHeader && (
|
|
||||||
<header
|
|
||||||
className={clsx(
|
|
||||||
'Overlay-header',
|
|
||||||
showHeaderDivider && 'Overlay-header--divided',
|
|
||||||
headerVariant && `Overlay-header--${headerVariant}`
|
|
||||||
)}
|
|
||||||
aria-role="none"
|
|
||||||
>
|
|
||||||
<div className="Overlay-headerContentWrap">
|
|
||||||
<div className="Overlay-titleWrap">
|
|
||||||
{title && (
|
|
||||||
<h1 id={titleId} className="Overlay-title">
|
|
||||||
{title}
|
|
||||||
</h1>
|
|
||||||
)}
|
|
||||||
{description && (
|
|
||||||
<h2 id={descriptionId} className="Overlay-description">
|
|
||||||
{description}
|
|
||||||
</h2>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{headerVariant == 'custom' && headerSlot && (
|
|
||||||
<div className="Overlay-customHeader">
|
|
||||||
{headerSlot}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{showCloseButton && (
|
|
||||||
<div className="Overlay-actionWrap">
|
|
||||||
{actionContentSlot && <div dangerouslySetInnerHTML={{__html: actionContentSlot}} />}
|
|
||||||
<button className="Overlay-closeButton" aria-label="Close" onClick={toggleDialog}>
|
|
||||||
<svg aria-hidden="true" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
|
||||||
<path
|
|
||||||
fill-rule="evenodd"
|
|
||||||
d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{subHeaderSlot && (
|
|
||||||
<div className="Overlay-subHeader">
|
|
||||||
{subHeaderSlot}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</header>
|
|
||||||
)}
|
|
||||||
<div className={clsx('Overlay-body', bodyPaddingVariant && `${bodyPaddingVariant}`)}>{bodySlot}</div>
|
|
||||||
{hasFooter && (
|
|
||||||
<footer
|
|
||||||
className={clsx(
|
|
||||||
'Overlay-footer',
|
|
||||||
showFooterDivider && 'Overlay-footer--divided',
|
|
||||||
footerContentAlign && `${footerContentAlign}`
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{showFooterButton && (
|
|
||||||
<button class="btn" onClick={toggleDialog}>
|
|
||||||
<span>Continue</span>
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</footer>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Playground = OverlayTemplate.bind();
|
|
||||||
Playground.storyName = 'Playground';
|
|
||||||
Playground.args = {
|
|
||||||
title: 'This is the title of the dialog',
|
|
||||||
description: 'This is the subtitle of the dialog',
|
|
||||||
motion: 1,
|
|
||||||
footerContentAlign: 2,
|
|
||||||
showCloseButton: true,
|
|
||||||
showFooterButton: false,
|
|
||||||
headerSlot: '',
|
|
||||||
actionContentSlot: '',
|
|
||||||
headerVariant: 'medium',
|
|
||||||
bodyPaddingVariant: 0,
|
|
||||||
width: 'small',
|
|
||||||
height: 'small',
|
|
||||||
hasHeader: true,
|
|
||||||
hasFooter: true,
|
|
||||||
showFooterDivider: false,
|
|
||||||
showHeaderDivider: false,
|
|
||||||
role: '',
|
|
||||||
ariaDescribedby: '',
|
|
||||||
dataFocusTrap: '',
|
|
||||||
bodySlot: (
|
|
||||||
<>
|
|
||||||
<p>This is the body of the dialog</p>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Dialog = OverlayTemplate.bind();
|
|
||||||
Dialog.storyName = 'Dialog';
|
|
||||||
Dialog.args = {
|
|
||||||
variant: 'center',
|
|
||||||
|
|
||||||
// Header
|
|
||||||
hasHeader: true,
|
|
||||||
title: 'Dialog title',
|
|
||||||
description: 'This is the subtitle of the dialog',
|
|
||||||
|
|
||||||
// Properties
|
|
||||||
width: 'medium',
|
|
||||||
height: 'small',
|
|
||||||
motion: 'auto',
|
|
||||||
|
|
||||||
footerContentAlign: 2,
|
|
||||||
showCloseButton: true,
|
|
||||||
showFooterButton: false,
|
|
||||||
headerSlot: '',
|
|
||||||
actionContentSlot: '',
|
|
||||||
headerVariant: 'large',
|
|
||||||
bodyPaddingVariant: 0,
|
|
||||||
hasFooter: false,
|
|
||||||
showFooterDivider: false,
|
|
||||||
showHeaderDivider: false,
|
|
||||||
role: '',
|
|
||||||
ariaDescribedby: '',
|
|
||||||
dataFocusTrap: '',
|
|
||||||
bodySlot: (
|
|
||||||
<>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CustomHeader = OverlayTemplate.bind();
|
|
||||||
CustomHeader.storyName = 'Custom header';
|
|
||||||
CustomHeader.args = {
|
|
||||||
variant: 'center',
|
|
||||||
|
|
||||||
// Header
|
|
||||||
hasHeader: true,
|
|
||||||
title: 'Dialog title',
|
|
||||||
description: 'This is the subtitle of the dialog',
|
|
||||||
|
|
||||||
// Properties
|
|
||||||
width: 'medium',
|
|
||||||
height: 'small',
|
|
||||||
motion: 'auto',
|
|
||||||
|
|
||||||
// Header
|
|
||||||
headerVariant: 'custom',
|
|
||||||
headerSlot: (
|
|
||||||
<><div style={{background: 'pink', height: '32px', width: '100%'}}>Custom header</div></>
|
|
||||||
),
|
|
||||||
subHeaderSlot: (
|
|
||||||
<>UnderlineNav</>
|
|
||||||
),
|
|
||||||
|
|
||||||
footerContentAlign: 2,
|
|
||||||
showCloseButton: true,
|
|
||||||
showFooterButton: false,
|
|
||||||
actionContentSlot: '',
|
|
||||||
bodyPaddingVariant: 0,
|
|
||||||
hasFooter: false,
|
|
||||||
showFooterDivider: false,
|
|
||||||
showHeaderDivider: false,
|
|
||||||
role: '',
|
|
||||||
ariaDescribedby: '',
|
|
||||||
dataFocusTrap: '',
|
|
||||||
|
|
||||||
bodySlot: (
|
|
||||||
<>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
<div>Lorem ipsum dolor sit amet.</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
};
|
|
275
docs/src/stories/ui-patterns/Overlay/OverlayBase.stories.jsx
Normal file
275
docs/src/stories/ui-patterns/Overlay/OverlayBase.stories.jsx
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
import clsx from 'clsx'
|
||||||
|
import React from 'react'
|
||||||
|
import ConditionalWrapper from '../../helpers/ConditionalWrapper'
|
||||||
|
import {PatternFullBleed} from '../ActionList/ActionListFeatures.stories.jsx'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'UI Patterns/Overlay base',
|
||||||
|
parameters: {
|
||||||
|
layout: 'padded'
|
||||||
|
},
|
||||||
|
excludeStories: ['OverlayBaseTemplate'],
|
||||||
|
argTypes: {
|
||||||
|
|
||||||
|
// # backdrop
|
||||||
|
// # - visible
|
||||||
|
// # - transparent
|
||||||
|
// # - none
|
||||||
|
// # motion
|
||||||
|
// # - auto
|
||||||
|
// # - none
|
||||||
|
// # placement
|
||||||
|
// # - viewport
|
||||||
|
// # - top, left, right, bottom, full, center
|
||||||
|
// # - anchored
|
||||||
|
// # - [directions]
|
||||||
|
// # open/dismiss behavior
|
||||||
|
// # - open: boolean
|
||||||
|
// # - API client-side:
|
||||||
|
// # - open
|
||||||
|
// # - dismiss
|
||||||
|
// # sizing
|
||||||
|
// # - width: auto, xsmall, small, medium, large, xlarge, xxlarge
|
||||||
|
// # - height: auto, xsmall, small, medium, large, xlarge
|
||||||
|
|
||||||
|
// backdrop
|
||||||
|
backdrop: {
|
||||||
|
options: ['visible', 'transparent', 'none'],
|
||||||
|
control: {
|
||||||
|
type: 'inline-radio',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
placement: {
|
||||||
|
// Todo: fix placement options
|
||||||
|
options: ['top', 'left', 'right', 'bottom', 'full', 'center', 'anchor'],
|
||||||
|
control: {
|
||||||
|
type: 'inline-radio',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
motion: {
|
||||||
|
options: ['auto', 'none'],
|
||||||
|
control: {
|
||||||
|
type: 'inline-radio',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
options: ['auto', 'xsmall', 'small', 'medium', 'large', 'xlarge', 'xxlarge'],
|
||||||
|
control: {
|
||||||
|
type: 'select',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
options: ['auto', 'xsmall', 'small', 'medium', 'large', 'xlarge', 'xlarge'],
|
||||||
|
control: {
|
||||||
|
type: 'select',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
open: {
|
||||||
|
control: {
|
||||||
|
type: 'boolean',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// content
|
||||||
|
contentSlot: {
|
||||||
|
description: 'Slot for the overlay contents.',
|
||||||
|
control: {type: 'string'},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const focusOverlay = function getFocus() {
|
||||||
|
const overlay = document.querySelector('.Overlay');
|
||||||
|
overlay.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleOverlay = () => {
|
||||||
|
const overlay = document.querySelector('.Overlay');
|
||||||
|
overlay.classList.toggle('Overlay--open');
|
||||||
|
focusOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
export const OverlayBaseTemplate = ({
|
||||||
|
placement,
|
||||||
|
backdrop,
|
||||||
|
motion,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
open,
|
||||||
|
contentSlot
|
||||||
|
}) => {
|
||||||
|
|
||||||
|
// Default values
|
||||||
|
backdrop = backdrop ?? 'visible';
|
||||||
|
placement = placement ?? 'center';
|
||||||
|
width = width ?? 'auto';
|
||||||
|
height = height ?? 'auto';
|
||||||
|
motion = motion ?? 'auto';
|
||||||
|
|
||||||
|
// Inherit values
|
||||||
|
// variantWhenNarrow = variantWhenNarrow === 'inherit' ? variant : variantWhenNarrow;
|
||||||
|
|
||||||
|
// Leave `null` values for states that don't require a modifier class
|
||||||
|
// headerVariant = headerVariant === 'medium' ? null : headerVariant;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button class="btn" onClick={toggleOverlay}>
|
||||||
|
<span>Open overlay</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
'Overlay',
|
||||||
|
open && 'Overlay--open',
|
||||||
|
placement && `Overlay--${placement}`,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
'Overlay-wrapper',
|
||||||
|
)}
|
||||||
|
// data-focus-trap={dataFocusTrap}
|
||||||
|
// role={role}
|
||||||
|
// aria-labelledby={ariaLabelledby}
|
||||||
|
// aria-describedby={ariaDescribedby}
|
||||||
|
// open
|
||||||
|
>
|
||||||
|
<div className={clsx(
|
||||||
|
'Overlay-content',
|
||||||
|
width && `Overlay-content--width-${width}`,
|
||||||
|
height && `Overlay-content--height-${height}`,
|
||||||
|
motion && `Overlay-content--motion-${motion}`,
|
||||||
|
)}>
|
||||||
|
{contentSlot}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{backdrop !== 'none' && (
|
||||||
|
<div className={clsx(
|
||||||
|
'Overlay-backdrop',
|
||||||
|
backdrop && `Overlay-backdrop--${backdrop}`,
|
||||||
|
)}></div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Playground = OverlayBaseTemplate.bind();
|
||||||
|
Playground.storyName = 'Playground';
|
||||||
|
Playground.args = {
|
||||||
|
placement: 'viewport-top',
|
||||||
|
width: 'small',
|
||||||
|
height: 'small',
|
||||||
|
open: true,
|
||||||
|
// title: 'This is the title of the dialog',
|
||||||
|
// description: 'This is the subtitle of the dialog',
|
||||||
|
// motion: 1,
|
||||||
|
// footerContentAlign: 2,
|
||||||
|
// showCloseButton: true,
|
||||||
|
// showFooterButton: false,
|
||||||
|
// headerSlot: '',
|
||||||
|
// actionContentSlot: '',
|
||||||
|
// headerVariant: 'medium',
|
||||||
|
// bodyPaddingVariant: 0,
|
||||||
|
// hasHeader: true,
|
||||||
|
// hasFooter: true,
|
||||||
|
// showFooterDivider: false,
|
||||||
|
// showHeaderDivider: false,
|
||||||
|
// role: '',
|
||||||
|
// ariaDescribedby: '',
|
||||||
|
// dataFocusTrap: '',
|
||||||
|
contentSlot: (
|
||||||
|
<>
|
||||||
|
<p>This is the body of the dialog</p>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// export const Dialog = OverlayBaseTemplate.bind();
|
||||||
|
// Dialog.storyName = 'Dialog';
|
||||||
|
// Dialog.args = {
|
||||||
|
// /*
|
||||||
|
// variant: 'center',
|
||||||
|
|
||||||
|
// // Header
|
||||||
|
// hasHeader: true,
|
||||||
|
// title: 'Dialog title',
|
||||||
|
// description: 'This is the subtitle of the dialog',
|
||||||
|
|
||||||
|
// // Properties
|
||||||
|
// width: 'medium',
|
||||||
|
// height: 'small',
|
||||||
|
// motion: 'auto',
|
||||||
|
|
||||||
|
// footerContentAlign: 2,
|
||||||
|
// showCloseButton: true,
|
||||||
|
// showFooterButton: false,
|
||||||
|
// headerSlot: '',
|
||||||
|
// actionContentSlot: '',
|
||||||
|
// headerVariant: 'large',
|
||||||
|
// bodyPaddingVariant: 0,
|
||||||
|
// hasFooter: false,
|
||||||
|
// showFooterDivider: false,
|
||||||
|
// showHeaderDivider: false,
|
||||||
|
// role: '',
|
||||||
|
// ariaDescribedby: '',
|
||||||
|
// dataFocusTrap: '',
|
||||||
|
// */
|
||||||
|
// contentSlot: (
|
||||||
|
// <>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// </>
|
||||||
|
// )
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export const CustomHeader = OverlayBaseTemplate.bind();
|
||||||
|
// CustomHeader.storyName = 'Custom header';
|
||||||
|
// CustomHeader.args = {
|
||||||
|
// variant: 'center',
|
||||||
|
|
||||||
|
// // Header
|
||||||
|
// hasHeader: true,
|
||||||
|
// title: 'Dialog title',
|
||||||
|
// description: 'This is the subtitle of the dialog',
|
||||||
|
|
||||||
|
// // Properties
|
||||||
|
// width: 'medium',
|
||||||
|
// height: 'small',
|
||||||
|
// motion: 'auto',
|
||||||
|
|
||||||
|
// // Header
|
||||||
|
// headerVariant: 'custom',
|
||||||
|
// headerSlot: (
|
||||||
|
// <><div style={{background: 'pink', height: '32px', width: '100%'}}>Custom header</div></>
|
||||||
|
// ),
|
||||||
|
// subHeaderSlot: (
|
||||||
|
// <>UnderlineNav</>
|
||||||
|
// ),
|
||||||
|
|
||||||
|
// footerContentAlign: 2,
|
||||||
|
// showCloseButton: true,
|
||||||
|
// showFooterButton: false,
|
||||||
|
// actionContentSlot: '',
|
||||||
|
// bodyPaddingVariant: 0,
|
||||||
|
// hasFooter: false,
|
||||||
|
// showFooterDivider: false,
|
||||||
|
// showHeaderDivider: false,
|
||||||
|
// role: '',
|
||||||
|
// ariaDescribedby: '',
|
||||||
|
// dataFocusTrap: '',
|
||||||
|
|
||||||
|
// bodySlot: (
|
||||||
|
// <>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// <div>Lorem ipsum dolor sit amet.</div>
|
||||||
|
// </>
|
||||||
|
// )
|
||||||
|
// };
|
@ -1,2 +1,2 @@
|
|||||||
@import '../support/index.scss';
|
@import '../support/index.scss';
|
||||||
@import './overlay.scss';
|
@import './overlay-base.scss';
|
||||||
|
@ -23,40 +23,171 @@ $Overlay-height: (
|
|||||||
xlarge: 600px
|
xlarge: 600px
|
||||||
) !default;
|
) !default;
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
@mixin Overlay--fullViewportHeight() {
|
||||||
|
height: 100vh;
|
||||||
|
height: -webkit-fill-available;
|
||||||
|
max-height: 100vh;
|
||||||
|
|
||||||
|
@supports(height: 100dvh) {
|
||||||
|
height: 100dvh;
|
||||||
|
max-height: 100dvh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Overlay structure
|
// Overlay structure
|
||||||
// =================
|
// =================
|
||||||
//
|
//
|
||||||
// .Overlay-backdrop
|
// .Overlay
|
||||||
// ├─ .Overlay
|
// ├─ .Overlay-wrapper
|
||||||
// │ ├─ .Overlay-header
|
// │ │ ├─ .Overlay-content
|
||||||
// │ │ ├─ .Overlay-headerContentWrap
|
// ├─ .Overlay-backdrop
|
||||||
// │ │ │ ├─ .Overlay-titleWrap
|
|
||||||
// │ │ │ │ ├─ .Overlay-title
|
|
||||||
// │ │ │ │ ├─ .Overlay-description
|
|
||||||
// │ │ ├─ .Overlay-actionWrap
|
|
||||||
// │ │ │ ├─ .Overlay-closeButton
|
|
||||||
// │ ├─ .Overlay-body
|
|
||||||
// │ ├─ .Overlay-footer
|
|
||||||
//
|
|
||||||
// Todo:
|
|
||||||
// - Overlay-form?
|
|
||||||
// - Deprecate Overlay-closeButton in favor of redesigned iconButton
|
|
||||||
|
|
||||||
// Visibility
|
|
||||||
// Todo: these are applied to `Overlay-backdrop`, not to `Overlay`
|
|
||||||
|
|
||||||
.Overlay--hidden {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Overlay--visibilityHidden {
|
|
||||||
height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Overlay {
|
.Overlay {
|
||||||
|
isolation: isolate;
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
@include Overlay--fullViewportHeight;
|
||||||
|
}
|
||||||
|
.Overlay--open {
|
||||||
|
visibility: visible;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overlay-wrapper
|
||||||
|
|
||||||
|
.Overlay-wrapper {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay--anchor {
|
||||||
|
// Todo: anchored position
|
||||||
|
outline: 10px solid pink;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay--center {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay--full {
|
||||||
|
.Overlay-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.Overlay-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
border-radius: unset;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100vw;
|
||||||
|
|
||||||
|
@include Overlay--fullViewportHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay--top {
|
||||||
|
align-items: start;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.Overlay-content {
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
animation: $primer-duration-slow $primer-easing-out Overlay--motion-slideInDown;
|
||||||
|
}
|
||||||
|
border-radius: $primer-borderRadius-large;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay--left {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: left;
|
||||||
|
|
||||||
|
.Overlay-content {
|
||||||
|
border-radius: $primer-borderRadius-large;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
|
||||||
|
@include Overlay--fullViewportHeight;
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
animation: $primer-duration-slow $primer-easing-out Overlay--motion-slideInRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay--bottom {
|
||||||
|
align-items: end;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.Overlay-content {
|
||||||
|
border-radius: $primer-borderRadius-large;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
animation: $primer-duration-slow $primer-easing-out Overlay--motion-slideInUp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay--right {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: right;
|
||||||
|
|
||||||
|
.Overlay-content {
|
||||||
|
border-radius: $primer-borderRadius-large;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
|
||||||
|
@include Overlay--fullViewportHeight;
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
animation: $primer-duration-slow $primer-easing-out Overlay--motion-slideInLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overlay-backdrop
|
||||||
|
|
||||||
|
.Overlay-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
background-color: var(--color-neutral-muted);
|
||||||
|
|
||||||
|
@include Overlay--fullViewportHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-backdrop--transparent {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// .Overlay--hidden {
|
||||||
|
// display: none !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Question: what's visibilityHidden used for?
|
||||||
|
// .Overlay--visibilityHidden {
|
||||||
|
// height: 0;
|
||||||
|
// overflow: hidden;
|
||||||
|
// visibility: hidden;
|
||||||
|
// opacity: 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Overlay-content
|
||||||
|
|
||||||
|
.Overlay-content {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
min-width: #{map-get($Overlay-width, 'xsmall')};
|
min-width: #{map-get($Overlay-width, 'xsmall')};
|
||||||
@ -70,88 +201,95 @@ $Overlay-height: (
|
|||||||
@supports (height: 100dvh) {
|
@supports (height: 100dvh) {
|
||||||
max-height: 100dvh;
|
max-height: 100dvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dimensions
|
|
||||||
// Todo: auto-generate based on Scss variables?
|
|
||||||
|
|
||||||
&.Overlay--height-auto {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--height-xsmall {
|
|
||||||
height: min(#{map-get($Overlay-height, 'xsmall')}, 100vh - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--height-small {
|
|
||||||
height: min(#{map-get($Overlay-height, 'small')}, 100vh - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--height-medium {
|
|
||||||
height: min(#{map-get($Overlay-height, 'medium')}, 100vh - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--height-large {
|
|
||||||
height: min(#{map-get($Overlay-height, 'large')}, 100vh - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--height-xlarge {
|
|
||||||
height: min(#{map-get($Overlay-height, 'xlarge')}, 100vh - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--width-auto {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--width-xsmall {
|
|
||||||
width: min(#{map-get($Overlay-width, 'xsmall')}, 100vw - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--width-small {
|
|
||||||
width: min(#{map-get($Overlay-width, 'small')}, 100vw - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--width-medium {
|
|
||||||
width: min(#{map-get($Overlay-width, 'medium')}, 100vw - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--width-large {
|
|
||||||
// stylelint-disable-next-line primer/responsive-widths
|
|
||||||
width: min(#{map-get($Overlay-width, 'large')}, 100vw - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--width-xlarge {
|
|
||||||
// stylelint-disable-next-line primer/responsive-widths
|
|
||||||
width: min(#{map-get($Overlay-width, 'xlarge')}, 100vw - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.Overlay--width-xxlarge {
|
|
||||||
// stylelint-disable-next-line primer/responsive-widths
|
|
||||||
width: min(#{map-get($Overlay-width, 'xxlarge')}, 100vw - 2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Motion
|
|
||||||
|
|
||||||
&.Overlay--motion-scaleFade {
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
// Todo: replace with primer-duration-slow token
|
|
||||||
animation: $primer-duration-slow $primer-easing-out Overlay--motion-scaleFade;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// &.Overlay--motion-slide {
|
|
||||||
// @media (prefers-reduced-motion: no-preference) {
|
|
||||||
// animation: $primer-duration-slow $primer-easing-out Overlay--motion-slide;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dimensions
|
||||||
|
|
||||||
|
.Overlay-content--height-auto {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--height-xsmall {
|
||||||
|
height: min(#{map-get($Overlay-height, 'xsmall')}, 100vh - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--height-small {
|
||||||
|
height: min(#{map-get($Overlay-height, 'small')}, 100vh - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--height-medium {
|
||||||
|
height: min(#{map-get($Overlay-height, 'medium')}, 100vh - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--height-large {
|
||||||
|
height: min(#{map-get($Overlay-height, 'large')}, 100vh - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--height-xlarge {
|
||||||
|
height: min(#{map-get($Overlay-height, 'xlarge')}, 100vh - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--width-auto {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--width-xsmall {
|
||||||
|
width: min(#{map-get($Overlay-width, 'xsmall')}, 100vw - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--width-small {
|
||||||
|
width: min(#{map-get($Overlay-width, 'small')}, 100vw - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--width-medium {
|
||||||
|
width: min(#{map-get($Overlay-width, 'medium')}, 100vw - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--width-large {
|
||||||
|
// stylelint-disable-next-line primer/responsive-widths
|
||||||
|
width: min(#{map-get($Overlay-width, 'large')}, 100vw - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--width-xlarge {
|
||||||
|
// stylelint-disable-next-line primer/responsive-widths
|
||||||
|
width: min(#{map-get($Overlay-width, 'xlarge')}, 100vw - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay-content--width-xxlarge {
|
||||||
|
// stylelint-disable-next-line primer/responsive-widths
|
||||||
|
width: min(#{map-get($Overlay-width, 'xxlarge')}, 100vw - 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Motion
|
||||||
|
|
||||||
|
.Overlay--motion-auto {
|
||||||
|
// Todo: Apply animation to Overlay-wrapper?
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
// Todo: replace with primer-duration-slow token
|
||||||
|
animation: $primer-duration-slow $primer-easing-out Overlay--motion-scaleFade;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Overlay--motion-none {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// &.Overlay--motion-slide {
|
||||||
|
// @media (prefers-reduced-motion: no-preference) {
|
||||||
|
// animation: $primer-duration-slow $primer-easing-out Overlay--motion-slide;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// for <form> element that wraps entire contents of overlay
|
// for <form> element that wraps entire contents of overlay
|
||||||
.Overlay-form {
|
// .Overlay-form {
|
||||||
display: flex;
|
// display: flex;
|
||||||
overflow: auto;
|
// overflow: auto;
|
||||||
flex-direction: column;
|
// flex-direction: column;
|
||||||
flex-grow: 1;
|
// flex-grow: 1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
// Move overlay header to specialized dialog component?
|
||||||
|
|
||||||
.Overlay-header {
|
.Overlay-header {
|
||||||
z-index: 1;
|
z-index: 1;
|
Loading…
Reference in New Issue
Block a user