@supersoniks/concorde 5.1.2 → 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 +1 -1
- 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 +1 -1
- 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} +11722 -8868
- 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/og-concorde.jpg +0 -0
- package/dist/robots.txt +11 -10
- package/docs/assets/index-CD4WyL6o.css +1 -0
- 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/{core → crawl/core}/components/functional/sdui/sdui-extension-points.html +8 -9
- 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/{core → crawl/core}/components/functional/subscriber/subscriber.html +5 -6
- package/docs/crawl/core/components/functional/value/value.html +51 -0
- package/docs/{core → crawl/core}/components/ui/alert/alert.html +63 -53
- package/docs/{core → crawl/core}/components/ui/alert-messages/alert-messages.html +5 -6
- package/docs/{core → crawl/core}/components/ui/badge/badge.html +33 -33
- package/docs/crawl/core/components/ui/button/button.html +150 -0
- package/docs/crawl/core/components/ui/captcha/captcha.html +112 -0
- package/docs/{core → crawl/core}/components/ui/card/card.html +11 -12
- package/docs/{core → crawl/core}/components/ui/divider/divider.html +14 -14
- 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/{core → crawl/core}/components/ui/form/form-actions/form-actions.html +23 -23
- 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/{core → crawl/core}/components/ui/icon/icon.html +9 -10
- package/docs/crawl/core/components/ui/image/image.html +298 -0
- package/docs/{core → crawl/core}/components/ui/link/link.html +11 -12
- package/docs/crawl/core/components/ui/loader/loader.html +124 -0
- package/docs/{core → crawl/core}/components/ui/menu/menu.html +33 -34
- package/docs/crawl/core/components/ui/modal/modal.html +342 -0
- package/docs/crawl/core/components/ui/pop/pop.html +296 -0
- package/docs/{core → crawl/core}/components/ui/progress/progress.html +7 -8
- 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/{docs/getting-started → crawl/docs/_core-concept}/dataFlow.html +29 -26
- 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/{docs/getting-started → crawl/docs/_getting-started}/ai-agents.html +11 -12
- 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/{docs/getting-started → crawl/docs/_getting-started}/create-a-component.html +14 -11
- package/docs/{docs/getting-started → crawl/docs/_getting-started}/my-first-component.html +22 -13
- 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/{docs/getting-started → crawl/docs/_getting-started}/theming.html +9 -10
- package/docs/{docs/misc → crawl/docs/_misc}/api-configuration.html +18 -18
- package/docs/{docs/misc → crawl/docs/_misc}/dataProviderKey.html +11 -12
- package/docs/{docs/misc → crawl/docs/_misc}/docs-mock-api.html +28 -25
- package/docs/{docs/misc → crawl/docs/_misc}/dynamic-path.html +15 -16
- package/docs/{docs/misc → crawl/docs/_misc}/endpoint.html +15 -16
- package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +138 -0
- package/docs/{docs/misc → crawl/docs/_misc}/html-integration.html +15 -12
- 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/docs-mock-api-sw.js +223 -58
- package/docs/docs-mock-api-sw.js.map +4 -4
- package/docs/index.html +68 -95
- package/docs/llms-full.txt +3610 -2231
- package/docs/llms.txt +86 -94
- package/docs/robots.txt +10 -11
- package/docs/sitemap.xml +84 -78
- package/docs/src/core/components/functional/date/date.md +231 -91
- package/docs/src/core/components/functional/fetch/fetch.md +83 -66
- package/docs/src/core/components/functional/if/if.md +3 -28
- package/docs/src/core/components/functional/jsonata/jsonata.md +37 -42
- package/docs/src/core/components/functional/list/list.md +43 -99
- package/docs/src/core/components/functional/mix/mix.md +26 -31
- package/docs/src/core/components/functional/queue/queue.md +61 -40
- package/docs/src/core/components/functional/router/router.md +65 -64
- package/docs/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
- package/docs/src/core/components/functional/sdui/component-catalog.json +1 -1
- package/docs/src/core/components/functional/sdui/example.json +86 -19
- package/docs/src/core/components/functional/sdui/sdui-extension-points.md +1 -1
- package/docs/src/core/components/functional/sdui/sdui.md +358 -187
- package/docs/src/core/components/functional/states/states.md +61 -86
- package/docs/src/core/components/functional/submit/submit.md +72 -64
- package/docs/src/core/components/functional/value/value.md +22 -34
- package/docs/src/core/components/ui/alert/alert.md +58 -48
- package/docs/src/core/components/ui/badge/badge.md +34 -27
- package/docs/src/core/components/ui/button/button.md +106 -139
- package/docs/src/core/components/ui/captcha/captcha.md +32 -17
- package/docs/src/core/components/ui/card/card.md +6 -6
- package/docs/src/core/components/ui/divider/divider.md +11 -8
- package/docs/src/core/components/ui/form/checkbox/checkbox.md +42 -90
- package/docs/src/core/components/ui/form/fieldset/fieldset.md +75 -31
- package/docs/src/core/components/ui/form/form-actions/form-actions.md +16 -14
- package/docs/src/core/components/ui/form/form-layout/form-layout.md +29 -19
- package/docs/src/core/components/ui/form/input/input.md +95 -95
- package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +29 -0
- package/docs/src/core/components/ui/form/radio/radio.md +34 -55
- package/docs/src/core/components/ui/form/select/select.md +45 -60
- package/docs/src/core/components/ui/form/switch/switch.md +34 -57
- package/docs/src/core/components/ui/form/textarea/textarea.md +38 -55
- package/docs/src/core/components/ui/group/group.md +33 -35
- package/docs/src/core/components/ui/icon/icon.md +4 -4
- package/docs/src/core/components/ui/image/image.md +107 -41
- package/docs/src/core/components/ui/link/link.md +6 -6
- package/docs/src/core/components/ui/loader/loader.md +55 -30
- package/docs/src/core/components/ui/menu/menu.md +27 -27
- package/docs/src/core/components/ui/modal/modal.md +96 -72
- package/docs/src/core/components/ui/pop/pop.md +158 -80
- package/docs/src/core/components/ui/progress/progress.md +2 -2
- package/docs/src/core/components/ui/table/table.md +255 -91
- package/docs/src/core/components/ui/theme/theme.md +36 -11
- package/docs/src/core/components/ui/toast/toast.md +117 -48
- package/docs/src/core/components/ui/tooltip/tooltip.md +62 -27
- package/docs/{docs/getting-started → src/docs/_core-concept}/dataFlow.md +18 -17
- package/docs/src/docs/_core-concept/overview.md +57 -0
- package/docs/src/docs/_core-concept/subscriber.md +75 -0
- package/docs/src/docs/_decorators/ancestor-attribute.md +128 -0
- package/docs/src/docs/_decorators/auto-subscribe.md +202 -0
- package/docs/src/docs/_decorators/bind.md +167 -0
- package/docs/src/docs/_decorators/get.md +162 -0
- package/docs/src/docs/_decorators/handle.md +175 -0
- package/docs/src/docs/_decorators/on-assign.md +390 -0
- package/docs/src/docs/_decorators/patch.md +70 -0
- package/docs/src/docs/_decorators/post.md +146 -0
- package/docs/src/docs/_decorators/publish.md +55 -0
- package/docs/src/docs/_decorators/put.md +70 -0
- package/docs/src/docs/_decorators/subscribe.md +100 -0
- package/docs/src/docs/_decorators/wait-for-ancestors.md +163 -0
- package/docs/src/docs/_directives/sub.md +91 -0
- package/docs/src/docs/{getting-started → _getting-started}/ai-agents.md +3 -3
- package/docs/src/docs/_getting-started/concorde-manual-install.md +133 -0
- package/docs/src/docs/_getting-started/concorde-outside.md +33 -0
- package/docs/{docs/getting-started → src/docs/_getting-started}/create-a-component.md +6 -3
- package/docs/src/docs/{getting-started → _getting-started}/my-first-component.md +14 -5
- package/docs/src/docs/_getting-started/my-first-subscriber.md +120 -0
- package/docs/src/docs/_getting-started/pubsub.md +37 -0
- package/docs/src/docs/{getting-started → _getting-started}/start.md +13 -1
- package/docs/src/docs/{getting-started → _getting-started}/theming.md +2 -2
- package/docs/src/docs/{misc → _misc}/api-configuration.md +12 -10
- package/docs/src/docs/{misc → _misc}/dataProviderKey.md +4 -4
- package/docs/{docs/misc → src/docs/_misc}/docs-mock-api.md +13 -12
- package/docs/{docs/misc → src/docs/_misc}/dynamic-path.md +8 -8
- package/docs/{docs/misc → src/docs/_misc}/endpoint.md +8 -8
- package/docs/src/docs/_misc/formelement-subscriber-removal.md +115 -0
- package/docs/{docs/misc → src/docs/_misc}/html-integration.md +5 -4
- package/docs/src/docs/search/docs-search.json +4375 -2420
- package/docs/src/tsconfig.declarations.json +22 -0
- package/docs/src/tsconfig.emit.json +23 -0
- package/docs/src/tsconfig.json +2 -23
- package/gitlab/job_github_mirror.sh +39 -0
- package/index.html +89 -0
- package/package.json +22 -4
- package/public/img/og-concorde.jpg +0 -0
- package/scripts/ai-init.mjs +104 -379
- package/scripts/ai-init.test.mjs +81 -239
- package/scripts/docs-markdown-vite-plugin.ts +11 -5
- package/scripts/docs-public-url.mjs +6 -0
- package/scripts/docs.htaccess +7 -0
- package/scripts/generate-cem.mjs +244 -0
- package/scripts/generate-cem.test.mjs +122 -0
- package/scripts/generate-crawl-docs.mjs +29 -5
- package/scripts/generate-sdui-catalog.mjs +11 -10
- package/scripts/github-export.mjs +150 -0
- package/scripts/post-build-docs.js +3 -0
- 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 +1 -1
- package/src/core/components/functional/example/example.ts +3 -1
- package/src/core/components/functional/if/if.ts +0 -0
- package/src/core/components/functional/list/list.demo.ts +0 -0
- package/src/core/components/functional/list/list.md +6 -2
- package/src/core/components/functional/list/list.ts +17 -4
- package/src/core/components/functional/mix/mix.md +0 -0
- package/src/core/components/functional/router/router.demo.ts +0 -0
- 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 +0 -0
- package/src/core/components/functional/sdui/sdui-immutable.spec.ts +74 -0
- 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.ts +0 -0
- 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/value/value.md +0 -0
- 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/captcha/altchaStyles.ts +0 -0
- package/src/core/components/ui/card/card.md +1 -1
- package/src/core/components/ui/form/input/input.md +19 -1
- package/src/core/components/ui/form/input/input.ts +8 -2
- package/src/core/components/ui/form/radio/radio.md +14 -0
- package/src/core/components/ui/image/image.md +17 -17
- package/src/core/components/ui/modal/modal.md +2 -2
- 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/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 +3 -3
- package/src/docs/decorators/bind.md +23 -24
- package/src/docs/docs-location.spec.ts +10 -0
- package/src/docs/docs-location.ts +10 -0
- package/src/docs/example/decorators-demo-bind-demos.ts +11 -28
- package/src/docs/example/docs-toggle-demos.ts +1 -1
- package/src/docs/example/users.ts +0 -0
- package/src/docs/getting-started/ai-agents.md +29 -55
- package/src/docs/getting-started/dataFlow.md +2 -2
- package/src/docs/home/home.ts +3 -1
- 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/navigation/navigation.ts +5 -1
- package/src/docs/search/docs-search.json +358 -58
- package/src/docs/search/markdown-renderer.ts +6 -1
- 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/.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/PLAN-DOCS-AGENTS.md +0 -80
- 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/.htaccess +0 -75
- package/docs/404.html +0 -15
- package/docs/404.md +0 -5
- package/docs/assets/index-BgG6FFPt.js +0 -11765
- package/docs/assets/index-x89XINSG.css +0 -1
- package/docs/core/components/functional/date/date.html +0 -211
- package/docs/core/components/functional/date/date.md +0 -150
- package/docs/core/components/functional/fetch/fetch.html +0 -180
- package/docs/core/components/functional/fetch/fetch.md +0 -108
- package/docs/core/components/functional/if/if.html +0 -65
- package/docs/core/components/functional/if/if.md +0 -34
- package/docs/core/components/functional/jsonata/jsonata.html +0 -110
- package/docs/core/components/functional/jsonata/jsonata.md +0 -61
- package/docs/core/components/functional/list/list.html +0 -198
- package/docs/core/components/functional/list/list.md +0 -121
- package/docs/core/components/functional/mix/mix.html +0 -78
- package/docs/core/components/functional/mix/mix.md +0 -46
- package/docs/core/components/functional/queue/queue.html +0 -155
- package/docs/core/components/functional/queue/queue.md +0 -51
- package/docs/core/components/functional/router/router.html +0 -154
- package/docs/core/components/functional/router/router.md +0 -93
- package/docs/core/components/functional/sdui/sdui-extension-points.md +0 -94
- package/docs/core/components/functional/sdui/sdui.html +0 -397
- package/docs/core/components/functional/sdui/sdui.md +0 -307
- package/docs/core/components/functional/states/states.html +0 -141
- package/docs/core/components/functional/states/states.md +0 -112
- package/docs/core/components/functional/submit/submit.html +0 -178
- package/docs/core/components/functional/submit/submit.md +0 -106
- package/docs/core/components/functional/subscriber/subscriber.md +0 -91
- package/docs/core/components/functional/translation/translation.html +0 -60
- package/docs/core/components/functional/translation/translation.md +0 -38
- package/docs/core/components/functional/value/value.html +0 -81
- package/docs/core/components/functional/value/value.md +0 -47
- package/docs/core/components/ui/alert/alert.md +0 -186
- package/docs/core/components/ui/alert-messages/alert-messages.md +0 -85
- package/docs/core/components/ui/badge/badge.md +0 -181
- package/docs/core/components/ui/button/button.html +0 -309
- package/docs/core/components/ui/button/button.md +0 -216
- package/docs/core/components/ui/captcha/captcha.html +0 -80
- package/docs/core/components/ui/captcha/captcha.md +0 -56
- package/docs/core/components/ui/card/card.md +0 -215
- package/docs/core/components/ui/divider/divider.md +0 -126
- package/docs/core/components/ui/form/checkbox/checkbox.html +0 -200
- package/docs/core/components/ui/form/checkbox/checkbox.md +0 -125
- package/docs/core/components/ui/form/fieldset/fieldset.html +0 -238
- package/docs/core/components/ui/form/fieldset/fieldset.md +0 -161
- package/docs/core/components/ui/form/form-actions/form-actions.md +0 -98
- package/docs/core/components/ui/form/form-layout/form-layout.html +0 -115
- package/docs/core/components/ui/form/form-layout/form-layout.md +0 -109
- package/docs/core/components/ui/form/input/input.html +0 -235
- package/docs/core/components/ui/form/input/input.md +0 -142
- package/docs/core/components/ui/form/radio/radio.html +0 -144
- package/docs/core/components/ui/form/radio/radio.md +0 -78
- package/docs/core/components/ui/form/select/select.html +0 -178
- package/docs/core/components/ui/form/select/select.md +0 -86
- package/docs/core/components/ui/form/switch/switch.html +0 -146
- package/docs/core/components/ui/form/switch/switch.md +0 -80
- package/docs/core/components/ui/form/textarea/textarea.html +0 -162
- package/docs/core/components/ui/form/textarea/textarea.md +0 -82
- package/docs/core/components/ui/group/group.html +0 -113
- package/docs/core/components/ui/group/group.md +0 -77
- package/docs/core/components/ui/icon/icon.md +0 -214
- package/docs/core/components/ui/image/image.html +0 -194
- package/docs/core/components/ui/image/image.md +0 -167
- package/docs/core/components/ui/link/link.md +0 -81
- package/docs/core/components/ui/loader/loader.html +0 -114
- package/docs/core/components/ui/loader/loader.md +0 -87
- package/docs/core/components/ui/menu/menu.md +0 -370
- package/docs/core/components/ui/modal/modal.html +0 -324
- package/docs/core/components/ui/modal/modal.md +0 -211
- package/docs/core/components/ui/pop/pop.html +0 -250
- package/docs/core/components/ui/pop/pop.md +0 -216
- package/docs/core/components/ui/progress/progress.md +0 -109
- package/docs/core/components/ui/table/table.html +0 -333
- package/docs/core/components/ui/table/table.md +0 -267
- package/docs/core/components/ui/theme/theme.html +0 -116
- package/docs/core/components/ui/theme/theme.md +0 -97
- package/docs/core/components/ui/toast/toast.html +0 -185
- package/docs/core/components/ui/toast/toast.md +0 -147
- package/docs/core/components/ui/tooltip/tooltip.html +0 -112
- package/docs/core/components/ui/tooltip/tooltip.md +0 -89
- package/docs/docs/decorators/ancestor-attribute.html +0 -71
- package/docs/docs/decorators/ancestor-attribute.md +0 -59
- package/docs/docs/decorators/auto-subscribe.html +0 -61
- package/docs/docs/decorators/auto-subscribe.md +0 -40
- package/docs/docs/decorators/bind.html +0 -86
- package/docs/docs/decorators/bind.md +0 -77
- package/docs/docs/decorators/get.html +0 -166
- package/docs/docs/decorators/get.md +0 -160
- package/docs/docs/decorators/handle.html +0 -139
- package/docs/docs/decorators/handle.md +0 -119
- package/docs/docs/decorators/on-assign.html +0 -72
- package/docs/docs/decorators/on-assign.md +0 -63
- package/docs/docs/decorators/patch.html +0 -76
- package/docs/docs/decorators/patch.md +0 -44
- package/docs/docs/decorators/post.html +0 -150
- package/docs/docs/decorators/post.md +0 -134
- package/docs/docs/decorators/publish.html +0 -74
- package/docs/docs/decorators/publish.md +0 -56
- package/docs/docs/decorators/put.html +0 -83
- package/docs/docs/decorators/put.md +0 -51
- package/docs/docs/decorators/subscribe.html +0 -91
- package/docs/docs/decorators/subscribe.md +0 -87
- package/docs/docs/decorators/wait-for-ancestors.html +0 -82
- package/docs/docs/decorators/wait-for-ancestors.md +0 -76
- package/docs/docs/directives/sub.html +0 -79
- package/docs/docs/directives/sub.md +0 -75
- package/docs/docs/directives/t.html +0 -91
- package/docs/docs/directives/t.md +0 -73
- package/docs/docs/getting-started/ai-agents.md +0 -76
- package/docs/docs/getting-started/components.html +0 -27
- package/docs/docs/getting-started/components.md +0 -5
- package/docs/docs/getting-started/installation.html +0 -69
- package/docs/docs/getting-started/installation.md +0 -36
- package/docs/docs/getting-started/my-first-component.md +0 -227
- package/docs/docs/getting-started/start.html +0 -47
- package/docs/docs/getting-started/start.md +0 -35
- package/docs/docs/getting-started/theming.md +0 -253
- package/docs/docs/index.html +0 -99
- package/docs/docs/misc/api-configuration.md +0 -79
- package/docs/docs/misc/dataProviderKey.md +0 -168
- package/docs/hubs/decorators.html +0 -443
- package/docs/hubs/form-components.html +0 -404
- package/docs/hubs/remote-data.html +0 -371
- 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 +0 -28
- package/docs/index.md +0 -22
- package/docs/src/core/components/functional/translation/translation.md +0 -38
- package/docs/src/docs/decorators/ancestor-attribute.md +0 -59
- package/docs/src/docs/decorators/auto-subscribe.md +0 -40
- package/docs/src/docs/decorators/bind.md +0 -77
- package/docs/src/docs/decorators/get.md +0 -160
- package/docs/src/docs/decorators/handle.md +0 -119
- package/docs/src/docs/decorators/on-assign.md +0 -63
- package/docs/src/docs/decorators/patch.md +0 -44
- package/docs/src/docs/decorators/post.md +0 -134
- package/docs/src/docs/decorators/publish.md +0 -56
- package/docs/src/docs/decorators/put.md +0 -51
- package/docs/src/docs/decorators/subscribe.md +0 -87
- package/docs/src/docs/decorators/wait-for-ancestors.md +0 -76
- package/docs/src/docs/directives/sub.md +0 -75
- package/docs/src/docs/directives/t.md +0 -73
- package/docs/src/docs/getting-started/components.md +0 -5
- package/docs/src/docs/getting-started/create-a-component.md +0 -136
- package/docs/src/docs/getting-started/dataFlow.md +0 -87
- package/docs/src/docs/getting-started/installation.md +0 -36
- package/docs/src/docs/misc/docs-mock-api.md +0 -62
- package/docs/src/docs/misc/dynamic-path.md +0 -71
- package/docs/src/docs/misc/endpoint.md +0 -45
- package/docs/src/docs/misc/html-integration.md +0 -14
- /package/{docs → dist}/img/concorde/plane_01.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_02.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_03.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_04.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_05.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_06.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_07.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_08.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_09.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_10.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_11.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_12.jpg +0 -0
- /package/{docs → dist}/img/concorde/plane_13.jpg +0 -0
|
@@ -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.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Styling
|
|
2
|
+
|
|
3
|
+
Docs: [Theming](https://concorde.supersoniks.org/docs/getting-started/theming). Which parts and states components offer: [composition.md](composition.md).
|
|
4
|
+
|
|
5
|
+
## Theme
|
|
6
|
+
|
|
7
|
+
One `<sonic-theme>` at the app root sets the tokens; popovers, modals and toasts mount under it.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
html`<sonic-theme theme="auto" color font class="block bg-base min-h-screen">…</sonic-theme>`;
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`theme="light" | "dark" | "auto"` picks a palette; without it, only your `--sc-*` overrides apply. To brand, override the **essential tokens** only (fills, `-content` pairs, `--sc-base-*`, `--sc-rounded`, fonts) on `sonic-theme` or `:root`. Never copy derived variables (`--sc-rounded-sm`, `--sc-btn-*`, …).
|
|
14
|
+
|
|
15
|
+
## Rules
|
|
16
|
+
|
|
17
|
+
1. **Compose components first.** `sonic-button`, `sonic-badge`, `sonic-alert`, `sonic-card`, `sonic-divider`, `sonic-menu`, `sonic-icon`, form fields… before hand-made markup ([composition.md](composition.md)).
|
|
18
|
+
2. **Configure components with attributes, not CSS.** `type` (`primary` · `neutral` · `success` · `warning` · `danger` · `info`), `variant` (`outline` · `ghost` · `link`), `size` (`2xs` … `2xl`), `shape`, `status`. `class` on a `sonic-*` element is for layout only (width, margin, grid placement). No `::part()`, no private `--sc_*` variables.
|
|
19
|
+
3. **Semantic tokens only.** Fills and their text go in pairs: `bg-primary text-primary-content`, `bg-danger text-danger-content`. Surfaces: `bg-base text-content`. Borders and muted UI: the neutral scale (`border-neutral-200`, `bg-neutral-50`, `text-neutral-600`). Never raw colors: no hex / rgb, no Tailwind palette (`blue-500`). A missing color becomes a theme token.
|
|
20
|
+
4. **No `dark:` overrides.** Dark mode comes from `sonic-theme`; tokens switch by themselves.
|
|
21
|
+
5. **Shape from tokens.** `rounded` / `rounded-lg`, `shadow` / `shadow-md` and `border` map to `--sc-rounded*`, `--sc-shadow*`, `--sc-border-width`. Avoid arbitrary values when they could be replaced easily (`rounded-[6px]`, `p-[13px]`).
|
|
22
|
+
6. **Layout with `flex` / `grid` + `gap`.** Not `space-x-*` / `space-y-*` or margins between siblings. `size-10` instead of `w-10 h-10`.
|
|
23
|
+
7. **Conditional classes with `classMap`** (`lit/directives/class-map.js`), dynamic values with `styleMap`. No template-literal ternaries inside `class="…"`.
|
|
24
|
+
8. **Accessible by default.** Every field has a `label`. An icon-only button (`shape="circle"` / `"square"`) gets an `aria-label`; `sonic-icon` is `aria-hidden`.
|
|
25
|
+
|
|
26
|
+
## In a component
|
|
27
|
+
|
|
28
|
+
Tailwind classes apply inside a shadow root only if the component includes the project's Tailwind styles in `static styles`. Otherwise, write `css` with the tokens:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
static styles = css`
|
|
32
|
+
:host { display: flex; gap: 0.5rem; }
|
|
33
|
+
.panel {
|
|
34
|
+
background: var(--sc-base);
|
|
35
|
+
color: var(--sc-base-content);
|
|
36
|
+
border: var(--sc-border-width) solid var(--sc-base-200);
|
|
37
|
+
border-radius: var(--sc-rounded);
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
html`<div class=${classMap({ "bg-warning text-warning-content": delayed, "bg-base": !delayed })}>
|
|
44
|
+
<sonic-badge type=${delayed ? "warning" : "success"} size="sm">${status}</sonic-badge>
|
|
45
|
+
</div>`;
|
|
46
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
Symptom → usual cause → fix. Check these before reading framework source.
|
|
4
|
+
|
|
5
|
+
## Data
|
|
6
|
+
|
|
7
|
+
| Symptom | Cause | Fix |
|
|
8
|
+
|---------|-------|-----|
|
|
9
|
+
| Value never updates in the view | Subscribed to a parent object; a child `set` mutates it in place without notifying | `sub(key.leaf)` or `@subscribe(key.leaf)` |
|
|
10
|
+
| Same, with a leaf key | `@subscribe` without `@state()` | Add `@state()` |
|
|
11
|
+
| Value frozen in a template | `get(key)` in `html` (one-time snapshot) | `sub(key)` |
|
|
12
|
+
| `sub()` renders nothing | The store has no value yet, or a placeholder is `null` / `undefined` | Set an initial value; check the host property |
|
|
13
|
+
| Store value overwritten when the component connects | `@publish` publishes a defined initializer on connect | Leave the property `undefined` to keep the store value |
|
|
14
|
+
| `@handle` method crashes on start | It runs on connect and on every assignment, `null` included | Guard nullish values, or `{ waitForAllDefined: true }` / `Skip.Nullish` |
|
|
15
|
+
| `get` / `set` / `dp` throw about a placeholder | A key with `${…}` reached imperative code | Decorator, or build the resolved key (`usersKey[id]`) |
|
|
16
|
+
| Decorator with a dynamic path does nothing | A placeholder property is `null` / `undefined` (or `""` with `skipEmptyPlaceholder`) | Set the host property |
|
|
17
|
+
|
|
18
|
+
## HTTP
|
|
19
|
+
|
|
20
|
+
| Symptom | Cause | Fix |
|
|
21
|
+
|---------|-------|-----|
|
|
22
|
+
| `@get` never sends | No `serviceURL` on an ancestor (the GET waits for it); common in modals and portals | `<sonic-scope serviceURL>` around it, or `@get(endpoint, apiConfigKey)` |
|
|
23
|
+
| POST sent on every keystroke | `@post` sends on each body mutation by default | `{ autoPostOnBodyMutation: false }` + `send()` |
|
|
24
|
+
| Property `undefined` after the request | Read `this.board.flights` instead of the `ApiResult` | `this.board?.result?.flights` |
|
|
25
|
+
|
|
26
|
+
## Lists and forms
|
|
27
|
+
|
|
28
|
+
| Symptom | Cause | Fix |
|
|
29
|
+
|---------|-------|-----|
|
|
30
|
+
| List renders nothing | `items=${fn}` without the dot, so the function is lost | `.items=${fn}` (same for `.noItems` / `.skeleton` / `.separator`) |
|
|
31
|
+
| `sonic-list` never requests | No `fetch` attribute | Add `fetch` |
|
|
32
|
+
| List empty although the response has data | `key` does not name the array in the response | Set `key` to the array property |
|
|
33
|
+
| `sonic-queue` loads one batch only | No `$offset` in `dataProviderExpression` | `…?offset=$offset&limit=$limit` |
|
|
34
|
+
| Queue ignores the filter form | `dataFilterProvider` is not the form's store, or fields lack `name` | Same key path on both; reload follows after a 400 ms debounce |
|
|
35
|
+
| Field value not in the store | Missing `name`, or no `formDataProvider` on the field or an ancestor (`dataProvider` does not count) | Add both; pass `key.path`, not the key |
|
|
36
|
+
|
|
37
|
+
## Rendering and styling
|
|
38
|
+
|
|
39
|
+
| Symptom | Cause | Fix |
|
|
40
|
+
|---------|-------|-----|
|
|
41
|
+
| A `sonic-*` tag shows nothing | Its module was never imported | `import "@supersoniks/concorde/<name>"` |
|
|
42
|
+
| Tailwind classes ignored inside a component | The shadow root does not include the Tailwind styles | Add them to `static styles`, or use `css` with `var(--sc-*)` |
|
|
43
|
+
| Modal, popover or toast unstyled | No `sonic-theme` ancestor: they mount under the nearest one | Wrap the app in `sonic-theme` |
|
|
44
|
+
| `hideModal` button does not close the modal | The button is not inside `sonic-modal-actions` | Move it there |
|
|
45
|
+
| `get` is not a function / wrong `get` | Decorator `get` (`/decorators`) and store `get` (`/utils`) collide | Alias one: `get as getRequest` |
|
package/build-infos.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"date":
|
|
1
|
+
{"date":1793309731}
|