@supersoniks/concorde 4.9.1 → 4.9.3

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.
Files changed (118) hide show
  1. package/README.md +2 -2
  2. package/build-infos.json +1 -1
  3. package/concorde-core.bundle.js +166 -166
  4. package/concorde-core.es.js +2646 -2624
  5. package/dist/concorde-core.bundle.js +166 -166
  6. package/dist/concorde-core.es.js +2646 -2624
  7. package/dist/docs-mock-api-sw.js +1 -0
  8. package/dist/js/core/components/ui/icon/icon.js +17 -1
  9. package/dist/js/core/components/ui/icon/icon.js.map +1 -1
  10. package/dist/js/core/components/ui/icon/icons.js +40 -19
  11. package/dist/js/core/components/ui/icon/icons.js.map +1 -1
  12. package/dist/js/core/utils/HTML.js +4 -5
  13. package/dist/js/core/utils/HTML.js.map +1 -1
  14. package/dist/robots.txt +15 -1
  15. package/dist/types/core/components/ui/icon/icon.d.ts +2 -0
  16. package/dist/types/core/components/ui/icon/icon.d.ts.map +1 -1
  17. package/dist/types/core/components/ui/icon/icons.d.ts +2 -0
  18. package/dist/types/core/components/ui/icon/icons.d.ts.map +1 -1
  19. package/dist/types/core/utils/HTML.d.ts.map +1 -1
  20. package/docs/assets/{index-CZLTFws2.css → index-Bnp7gVaA.css} +1 -1
  21. package/docs/assets/{index-nkkwC13U.js → index-hElUgV9_.js} +505 -438
  22. package/docs/crawl/core/components/functional/date/date.html +190 -0
  23. package/docs/crawl/core/components/functional/fetch/fetch.html +109 -0
  24. package/docs/crawl/core/components/functional/if/if.html +27 -0
  25. package/docs/crawl/core/components/functional/list/list.html +70 -0
  26. package/docs/crawl/core/components/functional/mix/mix.html +45 -0
  27. package/docs/crawl/core/components/functional/queue/queue.html +96 -0
  28. package/docs/crawl/core/components/functional/router/router.html +106 -0
  29. package/docs/crawl/core/components/functional/sdui/sdui.html +269 -0
  30. package/docs/crawl/core/components/functional/states/states.html +66 -0
  31. package/docs/crawl/core/components/functional/submit/submit.html +160 -0
  32. package/docs/crawl/core/components/functional/subscriber/subscriber.html +67 -0
  33. package/docs/crawl/core/components/functional/value/value.html +51 -0
  34. package/docs/crawl/core/components/ui/alert/alert.html +110 -0
  35. package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +23 -0
  36. package/docs/crawl/core/components/ui/badge/badge.html +119 -0
  37. package/docs/crawl/core/components/ui/button/button.html +149 -0
  38. package/docs/crawl/core/components/ui/captcha/captcha.html +30 -0
  39. package/docs/crawl/core/components/ui/card/card.html +99 -0
  40. package/docs/crawl/core/components/ui/divider/divider.html +58 -0
  41. package/docs/crawl/core/components/ui/form/checkbox/checkbox.html +73 -0
  42. package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +135 -0
  43. package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +79 -0
  44. package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +62 -0
  45. package/docs/crawl/core/components/ui/form/input/input.html +109 -0
  46. package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +106 -0
  47. package/docs/crawl/core/components/ui/form/radio/radio.html +56 -0
  48. package/docs/crawl/core/components/ui/form/select/select.html +73 -0
  49. package/docs/crawl/core/components/ui/form/switch/switch.html +56 -0
  50. package/docs/crawl/core/components/ui/form/textarea/textarea.html +59 -0
  51. package/docs/crawl/core/components/ui/group/group.html +82 -0
  52. package/docs/crawl/core/components/ui/icon/icon.html +133 -0
  53. package/docs/crawl/core/components/ui/image/image.html +110 -0
  54. package/docs/crawl/core/components/ui/link/link.html +42 -0
  55. package/docs/crawl/core/components/ui/loader/loader.html +50 -0
  56. package/docs/crawl/core/components/ui/menu/menu.html +322 -0
  57. package/docs/crawl/core/components/ui/modal/modal.html +117 -0
  58. package/docs/crawl/core/components/ui/pop/pop.html +102 -0
  59. package/docs/crawl/core/components/ui/progress/progress.html +58 -0
  60. package/docs/crawl/core/components/ui/table/table.html +413 -0
  61. package/docs/crawl/core/components/ui/toast/toast.html +122 -0
  62. package/docs/crawl/core/components/ui/tooltip/tooltip.html +79 -0
  63. package/docs/crawl/docs/_core-concept/dataFlow.html +166 -0
  64. package/docs/crawl/docs/_core-concept/overview.html +66 -0
  65. package/docs/crawl/docs/_core-concept/subscriber.html +75 -0
  66. package/docs/crawl/docs/_decorators/ancestor-attribute.html +116 -0
  67. package/docs/crawl/docs/_decorators/auto-subscribe.html +202 -0
  68. package/docs/crawl/docs/_decorators/bind.html +141 -0
  69. package/docs/crawl/docs/_decorators/get.html +120 -0
  70. package/docs/crawl/docs/_decorators/handle.html +165 -0
  71. package/docs/crawl/docs/_decorators/on-assign.html +355 -0
  72. package/docs/crawl/docs/_decorators/patch.html +52 -0
  73. package/docs/crawl/docs/_decorators/post.html +102 -0
  74. package/docs/crawl/docs/_decorators/publish.html +61 -0
  75. package/docs/crawl/docs/_decorators/put.html +49 -0
  76. package/docs/crawl/docs/_decorators/subscribe.html +109 -0
  77. package/docs/crawl/docs/_decorators/wait-for-ancestors.html +137 -0
  78. package/docs/crawl/docs/_directives/sub.html +93 -0
  79. package/docs/crawl/docs/_getting-started/ai-agents.html +134 -0
  80. package/docs/crawl/docs/_getting-started/concorde-manual-install.html +100 -0
  81. package/docs/crawl/docs/_getting-started/concorde-outside.html +58 -0
  82. package/docs/crawl/docs/_getting-started/create-a-component.html +111 -0
  83. package/docs/crawl/docs/_getting-started/my-first-component.html +189 -0
  84. package/docs/crawl/docs/_getting-started/my-first-subscriber.html +110 -0
  85. package/docs/crawl/docs/_getting-started/pubsub.html +62 -0
  86. package/docs/crawl/docs/_getting-started/start.html +76 -0
  87. package/docs/crawl/docs/_getting-started/theming.html +85 -0
  88. package/docs/crawl/docs/_misc/api-configuration.html +149 -0
  89. package/docs/crawl/docs/_misc/dataProviderKey.html +135 -0
  90. package/docs/crawl/docs/_misc/docs-mock-api.html +146 -0
  91. package/docs/crawl/docs/_misc/dynamic-path.html +180 -0
  92. package/docs/crawl/docs/_misc/endpoint.html +50 -0
  93. package/docs/crawl/docs/_misc/html-integration.html +47 -0
  94. package/docs/crawl/hubs/decorators.html +467 -0
  95. package/docs/crawl/hubs/form-components.html +357 -0
  96. package/docs/crawl/hubs/remote-data.html +374 -0
  97. package/docs/crawl/index.html +99 -0
  98. package/docs/docs-mock-api-sw.js +3 -1
  99. package/docs/docs-mock-api-sw.js.map +2 -2
  100. package/docs/index.html +3 -2
  101. package/docs/llms-full.txt +5423 -0
  102. package/docs/llms.txt +102 -0
  103. package/docs/robots.txt +15 -1
  104. package/docs/sitemap.xml +231 -0
  105. package/docs/src/docs/_decorators/get.md +47 -1
  106. package/docs/src/docs/search/docs-search.json +31 -1
  107. package/index.html +1 -0
  108. package/package.json +3 -12
  109. package/public/docs-mock-api-sw.js +1 -0
  110. package/public/robots.txt +15 -1
  111. package/scripts/generate-crawl-docs.mjs +569 -0
  112. package/scripts/post-build-docs.js +18 -14
  113. package/scripts/pre-build.mjs +1 -0
  114. package/src/core/components/ui/icon/icon.ts +15 -1
  115. package/src/core/components/ui/icon/icons.ts +44 -18
  116. package/src/core/decorators/subscriber/ancestorAttribute.spec.ts +42 -0
  117. package/src/core/utils/HTML.ts +4 -5
  118. package/src/docs/search/docs-search.json +61 -1
@@ -43,22 +43,38 @@ const libraries = {
43
43
  type Libraries = typeof libraries;
44
44
  type LibraryKey = keyof Libraries;
45
45
  type Library = Partial<{ url: string; defaultPrefix: string }>;
46
- let hasEnabledCustomLibrary = false;
47
- function enableCustomLibrary() {
48
- if (hasEnabledCustomLibrary) return;
49
46
 
50
- libraries.custom.url =
51
- document
52
- .querySelector("[customIconLibraryPath]")
53
- ?.getAttribute("customIconLibraryPath") || "";
54
- libraries.custom.defaultPrefix =
55
- document
56
- .querySelector("[customIconDefaultPrefix]")
57
- ?.getAttribute("customIconDefaultPrefix") || "";
47
+ function resolveCustomLibraryConfig(params: IconConf): Library {
48
+ let url = params.customLibraryPath;
49
+ let defaultPrefix = params.customLibraryDefaultPrefix;
58
50
 
59
- if (libraries.custom.url) {
60
- hasEnabledCustomLibrary = true;
51
+ // Attribut optionnel : peut être défini sur un ancêtre (scope / theme) ou,
52
+ // en secours, n'importe où dans le document (ex. config globale au boot).
53
+ if (url == null) {
54
+ const globalEl = document.querySelector("[customIconLibraryPath]");
55
+ url = globalEl?.getAttribute("customIconLibraryPath") ?? "";
56
+ if (defaultPrefix == null) {
57
+ defaultPrefix =
58
+ globalEl?.getAttribute("customIconDefaultPrefix") ??
59
+ document
60
+ .querySelector("[customIconDefaultPrefix]")
61
+ ?.getAttribute("customIconDefaultPrefix") ??
62
+ "";
63
+ }
61
64
  }
65
+
66
+ return {
67
+ url: url || "",
68
+ defaultPrefix: defaultPrefix || "",
69
+ };
70
+ }
71
+
72
+ function resolveLibraryItem(library: string, params: IconConf): Library | null {
73
+ if (!(library in libraries)) return null;
74
+ if (library !== "custom") {
75
+ return libraries[library as LibraryKey] as Library;
76
+ }
77
+ return resolveCustomLibraryConfig(params);
62
78
  }
63
79
  const iconCachStr = sessionStorage.getItem("sonicIconsCache");
64
80
  const iconCache = iconCachStr
@@ -70,6 +86,8 @@ export declare type IconConf = {
70
86
  name: string;
71
87
  prefix?: string;
72
88
  library?: string;
89
+ customLibraryPath?: string | null;
90
+ customLibraryDefaultPrefix?: string | null;
73
91
  };
74
92
  export default class Icons {
75
93
  static default = {
@@ -81,15 +99,23 @@ export default class Icons {
81
99
  /**
82
100
  * SVGS en ligne
83
101
  */
84
- if (library == "custom") {
85
- enableCustomLibrary();
102
+ if (!library) {
103
+ return unsafeHTML(iconsAsRecord["core"][params.name] || "");
86
104
  }
87
- if (library && library in libraries) {
88
- const libraryItem = libraries[library as LibraryKey] as Library;
105
+ const libraryItem = resolveLibraryItem(library, params);
106
+ if (libraryItem) {
107
+ // Pas d'URL encore (ancêtre ou config globale pas prête) : on attend
108
+ // sans fetch ni cache ; @ancestorAttribute relancera le chargement.
109
+ if (library === "custom" && !libraryItem.url) {
110
+ return "";
111
+ }
89
112
  const prefix: string = params.prefix || libraryItem.defaultPrefix || "";
90
113
  const libIcons = iconsAsRecord[library] || ({} as Library);
91
114
  iconsAsRecord[library] = libIcons;
92
- const libIconsKey = prefix + "-" + name;
115
+ const libIconsKey =
116
+ library === "custom"
117
+ ? `${libraryItem.url}|${prefix}-${name}`
118
+ : `${prefix}-${name}`;
93
119
 
94
120
  /**
95
121
  * Si l'icone a déjà été chargée on ne la recharge pas
@@ -55,6 +55,25 @@ describe("ancestorAttribute", () => {
55
55
  expect(el.dataProvider).toBe("scope-a");
56
56
  });
57
57
 
58
+ it("assigne une chaine vide si l'attribut ancêtre est présent sans valeur (mode statique)", () => {
59
+ const tag = "test-ancestor-attr-static-empty";
60
+ class C extends HTMLElement {
61
+ @ancestorAttribute("is_guichet")
62
+ isGuichet: string | null = null;
63
+ }
64
+ if (!customElements.get(tag)) {
65
+ customElements.define(tag, C);
66
+ }
67
+
68
+ const wrap = document.createElement("div");
69
+ wrap.setAttribute("is_guichet", "");
70
+ const el = document.createElement(tag) as InstanceType<typeof C>;
71
+ wrap.appendChild(el);
72
+ document.body.appendChild(wrap);
73
+
74
+ expect(el.isGuichet).toBe("");
75
+ });
76
+
58
77
  it("met à jour la propriété quand un ancêtre change (mode dynamique)", async () => {
59
78
  const tag = "test-ancestor-attr-dynamic-mutation";
60
79
  class C extends HTMLElement {
@@ -101,6 +120,29 @@ describe("ancestorAttribute", () => {
101
120
  expect(el.dataProvider).toBeNull();
102
121
  });
103
122
 
123
+ it("met à jour avec une chaine vide si l'attribut ancêtre devient présent sans valeur (mode dynamique)", async () => {
124
+ const tag = "test-ancestor-attr-dynamic-empty";
125
+ class C extends HTMLElement {
126
+ @ancestorAttribute("is_guichet", { dynamic: true })
127
+ isGuichet: string | null = null;
128
+ }
129
+ if (!customElements.get(tag)) {
130
+ customElements.define(tag, C);
131
+ }
132
+
133
+ const wrap = document.createElement("div");
134
+ const el = document.createElement(tag) as InstanceType<typeof C>;
135
+ wrap.appendChild(el);
136
+ document.body.appendChild(wrap);
137
+
138
+ expect(el.isGuichet).toBeNull();
139
+
140
+ wrap.setAttribute("is_guichet", "");
141
+ await flushFrames();
142
+
143
+ expect(el.isGuichet).toBe("");
144
+ });
145
+
104
146
  it("retombe sur l'ancêtre suivant quand le plus proche perd l'attribut", async () => {
105
147
  const tag = "test-ancestor-attr-dynamic-fallback";
106
148
  class C extends HTMLElement {
@@ -71,10 +71,9 @@ class HTML {
71
71
  ): string | null {
72
72
  for (const attrName of HTML.scopeAttributeNames(attributeName)) {
73
73
  if (element.hasAttribute(attrName)) {
74
- const attr = element.getAttribute(attrName);
75
- if (attr != null && attr.length > 0) {
76
- return attr;
77
- }
74
+ // Un attribut HTML peut exister sans valeur (ex: <x is_guichet>),
75
+ // on retourne donc "" plutôt que null pour préserver ce cas.
76
+ return element.getAttribute(attrName) ?? "";
78
77
  }
79
78
  }
80
79
  return null;
@@ -94,7 +93,7 @@ class HTML {
94
93
  while (current) {
95
94
  if (current instanceof HTMLElement) {
96
95
  const value = HTML.readScopeAttributeOnElement(current, attributeName);
97
- if (value != null && value.length > 0) {
96
+ if (value != null) {
98
97
  return value;
99
98
  }
100
99
  }
@@ -4759,6 +4759,51 @@
4759
4759
  }
4760
4760
  }
4761
4761
  },
4762
+ {
4763
+ "search": "Same pattern as @post: a publisher acts as a signal, independent of the response payload.\n",
4764
+ "files": {
4765
+ "docs/_decorators/get.md": {
4766
+ "title": "@get",
4767
+ "hashes": {
4768
+ "manual-refetch-triggerkey": {
4769
+ "count": 1,
4770
+ "title": "Manual refetch (`triggerKey`)",
4771
+ "type": "paragraph"
4772
+ }
4773
+ }
4774
+ }
4775
+ }
4776
+ },
4777
+ {
4778
+ "search": "Prefer triggerKey over mutating the API configuration publisher when you only want to reload the same URL — no need to touch serviceURL, tokens, etc.\n",
4779
+ "files": {
4780
+ "docs/_decorators/get.md": {
4781
+ "title": "@get",
4782
+ "hashes": {
4783
+ "manual-refetch-triggerkey": {
4784
+ "count": 1,
4785
+ "title": "Manual refetch (`triggerKey`)",
4786
+ "type": "paragraph"
4787
+ }
4788
+ }
4789
+ }
4790
+ }
4791
+ },
4792
+ {
4793
+ "search": "The docs mock adds an X-Fetched-At response header on /docs-mock-api/geo/communes so live demos can show when the last fetch happened (response.headers.get(&quot;X-Fetched-At&quot;)).\n",
4794
+ "files": {
4795
+ "docs/_decorators/get.md": {
4796
+ "title": "@get",
4797
+ "hashes": {
4798
+ "manual-refetch-triggerkey": {
4799
+ "count": 1,
4800
+ "title": "Manual refetch (`triggerKey`)",
4801
+ "type": "paragraph"
4802
+ }
4803
+ }
4804
+ }
4805
+ }
4806
+ },
4762
4807
  {
4763
4808
  "search": "Same demo service as sonic-queue (/docs-mock-api/geo/). Publisher setup lives in decorators-demo-geo.ts and decorators-demo-subscribe-publish-get-demos.ts.\n",
4764
4809
  "files": {
@@ -4775,7 +4820,22 @@
4775
4820
  }
4776
4821
  },
4777
4822
  {
4778
- "search": "Dynamic config and endpoint path (demo-api-get-configuration-key in doc sources):\n",
4823
+ "search": "@get with triggerKey refresh button + X-Fetched-At timestamp in the UI:\n",
4824
+ "files": {
4825
+ "docs/_decorators/get.md": {
4826
+ "title": "@get",
4827
+ "hashes": {
4828
+ "live-demos": {
4829
+ "count": 1,
4830
+ "title": "Live demos",
4831
+ "type": "paragraph"
4832
+ }
4833
+ }
4834
+ }
4835
+ }
4836
+ },
4837
+ {
4838
+ "search": "Dynamic config and endpoint path. Manual refetch is triggered from a separate component (same triggerKey publisher):\n",
4779
4839
  "files": {
4780
4840
  "docs/_decorators/get.md": {
4781
4841
  "title": "@get",