@supersoniks/concorde 5.1.0 → 5.1.2
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/.agents/skills/concorde-docs/SKILL.md +153 -0
- package/.agents/skills/{concorde-component-docs/template.md → concorde-docs/templates/component.md} +6 -2
- package/.agents/skills/concorde-docs/templates/decorator.md +43 -0
- package/.agents/skills/concorde-docs/templates/guide.md +25 -0
- package/.claude/launch.json +15 -0
- package/.claude/vite.http.config.mjs +7 -0
- package/.taste-skill/after/desktop-fold.jpg +0 -0
- package/.taste-skill/after/desktop-page-01.jpg +0 -0
- package/.taste-skill/after/desktop-page-02.jpg +0 -0
- package/.taste-skill/after/desktop-page-03.jpg +0 -0
- package/.taste-skill/after/mobile-fold.jpg +0 -0
- package/.taste-skill/after/mobile-page-01.jpg +0 -0
- package/.taste-skill/after/report.json +4103 -0
- package/.taste-skill/after/tablet-fold.jpg +0 -0
- package/.taste-skill/after/tablet-page-01.jpg +0 -0
- package/.taste-skill/after/tablet-page-02.jpg +0 -0
- package/.taste-skill/before/desktop-fold.jpg +0 -0
- package/.taste-skill/before/desktop-page-01.jpg +0 -0
- package/.taste-skill/before/desktop-page-02.jpg +0 -0
- package/.taste-skill/before/mobile-fold.jpg +0 -0
- package/.taste-skill/before/mobile-page-01.jpg +0 -0
- package/.taste-skill/before/report.json +2556 -0
- package/.taste-skill/before/tablet-fold.jpg +0 -0
- package/.taste-skill/before/tablet-page-01.jpg +0 -0
- package/.taste-skill/direction.json +510 -0
- package/.taste-skill/notes.md +84 -0
- package/.taste-skill/prod/desktop-fold.jpg +0 -0
- package/.taste-skill/prod/desktop-page-01.jpg +0 -0
- package/.taste-skill/prod/desktop-page-02.jpg +0 -0
- package/.taste-skill/prod/desktop-page-03.jpg +0 -0
- package/.taste-skill/prod/mobile-fold.jpg +0 -0
- package/.taste-skill/prod/mobile-page-01.jpg +0 -0
- package/.taste-skill/prod/mobile-page-02.jpg +0 -0
- package/.taste-skill/prod/report.json +1973 -0
- package/.taste-skill/prod/tablet-fold.jpg +0 -0
- package/.taste-skill/prod/tablet-page-01.jpg +0 -0
- package/.taste-skill/prod/tablet-page-02.jpg +0 -0
- package/.tmp-cem/custom-elements.json +2013 -2013
- package/AUDIT.md +228 -0
- package/PLAN-AMELIORATION.md +220 -0
- package/PLAN-DOCS-AGENTS.md +80 -0
- package/README.md +3 -3
- package/ai/skills/concorde/SKILL.md +1 -1
- package/ai/skills/concorde-get-set-dp/SKILL.md +3 -3
- package/ai/skills/concorde-theme/SKILL.md +1 -1
- package/build-infos.json +1 -1
- package/concorde-core.bundle.js +16 -16
- package/concorde-core.es.js +235 -233
- package/dist/concorde-core.bundle.js +16 -16
- package/dist/concorde-core.es.js +235 -233
- package/dist/img/archive/concorde-001-2cv.webp +0 -0
- package/dist/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
- package/dist/img/archive/concorde-red-arrows-2002.webm +0 -0
- package/dist/img/archive/credits.json +28 -0
- package/docs/.htaccess +75 -0
- package/docs/404.html +15 -0
- package/docs/404.md +5 -0
- package/docs/assets/index-BgG6FFPt.js +11765 -0
- package/docs/assets/index-x89XINSG.css +1 -0
- package/docs/core/components/functional/date/date.html +211 -0
- package/docs/core/components/functional/date/date.md +150 -0
- package/docs/core/components/functional/fetch/fetch.html +180 -0
- package/docs/core/components/functional/fetch/fetch.md +108 -0
- package/docs/core/components/functional/if/if.html +65 -0
- package/docs/core/components/functional/if/if.md +34 -0
- package/docs/core/components/functional/jsonata/jsonata.html +110 -0
- package/docs/core/components/functional/jsonata/jsonata.md +61 -0
- package/docs/core/components/functional/list/list.html +198 -0
- package/docs/core/components/functional/list/list.md +121 -0
- package/docs/core/components/functional/mix/mix.html +78 -0
- package/docs/core/components/functional/mix/mix.md +46 -0
- package/docs/core/components/functional/queue/queue.html +155 -0
- package/docs/core/components/functional/queue/queue.md +51 -0
- package/docs/core/components/functional/router/router.html +154 -0
- package/docs/core/components/functional/router/router.md +93 -0
- package/docs/core/components/functional/sdui/sdui-extension-points.html +127 -0
- package/docs/core/components/functional/sdui/sdui-extension-points.md +94 -0
- package/docs/core/components/functional/sdui/sdui.html +397 -0
- package/docs/core/components/functional/sdui/sdui.md +307 -0
- package/docs/core/components/functional/states/states.html +141 -0
- package/docs/core/components/functional/states/states.md +112 -0
- package/docs/core/components/functional/submit/submit.html +178 -0
- package/docs/core/components/functional/submit/submit.md +106 -0
- package/docs/{crawl/core → core}/components/functional/subscriber/subscriber.html +6 -5
- package/docs/core/components/functional/subscriber/subscriber.md +91 -0
- package/docs/core/components/functional/translation/translation.html +60 -0
- package/docs/core/components/functional/translation/translation.md +38 -0
- package/docs/core/components/functional/value/value.html +81 -0
- package/docs/core/components/functional/value/value.md +47 -0
- package/docs/core/components/ui/alert/alert.html +201 -0
- package/docs/core/components/ui/alert/alert.md +186 -0
- package/docs/core/components/ui/alert-messages/alert-messages.html +132 -0
- package/docs/core/components/ui/alert-messages/alert-messages.md +85 -0
- package/docs/core/components/ui/badge/badge.html +197 -0
- package/docs/core/components/ui/badge/badge.md +181 -0
- package/docs/core/components/ui/button/button.html +309 -0
- package/docs/core/components/ui/button/button.md +216 -0
- package/docs/core/components/ui/captcha/captcha.html +80 -0
- package/docs/core/components/ui/captcha/captcha.md +56 -0
- package/docs/core/components/ui/card/card.html +254 -0
- package/docs/core/components/ui/card/card.md +215 -0
- package/docs/core/components/ui/divider/divider.html +144 -0
- package/docs/core/components/ui/divider/divider.md +126 -0
- package/docs/core/components/ui/form/checkbox/checkbox.html +200 -0
- package/docs/core/components/ui/form/checkbox/checkbox.md +125 -0
- package/docs/core/components/ui/form/fieldset/fieldset.html +238 -0
- package/docs/core/components/ui/form/fieldset/fieldset.md +161 -0
- package/docs/core/components/ui/form/form-actions/form-actions.html +122 -0
- package/docs/core/components/ui/form/form-actions/form-actions.md +98 -0
- package/docs/core/components/ui/form/form-layout/form-layout.html +115 -0
- package/docs/core/components/ui/form/form-layout/form-layout.md +109 -0
- package/docs/core/components/ui/form/input/input.html +235 -0
- package/docs/core/components/ui/form/input/input.md +142 -0
- package/docs/core/components/ui/form/radio/radio.html +144 -0
- package/docs/core/components/ui/form/radio/radio.md +78 -0
- package/docs/core/components/ui/form/select/select.html +178 -0
- package/docs/core/components/ui/form/select/select.md +86 -0
- package/docs/core/components/ui/form/switch/switch.html +146 -0
- package/docs/core/components/ui/form/switch/switch.md +80 -0
- package/docs/core/components/ui/form/textarea/textarea.html +162 -0
- package/docs/core/components/ui/form/textarea/textarea.md +82 -0
- package/docs/core/components/ui/group/group.html +113 -0
- package/docs/core/components/ui/group/group.md +77 -0
- package/docs/core/components/ui/icon/icon.html +223 -0
- package/docs/core/components/ui/icon/icon.md +214 -0
- package/docs/core/components/ui/image/image.html +194 -0
- package/docs/core/components/ui/image/image.md +167 -0
- package/docs/core/components/ui/link/link.html +101 -0
- package/docs/core/components/ui/link/link.md +81 -0
- package/docs/core/components/ui/loader/loader.html +114 -0
- package/docs/core/components/ui/loader/loader.md +87 -0
- package/docs/{crawl/core → core}/components/ui/menu/menu.html +189 -116
- package/docs/core/components/ui/menu/menu.md +370 -0
- package/docs/core/components/ui/modal/modal.html +324 -0
- package/docs/core/components/ui/modal/modal.md +211 -0
- package/docs/core/components/ui/pop/pop.html +250 -0
- package/docs/core/components/ui/pop/pop.md +216 -0
- package/docs/core/components/ui/progress/progress.html +132 -0
- package/docs/core/components/ui/progress/progress.md +109 -0
- package/docs/core/components/ui/table/table.html +333 -0
- package/docs/core/components/ui/table/table.md +267 -0
- package/docs/core/components/ui/theme/theme.html +116 -0
- package/docs/core/components/ui/theme/theme.md +97 -0
- package/docs/core/components/ui/toast/toast.html +185 -0
- package/docs/core/components/ui/toast/toast.md +147 -0
- package/docs/core/components/ui/tooltip/tooltip.html +112 -0
- package/docs/core/components/ui/tooltip/tooltip.md +89 -0
- package/docs/docs/decorators/ancestor-attribute.html +71 -0
- package/docs/docs/decorators/ancestor-attribute.md +59 -0
- package/docs/docs/decorators/auto-subscribe.html +61 -0
- package/docs/docs/decorators/auto-subscribe.md +40 -0
- package/docs/docs/decorators/bind.html +86 -0
- package/docs/docs/decorators/bind.md +77 -0
- package/docs/docs/decorators/get.html +166 -0
- package/docs/docs/decorators/get.md +160 -0
- package/docs/docs/decorators/handle.html +139 -0
- package/docs/docs/decorators/handle.md +119 -0
- package/docs/docs/decorators/on-assign.html +72 -0
- package/docs/docs/decorators/on-assign.md +63 -0
- package/docs/docs/decorators/patch.html +76 -0
- package/docs/docs/decorators/patch.md +44 -0
- package/docs/docs/decorators/post.html +150 -0
- package/docs/docs/decorators/post.md +134 -0
- package/docs/docs/decorators/publish.html +74 -0
- package/docs/docs/decorators/publish.md +56 -0
- package/docs/docs/decorators/put.html +83 -0
- package/docs/docs/decorators/put.md +51 -0
- package/docs/docs/decorators/subscribe.html +91 -0
- package/docs/docs/decorators/subscribe.md +87 -0
- package/docs/docs/decorators/wait-for-ancestors.html +82 -0
- package/docs/docs/decorators/wait-for-ancestors.md +76 -0
- package/docs/docs/directives/sub.html +79 -0
- package/docs/docs/directives/sub.md +75 -0
- package/docs/docs/directives/t.html +91 -0
- package/docs/docs/directives/t.md +73 -0
- package/docs/{crawl/docs/_getting-started → docs/getting-started}/ai-agents.html +12 -11
- package/{src/docs/_getting-started → docs/docs/getting-started}/ai-agents.md +3 -3
- package/docs/docs/getting-started/components.html +27 -0
- package/docs/docs/getting-started/components.md +5 -0
- package/docs/{crawl/docs/_getting-started → docs/getting-started}/create-a-component.html +11 -14
- package/docs/{src/docs/_getting-started → docs/getting-started}/create-a-component.md +3 -6
- package/docs/{crawl/docs/_core-concept → docs/getting-started}/dataFlow.html +26 -29
- package/docs/{src/docs/_core-concept → docs/getting-started}/dataFlow.md +17 -18
- package/docs/docs/getting-started/installation.html +69 -0
- package/docs/docs/getting-started/installation.md +36 -0
- package/docs/{crawl/docs/_getting-started → docs/getting-started}/my-first-component.html +13 -22
- package/docs/{src/docs/_getting-started → docs/getting-started}/my-first-component.md +5 -14
- package/docs/docs/getting-started/start.html +47 -0
- package/{src/docs/_getting-started → docs/docs/getting-started}/start.md +1 -13
- package/docs/docs/getting-started/theming.html +334 -0
- package/{src/docs/_getting-started → docs/docs/getting-started}/theming.md +2 -2
- package/docs/docs/index.html +99 -0
- package/docs/{crawl/docs/_misc → docs/misc}/api-configuration.html +18 -18
- package/docs/{src/docs/_misc → docs/misc}/api-configuration.md +10 -12
- package/docs/{crawl/docs/_misc → docs/misc}/dataProviderKey.html +12 -11
- package/{src/docs/_misc → docs/docs/misc}/dataProviderKey.md +4 -4
- package/docs/{crawl/docs/_misc → docs/misc}/docs-mock-api.html +25 -28
- package/docs/{src/docs/_misc → docs/misc}/docs-mock-api.md +12 -13
- package/docs/{crawl/docs/_misc → docs/misc}/dynamic-path.html +16 -15
- package/{src/docs/_misc → docs/docs/misc}/dynamic-path.md +8 -8
- package/docs/{crawl/docs/_misc → docs/misc}/endpoint.html +16 -15
- package/{src/docs/_misc → docs/docs/misc}/endpoint.md +8 -8
- package/docs/{crawl/docs/_misc → docs/misc}/html-integration.html +12 -15
- package/docs/{src/docs/_misc → docs/misc}/html-integration.md +4 -5
- package/docs/docs-mock-api-sw.js +60 -223
- package/docs/docs-mock-api-sw.js.map +4 -4
- package/docs/hubs/decorators.html +443 -0
- package/docs/hubs/form-components.html +404 -0
- package/docs/hubs/remote-data.html +371 -0
- package/docs/img/archive/concorde-001-2cv.webp +0 -0
- package/docs/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
- package/docs/img/archive/concorde-red-arrows-2002.webm +0 -0
- package/docs/img/archive/credits.json +28 -0
- package/docs/img/concorde/plane_01.jpg +0 -0
- package/docs/img/concorde/plane_02.jpg +0 -0
- package/docs/img/concorde/plane_03.jpg +0 -0
- package/docs/img/concorde/plane_04.jpg +0 -0
- package/docs/img/concorde/plane_05.jpg +0 -0
- package/docs/img/concorde/plane_06.jpg +0 -0
- package/docs/img/concorde/plane_07.jpg +0 -0
- package/docs/img/concorde/plane_08.jpg +0 -0
- package/docs/img/concorde/plane_09.jpg +0 -0
- package/docs/img/concorde/plane_10.jpg +0 -0
- package/docs/img/concorde/plane_11.jpg +0 -0
- package/docs/img/concorde/plane_12.jpg +0 -0
- package/docs/img/concorde/plane_13.jpg +0 -0
- package/docs/index.html +96 -67
- package/docs/index.md +22 -0
- package/docs/llms-full.txt +3329 -3295
- package/docs/llms.txt +94 -92
- package/docs/robots.txt +11 -10
- package/docs/sitemap.xml +78 -78
- package/docs/src/core/components/functional/date/date.md +91 -231
- package/docs/src/core/components/functional/fetch/fetch.md +66 -83
- package/docs/src/core/components/functional/if/if.md +28 -3
- package/docs/src/core/components/functional/jsonata/jsonata.md +42 -37
- package/docs/src/core/components/functional/list/list.md +99 -43
- package/docs/src/core/components/functional/mix/mix.md +31 -26
- package/docs/src/core/components/functional/queue/queue.md +40 -61
- package/docs/src/core/components/functional/router/router.md +64 -65
- package/docs/src/core/components/functional/sdui/component-catalog.gaps.json +511 -0
- package/docs/src/core/components/functional/sdui/component-catalog.json +3103 -0
- package/docs/src/core/components/functional/sdui/example.json +19 -86
- package/docs/src/core/components/functional/sdui/sdui-extension-points.md +94 -0
- package/docs/src/core/components/functional/sdui/sdui.md +196 -245
- package/docs/src/core/components/functional/states/states.md +86 -61
- package/docs/src/core/components/functional/submit/submit.md +64 -72
- package/docs/src/core/components/functional/translation/translation.md +38 -0
- package/docs/src/core/components/functional/value/value.md +34 -22
- package/docs/src/core/components/ui/alert/alert.md +139 -74
- package/docs/src/core/components/ui/alert-messages/alert-messages.md +85 -0
- package/docs/src/core/components/ui/badge/badge.md +137 -83
- package/docs/src/core/components/ui/button/button.md +139 -105
- package/docs/src/core/components/ui/captcha/captcha.md +50 -6
- package/docs/src/core/components/ui/card/card.md +183 -65
- package/docs/src/core/components/ui/divider/divider.md +104 -13
- package/docs/src/core/components/ui/form/checkbox/checkbox.md +90 -42
- package/docs/src/core/components/ui/form/fieldset/fieldset.md +135 -103
- package/docs/src/core/components/ui/form/form-actions/form-actions.md +71 -50
- package/docs/src/core/components/ui/form/form-layout/form-layout.md +99 -34
- package/docs/src/core/components/ui/form/input/input.md +95 -95
- package/docs/src/core/components/ui/form/radio/radio.md +55 -34
- package/docs/src/core/components/ui/form/select/select.md +60 -45
- package/docs/src/core/components/ui/form/switch/switch.md +57 -34
- package/docs/src/core/components/ui/form/textarea/textarea.md +55 -38
- package/docs/src/core/components/ui/group/group.md +49 -47
- package/docs/src/core/components/ui/icon/icon.md +132 -43
- package/docs/src/core/components/ui/image/image.md +132 -72
- package/docs/src/core/components/ui/link/link.md +46 -8
- package/docs/src/core/components/ui/loader/loader.md +55 -23
- package/docs/src/core/components/ui/menu/menu.md +155 -114
- package/docs/src/core/components/ui/modal/modal.md +154 -62
- package/docs/src/core/components/ui/pop/pop.md +185 -65
- package/docs/src/core/components/ui/progress/progress.md +76 -30
- package/docs/src/core/components/ui/table/table.md +146 -334
- package/docs/src/core/components/ui/theme/theme.md +97 -0
- package/docs/src/core/components/ui/toast/toast.md +80 -99
- package/docs/src/core/components/ui/tooltip/tooltip.md +52 -45
- package/docs/src/docs/decorators/ancestor-attribute.md +59 -0
- package/docs/src/docs/decorators/auto-subscribe.md +40 -0
- package/docs/src/docs/decorators/bind.md +77 -0
- package/docs/src/docs/decorators/get.md +160 -0
- package/docs/src/docs/decorators/handle.md +119 -0
- package/docs/src/docs/decorators/on-assign.md +63 -0
- package/docs/src/docs/decorators/patch.md +44 -0
- package/docs/src/docs/decorators/post.md +134 -0
- package/docs/src/docs/decorators/publish.md +56 -0
- package/docs/src/docs/decorators/put.md +51 -0
- package/docs/src/docs/decorators/subscribe.md +87 -0
- package/docs/src/docs/decorators/wait-for-ancestors.md +76 -0
- package/docs/src/docs/directives/sub.md +75 -0
- package/docs/src/docs/directives/t.md +73 -0
- package/docs/src/docs/{_getting-started → getting-started}/ai-agents.md +3 -3
- package/docs/src/docs/getting-started/components.md +5 -0
- package/{src/docs/_getting-started → docs/src/docs/getting-started}/create-a-component.md +3 -6
- package/{src/docs/_core-concept → docs/src/docs/getting-started}/dataFlow.md +17 -18
- package/docs/src/docs/getting-started/installation.md +36 -0
- package/{src/docs/_getting-started → docs/src/docs/getting-started}/my-first-component.md +5 -14
- package/docs/src/docs/getting-started/start.md +35 -0
- package/docs/src/docs/getting-started/theming.md +253 -0
- package/{src/docs/_misc → docs/src/docs/misc}/api-configuration.md +10 -12
- package/docs/src/docs/{_misc → misc}/dataProviderKey.md +4 -4
- package/{src/docs/_misc → docs/src/docs/misc}/docs-mock-api.md +12 -13
- package/docs/src/docs/{_misc → misc}/dynamic-path.md +8 -8
- package/docs/src/docs/{_misc → misc}/endpoint.md +8 -8
- package/{src/docs/_misc → docs/src/docs/misc}/html-integration.md +4 -5
- package/docs/src/docs/search/docs-search.json +3729 -2949
- package/docs/src/tsconfig.json +176 -5
- package/index.html +94 -67
- package/package.json +11 -4
- package/public/docs-mock-api-sw.js +58 -223
- package/public/docs-mock-api-sw.js.map +4 -4
- package/public/img/archive/concorde-001-2cv.webp +0 -0
- package/public/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
- package/public/img/archive/concorde-red-arrows-2002.webm +0 -0
- package/public/img/archive/credits.json +28 -0
- package/public/img/concorde/plane_01.jpg +0 -0
- package/public/img/concorde/plane_02.jpg +0 -0
- package/public/img/concorde/plane_03.jpg +0 -0
- package/public/img/concorde/plane_04.jpg +0 -0
- package/public/img/concorde/plane_05.jpg +0 -0
- package/public/img/concorde/plane_06.jpg +0 -0
- package/public/img/concorde/plane_07.jpg +0 -0
- package/public/img/concorde/plane_08.jpg +0 -0
- package/public/img/concorde/plane_09.jpg +0 -0
- package/public/img/concorde/plane_10.jpg +0 -0
- package/public/img/concorde/plane_11.jpg +0 -0
- package/public/img/concorde/plane_12.jpg +0 -0
- package/public/img/concorde/plane_13.jpg +0 -0
- package/public/robots.txt +11 -10
- package/scripts/docs-markdown-vite-plugin.ts +37 -0
- package/scripts/docs-public-url.mjs +50 -0
- package/scripts/docs.htaccess +75 -0
- package/scripts/generate-crawl-docs.mjs +207 -116
- package/scripts/generate-crawl-docs.test.mjs +124 -0
- package/scripts/post-build-docs.js +34 -50
- package/scripts/post-build.mjs +0 -0
- package/src/core/components/functional/date/date.md +91 -231
- package/src/core/components/functional/fetch/fetch.md +66 -83
- package/src/core/components/functional/if/if.md +28 -3
- package/src/core/components/functional/if/if.ts +0 -0
- package/src/core/components/functional/jsonata/jsonata.md +42 -37
- package/src/core/components/functional/list/list.demo.ts +0 -0
- package/src/core/components/functional/list/list.md +99 -43
- package/src/core/components/functional/mix/mix.md +31 -26
- package/src/core/components/functional/queue/queue.demo.ts +10 -7
- package/src/core/components/functional/queue/queue.md +40 -61
- package/src/core/components/functional/router/router.demo.ts +16 -16
- package/src/core/components/functional/router/router.md +64 -65
- package/src/core/components/functional/router/router.ts +0 -0
- package/src/core/components/functional/sdui/SDUIDescriptorTransformer.ts +0 -0
- package/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
- package/src/core/components/functional/sdui/component-catalog.json +1 -1
- package/src/core/components/functional/sdui/example.json +19 -86
- package/src/core/components/functional/sdui/sdui-extension-points.md +1 -1
- package/src/core/components/functional/sdui/sdui.md +187 -358
- package/src/core/components/functional/sdui/types.ts +0 -0
- package/src/core/components/functional/states/states.demo.ts +21 -22
- package/src/core/components/functional/states/states.md +86 -61
- package/src/core/components/functional/states/states.ts +1 -1
- package/src/core/components/functional/submit/submit.md +64 -72
- package/src/core/components/functional/subscriber/subscriber.ts +0 -0
- package/src/core/components/functional/translation/translation.md +38 -0
- package/src/core/components/functional/value/value.md +34 -22
- package/src/core/components/functional/value/value.ts +0 -0
- package/src/core/components/ui/_css/size.ts +0 -0
- package/src/core/components/ui/alert/alert.md +48 -58
- package/src/core/components/ui/badge/badge.md +27 -34
- package/src/core/components/ui/button/button.md +139 -106
- package/src/core/components/ui/captcha/altchaStyles.ts +0 -0
- package/src/core/components/ui/captcha/captcha.md +17 -32
- package/src/core/components/ui/card/card.md +6 -6
- package/src/core/components/ui/divider/divider.md +8 -11
- package/src/core/components/ui/form/checkbox/checkbox.md +90 -42
- package/src/core/components/ui/form/fieldset/fieldset.md +31 -75
- package/src/core/components/ui/form/form-actions/form-actions.md +14 -16
- package/src/core/components/ui/form/form-layout/form-layout.md +19 -29
- package/src/core/components/ui/form/input/input.md +95 -95
- package/src/core/components/ui/form/radio/radio.md +55 -34
- package/src/core/components/ui/form/select/select.md +60 -45
- package/src/core/components/ui/form/switch/switch.md +57 -34
- package/src/core/components/ui/form/textarea/textarea.md +55 -38
- package/src/core/components/ui/group/group.md +35 -33
- package/src/core/components/ui/icon/icon.md +4 -4
- package/src/core/components/ui/image/image.md +41 -107
- package/src/core/components/ui/link/link.md +6 -6
- package/src/core/components/ui/loader/loader.md +30 -55
- package/src/core/components/ui/menu/menu.md +27 -27
- package/src/core/components/ui/modal/modal.md +72 -96
- package/src/core/components/ui/modal/modal.ts +14 -11
- package/src/core/components/ui/pop/pop.md +80 -158
- package/src/core/components/ui/progress/progress.md +2 -2
- package/src/core/components/ui/table/table.md +91 -255
- package/src/core/components/ui/theme/theme.md +11 -36
- package/src/core/components/ui/toast/toast.md +48 -117
- package/src/core/components/ui/tooltip/tooltip.md +27 -62
- package/src/core/mixins/Subscriber.ts +0 -0
- package/src/core/utils/DataBindObserver.ts +0 -0
- package/src/core/utils/LocationHandler.spec.ts +80 -0
- package/src/core/utils/LocationHandler.ts +5 -9
- package/src/core/utils/Objects.ts +0 -0
- package/src/core/utils/route.ts +0 -0
- package/src/docs/code.ts +88 -75
- package/src/docs/components/docs-demo-sources.ts +70 -147
- package/src/docs/components/docs-lit-demo.ts +20 -40
- package/src/docs/components/docs-source-link.ts +0 -82
- package/src/docs/decorators/ancestor-attribute.md +59 -0
- package/src/docs/decorators/auto-subscribe.md +40 -0
- package/src/docs/decorators/bind.md +77 -0
- package/src/docs/decorators/get.md +160 -0
- package/src/docs/decorators/handle.md +119 -0
- package/src/docs/decorators/on-assign.md +63 -0
- package/src/docs/decorators/patch.md +44 -0
- package/src/docs/decorators/post.md +134 -0
- package/src/docs/decorators/publish.md +56 -0
- package/src/docs/decorators/put.md +51 -0
- package/src/docs/decorators/subscribe.md +87 -0
- package/src/docs/decorators/wait-for-ancestors.md +76 -0
- package/src/docs/directives/sub.md +75 -0
- package/src/docs/directives/t.md +73 -0
- package/src/docs/docs-location.spec.ts +46 -0
- package/src/docs/docs-location.ts +123 -32
- package/src/docs/docs.ts +6 -2
- package/src/docs/example/decorators-demo-bind-demos.ts +81 -116
- package/src/docs/example/decorators-demo-geo.ts +30 -19
- package/src/docs/example/decorators-demo-post.ts +88 -186
- package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +165 -268
- package/src/docs/example/decorators-demo.ts +85 -98
- package/src/docs/example/docs-api-config-demos.ts +19 -20
- package/src/docs/example/docs-boarding-pass-demo.ts +134 -0
- package/src/docs/example/docs-flight-demos.ts +147 -0
- package/src/docs/example/docs-jsonata-demos.ts +52 -52
- package/src/docs/example/docs-list-demos.ts +43 -123
- package/src/docs/example/docs-provider-keys.ts +33 -28
- package/src/docs/example/docs-queue-demos.ts +37 -77
- package/src/docs/example/docs-router-demos.ts +20 -25
- package/src/docs/example/docs-submit-demos.ts +48 -48
- package/src/docs/example/docs-toggle-demos.ts +4 -3
- package/src/docs/example/users.ts +0 -0
- package/src/docs/getting-started/ai-agents.md +76 -0
- package/src/docs/getting-started/components.md +5 -0
- package/src/docs/getting-started/create-a-component.md +136 -0
- package/src/docs/getting-started/dataFlow.md +87 -0
- package/src/docs/getting-started/installation.md +36 -0
- package/src/docs/getting-started/my-first-component.md +227 -0
- package/src/docs/getting-started/start.md +35 -0
- package/src/docs/getting-started/theming.md +253 -0
- package/src/docs/header/header.ts +240 -71
- package/src/docs/home/catalog.ts +44 -0
- package/src/docs/home/home.ts +520 -0
- package/src/docs/home/mach-stage.ts +389 -0
- package/src/docs/layout.ts +12 -11
- package/src/docs/misc/api-configuration.md +79 -0
- package/src/docs/misc/dataProviderKey.md +168 -0
- package/src/docs/misc/docs-mock-api.md +62 -0
- package/src/docs/misc/dynamic-path.md +71 -0
- package/src/docs/misc/endpoint.md +45 -0
- package/src/docs/misc/html-integration.md +14 -0
- package/src/docs/mock-api/api-config-mock.ts +5 -0
- package/src/docs/mock-api/fixtures.ts +0 -278
- package/src/docs/mock-api/flights.ts +89 -0
- package/src/docs/mock-api/router.ts +3 -4
- package/src/docs/mock-api/urls.ts +1 -2
- package/src/docs/navigation/components-index.ts +56 -0
- package/src/docs/navigation/navigation.ts +219 -232
- package/src/docs/navigation/pager.ts +67 -0
- package/src/docs/navigation/toc.ts +101 -0
- package/src/docs/search/docs-search.json +2419 -4374
- package/src/docs/search/markdown-renderer.ts +33 -7
- package/src/docs/search/page.ts +9 -6
- package/src/docs/search/search.ts +154 -122
- package/src/docs/shiki/index.ts +109 -0
- package/src/docs/tailwind/css/base/scrollbar.css +22 -0
- package/src/docs/tailwind/css/base/theme.css +96 -0
- package/src/docs/tailwind/css/base/typography.css +4 -0
- package/src/docs/tailwind/css/docs/boarding-pass.css +65 -0
- package/src/docs/tailwind/css/docs/content.css +32 -0
- package/src/docs/tailwind/css/docs/page.css +10 -0
- package/src/docs/tailwind/css/docs.css +9 -0
- package/src/docs/tailwind/css/home/hero.css +210 -0
- package/src/docs/tailwind/css/home/motion.css +84 -0
- package/src/docs/tailwind/css/home/sections.css +416 -0
- package/src/docs/tailwind/css/tailwind.css +7 -185
- package/src/tsconfig.json +23 -2
- package/src/tsconfig.tsbuildinfo +1 -1
- package/tailwind.config.js +8 -4
- package/vite.config.mts +11 -2
- package/.agents/skills/concorde-component-docs/SKILL.md +0 -194
- package/.github/workflows/ci.yml +0 -21
- package/.github-export-ignore +0 -30
- package/CONTRIBUTING.md +0 -59
- package/DEV.md +0 -54
- package/LICENSE +0 -21
- package/OPEN_SOURCE_CHECKPOINT.md +0 -133
- package/concorde-3d.bundle.js +0 -3960
- package/concorde-3d.es.js +0 -33433
- package/concorde-hugging-face-infer.bundle.js +0 -32
- package/concorde-hugging-face-infer.es.js +0 -2952
- package/concorde-interactive.bundle.js +0 -1157
- package/concorde-interactive.es.js +0 -10734
- package/concorde-shader.bundle.js +0 -116
- package/concorde-shader.es.js +0 -8353
- package/concorde-webgpu.bundle.js +0 -307
- package/concorde-webgpu.es.js +0 -8627
- package/docs/assets/index-D8MVWqY6.js +0 -12251
- package/docs/assets/index-DiD0qYvE.css +0 -1
- package/docs/crawl/core/components/functional/date/date.html +0 -190
- package/docs/crawl/core/components/functional/fetch/fetch.html +0 -109
- package/docs/crawl/core/components/functional/if/if.html +0 -27
- package/docs/crawl/core/components/functional/jsonata/jsonata.html +0 -79
- package/docs/crawl/core/components/functional/list/list.html +0 -70
- package/docs/crawl/core/components/functional/mix/mix.html +0 -45
- package/docs/crawl/core/components/functional/queue/queue.html +0 -96
- package/docs/crawl/core/components/functional/router/router.html +0 -106
- package/docs/crawl/core/components/functional/sdui/sdui.html +0 -269
- package/docs/crawl/core/components/functional/states/states.html +0 -66
- package/docs/crawl/core/components/functional/submit/submit.html +0 -160
- package/docs/crawl/core/components/functional/value/value.html +0 -51
- package/docs/crawl/core/components/ui/alert/alert.html +0 -110
- package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +0 -23
- package/docs/crawl/core/components/ui/badge/badge.html +0 -119
- package/docs/crawl/core/components/ui/button/button.html +0 -149
- package/docs/crawl/core/components/ui/captcha/captcha.html +0 -30
- package/docs/crawl/core/components/ui/card/card.html +0 -99
- package/docs/crawl/core/components/ui/divider/divider.html +0 -58
- package/docs/crawl/core/components/ui/form/checkbox/checkbox.html +0 -73
- package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +0 -135
- package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +0 -79
- package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +0 -62
- package/docs/crawl/core/components/ui/form/input/input.html +0 -109
- package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +0 -38
- package/docs/crawl/core/components/ui/form/radio/radio.html +0 -56
- package/docs/crawl/core/components/ui/form/select/select.html +0 -73
- package/docs/crawl/core/components/ui/form/switch/switch.html +0 -56
- package/docs/crawl/core/components/ui/form/textarea/textarea.html +0 -59
- package/docs/crawl/core/components/ui/group/group.html +0 -82
- package/docs/crawl/core/components/ui/icon/icon.html +0 -133
- package/docs/crawl/core/components/ui/image/image.html +0 -110
- package/docs/crawl/core/components/ui/link/link.html +0 -42
- package/docs/crawl/core/components/ui/loader/loader.html +0 -50
- package/docs/crawl/core/components/ui/modal/modal.html +0 -117
- package/docs/crawl/core/components/ui/pop/pop.html +0 -102
- package/docs/crawl/core/components/ui/progress/progress.html +0 -58
- package/docs/crawl/core/components/ui/table/table.html +0 -413
- package/docs/crawl/core/components/ui/toast/toast.html +0 -122
- package/docs/crawl/core/components/ui/tooltip/tooltip.html +0 -79
- package/docs/crawl/docs/_core-concept/overview.html +0 -66
- package/docs/crawl/docs/_core-concept/subscriber.html +0 -75
- package/docs/crawl/docs/_decorators/ancestor-attribute.html +0 -116
- package/docs/crawl/docs/_decorators/auto-subscribe.html +0 -202
- package/docs/crawl/docs/_decorators/bind.html +0 -141
- package/docs/crawl/docs/_decorators/get.html +0 -149
- package/docs/crawl/docs/_decorators/handle.html +0 -165
- package/docs/crawl/docs/_decorators/on-assign.html +0 -355
- package/docs/crawl/docs/_decorators/patch.html +0 -78
- package/docs/crawl/docs/_decorators/post.html +0 -139
- package/docs/crawl/docs/_decorators/publish.html +0 -61
- package/docs/crawl/docs/_decorators/put.html +0 -78
- package/docs/crawl/docs/_decorators/subscribe.html +0 -109
- package/docs/crawl/docs/_decorators/wait-for-ancestors.html +0 -137
- package/docs/crawl/docs/_directives/sub.html +0 -93
- package/docs/crawl/docs/_getting-started/concorde-manual-install.html +0 -100
- package/docs/crawl/docs/_getting-started/concorde-outside.html +0 -58
- package/docs/crawl/docs/_getting-started/my-first-subscriber.html +0 -110
- package/docs/crawl/docs/_getting-started/pubsub.html +0 -62
- package/docs/crawl/docs/_getting-started/start.html +0 -76
- package/docs/crawl/docs/_getting-started/theming.html +0 -85
- package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +0 -138
- package/docs/crawl/hubs/decorators.html +0 -547
- package/docs/crawl/hubs/form-components.html +0 -359
- package/docs/crawl/hubs/remote-data.html +0 -452
- package/docs/crawl/index.html +0 -101
- package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -29
- package/docs/src/docs/_core-concept/overview.md +0 -57
- package/docs/src/docs/_core-concept/subscriber.md +0 -75
- package/docs/src/docs/_decorators/ancestor-attribute.md +0 -127
- package/docs/src/docs/_decorators/auto-subscribe.md +0 -202
- package/docs/src/docs/_decorators/bind.md +0 -167
- package/docs/src/docs/_decorators/get.md +0 -162
- package/docs/src/docs/_decorators/handle.md +0 -175
- package/docs/src/docs/_decorators/on-assign.md +0 -390
- package/docs/src/docs/_decorators/patch.md +0 -70
- package/docs/src/docs/_decorators/post.md +0 -146
- package/docs/src/docs/_decorators/publish.md +0 -55
- package/docs/src/docs/_decorators/put.md +0 -70
- package/docs/src/docs/_decorators/subscribe.md +0 -100
- package/docs/src/docs/_decorators/wait-for-ancestors.md +0 -163
- package/docs/src/docs/_directives/sub.md +0 -91
- package/docs/src/docs/_getting-started/concorde-manual-install.md +0 -133
- package/docs/src/docs/_getting-started/concorde-outside.md +0 -33
- package/docs/src/docs/_getting-started/my-first-subscriber.md +0 -120
- package/docs/src/docs/_getting-started/pubsub.md +0 -37
- package/docs/src/docs/_getting-started/start.md +0 -47
- package/docs/src/docs/_getting-started/theming.md +0 -91
- package/docs/src/docs/_misc/formelement-subscriber-removal.md +0 -115
- package/docs/src/tsconfig.declarations.json +0 -22
- package/docs/src/tsconfig.emit.json +0 -23
- package/gitlab/job_github_mirror.sh +0 -39
- package/scripts/github-export.mjs +0 -150
- package/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -29
- package/src/css.d.ts +0 -19
- package/src/docs/_core-concept/overview.md +0 -57
- package/src/docs/_core-concept/subscriber.md +0 -75
- package/src/docs/_decorators/ancestor-attribute.md +0 -128
- package/src/docs/_decorators/auto-subscribe.md +0 -202
- package/src/docs/_decorators/bind.md +0 -167
- package/src/docs/_decorators/get.md +0 -162
- package/src/docs/_decorators/handle.md +0 -175
- package/src/docs/_decorators/on-assign.md +0 -390
- package/src/docs/_decorators/patch.md +0 -70
- package/src/docs/_decorators/post.md +0 -146
- package/src/docs/_decorators/publish.md +0 -55
- package/src/docs/_decorators/put.md +0 -70
- package/src/docs/_decorators/subscribe.md +0 -100
- package/src/docs/_decorators/wait-for-ancestors.md +0 -163
- package/src/docs/_directives/sub.md +0 -91
- package/src/docs/_getting-started/concorde-manual-install.md +0 -133
- package/src/docs/_getting-started/concorde-outside.md +0 -33
- package/src/docs/_getting-started/my-first-subscriber.md +0 -120
- package/src/docs/_getting-started/pubsub.md +0 -37
- package/src/docs/_misc/formelement-subscriber-removal.md +0 -115
- package/src/docs/example/docs-input-autocomplete-demos.ts +0 -110
- package/src/docs/example/docs-joke-demos.ts +0 -297
- package/src/docs/prism/index.ts +0 -6
- package/src/docs/prism/prism.css +0 -158
- package/src/docs/prism/prism.js +0 -1022
- package/src/tsconfig.declarations.json +0 -22
- package/src/tsconfig.emit.json +0 -23
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { LitElement, html } from "lit";
|
|
2
|
+
import { customElement } from "lit/decorators.js";
|
|
3
|
+
|
|
4
|
+
/** The Concorde silhouette from the brand icon, nose up, in a 66 × 66 box centred on (33, 33). */
|
|
5
|
+
const PLANE =
|
|
6
|
+
"M33.2499 62.03C33.8799 59.24 34.26 56.17 34.39 53.08C34.57 52.78 34.9099 52.6 35.2599 52.64H35.39C35.48 52.64 35.5799 52.64 35.6899 52.64H35.7599C35.7599 52.64 35.7999 52.64 35.8299 52.64C36.2499 52.62 36.6799 52.58 36.9099 52.56C36.9399 52.56 36.9599 52.56 36.9799 52.56C37.0099 52.56 37.0299 52.56 37.0499 52.56H37.0899L37.2099 51.93H37.4799L37.5799 52.4L37.6899 52.49H39.2699L39.39 52.38L39.5099 51.93H39.7899L39.8399 52.21L39.9999 52.29L45.2099 51.86L46.2799 51.29C46.2799 51.29 46.2799 50.85 46.2399 50.25V50.18C46.2399 50.18 46.2399 50.13 46.2399 50.11C46.2099 49.62 46.1399 49.13 46.0399 48.65C45.7899 47.45 45.29 46 42.2 41.58C39.11 37.16 38.04 35.52 35.89 27.63C35.85 27.48 35.8199 27.35 35.7899 27.2C35.1399 24.53 34.6899 22.95 34.5199 22.38V10.89C34.4999 9.60996 34.3999 8.33996 34.2099 7.07996C34.0499 5.97996 33.6099 4.89996 33.3499 3.95996H32.6299C32.3599 4.89996 31.9299 5.97996 31.7699 7.06996C31.5799 8.33996 31.4799 9.60996 31.4599 10.89V22.38C31.2899 22.95 30.8299 24.52 30.1899 27.2C30.1599 27.35 30.1199 27.49 30.0899 27.63C27.9499 35.52 26.8699 37.16 23.7799 41.58C20.6899 46 20.1899 47.45 19.9399 48.65C19.8399 49.13 19.7799 49.62 19.7399 50.11C19.7399 50.13 19.7399 50.16 19.7399 50.18V50.25C19.6999 50.85 19.7 51.29 19.7 51.29L20.7699 51.86L25.9799 52.29L26.14 52.21L26.1899 51.93H26.4799L26.5999 52.38L26.7299 52.49H28.2999L28.4099 52.4L28.5099 51.93H28.7699L28.89 52.56H28.9399C28.9399 52.56 28.9799 52.56 29.0099 52.56C29.0299 52.56 29.0499 52.56 29.0799 52.56C29.3099 52.58 29.7499 52.63 30.1599 52.64C30.1799 52.64 30.2099 52.64 30.2299 52.64H30.2999C30.4099 52.64 30.5099 52.64 30.5999 52.64H30.7299C31.0799 52.6 31.4299 52.77 31.6099 53.08C31.7299 56.17 32.1099 59.24 32.7399 62.03H33.2499Z";
|
|
7
|
+
|
|
8
|
+
/** Speed of sound on the stage, in stage widths per second. */
|
|
9
|
+
const SOUND = 0.19;
|
|
10
|
+
/** Cruise: Concorde flew at Mach 2.02, 18 000 m up. */
|
|
11
|
+
const CRUISE = 2.02;
|
|
12
|
+
/** Grid cells across the field; every fourth line is heavier. */
|
|
13
|
+
const GRID = 24;
|
|
14
|
+
const WAVE_EVERY = 0.05;
|
|
15
|
+
const WAVE_LIFE = 2.6;
|
|
16
|
+
|
|
17
|
+
const clamp = (v: number, lo: number, hi: number) =>
|
|
18
|
+
Math.min(hi, Math.max(lo, v));
|
|
19
|
+
const smooth = (a: number, b: number, v: number) => {
|
|
20
|
+
const t = clamp((v - a) / (b - a), 0, 1);
|
|
21
|
+
return t * t * (3 - 2 * t);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type Wave = { x: number; y: number; t: number };
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The hero's orange field as a Mach diagram: the aircraft drops a sound wave as it flies and,
|
|
28
|
+
* once it outruns them, the waves pile into the shock cone. On autopilot it accelerates through
|
|
29
|
+
* the barrier on every pass; a moving pointer steers it and moving fast
|
|
30
|
+
* enough breaks the barrier by hand. Reduced motion gets one still frame at cruise.
|
|
31
|
+
*/
|
|
32
|
+
@customElement("docs-mach-stage")
|
|
33
|
+
export class DocsMachStage extends LitElement {
|
|
34
|
+
private canvas?: HTMLCanvasElement;
|
|
35
|
+
private ints: HTMLElement[] = [];
|
|
36
|
+
private decs: HTMLElement[] = [];
|
|
37
|
+
private plane = new Path2D(PLANE);
|
|
38
|
+
private waves: Wave[] = [];
|
|
39
|
+
private x = -0.3;
|
|
40
|
+
private y = 0.55;
|
|
41
|
+
private vx = 0.75 * SOUND;
|
|
42
|
+
private vy = 0;
|
|
43
|
+
private mach = 0;
|
|
44
|
+
private time = 0;
|
|
45
|
+
private lastWave = 0;
|
|
46
|
+
private pointer: { x: number; y: number; t: number } | null = null;
|
|
47
|
+
private boom = -10;
|
|
48
|
+
private frame = 0;
|
|
49
|
+
private last = 0;
|
|
50
|
+
private resize?: ResizeObserver;
|
|
51
|
+
private visible = true;
|
|
52
|
+
private io?: IntersectionObserver;
|
|
53
|
+
|
|
54
|
+
createRenderRoot() {
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
render() {
|
|
59
|
+
return html`<canvas class="mach-canvas" aria-hidden="true"></canvas>
|
|
60
|
+
<p class="mach-readout" aria-label="Concorde cruise speed: Mach 2.02">
|
|
61
|
+
<span class="mach-label">mach</span>
|
|
62
|
+
<span class="mach-value">
|
|
63
|
+
${[
|
|
64
|
+
"mach-layer",
|
|
65
|
+
"mach-layer mach-ghost-a",
|
|
66
|
+
"mach-layer mach-ghost-b",
|
|
67
|
+
].map(
|
|
68
|
+
(layer, i) =>
|
|
69
|
+
html`<span class=${layer} aria-hidden=${i ? "true" : "false"}
|
|
70
|
+
><span class="mach-int">0</span><span class="mach-dot">.</span
|
|
71
|
+
><span class="mach-dec">00</span></span
|
|
72
|
+
>`,
|
|
73
|
+
)}
|
|
74
|
+
</span>
|
|
75
|
+
</p>
|
|
76
|
+
<p class="mach-note">
|
|
77
|
+
cruise mach 2.02 · 18 000 m · paris – new york in 3 h 30
|
|
78
|
+
</p>`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
firstUpdated() {
|
|
82
|
+
this.canvas = this.querySelector("canvas")!;
|
|
83
|
+
this.ints = [...this.querySelectorAll<HTMLElement>(".mach-int")];
|
|
84
|
+
this.decs = [...this.querySelectorAll<HTMLElement>(".mach-dec")];
|
|
85
|
+
this.resize = new ResizeObserver(() => this.fit());
|
|
86
|
+
this.resize.observe(this);
|
|
87
|
+
this.io = new IntersectionObserver(
|
|
88
|
+
([e]) => (this.visible = e.isIntersecting),
|
|
89
|
+
);
|
|
90
|
+
this.io.observe(this);
|
|
91
|
+
this.addEventListener("pointermove", this.onPointer);
|
|
92
|
+
this.addEventListener("pointerdown", this.onPointer);
|
|
93
|
+
this.addEventListener("pointerleave", this.onLeave);
|
|
94
|
+
this.fit();
|
|
95
|
+
if (matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
96
|
+
this.still();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this.frame = requestAnimationFrame(this.tick);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
disconnectedCallback() {
|
|
103
|
+
super.disconnectedCallback();
|
|
104
|
+
cancelAnimationFrame(this.frame);
|
|
105
|
+
this.resize?.disconnect();
|
|
106
|
+
this.io?.disconnect();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private onPointer = (e: PointerEvent) => {
|
|
110
|
+
const r = this.getBoundingClientRect();
|
|
111
|
+
this.pointer = {
|
|
112
|
+
x: (e.clientX - r.left) / r.width,
|
|
113
|
+
y: (e.clientY - r.top) / r.width,
|
|
114
|
+
t: this.time,
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
private onLeave = () => {
|
|
119
|
+
this.pointer = null;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
private fit() {
|
|
123
|
+
const c = this.canvas!;
|
|
124
|
+
const dpr = Math.min(devicePixelRatio || 1, 2);
|
|
125
|
+
c.width = Math.round(this.clientWidth * dpr);
|
|
126
|
+
c.height = Math.round(this.clientHeight * dpr);
|
|
127
|
+
// publish the grid cell so the field's bevel can be cut along the grid
|
|
128
|
+
this.parentElement?.style.setProperty(
|
|
129
|
+
"--mach-cell",
|
|
130
|
+
`${this.clientWidth / GRID}px`,
|
|
131
|
+
);
|
|
132
|
+
if (matchMedia("(prefers-reduced-motion: reduce)").matches) this.still();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Height of the field in stage widths (positions are kept in widths so speed is uniform). */
|
|
136
|
+
private get aspect() {
|
|
137
|
+
return this.clientHeight / Math.max(1, this.clientWidth);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private tick = (now: number) => {
|
|
141
|
+
this.frame = requestAnimationFrame(this.tick);
|
|
142
|
+
const dt = Math.min(0.05, (now - (this.last || now)) / 1000);
|
|
143
|
+
this.last = now;
|
|
144
|
+
if (!this.visible || !dt) return;
|
|
145
|
+
this.time += dt;
|
|
146
|
+
this.fly(dt);
|
|
147
|
+
if (this.time - this.lastWave > WAVE_EVERY) {
|
|
148
|
+
this.lastWave = this.time;
|
|
149
|
+
this.waves.push({ x: this.x, y: this.y, t: this.time });
|
|
150
|
+
}
|
|
151
|
+
this.waves = this.waves.filter((w) => this.time - w.t < WAVE_LIFE);
|
|
152
|
+
this.draw();
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
private fly(dt: number) {
|
|
156
|
+
const h = this.aspect;
|
|
157
|
+
const before = this.mach;
|
|
158
|
+
// flown by heading and speed, never by position, so it always carries on along an arc
|
|
159
|
+
let speed = Math.hypot(this.vx, this.vy);
|
|
160
|
+
let heading = Math.atan2(this.vy, this.vx);
|
|
161
|
+
let wantSpeed: number;
|
|
162
|
+
let wantHeading: number;
|
|
163
|
+
let turn: number;
|
|
164
|
+
let throttle: number;
|
|
165
|
+
const steering = this.pointer && this.time - this.pointer.t < 0.4;
|
|
166
|
+
if (steering) {
|
|
167
|
+
// head for a moving pointer; the further ahead it runs, the faster the aircraft goes
|
|
168
|
+
const dx = this.pointer!.x - this.x;
|
|
169
|
+
const dy = this.pointer!.y - this.y;
|
|
170
|
+
wantHeading = Math.atan2(dy, dx);
|
|
171
|
+
wantSpeed = clamp(Math.hypot(dx, dy) * 2.5, 0.6 * SOUND, 2.4 * SOUND);
|
|
172
|
+
turn = 5;
|
|
173
|
+
throttle = 4;
|
|
174
|
+
} else {
|
|
175
|
+
// autopilot: endless passes, speeding up to cruise across the field and easing off
|
|
176
|
+
// while out of sight, so each pass hands over to the next without a cut
|
|
177
|
+
const up = smooth(-0.1, 0.65, this.x);
|
|
178
|
+
const down = smooth(1.0, 1.2, this.x);
|
|
179
|
+
wantSpeed = (0.6 + (CRUISE - 0.6) * up * (1 - down)) * SOUND;
|
|
180
|
+
const cy = h * 0.55 + Math.sin(this.time * 0.6) * h * 0.06;
|
|
181
|
+
wantHeading = Math.atan2(cy - this.y, 0.6);
|
|
182
|
+
turn = 2;
|
|
183
|
+
throttle = 2;
|
|
184
|
+
}
|
|
185
|
+
let delta = wantHeading - heading;
|
|
186
|
+
delta = Math.atan2(Math.sin(delta), Math.cos(delta));
|
|
187
|
+
heading += delta * Math.min(1, dt * turn);
|
|
188
|
+
speed += (wantSpeed - speed) * Math.min(1, dt * throttle);
|
|
189
|
+
this.vx = Math.cos(heading) * speed;
|
|
190
|
+
this.vy = Math.sin(heading) * speed;
|
|
191
|
+
this.x += this.vx * dt;
|
|
192
|
+
this.y += this.vy * dt;
|
|
193
|
+
// out of sight on the right, back in on the left; the old waves fade where they were left
|
|
194
|
+
if (!steering && this.x > 1.3) this.x -= 1.6;
|
|
195
|
+
this.mach = speed / SOUND;
|
|
196
|
+
if (before < 1 && this.mach >= 1) this.boom = this.time;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private colours() {
|
|
200
|
+
const s = getComputedStyle(this);
|
|
201
|
+
return { ink: s.color, field: s.backgroundColor };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
private draw() {
|
|
205
|
+
const c = this.canvas!;
|
|
206
|
+
const g = c.getContext("2d")!;
|
|
207
|
+
const W = c.width;
|
|
208
|
+
const u = W; // one stage width in device pixels
|
|
209
|
+
const { ink } = this.colours();
|
|
210
|
+
g.clearRect(0, 0, c.width, c.height);
|
|
211
|
+
g.strokeStyle = ink;
|
|
212
|
+
g.fillStyle = ink;
|
|
213
|
+
const px = this.x * u;
|
|
214
|
+
const py = this.y * u;
|
|
215
|
+
|
|
216
|
+
// graph paper under the diagram: a fine square grid, every fourth line heavier
|
|
217
|
+
const cell = u / GRID;
|
|
218
|
+
g.lineWidth = Math.max(1, u * 0.0008);
|
|
219
|
+
for (let i = 0, x = 0; x <= c.width; i++, x += cell) {
|
|
220
|
+
g.globalAlpha = i % 4 ? 0.1 : 0.22;
|
|
221
|
+
g.beginPath();
|
|
222
|
+
g.moveTo(Math.round(x) + 0.5, 0);
|
|
223
|
+
g.lineTo(Math.round(x) + 0.5, c.height);
|
|
224
|
+
g.stroke();
|
|
225
|
+
}
|
|
226
|
+
for (let i = 0, y = 0; y <= c.height; i++, y += cell) {
|
|
227
|
+
g.globalAlpha = i % 4 ? 0.1 : 0.22;
|
|
228
|
+
g.beginPath();
|
|
229
|
+
g.moveTo(0, Math.round(y) + 0.5);
|
|
230
|
+
g.lineTo(c.width, Math.round(y) + 0.5);
|
|
231
|
+
g.stroke();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// the shock cone, filled, once supersonic
|
|
235
|
+
if (this.mach > 1.02) {
|
|
236
|
+
const mu = Math.asin(1 / this.mach);
|
|
237
|
+
const dir = Math.atan2(this.vy, this.vx);
|
|
238
|
+
const len = u * 2;
|
|
239
|
+
g.globalAlpha = Math.min(0.22, (this.mach - 1) * 0.35);
|
|
240
|
+
g.beginPath();
|
|
241
|
+
g.moveTo(px, py);
|
|
242
|
+
g.lineTo(px - Math.cos(dir - mu) * len, py - Math.sin(dir - mu) * len);
|
|
243
|
+
g.lineTo(px - Math.cos(dir + mu) * len, py - Math.sin(dir + mu) * len);
|
|
244
|
+
g.closePath();
|
|
245
|
+
g.fill();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// the waves: each one a circle growing at the speed of sound from where it was dropped
|
|
249
|
+
g.lineWidth = Math.max(2, u * 0.003);
|
|
250
|
+
for (const w of this.waves) {
|
|
251
|
+
const age = this.time - w.t;
|
|
252
|
+
const r = age * SOUND * u;
|
|
253
|
+
g.globalAlpha = Math.max(0, 1 - age / WAVE_LIFE) * 0.9;
|
|
254
|
+
g.beginPath();
|
|
255
|
+
g.arc(w.x * u, w.y * u, r, 0, Math.PI * 2);
|
|
256
|
+
g.stroke();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
this.construct(g, u, px, py);
|
|
260
|
+
|
|
261
|
+
// the boom: one heavy ring when the barrier goes
|
|
262
|
+
const since = this.time - this.boom;
|
|
263
|
+
if (since >= 0 && since < 1.4) {
|
|
264
|
+
g.globalAlpha = 1 - since / 1.4;
|
|
265
|
+
g.lineWidth = u * 0.018 * (1 - since / 1.4) + 2;
|
|
266
|
+
g.beginPath();
|
|
267
|
+
g.arc(px, py, since * SOUND * u * 3.2, 0, Math.PI * 2);
|
|
268
|
+
g.stroke();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// the aircraft, pointing where it flies
|
|
272
|
+
g.globalAlpha = 1;
|
|
273
|
+
const size = u * 0.15;
|
|
274
|
+
g.save();
|
|
275
|
+
g.translate(px, py);
|
|
276
|
+
g.rotate(Math.atan2(this.vy, this.vx) + Math.PI / 2);
|
|
277
|
+
g.scale(size / 66, size / 66);
|
|
278
|
+
g.translate(-33, -33);
|
|
279
|
+
g.fill(this.plane);
|
|
280
|
+
g.restore();
|
|
281
|
+
|
|
282
|
+
const [int, dec] = this.mach.toFixed(2).split(".");
|
|
283
|
+
for (const el of this.ints) el.textContent = int;
|
|
284
|
+
for (const el of this.decs) el.textContent = dec;
|
|
285
|
+
// the readout splits and shakes for a moment as the barrier goes
|
|
286
|
+
this.toggleAttribute("data-boom", since >= 0 && since < 0.9);
|
|
287
|
+
this.toggleAttribute("data-supersonic", this.mach >= 1);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Construction lines, as on a textbook figure: the flight path, the Mach lines run out to the
|
|
292
|
+
* edges, a few radii dropped square onto them from the centres that made them, and the angle.
|
|
293
|
+
*/
|
|
294
|
+
private construct(
|
|
295
|
+
g: CanvasRenderingContext2D,
|
|
296
|
+
u: number,
|
|
297
|
+
px: number,
|
|
298
|
+
py: number,
|
|
299
|
+
) {
|
|
300
|
+
const c = this.canvas!;
|
|
301
|
+
const dir = Math.atan2(this.vy, this.vx);
|
|
302
|
+
const reach = Math.hypot(c.width, c.height) * 2;
|
|
303
|
+
const line = (x1: number, y1: number, x2: number, y2: number) => {
|
|
304
|
+
g.beginPath();
|
|
305
|
+
g.moveTo(x1, y1);
|
|
306
|
+
g.lineTo(x2, y2);
|
|
307
|
+
g.stroke();
|
|
308
|
+
};
|
|
309
|
+
g.lineWidth = Math.max(1, u * 0.0012);
|
|
310
|
+
|
|
311
|
+
// flight path, dashed, through the whole field
|
|
312
|
+
g.globalAlpha = 0.45;
|
|
313
|
+
g.setLineDash([u * 0.012, u * 0.008]);
|
|
314
|
+
line(
|
|
315
|
+
px - Math.cos(dir) * reach,
|
|
316
|
+
py - Math.sin(dir) * reach,
|
|
317
|
+
px + Math.cos(dir) * reach,
|
|
318
|
+
py + Math.sin(dir) * reach,
|
|
319
|
+
);
|
|
320
|
+
g.setLineDash([]);
|
|
321
|
+
|
|
322
|
+
// centre marks where the waves were dropped
|
|
323
|
+
const mark = u * 0.006;
|
|
324
|
+
g.globalAlpha = 0.5;
|
|
325
|
+
this.waves.forEach((w, i) => {
|
|
326
|
+
if (i % 6) return;
|
|
327
|
+
line(w.x * u - mark, w.y * u, w.x * u + mark, w.y * u);
|
|
328
|
+
line(w.x * u, w.y * u - mark, w.x * u, w.y * u + mark);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
if (this.mach <= 1.02) return;
|
|
332
|
+
const mu = Math.asin(1 / this.mach);
|
|
333
|
+
for (const side of [-1, 1]) {
|
|
334
|
+
const ex = Math.cos(dir + Math.PI + side * mu);
|
|
335
|
+
const ey = Math.sin(dir + Math.PI + side * mu);
|
|
336
|
+
// the Mach line, run out past the cone to the edge
|
|
337
|
+
g.globalAlpha = 0.6;
|
|
338
|
+
line(px, py, px + ex * reach, py + ey * reach);
|
|
339
|
+
// radii, square to the Mach line, from a few of the centres
|
|
340
|
+
g.globalAlpha = 0.45;
|
|
341
|
+
this.waves.forEach((w, i) => {
|
|
342
|
+
if (i % 12 || this.time - w.t < 0.5) return;
|
|
343
|
+
const cx = w.x * u;
|
|
344
|
+
const cy = w.y * u;
|
|
345
|
+
const along = (cx - px) * ex + (cy - py) * ey;
|
|
346
|
+
if (along <= 0) return;
|
|
347
|
+
line(cx, cy, px + ex * along, py + ey * along);
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// the angle, marked at the apex, its value set just outside the cone where no wave reaches
|
|
352
|
+
const r = u * 0.12;
|
|
353
|
+
g.globalAlpha = 1;
|
|
354
|
+
g.lineWidth = Math.max(2, u * 0.003);
|
|
355
|
+
g.beginPath();
|
|
356
|
+
g.arc(px, py, r, dir + Math.PI - mu, dir + Math.PI + mu);
|
|
357
|
+
g.stroke();
|
|
358
|
+
const edge = dir + Math.PI + mu;
|
|
359
|
+
const out = edge + Math.PI / 2;
|
|
360
|
+
const gap = u * 0.03;
|
|
361
|
+
g.font = `600 ${Math.round(u * 0.024)}px ${getComputedStyle(this).fontFamily}`;
|
|
362
|
+
g.textAlign = "center";
|
|
363
|
+
g.textBaseline = "middle";
|
|
364
|
+
const deg = ((mu * 180) / Math.PI).toFixed(1);
|
|
365
|
+
g.fillText(
|
|
366
|
+
`μ ${deg}°`,
|
|
367
|
+
px + Math.cos(edge) * r * 1.1 + Math.cos(out) * gap,
|
|
368
|
+
py + Math.sin(edge) * r * 1.1 + Math.sin(out) * gap,
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/** Reduced motion: the field at cruise, waves laid out as they would be, nothing moving. */
|
|
373
|
+
private still() {
|
|
374
|
+
if (!this.canvas) return;
|
|
375
|
+
const h = this.aspect;
|
|
376
|
+
this.x = 0.68;
|
|
377
|
+
this.y = h * 0.55;
|
|
378
|
+
this.vx = CRUISE * SOUND;
|
|
379
|
+
this.vy = 0;
|
|
380
|
+
this.mach = CRUISE;
|
|
381
|
+
this.time = WAVE_LIFE;
|
|
382
|
+
this.boom = -10;
|
|
383
|
+
this.waves = [];
|
|
384
|
+
for (let t = 0; t < WAVE_LIFE; t += WAVE_EVERY * 2) {
|
|
385
|
+
this.waves.push({ x: this.x - this.vx * (WAVE_LIFE - t), y: this.y, t });
|
|
386
|
+
}
|
|
387
|
+
this.draw();
|
|
388
|
+
}
|
|
389
|
+
}
|
package/src/docs/layout.ts
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import LocationHandler from "@supersoniks/concorde/core/utils/LocationHandler";
|
|
2
|
+
import { parseDocsLocation } from "./docs-location";
|
|
3
|
+
|
|
4
|
+
const onLocationChange = (locationHref: string) => {
|
|
5
|
+
const { url } = parseDocsLocation(locationHref);
|
|
6
|
+
// No markdown path → home.
|
|
7
|
+
if (!url) {
|
|
3
8
|
document.documentElement.setAttribute("data-home", "");
|
|
4
9
|
} else {
|
|
5
10
|
document.documentElement.removeAttribute("data-home");
|
|
6
11
|
}
|
|
7
12
|
};
|
|
8
|
-
const getCurrentLocation = () => document.location;
|
|
9
|
-
const currentLocation: Location = getCurrentLocation();
|
|
10
|
-
onLocationChange(currentLocation);
|
|
11
|
-
window.addEventListener("popstate", (event) => {
|
|
12
|
-
onLocationChange(getCurrentLocation());
|
|
13
|
-
});
|
|
14
13
|
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
// LocationHandler polls document.location (covers pushState; popstate alone does not).
|
|
15
|
+
LocationHandler.onChange({
|
|
16
|
+
set location(value: string) {
|
|
17
|
+
onLocationChange(value);
|
|
18
|
+
},
|
|
18
19
|
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# API configuration
|
|
2
|
+
|
|
3
|
+
`APIConfiguration` is the object built by [`HTML.getApiConfiguration`](../../core/utils/HTML.ts) from **ancestor attributes** on the DOM (or from a typed publisher — see [@get](/docs/decorators/get) / [@post](/docs/decorators/post) configuration key). It is passed to [`API`](../../core/utils/api.ts) by fetchers, **sonic-submit**, the **`wording()`** directive, **`@get`**, **`@post`**, **`@put`**, and **`@patch`**.
|
|
4
|
+
|
|
5
|
+
> **Mock service:** same [Local API demos](/docs/misc/docs-mock-api) Service Worker / Vite middleware. Routes used on this page are listed in the [API config routes](#api-config-routes) section below.
|
|
6
|
+
|
|
7
|
+
## Attribute map
|
|
8
|
+
|
|
9
|
+
| Attribute (ancestor) | `APIConfiguration` field | Role |
|
|
10
|
+
|---------------------|---------------------------|------|
|
|
11
|
+
| `serviceURL` | `serviceURL` | Base URL (e.g. `/docs-mock-api`) |
|
|
12
|
+
| `token` | `token` | Static Bearer sent on REST calls |
|
|
13
|
+
| `userName` / `password` | `userName` / `password` | Basic auth for **tokenProvider** fetch only |
|
|
14
|
+
| `eventsApiToken` | `authToken` | Bearer for **tokenProvider** when no Basic |
|
|
15
|
+
| `tokenProvider` | `tokenProvider` | Path to GET a new token (`{ token }` JSON) |
|
|
16
|
+
| `wordingProvider` | — (read by `wording()`) | Base path + query for label batch GET |
|
|
17
|
+
| `wordingVersionProvider` | — | Publisher id; bump version → reload wordings |
|
|
18
|
+
| `credentials` | `credentials` | `fetch` credentials mode |
|
|
19
|
+
| `addHTTPResponse` | `addHTTPResponse` | Attach `_sonic_http_response_` on result |
|
|
20
|
+
| `cache` | `cache` | `fetch` cache mode |
|
|
21
|
+
| `blockUntilDone` | `blockUntilDone` | Serialize calls per `serviceURL` |
|
|
22
|
+
| `keepAlive` | `keepAlive` | `fetch` keepalive |
|
|
23
|
+
|
|
24
|
+
**Lit / TypeScript:** store the same shape in a publisher and pass `DataProviderKey<APIConfiguration>` as the second argument of `@get` (see [DataProviderKey](/docs/misc/dataProviderKey)).
|
|
25
|
+
|
|
26
|
+
## Bearer token (static)
|
|
27
|
+
|
|
28
|
+
Publisher `docsApiConfBearerKey` (`set(docsApiConfBearerKey, { token: "docs-mock-valid-token", … })`) — mock returns the protected payload.
|
|
29
|
+
|
|
30
|
+
<docs-lit-demo for="docs-api-config-bearer-demo"></docs-lit-demo>
|
|
31
|
+
|
|
32
|
+
## tokenProvider + Basic auth
|
|
33
|
+
|
|
34
|
+
No static `token`: `API.auth()` calls `GET /docs-mock-api/auth/token` with Basic **demo** / **secret**, stores `token`, then calls the protected route.
|
|
35
|
+
|
|
36
|
+
<docs-lit-demo for="docs-api-config-token-provider-demo"></docs-lit-demo>
|
|
37
|
+
|
|
38
|
+
## HTTP 498 — stale token refresh
|
|
39
|
+
|
|
40
|
+
Initial `token="docs-mock-stale-token"` → mock responds **498** → Concorde invalidates the token, runs `auth()` again (same `tokenProvider` + Basic), retries with `docs-mock-fresh-token`.
|
|
41
|
+
|
|
42
|
+
<docs-lit-demo for="docs-api-config-stale-token-demo"></docs-lit-demo>
|
|
43
|
+
|
|
44
|
+
## eventsApiToken
|
|
45
|
+
|
|
46
|
+
Attribute **`eventsApiToken`** on an ancestor maps to **`authToken`** in config (used as Bearer when calling `tokenProvider`, instead of Basic).
|
|
47
|
+
|
|
48
|
+
<docs-lit-demo for="docs-api-config-events-token-demo"></docs-lit-demo>
|
|
49
|
+
|
|
50
|
+
## Wording API
|
|
51
|
+
|
|
52
|
+
`wordingProvider` and `wordingVersionProvider` are read by the translation directive: see [t()](/docs/directives/t).
|
|
53
|
+
|
|
54
|
+
## Scoped attributes (HTML / sonic-scope)
|
|
55
|
+
|
|
56
|
+
Attributes on **`sonic-scope`** (or any ancestor) are visible to descendants via `getAncestorAttributeValue`.
|
|
57
|
+
|
|
58
|
+
<docs-lit-demo for="docs-api-config-scoped-attrs-demo"></docs-lit-demo>
|
|
59
|
+
|
|
60
|
+
## API config routes
|
|
61
|
+
|
|
62
|
+
| Route | Demo |
|
|
63
|
+
|-------|------|
|
|
64
|
+
| `GET /docs-mock-api/auth/token` | tokenProvider, eventsApiToken |
|
|
65
|
+
| `GET /docs-mock-api/api/config/protected` | Bearer / Basic / 498 |
|
|
66
|
+
| `GET /docs-mock-api/wording/labels?labels[]=…&lang=fr` | `wording()` |
|
|
67
|
+
|
|
68
|
+
Mock tokens (doc only): `docs-mock-valid-token`, `docs-mock-stale-token` (498), `docs-mock-fresh-token` (after refresh). Basic: **demo** / **secret**. Events token: `docs-mock-events-token`.
|
|
69
|
+
|
|
70
|
+
Implementation: `src/docs/mock-api/api-config-mock.ts` (bundled in the Service Worker with `router.ts`).
|
|
71
|
+
|
|
72
|
+
## See also
|
|
73
|
+
|
|
74
|
+
- [@get](/docs/decorators/get) — `APIConfiguration` + `Endpoint`
|
|
75
|
+
- [@post](/docs/decorators/post) — same configuration model for POST
|
|
76
|
+
- [@put](/docs/decorators/put) · [@patch](/docs/decorators/patch) — PUT / PATCH
|
|
77
|
+
- [Endpoint](/docs/misc/endpoint) — typed path
|
|
78
|
+
- [Local API demos](/docs/misc/docs-mock-api) — offline `serviceURL`
|
|
79
|
+
- [Fetch](/core/components/functional/fetch) — attribute table (legacy sonic-fetch)
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# DataProviderKey
|
|
2
|
+
|
|
3
|
+
The `DataProviderKey<T>` utility provides type-safe navigation through composite data structures. Each property or index access extends the path, and the final key can be retrieved via `toString()` or the `path` property.
|
|
4
|
+
|
|
5
|
+
For a **single HTTP path string** (no dot-syntax), see [Endpoint](/docs/misc/endpoint). For **`DataProviderKey<APIConfiguration>`**, see [API configuration](/docs/misc/api-configuration).
|
|
6
|
+
|
|
7
|
+
## Principle
|
|
8
|
+
|
|
9
|
+
`DataProviderKey` uses a Proxy to intercept property access and build a cumulative path string. TypeScript infers the nested type at each level, so `myKey.items[0]` is correctly typed as `DataProviderKey<Item>` when `items` is `Item[]`.
|
|
10
|
+
|
|
11
|
+
In Lit demos, bind HTML attributes from a key’s **`.path`** (single source of truth), and use **`get` / `set` / `dp`** instead of `PublisherManager.get("…")`:
|
|
12
|
+
|
|
13
|
+
<sonic-code language="typescript">
|
|
14
|
+
<template>
|
|
15
|
+
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
16
|
+
import { get, set } from "@supersoniks/concorde/utils";
|
|
17
|
+
|
|
18
|
+
export const myFormKey = new DataProviderKey<{ email: string }>("myForm");
|
|
19
|
+
set(myFormKey, { email: "a@b.c" });
|
|
20
|
+
|
|
21
|
+
// template: formDataProvider=${myFormKey.path}
|
|
22
|
+
</template>
|
|
23
|
+
</sonic-code>
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Import
|
|
28
|
+
|
|
29
|
+
<sonic-code language="typescript">
|
|
30
|
+
<template>
|
|
31
|
+
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
32
|
+
</template>
|
|
33
|
+
</sonic-code>
|
|
34
|
+
|
|
35
|
+
### Basic example
|
|
36
|
+
|
|
37
|
+
<sonic-code language="typescript">
|
|
38
|
+
<template>
|
|
39
|
+
type Item = { id: string; name: string };
|
|
40
|
+
//
|
|
41
|
+
type Data = {
|
|
42
|
+
items: Item[];
|
|
43
|
+
count: number;
|
|
44
|
+
};
|
|
45
|
+
//
|
|
46
|
+
const myKey = new DataProviderKey<Data>("data").items[0];
|
|
47
|
+
// Equivalent to: new DataProviderKey<Item>("data.items.0")
|
|
48
|
+
myKey.toString(); // "data.items.0"
|
|
49
|
+
myKey.path; // same value
|
|
50
|
+
// myKey is typed as DataProviderKey<Item>
|
|
51
|
+
</template>
|
|
52
|
+
</sonic-code>
|
|
53
|
+
|
|
54
|
+
### Object property access
|
|
55
|
+
|
|
56
|
+
<sonic-code language="typescript">
|
|
57
|
+
<template>
|
|
58
|
+
const key = new DataProviderKey<Data>("data");
|
|
59
|
+
const countKey = key.count;
|
|
60
|
+
countKey.path; // "data.count"
|
|
61
|
+
countKey.toString(); // "data.count"
|
|
62
|
+
</template>
|
|
63
|
+
</sonic-code>
|
|
64
|
+
|
|
65
|
+
### Array index access
|
|
66
|
+
|
|
67
|
+
<sonic-code language="typescript">
|
|
68
|
+
<template>
|
|
69
|
+
const itemsKey = new DataProviderKey<Data>("data").items;
|
|
70
|
+
itemsKey.path; // "data.items"
|
|
71
|
+
// itemsKey is DataProviderKey<Item[]>
|
|
72
|
+
//
|
|
73
|
+
const firstItem = itemsKey[0];
|
|
74
|
+
firstItem.path; // "data.items.0"
|
|
75
|
+
// firstItem is DataProviderKey<Item>
|
|
76
|
+
</template>
|
|
77
|
+
</sonic-code>
|
|
78
|
+
|
|
79
|
+
### Dynamic paths
|
|
80
|
+
|
|
81
|
+
Use placeholders `${prop}` or `{$prop}` in the path string. The path is resolved at runtime from the component's properties. See [Dynamic path placeholders](/docs/misc/dynamic-path) for resolution rules and `skipEmptyPlaceholder`. The type remains declarative:
|
|
82
|
+
|
|
83
|
+
<sonic-code language="typescript">
|
|
84
|
+
<template>
|
|
85
|
+
type User = { name: string; email: string };
|
|
86
|
+
//
|
|
87
|
+
// Path resolved from component.userIndex at runtime
|
|
88
|
+
@subscribe(new DataProviderKey<User>("users.${userIndex}"))
|
|
89
|
+
@state()
|
|
90
|
+
user: User | null = null;
|
|
91
|
+
</template>
|
|
92
|
+
</sonic-code>
|
|
93
|
+
|
|
94
|
+
Dynamic keys are **not** supported by `get`, `set`, or `dp` — those APIs take a snapshot at call time with no component context. For dynamic paths use decorators (`@subscribe`, `@publish`, `@handle`) or **`sub(key)`** in Lit templates (resolves `${…}` from the host component). See [sub()](/docs/directives/sub).
|
|
95
|
+
|
|
96
|
+
### get / set / dp with static keys
|
|
97
|
+
|
|
98
|
+
For programmatic access, pass a `DataProviderKey` or a static path string. Dynamic placeholders are rejected:
|
|
99
|
+
|
|
100
|
+
<sonic-code language="typescript">
|
|
101
|
+
<template>
|
|
102
|
+
import { dp, get, set } from "@supersoniks/concorde/utils";
|
|
103
|
+
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
104
|
+
//
|
|
105
|
+
const counterKey = new DataProviderKey<{ count: number }>("myCounter");
|
|
106
|
+
//
|
|
107
|
+
set(counterKey, { count: 0 });
|
|
108
|
+
dp(counterKey.count).set(1);
|
|
109
|
+
get(counterKey); // snapshot: { count: 1 }
|
|
110
|
+
</template>
|
|
111
|
+
</sonic-code>
|
|
112
|
+
|
|
113
|
+
## Path retrieval
|
|
114
|
+
|
|
115
|
+
The final path is built by concatenating each accessed property with a dot:
|
|
116
|
+
|
|
117
|
+
- `new DataProviderKey<T>("base")` → `"base"`
|
|
118
|
+
- `key.prop` → `"base.prop"`
|
|
119
|
+
- `key.items[0]` → `"base.items.0"`
|
|
120
|
+
|
|
121
|
+
Use `toString()` or `path` to get the full path string:
|
|
122
|
+
|
|
123
|
+
<sonic-code language="typescript">
|
|
124
|
+
<template>
|
|
125
|
+
const key = new DataProviderKey<Data>("data").count;
|
|
126
|
+
const pathString = key.toString(); // "data.count"
|
|
127
|
+
const pathProp = key.path; // "data.count"
|
|
128
|
+
</template>
|
|
129
|
+
</sonic-code>
|
|
130
|
+
|
|
131
|
+
## Use cases
|
|
132
|
+
|
|
133
|
+
- **Type-safe bindings**: paths for `@bind`, `@subscribe`, `@publish`, `@handle`
|
|
134
|
+
- **Dynamic paths**: reusable keys with `${...}` placeholders
|
|
135
|
+
- **Form fields**: form data paths with compile-time checking
|
|
136
|
+
|
|
137
|
+
## Integration with @subscribe, @publish and @handle
|
|
138
|
+
|
|
139
|
+
Use `DataProviderKey` with `@subscribe` (read-only), `@publish` (write-only), or `@handle` (method callback on assign). With `@subscribe` / `@publish`, the decorated property **must** match the key’s value type. With `@handle`, the method receives `(value: T)`.
|
|
140
|
+
|
|
141
|
+
<sonic-code language="typescript">
|
|
142
|
+
<template>
|
|
143
|
+
import { subscribe } from "@supersoniks/concorde/decorators";
|
|
144
|
+
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
145
|
+
//
|
|
146
|
+
type FormData = { email: string };
|
|
147
|
+
const formKey = new DataProviderKey<FormData>("formData");
|
|
148
|
+
//
|
|
149
|
+
@customElement("user-form")
|
|
150
|
+
export class UserForm extends LitElement {
|
|
151
|
+
@subscribe(formKey.email)
|
|
152
|
+
@state()
|
|
153
|
+
email = "";
|
|
154
|
+
//
|
|
155
|
+
render() {
|
|
156
|
+
return html`<input .value=${this.email} @input=${(e) => this.email = (e.target as HTMLInputElement).value}>`;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
</template>
|
|
160
|
+
</sonic-code>
|
|
161
|
+
|
|
162
|
+
These decorators support dynamic paths: `"base.${prop}"` in the constructor. A wrong property type (e.g. `number` for `DataProviderKey<string>`) is a TypeScript error. Resolution rules: [Dynamic path placeholders](/docs/misc/dynamic-path). See [@handle](/docs/decorators/handle) for method callbacks.
|
|
163
|
+
|
|
164
|
+
## Notes
|
|
165
|
+
|
|
166
|
+
- Function properties are excluded from navigation (no `key.method()` chaining)
|
|
167
|
+
- Primitives have no navigable properties
|
|
168
|
+
- The `path` property and `toString()` are equivalent for retrieving the key
|