Skip to content
Draft
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
96 changes: 96 additions & 0 deletions pages/drawer/drawer-position-absolute.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import React, { useContext } from 'react';
import { capitalize, range } from 'lodash';

import { FormField, Input } from '~components';
import Drawer, { NextDrawerProps as DrawerProps } from '~components/drawer/next';

import AppContext, { AppContextType } from '../app/app-context';
import { SimplePage } from '../app/templates';

const accentColor = '#6237a7';
const overlayFontColor = '#ffffff';

type PageContext = React.Context<
AppContextType<{
overlayZIndex?: number;
}>
>;

export default function () {
const {
urlParams: { overlayZIndex = 1 },
setUrlParams,
} = useContext(AppContext as PageContext);
return (
<SimplePage
title="Drawer position: absolute"
subtitle="This page demonstrates drawers with absolute position."
i18n={{}}
screenshotArea={{}}
settings={
<FormField label="Overlay z-index">
<Input
type="number"
value={overlayZIndex.toString()}
onChange={({ detail }) => setUrlParams({ overlayZIndex: parseInt(detail.value) })}
/>
</FormField>
}
>
<div style={{ border: `1px solid ${accentColor}`, position: 'relative' }}>
<div style={{ flex: 1, padding: 16 }}>
{range(0, 50).map(i => (
<div key={i}>Line {i + 1}</div>
))}
</div>
<CustomOverlay zIndex={overlayZIndex}>Custom overlay with zIndex={overlayZIndex}</CustomOverlay>
<AbsoluteDrawer placement="top" offset={{ start: 200, end: 200 }} zIndex={1} contentHeight={200} />
<AbsoluteDrawer placement="start" offset={{ bottom: 200 }} zIndex={2} contentWidth={200} />
<AbsoluteDrawer placement="end" offset={{ bottom: 200 }} zIndex={3} contentWidth={200} />
<AbsoluteDrawer placement="bottom" offset={{}} zIndex={4} contentHeight={200} />
<AbsoluteDrawer placement="bottom" offset={{}} zIndex={5} contentHeight={150} />
</div>
</SimplePage>
);
}

function AbsoluteDrawer({
placement,
offset,
zIndex,
contentWidth,
contentHeight,
}: DrawerProps & { contentWidth?: number; contentHeight?: number }) {
const sizeStr = contentHeight ? `height=${contentHeight}px` : `width=${contentWidth}px`;
const formatOffset = (offset?: DrawerProps.Offset) => JSON.stringify(offset, null, 2).replace(/"/g, '');
return (
<Drawer position="absolute" placement={placement} disableContentPaddings={true} offset={offset} zIndex={zIndex}>
<div style={{ boxSizing: 'border-box', padding: 16, width: contentWidth, height: contentHeight }}>
{capitalize(placement)} drawer with content {sizeStr}, {`offset=${formatOffset(offset)}`}, and zIndex={zIndex}
</div>
</Drawer>
);
}

function CustomOverlay({ zIndex, children }: { zIndex?: number; children: React.ReactNode }) {
return (
<div
style={{
position: 'absolute',
inset: 0,
background: accentColor,
color: overlayFontColor,
opacity: 0.85,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex,
}}
>
{children}
</div>
);
}
125 changes: 125 additions & 0 deletions pages/drawer/drawer-position-static.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import React, { useContext } from 'react';

import { Box, Button, ColumnLayout, SpaceBetween, Tabs } from '~components';
import Drawer, { NextDrawerProps as DrawerProps } from '~components/drawer/next';

import AppContext, { AppContextType } from '../app/app-context';
import { SimplePage } from '../app/templates';

const accentColor = '#6237a7';

type PageContext = React.Context<
AppContextType<{
tabId?: string;
}>
>;

function createTab(label: string, content: React.ReactNode) {
return { id: label, label, content };
}

export default function () {
const {
urlParams: { tabId = 'Features' },
setUrlParams,
} = useContext(AppContext as PageContext);
return (
<SimplePage
title="Drawer position: static"
subtitle="This page demonstrates drawers with static (default) position."
i18n={{}}
screenshotArea={{}}
>
<Tabs
activeTabId={tabId}
onChange={({ detail }) => setUrlParams({ tabId: detail.activeTabId })}
tabs={[createTab('Features', <DrawerFeaturesTab />), createTab('Custom placement', <CustomPlacementTab />)]}
/>
</SimplePage>
);
}

function DrawerFeaturesTab() {
return (
<SpaceBetween size="s">
<Box>Note: all examples in this tab use a custom wrapper around the drawer to render visible borders.</Box>
<hr />
<ColumnLayout columns={2}>
<Box variant="p">Drawer with content and disabled content paddings.</Box>
<DrawerWithBorder disableContentPaddings={true}>
<SpaceBetween size="m">
<Box>Content line 1</Box>
<Box>Content line 2</Box>
<Box>Content line 3</Box>
</SpaceBetween>
</DrawerWithBorder>

<Box variant="p">Drawer with header, content, and footer.</Box>
<DrawerWithBorder header="Header" footer="Footer">
Content
</DrawerWithBorder>

<SpaceBetween size="xs">
<Box variant="p">Drawer with header actions.</Box>
<Box variant="p">
By default, there is a reserved space next to header actions where an externally-provided close action can
be rendered (using absolute positioning).
</Box>
</SpaceBetween>
<DrawerWithBorder header="Header" headerActions={<Button>Action</Button>}>
Content
</DrawerWithBorder>
</ColumnLayout>
</SpaceBetween>
);
}

function CustomPlacementTab() {
return (
<SpaceBetween size="s">
<Box>
Statically positioned drawers can be arranged into custom layouts and wrapped into elements with absolute,
sticky, or fixed position. In that case, the drawer borders are rendered by the consumers.
</Box>
<hr />
<ColumnLayout columns={2}>
<Box variant="p">Static drawers around content with custom flex layout.</Box>
<div style={{ border: `2px solid ${accentColor}` }}>
<div style={{ display: 'flex' }}>
<div style={{ border: `2px solid ${accentColor}`, margin: `-2px 0 -2px -2px` }}>
<Drawer header="Left">Left content</Drawer>
</div>
<div style={{ flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
Container content
</div>
<div style={{ border: `2px solid ${accentColor}`, margin: '-2px -2px -2px 0' }}>
<Drawer header="Right">Right content</Drawer>
</div>
</div>
<div style={{ border: `2px solid ${accentColor}`, margin: '0 -2px -2px -2px' }}>
<Drawer header="Bottom">Bottom content</Drawer>
</div>
</div>

<Box variant="p">Custom sticky drawer at the bottom.</Box>
<div style={{ border: `2px solid ${accentColor}` }}>
<div style={{ height: 300, padding: 16 }}>Container content</div>
<div style={{ borderTop: `2px solid ${accentColor}`, position: 'sticky', bottom: 0 }}>
<Drawer header="Drawer">I am a static drawer inside a sticky wrapper.</Drawer>
</div>
</div>
</ColumnLayout>
</SpaceBetween>
);
}

function DrawerWithBorder(props: DrawerProps) {
return (
<div style={{ padding: 2, background: accentColor }}>
<Drawer {...props} />
</div>
);
}
63 changes: 63 additions & 0 deletions pages/drawer/drawer-position-sticky.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import React, { useContext } from 'react';
import { range } from 'lodash';

import { Box, Checkbox, SpaceBetween } from '~components';
import Drawer from '~components/drawer/next';

import AppContext, { AppContextType } from '../app/app-context';
import { SimplePage } from '../app/templates';

const accentColor = '#6237a7';

type PageContext = React.Context<
AppContextType<{
offsets?: boolean;
stickyOffsets?: boolean;
}>
>;

export default function () {
const {
urlParams: { offsets = false, stickyOffsets = false },
setUrlParams,
} = useContext(AppContext as PageContext);
const offset = offsets ? { start: 50, end: 50, top: 20, bottom: 20 } : undefined;
const stickyOffset = stickyOffsets ? { top: 50, bottom: 50 } : undefined;
const offsetProps = { offset, stickyOffset };
return (
<SimplePage
title="Drawer position: sticky"
subtitle="This page demonstrates drawers with sticky position. Drawers in sticky position only support top and bottom placements."
i18n={{}}
screenshotArea={{}}
settings={
<SpaceBetween size="s">
<Checkbox checked={offsets} onChange={({ detail }) => setUrlParams({ offsets: detail.checked })}>
Use offsets {offset && <Box variant="awsui-inline-code">{JSON.stringify(offset, null, 2)}</Box>}
</Checkbox>
<Checkbox checked={stickyOffsets} onChange={({ detail }) => setUrlParams({ stickyOffsets: detail.checked })}>
Use sticky offsets{' '}
{stickyOffset && <Box variant="awsui-inline-code">{JSON.stringify(stickyOffset, null, 2)}</Box>}
</Checkbox>
</SpaceBetween>
}
>
<div style={{ border: `1px solid ${accentColor}` }}>
<Drawer header="Sticky top drawer" footer="Footer" position="sticky" placement="top" {...offsetProps}>
Content
</Drawer>
<div style={{ flex: 1, padding: 16 }}>
{range(0, 100).map(i => (
<div key={i}>Line {i + 1}</div>
))}
</div>
<Drawer header="Sticky bottom drawer" footer="Footer" position="sticky" placement="bottom" {...offsetProps}>
Content
</Drawer>
</div>
</SimplePage>
);
}
101 changes: 101 additions & 0 deletions pages/drawer/drawer-position-viewport.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import React, { useContext } from 'react';
import { capitalize, range } from 'lodash';

import { Box, Checkbox, Select, SpaceBetween } from '~components';
import Drawer, { NextDrawerProps as DrawerProps } from '~components/drawer/next';
import { colorBackgroundCellShaded as contentBackgroundColor } from '~design-tokens';

import AppContext, { AppContextType } from '../app/app-context';
import { SimplePage } from '../app/templates';

const accentColor = '#6237a7';
const overlayFontColor = '#ffffff';

type PageContext = React.Context<
AppContextType<{
offsets?: boolean;
customOverlay?: boolean;
placement?: DrawerProps.Placement;
}>
>;

const placementOptions = [{ value: 'top' }, { value: 'bottom' }, { value: 'start' }, { value: 'end' }];

export default function () {
const {
urlParams: { offsets = false, customOverlay = false, placement = 'bottom' },
setUrlParams,
} = useContext(AppContext as PageContext);
const offset = offsets ? { start: 50, end: 50, top: 50, bottom: 50 } : {};
return (
<SimplePage
title="Drawer position: viewport"
subtitle="This page demonstrates drawers with viewport (fixed) position."
i18n={{}}
screenshotArea={{}}
>
<div>
{range(0, 50).map(i => (
<div key={i}>Line {i + 1}</div>
))}
</div>

{customOverlay && <CustomOverlay>Custom fixed overlay</CustomOverlay>}

<ViewportDrawer placement={placement} disableContentPaddings={true} offset={offset}>
<Checkbox checked={offsets} onChange={({ detail }) => setUrlParams({ offsets: detail.checked })}>
Use offsets
</Checkbox>
<Checkbox checked={customOverlay} onChange={({ detail }) => setUrlParams({ customOverlay: detail.checked })}>
Show custom overlay
</Checkbox>
<Select
inlineLabelText="Placement"
options={placementOptions}
selectedOption={placementOptions.find(o => o.value === placement) ?? null}
onChange={({ detail }) => setUrlParams({ placement: detail.selectedOption.value as DrawerProps.Placement })}
/>
</ViewportDrawer>
</SimplePage>
);
}

function ViewportDrawer({ placement, offset, zIndex, children }: DrawerProps) {
const formatOffset = (offset?: DrawerProps.Offset) => JSON.stringify(offset, null, 2).replace(/"/g, '');
return (
<Drawer position="viewport" placement={placement} disableContentPaddings={true} offset={offset} zIndex={zIndex}>
<div
style={{ boxSizing: 'border-box', padding: 16, width: 300, height: 300, background: contentBackgroundColor }}
>
<SpaceBetween size="xs">
<Box>
{capitalize(placement)} drawer with 300px/300px content and {`offset=${formatOffset(offset)}`}
</Box>
{children}
</SpaceBetween>
</div>
</Drawer>
);
}

function CustomOverlay({ children }: { children: React.ReactNode }) {
return (
<div
style={{
position: 'fixed',
inset: 0,
background: accentColor,
color: overlayFontColor,
opacity: 0.85,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
{children}
</div>
);
}
Loading
Loading