@qwickapps/react-framework 1.3.5 → 1.4.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.
- package/README.md +1681 -2
- package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
- package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +7 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/Html.d.ts +28 -18
- package/dist/components/Html.d.ts.map +1 -1
- package/dist/components/Logo.d.ts +12 -35
- package/dist/components/Logo.d.ts.map +1 -1
- package/dist/components/Markdown.d.ts +18 -13
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/QwickApp.d.ts +16 -3
- package/dist/components/QwickApp.d.ts.map +1 -1
- package/dist/components/QwickIcon.d.ts +23 -0
- package/dist/components/QwickIcon.d.ts.map +1 -0
- package/dist/components/SafeSpan.d.ts +12 -5
- package/dist/components/SafeSpan.d.ts.map +1 -1
- package/dist/components/Scaffold.d.ts.map +1 -1
- package/dist/components/base/ModelView.d.ts +101 -0
- package/dist/components/base/ModelView.d.ts.map +1 -0
- package/dist/components/base/index.d.ts +11 -0
- package/dist/components/base/index.d.ts.map +1 -0
- package/dist/components/blocks/Article.d.ts +12 -2
- package/dist/components/blocks/Article.d.ts.map +1 -1
- package/dist/components/blocks/Code.d.ts +13 -2
- package/dist/components/blocks/Code.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/HeroBlock.d.ts +27 -13
- package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
- package/dist/components/blocks/Image.d.ts +41 -0
- package/dist/components/blocks/Image.d.ts.map +1 -0
- package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
- package/dist/components/blocks/Section.d.ts +16 -2
- package/dist/components/blocks/Section.d.ts.map +1 -1
- package/dist/components/blocks/Text.d.ts +41 -0
- package/dist/components/blocks/Text.d.ts.map +1 -0
- package/dist/components/blocks/index.d.ts +4 -0
- package/dist/components/blocks/index.d.ts.map +1 -1
- package/dist/components/buttons/Button.d.ts +23 -7
- package/dist/components/buttons/Button.d.ts.map +1 -1
- package/dist/components/forms/FormBlock.d.ts +19 -13
- package/dist/components/forms/FormBlock.d.ts.map +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/input/ChoiceInputField.d.ts +17 -11
- package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
- package/dist/components/input/HtmlInputField.d.ts +17 -11
- package/dist/components/input/HtmlInputField.d.ts.map +1 -1
- package/dist/components/input/SelectInputField.d.ts +16 -10
- package/dist/components/input/SelectInputField.d.ts.map +1 -1
- package/dist/components/input/SwitchInputField.d.ts +16 -10
- package/dist/components/input/SwitchInputField.d.ts.map +1 -1
- package/dist/components/input/TextField.d.ts.map +1 -1
- package/dist/components/input/TextInputField.d.ts +16 -11
- package/dist/components/input/TextInputField.d.ts.map +1 -1
- package/dist/components/layout/GridCell.d.ts +23 -6
- package/dist/components/layout/GridCell.d.ts.map +1 -1
- package/dist/components/layout/GridLayout.d.ts +24 -23
- package/dist/components/layout/GridLayout.d.ts.map +1 -1
- package/dist/components/pages/FormPage.d.ts.map +1 -1
- package/dist/components/pages/Page.d.ts +49 -87
- package/dist/components/pages/Page.d.ts.map +1 -1
- package/dist/components/pages/index.d.ts +2 -2
- package/dist/components/pages/index.d.ts.map +1 -1
- package/dist/config/AppConfig.d.ts +49 -0
- package/dist/config/AppConfig.d.ts.map +1 -0
- package/dist/config/AppConfigBuilder.d.ts +75 -0
- package/dist/config/AppConfigBuilder.d.ts.map +1 -0
- package/dist/config/index.d.ts +13 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/types.d.ts +130 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.esm.js +451 -0
- package/dist/config.js +455 -0
- package/dist/contexts/PrintModeContext.d.ts +27 -0
- package/dist/contexts/PrintModeContext.d.ts.map +1 -0
- package/dist/contexts/QwickAppContext.d.ts +2 -2
- package/dist/contexts/QwickAppContext.d.ts.map +1 -1
- package/dist/contexts/index.d.ts +2 -0
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/usePrintMode.d.ts +39 -0
- package/dist/hooks/usePrintMode.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +10951 -6238
- package/dist/index.js +11014 -6287
- package/dist/schemas/CodeSchema.d.ts +2 -1
- package/dist/schemas/CodeSchema.d.ts.map +1 -1
- package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
- package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
- package/dist/schemas/ContentSchema.d.ts +2 -1
- package/dist/schemas/ContentSchema.d.ts.map +1 -1
- package/dist/schemas/GridCellSchema.d.ts +25 -0
- package/dist/schemas/GridCellSchema.d.ts.map +1 -0
- package/dist/schemas/GridLayoutSchema.d.ts +23 -0
- package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
- package/dist/schemas/HtmlSchema.d.ts +14 -0
- package/dist/schemas/HtmlSchema.d.ts.map +1 -0
- package/dist/schemas/ImageSchema.d.ts +32 -0
- package/dist/schemas/ImageSchema.d.ts.map +1 -0
- package/dist/schemas/LogoSchema.d.ts +35 -0
- package/dist/schemas/LogoSchema.d.ts.map +1 -0
- package/dist/schemas/MarkdownSchema.d.ts +14 -0
- package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
- package/dist/schemas/PageTemplateSchema.d.ts +31 -0
- package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
- package/dist/schemas/PrintConfigSchema.d.ts +31 -0
- package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
- package/dist/schemas/SectionSchema.d.ts +2 -1
- package/dist/schemas/SectionSchema.d.ts.map +1 -1
- package/dist/schemas/TextSchema.d.ts +37 -0
- package/dist/schemas/TextSchema.d.ts.map +1 -0
- package/dist/schemas/ViewModelSchema.d.ts +23 -0
- package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +15 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
- package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
- package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
- package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
- package/dist/schemas/transformers/registry.d.ts +15 -0
- package/dist/schemas/transformers/registry.d.ts.map +1 -0
- package/dist/schemas/types/Serializable.d.ts +46 -0
- package/dist/schemas/types/Serializable.d.ts.map +1 -0
- package/dist/utils/htmlTransform.d.ts.map +1 -1
- package/dist/utils/reactUtils.d.ts +12 -3
- package/dist/utils/reactUtils.d.ts.map +1 -1
- package/package.json +17 -3
- package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
- package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
- package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
- package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
- package/src/__tests__/components/Logo.test.js +3 -3
- package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
- package/src/__tests__/components/base/ModelView.test.tsx +220 -0
- package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
- package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
- package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
- package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
- package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
- package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
- package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
- package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
- package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
- package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
- package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
- package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
- package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
- package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
- package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
- package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
- package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
- package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
- package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
- package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
- package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
- package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
- package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
- package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
- package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
- package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
- package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
- package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
- package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
- package/src/components/ErrorBoundary.tsx +8 -8
- package/src/components/Html.tsx +147 -44
- package/src/components/Logo.tsx +198 -100
- package/src/components/Markdown.tsx +125 -16
- package/src/components/QwickApp.tsx +64 -31
- package/src/components/QwickIcon.tsx +59 -0
- package/src/components/SafeSpan.tsx +65 -10
- package/src/components/Scaffold.tsx +2 -8
- package/src/components/base/ModelView.tsx +199 -0
- package/src/components/base/index.ts +11 -0
- package/src/components/blocks/Article.tsx +57 -18
- package/src/components/blocks/Code.md +529 -0
- package/src/components/blocks/Code.tsx +102 -15
- package/src/components/blocks/CoverImageHeader.tsx +9 -4
- package/src/components/blocks/FeatureCard.tsx +1 -2
- package/src/components/blocks/FeatureGrid.tsx +19 -1
- package/src/components/blocks/Footer.tsx +13 -1
- package/src/components/blocks/HeroBlock.tsx +87 -20
- package/src/components/blocks/Image.tsx +395 -0
- package/src/components/blocks/PageBannerHeader.tsx +14 -12
- package/src/components/blocks/ProductCard.tsx +1 -1
- package/src/components/blocks/Section.tsx +113 -8
- package/src/components/blocks/Text.tsx +285 -0
- package/src/components/blocks/index.ts +4 -0
- package/src/components/buttons/Button.tsx +184 -15
- package/src/components/forms/FormBlock.tsx +70 -17
- package/src/components/index.ts +5 -0
- package/src/components/input/ChoiceInputField.tsx +48 -18
- package/src/components/input/HtmlInputField.tsx +48 -18
- package/src/components/input/SelectInputField.tsx +48 -16
- package/src/components/input/SwitchInputField.tsx +48 -17
- package/src/components/input/TextField.tsx +41 -1
- package/src/components/input/TextInputField.tsx +52 -18
- package/src/components/layout/GridCell.tsx +118 -9
- package/src/components/layout/GridLayout.tsx +125 -24
- package/src/components/pages/FormPage.tsx +0 -1
- package/src/components/pages/Page.css +304 -332
- package/src/components/pages/Page.tsx +307 -255
- package/src/components/pages/index.ts +2 -2
- package/src/config/AppConfig.ts +133 -0
- package/src/config/AppConfigBuilder.ts +421 -0
- package/src/config/__tests__/AppConfig.test.ts +385 -0
- package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
- package/src/config/index.ts +24 -0
- package/src/config/types.ts +170 -0
- package/src/config.ts +25 -0
- package/src/contexts/PrintModeContext.tsx +332 -0
- package/src/contexts/QwickAppContext.tsx +2 -2
- package/src/contexts/index.ts +2 -0
- package/src/hooks/index.ts +5 -1
- package/src/hooks/usePrintMode.ts +73 -0
- package/src/index.ts +3 -0
- package/src/schemas/CodeSchema.ts +3 -3
- package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
- package/src/schemas/ContentSchema.ts +2 -1
- package/src/schemas/GridCellSchema.ts +164 -0
- package/src/schemas/GridLayoutSchema.ts +133 -0
- package/src/schemas/HtmlSchema.ts +47 -0
- package/src/schemas/ImageSchema.ts +235 -0
- package/src/schemas/LogoSchema.ts +241 -0
- package/src/schemas/MarkdownSchema.ts +47 -0
- package/src/schemas/PageTemplateSchema.ts +186 -0
- package/src/schemas/PrintConfigSchema.ts +207 -0
- package/src/schemas/README.md +661 -0
- package/src/schemas/SectionSchema.ts +2 -1
- package/src/schemas/TextSchema.ts +329 -0
- package/src/schemas/ViewModelSchema.ts +115 -0
- package/src/schemas/index.ts +21 -2
- package/src/schemas/transformers/ComponentTransformer.ts +403 -0
- package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
- package/src/schemas/transformers/registry.ts +72 -0
- package/src/schemas/types/Serializable.ts +51 -0
- package/src/stories/AccessibilityProvider.stories.tsx +253 -253
- package/src/stories/Article.stories.tsx +433 -433
- package/src/stories/Button.stories.tsx +1 -1
- package/src/stories/CardListGrid.stories.tsx +451 -451
- package/src/stories/ChoiceInputField.stories.tsx +503 -503
- package/src/stories/Code.stories.tsx +1 -1
- package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
- package/src/stories/Content.stories.tsx +393 -393
- package/src/stories/CoverImageHeader.stories.tsx +701 -701
- package/src/stories/DataBinding.advanced.stories.tsx +432 -432
- package/src/stories/DataProvider.stories.tsx +1192 -1192
- package/src/stories/FeatureCard.stories.tsx +557 -557
- package/src/stories/FeatureGrid.stories.tsx +594 -594
- package/src/stories/Footer.stories.tsx +640 -640
- package/src/stories/FormBlock.stories.tsx +760 -760
- package/src/stories/FormComponents.stories.tsx +349 -541
- package/src/stories/GridCell.stories.tsx +417 -0
- package/src/stories/GridLayout.stories.tsx +353 -0
- package/src/stories/HeroBlock.stories.tsx +862 -373
- package/src/stories/HtmlInputField.stories.tsx +474 -474
- package/src/stories/Image.stories.tsx +819 -0
- package/src/stories/Introduction.stories.tsx +667 -667
- package/src/stories/LayoutBlocks.stories.tsx +324 -324
- package/src/stories/Logo.stories.tsx +165 -6
- package/src/stories/Markdown.stories.tsx +137 -137
- package/src/stories/ModelView.stories.tsx +477 -0
- package/src/stories/Page.stories.tsx +688 -688
- package/src/stories/PageBannerHeader.stories.tsx +864 -864
- package/src/stories/PaletteSwitcher.stories.tsx +119 -119
- package/src/stories/ProductCard.stories.tsx +424 -424
- package/src/stories/QwickApp.stories.tsx +368 -368
- package/src/stories/ResponsiveMenu.stories.tsx +249 -249
- package/src/stories/SafeSpan.stories.tsx +531 -531
- package/src/stories/Section.stories.tsx +90 -2
- package/src/stories/SelectInputField.stories.tsx +524 -524
- package/src/stories/Text.stories.tsx +560 -0
- package/src/stories/TextInputField.stories.tsx +443 -443
- package/src/stories/ThemeSwitcher.stories.tsx +123 -123
- package/src/utils/htmlTransform.tsx +74 -53
- package/src/utils/reactUtils.tsx +57 -6
- package/dist/index.bundled.css +0 -12
- /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
- /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
|
@@ -18,9 +18,11 @@
|
|
|
18
18
|
|
|
19
19
|
import { Box, Container } from '@mui/material';
|
|
20
20
|
import type { WithDataBinding } from '@qwickapps/schema';
|
|
21
|
-
import React from 'react';
|
|
21
|
+
import React, { ReactElement, ReactNode } from 'react';
|
|
22
22
|
import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding, WithBaseProps } from '../../hooks';
|
|
23
23
|
import SectionModel from '../../schemas/SectionSchema';
|
|
24
|
+
import { ModelView } from '../base/ModelView';
|
|
25
|
+
import { ComponentTransformer } from '../../schemas/transformers/ComponentTransformer';
|
|
24
26
|
import type { BreakpointValue } from '../../types';
|
|
25
27
|
import { mapToMUIBreakpoint } from '../../utils/breakpoints';
|
|
26
28
|
|
|
@@ -146,18 +148,111 @@ function SectionView({
|
|
|
146
148
|
);
|
|
147
149
|
}
|
|
148
150
|
|
|
149
|
-
// Main component with data binding support
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
// Main component with data binding support and serialization capability
|
|
152
|
+
export class Section extends ModelView<SectionProps, SectionModel> {
|
|
153
|
+
// Component self-declaration for serialization
|
|
154
|
+
static readonly tagName = 'Section';
|
|
155
|
+
static readonly version = '1.0.0';
|
|
156
|
+
|
|
157
|
+
// Deserialization: JSON data → React element
|
|
158
|
+
static fromJson(jsonData: any): ReactElement {
|
|
159
|
+
return <Section {...jsonData} />;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Section supports nested components
|
|
163
|
+
protected hasNestedComponents(children: ReactNode): boolean {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Override serializeChildren to handle nested components properly
|
|
168
|
+
protected serializeChildren(children: ReactNode): any {
|
|
169
|
+
if (typeof children === 'string') {
|
|
170
|
+
return children;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (children !== undefined) {
|
|
174
|
+
return ComponentTransformer.serialize(children);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Component-specific serialization properties
|
|
181
|
+
protected getComponentSpecificProps(): any {
|
|
182
|
+
return {
|
|
183
|
+
background: this.props.background,
|
|
184
|
+
color: this.props.color,
|
|
185
|
+
padding: this.props.padding,
|
|
186
|
+
contentMaxWidth: this.props.contentMaxWidth,
|
|
187
|
+
component: this.props.component
|
|
188
|
+
};
|
|
189
|
+
}
|
|
152
190
|
|
|
153
|
-
//
|
|
154
|
-
|
|
191
|
+
// Section component renders traditional props view
|
|
192
|
+
protected renderView(): React.ReactElement {
|
|
193
|
+
const { dataSource, bindingOptions, ...restProps } = this.props;
|
|
155
194
|
return <SectionView {...restProps} />;
|
|
156
195
|
}
|
|
157
196
|
|
|
197
|
+
// Section component renders data-bound view
|
|
198
|
+
protected renderWithDataBinding(): React.ReactElement {
|
|
199
|
+
return <SectionWithDataBinding {...this.props} />;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Register HTML patterns that Section component can handle
|
|
203
|
+
static registerPatternHandlers(registry: any): void {
|
|
204
|
+
// Register section element pattern
|
|
205
|
+
if (!registry.hasPattern('section')) {
|
|
206
|
+
registry.registerPattern('section', Section.transformSection);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Register section with specific classes
|
|
210
|
+
if (!registry.hasPattern('section.blog-section')) {
|
|
211
|
+
registry.registerPattern('section.blog-section', Section.transformBlogSection);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Transform generic section elements to Section component
|
|
216
|
+
private static transformSection(element: Element): any {
|
|
217
|
+
const padding = element.getAttribute('data-padding') || 'medium';
|
|
218
|
+
const background = element.getAttribute('data-background');
|
|
219
|
+
const contentMaxWidth = element.getAttribute('data-max-width') || 'lg';
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
tagName: 'Section',
|
|
223
|
+
props: {
|
|
224
|
+
padding,
|
|
225
|
+
background,
|
|
226
|
+
contentMaxWidth,
|
|
227
|
+
children: element.innerHTML
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Transform blog section elements to Section component with specific styling
|
|
233
|
+
private static transformBlogSection(element: Element): any {
|
|
234
|
+
const padding = element.getAttribute('data-padding') || 'large';
|
|
235
|
+
const background = element.getAttribute('data-background') || 'var(--theme-surface)';
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
tagName: 'Section',
|
|
239
|
+
props: {
|
|
240
|
+
padding,
|
|
241
|
+
background,
|
|
242
|
+
contentMaxWidth: 'md',
|
|
243
|
+
children: element.innerHTML
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Helper component to handle data binding with hooks (since we can't use hooks in class components)
|
|
250
|
+
function SectionWithDataBinding(props: SectionProps) {
|
|
251
|
+
const { dataSource, bindingOptions, ...restProps } = props;
|
|
252
|
+
|
|
158
253
|
// Use data binding
|
|
159
254
|
const { dataSource: _source, loading, error, cached, ...sectionProps } = useDataBinding<SectionModel>(
|
|
160
|
-
dataSource
|
|
255
|
+
dataSource!,
|
|
161
256
|
restProps as Partial<SectionModel>,
|
|
162
257
|
SectionModel.getSchema(),
|
|
163
258
|
{ cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
|
|
@@ -203,7 +298,17 @@ function Section(props: SectionProps) {
|
|
|
203
298
|
return null;
|
|
204
299
|
}
|
|
205
300
|
|
|
206
|
-
|
|
301
|
+
console.log('Resolved props for Section:', sectionProps);
|
|
302
|
+
|
|
303
|
+
// Handle type conversion for contentMaxWidth - convert "false" string to boolean false
|
|
304
|
+
const typedSectionProps: SectionViewProps = {
|
|
305
|
+
...sectionProps,
|
|
306
|
+
contentMaxWidth: sectionProps.contentMaxWidth === "false"
|
|
307
|
+
? false
|
|
308
|
+
: sectionProps.contentMaxWidth as BreakpointValue
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
return <SectionView {...typedSectionProps} />;
|
|
207
312
|
}
|
|
208
313
|
|
|
209
314
|
export default Section;
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text - Comprehensive typography display component with serialization support
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Complete typography variant support (h1-h6, body1/2, subtitle, etc.)
|
|
6
|
+
* - Rich styling options (color, alignment, font properties)
|
|
7
|
+
* - Custom typography overrides (fontSize, fontFamily, etc.)
|
|
8
|
+
* - Semantic HTML element rendering
|
|
9
|
+
* - Text formatting and decoration options
|
|
10
|
+
* - Full serialization support via ModelView
|
|
11
|
+
*
|
|
12
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import React, { ReactElement, ReactNode } from 'react';
|
|
16
|
+
import { Typography } from '@mui/material';
|
|
17
|
+
import type { WithDataBinding, ModelProps } from '@qwickapps/schema';
|
|
18
|
+
import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding } from '../../hooks';
|
|
19
|
+
import TextModel from '../../schemas/TextSchema';
|
|
20
|
+
import { ModelView } from '../base/ModelView';
|
|
21
|
+
|
|
22
|
+
type TextViewProps = ModelProps<TextModel> & {
|
|
23
|
+
/** Click handler for the text */
|
|
24
|
+
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
25
|
+
/** Additional inline styles */
|
|
26
|
+
style?: React.CSSProperties;
|
|
27
|
+
/** Additional CSS class names */
|
|
28
|
+
className?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export interface TextProps extends TextViewProps, WithDataBinding {}
|
|
32
|
+
|
|
33
|
+
// View component - handles the actual rendering
|
|
34
|
+
function TextView({
|
|
35
|
+
content,
|
|
36
|
+
variant = 'body1',
|
|
37
|
+
color = 'inherit',
|
|
38
|
+
align = 'inherit',
|
|
39
|
+
component = 'p',
|
|
40
|
+
fontWeight = 'inherit',
|
|
41
|
+
textDecoration = 'none',
|
|
42
|
+
textTransform = 'none',
|
|
43
|
+
noWrap = false,
|
|
44
|
+
paragraph = false,
|
|
45
|
+
gutterBottom = false,
|
|
46
|
+
fontSize,
|
|
47
|
+
lineHeight,
|
|
48
|
+
letterSpacing,
|
|
49
|
+
fontFamily,
|
|
50
|
+
customColor,
|
|
51
|
+
maxWidth,
|
|
52
|
+
children,
|
|
53
|
+
onClick,
|
|
54
|
+
style,
|
|
55
|
+
className,
|
|
56
|
+
...restProps
|
|
57
|
+
}: TextViewProps) {
|
|
58
|
+
const { styleProps, htmlProps, restProps: otherProps } = useBaseProps(restProps);
|
|
59
|
+
|
|
60
|
+
// Mark as QwickApp component
|
|
61
|
+
(TextView as any)[QWICKAPP_COMPONENT] = true;
|
|
62
|
+
|
|
63
|
+
// Determine the text content to display
|
|
64
|
+
const textContent = children || content;
|
|
65
|
+
|
|
66
|
+
// Early return if no content provided
|
|
67
|
+
if (!textContent && textContent !== 0) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Build custom styles
|
|
72
|
+
const customStyles: React.CSSProperties = {
|
|
73
|
+
...style
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Apply custom typography overrides
|
|
77
|
+
if (fontSize) customStyles.fontSize = fontSize;
|
|
78
|
+
if (lineHeight) customStyles.lineHeight = lineHeight;
|
|
79
|
+
if (letterSpacing) customStyles.letterSpacing = letterSpacing;
|
|
80
|
+
if (fontFamily) customStyles.fontFamily = fontFamily;
|
|
81
|
+
if (customColor) customStyles.color = customColor;
|
|
82
|
+
if (maxWidth) customStyles.maxWidth = maxWidth;
|
|
83
|
+
|
|
84
|
+
// Apply text formatting
|
|
85
|
+
if (fontWeight !== 'inherit') customStyles.fontWeight = fontWeight;
|
|
86
|
+
if (textDecoration !== 'none') customStyles.textDecoration = textDecoration;
|
|
87
|
+
if (textTransform !== 'none') customStyles.textTransform = textTransform;
|
|
88
|
+
|
|
89
|
+
// Handle onClick cursor
|
|
90
|
+
if (onClick) customStyles.cursor = 'pointer';
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<Typography
|
|
94
|
+
{...htmlProps}
|
|
95
|
+
{...styleProps}
|
|
96
|
+
{...otherProps}
|
|
97
|
+
variant={variant}
|
|
98
|
+
color={color as any}
|
|
99
|
+
align={align}
|
|
100
|
+
component={component}
|
|
101
|
+
noWrap={noWrap}
|
|
102
|
+
paragraph={paragraph}
|
|
103
|
+
gutterBottom={gutterBottom}
|
|
104
|
+
className={`text ${className || ''}`.trim()}
|
|
105
|
+
style={customStyles}
|
|
106
|
+
onClick={onClick}
|
|
107
|
+
>
|
|
108
|
+
{textContent}
|
|
109
|
+
</Typography>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Main component with data binding support and serialization capability
|
|
114
|
+
export class Text extends ModelView<TextProps, TextModel> {
|
|
115
|
+
// Component self-declaration for serialization
|
|
116
|
+
static readonly tagName = 'Text';
|
|
117
|
+
static readonly version = '1.0.0';
|
|
118
|
+
|
|
119
|
+
// Deserialization: JSON data → React element
|
|
120
|
+
static fromJson(jsonData: any): ReactElement {
|
|
121
|
+
return <Text {...jsonData} />;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Component-specific serialization properties
|
|
125
|
+
protected getComponentSpecificProps(): any {
|
|
126
|
+
return {
|
|
127
|
+
content: this.props.content,
|
|
128
|
+
variant: this.props.variant,
|
|
129
|
+
color: this.props.color,
|
|
130
|
+
align: this.props.align,
|
|
131
|
+
component: this.props.component,
|
|
132
|
+
fontWeight: this.props.fontWeight,
|
|
133
|
+
textDecoration: this.props.textDecoration,
|
|
134
|
+
textTransform: this.props.textTransform,
|
|
135
|
+
noWrap: this.props.noWrap,
|
|
136
|
+
paragraph: this.props.paragraph,
|
|
137
|
+
gutterBottom: this.props.gutterBottom,
|
|
138
|
+
fontSize: this.props.fontSize,
|
|
139
|
+
lineHeight: this.props.lineHeight,
|
|
140
|
+
letterSpacing: this.props.letterSpacing,
|
|
141
|
+
fontFamily: this.props.fontFamily,
|
|
142
|
+
customColor: this.props.customColor,
|
|
143
|
+
maxWidth: this.props.maxWidth,
|
|
144
|
+
// Note: children ReactNode will be handled by base serialization if needed
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Text component renders traditional props view
|
|
149
|
+
protected renderView(): React.ReactElement {
|
|
150
|
+
const { dataSource, bindingOptions, ...restProps } = this.props;
|
|
151
|
+
return <TextView {...restProps} />;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Text component renders data-bound view
|
|
155
|
+
protected renderWithDataBinding(): React.ReactElement {
|
|
156
|
+
return <TextWithDataBinding {...this.props} />;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Register HTML patterns that Text component can handle
|
|
160
|
+
static registerPatternHandlers(registry: any): void {
|
|
161
|
+
// Register paragraph elements
|
|
162
|
+
if (!registry.hasPattern('p')) {
|
|
163
|
+
registry.registerPattern('p', Text.transformParagraph);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Register heading elements
|
|
167
|
+
const headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
168
|
+
headings.forEach(heading => {
|
|
169
|
+
if (!registry.hasPattern(heading)) {
|
|
170
|
+
registry.registerPattern(heading, (element: Element) => Text.transformHeading(element, heading));
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Register span elements
|
|
175
|
+
if (!registry.hasPattern('span')) {
|
|
176
|
+
registry.registerPattern('span', Text.transformSpan);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Transform paragraph elements to Text component
|
|
181
|
+
private static transformParagraph(element: Element): any {
|
|
182
|
+
return {
|
|
183
|
+
tagName: 'Text',
|
|
184
|
+
props: {
|
|
185
|
+
variant: 'body1',
|
|
186
|
+
component: 'p',
|
|
187
|
+
children: element.textContent || ''
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Transform heading elements to Text component
|
|
193
|
+
private static transformHeading(element: Element, tagName: string): any {
|
|
194
|
+
const variantMap: { [key: string]: string } = {
|
|
195
|
+
'h1': 'h1',
|
|
196
|
+
'h2': 'h2',
|
|
197
|
+
'h3': 'h3',
|
|
198
|
+
'h4': 'h4',
|
|
199
|
+
'h5': 'h5',
|
|
200
|
+
'h6': 'h6'
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
tagName: 'Text',
|
|
205
|
+
props: {
|
|
206
|
+
variant: variantMap[tagName] || 'h4',
|
|
207
|
+
component: tagName,
|
|
208
|
+
children: element.textContent || ''
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Transform span elements to Text component
|
|
214
|
+
private static transformSpan(element: Element): any {
|
|
215
|
+
return {
|
|
216
|
+
tagName: 'Text',
|
|
217
|
+
props: {
|
|
218
|
+
variant: 'body2',
|
|
219
|
+
component: 'span',
|
|
220
|
+
children: element.textContent || ''
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Helper component to handle data binding with hooks (since we can't use hooks in class components)
|
|
227
|
+
function TextWithDataBinding(props: TextProps) {
|
|
228
|
+
const { dataSource, bindingOptions, ...restProps } = props;
|
|
229
|
+
|
|
230
|
+
// Use data binding
|
|
231
|
+
const { dataSource: _source, loading, error, cached, ...rawTextProps } = useDataBinding<TextModel>(
|
|
232
|
+
dataSource!,
|
|
233
|
+
restProps as Partial<TextModel>,
|
|
234
|
+
TextModel.getSchema(),
|
|
235
|
+
{ cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
// Use props directly since new serialization system handles component-level transformation
|
|
239
|
+
const textProps = rawTextProps;
|
|
240
|
+
|
|
241
|
+
// Show loading state
|
|
242
|
+
if (loading) {
|
|
243
|
+
return (
|
|
244
|
+
<Typography
|
|
245
|
+
variant={textProps.variant || 'body1'}
|
|
246
|
+
color="text.secondary"
|
|
247
|
+
sx={{
|
|
248
|
+
backgroundColor: 'grey.100',
|
|
249
|
+
borderRadius: '4px',
|
|
250
|
+
padding: '0.5rem',
|
|
251
|
+
maxWidth: textProps.maxWidth
|
|
252
|
+
}}
|
|
253
|
+
>
|
|
254
|
+
Loading text...
|
|
255
|
+
</Typography>
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (error) {
|
|
260
|
+
console.error('Error loading text:', error);
|
|
261
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
262
|
+
return (
|
|
263
|
+
<Typography
|
|
264
|
+
variant={textProps.variant || 'body1'}
|
|
265
|
+
color="error"
|
|
266
|
+
sx={{
|
|
267
|
+
backgroundColor: 'error.light',
|
|
268
|
+
color: 'error.contrastText',
|
|
269
|
+
borderRadius: '4px',
|
|
270
|
+
padding: '0.5rem',
|
|
271
|
+
maxWidth: textProps.maxWidth
|
|
272
|
+
}}
|
|
273
|
+
>
|
|
274
|
+
Error Loading Text: {error.message}
|
|
275
|
+
</Typography>
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
console.log('Resolved props for Text:', textProps);
|
|
282
|
+
return <TextView {...textProps} />;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export default Text;
|
|
@@ -19,6 +19,8 @@ export { default as CoverImageHeader } from './CoverImageHeader';
|
|
|
19
19
|
export { default as FeatureGrid } from './FeatureGrid';
|
|
20
20
|
export { default as Footer } from './Footer';
|
|
21
21
|
export { default as Section } from './Section';
|
|
22
|
+
export { default as Image } from './Image';
|
|
23
|
+
export { default as Text } from './Text';
|
|
22
24
|
export { default as ProductCard } from './ProductCard';
|
|
23
25
|
export { default as FeatureCard } from './FeatureCard';
|
|
24
26
|
export { default as CardListGrid } from './CardListGrid';
|
|
@@ -32,6 +34,8 @@ export type { CoverImageHeaderProps, HeaderAction } from './CoverImageHeader';
|
|
|
32
34
|
export type { FeatureGridProps, FeatureItem as FeatureGridItem } from './FeatureGrid';
|
|
33
35
|
export type { FooterProps } from './Footer';
|
|
34
36
|
export type { SectionProps } from './Section';
|
|
37
|
+
export type { ImageProps } from './Image';
|
|
38
|
+
export type { TextProps } from './Text';
|
|
35
39
|
export type { ProductCardProps, Product, ProductCardAction } from './ProductCard';
|
|
36
40
|
export type { FeatureCardProps, FeatureItem, FeatureCardAction } from './FeatureCard';
|
|
37
41
|
export type { CardListGridProps } from './CardListGrid';
|