@qwickapps/react-framework 1.4.8 → 1.4.9
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 +13 -3
- package/dist/index.css +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +255 -54
- package/dist/index.js +249 -48
- package/dist/src/components/Logo.d.ts.map +1 -1
- package/dist/src/components/ResponsiveMenu.d.ts.map +1 -1
- package/dist/src/components/SafeSpan.d.ts.map +1 -1
- package/dist/src/components/Scaffold.d.ts.map +1 -1
- package/dist/src/components/blocks/Article.d.ts.map +1 -1
- package/dist/src/components/blocks/Footer.d.ts.map +1 -1
- package/dist/src/components/blocks/Text.d.ts.map +1 -1
- package/dist/src/components/buttons/Button.d.ts +26 -10
- package/dist/src/components/buttons/Button.d.ts.map +1 -1
- package/dist/src/components/menu/MenuItem.d.ts +2 -2
- package/dist/src/components/menu/MenuItem.d.ts.map +1 -1
- package/dist/src/schemas/ButtonSchema.d.ts +3 -0
- package/dist/src/schemas/ButtonSchema.d.ts.map +1 -1
- package/dist/src/schemas/transformers/ComponentTransformer.d.ts.map +1 -1
- package/dist/src/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -1
- package/package.json +9 -1
- package/src/components/Html.tsx +1 -1
- package/src/components/Logo.tsx +2 -4
- package/src/components/QwickApp.css +19 -13
- package/src/components/ResponsiveMenu.tsx +12 -1
- package/src/components/SafeSpan.tsx +0 -1
- package/src/components/Scaffold.css +14 -0
- package/src/components/Scaffold.tsx +16 -2
- package/src/components/blocks/Article.tsx +78 -7
- package/src/components/blocks/CoverImageHeader.tsx +1 -1
- package/src/components/blocks/Footer.tsx +23 -23
- package/src/components/blocks/PageBannerHeader.tsx +1 -1
- package/src/components/blocks/Text.tsx +7 -4
- package/src/components/buttons/Button.tsx +189 -15
- package/src/components/menu/MenuItem.tsx +2 -2
- package/src/contexts/ThemeContext.tsx +1 -1
- package/src/schemas/ButtonSchema.ts +33 -0
- package/src/schemas/ViewSchema.ts +1 -1
- package/src/schemas/transformers/ComponentTransformer.ts +2 -8
- package/src/schemas/transformers/ReactNodeTransformer.ts +1 -2
- package/src/stories/Article.stories.tsx +1 -1
- package/src/stories/ChoiceInputField.stories.tsx +2 -2
package/dist/index.esm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { useMediaQuery, Box, useTheme as useTheme$1, Paper, Typography, Tooltip, IconButton, Snackbar, Alert, CircularProgress, Button as Button$1, Container as Container$9, Stack, Skeleton, Avatar, Chip, Menu, MenuItem, Card, CardContent, ButtonGroup, Collapse, TextField as TextField$1, FormControl, InputLabel, Select, FormHelperText, FormControlLabel, Switch, Grid, Divider, Link, ListItemIcon, ListItemText } from '@mui/material';
|
|
2
|
+
import { useMediaQuery, Box, useTheme as useTheme$1, Paper, Typography, Tooltip, IconButton, Snackbar, Alert, CircularProgress, Button as Button$1, Container as Container$9, Stack, Skeleton, Avatar, Chip, Menu as Menu$1, MenuItem, Card, CardContent, ButtonGroup, Collapse, TextField as TextField$1, FormControl, InputLabel, Select, FormHelperText, FormControlLabel, Switch, Grid, Divider, Link, ListItemIcon, ListItemText } from '@mui/material';
|
|
3
3
|
import React, { useMemo, useContext, useState, useEffect, createContext, useReducer, useCallback, useRef, isValidElement, createElement, useId, useLayoutEffect, Component, cloneElement } from 'react';
|
|
4
4
|
import { MustacheTemplateProvider, MemoryCacheProvider, CachedDataProvider, Field, Editor, FieldType, Schema, Model, DataType } from '@qwickapps/schema';
|
|
5
5
|
import { createTheme, ThemeProvider as ThemeProvider$1 } from '@mui/material/styles';
|
|
6
|
-
import { Check, ContentCopy, BrokenImage, MoreVert, FormatBold, FormatItalic, FormatUnderlined, Code as Code$1,
|
|
6
|
+
import { Check, ContentCopy, Home, Download, CloudDownload, CloudUpload, Settings, Dashboard, Info, Help, Add, Edit, Delete, Close, ArrowForward, ArrowBack, Menu, Search, Favorite, Star, Share, Save, Send, Email, Phone, Person, Group, Business, ShoppingCart, AttachMoney, Lock, LockOpen, Visibility, VisibilityOff, BrokenImage, MoreVert, FormatBold, FormatItalic, FormatUnderlined, Code as Code$1, ExpandMore, ExpandLess, Schedule, Launch, LightMode, DarkMode, SettingsSystemDaydream, Palette, Circle, RadioButtonUnchecked } from '@mui/icons-material';
|
|
7
7
|
import { IsOptional, ValidateIf, IsIn, IsInt, Min, IsString, IsNotEmpty, IsBoolean, IsNumber, Max, IsArray, ValidateNested, IsUrl, IsObject } from 'class-validator';
|
|
8
8
|
import 'reflect-metadata';
|
|
9
9
|
import { Type } from 'class-transformer';
|
|
@@ -1543,7 +1543,7 @@ const ThemeProvider = ({
|
|
|
1543
1543
|
const backgroundMain = getCSSCustomProperty('--theme-background') || (isDark ? '#121212' : '#ffffff');
|
|
1544
1544
|
const surfaceMain = getCSSCustomProperty('--theme-surface') || (isDark ? '#1e1e1e' : '#ffffff');
|
|
1545
1545
|
const textPrimary = getCSSCustomProperty('--theme-text-primary') || (isDark ? '#ffffff' : '#000000');
|
|
1546
|
-
const textSecondary = getCSSCustomProperty('--theme-text-secondary') || (isDark ? '
|
|
1546
|
+
const textSecondary = getCSSCustomProperty('--theme-text-secondary') || (isDark ? 'rgba(255, 255, 255, 0.7)' : 'rgba(0, 0, 0, 0.6)');
|
|
1547
1547
|
const textDisabled = getCSSCustomProperty('--theme-on-disabled') || (isDark ? 'rgba(255, 255, 255, 0.38)' : 'rgba(0, 0, 0, 0.38)');
|
|
1548
1548
|
return createTheme({
|
|
1549
1549
|
palette: {
|
|
@@ -2648,11 +2648,64 @@ Code.transformCodeHighlight = element => {
|
|
|
2648
2648
|
};
|
|
2649
2649
|
};
|
|
2650
2650
|
|
|
2651
|
+
/**
|
|
2652
|
+
* Icon name to Material-UI icon component mapping
|
|
2653
|
+
* Used by finalize function to transform icon string names to React components
|
|
2654
|
+
*/
|
|
2655
|
+
const iconRegistry = {
|
|
2656
|
+
home: Home,
|
|
2657
|
+
download: Download,
|
|
2658
|
+
clouddownload: CloudDownload,
|
|
2659
|
+
cloudupload: CloudUpload,
|
|
2660
|
+
settings: Settings,
|
|
2661
|
+
dashboard: Dashboard,
|
|
2662
|
+
info: Info,
|
|
2663
|
+
help: Help,
|
|
2664
|
+
add: Add,
|
|
2665
|
+
edit: Edit,
|
|
2666
|
+
delete: Delete,
|
|
2667
|
+
check: Check,
|
|
2668
|
+
close: Close,
|
|
2669
|
+
arrowforward: ArrowForward,
|
|
2670
|
+
arrowback: ArrowBack,
|
|
2671
|
+
menu: Menu,
|
|
2672
|
+
search: Search,
|
|
2673
|
+
favorite: Favorite,
|
|
2674
|
+
star: Star,
|
|
2675
|
+
share: Share,
|
|
2676
|
+
save: Save,
|
|
2677
|
+
send: Send,
|
|
2678
|
+
email: Email,
|
|
2679
|
+
phone: Phone,
|
|
2680
|
+
person: Person,
|
|
2681
|
+
group: Group,
|
|
2682
|
+
business: Business,
|
|
2683
|
+
shoppingcart: ShoppingCart,
|
|
2684
|
+
attachmoney: AttachMoney,
|
|
2685
|
+
lock: Lock,
|
|
2686
|
+
lockopen: LockOpen,
|
|
2687
|
+
visibility: Visibility,
|
|
2688
|
+
visibilityoff: VisibilityOff
|
|
2689
|
+
};
|
|
2690
|
+
/**
|
|
2691
|
+
* Get icon component from icon name string
|
|
2692
|
+
* Exported for use by other components (Scaffold, ResponsiveMenu, etc.)
|
|
2693
|
+
*/
|
|
2694
|
+
function getIconComponent(iconName) {
|
|
2695
|
+
if (!iconName) return null;
|
|
2696
|
+
const IconComponent = iconRegistry[iconName.toLowerCase()];
|
|
2697
|
+
if (!IconComponent) {
|
|
2698
|
+
console.warn(`[Button] Icon "${iconName}" not found in registry`);
|
|
2699
|
+
return null;
|
|
2700
|
+
}
|
|
2701
|
+
return jsx(IconComponent, {});
|
|
2702
|
+
}
|
|
2651
2703
|
// View component - handles the actual rendering
|
|
2652
2704
|
const ButtonView = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
2653
2705
|
const {
|
|
2654
2706
|
label,
|
|
2655
2707
|
variant = 'primary',
|
|
2708
|
+
color,
|
|
2656
2709
|
buttonSize = 'medium',
|
|
2657
2710
|
icon,
|
|
2658
2711
|
endIcon,
|
|
@@ -2683,8 +2736,13 @@ const ButtonView = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
2683
2736
|
return 'contained';
|
|
2684
2737
|
}
|
|
2685
2738
|
};
|
|
2686
|
-
//
|
|
2687
|
-
const
|
|
2739
|
+
// Get theme color name - prioritize explicit color prop over variant-derived color
|
|
2740
|
+
const getThemeColorName = () => {
|
|
2741
|
+
// If color prop is explicitly provided, use it
|
|
2742
|
+
if (color) {
|
|
2743
|
+
return color;
|
|
2744
|
+
}
|
|
2745
|
+
// Otherwise derive from variant
|
|
2688
2746
|
switch (variant) {
|
|
2689
2747
|
case 'primary':
|
|
2690
2748
|
return 'primary';
|
|
@@ -2700,6 +2758,50 @@ const ButtonView = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
2700
2758
|
return 'primary';
|
|
2701
2759
|
}
|
|
2702
2760
|
};
|
|
2761
|
+
// Get CSS theme variable styles based on variant and color
|
|
2762
|
+
const getColorStyles = () => {
|
|
2763
|
+
const muiVariant = getMuiVariant();
|
|
2764
|
+
const colorName = getThemeColorName();
|
|
2765
|
+
// For contained buttons: use solid background
|
|
2766
|
+
if (muiVariant === 'contained') {
|
|
2767
|
+
return {
|
|
2768
|
+
backgroundColor: `var(--theme-${colorName})`,
|
|
2769
|
+
color: `var(--theme-on-${colorName})`,
|
|
2770
|
+
'&:hover': {
|
|
2771
|
+
backgroundColor: `var(--theme-${colorName}-dark)`
|
|
2772
|
+
},
|
|
2773
|
+
'&.Mui-disabled': {
|
|
2774
|
+
backgroundColor: 'var(--theme-text-disabled)',
|
|
2775
|
+
color: 'var(--theme-on-surface)'
|
|
2776
|
+
}
|
|
2777
|
+
};
|
|
2778
|
+
}
|
|
2779
|
+
// For outlined buttons: border and text color
|
|
2780
|
+
if (muiVariant === 'outlined') {
|
|
2781
|
+
return {
|
|
2782
|
+
borderColor: `var(--theme-${colorName})`,
|
|
2783
|
+
color: `var(--theme-${colorName})`,
|
|
2784
|
+
'&:hover': {
|
|
2785
|
+
borderColor: `var(--theme-${colorName}-dark)`,
|
|
2786
|
+
backgroundColor: `var(--theme-${colorName}-light)`
|
|
2787
|
+
},
|
|
2788
|
+
'&.Mui-disabled': {
|
|
2789
|
+
borderColor: 'var(--theme-border-main)',
|
|
2790
|
+
color: 'var(--theme-text-disabled)'
|
|
2791
|
+
}
|
|
2792
|
+
};
|
|
2793
|
+
}
|
|
2794
|
+
// For text buttons: just text color
|
|
2795
|
+
return {
|
|
2796
|
+
color: `var(--theme-${colorName})`,
|
|
2797
|
+
'&:hover': {
|
|
2798
|
+
backgroundColor: `var(--theme-${colorName}-light)`
|
|
2799
|
+
},
|
|
2800
|
+
'&.Mui-disabled': {
|
|
2801
|
+
color: 'var(--theme-text-disabled)'
|
|
2802
|
+
}
|
|
2803
|
+
};
|
|
2804
|
+
};
|
|
2703
2805
|
// Handle action serialization pattern for onClick
|
|
2704
2806
|
const handleActionClick = React.useCallback(event => {
|
|
2705
2807
|
if (action) {
|
|
@@ -2756,12 +2858,13 @@ const ButtonView = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
2756
2858
|
// Base button props
|
|
2757
2859
|
const baseProps = {
|
|
2758
2860
|
variant: getMuiVariant(),
|
|
2759
|
-
color: getMuiColor(),
|
|
2760
2861
|
size: buttonSize,
|
|
2761
2862
|
disabled: disabled || loading,
|
|
2762
2863
|
fullWidth,
|
|
2763
2864
|
...restProps,
|
|
2764
2865
|
sx: {
|
|
2866
|
+
// Apply CSS theme variable colors
|
|
2867
|
+
...getColorStyles(),
|
|
2765
2868
|
// Ensure consistent text transform
|
|
2766
2869
|
textTransform: 'none',
|
|
2767
2870
|
// Loading state adjustments
|
|
@@ -2770,6 +2873,7 @@ const ButtonView = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
2770
2873
|
marginRight: 1
|
|
2771
2874
|
}
|
|
2772
2875
|
}),
|
|
2876
|
+
// Merge user-provided sx prop last to allow overrides
|
|
2773
2877
|
...(restProps.sx || {})
|
|
2774
2878
|
},
|
|
2775
2879
|
startIcon: loading ? jsx(CircularProgress, {
|
|
@@ -2812,8 +2916,27 @@ const Button = createSerializableView({
|
|
|
2812
2916
|
tagName: 'Button',
|
|
2813
2917
|
version: '1.0.0',
|
|
2814
2918
|
role: 'view',
|
|
2815
|
-
View: ButtonView
|
|
2919
|
+
View: ButtonView,
|
|
2816
2920
|
// Button component uses default react-children strategy for potential child content
|
|
2921
|
+
finalize: props => {
|
|
2922
|
+
// Transform icon string names to React icon components
|
|
2923
|
+
const transformedProps = {
|
|
2924
|
+
...props
|
|
2925
|
+
};
|
|
2926
|
+
if (typeof props.icon === 'string') {
|
|
2927
|
+
const iconComponent = getIconComponent(props.icon);
|
|
2928
|
+
if (iconComponent) {
|
|
2929
|
+
transformedProps.icon = iconComponent;
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
if (typeof props.endIcon === 'string') {
|
|
2933
|
+
const endIconComponent = getIconComponent(props.endIcon);
|
|
2934
|
+
if (endIconComponent) {
|
|
2935
|
+
transformedProps.endIcon = endIconComponent;
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
return transformedProps;
|
|
2939
|
+
}
|
|
2817
2940
|
});
|
|
2818
2941
|
// Register HTML patterns that Button component can handle
|
|
2819
2942
|
Button.registerPatternHandlers = registry => {
|
|
@@ -3546,7 +3669,8 @@ Text$1.registerPatternHandlers = registry => {
|
|
|
3546
3669
|
Text$1.transformParagraph = element => {
|
|
3547
3670
|
return {
|
|
3548
3671
|
tagName: 'Text',
|
|
3549
|
-
|
|
3672
|
+
version: '1.0.0',
|
|
3673
|
+
data: {
|
|
3550
3674
|
variant: 'body1',
|
|
3551
3675
|
component: 'p',
|
|
3552
3676
|
content: element.textContent || ''
|
|
@@ -3565,7 +3689,8 @@ Text$1.transformHeading = (element, tagName) => {
|
|
|
3565
3689
|
};
|
|
3566
3690
|
return {
|
|
3567
3691
|
tagName: 'Text',
|
|
3568
|
-
|
|
3692
|
+
version: '1.0.0',
|
|
3693
|
+
data: {
|
|
3569
3694
|
variant: variantMap[tagName] || 'h4',
|
|
3570
3695
|
component: tagName,
|
|
3571
3696
|
content: element.textContent || ''
|
|
@@ -3576,7 +3701,8 @@ Text$1.transformHeading = (element, tagName) => {
|
|
|
3576
3701
|
Text$1.transformSpan = element => {
|
|
3577
3702
|
return {
|
|
3578
3703
|
tagName: 'Text',
|
|
3579
|
-
|
|
3704
|
+
version: '1.0.0',
|
|
3705
|
+
data: {
|
|
3580
3706
|
variant: 'body2',
|
|
3581
3707
|
component: 'span',
|
|
3582
3708
|
content: element.textContent || ''
|
|
@@ -3854,7 +3980,7 @@ __decorate([Field(), Editor({
|
|
|
3854
3980
|
field_type: FieldType.TEXTAREA,
|
|
3855
3981
|
label: 'Click Handler',
|
|
3856
3982
|
description: 'JavaScript function for click events',
|
|
3857
|
-
placeholder: 'function(event) { console.
|
|
3983
|
+
placeholder: 'function(event) { console.debug("clicked"); }'
|
|
3858
3984
|
}), IsOptional(), IsString(), __metadata("design:type", Function)], ViewSchema.prototype, "onClick", void 0);
|
|
3859
3985
|
__decorate([Field(), Editor({
|
|
3860
3986
|
field_type: FieldType.TEXTAREA,
|
|
@@ -4283,7 +4409,7 @@ function CoverImageHeaderView({
|
|
|
4283
4409
|
minWidth: 36
|
|
4284
4410
|
},
|
|
4285
4411
|
children: jsx(MoreVert, {})
|
|
4286
|
-
}), jsx(Menu, {
|
|
4412
|
+
}), jsx(Menu$1, {
|
|
4287
4413
|
anchorEl: anchorEl,
|
|
4288
4414
|
open: isMenuOpen,
|
|
4289
4415
|
onClose: handleMenuClose,
|
|
@@ -4522,7 +4648,7 @@ function CoverImageHeader(props) {
|
|
|
4522
4648
|
const convertedActions = modelActions ? modelActions.filter(action => typeof action.id === 'string' && !!action.id).map(action => ({
|
|
4523
4649
|
...action,
|
|
4524
4650
|
id: action.id,
|
|
4525
|
-
onClick: () => console.
|
|
4651
|
+
onClick: () => console.debug(`Action clicked: ${action.id}`) // Default handler for data-driven actions
|
|
4526
4652
|
})) : [];
|
|
4527
4653
|
return jsx(CoverImageHeaderView, {
|
|
4528
4654
|
...viewProps,
|
|
@@ -5079,6 +5205,11 @@ function LogoView({
|
|
|
5079
5205
|
// If image is a React node, render it directly
|
|
5080
5206
|
return jsx("div", {
|
|
5081
5207
|
className: "logo-image-container",
|
|
5208
|
+
style: {
|
|
5209
|
+
display: 'flex',
|
|
5210
|
+
alignItems: 'center',
|
|
5211
|
+
justifyContent: 'center'
|
|
5212
|
+
},
|
|
5082
5213
|
children: image
|
|
5083
5214
|
});
|
|
5084
5215
|
};
|
|
@@ -5092,7 +5223,8 @@ function LogoView({
|
|
|
5092
5223
|
xmlns: "http://www.w3.org/2000/svg",
|
|
5093
5224
|
className: `logo-svg dynamic-logo ${sizeClass} ${variantClass}`.trim(),
|
|
5094
5225
|
style: {
|
|
5095
|
-
height: `${height}px
|
|
5226
|
+
height: `${height}px`,
|
|
5227
|
+
...style
|
|
5096
5228
|
},
|
|
5097
5229
|
role: "img",
|
|
5098
5230
|
"aria-label": ariaLabel,
|
|
@@ -5202,7 +5334,6 @@ function Logo(props) {
|
|
|
5202
5334
|
}
|
|
5203
5335
|
// Show error state
|
|
5204
5336
|
if (error) {
|
|
5205
|
-
console.error('Error loading logo:', error);
|
|
5206
5337
|
return jsxs("div", {
|
|
5207
5338
|
style: {
|
|
5208
5339
|
color: 'red',
|
|
@@ -5212,7 +5343,6 @@ function Logo(props) {
|
|
|
5212
5343
|
children: ["Error loading logo: ", error.message]
|
|
5213
5344
|
});
|
|
5214
5345
|
}
|
|
5215
|
-
console.log('Resolved props for Logo:', logoProps);
|
|
5216
5346
|
return jsx(LogoView, {
|
|
5217
5347
|
...logoProps
|
|
5218
5348
|
});
|
|
@@ -16524,7 +16654,6 @@ function SafeSpanWithDataBinding(props) {
|
|
|
16524
16654
|
});
|
|
16525
16655
|
}
|
|
16526
16656
|
}
|
|
16527
|
-
console.log('Resolved props for SafeSpan:', safeSpanProps);
|
|
16528
16657
|
return jsx(SafeSpanView, {
|
|
16529
16658
|
...safeSpanProps
|
|
16530
16659
|
});
|
|
@@ -17442,7 +17571,6 @@ class Html extends ModelView {
|
|
|
17442
17571
|
if (version !== Html.version) {
|
|
17443
17572
|
console.warn(`Version mismatch: Expected ${Html.version} but got ${version}`);
|
|
17444
17573
|
}
|
|
17445
|
-
console.log(`TEST: Creating ${tagName} - ${version} from JSON:`, jsonData);
|
|
17446
17574
|
const {
|
|
17447
17575
|
children,
|
|
17448
17576
|
...props
|
|
@@ -17611,7 +17739,6 @@ class ReactNodeTransformer {
|
|
|
17611
17739
|
// Handle React elements
|
|
17612
17740
|
if (/*#__PURE__*/isValidElement(node)) {
|
|
17613
17741
|
const element = node;
|
|
17614
|
-
console.log(`TEST: isValidElement:`, element);
|
|
17615
17742
|
const comp = element.type;
|
|
17616
17743
|
const rawName = typeof comp === 'string' ? comp : comp?.render?.name || comp?.name || comp?.muiName || comp?.displayName || 'Anonymous';
|
|
17617
17744
|
// Normalize wrapper names like ForwardRef(Typography), Styled(Typography)
|
|
@@ -17724,7 +17851,6 @@ class ReactNodeTransformer {
|
|
|
17724
17851
|
// Handle HTML elements
|
|
17725
17852
|
if (typeof elementType === 'string') {
|
|
17726
17853
|
const deserializedProps = ReactNodeTransformer.deserializeProps(props);
|
|
17727
|
-
console.log(`TEST: Create Element:`, elementType, deserializedProps);
|
|
17728
17854
|
return /*#__PURE__*/createElement(elementType, {
|
|
17729
17855
|
key,
|
|
17730
17856
|
...deserializedProps
|
|
@@ -17851,7 +17977,6 @@ class ComponentTransformer {
|
|
|
17851
17977
|
if (componentRegistry.has(tagName)) {
|
|
17852
17978
|
console.warn(`Component '${tagName}' is already registered. Overwriting existing registration.`);
|
|
17853
17979
|
}
|
|
17854
|
-
console.log(`TEST: Registering component: ${tagName} (version ${version})`);
|
|
17855
17980
|
componentRegistry.set(tagName, componentClass);
|
|
17856
17981
|
// Register HTML patterns if component supports them
|
|
17857
17982
|
if (typeof componentClass.registerPatternHandlers === 'function') {
|
|
@@ -17965,13 +18090,9 @@ class ComponentTransformer {
|
|
|
17965
18090
|
if (typeof componentType === 'function') {
|
|
17966
18091
|
const tagName = ComponentTransformer.findTagNameForComponent(componentType);
|
|
17967
18092
|
if (tagName) {
|
|
17968
|
-
console.log(`TEST: Serializing component instance of ${tagName}:`, element.props);
|
|
17969
18093
|
const componentClass = componentRegistry.get(tagName);
|
|
17970
18094
|
let serializedData = null;
|
|
17971
|
-
console.log(`TEST: Element type:`, typeof element.toJson);
|
|
17972
|
-
console.log(`TEST: Component type:`, typeof componentClass.toJson);
|
|
17973
18095
|
if (typeof componentClass.toJson === 'function') {
|
|
17974
|
-
console.log(`TEST: Serializing via component toJson method ${tagName}:`, element.props);
|
|
17975
18096
|
serializedData = componentClass.toJson(element.props);
|
|
17976
18097
|
}
|
|
17977
18098
|
if (serializedData !== null) {
|
|
@@ -17983,7 +18104,6 @@ class ComponentTransformer {
|
|
|
17983
18104
|
...key,
|
|
17984
18105
|
...serializedData
|
|
17985
18106
|
};
|
|
17986
|
-
console.log(`TEST: Serialized component ${tagName}:`, result);
|
|
17987
18107
|
return result;
|
|
17988
18108
|
}
|
|
17989
18109
|
} else if (strictMode) {
|
|
@@ -18001,8 +18121,6 @@ class ComponentTransformer {
|
|
|
18001
18121
|
version: FALLBACK_VERSION,
|
|
18002
18122
|
data: ReactNodeTransformer.serialize(node)
|
|
18003
18123
|
};
|
|
18004
|
-
console.log(`TEST: Serialized unregistered node as ${FALLBACK_TAG}:`, result, node);
|
|
18005
|
-
console.log(`TEST: Component Registry:`, componentRegistry);
|
|
18006
18124
|
return result;
|
|
18007
18125
|
}
|
|
18008
18126
|
/**
|
|
@@ -18266,11 +18384,13 @@ function ArticleView({
|
|
|
18266
18384
|
// Ensure proper width constraints for article content
|
|
18267
18385
|
maxWidth: '800px',
|
|
18268
18386
|
mx: 'auto',
|
|
18387
|
+
p: 3,
|
|
18269
18388
|
// Header styling when headers are present
|
|
18270
18389
|
'& h1, & h2, & h3, & h4, & h5, & h6': {
|
|
18271
18390
|
maxWidth: '100%',
|
|
18272
|
-
mb:
|
|
18273
|
-
mt:
|
|
18391
|
+
mb: 2,
|
|
18392
|
+
mt: 3,
|
|
18393
|
+
color: 'var(--theme-text-primary)',
|
|
18274
18394
|
'&:first-of-type': {
|
|
18275
18395
|
mt: 0
|
|
18276
18396
|
}
|
|
@@ -18290,15 +18410,85 @@ function ArticleView({
|
|
|
18290
18410
|
fontWeight: 600,
|
|
18291
18411
|
lineHeight: 1.4
|
|
18292
18412
|
},
|
|
18413
|
+
'& h4': {
|
|
18414
|
+
fontSize: '1.25rem',
|
|
18415
|
+
fontWeight: 600,
|
|
18416
|
+
lineHeight: 1.4,
|
|
18417
|
+
mt: 2.5,
|
|
18418
|
+
mb: 1.5
|
|
18419
|
+
},
|
|
18293
18420
|
// Ensure paragraphs have proper spacing
|
|
18294
18421
|
'& p': {
|
|
18295
|
-
mb:
|
|
18296
|
-
lineHeight: 1.
|
|
18422
|
+
mb: 2,
|
|
18423
|
+
lineHeight: 1.8,
|
|
18424
|
+
fontSize: '1.1rem',
|
|
18425
|
+
color: 'var(--theme-text-primary)'
|
|
18297
18426
|
},
|
|
18298
18427
|
// Ensure lists have proper spacing
|
|
18299
18428
|
'& ul, & ol': {
|
|
18300
|
-
mb:
|
|
18301
|
-
pl:
|
|
18429
|
+
mb: 2.5,
|
|
18430
|
+
pl: 4,
|
|
18431
|
+
'& li': {
|
|
18432
|
+
mb: 1,
|
|
18433
|
+
lineHeight: 1.8,
|
|
18434
|
+
fontSize: '1.05rem',
|
|
18435
|
+
color: 'var(--theme-text-primary)'
|
|
18436
|
+
}
|
|
18437
|
+
},
|
|
18438
|
+
// Blockquote styling
|
|
18439
|
+
'& blockquote': {
|
|
18440
|
+
borderLeft: '4px solid var(--theme-primary)',
|
|
18441
|
+
pl: 3,
|
|
18442
|
+
pr: 2,
|
|
18443
|
+
py: 2,
|
|
18444
|
+
my: 3,
|
|
18445
|
+
ml: 0,
|
|
18446
|
+
mr: 0,
|
|
18447
|
+
background: 'var(--theme-surface)',
|
|
18448
|
+
borderRadius: '8px',
|
|
18449
|
+
'& p': {
|
|
18450
|
+
fontSize: '1.15rem',
|
|
18451
|
+
fontStyle: 'italic',
|
|
18452
|
+
lineHeight: 1.7,
|
|
18453
|
+
mb: 1,
|
|
18454
|
+
color: 'var(--theme-text-primary)'
|
|
18455
|
+
},
|
|
18456
|
+
'& cite': {
|
|
18457
|
+
display: 'block',
|
|
18458
|
+
fontSize: '0.95rem',
|
|
18459
|
+
fontStyle: 'normal',
|
|
18460
|
+
fontWeight: 600,
|
|
18461
|
+
color: 'var(--theme-text-secondary)',
|
|
18462
|
+
mt: 1
|
|
18463
|
+
}
|
|
18464
|
+
},
|
|
18465
|
+
// Strong/bold text
|
|
18466
|
+
'& strong': {
|
|
18467
|
+
fontWeight: 600,
|
|
18468
|
+
color: 'var(--theme-text-primary)'
|
|
18469
|
+
},
|
|
18470
|
+
// Emphasis/italic text
|
|
18471
|
+
'& em': {
|
|
18472
|
+
fontStyle: 'italic',
|
|
18473
|
+
color: 'var(--theme-text-primary)'
|
|
18474
|
+
},
|
|
18475
|
+
// Links
|
|
18476
|
+
'& a': {
|
|
18477
|
+
color: 'var(--theme-primary)',
|
|
18478
|
+
textDecoration: 'none',
|
|
18479
|
+
fontWeight: 500,
|
|
18480
|
+
'&:hover': {
|
|
18481
|
+
textDecoration: 'underline'
|
|
18482
|
+
}
|
|
18483
|
+
},
|
|
18484
|
+
// Images and figures
|
|
18485
|
+
'& figure': {
|
|
18486
|
+
margin: '2rem 0',
|
|
18487
|
+
'& img': {
|
|
18488
|
+
maxWidth: '100%',
|
|
18489
|
+
height: 'auto',
|
|
18490
|
+
borderRadius: '8px'
|
|
18491
|
+
}
|
|
18302
18492
|
},
|
|
18303
18493
|
...styleProps.sx,
|
|
18304
18494
|
children: html
|
|
@@ -18414,7 +18604,6 @@ function ArticleWithDataBinding(props) {
|
|
|
18414
18604
|
});
|
|
18415
18605
|
}
|
|
18416
18606
|
}
|
|
18417
|
-
console.log('Resolved props for Article:', articleProps);
|
|
18418
18607
|
return jsx(ArticleView, {
|
|
18419
18608
|
...articleProps
|
|
18420
18609
|
});
|
|
@@ -19167,7 +19356,7 @@ function PageBannerHeaderView({
|
|
|
19167
19356
|
borderColor: 'divider'
|
|
19168
19357
|
},
|
|
19169
19358
|
children: jsx(MoreVert, {})
|
|
19170
|
-
}), jsx(Menu, {
|
|
19359
|
+
}), jsx(Menu$1, {
|
|
19171
19360
|
anchorEl: anchorEl,
|
|
19172
19361
|
open: isMenuOpen,
|
|
19173
19362
|
onClose: handleMenuClose,
|
|
@@ -19345,7 +19534,7 @@ function PageBannerHeader(props) {
|
|
|
19345
19534
|
destructive: action.destructive,
|
|
19346
19535
|
priority: action.priority,
|
|
19347
19536
|
onClick: () => {
|
|
19348
|
-
console.
|
|
19537
|
+
console.debug(`Action clicked: ${action.id} - ${action.label}`);
|
|
19349
19538
|
// In a real app, this would dispatch events or call configured handlers
|
|
19350
19539
|
}
|
|
19351
19540
|
}));
|
|
@@ -20822,9 +21011,9 @@ function FooterView({
|
|
|
20822
21011
|
// Force vertical on mobile for better usability
|
|
20823
21012
|
const effectiveOrientation = isMobile ? 'vertical' : orientation;
|
|
20824
21013
|
const renderFooterItem = item => {
|
|
20825
|
-
const content = jsx(
|
|
21014
|
+
const content = jsx(Text$1, {
|
|
20826
21015
|
variant: "body2",
|
|
20827
|
-
|
|
21016
|
+
customColor: "var(--theme-text-secondary)",
|
|
20828
21017
|
sx: {
|
|
20829
21018
|
textDecoration: item.href ? 'none' : 'inherit',
|
|
20830
21019
|
'&:hover': item.href ? {
|
|
@@ -20860,14 +21049,14 @@ function FooterView({
|
|
|
20860
21049
|
sx: {
|
|
20861
21050
|
minWidth: 0
|
|
20862
21051
|
},
|
|
20863
|
-
children: [section.title && jsx(
|
|
21052
|
+
children: [section.title && jsx(Text$1, {
|
|
20864
21053
|
variant: "subtitle2",
|
|
20865
21054
|
component: "h3",
|
|
20866
21055
|
sx: {
|
|
20867
21056
|
fontWeight: 600,
|
|
20868
|
-
mb: 1.5
|
|
20869
|
-
color: 'text.primary'
|
|
21057
|
+
mb: 1.5
|
|
20870
21058
|
},
|
|
21059
|
+
customColor: "var(--theme-text-primary)",
|
|
20871
21060
|
children: section.title
|
|
20872
21061
|
}), jsx(Box, {
|
|
20873
21062
|
children: section.items.map(item => renderFooterItem(item))
|
|
@@ -20983,13 +21172,13 @@ function FooterView({
|
|
|
20983
21172
|
},
|
|
20984
21173
|
gap: 1
|
|
20985
21174
|
},
|
|
20986
|
-
children: [copyright && jsx(
|
|
21175
|
+
children: [copyright && jsx(Text$1, {
|
|
20987
21176
|
variant: "caption",
|
|
20988
|
-
|
|
21177
|
+
customColor: 'var(--theme-text-secondary)',
|
|
20989
21178
|
children: copyright
|
|
20990
|
-
}), legalText && jsx(
|
|
21179
|
+
}), legalText && jsx(Text$1, {
|
|
20991
21180
|
variant: "caption",
|
|
20992
|
-
|
|
21181
|
+
customColor: "var(--theme-text-secondary)",
|
|
20993
21182
|
children: legalText
|
|
20994
21183
|
})]
|
|
20995
21184
|
})
|
|
@@ -21035,9 +21224,9 @@ function Footer(props) {
|
|
|
21035
21224
|
},
|
|
21036
21225
|
textAlign: 'center'
|
|
21037
21226
|
},
|
|
21038
|
-
children: jsx(
|
|
21227
|
+
children: jsx(Text$1, {
|
|
21039
21228
|
variant: "body2",
|
|
21040
|
-
|
|
21229
|
+
customColor: "var(--theme-text-secondary)",
|
|
21041
21230
|
children: "Loading Footer..."
|
|
21042
21231
|
})
|
|
21043
21232
|
});
|
|
@@ -21056,9 +21245,9 @@ function Footer(props) {
|
|
|
21056
21245
|
},
|
|
21057
21246
|
textAlign: 'center'
|
|
21058
21247
|
},
|
|
21059
|
-
children: jsxs(
|
|
21248
|
+
children: jsxs(Text$1, {
|
|
21060
21249
|
variant: "body2",
|
|
21061
|
-
|
|
21250
|
+
customColor: 'var(--theme-error)',
|
|
21062
21251
|
children: ["Error Loading Footer: ", error.message]
|
|
21063
21252
|
})
|
|
21064
21253
|
});
|
|
@@ -22063,7 +22252,7 @@ function ThemeSwitcherView({
|
|
|
22063
22252
|
},
|
|
22064
22253
|
className: styleProps.className,
|
|
22065
22254
|
children: getCurrentIcon()
|
|
22066
|
-
}), jsxs(Menu, {
|
|
22255
|
+
}), jsxs(Menu$1, {
|
|
22067
22256
|
id: "theme-menu",
|
|
22068
22257
|
anchorEl: anchorEl,
|
|
22069
22258
|
open: open,
|
|
@@ -22433,7 +22622,7 @@ function PaletteSwitcherView({
|
|
|
22433
22622
|
},
|
|
22434
22623
|
children: jsx(Palette, {})
|
|
22435
22624
|
})
|
|
22436
|
-
}), jsx(Menu, {
|
|
22625
|
+
}), jsx(Menu$1, {
|
|
22437
22626
|
id: "palette-menu",
|
|
22438
22627
|
anchorEl: anchorEl,
|
|
22439
22628
|
open: open,
|
|
@@ -23138,9 +23327,21 @@ const Scaffold = ({
|
|
|
23138
23327
|
}
|
|
23139
23328
|
}
|
|
23140
23329
|
};
|
|
23141
|
-
//
|
|
23330
|
+
// Transform icon string to component, or use provided ReactNode, or fallback to DefaultIcon
|
|
23142
23331
|
const needsIcon = variant !== 'drawer';
|
|
23143
|
-
|
|
23332
|
+
let displayIcon = null;
|
|
23333
|
+
if (item.icon) {
|
|
23334
|
+
// If icon is a string, transform it to component
|
|
23335
|
+
if (typeof item.icon === 'string') {
|
|
23336
|
+
displayIcon = getIconComponent(item.icon) || (needsIcon ? jsx(RadioButtonUnchecked, {}) : null);
|
|
23337
|
+
} else {
|
|
23338
|
+
// If icon is already a React component, use it
|
|
23339
|
+
displayIcon = item.icon;
|
|
23340
|
+
}
|
|
23341
|
+
} else if (needsIcon) {
|
|
23342
|
+
// No icon provided, use default for primary navigation
|
|
23343
|
+
displayIcon = jsx(RadioButtonUnchecked, {});
|
|
23344
|
+
}
|
|
23144
23345
|
const content = jsxs(Fragment, {
|
|
23145
23346
|
children: [displayIcon && jsx("span", {
|
|
23146
23347
|
className: `menu-item-icon menu-item-icon-${variant}`,
|