diff --git a/site/src/components/RichParameterInput/RichParameterInput.tsx b/site/src/components/RichParameterInput/RichParameterInput.tsx index beaff8ca2772e..84fe47bbbfee3 100644 --- a/site/src/components/RichParameterInput/RichParameterInput.tsx +++ b/site/src/components/RichParameterInput/RichParameterInput.tsx @@ -19,7 +19,7 @@ import type { AutofillBuildParameter, AutofillSource, } from "utils/richParameters"; -import { MultiTextField } from "./MultiTextField"; +import { TagInput } from "../TagInput/TagInput"; const isBoolean = (parameter: TemplateVersionParameter) => { return parameter.type === "bool"; @@ -372,7 +372,7 @@ const RichParameterField: FC = ({ } return ( - = { + title: "components/TagInput", + component: TagInput, + decorators: [(Story) =>
{Story()}
], +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + values: [], + }, +}; + +export const WithEmptyTags: Story = { + args: { + values: ["", "", ""], + }, +}; + +export const WithLongTags: Story = { + args: { + values: [ + "this-is-a-very-long-long-long-tag-that-might-wrap", + "another-long-tag-example", + "short", + ], + }, +}; + +export const WithManyTags: Story = { + args: { + values: [ + "tag1", + "tag2", + "tag3", + "tag4", + "tag5", + "tag6", + "tag7", + "tag8", + "tag9", + "tag10", + "tag11", + "tag12", + "tag13", + "tag14", + "tag15", + "tag16", + "tag17", + "tag18", + "tag19", + "tag20", + ], + }, +}; diff --git a/site/src/components/RichParameterInput/MultiTextField.tsx b/site/src/components/TagInput/TagInput.tsx similarity index 56% rename from site/src/components/RichParameterInput/MultiTextField.tsx rename to site/src/components/TagInput/TagInput.tsx index aed995299dbf3..40e89625502a6 100644 --- a/site/src/components/RichParameterInput/MultiTextField.tsx +++ b/site/src/components/TagInput/TagInput.tsx @@ -1,27 +1,39 @@ -import type { Interpolation, Theme } from "@emotion/react"; import Chip from "@mui/material/Chip"; import FormHelperText from "@mui/material/FormHelperText"; -import type { FC } from "react"; +import { type FC, useId, useMemo } from "react"; -export type MultiTextFieldProps = { +export type TagInputProps = { label: string; id?: string; values: string[]; onChange: (values: string[]) => void; }; -export const MultiTextField: FC = ({ +export const TagInput: FC = ({ label, id, values, onChange, }) => { + const baseId = useId(); + + const itemIds = useMemo(() => { + return Array.from( + { length: values.length }, + (_, index) => `${baseId}-item-${index}`, + ); + }, [baseId, values.length]); + return (
-
); }; - -const styles = { - root: (theme) => ({ - border: `1px solid ${theme.palette.divider}`, - borderRadius: 8, - minHeight: 48, // Chip height + paddings - padding: "10px 14px", - fontSize: 16, - display: "flex", - flexWrap: "wrap", - gap: 8, - position: "relative", - margin: "8px 0 4px", // Have same margin than TextField - - "&:has(input:focus)": { - borderColor: theme.palette.primary.main, - borderWidth: 2, - // Compensate for the border width - top: -1, - left: -1, - }, - }), - - input: { - flexGrow: 1, - fontSize: "inherit", - padding: 0, - border: "none", - background: "none", - - "&:focus": { - outline: "none", - }, - }, -} satisfies Record>; diff --git a/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx b/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx index 9ec69158c4e84..dd1f52d73b07d 100644 --- a/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx +++ b/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx @@ -24,6 +24,7 @@ import { } from "components/Select/Select"; import { Slider } from "components/Slider/Slider"; import { Switch } from "components/Switch/Switch"; +import { TagInput } from "components/TagInput/TagInput"; import { Textarea } from "components/Textarea/Textarea"; import { Tooltip, @@ -198,21 +199,7 @@ const ParameterField: FC = ({ ); case "multi-select": { - let values: string[] = []; - - if (value) { - try { - const parsed = JSON.parse(value); - if (Array.isArray(parsed)) { - values = parsed; - } - } catch (e) { - console.error( - "Error parsing parameter value with form_type multi-select", - e, - ); - } - } + const values = parseStringArrayValue(value); // Map parameter options to MultiSelectCombobox options format const options: Option[] = parameter.options.map((opt) => ({ @@ -259,6 +246,21 @@ const ParameterField: FC = ({ ); } + case "tag-select": { + const values = parseStringArrayValue(value); + + return ( + { + onChange(JSON.stringify(values)); + }} + /> + ); + } + case "switch": return ( = ({ } }; +const parseStringArrayValue = (value: string): string[] => { + let values: string[] = []; + + if (value) { + try { + const parsed = JSON.parse(value); + if (Array.isArray(parsed)) { + values = parsed; + } + } catch (e) { + console.error("Error parsing parameter of type list(string)", e); + } + } + + return values; +}; + interface OptionDisplayProps { option: PreviewParameterOption; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy