@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,31 @@
1
+ import { JlElement } from '../base/jl-element';
2
+ import type { ControlSize } from '../types/options.types';
3
+ /** Copies a text to the clipboard, and says so for a moment. Fires `copy` with the text. */
4
+ export declare class JlCopyButton extends JlElement {
5
+ static readonly selector = "jl-copy-button";
6
+ readonly events: Readonly<import("@jadis/core").UseEventsHandler<{
7
+ copy: string;
8
+ }>>;
9
+ readonly value: Readonly<Readonly<{
10
+ get(): string;
11
+ set(setter: string | ((prevState: string) => string)): void;
12
+ }>>;
13
+ /** Shown beside the icon; without it the button is an icon with a tooltip. */
14
+ readonly label: Readonly<Readonly<{
15
+ get(): string;
16
+ set(setter: string | ((prevState: string) => string)): void;
17
+ }>>;
18
+ readonly size: Readonly<Readonly<{
19
+ get(): ControlSize;
20
+ set(setter: ((prevState: ControlSize) => ControlSize) | ControlSize): void;
21
+ }>>;
22
+ private readonly _timer;
23
+ private readonly _refs;
24
+ templateHtml(): Node;
25
+ templateCss(): string;
26
+ onConnect(): void;
27
+ onDisconnect(): void;
28
+ /** Copies the value now; resolves once the clipboard has it. */
29
+ copy(): Promise<void>;
30
+ private confirm;
31
+ }
@@ -0,0 +1,69 @@
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 { CONTROL_SIZES } from "../lib/options.js";
6
+ import { JlButton } from "../atoms/jl-button.js";
7
+ import jl_copy_button_default from "./jl-copy-button.css_raw.js";
8
+ import { css } from "@jadis/core";
9
+ import { Check, Copy } from "lucide";
10
+ import { jsx } from "@jadis/core/jsx-runtime";
11
+ // src/molecules/jl-copy-button.tsx
12
+ registerIcons({
13
+ check: Check,
14
+ copy: Copy
15
+ });
16
+ var CONFIRM_MS = 1600;
17
+ var COPY_ICON = "copy";
18
+ var DONE_ICON = "check";
19
+ /** Copies a text to the clipboard, and says so for a moment. Fires `copy` with the text. */
20
+ var JlCopyButton = class extends JlElement {
21
+ static selector = "jl-copy-button";
22
+ events = this.useEvents();
23
+ value = this.useChange("", () => void 0, { attribute: "value" });
24
+ /** Shown beside the icon; without it the button is an icon with a tooltip. */
25
+ label = this.useChange("", (value) => this._refs.button.label.set(value), { attribute: "label" });
26
+ size = this.useChange("sm", (value) => this._refs.button.size.set(value), {
27
+ attribute: "size",
28
+ parse: oneOf(CONTROL_SIZES, "sm")
29
+ });
30
+ _timer = { id: 0 };
31
+ _refs = this.useRefs((ref) => ({ button: ref("jl-button") }));
32
+ templateHtml() {
33
+ return /* @__PURE__ */ jsx(JlButton, {
34
+ variant: "ghost",
35
+ icon: COPY_ICON,
36
+ hint: "Copy"
37
+ });
38
+ }
39
+ templateCss() {
40
+ return css`${BASE_STYLES}${jl_copy_button_default}`;
41
+ }
42
+ onConnect() {
43
+ this._refs.button.events.register("press", () => void this.copy());
44
+ }
45
+ onDisconnect() {
46
+ window.clearTimeout(this._timer.id);
47
+ }
48
+ /** Copies the value now; resolves once the clipboard has it. */
49
+ async copy() {
50
+ const text = this.value.get();
51
+ await navigator.clipboard.writeText(text);
52
+ this.events.emit("copy", text);
53
+ this.confirm();
54
+ }
55
+ confirm() {
56
+ const button = this._refs.button;
57
+ button.icon.set(DONE_ICON);
58
+ button.hint.set("Copied");
59
+ this.reflect("copied", true);
60
+ window.clearTimeout(this._timer.id);
61
+ this._timer.id = window.setTimeout(() => {
62
+ button.icon.set(COPY_ICON);
63
+ button.hint.set("Copy");
64
+ this.reflect("copied", false);
65
+ }, CONFIRM_MS);
66
+ }
67
+ };
68
+ JlCopyButton.register();
69
+ export { JlCopyButton };
@@ -0,0 +1,3 @@
1
+ // src/molecules/jl-date-picker.css?raw
2
+ var jl_date_picker_default = ":host {\n display: block;\n /* As a grid or flex item, the field may be narrower than its text field would like. */\n min-width: 0;\n}\n\n.open:disabled {\n cursor: not-allowed;\n}\n\n:host([open]) .open {\n background: var(--jl-surface-3);\n color: var(--jl-text);\n}\n\n.popup {\n padding: 0;\n}\n\n/* The panel draws the frame: the calendar inside drops its own. */\n.calendar::part(base) {\n border: none;\n}\n";
3
+ export { jl_date_picker_default as default };
@@ -0,0 +1,109 @@
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 field for a date: it shows the date written for people (in the `locale`) and opens a calendar from its
6
+ * button, Alt + Down or Down. People may also type the date as ISO (`2026-10-25`). `value` and the form hold the
7
+ * ISO date.
8
+ */
9
+ export declare class JlDatePicker extends JlFormControl {
10
+ static readonly selector = "jl-date-picker";
11
+ readonly events: Readonly<import("@jadis/core").UseEventsHandler<{
12
+ change: string;
13
+ }>>;
14
+ /** The date, as ISO (`2026-10-25`); empty for none. */
15
+ readonly value: Readonly<Readonly<{
16
+ get(): string;
17
+ set(setter: string | ((prevState: string) => string)): void;
18
+ }>>;
19
+ readonly placeholder: Readonly<Readonly<{
20
+ get(): string;
21
+ set(setter: string | ((prevState: string) => string)): void;
22
+ }>>;
23
+ /** The field's name for screen readers, when no visible label names it. */
24
+ readonly label: Readonly<Readonly<{
25
+ get(): string;
26
+ set(setter: string | ((prevState: string) => string)): void;
27
+ }>>;
28
+ /** The first day that can be chosen, as ISO. */
29
+ readonly min: Readonly<Readonly<{
30
+ get(): string;
31
+ set(setter: string | ((prevState: string) => string)): void;
32
+ }>>;
33
+ /** The last day that can be chosen, as ISO. */
34
+ readonly max: Readonly<Readonly<{
35
+ get(): string;
36
+ set(setter: string | ((prevState: string) => string)): void;
37
+ }>>;
38
+ /** The language the date and the calendar are written in: `fr-CH`. The page's by default. */
39
+ readonly locale: Readonly<Readonly<{
40
+ get(): string;
41
+ set(setter: string | ((prevState: string) => string)): void;
42
+ }>>;
43
+ /** The day the calendar's weeks start on: 0 for Sunday, 1 for Monday. */
44
+ readonly firstDay: Readonly<Readonly<{
45
+ get(): Weekday;
46
+ set(setter: ((prevState: Weekday) => Weekday) | Weekday): void;
47
+ }>>;
48
+ /** Shows a button that empties the field while it holds a date. */
49
+ readonly clearable: Readonly<Readonly<{
50
+ get(): boolean;
51
+ set(setter: boolean | ((prevState: boolean) => boolean)): void;
52
+ }>>;
53
+ readonly required: Readonly<Readonly<{
54
+ get(): boolean;
55
+ set(setter: boolean | ((prevState: boolean) => boolean)): void;
56
+ }>>;
57
+ readonly disabled: Readonly<Readonly<{
58
+ get(): boolean;
59
+ set(setter: boolean | ((prevState: boolean) => boolean)): void;
60
+ }>>;
61
+ /** Draws the field in the danger colour, for an error the page found itself. */
62
+ readonly invalid: Readonly<Readonly<{
63
+ get(): boolean;
64
+ set(setter: boolean | ((prevState: boolean) => boolean)): void;
65
+ }>>;
66
+ readonly size: Readonly<Readonly<{
67
+ get(): ControlSize;
68
+ set(setter: ((prevState: ControlSize) => ControlSize) | ControlSize): void;
69
+ }>>;
70
+ private readonly _popupId;
71
+ private readonly _state;
72
+ private readonly _refs;
73
+ focus(options?: FocusOptions): void;
74
+ /** Opens the calendar, with the focus on its day. */
75
+ show(): void;
76
+ /** Closes the calendar. */
77
+ hide(): void;
78
+ templateHtml(): Node;
79
+ templateCss(): string;
80
+ onConnect(): void;
81
+ onDisconnect(): void;
82
+ protected resetValue(): void;
83
+ protected setDisabledByForm(disabled: boolean): void;
84
+ private isOpen;
85
+ /** Down (with or without Alt) opens the calendar. */
86
+ private onKey;
87
+ private onOpenPress;
88
+ private onToggle;
89
+ /** Escape closes the calendar and brings the focus back to the field, where it came from. */
90
+ private onPopupKey;
91
+ private onPick;
92
+ private openPopup;
93
+ private closePopup;
94
+ /** The typed text: an ISO date sets the value, an empty field clears it, anything else goes back to the date. */
95
+ private commitText;
96
+ /** Sets the value as people chose it, and says so when it changed. */
97
+ private commit;
98
+ private clearValue;
99
+ /** The value when it is a real ISO date, otherwise nothing. */
100
+ private validIso;
101
+ private display;
102
+ private renderValue;
103
+ private renderBound;
104
+ /** Required, and within min and max, as a native date field checks it. */
105
+ private renderValidity;
106
+ private renderMissing;
107
+ private renderClear;
108
+ private renderDisabled;
109
+ }
@@ -0,0 +1,322 @@
1
+ import { BASE_STYLES, CONTROL_STYLES, FLOATING_STYLES } from "../styles/shared.js";
2
+ import { JlFormControl } from "../base/jl-form-control.js";
3
+ import { clampedNumber, oneOf } from "../lib/attributes.js";
4
+ import { followAnchor } from "../lib/floating.js";
5
+ import { registerIcons } from "../lib/icons.js";
6
+ import { CONTROL_SIZES } from "../lib/options.js";
7
+ import { setOrRemove, uniqueId } from "../lib/dom.js";
8
+ import { JlIcon } from "../atoms/jl-icon.js";
9
+ import { compareDates, formatDate, parseIsoDate, toIsoDate } from "../lib/calendar.js";
10
+ import { pageLocale } from "../lib/locale.js";
11
+ import { JlCalendar } from "./jl-calendar.js";
12
+ import jl_date_picker_default from "./jl-date-picker.css_raw.js";
13
+ import { css } from "@jadis/core";
14
+ import { Calendar, X } from "lucide";
15
+ import { Fragment, jsx, jsxs } from "@jadis/core/jsx-runtime";
16
+ // src/molecules/jl-date-picker.tsx
17
+ registerIcons({
18
+ calendar: Calendar,
19
+ x: X
20
+ });
21
+ var ICON_SIZE = 16;
22
+ var ACTION_ICON_SIZE = 14;
23
+ var PLACEMENT = "bottom-start";
24
+ var MONDAY = 1;
25
+ var SUNDAY = 0;
26
+ var SATURDAY = 6;
27
+ var VALUE_MISSING = "Choose a date.";
28
+ var DIALOG_LABEL = "Choose a date";
29
+ var parseWeekday = (value) => Math.round(clampedNumber(MONDAY, SUNDAY, SATURDAY)(value));
30
+ /**
31
+ * A field for a date: it shows the date written for people (in the `locale`) and opens a calendar from its
32
+ * button, Alt + Down or Down. People may also type the date as ISO (`2026-10-25`). `value` and the form hold the
33
+ * ISO date.
34
+ */
35
+ var JlDatePicker = class extends JlFormControl {
36
+ static selector = "jl-date-picker";
37
+ events = this.useEvents();
38
+ /** The date, as ISO (`2026-10-25`); empty for none. */
39
+ value = this.useChange("", () => this.renderValue(), { attribute: "value" });
40
+ placeholder = this.useChange("", (value) => setOrRemove(this._refs.native, "placeholder", value), { attribute: "placeholder" });
41
+ /** The field's name for screen readers, when no visible label names it. */
42
+ label = this.useChange("", (value) => setOrRemove(this._refs.native, "aria-label", value), { attribute: "label" });
43
+ /** The first day that can be chosen, as ISO. */
44
+ min = this.useChange("", (value) => this.renderBound("min", value), { attribute: "min" });
45
+ /** The last day that can be chosen, as ISO. */
46
+ max = this.useChange("", (value) => this.renderBound("max", value), { attribute: "max" });
47
+ /** The language the date and the calendar are written in: `fr-CH`. The page's by default. */
48
+ locale = this.useChange("", (value) => {
49
+ this._refs.calendar.locale.set(value);
50
+ this.renderValue();
51
+ }, { attribute: "locale" });
52
+ /** The day the calendar's weeks start on: 0 for Sunday, 1 for Monday. */
53
+ firstDay = this.useChange(MONDAY, (value) => this._refs.calendar.firstDay.set(value), {
54
+ attribute: "first-day",
55
+ parse: parseWeekday
56
+ });
57
+ /** Shows a button that empties the field while it holds a date. */
58
+ clearable = this.useChange(false, () => this.renderClear(), { attribute: "clearable" });
59
+ required = this.useChange(false, (value) => {
60
+ this._refs.native.toggleAttribute("aria-required", value);
61
+ this.reflect("required", value);
62
+ this.renderValidity();
63
+ }, { attribute: "required" });
64
+ disabled = this.useChange(false, (value) => this.renderDisabled(value), { attribute: "disabled" });
65
+ /** Draws the field in the danger colour, for an error the page found itself. */
66
+ invalid = this.useChange(false, (value) => {
67
+ this.reflect("invalid", value);
68
+ this._refs.native.toggleAttribute("aria-invalid", value);
69
+ }, { attribute: "invalid" });
70
+ size = this.useChange("md", (value) => this.reflect("size", value), {
71
+ attribute: "size",
72
+ parse: oneOf(CONTROL_SIZES, "md")
73
+ });
74
+ _popupId = uniqueId("jl-date-picker-popup");
75
+ _state = {
76
+ opening: new AbortController(),
77
+ /** Whether a press on the button should open: read before the press closes the calendar by light dismiss. */
78
+ openOnPress: null
79
+ };
80
+ _refs = this.useRefs((ref) => ({
81
+ calendar: ref("jl-calendar"),
82
+ clear: ref(".clear"),
83
+ control: ref(".control"),
84
+ native: ref("input"),
85
+ open: ref(".open"),
86
+ popup: ref(".popup")
87
+ }));
88
+ focus(options) {
89
+ this._refs.native.focus(options);
90
+ }
91
+ /** Opens the calendar, with the focus on its day. */
92
+ show() {
93
+ this.whenRendered(() => this.openPopup());
94
+ }
95
+ /** Closes the calendar. */
96
+ hide() {
97
+ this.whenRendered(() => this.closePopup());
98
+ }
99
+ templateHtml() {
100
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
101
+ class: "control",
102
+ attrs: { part: "base" },
103
+ children: [
104
+ /* @__PURE__ */ jsx("input", {
105
+ class: "native",
106
+ role: "combobox",
107
+ autocomplete: "off",
108
+ spellcheck: false,
109
+ "aria-haspopup": "dialog",
110
+ "aria-expanded": "false",
111
+ "aria-controls": this._popupId
112
+ }),
113
+ /* @__PURE__ */ jsx("button", {
114
+ class: "action clear",
115
+ type: "button",
116
+ "aria-label": "Clear",
117
+ tabIndex: -1,
118
+ hidden: true,
119
+ children: /* @__PURE__ */ jsx(JlIcon, {
120
+ name: "x",
121
+ size: ACTION_ICON_SIZE
122
+ })
123
+ }),
124
+ /* @__PURE__ */ jsx("button", {
125
+ class: "action open",
126
+ type: "button",
127
+ "aria-label": DIALOG_LABEL,
128
+ "aria-haspopup": "dialog",
129
+ "aria-expanded": "false",
130
+ "aria-controls": this._popupId,
131
+ children: /* @__PURE__ */ jsx(JlIcon, {
132
+ name: "calendar",
133
+ size: ICON_SIZE
134
+ })
135
+ })
136
+ ]
137
+ }), /* @__PURE__ */ jsx("div", {
138
+ class: "floating panel popup",
139
+ id: this._popupId,
140
+ popover: "auto",
141
+ role: "dialog",
142
+ "aria-label": DIALOG_LABEL,
143
+ attrs: { part: "popup" },
144
+ children: /* @__PURE__ */ jsx(JlCalendar, { class: "calendar" })
145
+ })] });
146
+ }
147
+ templateCss() {
148
+ return css`${BASE_STYLES}${CONTROL_STYLES}${FLOATING_STYLES}${jl_date_picker_default}`;
149
+ }
150
+ onConnect() {
151
+ const native = this._refs.native;
152
+ const open = this._refs.open;
153
+ this.on(native, "input", (event) => {
154
+ event.stopPropagation();
155
+ this.renderClear();
156
+ });
157
+ this.on(native, "change", () => this.commitText());
158
+ this.on(native, "keydown", (event) => this.onKey(event));
159
+ this.on(open, "pointerdown", () => {
160
+ this._state.openOnPress = !this.isOpen();
161
+ });
162
+ this.on(open, "click", () => this.onOpenPress());
163
+ this.on(this._refs.clear, "mousedown", (event) => event.preventDefault());
164
+ this.on(this._refs.clear, "click", () => this.clearValue());
165
+ this.on(this._refs.popup, "toggle", (event) => this.onToggle(event));
166
+ this.on(this._refs.popup, "keydown", (event) => this.onPopupKey(event));
167
+ this._refs.calendar.events.register("pick", (iso) => this.onPick(iso));
168
+ }
169
+ onDisconnect() {
170
+ this._state.opening.abort();
171
+ }
172
+ resetValue() {
173
+ this.value.set(this.getAttribute("value") ?? "");
174
+ }
175
+ setDisabledByForm(disabled) {
176
+ const off = disabled || this.disabled.get();
177
+ this.whenRendered(() => {
178
+ this._refs.native.disabled = off;
179
+ this._refs.open.disabled = off;
180
+ });
181
+ }
182
+ isOpen() {
183
+ return this._refs.popup.matches(":popover-open");
184
+ }
185
+ /** Down (with or without Alt) opens the calendar. */
186
+ onKey(event) {
187
+ if (event.key === "ArrowDown") {
188
+ event.preventDefault();
189
+ this.openPopup();
190
+ }
191
+ }
192
+ onOpenPress() {
193
+ const shouldOpen = this._state.openOnPress ?? !this.isOpen();
194
+ this._state.openOnPress = null;
195
+ if (shouldOpen) {
196
+ this.openPopup();
197
+ return;
198
+ }
199
+ this.closePopup();
200
+ }
201
+ onToggle(event) {
202
+ const open = event.newState === "open";
203
+ this._refs.native.setAttribute("aria-expanded", String(open));
204
+ this._refs.open.setAttribute("aria-expanded", String(open));
205
+ this.reflect("open", open);
206
+ if (!open) this._state.opening.abort();
207
+ }
208
+ /** Escape closes the calendar and brings the focus back to the field, where it came from. */
209
+ onPopupKey(event) {
210
+ if (event.key !== "Escape") return;
211
+ event.preventDefault();
212
+ this.closePopup();
213
+ this.focus();
214
+ }
215
+ onPick(iso) {
216
+ this.closePopup();
217
+ this.commit(iso);
218
+ this.focus();
219
+ }
220
+ openPopup() {
221
+ if (this.isOpen() || this.disabled.get() || this._refs.native.disabled) return;
222
+ this.commitText();
223
+ const calendar = this._refs.calendar;
224
+ calendar.value.set(this.validIso());
225
+ const popup = this._refs.popup;
226
+ popup.showPopover();
227
+ this._state.opening.abort();
228
+ this._state.opening = new AbortController();
229
+ followAnchor(this._refs.control, popup, PLACEMENT, this._state.opening.signal);
230
+ calendar.focus();
231
+ }
232
+ closePopup() {
233
+ if (this.isOpen()) this._refs.popup.hidePopover();
234
+ }
235
+ /** The typed text: an ISO date sets the value, an empty field clears it, anything else goes back to the date. */
236
+ commitText() {
237
+ const text = this._refs.native.value.trim();
238
+ if (text === this.display(this.value.get())) return;
239
+ if (text === "") {
240
+ this.commit("");
241
+ return;
242
+ }
243
+ const date = parseIsoDate(text);
244
+ if (date === null) {
245
+ this.renderValue();
246
+ return;
247
+ }
248
+ this.commit(toIsoDate(date));
249
+ }
250
+ /** Sets the value as people chose it, and says so when it changed. */
251
+ commit(iso) {
252
+ const changed = iso !== this.value.get();
253
+ this.value.set(iso);
254
+ if (changed) this.events.emit("change", iso);
255
+ }
256
+ clearValue() {
257
+ this.commit("");
258
+ this.focus();
259
+ }
260
+ /** The value when it is a real ISO date, otherwise nothing. */
261
+ validIso() {
262
+ const date = parseIsoDate(this.value.get());
263
+ return date === null ? "" : toIsoDate(date);
264
+ }
265
+ display(value) {
266
+ const date = parseIsoDate(value);
267
+ return date === null ? "" : formatDate(date, pageLocale(this.locale.get()));
268
+ }
269
+ renderValue() {
270
+ const value = this.validIso();
271
+ this._refs.native.value = this.display(value);
272
+ this._refs.calendar.value.set(value);
273
+ this.internals.setFormValue(value);
274
+ this.renderValidity();
275
+ this.renderClear();
276
+ }
277
+ renderBound(bound, value) {
278
+ this._refs.calendar[bound].set(value);
279
+ this.renderValidity();
280
+ }
281
+ /** Required, and within min and max, as a native date field checks it. */
282
+ renderValidity() {
283
+ const date = parseIsoDate(this.value.get());
284
+ const anchor = this._refs.native;
285
+ if (date === null) {
286
+ this.renderMissing(anchor);
287
+ return;
288
+ }
289
+ const min = parseIsoDate(this.min.get());
290
+ const max = parseIsoDate(this.max.get());
291
+ const locale = pageLocale(this.locale.get());
292
+ if (min !== null && compareDates(date, min) < 0) {
293
+ this.internals.setValidity({ rangeUnderflow: true }, `Choose ${formatDate(min, locale)} or later.`, anchor);
294
+ return;
295
+ }
296
+ if (max !== null && compareDates(date, max) > 0) {
297
+ this.internals.setValidity({ rangeOverflow: true }, `Choose ${formatDate(max, locale)} or earlier.`, anchor);
298
+ return;
299
+ }
300
+ this.internals.setValidity({});
301
+ }
302
+ renderMissing(anchor) {
303
+ if (this.required.get()) {
304
+ this.internals.setValidity({ valueMissing: true }, VALUE_MISSING, anchor);
305
+ return;
306
+ }
307
+ this.internals.setValidity({});
308
+ }
309
+ renderClear() {
310
+ const editable = !this.disabled.get();
311
+ this._refs.clear.hidden = !(this.clearable.get() && editable && this._refs.native.value !== "");
312
+ }
313
+ renderDisabled(disabled) {
314
+ this._refs.native.disabled = disabled;
315
+ this._refs.open.disabled = disabled;
316
+ this.reflect("disabled", disabled);
317
+ this.closePopup();
318
+ this.renderClear();
319
+ }
320
+ };
321
+ JlDatePicker.register();
322
+ export { JlDatePicker };
@@ -0,0 +1,3 @@
1
+ // src/molecules/jl-empty.css?raw
2
+ var jl_empty_default = ":host {\n display: block;\n --pad: 40px 24px;\n --medallion: 48px;\n --heading: var(--jl-font-lg);\n}\n\n:host([size=\"sm\"]) {\n --pad: 24px 16px;\n --medallion: 40px;\n --heading: var(--jl-font-md);\n}\n\n.empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: var(--pad);\n text-align: center;\n}\n\n.medallion {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--medallion);\n height: var(--medallion);\n margin-bottom: 14px;\n border: 1px solid var(--jl-line);\n border-radius: 50%;\n background: var(--jl-surface-2);\n color: var(--jl-muted);\n}\n\n:host([size=\"sm\"]) .medallion {\n margin-bottom: 10px;\n}\n\n.heading {\n color: var(--jl-text);\n font-size: var(--heading);\n font-weight: 650;\n letter-spacing: -0.01em;\n line-height: 1.35;\n}\n\n.description {\n max-width: 44ch;\n margin-top: 4px;\n color: var(--jl-muted);\n font-size: var(--jl-font-sm);\n line-height: 1.55;\n}\n\n.actions {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n gap: 8px;\n margin-top: 18px;\n}\n\n:host([size=\"sm\"]) .actions {\n margin-top: 14px;\n}\n";
3
+ export { jl_empty_default as default };
@@ -0,0 +1,32 @@
1
+ import { JlElement } from '../base/jl-element';
2
+ import type { EmptySize } from '../types/jl-empty.types';
3
+ export declare const EMPTY_SIZES: readonly EmptySize[];
4
+ /**
5
+ * What a list, a table or a page shows when it has nothing yet: an icon, a heading, a sentence that says what to
6
+ * do, and the buttons to do it in the default slot.
7
+ */
8
+ export declare class JlEmpty extends JlElement {
9
+ static readonly selector = "jl-empty";
10
+ readonly icon: Readonly<Readonly<{
11
+ get(): string;
12
+ set(setter: string | ((prevState: string) => string)): void;
13
+ }>>;
14
+ readonly heading: Readonly<Readonly<{
15
+ get(): string;
16
+ set(setter: string | ((prevState: string) => string)): void;
17
+ }>>;
18
+ readonly description: Readonly<Readonly<{
19
+ get(): string;
20
+ set(setter: string | ((prevState: string) => string)): void;
21
+ }>>;
22
+ readonly size: Readonly<Readonly<{
23
+ get(): EmptySize;
24
+ set(setter: ((prevState: EmptySize) => EmptySize) | EmptySize): void;
25
+ }>>;
26
+ private readonly _refs;
27
+ templateHtml(): Node;
28
+ templateCss(): string;
29
+ onConnect(): void;
30
+ private renderActions;
31
+ private renderIcon;
32
+ }
@@ -0,0 +1,94 @@
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 { hasSlotted } from "../lib/slots.js";
6
+ import { JlIcon } from "../atoms/jl-icon.js";
7
+ import jl_empty_default from "./jl-empty.css_raw.js";
8
+ import { css } from "@jadis/core";
9
+ import { Inbox } from "lucide";
10
+ import { jsx, jsxs } from "@jadis/core/jsx-runtime";
11
+ // src/molecules/jl-empty.tsx
12
+ registerIcons({ inbox: Inbox });
13
+ var EMPTY_SIZES = ["md", "sm"];
14
+ var DEFAULT_ICON = "inbox";
15
+ var NO_ICON = "none";
16
+ var ICON_SIZES = {
17
+ md: 22,
18
+ sm: 18
19
+ };
20
+ /**
21
+ * What a list, a table or a page shows when it has nothing yet: an icon, a heading, a sentence that says what to
22
+ * do, and the buttons to do it in the default slot.
23
+ */
24
+ var JlEmpty = class extends JlElement {
25
+ static selector = "jl-empty";
26
+ icon = this.useChange(DEFAULT_ICON, () => this.renderIcon(), { attribute: "icon" });
27
+ heading = this.useChange("", (value) => {
28
+ this._refs.heading.textContent = value;
29
+ this._refs.heading.hidden = value === "";
30
+ }, { attribute: "heading" });
31
+ description = this.useChange("", (value) => {
32
+ this._refs.description.textContent = value;
33
+ this._refs.description.hidden = value === "";
34
+ }, { attribute: "description" });
35
+ size = this.useChange("md", (value) => {
36
+ this.reflect("size", value);
37
+ this.renderIcon();
38
+ }, {
39
+ attribute: "size",
40
+ parse: oneOf(EMPTY_SIZES, "md")
41
+ });
42
+ _refs = this.useRefs((ref) => ({
43
+ actions: ref(".actions"),
44
+ description: ref(".description"),
45
+ heading: ref(".heading"),
46
+ icon: ref("jl-icon"),
47
+ medallion: ref(".medallion"),
48
+ slot: ref("slot")
49
+ }));
50
+ templateHtml() {
51
+ return /* @__PURE__ */ jsxs("div", {
52
+ class: "empty",
53
+ attrs: { part: "base" },
54
+ children: [
55
+ /* @__PURE__ */ jsx("span", {
56
+ class: "medallion",
57
+ children: /* @__PURE__ */ jsx(JlIcon, {})
58
+ }),
59
+ /* @__PURE__ */ jsx("p", {
60
+ class: "heading",
61
+ hidden: true
62
+ }),
63
+ /* @__PURE__ */ jsx("p", {
64
+ class: "description",
65
+ hidden: true
66
+ }),
67
+ /* @__PURE__ */ jsx("div", {
68
+ class: "actions",
69
+ hidden: true,
70
+ children: /* @__PURE__ */ jsx("slot", {})
71
+ })
72
+ ]
73
+ });
74
+ }
75
+ templateCss() {
76
+ return css`${BASE_STYLES}${jl_empty_default}`;
77
+ }
78
+ onConnect() {
79
+ this.renderActions();
80
+ this.on(this._refs.slot, "slotchange", () => this.renderActions());
81
+ }
82
+ renderActions() {
83
+ this._refs.actions.hidden = !hasSlotted(this._refs.slot);
84
+ }
85
+ renderIcon() {
86
+ const name = this.icon.get();
87
+ const hidden = name === "" || name === NO_ICON;
88
+ this._refs.icon.name.set(hidden ? "" : name);
89
+ this._refs.icon.size.set(ICON_SIZES[this.size.get()]);
90
+ this._refs.medallion.hidden = hidden;
91
+ }
92
+ };
93
+ JlEmpty.register();
94
+ export { EMPTY_SIZES, JlEmpty };
@@ -0,0 +1,3 @@
1
+ // src/molecules/jl-field.css?raw
2
+ var jl_field_default = ":host {\n display: block;\n container-type: inline-size;\n --label-width: 160px;\n}\n\n.field {\n display: grid;\n gap: 6px;\n}\n\n.label-row {\n display: flex;\n gap: 3px;\n color: var(--jl-text);\n font-size: var(--jl-font-sm);\n font-weight: 600;\n line-height: 20px;\n}\n\n.asterisk {\n color: var(--jl-danger);\n}\n\n.body {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: 6px;\n min-width: 0;\n}\n\n.hint {\n color: var(--jl-muted);\n font-size: var(--jl-font-sm);\n line-height: 18px;\n}\n\n.error-region:empty {\n display: contents;\n}\n\n.error {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n color: var(--jl-danger);\n font-size: var(--jl-font-sm);\n line-height: 18px;\n}\n\n.error jl-icon {\n flex: none;\n margin-top: 2px;\n}\n\n/* Beside: the label takes a column and sits on the baseline of the control's first line of text. */\n:host([orientation=\"horizontal\"]) .field {\n grid-template-columns: var(--label-width) minmax(0, 1fr);\n align-items: baseline;\n gap: 6px 16px;\n}\n\n@container (max-width: 420px) {\n :host([orientation=\"horizontal\"]) .field {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n";
3
+ export { jl_field_default as default };