@supersoniks/concorde 3.1.0 → 3.1.2
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/build-infos.json +1 -1
- package/concorde-core.bundle.js +227 -142
- package/concorde-core.es.js +831 -726
- package/dist/concorde-core.bundle.js +227 -142
- package/dist/concorde-core.es.js +831 -726
- package/dist/img/paul_metrand.jpg +0 -0
- package/dist/img/paul_metrand_xs.jpg +0 -0
- package/package.json +1 -1
- package/public/img/paul_metrand.jpg +0 -0
- package/public/img/paul_metrand_xs.jpg +0 -0
- package/src/core/_types/types.ts +1 -0
- package/src/core/components/functional/list/list.md +8 -3
- package/src/core/components/functional/submit/submit.ts +3 -2
- package/src/core/components/ui/_css/scroll.ts +3 -2
- package/src/core/components/ui/_css/size.ts +5 -1
- package/src/core/components/ui/form/checkbox/checkbox.ts +31 -21
- package/src/core/components/ui/form/input/input.ts +70 -36
- package/src/core/components/ui/form/input-autocomplete/input-autocomplete.ts +101 -35
- package/src/core/components/ui/form/select/select.ts +1 -0
- package/src/core/components/ui/form/textarea/textarea.md +2 -3
- package/src/core/components/ui/form/textarea/textarea.ts +51 -24
- package/src/core/components/ui/progress/progress.md +4 -6
- package/src/core/components/ui/progress/progress.ts +28 -13
- package/src/core/components/ui/table/table.md +15 -27
- package/src/core/components/ui/table/table.ts +26 -15
- package/src/core/components/ui/theme/theme-collection/core-variables.ts +20 -12
- package/src/core/components/ui/tooltip/tooltip.md +45 -0
- package/src/core/components/ui/tooltip/tooltip.ts +63 -18
- package/src/core/mixins/FormElement.ts +50 -24
- package/src/core/utils/PublisherProxy.ts +3 -2
- package/src/docs/_getting-started/my-first-subscriber.md +174 -0
- package/src/docs/_getting-started/start.md +2 -2
- package/src/docs/example/users.ts +43 -48
- package/src/docs/header/header.ts +217 -217
- package/src/docs/navigation/navigation.ts +2 -2
- package/src/docs/search/docs-search.json +139 -4
- package/src/docs/search/search.ts +6 -4
- package/docs/assets/index--bDsd7qW.css +0 -1
- package/docs/assets/index-Ce3mr_lI.js +0 -4040
- package/docs/css/docs.css +0 -0
- package/docs/img/concorde-logo.svg +0 -1
- package/docs/img/concorde.png +0 -0
- package/docs/img/concorde_def.png +0 -0
- package/docs/index.html +0 -132
- package/docs/src/core/components/functional/date/date.md +0 -290
- package/docs/src/core/components/functional/fetch/fetch.md +0 -117
- package/docs/src/core/components/functional/if/if.md +0 -16
- package/docs/src/core/components/functional/list/list.md +0 -194
- package/docs/src/core/components/functional/mix/mix.md +0 -41
- package/docs/src/core/components/functional/queue/queue.md +0 -87
- package/docs/src/core/components/functional/router/router.md +0 -112
- package/docs/src/core/components/functional/sdui/default-library.json +0 -108
- package/docs/src/core/components/functional/sdui/example.json +0 -99
- package/docs/src/core/components/functional/sdui/sdui.md +0 -356
- package/docs/src/core/components/functional/states/states.md +0 -87
- package/docs/src/core/components/functional/submit/submit.md +0 -48
- package/docs/src/core/components/functional/subscriber/subscriber.md +0 -91
- package/docs/src/core/components/functional/value/value.md +0 -35
- package/docs/src/core/components/ui/alert/alert.md +0 -121
- package/docs/src/core/components/ui/badge/badge.md +0 -102
- package/docs/src/core/components/ui/button/button.md +0 -184
- package/docs/src/core/components/ui/captcha/captcha.md +0 -12
- package/docs/src/core/components/ui/card/card.md +0 -96
- package/docs/src/core/components/ui/divider/divider.md +0 -35
- package/docs/src/core/components/ui/form/checkbox/checkbox.md +0 -96
- package/docs/src/core/components/ui/form/fieldset/fieldset.md +0 -129
- package/docs/src/core/components/ui/form/form-actions/form-actions.md +0 -77
- package/docs/src/core/components/ui/form/form-layout/form-layout.md +0 -43
- package/docs/src/core/components/ui/form/input/input.md +0 -168
- package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -130
- package/docs/src/core/components/ui/form/radio/radio.md +0 -86
- package/docs/src/core/components/ui/form/select/select.md +0 -99
- package/docs/src/core/components/ui/form/textarea/textarea.md +0 -66
- package/docs/src/core/components/ui/group/group.md +0 -75
- package/docs/src/core/components/ui/icon/icon.md +0 -125
- package/docs/src/core/components/ui/icon/icons.json +0 -1
- package/docs/src/core/components/ui/image/image.md +0 -107
- package/docs/src/core/components/ui/link/link.md +0 -43
- package/docs/src/core/components/ui/loader/loader.md +0 -37
- package/docs/src/core/components/ui/menu/menu.md +0 -288
- package/docs/src/core/components/ui/modal/modal.md +0 -123
- package/docs/src/core/components/ui/pop/pop.md +0 -79
- package/docs/src/core/components/ui/progress/progress.md +0 -65
- package/docs/src/core/components/ui/table/table.md +0 -467
- package/docs/src/core/components/ui/tooltip/tooltip.md +0 -37
- package/docs/src/docs/_core-concept/overview.md +0 -57
- package/docs/src/docs/_core-concept/subscriber.md +0 -76
- package/docs/src/docs/_getting-started/concorde-outside.md +0 -141
- package/docs/src/docs/_getting-started/create-a-component.md +0 -137
- package/docs/src/docs/_getting-started/pubsub.md +0 -150
- package/docs/src/docs/_getting-started/start.md +0 -37
- package/docs/src/docs/_getting-started/theming.md +0 -91
- package/docs/src/docs/search/docs-search.json +0 -3737
- package/docs/src/tag-list.json +0 -1
- package/docs/src/tsconfig.json +0 -113
- package/docs/svg/regular/plane.svg +0 -1
- package/docs/svg/solid/plane.svg +0 -1
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import {PublisherManager} from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
2
|
-
import {property} from "lit/decorators.js";
|
|
3
|
-
import {SubscriberInterface} from "@supersoniks/concorde/core/mixins/Subscriber";
|
|
1
|
+
import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
2
|
+
import { property } from "lit/decorators.js";
|
|
3
|
+
import { SubscriberInterface } from "@supersoniks/concorde/core/mixins/Subscriber";
|
|
4
4
|
import Objects from "@supersoniks/concorde/core/utils/Objects";
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import {
|
|
6
|
+
PublisherInterface,
|
|
7
|
+
HTMLFormControl,
|
|
8
|
+
CoreJSType,
|
|
9
|
+
} from "../_types/types";
|
|
10
|
+
import { MixinArgsType } from "../_types/types";
|
|
7
11
|
type Constructor<T> = new (...args: MixinArgsType[]) => T;
|
|
8
12
|
type FormElementValue = string | string[] | object | null | undefined;
|
|
9
13
|
export interface FormElementInterface extends SubscriberInterface {
|
|
@@ -42,16 +46,17 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
42
46
|
*
|
|
43
47
|
*/
|
|
44
48
|
class FormElement extends superClass implements FormElementInterface {
|
|
45
|
-
@property({type: Boolean, reflect: true}) touched = false;
|
|
46
|
-
@property({type: Boolean}) error = false;
|
|
47
|
-
@property({type: Boolean}) autofocus = false;
|
|
48
|
-
@property({type: Boolean}) required = false;
|
|
49
|
-
@property({type: Boolean}) forceAutoFill = false;
|
|
50
|
-
@property({type: Boolean}) disabled: true | null = null;
|
|
49
|
+
@property({ type: Boolean, reflect: true }) touched = false;
|
|
50
|
+
@property({ type: Boolean }) error = false;
|
|
51
|
+
@property({ type: Boolean }) autofocus = false;
|
|
52
|
+
@property({ type: Boolean }) required = false;
|
|
53
|
+
@property({ type: Boolean }) forceAutoFill = false;
|
|
54
|
+
@property({ type: Boolean }) disabled: true | null = null;
|
|
51
55
|
|
|
52
56
|
/* Attribut data-aria-label pour passer aria-label */
|
|
53
|
-
@property({type: String, attribute: "data-aria-label"})
|
|
54
|
-
|
|
57
|
+
@property({ type: String, attribute: "data-aria-label" })
|
|
58
|
+
ariaLabel?: string;
|
|
59
|
+
@property({ type: String, attribute: "data-aria-labelledby" })
|
|
55
60
|
ariaLabelledby?: string;
|
|
56
61
|
|
|
57
62
|
onValueAssign?: (v: string) => void;
|
|
@@ -84,7 +89,8 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
84
89
|
return this._name;
|
|
85
90
|
}
|
|
86
91
|
set name(value: string) {
|
|
87
|
-
if (this.hasAttribute("name") && !this.forceAutoFill)
|
|
92
|
+
if (this.hasAttribute("name") && !this.forceAutoFill)
|
|
93
|
+
value = this.getAttribute("name");
|
|
88
94
|
this._name = value;
|
|
89
95
|
this.requestUpdate();
|
|
90
96
|
}
|
|
@@ -103,7 +109,9 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
111
|
getFormPublisher() {
|
|
106
|
-
if (!this.formDataProvider)
|
|
112
|
+
if (!this.formDataProvider)
|
|
113
|
+
this.formDataProvider =
|
|
114
|
+
this.getAncestorAttributeValue("formDataProvider");
|
|
107
115
|
if (this.formDataProvider) {
|
|
108
116
|
return PublisherManager.get(this.formDataProvider);
|
|
109
117
|
}
|
|
@@ -145,7 +153,7 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
145
153
|
if (
|
|
146
154
|
Objects.isObject(value) &&
|
|
147
155
|
Object.prototype.hasOwnProperty.call(value, "__value") &&
|
|
148
|
-
(value as {_value?: CoreJSType})._value == undefined
|
|
156
|
+
(value as { _value?: CoreJSType })._value == undefined
|
|
149
157
|
)
|
|
150
158
|
value = "";
|
|
151
159
|
if (this._value == value) return;
|
|
@@ -156,11 +164,15 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
156
164
|
initPublisher() {
|
|
157
165
|
let formPublisher = this.getFormPublisher();
|
|
158
166
|
const value =
|
|
159
|
-
this.hasAncestorAttribute("initFromPublisher") &&
|
|
167
|
+
this.hasAncestorAttribute("initFromPublisher") &&
|
|
168
|
+
this._name &&
|
|
169
|
+
formPublisher[this._name].get()
|
|
160
170
|
? formPublisher[this._name].get()
|
|
161
171
|
: this.getAttribute("value");
|
|
162
|
-
if (this._name && this.publisher)
|
|
163
|
-
|
|
172
|
+
if (this._name && this.publisher)
|
|
173
|
+
this.publisher[this._name].offAssign(this.onValueAssign);
|
|
174
|
+
if (this._name && formPublisher)
|
|
175
|
+
formPublisher[this._name].offAssign(this.onFormValueAssign);
|
|
164
176
|
super.initPublisher();
|
|
165
177
|
if (!this.name) this._name = this.getAttribute("name");
|
|
166
178
|
if (!this.value) this._value = this.getAttribute("value");
|
|
@@ -194,7 +206,8 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
194
206
|
* En appuyant sur la touche "Up", le déplacement inverse est effectué.
|
|
195
207
|
*/
|
|
196
208
|
addKeyboardNavigation() {
|
|
197
|
-
const keyboardLoopIds: string =
|
|
209
|
+
const keyboardLoopIds: string =
|
|
210
|
+
this.getAncestorAttributeValue("data-keyboard-nav");
|
|
198
211
|
if (!keyboardLoopIds) return;
|
|
199
212
|
|
|
200
213
|
const split = keyboardLoopIds.split(" ");
|
|
@@ -214,7 +227,8 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
214
227
|
this.addEventListener("keydown", (e) => {
|
|
215
228
|
const keyboardEvent = e as KeyboardEvent;
|
|
216
229
|
if (!["ArrowDown", "ArrowUp"].includes(keyboardEvent.key)) return;
|
|
217
|
-
const selector =
|
|
230
|
+
const selector =
|
|
231
|
+
"input:not([disabled]), button:not([disabled]), select:not([disabled]), textarea:not([disabled])";
|
|
218
232
|
const loop = keyboardLoop?.filter((el) => {
|
|
219
233
|
const child = el.shadowRoot?.querySelector(selector);
|
|
220
234
|
if (!child) return false;
|
|
@@ -244,7 +258,9 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
244
258
|
next = loop[index - 1];
|
|
245
259
|
}
|
|
246
260
|
}
|
|
247
|
-
const elt = next?.shadowRoot?.querySelector(
|
|
261
|
+
const elt = next?.shadowRoot?.querySelector(
|
|
262
|
+
selector
|
|
263
|
+
) as FormElementInterface | null;
|
|
248
264
|
|
|
249
265
|
if (elt && elt.focus) {
|
|
250
266
|
elt.focus();
|
|
@@ -254,15 +270,25 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
254
270
|
});
|
|
255
271
|
}
|
|
256
272
|
|
|
273
|
+
focus() {
|
|
274
|
+
const inputElement = this.shadowRoot?.querySelector(
|
|
275
|
+
"[data-form-element]"
|
|
276
|
+
) as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
|
277
|
+
inputElement?.focus();
|
|
278
|
+
}
|
|
279
|
+
|
|
257
280
|
connectedCallback(): void {
|
|
258
|
-
this.formDataProvider = this.getAncestorAttributeValue(
|
|
281
|
+
this.formDataProvider = this.getAncestorAttributeValue(
|
|
282
|
+
"formDataProvider"
|
|
283
|
+
) as string;
|
|
259
284
|
super.connectedCallback();
|
|
260
285
|
this.addKeyboardNavigation();
|
|
261
286
|
}
|
|
262
287
|
|
|
263
288
|
disconnectedCallback() {
|
|
264
289
|
super.disconnectedCallback();
|
|
265
|
-
if (this._name && this.publisher)
|
|
290
|
+
if (this._name && this.publisher)
|
|
291
|
+
this.publisher[this._name].offAssign(this.onValueAssign);
|
|
266
292
|
const formPublisher = this.getFormPublisher();
|
|
267
293
|
if (this._name && formPublisher) {
|
|
268
294
|
formPublisher[this._name].offAssign(this.onFormValueAssign);
|
|
@@ -77,8 +77,9 @@ export class PublisherProxy<T = any> {
|
|
|
77
77
|
* Supprime les écouteurs associés
|
|
78
78
|
*/
|
|
79
79
|
delete() {
|
|
80
|
-
for (const
|
|
81
|
-
|
|
80
|
+
for (const key in this._proxies_.keys()) {
|
|
81
|
+
if ((key as string) == "_parent_") continue;
|
|
82
|
+
this._proxies_.get(key)?.delete();
|
|
82
83
|
}
|
|
83
84
|
this._invalidateListeners_.clear();
|
|
84
85
|
this._assignListeners_.clear();
|
|
@@ -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
|
|
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
|
-
*
|
|
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
|
-
@
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
}
|