dbeaver/pro#5797 adds boilerplate for checkboxes (needs styles setting for CB)

This commit is contained in:
sergeyteleshev
2025-06-02 14:07:46 +02:00
parent 9c788a56cd
commit 0189684bed
12 changed files with 89 additions and 162 deletions
@@ -21,6 +21,12 @@
}
}
& .dbv-kit-checkbox__content {
display: flex;
flex-direction: column;
gap: var(--dbv-kit-checkbox-content-gap);
}
&[data-checked='true'] {
border-color: var(--dbv-kit-checkbox-border-color-checked);
}
@@ -16,11 +16,12 @@ import { componentProviderWrapper } from '../componentProviderWrapper.js';
export interface CheckboxProps extends Omit<AriaKitCheckboxProps, 'render' | 'size'> {
size?: ControlSize;
icon?: React.ReactNode;
caption?: string;
indeterminate?: boolean;
indeterminateIcon?: React.ReactNode;
}
export function CheckboxBase({ children, className, icon, indeterminate, indeterminateIcon, size = 'medium', ...props }: CheckboxProps) {
export function CheckboxBase({ children, className, icon, caption, indeterminate, indeterminateIcon, size = 'medium', ...props }: CheckboxProps) {
const [innerChecked, setInnerChecked] = useState(props.defaultChecked ?? false);
const checked = props.checked ?? innerChecked;
@@ -67,7 +68,10 @@ export function CheckboxBase({ children, className, icon, indeterminate, indeter
))}
</div>
<span className="dbv-kit-checkbox__text">{children}</span>
<div className="dbv-kit-checkbox__content">
<span className="dbv-kit-checkbox__text">{children}</span>
{caption && <span className="dbv-kit-checkbox__caption">{caption}</span>}
</div>
</label>
);
}
@@ -3,6 +3,7 @@
/* Checkbox sizes */
--dbv-kit-checkbox-height: var(--dbv-kit-control-height-medium);
--dbv-kit-checkbox-gap: calc(var(--tw-spacing) * 1.25);
--dbv-kit-checkbox-content-gap: calc(var(--tw-spacing) * 0.5);
--dbv-kit-checkbox-check-size: 0.5625;
/* Checkbox colors */
@@ -4,20 +4,22 @@
--dbv-kit-checkbox-small-font-size: calc(var(--dbv-kit-checkbox-font-size) * 0.875);
--dbv-kit-checkbox-small-height: var(--dbv-kit-control-height-small);
--dbv-kit-checkbox-small-gap: calc(var(--dbv-kit-checkbox-gap) * 0.5);
--dbv-kit-checkbox-small-content-gap: calc(var(--dbv-kit-checkbox-content-gap) * 0.5);
/* Medium checkbox */
--dbv-kit-checkbox-medium-font-size: var(--dbv-kit-checkbox-font-size);
--dbv-kit-checkbox-medium-height: var(--dbv-kit-control-height-medium);
--dbv-kit-checkbox-medium-gap: var(--dbv-kit-checkbox-gap);
--dbv-kit-checkbox-medium-content-gap: var(--dbv-kit-checkbox-content-gap);
/* Large checkbox */
--dbv-kit-checkbox-large-font-size: calc(var(--dbv-kit-checkbox-font-size) * 1.125);
--dbv-kit-checkbox-large-height: var(--dbv-kit-control-height-large);
--dbv-kit-checkbox-large-gap: calc(var(--dbv-kit-checkbox-gap) * 1.25);
--dbv-kit-checkbox-large-content-gap: calc(var(--dbv-kit-checkbox-content-gap) * 1.25);
/* Extra large checkbox */
--dbv-kit-checkbox-xlarge-font-size: calc(var(--dbv-kit-checkbox-font-size) * 1.25);
--dbv-kit-checkbox-xlarge-height: var(--dbv-kit-control-height-xlarge);
--dbv-kit-checkbox-xlarge-gap: calc(var(--dbv-kit-checkbox-gap) * 1.5);
--dbv-kit-checkbox-xlarge-content-gap: calc(var(--dbv-kit-checkbox-content-gap) * 1.5);
}
}
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* 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.
@@ -8,20 +8,21 @@
import { observer } from 'mobx-react-lite';
import { isControlPresented } from '../isControlPresented.js';
import { CheckboxMarkup, type CheckboxMod } from './CheckboxMarkup.js';
import { CheckboxMarkup } from './CheckboxMarkup.js';
import { type CheckboxOnChangeEvent, useCheckboxState } from './useCheckboxState.js';
import type { ControlSize } from '@dbeaver/ui-kit/types/controls';
export interface CheckboxBaseProps {
caption?: string;
mod?: CheckboxMod[];
ripple?: boolean;
indeterminate?: boolean;
inverse?: boolean;
size?: ControlSize;
variant?: 'primary' | 'secondary';
}
export type CheckboxInputProps = Omit<
React.InputHTMLAttributes<HTMLInputElement>,
'onChange' | 'type' | 'value' | 'defaultValue' | 'checked' | 'defaultChecked' | 'style'
'onChange' | 'type' | 'value' | 'defaultValue' | 'checked' | 'defaultChecked' | 'style' | 'size'
> & {
value?: string;
defaultValue?: string;
@@ -59,8 +60,6 @@ export const Checkbox: CheckboxType = observer(function Checkbox({
defaultChecked,
children,
inverse,
mod,
ripple,
className,
autoHide,
onChange,
@@ -81,16 +80,5 @@ export const Checkbox: CheckboxType = observer(function Checkbox({
return null;
}
return (
<CheckboxMarkup
{...rest}
name={name}
checked={checkboxState.checked}
label={label}
className={className}
mod={mod}
ripple={ripple}
onChange={checkboxState.change}
/>
);
return <CheckboxMarkup {...rest} name={name} checked={checkboxState.checked} label={label} className={className} onChange={checkboxState.change} />;
});
@@ -0,0 +1,38 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
@layer components {
.checkboxMarkup {
--dbv-kit-checkbox-background-checked: var(--theme-primary);
--dbv-kit-checkbox-icon-color: var(--theme-on-primary);
--dbv-kit-checkbox-check-size: 0.7;
--dbv-kit-checkbox-border-width: 2px;
--dbv-kit-checkbox-border-radius: 2px;
--dbv-kit-checkbox-border-color: color-mix(in srgb, var(--theme-on-secondary), white 20%);
--dbv-kit-checkbox-border-color-checked: transparent;
}
.dbv-kit-checkbox {
justify-content: center;
align-items: center;
}
.dbv-kit-checkbox__check {
margin: 0 12px;
}
.checkboxMarkup--secondary {
--dbv-kit-checkbox-background-checked: var(--theme-on-primary);
--dbv-kit-checkbox-icon-color: var(--theme-primary);
--dbv-kit-checkbox-border-color: var(--theme-on-primary);
--dbv-kit-checkbox-background: transparent;
--dbv-kit-checkbox-border-color-checked: var(--theme-on-primary);
}
}
@@ -1,74 +0,0 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
.checkbox {
composes: theme-checkbox from global;
box-sizing: content-box !important;
}
.checkboxInput {
composes: theme-checkbox_native-control from global;
}
.checkboxBackground {
composes: theme-checkbox__background from global;
box-sizing: border-box !important;
}
.checkboxCheckmark {
composes: theme-checkbox__checkmark from global;
}
.checkboxCheckmarkPath {
composes: theme-checkbox__checkmark-path from global;
}
.checkboxMixedmark {
composes: theme-checkbox__mixedmark from global;
}
.checkboxRipple {
composes: theme-checkbox__ripple from global;
}
.checkboxContainer {
display: flex;
align-items: center;
height: 32px;
}
.checkboxLabel {
composes: theme-typography--body2 from global;
cursor: pointer;
}
.checkboxCaption {
composes: theme-text-text-hint-on-light theme-typography--caption from global;
white-space: normal;
}
.primary {
composes: theme-checkbox_primary from global;
}
.surface {
composes: theme-checkbox_surface from global;
}
.small {
composes: theme-checkbox_small from global;
}
.small {
&.checkboxContainer {
& .checkbox {
width: 14px;
height: 14px;
}
& .checkboxBackground {
width: 14px;
height: 14px;
}
}
}
.disabled {
composes: theme-checkbox--disabled from global;
}
.checked {
composes: theme-checkbox--checked from global;
}
@@ -1,41 +1,37 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* 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 { useLayoutEffect, useRef } from 'react';
import { s } from '../../s.js';
import { useS } from '../../useS.js';
import CheckboxMarkupStyles from './CheckboxMarkup.module.css';
import { Checkbox as UiKitCheckbox, clsx } from '@dbeaver/ui-kit';
import './CheckboxMarkup.css';
import { useLayoutEffect, useRef } from 'react';
import type { ControlSize } from '@dbeaver/ui-kit/types/controls';
export type CheckboxMod = 'primary' | 'surface' | 'small';
interface ICheckboxMarkupProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'style'> {
interface ICheckboxMarkupProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'style' | 'size'> {
label?: string;
caption?: string;
indeterminate?: boolean;
ripple?: boolean;
mod?: CheckboxMod[];
size?: ControlSize;
variant?: 'primary' | 'secondary';
}
export { CheckboxMarkupStyles };
export const CheckboxMarkup: React.FC<ICheckboxMarkupProps> = function CheckboxMarkup({
id,
label,
indeterminate,
className,
size = 'small',
variant = 'primary',
title,
mod = ['primary'],
ripple = true,
readOnly,
caption,
...rest
}) {
const styles = useS(CheckboxMarkupStyles);
const checkboxRef = useRef<HTMLInputElement>(null);
useLayoutEffect(() => {
@@ -45,39 +41,10 @@ export const CheckboxMarkup: React.FC<ICheckboxMarkupProps> = function CheckboxM
});
return (
<div className={s(styles, { checkboxContainer: true, small: mod.includes('small') }, className)} title={title}>
<div
className={s(styles, {
checkbox: true,
disabled: rest.disabled,
checked: rest.checked,
primary: mod.includes('primary'),
surface: mod.includes('surface'),
small: mod.includes('small'),
})}
>
<input
ref={checkboxRef}
className={s(styles, { checkboxInput: true })}
type="checkbox"
{...rest}
disabled={rest.disabled || readOnly}
id={id || rest.name}
/>
<div className={s(styles, { checkboxBackground: true })}>
<svg className={s(styles, { checkboxCheckmark: true })} viewBox="0 0 24 24">
<path className={s(styles, { checkboxCheckmarkPath: true })} fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59" />
</svg>
<div className={s(styles, { checkboxMixedmark: true })} />
</div>
{ripple && <div className={s(styles, { checkboxRipple: true })} />}
</div>
{label && (id || rest.name) && (
<label className={s(styles, { checkboxLabel: true })} htmlFor={id || rest.name}>
{label}
{caption && <div className={s(styles, { checkboxCaption: true })}>{caption}</div>}
</label>
)}
<div className={clsx('checkboxMarkup', `checkboxMarkup--${variant}`, className)} title={title}>
<UiKitCheckbox ref={checkboxRef} id={id || rest.name} indeterminate={indeterminate} disabled={rest.disabled || readOnly} size={size} {...rest}>
{label}
</UiKitCheckbox>
</div>
);
};
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* 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.
@@ -70,7 +70,7 @@ export const MenuActionElement = observer<IMenuActionElementProps>(function Menu
>
<MenuItemElement
label={actionInfo.label}
icon={<Checkbox checked={checked} mod={['primary', 'small']} ripple={false} />}
icon={<Checkbox variant="secondary" checked={checked} size="small" />}
tooltip={actionInfo.tooltip}
loading={loading}
/>
@@ -89,11 +89,7 @@ export const MenuItemRenderer = observer<IMenuItemRendererProps>(function MenuIt
checked={item.checked}
onClick={() => onClick(false)}
>
<MenuItemElement
label={item.label}
icon={<Checkbox checked={item.checked} mod={['primary', 'small']} ripple={false} />}
tooltip={item.tooltip}
/>
<MenuItemElement label={item.label} icon={<Checkbox checked={item.checked} size="small" variant="secondary" />} tooltip={item.tooltip} />
</MenuItemCheckbox>
);
}
@@ -353,7 +353,6 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
name="saveCredentials"
state={optionsPart.state}
disabled={formState.isDisabled || readonly || optionsPart.state.sharedCredentials}
mod={['primary']}
title={translate(
!isSharedProject || serverConfigResource.data?.distributed
? 'connections_connection_authentication_save_credentials_for_user_tooltip'
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* 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.
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import {
CheckboxMarkupStyles,
// CheckboxMarkupStyles,
MenuItemElementStyles,
MenuItemStyles,
MenuPanelStyles,
@@ -27,7 +27,7 @@ import { MenuBarItemStyles, MenuBarStyles } from '@cloudbeaver/core-ui';
import TopMenuStyles from './shared/TopMenu.module.css';
import TopMenuBarStyles from './shared/TopMenuBar.module.css';
import TopMenuBarItemStyles from './shared/TopMenuBarItem.module.css';
import TopMenuCheckboxStyles from './shared/TopMenuCheckbox.module.css';
// import TopMenuCheckboxStyles from './shared/TopMenuCheckbox.module.css';
import TopMenuItemStyles from './shared/TopMenuItem.module.css';
import TopMenuItemElementStyles from './shared/TopMenuItemElement.module.css';
import TopMenuPanelStyles from './shared/TopMenuPanel.module.css';
@@ -88,13 +88,13 @@ const registry: StyleRegistry = [
styles: [TopMenuStyles],
},
],
[
CheckboxMarkupStyles,
{
mode: 'append',
styles: [TopMenuCheckboxStyles],
},
],
// [
// CheckboxMarkupStyles,
// {
// mode: 'append',
// styles: [TopMenuCheckboxStyles],
// },
// ],
];
export const TopNavBar: React.FC<Props> = observer(function TopNavBar({ container, className }) {