dbeaver/pro#6968 feat: add storybook (#3767)

* dbeaver/pro#6968 feat: add storybook

* chore: remove duplicate

* fix: ladle

* chore: remove storybook onboarding

* adds task to run storybook

---------

Co-authored-by: sergeyteleshev <iamsergeyteleshev@gmail.com>
This commit is contained in:
Alexey Potsetsuev
2025-09-23 21:02:07 +08:00
committed by GitHub
co-authored by sergeyteleshev
parent 4f53ece164
commit d1c2d6547f
18 changed files with 1621 additions and 20 deletions
+9
View File
@@ -136,6 +136,15 @@
"cwd": "${workspaceFolder}/webapp/common-react/@dbeaver/ui-kit"
},
"args": ["docs"]
},
{
"label": "Run Storybook",
"type": "shell",
"command": "yarn",
"options": {
"cwd": "${workspaceFolder}/webapp/packages/storybook"
},
"args": ["storybook"]
}
],
"inputs": [
@@ -1,10 +1,23 @@
/*
* 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 tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';
import { assetResolverPlugin } from '@wroud/vite-plugin-asset-resolver';
import { tscPlugin } from '@wroud/vite-plugin-tsc';
import svgr from 'vite-plugin-svgr';
/** @type {import('vite').UserConfig} */
export default {
export default defineConfig({
server: {
fs: {
strict: false,
},
},
plugins: [
svgr(),
tailwindcss(),
@@ -15,4 +28,4 @@ export default {
prebuild: true,
}),
],
};
});
+5 -2
View File
@@ -5,6 +5,7 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { defineConfig } from 'eslint/config';
import cloudbeaverPlugin from '@cloudbeaver/eslint-plugin';
import pluginReact from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
@@ -12,8 +13,10 @@ import tseslint from 'typescript-eslint';
import eslint from '@eslint/js';
import stylistic from '@stylistic/eslint-plugin';
import eslintConfigPrettier from 'eslint-config-prettier';
import storybook from 'eslint-plugin-storybook';
export default tseslint.config(
export default defineConfig(
storybook.configs['flat/recommended'],
eslint.configs.recommended,
tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
@@ -238,6 +241,6 @@ export default tseslint.config(
},
{
files: ['**/*.cjs'],
ignores: ['**/lib'],
ignores: ['**/lib', '!.storybook'],
},
);
@@ -30,6 +30,7 @@
"eslint-config-prettier": "^10",
"eslint-plugin-react": "^7",
"eslint-plugin-react-hooks": "^5",
"eslint-plugin-storybook": "^9",
"typescript-eslint": "^8"
}
}
+27
View File
@@ -0,0 +1,27 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*storybook.log
storybook-static
@@ -0,0 +1,132 @@
@import 'tailwindcss' layer(base) prefix(tw);
@layer theme {
main {
color: var(--dbv-kit-color-foreground);
background-color: var(--tw-color-gray-50);
}
a {
color: var(--tw-color-blue-600);
text-decoration: underline;
&:hover {
color: var(--tw-color-blue-700);
text-decoration-thickness: 2px;
}
}
code {
color: var(--tw-color-orange-700);
}
h1,
h2,
h3,
h3,
h5 {
font-weight: var(--tw-font-weight-semibold);
margin-block-start: 1em;
margin-block-end: 0.5em;
}
h1 {
font-size: var(--tw-text-2xl);
}
h2 {
font-size: var(--tw-text-xl);
}
h3 {
font-size: var(--tw-text-lg);
}
p {
font-size: var(--tw-text-base);
margin-block-start: 0.5em;
margin-block-end: 0.5em;
}
kbd {
background-color: #eee;
border-radius: 3px;
border: 1px solid #b4b4b4;
box-shadow:
0 1px 1px rgba(0, 0, 0, 0.2),
0 2px 0 0 rgba(255, 255, 255, 0.7) inset;
color: #333;
display: inline-block;
font-size: 0.85em;
font-weight: 700;
line-height: 1;
padding: 2px 4px;
white-space: nowrap;
}
.codeblock {
background-color: var(--tw-color-gray-100);
padding: 1em;
border-radius: 0.25em;
margin-block-start: 1em;
margin-block-end: 1em;
}
.comment {
color: var(--tw-color-gray-500);
}
.color-sample {
display: inline-block;
width: 1em;
height: 1em;
border-radius: 0.25em;
}
}
:root[data-theme='dark'] {
--dbv-kit-color-foreground: var(--tw-color-gray-200);
--dbv-kit-color-background: var(--tw-color-gray-900);
--dbv-kit-btn-loader-base-color: var(--tw-color-gray-900);
/* Primary Button */
--dbv-kit-btn-primary-foreground: var(--tw-color-gray-100);
--dbv-kit-btn-primary-background: var(--dbv-kit-color-primary-700);
--dbv-kit-btn-primary-background-hover: var(--dbv-kit-color-primary-600);
--dbv-kit-btn-primary-background-active: var(--dbv-kit-color-primary-500);
/* Secondary Button */
--dbv-kit-btn-secondary-foreground: var(--tw-color-gray-100);
--dbv-kit-btn-secondary-background: transparent;
--dbv-kit-btn-secondary-background-hover: var(--tw-color-gray-800);
--dbv-kit-btn-secondary-background-active: var(--tw-color-gray-700);
--dbv-kit-btn-secondary-border-color: var(--tw-color-gray-200);
/* Danger Button */
--dbv-kit-btn-danger-foreground: var(--tw-color-gray-100);
--dbv-kit-btn-danger-background: var(--tw-color-red-700);
--dbv-kit-btn-danger-background-hover: var(--tw-color-red-600);
--dbv-kit-btn-danger-background-active: var(--tw-color-red-500);
/* Input */
--dbv-kit-input-background: var(--tw-color-gray-800);
--dbv-kit-input-border-color: var(--tw-color-gray-700);
--dbv-kit-input-color: var(--tw-color-gray-100);
--dbv-kit-input-placeholder-foreground: var(--tw-color-gray-400);
main {
background-color: var(--tw-color-gray-900);
}
code {
color: var(--tw-color-orange-400);
}
a {
color: var(--tw-color-blue-300);
}
.codeblock {
background-color: var(--tw-color-gray-800);
}
}
@@ -0,0 +1,20 @@
import type { StorybookConfig } from '@storybook/react-vite';
import { join, dirname } from 'path';
/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
function getAbsolutePath(value: string): any {
return dirname(require.resolve(join(value, 'package.json')));
}
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [getAbsolutePath('@storybook/addon-docs')],
framework: {
name: getAbsolutePath('@storybook/react-vite'),
options: {},
},
};
export default config;
@@ -0,0 +1,15 @@
import './global.css';
import type { Preview } from '@storybook/react-vite';
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};
export default preview;
+31
View File
@@ -0,0 +1,31 @@
{
"name": "@cloudbeaver/storybook",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"@dbeaver/ui-kit": "workspace:^",
"react": "^19",
"react-dom": "^19"
},
"devDependencies": {
"@cloudbeaver/tsconfig": "workspace:*",
"@storybook/addon-docs": "^9",
"@storybook/react-vite": "^9",
"@tailwindcss/vite": "4.0.7",
"@types/react": "^19",
"@types/react-dom": "^19",
"@vitejs/plugin-react": "^5",
"@wroud/vite-plugin-asset-resolver": "^0",
"@wroud/vite-plugin-tsc": "^0",
"globals": "^16",
"storybook": "^9",
"tailwindcss": "4.0.7",
"typescript": "^5",
"vite": "^7"
}
}
@@ -0,0 +1,36 @@
# Button
The Button component is a simple button that can be used in different contexts. It has several visual parameters that can be customized.
## Class names
- `.dbv-kit-button` - the main class name for the button component.
- `.dbv-kit-button--primary` - the class name for the primary variant.
- `.dbv-kit-button--secondary` - the class name for the secondary variant.
- `.dbv-kit-button--danger` - the class name for the danger variant.
- `.dbv-kit-button--small` - the class name for the small size.
- `.dbv-kit-button--medium` - the class name for the medium size.
- `.dbv-kit-button--large` - the class name for the large size.
- `.dbv-kit-button--xlarge` - the class name for the extra large size.
---
- `.dbv-kit-button__icon` - the class name for the icon component.
- `.dbv-kit-button__icon--start` - the class name for the icon with placement="start".
- `.dbv-kit-button__icon--end` - the class name for the icon with placement="end".
Underlying components docs:
[https://ariakit.org/reference/button](https://ariakit.org/reference/button)
### Props:
**variant**
primary | secondary | danger
**size**
small | medium | large | xlarge
**loading**
boolean
@@ -0,0 +1,86 @@
# Button CSS Tokens
This UI kit uses several CSS tokens to style buttons.
## Common buttons tokens
### Size and space
- `--dbv-kit-btn-height:` var(--dbv-kit-control-height-medium) - Default button height
- `--dbv-kit-btn-padding-inline:` --spacing(2.5) - Medium button inline paddings, other sizes are calculated based on that variable
- `--dbv-kit-btn-gap:` calc(var(--dbv-kit-btn-padding-inline) /4) - Gap between button elements (mostly text and icon)
- `--dbv-kit-btn-outline-offset:` 1px - Button outline offset
### Basic colors
- `--dbv-kit-btn-foreground:` var(--color-white) - Default button text color
- `--dbv-kit-btn-background:` var(--dbv-kit-color-primary-600) - Default button background color
- `--dbv-kit-btn-background-hover:` var(--dbv-kit-color-primary-700) - Button hover background color
- `--dbv-kit-btn-background-active:` var(--dbv-kit-color-primary-800) - Button active background color
### Border
- `--dbv-kit-btn-border-width:` 1px - Button border width
- `--dbv-kit-btn-border-color:` transparent; --dbv-kit-btn-border-style: solid - Button border color and style
- `--dbv-kit-btn-border-radius:` var(--radius-md) - Button border radius
### Font
- `--dbv-kit-btn-font-weight:` var(--font-weight-normal) - Button font weight
- `--dbv-kit-btn-font-size:` calc(var(--dbv-kit-font-size-base) * 0.875) - Button font size, default for medium-sized button, other sizes calculated based on that value
### Loader
- `--dbv-kit-btn-loader-base-color:` var(--tw-color-white) - This color used in loader to mix with other button colors like `color: color-mix(in srgb, var(--dbv-kit-btn-foreground) 25%, var(--dbv-kit-btn-loader-base-color))`. It should be light in light mode and one of the dark colors for dark theme.
- `--dbv-kit-btn-loader-animation:` var(--animate-spin) - Button loader animation
### Others
- `--dbv-kit-btn-disabled-opacity:` 0.5 - Button opacity when disabled
## Specific buttons tokens
### Button Sizes
The `--dbv-kit-btn-*-height` tokens are used to define the height of buttons for different size variants. Default buttons use `--control-height-*` variable as the base height.
- Small button height: `--dbv-kit-btn-small-height`
- Medium button height: `--dbv-kit-btn-medium-height`
- Large button height: `--dbv-kit-btn-large-height`
- Extra large button height: `--dbv-kit-btn-xlarge-height`
### Button Padding
The `--dbv-kit-btn-*-padding-inline` tokens are used to define the padding of buttons for different size variants.
- Small button padding: `--dbv-kit-btn-small-padding-inline`
- Medium button padding: `--dbv-kit-btn-medium-padding-inline`
- Large button padding: `--dbv-kit-btn-large-padding-inline`
- Extra large button padding: `--dbv-kit-btn-xlarge-padding-inline`
### Button Colors
- Primary button background: `--dbv-kit-btn-primary-background`
- Primary button background (hover): `--dbv-kit-btn-primary-background-hover`
- Primary button background (active): `--dbv-kit-btn-primary-background-active`
- Secondary button background: `--dbv-kit-btn-secondary-background`
- Secondary button background (hover): `--dbv-kit-btn-secondary-background-hover`
- Secondary button background (active): `--dbv-kit-btn-secondary-background-active`
- Secondary button border color: `--dbv-kit-btn-secondary-border-color`
- Danger button background: `--dbv-kit-btn-danger-background`
- Danger button background (hover): `--dbv-kit-btn-danger-background-hover`
- Danger button background (active): `--dbv-kit-btn-danger-background-active`
The `--dbv-kit-btn-*-background` and `--dbv-kit-btn-*-foreground` tokens are used to define the background and text color of buttons for different variants (primary, secondary, danger).
To set another background or text color for your button, you can override the respective `--dbv-kit-btn-*` tokens in your CSS.
### Button Borders
Button border width: `--dbv-kit-btn-border-width`
The `--dbv-kit-btn-border-width` token is used to define the border width of buttons.
To change the border size of your button, you can override the `--dbv-kit-btn-border-width` token in your CSS.
@@ -0,0 +1,358 @@
/*
* 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, ButtonIcon } from '@dbeaver/ui-kit';
import { Meta, StoryObj } from '@storybook/react-vite';
import { useState } from 'react';
const meta = {
component: Button,
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
children: 'Button',
},
argTypes: {
variant: {
options: ['primary', 'secondary', 'danger'],
control: {
type: 'select',
},
defaultValue: 'primary',
},
size: {
options: ['small', 'medium', 'large', 'xlarge'],
control: {
type: 'select',
},
defaultValue: 'medium',
},
loading: {
control: {
type: 'boolean',
},
defaultValue: false,
},
},
};
export const Variants = () => (
<div>
<h3 className="tw:text-lg tw:my-2">Variants</h3>
<p>Button component has 3 predefined variants: primary, secondary, and danger.</p>
<div className="codeblock tw:bg-gray-100 tw:p-4 tw:my-4">
<code>&lt;Button variant="primary"/&gt;</code>
</div>
<div className="tw:flex tw:gap-4 tw:my-4 tw:items-center">
<Button loading>Loading</Button>
<Button>Primary</Button>
<Button disabled>Disabled</Button>
</div>
<div className="tw:flex tw:gap-4 tw:my-4 tw:items-center">
<Button variant="secondary" loading>
Secondary
</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="secondary" disabled>
Disabled
</Button>
</div>
<div className="tw:flex tw:gap-4 tw:my-4 tw:items-center">
<Button variant="danger" loading>
Danger
</Button>
<Button variant="danger">Danger</Button>
<Button variant="danger" disabled>
Disabled
</Button>
</div>
<div className="tw:my-4">
<h3>Design tokens for variants</h3>
<p className="tw:text-base">
Primary button background: <code>--dbv-kit-btn-primary-background</code>
</p>
<p className="tw:text-base">
Primary button background (hover): <code>--dbv-kit-btn-primary-background-hover</code>
</p>
<p className="tw:text-base">
Primary button background (active): <code>--dbv-kit-btn-primary-background-active</code>
</p>
<p className="tw:text-base">
Secondary button background: <code>--dbv-kit-btn-secondary-background</code>
</p>
<p className="tw:text-base">
Secondary button background (hover): <code>--dbv-kit-btn-secondary-background-hover</code>
</p>
<p className="tw:text-base">
Secondary button background (active): <code>--dbv-kit-btn-secondary-background-active</code>
</p>
<p className="tw:text-base">
Secondary button border color: <code>--dbv-kit-btn-secondary-border-color</code>
</p>
<p className="tw:text-base">
Danger button background: <code>--dbv-kit-btn-danger-background</code>
</p>
<p className="tw:text-base">
Danger button background (hover): <code>--dbv-kit-btn-danger-background-hover</code>
</p>
<p className="tw:text-base">
Danger button background (active): <code>--dbv-kit-btn-danger-background-active</code>
</p>
</div>
</div>
);
export const Sizes = () => (
<div>
<h2 className="tw:text-lg tw:my-2">Sizes</h2>
<p>Button component has 4 predefined sizes: small, medium, large, and extra large. Check the examples below:</p>
<div className="tw:flex tw:flex-col tw:gap-4">
<Button size="small">Small</Button>
<Button size="medium">Medium</Button>
<Button size="large">Large button</Button>
<Button size="xlarge">EXTRA Large button</Button>
</div>
<h3>Design tokens for sizes</h3>
<p>
The Button component uses the following design tokens to define the sizes of the buttons. You can customize these tokens to change the button
sizes.
</p>
<div className="tw:my-4">
<p className="tw:text-base">
Small button height: <code>--dbv-kit-btn-small-height</code>
</p>
<p className="tw:text-base">
Medium button height: <code>--dbv-kit-btn-medium-height</code>
</p>
<p className="tw:text-base">
Large button height: <code>--dbv-kit-btn-large-height</code>
</p>
<p className="tw:text-base">
Extra large button height: <code>--dbv-kit-btn-xlarge-height</code>
</p>
</div>
</div>
);
export const Icons = () => (
<div>
<h2>Icons</h2>
<h3>&lt;ButtonIcon&gt;</h3>
<code>.dbv-kit-button__icon</code>
<p>
To properly place an icon inside a button, you have to use ButtonIcon component. That component will compensate outer padding to balance the
button view. You need to specify the placement property to adjust the icon position.
</p>
<dl>
<dt className="tw:font-semibold">placement</dt>
<dd>start | end</dd>
</dl>
<div className="codeblock">
<code>
&lt;Button&gt; <br /> &nbsp;&nbsp;&lt;ButtonIcon placement="start"/&gt;
<br />
&nbsp; Text
<br /> &lt;Button/&gt;
</code>
</div>
<div>
<h4>Compare buttons:</h4>
<div className="tw:flex tw:gap-4 tw:items-center tw:my-4">
<Button variant="secondary">
<ButtonIcon placement="start">🧤</ButtonIcon>
Text
</Button>
<Button variant="secondary">🧤 Text</Button>
</div>
<p>
The left button uses ButtonIcon component and looks more balanced. If you feel that in your case it's not needed, feel free to not use the
<b> ButtonIcon </b> component.
</p>
</div>
<h3>Tokens</h3>
<div>
<code>--dbv-kit-btn-icon-margin-inline</code> - the margin between the icon and the text, by default calculated based on{' '}
<code>--dbv-kit-btn-padding-inline</code> for each size.
</div>
<h3>Examples</h3>
<p>
Here are some examples of how to use the Button component with icons. Don't forget to check the source code by pressing <kbd>s</kbd>
</p>
<div className="tw:flex tw:gap-4 tw:my-4 tw:items-center">
<Button size="small">
Love
<ButtonIcon placement="end">❤️</ButtonIcon>
</Button>
<Button className="tw:text-lime-300">
Have you seen
<ButtonIcon className="w-2">
<svg width="16" height="16" fill="none">
<g strokeWidth="0"></g>
<g strokeLinecap="round" strokeLinejoin="round"></g>
<g>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M8 16L3.54223 12.3383C1.93278 11.0162 1 9.04287 1 6.96005C1 3.11612 4.15607 0 8 0C11.8439 0 15 3.11612 15 6.96005C15 9.04287 14.0672 11.0162 12.4578 12.3383L8 16ZM3 6H5C6.10457 6 7 6.89543 7 8V9L3 7.5V6ZM11 6C9.89543 6 9 6.89543 9 8V9L13 7.5V6H11Z"
fill="currentColor"
></path>
</g>
</svg>
</ButtonIcon>
UFO?
</Button>
<Button size="large">
<ButtonIcon placement="start">🎾</ButtonIcon>
Tennis
</Button>
<Button size="xlarge">
<ButtonIcon placement="start">🎾</ButtonIcon>
Tennis is Love
<ButtonIcon placement="end">❤️</ButtonIcon>
</Button>
</div>
<div className="tw:flex tw:gap-4 tw:my-4 tw:items-center">
<Button loading>
<ButtonIcon className="tw:w-8 tw:h-4" placement="start">
<svg width="16" height="16" fill="none">
<g strokeWidth="0"></g>
<g strokeLinecap="round" strokeLinejoin="round"></g>
<g>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M8 16L3.54223 12.3383C1.93278 11.0162 1 9.04287 1 6.96005C1 3.11612 4.15607 0 8 0C11.8439 0 15 3.11612 15 6.96005C15 9.04287 14.0672 11.0162 12.4578 12.3383L8 16ZM3 6H5C6.10457 6 7 6.89543 7 8V9L3 7.5V6ZM11 6C9.89543 6 9 6.89543 9 8V9L13 7.5V6H11Z"
fill="currentColor"
></path>
</g>
</svg>
</ButtonIcon>
UFO
</Button>
<Button variant="secondary" loading>
<ButtonIcon placement="start">🎾</ButtonIcon>
Tennis
</Button>
<Button disabled>
<ButtonIcon placement="start">🎾</ButtonIcon>
Tennis
</Button>
<Button variant="danger">
<ButtonIcon placement="start">🎾</ButtonIcon>
Tennis
</Button>
<Button>
<ButtonIcon>🎾</ButtonIcon>
</Button>
</div>
</div>
);
const CustomLoader = () => (
<div>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" className="tw:animate-spin tw:p-1">
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeDasharray="31.415, 31.415" />
</svg>
</div>
);
export const Loading = () => {
const [loading, setLoading] = useState(true);
function toggleLoading() {
setLoading(prev => !prev);
}
return (
<div>
<h2>Loading</h2>
<h3>Design tokens</h3>
<p>
<code>--dbv-kit-btn-loader-base-color:</code> var(--tw-color-white);{' '}
<span className="comment">
// This color used in loader to mix with other button colors like{' '}
<i> color: color-mix(in srgb, var(--dbv-kit-btn-foreground) 25%, var(--dbv-kit-btn-loader-base-color));</i> It should be light in light mode
and one of the dark colors for dark theme.
</span>
</p>
<label>
Enable loaders <input type="checkbox" checked={loading} onChange={toggleLoading} />
</label>
<h3>Default loader</h3>
<p>Button component has a default loader that appears when the loading property is set to true.</p>
<div className="tw:flex tw:gap-4 tw:my-4 tw:items-center">
<Button loading={loading}>Primary</Button>
<Button variant="secondary" loading={loading}>
Secondary
</Button>
<Button variant="danger" loading={loading}>
Danger
</Button>
</div>
<h3> Custom loader</h3>
<p>Buttons support custom loaders.</p>
<div className="tw:flex tw:gap-4 tw:my-4 tw:items-center">
<Button loading={loading} loader={<span className="tw:flex tw:items-center tw:animate-spin">⚽️</span>}>
Loading
</Button>
<Button loading={loading} loader={<span className="tw:absolute tw:animate-bounce">🚴</span>}>
Loading
</Button>
<Button loading={loading} loader={<CustomLoader />}>
Custom SVG Loader
</Button>
</div>
</div>
);
};
export const WithCustomRendering = () => {
return (
<div>
<h3 className="tw:text-lg tw:my-2">Custom renders</h3>
<p>
Button can be rendered as different HTML element using <code>render</code> property. Read more{' '}
<a href="https://ariakit.org/reference/button#render">in AriaKit documentation</a>
</p>
<div className="tw:flex tw:gap-4 tw:my-4 tw:items-center">
<Button render={<a target="_blank" href="/" />} size="small">
Link button
</Button>
<Button variant="secondary" render={<a />}>
Link secondary
</Button>
<Button render={({ children, className }) => <p className={className}>{children} render</p>} size="medium">
Paragraph
</Button>
</div>
<h3 className="tw:text-lg tw:my-2">Change on focus</h3>
<div className="tw:flex tw:gap-4 tw:my-4 tw:items-center">
<Button onFocusVisible={e => (e.currentTarget.textContent = 'Click me!')} render={<a href="/" />} size="small">
Link button
</Button>
</div>
</div>
);
};
+1
View File
@@ -0,0 +1 @@
/// <reference types="vite/client" />
@@ -0,0 +1,26 @@
{
"extends": "@cloudbeaver/tsconfig/tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"tsBuildInfoFile": "dist/tsconfig.tsbuildinfo",
"composite": true
},
"references": [
{
"path": "../../common-react/@dbeaver/ui-kit"
}
],
"include": [
"__custom_mocks__/**/*",
"src/**/*",
"src/**/*.json",
"src/**/*.css",
"src/**/*.scss"
],
"exclude": [
"**/node_modules",
"dist/**/*",
"lib/**/*"
]
}
+8
View File
@@ -0,0 +1,8 @@
{
"files": [],
"references": [
{
"path": "../../common-react/@dbeaver/ui-kit"
}
]
}
@@ -0,0 +1,32 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2023",
"lib": [
"ES2023"
],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": [
"vite.config.ts"
],
"references": [
{
"path": "../../common-react/@dbeaver/ui-kit"
}
]
}
+26
View File
@@ -0,0 +1,26 @@
/*
* 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 { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { tscPlugin } from '@wroud/vite-plugin-tsc';
import { assetResolverPlugin } from '@wroud/vite-plugin-asset-resolver';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [
react(),
tscPlugin({
tscArgs: ['-b'],
prebuild: true,
enableOverlay: true,
}),
assetResolverPlugin(),
tailwindcss(),
],
});
+792 -15
View File
File diff suppressed because it is too large Load Diff