@dsh-workbench/shared 0.2.12 → 0.2.14
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/components/ChoiceGroup.css +53 -3
- package/dist/components/ChoiceGroup.d.ts +5 -0
- package/dist/components/ChoiceGroup.js +15 -5
- package/dist/components/FormActions.css +13 -0
- package/dist/components/FormActions.d.ts +15 -0
- package/dist/components/FormActions.js +38 -0
- package/dist/components/FormRows.css +69 -0
- package/dist/components/FormRows.d.ts +14 -0
- package/dist/components/FormRows.js +11 -0
- package/dist/components/SaveBar.d.ts +0 -1
- package/dist/components/SaveBar.js +13 -5
- package/dist/components/SelectField.css +12 -4
- package/dist/components/SelectField.d.ts +1 -0
- package/dist/components/SelectField.js +9 -7
- package/dist/components/Spinner.css +6 -0
- package/dist/components/Spinner.d.ts +6 -0
- package/dist/components/Spinner.js +7 -0
- package/dist/components/TextField.css +2 -2
- package/dist/host.d.ts +3 -3
- package/dist/host.js +3 -3
- package/dist/i18n/en.js +9 -0
- package/dist/i18n/index.d.ts +10 -1
- package/dist/i18n/zh.d.ts +9 -0
- package/dist/i18n/zh.js +9 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.js +8 -4
- package/dist/lib/form-problem.d.ts +2 -0
- package/dist/lib/form-problem.js +20 -0
- package/package.json +2 -1
- package/src/components/ChoiceGroup.css +53 -3
- package/src/components/ChoiceGroup.test.tsx +88 -0
- package/src/components/ChoiceGroup.tsx +70 -28
- package/src/components/FormActions.css +13 -0
- package/src/components/FormActions.test.tsx +157 -0
- package/src/components/FormActions.tsx +75 -0
- package/src/components/FormRows.css +69 -0
- package/src/components/FormRows.test.tsx +138 -0
- package/src/components/FormRows.tsx +39 -0
- package/src/components/SaveBar.tsx +14 -18
- package/src/components/SelectField.css +12 -4
- package/src/components/SelectField.test.tsx +20 -2
- package/src/components/SelectField.tsx +11 -3
- package/src/components/Spinner.css +6 -0
- package/src/components/Spinner.test.tsx +35 -0
- package/src/components/Spinner.tsx +19 -0
- package/src/components/TextField.css +2 -2
- package/src/host.ts +3 -3
- package/src/i18n/en.ts +9 -0
- package/src/i18n/zh.ts +9 -0
- package/src/index.ts +8 -4
- package/src/lib/form-problem.test.ts +76 -0
- package/src/lib/form-problem.ts +22 -0
- package/src/components/SaveBar.css +0 -7
package/dist/i18n/index.d.ts
CHANGED
|
@@ -47,6 +47,15 @@ export declare const dictionaries: {
|
|
|
47
47
|
readonly 'status.completed': "已完成";
|
|
48
48
|
readonly 'status.subagentsRunning.one': "{n} 个子代理运行中";
|
|
49
49
|
readonly 'status.subagentsRunning.other': "{n} 个子代理运行中";
|
|
50
|
+
readonly 'project.attention.warning.one': "1 个会话在等你点头";
|
|
51
|
+
readonly 'project.attention.warning.other': "{n} 个会话在等你点头";
|
|
52
|
+
readonly 'project.attention.running.one': "1 个会话在跑";
|
|
53
|
+
readonly 'project.attention.running.other': "{n} 个会话在跑";
|
|
54
|
+
readonly 'project.attention.done.one': "1 个会话跑完没看";
|
|
55
|
+
readonly 'project.attention.done.other': "{n} 个会话跑完没看";
|
|
56
|
+
readonly 'project.attention.state.warning': "待审批";
|
|
57
|
+
readonly 'project.attention.state.running': "在跑";
|
|
58
|
+
readonly 'project.attention.state.done': "新消息";
|
|
50
59
|
readonly 'hover.copied': "已复制";
|
|
51
60
|
readonly 'time.now': "刚刚";
|
|
52
61
|
readonly 'time.minutes': "{n} 分钟前";
|
|
@@ -400,7 +409,7 @@ export declare const dictionaries: {
|
|
|
400
409
|
readonly 'configSync.emptyProviders': "工作台还没有任何模型供应商 —— 去「配置同步」从某个 profile 把 llm- 那几行搬过来,或自己去「模型」里配。";
|
|
401
410
|
readonly 'configSync.failed': "同步没成功,再试一次。";
|
|
402
411
|
};
|
|
403
|
-
en: Record<"time.now" | "time.ago" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.fix.update" | "blocker.market.open" | "env.unit.failed" | "env.unit.failedHint" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "project.add.busy" | "project.add.failed" | "project.search.label" | "project.search.placeholder" | "project.search.empty" | "project.group.workspaces" | "project.group.defaultWorkspace" | "project.group.workshop" | "project.rename.row" | "project.rename.current" | "project.rename.title" | "project.rename.description" | "project.rename.field" | "project.rename.placeholder" | "project.rename.hint" | "project.rename.save" | "project.rename.saving" | "project.rename.cancel" | "project.rename.failed" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.list.label" | "session.copy" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.compact.approval" | "status.compact.planReview" | "status.compact.answer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "hover.copied" | "time.short.minutes" | "time.short.hours" | "time.short.days" | "time.short.months" | "time.short.years" | "panels.title" | "panels.groupBoardless" | "panels.groupPlugins" | "panels.market.defaultHint" | "panels.market.defaultLabel" | "panels.market.defaultLocked" | "panels.followAll" | "panels.followAllConfirmTitle" | "panels.followAllConfirmDetail" | "panels.followAllConfirmAck" | "panels.followAllConfirmYes" | "panels.followAllConfirmNo" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.buildModule" | "panels.failed" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.dep.failed" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.notActive" | "panels.market.notUsable" | "panels.market.broken" | "panels.market.hasNew" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.swapSlow" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.failed" | "panels.market.needEnv" | "panels.market.needCommands" | "panels.market.localMark" | "panels.market.localHint" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.sectionPlugins" | "panels.market.moduleOutdated" | "panels.market.moduleRefused" | "panels.market.moduleRefusedDetail" | "panels.market.moduleRestartHint" | "panels.market.pendingRestart" | "panels.market.workbenchName" | "panels.market.workbenchLocal" | "panels.market.pluginKeptInUse" | "panels.market.pluginKeptUnsure" | "panels.market.pluginKeptHeld" | "panels.market.pluginKeptUnnamed" | "panels.market.pluginBroken" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNotWorkbenchModule" | "panels.market.add.problemNotModuleOrPlugin" | "panels.market.add.failureNotModuleOrPlugin" | "panels.market.add.installedPlugin" | "panels.market.add.pluginPreview" | "panels.market.add.pluginAlias" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureInstalled" | "panels.market.add.failureGeneric" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.classifying" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.restartWhy" | "panels.market.add.restartWhy.no-hmr" | "panels.market.add.restartWhy.package-moved" | "panels.market.add.restartWhy.host-module" | "panels.market.add.restartWhy.unmanaged-plugin" | "panels.market.add.restartWhy.module-comparison" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.cardBroken" | "panels.cardRetry" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.column.label" | "rightbar.column.workbench" | "rightbar.column.dsh" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "rightbar.openPlatform" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label" | "configSync.nav" | "configSync.lead" | "configSync.source" | "configSync.sourceBroken" | "configSync.sourceRows" | "configSync.sourceDead" | "configSync.refresh" | "configSync.loading" | "configSync.readHint" | "configSync.tag.new" | "configSync.tag.differs" | "configSync.conflictNote" | "configSync.code.lang" | "configSync.code.copy" | "configSync.code.copied" | "configSync.code.wrap" | "configSync.code.unwrap" | "configSync.code.collapse" | "configSync.code.collapseAria" | "configSync.code.expandAria" | "configSync.code.expand" | "configSync.missing" | "configSync.apply" | "configSync.applyNone" | "configSync.applying" | "configSync.applied" | "configSync.appliedIds" | "configSync.skippedIds" | "configSync.nothing" | "configSync.unreadable" | "configSync.noSource" | "configSync.emptyProviders" | "configSync.failed", string>;
|
|
412
|
+
en: Record<"time.now" | "time.ago" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.fix.update" | "blocker.market.open" | "env.unit.failed" | "env.unit.failedHint" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "project.add.busy" | "project.add.failed" | "project.search.label" | "project.search.placeholder" | "project.search.empty" | "project.group.workspaces" | "project.group.defaultWorkspace" | "project.group.workshop" | "project.rename.row" | "project.rename.current" | "project.rename.title" | "project.rename.description" | "project.rename.field" | "project.rename.placeholder" | "project.rename.hint" | "project.rename.save" | "project.rename.saving" | "project.rename.cancel" | "project.rename.failed" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.list.label" | "session.copy" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.compact.approval" | "status.compact.planReview" | "status.compact.answer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "project.attention.warning.one" | "project.attention.warning.other" | "project.attention.running.one" | "project.attention.running.other" | "project.attention.done.one" | "project.attention.done.other" | "project.attention.state.warning" | "project.attention.state.running" | "project.attention.state.done" | "hover.copied" | "time.short.minutes" | "time.short.hours" | "time.short.days" | "time.short.months" | "time.short.years" | "panels.title" | "panels.groupBoardless" | "panels.groupPlugins" | "panels.market.defaultHint" | "panels.market.defaultLabel" | "panels.market.defaultLocked" | "panels.followAll" | "panels.followAllConfirmTitle" | "panels.followAllConfirmDetail" | "panels.followAllConfirmAck" | "panels.followAllConfirmYes" | "panels.followAllConfirmNo" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.buildModule" | "panels.failed" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.dep.failed" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.notActive" | "panels.market.notUsable" | "panels.market.broken" | "panels.market.hasNew" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.swapSlow" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.failed" | "panels.market.needEnv" | "panels.market.needCommands" | "panels.market.localMark" | "panels.market.localHint" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.sectionPlugins" | "panels.market.moduleOutdated" | "panels.market.moduleRefused" | "panels.market.moduleRefusedDetail" | "panels.market.moduleRestartHint" | "panels.market.pendingRestart" | "panels.market.workbenchName" | "panels.market.workbenchLocal" | "panels.market.pluginKeptInUse" | "panels.market.pluginKeptUnsure" | "panels.market.pluginKeptHeld" | "panels.market.pluginKeptUnnamed" | "panels.market.pluginBroken" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNotWorkbenchModule" | "panels.market.add.problemNotModuleOrPlugin" | "panels.market.add.failureNotModuleOrPlugin" | "panels.market.add.installedPlugin" | "panels.market.add.pluginPreview" | "panels.market.add.pluginAlias" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureInstalled" | "panels.market.add.failureGeneric" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.classifying" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.restartWhy" | "panels.market.add.restartWhy.no-hmr" | "panels.market.add.restartWhy.package-moved" | "panels.market.add.restartWhy.host-module" | "panels.market.add.restartWhy.unmanaged-plugin" | "panels.market.add.restartWhy.module-comparison" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.cardBroken" | "panels.cardRetry" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.column.label" | "rightbar.column.workbench" | "rightbar.column.dsh" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "rightbar.openPlatform" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label" | "configSync.nav" | "configSync.lead" | "configSync.source" | "configSync.sourceBroken" | "configSync.sourceRows" | "configSync.sourceDead" | "configSync.refresh" | "configSync.loading" | "configSync.readHint" | "configSync.tag.new" | "configSync.tag.differs" | "configSync.conflictNote" | "configSync.code.lang" | "configSync.code.copy" | "configSync.code.copied" | "configSync.code.wrap" | "configSync.code.unwrap" | "configSync.code.collapse" | "configSync.code.collapseAria" | "configSync.code.expandAria" | "configSync.code.expand" | "configSync.missing" | "configSync.apply" | "configSync.applyNone" | "configSync.applying" | "configSync.applied" | "configSync.appliedIds" | "configSync.skippedIds" | "configSync.nothing" | "configSync.unreadable" | "configSync.noSource" | "configSync.emptyProviders" | "configSync.failed", string>;
|
|
404
413
|
};
|
|
405
414
|
export type { WorkbenchMessages };
|
|
406
415
|
export interface Dictionaries {
|
package/dist/i18n/zh.d.ts
CHANGED
|
@@ -45,6 +45,15 @@ export declare const zh: {
|
|
|
45
45
|
readonly 'status.completed': "已完成";
|
|
46
46
|
readonly 'status.subagentsRunning.one': "{n} 个子代理运行中";
|
|
47
47
|
readonly 'status.subagentsRunning.other': "{n} 个子代理运行中";
|
|
48
|
+
readonly 'project.attention.warning.one': "1 个会话在等你点头";
|
|
49
|
+
readonly 'project.attention.warning.other': "{n} 个会话在等你点头";
|
|
50
|
+
readonly 'project.attention.running.one': "1 个会话在跑";
|
|
51
|
+
readonly 'project.attention.running.other': "{n} 个会话在跑";
|
|
52
|
+
readonly 'project.attention.done.one': "1 个会话跑完没看";
|
|
53
|
+
readonly 'project.attention.done.other': "{n} 个会话跑完没看";
|
|
54
|
+
readonly 'project.attention.state.warning': "待审批";
|
|
55
|
+
readonly 'project.attention.state.running': "在跑";
|
|
56
|
+
readonly 'project.attention.state.done': "新消息";
|
|
48
57
|
readonly 'hover.copied': "已复制";
|
|
49
58
|
readonly 'time.now': "刚刚";
|
|
50
59
|
readonly 'time.minutes': "{n} 分钟前";
|
package/dist/i18n/zh.js
CHANGED
|
@@ -45,6 +45,15 @@ export const zh = {
|
|
|
45
45
|
'status.completed': '已完成',
|
|
46
46
|
'status.subagentsRunning.one': '{n} 个子代理运行中',
|
|
47
47
|
'status.subagentsRunning.other': '{n} 个子代理运行中',
|
|
48
|
+
'project.attention.warning.one': '1 个会话在等你点头',
|
|
49
|
+
'project.attention.warning.other': '{n} 个会话在等你点头',
|
|
50
|
+
'project.attention.running.one': '1 个会话在跑',
|
|
51
|
+
'project.attention.running.other': '{n} 个会话在跑',
|
|
52
|
+
'project.attention.done.one': '1 个会话跑完没看',
|
|
53
|
+
'project.attention.done.other': '{n} 个会话跑完没看',
|
|
54
|
+
'project.attention.state.warning': '待审批',
|
|
55
|
+
'project.attention.state.running': '在跑',
|
|
56
|
+
'project.attention.state.done': '新消息',
|
|
48
57
|
'hover.copied': '已复制',
|
|
49
58
|
'time.now': '刚刚',
|
|
50
59
|
'time.minutes': '{n} 分钟前',
|
package/dist/index.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ export * from './api/facts.js';
|
|
|
7
7
|
export * from './api/host-write.js';
|
|
8
8
|
export * from './api/long-task.js';
|
|
9
9
|
export * from './api/unit-board.js';
|
|
10
|
-
export * from './api/unit.js';
|
|
11
10
|
export * from './api/unit-declaration.js';
|
|
11
|
+
export * from './api/unit.js';
|
|
12
12
|
export * from './api/workbench-client.js';
|
|
13
13
|
export * from './api/workbench-contract.js';
|
|
14
14
|
export * from './components/Activity.js';
|
|
@@ -19,18 +19,21 @@ export * from './components/CardAnchor.js';
|
|
|
19
19
|
export * from './components/CardBoundary.js';
|
|
20
20
|
export * from './components/CardHead.js';
|
|
21
21
|
export * from './components/ChoiceGroup.js';
|
|
22
|
+
export * from './components/Field.js';
|
|
23
|
+
export * from './components/FormActions.js';
|
|
24
|
+
export * from './components/FormRows.js';
|
|
25
|
+
export * from './components/Link.js';
|
|
22
26
|
export * from './components/LongTaskRow.js';
|
|
23
27
|
export * from './components/Note.js';
|
|
24
28
|
export * from './components/ResourceStates.js';
|
|
25
29
|
export * from './components/Rows.js';
|
|
26
30
|
export * from './components/SaveBar.js';
|
|
27
|
-
export * from './components/SettingsSection.js';
|
|
28
31
|
export * from './components/SelectField.js';
|
|
32
|
+
export * from './components/SettingsSection.js';
|
|
33
|
+
export * from './components/Spinner.js';
|
|
29
34
|
export * from './components/Stack.js';
|
|
30
35
|
export * from './components/StateBlock.js';
|
|
31
36
|
export * from './components/TextField.js';
|
|
32
|
-
export * from './components/Field.js';
|
|
33
|
-
export * from './components/Link.js';
|
|
34
37
|
export * from './components/board-module.js';
|
|
35
38
|
export * from './components/icons.js';
|
|
36
39
|
export * from './config/constants.js';
|
|
@@ -41,6 +44,7 @@ export * from './i18n/merge.js';
|
|
|
41
44
|
export * from './i18n/zh.js';
|
|
42
45
|
export * from './lib/blocker-action.js';
|
|
43
46
|
export * from './lib/busy.js';
|
|
47
|
+
export * from './lib/form-problem.js';
|
|
44
48
|
export * from './lib/panel-state.js';
|
|
45
49
|
export * from './lib/react.js';
|
|
46
50
|
export * from './lib/text.js';
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,8 @@ export * from './api/facts.js';
|
|
|
7
7
|
export * from './api/host-write.js';
|
|
8
8
|
export * from './api/long-task.js';
|
|
9
9
|
export * from './api/unit-board.js';
|
|
10
|
-
export * from './api/unit.js';
|
|
11
10
|
export * from './api/unit-declaration.js';
|
|
11
|
+
export * from './api/unit.js';
|
|
12
12
|
export * from './api/workbench-client.js';
|
|
13
13
|
export * from './api/workbench-contract.js';
|
|
14
14
|
export * from './components/Activity.js';
|
|
@@ -19,18 +19,21 @@ export * from './components/CardAnchor.js';
|
|
|
19
19
|
export * from './components/CardBoundary.js';
|
|
20
20
|
export * from './components/CardHead.js';
|
|
21
21
|
export * from './components/ChoiceGroup.js';
|
|
22
|
+
export * from './components/Field.js';
|
|
23
|
+
export * from './components/FormActions.js';
|
|
24
|
+
export * from './components/FormRows.js';
|
|
25
|
+
export * from './components/Link.js';
|
|
22
26
|
export * from './components/LongTaskRow.js';
|
|
23
27
|
export * from './components/Note.js';
|
|
24
28
|
export * from './components/ResourceStates.js';
|
|
25
29
|
export * from './components/Rows.js';
|
|
26
30
|
export * from './components/SaveBar.js';
|
|
27
|
-
export * from './components/SettingsSection.js';
|
|
28
31
|
export * from './components/SelectField.js';
|
|
32
|
+
export * from './components/SettingsSection.js';
|
|
33
|
+
export * from './components/Spinner.js';
|
|
29
34
|
export * from './components/Stack.js';
|
|
30
35
|
export * from './components/StateBlock.js';
|
|
31
36
|
export * from './components/TextField.js';
|
|
32
|
-
export * from './components/Field.js';
|
|
33
|
-
export * from './components/Link.js';
|
|
34
37
|
export * from './components/board-module.js';
|
|
35
38
|
export * from './components/icons.js';
|
|
36
39
|
export * from './config/constants.js';
|
|
@@ -41,6 +44,7 @@ export * from './i18n/merge.js';
|
|
|
41
44
|
export * from './i18n/zh.js';
|
|
42
45
|
export * from './lib/blocker-action.js';
|
|
43
46
|
export * from './lib/busy.js';
|
|
47
|
+
export * from './lib/form-problem.js';
|
|
44
48
|
export * from './lib/panel-state.js';
|
|
45
49
|
export * from './lib/react.js';
|
|
46
50
|
export * from './lib/text.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const PROBLEM_SELECTOR = '[data-wb-problem]';
|
|
2
|
+
const FOCUSABLE_SELECTOR = [
|
|
3
|
+
'input:not([disabled])',
|
|
4
|
+
'select:not([disabled])',
|
|
5
|
+
'textarea:not([disabled])',
|
|
6
|
+
'button:not([disabled])',
|
|
7
|
+
'a[href]',
|
|
8
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
9
|
+
].join(', ');
|
|
10
|
+
export function firstProblemOf(root) {
|
|
11
|
+
return root.querySelector(PROBLEM_SELECTOR);
|
|
12
|
+
}
|
|
13
|
+
export function revealFirstProblem(root) {
|
|
14
|
+
const problem = firstProblemOf(root);
|
|
15
|
+
if (problem === null)
|
|
16
|
+
return false;
|
|
17
|
+
problem.scrollIntoView?.({ block: 'nearest' });
|
|
18
|
+
problem.querySelector(FOCUSABLE_SELECTOR)?.focus?.();
|
|
19
|
+
return true;
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-workbench/shared",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.14",
|
|
4
4
|
"description": "工作台与模块共享的纯代码与契约类型:类型、纯逻辑、哑组件、平台解析。宿主侧的东西从 /host 进(不影响浏览器产物)。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"typecheck": "tsc --noEmit",
|
|
44
44
|
"test": "vitest run",
|
|
45
45
|
"coverage": "vitest run --coverage",
|
|
46
|
+
"barrels": "node scripts/barrels.mjs",
|
|
46
47
|
"selfcheck": "node scripts/check-state.mjs",
|
|
47
48
|
"arch:report": "arch-guard --report-only",
|
|
48
49
|
"arch": "arch-guard"
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
display: flex;
|
|
4
4
|
flex-direction: column;
|
|
5
5
|
gap: var(--wb-len-2);
|
|
6
|
+
background: transparent;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.wb-choiceMenu[data-variant='boxed'] {
|
|
6
10
|
padding: var(--wb-len-4);
|
|
7
11
|
border: 0.5px solid var(--dsw-alias-border-l3);
|
|
8
12
|
border-radius: var(--dsw-radius-md);
|
|
9
|
-
background: transparent;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
.wb-choiceOption {
|
|
@@ -14,8 +17,8 @@
|
|
|
14
17
|
display: flex;
|
|
15
18
|
align-items: center;
|
|
16
19
|
gap: var(--wb-len-6);
|
|
17
|
-
min-height: var(--wb-len-
|
|
18
|
-
padding: var(--wb-len-
|
|
20
|
+
min-height: var(--wb-len-28);
|
|
21
|
+
padding: var(--wb-len-4) var(--wb-len-8);
|
|
19
22
|
border-radius: var(--dsw-radius-md);
|
|
20
23
|
cursor: pointer;
|
|
21
24
|
font-size: var(--dsw-font-xs-13-font-size);
|
|
@@ -87,12 +90,59 @@
|
|
|
87
90
|
|
|
88
91
|
.wb-choiceLabel {
|
|
89
92
|
flex: 1;
|
|
93
|
+
min-width: 0;
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
96
|
+
overflow: hidden;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.wb-choiceLabelText {
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
text-overflow: ellipsis;
|
|
102
|
+
white-space: nowrap;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.wb-choiceLabel:has(.wb-choiceDescription) .wb-choiceLabelText {
|
|
106
|
+
overflow: visible;
|
|
107
|
+
white-space: normal;
|
|
108
|
+
overflow-wrap: anywhere;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.wb-choiceDescription {
|
|
112
|
+
font-size: var(--dsw-font-xxs-12-font-size);
|
|
113
|
+
line-height: var(--wb-line-18);
|
|
114
|
+
color: var(--dsw-alias-label-tertiary);
|
|
115
|
+
overflow-wrap: anywhere;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.wb-choiceLoading {
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: var(--wb-len-6);
|
|
122
|
+
min-height: var(--wb-len-28);
|
|
123
|
+
padding: var(--wb-len-4) var(--wb-len-8);
|
|
124
|
+
font-size: var(--dsw-font-xs-13-font-size);
|
|
125
|
+
line-height: var(--wb-line-20);
|
|
126
|
+
color: var(--dsw-alias-label-secondary);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.wb-choiceLoadingText {
|
|
90
130
|
min-width: 0;
|
|
91
131
|
overflow: hidden;
|
|
92
132
|
text-overflow: ellipsis;
|
|
93
133
|
white-space: nowrap;
|
|
94
134
|
}
|
|
95
135
|
|
|
136
|
+
.wb-choiceEmpty {
|
|
137
|
+
display: flex;
|
|
138
|
+
align-items: center;
|
|
139
|
+
min-height: var(--wb-len-28);
|
|
140
|
+
padding: var(--wb-len-4) var(--wb-len-8);
|
|
141
|
+
font-size: var(--dsw-font-xs-13-font-size);
|
|
142
|
+
line-height: var(--wb-line-20);
|
|
143
|
+
color: var(--dsw-alias-label-tertiary);
|
|
144
|
+
}
|
|
145
|
+
|
|
96
146
|
.wb-radio {
|
|
97
147
|
appearance: none;
|
|
98
148
|
-webkit-appearance: none;
|
|
@@ -195,6 +195,94 @@ describe('ChoiceGroup:单选照旧,多选是新加的那条路', () => {
|
|
|
195
195
|
expect(inputs.every((one) => one.props['disabled'] === true)).toBe(true);
|
|
196
196
|
});
|
|
197
197
|
|
|
198
|
+
it('★ loading:不画选项,画一行 Spinner + loadingText', () => {
|
|
199
|
+
const element = ChoiceGroup({
|
|
200
|
+
label: '环境',
|
|
201
|
+
name: 'env',
|
|
202
|
+
value: '',
|
|
203
|
+
options: OPTIONS,
|
|
204
|
+
loading: true,
|
|
205
|
+
loadingText: '正在读环境…',
|
|
206
|
+
onChange: () => {},
|
|
207
|
+
});
|
|
208
|
+
const tree = treeOf(element);
|
|
209
|
+
const loading = tree.find((one) => one.props['className'] === 'wb-choiceLoading');
|
|
210
|
+
|
|
211
|
+
expect(inputsOf(element)).toHaveLength(0);
|
|
212
|
+
expect(tree.some((one) => one.props['className'] === 'wb-choiceOption')).toBe(false);
|
|
213
|
+
expect(
|
|
214
|
+
treeOf(loading?.props['children']).some(
|
|
215
|
+
(one) => one.props['className'] === 'wb-spinner',
|
|
216
|
+
),
|
|
217
|
+
).toBe(true);
|
|
218
|
+
expect(
|
|
219
|
+
treeOf(loading?.props['children']).some(
|
|
220
|
+
(one) => one.props['children'] === '正在读环境…',
|
|
221
|
+
),
|
|
222
|
+
).toBe(true);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('★ 没得选且不 loading:画 emptyText 那句,不画选项', () => {
|
|
226
|
+
const element = ChoiceGroup({
|
|
227
|
+
label: '环境',
|
|
228
|
+
name: 'env',
|
|
229
|
+
value: '',
|
|
230
|
+
options: [],
|
|
231
|
+
emptyText: '这个工作区还没绑定环境',
|
|
232
|
+
onChange: () => {},
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
expect(inputsOf(element)).toHaveLength(0);
|
|
236
|
+
expect(
|
|
237
|
+
treeOf(element).find((one) => one.props['className'] === 'wb-choiceEmpty')
|
|
238
|
+
?.props['children'],
|
|
239
|
+
).toBe('这个工作区还没绑定环境');
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it('★ variant 落在菜单上:ghost 写 data-variant=ghost,默认是 boxed', () => {
|
|
243
|
+
const menuOf = (variant?: 'boxed' | 'ghost') =>
|
|
244
|
+
treeOf(
|
|
245
|
+
ChoiceGroup({
|
|
246
|
+
label: '环境',
|
|
247
|
+
name: 'env',
|
|
248
|
+
value: 'tencent-test',
|
|
249
|
+
options: OPTIONS,
|
|
250
|
+
...(variant === undefined ? {} : { variant }),
|
|
251
|
+
onChange: () => {},
|
|
252
|
+
}),
|
|
253
|
+
).find((one) => one.props['className'] === 'wb-choiceMenu');
|
|
254
|
+
|
|
255
|
+
expect(menuOf('ghost')?.props['data-variant']).toBe('ghost');
|
|
256
|
+
expect(menuOf(undefined)?.props['data-variant']).toBe('boxed');
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('★ description 画在 label 下面第二行', () => {
|
|
260
|
+
const element = ChoiceGroup({
|
|
261
|
+
label: '环境',
|
|
262
|
+
name: 'env',
|
|
263
|
+
value: 'tencent-test',
|
|
264
|
+
options: [
|
|
265
|
+
{ value: 'tencent-test', label: '腾讯云 · 测试', description: '走的是测试账号' },
|
|
266
|
+
{ value: 'tencent-prod', label: '腾讯云 · 生产' },
|
|
267
|
+
],
|
|
268
|
+
onChange: () => {},
|
|
269
|
+
});
|
|
270
|
+
const labels = treeOf(element).filter(
|
|
271
|
+
(one) => one.props['className'] === 'wb-choiceLabel',
|
|
272
|
+
);
|
|
273
|
+
const descriptions = treeOf(element).filter(
|
|
274
|
+
(one) => one.props['className'] === 'wb-choiceDescription',
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
expect(descriptions).toHaveLength(1);
|
|
278
|
+
expect(descriptions[0]?.props['children']).toBe('走的是测试账号');
|
|
279
|
+
expect(
|
|
280
|
+
treeOf(labels[0]?.props['children']).some(
|
|
281
|
+
(one) => one.props['className'] === 'wb-choiceDescription',
|
|
282
|
+
),
|
|
283
|
+
).toBe(true);
|
|
284
|
+
});
|
|
285
|
+
|
|
198
286
|
it('Fragment 还是 React 自己的(别把 key 语义换掉)', () => {
|
|
199
287
|
expect(Fragment).toBeDefined();
|
|
200
288
|
});
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { ReactNode } from '../lib/react.js';
|
|
2
2
|
import { Fragment, h } from '../lib/react.js';
|
|
3
3
|
import { IconCheckOutlineRegular } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
|
+
import { Spinner } from './Spinner.js';
|
|
4
5
|
import './ChoiceGroup.css';
|
|
5
6
|
|
|
6
7
|
export interface ChoiceGroupOption {
|
|
7
8
|
readonly value: string;
|
|
8
9
|
readonly label: ReactNode;
|
|
10
|
+
readonly description?: ReactNode | undefined;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
interface ChoiceGroupCommon {
|
|
@@ -13,6 +15,10 @@ interface ChoiceGroupCommon {
|
|
|
13
15
|
readonly name: string;
|
|
14
16
|
readonly options: readonly ChoiceGroupOption[];
|
|
15
17
|
readonly disabled?: boolean | undefined;
|
|
18
|
+
readonly variant?: 'boxed' | 'ghost' | undefined;
|
|
19
|
+
readonly loading?: boolean | undefined;
|
|
20
|
+
readonly loadingText?: ReactNode | undefined;
|
|
21
|
+
readonly emptyText?: ReactNode | undefined;
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
export interface ChoiceGroupSingleProps extends ChoiceGroupCommon {
|
|
@@ -40,42 +46,66 @@ function ChoiceMenu(input: {
|
|
|
40
46
|
readonly options: readonly ChoiceGroupOption[];
|
|
41
47
|
readonly disabled: boolean;
|
|
42
48
|
readonly multi: boolean;
|
|
49
|
+
readonly variant: 'boxed' | 'ghost';
|
|
50
|
+
readonly loading: boolean;
|
|
51
|
+
readonly loadingText: ReactNode | undefined;
|
|
52
|
+
readonly emptyText: ReactNode | undefined;
|
|
43
53
|
readonly rowOf: (value: string) => ChoiceRowState;
|
|
44
54
|
}) {
|
|
55
|
+
const body = input.loading ? (
|
|
56
|
+
<span className="wb-choiceLoading" role="status">
|
|
57
|
+
<Spinner size={14} />
|
|
58
|
+
<span className="wb-choiceLoadingText">{input.loadingText ?? '…'}</span>
|
|
59
|
+
</span>
|
|
60
|
+
) : input.options.length === 0 ? (
|
|
61
|
+
input.emptyText === undefined ? null : (
|
|
62
|
+
<span className="wb-choiceEmpty">{input.emptyText}</span>
|
|
63
|
+
)
|
|
64
|
+
) : (
|
|
65
|
+
input.options.map((option) => {
|
|
66
|
+
const row = input.rowOf(option.value);
|
|
67
|
+
return (
|
|
68
|
+
<Fragment key={option.value}>
|
|
69
|
+
<label
|
|
70
|
+
className={`wb-choiceOption${row.checked ? ' wb-choiceOptionOn' : ''}`}
|
|
71
|
+
>
|
|
72
|
+
<input
|
|
73
|
+
className={input.multi ? 'wb-checkbox' : 'wb-radio'}
|
|
74
|
+
type={input.multi ? 'checkbox' : 'radio'}
|
|
75
|
+
name={input.name}
|
|
76
|
+
checked={row.checked}
|
|
77
|
+
disabled={input.disabled}
|
|
78
|
+
onChange={row.onSelect}
|
|
79
|
+
/>
|
|
80
|
+
{input.multi ? (
|
|
81
|
+
<span
|
|
82
|
+
className="wb-checkboxBox"
|
|
83
|
+
aria-hidden="true"
|
|
84
|
+
>
|
|
85
|
+
{row.checked ? <IconCheckOutlineRegular size={12} /> : null}
|
|
86
|
+
</span>
|
|
87
|
+
) : null}
|
|
88
|
+
<span className="wb-choiceLabel">
|
|
89
|
+
<span className="wb-choiceLabelText">{option.label}</span>
|
|
90
|
+
{option.description === undefined ? null : (
|
|
91
|
+
<span className="wb-choiceDescription">{option.description}</span>
|
|
92
|
+
)}
|
|
93
|
+
</span>
|
|
94
|
+
</label>
|
|
95
|
+
</Fragment>
|
|
96
|
+
);
|
|
97
|
+
})
|
|
98
|
+
);
|
|
99
|
+
|
|
45
100
|
return (
|
|
46
101
|
<div
|
|
47
102
|
className="wb-choiceMenu"
|
|
103
|
+
data-variant={input.variant}
|
|
48
104
|
role={input.multi ? 'group' : 'radiogroup'}
|
|
49
105
|
aria-label={input.label}
|
|
106
|
+
aria-busy={input.loading ? true : undefined}
|
|
50
107
|
>
|
|
51
|
-
{
|
|
52
|
-
const row = input.rowOf(option.value);
|
|
53
|
-
return (
|
|
54
|
-
<Fragment key={option.value}>
|
|
55
|
-
<label
|
|
56
|
-
className={`wb-choiceOption${row.checked ? ' wb-choiceOptionOn' : ''}`}
|
|
57
|
-
>
|
|
58
|
-
<input
|
|
59
|
-
className={input.multi ? 'wb-checkbox' : 'wb-radio'}
|
|
60
|
-
type={input.multi ? 'checkbox' : 'radio'}
|
|
61
|
-
name={input.name}
|
|
62
|
-
checked={row.checked}
|
|
63
|
-
disabled={input.disabled}
|
|
64
|
-
onChange={row.onSelect}
|
|
65
|
-
/>
|
|
66
|
-
{input.multi ? (
|
|
67
|
-
<span
|
|
68
|
-
className="wb-checkboxBox"
|
|
69
|
-
aria-hidden="true"
|
|
70
|
-
>
|
|
71
|
-
{row.checked ? <IconCheckOutlineRegular size={12} /> : null}
|
|
72
|
-
</span>
|
|
73
|
-
) : null}
|
|
74
|
-
<span className="wb-choiceLabel">{option.label}</span>
|
|
75
|
-
</label>
|
|
76
|
-
</Fragment>
|
|
77
|
-
);
|
|
78
|
-
})}
|
|
108
|
+
{body}
|
|
79
109
|
</div>
|
|
80
110
|
);
|
|
81
111
|
}
|
|
@@ -86,6 +116,10 @@ export function ChoiceGroup(props: ChoiceGroupProps) {
|
|
|
86
116
|
name: props.name,
|
|
87
117
|
options: props.options,
|
|
88
118
|
disabled: props.disabled === true,
|
|
119
|
+
variant: props.variant ?? 'boxed',
|
|
120
|
+
loading: props.loading === true,
|
|
121
|
+
loadingText: props.loadingText,
|
|
122
|
+
emptyText: props.emptyText,
|
|
89
123
|
};
|
|
90
124
|
|
|
91
125
|
if (props.multi === true) {
|
|
@@ -98,6 +132,10 @@ export function ChoiceGroup(props: ChoiceGroupProps) {
|
|
|
98
132
|
options={common.options}
|
|
99
133
|
disabled={common.disabled}
|
|
100
134
|
multi={true}
|
|
135
|
+
variant={common.variant}
|
|
136
|
+
loading={common.loading}
|
|
137
|
+
loadingText={common.loadingText}
|
|
138
|
+
emptyText={common.emptyText}
|
|
101
139
|
rowOf={(value) => ({
|
|
102
140
|
checked: values.includes(value),
|
|
103
141
|
onSelect: () => {
|
|
@@ -121,6 +159,10 @@ export function ChoiceGroup(props: ChoiceGroupProps) {
|
|
|
121
159
|
options={common.options}
|
|
122
160
|
disabled={common.disabled}
|
|
123
161
|
multi={false}
|
|
162
|
+
variant={common.variant}
|
|
163
|
+
loading={common.loading}
|
|
164
|
+
loadingText={common.loadingText}
|
|
165
|
+
emptyText={common.emptyText}
|
|
124
166
|
rowOf={(option) => ({
|
|
125
167
|
checked: option === value,
|
|
126
168
|
onSelect: () => {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.wb-formActions {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-wrap: wrap;
|
|
4
|
+
align-items: center;
|
|
5
|
+
justify-content: flex-end;
|
|
6
|
+
gap: var(--wb-len-8);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.wb-formActionDanger {
|
|
10
|
+
color: var(--dsw-alias-state-error-primary);
|
|
11
|
+
border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary) 30%, transparent);
|
|
12
|
+
--dsw-alias-interactive-bg-hover: color-mix(in srgb, var(--dsw-alias-state-error-primary) 8%, transparent);
|
|
13
|
+
}
|