@qwickapps/react-framework 1.3.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 (441) hide show
  1. package/LICENSE +44 -0
  2. package/README.md +794 -0
  3. package/dist/components/AccessibilityChecker.d.ts +12 -0
  4. package/dist/components/AccessibilityChecker.d.ts.map +1 -0
  5. package/dist/components/Html.d.ts +48 -0
  6. package/dist/components/Html.d.ts.map +1 -0
  7. package/dist/components/Logo.d.ts +79 -0
  8. package/dist/components/Logo.d.ts.map +1 -0
  9. package/dist/components/Markdown.d.ts +47 -0
  10. package/dist/components/Markdown.d.ts.map +1 -0
  11. package/dist/components/QwickApp.d.ts +56 -0
  12. package/dist/components/QwickApp.d.ts.map +1 -0
  13. package/dist/components/QwickAppsLogo.d.ts +25 -0
  14. package/dist/components/QwickAppsLogo.d.ts.map +1 -0
  15. package/dist/components/ResponsiveMenu.d.ts +38 -0
  16. package/dist/components/ResponsiveMenu.d.ts.map +1 -0
  17. package/dist/components/SafeSpan.d.ts +23 -0
  18. package/dist/components/SafeSpan.d.ts.map +1 -0
  19. package/dist/components/Scaffold.d.ts +57 -0
  20. package/dist/components/Scaffold.d.ts.map +1 -0
  21. package/dist/components/blocks/Article.d.ts +23 -0
  22. package/dist/components/blocks/Article.d.ts.map +1 -0
  23. package/dist/components/blocks/CardListGrid.d.ts +23 -0
  24. package/dist/components/blocks/CardListGrid.d.ts.map +1 -0
  25. package/dist/components/blocks/Code.d.ts +21 -0
  26. package/dist/components/blocks/Code.d.ts.map +1 -0
  27. package/dist/components/blocks/Content.d.ts +24 -0
  28. package/dist/components/blocks/Content.d.ts.map +1 -0
  29. package/dist/components/blocks/CoverImageHeader.d.ts +44 -0
  30. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -0
  31. package/dist/components/blocks/FeatureCard.d.ts +66 -0
  32. package/dist/components/blocks/FeatureCard.d.ts.map +1 -0
  33. package/dist/components/blocks/FeatureGrid.d.ts +48 -0
  34. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -0
  35. package/dist/components/blocks/Footer.d.ts +56 -0
  36. package/dist/components/blocks/Footer.d.ts.map +1 -0
  37. package/dist/components/blocks/HeroBlock.d.ts +33 -0
  38. package/dist/components/blocks/HeroBlock.d.ts.map +1 -0
  39. package/dist/components/blocks/PageBannerHeader.d.ts +30 -0
  40. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -0
  41. package/dist/components/blocks/ProductCard.d.ts +57 -0
  42. package/dist/components/blocks/ProductCard.d.ts.map +1 -0
  43. package/dist/components/blocks/Section.d.ts +40 -0
  44. package/dist/components/blocks/Section.d.ts.map +1 -0
  45. package/dist/components/blocks/index.d.ts +37 -0
  46. package/dist/components/blocks/index.d.ts.map +1 -0
  47. package/dist/components/buttons/Button.d.ts +38 -0
  48. package/dist/components/buttons/Button.d.ts.map +1 -0
  49. package/dist/components/buttons/PaletteSwitcher.d.ts +24 -0
  50. package/dist/components/buttons/PaletteSwitcher.d.ts.map +1 -0
  51. package/dist/components/buttons/ThemeSwitcher.d.ts +24 -0
  52. package/dist/components/buttons/ThemeSwitcher.d.ts.map +1 -0
  53. package/dist/components/buttons/index.d.ts +11 -0
  54. package/dist/components/buttons/index.d.ts.map +1 -0
  55. package/dist/components/forms/FormBlock.d.ts +45 -0
  56. package/dist/components/forms/FormBlock.d.ts.map +1 -0
  57. package/dist/components/forms/index.d.ts +8 -0
  58. package/dist/components/forms/index.d.ts.map +1 -0
  59. package/dist/components/index.d.ts +32 -0
  60. package/dist/components/index.d.ts.map +1 -0
  61. package/dist/components/input/ChoiceInputField.d.ts +30 -0
  62. package/dist/components/input/ChoiceInputField.d.ts.map +1 -0
  63. package/dist/components/input/HtmlInputField.d.ts +29 -0
  64. package/dist/components/input/HtmlInputField.d.ts.map +1 -0
  65. package/dist/components/input/SelectInputField.d.ts +29 -0
  66. package/dist/components/input/SelectInputField.d.ts.map +1 -0
  67. package/dist/components/input/TextField.d.ts +18 -0
  68. package/dist/components/input/TextField.d.ts.map +1 -0
  69. package/dist/components/input/TextInputField.d.ts +32 -0
  70. package/dist/components/input/TextInputField.d.ts.map +1 -0
  71. package/dist/components/input/index.d.ts +17 -0
  72. package/dist/components/input/index.d.ts.map +1 -0
  73. package/dist/components/layout/GridCell.d.ts +16 -0
  74. package/dist/components/layout/GridCell.d.ts.map +1 -0
  75. package/dist/components/layout/GridCellWrapper.d.ts +46 -0
  76. package/dist/components/layout/GridCellWrapper.d.ts.map +1 -0
  77. package/dist/components/layout/GridLayout.d.ts +38 -0
  78. package/dist/components/layout/GridLayout.d.ts.map +1 -0
  79. package/dist/components/layout/index.d.ts +12 -0
  80. package/dist/components/layout/index.d.ts.map +1 -0
  81. package/dist/components/menu/Menu.d.ts +1 -0
  82. package/dist/components/menu/Menu.d.ts.map +1 -0
  83. package/dist/components/menu/MenuItem.d.ts +31 -0
  84. package/dist/components/menu/MenuItem.d.ts.map +1 -0
  85. package/dist/components/menu/index.d.ts +7 -0
  86. package/dist/components/menu/index.d.ts.map +1 -0
  87. package/dist/components/pages/FormPage.d.ts +66 -0
  88. package/dist/components/pages/FormPage.d.ts.map +1 -0
  89. package/dist/components/pages/Page.d.ts +124 -0
  90. package/dist/components/pages/Page.d.ts.map +1 -0
  91. package/dist/components/pages/index.d.ts +11 -0
  92. package/dist/components/pages/index.d.ts.map +1 -0
  93. package/dist/contexts/DataContext.d.ts +139 -0
  94. package/dist/contexts/DataContext.d.ts.map +1 -0
  95. package/dist/contexts/DimensionsContext.d.ts +42 -0
  96. package/dist/contexts/DimensionsContext.d.ts.map +1 -0
  97. package/dist/contexts/PaletteContext.d.ts +53 -0
  98. package/dist/contexts/PaletteContext.d.ts.map +1 -0
  99. package/dist/contexts/QwickAppContext.d.ts +71 -0
  100. package/dist/contexts/QwickAppContext.d.ts.map +1 -0
  101. package/dist/contexts/ThemeContext.d.ts +65 -0
  102. package/dist/contexts/ThemeContext.d.ts.map +1 -0
  103. package/dist/contexts/index.d.ts +9 -0
  104. package/dist/contexts/index.d.ts.map +1 -0
  105. package/dist/hooks/index.d.ts +10 -0
  106. package/dist/hooks/index.d.ts.map +1 -0
  107. package/dist/hooks/useBaseProps.d.ts +101 -0
  108. package/dist/hooks/useBaseProps.d.ts.map +1 -0
  109. package/dist/hooks/useDataBinding.d.ts +22 -0
  110. package/dist/hooks/useDataBinding.d.ts.map +1 -0
  111. package/dist/index.css +1 -0
  112. package/dist/index.d.ts +8 -0
  113. package/dist/index.d.ts.map +1 -0
  114. package/dist/index.esm.css +1 -0
  115. package/dist/index.esm.js +24143 -0
  116. package/dist/index.js +24245 -0
  117. package/dist/palettes/PaletteAutumn.d.ts +10 -0
  118. package/dist/palettes/PaletteAutumn.d.ts.map +1 -0
  119. package/dist/palettes/PaletteCosmic.d.ts +10 -0
  120. package/dist/palettes/PaletteCosmic.d.ts.map +1 -0
  121. package/dist/palettes/PaletteDefault.d.ts +10 -0
  122. package/dist/palettes/PaletteDefault.d.ts.map +1 -0
  123. package/dist/palettes/PaletteOcean.d.ts +10 -0
  124. package/dist/palettes/PaletteOcean.d.ts.map +1 -0
  125. package/dist/palettes/PaletteSpring.d.ts +10 -0
  126. package/dist/palettes/PaletteSpring.d.ts.map +1 -0
  127. package/dist/palettes/PaletteWinter.d.ts +10 -0
  128. package/dist/palettes/PaletteWinter.d.ts.map +1 -0
  129. package/dist/palettes/index.d.ts +13 -0
  130. package/dist/palettes/index.d.ts.map +1 -0
  131. package/dist/schemas/ActionSchema.d.ts +21 -0
  132. package/dist/schemas/ActionSchema.d.ts.map +1 -0
  133. package/dist/schemas/ArticleSchema.d.ts +13 -0
  134. package/dist/schemas/ArticleSchema.d.ts.map +1 -0
  135. package/dist/schemas/Builders.d.ts +7 -0
  136. package/dist/schemas/Builders.d.ts.map +1 -0
  137. package/dist/schemas/ButtonSchema.d.ts +19 -0
  138. package/dist/schemas/ButtonSchema.d.ts.map +1 -0
  139. package/dist/schemas/CardListGridSchema.d.ts +17 -0
  140. package/dist/schemas/CardListGridSchema.d.ts.map +1 -0
  141. package/dist/schemas/ChoiceInputFieldSchema.d.ts +18 -0
  142. package/dist/schemas/ChoiceInputFieldSchema.d.ts.map +1 -0
  143. package/dist/schemas/CodeSchema.d.ts +18 -0
  144. package/dist/schemas/CodeSchema.d.ts.map +1 -0
  145. package/dist/schemas/ContentSchema.d.ts +20 -0
  146. package/dist/schemas/ContentSchema.d.ts.map +1 -0
  147. package/dist/schemas/CoverImageHeaderSchema.d.ts +28 -0
  148. package/dist/schemas/CoverImageHeaderSchema.d.ts.map +1 -0
  149. package/dist/schemas/FeatureCardSchema.d.ts +28 -0
  150. package/dist/schemas/FeatureCardSchema.d.ts.map +1 -0
  151. package/dist/schemas/FeatureGridSchema.d.ts +17 -0
  152. package/dist/schemas/FeatureGridSchema.d.ts.map +1 -0
  153. package/dist/schemas/FeatureItemSchema.d.ts +16 -0
  154. package/dist/schemas/FeatureItemSchema.d.ts.map +1 -0
  155. package/dist/schemas/FooterItemSchema.d.ts +15 -0
  156. package/dist/schemas/FooterItemSchema.d.ts.map +1 -0
  157. package/dist/schemas/FooterSchema.d.ts +20 -0
  158. package/dist/schemas/FooterSchema.d.ts.map +1 -0
  159. package/dist/schemas/FooterSectionSchema.d.ts +15 -0
  160. package/dist/schemas/FooterSectionSchema.d.ts.map +1 -0
  161. package/dist/schemas/FormBlockSchema.d.ts +19 -0
  162. package/dist/schemas/FormBlockSchema.d.ts.map +1 -0
  163. package/dist/schemas/HeaderActionSchema.d.ts +17 -0
  164. package/dist/schemas/HeaderActionSchema.d.ts.map +1 -0
  165. package/dist/schemas/HeroBlockSchema.d.ts +22 -0
  166. package/dist/schemas/HeroBlockSchema.d.ts.map +1 -0
  167. package/dist/schemas/HtmlInputFieldSchema.d.ts +18 -0
  168. package/dist/schemas/HtmlInputFieldSchema.d.ts.map +1 -0
  169. package/dist/schemas/MetadataItemSchema.d.ts +13 -0
  170. package/dist/schemas/MetadataItemSchema.d.ts.map +1 -0
  171. package/dist/schemas/PageBannerHeaderSchema.d.ts +28 -0
  172. package/dist/schemas/PageBannerHeaderSchema.d.ts.map +1 -0
  173. package/dist/schemas/PaletteSwitcherSchema.d.ts +16 -0
  174. package/dist/schemas/PaletteSwitcherSchema.d.ts.map +1 -0
  175. package/dist/schemas/ProductCardSchema.d.ts +39 -0
  176. package/dist/schemas/ProductCardSchema.d.ts.map +1 -0
  177. package/dist/schemas/SafeSpanSchema.d.ts +13 -0
  178. package/dist/schemas/SafeSpanSchema.d.ts.map +1 -0
  179. package/dist/schemas/SectionSchema.d.ts +17 -0
  180. package/dist/schemas/SectionSchema.d.ts.map +1 -0
  181. package/dist/schemas/SelectInputFieldSchema.d.ts +27 -0
  182. package/dist/schemas/SelectInputFieldSchema.d.ts.map +1 -0
  183. package/dist/schemas/TextInputFieldSchema.d.ts +22 -0
  184. package/dist/schemas/TextInputFieldSchema.d.ts.map +1 -0
  185. package/dist/schemas/ThemeSwitcherSchema.d.ts +19 -0
  186. package/dist/schemas/ThemeSwitcherSchema.d.ts.map +1 -0
  187. package/dist/schemas/index.d.ts +33 -0
  188. package/dist/schemas/index.d.ts.map +1 -0
  189. package/dist/schemas/types.d.ts +7 -0
  190. package/dist/schemas/types.d.ts.map +1 -0
  191. package/dist/templates/TemplateResolver.d.ts +52 -0
  192. package/dist/templates/TemplateResolver.d.ts.map +1 -0
  193. package/dist/templates/index.d.ts +7 -0
  194. package/dist/templates/index.d.ts.map +1 -0
  195. package/dist/tests/ConsoleWarningTest.d.ts +5 -0
  196. package/dist/tests/ConsoleWarningTest.d.ts.map +1 -0
  197. package/dist/tests/StorageKeyTest.d.ts +6 -0
  198. package/dist/tests/StorageKeyTest.d.ts.map +1 -0
  199. package/dist/tests/ThemeStorageKeyTest.d.ts +6 -0
  200. package/dist/tests/ThemeStorageKeyTest.d.ts.map +1 -0
  201. package/dist/types/CacheProvider.d.ts +18 -0
  202. package/dist/types/CacheProvider.d.ts.map +1 -0
  203. package/dist/types/ContentProxy.d.ts +47 -0
  204. package/dist/types/ContentProxy.d.ts.map +1 -0
  205. package/dist/types/DataBinding.d.ts +7 -0
  206. package/dist/types/DataBinding.d.ts.map +1 -0
  207. package/dist/types/DataProvider.d.ts +7 -0
  208. package/dist/types/DataProvider.d.ts.map +1 -0
  209. package/dist/types/DataTypes.d.ts +185 -0
  210. package/dist/types/DataTypes.d.ts.map +1 -0
  211. package/dist/types/TemplateProvider.d.ts +10 -0
  212. package/dist/types/TemplateProvider.d.ts.map +1 -0
  213. package/dist/types/TemplateResolver.d.ts +23 -0
  214. package/dist/types/TemplateResolver.d.ts.map +1 -0
  215. package/dist/types/index.d.ts +81 -0
  216. package/dist/types/index.d.ts.map +1 -0
  217. package/dist/utils/breakpoints.d.ts +35 -0
  218. package/dist/utils/breakpoints.d.ts.map +1 -0
  219. package/dist/utils/customPaletteManager.d.ts +8 -0
  220. package/dist/utils/customPaletteManager.d.ts.map +1 -0
  221. package/dist/utils/dimensions.d.ts +34 -0
  222. package/dist/utils/dimensions.d.ts.map +1 -0
  223. package/dist/utils/htmlTransform.d.ts +44 -0
  224. package/dist/utils/htmlTransform.d.ts.map +1 -0
  225. package/dist/utils/index.d.ts +15 -0
  226. package/dist/utils/index.d.ts.map +1 -0
  227. package/dist/utils/logger.d.ts +14 -0
  228. package/dist/utils/logger.d.ts.map +1 -0
  229. package/dist/utils/paletteUtils.d.ts +38 -0
  230. package/dist/utils/paletteUtils.d.ts.map +1 -0
  231. package/dist/utils/persistenceUtils.d.ts +31 -0
  232. package/dist/utils/persistenceUtils.d.ts.map +1 -0
  233. package/dist/utils/reactUtils.d.ts +24 -0
  234. package/dist/utils/reactUtils.d.ts.map +1 -0
  235. package/dist/utils/spacing.d.ts +34 -0
  236. package/dist/utils/spacing.d.ts.map +1 -0
  237. package/dist/utils/themePerformanceMonitor.d.ts +32 -0
  238. package/dist/utils/themePerformanceMonitor.d.ts.map +1 -0
  239. package/dist/utils/themeUtils.d.ts +27 -0
  240. package/dist/utils/themeUtils.d.ts.map +1 -0
  241. package/package.json +141 -0
  242. package/src/__tests__/components/Logo.test.js +172 -0
  243. package/src/__tests__/contexts/DataContext.test.js +505 -0
  244. package/src/__tests__/contexts/PaletteContext.test.js +115 -0
  245. package/src/__tests__/contexts/ThemeContext.test.js +123 -0
  246. package/src/__tests__/utils/paletteUtils.test.js +142 -0
  247. package/src/__tests__/utils/themeUtils.test.js +142 -0
  248. package/src/components/AccessibilityChecker.tsx +264 -0
  249. package/src/components/Html.tsx +191 -0
  250. package/src/components/Logo.css +217 -0
  251. package/src/components/Logo.tsx +370 -0
  252. package/src/components/Markdown.tsx +191 -0
  253. package/src/components/QwickApp.css +257 -0
  254. package/src/components/QwickApp.tsx +157 -0
  255. package/src/components/QwickAppsLogo.tsx +77 -0
  256. package/src/components/ResponsiveMenu.css +416 -0
  257. package/src/components/ResponsiveMenu.tsx +310 -0
  258. package/src/components/SafeSpan.tsx +128 -0
  259. package/src/components/Scaffold.css +541 -0
  260. package/src/components/Scaffold.tsx +463 -0
  261. package/src/components/__tests__/Article.test.tsx +419 -0
  262. package/src/components/__tests__/Button.test.tsx +702 -0
  263. package/src/components/__tests__/CardListGrid.test.tsx +478 -0
  264. package/src/components/__tests__/ChoiceInputField.test.tsx +864 -0
  265. package/src/components/__tests__/Code.test.tsx +595 -0
  266. package/src/components/__tests__/Content.integration.test.tsx +193 -0
  267. package/src/components/__tests__/Content.test.tsx +504 -0
  268. package/src/components/__tests__/CoverImageHeader.test.tsx +456 -0
  269. package/src/components/__tests__/FeatureCard.integration.test.tsx +384 -0
  270. package/src/components/__tests__/FeatureGrid.integration.test.tsx +364 -0
  271. package/src/components/__tests__/FeatureGrid.test.tsx +494 -0
  272. package/src/components/__tests__/Footer.test.tsx +544 -0
  273. package/src/components/__tests__/FormBlock.test.tsx +857 -0
  274. package/src/components/__tests__/HeroBlock.integration.test.tsx +272 -0
  275. package/src/components/__tests__/HeroBlock.test.tsx +463 -0
  276. package/src/components/__tests__/Html.test.tsx +174 -0
  277. package/src/components/__tests__/HtmlInputField.test.tsx +856 -0
  278. package/src/components/__tests__/Markdown.test.tsx +233 -0
  279. package/src/components/__tests__/PageBannerHeader.test.tsx +614 -0
  280. package/src/components/__tests__/PaletteSwitcher.test.tsx +864 -0
  281. package/src/components/__tests__/ProductCard.test.tsx +377 -0
  282. package/src/components/__tests__/SafeSpan.integration.test.tsx +123 -0
  283. package/src/components/__tests__/SafeSpan.simple.test.tsx +65 -0
  284. package/src/components/__tests__/SafeSpan.test.tsx +388 -0
  285. package/src/components/__tests__/Section.integration.test.tsx +288 -0
  286. package/src/components/__tests__/Section.test.tsx +494 -0
  287. package/src/components/__tests__/SelectInputField.test.tsx +886 -0
  288. package/src/components/__tests__/TextInputField.test.tsx +749 -0
  289. package/src/components/__tests__/ThemeSwitcher.test.tsx +777 -0
  290. package/src/components/blocks/Article.tsx +194 -0
  291. package/src/components/blocks/CardListGrid.tsx +132 -0
  292. package/src/components/blocks/Code.tsx +313 -0
  293. package/src/components/blocks/Content.tsx +265 -0
  294. package/src/components/blocks/CoverImageHeader.css +17 -0
  295. package/src/components/blocks/CoverImageHeader.tsx +435 -0
  296. package/src/components/blocks/FeatureCard.tsx +321 -0
  297. package/src/components/blocks/FeatureGrid.tsx +147 -0
  298. package/src/components/blocks/Footer.tsx +343 -0
  299. package/src/components/blocks/HeroBlock.tsx +280 -0
  300. package/src/components/blocks/PageBannerHeader.tsx +471 -0
  301. package/src/components/blocks/ProductCard.tsx +472 -0
  302. package/src/components/blocks/Section.tsx +209 -0
  303. package/src/components/blocks/index.ts +37 -0
  304. package/src/components/buttons/Button.tsx +233 -0
  305. package/src/components/buttons/PaletteSwitcher.tsx +268 -0
  306. package/src/components/buttons/ThemeSwitcher.tsx +283 -0
  307. package/src/components/buttons/index.ts +11 -0
  308. package/src/components/forms/FormBlock.tsx +291 -0
  309. package/src/components/forms/index.ts +7 -0
  310. package/src/components/index.ts +37 -0
  311. package/src/components/input/ChoiceInputField.tsx +188 -0
  312. package/src/components/input/HtmlInputField.tsx +326 -0
  313. package/src/components/input/SelectInputField.tsx +197 -0
  314. package/src/components/input/TextField.tsx +47 -0
  315. package/src/components/input/TextInputField.tsx +144 -0
  316. package/src/components/input/index.ts +17 -0
  317. package/src/components/layout/GridCell.tsx +46 -0
  318. package/src/components/layout/GridCellWrapper.tsx +87 -0
  319. package/src/components/layout/GridLayout.tsx +169 -0
  320. package/src/components/layout/index.ts +13 -0
  321. package/src/components/menu/Menu.tsx +0 -0
  322. package/src/components/menu/MenuItem.tsx +32 -0
  323. package/src/components/menu/index.ts +6 -0
  324. package/src/components/pages/FormPage.tsx +108 -0
  325. package/src/components/pages/Page.css +460 -0
  326. package/src/components/pages/Page.tsx +345 -0
  327. package/src/components/pages/index.ts +11 -0
  328. package/src/contexts/DataContext.tsx +355 -0
  329. package/src/contexts/DimensionsContext.tsx +154 -0
  330. package/src/contexts/PaletteContext.tsx +217 -0
  331. package/src/contexts/QwickAppContext.tsx +95 -0
  332. package/src/contexts/ThemeContext.tsx +376 -0
  333. package/src/contexts/index.ts +9 -0
  334. package/src/hooks/__tests__/useDataBinding.test.tsx.disabled +229 -0
  335. package/src/hooks/index.ts +11 -0
  336. package/src/hooks/useBaseProps.ts +267 -0
  337. package/src/hooks/useDataBinding.ts +77 -0
  338. package/src/index.ts +23 -0
  339. package/src/palettes/PaletteAutumn.css +172 -0
  340. package/src/palettes/PaletteAutumn.ts +16 -0
  341. package/src/palettes/PaletteCosmic.css +172 -0
  342. package/src/palettes/PaletteCosmic.ts +16 -0
  343. package/src/palettes/PaletteDefault.css +178 -0
  344. package/src/palettes/PaletteDefault.ts +17 -0
  345. package/src/palettes/PaletteOcean.css +172 -0
  346. package/src/palettes/PaletteOcean.ts +16 -0
  347. package/src/palettes/PaletteSpring.css +160 -0
  348. package/src/palettes/PaletteSpring.ts +16 -0
  349. package/src/palettes/PaletteWinter.css +172 -0
  350. package/src/palettes/PaletteWinter.ts +16 -0
  351. package/src/palettes/index.css +12 -0
  352. package/src/palettes/index.ts +29 -0
  353. package/src/schemas/ActionSchema.ts +140 -0
  354. package/src/schemas/ArticleSchema.ts +35 -0
  355. package/src/schemas/ButtonSchema.ts +99 -0
  356. package/src/schemas/CardListGridSchema.ts +102 -0
  357. package/src/schemas/ChoiceInputFieldSchema.ts +89 -0
  358. package/src/schemas/CodeSchema.ts +88 -0
  359. package/src/schemas/ContentSchema.ts +128 -0
  360. package/src/schemas/CoverImageHeaderSchema.ts +208 -0
  361. package/src/schemas/FeatureCardSchema.ts +161 -0
  362. package/src/schemas/FeatureGridSchema.ts +87 -0
  363. package/src/schemas/FeatureItemSchema.ts +68 -0
  364. package/src/schemas/FooterItemSchema.ts +57 -0
  365. package/src/schemas/FooterSchema.ts +116 -0
  366. package/src/schemas/FooterSectionSchema.ts +50 -0
  367. package/src/schemas/FormBlockSchema.ts +102 -0
  368. package/src/schemas/HeaderActionSchema.ts +83 -0
  369. package/src/schemas/HeroBlockSchema.ts +149 -0
  370. package/src/schemas/HtmlInputFieldSchema.ts +88 -0
  371. package/src/schemas/MetadataItemSchema.ts +35 -0
  372. package/src/schemas/PageBannerHeaderSchema.ts +206 -0
  373. package/src/schemas/PaletteSwitcherSchema.ts +66 -0
  374. package/src/schemas/ProductCardSchema.ts +264 -0
  375. package/src/schemas/SafeSpanSchema.ts +36 -0
  376. package/src/schemas/SectionSchema.ts +106 -0
  377. package/src/schemas/SelectInputFieldSchema.ts +137 -0
  378. package/src/schemas/TextInputFieldSchema.ts +129 -0
  379. package/src/schemas/ThemeSwitcherSchema.ts +97 -0
  380. package/src/schemas/__tests__/builders.test.ts +313 -0
  381. package/src/schemas/index.ts +34 -0
  382. package/src/setupTests.js +60 -0
  383. package/src/stories/Article.stories.tsx +549 -0
  384. package/src/stories/Button.stories.tsx +498 -0
  385. package/src/stories/CardListGrid.stories.tsx +539 -0
  386. package/src/stories/ChoiceInputField.stories.tsx +591 -0
  387. package/src/stories/Code.stories.tsx +711 -0
  388. package/src/stories/Content.stories.tsx +463 -0
  389. package/src/stories/CoverImageHeader.stories.tsx +794 -0
  390. package/src/stories/DataBinding.advanced.stories.tsx +548 -0
  391. package/src/stories/DataBinding.stories.tsx +452 -0
  392. package/src/stories/DataProvider.stories.tsx +1361 -0
  393. package/src/stories/FeatureCard.stories.tsx +642 -0
  394. package/src/stories/FeatureGrid.stories.tsx +669 -0
  395. package/src/stories/Footer.stories.tsx +724 -0
  396. package/src/stories/FormBlock.stories.tsx +834 -0
  397. package/src/stories/HeroBlock.stories.tsx +442 -0
  398. package/src/stories/Html.stories.tsx +264 -0
  399. package/src/stories/HtmlInputField.stories.tsx +558 -0
  400. package/src/stories/Introduction.stories.tsx +721 -0
  401. package/src/stories/LayoutBlocks.stories.tsx +382 -0
  402. package/src/stories/LayoutSystem.stories.tsx +253 -0
  403. package/src/stories/Logo.stories.tsx +400 -0
  404. package/src/stories/Markdown.stories.tsx +349 -0
  405. package/src/stories/Page.stories.tsx +762 -0
  406. package/src/stories/PageBannerHeader.stories.tsx +949 -0
  407. package/src/stories/PaletteSwitcher.stories.tsx +156 -0
  408. package/src/stories/ProductCard.stories.tsx +504 -0
  409. package/src/stories/QwickApp.stories.tsx +461 -0
  410. package/src/stories/ResponsiveMenu.stories.tsx +299 -0
  411. package/src/stories/SafeSpan.stories.tsx +612 -0
  412. package/src/stories/Section.stories.tsx +613 -0
  413. package/src/stories/SelectInputField.stories.tsx +605 -0
  414. package/src/stories/TextInputField.stories.tsx +526 -0
  415. package/src/stories/ThemeSwitcher.stories.tsx +170 -0
  416. package/src/stories/form/FormComponents.stories.tsx +588 -0
  417. package/src/templates/TemplateResolver.ts +156 -0
  418. package/src/templates/index.ts +6 -0
  419. package/src/tests/ConsoleWarningTest.tsx +30 -0
  420. package/src/tests/StorageKeyTest.tsx +110 -0
  421. package/src/tests/ThemeStorageKeyTest.tsx +114 -0
  422. package/src/types/CacheProvider.ts +14 -0
  423. package/src/types/ContentProxy.ts +99 -0
  424. package/src/types/DataTypes.ts +196 -0
  425. package/src/types/TemplateProvider.ts +9 -0
  426. package/src/types/TemplateResolver.ts +26 -0
  427. package/src/types/index.ts +99 -0
  428. package/src/utils/__tests__/createDataDrivenComponent.test.tsx.disabled +193 -0
  429. package/src/utils/__tests__/htmlTransform.test.tsx +255 -0
  430. package/src/utils/breakpoints.ts +87 -0
  431. package/src/utils/customPaletteManager.js +214 -0
  432. package/src/utils/dimensions.ts +147 -0
  433. package/src/utils/htmlTransform.tsx +323 -0
  434. package/src/utils/index.ts +16 -0
  435. package/src/utils/logger.ts +28 -0
  436. package/src/utils/paletteUtils.ts +78 -0
  437. package/src/utils/persistenceUtils.ts +107 -0
  438. package/src/utils/reactUtils.tsx +37 -0
  439. package/src/utils/spacing.ts +155 -0
  440. package/src/utils/themePerformanceMonitor.js +113 -0
  441. package/src/utils/themeUtils.ts +67 -0
@@ -0,0 +1,614 @@
1
+ /**
2
+ * Unit tests for PageBannerHeader component
3
+ *
4
+ * Tests both traditional props usage and data binding functionality
5
+ * with the new schema system.
6
+ */
7
+
8
+ import React from 'react';
9
+ import { render, screen, fireEvent } from '@testing-library/react';
10
+ import '@testing-library/jest-dom';
11
+ import PageBannerHeader from '../blocks/PageBannerHeader';
12
+ import { JsonDataProvider } from '@qwickapps/schema';
13
+ import { ThemeProvider, PaletteProvider } from '../../contexts';
14
+ import QwickApp from '../QwickApp';
15
+
16
+ // Test data for data binding - using nested structure
17
+ const sampleCmsData = {
18
+ 'pageBannerHeaders': {
19
+ 'aboutBanner': {
20
+ coverImage: '/images/about-banner.jpg',
21
+ coverImageAlt: 'About us banner',
22
+ profileImage: '/images/company-logo.jpg',
23
+ profileImageAlt: 'Company logo',
24
+ profileImageSize: 'large',
25
+ overline: 'About Us',
26
+ title: 'QwickApps React Framework',
27
+ subtitle: 'Building the future of web development',
28
+ metadata: [
29
+ { label: 'Developers', value: '50+' },
30
+ { label: 'Projects', value: '1000+' }
31
+ ],
32
+ tags: ['React', 'TypeScript', 'Material-UI', 'Open Source'],
33
+ maxVisibleActions: 2,
34
+ height: 300,
35
+ profilePosition: 'bottom-left'
36
+ },
37
+ 'teamHero': {
38
+ coverImage: '/images/team-banner.jpg',
39
+ title: 'Meet Our Team',
40
+ subtitle: 'Passionate developers creating amazing software',
41
+ profilePosition: 'overlay-center',
42
+ height: 250
43
+ },
44
+ 'minimalHeader': {
45
+ title: 'Simple Header',
46
+ subtitle: 'Clean and minimal design',
47
+ profilePosition: 'bottom-center'
48
+ },
49
+ 'emptyData': {},
50
+ 'loadingTest': {
51
+ title: 'Loading Test',
52
+ subtitle: 'Testing loading state behavior'
53
+ },
54
+ 'errorTest': {
55
+ title: 'Error Test',
56
+ subtitle: 'Testing error state behavior'
57
+ }
58
+ }
59
+ };
60
+
61
+ // Mock HeaderAction type
62
+ const mockActions = [
63
+ {
64
+ id: 'primary',
65
+ label: 'Primary Action',
66
+ priority: 1,
67
+ onClick: jest.fn(),
68
+ disabled: false,
69
+ destructive: false
70
+ },
71
+ {
72
+ id: 'secondary',
73
+ label: 'Secondary Action',
74
+ priority: 2,
75
+ onClick: jest.fn(),
76
+ disabled: false,
77
+ destructive: false
78
+ }
79
+ ];
80
+
81
+ // Wrapper component for tests that need providers
82
+ const TestWrapper: React.FC<{ children: React.ReactNode; dataProvider?: any }> = ({
83
+ children,
84
+ dataProvider
85
+ }) => (
86
+ <ThemeProvider>
87
+ <PaletteProvider>
88
+ {dataProvider ? (
89
+ <QwickApp appId="test-pagebanner" appName="PageBannerHeader Test" dataSource={{ dataProvider }}>
90
+ {children}
91
+ </QwickApp>
92
+ ) : (
93
+ children
94
+ )}
95
+ </PaletteProvider>
96
+ </ThemeProvider>
97
+ );
98
+
99
+ describe('PageBannerHeader', () => {
100
+ describe('Traditional Props Usage', () => {
101
+ it('renders basic header with title only', () => {
102
+ render(
103
+ <TestWrapper>
104
+ <PageBannerHeader title="Basic Header" />
105
+ </TestWrapper>
106
+ );
107
+
108
+ expect(screen.getByText('Basic Header')).toBeInTheDocument();
109
+ expect(screen.getByRole('banner')).toBeInTheDocument();
110
+ });
111
+
112
+ it('renders full header with all props', () => {
113
+ render(
114
+ <TestWrapper>
115
+ <PageBannerHeader
116
+ coverImage="/test-cover.jpg"
117
+ coverImageAlt="Test cover"
118
+ profileImage="/test-profile.jpg"
119
+ profileImageAlt="Test profile"
120
+ overline="Test Overline"
121
+ title="Full Header"
122
+ subtitle="Complete header with all features"
123
+ metadata={[
124
+ { label: 'followers', value: '1.2k' },
125
+ { label: 'posts', value: 42 }
126
+ ]}
127
+ tags={['React', 'TypeScript']}
128
+ actions={mockActions}
129
+ />
130
+ </TestWrapper>
131
+ );
132
+
133
+ expect(screen.getByText('Test Overline')).toBeInTheDocument();
134
+ expect(screen.getByText('Full Header')).toBeInTheDocument();
135
+ expect(screen.getByText('Complete header with all features')).toBeInTheDocument();
136
+ expect(screen.getByText('1.2k')).toBeInTheDocument();
137
+ expect(screen.getByText('followers')).toBeInTheDocument();
138
+ expect(screen.getByText('42')).toBeInTheDocument();
139
+ expect(screen.getByText('posts')).toBeInTheDocument();
140
+ expect(screen.getByText('React')).toBeInTheDocument();
141
+ expect(screen.getByText('TypeScript')).toBeInTheDocument();
142
+ expect(screen.getByText('Primary Action')).toBeInTheDocument();
143
+ expect(screen.getByText('Secondary Action')).toBeInTheDocument();
144
+ });
145
+
146
+ it('renders with different profile image sizes', () => {
147
+ const sizes = ['small', 'medium', 'large'] as const;
148
+
149
+ sizes.forEach(size => {
150
+ const { unmount } = render(
151
+ <TestWrapper>
152
+ <PageBannerHeader
153
+ title={`${size} profile`}
154
+ profileImage="/test-profile.jpg"
155
+ profileImageSize={size}
156
+ />
157
+ </TestWrapper>
158
+ );
159
+
160
+ expect(screen.getByText(`${size} profile`)).toBeInTheDocument();
161
+
162
+ unmount();
163
+ });
164
+ });
165
+
166
+ it('renders with different profile positions', () => {
167
+ const positions = ['bottom-left', 'bottom-center', 'overlay-center'] as const;
168
+
169
+ positions.forEach(position => {
170
+ const { unmount } = render(
171
+ <TestWrapper>
172
+ <PageBannerHeader
173
+ title={`${position} position`}
174
+ profileImage="/test-profile.jpg"
175
+ profilePosition={position}
176
+ />
177
+ </TestWrapper>
178
+ );
179
+
180
+ expect(screen.getByText(`${position} position`)).toBeInTheDocument();
181
+
182
+ unmount();
183
+ });
184
+ });
185
+
186
+ it('handles action button clicks', () => {
187
+ const handleClick = jest.fn();
188
+ const actionWithClick = [{
189
+ id: 'test',
190
+ label: 'Click Me',
191
+ priority: 1,
192
+ onClick: handleClick,
193
+ disabled: false,
194
+ destructive: false
195
+ }];
196
+
197
+ render(
198
+ <TestWrapper>
199
+ <PageBannerHeader
200
+ title="Action Test"
201
+ actions={actionWithClick}
202
+ />
203
+ </TestWrapper>
204
+ );
205
+
206
+ const button = screen.getByText('Click Me');
207
+ fireEvent.click(button);
208
+
209
+ expect(handleClick).toHaveBeenCalledTimes(1);
210
+ });
211
+
212
+ it('handles overflow actions with menu', () => {
213
+ const manyActions = Array.from({ length: 5 }, (_, i) => ({
214
+ id: `action-${i}`,
215
+ label: `Action ${i + 1}`,
216
+ priority: i + 1,
217
+ onClick: jest.fn(),
218
+ disabled: false,
219
+ destructive: false
220
+ }));
221
+
222
+ render(
223
+ <TestWrapper>
224
+ <PageBannerHeader
225
+ title="Overflow Test"
226
+ actions={manyActions}
227
+ maxVisibleActions={2}
228
+ />
229
+ </TestWrapper>
230
+ );
231
+
232
+ // First 2 actions should be visible
233
+ expect(screen.getByText('Action 1')).toBeInTheDocument();
234
+ expect(screen.getByText('Action 2')).toBeInTheDocument();
235
+
236
+ // Overflow menu button should be present
237
+ const menuButton = screen.getByLabelText('More actions');
238
+ expect(menuButton).toBeInTheDocument();
239
+
240
+ // Click to open menu
241
+ fireEvent.click(menuButton);
242
+
243
+ // Remaining actions should be in the menu
244
+ expect(screen.getByText('Action 3')).toBeInTheDocument();
245
+ expect(screen.getByText('Action 4')).toBeInTheDocument();
246
+ expect(screen.getByText('Action 5')).toBeInTheDocument();
247
+ });
248
+
249
+ it('renders with custom height', () => {
250
+ const { container } = render(
251
+ <TestWrapper>
252
+ <PageBannerHeader
253
+ title="Custom Height"
254
+ coverImage="/test-cover.jpg"
255
+ height={400}
256
+ />
257
+ </TestWrapper>
258
+ );
259
+
260
+ // Check that the component renders without errors
261
+ expect(screen.getByText('Custom Height')).toBeInTheDocument();
262
+ });
263
+
264
+ it('supports grid props', () => {
265
+ const { container } = render(
266
+ <TestWrapper>
267
+ <PageBannerHeader
268
+ title="Grid Test"
269
+ span={6}
270
+ xs={12}
271
+ md={8}
272
+ />
273
+ </TestWrapper>
274
+ );
275
+
276
+ const element = container.querySelector('[data-grid-span]');
277
+ expect(element).toHaveAttribute('data-grid-span', '6');
278
+ expect(element).toBeInTheDocument();
279
+ });
280
+
281
+ it('handles profile image as React node', () => {
282
+ const CustomProfile = () => <div>Custom Profile</div>;
283
+
284
+ render(
285
+ <TestWrapper>
286
+ <PageBannerHeader
287
+ title="Custom Profile Test"
288
+ profileImage={<CustomProfile />}
289
+ />
290
+ </TestWrapper>
291
+ );
292
+
293
+ expect(screen.getByText('Custom Profile Test')).toBeInTheDocument();
294
+ expect(screen.getByText('Custom Profile')).toBeInTheDocument();
295
+ });
296
+
297
+ it('handles destructive actions', () => {
298
+ const destructiveAction = [{
299
+ id: 'delete',
300
+ label: 'Delete',
301
+ priority: 1,
302
+ onClick: jest.fn(),
303
+ disabled: false,
304
+ destructive: true
305
+ }];
306
+
307
+ render(
308
+ <TestWrapper>
309
+ <PageBannerHeader
310
+ title="Destructive Action Test"
311
+ actions={destructiveAction}
312
+ />
313
+ </TestWrapper>
314
+ );
315
+
316
+ expect(screen.getByText('Delete')).toBeInTheDocument();
317
+ });
318
+
319
+ it('handles disabled actions', () => {
320
+ const disabledAction = [{
321
+ id: 'disabled',
322
+ label: 'Disabled',
323
+ priority: 1,
324
+ onClick: jest.fn(),
325
+ disabled: true,
326
+ destructive: false
327
+ }];
328
+
329
+ render(
330
+ <TestWrapper>
331
+ <PageBannerHeader
332
+ title="Disabled Action Test"
333
+ actions={disabledAction}
334
+ />
335
+ </TestWrapper>
336
+ );
337
+
338
+ const button = screen.getByText('Disabled');
339
+ expect(button).toBeDisabled();
340
+ });
341
+
342
+ it('renders without cover image', () => {
343
+ render(
344
+ <TestWrapper>
345
+ <PageBannerHeader
346
+ title="No Cover Image"
347
+ subtitle="Just title and subtitle"
348
+ />
349
+ </TestWrapper>
350
+ );
351
+
352
+ expect(screen.getByText('No Cover Image')).toBeInTheDocument();
353
+ expect(screen.getByText('Just title and subtitle')).toBeInTheDocument();
354
+ });
355
+
356
+ it('renders with tags as React nodes', () => {
357
+ const customTags = [
358
+ 'String Tag',
359
+ <span key="custom">Custom Tag</span>
360
+ ];
361
+
362
+ render(
363
+ <TestWrapper>
364
+ <PageBannerHeader
365
+ title="Custom Tags Test"
366
+ tags={customTags}
367
+ />
368
+ </TestWrapper>
369
+ );
370
+
371
+ expect(screen.getByText('Custom Tags Test')).toBeInTheDocument();
372
+ expect(screen.getByText('String Tag')).toBeInTheDocument();
373
+ expect(screen.getByText('Custom Tag')).toBeInTheDocument();
374
+ });
375
+ });
376
+
377
+ describe('Data Binding Usage', () => {
378
+ let dataProvider: JsonDataProvider;
379
+
380
+ beforeEach(() => {
381
+ dataProvider = new JsonDataProvider({ data: sampleCmsData });
382
+ });
383
+
384
+ it('renders with dataSource prop (about banner)', async () => {
385
+ render(
386
+ <TestWrapper dataProvider={dataProvider}>
387
+ <PageBannerHeader dataSource="pageBannerHeaders.aboutBanner" />
388
+ </TestWrapper>
389
+ );
390
+
391
+ await screen.findByText('QwickApps React Framework');
392
+ expect(screen.getByText('About Us')).toBeInTheDocument();
393
+ expect(screen.getByText('Building the future of web development')).toBeInTheDocument();
394
+ expect(screen.getByText('50+')).toBeInTheDocument();
395
+ expect(screen.getByText('Developers')).toBeInTheDocument();
396
+ expect(screen.getByText('React')).toBeInTheDocument();
397
+ });
398
+
399
+ it('renders with dataSource prop (team hero)', async () => {
400
+ render(
401
+ <TestWrapper dataProvider={dataProvider}>
402
+ <PageBannerHeader dataSource="pageBannerHeaders.teamHero" />
403
+ </TestWrapper>
404
+ );
405
+
406
+ await screen.findByText('Meet Our Team');
407
+ expect(screen.getByText('Passionate developers creating amazing software')).toBeInTheDocument();
408
+ });
409
+
410
+ it('shows loading state while data is loading', () => {
411
+ render(
412
+ <TestWrapper dataProvider={dataProvider}>
413
+ <PageBannerHeader dataSource="pageBannerHeaders.nonexistent" />
414
+ </TestWrapper>
415
+ );
416
+
417
+ expect(screen.getByText('Loading...')).toBeInTheDocument();
418
+ expect(screen.getByText('Loading page banner content...')).toBeInTheDocument();
419
+ });
420
+
421
+ it('shows loading state when dataSource does not exist', async () => {
422
+ render(
423
+ <TestWrapper dataProvider={dataProvider}>
424
+ <PageBannerHeader
425
+ dataSource="pageBannerHeaders.nonexistent"
426
+ title="Fallback Title"
427
+ subtitle="Fallback subtitle"
428
+ />
429
+ </TestWrapper>
430
+ );
431
+
432
+ // When dataSource doesn't exist, component shows loading state
433
+ expect(screen.getByText('Loading...')).toBeInTheDocument();
434
+ expect(screen.getByText('Loading page banner content...')).toBeInTheDocument();
435
+ });
436
+
437
+ it('handles minimal header from data', async () => {
438
+ render(
439
+ <TestWrapper dataProvider={dataProvider}>
440
+ <PageBannerHeader dataSource="pageBannerHeaders.minimalHeader" />
441
+ </TestWrapper>
442
+ );
443
+
444
+ await screen.findByText('Simple Header');
445
+ expect(screen.getByText('Clean and minimal design')).toBeInTheDocument();
446
+ });
447
+
448
+ it('works with custom binding options', async () => {
449
+ render(
450
+ <TestWrapper dataProvider={dataProvider}>
451
+ <PageBannerHeader
452
+ dataSource="pageBannerHeaders.aboutBanner"
453
+ bindingOptions={{ cache: false, strict: true }}
454
+ />
455
+ </TestWrapper>
456
+ );
457
+
458
+ await screen.findByText('QwickApps React Framework');
459
+ });
460
+
461
+ it('handles empty data from CMS', async () => {
462
+ render(
463
+ <TestWrapper dataProvider={dataProvider}>
464
+ <PageBannerHeader
465
+ dataSource="pageBannerHeaders.emptyData"
466
+ title="Fallback for Empty Data"
467
+ />
468
+ </TestWrapper>
469
+ );
470
+
471
+ await screen.findByText('Fallback for Empty Data');
472
+ });
473
+
474
+ it('shows error state in development mode', () => {
475
+ // Mock console.error to avoid test noise
476
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
477
+
478
+ // Mock process.env.NODE_ENV
479
+ const originalEnv = process.env.NODE_ENV;
480
+ process.env.NODE_ENV = 'development';
481
+
482
+ // Create an empty data provider which should cause loading/error state
483
+ const emptyDataProvider = new JsonDataProvider({ data: {} });
484
+
485
+ render(
486
+ <TestWrapper dataProvider={emptyDataProvider}>
487
+ <PageBannerHeader dataSource="pageBannerHeaders.nonexistentData" />
488
+ </TestWrapper>
489
+ );
490
+
491
+ // Should show loading initially, then fallback to null or show fallback content
492
+ expect(screen.getByText('Loading...')).toBeInTheDocument();
493
+
494
+ // Restore environment
495
+ process.env.NODE_ENV = originalEnv;
496
+ consoleSpy.mockRestore();
497
+ });
498
+
499
+ it('returns loading state when no data provider available', () => {
500
+ // Mock console.error to avoid test noise
501
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
502
+
503
+ // Mock process.env.NODE_ENV
504
+ const originalEnv = process.env.NODE_ENV;
505
+ process.env.NODE_ENV = 'production';
506
+
507
+ const emptyDataProvider = new JsonDataProvider({ data: {} });
508
+
509
+ const { container } = render(
510
+ <TestWrapper dataProvider={emptyDataProvider}>
511
+ <PageBannerHeader dataSource="pageBannerHeaders.nonexistentData" />
512
+ </TestWrapper>
513
+ );
514
+
515
+ // Should show loading state when data is not available
516
+ expect(screen.getByText('Loading...')).toBeInTheDocument();
517
+
518
+ // Restore environment
519
+ process.env.NODE_ENV = originalEnv;
520
+ consoleSpy.mockRestore();
521
+ });
522
+ });
523
+
524
+ describe('Edge Cases', () => {
525
+ it('handles empty metadata array', () => {
526
+ render(
527
+ <TestWrapper>
528
+ <PageBannerHeader
529
+ title="Empty Metadata"
530
+ metadata={[]}
531
+ />
532
+ </TestWrapper>
533
+ );
534
+
535
+ expect(screen.getByText('Empty Metadata')).toBeInTheDocument();
536
+ });
537
+
538
+ it('handles empty tags array', () => {
539
+ render(
540
+ <TestWrapper>
541
+ <PageBannerHeader
542
+ title="Empty Tags"
543
+ tags={[]}
544
+ />
545
+ </TestWrapper>
546
+ );
547
+
548
+ expect(screen.getByText('Empty Tags')).toBeInTheDocument();
549
+ });
550
+
551
+ it('handles empty actions array', () => {
552
+ render(
553
+ <TestWrapper>
554
+ <PageBannerHeader
555
+ title="Empty Actions"
556
+ actions={[]}
557
+ />
558
+ </TestWrapper>
559
+ );
560
+
561
+ expect(screen.getByText('Empty Actions')).toBeInTheDocument();
562
+ });
563
+
564
+ it('handles long title text', () => {
565
+ const longTitle = 'Very '.repeat(20) + 'Long Title That Should Handle Wrapping Properly';
566
+
567
+ render(
568
+ <TestWrapper>
569
+ <PageBannerHeader title={longTitle} />
570
+ </TestWrapper>
571
+ );
572
+
573
+ expect(screen.getByText(longTitle)).toBeInTheDocument();
574
+ });
575
+
576
+ it('handles special characters in content', () => {
577
+ render(
578
+ <TestWrapper>
579
+ <PageBannerHeader
580
+ title="Special: &lt;&gt;&amp;&quot;&apos;"
581
+ subtitle="Content with special chars: &amp; &lt; &gt;"
582
+ />
583
+ </TestWrapper>
584
+ );
585
+
586
+ expect(screen.getByText(/Special:/, { exact: false })).toBeInTheDocument();
587
+ expect(screen.getByText(/Content with special chars:/, { exact: false })).toBeInTheDocument();
588
+ });
589
+
590
+ it('handles custom CSS classes and styles', () => {
591
+ const { container } = render(
592
+ <TestWrapper>
593
+ <PageBannerHeader
594
+ title="Custom Styled"
595
+ className="custom-header"
596
+ sx={{ border: '1px solid red' }}
597
+ />
598
+ </TestWrapper>
599
+ );
600
+
601
+ expect(screen.getByText('Custom Styled')).toBeInTheDocument();
602
+ });
603
+
604
+ it('renders without optional props', () => {
605
+ render(
606
+ <TestWrapper>
607
+ <PageBannerHeader title="Minimal Props" />
608
+ </TestWrapper>
609
+ );
610
+
611
+ expect(screen.getByText('Minimal Props')).toBeInTheDocument();
612
+ });
613
+ });
614
+ });