This is an automated email from the ASF dual-hosted git repository.

shuai pushed a commit to branch feat/schema-form
in repository https://gitbox.apache.org/repos/asf/answer.git

commit 9b7c2bd85ab91b18d0044b51955a3878168b2117
Author: shuai <lishuail...@sifou.com>
AuthorDate: Fri Aug 8 10:20:46 2025 +0800

    feat: schemeForm support tagSelector component
---
 .../SchemaForm/components/TagSelector.tsx          | 66 ++++++++++++++++++++++
 ui/src/components/SchemaForm/components/index.ts   |  2 +
 ui/src/components/SchemaForm/index.tsx             | 13 ++++-
 ui/src/components/SchemaForm/types.ts              |  6 +-
 4 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/ui/src/components/SchemaForm/components/TagSelector.tsx 
b/ui/src/components/SchemaForm/components/TagSelector.tsx
new file mode 100644
index 00000000..f23b14f6
--- /dev/null
+++ b/ui/src/components/SchemaForm/components/TagSelector.tsx
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { FC } from 'react';
+
+import { TagSelector } from '@/components';
+import type * as Type from '@/common/interface';
+
+interface Props {
+  maxTagLength?: number;
+  description?: string;
+  fieldName: string;
+  onChange?: (fd: Type.FormDataType) => void;
+  formData: Type.FormDataType;
+}
+const Index: FC<Props> = ({
+  description,
+  maxTagLength,
+  fieldName,
+  onChange,
+  formData,
+}) => {
+  const fieldObject = formData[fieldName];
+  const handleChange = (data: Type.Tag[]) => {
+    const state = {
+      ...formData,
+      [fieldName]: {
+        ...formData[fieldName],
+        value: data,
+        isInvalid: false,
+      },
+    };
+    if (typeof onChange === 'function') {
+      onChange(state);
+    }
+  };
+
+  return (
+    <TagSelector
+      value={fieldObject?.value || []}
+      onChange={handleChange}
+      maxTagLength={maxTagLength || 0}
+      isInvalid={fieldObject?.isInvalid}
+      formText={description}
+      errMsg={fieldObject?.errorMsg}
+    />
+  );
+};
+
+export default Index;
diff --git a/ui/src/components/SchemaForm/components/index.ts 
b/ui/src/components/SchemaForm/components/index.ts
index df28f4ac..2a75307d 100644
--- a/ui/src/components/SchemaForm/components/index.ts
+++ b/ui/src/components/SchemaForm/components/index.ts
@@ -27,6 +27,7 @@ import Textarea from './Textarea';
 import Input from './Input';
 import Button from './Button';
 import InputGroup from './InputGroup';
+import TagSelector from './TagSelector';
 
 export {
   Legend,
@@ -39,4 +40,5 @@ export {
   Input,
   Button,
   InputGroup,
+  TagSelector,
 };
diff --git a/ui/src/components/SchemaForm/index.tsx 
b/ui/src/components/SchemaForm/index.tsx
index 6b7cbbf0..421e0b1e 100644
--- a/ui/src/components/SchemaForm/index.tsx
+++ b/ui/src/components/SchemaForm/index.tsx
@@ -51,6 +51,7 @@ import {
   Input,
   Button as SfButton,
   InputGroup,
+  TagSelector,
 } from './components';
 
 export * from './types';
@@ -258,6 +259,7 @@ const SchemaForm: ForwardRefRenderFunction<FormRef, 
FormProps> = (
           description,
           enum: enumValues = [],
           enumNames = [],
+          max_length = 0,
         } = properties[key];
         const { 'ui:widget': widget = 'input', 'ui:options': uiOpt } =
           uiSchema?.[key] || {};
@@ -413,11 +415,20 @@ const SchemaForm: ForwardRefRenderFunction<FormRef, 
FormProps> = (
                 />
               </InputGroup>
             ) : null}
+            {widget === 'tag_selector' ? (
+              <TagSelector
+                maxTagLength={max_length}
+                fieldName={key}
+                onChange={onChange}
+                formData={formData}
+                description={description}
+              />
+            ) : null}
             {/* Unified handling of `Feedback` and `Text` */}
             <Form.Control.Feedback type="invalid">
               {fieldState?.errorMsg}
             </Form.Control.Feedback>
-            {description ? (
+            {description && widget !== 'tag_selector' ? (
               <Form.Text dangerouslySetInnerHTML={{ __html: description }} />
             ) : null}
           </Form.Group>
diff --git a/ui/src/components/SchemaForm/types.ts 
b/ui/src/components/SchemaForm/types.ts
index 8347b98f..db1aa8a5 100644
--- a/ui/src/components/SchemaForm/types.ts
+++ b/ui/src/components/SchemaForm/types.ts
@@ -44,12 +44,13 @@ export interface JSONSchema {
   required?: string[];
   properties: {
     [key: string]: {
-      type: 'string' | 'boolean' | 'number';
+      type?: 'string' | 'boolean' | 'number';
       title: string;
       description?: string;
       enum?: Array<string | boolean | number>;
       enumNames?: string[];
       default?: string | boolean | number | any[];
+      max_length?: number;
     };
   };
 }
@@ -152,7 +153,8 @@ export type UIWidget =
   | 'switch'
   | 'legend'
   | 'button'
-  | 'input_group';
+  | 'input_group'
+  | 'tag_selector';
 export interface UISchema {
   [key: string]: {
     'ui:widget'?: UIWidget;

Reply via email to