zidane-ui 9.1.6 → 9.1.9
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/dist/adapters/run-host.js +17 -20
- package/dist/adapters/server-files-host.js +3 -1
- package/dist/adapters/server-host.js +18 -11
- package/dist/adapters/server-machines-host.js +3 -1
- package/dist/adapters/server-session-host.js +2 -1
- package/dist/adapters/server-settings-accounts.js +2 -1
- package/dist/adapters/server-settings-host.js +3 -3
- package/dist/adapters/sse-host.js +9 -7
- package/dist/chat/SessionGroupHeader.js +2 -2
- package/dist/chat/SessionHostHeader.js +1 -1
- package/dist/chat/StatusDot.js +24 -20
- package/dist/chat/composer/Composer.d.ts +13 -8
- package/dist/chat/composer/Composer.js +14 -10
- package/dist/chat/composer/ComposerEditor.js +1 -1
- package/dist/chat/composer/HostComposer.d.ts +1 -1
- package/dist/chat/composer/HostComposer.js +7 -10
- package/dist/chat/composer/RunStatusChip.js +13 -1
- package/dist/chat/composer/attachment-ingest.d.ts +4 -1
- package/dist/chat/composer/attachment-ingest.js +27 -10
- package/dist/chat/composer/composer-bus.d.ts +9 -1
- package/dist/chat/composer/composer-bus.js +49 -6
- package/dist/chat/composer/index.d.ts +2 -2
- package/dist/chat/composer/index.js +2 -2
- package/dist/chat/composer/use-draft-target.d.ts +4 -0
- package/dist/chat/composer/use-draft-target.js +15 -4
- package/dist/chat/composer/use-send-prompt.d.ts +5 -1
- package/dist/chat/composer/use-send-prompt.js +2 -12
- package/dist/chat/headless/chip-labels.d.ts +2 -0
- package/dist/chat/headless/chip-labels.js +3 -1
- package/dist/chat/headless/composer/labels-editor.d.ts +2 -0
- package/dist/chat/headless/composer/labels-editor.js +2 -0
- package/dist/chat/headless/file-chip.d.ts +12 -13
- package/dist/chat/headless/file-chip.js +40 -2
- package/dist/chat/headless/fixture-host.js +14 -17
- package/dist/chat/headless/host.d.ts +24 -6
- package/dist/chat/headless/index.d.ts +4 -4
- package/dist/chat/headless/index.js +4 -4
- package/dist/chat/headless/labels.d.ts +16 -0
- package/dist/chat/headless/labels.js +15 -2
- package/dist/chat/headless/send-flow.d.ts +21 -4
- package/dist/chat/headless/send-flow.js +25 -6
- package/dist/chat/headless/session-list.d.ts +11 -0
- package/dist/chat/headless/sidebar/index.js +1 -1
- package/dist/chat/headless/sidebar/labels.d.ts +12 -1
- package/dist/chat/headless/transcript-host.d.ts +8 -1
- package/dist/chat/headless/transcript-labels.d.ts +2 -0
- package/dist/chat/index.d.ts +3 -3
- package/dist/chat/index.js +2 -2
- package/dist/chat/interactions/InboxPanel.js +2 -2
- package/dist/chat/interactions/QuestionField.js +2 -2
- package/dist/chat/rich-composer/RichComposer.d.ts +9 -2
- package/dist/chat/rich-composer/RichComposer.js +28 -7
- package/dist/chat/rich-composer/composer-extensions.d.ts +2 -0
- package/dist/chat/rich-composer/composer-extensions.js +2 -2
- package/dist/chat/rich-composer/composer-keys.js +1 -1
- package/dist/chat/rich-composer/use-composer-bus.js +2 -1
- package/dist/chat/rich-composer/use-composer-editor.d.ts +4 -1
- package/dist/chat/rich-composer/use-composer-editor.js +2 -1
- package/dist/chat/sidebar/SessionSidebar.js +1 -2
- package/dist/chat/sidebar/SidebarSearchRow.js +1 -1
- package/dist/chat/sidebar/useSidebarKeyboardNav.d.ts +0 -2
- package/dist/chat/sidebar/useSidebarKeyboardNav.js +7 -13
- package/dist/chat/testing/contract.d.ts +1 -1
- package/dist/chat/testing/contract.js +8 -7
- package/dist/chat/transcript/BadgeMenu.d.ts +12 -3
- package/dist/chat/transcript/BadgeMenu.js +20 -3
- package/dist/chat/transcript/CodemodeScript.js +147 -44
- package/dist/chat/transcript/EditDiffBlock.js +1 -4
- package/dist/chat/transcript/FileChip.js +60 -14
- package/dist/chat/transcript/LiveOutput.js +7 -3
- package/dist/chat/transcript/badges.js +2 -2
- package/dist/chat/transcript/index.d.ts +2 -2
- package/dist/chat/transcript/markdown-context.d.ts +4 -1
- package/dist/chat/transcript/rolling.d.ts +12 -0
- package/dist/chat/transcript/rolling.js +22 -0
- package/dist/chat/transcript/script-input.d.ts +1 -1
- package/dist/chat/transcript/shell-block.js +70 -60
- package/dist/chat/transcript/tool-row.js +21 -5
- package/dist/code/editor/FileTree.d.ts +3 -1
- package/dist/code/editor/FileTree.js +29 -1
- package/dist/components/Restricted.d.ts +25 -0
- package/dist/components/Restricted.js +32 -0
- package/dist/components/StepFrame.d.ts +1 -1
- package/dist/components/ZidaneMark.d.ts +28 -0
- package/dist/components/ZidaneMark.js +114 -0
- package/dist/components/palette/PalettePanel.d.ts +7 -1
- package/dist/components/palette/PalettePanel.js +37 -11
- package/dist/components/zidane-mark.d.ts +52 -0
- package/dist/components/zidane-mark.js +94 -0
- package/dist/core.css +59 -6
- package/dist/dist/{index-DqCio7Nd.d.ts → index-Bq87OcGy.d.ts} +19 -12
- package/dist/dist/index.d.ts +1 -1
- package/dist/extensions/ExtensionSettingsSection.d.ts +18 -0
- package/dist/extensions/ExtensionSettingsSection.js +227 -0
- package/dist/extensions/headless/host.d.ts +1 -1
- package/dist/extensions/headless/labels.d.ts +41 -1
- package/dist/extensions/headless/labels.js +57 -0
- package/dist/extensions/headless/select.js +1 -2
- package/dist/extensions/index.d.ts +2 -1
- package/dist/extensions/index.js +2 -1
- package/dist/files/FilesTab.js +2 -0
- package/dist/files/TreeColumn.d.ts +5 -1
- package/dist/files/TreeColumn.js +6 -0
- package/dist/files/headless/fixture-host.js +5 -3
- package/dist/files/headless/host.d.ts +24 -6
- package/dist/files/headless/index.d.ts +2 -2
- package/dist/files/headless/labels.d.ts +1 -0
- package/dist/files/headless/labels.js +1 -0
- package/dist/files/testing/contract.js +9 -2
- package/dist/files/useWorkspace.d.ts +14 -2
- package/dist/files/useWorkspace.js +87 -9
- package/dist/git/BranchMenu.js +1 -1
- package/dist/git/MoveSessionDialog.js +1 -1
- package/dist/git/RemoteFolderPicker.js +1 -1
- package/dist/git/WherePicker.js +1 -1
- package/dist/git/headless/index.js +1 -1
- package/dist/git/useEnvironmentChoices.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/keybindings/headless/catalog.js +1 -1
- package/dist/labels.d.ts +1 -0
- package/dist/labels.js +1 -0
- package/dist/machines/DaemonMenu.js +1 -1
- package/dist/machines/HostCapabilities.d.ts +23 -1
- package/dist/machines/HostCapabilities.js +149 -65
- package/dist/machines/HostSyncPanel.js +129 -123
- package/dist/machines/HostsSection.js +5 -1
- package/dist/machines/ServerCard.d.ts +4 -2
- package/dist/machines/ServerCard.js +222 -99
- package/dist/machines/ServerMachinesPanel.js +16 -13
- package/dist/machines/ServerUpdatePanel.js +31 -21
- package/dist/machines/TokensPanel.js +75 -53
- package/dist/machines/headless/fixture-host.d.ts +5 -0
- package/dist/machines/headless/fixture-host.js +13 -4
- package/dist/machines/headless/fixtures.js +1 -1
- package/dist/machines/headless/host.d.ts +22 -2
- package/dist/machines/headless/index.d.ts +2 -2
- package/dist/machines/headless/labels.d.ts +22 -1
- package/dist/machines/headless/labels.js +22 -2
- package/dist/machines/testing/contract.d.ts +3 -1
- package/dist/machines/testing/contract.js +9 -0
- package/dist/motion/size.d.ts +22 -1
- package/dist/motion/size.js +82 -4
- package/dist/onboarding/demos/delivery.d.ts +16 -0
- package/dist/onboarding/demos/delivery.js +132 -0
- package/dist/onboarding/demos/index.d.ts +2 -1
- package/dist/onboarding/demos/index.js +2 -1
- package/dist/onboarding/headless/labels.d.ts +8 -0
- package/dist/onboarding/headless/labels.js +7 -0
- package/dist/onboarding/index.d.ts +2 -1
- package/dist/onboarding/index.js +2 -1
- package/dist/onboarding/steps/ConversationStep.js +46 -4
- package/dist/palette/CommandPalette.js +3 -0
- package/dist/palette/PaletteDialog.js +7 -3
- package/dist/palette/usePaletteController.d.ts +10 -0
- package/dist/palette/usePaletteController.js +25 -3
- package/dist/server/sse-handler.js +6 -1
- package/dist/session/ArtifactsPanel.js +1 -1
- package/dist/session/SideChat.js +1 -2
- package/dist/session/UsagePanel.js +1 -1
- package/dist/session/headless/host.d.ts +3 -1
- package/dist/session/headless/index.js +2 -2
- package/dist/settings/SettingsRestricted.d.ts +25 -0
- package/dist/settings/SettingsRestricted.js +44 -0
- package/dist/settings/SettingsRowsPage.js +31 -37
- package/dist/settings/headless/catalog.js +7 -6
- package/dist/settings/headless/labels.d.ts +4 -2
- package/dist/settings/headless/labels.js +4 -2
- package/dist/settings/headless/layout.js +1 -1
- package/dist/settings/headless/providers.d.ts +2 -0
- package/dist/settings/headless/search.d.ts +1 -1
- package/dist/settings/index.d.ts +2 -2
- package/dist/settings/index.js +2 -2
- package/dist/settings/rows.d.ts +51 -8
- package/dist/settings/rows.js +81 -26
- package/dist/settings/sections/enabled-list/EnabledListSection.js +3 -2
- package/dist/settings/sections/environments/EnvironmentsSection.js +4 -3
- package/dist/settings/sections/extensions/ExtensionConfigRows.d.ts +2 -2
- package/dist/settings/sections/extensions/ExtensionConfigRows.js +22 -25
- package/dist/settings/sections/extensions/ExtensionOptionsSection.js +3 -2
- package/dist/settings/sections/extensions/options-labels.d.ts +2 -2
- package/dist/settings/sections/extensions/options-labels.js +2 -2
- package/dist/settings/sections/host-catalog/HostCatalogSection.d.ts +5 -3
- package/dist/settings/sections/host-catalog/HostCatalogSection.js +7 -4
- package/dist/settings/sections/instructions/InstructionsSection.js +24 -17
- package/dist/settings/sections/logs/LogsSection.d.ts +2 -1
- package/dist/settings/sections/logs/LogsSection.js +64 -56
- package/dist/settings/sections/mcp/McpSection.d.ts +1 -1
- package/dist/settings/sections/mcp/McpSection.js +18 -17
- package/dist/settings/sections/models/ModelRows.d.ts +3 -3
- package/dist/settings/sections/models/ModelRows.js +8 -7
- package/dist/settings/sections/performance/PerformanceSection.js +13 -4
- package/dist/settings/sections/performance/labels.d.ts +0 -1
- package/dist/settings/sections/performance/labels.js +0 -1
- package/dist/settings/sections/providers/CredentialSources.js +18 -8
- package/dist/settings/sections/providers/ProvidersSection.d.ts +2 -2
- package/dist/settings/sections/providers/ProvidersSection.js +20 -17
- package/dist/settings/sections/providers/ServerProvidersSection.d.ts +1 -1
- package/dist/settings/sections/providers/ServerProvidersSection.js +10 -14
- package/dist/settings/sections/shared/catalog.js +3 -2
- package/dist/settings/sections/skills/SkillList.js +3 -2
- package/dist/settings/testing/accounts-demo.js +1 -0
- package/dist/settings/testing/accounts.contract.js +2 -0
- package/dist/styles.css +160 -24
- package/dist/terminal/HostTerminalSurface.js +1 -1
- package/dist/terminal/headless/links.d.ts +19 -1
- package/dist/terminal/headless/links.js +26 -2
- package/dist/theme/css-vars.js +1 -0
- package/dist/theme/derive.d.ts +4 -0
- package/dist/theme/derive.js +2 -0
- package/dist/workspace/PanelContentView.js +1 -1
- package/dist/workspace/PanelHome.d.ts +3 -1
- package/dist/workspace/PanelHome.js +4 -3
- package/dist/workspace/SidePanel.d.ts +3 -1
- package/dist/workspace/SidePanel.js +3 -2
- package/dist/workspace/headless/open-target.d.ts +1 -1
- package/dist/workspace/headless/open-target.js +2 -2
- package/package.json +2 -2
- package/src/styles/chat.css +10 -10
- package/src/styles/motion.css +37 -0
- package/src/styles/primitives.css +11 -3
- package/src/styles/sidebar.css +12 -0
- package/src/styles/tokens.css +6 -0
- package/src/styles/transcript.css +69 -5
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { iconButtonClass } from "../../components/IconButton.js";
|
|
2
2
|
import { CopyButton } from "../../components/CopyButton.js";
|
|
3
|
+
import { Grow, GrowPresence } from "../../motion/grow.js";
|
|
4
|
+
import { SmoothHeight } from "../../motion/size.js";
|
|
3
5
|
import { constant, useReadable } from "../headless/store.js";
|
|
4
6
|
import "../headless/block-runs.js";
|
|
5
7
|
import { useOptionalChatHost } from "../ChatProvider.js";
|
|
@@ -68,6 +70,8 @@ function RunnableCodeBlock({ code, language, scope, CodeBlock }) {
|
|
|
68
70
|
const live = useReadable(blocks ? blocks.live(scope.sessionId) : NO_LIVE)[key];
|
|
69
71
|
const caretRef = useRef(null);
|
|
70
72
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
73
|
+
const [shownAtMount] = useState(() => live !== void 0 || saved !== void 0);
|
|
74
|
+
const [removed, setRemoved] = useState(false);
|
|
71
75
|
const [menuArmed, setMenuArmed] = useState(false);
|
|
72
76
|
if (!plan || !blocks && !runInTerminal) return /* @__PURE__ */ jsx(CodeBlock, {
|
|
73
77
|
code,
|
|
@@ -153,16 +157,23 @@ function RunnableCodeBlock({ code, language, scope, CodeBlock }) {
|
|
|
153
157
|
items: menu
|
|
154
158
|
})
|
|
155
159
|
}),
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
live,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
160
|
+
/* @__PURE__ */ jsx(GrowPresence, {
|
|
161
|
+
initial: false,
|
|
162
|
+
children: (live ?? saved) && /* @__PURE__ */ jsx(Grow, {
|
|
163
|
+
appear: !shownAtMount || removed,
|
|
164
|
+
children: /* @__PURE__ */ jsx(RunPanel, {
|
|
165
|
+
code,
|
|
166
|
+
live,
|
|
167
|
+
saved,
|
|
168
|
+
onAgain: runHere,
|
|
169
|
+
onTerminal: inTerminal,
|
|
170
|
+
onRemove: () => {
|
|
171
|
+
setRemoved(true);
|
|
172
|
+
if (live?.error !== void 0) stop();
|
|
173
|
+
else if (blocks && saved) blocks.remove(scope.sessionId, key);
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
}, "run")
|
|
166
177
|
})
|
|
167
178
|
]
|
|
168
179
|
});
|
|
@@ -222,58 +233,57 @@ function RunPanel({ code, live, saved, onAgain, onTerminal, onRemove }) {
|
|
|
222
233
|
className: "zg-run-panel group",
|
|
223
234
|
"aria-label": labels.blockRunOutput,
|
|
224
235
|
"data-failed": failed ? "" : void 0,
|
|
225
|
-
children: [
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
className: "i-ph-paperclip text-zg-label"
|
|
244
|
-
})
|
|
245
|
-
})] }),
|
|
246
|
-
onAgain && /* @__PURE__ */ jsx("button", {
|
|
247
|
-
type: "button",
|
|
248
|
-
"aria-label": labels.blockRunAgain,
|
|
249
|
-
title: labels.blockRunAgain,
|
|
250
|
-
onClick: onAgain,
|
|
251
|
-
className: `zg-reveal ${button}`,
|
|
252
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
253
|
-
"aria-hidden": true,
|
|
254
|
-
className: "i-ph-arrow-clockwise text-zg-label"
|
|
255
|
-
})
|
|
256
|
-
}),
|
|
257
|
-
/* @__PURE__ */ jsx("button", {
|
|
258
|
-
type: "button",
|
|
259
|
-
"aria-label": labels.blockRunRemove,
|
|
260
|
-
title: labels.blockRunRemove,
|
|
261
|
-
onClick: onRemove,
|
|
262
|
-
className: `zg-reveal ${button}`,
|
|
263
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
264
|
-
"aria-hidden": true,
|
|
265
|
-
className: "i-ph-x text-zg-label"
|
|
266
|
-
})
|
|
236
|
+
children: [/* @__PURE__ */ jsxs("header", {
|
|
237
|
+
className: "zg-meta flex items-center gap-2 min-h-6",
|
|
238
|
+
children: [status, /* @__PURE__ */ jsx("span", {
|
|
239
|
+
className: "ml-auto flex items-center gap-0.5",
|
|
240
|
+
children: !running && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
241
|
+
saved && text !== "" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(CopyButton, {
|
|
242
|
+
text,
|
|
243
|
+
label: labels.blockRunCopy,
|
|
244
|
+
reveal: true
|
|
245
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
246
|
+
type: "button",
|
|
247
|
+
"aria-label": labels.blockRunAttach,
|
|
248
|
+
title: labels.blockRunAttach,
|
|
249
|
+
onClick: attach,
|
|
250
|
+
className: `zg-reveal ${button}`,
|
|
251
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
252
|
+
"aria-hidden": true,
|
|
253
|
+
className: "i-ph-paperclip text-zg-label"
|
|
267
254
|
})
|
|
268
|
-
] })
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
255
|
+
})] }),
|
|
256
|
+
onAgain && /* @__PURE__ */ jsx("button", {
|
|
257
|
+
type: "button",
|
|
258
|
+
"aria-label": labels.blockRunAgain,
|
|
259
|
+
title: labels.blockRunAgain,
|
|
260
|
+
onClick: onAgain,
|
|
261
|
+
className: `zg-reveal ${button}`,
|
|
262
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
263
|
+
"aria-hidden": true,
|
|
264
|
+
className: "i-ph-arrow-clockwise text-zg-label"
|
|
265
|
+
})
|
|
266
|
+
}),
|
|
267
|
+
/* @__PURE__ */ jsx("button", {
|
|
268
|
+
type: "button",
|
|
269
|
+
"aria-label": labels.blockRunRemove,
|
|
270
|
+
title: labels.blockRunRemove,
|
|
271
|
+
onClick: onRemove,
|
|
272
|
+
className: `zg-reveal ${button}`,
|
|
273
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
274
|
+
"aria-hidden": true,
|
|
275
|
+
className: "i-ph-x text-zg-label"
|
|
276
|
+
})
|
|
277
|
+
})
|
|
278
|
+
] })
|
|
279
|
+
})]
|
|
280
|
+
}), /* @__PURE__ */ jsxs(SmoothHeight, {
|
|
281
|
+
swapKey: running ? live.lines.length > 0 ? "live" : "starting" : live ? "failed" : "saved",
|
|
282
|
+
children: [live ? live.lines.length > 0 && /* @__PURE__ */ jsx(LiveOutput, {
|
|
272
283
|
lines: live.lines,
|
|
273
284
|
window: 15,
|
|
274
285
|
label: labels.blockRunOutput
|
|
275
|
-
}) : saved && saved.output !== "" && /* @__PURE__ */ jsx(RunOutput, { run: saved }),
|
|
276
|
-
failed && !running && onTerminal && /* @__PURE__ */ jsxs("button", {
|
|
286
|
+
}) : saved && saved.output !== "" && /* @__PURE__ */ jsx(RunOutput, { run: saved }), failed && !running && onTerminal && /* @__PURE__ */ jsxs("button", {
|
|
277
287
|
type: "button",
|
|
278
288
|
onClick: onTerminal,
|
|
279
289
|
className: "zg-run-terminal zg-meta",
|
|
@@ -281,8 +291,8 @@ function RunPanel({ code, live, saved, onAgain, onTerminal, onRemove }) {
|
|
|
281
291
|
"aria-hidden": true,
|
|
282
292
|
className: "i-ph-terminal-window"
|
|
283
293
|
}), labels.blockRunNeedsTerminal]
|
|
284
|
-
})
|
|
285
|
-
]
|
|
294
|
+
})]
|
|
295
|
+
})]
|
|
286
296
|
});
|
|
287
297
|
}
|
|
288
298
|
/** A saved run's output, scrolled to its end: where a command says how it went. */
|
|
@@ -3,6 +3,7 @@ import { useDisplayPath } from "../../hooks/useDisplayPath.js";
|
|
|
3
3
|
import { useChatLabels } from "../useChatLabels.js";
|
|
4
4
|
import { useModelName } from "./actions.js";
|
|
5
5
|
import { Caret, FailedMark } from "./frame.js";
|
|
6
|
+
import { Rolling } from "./rolling.js";
|
|
6
7
|
import { AnsiText } from "./AnsiText.js";
|
|
7
8
|
import { CODE_PANEL, LoadFullOutputButton, ReadFileBlock, ToolGlyph, ToolInput, ToolTiming, useFullOutput } from "./tool-parts.js";
|
|
8
9
|
import { EditDiffBlock } from "./EditDiffBlock.js";
|
|
@@ -311,19 +312,34 @@ function ScriptProgressChips({ tool }) {
|
|
|
311
312
|
"data-testid": "script-progress",
|
|
312
313
|
children: [view.total !== void 0 && view.percent !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
313
314
|
className: "zg-meta-chip",
|
|
314
|
-
children:
|
|
315
|
+
children: /* @__PURE__ */ jsx(Rolling, {
|
|
316
|
+
text: labels.scriptCallsOf(view.done, view.total),
|
|
317
|
+
value: view.done
|
|
318
|
+
})
|
|
315
319
|
}), /* @__PURE__ */ jsx("span", {
|
|
316
320
|
className: "zg-meta-chip",
|
|
317
|
-
children:
|
|
321
|
+
children: /* @__PURE__ */ jsx(Rolling, {
|
|
322
|
+
text: labels.scriptPercent(view.percent),
|
|
323
|
+
value: view.percent
|
|
324
|
+
})
|
|
318
325
|
})] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
319
326
|
className: "zg-meta-chip",
|
|
320
|
-
children:
|
|
327
|
+
children: /* @__PURE__ */ jsx(Rolling, {
|
|
328
|
+
text: labels.scriptCallsDone(view.done),
|
|
329
|
+
value: view.done
|
|
330
|
+
})
|
|
321
331
|
}), view.running > 0 && /* @__PURE__ */ jsx("span", {
|
|
322
332
|
className: "zg-meta-chip",
|
|
323
|
-
children:
|
|
333
|
+
children: /* @__PURE__ */ jsx(Rolling, {
|
|
334
|
+
text: labels.scriptCallsRunning(view.running),
|
|
335
|
+
value: view.running
|
|
336
|
+
})
|
|
324
337
|
})] }), view.failed > 0 && /* @__PURE__ */ jsx("span", {
|
|
325
338
|
className: "zg-meta-chip text-zg-danger",
|
|
326
|
-
children:
|
|
339
|
+
children: /* @__PURE__ */ jsx(Rolling, {
|
|
340
|
+
text: labels.scriptCallsFailed(view.failed),
|
|
341
|
+
value: view.failed
|
|
342
|
+
})
|
|
327
343
|
})]
|
|
328
344
|
});
|
|
329
345
|
}
|
|
@@ -87,6 +87,8 @@ interface FileTreeProps {
|
|
|
87
87
|
label?: string;
|
|
88
88
|
/** Rename, create, drag and drop. Absent: the tree only browses. Read when the tree is created. */
|
|
89
89
|
editing?: FileTreeEditing;
|
|
90
|
+
/** An ignored folder listed as one node was expanded (its path, without the trailing `/`). */
|
|
91
|
+
onExpandFolder?: (path: string) => void;
|
|
90
92
|
}
|
|
91
93
|
/**
|
|
92
94
|
* The workspace file tree: rows from `entries`, painted with `gitStatus`, reporting selection,
|
|
@@ -94,7 +96,7 @@ interface FileTreeProps {
|
|
|
94
96
|
*
|
|
95
97
|
* @param props - The paths, git status and selection to show, and the handlers it reports to.
|
|
96
98
|
*/
|
|
97
|
-
declare function FileTree({ controlRef, entries, gitStatus, selectedPath, onSelect, onOpen, onContextMenu, className, style, openPaths, label, editing }: FileTreeProps): import("react").JSX.Element;
|
|
99
|
+
declare function FileTree({ controlRef, entries, gitStatus, selectedPath, onSelect, onOpen, onContextMenu, className, style, openPaths, label, editing, onExpandFolder }: FileTreeProps): import("react").JSX.Element;
|
|
98
100
|
/**
|
|
99
101
|
* Every folder holding one of `paths` (`src/`, `src/chat/`), as tree ids.
|
|
100
102
|
*
|
|
@@ -18,6 +18,10 @@ import { FileTree as FileTree$1, useFileTree } from "@pierre/trees/react";
|
|
|
18
18
|
* (⌥ held: a copy), and files dragged in from outside the page drop onto a
|
|
19
19
|
* folder. The tree shows each change at once and reports it; the host does
|
|
20
20
|
* it, then hands new `entries` (or calls `control.resync` when it failed).
|
|
21
|
+
*
|
|
22
|
+
* An ignored folder listed as one node (`dist/`, `ignored`) is opened like any
|
|
23
|
+
* folder; the tree reports it (`onExpandFolder`) so the host can list what
|
|
24
|
+
* is under it and hand it in with the next `entries`.
|
|
21
25
|
*/
|
|
22
26
|
/** The drag data type a tree row carries (its path, relative to the tree's root): what an editor takes to open it. */
|
|
23
27
|
const TREE_PATH_MIME = "application/x-zidane-tree-path";
|
|
@@ -27,7 +31,7 @@ const TREE_PATH_MIME = "application/x-zidane-tree-path";
|
|
|
27
31
|
*
|
|
28
32
|
* @param props - The paths, git status and selection to show, and the handlers it reports to.
|
|
29
33
|
*/
|
|
30
|
-
function FileTree({ controlRef, entries, gitStatus, selectedPath, onSelect, onOpen, onContextMenu, className, style, openPaths, label, editing }) {
|
|
34
|
+
function FileTree({ controlRef, entries, gitStatus, selectedPath, onSelect, onOpen, onContextMenu, className, style, openPaths, label, editing, onExpandFolder }) {
|
|
31
35
|
const labels = useLabels();
|
|
32
36
|
const paths = useMemo(() => entries.map((e) => e.path), [entries]);
|
|
33
37
|
const editingRef = useRef(editing);
|
|
@@ -92,6 +96,30 @@ function FileTree({ controlRef, entries, gitStatus, selectedPath, onSelect, onOp
|
|
|
92
96
|
} }
|
|
93
97
|
} : {}
|
|
94
98
|
});
|
|
99
|
+
const lazyDirs = useMemo(() => entries.filter((e) => e.ignored && e.kind === "dir" && e.path.endsWith("/")).map((e) => e.path), [entries]);
|
|
100
|
+
const lazyRef = useRef({
|
|
101
|
+
dirs: lazyDirs,
|
|
102
|
+
onExpandFolder
|
|
103
|
+
});
|
|
104
|
+
lazyRef.current = {
|
|
105
|
+
dirs: lazyDirs,
|
|
106
|
+
onExpandFolder
|
|
107
|
+
};
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
const open = /* @__PURE__ */ new Set();
|
|
110
|
+
return model.subscribe(() => {
|
|
111
|
+
const { dirs, onExpandFolder: report } = lazyRef.current;
|
|
112
|
+
if (!report) return;
|
|
113
|
+
for (const path of dirs) {
|
|
114
|
+
const item = model.getItem(path);
|
|
115
|
+
if (!(item !== null && "isExpanded" in item && item.isExpanded())) open.delete(path);
|
|
116
|
+
else if (!open.has(path)) {
|
|
117
|
+
open.add(path);
|
|
118
|
+
report(bare(path));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}, [model]);
|
|
95
123
|
useEffect(() => {
|
|
96
124
|
if (!editable) return;
|
|
97
125
|
return model.onMutation("remove", (event) => {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from "react";
|
|
2
|
+
//#region src/components/Restricted.d.ts
|
|
3
|
+
/** Props for {@link Restricted}. */
|
|
4
|
+
interface RestrictedProps {
|
|
5
|
+
/** Whether this connection may not change what it wraps. */
|
|
6
|
+
restricted: boolean;
|
|
7
|
+
/** Why, short: the tooltip and the group's accessible name ("Admin only"). */
|
|
8
|
+
reason: string;
|
|
9
|
+
/** What it wraps. */
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
/** Wrap inline content (a button in a row) instead of a block (a section). */
|
|
12
|
+
inline?: boolean;
|
|
13
|
+
/** Classes merged on the root while restricted. */
|
|
14
|
+
className?: string;
|
|
15
|
+
/** Inline styles on the root while restricted. */
|
|
16
|
+
style?: CSSProperties;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Renders `children` dimmed and inert, with `reason` as a tooltip, while `restricted`; else as they are.
|
|
20
|
+
*
|
|
21
|
+
* @param props - {@link RestrictedProps}.
|
|
22
|
+
*/
|
|
23
|
+
declare function Restricted({ restricted, reason, children, inline, className, style }: RestrictedProps): import("react").JSX.Element;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { Restricted, RestrictedProps };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Tooltip } from "./Tooltip.js";
|
|
2
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/components/Restricted.tsx
|
|
4
|
+
/**
|
|
5
|
+
* Renders `children` dimmed and inert, with `reason` as a tooltip, while `restricted`; else as they are.
|
|
6
|
+
*
|
|
7
|
+
* @param props - {@link RestrictedProps}.
|
|
8
|
+
*/
|
|
9
|
+
function Restricted({ restricted, reason, children, inline = false, className = "", style }) {
|
|
10
|
+
if (!restricted) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
11
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
12
|
+
label: reason,
|
|
13
|
+
portal: true,
|
|
14
|
+
className: `${inline ? "" : "flex w-full"} ${className}`,
|
|
15
|
+
...style ? { style } : {},
|
|
16
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
17
|
+
role: "group",
|
|
18
|
+
tabIndex: 0,
|
|
19
|
+
"aria-label": reason,
|
|
20
|
+
"aria-disabled": true,
|
|
21
|
+
"data-restricted": "",
|
|
22
|
+
className: `zg-restricted zg-focus-ring rounded-zg-md ${inline ? "inline-flex" : "block w-full"}`,
|
|
23
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
24
|
+
inert: true,
|
|
25
|
+
className: inline ? "inline-flex" : "block",
|
|
26
|
+
children
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { Restricted };
|
|
@@ -2,7 +2,7 @@ import { CSSProperties, ReactNode } from "react";
|
|
|
2
2
|
//#region src/components/StepFrame.d.ts
|
|
3
3
|
/** Props for {@link StepFrame}. */
|
|
4
4
|
interface StepFrameProps {
|
|
5
|
-
/** Small
|
|
5
|
+
/** Small label above the title, such as the step's name. */
|
|
6
6
|
eyebrow?: ReactNode;
|
|
7
7
|
/** The step's question or heading. */
|
|
8
8
|
title: ReactNode;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CSSProperties } from "react";
|
|
2
|
+
//#region src/components/ZidaneMark.d.ts
|
|
3
|
+
type Tone = 'inherit' | 'accent' | 'warn' | 'muted';
|
|
4
|
+
/** Props for {@link ZidaneMark}. */
|
|
5
|
+
interface ZidaneMarkProps {
|
|
6
|
+
/** Width and height in pixels. Small marks draw fewer, wider bands. @default 16 */
|
|
7
|
+
size?: number;
|
|
8
|
+
/** Loops per second; 0 holds still. @default 1.2 */
|
|
9
|
+
speed?: number;
|
|
10
|
+
/** Colour of the bands. `inherit` follows the surrounding text colour. @default 'accent' */
|
|
11
|
+
tone?: Tone;
|
|
12
|
+
/** Accessible name and tooltip. Defaults to the `working` label from {@link useLabels}. */
|
|
13
|
+
label?: string;
|
|
14
|
+
/** Hidden from assistive tech, for a mark inside an element that names the state itself. */
|
|
15
|
+
decorative?: boolean;
|
|
16
|
+
/** Extra classes on the root. */
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Inline styles on the root element, merged after the component's own. */
|
|
19
|
+
style?: CSSProperties;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Renders the zidane mark, its bands flowing while `speed` is above 0 and motion is on.
|
|
23
|
+
*
|
|
24
|
+
* @param props - Component props.
|
|
25
|
+
*/
|
|
26
|
+
declare function ZidaneMark({ size, speed, tone, label: labelProp, decorative, className, style }: ZidaneMarkProps): import("react").JSX.Element;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { ZidaneMark, ZidaneMarkProps };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { useLabels } from "../labels.js";
|
|
2
|
+
import { useReducedMotion } from "../motion/reduced.js";
|
|
3
|
+
import { markDetail, markEase, markFrame, markFrameIndex, markStill } from "./zidane-mark.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
6
|
+
//#region src/components/ZidaneMark.tsx
|
|
7
|
+
/**
|
|
8
|
+
* The zidane mark as a live indicator: the logo's sphere, its S-shaped bands
|
|
9
|
+
* flowing across it. One shared animation frame loop draws every mounted
|
|
10
|
+
* mark (it writes the paths' `d` straight to the DOM, so nothing
|
|
11
|
+
* re-renders), from frames cached per detail (`zidane-mark.ts`). A mark
|
|
12
|
+
* starts at its full pace; a later change of `speed` eases in rather than
|
|
13
|
+
* jumping. Reduced or off motion shows the still mark. Bands take
|
|
14
|
+
* `currentColor` over a faint disk of the same tone. To spin it in and out
|
|
15
|
+
* with a state, wrap it in a `Presence` with `zg-mark-swap` (styles/motion.css).
|
|
16
|
+
*/
|
|
17
|
+
const TONE = {
|
|
18
|
+
inherit: void 0,
|
|
19
|
+
accent: "var(--zg-accent)",
|
|
20
|
+
warn: "var(--zg-warn)",
|
|
21
|
+
muted: "var(--zg-text-muted)"
|
|
22
|
+
};
|
|
23
|
+
const live = /* @__PURE__ */ new Set();
|
|
24
|
+
let raf = 0;
|
|
25
|
+
let last = 0;
|
|
26
|
+
function tick(now) {
|
|
27
|
+
const dt = last ? Math.min(.1, (now - last) / 1e3) : 0;
|
|
28
|
+
last = now;
|
|
29
|
+
for (const mark of live) {
|
|
30
|
+
mark.speed += (mark.target - mark.speed) * Math.min(1, dt * 3);
|
|
31
|
+
mark.phase = (mark.phase + dt * mark.speed / 3) % 1;
|
|
32
|
+
const frame = markFrameIndex(markEase(mark.phase));
|
|
33
|
+
if (frame === mark.drawn) continue;
|
|
34
|
+
mark.drawn = frame;
|
|
35
|
+
const d = markFrame(mark.detail, frame);
|
|
36
|
+
mark.paths.forEach((path, i) => path.setAttribute("d", d[i] ?? ""));
|
|
37
|
+
}
|
|
38
|
+
raf = live.size > 0 ? requestAnimationFrame(tick) : 0;
|
|
39
|
+
if (!raf) last = 0;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Renders the zidane mark, its bands flowing while `speed` is above 0 and motion is on.
|
|
43
|
+
*
|
|
44
|
+
* @param props - Component props.
|
|
45
|
+
*/
|
|
46
|
+
function ZidaneMark({ size = 16, speed = 1.2, tone = "accent", label: labelProp, decorative = false, className = "", style }) {
|
|
47
|
+
const labels = useLabels();
|
|
48
|
+
const label = labelProp ?? labels.working;
|
|
49
|
+
const reduced = useReducedMotion();
|
|
50
|
+
const detail = useMemo(() => markDetail(size), [size]);
|
|
51
|
+
const still = markStill(detail);
|
|
52
|
+
const svg = useRef(null);
|
|
53
|
+
const mark = useRef(null);
|
|
54
|
+
const moving = !reduced && speed > 0;
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
const el = svg.current;
|
|
57
|
+
if (!moving || !el || typeof requestAnimationFrame !== "function") return void 0;
|
|
58
|
+
const entry = {
|
|
59
|
+
paths: Array.from(el.querySelectorAll("path")),
|
|
60
|
+
detail,
|
|
61
|
+
phase: 0,
|
|
62
|
+
speed,
|
|
63
|
+
target: speed,
|
|
64
|
+
drawn: 0
|
|
65
|
+
};
|
|
66
|
+
mark.current = entry;
|
|
67
|
+
live.add(entry);
|
|
68
|
+
if (!raf) raf = requestAnimationFrame(tick);
|
|
69
|
+
return () => {
|
|
70
|
+
live.delete(entry);
|
|
71
|
+
mark.current = null;
|
|
72
|
+
if (live.size === 0 && raf) {
|
|
73
|
+
cancelAnimationFrame(raf);
|
|
74
|
+
raf = 0;
|
|
75
|
+
last = 0;
|
|
76
|
+
}
|
|
77
|
+
const d = markStill(detail);
|
|
78
|
+
entry.paths.forEach((path, i) => path.setAttribute("d", d[i] ?? ""));
|
|
79
|
+
};
|
|
80
|
+
}, [moving, detail]);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (mark.current) mark.current.target = speed;
|
|
83
|
+
}, [speed]);
|
|
84
|
+
const color = TONE[tone];
|
|
85
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
86
|
+
ref: svg,
|
|
87
|
+
viewBox: "-1 -1 2 2",
|
|
88
|
+
width: size,
|
|
89
|
+
height: size,
|
|
90
|
+
...decorative ? { "aria-hidden": true } : {
|
|
91
|
+
role: "img",
|
|
92
|
+
"aria-label": label
|
|
93
|
+
},
|
|
94
|
+
className: `block shrink-0 ${className}`,
|
|
95
|
+
style: {
|
|
96
|
+
...color ? { color } : {},
|
|
97
|
+
...style
|
|
98
|
+
},
|
|
99
|
+
children: [
|
|
100
|
+
!decorative && /* @__PURE__ */ jsx("title", { children: label }),
|
|
101
|
+
/* @__PURE__ */ jsx("circle", {
|
|
102
|
+
r: "1",
|
|
103
|
+
fill: "currentColor",
|
|
104
|
+
opacity: "0.18"
|
|
105
|
+
}),
|
|
106
|
+
still.map((d, i) => /* @__PURE__ */ jsx("path", {
|
|
107
|
+
d,
|
|
108
|
+
fill: "currentColor"
|
|
109
|
+
}, i))
|
|
110
|
+
]
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
export { ZidaneMark };
|
|
@@ -49,6 +49,12 @@ type PalettePanelProps<T extends PaletteEntry = PaletteEntry> = PanelElementProp
|
|
|
49
49
|
onBack?: () => void;
|
|
50
50
|
/** The level's name, as a chip before the query. */
|
|
51
51
|
title?: string;
|
|
52
|
+
/** The section the root search is scoped to, as a chip before the query. */
|
|
53
|
+
scope?: string;
|
|
54
|
+
/** Shift+Tab at the root: scope the search to the next section (after the last, back to every section). */
|
|
55
|
+
onScopeNext?: () => void;
|
|
56
|
+
/** Backspace on an empty query at the root while scoped: search every section again. */
|
|
57
|
+
onScopeClear?: () => void;
|
|
52
58
|
/** Defaults to the labels' `paletteFilter`. */
|
|
53
59
|
placeholder?: string;
|
|
54
60
|
/** False while the rows are still for an earlier query: Enter waits for them. Default true. */
|
|
@@ -82,6 +88,6 @@ type PalettePanelProps<T extends PaletteEntry = PaletteEntry> = PanelElementProp
|
|
|
82
88
|
*
|
|
83
89
|
* @param props - {@link PalettePanelProps}.
|
|
84
90
|
*/
|
|
85
|
-
declare function PalettePanel<T extends PaletteEntry>({ groups, query, onQueryChange, cursor, onCursorChange, onRun, onClose, nested, onBack, title, placeholder, settled, loading, running, notice, verb, renderRow, renderIcon, renderKeys, inputRef, className, ...rest }: PalettePanelProps<T>): import("react").JSX.Element;
|
|
91
|
+
declare function PalettePanel<T extends PaletteEntry>({ groups, query, onQueryChange, cursor, onCursorChange, onRun, onClose, nested, onBack, title, scope, onScopeNext, onScopeClear, placeholder, settled, loading, running, notice, verb, renderRow, renderIcon, renderKeys, inputRef, className, ...rest }: PalettePanelProps<T>): import("react").JSX.Element;
|
|
86
92
|
//#endregion
|
|
87
93
|
export { PaletteNotice, PalettePanel, PalettePanelProps, paletteVerb };
|
|
@@ -11,7 +11,8 @@ import { Fragment as Fragment$1, useEffect, useMemo, useRef, useState } from "re
|
|
|
11
11
|
* desktop app's palette runs sources and nested pickers, the website opens
|
|
12
12
|
* a docs page). The panel owns the keys of its input: arrows, Home / End,
|
|
13
13
|
* Enter (held until the rows are for the query typed: `settled`), Escape,
|
|
14
|
-
*
|
|
14
|
+
* Backspace on an empty query to leave a nested level or drop the section
|
|
15
|
+
* scope, and Shift+Tab to move the scope to the next section.
|
|
15
16
|
*
|
|
16
17
|
* Mount it in a layer (an `Overlay`, the app's modal slot): it brings no
|
|
17
18
|
* scrim or focus trap of its own; its input takes focus on mount.
|
|
@@ -56,7 +57,7 @@ function paletteVerb(row, nested, labels) {
|
|
|
56
57
|
*
|
|
57
58
|
* @param props - {@link PalettePanelProps}.
|
|
58
59
|
*/
|
|
59
|
-
function PalettePanel({ groups, query, onQueryChange, cursor, onCursorChange, onRun, onClose, nested = false, onBack, title, placeholder, settled = true, loading = false, running = false, notice, verb, renderRow, renderIcon, renderKeys = defaultPaletteKeys, inputRef, className = "zg-modal-panel zg-float w-[40rem] max-w-[92vw] self-start mt-[13vh] flex flex-col overflow-hidden", ...rest }) {
|
|
60
|
+
function PalettePanel({ groups, query, onQueryChange, cursor, onCursorChange, onRun, onClose, nested = false, onBack, title, scope, onScopeNext, onScopeClear, placeholder, settled = true, loading = false, running = false, notice, verb, renderRow, renderIcon, renderKeys = defaultPaletteKeys, inputRef, className = "zg-modal-panel zg-float w-[40rem] max-w-[92vw] self-start mt-[13vh] flex flex-col overflow-hidden", ...rest }) {
|
|
60
61
|
const labels = useLabels();
|
|
61
62
|
const flat = useMemo(() => groups.flatMap((g) => g.rows), [groups]);
|
|
62
63
|
const showLoading = useLasting(loading, LOADING_LINE_AFTER_MS);
|
|
@@ -113,10 +114,22 @@ function PalettePanel({ groups, query, onQueryChange, cursor, onCursorChange, on
|
|
|
113
114
|
if (row) onRun(row);
|
|
114
115
|
return;
|
|
115
116
|
}
|
|
117
|
+
case "Tab":
|
|
118
|
+
if (e.shiftKey && !nested && onScopeNext) {
|
|
119
|
+
e.preventDefault();
|
|
120
|
+
e.stopPropagation();
|
|
121
|
+
onScopeNext();
|
|
122
|
+
onCursorChange(0);
|
|
123
|
+
}
|
|
124
|
+
return;
|
|
116
125
|
case "Backspace":
|
|
117
126
|
if (query === "" && nested && onBack) {
|
|
118
127
|
e.preventDefault();
|
|
119
128
|
onBack();
|
|
129
|
+
} else if (query === "" && !nested && scope && onScopeClear) {
|
|
130
|
+
e.preventDefault();
|
|
131
|
+
onScopeClear();
|
|
132
|
+
onCursorChange(0);
|
|
120
133
|
}
|
|
121
134
|
return;
|
|
122
135
|
}
|
|
@@ -144,6 +157,11 @@ function PalettePanel({ groups, query, onQueryChange, cursor, onCursorChange, on
|
|
|
144
157
|
className: "zg-track-chip shrink-0 px-2.5 h-6 inline-flex items-center text-zg-label text-[var(--zg-text-muted)]",
|
|
145
158
|
children: title
|
|
146
159
|
}),
|
|
160
|
+
!nested && scope && /* @__PURE__ */ jsx("span", {
|
|
161
|
+
"data-testid": "palette-scope",
|
|
162
|
+
className: "zg-track-chip shrink-0 px-2.5 h-6 inline-flex items-center text-zg-label text-[var(--zg-text)]",
|
|
163
|
+
children: scope
|
|
164
|
+
}),
|
|
147
165
|
/* @__PURE__ */ jsx("input", {
|
|
148
166
|
ref: inputRef,
|
|
149
167
|
autoFocus: true,
|
|
@@ -189,15 +207,23 @@ function PalettePanel({ groups, query, onQueryChange, cursor, onCursorChange, on
|
|
|
189
207
|
}),
|
|
190
208
|
/* @__PURE__ */ jsxs("div", {
|
|
191
209
|
className: "flex items-center gap-4 px-4 h-9 shrink-0 shadow-[inset_0_1px_0_var(--zg-hairline)]",
|
|
192
|
-
children: [
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
210
|
+
children: [
|
|
211
|
+
marked && /* @__PURE__ */ jsx(PaletteHint, {
|
|
212
|
+
keys: ["enter"],
|
|
213
|
+
label: verb?.(marked, nested) ?? paletteVerb(marked, nested, labels),
|
|
214
|
+
renderKeys
|
|
215
|
+
}),
|
|
216
|
+
nested && /* @__PURE__ */ jsx(PaletteHint, {
|
|
217
|
+
keys: ["⌫"],
|
|
218
|
+
label: labels.paletteBack,
|
|
219
|
+
renderKeys
|
|
220
|
+
}),
|
|
221
|
+
!nested && onScopeNext && /* @__PURE__ */ jsx(PaletteHint, {
|
|
222
|
+
keys: ["shift+tab"],
|
|
223
|
+
label: labels.paletteScopeHint,
|
|
224
|
+
renderKeys
|
|
225
|
+
})
|
|
226
|
+
]
|
|
201
227
|
}),
|
|
202
228
|
notice && /* @__PURE__ */ jsx("div", {
|
|
203
229
|
role: "status",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//#region src/components/zidane-mark.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The zidane mark's geometry: flat S-shaped stripes wrapped onto a sphere.
|
|
4
|
+
* In the flat texture a band lies between two curves
|
|
5
|
+
* u = c + amplitude·sin(WAVE·π·v) (v from -1 to 1)
|
|
6
|
+
* one and a half waves top to bottom, so each band reads as an S whose turns
|
|
7
|
+
* hook against the left and right rims, as in the logo (its stripe
|
|
8
|
+
* directions fitted to the app icon). The texture is spherized: a point at texture radius ρ lands at disk
|
|
9
|
+
* radius sin(ρ·π/2), so bands thin out toward the rim, and what lies past
|
|
10
|
+
* ρ = 1 collapses onto it. Shifting every band by one `spacing` gives the
|
|
11
|
+
* same picture, so a phase from 0 to 1 is one seamless loop. Coordinates are
|
|
12
|
+
* in the unit disk (viewBox `-1 -1 2 2`).
|
|
13
|
+
*/
|
|
14
|
+
/** How finely a mark is drawn: band pitch, band share, samples per edge. */
|
|
15
|
+
interface MarkDetail {
|
|
16
|
+
/** Texture distance from one band to the next (disk radius = 1). */
|
|
17
|
+
spacing: number;
|
|
18
|
+
/** Share of `spacing` that is band; the rest is gap. */
|
|
19
|
+
duty: number;
|
|
20
|
+
/** Samples along each band edge. */
|
|
21
|
+
steps: number;
|
|
22
|
+
}
|
|
23
|
+
/** The detail for a mark drawn `size` pixels wide: fewer, wider bands when small, so they stay apart. */
|
|
24
|
+
declare function markDetail(size: number): MarkDetail;
|
|
25
|
+
/**
|
|
26
|
+
* The band paths at `phase` (0 to 1, one loop). Always the same number of
|
|
27
|
+
* paths for a detail; a band out of view is an empty path.
|
|
28
|
+
*/
|
|
29
|
+
declare function markPaths(detail: MarkDetail, phase: number): string[];
|
|
30
|
+
/** Bands one swell carries: a slow surge, not a throb per band. */
|
|
31
|
+
declare const MARK_SWELL = 3;
|
|
32
|
+
/**
|
|
33
|
+
* Where a swell's time (0 to 1) puts the bands, in loops (0 to
|
|
34
|
+
* {@link MARK_SWELL}): they gather speed, peak mid-swell and settle, a
|
|
35
|
+
* raised-cosine bell of speed. Its mean is one loop per loop of time, so
|
|
36
|
+
* `speed` still counts loops per second, and a swell ends on a whole loop.
|
|
37
|
+
*/
|
|
38
|
+
declare function markEase(t: number): number;
|
|
39
|
+
/**
|
|
40
|
+
* Frames kept per loop. At the fastest pace (streaming, mid-swell) a loop
|
|
41
|
+
* takes about a third of a second, so 96 frames is still more than a display shows:
|
|
42
|
+
* snapping to them is invisible, and every mark of a detail shares them.
|
|
43
|
+
*/
|
|
44
|
+
declare const MARK_FRAMES = 96;
|
|
45
|
+
/** The frame index (0 to {@link MARK_FRAMES} - 1) a phase snaps to. */
|
|
46
|
+
declare function markFrameIndex(phase: number): number;
|
|
47
|
+
/** The band paths of frame `index` for a detail, computed once and kept. */
|
|
48
|
+
declare function markFrame(detail: MarkDetail, index: number): string[];
|
|
49
|
+
/** The still mark (phase 0) for a detail, computed once and kept. */
|
|
50
|
+
declare function markStill(detail: MarkDetail): string[];
|
|
51
|
+
//#endregion
|
|
52
|
+
export { MARK_FRAMES, MARK_SWELL, MarkDetail, markDetail, markEase, markFrame, markFrameIndex, markPaths, markStill };
|