@termix-ssh/plugin-sdk 1.0.21 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/PLUGIN-GUIDE.md +62 -3
- package/cli/commands/build.mjs +55 -36
- package/cli/commands/validate.mjs +4 -0
- package/dist/backend.d.ts +32 -7
- package/dist/frontend.d.ts +7 -0
- package/dist/host/{PluginsTab-HQGSDSHS.js → PluginsTab-CM2B33BD.js} +22 -14
- package/dist/host/chunk-7J4QNGFM.js +345 -0
- package/dist/host/{chunk-A5CULDWV.js → chunk-HQ6NNFSX.js} +109 -1574
- package/dist/host/chunk-I5F2PSMR.js +1526 -0
- package/dist/host/{chunk-FGX27MAA.js → chunk-JRV2HIDK.js} +1 -1
- package/dist/host/{chunk-JFQGI4OD.js → chunk-P26QKKU5.js} +38 -9
- package/dist/host/{chunk-WWFRBU2E.js → chunk-ROB2SH5Q.js} +76 -49
- package/dist/host/chunk-TK3Y437H.js +53 -0
- package/dist/host/{chunk-GTHINW3L.js → chunk-VKNGNEF3.js} +34650 -34968
- package/dist/host/core-classes.json +1 -1
- package/dist/host/frame-host.css +2 -0
- package/dist/host/frame-host.js +242 -0
- package/dist/host/{linked-server-UDSFY3N7.js → linked-server-J5G457OA.js} +1 -1
- package/dist/host/{rbac-api-AAAPMF52.js → rbac-api-PY22W5UY.js} +5 -1
- package/dist/host/testing-host.js +9 -6
- package/dist/host/types/src/types/host-sidebar-preferences.d.ts +2 -0
- package/dist/host/types/src/types/index.d.ts +8 -0
- package/dist/host/types/src/ui/api/plugins-api.d.ts +2 -1
- package/dist/host/types/src/ui/api/rbac-api.d.ts +19 -1
- package/dist/host/types/src/ui/components/data-view.d.ts +1 -1
- package/dist/host/types/src/ui/main-axios.d.ts +1 -1
- package/dist/host/types/src/ui/plugin-host/loader.d.ts +6 -0
- package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +1 -1
- package/dist/host/types/src/ui/plugins/use-plugins-manager.d.ts +1 -1
- package/dist/host/types/src/ui/shell/tab-registry.d.ts +2 -0
- package/dist/host/ui.js +356 -369
- package/dist/host/{use-permissions-VAND5GEG.js → use-permissions-EWRI3WLT.js} +1 -1
- package/dist/host-commands.d.ts +7 -0
- package/dist/host-commands.js +35 -5
- package/dist/manifest.d.ts +28 -1
- package/dist/manifest.js +108 -1
- package/package.json +5 -1
- package/schema/manifest.schema.json +42 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
const __termixNoGlob = () => ({});
|
|
2
|
+
import {
|
|
3
|
+
Puzzle,
|
|
4
|
+
RotateCcw,
|
|
5
|
+
X,
|
|
6
|
+
clsx,
|
|
7
|
+
cn,
|
|
8
|
+
dist_exports,
|
|
9
|
+
icons_exports,
|
|
10
|
+
isFieldActive,
|
|
11
|
+
usePluginScope
|
|
12
|
+
} from "./chunk-VKNGNEF3.js";
|
|
13
|
+
import {
|
|
14
|
+
init_define_import_meta_env
|
|
15
|
+
} from "./chunk-YGYBM7SQ.js";
|
|
16
|
+
|
|
17
|
+
// src/ui/components/button.tsx
|
|
18
|
+
init_define_import_meta_env();
|
|
19
|
+
|
|
20
|
+
// node_modules/class-variance-authority/dist/index.mjs
|
|
21
|
+
init_define_import_meta_env();
|
|
22
|
+
var falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
|
|
23
|
+
var cx = clsx;
|
|
24
|
+
var cva = (base, config) => (props) => {
|
|
25
|
+
var _config_compoundVariants;
|
|
26
|
+
if ((config === null || config === void 0 ? void 0 : config.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
27
|
+
const { variants, defaultVariants } = config;
|
|
28
|
+
const getVariantClassNames = Object.keys(variants).map((variant) => {
|
|
29
|
+
const variantProp = props === null || props === void 0 ? void 0 : props[variant];
|
|
30
|
+
const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
|
|
31
|
+
if (variantProp === null) return null;
|
|
32
|
+
const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
|
|
33
|
+
return variants[variant][variantKey];
|
|
34
|
+
});
|
|
35
|
+
const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
|
|
36
|
+
let [key, value] = param;
|
|
37
|
+
if (value === void 0) {
|
|
38
|
+
return acc;
|
|
39
|
+
}
|
|
40
|
+
acc[key] = value;
|
|
41
|
+
return acc;
|
|
42
|
+
}, {});
|
|
43
|
+
const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (_config_compoundVariants = config.compoundVariants) === null || _config_compoundVariants === void 0 ? void 0 : _config_compoundVariants.reduce((acc, param) => {
|
|
44
|
+
let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param;
|
|
45
|
+
return Object.entries(compoundVariantOptions).every((param2) => {
|
|
46
|
+
let [key, value] = param2;
|
|
47
|
+
return Array.isArray(value) ? value.includes({
|
|
48
|
+
...defaultVariants,
|
|
49
|
+
...propsWithoutUndefined
|
|
50
|
+
}[key]) : {
|
|
51
|
+
...defaultVariants,
|
|
52
|
+
...propsWithoutUndefined
|
|
53
|
+
}[key] === value;
|
|
54
|
+
}) ? [
|
|
55
|
+
...acc,
|
|
56
|
+
cvClass,
|
|
57
|
+
cvClassName
|
|
58
|
+
] : acc;
|
|
59
|
+
}, []);
|
|
60
|
+
return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// src/ui/components/button.tsx
|
|
64
|
+
import { jsx } from "react/jsx-runtime";
|
|
65
|
+
var buttonVariants = cva(
|
|
66
|
+
"group/button inline-flex shrink-0 items-center justify-center rounded-none border border-transparent bg-clip-padding text-xs font-medium whitespace-nowrap transition-[color,background-color,border-color,opacity,box-shadow,transform] outline-none select-none focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
67
|
+
{
|
|
68
|
+
variants: {
|
|
69
|
+
variant: {
|
|
70
|
+
default: "border-accent-brand/40 bg-accent-brand/15 text-accent-brand hover:bg-accent-brand/25 aria-expanded:bg-accent-brand/25",
|
|
71
|
+
outline: "border-accent-brand/40 bg-transparent text-accent-brand hover:bg-accent-brand/10 aria-expanded:bg-accent-brand/10",
|
|
72
|
+
secondary: "border-accent-brand/20 bg-accent-brand/10 text-accent-brand hover:bg-accent-brand/20 aria-expanded:bg-accent-brand/20",
|
|
73
|
+
ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
|
|
74
|
+
destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
|
|
75
|
+
link: "text-accent-brand underline-offset-4 hover:underline"
|
|
76
|
+
},
|
|
77
|
+
size: {
|
|
78
|
+
default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
79
|
+
xs: "h-6 gap-1 rounded-none px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
80
|
+
sm: "h-7 gap-1 rounded-none px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
81
|
+
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
82
|
+
icon: "size-8",
|
|
83
|
+
"icon-xs": "size-6 rounded-none [&_svg:not([class*='size-'])]:size-3",
|
|
84
|
+
"icon-sm": "size-7 rounded-none",
|
|
85
|
+
"icon-lg": "size-9"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
defaultVariants: {
|
|
89
|
+
variant: "default",
|
|
90
|
+
size: "default"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
function Button({
|
|
95
|
+
className,
|
|
96
|
+
variant = "default",
|
|
97
|
+
size = "default",
|
|
98
|
+
asChild = false,
|
|
99
|
+
...props
|
|
100
|
+
}) {
|
|
101
|
+
const Comp = asChild ? dist_exports.Root : "button";
|
|
102
|
+
return /* @__PURE__ */ jsx(
|
|
103
|
+
Comp,
|
|
104
|
+
{
|
|
105
|
+
"data-slot": "button",
|
|
106
|
+
"data-variant": variant,
|
|
107
|
+
"data-size": size,
|
|
108
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
109
|
+
...props
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/ui/components/input.tsx
|
|
115
|
+
init_define_import_meta_env();
|
|
116
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
117
|
+
function Input({ className, type, ...props }) {
|
|
118
|
+
return /* @__PURE__ */ jsx2(
|
|
119
|
+
"input",
|
|
120
|
+
{
|
|
121
|
+
type,
|
|
122
|
+
"data-slot": "input",
|
|
123
|
+
className: cn(
|
|
124
|
+
"h-8 w-full min-w-0 rounded-none border border-input bg-transparent px-2.5 py-1 text-xs transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-xs file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 md:text-xs dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
|
125
|
+
type === "number" && "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
|
|
126
|
+
className
|
|
127
|
+
),
|
|
128
|
+
...props
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/ui/lib/host-defaults-context.tsx
|
|
134
|
+
init_define_import_meta_env();
|
|
135
|
+
import { createContext, useContext } from "react";
|
|
136
|
+
import { useTranslation } from "react-i18next";
|
|
137
|
+
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
138
|
+
var HostDefaultsContext = createContext(null);
|
|
139
|
+
function useHostDefaults() {
|
|
140
|
+
return useContext(HostDefaultsContext);
|
|
141
|
+
}
|
|
142
|
+
function useIsDefaultsEditor() {
|
|
143
|
+
return useContext(HostDefaultsContext)?.mode === "defaults";
|
|
144
|
+
}
|
|
145
|
+
function useDefaultKey(settingKey) {
|
|
146
|
+
const scope = usePluginScope();
|
|
147
|
+
if (!settingKey) return null;
|
|
148
|
+
if (settingKey.includes(".")) return settingKey;
|
|
149
|
+
return scope ? `${scope}.${settingKey}` : null;
|
|
150
|
+
}
|
|
151
|
+
function useSourceLabel() {
|
|
152
|
+
const { t } = useTranslation();
|
|
153
|
+
return (source) => {
|
|
154
|
+
switch (source?.level) {
|
|
155
|
+
case "folder":
|
|
156
|
+
return t("hostDefaults.source.folder", {
|
|
157
|
+
name: source.folderName ?? ""
|
|
158
|
+
});
|
|
159
|
+
case "user":
|
|
160
|
+
return t("hostDefaults.source.user");
|
|
161
|
+
case "admin":
|
|
162
|
+
return t("hostDefaults.source.admin");
|
|
163
|
+
default:
|
|
164
|
+
return t("hostDefaults.source.builtin");
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function HostDefaultBadge({ settingKey }) {
|
|
169
|
+
const { t } = useTranslation();
|
|
170
|
+
const context = useHostDefaults();
|
|
171
|
+
const fullKey = useDefaultKey(settingKey);
|
|
172
|
+
const sourceLabel = useSourceLabel();
|
|
173
|
+
if (!context || !fullKey || !context.isAvailable(fullKey)) return null;
|
|
174
|
+
const own = context.isOwn(fullKey);
|
|
175
|
+
const source = context.source(fullKey);
|
|
176
|
+
const from = sourceLabel(source);
|
|
177
|
+
if (own && (context.mode === "defaults" || source)) {
|
|
178
|
+
const defaults = context.mode === "defaults";
|
|
179
|
+
return /* @__PURE__ */ jsxs(
|
|
180
|
+
"button",
|
|
181
|
+
{
|
|
182
|
+
type: "button",
|
|
183
|
+
onClick: () => context.reset(fullKey),
|
|
184
|
+
title: defaults ? t("hostDefaults.clearTitle", { source: from }) : t("hostDefaults.resetTitle", { source: from }),
|
|
185
|
+
className: "inline-flex items-center gap-0.5 border border-accent-brand/40 px-1 text-[10px] font-medium normal-case tracking-normal text-accent-brand hover:bg-accent-brand/10",
|
|
186
|
+
children: [
|
|
187
|
+
defaults ? /* @__PURE__ */ jsx3(X, { className: "size-2.5" }) : /* @__PURE__ */ jsx3(RotateCcw, { className: "size-2.5" }),
|
|
188
|
+
defaults ? t("hostDefaults.setHere") : t("hostDefaults.custom")
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
if (own || source?.level === "builtin") return null;
|
|
194
|
+
return /* @__PURE__ */ jsx3(
|
|
195
|
+
"span",
|
|
196
|
+
{
|
|
197
|
+
title: source ? t("hostDefaults.inheritedTitle", { source: from }) : t("hostDefaults.notSetTitle"),
|
|
198
|
+
className: "border border-border px-1 text-[10px] font-normal normal-case tracking-normal text-muted-foreground",
|
|
199
|
+
children: source ? from : t("hostDefaults.notSet")
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
function DefaultsOnly({
|
|
204
|
+
settingKey,
|
|
205
|
+
children
|
|
206
|
+
}) {
|
|
207
|
+
const context = useHostDefaults();
|
|
208
|
+
const fullKey = useDefaultKey(settingKey);
|
|
209
|
+
if (context?.mode === "defaults" && fullKey && !context.isAvailable(fullKey)) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
return /* @__PURE__ */ jsx3(Fragment, { children });
|
|
213
|
+
}
|
|
214
|
+
function HostOnly({ children }) {
|
|
215
|
+
return useIsDefaultsEditor() ? null : /* @__PURE__ */ jsx3(Fragment, { children });
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/ui/components/section-card.tsx
|
|
219
|
+
init_define_import_meta_env();
|
|
220
|
+
import { useState } from "react";
|
|
221
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
222
|
+
function SectionCard({
|
|
223
|
+
title,
|
|
224
|
+
icon,
|
|
225
|
+
action,
|
|
226
|
+
children,
|
|
227
|
+
className,
|
|
228
|
+
rowId
|
|
229
|
+
}) {
|
|
230
|
+
return /* @__PURE__ */ jsxs2(
|
|
231
|
+
"div",
|
|
232
|
+
{
|
|
233
|
+
"data-setting-row": rowId,
|
|
234
|
+
className: `flex flex-col border border-border bg-card overflow-hidden ${className ?? ""}`,
|
|
235
|
+
children: [
|
|
236
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 px-4 py-2.5 border-b border-border shrink-0", children: [
|
|
237
|
+
/* @__PURE__ */ jsx4("span", { className: "text-muted-foreground", children: icon }),
|
|
238
|
+
/* @__PURE__ */ jsx4("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-muted-foreground flex-1", children: title }),
|
|
239
|
+
action && /* @__PURE__ */ jsx4("div", { className: "ml-auto", children: action })
|
|
240
|
+
] }),
|
|
241
|
+
/* @__PURE__ */ jsx4("div", { className: "px-3 md:px-4 py-1", children })
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
function SettingRow({
|
|
247
|
+
label,
|
|
248
|
+
badge,
|
|
249
|
+
description,
|
|
250
|
+
defaultKey,
|
|
251
|
+
rowId,
|
|
252
|
+
children
|
|
253
|
+
}) {
|
|
254
|
+
return /* @__PURE__ */ jsx4(DefaultsOnly, { settingKey: defaultKey ?? "", children: /* @__PURE__ */ jsxs2(
|
|
255
|
+
"div",
|
|
256
|
+
{
|
|
257
|
+
"data-setting-row": rowId ?? "",
|
|
258
|
+
className: "flex items-center justify-between gap-3 py-3 border-b border-border last:border-0 [.gap-4>&]:py-0 [.gap-4>&]:border-0",
|
|
259
|
+
children: [
|
|
260
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-0.5 min-w-0 flex-1", children: [
|
|
261
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
|
|
262
|
+
/* @__PURE__ */ jsx4("span", { className: "text-sm font-medium leading-snug", children: label }),
|
|
263
|
+
badge && /* @__PURE__ */ jsx4("span", { className: "text-[10px] font-bold text-warning border border-warning/40 px-1 shrink-0", children: badge }),
|
|
264
|
+
defaultKey && /* @__PURE__ */ jsx4(HostDefaultBadge, { settingKey: defaultKey })
|
|
265
|
+
] }),
|
|
266
|
+
description && /* @__PURE__ */ jsx4("span", { className: "text-xs text-muted-foreground leading-snug", children: description })
|
|
267
|
+
] }),
|
|
268
|
+
/* @__PURE__ */ jsx4("div", { className: "shrink-0", children })
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
) });
|
|
272
|
+
}
|
|
273
|
+
function FakeSwitch({
|
|
274
|
+
defaultChecked = false,
|
|
275
|
+
disabled = false,
|
|
276
|
+
checked,
|
|
277
|
+
onChange
|
|
278
|
+
}) {
|
|
279
|
+
const [internalOn, setInternalOn] = useState(defaultChecked);
|
|
280
|
+
const on = checked !== void 0 ? checked : internalOn;
|
|
281
|
+
return /* @__PURE__ */ jsx4(
|
|
282
|
+
"button",
|
|
283
|
+
{
|
|
284
|
+
type: "button",
|
|
285
|
+
role: "switch",
|
|
286
|
+
"aria-checked": on,
|
|
287
|
+
disabled,
|
|
288
|
+
onClick: () => {
|
|
289
|
+
const next = !on;
|
|
290
|
+
if (checked === void 0) setInternalOn(next);
|
|
291
|
+
onChange?.(next);
|
|
292
|
+
},
|
|
293
|
+
className: `relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center border-2 transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${on ? "bg-accent-brand border-accent-brand" : "bg-muted border-border"}`,
|
|
294
|
+
children: /* @__PURE__ */ jsx4(
|
|
295
|
+
"span",
|
|
296
|
+
{
|
|
297
|
+
className: `pointer-events-none inline-block h-3 w-3 bg-background shadow-sm transition-transform ${on ? "translate-x-4" : "translate-x-0.5"}`
|
|
298
|
+
}
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/ui/lib/plugin-icon.tsx
|
|
305
|
+
init_define_import_meta_env();
|
|
306
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
307
|
+
function PluginIcon({
|
|
308
|
+
name,
|
|
309
|
+
...props
|
|
310
|
+
}) {
|
|
311
|
+
const Icon = name && icons_exports[name] || Puzzle;
|
|
312
|
+
return /* @__PURE__ */ jsx5(Icon, { ...props });
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/ui/settings/settings-fields-util.ts
|
|
316
|
+
init_define_import_meta_env();
|
|
317
|
+
function isFieldShown(field, values) {
|
|
318
|
+
return !field.hidden && isFieldActive(field, values);
|
|
319
|
+
}
|
|
320
|
+
function hasVisibleFields(fields) {
|
|
321
|
+
return fields.some((field) => !field.hidden);
|
|
322
|
+
}
|
|
323
|
+
function hasSettingsPage(plugin, isAdmin) {
|
|
324
|
+
const settings = plugin.contributes?.settings;
|
|
325
|
+
return plugin.enabled && (hasVisibleFields(settings?.user ?? []) || isAdmin && hasVisibleFields(settings?.admin ?? []));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export {
|
|
329
|
+
cva,
|
|
330
|
+
buttonVariants,
|
|
331
|
+
Button,
|
|
332
|
+
Input,
|
|
333
|
+
HostDefaultsContext,
|
|
334
|
+
useIsDefaultsEditor,
|
|
335
|
+
HostDefaultBadge,
|
|
336
|
+
DefaultsOnly,
|
|
337
|
+
HostOnly,
|
|
338
|
+
SectionCard,
|
|
339
|
+
SettingRow,
|
|
340
|
+
FakeSwitch,
|
|
341
|
+
PluginIcon,
|
|
342
|
+
isFieldShown,
|
|
343
|
+
hasVisibleFields,
|
|
344
|
+
hasSettingsPage
|
|
345
|
+
};
|