diff --git a/app/components/Btn/index.tsx b/app/components/Btn/index.tsx index c9ba305bf..9a65a50ba 100644 --- a/app/components/Btn/index.tsx +++ b/app/components/Btn/index.tsx @@ -42,7 +42,7 @@ export default function Btn(props: BtnProps) { } text-text-btn-primary `; break; case "danger": - btnClassName = `bg-danger-btn text-text-btn-danger hover:bg-hovered-btn`; + btnClassName = `bg-danger-btn text-text-btn-danger hover:bg-hovered-danger-btn`; break; default: btnClassName = `bg-default-btn text-text-btn-default hover:bg-hovered-btn`; diff --git a/app/components/Input/index.tsx b/app/components/Input/index.tsx index 9e28e886a..79826a4b4 100644 --- a/app/components/Input/index.tsx +++ b/app/components/Input/index.tsx @@ -4,7 +4,6 @@ import { DetailedHTMLProps, InputHTMLAttributes, useContext, - useEffect, useLayoutEffect, useState, } from "react"; @@ -17,6 +16,7 @@ export interface CommonInputProps > { className?: string; } + export interface NumberInputProps { onChange?: (v: number) => void; type?: "number"; @@ -49,12 +49,16 @@ export default function Input(props: CommonInputProps & InputProps) { const internalType = (show && "text") || type; - const { update } = useContext(List.ListContext); + const { update, handleValidate } = useContext(List.ListContext); useLayoutEffect(() => { update?.({ type: "input" }); }, []); + useLayoutEffect(() => { + handleValidate?.(value); + }, [value]); + return (
void; nextline?: boolean; + validator?: (v: any) => Error | Promise; } export const ListContext = createContext< - { isMobileScreen?: boolean; update?: (m: ChildrenMeta) => void } & WidgetStyle + { + isMobileScreen?: boolean; + update?: (m: ChildrenMeta) => void; + handleValidate?: (v: any) => void; + } & WidgetStyle >({ isMobileScreen: false }); export function ListItem(props: ListItemProps) { @@ -48,6 +63,7 @@ export function ListItem(props: ListItemProps) { subTitle, children, nextline, + validator, } = props; const context = useContext(ListContext); @@ -56,9 +72,11 @@ export function ListItem(props: ListItemProps) { const { inputNextLine, rangeNextLine } = context; + const { type, error } = childrenMeta; + let internalNextLine; - switch (childrenMeta.type) { + switch (type) { case "input": internalNextLine = !!(nextline || inputNextLine); break; @@ -70,7 +88,22 @@ export function ListItem(props: ListItemProps) { } const update = useCallback((m: ChildrenMeta) => { - setMeta(m); + setMeta((pre) => ({ ...pre, ...m })); + }, []); + + const handleValidate = useCallback((v: any) => { + const insideValidator = validator || (() => {}); + + Promise.resolve(insideValidator(v)).then((result) => { + if (result && result.error) { + return update({ + error: result.message, + }); + } + update({ + error: undefined, + }); + }); }, []); return ( @@ -88,13 +121,18 @@ export function ListItem(props: ListItemProps) {
{subTitle}
)}
- +
- {children} +
{children}
+ {!!error && ( +
+
{error}
+
+ )}
diff --git a/app/components/MenuLayout/index.tsx b/app/components/MenuLayout/index.tsx index 8145690c8..57f4c0c20 100644 --- a/app/components/MenuLayout/index.tsx +++ b/app/components/MenuLayout/index.tsx @@ -61,6 +61,7 @@ export default function MenuLayout<
diff --git a/app/components/Select/index.tsx b/app/components/Select/index.tsx index 728d97b41..640b98737 100644 --- a/app/components/Select/index.tsx +++ b/app/components/Select/index.tsx @@ -96,7 +96,7 @@ const Select = (props: SearchProps) => { className={selectClassName} >
svg { + filter: invert(0.5); + } } .export-content { diff --git a/app/components/mask.module.scss b/app/components/mask.module.scss index d66d98864..40c78a4d9 100644 --- a/app/components/mask.module.scss +++ b/app/components/mask.module.scss @@ -4,6 +4,10 @@ display: flex; flex-direction: column; + div:not(.no-dark) > svg { + filter: invert(0.5); + } + .mask-page-body { padding: 20px; overflow-y: auto; diff --git a/app/components/mask.tsx b/app/components/mask.tsx index 82d980686..24c726a60 100644 --- a/app/components/mask.tsx +++ b/app/components/mask.tsx @@ -398,7 +398,7 @@ export function ContextPrompts(props: { ); } -export function MaskPage() { +export function MaskPage(props: { className?: string }) { const navigate = useNavigate(); const maskStore = useMaskStore(); @@ -465,14 +465,13 @@ export function MaskPage() { }); }; - const isMobileScreen = useMobileScreen(); - return ( <>
diff --git a/app/components/new-chat.module.scss b/app/components/new-chat.module.scss index b291a2366..1b48659d3 100644 --- a/app/components/new-chat.module.scss +++ b/app/components/new-chat.module.scss @@ -8,6 +8,10 @@ justify-content: center; flex-direction: column; + div:not(.no-dark) > svg { + filter: invert(0.5); + } + .mask-header { display: flex; justify-content: space-between; diff --git a/app/components/new-chat.tsx b/app/components/new-chat.tsx index aba3c5b1c..59a26ca32 100644 --- a/app/components/new-chat.tsx +++ b/app/components/new-chat.tsx @@ -72,7 +72,7 @@ function useMaskGroup(masks: Mask[]) { return groups; } -export function NewChat() { +export function NewChat(props: { className?: string }) { const chatStore = useChatStore(); const maskStore = useMaskStore(); @@ -115,9 +115,10 @@ export function NewChat() { return (
( {!isMobileScreen && (
 
-
+
{Locale.Chat.Input(submitKey)}