From e4059a6b09b7cf7a68ddd0648d0f436ed6050c7d Mon Sep 17 00:00:00 2001 From: Ida Date: Wed, 27 May 2026 10:38:01 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Filter=20zur=C3=BCcksetzen=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FilterSearchInput.module.css | 48 +++++++++++++ .../FilterSearchInput/FilterSearchInput.tsx | 69 +++++++++++++++++++ .../FormGenerator/FilterSearchInput/index.ts | 2 + .../FormGeneratorControls.module.css | 2 +- .../FormGeneratorControls.tsx | 12 ++-- .../FormGeneratorTable/FormGeneratorTable.tsx | 20 ++---- 6 files changed, 132 insertions(+), 21 deletions(-) create mode 100644 src/components/FormGenerator/FilterSearchInput/FilterSearchInput.module.css create mode 100644 src/components/FormGenerator/FilterSearchInput/FilterSearchInput.tsx create mode 100644 src/components/FormGenerator/FilterSearchInput/index.ts diff --git a/src/components/FormGenerator/FilterSearchInput/FilterSearchInput.module.css b/src/components/FormGenerator/FilterSearchInput/FilterSearchInput.module.css new file mode 100644 index 0000000..9756ac2 --- /dev/null +++ b/src/components/FormGenerator/FilterSearchInput/FilterSearchInput.module.css @@ -0,0 +1,48 @@ +.wrapper { + position: relative; + width: 100%; +} + +.input { + width: 100%; + padding: 3px 30px 3px 6px; + font-size: 12px; + border: 1px solid var(--border-color, #ccc); + border-radius: 3px; + outline: none; + box-sizing: border-box; + background: var(--color-bg, #fff); + color: var(--color-text, #334155); +} + +.input:focus { + border-color: var(--primary-color, #F25843); +} + +.input::placeholder { + color: var(--color-text-muted, #94a3b8); +} + +.clearBtn { + position: absolute; + right: 5px; + top: 3px; + bottom: 3px; + display: inline-flex; + align-items: center; + justify-content: center; + width: 25px; + padding: 0; + border: none; + border-radius: 3px; + background: none; + cursor: pointer; + font-size: 25px; + line-height: 1; + color: var(--color-text-secondary, #94a3b8); +} + +.clearBtn:hover { + background: none; + color: var(--color-text-secondary, #94a3b8); +} diff --git a/src/components/FormGenerator/FilterSearchInput/FilterSearchInput.tsx b/src/components/FormGenerator/FilterSearchInput/FilterSearchInput.tsx new file mode 100644 index 0000000..00aaf29 --- /dev/null +++ b/src/components/FormGenerator/FilterSearchInput/FilterSearchInput.tsx @@ -0,0 +1,69 @@ +import React, { type Ref } from 'react'; +import styles from './FilterSearchInput.module.css'; + +export interface FilterSearchInputProps { + value: string; + onChange: (value: string) => void; + placeholder?: string; + inputRef?: Ref; + onInputClick?: (e: React.MouseEvent) => void; + onFocus?: () => void; + onBlur?: () => void; + /** When set, only `inputClassName` styles the input (for floating-label toolbar search). */ + variant?: 'compact' | 'inherit'; + inputClassName?: string; + wrapperClassName?: string; + clearTitle?: string; +} + +export function FilterSearchInput({ + value, + onChange, + placeholder = 'Filter...', + inputRef, + onInputClick, + onFocus, + onBlur, + variant = 'compact', + inputClassName, + wrapperClassName, + clearTitle = 'Eingabe löschen', +}: FilterSearchInputProps) { + const inputClass = variant === 'inherit' + ? inputClassName + : inputClassName + ? `${styles.input} ${inputClassName}` + : styles.input; + + return ( +
+ onChange(e.target.value)} + placeholder={placeholder} + className={inputClass} + onClick={onInputClick} + onFocus={onFocus} + onBlur={onBlur} + /> + {value && ( + + )} +
+ ); +} diff --git a/src/components/FormGenerator/FilterSearchInput/index.ts b/src/components/FormGenerator/FilterSearchInput/index.ts new file mode 100644 index 0000000..7b8e18a --- /dev/null +++ b/src/components/FormGenerator/FilterSearchInput/index.ts @@ -0,0 +1,2 @@ +export { FilterSearchInput } from './FilterSearchInput'; +export type { FilterSearchInputProps } from './FilterSearchInput'; diff --git a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.module.css b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.module.css index 329e7a3..6bf10a7 100644 --- a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.module.css +++ b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.module.css @@ -168,7 +168,7 @@ .searchInput { width: 100%; height: 40px; - padding: 8px 12px; + padding: 8px 28px 8px 12px; border: 1px solid var(--color-border, #E2E8F0); border-radius: 6px; font-size: 14px; diff --git a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx index e57fce2..7d23d9f 100644 --- a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx +++ b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx @@ -2,6 +2,7 @@ import React from 'react'; import type { IconType } from 'react-icons'; import { useLanguage } from '../../../providers/language/LanguageContext'; import styles from './FormGeneratorControls.module.css'; +import { FilterSearchInput } from '../FilterSearchInput'; import { Button } from '../../UiComponents/Button'; import { IoIosRefresh } from "react-icons/io"; import { FaTrash, FaDownload } from "react-icons/fa"; @@ -189,14 +190,15 @@ export function FormGeneratorControls({
{searchable && (
- onSearchChange(e.target.value)} + onChange={onSearchChange} + placeholder=" " onFocus={() => onSearchFocus(true)} onBlur={() => onSearchFocus(false)} - className={`${styles.searchInput} ${searchFocused || searchTerm ? styles.focused : ''}`} + inputClassName={`${styles.searchInput} ${searchFocused || searchTerm ? styles.focused : ''}`} + clearTitle={t('Suche löschen')} />