From 8cb65f96364305972157a8c32b928a1247a3a2eb Mon Sep 17 00:00:00 2001 From: Jay <53023+jayair@users.noreply.github.com> Date: Sat, 4 Jul 2026 22:02:05 +0000 Subject: [PATCH 1/3] fix(app): preserve provider dialog backdrop --- .../components/dialog-connect-provider.tsx | 143 ++++---- .../src/components/dialog-custom-provider.tsx | 315 +++++++++--------- .../src/components/dialog-select-provider.tsx | 163 +++++---- 3 files changed, 349 insertions(+), 272 deletions(-) diff --git a/packages/app/src/components/dialog-connect-provider.tsx b/packages/app/src/components/dialog-connect-provider.tsx index 3a57769b5a68..886aa7ffa3ce 100644 --- a/packages/app/src/components/dialog-connect-provider.tsx +++ b/packages/app/src/components/dialog-connect-provider.tsx @@ -17,7 +17,13 @@ import { useServerSync } from "@/context/server-sync" import { useLanguage } from "@/context/language" import { useProviders } from "@/hooks/use-providers" -export function DialogConnectProvider(props: { provider: string; directory?: Accessor }) { +export function DialogConnectProvider(props: { + provider: string + directory?: Accessor + onBack?: () => void + content?: boolean + bind?: (value: { back: () => void }) => void +}) { const dialog = useDialog() const serverSync = useServerSync() const serverSDK = useServerSDK() @@ -25,6 +31,10 @@ export function DialogConnectProvider(props: { provider: string; directory?: Acc const providers = useProviders(props.directory) const all = () => { + if (props.onBack) { + props.onBack() + return + } void import("./dialog-select-provider").then((x) => { dialog.show(() => ) }) @@ -598,6 +608,74 @@ export function DialogConnectProvider(props: { provider: string; directory?: Acc ) } + const content = ( +
+
+ +
+ + + {language.t("provider.connect.title.anthropicProMax")} + + {language.t("provider.connect.title", { provider: provider().name })} + +
+
+
+
+ + +
+
+ + {language.t("provider.connect.status.inProgress")} +
+
+
+ + + + +
+
+ + {language.t("provider.connect.status.inProgress")} +
+
+
+ + + + +
+
+ + {language.t("provider.connect.status.failed", { error: store.error ?? "" })} +
+
+
+ + + + + + + + + + + + + +
+
+
+
+ ) + + props.bind?.({ back: goBack }) + if (props.content) return content + return ( } > -
-
- -
- - - {language.t("provider.connect.title.anthropicProMax")} - - {language.t("provider.connect.title", { provider: provider().name })} - -
-
-
-
- - -
-
- - {language.t("provider.connect.status.inProgress")} -
-
-
- - - - -
-
- - {language.t("provider.connect.status.inProgress")} -
-
-
- - - - -
-
- - {language.t("provider.connect.status.failed", { error: store.error ?? "" })} -
-
-
- - - - - - - - - - - - - -
-
-
-
+ {content}
) } diff --git a/packages/app/src/components/dialog-custom-provider.tsx b/packages/app/src/components/dialog-custom-provider.tsx index 647e5002a297..2afec1460a6c 100644 --- a/packages/app/src/components/dialog-custom-provider.tsx +++ b/packages/app/src/components/dialog-custom-provider.tsx @@ -16,8 +16,10 @@ import { type FormState, headerRow, modelRow, validateCustomProvider } from "./d import { DialogSelectProvider } from "./dialog-select-provider" type Props = { - back?: "providers" | "close" + back?: "providers" | "close" | (() => void) directory?: Accessor + content?: boolean + bind?: (value: { back: () => void }) => void } export function DialogCustomProvider(props: Props) { @@ -37,6 +39,10 @@ export function DialogCustomProvider(props: Props) { }) const goBack = () => { + if (typeof props.back === "function") { + props.back() + return + } if (props.back === "close") { dialog.close() return @@ -162,6 +168,162 @@ export function DialogCustomProvider(props: Props) { saveMutation.mutate(result) } + const content = ( +
+
+ +
{language.t("provider.custom.title")}
+
+ +
+

+ {language.t("provider.custom.description.prefix")} + + {language.t("provider.custom.description.link")} + + {language.t("provider.custom.description.suffix")} +

+ +
+ setField("providerID", v)} + validationState={form.err.providerID ? "invalid" : undefined} + error={form.err.providerID} + /> + setField("name", v)} + validationState={form.err.name ? "invalid" : undefined} + error={form.err.name} + /> + setField("baseURL", v)} + validationState={form.err.baseURL ? "invalid" : undefined} + error={form.err.baseURL} + /> + setField("apiKey", v)} + /> +
+ +
+ + + {(m, i) => ( +
+
+ setModel(i(), "id", v)} + validationState={m.err.id ? "invalid" : undefined} + error={m.err.id} + /> +
+
+ setModel(i(), "name", v)} + validationState={m.err.name ? "invalid" : undefined} + error={m.err.name} + /> +
+ removeModel(i())} + disabled={form.models.length <= 1} + aria-label={language.t("provider.custom.models.remove")} + /> +
+ )} +
+ +
+ +
+ + + {(h, i) => ( +
+
+ setHeader(i(), "key", v)} + validationState={h.err.key ? "invalid" : undefined} + error={h.err.key} + /> +
+
+ setHeader(i(), "value", v)} + validationState={h.err.value ? "invalid" : undefined} + error={h.err.value} + /> +
+ removeHeader(i())} + disabled={form.headers.length <= 1} + aria-label={language.t("provider.custom.headers.remove")} + /> +
+ )} +
+ +
+ + +
+
+ ) + + props.bind?.({ back: goBack }) + if (props.content) return content + return ( -
-
- -
{language.t("provider.custom.title")}
-
- -
-

- {language.t("provider.custom.description.prefix")} - - {language.t("provider.custom.description.link")} - - {language.t("provider.custom.description.suffix")} -

- -
- setField("providerID", v)} - validationState={form.err.providerID ? "invalid" : undefined} - error={form.err.providerID} - /> - setField("name", v)} - validationState={form.err.name ? "invalid" : undefined} - error={form.err.name} - /> - setField("baseURL", v)} - validationState={form.err.baseURL ? "invalid" : undefined} - error={form.err.baseURL} - /> - setField("apiKey", v)} - /> -
- -
- - - {(m, i) => ( -
-
- setModel(i(), "id", v)} - validationState={m.err.id ? "invalid" : undefined} - error={m.err.id} - /> -
-
- setModel(i(), "name", v)} - validationState={m.err.name ? "invalid" : undefined} - error={m.err.name} - /> -
- removeModel(i())} - disabled={form.models.length <= 1} - aria-label={language.t("provider.custom.models.remove")} - /> -
- )} -
- -
- -
- - - {(h, i) => ( -
-
- setHeader(i(), "key", v)} - validationState={h.err.key ? "invalid" : undefined} - error={h.err.key} - /> -
-
- setHeader(i(), "value", v)} - validationState={h.err.value ? "invalid" : undefined} - error={h.err.value} - /> -
- removeHeader(i())} - disabled={form.headers.length <= 1} - aria-label={language.t("provider.custom.headers.remove")} - /> -
- )} -
- -
- - -
-
+ {content}
) } diff --git a/packages/app/src/components/dialog-select-provider.tsx b/packages/app/src/components/dialog-select-provider.tsx index ff0ab5d2bf0c..022827854818 100644 --- a/packages/app/src/components/dialog-select-provider.tsx +++ b/packages/app/src/components/dialog-select-provider.tsx @@ -1,7 +1,8 @@ -import { type Accessor, Component, Show } from "solid-js" -import { useDialog } from "@opencode-ai/ui/context/dialog" +import { type Accessor, Component, Match, Show, Switch } from "solid-js" +import { createStore } from "solid-js/store" import { popularProviders, useProviders } from "@/hooks/use-providers" import { Dialog } from "@opencode-ai/ui/dialog" +import { IconButton } from "@opencode-ai/ui/icon-button" import { List } from "@opencode-ai/ui/list" import { Tag } from "@opencode-ai/ui/tag" import { ProviderIcon } from "@opencode-ai/ui/provider-icon" @@ -12,9 +13,15 @@ import { DialogCustomProvider } from "./dialog-custom-provider" const CUSTOM_ID = "_custom" export const DialogSelectProvider: Component<{ directory?: Accessor }> = (props) => { - const dialog = useDialog() const providers = useProviders(props.directory) const language = useLanguage() + const [store, setStore] = createStore({ selected: undefined as string | undefined }) + const navigation = { back: showPicker } + + function showPicker() { + navigation.back = showPicker + setStore("selected", undefined) + } const popularGroup = () => language.t("dialog.provider.group.popular") const otherGroup = () => language.t("dialog.provider.group.other") @@ -27,61 +34,101 @@ export const DialogSelectProvider: Component<{ directory?: Accessor - x?.id} - items={() => { - language.locale() - return [{ id: CUSTOM_ID, name: customLabel() }, ...providers.all().values()] - }} - filterKeys={["id", "name"]} - groupBy={(x) => (popularProviders.includes(x.id) ? popularGroup() : otherGroup())} - sortBy={(a, b) => { - if (a.id === CUSTOM_ID) return -1 - if (b.id === CUSTOM_ID) return 1 - if (popularProviders.includes(a.id) && popularProviders.includes(b.id)) - return popularProviders.indexOf(a.id) - popularProviders.indexOf(b.id) - return a.name.localeCompare(b.name) - }} - sortGroupsBy={(a, b) => { - const popular = popularGroup() - if (a.category === popular && b.category !== popular) return -1 - if (b.category === popular && a.category !== popular) return 1 - return 0 - }} - onSelect={(x) => { - if (!x) return - if (x.id === CUSTOM_ID) { - dialog.show(() => ) - return - } - dialog.show(() => ) - }} - > - {(i) => ( -
- - {i.name} - -
{language.t("dialog.provider.opencode.tagline")}
-
- - {language.t("settings.providers.tag.custom")} - - - {language.t("dialog.provider.tag.recommended")} - - {(value) =>
{value()}
}
- - {language.t("dialog.provider.tag.recommended")} - -
- )} -
+ + + navigation.back()} + aria-label={language.t("common.goBack")} + /> + + {language.t("command.provider.connect")} + + } + > + + + { + navigation.back = value.back + }} + /> + + + {(provider) => ( + { + navigation.back = value.back + }} + /> + )} + + + x?.id} + items={() => { + language.locale() + return [{ id: CUSTOM_ID, name: customLabel() }, ...providers.all().values()] + }} + filterKeys={["id", "name"]} + groupBy={(x) => (popularProviders.includes(x.id) ? popularGroup() : otherGroup())} + sortBy={(a, b) => { + if (a.id === CUSTOM_ID) return -1 + if (b.id === CUSTOM_ID) return 1 + if (popularProviders.includes(a.id) && popularProviders.includes(b.id)) + return popularProviders.indexOf(a.id) - popularProviders.indexOf(b.id) + return a.name.localeCompare(b.name) + }} + sortGroupsBy={(a, b) => { + const popular = popularGroup() + if (a.category === popular && b.category !== popular) return -1 + if (b.category === popular && a.category !== popular) return 1 + return 0 + }} + onSelect={(x) => { + if (!x) return + setStore("selected", x.id) + }} + > + {(i) => ( +
+ + {i.name} + +
{language.t("dialog.provider.opencode.tagline")}
+
+ + {language.t("settings.providers.tag.custom")} + + + {language.t("dialog.provider.tag.recommended")} + + {(value) =>
{value()}
}
+ + {language.t("dialog.provider.tag.recommended")} + +
+ )} +
+
+
) } From 3a470147f29c5b903b4e446a79bbd99c4c59dba3 Mon Sep 17 00:00:00 2001 From: Jay <53023+jayair@users.noreply.github.com> Date: Mon, 6 Jul 2026 02:07:00 +0000 Subject: [PATCH 2/3] refactor(app): parent provider back navigation --- .../components/dialog-connect-provider.tsx | 31 ++-------- .../src/components/dialog-custom-provider.tsx | 26 ++------ .../components/dialog-select-model-unpaid.tsx | 2 +- .../src/components/dialog-select-provider.tsx | 61 ++++--------------- .../app/src/components/settings-providers.tsx | 9 ++- .../src/components/settings-v2/providers.tsx | 9 ++- .../pages/session/usage-exceeded-dialogs.tsx | 11 +++- 7 files changed, 46 insertions(+), 103 deletions(-) diff --git a/packages/app/src/components/dialog-connect-provider.tsx b/packages/app/src/components/dialog-connect-provider.tsx index 886aa7ffa3ce..c2edb119c660 100644 --- a/packages/app/src/components/dialog-connect-provider.tsx +++ b/packages/app/src/components/dialog-connect-provider.tsx @@ -20,9 +20,7 @@ import { useProviders } from "@/hooks/use-providers" export function DialogConnectProvider(props: { provider: string directory?: Accessor - onBack?: () => void - content?: boolean - bind?: (value: { back: () => void }) => void + onBack: () => void }) { const dialog = useDialog() const serverSync = useServerSync() @@ -30,16 +28,6 @@ export function DialogConnectProvider(props: { const language = useLanguage() const providers = useProviders(props.directory) - const all = () => { - if (props.onBack) { - props.onBack() - return - } - void import("./dialog-select-provider").then((x) => { - dialog.show(() => ) - }) - } - const alive = { value: true } const timer = { current: undefined as ReturnType | undefined } @@ -374,19 +362,11 @@ export function DialogConnectProvider(props: { } function goBack() { - if (methods().length === 1) { - all() - return - } - if (store.authorization) { - dispatch({ type: "method.reset" }) - return - } - if (store.methodIndex !== undefined) { + if (methods().length > 1 && store.methodIndex !== undefined) { dispatch({ type: "method.reset" }) return } - all() + props.onBack() } function MethodSelection() { @@ -673,11 +653,9 @@ export function DialogConnectProvider(props: { ) - props.bind?.({ back: goBack }) - if (props.content) return content - return ( } + transition > {content} diff --git a/packages/app/src/components/dialog-custom-provider.tsx b/packages/app/src/components/dialog-custom-provider.tsx index 2afec1460a6c..4492d2baaeec 100644 --- a/packages/app/src/components/dialog-custom-provider.tsx +++ b/packages/app/src/components/dialog-custom-provider.tsx @@ -6,20 +6,16 @@ import { ProviderIcon } from "@opencode-ai/ui/provider-icon" import { useMutation } from "@tanstack/solid-query" import { TextField } from "@opencode-ai/ui/text-field" import { showToast } from "@/utils/toast" -import { type Accessor, batch, For } from "solid-js" +import { batch, For } from "solid-js" import { createStore, produce } from "solid-js/store" import { Link } from "@/components/link" import { useServerSDK } from "@/context/server-sdk" import { useServerSync } from "@/context/server-sync" import { useLanguage } from "@/context/language" import { type FormState, headerRow, modelRow, validateCustomProvider } from "./dialog-custom-provider-form" -import { DialogSelectProvider } from "./dialog-select-provider" type Props = { - back?: "providers" | "close" | (() => void) - directory?: Accessor - content?: boolean - bind?: (value: { back: () => void }) => void + onBack: () => void } export function DialogCustomProvider(props: Props) { @@ -38,18 +34,6 @@ export function DialogCustomProvider(props: Props) { err: {}, }) - const goBack = () => { - if (typeof props.back === "function") { - props.back() - return - } - if (props.back === "close") { - dialog.close() - return - } - dialog.show(() => ) - } - const addModel = () => { setForm( "models", @@ -321,17 +305,15 @@ export function DialogCustomProvider(props: Props) { ) - props.bind?.({ back: goBack }) - if (props.content) return content - return ( } diff --git a/packages/app/src/components/dialog-select-model-unpaid.tsx b/packages/app/src/components/dialog-select-model-unpaid.tsx index bcb4a2fbcbf4..0a32ad48b36d 100644 --- a/packages/app/src/components/dialog-select-model-unpaid.tsx +++ b/packages/app/src/components/dialog-select-model-unpaid.tsx @@ -24,7 +24,7 @@ export const DialogSelectModelUnpaid: Component<{ model?: ModelState }> = (props const connect = (provider: string) => { void import("./dialog-connect-provider").then((x) => { - dialog.show(() => ) + dialog.show(() => ) }) } diff --git a/packages/app/src/components/dialog-select-provider.tsx b/packages/app/src/components/dialog-select-provider.tsx index 022827854818..e1facf48219a 100644 --- a/packages/app/src/components/dialog-select-provider.tsx +++ b/packages/app/src/components/dialog-select-provider.tsx @@ -2,7 +2,6 @@ import { type Accessor, Component, Match, Show, Switch } from "solid-js" import { createStore } from "solid-js/store" import { popularProviders, useProviders } from "@/hooks/use-providers" import { Dialog } from "@opencode-ai/ui/dialog" -import { IconButton } from "@opencode-ai/ui/icon-button" import { List } from "@opencode-ai/ui/list" import { Tag } from "@opencode-ai/ui/tag" import { ProviderIcon } from "@opencode-ai/ui/provider-icon" @@ -16,10 +15,8 @@ export const DialogSelectProvider: Component<{ directory?: Accessor - - navigation.back()} - aria-label={language.t("common.goBack")} - /> - - {language.t("command.provider.connect")} - - } - > - - - { - navigation.back = value.back - }} - /> - - - {(provider) => ( - { - navigation.back = value.back - }} - /> - )} - - + + + + + + {(provider) => } + + + )} - - - + + + ) } diff --git a/packages/app/src/components/settings-providers.tsx b/packages/app/src/components/settings-providers.tsx index 24e7a60104ae..9791fc21fcae 100644 --- a/packages/app/src/components/settings-providers.tsx +++ b/packages/app/src/components/settings-providers.tsx @@ -211,7 +211,12 @@ const SettingsProvidersContent: Component = () => { variant="secondary" icon="plus-small" onClick={() => { - dialog.show(() => ) + dialog.show(() => ( + dialog.show(() => )} + /> + )) }} > {language.t("common.connect")} @@ -239,7 +244,7 @@ const SettingsProvidersContent: Component = () => { variant="secondary" icon="plus-small" onClick={() => { - dialog.show(() => ) + dialog.show(() => ) }} > {language.t("common.connect")} diff --git a/packages/app/src/components/settings-v2/providers.tsx b/packages/app/src/components/settings-v2/providers.tsx index cd24bbd4558c..99a4101f9a35 100644 --- a/packages/app/src/components/settings-v2/providers.tsx +++ b/packages/app/src/components/settings-v2/providers.tsx @@ -211,7 +211,12 @@ export const SettingsProvidersV2: Component = () => { variant="neutral" icon="plus" onClick={() => { - dialog.show(() => ) + dialog.show(() => ( + dialog.show(() => )} + /> + )) }} > {language.t("common.connect")} @@ -241,7 +246,7 @@ export const SettingsProvidersV2: Component = () => { variant="neutral" icon="plus" onClick={() => { - dialog.show(() => ) + dialog.show(() => ) }} > {language.t("common.connect")} diff --git a/packages/app/src/pages/session/usage-exceeded-dialogs.tsx b/packages/app/src/pages/session/usage-exceeded-dialogs.tsx index 935eed7e6969..5c77e7bcecc0 100644 --- a/packages/app/src/pages/session/usage-exceeded-dialogs.tsx +++ b/packages/app/src/pages/session/usage-exceeded-dialogs.tsx @@ -77,7 +77,16 @@ export function useUsageExceededDialogs() { if (dontShowAgain) setGoUpsellState(keys.dontShow, Date.now()) else { void import("../../components/dialog-connect-provider").then((x) => - dialog.show(() => ), + dialog.show(() => ( + { + void import("../../components/dialog-select-provider").then((provider) => { + dialog.show(() => ) + }) + }} + /> + )), ) } }} From ef60c0db35443902af5ff3c5f5e864cdec0bd1b0 Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Mon, 6 Jul 2026 13:49:04 +0800 Subject: [PATCH 3/3] cleanup --- .../components/dialog-connect-provider.tsx | 128 ++++---- .../src/components/dialog-custom-provider.tsx | 304 +++++++++--------- 2 files changed, 212 insertions(+), 220 deletions(-) diff --git a/packages/app/src/components/dialog-connect-provider.tsx b/packages/app/src/components/dialog-connect-provider.tsx index c2edb119c660..c94cca505351 100644 --- a/packages/app/src/components/dialog-connect-provider.tsx +++ b/packages/app/src/components/dialog-connect-provider.tsx @@ -588,71 +588,6 @@ export function DialogConnectProvider(props: { ) } - const content = ( -
-
- -
- - - {language.t("provider.connect.title.anthropicProMax")} - - {language.t("provider.connect.title", { provider: provider().name })} - -
-
-
-
- - -
-
- - {language.t("provider.connect.status.inProgress")} -
-
-
- - - - -
-
- - {language.t("provider.connect.status.inProgress")} -
-
-
- - - - -
-
- - {language.t("provider.connect.status.failed", { error: store.error ?? "" })} -
-
-
- - - - - - - - - - - - - -
-
-
-
- ) - return ( - {content} +
+
+ +
+ + + {language.t("provider.connect.title.anthropicProMax")} + + {language.t("provider.connect.title", { provider: provider().name })} + +
+
+
+
+ + +
+
+ + {language.t("provider.connect.status.inProgress")} +
+
+
+ + + + +
+
+ + {language.t("provider.connect.status.inProgress")} +
+
+
+ + + + +
+
+ + {language.t("provider.connect.status.failed", { error: store.error ?? "" })} +
+
+
+ + + + + + + + + + + + + +
+
+
+
) } diff --git a/packages/app/src/components/dialog-custom-provider.tsx b/packages/app/src/components/dialog-custom-provider.tsx index 4492d2baaeec..e8cae859e06a 100644 --- a/packages/app/src/components/dialog-custom-provider.tsx +++ b/packages/app/src/components/dialog-custom-provider.tsx @@ -152,159 +152,6 @@ export function DialogCustomProvider(props: Props) { saveMutation.mutate(result) } - const content = ( -
-
- -
{language.t("provider.custom.title")}
-
- -
-

- {language.t("provider.custom.description.prefix")} - - {language.t("provider.custom.description.link")} - - {language.t("provider.custom.description.suffix")} -

- -
- setField("providerID", v)} - validationState={form.err.providerID ? "invalid" : undefined} - error={form.err.providerID} - /> - setField("name", v)} - validationState={form.err.name ? "invalid" : undefined} - error={form.err.name} - /> - setField("baseURL", v)} - validationState={form.err.baseURL ? "invalid" : undefined} - error={form.err.baseURL} - /> - setField("apiKey", v)} - /> -
- -
- - - {(m, i) => ( -
-
- setModel(i(), "id", v)} - validationState={m.err.id ? "invalid" : undefined} - error={m.err.id} - /> -
-
- setModel(i(), "name", v)} - validationState={m.err.name ? "invalid" : undefined} - error={m.err.name} - /> -
- removeModel(i())} - disabled={form.models.length <= 1} - aria-label={language.t("provider.custom.models.remove")} - /> -
- )} -
- -
- -
- - - {(h, i) => ( -
-
- setHeader(i(), "key", v)} - validationState={h.err.key ? "invalid" : undefined} - error={h.err.key} - /> -
-
- setHeader(i(), "value", v)} - validationState={h.err.value ? "invalid" : undefined} - error={h.err.value} - /> -
- removeHeader(i())} - disabled={form.headers.length <= 1} - aria-label={language.t("provider.custom.headers.remove")} - /> -
- )} -
- -
- - -
-
- ) - return ( - {content} +
+
+ +
{language.t("provider.custom.title")}
+
+ +
+

+ {language.t("provider.custom.description.prefix")} + + {language.t("provider.custom.description.link")} + + {language.t("provider.custom.description.suffix")} +

+ +
+ setField("providerID", v)} + validationState={form.err.providerID ? "invalid" : undefined} + error={form.err.providerID} + /> + setField("name", v)} + validationState={form.err.name ? "invalid" : undefined} + error={form.err.name} + /> + setField("baseURL", v)} + validationState={form.err.baseURL ? "invalid" : undefined} + error={form.err.baseURL} + /> + setField("apiKey", v)} + /> +
+ +
+ + + {(m, i) => ( +
+
+ setModel(i(), "id", v)} + validationState={m.err.id ? "invalid" : undefined} + error={m.err.id} + /> +
+
+ setModel(i(), "name", v)} + validationState={m.err.name ? "invalid" : undefined} + error={m.err.name} + /> +
+ removeModel(i())} + disabled={form.models.length <= 1} + aria-label={language.t("provider.custom.models.remove")} + /> +
+ )} +
+ +
+ +
+ + + {(h, i) => ( +
+
+ setHeader(i(), "key", v)} + validationState={h.err.key ? "invalid" : undefined} + error={h.err.key} + /> +
+
+ setHeader(i(), "value", v)} + validationState={h.err.value ? "invalid" : undefined} + error={h.err.value} + /> +
+ removeHeader(i())} + disabled={form.headers.length <= 1} + aria-label={language.t("provider.custom.headers.remove")} + /> +
+ )} +
+ +
+ + +
+
) }