@supersoniks/concorde 4.5.2 → 4.7.0
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/.gitlab-ci.yml +23 -0
- package/README.md +106 -55
- package/ai/AGENTS.md +52 -0
- package/ai/README.md +30 -0
- package/ai/cursor/rules/concorde-menu.mdc +15 -0
- package/ai/cursor/rules/concorde-scope.mdc +14 -0
- package/ai/cursor/rules/concorde-theme.mdc +13 -0
- package/ai/cursor/rules/concorde.mdc +49 -0
- package/ai/jetbrains/rules/concorde.md +39 -0
- package/ai/skills/concorde/SKILL.md +220 -0
- package/ai/skills/concorde-get-set-dp/SKILL.md +194 -0
- package/ai/skills/concorde-imports/SKILL.md +78 -0
- package/ai/skills/concorde-menu/SKILL.md +74 -0
- package/ai/skills/concorde-scope/SKILL.md +70 -0
- package/ai/skills/concorde-theme/SKILL.md +46 -0
- package/build-infos.json +1 -1
- package/concorde-core.bundle.js +159 -159
- package/concorde-core.es.js +1915 -1809
- package/dist/altcha-widget.js +2662 -0
- package/dist/concorde-core.bundle.js +159 -159
- package/dist/concorde-core.es.js +1915 -1809
- package/dist/docs-mock-api-sw.js +589 -0
- package/dist/docs-mock-api-sw.js.map +7 -0
- package/docs/altcha-widget.js +2662 -0
- package/docs/assets/index-D9pxaQYK.js +7508 -0
- package/docs/assets/index-t0-i22oI.css +1 -0
- package/docs/docs-mock-api-sw.js +589 -0
- package/docs/docs-mock-api-sw.js.map +7 -0
- package/docs/index.html +2 -2
- package/docs/src/core/components/functional/fetch/fetch.md +13 -11
- package/docs/src/core/components/functional/if/if.md +4 -11
- package/docs/src/core/components/functional/list/list.md +60 -194
- package/docs/src/core/components/functional/queue/queue.md +70 -85
- package/docs/src/core/components/functional/router/router.md +62 -97
- package/docs/src/core/components/functional/states/states.md +2 -2
- package/docs/src/core/components/functional/submit/submit.md +86 -55
- package/docs/src/core/components/ui/captcha/captcha.md +2 -2
- package/docs/src/core/components/ui/card/card.md +1 -1
- package/docs/src/core/components/ui/form/checkbox/checkbox.md +5 -32
- package/docs/src/core/components/ui/form/input/input.md +5 -30
- package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +6 -4
- package/docs/src/core/components/ui/form/radio/radio.md +5 -32
- package/docs/src/core/components/ui/form/select/select.md +5 -31
- package/docs/src/core/components/ui/form/switch/switch.md +5 -32
- package/docs/src/core/components/ui/loader/loader.md +1 -13
- package/docs/src/core/components/ui/table/table.md +3 -3
- package/docs/src/docs/_core-concept/dataFlow.md +73 -0
- package/docs/src/docs/_core-concept/subscriber.md +9 -10
- package/docs/src/docs/_decorators/ancestor-attribute.md +4 -3
- package/docs/src/docs/_decorators/auto-subscribe.md +19 -16
- package/docs/src/docs/_decorators/bind.md +20 -17
- package/docs/src/docs/_decorators/get.md +7 -4
- package/docs/src/docs/_decorators/handle.md +171 -0
- package/docs/src/docs/_decorators/on-assign.md +99 -73
- package/docs/src/docs/_decorators/publish.md +2 -1
- package/docs/src/docs/_decorators/subscribe.md +70 -9
- package/docs/src/docs/_decorators/wait-for-ancestors.md +13 -10
- package/docs/src/docs/_directives/sub.md +91 -0
- package/docs/src/docs/_getting-started/ai-agents.md +56 -0
- package/docs/src/docs/_getting-started/concorde-manual-install.md +133 -0
- package/docs/src/docs/_getting-started/concorde-outside.md +13 -123
- package/docs/src/docs/_getting-started/create-a-component.md +2 -0
- package/docs/src/docs/_getting-started/my-first-component.md +236 -0
- package/docs/src/docs/_getting-started/my-first-subscriber.md +29 -83
- package/docs/src/docs/_getting-started/pubsub.md +21 -134
- package/docs/src/docs/_getting-started/start.md +26 -18
- package/docs/src/docs/_misc/api-configuration.md +79 -0
- package/docs/src/docs/_misc/dataProviderKey.md +38 -5
- package/docs/src/docs/_misc/docs-mock-api.md +60 -0
- package/docs/src/docs/_misc/endpoint.md +2 -1
- package/docs/src/docs/_misc/html-integration.md +13 -0
- package/docs/src/docs/search/docs-search.json +4163 -873
- package/docs/src/tsconfig.json +380 -317
- package/gitlab/job_tests.sh +55 -0
- package/package.json +37 -3
- package/public/altcha-widget.js +2662 -0
- package/public/docs-mock-api-sw.js +589 -0
- package/public/docs-mock-api-sw.js.map +7 -0
- package/scripts/ai-init.mjs +167 -0
- package/scripts/docs-mock-api-vite-plugin.ts +116 -0
- package/scripts/docs-open-in-editor-plugin.ts +130 -0
- package/scripts/pre-publish.mjs +2 -1
- package/src/core/components/functional/example/example.ts +1 -1
- package/src/core/components/functional/fetch/fetch.md +13 -11
- package/src/core/components/functional/if/if.md +4 -11
- package/src/core/components/functional/list/list.demo.ts +4 -4
- package/src/core/components/functional/list/list.md +60 -194
- package/src/core/components/functional/list/list.ts +8 -7
- package/src/core/components/functional/queue/queue.demo.ts +1 -1
- package/src/core/components/functional/queue/queue.md +70 -85
- package/src/core/components/functional/queue/queue.ts +4 -4
- package/src/core/components/functional/router/router.md +62 -97
- package/src/core/components/functional/router/router.ts +1 -1
- package/src/core/components/functional/states/states.md +2 -2
- package/src/core/components/functional/submit/submit.md +86 -55
- package/src/core/components/functional/submit/submit.ts +10 -3
- package/src/core/components/ui/captcha/captcha.md +2 -2
- package/src/core/components/ui/card/card.md +1 -1
- package/src/core/components/ui/form/checkbox/checkbox.md +5 -32
- package/src/core/components/ui/form/input/input.md +5 -30
- package/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +6 -4
- package/src/core/components/ui/form/radio/radio.md +5 -32
- package/src/core/components/ui/form/select/select.md +5 -31
- package/src/core/components/ui/form/switch/switch.md +5 -32
- package/src/core/components/ui/loader/loader.md +1 -13
- package/src/core/components/ui/table/table.md +3 -3
- package/src/core/decorators/Subscriber.ts +2 -0
- package/src/core/decorators/subscriber/handle.disambig.spec.ts +20 -0
- package/src/core/decorators/subscriber/handle.skip.spec.ts +37 -0
- package/src/core/decorators/subscriber/handle.ts +128 -0
- package/src/core/decorators/subscriber/onAssign.ts +94 -4
- package/src/core/directives/DataProvider.sub.spec.ts +96 -0
- package/src/core/directives/DataProvider.ts +109 -40
- package/src/core/utils/PublisherProxy.ts +33 -18
- package/src/core/utils/dataProviderKey.ts +23 -0
- package/src/core/utils/publisherPathKey.spec.ts +58 -0
- package/src/decorators.ts +6 -0
- package/src/docs/_core-concept/dataFlow.md +73 -0
- package/src/docs/_core-concept/subscriber.md +9 -10
- package/src/docs/_decorators/ancestor-attribute.md +4 -3
- package/src/docs/_decorators/auto-subscribe.md +19 -16
- package/src/docs/_decorators/bind.md +20 -17
- package/src/docs/_decorators/get.md +7 -4
- package/src/docs/_decorators/handle.md +171 -0
- package/src/docs/_decorators/on-assign.md +99 -47
- package/src/docs/_decorators/publish.md +2 -1
- package/src/docs/_decorators/subscribe.md +70 -9
- package/src/docs/_decorators/wait-for-ancestors.md +13 -10
- package/src/docs/_directives/sub.md +91 -0
- package/src/docs/_getting-started/ai-agents.md +56 -0
- package/src/docs/_getting-started/concorde-manual-install.md +133 -0
- package/src/docs/_getting-started/concorde-outside.md +13 -123
- package/src/docs/_getting-started/create-a-component.md +2 -0
- package/src/docs/_getting-started/my-first-component.md +236 -0
- package/src/docs/_getting-started/my-first-subscriber.md +29 -83
- package/src/docs/_getting-started/pubsub.md +21 -134
- package/src/docs/_getting-started/start.md +26 -18
- package/src/docs/_misc/api-configuration.md +79 -0
- package/src/docs/_misc/dataProviderKey.md +38 -5
- package/src/docs/_misc/docs-mock-api.md +60 -0
- package/src/docs/_misc/endpoint.md +2 -1
- package/src/docs/_misc/html-integration.md +13 -0
- package/src/docs/code.ts +58 -12
- package/src/docs/components/docs-demo-sources.ts +397 -0
- package/src/docs/components/docs-lit-demo-raw.ts +28 -0
- package/src/docs/components/docs-lit-demo.ts +166 -0
- package/src/docs/components/docs-source-link.ts +72 -0
- package/src/docs/docs-location.ts +54 -0
- package/src/docs/docs.ts +12 -0
- package/src/docs/example/decorators-demo-bind-demos.ts +41 -46
- package/src/docs/example/decorators-demo-geo.ts +16 -11
- package/src/docs/example/decorators-demo-init.ts +2 -228
- package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +142 -12
- package/src/docs/example/decorators-demo.ts +71 -70
- package/src/docs/example/docs-api-config-demos.ts +234 -0
- package/src/docs/example/docs-joke-demos.ts +297 -0
- package/src/docs/example/docs-list-demos.ts +179 -0
- package/src/docs/example/docs-provider-keys.ts +315 -0
- package/src/docs/example/docs-queue-demos.ts +114 -0
- package/src/docs/example/docs-router-demos.ts +89 -0
- package/src/docs/example/docs-submit-demos.ts +455 -0
- package/src/docs/example/docs-toggle-demos.ts +73 -0
- package/src/docs/example/docs-user-two-scopes.ts +37 -0
- package/src/docs/example/docs-users-list.ts +71 -0
- package/src/docs/example/users.ts +41 -24
- package/src/docs/mock-api/api-config-mock.ts +152 -0
- package/src/docs/mock-api/fixtures.ts +377 -0
- package/src/docs/mock-api/register.ts +25 -0
- package/src/docs/mock-api/router.ts +234 -0
- package/src/docs/mock-api/service-worker.ts +23 -0
- package/src/docs/mock-api/urls.ts +11 -0
- package/src/docs/navigation/navigation.ts +43 -7
- package/src/docs/search/docs-search.json +4193 -858
- package/src/docs/search/markdown-renderer.ts +7 -3
- package/src/docs/search/page.ts +11 -14
- package/src/docs/search/sonic-code-markdown.spec.ts +29 -0
- package/src/docs/search/sonic-code-markdown.ts +28 -0
- package/src/docs.ts +4 -0
- package/src/tsconfig.json +96 -0
- package/src/tsconfig.tsbuildinfo +1 -1
- package/vite.config.mts +8 -0
- package/docs/assets/index-CaysOMFz.js +0 -5046
- package/docs/assets/index-D8mGoXzF.css +0 -1
- package/docs/src/docs/_misc/templates-demo.md +0 -19
- package/src/docs/_misc/templates-demo.md +0 -19
|
@@ -1,199 +1,65 @@
|
|
|
1
1
|
# List
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{"id":"4", "tpl":"custom-tpl-danger"},
|
|
61
|
-
{"id":"5", "tpl":"custom-tpl-info"},
|
|
62
|
-
{"id":"6", "tpl":"custom-tpl-success"},
|
|
63
|
-
{"id":"7", "tpl": "Non-valid tpl name, Back to the first template with no data-value"}
|
|
64
|
-
]'
|
|
65
|
-
debug
|
|
66
|
-
>
|
|
67
|
-
<template>
|
|
68
|
-
<div class="p-2 border rounded text-neutral-900">
|
|
69
|
-
<sonic-value key="id"> : </sonic-value>
|
|
70
|
-
<b>First</b> template with no <b>data-value</b> attribute
|
|
71
|
-
</div>
|
|
72
|
-
</template>
|
|
73
|
-
<template data-value="custom-tpl-danger">
|
|
74
|
-
<div class="p-2 border rounded text-danger">
|
|
75
|
-
<sonic-value key="id"> : </sonic-value>
|
|
76
|
-
data-value : <b>custom-tpl-danger</b>
|
|
77
|
-
</div>
|
|
78
|
-
</template>
|
|
79
|
-
<template data-value="custom-tpl-info">
|
|
80
|
-
<div class="p-2 border rounded text-info">
|
|
81
|
-
<sonic-value key="id"> : </sonic-value>
|
|
82
|
-
data-value : <b>custom-tpl-info</b>
|
|
83
|
-
</div>
|
|
84
|
-
</template>
|
|
85
|
-
<template data-value="custom-tpl-success">
|
|
86
|
-
<div class="p-2 border rounded text-success">
|
|
87
|
-
<sonic-value key="id"> : </sonic-value>
|
|
88
|
-
data-value : <b>custom-tpl-success</b>
|
|
89
|
-
</div>
|
|
90
|
-
</template>
|
|
91
|
-
<template>
|
|
92
|
-
<div class="p-2 border rounded text-neutral-400">
|
|
93
|
-
<sonic-value key="id"> : </sonic-value>
|
|
94
|
-
<b>Second</b> template with no <b>data-value</b> attribute <br>
|
|
95
|
-
This one is used if it <b>follows another data-item</b> with <b>no tpl</b> specified in the props
|
|
96
|
-
</div>
|
|
97
|
-
</template>
|
|
98
|
-
</sonic-list>
|
|
99
|
-
</template>
|
|
100
|
-
</sonic-code>
|
|
101
|
-
|
|
102
|
-
## Special templates : list item separator / empty list view
|
|
103
|
-
|
|
104
|
-
A special template with attribute **data-value="separator"** will act as a separator between each list item
|
|
105
|
-
|
|
106
|
-
<sonic-code>
|
|
107
|
-
<template>
|
|
108
|
-
<sonic-list props='[{"id":"1"},{"id":"2"},{"id":"3"}]' dataProvider="ListSeparatorDemo">
|
|
109
|
-
<template><sonic-value key="id"></sonic-value></template>
|
|
110
|
-
<template data-value="separator"> 🤜 </template>
|
|
111
|
-
</sonic-list>
|
|
112
|
-
</template>
|
|
113
|
-
</sonic-code>
|
|
114
|
-
|
|
115
|
-
The same principle can be used to handle empty lists using a template with attribute **data-value="no-item"**
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
## Fetch
|
|
119
|
-
|
|
120
|
-
Enables the list to get data from an external API in order to fill its **props** attribute with an **array of items**
|
|
121
|
-
See the [Fetch] web component(#core/components/functional/fetch/fetch.md/fetch)
|
|
122
|
-
<sonic-code>
|
|
123
|
-
<template>
|
|
124
|
-
<sonic-list
|
|
125
|
-
props='["a", "b", "c"]' fetch
|
|
126
|
-
serviceURL="https://reqres.in"
|
|
127
|
-
dataProvider="api/users"
|
|
128
|
-
key="data"
|
|
129
|
-
class="grid grid-cols-1" debug>
|
|
130
|
-
<template>
|
|
131
|
-
<docs-user></docs-user>
|
|
132
|
-
</template>
|
|
133
|
-
</sonic-list>
|
|
134
|
-
</template>
|
|
135
|
-
</sonic-code>
|
|
136
|
-
|
|
137
|
-
## Extract Values
|
|
138
|
-
|
|
139
|
-
Example of using the `extractValues` attribute with a service.
|
|
140
|
-
As in the previous example, the `fetch` attribute indicates that a service call should be made.
|
|
141
|
-
Note that we use:
|
|
142
|
-
* the property `_metadata_` added by the list component to display the key of the extracted value
|
|
143
|
-
* the special property `_self_` that allows targeting the item itself. This is useful here because there is no sub-property; we are directly dealing with a string.
|
|
144
|
-
<sonic-code>
|
|
145
|
-
<template>
|
|
146
|
-
<sonic-list
|
|
147
|
-
debug
|
|
148
|
-
fetch
|
|
149
|
-
serviceURL="https://reqres.in"
|
|
150
|
-
dataProvider="list-extract-values-test"
|
|
151
|
-
endPoint="api/users/2"
|
|
152
|
-
key="data"
|
|
153
|
-
extractValues
|
|
154
|
-
>
|
|
155
|
-
<template>
|
|
156
|
-
<div class="flex items-center">
|
|
157
|
-
<span data-bind ::inner-html="$_metadata_.key : " class="bold w-24"></span>
|
|
158
|
-
<span data-bind ::inner-html="$_self_"></span>
|
|
159
|
-
<sonic-if data-bind ::condition="|'$_metadata_.key' == 'avatar'">
|
|
160
|
-
<sonic-image data-bind ::src="$_self_" rounded="full" ratio="1/1" class="w-20 block"></sonic-image>
|
|
161
|
-
</sonic-if>
|
|
162
|
-
</div>
|
|
163
|
-
</template>
|
|
164
|
-
</sonic-list>
|
|
165
|
-
</template>
|
|
166
|
-
</sonic-code>
|
|
3
|
+
> **Try offline:** `serviceURL="/docs-mock-api"` and `dataProvider="api/users"` with `key="data"` — see [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api). Recommended patterns: [Data flow](#docs/_core-concept/dataFlow.md/dataFlow).
|
|
4
|
+
|
|
5
|
+
The **sonic-list** component renders one row per entry in **`props`** (array from fetch or set on the element).
|
|
6
|
+
|
|
7
|
+
List extends [Subscriber](#docs/_core-concept/subscriber.md/subscriber) and **Fetcher**:
|
|
8
|
+
* **Subscriber** — `props` + `dataProvider`
|
|
9
|
+
* **Fetcher** — optional `fetch` + `serviceURL` / `key` (see [Fetch](#core/components/functional/fetch/fetch.md/fetch))
|
|
10
|
+
|
|
11
|
+
## Row renderer (`items`) — recommended
|
|
12
|
+
|
|
13
|
+
From a **Lit** parent, pass a function on the **`items`** property (`ListItems`). Each row is wrapped in a `sonic-subscriber` with `dataProvider="…/list-item/n"` (hover rows with `debug`).
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
private items = ({ first_name, last_name, email, avatar }) => html`
|
|
17
|
+
<sonic-image src=${avatar} …></sonic-image>
|
|
18
|
+
<div>${first_name} <b>${last_name}</b></div>
|
|
19
|
+
<div>${email}</div>
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
html`<sonic-list
|
|
23
|
+
fetch
|
|
24
|
+
dataProvider="api/users"
|
|
25
|
+
key="data"
|
|
26
|
+
serviceURL="/docs-mock-api"
|
|
27
|
+
.items=${this.items}
|
|
28
|
+
></sonic-list>`;
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Use **`.items=${fn}`** (property binding): Lit passes functions only as properties, not as HTML attributes — `@property({ type: Function })` does not change that. Same for **`.noItems`**, **`.separator`**, **`.skeleton`**. The callback receives each row object (replacing `data-bind` / `<sonic-value>` in a `<template>`).
|
|
32
|
+
|
|
33
|
+
Live demo + TypeScript source (one file, no Markdown copy):
|
|
34
|
+
|
|
35
|
+
<docs-lit-demo for="docs-users-list"></docs-lit-demo>
|
|
36
|
+
|
|
37
|
+
Implementation: `src/docs/example/docs-users-list.ts` — row markup in the **`items`** callback (`item.first_name`, …), same idea as replacing `data-bind` / `<sonic-value>` in a `<template>`.
|
|
38
|
+
|
|
39
|
+
## Alternating row layouts
|
|
40
|
+
|
|
41
|
+
Use **`metadata`** (`even`, `odd`, `firstChild`, …) or fields on each item (e.g. `tpl` with `templateKey`):
|
|
42
|
+
|
|
43
|
+
<docs-lit-demo for="docs-list-alternate-demo"></docs-lit-demo>
|
|
44
|
+
|
|
45
|
+
<docs-lit-demo for="docs-list-template-key-demo"></docs-lit-demo>
|
|
46
|
+
|
|
47
|
+
## Separator and empty list
|
|
48
|
+
|
|
49
|
+
<docs-lit-demo for="docs-list-separator-demo"></docs-lit-demo>
|
|
50
|
+
|
|
51
|
+
## Fetch + `extractValues`
|
|
52
|
+
|
|
53
|
+
<docs-lit-demo for="docs-list-extract-values-demo"></docs-lit-demo>
|
|
54
|
+
|
|
55
|
+
## HTML `<template>` children (integration without Lit)
|
|
56
|
+
|
|
57
|
+
For **plain HTML** hosts, you can still declare **`<template>`** children (and `data-value` for `templateKey`, `separator`, `no-item`). That path is for [HTML integration](#docs/_misc/html-integration.md/html-integration) — not used in Concorde doc live demos.
|
|
58
|
+
|
|
59
|
+
Each list row still gets `dataProvider="[list]/list-item/[index]"`.
|
|
167
60
|
|
|
168
61
|
## Additionnal tips
|
|
169
62
|
|
|
170
|
-
* If the
|
|
171
|
-
*
|
|
172
|
-
* Each
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
<!--
|
|
177
|
-
## FormDataProvider
|
|
178
|
-
|
|
179
|
-
<sonic-alert status="error" background>À déplacer dans la bonne doc</sonic-alert>
|
|
180
|
-
|
|
181
|
-
<sonic-code>
|
|
182
|
-
<template>
|
|
183
|
-
<div formDataProvider="profileInfos">
|
|
184
|
-
<form>
|
|
185
|
-
<sonic-fieldset label="Edit profile">
|
|
186
|
-
<sonic-form-layout>
|
|
187
|
-
<sonic-input label="First name" type="text" name="first_name" value="Sponge" size="sm"></sonic-input>
|
|
188
|
-
<sonic-input label="Last name" type="text" name="last_name" value="Bob" size="sm"></sonic-input>
|
|
189
|
-
<sonic-input label="email" type="email" name="email" value="bob@krustykrab.com" size="sm"></sonic-input>
|
|
190
|
-
<sonic-input label="Image url" type="text" name="avatar" value="http://www.bobleponge.fr/goodies/avatars/avatar-bob-eponge_Bob-Eponge-coiffure.jpg" size="sm"></sonic-input>
|
|
191
|
-
</sonic-form-layout>
|
|
192
|
-
</sonic-fieldset>
|
|
193
|
-
</form>
|
|
194
|
-
</div>
|
|
195
|
-
<sonic-card dataProvider="profileInfos">
|
|
196
|
-
<docs-user ></docs-user>
|
|
197
|
-
</sonic-card>
|
|
198
|
-
</template>
|
|
199
|
-
</sonic-code> -->
|
|
63
|
+
* If the request returns an object, it is wrapped in an array (unless `extractValues` is set).
|
|
64
|
+
* Call **`invalidate()`** on the list publisher to reload fetch data.
|
|
65
|
+
* Each row publisher exposes **`_parent_`** pointing at the list publisher.
|
|
@@ -21,7 +21,7 @@ const tagName = "sonic-list";
|
|
|
21
21
|
* Voir [fetcher](./?path=/docs/core-components-functional-fetch--basic) pour la configuration des autres attributs.
|
|
22
22
|
* * Chaque élément créé est englobé dans un objet [Subscriber](./?path=/docs/miscallenous-🔔-subscriber--page).<br>
|
|
23
23
|
* Un dataProvider y est associé a l'adresse suivante *dataProvider-de-la-liste$/*index-de-la-ligne-courante*
|
|
24
|
-
* Les données de la ligne sont donc disponible pour les élements internes (subscribers
|
|
24
|
+
* Les données de la ligne sont donc disponible pour les élements internes (subscribers)
|
|
25
25
|
* * Lors du chargement un objet loader inline est affiché.
|
|
26
26
|
* * Si le résultat de la requête est un objet, il est imbriqué dans un tableau pour garantir le fonctionnement.<br>
|
|
27
27
|
* Cependant, si l'attribut `extractValues` est présent, les valeurs des propriétés de l'objet sont mises dans dans un tableau pour le rendu.
|
|
@@ -48,7 +48,7 @@ export type ListItemMetadata = {
|
|
|
48
48
|
// Simplifier le type ListItems pour n'être qu'une fonction
|
|
49
49
|
export type ListItems = (
|
|
50
50
|
item: any,
|
|
51
|
-
metadata: ListItemMetadata
|
|
51
|
+
metadata: ListItemMetadata,
|
|
52
52
|
) => DirectiveResult;
|
|
53
53
|
|
|
54
54
|
@customElement(tagName)
|
|
@@ -73,6 +73,7 @@ export class List extends Fetcher(Subscriber(TemplatesContainer(LitElement))) {
|
|
|
73
73
|
|
|
74
74
|
@property({
|
|
75
75
|
type: Function,
|
|
76
|
+
attribute: false,
|
|
76
77
|
}) /**add a getter setter check if the value is a ListItems befor assignation */
|
|
77
78
|
get items(): ListItems | undefined {
|
|
78
79
|
return this._items;
|
|
@@ -83,9 +84,9 @@ export class List extends Fetcher(Subscriber(TemplatesContainer(LitElement))) {
|
|
|
83
84
|
this.requestUpdate();
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
@property({ type: Function }) noItems?: () => DirectiveResult;
|
|
87
|
-
@property({ type: Function }) skeleton?: () => DirectiveResult;
|
|
88
|
-
@property({ type: Function }) separator?: () => DirectiveResult;
|
|
87
|
+
@property({ type: Function, attribute: false }) noItems?: () => DirectiveResult;
|
|
88
|
+
@property({ type: Function, attribute: false }) skeleton?: () => DirectiveResult;
|
|
89
|
+
@property({ type: Function, attribute: false }) separator?: () => DirectiveResult;
|
|
89
90
|
|
|
90
91
|
connectedCallback() {
|
|
91
92
|
this.noShadowDom = "";
|
|
@@ -245,7 +246,7 @@ export class List extends Fetcher(Subscriber(TemplatesContainer(LitElement))) {
|
|
|
245
246
|
private handleProgrammaticTemplates(
|
|
246
247
|
item: any,
|
|
247
248
|
metadata: ListItemMetadata,
|
|
248
|
-
key: string | number
|
|
249
|
+
key: string | number,
|
|
249
250
|
): DirectiveResult | null {
|
|
250
251
|
if (!this.items) return null;
|
|
251
252
|
|
|
@@ -347,7 +348,7 @@ export class List extends Fetcher(Subscriber(TemplatesContainer(LitElement))) {
|
|
|
347
348
|
const programmaticTemplate = this.handleProgrammaticTemplates(
|
|
348
349
|
item,
|
|
349
350
|
metadata,
|
|
350
|
-
key
|
|
351
|
+
key,
|
|
351
352
|
);
|
|
352
353
|
if (programmaticTemplate) {
|
|
353
354
|
return html`${programmaticTemplate}${!isLastChild
|
|
@@ -24,7 +24,7 @@ export class QueueDemo extends LitElement {
|
|
|
24
24
|
return html`
|
|
25
25
|
<sonic-queue
|
|
26
26
|
class="grid grid-cols-3 gap-3"
|
|
27
|
-
serviceurl="
|
|
27
|
+
serviceurl="/docs-mock-api/geo/"
|
|
28
28
|
dataproviderexpression="communes?limit=$limit"
|
|
29
29
|
limit="30"
|
|
30
30
|
.items=${this.items}
|
|
@@ -1,87 +1,72 @@
|
|
|
1
1
|
# Queue
|
|
2
2
|
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
<div class="flex px-4 py-3 items-center gap-4">
|
|
74
|
-
<sonic-image data-bind ::src="$avatar" rounded="full" ratio="1/1" class="w-20 block"></sonic-image>
|
|
75
|
-
<div>
|
|
76
|
-
<div class="text-bold text-2xl mb-2">
|
|
77
|
-
<span data-bind ::inner-html="$first_name"></span>
|
|
78
|
-
<span data-bind ::inner-html="$last_name"></span>
|
|
79
|
-
</div>
|
|
80
|
-
<sonic-button data-bind ::href="mailto|$email" size="xs" variant="outline"> Contact </sonic-button>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
<div class="border-0 border-t-2 border-t-neutral-200 w-full border-solid"></div>
|
|
84
|
-
</template>
|
|
85
|
-
</sonic-list>
|
|
86
|
-
</template>
|
|
87
|
-
</sonic-code>
|
|
3
|
+
> **Try offline:** `serviceURL="/docs-mock-api"` — see [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api). Row rendering: [Data flow](#docs/_core-concept/dataFlow.md/dataFlow) (`.items` property binding).
|
|
4
|
+
|
|
5
|
+
**sonic-queue** loads data in **batches**. Each batch is an internal [List](#core/components/functional/list/list.md/list) with its own `dataProvider` (`…/list-item/0`, `…/1`, …).
|
|
6
|
+
|
|
7
|
+
| Mechanism | Role |
|
|
8
|
+
|-----------|------|
|
|
9
|
+
| **`dataProviderExpression`** | API path template; `$offset` and `$limit` are replaced per batch |
|
|
10
|
+
| **`lazyload`** | Load the next batch when the user scrolls near the end |
|
|
11
|
+
| **`dataFilterProvider`** | Publisher id of a form (`formDataProvider`); field values are merged into the request query string |
|
|
12
|
+
| **`filteredFields`** | Optional list of form field names to **exclude** from the query (space-separated) — omit when every field should be sent |
|
|
13
|
+
| **`.items`**, **`.noItems`**, **`.separator`**, **`.skeleton`** | Lit callbacks forwarded to each batch list (use the **dot** — functions are properties, not attributes) |
|
|
14
|
+
|
|
15
|
+
## Lazy load — `$offset` and `$limit`
|
|
16
|
+
|
|
17
|
+
When the expression contains **`$offset`** and **`$limit`**, the queue:
|
|
18
|
+
|
|
19
|
+
1. Fetches the first batch with `offset=0` (or the initial `offset` attribute) and `per_page=$limit`.
|
|
20
|
+
2. On scroll, appends a batch with `offset` increased by the previous batch size.
|
|
21
|
+
3. Stops when a batch returns fewer rows than `limit` (or none).
|
|
22
|
+
|
|
23
|
+
The doc mock implements this on `GET /docs-mock-api/api/users?offset=…&per_page=…` (`paginateUsers` in `src/docs/mock-api/router.ts`).
|
|
24
|
+
|
|
25
|
+
<docs-lit-demo for="docs-queue-users-demo"></docs-lit-demo>
|
|
26
|
+
|
|
27
|
+
Wrap the queue in a **fixed height** with **`overflow-y-auto`** so lazy load triggers when scrolling inside the box (same layout as the [TS starter](https://github.com/supersoniks/create-concorde-ts-starter) `demo-queue-templates`).
|
|
28
|
+
|
|
29
|
+
Try scrolling after load — batches of 4 users. Search e.g. `George`, `Bluth`, or `zzz` for empty results.
|
|
30
|
+
|
|
31
|
+
### Expression example
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
html`<sonic-queue
|
|
35
|
+
lazyload
|
|
36
|
+
serviceURL="/docs-mock-api"
|
|
37
|
+
dataProviderExpression="api/users?offset=$offset&limit=$limit"
|
|
38
|
+
key="data"
|
|
39
|
+
limit="4"
|
|
40
|
+
class="grid max-h-96 overflow-y-auto"
|
|
41
|
+
.items=${this.renderUser}
|
|
42
|
+
></sonic-queue>`;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Without **`$offset`** in the expression, the queue behaves like a single list (one batch), e.g. geo communes below.
|
|
46
|
+
|
|
47
|
+
## Filter — `dataFilterProvider` + `q`
|
|
48
|
+
|
|
49
|
+
One search field (`name="q"`) on `formDataProvider="filter"`. The queue listens via **`dataFilterProvider="filter"`** and, on change:
|
|
50
|
+
|
|
51
|
+
1. Resets loaded batches.
|
|
52
|
+
2. Appends each non-empty form field to the query (here only **`q`** — no `filteredFields` needed).
|
|
53
|
+
3. Fetches again from offset `0`.
|
|
54
|
+
|
|
55
|
+
Use **`filteredFields`** only when the form has extra fields that must **not** be sent to the API (e.g. `filteredFields="rememberMe internalId"`).
|
|
56
|
+
|
|
57
|
+
The mock API filters before pagination — same haystack logic as the starter (`filterDocsUsers` in `src/docs/mock-api/fixtures.ts`, used by `paginateUsers` in `router.ts` / Service Worker):
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const haystack = `${first_name} ${last_name} ${email}`.toLowerCase();
|
|
61
|
+
return haystack.includes(q);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Simple batch (no lazy scroll)
|
|
65
|
+
|
|
66
|
+
Geo communes: expression uses **`$limit` only** (no `$offset`) — one request, one batch.
|
|
67
|
+
|
|
68
|
+
<docs-lit-demo for="docs-queue-geo-demo"></docs-lit-demo>
|
|
69
|
+
|
|
70
|
+
## HTML `<template>` children
|
|
71
|
+
|
|
72
|
+
Optional for hosts without Lit — see [HTML integration](#docs/_misc/html-integration.md/html-integration).
|
|
@@ -32,9 +32,9 @@ const tagName = "sonic-queue";
|
|
|
32
32
|
export default class Queue extends Subscriber(LitElement, {} as QueueProps) {
|
|
33
33
|
@property({ type: Array }) templates: Array<HTMLTemplateElement> | null =
|
|
34
34
|
null;
|
|
35
|
-
@property({ type: Function }) items: ListItems | null = null;
|
|
36
|
-
@property({ type: Function }) noItems: ListItems | null = null;
|
|
37
|
-
@property({ type: Function }) skeleton: ListItems | null = null;
|
|
35
|
+
@property({ type: Function, attribute: false }) items: ListItems | null = null;
|
|
36
|
+
@property({ type: Function, attribute: false }) noItems: ListItems | null = null;
|
|
37
|
+
@property({ type: Function, attribute: false }) skeleton: ListItems | null = null;
|
|
38
38
|
lastRequestTime = 0;
|
|
39
39
|
key = "";
|
|
40
40
|
|
|
@@ -151,7 +151,7 @@ export default class Queue extends Subscriber(LitElement, {} as QueueProps) {
|
|
|
151
151
|
if (Array.isArray(value))
|
|
152
152
|
value = value.filter((v: string | null) => v !== null);
|
|
153
153
|
if (
|
|
154
|
-
(this.filteredFields &&
|
|
154
|
+
(this.filteredFields && filteredFieldsArray.includes(f)) ||
|
|
155
155
|
value == null ||
|
|
156
156
|
value.toString() === ""
|
|
157
157
|
)
|