@pautena/react-design-system 0.0.1

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 (409) hide show
  1. package/.eslintrc.js +26 -0
  2. package/.github/workflows/ci.yml +23 -0
  3. package/.github/workflows/deploy-storybook.yaml +23 -0
  4. package/.github/workflows/publish.yml +31 -0
  5. package/.husky/pre-commit +5 -0
  6. package/.prettierignore +4 -0
  7. package/.prettierrc.js +5 -0
  8. package/.storybook/main.js +10 -0
  9. package/.storybook/preview.js +36 -0
  10. package/README.md +7 -0
  11. package/babel.config.js +3 -0
  12. package/dist/cjs/index.js +278 -0
  13. package/dist/cjs/index.js.map +1 -0
  14. package/dist/cjs/types/components/app-bar/app-bar.d.ts +2 -0
  15. package/dist/cjs/types/components/app-bar/app-bar.types.d.ts +13 -0
  16. package/dist/cjs/types/components/app-bar/index.d.ts +3 -0
  17. package/dist/cjs/types/components/app-bar/mini-app-bar/index.d.ts +1 -0
  18. package/dist/cjs/types/components/app-bar/mini-app-bar/mini-app-bar.d.ts +2 -0
  19. package/dist/cjs/types/components/bullet/bullet.d.ts +14 -0
  20. package/dist/cjs/types/components/bullet/index.d.ts +1 -0
  21. package/dist/cjs/types/components/center-container/center-container.d.ts +9 -0
  22. package/dist/cjs/types/components/center-container/index.d.ts +1 -0
  23. package/dist/cjs/types/components/drawer/drawer.context.d.ts +9 -0
  24. package/dist/cjs/types/components/drawer/drawer.d.ts +2 -0
  25. package/dist/cjs/types/components/drawer/drawer.mixins.d.ts +4 -0
  26. package/dist/cjs/types/components/drawer/drawer.mock.d.ts +3 -0
  27. package/dist/cjs/types/components/drawer/drawer.provider.d.ts +6 -0
  28. package/dist/cjs/types/components/drawer/drawer.types.d.ts +44 -0
  29. package/dist/cjs/types/components/drawer/index.d.ts +5 -0
  30. package/dist/cjs/types/components/drawer/mini-drawer/index.d.ts +1 -0
  31. package/dist/cjs/types/components/drawer/mini-drawer/mini-drawer.d.ts +1 -0
  32. package/dist/cjs/types/components/drawer-content/drawer-content.d.ts +5 -0
  33. package/dist/cjs/types/components/drawer-content/index.d.ts +1 -0
  34. package/dist/cjs/types/components/drawer-item/drawer-item.d.ts +33 -0
  35. package/dist/cjs/types/components/drawer-item/index.d.ts +1 -0
  36. package/dist/cjs/types/components/drawer-section/drawer-section.d.ts +16 -0
  37. package/dist/cjs/types/components/drawer-section/drawer-section.mock.d.ts +2 -0
  38. package/dist/cjs/types/components/drawer-section/index.d.ts +1 -0
  39. package/dist/cjs/types/components/header/header.d.ts +65 -0
  40. package/dist/cjs/types/components/header/header.dummy.d.ts +4 -0
  41. package/dist/cjs/types/components/header/index.d.ts +1 -0
  42. package/dist/cjs/types/components/index.d.ts +17 -0
  43. package/dist/cjs/types/components/label/index.d.ts +1 -0
  44. package/dist/cjs/types/components/label/label.d.ts +18 -0
  45. package/dist/cjs/types/components/link/index.d.ts +1 -0
  46. package/dist/cjs/types/components/link/link.d.ts +7 -0
  47. package/dist/cjs/types/components/loading-area/index.d.ts +1 -0
  48. package/dist/cjs/types/components/loading-area/loading-area.d.ts +4 -0
  49. package/dist/cjs/types/components/placeholder/index.d.ts +1 -0
  50. package/dist/cjs/types/components/placeholder/placeholder.d.ts +21 -0
  51. package/dist/cjs/types/components/placeholder/placeholder.mock.d.ts +2 -0
  52. package/dist/cjs/types/components/query-container/index.d.ts +1 -0
  53. package/dist/cjs/types/components/query-container/query-container.d.ts +39 -0
  54. package/dist/cjs/types/components/sign-in/index.d.ts +1 -0
  55. package/dist/cjs/types/components/sign-in/sign-in.d.ts +9 -0
  56. package/dist/cjs/types/components/tab/index.d.ts +3 -0
  57. package/dist/cjs/types/components/tab/tab-card/index.d.ts +1 -0
  58. package/dist/cjs/types/components/tab/tab-card/tab-card.d.ts +7 -0
  59. package/dist/cjs/types/components/tab/tab-card/tab-card.dummy.d.ts +7 -0
  60. package/dist/cjs/types/components/tab/tab-panel/index.d.ts +1 -0
  61. package/dist/cjs/types/components/tab/tab-panel/tab-panel.d.ts +7 -0
  62. package/dist/cjs/types/components/tab/tab.context.d.ts +4 -0
  63. package/dist/cjs/types/components/table/enhanced-remote-table/enhanced-remote-table.d.ts +13 -0
  64. package/dist/cjs/types/components/table/enhanced-remote-table/enhanced-remote-table.mock.d.ts +11 -0
  65. package/dist/cjs/types/components/table/enhanced-remote-table/index.d.ts +1 -0
  66. package/dist/cjs/types/components/table/enhanced-table/enhanced-table-head.d.ts +16 -0
  67. package/dist/cjs/types/components/table/enhanced-table/enhanced-table.d.ts +18 -0
  68. package/dist/cjs/types/components/table/enhanced-table/enhanced-table.mock.d.ts +17 -0
  69. package/dist/cjs/types/components/table/enhanced-table/index.d.ts +2 -0
  70. package/dist/cjs/types/components/table/index.d.ts +2 -0
  71. package/dist/cjs/types/components/table-list/index.d.ts +1 -0
  72. package/dist/cjs/types/components/table-list/table-list.d.ts +21 -0
  73. package/dist/cjs/types/components/value-displays/group-value-card/group-value-card.d.ts +15 -0
  74. package/dist/cjs/types/components/value-displays/group-value-card/group-value-card.mock.d.ts +1 -0
  75. package/dist/cjs/types/components/value-displays/group-value-card/index.d.ts +1 -0
  76. package/dist/cjs/types/components/value-displays/index.d.ts +4 -0
  77. package/dist/cjs/types/components/value-displays/value-boolean/index.d.ts +1 -0
  78. package/dist/cjs/types/components/value-displays/value-boolean/value-boolean.d.ts +14 -0
  79. package/dist/cjs/types/components/value-displays/value-card/index.d.ts +1 -0
  80. package/dist/cjs/types/components/value-displays/value-card/value-card.d.ts +6 -0
  81. package/dist/cjs/types/components/value-displays/value-text/index.d.ts +1 -0
  82. package/dist/cjs/types/components/value-displays/value-text/value-text.d.ts +14 -0
  83. package/dist/cjs/types/generators/generators.mock.d.ts +3 -0
  84. package/dist/cjs/types/generators/generators.model.d.ts +33 -0
  85. package/dist/cjs/types/generators/index.d.ts +4 -0
  86. package/dist/cjs/types/generators/model-form/index.d.ts +1 -0
  87. package/dist/cjs/types/generators/model-form/model-form.d.ts +8 -0
  88. package/dist/cjs/types/generators/model-router/index.d.ts +1 -0
  89. package/dist/cjs/types/generators/model-router/model-router.d.ts +35 -0
  90. package/dist/cjs/types/generators/model-router/screens/add-screen.d.ts +2 -0
  91. package/dist/cjs/types/generators/model-router/screens/details-screen.d.ts +2 -0
  92. package/dist/cjs/types/generators/model-router/screens/index.d.ts +4 -0
  93. package/dist/cjs/types/generators/model-router/screens/list-screen.d.ts +2 -0
  94. package/dist/cjs/types/generators/model-router/screens/update-screen.d.ts +2 -0
  95. package/dist/cjs/types/generators/object-details/index.d.ts +1 -0
  96. package/dist/cjs/types/generators/object-details/object-details.d.ts +6 -0
  97. package/dist/cjs/types/index.d.ts +4 -0
  98. package/dist/cjs/types/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.d.ts +10 -0
  99. package/dist/cjs/types/layouts/app-bar-with-drawer-layout/index.d.ts +1 -0
  100. package/dist/cjs/types/layouts/data-table-layout/data-table-layout.d.ts +12 -0
  101. package/dist/cjs/types/layouts/data-table-layout/index.d.ts +1 -0
  102. package/dist/cjs/types/layouts/details-layout/details-layout.d.ts +12 -0
  103. package/dist/cjs/types/layouts/details-layout/index.d.ts +1 -0
  104. package/dist/cjs/types/layouts/form-layout/form-layout.d.ts +8 -0
  105. package/dist/cjs/types/layouts/form-layout/index.d.ts +1 -0
  106. package/dist/cjs/types/layouts/header-layout/header-layout.d.ts +8 -0
  107. package/dist/cjs/types/layouts/header-layout/index.d.ts +1 -0
  108. package/dist/cjs/types/layouts/index.d.ts +7 -0
  109. package/dist/cjs/types/layouts/list-layout/index.d.ts +1 -0
  110. package/dist/cjs/types/layouts/list-layout/list-layout.d.ts +8 -0
  111. package/dist/cjs/types/layouts/tab-layout/index.d.ts +1 -0
  112. package/dist/cjs/types/layouts/tab-layout/tab-layout.d.ts +7 -0
  113. package/dist/cjs/types/providers/index.d.ts +1 -0
  114. package/dist/cjs/types/providers/notification-center/index.d.ts +1 -0
  115. package/dist/cjs/types/providers/notification-center/notification-center.context.d.ts +16 -0
  116. package/dist/cjs/types/providers/notification-center/notification-center.provider.d.ts +5 -0
  117. package/dist/cjs/types/utils/arrays.d.ts +5 -0
  118. package/dist/cjs/types/utils/arrays.test.d.ts +1 -0
  119. package/dist/cjs/types/utils/index.d.ts +2 -0
  120. package/dist/cjs/types/utils/theme.d.ts +4 -0
  121. package/dist/esm/index.js +278 -0
  122. package/dist/esm/index.js.map +1 -0
  123. package/dist/esm/types/components/app-bar/app-bar.d.ts +2 -0
  124. package/dist/esm/types/components/app-bar/app-bar.types.d.ts +13 -0
  125. package/dist/esm/types/components/app-bar/index.d.ts +3 -0
  126. package/dist/esm/types/components/app-bar/mini-app-bar/index.d.ts +1 -0
  127. package/dist/esm/types/components/app-bar/mini-app-bar/mini-app-bar.d.ts +2 -0
  128. package/dist/esm/types/components/bullet/bullet.d.ts +14 -0
  129. package/dist/esm/types/components/bullet/index.d.ts +1 -0
  130. package/dist/esm/types/components/center-container/center-container.d.ts +9 -0
  131. package/dist/esm/types/components/center-container/index.d.ts +1 -0
  132. package/dist/esm/types/components/drawer/drawer.context.d.ts +9 -0
  133. package/dist/esm/types/components/drawer/drawer.d.ts +2 -0
  134. package/dist/esm/types/components/drawer/drawer.mixins.d.ts +4 -0
  135. package/dist/esm/types/components/drawer/drawer.mock.d.ts +3 -0
  136. package/dist/esm/types/components/drawer/drawer.provider.d.ts +6 -0
  137. package/dist/esm/types/components/drawer/drawer.types.d.ts +44 -0
  138. package/dist/esm/types/components/drawer/index.d.ts +5 -0
  139. package/dist/esm/types/components/drawer/mini-drawer/index.d.ts +1 -0
  140. package/dist/esm/types/components/drawer/mini-drawer/mini-drawer.d.ts +1 -0
  141. package/dist/esm/types/components/drawer-content/drawer-content.d.ts +5 -0
  142. package/dist/esm/types/components/drawer-content/index.d.ts +1 -0
  143. package/dist/esm/types/components/drawer-item/drawer-item.d.ts +33 -0
  144. package/dist/esm/types/components/drawer-item/index.d.ts +1 -0
  145. package/dist/esm/types/components/drawer-section/drawer-section.d.ts +16 -0
  146. package/dist/esm/types/components/drawer-section/drawer-section.mock.d.ts +2 -0
  147. package/dist/esm/types/components/drawer-section/index.d.ts +1 -0
  148. package/dist/esm/types/components/header/header.d.ts +65 -0
  149. package/dist/esm/types/components/header/header.dummy.d.ts +4 -0
  150. package/dist/esm/types/components/header/index.d.ts +1 -0
  151. package/dist/esm/types/components/index.d.ts +17 -0
  152. package/dist/esm/types/components/label/index.d.ts +1 -0
  153. package/dist/esm/types/components/label/label.d.ts +18 -0
  154. package/dist/esm/types/components/link/index.d.ts +1 -0
  155. package/dist/esm/types/components/link/link.d.ts +7 -0
  156. package/dist/esm/types/components/loading-area/index.d.ts +1 -0
  157. package/dist/esm/types/components/loading-area/loading-area.d.ts +4 -0
  158. package/dist/esm/types/components/placeholder/index.d.ts +1 -0
  159. package/dist/esm/types/components/placeholder/placeholder.d.ts +21 -0
  160. package/dist/esm/types/components/placeholder/placeholder.mock.d.ts +2 -0
  161. package/dist/esm/types/components/query-container/index.d.ts +1 -0
  162. package/dist/esm/types/components/query-container/query-container.d.ts +39 -0
  163. package/dist/esm/types/components/sign-in/index.d.ts +1 -0
  164. package/dist/esm/types/components/sign-in/sign-in.d.ts +9 -0
  165. package/dist/esm/types/components/tab/index.d.ts +3 -0
  166. package/dist/esm/types/components/tab/tab-card/index.d.ts +1 -0
  167. package/dist/esm/types/components/tab/tab-card/tab-card.d.ts +7 -0
  168. package/dist/esm/types/components/tab/tab-card/tab-card.dummy.d.ts +7 -0
  169. package/dist/esm/types/components/tab/tab-panel/index.d.ts +1 -0
  170. package/dist/esm/types/components/tab/tab-panel/tab-panel.d.ts +7 -0
  171. package/dist/esm/types/components/tab/tab.context.d.ts +4 -0
  172. package/dist/esm/types/components/table/enhanced-remote-table/enhanced-remote-table.d.ts +13 -0
  173. package/dist/esm/types/components/table/enhanced-remote-table/enhanced-remote-table.mock.d.ts +11 -0
  174. package/dist/esm/types/components/table/enhanced-remote-table/index.d.ts +1 -0
  175. package/dist/esm/types/components/table/enhanced-table/enhanced-table-head.d.ts +16 -0
  176. package/dist/esm/types/components/table/enhanced-table/enhanced-table.d.ts +18 -0
  177. package/dist/esm/types/components/table/enhanced-table/enhanced-table.mock.d.ts +17 -0
  178. package/dist/esm/types/components/table/enhanced-table/index.d.ts +2 -0
  179. package/dist/esm/types/components/table/index.d.ts +2 -0
  180. package/dist/esm/types/components/table-list/index.d.ts +1 -0
  181. package/dist/esm/types/components/table-list/table-list.d.ts +21 -0
  182. package/dist/esm/types/components/value-displays/group-value-card/group-value-card.d.ts +15 -0
  183. package/dist/esm/types/components/value-displays/group-value-card/group-value-card.mock.d.ts +1 -0
  184. package/dist/esm/types/components/value-displays/group-value-card/index.d.ts +1 -0
  185. package/dist/esm/types/components/value-displays/index.d.ts +4 -0
  186. package/dist/esm/types/components/value-displays/value-boolean/index.d.ts +1 -0
  187. package/dist/esm/types/components/value-displays/value-boolean/value-boolean.d.ts +14 -0
  188. package/dist/esm/types/components/value-displays/value-card/index.d.ts +1 -0
  189. package/dist/esm/types/components/value-displays/value-card/value-card.d.ts +6 -0
  190. package/dist/esm/types/components/value-displays/value-text/index.d.ts +1 -0
  191. package/dist/esm/types/components/value-displays/value-text/value-text.d.ts +14 -0
  192. package/dist/esm/types/generators/generators.mock.d.ts +3 -0
  193. package/dist/esm/types/generators/generators.model.d.ts +33 -0
  194. package/dist/esm/types/generators/index.d.ts +4 -0
  195. package/dist/esm/types/generators/model-form/index.d.ts +1 -0
  196. package/dist/esm/types/generators/model-form/model-form.d.ts +8 -0
  197. package/dist/esm/types/generators/model-router/index.d.ts +1 -0
  198. package/dist/esm/types/generators/model-router/model-router.d.ts +35 -0
  199. package/dist/esm/types/generators/model-router/screens/add-screen.d.ts +2 -0
  200. package/dist/esm/types/generators/model-router/screens/details-screen.d.ts +2 -0
  201. package/dist/esm/types/generators/model-router/screens/index.d.ts +4 -0
  202. package/dist/esm/types/generators/model-router/screens/list-screen.d.ts +2 -0
  203. package/dist/esm/types/generators/model-router/screens/update-screen.d.ts +2 -0
  204. package/dist/esm/types/generators/object-details/index.d.ts +1 -0
  205. package/dist/esm/types/generators/object-details/object-details.d.ts +6 -0
  206. package/dist/esm/types/index.d.ts +4 -0
  207. package/dist/esm/types/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.d.ts +10 -0
  208. package/dist/esm/types/layouts/app-bar-with-drawer-layout/index.d.ts +1 -0
  209. package/dist/esm/types/layouts/data-table-layout/data-table-layout.d.ts +12 -0
  210. package/dist/esm/types/layouts/data-table-layout/index.d.ts +1 -0
  211. package/dist/esm/types/layouts/details-layout/details-layout.d.ts +12 -0
  212. package/dist/esm/types/layouts/details-layout/index.d.ts +1 -0
  213. package/dist/esm/types/layouts/form-layout/form-layout.d.ts +8 -0
  214. package/dist/esm/types/layouts/form-layout/index.d.ts +1 -0
  215. package/dist/esm/types/layouts/header-layout/header-layout.d.ts +8 -0
  216. package/dist/esm/types/layouts/header-layout/index.d.ts +1 -0
  217. package/dist/esm/types/layouts/index.d.ts +7 -0
  218. package/dist/esm/types/layouts/list-layout/index.d.ts +1 -0
  219. package/dist/esm/types/layouts/list-layout/list-layout.d.ts +8 -0
  220. package/dist/esm/types/layouts/tab-layout/index.d.ts +1 -0
  221. package/dist/esm/types/layouts/tab-layout/tab-layout.d.ts +7 -0
  222. package/dist/esm/types/providers/index.d.ts +1 -0
  223. package/dist/esm/types/providers/notification-center/index.d.ts +1 -0
  224. package/dist/esm/types/providers/notification-center/notification-center.context.d.ts +16 -0
  225. package/dist/esm/types/providers/notification-center/notification-center.provider.d.ts +5 -0
  226. package/dist/esm/types/utils/arrays.d.ts +5 -0
  227. package/dist/esm/types/utils/arrays.test.d.ts +1 -0
  228. package/dist/esm/types/utils/index.d.ts +2 -0
  229. package/dist/esm/types/utils/theme.d.ts +4 -0
  230. package/dist/index.d.ts +594 -0
  231. package/jest.config.js +14 -0
  232. package/jest.setup.ts +5 -0
  233. package/package.json +98 -0
  234. package/rollup.config.js +40 -0
  235. package/src/components/app-bar/app-bar.stories.tsx +54 -0
  236. package/src/components/app-bar/app-bar.test.tsx +142 -0
  237. package/src/components/app-bar/app-bar.tsx +150 -0
  238. package/src/components/app-bar/app-bar.types.ts +16 -0
  239. package/src/components/app-bar/index.ts +3 -0
  240. package/src/components/app-bar/mini-app-bar/index.ts +1 -0
  241. package/src/components/app-bar/mini-app-bar/mini-app-bar.tsx +31 -0
  242. package/src/components/bullet/bullet.stories.tsx +43 -0
  243. package/src/components/bullet/bullet.test.tsx +24 -0
  244. package/src/components/bullet/bullet.tsx +30 -0
  245. package/src/components/bullet/index.ts +1 -0
  246. package/src/components/center-container/center-container.stories.tsx +50 -0
  247. package/src/components/center-container/center-container.test.tsx +16 -0
  248. package/src/components/center-container/center-container.tsx +32 -0
  249. package/src/components/center-container/index.ts +1 -0
  250. package/src/components/drawer/__snapshots__/drawer.test.tsx.snap +20 -0
  251. package/src/components/drawer/drawer.context.ts +20 -0
  252. package/src/components/drawer/drawer.mixins.ts +24 -0
  253. package/src/components/drawer/drawer.mock.tsx +100 -0
  254. package/src/components/drawer/drawer.provider.tsx +23 -0
  255. package/src/components/drawer/drawer.test.tsx +97 -0
  256. package/src/components/drawer/drawer.tsx +30 -0
  257. package/src/components/drawer/drawer.types.ts +53 -0
  258. package/src/components/drawer/index.ts +5 -0
  259. package/src/components/drawer/mini-drawer/index.ts +1 -0
  260. package/src/components/drawer/mini-drawer/mini-drawer.stories.tsx +34 -0
  261. package/src/components/drawer/mini-drawer/mini-drawer.tsx +67 -0
  262. package/src/components/drawer-content/drawer-content.stories.tsx +29 -0
  263. package/src/components/drawer-content/drawer-content.test.tsx +34 -0
  264. package/src/components/drawer-content/drawer-content.tsx +18 -0
  265. package/src/components/drawer-content/index.ts +1 -0
  266. package/src/components/drawer-item/drawer-item.stories.tsx +62 -0
  267. package/src/components/drawer-item/drawer-item.test.tsx +119 -0
  268. package/src/components/drawer-item/drawer-item.tsx +69 -0
  269. package/src/components/drawer-item/index.ts +1 -0
  270. package/src/components/drawer-section/drawer-section.mock.tsx +39 -0
  271. package/src/components/drawer-section/drawer-section.stories.tsx +28 -0
  272. package/src/components/drawer-section/drawer-section.test.tsx +44 -0
  273. package/src/components/drawer-section/drawer-section.tsx +40 -0
  274. package/src/components/drawer-section/index.ts +1 -0
  275. package/src/components/header/header.dummy.ts +55 -0
  276. package/src/components/header/header.stories.tsx +116 -0
  277. package/src/components/header/header.test.tsx +167 -0
  278. package/src/components/header/header.tsx +185 -0
  279. package/src/components/header/index.ts +1 -0
  280. package/src/components/index.ts +17 -0
  281. package/src/components/label/index.ts +1 -0
  282. package/src/components/label/label.stories.tsx +49 -0
  283. package/src/components/label/label.test.tsx +30 -0
  284. package/src/components/label/label.tsx +60 -0
  285. package/src/components/link/index.ts +1 -0
  286. package/src/components/link/link.tsx +17 -0
  287. package/src/components/loading-area/index.ts +1 -0
  288. package/src/components/loading-area/loading-area.stories.tsx +17 -0
  289. package/src/components/loading-area/loading-area.test.tsx +11 -0
  290. package/src/components/loading-area/loading-area.tsx +13 -0
  291. package/src/components/placeholder/index.ts +1 -0
  292. package/src/components/placeholder/placeholder.mock.ts +15 -0
  293. package/src/components/placeholder/placeholder.stories.tsx +44 -0
  294. package/src/components/placeholder/placeholder.test.tsx +76 -0
  295. package/src/components/placeholder/placeholder.tsx +75 -0
  296. package/src/components/query-container/index.ts +1 -0
  297. package/src/components/query-container/query-container.stories.tsx +68 -0
  298. package/src/components/query-container/query-container.test.tsx +95 -0
  299. package/src/components/query-container/query-container.tsx +71 -0
  300. package/src/components/sign-in/index.ts +1 -0
  301. package/src/components/sign-in/sign-in.stories.tsx +36 -0
  302. package/src/components/sign-in/sign-in.test.tsx +95 -0
  303. package/src/components/sign-in/sign-in.tsx +97 -0
  304. package/src/components/tab/index.ts +3 -0
  305. package/src/components/tab/tab-card/index.ts +1 -0
  306. package/src/components/tab/tab-card/tab-card.dummy.tsx +27 -0
  307. package/src/components/tab/tab-card/tab-card.stories.tsx +22 -0
  308. package/src/components/tab/tab-card/tab-card.test.tsx +53 -0
  309. package/src/components/tab/tab-card/tab-card.tsx +30 -0
  310. package/src/components/tab/tab-panel/index.ts +1 -0
  311. package/src/components/tab/tab-panel/tab-panel.test.tsx +26 -0
  312. package/src/components/tab/tab-panel/tab-panel.tsx +27 -0
  313. package/src/components/tab/tab.context.ts +5 -0
  314. package/src/components/table/enhanced-remote-table/enhanced-remote-table.mock.tsx +27 -0
  315. package/src/components/table/enhanced-remote-table/enhanced-remote-table.stories.tsx +24 -0
  316. package/src/components/table/enhanced-remote-table/enhanced-remote-table.test.tsx +77 -0
  317. package/src/components/table/enhanced-remote-table/enhanced-remote-table.tsx +74 -0
  318. package/src/components/table/enhanced-remote-table/index.ts +1 -0
  319. package/src/components/table/enhanced-table/enhanced-table-head.tsx +58 -0
  320. package/src/components/table/enhanced-table/enhanced-table.mock.tsx +93 -0
  321. package/src/components/table/enhanced-table/enhanced-table.stories.tsx +21 -0
  322. package/src/components/table/enhanced-table/enhanced-table.test.tsx +107 -0
  323. package/src/components/table/enhanced-table/enhanced-table.tsx +136 -0
  324. package/src/components/table/enhanced-table/index.ts +2 -0
  325. package/src/components/table/index.ts +2 -0
  326. package/src/components/table-list/index.ts +1 -0
  327. package/src/components/table-list/table-list.stories.tsx +75 -0
  328. package/src/components/table-list/table-list.test.tsx +283 -0
  329. package/src/components/table-list/table-list.tsx +131 -0
  330. package/src/components/value-displays/group-value-card/group-value-card.mock.tsx +35 -0
  331. package/src/components/value-displays/group-value-card/group-value-card.stories.tsx +26 -0
  332. package/src/components/value-displays/group-value-card/group-value-card.test.tsx +58 -0
  333. package/src/components/value-displays/group-value-card/group-value-card.tsx +65 -0
  334. package/src/components/value-displays/group-value-card/index.ts +1 -0
  335. package/src/components/value-displays/index.ts +4 -0
  336. package/src/components/value-displays/value-boolean/index.ts +1 -0
  337. package/src/components/value-displays/value-boolean/value-boolean.stories.tsx +25 -0
  338. package/src/components/value-displays/value-boolean/value-boolean.test.tsx +27 -0
  339. package/src/components/value-displays/value-boolean/value-boolean.tsx +33 -0
  340. package/src/components/value-displays/value-card/index.ts +1 -0
  341. package/src/components/value-displays/value-card/value-card.stories.tsx +22 -0
  342. package/src/components/value-displays/value-card/value-card.test.tsx +18 -0
  343. package/src/components/value-displays/value-card/value-card.tsx +12 -0
  344. package/src/components/value-displays/value-text/index.ts +1 -0
  345. package/src/components/value-displays/value-text/value-test.test.tsx +21 -0
  346. package/src/components/value-displays/value-text/value-text.stories.tsx +26 -0
  347. package/src/components/value-displays/value-text/value-text.tsx +32 -0
  348. package/src/generators/generators.mock.ts +215 -0
  349. package/src/generators/generators.model.ts +41 -0
  350. package/src/generators/index.ts +4 -0
  351. package/src/generators/model-form/index.ts +1 -0
  352. package/src/generators/model-form/model-form.stories.tsx +30 -0
  353. package/src/generators/model-form/model-form.test.tsx +98 -0
  354. package/src/generators/model-form/model-form.tsx +97 -0
  355. package/src/generators/model-router/index.ts +1 -0
  356. package/src/generators/model-router/model-router.stories.tsx +160 -0
  357. package/src/generators/model-router/model-router.test.tsx +633 -0
  358. package/src/generators/model-router/model-router.tsx +54 -0
  359. package/src/generators/model-router/screens/add-screen.tsx +52 -0
  360. package/src/generators/model-router/screens/details-screen.tsx +53 -0
  361. package/src/generators/model-router/screens/index.ts +4 -0
  362. package/src/generators/model-router/screens/list-screen.tsx +81 -0
  363. package/src/generators/model-router/screens/update-screen.tsx +62 -0
  364. package/src/generators/object-details/index.ts +1 -0
  365. package/src/generators/object-details/object-details.stories.tsx +20 -0
  366. package/src/generators/object-details/object-details.test.tsx +21 -0
  367. package/src/generators/object-details/object-details.tsx +70 -0
  368. package/src/index.ts +4 -0
  369. package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.stories.tsx +29 -0
  370. package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.tsx +34 -0
  371. package/src/layouts/app-bar-with-drawer-layout/index.ts +1 -0
  372. package/src/layouts/data-table-layout/data-table-layout.stories.tsx +94 -0
  373. package/src/layouts/data-table-layout/data-table-layout.tsx +30 -0
  374. package/src/layouts/data-table-layout/index.ts +1 -0
  375. package/src/layouts/details-layout/details-layout.stories.tsx +81 -0
  376. package/src/layouts/details-layout/details-layout.tsx +33 -0
  377. package/src/layouts/details-layout/index.ts +1 -0
  378. package/src/layouts/form-layout/form-layout.stories.tsx +65 -0
  379. package/src/layouts/form-layout/form-layout.tsx +18 -0
  380. package/src/layouts/form-layout/index.ts +1 -0
  381. package/src/layouts/header-layout/header-layout.stories.tsx +68 -0
  382. package/src/layouts/header-layout/header-layout.tsx +24 -0
  383. package/src/layouts/header-layout/index.ts +1 -0
  384. package/src/layouts/index.ts +7 -0
  385. package/src/layouts/list-layout/index.ts +1 -0
  386. package/src/layouts/list-layout/list-layout.stories.tsx +102 -0
  387. package/src/layouts/list-layout/list-layout.tsx +36 -0
  388. package/src/layouts/tab-layout/index.ts +1 -0
  389. package/src/layouts/tab-layout/tab-layout.stories.tsx +88 -0
  390. package/src/layouts/tab-layout/tab-layout.tsx +11 -0
  391. package/src/providers/index.ts +1 -0
  392. package/src/providers/notification-center/index.ts +1 -0
  393. package/src/providers/notification-center/notification-center.context.ts +37 -0
  394. package/src/providers/notification-center/notification-center.provider.tsx +51 -0
  395. package/src/providers/notification-center/notification-center.stories.tsx +52 -0
  396. package/src/providers/notification-center/notification-center.test.tsx +112 -0
  397. package/src/storybook.tsx +56 -0
  398. package/src/tests/assertions.ts +72 -0
  399. package/src/tests/components.tsx +60 -0
  400. package/src/tests/content-placeholder.stories.tsx +16 -0
  401. package/src/tests/index.ts +3 -0
  402. package/src/tests/skeleton-card.stories.tsx +18 -0
  403. package/src/tests/testing-library.tsx +65 -0
  404. package/src/utils/arrays.test.ts +9 -0
  405. package/src/utils/arrays.ts +7 -0
  406. package/src/utils/index.ts +2 -0
  407. package/src/utils/theme.ts +6 -0
  408. package/tsconfig.json +27 -0
  409. package/tsconfig.rollup.json +26 -0
@@ -0,0 +1,633 @@
1
+ import React from "react";
2
+ import { DummyModelRouter } from "./model-router.stories";
3
+ import {
4
+ expectModelFieldInputExist,
5
+ expectProgressIndicator,
6
+ waitForProgressIndicatorToBeRemoved,
7
+ render,
8
+ screen,
9
+ TestRouter,
10
+ expectModelFieldValue,
11
+ expectModelFieldInputValue,
12
+ } from "../../tests";
13
+ import userEvent from "@testing-library/user-event";
14
+ import { getRandomItem } from "../../utils";
15
+ import { Model } from "../generators.model";
16
+ import { createModelInstance } from "../generators.mock";
17
+
18
+ const REQUEST_TIMEOUT = 20;
19
+
20
+ describe("ModelRouter", () => {
21
+ const assertions = {
22
+ expectListScreen: async () =>
23
+ await screen.findByRole("heading", {
24
+ name: "Items",
25
+ level: 1,
26
+ }),
27
+ expectAddScreen: async () =>
28
+ await screen.findByRole("heading", {
29
+ name: "Add Items",
30
+ level: 1,
31
+ }),
32
+ expectDetailScreen: async ({ id }: { id: string }) =>
33
+ await screen.findByRole("heading", {
34
+ name: id,
35
+ level: 1,
36
+ }),
37
+ expectUpdateScreen: async ({ id }: { id: string }) =>
38
+ await screen.findByRole("heading", {
39
+ name: `Edit ${id}`,
40
+ level: 1,
41
+ }),
42
+ expectListItems: async ({ data, model }: { data: any[]; model: Model }) => {
43
+ for (let i = 0; i < model.fields.length; ++i) {
44
+ const { id, listable } = model.fields[i];
45
+
46
+ if (listable) {
47
+ expect(await screen.findAllByRole("cell", { name: data[id] })).toBeTruthy();
48
+ }
49
+ }
50
+ },
51
+ expectMenuOption: async ({ id }: { id: number }) => {
52
+ await screen.findByTestId(`options-${id}`);
53
+ },
54
+ expectSubmitInstanceCall: (mockFn: jest.Mock, instance: any) => {
55
+ expect(mockFn).toHaveBeenCalledTimes(1);
56
+ expect(mockFn).toHaveBeenCalledWith({
57
+ id: instance.id,
58
+ firstName: instance.firstName,
59
+ middleName: instance.middleName,
60
+ lastName: instance.lastName,
61
+ gender: instance.gender,
62
+ age: instance.age.toString(),
63
+ birthDate: instance.birthDate,
64
+ car: {
65
+ model: instance.car.model,
66
+ manufacturer: instance.car.manufacturer,
67
+ color: instance.car.color,
68
+ type: instance.car.type,
69
+ vin: instance.car.vin,
70
+ vrm: instance.car.vrm,
71
+ },
72
+ quantity: instance.quantity.toString(),
73
+ available: instance.available.toString(),
74
+ currency: instance.currency,
75
+ tradeDate: instance.tradeDate,
76
+ });
77
+ },
78
+ };
79
+
80
+ const actions = {
81
+ navigateToAddScreen: async () => {
82
+ await userEvent.click(screen.getByRole("button", { name: /add/i }));
83
+ },
84
+ navigateToUpdateScreen: async ({ id }: { id: number }) => {
85
+ await actions.openItemOptions({ id });
86
+ await userEvent.click(screen.getByRole("menuitem", { name: /edit/i }));
87
+ },
88
+ navigateToDetailScreen: async ({ name }: { name: string }) => {
89
+ await userEvent.click(await screen.findByRole("cell", { name }));
90
+ },
91
+ openItemOptions: async ({ id }: { id: number }) => {
92
+ await userEvent.click(await screen.findByTestId(`options-${id}`));
93
+ },
94
+ fullfillModelForm: async ({
95
+ model,
96
+ submit,
97
+ clear,
98
+ }: {
99
+ model: Model;
100
+ submit?: boolean;
101
+ clear?: boolean;
102
+ }) => {
103
+ const instance = createModelInstance(model);
104
+
105
+ const idElement = screen.getByRole("textbox", { name: "Id" });
106
+ const firstNameElement = screen.getByRole("textbox", { name: /first name/i });
107
+ const middleNameElement = screen.getByRole("textbox", { name: /middle name/i });
108
+ const lastNameElement = screen.getByRole("textbox", { name: /last name/i });
109
+ const genderElement = screen.getByRole("textbox", { name: /gender/i });
110
+ const ageElement = screen.getByRole("spinbutton", { name: /age/i });
111
+ const birthDateElement = screen.getByRole("textbox", { name: /birth date/i });
112
+ const manufacturerElement = screen.getByRole("textbox", { name: /manufacturer/i });
113
+ const modelElement = screen.getByRole("textbox", { name: /model/i });
114
+ const colorElement = screen.getByRole("textbox", { name: /color/i });
115
+ const typeElement = screen.getByRole("textbox", { name: /type/i });
116
+ const vinElement = screen.getByRole("textbox", { name: /vin/i });
117
+ const vrmElement = screen.getByRole("textbox", { name: /vrm/i });
118
+ const quantityElement = screen.getByRole("spinbutton", { name: /q/i });
119
+ const availableElement = screen.getByRole("textbox", { name: /available/i });
120
+ const currencyElement = screen.getByRole("textbox", { name: /currency/i });
121
+ const tradeDateElement = screen.getByRole("textbox", { name: /trade date/i });
122
+
123
+ if (clear) {
124
+ await userEvent.clear(idElement);
125
+ await userEvent.clear(firstNameElement);
126
+ await userEvent.clear(middleNameElement);
127
+ await userEvent.clear(lastNameElement);
128
+ await userEvent.clear(genderElement);
129
+ await userEvent.clear(ageElement);
130
+ await userEvent.clear(birthDateElement);
131
+ await userEvent.clear(manufacturerElement);
132
+ await userEvent.clear(modelElement);
133
+ await userEvent.clear(colorElement);
134
+ await userEvent.clear(typeElement);
135
+ await userEvent.clear(vinElement);
136
+ await userEvent.clear(vrmElement);
137
+ await userEvent.clear(quantityElement);
138
+ await userEvent.clear(availableElement);
139
+ await userEvent.clear(currencyElement);
140
+ await userEvent.clear(tradeDateElement);
141
+ }
142
+ await userEvent.type(idElement, instance.id);
143
+ await userEvent.type(firstNameElement, instance.firstName);
144
+ await userEvent.type(middleNameElement, instance.middleName);
145
+ await userEvent.type(lastNameElement, instance.lastName);
146
+ await userEvent.type(genderElement, instance.gender);
147
+ await userEvent.type(ageElement, instance.age.toString());
148
+ await userEvent.type(birthDateElement, instance.birthDate);
149
+ await userEvent.type(modelElement, instance.car.model);
150
+ await userEvent.type(manufacturerElement, instance.car.manufacturer);
151
+ await userEvent.type(colorElement, instance.car.color);
152
+ await userEvent.type(typeElement, instance.car.type);
153
+ await userEvent.type(vinElement, instance.car.vin);
154
+ await userEvent.type(vrmElement, instance.car.vrm);
155
+ await userEvent.type(quantityElement, instance.quantity.toString());
156
+ await userEvent.type(availableElement, instance.available.toString());
157
+ await userEvent.type(currencyElement, instance.currency);
158
+ await userEvent.type(tradeDateElement, instance.tradeDate);
159
+
160
+ submit && (await userEvent.click(screen.getByRole("button", { name: /save/i })));
161
+
162
+ return instance;
163
+ },
164
+ };
165
+
166
+ const renderComponent = async ({
167
+ router = "memory",
168
+ screen = "initial",
169
+ }: { router?: TestRouter; screen?: "initial" | "add" | "details" | "update" } = {}) => {
170
+ const requestList = jest.fn();
171
+ const onSubmitAdd = jest.fn();
172
+ const onSubmitUpdate = jest.fn();
173
+ const onRequestDelete = jest.fn();
174
+ const args = DummyModelRouter.args;
175
+ const instance = render(
176
+ <DummyModelRouter
177
+ {...args}
178
+ requestTimeout={REQUEST_TIMEOUT}
179
+ requestListAction={requestList}
180
+ onSubmitAddAction={onSubmitAdd}
181
+ onSubmitUpdateAction={onSubmitUpdate}
182
+ onRequestDeleteAction={onRequestDelete}
183
+ />,
184
+ {
185
+ router,
186
+ },
187
+ );
188
+
189
+ const randomItem = getRandomItem<any>(args.initialData);
190
+
191
+ if (screen === "add") {
192
+ await actions.navigateToAddScreen();
193
+ } else if (screen === "details") {
194
+ await actions.navigateToDetailScreen({ name: randomItem.item.firstName });
195
+ } else if (screen === "update") {
196
+ await actions.navigateToUpdateScreen({ id: randomItem.item.id });
197
+ }
198
+
199
+ return {
200
+ ...instance,
201
+ data: args.initialData,
202
+ model: args.model,
203
+ randomItem,
204
+ requestList,
205
+ onSubmitAdd,
206
+ onSubmitUpdate,
207
+ onRequestDelete,
208
+ };
209
+ };
210
+
211
+ describe("router screens", () => {
212
+ it("would render the list screen by default", async () => {
213
+ await renderComponent();
214
+
215
+ await assertions.expectListScreen();
216
+ });
217
+
218
+ it("would render the add screen if we navigate there", async () => {
219
+ await renderComponent();
220
+
221
+ await actions.navigateToAddScreen();
222
+
223
+ await assertions.expectAddScreen();
224
+ });
225
+
226
+ it("would render the update screen if we navigate there", async () => {
227
+ const { data } = await renderComponent();
228
+ const { item } = getRandomItem<any>(data);
229
+ const { id } = item;
230
+
231
+ await actions.navigateToUpdateScreen({ id });
232
+
233
+ await assertions.expectUpdateScreen({ id });
234
+ });
235
+
236
+ it("would render the detail screen if we navigate there", async () => {
237
+ const { data } = await renderComponent();
238
+ const {
239
+ item: { id, firstName },
240
+ } = getRandomItem<any>(data);
241
+
242
+ await actions.navigateToDetailScreen({ name: firstName });
243
+
244
+ await assertions.expectDetailScreen({ id });
245
+ });
246
+ });
247
+
248
+ describe("router paths", () => {
249
+ it("would have the pathname / by default", async () => {
250
+ const { history } = await renderComponent({ router: "router" });
251
+
252
+ expect(history.location.pathname).toBe("/");
253
+ });
254
+
255
+ it("would have the path /add if navigates to the add screen", async () => {
256
+ const { history } = await renderComponent({ router: "router" });
257
+
258
+ await actions.navigateToAddScreen();
259
+
260
+ expect(history.location.pathname).toBe("/add");
261
+ });
262
+
263
+ it("would have the path /:id/update if navigates to the update an item", async () => {
264
+ const { history, data } = await renderComponent({ router: "router" });
265
+ const {
266
+ item: { id },
267
+ } = getRandomItem<any>(data);
268
+
269
+ await actions.navigateToUpdateScreen({ id });
270
+
271
+ expect(history.location.pathname).toBe(`/${id}/update`);
272
+ });
273
+
274
+ it("would have the path /:id if navigates to the item details", async () => {
275
+ const { history, data } = await renderComponent({ router: "router" });
276
+ const {
277
+ item: { id, firstName },
278
+ } = getRandomItem<any>(data);
279
+
280
+ await actions.navigateToDetailScreen({ name: firstName });
281
+
282
+ expect(history.location.pathname).toBe(`/${id}`);
283
+ });
284
+ });
285
+
286
+ describe("list screen", () => {
287
+ it("would call requestList when is mounted", async () => {
288
+ const { requestList } = await renderComponent();
289
+
290
+ expect(requestList).toHaveBeenCalledTimes(1);
291
+ });
292
+
293
+ it("would render a loading indicator until the data is ready", async () => {
294
+ await renderComponent();
295
+
296
+ expectProgressIndicator();
297
+ await waitForProgressIndicatorToBeRemoved();
298
+ });
299
+
300
+ it("would render a title", async () => {
301
+ await renderComponent();
302
+
303
+ expect(
304
+ screen.getByRole("heading", {
305
+ name: "Items",
306
+ level: 1,
307
+ }),
308
+ ).toBeInTheDocument();
309
+ });
310
+
311
+ describe("add button", () => {
312
+ it("would render an add button", async () => {
313
+ await renderComponent();
314
+
315
+ expect(screen.getByRole("button", { name: /add/i })).toBeInTheDocument();
316
+ });
317
+
318
+ it("would navigate to the add screen if I press the add button", async () => {
319
+ const { history } = await renderComponent({ router: "router" });
320
+
321
+ await userEvent.click(screen.getByRole("button", { name: /add/i }));
322
+
323
+ expect(history.location.pathname).toBe("/add");
324
+ });
325
+ });
326
+
327
+ it("would render a list with the data", async () => {
328
+ const { data, model } = await renderComponent();
329
+
330
+ await assertions.expectListItems({ data, model });
331
+ });
332
+
333
+ it("would navigate to the detail screen if an item is clicked", async () => {
334
+ const { data, history } = await renderComponent({ router: "router" });
335
+ const {
336
+ item: { id, firstName },
337
+ } = getRandomItem<any>(data);
338
+
339
+ await userEvent.click(await screen.findByRole("cell", { name: firstName }));
340
+
341
+ expect(history.location.pathname).toBe(`/${id}`);
342
+ });
343
+
344
+ describe("item options", () => {
345
+ it("would have a options button for each item", async () => {
346
+ const { data } = await renderComponent();
347
+
348
+ for (let i = 0; i < data.length; ++i) {
349
+ const id = (data[i] as any).id;
350
+ await assertions.expectMenuOption({ id });
351
+ }
352
+ });
353
+
354
+ it("would render an option to edit", async () => {
355
+ const { data } = await renderComponent({ router: "router" });
356
+ const {
357
+ item: { id },
358
+ } = getRandomItem<any>(data);
359
+
360
+ await actions.openItemOptions({ id });
361
+
362
+ expect(screen.getByRole("menuitem", { name: /edit/i })).toBeInTheDocument();
363
+ });
364
+
365
+ it("would render an option to delete", async () => {
366
+ const { data } = await renderComponent({ router: "router" });
367
+ const {
368
+ item: { id },
369
+ } = getRandomItem<any>(data);
370
+
371
+ await actions.openItemOptions({ id });
372
+
373
+ expect(screen.getByRole("menuitem", { name: /remove/i })).toBeInTheDocument();
374
+ });
375
+ });
376
+ });
377
+
378
+ describe("add screen", () => {
379
+ it("would render a title", async () => {
380
+ await renderComponent({ screen: "add" });
381
+
382
+ expect(
383
+ screen.getByRole("heading", {
384
+ level: 1,
385
+ name: /add items/i,
386
+ }),
387
+ );
388
+ });
389
+
390
+ it("would render the navigation path", async () => {
391
+ await renderComponent({ screen: "add" });
392
+
393
+ expect(screen.getByRole("link", { name: "Items" })).toBeInTheDocument();
394
+ expect(screen.getByRole("link", { name: "Add new Items" })).toBeInTheDocument();
395
+ });
396
+
397
+ it("would be able to go back to the list screen", async () => {
398
+ await renderComponent({ screen: "add" });
399
+
400
+ await userEvent.click(screen.getByRole("link", { name: "Items" }));
401
+
402
+ await assertions.expectListScreen();
403
+ });
404
+
405
+ it("would render a form", async () => {
406
+ const { model } = await renderComponent({ screen: "add" });
407
+
408
+ expectModelFieldInputExist(model.fields);
409
+ });
410
+
411
+ it("would be able to fullfill the form", async () => {
412
+ const { model } = await renderComponent({ screen: "add" });
413
+
414
+ const newInstance = await actions.fullfillModelForm({ model, submit: false });
415
+
416
+ expectModelFieldInputValue(model.fields, newInstance);
417
+ });
418
+
419
+ it("would make a request when the form is submitted", async () => {
420
+ const { onSubmitAdd, model } = await renderComponent({ screen: "add" });
421
+
422
+ const newInstance = await actions.fullfillModelForm({ model, submit: true });
423
+
424
+ assertions.expectSubmitInstanceCall(onSubmitAdd, newInstance);
425
+ });
426
+
427
+ it("would show a loading indicator when the request is in progress", async () => {
428
+ const { model } = await renderComponent({ screen: "add" });
429
+
430
+ await actions.fullfillModelForm({ model, submit: true });
431
+
432
+ expectProgressIndicator();
433
+ });
434
+
435
+ // TODO it("would show a success message if the request finish with a success", async () => {
436
+ // await renderComponent({ screen: "add" });
437
+
438
+ // await actions.fullfillModelForm();
439
+
440
+ // await expectAlert({
441
+ // message: /item added successfully/i,
442
+ // severity: "success",
443
+ // });
444
+ // });
445
+
446
+ // TODO it("would navigate to the list screen if the request finish with a success", async () => {
447
+ // await renderComponent({ screen: "add" });
448
+
449
+ // await actions.fullfillModelForm();
450
+
451
+ // await assertions.expectListScreen();
452
+ // });
453
+ });
454
+
455
+ describe("details screen", () => {
456
+ it("would render a title", async () => {
457
+ const {
458
+ randomItem: {
459
+ item: { id },
460
+ },
461
+ } = await renderComponent({ screen: "details" });
462
+
463
+ expect(
464
+ screen.getByRole("heading", {
465
+ name: id,
466
+ level: 1,
467
+ }),
468
+ );
469
+ });
470
+
471
+ it("would be able to go back to the list screen", async () => {
472
+ await renderComponent({ screen: "details" });
473
+
474
+ await userEvent.click(
475
+ screen.getByRole("link", {
476
+ name: /items/i,
477
+ }),
478
+ );
479
+
480
+ await assertions.expectListScreen();
481
+ });
482
+
483
+ it("would show a loading indicator when the request is in progress", async () => {
484
+ await renderComponent({ screen: "details" });
485
+
486
+ expectProgressIndicator();
487
+ });
488
+
489
+ it("would show the details of an instance", async () => {
490
+ const { model, randomItem } = await renderComponent({ screen: "details" });
491
+
492
+ await waitForProgressIndicatorToBeRemoved();
493
+
494
+ model.fields.forEach((detail) => expectModelFieldValue(detail, randomItem.item));
495
+ });
496
+ });
497
+
498
+ describe("update screen", () => {
499
+ it("would render a title", async () => {
500
+ const {
501
+ randomItem: {
502
+ item: { id },
503
+ },
504
+ } = await renderComponent({ screen: "update" });
505
+
506
+ expect(
507
+ screen.getByRole("heading", {
508
+ name: `Edit ${id}`,
509
+ level: 1,
510
+ }),
511
+ ).toBeInTheDocument();
512
+ });
513
+
514
+ it("would render the navigation path", async () => {
515
+ const {
516
+ randomItem: {
517
+ item: { id },
518
+ },
519
+ } = await renderComponent({ screen: "update" });
520
+
521
+ expect(
522
+ screen.getByRole("link", {
523
+ name: /items/i,
524
+ }),
525
+ ).toBeInTheDocument();
526
+ expect(
527
+ screen.getByRole("link", {
528
+ name: `Edit ${id}`,
529
+ }),
530
+ ).toBeInTheDocument();
531
+ });
532
+
533
+ it("would be able to go back to the list screen", async () => {
534
+ await renderComponent({ screen: "update" });
535
+
536
+ await userEvent.click(
537
+ screen.getByRole("link", {
538
+ name: /Items/i,
539
+ }),
540
+ );
541
+
542
+ await assertions.expectListScreen();
543
+ });
544
+
545
+ it("would show a loading indicator while the instance is requested", async () => {
546
+ await renderComponent({ screen: "update" });
547
+
548
+ await expectProgressIndicator();
549
+ });
550
+
551
+ it("would render a form with the instance values", async () => {
552
+ const {
553
+ model,
554
+ randomItem: { item },
555
+ } = await renderComponent({ screen: "update" });
556
+
557
+ await waitForProgressIndicatorToBeRemoved();
558
+
559
+ expectModelFieldInputValue(model.fields, item);
560
+ });
561
+
562
+ it("would make a request with the new values when the form is submitted", async () => {
563
+ const { model } = await renderComponent({ screen: "update" });
564
+
565
+ await waitForProgressIndicatorToBeRemoved();
566
+ const newInstance = await actions.fullfillModelForm({ model, clear: true });
567
+
568
+ expectModelFieldInputValue(model.fields, newInstance);
569
+ });
570
+
571
+ it("would show a loading indicator while the submit request is in progress", async () => {
572
+ const { model } = await renderComponent({ screen: "update" });
573
+
574
+ await waitForProgressIndicatorToBeRemoved();
575
+ await actions.fullfillModelForm({ model, submit: true });
576
+
577
+ expectProgressIndicator();
578
+ });
579
+
580
+ it("would navigate to the list screen when the submit request finish", async () => {
581
+ const { model, onSubmitUpdate } = await renderComponent({ screen: "update" });
582
+
583
+ await waitForProgressIndicatorToBeRemoved();
584
+ const newInstance = await actions.fullfillModelForm({ model, submit: true, clear: true });
585
+
586
+ assertions.expectSubmitInstanceCall(onSubmitUpdate, newInstance);
587
+ });
588
+ });
589
+
590
+ describe("delete item", () => {
591
+ it("would make a request when we try to delete an option", async () => {
592
+ const { data, onRequestDelete } = await renderComponent();
593
+
594
+ const { item } = getRandomItem<any>(data);
595
+ const { id, firstName } = item;
596
+
597
+ await screen.findByRole("cell", { name: firstName });
598
+
599
+ await actions.openItemOptions({ id });
600
+
601
+ await userEvent.click(screen.getByRole("menuitem", { name: /remove/i }));
602
+
603
+ expect(onRequestDelete).toHaveBeenCalledTimes(1);
604
+ expect(onRequestDelete).toHaveBeenCalledWith(item);
605
+ });
606
+
607
+ it("would show a loading indicator while the request is in progress", async () => {
608
+ const { data } = await renderComponent();
609
+
610
+ const { item } = getRandomItem<any>(data);
611
+ const { id, firstName } = item;
612
+
613
+ await screen.findByRole("cell", { name: firstName });
614
+ await actions.openItemOptions({ id });
615
+ await userEvent.click(screen.getByRole("menuitem", { name: /remove/i }));
616
+
617
+ expectProgressIndicator();
618
+ });
619
+
620
+ it("would remove the item from the list when the request finish", async () => {
621
+ const { data } = await renderComponent();
622
+ const { item } = getRandomItem<any>(data);
623
+ const { id, firstName } = item;
624
+
625
+ await screen.findByRole("cell", { name: firstName });
626
+ await actions.openItemOptions({ id });
627
+ await userEvent.click(screen.getByRole("menuitem", { name: /remove/i }));
628
+ await waitForProgressIndicatorToBeRemoved();
629
+
630
+ expect(screen.queryByRole("cell", { name: firstName })).not.toBeInTheDocument();
631
+ });
632
+ });
633
+ });
@@ -0,0 +1,54 @@
1
+ import React from "react";
2
+ import { Routes, Route } from "react-router-dom";
3
+ import { Model } from "../generators.model";
4
+ import { AddScreen, DetailsScreen, ListScreen, UpdateScreen } from "./screens";
5
+
6
+ export interface RequestState {
7
+ idle?: boolean;
8
+ loading?: boolean;
9
+ error?: string;
10
+ success?: boolean;
11
+ }
12
+
13
+ export interface ModelRouterProps {
14
+ modelName: string;
15
+ model: Model;
16
+ //list screen
17
+ requestList?: () => void;
18
+ list: {
19
+ data: any[];
20
+ onClickRemoveItem: (item: any) => void;
21
+ listRequest: RequestState;
22
+ requestDelete: RequestState;
23
+ };
24
+ //add screen
25
+ add: {
26
+ onSubmit: (obj: object) => void;
27
+ request: RequestState;
28
+ };
29
+ //detail screen
30
+ detail: {
31
+ onScreenMount?: (id: string) => void;
32
+ request: RequestState;
33
+ instance?: any;
34
+ };
35
+ //update screen
36
+ update: {
37
+ onSubmit: (obj: object) => void;
38
+ request: RequestState;
39
+ requestInstance: RequestState;
40
+ onRequestInstance: (id: string) => void;
41
+ instance?: any;
42
+ };
43
+ }
44
+
45
+ export const ModelRouter = (props: ModelRouterProps) => {
46
+ return (
47
+ <Routes>
48
+ <Route path="" element={<ListScreen {...props} />} />
49
+ <Route path=":id" element={<DetailsScreen {...props} />} />
50
+ <Route path="add" element={<AddScreen {...props} />} />
51
+ <Route path=":id/update" element={<UpdateScreen {...props} />} />
52
+ </Routes>
53
+ );
54
+ };