Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/dbeaver/vscode#86/storybook integration #3251

Open
wants to merge 82 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
e0896aa
feat: add ui-kit package to common-react
SychevAndrey Feb 5, 2025
c47c19b
feat: add tailwind and ladle to ui-kit, use ui-kit in ce
SychevAndrey Feb 6, 2025
d11fe80
feat: create custom properties for button and checkbox using tailwind…
SychevAndrey Feb 10, 2025
74241c0
feat: create simple button with 2 variants
SychevAndrey Feb 10, 2025
0ed231c
feat: create simple checkbox
SychevAndrey Feb 10, 2025
2cf9224
refactor: update after rebase
SychevAndrey Feb 10, 2025
f02c669
feat: experiments with button and checkbox
SychevAndrey Feb 10, 2025
3e41bfc
feat: add buttons sizes, adjust btn loader, add interactive story ins…
SychevAndrey Feb 11, 2025
01b1fa8
fix: add license
SychevAndrey Feb 11, 2025
ba32e62
fix: a11y issues with color contrast
SychevAndrey Feb 11, 2025
c88f33e
fix: mdx stories support
SychevAndrey Feb 11, 2025
3393ff4
feat: experiments with icons
SychevAndrey Feb 11, 2025
c5a5419
feat: try custom rendering
SychevAndrey Feb 12, 2025
e2f79cc
docs: add small kinda docs for button
SychevAndrey Feb 12, 2025
3173019
refactor: css layers
SychevAndrey Feb 12, 2025
e54263e
chore: deps
SychevAndrey Feb 12, 2025
805487e
chore: remove buildinfo from git
SychevAndrey Feb 12, 2025
574f786
chore: remove tsbuildinfo from git
SychevAndrey Feb 12, 2025
ef3e005
fix: vertical tab overflow
SychevAndrey Feb 12, 2025
62bb1fe
feat: use UIKit button as base for Cloudbeaver button
SychevAndrey Feb 12, 2025
67d0522
fix: box-sizing problems
SychevAndrey Feb 12, 2025
ed91ba2
refactor: button styles use BEM model
SychevAndrey Feb 13, 2025
f5e137c
refactor: separate base tokens from aliases
SychevAndrey Feb 13, 2025
5322cd8
refactor: add some defaults, write all properties in snake case
SychevAndrey Feb 13, 2025
5506e34
refactor: rename button classes, add ui-kit prefix
SychevAndrey Feb 13, 2025
5c2b6c7
refactor: remove redundant story, omit a couple of props, add example…
SychevAndrey Feb 14, 2025
22600ca
refactor: add general sizes tokens, update license
SychevAndrey Feb 14, 2025
d515341
feat: add scaffold for input component
SychevAndrey Feb 14, 2025
f7d6533
refactor: update deps
SychevAndrey Feb 14, 2025
ff8b6e7
refactor: remove links
SychevAndrey Feb 14, 2025
7fa37ac
refactor: change props naming, add prefixes in checkbox, removes vali…
SychevAndrey Feb 14, 2025
1d93f2b
refactor: partially revert "feat: use UIKit button as base for Cloudb…
SychevAndrey Feb 14, 2025
c58f40f
Revert "refactor: update deps"
SychevAndrey Feb 14, 2025
72ea725
refactor: update deps once again
SychevAndrey Feb 14, 2025
e7fa7df
refactor: rename ui-kit prefix
SychevAndrey Feb 14, 2025
9f16ad0
chore: update deps
SychevAndrey Feb 14, 2025
3cec396
refactor: Button Icon Interface
SychevAndrey Feb 14, 2025
f27cf5d
refactor: use JSDoc for placement comment
SychevAndrey Feb 14, 2025
8da1693
refactor css custom props for Button
SychevAndrey Feb 14, 2025
4522512
refactor: introduce opacity custom property, fix icon margin property
SychevAndrey Feb 14, 2025
e421ed2
fix: button text should not wrap;
SychevAndrey Feb 14, 2025
705459d
fix: tailwindcss version
SychevAndrey Feb 14, 2025
a576223
fix: tailwindcss version
SychevAndrey Feb 14, 2025
624a99d
Merge branch 'devel' into feat/dbeaver/vscode#86/storybook-integration
mr-anton-t Feb 18, 2025
35da52d
refactor: remove checkbox styles, keep only wireframe
SychevAndrey Feb 18, 2025
e26c098
refactor: move input-related css variables to the dedicated folder
SychevAndrey Feb 18, 2025
3b96717
Merge branch 'devel' into feat/dbeaver/vscode#86/storybook-integration
mr-anton-t Feb 18, 2025
5691098
refactor: remove unused input props
SychevAndrey Feb 18, 2025
20577e0
refactor: btn loader animation
SychevAndrey Feb 18, 2025
fbc796f
refactor: use nesting for states, refactor classnames using BEM delim…
SychevAndrey Feb 18, 2025
6f8e0e9
refactor: introduce btn-border-width prop, removed redundant btn-padd…
SychevAndrey Feb 18, 2025
cae65af
refactor: input and button
SychevAndrey Feb 18, 2025
d4fe471
fix: input
SychevAndrey Feb 18, 2025
fb3a4aa
chore: deps
SychevAndrey Feb 18, 2025
6ab47df
Merge branch 'feat/dbeaver/vscode#86/storybook-integration' of github…
SychevAndrey Feb 18, 2025
c83242e
chore: deps
SychevAndrey Feb 18, 2025
f109009
chore: add vite as dev dep
SychevAndrey Feb 18, 2025
58b0854
refactor: button variants
SychevAndrey Feb 19, 2025
5ad9d14
chore: yarn install
SychevAndrey Feb 19, 2025
1320bdc
Merge branch 'devel' into feat/dbeaver/vscode#86/storybook-integration
mr-anton-t Feb 19, 2025
9a8aff1
fix: loading button should not react on hover
SychevAndrey Feb 19, 2025
4b96b2b
Merge branch 'feat/dbeaver/vscode#86/storybook-integration' of github…
SychevAndrey Feb 19, 2025
6f453a1
docs: add stories about tokens
SychevAndrey Feb 19, 2025
5c60cc5
chore: remove lint command
SychevAndrey Feb 19, 2025
c5f2fe0
refactor: add prefix to css variables
SychevAndrey Feb 19, 2025
eec10c5
refactor: add base border-radius and border-width for controls
SychevAndrey Feb 20, 2025
aa4aa3d
Merge branch 'devel' into feat/dbeaver/vscode#86/storybook-integration
SychevAndrey Feb 20, 2025
555fd1e
fix: don't import tailwind in style files
SychevAndrey Feb 20, 2025
007e11f
fix: add tailwindcss import for ladle
SychevAndrey Feb 20, 2025
5b0635d
fix: base radius variable
SychevAndrey Feb 20, 2025
58291c5
refactor: rename css var
SychevAndrey Feb 20, 2025
63ff49e
refactor: add tw prefix for tailwind classes and vars
SychevAndrey Feb 20, 2025
e7ffc3b
fix: styles in easy-config
SychevAndrey Feb 20, 2025
97c3f78
fix: after tailwind reset paddings don't in width anymore, compensate
SychevAndrey Feb 20, 2025
64b71f7
Merge branch 'devel' into feat/dbeaver/vscode#86/storybook-integration
mr-anton-t Feb 20, 2025
ba5dd42
fix: don't show outline on mouse click
SychevAndrey Feb 20, 2025
b957ab0
Merge branch 'feat/dbeaver/vscode#86/storybook-integration' of github…
SychevAndrey Feb 20, 2025
9f7c7cb
refactor: change btn state classes, remove not loading for hover beca…
SychevAndrey Feb 20, 2025
dad2d40
fix: icons
SychevAndrey Feb 21, 2025
f9c0e84
fix: add letter-spacing to normalize to prevent tailwind reset it wit…
SychevAndrey Feb 21, 2025
655278e
Merge branch 'devel' into feat/dbeaver/vscode#86/storybook-integration
mr-anton-t Feb 21, 2025
09aa816
fix: welcome page selector
SychevAndrey Feb 21, 2025
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
23 changes: 23 additions & 0 deletions common-react/@dbeaver/ui-kit/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/lib

# misc
.DS_Store
.env*

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

tsconfig.tsbuildinfo
2 changes: 2 additions & 0 deletions common-react/@dbeaver/ui-kit/.ladle/components.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '../src/index.css';
import './global.css';
8 changes: 8 additions & 0 deletions common-react/@dbeaver/ui-kit/.ladle/config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('@ladle/react').UserConfig} */
export default {
addons: {
a11y: {
enabled: true,
},
},
};
19 changes: 19 additions & 0 deletions common-react/@dbeaver/ui-kit/.ladle/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import 'tailwindcss' prefix(tw);

@layer theme {
a {
color: var(--tw-color-blue-600);
}

code {
color: var(--tw-color-yellow-600);
}

.comment {
color: var(--tw-color-gray-400);
}
}

:root[data-theme='dark'] {
color: white;
}
32 changes: 32 additions & 0 deletions common-react/@dbeaver/ui-kit/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@dbeaver/ui-kit",
"type": "module",
"version": "0.1.0",
"description": "",
"license": "Apache-2.0",
"exports": {
".": "./dist/index.js"
},
"scripts": {
"build": "tsc -b",
"clean": "rimraf --glob dist"
},
"packageManager": "[email protected]",
"devDependencies": {
"@dbeaver/tsconfig": "workspace:^",
"@ladle/react": "^5",
"@tailwindcss/vite": "^4",
"@types/react": "^19",
"@types/react-dom": "^19",
"@wroud/vite-plugin-asset-resolver": "^0",
"rimraf": "^6",
"tailwindcss": "^4",
"typescript": "^5",
"vite": "^6"
},
"dependencies": {
"@ariakit/react": "^0",
"react": "^19",
"react-dom": "^19"
}
}
172 changes: 172 additions & 0 deletions common-react/@dbeaver/ui-kit/src/Button/Button.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
@import './_base.css';
@import './_sizes.css';
@import './_variants.css';

@layer components {
.dbv-kit-button {
display: inline-flex;
text-align: center;
text-decoration: none;
cursor: pointer;
user-select: none;
position: relative;
align-items: center;
white-space: nowrap;

height: var(--dbv-kit-btn-height);
padding-inline: var(--dbv-kit-btn-padding-inline);
gap: var(--dbv-kit-btn-gap);

background-color: var(--dbv-kit-btn-background);
color: var(--dbv-kit-btn-foreground);

border-radius: var(--dbv-kit-btn-border-radius);
border-width: var(--dbv-kit-btn-border-width);
border-color: var(--dbv-kit-btn-border-color);
border-style: var(--dbv-kit-btn-border-style);

font-size: var(--dbv-kit-btn-font-size);
font-weight: var(--dbv-kit-btn-font-weight);

&:focus-visible,
&[data-focus-visible] {
outline: 2px solid var(--dbv-kit-color-outline);
}

&:hover {
@media (hover: hover) {
background-color: var(--dbv-kit-btn-background-hover);
}
}

&:active,
&[data-active] {
background-color: var(--dbv-kit-btn-background-active);
}

&:disabled {
opacity: var(--dbv-kit-btn-disabled-opacity);
}
}

/* ---------------------------- */
/* Sizes */

.dbv-kit-button__small {
--dbv-kit-btn-padding-inline: var(--dbv-kit-btn-small-padding-inline);
--dbv-kit-btn-font-size: var(--dbv-kit-btn-small-font-size);
--dbv-kit-btn-height: var(--dbv-kit-btn-small-height);
--dbv-kit-btn-gap: var(--dbv-kit-btn-small-gap);

--dbv-kit-btn-icon-margin-inline: calc(var(--dbv-kit-btn-small-padding-inline) * -0.25);
}

.dbv-kit-button__medium {
--dbv-kit-btn-padding-inline: var(--dbv-kit-btn-medium-padding-inline);
--dbv-kit-btn-font-size: var(--dbv-kit-btn-medium-font-size);
--dbv-kit-btn-height: var(--dbv-kit-btn-medium-height);
--dbv-kit-btn-gap: var(--dbv-kit-btn-medium-gap);

--dbv-kit-btn-icon-margin-inline: calc(var(--dbv-kit-btn-medium-padding-inline) * -0.25);
}

.dbv-kit-button__large {
--dbv-kit-btn-padding-inline: var(--dbv-kit-btn-large-padding-inline);
--dbv-kit-btn-font-size: var(--dbv-kit-btn-large-font-size);
--dbv-kit-btn-height: var(--dbv-kit-btn-large-height);
--dbv-kit-btn-gap: var(--dbv-kit-btn-large-gap);

--dbv-kit-btn-icon-margin-inline: calc(var(--dbv-kit-btn-large-padding-inline) * -0.25);
}

.dbv-kit-button__xlarge {
--dbv-kit-btn-padding-inline: var(--dbv-kit-btn-xlarge-padding-inline);
--dbv-kit-btn-font-size: var(--dbv-kit-btn-xlarge-font-size);
--dbv-kit-btn-height: var(--dbv-kit-btn-xlarge-height);
--dbv-kit-btn-gap: var(--dbv-kit-btn-xlarge-gap);

--dbv-kit-btn-icon-margin-inline: calc(var(--dbv-kit-btn-xlarge-padding-inline) * -0.25);
}

/* ---------------------------- */
/* Variants */

.dbv-kit-button__primary {
--dbv-kit-btn-background: var(--dbv-kit-btn-primary-background);
--dbv-kit-btn-foreground: var(--dbv-kit-btn-primary-foreground);
--dbv-kit-btn-background-hover: var(--dbv-kit-btn-primary-background-hover);
--dbv-kit-btn-background-active: var(--dbv-kit-btn-primary-background-active);

--dbv-kit-btn-loader-color: color-mix(in srgb, var(--dbv-kit-btn-background) 65%, var(--tw-color-white));
--dbv-kit-btn-loader-background: color-mix(in srgb, var(--dbv-kit-btn-foreground) 85%, transparent);
}

.dbv-kit-button__secondary {
--dbv-kit-btn-background: var(--dbv-kit-btn-secondary-background);
--dbv-kit-btn-foreground: var(--dbv-kit-btn-secondary-foreground);
--dbv-kit-btn-background-hover: var(--dbv-kit-btn-secondary-background-hover);
--dbv-kit-btn-background-active: var(--dbv-kit-btn-secondary-background-active);
--dbv-kit-btn-border-color: var(--dbv-kit-btn-secondary-border-color);

--dbv-kit-btn-loader-color: color-mix(in srgb, var(--dbv-kit-btn-secondary-foreground) 75%, var(--tw-color-gray-600));
--dbv-kit-btn-loader-background: color-mix(in srgb, var(--tw-color-white) 75%, transparent);
}

.dbv-kit-button__danger {
--dbv-kit-btn-background: var(--dbv-kit-btn-danger-background);
--dbv-kit-btn-foreground: var(--dbv-kit-btn-danger-foreground);
--dbv-kit-btn-background-hover: var(--dbv-kit-btn-danger-background-hover);
--dbv-kit-btn-background-active: var(--dbv-kit-btn-danger-background-active);

--dbv-kit-btn-loader-color: color-mix(in srgb, var(--dbv-kit-btn-danger-background) 65%, var(--tw-color-white));
--dbv-kit-btn-loader-background: color-mix(in srgb, var(--dbv-kit-btn-danger-foreground) 85%, transparent);
}

/* ---------------------------- */
/* Loader */

.dbv-kit-button_loader {
position: absolute;
top: calc(var(--dbv-kit-btn-border-width) * -1);
left: calc(var(--dbv-kit-btn-border-width) * -1);
width: calc(100% + var(--dbv-kit-btn-border-width) * 2);
height: calc(100% + var(--dbv-kit-btn-border-width) * 2);
background: color-mix(in srgb, var(--dbv-kit-btn-loader-background) 75%, var(--tw-color-gray-100));
display: flex;
align-items: center;
justify-content: center;
border-radius: inherit;
pointer-events: none;

&::after {
--loader-width: calc(var(--dbv-kit-btn-font-size) * 0.2);
content: '';
border: var(--loader-width) solid var(--dbv-kit-btn-loader-background);
border-top: var(--loader-width) solid var(--dbv-kit-btn-loader-color);
border-radius: 50%;
opacity: 1;
width: calc(var(--dbv-kit-btn-font-size) * 1.2);
height: calc(var(--dbv-kit-btn-font-size) * 1.2);
animation: var(--dbv-kit-btn-loader-animation);
}
}

/* ---------------------------- */
/* Icon */

.dbv-kit-button_icon {
display: flex;
align-items: center;
justify-content: center;

fill: currentColor;
}

.dbv-kit-button_icon__start {
margin-inline-start: var(--dbv-kit-btn-icon-margin-inline);
}

.dbv-kit-button_icon__end {
margin-inline-end: var(--dbv-kit-btn-icon-margin-inline);
}
}
39 changes: 39 additions & 0 deletions common-react/@dbeaver/ui-kit/src/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 { Button as AriaButton, type ButtonProps as AriaKitButtonProps } from '@ariakit/react';
import './Button.css';

export interface ButtonProps extends Omit<AriaKitButtonProps, 'clickOnEnter' | 'clickOnSpace'> {
variant?: 'primary' | 'secondary' | 'danger';
size?: 'small' | 'medium' | 'large' | 'xlarge';
loading?: boolean;
}

export function Button({ className, variant = 'primary', size = 'medium', loading, children, onClick, ...props }: ButtonProps) {
const classToApply = `dbv-kit-button dbv-kit-button__${variant} dbv-kit-button__${size}` + (className ? ` ${className}` : '');

return (
<AriaButton aria-label={loading ? 'Loading' : ''} onClick={loading ? () => null : onClick} className={classToApply} {...props}>
{loading && <span className="dbv-kit-button_loader" />}
{children}
</AriaButton>
);
}
export interface ButtonIconProps extends React.HTMLAttributes<HTMLSpanElement> {
placement?: 'start' | 'end';
}

/**
* Button Icon component - used to place an icon inside a button, renders span element.;
*
* @param props.placement This property is needed to adjust icon placement inside a button. The icon with placement="start" will cut the inline-start padding. placement="end" will affect the padding-inline-end accordingly. This property supports RTL and LTR, so you don't need to think about it.
*/
Button.Icon = function ButtonIcon({ className, children, placement }: ButtonIconProps) {
const classToApply = `dbv-kit-button_icon` + (placement ? ` dbv-kit-button-icon__${placement}` : '') + (className ? ` ${className}` : '');
return <span className={classToApply}>{children}</span>;
};
19 changes: 19 additions & 0 deletions common-react/@dbeaver/ui-kit/src/Button/_base.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@layer base {
:root {
--dbv-kit-btn-height: var(--dbv-kit-control-height-medium);
--dbv-kit-btn-padding-inline: calc(var(--tw-spacing) * 2.5);
--dbv-kit-btn-gap: calc(var(--dbv-kit-btn-padding-inline) / 4);
--dbv-kit-btn-foreground: var(--tw-color-white);
--dbv-kit-btn-background: var(--dbv-kit-color-primary-600);
--dbv-kit-btn-background-hover: var(--dbv-kit-color-primary-700);
--dbv-kit-btn-background-active: var(--dbv-kit-color-primary-800);
--dbv-kit-btn-border-width: var(--dbv-kit-control-border-width);
--dbv-kit-btn-border-color: transparent;
--dbv-kit-btn-border-style: solid;
--dbv-kit-btn-border-radius: var(--dbv-kit-control-border-radius);
--dbv-kit-btn-font-weight: var(--tw-font-weight-normal);
--dbv-kit-btn-font-size: calc(var(--dbv-kit-font-size-base) * 0.875);
--dbv-kit-btn-disabled-opacity: 0.5;
--dbv-kit-btn-loader-animation: var(--tw-animate-spin);
}
}
27 changes: 27 additions & 0 deletions common-react/@dbeaver/ui-kit/src/Button/_sizes.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@layer base {
:root {
/*Small button*/
--dbv-kit-btn-small-padding-inline: calc(var(--dbv-kit-btn-padding-inline) * 0.5);
--dbv-kit-btn-small-font-size: calc(var(--dbv-kit-btn-font-size) * 0.875);
--dbv-kit-btn-small-height: var(--dbv-kit-control-height-small);
--dbv-kit-btn-small-gap: calc(var(--dbv-kit-btn-gap) * 0.5);

/*Medium button*/
--dbv-kit-btn-medium-padding-inline: var(--dbv-kit-btn-padding-inline);
--dbv-kit-btn-medium-font-size: var(--dbv-kit-btn-font-size);
--dbv-kit-btn-medium-height: var(--dbv-kit-control-height-medium);
--dbv-kit-btn-medium-gap: var(--dbv-kit-btn-gap);

/*Large button*/
--dbv-kit-btn-large-padding-inline: calc(var(--dbv-kit-btn-padding-inline) * 1.25);
--dbv-kit-btn-large-font-size: calc(var(--dbv-kit-btn-font-size) * 1.125);
--dbv-kit-btn-large-height: var(--dbv-kit-control-height-large);
--dbv-kit-btn-large-gap: calc(var(--dbv-kit-btn-gap) * 1.25);

/*Extra large button*/
--dbv-kit-btn-xlarge-padding-inline: calc(var(--dbv-kit-btn-padding-inline) * 1.5);
--dbv-kit-btn-xlarge-font-size: calc(var(--dbv-kit-btn-font-size) * 1.25);
--dbv-kit-btn-xlarge-height: var(--dbv-kit-control-height-xlarge);
--dbv-kit-btn-xlarge-gap: calc(var(--dbv-kit-btn-gap) * 1.5);
}
}
22 changes: 22 additions & 0 deletions common-react/@dbeaver/ui-kit/src/Button/_variants.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@layer base {
:root {
/* Primary Button */
--dbv-kit-btn-primary-foreground: var(--tw-color-white);
--dbv-kit-btn-primary-background: var(--dbv-kit-color-primary-600);
--dbv-kit-btn-primary-background-hover: var(--dbv-kit-color-primary-700);
--dbv-kit-btn-primary-background-active: var(--dbv-kit-color-primary-800);

/* Secondary Button */
--dbv-kit-btn-secondary-foreground: var(--dbv-kit-color-primary-600);
--dbv-kit-btn-secondary-background: transparent;
--dbv-kit-btn-secondary-background-hover: var(--dbv-kit-color-primary-50);
--dbv-kit-btn-secondary-background-active: var(--dbv-kit-color-primary-100);
--dbv-kit-btn-secondary-border-color: var(--dbv-kit-color-primary-600);

/* Danger Button */
--dbv-kit-btn-danger-foreground: var(--tw-color-white);
--dbv-kit-btn-danger-background: var(--tw-color-red-600);
--dbv-kit-btn-danger-background-hover: var(--tw-color-red-700);
--dbv-kit-btn-danger-background-active: var(--tw-color-red-800);
}
}
Loading
Loading