@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.
- package/dist/components/AccessibilityChecker.d.ts.map +1 -1
- package/dist/components/Html.d.ts +1 -1
- package/dist/components/Html.d.ts.map +1 -1
- package/dist/components/Logo.d.ts.map +1 -1
- package/dist/components/Markdown.d.ts +2 -2
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/QwickApp.d.ts.map +1 -1
- package/dist/components/SafeSpan.d.ts +1 -1
- package/dist/components/SafeSpan.d.ts.map +1 -1
- package/dist/components/base/ModelView.d.ts +1 -1
- package/dist/components/base/ModelView.d.ts.map +1 -1
- package/dist/components/blocks/Article.d.ts +1 -1
- package/dist/components/blocks/Article.d.ts.map +1 -1
- package/dist/components/blocks/CardListGrid.d.ts.map +1 -1
- package/dist/components/blocks/Code.d.ts.map +1 -1
- package/dist/components/blocks/Content.d.ts.map +1 -1
- package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
- package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
- package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
- package/dist/components/blocks/Footer.d.ts.map +1 -1
- package/dist/components/blocks/Image.d.ts.map +1 -1
- package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
- package/dist/components/blocks/ProductCard.d.ts.map +1 -1
- package/dist/components/blocks/Section.d.ts.map +1 -1
- package/dist/components/blocks/Text.d.ts +8 -1
- package/dist/components/blocks/Text.d.ts.map +1 -1
- package/dist/components/buttons/Button.d.ts.map +1 -1
- package/dist/components/buttons/PaletteSwitcher.d.ts.map +1 -1
- package/dist/components/buttons/ThemeSwitcher.d.ts.map +1 -1
- package/dist/components/forms/FormBlock.d.ts +1 -1
- package/dist/components/forms/FormBlock.d.ts.map +1 -1
- package/dist/components/forms/SchemaFormRenderer.d.ts +28 -0
- package/dist/components/forms/SchemaFormRenderer.d.ts.map +1 -0
- package/dist/components/forms/index.d.ts +2 -0
- package/dist/components/forms/index.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
- package/dist/components/input/HtmlInputField.d.ts.map +1 -1
- package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts.map +1 -1
- package/dist/components/layout/GridLayout.d.ts +5 -0
- package/dist/components/layout/GridLayout.d.ts.map +1 -1
- package/dist/components/plugins/DataTable.d.ts +57 -0
- package/dist/components/plugins/DataTable.d.ts.map +1 -0
- package/dist/components/plugins/StatCard.d.ts +44 -0
- package/dist/components/plugins/StatCard.d.ts.map +1 -0
- package/dist/components/plugins/index.d.ts +13 -0
- package/dist/components/plugins/index.d.ts.map +1 -0
- package/dist/components/shared/createSerializableView.d.ts.map +1 -1
- package/dist/contexts/NavigationContext.d.ts.map +1 -1
- package/dist/hooks/useBaseProps.d.ts +1 -1
- package/dist/hooks/useBaseProps.d.ts.map +1 -1
- package/dist/index.esm.js +5939 -5532
- package/dist/index.js +6028 -5618
- package/dist/palettes/manifest.json +19 -19
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -1
- package/dist/utils/iconMap.d.ts +21 -8
- package/dist/utils/iconMap.d.ts.map +1 -1
- package/package.json +1 -2
- package/src/__tests__/utils/iconMap.test.tsx +197 -0
- package/src/components/AccessibilityChecker.tsx +10 -7
- package/src/components/ErrorBoundary.tsx +3 -3
- package/src/components/Html.tsx +17 -12
- package/src/components/Logo.tsx +1 -8
- package/src/components/Markdown.tsx +10 -10
- package/src/components/QwickApp.tsx +8 -1
- package/src/components/ResponsiveMenu.tsx +1 -1
- package/src/components/SafeSpan.tsx +9 -9
- package/src/components/Scaffold.tsx +4 -4
- package/src/components/base/ModelView.tsx +2 -2
- package/src/components/blocks/Article.tsx +7 -7
- package/src/components/blocks/CardListGrid.tsx +1 -3
- package/src/components/blocks/Code.tsx +10 -8
- package/src/components/blocks/Content.tsx +2 -4
- package/src/components/blocks/CoverImageHeader.tsx +3 -4
- package/src/components/blocks/FeatureCard.tsx +2 -4
- package/src/components/blocks/FeatureGrid.tsx +2 -4
- package/src/components/blocks/Footer.tsx +2 -4
- package/src/components/blocks/Image.tsx +8 -5
- package/src/components/blocks/PageBannerHeader.tsx +3 -4
- package/src/components/blocks/ProductCard.tsx +8 -5
- package/src/components/blocks/Section.tsx +6 -4
- package/src/components/blocks/Text.tsx +15 -7
- package/src/components/buttons/Button.tsx +8 -6
- package/src/components/buttons/PaletteSwitcher.tsx +6 -8
- package/src/components/buttons/ThemeSwitcher.tsx +8 -9
- package/src/components/forms/Captcha.tsx +1 -1
- package/src/components/forms/FormBlock.tsx +3 -5
- package/src/components/forms/FormCheckbox.tsx +1 -1
- package/src/components/forms/FormField.tsx +1 -1
- package/src/components/forms/FormSelect.tsx +1 -1
- package/src/components/forms/SchemaFormRenderer.tsx +268 -0
- package/src/components/forms/__tests__/SchemaFormRenderer.test.tsx +212 -0
- package/src/components/forms/index.ts +3 -0
- package/src/components/index.ts +1 -0
- package/src/components/input/ChoiceInputField.tsx +2 -1
- package/src/components/input/HtmlInputField.tsx +14 -9
- package/src/components/input/TextField.tsx +1 -1
- package/src/components/layout/CollapsibleLayout/CollapsibleLayout.tsx +6 -8
- package/src/components/layout/GridLayout.tsx +4 -0
- package/src/components/plugins/DataTable.tsx +259 -0
- package/src/components/plugins/StatCard.tsx +122 -0
- package/src/components/plugins/__tests__/DataTable.test.tsx +158 -0
- package/src/components/plugins/index.ts +14 -0
- package/src/components/shared/createSerializableView.tsx +8 -6
- package/src/contexts/NavigationContext.tsx +21 -15
- package/src/hooks/useBaseProps.ts +1 -1
- package/src/schemas/transformers/ReactNodeTransformer.ts +13 -10
- package/src/utils/iconMap.tsx +290 -174
- /package/dist/palettes/{palette-autumn.1.5.6.css → palette-autumn.1.5.8.css} +0 -0
- /package/dist/palettes/{palette-autumn.1.5.6.min.css → palette-autumn.1.5.8.min.css} +0 -0
- /package/dist/palettes/{palette-cosmic.1.5.6.css → palette-cosmic.1.5.8.css} +0 -0
- /package/dist/palettes/{palette-cosmic.1.5.6.min.css → palette-cosmic.1.5.8.min.css} +0 -0
- /package/dist/palettes/{palette-default.1.5.6.css → palette-default.1.5.8.css} +0 -0
- /package/dist/palettes/{palette-default.1.5.6.min.css → palette-default.1.5.8.min.css} +0 -0
- /package/dist/palettes/{palette-ocean.1.5.6.css → palette-ocean.1.5.8.css} +0 -0
- /package/dist/palettes/{palette-ocean.1.5.6.min.css → palette-ocean.1.5.8.min.css} +0 -0
- /package/dist/palettes/{palette-spring.1.5.6.css → palette-spring.1.5.8.css} +0 -0
- /package/dist/palettes/{palette-spring.1.5.6.min.css → palette-spring.1.5.8.min.css} +0 -0
- /package/dist/palettes/{palette-winter.1.5.6.css → palette-winter.1.5.8.css} +0 -0
- /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
|
-
|
|
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
|
|
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 ?
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 (!
|
|
367
|
-
|
|
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
|
|
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 (!
|
|
265
|
-
|
|
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 (!
|
|
273
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 (!
|
|
236
|
-
|
|
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 (!
|
|
241
|
-
|
|
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
|
|
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
|
|
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
|
|
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 (!
|
|
173
|
-
|
|
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 (!
|
|
178
|
-
|
|
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 (!
|
|
137
|
-
|
|
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
|
-
|
|
144
|
-
|
|
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 (!
|
|
150
|
-
|
|
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 (!
|
|
316
|
-
|
|
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 (!
|
|
321
|
-
|
|
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 (!
|
|
326
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
138
|
+
Object.assign(FormSelect, { [QWICKAPP_COMPONENT]: true });
|
|
139
139
|
|
|
140
140
|
export default FormSelect;
|