@furystack/shades-common-components 12.6.0 → 13.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 (594) hide show
  1. package/CHANGELOG.md +183 -0
  2. package/README.md +218 -4
  3. package/esm/components/accordion/accordion-item.d.ts +1 -1
  4. package/esm/components/accordion/accordion-item.d.ts.map +1 -1
  5. package/esm/components/accordion/accordion-item.js +6 -11
  6. package/esm/components/accordion/accordion-item.js.map +1 -1
  7. package/esm/components/accordion/accordion.d.ts.map +1 -1
  8. package/esm/components/accordion/accordion.js +1 -0
  9. package/esm/components/accordion/accordion.js.map +1 -1
  10. package/esm/components/app-bar-link.d.ts.map +1 -1
  11. package/esm/components/app-bar-link.js +1 -0
  12. package/esm/components/app-bar-link.js.map +1 -1
  13. package/esm/components/app-bar.d.ts.map +1 -1
  14. package/esm/components/app-bar.js +2 -0
  15. package/esm/components/app-bar.js.map +1 -1
  16. package/esm/components/app-bar.spec.js +3 -3
  17. package/esm/components/app-bar.spec.js.map +1 -1
  18. package/esm/components/avatar.d.ts.map +1 -1
  19. package/esm/components/avatar.js +1 -0
  20. package/esm/components/avatar.js.map +1 -1
  21. package/esm/components/badge.d.ts.map +1 -1
  22. package/esm/components/badge.js +2 -1
  23. package/esm/components/badge.js.map +1 -1
  24. package/esm/components/breadcrumb.d.ts.map +1 -1
  25. package/esm/components/breadcrumb.js +1 -0
  26. package/esm/components/breadcrumb.js.map +1 -1
  27. package/esm/components/button-group.d.ts.map +1 -1
  28. package/esm/components/button-group.js +57 -60
  29. package/esm/components/button-group.js.map +1 -1
  30. package/esm/components/button-group.spec.js +7 -6
  31. package/esm/components/button-group.spec.js.map +1 -1
  32. package/esm/components/button.d.ts.map +1 -1
  33. package/esm/components/button.js +1 -0
  34. package/esm/components/button.js.map +1 -1
  35. package/esm/components/cache-view.d.ts.map +1 -1
  36. package/esm/components/cache-view.js +4 -0
  37. package/esm/components/cache-view.js.map +1 -1
  38. package/esm/components/cache-view.spec.js +4 -1
  39. package/esm/components/cache-view.spec.js.map +1 -1
  40. package/esm/components/card.d.ts.map +1 -1
  41. package/esm/components/card.js +3 -1
  42. package/esm/components/card.js.map +1 -1
  43. package/esm/components/circular-progress.d.ts.map +1 -1
  44. package/esm/components/circular-progress.js +1 -0
  45. package/esm/components/circular-progress.js.map +1 -1
  46. package/esm/components/command-palette/command-palette-input.d.ts.map +1 -1
  47. package/esm/components/command-palette/command-palette-input.js +1 -0
  48. package/esm/components/command-palette/command-palette-input.js.map +1 -1
  49. package/esm/components/command-palette/command-palette-suggestion-list.d.ts.map +1 -1
  50. package/esm/components/command-palette/command-palette-suggestion-list.js +3 -1
  51. package/esm/components/command-palette/command-palette-suggestion-list.js.map +1 -1
  52. package/esm/components/command-palette/index.d.ts.map +1 -1
  53. package/esm/components/command-palette/index.js +2 -0
  54. package/esm/components/command-palette/index.js.map +1 -1
  55. package/esm/components/context-menu/context-menu-item.d.ts.map +1 -1
  56. package/esm/components/context-menu/context-menu-item.js +1 -0
  57. package/esm/components/context-menu/context-menu-item.js.map +1 -1
  58. package/esm/components/context-menu/context-menu.d.ts.map +1 -1
  59. package/esm/components/context-menu/context-menu.js +1 -0
  60. package/esm/components/context-menu/context-menu.js.map +1 -1
  61. package/esm/components/data-grid/body.d.ts.map +1 -1
  62. package/esm/components/data-grid/body.js +2 -0
  63. package/esm/components/data-grid/body.js.map +1 -1
  64. package/esm/components/data-grid/data-grid-row.d.ts.map +1 -1
  65. package/esm/components/data-grid/data-grid-row.js +1 -0
  66. package/esm/components/data-grid/data-grid-row.js.map +1 -1
  67. package/esm/components/data-grid/data-grid.d.ts.map +1 -1
  68. package/esm/components/data-grid/data-grid.js +1 -0
  69. package/esm/components/data-grid/data-grid.js.map +1 -1
  70. package/esm/components/data-grid/filters/boolean-filter.d.ts.map +1 -1
  71. package/esm/components/data-grid/filters/boolean-filter.js +2 -0
  72. package/esm/components/data-grid/filters/boolean-filter.js.map +1 -1
  73. package/esm/components/data-grid/filters/date-filter.d.ts.map +1 -1
  74. package/esm/components/data-grid/filters/date-filter.js +2 -0
  75. package/esm/components/data-grid/filters/date-filter.js.map +1 -1
  76. package/esm/components/data-grid/filters/enum-filter.d.ts.map +1 -1
  77. package/esm/components/data-grid/filters/enum-filter.js +2 -0
  78. package/esm/components/data-grid/filters/enum-filter.js.map +1 -1
  79. package/esm/components/data-grid/filters/filter-dropdown.d.ts.map +1 -1
  80. package/esm/components/data-grid/filters/filter-dropdown.js +1 -0
  81. package/esm/components/data-grid/filters/filter-dropdown.js.map +1 -1
  82. package/esm/components/data-grid/filters/number-filter.d.ts.map +1 -1
  83. package/esm/components/data-grid/filters/number-filter.js +2 -0
  84. package/esm/components/data-grid/filters/number-filter.js.map +1 -1
  85. package/esm/components/data-grid/filters/string-filter.d.ts.map +1 -1
  86. package/esm/components/data-grid/filters/string-filter.js +2 -0
  87. package/esm/components/data-grid/filters/string-filter.js.map +1 -1
  88. package/esm/components/data-grid/footer.d.ts.map +1 -1
  89. package/esm/components/data-grid/footer.js +1 -0
  90. package/esm/components/data-grid/footer.js.map +1 -1
  91. package/esm/components/data-grid/header.d.ts.map +1 -1
  92. package/esm/components/data-grid/header.js +2 -0
  93. package/esm/components/data-grid/header.js.map +1 -1
  94. package/esm/components/data-grid/selection-cell.d.ts.map +1 -1
  95. package/esm/components/data-grid/selection-cell.js +1 -0
  96. package/esm/components/data-grid/selection-cell.js.map +1 -1
  97. package/esm/components/dialog.d.ts.map +1 -1
  98. package/esm/components/dialog.js +8 -12
  99. package/esm/components/dialog.js.map +1 -1
  100. package/esm/components/divider.d.ts.map +1 -1
  101. package/esm/components/divider.js +1 -0
  102. package/esm/components/divider.js.map +1 -1
  103. package/esm/components/drawer/drawer-toggle-button.d.ts +1 -1
  104. package/esm/components/drawer/drawer-toggle-button.d.ts.map +1 -1
  105. package/esm/components/drawer/drawer-toggle-button.js +2 -1
  106. package/esm/components/drawer/drawer-toggle-button.js.map +1 -1
  107. package/esm/components/drawer/index.d.ts.map +1 -1
  108. package/esm/components/drawer/index.js +1 -0
  109. package/esm/components/drawer/index.js.map +1 -1
  110. package/esm/components/dropdown.d.ts.map +1 -1
  111. package/esm/components/dropdown.js +1 -0
  112. package/esm/components/dropdown.js.map +1 -1
  113. package/esm/components/fab.d.ts.map +1 -1
  114. package/esm/components/fab.js +1 -0
  115. package/esm/components/fab.js.map +1 -1
  116. package/esm/components/form.d.ts.map +1 -1
  117. package/esm/components/form.js +2 -0
  118. package/esm/components/form.js.map +1 -1
  119. package/esm/components/grid.d.ts.map +1 -1
  120. package/esm/components/grid.js +3 -1
  121. package/esm/components/grid.js.map +1 -1
  122. package/esm/components/icons/icon.d.ts.map +1 -1
  123. package/esm/components/icons/icon.js +2 -0
  124. package/esm/components/icons/icon.js.map +1 -1
  125. package/esm/components/image.d.ts.map +1 -1
  126. package/esm/components/image.js +1 -0
  127. package/esm/components/image.js.map +1 -1
  128. package/esm/components/inputs/autocomplete.d.ts.map +1 -1
  129. package/esm/components/inputs/autocomplete.js +2 -0
  130. package/esm/components/inputs/autocomplete.js.map +1 -1
  131. package/esm/components/inputs/checkbox.d.ts.map +1 -1
  132. package/esm/components/inputs/checkbox.js +2 -1
  133. package/esm/components/inputs/checkbox.js.map +1 -1
  134. package/esm/components/inputs/input-number.d.ts.map +1 -1
  135. package/esm/components/inputs/input-number.js +1 -0
  136. package/esm/components/inputs/input-number.js.map +1 -1
  137. package/esm/components/inputs/input.d.ts.map +1 -1
  138. package/esm/components/inputs/input.js +1 -0
  139. package/esm/components/inputs/input.js.map +1 -1
  140. package/esm/components/inputs/radio-group.d.ts.map +1 -1
  141. package/esm/components/inputs/radio-group.js +1 -0
  142. package/esm/components/inputs/radio-group.js.map +1 -1
  143. package/esm/components/inputs/radio.d.ts.map +1 -1
  144. package/esm/components/inputs/radio.js +1 -0
  145. package/esm/components/inputs/radio.js.map +1 -1
  146. package/esm/components/inputs/select.d.ts.map +1 -1
  147. package/esm/components/inputs/select.js +14 -16
  148. package/esm/components/inputs/select.js.map +1 -1
  149. package/esm/components/inputs/select.spec.js +3 -6
  150. package/esm/components/inputs/select.spec.js.map +1 -1
  151. package/esm/components/inputs/slider.d.ts.map +1 -1
  152. package/esm/components/inputs/slider.js +5 -31
  153. package/esm/components/inputs/slider.js.map +1 -1
  154. package/esm/components/inputs/switch.d.ts.map +1 -1
  155. package/esm/components/inputs/switch.js +2 -1
  156. package/esm/components/inputs/switch.js.map +1 -1
  157. package/esm/components/inputs/text-area.d.ts.map +1 -1
  158. package/esm/components/inputs/text-area.js +1 -0
  159. package/esm/components/inputs/text-area.js.map +1 -1
  160. package/esm/components/linear-progress.d.ts.map +1 -1
  161. package/esm/components/linear-progress.js +1 -0
  162. package/esm/components/linear-progress.js.map +1 -1
  163. package/esm/components/list/list-item.d.ts.map +1 -1
  164. package/esm/components/list/list-item.js +1 -0
  165. package/esm/components/list/list-item.js.map +1 -1
  166. package/esm/components/list/list.d.ts.map +1 -1
  167. package/esm/components/list/list.js +2 -0
  168. package/esm/components/list/list.js.map +1 -1
  169. package/esm/components/loader.d.ts.map +1 -1
  170. package/esm/components/loader.js +1 -0
  171. package/esm/components/loader.js.map +1 -1
  172. package/esm/components/markdown/markdown-display.js +1 -1
  173. package/esm/components/markdown/markdown-display.js.map +1 -1
  174. package/esm/components/markdown/markdown-display.spec.js +2 -2
  175. package/esm/components/markdown/markdown-display.spec.js.map +1 -1
  176. package/esm/components/markdown/markdown-editor.d.ts +16 -2
  177. package/esm/components/markdown/markdown-editor.d.ts.map +1 -1
  178. package/esm/components/markdown/markdown-editor.js +43 -8
  179. package/esm/components/markdown/markdown-editor.js.map +1 -1
  180. package/esm/components/markdown/markdown-editor.spec.js +191 -1
  181. package/esm/components/markdown/markdown-editor.spec.js.map +1 -1
  182. package/esm/components/markdown/markdown-input.d.ts +2 -0
  183. package/esm/components/markdown/markdown-input.d.ts.map +1 -1
  184. package/esm/components/markdown/markdown-input.js +5 -9
  185. package/esm/components/markdown/markdown-input.js.map +1 -1
  186. package/esm/components/markdown/markdown-input.spec.js +43 -0
  187. package/esm/components/markdown/markdown-input.spec.js.map +1 -1
  188. package/esm/components/markdown/markdown-validation.d.ts +25 -0
  189. package/esm/components/markdown/markdown-validation.d.ts.map +1 -0
  190. package/esm/components/markdown/markdown-validation.js +15 -0
  191. package/esm/components/markdown/markdown-validation.js.map +1 -0
  192. package/esm/components/modal.d.ts.map +1 -1
  193. package/esm/components/modal.js +2 -0
  194. package/esm/components/modal.js.map +1 -1
  195. package/esm/components/noty-list.d.ts.map +1 -1
  196. package/esm/components/noty-list.js +4 -2
  197. package/esm/components/noty-list.js.map +1 -1
  198. package/esm/components/noty-list.spec.js +1 -1
  199. package/esm/components/noty-list.spec.js.map +1 -1
  200. package/esm/components/page-container/index.d.ts +1 -1
  201. package/esm/components/page-container/index.d.ts.map +1 -1
  202. package/esm/components/page-container/index.js +2 -1
  203. package/esm/components/page-container/index.js.map +1 -1
  204. package/esm/components/page-container/page-header.d.ts.map +1 -1
  205. package/esm/components/page-container/page-header.js +10 -12
  206. package/esm/components/page-container/page-header.js.map +1 -1
  207. package/esm/components/page-container/page-header.spec.js +6 -4
  208. package/esm/components/page-container/page-header.spec.js.map +1 -1
  209. package/esm/components/page-layout/index.d.ts.map +1 -1
  210. package/esm/components/page-layout/index.js +2 -0
  211. package/esm/components/page-layout/index.js.map +1 -1
  212. package/esm/components/paper.d.ts.map +1 -1
  213. package/esm/components/paper.js +6 -1
  214. package/esm/components/paper.js.map +1 -1
  215. package/esm/components/rating.d.ts.map +1 -1
  216. package/esm/components/rating.js +1 -0
  217. package/esm/components/rating.js.map +1 -1
  218. package/esm/components/result.d.ts.map +1 -1
  219. package/esm/components/result.js +3 -14
  220. package/esm/components/result.js.map +1 -1
  221. package/esm/components/result.spec.js +3 -3
  222. package/esm/components/result.spec.js.map +1 -1
  223. package/esm/components/suggest/index.d.ts.map +1 -1
  224. package/esm/components/suggest/index.js +2 -0
  225. package/esm/components/suggest/index.js.map +1 -1
  226. package/esm/components/suggest/suggest-input.d.ts.map +1 -1
  227. package/esm/components/suggest/suggest-input.js +1 -0
  228. package/esm/components/suggest/suggest-input.js.map +1 -1
  229. package/esm/components/suggest/suggestion-list.d.ts.map +1 -1
  230. package/esm/components/suggest/suggestion-list.js +3 -1
  231. package/esm/components/suggest/suggestion-list.js.map +1 -1
  232. package/esm/components/tabs.d.ts.map +1 -1
  233. package/esm/components/tabs.js +1 -0
  234. package/esm/components/tabs.js.map +1 -1
  235. package/esm/components/timeline.d.ts.map +1 -1
  236. package/esm/components/timeline.js +58 -51
  237. package/esm/components/timeline.js.map +1 -1
  238. package/esm/components/timeline.spec.js +0 -66
  239. package/esm/components/timeline.spec.js.map +1 -1
  240. package/esm/components/tooltip.d.ts.map +1 -1
  241. package/esm/components/tooltip.js +1 -0
  242. package/esm/components/tooltip.js.map +1 -1
  243. package/esm/components/tree/tree-item.d.ts.map +1 -1
  244. package/esm/components/tree/tree-item.js +1 -0
  245. package/esm/components/tree/tree-item.js.map +1 -1
  246. package/esm/components/tree/tree.d.ts.map +1 -1
  247. package/esm/components/tree/tree.js +2 -0
  248. package/esm/components/tree/tree.js.map +1 -1
  249. package/esm/components/typography.d.ts +2 -19
  250. package/esm/components/typography.d.ts.map +1 -1
  251. package/esm/components/typography.js +104 -94
  252. package/esm/components/typography.js.map +1 -1
  253. package/esm/components/typography.spec.js +16 -16
  254. package/esm/components/typography.spec.js.map +1 -1
  255. package/esm/components/wizard/index.d.ts.map +1 -1
  256. package/esm/components/wizard/index.js +1 -0
  257. package/esm/components/wizard/index.js.map +1 -1
  258. package/esm/services/css-variable-theme.d.ts +4 -0
  259. package/esm/services/css-variable-theme.d.ts.map +1 -1
  260. package/esm/services/css-variable-theme.js +29 -6
  261. package/esm/services/css-variable-theme.js.map +1 -1
  262. package/esm/services/css-variable-theme.spec.js +93 -1
  263. package/esm/services/css-variable-theme.spec.js.map +1 -1
  264. package/esm/services/get-rgb-from-color-string.d.ts +10 -0
  265. package/esm/services/get-rgb-from-color-string.d.ts.map +1 -0
  266. package/esm/services/get-rgb-from-color-string.js +86 -0
  267. package/esm/services/get-rgb-from-color-string.js.map +1 -0
  268. package/esm/services/get-rgb-from-color-string.spec.d.ts +2 -0
  269. package/esm/services/get-rgb-from-color-string.spec.d.ts.map +1 -0
  270. package/esm/services/get-rgb-from-color-string.spec.js +107 -0
  271. package/esm/services/get-rgb-from-color-string.spec.js.map +1 -0
  272. package/esm/services/get-text-color.d.ts +10 -0
  273. package/esm/services/get-text-color.d.ts.map +1 -0
  274. package/esm/services/get-text-color.js +15 -0
  275. package/esm/services/get-text-color.js.map +1 -0
  276. package/esm/services/get-text-color.spec.d.ts +2 -0
  277. package/esm/services/get-text-color.spec.d.ts.map +1 -0
  278. package/esm/services/get-text-color.spec.js +21 -0
  279. package/esm/services/get-text-color.spec.js.map +1 -0
  280. package/esm/services/index.d.ts +7 -4
  281. package/esm/services/index.d.ts.map +1 -1
  282. package/esm/services/index.js +7 -4
  283. package/esm/services/index.js.map +1 -1
  284. package/esm/services/rgb-color.d.ts +13 -0
  285. package/esm/services/rgb-color.d.ts.map +1 -0
  286. package/esm/services/rgb-color.js +23 -0
  287. package/esm/services/rgb-color.js.map +1 -0
  288. package/esm/services/rgb-color.spec.d.ts +2 -0
  289. package/esm/services/rgb-color.spec.d.ts.map +1 -0
  290. package/esm/services/rgb-color.spec.js +69 -0
  291. package/esm/services/rgb-color.spec.js.map +1 -0
  292. package/esm/services/theme-provider-service.d.ts +9 -23
  293. package/esm/services/theme-provider-service.d.ts.map +1 -1
  294. package/esm/services/theme-provider-service.js +1 -63
  295. package/esm/services/theme-provider-service.js.map +1 -1
  296. package/esm/services/theme-provider-service.spec.js +12 -159
  297. package/esm/services/theme-provider-service.spec.js.map +1 -1
  298. package/esm/themes/architect-palette.d.ts +8 -0
  299. package/esm/themes/architect-palette.d.ts.map +1 -0
  300. package/esm/themes/architect-palette.js +56 -0
  301. package/esm/themes/architect-palette.js.map +1 -0
  302. package/esm/themes/architect-theme.d.ts +120 -0
  303. package/esm/themes/architect-theme.d.ts.map +1 -0
  304. package/esm/themes/architect-theme.js +122 -0
  305. package/esm/themes/architect-theme.js.map +1 -0
  306. package/esm/themes/auditore-palette.d.ts +8 -0
  307. package/esm/themes/auditore-palette.d.ts.map +1 -0
  308. package/esm/themes/auditore-palette.js +56 -0
  309. package/esm/themes/auditore-palette.js.map +1 -0
  310. package/esm/themes/auditore-theme.d.ts +120 -0
  311. package/esm/themes/auditore-theme.d.ts.map +1 -0
  312. package/esm/themes/auditore-theme.js +122 -0
  313. package/esm/themes/auditore-theme.js.map +1 -0
  314. package/esm/themes/black-mesa-palette.d.ts +8 -0
  315. package/esm/themes/black-mesa-palette.d.ts.map +1 -0
  316. package/esm/themes/black-mesa-palette.js +56 -0
  317. package/esm/themes/black-mesa-palette.js.map +1 -0
  318. package/esm/themes/black-mesa-theme.d.ts +120 -0
  319. package/esm/themes/black-mesa-theme.d.ts.map +1 -0
  320. package/esm/themes/black-mesa-theme.js +122 -0
  321. package/esm/themes/black-mesa-theme.js.map +1 -0
  322. package/esm/themes/chieftain-palette.d.ts +8 -0
  323. package/esm/themes/chieftain-palette.d.ts.map +1 -0
  324. package/esm/themes/chieftain-palette.js +56 -0
  325. package/esm/themes/chieftain-palette.js.map +1 -0
  326. package/esm/themes/chieftain-theme.d.ts +121 -0
  327. package/esm/themes/chieftain-theme.d.ts.map +1 -0
  328. package/esm/themes/chieftain-theme.js +123 -0
  329. package/esm/themes/chieftain-theme.js.map +1 -0
  330. package/esm/themes/default-dark-palette.d.ts +8 -0
  331. package/esm/themes/default-dark-palette.d.ts.map +1 -0
  332. package/esm/{services → themes}/default-dark-palette.js +1 -1
  333. package/esm/themes/default-dark-palette.js.map +1 -0
  334. package/esm/{services → themes}/default-dark-theme.d.ts +7 -1
  335. package/esm/themes/default-dark-theme.d.ts.map +1 -0
  336. package/esm/{services → themes}/default-dark-theme.js +6 -0
  337. package/esm/themes/default-dark-theme.js.map +1 -0
  338. package/esm/{services → themes}/default-light-theme.d.ts +7 -1
  339. package/esm/themes/default-light-theme.d.ts.map +1 -0
  340. package/esm/{services → themes}/default-light-theme.js +6 -0
  341. package/esm/themes/default-light-theme.js.map +1 -0
  342. package/esm/{services → themes}/default-palette.d.ts +1 -1
  343. package/esm/themes/default-palette.d.ts.map +1 -0
  344. package/esm/themes/default-palette.js.map +1 -0
  345. package/esm/themes/dragonborn-palette.d.ts +8 -0
  346. package/esm/themes/dragonborn-palette.d.ts.map +1 -0
  347. package/esm/themes/dragonborn-palette.js +56 -0
  348. package/esm/themes/dragonborn-palette.js.map +1 -0
  349. package/esm/themes/dragonborn-theme.d.ts +120 -0
  350. package/esm/themes/dragonborn-theme.d.ts.map +1 -0
  351. package/esm/themes/dragonborn-theme.js +122 -0
  352. package/esm/themes/dragonborn-theme.js.map +1 -0
  353. package/esm/themes/hawkins-palette.d.ts +8 -0
  354. package/esm/themes/hawkins-palette.d.ts.map +1 -0
  355. package/esm/themes/hawkins-palette.js +56 -0
  356. package/esm/themes/hawkins-palette.js.map +1 -0
  357. package/esm/themes/hawkins-theme.d.ts +120 -0
  358. package/esm/themes/hawkins-theme.d.ts.map +1 -0
  359. package/esm/themes/hawkins-theme.js +122 -0
  360. package/esm/themes/hawkins-theme.js.map +1 -0
  361. package/esm/themes/jedi-palette.d.ts +8 -0
  362. package/esm/themes/jedi-palette.d.ts.map +1 -0
  363. package/esm/themes/jedi-palette.js +56 -0
  364. package/esm/themes/jedi-palette.js.map +1 -0
  365. package/esm/themes/jedi-theme.d.ts +120 -0
  366. package/esm/themes/jedi-theme.d.ts.map +1 -0
  367. package/esm/themes/jedi-theme.js +122 -0
  368. package/esm/themes/jedi-theme.js.map +1 -0
  369. package/esm/themes/neon-runner-palette.d.ts +8 -0
  370. package/esm/themes/neon-runner-palette.d.ts.map +1 -0
  371. package/esm/themes/neon-runner-palette.js +56 -0
  372. package/esm/themes/neon-runner-palette.js.map +1 -0
  373. package/esm/themes/neon-runner-theme.d.ts +119 -0
  374. package/esm/themes/neon-runner-theme.d.ts.map +1 -0
  375. package/esm/themes/neon-runner-theme.js +120 -0
  376. package/esm/themes/neon-runner-theme.js.map +1 -0
  377. package/esm/themes/paladin-palette.d.ts +8 -0
  378. package/esm/themes/paladin-palette.d.ts.map +1 -0
  379. package/esm/themes/paladin-palette.js +56 -0
  380. package/esm/themes/paladin-palette.js.map +1 -0
  381. package/esm/themes/paladin-theme.d.ts +121 -0
  382. package/esm/themes/paladin-theme.d.ts.map +1 -0
  383. package/esm/themes/paladin-theme.js +123 -0
  384. package/esm/themes/paladin-theme.js.map +1 -0
  385. package/esm/themes/plumber-palette.d.ts +8 -0
  386. package/esm/themes/plumber-palette.d.ts.map +1 -0
  387. package/esm/themes/plumber-palette.js +56 -0
  388. package/esm/themes/plumber-palette.js.map +1 -0
  389. package/esm/themes/plumber-theme.d.ts +120 -0
  390. package/esm/themes/plumber-theme.d.ts.map +1 -0
  391. package/esm/themes/plumber-theme.js +121 -0
  392. package/esm/themes/plumber-theme.js.map +1 -0
  393. package/esm/themes/replicant-palette.d.ts +8 -0
  394. package/esm/themes/replicant-palette.d.ts.map +1 -0
  395. package/esm/themes/replicant-palette.js +56 -0
  396. package/esm/themes/replicant-palette.js.map +1 -0
  397. package/esm/themes/replicant-theme.d.ts +120 -0
  398. package/esm/themes/replicant-theme.d.ts.map +1 -0
  399. package/esm/themes/replicant-theme.js +122 -0
  400. package/esm/themes/replicant-theme.js.map +1 -0
  401. package/esm/themes/sandworm-palette.d.ts +8 -0
  402. package/esm/themes/sandworm-palette.d.ts.map +1 -0
  403. package/esm/themes/sandworm-palette.js +56 -0
  404. package/esm/themes/sandworm-palette.js.map +1 -0
  405. package/esm/themes/sandworm-theme.d.ts +120 -0
  406. package/esm/themes/sandworm-theme.d.ts.map +1 -0
  407. package/esm/themes/sandworm-theme.js +122 -0
  408. package/esm/themes/sandworm-theme.js.map +1 -0
  409. package/esm/themes/shadow-broker-palette.d.ts +8 -0
  410. package/esm/themes/shadow-broker-palette.d.ts.map +1 -0
  411. package/esm/themes/shadow-broker-palette.js +56 -0
  412. package/esm/{services/default-dark-palette.js.map → themes/shadow-broker-palette.js.map} +1 -1
  413. package/esm/themes/shadow-broker-theme.d.ts +120 -0
  414. package/esm/themes/shadow-broker-theme.d.ts.map +1 -0
  415. package/esm/themes/shadow-broker-theme.js +121 -0
  416. package/esm/themes/shadow-broker-theme.js.map +1 -0
  417. package/esm/themes/sith-palette.d.ts +8 -0
  418. package/esm/themes/sith-palette.d.ts.map +1 -0
  419. package/esm/themes/sith-palette.js +56 -0
  420. package/esm/themes/sith-palette.js.map +1 -0
  421. package/esm/themes/sith-theme.d.ts +120 -0
  422. package/esm/themes/sith-theme.d.ts.map +1 -0
  423. package/esm/themes/sith-theme.js +122 -0
  424. package/esm/themes/sith-theme.js.map +1 -0
  425. package/esm/themes/vault-dweller-palette.d.ts +8 -0
  426. package/esm/themes/vault-dweller-palette.d.ts.map +1 -0
  427. package/esm/themes/vault-dweller-palette.js +56 -0
  428. package/esm/themes/vault-dweller-palette.js.map +1 -0
  429. package/esm/themes/vault-dweller-theme.d.ts +120 -0
  430. package/esm/themes/vault-dweller-theme.d.ts.map +1 -0
  431. package/esm/themes/vault-dweller-theme.js +122 -0
  432. package/esm/themes/vault-dweller-theme.js.map +1 -0
  433. package/esm/themes/wild-hunt-palette.d.ts +8 -0
  434. package/esm/themes/wild-hunt-palette.d.ts.map +1 -0
  435. package/esm/themes/wild-hunt-palette.js +56 -0
  436. package/esm/themes/wild-hunt-palette.js.map +1 -0
  437. package/esm/themes/wild-hunt-theme.d.ts +120 -0
  438. package/esm/themes/wild-hunt-theme.d.ts.map +1 -0
  439. package/esm/themes/wild-hunt-theme.js +122 -0
  440. package/esm/themes/wild-hunt-theme.js.map +1 -0
  441. package/esm/themes/xenomorph-palette.d.ts +8 -0
  442. package/esm/themes/xenomorph-palette.d.ts.map +1 -0
  443. package/esm/themes/xenomorph-palette.js +56 -0
  444. package/esm/themes/xenomorph-palette.js.map +1 -0
  445. package/esm/themes/xenomorph-theme.d.ts +120 -0
  446. package/esm/themes/xenomorph-theme.d.ts.map +1 -0
  447. package/esm/themes/xenomorph-theme.js +121 -0
  448. package/esm/themes/xenomorph-theme.js.map +1 -0
  449. package/package.json +7 -3
  450. package/src/components/accordion/accordion-item.tsx +16 -23
  451. package/src/components/accordion/accordion.tsx +1 -0
  452. package/src/components/app-bar-link.tsx +1 -0
  453. package/src/components/app-bar.spec.tsx +3 -3
  454. package/src/components/app-bar.tsx +2 -0
  455. package/src/components/avatar.tsx +1 -0
  456. package/src/components/badge.tsx +2 -1
  457. package/src/components/breadcrumb.tsx +1 -0
  458. package/src/components/button-group.spec.tsx +7 -6
  459. package/src/components/button-group.tsx +72 -70
  460. package/src/components/button.tsx +1 -0
  461. package/src/components/cache-view.spec.tsx +4 -1
  462. package/src/components/cache-view.tsx +4 -0
  463. package/src/components/card.tsx +3 -1
  464. package/src/components/circular-progress.tsx +1 -0
  465. package/src/components/command-palette/command-palette-input.tsx +1 -0
  466. package/src/components/command-palette/command-palette-suggestion-list.tsx +3 -1
  467. package/src/components/command-palette/index.tsx +2 -0
  468. package/src/components/context-menu/context-menu-item.tsx +1 -0
  469. package/src/components/context-menu/context-menu.tsx +1 -0
  470. package/src/components/data-grid/body.tsx +2 -0
  471. package/src/components/data-grid/data-grid-row.tsx +1 -0
  472. package/src/components/data-grid/data-grid.tsx +1 -0
  473. package/src/components/data-grid/filters/boolean-filter.tsx +2 -0
  474. package/src/components/data-grid/filters/date-filter.tsx +2 -0
  475. package/src/components/data-grid/filters/enum-filter.tsx +2 -0
  476. package/src/components/data-grid/filters/filter-dropdown.tsx +1 -0
  477. package/src/components/data-grid/filters/number-filter.tsx +2 -0
  478. package/src/components/data-grid/filters/string-filter.tsx +2 -0
  479. package/src/components/data-grid/footer.tsx +1 -0
  480. package/src/components/data-grid/header.tsx +2 -0
  481. package/src/components/data-grid/selection-cell.tsx +1 -0
  482. package/src/components/dialog.tsx +15 -15
  483. package/src/components/divider.tsx +1 -0
  484. package/src/components/drawer/drawer-toggle-button.tsx +2 -1
  485. package/src/components/drawer/index.tsx +1 -0
  486. package/src/components/dropdown.tsx +1 -0
  487. package/src/components/fab.tsx +1 -0
  488. package/src/components/form.tsx +2 -0
  489. package/src/components/grid.tsx +3 -1
  490. package/src/components/icons/icon.tsx +2 -0
  491. package/src/components/image.tsx +1 -0
  492. package/src/components/inputs/autocomplete.tsx +2 -0
  493. package/src/components/inputs/checkbox.tsx +2 -1
  494. package/src/components/inputs/input-number.tsx +1 -0
  495. package/src/components/inputs/input.tsx +1 -0
  496. package/src/components/inputs/radio-group.tsx +1 -0
  497. package/src/components/inputs/radio.tsx +1 -0
  498. package/src/components/inputs/select.spec.tsx +3 -6
  499. package/src/components/inputs/select.tsx +13 -15
  500. package/src/components/inputs/slider.tsx +27 -36
  501. package/src/components/inputs/switch.tsx +2 -1
  502. package/src/components/inputs/text-area.tsx +1 -0
  503. package/src/components/linear-progress.tsx +1 -0
  504. package/src/components/list/list-item.tsx +1 -0
  505. package/src/components/list/list.tsx +2 -0
  506. package/src/components/loader.tsx +1 -0
  507. package/src/components/markdown/markdown-display.spec.tsx +2 -2
  508. package/src/components/markdown/markdown-display.tsx +1 -1
  509. package/src/components/markdown/markdown-editor.spec.tsx +262 -1
  510. package/src/components/markdown/markdown-editor.tsx +64 -10
  511. package/src/components/markdown/markdown-input.spec.tsx +63 -0
  512. package/src/components/markdown/markdown-input.tsx +7 -11
  513. package/src/components/markdown/markdown-validation.ts +33 -0
  514. package/src/components/modal.tsx +2 -0
  515. package/src/components/noty-list.spec.tsx +1 -1
  516. package/src/components/noty-list.tsx +4 -2
  517. package/src/components/page-container/index.tsx +2 -1
  518. package/src/components/page-container/page-header.spec.tsx +6 -4
  519. package/src/components/page-container/page-header.tsx +23 -15
  520. package/src/components/page-layout/index.tsx +2 -0
  521. package/src/components/paper.tsx +6 -1
  522. package/src/components/rating.tsx +1 -0
  523. package/src/components/result.spec.tsx +3 -3
  524. package/src/components/result.tsx +9 -15
  525. package/src/components/suggest/index.tsx +2 -0
  526. package/src/components/suggest/suggest-input.tsx +1 -0
  527. package/src/components/suggest/suggestion-list.tsx +3 -1
  528. package/src/components/tabs.tsx +1 -0
  529. package/src/components/timeline.spec.tsx +0 -95
  530. package/src/components/timeline.tsx +63 -54
  531. package/src/components/tooltip.tsx +1 -0
  532. package/src/components/tree/tree-item.tsx +1 -0
  533. package/src/components/tree/tree.tsx +2 -0
  534. package/src/components/typography.spec.tsx +16 -16
  535. package/src/components/typography.tsx +121 -110
  536. package/src/components/wizard/index.tsx +1 -0
  537. package/src/services/css-variable-theme.spec.ts +108 -0
  538. package/src/services/css-variable-theme.ts +30 -7
  539. package/src/services/get-rgb-from-color-string.spec.ts +122 -0
  540. package/src/services/get-rgb-from-color-string.ts +96 -0
  541. package/src/services/get-text-color.spec.ts +25 -0
  542. package/src/services/get-text-color.ts +15 -0
  543. package/src/services/index.ts +7 -4
  544. package/src/services/rgb-color.spec.ts +79 -0
  545. package/src/services/rgb-color.ts +20 -0
  546. package/src/services/theme-provider-service.spec.ts +12 -185
  547. package/src/services/theme-provider-service.ts +8 -72
  548. package/src/themes/architect-palette.ts +57 -0
  549. package/src/themes/architect-theme.ts +124 -0
  550. package/src/themes/auditore-palette.ts +57 -0
  551. package/src/themes/auditore-theme.ts +124 -0
  552. package/src/themes/black-mesa-palette.ts +57 -0
  553. package/src/themes/black-mesa-theme.ts +124 -0
  554. package/src/themes/chieftain-palette.ts +57 -0
  555. package/src/themes/chieftain-theme.ts +125 -0
  556. package/src/{services → themes}/default-dark-palette.ts +2 -2
  557. package/src/{services → themes}/default-dark-theme.ts +7 -1
  558. package/src/{services → themes}/default-light-theme.ts +7 -1
  559. package/src/{services → themes}/default-palette.ts +1 -1
  560. package/src/themes/dragonborn-palette.ts +57 -0
  561. package/src/themes/dragonborn-theme.ts +124 -0
  562. package/src/themes/hawkins-palette.ts +57 -0
  563. package/src/themes/hawkins-theme.ts +124 -0
  564. package/src/themes/jedi-palette.ts +57 -0
  565. package/src/themes/jedi-theme.ts +124 -0
  566. package/src/themes/neon-runner-palette.ts +57 -0
  567. package/src/themes/neon-runner-theme.ts +121 -0
  568. package/src/themes/paladin-palette.ts +57 -0
  569. package/src/themes/paladin-theme.ts +125 -0
  570. package/src/themes/plumber-palette.ts +57 -0
  571. package/src/themes/plumber-theme.ts +122 -0
  572. package/src/themes/replicant-palette.ts +57 -0
  573. package/src/themes/replicant-theme.ts +124 -0
  574. package/src/themes/sandworm-palette.ts +57 -0
  575. package/src/themes/sandworm-theme.ts +124 -0
  576. package/src/themes/shadow-broker-palette.ts +57 -0
  577. package/src/themes/shadow-broker-theme.ts +122 -0
  578. package/src/themes/sith-palette.ts +57 -0
  579. package/src/themes/sith-theme.ts +124 -0
  580. package/src/themes/vault-dweller-palette.ts +57 -0
  581. package/src/themes/vault-dweller-theme.ts +124 -0
  582. package/src/themes/wild-hunt-palette.ts +57 -0
  583. package/src/themes/wild-hunt-theme.ts +124 -0
  584. package/src/themes/xenomorph-palette.ts +57 -0
  585. package/src/themes/xenomorph-theme.ts +122 -0
  586. package/esm/services/default-dark-palette.d.ts +0 -8
  587. package/esm/services/default-dark-palette.d.ts.map +0 -1
  588. package/esm/services/default-dark-theme.d.ts.map +0 -1
  589. package/esm/services/default-dark-theme.js.map +0 -1
  590. package/esm/services/default-light-theme.d.ts.map +0 -1
  591. package/esm/services/default-light-theme.js.map +0 -1
  592. package/esm/services/default-palette.d.ts.map +0 -1
  593. package/esm/services/default-palette.js.map +0 -1
  594. /package/esm/{services → themes}/default-palette.js +0 -0
@@ -133,10 +133,271 @@ describe('MarkdownEditor', () => {
133
133
  expect(textarea.value).toBe(mdContent)
134
134
 
135
135
  const heading = document.querySelector(
136
- 'shade-markdown-editor shade-markdown-display shade-typography[data-variant="h1"]',
136
+ 'shade-markdown-editor shade-markdown-display [is^="shade-typography"][data-variant="h1"]',
137
137
  )
138
138
  expect(heading).not.toBeNull()
139
139
  expect(heading?.textContent).toContain('Test Content')
140
140
  })
141
141
  })
142
+
143
+ describe('form integration', () => {
144
+ it('should render a label when labelTitle is provided', async () => {
145
+ await usingAsync(new Injector(), async (injector) => {
146
+ const rootElement = document.getElementById('root') as HTMLDivElement
147
+
148
+ initializeShadeRoot({
149
+ injector,
150
+ rootElement,
151
+ jsxElement: <MarkdownEditor value="" labelTitle="Description" />,
152
+ })
153
+
154
+ await flushUpdates()
155
+
156
+ const label = document.querySelector('shade-markdown-editor .md-editor-label')
157
+ expect(label).not.toBeNull()
158
+ expect(label?.textContent).toBe('Description')
159
+ })
160
+ })
161
+
162
+ it('should not render a label when labelTitle is not provided', async () => {
163
+ await usingAsync(new Injector(), async (injector) => {
164
+ const rootElement = document.getElementById('root') as HTMLDivElement
165
+
166
+ initializeShadeRoot({
167
+ injector,
168
+ rootElement,
169
+ jsxElement: <MarkdownEditor value="" />,
170
+ })
171
+
172
+ await flushUpdates()
173
+
174
+ const label = document.querySelector('shade-markdown-editor .md-editor-label')
175
+ expect(label).toBeNull()
176
+ })
177
+ })
178
+
179
+ it('should set data-invalid when required and value is empty', async () => {
180
+ await usingAsync(new Injector(), async (injector) => {
181
+ const rootElement = document.getElementById('root') as HTMLDivElement
182
+
183
+ initializeShadeRoot({
184
+ injector,
185
+ rootElement,
186
+ jsxElement: <MarkdownEditor value="" required />,
187
+ })
188
+
189
+ await flushUpdates()
190
+
191
+ const editor = document.querySelector('shade-markdown-editor') as HTMLElement
192
+ expect(editor.hasAttribute('data-invalid')).toBe(true)
193
+ })
194
+ })
195
+
196
+ it('should not set data-invalid when required and value is provided', async () => {
197
+ await usingAsync(new Injector(), async (injector) => {
198
+ const rootElement = document.getElementById('root') as HTMLDivElement
199
+
200
+ initializeShadeRoot({
201
+ injector,
202
+ rootElement,
203
+ jsxElement: <MarkdownEditor value="some content" required />,
204
+ })
205
+
206
+ await flushUpdates()
207
+
208
+ const editor = document.querySelector('shade-markdown-editor') as HTMLElement
209
+ expect(editor.hasAttribute('data-invalid')).toBe(false)
210
+ })
211
+ })
212
+
213
+ it('should show "Value is required" helper text when required and empty', async () => {
214
+ await usingAsync(new Injector(), async (injector) => {
215
+ const rootElement = document.getElementById('root') as HTMLDivElement
216
+
217
+ initializeShadeRoot({
218
+ injector,
219
+ rootElement,
220
+ jsxElement: <MarkdownEditor value="" required />,
221
+ })
222
+
223
+ await flushUpdates()
224
+
225
+ const helperText = document.querySelector('shade-markdown-editor .md-editor-helperText')
226
+ expect(helperText).not.toBeNull()
227
+ expect(helperText?.textContent).toBe('Value is required')
228
+ })
229
+ })
230
+
231
+ it('should set data-invalid when getValidationResult returns invalid', async () => {
232
+ await usingAsync(new Injector(), async (injector) => {
233
+ const rootElement = document.getElementById('root') as HTMLDivElement
234
+
235
+ initializeShadeRoot({
236
+ injector,
237
+ rootElement,
238
+ jsxElement: (
239
+ <MarkdownEditor
240
+ value="short"
241
+ getValidationResult={({ value }) =>
242
+ value.length < 10 ? { isValid: false, message: 'Too short' } : { isValid: true }
243
+ }
244
+ />
245
+ ),
246
+ })
247
+
248
+ await flushUpdates()
249
+
250
+ const editor = document.querySelector('shade-markdown-editor') as HTMLElement
251
+ expect(editor.hasAttribute('data-invalid')).toBe(true)
252
+ expect(editor.textContent).toContain('Too short')
253
+ })
254
+ })
255
+
256
+ it('should not set data-invalid when getValidationResult returns valid', async () => {
257
+ await usingAsync(new Injector(), async (injector) => {
258
+ const rootElement = document.getElementById('root') as HTMLDivElement
259
+
260
+ initializeShadeRoot({
261
+ injector,
262
+ rootElement,
263
+ jsxElement: (
264
+ <MarkdownEditor
265
+ value="long enough content"
266
+ getValidationResult={({ value }) =>
267
+ value.length < 10 ? { isValid: false, message: 'Too short' } : { isValid: true }
268
+ }
269
+ />
270
+ ),
271
+ })
272
+
273
+ await flushUpdates()
274
+
275
+ const editor = document.querySelector('shade-markdown-editor') as HTMLElement
276
+ expect(editor.hasAttribute('data-invalid')).toBe(false)
277
+ })
278
+ })
279
+
280
+ it('should display helper text from getHelperText', async () => {
281
+ await usingAsync(new Injector(), async (injector) => {
282
+ const rootElement = document.getElementById('root') as HTMLDivElement
283
+
284
+ initializeShadeRoot({
285
+ injector,
286
+ rootElement,
287
+ jsxElement: <MarkdownEditor value="" getHelperText={() => 'Enter your description'} />,
288
+ })
289
+
290
+ await flushUpdates()
291
+
292
+ const helperText = document.querySelector('shade-markdown-editor .md-editor-helperText')
293
+ expect(helperText).not.toBeNull()
294
+ expect(helperText?.textContent).toBe('Enter your description')
295
+ })
296
+ })
297
+
298
+ it('should forward name prop to the inner textarea', async () => {
299
+ await usingAsync(new Injector(), async (injector) => {
300
+ const rootElement = document.getElementById('root') as HTMLDivElement
301
+
302
+ initializeShadeRoot({
303
+ injector,
304
+ rootElement,
305
+ jsxElement: <MarkdownEditor value="" name="description" />,
306
+ })
307
+
308
+ await flushUpdates()
309
+
310
+ const textarea = document.querySelector('shade-markdown-editor textarea') as HTMLTextAreaElement
311
+ expect(textarea.name).toBe('description')
312
+ })
313
+ })
314
+
315
+ it('should forward required prop to the inner textarea', async () => {
316
+ await usingAsync(new Injector(), async (injector) => {
317
+ const rootElement = document.getElementById('root') as HTMLDivElement
318
+
319
+ initializeShadeRoot({
320
+ injector,
321
+ rootElement,
322
+ jsxElement: <MarkdownEditor value="content" required />,
323
+ })
324
+
325
+ await flushUpdates()
326
+
327
+ const textarea = document.querySelector('shade-markdown-editor textarea') as HTMLTextAreaElement
328
+ expect(textarea.required).toBe(true)
329
+ })
330
+ })
331
+
332
+ it('should forward disabled prop to the inner textarea', async () => {
333
+ await usingAsync(new Injector(), async (injector) => {
334
+ const rootElement = document.getElementById('root') as HTMLDivElement
335
+
336
+ initializeShadeRoot({
337
+ injector,
338
+ rootElement,
339
+ jsxElement: <MarkdownEditor value="" disabled />,
340
+ })
341
+
342
+ await flushUpdates()
343
+
344
+ const textarea = document.querySelector('shade-markdown-editor textarea') as HTMLTextAreaElement
345
+ expect(textarea.disabled).toBe(true)
346
+ })
347
+ })
348
+
349
+ it('should forward placeholder prop to the inner textarea', async () => {
350
+ await usingAsync(new Injector(), async (injector) => {
351
+ const rootElement = document.getElementById('root') as HTMLDivElement
352
+
353
+ initializeShadeRoot({
354
+ injector,
355
+ rootElement,
356
+ jsxElement: <MarkdownEditor value="" placeholder="Type here..." />,
357
+ })
358
+
359
+ await flushUpdates()
360
+
361
+ const textarea = document.querySelector('shade-markdown-editor textarea') as HTMLTextAreaElement
362
+ expect(textarea.placeholder).toBe('Type here...')
363
+ })
364
+ })
365
+
366
+ it('should forward rows prop to the inner textarea', async () => {
367
+ await usingAsync(new Injector(), async (injector) => {
368
+ const rootElement = document.getElementById('root') as HTMLDivElement
369
+
370
+ initializeShadeRoot({
371
+ injector,
372
+ rootElement,
373
+ jsxElement: <MarkdownEditor value="" rows={5} />,
374
+ })
375
+
376
+ await flushUpdates()
377
+
378
+ const textarea = document.querySelector('shade-markdown-editor textarea') as HTMLTextAreaElement
379
+ expect(textarea.rows).toBe(5)
380
+ })
381
+ })
382
+
383
+ it('should set hideChrome on the inner MarkdownInput', async () => {
384
+ await usingAsync(new Injector(), async (injector) => {
385
+ const rootElement = document.getElementById('root') as HTMLDivElement
386
+
387
+ initializeShadeRoot({
388
+ injector,
389
+ rootElement,
390
+ jsxElement: <MarkdownEditor value="" labelTitle="My Label" />,
391
+ })
392
+
393
+ await flushUpdates()
394
+
395
+ const editorLabel = document.querySelector('shade-markdown-editor .md-editor-label')
396
+ expect(editorLabel?.textContent).toBe('My Label')
397
+
398
+ const inputLabel = document.querySelector('shade-markdown-editor shade-markdown-input label > span')
399
+ expect(inputLabel).toBeNull()
400
+ })
401
+ })
402
+ })
142
403
  })
@@ -2,7 +2,8 @@ import { Shade, createComponent } from '@furystack/shades'
2
2
  import { cssVariableTheme } from '../../services/css-variable-theme.js'
3
3
  import { Tabs } from '../tabs.js'
4
4
  import { MarkdownDisplay } from './markdown-display.js'
5
- import { MarkdownInput } from './markdown-input.js'
5
+ import { MarkdownInput, type MarkdownInputProps } from './markdown-input.js'
6
+ import { resolveValidationState } from './markdown-validation.js'
6
7
 
7
8
  export type MarkdownEditorLayout = 'side-by-side' | 'tabs' | 'above-below'
8
9
 
@@ -19,7 +20,10 @@ export type MarkdownEditorProps = {
19
20
  readOnly?: boolean
20
21
  /** Inline styles applied to the host element */
21
22
  style?: Partial<CSSStyleDeclaration>
22
- }
23
+ } & Pick<
24
+ MarkdownInputProps,
25
+ 'name' | 'required' | 'labelTitle' | 'disabled' | 'placeholder' | 'rows' | 'getValidationResult' | 'getHelperText'
26
+ >
23
27
 
24
28
  type TabType = 'edit' | 'preview'
25
29
 
@@ -31,12 +35,42 @@ export const MarkdownEditor = Shade<MarkdownEditorProps>({
31
35
  shadowDomName: 'shade-markdown-editor',
32
36
  css: {
33
37
  display: 'flex',
38
+ fontFamily: cssVariableTheme.typography.fontFamily,
34
39
  flexDirection: 'column',
35
- border: `1px solid ${cssVariableTheme.action.subtleBorder}`,
36
- borderRadius: cssVariableTheme.shape.borderRadius.md,
37
- overflow: 'hidden',
38
40
  minHeight: '0',
39
41
 
42
+ '& .md-editor-label': {
43
+ fontSize: cssVariableTheme.typography.fontSize.xs,
44
+ color: cssVariableTheme.text.secondary,
45
+ padding: `0 0 ${cssVariableTheme.spacing.sm} 0`,
46
+ transition: `color ${cssVariableTheme.transitions.duration.slow} ${cssVariableTheme.transitions.easing.default}`,
47
+ },
48
+
49
+ '&[data-invalid] .md-editor-label': {
50
+ color: cssVariableTheme.palette.error.main,
51
+ },
52
+
53
+ '& .md-editor-frame': {
54
+ display: 'flex',
55
+ flexDirection: 'column',
56
+ border: `1px solid ${cssVariableTheme.action.subtleBorder}`,
57
+ borderRadius: cssVariableTheme.shape.borderRadius.md,
58
+ overflow: 'hidden',
59
+ flex: '1',
60
+ minHeight: '0',
61
+ },
62
+
63
+ '&[data-invalid] .md-editor-frame': {
64
+ borderColor: cssVariableTheme.palette.error.main,
65
+ },
66
+
67
+ '& .md-editor-helperText': {
68
+ fontSize: cssVariableTheme.typography.fontSize.xs,
69
+ padding: `${cssVariableTheme.spacing.sm} 0 0 0`,
70
+ opacity: '0.85',
71
+ lineHeight: '1.4',
72
+ },
73
+
40
74
  '& .md-editor-split': {
41
75
  display: 'flex',
42
76
  flex: '1',
@@ -119,8 +153,11 @@ export const MarkdownEditor = Shade<MarkdownEditorProps>({
119
153
  render: ({ props, useState, useHostProps }) => {
120
154
  const layout = props.layout ?? 'side-by-side'
121
155
 
156
+ const { isInvalid, helperNode } = resolveValidationState(props)
157
+
122
158
  useHostProps({
123
159
  ...(props.style ? { style: props.style as Record<string, string> } : {}),
160
+ 'data-invalid': isInvalid ? '' : undefined,
124
161
  })
125
162
 
126
163
  const [activeTab, setActiveTab] = useState<TabType>('activeTab', 'edit')
@@ -131,13 +168,22 @@ export const MarkdownEditor = Shade<MarkdownEditorProps>({
131
168
  onValueChange={props.onValueChange}
132
169
  maxImageSizeBytes={props.maxImageSizeBytes}
133
170
  readOnly={props.readOnly}
171
+ name={props.name}
172
+ required={props.required}
173
+ disabled={props.disabled}
174
+ placeholder={props.placeholder}
175
+ rows={props.rows}
176
+ getValidationResult={props.getValidationResult}
177
+ hideChrome
134
178
  />
135
179
  )
136
180
 
137
181
  const previewPane = <MarkdownDisplay content={props.value} readOnly={false} onChange={props.onValueChange} />
138
182
 
183
+ let content: JSX.Element
184
+
139
185
  if (layout === 'tabs') {
140
- return (
186
+ content = (
141
187
  <Tabs
142
188
  activeKey={activeTab}
143
189
  onTabChange={(key) => setActiveTab(key as TabType)}
@@ -155,13 +201,21 @@ export const MarkdownEditor = Shade<MarkdownEditorProps>({
155
201
  ]}
156
202
  />
157
203
  )
204
+ } else {
205
+ content = (
206
+ <div className="md-editor-split" data-layout={layout}>
207
+ <div className="md-editor-pane md-editor-pane-input">{inputPane}</div>
208
+ <div className="md-editor-pane md-editor-pane-preview">{previewPane}</div>
209
+ </div>
210
+ )
158
211
  }
159
212
 
160
213
  return (
161
- <div className="md-editor-split" data-layout={layout}>
162
- <div className="md-editor-pane md-editor-pane-input">{inputPane}</div>
163
- <div className="md-editor-pane md-editor-pane-preview">{previewPane}</div>
164
- </div>
214
+ <>
215
+ {props.labelTitle ? <span className="md-editor-label">{props.labelTitle}</span> : null}
216
+ <div className="md-editor-frame">{content}</div>
217
+ {helperNode ? <span className="md-editor-helperText">{helperNode}</span> : null}
218
+ </>
165
219
  )
166
220
  },
167
221
  })
@@ -271,6 +271,69 @@ describe('MarkdownInput', () => {
271
271
  })
272
272
  })
273
273
 
274
+ describe('hideChrome', () => {
275
+ it('should suppress the label when hideChrome is true', async () => {
276
+ await usingAsync(new Injector(), async (injector) => {
277
+ const rootElement = document.getElementById('root') as HTMLDivElement
278
+
279
+ initializeShadeRoot({
280
+ injector,
281
+ rootElement,
282
+ jsxElement: <MarkdownInput value="" labelTitle="My Label" hideChrome />,
283
+ })
284
+
285
+ await flushUpdates()
286
+
287
+ const wrapper = document.querySelector('shade-markdown-input') as HTMLElement
288
+ const spans = wrapper.querySelectorAll('label > span')
289
+ const labelSpan = Array.from(spans).find((s) => s.textContent === 'My Label')
290
+ expect(labelSpan).toBeUndefined()
291
+ })
292
+ })
293
+
294
+ it('should suppress the helper text when hideChrome is true', async () => {
295
+ await usingAsync(new Injector(), async (injector) => {
296
+ const rootElement = document.getElementById('root') as HTMLDivElement
297
+
298
+ initializeShadeRoot({
299
+ injector,
300
+ rootElement,
301
+ jsxElement: (
302
+ <MarkdownInput
303
+ value="short"
304
+ hideChrome
305
+ getValidationResult={({ value }) =>
306
+ value.length < 10 ? { isValid: false, message: 'Too short' } : { isValid: true }
307
+ }
308
+ />
309
+ ),
310
+ })
311
+
312
+ await flushUpdates()
313
+
314
+ const helperText = document.querySelector('shade-markdown-input .helperText')
315
+ expect(helperText).toBeNull()
316
+ })
317
+ })
318
+
319
+ it('should still set data-invalid when hideChrome is true', async () => {
320
+ await usingAsync(new Injector(), async (injector) => {
321
+ const rootElement = document.getElementById('root') as HTMLDivElement
322
+
323
+ initializeShadeRoot({
324
+ injector,
325
+ rootElement,
326
+ jsxElement: <MarkdownInput value="" required hideChrome />,
327
+ })
328
+
329
+ await flushUpdates()
330
+
331
+ const wrapper = document.querySelector('shade-markdown-input') as HTMLElement
332
+ expect(wrapper.hasAttribute('data-invalid')).toBe(true)
333
+ })
334
+ })
335
+ })
336
+
274
337
  it('should render with validation inside a Form', async () => {
275
338
  await usingAsync(new Injector(), async (injector) => {
276
339
  const rootElement = document.getElementById('root') as HTMLDivElement
@@ -2,6 +2,7 @@ import { Shade, createComponent } from '@furystack/shades'
2
2
  import { cssVariableTheme } from '../../services/css-variable-theme.js'
3
3
  import type { InputValidationResult } from '../inputs/input.js'
4
4
  import { FormService } from '../form.js'
5
+ import { resolveValidationState } from './markdown-validation.js'
5
6
 
6
7
  const DEFAULT_MAX_IMAGE_SIZE = 256 * 1024
7
8
 
@@ -30,6 +31,8 @@ export type MarkdownInputProps = {
30
31
  getValidationResult?: (options: { value: string }) => InputValidationResult
31
32
  /** Optional helper text callback */
32
33
  getHelperText?: (options: { value: string; validationResult?: InputValidationResult }) => JSX.Element | string
34
+ /** When true, suppresses visual label and helper text rendering while keeping form mechanics */
35
+ hideChrome?: boolean
33
36
  }
34
37
 
35
38
  /**
@@ -41,6 +44,7 @@ export const MarkdownInput = Shade<MarkdownInputProps>({
41
44
  shadowDomName: 'shade-markdown-input',
42
45
  css: {
43
46
  display: 'block',
47
+ fontFamily: cssVariableTheme.typography.fontFamily,
44
48
  marginBottom: '1em',
45
49
 
46
50
  '& label': {
@@ -117,9 +121,7 @@ export const MarkdownInput = Shade<MarkdownInputProps>({
117
121
  }
118
122
  })
119
123
 
120
- const validationResult = props.getValidationResult?.({ value: props.value })
121
- const isRequired = props.required && !props.value
122
- const isInvalid = validationResult?.isValid === false || isRequired
124
+ const { validationResult, isRequired, isInvalid, helperNode } = resolveValidationState(props)
123
125
 
124
126
  if (injector.cachedSingletons.has(FormService) && props.name) {
125
127
  const formService = injector.getInstance(FormService)
@@ -135,12 +137,6 @@ export const MarkdownInput = Shade<MarkdownInputProps>({
135
137
  'data-invalid': isInvalid ? '' : undefined,
136
138
  })
137
139
 
138
- const helperNode =
139
- (validationResult?.isValid === false && validationResult?.message) ||
140
- (isRequired && 'Value is required') ||
141
- props.getHelperText?.({ value: props.value, validationResult }) ||
142
- ''
143
-
144
140
  const handleInput = (ev: Event) => {
145
141
  const target = ev.target as HTMLTextAreaElement
146
142
  props.onValueChange?.(target.value)
@@ -187,7 +183,7 @@ export const MarkdownInput = Shade<MarkdownInputProps>({
187
183
 
188
184
  return (
189
185
  <label>
190
- {props.labelTitle ? <span>{props.labelTitle}</span> : null}
186
+ {!props.hideChrome && props.labelTitle ? <span>{props.labelTitle}</span> : null}
191
187
  <textarea
192
188
  ref={textareaRef}
193
189
  name={props.name}
@@ -200,7 +196,7 @@ export const MarkdownInput = Shade<MarkdownInputProps>({
200
196
  placeholder={props.placeholder}
201
197
  rows={props.rows ?? 10}
202
198
  />
203
- {helperNode ? <span className="helperText">{helperNode}</span> : null}
199
+ {!props.hideChrome && helperNode ? <span className="helperText">{helperNode}</span> : null}
204
200
  </label>
205
201
  )
206
202
  },
@@ -0,0 +1,33 @@
1
+ import type { InputValidationResult } from '../inputs/input.js'
2
+
3
+ type ValidationOptions = {
4
+ value: string
5
+ required?: boolean
6
+ getValidationResult?: (options: { value: string }) => InputValidationResult
7
+ getHelperText?: (options: { value: string; validationResult?: InputValidationResult }) => JSX.Element | string
8
+ }
9
+
10
+ export type ValidationState = {
11
+ validationResult: InputValidationResult | undefined
12
+ isRequired: boolean
13
+ isInvalid: boolean
14
+ helperNode: JSX.Element | string
15
+ }
16
+
17
+ /**
18
+ * Computes validation state from common markdown field props.
19
+ * Shared between MarkdownInput and MarkdownEditor to keep the logic in one place.
20
+ */
21
+ export const resolveValidationState = (options: ValidationOptions): ValidationState => {
22
+ const validationResult = options.getValidationResult?.({ value: options.value })
23
+ const isRequired = !!options.required && !options.value
24
+ const isInvalid = validationResult?.isValid === false || isRequired
25
+
26
+ const helperNode =
27
+ (validationResult?.isValid === false && validationResult?.message) ||
28
+ (isRequired && 'Value is required') ||
29
+ options.getHelperText?.({ value: options.value, validationResult }) ||
30
+ ''
31
+
32
+ return { validationResult, isRequired, isInvalid, helperNode }
33
+ }
@@ -1,4 +1,5 @@
1
1
  import { Shade, createComponent } from '@furystack/shades'
2
+ import { cssVariableTheme } from '../services/css-variable-theme.js'
2
3
 
3
4
  export type ModalProps = {
4
5
  backdropStyle?: Partial<CSSStyleDeclaration>
@@ -11,6 +12,7 @@ export type ModalProps = {
11
12
  export const Modal = Shade<ModalProps>({
12
13
  shadowDomName: 'shade-modal',
13
14
  css: {
15
+ fontFamily: cssVariableTheme.typography.fontFamily,
14
16
  '& .shade-backdrop': {
15
17
  width: '100%',
16
18
  height: '100%',
@@ -2,7 +2,7 @@ import { Injector } from '@furystack/inject'
2
2
  import { createComponent, flushUpdates, initializeShadeRoot } from '@furystack/shades'
3
3
  import { usingAsync } from '@furystack/utils'
4
4
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
5
- import { defaultDarkTheme } from '../services/default-dark-theme.js'
5
+ import { defaultDarkTheme } from '../themes/default-dark-theme.js'
6
6
  import type { NotyModel } from '../services/noty-service.js'
7
7
  import { NotyService } from '../services/noty-service.js'
8
8
  import { ThemeProviderService } from '../services/theme-provider-service.js'
@@ -1,11 +1,12 @@
1
1
  import { createComponent, Shade } from '@furystack/shades'
2
2
  import { cssVariableTheme } from '../services/css-variable-theme.js'
3
+ import { getTextColor } from '../services/get-text-color.js'
3
4
  import type { NotyModel } from '../services/noty-service.js'
4
5
  import { NotyService } from '../services/noty-service.js'
5
6
  import { ThemeProviderService } from '../services/theme-provider-service.js'
6
7
  import { promisifyAnimation } from '../utils/promisify-animation.js'
7
- import { Icon } from './icons/icon.js'
8
8
  import { close } from './icons/icon-definitions.js'
9
+ import { Icon } from './icons/icon.js'
9
10
 
10
11
  export const getDefaultNotyTimeouts = (type: NotyModel['type']) => {
11
12
  switch (type) {
@@ -96,7 +97,7 @@ export const NotyComponent = Shade<{ model: NotyModel; onDismiss: () => void }>(
96
97
 
97
98
  const themeProvider = injector.getInstance(ThemeProviderService)
98
99
  const colors = themeProvider.theme.palette[props.model.type]
99
- const textColor = themeProvider.getTextColor(colors.main)
100
+ const textColor = getTextColor(colors.main)
100
101
 
101
102
  const removeSelf = async () => {
102
103
  const hostEl = wrapperRef.current?.closest('shade-noty') as HTMLElement | null
@@ -145,6 +146,7 @@ export const NotyList = Shade({
145
146
  shadowDomName: 'shade-noty-list',
146
147
  css: {
147
148
  position: 'fixed',
149
+ fontFamily: cssVariableTheme.typography.fontFamily,
148
150
  bottom: cssVariableTheme.spacing.md,
149
151
  right: cssVariableTheme.spacing.md,
150
152
  display: 'flex',
@@ -44,7 +44,7 @@ export type PageContainerProps = {
44
44
  * ```tsx
45
45
  * // Full width container
46
46
  * <PageContainer gap="16px">
47
- * <h2>Dashboard</h2>
47
+ * <Typography variant="h4">Dashboard</Typography>
48
48
  * <GridOfCards />
49
49
  * </PageContainer>
50
50
  * ```
@@ -55,6 +55,7 @@ export const PageContainer = Shade<PageContainerProps>({
55
55
  elementBaseName: 'div',
56
56
  css: {
57
57
  display: 'flex',
58
+ fontFamily: cssVariableTheme.typography.fontFamily,
58
59
  flexDirection: 'column',
59
60
  boxSizing: 'border-box',
60
61
  color: cssVariableTheme.text.primary,
@@ -48,7 +48,7 @@ describe('PageHeader component', () => {
48
48
  })
49
49
  })
50
50
 
51
- it('should render the title as h2', async () => {
51
+ it('should render the title as Typography with h4 variant', async () => {
52
52
  await usingAsync(new Injector(), async (injector) => {
53
53
  const rootElement = document.getElementById('root') as HTMLDivElement
54
54
 
@@ -60,7 +60,8 @@ describe('PageHeader component', () => {
60
60
 
61
61
  await flushUpdates()
62
62
  const title = document.querySelector('[data-testid="page-header-title"]')
63
- expect(title?.tagName.toLowerCase()).toBe('h2')
63
+ expect(title?.getAttribute('is')).toBe('shade-typography-h4')
64
+ expect(title?.getAttribute('data-variant')).toBe('h4')
64
65
  })
65
66
  })
66
67
  })
@@ -151,7 +152,7 @@ describe('PageHeader component', () => {
151
152
  })
152
153
  })
153
154
 
154
- it('should render description as p element', async () => {
155
+ it('should render description as Typography with body1 variant', async () => {
155
156
  await usingAsync(new Injector(), async (injector) => {
156
157
  const rootElement = document.getElementById('root') as HTMLDivElement
157
158
 
@@ -163,7 +164,8 @@ describe('PageHeader component', () => {
163
164
 
164
165
  await flushUpdates()
165
166
  const description = document.querySelector('[data-testid="page-header-description"]')
166
- expect(description?.tagName.toLowerCase()).toBe('p')
167
+ expect(description?.getAttribute('is')).toBe('shade-typography-p')
168
+ expect(description?.getAttribute('data-variant')).toBe('body1')
167
169
  })
168
170
  })
169
171
  })