@aiot-nexus/plugin-sdk 3.1.1 → 3.3.0
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/README.md +34 -22
- package/dev-host/main.js +20 -5
- package/dist/.generated/plugin-framework-version.d.ts +2 -1
- package/dist/.generated/plugin-framework-version.js +3 -2
- package/dist/.generated/plugin-manifest.schema.json +1 -1
- package/dist/.generated/theme-contract.d.ts +43 -0
- package/dist/.generated/theme-contract.js +75 -0
- package/dist/browser/frame-client.d.ts +1 -0
- package/dist/browser/frame-client.mjs +197 -0
- package/dist/dev-host-metadata.json +1 -1
- package/dist/src/browser/frame-client.d.ts +1 -0
- package/dist/src/browser/frame-client.js +197 -0
- package/dist/src/cli/run.js +2 -2
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +3 -1
- package/dist/src/nexus-dev-deployment.js +2 -2
- package/dist/src/scaffold.js +1 -1
- package/dist/src/sdk-info.d.ts +1 -1
- package/dist/src/sdk-info.js +1 -1
- package/dist/src/types.d.ts +37 -0
- package/dist/src/web-dev.js +2 -0
- package/package.json +1 -1
- package/templates/minimal/README.md.tmpl +13 -9
- package/templates/minimal/src/renderer/app.ts.tmpl +4 -1
- package/templates/minimal/src/renderer/plugin.css +78 -52
- package/templates/sqlite/README.md.tmpl +13 -9
- package/templates/sqlite/src/renderer/app.ts.tmpl +4 -1
- package/templates/sqlite/src/renderer/plugin.css +135 -57
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
:root {
|
|
2
|
+
--bg: var(--nexus-color-background, #eef1f4);
|
|
3
|
+
--panel: var(--nexus-color-surface, #ffffff);
|
|
4
|
+
--raise: var(--nexus-color-surface-raised, #f7f9fa);
|
|
5
|
+
--hover: var(--nexus-color-surface-hover, #eef3f6);
|
|
6
|
+
--line: var(--nexus-color-border, #d7dde3);
|
|
7
|
+
--line-strong: var(--nexus-color-border-strong, #c2cbd3);
|
|
8
|
+
--fg: var(--nexus-color-text, #212a32);
|
|
9
|
+
--fg-dim: var(--nexus-color-text-muted, #5a6772);
|
|
10
|
+
--brand: var(--nexus-color-primary, #8fc31f);
|
|
11
|
+
--brand-text: var(--nexus-color-accent, #6f9a15);
|
|
12
|
+
--on-brand: var(--nexus-color-on-primary, #ffffff);
|
|
13
|
+
--primary-action: var(--nexus-color-primary, #8fc31f);
|
|
14
|
+
--on-primary: var(--nexus-color-on-primary, #ffffff);
|
|
15
|
+
--on-negative: var(--nexus-color-on-negative, #ffffff);
|
|
16
|
+
--focus-ring: var(--nexus-color-accent, #6f9a15);
|
|
17
|
+
--brand-soft: var(--nexus-color-primary-soft, rgba(143, 195, 31, 0.12));
|
|
18
|
+
--positive: var(--nexus-color-positive, #1f9a4e);
|
|
2
19
|
color-scheme: light;
|
|
3
|
-
font-family: "
|
|
4
|
-
|
|
5
|
-
|
|
20
|
+
font-family: "Noto Sans SC", "Source Han Sans SC", "Microsoft YaHei",
|
|
21
|
+
"Segoe UI", system-ui, sans-serif;
|
|
22
|
+
background: var(--bg);
|
|
23
|
+
color: var(--fg);
|
|
24
|
+
font-size: 14px;
|
|
25
|
+
letter-spacing: 0;
|
|
6
26
|
}
|
|
7
27
|
|
|
8
28
|
* {
|
|
@@ -16,7 +36,8 @@
|
|
|
16
36
|
body {
|
|
17
37
|
margin: 0;
|
|
18
38
|
min-height: 0;
|
|
19
|
-
background:
|
|
39
|
+
background: var(--bg);
|
|
40
|
+
color: var(--fg);
|
|
20
41
|
}
|
|
21
42
|
|
|
22
43
|
.plugin-shell {
|
|
@@ -27,9 +48,9 @@ body {
|
|
|
27
48
|
|
|
28
49
|
.plugin-header,
|
|
29
50
|
.echo-panel {
|
|
30
|
-
border: 1px solid
|
|
31
|
-
border-radius:
|
|
32
|
-
background:
|
|
51
|
+
border: 1px solid var(--line);
|
|
52
|
+
border-radius: 10px;
|
|
53
|
+
background: var(--panel);
|
|
33
54
|
}
|
|
34
55
|
|
|
35
56
|
.plugin-header {
|
|
@@ -47,22 +68,24 @@ p {
|
|
|
47
68
|
}
|
|
48
69
|
|
|
49
70
|
h1 {
|
|
50
|
-
font-size:
|
|
71
|
+
font-size: 18px;
|
|
72
|
+
font-weight: 600;
|
|
51
73
|
}
|
|
52
74
|
|
|
53
75
|
h2 {
|
|
54
|
-
font-size:
|
|
76
|
+
font-size: 14.5px;
|
|
77
|
+
font-weight: 600;
|
|
55
78
|
}
|
|
56
79
|
|
|
57
80
|
p,
|
|
58
81
|
.result-row > span {
|
|
59
82
|
margin-top: 4px;
|
|
60
|
-
color:
|
|
83
|
+
color: var(--fg-dim);
|
|
61
84
|
font-size: 12px;
|
|
62
85
|
}
|
|
63
86
|
|
|
64
87
|
.status {
|
|
65
|
-
color:
|
|
88
|
+
color: var(--positive);
|
|
66
89
|
font-size: 12px;
|
|
67
90
|
font-weight: 600;
|
|
68
91
|
}
|
|
@@ -87,24 +110,42 @@ label {
|
|
|
87
110
|
input {
|
|
88
111
|
min-width: 0;
|
|
89
112
|
height: 36px;
|
|
90
|
-
border: 1px solid
|
|
91
|
-
border-radius:
|
|
113
|
+
border: 1px solid var(--line-strong);
|
|
114
|
+
border-radius: 7px;
|
|
92
115
|
padding: 0 10px;
|
|
93
|
-
background:
|
|
94
|
-
color:
|
|
116
|
+
background: var(--panel);
|
|
117
|
+
color: var(--fg);
|
|
95
118
|
font: inherit;
|
|
96
119
|
}
|
|
97
120
|
|
|
98
121
|
button {
|
|
99
122
|
height: 36px;
|
|
100
|
-
border: 1px solid
|
|
101
|
-
border-radius:
|
|
123
|
+
border: 1px solid var(--brand);
|
|
124
|
+
border-radius: 7px;
|
|
102
125
|
padding: 0 16px;
|
|
103
|
-
background:
|
|
104
|
-
color:
|
|
126
|
+
background: var(--brand);
|
|
127
|
+
color: var(--on-brand);
|
|
105
128
|
font: inherit;
|
|
106
129
|
font-weight: 600;
|
|
107
130
|
cursor: pointer;
|
|
131
|
+
transition: filter 0.15s ease, background-color 0.15s ease,
|
|
132
|
+
border-color 0.15s ease, color 0.15s ease;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
button:not(:disabled):hover {
|
|
136
|
+
border-color: var(--primary-action);
|
|
137
|
+
background: var(--primary-action);
|
|
138
|
+
color: var(--on-primary);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
button:focus-visible,
|
|
142
|
+
input:focus-visible {
|
|
143
|
+
outline: 2px solid var(--focus-ring);
|
|
144
|
+
outline-offset: 2px;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
input:hover {
|
|
148
|
+
border-color: var(--brand);
|
|
108
149
|
}
|
|
109
150
|
|
|
110
151
|
button:disabled {
|
|
@@ -117,7 +158,7 @@ button:disabled {
|
|
|
117
158
|
grid-template-columns: 80px minmax(0, 1fr);
|
|
118
159
|
gap: 10px;
|
|
119
160
|
margin-top: 14px;
|
|
120
|
-
border-top: 1px solid
|
|
161
|
+
border-top: 1px solid var(--line);
|
|
121
162
|
padding-top: 12px;
|
|
122
163
|
}
|
|
123
164
|
|
|
@@ -135,37 +176,22 @@ output {
|
|
|
135
176
|
}
|
|
136
177
|
|
|
137
178
|
:root[data-theme="dark"] {
|
|
179
|
+
--bg: var(--nexus-color-background, #101418);
|
|
180
|
+
--panel: var(--nexus-color-surface, #1b222a);
|
|
181
|
+
--raise: var(--nexus-color-surface-raised, #171c22);
|
|
182
|
+
--hover: var(--nexus-color-surface-hover, #222a34);
|
|
183
|
+
--line: var(--nexus-color-border, #2a333e);
|
|
184
|
+
--line-strong: var(--nexus-color-border-strong, #38434f);
|
|
185
|
+
--fg: var(--nexus-color-text, #e2e8ee);
|
|
186
|
+
--fg-dim: var(--nexus-color-text-muted, #97a3af);
|
|
187
|
+
--brand-text: var(--nexus-color-accent, #a5d43e);
|
|
188
|
+
--primary-action: var(--nexus-color-primary, #8fc31f);
|
|
189
|
+
--on-primary: var(--nexus-color-on-primary, #ffffff);
|
|
190
|
+
--on-negative: var(--nexus-color-on-negative, #101418);
|
|
191
|
+
--focus-ring: var(--nexus-color-accent, #a5d43e);
|
|
192
|
+
--brand-soft: var(--nexus-color-primary-soft, rgba(143, 195, 31, 0.14));
|
|
193
|
+
--positive: var(--nexus-color-positive, #46b96e);
|
|
138
194
|
color-scheme: dark;
|
|
139
|
-
background:
|
|
140
|
-
color:
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
:root[data-theme="dark"] body {
|
|
144
|
-
background: #16191d;
|
|
145
|
-
color: #edf0f2;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
:root[data-theme="dark"] .plugin-header,
|
|
149
|
-
:root[data-theme="dark"] .echo-panel {
|
|
150
|
-
border-color: #454b52;
|
|
151
|
-
background: #24282d;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
:root[data-theme="dark"] p,
|
|
155
|
-
:root[data-theme="dark"] .result-row > span {
|
|
156
|
-
color: #aeb7c2;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
:root[data-theme="dark"] input {
|
|
160
|
-
border-color: #59616a;
|
|
161
|
-
background: #191c20;
|
|
162
|
-
color: #edf0f2;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
:root[data-theme="dark"] .result-row {
|
|
166
|
-
border-top-color: #454b52;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
:root[data-theme="dark"] .status {
|
|
170
|
-
color: #75d6a5;
|
|
195
|
+
background: var(--bg);
|
|
196
|
+
color: var(--fg);
|
|
171
197
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# __DISPLAY_NAME_MARKDOWN__
|
|
2
2
|
|
|
3
|
-
AIoT
|
|
3
|
+
AIoT Toolkits independent PluginFrame plugin generated from the `sqlite` template.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npm install
|
|
@@ -8,7 +8,7 @@ npm run typecheck
|
|
|
8
8
|
npm run build
|
|
9
9
|
npm run dev:web
|
|
10
10
|
npm run dev
|
|
11
|
-
npm run dev:nexus -- --host C:\path\to\
|
|
11
|
+
npm run dev:nexus -- --host "C:\path\to\AIoT Toolkits.exe"
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
SDK checks for a newer `@aiot-nexus/plugin-sdk` in two steps. The package `postinstall` refreshes a user cache; npm 7+ hides dependency lifecycle output by default, so use `npm install --foreground-scripts` to see it. The `nexus-plugin` CLI reads that cache and prints npm-style notices when it is fresh; missing or older-than-24-hours cache data is checked in the background without blocking the command. `npm install --ignore-scripts` skips only the install check, while CLI checks remain available.
|
|
@@ -17,7 +17,7 @@ The check follows the npm-configured registry, falls back to the official npm re
|
|
|
17
17
|
|
|
18
18
|
Every `npm run build` rebuilds `better-sqlite3@8.7.0` for Electron 22.3.27 with `@electron/rebuild@3.7.2` before packaging. `npm run rebuild:native` remains available as a standalone diagnostic command.
|
|
19
19
|
|
|
20
|
-
The deployable plugin package is `dist/__PLUGIN_ID__/`. For a manual installation, stop
|
|
20
|
+
The deployable plugin package is `dist/__PLUGIN_ID__/`. For a manual installation, stop AIoT Toolkits before replacing `Plugins/__PLUGIN_ID__/`, then start it again. During development, use `npm run dev:nexus` so the CLI coordinates AIoT Toolkits shutdown, atomic replacement, and restart for trusted `mainEntry` changes. Runtime data is stored in the host-provided plugin data directory and is not written into the plugin package.
|
|
21
21
|
|
|
22
22
|
The template is a schema-aware SQLite database browser. It opens `plugin.db` in the plugin data directory by default and initializes the `plugin_records` sample table there. **Open Database** calls Electron's directly imported `dialog.showOpenDialog()` from trusted `mainEntry`; it accepts a single existing SQLite file, including files without an extension. The renderer only displays the selected path and invokes parameterized operations. It never receives an Electron object and does not expose a path input, arbitrary SQL, DDL, `ATTACH`, or a SQL console.
|
|
23
23
|
|
|
@@ -43,19 +43,23 @@ if (!result.canceled && result.filePaths[0]) {
|
|
|
43
43
|
}
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
For related workflows, use `properties: ["openDirectory", "createDirectory"]` to choose a folder or `dialog.showSaveDialog()` to choose a save path. These calls belong in trusted `mainEntry`; the renderer should invoke a registered business operation such as `sqlite.chooseDatabase` through `client.invokeMain()` and receive only the result it needs. Native dialogs are unavailable in `npm run dev:web`; use `npm run dev` or a formal
|
|
46
|
+
For related workflows, use `properties: ["openDirectory", "createDirectory"]` to choose a folder or `dialog.showSaveDialog()` to choose a save path. These calls belong in trusted `mainEntry`; the renderer should invoke a registered business operation such as `sqlite.chooseDatabase` through `client.invokeMain()` and receive only the result it needs. Native dialogs are unavailable in `npm run dev:web`; use `npm run dev` or a formal AIoT Toolkits host.
|
|
47
47
|
|
|
48
48
|
External files are opened read/write only after a separate candidate connection can query `sqlite_schema`. Canceling the dialog or selecting a corrupt, locked, or inaccessible file keeps the current connection. The latest external path is atomically stored as `sqlite-browser-state.json` in the plugin data directory. Startup restores it when valid; otherwise the template clears the saved selection, falls back to `plugin.db`, and returns a visible notice. External databases do not receive the sample schema or journal pragma.
|
|
49
49
|
|
|
50
50
|
The table selector lists ordinary user tables from the `main` schema. Dynamic headers show declared type, SQLite affinity, primary-key order, NULL, default, and generated-column metadata. The editor supports default/NULL/value modes for inserts and unchanged/NULL/value modes for updates. INTEGER input uses exact decimal integers, REAL must be finite, NUMERIC accepts integer, real, or text values, and BLOB input uses even-length hexadecimal text. The 1 MiB field and 4 MiB row limits count decoded BLOB bytes rather than hexadecimal characters. Ordinary rowid tables prefer an unshadowed built-in rowid; `WITHOUT ROWID` tables, or tables that shadow every rowid alias, fall back only to primary-key columns that are all non-NULL. A table without a unique locator remains browsable and insertable, but update and delete are unavailable. Primary-key locators larger than 16 KiB are also treated as browse-only so a page cannot copy unbounded keys into the trusted main process and iframe. Update and delete run in a transaction and must affect exactly one row. TEXT previews are capped at 16 KiB of UTF-8 data; BLOB previews show the byte length and first 32 bytes.
|
|
51
51
|
|
|
52
|
-
The renderer follows `context.language` and `context.themeMode` from
|
|
52
|
+
The renderer follows `context.language` and `context.themeMode` from AIoT Toolkits and preserves unfinished editor values during in-place context updates. The plugin page has no language or theme selector; the controls shown by `npm run dev` belong to the debug host. Below that toolbar, the iframe has no host padding, border, minimum size, or content-driven height and fills the remaining host viewport. This SDK template deliberately has no Quasar dependency, so its data grid uses a native `<table>` as a dependency-minimized template exception. It still provides pagination, contained horizontal scrolling, light/dark themes, `en-US` / `zh-CN`, and busy/empty/error states. Edit renderer messages in `src/renderer/app.ts`; edit host-shell titles and descriptions in `src/manifest.json` resources.
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
SDK 3.2 automatically maps the active `context.theme` palette to `--nexus-color-*` variables and sets `data-nexus-theme="light|dark"` on the document root. This template consumes those variables with local light/dark fallbacks, so it still renders on an older host. Merely upgrading the SDK does not recolor custom CSS: use the namespaced variables or read the optional palette explicitly, for example `const primary = context.theme?.light.primary`.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
For a plugin-owned theme, create the client with `createPluginFrameClient({ autoApplyHostTheme: false })`. The palette remains available from `await client.waitForContext()`, but the SDK will not write CSS variables or `data-nexus-theme`. It never overwrites plugin-owned `--bg`, `--accent`, `data-theme`, or `color-scheme` values.
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
The current SDK has no generic business-event subscription API. For a long-running operation, register a fast `job.start` operation that returns a `taskId`, then expose `job.getStatus` and optional `job.cancel` for renderer polling. See the AIoT Toolkits repository's plugin IPC and event notification example for the full contract and code.
|
|
59
|
+
|
|
60
|
+
Use `npm run dev:web` for renderer-only layout, styling, localization, and responsive checks in the system browser. It runs `build:web`, writes an isolated package under `.nexus-plugin-dev/web-package/`, and does not rebuild or load `better-sqlite3`, execute `mainEntry`, provide Node or Electron main-process APIs, copy native runtime files, or overwrite the deployable `dist` package. It builds with source maps, serves only on `127.0.0.1:4173`, and opens the browser automatically. The page explicitly reports `PluginCapabilityUnsupported`; file selection, table loading, and CRUD require `npm run dev` or a formal AIoT Toolkits host. Pass `-- --no-open` or `-- --port <port>` when needed.
|
|
61
|
+
|
|
62
|
+
Use `npm run dev:nexus -- --host "C:\path\to\AIoT Toolkits.exe"` to run the plugin inside a compiled, packaged AIoT Toolkits. The initial deployment and every full package replacement are atomic. Renderer-only and safe manifest updates keep the AIoT Toolkits PID; `mainEntry`, dependency, native-module, or restart-sensitive manifest changes run the complete build (including the Electron 22.3.27 native rebuild), stop AIoT Toolkits, replace the package, and start a new AIoT Toolkits process. The database remains under the host-provided plugin data directory across host restarts. Failed builds keep the previous deployment, and launch or readiness failures roll the package back and restore the previous host. Add `--no-devtools`, `--inspect[=<port>]`, `--inspect-brk[=<port>]`, `--surface`, or `--contribution-id` after the second `--` as needed.
|
|
59
63
|
|
|
60
64
|
When this project was created from a local SDK archive, `vendor/aiot-nexus-plugin-sdk.tgz` is part of the source project and must be kept when the project is moved or committed. An explicit local upgrade copies the target archive to `vendor/aiot-nexus-plugin-sdk-<version>.tgz` and updates the exact file dependency.
|
|
61
65
|
|
|
@@ -63,4 +67,4 @@ For a local SDK archive, the tgz version remains the plugin's current SDK versio
|
|
|
63
67
|
|
|
64
68
|
For trusted-main breakpoints, open this plugin directory in VS Code, set breakpoints in `src/main.ts`, and run `Debug Nexus plugin`. To attach manually, start `npm run dev:debug` and select `Attach Nexus plugin main process (9229)`. Renderer DevTools opens automatically, with `src/renderer/app.ts` available through the development source map. The default debug build also runs the Electron 22.3.27 native rebuild before launch. Use `npm run dev -- --no-build` only when intentionally reusing a compatible current `dist` output.
|
|
65
69
|
|
|
66
|
-
The independent host stores the SQLite database and settings under `.nexus-plugin-dev/data/` and mirrors the PluginFrame protocol and current Host API surface. Its simulated
|
|
70
|
+
The independent host stores the SQLite database and settings under `.nexus-plugin-dev/data/` and mirrors the PluginFrame protocol and current Host API surface. Its simulated AIoT Toolkits application version defaults to the version recorded by the SDK build; pass `npm run dev -- --host-version <X.Y.Z>` to exercise another compatibility branch. Run the deployable `dist/__PLUGIN_ID__/` in AIoT Toolkits before delivery because the standalone host does not reproduce the full application shell or routing state.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createPluginFrameClient } from "@aiot-nexus/plugin-sdk/browser";
|
|
2
|
+
import type { PluginThemeTokens } from "@aiot-nexus/plugin-sdk";
|
|
2
3
|
|
|
3
4
|
type DatabaseSource = "default" | "external";
|
|
4
5
|
type SqliteAffinity = "integer" | "real" | "text" | "blob" | "numeric";
|
|
@@ -906,9 +907,11 @@ function applyLanguage(nextLanguage: SupportedLanguage): void {
|
|
|
906
907
|
client.notifyResize();
|
|
907
908
|
}
|
|
908
909
|
|
|
909
|
-
function applyContext(context: { language: string; themeMode: ThemeMode }): void {
|
|
910
|
+
function applyContext(context: { language: string; themeMode: ThemeMode; theme?: { light: PluginThemeTokens; dark: PluginThemeTokens } }): void {
|
|
910
911
|
applyLanguage(resolveLanguage(context.language));
|
|
911
912
|
applyTheme(context.themeMode);
|
|
913
|
+
const resolvedMode = context.themeMode === "dark" || (context.themeMode === "system" && systemDarkMode.matches) ? "dark" : "light";
|
|
914
|
+
document.documentElement.dataset.hostPrimary = context.theme?.[resolvedMode].primary || "";
|
|
912
915
|
revealPluginContent();
|
|
913
916
|
}
|
|
914
917
|
|
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
:root {
|
|
2
|
+
--bg: var(--nexus-color-background, #eef1f4);
|
|
3
|
+
--panel: var(--nexus-color-surface, #ffffff);
|
|
4
|
+
--raise: var(--nexus-color-surface-raised, #f7f9fa);
|
|
5
|
+
--hover: var(--nexus-color-surface-hover, #eef3f6);
|
|
6
|
+
--inset: var(--nexus-color-surface-inset, #e4e9ed);
|
|
7
|
+
--line: var(--nexus-color-border, #d7dde3);
|
|
8
|
+
--line-strong: var(--nexus-color-border-strong, #c2cbd3);
|
|
9
|
+
--fg: var(--nexus-color-text, #212a32);
|
|
10
|
+
--fg-dim: var(--nexus-color-text-muted, #5a6772);
|
|
11
|
+
--fg-faint: var(--nexus-color-text-faint, #8b97a1);
|
|
12
|
+
--brand: var(--nexus-color-primary, #8fc31f);
|
|
13
|
+
--brand-text: var(--nexus-color-accent, #6f9a15);
|
|
14
|
+
--on-brand: var(--nexus-color-on-primary, #ffffff);
|
|
15
|
+
--primary-action: var(--nexus-color-primary, #8fc31f);
|
|
16
|
+
--on-primary: var(--nexus-color-on-primary, #ffffff);
|
|
17
|
+
--on-negative: var(--nexus-color-on-negative, #ffffff);
|
|
18
|
+
--focus-ring: var(--nexus-color-accent, #6f9a15);
|
|
19
|
+
--brand-soft: var(--nexus-color-primary-soft, rgba(143, 195, 31, 0.12));
|
|
20
|
+
--negative: var(--nexus-color-negative, #c2402f);
|
|
2
21
|
color-scheme: light;
|
|
3
|
-
font-family: "
|
|
4
|
-
|
|
5
|
-
|
|
22
|
+
font-family: "Noto Sans SC", "Source Han Sans SC", "Microsoft YaHei",
|
|
23
|
+
"Segoe UI", system-ui, sans-serif;
|
|
24
|
+
background: var(--bg);
|
|
25
|
+
color: var(--fg);
|
|
26
|
+
font-size: 14px;
|
|
6
27
|
}
|
|
7
28
|
|
|
8
29
|
* {
|
|
@@ -19,7 +40,8 @@ body {
|
|
|
19
40
|
height: 100vh;
|
|
20
41
|
min-height: 100vh;
|
|
21
42
|
overflow: hidden;
|
|
22
|
-
background:
|
|
43
|
+
background: var(--bg);
|
|
44
|
+
color: var(--fg);
|
|
23
45
|
}
|
|
24
46
|
|
|
25
47
|
button,
|
|
@@ -46,9 +68,9 @@ textarea {
|
|
|
46
68
|
.editor-panel,
|
|
47
69
|
.data-panel {
|
|
48
70
|
min-width: 0;
|
|
49
|
-
border: 1px solid
|
|
50
|
-
border-radius:
|
|
51
|
-
background:
|
|
71
|
+
border: 1px solid var(--line);
|
|
72
|
+
border-radius: 10px;
|
|
73
|
+
background: var(--panel);
|
|
52
74
|
}
|
|
53
75
|
|
|
54
76
|
.plugin-header {
|
|
@@ -86,18 +108,19 @@ p {
|
|
|
86
108
|
}
|
|
87
109
|
|
|
88
110
|
h1 {
|
|
89
|
-
font-size:
|
|
111
|
+
font-size: 18px;
|
|
112
|
+
font-weight: 600;
|
|
90
113
|
}
|
|
91
114
|
|
|
92
115
|
h2 {
|
|
93
|
-
font-size:
|
|
116
|
+
font-size: 14.5px;
|
|
94
117
|
}
|
|
95
118
|
|
|
96
119
|
.database-heading p {
|
|
97
120
|
overflow: hidden;
|
|
98
121
|
max-width: min(62vw, 760px);
|
|
99
122
|
margin-top: 3px;
|
|
100
|
-
color:
|
|
123
|
+
color: var(--fg-dim);
|
|
101
124
|
font-size: 12px;
|
|
102
125
|
text-overflow: ellipsis;
|
|
103
126
|
white-space: nowrap;
|
|
@@ -115,13 +138,15 @@ h2 {
|
|
|
115
138
|
|
|
116
139
|
button {
|
|
117
140
|
min-height: 32px;
|
|
118
|
-
border: 1px solid
|
|
119
|
-
border-radius:
|
|
141
|
+
border: 1px solid var(--brand);
|
|
142
|
+
border-radius: 7px;
|
|
120
143
|
padding: 0 11px;
|
|
121
|
-
background:
|
|
122
|
-
color:
|
|
144
|
+
background: var(--brand);
|
|
145
|
+
color: var(--on-brand);
|
|
123
146
|
font-weight: 600;
|
|
124
147
|
cursor: pointer;
|
|
148
|
+
transition: filter 0.15s ease, background-color 0.15s ease,
|
|
149
|
+
border-color 0.15s ease, color 0.15s ease;
|
|
125
150
|
}
|
|
126
151
|
|
|
127
152
|
button:disabled,
|
|
@@ -133,14 +158,50 @@ textarea:disabled {
|
|
|
133
158
|
}
|
|
134
159
|
|
|
135
160
|
button.button-secondary {
|
|
136
|
-
border-color:
|
|
137
|
-
background:
|
|
138
|
-
color:
|
|
161
|
+
border-color: var(--line-strong);
|
|
162
|
+
background: var(--panel);
|
|
163
|
+
color: var(--fg);
|
|
139
164
|
}
|
|
140
165
|
|
|
141
166
|
button.button-danger {
|
|
142
|
-
border-color:
|
|
143
|
-
background:
|
|
167
|
+
border-color: var(--negative);
|
|
168
|
+
background: var(--negative);
|
|
169
|
+
color: var(--on-negative);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
button:not(:disabled):hover {
|
|
173
|
+
border-color: var(--primary-action);
|
|
174
|
+
background: var(--primary-action);
|
|
175
|
+
color: var(--on-primary);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
button.button-secondary:not(:disabled):hover,
|
|
179
|
+
button.record-action:not(:disabled):hover {
|
|
180
|
+
filter: none;
|
|
181
|
+
border-color: var(--brand);
|
|
182
|
+
background: var(--hover);
|
|
183
|
+
color: var(--fg);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
button.button-danger:not(:disabled):hover {
|
|
187
|
+
border-color: var(--negative);
|
|
188
|
+
background: var(--negative);
|
|
189
|
+
color: var(--on-negative);
|
|
190
|
+
filter: brightness(1.06);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
button:focus-visible,
|
|
194
|
+
input:focus-visible,
|
|
195
|
+
select:focus-visible,
|
|
196
|
+
textarea:focus-visible {
|
|
197
|
+
outline: 2px solid var(--focus-ring);
|
|
198
|
+
outline-offset: 2px;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
input:hover,
|
|
202
|
+
select:hover,
|
|
203
|
+
textarea:hover {
|
|
204
|
+
border-color: var(--brand);
|
|
144
205
|
}
|
|
145
206
|
|
|
146
207
|
.compact-button {
|
|
@@ -168,7 +229,7 @@ button.button-danger {
|
|
|
168
229
|
#statusLog,
|
|
169
230
|
.editor-panel .panel-heading p,
|
|
170
231
|
.field-current {
|
|
171
|
-
color:
|
|
232
|
+
color: var(--fg-dim);
|
|
172
233
|
font-size: 12px;
|
|
173
234
|
}
|
|
174
235
|
|
|
@@ -184,11 +245,11 @@ select,
|
|
|
184
245
|
textarea {
|
|
185
246
|
width: 100%;
|
|
186
247
|
min-width: 0;
|
|
187
|
-
border: 1px solid
|
|
188
|
-
border-radius:
|
|
248
|
+
border: 1px solid var(--line-strong);
|
|
249
|
+
border-radius: 7px;
|
|
189
250
|
padding: 7px 9px;
|
|
190
|
-
background:
|
|
191
|
-
color:
|
|
251
|
+
background: var(--panel);
|
|
252
|
+
color: var(--fg);
|
|
192
253
|
}
|
|
193
254
|
|
|
194
255
|
textarea {
|
|
@@ -236,7 +297,7 @@ textarea {
|
|
|
236
297
|
gap: 6px 8px;
|
|
237
298
|
align-items: end;
|
|
238
299
|
min-width: 0;
|
|
239
|
-
border-top: 1px solid
|
|
300
|
+
border-top: 1px solid var(--line);
|
|
240
301
|
padding-top: 8px;
|
|
241
302
|
}
|
|
242
303
|
|
|
@@ -255,11 +316,11 @@ textarea {
|
|
|
255
316
|
}
|
|
256
317
|
|
|
257
318
|
.column-badge {
|
|
258
|
-
border: 1px solid
|
|
319
|
+
border: 1px solid var(--line);
|
|
259
320
|
border-radius: 4px;
|
|
260
321
|
padding: 1px 4px;
|
|
261
|
-
background:
|
|
262
|
-
color:
|
|
322
|
+
background: var(--raise);
|
|
323
|
+
color: var(--fg-dim);
|
|
263
324
|
font-size: 10px;
|
|
264
325
|
font-weight: 600;
|
|
265
326
|
}
|
|
@@ -282,7 +343,7 @@ textarea {
|
|
|
282
343
|
|
|
283
344
|
.error {
|
|
284
345
|
margin-top: 8px;
|
|
285
|
-
color:
|
|
346
|
+
color: var(--negative);
|
|
286
347
|
font-size: 12px;
|
|
287
348
|
}
|
|
288
349
|
|
|
@@ -306,9 +367,9 @@ textarea {
|
|
|
306
367
|
|
|
307
368
|
.empty-state {
|
|
308
369
|
padding: 18px;
|
|
309
|
-
border: 1px dashed
|
|
310
|
-
border-radius:
|
|
311
|
-
color:
|
|
370
|
+
border: 1px dashed var(--line-strong);
|
|
371
|
+
border-radius: 7px;
|
|
372
|
+
color: var(--fg-dim);
|
|
312
373
|
text-align: center;
|
|
313
374
|
}
|
|
314
375
|
|
|
@@ -318,8 +379,8 @@ textarea {
|
|
|
318
379
|
min-height: 80px;
|
|
319
380
|
max-width: 100%;
|
|
320
381
|
overflow: auto;
|
|
321
|
-
border: 1px solid
|
|
322
|
-
border-radius:
|
|
382
|
+
border: 1px solid var(--line);
|
|
383
|
+
border-radius: 7px;
|
|
323
384
|
}
|
|
324
385
|
|
|
325
386
|
table {
|
|
@@ -331,7 +392,7 @@ table {
|
|
|
331
392
|
th,
|
|
332
393
|
td {
|
|
333
394
|
max-width: 360px;
|
|
334
|
-
border-bottom: 1px solid
|
|
395
|
+
border-bottom: 1px solid var(--line);
|
|
335
396
|
padding: 7px 9px;
|
|
336
397
|
text-align: left;
|
|
337
398
|
vertical-align: top;
|
|
@@ -342,8 +403,8 @@ th {
|
|
|
342
403
|
z-index: 1;
|
|
343
404
|
top: 0;
|
|
344
405
|
min-width: 120px;
|
|
345
|
-
background:
|
|
346
|
-
color:
|
|
406
|
+
background: var(--raise);
|
|
407
|
+
color: var(--fg-dim);
|
|
347
408
|
font-size: 12px;
|
|
348
409
|
}
|
|
349
410
|
|
|
@@ -365,7 +426,7 @@ td {
|
|
|
365
426
|
.cell-null,
|
|
366
427
|
.cell-blob,
|
|
367
428
|
.cell-truncated {
|
|
368
|
-
color:
|
|
429
|
+
color: var(--fg-dim);
|
|
369
430
|
font-family: Consolas, monospace;
|
|
370
431
|
font-size: 12px;
|
|
371
432
|
}
|
|
@@ -379,7 +440,7 @@ td {
|
|
|
379
440
|
td.row-actions-cell {
|
|
380
441
|
position: sticky;
|
|
381
442
|
right: 0;
|
|
382
|
-
background:
|
|
443
|
+
background: var(--panel);
|
|
383
444
|
}
|
|
384
445
|
|
|
385
446
|
.pager {
|
|
@@ -388,7 +449,7 @@ td.row-actions-cell {
|
|
|
388
449
|
justify-content: flex-end;
|
|
389
450
|
gap: 12px;
|
|
390
451
|
padding-top: 9px;
|
|
391
|
-
color:
|
|
452
|
+
color: var(--fg-dim);
|
|
392
453
|
font-size: 12px;
|
|
393
454
|
}
|
|
394
455
|
|
|
@@ -449,14 +510,31 @@ td.row-actions-cell {
|
|
|
449
510
|
}
|
|
450
511
|
|
|
451
512
|
:root[data-theme="dark"] {
|
|
513
|
+
--bg: var(--nexus-color-background, #101418);
|
|
514
|
+
--panel: var(--nexus-color-surface, #1b222a);
|
|
515
|
+
--raise: var(--nexus-color-surface-raised, #171c22);
|
|
516
|
+
--hover: var(--nexus-color-surface-hover, #222a34);
|
|
517
|
+
--inset: var(--nexus-color-surface-inset, #0c0f13);
|
|
518
|
+
--line: var(--nexus-color-border, #2a333e);
|
|
519
|
+
--line-strong: var(--nexus-color-border-strong, #38434f);
|
|
520
|
+
--fg: var(--nexus-color-text, #e2e8ee);
|
|
521
|
+
--fg-dim: var(--nexus-color-text-muted, #97a3af);
|
|
522
|
+
--fg-faint: var(--nexus-color-text-faint, #64707c);
|
|
523
|
+
--brand-text: var(--nexus-color-accent, #a5d43e);
|
|
524
|
+
--primary-action: var(--nexus-color-primary, #8fc31f);
|
|
525
|
+
--on-primary: var(--nexus-color-on-primary, #ffffff);
|
|
526
|
+
--on-negative: var(--nexus-color-on-negative, #101418);
|
|
527
|
+
--focus-ring: var(--nexus-color-accent, #a5d43e);
|
|
528
|
+
--brand-soft: var(--nexus-color-primary-soft, rgba(143, 195, 31, 0.14));
|
|
529
|
+
--negative: var(--nexus-color-negative, #e2604f);
|
|
452
530
|
color-scheme: dark;
|
|
453
|
-
background:
|
|
454
|
-
color:
|
|
531
|
+
background: var(--bg);
|
|
532
|
+
color: var(--fg);
|
|
455
533
|
}
|
|
456
534
|
|
|
457
535
|
:root[data-theme="dark"] body {
|
|
458
|
-
background:
|
|
459
|
-
color:
|
|
536
|
+
background: var(--bg);
|
|
537
|
+
color: var(--fg);
|
|
460
538
|
}
|
|
461
539
|
|
|
462
540
|
:root[data-theme="dark"] .plugin-header,
|
|
@@ -464,8 +542,8 @@ td.row-actions-cell {
|
|
|
464
542
|
:root[data-theme="dark"] .editor-panel,
|
|
465
543
|
:root[data-theme="dark"] .data-panel,
|
|
466
544
|
:root[data-theme="dark"] td.row-actions-cell {
|
|
467
|
-
border-color:
|
|
468
|
-
background:
|
|
545
|
+
border-color: var(--line);
|
|
546
|
+
background: var(--panel);
|
|
469
547
|
}
|
|
470
548
|
|
|
471
549
|
:root[data-theme="dark"] .database-heading p,
|
|
@@ -479,36 +557,36 @@ td.row-actions-cell {
|
|
|
479
557
|
:root[data-theme="dark"] .cell-null,
|
|
480
558
|
:root[data-theme="dark"] .cell-blob,
|
|
481
559
|
:root[data-theme="dark"] .cell-truncated {
|
|
482
|
-
color:
|
|
560
|
+
color: var(--fg-dim);
|
|
483
561
|
}
|
|
484
562
|
|
|
485
563
|
:root[data-theme="dark"] input,
|
|
486
564
|
:root[data-theme="dark"] select,
|
|
487
565
|
:root[data-theme="dark"] textarea,
|
|
488
566
|
:root[data-theme="dark"] button.button-secondary {
|
|
489
|
-
border-color:
|
|
490
|
-
background:
|
|
491
|
-
color:
|
|
567
|
+
border-color: var(--line-strong);
|
|
568
|
+
background: var(--inset);
|
|
569
|
+
color: var(--fg);
|
|
492
570
|
}
|
|
493
571
|
|
|
494
572
|
:root[data-theme="dark"] .column-badge {
|
|
495
|
-
border-color:
|
|
496
|
-
background:
|
|
497
|
-
color:
|
|
573
|
+
border-color: var(--line-strong);
|
|
574
|
+
background: var(--raise);
|
|
575
|
+
color: var(--fg-dim);
|
|
498
576
|
}
|
|
499
577
|
|
|
500
578
|
:root[data-theme="dark"] .table-wrap,
|
|
501
579
|
:root[data-theme="dark"] .empty-state,
|
|
502
580
|
:root[data-theme="dark"] .editor-field {
|
|
503
|
-
border-color:
|
|
581
|
+
border-color: var(--line);
|
|
504
582
|
}
|
|
505
583
|
|
|
506
584
|
:root[data-theme="dark"] th {
|
|
507
|
-
background:
|
|
508
|
-
color:
|
|
585
|
+
background: var(--raise);
|
|
586
|
+
color: var(--fg-dim);
|
|
509
587
|
}
|
|
510
588
|
|
|
511
589
|
:root[data-theme="dark"] th,
|
|
512
590
|
:root[data-theme="dark"] td {
|
|
513
|
-
border-bottom-color:
|
|
591
|
+
border-bottom-color: var(--line);
|
|
514
592
|
}
|