@furystack/shades-common-components 10.0.35 → 11.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 (295) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/esm/components/animations.spec.d.ts +2 -0
  3. package/esm/components/animations.spec.d.ts.map +1 -0
  4. package/esm/components/animations.spec.js +201 -0
  5. package/esm/components/animations.spec.js.map +1 -0
  6. package/esm/components/app-bar-link.js +21 -20
  7. package/esm/components/app-bar-link.js.map +1 -1
  8. package/esm/components/app-bar-link.spec.d.ts +2 -0
  9. package/esm/components/app-bar-link.spec.d.ts.map +1 -0
  10. package/esm/components/app-bar-link.spec.js +252 -0
  11. package/esm/components/app-bar-link.spec.js.map +1 -0
  12. package/esm/components/app-bar.js +21 -21
  13. package/esm/components/app-bar.js.map +1 -1
  14. package/esm/components/app-bar.spec.d.ts +2 -0
  15. package/esm/components/app-bar.spec.d.ts.map +1 -0
  16. package/esm/components/app-bar.spec.js +117 -0
  17. package/esm/components/app-bar.spec.js.map +1 -0
  18. package/esm/components/avatar.d.ts.map +1 -1
  19. package/esm/components/avatar.js +15 -19
  20. package/esm/components/avatar.js.map +1 -1
  21. package/esm/components/avatar.spec.d.ts +2 -0
  22. package/esm/components/avatar.spec.d.ts.map +1 -0
  23. package/esm/components/avatar.spec.js +114 -0
  24. package/esm/components/avatar.spec.js.map +1 -0
  25. package/esm/components/button.d.ts.map +1 -1
  26. package/esm/components/button.js +145 -156
  27. package/esm/components/button.js.map +1 -1
  28. package/esm/components/button.spec.d.ts +2 -0
  29. package/esm/components/button.spec.d.ts.map +1 -0
  30. package/esm/components/button.spec.js +155 -0
  31. package/esm/components/button.spec.js.map +1 -0
  32. package/esm/components/command-palette/command-palette-input.d.ts.map +1 -1
  33. package/esm/components/command-palette/command-palette-input.js +18 -16
  34. package/esm/components/command-palette/command-palette-input.js.map +1 -1
  35. package/esm/components/command-palette/command-palette-input.spec.d.ts +2 -0
  36. package/esm/components/command-palette/command-palette-input.spec.d.ts.map +1 -0
  37. package/esm/components/command-palette/command-palette-input.spec.js +233 -0
  38. package/esm/components/command-palette/command-palette-input.spec.js.map +1 -0
  39. package/esm/components/command-palette/command-palette-manager.spec.d.ts +2 -0
  40. package/esm/components/command-palette/command-palette-manager.spec.d.ts.map +1 -0
  41. package/esm/components/command-palette/command-palette-manager.spec.js +362 -0
  42. package/esm/components/command-palette/command-palette-manager.spec.js.map +1 -0
  43. package/esm/components/command-palette/command-palette-suggestion-list.d.ts.map +1 -1
  44. package/esm/components/command-palette/command-palette-suggestion-list.js +42 -46
  45. package/esm/components/command-palette/command-palette-suggestion-list.js.map +1 -1
  46. package/esm/components/command-palette/command-palette-suggestion-list.spec.d.ts +2 -0
  47. package/esm/components/command-palette/command-palette-suggestion-list.spec.d.ts.map +1 -0
  48. package/esm/components/command-palette/command-palette-suggestion-list.spec.js +376 -0
  49. package/esm/components/command-palette/command-palette-suggestion-list.spec.js.map +1 -0
  50. package/esm/components/command-palette/index.d.ts.map +1 -1
  51. package/esm/components/command-palette/index.js +100 -110
  52. package/esm/components/command-palette/index.js.map +1 -1
  53. package/esm/components/command-palette/index.spec.d.ts +2 -0
  54. package/esm/components/command-palette/index.spec.d.ts.map +1 -0
  55. package/esm/components/command-palette/index.spec.js +509 -0
  56. package/esm/components/command-palette/index.spec.js.map +1 -0
  57. package/esm/components/data-grid/body.js +1 -1
  58. package/esm/components/data-grid/body.js.map +1 -1
  59. package/esm/components/data-grid/body.spec.d.ts +2 -0
  60. package/esm/components/data-grid/body.spec.d.ts.map +1 -0
  61. package/esm/components/data-grid/body.spec.js +228 -0
  62. package/esm/components/data-grid/body.spec.js.map +1 -0
  63. package/esm/components/data-grid/data-grid-row.d.ts.map +1 -1
  64. package/esm/components/data-grid/data-grid-row.js +49 -73
  65. package/esm/components/data-grid/data-grid-row.js.map +1 -1
  66. package/esm/components/data-grid/data-grid-row.spec.d.ts +2 -0
  67. package/esm/components/data-grid/data-grid-row.spec.d.ts.map +1 -0
  68. package/esm/components/data-grid/data-grid-row.spec.js +296 -0
  69. package/esm/components/data-grid/data-grid-row.spec.js.map +1 -0
  70. package/esm/components/data-grid/data-grid.d.ts.map +1 -1
  71. package/esm/components/data-grid/data-grid.js +35 -28
  72. package/esm/components/data-grid/data-grid.js.map +1 -1
  73. package/esm/components/data-grid/data-grid.spec.d.ts +2 -0
  74. package/esm/components/data-grid/data-grid.spec.d.ts.map +1 -0
  75. package/esm/components/data-grid/data-grid.spec.js +544 -0
  76. package/esm/components/data-grid/data-grid.spec.js.map +1 -0
  77. package/esm/components/data-grid/footer.js +21 -15
  78. package/esm/components/data-grid/footer.js.map +1 -1
  79. package/esm/components/data-grid/footer.spec.d.ts +2 -0
  80. package/esm/components/data-grid/footer.spec.d.ts.map +1 -0
  81. package/esm/components/data-grid/footer.spec.js +264 -0
  82. package/esm/components/data-grid/footer.spec.js.map +1 -0
  83. package/esm/components/data-grid/header.d.ts.map +1 -1
  84. package/esm/components/data-grid/header.js +55 -33
  85. package/esm/components/data-grid/header.js.map +1 -1
  86. package/esm/components/data-grid/header.spec.d.ts +2 -0
  87. package/esm/components/data-grid/header.spec.d.ts.map +1 -0
  88. package/esm/components/data-grid/header.spec.js +421 -0
  89. package/esm/components/data-grid/header.spec.js.map +1 -0
  90. package/esm/components/data-grid/selection-cell.d.ts.map +1 -1
  91. package/esm/components/data-grid/selection-cell.js +13 -6
  92. package/esm/components/data-grid/selection-cell.js.map +1 -1
  93. package/esm/components/data-grid/selection-cell.spec.d.ts +2 -0
  94. package/esm/components/data-grid/selection-cell.spec.d.ts.map +1 -0
  95. package/esm/components/data-grid/selection-cell.spec.js +118 -0
  96. package/esm/components/data-grid/selection-cell.spec.js.map +1 -0
  97. package/esm/components/fab.d.ts.map +1 -1
  98. package/esm/components/fab.js +10 -1
  99. package/esm/components/fab.js.map +1 -1
  100. package/esm/components/fab.spec.d.ts +2 -0
  101. package/esm/components/fab.spec.d.ts.map +1 -0
  102. package/esm/components/fab.spec.js +95 -0
  103. package/esm/components/fab.spec.js.map +1 -0
  104. package/esm/components/form.spec.d.ts +2 -0
  105. package/esm/components/form.spec.d.ts.map +1 -0
  106. package/esm/components/form.spec.js +314 -0
  107. package/esm/components/form.spec.js.map +1 -0
  108. package/esm/components/grid.d.ts.map +1 -1
  109. package/esm/components/grid.js +40 -37
  110. package/esm/components/grid.js.map +1 -1
  111. package/esm/components/grid.spec.d.ts +2 -0
  112. package/esm/components/grid.spec.d.ts.map +1 -0
  113. package/esm/components/grid.spec.js +316 -0
  114. package/esm/components/grid.spec.js.map +1 -0
  115. package/esm/components/inputs/autocomplete.spec.d.ts +2 -0
  116. package/esm/components/inputs/autocomplete.spec.d.ts.map +1 -0
  117. package/esm/components/inputs/autocomplete.spec.js +194 -0
  118. package/esm/components/inputs/autocomplete.spec.js.map +1 -0
  119. package/esm/components/inputs/input.d.ts.map +1 -1
  120. package/esm/components/inputs/input.js +141 -109
  121. package/esm/components/inputs/input.js.map +1 -1
  122. package/esm/components/inputs/input.spec.d.ts +2 -0
  123. package/esm/components/inputs/input.spec.d.ts.map +1 -0
  124. package/esm/components/inputs/input.spec.js +577 -0
  125. package/esm/components/inputs/input.spec.js.map +1 -0
  126. package/esm/components/inputs/text-area.d.ts.map +1 -1
  127. package/esm/components/inputs/text-area.js +54 -58
  128. package/esm/components/inputs/text-area.js.map +1 -1
  129. package/esm/components/inputs/text-area.spec.d.ts +2 -0
  130. package/esm/components/inputs/text-area.spec.d.ts.map +1 -0
  131. package/esm/components/inputs/text-area.spec.js +214 -0
  132. package/esm/components/inputs/text-area.spec.js.map +1 -0
  133. package/esm/components/loader.js +1 -1
  134. package/esm/components/loader.js.map +1 -1
  135. package/esm/components/loader.spec.d.ts +2 -0
  136. package/esm/components/loader.spec.d.ts.map +1 -0
  137. package/esm/components/loader.spec.js +251 -0
  138. package/esm/components/loader.spec.js.map +1 -0
  139. package/esm/components/modal.d.ts.map +1 -1
  140. package/esm/components/modal.js +11 -9
  141. package/esm/components/modal.js.map +1 -1
  142. package/esm/components/modal.spec.d.ts +2 -0
  143. package/esm/components/modal.spec.d.ts.map +1 -0
  144. package/esm/components/modal.spec.js +227 -0
  145. package/esm/components/modal.spec.js.map +1 -0
  146. package/esm/components/noty-list.d.ts.map +1 -1
  147. package/esm/components/noty-list.js +39 -40
  148. package/esm/components/noty-list.js.map +1 -1
  149. package/esm/components/noty-list.spec.d.ts +2 -0
  150. package/esm/components/noty-list.spec.d.ts.map +1 -0
  151. package/esm/components/noty-list.spec.js +486 -0
  152. package/esm/components/noty-list.spec.js.map +1 -0
  153. package/esm/components/paper.d.ts.map +1 -1
  154. package/esm/components/paper.js +15 -12
  155. package/esm/components/paper.js.map +1 -1
  156. package/esm/components/paper.spec.d.ts +2 -0
  157. package/esm/components/paper.spec.d.ts.map +1 -0
  158. package/esm/components/paper.spec.js +63 -0
  159. package/esm/components/paper.spec.js.map +1 -0
  160. package/esm/components/skeleton.js +1 -1
  161. package/esm/components/skeleton.js.map +1 -1
  162. package/esm/components/skeleton.spec.d.ts +2 -0
  163. package/esm/components/skeleton.spec.d.ts.map +1 -0
  164. package/esm/components/skeleton.spec.js +159 -0
  165. package/esm/components/skeleton.spec.js.map +1 -0
  166. package/esm/components/styles.spec.d.ts +2 -0
  167. package/esm/components/styles.spec.d.ts.map +1 -0
  168. package/esm/components/styles.spec.js +56 -0
  169. package/esm/components/styles.spec.js.map +1 -0
  170. package/esm/components/suggest/index.d.ts.map +1 -1
  171. package/esm/components/suggest/index.js +74 -83
  172. package/esm/components/suggest/index.js.map +1 -1
  173. package/esm/components/suggest/index.spec.d.ts +2 -0
  174. package/esm/components/suggest/index.spec.d.ts.map +1 -0
  175. package/esm/components/suggest/index.spec.js +515 -0
  176. package/esm/components/suggest/index.spec.js.map +1 -0
  177. package/esm/components/suggest/suggest-input.d.ts.map +1 -1
  178. package/esm/components/suggest/suggest-input.js +16 -17
  179. package/esm/components/suggest/suggest-input.js.map +1 -1
  180. package/esm/components/suggest/suggest-input.spec.d.ts +2 -0
  181. package/esm/components/suggest/suggest-input.spec.d.ts.map +1 -0
  182. package/esm/components/suggest/suggest-input.spec.js +138 -0
  183. package/esm/components/suggest/suggest-input.spec.js.map +1 -0
  184. package/esm/components/suggest/suggest-manager.spec.d.ts +2 -0
  185. package/esm/components/suggest/suggest-manager.spec.d.ts.map +1 -0
  186. package/esm/components/suggest/suggest-manager.spec.js +308 -0
  187. package/esm/components/suggest/suggest-manager.spec.js.map +1 -0
  188. package/esm/components/suggest/suggestion-list.d.ts.map +1 -1
  189. package/esm/components/suggest/suggestion-list.js +43 -48
  190. package/esm/components/suggest/suggestion-list.js.map +1 -1
  191. package/esm/components/suggest/suggestion-list.spec.d.ts +2 -0
  192. package/esm/components/suggest/suggestion-list.spec.d.ts.map +1 -0
  193. package/esm/components/suggest/suggestion-list.spec.js +252 -0
  194. package/esm/components/suggest/suggestion-list.spec.js.map +1 -0
  195. package/esm/components/tabs.d.ts.map +1 -1
  196. package/esm/components/tabs.js +32 -18
  197. package/esm/components/tabs.js.map +1 -1
  198. package/esm/components/tabs.spec.d.ts +2 -0
  199. package/esm/components/tabs.spec.d.ts.map +1 -0
  200. package/esm/components/tabs.spec.js +187 -0
  201. package/esm/components/tabs.spec.js.map +1 -0
  202. package/esm/components/wizard/index.d.ts.map +1 -1
  203. package/esm/components/wizard/index.js +10 -7
  204. package/esm/components/wizard/index.js.map +1 -1
  205. package/esm/components/wizard/index.spec.d.ts +2 -0
  206. package/esm/components/wizard/index.spec.d.ts.map +1 -0
  207. package/esm/components/wizard/index.spec.js +171 -0
  208. package/esm/components/wizard/index.spec.js.map +1 -0
  209. package/esm/services/collection-service.spec.js +391 -2
  210. package/esm/services/collection-service.spec.js.map +1 -1
  211. package/esm/services/css-variable-theme.d.ts.map +1 -1
  212. package/esm/services/css-variable-theme.js +21 -1
  213. package/esm/services/css-variable-theme.js.map +1 -1
  214. package/esm/services/css-variable-theme.spec.d.ts +2 -0
  215. package/esm/services/css-variable-theme.spec.d.ts.map +1 -0
  216. package/esm/services/css-variable-theme.spec.js +169 -0
  217. package/esm/services/css-variable-theme.spec.js.map +1 -0
  218. package/esm/services/default-palette.d.ts +4 -0
  219. package/esm/services/default-palette.d.ts.map +1 -1
  220. package/esm/services/default-palette.js +22 -0
  221. package/esm/services/default-palette.js.map +1 -1
  222. package/esm/services/theme-provider-service.d.ts +59 -1
  223. package/esm/services/theme-provider-service.d.ts.map +1 -1
  224. package/esm/services/theme-provider-service.js.map +1 -1
  225. package/esm/services/theme-provider-service.spec.d.ts +2 -0
  226. package/esm/services/theme-provider-service.spec.d.ts.map +1 -0
  227. package/esm/services/theme-provider-service.spec.js +166 -0
  228. package/esm/services/theme-provider-service.spec.js.map +1 -0
  229. package/package.json +2 -2
  230. package/src/components/animations.spec.ts +299 -0
  231. package/src/components/app-bar-link.spec.tsx +341 -0
  232. package/src/components/app-bar-link.tsx +21 -21
  233. package/src/components/app-bar.spec.tsx +142 -0
  234. package/src/components/app-bar.tsx +22 -22
  235. package/src/components/avatar.spec.tsx +146 -0
  236. package/src/components/avatar.tsx +17 -20
  237. package/src/components/button.spec.tsx +193 -0
  238. package/src/components/button.tsx +162 -197
  239. package/src/components/command-palette/command-palette-input.spec.tsx +320 -0
  240. package/src/components/command-palette/command-palette-input.tsx +19 -22
  241. package/src/components/command-palette/command-palette-manager.spec.ts +470 -0
  242. package/src/components/command-palette/command-palette-suggestion-list.spec.tsx +499 -0
  243. package/src/components/command-palette/command-palette-suggestion-list.tsx +42 -46
  244. package/src/components/command-palette/index.spec.tsx +684 -0
  245. package/src/components/command-palette/index.tsx +107 -136
  246. package/src/components/data-grid/body.spec.tsx +340 -0
  247. package/src/components/data-grid/body.tsx +1 -1
  248. package/src/components/data-grid/data-grid-row.spec.tsx +382 -0
  249. package/src/components/data-grid/data-grid-row.tsx +50 -82
  250. package/src/components/data-grid/data-grid.spec.tsx +939 -0
  251. package/src/components/data-grid/data-grid.tsx +38 -35
  252. package/src/components/data-grid/footer.spec.tsx +344 -0
  253. package/src/components/data-grid/footer.tsx +19 -19
  254. package/src/components/data-grid/header.spec.tsx +563 -0
  255. package/src/components/data-grid/header.tsx +53 -44
  256. package/src/components/data-grid/selection-cell.spec.tsx +150 -0
  257. package/src/components/data-grid/selection-cell.tsx +12 -6
  258. package/src/components/fab.spec.tsx +108 -0
  259. package/src/components/fab.tsx +10 -1
  260. package/src/components/form.spec.tsx +481 -0
  261. package/src/components/grid.spec.tsx +334 -0
  262. package/src/components/grid.tsx +57 -63
  263. package/src/components/inputs/autocomplete.spec.tsx +258 -0
  264. package/src/components/inputs/input.spec.tsx +808 -0
  265. package/src/components/inputs/input.tsx +153 -139
  266. package/src/components/inputs/text-area.spec.tsx +285 -0
  267. package/src/components/inputs/text-area.tsx +53 -79
  268. package/src/components/loader.spec.tsx +346 -0
  269. package/src/components/loader.tsx +1 -1
  270. package/src/components/modal.spec.tsx +304 -0
  271. package/src/components/modal.tsx +11 -9
  272. package/src/components/noty-list.spec.tsx +631 -0
  273. package/src/components/noty-list.tsx +39 -50
  274. package/src/components/paper.spec.tsx +72 -0
  275. package/src/components/paper.tsx +15 -13
  276. package/src/components/skeleton.spec.tsx +219 -0
  277. package/src/components/skeleton.tsx +1 -1
  278. package/src/components/styles.spec.ts +70 -0
  279. package/src/components/suggest/index.spec.tsx +861 -0
  280. package/src/components/suggest/index.tsx +74 -101
  281. package/src/components/suggest/suggest-input.spec.tsx +181 -0
  282. package/src/components/suggest/suggest-input.tsx +16 -24
  283. package/src/components/suggest/suggest-manager.spec.ts +409 -0
  284. package/src/components/suggest/suggestion-list.spec.tsx +334 -0
  285. package/src/components/suggest/suggestion-list.tsx +43 -48
  286. package/src/components/tabs.spec.tsx +236 -0
  287. package/src/components/tabs.tsx +33 -21
  288. package/src/components/wizard/index.spec.tsx +224 -0
  289. package/src/components/wizard/index.tsx +10 -9
  290. package/src/services/collection-service.spec.ts +492 -3
  291. package/src/services/css-variable-theme.spec.ts +204 -0
  292. package/src/services/css-variable-theme.ts +21 -1
  293. package/src/services/default-palette.ts +22 -0
  294. package/src/services/theme-provider-service.spec.ts +195 -0
  295. package/src/services/theme-provider-service.ts +60 -2
@@ -23,6 +23,9 @@ export const OrderButton = Shade<{
23
23
  findOptions: ObservableValue<FindOptions<any, any[]>>
24
24
  }>({
25
25
  shadowDomName: 'data-grid-order-button',
26
+ css: {
27
+ display: 'inline-block',
28
+ },
26
29
  render: ({ props, useObservable }) => {
27
30
  const [findOptions, onFindOptionsChange] = useObservable('findOptions', props.findOptions, {})
28
31
 
@@ -31,11 +34,7 @@ export const OrderButton = Shade<{
31
34
  return (
32
35
  <Button
33
36
  title="Change order"
34
- style={{
35
- padding: '4px',
36
- margin: '0',
37
- cursor: 'pointer',
38
- }}
37
+ variant="outlined"
39
38
  color={currentOrder === props.field ? 'info' : undefined}
40
39
  onclick={(ev) => {
41
40
  ev.stopPropagation()
@@ -64,6 +63,9 @@ const SearchButton = Shade<{
64
63
  findOptions: ObservableValue<FindOptions<any, any[]>>
65
64
  }>({
66
65
  shadowDomName: 'data-grid-search-button',
66
+ css: {
67
+ display: 'inline-block',
68
+ },
67
69
  render: ({ props, useObservable }) => {
68
70
  const [findOptions] = useObservable('currentValue', props.findOptions, {
69
71
  filter: (newValue) => {
@@ -75,16 +77,7 @@ const SearchButton = Shade<{
75
77
  (findOptions.filter?.[props.fieldName] as FilterType<{ [K in typeof props.fieldName]: string }>)?.$regex || ''
76
78
 
77
79
  return (
78
- <Button
79
- type="button"
80
- title="Filter"
81
- style={{
82
- padding: '4px',
83
- margin: '0',
84
- cursor: 'pointer',
85
- }}
86
- onclick={props.onclick}
87
- >
80
+ <Button type="button" title="Filter" variant="outlined" onclick={props.onclick}>
88
81
  {filterValue ? '🔍' : '🔎'}
89
82
  </Button>
90
83
  )
@@ -98,6 +91,24 @@ const SearchForm = Shade<{
98
91
  findOptions: ObservableValue<FindOptions<any, any[]>>
99
92
  }>({
100
93
  shadowDomName: 'data-grid-search-form',
94
+ css: {
95
+ display: 'block',
96
+ '& .search-form': {
97
+ display: 'flex',
98
+ width: '100%',
99
+ overflow: 'hidden',
100
+ height: '0px',
101
+ justifyContent: 'space-around',
102
+ opacity: '0',
103
+ },
104
+ '& .search-form-actions': {
105
+ display: 'flex',
106
+ width: '64px',
107
+ alignItems: 'center',
108
+ justifyContent: 'center',
109
+ gap: '8px',
110
+ },
111
+ },
101
112
  render: ({ props, useObservable }) => {
102
113
  type SearchSubmitType = { searchValue: string }
103
114
 
@@ -114,14 +125,6 @@ const SearchForm = Shade<{
114
125
  return (
115
126
  <Form<SearchSubmitType>
116
127
  className="search-form"
117
- style={{
118
- display: 'flex',
119
- width: '100%',
120
- overflow: 'hide',
121
- height: '0px',
122
- justifyContent: 'space-around',
123
- opacity: '0',
124
- }}
125
128
  validate={(data): data is SearchSubmitType =>
126
129
  typeof (data as SearchSubmitType).searchValue?.length === 'number'
127
130
  }
@@ -130,7 +133,6 @@ const SearchForm = Shade<{
130
133
  }}
131
134
  >
132
135
  <Input
133
- style={{ padding: '0px', paddingBottom: '0', margin: '0' }}
134
136
  placeholder={props.fieldName}
135
137
  autofocus
136
138
  labelTitle={`${props.fieldName}`}
@@ -140,10 +142,10 @@ const SearchForm = Shade<{
140
142
  style: { padding: '0px 2em' },
141
143
  }}
142
144
  />
143
- <div style={{ display: 'flex', width: '64px', alignItems: 'center', justifyContent: 'center', gap: '8px' }}>
145
+ <div className="search-form-actions">
144
146
  <Button
145
147
  type="reset"
146
- style={{ padding: '4px', margin: '0' }}
148
+ variant="outlined"
147
149
  onclick={(ev) => {
148
150
  ev.preventDefault()
149
151
  ev.stopPropagation()
@@ -152,7 +154,7 @@ const SearchForm = Shade<{
152
154
  >
153
155
 
154
156
  </Button>
155
- <Button style={{ padding: '4px', margin: '0' }} type="submit">
157
+ <Button variant="outlined" type="submit">
156
158
  🔎
157
159
  </Button>
158
160
  </div>
@@ -167,6 +169,27 @@ export const DataGridHeader: <T, Column extends string>(
167
169
  findOptions: ObservableValue<FindOptions<T, Array<keyof T>>>,
168
170
  ) => JSX.Element<any> = Shade({
169
171
  shadowDomName: 'data-grid-header',
172
+ css: {
173
+ display: 'block',
174
+ '& .header-content': {
175
+ display: 'flex',
176
+ width: '100%',
177
+ height: '48px',
178
+ justifyContent: 'space-between',
179
+ alignItems: 'center',
180
+ gap: '12px',
181
+ overflow: 'hidden',
182
+ },
183
+ '& .header-field-name': {
184
+ fontWeight: '600',
185
+ },
186
+ '& .header-controls': {
187
+ display: 'flex',
188
+ justifyContent: 'center',
189
+ alignItems: 'center',
190
+ gap: '4px',
191
+ },
192
+ },
170
193
  render: ({ props, element, useObservable }) => {
171
194
  const [, setIsSearchOpened] = useObservable('isSearchOpened', new ObservableValue(false), {
172
195
  onChange: (newValue) => {
@@ -214,23 +237,9 @@ export const DataGridHeader: <T, Column extends string>(
214
237
  fieldName={props.field}
215
238
  findOptions={props.findOptions}
216
239
  />
217
- <div
218
- className="header-content"
219
- style={{
220
- display: 'flex',
221
- width: '100%',
222
- height: '48px',
223
- justifyContent: 'space-between',
224
- alignItems: 'center',
225
- gap: '12px',
226
- overflow: 'hide',
227
- }}
228
- >
229
- <div style={{ paddingLeft: '0', fontWeight: '600' }}>{props.field}</div>
230
- <div
231
- className="header-controls"
232
- style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', paddingRight: '0', gap: '4px' }}
233
- >
240
+ <div className="header-content">
241
+ <div className="header-field-name">{props.field}</div>
242
+ <div className="header-controls">
234
243
  <SearchButton
235
244
  onclick={() => {
236
245
  setIsSearchOpened(true)
@@ -0,0 +1,150 @@
1
+ import { Injector } from '@furystack/inject'
2
+ import { createComponent, initializeShadeRoot } from '@furystack/shades'
3
+ import { sleepAsync, usingAsync } from '@furystack/utils'
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest'
5
+ import { CollectionService } from '../../services/collection-service.js'
6
+ import { SelectionCell } from './selection-cell.js'
7
+
8
+ type TestEntry = { id: number; name: string }
9
+
10
+ describe('SelectionCell', () => {
11
+ beforeEach(() => {
12
+ document.body.innerHTML = '<div id="root"></div>'
13
+ })
14
+
15
+ afterEach(() => {
16
+ document.body.innerHTML = ''
17
+ })
18
+
19
+ const renderSelectionCell = async (entry: TestEntry, service: CollectionService<TestEntry>) => {
20
+ const injector = new Injector()
21
+ const root = document.getElementById('root')!
22
+ initializeShadeRoot({
23
+ injector,
24
+ rootElement: root,
25
+ jsxElement: <SelectionCell entry={entry} service={service} />,
26
+ })
27
+ await sleepAsync(50)
28
+ return {
29
+ injector,
30
+ cell: root.querySelector('shades-data-grid-selection-cell') as HTMLElement,
31
+ getCheckbox: () =>
32
+ root.querySelector('shades-data-grid-selection-cell')?.querySelector('input[type="checkbox"]') as
33
+ | HTMLInputElement
34
+ | undefined,
35
+ }
36
+ }
37
+
38
+ describe('rendering', () => {
39
+ it('should render a checkbox input', async () => {
40
+ await usingAsync(new CollectionService<TestEntry>(), async (service) => {
41
+ const entry = { id: 1, name: 'Test' }
42
+ const { cell, getCheckbox } = await renderSelectionCell(entry, service)
43
+
44
+ expect(cell).toBeTruthy()
45
+ expect(getCheckbox()).toBeTruthy()
46
+ expect(getCheckbox()?.type).toBe('checkbox')
47
+ })
48
+ })
49
+ })
50
+
51
+ describe('checkbox state sync', () => {
52
+ it('should be unchecked when entry is not selected', async () => {
53
+ await usingAsync(new CollectionService<TestEntry>(), async (service) => {
54
+ const entry = { id: 1, name: 'Test' }
55
+ const { getCheckbox } = await renderSelectionCell(entry, service)
56
+
57
+ expect(getCheckbox()?.checked).toBe(false)
58
+ })
59
+ })
60
+
61
+ it('should be checked when entry is in selection', async () => {
62
+ await usingAsync(new CollectionService<TestEntry>(), async (service) => {
63
+ const entry = { id: 1, name: 'Test' }
64
+ service.selection.setValue([entry])
65
+ const { getCheckbox } = await renderSelectionCell(entry, service)
66
+
67
+ expect(getCheckbox()?.checked).toBe(true)
68
+ })
69
+ })
70
+
71
+ it('should update checkbox when selection changes externally', async () => {
72
+ await usingAsync(new CollectionService<TestEntry>(), async (service) => {
73
+ const entry = { id: 1, name: 'Test' }
74
+ const { getCheckbox } = await renderSelectionCell(entry, service)
75
+
76
+ expect(getCheckbox()?.checked).toBe(false)
77
+
78
+ service.selection.setValue([entry])
79
+ await sleepAsync(50)
80
+
81
+ expect(getCheckbox()?.checked).toBe(true)
82
+
83
+ service.selection.setValue([])
84
+ await sleepAsync(50)
85
+
86
+ expect(getCheckbox()?.checked).toBe(false)
87
+ })
88
+ })
89
+
90
+ it('should remain unchecked when different entries are selected', async () => {
91
+ await usingAsync(new CollectionService<TestEntry>(), async (service) => {
92
+ const entry = { id: 1, name: 'Test' }
93
+ const otherEntry = { id: 2, name: 'Other' }
94
+ service.selection.setValue([otherEntry])
95
+ const { getCheckbox } = await renderSelectionCell(entry, service)
96
+
97
+ expect(getCheckbox()?.checked).toBe(false)
98
+ })
99
+ })
100
+ })
101
+
102
+ describe('selection toggle', () => {
103
+ it('should add entry to selection when checkbox is clicked and entry is not selected', async () => {
104
+ await usingAsync(new CollectionService<TestEntry>(), async (service) => {
105
+ const entry = { id: 1, name: 'Test' }
106
+ const { getCheckbox } = await renderSelectionCell(entry, service)
107
+
108
+ expect(service.selection.getValue()).toEqual([])
109
+
110
+ const checkbox = getCheckbox()
111
+ checkbox?.dispatchEvent(new Event('change', { bubbles: true }))
112
+ await sleepAsync(50)
113
+
114
+ expect(service.selection.getValue()).toContain(entry)
115
+ })
116
+ })
117
+
118
+ it('should remove entry from selection when checkbox is clicked and entry is selected', async () => {
119
+ await usingAsync(new CollectionService<TestEntry>(), async (service) => {
120
+ const entry = { id: 1, name: 'Test' }
121
+ service.selection.setValue([entry])
122
+ const { getCheckbox } = await renderSelectionCell(entry, service)
123
+
124
+ expect(service.selection.getValue()).toContain(entry)
125
+
126
+ const checkbox = getCheckbox()
127
+ checkbox?.dispatchEvent(new Event('change', { bubbles: true }))
128
+ await sleepAsync(50)
129
+
130
+ expect(service.selection.getValue()).not.toContain(entry)
131
+ })
132
+ })
133
+
134
+ it('should preserve other selected entries when toggling', async () => {
135
+ await usingAsync(new CollectionService<TestEntry>(), async (service) => {
136
+ const entry = { id: 1, name: 'Test' }
137
+ const otherEntry = { id: 2, name: 'Other' }
138
+ service.selection.setValue([otherEntry])
139
+ const { getCheckbox } = await renderSelectionCell(entry, service)
140
+
141
+ const checkbox = getCheckbox()
142
+ checkbox?.dispatchEvent(new Event('change', { bubbles: true }))
143
+ await sleepAsync(50)
144
+
145
+ expect(service.selection.getValue()).toContain(entry)
146
+ expect(service.selection.getValue()).toContain(otherEntry)
147
+ })
148
+ })
149
+ })
150
+ })
@@ -1,8 +1,20 @@
1
1
  import { createComponent, Shade } from '@furystack/shades'
2
2
  import type { CollectionService } from '../../services/collection-service.js'
3
+ import { cssVariableTheme } from '../../services/css-variable-theme.js'
3
4
 
4
5
  export const SelectionCell = Shade<{ entry: any; service: CollectionService<any> }>({
5
6
  shadowDomName: 'shades-data-grid-selection-cell',
7
+ css: {
8
+ display: 'inline-flex',
9
+ alignItems: 'center',
10
+ justifyContent: 'center',
11
+ '& input[type="checkbox"]': {
12
+ cursor: 'pointer',
13
+ width: '18px',
14
+ height: '18px',
15
+ accentColor: cssVariableTheme.palette.primary.main,
16
+ },
17
+ },
6
18
  render: ({ props, useObservable, element }) => {
7
19
  const [selection] = useObservable('selection', props.service.selection, {
8
20
  onChange: (newSelection) => {
@@ -18,12 +30,6 @@ export const SelectionCell = Shade<{ entry: any; service: CollectionService<any>
18
30
  }}
19
31
  type="checkbox"
20
32
  checked={isSelected}
21
- style={{
22
- cursor: 'pointer',
23
- width: '18px',
24
- height: '18px',
25
- accentColor: 'var(--shades-theme-palette-primary-main)',
26
- }}
27
33
  />
28
34
  )
29
35
  },
@@ -0,0 +1,108 @@
1
+ import { Injector } from '@furystack/inject'
2
+ import { createComponent, initializeShadeRoot } from '@furystack/shades'
3
+ import { sleepAsync } from '@furystack/utils'
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
5
+ import { Fab } from './fab.js'
6
+
7
+ describe('Fab', () => {
8
+ beforeEach(() => {
9
+ document.body.innerHTML = '<div id="root"></div>'
10
+ })
11
+
12
+ afterEach(() => {
13
+ document.body.innerHTML = ''
14
+ })
15
+
16
+ const renderFab = async (children?: JSX.Element[]) => {
17
+ const injector = new Injector()
18
+ const root = document.getElementById('root')!
19
+ initializeShadeRoot({
20
+ injector,
21
+ rootElement: root,
22
+ jsxElement: <Fab>{children}</Fab>,
23
+ })
24
+ await sleepAsync(50)
25
+ return {
26
+ injector,
27
+ fab: root.querySelector('button[is="shade-fab"]') as HTMLButtonElement,
28
+ }
29
+ }
30
+
31
+ describe('rendering', () => {
32
+ it('should render a button element', async () => {
33
+ const { fab } = await renderFab()
34
+ expect(fab).toBeTruthy()
35
+ expect(fab.tagName.toLowerCase()).toBe('button')
36
+ expect(fab.getAttribute('is')).toBe('shade-fab')
37
+ })
38
+ })
39
+
40
+ describe('positioning', () => {
41
+ it('should have fixed positioning', async () => {
42
+ const { fab } = await renderFab()
43
+ const computedStyle = window.getComputedStyle(fab)
44
+ expect(computedStyle.position).toBe('fixed')
45
+ })
46
+
47
+ it('should be positioned at bottom-right corner', async () => {
48
+ const { fab } = await renderFab()
49
+ const computedStyle = window.getComputedStyle(fab)
50
+ expect(computedStyle.bottom).toBe('32px')
51
+ expect(computedStyle.right).toBe('32px')
52
+ })
53
+ })
54
+
55
+ describe('children', () => {
56
+ it('should render text children', async () => {
57
+ const { fab } = await renderFab(['+'] as unknown as JSX.Element[])
58
+ expect(fab.textContent).toContain('+')
59
+ })
60
+
61
+ it('should render element children', async () => {
62
+ const { fab } = await renderFab([<span>🚀</span>])
63
+ expect(fab.textContent).toContain('🚀')
64
+ })
65
+ })
66
+
67
+ describe('styling', () => {
68
+ it('should have circular shape', async () => {
69
+ const { fab } = await renderFab()
70
+ const computedStyle = window.getComputedStyle(fab)
71
+ expect(computedStyle.borderRadius).toBe('50%')
72
+ })
73
+
74
+ it('should have fixed dimensions', async () => {
75
+ const { fab } = await renderFab()
76
+ const computedStyle = window.getComputedStyle(fab)
77
+ expect(computedStyle.width).toBe('64px')
78
+ expect(computedStyle.height).toBe('64px')
79
+ })
80
+
81
+ it('should center content with flexbox', async () => {
82
+ const { fab } = await renderFab()
83
+ const computedStyle = window.getComputedStyle(fab)
84
+ expect(computedStyle.display).toBe('flex')
85
+ expect(computedStyle.justifyContent).toBe('center')
86
+ expect(computedStyle.alignItems).toBe('center')
87
+ })
88
+ })
89
+
90
+ describe('button functionality', () => {
91
+ it('should trigger onclick handler when clicked', async () => {
92
+ const handleClick = vi.fn()
93
+ const injector = new Injector()
94
+ const root = document.getElementById('root')!
95
+ initializeShadeRoot({
96
+ injector,
97
+ rootElement: root,
98
+ jsxElement: <Fab onclick={handleClick}>+</Fab>,
99
+ })
100
+ await sleepAsync(50)
101
+ const fab = root.querySelector('button[is="shade-fab"]') as HTMLButtonElement
102
+
103
+ fab.click()
104
+
105
+ expect(handleClick).toHaveBeenCalledTimes(1)
106
+ })
107
+ })
108
+ })
@@ -4,7 +4,7 @@ export const Fab = Shade({
4
4
  shadowDomName: 'shade-fab',
5
5
  elementBase: HTMLButtonElement,
6
6
  elementBaseName: 'button',
7
- style: {
7
+ css: {
8
8
  position: 'fixed',
9
9
  bottom: '32px',
10
10
  right: '32px',
@@ -17,6 +17,15 @@ export const Fab = Shade({
17
17
  borderRadius: '50%',
18
18
  boxShadow: '2px 2px 4px rgba(0,0,0,0.3)',
19
19
  cursor: 'pointer',
20
+ border: 'none',
21
+ transition: 'transform 0.2s ease, box-shadow 0.2s ease',
22
+ '&:hover': {
23
+ transform: 'scale(1.05)',
24
+ boxShadow: '3px 3px 6px rgba(0,0,0,0.4)',
25
+ },
26
+ '&:active': {
27
+ transform: 'scale(0.95)',
28
+ },
20
29
  },
21
30
  render: ({ children }) => {
22
31
  return <>{children}</>