@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,307 +1,478 @@
|
|
|
1
1
|
# SDUI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## What is SDUI?
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
SDUI stands for `Server Driven User Interfaces`.
|
|
6
|
+
Basically, it generates a user interface based on a JSON SDUI Descriptor.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
### Subscriber extension:
|
|
9
|
+
|
|
10
|
+
SDUI extends the mixin [Subscriber](#docs/_core-concept/subscriber.md/subscriber).
|
|
11
|
+
This means that you must set a dataProvider with an id pointing to the publisher that will hold your SDUI Descriptor.
|
|
12
|
+
This also means that it has a reactive property named `props` that you can set with the JSON SDUI Descriptor in order to configure it.
|
|
13
|
+
|
|
14
|
+
### Fetcher extension:
|
|
15
|
+
|
|
16
|
+
SDUI extends the mixin Fetcher as [Fetch](#core/components/functional/fetch/fetch.md/fetch) and [List](#core/components/functional/list/list.md/list).
|
|
17
|
+
|
|
18
|
+
In this case, it will parse the JSON coming from the request.
|
|
19
|
+
The JSON must comply with the SDUI descriptor format.
|
|
20
|
+
|
|
21
|
+
As a fetcher, invalidating the publisher or updating the endpoint will trigger a new fetch and update accordingly.
|
|
22
|
+
|
|
23
|
+
### Rendering:
|
|
24
|
+
|
|
25
|
+
It has no shadowdom, and its display style is set to `contents`, so an empty SDUI has the fewest impact on the layout.
|
|
26
|
+
|
|
27
|
+
### Safe profile (opt-in)
|
|
28
|
+
|
|
29
|
+
Set `profile="safe"` on `sonic-sdui` to refuse untrusted HTML/JS from the descriptor:
|
|
30
|
+
|
|
31
|
+
* `js` URLs are **not** loaded
|
|
32
|
+
* nodes that use `markup`, `innerHTML`, `prefix`, or `suffix` are **skipped** (not rendered)
|
|
33
|
+
* `textContent` is **allowed** (plain text, no HTML parsing)
|
|
34
|
+
* a clear `console.warn` is emitted for each refusal
|
|
35
|
+
* without the attribute, behaviour is unchanged
|
|
36
|
+
|
|
37
|
+
Use the pure helper `validateSafeDescriptor(descriptor)` (from `sdui-safe`) to list violations server-side or in a custom validator — it returns `{ path, field, message }[]` and has no side effects.
|
|
8
38
|
|
|
9
39
|
<sonic-code>
|
|
10
40
|
<template>
|
|
11
41
|
<sonic-sdui
|
|
12
|
-
|
|
42
|
+
profile="safe"
|
|
43
|
+
dataProvider="sdui-safe-example"
|
|
13
44
|
props='{
|
|
14
|
-
"nodes":[
|
|
15
|
-
"tagName":"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{ "tagName":"strong", "textContent":"CN 001 · CDG → JFK" },
|
|
19
|
-
{ "tagName":"sonic-badge", "attributes":{ "type":"warning" }, "textContent":"Delayed" }
|
|
20
|
-
]
|
|
21
|
-
}]
|
|
45
|
+
"nodes":[
|
|
46
|
+
{ "tagName":"p", "textContent":"Plain text is fine" },
|
|
47
|
+
{ "innerHTML":"<script>/* refused */</script>" }
|
|
48
|
+
]
|
|
22
49
|
}'
|
|
23
50
|
></sonic-sdui>
|
|
24
51
|
</template>
|
|
25
52
|
</sonic-code>
|
|
26
53
|
|
|
27
|
-
|
|
54
|
+
### Component catalog (build-only)
|
|
28
55
|
|
|
29
|
-
|
|
56
|
+
At build time, Concorde generates a **neutral JSON catalog** of custom elements for SDUI / external agents:
|
|
57
|
+
|
|
58
|
+
* file: `src/core/components/functional/sdui/component-catalog.json`
|
|
59
|
+
* import: `@supersoniks/concorde/sdui/component-catalog.json` (or the long `core/components/functional/sdui/…` path)
|
|
60
|
+
* regenerate: `yarn generate:sdui-catalog` (also runs in `prebuild`)
|
|
61
|
+
* source: Custom Elements Manifest via `@custom-elements-manifest/analyzer` (Lit)
|
|
62
|
+
* no runtime impact
|
|
63
|
+
|
|
64
|
+
Each entry includes `tag`, `props` (name, attribute, type, allowed `values` when detectable, `default`, description), plus slots/events when present.
|
|
65
|
+
|
|
66
|
+
Components with thin JSDoc are listed in `component-catalog.gaps.json` (same folder) — annotations are **not** mass-rewritten in this step.
|
|
67
|
+
|
|
68
|
+
### Incremental operations (opt-in)
|
|
69
|
+
|
|
70
|
+
Beside the full-descriptor rebuild path, `sonic-sdui` exposes surgical ops (siblings keep DOM state):
|
|
71
|
+
|
|
72
|
+
* `upsertNode(node, parentId?, index?)` — `node.nodeId` required
|
|
73
|
+
* `removeNode(nodeId)`
|
|
74
|
+
* `setData(path, value)` — updates a publisher path (`form.email` or `provider.nested`)
|
|
75
|
+
* `applyOp(op)` / optional `opsDataProvider` for a stream of `SDUIOp`
|
|
76
|
+
* `endIncremental()` — return to props → full rebuild
|
|
77
|
+
|
|
78
|
+
Public extension surface (also covered above): `profile="safe"`, `textContent`, `sdui-action` / `action`, component catalog JSON, `partial` + `childNodeIds` / `nodeById`, and these incremental ops.
|
|
79
|
+
|
|
80
|
+
### Partial rendering (opt-in)
|
|
81
|
+
|
|
82
|
+
Set the boolean attribute `partial` on `sonic-sdui` to tolerate missing child references:
|
|
83
|
+
|
|
84
|
+
* Declare a flat registry with `nodeById` and point to children with `childNodeIds: ["a", "b"]`
|
|
85
|
+
* If a `childNodeId` is **missing** and `partial` is set → a light placeholder is inserted
|
|
86
|
+
(`data-sdui-placeholder`, `data-node-id`, `display: contents`, `aria-hidden`)
|
|
87
|
+
* If `partial` is **not** set → `console.warn` and the missing child is skipped (no crash)
|
|
88
|
+
* Nested `nodes` arrays keep working as before; without `childNodeIds` / `partial`, behaviour is unchanged
|
|
89
|
+
* Incremental ops (later) reuse the same placeholder path
|
|
30
90
|
|
|
31
91
|
<sonic-code>
|
|
32
92
|
<template>
|
|
33
|
-
<sonic-sdui
|
|
93
|
+
<sonic-sdui
|
|
94
|
+
partial
|
|
95
|
+
dataProvider="sdui-partial-example"
|
|
96
|
+
props='{
|
|
97
|
+
"nodes":[{
|
|
98
|
+
"tagName":"div",
|
|
99
|
+
"childNodeIds":["title", "body"]
|
|
100
|
+
}],
|
|
101
|
+
"nodeById":{
|
|
102
|
+
"title":{ "nodeId":"title", "tagName":"h2", "textContent":"Hello" }
|
|
103
|
+
}
|
|
104
|
+
}'
|
|
105
|
+
></sonic-sdui>
|
|
34
106
|
</template>
|
|
35
107
|
</sonic-code>
|
|
36
108
|
|
|
37
|
-
|
|
109
|
+
### Actions (`sdui-action`)
|
|
110
|
+
|
|
111
|
+
Declarative opt-in on a node: set `action: { name, context? }` (and optionally `nodeId`).
|
|
112
|
+
A click on the rendered element dispatches a `CustomEvent` named **`sdui-action`** on `sonic-sdui` with:
|
|
113
|
+
|
|
114
|
+
* `detail: { name, context, sourceNodeId? }`
|
|
115
|
+
* `bubbles: true`, `composed: true` — so a host (page shell, parent) can listen without binding each node
|
|
38
116
|
|
|
39
|
-
|
|
117
|
+
This does **not** replace form submit (`sonic-submit` / POST / `messagesKey`). Those keep working as before; only nodes that declare `action` emit `sdui-action`.
|
|
40
118
|
|
|
41
119
|
<sonic-code>
|
|
42
120
|
<template>
|
|
43
121
|
<sonic-sdui
|
|
44
|
-
dataProvider="sdui-
|
|
122
|
+
dataProvider="sdui-action-example"
|
|
45
123
|
props='{
|
|
46
|
-
"nodes":[
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
124
|
+
"nodes":[{
|
|
125
|
+
"tagName":"sonic-button",
|
|
126
|
+
"nodeId":"confirm-btn",
|
|
127
|
+
"textContent":"Confirm",
|
|
128
|
+
"action":{ "name":"confirm", "context":{ "step":1 } }
|
|
129
|
+
}]
|
|
50
130
|
}'
|
|
51
131
|
></sonic-sdui>
|
|
132
|
+
<script type="module">
|
|
133
|
+
document.querySelector("sonic-sdui")?.addEventListener("sdui-action", (e) => {
|
|
134
|
+
console.log(e.detail); // { name, context, sourceNodeId }
|
|
135
|
+
});
|
|
136
|
+
</script>
|
|
137
|
+
</template>
|
|
138
|
+
</sonic-code>
|
|
139
|
+
|
|
140
|
+
## SDUI descriptor
|
|
141
|
+
|
|
142
|
+
### TypeScript definition:
|
|
143
|
+
<sonic-code language="typescript">
|
|
144
|
+
<template>
|
|
145
|
+
export type SDUIDescriptor = {
|
|
146
|
+
js?: Array<string>;
|
|
147
|
+
css?: Array<string>;
|
|
148
|
+
library?: Record<string, SDUINode>;
|
|
149
|
+
nodes?: Array<SDUINode>;
|
|
150
|
+
nodeById?: Record<string, SDUINode>;
|
|
151
|
+
};
|
|
52
152
|
</template>
|
|
53
153
|
</sonic-code>
|
|
54
154
|
|
|
55
|
-
|
|
155
|
+
### Meaning of the keys:
|
|
56
156
|
|
|
57
|
-
|
|
157
|
+
* **js**: An array of URLs pointing to JavaScript files to load.
|
|
158
|
+
* **css**: An array of URLs pointing to CSS files to load.
|
|
159
|
+
* **library**: A record of SDUINode definitions intended to be used as a model for other nodes. The keys of the record can be used as the libraryKey of the node. This node will then specialize the model with its own descriptor.
|
|
160
|
+
* **nodes**: An array of SDUINode descriptors. Each SDUINode will result in an HTMLElement added to the root of the component.
|
|
161
|
+
* **nodeById**: Optional flat map of nodes by `nodeId`, used with `childNodeIds` for partial / incremental graphs.
|
|
162
|
+
|
|
163
|
+
## SDUINode
|
|
164
|
+
|
|
165
|
+
### Descriptor
|
|
166
|
+
|
|
167
|
+
An SDUINode represents an HTMLElement.
|
|
168
|
+
|
|
169
|
+
TypeScript definition:
|
|
170
|
+
|
|
171
|
+
<sonic-code language="typescript">
|
|
172
|
+
<template>
|
|
173
|
+
export type SDUINode = {
|
|
174
|
+
markup?: string;
|
|
175
|
+
tagName?: string;
|
|
176
|
+
attributes?: Record<string, string>;
|
|
177
|
+
nodes?: Array<SDUINode>;
|
|
178
|
+
textContent?: string;
|
|
179
|
+
innerHTML?: string;
|
|
180
|
+
prefix?: string;
|
|
181
|
+
suffix?: string;
|
|
182
|
+
libraryKey?: string;
|
|
183
|
+
contentElementSelector?: string;
|
|
184
|
+
parentElementSelector?: string;
|
|
185
|
+
action?: { name: string; context?: Record<string, unknown> };
|
|
186
|
+
nodeId?: string;
|
|
187
|
+
};
|
|
188
|
+
</template>
|
|
189
|
+
</sonic-code>
|
|
190
|
+
|
|
191
|
+
Summary of properties:
|
|
192
|
+
* **markup**: Use it if you prefer to define your node entirely using an HTML string.
|
|
193
|
+
* **tagName**: The tag name of the HTML element.
|
|
194
|
+
* **attributes**: A string key/value pair storing each attribute name/value of the HTML element created.
|
|
195
|
+
* **nodes**: An array of SDUINode descriptors. The children of the HTMLElement are created this way.
|
|
196
|
+
* **textContent**: Plain text for the node (no HTML parsing). Preferred for safe UIs; ignored when `nodes` is non-empty. Allowed with `profile="safe"`.
|
|
197
|
+
* **innerHTML**: The inner HTML of the current node is defined here if needed.
|
|
198
|
+
* **prefix**: Use it if you want to wrap the component with some HTML string in conjunction with the suffix.
|
|
199
|
+
* **suffix**: Use it if you want to wrap the component with some HTML string in conjunction with the prefix.
|
|
200
|
+
* **libraryKey**: An identifier that points to an SDUINode to be used as a model for this node.
|
|
201
|
+
* **contentElementSelector**: For SDUINodes defined in the library only. It is a CSS selector that defines where child nodes are added.
|
|
202
|
+
* **parentElementSelector**: If the current node, as a future child, has a `parentElementSelector` attribute, it is added to the node corresponding to the associated CSS selector rather than directly to the element.
|
|
203
|
+
* **action**: Optional `{ name, context? }`. Click emits `sdui-action` (see above).
|
|
204
|
+
* **nodeId**: Optional logical id (not the DOM `id` attribute). Copied into `sdui-action.detail.sourceNodeId` when set.
|
|
205
|
+
* **childNodeIds**: Optional list of `nodeId`s to append as children (from `nodeById` / tree index). See Partial rendering.
|
|
206
|
+
|
|
207
|
+
### Markup
|
|
208
|
+
Use it if you prefer to define your node entirely using an HTML string.
|
|
58
209
|
|
|
59
210
|
<sonic-code>
|
|
60
211
|
<template>
|
|
61
|
-
<sonic-sdui
|
|
62
|
-
dataProvider="sdui-
|
|
212
|
+
<sonic-sdui
|
|
213
|
+
dataProvider="sdui-markup-example"
|
|
63
214
|
props='{
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"contentElementSelector":"div"
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
"nodes":[
|
|
73
|
-
{ "libraryKey":"flightCard", "nodes":[{ "tagName":"span", "textContent":"CN 001 · Gate C4" }] },
|
|
74
|
-
{ "libraryKey":"email", "attributes":{ "label":"Passenger email", "name":"email", "class":"block mt-4 max-w-sm" } }
|
|
75
|
-
]
|
|
76
|
-
}'
|
|
215
|
+
"nodes":[
|
|
216
|
+
{
|
|
217
|
+
"markup":"keep shouting <sonic-badge>foo</sonic-badge> <sonic-badge>bar</sonic-badge> !"
|
|
218
|
+
}
|
|
219
|
+
]}'
|
|
77
220
|
></sonic-sdui>
|
|
78
221
|
</template>
|
|
79
222
|
</sonic-code>
|
|
80
223
|
|
|
81
|
-
|
|
224
|
+
### Tag name
|
|
225
|
+
Here we use the field `tagName` of SDUINode to create an element with tag name `sonic-input`.
|
|
226
|
+
|
|
227
|
+
<sonic-code>
|
|
228
|
+
<template>
|
|
229
|
+
<sonic-sdui
|
|
230
|
+
dataProvider="sdui-tagName-example"
|
|
231
|
+
props='{
|
|
232
|
+
"nodes":[
|
|
233
|
+
{
|
|
234
|
+
"tagName":"sonic-input"
|
|
235
|
+
}
|
|
236
|
+
]}'
|
|
237
|
+
></sonic-sdui>
|
|
238
|
+
</template>
|
|
239
|
+
</sonic-code>
|
|
82
240
|
|
|
83
|
-
|
|
241
|
+
### Attributes
|
|
242
|
+
A string key/value pair storing each attribute name/value of the HTML element created.
|
|
243
|
+
As no tag name is defined, a div element is created.
|
|
244
|
+
Here we define the style attribute to create a tiny red square.
|
|
84
245
|
|
|
85
246
|
<sonic-code>
|
|
86
247
|
<template>
|
|
87
|
-
<sonic-sdui
|
|
88
|
-
dataProvider="sdui-
|
|
248
|
+
<sonic-sdui
|
|
249
|
+
dataProvider="sdui-attributes-example"
|
|
89
250
|
props='{
|
|
90
251
|
"nodes":[{
|
|
91
|
-
"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
{ "tagName":"li", "parentElementSelector":"ul", "textContent":"CN 001 · CDG → JFK" },
|
|
95
|
-
{ "tagName":"li", "parentElementSelector":"ul", "textContent":"CN 003 · LHR → JFK" }
|
|
96
|
-
]
|
|
252
|
+
"attributes":{
|
|
253
|
+
"style":"width:50px;height:10px;background:red;"
|
|
254
|
+
}
|
|
97
255
|
}]
|
|
98
256
|
}'
|
|
99
257
|
></sonic-sdui>
|
|
100
258
|
</template>
|
|
101
259
|
</sonic-code>
|
|
102
260
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
A node with `action: { name, context? }` makes a click on its element dispatch an `sdui-action` event from `sonic-sdui`. `detail` is `{ name, context, sourceNodeId? }`, where `sourceNodeId` is the node `nodeId`. The event bubbles and is composed, so a page shell can listen once for every node. Form posting stays with [Submit](/core/components/functional/submit).
|
|
261
|
+
### Nodes
|
|
262
|
+
Children of the current node can be added using the field `nodes` recursively.
|
|
106
263
|
|
|
107
264
|
<sonic-code>
|
|
108
265
|
<template>
|
|
109
|
-
<sonic-sdui
|
|
110
|
-
|
|
111
|
-
dataProvider="sdui-action-example"
|
|
266
|
+
<sonic-sdui
|
|
267
|
+
dataProvider="sdui-nodes-example"
|
|
112
268
|
props='{
|
|
113
269
|
"nodes":[{
|
|
114
|
-
"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
270
|
+
"nodes":[
|
|
271
|
+
{"innerHTML":"A"},
|
|
272
|
+
{
|
|
273
|
+
"prefix":"B",
|
|
274
|
+
"nodes":[
|
|
275
|
+
{"innerHTML":"👉 B.1"},
|
|
276
|
+
{"innerHTML":"👉 B.2"}
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
]
|
|
118
280
|
}]
|
|
119
281
|
}'
|
|
120
282
|
></sonic-sdui>
|
|
121
283
|
</template>
|
|
122
284
|
</sonic-code>
|
|
123
285
|
|
|
124
|
-
|
|
286
|
+
### InnerHTML
|
|
287
|
+
As no tag name is defined, a div element is created, and then we use `innerHTML` to add content to it.
|
|
288
|
+
|
|
289
|
+
<sonic-code>
|
|
125
290
|
<template>
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
291
|
+
<sonic-sdui
|
|
292
|
+
dataProvider="sdui-html-example"
|
|
293
|
+
props='{
|
|
294
|
+
"nodes":[{
|
|
295
|
+
"innerHTML":"keep shouting <sonic-badge>foo</sonic-badge> <sonic-badge>bar</sonic-badge> !"
|
|
296
|
+
}]
|
|
297
|
+
}'
|
|
298
|
+
></sonic-sdui>
|
|
129
299
|
</template>
|
|
130
300
|
</sonic-code>
|
|
131
301
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
With `profile="safe"`, the descriptor cannot inject HTML or scripts: `js` URLs are not loaded, and nodes using `markup` / `innerHTML` / `prefix` / `suffix` (directly or through their library model) are skipped with a `console.warn`. `textContent`, attributes and actions still work. Without the attribute, everything is rendered.
|
|
302
|
+
### Prefix and suffix
|
|
303
|
+
Use them if you want to wrap the component with some HTML string.
|
|
135
304
|
|
|
136
305
|
<sonic-code>
|
|
137
306
|
<template>
|
|
138
|
-
<sonic-sdui
|
|
139
|
-
|
|
140
|
-
dataProvider="sdui-safe-example"
|
|
307
|
+
<sonic-sdui
|
|
308
|
+
dataProvider="sdui-prefixSuffix-example"
|
|
141
309
|
props='{
|
|
142
|
-
"nodes":[
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
310
|
+
"nodes":[{
|
|
311
|
+
"prefix":"👇",
|
|
312
|
+
"suffix":"☝️",
|
|
313
|
+
"innerHTML":"The node content"
|
|
314
|
+
}]
|
|
146
315
|
}'
|
|
147
316
|
></sonic-sdui>
|
|
148
317
|
</template>
|
|
149
318
|
</sonic-code>
|
|
150
319
|
|
|
151
|
-
|
|
320
|
+
### Library key and contentElementSelector
|
|
321
|
+
The libraryKey of SDUINode is an identifier that points to an SDUINode description in the library to be used as a model for this node.
|
|
322
|
+
|
|
323
|
+
Note that the SDUI has a default library containing some basic component definitions useful for form declaration (see default-library.json).
|
|
324
|
+
|
|
325
|
+
This example uses the library key `submit` which points to a `sonic-submit` containing a button also coming from the library.
|
|
152
326
|
|
|
153
|
-
|
|
327
|
+
The element named `button` in the library is a `sonic-button` of type `success` containing a check icon as a prefix.
|
|
154
328
|
|
|
155
|
-
|
|
329
|
+
Since the `submit` library element contains an attribute `contentElementSelector` with the value `sonic-button`, the "injected content" is put inside the button.
|
|
330
|
+
|
|
331
|
+
We used `innerHTML` for the sake of simplicity, but you can use nodes to add any complex content.
|
|
156
332
|
|
|
157
333
|
<sonic-code>
|
|
158
334
|
<template>
|
|
159
|
-
<sonic-sdui
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
></sonic-sdui>
|
|
335
|
+
<sonic-sdui dataProvider="sdui-library-example" props='
|
|
336
|
+
{
|
|
337
|
+
"nodes":[
|
|
338
|
+
{
|
|
339
|
+
"libraryKey":"submit",
|
|
340
|
+
"innerHTML":"Injected content"
|
|
341
|
+
}
|
|
342
|
+
]
|
|
343
|
+
}
|
|
344
|
+
'></sonic-sdui>
|
|
169
345
|
</template>
|
|
170
346
|
</sonic-code>
|
|
171
347
|
|
|
172
|
-
|
|
348
|
+
### parentElementSelector
|
|
349
|
+
|
|
350
|
+
This special field lets you inject the content at any place in the HTML flow already set inside the parent SDUI component by using a CSS selector.
|
|
173
351
|
|
|
174
|
-
|
|
352
|
+
⚠️ Note that it doesn't work with top-level nodes.
|
|
175
353
|
|
|
176
354
|
<sonic-code>
|
|
177
355
|
<template>
|
|
178
|
-
<sonic-sdui
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
356
|
+
<sonic-sdui dataProvider="sdui-parentElementSelector-example" props='
|
|
357
|
+
{
|
|
358
|
+
"nodes":[
|
|
359
|
+
{
|
|
360
|
+
"nodes":[
|
|
361
|
+
{
|
|
362
|
+
"prefix":"👇 Selected parent element",
|
|
363
|
+
"suffix":"☝️ End of selected parent element",
|
|
364
|
+
"tagName":"span"
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"parentElementSelector":"span",
|
|
368
|
+
"innerHTML":"Content having a parentElementSelector attribute"
|
|
369
|
+
}
|
|
370
|
+
]
|
|
371
|
+
}
|
|
372
|
+
]
|
|
373
|
+
}
|
|
374
|
+
'></sonic-sdui>
|
|
190
375
|
</template>
|
|
191
376
|
</sonic-code>
|
|
192
377
|
|
|
193
|
-
|
|
378
|
+
### Fetch example:
|
|
194
379
|
|
|
195
|
-
|
|
380
|
+
<sonic-code>
|
|
381
|
+
<template>
|
|
382
|
+
<sonic-sdui dataProvider="sdui-fetch-example" endPoint="/src/core/components/functional/sdui/example.json"></sonic-sdui>
|
|
383
|
+
</template>
|
|
384
|
+
</sonic-code>
|
|
385
|
+
|
|
386
|
+
## Transformers:
|
|
387
|
+
|
|
388
|
+
The transformers let you transform the structure of the SDUI Descriptor into a new one before parsing and rendering it.
|
|
389
|
+
|
|
390
|
+
To enable it, you must fill the `transformation` attribute of the component with a URL pointing to a Transform descriptor.
|
|
196
391
|
|
|
197
392
|
<sonic-code language="typescript">
|
|
198
393
|
<template>
|
|
199
|
-
{
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
]
|
|
204
|
-
}
|
|
394
|
+
export type SDUITransformDescription = {
|
|
395
|
+
library?: Record<string, SDUINode>;
|
|
396
|
+
transforms: Array<SDUITransformAction>;
|
|
397
|
+
};
|
|
205
398
|
</template>
|
|
206
399
|
</sonic-code>
|
|
207
400
|
|
|
208
|
-
|
|
209
|
-
|--------|--------|
|
|
210
|
-
| `remap` | Replaces each matched node with `ui`, keeping its attributes, content and children unless `ui` redefines them |
|
|
211
|
-
| `unwrap` | Replaces each matched node with its children |
|
|
212
|
-
| `wrap` | Groups the matched nodes into the `ui` node |
|
|
213
|
-
| `delete` | Removes the matched nodes |
|
|
214
|
-
| `insert` | Inserts `ui` relative to the node matched by `before` · `after` · `in` |
|
|
215
|
-
| `move` | Moves the matched nodes next to the node matched by `before` or `after` |
|
|
401
|
+
### The library:
|
|
216
402
|
|
|
217
|
-
|
|
403
|
+
Each key of the library will be merged with the current library in the SDUI Descriptor, by replacing or creating items library key by key.
|
|
218
404
|
|
|
219
|
-
|
|
405
|
+
### The transform actions:
|
|
220
406
|
|
|
221
|
-
|
|
407
|
+
Each transform represents an action that will be done on the SDUI descriptor before the creation of the entire UI.
|
|
408
|
+
|
|
409
|
+
<sonic-code language="typescript">
|
|
222
410
|
<template>
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
411
|
+
export type SDUITransformAction = {
|
|
412
|
+
action: SDUITransformActionName;
|
|
413
|
+
patterns?: Array<SDUINode>;
|
|
414
|
+
after?: SDUINode;
|
|
415
|
+
before?: SDUINode;
|
|
416
|
+
in?: SDUINode;
|
|
417
|
+
ui?: SDUINode;
|
|
418
|
+
};
|
|
419
|
+
</template>
|
|
420
|
+
</sonic-code>
|
|
421
|
+
|
|
422
|
+
The action that will be done is a verb:
|
|
423
|
+
|
|
424
|
+
<sonic-code language="typescript">
|
|
425
|
+
<template>
|
|
426
|
+
export type SDUITransformActionName = "remap" | "unwrap" | "wrap" | "delete" | "insert" | "move";
|
|
231
427
|
</template>
|
|
232
428
|
</sonic-code>
|
|
233
429
|
|
|
234
|
-
|
|
430
|
+
* **remap**: The properties (tagName, innerHTML, etc.) of the targeted SDUINode will be created/changed according to their presence in the `ui` (SDUINode) property of the transformAction.
|
|
431
|
+
* **unwrap**: Replaces the targeted SDUINode in place with its children.
|
|
432
|
+
* **wrap**: Groups all SDUINodes targeted by the patterns into the new SDUINode described in the `ui` prop of the transformAction.
|
|
433
|
+
* **delete**: Deletes the targeted item.
|
|
434
|
+
* **insert**: Inserts a new SDUINode described by the `ui` prop into the flow. The position of insertion depends on the presence of the attributes `before`, `after`, `in`, which is a pattern to target an existing SDUINode.
|
|
235
435
|
|
|
236
|
-
|
|
436
|
+
## Misc Tricks:
|
|
237
437
|
|
|
438
|
+
### sduiKey
|
|
439
|
+
|
|
440
|
+
This is an HTML attribute to set on the component if needed. In this case, the component will not treat its props value directly as an SDUI descriptor. Internally, it will basically extract the SDUIDescriptor by doing something like this: `const sduiDescriptor = this.props[this.sduikey]`.
|
|
441
|
+
|
|
442
|
+
### messageKey
|
|
443
|
+
|
|
444
|
+
This is an HTML attribute to set on the component if needed. In this case, the component will automatically create a `sonic-toast-message-subscriber` component. The data found in `props[messageKey]` will be treated as the data expected by the `sonic-toast-message-subscriber`. So, by respecting the format of data supported by this component, you will be able to show multiple toasts in the result of a request.
|
|
445
|
+
|
|
446
|
+
Example of JSON with `messageKey`=`messages`:
|
|
238
447
|
<sonic-code language="typescript">
|
|
239
448
|
<template>
|
|
240
|
-
|
|
449
|
+
{
|
|
450
|
+
"messages": [{
|
|
451
|
+
"content": "The product has been added to your cart",
|
|
452
|
+
"status": "success",
|
|
453
|
+
"type": "public"
|
|
454
|
+
}]
|
|
455
|
+
}
|
|
241
456
|
</template>
|
|
242
457
|
</sonic-code>
|
|
243
458
|
|
|
459
|
+
### library
|
|
460
|
+
|
|
461
|
+
This is an HTML attribute to set on the component if needed. You can set a URL pointing to a JSON describing a library with the same structure as the library in the SDUIDescriptor. The component will simply override its library with the given one.
|
|
462
|
+
|
|
244
463
|
## Playground
|
|
245
464
|
|
|
246
|
-
|
|
465
|
+
Here is a little playground to let you test some simple tricks.
|
|
247
466
|
|
|
248
467
|
<sonic-code>
|
|
249
468
|
<template>
|
|
250
|
-
<sonic-textarea
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
469
|
+
<sonic-textarea
|
|
470
|
+
rows="10"
|
|
471
|
+
onChange="SonicPublisherManager.get('sdui-playground').set(JSON.parse(this.value))"
|
|
472
|
+
value='{"nodes":[{"tagName":"div", "innerHTML":"test"}]}'
|
|
473
|
+
>
|
|
474
|
+
</sonic-textarea>
|
|
475
|
+
<sonic-sdui dataProvider="sdui-playground" props='{"nodes":[{"tagName":"div", "innerHTML":"test"}]}'>
|
|
476
|
+
</sonic-sdui>
|
|
256
477
|
</template>
|
|
257
478
|
</sonic-code>
|
|
258
|
-
|
|
259
|
-
## API reference
|
|
260
|
-
|
|
261
|
-
| Attribute | Values | Description |
|
|
262
|
-
|-----------|--------|-------------|
|
|
263
|
-
| `dataProvider` | string | Publisher holding the descriptor. Required |
|
|
264
|
-
| `props` | `SDUIDescriptor` (JSON) | Descriptor to render |
|
|
265
|
-
| `fetch` | boolean | Loads the descriptor from `serviceURL` + `endPoint` (or `dataProvider`). Other request attributes as on [Fetch](/core/components/functional/fetch) |
|
|
266
|
-
| `sduiKey` | string | Reads the descriptor from `props[sduiKey]` |
|
|
267
|
-
| `messagesKey` | string | Path in `props` of the toast messages to display |
|
|
268
|
-
| `profile` | `safe` | Refuses `js` / `markup` / `innerHTML` / `prefix` / `suffix`. Unset by default |
|
|
269
|
-
| `partial` | boolean | Renders a placeholder for missing `childNodeIds` |
|
|
270
|
-
| `library` | URL | JSON library that replaces the descriptor library |
|
|
271
|
-
| `transformation` | URL | JSON transform description applied before rendering |
|
|
272
|
-
| `opsDataProvider` | string | Publisher whose assigned values are passed to `applyOp` |
|
|
273
|
-
|
|
274
|
-
| Descriptor key | Description |
|
|
275
|
-
|----------------|-------------|
|
|
276
|
-
| `nodes` | Root nodes |
|
|
277
|
-
| `nodeById` | Flat registry of nodes for `childNodeIds` |
|
|
278
|
-
| `library` | Node models by key, merged over the default library |
|
|
279
|
-
| `js` / `css` | Script and stylesheet URLs to load (`js` refused in safe profile) |
|
|
280
|
-
|
|
281
|
-
| Node field | Description |
|
|
282
|
-
|------------|-------------|
|
|
283
|
-
| `tagName` | Element tag (default `div`) |
|
|
284
|
-
| `attributes` | Attribute name → value (objects are serialized to JSON) |
|
|
285
|
-
| `nodes` | Child nodes |
|
|
286
|
-
| `childNodeIds` | Child `nodeId`s resolved from `nodeById` or the tree |
|
|
287
|
-
| `textContent` | Plain text. Ignored when the node has children |
|
|
288
|
-
| `markup` · `innerHTML` · `prefix` · `suffix` | HTML strings (refused in safe profile) |
|
|
289
|
-
| `libraryKey` | Library entry used as the model |
|
|
290
|
-
| `contentElementSelector` | In a library model: where children are appended |
|
|
291
|
-
| `parentElementSelector` | Appends the node to a matching element of its parent |
|
|
292
|
-
| `nodeId` | Logical id for actions, `childNodeIds` and incremental updates (rendered as `data-sdui-node-id`) |
|
|
293
|
-
| `action` | `{ name, context? }` dispatched as `sdui-action` on click |
|
|
294
|
-
|
|
295
|
-
| Method | Description |
|
|
296
|
-
|--------|-------------|
|
|
297
|
-
| `upsertNode(node, parentId?, index?)` | Adds or replaces a node by `nodeId` |
|
|
298
|
-
| `removeNode(nodeId)` | Removes a node |
|
|
299
|
-
| `setData(path, value)` | Sets a publisher path (`form.email`), absolute or relative to `dataProvider` |
|
|
300
|
-
| `applyOp(op)` | Runs an `SDUIOp`: `upsertNode` · `removeNode` · `setData` |
|
|
301
|
-
| `endIncremental()` | Leaves incremental mode; the next `props` change rebuilds everything |
|
|
302
|
-
|
|
303
|
-
| Event | Detail |
|
|
304
|
-
|-------|--------|
|
|
305
|
-
| `sdui-action` | `{ name, context, sourceNodeId? }` |
|
|
306
|
-
|
|
307
|
-
No slots.
|