adds layers to InputField and moves border-offset-layout

This commit is contained in:
sergeyteleshev
2025-09-30 13:39:53 +02:00
parent db8049b56b
commit 272baafab6
5 changed files with 66 additions and 67 deletions
@@ -58,28 +58,24 @@
/* Sizes */
.dbv-kit-input--small {
--dbv-kit-control-outline-offset: 0px;
--dbv-kit-input-height: var(--dbv-kit-input-small-height);
--dbv-kit-input-padding: var(--dbv-kit-input-small-padding);
--dbv-kit-input-font-size: var(--dbv-kit-input-small-font-size);
}
.dbv-kit-input--medium {
--dbv-kit-control-outline-offset: -2px;
--dbv-kit-input-height: var(--dbv-kit-input-medium-height);
--dbv-kit-input-padding: var(--dbv-kit-input-medium-padding);
--dbv-kit-input-font-size: var(--dbv-kit-input-medium-font-size);
}
.dbv-kit-input--large {
--dbv-kit-control-outline-offset: -2px;
--dbv-kit-input-height: var(--dbv-kit-input-large-height);
--dbv-kit-input-padding: var(--dbv-kit-input-large-padding);
--dbv-kit-input-font-size: var(--dbv-kit-input-large-font-size);
}
.dbv-kit-input--xlarge {
--dbv-kit-control-outline-offset: -2px;
--dbv-kit-input-height: var(--dbv-kit-input-xlarge-height);
--dbv-kit-input-padding: var(--dbv-kit-input-xlarge-padding);
--dbv-kit-input-font-size: var(--dbv-kit-input-xlarge-font-size);
@@ -0,0 +1,56 @@
/*
* 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 {
.dbv-kit-input {
--dbv-kit-control-outline-offset: -2px;
}
.input-field--label {
display: block;
composes: theme-typography--body1 from global;
font-weight: 500;
}
.input-field--label:not(:empty) {
padding-bottom: 10px;
}
.input-field--container {
position: relative;
}
.input-field--loader-container,
.input-field--icon-container {
position: absolute;
right: 4px;
top: 50%;
transform: translateY(-50%);
width: 24px;
height: 24px;
--dbv-kit-icon-btn-outline-offset: -2px;
}
.input-field--custom-icon-container {
composes: input-field--icon-container;
right: 6px;
width: 24px;
height: 24px;
cursor: auto;
display: flex;
align-items: center;
justify-content: center;
}
.input-field--input[disabled] + .input-field--icon-container {
cursor: auto;
}
.input-field--input:not(:only-child) {
padding-right: 32px !important;
}
.input-field--input {
font-size: 12px;
}
}
@@ -1,49 +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.
*/
.fieldLabel {
display: block;
composes: theme-typography--body1 from global;
font-weight: 500;
}
.fieldLabel:not(:empty) {
padding-bottom: 10px;
}
.inputContainer {
position: relative;
}
.loaderContainer,
.iconContainer {
position: absolute;
right: 4px;
top: 50%;
transform: translateY(-50%);
width: 24px;
height: 24px;
--dbv-kit-icon-btn-outline-offset: -2px;
}
.customIconContainer {
composes: iconContainer;
right: 6px;
width: 24px;
height: 24px;
cursor: auto;
display: flex;
align-items: center;
justify-content: center;
}
.input[disabled] + .iconContainer {
cursor: auto;
}
.input:not(:only-child) {
padding-right: 32px !important;
}
.input {
font-size: 12px;
}
@@ -14,17 +14,15 @@ import { filterLayoutFakeProps, getLayoutProps } from '../../Containers/filterLa
import type { ILayoutSizeProps } from '../../Containers/ILayoutSizeProps.js';
import { Icon } from '../../Icon.js';
import { useTranslate } from '../../localization/useTranslate.js';
import { s } from '../../s.js';
import { useCombinedHandler } from '../../useCombinedHandler.js';
import { useCombinedRef } from '../../useCombinedRef.js';
import { useS } from '../../useS.js';
import { useStateDelay } from '../../useStateDelay.js';
import { Field } from '../Field.js';
import { FieldDescription } from '../FieldDescription.js';
import { FieldLabel } from '../FieldLabel.js';
import { useCapsLockTracker } from '../useCapsLockTracker.js';
import inputFieldStyle from './InputField.module.css';
import { IconButton, Input, Spinner, type InputProps } from '@dbeaver/ui-kit';
import './InputField.css';
import { clsx, IconButton, Input, Spinner, type InputProps } from '@dbeaver/ui-kit';
export type InputFieldBaseProps = Omit<InputProps, 'onChange'> &
ILayoutSizeProps & {
@@ -70,7 +68,6 @@ export const InputFieldBase = observer<InputFieldBaseProps, HTMLInputElement>(
const translate = useTranslate();
const layoutProps = getLayoutProps(rest);
rest = filterLayoutFakeProps(rest);
const styles = useS(inputFieldStyle);
loading = useStateDelay(loading ?? false, 300);
const revealPassword = useCallback(() => {
@@ -116,11 +113,11 @@ export const InputFieldBase = observer<InputFieldBaseProps, HTMLInputElement>(
}
return (
<Field {...layoutProps} className={s(styles, {}, className)}>
<FieldLabel htmlFor={inputId} title={labelTooltip || rest.title} className={s(styles, { fieldLabel: true })} required={required}>
<Field {...layoutProps} className={clsx('input-field', className)}>
<FieldLabel htmlFor={inputId} title={labelTooltip || rest.title} className="input-field--field-label" required={required}>
{children}
</FieldLabel>
<div className={s(styles, { inputContainer: true })}>
<div className="input-field--input-container">
<Input
ref={mergedRef}
{...rest}
@@ -129,14 +126,14 @@ export const InputFieldBase = observer<InputFieldBaseProps, HTMLInputElement>(
name={name}
value={uncontrolled ? undefined : value}
defaultValue={defaultValue}
className={s(styles, { input: true })}
className="input-field--input"
required={required}
onChange={handleChange}
onBlur={handleBlur}
onKeyDown={handleKeyDown}
/>
{loading && (
<div title={translate('ui_processing_loading')} className={s(styles, { loaderContainer: true })}>
<div title={translate('ui_processing_loading')} className="input-field--loader-container">
<Spinner size="small" />
</div>
)}
@@ -146,7 +143,7 @@ export const InputFieldBase = observer<InputFieldBaseProps, HTMLInputElement>(
size="small"
aria-label={translate('ui_reveal_password')}
title={translate('ui_reveal_password')}
className={styles['iconContainer']}
className="input-field--icon-container"
onClick={revealPassword}
>
<Icon width={16} height={16} name={passwordRevealed ? 'password-hide' : 'password-show'} viewBox="0 0 16 16" />
@@ -157,13 +154,13 @@ export const InputFieldBase = observer<InputFieldBaseProps, HTMLInputElement>(
size="small"
aria-label={translate('ui_copy_to_clipboard')}
title={translate('ui_copy_to_clipboard')}
className={styles['iconContainer']}
className="input-field--icon-container"
onClick={onCustomCopy}
>
<Icon width={16} height={16} name="copy" viewBox="0 0 32 32" />
</IconButton>
)}
{icon && <div className={s(styles, { customIconContainer: true })}>{icon}</div>}
{icon && <div className="input-field--custom-icon-container">{icon}</div>}
</div>
{(description || passwordType) && <FieldDescription invalid={error}>{description}</FieldDescription>}
</Field>
-1
View File
@@ -183,7 +183,6 @@ export * from './FormControls/ComboboxLoader.js';
export * from './FormControls/FormContext.js';
export * from './FormControls/FormFieldDescription.js';
export * from './FormControls/InputField/InputField.js';
export { default as InputFieldStyles } from './FormControls/InputField/InputField.module.css';
export * from './FormControls/InputFiles.js';
export * from './FormControls/InputFileTextContent.js';
export * from './FormControls/Radio.js';