Introduce new combobox and make it work with chip input

We introduced a new accessible combobox component. This component is based on headless ui and made compatible with our components and forms. Also we replaced the outdated `Autocomplete` component with the new combobox.

Co-authored-by: Konstantin Schaper <konstantin.schaper@cloudogu.com>

Reviewed-by: Florian Scholdei <florian.scholdei@cloudogu.com>
This commit is contained in:
Eduard Heimbuch
2023-06-19 13:04:26 +02:00
parent e4d846b0d4
commit bc2a599b2c
39 changed files with 1119 additions and 276 deletions

View File

@@ -26,12 +26,13 @@ import React, { ComponentProps } from "react";
import { Controller, ControllerRenderProps, Path } from "react-hook-form";
import { useScmFormContext } from "../ScmFormContext";
import { useScmFormPathContext } from "../FormPathContext";
import { prefixWithoutIndices } from "../helpers";
import { defaultOptionFactory, prefixWithoutIndices } from "../helpers";
import classNames from "classnames";
import ChipInputField from "./ChipInputField";
import { Option } from "@scm-manager/ui-types";
type Props<T extends Record<string, unknown>> = Omit<
ComponentProps<typeof ChipInputField>,
Parameters<typeof ChipInputField>[0],
"error" | "createDeleteText" | "label" | "defaultChecked" | "required" | keyof ControllerRenderProps
> & {
rules?: ComponentProps<typeof Controller>["rules"];
@@ -39,6 +40,7 @@ type Props<T extends Record<string, unknown>> = Omit<
label?: string;
defaultValue?: string[];
createDeleteText?: (value: string) => string;
optionFactory?: (val: any) => Option<unknown>;
};
/**
@@ -56,6 +58,8 @@ function ControlledChipInputField<T extends Record<string, unknown>>({
placeholder,
className,
createDeleteText,
children,
optionFactory = defaultOptionFactory,
...props
}: Props<T>) {
const { control, t, readOnly: formReadonly } = useScmFormContext();
@@ -73,12 +77,14 @@ function ControlledChipInputField<T extends Record<string, unknown>>({
name={nameWithPrefix}
rules={rules}
defaultValue={defaultValue}
render={({ field, fieldState }) => (
render={({ field: { value, onChange, ...field }, fieldState }) => (
<ChipInputField
label={labelTranslation}
helpText={helpTextTranslation}
placeholder={placeholderTranslation}
aria-label={ariaLabelTranslation}
value={value ? value.map(optionFactory) : []}
onChange={(selectedOptions) => onChange(selectedOptions.map((item) => item.value))}
{...props}
{...field}
readOnly={readOnly ?? formReadonly}
@@ -89,7 +95,9 @@ function ControlledChipInputField<T extends Record<string, unknown>>({
: undefined
}
testId={testId ?? `input-${nameWithPrefix}`}
/>
>
{children}
</ChipInputField>
)}
/>
);