Skip to content
Open
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
6 changes: 4 additions & 2 deletions .specs/drawer.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ category: overlay
structure: composition
status: implemented
spec_version: 1
checksum: f236ede5538b80ceac858f16528e77b92cd84a979dee3ab640435575e0f426ba
checksum: 380c8b7121907e3ac77be9b9ed690401b7bd0b22654667bee8ac6085948b5381
created: 2026-05-22
last_updated: 2026-05-22
last_updated: 2026-05-29
---
# Drawer — Component Spec

Expand Down Expand Up @@ -84,6 +84,8 @@ _none_
## Stories (Storybook)

- Default
- Sizes
- ScrollContent — long `PanelContent` scrolls inside `ScrollArea`; header and footer stay in the panel flex layout (not sticky).

## Constraints — DO NOT

Expand Down
4 changes: 2 additions & 2 deletions .specs/panel.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ category: overlay
structure: composition
status: implemented
spec_version: 1
checksum: 45b27b09631c3ef06a0ac19b2a264aedbf06dc86dda5be9181d9eff32014280b
checksum: 015f8188bde283cbb6e84bdd8639c3b1bea1ea95339d06bc1c518b42c7325f5f
created: 2026-05-22
last_updated: 2026-05-22
last_updated: 2026-05-29
---
# Panel — Component Spec

Expand Down
133 changes: 87 additions & 46 deletions apps/storybook/src/stories/webkit/overlay/Dialog.stories.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { ref } from 'vue'

import Button from '@aziontech/webkit/button'
import Dialog from '@aziontech/webkit/overlay/dialog'
import DialogClose from '@aziontech/webkit/overlay/dialog-close'
Expand All @@ -12,10 +10,27 @@ import DialogTrigger from '@aziontech/webkit/overlay/dialog-trigger'
import PanelContent from '@aziontech/webkit/overlay/panel-content'
import PanelFooter from '@aziontech/webkit/overlay/panel-footer'
import PanelHeader from '@aziontech/webkit/overlay/panel-header'
import { ref } from 'vue'

const sizes = ['small', 'medium', 'large']

export default {
const dialogStoryComponents = {
Dialog,
DialogTrigger,
DialogPortal,
DialogOverlay,
DialogContent,
DialogTitle,
DialogDescription,
DialogClose,
PanelHeader,
PanelContent,
PanelFooter,
Button
}

/** @type {import('@storybook/vue3').Meta<typeof Dialog>} */
const meta = {
title: 'Webkit/Overlay/Dialog',
component: Dialog,
subcomponents: {
Expand All @@ -34,16 +49,62 @@ export default {
parameters: {
layout: 'fullscreen',
backgrounds: { default: 'dark' },
actions: { argTypesRegex: '^on[A-Z].*' },
a11y: {
config: {
rules: [{ id: 'color-contrast', enabled: true }]
}
},
docs: {
description: {
component:
'Modal dialog built on the shared Panel shell. Figma Webkit Panel (node 482:935). Supports overlay backdrop, closeable behavior, and theme motion tokens (panel scale 0.98 → 1 + opacity fade, overlay fade).'
component: [
'Modal dialog built on the shared Panel shell. Supports overlay backdrop, closeable behavior, and theme motion tokens (panel scale + opacity fade, overlay fade).',
'',
'## Usage',
'',
'```vue',
'<script setup>',
"import { ref } from 'vue'",
"import Button from '@aziontech/webkit/button'",
"import Dialog from '@aziontech/webkit/overlay/dialog'",
"import DialogClose from '@aziontech/webkit/overlay/dialog-close'",
"import DialogContent from '@aziontech/webkit/overlay/dialog-content'",
"import DialogDescription from '@aziontech/webkit/overlay/dialog-description'",
"import DialogOverlay from '@aziontech/webkit/overlay/dialog-overlay'",
"import DialogPortal from '@aziontech/webkit/overlay/dialog-portal'",
"import DialogTitle from '@aziontech/webkit/overlay/dialog-title'",
"import DialogTrigger from '@aziontech/webkit/overlay/dialog-trigger'",
"import PanelContent from '@aziontech/webkit/overlay/panel-content'",
"import PanelFooter from '@aziontech/webkit/overlay/panel-footer'",
"import PanelHeader from '@aziontech/webkit/overlay/panel-header'",
'',
'const open = ref(false)',
'</script>',
'',
'<template>',
' <Dialog v-model:open="open" closeable size="medium">',
' <DialogTrigger>',
' <Button label="Open dialog" kind="primary" />',
' </DialogTrigger>',
' <DialogPortal>',
' <DialogOverlay />',
' <DialogContent>',
' <PanelHeader class="w-full">',
' <DialogTitle>Dialog Title</DialogTitle>',
' <DialogClose />',
' </PanelHeader>',
' <PanelContent>',
' <DialogDescription>Modal content.</DialogDescription>',
' </PanelContent>',
' <PanelFooter class="flex-col md:flex-row md:justify-end">',
' <Button class="w-full md:w-auto" label="Cancel" kind="outlined" @click="open = false" />',
' <Button class="w-full md:w-auto" label="Save" kind="primary" />',
' </PanelFooter>',
' </DialogContent>',
' </DialogPortal>',
' </Dialog>',
'</template>',
'```'
].join('\n')
}
}
},
Expand Down Expand Up @@ -83,63 +144,43 @@ export default {
}
}

const alertDialogTemplate = `
export default meta

const dialogTemplate = `
<Dialog v-bind="args" v-model:open="open">
<DialogTrigger>
<Button label="Open alert" kind="primary" />
<Button label="Open dialog" kind="primary" />
</DialogTrigger>
<DialogPortal>
<DialogOverlay />
<DialogContent>
<PanelContent class="p-0">
<div class="flex w-full flex-col">
<div
class="flex items-start gap-[var(--spacing-4)] px-[var(--spacing-6)] py-[var(--spacing-6)]"
>
<div class="flex min-w-0 flex-1 flex-col gap-[var(--spacing-2)]">
<DialogTitle>Cancel Scheduled Downgrade</DialogTitle>
<DialogDescription>
Confirm to remove the scheduled downgrade. Your current plan will continue without changes.
</DialogDescription>
</div>
<DialogClose class="shrink-0" />
</div>
<div
class="flex flex-col gap-[var(--spacing-3)] border-t border-[length:var(--border-width-default)] border-[var(--border-muted)] px-[var(--spacing-6)] py-[var(--spacing-4)] md:flex-row md:justify-end"
>
<Button class="w-full md:w-auto" label="Cancel" size="medium" kind="outlined" @click="open = false" />
<Button class="w-full md:w-auto" kind="secondary" size="medium" label="Keep current plan" @click="open = false" />
</div>
</div>
<PanelHeader class="w-full">
<DialogTitle>Dialog Title</DialogTitle>
<DialogClose />
</PanelHeader>
<PanelContent>
<DialogDescription>
Modal content. Uses the shared Panel header, body, and footer regions.
</DialogDescription>
</PanelContent>
<PanelFooter class="flex-col md:flex-row md:justify-end">
<Button class="w-full md:w-auto" label="Cancel" kind="outlined" @click="open = false" />
<Button class="w-full md:w-auto" label="Save" kind="primary" />
</PanelFooter>
</DialogContent>
</DialogPortal>
</Dialog>
`

/** @type {import('@storybook/vue3').StoryObj<typeof Dialog>} */
export const Default = {
args: {
defaultOpen: false,
closeable: true,
size: 'small'
},
render: (args) => ({
components: {
Dialog,
DialogTrigger,
DialogPortal,
DialogOverlay,
DialogContent,
DialogTitle,
DialogDescription,
DialogClose,
PanelContent,
Button
},
components: dialogStoryComponents,
setup() {
const open = ref(args.defaultOpen)

return { args, open }
},
template: alertDialogTemplate
template: dialogTemplate
})
}
Loading
Loading