@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PropsWithChildren, ReactNode } from 'react'
|
|
2
2
|
import type { NavTranslate, PanelNavConfig, PanelNavLink } from '@owlmeans/client-panel'
|
|
3
|
+
import type { FooterThemeToggle } from '../footer/types.js'
|
|
3
4
|
import type { StyledProps } from '../types.js'
|
|
4
5
|
|
|
5
6
|
interface NavCommonProps extends StyledProps {
|
|
@@ -7,9 +8,10 @@ interface NavCommonProps extends StyledProps {
|
|
|
7
8
|
/** See {@link NavTranslate} — omitted, literal labels and humanized aliases are used. */
|
|
8
9
|
translate?: NavTranslate
|
|
9
10
|
ariaLabel?: string
|
|
11
|
+
testId?: string
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
export interface TopNavProps extends NavCommonProps {
|
|
14
|
+
export interface TopNavProps extends NavCommonProps {}
|
|
13
15
|
|
|
14
16
|
export interface SideNavProps extends NavCommonProps {
|
|
15
17
|
/**
|
|
@@ -19,8 +21,17 @@ export interface SideNavProps extends NavCommonProps {
|
|
|
19
21
|
variant?: 'side' | 'bar'
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
/**
|
|
25
|
+
* `ariaLabel` names the navigation landmark INSIDE the sheet; `translate` also resolves the menu
|
|
26
|
+
* button's accessible name and the sheet's title (`shell.menu`, default "Menu") and its close
|
|
27
|
+
* button's (`shell.close`, default "Close"). `className` and `style` land on the trigger button.
|
|
28
|
+
*/
|
|
29
|
+
export interface MobileNavProps extends NavCommonProps {}
|
|
30
|
+
|
|
22
31
|
export interface NavLayoutProps extends PropsWithChildren<StyledProps> {
|
|
23
32
|
nav: PanelNavConfig
|
|
33
|
+
/** Stable selector on the desktop navigation landmark. */
|
|
34
|
+
navTestId?: string
|
|
24
35
|
translate?: NavTranslate
|
|
25
36
|
/** Brand slot — rendered at the far left of the header. */
|
|
26
37
|
title?: ReactNode
|
|
@@ -28,7 +39,59 @@ export interface NavLayoutProps extends PropsWithChildren<StyledProps> {
|
|
|
28
39
|
home?: string
|
|
29
40
|
/** Header right side — sign-in controls, a theme toggle, whatever the app puts there. */
|
|
30
41
|
actions?: ReactNode
|
|
31
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* Opt-in narrow-viewport menu. Below `md` (768px) the section menu is hidden and a menu button
|
|
44
|
+
* at the end of the header opens a sheet listing every section and its screens ({@link
|
|
45
|
+
* MobileNavProps}); `actions` stay in the header at every width. The screen strip the narrow
|
|
46
|
+
* viewport otherwise gets under the header is NOT rendered then — the sheet already lists the
|
|
47
|
+
* same screens, and two menus for one level is one too many. Off, the shell is exactly what it
|
|
48
|
+
* has always been.
|
|
49
|
+
*/
|
|
50
|
+
mobileMenu?: boolean
|
|
51
|
+
/**
|
|
52
|
+
* The skip link rendered first in the page, ahead of the header, moving focus to the content
|
|
53
|
+
* (`<main id="main">`). Invisible until focused, then a pill in the top-left corner. Defaults to
|
|
54
|
+
* `translate('shell.skip', 'Skip to content')`; `false` renders no link AND leaves `main`
|
|
55
|
+
* without the `main` id, for an application that renders its own skip link and target.
|
|
56
|
+
*/
|
|
57
|
+
skipLinkLabel?: string | false
|
|
58
|
+
/**
|
|
59
|
+
* The light/dark switcher in the footer's bottom row, beside the credit — forwarded to
|
|
60
|
+
* `Footer`, whether `footer` is links, a node or absent. The accessible names resolve
|
|
61
|
+
* `shell.toLight` / `shell.toDark` through `translate` unless `labels` gives them. Absent or
|
|
62
|
+
* `false`, the footer renders exactly as it does without one.
|
|
63
|
+
*/
|
|
64
|
+
themeToggle?: FooterThemeToggle
|
|
65
|
+
/**
|
|
66
|
+
* An array renders the standard footer: a centred row of links above the credit line.
|
|
67
|
+
*
|
|
68
|
+
* A node is the application's OWN footer layout — brand, description, link columns — and is
|
|
69
|
+
* rendered as a full-width block (`w-full self-stretch`, start-aligned text) inside the footer's
|
|
70
|
+
* container, on the shell's rhythm, above the platform/owner credit line. It never replaces the
|
|
71
|
+
* credit: `ShellCredit` stays last in every footer, and nothing a caller passes here removes it.
|
|
72
|
+
*/
|
|
32
73
|
footer?: PanelNavLink[] | ReactNode
|
|
74
|
+
/**
|
|
75
|
+
* Styles the HEADER — the sticky bar carrying the brand, the section menu and `actions`.
|
|
76
|
+
*
|
|
77
|
+
* The header is its own SURFACE: it paints an opaque background because content scrolls
|
|
78
|
+
* under it. Give it a background here and you must give it the paired foreground too
|
|
79
|
+
* (`bg-secondary text-secondary-foreground`), exactly as on any other surface — this is the
|
|
80
|
+
* supported way to give an application a dark top bar, and it is why colouring the root
|
|
81
|
+
* instead is not.
|
|
82
|
+
*/
|
|
83
|
+
headerClassName?: string
|
|
84
|
+
/** Styles the content area. NOT its width — see `containerClassName`. */
|
|
33
85
|
contentClassName?: string
|
|
86
|
+
/**
|
|
87
|
+
* The page's horizontal rhythm — width and side padding — applied identically to the header
|
|
88
|
+
* row, the content and the footer row. Give the content a width of its own and it sits inset
|
|
89
|
+
* from a full-width header, which reads as a bug rather than as a layout.
|
|
90
|
+
*
|
|
91
|
+
* MERGED over the shell's default (`mx-auto w-full max-w-6xl px-4`), not substituted for it:
|
|
92
|
+
* pass `max-w-[1280px]` and only the width changes, while the centring and the side padding
|
|
93
|
+
* stay. Name the utility you actually want to move — `px-8` widens the gutters — because
|
|
94
|
+
* anything you do not name keeps its default.
|
|
95
|
+
*/
|
|
96
|
+
containerClassName?: string
|
|
34
97
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
/** The same md boundary as the shell's Tailwind layout, including resize after mount. */
|
|
4
|
+
export const useWideNav = (): boolean => {
|
|
5
|
+
const [wide, setWide] = useState(
|
|
6
|
+
() => typeof window === 'undefined' || window.matchMedia('(min-width: 768px)').matches
|
|
7
|
+
)
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const media = window.matchMedia('(min-width: 768px)')
|
|
10
|
+
const change = () => setWide(media.matches)
|
|
11
|
+
change()
|
|
12
|
+
media.addEventListener('change', change)
|
|
13
|
+
return () => media.removeEventListener('change', change)
|
|
14
|
+
}, [])
|
|
15
|
+
return wide
|
|
16
|
+
}
|
|
@@ -3,13 +3,21 @@ import type { PanelAppProps } from './types.js'
|
|
|
3
3
|
|
|
4
4
|
import { App } from '@owlmeans/client'
|
|
5
5
|
import { I18nContext } from '@owlmeans/client-i18n'
|
|
6
|
-
import { cn } from '
|
|
6
|
+
import { cn } from '../../@/lib/utils.js'
|
|
7
|
+
import { SocketReloadDialog } from '../socket/reload-dialog.js'
|
|
7
8
|
|
|
8
9
|
export const PanelApp: FC<PanelAppProps> = ({ context, provide, children, rootClassName }) => {
|
|
9
10
|
return <div className={cn('min-h-screen bg-background text-foreground', rootClassName)}>
|
|
10
11
|
<I18nContext config={context.cfg}>
|
|
11
12
|
<App context={context} provide={provide}>
|
|
12
13
|
{children}
|
|
14
|
+
{/*
|
|
15
|
+
A sibling of the Router, exactly like `PanelCookieConsent` — a dialog mounted inside a
|
|
16
|
+
route is torn down on every navigation, which for a modal means it closes itself the
|
|
17
|
+
first time anything moves. Opt-in per app via `cfg.socket.reloadDialog`; the component
|
|
18
|
+
itself stays inert (renders nothing) whenever the flag is off or nothing is `'lost'`.
|
|
19
|
+
*/}
|
|
20
|
+
{context.cfg.socket?.reloadDialog === true && <SocketReloadDialog />}
|
|
13
21
|
</App>
|
|
14
22
|
</I18nContext>
|
|
15
23
|
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FC } from 'react'
|
|
2
|
+
import type { ColorPickerProps } from './types.js'
|
|
3
|
+
import { PickerRoot } from './root.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The colour half alone: a trigger opening the swatches (plus a colour wheel and a hex field with
|
|
7
|
+
* `customColors`). A swatch commits its key and closes; the wheel and the field commit as they
|
|
8
|
+
* change and keep it open. Pass `colors` for an application palette — a status palette, say.
|
|
9
|
+
*/
|
|
10
|
+
export const ColorPicker: FC<ColorPickerProps> = (
|
|
11
|
+
{ value, onChange, trigger = 'button', customColors = false, ...base }
|
|
12
|
+
) => <PickerRoot
|
|
13
|
+
{...base} mode="color" trigger={trigger} customColors={customColors} closeOnPick color={value}
|
|
14
|
+
onColor={onChange} onIcon={() => undefined}
|
|
15
|
+
/>
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react'
|
|
2
|
+
import type { PickerDotSize, PickerTileSize } from './types.js'
|
|
3
|
+
import type { PickerLayout } from './types.local.js'
|
|
4
|
+
|
|
5
|
+
/** From this width up `surface="auto"` opens a popover; below it, a bottom sheet. */
|
|
6
|
+
export const POPOVER_QUERY = '(min-width: 768px)'
|
|
7
|
+
|
|
8
|
+
/** A mouse or trackpad — the search field may take focus on open without raising a keyboard. */
|
|
9
|
+
export const FINE_POINTER_QUERY = '(pointer: fine)'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The current mode's ink and ground, read from the five custom properties `styleOf` sets.
|
|
13
|
+
*
|
|
14
|
+
* Dark follows web-panel's colour-scheme contract — `.dark` on the document element, or the
|
|
15
|
+
* operating system's dark unless `.light` is there — through explicit arbitrary variants. Never the
|
|
16
|
+
* consumer's `dark:`: an application may define it any way it likes, or not at all. Every part that
|
|
17
|
+
* carries a colour's style puts this on the same element; children read `--pick-fg` / `--pick-bg`.
|
|
18
|
+
*/
|
|
19
|
+
export const PICK_SCOPE = [
|
|
20
|
+
'[--pick-fg:var(--pick-ink)] [--pick-bg:var(--pick-soft)]',
|
|
21
|
+
'[.dark_&]:[--pick-fg:var(--pick-ink-dark)] [.dark_&]:[--pick-bg:var(--pick-soft-dark)]',
|
|
22
|
+
'[@media(prefers-color-scheme:dark)]:[:root:not(.light)_&]:[--pick-fg:var(--pick-ink-dark)]',
|
|
23
|
+
'[@media(prefers-color-scheme:dark)]:[:root:not(.light)_&]:[--pick-bg:var(--pick-soft-dark)]',
|
|
24
|
+
].join(' ')
|
|
25
|
+
|
|
26
|
+
/** A hairline inside a swatch, so a dark swatch keeps an edge on a dark surface and a pale one on a light. */
|
|
27
|
+
export const HAIRLINE = [
|
|
28
|
+
'shadow-[inset_0_0_0_1px_rgb(0_0_0/0.14)]',
|
|
29
|
+
'[.dark_&]:shadow-[inset_0_0_0_1px_rgb(255_255_255/0.24)]',
|
|
30
|
+
'[@media(prefers-color-scheme:dark)]:[:root:not(.light)_&]:shadow-[inset_0_0_0_1px_rgb(255_255_255/0.24)]',
|
|
31
|
+
].join(' ')
|
|
32
|
+
|
|
33
|
+
export const TILE = 'inline-flex shrink-0 items-center justify-center bg-(--pick-bg) text-(--pick-fg)'
|
|
34
|
+
|
|
35
|
+
export const TILE_SIZE: Record<PickerTileSize, string> = {
|
|
36
|
+
xs: 'size-5 rounded-[5px] [&>svg]:size-3',
|
|
37
|
+
sm: 'size-7 rounded-md [&>svg]:size-4',
|
|
38
|
+
md: 'size-9 rounded-lg [&>svg]:size-5',
|
|
39
|
+
lg: 'size-12 rounded-xl [&>svg]:size-6',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const PLAIN = 'inline-flex shrink-0 items-center justify-center text-(--pick-fg)'
|
|
43
|
+
|
|
44
|
+
export const PLAIN_SIZE: Record<PickerTileSize, string> = {
|
|
45
|
+
xs: '[&>svg]:size-3',
|
|
46
|
+
sm: '[&>svg]:size-4',
|
|
47
|
+
md: '[&>svg]:size-5',
|
|
48
|
+
lg: '[&>svg]:size-6',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const DOT = 'inline-block shrink-0 rounded-full bg-(--pick-fg)'
|
|
52
|
+
|
|
53
|
+
export const DOT_SIZE: Record<PickerDotSize, string> = {
|
|
54
|
+
xs: 'size-2',
|
|
55
|
+
sm: 'size-2.5',
|
|
56
|
+
md: 'size-3.5',
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Focus on a cell is an outline, so it never fights the ring that marks the selected one. Tailwind
|
|
61
|
+
* v4's `outline-none` would pin the style to `none` under the focus width — `outline-hidden` plus an
|
|
62
|
+
* explicit `outline-solid` is what shows it.
|
|
63
|
+
*/
|
|
64
|
+
const CELL_FOCUS = [
|
|
65
|
+
'outline-hidden focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1',
|
|
66
|
+
'focus-visible:outline-ring',
|
|
67
|
+
].join(' ')
|
|
68
|
+
|
|
69
|
+
/** Below 768px and on a coarse pointer every control is at least 44px. */
|
|
70
|
+
const TOUCH_HEIGHT = 'max-md:h-11 pointer-coarse:h-11'
|
|
71
|
+
|
|
72
|
+
export const TRIGGER_BUTTON = [
|
|
73
|
+
'group/picker inline-flex h-9 w-full min-w-0 cursor-pointer items-center gap-2 rounded-md border border-input',
|
|
74
|
+
'bg-transparent py-1 pr-2.5 pl-1 text-left text-sm shadow-xs outline-none',
|
|
75
|
+
'transition-[color,box-shadow,background-color] hover:bg-accent/60 motion-reduce:transition-none',
|
|
76
|
+
'focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50',
|
|
77
|
+
'aria-expanded:border-ring aria-expanded:ring-[3px] aria-expanded:ring-ring/30',
|
|
78
|
+
'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
|
|
79
|
+
'max-md:h-11 max-md:pl-2 pointer-coarse:h-11 pointer-coarse:pl-2',
|
|
80
|
+
].join(' ')
|
|
81
|
+
|
|
82
|
+
export const TRIGGER_COMPACT = [
|
|
83
|
+
'inline-flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-lg outline-none',
|
|
84
|
+
'transition-shadow motion-reduce:transition-none',
|
|
85
|
+
'focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-expanded:ring-[3px] aria-expanded:ring-ring/30',
|
|
86
|
+
'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
|
|
87
|
+
'max-md:size-11 pointer-coarse:size-11',
|
|
88
|
+
].join(' ')
|
|
89
|
+
|
|
90
|
+
export const TRIGGER_DOT = 'rounded-full border border-input bg-transparent hover:bg-accent/60'
|
|
91
|
+
|
|
92
|
+
/** The empty tile of a trigger while nothing is chosen. */
|
|
93
|
+
export const TRIGGER_EMPTY = [
|
|
94
|
+
'inline-flex size-7 shrink-0 items-center justify-center rounded-md border border-dashed',
|
|
95
|
+
'border-muted-foreground/40 text-muted-foreground [&>svg]:size-4',
|
|
96
|
+
].join(' ')
|
|
97
|
+
|
|
98
|
+
export const CHEVRON = [
|
|
99
|
+
'ml-auto size-4 shrink-0 text-muted-foreground transition-transform motion-reduce:transition-none',
|
|
100
|
+
'group-aria-expanded/picker:rotate-180',
|
|
101
|
+
].join(' ')
|
|
102
|
+
|
|
103
|
+
export const POPOVER = [
|
|
104
|
+
'flex w-[23rem] max-w-[calc(100vw-1.5rem)] flex-col overflow-hidden rounded-xl border border-border p-0 shadow-lg',
|
|
105
|
+
'bg-popover text-popover-foreground',
|
|
106
|
+
'max-h-[min(34rem,var(--radix-popover-content-available-height))]',
|
|
107
|
+
// `!`: the primitive's `data-[state=open]:animate-in` outranks a plain variant class.
|
|
108
|
+
'pointer-coarse:w-[26rem] motion-reduce:animate-none! motion-reduce:transition-none!',
|
|
109
|
+
].join(' ')
|
|
110
|
+
|
|
111
|
+
export const SHEET = [
|
|
112
|
+
'mx-auto max-h-[88dvh] w-full gap-0 overflow-hidden rounded-t-2xl border-t border-border p-0',
|
|
113
|
+
'bg-popover text-popover-foreground pb-[env(safe-area-inset-bottom)]',
|
|
114
|
+
'sm:max-w-xl sm:border-x motion-reduce:animate-none! motion-reduce:transition-none!',
|
|
115
|
+
].join(' ')
|
|
116
|
+
|
|
117
|
+
/** With an icon grid the surface keeps one height, so filtering never makes it jump. */
|
|
118
|
+
export const TALL: Record<'popover' | 'sheet', string> = {
|
|
119
|
+
popover: 'h-[min(34rem,var(--radix-popover-content-available-height))]',
|
|
120
|
+
sheet: 'h-[88dvh]',
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The trigger's swatch disc for a colour-only picker — the colour as it was picked. */
|
|
124
|
+
export const TRIGGER_DISC = 'block size-4 shrink-0 rounded-full bg-(--pick-swatch)'
|
|
125
|
+
|
|
126
|
+
export const GRAB = 'mx-auto mt-2 mb-1 h-1.5 w-10 shrink-0 rounded-full bg-muted-foreground/30'
|
|
127
|
+
|
|
128
|
+
export const HEADER: Record<'popover' | 'sheet', string> = {
|
|
129
|
+
popover: 'flex shrink-0 items-center gap-3 border-b border-border px-3 py-2.5',
|
|
130
|
+
sheet: 'flex shrink-0 items-center gap-3 border-b border-border px-4 pt-1 pb-3',
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export const HEADER_TITLE = 'truncate text-sm font-semibold leading-5'
|
|
134
|
+
export const HEADER_SUMMARY = 'truncate text-xs leading-4 text-muted-foreground'
|
|
135
|
+
|
|
136
|
+
export const DONE = [
|
|
137
|
+
'inline-flex h-11 min-w-16 shrink-0 cursor-pointer items-center justify-center rounded-lg px-4',
|
|
138
|
+
'bg-primary text-sm font-medium text-primary-foreground outline-none hover:bg-primary/90',
|
|
139
|
+
'focus-visible:ring-[3px] focus-visible:ring-ring/50',
|
|
140
|
+
].join(' ')
|
|
141
|
+
|
|
142
|
+
export const BODY = 'min-h-0 flex-1 overflow-y-auto overscroll-contain'
|
|
143
|
+
|
|
144
|
+
export const SECTION: Record<'popover' | 'sheet', string> = {
|
|
145
|
+
popover: 'px-3 pt-3',
|
|
146
|
+
sheet: 'px-4 pt-4',
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export const SECTION_TITLE = 'mb-2 text-xs font-medium text-muted-foreground'
|
|
150
|
+
|
|
151
|
+
export const SWATCHES: Record<PickerLayout, string> = {
|
|
152
|
+
popover: [
|
|
153
|
+
'grid grid-cols-12 gap-1',
|
|
154
|
+
'max-md:grid-cols-[repeat(auto-fill,minmax(44px,1fr))] pointer-coarse:grid-cols-[repeat(auto-fill,minmax(44px,1fr))]',
|
|
155
|
+
].join(' '),
|
|
156
|
+
sheet: 'grid grid-cols-[repeat(auto-fill,minmax(44px,1fr))] gap-1.5',
|
|
157
|
+
inline: [
|
|
158
|
+
'grid grid-cols-[repeat(auto-fill,minmax(44px,1fr))] gap-1.5',
|
|
159
|
+
'md:pointer-fine:grid-cols-[repeat(12,minmax(0,2rem))] md:pointer-fine:gap-1',
|
|
160
|
+
].join(' '),
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const SWATCH = [
|
|
164
|
+
'group/swatch inline-flex aspect-square w-full min-w-0 cursor-pointer items-center justify-center rounded-full',
|
|
165
|
+
CELL_FOCUS,
|
|
166
|
+
].join(' ')
|
|
167
|
+
|
|
168
|
+
export const SWATCH_DISC = [
|
|
169
|
+
'pointer-events-none block size-[76%] max-h-9 max-w-9 rounded-full bg-(--pick-swatch)',
|
|
170
|
+
'transition-transform group-hover/swatch:scale-110 motion-reduce:transition-none motion-reduce:group-hover/swatch:scale-100',
|
|
171
|
+
HAIRLINE,
|
|
172
|
+
].join(' ')
|
|
173
|
+
|
|
174
|
+
export const SWATCH_SELECTED = 'ring-2 ring-foreground ring-offset-2 ring-offset-popover'
|
|
175
|
+
|
|
176
|
+
export const CUSTOM_ROW = [
|
|
177
|
+
'mt-2 flex h-8 w-full cursor-pointer items-center gap-2 rounded-md px-1.5 text-left text-sm',
|
|
178
|
+
'hover:bg-accent hover:text-accent-foreground',
|
|
179
|
+
'outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50',
|
|
180
|
+
TOUCH_HEIGHT,
|
|
181
|
+
].join(' ')
|
|
182
|
+
|
|
183
|
+
export const CUSTOM_DISC = 'block size-5 shrink-0 rounded-full'
|
|
184
|
+
|
|
185
|
+
/** The colour wheel's mark while no custom colour is chosen. */
|
|
186
|
+
export const RAINBOW = 'bg-[conic-gradient(from_180deg,#ef4444,#f59e0b,#eab308,#22c55e,#06b6d4,#3b82f6,#8b5cf6,#ec4899,#ef4444)]'
|
|
187
|
+
|
|
188
|
+
export const CUSTOM_PANEL = 'mt-2 flex flex-col gap-2'
|
|
189
|
+
|
|
190
|
+
/** A full six-digit value — committed while typing; a three-digit one waits for Enter or blur. */
|
|
191
|
+
export const FULL_HEX = /^#?[0-9a-f]{6}$/i
|
|
192
|
+
|
|
193
|
+
/** The wheel's colour while nothing custom is chosen yet — also the hex field's placeholder. */
|
|
194
|
+
export const CUSTOM_START = '#3b82f6'
|
|
195
|
+
|
|
196
|
+
/** react-colorful sizes itself with a stylesheet it injects; an inline size is the one that always wins. */
|
|
197
|
+
export const WHEEL_STYLE: CSSProperties = { width: '100%', height: 148 }
|
|
198
|
+
|
|
199
|
+
export const FIELD = [
|
|
200
|
+
'h-8 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 text-sm shadow-xs outline-none',
|
|
201
|
+
'placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50',
|
|
202
|
+
'aria-invalid:border-destructive aria-invalid:ring-destructive/20',
|
|
203
|
+
TOUCH_HEIGHT,
|
|
204
|
+
].join(' ')
|
|
205
|
+
|
|
206
|
+
export const HEX_FIELD = 'font-mono'
|
|
207
|
+
|
|
208
|
+
export const FIELD_ERROR = 'text-xs text-destructive'
|
|
209
|
+
|
|
210
|
+
/** The search field and the chips stay in view while the grid scrolls under them. */
|
|
211
|
+
export const ICON_TOOLS: Record<PickerLayout, string> = {
|
|
212
|
+
popover: 'sticky top-0 z-10 -mx-3 bg-popover px-3 pb-2',
|
|
213
|
+
sheet: 'sticky top-0 z-10 -mx-4 bg-popover px-4 pb-2',
|
|
214
|
+
inline: 'pb-2',
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export const SEARCH_WRAP = 'relative'
|
|
218
|
+
export const SEARCH_ICON = 'pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground'
|
|
219
|
+
export const SEARCH = 'pl-8 [&::-webkit-search-cancel-button]:cursor-pointer'
|
|
220
|
+
|
|
221
|
+
/** One scrolling row of category chips, running to the surface's edges rather than its padding. */
|
|
222
|
+
export const CHIPS: Record<PickerLayout, string> = {
|
|
223
|
+
popover: 'mt-2 -mx-3 flex gap-1.5 overflow-x-auto px-3 pb-0.5 scroll-px-3 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
|
|
224
|
+
sheet: 'mt-2 -mx-4 flex gap-1.5 overflow-x-auto px-4 pb-0.5 scroll-px-4 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
|
|
225
|
+
inline: 'mt-2 flex gap-1.5 overflow-x-auto pb-0.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export const CHIP = [
|
|
229
|
+
'inline-flex h-7 shrink-0 cursor-pointer items-center rounded-full border border-input px-2.5',
|
|
230
|
+
'text-xs font-medium text-muted-foreground transition-colors motion-reduce:transition-none',
|
|
231
|
+
'hover:bg-accent hover:text-accent-foreground',
|
|
232
|
+
'aria-pressed:border-transparent aria-pressed:bg-primary aria-pressed:text-primary-foreground',
|
|
233
|
+
CELL_FOCUS,
|
|
234
|
+
'max-md:h-11 max-md:px-4 max-md:text-sm pointer-coarse:h-11 pointer-coarse:px-4 pointer-coarse:text-sm',
|
|
235
|
+
].join(' ')
|
|
236
|
+
|
|
237
|
+
export const ICONS: Record<PickerLayout, string> = {
|
|
238
|
+
popover: [
|
|
239
|
+
'grid grid-cols-9 gap-0.5',
|
|
240
|
+
'max-md:grid-cols-[repeat(auto-fill,minmax(44px,1fr))] pointer-coarse:grid-cols-[repeat(auto-fill,minmax(44px,1fr))]',
|
|
241
|
+
].join(' '),
|
|
242
|
+
sheet: 'grid grid-cols-[repeat(auto-fill,minmax(44px,1fr))] gap-1',
|
|
243
|
+
inline: [
|
|
244
|
+
'grid grid-cols-[repeat(auto-fill,minmax(44px,1fr))] gap-1',
|
|
245
|
+
'md:pointer-fine:grid-cols-[repeat(auto-fill,minmax(36px,1fr))] md:pointer-fine:gap-0.5',
|
|
246
|
+
].join(' '),
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export const ICON_CELL = [
|
|
250
|
+
'inline-flex aspect-square w-full min-w-0 cursor-pointer items-center justify-center rounded-md text-(--pick-fg)',
|
|
251
|
+
'transition-colors hover:bg-accent motion-reduce:transition-none [&>svg]:size-5',
|
|
252
|
+
'aria-pressed:bg-(--pick-bg) aria-pressed:ring-2 aria-pressed:ring-(--pick-fg) aria-pressed:ring-inset',
|
|
253
|
+
CELL_FOCUS,
|
|
254
|
+
].join(' ')
|
|
255
|
+
|
|
256
|
+
export const ICON_GRID_PAD: Record<PickerLayout, string> = {
|
|
257
|
+
popover: 'pb-3',
|
|
258
|
+
sheet: 'pb-4',
|
|
259
|
+
inline: '',
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export const EMPTY = 'flex flex-col items-center gap-2 px-4 py-8 text-center text-sm text-muted-foreground'
|
|
263
|
+
|
|
264
|
+
export const LINK_BUTTON = [
|
|
265
|
+
'cursor-pointer rounded-sm text-sm font-medium text-foreground underline underline-offset-4',
|
|
266
|
+
'outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50',
|
|
267
|
+
].join(' ')
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FC } from 'react'
|
|
2
|
+
import { cn } from '../../@/lib/utils.js'
|
|
3
|
+
import { pickerColorHelper } from '../../picker/vocabulary.js'
|
|
4
|
+
import type { ColorDotProps } from './types.js'
|
|
5
|
+
import { DOT, DOT_SIZE, PICK_SCOPE } from './consts.local.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A stored colour as a dot, in the colour's ink — the ink keeps 3:1 on the page in both schemes,
|
|
9
|
+
* which a dot (a graphic) needs; the brighter swatch does not. Unknown → slate.
|
|
10
|
+
*/
|
|
11
|
+
export const ColorDot: FC<ColorDotProps> = ({ color, colors, size = 'sm', label, className }) =>
|
|
12
|
+
<span
|
|
13
|
+
data-color-dot
|
|
14
|
+
data-color={pickerColorHelper.resolve(color, colors)?.key}
|
|
15
|
+
role={label != null ? 'img' : undefined}
|
|
16
|
+
aria-label={label}
|
|
17
|
+
aria-hidden={label != null ? undefined : true}
|
|
18
|
+
title={label}
|
|
19
|
+
style={pickerColorHelper.styleOf(color, colors)}
|
|
20
|
+
className={cn(PICK_SCOPE, DOT, DOT_SIZE[size], className)}
|
|
21
|
+
/>
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { useMemo, useRef, useState } from 'react'
|
|
2
|
+
import type { FC, KeyboardEvent } from 'react'
|
|
3
|
+
import { SearchIcon, SearchXIcon } from 'lucide-react'
|
|
4
|
+
import { cn } from '../../@/lib/utils.js'
|
|
5
|
+
import { pickerIconHelper } from '../../picker/icons.js'
|
|
6
|
+
import { pickerColorHelper } from '../../picker/vocabulary.js'
|
|
7
|
+
import { PICKER_COLORS, PICKER_ICON_CATEGORIES } from '../../picker/vocabulary/consts.js'
|
|
8
|
+
import type { PickerIconCategory } from '../../picker/vocabulary/types.js'
|
|
9
|
+
import type { IconGridProps } from './types.js'
|
|
10
|
+
import type { IconBrowserProps } from './types.local.js'
|
|
11
|
+
import { useRovingGrid } from './roving.js'
|
|
12
|
+
import { makePickerText } from './text.js'
|
|
13
|
+
import {
|
|
14
|
+
CHIP, CHIPS, EMPTY, FIELD, ICON_CELL, ICON_TOOLS, ICONS, LINK_BUTTON, PICK_SCOPE, SEARCH, SEARCH_ICON, SEARCH_WRAP,
|
|
15
|
+
} from './consts.local.js'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The searchable icon grid every picker shares: a search field, category chips and the icons,
|
|
19
|
+
* tinted in the chosen colour. The search field and the chips stay put while the grid scrolls;
|
|
20
|
+
* ArrowDown (or Enter) moves from the field into the grid, ArrowUp from the grid's first row back.
|
|
21
|
+
* An empty result says so and offers to clear; the result count is announced politely.
|
|
22
|
+
*/
|
|
23
|
+
export const IconBrowser: FC<IconBrowserProps> = (
|
|
24
|
+
{ value, onChange, color, colors, icons, text, layout, label, searchRef, className }
|
|
25
|
+
) => {
|
|
26
|
+
const [query, setQuery] = useState('')
|
|
27
|
+
const [category, setCategory] = useState<PickerIconCategory | null>(null)
|
|
28
|
+
const search = useRef<HTMLInputElement | null>(null)
|
|
29
|
+
|
|
30
|
+
const categories = useMemo(() => {
|
|
31
|
+
const scope = pickerIconHelper.search('', icons)
|
|
32
|
+
|
|
33
|
+
return PICKER_ICON_CATEGORIES.filter(candidate => scope.some(entry => entry.category === candidate))
|
|
34
|
+
}, [icons])
|
|
35
|
+
const results = useMemo(
|
|
36
|
+
() => pickerIconHelper.search(query, icons).filter(entry => category == null || entry.category === category),
|
|
37
|
+
[query, icons, category]
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
const grid = useRovingGrid({
|
|
41
|
+
count: results.length,
|
|
42
|
+
selected: results.findIndex(entry => entry.name === value),
|
|
43
|
+
onExitUp: () => search.current?.focus(),
|
|
44
|
+
})
|
|
45
|
+
const chips = useRovingGrid({
|
|
46
|
+
count: categories.length + 1,
|
|
47
|
+
selected: category == null ? 0 : categories.indexOf(category) + 1,
|
|
48
|
+
grid: false,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const bindSearch = (node: HTMLInputElement | null): void => {
|
|
52
|
+
search.current = node
|
|
53
|
+
if (typeof searchRef === 'function') {
|
|
54
|
+
searchRef(node)
|
|
55
|
+
} else if (searchRef != null) {
|
|
56
|
+
searchRef.current = node
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const onSearchKey = (event: KeyboardEvent<HTMLInputElement>): void => {
|
|
61
|
+
if (event.key === 'ArrowDown' || event.key === 'Enter') {
|
|
62
|
+
// Enter must never submit the form the grid sits in.
|
|
63
|
+
event.preventDefault()
|
|
64
|
+
grid.focusCurrent()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const filtered = query.trim() !== '' || category != null
|
|
69
|
+
|
|
70
|
+
return <div
|
|
71
|
+
data-picker-icons style={pickerColorHelper.styleOf(color, colors)} className={cn(PICK_SCOPE, className)}
|
|
72
|
+
>
|
|
73
|
+
<div className={ICON_TOOLS[layout]}>
|
|
74
|
+
<div className={SEARCH_WRAP}>
|
|
75
|
+
<SearchIcon aria-hidden="true" className={SEARCH_ICON} />
|
|
76
|
+
<input
|
|
77
|
+
ref={bindSearch} type="search" data-picker-search autoComplete="off" spellCheck={false} enterKeyHint="search"
|
|
78
|
+
aria-label={text.text('search', 'Search icons')} placeholder={text.text('searchPlaceholder', 'Search icons…')}
|
|
79
|
+
value={query} onChange={event => setQuery(event.target.value)} onKeyDown={onSearchKey}
|
|
80
|
+
className={cn(FIELD, SEARCH)}
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
83
|
+
{categories.length > 1 && <div
|
|
84
|
+
ref={chips.ref} role="group" aria-label={text.text('categoriesLabel', 'Categories')} onKeyDown={chips.onKeyDown}
|
|
85
|
+
className={CHIPS[layout]}
|
|
86
|
+
>
|
|
87
|
+
{[null, ...categories].map((candidate, index) => {
|
|
88
|
+
const name = candidate == null ? text.text('all', 'All') : text.category(candidate)
|
|
89
|
+
|
|
90
|
+
return <button
|
|
91
|
+
key={candidate ?? 'all'} type="button" data-roving-item data-picker-category={candidate ?? 'all'}
|
|
92
|
+
aria-label={name} aria-pressed={category === candidate} tabIndex={chips.tabIndexOf(index)}
|
|
93
|
+
onFocus={() => chips.setCurrent(index)} onClick={() => setCategory(candidate)} className={CHIP}
|
|
94
|
+
>{name}</button>
|
|
95
|
+
})}
|
|
96
|
+
</div>}
|
|
97
|
+
</div>
|
|
98
|
+
<p className="sr-only" aria-live="polite">{filtered ? text.count(results.length) : ''}</p>
|
|
99
|
+
{results.length > 0
|
|
100
|
+
? <div ref={grid.ref} role="group" aria-label={label} onKeyDown={grid.onKeyDown} className={ICONS[layout]}>
|
|
101
|
+
{results.map((entry, index) => {
|
|
102
|
+
const Icon = pickerIconHelper.iconOf(entry.name)
|
|
103
|
+
const name = text.icon(entry.name)
|
|
104
|
+
|
|
105
|
+
return <button
|
|
106
|
+
key={entry.name} type="button" data-roving-item data-picker-icon={entry.name}
|
|
107
|
+
aria-label={name} aria-pressed={entry.name === value} title={name}
|
|
108
|
+
tabIndex={grid.tabIndexOf(index)} onFocus={() => grid.setCurrent(index)}
|
|
109
|
+
onClick={() => onChange(entry.name)} className={ICON_CELL}
|
|
110
|
+
><Icon aria-hidden="true" /></button>
|
|
111
|
+
})}
|
|
112
|
+
</div>
|
|
113
|
+
: <div data-picker-empty className={EMPTY}>
|
|
114
|
+
<SearchXIcon aria-hidden="true" className="size-6" />
|
|
115
|
+
<p>{text.empty(query.trim())}</p>
|
|
116
|
+
<button
|
|
117
|
+
type="button" aria-label={text.text('clear', 'Clear search')} className={LINK_BUTTON}
|
|
118
|
+
onClick={() => { setQuery(''); setCategory(null); search.current?.focus() }}
|
|
119
|
+
>{text.text('clear', 'Clear search')}</button>
|
|
120
|
+
</div>}
|
|
121
|
+
</div>
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The searchable icon grid inline — for a dialog or sheet the application already owns. Commits
|
|
126
|
+
* on click; `color` tints it, `icons` narrows (and orders) the catalogue. Strings through
|
|
127
|
+
* `translate` (English without it — never an implicit i18n read).
|
|
128
|
+
*/
|
|
129
|
+
export const IconGrid: FC<IconGridProps> = (
|
|
130
|
+
{ value, onChange, color, colors = PICKER_COLORS, icons, translate, label, className }
|
|
131
|
+
) => {
|
|
132
|
+
const text = useMemo(() => makePickerText(translate), [translate])
|
|
133
|
+
|
|
134
|
+
return <IconBrowser
|
|
135
|
+
value={value} onChange={onChange} color={color} colors={colors} icons={icons} text={text} layout="inline"
|
|
136
|
+
label={label ?? text.text('icon', 'Icon')} className={className}
|
|
137
|
+
/>
|
|
138
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"label": "Значок і колер",
|
|
3
|
+
"icon": "Значок",
|
|
4
|
+
"color": "Колер",
|
|
5
|
+
"placeholder": {
|
|
6
|
+
"both": "Выберыце значок і колер",
|
|
7
|
+
"icon": "Выберыце значок",
|
|
8
|
+
"color": "Выберыце колер"
|
|
9
|
+
},
|
|
10
|
+
"nothing": "Нічога не выбрана",
|
|
11
|
+
"done": "Гатова",
|
|
12
|
+
"search": "Пошук значкоў",
|
|
13
|
+
"searchPlaceholder": "Пошук значкоў…",
|
|
14
|
+
"categoriesLabel": "Катэгорыі",
|
|
15
|
+
"all": "Усе",
|
|
16
|
+
"results": "Знойдзена значкоў: {count}",
|
|
17
|
+
"empty": "Няма значкоў па запыце «{query}»",
|
|
18
|
+
"clear": "Ачысціць пошук",
|
|
19
|
+
"custom": "Свой колер",
|
|
20
|
+
"hex": "Колер у фармаце HEX",
|
|
21
|
+
"invalidHex": "Увядзіце колер, напрыклад #3b82f6",
|
|
22
|
+
"colors": {
|
|
23
|
+
"red": "Чырвоны",
|
|
24
|
+
"orange": "Аранжавы",
|
|
25
|
+
"amber": "Бурштынавы",
|
|
26
|
+
"yellow": "Жоўты",
|
|
27
|
+
"lime": "Лаймавы",
|
|
28
|
+
"green": "Зялёны",
|
|
29
|
+
"emerald": "Смарагдавы",
|
|
30
|
+
"teal": "Бірузовы",
|
|
31
|
+
"cyan": "Цыян",
|
|
32
|
+
"sky": "Нябесны",
|
|
33
|
+
"blue": "Сіні",
|
|
34
|
+
"indigo": "Індыга",
|
|
35
|
+
"violet": "Фіялетавы",
|
|
36
|
+
"purple": "Пурпурны",
|
|
37
|
+
"fuchsia": "Фуксія",
|
|
38
|
+
"pink": "Ружовы",
|
|
39
|
+
"rose": "Малінавы",
|
|
40
|
+
"maroon": "Бардовы",
|
|
41
|
+
"brown": "Карычневы",
|
|
42
|
+
"olive": "Аліўкавы",
|
|
43
|
+
"navy": "Цёмна-сіні",
|
|
44
|
+
"slate": "Сланцавы",
|
|
45
|
+
"stone": "Каменны",
|
|
46
|
+
"graphite": "Графітавы"
|
|
47
|
+
},
|
|
48
|
+
"categories": {
|
|
49
|
+
"work": "Праца",
|
|
50
|
+
"people": "Людзі",
|
|
51
|
+
"communication": "Зносіны",
|
|
52
|
+
"commerce": "Гандаль",
|
|
53
|
+
"operations": "Аперацыі",
|
|
54
|
+
"places": "Месцы",
|
|
55
|
+
"tech": "Тэхналогіі",
|
|
56
|
+
"status": "Статусы",
|
|
57
|
+
"objects": "Прадметы",
|
|
58
|
+
"nature": "Прырода"
|
|
59
|
+
}
|
|
60
|
+
}
|