Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
90d5b38
dbeaver/pro#5232 feat: add Dialog component to UI-kit
SychevAndrey Dec 1, 2025
716929d
dbeaver/pro#5232 feat: add slide variant for Dialog component
SychevAndrey Dec 1, 2025
31e47e2
dbeaver/pro#5232 refactor: dialog backdrop component
SychevAndrey Dec 1, 2025
7dbeaf0
dbeaver/pro#5232 feat: use dialog component for side panel to prevent…
SychevAndrey Dec 2, 2025
401e189
dbeaver/pro#5232 feat: add DialogHeader, DialogBody, and DialogFooter…
SychevAndrey Dec 2, 2025
b31f246
dbeaver/pro#5232 feat: add Storysource addon to Storybook configuration
SychevAndrey Dec 2, 2025
c1d6027
dbeaver/pro#5232 refactor: use ui-kit dialog for CommonDialog impleme…
SychevAndrey Dec 2, 2025
ad889f7
dbeaver/pro#5232 feat: add animated prop to Dialog component to contr…
SychevAndrey Dec 2, 2025
3375f0a
dbeaver/pro#5232 refactor: remove dialog animation for side panel
SychevAndrey Dec 2, 2025
5303196
dbeaver/pro#5232 refactor: remove unused backdrop and focus managemen…
SychevAndrey Dec 2, 2025
b0f889e
dbeaver/pro#5232 style: adjust dialog padding and size for large variant
SychevAndrey Dec 2, 2025
cefd346
dbeaver/pro#5232 feat: add dialog to admin part implementation
SychevAndrey Dec 3, 2025
6f393cc
dbeaver/pro#5232 fix: remove autofocus prop from CommonDialogWrapper …
SychevAndrey Dec 3, 2025
48aadde
dbeaver/pro#5232 style: correct apostrophe in label text for NestedDi…
SychevAndrey Dec 3, 2025
69cb56b
dbeaver/pro#5232 fix: update dialog component styles for improved acc…
SychevAndrey Dec 3, 2025
3ca2cf1
dbeaver/pro#5232 refactor: add DialogElement component to get rid of …
SychevAndrey Dec 3, 2025
e5960a0
dbeaver/pro#5232 fix: correct min-width for large fixedWidth dialog size
SychevAndrey Dec 3, 2025
1811d90
dbeaver/pro#5232 refactor: update DialogElement properties for improv…
SychevAndrey Dec 3, 2025
33293b1
dbeaver/pro#5232 fix: use l10n for DialogElement close buttons
SychevAndrey Dec 3, 2025
fa02dea
dbeaver/pro#5232 refactor: update DialogElement to be a modal to trap…
SychevAndrey Dec 4, 2025
6d2b2ed
dbeaver/pro#5232 refactor: remove unmountOnHide prop from CommonDialo…
SychevAndrey Dec 4, 2025
a540197
dbeaver/pro#5232 feat: return ESC hotkey handling in SlideBox
SychevAndrey Dec 5, 2025
16f84ce
dbeaver/pro#5232 feat: make background panel inert to make focus neve…
SychevAndrey Dec 5, 2025
fcf394f
dbeaver/pro#5232 feat: add SlidePanel component to replace DialogElem…
SychevAndrey Dec 5, 2025
c13138e
dbeaver/pro#5232 feat: add inert prop to SlideElement for focus trapp…
SychevAndrey Dec 5, 2025
dc1aeb3
dbeaver/pro#5232 feat: pass onClose handler to SlideBox to activate h…
SychevAndrey Dec 5, 2025
c750898
dbeaver/pro#5232 style: return to initial state to avoid redundant diffs
SychevAndrey Dec 5, 2025
6b9fa46
dbeaver/pro#5232 style: update copyright year in SlideElement.module.css
SychevAndrey Dec 5, 2025
a24e915
dbeaver/pro#5232 chore: remove ui-kit dependency from package.json an…
SychevAndrey Dec 5, 2025
471753c
dbeaver/pro#5232 build: update @storybook/addon-storysource dependenc…
SychevAndrey Dec 5, 2025
c1be619
dbeaver/pro#5232 build: update @storybook/addon-storysource dependenc…
SychevAndrey Dec 5, 2025
12e0ad3
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
dariamarutkina Dec 9, 2025
e93fb04
dbeaver/pro#5232 style: remove border styles from dialog header and f…
SychevAndrey Dec 15, 2025
6d45d03
dbeaver/pro#5232 fix: update hover background color for icon button
SychevAndrey Dec 15, 2025
2e11cf2
dbeaver/pro#5232 feat: move focus from driver dialog to panel when ap…
SychevAndrey Dec 15, 2025
05f2e34
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
mr-anton-t Dec 16, 2025
63d10d3
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
EvgeniaBzzz Dec 16, 2025
8e12248
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
EvgeniaBzzz Dec 18, 2025
b31818f
dbeaver/pro#6326 fix: large window size
SychevAndrey Dec 19, 2025
3662cb7
dbeaver/pro#5232 fix: update focus on hide logic
SychevAndrey Dec 19, 2025
cd61a9a
dbeaver/pro#5232 fix: update hover and focus styles for icon button i…
SychevAndrey Dec 22, 2025
9aec4df
dbeaver/pro#5232 feat: return back the common backdrop, replace commo…
SychevAndrey Dec 22, 2025
fb0536e
dbeaver/pro#5232 fix: replace useFocus by dialog's initial focus in R…
SychevAndrey Dec 22, 2025
3dc8778
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
SychevAndrey Dec 22, 2025
48b98cb
dbeaver/pro#5232 build: update deps after merge
SychevAndrey Dec 22, 2025
443d362
dbeaver/pro#5232 refactor: use constant for button id
SychevAndrey Dec 23, 2025
15b79f2
dbeaver/pro#5232 feat: add Loader component to DialogsPortal
SychevAndrey Dec 23, 2025
6039f84
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
mr-anton-t Dec 25, 2025
f2f247f
dbeaver/pro#5232 refactor: update Dialog component to use semantic HT…
SychevAndrey Dec 26, 2025
5bf2404
dbeaver/pro#5232 fix: gap in footer of dialogs
SychevAndrey Dec 26, 2025
7ee771c
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
mr-anton-t Dec 29, 2025
e41ffe2
dbeaver/pro#5232 feat: focus input initially in New Folder dialog
SychevAndrey Dec 30, 2025
4b7b2e6
dbeaver/pro#5232 feat: add autoFocusOnShow prop to CommonDialogWrappe…
SychevAndrey Dec 30, 2025
3753d6d
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
mr-anton-t Dec 30, 2025
15be0a5
dbeaver/pro#5232 fix: padding for CommonDialogFooter
SychevAndrey Jan 5, 2026
910d9ab
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
mr-anton-t Jan 5, 2026
99a90cd
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
mr-anton-t Jan 5, 2026
d5a3f61
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
dariamarutkina Jan 6, 2026
d71a57d
Merge branch 'devel' into 5232-cb-6326-add-focus-trap-component-from-…
dariamarutkina Jan 8, 2026
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
213 changes: 213 additions & 0 deletions webapp/common-react/@dbeaver/ui-kit/src/Dialog/Dialog.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
@import './_base.css';

@layer base {
.dbv-kit-dialog__backdrop {
background-color: transparent;
opacity: 0;
transition-property: opacity, background-color;
transition-timing-function: ease-in-out;
transition-duration: 100ms;

&[data-enter] {
opacity: 1;
background-color: var(--dbv-kit-dialog-backdrop-background);
}

&:not([data-enter]) {
opacity: 0;
}

&[data-animated='false'] {
transition: none !important;
opacity: 1;
background-color: var(--dbv-kit-dialog-backdrop-background);
}

@media (prefers-reduced-motion: reduce) {
transition: none !important;
opacity: 1;
background-color: var(--dbv-kit-dialog-backdrop-background);
}
}

.dbv-kit-dialog {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1000;
display: flex;
flex-direction: column;
padding: 0;
background-color: var(--dbv-kit-dialog-content-background);
color: var(--dbv-kit-dialog-content-foreground);
border: none;
border-radius: var(--dbv-kit-dialog-content-border-radius);
box-shadow: var(--dbv-kit-dialog-content-shadow);
outline: 0;
overflow: hidden;
margin: 0;
max-width: var(--dbv-kit-dialog-large-width);

@media (prefers-reduced-motion: no-preference) {
opacity: 0;
transform: translate(-50%, -50%) scale(0.95);
transition-property: opacity, transform;
transition-timing-function: ease-in-out;
transition-duration: 150ms;

&:not([data-enter]) {
opacity: 0;
transform: translate(-50%, -50%) scale(0.95);
}
&[data-enter] {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}

&[data-animated='false'] {
transition: none !important;
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
}

@media (prefers-reduced-motion: reduce) {
transition: none !important;
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}

&[data-size='small'] {
min-width: var(--dbv-kit-dialog-small-width);
min-height: var(--dbv-kit-dialog-small-height);
max-height: max(var(--app-height, 100vh) - 48px, var(--dbv-kit-dialog-small-height));
}

&[data-size='medium'] {
min-width: var(--dbv-kit-dialog-medium-width);
min-height: var(--dbv-kit-dialog-medium-height);
max-height: max(var(--app-height, 100vh) - 48px, var(--dbv-kit-dialog-medium-height));
}

&[data-size='large'] {
min-width: var(--dbv-kit-dialog-large-width);
min-height: var(--dbv-kit-dialog-large-height);
max-height: max(var(--app-height, 100vh) - 48px, var(--dbv-kit-dialog-large-height));
}

&[data-size='free'] {
min-width: auto;
min-height: auto;
max-width: calc(100vw - 48px);
max-height: calc(100vh - 48px);
}

/* Slide variant (side panel from right) */
&[data-variant='slide'] {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transform: translateX(100%);
width: 100%;
max-width: none;
height: 100%;
max-height: 100%;
min-width: 0;
min-height: 0;
border-radius: 0;

@media (prefers-reduced-motion: no-preference) {
opacity: 1;
transition-property: transform;
transition-timing-function: var(--dbv-kit-dialog-slide-transition-timing);
transition-duration: var(--dbv-kit-dialog-slide-transition-duration);

&[data-enter] {
transform: translateX(0);
}

&:not([data-enter]) {
transform: translateX(100%);
}

&[data-animated='false'] {
transition: none !important;
transform: translateX(0);
}
}

@media (prefers-reduced-motion: reduce) {
transition: none !important;
opacity: 1;
transform: translateX(0);
}
}
}

.dbv-kit-dialog__header {
flex-shrink: 0;
padding: var(--dbv-kit-dialog-header-padding);
border-bottom: var(--dbv-kit-dialog-header-border-bottom);
}

.dbv-kit-dialog__body {
flex: 1 1 auto;
overflow-y: auto;
padding: var(--dbv-kit-dialog-body-padding);
}

.dbv-kit-dialog__footer {
flex-shrink: 0;
padding: var(--dbv-kit-dialog-footer-padding);
border-top: var(--dbv-kit-dialog-footer-border-top);
display: flex;
gap: var(--dbv-kit-dialog-footer-gap);
justify-content: flex-end;
}

.dbv-kit-dialog__disclosure {
background-color: var(--dbv-kit-dialog-disclosure-background);
color: var(--dbv-kit-dialog-disclosure-foreground);
}

.dbv-kit-dialog__heading {
margin: var(--dbv-kit-dialog-heading-margin);
font-size: var(--dbv-kit-dialog-heading-font-size);
font-weight: var(--dbv-kit-dialog-heading-font-weight);
line-height: var(--dbv-kit-dialog-heading-line-height);
color: var(--dbv-kit-dialog-heading-color);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.dbv-kit-dialog__description {
margin: var(--dbv-kit-dialog-description-margin);
font-size: var(--dbv-kit-dialog-description-font-size);
color: var(--dbv-kit-dialog-description-color);
}

.dbv-kit-dialog__dismiss {
background-color: var(--dbv-kit-dialog-dismiss-background);
color: var(--dbv-kit-dialog-dismiss-foreground);
padding: 0.5rem 1rem;
border-radius: 0.375rem;
border: none;
cursor: pointer;
font-weight: 500;
font-size: 0.875rem;
transition: background-color 150ms var(--tw-ease-in-out);

&:hover:not([aria-disabled='true']) {
background-color: var(--dbv-kit-dialog-dismiss-hover-background);
}

&[aria-disabled='true'] {
opacity: var(--dbv-kit-control-disabled-opacity, 0.5);
cursor: not-allowed;
}
}
}
92 changes: 92 additions & 0 deletions webapp/common-react/@dbeaver/ui-kit/src/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/

import {
Dialog as AriakitDialog,
DialogDescription as AriakitDialogDescription,
DialogDisclosure as AriakitDialogDisclosure,
DialogDismiss as AriakitDialogDismiss,
DialogHeading as AriakitDialogHeading,
DialogProvider,
type DialogDescriptionProps,
type DialogDismissProps,
type DialogDisclosureProps,
type DialogHeadingProps,
type DialogProps,
type DialogProviderProps,
type DialogStore,
type DialogStoreProps,
type DialogStoreState,
useDialogContext,
useDialogStore,
} from '@ariakit/react';
import clsx from 'clsx';
import type { ComponentPropsWithoutRef, JSX } from 'react';

import './Dialog.css';

interface ExtendedDialogProps extends DialogProps {
animated?: boolean;
}

function Dialog({ className, backdrop, animated = true, ...props }: ExtendedDialogProps): JSX.Element {
const backdropElement = backdrop === true ? <div className="dbv-kit-dialog__backdrop" data-animated={animated} /> : backdrop;

return <AriakitDialog className={clsx('dbv-kit-dialog', className)} backdrop={backdropElement} data-animated={animated} {...props} />;
}

function DialogDisclosure({ className, ...props }: DialogDisclosureProps): JSX.Element {
return <AriakitDialogDisclosure className={clsx('dbv-kit-dialog__disclosure', className)} {...props} />;
}

function DialogHeader({ className, ...props }: ComponentPropsWithoutRef<'header'>): JSX.Element {
return <header className={clsx('dbv-kit-dialog__header', className)} {...props} />;
}

function DialogBody({ className, ...props }: ComponentPropsWithoutRef<'div'>): JSX.Element {
return <div className={clsx('dbv-kit-dialog__body', className)} {...props} />;
}

function DialogFooter({ className, ...props }: ComponentPropsWithoutRef<'footer'>): JSX.Element {
return <footer className={clsx('dbv-kit-dialog__footer', className)} {...props} />;
}

function DialogHeading({ className, ...props }: DialogHeadingProps): JSX.Element {
return <AriakitDialogHeading className={clsx('dbv-kit-dialog__heading', className)} {...props} />;
}

function DialogDescription({ className, ...props }: DialogDescriptionProps): JSX.Element {
return <AriakitDialogDescription className={clsx('dbv-kit-dialog__description', className)} {...props} />;
}

function DialogDismiss({ className, ...props }: DialogDismissProps): JSX.Element {
return <AriakitDialogDismiss className={clsx('dbv-kit-dialog__dismiss', className)} {...props} />;
}

export {
Dialog,
DialogDisclosure,
DialogHeader,
DialogBody,
DialogFooter,
DialogHeading,
DialogDescription,
DialogDismiss,
DialogProvider,
useDialogStore,
useDialogContext,
type ExtendedDialogProps as DialogProps,
type DialogProviderProps,
type DialogDisclosureProps,
type DialogHeadingProps,
type DialogDescriptionProps,
type DialogDismissProps,
type DialogStore,
type DialogStoreProps,
type DialogStoreState,
};
66 changes: 66 additions & 0 deletions webapp/common-react/@dbeaver/ui-kit/src/Dialog/_base.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
@layer base {
:root {
/* Dialog container */
--dbv-kit-dialog-content-background: #ffffff;
--dbv-kit-dialog-content-foreground: #353535;
--dbv-kit-dialog-content-border-radius: 0.25rem;
--dbv-kit-dialog-content-shadow: 0 6px 6px -3px #0003, 0 10px 14px 1px #00000024, 0 4px 18px 3px #0000001f;

/* Dialog layout */
--dbv-kit-dialog-header-padding: 1rem 1.5rem;
--dbv-kit-dialog-header-border-bottom: none;
--dbv-kit-dialog-body-padding: 1.5rem;
--dbv-kit-dialog-footer-padding: 1rem 1.5rem;
--dbv-kit-dialog-footer-border-top: none;
--dbv-kit-dialog-footer-gap: 0.75rem;

/* Dialog sizes */
--dbv-kit-dialog-small-width: 404px;
--dbv-kit-dialog-small-height: 262px;
--dbv-kit-dialog-medium-width: 576px;
--dbv-kit-dialog-medium-height: 374px;
--dbv-kit-dialog-large-width: 720px;
--dbv-kit-dialog-large-height: 468px;
--dbv-kit-dialog-max-width: 720px;

/* Slide variant (side panel) */
--dbv-kit-dialog-slide-transition-duration: 300ms;
--dbv-kit-dialog-slide-transition-timing: ease-in-out;

/* Backdrop */
--dbv-kit-dialog-backdrop-background: #0000007a;

/* Heading */
--dbv-kit-dialog-heading-margin: 0;
--dbv-kit-dialog-heading-font-size: 1.25rem;
--dbv-kit-dialog-heading-font-weight: 400;
--dbv-kit-dialog-heading-line-height: 2rem;
--dbv-kit-dialog-heading-color: var(--dbv-kit-dialog-content-foreground);

/* Description */
--dbv-kit-dialog-description-margin: 0;
--dbv-kit-dialog-description-font-size: 0.875rem;
--dbv-kit-dialog-description-color: inherit;

/* Disclosure */
--dbv-kit-dialog-disclosure-background: transparent;
--dbv-kit-dialog-disclosure-foreground: inherit;

/* Dismiss */
--dbv-kit-dialog-dismiss-background: #f2f2f2;
--dbv-kit-dialog-dismiss-foreground: #353535;
--dbv-kit-dialog-dismiss-hover-background: #e5e5e5;
}

@media (prefers-color-scheme: dark) {
:root {
--dbv-kit-dialog-content-background: hsl(240deg, 10%, 16%);
--dbv-kit-dialog-content-foreground: #ffffff;
--dbv-kit-dialog-header-border-bottom: none;
--dbv-kit-dialog-footer-border-top: none;
--dbv-kit-dialog-dismiss-background: hsl(240deg, 10%, 18%);
--dbv-kit-dialog-dismiss-foreground: #cbcbcb;
--dbv-kit-dialog-dismiss-hover-background: hsl(240deg, 10%, 22%);
}
}
}
1 change: 1 addition & 0 deletions webapp/common-react/@dbeaver/ui-kit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
type FocusTrapRegionProps,
} from '@ariakit/react';

export { Button, ButtonBase, type ButtonProps, ButtonIcon, type ButtonIconProps } from './Button/Button.js';

Check failure on line 24 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export { IconButton, IconButtonBase, type IconButtonProps } from './IconButton/IconButton.js';

Check failure on line 25 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export { Checkbox, CheckboxBase, type CheckboxProps } from './Checkbox/Checkbox.js';

Check failure on line 26 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export { ColorPicker } from './ColorPicker/ColorPicker.js';

Check failure on line 27 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export { ColorPickerBase, type ColorPickerProps } from './ColorPicker/ColorPickerBase.js';

Check failure on line 28 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export { Input, InputBase, type InputProps } from './Input/Input.js';

Check failure on line 29 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export {
Select,
useSelectContext,
Expand All @@ -36,10 +36,10 @@
type SelectLabelProps,
type SelectPopoverProps,
type SelectItemProps,
} from './Select/Select.js';

Check failure on line 39 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export * from './Combobox/Combobox.js';

Check failure on line 40 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export * from './Command/Command.js';

Check failure on line 41 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export { Popover } from './Popover/Popover.js';

Check failure on line 42 in webapp/common-react/@dbeaver/ui-kit/src/index.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

Don't import/export .tsx files from .ts files directly, use React.lazy()
export { SelectField, type SelectFieldProps, type SelectItem } from './Select/SelectField.js';
export { Spinner, type SpinnerProps } from './Spinner/Spinner.js';
export { Radio, RadioGroup, useRadioContext, useRadioStore, type RadioProviderProps, type RadioProps, type RadioGroupProps } from './Radio/index.js';
Expand All @@ -48,3 +48,4 @@
export * from './ComponentProvider.js';
export * from './Menu/Menu.js';
export * from './Disclosure/Disclosure.js';
export * from './Dialog/Dialog.js';
Loading
Loading