@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
@@ -1,7 +1,6 @@
1
1
  import type { PartialElement } from '@furystack/shades'
2
2
  import { createComponent, Shade } from '@furystack/shades'
3
- import { ThemeProviderService } from '../../services/theme-provider-service.js'
4
- import { promisifyAnimation } from '../../utils/promisify-animation.js'
3
+ import { cssVariableTheme } from '../../services/css-variable-theme.js'
5
4
 
6
5
  export interface TextAreaProps extends PartialElement<HTMLTextAreaElement> {
7
6
  labelTitle?: string
@@ -12,90 +11,65 @@ export interface TextAreaProps extends PartialElement<HTMLTextAreaElement> {
12
11
 
13
12
  export const TextArea = Shade<TextAreaProps>({
14
13
  shadowDomName: 'shade-text-area',
15
- render: ({ props, element, injector }) => {
16
- const themeProvider = injector.getInstance(ThemeProviderService)
17
- const { theme } = themeProvider
18
- const { palette } = theme
14
+ css: {
15
+ display: 'block',
16
+ marginBottom: '1em',
17
+ '& label': {
18
+ display: 'flex',
19
+ flexDirection: 'column',
20
+ alignItems: 'flex-start',
21
+ justifyContent: 'space-between',
22
+ fontSize: '10px',
23
+ color: '#bbb',
24
+ padding: '1em',
25
+ borderRadius: '5px',
26
+ border: 'none',
27
+ transition: 'color 0.3s cubic-bezier(0.455, 0.030, 0.515, 0.955)',
28
+ },
29
+ '&[data-variant="outlined"] label': {
30
+ border: '1px solid #bbb',
31
+ },
32
+ '&[data-disabled] label': {
33
+ color: 'rgb(170, 170, 170)',
34
+ },
35
+ '&:focus-within label': {
36
+ color: cssVariableTheme.palette.primary.main,
37
+ },
38
+ '& .textarea-content': {
39
+ border: 'none',
40
+ backgroundColor: 'transparent',
41
+ outline: 'none',
42
+ fontSize: '12px',
43
+ width: '100%',
44
+ textOverflow: 'ellipsis',
45
+ boxShadow: '0px 0px 0px rgba(128,128,128,0.1)',
46
+ transition: 'box-shadow 0.2s ease',
47
+ },
48
+ '&:focus-within .textarea-content': {
49
+ boxShadow: `0px 3px 0px ${cssVariableTheme.palette.primary.main}`,
50
+ },
51
+ },
52
+ render: ({ props, element }) => {
53
+ if (props.variant) {
54
+ element.setAttribute('data-variant', props.variant)
55
+ } else {
56
+ element.removeAttribute('data-variant')
57
+ }
58
+ if (props.disabled) {
59
+ element.setAttribute('data-disabled', '')
60
+ } else {
61
+ element.removeAttribute('data-disabled')
62
+ }
19
63
 
20
64
  return (
21
- <label
22
- {...props.labelProps}
23
- style={{
24
- display: 'flex',
25
- flexDirection: 'column',
26
- alignItems: 'flex-start',
27
- justifyContent: 'space-between',
28
- fontSize: '10px',
29
- color: props.disabled ? 'rgb(170, 170, 170)' : '#bbb',
30
- marginBottom: '1em',
31
- padding: '1em',
32
- borderRadius: '5px',
33
- border: props.variant === 'outlined' ? '1px solid #bbb' : 'none',
34
- ...props.labelProps?.style,
35
- }}
36
- >
65
+ <label {...props.labelProps} style={props.labelProps?.style}>
37
66
  <span>{props.labelTitle}</span>
38
67
 
39
68
  <div
69
+ className="textarea-content"
40
70
  contentEditable={props.readOnly === true || props.disabled === true ? 'inherit' : 'true'}
41
71
  {...props}
42
- style={{
43
- border: 'none',
44
- backgroundColor: 'transparent',
45
- outline: 'none',
46
- fontSize: '12px',
47
- width: '100%',
48
- textOverflow: 'ellipsis',
49
- ...props.style,
50
- }}
51
- onfocus={() => {
52
- if (!props.disabled) {
53
- void promisifyAnimation(
54
- element.querySelector('label'),
55
- [{ color: themeProvider.getTextColor(theme.background.default) }, { color: palette.primary.main }],
56
- {
57
- duration: 500,
58
- easing: 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',
59
- fill: 'forwards',
60
- },
61
- )
62
- void promisifyAnimation(
63
- element.querySelector('div[contenteditable="true"]'),
64
- [
65
- { boxShadow: '0px 0px 0px rgba(128,128,128,0.1)' },
66
- { boxShadow: `0px 3px 0px ${palette.primary.main}` },
67
- ],
68
- {
69
- duration: 200,
70
- fill: 'forwards',
71
- },
72
- )
73
- }
74
- }}
75
- onblur={() => {
76
- if (!props.disabled) {
77
- void promisifyAnimation(
78
- element.querySelector('label'),
79
- [{ color: palette.primary.main }, { color: themeProvider.getTextColor(theme.background.default) }],
80
- {
81
- duration: 200,
82
- easing: 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',
83
- fill: 'forwards',
84
- },
85
- )
86
- void promisifyAnimation(
87
- element.querySelector('div[contenteditable="true"]'),
88
- [
89
- { boxShadow: '0px 3px 0px rgba(128,128,128,0.4)' },
90
- { boxShadow: '0px 0px 0px rgba(128,128,128,0.1)' },
91
- ],
92
- {
93
- duration: 400,
94
- fill: 'forwards',
95
- },
96
- )
97
- }
98
- }}
72
+ style={props.style}
99
73
  >
100
74
  {props.value}
101
75
  </div>
@@ -0,0 +1,346 @@
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 { ThemeProviderService } from '../services/theme-provider-service.js'
6
+ import { Loader } from './loader.js'
7
+
8
+ describe('Loader', () => {
9
+ let originalAnimate: typeof Element.prototype.animate
10
+ let animateCalls: Array<{ keyframes: unknown; options: unknown }>
11
+
12
+ beforeEach(() => {
13
+ document.body.innerHTML = '<div id="root"></div>'
14
+ animateCalls = []
15
+ originalAnimate = Element.prototype.animate
16
+
17
+ Element.prototype.animate = vi.fn(
18
+ (keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions) => {
19
+ animateCalls.push({ keyframes, options })
20
+ const mockAnimation = {
21
+ onfinish: null as ((event: AnimationPlaybackEvent) => void) | null,
22
+ oncancel: null as ((event: AnimationPlaybackEvent) => void) | null,
23
+ cancel: vi.fn(),
24
+ play: vi.fn(),
25
+ pause: vi.fn(),
26
+ finish: vi.fn(),
27
+ addEventListener: vi.fn(),
28
+ removeEventListener: vi.fn(),
29
+ }
30
+
31
+ return mockAnimation as unknown as Animation
32
+ },
33
+ ) as typeof Element.prototype.animate
34
+ })
35
+
36
+ afterEach(() => {
37
+ document.body.innerHTML = ''
38
+ Element.prototype.animate = originalAnimate
39
+ vi.restoreAllMocks()
40
+ })
41
+
42
+ it('should render with shadow DOM', async () => {
43
+ const injector = new Injector()
44
+ const rootElement = document.getElementById('root') as HTMLDivElement
45
+
46
+ initializeShadeRoot({
47
+ injector,
48
+ rootElement,
49
+ jsxElement: <Loader />,
50
+ })
51
+
52
+ await sleepAsync(50)
53
+
54
+ const loader = document.querySelector('shade-loader')
55
+ expect(loader).not.toBeNull()
56
+ })
57
+
58
+ it('should have initial opacity of 0', async () => {
59
+ const injector = new Injector()
60
+ const rootElement = document.getElementById('root') as HTMLDivElement
61
+
62
+ initializeShadeRoot({
63
+ injector,
64
+ rootElement,
65
+ jsxElement: <Loader />,
66
+ })
67
+
68
+ await sleepAsync(50)
69
+
70
+ const loader = document.querySelector('shade-loader') as HTMLElement
71
+ expect(loader).not.toBeNull()
72
+
73
+ const computedStyle = window.getComputedStyle(loader)
74
+ expect(computedStyle.opacity).toBe('0')
75
+ })
76
+
77
+ it('should have correct css styles applied', async () => {
78
+ const injector = new Injector()
79
+ const rootElement = document.getElementById('root') as HTMLDivElement
80
+
81
+ initializeShadeRoot({
82
+ injector,
83
+ rootElement,
84
+ jsxElement: <Loader />,
85
+ })
86
+
87
+ await sleepAsync(50)
88
+
89
+ const loader = document.querySelector('shade-loader') as HTMLElement
90
+ expect(loader).not.toBeNull()
91
+
92
+ const computedStyle = window.getComputedStyle(loader)
93
+ expect(computedStyle.display).toBe('inline-block')
94
+ expect(computedStyle.transformOrigin).toBe('center')
95
+ })
96
+
97
+ it('should use default delay of 500ms', async () => {
98
+ const injector = new Injector()
99
+ const rootElement = document.getElementById('root') as HTMLDivElement
100
+
101
+ initializeShadeRoot({
102
+ injector,
103
+ rootElement,
104
+ jsxElement: <Loader />,
105
+ })
106
+
107
+ await sleepAsync(50)
108
+
109
+ const fadeInCall = animateCalls.find(
110
+ (call) => Array.isArray(call.keyframes) && call.keyframes.some((kf: Keyframe) => 'opacity' in kf),
111
+ )
112
+
113
+ expect(fadeInCall).toBeDefined()
114
+ expect((fadeInCall?.options as KeyframeAnimationOptions)?.delay).toBe(500)
115
+ })
116
+
117
+ it('should use custom delay when provided', async () => {
118
+ const injector = new Injector()
119
+ const rootElement = document.getElementById('root') as HTMLDivElement
120
+
121
+ initializeShadeRoot({
122
+ injector,
123
+ rootElement,
124
+ jsxElement: <Loader delay={200} />,
125
+ })
126
+
127
+ await sleepAsync(50)
128
+
129
+ const fadeInCall = animateCalls.find(
130
+ (call) => Array.isArray(call.keyframes) && call.keyframes.some((kf: Keyframe) => 'opacity' in kf),
131
+ )
132
+
133
+ expect(fadeInCall).toBeDefined()
134
+ expect((fadeInCall?.options as KeyframeAnimationOptions)?.delay).toBe(200)
135
+ })
136
+
137
+ it('should start fade-in animation with correct parameters', async () => {
138
+ const injector = new Injector()
139
+ const rootElement = document.getElementById('root') as HTMLDivElement
140
+
141
+ initializeShadeRoot({
142
+ injector,
143
+ rootElement,
144
+ jsxElement: <Loader delay={100} />,
145
+ })
146
+
147
+ await sleepAsync(50)
148
+
149
+ const fadeInCall = animateCalls.find(
150
+ (call) =>
151
+ Array.isArray(call.keyframes) &&
152
+ call.keyframes.length === 2 &&
153
+ (call.keyframes[0] as Keyframe).opacity === '0' &&
154
+ (call.keyframes[1] as Keyframe).opacity === '1',
155
+ )
156
+
157
+ expect(fadeInCall).toBeDefined()
158
+
159
+ const options = fadeInCall?.options as KeyframeAnimationOptions
160
+ expect(options.fill).toBe('forwards')
161
+ expect(options.duration).toBe(500)
162
+ expect(options.delay).toBe(100)
163
+ })
164
+
165
+ it('should start rotation animation', async () => {
166
+ const injector = new Injector()
167
+ const rootElement = document.getElementById('root') as HTMLDivElement
168
+
169
+ initializeShadeRoot({
170
+ injector,
171
+ rootElement,
172
+ jsxElement: <Loader />,
173
+ })
174
+
175
+ await sleepAsync(50)
176
+
177
+ const rotationCall = animateCalls.find(
178
+ (call) => Array.isArray(call.keyframes) && call.keyframes.some((kf: Keyframe) => 'transform' in kf),
179
+ )
180
+
181
+ expect(rotationCall).toBeDefined()
182
+
183
+ const options = rotationCall?.options as KeyframeAnimationOptions
184
+ expect(options.duration).toBe(1500)
185
+ expect(options.easing).toBe('ease-in-out')
186
+ expect(options.iterations).toBe(Infinity)
187
+ })
188
+
189
+ it('should have rotation keyframes from 0 to 360 degrees', async () => {
190
+ const injector = new Injector()
191
+ const rootElement = document.getElementById('root') as HTMLDivElement
192
+
193
+ initializeShadeRoot({
194
+ injector,
195
+ rootElement,
196
+ jsxElement: <Loader />,
197
+ })
198
+
199
+ await sleepAsync(50)
200
+
201
+ const rotationCall = animateCalls.find(
202
+ (call) => Array.isArray(call.keyframes) && call.keyframes.some((kf: Keyframe) => 'transform' in kf),
203
+ )
204
+
205
+ expect(rotationCall).toBeDefined()
206
+
207
+ const keyframes = rotationCall?.keyframes as Keyframe[]
208
+ expect(keyframes).toHaveLength(3)
209
+ expect(keyframes[0].transform).toBe('rotate(0deg)')
210
+ expect(keyframes[1].transform).toBe('rotate(180deg)')
211
+ expect(keyframes[2].transform).toBe('rotate(360deg)')
212
+ })
213
+
214
+ it('should use default borderWidth of 15px', async () => {
215
+ const injector = new Injector()
216
+ const rootElement = document.getElementById('root') as HTMLDivElement
217
+
218
+ initializeShadeRoot({
219
+ injector,
220
+ rootElement,
221
+ jsxElement: <Loader />,
222
+ })
223
+
224
+ await sleepAsync(50)
225
+
226
+ const loader = document.querySelector('shade-loader') as HTMLElement
227
+ expect(loader).not.toBeNull()
228
+
229
+ const innerDiv = loader.querySelector('div') as HTMLElement
230
+ expect(innerDiv).not.toBeNull()
231
+
232
+ expect(innerDiv.style.width).toBe('calc(100% - 30px)')
233
+ expect(innerDiv.style.height).toBe('calc(100% - 30px)')
234
+ expect(innerDiv.style.borderTopWidth).toBe('15px')
235
+ })
236
+
237
+ it('should use custom borderWidth when provided', async () => {
238
+ const injector = new Injector()
239
+ const rootElement = document.getElementById('root') as HTMLDivElement
240
+
241
+ initializeShadeRoot({
242
+ injector,
243
+ rootElement,
244
+ jsxElement: <Loader borderWidth={10} />,
245
+ })
246
+
247
+ await sleepAsync(50)
248
+
249
+ const loader = document.querySelector('shade-loader') as HTMLElement
250
+ expect(loader).not.toBeNull()
251
+
252
+ const innerDiv = loader.querySelector('div') as HTMLElement
253
+ expect(innerDiv).not.toBeNull()
254
+
255
+ expect(innerDiv.style.width).toBe('calc(100% - 20px)')
256
+ expect(innerDiv.style.height).toBe('calc(100% - 20px)')
257
+ expect(innerDiv.style.borderTopWidth).toBe('10px')
258
+ })
259
+
260
+ it('should use custom borderColor when provided', async () => {
261
+ const injector = new Injector()
262
+ const rootElement = document.getElementById('root') as HTMLDivElement
263
+
264
+ initializeShadeRoot({
265
+ injector,
266
+ rootElement,
267
+ jsxElement: <Loader borderColor="#ff0000" />,
268
+ })
269
+
270
+ await sleepAsync(50)
271
+
272
+ const loader = document.querySelector('shade-loader') as HTMLElement
273
+ expect(loader).not.toBeNull()
274
+
275
+ const innerDiv = loader.querySelector('div') as HTMLElement
276
+ expect(innerDiv).not.toBeNull()
277
+
278
+ expect(innerDiv.style.borderBottomColor).toBe('rgb(255, 0, 0)')
279
+ })
280
+
281
+ it('should use theme primary color as default borderColor', async () => {
282
+ const injector = new Injector()
283
+ const rootElement = document.getElementById('root') as HTMLDivElement
284
+
285
+ initializeShadeRoot({
286
+ injector,
287
+ rootElement,
288
+ jsxElement: <Loader />,
289
+ })
290
+
291
+ await sleepAsync(50)
292
+
293
+ const loader = document.querySelector('shade-loader') as HTMLElement
294
+ expect(loader).not.toBeNull()
295
+
296
+ const innerDiv = loader.querySelector('div') as HTMLElement
297
+ expect(innerDiv).not.toBeNull()
298
+
299
+ const themeService = injector.getInstance(ThemeProviderService)
300
+ expect(innerDiv.style.borderBottom).toContain(themeService.theme.palette.primary.main)
301
+ })
302
+
303
+ it('should render with circular shape', async () => {
304
+ const injector = new Injector()
305
+ const rootElement = document.getElementById('root') as HTMLDivElement
306
+
307
+ initializeShadeRoot({
308
+ injector,
309
+ rootElement,
310
+ jsxElement: <Loader />,
311
+ })
312
+
313
+ await sleepAsync(50)
314
+
315
+ const loader = document.querySelector('shade-loader') as HTMLElement
316
+ expect(loader).not.toBeNull()
317
+
318
+ const innerDiv = loader.querySelector('div') as HTMLElement
319
+ expect(innerDiv).not.toBeNull()
320
+
321
+ expect(innerDiv.style.borderRadius).toBe('50%')
322
+ expect(innerDiv.style.position).toBe('relative')
323
+ })
324
+
325
+ it('should have a semi-transparent main border and colored bottom border', async () => {
326
+ const injector = new Injector()
327
+ const rootElement = document.getElementById('root') as HTMLDivElement
328
+
329
+ initializeShadeRoot({
330
+ injector,
331
+ rootElement,
332
+ jsxElement: <Loader borderColor="#00ff00" />,
333
+ })
334
+
335
+ await sleepAsync(50)
336
+
337
+ const loader = document.querySelector('shade-loader') as HTMLElement
338
+ expect(loader).not.toBeNull()
339
+
340
+ const innerDiv = loader.querySelector('div') as HTMLElement
341
+ expect(innerDiv).not.toBeNull()
342
+
343
+ expect(innerDiv.style.borderTopColor).toBe('rgba(128, 128, 128, 0.1)')
344
+ expect(innerDiv.style.borderBottomColor).toBe('rgb(0, 255, 0)')
345
+ })
346
+ })
@@ -25,7 +25,7 @@ interface LoaderProps {
25
25
 
26
26
  export const Loader = Shade<LoaderProps>({
27
27
  shadowDomName: 'shade-loader',
28
- style: {
28
+ css: {
29
29
  display: 'inline-block',
30
30
  transformOrigin: 'center',
31
31
  opacity: '0',