@livenetworks/ashlar 1.6.1 → 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 (559) 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/{js → components}/ln-confirm/README.md +69 -18
  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 -171
  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/_ln-confirm.scss +0 -24
  414. package/js/ln-confirm/ln-confirm.js +0 -1
  415. package/js/ln-core/crypto.js +0 -83
  416. package/js/ln-core/helpers.js +0 -788
  417. package/js/ln-core/index.js +0 -7
  418. package/js/ln-core/persist.js +0 -97
  419. package/js/ln-couchdb-connector/ln-couchdb-connector.js +0 -1
  420. package/js/ln-data-coordinator/ln-data-coordinator.js +0 -1
  421. package/js/ln-data-coordinator/src/data-read-policy.js +0 -18
  422. package/js/ln-data-store/ln-data-store.js +0 -1
  423. package/js/ln-date/ln-date.js +0 -1
  424. package/js/ln-date/src/ln-date.js +0 -603
  425. package/js/ln-debug/README.md +0 -58
  426. package/js/ln-debug/ln-debug.js +0 -1
  427. package/js/ln-debug/src/ln-debug.js +0 -19
  428. package/js/ln-dropdown/ln-dropdown.js +0 -1
  429. package/js/ln-dropdown/ln-dropdown.scss +0 -15
  430. package/js/ln-editor/ln-editor.js +0 -1
  431. package/js/ln-editor/ln-editor.scss +0 -43
  432. package/js/ln-external-links/ln-external-links.js +0 -1
  433. package/js/ln-fill/ln-fill.js +0 -1
  434. package/js/ln-filter/README.md +0 -189
  435. package/js/ln-filter/ln-filter-dev.scss +0 -8
  436. package/js/ln-filter/ln-filter.js +0 -1
  437. package/js/ln-filter/src/ln-filter.js +0 -419
  438. package/js/ln-form/ln-form.js +0 -1
  439. package/js/ln-http/ln-http.js +0 -1
  440. package/js/ln-link/ln-link.js +0 -1
  441. package/js/ln-list/README.md +0 -129
  442. package/js/ln-list/ln-list.js +0 -1
  443. package/js/ln-list/ln-list.scss +0 -28
  444. package/js/ln-modal/ln-modal-dev.scss +0 -13
  445. package/js/ln-modal/ln-modal.js +0 -1
  446. package/js/ln-modal/ln-modal.scss +0 -35
  447. package/js/ln-modal-coordinator/README.md +0 -99
  448. package/js/ln-modal-coordinator/ln-modal-coordinator-dev.scss +0 -8
  449. package/js/ln-modal-coordinator/ln-modal-coordinator.js +0 -1
  450. package/js/ln-nav/ln-nav.js +0 -1
  451. package/js/ln-number/README.md +0 -149
  452. package/js/ln-number/ln-number.js +0 -1
  453. package/js/ln-number/src/ln-number.js +0 -443
  454. package/js/ln-options/ln-options.js +0 -1
  455. package/js/ln-popover/ln-popover.js +0 -1
  456. package/js/ln-progress/ln-progress.js +0 -1
  457. package/js/ln-progress/src/ln-progress.js +0 -98
  458. package/js/ln-router/ln-router.js +0 -1
  459. package/js/ln-search/README.md +0 -158
  460. package/js/ln-search/ln-search-dev.scss +0 -8
  461. package/js/ln-search/ln-search.js +0 -1
  462. package/js/ln-search/src/ln-search.js +0 -117
  463. package/js/ln-slug/ln-slug.js +0 -1
  464. package/js/ln-sort/ln-sort.js +0 -1
  465. package/js/ln-sort/src/ln-sort.js +0 -178
  466. package/js/ln-sortable/ln-sortable.js +0 -1
  467. package/js/ln-stat/ln-stat.js +0 -1
  468. package/js/ln-table/ln-table.js +0 -1
  469. package/js/ln-table/ln-table.scss +0 -11
  470. package/js/ln-table-coordinator/README.md +0 -73
  471. package/js/ln-table-coordinator/ln-table-coordinator.js +0 -1
  472. package/js/ln-table-coordinator/src/ln-table-coordinator.js +0 -160
  473. package/js/ln-tabs/ln-tabs-dev.scss +0 -18
  474. package/js/ln-tabs/ln-tabs.js +0 -1
  475. package/js/ln-tabs/src/ln-tabs.js +0 -188
  476. package/js/ln-time/ln-time.js +0 -1
  477. package/js/ln-toast/ln-toast.js +0 -1
  478. package/js/ln-toggle/ln-toggle.js +0 -1
  479. package/js/ln-tooltip/ln-tooltip.js +0 -1
  480. package/js/ln-tooltip/ln-tooltip.scss +0 -9
  481. package/js/ln-translations/ln-translations.js +0 -1
  482. package/js/ln-upload/README.md +0 -255
  483. package/js/ln-upload/ln-upload.js +0 -1
  484. package/js/ln-upload/ln-upload.scss +0 -20
  485. package/js/ln-upload/src/ln-upload.js +0 -423
  486. package/js/ln-validate/ln-validate.js +0 -1
  487. package/scss/components/_button.scss +0 -20
  488. package/scss/components/_confirm.scss +0 -5
  489. package/scss/components/_form.scss +0 -107
  490. package/scss/components/_status-badge.scss +0 -4
  491. package/scss/components/_toast.scss +0 -68
  492. package/scss/components/_upload.scss +0 -51
  493. package/scss/config/_theme.scss +0 -216
  494. package/scss/config/mixins/_btn.scss +0 -179
  495. package/scss/config/mixins/_confirm.scss +0 -31
  496. package/scss/config/mixins/_dropdown.scss +0 -141
  497. package/scss/config/mixins/_popover.scss +0 -64
  498. package/scss/ln-ashlar-dev.scss +0 -39
  499. /package/{js → components}/ln-core/positioning.js +0 -0
  500. /package/{js → components}/ln-core/reactive.js +0 -0
  501. /package/{js → components}/ln-filter/ln-filter.scss +0 -0
  502. /package/{js → components}/ln-icon/ln-icon.js +0 -0
  503. /package/{js → components}/ln-icon/src/ln-icon.js +0 -0
  504. /package/{js → components}/ln-search/ln-search.scss +0 -0
  505. /package/{js → components}/ln-toast/template.html +0 -0
  506. /package/{scss → theme}/components/_accordion.scss +0 -0
  507. /package/{scss → theme}/components/_ajax.scss +0 -0
  508. /package/{scss → theme}/components/_alert.scss +0 -0
  509. /package/{scss → theme}/components/_avatar.scss +0 -0
  510. /package/{scss → theme}/components/_breadcrumbs.scss +0 -0
  511. /package/{scss → theme}/components/_card.scss +0 -0
  512. /package/{scss → theme}/components/_chip.scss +0 -0
  513. /package/{scss → theme}/components/_circular-progress.scss +0 -0
  514. /package/{scss → theme}/components/_editor.scss +0 -0
  515. /package/{scss → theme}/components/_empty-state.scss +0 -0
  516. /package/{scss → theme}/components/_filter.scss +0 -0
  517. /package/{scss → theme}/components/_link.scss +0 -0
  518. /package/{scss → theme}/components/_loader.scss +0 -0
  519. /package/{scss → theme}/components/_modal.scss +0 -0
  520. /package/{scss → theme}/components/_nav.scss +0 -0
  521. /package/{scss → theme}/components/_page-header.scss +0 -0
  522. /package/{scss → theme}/components/_popover.scss +0 -0
  523. /package/{scss → theme}/components/_progress.scss +0 -0
  524. /package/{scss → theme}/components/_prose.scss +0 -0
  525. /package/{scss → theme}/components/_scrollbar.scss +0 -0
  526. /package/{scss → theme}/components/_sections.scss +0 -0
  527. /package/{scss → theme}/components/_sidebar.scss +0 -0
  528. /package/{scss → theme}/components/_stat-card.scss +0 -0
  529. /package/{scss → theme}/components/_stepper.scss +0 -0
  530. /package/{scss → theme}/components/_timeline.scss +0 -0
  531. /package/{scss → theme}/components/_tooltip.scss +0 -0
  532. /package/{scss → theme}/components/_translations.scss +0 -0
  533. /package/{scss → theme}/config/_icons.scss +0 -0
  534. /package/{scss → theme}/config/_mixins.scss +0 -0
  535. /package/{scss → theme}/config/mixins/_ajax.scss +0 -0
  536. /package/{scss → theme}/config/mixins/_avatar.scss +0 -0
  537. /package/{scss → theme}/config/mixins/_breadcrumbs.scss +0 -0
  538. /package/{scss → theme}/config/mixins/_breakpoints.scss +0 -0
  539. /package/{scss → theme}/config/mixins/_chip.scss +0 -0
  540. /package/{scss → theme}/config/mixins/_circular-progress.scss +0 -0
  541. /package/{scss → theme}/config/mixins/_display.scss +0 -0
  542. /package/{scss → theme}/config/mixins/_empty-state.scss +0 -0
  543. /package/{scss → theme}/config/mixins/_focus.scss +0 -0
  544. /package/{scss → theme}/config/mixins/_interaction.scss +0 -0
  545. /package/{scss → theme}/config/mixins/_kbd.scss +0 -0
  546. /package/{scss → theme}/config/mixins/_link.scss +0 -0
  547. /package/{scss → theme}/config/mixins/_page-header.scss +0 -0
  548. /package/{scss → theme}/config/mixins/_position.scss +0 -0
  549. /package/{scss → theme}/config/mixins/_progress.scss +0 -0
  550. /package/{scss → theme}/config/mixins/_prose.scss +0 -0
  551. /package/{scss → theme}/config/mixins/_shadows.scss +0 -0
  552. /package/{scss → theme}/config/mixins/_sizing.scss +0 -0
  553. /package/{scss → theme}/config/mixins/_spacing.scss +0 -0
  554. /package/{scss → theme}/config/mixins/_stat-card.scss +0 -0
  555. /package/{scss → theme}/config/mixins/_stepper.scss +0 -0
  556. /package/{scss → theme}/config/mixins/_timeline.scss +0 -0
  557. /package/{scss → theme}/config/mixins/_transitions.scss +0 -0
  558. /package/{scss → theme}/config/mixins/_translations.scss +0 -0
  559. /package/{scss → theme}/tabler-icons.txt +0 -0
@@ -0,0 +1,119 @@
1
+ // ─── Windowed Store Position Index ────────────────────────────
2
+ //
3
+ // In-memory sliding-window index mapping logical positions to record IDs
4
+ // for server-side virtualization. Holds logical/grand totals, request dedup,
5
+ // stale-guard queryGen, and LRU eviction using JS Map insertion order.
6
+
7
+ export function createWindowIndex(config = {}) {
8
+ let windowSize = config.windowSize > 0 ? config.windowSize : 1000;
9
+ let pageSize = config.pageSize > 0 ? config.pageSize : 200;
10
+ let fetchDebounce = config.fetchDebounce != null ? config.fetchDebounce : 120;
11
+ const requestPage = typeof config.requestPage === 'function' ? config.requestPage : () => {};
12
+
13
+ const map = new Map(); // logicalIndex → id (LRU by insertion order)
14
+ const inflight = new Set(); // offsets currently requested
15
+ let logicalTotal = 0, grandTotal = 0, queryGen = 0, hasLoaded = false, debounceId = null;
16
+
17
+ function touch(i, id) {
18
+ map.delete(i);
19
+ map.set(i, id);
20
+ }
21
+
22
+ // Returns the ids that left residency, so the store can drop them from
23
+ // IndexedDB and windowSize bounds the records held, not just the positions.
24
+ // Only ids this index itself placed can ever be returned — a locally created
25
+ // record the server has not positioned is never in the map, so eviction can
26
+ // not reach it.
27
+ function evict() {
28
+ if (map.size <= windowSize) return [];
29
+ const dropped = [];
30
+ while (map.size > windowSize) {
31
+ const key = map.keys().next().value;
32
+ dropped.push(map.get(key));
33
+ map.delete(key);
34
+ }
35
+ // One id can occupy more than one position; it has only left residency
36
+ // once no remaining position refers to it.
37
+ const remaining = new Set(map.values());
38
+ return dropped.filter(id => !remaining.has(id));
39
+ }
40
+
41
+ function fire(offset, query) {
42
+ inflight.add(offset);
43
+ clearTimeout(debounceId);
44
+ debounceId = setTimeout(() => requestPage(offset, pageSize, query), fetchDebounce);
45
+ }
46
+
47
+ return {
48
+ get logicalTotal() { return logicalTotal; },
49
+ set logicalTotal(val) { logicalTotal = val; },
50
+ get grandTotal() { return grandTotal; },
51
+ set grandTotal(val) { grandTotal = val; },
52
+ get queryGen() { return queryGen; },
53
+ set queryGen(val) { queryGen = val; },
54
+ get size() { return map.size; },
55
+ // Whether a server ordering exists for the current query at all — false
56
+ // from reset() until the first ingest(). Distinct from a missing page.
57
+ get hasLoaded() { return hasLoaded; },
58
+
59
+ getId: i => {
60
+ if (!map.has(i)) return undefined;
61
+ const id = map.get(i);
62
+ touch(i, id);
63
+ return id;
64
+ },
65
+
66
+ ensure: (startRow, endRow, query) => {
67
+ if (!hasLoaded && !inflight.has(0)) return fire(0, query);
68
+ if (logicalTotal <= 0) return;
69
+
70
+ const start = Math.max(0, startRow);
71
+ const end = Math.min(logicalTotal, endRow);
72
+
73
+ for (let i = start; i < end; i++) {
74
+ if (!map.has(i)) {
75
+ const pageOffset = Math.floor(i / pageSize) * pageSize;
76
+ if (!inflight.has(pageOffset)) return fire(pageOffset, query);
77
+ }
78
+ }
79
+ },
80
+
81
+ ingest: (offset, ids, total, filtered, qGen) => {
82
+ if (qGen != null && qGen !== queryGen) return [];
83
+ hasLoaded = true;
84
+ if (total != null) grandTotal = total;
85
+ if (filtered != null) logicalTotal = filtered;
86
+
87
+ for (let i = 0; i < ids.length; i++) {
88
+ touch(offset + i, ids[i]);
89
+ }
90
+ inflight.delete(offset);
91
+ return evict();
92
+ },
93
+
94
+ reset: function () {
95
+ queryGen++;
96
+ this.clear();
97
+ },
98
+
99
+ clear: () => {
100
+ hasLoaded = false;
101
+ map.clear();
102
+ inflight.clear();
103
+ clearTimeout(debounceId);
104
+ },
105
+
106
+ // Returns the ids evicted by a window shrink, same contract as ingest() —
107
+ // the caller must purge them from storage.
108
+ configure: (partial = {}) => {
109
+ let evicted = [];
110
+ if (partial.windowSize > 0 && partial.windowSize !== windowSize) {
111
+ windowSize = partial.windowSize;
112
+ evicted = evict();
113
+ }
114
+ if (partial.pageSize > 0) pageSize = partial.pageSize;
115
+ if (partial.fetchDebounce >= 0) fetchDebounce = partial.fetchDebounce;
116
+ return evicted;
117
+ }
118
+ };
119
+ }
@@ -1,6 +1,9 @@
1
1
  # ln-date
2
2
 
3
- Locale-aware date formatting with native browser picker.
3
+ > Applied to an `<input type="date" data-ln-date name="...">`. On initialization, it wraps the element in a
4
+ > `<span data-ln-date-field>` containing a visible text input, a hidden native date picker, a hidden `<input type="hidden" name="...">`
5
+ > for form submission, and a calendar button. On button `click`, it calls `showPicker()` on the date picker; on text input `blur`,
6
+ > it parses the entered string, updates the hidden ISO input, and reformats the visible text.
4
7
 
5
8
  ## Usage
6
9
 
@@ -59,7 +62,9 @@ The hidden input holds the ISO date string (YYYY-MM-DD) for form submission.
59
62
 
60
63
  | Attribute | On | Description |
61
64
  |-----------|-----|-------------|
62
- | `data-ln-date` | `<input>` | Enables date formatting. Value = format (keyword or pattern). Default: `medium` |
65
+ | `data-ln-date` | `<input>`, `<time>`, `<td>` | Enables date formatting. Value = format (keyword or pattern). Default: `medium` |
66
+ | `datetime` | `<time>` | Native machine-readable date attribute; primary observable SSOT on `<time>` elements. |
67
+ | `data-ln-value` | `<td>`, `<span>`, `<input>` | Raw ISO date string or timestamp; acts as raw machine value for non-`<time>` elements. |
63
68
  | `data-ln-date-label` | `<input>` | Optional. Translated `aria-label` for the injected calendar button. Default: `Open date picker` (dev fallback only). |
64
69
 
65
70
  ### Format Keywords (locale-aware via Intl.DateTimeFormat)
@@ -94,7 +99,6 @@ The hidden input holds the ISO date string (YYYY-MM-DD) for form submission.
94
99
  | Event | Bubbles | Cancelable | Detail |
95
100
  |-------|---------|------------|--------|
96
101
  | `ln-date:change` | yes | no | `{ value: String (ISO), formatted: String, date: Date }` |
97
- | `ln-date:destroyed` | yes | no | `{ target: Element }` |
98
102
 
99
103
  ## API
100
104
 
@@ -146,6 +150,12 @@ Locale is detected by walking up the DOM tree to find the nearest `[lang]` attri
146
150
  <label for="hired">Hire Date</label>
147
151
  <input type="date" id="hired" name="hired" value="2024-03-15" data-ln-date>
148
152
  </div>
153
+
154
+ <!-- Semantic HTML5 time element (observable datetime SSOT, no data-ln-value needed) -->
155
+ <time datetime="2026-07-25" data-ln-date="medium">2026-07-25</time>
156
+
157
+ <!-- Table cell with explicit raw machine value -->
158
+ <td data-ln-value="2026-07-25" data-ln-date="dd.MM.yyyy">2026-07-25</td>
149
159
  ```
150
160
 
151
161
  ## Integration with ln-form
@@ -165,18 +175,18 @@ Include the main Ashlar bundle in your HTML. This bundle registers all Ashlar co
165
175
  ### 2. Standalone (Zero-Dependency IIFE)
166
176
  If you only need date-formatting functionality without the rest of the Ashlar library, load the component's standalone IIFE script:
167
177
  ```html
168
- <script src="js/ln-date/ln-date.js" defer></script>
178
+ <script src="components/ln-date/ln-date.js" defer></script>
169
179
  ```
170
180
 
171
181
  ### 3. Source & Reference
172
- * **Active Development Source**: [js/ln-date/src/ln-date.js](file:///c:/laragon/www/ln-ashlar/js/ln-date/src/ln-date.js) — The source of truth containing the ES module implementation.
173
- * **Compiled Standalone Release**: [js/ln-date/ln-date.js](file:///c:/laragon/www/ln-ashlar/js/ln-date/ln-date.js) — The compiled IIFE distribution file.
182
+ * **Active Development Source**: [components/ln-date/src/ln-date.js](file:///c:/laragon/www/ln-ashlar/components/ln-date/src/ln-date.js) — The source of truth containing the ES module implementation.
183
+ * **Compiled Standalone Release**: [components/ln-date/ln-date.js](file:///c:/laragon/www/ln-ashlar/components/ln-date/ln-date.js) — The compiled IIFE distribution file.
174
184
 
175
185
  ---
176
186
 
177
187
  ## 🔧 Internals
178
188
 
179
- Source: `js/ln-date/ln-date.js`. Each `[data-ln-date]` gets a `_component` instance at `element.lnDate` (`dom` visible input, `_wrapper`, `_hidden` form input, `_picker` hidden native date input, `_btn` calendar button, `_lastISO` — the last known valid ISO value, used to revert on invalid typed input).
189
+ Source: `components/ln-date/ln-date.js`. Each `[data-ln-date]` gets a `_component` instance at `element.lnDate` (`dom` visible input, `_wrapper`, `_hidden` form input, `_picker` hidden native date input, `_btn` calendar button, `_lastISO` — the last known valid ISO value, used to revert on invalid typed input).
180
190
 
181
191
  ### Format resolution
182
192
 
@@ -1,14 +1,14 @@
1
- @use '../../scss/config/mixins' as *;
2
-
3
- [data-ln-debug] {
4
- // 1. Date element misuse: data-ln-date belongs on <input>, <span>, <time>, or <td>
5
- [data-ln-date]:not(input, span, time, td, p, div, b, strong, data) {
6
- @include dev-inline-error("data-ln-date belongs on <input>, <span>, <time>, or <td>");
7
- }
8
-
9
- // 2. Date input missing ID: input[data-ln-date] must have an id for proper labeling/association
10
- input[data-ln-date]:not([id]) {
11
- @include dev-inline-error("data-ln-date is missing required 'id' attribute");
12
- }
13
- }
14
-
1
+ @use '../../theme/config/mixins' as *;
2
+
3
+ [data-ln-debug] {
4
+ // 1. Date element misuse: data-ln-date belongs on <input>, <span>, <time>, or <td>
5
+ [data-ln-date]:not(input, span, time, td, p, div, b, strong, data) {
6
+ @include dev-inline-error("data-ln-date belongs on <input>, <span>, <time>, or <td>");
7
+ }
8
+
9
+ // 2. Date input missing ID: input[data-ln-date] must have an id for proper labeling/association
10
+ input[data-ln-date]:not([id]) {
11
+ @include dev-inline-error("data-ln-date is missing required 'id' attribute");
12
+ }
13
+ }
14
+
@@ -0,0 +1 @@
1
+ (function(){"use strict";function q(){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 N(t){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return t?window.lnCore._debugIsContained(t):window.lnCore._debugSink!==null;if(t&&t.closest){const e=t.closest("[data-ln-debug]");return!(!e||typeof document<"u"&&e===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 t=console.warn;console.warn=function(...e){if(typeof e[0]=="string"&&(e[0].startsWith("[ln-")||e[0].startsWith("[lnCore"))){let r=null;for(let o=1;o<e.length;o++)if(e[o]&&e[o].nodeType===1){r=e[o];break}if(!N(r))return}t.apply(console,e)}}function P(t,e,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",e,t,r),t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:r}))}function M(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){M(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}function Z(t,e,{get:n,set:r}){Object.defineProperty(t,"value",{get:function(){return n?n.call(this):e.get.call(this)},set:function(o){r?r.call(this,o,l=>e.set.call(this,l)):e.set.call(this,o)},configurable:!0})}const j={};function tt(t,e){j[t]=e}function et(t){return j[t]||{ingress:e=>e,egress:e=>e}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=tt,window.lnCore.getDataMapper=et);function L(t){const e=t?t.closest("[lang]"):null,n=(e?e.getAttribute("lang")||e.lang:null)||(typeof document<"u"&&document.documentElement?document.documentElement.getAttribute("lang")||document.documentElement.lang:null)||(typeof navigator<"u"?navigator.language:null);return n?n.trim():"en-US"}function H(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,M(function(){new MutationObserver(function(){P(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const W={};function U(t,e){if(!t||typeof e!="object")return;const n=t.toLowerCase().split("-")[0];W[n]=e}function T(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return W[e]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=U,window.lnCore.getLocaleFallback=T,window.lnCore.ensureLocaleObserver=H);const F={};function nt(t,e){F[t]||(F[t]=document.querySelector('[data-ln-template="'+t+'"]'));const n=F[t];return n?n.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function K(t,e){if(!t||!e)return t;const n=t.querySelectorAll("[data-ln-field]");for(let s=0;s<n.length;s++){const u=n[s],c=u.getAttribute("data-ln-field");e[c]!=null&&(u.textContent=e[c])}const r=t.querySelectorAll("[data-ln-attr]");for(let s=0;s<r.length;s++){const u=r[s],c=u.getAttribute("data-ln-attr").split(",");for(let i=0;i<c.length;i++){const a=c[i].trim().split(":");if(a.length!==2)continue;const d=a[0].trim(),h=a[1].trim();e[h]!=null&&u.setAttribute(d,e[h])}}const o=t.querySelectorAll("[data-ln-show]");for(let s=0;s<o.length;s++){const u=o[s],c=u.getAttribute("data-ln-show");c in e&&u.classList.toggle("hidden",!e[c])}const l=t.querySelectorAll("[data-ln-class]");for(let s=0;s<l.length;s++){const u=l[s],c=u.getAttribute("data-ln-class").split(",");for(let i=0;i<c.length;i++){const a=c[i].trim().split(":");if(a.length!==2)continue;const d=a[0].trim(),h=a[1].trim();h in e&&u.classList.toggle(d,!!e[h])}}return t}function it(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",t,e??null),t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0})));const n=t.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],e??null),n[r].dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(t){if(!(!t.target.matches||!t.target.matches("[data-ln-fillable]")))if(t.detail)K(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let n=0;n<e.length;n++)e[n].textContent=""}})));function Y(t,e){if(!t||!e)return t;const n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const l=n.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(s,u){return e[u]!==void 0?e[u]:""}))}const r=function(l,s){return e[s]!==void 0?e[s]:""},o=Array.from(t.querySelectorAll("*"));t.nodeType===1&&o.push(t);for(let l=0;l<o.length;l++){const s=o[l],u=s.attributes;for(let c=0;c<u.length;c++){const i=u[c];i.value.indexOf("{{")!==-1&&s.setAttribute(i.name,i.value.replace(/\{\{\s*(\w+)\s*\}\}/g,r))}}return t}function rt(t,e,n,r,o,l){const s={};for(let c=0;c<t.children.length;c++){const i=t.children[c],a=i.getAttribute("data-ln-render-key");a&&(s[a]=i)}const u=document.createDocumentFragment();for(let c=0;c<e.length;c++){const i=e[c],a=String(r(i));let d=s[a];if(d)o(d,i,c);else{const h=nt(n,l);if(!h||(Y(h,i),d=h.firstElementChild,!d))continue;d.setAttribute("data-ln-render-key",a),o(d,i,c)}u.appendChild(d)}t.textContent="",t.appendChild(u)}function ot(t,e){const n={},r=t.querySelectorAll("["+e+"]");for(let o=0;o<r.length;o++)n[r[o].getAttribute(e)]=r[o].textContent,r[o].remove();return n}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=Y,window.lnCore.fill=K,window.lnCore.lnFill=it,window.lnCore.renderList=rt);function Q(t,e,n,r,o){if(!t||e===null)return!0;const l=r||"ln-component",s=t.type;if(s==="trigger"||s==="marker"||s==="string"||s==="list"||!s||e===""&&t.fallback!==void 0)return!0;const u=c=>{o?console.warn(c,o):console.warn(c)};if(s==="boolean"){const c=e.trim().toLowerCase();return c!==""&&c!=="true"&&c!=="false"&&c!=="1"&&c!=="0"?(u(`[${l}] Invalid value "${e}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(s==="enum"){const c=t.values||[];return c.includes(e)?!0:(u(`[${l}] Invalid value "${e}" for attribute "${n}". Allowed: ${c.join(", ")}. Fallback: "${t.fallback}".`),!1)}if(s==="integer"){if(!/^-?\d+$/.test(e))return u(`[${l}] Invalid integer "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1;const c=parseInt(e,10);return t.min!==void 0&&c<t.min?(u(`[${l}] Value ${c} for attribute "${n}" is less than min (${t.min}).`),!1):t.max!==void 0&&c>t.max?(u(`[${l}] Value ${c} for attribute "${n}" is greater than max (${t.max}).`),!1):!0}if(s==="float")return isNaN(Number(e))?(u(`[${l}] Invalid float "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1):!0;if(s==="json")try{return JSON.parse(e),!0}catch(c){return u(`[${l}] Invalid JSON for attribute "${n}": ${c.message}. Fallback: ${t.fallback}.`),!1}return!0}function lt(t){const e={};for(const n in t){const r=t[n];r&&r.effect&&(e[n]=r.effect)}return Object.keys(e).length?e:null}function st(t){if(t.onAttrChange&&!t.declared)return null;const e=new Set;if(t.effects)for(const n in t.effects)e.add(n);if(t.onAttrChange&&t.declared)for(const n of t.declared)e.add(n);return e}function R(t,e,n,r){if(t.nodeType!==1)return;const l=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]",s=Array.from(t.querySelectorAll(l));t.matches&&t.matches(l)&&s.push(t);for(const u of s)if(!u[n]){window.lnCore._persistSink&&u.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(u,e);try{u[n]=new r(u)}catch(c){console.error("["+n+"] init failed",u,c)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function at(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function ct(t){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(t):setTimeout(t,0)):t()}function G(){window.lnCore=window.lnCore||{};const t=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return t.byReactive=t.byReactive||new Map,t.reactiveWildcard=t.reactiveWildcard||[],t}function ut(t){const e=G(),n=t.observed||[];for(let r=0;r<n.length;r++){const o=n[r];e.byAttr.has(o)||e.byAttr.set(o,[]),e.byAttr.get(o).push(t)}if(e.byDeclaredAttr=e.byDeclaredAttr||new Map,t.attributes)for(const r in t.attributes){e.byDeclaredAttr.has(r)||e.byDeclaredAttr.set(r,[]);const o=e.byDeclaredAttr.get(r);o.some(l=>l.componentTag===t.componentTag)||o.push({spec:t.attributes[r],componentTag:t.componentTag})}if(t.onAttrChange||t.effects){e.reactive.push(t);const r=st(t);if(r===null)e.reactiveWildcard.push(t);else for(const o of r)e.byReactive.has(o)||e.byReactive.set(o,[]),e.byReactive.get(o).push(t)}t.persist&&e.persist.push(t)}function J(t,e,n,r){for(let o=0;o<t.length;o++){const l=t[o];if(!e[l.attribute])continue;const s=l.effects&&l.effects[n];s?s(e,n,r):l.onAttrChange&&(!l.declared||l.declared.has(n))&&l.onAttrChange(e,n,r)}}function dt(t){const e=t.target,n=t.attributeName;if(t.oldValue===e.getAttribute(n))return;const r=G(),o=r.byAttr.get(n);if(q()&&r.byDeclaredAttr&&r.byDeclaredAttr.has(n)&&N(e)){const l=r.byDeclaredAttr.get(n),s=e.getAttribute(n);for(let u=0;u<l.length;u++)Q(l[u].spec,s,n,l[u].componentTag,e)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||o)&&window.lnCore._debugSink("attr",n,e,{oldValue:t.oldValue,newValue:e.getAttribute(n)}),n.indexOf("data-ln-")===0){const l=r.byReactive.get(n);l&&J(l,e,n,t.oldValue),r.reactiveWildcard.length&&J(r.reactiveWildcard,e,n,t.oldValue)}if(o)for(let l=0;l<o.length;l++){const s=o[l];if(s.handler){s.handler(e,n,t.oldValue);continue}s.onAttributeChange&&e[s.attribute]?s.onAttributeChange(e,n):(R(e,s.selector,s.attribute,s.ComponentFn),s.onInit&&s.onInit(e))}}function ft(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,M(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++)try{dt(e[n])}catch(r){console.error("[ln-core] mutation handler failed",e[n].target,r)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function X(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function ht(t){const e=X();if(e.length){if(t.target)for(let n=0;n<e.length;n++){const r=e[n];if(r.onSubtreeChange){const o=r.query,l=t.target.nodeType===1?t.target.matches(o)?t.target:t.target.closest(o):t.target.parentElement?t.target.parentElement.closest(o):null;l&&r.onSubtreeChange(l,t)}}for(let n=0;n<t.addedNodes.length;n++){const r=t.addedNodes[n];if(r.nodeType===1)for(let o=0;o<e.length;o++){const l=e[o];R(r,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(r)}}for(let n=0;n<t.removedNodes.length;n++){const r=t.removedNodes[n];if(r.nodeType===1)for(let o=0;o<e.length;o++){const l=e[o],s=l.query,u=Array.from(r.querySelectorAll(s));r.matches&&r.matches(s)&&u.push(r);for(let c=0;c<u.length;c++){const i=u[c];if(!document.contains(i)){const a=i[l.attribute];if(a&&typeof a.destroy=="function")try{a.destroy()}catch(d){console.error("["+l.attribute+"] destroy failed",i,d)}delete i[l.attribute]}}}}}}function mt(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,M(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++){const r=e[n];if(r.type==="childList")try{ht(r)}catch(o){console.error("[ln-core] lifecycle handler failed",r.target,o)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function gt(t,e,n,r,o={}){const l=o.extraAttributes||[],s=o.onAttributeChange||null,u=o.onSubtreeChange||null,c=o.onInit||null,i=o.onAttrChange||null,a=o.effects||null,d=o.attributes||null,h=d?lt(d):a,b=d?new Set(Object.keys(d)):null,p=o.persist||null;function w(m){const g=m||document.body;if(R(g,t,e,n),d&&q())for(const y in d){const A=d[y],v=Array.from(g.querySelectorAll("["+y+"]"));g.matches&&g.matches("["+y+"]")&&v.push(g);for(let D=0;D<v.length;D++){const k=v[D];N(k)&&Q(A,k.getAttribute(y),y,r,k)}}c&&c(g)}const C=[];if(t.indexOf("[")!==-1){const m=/\[([\w-]+)/g;let g;for(;(g=m.exec(t))!==null;)C.push(g[1])}else C.push(t);ut({selector:t,attribute:e,componentTag:r,attributes:d,ComponentFn:n,onInit:c,observed:C.concat(l),onAttributeChange:s,onAttrChange:i,effects:h,declared:b,persist:p}),ft();const O=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]";X().push({selector:t,attribute:e,ComponentFn:n,onInit:c,onSubtreeChange:u,query:O}),mt(),window[e]=w;function f(){at()>0?ct(function(){w(document.body)}):w(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",f):f(),w}function z(t){return(t||"").replace(/^#/,"")}function $(t){const e=t===void 0?location.hash:t,n={},r=z(e);if(!r)return n;const o=r.split("&");for(let l=0;l<o.length;l++){const s=o[l];if(!s)continue;const u=s.indexOf(":"),c=u>-1?s.slice(0,u):s,i=u>-1?s.slice(u+1):"";if(c)try{n[c]=decodeURIComponent(i)}catch{n[c]=i}}return n}function pt(t){if(!t)return null;const e=$();return t in e?e[t]:null}function wt(t,e){if(!t)return;const n=$();e==null?delete n[t]:n[t]=String(e);const o=Object.keys(n).map(function(l){const s=n[l];return s===""?l:l+":"+encodeURIComponent(s)}).join("&");z(location.hash)!==o&&(location.hash=o)}function bt(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}function yt(t,e){if(!t||!t.hasAttribute("data-ln-hash"))return null;const n=t.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const r=t.getAttribute("data-ln-sort")||t.getAttribute("data-ln-search-for")||t.getAttribute("data-ln-search")||t.getAttribute("data-ln-filter")||t.id;return r?e?r+"-"+e:r:e||null}function Ct(t,e){return!e||e==="none"||t===null||t===void 0?null:String(t)+"."+e}function _t(t){return!t||typeof t!="string"?null:t.endsWith(".asc")?{fieldOrColumn:t.slice(0,-4),direction:"asc"}:t.endsWith(".desc")?{fieldOrColumn:t.slice(0,-5),direction:"desc"}:null}function At(t,e){return!t||!Array.isArray(e)||e.length===0?null:t+":"+e.map(encodeURIComponent).join(",")}function vt(t){if(!t||typeof t!="string")return null;const e=t.indexOf(":");if(e===-1)return null;const n=t.slice(0,e),r=t.slice(e+1),o=r?r.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:n,values:o}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=$,window.lnCore.hashGet=pt,window.lnCore.hashSet=wt,window.lnCore.hashLinkClick=bt,window.lnCore.resolveHashNamespace=yt,window.lnCore.hashSortEncode=Ct,window.lnCore.hashSortDecode=_t,window.lnCore.hashFilterEncode=At,window.lnCore.hashFilterDecode=vt);function _(t){if(t==null||t==="")return null;if(t instanceof Date)return isNaN(t.getTime())?null:t;const e=Number(t);if(!isNaN(e)&&e>0){const n=e<1e11?e*1e3:e,r=new Date(n);return isNaN(r.getTime())?null:r}if(typeof t=="string"){const n=t.trim();if(!n)return null;const r=/^(\d{4})-(\d{2})-(\d{2})$/.exec(n);if(r){const l=+r[1],s=+r[2],u=+r[3],c=new Date(l,s-1,u);return c.getFullYear()!==l||c.getMonth()!==s-1||c.getDate()!==u?null:c}const o=new Date(n);return isNaN(o.getTime())?null:o}return null}function E(t){if(!t||!(t instanceof Date)||isNaN(t.getTime()))return"";const e=t.getFullYear(),n=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0");return e+"-"+n+"-"+r}const B=/^(short|medium|long)(\s+datetime)?$/,St={short:{dateStyle:"short"},medium:{dateStyle:"medium"},long:{dateStyle:"long"},"short datetime":{dateStyle:"short",timeStyle:"short"},"medium datetime":{dateStyle:"medium",timeStyle:"short"},"long datetime":{dateStyle:"long",timeStyle:"short"}};function Et(t){return!t||t===""?{dateStyle:"medium"}:String(t).trim().match(B)?St[t.trim()]:null}function x(t){if(!t||typeof t!="string")return null;const e=t.trim();if(e.length<6)return null;let n,r;if(e.indexOf(".")!==-1)n=".",r=e.split(".");else if(e.indexOf("/")!==-1)n="/",r=e.split("/");else if(e.indexOf("-")!==-1)n="-",r=e.split("-");else return null;if(r.length!==3)return null;const o=[];for(let i=0;i<3;i++){const a=parseInt(r[i],10);if(isNaN(a))return null;o.push(a)}let l,s,u;n==="."?(l=o[0],s=o[1],u=o[2]):n==="/"?(s=o[0],l=o[1],u=o[2]):r[0].length===4?(u=o[0],s=o[1],l=o[2]):(l=o[0],s=o[1],u=o[2]),u<100&&(u+=u<50?2e3:1900);const c=new Date(u,s-1,l);return c.getFullYear()!==u||c.getMonth()!==s-1||c.getDate()!==l?null:c}function V(t,e,n,r){if(!t||!(t instanceof Date)||isNaN(t.getTime())||!e||typeof e!="string")return"";const o=t.getDate(),l=t.getMonth(),s=t.getFullYear(),u=t.getHours(),c=t.getMinutes();let i,a;const d=(n||"").toLowerCase().split("-")[0];let h=!1;try{const w=new Intl.DateTimeFormat(n,{month:"long"}).resolvedOptions().locale.toLowerCase().split("-")[0];h=!!(r&&w!==d)}catch{h=!!r}if(h&&r&&r.monthsLong)i=r.monthsLong[l];else try{i=new Intl.DateTimeFormat(n,{month:"long"}).format(t)}catch{i=String(l+1)}if(h&&r&&r.monthsShort)a=r.monthsShort[l];else try{a=new Intl.DateTimeFormat(n,{month:"short"}).format(t)}catch{a=String(l+1)}const b={yyyy:String(s),yy:String(s).slice(-2),MMMM:i,MMM:a,MM:String(l+1).padStart(2,"0"),M:String(l+1),dd:String(o).padStart(2,"0"),d:String(o),HH:String(u).padStart(2,"0"),mm:String(c).padStart(2,"0")};return e.replace(/yyyy|yy|MMMM|MMM|MM|M|dd|d|HH|mm/g,function(p){return b[p]!==void 0?b[p]:p})}function I(t,e,n,r){if(!t||!(t instanceof Date)||isNaN(t.getTime()))return"";const o=Et(e);if(o)try{const l=new Intl.DateTimeFormat(n,o),s=(n||"").toLowerCase().split("-")[0],u=l.resolvedOptions().locale.toLowerCase().split("-")[0];return r&&u!==s?V(t,"dd.MM.yyyy",n,r):l.format(t)}catch{return V(t,"dd.MM.yyyy",n,r)}return V(t,e||"dd.MM.yyyy",n,r)}(function(){const t="data-ln-date",e="lnDate";if(window[e]!==void 0)return;function n(i){const a=i[e];if(a){if(a.isTextElement)a._initTextElement();else if(a.value){const d=_(a.value);d&&a._displayFormatted(d)}}}const r={"data-ln-date":{type:"enum",values:["short","medium","long","full","iso"],fallback:"medium",effect:n,description:"Date display style preset or activator"},"data-ln-date-format":{type:"string",effect:n,description:"Custom Intl.DateTimeFormat pattern or options"},"data-ln-date-locale":{type:"string",effect:n,description:"BCP 47 language tag override for date formatting"},"data-ln-value":{type:"string",effect:n,description:"Raw ISO date string or timestamp for non-time elements (td, span)"},"data-ln-date-dict":{type:"marker",description:"Container for date translation dictionary"},"data-ln-date-dict-key":{type:"string",description:"Dictionary key for relative time or custom date formatting"},"data-ln-date-field":{type:"string",description:"Field name mapping for date record binding"},"data-ln-date-label":{type:"string",description:"Accessible label text for the date input"}},o=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value");function l(i,a,d){P(i.dom,"ln-date:change",{value:a,formatted:i.dom.value,date:d}),i.dom.dispatchEvent(new Event("change",{bubbles:!0}))}function s(i,a,d,h){i._setHiddenRaw(a),o.set.call(i._picker,a),i._lastISO=a,h!==void 0?(i._isFormatting=!0,i.dom.value=h,i._isFormatting=!1):d&&i._displayFormatted(d),l(i,a,d)}function u(i){i._setHiddenRaw(""),o.set.call(i._picker,""),i._isFormatting=!0,i.dom.value="",i._isFormatting=!1,i._lastISO="",l(i,"",null)}function c(i){if(i[e])return i[e];i[e]=this,this.dom=i;const a=this;if(this._onLocaleChange=function(){if(a.isTextElement)a._formatTextContent();else if(a.value){const f=_(a.value);f&&a._displayFormatted(f)}},H(),document.addEventListener("ln-core:locale-change",this._onLocaleChange),i.tagName!=="INPUT")return this.isTextElement=!0,this._initTextElement(),this;this.isTextElement=!1;const d=i.value,h=i.name,b=i.closest(".form-element, form")||i.parentNode;if(b){const f=b.querySelectorAll("[data-ln-date-dict]");for(let m=0;m<f.length;m++){const g=f[m].getAttribute("data-ln-date-dict");if(g){const y=ot(f[m],"data-ln-date-dict-key");y["months-long"]&&(y.monthsLong=y["months-long"].split(",").map(A=>A.trim())),y["months-short"]&&(y.monthsShort=y["months-short"].split(",").map(A=>A.trim())),U(g,y)}}}const p=document.createElement("span");p.setAttribute("data-ln-date-field",""),i.parentNode.insertBefore(p,i),p.appendChild(i),this._wrapper=p;const w=document.createElement("input");w.type="hidden",w.name=h,i.removeAttribute("name"),i.hasAttribute("data-ln-fill-as")&&w.setAttribute("data-ln-fill-as",i.getAttribute("data-ln-fill-as")),i.insertAdjacentElement("afterend",w),this._hidden=w;const C=document.createElement("input");C.type="date",C.tabIndex=-1,C.setAttribute("tabindex","-1"),C.setAttribute("aria-hidden","true"),C.setAttribute("aria-label",i.getAttribute("data-ln-date-label")||"Date picker"),C.style.cssText="position:absolute;opacity:0;width:0;height:0;overflow:hidden;pointer-events:none",w.insertAdjacentElement("afterend",C),this._picker=C,i.type="text";const S=document.createElement("button");S.type="button",S.setAttribute("aria-label",i.getAttribute("data-ln-date-label")||"Open date picker"),S.innerHTML='<svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-calendar"></use></svg>',C.insertAdjacentElement("afterend",S),this._btn=S,this._lastISO="",Object.defineProperty(w,"value",{get:function(){return o.get.call(w)},set:function(f){if(o.set.call(w,f),f&&f!==""){const m=_(f);m&&s(a,f,m)}else f===""&&u(a)}}),Z(i,o,{get:function(){return o.get.call(i)},set:function(f,m){if(a._isFormatting){m(f);return}if(!f||f===""){m(""),u(a);return}const g=_(f)||x(f);if(g){const y=E(g),A=i.getAttribute(t)||"",v=L(i),D=T(v),k=I(g,A,v,D);m(k),s(a,y,g,k)}else m(String(f)),u(a)}}),this._onPickerChange=function(){const f=C.value;if(f){const m=_(f);m&&s(a,f,m)}else u(a)},C.addEventListener("change",this._onPickerChange),this._onBlur=function(){const f=a.dom.value.trim();if(f===""){a._lastISO!==""&&u(a);return}if(a._lastISO){const g=_(a._lastISO);if(g){const y=a.dom.getAttribute(t)||"",A=L(a.dom),v=T(A);if(f===I(g,y,A,v))return}}const m=x(f);if(m){const g=E(m);s(a,g,m)}else if(a._lastISO){const g=_(a._lastISO);g&&a._displayFormatted(g)}else a.dom.value=""},i.addEventListener("blur",this._onBlur),this._onBtnClick=function(){a._openPicker()},S.addEventListener("click",this._onBtnClick);const O=i.form;if(O&&(this._form=O,this._onFormReset=function(){setTimeout(function(){const f=a.dom.value;if(f){const m=_(f)||x(f);if(m){const g=E(m);s(a,g,m);return}}u(a)},0)},O.addEventListener("reset",this._onFormReset)),d&&d!==""){const f=_(d);f&&s(a,d,f)}return this}c.prototype._initTextElement=function(){const i=this.dom,a=i.getAttribute("data-ln-value"),d=i.getAttribute("data-ln-date"),h=i.getAttribute("datetime");let b=null;i.tagName==="TIME"&&h!==null&&h!==""?b=h:a!==null&&a!==""?b=a:h!==null&&h!==""?b=h:d!==null&&d!==""&&d!=="true"&&!B.test(d)?b=d:b=i.textContent.trim();const p=_(b)||x(b);if(p&&!isNaN(p.getTime())){const w=E(p);this._rawValue=w,i.tagName!=="TIME"&&!i.hasAttribute("data-ln-value")&&i.setAttribute("data-ln-value",w),this._formatTextContent()}else this._rawValue=null},c.prototype._formatTextContent=function(){if(this._rawValue){const i=_(this._rawValue);if(i){let d=this.dom.getAttribute("data-ln-date-format");if(!d){const p=this.dom.getAttribute("data-ln-date");p&&B.test(p)&&(d=p)}const h=L(this.dom),b=T(h);this.dom.textContent=I(i,d||"medium",h,b)}}},c.prototype._openPicker=function(){if(typeof this._picker.showPicker=="function")try{this._picker.showPicker()}catch{this._picker.click()}else this._picker.click()},c.prototype._setHiddenRaw=function(i){o.set.call(this._hidden,i)},c.prototype._displayFormatted=function(i){const a=this.dom.getAttribute(t)||"",d=L(this.dom),h=T(d);this._isFormatting=!0,this.dom.value=I(i,a,d,h),this._isFormatting=!1},Object.defineProperty(c.prototype,"value",{get:function(){return this.isTextElement?this._rawValue||"":o.get.call(this._hidden)},set:function(i){if(this.isTextElement){if(!i||i===""){this._rawValue=null,this.dom.removeAttribute("data-ln-value"),this.dom.tagName==="TIME"&&this.dom.removeAttribute("datetime"),this.dom.textContent="";return}const d=_(i)||x(i);if(!d)return;const h=E(d);this._rawValue=h,this.dom.tagName==="TIME"?this.dom.setAttribute("datetime",h):this.dom.setAttribute("data-ln-value",h),this._formatTextContent();return}if(!i||i===""){u(this);return}const a=_(i);a&&s(this,i,a)}}),Object.defineProperty(c.prototype,"date",{get:function(){const i=this.value;return i?_(i):null},set:function(i){if(!i||!(i instanceof Date)||isNaN(i.getTime())){this.value="";return}this.value=E(i)}}),Object.defineProperty(c.prototype,"formatted",{get:function(){return this.isTextElement?this.dom.textContent:this.dom.value}}),c.prototype.destroy=function(){if(!this.dom[e])return;if(this.isTextElement){delete this.dom[e];return}this._form&&this._onFormReset&&this._form.removeEventListener("reset",this._onFormReset),this._picker.removeEventListener("change",this._onPickerChange),this.dom.removeEventListener("blur",this._onBlur),this._btn.removeEventListener("click",this._onBtnClick);const i=this.value;this._hidden.remove(),this._picker.remove(),this._btn.remove(),this._wrapper&&this._wrapper.parentNode&&(this._wrapper.parentNode.insertBefore(this.dom,this._wrapper),this._wrapper.remove()),delete this.dom.value,this.dom.name=this._hidden.name,this.dom.type="date",i&&(this.dom.value=i),this._onLocaleChange&&document.removeEventListener("ln-core:locale-change",this._onLocaleChange),delete this.dom[e]},gt(t,e,c,"ln-date",{attributes:r,extraAttributes:["datetime","lang"],onAttributeChange:n})})()})();
@@ -0,0 +1,92 @@
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-date",
4
+ "generator": "scripts/sync-ln-schemas.mjs",
5
+ "attributes": {
6
+ "data-ln-date": {
7
+ "direction": "author",
8
+ "sources": [
9
+ "ln-date-dev.scss",
10
+ "src/ln-date.js"
11
+ ],
12
+ "type": "enum",
13
+ "values": [
14
+ "short",
15
+ "medium",
16
+ "long",
17
+ "full",
18
+ "iso"
19
+ ],
20
+ "fallback": "medium",
21
+ "description": "Date display style preset or activator"
22
+ },
23
+ "data-ln-date-dict": {
24
+ "direction": "author",
25
+ "sources": [
26
+ "src/ln-date.js"
27
+ ],
28
+ "type": "marker",
29
+ "description": "Container for date translation dictionary"
30
+ },
31
+ "data-ln-date-dict-key": {
32
+ "direction": null,
33
+ "sources": [
34
+ "src/ln-date.js"
35
+ ],
36
+ "type": "string",
37
+ "description": "Dictionary key for relative time or custom date formatting"
38
+ },
39
+ "data-ln-date-field": {
40
+ "direction": "runtime",
41
+ "sources": [
42
+ "src/ln-date.js"
43
+ ],
44
+ "type": "string",
45
+ "description": "Field name mapping for date record binding"
46
+ },
47
+ "data-ln-date-format": {
48
+ "direction": "author",
49
+ "sources": [
50
+ "src/ln-date.js"
51
+ ],
52
+ "type": "string",
53
+ "description": "Custom Intl.DateTimeFormat pattern or options"
54
+ },
55
+ "data-ln-date-label": {
56
+ "direction": "both",
57
+ "sources": [
58
+ "src/ln-date.js"
59
+ ],
60
+ "type": "string",
61
+ "description": "Accessible label text for the date input"
62
+ },
63
+ "data-ln-date-locale": {
64
+ "direction": null,
65
+ "sources": [
66
+ "src/ln-date.js"
67
+ ],
68
+ "type": "string",
69
+ "description": "BCP 47 language tag override for date formatting"
70
+ },
71
+ "data-ln-debug": {
72
+ "direction": null,
73
+ "sources": [
74
+ "ln-date-dev.scss"
75
+ ]
76
+ },
77
+ "data-ln-fill-as": {
78
+ "direction": "both",
79
+ "sources": [
80
+ "src/ln-date.js"
81
+ ]
82
+ },
83
+ "data-ln-value": {
84
+ "direction": "both",
85
+ "sources": [
86
+ "src/ln-date.js"
87
+ ],
88
+ "type": "string",
89
+ "description": "Raw ISO date string or timestamp for non-time elements (td, span)"
90
+ }
91
+ }
92
+ }
@@ -0,0 +1,186 @@
1
+ export const KEYWORD_RE = /^(short|medium|long)(\s+datetime)?$/;
2
+
3
+ export const KEYWORD_OPTIONS = {
4
+ 'short': { dateStyle: 'short' },
5
+ 'medium': { dateStyle: 'medium' },
6
+ 'long': { dateStyle: 'long' },
7
+ 'short datetime': { dateStyle: 'short', timeStyle: 'short' },
8
+ 'medium datetime': { dateStyle: 'medium', timeStyle: 'short' },
9
+ 'long datetime': { dateStyle: 'long', timeStyle: 'short' }
10
+ };
11
+
12
+ /**
13
+ * Returns Intl.DateTimeFormat options if format is a recognized keyword, or null for custom patterns.
14
+ * @param {string} format
15
+ * @returns {Intl.DateTimeFormatOptions|null}
16
+ */
17
+ export function getIntlDateOptions(format) {
18
+ if (!format || format === '') return { dateStyle: 'medium' };
19
+ const match = String(format).trim().match(KEYWORD_RE);
20
+ if (match) {
21
+ return KEYWORD_OPTIONS[format.trim()];
22
+ }
23
+ return null;
24
+ }
25
+
26
+ /**
27
+ * Parses user typed date strings (e.g. DD.MM.YYYY, MM/DD/YYYY, YYYY-MM-DD) into a valid Date object.
28
+ * @param {string} str
29
+ * @returns {Date|null}
30
+ */
31
+ export function parseTypedDate(str) {
32
+ if (!str || typeof str !== 'string') return null;
33
+ const trimmed = str.trim();
34
+ if (trimmed.length < 6) return null;
35
+
36
+ let sep, parts;
37
+ if (trimmed.indexOf('.') !== -1) {
38
+ sep = '.';
39
+ parts = trimmed.split('.');
40
+ } else if (trimmed.indexOf('/') !== -1) {
41
+ sep = '/';
42
+ parts = trimmed.split('/');
43
+ } else if (trimmed.indexOf('-') !== -1) {
44
+ sep = '-';
45
+ parts = trimmed.split('-');
46
+ } else {
47
+ return null;
48
+ }
49
+
50
+ if (parts.length !== 3) return null;
51
+ const nums = [];
52
+ for (let i = 0; i < 3; i++) {
53
+ const n = parseInt(parts[i], 10);
54
+ if (isNaN(n)) return null;
55
+ nums.push(n);
56
+ }
57
+
58
+ let day, month, year;
59
+ if (sep === '.') {
60
+ day = nums[0];
61
+ month = nums[1];
62
+ year = nums[2];
63
+ } else if (sep === '/') {
64
+ month = nums[0];
65
+ day = nums[1];
66
+ year = nums[2];
67
+ } else {
68
+ if (parts[0].length === 4) {
69
+ year = nums[0];
70
+ month = nums[1];
71
+ day = nums[2];
72
+ } else {
73
+ day = nums[0];
74
+ month = nums[1];
75
+ year = nums[2];
76
+ }
77
+ }
78
+
79
+ if (year < 100) {
80
+ year += (year < 50) ? 2000 : 1900;
81
+ }
82
+
83
+ const date = new Date(year, month - 1, day);
84
+ if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
85
+ return null;
86
+ }
87
+ return date;
88
+ }
89
+
90
+ /**
91
+ * Formats a Date object using a custom pattern with token replacements.
92
+ * @param {Date} date
93
+ * @param {string} pattern Pattern with tokens (yyyy, yy, MMMM, MMM, MM, M, dd, d, HH, mm)
94
+ * @param {string} [locale]
95
+ * @param {object} [fallback] Custom locale fallback dictionary
96
+ * @returns {string}
97
+ */
98
+ export function formatCustomDate(date, pattern, locale, fallback) {
99
+ if (!date || !(date instanceof Date) || isNaN(date.getTime())) return '';
100
+ if (!pattern || typeof pattern !== 'string') return '';
101
+
102
+ const day = date.getDate();
103
+ const month = date.getMonth();
104
+ const year = date.getFullYear();
105
+ const hours = date.getHours();
106
+ const minutes = date.getMinutes();
107
+
108
+ let mmmmVal, mmmVal;
109
+ const langPrefix = (locale || '').toLowerCase().split('-')[0];
110
+
111
+ let isFallbackNeeded = false;
112
+ try {
113
+ const fmt = new Intl.DateTimeFormat(locale, { month: 'long' });
114
+ const resolvedLocale = fmt.resolvedOptions().locale.toLowerCase().split('-')[0];
115
+ isFallbackNeeded = Boolean(fallback && resolvedLocale !== langPrefix);
116
+ } catch (e) {
117
+ isFallbackNeeded = Boolean(fallback);
118
+ }
119
+
120
+ if (isFallbackNeeded && fallback && fallback.monthsLong) {
121
+ mmmmVal = fallback.monthsLong[month];
122
+ } else {
123
+ try {
124
+ mmmmVal = new Intl.DateTimeFormat(locale, { month: 'long' }).format(date);
125
+ } catch (e) {
126
+ mmmmVal = String(month + 1);
127
+ }
128
+ }
129
+
130
+ if (isFallbackNeeded && fallback && fallback.monthsShort) {
131
+ mmmVal = fallback.monthsShort[month];
132
+ } else {
133
+ try {
134
+ mmmVal = new Intl.DateTimeFormat(locale, { month: 'short' }).format(date);
135
+ } catch (e) {
136
+ mmmVal = String(month + 1);
137
+ }
138
+ }
139
+
140
+ const tokens = {
141
+ 'yyyy': String(year),
142
+ 'yy': String(year).slice(-2),
143
+ 'MMMM': mmmmVal,
144
+ 'MMM': mmmVal,
145
+ 'MM': String(month + 1).padStart(2, '0'),
146
+ 'M': String(month + 1),
147
+ 'dd': String(day).padStart(2, '0'),
148
+ 'd': String(day),
149
+ 'HH': String(hours).padStart(2, '0'),
150
+ 'mm': String(minutes).padStart(2, '0')
151
+ };
152
+
153
+ return pattern.replace(/yyyy|yy|MMMM|MMM|MM|M|dd|d|HH|mm/g, function (m) {
154
+ return tokens[m] !== undefined ? tokens[m] : m;
155
+ });
156
+ }
157
+
158
+ /**
159
+ * Formats a date value using either standard Intl options or a custom pattern.
160
+ * @param {Date} date
161
+ * @param {string} [format='medium']
162
+ * @param {string} [locale]
163
+ * @param {object} [fallback]
164
+ * @returns {string}
165
+ */
166
+ export function formatDateValue(date, format, locale, fallback) {
167
+ if (!date || !(date instanceof Date) || isNaN(date.getTime())) return '';
168
+
169
+ const intlOptions = getIntlDateOptions(format);
170
+ if (intlOptions) {
171
+ try {
172
+ const formatter = new Intl.DateTimeFormat(locale, intlOptions);
173
+ const langPrefix = (locale || '').toLowerCase().split('-')[0];
174
+ const resolvedLocale = formatter.resolvedOptions().locale.toLowerCase().split('-')[0];
175
+
176
+ if (fallback && resolvedLocale !== langPrefix) {
177
+ return formatCustomDate(date, 'dd.MM.yyyy', locale, fallback);
178
+ }
179
+ return formatter.format(date);
180
+ } catch (e) {
181
+ return formatCustomDate(date, 'dd.MM.yyyy', locale, fallback);
182
+ }
183
+ }
184
+
185
+ return formatCustomDate(date, format || 'dd.MM.yyyy', locale, fallback);
186
+ }