@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
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The horizontal rhythm of the whole page, applied identically to the header row, the content
|
|
3
|
+
* and the footer row.
|
|
4
|
+
*
|
|
5
|
+
* It lives in ONE constant because the three regions have to agree: a content area with its own
|
|
6
|
+
* width sits visibly inset from a full-width header, which reads as a mistake rather than as a
|
|
7
|
+
* design. Adjust it through `containerClassName`, which is MERGED over this — never by giving
|
|
8
|
+
* the content a width of its own.
|
|
9
|
+
*/
|
|
10
|
+
export const CONTAINER = 'mx-auto w-full max-w-6xl px-4'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A 44px target and a ring that is actually visible: the shadcn button draws its focus ring at
|
|
14
|
+
* half the ring colour's alpha, which on a white header is close to nothing, and a menu button is
|
|
15
|
+
* the one control a keyboard user on a narrow window has to find before anything else.
|
|
16
|
+
*/
|
|
17
|
+
export const TARGET = 'size-11 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background'
|
|
18
|
+
|
|
19
|
+
export const ENTRY_ACTIVE = 'bg-accent text-accent-foreground'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Section entries are LINKS, not buttons.
|
|
23
|
+
*
|
|
24
|
+
* The shadcn primitive styles its links as menu tiles — a filled hover/active background, a
|
|
25
|
+
* radius and tile padding — which reads as a row of buttons across the top of an application.
|
|
26
|
+
* These classes land after the primitive's, so `cn`'s tailwind-merge drops the conflicting
|
|
27
|
+
* ones; every neutralised utility here has a counterpart in the primitive, and removing one
|
|
28
|
+
* brings the tile back.
|
|
29
|
+
*/
|
|
30
|
+
export const SECTION_LINK = [
|
|
31
|
+
'bg-transparent hover:bg-transparent focus:bg-transparent',
|
|
32
|
+
'rounded-none px-0 py-1',
|
|
33
|
+
'text-sm font-medium text-muted-foreground',
|
|
34
|
+
'hover:text-foreground hover:underline underline-offset-4',
|
|
35
|
+
// Radix marks the active link with a VALUELESS `data-active`, so the state has to be matched
|
|
36
|
+
// on the attribute's presence. `data-[active=true]` — which the shadcn primitive itself uses —
|
|
37
|
+
// matches nothing here, which is why its own active styling never showed either.
|
|
38
|
+
'data-[active]:text-foreground data-[active]:underline data-[active]:bg-transparent',
|
|
39
|
+
'cursor-pointer',
|
|
40
|
+
].join(' ')
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Invisible until it takes focus, then a pill in the top-left corner above everything — the
|
|
44
|
+
* inverse of the page's own surface (`bg-foreground text-background`), so it reads on any theme.
|
|
45
|
+
*
|
|
46
|
+
* The padding is focus-only: `sr-only` zeroes padding, but a plain `px-4` sorts after it and wins,
|
|
47
|
+
* which leaves a 32px box behind the clip instead of the 1px one assistive tech expects.
|
|
48
|
+
*/
|
|
49
|
+
export const SKIP_LINK = [
|
|
50
|
+
'sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-50 focus:px-4 focus:py-3',
|
|
51
|
+
'rounded-full bg-foreground text-sm font-semibold text-background',
|
|
52
|
+
'outline-none focus-visible:ring-[3px] focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
53
|
+
'focus-visible:ring-offset-background',
|
|
54
|
+
].join(' ')
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Sheet entries are LINKS, exactly as the section menu's are — a real `href` keeps each one
|
|
58
|
+
* focusable, openable in a new tab and announced as a link — and each row is a 44px touch target.
|
|
59
|
+
*/
|
|
60
|
+
export const ENTRY = [
|
|
61
|
+
'flex min-h-11 items-center gap-2 rounded-md px-3 text-sm font-medium text-foreground',
|
|
62
|
+
'hover:bg-accent hover:text-accent-foreground',
|
|
63
|
+
'outline-none focus-visible:ring-[3px] focus-visible:ring-ring',
|
|
64
|
+
].join(' ')
|
|
@@ -1,47 +1,205 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { useRef, type FC, type MouseEvent } from 'react'
|
|
2
2
|
import { useNavigate } from '@owlmeans/client'
|
|
3
|
-
import {
|
|
3
|
+
import { navLabelHelper } from '@owlmeans/client-panel'
|
|
4
|
+
import { cn } from '../../@/lib/utils.js'
|
|
4
5
|
import { Footer } from '../footer/component.js'
|
|
5
6
|
|
|
7
|
+
import { useWideNav } from './viewport.js'
|
|
8
|
+
import { MobileNav } from './mobile.js'
|
|
6
9
|
import { SideNav } from './side.js'
|
|
7
10
|
import { TopNav } from './top.js'
|
|
8
11
|
import type { NavLayoutProps } from './types.js'
|
|
12
|
+
import { CONTAINER, SKIP_LINK } from './consts.local.js'
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
15
|
* The standard two-layer application shell.
|
|
12
16
|
*
|
|
13
|
-
* A layout entrypoint
|
|
17
|
+
* A layout entrypoint binds a component that renders this and nothing else — the screen
|
|
14
18
|
* arrives as `children`. The side menu is mounted twice on purpose: one column for wide
|
|
15
19
|
* viewports and one strip for narrow ones. Both render only when the active section has
|
|
16
20
|
* more than one screen, so the single-screen case costs nothing but the elements' absence.
|
|
21
|
+
*
|
|
22
|
+
* `mobileMenu` swaps the narrow viewport's navigation for a menu button and a sheet holding
|
|
23
|
+
* both levels: the section menu hides below `md`, and the strip is not mounted at all, because
|
|
24
|
+
* the sheet already lists the screens it would show. Wide viewports are unaffected either way.
|
|
25
|
+
*
|
|
26
|
+
* The skip link comes FIRST in the root, ahead of the header — the first thing a keyboard reaches
|
|
27
|
+
* — and moves focus to `<main id="main">`, past the brand, the menus and the actions.
|
|
17
28
|
*/
|
|
18
29
|
export const NavLayout: FC<NavLayoutProps> = ({
|
|
19
|
-
nav,
|
|
30
|
+
nav,
|
|
31
|
+
translate = navLabelHelper.defaultNavTranslate,
|
|
32
|
+
title,
|
|
33
|
+
home,
|
|
34
|
+
actions,
|
|
35
|
+
footer,
|
|
36
|
+
children,
|
|
37
|
+
className,
|
|
38
|
+
style,
|
|
39
|
+
headerClassName,
|
|
40
|
+
contentClassName,
|
|
41
|
+
containerClassName,
|
|
42
|
+
mobileMenu = false,
|
|
43
|
+
skipLinkLabel,
|
|
44
|
+
themeToggle,
|
|
45
|
+
navTestId
|
|
20
46
|
}) => {
|
|
21
47
|
const navigator = useNavigate()
|
|
22
|
-
const
|
|
48
|
+
const wide = useWideNav()
|
|
49
|
+
// The switcher's names go through `translate` like every other shell string, with the caller's
|
|
50
|
+
// own labels winning; `false`/absent stays absent, so the footer renders exactly as it did.
|
|
51
|
+
const toggle =
|
|
52
|
+
themeToggle == null || themeToggle === false
|
|
53
|
+
? undefined
|
|
54
|
+
: {
|
|
55
|
+
labels: {
|
|
56
|
+
toLight:
|
|
57
|
+
(themeToggle === true ? undefined : themeToggle.labels?.toLight) ??
|
|
58
|
+
translate('shell.toLight', 'Switch to light mode'),
|
|
59
|
+
toDark:
|
|
60
|
+
(themeToggle === true ? undefined : themeToggle.labels?.toDark) ??
|
|
61
|
+
translate('shell.toDark', 'Switch to dark mode')
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const toggleProp = toggle != null ? { themeToggle: toggle } : {}
|
|
65
|
+
const main = useRef<HTMLElement>(null)
|
|
66
|
+
const skipLabel = skipLinkLabel === false ? null : (skipLinkLabel ?? translate('shell.skip', 'Skip to content'))
|
|
67
|
+
// Focus is moved by hand rather than left to the fragment navigation `href="#main"` would
|
|
68
|
+
// perform: that changes the location, and the router reads a location change as navigation.
|
|
69
|
+
// The `href` stays so the link is a link — focusable, announced, and working without script.
|
|
70
|
+
const skip = (event: MouseEvent<HTMLAnchorElement>) => {
|
|
71
|
+
event.preventDefault()
|
|
72
|
+
main.current?.focus()
|
|
73
|
+
}
|
|
74
|
+
const brandAlias = home ?? nav.sections.find((section) => section.items.length > 0)?.items[0]?.alias
|
|
75
|
+
// MERGED over the default, never substituted for it. `containerClassName` is how a design
|
|
76
|
+
// adjusts ONE aspect of the rhythm — almost always the width — and a caller passing
|
|
77
|
+
// `max-w-[1280px]` means "wider", not "no padding and no centring". Substituting dropped
|
|
78
|
+
// `px-4` and `mx-auto` along with the width it replaced, which is a page whose header,
|
|
79
|
+
// content and footer all run flush to the window edge. tailwind-merge keeps the override
|
|
80
|
+
// winning on the utility it names and leaves the rest of the rhythm standing, so a width-only
|
|
81
|
+
// value stays a width-only change; `px-8` still overrides the padding when that is the intent.
|
|
82
|
+
const container = cn(CONTAINER, containerClassName)
|
|
23
83
|
|
|
24
|
-
return
|
|
25
|
-
className={cn('flex min-h-screen flex-col bg-background text-foreground', className)}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
84
|
+
return (
|
|
85
|
+
<div className={cn('flex min-h-screen flex-col bg-background text-foreground', className)} style={style}>
|
|
86
|
+
{/*
|
|
87
|
+
* Before `header`, never inside it: `header`'s own first `div` is the shared-rhythm row a
|
|
88
|
+
* position-based query locates, and a skip link is not part of any row.
|
|
89
|
+
*/}
|
|
90
|
+
{skipLabel != null && (
|
|
91
|
+
<a href="#main" onClick={skip} data-skip-link className={SKIP_LINK}>
|
|
92
|
+
{skipLabel}
|
|
93
|
+
</a>
|
|
94
|
+
)}
|
|
95
|
+
{/*
|
|
96
|
+
* The header is a SURFACE, and it states both halves of one.
|
|
97
|
+
*
|
|
98
|
+
* It has to paint an opaque background — it is sticky, and content scrolls underneath —
|
|
99
|
+
* which makes it a different surface from the root behind it. A colour set on the root
|
|
100
|
+
* (`className="bg-secondary text-secondary-foreground"`, a dark application shell) then
|
|
101
|
+
* inherits INTO this bar while its own `bg-background` stays put, and every child that
|
|
102
|
+
* states no colour of its own — the brand, a ghost-variant action button — is painted in
|
|
103
|
+
* the foreground of a surface it is not on. That is light-on-light, it raises nothing at
|
|
104
|
+
* build or run time, and it is invisible only to whoever opens the page.
|
|
105
|
+
*
|
|
106
|
+
* `text-foreground` is what stops the inheritance at the boundary. It is not decoration
|
|
107
|
+
* and it is not redundant with the root: pairing has to be restated by every element that
|
|
108
|
+
* repaints its own background. `headerClassName` lands after it, so an app that wants a
|
|
109
|
+
* dark bar overrides BOTH halves through tailwind-merge.
|
|
110
|
+
*
|
|
111
|
+
* The `data-nav-backdrop` layer underneath is what keeps that promise even when
|
|
112
|
+
* `headerClassName` does NOT: a restyle that hands it an invalid Tailwind v4 arbitrary-value
|
|
113
|
+
* class (`bg-[--x]`, dropped silently), a bare `bg-transparent`, or a translucent surface
|
|
114
|
+
* (`bg-x/50`) used to leave the sticky bar with no background paint at all, and page content
|
|
115
|
+
* scrolled visibly through the menu. `-z-10` keeps it behind everything `header` renders and
|
|
116
|
+
* `pointer-events-none` keeps it out of the way of clicks; it paints `bg-background` no
|
|
117
|
+
* matter what `headerClassName` does or fails to do, and a caller who genuinely wants a dark
|
|
118
|
+
* bar still gets it because `headerClassName`'s own background paints OVER this one.
|
|
119
|
+
*/}
|
|
120
|
+
<header className={cn('sticky top-0 z-40 isolate border-b bg-background text-foreground', headerClassName)}>
|
|
121
|
+
<div className={cn('flex h-14 items-center gap-6', container)}>
|
|
122
|
+
{title != null ? (
|
|
123
|
+
<a
|
|
124
|
+
onClick={brandAlias != null ? navigator.press(brandAlias) : undefined}
|
|
125
|
+
className={cn(
|
|
126
|
+
'brand flex items-center gap-2 text-lg font-semibold',
|
|
127
|
+
brandAlias != null && 'cursor-pointer'
|
|
128
|
+
)}
|
|
129
|
+
>
|
|
130
|
+
{title}
|
|
131
|
+
</a>
|
|
132
|
+
) : null}
|
|
133
|
+
{(!mobileMenu || wide) && (
|
|
134
|
+
<TopNav
|
|
135
|
+
config={nav}
|
|
136
|
+
translate={translate}
|
|
137
|
+
ariaLabel="Sections"
|
|
138
|
+
testId={navTestId}
|
|
139
|
+
className={mobileMenu ? 'hidden md:flex' : undefined}
|
|
140
|
+
/>
|
|
141
|
+
)}
|
|
142
|
+
{/*
|
|
143
|
+
* The menu button goes INTO the actions row, after the actions, rather than being a
|
|
144
|
+
* sibling of it: the row is what `ml-auto` pushes to the far edge, and the actions — a
|
|
145
|
+
* "Get started" button, a sign-in link — have to stay visible at every width beside it.
|
|
146
|
+
*/}
|
|
147
|
+
<div className="ml-auto flex items-center gap-2">
|
|
148
|
+
{actions}
|
|
149
|
+
{mobileMenu && !wide && (
|
|
150
|
+
<MobileNav config={nav} translate={translate} ariaLabel="Sections" className="md:hidden" />
|
|
151
|
+
)}
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
{!mobileMenu && (
|
|
155
|
+
<SideNav config={nav} translate={translate} variant="bar" ariaLabel="Screens" className="md:hidden" />
|
|
156
|
+
)}
|
|
157
|
+
{/*
|
|
158
|
+
* Last in source order, not first — `header`'s own FIRST `div` child is what the layout
|
|
159
|
+
* test locates to measure the shared rhythm (`header > div`, `.first()`), and this element
|
|
160
|
+
* is not part of that rhythm. Negative z-index inside `header`'s own `isolate` stacking
|
|
161
|
+
* context paints a layer behind every normal-flow child regardless of where it sits in the
|
|
162
|
+
* DOM, so moving it here changes nothing about what is visible — only which `div` a
|
|
163
|
+
* position-based query finds first.
|
|
164
|
+
*/}
|
|
165
|
+
<div
|
|
166
|
+
aria-hidden="true"
|
|
167
|
+
data-nav-backdrop
|
|
168
|
+
className="absolute inset-0 -z-10 bg-background pointer-events-none"
|
|
169
|
+
/>
|
|
170
|
+
</header>
|
|
171
|
+
<div className="flex flex-1">
|
|
172
|
+
<SideNav config={nav} translate={translate} variant="side" ariaLabel="Screens" className="hidden md:block" />
|
|
173
|
+
{/*
|
|
174
|
+
* `tabIndex={-1}` makes the skip link's target focusable by script without putting it in
|
|
175
|
+
* the tab order. With the skip link disabled the id is not claimed either: an application
|
|
176
|
+
* that renders its own skip link owns its own `#main`, and two elements must not share it.
|
|
177
|
+
*/}
|
|
178
|
+
<main
|
|
179
|
+
ref={main}
|
|
180
|
+
{...(skipLabel != null ? { id: 'main', tabIndex: -1 } : {})}
|
|
181
|
+
className={cn('flex-1 py-8 outline-none', contentClassName)}
|
|
182
|
+
>
|
|
183
|
+
<div className={cn(container)}>{children}</div>
|
|
184
|
+
</main>
|
|
36
185
|
</div>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
186
|
+
{/*
|
|
187
|
+
* The footer is rendered unconditionally, `footer` prop or not: `Footer` itself renders the
|
|
188
|
+
* platform/owner credit line even when there are no links and no children, and only that
|
|
189
|
+
* component gets to decide there is nothing to show. Gating this on `footer` used to make
|
|
190
|
+
* the credit disappear from every layout that never passed one.
|
|
191
|
+
*
|
|
192
|
+
* A NODE footer goes in as `content`, not as children: children join the centred link row,
|
|
193
|
+
* which squeezes an application's own footer layout (a brand, a description, link columns)
|
|
194
|
+
* into a shrink-wrapped, centred line. `content` is a full-width block on the shell's rhythm.
|
|
195
|
+
*/}
|
|
196
|
+
{Array.isArray(footer) ? (
|
|
197
|
+
<Footer links={footer} translate={translate} containerClassName={container} {...toggleProp} />
|
|
198
|
+
) : footer != null ? (
|
|
199
|
+
<Footer containerClassName={container} content={footer} {...toggleProp} />
|
|
200
|
+
) : (
|
|
201
|
+
<Footer containerClassName={container} {...toggleProp} />
|
|
202
|
+
)}
|
|
42
203
|
</div>
|
|
43
|
-
|
|
44
|
-
? <Footer links={footer} translate={translate} />
|
|
45
|
-
: footer != null ? <Footer>{footer}</Footer> : null}
|
|
46
|
-
</div>
|
|
204
|
+
)
|
|
47
205
|
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { useId, useState, type FC, type MouseEvent } from 'react'
|
|
2
|
+
import { MenuIcon, XIcon } from 'lucide-react'
|
|
3
|
+
import { usePanelNav, navLabelHelper } from '@owlmeans/client-panel'
|
|
4
|
+
import { cn } from '../../@/lib/utils.js'
|
|
5
|
+
import { Button } from '../../@/components/ui/button.js'
|
|
6
|
+
import { Sheet, SheetClose, SheetContent, SheetTitle, SheetTrigger } from '../../@/components/ui/sheet.js'
|
|
7
|
+
|
|
8
|
+
import type { MobileNavProps } from './types.js'
|
|
9
|
+
import { ENTRY_ACTIVE, TARGET, ENTRY } from './consts.local.js'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Both navigation levels behind one menu button — what a narrow viewport gets instead of the
|
|
13
|
+
* section menu.
|
|
14
|
+
*
|
|
15
|
+
* The sheet lists every section; a section holding more than one screen lists its screens under
|
|
16
|
+
* the section's name, and a single-screen section is one link carrying the section's own label —
|
|
17
|
+
* the same rule the side menu follows, so a destination never appears twice. Labels resolve
|
|
18
|
+
* exactly as `TopNav` and `SideNav` resolve theirs (`nav.<section>`, `modules.<alias>`), through
|
|
19
|
+
* the same `translate` prop.
|
|
20
|
+
*
|
|
21
|
+
* Pressing an entry navigates in-app AND closes the sheet. Both happen in the anchor's own click
|
|
22
|
+
* handler: the `preventDefault()` that stops a full page load is not something a dialog notices,
|
|
23
|
+
* so a sheet left to close itself would stay open over the screen it just navigated to.
|
|
24
|
+
*
|
|
25
|
+
* `className` and `style` land on the TRIGGER — the only element the sheet places in the host's
|
|
26
|
+
* flow; the sheet itself is portalled to the document body.
|
|
27
|
+
*/
|
|
28
|
+
export const MobileNav: FC<MobileNavProps> = ({
|
|
29
|
+
config,
|
|
30
|
+
translate = navLabelHelper.defaultNavTranslate,
|
|
31
|
+
ariaLabel,
|
|
32
|
+
className,
|
|
33
|
+
style
|
|
34
|
+
}) => {
|
|
35
|
+
const model = usePanelNav(config)
|
|
36
|
+
const [open, setOpen] = useState(false)
|
|
37
|
+
const id = useId()
|
|
38
|
+
|
|
39
|
+
if (model.sections.length < 1) {
|
|
40
|
+
return null
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Keys outside the `nav.` family on purpose: `nav.<name>` addresses a SECTION, and an
|
|
44
|
+
// application is free to have a section called `menu`.
|
|
45
|
+
const label = translate('shell.menu', 'Menu')
|
|
46
|
+
const closeLabel = translate('shell.close', 'Close')
|
|
47
|
+
|
|
48
|
+
const follow = (go: () => void) => (event: MouseEvent<HTMLAnchorElement>) => {
|
|
49
|
+
event.preventDefault()
|
|
50
|
+
setOpen(false)
|
|
51
|
+
go()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Sheet open={open} onOpenChange={setOpen}>
|
|
56
|
+
<SheetTrigger asChild>
|
|
57
|
+
<Button
|
|
58
|
+
variant="ghost"
|
|
59
|
+
size="icon"
|
|
60
|
+
aria-label={label}
|
|
61
|
+
data-nav-menu-trigger
|
|
62
|
+
className={cn(TARGET, className)}
|
|
63
|
+
style={style}
|
|
64
|
+
>
|
|
65
|
+
<MenuIcon className="size-6" aria-hidden="true" />
|
|
66
|
+
</Button>
|
|
67
|
+
</SheetTrigger>
|
|
68
|
+
{/*
|
|
69
|
+
* `text-foreground` beside the primitive's `bg-background`: the sheet is portalled to the
|
|
70
|
+
* document body, so it inherits nothing from the shell and states both halves of its surface
|
|
71
|
+
* itself — the same rule the header follows.
|
|
72
|
+
*
|
|
73
|
+
* No description, deliberately: the title names the dialog, and Radix only warns about a
|
|
74
|
+
* missing one unless `aria-describedby` is passed explicitly as undefined.
|
|
75
|
+
*/}
|
|
76
|
+
<SheetContent
|
|
77
|
+
side="right"
|
|
78
|
+
showCloseButton={false}
|
|
79
|
+
aria-describedby={undefined}
|
|
80
|
+
data-nav-sheet
|
|
81
|
+
className="gap-0 p-0 text-foreground"
|
|
82
|
+
>
|
|
83
|
+
<div className="flex h-14 shrink-0 items-center justify-between border-b pl-4 pr-2">
|
|
84
|
+
<SheetTitle className="text-base">{label}</SheetTitle>
|
|
85
|
+
<SheetClose asChild>
|
|
86
|
+
<Button variant="ghost" size="icon" aria-label={closeLabel} className={TARGET}>
|
|
87
|
+
<XIcon className="size-5" aria-hidden="true" />
|
|
88
|
+
</Button>
|
|
89
|
+
</SheetClose>
|
|
90
|
+
</div>
|
|
91
|
+
<nav aria-label={ariaLabel} className="flex-1 overflow-y-auto p-2">
|
|
92
|
+
<ul className="flex flex-col gap-1">
|
|
93
|
+
{model.sections.map((section) => {
|
|
94
|
+
const sectionLabel = navLabelHelper.resolveNavLabel(
|
|
95
|
+
translate,
|
|
96
|
+
section.label,
|
|
97
|
+
`nav.${section.name}`,
|
|
98
|
+
section.name
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
if (section.items.length > 1) {
|
|
102
|
+
const heading = `${id}-${section.name}`
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<li key={section.name} className="pt-2">
|
|
106
|
+
<p
|
|
107
|
+
id={heading}
|
|
108
|
+
className={cn(
|
|
109
|
+
'px-3 pb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground',
|
|
110
|
+
model.isSectionActive(section) && 'text-foreground'
|
|
111
|
+
)}
|
|
112
|
+
>
|
|
113
|
+
{sectionLabel}
|
|
114
|
+
</p>
|
|
115
|
+
<ul aria-labelledby={heading} className="flex flex-col gap-1">
|
|
116
|
+
{section.items.map((item) => {
|
|
117
|
+
const active = model.isItemActive(item)
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<li key={item.alias}>
|
|
121
|
+
<a
|
|
122
|
+
data-testid={item.testId}
|
|
123
|
+
href={model.hrefOf(item)}
|
|
124
|
+
onClick={follow(model.goItem(item))}
|
|
125
|
+
aria-current={active ? 'page' : undefined}
|
|
126
|
+
className={cn(ENTRY, active && ENTRY_ACTIVE)}
|
|
127
|
+
>
|
|
128
|
+
{item.Icon != null ? <item.Icon className="size-4" /> : null}
|
|
129
|
+
{navLabelHelper.resolveNavLabel(
|
|
130
|
+
translate,
|
|
131
|
+
item.label,
|
|
132
|
+
`modules.${item.alias}`,
|
|
133
|
+
item.alias
|
|
134
|
+
)}
|
|
135
|
+
</a>
|
|
136
|
+
</li>
|
|
137
|
+
)
|
|
138
|
+
})}
|
|
139
|
+
</ul>
|
|
140
|
+
</li>
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const active = model.isSectionActive(section)
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
<li key={section.name}>
|
|
148
|
+
<a
|
|
149
|
+
data-testid={section.testId}
|
|
150
|
+
href={model.hrefOf(section)}
|
|
151
|
+
onClick={follow(model.goSection(section))}
|
|
152
|
+
aria-current={active ? 'page' : undefined}
|
|
153
|
+
className={cn(ENTRY, active && ENTRY_ACTIVE)}
|
|
154
|
+
>
|
|
155
|
+
{sectionLabel}
|
|
156
|
+
</a>
|
|
157
|
+
</li>
|
|
158
|
+
)
|
|
159
|
+
})}
|
|
160
|
+
</ul>
|
|
161
|
+
</nav>
|
|
162
|
+
</SheetContent>
|
|
163
|
+
</Sheet>
|
|
164
|
+
)
|
|
165
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { FC } from 'react'
|
|
2
|
-
import {
|
|
3
|
-
import { cn } from '
|
|
4
|
-
import { Button } from '
|
|
2
|
+
import { usePanelNav, navLabelHelper } from '@owlmeans/client-panel'
|
|
3
|
+
import { cn } from '../../@/lib/utils.js'
|
|
4
|
+
import { Button } from '../../@/components/ui/button.js'
|
|
5
5
|
|
|
6
|
+
import { useWideNav } from './viewport.js'
|
|
6
7
|
import type { SideNavProps } from './types.js'
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -12,41 +13,56 @@ import type { SideNavProps } from './types.js'
|
|
|
12
13
|
* are already on is noise. The component still exists in the tree, so a section that grows
|
|
13
14
|
* a second screen gains its side menu with no layout change.
|
|
14
15
|
*/
|
|
15
|
-
export const SideNav: FC<SideNavProps> = (
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
export const SideNav: FC<SideNavProps> = ({
|
|
17
|
+
config,
|
|
18
|
+
translate = navLabelHelper.defaultNavTranslate,
|
|
19
|
+
variant = 'side',
|
|
20
|
+
ariaLabel,
|
|
21
|
+
className,
|
|
22
|
+
style
|
|
23
|
+
}) => {
|
|
18
24
|
const model = usePanelNav(config)
|
|
25
|
+
const wide = useWideNav()
|
|
19
26
|
|
|
20
27
|
if (!model.showSide || model.active == null) {
|
|
21
28
|
return null
|
|
22
29
|
}
|
|
23
30
|
|
|
24
|
-
const items = model.active.items.map(item => {
|
|
25
|
-
const label = resolveNavLabel(translate, item.label, `modules.${item.alias}`, item.alias)
|
|
31
|
+
const items = model.active.items.map((item) => {
|
|
32
|
+
const label = navLabelHelper.resolveNavLabel(translate, item.label, `modules.${item.alias}`, item.alias)
|
|
26
33
|
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
return (
|
|
35
|
+
<Button
|
|
36
|
+
key={item.alias}
|
|
37
|
+
data-testid={(variant === 'side' ? wide : !wide) ? item.testId : undefined}
|
|
38
|
+
variant="ghost"
|
|
39
|
+
size={variant === 'bar' ? 'sm' : 'default'}
|
|
40
|
+
onClick={model.goItem(item)}
|
|
41
|
+
aria-current={model.isItemActive(item) ? 'page' : undefined}
|
|
42
|
+
className={cn(
|
|
43
|
+
variant === 'bar' ? 'shrink-0' : 'w-full justify-start',
|
|
44
|
+
model.isItemActive(item) && 'bg-accent text-accent-foreground'
|
|
45
|
+
)}
|
|
46
|
+
>
|
|
47
|
+
{item.Icon != null ? <item.Icon className="size-4" /> : null}
|
|
48
|
+
{label}
|
|
49
|
+
</Button>
|
|
50
|
+
)
|
|
41
51
|
})
|
|
42
52
|
|
|
43
|
-
return variant === 'bar'
|
|
44
|
-
|
|
53
|
+
return variant === 'bar' ? (
|
|
54
|
+
<nav
|
|
45
55
|
aria-label={ariaLabel}
|
|
46
56
|
className={cn('flex gap-1 overflow-x-auto border-b px-2 py-1', className)}
|
|
47
57
|
style={style}
|
|
48
|
-
>
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
>
|
|
59
|
+
{items}
|
|
60
|
+
</nav>
|
|
61
|
+
) : (
|
|
62
|
+
<aside className={cn('w-56 shrink-0 border-r', className)} style={style}>
|
|
63
|
+
<nav aria-label={ariaLabel} className="flex flex-col gap-1 p-3">
|
|
64
|
+
{items}
|
|
65
|
+
</nav>
|
|
51
66
|
</aside>
|
|
67
|
+
)
|
|
52
68
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { FC } from 'react'
|
|
2
|
-
import {
|
|
3
|
-
import { cn } from '
|
|
2
|
+
import { usePanelNav, navLabelHelper } from '@owlmeans/client-panel'
|
|
3
|
+
import { cn } from '../../@/lib/utils.js'
|
|
4
4
|
import {
|
|
5
|
-
NavigationMenu,
|
|
6
|
-
|
|
5
|
+
NavigationMenu,
|
|
6
|
+
NavigationMenuItem,
|
|
7
|
+
NavigationMenuLink,
|
|
8
|
+
NavigationMenuList
|
|
9
|
+
} from '../../@/components/ui/navigation-menu.js'
|
|
7
10
|
|
|
8
11
|
import type { TopNavProps } from './types.js'
|
|
12
|
+
import { SECTION_LINK } from './consts.local.js'
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
15
|
* The first navigation level — one entry per section.
|
|
@@ -13,29 +17,47 @@ import type { TopNavProps } from './types.js'
|
|
|
13
17
|
* Pressing a section goes to its first screen; the side menu then offers the rest. The
|
|
14
18
|
* viewport is off because no section opens a panel: these are links, not dropdowns.
|
|
15
19
|
*/
|
|
16
|
-
export const TopNav: FC<TopNavProps> = ({
|
|
20
|
+
export const TopNav: FC<TopNavProps> = ({
|
|
21
|
+
config,
|
|
22
|
+
translate = navLabelHelper.defaultNavTranslate,
|
|
23
|
+
ariaLabel,
|
|
24
|
+
testId,
|
|
25
|
+
className,
|
|
26
|
+
style
|
|
27
|
+
}) => {
|
|
17
28
|
const model = usePanelNav(config)
|
|
18
29
|
|
|
19
30
|
if (model.sections.length < 1) {
|
|
20
31
|
return null
|
|
21
32
|
}
|
|
22
33
|
|
|
23
|
-
return
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
return (
|
|
35
|
+
<NavigationMenu viewport={false} aria-label={ariaLabel} data-testid={testId} className={className} style={style}>
|
|
36
|
+
<NavigationMenuList className="flex-wrap gap-4">
|
|
37
|
+
{model.sections.map((section) => {
|
|
38
|
+
const go = model.goSection(section)
|
|
27
39
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
return (
|
|
41
|
+
<NavigationMenuItem key={section.name}>
|
|
42
|
+
<NavigationMenuLink
|
|
43
|
+
active={model.isSectionActive(section)}
|
|
44
|
+
aria-current={model.isSectionActive(section) ? 'page' : undefined}
|
|
45
|
+
data-testid={section.testId}
|
|
46
|
+
// A real `href` keeps the entry focusable and openable in a new tab; the click is
|
|
47
|
+
// still handled in-app, so the browser never reloads the whole application.
|
|
48
|
+
href={model.hrefOf(section)}
|
|
49
|
+
onClick={(event) => {
|
|
50
|
+
event.preventDefault()
|
|
51
|
+
go()
|
|
52
|
+
}}
|
|
53
|
+
className={cn(SECTION_LINK)}
|
|
54
|
+
>
|
|
55
|
+
{navLabelHelper.resolveNavLabel(translate, section.label, `nav.${section.name}`, section.name)}
|
|
56
|
+
</NavigationMenuLink>
|
|
57
|
+
</NavigationMenuItem>
|
|
58
|
+
)
|
|
59
|
+
})}
|
|
60
|
+
</NavigationMenuList>
|
|
61
|
+
</NavigationMenu>
|
|
62
|
+
)
|
|
41
63
|
}
|