@livenetworks/ashlar 1.6.0 → 2.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.
Files changed (560) hide show
  1. package/LICENSE +641 -0
  2. package/README.md +202 -86
  3. package/{js → components}/COMPONENTS.md +1116 -1108
  4. package/{js → components}/index.js +81 -58
  5. package/{js → components}/ln-accordion/README.md +7 -6
  6. package/components/ln-accordion/ln-accordion-dev.scss +8 -0
  7. package/components/ln-accordion/ln-accordion.js +1 -0
  8. package/components/ln-accordion/ln-accordion.schema.json +30 -0
  9. package/components/ln-accordion/ln-accordion.scss +8 -0
  10. package/{js → components}/ln-accordion/src/ln-accordion.js +8 -2
  11. package/{js → components}/ln-ajax/README.md +171 -160
  12. package/components/ln-ajax/ln-ajax-dev.scss +8 -0
  13. package/components/ln-ajax/ln-ajax.js +1 -0
  14. package/components/ln-ajax/ln-ajax.schema.json +30 -0
  15. package/{js → components}/ln-ajax/src/ln-ajax.js +65 -30
  16. package/{js → components}/ln-api-connector/README.md +27 -5
  17. package/components/ln-api-connector/ln-api-connector.js +1 -0
  18. package/components/ln-api-connector/ln-api-connector.schema.json +96 -0
  19. package/components/ln-api-connector/src/connector-core.js +97 -0
  20. package/components/ln-api-connector/src/ln-api-connector.js +447 -0
  21. package/{js → components}/ln-api-queue/README.md +12 -9
  22. package/components/ln-api-queue/ln-api-queue.js +1 -0
  23. package/components/ln-api-queue/ln-api-queue.schema.json +34 -0
  24. package/{js → components}/ln-api-queue/src/ln-api-queue.js +33 -14
  25. package/{js → components}/ln-api-queue/src/queue-storage.js +7 -3
  26. package/{js → components}/ln-autoresize/README.md +129 -127
  27. package/components/ln-autoresize/ln-autoresize-dev.scss +8 -0
  28. package/components/ln-autoresize/ln-autoresize.js +1 -0
  29. package/components/ln-autoresize/ln-autoresize.schema.json +22 -0
  30. package/{js → components}/ln-autoresize/src/ln-autoresize.js +8 -1
  31. package/{js → components}/ln-autosave/README.md +127 -124
  32. package/components/ln-autosave/ln-autosave-dev.scss +13 -0
  33. package/components/ln-autosave/ln-autosave.js +1 -0
  34. package/components/ln-autosave/ln-autosave.schema.json +48 -0
  35. package/components/ln-autosave/src/autosave-model.js +34 -0
  36. package/{js → components}/ln-autosave/src/ln-autosave.js +65 -58
  37. package/components/ln-chart/README.md +145 -0
  38. package/components/ln-chart/ln-chart-dev.scss +20 -0
  39. package/components/ln-chart/ln-chart.js +1 -0
  40. package/components/ln-chart/ln-chart.schema.json +146 -0
  41. package/components/ln-chart/ln-chart.scss +8 -0
  42. package/components/ln-chart/src/chart-model.js +154 -0
  43. package/components/ln-chart/src/ln-chart.js +176 -0
  44. package/{js → components}/ln-circular-progress/README.md +15 -14
  45. package/components/ln-circular-progress/ln-circular-progress-dev.scss +8 -0
  46. package/components/ln-circular-progress/ln-circular-progress.js +1 -0
  47. package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -0
  48. package/{js → components}/ln-circular-progress/src/ln-circular-progress.js +32 -50
  49. package/components/ln-confirm/README.md +216 -0
  50. package/components/ln-confirm/ln-confirm-dev.scss +24 -0
  51. package/components/ln-confirm/ln-confirm.js +1 -0
  52. package/components/ln-confirm/ln-confirm.schema.json +66 -0
  53. package/components/ln-confirm/ln-confirm.scss +24 -0
  54. package/{js → components}/ln-confirm/src/ln-confirm.js +180 -167
  55. package/{js → components}/ln-core/README.md +374 -149
  56. package/components/ln-core/attrs.js +273 -0
  57. package/components/ln-core/compare.js +40 -0
  58. package/components/ln-core/crypto.js +265 -0
  59. package/components/ln-core/date.js +50 -0
  60. package/components/ln-core/dom.js +115 -0
  61. package/components/ln-core/events.js +122 -0
  62. package/components/ln-core/form.js +136 -0
  63. package/{js → components}/ln-core/hash.js +149 -92
  64. package/components/ln-core/helpers.js +33 -0
  65. package/components/ln-core/http.js +48 -0
  66. package/components/ln-core/index.js +11 -0
  67. package/components/ln-core/lifecycle.js +403 -0
  68. package/components/ln-core/ln-core.schema.json +109 -0
  69. package/components/ln-core/locale.js +55 -0
  70. package/components/ln-core/matching.js +78 -0
  71. package/components/ln-core/number.js +125 -0
  72. package/components/ln-core/progress.js +30 -0
  73. package/components/ln-core/template.js +206 -0
  74. package/{js → components}/ln-core/window-cache.js +247 -213
  75. package/{js → components}/ln-couchdb-connector/README.md +7 -5
  76. package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -0
  77. package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -0
  78. package/{js → components}/ln-couchdb-connector/src/ln-couchdb-connector.js +29 -43
  79. package/{js → components}/ln-data-coordinator/README.md +109 -73
  80. package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -0
  81. package/components/ln-data-coordinator/ln-data-coordinator.js +1 -0
  82. package/components/ln-data-coordinator/ln-data-coordinator.schema.json +196 -0
  83. package/components/ln-data-coordinator/src/data-read-policy.js +41 -0
  84. package/{js → components}/ln-data-coordinator/src/ln-data-coordinator.js +411 -154
  85. package/{js → components}/ln-data-coordinator/src/mutation-receipts.js +0 -5
  86. package/{js → components}/ln-data-store/README.md +42 -17
  87. package/components/ln-data-store/ln-data-store-dev.scss +13 -0
  88. package/components/ln-data-store/ln-data-store.js +1 -0
  89. package/components/ln-data-store/ln-data-store.schema.json +84 -0
  90. package/components/ln-data-store/src/data-store-model.js +155 -0
  91. package/{js → components}/ln-data-store/src/ln-data-store.js +407 -105
  92. package/components/ln-data-store/src/window-index.js +119 -0
  93. package/{js → components}/ln-date/README.md +17 -7
  94. package/{js → components}/ln-date/ln-date-dev.scss +14 -14
  95. package/components/ln-date/ln-date.js +1 -0
  96. package/components/ln-date/ln-date.schema.json +92 -0
  97. package/components/ln-date/src/date-model.js +186 -0
  98. package/components/ln-date/src/ln-date.js +486 -0
  99. package/components/ln-debug/README.md +132 -0
  100. package/components/ln-debug/ln-debug.js +1 -0
  101. package/components/ln-debug/ln-debug.schema.json +28 -0
  102. package/components/ln-debug/src/console-sink.js +19 -0
  103. package/components/ln-debug/src/debug-verifier.js +331 -0
  104. package/components/ln-debug/src/gate.js +95 -0
  105. package/components/ln-debug/src/generated-attributes.js +299 -0
  106. package/components/ln-debug/src/ln-debug.js +60 -0
  107. package/{js → components}/ln-dropdown/README.md +150 -140
  108. package/components/ln-dropdown/ln-dropdown-dev.scss +13 -0
  109. package/components/ln-dropdown/ln-dropdown.js +1 -0
  110. package/components/ln-dropdown/ln-dropdown.schema.json +90 -0
  111. package/components/ln-dropdown/ln-dropdown.scss +18 -0
  112. package/{js → components}/ln-dropdown/src/ln-dropdown.js +114 -11
  113. package/{js → components}/ln-editor/README.md +11 -9
  114. package/components/ln-editor/ln-editor-dev.scss +18 -0
  115. package/components/ln-editor/ln-editor.js +1 -0
  116. package/components/ln-editor/ln-editor.schema.json +58 -0
  117. package/components/ln-editor/ln-editor.scss +13 -0
  118. package/{js → components}/ln-editor/src/ln-editor.js +59 -11
  119. package/{js → components}/ln-external-links/README.md +10 -8
  120. package/components/ln-external-links/ln-external-links.js +1 -0
  121. package/components/ln-external-links/ln-external-links.schema.json +18 -0
  122. package/{js → components}/ln-external-links/src/ln-external-links.js +13 -11
  123. package/{js → components}/ln-fill/README.md +6 -8
  124. package/components/ln-fill/ln-fill.js +1 -0
  125. package/components/ln-fill/ln-fill.schema.json +23 -0
  126. package/{js → components}/ln-fill/src/ln-fill.js +7 -1
  127. package/components/ln-filter/README.md +131 -0
  128. package/components/ln-filter/ln-filter-dev.scss +13 -0
  129. package/components/ln-filter/ln-filter.js +1 -0
  130. package/components/ln-filter/ln-filter.schema.json +153 -0
  131. package/components/ln-filter/src/filter-model.js +185 -0
  132. package/components/ln-filter/src/ln-filter.js +435 -0
  133. package/{js → components}/ln-form/README.md +260 -264
  134. package/components/ln-form/ln-form-dev.scss +8 -0
  135. package/components/ln-form/ln-form.js +1 -0
  136. package/components/ln-form/ln-form.schema.json +45 -0
  137. package/{js → components}/ln-form/src/ln-form.js +107 -99
  138. package/{js → components}/ln-http/README.md +11 -6
  139. package/components/ln-http/ln-http.js +1 -0
  140. package/components/ln-http/ln-http.schema.json +6 -0
  141. package/components/ln-http/src/http-core.js +51 -0
  142. package/{js → components}/ln-http/src/ln-http.js +28 -33
  143. package/{js → components}/ln-icon/README.md +16 -9
  144. package/components/ln-icon/ln-icon.schema.json +6 -0
  145. package/components/ln-include/README.md +75 -0
  146. package/components/ln-include/ln-include-dev.scss +13 -0
  147. package/components/ln-include/ln-include.js +1 -0
  148. package/components/ln-include/ln-include.schema.json +23 -0
  149. package/components/ln-include/src/ln-include.js +111 -0
  150. package/components/ln-key/README.md +130 -0
  151. package/components/ln-key/ln-key-dev.scss +18 -0
  152. package/components/ln-key/ln-key.js +1 -0
  153. package/components/ln-key/ln-key.schema.json +56 -0
  154. package/components/ln-key/src/key-model.js +146 -0
  155. package/components/ln-key/src/ln-key.js +201 -0
  156. package/{js → components}/ln-link/README.md +7 -9
  157. package/components/ln-link/ln-link-dev.scss +8 -0
  158. package/components/ln-link/ln-link.js +1 -0
  159. package/components/ln-link/ln-link.schema.json +22 -0
  160. package/{js → components}/ln-link/src/ln-link.js +16 -11
  161. package/components/ln-list/README.md +152 -0
  162. package/components/ln-list/ln-list-dev.scss +8 -0
  163. package/components/ln-list/ln-list.js +1 -0
  164. package/components/ln-list/ln-list.schema.json +166 -0
  165. package/components/ln-list/ln-list.scss +25 -0
  166. package/{js → components}/ln-list/src/ln-list.js +1301 -1216
  167. package/{js → components}/ln-modal/README.md +13 -10
  168. package/components/ln-modal/ln-modal-dev.scss +18 -0
  169. package/components/ln-modal/ln-modal.js +1 -0
  170. package/components/ln-modal/ln-modal.schema.json +54 -0
  171. package/components/ln-modal/ln-modal.scss +51 -0
  172. package/{js → components}/ln-modal/src/ln-modal.js +164 -137
  173. package/{js → components}/ln-nav/README.md +11 -11
  174. package/components/ln-nav/ln-nav.js +1 -0
  175. package/components/ln-nav/ln-nav.schema.json +25 -0
  176. package/{js → components}/ln-nav/src/ln-nav.js +25 -14
  177. package/components/ln-number/README.md +205 -0
  178. package/{js → components}/ln-number/ln-number-dev.scss +13 -13
  179. package/components/ln-number/ln-number.js +1 -0
  180. package/components/ln-number/ln-number.schema.json +63 -0
  181. package/components/ln-number/src/ln-number.js +400 -0
  182. package/components/ln-number/src/number-model.js +31 -0
  183. package/components/ln-obfuscator/README.md +60 -0
  184. package/components/ln-obfuscator/ln-obfuscator.js +1 -0
  185. package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -0
  186. package/components/ln-obfuscator/src/ln-obfuscator.js +159 -0
  187. package/components/ln-obfuscator/src/obfuscator-model.js +250 -0
  188. package/{js → components}/ln-options/README.md +3 -1
  189. package/components/ln-options/ln-options-dev.scss +13 -0
  190. package/components/ln-options/ln-options.js +1 -0
  191. package/components/ln-options/ln-options.schema.json +41 -0
  192. package/{js → components}/ln-options/src/ln-options.js +13 -5
  193. package/components/ln-persist/README.md +151 -0
  194. package/components/ln-persist/ln-persist.js +1 -0
  195. package/components/ln-persist/ln-persist.schema.json +28 -0
  196. package/components/ln-persist/src/ln-persist.js +83 -0
  197. package/components/ln-picklist/README.md +230 -0
  198. package/components/ln-picklist/ln-picklist-dev.scss +22 -0
  199. package/components/ln-picklist/ln-picklist.js +1 -0
  200. package/components/ln-picklist/ln-picklist.schema.json +49 -0
  201. package/components/ln-picklist/src/ln-picklist.js +228 -0
  202. package/{js → components}/ln-popover/README.md +164 -162
  203. package/components/ln-popover/ln-popover-dev.scss +13 -0
  204. package/components/ln-popover/ln-popover.js +1 -0
  205. package/components/ln-popover/ln-popover.schema.json +82 -0
  206. package/components/ln-popover/ln-popover.scss +18 -0
  207. package/{js → components}/ln-popover/src/ln-popover.js +42 -36
  208. package/{js → components}/ln-progress/README.md +410 -413
  209. package/components/ln-progress/ln-progress-dev.scss +8 -0
  210. package/components/ln-progress/ln-progress.js +1 -0
  211. package/components/ln-progress/ln-progress.schema.json +40 -0
  212. package/components/ln-progress/src/ln-progress.js +91 -0
  213. package/components/ln-progress/src/progress-model.js +20 -0
  214. package/{js → components}/ln-router/README.md +443 -432
  215. package/components/ln-router/ln-router-dev.scss +13 -0
  216. package/components/ln-router/ln-router.js +1 -0
  217. package/components/ln-router/ln-router.schema.json +68 -0
  218. package/{js → components}/ln-router/src/ln-router.js +585 -539
  219. package/components/ln-router/src/router-model.js +50 -0
  220. package/components/ln-scroll/README.md +45 -0
  221. package/components/ln-scroll/ln-scroll.js +1 -0
  222. package/components/ln-scroll/ln-scroll.schema.json +85 -0
  223. package/components/ln-scroll/src/ln-scroll.js +150 -0
  224. package/components/ln-search/README.md +188 -0
  225. package/components/ln-search/ln-search-dev.scss +13 -0
  226. package/components/ln-search/ln-search.js +1 -0
  227. package/components/ln-search/ln-search.schema.json +103 -0
  228. package/components/ln-search/src/ln-search.js +330 -0
  229. package/{js → components}/ln-slug/README.md +6 -3
  230. package/components/ln-slug/ln-slug-dev.scss +18 -0
  231. package/components/ln-slug/ln-slug.js +1 -0
  232. package/components/ln-slug/ln-slug.schema.json +23 -0
  233. package/{js → components}/ln-slug/src/ln-slug.js +20 -13
  234. package/components/ln-slug/src/slug-model.js +21 -0
  235. package/{js → components}/ln-sort/README.md +178 -170
  236. package/{js → components}/ln-sort/ln-sort-dev.scss +8 -8
  237. package/components/ln-sort/ln-sort.js +1 -0
  238. package/components/ln-sort/ln-sort.schema.json +104 -0
  239. package/components/ln-sort/src/ln-sort.js +321 -0
  240. package/components/ln-sort/src/sort-model.js +117 -0
  241. package/{js → components}/ln-sortable/README.md +7 -11
  242. package/components/ln-sortable/ln-sortable-dev.scss +13 -0
  243. package/components/ln-sortable/ln-sortable.js +1 -0
  244. package/components/ln-sortable/ln-sortable.schema.json +36 -0
  245. package/{js → components}/ln-sortable/src/ln-sortable.js +8 -13
  246. package/{js → components}/ln-stat/README.md +3 -1
  247. package/components/ln-stat/ln-stat-dev.scss +8 -0
  248. package/components/ln-stat/ln-stat.js +1 -0
  249. package/components/ln-stat/ln-stat.schema.json +32 -0
  250. package/{js → components}/ln-stat/src/ln-stat.js +14 -18
  251. package/components/ln-stat/src/stat-model.js +28 -0
  252. package/{js → components}/ln-table/README.md +37 -24
  253. package/{js → components}/ln-table/ln-table-dev.scss +17 -17
  254. package/components/ln-table/ln-table.js +1 -0
  255. package/components/ln-table/ln-table.schema.json +211 -0
  256. package/components/ln-table/ln-table.scss +15 -0
  257. package/{js → components}/ln-table/src/ln-table.js +1365 -1493
  258. package/components/ln-table/src/table-model.js +98 -0
  259. package/components/ln-table-coordinator/README.md +61 -0
  260. package/components/ln-table-coordinator/ln-table-coordinator.js +1 -0
  261. package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -0
  262. package/components/ln-table-coordinator/src/ln-table-coordinator.js +193 -0
  263. package/{js → components}/ln-tabs/README.md +32 -14
  264. package/components/ln-tabs/ln-tabs-dev.scss +24 -0
  265. package/components/ln-tabs/ln-tabs.js +1 -0
  266. package/components/ln-tabs/ln-tabs.schema.json +75 -0
  267. package/components/ln-tabs/ln-tabs.scss +8 -0
  268. package/components/ln-tabs/src/ln-tabs.js +207 -0
  269. package/components/ln-tabs/src/tabs-model.js +82 -0
  270. package/{js → components}/ln-time/README.md +96 -95
  271. package/components/ln-time/ln-time-dev.scss +13 -0
  272. package/components/ln-time/ln-time.js +1 -0
  273. package/components/ln-time/ln-time.schema.json +38 -0
  274. package/{js → components}/ln-time/src/ln-time.js +206 -223
  275. package/components/ln-time/src/time-model.js +64 -0
  276. package/{js → components}/ln-toast/README.md +23 -5
  277. package/components/ln-toast/ln-toast-dev.scss +8 -0
  278. package/components/ln-toast/ln-toast.js +1 -0
  279. package/components/ln-toast/ln-toast.schema.json +65 -0
  280. package/components/ln-toast/ln-toast.scss +59 -0
  281. package/{js → components}/ln-toast/src/ln-toast.js +233 -232
  282. package/{js → components}/ln-toggle/README.md +198 -196
  283. package/{js → components}/ln-toggle/ln-toggle-dev.scss +13 -13
  284. package/components/ln-toggle/ln-toggle.js +1 -0
  285. package/components/ln-toggle/ln-toggle.schema.json +52 -0
  286. package/components/ln-toggle/ln-toggle.scss +37 -0
  287. package/{js → components}/ln-toggle/src/ln-toggle.js +61 -46
  288. package/{js → components}/ln-tooltip/README.md +6 -6
  289. package/{js → components}/ln-tooltip/ln-tooltip-dev.scss +9 -9
  290. package/components/ln-tooltip/ln-tooltip.js +1 -0
  291. package/components/ln-tooltip/ln-tooltip.schema.json +86 -0
  292. package/components/ln-tooltip/ln-tooltip.scss +9 -0
  293. package/{js → components}/ln-tooltip/src/ln-tooltip.js +14 -3
  294. package/{js → components}/ln-translations/README.md +3 -1
  295. package/components/ln-translations/ln-translations-dev.scss +13 -0
  296. package/components/ln-translations/ln-translations.js +1 -0
  297. package/components/ln-translations/ln-translations.schema.json +120 -0
  298. package/{js → components}/ln-translations/src/ln-translations.js +25 -10
  299. package/components/ln-ui-coordinator/README.md +101 -0
  300. package/components/ln-ui-coordinator/ln-ui-coordinator-dev.scss +8 -0
  301. package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -0
  302. package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +60 -0
  303. package/{js/ln-modal-coordinator/src/ln-modal-coordinator.js → components/ln-ui-coordinator/src/ln-ui-coordinator.js} +403 -345
  304. package/components/ln-upload/README.md +133 -0
  305. package/components/ln-upload/ln-upload-dev.scss +18 -0
  306. package/components/ln-upload/ln-upload.js +1 -0
  307. package/components/ln-upload/ln-upload.schema.json +193 -0
  308. package/components/ln-upload/ln-upload.scss +20 -0
  309. package/components/ln-upload/src/ln-upload.js +652 -0
  310. package/components/ln-upload/src/upload-model.js +78 -0
  311. package/{js → components}/ln-validate/README.md +182 -180
  312. package/{js → components}/ln-validate/ln-validate-dev.scss +15 -15
  313. package/components/ln-validate/ln-validate.js +1 -0
  314. package/components/ln-validate/ln-validate.schema.json +50 -0
  315. package/components/ln-validate/ln-validate.scss +7 -0
  316. package/{js → components}/ln-validate/src/ln-validate.js +23 -45
  317. package/components/ln-validate/src/validate-model.js +64 -0
  318. package/components/ln-websocket-connector/README.md +166 -0
  319. package/components/ln-websocket-connector/ln-websocket-connector.js +1 -0
  320. package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -0
  321. package/components/ln-websocket-connector/src/ln-websocket-connector.js +279 -0
  322. package/ln-ashlar.html-data.json +1796 -0
  323. package/package.json +84 -61
  324. package/{scss → theme}/base/_global.scss +1 -2
  325. package/{scss → theme}/base/_reset.scss +1 -1
  326. package/{scss → theme}/base/_typography.scss +2 -0
  327. package/theme/brand.css +73 -0
  328. package/{scss → theme}/components/_app-shell.scss +8 -0
  329. package/theme/components/_button.scss +24 -0
  330. package/theme/components/_chart.scss +5 -0
  331. package/theme/components/_confirm.scss +6 -0
  332. package/{scss → theme}/components/_date.scss +30 -22
  333. package/{scss → theme}/components/_dropdown.scss +6 -1
  334. package/theme/components/_form.scss +140 -0
  335. package/{scss → theme}/components/_layout.scss +6 -0
  336. package/{scss → theme}/components/_ln-table.scss +1 -6
  337. package/theme/components/_picklist.scss +3 -0
  338. package/{scss → theme}/components/_sort.scss +10 -10
  339. package/theme/components/_status-badge.scss +6 -0
  340. package/{scss → theme}/components/_table.scss +16 -0
  341. package/{scss → theme}/components/_tabs.scss +0 -4
  342. package/theme/components/_toast.scss +48 -0
  343. package/{scss → theme}/components/_toggle.scss +1 -1
  344. package/theme/components/_upload.scss +45 -0
  345. package/{scss → theme}/config/_breakpoints.scss +1 -1
  346. package/theme/config/_contrast.scss +128 -0
  347. package/{scss → theme}/config/_density.scss +191 -205
  348. package/theme/config/_palette.scss +274 -0
  349. package/theme/config/_theme.scss +293 -0
  350. package/{scss → theme}/config/_tokens.scss +285 -441
  351. package/{scss → theme}/config/mixins/_accordion.scss +1 -1
  352. package/{scss → theme}/config/mixins/_alert.scss +1 -0
  353. package/{scss → theme}/config/mixins/_app-shell.scss +4 -2
  354. package/{scss → theme}/config/mixins/_borders.scss +2 -0
  355. package/theme/config/mixins/_btn.scss +175 -0
  356. package/{scss → theme}/config/mixins/_card.scss +55 -46
  357. package/theme/config/mixins/_chart.scss +82 -0
  358. package/{scss → theme}/config/mixins/_collapsible.scss +2 -1
  359. package/{scss → theme}/config/mixins/_colors.scss +8 -14
  360. package/{scss → theme}/config/mixins/_diagnostics.scss +48 -48
  361. package/theme/config/mixins/_dropdown.scss +169 -0
  362. package/{scss → theme}/config/mixins/_editor.scss +0 -7
  363. package/{scss → theme}/config/mixins/_filter.scss +47 -47
  364. package/{scss → theme}/config/mixins/_footer.scss +1 -1
  365. package/{scss → theme}/config/mixins/_form.scss +49 -18
  366. package/{scss → theme}/config/mixins/_index.scss +62 -61
  367. package/{scss → theme}/config/mixins/_layout.scss +6 -2
  368. package/{scss → theme}/config/mixins/_ln-table.scss +31 -10
  369. package/{scss → theme}/config/mixins/_loader.scss +1 -1
  370. package/{scss → theme}/config/mixins/_modal.scss +145 -149
  371. package/{scss → theme}/config/mixins/_motion.scss +13 -0
  372. package/{scss → theme}/config/mixins/_nav.scss +7 -7
  373. package/theme/config/mixins/_picklist.scss +66 -0
  374. package/theme/config/mixins/_popover.scss +96 -0
  375. package/{scss → theme}/config/mixins/_sidebar.scss +7 -4
  376. package/{scss → theme}/config/mixins/_sort.scss +43 -42
  377. package/{scss → theme}/config/mixins/_status-badge.scss +15 -2
  378. package/{scss → theme}/config/mixins/_table.scss +25 -14
  379. package/{scss → theme}/config/mixins/_tabs.scss +1 -1
  380. package/{scss → theme}/config/mixins/_toast.scss +174 -179
  381. package/{scss → theme}/config/mixins/_tooltip.scss +2 -2
  382. package/{scss → theme}/config/mixins/_typography.scss +16 -5
  383. package/{scss → theme}/config/mixins/_upload.scss +8 -6
  384. package/theme/ln-ashlar-core.scss +24 -0
  385. package/theme/ln-ashlar-dev.scss +66 -0
  386. package/theme/ln-ashlar-landing.scss +56 -0
  387. package/{scss/ln-ashlar.scss → theme/ln-ashlar-theme.scss} +63 -69
  388. package/theme/ln-ashlar.scss +8 -0
  389. package/theme/presentation/_bento.scss +151 -0
  390. package/theme/presentation/_cta.scss +111 -0
  391. package/theme/presentation/_effects.scss +216 -0
  392. package/theme/presentation/_features.scss +108 -0
  393. package/theme/presentation/_footer.scss +129 -0
  394. package/theme/presentation/_hero.scss +158 -0
  395. package/theme/presentation/_layout.scss +170 -0
  396. package/theme/presentation/_navbar.scss +140 -0
  397. package/theme/presentation/_pricing.scss +262 -0
  398. package/theme/presentation/_stats.scss +87 -0
  399. package/theme/presentation/_testimonials.scss +124 -0
  400. package/theme/presentation/_tokens.scss +39 -0
  401. package/theme/presentation/_typography.scss +163 -0
  402. package/{scss → theme}/utilities/_animations.scss +38 -0
  403. package/{scss → theme}/utilities/_utilities.scss +6 -0
  404. package/web-types.json +2312 -0
  405. package/js/ln-accordion/ln-accordion.js +0 -1
  406. package/js/ln-ajax/ln-ajax.js +0 -1
  407. package/js/ln-api-connector/ln-api-connector.js +0 -1
  408. package/js/ln-api-connector/src/ln-api-connector.js +0 -368
  409. package/js/ln-api-queue/ln-api-queue.js +0 -1
  410. package/js/ln-autoresize/ln-autoresize.js +0 -1
  411. package/js/ln-autosave/ln-autosave.js +0 -1
  412. package/js/ln-circular-progress/ln-circular-progress.js +0 -1
  413. package/js/ln-confirm/README.md +0 -162
  414. package/js/ln-confirm/_ln-confirm.scss +0 -24
  415. package/js/ln-confirm/ln-confirm.js +0 -1
  416. package/js/ln-core/crypto.js +0 -83
  417. package/js/ln-core/helpers.js +0 -788
  418. package/js/ln-core/index.js +0 -7
  419. package/js/ln-core/persist.js +0 -97
  420. package/js/ln-couchdb-connector/ln-couchdb-connector.js +0 -1
  421. package/js/ln-data-coordinator/ln-data-coordinator.js +0 -1
  422. package/js/ln-data-coordinator/src/data-read-policy.js +0 -18
  423. package/js/ln-data-store/ln-data-store.js +0 -1
  424. package/js/ln-date/ln-date.js +0 -1
  425. package/js/ln-date/src/ln-date.js +0 -603
  426. package/js/ln-debug/README.md +0 -58
  427. package/js/ln-debug/ln-debug.js +0 -1
  428. package/js/ln-debug/src/ln-debug.js +0 -19
  429. package/js/ln-dropdown/ln-dropdown.js +0 -1
  430. package/js/ln-dropdown/ln-dropdown.scss +0 -15
  431. package/js/ln-editor/ln-editor.js +0 -1
  432. package/js/ln-editor/ln-editor.scss +0 -43
  433. package/js/ln-external-links/ln-external-links.js +0 -1
  434. package/js/ln-fill/ln-fill.js +0 -1
  435. package/js/ln-filter/README.md +0 -189
  436. package/js/ln-filter/ln-filter-dev.scss +0 -8
  437. package/js/ln-filter/ln-filter.js +0 -1
  438. package/js/ln-filter/src/ln-filter.js +0 -419
  439. package/js/ln-form/ln-form.js +0 -1
  440. package/js/ln-http/ln-http.js +0 -1
  441. package/js/ln-link/ln-link.js +0 -1
  442. package/js/ln-list/README.md +0 -129
  443. package/js/ln-list/ln-list.js +0 -1
  444. package/js/ln-list/ln-list.scss +0 -28
  445. package/js/ln-modal/ln-modal-dev.scss +0 -13
  446. package/js/ln-modal/ln-modal.js +0 -1
  447. package/js/ln-modal/ln-modal.scss +0 -35
  448. package/js/ln-modal-coordinator/README.md +0 -99
  449. package/js/ln-modal-coordinator/ln-modal-coordinator-dev.scss +0 -8
  450. package/js/ln-modal-coordinator/ln-modal-coordinator.js +0 -1
  451. package/js/ln-nav/ln-nav.js +0 -1
  452. package/js/ln-number/README.md +0 -149
  453. package/js/ln-number/ln-number.js +0 -1
  454. package/js/ln-number/src/ln-number.js +0 -443
  455. package/js/ln-options/ln-options.js +0 -1
  456. package/js/ln-popover/ln-popover.js +0 -1
  457. package/js/ln-progress/ln-progress.js +0 -1
  458. package/js/ln-progress/src/ln-progress.js +0 -98
  459. package/js/ln-router/ln-router.js +0 -1
  460. package/js/ln-search/README.md +0 -158
  461. package/js/ln-search/ln-search-dev.scss +0 -8
  462. package/js/ln-search/ln-search.js +0 -1
  463. package/js/ln-search/src/ln-search.js +0 -117
  464. package/js/ln-slug/ln-slug.js +0 -1
  465. package/js/ln-sort/ln-sort.js +0 -1
  466. package/js/ln-sort/src/ln-sort.js +0 -178
  467. package/js/ln-sortable/ln-sortable.js +0 -1
  468. package/js/ln-stat/ln-stat.js +0 -1
  469. package/js/ln-table/ln-table.js +0 -1
  470. package/js/ln-table/ln-table.scss +0 -11
  471. package/js/ln-table-coordinator/README.md +0 -73
  472. package/js/ln-table-coordinator/ln-table-coordinator.js +0 -1
  473. package/js/ln-table-coordinator/src/ln-table-coordinator.js +0 -160
  474. package/js/ln-tabs/ln-tabs-dev.scss +0 -18
  475. package/js/ln-tabs/ln-tabs.js +0 -1
  476. package/js/ln-tabs/src/ln-tabs.js +0 -188
  477. package/js/ln-time/ln-time.js +0 -1
  478. package/js/ln-toast/ln-toast.js +0 -1
  479. package/js/ln-toggle/ln-toggle.js +0 -1
  480. package/js/ln-tooltip/ln-tooltip.js +0 -1
  481. package/js/ln-tooltip/ln-tooltip.scss +0 -9
  482. package/js/ln-translations/ln-translations.js +0 -1
  483. package/js/ln-upload/README.md +0 -255
  484. package/js/ln-upload/ln-upload.js +0 -1
  485. package/js/ln-upload/ln-upload.scss +0 -20
  486. package/js/ln-upload/src/ln-upload.js +0 -423
  487. package/js/ln-validate/ln-validate.js +0 -1
  488. package/scss/components/_button.scss +0 -20
  489. package/scss/components/_confirm.scss +0 -5
  490. package/scss/components/_form.scss +0 -107
  491. package/scss/components/_status-badge.scss +0 -4
  492. package/scss/components/_toast.scss +0 -68
  493. package/scss/components/_upload.scss +0 -51
  494. package/scss/config/_theme.scss +0 -216
  495. package/scss/config/mixins/_btn.scss +0 -179
  496. package/scss/config/mixins/_confirm.scss +0 -31
  497. package/scss/config/mixins/_dropdown.scss +0 -141
  498. package/scss/config/mixins/_popover.scss +0 -64
  499. package/scss/ln-ashlar-dev.scss +0 -39
  500. /package/{js → components}/ln-core/positioning.js +0 -0
  501. /package/{js → components}/ln-core/reactive.js +0 -0
  502. /package/{js → components}/ln-filter/ln-filter.scss +0 -0
  503. /package/{js → components}/ln-icon/ln-icon.js +0 -0
  504. /package/{js → components}/ln-icon/src/ln-icon.js +0 -0
  505. /package/{js → components}/ln-search/ln-search.scss +0 -0
  506. /package/{js → components}/ln-toast/template.html +0 -0
  507. /package/{scss → theme}/components/_accordion.scss +0 -0
  508. /package/{scss → theme}/components/_ajax.scss +0 -0
  509. /package/{scss → theme}/components/_alert.scss +0 -0
  510. /package/{scss → theme}/components/_avatar.scss +0 -0
  511. /package/{scss → theme}/components/_breadcrumbs.scss +0 -0
  512. /package/{scss → theme}/components/_card.scss +0 -0
  513. /package/{scss → theme}/components/_chip.scss +0 -0
  514. /package/{scss → theme}/components/_circular-progress.scss +0 -0
  515. /package/{scss → theme}/components/_editor.scss +0 -0
  516. /package/{scss → theme}/components/_empty-state.scss +0 -0
  517. /package/{scss → theme}/components/_filter.scss +0 -0
  518. /package/{scss → theme}/components/_link.scss +0 -0
  519. /package/{scss → theme}/components/_loader.scss +0 -0
  520. /package/{scss → theme}/components/_modal.scss +0 -0
  521. /package/{scss → theme}/components/_nav.scss +0 -0
  522. /package/{scss → theme}/components/_page-header.scss +0 -0
  523. /package/{scss → theme}/components/_popover.scss +0 -0
  524. /package/{scss → theme}/components/_progress.scss +0 -0
  525. /package/{scss → theme}/components/_prose.scss +0 -0
  526. /package/{scss → theme}/components/_scrollbar.scss +0 -0
  527. /package/{scss → theme}/components/_sections.scss +0 -0
  528. /package/{scss → theme}/components/_sidebar.scss +0 -0
  529. /package/{scss → theme}/components/_stat-card.scss +0 -0
  530. /package/{scss → theme}/components/_stepper.scss +0 -0
  531. /package/{scss → theme}/components/_timeline.scss +0 -0
  532. /package/{scss → theme}/components/_tooltip.scss +0 -0
  533. /package/{scss → theme}/components/_translations.scss +0 -0
  534. /package/{scss → theme}/config/_icons.scss +0 -0
  535. /package/{scss → theme}/config/_mixins.scss +0 -0
  536. /package/{scss → theme}/config/mixins/_ajax.scss +0 -0
  537. /package/{scss → theme}/config/mixins/_avatar.scss +0 -0
  538. /package/{scss → theme}/config/mixins/_breadcrumbs.scss +0 -0
  539. /package/{scss → theme}/config/mixins/_breakpoints.scss +0 -0
  540. /package/{scss → theme}/config/mixins/_chip.scss +0 -0
  541. /package/{scss → theme}/config/mixins/_circular-progress.scss +0 -0
  542. /package/{scss → theme}/config/mixins/_display.scss +0 -0
  543. /package/{scss → theme}/config/mixins/_empty-state.scss +0 -0
  544. /package/{scss → theme}/config/mixins/_focus.scss +0 -0
  545. /package/{scss → theme}/config/mixins/_interaction.scss +0 -0
  546. /package/{scss → theme}/config/mixins/_kbd.scss +0 -0
  547. /package/{scss → theme}/config/mixins/_link.scss +0 -0
  548. /package/{scss → theme}/config/mixins/_page-header.scss +0 -0
  549. /package/{scss → theme}/config/mixins/_position.scss +0 -0
  550. /package/{scss → theme}/config/mixins/_progress.scss +0 -0
  551. /package/{scss → theme}/config/mixins/_prose.scss +0 -0
  552. /package/{scss → theme}/config/mixins/_shadows.scss +0 -0
  553. /package/{scss → theme}/config/mixins/_sizing.scss +0 -0
  554. /package/{scss → theme}/config/mixins/_spacing.scss +0 -0
  555. /package/{scss → theme}/config/mixins/_stat-card.scss +0 -0
  556. /package/{scss → theme}/config/mixins/_stepper.scss +0 -0
  557. /package/{scss → theme}/config/mixins/_timeline.scss +0 -0
  558. /package/{scss → theme}/config/mixins/_transitions.scss +0 -0
  559. /package/{scss → theme}/config/mixins/_translations.scss +0 -0
  560. /package/{scss → theme}/tabler-icons.txt +0 -0
@@ -0,0 +1,216 @@
1
+ # ln-confirm
2
+
3
+ > Applied directly to `<button data-ln-confirm>` or `<a data-ln-confirm>`. On the first `click`, it calls
4
+ > `e.preventDefault()`, sets `data-ln-confirm-state="confirming"`, unhides `[data-ln-confirm-active]` (or swaps text),
5
+ > and starts a `setTimeout`. A second `click` before timeout lets the native event proceed; if the timer fires first,
6
+ > it clears the attribute and restores the original DOM content.
7
+
8
+ ---
9
+
10
+ ## 🧭 Philosophy & Architecture
11
+
12
+ 1. **In-Place Morphing:** Instead of launching heavy, separate dialogs or using frozen, unstyleable `window.confirm()` scripts, confirmation lives **directly on the target button**. It preserves structural styling while swapping labels, child states or the icon in place.
13
+ 2. **Platform Event Release:** `ln-confirm` does not implement a custom `accept` handler. The acceptance is the standard platform `click` event. On the second click, the component steps out of the way of the *default action* — form submissions (`type="submit"`), links (`href`), or custom AJAX click listeners execute natively. It does **not** step out of the way of propagation: the click stops at the button on both clicks, so an ancestor click surface never sees it.
14
+ 3. **Graceful Auto-Revert:** The gate is timed. When armed, a countdown timer is scheduled. If a second click does not arrive within the window, the button cleanly reverts to its idle text or icon state.
15
+
16
+ ---
17
+
18
+ ## 📦 Minimal Blueprint
19
+
20
+ ### Text-Button Mode
21
+
22
+ ```html
23
+ <button data-ln-confirm="Are you sure you want to delete?">Delete account</button>
24
+ ```
25
+
26
+ On click, the text replaces with the confirmation prompt in-place, and the button accent shifts to error red.
27
+
28
+ ### Icon-Only Mode
29
+
30
+ ```html
31
+ <button aria-label="Delete item" data-ln-confirm="Confirm delete?">
32
+ <svg class="ln-icon"><use href="#ln-icon-trash"></use></svg>
33
+ </button>
34
+ ```
35
+
36
+ ### Two-Element Mode (Recommended for rich content)
37
+
38
+ ```html
39
+ <button class="btn btn-danger" data-ln-confirm>
40
+ <!-- Idle state -->
41
+ <span data-ln-confirm-idle>
42
+ <svg class="ln-icon"><use href="#ln-icon-trash"></use></svg>
43
+ Delete Selected (<span data-ln-table-selected></span>)
44
+ </span>
45
+ <!-- Active (Confirming) state -->
46
+ <span data-ln-confirm-active hidden>
47
+ Are you sure?
48
+ </span>
49
+ </button>
50
+ ```
51
+
52
+ On click, the idle content hides and the active content unhides, without mutating or destroying the button's internal DOM nodes (such as the icon or selection span).
53
+
54
+ ---
55
+
56
+ ## 🛠️ Declarative API Contract
57
+
58
+
59
+ ### HTML Attributes
60
+
61
+ | Attribute | Elements | Description |
62
+ | :--- | :--- | :--- |
63
+ | `data-ln-confirm="Prompt"` | `<button>`, `<a>` | Action gate marker. Empty value defaults to `"Confirm?"` (in legacy mode). If using Two-Element Mode, this value is left blank. |
64
+ | `data-ln-confirm-timeout="3"` | `<button>`, `<a>` | Auto-revert delay in seconds (default `3`). |
65
+ | `data-ln-confirm-state="confirming"` | `<button>` (auto) | Managed state. Set during active confirmation; acts as public CSS hook. |
66
+ | `data-ln-confirm-announcer` | injected `<span>` (auto) | Marker on the transient `role="alert"` node that speaks the prompt in icon-only mode. |
67
+ | `data-ln-confirm-idle` | Any child | Defines the idle state layout/content (button icon/text) in Two-Element Mode. |
68
+ | `data-ln-confirm-active` | Any child | Defines the confirmation prompt content in Two-Element Mode. |
69
+
70
+ ---
71
+
72
+ ### JS API
73
+
74
+ Access the confirmation instance directly via the `lnConfirm` property on the button element:
75
+
76
+ ```javascript
77
+ const button = document.getElementById('delete-btn');
78
+
79
+ // 1. Check if armed (live read-only getter over data-ln-confirm-state)
80
+ if (button.lnConfirm.confirming) { ... }
81
+
82
+ // 2. Disarm immediately, restore visual states, and unbind listeners
83
+ button.lnConfirm.destroy();
84
+ ```
85
+
86
+ ---
87
+
88
+ ## ⚡ DOM Events
89
+
90
+ `ln-confirm` dispatches exactly one event during its lifecycle:
91
+
92
+ | Event | Bubbles | Payload | Description |
93
+ | :--- | :--- | :--- | :--- |
94
+ | `ln-confirm:waiting` | Yes | `{ target }` | Fires on first click, right after the button arms. Useful for telemetry. |
95
+
96
+ *Note: There is no `accept` event. Code execution on accept belongs on standard browser `click` or form `submit` handlers.*
97
+
98
+ ---
99
+
100
+ ## ⚠️ Common Pitfalls
101
+
102
+ - **Listening for an `:accept` event:** There is no `ln-confirm:accept`. Destructive logic belongs in the button's native click handler or form submit listener — which are automatically gated.
103
+ - **Double-Click Protection:** Once the second click executes the target action, the button returns to idle. If your custom AJAX handler takes time, the user can click again and execute duplicate actions. Disable the button on submit:
104
+ ```javascript
105
+ form.addEventListener('submit', () => submitButton.disabled = true);
106
+ ```
107
+ - **GET Request Navigation (`<a>`):** While the script works on links, performing destructive actions via HTTP GET is a security risk (crawlers and pre-fetchers can trigger deletes). Always use `<form method="POST">` with submit buttons instead.
108
+ - **Attachment Order:** `ln-confirm` intercepts first clicks via `stopImmediatePropagation()`. If custom click handlers are bound *before* the bundle loads, they will run on the first click anyway. Ensure scripts are defer-loaded.
109
+ - **Bulk Actions & High-Impact Operations:** `ln-confirm` is strictly for **single-element, low-impact actions** (e.g. deleting a single table row). Bulk operations (e.g. "Delete selected users") must use a proper confirmation modal (`ln-modal`) that lists affected resources and offers explicit "Confirm" / "Cancel" buttons.
110
+
111
+ ---
112
+
113
+ ## 🔧 Internals
114
+
115
+ Source: `components/ln-confirm/ln-confirm.js`. Imports nothing from other components, consumes no `ln-*` event, and emits nothing the library listens to. Its entire contract is the platform `click` sequence on its own button.
116
+
117
+ ### Two-click flow
118
+
119
+ The click handler branches on `this.confirming`.
120
+
121
+ **First click** (`confirming === false`) — arm:
122
+ - `preventDefault()` blocks the platform action (submit / navigate).
123
+ - `stopImmediatePropagation()` stops *later* same-element listeners, so a project's own analytics/validation click handler does not fire on the arming click — only on the second, accepting click. Listeners bound *before* ln-confirm still run, which is why the bundle must be defer-loaded.
124
+ - `_enterConfirm()`: set `confirming`, write `data-ln-confirm-state="confirming"` (CSS hook), swap the button to its confirm presentation (see Modes), schedule the auto-revert timer, dispatch `ln-confirm:waiting`.
125
+
126
+ **Second click** (`confirming === true`) — accept:
127
+ - No `preventDefault` — the click runs its native default (form submit, link nav, existing handler) unmodified. That is the whole design: insert a checkpoint, then step out.
128
+ - `stopPropagation()` — the click is contained at the button, exactly as on the first click. Without it the accepting click reaches ancestor click surfaces (a clickable card, a row handler) and fires *their* action alongside the confirmed one. Deliberately **not** `stopImmediatePropagation`: same-element listeners are the accept path and must run.
129
+ - `_reset()` runs **synchronously before the handler returns**, so the button is visually reverted in the same frame the action proceeds — no flash of the armed state. A `_submitted` flag guards against a synthetic re-entrant click inside the same handler.
130
+
131
+ Containment covers listener-based ancestors. It does not cover an ancestor `<a href>`: navigation is activation behavior, cancelled only by `preventDefault` — which would also cancel the confirmed action. Don't nest the button inside the anchor; see [ln-link](../ln-link/README.md), which skips clicks originating from `button`.
132
+
133
+ There is deliberately no `ln-confirm:accept` event and no second-click cancel signal — "accept" is just the native click; listen on the form `submit`, the link, or the button `click`.
134
+
135
+ ### Attribute contract
136
+
137
+ The `ATTRIBUTES` table is the single source of truth for the host attributes. Each entry
138
+ with a `prop` becomes a **live getter** via `defineAttrs` — `confirmText`, `timeout` and
139
+ `confirming` read the DOM on every access, so nothing is copied into instance state and
140
+ there is no sync step. The getters have no setter; assigning to them throws.
141
+
142
+ `data-ln-confirm` and `data-ln-confirm-timeout` are therefore read at the moment they are
143
+ used — the prompt when the button arms, the timeout when `_startTimer` schedules the
144
+ revert. Changing the timeout while armed does not affect the already-running timer.
145
+
146
+ No entry declares an `effect`, so the component is deliberately non-reactive: the shared
147
+ observer watches `data-ln-confirm` for instance creation only, and editing any of these
148
+ attributes never runs component code on its own.
149
+
150
+ `originalText` is the one genuine snapshot — it is `dom.textContent.trim()` captured at
151
+ construction, not an attribute, and is what `_reset` restores. Text mode therefore reverts
152
+ to the label the button had when it was hydrated; use Two-Element mode for labels that
153
+ change at runtime.
154
+
155
+ ### Modes
156
+
157
+ - **Two-Element (recommended):** if the button contains `[data-ln-confirm-idle]` and `[data-ln-confirm-active]`, the component only toggles their `hidden` attribute — no DOM mutation, so inner icons / selection-count spans survive and all text stays authored in HTML.
158
+ - **Legacy text:** no child markers → `dom.textContent` is swapped to `confirmText` and restored on revert.
159
+ - **Icon-only:** fires when `originalText === ''` **and** a `svg.ln-icon use` exists at confirm time (checked fresh, to handle async-rendered icons). Swaps `<use href>` to `#ln-icon-check` (ln-icon fetches it on demand) and handles a11y (below). Everything is restored symmetrically in `_reset`.
160
+
161
+ ### Icon-only accessibility
162
+
163
+ The icon swap is silent to AT and there is no visible text to read. So the icon branch:
164
+ 1. swaps `aria-label` to `confirmText` (original captured, restored on reset), and
165
+ 2. appends a transient `<span data-ln-confirm-announcer role="alert">` carrying the prompt,
166
+ removed again in `_reset`.
167
+
168
+ `role="alert"` is its own assertive live region, which is why this branch deliberately does
169
+ **not** also set `aria-live` on the button — a live region nested inside a live region gets
170
+ announced twice. The two-element branch does still set `aria-live="polite"`, because there
171
+ the button's own content changes (`hidden` flips) and nothing is injected.
172
+
173
+ The announcer is hidden by a co-located rule on `[data-ln-confirm-announcer]` rather than
174
+ by `.sr-only`: this component's SCSS ships in `ln-ashlar-core.css` and `.sr-only` does not,
175
+ so a core-only consumer would otherwise see the prompt printed inside the button.
176
+
177
+ Text mode needs neither: `textContent` *is* the accessible name, and changing it is itself
178
+ the announcement.
179
+
180
+ ### CSS hooks
181
+
182
+ Co-located SCSS carries two functional rules. This file ships in the **core** bundle, so
183
+ neither may lean on theme tokens or theme utilities:
184
+
185
+ ```scss
186
+ [data-ln-confirm] [hidden] { display: none; }
187
+ [data-ln-confirm-announcer] { /* visually hidden, no theme dependency */ }
188
+ ```
189
+
190
+ The first is the П4 hiding contract: native `hidden` is the mechanism — `_enterConfirm` and
191
+ `_reset` toggle it on the idle/active children — and the rule backs the UA default up at
192
+ (0,2,0) so a `display` set on a child cannot defeat it. There is deliberately no second,
193
+ state-keyed rule performing the same hiding. A two-element button whose
194
+ `[data-ln-confirm-active]` is missing `hidden` in the authored markup is a markup bug, and
195
+ `ln-confirm-dev.scss` says so under `[data-ln-debug]` instead of silently papering over it.
196
+
197
+ The single themed rule rebinds the accent token while armed:
198
+
199
+ ```scss
200
+ // theme/components/_confirm.scss
201
+ [data-ln-confirm-state="confirming"] { --color-primary: var(--color-error); }
202
+ ```
203
+
204
+ `theme/base/_global.scss` documents this as *the* way to express a colour variant, so a
205
+ button carrying `@mixin btn` — including `button[type="submit"]` — turns red while armed and
206
+ theme overrides keep working. A bare `<button>` runs only `@mixin button-base`, whose
207
+ `color: var(--btn-fg)` never reads `--color-primary`; it has no variant to recolour, so its
208
+ armed signal is the icon swap alone. That is deliberate, not an oversight.
209
+
210
+ `ln-confirm` renders no bubble, no tooltip and no overlay, and therefore needs no ancestor
211
+ to relax `overflow`. A button that also wants a tooltip composes
212
+ [ln-tooltip](../ln-tooltip/README.md) alongside it.
213
+
214
+ ### Destroy
215
+
216
+ `destroy()` is idempotent, calls `_reset()` **first** (so a destroy-while-armed clears the pending timer and visual state), then unbinds the listener and deletes `el.lnConfirm`. It does not remove `data-ln-confirm` — the caller owns the attribute, so a later observer rescan can re-create the instance.
@@ -0,0 +1,24 @@
1
+ @use '../../theme/config/mixins' as *;
2
+
3
+ [data-ln-debug] {
4
+ // 1. Two-Element Mode Incomplete: if [data-ln-confirm-idle] is present, [data-ln-confirm-active] is required
5
+ [data-ln-confirm]:has([data-ln-confirm-idle]):not(:has([data-ln-confirm-active])) {
6
+ @include dev-inline-error("ln-confirm two-element mode is missing [data-ln-confirm-active]");
7
+ }
8
+
9
+ // 2. Two-Element Mode Incomplete: if [data-ln-confirm-active] is present, [data-ln-confirm-idle] is required
10
+ [data-ln-confirm]:has([data-ln-confirm-active]):not(:has([data-ln-confirm-idle])) {
11
+ @include dev-inline-error("ln-confirm two-element mode is missing [data-ln-confirm-idle]");
12
+ }
13
+
14
+ // 3. Confirm Empty Message: empty string without two-element mode
15
+ [data-ln-confirm=""]:not(:has([data-ln-confirm-idle])):not(:has([data-ln-confirm-active])) {
16
+ @include dev-inline-error("data-ln-confirm has empty prompt and no idle/active child elements");
17
+ }
18
+
19
+ // 4. Two-Element Mode: the active child must carry `hidden` in the authored markup,
20
+ // otherwise both labels render at rest
21
+ [data-ln-confirm]:not([data-ln-confirm-state="confirming"]) [data-ln-confirm-active]:not([hidden]) {
22
+ @include dev-inline-error("ln-confirm [data-ln-confirm-active] is missing the hidden attribute");
23
+ }
24
+ }
@@ -0,0 +1 @@
1
+ (function(){"use strict";function L(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function C(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let r=null;for(let i=1;i<t.length;i++)if(t[i]&&t[i].nodeType===1){r=t[i];break}if(!C(r))return}e.apply(console,t)}}function O(e,t,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,r),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:r}))}function m(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){m(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function H(e){return!!(!e||e.ctrlKey||e.metaKey||e.shiftKey||e.altKey||typeof e.button=="number"&&e.button!==0)}const I={};function U(e,t){I[e]=t}function V(e){return I[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=U,window.lnCore.getDataMapper=V);function K(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,m(function(){new MutationObserver(function(){O(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const D={};function P(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];D[n]=t}function Q(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return D[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=P,window.lnCore.getLocaleFallback=Q,window.lnCore.ensureLocaleObserver=K);const y={};function J(e,t){y[e]||(y[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=y[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function $(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let l=0;l<n.length;l++){const a=n[l],s=a.getAttribute("data-ln-field");t[s]!=null&&(a.textContent=t[s])}const r=e.querySelectorAll("[data-ln-attr]");for(let l=0;l<r.length;l++){const a=r[l],s=a.getAttribute("data-ln-attr").split(",");for(let d=0;d<s.length;d++){const f=s[d].trim().split(":");if(f.length!==2)continue;const c=f[0].trim(),u=f[1].trim();t[u]!=null&&a.setAttribute(c,t[u])}}const i=e.querySelectorAll("[data-ln-show]");for(let l=0;l<i.length;l++){const a=i[l],s=a.getAttribute("data-ln-show");s in t&&a.classList.toggle("hidden",!t[s])}const o=e.querySelectorAll("[data-ln-class]");for(let l=0;l<o.length;l++){const a=o[l],s=a.getAttribute("data-ln-class").split(",");for(let d=0;d<s.length;d++){const f=s[d].trim().split(":");if(f.length!==2)continue;const c=f[0].trim(),u=f[1].trim();u in t&&a.classList.toggle(c,!!t[u])}}return e}function G(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let r=0;r<n.length;r++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[r],t??null),n[r].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)$(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function q(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const o=n.currentNode;o.textContent.indexOf("{{")!==-1&&(o.textContent=o.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(l,a){return t[a]!==void 0?t[a]:""}))}const r=function(o,l){return t[l]!==void 0?t[l]:""},i=Array.from(e.querySelectorAll("*"));e.nodeType===1&&i.push(e);for(let o=0;o<i.length;o++){const l=i[o],a=l.attributes;for(let s=0;s<a.length;s++){const d=a[s];d.value.indexOf("{{")!==-1&&l.setAttribute(d.name,d.value.replace(/\{\{\s*(\w+)\s*\}\}/g,r))}}return e}function X(e,t,n,r,i,o){const l={};for(let s=0;s<e.children.length;s++){const d=e.children[s],f=d.getAttribute("data-ln-render-key");f&&(l[f]=d)}const a=document.createDocumentFragment();for(let s=0;s<t.length;s++){const d=t[s],f=String(r(d));let c=l[f];if(c)i(c,d,s);else{const u=J(n,o);if(!u||(q(u,d),c=u.firstElementChild,!c))continue;c.setAttribute("data-ln-render-key",f),i(c,d,s)}a.appendChild(c)}e.textContent="",e.appendChild(a)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=q,window.lnCore.fill=$,window.lnCore.lnFill=G,window.lnCore.renderList=X);function M(e,t,n){const r=e.getAttribute(t);return r===null?n:r}function z(e,t,n){const r=parseInt(e.getAttribute(t),10);return isNaN(r)?n:r}function Y(e,t,n=!1){const r=e.getAttribute(t);if(r===null)return!!n;const i=r.trim().toLowerCase();return!(i==="false"||i==="0")}function Z(e,t){return(e.getAttribute(t)||"").split(",").map(n=>n.trim()).filter(Boolean)}const A=new Map;function ee(e,t){const n=(e?e.join("|"):"")+"::"+t;if(A.has(n))return A.get(n);const r=new Set(e||[]),i=function(o,l){const a=o.getAttribute(l);return a!==null&&r.has(a)?a:t};return A.set(n,i),i}function te(e,t,n){const r=parseFloat(e.getAttribute(t));return isNaN(r)?n:r}function ne(e,t,n){const r=e.getAttribute(t);if(!r)return n;try{return JSON.parse(r)}catch{return n}}function N(e,t,n,r,i){if(!e||t===null)return!0;const o=r||"ln-component",l=e.type;if(l==="trigger"||l==="marker"||l==="string"||l==="list"||!l||t===""&&e.fallback!==void 0)return!0;const a=s=>{i?console.warn(s,i):console.warn(s)};if(l==="boolean"){const s=t.trim().toLowerCase();return s!==""&&s!=="true"&&s!=="false"&&s!=="1"&&s!=="0"?(a(`[${o}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(l==="enum"){const s=e.values||[];return s.includes(t)?!0:(a(`[${o}] Invalid value "${t}" for attribute "${n}". Allowed: ${s.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(l==="integer"){if(!/^-?\d+$/.test(t))return a(`[${o}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const s=parseInt(t,10);return e.min!==void 0&&s<e.min?(a(`[${o}] Value ${s} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&s>e.max?(a(`[${o}] Value ${s} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(l==="float")return isNaN(Number(t))?(a(`[${o}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(l==="json")try{return JSON.parse(t),!0}catch(s){return a(`[${o}] Invalid JSON for attribute "${n}": ${s.message}. Fallback: ${e.fallback}.`),!1}return!0}function re(e,t,n){for(const r in n){const[i,o,l]=n[r];Object.defineProperty(e,r,{get:function(){return i(t,o,l)},enumerable:!0,configurable:!0})}return e}function ie(e){const t={};for(const n in e){const r=e[n];if(!r||!r.prop)continue;let i=r.read;if(!i&&r.type)switch(r.type){case"enum":i=ee(r.values,r.fallback);break;case"integer":i=z;break;case"float":i=te;break;case"boolean":i=Y;break;case"list":i=Z;break;case"json":i=ne;break;case"string":default:i=M;break}i||(i=M),t[r.prop]=[i,n,r.fallback]}return t}function oe(e){const t={};for(const n in e){const r=e[n];r&&r.effect&&(t[n]=r.effect)}return Object.keys(t).length?t:null}function le(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}function v(e,t,n,r){if(e.nodeType!==1)return;const o=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",l=Array.from(e.querySelectorAll(o));e.matches&&e.matches(o)&&l.push(e);for(const a of l)if(!a[n]){window.lnCore._persistSink&&a.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(a,t);try{a[n]=new r(a)}catch(s){console.error("["+n+"] init failed",a,s)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function se(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function ae(e){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(e):setTimeout(e,0)):e()}function R(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function ce(e){const t=R(),n=e.observed||[];for(let r=0;r<n.length;r++){const i=n[r];t.byAttr.has(i)||t.byAttr.set(i,[]),t.byAttr.get(i).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const r in e.attributes){t.byDeclaredAttr.has(r)||t.byDeclaredAttr.set(r,[]);const i=t.byDeclaredAttr.get(r);i.some(o=>o.componentTag===e.componentTag)||i.push({spec:e.attributes[r],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const r=le(e);if(r===null)t.reactiveWildcard.push(e);else for(const i of r)t.byReactive.has(i)||t.byReactive.set(i,[]),t.byReactive.get(i).push(e)}e.persist&&t.persist.push(e)}function F(e,t,n,r){for(let i=0;i<e.length;i++){const o=e[i];if(!t[o.attribute])continue;const l=o.effects&&o.effects[n];l?l(t,n,r):o.onAttrChange&&(!o.declared||o.declared.has(n))&&o.onAttrChange(t,n,r)}}function ue(e){const t=e.target,n=e.attributeName;if(e.oldValue===t.getAttribute(n))return;const r=R(),i=r.byAttr.get(n);if(L()&&r.byDeclaredAttr&&r.byDeclaredAttr.has(n)&&C(t)){const o=r.byDeclaredAttr.get(n),l=t.getAttribute(n);for(let a=0;a<o.length;a++)N(o[a].spec,l,n,o[a].componentTag,t)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||i)&&window.lnCore._debugSink("attr",n,t,{oldValue:e.oldValue,newValue:t.getAttribute(n)}),n.indexOf("data-ln-")===0){const o=r.byReactive.get(n);o&&F(o,t,n,e.oldValue),r.reactiveWildcard.length&&F(r.reactiveWildcard,t,n,e.oldValue)}if(i)for(let o=0;o<i.length;o++){const l=i[o];if(l.handler){l.handler(t,n,e.oldValue);continue}l.onAttributeChange&&t[l.attribute]?l.onAttributeChange(t,n):(v(t,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(t))}}function de(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,m(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{ue(t[n])}catch(r){console.error("[ln-core] mutation handler failed",t[n].target,r)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function B(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function fe(e){const t=B();if(t.length){if(e.target)for(let n=0;n<t.length;n++){const r=t[n];if(r.onSubtreeChange){const i=r.query,o=e.target.nodeType===1?e.target.matches(i)?e.target:e.target.closest(i):e.target.parentElement?e.target.parentElement.closest(i):null;o&&r.onSubtreeChange(o,e)}}for(let n=0;n<e.addedNodes.length;n++){const r=e.addedNodes[n];if(r.nodeType===1)for(let i=0;i<t.length;i++){const o=t[i];v(r,o.selector,o.attribute,o.ComponentFn),o.onInit&&o.onInit(r)}}for(let n=0;n<e.removedNodes.length;n++){const r=e.removedNodes[n];if(r.nodeType===1)for(let i=0;i<t.length;i++){const o=t[i],l=o.query,a=Array.from(r.querySelectorAll(l));r.matches&&r.matches(l)&&a.push(r);for(let s=0;s<a.length;s++){const d=a[s];if(!document.contains(d)){const f=d[o.attribute];if(f&&typeof f.destroy=="function")try{f.destroy()}catch(c){console.error("["+o.attribute+"] destroy failed",d,c)}delete d[o.attribute]}}}}}}function he(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,m(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++){const r=t[n];if(r.type==="childList")try{fe(r)}catch(i){console.error("[ln-core] lifecycle handler failed",r.target,i)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function we(e,t,n,r,i={}){const o=i.extraAttributes||[],l=i.onAttributeChange||null,a=i.onSubtreeChange||null,s=i.onInit||null,d=i.onAttrChange||null,f=i.effects||null,c=i.attributes||null,u=c?oe(c):f,h=c?new Set(Object.keys(c)):null,b=i.persist||null;function p(k){const w=k||document.body;if(v(w,e,t,n),c&&L())for(const g in c){const Te=c[g],S=Array.from(w.querySelectorAll("["+g+"]"));w.matches&&w.matches("["+g+"]")&&S.push(w);for(let E=0;E<S.length;E++){const x=S[E];C(x)&&N(Te,x.getAttribute(g),g,r,x)}}s&&s(w)}const T=[];if(e.indexOf("[")!==-1){const k=/\[([\w-]+)/g;let w;for(;(w=k.exec(e))!==null;)T.push(w[1])}else T.push(e);ce({selector:e,attribute:t,componentTag:r,attributes:c,ComponentFn:n,onInit:s,observed:T.concat(o),onAttributeChange:l,onAttrChange:d,effects:u,declared:h,persist:b}),de();const _e=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";B().push({selector:e,attribute:t,ComponentFn:n,onInit:s,onSubtreeChange:a,query:_e}),he(),window[t]=p;function W(){se()>0?ae(function(){p(document.body)}):p(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",W):W(),p}function j(e){return(e||"").replace(/^#/,"")}function _(e){const t=e===void 0?location.hash:e,n={},r=j(t);if(!r)return n;const i=r.split("&");for(let o=0;o<i.length;o++){const l=i[o];if(!l)continue;const a=l.indexOf(":"),s=a>-1?l.slice(0,a):l,d=a>-1?l.slice(a+1):"";if(s)try{n[s]=decodeURIComponent(d)}catch{n[s]=d}}return n}function be(e){if(!e)return null;const t=_();return e in t?t[e]:null}function ge(e,t){if(!e)return;const n=_();t==null?delete n[e]:n[e]=String(t);const i=Object.keys(n).map(function(o){const l=n[o];return l===""?o:o+":"+encodeURIComponent(l)}).join("&");j(location.hash)!==i&&(location.hash=i)}function me(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function pe(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const r=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return r?t?r+"-"+t:r:t||null}function Ce(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function ye(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function Ae(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function ve(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),r=e.slice(t+1),i=r?r.split(",").map(function(o){try{return decodeURIComponent(o)}catch{return o}}).filter(Boolean):[];return{key:n,values:i}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=_,window.lnCore.hashGet=be,window.lnCore.hashSet=ge,window.lnCore.hashLinkClick=me,window.lnCore.resolveHashNamespace=pe,window.lnCore.hashSortEncode=Ce,window.lnCore.hashSortDecode=ye,window.lnCore.hashFilterEncode=Ae,window.lnCore.hashFilterDecode=ve),(function(){const e="data-ln-confirm",t="lnConfirm",n="data-ln-confirm-state",r="data-ln-confirm-announcer";if(window[t]!==void 0)return;function o(c,u,h){return c.getAttribute(u)||h}function l(c,u,h){const b=parseFloat(c.getAttribute(u));return isNaN(b)||b<=0?h:b}function a(c){const u=document.createElement("span");return u.setAttribute(r,""),u.setAttribute("role","alert"),u.textContent=c,u}const s={"data-ln-confirm":{prop:"confirmText",type:"string",read:o,fallback:"Confirm?",description:"Prompt text or confirmation action trigger"},"data-ln-confirm-timeout":{prop:"timeout",type:"float",read:l,fallback:3,min:.1,description:"Confirmation timeout in seconds before reverting"},"data-ln-confirm-state":{prop:"confirming",type:"enum",values:["confirming"],read:(c,u)=>c.getAttribute(u)==="confirming",description:'Active confirmation state marker on button ("confirming")'}},d=ie(s);function f(c){this.dom=c,re(this,c,d),this.revertTimer=null,this._submitted=!1,this.idleEl=c.querySelector("[data-ln-confirm-idle]"),this.activeEl=c.querySelector("[data-ln-confirm-active]"),this.isTwoElementMode=!!(this.idleEl||this.activeEl),this.originalText=this.isTwoElementMode?"":c.textContent.trim();const u=this;return this._onClick=function(h){if(!H(h))if(!u.confirming)h.preventDefault(),h.stopImmediatePropagation(),u._enterConfirm();else{if(u._submitted)return;u._submitted=!0,h.stopPropagation(),u._reset()}},c.addEventListener("click",this._onClick),this}f.prototype._enterConfirm=function(){if(this.dom.setAttribute(n,"confirming"),this.originalAriaLabel=this.dom.getAttribute("aria-label"),this.originalAriaLive=this.dom.getAttribute("aria-live"),this.isTwoElementMode){this.idleEl&&this.idleEl.setAttribute("hidden","true"),this.activeEl&&this.activeEl.removeAttribute("hidden");const c=this.activeEl?this.activeEl.textContent.trim():"";c&&(this.dom.setAttribute("aria-label",c),this.dom.setAttribute("aria-live","polite"))}else{const c=this.dom.querySelector("svg.ln-icon use");c&&this.originalText===""?(this.isIconButton=!0,this.originalIconHref=c.getAttribute("href"),c.setAttribute("href","#ln-icon-check"),this.dom.setAttribute("aria-label",this.confirmText),this.dom.appendChild(a(this.confirmText))):this.dom.textContent=this.confirmText}this._startTimer(),O(this.dom,"ln-confirm:waiting",{target:this.dom})},f.prototype._startTimer=function(){this.revertTimer&&clearTimeout(this.revertTimer);const c=this,u=this.timeout*1e3;this.revertTimer=setTimeout(function(){c._reset()},u)},f.prototype._reset=function(){if(this._submitted=!1,this.dom.removeAttribute(n),this.isTwoElementMode)this.idleEl&&this.idleEl.removeAttribute("hidden"),this.activeEl&&this.activeEl.setAttribute("hidden","true");else if(this.isIconButton){const c=this.dom.querySelector("svg.ln-icon use");c&&this.originalIconHref&&c.setAttribute("href",this.originalIconHref);const u=this.dom.querySelector("["+r+"]");u&&u.remove(),this.isIconButton=!1,this.originalIconHref=null}else this.dom.textContent=this.originalText;this.originalAriaLabel!==null&&this.originalAriaLabel!==void 0?this.dom.setAttribute("aria-label",this.originalAriaLabel):this.dom.removeAttribute("aria-label"),this.originalAriaLabel=null,this.originalAriaLive!==null&&this.originalAriaLive!==void 0?this.dom.setAttribute("aria-live",this.originalAriaLive):this.dom.removeAttribute("aria-live"),this.originalAriaLive=null,this.revertTimer&&(clearTimeout(this.revertTimer),this.revertTimer=null)},f.prototype.destroy=function(){this.dom[t]&&(this.confirming&&this._reset(),this.dom.removeEventListener("click",this._onClick),delete this.dom[t])},we(e,t,f,"ln-confirm",{attributes:s})})()})();
@@ -0,0 +1,66 @@
1
+ {
2
+ "$comment": "This file is partly generated. The $comment, component, generator, and each attribute's direction, sources, type, values, fallback, and description keys are owned by the generator and synchronized from JS source code. All other keys are preserved and safe to hand-author. Regenerate with `npm run sync:ln-schemas`.",
3
+ "component": "ln-confirm",
4
+ "generator": "scripts/sync-ln-schemas.mjs",
5
+ "attributes": {
6
+ "data-ln-confirm": {
7
+ "direction": null,
8
+ "sources": [
9
+ "ln-confirm-dev.scss",
10
+ "ln-confirm.scss",
11
+ "src/ln-confirm.js"
12
+ ],
13
+ "type": "string",
14
+ "fallback": "Confirm?",
15
+ "description": "Prompt text or confirmation action trigger"
16
+ },
17
+ "data-ln-confirm-active": {
18
+ "direction": "author",
19
+ "sources": [
20
+ "ln-confirm-dev.scss",
21
+ "src/ln-confirm.js"
22
+ ]
23
+ },
24
+ "data-ln-confirm-announcer": {
25
+ "direction": "both",
26
+ "sources": [
27
+ "ln-confirm.scss",
28
+ "src/ln-confirm.js"
29
+ ]
30
+ },
31
+ "data-ln-confirm-idle": {
32
+ "direction": "author",
33
+ "sources": [
34
+ "ln-confirm-dev.scss",
35
+ "src/ln-confirm.js"
36
+ ]
37
+ },
38
+ "data-ln-confirm-state": {
39
+ "direction": "runtime",
40
+ "sources": [
41
+ "ln-confirm-dev.scss",
42
+ "src/ln-confirm.js"
43
+ ],
44
+ "type": "enum",
45
+ "values": [
46
+ "confirming"
47
+ ],
48
+ "description": "Active confirmation state marker on button ("
49
+ },
50
+ "data-ln-confirm-timeout": {
51
+ "direction": null,
52
+ "sources": [
53
+ "src/ln-confirm.js"
54
+ ],
55
+ "type": "float",
56
+ "min": 0.1,
57
+ "description": "Confirmation timeout in seconds before reverting"
58
+ },
59
+ "data-ln-debug": {
60
+ "direction": null,
61
+ "sources": [
62
+ "ln-confirm-dev.scss"
63
+ ]
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,24 @@
1
+ // ==========================================================================
2
+ // ln-confirm — Functional Hiding Contract & Announcer
3
+ // ==========================================================================
4
+
5
+ // П4 hiding contract: native `hidden` is the mechanism — the component toggles it
6
+ // on the idle/active children. This backs up the UA default at (0,2,0) so a
7
+ // `display` set on a child cannot defeat it.
8
+ [data-ln-confirm] [hidden] {
9
+ display: none;
10
+ }
11
+
12
+ // Injected announcer. This file ships in the CORE bundle and `.sr-only` does not,
13
+ // so the hiding cannot be delegated to the theme.
14
+ [data-ln-confirm-announcer] {
15
+ position: absolute;
16
+ width: 1px;
17
+ height: 1px;
18
+ padding: 0;
19
+ margin: -1px;
20
+ overflow: hidden;
21
+ clip: rect(0, 0, 0, 0);
22
+ white-space: nowrap;
23
+ border-width: 0;
24
+ }