@supersoniks/concorde 5.0.0 → 5.0.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.
Files changed (314) hide show
  1. package/.gitlab-ci.yml +0 -13
  2. package/build-infos.json +1 -1
  3. package/concorde-core.bundle.js +606 -689
  4. package/concorde-core.es.js +4511 -4329
  5. package/dist/concorde-core.bundle.js +606 -689
  6. package/dist/concorde-core.es.js +4511 -4329
  7. package/gitlab/job_tests.sh +25 -12
  8. package/index.html +3 -3
  9. package/package.json +16 -1
  10. package/scripts/post-build-docs.js +0 -0
  11. package/scripts/post-build.mjs +0 -0
  12. package/src/core/components/functional/fetch/fetch.md +0 -0
  13. package/src/core/components/functional/if/if.md +0 -0
  14. package/src/core/components/functional/list/list.demo.ts +0 -0
  15. package/src/core/components/functional/list/list.md +0 -0
  16. package/src/core/components/functional/list/list.ts +0 -0
  17. package/src/core/components/functional/router/router.md +0 -0
  18. package/src/core/components/functional/router/router.ts +0 -0
  19. package/src/core/components/functional/sdui/sdui.md +0 -0
  20. package/src/core/components/functional/states/states.md +0 -0
  21. package/src/core/components/functional/submit/submit.md +0 -0
  22. package/src/core/components/ui/_css/rounded.ts +36 -0
  23. package/src/core/components/ui/_css/size.ts +0 -0
  24. package/src/core/components/ui/_css/type.ts +49 -0
  25. package/src/core/components/ui/_i18n/ui-aria-labels.ts +104 -0
  26. package/src/core/components/ui/alert/alert.md +128 -72
  27. package/src/core/components/ui/alert/alert.spec.ts +145 -0
  28. package/src/core/components/ui/alert/alert.ts +86 -91
  29. package/src/core/components/ui/alert-messages/alert-messages.ts +1 -1
  30. package/src/core/components/ui/badge/badge.md +126 -78
  31. package/src/core/components/ui/badge/badge.ts +29 -81
  32. package/src/core/components/ui/button/button.md +1 -0
  33. package/src/core/components/ui/button/button.ts +11 -8
  34. package/src/core/components/ui/captcha/altchaStyles.ts +0 -0
  35. package/src/core/components/ui/captcha/captcha.md +0 -0
  36. package/src/core/components/ui/card/card-header.ts +7 -2
  37. package/src/core/components/ui/card/card.md +120 -65
  38. package/src/core/components/ui/divider/divider.ts +4 -9
  39. package/src/core/components/ui/form/fieldset/legend-description.ts +1 -1
  40. package/src/core/components/ui/form/fieldset/legend.ts +1 -1
  41. package/src/core/components/ui/form/input/input.md +1 -1
  42. package/src/core/components/ui/form/input/input.ts +19 -15
  43. package/src/core/components/ui/form/radio/radio.md +0 -0
  44. package/src/core/components/ui/form/select/select.md +0 -0
  45. package/src/core/components/ui/form/switch/switch.md +0 -0
  46. package/src/core/components/ui/form/textarea/textarea.md +1 -1
  47. package/src/core/components/ui/image/image.md +147 -53
  48. package/src/core/components/ui/image/image.ts +10 -44
  49. package/src/core/components/ui/link/link.md +2 -2
  50. package/src/core/components/ui/link/link.ts +42 -37
  51. package/src/core/components/ui/loader/loader.md +0 -0
  52. package/src/core/components/ui/menu/menu.md +0 -0
  53. package/src/core/components/ui/modal/modal-close.ts +8 -12
  54. package/src/core/components/ui/modal/modal.md +0 -0
  55. package/src/core/components/ui/modal/modal.ts +18 -18
  56. package/src/core/components/ui/pop/pop.md +105 -1
  57. package/src/core/components/ui/pop/pop.ts +143 -148
  58. package/src/core/components/ui/table/table-caption.ts +0 -0
  59. package/src/core/components/ui/table/table.md +0 -0
  60. package/src/core/components/ui/table/table.ts +2 -8
  61. package/src/core/components/ui/theme/theme.ts +1 -1
  62. package/src/core/components/ui/toast/dismissed.ts +14 -0
  63. package/src/core/components/ui/toast/toast-item.ts +139 -91
  64. package/src/core/components/ui/toast/toast.ts +4 -7
  65. package/src/core/components/ui/tooltip/tooltip.ts +176 -154
  66. package/src/core/utils/LocationHandler.ts +12 -5
  67. package/src/core/utils/dismissed.ts +22 -0
  68. package/src/core/utils/positioning.spec.ts +208 -0
  69. package/src/core/utils/positioning.ts +183 -0
  70. package/src/core/utils/route.ts +0 -0
  71. package/src/directives.ts +2 -3
  72. package/src/docs/_core-concept/subscriber.md +0 -0
  73. package/src/docs/_getting-started/concorde-outside.md +3 -3
  74. package/src/docs/_getting-started/my-first-subscriber.md +0 -0
  75. package/src/docs/_getting-started/pubsub.md +0 -0
  76. package/src/docs/_getting-started/start.md +0 -0
  77. package/src/docs/code.ts +3 -1
  78. package/src/docs/example/users.ts +0 -0
  79. package/src/docs/search/docs-search.json +651 -21
  80. package/src/docs/search/page.ts +0 -0
  81. package/src/docs/tailwind/css/tailwind.css +13 -6
  82. package/src/tsconfig.json +45 -0
  83. package/src/tsconfig.tsbuildinfo +1 -1
  84. package/tailwind.config.js +50 -3
  85. package/vitest.setup.ts +49 -13
  86. package/.github/workflows/ci.yml +0 -21
  87. package/.github-export-ignore +0 -30
  88. package/CONTRIBUTING.md +0 -59
  89. package/DEV.md +0 -54
  90. package/LICENSE +0 -21
  91. package/OPEN_SOURCE_CHECKPOINT.md +0 -133
  92. package/concorde-3d.bundle.js +0 -3960
  93. package/concorde-3d.es.js +0 -33433
  94. package/concorde-hugging-face-infer.bundle.js +0 -32
  95. package/concorde-hugging-face-infer.es.js +0 -2952
  96. package/concorde-shader.bundle.js +0 -116
  97. package/concorde-shader.es.js +0 -8353
  98. package/concorde-webgpu.bundle.js +0 -307
  99. package/concorde-webgpu.es.js +0 -8627
  100. package/docs/altcha-widget.js +0 -2662
  101. package/docs/assets/index-BZiZXMU-.css +0 -1
  102. package/docs/assets/index-FmK4JaIM.js +0 -11992
  103. package/docs/crawl/core/components/functional/date/date.html +0 -190
  104. package/docs/crawl/core/components/functional/fetch/fetch.html +0 -109
  105. package/docs/crawl/core/components/functional/if/if.html +0 -27
  106. package/docs/crawl/core/components/functional/jsonata/jsonata.html +0 -79
  107. package/docs/crawl/core/components/functional/list/list.html +0 -70
  108. package/docs/crawl/core/components/functional/mix/mix.html +0 -45
  109. package/docs/crawl/core/components/functional/queue/queue.html +0 -96
  110. package/docs/crawl/core/components/functional/router/router.html +0 -106
  111. package/docs/crawl/core/components/functional/sdui/sdui.html +0 -269
  112. package/docs/crawl/core/components/functional/states/states.html +0 -66
  113. package/docs/crawl/core/components/functional/submit/submit.html +0 -160
  114. package/docs/crawl/core/components/functional/subscriber/subscriber.html +0 -67
  115. package/docs/crawl/core/components/functional/value/value.html +0 -51
  116. package/docs/crawl/core/components/ui/alert/alert.html +0 -110
  117. package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +0 -23
  118. package/docs/crawl/core/components/ui/badge/badge.html +0 -119
  119. package/docs/crawl/core/components/ui/button/button.html +0 -149
  120. package/docs/crawl/core/components/ui/captcha/captcha.html +0 -30
  121. package/docs/crawl/core/components/ui/card/card.html +0 -99
  122. package/docs/crawl/core/components/ui/divider/divider.html +0 -58
  123. package/docs/crawl/core/components/ui/form/checkbox/checkbox.html +0 -73
  124. package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +0 -135
  125. package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +0 -79
  126. package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +0 -62
  127. package/docs/crawl/core/components/ui/form/input/input.html +0 -109
  128. package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +0 -106
  129. package/docs/crawl/core/components/ui/form/radio/radio.html +0 -56
  130. package/docs/crawl/core/components/ui/form/select/select.html +0 -73
  131. package/docs/crawl/core/components/ui/form/switch/switch.html +0 -56
  132. package/docs/crawl/core/components/ui/form/textarea/textarea.html +0 -59
  133. package/docs/crawl/core/components/ui/group/group.html +0 -82
  134. package/docs/crawl/core/components/ui/icon/icon.html +0 -133
  135. package/docs/crawl/core/components/ui/image/image.html +0 -110
  136. package/docs/crawl/core/components/ui/link/link.html +0 -42
  137. package/docs/crawl/core/components/ui/loader/loader.html +0 -50
  138. package/docs/crawl/core/components/ui/menu/menu.html +0 -322
  139. package/docs/crawl/core/components/ui/modal/modal.html +0 -117
  140. package/docs/crawl/core/components/ui/pop/pop.html +0 -102
  141. package/docs/crawl/core/components/ui/progress/progress.html +0 -58
  142. package/docs/crawl/core/components/ui/table/table.html +0 -413
  143. package/docs/crawl/core/components/ui/toast/toast.html +0 -122
  144. package/docs/crawl/core/components/ui/tooltip/tooltip.html +0 -79
  145. package/docs/crawl/docs/_core-concept/dataFlow.html +0 -177
  146. package/docs/crawl/docs/_core-concept/overview.html +0 -66
  147. package/docs/crawl/docs/_core-concept/subscriber.html +0 -75
  148. package/docs/crawl/docs/_decorators/ancestor-attribute.html +0 -116
  149. package/docs/crawl/docs/_decorators/auto-subscribe.html +0 -202
  150. package/docs/crawl/docs/_decorators/bind.html +0 -141
  151. package/docs/crawl/docs/_decorators/get.html +0 -149
  152. package/docs/crawl/docs/_decorators/handle.html +0 -165
  153. package/docs/crawl/docs/_decorators/on-assign.html +0 -355
  154. package/docs/crawl/docs/_decorators/patch.html +0 -78
  155. package/docs/crawl/docs/_decorators/post.html +0 -139
  156. package/docs/crawl/docs/_decorators/publish.html +0 -61
  157. package/docs/crawl/docs/_decorators/put.html +0 -78
  158. package/docs/crawl/docs/_decorators/subscribe.html +0 -109
  159. package/docs/crawl/docs/_decorators/wait-for-ancestors.html +0 -137
  160. package/docs/crawl/docs/_directives/sub.html +0 -93
  161. package/docs/crawl/docs/_getting-started/ai-agents.html +0 -173
  162. package/docs/crawl/docs/_getting-started/concorde-manual-install.html +0 -100
  163. package/docs/crawl/docs/_getting-started/concorde-outside.html +0 -58
  164. package/docs/crawl/docs/_getting-started/create-a-component.html +0 -111
  165. package/docs/crawl/docs/_getting-started/my-first-component.html +0 -189
  166. package/docs/crawl/docs/_getting-started/my-first-subscriber.html +0 -110
  167. package/docs/crawl/docs/_getting-started/pubsub.html +0 -62
  168. package/docs/crawl/docs/_getting-started/start.html +0 -76
  169. package/docs/crawl/docs/_getting-started/theming.html +0 -85
  170. package/docs/crawl/docs/_misc/api-configuration.html +0 -149
  171. package/docs/crawl/docs/_misc/dataProviderKey.html +0 -135
  172. package/docs/crawl/docs/_misc/docs-mock-api.html +0 -158
  173. package/docs/crawl/docs/_misc/dynamic-path.html +0 -180
  174. package/docs/crawl/docs/_misc/endpoint.html +0 -50
  175. package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +0 -138
  176. package/docs/crawl/docs/_misc/html-integration.html +0 -48
  177. package/docs/crawl/hubs/decorators.html +0 -547
  178. package/docs/crawl/hubs/form-components.html +0 -357
  179. package/docs/crawl/hubs/remote-data.html +0 -452
  180. package/docs/crawl/index.html +0 -101
  181. package/docs/css/docs.css +0 -0
  182. package/docs/docs-mock-api-sw.js +0 -720
  183. package/docs/docs-mock-api-sw.js.map +0 -7
  184. package/docs/fonts/ClashGrotesk-Bold.eot +0 -0
  185. package/docs/fonts/ClashGrotesk-Bold.ttf +0 -0
  186. package/docs/fonts/ClashGrotesk-Bold.woff +0 -0
  187. package/docs/fonts/ClashGrotesk-Bold.woff2 +0 -0
  188. package/docs/fonts/ClashGrotesk-Extralight.eot +0 -0
  189. package/docs/fonts/ClashGrotesk-Extralight.ttf +0 -0
  190. package/docs/fonts/ClashGrotesk-Extralight.woff +0 -0
  191. package/docs/fonts/ClashGrotesk-Extralight.woff2 +0 -0
  192. package/docs/fonts/ClashGrotesk-Light.eot +0 -0
  193. package/docs/fonts/ClashGrotesk-Light.ttf +0 -0
  194. package/docs/fonts/ClashGrotesk-Light.woff +0 -0
  195. package/docs/fonts/ClashGrotesk-Light.woff2 +0 -0
  196. package/docs/fonts/ClashGrotesk-Medium.eot +0 -0
  197. package/docs/fonts/ClashGrotesk-Medium.ttf +0 -0
  198. package/docs/fonts/ClashGrotesk-Medium.woff +0 -0
  199. package/docs/fonts/ClashGrotesk-Medium.woff2 +0 -0
  200. package/docs/fonts/ClashGrotesk-Regular.eot +0 -0
  201. package/docs/fonts/ClashGrotesk-Regular.ttf +0 -0
  202. package/docs/fonts/ClashGrotesk-Regular.woff +0 -0
  203. package/docs/fonts/ClashGrotesk-Regular.woff2 +0 -0
  204. package/docs/fonts/ClashGrotesk-Semibold.eot +0 -0
  205. package/docs/fonts/ClashGrotesk-Semibold.ttf +0 -0
  206. package/docs/fonts/ClashGrotesk-Semibold.woff +0 -0
  207. package/docs/fonts/ClashGrotesk-Semibold.woff2 +0 -0
  208. package/docs/fonts/ClashGrotesk-Variable.eot +0 -0
  209. package/docs/fonts/ClashGrotesk-Variable.ttf +0 -0
  210. package/docs/fonts/ClashGrotesk-Variable.woff +0 -0
  211. package/docs/fonts/ClashGrotesk-Variable.woff2 +0 -0
  212. package/docs/img/concorde-icon.svg +0 -5
  213. package/docs/img/concorde-logo.svg +0 -1
  214. package/docs/img/concorde.png +0 -0
  215. package/docs/img/concorde_def.png +0 -0
  216. package/docs/img/concorde_seuil.png.webp +0 -0
  217. package/docs/img/concorde_seuil_invert.png +0 -0
  218. package/docs/img/paul_metrand.jpg +0 -0
  219. package/docs/img/paul_metrand_xs.jpg +0 -0
  220. package/docs/index.html +0 -93
  221. package/docs/llms-full.txt +0 -5787
  222. package/docs/llms.txt +0 -104
  223. package/docs/robots.txt +0 -16
  224. package/docs/sitemap.xml +0 -237
  225. package/docs/src/core/components/functional/date/date.md +0 -290
  226. package/docs/src/core/components/functional/fetch/fetch.md +0 -125
  227. package/docs/src/core/components/functional/if/if.md +0 -9
  228. package/docs/src/core/components/functional/jsonata/jsonata.md +0 -56
  229. package/docs/src/core/components/functional/list/list.md +0 -65
  230. package/docs/src/core/components/functional/mix/mix.md +0 -41
  231. package/docs/src/core/components/functional/queue/queue.md +0 -72
  232. package/docs/src/core/components/functional/router/router.md +0 -94
  233. package/docs/src/core/components/functional/sdui/default-library.json +0 -108
  234. package/docs/src/core/components/functional/sdui/example.json +0 -99
  235. package/docs/src/core/components/functional/sdui/sdui.md +0 -356
  236. package/docs/src/core/components/functional/states/states.md +0 -87
  237. package/docs/src/core/components/functional/submit/submit.md +0 -114
  238. package/docs/src/core/components/functional/subscriber/subscriber.md +0 -91
  239. package/docs/src/core/components/functional/value/value.md +0 -35
  240. package/docs/src/core/components/ui/alert/alert.md +0 -121
  241. package/docs/src/core/components/ui/alert-messages/alert-messages.md +0 -0
  242. package/docs/src/core/components/ui/badge/badge.md +0 -127
  243. package/docs/src/core/components/ui/button/button.md +0 -182
  244. package/docs/src/core/components/ui/captcha/captcha.md +0 -12
  245. package/docs/src/core/components/ui/card/card.md +0 -97
  246. package/docs/src/core/components/ui/divider/divider.md +0 -35
  247. package/docs/src/core/components/ui/form/checkbox/checkbox.md +0 -77
  248. package/docs/src/core/components/ui/form/fieldset/fieldset.md +0 -129
  249. package/docs/src/core/components/ui/form/form-actions/form-actions.md +0 -77
  250. package/docs/src/core/components/ui/form/form-layout/form-layout.md +0 -44
  251. package/docs/src/core/components/ui/form/input/input.md +0 -142
  252. package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -133
  253. package/docs/src/core/components/ui/form/radio/radio.md +0 -57
  254. package/docs/src/core/components/ui/form/select/select.md +0 -71
  255. package/docs/src/core/components/ui/form/switch/switch.md +0 -57
  256. package/docs/src/core/components/ui/form/textarea/textarea.md +0 -65
  257. package/docs/src/core/components/ui/group/group.md +0 -75
  258. package/docs/src/core/components/ui/icon/icon.md +0 -125
  259. package/docs/src/core/components/ui/icon/icons.json +0 -1
  260. package/docs/src/core/components/ui/image/image.md +0 -107
  261. package/docs/src/core/components/ui/link/link.md +0 -43
  262. package/docs/src/core/components/ui/loader/loader.md +0 -55
  263. package/docs/src/core/components/ui/menu/menu.md +0 -329
  264. package/docs/src/core/components/ui/modal/modal.md +0 -119
  265. package/docs/src/core/components/ui/pop/pop.md +0 -96
  266. package/docs/src/core/components/ui/progress/progress.md +0 -63
  267. package/docs/src/core/components/ui/table/table.md +0 -455
  268. package/docs/src/core/components/ui/toast/toast.md +0 -166
  269. package/docs/src/core/components/ui/tooltip/tooltip.md +0 -82
  270. package/docs/src/docs/_core-concept/dataFlow.md +0 -88
  271. package/docs/src/docs/_core-concept/overview.md +0 -57
  272. package/docs/src/docs/_core-concept/subscriber.md +0 -75
  273. package/docs/src/docs/_decorators/ancestor-attribute.md +0 -127
  274. package/docs/src/docs/_decorators/auto-subscribe.md +0 -202
  275. package/docs/src/docs/_decorators/bind.md +0 -167
  276. package/docs/src/docs/_decorators/get.md +0 -162
  277. package/docs/src/docs/_decorators/handle.md +0 -175
  278. package/docs/src/docs/_decorators/on-assign.md +0 -390
  279. package/docs/src/docs/_decorators/patch.md +0 -70
  280. package/docs/src/docs/_decorators/post.md +0 -146
  281. package/docs/src/docs/_decorators/publish.md +0 -55
  282. package/docs/src/docs/_decorators/put.md +0 -70
  283. package/docs/src/docs/_decorators/subscribe.md +0 -100
  284. package/docs/src/docs/_decorators/wait-for-ancestors.md +0 -163
  285. package/docs/src/docs/_directives/sub.md +0 -91
  286. package/docs/src/docs/_getting-started/ai-agents.md +0 -76
  287. package/docs/src/docs/_getting-started/concorde-manual-install.md +0 -133
  288. package/docs/src/docs/_getting-started/concorde-outside.md +0 -33
  289. package/docs/src/docs/_getting-started/create-a-component.md +0 -139
  290. package/docs/src/docs/_getting-started/my-first-component.md +0 -236
  291. package/docs/src/docs/_getting-started/my-first-subscriber.md +0 -120
  292. package/docs/src/docs/_getting-started/pubsub.md +0 -37
  293. package/docs/src/docs/_getting-started/start.md +0 -47
  294. package/docs/src/docs/_getting-started/theming.md +0 -91
  295. package/docs/src/docs/_misc/api-configuration.md +0 -81
  296. package/docs/src/docs/_misc/dataProviderKey.md +0 -168
  297. package/docs/src/docs/_misc/docs-mock-api.md +0 -63
  298. package/docs/src/docs/_misc/dynamic-path.md +0 -71
  299. package/docs/src/docs/_misc/endpoint.md +0 -45
  300. package/docs/src/docs/_misc/formelement-subscriber-removal.md +0 -115
  301. package/docs/src/docs/_misc/html-integration.md +0 -15
  302. package/docs/src/docs/search/docs-search.json +0 -9512
  303. package/docs/src/tag-list.json +0 -1
  304. package/docs/src/tsconfig-model.json +0 -23
  305. package/docs/src/tsconfig.declarations.json +0 -22
  306. package/docs/src/tsconfig.emit.json +0 -23
  307. package/docs/src/tsconfig.json +0 -858
  308. package/docs/svg/regular/plane.svg +0 -1
  309. package/docs/svg/solid/plane.svg +0 -1
  310. package/gitlab/job_github_mirror.sh +0 -39
  311. package/scripts/github-export.mjs +0 -150
  312. package/src/css.d.ts +0 -19
  313. package/src/tsconfig.declarations.json +0 -22
  314. package/src/tsconfig.emit.json +0 -23
@@ -1,27 +1,44 @@
1
1
  import { html, LitElement, css, PropertyValues } from "lit";
2
2
  import { customElement, query, state, property } from "lit/decorators.js";
3
+ import { ifDefined } from "lit/directives/if-defined.js";
3
4
 
4
5
  import HTML, {
5
6
  SearchableDomElement,
6
7
  } from "@supersoniks/concorde/core/utils/HTML";
8
+ import {
9
+ computeFloatingPosition,
10
+ FloatingPlacement,
11
+ FloatingSide,
12
+ getFloatingBounds,
13
+ parsePlacement,
14
+ startFrameLoop,
15
+ supportsPopover,
16
+ } from "@supersoniks/concorde/core/utils/positioning";
7
17
  import { Shadow, shadowable } from "../_css/shadow";
8
- // Toast
9
- type PopPlacement =
10
- | "bottom"
11
- | "top"
12
- | "right"
13
- | "left"
14
- | "top"
15
- | "bottom center"
16
- | "top center"
17
- | "right center"
18
- | "left center";
18
+
19
+ /** @deprecated écriture avec espace, utiliser `"bottom-center"`. */
20
+ type LegacyPopPlacement = `${FloatingSide} center`;
21
+ type PopPlacement = FloatingPlacement | LegacyPopPlacement;
22
+
23
+ let legacyPlacementWarned = false;
24
+
25
+ function normalizePopPlacement(placement: PopPlacement): FloatingPlacement {
26
+ if (!placement.includes(" ")) return placement as FloatingPlacement;
27
+ if (!legacyPlacementWarned) {
28
+ legacyPlacementWarned = true;
29
+ console.warn(
30
+ `[concorde] sonic-pop placement="${placement}" est déprécié, utiliser placement="${placement.replace(" ", "-")}".`,
31
+ );
32
+ }
33
+ return placement.replace(" ", "-") as FloatingPlacement;
34
+ }
19
35
 
20
36
  const tagName = "sonic-pop";
21
37
 
22
38
  @customElement(tagName)
23
39
  export class Pop extends LitElement {
24
40
  static pops = new Set<Pop>();
41
+ static readonly supportsPopover = supportsPopover;
25
42
  static styles = [
26
43
  css`
27
44
  :host {
@@ -44,7 +61,7 @@ export class Pop extends LitElement {
44
61
  border-radius: min(calc(var(--sc-btn-rounded) * 2), 0.4em);
45
62
  }
46
63
 
47
- slot[name="content"].is-open:not(.is-empty) {
64
+ slot[name="content"].is-open {
48
65
  transform: translateY(0) scale(1);
49
66
  opacity: 1;
50
67
  pointer-events: auto;
@@ -52,6 +69,36 @@ export class Pop extends LitElement {
52
69
  transition-timing-function: cubic-bezier(0.25, 0.25, 0.42, 1.225);
53
70
  }
54
71
 
72
+ slot[name="content"][popover] {
73
+ inset: auto;
74
+ width: auto;
75
+ height: auto;
76
+ margin: 0;
77
+ padding: 0;
78
+ border: none;
79
+ overflow: visible;
80
+ color: inherit;
81
+ /* display / overlay en allow-discrete : reste dans le top layer pendant le fondu de fermeture */
82
+ transition-property: all, display, overlay;
83
+ transition-behavior: normal, allow-discrete, allow-discrete;
84
+ }
85
+
86
+ slot[name="content"][popover]:not(:popover-open) {
87
+ display: none;
88
+ }
89
+
90
+ slot[name="content"][popover].is-open {
91
+ transition-property: scale, opacity, display, overlay;
92
+ transition-behavior: normal, normal, allow-discrete, allow-discrete;
93
+ }
94
+
95
+ @starting-style {
96
+ slot[name="content"][popover].is-open:popover-open {
97
+ transform: translateY(1rem) scale(0.95);
98
+ opacity: 0;
99
+ }
100
+ }
101
+
55
102
  :host([inline]) {
56
103
  vertical-align: baseline;
57
104
  }
@@ -72,7 +119,6 @@ export class Pop extends LitElement {
72
119
  @property({ type: String, reflect: true }) shadow: Shadow = "lg";
73
120
 
74
121
  @property({ type: String }) placement: PopPlacement = "bottom";
75
- positioningRuns = false;
76
122
  lastContentX = 0;
77
123
  lastContentY = 0;
78
124
  resizeObserver: ResizeObserver = new ResizeObserver(() =>
@@ -80,13 +126,9 @@ export class Pop extends LitElement {
80
126
  );
81
127
 
82
128
  @state() private triggerElement: HTMLElement | null = null;
83
-
84
- runPositioningLoop() {
85
- if (!this.positioningRuns) return;
86
- this.positioningRuns = true;
87
- this.computePosition(this.placement);
88
- window.requestAnimationFrame(() => this.runPositioningLoop());
89
- }
129
+ private stopPositioning?: () => void;
130
+ private hideDisplayTimeout?: ReturnType<typeof setTimeout>;
131
+ private pendingShow = false;
90
132
 
91
133
  toggle(e: Event) {
92
134
  if (this.open && this.noToggle) return;
@@ -99,47 +141,74 @@ export class Pop extends LitElement {
99
141
  this.triggerElement = e.target as HTMLElement;
100
142
  }
101
143
 
102
- this.open = !this.open;
103
- this.open ? this.show() : this.hide();
144
+ if (this.open) this.hide();
145
+ else this.show();
104
146
  }
105
147
 
106
148
  show() {
107
- this.setMaxZindex();
149
+ if (!this.popContent) {
150
+ this.pendingShow = true;
151
+ this.updateComplete.then(() => {
152
+ if (this.pendingShow) this.show();
153
+ });
154
+ return;
155
+ }
156
+ this.pendingShow = false;
157
+ if (this.open) return;
158
+ if (!Pop.supportsPopover) this.setMaxZindex();
159
+ clearTimeout(this.hideDisplayTimeout);
108
160
  this.popContent?.style?.removeProperty("display");
161
+ if (Pop.supportsPopover && !this.popContent.matches(":popover-open")) {
162
+ this.popContent.showPopover();
163
+ }
109
164
  this.open = true;
165
+ // Pop.pops suit l'ordre d'ouverture : Escape ferme le dernier ouvert.
166
+ if (Pop.pops.delete(this)) Pop.pops.add(this);
110
167
  this.popContent.setAttribute("tabindex", "0");
111
- if (this.popBtn && this.popContent && !this.positioningRuns) {
112
- this.positioningRuns = true;
168
+ if (this.popBtn && this.popContent && !this.stopPositioning) {
113
169
  this.lastContentX = 0;
114
170
  this.lastContentY = 0;
115
- this.runPositioningLoop();
171
+ this.stopPositioning = startFrameLoop(() =>
172
+ this.computePosition(this.placement),
173
+ );
116
174
  }
117
175
  this.dispatchEvent(new CustomEvent("show"));
118
176
  }
119
177
 
120
178
  hide() {
121
- this.resetZindexes();
179
+ this.pendingShow = false;
180
+ if (!this.popContent) {
181
+ this.dispatchEvent(new CustomEvent("hide"));
182
+ return;
183
+ }
184
+ if (!Pop.supportsPopover) this.resetZindexes();
185
+ if (Pop.supportsPopover && this.popContent?.matches(":popover-open")) {
186
+ this.popContent.hidePopover();
187
+ }
122
188
  this.open = false;
123
189
  this.popContent.setAttribute("tabindex", "-1");
124
- this.positioningRuns = false;
190
+ this.stopPositionLoop();
191
+ if (!Pop.supportsPopover) this.hideContentAfterTransition();
125
192
  if (this.triggerElement) {
126
193
  this.triggerElement.focus();
127
194
  this.triggerElement = null;
128
195
  }
129
- Object.assign(this.popContent.style, {
130
- left: `${this.lastContentX}px`,
131
- top: `${this.lastContentY}px`,
132
- });
133
196
  this.dispatchEvent(new CustomEvent("hide"));
134
197
  }
135
198
 
136
- protected updated(changedProperties: PropertyValues): void {
137
- super.updated(changedProperties);
138
- // Le template remet style="display:none" à chaque render —
139
- // on le retire après coup quand le pop est ouvert.
140
- if (this.open) {
141
- this.popContent?.style?.removeProperty("display");
142
- }
199
+ private stopPositionLoop() {
200
+ this.stopPositioning?.();
201
+ this.stopPositioning = undefined;
202
+ }
203
+
204
+ /** Sans display:none, le contenu masqué par opacité resterait atteignable au clavier. */
205
+ private hideContentAfterTransition() {
206
+ clearTimeout(this.hideDisplayTimeout);
207
+ const duration =
208
+ parseFloat(getComputedStyle(this.popContent).transitionDuration) * 1000;
209
+ this.hideDisplayTimeout = setTimeout(() => {
210
+ if (!this.open) this.popContent.style.display = "none";
211
+ }, duration || 0);
143
212
  }
144
213
 
145
214
  /**
@@ -183,6 +252,7 @@ export class Pop extends LitElement {
183
252
  const target = path[0] as HTMLElement;
184
253
 
185
254
  Pop.pops.forEach((pop: Pop) => {
255
+ if (!pop.open) return;
186
256
  const popContainsTarget = path.includes(pop);
187
257
  const popContentContainsTarget = path.includes(
188
258
  pop.querySelector('[slot="content"]') as EventTarget,
@@ -204,7 +274,8 @@ export class Pop extends LitElement {
204
274
  if (Pop.pops.size == 0) {
205
275
  document.addEventListener("pointerdown", this._handleClosePop);
206
276
  document.addEventListener("click", this._handleClosePop);
207
- document.addEventListener("keydown", this._handleKeyDown);
277
+ // Capture : passer avant les écouteurs Escape des ancêtres (ex. sonic-modal).
278
+ document.addEventListener("keydown", Pop._handleKeyDown, true);
208
279
  }
209
280
  Pop.pops.add(this);
210
281
  }
@@ -221,133 +292,56 @@ export class Pop extends LitElement {
221
292
  if (this.popContent) {
222
293
  this.resizeObserver.unobserve(this.popContent);
223
294
  }
295
+ this.stopPositionLoop();
296
+ clearTimeout(this.hideDisplayTimeout);
297
+ if (this.open) {
298
+ if (!Pop.supportsPopover) this.resetZindexes();
299
+ this.open = false;
300
+ this.triggerElement = null;
301
+ this.popContent?.style.setProperty("display", "none");
302
+ }
224
303
  super.disconnectedCallback();
225
304
  Pop.pops.delete(this);
226
305
  if (Pop.pops.size == 0) {
227
306
  document.removeEventListener("pointerdown", this._handleClosePop);
228
307
  document.removeEventListener("click", this._handleClosePop);
229
- document.removeEventListener("keydown", this._handleKeyDown);
308
+ document.removeEventListener("keydown", Pop._handleKeyDown, true);
230
309
  }
231
310
  }
232
311
 
233
312
  computePosition(placement: PopPlacement) {
234
- const placementSplit = placement.split(" ");
235
- const placementBase = placementSplit[0];
236
- let placementSec = placementSplit[1];
237
-
238
- const padding = 5;
239
- const thisRect = this.getBoundingClientRect();
240
-
241
- const scrollableAncestor = HTML.getScrollableAncestor(
242
- this.popContent,
243
- ) as HTMLElement;
244
- const scrollableAncestorRect = scrollableAncestor?.getBoundingClientRect();
245
- const minX = Math.max(0, scrollableAncestorRect?.left || 0) + padding;
246
- const minY = Math.max(0, scrollableAncestorRect?.top || 0) + padding;
247
- const maxX =
248
- Math.min(
249
- window.innerWidth,
250
- scrollableAncestorRect?.right || window.innerWidth,
251
- ) - padding;
252
- const maxY =
253
- Math.min(
254
- window.innerHeight,
255
- scrollableAncestorRect?.bottom || window.innerHeight,
256
- ) - padding;
257
- const x0 = thisRect.left;
258
- const y0 = thisRect.top;
259
- let x = x0,
260
- y = y0;
261
- let contentRect = this.popContent?.getBoundingClientRect();
262
- const yTop = y0 - contentRect.height;
263
- const xLeft = x0 - contentRect.width;
264
- const xRight = x0 + thisRect.width;
265
- const yBottom = y0 + thisRect.height;
266
- const xCenter = x0 + (thisRect.width - contentRect.width) * 0.5;
267
- const yCenter = y0 + (thisRect.height - contentRect.height) * 0.5;
268
- switch (placementBase) {
269
- case "bottom":
270
- y = yBottom;
271
- if (placementSec == "center") {
272
- x = xCenter;
273
- }
274
- break;
275
- case "top":
276
- y = yTop;
277
- if (placementSec == "center") {
278
- x = xCenter;
279
- }
280
- break;
281
- case "left":
282
- x = xLeft;
283
- if (placementSec == "center") {
284
- y = yCenter;
285
- }
286
- break;
287
- case "right":
288
- x = xRight;
289
- if (placementSec == "center") {
290
- y = yCenter;
291
- }
292
- break;
293
- }
294
-
295
- this.lastContentX += x - contentRect.x;
296
- this.lastContentY += y - contentRect.y;
297
- Object.assign(this.popContent.style, {
298
- left: `${this.lastContentX}px`,
299
- top: `${this.lastContentY}px`,
313
+ const { side, align } = parsePlacement(
314
+ normalizePopPlacement(placement),
315
+ "bottom",
316
+ "start",
317
+ );
318
+ const contentRect = this.popContent.getBoundingClientRect();
319
+
320
+ const { x, y } = computeFloatingPosition({
321
+ anchor: this.getBoundingClientRect(),
322
+ floating: contentRect,
323
+ side,
324
+ align,
325
+ bounds: getFloatingBounds(this.popContent, 5),
300
326
  });
301
327
 
302
- contentRect = this.popContent?.getBoundingClientRect();
303
- if (contentRect.x < minX && placementBase == "left") x = xRight;
304
- if (contentRect.y < minY && placementBase == "top") y = yBottom;
305
- if (contentRect.x + contentRect.width > maxX && placementBase == "right")
306
- x = xLeft;
307
- if (contentRect.y + contentRect.height > maxY && placementBase == "bottom")
308
- y = yTop;
309
-
328
+ // Déplacement relatif à la position mesurée : reste juste quand un ancêtre transformé
329
+ // (ex. modale en translateZ) devient le bloc conteneur du position: fixed.
310
330
  this.lastContentX += x - contentRect.x;
311
331
  this.lastContentY += y - contentRect.y;
312
-
313
- Object.assign(this.popContent.style, {
314
- left: `${this.lastContentX}px`,
315
- top: `${this.lastContentY}px`,
316
- });
317
-
318
- contentRect = this.popContent?.getBoundingClientRect();
319
-
320
- if (contentRect.x < minX) {
321
- this.lastContentX += minX - contentRect.x;
322
- }
323
- if (contentRect.y < minY) {
324
- this.lastContentY += minY - contentRect.y;
325
- }
326
-
327
- Object.assign(this.popContent.style, {
328
- left: `${this.lastContentX}px`,
329
- top: `${this.lastContentY}px`,
330
- });
331
- contentRect = this.popContent?.getBoundingClientRect();
332
- if (contentRect.x + contentRect.width > maxX) {
333
- this.lastContentX += maxX - (contentRect.x + contentRect.width);
334
- }
335
- if (contentRect.y + contentRect.height > maxY) {
336
- this.lastContentY += maxY - (contentRect.y + contentRect.height);
337
- }
338
-
339
332
  Object.assign(this.popContent.style, {
340
333
  left: `${this.lastContentX}px`,
341
334
  top: `${this.lastContentY}px`,
342
335
  });
343
336
  }
344
337
 
345
- private _handleKeyDown = (e: KeyboardEvent) => {
346
- if (e.key === "Escape" && this.open) {
347
- e.stopPropagation();
348
- this.hide();
349
- }
350
- };
338
+ private static _handleKeyDown(e: KeyboardEvent) {
339
+ if (e.key !== "Escape") return;
340
+ const lastOpened = [...Pop.pops].reverse().find((pop) => pop.open);
341
+ if (!lastOpened) return;
342
+ e.stopPropagation();
343
+ lastOpened.hide();
344
+ }
351
345
 
352
346
  render() {
353
347
  return html`
@@ -358,6 +352,7 @@ export class Pop extends LitElement {
358
352
  ></slot>
359
353
  <slot
360
354
  name="content"
355
+ popover=${ifDefined(Pop.supportsPopover ? "manual" : undefined)}
361
356
  tabindex="-1"
362
357
  part="content"
363
358
  style="display: none;"
File without changes
File without changes
@@ -11,6 +11,7 @@ import "@supersoniks/concorde/core/components/ui/table/table-tbody";
11
11
  import "@supersoniks/concorde/core/components/ui/table/table-tfoot";
12
12
  import "@supersoniks/concorde/core/components/ui/table/table-caption";
13
13
  import { fontSize } from "@supersoniks/concorde/core/components/ui/_css/size";
14
+ import { Size } from "@supersoniks/concorde/core/components/ui/_css/size";
14
15
 
15
16
  const tagName = "sonic-table";
16
17
  @customElement(tagName)
@@ -66,14 +67,7 @@ export class Table extends LitElement {
66
67
  `,
67
68
  ];
68
69
 
69
- @property({ type: String, reflect: true }) size?:
70
- | "2xs"
71
- | "xs"
72
- | "sm"
73
- | "md"
74
- | "lg"
75
- | "xl"
76
- | "2xl";
70
+ @property({ type: String, reflect: true }) size?: Size;
77
71
  @property({ type: Boolean, reflect: true }) bordered?: boolean;
78
72
  @property({ type: Boolean, reflect: true }) rounded?: boolean;
79
73
  @property({ type: Boolean, reflect: true }) noCustomScroll?: boolean;
@@ -38,7 +38,7 @@ export class Theme extends LitElement {
38
38
  border-radius: min(calc(var(--sc-btn-rounded) * 2), 0.4em);
39
39
  }
40
40
 
41
- ::slotted(.sonic-pop-content).is-open:not(.is-empty) {
41
+ ::slotted(.sonic-pop-content).is-open {
42
42
  transform: translateY(0) scale(1);
43
43
  opacity: 1;
44
44
  pointer-events: auto;
@@ -0,0 +1,14 @@
1
+ import {
2
+ isDismissed,
3
+ markDismissed,
4
+ } from "@supersoniks/concorde/core/utils/dismissed";
5
+
6
+ const storageKey = "sonic-toast-dismissed";
7
+
8
+ export function isToastDismissed(id: string | number): boolean {
9
+ return isDismissed(storageKey, id);
10
+ }
11
+
12
+ export function markToastDismissed(id: string | number): void {
13
+ markDismissed(storageKey, id);
14
+ }