@syware/jlib 0.0.0-stage → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (331) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +133 -2
  3. package/dist/all.d.ts +1 -0
  4. package/dist/all.js +75 -0
  5. package/dist/atoms/jl-avatar.css_raw.js +3 -0
  6. package/dist/atoms/jl-avatar.d.ts +52 -0
  7. package/dist/atoms/jl-avatar.js +167 -0
  8. package/dist/atoms/jl-badge.css_raw.js +3 -0
  9. package/dist/atoms/jl-badge.d.ts +32 -0
  10. package/dist/atoms/jl-badge.js +60 -0
  11. package/dist/atoms/jl-button.css_raw.js +3 -0
  12. package/dist/atoms/jl-button.d.ts +70 -0
  13. package/dist/atoms/jl-button.js +146 -0
  14. package/dist/atoms/jl-checkbox.css_raw.js +3 -0
  15. package/dist/atoms/jl-checkbox.d.ts +61 -0
  16. package/dist/atoms/jl-checkbox.js +149 -0
  17. package/dist/atoms/jl-chip.css_raw.js +3 -0
  18. package/dist/atoms/jl-chip.d.ts +59 -0
  19. package/dist/atoms/jl-chip.js +164 -0
  20. package/dist/atoms/jl-divider.css_raw.js +3 -0
  21. package/dist/atoms/jl-divider.d.ts +26 -0
  22. package/dist/atoms/jl-divider.js +59 -0
  23. package/dist/atoms/jl-icon.css_raw.js +3 -0
  24. package/dist/atoms/jl-icon.d.ts +25 -0
  25. package/dist/atoms/jl-icon.js +41 -0
  26. package/dist/atoms/jl-input.css_raw.js +3 -0
  27. package/dist/atoms/jl-input.d.ts +112 -0
  28. package/dist/atoms/jl-input.js +202 -0
  29. package/dist/atoms/jl-kbd.css_raw.js +3 -0
  30. package/dist/atoms/jl-kbd.d.ts +17 -0
  31. package/dist/atoms/jl-kbd.js +62 -0
  32. package/dist/atoms/jl-link.css_raw.js +3 -0
  33. package/dist/atoms/jl-link.d.ts +37 -0
  34. package/dist/atoms/jl-link.js +86 -0
  35. package/dist/atoms/jl-progress-ring.css_raw.js +3 -0
  36. package/dist/atoms/jl-progress-ring.d.ts +49 -0
  37. package/dist/atoms/jl-progress-ring.js +132 -0
  38. package/dist/atoms/jl-progress.css_raw.js +3 -0
  39. package/dist/atoms/jl-progress.d.ts +43 -0
  40. package/dist/atoms/jl-progress.js +109 -0
  41. package/dist/atoms/jl-rating.css_raw.js +3 -0
  42. package/dist/atoms/jl-rating.d.ts +73 -0
  43. package/dist/atoms/jl-rating.js +184 -0
  44. package/dist/atoms/jl-select.css_raw.js +3 -0
  45. package/dist/atoms/jl-select.d.ts +70 -0
  46. package/dist/atoms/jl-select.js +146 -0
  47. package/dist/atoms/jl-skeleton.css_raw.js +3 -0
  48. package/dist/atoms/jl-skeleton.d.ts +34 -0
  49. package/dist/atoms/jl-skeleton.js +63 -0
  50. package/dist/atoms/jl-slider.css_raw.js +3 -0
  51. package/dist/atoms/jl-slider.d.ts +65 -0
  52. package/dist/atoms/jl-slider.js +143 -0
  53. package/dist/atoms/jl-spinner.css_raw.js +3 -0
  54. package/dist/atoms/jl-spinner.d.ts +16 -0
  55. package/dist/atoms/jl-spinner.js +26 -0
  56. package/dist/atoms/jl-switch.css_raw.js +3 -0
  57. package/dist/atoms/jl-switch.d.ts +57 -0
  58. package/dist/atoms/jl-switch.js +125 -0
  59. package/dist/atoms/jl-textarea.css_raw.js +3 -0
  60. package/dist/atoms/jl-textarea.d.ts +81 -0
  61. package/dist/atoms/jl-textarea.js +148 -0
  62. package/dist/base/jl-element.d.ts +16 -0
  63. package/dist/base/jl-element.js +35 -0
  64. package/dist/base/jl-form-control.d.ts +29 -0
  65. package/dist/base/jl-form-control.js +44 -0
  66. package/dist/index.d.ts +119 -0
  67. package/dist/index.js +72 -0
  68. package/dist/lib/arrow.d.ts +6 -0
  69. package/dist/lib/arrow.js +15 -0
  70. package/dist/lib/attributes.d.ts +9 -0
  71. package/dist/lib/attributes.js +22 -0
  72. package/dist/lib/avatar.d.ts +11 -0
  73. package/dist/lib/avatar.js +37 -0
  74. package/dist/lib/calendar.d.ts +48 -0
  75. package/dist/lib/calendar.js +166 -0
  76. package/dist/lib/css-length.d.ts +2 -0
  77. package/dist/lib/css-length.js +8 -0
  78. package/dist/lib/define.d.ts +9 -0
  79. package/dist/lib/define.js +9 -0
  80. package/dist/lib/dom.d.ts +4 -0
  81. package/dist/lib/dom.js +16 -0
  82. package/dist/lib/files.d.ts +18 -0
  83. package/dist/lib/files.js +89 -0
  84. package/dist/lib/floating.d.ts +13 -0
  85. package/dist/lib/floating.js +127 -0
  86. package/dist/lib/fuzzy.d.ts +26 -0
  87. package/dist/lib/fuzzy.js +149 -0
  88. package/dist/lib/highlight.d.ts +5 -0
  89. package/dist/lib/highlight.js +267 -0
  90. package/dist/lib/hotkey.d.ts +9 -0
  91. package/dist/lib/hotkey.js +101 -0
  92. package/dist/lib/icon-set.d.ts +95 -0
  93. package/dist/lib/icon-set.js +97 -0
  94. package/dist/lib/icons.d.ts +12 -0
  95. package/dist/lib/icons.js +39 -0
  96. package/dist/lib/indicator.d.ts +6 -0
  97. package/dist/lib/indicator.js +18 -0
  98. package/dist/lib/keep-in-view.d.ts +5 -0
  99. package/dist/lib/keep-in-view.js +15 -0
  100. package/dist/lib/key-shortcut.d.ts +20 -0
  101. package/dist/lib/key-shortcut.js +100 -0
  102. package/dist/lib/keycaps.d.ts +8 -0
  103. package/dist/lib/keycaps.js +162 -0
  104. package/dist/lib/locale.d.ts +4 -0
  105. package/dist/lib/locale.js +13 -0
  106. package/dist/lib/nav-tree.d.ts +9 -0
  107. package/dist/lib/nav-tree.js +30 -0
  108. package/dist/lib/numeric.d.ts +20 -0
  109. package/dist/lib/numeric.js +50 -0
  110. package/dist/lib/option-filter.d.ts +29 -0
  111. package/dist/lib/option-filter.js +108 -0
  112. package/dist/lib/option-groups.d.ts +6 -0
  113. package/dist/lib/option-groups.js +26 -0
  114. package/dist/lib/options.d.ts +5 -0
  115. package/dist/lib/options.js +24 -0
  116. package/dist/lib/pagination.d.ts +9 -0
  117. package/dist/lib/pagination.js +52 -0
  118. package/dist/lib/palette.d.ts +8 -0
  119. package/dist/lib/palette.js +46 -0
  120. package/dist/lib/progress.d.ts +20 -0
  121. package/dist/lib/progress.js +33 -0
  122. package/dist/lib/rating.d.ts +7 -0
  123. package/dist/lib/rating.js +26 -0
  124. package/dist/lib/roving-index.d.ts +10 -0
  125. package/dist/lib/roving-index.js +32 -0
  126. package/dist/lib/roving.d.ts +11 -0
  127. package/dist/lib/roving.js +21 -0
  128. package/dist/lib/slots.d.ts +2 -0
  129. package/dist/lib/slots.js +6 -0
  130. package/dist/lib/sparkline.d.ts +11 -0
  131. package/dist/lib/sparkline.js +42 -0
  132. package/dist/lib/split.d.ts +12 -0
  133. package/dist/lib/split.js +37 -0
  134. package/dist/lib/surface.d.ts +7 -0
  135. package/dist/lib/surface.js +28 -0
  136. package/dist/lib/table.d.ts +30 -0
  137. package/dist/lib/table.js +110 -0
  138. package/dist/lib/tags.d.ts +14 -0
  139. package/dist/lib/tags.js +29 -0
  140. package/dist/lib/text.d.ts +5 -0
  141. package/dist/lib/text.js +13 -0
  142. package/dist/lib/tokens.d.ts +5 -0
  143. package/dist/lib/tokens.js +15 -0
  144. package/dist/lib/tree.d.ts +16 -0
  145. package/dist/lib/tree.js +89 -0
  146. package/dist/lib/trend.d.ts +3 -0
  147. package/dist/lib/trend.js +15 -0
  148. package/dist/lib/trigger.d.ts +11 -0
  149. package/dist/lib/trigger.js +34 -0
  150. package/dist/molecules/jl-accordion-item.css_raw.js +3 -0
  151. package/dist/molecules/jl-accordion-item.d.ts +34 -0
  152. package/dist/molecules/jl-accordion-item.js +82 -0
  153. package/dist/molecules/jl-accordion.css_raw.js +3 -0
  154. package/dist/molecules/jl-accordion.d.ts +27 -0
  155. package/dist/molecules/jl-accordion.js +61 -0
  156. package/dist/molecules/jl-alert.css_raw.js +3 -0
  157. package/dist/molecules/jl-alert.d.ts +38 -0
  158. package/dist/molecules/jl-alert.js +131 -0
  159. package/dist/molecules/jl-avatar-group.css_raw.js +3 -0
  160. package/dist/molecules/jl-avatar-group.d.ts +28 -0
  161. package/dist/molecules/jl-avatar-group.js +69 -0
  162. package/dist/molecules/jl-breadcrumb.css_raw.js +3 -0
  163. package/dist/molecules/jl-breadcrumb.d.ts +35 -0
  164. package/dist/molecules/jl-breadcrumb.js +126 -0
  165. package/dist/molecules/jl-calendar.css_raw.js +3 -0
  166. package/dist/molecules/jl-calendar.d.ts +101 -0
  167. package/dist/molecules/jl-calendar.js +314 -0
  168. package/dist/molecules/jl-card.css_raw.js +3 -0
  169. package/dist/molecules/jl-card.d.ts +46 -0
  170. package/dist/molecules/jl-card.js +172 -0
  171. package/dist/molecules/jl-code-block.css_raw.js +3 -0
  172. package/dist/molecules/jl-code-block.d.ts +44 -0
  173. package/dist/molecules/jl-code-block.js +106 -0
  174. package/dist/molecules/jl-combobox.css_raw.js +3 -0
  175. package/dist/molecules/jl-combobox.d.ts +120 -0
  176. package/dist/molecules/jl-combobox.js +450 -0
  177. package/dist/molecules/jl-copy-button.css_raw.js +3 -0
  178. package/dist/molecules/jl-copy-button.d.ts +31 -0
  179. package/dist/molecules/jl-copy-button.js +69 -0
  180. package/dist/molecules/jl-date-picker.css_raw.js +3 -0
  181. package/dist/molecules/jl-date-picker.d.ts +109 -0
  182. package/dist/molecules/jl-date-picker.js +322 -0
  183. package/dist/molecules/jl-empty.css_raw.js +3 -0
  184. package/dist/molecules/jl-empty.d.ts +32 -0
  185. package/dist/molecules/jl-empty.js +94 -0
  186. package/dist/molecules/jl-field.css_raw.js +3 -0
  187. package/dist/molecules/jl-field.d.ts +49 -0
  188. package/dist/molecules/jl-field.js +147 -0
  189. package/dist/molecules/jl-file-drop.css_raw.js +3 -0
  190. package/dist/molecules/jl-file-drop.d.ts +93 -0
  191. package/dist/molecules/jl-file-drop.js +366 -0
  192. package/dist/molecules/jl-list-item.css_raw.js +3 -0
  193. package/dist/molecules/jl-list-item.d.ts +56 -0
  194. package/dist/molecules/jl-list-item.js +176 -0
  195. package/dist/molecules/jl-menu.css_raw.js +3 -0
  196. package/dist/molecules/jl-menu.d.ts +62 -0
  197. package/dist/molecules/jl-menu.js +288 -0
  198. package/dist/molecules/jl-number-input.css_raw.js +3 -0
  199. package/dist/molecules/jl-number-input.d.ts +81 -0
  200. package/dist/molecules/jl-number-input.js +220 -0
  201. package/dist/molecules/jl-pagination.css_raw.js +3 -0
  202. package/dist/molecules/jl-pagination.d.ts +59 -0
  203. package/dist/molecules/jl-pagination.js +172 -0
  204. package/dist/molecules/jl-popover.css_raw.js +3 -0
  205. package/dist/molecules/jl-popover.d.ts +49 -0
  206. package/dist/molecules/jl-popover.js +152 -0
  207. package/dist/molecules/jl-radio-group.css_raw.js +3 -0
  208. package/dist/molecules/jl-radio-group.d.ts +71 -0
  209. package/dist/molecules/jl-radio-group.js +202 -0
  210. package/dist/molecules/jl-search.css_raw.js +3 -0
  211. package/dist/molecules/jl-search.d.ts +71 -0
  212. package/dist/molecules/jl-search.js +210 -0
  213. package/dist/molecules/jl-segmented.css_raw.js +3 -0
  214. package/dist/molecules/jl-segmented.d.ts +65 -0
  215. package/dist/molecules/jl-segmented.js +187 -0
  216. package/dist/molecules/jl-stat.css_raw.js +3 -0
  217. package/dist/molecules/jl-stat.d.ts +55 -0
  218. package/dist/molecules/jl-stat.js +169 -0
  219. package/dist/molecules/jl-steps.css_raw.js +3 -0
  220. package/dist/molecules/jl-steps.d.ts +44 -0
  221. package/dist/molecules/jl-steps.js +118 -0
  222. package/dist/molecules/jl-tab-panel.css_raw.js +3 -0
  223. package/dist/molecules/jl-tab-panel.d.ts +35 -0
  224. package/dist/molecules/jl-tab-panel.js +35 -0
  225. package/dist/molecules/jl-tabs.css_raw.js +3 -0
  226. package/dist/molecules/jl-tabs.d.ts +51 -0
  227. package/dist/molecules/jl-tabs.js +198 -0
  228. package/dist/molecules/jl-tag-input.css_raw.js +3 -0
  229. package/dist/molecules/jl-tag-input.d.ts +103 -0
  230. package/dist/molecules/jl-tag-input.js +429 -0
  231. package/dist/molecules/jl-timeline.css_raw.js +3 -0
  232. package/dist/molecules/jl-timeline.d.ts +28 -0
  233. package/dist/molecules/jl-timeline.js +81 -0
  234. package/dist/molecules/jl-toast.css_raw.js +3 -0
  235. package/dist/molecules/jl-toast.d.ts +75 -0
  236. package/dist/molecules/jl-toast.js +274 -0
  237. package/dist/molecules/jl-tooltip.css_raw.js +3 -0
  238. package/dist/molecules/jl-tooltip.d.ts +44 -0
  239. package/dist/molecules/jl-tooltip.js +160 -0
  240. package/dist/organisms/jl-command-palette.css_raw.js +3 -0
  241. package/dist/organisms/jl-command-palette.d.ts +60 -0
  242. package/dist/organisms/jl-command-palette.js +285 -0
  243. package/dist/organisms/jl-confirm.css_raw.js +3 -0
  244. package/dist/organisms/jl-confirm.d.ts +56 -0
  245. package/dist/organisms/jl-confirm.js +132 -0
  246. package/dist/organisms/jl-dialog.css_raw.js +3 -0
  247. package/dist/organisms/jl-dialog.d.ts +43 -0
  248. package/dist/organisms/jl-dialog.js +120 -0
  249. package/dist/organisms/jl-drawer.css_raw.js +3 -0
  250. package/dist/organisms/jl-drawer.d.ts +50 -0
  251. package/dist/organisms/jl-drawer.js +141 -0
  252. package/dist/organisms/jl-navbar.css_raw.js +3 -0
  253. package/dist/organisms/jl-navbar.d.ts +32 -0
  254. package/dist/organisms/jl-navbar.js +121 -0
  255. package/dist/organisms/jl-page-header.css_raw.js +3 -0
  256. package/dist/organisms/jl-page-header.d.ts +26 -0
  257. package/dist/organisms/jl-page-header.js +85 -0
  258. package/dist/organisms/jl-side-nav.css_raw.js +3 -0
  259. package/dist/organisms/jl-side-nav.d.ts +60 -0
  260. package/dist/organisms/jl-side-nav.js +269 -0
  261. package/dist/organisms/jl-table.css_raw.js +3 -0
  262. package/dist/organisms/jl-table.d.ts +109 -0
  263. package/dist/organisms/jl-table.js +318 -0
  264. package/dist/organisms/jl-toaster.css_raw.js +3 -0
  265. package/dist/organisms/jl-toaster.d.ts +48 -0
  266. package/dist/organisms/jl-toaster.js +142 -0
  267. package/dist/organisms/jl-tree.css_raw.js +3 -0
  268. package/dist/organisms/jl-tree.d.ts +59 -0
  269. package/dist/organisms/jl-tree.js +198 -0
  270. package/dist/styles/base.css_raw.js +3 -0
  271. package/dist/styles/control.css_raw.js +3 -0
  272. package/dist/styles/floating.css_raw.js +3 -0
  273. package/dist/styles/shared.d.ts +8 -0
  274. package/dist/styles/shared.js +14 -0
  275. package/dist/styles/tokens.css_raw.js +3 -0
  276. package/dist/templates/jl-app-shell.css_raw.js +3 -0
  277. package/dist/templates/jl-app-shell.d.ts +37 -0
  278. package/dist/templates/jl-app-shell.js +150 -0
  279. package/dist/templates/jl-split-view.css_raw.js +3 -0
  280. package/dist/templates/jl-split-view.d.ts +49 -0
  281. package/dist/templates/jl-split-view.js +149 -0
  282. package/dist/tokens.css +188 -0
  283. package/dist/types/calendar.types.d.ts +11 -0
  284. package/dist/types/files.types.d.ts +23 -0
  285. package/dist/types/floating.types.d.ts +13 -0
  286. package/dist/types/fuzzy.types.d.ts +10 -0
  287. package/dist/types/highlight.types.d.ts +6 -0
  288. package/dist/types/hotkey.types.d.ts +19 -0
  289. package/dist/types/jl-accordion.types.d.ts +2 -0
  290. package/dist/types/jl-avatar.types.d.ts +10 -0
  291. package/dist/types/jl-breadcrumb.types.d.ts +6 -0
  292. package/dist/types/jl-button.types.d.ts +3 -0
  293. package/dist/types/jl-card.types.d.ts +2 -0
  294. package/dist/types/jl-chip.types.d.ts +1 -0
  295. package/dist/types/jl-combobox.types.d.ts +8 -0
  296. package/dist/types/jl-command-palette.types.d.ts +22 -0
  297. package/dist/types/jl-confirm.types.d.ts +10 -0
  298. package/dist/types/jl-dialog.types.d.ts +1 -0
  299. package/dist/types/jl-divider.types.d.ts +2 -0
  300. package/dist/types/jl-drawer.types.d.ts +4 -0
  301. package/dist/types/jl-empty.types.d.ts +2 -0
  302. package/dist/types/jl-field.types.d.ts +2 -0
  303. package/dist/types/jl-input.types.d.ts +1 -0
  304. package/dist/types/jl-link.types.d.ts +2 -0
  305. package/dist/types/jl-menu.types.d.ts +22 -0
  306. package/dist/types/jl-navbar.types.d.ts +6 -0
  307. package/dist/types/jl-progress.types.d.ts +3 -0
  308. package/dist/types/jl-radio-group.types.d.ts +10 -0
  309. package/dist/types/jl-segmented.types.d.ts +7 -0
  310. package/dist/types/jl-select.types.d.ts +12 -0
  311. package/dist/types/jl-side-nav.types.d.ts +17 -0
  312. package/dist/types/jl-skeleton.types.d.ts +2 -0
  313. package/dist/types/jl-slider.types.d.ts +5 -0
  314. package/dist/types/jl-split-view.types.d.ts +2 -0
  315. package/dist/types/jl-stat.types.d.ts +2 -0
  316. package/dist/types/jl-steps.types.d.ts +8 -0
  317. package/dist/types/jl-switch.types.d.ts +1 -0
  318. package/dist/types/jl-table.types.d.ts +30 -0
  319. package/dist/types/jl-tabs.types.d.ts +2 -0
  320. package/dist/types/jl-timeline.types.d.ts +10 -0
  321. package/dist/types/jl-toast.types.d.ts +2 -0
  322. package/dist/types/jl-toaster.types.d.ts +23 -0
  323. package/dist/types/jl-tree.types.d.ts +26 -0
  324. package/dist/types/key-shortcut.types.d.ts +9 -0
  325. package/dist/types/keycaps.types.d.ts +7 -0
  326. package/dist/types/option-filter.types.d.ts +10 -0
  327. package/dist/types/options.types.d.ts +4 -0
  328. package/dist/types/pagination.types.d.ts +8 -0
  329. package/dist/types/roving-index.types.d.ts +2 -0
  330. package/dist/types/sparkline.types.d.ts +11 -0
  331. package/package.json +102 -4
@@ -0,0 +1,61 @@
1
+ import { BASE_STYLES } from "../styles/shared.js";
2
+ import { JlElement } from "../base/jl-element.js";
3
+ import { oneOf } from "../lib/attributes.js";
4
+ import { define } from "../lib/define.js";
5
+ import { JlAccordionItem } from "./jl-accordion-item.js";
6
+ import jl_accordion_default from "./jl-accordion.css_raw.js";
7
+ import { css } from "@jadis/core";
8
+ import { jsx } from "@jadis/core/jsx-runtime";
9
+ // src/molecules/jl-accordion.tsx
10
+ var ACCORDION_VARIANTS = ["plain", "bordered"];
11
+ define(JlAccordionItem);
12
+ var TOGGLE = "toggle";
13
+ /**
14
+ * A list of `jl-accordion-item`s. One item opens at a time (opening one closes the others) unless `multiple` is
15
+ * set. `bordered` puts the items in a box with lines between them.
16
+ */
17
+ var JlAccordion = class extends JlElement {
18
+ static selector = "jl-accordion";
19
+ /** Lets several items stay open together. */
20
+ multiple = this.useChange(false, () => this.keepOneOpen(), { attribute: "multiple" });
21
+ variant = this.useChange("plain", (value) => this.reflect("variant", value), {
22
+ attribute: "variant",
23
+ parse: oneOf(ACCORDION_VARIANTS, "plain")
24
+ });
25
+ templateHtml() {
26
+ return /* @__PURE__ */ jsx("div", {
27
+ class: "accordion",
28
+ attrs: { part: "base" },
29
+ children: /* @__PURE__ */ jsx("slot", {})
30
+ });
31
+ }
32
+ templateCss() {
33
+ return css`${BASE_STYLES}${jl_accordion_default}`;
34
+ }
35
+ onConnect() {
36
+ this.keepOneOpen();
37
+ this.addEventListener(TOGGLE, (event) => this.onToggle(event), {
38
+ capture: true,
39
+ signal: this.killSignal
40
+ });
41
+ }
42
+ items() {
43
+ return [...this.children].filter((child) => child instanceof JlAccordionItem);
44
+ }
45
+ onToggle(event) {
46
+ const item = event.target;
47
+ const opened = event.detail === true;
48
+ if (!(item instanceof JlAccordionItem) || item.parentElement !== this || !opened || this.multiple.get()) return;
49
+ this.closeAllBut(item);
50
+ }
51
+ /** Without `multiple`, only the first open item stays open. */
52
+ keepOneOpen() {
53
+ const firstOpen = this.items().find((item) => item.open.get());
54
+ if (firstOpen !== void 0 && !this.multiple.get()) this.closeAllBut(firstOpen);
55
+ }
56
+ closeAllBut(kept) {
57
+ for (const item of this.items()) if (item !== kept && item.open.get()) item.open.set(false);
58
+ }
59
+ };
60
+ JlAccordion.register();
61
+ export { ACCORDION_VARIANTS, JlAccordion };
@@ -0,0 +1,3 @@
1
+ // src/molecules/jl-alert.css?raw
2
+ var jl_alert_default = ":host {\n display: block;\n --fg: var(--jl-info);\n --bg: var(--jl-info-soft);\n --border: color-mix(in srgb, var(--fg) 24%, var(--bg));\n}\n\n:host([tone=\"accent\"]) {\n --fg: var(--jl-accent);\n --bg: var(--jl-accent-soft);\n}\n\n:host([tone=\"ok\"]) {\n --fg: var(--jl-ok);\n --bg: var(--jl-ok-soft);\n}\n\n:host([tone=\"warn\"]) {\n --fg: var(--jl-warn);\n --bg: var(--jl-warn-soft);\n}\n\n:host([tone=\"danger\"]) {\n --fg: var(--jl-danger);\n --bg: var(--jl-danger-soft);\n}\n\n:host([tone=\"neutral\"]) {\n --fg: var(--jl-muted);\n --bg: var(--jl-surface-2);\n --border: var(--jl-line);\n}\n\n.alert {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px 14px;\n border: 1px solid var(--border);\n border-radius: var(--jl-radius);\n background: var(--bg);\n color: var(--jl-text-2);\n font-size: var(--jl-font-md);\n line-height: 1.5;\n}\n\n:host([dismissible]) .alert {\n padding-right: 8px;\n}\n\n.icon {\n /* Centred on the first line of text: 21px high at this size. */\n margin-top: 1.5px;\n color: var(--fg);\n}\n\n.content {\n display: grid;\n flex: 1;\n gap: 2px;\n min-width: 0;\n}\n\n.heading {\n color: var(--jl-text);\n font-weight: 650;\n}\n\n.actions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin-top: 10px;\n}\n\n.close {\n margin: -5px 0 -5px 0;\n --jl-accent: var(--fg);\n --jl-accent-soft: color-mix(in srgb, var(--fg) 12%, transparent);\n}\n\n::slotted(a) {\n color: inherit;\n font-weight: 600;\n}\n";
3
+ export { jl_alert_default as default };
@@ -0,0 +1,38 @@
1
+ import { JlElement } from '../base/jl-element';
2
+ import type { Tone } from '../types/options.types';
3
+ /**
4
+ * A message in the flow of the page, coloured by its tone: a tip, a success, a warning, an error. The text goes
5
+ * in the default slot, buttons in `slot="actions"`. A `dismissible` alert has an × that hides it.
6
+ */
7
+ export declare class JlAlert extends JlElement {
8
+ static readonly selector = "jl-alert";
9
+ readonly events: Readonly<import("@jadis/core").UseEventsHandler<{
10
+ dismiss: undefined;
11
+ }>>;
12
+ readonly tone: Readonly<Readonly<{
13
+ get(): Tone;
14
+ set(setter: ((prevState: Tone) => Tone) | Tone): void;
15
+ }>>;
16
+ readonly heading: Readonly<Readonly<{
17
+ get(): string;
18
+ set(setter: string | ((prevState: string) => string)): void;
19
+ }>>;
20
+ /** An icon name in place of the tone's own; `none` shows no icon. */
21
+ readonly icon: Readonly<Readonly<{
22
+ get(): string;
23
+ set(setter: string | ((prevState: string) => string)): void;
24
+ }>>;
25
+ /** Shows an × that hides the alert and fires `dismiss`. */
26
+ readonly dismissible: Readonly<Readonly<{
27
+ get(): boolean;
28
+ set(setter: boolean | ((prevState: boolean) => boolean)): void;
29
+ }>>;
30
+ private readonly _refs;
31
+ /** Hides the alert as its × does, and fires `dismiss`. */
32
+ dismiss(): void;
33
+ templateHtml(): Node;
34
+ templateCss(): string;
35
+ onConnect(): void;
36
+ private renderActions;
37
+ private renderIcon;
38
+ }
@@ -0,0 +1,131 @@
1
+ import { BASE_STYLES } from "../styles/shared.js";
2
+ import { JlElement } from "../base/jl-element.js";
3
+ import { oneOf } from "../lib/attributes.js";
4
+ import { registerIcons } from "../lib/icons.js";
5
+ import { TONES, TONE_ICONS } from "../lib/options.js";
6
+ import { hasSlotted } from "../lib/slots.js";
7
+ import { JlIcon } from "../atoms/jl-icon.js";
8
+ import { JlButton } from "../atoms/jl-button.js";
9
+ import jl_alert_default from "./jl-alert.css_raw.js";
10
+ import { css } from "@jadis/core";
11
+ import { CircleCheck, CircleX, Info, Sparkles, TriangleAlert, X } from "lucide";
12
+ import { jsx, jsxs } from "@jadis/core/jsx-runtime";
13
+ // src/molecules/jl-alert.tsx
14
+ registerIcons({
15
+ "circle-check": CircleCheck,
16
+ "circle-x": CircleX,
17
+ info: Info,
18
+ sparkles: Sparkles,
19
+ "triangle-alert": TriangleAlert,
20
+ x: X
21
+ });
22
+ var ICON_SIZE = 18;
23
+ var NO_ICON = "none";
24
+ /** Warnings and failures interrupt a screen reader; the other tones wait for a pause. */
25
+ var TONE_ROLES = {
26
+ accent: "status",
27
+ danger: "alert",
28
+ info: "status",
29
+ neutral: "status",
30
+ ok: "status",
31
+ warn: "alert"
32
+ };
33
+ /**
34
+ * A message in the flow of the page, coloured by its tone: a tip, a success, a warning, an error. The text goes
35
+ * in the default slot, buttons in `slot="actions"`. A `dismissible` alert has an × that hides it.
36
+ */
37
+ var JlAlert = class extends JlElement {
38
+ static selector = "jl-alert";
39
+ events = this.useEvents();
40
+ tone = this.useChange("info", (value) => {
41
+ this.reflect("tone", value);
42
+ this._refs.alert.setAttribute("role", TONE_ROLES[value]);
43
+ this.renderIcon();
44
+ }, {
45
+ attribute: "tone",
46
+ parse: oneOf(TONES, "info")
47
+ });
48
+ heading = this.useChange("", (value) => {
49
+ this._refs.heading.textContent = value;
50
+ this._refs.heading.hidden = value === "";
51
+ }, { attribute: "heading" });
52
+ /** An icon name in place of the tone's own; `none` shows no icon. */
53
+ icon = this.useChange("", () => this.renderIcon(), { attribute: "icon" });
54
+ /** Shows an × that hides the alert and fires `dismiss`. */
55
+ dismissible = this.useChange(false, (value) => {
56
+ this._refs.close.hidden = !value;
57
+ this.reflect("dismissible", value);
58
+ }, { attribute: "dismissible" });
59
+ _refs = this.useRefs((ref) => ({
60
+ actions: ref(".actions"),
61
+ actionsSlot: ref("slot[name=\"actions\"]"),
62
+ alert: ref(".alert"),
63
+ close: ref(".close"),
64
+ heading: ref(".heading"),
65
+ icon: ref(".icon")
66
+ }));
67
+ /** Hides the alert as its × does, and fires `dismiss`. */
68
+ dismiss() {
69
+ this.hidden = true;
70
+ this.events.emit("dismiss");
71
+ }
72
+ templateHtml() {
73
+ return /* @__PURE__ */ jsxs("div", {
74
+ class: "alert",
75
+ role: "status",
76
+ attrs: { part: "base" },
77
+ children: [
78
+ /* @__PURE__ */ jsx(JlIcon, {
79
+ class: "icon",
80
+ size: ICON_SIZE
81
+ }),
82
+ /* @__PURE__ */ jsxs("div", {
83
+ class: "content",
84
+ children: [
85
+ /* @__PURE__ */ jsx("p", {
86
+ class: "heading",
87
+ hidden: true
88
+ }),
89
+ /* @__PURE__ */ jsx("div", {
90
+ class: "text",
91
+ children: /* @__PURE__ */ jsx("slot", {})
92
+ }),
93
+ /* @__PURE__ */ jsx("div", {
94
+ class: "actions",
95
+ hidden: true,
96
+ children: /* @__PURE__ */ jsx("slot", { name: "actions" })
97
+ })
98
+ ]
99
+ }),
100
+ /* @__PURE__ */ jsx(JlButton, {
101
+ class: "close",
102
+ variant: "ghost",
103
+ icon: "x",
104
+ hint: "Dismiss",
105
+ size: "sm",
106
+ hidden: true
107
+ })
108
+ ]
109
+ });
110
+ }
111
+ templateCss() {
112
+ return css`${BASE_STYLES}${jl_alert_default}`;
113
+ }
114
+ onConnect() {
115
+ this._refs.close.events.register("press", () => this.dismiss());
116
+ this.renderActions();
117
+ this.on(this._refs.actionsSlot, "slotchange", () => this.renderActions());
118
+ }
119
+ renderActions() {
120
+ this._refs.actions.hidden = !hasSlotted(this._refs.actionsSlot);
121
+ }
122
+ renderIcon() {
123
+ const own = this.icon.get();
124
+ const name = own === "" ? TONE_ICONS[this.tone.get()] : own;
125
+ this._refs.icon.name.set(name === NO_ICON ? "" : name);
126
+ this._refs.icon.hidden = name === NO_ICON;
127
+ this.reflect("has-icon", name !== NO_ICON);
128
+ }
129
+ };
130
+ JlAlert.register();
131
+ export { JlAlert };
@@ -0,0 +1,3 @@
1
+ // src/molecules/jl-avatar-group.css?raw
2
+ var jl_avatar_group_default = ":host {\n display: inline-flex;\n vertical-align: middle;\n --overlap: 6px;\n --ring-color: var(--jl-surface);\n}\n\n:host([size=\"sm\"]) {\n --overlap: 4px;\n}\n\n:host([size=\"lg\"]) {\n --overlap: 8px;\n}\n\n:host([size=\"xl\"]) {\n --overlap: 10px;\n}\n\n.group {\n display: inline-flex;\n align-items: center;\n padding-left: var(--overlap);\n}\n\njl-avatar {\n margin-left: calc(var(--overlap) * -1);\n --ring: 2px;\n --ring-color: inherit;\n}\n\n.more {\n font-variant-numeric: tabular-nums;\n}\n";
3
+ export { jl_avatar_group_default as default };
@@ -0,0 +1,28 @@
1
+ import { JlElement } from '../base/jl-element';
2
+ import type { AvatarItem, AvatarSize } from '../types/jl-avatar.types';
3
+ /**
4
+ * A few people at a glance: their avatars overlap, each ringed with the surface colour. Past `max`, a last
5
+ * avatar counts the others ("+3") and names them in its tooltip.
6
+ */
7
+ export declare class JlAvatarGroup extends JlElement {
8
+ static readonly selector = "jl-avatar-group";
9
+ /** The people, in order: `[{ "name": "Ada Lovelace", "src": "/ada.jpg" }]`. */
10
+ readonly items: Readonly<Readonly<{
11
+ get(): AvatarItem[];
12
+ set(setter: AvatarItem[] | ((prevState: AvatarItem[]) => AvatarItem[])): void;
13
+ }>>;
14
+ /** How many avatars show before the count; 0 shows them all. */
15
+ readonly max: Readonly<Readonly<{
16
+ get(): number;
17
+ set(setter: number | ((prevState: number) => number)): void;
18
+ }>>;
19
+ readonly size: Readonly<Readonly<{
20
+ get(): AvatarSize;
21
+ set(setter: ((prevState: AvatarSize) => AvatarSize) | AvatarSize): void;
22
+ }>>;
23
+ private readonly _refs;
24
+ templateHtml(): Node;
25
+ templateCss(): string;
26
+ private render;
27
+ private countAvatar;
28
+ }
@@ -0,0 +1,69 @@
1
+ import { BASE_STYLES } from "../styles/shared.js";
2
+ import { JlElement } from "../base/jl-element.js";
3
+ import { jsonOf, oneOf } from "../lib/attributes.js";
4
+ import { splitVisible } from "../lib/avatar.js";
5
+ import { AVATAR_SIZES, JlAvatar } from "../atoms/jl-avatar.js";
6
+ import jl_avatar_group_default from "./jl-avatar-group.css_raw.js";
7
+ import { css } from "@jadis/core";
8
+ import { jsx } from "@jadis/core/jsx-runtime";
9
+ // src/molecules/jl-avatar-group.tsx
10
+ var NAME_SEPARATOR = ", ";
11
+ /**
12
+ * A few people at a glance: their avatars overlap, each ringed with the surface colour. Past `max`, a last
13
+ * avatar counts the others ("+3") and names them in its tooltip.
14
+ */
15
+ var JlAvatarGroup = class extends JlElement {
16
+ static selector = "jl-avatar-group";
17
+ /** The people, in order: `[{ "name": "Ada Lovelace", "src": "/ada.jpg" }]`. */
18
+ items = this.useChange([], () => this.render(), {
19
+ attribute: "items",
20
+ parse: jsonOf([])
21
+ });
22
+ /** How many avatars show before the count; 0 shows them all. */
23
+ max = this.useChange(0, () => this.render(), { attribute: "max" });
24
+ size = this.useChange("md", (value) => {
25
+ this.reflect("size", value);
26
+ this.render();
27
+ }, {
28
+ attribute: "size",
29
+ parse: oneOf(AVATAR_SIZES, "md")
30
+ });
31
+ _refs = this.useRefs((ref) => ({ group: ref(".group") }));
32
+ templateHtml() {
33
+ return /* @__PURE__ */ jsx("div", {
34
+ class: "group",
35
+ role: "group",
36
+ attrs: { part: "base" }
37
+ });
38
+ }
39
+ templateCss() {
40
+ return css`${BASE_STYLES}${jl_avatar_group_default}`;
41
+ }
42
+ render() {
43
+ const items = this.items.get().filter((item) => typeof item?.name === "string");
44
+ const { shown, hidden } = splitVisible(items, this.max.get());
45
+ const size = this.size.get();
46
+ const avatars = shown.map((item) => /* @__PURE__ */ jsx(JlAvatar, {
47
+ name: item.name,
48
+ src: item.src ?? "",
49
+ size,
50
+ title: item.name
51
+ }));
52
+ const more = hidden.length === 0 ? [] : [this.countAvatar(hidden, size)];
53
+ this._refs.group.replaceChildren(...avatars, ...more);
54
+ this._refs.group.setAttribute("aria-label", `${items.length} ${items.length === 1 ? "person" : "people"}`);
55
+ }
56
+ countAvatar(hidden, size) {
57
+ const names = hidden.map((item) => item.name).join(NAME_SEPARATOR);
58
+ const avatar = /* @__PURE__ */ jsx(JlAvatar, {
59
+ class: "more",
60
+ size,
61
+ label: `${hidden.length} more: ${names}`
62
+ });
63
+ avatar.title = names;
64
+ avatar.textContent = `+${hidden.length}`;
65
+ return avatar;
66
+ }
67
+ };
68
+ JlAvatarGroup.register();
69
+ export { JlAvatarGroup };
@@ -0,0 +1,3 @@
1
+ // src/molecules/jl-breadcrumb.css?raw
2
+ var jl_breadcrumb_default = ":host {\n display: block;\n}\n\nol {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px 0;\n padding: 0;\n list-style: none;\n font-size: var(--jl-font-sm);\n line-height: 20px;\n}\n\nli {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n}\n\n.separator {\n margin: 0 6px;\n color: var(--jl-faint);\n}\n\n.crumb {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n padding: 2px 4px;\n border-radius: var(--jl-radius-xs);\n color: var(--jl-muted);\n text-decoration: none;\n}\n\na.crumb:hover {\n color: var(--jl-text);\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n\n.crumb[aria-current=\"page\"] {\n color: var(--jl-text);\n font-weight: 600;\n}\n\n.label {\n max-width: 24ch;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.more {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 22px;\n padding: 0;\n border: none;\n border-radius: var(--jl-radius-xs);\n background: none;\n color: var(--jl-muted);\n cursor: pointer;\n}\n\n.more:hover {\n background: var(--jl-surface-3);\n color: var(--jl-text);\n}\n\n/* The first crumb's text lines up with what is under the trail, its padding hanging out to the left. */\nli:first-child .crumb {\n margin-left: -4px;\n}\n";
3
+ export { jl_breadcrumb_default as default };
@@ -0,0 +1,35 @@
1
+ import { JlElement } from '../base/jl-element';
2
+ import type { BreadcrumbItem } from '../types/jl-breadcrumb.types';
3
+ /**
4
+ * Where the page sits in a hierarchy: a trail of links, the last one being the current page. With `max`, a long
5
+ * trail folds its middle into a button that unfolds it.
6
+ */
7
+ export declare class JlBreadcrumb extends JlElement {
8
+ static readonly selector = "jl-breadcrumb";
9
+ readonly items: Readonly<Readonly<{
10
+ get(): BreadcrumbItem[];
11
+ set(setter: BreadcrumbItem[] | ((prevState: BreadcrumbItem[]) => BreadcrumbItem[])): void;
12
+ }>>;
13
+ /** The most items shown before the middle folds; 0 never folds. */
14
+ readonly max: Readonly<Readonly<{
15
+ get(): number;
16
+ set(setter: number | ((prevState: number) => number)): void;
17
+ }>>;
18
+ /** The trail's name for screen readers. */
19
+ readonly label: Readonly<Readonly<{
20
+ get(): string;
21
+ set(setter: string | ((prevState: string) => string)): void;
22
+ }>>;
23
+ private readonly _state;
24
+ private readonly _refs;
25
+ templateHtml(): Node;
26
+ templateCss(): string;
27
+ onConnect(): void;
28
+ /** A new trail starts folded. */
29
+ private renderTrail;
30
+ private render;
31
+ private crumb;
32
+ private moreButton;
33
+ /** Unfolds the middle, and moves the focus to the first item it showed. */
34
+ private expand;
35
+ }
@@ -0,0 +1,126 @@
1
+ import { BASE_STYLES } from "../styles/shared.js";
2
+ import { JlElement } from "../base/jl-element.js";
3
+ import { jsonOf } from "../lib/attributes.js";
4
+ import { registerIcons } from "../lib/icons.js";
5
+ import { JlIcon } from "../atoms/jl-icon.js";
6
+ import jl_breadcrumb_default from "./jl-breadcrumb.css_raw.js";
7
+ import { css } from "@jadis/core";
8
+ import { ChevronRight, Ellipsis } from "lucide";
9
+ import { jsx, jsxs } from "@jadis/core/jsx-runtime";
10
+ // src/molecules/jl-breadcrumb.tsx
11
+ registerIcons({
12
+ "chevron-right": ChevronRight,
13
+ ellipsis: Ellipsis
14
+ });
15
+ var ICON_SIZE = 15;
16
+ var SEPARATOR_SIZE = 14;
17
+ var DEFAULT_LABEL = "Breadcrumb";
18
+ var MIN_MAX = 2;
19
+ /** The crumbs shown: all of them, or the first, a gap for the middle, and the last `max - 1`. */
20
+ function visibleCrumbs(items, max, expanded) {
21
+ const all = items.map((item, index) => ({
22
+ index,
23
+ item
24
+ }));
25
+ if (expanded || max < MIN_MAX || items.length <= max) return all;
26
+ const tail = all.slice(items.length - (max - 1));
27
+ return [
28
+ ...all.slice(0, 1),
29
+ { hidden: items.length - max },
30
+ ...tail
31
+ ];
32
+ }
33
+ /**
34
+ * Where the page sits in a hierarchy: a trail of links, the last one being the current page. With `max`, a long
35
+ * trail folds its middle into a button that unfolds it.
36
+ */
37
+ var JlBreadcrumb = class extends JlElement {
38
+ static selector = "jl-breadcrumb";
39
+ items = this.useChange([], () => this.renderTrail(), {
40
+ attribute: "items",
41
+ parse: jsonOf([])
42
+ });
43
+ /** The most items shown before the middle folds; 0 never folds. */
44
+ max = this.useChange(0, () => this.render(), { attribute: "max" });
45
+ /** The trail's name for screen readers. */
46
+ label = this.useChange(DEFAULT_LABEL, (value) => {
47
+ this._refs.nav.setAttribute("aria-label", value || DEFAULT_LABEL);
48
+ }, { attribute: "label" });
49
+ _state = { expanded: false };
50
+ _refs = this.useRefs((ref) => ({
51
+ list: ref("ol"),
52
+ nav: ref("nav")
53
+ }));
54
+ templateHtml() {
55
+ return /* @__PURE__ */ jsx("nav", {
56
+ attrs: { part: "base" },
57
+ children: /* @__PURE__ */ jsx("ol", {})
58
+ });
59
+ }
60
+ templateCss() {
61
+ return css`${BASE_STYLES}${jl_breadcrumb_default}`;
62
+ }
63
+ onConnect() {
64
+ this.on(this._refs.list, "click", (event) => {
65
+ if (event.target.closest(".more") !== null) this.expand();
66
+ });
67
+ }
68
+ /** A new trail starts folded. */
69
+ renderTrail() {
70
+ this._state.expanded = false;
71
+ this.render();
72
+ }
73
+ render() {
74
+ const items = this.items.get();
75
+ const crumbs = visibleCrumbs(items, this.max.get(), this._state.expanded);
76
+ const lastIndex = items.length - 1;
77
+ this._refs.list.replaceChildren(...crumbs.map((crumb, position) => /* @__PURE__ */ jsxs("li", { children: [position > 0 ? /* @__PURE__ */ jsx(JlIcon, {
78
+ class: "separator",
79
+ name: "chevron-right",
80
+ size: SEPARATOR_SIZE
81
+ }) : "", "hidden" in crumb ? this.moreButton(crumb.hidden) : this.crumb(crumb.item, crumb.index === lastIndex)] })));
82
+ }
83
+ crumb(item, current) {
84
+ const ariaCurrent = current ? "page" : void 0;
85
+ const content = [item.icon === void 0 ? "" : /* @__PURE__ */ jsx(JlIcon, {
86
+ name: item.icon,
87
+ size: ICON_SIZE
88
+ }), /* @__PURE__ */ jsx("span", {
89
+ class: "label",
90
+ children: item.label
91
+ })];
92
+ if (item.href === void 0) return /* @__PURE__ */ jsx("span", {
93
+ class: "crumb",
94
+ title: item.label,
95
+ "aria-current": ariaCurrent,
96
+ children: content
97
+ });
98
+ return /* @__PURE__ */ jsx("a", {
99
+ class: "crumb",
100
+ href: item.href,
101
+ title: item.label,
102
+ "aria-current": ariaCurrent,
103
+ children: content
104
+ });
105
+ }
106
+ moreButton(hidden) {
107
+ return /* @__PURE__ */ jsx("button", {
108
+ type: "button",
109
+ class: "more",
110
+ "aria-label": `Show ${hidden} more`,
111
+ title: `Show ${hidden} more`,
112
+ children: /* @__PURE__ */ jsx(JlIcon, {
113
+ name: "ellipsis",
114
+ size: ICON_SIZE
115
+ })
116
+ });
117
+ }
118
+ /** Unfolds the middle, and moves the focus to the first item it showed. */
119
+ expand() {
120
+ this._state.expanded = true;
121
+ this.render();
122
+ this._refs.list.querySelector("li:nth-child(2) .crumb")?.focus();
123
+ }
124
+ };
125
+ JlBreadcrumb.register();
126
+ export { JlBreadcrumb };
@@ -0,0 +1,3 @@
1
+ // src/molecules/jl-calendar.css?raw
2
+ var jl_calendar_default = ":host {\n display: inline-block;\n vertical-align: top;\n --cell: 36px;\n}\n\n:host([size=\"sm\"]) {\n --cell: 32px;\n}\n\n:host([size=\"lg\"]) {\n --cell: 42px;\n}\n\n.calendar {\n display: inline-grid;\n gap: 6px;\n padding: 12px;\n border: 1px solid var(--jl-line);\n border-radius: var(--jl-radius-lg);\n background: var(--jl-surface);\n color: var(--jl-text);\n}\n\n:host([invalid]) .calendar {\n border-color: var(--jl-danger);\n}\n\nheader {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.title {\n flex: 1;\n font-size: var(--jl-font-md);\n font-weight: 650;\n text-align: center;\n}\n\n/* \"octobre 2026\": a title starts with a capital, whatever the locale writes. */\n.title::first-letter {\n text-transform: uppercase;\n}\n\n.nav {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n padding: 0;\n border: none;\n border-radius: var(--jl-radius-sm);\n background: none;\n color: var(--jl-text-2);\n cursor: pointer;\n}\n\n.nav:hover {\n background: var(--jl-surface-3);\n color: var(--jl-text);\n}\n\n.nav:disabled {\n background: none;\n color: var(--jl-faint);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\nth {\n width: var(--cell);\n height: 28px;\n padding: 0;\n color: var(--jl-muted);\n font-size: 11px;\n font-weight: 600;\n text-align: center;\n}\n\ntd {\n width: var(--cell);\n height: var(--cell);\n padding: 2px;\n text-align: center;\n cursor: pointer;\n}\n\n.number {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n border-radius: var(--jl-radius-sm);\n font-size: var(--jl-font-sm);\n font-variant-numeric: tabular-nums;\n transition:\n background var(--jl-fast) var(--jl-ease),\n color var(--jl-fast) var(--jl-ease);\n}\n\ntd:hover .number {\n background: var(--jl-surface-3);\n}\n\ntd:focus-visible {\n box-shadow: none;\n}\n\ntd:focus-visible .number {\n box-shadow: var(--jl-focus-ring);\n}\n\ntd.outside .number {\n color: var(--jl-muted);\n}\n\ntd[aria-current=\"date\"] .number {\n color: var(--jl-accent);\n font-weight: 700;\n box-shadow: inset 0 0 0 1px var(--jl-accent-line);\n}\n\ntd[aria-disabled=\"true\"] {\n cursor: not-allowed;\n}\n\ntd[aria-disabled=\"true\"] .number {\n background: none;\n color: var(--jl-faint);\n text-decoration: line-through;\n text-decoration-color: color-mix(in srgb, var(--jl-faint) 60%, transparent);\n}\n\ntd[aria-selected=\"true\"] .number {\n background: var(--jl-accent);\n color: var(--jl-on-accent);\n font-weight: 650;\n}\n\n:host([disabled]) .calendar {\n opacity: 0.55;\n}\n\n:host([disabled]) td {\n cursor: not-allowed;\n}\n\n:host([disabled]) td:hover .number {\n background: none;\n}\n";
3
+ export { jl_calendar_default as default };
@@ -0,0 +1,101 @@
1
+ import { JlFormControl } from '../base/jl-form-control';
2
+ import type { Weekday } from '../types/calendar.types';
3
+ import type { ControlSize } from '../types/options.types';
4
+ /**
5
+ * A month to pick a day from. Arrows move by day and week, Page Up and Page Down by month (by year with Shift),
6
+ * Home and End to the ends of the week, Enter chooses. Month and weekday names follow the `locale`; days outside
7
+ * `min` and `max` cannot be chosen. `value` is an ISO date (`2026-10-25`).
8
+ */
9
+ export declare class JlCalendar extends JlFormControl {
10
+ static readonly selector = "jl-calendar";
11
+ /** `change` when the chosen day changes; `pick` each time a day is chosen, even the one already chosen. */
12
+ readonly events: Readonly<import("@jadis/core").UseEventsHandler<{
13
+ change: string;
14
+ pick: string;
15
+ }>>;
16
+ readonly value: Readonly<Readonly<{
17
+ get(): string;
18
+ set(setter: string | ((prevState: string) => string)): void;
19
+ }>>;
20
+ /** The first day that can be chosen, as an ISO date. */
21
+ readonly min: Readonly<Readonly<{
22
+ get(): string;
23
+ set(setter: string | ((prevState: string) => string)): void;
24
+ }>>;
25
+ /** The last day that can be chosen, as an ISO date. */
26
+ readonly max: Readonly<Readonly<{
27
+ get(): string;
28
+ set(setter: string | ((prevState: string) => string)): void;
29
+ }>>;
30
+ /** The day weeks start on: 0 for Sunday, 1 for Monday, up to 6 for Saturday. */
31
+ readonly firstDay: Readonly<Readonly<{
32
+ get(): Weekday;
33
+ set(setter: ((prevState: Weekday) => Weekday) | Weekday): void;
34
+ }>>;
35
+ /** The language of month and weekday names: `fr-CH`. The page's language by default. */
36
+ readonly locale: Readonly<Readonly<{
37
+ get(): string;
38
+ set(setter: string | ((prevState: string) => string)): void;
39
+ }>>;
40
+ /** The calendar's name for screen readers; the month's title names it otherwise. */
41
+ readonly label: Readonly<Readonly<{
42
+ get(): string;
43
+ set(setter: string | ((prevState: string) => string)): void;
44
+ }>>;
45
+ readonly required: Readonly<Readonly<{
46
+ get(): boolean;
47
+ set(setter: boolean | ((prevState: boolean) => boolean)): void;
48
+ }>>;
49
+ readonly disabled: Readonly<Readonly<{
50
+ get(): boolean;
51
+ set(setter: boolean | ((prevState: boolean) => boolean)): void;
52
+ }>>;
53
+ /** Draws the frame in the danger colour, for an error the page found itself. */
54
+ readonly invalid: Readonly<Readonly<{
55
+ get(): boolean;
56
+ set(setter: boolean | ((prevState: boolean) => boolean)): void;
57
+ }>>;
58
+ /** The size of the days: 32, 36 or 42 pixels. */
59
+ readonly size: Readonly<Readonly<{
60
+ get(): ControlSize;
61
+ set(setter: ((prevState: ControlSize) => ControlSize) | ControlSize): void;
62
+ }>>;
63
+ private readonly _titleId;
64
+ /** The month shown, and the day the arrows move from (the one focusable cell of the grid). */
65
+ private readonly _state;
66
+ private readonly _refs;
67
+ /** Focuses the day the arrows move from: the chosen one, or today, or the first of the month. */
68
+ focus(options?: FocusOptions): void;
69
+ /** Shows the month of a date (ISO), without choosing it. */
70
+ showMonth(iso: string): void;
71
+ templateHtml(): Node;
72
+ templateCss(): string;
73
+ onConnect(): void;
74
+ protected resetValue(): void;
75
+ protected setDisabledByForm(disabled: boolean): void;
76
+ private bounds;
77
+ private isOff;
78
+ private onDayClick;
79
+ private onKey;
80
+ /** Moves the focus to a day, turning the page when it is in another month. */
81
+ private moveFocus;
82
+ private turnPage;
83
+ private choose;
84
+ /** A new value: its month shows, the focus moves to it, and the form gets it (or nothing, when unreadable). */
85
+ private renderValue;
86
+ /** The month shown, moved to the nearest one with days that can be chosen: today may be before `min`. */
87
+ private viewWithin;
88
+ /** The day the grid lets focus on: the remembered one when it is on the page, else the first day it can. */
89
+ private rovingDate;
90
+ private renderPage;
91
+ /** The title is a live region: written only when the month changes, so it is announced once. */
92
+ private renderTitle;
93
+ private renderWeekdays;
94
+ private dayCell;
95
+ /** Only the remembered day is in the tab order: the arrows reach the others. */
96
+ private renderFocus;
97
+ /** The arrows of the header stop where no day of the next month could be chosen. */
98
+ private renderNavigation;
99
+ private renderValidity;
100
+ private renderDisabled;
101
+ }