@owlmeans/web-panel 0.1.18-rc.9 → 0.1.18
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 +510 -143
- package/THIRD-PARTY-NOTICES.txt +24 -0
- package/agent-meta/manifest.json +163 -4
- package/agent-meta/skills/web-panel/SKILL.md +136 -83
- package/agent-meta/skills/web-panel/parts/consent.md +114 -0
- package/agent-meta/skills/web-panel/parts/editor.md +47 -0
- package/agent-meta/skills/web-panel/parts/forms.md +85 -0
- package/agent-meta/skills/web-panel/parts/navigation.md +203 -0
- package/agent-meta/skills/web-panel/parts/picker.md +164 -0
- package/agent-meta/skills/web-panel/parts/reload.md +46 -0
- package/agent-meta/skills/web-panel/parts/sign-in.md +65 -0
- package/agent-meta/skills/web-panel/parts/theme.md +74 -0
- package/build/@/components/ui/alert-dialog.d.ts +15 -0
- package/build/@/components/ui/alert-dialog.d.ts.map +1 -0
- package/build/@/components/ui/alert-dialog.js +39 -0
- package/build/@/components/ui/alert-dialog.js.map +1 -0
- package/build/@/components/ui/alert.js +1 -1
- package/build/@/components/ui/alert.js.map +1 -1
- package/build/@/components/ui/button.js +1 -1
- package/build/@/components/ui/button.js.map +1 -1
- package/build/@/components/ui/card.js +1 -1
- package/build/@/components/ui/card.js.map +1 -1
- package/build/@/components/ui/input.js +1 -1
- package/build/@/components/ui/input.js.map +1 -1
- package/build/@/components/ui/label.js +1 -1
- package/build/@/components/ui/label.js.map +1 -1
- package/build/@/components/ui/navigation-menu.js +1 -1
- package/build/@/components/ui/navigation-menu.js.map +1 -1
- package/build/@/components/ui/popover.d.ts +8 -0
- package/build/@/components/ui/popover.d.ts.map +1 -0
- package/build/@/components/ui/popover.js +17 -0
- package/build/@/components/ui/popover.js.map +1 -0
- package/build/@/components/ui/progress.js +1 -1
- package/build/@/components/ui/progress.js.map +1 -1
- package/build/@/components/ui/separator.js +1 -1
- package/build/@/components/ui/separator.js.map +1 -1
- package/build/@/components/ui/sheet.d.ts +15 -0
- package/build/@/components/ui/sheet.d.ts.map +1 -0
- package/build/@/components/ui/sheet.js +40 -0
- package/build/@/components/ui/sheet.js.map +1 -0
- package/build/auth/context.d.ts.map +1 -1
- package/build/auth/context.js +0 -1
- package/build/auth/context.js.map +1 -1
- package/build/auth/entrypoints.d.ts +10 -0
- package/build/auth/entrypoints.d.ts.map +1 -0
- package/build/auth/entrypoints.js +4 -0
- package/build/auth/entrypoints.js.map +1 -0
- package/build/auth/exports.d.ts +4 -4
- package/build/auth/exports.d.ts.map +1 -1
- package/build/auth/exports.js +3 -3
- package/build/auth/exports.js.map +1 -1
- package/build/auth/modules.d.ts +1 -1
- package/build/auth/modules.d.ts.map +1 -1
- package/build/auth/plugins/basic-ed25519.js +4 -4
- package/build/auth/plugins/basic-ed25519.js.map +1 -1
- package/build/auth/plugins/re-captcha.js +3 -3
- package/build/auth/plugins/re-captcha.js.map +1 -1
- package/build/auth/plugins/tunnel-consumer.js +1 -1
- package/build/auth/plugins/tunnel-consumer.js.map +1 -1
- package/build/components/block.js +2 -2
- package/build/components/block.js.map +1 -1
- package/build/components/consts.local.d.ts +14 -0
- package/build/components/consts.local.d.ts.map +1 -0
- package/build/components/consts.local.js +26 -0
- package/build/components/consts.local.js.map +1 -0
- package/build/components/footer/component.d.ts +19 -1
- package/build/components/footer/component.d.ts.map +1 -1
- package/build/components/footer/component.js +38 -11
- package/build/components/footer/component.js.map +1 -1
- package/build/components/footer/credit.d.ts +27 -0
- package/build/components/footer/credit.d.ts.map +1 -0
- package/build/components/footer/credit.js +42 -0
- package/build/components/footer/credit.js.map +1 -0
- package/build/components/footer/index.d.ts +1 -0
- package/build/components/footer/index.d.ts.map +1 -1
- package/build/components/footer/index.js +1 -0
- package/build/components/footer/index.js.map +1 -1
- package/build/components/footer/types.d.ts +22 -1
- package/build/components/footer/types.d.ts.map +1 -1
- package/build/components/form/button/component.d.ts.map +1 -1
- package/build/components/form/button/component.js +5 -3
- package/build/components/form/button/component.js.map +1 -1
- package/build/components/form/component.js +2 -2
- package/build/components/form/component.js.map +1 -1
- package/build/components/form/text/component.js +2 -2
- package/build/components/form/text/component.js.map +1 -1
- package/build/components/helper.d.ts.map +1 -1
- package/build/components/helper.js +1 -12
- package/build/components/helper.js.map +1 -1
- package/build/components/index.d.ts +4 -0
- package/build/components/index.d.ts.map +1 -1
- package/build/components/index.js +4 -0
- package/build/components/index.js.map +1 -1
- package/build/components/link.js +3 -3
- package/build/components/link.js.map +1 -1
- package/build/components/login/append.d.ts +15 -0
- package/build/components/login/append.d.ts.map +1 -0
- package/build/components/login/append.js +26 -0
- package/build/components/login/append.js.map +1 -0
- package/build/components/login/consts.d.ts +3 -0
- package/build/components/login/consts.d.ts.map +1 -0
- package/build/components/login/consts.js +3 -0
- package/build/components/login/consts.js.map +1 -0
- package/build/components/login/consts.local.d.ts +4 -0
- package/build/components/login/consts.local.d.ts.map +1 -0
- package/build/components/login/consts.local.js +8 -0
- package/build/components/login/consts.local.js.map +1 -0
- package/build/components/login/credit.d.ts +12 -0
- package/build/components/login/credit.d.ts.map +1 -0
- package/build/components/login/credit.js +18 -0
- package/build/components/login/credit.js.map +1 -0
- package/build/components/login/i18n/be.json +10 -0
- package/build/components/login/i18n/de.json +10 -0
- package/build/components/login/i18n/en.json +10 -0
- package/build/components/login/i18n/es.json +10 -0
- package/build/components/login/i18n/fr.json +10 -0
- package/build/components/login/i18n/pl.json +10 -0
- package/build/components/login/i18n/ru.json +10 -0
- package/build/components/login/i18n/uk.json +10 -0
- package/build/components/login/i18n.d.ts +2 -0
- package/build/components/login/i18n.d.ts.map +1 -0
- package/build/components/login/i18n.js +28 -0
- package/build/components/login/i18n.js.map +1 -0
- package/build/components/login/icons.d.ts +14 -0
- package/build/components/login/icons.d.ts.map +1 -0
- package/build/components/login/icons.js +29 -0
- package/build/components/login/icons.js.map +1 -0
- package/build/components/login/index.d.ts +11 -0
- package/build/components/login/index.d.ts.map +1 -0
- package/build/components/login/index.js +10 -0
- package/build/components/login/index.js.map +1 -0
- package/build/components/login/notify.d.ts +18 -0
- package/build/components/login/notify.d.ts.map +1 -0
- package/build/components/login/notify.js +41 -0
- package/build/components/login/notify.js.map +1 -0
- package/build/components/login/provider.d.ts +20 -0
- package/build/components/login/provider.d.ts.map +1 -0
- package/build/components/login/provider.js +31 -0
- package/build/components/login/provider.js.map +1 -0
- package/build/components/login/screen.d.ts +24 -0
- package/build/components/login/screen.d.ts.map +1 -0
- package/build/components/login/screen.js +92 -0
- package/build/components/login/screen.js.map +1 -0
- package/build/components/login/terms.d.ts +19 -0
- package/build/components/login/terms.d.ts.map +1 -0
- package/build/components/login/terms.js +32 -0
- package/build/components/login/terms.js.map +1 -0
- package/build/components/login/types.d.ts +28 -0
- package/build/components/login/types.d.ts.map +1 -0
- package/build/components/login/types.js +2 -0
- package/build/components/login/types.js.map +1 -0
- package/build/components/nav/consts.local.d.ts +41 -0
- package/build/components/nav/consts.local.d.ts.map +1 -0
- package/build/components/nav/consts.local.js +60 -0
- package/build/components/nav/consts.local.js.map +1 -0
- package/build/components/nav/index.d.ts +1 -0
- package/build/components/nav/index.d.ts.map +1 -1
- package/build/components/nav/index.js +1 -0
- package/build/components/nav/index.js.map +1 -1
- package/build/components/nav/layout.d.ts +9 -2
- package/build/components/nav/layout.d.ts.map +1 -1
- package/build/components/nav/layout.js +48 -7
- package/build/components/nav/layout.js.map +1 -1
- package/build/components/nav/mobile.d.ts +21 -0
- package/build/components/nav/mobile.d.ts.map +1 -0
- package/build/components/nav/mobile.js +55 -0
- package/build/components/nav/mobile.js.map +1 -0
- package/build/components/nav/side.d.ts.map +1 -1
- package/build/components/nav/side.js +10 -10
- package/build/components/nav/side.js.map +1 -1
- package/build/components/nav/top.d.ts.map +1 -1
- package/build/components/nav/top.js +12 -8
- package/build/components/nav/top.js.map +1 -1
- package/build/components/nav/types.d.ts +64 -1
- package/build/components/nav/types.d.ts.map +1 -1
- package/build/components/nav/viewport.d.ts +3 -0
- package/build/components/nav/viewport.d.ts.map +1 -0
- package/build/components/nav/viewport.js +14 -0
- package/build/components/nav/viewport.js.map +1 -0
- package/build/components/panel-app/component.d.ts.map +1 -1
- package/build/components/panel-app/component.js +4 -3
- package/build/components/panel-app/component.js.map +1 -1
- package/build/components/picker/color-picker.d.ts +9 -0
- package/build/components/picker/color-picker.d.ts.map +1 -0
- package/build/components/picker/color-picker.js +9 -0
- package/build/components/picker/color-picker.js.map +1 -0
- package/build/components/picker/consts.local.d.ts +76 -0
- package/build/components/picker/consts.local.d.ts.map +1 -0
- package/build/components/picker/consts.local.js +214 -0
- package/build/components/picker/consts.local.js.map +1 -0
- package/build/components/picker/dot.d.ts +8 -0
- package/build/components/picker/dot.d.ts.map +1 -0
- package/build/components/picker/dot.js +10 -0
- package/build/components/picker/dot.js.map +1 -0
- package/build/components/picker/grid.d.ts +17 -0
- package/build/components/picker/grid.d.ts.map +1 -0
- package/build/components/picker/grid.js +73 -0
- package/build/components/picker/grid.js.map +1 -0
- package/build/components/picker/i18n/be.json +60 -0
- package/build/components/picker/i18n/de.json +60 -0
- package/build/components/picker/i18n/en.json +60 -0
- package/build/components/picker/i18n/es.json +60 -0
- package/build/components/picker/i18n/fr.json +60 -0
- package/build/components/picker/i18n/pl.json +60 -0
- package/build/components/picker/i18n/ru.json +60 -0
- package/build/components/picker/i18n/uk.json +60 -0
- package/build/components/picker/i18n.d.ts +2 -0
- package/build/components/picker/i18n.d.ts.map +1 -0
- package/build/components/picker/i18n.js +18 -0
- package/build/components/picker/i18n.js.map +1 -0
- package/build/components/picker/icon-color-picker.d.ts +14 -0
- package/build/components/picker/icon-color-picker.d.ts.map +1 -0
- package/build/components/picker/icon-color-picker.js +15 -0
- package/build/components/picker/icon-color-picker.js.map +1 -0
- package/build/components/picker/icon-picker.d.ts +8 -0
- package/build/components/picker/icon-picker.d.ts.map +1 -0
- package/build/components/picker/icon-picker.js +8 -0
- package/build/components/picker/icon-picker.js.map +1 -0
- package/build/components/picker/index.d.ts +11 -0
- package/build/components/picker/index.d.ts.map +1 -0
- package/build/components/picker/index.js +10 -0
- package/build/components/picker/index.js.map +1 -0
- package/build/components/picker/panel.d.ts +9 -0
- package/build/components/picker/panel.d.ts.map +1 -0
- package/build/components/picker/panel.js +23 -0
- package/build/components/picker/panel.js.map +1 -0
- package/build/components/picker/root.d.ts +13 -0
- package/build/components/picker/root.d.ts.map +1 -0
- package/build/components/picker/root.js +55 -0
- package/build/components/picker/root.js.map +1 -0
- package/build/components/picker/roving.d.ts +8 -0
- package/build/components/picker/roving.d.ts.map +1 -0
- package/build/components/picker/roving.js +62 -0
- package/build/components/picker/roving.js.map +1 -0
- package/build/components/picker/surface.d.ts +18 -0
- package/build/components/picker/surface.d.ts.map +1 -0
- package/build/components/picker/surface.js +36 -0
- package/build/components/picker/surface.js.map +1 -0
- package/build/components/picker/swatches/custom.d.ts +10 -0
- package/build/components/picker/swatches/custom.d.ts.map +1 -0
- package/build/components/picker/swatches/custom.js +65 -0
- package/build/components/picker/swatches/custom.js.map +1 -0
- package/build/components/picker/swatches.d.ts +16 -0
- package/build/components/picker/swatches.d.ts.map +1 -0
- package/build/components/picker/swatches.js +35 -0
- package/build/components/picker/swatches.js.map +1 -0
- package/build/components/picker/text.d.ts +5 -0
- package/build/components/picker/text.d.ts.map +1 -0
- package/build/components/picker/text.js +29 -0
- package/build/components/picker/text.js.map +1 -0
- package/build/components/picker/tile.d.ts +11 -0
- package/build/components/picker/tile.d.ts.map +1 -0
- package/build/components/picker/tile.js +19 -0
- package/build/components/picker/tile.js.map +1 -0
- package/build/components/picker/translate.d.ts +9 -0
- package/build/components/picker/translate.d.ts.map +1 -0
- package/build/components/picker/translate.js +13 -0
- package/build/components/picker/translate.js.map +1 -0
- package/build/components/picker/trigger.d.ts +12 -0
- package/build/components/picker/trigger.d.ts.map +1 -0
- package/build/components/picker/trigger.js +29 -0
- package/build/components/picker/trigger.js.map +1 -0
- package/build/components/picker/types.d.ts +114 -0
- package/build/components/picker/types.d.ts.map +1 -0
- package/build/components/picker/types.js +2 -0
- package/build/components/picker/types.js.map +1 -0
- package/build/components/picker/types.local.d.ts +143 -0
- package/build/components/picker/types.local.d.ts.map +1 -0
- package/build/components/picker/types.local.js +2 -0
- package/build/components/picker/types.local.js.map +1 -0
- package/build/components/scheme/consts.local.d.ts +8 -0
- package/build/components/scheme/consts.local.d.ts.map +1 -0
- package/build/components/scheme/consts.local.js +13 -0
- package/build/components/scheme/consts.local.js.map +1 -0
- package/build/components/scheme/hook.d.ts +16 -0
- package/build/components/scheme/hook.d.ts.map +1 -0
- package/build/components/scheme/hook.js +52 -0
- package/build/components/scheme/hook.js.map +1 -0
- package/build/components/scheme/index.d.ts +4 -0
- package/build/components/scheme/index.d.ts.map +1 -0
- package/build/components/scheme/index.js +3 -0
- package/build/components/scheme/index.js.map +1 -0
- package/build/components/scheme/toggle.d.ts +14 -0
- package/build/components/scheme/toggle.d.ts.map +1 -0
- package/build/components/scheme/toggle.js +24 -0
- package/build/components/scheme/toggle.js.map +1 -0
- package/build/components/scheme/types.d.ts +21 -0
- package/build/components/scheme/types.d.ts.map +1 -0
- package/build/components/scheme/types.js +2 -0
- package/build/components/scheme/types.js.map +1 -0
- package/build/components/socket/i18n/be.json +9 -0
- package/build/components/socket/i18n/de.json +9 -0
- package/build/components/socket/i18n/en.json +9 -0
- package/build/components/socket/i18n/es.json +9 -0
- package/build/components/socket/i18n/fr.json +9 -0
- package/build/components/socket/i18n/pl.json +9 -0
- package/build/components/socket/i18n/ru.json +9 -0
- package/build/components/socket/i18n/uk.json +9 -0
- package/build/components/socket/i18n.d.ts +2 -0
- package/build/components/socket/i18n.d.ts.map +1 -0
- package/build/components/socket/i18n.js +18 -0
- package/build/components/socket/i18n.js.map +1 -0
- package/build/components/socket/index.d.ts +3 -0
- package/build/components/socket/index.d.ts.map +1 -0
- package/build/components/socket/index.js +3 -0
- package/build/components/socket/index.js.map +1 -0
- package/build/components/socket/reload-dialog.d.ts +22 -0
- package/build/components/socket/reload-dialog.d.ts.map +1 -0
- package/build/components/socket/reload-dialog.js +34 -0
- package/build/components/socket/reload-dialog.js.map +1 -0
- package/build/components/status.js +1 -1
- package/build/components/status.js.map +1 -1
- package/build/components/text.d.ts.map +1 -1
- package/build/components/text.js +2 -13
- package/build/components/text.js.map +1 -1
- package/build/components/toaster.d.ts +16 -0
- package/build/components/toaster.d.ts.map +1 -0
- package/build/components/toaster.js +52 -0
- package/build/components/toaster.js.map +1 -0
- package/build/components/uploader/consts.local.d.ts +4 -0
- package/build/components/uploader/consts.local.d.ts.map +1 -0
- package/build/components/uploader/consts.local.js +6 -0
- package/build/components/uploader/consts.local.js.map +1 -0
- package/build/components/uploader/image.d.ts.map +1 -1
- package/build/components/uploader/image.js +2 -6
- package/build/components/uploader/image.js.map +1 -1
- package/build/consent/component.d.ts +27 -0
- package/build/consent/component.d.ts.map +1 -0
- package/build/consent/component.js +60 -0
- package/build/consent/component.js.map +1 -0
- package/build/consent/consts.d.ts +2 -0
- package/build/consent/consts.d.ts.map +1 -0
- package/build/consent/consts.js +2 -0
- package/build/consent/consts.js.map +1 -0
- package/build/consent/consts.local.d.ts +9 -0
- package/build/consent/consts.local.d.ts.map +1 -0
- package/build/consent/consts.local.js +9 -0
- package/build/consent/consts.local.js.map +1 -0
- package/build/consent/geo.d.ts +17 -0
- package/build/consent/geo.d.ts.map +1 -0
- package/build/consent/geo.js +19 -0
- package/build/consent/geo.js.map +1 -0
- package/build/consent/index.d.ts +11 -0
- package/build/consent/index.d.ts.map +1 -0
- package/build/consent/index.js +9 -0
- package/build/consent/index.js.map +1 -0
- package/build/consent/language.d.ts +12 -0
- package/build/consent/language.d.ts.map +1 -0
- package/build/consent/language.js +11 -0
- package/build/consent/language.js.map +1 -0
- package/build/consent/menu-widget.d.ts +13 -0
- package/build/consent/menu-widget.d.ts.map +1 -0
- package/build/consent/menu-widget.js +20 -0
- package/build/consent/menu-widget.js.map +1 -0
- package/build/consent/presence.d.ts +30 -0
- package/build/consent/presence.d.ts.map +1 -0
- package/build/consent/presence.js +40 -0
- package/build/consent/presence.js.map +1 -0
- package/build/consent/service.d.ts +18 -0
- package/build/consent/service.d.ts.map +1 -0
- package/build/consent/service.js +53 -0
- package/build/consent/service.js.map +1 -0
- package/build/consent/translate.d.ts +14 -0
- package/build/consent/translate.d.ts.map +1 -0
- package/build/consent/translate.js +28 -0
- package/build/consent/translate.js.map +1 -0
- package/build/consent/types.d.ts +39 -0
- package/build/consent/types.d.ts.map +1 -0
- package/build/consent/types.js +2 -0
- package/build/consent/types.js.map +1 -0
- package/build/consent/types.local.d.ts +6 -0
- package/build/consent/types.local.d.ts.map +1 -0
- package/build/consent/types.local.js +2 -0
- package/build/consent/types.local.js.map +1 -0
- package/build/context.d.ts.map +1 -1
- package/build/context.js +10 -0
- package/build/context.js.map +1 -1
- package/build/editor/component.d.ts +4 -0
- package/build/editor/component.d.ts.map +1 -0
- package/build/editor/component.js +103 -0
- package/build/editor/component.js.map +1 -0
- package/build/editor/consts.local.d.ts +6 -0
- package/build/editor/consts.local.d.ts.map +1 -0
- package/build/editor/consts.local.js +58 -0
- package/build/editor/consts.local.js.map +1 -0
- package/build/editor/index.d.ts +3 -0
- package/build/editor/index.d.ts.map +1 -0
- package/build/editor/index.js +2 -0
- package/build/editor/index.js.map +1 -0
- package/build/editor/types.d.ts +24 -0
- package/build/editor/types.d.ts.map +1 -0
- package/build/editor/types.js +2 -0
- package/build/editor/types.js.map +1 -0
- package/build/entrypoints.d.ts +8 -0
- package/build/entrypoints.d.ts.map +1 -0
- package/build/entrypoints.js +4 -0
- package/build/entrypoints.js.map +1 -0
- package/build/exports.d.ts +6 -5
- package/build/exports.d.ts.map +1 -1
- package/build/exports.js +5 -5
- package/build/exports.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/main.d.ts +1 -4
- package/build/main.d.ts.map +1 -1
- package/build/main.js.map +1 -1
- package/build/modules.d.ts +1 -1
- package/build/modules.d.ts.map +1 -1
- package/build/permission/i18n/be.json +13 -0
- package/build/permission/i18n/de.json +13 -0
- package/build/permission/i18n/en.json +13 -0
- package/build/permission/i18n/es.json +13 -0
- package/build/permission/i18n/fr.json +13 -0
- package/build/permission/i18n/pl.json +13 -0
- package/build/permission/i18n/ru.json +13 -0
- package/build/permission/i18n/uk.json +13 -0
- package/build/permission/i18n.d.ts +2 -0
- package/build/permission/i18n.d.ts.map +1 -0
- package/build/permission/i18n.js +13 -0
- package/build/permission/i18n.js.map +1 -0
- package/build/permission/index.d.ts +6 -0
- package/build/permission/index.d.ts.map +1 -0
- package/build/permission/index.js +27 -0
- package/build/permission/index.js.map +1 -0
- package/build/permission/toast.d.ts +5 -0
- package/build/permission/toast.d.ts.map +1 -0
- package/build/permission/toast.js +8 -0
- package/build/permission/toast.js.map +1 -0
- package/build/permission/types.d.ts +6 -0
- package/build/permission/types.d.ts.map +1 -0
- package/build/permission/types.js +2 -0
- package/build/permission/types.js.map +1 -0
- package/build/picker/icons/consts.d.ts +9 -0
- package/build/picker/icons/consts.d.ts.map +1 -0
- package/build/picker/icons/consts.js +264 -0
- package/build/picker/icons/consts.js.map +1 -0
- package/build/picker/icons/types.d.ts +18 -0
- package/build/picker/icons/types.d.ts.map +1 -0
- package/build/picker/icons/types.js +2 -0
- package/build/picker/icons/types.js.map +1 -0
- package/build/picker/icons.d.ts +4 -0
- package/build/picker/icons.d.ts.map +1 -0
- package/build/picker/icons.js +54 -0
- package/build/picker/icons.js.map +1 -0
- package/build/picker/index.d.ts +11 -0
- package/build/picker/index.d.ts.map +1 -0
- package/build/picker/index.js +10 -0
- package/build/picker/index.js.map +1 -0
- package/build/picker/utils/color/types.d.ts +35 -0
- package/build/picker/utils/color/types.d.ts.map +1 -0
- package/build/picker/utils/color/types.js +2 -0
- package/build/picker/utils/color/types.js.map +1 -0
- package/build/picker/utils/color.d.ts +4 -0
- package/build/picker/utils/color.d.ts.map +1 -0
- package/build/picker/utils/color.js +96 -0
- package/build/picker/utils/color.js.map +1 -0
- package/build/picker/vocabulary/consts.d.ts +26 -0
- package/build/picker/vocabulary/consts.d.ts.map +1 -0
- package/build/picker/vocabulary/consts.js +336 -0
- package/build/picker/vocabulary/consts.js.map +1 -0
- package/build/picker/vocabulary/types.d.ts +67 -0
- package/build/picker/vocabulary/types.d.ts.map +1 -0
- package/build/picker/vocabulary/types.js +2 -0
- package/build/picker/vocabulary/types.js.map +1 -0
- package/build/picker/vocabulary.d.ts +11 -0
- package/build/picker/vocabulary.d.ts.map +1 -0
- package/build/picker/vocabulary.js +83 -0
- package/build/picker/vocabulary.js.map +1 -0
- package/build/scheme/consts.d.ts +8 -0
- package/build/scheme/consts.d.ts.map +1 -0
- package/build/scheme/consts.js +8 -0
- package/build/scheme/consts.js.map +1 -0
- package/build/scheme/index.d.ts +4 -0
- package/build/scheme/index.d.ts.map +1 -0
- package/build/scheme/index.js +3 -0
- package/build/scheme/index.js.map +1 -0
- package/build/scheme/scheme.d.ts +16 -0
- package/build/scheme/scheme.d.ts.map +1 -0
- package/build/scheme/scheme.js +58 -0
- package/build/scheme/scheme.js.map +1 -0
- package/build/scheme/types.d.ts +30 -0
- package/build/scheme/types.d.ts.map +1 -0
- package/build/scheme/types.js +2 -0
- package/build/scheme/types.js.map +1 -0
- package/build/types.d.ts +18 -2
- package/build/types.d.ts.map +1 -1
- package/package.json +107 -52
- package/src/@/components/ui/alert-dialog.tsx +156 -0
- package/src/@/components/ui/alert.tsx +1 -1
- package/src/@/components/ui/button.tsx +1 -1
- package/src/@/components/ui/card.tsx +1 -1
- package/src/@/components/ui/input.tsx +1 -1
- package/src/@/components/ui/label.tsx +1 -1
- package/src/@/components/ui/navigation-menu.tsx +1 -1
- package/src/@/components/ui/popover.tsx +47 -0
- package/src/@/components/ui/progress.tsx +1 -1
- package/src/@/components/ui/separator.tsx +1 -1
- package/src/@/components/ui/sheet.tsx +142 -0
- package/src/auth/context.ts +0 -2
- package/src/auth/entrypoints.ts +5 -0
- package/src/auth/exports.ts +4 -4
- package/src/auth/plugins/basic-ed25519.tsx +4 -4
- package/src/auth/plugins/re-captcha.tsx +3 -3
- package/src/auth/plugins/tunnel-consumer.tsx +1 -1
- package/src/components/block.tsx +2 -2
- package/src/components/consts.local.ts +29 -0
- package/src/components/footer/component.tsx +58 -16
- package/src/components/footer/credit.tsx +61 -0
- package/src/components/footer/index.ts +1 -0
- package/src/components/footer/types.ts +22 -1
- package/src/components/form/button/component.tsx +7 -4
- package/src/components/form/component.tsx +2 -2
- package/src/components/form/text/component.tsx +2 -2
- package/src/components/helper.ts +1 -13
- package/src/components/index.ts +4 -0
- package/src/components/link.tsx +3 -3
- package/src/components/login/append.ts +34 -0
- package/src/components/login/consts.local.ts +10 -0
- package/src/components/login/consts.ts +2 -0
- package/src/components/login/credit.tsx +33 -0
- package/src/components/login/i18n/be.json +10 -0
- package/src/components/login/i18n/de.json +10 -0
- package/src/components/login/i18n/en.json +10 -0
- package/src/components/login/i18n/es.json +10 -0
- package/src/components/login/i18n/fr.json +10 -0
- package/src/components/login/i18n/pl.json +10 -0
- package/src/components/login/i18n/ru.json +10 -0
- package/src/components/login/i18n/uk.json +10 -0
- package/src/components/login/i18n.ts +29 -0
- package/src/components/login/icons.tsx +39 -0
- package/src/components/login/index.ts +11 -0
- package/src/components/login/notify.ts +48 -0
- package/src/components/login/provider.tsx +57 -0
- package/src/components/login/screen.tsx +178 -0
- package/src/components/login/terms.tsx +75 -0
- package/src/components/login/types.ts +30 -0
- package/src/components/nav/consts.local.ts +64 -0
- package/src/components/nav/index.ts +1 -0
- package/src/components/nav/layout.tsx +184 -26
- package/src/components/nav/mobile.tsx +165 -0
- package/src/components/nav/side.tsx +43 -27
- package/src/components/nav/top.tsx +44 -22
- package/src/components/nav/types.ts +65 -2
- package/src/components/nav/viewport.ts +16 -0
- package/src/components/panel-app/component.tsx +9 -1
- package/src/components/picker/color-picker.tsx +15 -0
- package/src/components/picker/consts.local.ts +267 -0
- package/src/components/picker/dot.tsx +21 -0
- package/src/components/picker/grid.tsx +138 -0
- package/src/components/picker/i18n/be.json +60 -0
- package/src/components/picker/i18n/de.json +60 -0
- package/src/components/picker/i18n/en.json +60 -0
- package/src/components/picker/i18n/es.json +60 -0
- package/src/components/picker/i18n/fr.json +60 -0
- package/src/components/picker/i18n/pl.json +60 -0
- package/src/components/picker/i18n/ru.json +60 -0
- package/src/components/picker/i18n/uk.json +60 -0
- package/src/components/picker/i18n.ts +19 -0
- package/src/components/picker/icon-color-picker.tsx +25 -0
- package/src/components/picker/icon-picker.tsx +13 -0
- package/src/components/picker/index.ts +11 -0
- package/src/components/picker/panel.tsx +61 -0
- package/src/components/picker/root.tsx +81 -0
- package/src/components/picker/roving.ts +70 -0
- package/src/components/picker/surface.tsx +62 -0
- package/src/components/picker/swatches/custom.tsx +110 -0
- package/src/components/picker/swatches.tsx +67 -0
- package/src/components/picker/text.ts +46 -0
- package/src/components/picker/tile.tsx +35 -0
- package/src/components/picker/translate.ts +15 -0
- package/src/components/picker/trigger.tsx +54 -0
- package/src/components/picker/types.local.ts +154 -0
- package/src/components/picker/types.ts +125 -0
- package/src/components/scheme/consts.local.ts +13 -0
- package/src/components/scheme/hook.ts +62 -0
- package/src/components/scheme/index.ts +4 -0
- package/src/components/scheme/toggle.tsx +32 -0
- package/src/components/scheme/types.ts +23 -0
- package/src/components/socket/i18n/be.json +9 -0
- package/src/components/socket/i18n/de.json +9 -0
- package/src/components/socket/i18n/en.json +9 -0
- package/src/components/socket/i18n/es.json +9 -0
- package/src/components/socket/i18n/fr.json +9 -0
- package/src/components/socket/i18n/pl.json +9 -0
- package/src/components/socket/i18n/ru.json +9 -0
- package/src/components/socket/i18n/uk.json +9 -0
- package/src/components/socket/i18n.ts +19 -0
- package/src/components/socket/index.ts +2 -0
- package/src/components/socket/reload-dialog.tsx +61 -0
- package/src/components/status.tsx +1 -1
- package/src/components/text.tsx +2 -14
- package/src/components/toaster.tsx +65 -0
- package/src/components/uploader/consts.local.ts +7 -0
- package/src/components/uploader/image.tsx +2 -6
- package/src/consent/component.tsx +84 -0
- package/src/consent/consts.local.ts +10 -0
- package/src/consent/consts.ts +1 -0
- package/src/consent/geo.ts +26 -0
- package/src/consent/index.ts +24 -0
- package/src/consent/language.ts +12 -0
- package/src/consent/menu-widget.tsx +22 -0
- package/src/consent/presence.ts +45 -0
- package/src/consent/service.ts +75 -0
- package/src/consent/translate.ts +31 -0
- package/src/consent/types.local.ts +6 -0
- package/src/consent/types.ts +43 -0
- package/src/context.ts +12 -0
- package/src/editor/component.tsx +172 -0
- package/src/editor/consts.local.ts +62 -0
- package/src/editor/index.ts +2 -0
- package/src/editor/types.ts +24 -0
- package/src/entrypoints.ts +5 -0
- package/src/exports.ts +6 -5
- package/src/index.ts +1 -1
- package/src/main.tsx +2 -6
- package/src/permission/i18n/be.json +13 -0
- package/src/permission/i18n/de.json +13 -0
- package/src/permission/i18n/en.json +13 -0
- package/src/permission/i18n/es.json +13 -0
- package/src/permission/i18n/fr.json +13 -0
- package/src/permission/i18n/pl.json +13 -0
- package/src/permission/i18n/ru.json +13 -0
- package/src/permission/i18n/uk.json +13 -0
- package/src/permission/i18n.ts +13 -0
- package/src/permission/index.ts +27 -0
- package/src/permission/toast.tsx +20 -0
- package/src/permission/types.ts +5 -0
- package/src/picker/icons/consts.ts +309 -0
- package/src/picker/icons/types.ts +18 -0
- package/src/picker/icons.ts +70 -0
- package/src/picker/index.ts +11 -0
- package/src/picker/utils/color/types.ts +37 -0
- package/src/picker/utils/color.ts +119 -0
- package/src/picker/vocabulary/consts.ts +347 -0
- package/src/picker/vocabulary/types.ts +72 -0
- package/src/picker/vocabulary.ts +111 -0
- package/src/scheme/consts.ts +8 -0
- package/src/scheme/index.ts +3 -0
- package/src/scheme/scheme.ts +66 -0
- package/src/scheme/types.ts +30 -0
- package/src/types.ts +19 -2
- package/tests/consent-language.spec.ts +31 -0
- package/tests/consent.spec.ts +112 -0
- package/tests/context.ts +4 -0
- package/tests/editor.spec.ts +58 -0
- package/tests/harness/editor.tsx +32 -0
- package/tests/harness/index.html +1 -0
- package/tests/harness/lazy-screen.tsx +9 -0
- package/tests/harness/mount.tsx +370 -29
- package/tests/harness/picker.tsx +110 -0
- package/tests/lazy.spec.ts +104 -0
- package/tests/login-provider.spec.ts +114 -0
- package/tests/login.spec.ts +447 -0
- package/tests/nav.spec.ts +449 -3
- package/tests/package-boundary.spec.ts +19 -0
- package/tests/picker-shots.spec.ts +174 -0
- package/tests/picker-vocabulary.spec.ts +217 -0
- package/tests/picker.spec.ts +333 -0
- package/tests/scheme.spec.ts +149 -0
- package/tests/smoke.spec.ts +2 -2
- package/tests/socket-dialog.spec.ts +154 -0
- package/tests/toaster.spec.ts +59 -0
- package/zz-tw.d.mts +2 -0
- package/zz-tw.d.mts.map +1 -0
- package/build/.gitkeep +0 -0
- package/src/auth/modules.ts +0 -5
- package/src/modules.ts +0 -5
package/tests/harness/mount.tsx
CHANGED
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
import '../../src/@/globals.css'
|
|
2
2
|
|
|
3
3
|
import type { FC, PropsWithChildren } from 'react'
|
|
4
|
+
import { useState } from 'react'
|
|
4
5
|
import { createRoot } from 'react-dom/client'
|
|
5
6
|
import { config } from '@owlmeans/client-context'
|
|
6
7
|
import { AppType, service } from '@owlmeans/config'
|
|
7
8
|
import { BASE, HOME } from '@owlmeans/context'
|
|
8
|
-
import {
|
|
9
|
+
import { bindScreen } from '@owlmeans/client-entrypoint'
|
|
10
|
+
import { openProtocol } from '@owlmeans/entrypoint'
|
|
9
11
|
import { frontend, route } from '@owlmeans/route'
|
|
10
12
|
import { handler, useNavigate } from '@owlmeans/client'
|
|
13
|
+
import { toast } from 'sonner'
|
|
11
14
|
import type { PanelNavConfig, PanelNavLink } from '../../src/index.js'
|
|
12
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
makeContext, useContext, entrypoints as baseEntrypoints, NavLayout, PanelApp, Toaster,
|
|
17
|
+
lazyHandler, lazyComponent,
|
|
18
|
+
} from '../../src/index.js'
|
|
19
|
+
import { LoginScreen } from '../../src/components/login/index.js'
|
|
20
|
+
import {
|
|
21
|
+
PanelCookieConsent, PanelConsentMenuWidget, appendConsentWidgetService, useConsentMenuPresence,
|
|
22
|
+
appendConsentGeoPlugin,
|
|
23
|
+
} from '../../src/consent/index.js'
|
|
24
|
+
import { LoginOutcome, ensureLoginService } from '@owlmeans/client-auth/login'
|
|
25
|
+
import type { LoginMethod } from '@owlmeans/client-auth/login'
|
|
26
|
+
import { EditorHarness } from './editor.js'
|
|
27
|
+
import { PickerScreen, TranslatedPickerScreen } from './picker.js'
|
|
13
28
|
|
|
14
29
|
// A real app: a context, a layout entrypoint rendering NavLayout, and screens under it.
|
|
15
30
|
// The nav model resolves the active screen from the router, so nothing here may be faked.
|
|
@@ -22,42 +37,219 @@ const alias = {
|
|
|
22
37
|
reports: `${SERVICE}:web:reports`,
|
|
23
38
|
reportsIndex: `${SERVICE}:web:reports-index`,
|
|
24
39
|
reportDetail: `${SERVICE}:web:report-detail`,
|
|
40
|
+
reportSibling: `${SERVICE}:web:report-sibling`,
|
|
25
41
|
prefs: `${SERVICE}:web:prefs`,
|
|
42
|
+
login: `${SERVICE}:web:login`,
|
|
43
|
+
socket: `${SERVICE}:web:socket`,
|
|
44
|
+
lazy: `${SERVICE}:web:lazy`,
|
|
45
|
+
lazyEntry: `${SERVICE}:web:lazy-entry`,
|
|
46
|
+
picker: `${SERVICE}:web:picker`,
|
|
26
47
|
}
|
|
27
48
|
|
|
49
|
+
/** A harness id for the ONE tracked connection this screen simulates — a real `ws()`/`useWs()`
|
|
50
|
+
* connection would generate its own, but the status service only cares that it is stable across
|
|
51
|
+
* the two buttons below. */
|
|
52
|
+
const HARNESS_SOCKET_ID = 'harness-socket'
|
|
53
|
+
|
|
28
54
|
const navConfig: PanelNavConfig = {
|
|
29
55
|
sections: [
|
|
30
56
|
// Two screens — the side menu shows.
|
|
31
57
|
{
|
|
32
58
|
name: 'work', label: 'Work', items: [
|
|
33
|
-
{ alias: alias.dash, label: 'Dashboard' },
|
|
59
|
+
{ alias: alias.dash, label: 'Dashboard', testId: 'dashboard-nav' },
|
|
34
60
|
{ alias: alias.reports, label: 'Reports' },
|
|
35
61
|
]
|
|
36
62
|
},
|
|
37
63
|
// One screen — the side menu must not render at all.
|
|
38
|
-
{ name: 'settings', label: 'Settings', items: [{ alias: alias.prefs, label: 'Preferences' }] },
|
|
64
|
+
{ name: 'settings', label: 'Settings', testId: 'settings-nav', items: [{ alias: alias.prefs, label: 'Preferences' }] },
|
|
39
65
|
// No literal labels: exercises the humanized-alias fallback with no i18n present.
|
|
40
66
|
{ name: 'extra', items: [{ alias: HOME }] },
|
|
41
67
|
],
|
|
42
68
|
}
|
|
43
69
|
|
|
44
70
|
const footerLinks: PanelNavLink[] = [
|
|
45
|
-
{ alias: alias.dash, label: 'Dashboard' },
|
|
71
|
+
{ alias: alias.dash, label: 'Dashboard', testId: 'dashboard-nav' },
|
|
46
72
|
{ href: 'https://owlmeans.com', label: 'OwlMeans', open: true },
|
|
47
73
|
]
|
|
48
74
|
|
|
49
75
|
const screen = (id: string, text: string): FC => () => <div id={id}>{text}</div>
|
|
50
76
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
77
|
+
/**
|
|
78
|
+
* What the sign-in screen offers in the harness.
|
|
79
|
+
*
|
|
80
|
+
* Real methods, with real `start` handlers that record they were called — the one thing the
|
|
81
|
+
* screen must never do is start one on its own, and a method that only pretended to start could
|
|
82
|
+
* not prove it.
|
|
83
|
+
*/
|
|
84
|
+
const started: string[] = []
|
|
85
|
+
;(globalThis as unknown as { __loginStarted: string[] }).__loginStarted = started
|
|
86
|
+
|
|
87
|
+
const method = (id: string, over?: Partial<LoginMethod>): LoginMethod => ({
|
|
88
|
+
id,
|
|
89
|
+
order: 10,
|
|
90
|
+
start: async () => { started.push(id); return LoginOutcome.Handled },
|
|
91
|
+
...over,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
/** The sign-in screen, with the terms confirmation the configuration requires. */
|
|
95
|
+
const LoginHarness: FC = () => {
|
|
96
|
+
const [locale, setLocale] = useState<string | undefined>(localizedTerms ? 'pl' : undefined)
|
|
97
|
+
|
|
98
|
+
return <>
|
|
99
|
+
{localizedTerms && <button id="login-language-fr" onClick={() => setLocale('fr')}>Français</button>}
|
|
100
|
+
<LoginScreen
|
|
101
|
+
Logo={() => <span id="login-logo">logo</span>}
|
|
102
|
+
translate={(_key, defaultValue) => defaultValue}
|
|
103
|
+
locale={locale}
|
|
104
|
+
/>
|
|
105
|
+
</>
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// `?header=broken` simulates the layout-restyle bug this harness pins: a `headerClassName`
|
|
109
|
+
// carrying an invalid Tailwind v4 arbitrary-value background (v3 syntax, silently dropped) and a
|
|
110
|
+
// bare `bg-transparent`, either of which used to leave the sticky header with no background paint
|
|
111
|
+
// of its own at all. One harness process serves both branches, exactly like `reloadDialog` above.
|
|
112
|
+
const brokenHeader = new URLSearchParams(window.location.search).get('header') === 'broken'
|
|
113
|
+
// `?footer=none` omits the `footer` prop entirely — the shape every area layout had before the
|
|
114
|
+
// shell grew a footer-links convention. `NavLayout` must still render the credit line then.
|
|
115
|
+
const noFooterProp = new URLSearchParams(window.location.search).get('footer') === 'none'
|
|
116
|
+
// `?footer=node` hands `NavLayout` a NODE footer — an application's own footer layout (a brand
|
|
117
|
+
// block and a Legal column), the shape a generated app's footer takes — instead of links.
|
|
118
|
+
const nodeFooter = new URLSearchParams(window.location.search).get('footer') === 'node'
|
|
119
|
+
// `?mobileMenu=1` opts into the narrow-viewport menu sheet. Absent, the prop is not passed at
|
|
120
|
+
// all — the shape every existing layout has — and the shell must render exactly what it always did.
|
|
121
|
+
const mobileMenu = new URLSearchParams(window.location.search).get('mobileMenu') === '1'
|
|
122
|
+
// `?consent=bare` mounts `PanelCookieConsent` on a context that never appended the presence
|
|
123
|
+
// service — an application using the dialog on its own. `?consent=menu` appends the service, so
|
|
124
|
+
// the footer's "Cookie settings" control takes over the floating button's job.
|
|
125
|
+
const consentMode = new URLSearchParams(window.location.search).get('consent')
|
|
126
|
+
// `?consentCfg=window|bar` sets `cfg.cookieConsent.mode`; `?modeProp=bar|window` passes `mode` as a
|
|
127
|
+
// prop on top of it (the prop must win). `?consentGeo=<CC>|fail` appends a context-level locator
|
|
128
|
+
// with `appendConsentGeoPlugin` — the gate turns on with no `geo` configured anywhere.
|
|
129
|
+
const consentCfg = new URLSearchParams(window.location.search).get('consentCfg')
|
|
130
|
+
const modeProp = new URLSearchParams(window.location.search).get('modeProp')
|
|
131
|
+
const consentGeo = new URLSearchParams(window.location.search).get('consentGeo')
|
|
132
|
+
// `?skip=off` passes `skipLinkLabel={false}` — an application that renders its own skip link.
|
|
133
|
+
const skipOff = new URLSearchParams(window.location.search).get('skip') === 'off'
|
|
134
|
+
// `?themeToggle=1` asks for the footer's light/dark switcher. Absent, the prop is not passed.
|
|
135
|
+
const themeToggle = new URLSearchParams(window.location.search).get('themeToggle') === '1'
|
|
136
|
+
// `?terms=extended` adds billing/product/custom documents and a revision date to the terms
|
|
137
|
+
// confirmation — the shape that pins the "still exactly one checkbox" and "documents render
|
|
138
|
+
// outside the notice" rules even when there is more than terms+privacy to show.
|
|
139
|
+
const extendedTerms = new URLSearchParams(window.location.search).get('terms') === 'extended'
|
|
140
|
+
// `?terms=localized` selects known translated destinations using the live screen locale.
|
|
141
|
+
const localizedTerms = new URLSearchParams(window.location.search).get('terms') === 'localized'
|
|
142
|
+
// `?defer=bound` registers a step that CONFIRMS the terms, bound to a real screen — the sign-in
|
|
143
|
+
// screen must then show no checkbox, only the privacy notice, and block nothing.
|
|
144
|
+
// `?defer=unbound` registers the same step but never binds its entrypoint — the checkbox must
|
|
145
|
+
// stay (fail-closed): a step nobody can reach must never silently remove the confirmation.
|
|
146
|
+
const defer = new URLSearchParams(window.location.search).get('defer')
|
|
147
|
+
// `?domains=1` passes `linker` through to `PanelCookieConsent` — proving the prop reaches
|
|
148
|
+
// `@owlmeans/web-consent`'s `CookieConsent` with nothing lost in between (the props already just
|
|
149
|
+
// spread through; this is what pins that they keep doing so).
|
|
150
|
+
const withDomains = new URLSearchParams(window.location.search).get('domains') === '1'
|
|
151
|
+
// `?provider=top|inline` configures who signs the person in — the disclosure a platform-hosted
|
|
152
|
+
// app shows. A product name is set only then, so every other screen keeps the brand it always had.
|
|
153
|
+
const providerPlacement = new URLSearchParams(window.location.search).get('provider')
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The footer's "Cookie settings" control — the menu widget, rendered from an always-mounted
|
|
157
|
+
* component that also declares the presence, exactly as the `./consent` rules ask.
|
|
158
|
+
*/
|
|
159
|
+
const CookieSettings: FC = () => {
|
|
160
|
+
useConsentMenuPresence()
|
|
161
|
+
|
|
162
|
+
return <PanelConsentMenuWidget label="Cookie settings" className="w-auto" />
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const FooterBlock: FC = () => <div id="footer-block" className="flex flex-wrap justify-between gap-8">
|
|
166
|
+
<div>
|
|
167
|
+
<strong>Harness</strong>
|
|
168
|
+
<p>One line about what the harness does.</p>
|
|
169
|
+
</div>
|
|
170
|
+
<nav aria-label="Legal">
|
|
171
|
+
<p>Legal</p>
|
|
172
|
+
<ul>
|
|
173
|
+
<li><a href="/privacy">Privacy</a></li>
|
|
174
|
+
<li><a href="/terms">Terms</a></li>
|
|
175
|
+
{consentMode != null && <li><CookieSettings /></li>}
|
|
176
|
+
</ul>
|
|
177
|
+
</nav>
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
// `/picker` is a page of its own — no shell around it, so its screenshots show the picker alone.
|
|
181
|
+
const pickerPage = window.location.pathname.startsWith('/picker')
|
|
182
|
+
// `/picker?bare=1` is mounted with no `PanelApp` and no i18n instance at all — the parts must render.
|
|
183
|
+
const pickerBare = pickerPage && new URLSearchParams(window.location.search).get('bare') === '1'
|
|
184
|
+
|
|
185
|
+
const Layout: FC<PropsWithChildren> = ({ children }) => pickerPage ? <>{children}</> : <>
|
|
186
|
+
<NavLayout
|
|
187
|
+
nav={navConfig}
|
|
188
|
+
navTestId="harness-nav"
|
|
189
|
+
title="Harness"
|
|
190
|
+
actions={<button id="action-slot">action</button>}
|
|
191
|
+
{...(noFooterProp ? {} : { footer: nodeFooter ? <FooterBlock /> : footerLinks })}
|
|
192
|
+
{...(mobileMenu ? { mobileMenu: true } : {})}
|
|
193
|
+
{...(skipOff ? { skipLinkLabel: false as const } : {})}
|
|
194
|
+
{...(themeToggle ? { themeToggle: true } : {})}
|
|
195
|
+
// A DARK APPLICATION SHELL, which is what a themed app does to the root: a contrasting
|
|
196
|
+
// surface pair, both halves correct. The header paints its own opaque background, so it is
|
|
197
|
+
// a different surface, and everything in it must stay legible against `--background`
|
|
198
|
+
// rather than against this. The harness carries it permanently so every navigation test
|
|
199
|
+
// runs against the hostile case instead of a default-coloured page.
|
|
200
|
+
className="bg-primary text-primary-foreground"
|
|
201
|
+
// A WIDTH-ONLY rhythm override, which is what a design pass writes when it wants a wider
|
|
202
|
+
// page. It names the width and nothing else, so the centring and the side padding must
|
|
203
|
+
// survive it — substituting this for the default is a page running flush to the window edge.
|
|
204
|
+
containerClassName="max-w-[1280px]"
|
|
205
|
+
{...(brokenHeader ? { headerClassName: 'bg-[--nope] bg-transparent' } : {})}
|
|
206
|
+
>{children}</NavLayout>
|
|
207
|
+
{/* Mounted ONCE, in the layout — exactly where an application mounts it. */}
|
|
208
|
+
<Toaster />
|
|
209
|
+
</>
|
|
210
|
+
|
|
211
|
+
/** The toast surface's exercise: a screen action that reports its outcome. */
|
|
212
|
+
const PrefsScreen: FC = () => <div id="prefs">
|
|
213
|
+
prefs-screen
|
|
214
|
+
<button id="fire-toast" onClick={() => toast.success('preferences saved')}>save</button>
|
|
215
|
+
{/* Outlives any assertion — a theme check must not race the 5s default dismissal. */}
|
|
216
|
+
<button id="fire-sticky" onClick={() => toast.error('sticky failure', { duration: 600_000 })}>fail</button>
|
|
217
|
+
</div>
|
|
57
218
|
|
|
58
219
|
/** A grouping screen — it renders whichever child the router matched. */
|
|
59
220
|
const ReportsGroup: FC<PropsWithChildren> = ({ children }) => <div id="reports-group">{children}</div>
|
|
60
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Drives the SAME status service `SocketReloadDialog` reads, exactly the way a real dropped
|
|
224
|
+
* `ws()`/`useWs()` connection would — through `report()`/`release()`, never a prop the dialog
|
|
225
|
+
* itself exposes, since it has none: the whole point is that any socket, anywhere in the app,
|
|
226
|
+
* can put the dialog up.
|
|
227
|
+
*/
|
|
228
|
+
const SocketStatusScreen: FC = () => {
|
|
229
|
+
const context = useContext()
|
|
230
|
+
// A revive the way a real carrier's goes: the connection is retrying again the moment it is
|
|
231
|
+
// asked to. How that retry ends is up to the test — `#report-online` or `#report-lost`.
|
|
232
|
+
const [revived, setRevived] = useState(0)
|
|
233
|
+
const reportLost = () => context.socketStatus().report(HARNESS_SOCKET_ID, 'lost', () => {
|
|
234
|
+
setRevived(n => n + 1)
|
|
235
|
+
context.socketStatus().report(HARNESS_SOCKET_ID, 'reconnecting')
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
return <div id="socket-status">
|
|
239
|
+
socket-status-screen
|
|
240
|
+
<span id="revived">{revived}</span>
|
|
241
|
+
<button id="report-lost" onClick={reportLost}>
|
|
242
|
+
lose connection
|
|
243
|
+
</button>
|
|
244
|
+
<button id="report-online" onClick={() => context.socketStatus().report(HARNESS_SOCKET_ID, 'online')}>
|
|
245
|
+
reconnected
|
|
246
|
+
</button>
|
|
247
|
+
<button id="release-lost" onClick={() => context.socketStatus().release(HARNESS_SOCKET_ID)}>
|
|
248
|
+
restore connection
|
|
249
|
+
</button>
|
|
250
|
+
</div>
|
|
251
|
+
}
|
|
252
|
+
|
|
61
253
|
/**
|
|
62
254
|
* The section's landing screen. Its button navigates to a screen the MENU DOES NOT LIST,
|
|
63
255
|
* which is the only way to exercise the parent-chain walk: an in-app navigation puts the
|
|
@@ -69,6 +261,38 @@ const ReportsIndex: FC = () => {
|
|
|
69
261
|
return <div id="reports">
|
|
70
262
|
reports-screen
|
|
71
263
|
<button id="to-detail" onClick={nav.press(alias.reportDetail)}>detail</button>
|
|
264
|
+
<button id="to-sibling" onClick={nav.press(alias.reportSibling)}>sibling detail</button>
|
|
265
|
+
</div>
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Lazily-loaded screens, declared at MODULE SCOPE as the helpers require — the route renderer
|
|
270
|
+
* remounts a screen on every navigation, so a lazy object made during render would re-suspend
|
|
271
|
+
* each time. Both go through the package root, which is what an application imports.
|
|
272
|
+
*
|
|
273
|
+
* `flakyScreen` fails its first load on purpose: a rejected load must be retried, never cached.
|
|
274
|
+
* The globals let a spec drive `preload()` without a screen of its own.
|
|
275
|
+
*/
|
|
276
|
+
let flakyLoads = 0
|
|
277
|
+
const lazyScreen = lazyHandler(
|
|
278
|
+
() => import('./lazy-screen.js'), 'LazyScreen', { fallback: <div id="lazy-fallback">loading</div> }
|
|
279
|
+
)
|
|
280
|
+
const flakyScreen = lazyComponent(async () => {
|
|
281
|
+
if (++flakyLoads === 1) throw new Error('first-load-fails')
|
|
282
|
+
return import('./lazy-screen.js')
|
|
283
|
+
}, 'LazyScreen')
|
|
284
|
+
;(globalThis as unknown as { __lazyPreload: () => Promise<boolean> }).__lazyPreload =
|
|
285
|
+
async () => typeof await lazyScreen.preload() === 'function'
|
|
286
|
+
;(globalThis as unknown as { __flakyPreload: () => Promise<string> }).__flakyPreload =
|
|
287
|
+
() => flakyScreen.preload().then(() => 'loaded', (e: Error) => e.message)
|
|
288
|
+
|
|
289
|
+
/** The lazy screen's way in: an in-app navigation, so the layout around it is already mounted. */
|
|
290
|
+
const LazyEntry: FC = () => {
|
|
291
|
+
const nav = useNavigate()
|
|
292
|
+
|
|
293
|
+
return <div id="lazy-entry">
|
|
294
|
+
lazy-entry-screen
|
|
295
|
+
<button id="to-lazy" onClick={nav.press(alias.lazy)}>lazy</button>
|
|
72
296
|
</div>
|
|
73
297
|
}
|
|
74
298
|
|
|
@@ -77,7 +301,55 @@ const ReportsIndex: FC = () => {
|
|
|
77
301
|
// sides are declared here exactly as a real app declares them.
|
|
78
302
|
const base = service({ type: AppType.Frontend, service: SERVICE, host: 'localhost', port: 5173 })
|
|
79
303
|
service({ type: AppType.Backend, service: API, host: 'localhost', port: 5174, base: 'api' }, base)
|
|
80
|
-
base.security = {
|
|
304
|
+
base.security = {
|
|
305
|
+
unsecure: true,
|
|
306
|
+
auth: {
|
|
307
|
+
login: {
|
|
308
|
+
// Confirmation required, which is the case that matters: a method must be blocked until it
|
|
309
|
+
// is given, and blocking must SAY so rather than swallow the click.
|
|
310
|
+
terms: {
|
|
311
|
+
required: true, terms: 'https://example.test/terms', privacy: 'https://example.test/privacy',
|
|
312
|
+
...(localizedTerms ? {
|
|
313
|
+
billing: { href: 'https://example.test/billing', revisedAt: '2026-10-04' },
|
|
314
|
+
cookies: 'https://example.test/cookies', showRevision: true,
|
|
315
|
+
localizedHrefs: {
|
|
316
|
+
terms: { pl: 'https://example.test/pl/terms', fr: 'https://example.test/fr/terms' },
|
|
317
|
+
billing: { pl: 'https://example.test/pl/billing', fr: 'https://example.test/fr/billing' },
|
|
318
|
+
privacy: { pl: 'https://example.test/pl/privacy', fr: 'https://example.test/fr/privacy' },
|
|
319
|
+
cookies: { pl: 'https://example.test/pl/cookies', fr: 'https://example.test/fr/cookies' },
|
|
320
|
+
},
|
|
321
|
+
} : {}),
|
|
322
|
+
...(extendedTerms ? {
|
|
323
|
+
billing: { href: 'https://example.test/billing', revisedAt: '2026-01-01' },
|
|
324
|
+
product: { name: 'Harness', href: 'https://example.test/product' },
|
|
325
|
+
documents: [
|
|
326
|
+
{ key: 'custom-a', href: 'https://example.test/custom-a', label: 'Custom A' },
|
|
327
|
+
{ key: 'custom-b', href: 'https://example.test/custom-b', label: 'Custom B' },
|
|
328
|
+
],
|
|
329
|
+
showRevision: true,
|
|
330
|
+
} : {}),
|
|
331
|
+
},
|
|
332
|
+
credit: { poweredBy: true, product: 'Harness', organization: 'Acme' },
|
|
333
|
+
...(providerPlacement === 'top' || providerPlacement === 'inline' ? {
|
|
334
|
+
provider: {
|
|
335
|
+
name: 'Harness IAM', operator: 'Harness Hosting', info: 'https://example.test/about',
|
|
336
|
+
placement: providerPlacement,
|
|
337
|
+
},
|
|
338
|
+
} : {}),
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
}
|
|
342
|
+
if (providerPlacement != null) {
|
|
343
|
+
base.brand = { ...base.brand, name: 'Harness App' }
|
|
344
|
+
}
|
|
345
|
+
// Every other screen in this harness stays unaffected: nothing ever reports into the status
|
|
346
|
+
// service unless `#report-lost` is clicked, so the flag being on by default costs nothing. A
|
|
347
|
+
// test that needs the OFF case loads `?reloadDialog=0` — one harness process, both branches.
|
|
348
|
+
const reloadDialogEnabled = new URLSearchParams(window.location.search).get('reloadDialog') !== '0'
|
|
349
|
+
;(base as { socket?: { reloadDialog?: boolean } }).socket = { reloadDialog: reloadDialogEnabled }
|
|
350
|
+
if (consentCfg === 'window' || consentCfg === 'bar') {
|
|
351
|
+
;(base as { cookieConsent?: { mode: 'window' | 'bar' } }).cookieConsent = { mode: consentCfg }
|
|
352
|
+
}
|
|
81
353
|
|
|
82
354
|
// `ready` stays false: the Router compiles the entrypoint tree into routes ONLY while the
|
|
83
355
|
// context is un-initialized, so a pre-readied context renders a blank page.
|
|
@@ -85,29 +357,98 @@ const cfg = config(SERVICE, base as never)
|
|
|
85
357
|
const context = makeContext(cfg as never)
|
|
86
358
|
context.serviceRoute(SERVICE, true)
|
|
87
359
|
context.serviceRoute(API, true)
|
|
360
|
+
if (consentMode === 'menu') {
|
|
361
|
+
appendConsentWidgetService(context as never)
|
|
362
|
+
}
|
|
363
|
+
if (consentGeo != null) {
|
|
364
|
+
appendConsentGeoPlugin(context as never, {
|
|
365
|
+
alias: 'harness-geo',
|
|
366
|
+
locate: async () => {
|
|
367
|
+
if (consentGeo === 'fail') {
|
|
368
|
+
throw new Error('the harness locator cannot tell')
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return { country: consentGeo }
|
|
372
|
+
},
|
|
373
|
+
})
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
ensureLoginService(context as never).registerMethodSource({
|
|
377
|
+
alias: 'harness',
|
|
378
|
+
list: () => [
|
|
379
|
+
method('primary', { emphasis: 'primary', icon: 'google', label: 'Continue with Google' }),
|
|
380
|
+
// A method that finishes without moving the document — the shape of a relying party that
|
|
381
|
+
// could not build an authorization URL. The screen must SAY so; silence reads as a dead
|
|
382
|
+
// button, which is exactly the bug this pins.
|
|
383
|
+
method('secondary', {
|
|
384
|
+
order: 20, label: 'Sign in with a key',
|
|
385
|
+
start: async () => { started.push('secondary'); return LoginOutcome.Passed },
|
|
386
|
+
}),
|
|
387
|
+
method('operator', { order: 900, restricted: true, label: 'Secret key' }),
|
|
388
|
+
],
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
if (defer != null) {
|
|
392
|
+
ensureLoginService(context as never).registerStep({
|
|
393
|
+
alias: 'harness-terms-step',
|
|
394
|
+
// "bound" points at a real screen of this harness (`/prefs`, already registered below) —
|
|
395
|
+
// `termsDeferred` only reads `ctx.hasEntrypoint`, so any bound alias proves the point.
|
|
396
|
+
// "unbound" points nowhere: `hasEntrypoint` answers false and the step stays unreachable.
|
|
397
|
+
entrypoint: defer === 'bound' ? alias.prefs : 'harness-terms-step-nowhere',
|
|
398
|
+
confirmsTerms: true,
|
|
399
|
+
required: true,
|
|
400
|
+
pending: async () => false,
|
|
401
|
+
})
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const protocols = {
|
|
405
|
+
base: openProtocol(route(BASE, '/', frontend())),
|
|
406
|
+
home: openProtocol(route(HOME, '/', frontend({ default: true, parent: BASE }))),
|
|
407
|
+
dash: openProtocol(route(alias.dash, '/dash', frontend({ parent: BASE }))),
|
|
408
|
+
reports: openProtocol(route(alias.reports, '/reports', frontend({ parent: BASE }))),
|
|
409
|
+
reportsIndex: openProtocol(route(alias.reportsIndex, '/', frontend({ default: true, parent: alias.reports }))),
|
|
410
|
+
reportDetail: openProtocol(route(alias.reportDetail, '/detail', frontend({ parent: alias.reports }))),
|
|
411
|
+
reportSibling: openProtocol(route(alias.reportSibling, '/reports/sibling', frontend({ parent: BASE }))),
|
|
412
|
+
prefs: openProtocol(route(alias.prefs, '/prefs', frontend({ parent: BASE }))),
|
|
413
|
+
login: openProtocol(route(alias.login, '/login', frontend({ parent: BASE }))),
|
|
414
|
+
socket: openProtocol(route(alias.socket, '/socket', frontend({ parent: BASE }))),
|
|
415
|
+
lazy: openProtocol(route(alias.lazy, '/lazy', frontend({ parent: BASE }))),
|
|
416
|
+
lazyEntry: openProtocol(route(alias.lazyEntry, '/lazy-entry', frontend({ parent: BASE }))),
|
|
417
|
+
picker: openProtocol(route(alias.picker, '/picker', frontend({ parent: BASE }))),
|
|
418
|
+
}
|
|
88
419
|
|
|
89
|
-
const
|
|
420
|
+
const entrypoints = [
|
|
90
421
|
// The framework's own entrypoints come first — the api-config middleware the panel context
|
|
91
422
|
// registers resolves one of them during init, and without them init throws before any route
|
|
92
423
|
// is compiled.
|
|
93
|
-
...
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
424
|
+
...baseEntrypoints,
|
|
425
|
+
bindScreen(protocols.base, handler(Layout)),
|
|
426
|
+
bindScreen(protocols.home, handler(screen('home', 'home-screen'))),
|
|
427
|
+
bindScreen(protocols.dash, handler(screen('dash', 'dash-screen'))),
|
|
97
428
|
// A screen that has children needs a `default: true` child of its own — without one its own
|
|
98
429
|
// path matches nothing and the page renders blank.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
),
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
),
|
|
108
|
-
|
|
430
|
+
bindScreen(protocols.reports, handler(ReportsGroup)),
|
|
431
|
+
bindScreen(protocols.reportsIndex, handler(ReportsIndex)),
|
|
432
|
+
bindScreen(protocols.reportDetail, handler(screen('detail', 'detail-screen'))),
|
|
433
|
+
bindScreen(protocols.reportSibling, handler(screen('sibling-detail', 'sibling-detail-screen'))),
|
|
434
|
+
bindScreen(protocols.prefs, handler(PrefsScreen)),
|
|
435
|
+
bindScreen(protocols.login, handler(LoginHarness)),
|
|
436
|
+
bindScreen(protocols.socket, handler(SocketStatusScreen)),
|
|
437
|
+
bindScreen(protocols.lazy, lazyScreen),
|
|
438
|
+
bindScreen(protocols.lazyEntry, handler(LazyEntry)),
|
|
439
|
+
bindScreen(protocols.picker, handler(TranslatedPickerScreen)),
|
|
109
440
|
]
|
|
110
441
|
|
|
111
|
-
context.registerEntrypoints(
|
|
442
|
+
context.registerEntrypoints(entrypoints)
|
|
112
443
|
|
|
113
|
-
|
|
444
|
+
// The consent dialog is a sibling of the Router, as in an application — and only on the consent
|
|
445
|
+
// branches, since its first-visit overlay covers the page every other test clicks through.
|
|
446
|
+
createRoot(document.getElementById('root')!).render(new URLSearchParams(location.search).has('editor') ? <EditorHarness /> : pickerBare
|
|
447
|
+
? <div className="min-h-screen bg-background text-foreground"><PickerScreen /></div>
|
|
448
|
+
: <PanelApp context={context as never}>
|
|
449
|
+
{consentMode != null && <PanelCookieConsent
|
|
450
|
+
policyHref="/cookies"
|
|
451
|
+
{...(withDomains ? { linker: { domains: ['harness-partner.test'] } } : {})}
|
|
452
|
+
{...(modeProp === 'window' || modeProp === 'bar' ? { mode: modeProp } : {})}
|
|
453
|
+
/>}
|
|
454
|
+
</PanelApp>)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import type { FC } from 'react'
|
|
3
|
+
import {
|
|
4
|
+
ColorDot, ColorPicker, ColorSwatches, IconColorPicker, IconGrid, IconPicker, IconTile, usePickerTranslate,
|
|
5
|
+
} from '../../src/picker/index.js'
|
|
6
|
+
import type { IconColorChange, PickerTranslate } from '../../src/picker/index.js'
|
|
7
|
+
import { Sheet, SheetContent, SheetTitle, SheetTrigger } from '../../src/@/components/ui/sheet.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The picker's scenarios, picked by query parameters:
|
|
11
|
+
*
|
|
12
|
+
* - `?custom=1` — `customColors` on every picker;
|
|
13
|
+
* - `?surface=popover|sheet` — forces the surface (default `auto`);
|
|
14
|
+
* - `?compact=1` — the `tile` / `dot` triggers;
|
|
15
|
+
* - `?empty=1` — nothing chosen yet;
|
|
16
|
+
* - `?inSheet=1` — the composite picker inside a Radix Sheet of the page's own;
|
|
17
|
+
* - `?inline=1` — the inline parts (`ColorSwatches`, `IconGrid`) on the page;
|
|
18
|
+
* - `?bare=1` — mounted with no `PanelApp` and no i18n instance at all (mount.tsx);
|
|
19
|
+
* - `?dark=1` — `.dark` on the document element.
|
|
20
|
+
*/
|
|
21
|
+
const params = new URLSearchParams(window.location.search)
|
|
22
|
+
const custom = params.get('custom') === '1'
|
|
23
|
+
const compact = params.get('compact') === '1'
|
|
24
|
+
const empty = params.get('empty') === '1'
|
|
25
|
+
const inSheet = params.get('inSheet') === '1'
|
|
26
|
+
const inline = params.get('inline') === '1'
|
|
27
|
+
const surfaceParam = params.get('surface')
|
|
28
|
+
const surface = surfaceParam === 'popover' || surfaceParam === 'sheet' ? surfaceParam : 'auto'
|
|
29
|
+
|
|
30
|
+
if (params.get('dark') === '1') {
|
|
31
|
+
document.documentElement.classList.add('dark')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const SAMPLES: Array<[string, string]> = [
|
|
35
|
+
['rocket', 'blue'], ['bug', 'red'], ['handshake', 'emerald'], ['flag', 'amber'], ['users', 'violet'],
|
|
36
|
+
['package', 'brown'], ['map-pin', 'navy'], ['siren', 'maroon'], ['leaf', 'olive'], ['star', 'graphite'],
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
export const PickerScreen: FC<{ translate?: PickerTranslate }> = ({ translate }) => {
|
|
40
|
+
const [mark, setMark] = useState<IconColorChange>(empty ? {} : { icon: 'rocket', color: 'indigo' })
|
|
41
|
+
const [color, setColor] = useState<string | undefined>(empty ? undefined : 'teal')
|
|
42
|
+
const [icon, setIcon] = useState<string | undefined>(empty ? undefined : 'briefcase')
|
|
43
|
+
const [submits, setSubmits] = useState(0)
|
|
44
|
+
|
|
45
|
+
const form = (id: string) => <form
|
|
46
|
+
id={id} className="flex flex-col gap-4"
|
|
47
|
+
onSubmit={event => { event.preventDefault(); setSubmits(count => count + 1) }}
|
|
48
|
+
>
|
|
49
|
+
<div className="flex flex-col gap-1.5">
|
|
50
|
+
<label htmlFor={`${id}-mark`} className="text-sm font-medium">Mark</label>
|
|
51
|
+
<IconColorPicker
|
|
52
|
+
id={`${id}-mark`} label="Mark" value={mark} onChange={setMark} customColors={custom} surface={surface}
|
|
53
|
+
trigger={compact ? 'tile' : 'button'} translate={translate}
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
<div className="grid gap-4 sm:grid-cols-2">
|
|
57
|
+
<div className="flex flex-col gap-1.5">
|
|
58
|
+
<label htmlFor={`${id}-color`} className="text-sm font-medium">Colour</label>
|
|
59
|
+
<ColorPicker
|
|
60
|
+
id={`${id}-color`} label="Colour" value={color} onChange={setColor} customColors={custom} surface={surface}
|
|
61
|
+
trigger={compact ? 'dot' : 'button'} translate={translate}
|
|
62
|
+
/>
|
|
63
|
+
</div>
|
|
64
|
+
<div className="flex flex-col gap-1.5">
|
|
65
|
+
<label htmlFor={`${id}-icon`} className="text-sm font-medium">Icon</label>
|
|
66
|
+
<IconPicker
|
|
67
|
+
id={`${id}-icon`} label="Icon" value={icon} onChange={setIcon} color={color} surface={surface}
|
|
68
|
+
trigger={compact ? 'tile' : 'button'} translate={translate}
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
<button type="submit" className="self-start rounded-md border px-3 py-1.5 text-sm">Save</button>
|
|
73
|
+
</form>
|
|
74
|
+
|
|
75
|
+
return <main id="picker" className="mx-auto flex w-full max-w-2xl flex-col gap-6 px-4 py-8">
|
|
76
|
+
<h1 className="text-xl font-semibold">Icon and colour picker</h1>
|
|
77
|
+
{inSheet
|
|
78
|
+
? <Sheet>
|
|
79
|
+
<SheetTrigger id="open-sheet" className="self-start rounded-md border px-3 py-1.5 text-sm">Open sheet</SheetTrigger>
|
|
80
|
+
<SheetContent side="right" aria-describedby={undefined} className="gap-0 p-6 text-foreground">
|
|
81
|
+
<SheetTitle className="mb-4">Edit type</SheetTitle>
|
|
82
|
+
{form('sheet-form')}
|
|
83
|
+
</SheetContent>
|
|
84
|
+
</Sheet>
|
|
85
|
+
: <section className="rounded-xl border p-4">{form('picker-form')}</section>}
|
|
86
|
+
{inline && <section id="inline" className="flex flex-col gap-4 rounded-xl border p-4">
|
|
87
|
+
<ColorSwatches value={mark.color} onChange={next => setMark({ ...mark, color: next })} customColors={custom} translate={translate} />
|
|
88
|
+
<div className="max-h-72 overflow-y-auto">
|
|
89
|
+
<IconGrid value={mark.icon} onChange={next => setMark({ ...mark, icon: next })} color={mark.color} translate={translate} />
|
|
90
|
+
</div>
|
|
91
|
+
</section>}
|
|
92
|
+
<section id="samples" className="flex flex-wrap items-center gap-3 rounded-xl border p-4">
|
|
93
|
+
{SAMPLES.map(([sampleIcon, sampleColor]) =>
|
|
94
|
+
<IconTile key={sampleColor} icon={sampleIcon} color={sampleColor} label={`${sampleIcon} ${sampleColor}`} />)}
|
|
95
|
+
<IconTile icon="rocket" color="blue" variant="plain" size="lg" label="plain rocket" />
|
|
96
|
+
<IconTile icon="not-an-icon" color="not-a-colour" label="fallback" />
|
|
97
|
+
<ColorDot color="blue" size="md" label="blue dot" />
|
|
98
|
+
<ColorDot color="#ff00aa" size="md" label="custom dot" />
|
|
99
|
+
</section>
|
|
100
|
+
<dl className="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-sm">
|
|
101
|
+
<dt>mark</dt><dd><output id="mark-value">{JSON.stringify(mark)}</output></dd>
|
|
102
|
+
<dt>colour</dt><dd><output id="color-value">{color ?? ''}</output></dd>
|
|
103
|
+
<dt>icon</dt><dd><output id="icon-value">{icon ?? ''}</output></dd>
|
|
104
|
+
<dt>submits</dt><dd><output id="submits">{submits}</output></dd>
|
|
105
|
+
</dl>
|
|
106
|
+
</main>
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** The screen as an application rendered by `PanelApp` mounts it: strings from the packaged bundle. */
|
|
110
|
+
export const TranslatedPickerScreen: FC = () => <PickerScreen translate={usePickerTranslate()} />
|