@qwickapps/react-framework 1.5.6 → 1.5.8

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 (121) hide show
  1. package/dist/components/AccessibilityChecker.d.ts.map +1 -1
  2. package/dist/components/Html.d.ts +1 -1
  3. package/dist/components/Html.d.ts.map +1 -1
  4. package/dist/components/Logo.d.ts.map +1 -1
  5. package/dist/components/Markdown.d.ts +2 -2
  6. package/dist/components/Markdown.d.ts.map +1 -1
  7. package/dist/components/QwickApp.d.ts.map +1 -1
  8. package/dist/components/SafeSpan.d.ts +1 -1
  9. package/dist/components/SafeSpan.d.ts.map +1 -1
  10. package/dist/components/base/ModelView.d.ts +1 -1
  11. package/dist/components/base/ModelView.d.ts.map +1 -1
  12. package/dist/components/blocks/Article.d.ts +1 -1
  13. package/dist/components/blocks/Article.d.ts.map +1 -1
  14. package/dist/components/blocks/CardListGrid.d.ts.map +1 -1
  15. package/dist/components/blocks/Code.d.ts.map +1 -1
  16. package/dist/components/blocks/Content.d.ts.map +1 -1
  17. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
  18. package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
  19. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
  20. package/dist/components/blocks/Footer.d.ts.map +1 -1
  21. package/dist/components/blocks/Image.d.ts.map +1 -1
  22. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
  23. package/dist/components/blocks/ProductCard.d.ts.map +1 -1
  24. package/dist/components/blocks/Section.d.ts.map +1 -1
  25. package/dist/components/blocks/Text.d.ts +8 -1
  26. package/dist/components/blocks/Text.d.ts.map +1 -1
  27. package/dist/components/buttons/Button.d.ts.map +1 -1
  28. package/dist/components/buttons/PaletteSwitcher.d.ts.map +1 -1
  29. package/dist/components/buttons/ThemeSwitcher.d.ts.map +1 -1
  30. package/dist/components/forms/FormBlock.d.ts +1 -1
  31. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  32. package/dist/components/forms/SchemaFormRenderer.d.ts +28 -0
  33. package/dist/components/forms/SchemaFormRenderer.d.ts.map +1 -0
  34. package/dist/components/forms/index.d.ts +2 -0
  35. package/dist/components/forms/index.d.ts.map +1 -1
  36. package/dist/components/index.d.ts +1 -0
  37. package/dist/components/index.d.ts.map +1 -1
  38. package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
  39. package/dist/components/input/HtmlInputField.d.ts.map +1 -1
  40. package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts.map +1 -1
  41. package/dist/components/layout/GridLayout.d.ts +5 -0
  42. package/dist/components/layout/GridLayout.d.ts.map +1 -1
  43. package/dist/components/plugins/DataTable.d.ts +57 -0
  44. package/dist/components/plugins/DataTable.d.ts.map +1 -0
  45. package/dist/components/plugins/StatCard.d.ts +44 -0
  46. package/dist/components/plugins/StatCard.d.ts.map +1 -0
  47. package/dist/components/plugins/index.d.ts +13 -0
  48. package/dist/components/plugins/index.d.ts.map +1 -0
  49. package/dist/components/shared/createSerializableView.d.ts.map +1 -1
  50. package/dist/contexts/NavigationContext.d.ts.map +1 -1
  51. package/dist/hooks/useBaseProps.d.ts +1 -1
  52. package/dist/hooks/useBaseProps.d.ts.map +1 -1
  53. package/dist/index.esm.js +5939 -5532
  54. package/dist/index.js +6028 -5618
  55. package/dist/palettes/manifest.json +19 -19
  56. package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -1
  57. package/dist/utils/iconMap.d.ts +21 -8
  58. package/dist/utils/iconMap.d.ts.map +1 -1
  59. package/package.json +1 -2
  60. package/src/__tests__/utils/iconMap.test.tsx +197 -0
  61. package/src/components/AccessibilityChecker.tsx +10 -7
  62. package/src/components/ErrorBoundary.tsx +3 -3
  63. package/src/components/Html.tsx +17 -12
  64. package/src/components/Logo.tsx +1 -8
  65. package/src/components/Markdown.tsx +10 -10
  66. package/src/components/QwickApp.tsx +8 -1
  67. package/src/components/ResponsiveMenu.tsx +1 -1
  68. package/src/components/SafeSpan.tsx +9 -9
  69. package/src/components/Scaffold.tsx +4 -4
  70. package/src/components/base/ModelView.tsx +2 -2
  71. package/src/components/blocks/Article.tsx +7 -7
  72. package/src/components/blocks/CardListGrid.tsx +1 -3
  73. package/src/components/blocks/Code.tsx +10 -8
  74. package/src/components/blocks/Content.tsx +2 -4
  75. package/src/components/blocks/CoverImageHeader.tsx +3 -4
  76. package/src/components/blocks/FeatureCard.tsx +2 -4
  77. package/src/components/blocks/FeatureGrid.tsx +2 -4
  78. package/src/components/blocks/Footer.tsx +2 -4
  79. package/src/components/blocks/Image.tsx +8 -5
  80. package/src/components/blocks/PageBannerHeader.tsx +3 -4
  81. package/src/components/blocks/ProductCard.tsx +8 -5
  82. package/src/components/blocks/Section.tsx +6 -4
  83. package/src/components/blocks/Text.tsx +15 -7
  84. package/src/components/buttons/Button.tsx +8 -6
  85. package/src/components/buttons/PaletteSwitcher.tsx +6 -8
  86. package/src/components/buttons/ThemeSwitcher.tsx +8 -9
  87. package/src/components/forms/Captcha.tsx +1 -1
  88. package/src/components/forms/FormBlock.tsx +3 -5
  89. package/src/components/forms/FormCheckbox.tsx +1 -1
  90. package/src/components/forms/FormField.tsx +1 -1
  91. package/src/components/forms/FormSelect.tsx +1 -1
  92. package/src/components/forms/SchemaFormRenderer.tsx +268 -0
  93. package/src/components/forms/__tests__/SchemaFormRenderer.test.tsx +212 -0
  94. package/src/components/forms/index.ts +3 -0
  95. package/src/components/index.ts +1 -0
  96. package/src/components/input/ChoiceInputField.tsx +2 -1
  97. package/src/components/input/HtmlInputField.tsx +14 -9
  98. package/src/components/input/TextField.tsx +1 -1
  99. package/src/components/layout/CollapsibleLayout/CollapsibleLayout.tsx +6 -8
  100. package/src/components/layout/GridLayout.tsx +4 -0
  101. package/src/components/plugins/DataTable.tsx +259 -0
  102. package/src/components/plugins/StatCard.tsx +122 -0
  103. package/src/components/plugins/__tests__/DataTable.test.tsx +158 -0
  104. package/src/components/plugins/index.ts +14 -0
  105. package/src/components/shared/createSerializableView.tsx +8 -6
  106. package/src/contexts/NavigationContext.tsx +21 -15
  107. package/src/hooks/useBaseProps.ts +1 -1
  108. package/src/schemas/transformers/ReactNodeTransformer.ts +13 -10
  109. package/src/utils/iconMap.tsx +290 -174
  110. /package/dist/palettes/{palette-autumn.1.5.6.css → palette-autumn.1.5.8.css} +0 -0
  111. /package/dist/palettes/{palette-autumn.1.5.6.min.css → palette-autumn.1.5.8.min.css} +0 -0
  112. /package/dist/palettes/{palette-cosmic.1.5.6.css → palette-cosmic.1.5.8.css} +0 -0
  113. /package/dist/palettes/{palette-cosmic.1.5.6.min.css → palette-cosmic.1.5.8.min.css} +0 -0
  114. /package/dist/palettes/{palette-default.1.5.6.css → palette-default.1.5.8.css} +0 -0
  115. /package/dist/palettes/{palette-default.1.5.6.min.css → palette-default.1.5.8.min.css} +0 -0
  116. /package/dist/palettes/{palette-ocean.1.5.6.css → palette-ocean.1.5.8.css} +0 -0
  117. /package/dist/palettes/{palette-ocean.1.5.6.min.css → palette-ocean.1.5.8.min.css} +0 -0
  118. /package/dist/palettes/{palette-spring.1.5.6.css → palette-spring.1.5.8.css} +0 -0
  119. /package/dist/palettes/{palette-spring.1.5.6.min.css → palette-spring.1.5.8.min.css} +0 -0
  120. /package/dist/palettes/{palette-winter.1.5.6.css → palette-winter.1.5.8.css} +0 -0
  121. /package/dist/palettes/{palette-winter.1.5.6.min.css → palette-winter.1.5.8.min.css} +0 -0
@@ -21,7 +21,7 @@ import { useQwickApp } from '../contexts/QwickAppContext';
21
21
  import Logo from './Logo';
22
22
  import ThemeSwitcher from './buttons/ThemeSwitcher';
23
23
  import PaletteSwitcher from './buttons/PaletteSwitcher';
24
- import { RadioButtonUnchecked as DefaultIcon } from '@mui/icons-material';
24
+ // DefaultIcon removed - using iconMap radio_button_unchecked instead
25
25
  import { getIconComponent } from './buttons/Button';
26
26
  import './Scaffold.css';
27
27
  import { useNavigation } from '../contexts/NavigationContext';
@@ -260,21 +260,21 @@ const Scaffold: React.FC<ScaffoldProps> = ({
260
260
  }
261
261
  };
262
262
 
263
- // Transform icon string to component, or use provided ReactNode, or fallback to DefaultIcon
263
+ // Transform icon string to component, or use provided ReactNode, or fallback to radio_button_unchecked
264
264
  const needsIcon = variant !== 'drawer';
265
265
  let displayIcon: React.ReactNode = null;
266
266
 
267
267
  if (item.icon) {
268
268
  // If icon is a string, transform it to component
269
269
  if (typeof item.icon === 'string') {
270
- displayIcon = getIconComponent(item.icon) || (needsIcon ? <DefaultIcon /> : null);
270
+ displayIcon = getIconComponent(item.icon) || (needsIcon ? getIconComponent('radio_button_unchecked') : null);
271
271
  } else {
272
272
  // If icon is already a React component, use it
273
273
  displayIcon = item.icon;
274
274
  }
275
275
  } else if (needsIcon) {
276
276
  // No icon provided, use default for primary navigation
277
- displayIcon = <DefaultIcon />;
277
+ displayIcon = getIconComponent('radio_button_unchecked');
278
278
  }
279
279
 
280
280
  const content = (
@@ -295,7 +295,7 @@ export abstract class ModelView<TProps = Record<string, unknown>>
295
295
  * Helper function for creating ModelView component classes with ViewSchema support
296
296
  * Updated to work with the new ViewSchema processing system
297
297
  */
298
- export function createModelViewClass<TProps, TModel>(
298
+ export function createModelViewClass<TProps>(
299
299
  config: {
300
300
  tagName: string;
301
301
  version: string;
@@ -306,7 +306,7 @@ export function createModelViewClass<TProps, TModel>(
306
306
  }
307
307
  ): unknown {
308
308
 
309
- class DynamicModelView extends ModelView<TProps, TModel> {
309
+ class DynamicModelView extends ModelView<TProps> {
310
310
  static readonly tagName = config.tagName;
311
311
  static readonly version = config.version;
312
312
 
@@ -39,7 +39,7 @@ function ArticleView({
39
39
  const { styleProps, htmlProps, restProps: otherProps } = useBaseProps(restProps);
40
40
 
41
41
  // Mark as QwickApp component
42
- (ArticleView as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
42
+ Object.assign(ArticleView, { [QWICKAPP_COMPONENT]: true });
43
43
 
44
44
  // Return empty state if no HTML content
45
45
  if (!html.trim()) {
@@ -336,7 +336,7 @@ function ArticleView({
336
336
  }
337
337
 
338
338
  // Main component with data binding support and serialization capability
339
- export class Article extends ModelView<ArticleProps, ArticleModel> {
339
+ export class Article extends ModelView<ArticleProps> {
340
340
  // Component self-declaration for serialization
341
341
  static readonly tagName = 'Article';
342
342
  static readonly version = '1.0.0';
@@ -362,9 +362,11 @@ export class Article extends ModelView<ArticleProps, ArticleModel> {
362
362
 
363
363
  // Register HTML patterns that Article component can handle
364
364
  static registerPatternHandlers(registry: unknown): void {
365
+ const typedRegistry = registry as { hasPattern?: (pattern: string) => boolean; registerPattern?: (pattern: string, handler: (element: Element) => Record<string, unknown>) => void };
366
+
365
367
  // Register article elements
366
- if (!registry.hasPattern('article')) {
367
- registry.registerPattern('article', Article.transformArticle);
368
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('article')) {
369
+ typedRegistry.registerPattern?.('article', Article.transformArticle);
368
370
  }
369
371
  }
370
372
 
@@ -389,9 +391,7 @@ function ArticleWithDataBinding(props: ArticleProps) {
389
391
  // Use data binding
390
392
  const { loading, error, ...articleProps } = useDataBinding<ArticleModel>(
391
393
  dataSource!,
392
- restProps as Partial<ArticleModel>,
393
- ArticleModel.getSchema(),
394
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
394
+ restProps as Partial<ArticleModel>
395
395
  );
396
396
 
397
397
  // Show loading state
@@ -87,9 +87,7 @@ function CardListGrid(props: CardListGridProps) {
87
87
  // Always call hooks unconditionally
88
88
  const result = useDataBinding<CardListGridModel>(
89
89
  dataSource || '',
90
- restProps as Partial<CardListGridModel>,
91
- CardListGridModel.getSchema(),
92
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
90
+ restProps as Partial<CardListGridModel>
93
91
  );
94
92
 
95
93
  // If no dataSource, use traditional props
@@ -22,7 +22,10 @@
22
22
 
23
23
  import React, { useState } from 'react';
24
24
  import { Box, Typography, Tooltip, IconButton, Snackbar, Alert, useTheme, Paper } from '@mui/material';
25
- import { ContentCopy as CopyIcon, Check as CheckIcon } from '@mui/icons-material';
25
+ import ContentCopy from '@mui/icons-material/ContentCopy';
26
+ import Check from '@mui/icons-material/Check';
27
+ const CopyIcon = ContentCopy;
28
+ const CheckIcon = Check;
26
29
  import CodeSchema from '../../schemas/CodeSchema';
27
30
  import type { SchemaProps } from '@qwickapps/schema/src/types/ModelProps';
28
31
  import { ViewProps } from '../shared/viewProps';
@@ -260,17 +263,16 @@ export const Code: SerializableComponent<CodeProps> = createSerializableView<Cod
260
263
 
261
264
  // Register HTML patterns that Code component can handle
262
265
  (Code as Record<string, unknown>).registerPatternHandlers = (registry: Record<string, (...args: unknown[]) => unknown>): void => {
266
+ const typedRegistry = registry as { hasPattern?: (pattern: string) => boolean; registerPattern?: (pattern: string, handler: (...args: unknown[]) => unknown) => void };
267
+
263
268
  // Register pre + code pattern
264
- if (!registry.hasPattern) {
265
- return;
266
- }
267
- if (!registry.hasPattern('pre code')) {
268
- registry.registerPattern('pre code', (Code as Record<string, unknown>).transformPreCode as (...args: unknown[]) => unknown);
269
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('pre code')) {
270
+ typedRegistry.registerPattern?.('pre code', (Code as Record<string, unknown>).transformPreCode as (...args: unknown[]) => unknown);
269
271
  }
270
272
 
271
273
  // Register standalone code pattern for complex code blocks
272
- if (!registry.hasPattern('code.highlight')) {
273
- registry.registerPattern('code.highlight', (Code as Record<string, unknown>).transformCodeHighlight as (...args: unknown[]) => unknown);
274
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('code.highlight')) {
275
+ typedRegistry.registerPattern?.('code.highlight', (Code as Record<string, unknown>).transformCodeHighlight as (...args: unknown[]) => unknown);
274
276
  }
275
277
  };
276
278
 
@@ -45,7 +45,7 @@ function ContentView({
45
45
  const theme = useTheme();
46
46
 
47
47
  // Mark as QwickApp component
48
- (ContentView as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
48
+ Object.assign(ContentView, { [QWICKAPP_COMPONENT]: true });
49
49
 
50
50
  // Map spacing to padding values
51
51
  const getPadding = () => {
@@ -170,9 +170,7 @@ function Content(props: ContentProps) {
170
170
  // Always call hooks unconditionally
171
171
  const bindingResult = useDataBinding<ContentModel>(
172
172
  dataSource || '',
173
- restProps as Partial<ContentModel>,
174
- ContentModel.getSchema(),
175
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
173
+ restProps as Partial<ContentModel>
176
174
  );
177
175
 
178
176
  // If no dataSource, use traditional props
@@ -11,7 +11,8 @@
11
11
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
12
12
  */
13
13
 
14
- import { MoreVert as MoreIcon } from '@mui/icons-material';
14
+ import MoreVert from "@mui/icons-material/MoreVert";
15
+ const MoreIcon = MoreVert;
15
16
  import {
16
17
  Avatar,
17
18
  Box,
@@ -401,9 +402,7 @@ function CoverImageHeader(props: CoverImageHeaderProps) {
401
402
  // Always call hooks unconditionally
402
403
  const bindingResult = useDataBinding<CoverImageHeaderModel>(
403
404
  dataSource || '',
404
- restProps as Partial<CoverImageHeaderModel>,
405
- CoverImageHeaderModel.getSchema(),
406
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
405
+ restProps as Partial<CoverImageHeaderModel>
407
406
  );
408
407
 
409
408
  // If no dataSource, use traditional props
@@ -260,14 +260,12 @@ function FeatureCard(props: FeatureCardProps) {
260
260
  const { dataSource, bindingOptions, ...restProps } = props;
261
261
 
262
262
  // Mark as QwickApp component
263
- (FeatureCard as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
263
+ Object.assign(FeatureCard, { [QWICKAPP_COMPONENT]: true });
264
264
 
265
265
  // Always call hooks unconditionally
266
266
  const bindingResult = useDataBinding<FeatureCardModel>(
267
267
  dataSource || '',
268
- restProps as Partial<FeatureCardModel>,
269
- FeatureCardModel.getSchema(),
270
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
268
+ restProps as Partial<FeatureCardModel>
271
269
  );
272
270
 
273
271
  // If no dataSource, use traditional props
@@ -64,7 +64,7 @@ function FeatureGridView({
64
64
  const { styleProps, htmlProps } = useBaseProps(restProps);
65
65
 
66
66
  // Mark as QwickApp component
67
- (FeatureGridView as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
67
+ Object.assign(FeatureGridView, { [QWICKAPP_COMPONENT]: true });
68
68
 
69
69
  // Map gap to spacing value for GridLayout
70
70
  const getSpacing = (): 'none' | 'tiny' | 'small' | 'medium' | 'large' | 'huge' => {
@@ -95,9 +95,7 @@ function FeatureGrid(props: FeatureGridProps) {
95
95
  // Always call hooks unconditionally
96
96
  const bindingResult = useDataBinding<FeatureGridModel>(
97
97
  dataSource || '',
98
- restProps as Partial<FeatureGridModel>,
99
- FeatureGridModel.getSchema(),
100
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
98
+ restProps as Partial<FeatureGridModel>
101
99
  );
102
100
 
103
101
  // If no dataSource, use traditional props
@@ -81,7 +81,7 @@ function FooterView({
81
81
  const { gridProps, styleProps, htmlProps } = useBaseProps(restProps);
82
82
 
83
83
  // Mark as QwickApp component
84
- (FooterView as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
84
+ Object.assign(FooterView, { [QWICKAPP_COMPONENT]: true });
85
85
  const theme = useTheme();
86
86
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));
87
87
 
@@ -292,9 +292,7 @@ function Footer(props: FooterProps) {
292
292
  // Always call hooks unconditionally
293
293
  const bindingResult = useDataBinding<FooterModel>(
294
294
  dataSource || '',
295
- restProps as Partial<FooterModel>,
296
- FooterModel.getSchema(),
297
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
295
+ restProps as Partial<FooterModel>
298
296
  );
299
297
 
300
298
  // If no dataSource, use traditional props
@@ -17,7 +17,8 @@
17
17
 
18
18
  import React, { useState, useCallback } from 'react';
19
19
  import { Box, Skeleton, Typography, useTheme } from '@mui/material';
20
- import { BrokenImage as BrokenImageIcon } from '@mui/icons-material';
20
+ import BrokenImage from "@mui/icons-material/BrokenImage";
21
+ const BrokenImageIcon = BrokenImage;
21
22
  import { ImageFit, ImageLoading, ImagePosition } from '../../schemas/ImageSchema';
22
23
  import { createSerializableView, SerializableComponent } from '../shared/createSerializableView';
23
24
  import { ViewProps } from '../shared/viewProps';
@@ -231,14 +232,16 @@ interface PatternRegistry {
231
232
 
232
233
  // Register HTML patterns that Image component can handle
233
234
  (Image as unknown as { registerPatternHandlers: (registry: PatternRegistry) => void }).registerPatternHandlers = (registry: PatternRegistry): void => {
235
+ const typedRegistry = registry as { hasPattern?: (pattern: string) => boolean; registerPattern?: (pattern: string, handler: (element: Element) => Record<string, unknown>) => void };
236
+
234
237
  // Register img elements
235
- if (!registry.hasPattern('img')) {
236
- registry.registerPattern('img', transformImage);
238
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('img')) {
239
+ typedRegistry.registerPattern?.('img', transformImage);
237
240
  }
238
241
 
239
242
  // Register figure elements with img
240
- if (!registry.hasPattern('figure img')) {
241
- registry.registerPattern('figure img', transformFigureImage);
243
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('figure img')) {
244
+ typedRegistry.registerPattern?.('figure img', transformFigureImage);
242
245
  }
243
246
  };
244
247
 
@@ -12,7 +12,8 @@
12
12
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
13
13
  */
14
14
 
15
- import { MoreVert as MoreIcon } from '@mui/icons-material';
15
+ import MoreVert from "@mui/icons-material/MoreVert";
16
+ const MoreIcon = MoreVert;
16
17
  import {
17
18
  Avatar,
18
19
  Box,
@@ -387,9 +388,7 @@ function PageBannerHeader(props: PageBannerHeaderProps) {
387
388
  // Always call hooks unconditionally
388
389
  const bindingResult = useDataBinding<PageBannerHeaderModel>(
389
390
  dataSource || '',
390
- restProps as Partial<PageBannerHeaderModel>,
391
- PageBannerHeaderModel.getSchema(),
392
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
391
+ restProps as Partial<PageBannerHeaderModel>
393
392
  );
394
393
 
395
394
  // If no dataSource, use traditional props
@@ -10,7 +10,12 @@
10
10
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
11
11
  */
12
12
 
13
- import { Schedule as ComingSoonIcon, Launch as LaunchIcon, Visibility as PreviewIcon } from '@mui/icons-material';
13
+ import Schedule from '@mui/icons-material/Schedule';
14
+ import Launch from '@mui/icons-material/Launch';
15
+ import Visibility from '@mui/icons-material/Visibility';
16
+ const ComingSoonIcon = Schedule;
17
+ const LaunchIcon = Launch;
18
+ const PreviewIcon = Visibility;
14
19
  import {
15
20
  Box,
16
21
  Chip,
@@ -406,14 +411,12 @@ function ProductCard(props: ProductCardProps) {
406
411
  const { dataSource, bindingOptions, ...restProps } = props;
407
412
 
408
413
  // Mark as QwickApp component
409
- (ProductCard as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
414
+ Object.assign(ProductCard, { [QWICKAPP_COMPONENT]: true });
410
415
 
411
416
  // Always call hooks unconditionally
412
417
  const bindingResult = useDataBinding<ProductCardModel>(
413
418
  dataSource || '',
414
- restProps as Partial<ProductCardModel>,
415
- ProductCardModel.getSchema(),
416
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
419
+ restProps as Partial<ProductCardModel>
417
420
  );
418
421
 
419
422
  // If no dataSource, use traditional props
@@ -168,14 +168,16 @@ interface PatternRegistry {
168
168
 
169
169
  // Register HTML patterns that Section component can handle
170
170
  (Section as unknown as { registerPatternHandlers: (registry: PatternRegistry) => void }).registerPatternHandlers = (registry: PatternRegistry): void => {
171
+ const typedRegistry = registry as { hasPattern?: (pattern: string) => boolean; registerPattern?: (pattern: string, handler: (element: Element) => Record<string, unknown>) => void };
172
+
171
173
  // Register section element pattern
172
- if (!registry.hasPattern('section')) {
173
- registry.registerPattern('section', (Section as unknown as { transformSection: (element: Element) => unknown }).transformSection);
174
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('section')) {
175
+ typedRegistry.registerPattern?.('section', (Section as unknown as { transformSection: (element: Element) => unknown }).transformSection);
174
176
  }
175
177
 
176
178
  // Register section with specific classes
177
- if (!registry.hasPattern('section.blog-section')) {
178
- registry.registerPattern('section.blog-section', (Section as unknown as { transformBlogSection: (element: Element) => unknown }).transformBlogSection);
179
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('section.blog-section')) {
180
+ typedRegistry.registerPattern?.('section.blog-section', (Section as unknown as { transformBlogSection: (element: Element) => unknown }).transformBlogSection);
179
181
  }
180
182
  };
181
183
 
@@ -25,8 +25,14 @@ import type { SchemaProps } from '@qwickapps/schema/src/types/ModelProps';
25
25
  /**
26
26
  * Props interface for Text component
27
27
  * Uses SchemaProps<typeof TextSchema> for clean typing
28
+ * Explicitly includes sx and style for type resolution
28
29
  */
29
- export type TextProps = ViewProps & SchemaProps<typeof TextSchema>;
30
+ export type TextProps = ViewProps & SchemaProps<typeof TextSchema> & {
31
+ /** MUI sx prop for advanced styling (explicit override for type resolution) */
32
+ sx?: import('@mui/material/styles').SxProps<import('@mui/material/styles').Theme>;
33
+ /** Inline CSS styles (explicit override for type resolution) */
34
+ style?: React.CSSProperties;
35
+ };
30
36
 
31
37
  /**
32
38
  * TextView - Pure view component that renders the typography
@@ -130,24 +136,26 @@ interface TextComponentWithPatterns {
130
136
 
131
137
  // Register HTML patterns that Text component can handle
132
138
  (Text as unknown as TextComponentWithPatterns).registerPatternHandlers = (registry: PatternRegistry): void => {
139
+ const typedRegistry = registry as { hasPattern?: (pattern: string) => boolean; registerPattern?: (pattern: string, handler: (element: Element) => Record<string, unknown>) => void };
133
140
  const textComponent = Text as unknown as TextComponentWithPatterns;
134
141
 
135
142
  // Register paragraph elements
136
- if (!registry.hasPattern('p')) {
137
- registry.registerPattern('p', textComponent.transformParagraph);
143
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('p')) {
144
+ typedRegistry.registerPattern?.('p', textComponent.transformParagraph);
138
145
  }
139
146
 
140
147
  // Register heading elements
141
148
  const headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
142
149
  headings.forEach(heading => {
143
- if (!registry.hasPattern(heading)) {
144
- registry.registerPattern(heading, (element: Element) => textComponent.transformHeading(element, heading));
150
+
151
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern(heading)) {
152
+ typedRegistry.registerPattern?.(heading, (element: Element) => textComponent.transformHeading(element, heading));
145
153
  }
146
154
  });
147
155
 
148
156
  // Register span elements
149
- if (!registry.hasPattern('span')) {
150
- registry.registerPattern('span', textComponent.transformSpan);
157
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('span')) {
158
+ typedRegistry.registerPattern?.('span', textComponent.transformSpan);
151
159
  }
152
160
  };
153
161
 
@@ -311,19 +311,21 @@ export const Button: SerializableComponent<ButtonProps> = createSerializableView
311
311
 
312
312
  // Register HTML patterns that Button component can handle
313
313
  (Button as Record<string, unknown>).registerPatternHandlers = (registry: Record<string, (...args: unknown[]) => unknown>): void => {
314
+ const typedRegistry = registry as { hasPattern?: (pattern: string) => boolean; registerPattern?: (pattern: string, handler: (element: Element) => Record<string, unknown>) => void };
315
+
314
316
  // Register button elements
315
- if (!registry.hasPattern('button')) {
316
- registry.registerPattern('button', transformButton);
317
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('button')) {
318
+ typedRegistry.registerPattern?.('button', transformButton);
317
319
  }
318
320
 
319
321
  // Register input type="button" elements
320
- if (!registry.hasPattern('input[type="button"]')) {
321
- registry.registerPattern('input[type="button"]', transformInputButton);
322
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('input[type="button"]')) {
323
+ typedRegistry.registerPattern?.('input[type="button"]', transformInputButton);
322
324
  }
323
325
 
324
326
  // Register input type="submit" elements
325
- if (!registry.hasPattern('input[type="submit"]')) {
326
- registry.registerPattern('input[type="submit"]', transformSubmitButton);
327
+ if (typedRegistry.hasPattern && !typedRegistry.hasPattern('input[type="submit"]')) {
328
+ typedRegistry.registerPattern?.('input[type="submit"]', transformSubmitButton);
327
329
  }
328
330
  };
329
331
 
@@ -11,10 +11,10 @@
11
11
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
12
12
  */
13
13
 
14
- import {
15
- Palette as PaletteIcon,
16
- Circle as CircleIcon,
17
- } from '@mui/icons-material';
14
+ import Palette from '@mui/icons-material/Palette';
15
+ import Circle from '@mui/icons-material/Circle';
16
+ const PaletteIcon = Palette;
17
+ const CircleIcon = Circle;
18
18
  import {
19
19
  IconButton,
20
20
  Menu,
@@ -210,9 +210,7 @@ function PaletteSwitcher(props: PaletteSwitcherProps) {
210
210
  // Always call hooks unconditionally
211
211
  const bindingResult = useDataBinding<PaletteSwitcherModel>(
212
212
  dataSource || '',
213
- restProps as Partial<PaletteSwitcherModel>,
214
- PaletteSwitcherModel.getSchema(),
215
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
213
+ restProps as Partial<PaletteSwitcherModel>
216
214
  );
217
215
 
218
216
  // If no dataSource, use traditional props
@@ -266,6 +264,6 @@ function PaletteSwitcher(props: PaletteSwitcherProps) {
266
264
  }
267
265
 
268
266
  // Mark as QwickApp component
269
- (PaletteSwitcher as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
267
+ Object.assign(PaletteSwitcher, { [QWICKAPP_COMPONENT]: true });
270
268
 
271
269
  export default PaletteSwitcher;
@@ -21,11 +21,12 @@ import {
21
21
  Tooltip,
22
22
  Typography
23
23
  } from '@mui/material';
24
- import {
25
- DarkMode as DarkModeIcon,
26
- LightMode as LightModeIcon,
27
- SettingsSystemDaydream as SystemIcon
28
- } from '@mui/icons-material';
24
+ import DarkMode from '@mui/icons-material/DarkMode';
25
+ import LightMode from '@mui/icons-material/LightMode';
26
+ import SettingsSystemDaydream from '@mui/icons-material/SettingsSystemDaydream';
27
+ const DarkModeIcon = DarkMode;
28
+ const LightModeIcon = LightMode;
29
+ const SystemIcon = SettingsSystemDaydream;
29
30
  import type { WithDataBinding, SchemaProps } from '@qwickapps/schema';
30
31
  import { useState } from 'react';
31
32
  import { useTheme } from '../../contexts/ThemeContext';
@@ -235,9 +236,7 @@ function ThemeSwitcher(props: ThemeSwitcherProps) {
235
236
  // Always call hooks unconditionally
236
237
  const bindingResult = useDataBinding<ThemeSwitcherModel>(
237
238
  dataSource || '',
238
- restProps as Partial<ThemeSwitcherModel>,
239
- ThemeSwitcherModel.getSchema(),
240
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
239
+ restProps as Partial<ThemeSwitcherModel>
241
240
  );
242
241
 
243
242
  // If no dataSource, use traditional props
@@ -282,6 +281,6 @@ function ThemeSwitcher(props: ThemeSwitcherProps) {
282
281
  }
283
282
 
284
283
  // Mark as QwickApp component
285
- (ThemeSwitcher as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
284
+ Object.assign(ThemeSwitcher, { [QWICKAPP_COMPONENT]: true });
286
285
 
287
286
  export default ThemeSwitcher;
@@ -286,6 +286,6 @@ export const Captcha = React.forwardRef<HTMLDivElement, CaptchaProps>((props, re
286
286
  Captcha.displayName = 'Captcha';
287
287
 
288
288
  // Mark as QwickApp component
289
- (Captcha as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
289
+ Object.assign(Captcha, { [QWICKAPP_COMPONENT]: true });
290
290
 
291
291
  export default Captcha;
@@ -225,7 +225,7 @@ function FormBlockView({
225
225
  }
226
226
 
227
227
  // Main component with data binding support and serialization capability
228
- export class FormBlock extends ModelView<FormBlockProps, FormBlockModel> {
228
+ export class FormBlock extends ModelView<FormBlockProps> {
229
229
  // Component self-declaration for serialization
230
230
  static readonly tagName = 'FormBlock';
231
231
  static readonly version = '1.0.0';
@@ -298,9 +298,7 @@ function FormBlockWithDataBinding(props: FormBlockProps) {
298
298
  // Use data binding
299
299
  const { loading, error, ...formBlockProps } = useDataBinding<FormBlockModel>(
300
300
  dataSource!,
301
- restProps as Partial<FormBlockModel>,
302
- FormBlockModel.getSchema(),
303
- { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
301
+ restProps as Partial<FormBlockModel>
304
302
  );
305
303
 
306
304
  // Show loading state
@@ -346,6 +344,6 @@ function FormBlockWithDataBinding(props: FormBlockProps) {
346
344
  }
347
345
 
348
346
  // Mark as QwickApp component
349
- (FormBlock as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
347
+ Object.assign(FormBlock, { [QWICKAPP_COMPONENT]: true });
350
348
 
351
349
  export default FormBlock;
@@ -111,6 +111,6 @@ export const FormCheckbox = React.forwardRef<HTMLDivElement, FormCheckboxProps>(
111
111
  FormCheckbox.displayName = 'FormCheckbox';
112
112
 
113
113
  // Mark as QwickApp component
114
- (FormCheckbox as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
114
+ Object.assign(FormCheckbox, { [QWICKAPP_COMPONENT]: true });
115
115
 
116
116
  export default FormCheckbox;
@@ -175,6 +175,6 @@ export const FormField = React.forwardRef<HTMLDivElement, FormFieldProps>((props
175
175
  FormField.displayName = 'FormField';
176
176
 
177
177
  // Mark as QwickApp component
178
- (FormField as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
178
+ Object.assign(FormField, { [QWICKAPP_COMPONENT]: true });
179
179
 
180
180
  export default FormField;
@@ -135,6 +135,6 @@ export const FormSelect = React.forwardRef<HTMLDivElement, FormSelectProps>((pro
135
135
  FormSelect.displayName = 'FormSelect';
136
136
 
137
137
  // Mark as QwickApp component
138
- (FormSelect as Record<string, unknown>)[QWICKAPP_COMPONENT] = true;
138
+ Object.assign(FormSelect, { [QWICKAPP_COMPONENT]: true });
139
139
 
140
140
  export default FormSelect;