@supersoniks/concorde 3.3.2 → 4.0.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/build-infos.json +1 -1
- package/concorde-core.bundle.js +154 -154
- package/concorde-core.es.js +2366 -2356
- package/dist/concorde-core.bundle.js +154 -154
- package/dist/concorde-core.es.js +2366 -2356
- package/package.json +1 -4
- package/src/core/_types/types.ts +1 -1
- package/src/core/components/functional/queue/queue.ts +3 -4
- package/src/core/components/functional/states/states.demo.ts +5 -2
- package/src/core/components/functional/states/states.spec.ts +14 -13
- package/src/core/components/functional/submit/submit.ts +2 -2
- package/src/core/components/ui/captcha/captcha.ts +16 -12
- package/src/core/components/ui/form/input-autocomplete/input-autocomplete.ts +41 -7
- package/src/core/components/ui/pop/pop.ts +6 -6
- package/src/core/components/ui/theme/theme.ts +3 -3
- package/src/core/decorators/subscriber/bind.ts +2 -2
- package/src/core/decorators/subscriber/onAssign.ts +6 -4
- package/src/core/directives/DataProvider.ts +47 -60
- package/src/core/directives/Wording.ts +4 -4
- package/src/core/mixins/FormCheckable.ts +12 -12
- package/src/core/mixins/FormElement.ts +1 -1
- package/src/core/utils/PublisherProxy.ts +260 -178
- package/src/core/utils/Utils.ts +3 -0
- package/src/core/utils/api.ts +4 -6
- package/src/dataprovider.ts +1 -0
- package/src/directives.ts +27 -13
- package/src/docs/_misc/on-assign.md +5 -5
- package/src/docs/search/docs-search.json +70 -0
- package/src/tsconfig.json +0 -9
- package/src/tsconfig.tsbuildinfo +1 -1
- package/src/utils.ts +2 -4
- package/mcp-server/COMPARISON-MCP.md +0 -176
- package/mcp-server/README-MCP-NODEJS.md +0 -284
- package/mcp-server/README-MCP.md +0 -114
- package/mcp-server/README.md +0 -127
- package/mcp-server/TECHNICAL-DOCS.md +0 -269
- package/mcp-server/concorde-mcp-server.js +0 -859
- package/mcp-server/concorde-mcp-server.py +0 -801
- package/mcp-server/cursor-mcp-config-advanced.json +0 -68
- package/mcp-server/cursor-mcp-config-nodejs.json +0 -74
- package/mcp-server/cursor-mcp-config.json +0 -11
- package/mcp-server/install-mcp-nodejs.sh +0 -104
- package/mcp-server/install-mcp.sh +0 -62
- package/mcp-server/package-lock.json +0 -147
- package/mcp-server/package-mcp.json +0 -40
- package/mcp-server/package.json +0 -40
- package/mcp-server/test-mcp.js +0 -107
- package/mcp-server/test-mcp.py +0 -73
- package/src/core/components/ui/toast/message-subscriber.stories.ts +0 -43
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supersoniks/concorde",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "",
|
|
@@ -260,9 +260,6 @@
|
|
|
260
260
|
"./ui/theme/light": "./src/core/components/ui/theme/theme-collection/light.ts",
|
|
261
261
|
"./theme": "./src/core/components/ui/theme/theme.ts",
|
|
262
262
|
"./ui/theme": "./src/core/components/ui/theme/theme.ts",
|
|
263
|
-
"./message-subscriber.stories": "./src/core/components/ui/toast/message-subscriber.stories.ts",
|
|
264
|
-
"./ui/message-subscriber.stories": "./src/core/components/ui/toast/message-subscriber.stories.ts",
|
|
265
|
-
"./ui/toast/message-subscriber.stories": "./src/core/components/ui/toast/message-subscriber.stories.ts",
|
|
266
263
|
"./message-subscriber": "./src/core/components/ui/toast/message-subscriber.ts",
|
|
267
264
|
"./ui/message-subscriber": "./src/core/components/ui/toast/message-subscriber.ts",
|
|
268
265
|
"./ui/toast/message-subscriber": "./src/core/components/ui/toast/message-subscriber.ts",
|
package/src/core/_types/types.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any*/
|
|
2
2
|
|
|
3
3
|
import DataBindObserver from "@supersoniks/concorde/core/utils/DataBindObserver";
|
|
4
|
-
import Publisher from "../utils/PublisherProxy";
|
|
4
|
+
import type { Publisher } from "../utils/PublisherProxy";
|
|
5
5
|
export type Message = {
|
|
6
6
|
type?: string;
|
|
7
7
|
content?: string;
|
|
@@ -2,9 +2,8 @@ import { html, LitElement, nothing, PropertyValues } from "lit";
|
|
|
2
2
|
import { customElement, property } from "lit/decorators.js";
|
|
3
3
|
import Subscriber from "@supersoniks/concorde/core/mixins/Subscriber";
|
|
4
4
|
import { map } from "lit/directives/map.js";
|
|
5
|
-
import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
5
|
+
import DataProvider, { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
6
6
|
import "@supersoniks/concorde/core/components/functional/list/list";
|
|
7
|
-
import { PublisherProxy } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
8
7
|
import { HTML } from "@supersoniks/concorde/utils";
|
|
9
8
|
import { ListItems } from "@supersoniks/concorde/core/components/functional/list/list";
|
|
10
9
|
|
|
@@ -118,7 +117,7 @@ export default class Queue extends Subscriber(LitElement, {} as QueueProps) {
|
|
|
118
117
|
this.lastRequestTime = new Date().getTime();
|
|
119
118
|
this.configFilter();
|
|
120
119
|
}
|
|
121
|
-
filterPublisher:
|
|
120
|
+
filterPublisher: DataProvider | null = null;
|
|
122
121
|
configFilter() {
|
|
123
122
|
const dataFilterProvider =
|
|
124
123
|
this.getAncestorAttributeValue("dataFilterProvider");
|
|
@@ -145,7 +144,7 @@ export default class Queue extends Subscriber(LitElement, {} as QueueProps) {
|
|
|
145
144
|
split.shift();
|
|
146
145
|
const searchParams = new URLSearchParams(split.join("?"));
|
|
147
146
|
const filterData: Record<string, string | string[]> =
|
|
148
|
-
this.filterPublisher?.get();
|
|
147
|
+
this.filterPublisher?.get() ;
|
|
149
148
|
const filteredFieldsArray = this.filteredFields.split(" ");
|
|
150
149
|
for (const f in filterData) {
|
|
151
150
|
let value = filterData[f];
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { LitElement } from "lit";
|
|
2
2
|
import { html } from "lit";
|
|
3
3
|
import { customElement, state } from "lit/decorators.js";
|
|
4
|
-
import { dp } from "@supersoniks/concorde/
|
|
4
|
+
import { dp } from "@supersoniks/concorde/dataprovider";
|
|
5
5
|
import "./states";
|
|
6
6
|
import { tailwind } from "../../../../docs/tailwind";
|
|
7
|
+
type StatesDemoProvider = {
|
|
8
|
+
status?: string;
|
|
9
|
+
};
|
|
7
10
|
|
|
8
11
|
@customElement("sonic-states-demo")
|
|
9
12
|
export class SonicStatesDemo extends LitElement {
|
|
@@ -12,7 +15,7 @@ export class SonicStatesDemo extends LitElement {
|
|
|
12
15
|
constructor() {
|
|
13
16
|
super();
|
|
14
17
|
// Initialisation du dataProvider
|
|
15
|
-
dp("states-demo-provider").set({});
|
|
18
|
+
dp<StatesDemoProvider>("states-demo-provider").set({});
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
@state()
|
|
@@ -5,7 +5,7 @@ import "./states";
|
|
|
5
5
|
import { dp } from "@supersoniks/concorde/directives";
|
|
6
6
|
|
|
7
7
|
function create(template = "", addToDocument = true) {
|
|
8
|
-
dp("state-dataprovider-test").set({});
|
|
8
|
+
dp<{state: string}>("state-dataprovider-test").set({state: ""});
|
|
9
9
|
return TestUtils.bootstrap(
|
|
10
10
|
`
|
|
11
11
|
<sonic-states dataProvider="state-dataprovider-test" data-path="status">
|
|
@@ -25,8 +25,9 @@ describe("SonicStates", () => {
|
|
|
25
25
|
<template data-value="inactive">
|
|
26
26
|
<div>État Inactif</div>
|
|
27
27
|
</template>
|
|
28
|
-
`);
|
|
29
|
-
|
|
28
|
+
`);
|
|
29
|
+
|
|
30
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "active"});
|
|
30
31
|
await elt.updated();
|
|
31
32
|
expect(elt.textContent.trim()).toBe("État Actif");
|
|
32
33
|
});
|
|
@@ -37,7 +38,7 @@ describe("SonicStates", () => {
|
|
|
37
38
|
<div>Nombre</div>
|
|
38
39
|
</template>
|
|
39
40
|
`);
|
|
40
|
-
dp("state-dataprovider-test").
|
|
41
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "123"});
|
|
41
42
|
await elt.updated();
|
|
42
43
|
expect(elt.textContent.trim()).toBe("Nombre");
|
|
43
44
|
});
|
|
@@ -48,7 +49,7 @@ describe("SonicStates", () => {
|
|
|
48
49
|
<div>Utilisateur</div>
|
|
49
50
|
</template>
|
|
50
51
|
`);
|
|
51
|
-
dp("state-dataprovider-test").
|
|
52
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "user/123"});
|
|
52
53
|
await elt.updated();
|
|
53
54
|
expect(elt.textContent.trim()).toBe("Utilisateur");
|
|
54
55
|
});
|
|
@@ -59,7 +60,7 @@ describe("SonicStates", () => {
|
|
|
59
60
|
<div>Utilisateur</div>
|
|
60
61
|
</template>
|
|
61
62
|
`);
|
|
62
|
-
dp("state-dataprovider-test").
|
|
63
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "user/123"});
|
|
63
64
|
await elt.updated();
|
|
64
65
|
const divWrapper = elt.querySelector("div[dataProvider]");
|
|
65
66
|
expect(divWrapper.getAttribute("dataProvider")).toBe("/api/user/123");
|
|
@@ -71,7 +72,7 @@ describe("SonicStates", () => {
|
|
|
71
72
|
<div>Utilisateur</div>
|
|
72
73
|
</template>
|
|
73
74
|
`);
|
|
74
|
-
dp("state-dataprovider-test").
|
|
75
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "user/123"});
|
|
75
76
|
await elt.updated();
|
|
76
77
|
const divWrapper = elt.querySelector("div[dataProvider]");
|
|
77
78
|
expect(divWrapper.getAttribute("dataProvider")).toBe("/api/user/123");
|
|
@@ -82,7 +83,7 @@ describe("SonicStates", () => {
|
|
|
82
83
|
elt.states = {
|
|
83
84
|
active: () => html`<div>État Actif Programmatique</div>`,
|
|
84
85
|
};
|
|
85
|
-
dp("state-dataprovider-test").
|
|
86
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "active"});
|
|
86
87
|
await elt.updated();
|
|
87
88
|
expect(elt.textContent.trim()).toBe("État Actif Programmatique");
|
|
88
89
|
});
|
|
@@ -92,7 +93,7 @@ describe("SonicStates", () => {
|
|
|
92
93
|
elt.states = {
|
|
93
94
|
"(\\d+)": (status: string) => html`<div>Nombre: ${status}</div>`,
|
|
94
95
|
};
|
|
95
|
-
dp("state-dataprovider-test").
|
|
96
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "123"});
|
|
96
97
|
await elt.updated();
|
|
97
98
|
expect(elt.textContent.trim()).toBe("Nombre: 123");
|
|
98
99
|
});
|
|
@@ -104,7 +105,7 @@ describe("SonicStates", () => {
|
|
|
104
105
|
return html`<div>Utilisateur ${id} ${slug}</div>`;
|
|
105
106
|
},
|
|
106
107
|
};
|
|
107
|
-
dp("state-dataprovider-test").
|
|
108
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "user/123/mySlug"});
|
|
108
109
|
await elt.updated();
|
|
109
110
|
expect(elt.textContent.trim()).toBe("Utilisateur 123 mySlug");
|
|
110
111
|
});
|
|
@@ -115,7 +116,7 @@ describe("SonicStates", () => {
|
|
|
115
116
|
active: () => html`<div>État Actif</div>`,
|
|
116
117
|
fallback: () => html`<div>État Par Défaut</div>`,
|
|
117
118
|
};
|
|
118
|
-
dp("state-dataprovider-test").
|
|
119
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "unknown"});
|
|
119
120
|
await elt.updated();
|
|
120
121
|
expect(elt.textContent.trim()).toBe("État Par Défaut");
|
|
121
122
|
});
|
|
@@ -130,11 +131,11 @@ describe("SonicStates", () => {
|
|
|
130
131
|
prog: () => html`<div>Template Programmatique</div>`,
|
|
131
132
|
};
|
|
132
133
|
|
|
133
|
-
dp("state-dataprovider-test").
|
|
134
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "html"});
|
|
134
135
|
await elt.updated();
|
|
135
136
|
expect(elt.textContent.trim()).toBe("Template HTML");
|
|
136
137
|
|
|
137
|
-
dp("state-dataprovider-test").
|
|
138
|
+
dp<{state: string}>("state-dataprovider-test").set({state: "prog"});
|
|
138
139
|
await elt.updated();
|
|
139
140
|
expect(elt.textContent.trim()).toBe("Template Programmatique");
|
|
140
141
|
});
|
|
@@ -113,7 +113,7 @@ export class Submit extends Subscriber(LitElement) {
|
|
|
113
113
|
);
|
|
114
114
|
//
|
|
115
115
|
// Validation du formulaire
|
|
116
|
-
formPublisher.isFormValid
|
|
116
|
+
formPublisher.isFormValid.set(true);
|
|
117
117
|
formPublisher.invalidateForm();
|
|
118
118
|
if (!formPublisher.isFormValid.get()) return;
|
|
119
119
|
this.disabled = true;
|
|
@@ -258,7 +258,7 @@ export class Submit extends Subscriber(LitElement) {
|
|
|
258
258
|
? formPublisher
|
|
259
259
|
: null;
|
|
260
260
|
if (captchaPublisher) {
|
|
261
|
-
captchaPublisher.captchaToken
|
|
261
|
+
captchaPublisher.captchaToken.set("request_token");
|
|
262
262
|
const captchaAssign = (token?: string) => {
|
|
263
263
|
if (token != "request_token") {
|
|
264
264
|
sendData();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Subscriber } from "@supersoniks/concorde/mixins";
|
|
2
|
-
import {
|
|
2
|
+
import { dp, HTML } from "@supersoniks/concorde/utils";
|
|
3
3
|
import { css, html, LitElement, nothing } from "lit";
|
|
4
4
|
import { customElement, property } from "lit/decorators.js";
|
|
5
5
|
import { ConcordeWindow } from "@supersoniks/concorde/core/_types/types";
|
|
6
|
-
import Publisher from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
6
|
+
import type { DataProvider, Publisher } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
7
7
|
import {
|
|
8
8
|
generateKey,
|
|
9
9
|
encryptToBase64,
|
|
@@ -51,15 +51,15 @@ export class Captcha extends Subscriber(LitElement) {
|
|
|
51
51
|
@property() key = "";
|
|
52
52
|
@property() action: string | null = null;
|
|
53
53
|
@property({ type: Number }) zIndex = 9999;
|
|
54
|
-
formPublisher?: {
|
|
54
|
+
formPublisher?: DataProvider<{
|
|
55
55
|
needsCaptchaValidation: boolean;
|
|
56
56
|
captchaKey: string;
|
|
57
|
-
captchaToken:
|
|
58
|
-
}
|
|
57
|
+
captchaToken: string;
|
|
58
|
+
}>;
|
|
59
59
|
|
|
60
60
|
onCaptchaTokenChanged = (v: string) => {
|
|
61
61
|
if (v == "request_token") {
|
|
62
|
-
if (this.formPublisher) this.formPublisher.captchaToken
|
|
62
|
+
if (this.formPublisher) this.formPublisher.captchaToken.set("");
|
|
63
63
|
this.requestToken();
|
|
64
64
|
}
|
|
65
65
|
};
|
|
@@ -78,7 +78,11 @@ export class Captcha extends Subscriber(LitElement) {
|
|
|
78
78
|
}
|
|
79
79
|
this.generateEncryptedKey();
|
|
80
80
|
super.connectedCallback();
|
|
81
|
-
this.formPublisher =
|
|
81
|
+
this.formPublisher = dp<{
|
|
82
|
+
needsCaptchaValidation: boolean;
|
|
83
|
+
captchaKey: string;
|
|
84
|
+
captchaToken: string;
|
|
85
|
+
}>(
|
|
82
86
|
this.getAncestorAttributeValue("headersDataProvider") ??
|
|
83
87
|
this.getAncestorAttributeValue("formDataProvider")
|
|
84
88
|
);
|
|
@@ -87,7 +91,7 @@ export class Captcha extends Subscriber(LitElement) {
|
|
|
87
91
|
this.formPublisher &&
|
|
88
92
|
!(this.formPublisher.captchaToken as Publisher<string>).get()
|
|
89
93
|
) {
|
|
90
|
-
this.formPublisher.needsCaptchaValidation
|
|
94
|
+
this.formPublisher.needsCaptchaValidation.set(true);
|
|
91
95
|
(this.formPublisher.captchaToken as Publisher<string>).onAssign(
|
|
92
96
|
this.onCaptchaTokenChanged
|
|
93
97
|
);
|
|
@@ -98,8 +102,8 @@ export class Captcha extends Subscriber(LitElement) {
|
|
|
98
102
|
(this.formPublisher.captchaToken as Publisher<string>).offAssign(
|
|
99
103
|
this.onCaptchaTokenChanged
|
|
100
104
|
);
|
|
101
|
-
this.formPublisher.captchaToken
|
|
102
|
-
this.formPublisher.needsCaptchaValidation
|
|
105
|
+
this.formPublisher.captchaToken.set("");
|
|
106
|
+
this.formPublisher.needsCaptchaValidation.set(false);
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
super.disconnectedCallback();
|
|
@@ -110,8 +114,8 @@ export class Captcha extends Subscriber(LitElement) {
|
|
|
110
114
|
const form = this.shadowRoot.querySelector("form");
|
|
111
115
|
if (!form) return;
|
|
112
116
|
const formData = new FormData(form);
|
|
113
|
-
this.formPublisher.captchaKey
|
|
114
|
-
this.formPublisher.captchaToken
|
|
117
|
+
this.formPublisher.captchaKey.set(this.key);
|
|
118
|
+
this.formPublisher.captchaToken.set(formData.get("altcha")?.toString() || "");
|
|
115
119
|
}
|
|
116
120
|
|
|
117
121
|
async generateEncryptedKey() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { html, LitElement, css, nothing } from "lit";
|
|
1
|
+
import { html, LitElement, css, nothing, PropertyValues } from "lit";
|
|
2
2
|
import {
|
|
3
3
|
customElement,
|
|
4
4
|
property,
|
|
@@ -18,7 +18,7 @@ import "@supersoniks/concorde/core/components/functional/queue/queue";
|
|
|
18
18
|
import "@supersoniks/concorde/core/components/ui/menu/menu-item";
|
|
19
19
|
import { ifDefined } from "lit/directives/if-defined.js";
|
|
20
20
|
import { PublisherManager } from "@supersoniks/concorde/utils";
|
|
21
|
-
import
|
|
21
|
+
import DataProvider from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
22
22
|
import { Size } from "../../_css/size";
|
|
23
23
|
import { Input } from "@supersoniks/concorde/core/components/ui/form/input/input";
|
|
24
24
|
import { customScroll } from "@supersoniks/concorde/core/components/ui/_css/scroll";
|
|
@@ -98,10 +98,10 @@ export class InputAutocomplete extends TemplatesContainer(
|
|
|
98
98
|
private initQueueDataProvider = "";
|
|
99
99
|
@state()
|
|
100
100
|
private lastValidSearch: ListItem | string = "";
|
|
101
|
-
private searchPublisher?:
|
|
102
|
-
private countPublisher?:
|
|
103
|
-
private initCountPublisher?:
|
|
104
|
-
private formValuePublisher?:
|
|
101
|
+
private searchPublisher?: DataProvider;
|
|
102
|
+
private countPublisher?: DataProvider;
|
|
103
|
+
private initCountPublisher?: DataProvider;
|
|
104
|
+
private formValuePublisher?: DataProvider;
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Les fonctions de gestion
|
|
@@ -239,7 +239,7 @@ export class InputAutocomplete extends TemplatesContainer(
|
|
|
239
239
|
* Pour récupérer la valeur de searchParameter correspondante et renseigner l'input
|
|
240
240
|
**/
|
|
241
241
|
if (this.value) {
|
|
242
|
-
PublisherManager.get(this.initSearchDataProvider)[this.name]
|
|
242
|
+
PublisherManager.get(this.initSearchDataProvider)[this.name].set(this.value);
|
|
243
243
|
}
|
|
244
244
|
this.initCountPublisher?.onAssign(this.initSearchParameter);
|
|
245
245
|
|
|
@@ -257,6 +257,12 @@ export class InputAutocomplete extends TemplatesContainer(
|
|
|
257
257
|
this.searchPublisher?.onAssign(this.updatePopContentVisibility);
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
+
protected firstUpdated(_changedProperties: PropertyValues): void {
|
|
261
|
+
super.firstUpdated(_changedProperties);
|
|
262
|
+
// Écouter le focusout sur le popElement pour fermer le pop quand le focus sort
|
|
263
|
+
this.popElement.addEventListener("focusout", this.handleFocusOut);
|
|
264
|
+
}
|
|
265
|
+
|
|
260
266
|
disconnectedCallback() {
|
|
261
267
|
super.disconnectedCallback();
|
|
262
268
|
this.initCountPublisher?.offAssign(this.initSearchParameter);
|
|
@@ -269,6 +275,9 @@ export class InputAutocomplete extends TemplatesContainer(
|
|
|
269
275
|
getPublisher(this.queueDataProvider).delete();
|
|
270
276
|
|
|
271
277
|
this.searchPublisher?.offAssign(this.updatePopContentVisibility);
|
|
278
|
+
|
|
279
|
+
// Retirer l'écouteur de focusout
|
|
280
|
+
this.popElement.removeEventListener("focusout", this.handleFocusOut);
|
|
272
281
|
}
|
|
273
282
|
|
|
274
283
|
/**
|
|
@@ -331,6 +340,31 @@ export class InputAutocomplete extends TemplatesContainer(
|
|
|
331
340
|
this.popElement.show();
|
|
332
341
|
}
|
|
333
342
|
|
|
343
|
+
handleFocusOut = (_e: FocusEvent): void => {
|
|
344
|
+
// Utiliser setTimeout pour vérifier où va le focus après le focusout
|
|
345
|
+
// Cela permet de ne pas fermer le pop si le focus va vers un élément du pop
|
|
346
|
+
setTimeout(() => {
|
|
347
|
+
const activeElement = document.activeElement;
|
|
348
|
+
if (!activeElement) {
|
|
349
|
+
this.popElement.hide();
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Vérifier si le focus est dans le popElement ou dans ce composant
|
|
354
|
+
const isInPop =
|
|
355
|
+
this.popElement.contains(activeElement) ||
|
|
356
|
+
this.popElement.shadowRoot?.contains(activeElement);
|
|
357
|
+
const isInComponent =
|
|
358
|
+
this.contains(activeElement) ||
|
|
359
|
+
this.shadowRoot?.contains(activeElement);
|
|
360
|
+
|
|
361
|
+
// Si le focus n'est ni dans le pop ni dans ce composant, fermer le pop
|
|
362
|
+
if (!isInPop && !isInComponent) {
|
|
363
|
+
this.popElement.hide();
|
|
364
|
+
}
|
|
365
|
+
}, 0);
|
|
366
|
+
};
|
|
367
|
+
|
|
334
368
|
render() {
|
|
335
369
|
return html`
|
|
336
370
|
<sonic-pop manual style="display:block;" @hide=${this.handleHide}>
|
|
@@ -30,7 +30,7 @@ export class Pop extends LitElement {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
slot[name="content"] {
|
|
33
|
-
max-width:
|
|
33
|
+
max-width: 100vw;
|
|
34
34
|
background-color: var(--sc-base, #fff);
|
|
35
35
|
position: fixed;
|
|
36
36
|
z-index: 99999;
|
|
@@ -76,7 +76,7 @@ export class Pop extends LitElement {
|
|
|
76
76
|
lastContentX = 0;
|
|
77
77
|
lastContentY = 0;
|
|
78
78
|
resizeObserver: ResizeObserver = new ResizeObserver(() =>
|
|
79
|
-
this.computePosition(this.placement)
|
|
79
|
+
this.computePosition(this.placement),
|
|
80
80
|
);
|
|
81
81
|
|
|
82
82
|
@state() private triggerElement: HTMLElement | null = null;
|
|
@@ -176,7 +176,7 @@ export class Pop extends LitElement {
|
|
|
176
176
|
Pop.pops.forEach((pop: Pop) => {
|
|
177
177
|
const popContainsTarget = path.includes(pop);
|
|
178
178
|
const popContentContainsTarget = path.includes(
|
|
179
|
-
pop.querySelector('[slot="content"]') as EventTarget
|
|
179
|
+
pop.querySelector('[slot="content"]') as EventTarget,
|
|
180
180
|
);
|
|
181
181
|
const isCloseManual =
|
|
182
182
|
HTML.getAncestorAttributeValue(target, "data-on-select") === "keep";
|
|
@@ -230,7 +230,7 @@ export class Pop extends LitElement {
|
|
|
230
230
|
const thisRect = this.getBoundingClientRect();
|
|
231
231
|
|
|
232
232
|
const scrollableAncestor = HTML.getScrollableAncestor(
|
|
233
|
-
this.popContent
|
|
233
|
+
this.popContent,
|
|
234
234
|
) as HTMLElement;
|
|
235
235
|
const scrollableAncestorRect = scrollableAncestor?.getBoundingClientRect();
|
|
236
236
|
const minX = Math.max(0, scrollableAncestorRect?.left || 0) + padding;
|
|
@@ -238,12 +238,12 @@ export class Pop extends LitElement {
|
|
|
238
238
|
const maxX =
|
|
239
239
|
Math.min(
|
|
240
240
|
window.innerWidth,
|
|
241
|
-
scrollableAncestorRect?.right || window.innerWidth
|
|
241
|
+
scrollableAncestorRect?.right || window.innerWidth,
|
|
242
242
|
) - padding;
|
|
243
243
|
const maxY =
|
|
244
244
|
Math.min(
|
|
245
245
|
window.innerHeight,
|
|
246
|
-
scrollableAncestorRect?.bottom || window.innerHeight
|
|
246
|
+
scrollableAncestorRect?.bottom || window.innerHeight,
|
|
247
247
|
) - padding;
|
|
248
248
|
const x0 = thisRect.left;
|
|
249
249
|
const y0 = thisRect.top;
|
|
@@ -24,7 +24,7 @@ export class Theme extends LitElement {
|
|
|
24
24
|
font-style: var(--sc-font-style-base, normal);
|
|
25
25
|
}
|
|
26
26
|
::slotted(.sonic-pop-content) {
|
|
27
|
-
max-width:
|
|
27
|
+
max-width: 100vw;
|
|
28
28
|
background-color: var(--sc-base, #fff);
|
|
29
29
|
position: fixed;
|
|
30
30
|
z-index: 99999;
|
|
@@ -99,8 +99,8 @@ export class Theme extends LitElement {
|
|
|
99
99
|
type: "SonicTheme",
|
|
100
100
|
...theme,
|
|
101
101
|
},
|
|
102
|
-
"*"
|
|
103
|
-
)
|
|
102
|
+
"*",
|
|
103
|
+
),
|
|
104
104
|
);
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Objects } from "@supersoniks/concorde/utils";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import DataProvider, { PublisherManager } from "../../utils/PublisherProxy";
|
|
4
4
|
import { ConnectedComponent, setSubscribable } from "./common";
|
|
5
5
|
|
|
6
6
|
const dynamicWatcherStore = Symbol("__bindDynamicWatcherStore__");
|
|
@@ -138,7 +138,7 @@ function getPublisherFromPath(path: string) {
|
|
|
138
138
|
let publisher = PublisherManager.get(dataProvider);
|
|
139
139
|
if (!publisher) return null;
|
|
140
140
|
publisher = Objects.traverse(publisher, segments);
|
|
141
|
-
return publisher as
|
|
141
|
+
return publisher as DataProvider | null;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
export function bind(path: string, options?: { reflect?: boolean }) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Objects } from "@supersoniks/concorde/utils";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import DataProvider, { PublisherManager } from "../../utils/PublisherProxy";
|
|
4
4
|
import { ConnectedComponent, setSubscribable } from "./common";
|
|
5
5
|
|
|
6
6
|
const dynamicWatcherStore = Symbol("__onAssignDynamicWatcherStore__");
|
|
@@ -43,12 +43,14 @@ function registerDynamicWatcher(
|
|
|
43
43
|
function ensureWillUpdateHook(instance: any) {
|
|
44
44
|
const proto = Object.getPrototypeOf(instance);
|
|
45
45
|
if (!proto || proto[dynamicWillUpdateHookedStore]) return;
|
|
46
|
+
|
|
46
47
|
const originalWillUpdate = Object.prototype.hasOwnProperty.call(
|
|
47
48
|
proto,
|
|
48
49
|
"willUpdate"
|
|
49
50
|
)
|
|
50
51
|
? proto.willUpdate
|
|
51
52
|
: Object.getPrototypeOf(proto)?.willUpdate;
|
|
53
|
+
|
|
52
54
|
proto.willUpdate = function (changedProperties?: Map<unknown, unknown>) {
|
|
53
55
|
const handlers = this[dynamicWatcherStore] as
|
|
54
56
|
| Map<string, Set<() => void>>
|
|
@@ -140,7 +142,7 @@ function getPublisherFromPath(path: string) {
|
|
|
140
142
|
let publisher = PublisherManager.get(dataProvider);
|
|
141
143
|
if (!publisher) return null;
|
|
142
144
|
publisher = Objects.traverse(publisher, segments);
|
|
143
|
-
return publisher as
|
|
145
|
+
return publisher as DataProvider | null;
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
type Callback = (...values: unknown[]) => void;
|
|
@@ -152,7 +154,7 @@ type PathConfiguration = {
|
|
|
152
154
|
|
|
153
155
|
type Configuration = {
|
|
154
156
|
callbacks: Set<Callback>;
|
|
155
|
-
publisher:
|
|
157
|
+
publisher: DataProvider | null;
|
|
156
158
|
onAssign: (value: unknown) => void;
|
|
157
159
|
unsubscribePublisher: (() => void) | null;
|
|
158
160
|
pathConfig: PathConfiguration;
|
|
@@ -175,7 +177,7 @@ export function onAssign(...values: Array<string>) {
|
|
|
175
177
|
descriptor: PropertyDescriptor
|
|
176
178
|
) {
|
|
177
179
|
setSubscribable(target);
|
|
178
|
-
const stateKey = `
|
|
180
|
+
const stateKey = `__onAssign_state_${_propertyKey}__`;
|
|
179
181
|
let callback: Callback;
|
|
180
182
|
|
|
181
183
|
(target as ConnectedComponent).__onConnected__((component) => {
|
|
@@ -1,41 +1,22 @@
|
|
|
1
1
|
import { AsyncDirective, PartInfo } from "lit/async-directive.js";
|
|
2
2
|
import { directive } from "lit/directive.js";
|
|
3
|
-
import {
|
|
4
|
-
PublisherManager,
|
|
5
|
-
PublisherProxy,
|
|
6
|
-
} from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
7
3
|
import { noChange } from "lit";
|
|
8
|
-
import Objects from "../utils/Objects";
|
|
9
4
|
import { SearchableDomElement } from "../utils/HTML";
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
func();
|
|
17
|
-
return PublisherManager.getModifiedPublishers() || new Set();
|
|
18
|
-
}
|
|
19
|
-
if (typeof observable === "string") {
|
|
20
|
-
const split = observable.split(".");
|
|
21
|
-
const dataProvider: string = split.shift() || "";
|
|
22
|
-
let publisher = PublisherManager.get(dataProvider);
|
|
23
|
-
publisher = Objects.traverse(publisher, split);
|
|
24
|
-
const set = new Set<PublisherProxy>();
|
|
25
|
-
set.add(publisher);
|
|
26
|
-
return set;
|
|
27
|
-
}
|
|
28
|
-
return new Set<PublisherProxy>([observable as Publisher]);
|
|
29
|
-
}
|
|
5
|
+
import {
|
|
6
|
+
getObservables,
|
|
7
|
+
get as pubGet, set as pubSet, dataProvider as pubDataProvider ,
|
|
8
|
+
dp as pubDp, DataProvider
|
|
9
|
+
} from "../utils/PublisherProxy";
|
|
10
|
+
|
|
30
11
|
|
|
31
12
|
class ObserveDirective extends AsyncDirective {
|
|
32
|
-
observables: Set<
|
|
13
|
+
observables: Set<DataProvider<any>> = new Set();
|
|
33
14
|
unsubscribe(): void {
|
|
34
|
-
this.observables.forEach((publisher:
|
|
15
|
+
this.observables.forEach((publisher: DataProvider<any>) =>
|
|
35
16
|
publisher.offAssign(this.onAssign)
|
|
36
17
|
);
|
|
37
18
|
}
|
|
38
|
-
observable?:
|
|
19
|
+
observable?: string;
|
|
39
20
|
node?: SearchableDomElement;
|
|
40
21
|
|
|
41
22
|
/* eslint-disable @typescript-eslint/no-explicit-any*/
|
|
@@ -45,7 +26,7 @@ class ObserveDirective extends AsyncDirective {
|
|
|
45
26
|
}
|
|
46
27
|
/* eslint-enable @typescript-eslint/no-explicit-any*/
|
|
47
28
|
|
|
48
|
-
render(observable:
|
|
29
|
+
render(observable: string) {
|
|
49
30
|
if (this.observable !== observable) {
|
|
50
31
|
this.observable = observable;
|
|
51
32
|
if (this.isConnected) {
|
|
@@ -60,18 +41,12 @@ class ObserveDirective extends AsyncDirective {
|
|
|
60
41
|
};
|
|
61
42
|
// Subscribes to the observable, calling the directive's asynchronous
|
|
62
43
|
// setValue API each time the value changes
|
|
63
|
-
subscribe(observable:
|
|
44
|
+
subscribe<T>(observable: string) {
|
|
64
45
|
this.unsubscribe();
|
|
65
|
-
|
|
66
|
-
this.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
} else {
|
|
70
|
-
this.onAssign = (v: unknown) => {
|
|
71
|
-
this.setValue(v);
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
this.observables = getObservables(observable);
|
|
46
|
+
this.onAssign = (v: unknown) => {
|
|
47
|
+
this.setValue(v);
|
|
48
|
+
};
|
|
49
|
+
this.observables = getObservables<T>(observable);
|
|
75
50
|
|
|
76
51
|
this.observables.forEach((publisher) => {
|
|
77
52
|
publisher.onAssign(this.onAssign);
|
|
@@ -86,7 +61,7 @@ class ObserveDirective extends AsyncDirective {
|
|
|
86
61
|
// re-connected, re-subscribe to make the directive operable again
|
|
87
62
|
reconnected() {
|
|
88
63
|
if (!this.observable) return;
|
|
89
|
-
this.subscribe(this.observable
|
|
64
|
+
this.subscribe(this.observable);
|
|
90
65
|
}
|
|
91
66
|
}
|
|
92
67
|
const dir = directive(ObserveDirective);
|
|
@@ -95,25 +70,37 @@ const dir = directive(ObserveDirective);
|
|
|
95
70
|
export const subscribe = dir;
|
|
96
71
|
export const sub = dir;
|
|
97
72
|
|
|
98
|
-
// get value
|
|
99
|
-
export const get = (id: Observable) => {
|
|
100
|
-
return getObservables(id).values().next().value?.get();
|
|
101
|
-
};
|
|
102
73
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
74
|
+
/**
|
|
75
|
+
* @deprecated @see {@link "/src/core/utils/PublisherProxy.ts#get"}
|
|
76
|
+
* @param id Observable
|
|
77
|
+
* @returns value of the observable
|
|
78
|
+
*
|
|
79
|
+
*/
|
|
80
|
+
export const get: <T = any>(id: string) => T = pubGet;
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @deprecated @see {@link "/src/core/utils/PublisherProxy.ts#dataProvider"}
|
|
86
|
+
* @param id Observable
|
|
87
|
+
* @param defaultValue Optional default value
|
|
88
|
+
* @returns Observable
|
|
89
|
+
*/
|
|
90
|
+
export const dataProvider = pubDataProvider;
|
|
113
91
|
|
|
114
|
-
|
|
115
|
-
|
|
92
|
+
/**
|
|
93
|
+
* @deprecated @see {@link "/src/core/utils/PublisherProxy.ts#dp"}
|
|
94
|
+
* @param id Observable
|
|
95
|
+
* @param defaultValue Optional default value
|
|
96
|
+
* @returns Observable
|
|
97
|
+
*/
|
|
98
|
+
export const dp = pubDp;
|
|
116
99
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
100
|
+
/**
|
|
101
|
+
* @deprecated @see {@link "/src/core/utils/PublisherProxy.ts#set"}
|
|
102
|
+
* @param id Observable
|
|
103
|
+
* @param value value to set
|
|
104
|
+
* @returns void
|
|
105
|
+
*/
|
|
106
|
+
export const set: <T = any>(id: string, value: T) => void = pubSet;
|