@supersoniks/concorde 5.1.1 → 5.1.3-immutable.1
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/skills +1 -0
- package/.github/workflows/ci.yml +21 -0
- package/.github-export-ignore +30 -0
- package/CONTRIBUTING.md +59 -0
- package/DEV.md +54 -0
- package/LICENSE +21 -0
- package/OPEN_SOURCE_CHECKPOINT.md +133 -0
- package/README.md +4 -4
- package/ai/README.md +29 -41
- package/ai/skills/concorde/SKILL.md +54 -324
- package/ai/skills/concorde/rules/composition.md +32 -0
- package/ai/skills/concorde/rules/data.md +47 -0
- package/ai/skills/concorde/rules/http.md +25 -0
- package/ai/skills/concorde/rules/lists-forms.md +35 -0
- package/ai/skills/concorde/rules/styling.md +46 -0
- package/ai/skills/concorde/rules/troubleshooting.md +45 -0
- package/build-infos.json +1 -1
- package/concorde-core.bundle.js +177 -177
- package/concorde-core.es.js +4993 -4833
- package/custom-elements-manifest.public.config.mjs +8 -0
- package/{.tmp-cem/custom-elements.json → custom-elements.json} +11758 -8904
- package/dist/concorde-core.bundle.js +177 -177
- package/dist/concorde-core.es.js +4993 -4833
- package/dist/docs-mock-api-sw.js +58 -223
- package/dist/docs-mock-api-sw.js.map +4 -4
- package/dist/img/concorde/plane_01.jpg +0 -0
- package/dist/img/concorde/plane_02.jpg +0 -0
- package/dist/img/concorde/plane_03.jpg +0 -0
- package/dist/img/concorde/plane_04.jpg +0 -0
- package/dist/img/concorde/plane_05.jpg +0 -0
- package/dist/img/concorde/plane_06.jpg +0 -0
- package/dist/img/concorde/plane_07.jpg +0 -0
- package/dist/img/concorde/plane_08.jpg +0 -0
- package/dist/img/concorde/plane_09.jpg +0 -0
- package/dist/img/concorde/plane_10.jpg +0 -0
- package/dist/img/concorde/plane_11.jpg +0 -0
- package/dist/img/concorde/plane_12.jpg +0 -0
- package/dist/img/concorde/plane_13.jpg +0 -0
- package/dist/img/og-concorde.jpg +0 -0
- package/dist/robots.txt +11 -10
- package/docs/assets/index-D_alEsng.js +12122 -0
- package/docs/crawl/core/components/functional/date/date.html +190 -0
- package/docs/crawl/core/components/functional/fetch/fetch.html +109 -0
- package/docs/crawl/core/components/functional/if/if.html +27 -0
- package/docs/crawl/core/components/functional/jsonata/jsonata.html +79 -0
- package/docs/crawl/core/components/functional/list/list.html +70 -0
- package/docs/crawl/core/components/functional/mix/mix.html +45 -0
- package/docs/crawl/core/components/functional/queue/queue.html +96 -0
- package/docs/crawl/core/components/functional/router/router.html +106 -0
- package/docs/crawl/core/components/functional/sdui/sdui-extension-points.html +126 -0
- package/docs/crawl/core/components/functional/sdui/sdui.html +368 -0
- package/docs/crawl/core/components/functional/states/states.html +66 -0
- package/docs/crawl/core/components/functional/submit/submit.html +160 -0
- package/docs/crawl/core/components/functional/subscriber/subscriber.html +67 -0
- package/docs/crawl/core/components/functional/value/value.html +51 -0
- package/docs/crawl/core/components/ui/alert/alert.html +211 -0
- package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +131 -0
- package/docs/crawl/core/components/ui/badge/badge.html +197 -0
- package/docs/crawl/core/components/ui/button/button.html +150 -0
- package/docs/crawl/core/components/ui/captcha/captcha.html +112 -0
- package/docs/crawl/core/components/ui/card/card.html +253 -0
- package/docs/crawl/core/components/ui/divider/divider.html +144 -0
- package/docs/crawl/core/components/ui/form/checkbox/checkbox.html +73 -0
- package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +266 -0
- package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +122 -0
- package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +121 -0
- package/docs/crawl/core/components/ui/form/input/input.html +109 -0
- package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +38 -0
- package/docs/crawl/core/components/ui/form/radio/radio.html +56 -0
- package/docs/crawl/core/components/ui/form/select/select.html +73 -0
- package/docs/crawl/core/components/ui/form/switch/switch.html +56 -0
- package/docs/crawl/core/components/ui/form/textarea/textarea.html +59 -0
- package/docs/crawl/core/components/ui/group/group.html +104 -0
- package/docs/crawl/core/components/ui/icon/icon.html +222 -0
- package/docs/crawl/core/components/ui/image/image.html +298 -0
- package/docs/crawl/core/components/ui/link/link.html +100 -0
- package/docs/crawl/core/components/ui/loader/loader.html +124 -0
- package/docs/crawl/core/components/ui/menu/menu.html +394 -0
- package/docs/crawl/core/components/ui/modal/modal.html +342 -0
- package/docs/crawl/core/components/ui/pop/pop.html +296 -0
- package/docs/crawl/core/components/ui/progress/progress.html +131 -0
- package/docs/crawl/core/components/ui/table/table.html +545 -0
- package/docs/crawl/core/components/ui/theme/theme.html +131 -0
- package/docs/crawl/core/components/ui/toast/toast.html +233 -0
- package/docs/crawl/core/components/ui/tooltip/tooltip.html +140 -0
- package/docs/crawl/docs/_core-concept/dataFlow.html +177 -0
- package/docs/crawl/docs/_core-concept/overview.html +66 -0
- package/docs/crawl/docs/_core-concept/subscriber.html +75 -0
- package/docs/crawl/docs/_decorators/ancestor-attribute.html +117 -0
- package/docs/crawl/docs/_decorators/auto-subscribe.html +202 -0
- package/docs/crawl/docs/_decorators/bind.html +141 -0
- package/docs/crawl/docs/_decorators/get.html +149 -0
- package/docs/crawl/docs/_decorators/handle.html +165 -0
- package/docs/crawl/docs/_decorators/on-assign.html +355 -0
- package/docs/crawl/docs/_decorators/patch.html +78 -0
- package/docs/crawl/docs/_decorators/post.html +139 -0
- package/docs/crawl/docs/_decorators/publish.html +61 -0
- package/docs/crawl/docs/_decorators/put.html +78 -0
- package/docs/crawl/docs/_decorators/subscribe.html +109 -0
- package/docs/crawl/docs/_decorators/wait-for-ancestors.html +137 -0
- package/docs/crawl/docs/_directives/sub.html +93 -0
- package/docs/crawl/docs/_getting-started/ai-agents.html +173 -0
- package/docs/crawl/docs/_getting-started/concorde-manual-install.html +100 -0
- package/docs/crawl/docs/_getting-started/concorde-outside.html +58 -0
- package/docs/crawl/docs/_getting-started/create-a-component.html +111 -0
- package/docs/crawl/docs/_getting-started/my-first-component.html +189 -0
- package/docs/crawl/docs/_getting-started/my-first-subscriber.html +110 -0
- package/docs/crawl/docs/_getting-started/pubsub.html +62 -0
- package/docs/crawl/docs/_getting-started/start.html +76 -0
- package/docs/crawl/docs/_getting-started/theming.html +333 -0
- package/docs/crawl/docs/_misc/api-configuration.html +149 -0
- package/docs/crawl/docs/_misc/dataProviderKey.html +135 -0
- package/docs/crawl/docs/_misc/docs-mock-api.html +158 -0
- package/docs/crawl/docs/_misc/dynamic-path.html +180 -0
- package/docs/crawl/docs/_misc/endpoint.html +50 -0
- package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +138 -0
- package/docs/crawl/docs/_misc/html-integration.html +48 -0
- package/docs/crawl/hubs/decorators.html +547 -0
- package/docs/crawl/hubs/form-components.html +381 -0
- package/docs/crawl/hubs/remote-data.html +452 -0
- package/docs/crawl/index.html +103 -0
- package/docs/index.html +1 -1
- package/docs/llms-full.txt +7174 -0
- package/docs/llms.txt +98 -0
- package/docs/sitemap.xml +243 -0
- package/docs/src/core/components/functional/date/date.md +290 -0
- package/docs/src/core/components/functional/fetch/fetch.md +125 -0
- package/docs/src/core/components/functional/if/if.md +9 -0
- package/docs/src/core/components/functional/jsonata/jsonata.md +56 -0
- package/docs/src/core/components/functional/list/list.md +65 -0
- package/docs/src/core/components/functional/mix/mix.md +41 -0
- package/docs/src/core/components/functional/queue/queue.md +72 -0
- package/docs/src/core/components/functional/router/router.md +94 -0
- 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/default-library.json +108 -0
- package/docs/src/core/components/functional/sdui/example.json +99 -0
- package/docs/src/core/components/functional/sdui/sdui-extension-points.md +94 -0
- package/docs/src/core/components/functional/sdui/sdui.md +478 -0
- package/docs/src/core/components/functional/states/states.md +87 -0
- package/docs/src/core/components/functional/submit/submit.md +114 -0
- package/docs/src/core/components/functional/subscriber/subscriber.md +91 -0
- package/docs/src/core/components/functional/value/value.md +35 -0
- package/docs/src/core/components/ui/alert/alert.md +196 -0
- package/docs/src/core/components/ui/alert-messages/alert-messages.md +85 -0
- package/docs/src/core/components/ui/badge/badge.md +188 -0
- package/docs/src/core/components/ui/button/button.md +183 -0
- package/docs/src/core/components/ui/captcha/captcha.md +71 -0
- package/docs/src/core/components/ui/card/card.md +215 -0
- package/docs/src/core/components/ui/divider/divider.md +129 -0
- package/docs/src/core/components/ui/form/checkbox/checkbox.md +77 -0
- package/docs/src/core/components/ui/form/fieldset/fieldset.md +205 -0
- package/docs/src/core/components/ui/form/form-actions/form-actions.md +100 -0
- package/docs/src/core/components/ui/form/form-layout/form-layout.md +119 -0
- package/docs/src/core/components/ui/form/input/input.md +142 -0
- package/docs/src/core/components/ui/form/radio/radio.md +57 -0
- package/docs/src/core/components/ui/form/select/select.md +71 -0
- package/docs/src/core/components/ui/form/switch/switch.md +57 -0
- package/docs/src/core/components/ui/form/textarea/textarea.md +65 -0
- package/docs/src/core/components/ui/group/group.md +75 -0
- package/docs/src/core/components/ui/icon/icon.md +214 -0
- package/docs/src/core/components/ui/icon/icons.json +1 -0
- package/docs/src/core/components/ui/image/image.md +233 -0
- package/docs/src/core/components/ui/link/link.md +81 -0
- package/docs/src/core/components/ui/loader/loader.md +112 -0
- package/docs/src/core/components/ui/menu/menu.md +370 -0
- package/docs/src/core/components/ui/modal/modal.md +235 -0
- package/docs/src/core/components/ui/pop/pop.md +294 -0
- package/docs/src/core/components/ui/progress/progress.md +109 -0
- package/docs/src/core/components/ui/table/table.md +431 -0
- package/docs/src/core/components/ui/theme/theme.md +122 -0
- package/docs/src/core/components/ui/toast/toast.md +216 -0
- package/docs/src/core/components/ui/tooltip/tooltip.md +124 -0
- package/{src → docs/src}/docs/_core-concept/subscriber.md +0 -0
- package/{src → docs/src}/docs/_getting-started/my-first-subscriber.md +0 -0
- package/{src → docs/src}/docs/_getting-started/pubsub.md +0 -0
- package/docs/src/docs/_getting-started/theming.md +253 -0
- package/docs/src/docs/search/docs-search.json +12242 -0
- package/docs/src/tag-list.json +1 -0
- package/docs/src/tsconfig-model.json +23 -0
- package/docs/src/tsconfig.declarations.json +22 -0
- package/docs/src/tsconfig.emit.json +23 -0
- package/docs/src/tsconfig.json +1332 -0
- package/gitlab/job_github_mirror.sh +39 -0
- package/index.html +157 -5
- package/package.json +22 -4
- package/public/docs-mock-api-sw.js +58 -223
- package/public/docs-mock-api-sw.js.map +4 -4
- 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/img/og-concorde.jpg +0 -0
- package/public/robots.txt +11 -10
- package/scripts/ai-init.mjs +104 -379
- package/scripts/ai-init.test.mjs +81 -239
- package/scripts/docs-markdown-vite-plugin.ts +43 -0
- package/scripts/docs-public-url.mjs +56 -0
- package/scripts/docs.htaccess +82 -0
- package/scripts/generate-cem.mjs +244 -0
- package/scripts/generate-cem.test.mjs +122 -0
- package/scripts/generate-crawl-docs.mjs +233 -118
- package/scripts/generate-crawl-docs.test.mjs +124 -0
- package/scripts/generate-sdui-catalog.mjs +11 -10
- package/scripts/github-export.mjs +150 -0
- package/scripts/post-build-docs.js +37 -50
- package/scripts/post-build.mjs +0 -0
- package/scripts/pre-publish.mjs +2 -1
- package/scripts/site-pages.mjs +212 -0
- package/scripts/site-pages.test.mjs +116 -0
- package/site-pages/about.md +22 -0
- package/site-pages/privacy.md +32 -0
- package/src/core/components/functional/date/date.md +91 -231
- package/src/core/components/functional/example/example.ts +3 -1
- 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 +103 -43
- package/src/core/components/functional/list/list.ts +17 -4
- 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 +2 -2
- 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-immutable.spec.ts +74 -0
- package/src/core/components/functional/sdui/sdui.md +187 -358
- package/src/core/components/functional/sdui/sdui.ts +33 -8
- 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/submit/submit.spec.ts +60 -0
- package/src/core/components/functional/submit/submit.ts +6 -3
- 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 +108 -90
- package/src/core/components/ui/form/input/input.ts +8 -2
- package/src/core/components/ui/form/radio/radio.md +65 -30
- 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/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/decorators/subscriber/bind.ts +9 -14
- package/src/core/decorators/subscriber/subscribe.ts +15 -9
- package/src/core/decorators/subscriber/subscribe.type-test.ts +14 -5
- 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/PublisherProxy.ts +166 -125
- package/src/core/utils/deepReadonly.spec.ts +66 -0
- package/src/core/utils/deepReadonly.ts +71 -0
- package/src/core/utils/immutableValue.spec.ts +54 -0
- package/src/core/utils/immutableValue.ts +102 -0
- package/src/core/utils/nestedDotForm.spec.ts +88 -0
- package/src/core/utils/publisherImmutable.spec.ts +76 -0
- package/src/core/utils/route.ts +0 -0
- package/src/core/utils/strictGet.spec.ts +61 -0
- package/src/core/utils/strictGet.ts +102 -0
- package/src/css.d.ts +19 -0
- package/src/docs/components/docs-demo-sources.ts +55 -140
- package/src/docs/components/docs-lit-demo.ts +1 -3
- 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 +76 -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 +56 -0
- package/src/docs/docs-location.ts +133 -32
- package/src/docs/docs.ts +1 -2
- package/src/docs/example/decorators-demo-bind-demos.ts +83 -135
- 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-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 +21 -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 +50 -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/header/header.ts +11 -6
- package/src/docs/home/catalog.ts +1 -1
- package/src/docs/home/home.ts +20 -11
- package/src/docs/layout.ts +12 -13
- 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/misc/publisher-get-immutability-docs-crawl.json +902 -0
- package/src/docs/misc/publisher-get-immutability-docs-recheck.json +13 -0
- package/src/docs/misc/publisher-get-immutability-study.md +229 -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/navigation.ts +84 -101
- package/src/docs/navigation/toc.ts +7 -4
- package/src/docs/search/docs-search.json +3188 -5153
- package/src/docs/search/markdown-renderer.ts +31 -8
- package/src/docs/search/page.ts +9 -6
- package/src/docs/search/search.ts +154 -122
- package/src/docs/tailwind/css/docs/content.css +4 -5
- package/src/tsconfig.declarations.json +22 -0
- package/src/tsconfig.emit.json +23 -0
- package/src/tsconfig.json +53 -5
- package/src/tsconfig.tsbuildinfo +1 -1
- package/vite.config.mts +11 -2
- package/.agents/skills/concorde-component-docs/SKILL.md +0 -194
- 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 +0 -4103
- 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 +0 -2556
- package/.taste-skill/before/tablet-fold.jpg +0 -0
- package/.taste-skill/before/tablet-page-01.jpg +0 -0
- package/.taste-skill/direction.json +0 -510
- package/.taste-skill/notes.md +0 -84
- 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 +0 -1973
- 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/AUDIT.md +0 -228
- package/PLAN-AMELIORATION.md +0 -220
- package/ai/AGENTS.md +0 -56
- package/ai/cursor/rules/concorde-menu.mdc +0 -15
- package/ai/cursor/rules/concorde-scope.mdc +0 -14
- package/ai/cursor/rules/concorde-theme.mdc +0 -13
- package/ai/cursor/rules/concorde.mdc +0 -66
- package/ai/jetbrains/rules/concorde.md +0 -53
- package/ai/skills/concorde-get-set-dp/SKILL.md +0 -194
- package/ai/skills/concorde-imports/SKILL.md +0 -78
- package/ai/skills/concorde-menu/SKILL.md +0 -74
- package/ai/skills/concorde-scope/SKILL.md +0 -70
- package/ai/skills/concorde-theme/SKILL.md +0 -57
- package/docs/assets/index-Bb-_LRyY.js +0 -12280
- package/src/docs/example/docs-input-autocomplete-demos.ts +0 -110
- package/src/docs/example/docs-joke-demos.ts +0 -297
- /package/{src → docs/src}/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -0
- /package/{src → docs/src}/docs/_core-concept/dataFlow.md +0 -0
- /package/{src → docs/src}/docs/_core-concept/overview.md +0 -0
- /package/{src → docs/src}/docs/_decorators/ancestor-attribute.md +0 -0
- /package/{src → docs/src}/docs/_decorators/auto-subscribe.md +0 -0
- /package/{src → docs/src}/docs/_decorators/bind.md +0 -0
- /package/{src → docs/src}/docs/_decorators/get.md +0 -0
- /package/{src → docs/src}/docs/_decorators/handle.md +0 -0
- /package/{src → docs/src}/docs/_decorators/on-assign.md +0 -0
- /package/{src → docs/src}/docs/_decorators/patch.md +0 -0
- /package/{src → docs/src}/docs/_decorators/post.md +0 -0
- /package/{src → docs/src}/docs/_decorators/publish.md +0 -0
- /package/{src → docs/src}/docs/_decorators/put.md +0 -0
- /package/{src → docs/src}/docs/_decorators/subscribe.md +0 -0
- /package/{src → docs/src}/docs/_decorators/wait-for-ancestors.md +0 -0
- /package/{src → docs/src}/docs/_directives/sub.md +0 -0
- /package/{src → docs/src}/docs/_getting-started/ai-agents.md +0 -0
- /package/{src → docs/src}/docs/_getting-started/concorde-manual-install.md +0 -0
- /package/{src → docs/src}/docs/_getting-started/concorde-outside.md +0 -0
- /package/{src → docs/src}/docs/_getting-started/create-a-component.md +0 -0
- /package/{src → docs/src}/docs/_getting-started/my-first-component.md +0 -0
- /package/{src → docs/src}/docs/_getting-started/start.md +0 -0
- /package/{src → docs/src}/docs/_misc/api-configuration.md +0 -0
- /package/{src → docs/src}/docs/_misc/dataProviderKey.md +0 -0
- /package/{src → docs/src}/docs/_misc/docs-mock-api.md +0 -0
- /package/{src → docs/src}/docs/_misc/dynamic-path.md +0 -0
- /package/{src → docs/src}/docs/_misc/endpoint.md +0 -0
- /package/{src → docs/src}/docs/_misc/formelement-subscriber-removal.md +0 -0
- /package/{src → docs/src}/docs/_misc/html-integration.md +0 -0
- /package/src/docs/{_getting-started → getting-started}/components.md +0 -0
- /package/src/docs/{_getting-started → getting-started}/theming.md +0 -0
package/ai/README.md
CHANGED
|
@@ -1,58 +1,46 @@
|
|
|
1
1
|
# Agent IA — Concorde
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Une skill unique, `concorde` (format [Agent Skills](https://agentskills.io)), installable dans un projet : Cursor, Claude Code, JetBrains Junie et tout agent qui lit `.agents/skills`.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Options :
|
|
5
|
+
## Structure
|
|
12
6
|
|
|
13
|
-
|
|
14
|
-
- `--skip-agents` — n’écrit jamais `AGENTS.md` (skills / rules seulement)
|
|
15
|
-
- `--merge-agents` — opt-in : conserve le préambule projet et ajoute / rafraîchit le bloc Concorde
|
|
16
|
-
- `--force-agents` — opt-in : **remplace** tout `AGENTS.md` (destructif)
|
|
17
|
-
- `--cursor-only` / `--jetbrains-only`
|
|
7
|
+
Sur le modèle de la skill shadcn : un point d’entrée court, des fichiers de règles lus à la demande.
|
|
18
8
|
|
|
19
|
-
|
|
9
|
+
```text
|
|
10
|
+
skills/concorde/
|
|
11
|
+
SKILL.md point d’entrée : sources (projet, doc, custom-elements.json), règles critiques, imports
|
|
12
|
+
rules/data.md store, DataProviderKey, décorateurs, sub(), get / set / dp
|
|
13
|
+
rules/http.md Endpoint, @get / @post, configuration API
|
|
14
|
+
rules/lists-forms.md
|
|
15
|
+
rules/styling.md thème, tokens, règles de style
|
|
16
|
+
rules/composition.md parties des composants composés, états intégrés
|
|
17
|
+
rules/troubleshooting.md symptôme → cause → correction
|
|
18
|
+
```
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
Ajouter un sujet = un fichier dans `rules/` + une ligne dans le tableau « Rules files » de `SKILL.md`. Pas de nouvelle skill sauf besoin vraiment distinct.
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|-----------|-------------------------|
|
|
25
|
-
| Pas de `AGENTS.md` | Création du guide Concorde |
|
|
26
|
-
| Fichier avec `<!-- concorde-ai -->` | Rafraîchit la zone gérée seulement |
|
|
27
|
-
| Fichier **sans** marker (notes projet) | **Laissé intact** — skills / rules suffisent |
|
|
28
|
-
| `--merge-agents` | Préambule projet + bloc Concorde après le marker |
|
|
29
|
-
| `--force-agents` | Remplacement complet |
|
|
30
|
-
| `--skip-agents` | Jamais d’écriture `AGENTS.md` |
|
|
22
|
+
## Installation dans un projet
|
|
31
23
|
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
<!-- concorde-ai -->
|
|
35
|
-
<package ai/AGENTS.md>
|
|
36
|
-
[--- + overlay AGENTS.concorde.md]
|
|
24
|
+
```bash
|
|
25
|
+
node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
|
|
37
26
|
```
|
|
38
27
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
Depuis le dépôt Concorde : `yarn ai-init`.
|
|
29
|
+
|
|
30
|
+
| Source | Cible dans le projet |
|
|
31
|
+
|--------|---------------------|
|
|
32
|
+
| `skills/<nom>/` | `.agents/skills/<nom>/` (copie ; lue directement par Cursor) |
|
|
33
|
+
| — | `.claude/skills/<nom>` et `.junie/skills/<nom>` : liens symboliques (copie si les liens sont interdits) |
|
|
43
34
|
|
|
44
|
-
|
|
35
|
+
Options :
|
|
45
36
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
| `cursor/rules/` | `.cursor/rules/` |
|
|
50
|
-
| `jetbrains/rules/` | `.aiassistant/rules/` |
|
|
51
|
-
| `AGENTS.md` | racine du projet **seulement** si absent, déjà marqué, ou via `--merge-agents` / `--force-agents` |
|
|
37
|
+
- `--overlay <dir>` — skills supplémentaires d’un kit projet (`<dir>/skills/<nom>/`)
|
|
38
|
+
- `--no-links` — `.agents/skills` seulement
|
|
39
|
+
- `--project-root <dir>`, `--concorde-ai <dir>`
|
|
52
40
|
|
|
53
|
-
|
|
41
|
+
**`AGENTS.md` appartient au projet** : `ai-init` ne le lit ni ne l’écrit. Les agents trouvent la skill seuls, par sa description.
|
|
54
42
|
|
|
55
|
-
|
|
43
|
+
Seules les skills du package sont remplacées ; une skill du projet portant le même nom n’est jamais écrasée. Si `.claude/skills` pointe déjà vers `.agents/skills`, aucun lien par skill n’est créé.
|
|
56
44
|
|
|
57
45
|
## Tests
|
|
58
46
|
|
|
@@ -1,348 +1,78 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: concorde
|
|
3
3
|
description: >-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
Entry point for any work in a project that uses Concorde
|
|
5
|
+
(@supersoniks/concorde), the Lit web components library: writing components,
|
|
6
|
+
reading or writing the DataProvider store, calling APIs, lists, forms,
|
|
7
|
+
styling with sonic-* components and theme tokens, imports. Use whenever code
|
|
8
|
+
imports @supersoniks/concorde or uses sonic-* elements.
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
# Concorde
|
|
11
|
+
# Concorde
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
Lit + TypeScript web components (`sonic-*`) with a shared data store, the **DataProvider**. This file holds the critical rules; read the matching file in `rules/` before working on that topic.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
## Rules files
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
| Topic | Read |
|
|
18
|
+
|-------|------|
|
|
19
|
+
| Store, `DataProviderKey`, `@subscribe` / `@publish` / `@bind` / `@handle`, `sub()`, `get` / `set` / `dp` | [rules/data.md](rules/data.md) |
|
|
20
|
+
| HTTP: `Endpoint`, `@get` / `@post`, API configuration | [rules/http.md](rules/http.md) |
|
|
21
|
+
| `sonic-list` / `sonic-queue`, forms | [rules/lists-forms.md](rules/lists-forms.md) |
|
|
22
|
+
| Theme, tokens, classes, styling rules | [rules/styling.md](rules/styling.md) |
|
|
23
|
+
| Which parts go in which component, built-in states | [rules/composition.md](rules/composition.md) |
|
|
24
|
+
| Something does not update, render or send | [rules/troubleshooting.md](rules/troubleshooting.md) |
|
|
17
25
|
|
|
18
|
-
##
|
|
26
|
+
## Sources of truth
|
|
19
27
|
|
|
20
|
-
|
|
28
|
+
1. **The project.** Check the installed version (`npm ls @supersoniks/concorde`); an API missing from it is not available. Reuse the project's `DataProviderKey`s, `Endpoint`s, API configuration and components before creating new ones.
|
|
29
|
+
2. **The docs.** Every page is Markdown when you append `.md` to its URL. Index: https://concorde.supersoniks.org/llms.txt · offline: `node_modules/@supersoniks/concorde/src/**/*.md`.
|
|
30
|
+
3. **The element API.** Attributes with allowed values, properties, events and slots are in `node_modules/@supersoniks/concorde/custom-elements.json`. It is large: query one element.
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
## Interdits pour du **nouveau** code
|
|
25
|
-
|
|
26
|
-
- **Ne pas** étendre les mixins `Subscriber` / `Fetcher` sur des composants métier.
|
|
27
|
-
- **Ne pas** utiliser `data-bind`, `data-publish`, `data-subscribe` en HTML.
|
|
28
|
-
- **Ne pas** mettre `@input`, `@change` ou `.value` + assignation manuelle sur **`sonic-input`** quand `formDataProvider` + `name` suffit.
|
|
29
|
-
- **Ne pas** introduire `@onAssign` — préférer `@handle` + `DataProviderKey`.
|
|
30
|
-
- **Ne pas** utiliser **`@bind`** sur les composants métier — préférer **`@subscribe`** + `DataProviderKey<T, U>` (typage + placeholders `${prop}` sur l’hôte).
|
|
31
|
-
- **Ne pas** utiliser **`sonic-fetch`** — préférer **`sonic-queue`** (+ filtre `formDataProvider`) ou **`@get`** + `Endpoint`.
|
|
32
|
-
- Les décorateurs API **`@get`**, **`@post`**, **`@put`** et **`@patch`**
|
|
33
|
-
s'adaptent aux propriétés et aux méthodes ; la méthode reçoit le
|
|
34
|
-
`ApiResult` complet.
|
|
35
|
-
- **Ne pas** importer **`PublisherManager`** — utiliser **`get` / `set`** (réexport Concorde ou wrapper projet).
|
|
36
|
-
- **Ne pas** promouvoir les templates HTML (`<template>`, `data-value`) pour **`sonic-list`** / **`sonic-queue`** — préférer **`.items`**, **`.noItems`**, **`.skeleton`**, **`.separator`** (binding propriété Lit obligatoire pour les fonctions).
|
|
37
|
-
|
|
38
|
-
## DataProvider
|
|
39
|
-
|
|
40
|
-
Store observable adressé par un chemin string :
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
import { dp, get, set } from "@supersoniks/concorde/utils";
|
|
44
|
-
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
45
|
-
|
|
46
|
-
const counterKey = new DataProviderKey<{ count: number }>("myCounter");
|
|
47
|
-
|
|
48
|
-
set(counterKey, { count: 0 });
|
|
49
|
-
dp(counterKey.count).set(1);
|
|
50
|
-
get(counterKey); // snapshot { count: 1 }
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Chemins **statiques** uniquement pour `get` / `set` / `dp`. Clés avec `${…}` → décorateurs ou **`sub(clé)`** dans les templates. Migration : skill **`concorde-get-set-dp`**.
|
|
54
|
-
|
|
55
|
-
Attributs HTML courants :
|
|
56
|
-
|
|
57
|
-
| Attribut | Rôle |
|
|
58
|
-
|----------|------|
|
|
59
|
-
| `dataProvider` | Lie un composant au DataProvider à ce chemin |
|
|
60
|
-
| `formDataProvider` | Conteneur de formulaire — les champs `name` écrivent dedans |
|
|
61
|
-
| `dataFilterProvider` | Filtre lu par `sonic-queue` (relance les requêtes) |
|
|
62
|
-
|
|
63
|
-
## DataProviderKey
|
|
64
|
-
|
|
65
|
-
### Chemins statiques
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
const counterKey = new DataProviderKey<{ count: number }>("myCounter");
|
|
69
|
-
counterKey.count.path; // "myCounter.count"
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Chemins dynamiques (placeholder)
|
|
73
|
-
|
|
74
|
-
Placeholder `${prop}` dans une **chaîne normale** (pas de backticks). Résolu depuis les propriétés du composant hôte ; ré-abonnement automatique quand elles changent.
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
export const userKey = new DataProviderKey<User, { userIndex: number }>(
|
|
78
|
-
"users.${userIndex}",
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
@property({ type: Number }) userIndex = 0;
|
|
82
|
-
|
|
83
|
-
@subscribe(userKey)
|
|
84
|
-
@state() user: User | null = null;
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Même mécanisme pour `@handle`, `@publish`, `@subscribe`. Éviter `@bind` (bidirectionnel / chemins string legacy).
|
|
88
|
-
|
|
89
|
-
Doc : `src/docs/_misc/dataProviderKey.md`, `src/docs/_decorators/subscribe.md`, `handle.md`.
|
|
90
|
-
|
|
91
|
-
## Endpoint
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
const users = new Endpoint<UsersResponse>("users?offset=$offset&limit=$limit");
|
|
95
|
-
users.path;
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Utilisé avec `@get(endpoint)` ou `@get(endpoint, apiConfigKey)` — voir **Scope** ci-dessous.
|
|
99
|
-
|
|
100
|
-
### Décorateurs API sur une méthode
|
|
101
|
-
|
|
102
|
-
`@get`, `@post`, `@put` et `@patch` peuvent décorer une propriété ou une
|
|
103
|
-
méthode. En mode méthode, le callback reçoit le `ApiResult` complet :
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
@get(endpoints.ticket)
|
|
107
|
-
handleTicket(payload: ApiResult<PurchaseItem> | undefined) {
|
|
108
|
-
if (!payload?.result || !payload.response?.ok) return;
|
|
109
|
-
dp<PurchaseItem>(this.dataProvider).set(payload.result);
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
La méthode reçoit le payload complet (`result`, `response`, `request`).
|
|
114
|
-
`undefined` représente un appel terminé sans payload, par exemple une erreur
|
|
115
|
-
réseau. Si un refetch nommé est nécessaire, conserver le handle et décorer la
|
|
116
|
-
méthode avec lui :
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
const ticketGet = get(endpoints.ticket);
|
|
120
|
-
|
|
121
|
-
@ticketGet
|
|
122
|
-
handleTicket(payload: ApiResult<PurchaseItem> | undefined) {}
|
|
123
|
-
|
|
124
|
-
@refetch(ticketGet)
|
|
125
|
-
reloadTicket() {}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
`@send(handle)` reste le décorateur de méthode qui déclenche explicitement une
|
|
129
|
-
écriture ; les mutations du body, triggers et polling conservent leur
|
|
130
|
-
comportement.
|
|
131
|
-
|
|
132
|
-
Exemple écriture :
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
@post(endpoints.ticket, ticketBodyKey)
|
|
136
|
-
handleTicketCreation(payload: ApiResult<PurchaseItem> | undefined) {
|
|
137
|
-
if (payload?.response?.ok) console.log(payload.result);
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Scope — defaults hérités
|
|
142
|
-
|
|
143
|
-
Skill dédié : **`concorde-scope`**.
|
|
144
|
-
|
|
145
|
-
`<sonic-scope>` (light DOM) : les descendants héritent des attributs (`serviceURL`, `token`, `formDataProvider`, icônes custom…).
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
import "@supersoniks/concorde/sonic-scope";
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
```html
|
|
152
|
-
<sonic-scope serviceURL="https://api.example.com" formDataProvider="checkout">
|
|
153
|
-
…app…
|
|
154
|
-
</sonic-scope>
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
**API** — type `APIConfiguration` (`@supersoniks/concorde/utils/api`) :
|
|
158
|
-
|
|
159
|
-
| Mode | `@get` | Config |
|
|
160
|
-
|------|--------|--------|
|
|
161
|
-
| Scope | `@get(endpoint)` | hérite `serviceURL`, `token`, … du scope |
|
|
162
|
-
| DataProvider | `@get(endpoint, apiConfigKey)` | objet publié via `set(apiConfigKey, { … })` |
|
|
163
|
-
|
|
164
|
-
Champs courants : `serviceURL`, `token`, `userName`/`password`, `credentials`, `authToken`, `tokenProvider`.
|
|
165
|
-
Avancés : `cache`, `blockUntilDone`, `keepAlive`, `addHTTPResponse`.
|
|
166
|
-
|
|
167
|
-
**Ne pas confondre** avec **theme** (couleurs / typo) — skill **`concorde-theme`**.
|
|
168
|
-
|
|
169
|
-
## Theme — design tokens
|
|
170
|
-
|
|
171
|
-
Skill dédié : **`concorde-theme`**.
|
|
172
|
-
|
|
173
|
-
`<sonic-theme color font class="block bg-base">` + variables CSS `--sc-*` (surfaces, sémantique, typo). Pas pour l’API.
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
import "@supersoniks/concorde/theme";
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
## @publish / @subscribe
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
@publish(counterKey.count)
|
|
183
|
-
@state()
|
|
184
|
-
count = 0;
|
|
185
|
-
|
|
186
|
-
@subscribe(counterKey.count)
|
|
187
|
-
@state()
|
|
188
|
-
subscribedCount = 0;
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### Règle impérative — une souscription par valeur affichée
|
|
192
|
-
|
|
193
|
-
Sur un composant **`LitElement`** métier, chaque donnée lue dans `render()` doit avoir **son propre** `@subscribe` + `@state()` (ou `@property` si besoin explicite) sur le **publisher feuille** — jamais un abonnement à l’objet parent + getters.
|
|
194
|
-
|
|
195
|
-
| Anti-pattern | Pourquoi |
|
|
196
|
-
|--------------|----------|
|
|
197
|
-
| `@subscribe(dpKeys.currentSession)` + `get edito()` | Si seul `edito` change (même référence `Session`), Lit peut **ne pas** re-rendre |
|
|
198
|
-
| `@subscribe` sur un parent + `sub()` enfant pour le détail | Mélange deux modèles ; préférer des feuilles cohérentes |
|
|
199
|
-
|
|
200
|
-
```typescript
|
|
201
|
-
// ❌ — re-render non garanti sur sous-clés
|
|
202
|
-
@subscribe(dpKeys.currentSession)
|
|
203
|
-
@state() session?: Session;
|
|
204
|
-
get edito() { return this.session?.edito; }
|
|
205
|
-
|
|
206
|
-
// ✅ — une propriété réactive par champ du template
|
|
207
|
-
@subscribe(dpKeys.currentSession.slug)
|
|
208
|
-
@state() slug = "";
|
|
209
|
-
|
|
210
|
-
@subscribe(dpKeys.currentSession.edito)
|
|
211
|
-
@state() edito: Edito | null = null;
|
|
212
|
-
|
|
213
|
-
@subscribe(dpKeys.currentSession.settings)
|
|
214
|
-
@state() settings: SettingsSessionAPI | null = null;
|
|
32
|
+
```bash
|
|
33
|
+
node -e 'const t=process.argv[1];for(const m of require("@supersoniks/concorde/custom-elements.json").modules)for(const d of m.declarations)if(d.tagName===t)console.log(JSON.stringify({attributes:d.attributes?.map(a=>[a.name,a.type?.text,a.default]),properties:d.members?.filter(p=>p.kind==="field"&&!p.attribute).map(p=>p.name),events:d.events?.map(e=>e.name),slots:d.slots?.map(s=>s.name)},null,1))' sonic-select
|
|
215
34
|
```
|
|
216
35
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
**Granularité** : descendre jusqu’à la **feuille** réellement affichée si les mutations ne remplacent pas l’objet intermédiaire (ex. `@subscribe(dpKeys.currentSession.edito.title)` si seul `title` change sans nouvel objet `edito`).
|
|
36
|
+
## Critical rules
|
|
220
37
|
|
|
221
|
-
|
|
38
|
+
- `LitElement` + decorators. In new code, and when touching old code: `Subscriber` mixin → decorators · `sonic-fetch` → `@get`, or `sonic-list` with `fetch` · `@onAssign` → `@handle` · `PublisherManager` → `get` / `set` / `dp` · `data-bind` → `sub()`.
|
|
39
|
+
- Store access through a typed `DataProviderKey`, never a string path.
|
|
40
|
+
- Display store values with `sub(key.leaf)`; subscribe to the leaf you render, not to its parent object.
|
|
41
|
+
- Lists render rows with `.items` / `.noItems` / `.skeleton` (Lit properties, with the dot).
|
|
42
|
+
- Form fields write to the store by themselves: `formDataProvider` + `name`, no `@input` wiring.
|
|
43
|
+
- `@post` sends on every body mutation by default: forms use `autoPostOnBodyMutation: false` + `send()`.
|
|
44
|
+
- Use `sonic-*` components and their attributes before custom markup; semantic tokens only, no raw colors, no `dark:`.
|
|
222
45
|
|
|
223
|
-
|
|
46
|
+
## Component shape
|
|
224
47
|
|
|
225
|
-
|
|
48
|
+
```ts
|
|
49
|
+
import { html, LitElement } from "lit";
|
|
50
|
+
import { customElement, state } from "lit/decorators.js";
|
|
51
|
+
import { subscribe, DataProviderKey } from "@supersoniks/concorde/decorators";
|
|
226
52
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
| Composant métier **sans** enfants `Subscriber` | `LitElement` + `@subscribe` **feuille par feuille** |
|
|
230
|
-
| Composant **hôte** d’enfants sonic `Subscriber` | `extends Subscriber(LitElement)` + `@property` remplies par template filling ; **exposer** `dataProvider` aux descendants |
|
|
53
|
+
type Flight = { code: string; gate: string };
|
|
54
|
+
const flightKey = new DataProviderKey<Flight>("flight");
|
|
231
55
|
|
|
232
|
-
|
|
56
|
+
@customElement("app-flight")
|
|
57
|
+
export class AppFlight extends LitElement {
|
|
58
|
+
@subscribe(flightKey.gate)
|
|
59
|
+
@state()
|
|
60
|
+
gate = "";
|
|
233
61
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
Après `initPublisher`, refléter le chemin résolu sur l’attribut (ex. `app/currentSession`) pour que les **enfants** héritent le bon publisher — ils ne lisent pas `subDataProvider` sur l’ancêtre.
|
|
239
|
-
|
|
240
|
-
**Liste / queue** : chaque ligne a son publisher — l’hôte **hérite** de l’ancêtre ; ne pas forcer `app.currentSession` sur un item de liste.
|
|
241
|
-
|
|
242
|
-
### Piège migration `Subscriber` → `LitElement` (checklist)
|
|
243
|
-
|
|
244
|
-
Lors du remplacement de `sonic-fetch` ou du retrait du mixin `Subscriber` sur un composant **métier** :
|
|
245
|
-
|
|
246
|
-
| Étape | Vérification |
|
|
247
|
-
|-------|----------------|
|
|
248
|
-
| Champs affichés dans `render()` | Chaque `@property` autrefois remplie par template filling → **`@subscribe(dpKey.feuille)` + `@state()`** (pas laisser des `@property` orphelins) |
|
|
249
|
-
| Enfant d’un `@get` | `@get` + `@publish`/`@handle` vers le DataProvider cible ; l’UI lit ce DP via `@subscribe`, pas via des props vides |
|
|
250
|
-
| Placeholders `Endpoint` | Les noms `${prop}` doivent exister sur l’hôte (`@property` ou copie dans `willUpdate` si le scan utilise un autre nom, ex. `checkCode` → `code`) |
|
|
251
|
-
| Modale / portal | `@get(endpoint, apiConfigKey)` si pas de `serviceURL` ascendant fiable (`Modal` → `Theme.getPopContainer()`) |
|
|
252
|
-
| Remplacement `sonic-fetch` | Expliciter `dataProvider` + `subDataProvider` sur les hôtes `Subscriber` enfants (ex. `app` + `currentScanTicket`) |
|
|
253
|
-
|
|
254
|
-
```typescript
|
|
255
|
-
// ❌ — Subscriber retiré, props jamais alimentées
|
|
256
|
-
export class TicketInfos extends LitElement {
|
|
257
|
-
@property({ type: Object }) owner = {};
|
|
258
|
-
render() { return html`${this.owner?.firstName}`; }
|
|
62
|
+
render() {
|
|
63
|
+
return html`Gate ${this.gate}`;
|
|
64
|
+
}
|
|
259
65
|
}
|
|
260
|
-
|
|
261
|
-
// ✅ — une souscription par champ affiché
|
|
262
|
-
@subscribe(dpKeys.currentScanTicket.owner)
|
|
263
|
-
@state() owner: Contact = {};
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
**`@subscribe` + décorateur Lit** : préférer **`@state()`** (pas `@property`) pour les champs purement lus depuis le DataProvider.
|
|
267
|
-
|
|
268
|
-
## formDataProvider
|
|
269
|
-
|
|
270
|
-
```html
|
|
271
|
-
<div formDataProvider="myForm">
|
|
272
|
-
<sonic-input name="value" label="Texte"></sonic-input>
|
|
273
|
-
</div>
|
|
274
66
|
```
|
|
275
67
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
## sonic-queue — scroll infini + recherche
|
|
279
|
-
|
|
280
|
-
Pagination (`$offset` / `$limit`) **automatisée** avec `lazyload`.
|
|
281
|
-
|
|
282
|
-
```html
|
|
283
|
-
<div formDataProvider="myFilter">
|
|
284
|
-
<sonic-input name="q" type="search" label="Rechercher"></sonic-input>
|
|
285
|
-
</div>
|
|
286
|
-
<sonic-queue
|
|
287
|
-
lazyload
|
|
288
|
-
dataFilterProvider="myFilter"
|
|
289
|
-
dataProviderExpression="users?offset=$offset&limit=$limit"
|
|
290
|
-
serviceurl="…"
|
|
291
|
-
key="data"
|
|
292
|
-
limit="4"
|
|
293
|
-
.items=${renderUser}
|
|
294
|
-
></sonic-queue>
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
## Templates sonic-list / sonic-queue
|
|
298
|
-
|
|
299
|
-
Propriétés Lit (recommandé) :
|
|
300
|
-
|
|
301
|
-
| Propriété | Rôle |
|
|
302
|
-
|-----------|------|
|
|
303
|
-
| `.items=${fn}` | Rendu de chaque ligne — **point obligatoire** (Lit ne passe pas les fonctions en attribut HTML) |
|
|
304
|
-
| `.separator` | Entre chaque item (pas après le dernier) |
|
|
305
|
-
| `.noItems` | Liste vide |
|
|
306
|
-
| `.skeleton` | Chargement pendant un `fetch` |
|
|
307
|
-
|
|
308
|
-
`sonic-queue` transmet ces propriétés à chaque lot (`sonic-list` interne). `.noItems` ne s’applique qu’au **premier** lot.
|
|
309
|
-
|
|
310
|
-
## Décorateurs
|
|
311
|
-
|
|
312
|
-
| Besoin | API |
|
|
313
|
-
|--------|-----|
|
|
314
|
-
| Lire (affichage Lit) | `@subscribe(dpKey.leaf)` + `@state()` — **une fois par champ** du `render()` |
|
|
315
|
-
| Effet typé | `@handle(dpKey.a, …)` |
|
|
316
|
-
| API HTTP | `@get(Endpoint)` ou `@get(Endpoint, apiConfigKey)` |
|
|
317
|
-
| Effet après GET | `@get(endpoint)` sur une méthode |
|
|
318
|
-
| Effet après écriture | `@post` / `@put` / `@patch` sur une méthode |
|
|
319
|
-
| Écriture classe (hors form) | `@publish` |
|
|
320
|
-
| Lecture classe (hors form) | `@subscribe` + `DataProviderKey` — pas `@bind` |
|
|
321
|
-
|
|
322
|
-
## Migrations courantes
|
|
323
|
-
|
|
324
|
-
| Ancien | Nouveau |
|
|
325
|
-
|--------|---------|
|
|
326
|
-
| `PublisherManager.get(…)` | `get(…)` ou `set(…)` |
|
|
327
|
-
| « publisher » | DataProvider |
|
|
328
|
-
| `sonic-input` + `@input` | `formDataProvider` + `name` |
|
|
329
|
-
| `sonic-fetch` | `sonic-queue` + filtre, ou `@get` + `@publish`/`@handle` + `@subscribe` / hôte `Subscriber` |
|
|
330
|
-
| `extends Subscriber(LitElement)` (métier seul) | `LitElement` + `@subscribe` feuille par feuille / `sub()` — **ne pas oublier** les champs template-filled |
|
|
331
|
-
| `extends Subscriber` (hôte d’enfants sonic) | Conserver `Subscriber` + `dataProvider` / `subDataProvider` corrects |
|
|
332
|
-
| `@get` dans modale | `@get(endpoint, apiConfigKey)` si config API hors scope DOM |
|
|
333
|
-
| `data-bind` HTML | `@subscribe` / `sub()` |
|
|
334
|
-
| `@bind` décorateur | `@subscribe` + `DataProviderKey` (lecture) ou `@publish` (écriture) |
|
|
335
|
-
| `@onAssign` | `@handle` + `DataProviderKey` |
|
|
336
|
-
| Templates HTML list/queue | `items`, `.separator`, `.noItems`, `.skeleton` (propriétés Lit) |
|
|
68
|
+
## Imports
|
|
337
69
|
|
|
338
|
-
|
|
70
|
+
| What | From |
|
|
71
|
+
|------|------|
|
|
72
|
+
| Components (side-effect import) | `@supersoniks/concorde/button` · `/input` · `/list` · `/queue` · `/sonic-scope` · `/theme` … |
|
|
73
|
+
| Decorators, `DataProviderKey`, `Endpoint`, `ApiResult` | `@supersoniks/concorde/decorators` |
|
|
74
|
+
| `sub()` | `@supersoniks/concorde/directives` |
|
|
75
|
+
| `get` / `set` / `dp`, `derive` | `@supersoniks/concorde/utils` |
|
|
76
|
+
| `APIConfiguration` type | `@supersoniks/concorde/utils/api` |
|
|
339
77
|
|
|
340
|
-
|
|
341
|
-
- **Formulaire** : `formDataProvider` + `name` → `sub()` ou `@subscribe`.
|
|
342
|
-
- **Liste scroll infini** : `sonic-queue` + `lazyload` + `dataFilterProvider`.
|
|
343
|
-
- **Templates list/queue** : `items`, `separator`, `noItems`, `skeleton` (depuis un parent Lit).
|
|
344
|
-
- **Config API app-wide** : `<sonic-scope serviceURL="…">` ou `DataProviderKey<APIConfiguration>`.
|
|
345
|
-
- **Theme / couleurs** : `<sonic-theme>` + CSS `--sc-*`.
|
|
346
|
-
- **Clé dynamique** : `"chemin.${prop}"` + `DataProviderKey<T, { prop: … }>`.
|
|
347
|
-
- **GET avec effet de bord** : `@get(endpoint)` sur une méthode ; conserver
|
|
348
|
-
`const request = get(endpoint)` si un refetch nommé est nécessaire.
|
|
78
|
+
`get` exists twice: the HTTP decorator (`/decorators`) and the store read (`/utils`). Alias one when a file needs both: `import { get as getRequest } from "@supersoniks/concorde/decorators"`. Inside the Concorde repository itself, short entry points do not resolve: import `@supersoniks/concorde/core/…` or relative paths.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Composition and states
|
|
2
|
+
|
|
3
|
+
Docs: [Components](https://concorde.supersoniks.org/docs/getting-started/components). Exact attributes: query `custom-elements.json` (see `SKILL.md`).
|
|
4
|
+
|
|
5
|
+
## Parts
|
|
6
|
+
|
|
7
|
+
Compound components keep their parts inside them; do not rebuild a part with a `div`. A nav is `sonic-menu` + `sonic-menu-item`, not a stack of ghost buttons.
|
|
8
|
+
|
|
9
|
+
| Component | Parts |
|
|
10
|
+
|-----------|-------|
|
|
11
|
+
| `sonic-card` | `sonic-card-header` (+ `sonic-card-header-description`) · `sonic-card-main` · `sonic-card-footer` |
|
|
12
|
+
| `sonic-modal` | `sonic-modal-title` (always) · `sonic-modal-subtitle` · `sonic-modal-content` · `sonic-modal-actions`; inside the actions, a `sonic-button` with `hideModal` closes it |
|
|
13
|
+
| `sonic-menu` | `sonic-menu-item` only; sections with `sonic-divider label="…"` |
|
|
14
|
+
| `sonic-fieldset` | `sonic-legend` (or `label` / `description`), then `sonic-form-layout` |
|
|
15
|
+
| Form body | `sonic-form-layout` for fields, `sonic-form-actions` last for the buttons |
|
|
16
|
+
| `sonic-table` | `sonic-thead` · `sonic-tbody` · `sonic-tfoot` → `sonic-tr` → `sonic-th` / `sonic-td`; rows from `sonic-list` |
|
|
17
|
+
|
|
18
|
+
Icons go in a button's `prefix` / `suffix` slot as `sonic-icon`, not as inline SVG.
|
|
19
|
+
|
|
20
|
+
## States
|
|
21
|
+
|
|
22
|
+
Use the state a component already has before adding `@state` flags and `if` branches.
|
|
23
|
+
|
|
24
|
+
| State | Use |
|
|
25
|
+
|-------|-----|
|
|
26
|
+
| Action running | `loading` on `sonic-button` (spinner, blocks clicks) |
|
|
27
|
+
| List loading / empty | `.skeleton` / `.noItems` on `sonic-list` / `sonic-queue`, or their `loader` attribute |
|
|
28
|
+
| Other content loading | `sonic-loader mode="inline"`; without `mode` it covers the viewport |
|
|
29
|
+
| Field validation | `required` / `pattern` / `min` / `max`; `status="error"` and `description` for the message |
|
|
30
|
+
| Inline message | `sonic-alert status="…"` |
|
|
31
|
+
| Short feedback | `SonicToast.add({ text, status })` from `@supersoniks/concorde/toast` |
|
|
32
|
+
| Disabled | `disabled` on the button or field, not a class |
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Data: store and keys
|
|
2
|
+
|
|
3
|
+
Docs: [Data flow](https://concorde.supersoniks.org/docs/getting-started/dataFlow) · [DataProviderKey](https://concorde.supersoniks.org/docs/misc/dataProviderKey) · [Dynamic paths](https://concorde.supersoniks.org/docs/misc/dynamic-path) · [@subscribe](https://concorde.supersoniks.org/docs/decorators/subscribe) · [@bind](https://concorde.supersoniks.org/docs/decorators/bind) · [@handle](https://concorde.supersoniks.org/docs/decorators/handle) · [sub()](https://concorde.supersoniks.org/docs/directives/sub)
|
|
4
|
+
|
|
5
|
+
The app state is one store, the **DataProvider**, addressed by dot paths. Always go through a typed `DataProviderKey<T>`: `cartKey.items[0].qty` builds the path and checks the type.
|
|
6
|
+
|
|
7
|
+
| Need | Use |
|
|
8
|
+
|------|-----|
|
|
9
|
+
| Display a value in a template | `sub(key.field)` |
|
|
10
|
+
| Value used in logic / `willUpdate` | `@subscribe(key.field)` + `@state()` (read only) |
|
|
11
|
+
| Write a property to the store | `@publish(key.field)` |
|
|
12
|
+
| Read **and** write the same path | `@bind(key.field, { reflect: true })` |
|
|
13
|
+
| Side effect on change | `@handle(keyA, keyB)` method |
|
|
14
|
+
| Imperative read / write | `get(key)` · `set(key, value)` · `dp(key)` |
|
|
15
|
+
| Inherit an ancestor attribute | `@ancestorAttribute("dataProvider")` |
|
|
16
|
+
|
|
17
|
+
## Subscribe to the leaf you render
|
|
18
|
+
|
|
19
|
+
A `set` on a child mutates the parent object in place and does not notify subscribers of the parent. `@subscribe(sessionKey)` + `this.session.title` misses title changes: use `sub(sessionKey.title)` or `@subscribe(sessionKey.title)`.
|
|
20
|
+
|
|
21
|
+
`sub()` in templates, `get()` in code: `get()` in a template renders once and never updates.
|
|
22
|
+
|
|
23
|
+
## Dynamic paths
|
|
24
|
+
|
|
25
|
+
Placeholders go in a plain string (not a template literal) and are declared in the key's second generic. They resolve from properties of the host component, in decorators and in `sub()`:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
const userKey = new DataProviderKey<User, { userId: string }>("users.${userId}");
|
|
29
|
+
|
|
30
|
+
@property() userId = "";
|
|
31
|
+
@subscribe(userKey.name) @state() name = "";
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`get`, `set` and `dp` **throw** if the path they receive still contains `${…}` or `{$…}`. In imperative code, build the resolved key instead:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
const usersKey = new DataProviderKey<Record<string, User>>("users");
|
|
38
|
+
set(usersKey[userId], user);
|
|
39
|
+
set(`app.pages.${index}.done`, true); // fine too: JS resolves it before the call
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Moving old code to keys
|
|
43
|
+
|
|
44
|
+
- `get("app.widget.distance")` → `get(widgetKey.distance)`.
|
|
45
|
+
- `dp(key.path)` / `set(key.path, v)` → `dp(key)` / `set(key, v)`.
|
|
46
|
+
- A key with placeholders passed to `get` / `set` / `dp` → a decorator, or the resolved key above.
|
|
47
|
+
- Leave `sub()` and decorators with placeholders as they are. Grepping `${` is not enough: what matters is the string received at runtime.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# HTTP
|
|
2
|
+
|
|
3
|
+
Docs: [@get](https://concorde.supersoniks.org/docs/decorators/get) · [@post](https://concorde.supersoniks.org/docs/decorators/post) · [Endpoint](https://concorde.supersoniks.org/docs/misc/endpoint) · [API configuration](https://concorde.supersoniks.org/docs/misc/api-configuration)
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
const boardEndpoint = new Endpoint<FlightBoard, { direction: string }>(
|
|
7
|
+
"flights?direction=${direction}",
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
@property() direction = "departures";
|
|
11
|
+
|
|
12
|
+
@get(boardEndpoint)
|
|
13
|
+
@state()
|
|
14
|
+
board?: ApiResult<FlightBoard>; // { result, response, request } | undefined
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- `@get` on a property stores the `ApiResult<T>`; on a method, the method receives it. A change of a placeholder property runs the request again; while a placeholder is `null` / `undefined`, nothing is sent.
|
|
18
|
+
- To reload: keep the handle (`const load = get(endpoint)`, then `@load` on the property) and call `load.refetch(this)`, or decorate a method with `@refetch(load)`.
|
|
19
|
+
- `@post(endpoint, bodyKey)` (and `@put` / `@patch`) send the store value at `bodyKey`, **on every body mutation by default**. For a form submitted by a button: `post(endpoint, bodyKey, { autoPostOnBodyMutation: false })` kept in a constant, then `save.send(this)` or `@send(save)` on a method.
|
|
20
|
+
|
|
21
|
+
## API configuration
|
|
22
|
+
|
|
23
|
+
`serviceURL`, `token`, `credentials`… are read from ancestor attributes by default, usually `<sonic-scope serviceURL="…">` at the app root. A component rendered outside that DOM (modal, portal) gets them from the store instead: pass a `DataProviderKey<APIConfiguration>` as second argument, `@get(endpoint, apiKey)`.
|
|
24
|
+
|
|
25
|
+
Do not put API settings on `sonic-theme`: it is for styling only.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Lists and forms
|
|
2
|
+
|
|
3
|
+
Docs: [List](https://concorde.supersoniks.org/core/components/functional/list) · [Queue](https://concorde.supersoniks.org/core/components/functional/queue) · [Input](https://concorde.supersoniks.org/core/components/ui/form/input) · [Submit](https://concorde.supersoniks.org/core/components/functional/submit)
|
|
4
|
+
|
|
5
|
+
## Lists
|
|
6
|
+
|
|
7
|
+
`sonic-list` renders one array; `sonic-queue` loads a paginated API in batches (lazy scroll, filters). Render rows with Lit properties: `.items=${(item) => html`…`}`, plus `.noItems` · `.skeleton` · `.separator`. The `.` is required: functions only pass as properties. (`<template>` children exist for plain-HTML hosts only.)
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
html`<sonic-queue
|
|
11
|
+
serviceURL="/api"
|
|
12
|
+
dataProviderExpression="flights?offset=$offset&limit=$limit"
|
|
13
|
+
key="flights"
|
|
14
|
+
dataFilterProvider=${flightSearchKey.path}
|
|
15
|
+
.items=${(f: Flight) => html`<app-flight-row .flight=${f}></app-flight-row>`}
|
|
16
|
+
.noItems=${() => html`No flights`}
|
|
17
|
+
></sonic-queue>`;
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Forms
|
|
21
|
+
|
|
22
|
+
Fields write into the store by themselves: `formDataProvider` on a container (or on the field) + `name` on each field. No `@input` / `.value` wiring.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
html`<div formDataProvider=${checkInKey.path}>
|
|
26
|
+
<sonic-form-layout>
|
|
27
|
+
<sonic-input name="passenger" label="Passenger" required></sonic-input>
|
|
28
|
+
<sonic-select name="cabin" label="Cabin" .options=${cabins}></sonic-select>
|
|
29
|
+
</sonic-form-layout>
|
|
30
|
+
</div>`;
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- Read values with `sub()` / `@subscribe` on the form key.
|
|
34
|
+
- Submit with `@post` + `send()` (see [http.md](http.md)), or `sonic-submit`.
|
|
35
|
+
- A `sonic-queue` filters on a form store through `dataFilterProvider`: each non-empty field becomes a query parameter.
|