@supersoniks/concorde 3.1.0 → 3.1.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.
@@ -0,0 +1,174 @@
1
+ # My first subscriber component
2
+
3
+ Learn how to build a subscriber component, styled with tailwind,
4
+ which could be used as a regular component or could be filled from a dataprovider.
5
+
6
+ ## Create a classic lit component
7
+
8
+ <sonic-code language="javascript" >
9
+ <template>
10
+ import { html, LitElement, nothing } from "lit";
11
+ import { customElement, property } from "lit/decorators.js";
12
+ // name component
13
+ @customElement("docs-user")
14
+ export class user extends LitElement {
15
+ // set a few props
16
+ @property({ type: String }) first_name = "";
17
+ @property({ type: String }) last_name = "";
18
+ @property({ type: String }) avatar = "";
19
+ @property({ type: String }) email = "";
20
+ // output
21
+ render() {
22
+ return html`
23
+ <img src="${this.avatar}" /> <br>
24
+ ${this.first_name} ${this.last_name} <br>
25
+ ${this.email}`;
26
+ }
27
+ }
28
+ </template>
29
+ </sonic-code>
30
+
31
+
32
+ ### Style with tailwind and ui components
33
+
34
+ First export tailwind, in a tailwind.ts file, stylesheet to add it in our component when needed.
35
+
36
+ <sonic-code language="javascript">
37
+ <template>
38
+ import { css, unsafeCSS } from "lit";
39
+ import tailwindImport from "./css/tailwind.css?inline";
40
+ export const tailwind = css`${unsafeCSS(tailwindImport)}`;
41
+ </template>
42
+ </sonic-code>
43
+
44
+ <sonic-code language="javascript">
45
+ <template>
46
+ import { html, LitElement, nothing } from "lit";
47
+ import { customElement, property } from "lit/decorators.js";
48
+ // add tailwind and needed components
49
+ import { tailwind } from "../tailwind";
50
+ import '@supersoniks/concode/ui/image'
51
+ import '@supersoniks/concode/ui/button'
52
+ import '@supersoniks/concode/ui/icon'
53
+ //
54
+ @customElement("docs-user")
55
+ export class user extends LitElement {
56
+ // add tailwind stylesheed
57
+ static styles = [tailwind];
58
+ @property({ type: String }) first_name = "";
59
+ @property({ type: String }) last_name = "";
60
+ @property({ type: String }) avatar = "";
61
+ @property({ type: String }) email = "";
62
+ // use utility class in your markup
63
+ render() {
64
+ return html`<div
65
+ class="flex items-center gap-3 rounded-md hover:bg-neutral-50 -mx-2 p-2"
66
+ >
67
+ <sonic-image
68
+ src=${this.avatar}
69
+ rounded="md"
70
+ ratio="1/1"
71
+ class="w-16 block"
72
+ ></sonic-image>
73
+ <div>
74
+ <div>
75
+ ${this.first_name} <span class="font-bold">${this.last_name}</span>
76
+ </div>
77
+ <div class="text-sm text-neutral-400">${this.email}</div>
78
+ </div>
79
+ <div class="ml-auto relative">
80
+ <sonic-button
81
+ href="mailto:${this.email}"
82
+ size="sm"
83
+ variant="outline"
84
+ shape="circle"
85
+ class="relative"
86
+ icon
87
+ >
88
+ <sonic-icon library="iconoir" name="chat-bubble"></sonic-icon>
89
+ </sonic-button>
90
+ </div>
91
+ </div>`;
92
+ }
93
+ }
94
+ </template>
95
+ </sonic-code>
96
+
97
+ ### Basic usage
98
+
99
+ Reactive properties can be filled by its attributes as a simple lit component.
100
+
101
+ <sonic-code>
102
+ <template>
103
+ <docs-user
104
+ first_name="Paul"
105
+ last_name="Metrand"
106
+ avatar="/img/paul_metrand_xs.jpg"
107
+ email="paulmetrand@concorde.fr"
108
+ ></docs-user>
109
+ </template>
110
+ </sonic-code>
111
+
112
+ ## Add Subscriber mixin
113
+
114
+ Import Subscriber mixin, and add it around LitElement.
115
+ <sonic-code language="javascript">
116
+ <template>
117
+ import { html, LitElement, nothing } from "lit";
118
+ import { customElement, property } from "lit/decorators.js";
119
+ import { tailwind } from "../tailwind";
120
+ import Subscriber from "@supersoniks/concorde/core/mixins/Subscriber";
121
+ @customElement("docs-user")
122
+ export class user extends Subscriber(LitElement) {
123
+ //...
124
+ }
125
+ </template>
126
+ </sonic-code>
127
+
128
+ ## Autofill properties from a dataProvider
129
+
130
+ Without a dataProvider attribute, a subscriber set its own dataprovider from first ancestor found, and then reactive properties automatically filled and update from it.
131
+ A fetcher is a simple component which set its fetch result to props of its dataprovider.
132
+ <sonic-code >
133
+ <template>
134
+ <sonic-fetch
135
+ serviceURL="https://reqres.in"
136
+ dataProvider="api/users/3"
137
+ key="data">
138
+ <docs-user></docs-user>
139
+ </sonic-fetch>
140
+ </template>
141
+ </sonic-code>
142
+
143
+ A subscriber can subscribe data from anywhere in the DOM, with its dataprovider set as a provider id.
144
+ <sonic-code >
145
+ <template>
146
+ <sonic-fetch
147
+ serviceURL="https://reqres.in"
148
+ dataProvider="api/users/2"
149
+ key="data"></sonic-fetch>
150
+ <docs-user dataProvider="api/users/2" ></docs-user>
151
+ <docs-user dataProvider="api/users/2" ></docs-user>
152
+ <docs-user dataProvider="api/users/2" ></docs-user>
153
+ </template>
154
+ </sonic-code>
155
+
156
+
157
+ <sonic-code >
158
+ <template>
159
+
160
+ <div class="grid grid-cols-1 gap-4">
161
+ <form formDataProvider="userPreview" class="grid grid-cols-4 gap-3" >
162
+ <sonic-input label="First name" type="text" name="first_name" placeholder="John" value="Paul"></sonic-input>
163
+ <sonic-input label="Last name" type="text" name="last_name" placeholder="Doe" value="Metrand"></sonic-input>
164
+ <sonic-input class="col-span-2" label="email" type="text" name="email" placeholder="johndoe@concorde.fr" value="paulmetrand@concorde.fr"></sonic-input>
165
+ <sonic-input type="file" name="avatar" value="/img/paul_metrand_xs.jpg"></sonic-input>
166
+ </form>
167
+ <sonic-divider align="left">Preview before submit</sonic-divider>
168
+ <docs-user dataProvider="userPreview" ></docs-user>
169
+ <sonic-button onClick="alert(JSON.stringify(SonicPublisherManager.get('userPreview').get()))">
170
+ Update data
171
+ </sonic-button>
172
+ </div>
173
+ </template>
174
+ </sonic-code>
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## What is Concorde ?
4
4
 
5
- Based on **[lit.dev](https://lit.dev)**, Concorde is a collection of webcomponents made to build shared components, between apps or websites.
5
+ Based on **[lit.dev](https://lit.dev)**, Concorde is a collection of webcomponents made to build shared apps or websites.
6
6
  Develop user interfaces without thinking about the implementation context, where everything is scoped, but preserving graphic consistency by setting the strict minimum of css variables.
7
7
 
8
8
  ## Why and use case
@@ -25,7 +25,7 @@ Webcomponents appeared to be a the perfect solution to guarantee that compatibil
25
25
  * Fetching data, lists, queue with lazyload
26
26
  * Data binding
27
27
  * Simple router, state component, ...
28
- * All ui component, with status variations to build an app with a consistent design
28
+ * And all ui component, with status variants to build an app with a consistent design
29
29
 
30
30
 
31
31
  ## Start a new project easily
@@ -1,64 +1,59 @@
1
- import { html, LitElement } from "lit";
1
+ import { html, LitElement, nothing } from "lit";
2
2
  import { customElement, property } from "lit/decorators.js";
3
- import Subscriber from "@supersoniks/concorde/core/mixins/Subscriber";
4
3
  import { tailwind } from "../tailwind";
5
4
 
6
- @customElement("docs-preview-user-item")
5
+ import Subscriber from "@supersoniks/concorde/core/mixins/Subscriber";
6
+
7
+ @customElement("docs-user")
7
8
  export class user extends Subscriber(LitElement) {
9
+ // add tailwind
8
10
  static styles = [tailwind];
9
11
 
12
+ @property({ type: String }) id = "";
10
13
  @property({ type: String }) avatar = "";
11
14
  @property({ type: String }) first_name = "";
12
15
  @property({ type: String }) email = "";
13
16
  @property({ type: String }) last_name = "";
14
- @property({ type: String }) id = "";
15
17
 
16
18
  render() {
17
- const inList = !!this.props?._metadata_;
18
- const isfirst = this.props?._metadata_?.firstChild;
19
- return html` ${!isfirst && inList
20
- ? html`<div class="border-t my-1 border-neutral-100"></div>`
21
- : ""}
22
- <div
23
- class="flex items-center gap-3 rounded-md hover:bg-neutral-100 -mx-2 p-2"
24
- >
25
- <sonic-image
26
- data-bind=""
27
- src=${this.avatar}
28
- rounded="md"
29
- ratio="1/1"
30
- class="w-16 block"
31
- ></sonic-image>
19
+ return html`<div
20
+ class="flex items-center gap-3 rounded-md hover:bg-neutral-50 -mx-2 p-2"
21
+ >
22
+ <sonic-image
23
+ src=${this.avatar}
24
+ rounded="md"
25
+ ratio="1/1"
26
+ class="w-16 block"
27
+ ></sonic-image>
28
+ <div>
32
29
  <div>
33
- <div class="text-bold">
34
- ${this.first_name} <span class="font-bold">${this.last_name}</span>
35
- </div>
36
- <div class="text-sm text-neutral-400">${this.email}</div>
37
- </div>
38
- <div class="ml-auto relative">
39
- ${this.id == "2" || this.id == "5"
40
- ? html`
41
- <sonic-badge
42
- type="danger"
43
- size="2xs"
44
- class="absolute left-0 -top-1 z-10"
45
- >
46
- ${this.id}</sonic-badge
47
- >
48
- `
49
- : ""}
50
- <sonic-button
51
- data-bind=""
52
- href="mailto:${this.email}"
53
- size="sm"
54
- variant="outline"
55
- shape="circle"
56
- class="relative"
57
- icon
58
- >
59
- <sonic-icon library="iconoir" name="chat-bubble"></sonic-icon>
60
- </sonic-button>
30
+ ${this.first_name} <span class="font-bold">${this.last_name}</span>
61
31
  </div>
62
- </div>`;
32
+ <div class="text-sm text-neutral-400">${this.email}</div>
33
+ </div>
34
+ <div class="ml-auto relative">
35
+ ${this.id == "2" || this.id == "5"
36
+ ? html`
37
+ <sonic-badge
38
+ type="danger"
39
+ size="2xs"
40
+ class="absolute left-0 -top-1 z-10"
41
+ >
42
+ ${this.id}</sonic-badge
43
+ >
44
+ `
45
+ : nothing}
46
+ <sonic-button
47
+ href="mailto:${this.email}"
48
+ size="sm"
49
+ variant="outline"
50
+ shape="circle"
51
+ class="relative"
52
+ icon
53
+ >
54
+ <sonic-icon library="iconoir" name="chat-bubble"></sonic-icon>
55
+ </sonic-button>
56
+ </div>
57
+ </div>`;
63
58
  }
64
59
  }
@@ -11,8 +11,8 @@ export class DocsNavigation extends LitElement {
11
11
  href: "#docs/_getting-started/concorde-outside.md/concorde-outside",
12
12
  },
13
13
  {
14
- label: "Creating components",
15
- href: "#docs/_getting-started/create-a-component.md/create-a-component",
14
+ label: "My first subscriber",
15
+ href: "#docs/_getting-started/my-first-subscriber.md/my-first-subscriber",
16
16
  },
17
17
  {
18
18
  label: "Adding styles",
@@ -2144,6 +2144,21 @@
2144
2144
  }
2145
2145
  }
2146
2146
  },
2147
+ {
2148
+ "search": "Displays an indicator showing the completion progress of a task.\n",
2149
+ "files": {
2150
+ "core/components/ui/progress/progress.md": {
2151
+ "title": "Progress bar",
2152
+ "hashes": {
2153
+ "progress-bar": {
2154
+ "count": 1,
2155
+ "title": "",
2156
+ "type": "paragraph"
2157
+ }
2158
+ }
2159
+ }
2160
+ }
2161
+ },
2147
2162
  {
2148
2163
  "search": "Table",
2149
2164
  "files": {
@@ -2190,14 +2205,14 @@
2190
2205
  }
2191
2206
  },
2192
2207
  {
2193
- "search": "A scroll bar is automatically added if the content if is wider than the table width\n",
2208
+ "search": "Every table is responsive by default\n",
2194
2209
  "files": {
2195
2210
  "core/components/ui/table/table.md": {
2196
2211
  "title": "Table",
2197
2212
  "hashes": {
2198
- "scroll-x": {
2213
+ "responsive": {
2199
2214
  "count": 1,
2200
- "title": "Scroll-x",
2215
+ "title": "Responsive",
2201
2216
  "type": "paragraph"
2202
2217
  }
2203
2218
  }
@@ -2219,6 +2234,21 @@
2219
2234
  }
2220
2235
  }
2221
2236
  },
2237
+ {
2238
+ "search": "By default, tooltip is centered next to its content\n",
2239
+ "files": {
2240
+ "core/components/ui/tooltip/tooltip.md": {
2241
+ "title": "Tooltip",
2242
+ "hashes": {
2243
+ "placement": {
2244
+ "count": 1,
2245
+ "title": "Placement",
2246
+ "type": "paragraph"
2247
+ }
2248
+ }
2249
+ }
2250
+ }
2251
+ },
2222
2252
  {
2223
2253
  "search": "lit + tailwind + vite",
2224
2254
  "files": {
@@ -3254,6 +3284,111 @@
3254
3284
  }
3255
3285
  }
3256
3286
  },
3287
+ {
3288
+ "search": "My first subscriber component",
3289
+ "files": {
3290
+ "docs/_getting-started/my-first-subscriber.md": {
3291
+ "title": "My first subscriber component",
3292
+ "hashes": {
3293
+ "my-first-subscriber-component": {
3294
+ "count": 1,
3295
+ "title": "",
3296
+ "type": "page"
3297
+ }
3298
+ }
3299
+ }
3300
+ }
3301
+ },
3302
+ {
3303
+ "search": "Learn how to build a subscriber component, styled with tailwind, \nwhich could be used as a regular component or could be filled from a dataprovider.\n",
3304
+ "files": {
3305
+ "docs/_getting-started/my-first-subscriber.md": {
3306
+ "title": "My first subscriber component",
3307
+ "hashes": {
3308
+ "my-first-subscriber-component": {
3309
+ "count": 1,
3310
+ "title": "",
3311
+ "type": "paragraph"
3312
+ }
3313
+ }
3314
+ }
3315
+ }
3316
+ },
3317
+ {
3318
+ "search": "First export tailwind, in a tailwind.ts file, stylesheet to add it in our component when needed.\n",
3319
+ "files": {
3320
+ "docs/_getting-started/my-first-subscriber.md": {
3321
+ "title": "My first subscriber component",
3322
+ "hashes": {
3323
+ "style-with-tailwind-and-ui-components": {
3324
+ "count": 1,
3325
+ "title": "Style with tailwind and ui components",
3326
+ "type": "paragraph"
3327
+ }
3328
+ }
3329
+ }
3330
+ }
3331
+ },
3332
+ {
3333
+ "search": "Reactive properties can be filled by its attributes as a simple lit component.\n",
3334
+ "files": {
3335
+ "docs/_getting-started/my-first-subscriber.md": {
3336
+ "title": "My first subscriber component",
3337
+ "hashes": {
3338
+ "basic-usage": {
3339
+ "count": 1,
3340
+ "title": "Basic usage",
3341
+ "type": "paragraph"
3342
+ }
3343
+ }
3344
+ }
3345
+ }
3346
+ },
3347
+ {
3348
+ "search": "Import Subscriber mixin, and add it around LitElement.\n\n",
3349
+ "files": {
3350
+ "docs/_getting-started/my-first-subscriber.md": {
3351
+ "title": "My first subscriber component",
3352
+ "hashes": {
3353
+ "add-subscriber-mixin": {
3354
+ "count": 1,
3355
+ "title": "Add Subscriber mixin",
3356
+ "type": "paragraph"
3357
+ }
3358
+ }
3359
+ }
3360
+ }
3361
+ },
3362
+ {
3363
+ "search": "Without a dataProvider attribute, a subscriber set its own dataprovider from first ancestor found, and then reactive properties automatically filled and update from it.\nA fetcher is a simple component which set its fetch result to props of its dataprovider.\n\n",
3364
+ "files": {
3365
+ "docs/_getting-started/my-first-subscriber.md": {
3366
+ "title": "My first subscriber component",
3367
+ "hashes": {
3368
+ "autofill-properties-from-a-dataprovider": {
3369
+ "count": 1,
3370
+ "title": "Autofill properties from a dataProvider",
3371
+ "type": "paragraph"
3372
+ }
3373
+ }
3374
+ }
3375
+ }
3376
+ },
3377
+ {
3378
+ "search": "A subscriber can subscribe data from anywhere in the DOM, with its dataprovider set as a provider id.\n",
3379
+ "files": {
3380
+ "docs/_getting-started/my-first-subscriber.md": {
3381
+ "title": "My first subscriber component",
3382
+ "hashes": {
3383
+ "autofill-properties-from-a-dataprovider": {
3384
+ "count": 1,
3385
+ "title": "Autofill properties from a dataProvider",
3386
+ "type": "paragraph"
3387
+ }
3388
+ }
3389
+ }
3390
+ }
3391
+ },
3257
3392
  {
3258
3393
  "search": "Sharing data",
3259
3394
  "files": {
@@ -3420,7 +3555,7 @@
3420
3555
  }
3421
3556
  },
3422
3557
  {
3423
- "search": "Based on lit.dev, Concorde is a collection of webcomponents made to build shared components, between apps or websites.Develop user interfaces without thinking about the implementation context, where everything is scoped, but preserving graphic consistency by setting the strict minimum of css variables.\n",
3558
+ "search": "Based on lit.dev, Concorde is a collection of webcomponents made to build shared apps or websites.Develop user interfaces without thinking about the implementation context, where everything is scoped, but preserving graphic consistency by setting the strict minimum of css variables.\n",
3424
3559
  "files": {
3425
3560
  "docs/_getting-started/start.md": {
3426
3561
  "title": "Introduction",
@@ -90,10 +90,12 @@ export class DocsSearch extends LitElement {
90
90
 
91
91
  firstUpdated() {
92
92
  if (this.setFocus) {
93
- const input = this.shadowRoot?.querySelector(
94
- "sonic-input"
95
- ) as FormElementInterface;
96
- input?.focus();
93
+ setTimeout(() => {
94
+ const input = this.shadowRoot?.querySelector(
95
+ "sonic-input"
96
+ ) as FormElementInterface;
97
+ input?.focus();
98
+ }, 100);
97
99
  }
98
100
  }
99
101