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
3 changes: 3 additions & 0 deletions build-tools/utils/custom-css-properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ const customCssPropertiesList = [
'stackedNotificationsDefaultBottomMargin',
// Dropdown Custom Properties
'dropdownDefaultMaxWidth',
// Modal Custom Properties
'modalCustomWidth',
'modalCustomHeight',
// Spinner Custom Properties
'spinnerRotatorFrom',
'spinnerRotatorTo',
Expand Down
149 changes: 149 additions & 0 deletions pages/modal/playground.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useState } from 'react';

import Box from '~components/box';
import Button from '~components/button';
import Checkbox from '~components/checkbox';
import FormField from '~components/form-field';
import Input from '~components/input';
import Modal from '~components/modal';
import Select from '~components/select';
import SpaceBetween from '~components/space-between';

export default function ModalPlayground() {
const [visible, setVisible] = useState(false);
const [size, setSize] = useState<'small' | 'medium' | 'large' | 'x-large' | 'xx-large' | 'max'>('medium');
const [position, setPosition] = useState<'center' | 'top'>('center');
const [width, setWidth] = useState('');
const [height, setHeight] = useState('');
const [disableContentPaddings, setDisableContentPaddings] = useState(false);
const [contentLines, setContentLines] = useState(10);
const [hasFooter, setHasFooter] = useState(true);
const [headerText, setHeaderText] = useState('Modal Playground');
const [closeAriaLabel, setCloseAriaLabel] = useState('');

return (
<Box padding="l">
<SpaceBetween size="l">
<h1>Modal Playground</h1>

<SpaceBetween size="m">
<FormField label="Size">
<Select
selectedOption={{ value: size }}
onChange={({ detail }) => setSize(detail.selectedOption.value as any)}
options={[
{ value: 'small', label: 'small' },
{ value: 'medium', label: 'medium' },
{ value: 'large', label: 'large' },
{ value: 'x-large', label: 'X-Large' },
{ value: 'xx-large', label: 'XX-Large' },
{ value: 'max', label: 'max' },
]}
/>
</FormField>

<FormField label="Position">
<Select
selectedOption={{ value: position }}
onChange={({ detail }) => setPosition(detail.selectedOption.value as any)}
options={[
{ value: 'center', label: 'Center' },
{ value: 'top', label: 'Top' },
]}
/>
</FormField>

<FormField label="Header Text">
<Input value={headerText} onChange={({ detail }) => setHeaderText(detail.value)} />
</FormField>

<FormField label="Close Aria Label">
<Input
value={closeAriaLabel}
onChange={({ detail }) => setCloseAriaLabel(detail.value)}
placeholder="Default: Close modal"
/>
</FormField>

<FormField label="Custom Width (px)">
<Input
value={width}
onChange={({ detail }) => setWidth(detail.value)}
placeholder="Leave empty for default"
type="number"
/>
</FormField>

<FormField label="Custom Height (px)">
<Input
value={height}
onChange={({ detail }) => setHeight(detail.value)}
placeholder="Leave empty for default"
type="number"
/>
</FormField>

<FormField label="Content Lines">
<Input
value={String(contentLines)}
onChange={({ detail }) => setContentLines(Number(detail.value) || 10)}
type="number"
/>
</FormField>

<Checkbox
checked={disableContentPaddings}
onChange={({ detail }) => setDisableContentPaddings(detail.checked)}
>
Disable content paddings
</Checkbox>

<Checkbox checked={hasFooter} onChange={({ detail }) => setHasFooter(detail.checked)}>
Show footer
</Checkbox>

<Button variant="primary" onClick={() => setVisible(true)}>
Open Modal
</Button>
</SpaceBetween>

<Modal
visible={visible}
onDismiss={() => setVisible(false)}
size={size}
position={position}
width={width ? Number(width) : undefined}
height={height ? Number(height) : undefined}
disableContentPaddings={disableContentPaddings}
closeAriaLabel={closeAriaLabel || undefined}
header={headerText}
footer={
hasFooter ? (
<Box float="right">
<SpaceBetween direction="horizontal" size="xs">
<Button variant="link" onClick={() => setVisible(false)}>
Cancel
</Button>
<Button variant="primary" onClick={() => setVisible(false)}>
Confirm
</Button>
</SpaceBetween>
</Box>
) : undefined
}
>
<SpaceBetween size="m">
{Array.from({ length: contentLines }, (_, i) => (
<Box key={i}>
Line {i + 1}: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.
</Box>
))}
</SpaceBetween>
</Modal>
</SpaceBetween>
</Box>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17503,6 +17503,13 @@ The function will be called when a user clicks on the trigger button.",
"optional": true,
"type": "((options: { abortSignal: AbortSignal; }) => Promise<HTMLElement>)",
},
{
"description": "Specifies the height of the modal. When provided, the modal content becomes scrollable if it exceeds the specified height.
If the specified height exceeds available viewport space, the modal will use the maximum available space.",
"name": "height",
"optional": true,
"type": "number",
},
{
"deprecatedTag": "The usage of the \`id\` attribute is reserved for internal use cases. For testing and other use cases,
use [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes). If you must
Expand All @@ -17520,6 +17527,28 @@ render to an element under \`document.body\`.",
"optional": true,
"type": "HTMLElement",
},
{
"defaultValue": "'center'",
"description": "Controls the vertical positioning of the modal.

- \`center\` (default) - Modal is vertically centered in viewport and re-centers
when content height changes. Use for dialogs with static, predictable content.

- \`top\` - Modal anchors at fixed distance and grows downward
as content expands. Use when content changes dynamically to prevent disruptive
vertical repositioning that causes users to lose focus.",
"inlineType": {
"name": "ModalProps.Position",
"type": "union",
"values": [
"center",
"top",
],
},
"name": "position",
"optional": true,
"type": "string",
},
{
"description": "Use this property when \`getModalRoot\` is used to clean up the modal root
element after a user closes the dialog. The function receives the return value
Expand All @@ -17542,8 +17571,8 @@ of the most recent getModalRoot call as an argument.",
{
"defaultValue": "'medium'",
"description": "Sets the width of the modal. \`max\` uses variable width up to the
largest size allowed by the design guidelines. Other sizes
(\`small\`/\`medium\`/\`large\`) have fixed widths.",
largest size allowed by the design guidelines. Other sizes:
\`small\` (320px), \`medium\` (600px), \`large\` (820px), \`x-large\` (1024px), \`xx-large\` (1280px).",
"inlineType": {
"name": "ModalProps.Size",
"type": "union",
Expand All @@ -17552,6 +17581,8 @@ largest size allowed by the design guidelines. Other sizes
"max",
"medium",
"large",
"x-large",
"xx-large",
],
},
"name": "size",
Expand All @@ -17565,6 +17596,13 @@ Set this property to \`true\` to show them.",
"optional": false,
"type": "boolean",
},
{
"description": "Specifies the width of the modal. When provided, takes precedence over the \`size\` property.
If the specified width exceeds available viewport space, the modal will use the maximum available space.",
"name": "width",
"optional": true,
"type": "number",
},
],
"regions": [
{
Expand Down
Loading
Loading