waybetter 0.1.1 → 0.7.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 +139 -6
- package/bin/waybetter.mjs +43 -0
- package/build/runtime.mjs +105 -0
- package/cli/buildenv.mjs +130 -0
- package/cli/dev.mjs +97 -0
- package/cli/i18n.mjs +382 -0
- package/cli/manifests.mjs +383 -0
- package/cli/release.mjs +437 -0
- package/cli/releasecheck.mjs +15 -0
- package/cli/remote.mjs +260 -0
- package/cli/store.mjs +378 -0
- package/cli/strings.mjs +123 -0
- package/dist/runtime/column.d.ts +93 -0
- package/dist/runtime/column.js +451 -0
- package/dist/runtime/column.js.map +1 -0
- package/dist/runtime/commandReport.d.ts +19 -0
- package/dist/runtime/commandReport.js +47 -0
- package/dist/runtime/commandReport.js.map +1 -0
- package/dist/runtime/commands.d.ts +72 -0
- package/dist/runtime/commands.js +214 -0
- package/dist/runtime/commands.js.map +1 -0
- package/dist/runtime/devErrors.d.ts +16 -0
- package/dist/runtime/devErrors.js +30 -0
- package/dist/runtime/devErrors.js.map +1 -0
- package/dist/runtime/domHub.d.ts +21 -0
- package/dist/runtime/domHub.js +139 -4
- package/dist/runtime/domHub.js.map +1 -1
- package/dist/runtime/featureModules.d.ts +157 -0
- package/dist/runtime/featureModules.js +484 -0
- package/dist/runtime/featureModules.js.map +1 -0
- package/dist/runtime/featureTable.d.ts +144 -0
- package/dist/runtime/featureTable.js +223 -0
- package/dist/runtime/featureTable.js.map +1 -0
- package/dist/runtime/fonts.d.ts +22 -0
- package/dist/runtime/fonts.js +72 -0
- package/dist/runtime/fonts.js.map +1 -0
- package/dist/runtime/i18n.d.ts +138 -0
- package/dist/runtime/i18n.js +614 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/i18nCheck.d.ts +30 -0
- package/dist/runtime/i18nCheck.js +224 -0
- package/dist/runtime/i18nCheck.js.map +1 -0
- package/dist/runtime/pageLang.d.ts +8 -0
- package/dist/runtime/pageLang.js +64 -0
- package/dist/runtime/pageLang.js.map +1 -0
- package/dist/runtime/pageStrings.d.ts +35 -0
- package/dist/runtime/pageStrings.js +76 -0
- package/dist/runtime/pageStrings.js.map +1 -0
- package/dist/runtime/panelButton.d.ts +33 -0
- package/dist/runtime/panelButton.js +83 -0
- package/dist/runtime/panelButton.js.map +1 -0
- package/dist/runtime/permissions.d.ts +47 -0
- package/dist/runtime/permissions.js +141 -0
- package/dist/runtime/permissions.js.map +1 -0
- package/dist/runtime/pluginApi.d.ts +51 -2
- package/dist/runtime/pluginApi.js +137 -22
- package/dist/runtime/pluginApi.js.map +1 -1
- package/dist/runtime/pluginI18n.d.ts +29 -0
- package/dist/runtime/pluginI18n.js +119 -0
- package/dist/runtime/pluginI18n.js.map +1 -0
- package/dist/runtime/settingsForm.d.ts +66 -0
- package/dist/runtime/settingsForm.js +114 -0
- package/dist/runtime/settingsForm.js.map +1 -0
- package/dist/runtime/site.d.ts +5 -0
- package/dist/runtime/site.js +1 -1
- package/dist/runtime/site.js.map +1 -1
- package/dist/runtime/siteRuntime.d.ts +144 -0
- package/dist/runtime/siteRuntime.js +175 -0
- package/dist/runtime/siteRuntime.js.map +1 -0
- package/dist/runtime/stringPackHook.d.ts +84 -0
- package/dist/runtime/stringPackHook.js +220 -0
- package/dist/runtime/stringPackHook.js.map +1 -0
- package/dist/runtime/stringPackTranslate.d.ts +61 -0
- package/dist/runtime/stringPackTranslate.js +267 -0
- package/dist/runtime/stringPackTranslate.js.map +1 -0
- package/dist/runtime/stringPacks.d.ts +248 -0
- package/dist/runtime/stringPacks.js +610 -0
- package/dist/runtime/stringPacks.js.map +1 -0
- package/dist/runtime/styles.d.ts +15 -0
- package/dist/runtime/styles.js +81 -0
- package/dist/runtime/styles.js.map +1 -0
- package/dist/runtime/textNet.d.ts +15 -0
- package/dist/runtime/textNet.js +131 -0
- package/dist/runtime/textNet.js.map +1 -0
- package/dist/runtime/themeApi.d.ts +121 -0
- package/dist/runtime/themeApi.js +220 -0
- package/dist/runtime/themeApi.js.map +1 -0
- package/dist/runtime/themeBar.d.ts +28 -0
- package/dist/runtime/themeBar.js +82 -0
- package/dist/runtime/themeBar.js.map +1 -0
- package/dist/runtime/themeChoice.d.ts +52 -0
- package/dist/runtime/themeChoice.js +69 -0
- package/dist/runtime/themeChoice.js.map +1 -0
- package/dist/runtime/themeComponents.d.ts +435 -0
- package/dist/runtime/themeComponents.js +476 -0
- package/dist/runtime/themeComponents.js.map +1 -0
- package/dist/runtime/themeDecor.d.ts +73 -0
- package/dist/runtime/themeDecor.js +133 -0
- package/dist/runtime/themeDecor.js.map +1 -0
- package/dist/runtime/themeDerive.d.ts +69 -0
- package/dist/runtime/themeDerive.js +117 -0
- package/dist/runtime/themeDerive.js.map +1 -0
- package/dist/runtime/themeDoctor.d.ts +52 -0
- package/dist/runtime/themeDoctor.js +112 -0
- package/dist/runtime/themeDoctor.js.map +1 -0
- package/dist/runtime/themeGuards.d.ts +60 -0
- package/dist/runtime/themeGuards.js +235 -0
- package/dist/runtime/themeGuards.js.map +1 -0
- package/dist/runtime/themeIcons.d.ts +130 -0
- package/dist/runtime/themeIcons.js +271 -0
- package/dist/runtime/themeIcons.js.map +1 -0
- package/dist/runtime/themeInk.d.ts +37 -0
- package/dist/runtime/themeInk.js +111 -0
- package/dist/runtime/themeInk.js.map +1 -0
- package/dist/runtime/themeInvariants.d.ts +39 -0
- package/dist/runtime/themeInvariants.js +273 -0
- package/dist/runtime/themeInvariants.js.map +1 -0
- package/dist/runtime/themeRuntime.d.ts +114 -0
- package/dist/runtime/themeRuntime.js +570 -0
- package/dist/runtime/themeRuntime.js.map +1 -0
- package/dist/runtime/themeSchema.d.ts +10 -0
- package/dist/runtime/themeSchema.js +150 -0
- package/dist/runtime/themeSchema.js.map +1 -0
- package/dist/runtime/themeSpec.d.ts +263 -0
- package/dist/runtime/themeSpec.js +435 -0
- package/dist/runtime/themeSpec.js.map +1 -0
- package/dist/runtime/themeTokens.d.ts +12 -0
- package/dist/runtime/themeTokens.js +14 -6
- package/dist/runtime/themeTokens.js.map +1 -1
- package/dist/runtime/themeVariants.d.ts +30 -0
- package/dist/runtime/themeVariants.js +53 -0
- package/dist/runtime/themeVariants.js.map +1 -0
- package/dist/runtime/ui.d.ts +192 -0
- package/dist/runtime/ui.js +926 -0
- package/dist/runtime/ui.js.map +1 -0
- package/dist/shell/InstallDialog.d.ts +40 -0
- package/dist/shell/InstallDialog.js +176 -0
- package/dist/shell/InstallDialog.js.map +1 -0
- package/dist/shell/StoreView.d.ts +78 -0
- package/dist/shell/StoreView.js +108 -0
- package/dist/shell/StoreView.js.map +1 -0
- package/dist/shell/addressModel.js.map +1 -1
- package/dist/shell/chrome.js.map +1 -1
- package/dist/shell/deckModel.d.ts +117 -0
- package/dist/shell/deckModel.js +267 -0
- package/dist/shell/deckModel.js.map +1 -0
- package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
- package/dist/shell/frame/AccountSwitcher.js +243 -0
- package/dist/shell/frame/AccountSwitcher.js.map +1 -0
- package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
- package/dist/shell/frame/AddColumnDialog.js +81 -0
- package/dist/shell/frame/AddColumnDialog.js.map +1 -0
- package/dist/shell/frame/AppMenu.d.ts +44 -0
- package/dist/shell/frame/AppMenu.js +721 -0
- package/dist/shell/frame/AppMenu.js.map +1 -0
- package/dist/shell/frame/CommandPalette.d.ts +7 -0
- package/dist/shell/frame/CommandPalette.js +118 -0
- package/dist/shell/frame/CommandPalette.js.map +1 -0
- package/dist/shell/frame/DeckView.d.ts +13 -0
- package/dist/shell/frame/DeckView.js +287 -0
- package/dist/shell/frame/DeckView.js.map +1 -0
- package/dist/shell/frame/FindBar.d.ts +10 -0
- package/dist/shell/frame/FindBar.js +108 -0
- package/dist/shell/frame/FindBar.js.map +1 -0
- package/dist/shell/frame/MediaPanel.d.ts +8 -0
- package/dist/shell/frame/MediaPanel.js +76 -0
- package/dist/shell/frame/MediaPanel.js.map +1 -0
- package/dist/shell/frame/NewTabPage.d.ts +9 -0
- package/dist/shell/frame/NewTabPage.js +71 -0
- package/dist/shell/frame/NewTabPage.js.map +1 -0
- package/dist/shell/frame/PaneTheme.d.ts +16 -0
- package/dist/shell/frame/PaneTheme.js +67 -0
- package/dist/shell/frame/PaneTheme.js.map +1 -0
- package/dist/shell/frame/ReportDialog.d.ts +3 -0
- package/dist/shell/frame/ReportDialog.js +95 -0
- package/dist/shell/frame/ReportDialog.js.map +1 -0
- package/dist/shell/frame/Shell.d.ts +9 -0
- package/dist/shell/frame/Shell.js +1139 -0
- package/dist/shell/frame/Shell.js.map +1 -0
- package/dist/shell/frame/Titlebar.d.ts +17 -0
- package/dist/shell/frame/Titlebar.js +79 -0
- package/dist/shell/frame/Titlebar.js.map +1 -0
- package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
- package/dist/shell/frame/TitlebarExtras.js +202 -0
- package/dist/shell/frame/TitlebarExtras.js.map +1 -0
- package/dist/shell/frame/WebPanel.d.ts +4 -0
- package/dist/shell/frame/WebPanel.js +185 -0
- package/dist/shell/frame/WebPanel.js.map +1 -0
- package/dist/shell/frame/accountModel.d.ts +49 -0
- package/dist/shell/frame/accountModel.js +67 -0
- package/dist/shell/frame/accountModel.js.map +1 -0
- package/dist/shell/frame/accountSwitcher.css +91 -0
- package/dist/shell/frame/appI18n.d.ts +44 -0
- package/dist/shell/frame/appI18n.js +64 -0
- package/dist/shell/frame/appI18n.js.map +1 -0
- package/dist/shell/frame/appMenu.css +127 -0
- package/dist/shell/frame/backupModel.d.ts +38 -0
- package/dist/shell/frame/backupModel.js +192 -0
- package/dist/shell/frame/backupModel.js.map +1 -0
- package/dist/shell/frame/boot.d.ts +8 -0
- package/dist/shell/frame/boot.js +37 -0
- package/dist/shell/frame/boot.js.map +1 -0
- package/dist/shell/frame/brand.d.ts +1 -0
- package/dist/shell/frame/brand.js +4 -0
- package/dist/shell/frame/brand.js.map +1 -0
- package/dist/shell/frame/bridge.d.ts +35 -0
- package/dist/shell/frame/bridge.js +70 -0
- package/dist/shell/frame/bridge.js.map +1 -0
- package/dist/shell/frame/chromeTheme.d.ts +47 -0
- package/dist/shell/frame/chromeTheme.js +118 -0
- package/dist/shell/frame/chromeTheme.js.map +1 -0
- package/dist/shell/frame/deck.css +209 -0
- package/dist/shell/frame/deckStore.d.ts +89 -0
- package/dist/shell/frame/deckStore.js +239 -0
- package/dist/shell/frame/deckStore.js.map +1 -0
- package/dist/shell/frame/devHost.d.ts +35 -0
- package/dist/shell/frame/devHost.js +80 -0
- package/dist/shell/frame/devHost.js.map +1 -0
- package/dist/shell/frame/devModel.d.ts +7 -0
- package/dist/shell/frame/devModel.js +17 -0
- package/dist/shell/frame/devModel.js.map +1 -0
- package/dist/shell/frame/diag.d.ts +7 -0
- package/dist/shell/frame/diag.js +39 -0
- package/dist/shell/frame/diag.js.map +1 -0
- package/dist/shell/frame/edges.css +159 -0
- package/dist/shell/frame/findBar.css +14 -0
- package/dist/shell/frame/frameMessages.d.ts +248 -0
- package/dist/shell/frame/frameMessages.js +252 -0
- package/dist/shell/frame/frameMessages.js.map +1 -0
- package/dist/shell/frame/hooks.d.ts +39 -0
- package/dist/shell/frame/hooks.js +97 -0
- package/dist/shell/frame/hooks.js.map +1 -0
- package/dist/shell/frame/i18n.d.ts +27 -0
- package/dist/shell/frame/i18n.js +66 -0
- package/dist/shell/frame/i18n.js.map +1 -0
- package/dist/shell/frame/iconPack.d.ts +11 -0
- package/dist/shell/frame/iconPack.js +45 -0
- package/dist/shell/frame/iconPack.js.map +1 -0
- package/dist/shell/frame/icons.d.ts +71 -0
- package/dist/shell/frame/icons.js +75 -0
- package/dist/shell/frame/icons.js.map +1 -0
- package/dist/shell/frame/index.d.ts +34 -0
- package/dist/shell/frame/index.js +43 -0
- package/dist/shell/frame/index.js.map +1 -0
- package/dist/shell/frame/language.d.ts +58 -0
- package/dist/shell/frame/language.js +165 -0
- package/dist/shell/frame/language.js.map +1 -0
- package/dist/shell/frame/mediaModel.d.ts +47 -0
- package/dist/shell/frame/mediaModel.js +67 -0
- package/dist/shell/frame/mediaModel.js.map +1 -0
- package/dist/shell/frame/menuMessages.en.json +96 -0
- package/dist/shell/frame/menuModel.d.ts +319 -0
- package/dist/shell/frame/menuModel.js +301 -0
- package/dist/shell/frame/menuModel.js.map +1 -0
- package/dist/shell/frame/nativeMenu.d.ts +5 -0
- package/dist/shell/frame/nativeMenu.js +178 -0
- package/dist/shell/frame/nativeMenu.js.map +1 -0
- package/dist/shell/frame/nativeMenuModel.d.ts +102 -0
- package/dist/shell/frame/nativeMenuModel.js +186 -0
- package/dist/shell/frame/nativeMenuModel.js.map +1 -0
- package/dist/shell/frame/paletteModel.d.ts +139 -0
- package/dist/shell/frame/paletteModel.js +114 -0
- package/dist/shell/frame/paletteModel.js.map +1 -0
- package/dist/shell/frame/paneTheme.css +9 -0
- package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
- package/dist/shell/frame/pluginCommandStore.js +70 -0
- package/dist/shell/frame/pluginCommandStore.js.map +1 -0
- package/dist/shell/frame/reportModel.d.ts +52 -0
- package/dist/shell/frame/reportModel.js +105 -0
- package/dist/shell/frame/reportModel.js.map +1 -0
- package/dist/shell/frame/safeStore.d.ts +7 -0
- package/dist/shell/frame/safeStore.js +40 -0
- package/dist/shell/frame/safeStore.js.map +1 -0
- package/dist/shell/frame/searchInput.d.ts +2 -0
- package/dist/shell/frame/searchInput.js +11 -0
- package/dist/shell/frame/searchInput.js.map +1 -0
- package/dist/shell/frame/shell.css +634 -0
- package/dist/shell/frame/site.d.ts +206 -0
- package/dist/shell/frame/site.js +22 -0
- package/dist/shell/frame/site.js.map +1 -0
- package/dist/shell/frame/state.d.ts +101 -0
- package/dist/shell/frame/state.js +286 -0
- package/dist/shell/frame/state.js.map +1 -0
- package/dist/shell/frame/syncGate.d.ts +10 -0
- package/dist/shell/frame/syncGate.js +36 -0
- package/dist/shell/frame/syncGate.js.map +1 -0
- package/dist/shell/frame/syncHost.d.ts +35 -0
- package/dist/shell/frame/syncHost.js +85 -0
- package/dist/shell/frame/syncHost.js.map +1 -0
- package/dist/shell/frame/tabStill.d.ts +2 -0
- package/dist/shell/frame/tabStill.js +62 -0
- package/dist/shell/frame/tabStill.js.map +1 -0
- package/dist/shell/frame/themeScopes.d.ts +29 -0
- package/dist/shell/frame/themeScopes.js +61 -0
- package/dist/shell/frame/themeScopes.js.map +1 -0
- package/dist/shell/frame/themeStore.d.ts +99 -0
- package/dist/shell/frame/themeStore.js +267 -0
- package/dist/shell/frame/themeStore.js.map +1 -0
- package/dist/shell/frame/windowBinding.d.ts +2 -0
- package/dist/shell/frame/windowBinding.js +7 -0
- package/dist/shell/frame/windowBinding.js.map +1 -0
- package/dist/shell/frame/workspaceModel.d.ts +82 -0
- package/dist/shell/frame/workspaceModel.js +250 -0
- package/dist/shell/frame/workspaceModel.js.map +1 -0
- package/dist/shell/frame/workspaces.css +84 -0
- package/dist/shell/frame/workspaces.d.ts +22 -0
- package/dist/shell/frame/workspaces.js +125 -0
- package/dist/shell/frame/workspaces.js.map +1 -0
- package/dist/shell/frame/zoomStore.d.ts +10 -0
- package/dist/shell/frame/zoomStore.js +65 -0
- package/dist/shell/frame/zoomStore.js.map +1 -0
- package/dist/shell/installController.d.ts +137 -0
- package/dist/shell/installController.js +172 -0
- package/dist/shell/installController.js.map +1 -0
- package/dist/shell/installerMessages.d.ts +30 -0
- package/dist/shell/installerMessages.js +36 -0
- package/dist/shell/installerMessages.js.map +1 -0
- package/dist/shell/linkDrop.js.map +1 -1
- package/dist/shell/messages.d.ts +16 -0
- package/dist/shell/messages.js +27 -0
- package/dist/shell/messages.js.map +1 -0
- package/dist/shell/palette.js.map +1 -1
- package/dist/shell/paneModel.d.ts +22 -0
- package/dist/shell/paneModel.js +24 -1
- package/dist/shell/paneModel.js.map +1 -1
- package/dist/shell/panel/Appearance.d.ts +8 -0
- package/dist/shell/panel/Appearance.js +265 -0
- package/dist/shell/panel/Appearance.js.map +1 -0
- package/dist/shell/panel/BackupPanel.d.ts +5 -0
- package/dist/shell/panel/BackupPanel.js +198 -0
- package/dist/shell/panel/BackupPanel.js.map +1 -0
- package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
- package/dist/shell/panel/DeveloperPanel.js +51 -0
- package/dist/shell/panel/DeveloperPanel.js.map +1 -0
- package/dist/shell/panel/FeatureToggles.d.ts +13 -0
- package/dist/shell/panel/FeatureToggles.js +42 -0
- package/dist/shell/panel/FeatureToggles.js.map +1 -0
- package/dist/shell/panel/Home.d.ts +3 -0
- package/dist/shell/panel/Home.js +23 -0
- package/dist/shell/panel/Home.js.map +1 -0
- package/dist/shell/panel/IconPackInstall.d.ts +15 -0
- package/dist/shell/panel/IconPackInstall.js +41 -0
- package/dist/shell/panel/IconPackInstall.js.map +1 -0
- package/dist/shell/panel/LanguageSettings.d.ts +1 -0
- package/dist/shell/panel/LanguageSettings.js +54 -0
- package/dist/shell/panel/LanguageSettings.js.map +1 -0
- package/dist/shell/panel/MakePanel.d.ts +3 -0
- package/dist/shell/panel/MakePanel.js +237 -0
- package/dist/shell/panel/MakePanel.js.map +1 -0
- package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
- package/dist/shell/panel/MarkdownDoc.js +35 -0
- package/dist/shell/panel/MarkdownDoc.js.map +1 -0
- package/dist/shell/panel/Modes.d.ts +40 -0
- package/dist/shell/panel/Modes.js +270 -0
- package/dist/shell/panel/Modes.js.map +1 -0
- package/dist/shell/panel/NavIcon.d.ts +4 -0
- package/dist/shell/panel/NavIcon.js +6 -0
- package/dist/shell/panel/NavIcon.js.map +1 -0
- package/dist/shell/panel/Panel.d.ts +7 -0
- package/dist/shell/panel/Panel.js +139 -0
- package/dist/shell/panel/Panel.js.map +1 -0
- package/dist/shell/panel/PluginFeatures.d.ts +24 -0
- package/dist/shell/panel/PluginFeatures.js +165 -0
- package/dist/shell/panel/PluginFeatures.js.map +1 -0
- package/dist/shell/panel/Plugins.d.ts +33 -0
- package/dist/shell/panel/Plugins.js +112 -0
- package/dist/shell/panel/Plugins.js.map +1 -0
- package/dist/shell/panel/PowerSettings.d.ts +4 -0
- package/dist/shell/panel/PowerSettings.js +52 -0
- package/dist/shell/panel/PowerSettings.js.map +1 -0
- package/dist/shell/panel/Settings.d.ts +23 -0
- package/dist/shell/panel/Settings.js +117 -0
- package/dist/shell/panel/Settings.js.map +1 -0
- package/dist/shell/panel/ShareSetup.d.ts +8 -0
- package/dist/shell/panel/ShareSetup.js +130 -0
- package/dist/shell/panel/ShareSetup.js.map +1 -0
- package/dist/shell/panel/StoreSection.d.ts +7 -0
- package/dist/shell/panel/StoreSection.js +78 -0
- package/dist/shell/panel/StoreSection.js.map +1 -0
- package/dist/shell/panel/StringPacks.d.ts +20 -0
- package/dist/shell/panel/StringPacks.js +131 -0
- package/dist/shell/panel/StringPacks.js.map +1 -0
- package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
- package/dist/shell/panel/ThemeBuilder.js +205 -0
- package/dist/shell/panel/ThemeBuilder.js.map +1 -0
- package/dist/shell/panel/backup.css +34 -0
- package/dist/shell/panel/builder.css +240 -0
- package/dist/shell/panel/builderModel.d.ts +55 -0
- package/dist/shell/panel/builderModel.js +95 -0
- package/dist/shell/panel/builderModel.js.map +1 -0
- package/dist/shell/panel/compare.d.ts +10 -0
- package/dist/shell/panel/compare.js +51 -0
- package/dist/shell/panel/compare.js.map +1 -0
- package/dist/shell/panel/controls.d.ts +135 -0
- package/dist/shell/panel/controls.js +213 -0
- package/dist/shell/panel/controls.js.map +1 -0
- package/dist/shell/panel/featureModel.d.ts +69 -0
- package/dist/shell/panel/featureModel.js +79 -0
- package/dist/shell/panel/featureModel.js.map +1 -0
- package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
- package/dist/shell/panel/fonts/FontBrowser.js +189 -0
- package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
- package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
- package/dist/shell/panel/fonts/FontRoles.js +77 -0
- package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
- package/dist/shell/panel/fonts/catalog.d.ts +37 -0
- package/dist/shell/panel/fonts/catalog.js +68 -0
- package/dist/shell/panel/fonts/catalog.js.map +1 -0
- package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
- package/dist/shell/panel/index.d.ts +20 -0
- package/dist/shell/panel/index.js +34 -0
- package/dist/shell/panel/index.js.map +1 -0
- package/dist/shell/panel/languageModel.d.ts +5 -0
- package/dist/shell/panel/languageModel.js +7 -0
- package/dist/shell/panel/languageModel.js.map +1 -0
- package/dist/shell/panel/make.css +73 -0
- package/dist/shell/panel/makeModel.d.ts +32 -0
- package/dist/shell/panel/makeModel.js +84 -0
- package/dist/shell/panel/makeModel.js.map +1 -0
- package/dist/shell/panel/markdown.d.ts +46 -0
- package/dist/shell/panel/markdown.js +100 -0
- package/dist/shell/panel/markdown.js.map +1 -0
- package/dist/shell/panel/nav.d.ts +12 -0
- package/dist/shell/panel/nav.js +50 -0
- package/dist/shell/panel/nav.js.map +1 -0
- package/dist/shell/panel/panel.css +401 -0
- package/dist/shell/panel/panelMessages.d.ts +803 -0
- package/dist/shell/panel/panelMessages.js +779 -0
- package/dist/shell/panel/panelMessages.js.map +1 -0
- package/dist/shell/panel/plugins.css +59 -0
- package/dist/shell/panel/setupModel.d.ts +87 -0
- package/dist/shell/panel/setupModel.js +152 -0
- package/dist/shell/panel/setupModel.js.map +1 -0
- package/dist/shell/panel/site.d.ts +259 -0
- package/dist/shell/panel/site.js +25 -0
- package/dist/shell/panel/site.js.map +1 -0
- package/dist/shell/panel/strings.css +7 -0
- package/dist/shell/panel/themes.d.ts +10 -0
- package/dist/shell/panel/themes.js +8 -0
- package/dist/shell/panel/themes.js.map +1 -0
- package/dist/shell/profileModel.d.ts +3 -2
- package/dist/shell/profileModel.js +7 -5
- package/dist/shell/profileModel.js.map +1 -1
- package/dist/shell/store.css +250 -0
- package/dist/shell/storeMessages.d.ts +193 -0
- package/dist/shell/storeMessages.js +196 -0
- package/dist/shell/storeMessages.js.map +1 -0
- package/dist/shell/storeModel.d.ts +205 -0
- package/dist/shell/storeModel.js +146 -0
- package/dist/shell/storeModel.js.map +1 -0
- package/dist/shell/stringPacksModel.d.ts +44 -0
- package/dist/shell/stringPacksModel.js +99 -0
- package/dist/shell/stringPacksModel.js.map +1 -0
- package/dist/shell/updateModel.d.ts +2 -1
- package/dist/shell/updateModel.js +5 -4
- package/dist/shell/updateModel.js.map +1 -1
- package/dist/shell/windowControls.d.ts +4 -0
- package/dist/shell/windowControls.js +5 -0
- package/dist/shell/windowControls.js.map +1 -1
- package/i18n-config.schema.json +29 -0
- package/i18n-meta.schema.json +26 -0
- package/i18n.schema.json +42 -0
- package/icons.schema.json +655 -0
- package/languages.schema.json +23 -0
- package/locales/ar-x-fm.json +11 -0
- package/locales/ar.json +1388 -0
- package/locales/bg.json +1387 -0
- package/locales/bn.json +1387 -0
- package/locales/ca.json +1387 -0
- package/locales/cs.json +1387 -0
- package/locales/da.json +1387 -0
- package/locales/de.json +1387 -0
- package/locales/el.json +1387 -0
- package/locales/en-GB.json +27 -0
- package/locales/en.json +1386 -0
- package/locales/en.meta.json +51 -0
- package/locales/es.json +1387 -0
- package/locales/eu.json +1387 -0
- package/locales/fa.json +1388 -0
- package/locales/fi.json +1387 -0
- package/locales/fil.json +1387 -0
- package/locales/fr.json +1387 -0
- package/locales/ga.json +1387 -0
- package/locales/gl.json +1387 -0
- package/locales/gu.json +1387 -0
- package/locales/ha.json +1387 -0
- package/locales/he.json +1388 -0
- package/locales/hi.json +1387 -0
- package/locales/hr.json +1387 -0
- package/locales/hu.json +1387 -0
- package/locales/id.json +1387 -0
- package/locales/ig.json +1387 -0
- package/locales/it.json +1387 -0
- package/locales/ja.json +1387 -0
- package/locales/kn.json +1387 -0
- package/locales/ko.json +1387 -0
- package/locales/mr.json +1387 -0
- package/locales/ms.json +1387 -0
- package/locales/nb.json +1387 -0
- package/locales/nl.json +1387 -0
- package/locales/pl.json +1387 -0
- package/locales/pt.json +1387 -0
- package/locales/ro.json +1387 -0
- package/locales/ru.json +1387 -0
- package/locales/sk.json +1387 -0
- package/locales/sr.json +1387 -0
- package/locales/sv.json +1387 -0
- package/locales/ta.json +1387 -0
- package/locales/th.json +1387 -0
- package/locales/tr.json +1387 -0
- package/locales/uk.json +1387 -0
- package/locales/ur.json +1388 -0
- package/locales/vi.json +1387 -0
- package/locales/yo.json +1387 -0
- package/locales/zh-Hans.json +1387 -0
- package/locales/zh-Hant.json +1387 -0
- package/package.json +138 -5
- package/store-catalog.schema.json +78 -0
- package/theme.schema.json +4668 -0
- package/windows/installer.nsi +946 -0
- package/windows/languages/Basque.nsh +28 -0
- package/windows/languages/Catalan.nsh +28 -0
- package/windows/languages/Croatian.nsh +28 -0
- package/windows/languages/Czech.nsh +28 -0
- package/windows/languages/Danish.nsh +28 -0
- package/windows/languages/Finnish.nsh +28 -0
- package/windows/languages/Galician.nsh +28 -0
- package/windows/languages/Greek.nsh +28 -0
- package/windows/languages/Hungarian.nsh +28 -0
- package/windows/languages/Indonesian.nsh +28 -0
- package/windows/languages/Irish.nsh +28 -0
- package/windows/languages/Malay.nsh +28 -0
- package/windows/languages/Polish.nsh +28 -0
- package/windows/languages/Romanian.nsh +28 -0
- package/windows/languages/Serbian.nsh +28 -0
- package/windows/languages/Slovak.nsh +28 -0
- package/windows/languages/Thai.nsh +28 -0
|
@@ -8,11 +8,7 @@
|
|
|
8
8
|
//
|
|
9
9
|
// Pure: runs in the page runtime, the settings previews and the tests. The site adapter supplies the
|
|
10
10
|
// source palettes (`SourceAxis`, one per site mode); e.g. X's Default/Dim/Lights out.
|
|
11
|
-
|
|
12
|
-
function hexToRgb(hex) {
|
|
13
|
-
const n = parseInt(hex.slice(1, 7), 16);
|
|
14
|
-
return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
|
|
15
|
-
}
|
|
11
|
+
import { hexToRgb } from "./themeApi.js";
|
|
16
12
|
const toLinear = (v) => { v /= 255; return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4; };
|
|
17
13
|
const toGamma = (v) => Math.round(255 * Math.min(1, Math.max(0, v <= 0.0031308 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055)));
|
|
18
14
|
export function rgbToOklab([r, g, b]) {
|
|
@@ -45,6 +41,8 @@ const NEUTRAL_CHROMA = 0.05;
|
|
|
45
41
|
/** How far past the site's own background/text a neutral may sit and still be on the axis (pure white
|
|
46
42
|
* text in Lights out is slightly past the site's 231,233,234; black in Default is far past and is a shadow). */
|
|
47
43
|
const AXIS_SLACK = 0.12;
|
|
44
|
+
/** How close to a surface or to the secondary text a foreground may sit and still count as that role's own shade. */
|
|
45
|
+
const DIM_SLACK = 0.01;
|
|
48
46
|
const PRIORITY = {
|
|
49
47
|
background: ['bg', 'surface', 'elevated', 'border', 'muted', 'text'],
|
|
50
48
|
border: ['bg', 'border', 'elevated', 'surface', 'muted', 'text'],
|
|
@@ -92,8 +90,16 @@ export function buildColorModel(source, target, usage = 'background') {
|
|
|
92
90
|
if (!exact.has(key))
|
|
93
91
|
exact.set(key, hexToRgb(target.accent));
|
|
94
92
|
anchors.sort((a, b) => a.t - b.t);
|
|
93
|
+
let dim = null;
|
|
94
|
+
if (usage === 'text' && target.muted && source.muted.length) {
|
|
95
|
+
const positions = (roles) => roles.flatMap(role => source[role].map(key => position(rgbToOklab(keyRgb(key)))));
|
|
96
|
+
const from = Math.max(0, ...positions(['bg', 'surface', 'elevated'])) + DIM_SLACK;
|
|
97
|
+
const to = Math.min(...positions(['muted'])) - DIM_SLACK;
|
|
98
|
+
if (to > from)
|
|
99
|
+
dim = { from, to, color: hexToRgb(target.muted) };
|
|
100
|
+
}
|
|
95
101
|
return {
|
|
96
|
-
sourceBg, sourceText, anchors, exact,
|
|
102
|
+
sourceBg, sourceText, anchors, exact, dim,
|
|
97
103
|
sourceAccent: rgbToOklab(keyRgb(source.accent[0])),
|
|
98
104
|
accent: target.accent ? rgbToOklab(hexToRgb(target.accent)) : null,
|
|
99
105
|
};
|
|
@@ -131,6 +137,8 @@ export function projectColor(model, rgb) {
|
|
|
131
137
|
return listed;
|
|
132
138
|
const c = rgbToOklab(rgb);
|
|
133
139
|
const t = axisPosition(model, rgb);
|
|
140
|
+
if (t !== null && model.dim && t > model.dim.from && t < model.dim.to)
|
|
141
|
+
return model.dim.color;
|
|
134
142
|
if (t !== null)
|
|
135
143
|
return oklabToRgb(onCurve(model, t));
|
|
136
144
|
if (model.accent && isAccentFamily(model, c)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"themeTokens.js","sourceRoot":"","sources":["../../../runtime/src/themeTokens.ts"],"names":[],"mappings":"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","sourcesContent":["// The color foundation every theme is built on. The site's own palette (one per site color mode) is\n// the reference coordinate system: every neutral the site paints sits somewhere on its axis from page\n// background to text, and a theme says where its own background, surfaces, border, secondary text and\n// text sit on that same axis. Any site neutral (listed or not, hover tints included) lands at the same\n// position on the theme's curve, interpolated in OKLab, so nothing keeps the site's gray and nothing\n// collapses onto the wrong role. The site's accent family follows the theme accent with the same\n// lightness offset. Colors that mean something (likes, errors, badges) are left alone.\n//\n// Pure: runs in the page runtime, the settings previews and the tests. The site adapter supplies the\n// source palettes (`SourceAxis`, one per site mode); e.g. X's Default/Dim/Lights out.\n\n/** `#rrggbb` → [r, g, b] (local, so themeSpec.ts can import this module without a cycle). */\nfunction hexToRgb(hex: string): Rgb {\n const n = parseInt(hex.slice(1, 7), 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\n\nexport type Oklab = [number, number, number];\ntype Rgb = [number, number, number];\nexport type AxisRole = 'bg' | 'surface' | 'elevated' | 'border' | 'muted' | 'text';\nexport type SourceAxis = Record<AxisRole | 'accent', string[]>;\nexport type TargetAxis = Partial<Record<AxisRole | 'accent', string>>;\n\nconst toLinear = (v: number) => { v /= 255; return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4; };\nconst toGamma = (v: number) => Math.round(255 * Math.min(1, Math.max(0, v <= 0.0031308 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055)));\n\nexport function rgbToOklab([r, g, b]: Rgb): Oklab {\n const [lr, lg, lb] = [toLinear(r), toLinear(g), toLinear(b)];\n const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);\n const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);\n const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);\n return [\n 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n ];\n}\n\nexport function oklabToRgb([L, A, B]: Oklab): Rgb {\n const l = (L + 0.3963377774 * A + 0.2158037573 * B) ** 3;\n const m = (L - 0.1055613458 * A - 0.0638541728 * B) ** 3;\n const s = (L - 0.0894841775 * A - 1.291485548 * B) ** 3;\n return [\n toGamma(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s),\n toGamma(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s),\n toGamma(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s),\n ];\n}\n\nconst keyRgb = (key: string) => key.split(',').map(Number) as Rgb;\nconst lerp = (a: Oklab, b: Oklab, t: number): Oklab => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];\nconst chroma = (c: Oklab) => Math.hypot(c[1], c[2]);\nconst hue = (c: Oklab) => (Math.atan2(c[2], c[1]) * 180) / Math.PI;\n\n/** Anything whose chroma is below this is a neutral (the site's grays carry a faint tint). */\nconst NEUTRAL_CHROMA = 0.05;\n/** How far past the site's own background/text a neutral may sit and still be on the axis (pure white\n * text in Lights out is slightly past the site's 231,233,234; black in Default is far past and is a shadow). */\nconst AXIS_SLACK = 0.12;\n\nexport type ColorModel = {\n sourceBg: Oklab;\n sourceText: Oklab;\n /** Sorted by `t`: the site's position on its bg→text axis and the theme color placed there. */\n anchors: Array<{ t: number; color: Oklab }>;\n /** The site's listed role colors (`r,g,b`) and the theme color they become, exactly. */\n exact: Map<string, Rgb>;\n sourceAccent: Oklab;\n accent: Oklab | null;\n};\n\n/**\n * How a color is used decides which site role wins where the site reuses one value for two roles (Default's\n * 239,243,244 is both a raised surface and a border): backgrounds read it as a surface, borders as\n * a border, text as text.\n */\nexport type Usage = 'background' | 'border' | 'text';\nconst PRIORITY: Record<Usage, AxisRole[]> = {\n background: ['bg', 'surface', 'elevated', 'border', 'muted', 'text'],\n border: ['bg', 'border', 'elevated', 'surface', 'muted', 'text'],\n // Text pins only text roles: a theme may draw borders brighter than its secondary text (High\n // Contrast), and a grey the site uses for text must not jump to that border.\n text: ['bg', 'text', 'muted'],\n};\n\n/**\n * The model for mapping the site's palette (`source`, one site mode) onto a theme's axis colors for one usage.\n * Every color the site lists for a role is pinned to the theme's color for that role (so a surface the site uses\n * stays exactly the theme's surface), and everything the site paints between them is interpolated.\n */\nexport function buildColorModel(source: SourceAxis, target: TargetAxis, usage: Usage = 'background'): ColorModel | null {\n if (!target.bg || !target.text) return null;\n const sourceBg = rgbToOklab(keyRgb(source.bg[0]!));\n const sourceText = rgbToOklab(keyRgb(source.text[0]!));\n const span = sourceText[0] - sourceBg[0];\n const position = (c: Oklab) => (c[0] - sourceBg[0]) / span;\n const anchors: ColorModel['anchors'] = [\n { t: 0, color: rgbToOklab(hexToRgb(target.bg)) },\n { t: 1, color: rgbToOklab(hexToRgb(target.text)) },\n ];\n const claimed = new Set<string>();\n const exact = new Map<string, Rgb>();\n for (const role of PRIORITY[usage]) {\n const color = target[role];\n for (const key of source[role]) {\n if (claimed.has(key)) continue;\n claimed.add(key);\n if (!color) continue;\n exact.set(key, hexToRgb(color));\n const t = position(rgbToOklab(keyRgb(key)));\n if (t <= 0.002 || t >= 0.998 || anchors.some(anchor => Math.abs(anchor.t - t) < 0.002)) continue;\n anchors.push({ t, color: rgbToOklab(hexToRgb(color)) });\n }\n }\n // Text and borders in the site's blue stay exactly the theme accent (legibility is checked on it);\n // accent backgrounds keep the site's lightness offsets (hover, pressed) through projectColor.\n if (target.accent && usage !== 'background') for (const key of source.accent) if (!exact.has(key)) exact.set(key, hexToRgb(target.accent));\n anchors.sort((a, b) => a.t - b.t);\n return {\n sourceBg, sourceText, anchors, exact,\n sourceAccent: rgbToOklab(keyRgb(source.accent[0]!)),\n accent: target.accent ? rgbToOklab(hexToRgb(target.accent)) : null,\n };\n}\n\n/** Where a neutral sits on the site's axis (0 = the site background, 1 = the site text), or null when it is off the axis. */\nexport function axisPosition(model: ColorModel, rgb: Rgb): number | null {\n const c = rgbToOklab(rgb);\n if (chroma(c) >= NEUTRAL_CHROMA) return null;\n const t = (c[0] - model.sourceBg[0]) / (model.sourceText[0] - model.sourceBg[0]);\n if (t < -AXIS_SLACK || t > 1 + AXIS_SLACK) return null;\n return Math.min(1, Math.max(0, t));\n}\n\nfunction onCurve(model: ColorModel, t: number): Oklab {\n const { anchors } = model;\n for (let i = 1; i < anchors.length; i++) {\n const a = anchors[i - 1]!, b = anchors[i]!;\n if (t <= b.t) return lerp(a.color, b.color, (t - a.t) / (b.t - a.t || 1));\n }\n return anchors[anchors.length - 1]!.color;\n}\n\n/** The site's accent family: same hue family as the site's accent, clearly chromatic. */\nfunction isAccentFamily(model: ColorModel, c: Oklab): boolean {\n if (chroma(c) < 0.07) return false;\n const delta = Math.abs(((hue(c) - hue(model.sourceAccent) + 540) % 360) - 180);\n return delta < 22;\n}\n\n/** The theme color for one of the site's colors, or null to leave it as the site painted it. */\nexport function projectColor(model: ColorModel, rgb: Rgb): Rgb | null {\n const listed = model.exact.get(rgb.join(','));\n if (listed) return listed;\n const c = rgbToOklab(rgb);\n const t = axisPosition(model, rgb);\n if (t !== null) return oklabToRgb(onCurve(model, t));\n if (model.accent && isAccentFamily(model, c)) {\n // Keep the site's lightness offset (hover is darker, tints lighter) on the theme's accent.\n const shifted: Oklab = [Math.min(1, Math.max(0, model.accent[0] + (c[0] - model.sourceAccent[0]))), model.accent[1], model.accent[2]];\n return oklabToRgb(shifted);\n }\n return null;\n}\n\n/**\n * The base structure every theme is built on: where a raised surface, a hover/elevated surface, a\n * border and secondary text sit between a theme's background (0) and its text (1), in OKLab\n * lightness. Taken from the built-in themes (their median), so a theme that only names its\n * background, text and accent gets the same proportions as the rest.\n */\nexport const BASE_STEPS: Record<'dark' | 'light', Record<'surface' | 'elevated' | 'border' | 'muted', number>> = {\n dark: { surface: 0.04, elevated: 0.09, border: 0.17, muted: 0.7 },\n light: { surface: 0.025, elevated: 0.06, border: 0.13, muted: 0.7 },\n};\n\nconst toHex = (rgb: Rgb) => `#${rgb.map(v => v.toString(16).padStart(2, '0')).join('')}`;\n\n/** Fills in the roles a theme did not name from its background, text and the base structure. */\nexport function deriveColors<T extends { bg: string; text: string; accent: string; surface?: string; elevated?: string; border?: string; muted?: string }>(seed: T):\n T & Record<'surface' | 'elevated' | 'border' | 'muted', string> {\n const bg = rgbToOklab(hexToRgb(seed.bg));\n const text = rgbToOklab(hexToRgb(seed.text));\n const steps = BASE_STEPS[bg[0] < text[0] ? 'dark' : 'light'];\n const at = (t: number) => toHex(oklabToRgb(lerp(bg, text, t)));\n return {\n ...seed,\n surface: seed.surface ?? at(steps.surface),\n elevated: seed.elevated ?? at(steps.elevated),\n border: seed.border ?? at(steps.border),\n muted: seed.muted ?? at(steps.muted),\n };\n}\n\n/** Where a theme's roles sit on its own background→text axis (0 = bg, 1 = text). */\nexport function rolePositions(colors: { bg: string; text: string } & Record<'surface' | 'elevated' | 'border' | 'muted', string>) {\n const L = (hex: string) => rgbToOklab(hexToRgb(hex))[0];\n const span = L(colors.text) - L(colors.bg);\n const pos = (hex: string) => (L(hex) - L(colors.bg)) / span;\n return { surface: pos(colors.surface), elevated: pos(colors.elevated), border: pos(colors.border), muted: pos(colors.muted) };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"themeTokens.js","sourceRoot":"","sources":["../../../runtime/src/themeTokens.ts"],"names":[],"mappings":"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","sourcesContent":["// The color foundation every theme is built on. The site's own palette (one per site color mode) is\n// the reference coordinate system: every neutral the site paints sits somewhere on its axis from page\n// background to text, and a theme says where its own background, surfaces, border, secondary text and\n// text sit on that same axis. Any site neutral (listed or not, hover tints included) lands at the same\n// position on the theme's curve, interpolated in OKLab, so nothing keeps the site's gray and nothing\n// collapses onto the wrong role. The site's accent family follows the theme accent with the same\n// lightness offset. Colors that mean something (likes, errors, badges) are left alone.\n//\n// Pure: runs in the page runtime, the settings previews and the tests. The site adapter supplies the\n// source palettes (`SourceAxis`, one per site mode); e.g. X's Default/Dim/Lights out.\n\nimport { hexToRgb } from './themeApi.ts';\n\nexport type Oklab = [number, number, number];\ntype Rgb = [number, number, number];\nexport type AxisRole = 'bg' | 'surface' | 'elevated' | 'border' | 'muted' | 'text';\nexport type SourceAxis = Record<AxisRole | 'accent', string[]>;\nexport type TargetAxis = Partial<Record<AxisRole | 'accent', string>>;\n\nconst toLinear = (v: number) => { v /= 255; return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4; };\nconst toGamma = (v: number) => Math.round(255 * Math.min(1, Math.max(0, v <= 0.0031308 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055)));\n\nexport function rgbToOklab([r, g, b]: Rgb): Oklab {\n const [lr, lg, lb] = [toLinear(r), toLinear(g), toLinear(b)];\n const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);\n const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);\n const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);\n return [\n 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n ];\n}\n\nexport function oklabToRgb([L, A, B]: Oklab): Rgb {\n const l = (L + 0.3963377774 * A + 0.2158037573 * B) ** 3;\n const m = (L - 0.1055613458 * A - 0.0638541728 * B) ** 3;\n const s = (L - 0.0894841775 * A - 1.291485548 * B) ** 3;\n return [\n toGamma(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s),\n toGamma(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s),\n toGamma(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s),\n ];\n}\n\nconst keyRgb = (key: string) => key.split(',').map(Number) as Rgb;\nconst lerp = (a: Oklab, b: Oklab, t: number): Oklab => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];\nconst chroma = (c: Oklab) => Math.hypot(c[1], c[2]);\nconst hue = (c: Oklab) => (Math.atan2(c[2], c[1]) * 180) / Math.PI;\n\n/** Anything whose chroma is below this is a neutral (the site's grays carry a faint tint). */\nconst NEUTRAL_CHROMA = 0.05;\n/** How far past the site's own background/text a neutral may sit and still be on the axis (pure white\n * text in Lights out is slightly past the site's 231,233,234; black in Default is far past and is a shadow). */\nconst AXIS_SLACK = 0.12;\n/** How close to a surface or to the secondary text a foreground may sit and still count as that role's own shade. */\nconst DIM_SLACK = 0.01;\n\nexport type ColorModel = {\n sourceBg: Oklab;\n sourceText: Oklab;\n /** Sorted by `t`: the site's position on its bg→text axis and the theme color placed there. */\n anchors: Array<{ t: number; color: Oklab }>;\n /** The site's listed role colors (`r,g,b`) and the theme color they become, exactly. */\n exact: Map<string, Rgb>;\n sourceAccent: Oklab;\n accent: Oklab | null;\n /**\n * Text only: the stretch of the site's axis between its most raised surface and its secondary text.\n * A foreground the site paints there (a dimmed icon, a gray it also uses for borders) would land\n * between the theme's background and its secondary text, under every contrast a theme guarantees;\n * it becomes the theme's secondary text instead. Below `from` a foreground is as dark (or light) as\n * the site's surfaces: a label on a filled surface, which keeps its place.\n */\n dim: { from: number; to: number; color: Rgb } | null;\n};\n\n/**\n * How a color is used decides which site role wins where the site reuses one value for two roles (Default's\n * 239,243,244 is both a raised surface and a border): backgrounds read it as a surface, borders as\n * a border, text as text.\n */\nexport type Usage = 'background' | 'border' | 'text';\nconst PRIORITY: Record<Usage, AxisRole[]> = {\n background: ['bg', 'surface', 'elevated', 'border', 'muted', 'text'],\n border: ['bg', 'border', 'elevated', 'surface', 'muted', 'text'],\n // Text pins only text roles: a theme may draw borders brighter than its secondary text (High\n // Contrast), and a grey the site uses for text must not jump to that border.\n text: ['bg', 'text', 'muted'],\n};\n\n/**\n * The model for mapping the site's palette (`source`, one site mode) onto a theme's axis colors for one usage.\n * Every color the site lists for a role is pinned to the theme's color for that role (so a surface the site uses\n * stays exactly the theme's surface), and everything the site paints between them is interpolated.\n */\nexport function buildColorModel(source: SourceAxis, target: TargetAxis, usage: Usage = 'background'): ColorModel | null {\n if (!target.bg || !target.text) return null;\n const sourceBg = rgbToOklab(keyRgb(source.bg[0]!));\n const sourceText = rgbToOklab(keyRgb(source.text[0]!));\n const span = sourceText[0] - sourceBg[0];\n const position = (c: Oklab) => (c[0] - sourceBg[0]) / span;\n const anchors: ColorModel['anchors'] = [\n { t: 0, color: rgbToOklab(hexToRgb(target.bg)) },\n { t: 1, color: rgbToOklab(hexToRgb(target.text)) },\n ];\n const claimed = new Set<string>();\n const exact = new Map<string, Rgb>();\n for (const role of PRIORITY[usage]) {\n const color = target[role];\n for (const key of source[role]) {\n if (claimed.has(key)) continue;\n claimed.add(key);\n if (!color) continue;\n exact.set(key, hexToRgb(color));\n const t = position(rgbToOklab(keyRgb(key)));\n if (t <= 0.002 || t >= 0.998 || anchors.some(anchor => Math.abs(anchor.t - t) < 0.002)) continue;\n anchors.push({ t, color: rgbToOklab(hexToRgb(color)) });\n }\n }\n // Text and borders in the site's blue stay exactly the theme accent (legibility is checked on it);\n // accent backgrounds keep the site's lightness offsets (hover, pressed) through projectColor.\n if (target.accent && usage !== 'background') for (const key of source.accent) if (!exact.has(key)) exact.set(key, hexToRgb(target.accent));\n anchors.sort((a, b) => a.t - b.t);\n let dim: ColorModel['dim'] = null;\n if (usage === 'text' && target.muted && source.muted.length) {\n const positions = (roles: AxisRole[]) => roles.flatMap(role => source[role].map(key => position(rgbToOklab(keyRgb(key)))));\n const from = Math.max(0, ...positions(['bg', 'surface', 'elevated'])) + DIM_SLACK;\n const to = Math.min(...positions(['muted'])) - DIM_SLACK;\n if (to > from) dim = { from, to, color: hexToRgb(target.muted) };\n }\n return {\n sourceBg, sourceText, anchors, exact, dim,\n sourceAccent: rgbToOklab(keyRgb(source.accent[0]!)),\n accent: target.accent ? rgbToOklab(hexToRgb(target.accent)) : null,\n };\n}\n\n/** Where a neutral sits on the site's axis (0 = the site background, 1 = the site text), or null when it is off the axis. */\nexport function axisPosition(model: ColorModel, rgb: Rgb): number | null {\n const c = rgbToOklab(rgb);\n if (chroma(c) >= NEUTRAL_CHROMA) return null;\n const t = (c[0] - model.sourceBg[0]) / (model.sourceText[0] - model.sourceBg[0]);\n if (t < -AXIS_SLACK || t > 1 + AXIS_SLACK) return null;\n return Math.min(1, Math.max(0, t));\n}\n\nfunction onCurve(model: ColorModel, t: number): Oklab {\n const { anchors } = model;\n for (let i = 1; i < anchors.length; i++) {\n const a = anchors[i - 1]!, b = anchors[i]!;\n if (t <= b.t) return lerp(a.color, b.color, (t - a.t) / (b.t - a.t || 1));\n }\n return anchors[anchors.length - 1]!.color;\n}\n\n/** The site's accent family: same hue family as the site's accent, clearly chromatic. */\nfunction isAccentFamily(model: ColorModel, c: Oklab): boolean {\n if (chroma(c) < 0.07) return false;\n const delta = Math.abs(((hue(c) - hue(model.sourceAccent) + 540) % 360) - 180);\n return delta < 22;\n}\n\n/** The theme color for one of the site's colors, or null to leave it as the site painted it. */\nexport function projectColor(model: ColorModel, rgb: Rgb): Rgb | null {\n const listed = model.exact.get(rgb.join(','));\n if (listed) return listed;\n const c = rgbToOklab(rgb);\n const t = axisPosition(model, rgb);\n if (t !== null && model.dim && t > model.dim.from && t < model.dim.to) return model.dim.color;\n if (t !== null) return oklabToRgb(onCurve(model, t));\n if (model.accent && isAccentFamily(model, c)) {\n // Keep the site's lightness offset (hover is darker, tints lighter) on the theme's accent.\n const shifted: Oklab = [Math.min(1, Math.max(0, model.accent[0] + (c[0] - model.sourceAccent[0]))), model.accent[1], model.accent[2]];\n return oklabToRgb(shifted);\n }\n return null;\n}\n\n/**\n * The base structure every theme is built on: where a raised surface, a hover/elevated surface, a\n * border and secondary text sit between a theme's background (0) and its text (1), in OKLab\n * lightness. Taken from the built-in themes (their median), so a theme that only names its\n * background, text and accent gets the same proportions as the rest.\n */\nexport const BASE_STEPS: Record<'dark' | 'light', Record<'surface' | 'elevated' | 'border' | 'muted', number>> = {\n dark: { surface: 0.04, elevated: 0.09, border: 0.17, muted: 0.7 },\n light: { surface: 0.025, elevated: 0.06, border: 0.13, muted: 0.7 },\n};\n\nconst toHex = (rgb: Rgb) => `#${rgb.map(v => v.toString(16).padStart(2, '0')).join('')}`;\n\n/** Fills in the roles a theme did not name from its background, text and the base structure. */\nexport function deriveColors<T extends { bg: string; text: string; accent: string; surface?: string; elevated?: string; border?: string; muted?: string }>(seed: T):\n T & Record<'surface' | 'elevated' | 'border' | 'muted', string> {\n const bg = rgbToOklab(hexToRgb(seed.bg));\n const text = rgbToOklab(hexToRgb(seed.text));\n const steps = BASE_STEPS[bg[0] < text[0] ? 'dark' : 'light'];\n const at = (t: number) => toHex(oklabToRgb(lerp(bg, text, t)));\n return {\n ...seed,\n surface: seed.surface ?? at(steps.surface),\n elevated: seed.elevated ?? at(steps.elevated),\n border: seed.border ?? at(steps.border),\n muted: seed.muted ?? at(steps.muted),\n };\n}\n\n/** Where a theme's roles sit on its own background→text axis (0 = bg, 1 = text). */\nexport function rolePositions(colors: { bg: string; text: string } & Record<'surface' | 'elevated' | 'border' | 'muted', string>) {\n const L = (hex: string) => rgbToOklab(hexToRgb(hex))[0];\n const span = L(colors.text) - L(colors.bg);\n const pos = (hex: string) => (L(hex) - L(colors.bg)) / span;\n return { surface: pos(colors.surface), elevated: pos(colors.elevated), border: pos(colors.border), muted: pos(colors.muted) };\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** The axes and their options. The first option of each axis is the site's own layout (no rule). */
|
|
2
|
+
export declare const VARIANT_AXES: {
|
|
3
|
+
readonly nav: readonly ["labels", "icons", "top", "bottom"];
|
|
4
|
+
readonly post: readonly ["default", "cards", "bubbles", "compact", "broadsheet"];
|
|
5
|
+
readonly actions: readonly ["icons", "labels", "quiet"];
|
|
6
|
+
readonly header: readonly ["default", "solid", "bar"];
|
|
7
|
+
readonly sidebar: readonly ["default", "narrow", "hidden"];
|
|
8
|
+
readonly width: readonly ["default", "full"];
|
|
9
|
+
};
|
|
10
|
+
export type VariantAxis = keyof typeof VARIANT_AXES;
|
|
11
|
+
export declare const VARIANT_AXIS_NAMES: VariantAxis[];
|
|
12
|
+
export type ThemeVariants = {
|
|
13
|
+
[A in VariantAxis]?: typeof VARIANT_AXES[A][number];
|
|
14
|
+
};
|
|
15
|
+
/** The `variants` group from JSON: known axes and options only; an axis left at the site's own layout is dropped. */
|
|
16
|
+
export declare function sanitizeVariants(value: unknown): ThemeVariants | null;
|
|
17
|
+
export type VariantGate = {
|
|
18
|
+
/** The owner lets themes change the layout (default: yes). */
|
|
19
|
+
allowed?: boolean;
|
|
20
|
+
/** Axes an owner's own switch controls right now: the theme's suggestion is not drawn for them. */
|
|
21
|
+
owned?: readonly VariantAxis[];
|
|
22
|
+
};
|
|
23
|
+
/** The variants that are drawn: the theme's (with the owner's customization already merged in), minus what the owner holds. */
|
|
24
|
+
export declare function resolveVariants(variants: ThemeVariants | null | undefined, gate?: VariantGate): ThemeVariants;
|
|
25
|
+
/** A site's CSS for each variant it can draw: `skins.nav.top(ctx)` returns the rules. */
|
|
26
|
+
export type VariantSkins<Context> = {
|
|
27
|
+
[A in VariantAxis]?: Partial<Record<typeof VARIANT_AXES[A][number], (ctx: Context) => string>>;
|
|
28
|
+
};
|
|
29
|
+
/** The CSS of the resolved variants, in axis order. A variant the site has no skin for draws nothing. */
|
|
30
|
+
export declare function compileVariants<Context>(variants: ThemeVariants, skins: VariantSkins<Context>, ctx: Context): string[];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Layout variants: the structural choices a theme may suggest (navigation on top, compact posts,
|
|
2
|
+
// worded actions), as fixed words on a few axes. The vocabulary and the precedence are here; what a
|
|
3
|
+
// variant looks like on a site is that site's CSS (its skins). Pure.
|
|
4
|
+
//
|
|
5
|
+
// A theme suggests, the owner decides: an axis an owner's own switch already controls is left to that
|
|
6
|
+
// switch, and the owner can turn layout changes by themes off altogether.
|
|
7
|
+
/** The axes and their options. The first option of each axis is the site's own layout (no rule). */
|
|
8
|
+
export const VARIANT_AXES = {
|
|
9
|
+
nav: ['labels', 'icons', 'top', 'bottom'],
|
|
10
|
+
post: ['default', 'cards', 'bubbles', 'compact', 'broadsheet'],
|
|
11
|
+
actions: ['icons', 'labels', 'quiet'],
|
|
12
|
+
header: ['default', 'solid', 'bar'],
|
|
13
|
+
sidebar: ['default', 'narrow', 'hidden'],
|
|
14
|
+
width: ['default', 'full'],
|
|
15
|
+
};
|
|
16
|
+
export const VARIANT_AXIS_NAMES = Object.keys(VARIANT_AXES);
|
|
17
|
+
/** The `variants` group from JSON: known axes and options only; an axis left at the site's own layout is dropped. */
|
|
18
|
+
export function sanitizeVariants(value) {
|
|
19
|
+
const source = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
20
|
+
const out = {};
|
|
21
|
+
for (const axis of VARIANT_AXIS_NAMES) {
|
|
22
|
+
const options = VARIANT_AXES[axis];
|
|
23
|
+
const option = source[axis];
|
|
24
|
+
if (typeof option === 'string' && options.includes(option) && option !== options[0])
|
|
25
|
+
out[axis] = option;
|
|
26
|
+
}
|
|
27
|
+
return Object.keys(out).length ? out : null;
|
|
28
|
+
}
|
|
29
|
+
/** The variants that are drawn: the theme's (with the owner's customization already merged in), minus what the owner holds. */
|
|
30
|
+
export function resolveVariants(variants, gate = {}) {
|
|
31
|
+
if (!variants || gate.allowed === false)
|
|
32
|
+
return {};
|
|
33
|
+
const out = {};
|
|
34
|
+
for (const axis of VARIANT_AXIS_NAMES) {
|
|
35
|
+
const option = variants[axis];
|
|
36
|
+
if (option && !gate.owned?.includes(axis))
|
|
37
|
+
out[axis] = option;
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/** The CSS of the resolved variants, in axis order. A variant the site has no skin for draws nothing. */
|
|
42
|
+
export function compileVariants(variants, skins, ctx) {
|
|
43
|
+
const out = [];
|
|
44
|
+
for (const axis of VARIANT_AXIS_NAMES) {
|
|
45
|
+
const option = variants[axis];
|
|
46
|
+
const build = option ? skins[axis]?.[option] : undefined;
|
|
47
|
+
const css = build?.(ctx);
|
|
48
|
+
if (css)
|
|
49
|
+
out.push(css);
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=themeVariants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themeVariants.js","sourceRoot":"","sources":["../../../runtime/src/themeVariants.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,oGAAoG;AACpG,qEAAqE;AACrE,EAAE;AACF,sGAAsG;AACtG,0EAA0E;AAE1E,oGAAoG;AACpG,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,GAAG,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;IACzC,IAAI,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC;IAC9D,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC;IACrC,MAAM,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC;IACnC,OAAO,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACxC,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;CAClB,CAAC;AAEX,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAkB,CAAC;AAG7E,qHAAqH;AACrH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,MAAM,MAAM,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnH,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACtC,MAAM,OAAO,GAAsB,YAAY,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IAC1G,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAoB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AASD,+HAA+H;AAC/H,MAAM,UAAU,eAAe,CAAC,QAA0C,EAAE,OAAoB,EAAE;IAChG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IACnD,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IAChE,CAAC;IACD,OAAO,GAAoB,CAAC;AAC9B,CAAC;AAKD,yGAAyG;AACzG,MAAM,UAAU,eAAe,CAAU,QAAuB,EAAE,KAA4B,EAAE,GAAY;IAC1G,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,KAAK,CAAC,IAAI,CAAwE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACjI,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,GAAG;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["// Layout variants: the structural choices a theme may suggest (navigation on top, compact posts,\n// worded actions), as fixed words on a few axes. The vocabulary and the precedence are here; what a\n// variant looks like on a site is that site's CSS (its skins). Pure.\n//\n// A theme suggests, the owner decides: an axis an owner's own switch already controls is left to that\n// switch, and the owner can turn layout changes by themes off altogether.\n\n/** The axes and their options. The first option of each axis is the site's own layout (no rule). */\nexport const VARIANT_AXES = {\n nav: ['labels', 'icons', 'top', 'bottom'],\n post: ['default', 'cards', 'bubbles', 'compact', 'broadsheet'],\n actions: ['icons', 'labels', 'quiet'],\n header: ['default', 'solid', 'bar'],\n sidebar: ['default', 'narrow', 'hidden'],\n width: ['default', 'full'],\n} as const;\nexport type VariantAxis = keyof typeof VARIANT_AXES;\nexport const VARIANT_AXIS_NAMES = Object.keys(VARIANT_AXES) as VariantAxis[];\nexport type ThemeVariants = { [A in VariantAxis]?: typeof VARIANT_AXES[A][number] };\n\n/** The `variants` group from JSON: known axes and options only; an axis left at the site's own layout is dropped. */\nexport function sanitizeVariants(value: unknown): ThemeVariants | null {\n const source = value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};\n const out: Record<string, string> = {};\n for (const axis of VARIANT_AXIS_NAMES) {\n const options: readonly string[] = VARIANT_AXES[axis];\n const option = source[axis];\n if (typeof option === 'string' && options.includes(option) && option !== options[0]) out[axis] = option;\n }\n return Object.keys(out).length ? out as ThemeVariants : null;\n}\n\nexport type VariantGate = {\n /** The owner lets themes change the layout (default: yes). */\n allowed?: boolean;\n /** Axes an owner's own switch controls right now: the theme's suggestion is not drawn for them. */\n owned?: readonly VariantAxis[];\n};\n\n/** The variants that are drawn: the theme's (with the owner's customization already merged in), minus what the owner holds. */\nexport function resolveVariants(variants: ThemeVariants | null | undefined, gate: VariantGate = {}): ThemeVariants {\n if (!variants || gate.allowed === false) return {};\n const out: Record<string, string> = {};\n for (const axis of VARIANT_AXIS_NAMES) {\n const option = variants[axis];\n if (option && !gate.owned?.includes(axis)) out[axis] = option;\n }\n return out as ThemeVariants;\n}\n\n/** A site's CSS for each variant it can draw: `skins.nav.top(ctx)` returns the rules. */\nexport type VariantSkins<Context> = { [A in VariantAxis]?: Partial<Record<typeof VARIANT_AXES[A][number], (ctx: Context) => string>> };\n\n/** The CSS of the resolved variants, in axis order. A variant the site has no skin for draws nothing. */\nexport function compileVariants<Context>(variants: ThemeVariants, skins: VariantSkins<Context>, ctx: Context): string[] {\n const out: string[] = [];\n for (const axis of VARIANT_AXIS_NAMES) {\n const option = variants[axis];\n const build = option ? (skins[axis] as Record<string, ((ctx: Context) => string) | undefined> | undefined)?.[option] : undefined;\n const css = build?.(ctx);\n if (css) out.push(css);\n }\n return out;\n}\n"]}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { type ThemeApi } from './themeApi.ts';
|
|
2
|
+
export type Tone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
|
|
3
|
+
/** Dialog content: text, a node, or a function that fills the dialog's body element. */
|
|
4
|
+
export type Content = string | Node | ((body: HTMLElement) => void) | null | undefined;
|
|
5
|
+
export type ModalAction = {
|
|
6
|
+
label: string;
|
|
7
|
+
/** `primary` (filled, the theme's button colors), `secondary` (outlined, default), `danger`, `plain` (text). */
|
|
8
|
+
tone?: 'primary' | 'secondary' | 'danger' | 'plain';
|
|
9
|
+
/** Runs on click. Return `false` (or a promise of `false`) to keep the dialog open. */
|
|
10
|
+
onClick?: (handle: ModalHandle) => unknown;
|
|
11
|
+
/** What `closed` resolves with when this action closes the dialog (default: the label). */
|
|
12
|
+
value?: unknown;
|
|
13
|
+
/** Enter in a single-line field (or on the dialog itself) runs this action. */
|
|
14
|
+
default?: boolean;
|
|
15
|
+
/** Focused when the dialog opens. */
|
|
16
|
+
autoFocus?: boolean;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type ModalOptions = {
|
|
20
|
+
role?: 'dialog' | 'alertdialog';
|
|
21
|
+
title?: string;
|
|
22
|
+
/** Text under the title (also the dialog's accessible description). */
|
|
23
|
+
message?: string;
|
|
24
|
+
/** Accessible name when there is no visible title. */
|
|
25
|
+
label?: string;
|
|
26
|
+
content?: Content;
|
|
27
|
+
actions?: ModalAction[];
|
|
28
|
+
/** px, or `sm` (380), `md` (480, default), `lg` (640). Always fits the window. */
|
|
29
|
+
width?: number | 'sm' | 'md' | 'lg';
|
|
30
|
+
/** Adds a tone icon before the title. */
|
|
31
|
+
tone?: Tone;
|
|
32
|
+
/** Esc and the close button dismiss it (default true). */
|
|
33
|
+
dismissible?: boolean;
|
|
34
|
+
/** A click on the backdrop dismisses it (default false; alerts and confirmations say true). */
|
|
35
|
+
closeOnBackdrop?: boolean;
|
|
36
|
+
/** Shows a close button in the header (default: dismissible and titled). */
|
|
37
|
+
closeButton?: boolean;
|
|
38
|
+
/** Element or selector (inside the dialog) to focus first. */
|
|
39
|
+
initialFocus?: HTMLElement | string;
|
|
40
|
+
/** Extra CSS for this dialog's content (scoped to the kit's shadow root). */
|
|
41
|
+
css?: string;
|
|
42
|
+
/** `closed` resolves with this when dismissed (Esc, backdrop, close button, owner stopped). */
|
|
43
|
+
dismissValue?: unknown;
|
|
44
|
+
/** Buttons stacked full width (the site's confirmation sheet look) instead of a right-aligned row. */
|
|
45
|
+
stackActions?: boolean;
|
|
46
|
+
onClose?: (result: unknown) => void;
|
|
47
|
+
};
|
|
48
|
+
export type ModalHandle = {
|
|
49
|
+
/** The dialog element (`role="dialog"`). */
|
|
50
|
+
readonly element: HTMLElement;
|
|
51
|
+
/** Where `content` went; add or replace your own nodes here. */
|
|
52
|
+
readonly body: HTMLElement;
|
|
53
|
+
readonly open: boolean;
|
|
54
|
+
/** Resolves with the close result once the dialog is gone. */
|
|
55
|
+
readonly closed: Promise<unknown>;
|
|
56
|
+
close(result?: unknown): void;
|
|
57
|
+
/** Shows (or clears with null) an error line above the actions, announced to screen readers. */
|
|
58
|
+
setError(message: string | null): void;
|
|
59
|
+
/** Disables the actions while something runs. */
|
|
60
|
+
setBusy(busy: boolean): void;
|
|
61
|
+
};
|
|
62
|
+
export type DialogOptions = Omit<ModalOptions, 'role'>;
|
|
63
|
+
export type AlertOptions = {
|
|
64
|
+
title?: string;
|
|
65
|
+
message?: string;
|
|
66
|
+
tone?: Tone;
|
|
67
|
+
okLabel?: string;
|
|
68
|
+
};
|
|
69
|
+
export type ConfirmOptions = {
|
|
70
|
+
title?: string;
|
|
71
|
+
message?: string;
|
|
72
|
+
confirmLabel?: string;
|
|
73
|
+
cancelLabel?: string;
|
|
74
|
+
danger?: boolean;
|
|
75
|
+
};
|
|
76
|
+
export type PromptOptions = {
|
|
77
|
+
title?: string;
|
|
78
|
+
message?: string;
|
|
79
|
+
label?: string;
|
|
80
|
+
value?: string;
|
|
81
|
+
placeholder?: string;
|
|
82
|
+
/** Return an error message (or false) to refuse the value; anything else accepts it. */
|
|
83
|
+
validate?: (value: string) => string | boolean | null | undefined;
|
|
84
|
+
/** A textarea instead of a single line (Ctrl/Cmd+Enter submits). */
|
|
85
|
+
multiline?: boolean;
|
|
86
|
+
maxLength?: number;
|
|
87
|
+
confirmLabel?: string;
|
|
88
|
+
cancelLabel?: string;
|
|
89
|
+
width?: ModalOptions['width'];
|
|
90
|
+
};
|
|
91
|
+
export type ToastAction = {
|
|
92
|
+
label: string;
|
|
93
|
+
onClick: () => void;
|
|
94
|
+
};
|
|
95
|
+
export type ToastOptions = {
|
|
96
|
+
tone?: Tone;
|
|
97
|
+
/** ms on screen (default 3200, 6000 with an action); 0 keeps it until closed. */
|
|
98
|
+
duration?: number;
|
|
99
|
+
action?: ToastAction;
|
|
100
|
+
};
|
|
101
|
+
export type ToastHandle = {
|
|
102
|
+
readonly element: HTMLElement;
|
|
103
|
+
close(): void;
|
|
104
|
+
readonly closed: Promise<void>;
|
|
105
|
+
};
|
|
106
|
+
type Child = Node | string | number | null | undefined | false | Child[];
|
|
107
|
+
export type ElementProps = Record<string, unknown>;
|
|
108
|
+
export type UiKit = {
|
|
109
|
+
toast(message: string, options?: ToastOptions | number): ToastHandle;
|
|
110
|
+
alert(options: AlertOptions | string): Promise<void>;
|
|
111
|
+
confirm(options: ConfirmOptions | string): Promise<boolean>;
|
|
112
|
+
prompt(options: PromptOptions | string): Promise<string | null>;
|
|
113
|
+
dialog(options: DialogOptions): ModalHandle;
|
|
114
|
+
modal(options: ModalOptions): ModalHandle;
|
|
115
|
+
/**
|
|
116
|
+
* A safe element builder for dialog content: `h('label', { class: 'wb-check' }, input, 'Text')`.
|
|
117
|
+
* Strings become text nodes; `on<event>` functions become listeners; `value`/`checked`/`disabled`
|
|
118
|
+
* are set as properties; everything else as attributes (no `innerHTML`, no string handlers, no
|
|
119
|
+
* `javascript:` URLs).
|
|
120
|
+
*/
|
|
121
|
+
h(tag: string, props?: ElementProps | null, ...children: Child[]): HTMLElement;
|
|
122
|
+
};
|
|
123
|
+
export type UiKitOptions = {
|
|
124
|
+
theme: ThemeApi;
|
|
125
|
+
/** Custom element name of the shadow host (default `wb-ui`). */
|
|
126
|
+
hostTag?: string;
|
|
127
|
+
/** Id of the shadow host element. */
|
|
128
|
+
hostId?: string;
|
|
129
|
+
zIndex?: number;
|
|
130
|
+
/** Console prefix. */
|
|
131
|
+
product?: string;
|
|
132
|
+
/**
|
|
133
|
+
* The kit's own words (buttons, accessible names, default errors) in the app's language:
|
|
134
|
+
* called with a `kit.*` key and returns the translation, or undefined for English.
|
|
135
|
+
*/
|
|
136
|
+
text?: (key: KitKey) => string | undefined;
|
|
137
|
+
};
|
|
138
|
+
/** The kit's default words (English source; `kit.*` keys in the framework catalogs). */
|
|
139
|
+
export declare const KIT_MESSAGES: {
|
|
140
|
+
readonly 'kit.ok': "OK";
|
|
141
|
+
readonly 'kit.cancel': "Cancel";
|
|
142
|
+
readonly 'kit.delete': "Delete";
|
|
143
|
+
readonly 'kit.close': "Close";
|
|
144
|
+
readonly 'kit.dismiss': "Dismiss";
|
|
145
|
+
readonly 'kit.dialog': "Dialog";
|
|
146
|
+
readonly 'kit.value': "Value";
|
|
147
|
+
readonly 'kit.checkValue': "Please check this value.";
|
|
148
|
+
readonly 'kit.failed': "Something went wrong.";
|
|
149
|
+
readonly 'kit.save': "Save";
|
|
150
|
+
readonly 'kit.feature.paused': "{feature} ({area}) is paused: this page changed.";
|
|
151
|
+
readonly 'kit.feature.pausedOne': "A feature of {area} is paused: this page changed.";
|
|
152
|
+
readonly 'kit.feature.pausedList': "Paused features of {area}";
|
|
153
|
+
readonly 'kit.feature.needsEnglish': "{feature} needs the site in English.";
|
|
154
|
+
readonly 'kit.feature.settings': "{name} settings";
|
|
155
|
+
};
|
|
156
|
+
export type KitKey = keyof typeof KIT_MESSAGES;
|
|
157
|
+
export type RootUiKit = UiKit & {
|
|
158
|
+
/** A kit whose dialogs and toasts are closed by `dispose()` (a plugin's `scope.ui`). */
|
|
159
|
+
scoped(): {
|
|
160
|
+
kit: UiKit;
|
|
161
|
+
dispose(): void;
|
|
162
|
+
};
|
|
163
|
+
/** Open dialogs, bottom first (for tests and the shell). */
|
|
164
|
+
openModals(): number;
|
|
165
|
+
};
|
|
166
|
+
export declare const WIDTHS: {
|
|
167
|
+
readonly sm: 380;
|
|
168
|
+
readonly md: 480;
|
|
169
|
+
readonly lg: 640;
|
|
170
|
+
};
|
|
171
|
+
export declare const MAX_TOASTS = 4;
|
|
172
|
+
/** Dialog width in px for an option value. */
|
|
173
|
+
export declare function dialogWidth(width: ModalOptions['width']): number;
|
|
174
|
+
/** How long a toast stays: explicit ms, 0 = until closed; defaults 3200 / 6000 with an action. */
|
|
175
|
+
export declare function toastDuration(options: ToastOptions): number;
|
|
176
|
+
/** Tab / Shift+Tab inside a trap: the index to focus next, or -1 to let the browser move focus. */
|
|
177
|
+
export declare function trapIndex(count: number, current: number, backwards: boolean): number;
|
|
178
|
+
/** A validator's answer as an error message (null = valid). */
|
|
179
|
+
export declare function validationMessage(result: unknown, fallback?: string): string | null;
|
|
180
|
+
/**
|
|
181
|
+
* Whether a URL attribute value is safe: relative, or http(s)/mailto. Checked the way browsers read
|
|
182
|
+
* a URL (tabs and newlines anywhere and leading control characters/spaces are ignored), so
|
|
183
|
+
* `java\tscript:` or `\x01javascript:` do not slip through.
|
|
184
|
+
*/
|
|
185
|
+
export declare function isSafeUrl(value: string): boolean;
|
|
186
|
+
/** The builder behind `ui.h`, for any document. */
|
|
187
|
+
export declare function buildElement(doc: Document, tag: string, props?: ElementProps | null, ...children: Child[]): HTMLElement;
|
|
188
|
+
export declare const UI_CSS: string;
|
|
189
|
+
/** The deepest focused element, through open shadow roots. */
|
|
190
|
+
export declare function deepActiveElement(doc: Document): HTMLElement | null;
|
|
191
|
+
export declare function createUiKit(win: Window & typeof globalThis, options: UiKitOptions): RootUiKit;
|
|
192
|
+
export {};
|