@qwickapps/react-framework 1.3.3 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +227 -0
  2. package/dist/components/blocks/Content.d.ts.map +1 -1
  3. package/dist/components/blocks/ProductCard.d.ts.map +1 -1
  4. package/dist/components/forms/FormBlock.d.ts +1 -1
  5. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  6. package/dist/components/input/SwitchInputField.d.ts +28 -0
  7. package/dist/components/input/SwitchInputField.d.ts.map +1 -0
  8. package/dist/components/input/index.d.ts +2 -0
  9. package/dist/components/input/index.d.ts.map +1 -1
  10. package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts +34 -0
  11. package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts.map +1 -0
  12. package/dist/components/layout/CollapsibleLayout/index.d.ts +9 -0
  13. package/dist/components/layout/CollapsibleLayout/index.d.ts.map +1 -0
  14. package/dist/components/layout/index.d.ts +2 -0
  15. package/dist/components/layout/index.d.ts.map +1 -1
  16. package/dist/contexts/ThemeContext.d.ts.map +1 -1
  17. package/dist/index.esm.js +963 -105
  18. package/dist/index.js +967 -101
  19. package/dist/schemas/CollapsibleLayoutSchema.d.ts +31 -0
  20. package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -0
  21. package/dist/schemas/SwitchInputFieldSchema.d.ts +18 -0
  22. package/dist/schemas/SwitchInputFieldSchema.d.ts.map +1 -0
  23. package/dist/types/CollapsibleLayout.d.ts +142 -0
  24. package/dist/types/CollapsibleLayout.d.ts.map +1 -0
  25. package/dist/types/index.d.ts +1 -0
  26. package/dist/types/index.d.ts.map +1 -1
  27. package/package.json +1 -1
  28. package/src/components/blocks/Content.tsx +25 -77
  29. package/src/components/blocks/ProductCard.tsx +50 -51
  30. package/src/components/forms/FormBlock.tsx +2 -2
  31. package/src/components/input/SwitchInputField.tsx +165 -0
  32. package/src/components/input/index.ts +2 -0
  33. package/src/components/layout/CollapsibleLayout/CollapsibleLayout.tsx +554 -0
  34. package/src/components/layout/CollapsibleLayout/__tests__/CollapsibleLayout.test.tsx +1469 -0
  35. package/src/components/layout/CollapsibleLayout/index.tsx +17 -0
  36. package/src/components/layout/index.ts +4 -1
  37. package/src/components/pages/FormPage.tsx +1 -1
  38. package/src/contexts/ThemeContext.tsx +1 -2
  39. package/src/schemas/CollapsibleLayoutSchema.ts +276 -0
  40. package/src/schemas/SwitchInputFieldSchema.ts +99 -0
  41. package/src/stories/CollapsibleLayout.stories.tsx +1566 -0
  42. package/src/types/CollapsibleLayout.ts +231 -0
  43. package/src/types/index.ts +1 -0
package/dist/index.js CHANGED
@@ -13762,72 +13762,62 @@ function ContentView({
13762
13762
  return 3;
13763
13763
  }
13764
13764
  };
13765
- // Content wrapper based on variant
13766
- const ContentWrapper = ({
13767
- children
13768
- }) => {
13769
- const paddingValue = getPadding();
13770
- const mappedMaxWidth = mapToMUIBreakpoint(contentMaxWidth === 'false' ? false : contentMaxWidth);
13771
- const commonSx = {
13772
- textAlign: centered ? 'center' : 'left',
13773
- maxWidth: mappedMaxWidth !== false ? theme.breakpoints.values[mappedMaxWidth] : '100%',
13774
- width: '100%',
13775
- ...(centered && contentMaxWidth && {
13776
- mx: 'auto'
13777
- }),
13778
- p: paddingValue,
13779
- ...styleProps.sx
13780
- };
13781
- switch (variant) {
13782
- case 'elevated':
13783
- return jsxRuntime.jsx(material.Paper, {
13784
- elevation: 4,
13785
- ...htmlProps,
13786
- ...otherProps,
13787
- sx: {
13788
- ...commonSx,
13789
- backgroundColor: theme.palette.background.paper
13790
- },
13791
- children: children
13792
- });
13793
- case 'outlined':
13794
- return jsxRuntime.jsx(material.Paper, {
13795
- variant: "outlined",
13796
- elevation: 0,
13797
- ...htmlProps,
13798
- ...otherProps,
13799
- sx: {
13800
- ...commonSx,
13801
- backgroundColor: 'var(--theme-surface)',
13802
- borderColor: 'var(--theme-border-main)',
13803
- // Use theme border color
13804
- borderWidth: 1,
13805
- borderStyle: 'solid'
13806
- },
13807
- children: children
13808
- });
13809
- case 'filled':
13810
- return jsxRuntime.jsx(material.Box, {
13811
- ...htmlProps,
13812
- ...otherProps,
13813
- sx: {
13814
- ...commonSx,
13815
- backgroundColor: 'var(--theme-surface-variant)',
13816
- // Use theme surface variant
13817
- borderRadius: 1
13818
- },
13819
- children: children
13820
- });
13821
- default:
13822
- return jsxRuntime.jsx(material.Box, {
13823
- ...htmlProps,
13824
- ...otherProps,
13825
- sx: commonSx,
13826
- children: children
13827
- });
13828
- }
13765
+ // Compute stable wrapper element (avoid recreating component type each render which caused remount & focus loss)
13766
+ const paddingValue = getPadding();
13767
+ const mappedMaxWidth = mapToMUIBreakpoint(contentMaxWidth === 'false' ? false : contentMaxWidth);
13768
+ const commonSx = {
13769
+ textAlign: centered ? 'center' : 'left',
13770
+ maxWidth: mappedMaxWidth !== false ? theme.breakpoints.values[mappedMaxWidth] : '100%',
13771
+ width: '100%',
13772
+ ...(centered && contentMaxWidth && {
13773
+ mx: 'auto'
13774
+ }),
13775
+ p: paddingValue,
13776
+ ...styleProps.sx
13777
+ };
13778
+ let Wrapper = material.Box;
13779
+ let wrapperProps = {
13780
+ ...htmlProps,
13781
+ ...otherProps,
13782
+ sx: commonSx
13829
13783
  };
13830
- return jsxRuntime.jsx(ContentWrapper, {
13784
+ if (variant === 'elevated') {
13785
+ Wrapper = material.Paper;
13786
+ wrapperProps = {
13787
+ ...wrapperProps,
13788
+ elevation: 4,
13789
+ sx: {
13790
+ ...commonSx,
13791
+ backgroundColor: theme.palette.background.paper
13792
+ }
13793
+ };
13794
+ } else if (variant === 'outlined') {
13795
+ Wrapper = material.Paper;
13796
+ wrapperProps = {
13797
+ ...wrapperProps,
13798
+ variant: 'outlined',
13799
+ elevation: 0,
13800
+ sx: {
13801
+ ...commonSx,
13802
+ backgroundColor: 'var(--theme-surface)',
13803
+ borderColor: 'var(--theme-border-main)',
13804
+ borderWidth: 1,
13805
+ borderStyle: 'solid'
13806
+ }
13807
+ };
13808
+ } else if (variant === 'filled') {
13809
+ Wrapper = material.Box;
13810
+ wrapperProps = {
13811
+ ...wrapperProps,
13812
+ sx: {
13813
+ ...commonSx,
13814
+ backgroundColor: 'var(--theme-surface-variant)',
13815
+ borderRadius: 1
13816
+ }
13817
+ };
13818
+ }
13819
+ return jsxRuntime.jsx(Wrapper, {
13820
+ ...wrapperProps,
13831
13821
  children: jsxRuntime.jsxs(material.Stack, {
13832
13822
  spacing: 2,
13833
13823
  children: [(title || subtitle) && jsxRuntime.jsxs(material.Box, {
@@ -15336,6 +15326,689 @@ const GridCell = props => {
15336
15326
  };
15337
15327
  GridCell.displayName = 'GridCell';
15338
15328
 
15329
+ /**
15330
+ * CollapsibleLayout Schema - Data model for collapsible layout component
15331
+ *
15332
+ * Advanced expandable/collapsible container with header controls, animations,
15333
+ * content management, and state persistence capabilities.
15334
+ *
15335
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
15336
+ */
15337
+ let CollapsibleLayoutModel = class CollapsibleLayoutModel extends schema.Model {};
15338
+ __decorate([schema.Field({
15339
+ defaultValue: false
15340
+ }), schema.Editor({
15341
+ field_type: schema.FieldType.BOOLEAN,
15342
+ label: 'Collapsed',
15343
+ description: 'Whether the layout is currently collapsed'
15344
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], CollapsibleLayoutModel.prototype, "collapsed", void 0);
15345
+ __decorate([schema.Field({
15346
+ defaultValue: false
15347
+ }), schema.Editor({
15348
+ field_type: schema.FieldType.BOOLEAN,
15349
+ label: 'Default Collapsed',
15350
+ description: 'Initial collapsed state for uncontrolled usage'
15351
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], CollapsibleLayoutModel.prototype, "defaultCollapsed", void 0);
15352
+ __decorate([schema.Field(), schema.Editor({
15353
+ field_type: schema.FieldType.TEXT,
15354
+ label: 'Title',
15355
+ description: 'Main title displayed in the header',
15356
+ placeholder: 'Enter title...'
15357
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "title", void 0);
15358
+ __decorate([schema.Field(), schema.Editor({
15359
+ field_type: schema.FieldType.TEXT,
15360
+ label: 'Subtitle',
15361
+ description: 'Secondary text displayed below the title',
15362
+ placeholder: 'Enter subtitle...'
15363
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "subtitle", void 0);
15364
+ __decorate([schema.Field(), schema.Editor({
15365
+ field_type: schema.FieldType.TEXT,
15366
+ label: 'Lead Icon',
15367
+ description: 'Icon displayed before the title (icon identifier or HTML)',
15368
+ placeholder: 'Icon identifier...'
15369
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "leadIcon", void 0);
15370
+ __decorate([schema.Field(), schema.Editor({
15371
+ field_type: schema.FieldType.TEXTAREA,
15372
+ label: 'Header Actions',
15373
+ description: 'Additional controls displayed in header (HTML/React content)',
15374
+ placeholder: 'Enter header actions HTML...'
15375
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "headerActions", void 0);
15376
+ __decorate([schema.Field(), schema.Editor({
15377
+ field_type: schema.FieldType.TEXTAREA,
15378
+ label: 'Collapsed View',
15379
+ description: 'Summary content shown when collapsed (HTML supported)',
15380
+ placeholder: 'Enter collapsed view content...'
15381
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "collapsedView", void 0);
15382
+ __decorate([schema.Field(), schema.Editor({
15383
+ field_type: schema.FieldType.TEXTAREA,
15384
+ label: 'Content',
15385
+ description: 'Main content shown when expanded (HTML supported)',
15386
+ placeholder: 'Enter main content...'
15387
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "children", void 0);
15388
+ __decorate([schema.Field(), schema.Editor({
15389
+ field_type: schema.FieldType.TEXTAREA,
15390
+ label: 'Footer View',
15391
+ description: 'Always visible footer content (HTML supported)',
15392
+ placeholder: 'Enter footer content...'
15393
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "footerView", void 0);
15394
+ __decorate([schema.Field({
15395
+ defaultValue: 'header'
15396
+ }), schema.Editor({
15397
+ field_type: schema.FieldType.SELECT,
15398
+ label: 'Trigger Area',
15399
+ description: 'Area that responds to clicks for toggle functionality',
15400
+ validation: {
15401
+ options: [{
15402
+ label: 'Button Only',
15403
+ value: 'button'
15404
+ }, {
15405
+ label: 'Header Area',
15406
+ value: 'header'
15407
+ }, {
15408
+ label: 'Button and Header',
15409
+ value: 'both'
15410
+ }]
15411
+ }
15412
+ }), classValidator.IsOptional(), classValidator.IsIn(['button', 'header', 'both']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "triggerArea", void 0);
15413
+ __decorate([schema.Field({
15414
+ defaultValue: 'slide'
15415
+ }), schema.Editor({
15416
+ field_type: schema.FieldType.SELECT,
15417
+ label: 'Animation Style',
15418
+ description: 'Animation variant for expand/collapse transitions',
15419
+ validation: {
15420
+ options: [{
15421
+ label: 'Fade',
15422
+ value: 'fade'
15423
+ }, {
15424
+ label: 'Slide',
15425
+ value: 'slide'
15426
+ }, {
15427
+ label: 'Scale',
15428
+ value: 'scale'
15429
+ }]
15430
+ }
15431
+ }), classValidator.IsOptional(), classValidator.IsIn(['fade', 'slide', 'scale']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "animationStyle", void 0);
15432
+ __decorate([schema.Field({
15433
+ defaultValue: false
15434
+ }), schema.Editor({
15435
+ field_type: schema.FieldType.BOOLEAN,
15436
+ label: 'Persist State',
15437
+ description: 'Save collapse state in local storage'
15438
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], CollapsibleLayoutModel.prototype, "persistState", void 0);
15439
+ __decorate([schema.Field(), schema.Editor({
15440
+ field_type: schema.FieldType.TEXT,
15441
+ label: 'Collapsed Icon',
15442
+ description: 'Icon shown when content is collapsed (default: VisibilityIcon)',
15443
+ placeholder: 'Icon identifier...'
15444
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "collapsedIcon", void 0);
15445
+ __decorate([schema.Field(), schema.Editor({
15446
+ field_type: schema.FieldType.TEXT,
15447
+ label: 'Expanded Icon',
15448
+ description: 'Icon shown when content is expanded (default: VisibilityOffIcon)',
15449
+ placeholder: 'Icon identifier...'
15450
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "expandedIcon", void 0);
15451
+ __decorate([schema.Field({
15452
+ defaultValue: true
15453
+ }), schema.Editor({
15454
+ field_type: schema.FieldType.BOOLEAN,
15455
+ label: 'Show Divider',
15456
+ description: 'Show divider lines between header, content, and footer sections'
15457
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], CollapsibleLayoutModel.prototype, "showDivider", void 0);
15458
+ __decorate([schema.Field({
15459
+ defaultValue: 'default'
15460
+ }), schema.Editor({
15461
+ field_type: schema.FieldType.SELECT,
15462
+ label: 'Variant',
15463
+ description: 'Visual style variant for the layout container',
15464
+ validation: {
15465
+ options: [{
15466
+ label: 'Default',
15467
+ value: 'default'
15468
+ }, {
15469
+ label: 'Outlined',
15470
+ value: 'outlined'
15471
+ }, {
15472
+ label: 'Elevated',
15473
+ value: 'elevated'
15474
+ }, {
15475
+ label: 'Filled',
15476
+ value: 'filled'
15477
+ }]
15478
+ }
15479
+ }), classValidator.IsOptional(), classValidator.IsIn(['default', 'outlined', 'elevated', 'filled']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "variant", void 0);
15480
+ __decorate([schema.Field({
15481
+ defaultValue: 'comfortable'
15482
+ }), schema.Editor({
15483
+ field_type: schema.FieldType.SELECT,
15484
+ label: 'Header Spacing',
15485
+ description: 'Padding/spacing within the header area',
15486
+ validation: {
15487
+ options: [{
15488
+ label: 'Compact',
15489
+ value: 'compact'
15490
+ }, {
15491
+ label: 'Comfortable',
15492
+ value: 'comfortable'
15493
+ }, {
15494
+ label: 'Spacious',
15495
+ value: 'spacious'
15496
+ }]
15497
+ }
15498
+ }), classValidator.IsOptional(), classValidator.IsIn(['compact', 'comfortable', 'spacious']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "headerSpacing", void 0);
15499
+ __decorate([schema.Field({
15500
+ defaultValue: 'comfortable'
15501
+ }), schema.Editor({
15502
+ field_type: schema.FieldType.SELECT,
15503
+ label: 'Content Spacing',
15504
+ description: 'Padding/spacing within the content area',
15505
+ validation: {
15506
+ options: [{
15507
+ label: 'Compact',
15508
+ value: 'compact'
15509
+ }, {
15510
+ label: 'Comfortable',
15511
+ value: 'comfortable'
15512
+ }, {
15513
+ label: 'Spacious',
15514
+ value: 'spacious'
15515
+ }]
15516
+ }
15517
+ }), classValidator.IsOptional(), classValidator.IsIn(['compact', 'comfortable', 'spacious']), __metadata("design:type", String)], CollapsibleLayoutModel.prototype, "contentSpacing", void 0);
15518
+ CollapsibleLayoutModel = __decorate([schema.Schema('CollapsibleLayout', '1.0.0')], CollapsibleLayoutModel);
15519
+ var CollapsibleLayoutModel$1 = CollapsibleLayoutModel;
15520
+
15521
+ /**
15522
+ * TypeScript type definitions for CollapsibleLayout component
15523
+ *
15524
+ * Provides TypeScript interfaces that extend the schema model with React-specific types
15525
+ * and component-level functionality for the CollapsibleLayout component.
15526
+ *
15527
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
15528
+ */
15529
+ /**
15530
+ * Type guard to check if a component has CollapsibleLayout props
15531
+ */
15532
+ function isCollapsibleLayoutProps(props) {
15533
+ return props && typeof props === 'object' && ('collapsed' in props || 'defaultCollapsed' in props);
15534
+ }
15535
+ /**
15536
+ * Default props for CollapsibleLayout component
15537
+ */
15538
+ const defaultCollapsibleLayoutProps = {
15539
+ // Note: collapsed is intentionally omitted so components can be uncontrolled
15540
+ defaultCollapsed: false,
15541
+ triggerArea: 'both',
15542
+ animationStyle: 'slide',
15543
+ persistState: false,
15544
+ showDivider: true,
15545
+ variant: 'default',
15546
+ headerSpacing: 'comfortable',
15547
+ contentSpacing: 'comfortable',
15548
+ animationDuration: 300,
15549
+ disableAnimations: false,
15550
+ toggleAriaLabel: 'Toggle content visibility'
15551
+ };
15552
+ const animationConfigs = {
15553
+ fade: {
15554
+ duration: 300,
15555
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
15556
+ opacity: [0, 1]
15557
+ },
15558
+ slide: {
15559
+ duration: 300,
15560
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
15561
+ transform: 'translateY(-10px)'
15562
+ },
15563
+ scale: {
15564
+ duration: 200,
15565
+ easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
15566
+ transform: 'scale(0.95)',
15567
+ opacity: [0, 1]
15568
+ }
15569
+ };
15570
+ const spacingConfigs = {
15571
+ compact: {
15572
+ padding: '8px 12px',
15573
+ gap: '4px'
15574
+ },
15575
+ comfortable: {
15576
+ padding: '16px 20px',
15577
+ gap: '8px'
15578
+ },
15579
+ spacious: {
15580
+ padding: '24px 32px',
15581
+ gap: '16px'
15582
+ }
15583
+ };
15584
+
15585
+ /**
15586
+ * Custom hook for managing collapsible state - simplified approach
15587
+ */
15588
+ function useCollapsibleState(controlled, collapsedProp, defaultCollapsedProp, onToggleProp, persistState, storageKey) {
15589
+ const id = React.useId();
15590
+ const finalStorageKey = storageKey || `collapsible-${id}`;
15591
+ // For controlled components, use the prop; for uncontrolled, use internal state
15592
+ const [internalCollapsed, setInternalCollapsed] = React.useState(() => {
15593
+ if (controlled) {
15594
+ return collapsedProp ?? false;
15595
+ }
15596
+ // Try localStorage first if persistence is enabled
15597
+ if (persistState && typeof window !== 'undefined') {
15598
+ const stored = localStorage.getItem(finalStorageKey);
15599
+ if (stored !== null) {
15600
+ return JSON.parse(stored);
15601
+ }
15602
+ }
15603
+ return defaultCollapsedProp ?? false;
15604
+ });
15605
+ // Sync with controlled prop changes
15606
+ React.useEffect(() => {
15607
+ if (controlled && collapsedProp !== undefined) {
15608
+ setInternalCollapsed(collapsedProp);
15609
+ }
15610
+ }, [controlled, collapsedProp]);
15611
+ // Persist to localStorage for uncontrolled components
15612
+ React.useEffect(() => {
15613
+ if (!controlled && persistState && typeof window !== 'undefined') {
15614
+ localStorage.setItem(finalStorageKey, JSON.stringify(internalCollapsed));
15615
+ }
15616
+ }, [controlled, internalCollapsed, persistState, finalStorageKey]);
15617
+ const toggle = React.useCallback(() => {
15618
+ const currentState = controlled ? collapsedProp ?? false : internalCollapsed;
15619
+ const newCollapsed = !currentState;
15620
+ // Always update internal state for visual updates
15621
+ setInternalCollapsed(newCollapsed);
15622
+ // Call callback to notify parent
15623
+ onToggleProp?.(newCollapsed);
15624
+ }, [controlled, collapsedProp, internalCollapsed, onToggleProp]);
15625
+ const setCollapsed = React.useCallback(collapsed => {
15626
+ setInternalCollapsed(collapsed);
15627
+ onToggleProp?.(collapsed);
15628
+ }, [onToggleProp]);
15629
+ // Return the appropriate state
15630
+ const finalCollapsed = controlled ? collapsedProp ?? false : internalCollapsed;
15631
+ return {
15632
+ collapsed: finalCollapsed,
15633
+ toggle,
15634
+ setCollapsed,
15635
+ isControlled: controlled
15636
+ };
15637
+ }
15638
+ /**
15639
+ * Core CollapsibleLayout View component
15640
+ */
15641
+ function CollapsibleLayoutView({
15642
+ // State props
15643
+ collapsed: collapsedProp,
15644
+ defaultCollapsed = false,
15645
+ onToggle,
15646
+ // Content props
15647
+ title,
15648
+ subtitle,
15649
+ leadIcon,
15650
+ headerActions,
15651
+ collapsedView,
15652
+ children,
15653
+ footerView,
15654
+ // Behavior props
15655
+ triggerArea = 'both',
15656
+ animationStyle = 'slide',
15657
+ persistState = false,
15658
+ storageKey,
15659
+ animationDuration = 300,
15660
+ disableAnimations = false,
15661
+ // Icons
15662
+ collapsedIcon,
15663
+ expandedIcon,
15664
+ // Layout props
15665
+ showDivider = true,
15666
+ variant = 'default',
15667
+ headerSpacing = 'comfortable',
15668
+ contentSpacing = 'comfortable',
15669
+ // Accessibility
15670
+ toggleAriaLabel = 'Toggle content visibility',
15671
+ 'aria-describedby': ariaDescribedBy,
15672
+ contentAriaProps = {},
15673
+ // CSS classes
15674
+ containerClassName,
15675
+ headerClassName,
15676
+ contentClassName,
15677
+ footerClassName,
15678
+ ...restProps
15679
+ }) {
15680
+ const theme = material.useTheme();
15681
+ const {
15682
+ styleProps,
15683
+ htmlProps,
15684
+ restProps: otherProps
15685
+ } = useBaseProps(restProps);
15686
+ // Mark as QwickApp component
15687
+ CollapsibleLayoutView[QWICKAPP_COMPONENT] = true;
15688
+ // Determine controlled vs uncontrolled usage
15689
+ const controlled = collapsedProp !== undefined;
15690
+ // State management
15691
+ const {
15692
+ collapsed,
15693
+ toggle,
15694
+ setCollapsed
15695
+ } = useCollapsibleState(controlled, collapsedProp, defaultCollapsed, onToggle, persistState, storageKey);
15696
+ // Get spacing configurations
15697
+ const headerSpacingConfig = spacingConfigs[headerSpacing];
15698
+ const contentSpacingConfig = spacingConfigs[contentSpacing];
15699
+ // Get animation configuration
15700
+ const animationConfig = animationConfigs[animationStyle];
15701
+ // Generate unique IDs for accessibility
15702
+ const headerId = React.useId();
15703
+ const contentId = React.useId();
15704
+ // Handle click events
15705
+ const handleHeaderClick = React.useCallback(event => {
15706
+ if (triggerArea === 'header' || triggerArea === 'both') {
15707
+ event.preventDefault();
15708
+ toggle();
15709
+ }
15710
+ }, [triggerArea, toggle]);
15711
+ const handleButtonClick = React.useCallback(event => {
15712
+ event.stopPropagation();
15713
+ toggle();
15714
+ }, [toggle]);
15715
+ // Render icons
15716
+ const renderIcon = React.useCallback((icon, defaultIcon) => {
15717
+ if (/*#__PURE__*/React.isValidElement(icon)) {
15718
+ return icon;
15719
+ }
15720
+ if (typeof icon === 'string') {
15721
+ return jsxRuntime.jsx(Html, {
15722
+ children: icon
15723
+ });
15724
+ }
15725
+ return defaultIcon;
15726
+ }, []);
15727
+ const toggleIcon = renderIcon(collapsed ? collapsedIcon : expandedIcon, collapsed ? jsxRuntime.jsx(iconsMaterial.ExpandMore, {}) : jsxRuntime.jsx(iconsMaterial.ExpandLess, {}));
15728
+ // Container styles based on variant
15729
+ const containerSx = React.useMemo(() => {
15730
+ const baseSx = {
15731
+ width: '100%',
15732
+ position: 'relative',
15733
+ ...styleProps.sx
15734
+ };
15735
+ switch (variant) {
15736
+ case 'outlined':
15737
+ return {
15738
+ ...baseSx,
15739
+ border: `1px solid ${theme.palette.divider}`,
15740
+ borderRadius: 1,
15741
+ backgroundColor: 'var(--theme-surface)'
15742
+ };
15743
+ case 'elevated':
15744
+ return {
15745
+ ...baseSx,
15746
+ boxShadow: theme.shadows[2],
15747
+ borderRadius: 1,
15748
+ backgroundColor: theme.palette.background.paper
15749
+ };
15750
+ case 'filled':
15751
+ return {
15752
+ ...baseSx,
15753
+ backgroundColor: 'var(--theme-surface-variant)',
15754
+ borderRadius: 1
15755
+ };
15756
+ default:
15757
+ return baseSx;
15758
+ }
15759
+ }, [variant, theme, styleProps.sx]);
15760
+ // Header styles
15761
+ const headerSx = React.useMemo(() => ({
15762
+ ...headerSpacingConfig,
15763
+ cursor: triggerArea === 'header' || triggerArea === 'both' ? 'pointer' : 'default',
15764
+ userSelect: 'none',
15765
+ display: 'flex',
15766
+ alignItems: 'center',
15767
+ justifyContent: 'space-between',
15768
+ '&:hover': triggerArea === 'header' || triggerArea === 'both' ? {
15769
+ backgroundColor: 'rgba(0, 0, 0, 0.04)'
15770
+ } : {}
15771
+ }), [headerSpacingConfig, triggerArea]);
15772
+ // Content styles
15773
+ const contentSx = React.useMemo(() => ({
15774
+ ...contentSpacingConfig
15775
+ }), [contentSpacingConfig]);
15776
+ // Animation props for Collapse component
15777
+ const collapseProps = React.useMemo(() => {
15778
+ if (disableAnimations) {
15779
+ return {
15780
+ timeout: 0
15781
+ };
15782
+ }
15783
+ const baseProps = {
15784
+ timeout: animationDuration
15785
+ };
15786
+ switch (animationStyle) {
15787
+ case 'fade':
15788
+ return {
15789
+ ...baseProps,
15790
+ sx: {
15791
+ '& .MuiCollapse-wrapper': {
15792
+ opacity: collapsed ? 0 : 1,
15793
+ transition: `opacity ${animationDuration}ms ${animationConfig.easing}`
15794
+ }
15795
+ }
15796
+ };
15797
+ case 'scale':
15798
+ return {
15799
+ ...baseProps,
15800
+ sx: {
15801
+ '& .MuiCollapse-wrapper': {
15802
+ transform: collapsed ? 'scale(0.95)' : 'scale(1)',
15803
+ opacity: collapsed ? 0 : 1,
15804
+ transition: `all ${animationDuration}ms ${animationConfig.easing}`
15805
+ }
15806
+ }
15807
+ };
15808
+ default:
15809
+ // slide
15810
+ return baseProps;
15811
+ }
15812
+ }, [disableAnimations, animationDuration, animationStyle, animationConfig, collapsed]);
15813
+ // Render content based on type
15814
+ const renderContent = React.useCallback(content => {
15815
+ if (!content) return null;
15816
+ if (typeof content === 'string') {
15817
+ return jsxRuntime.jsx(Html, {
15818
+ children: content
15819
+ });
15820
+ }
15821
+ return content;
15822
+ }, []);
15823
+ // Container content that will be wrapped
15824
+ const containerContent = jsxRuntime.jsxs(jsxRuntime.Fragment, {
15825
+ children: [(title || subtitle || leadIcon || headerActions || triggerArea === 'button' || triggerArea === 'both') && jsxRuntime.jsxs(jsxRuntime.Fragment, {
15826
+ children: [jsxRuntime.jsxs(material.Box, {
15827
+ id: headerId,
15828
+ className: headerClassName,
15829
+ sx: headerSx,
15830
+ onClick: handleHeaderClick,
15831
+ role: triggerArea === 'header' || triggerArea === 'both' ? 'button' : undefined,
15832
+ tabIndex: triggerArea === 'header' || triggerArea === 'both' ? 0 : undefined,
15833
+ "aria-expanded": !collapsed,
15834
+ "aria-controls": contentId,
15835
+ "aria-describedby": ariaDescribedBy,
15836
+ onKeyDown: e => {
15837
+ if ((triggerArea === 'header' || triggerArea === 'both') && (e.key === 'Enter' || e.key === ' ')) {
15838
+ e.preventDefault();
15839
+ toggle();
15840
+ }
15841
+ },
15842
+ children: [jsxRuntime.jsxs(material.Stack, {
15843
+ direction: "row",
15844
+ spacing: 2,
15845
+ alignItems: "center",
15846
+ sx: {
15847
+ minWidth: 0,
15848
+ flex: 1
15849
+ },
15850
+ children: [leadIcon && jsxRuntime.jsx(material.Box, {
15851
+ sx: {
15852
+ flexShrink: 0
15853
+ },
15854
+ children: renderContent(leadIcon)
15855
+ }), (title || subtitle) && jsxRuntime.jsxs(material.Box, {
15856
+ sx: {
15857
+ minWidth: 0,
15858
+ flex: 1
15859
+ },
15860
+ children: [title && jsxRuntime.jsx(material.Typography, {
15861
+ variant: "h6",
15862
+ component: "h3",
15863
+ sx: {
15864
+ fontWeight: 600,
15865
+ lineHeight: 1.2,
15866
+ ...(subtitle && {
15867
+ mb: 0.5
15868
+ })
15869
+ },
15870
+ children: title
15871
+ }), subtitle && jsxRuntime.jsx(material.Typography, {
15872
+ variant: "body2",
15873
+ color: "text.secondary",
15874
+ sx: {
15875
+ lineHeight: 1.3
15876
+ },
15877
+ children: subtitle
15878
+ })]
15879
+ })]
15880
+ }), jsxRuntime.jsxs(material.Stack, {
15881
+ direction: "row",
15882
+ spacing: 1,
15883
+ alignItems: "center",
15884
+ sx: {
15885
+ flexShrink: 0
15886
+ },
15887
+ children: [headerActions && jsxRuntime.jsx(material.Box, {
15888
+ children: renderContent(headerActions)
15889
+ }), jsxRuntime.jsx(material.IconButton, {
15890
+ onClick: handleButtonClick,
15891
+ size: "small",
15892
+ "aria-label": toggleAriaLabel,
15893
+ "aria-expanded": !collapsed,
15894
+ "aria-controls": contentId,
15895
+ children: toggleIcon
15896
+ })]
15897
+ })]
15898
+ }), showDivider && jsxRuntime.jsx(material.Divider, {})]
15899
+ }), collapsed && collapsedView && jsxRuntime.jsxs(jsxRuntime.Fragment, {
15900
+ children: [jsxRuntime.jsx(material.Box, {
15901
+ className: contentClassName,
15902
+ sx: contentSx,
15903
+ children: renderContent(collapsedView)
15904
+ }), showDivider && footerView && jsxRuntime.jsx(material.Divider, {})]
15905
+ }), jsxRuntime.jsxs(material.Collapse, {
15906
+ in: !collapsed,
15907
+ ...collapseProps,
15908
+ children: [jsxRuntime.jsx(material.Box, {
15909
+ id: contentId,
15910
+ className: contentClassName,
15911
+ sx: contentSx,
15912
+ role: "region",
15913
+ "aria-labelledby": title ? headerId : undefined,
15914
+ ...contentAriaProps,
15915
+ children: renderContent(children)
15916
+ }), showDivider && footerView && jsxRuntime.jsx(material.Divider, {})]
15917
+ }), footerView && jsxRuntime.jsx(material.Box, {
15918
+ className: footerClassName,
15919
+ sx: contentSx,
15920
+ children: renderContent(footerView)
15921
+ })]
15922
+ });
15923
+ // Return appropriate container based on variant
15924
+ if (variant === 'outlined') {
15925
+ return jsxRuntime.jsx(material.Paper, {
15926
+ variant: "outlined",
15927
+ elevation: 0,
15928
+ ...htmlProps,
15929
+ ...otherProps,
15930
+ className: containerClassName,
15931
+ sx: containerSx,
15932
+ children: containerContent
15933
+ });
15934
+ }
15935
+ if (variant === 'elevated') {
15936
+ return jsxRuntime.jsx(material.Paper, {
15937
+ elevation: 2,
15938
+ ...htmlProps,
15939
+ ...otherProps,
15940
+ className: containerClassName,
15941
+ sx: containerSx,
15942
+ children: containerContent
15943
+ });
15944
+ }
15945
+ // Default variant (default, filled)
15946
+ return jsxRuntime.jsx(material.Box, {
15947
+ ...htmlProps,
15948
+ ...otherProps,
15949
+ className: containerClassName,
15950
+ sx: containerSx,
15951
+ children: containerContent
15952
+ });
15953
+ }
15954
+ /**
15955
+ * Main CollapsibleLayout component with data binding support
15956
+ */
15957
+ function CollapsibleLayout(props) {
15958
+ const {
15959
+ dataSource,
15960
+ bindingOptions,
15961
+ ...restProps
15962
+ } = props;
15963
+ // If no dataSource, use traditional props
15964
+ if (!dataSource) {
15965
+ return jsxRuntime.jsx(CollapsibleLayoutView, {
15966
+ ...restProps
15967
+ });
15968
+ }
15969
+ // Use data binding
15970
+ const {
15971
+ dataSource: _source,
15972
+ loading,
15973
+ error,
15974
+ cached,
15975
+ ...collapsibleProps
15976
+ } = useDataBinding(dataSource, restProps, CollapsibleLayoutModel$1.getSchema(), {
15977
+ cache: true,
15978
+ cacheTTL: 300000,
15979
+ strict: false,
15980
+ ...bindingOptions
15981
+ });
15982
+ // Show loading state
15983
+ if (loading) {
15984
+ return jsxRuntime.jsx(CollapsibleLayoutView, {
15985
+ ...restProps,
15986
+ title: "Loading...",
15987
+ variant: "default",
15988
+ headerSpacing: "comfortable",
15989
+ contentSpacing: "comfortable"
15990
+ });
15991
+ }
15992
+ if (error) {
15993
+ console.error('Error loading collapsible layout:', error);
15994
+ {
15995
+ return jsxRuntime.jsx(CollapsibleLayoutView, {
15996
+ ...restProps,
15997
+ title: "Error Loading Layout",
15998
+ subtitle: error.message,
15999
+ variant: "outlined",
16000
+ headerSpacing: "comfortable",
16001
+ contentSpacing: "comfortable"
16002
+ });
16003
+ }
16004
+ }
16005
+ return jsxRuntime.jsx(CollapsibleLayoutView, {
16006
+ ...collapsibleProps
16007
+ });
16008
+ }
16009
+ // Set default props
16010
+ CollapsibleLayout.defaultProps = defaultCollapsibleLayoutProps;
16011
+
15339
16012
  /**
15340
16013
  * FeatureCard Schema - Schema definition for FeatureCard component
15341
16014
  *
@@ -16456,7 +17129,9 @@ function ProductCardView({
16456
17129
  return actions;
16457
17130
  };
16458
17131
  const displayActions = actions || getDefaultActions();
16459
- const FeaturesList = () => {
17132
+ // INLINE WRAPPERS REFACTORED: Instead of inline component declarations (which cause remounts),
17133
+ // compute JSX fragments via plain variables/functions and inject directly.
17134
+ const featuresListElement = (() => {
16460
17135
  const featuresToShow = variant === 'compact' ? (product.features || []).slice(0, maxFeaturesCompact) : product.features || [];
16461
17136
  return jsxRuntime.jsxs(material.Box, {
16462
17137
  sx: {
@@ -16516,40 +17191,37 @@ function ProductCardView({
16516
17191
  })]
16517
17192
  })]
16518
17193
  });
16519
- };
16520
- const TechnologiesSection = () => {
16521
- if (!showTechnologies || variant === 'compact') return null;
16522
- return jsxRuntime.jsxs(material.Box, {
17194
+ })();
17195
+ const technologiesSectionElement = !showTechnologies || variant === 'compact' ? null : jsxRuntime.jsxs(material.Box, {
17196
+ sx: {
17197
+ mb: 3
17198
+ },
17199
+ children: [jsxRuntime.jsx(material.Typography, {
17200
+ variant: "h6",
17201
+ component: "h4",
16523
17202
  sx: {
16524
- mb: 3
17203
+ mb: 1.5,
17204
+ fontSize: '1rem',
17205
+ fontWeight: 600
16525
17206
  },
16526
- children: [jsxRuntime.jsx(material.Typography, {
16527
- variant: "h6",
16528
- component: "h4",
16529
- sx: {
16530
- mb: 1.5,
16531
- fontSize: '1rem',
16532
- fontWeight: 600
16533
- },
16534
- children: "Technologies:"
16535
- }), jsxRuntime.jsx(material.Box, {
17207
+ children: "Technologies:"
17208
+ }), jsxRuntime.jsx(material.Box, {
17209
+ sx: {
17210
+ display: 'flex',
17211
+ flexWrap: 'wrap',
17212
+ gap: 1
17213
+ },
17214
+ children: product.technologies.map((tech, index) => jsxRuntime.jsx(material.Chip, {
17215
+ label: tech,
17216
+ variant: "outlined",
17217
+ size: "small",
16536
17218
  sx: {
16537
- display: 'flex',
16538
- flexWrap: 'wrap',
16539
- gap: 1
16540
- },
16541
- children: product.technologies.map((tech, index) => jsxRuntime.jsx(material.Chip, {
16542
- label: tech,
16543
- variant: "outlined",
16544
- size: "small",
16545
- sx: {
16546
- fontSize: '0.8rem',
16547
- fontWeight: 500
16548
- }
16549
- }, index))
16550
- })]
16551
- });
16552
- };
17219
+ fontSize: '0.8rem',
17220
+ fontWeight: 500
17221
+ }
17222
+ }, index))
17223
+ })]
17224
+ });
16553
17225
  return jsxRuntime.jsxs(material.Box, {
16554
17226
  className: styleProps.className || "product-card",
16555
17227
  onClick: htmlProps.onClick || (variant === 'compact' ? handleProductClick : undefined),
@@ -16655,7 +17327,7 @@ function ProductCardView({
16655
17327
  },
16656
17328
  children: variant === 'detailed' ? product.description : product.shortDescription || product.description
16657
17329
  })]
16658
- }), jsxRuntime.jsx(FeaturesList, {}), jsxRuntime.jsx(TechnologiesSection, {}), jsxRuntime.jsx(material.Box, {
17330
+ }), featuresListElement, technologiesSectionElement, jsxRuntime.jsx(material.Box, {
16659
17331
  sx: {
16660
17332
  display: 'flex',
16661
17333
  gap: 1.5,
@@ -17516,7 +18188,6 @@ const ThemeProvider = ({
17516
18188
  }
17517
18189
  }
17518
18190
  });
17519
- // eslint-disable-next-line react-hooks/exhaustive-deps
17520
18191
  }, [actualThemeMode, paletteChangeCounter]); // paletteChangeCounter is needed to force theme rebuild // Re-create theme when palette changes
17521
18192
  // Theme preference management methods
17522
18193
  const setPreferredTheme = theme => {
@@ -18728,7 +19399,7 @@ function FormBlockView({
18728
19399
  title,
18729
19400
  description,
18730
19401
  coverImage,
18731
- form,
19402
+ children: form,
18732
19403
  footer,
18733
19404
  status,
18734
19405
  message,
@@ -19729,6 +20400,193 @@ function SelectInputField(props) {
19729
20400
  // Mark as QwickApp component
19730
20401
  SelectInputField[QWICKAPP_COMPONENT] = true;
19731
20402
 
20403
+ /**
20404
+ * SwitchInputField Schema - Data model for switch input field component
20405
+ *
20406
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
20407
+ */
20408
+ let SwitchInputFieldModel = class SwitchInputFieldModel extends schema.Model {};
20409
+ __decorate([schema.Field(), schema.Editor({
20410
+ field_type: schema.FieldType.TEXT,
20411
+ label: 'Label',
20412
+ description: 'The label text for the switch'
20413
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "label", void 0);
20414
+ __decorate([schema.Field({
20415
+ defaultValue: false
20416
+ }), schema.Editor({
20417
+ field_type: schema.FieldType.BOOLEAN,
20418
+ label: 'Checked',
20419
+ description: 'Whether the switch is checked'
20420
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], SwitchInputFieldModel.prototype, "checked", void 0);
20421
+ __decorate([schema.Field({
20422
+ defaultValue: false
20423
+ }), schema.Editor({
20424
+ field_type: schema.FieldType.BOOLEAN,
20425
+ label: 'Required',
20426
+ description: 'Whether the field is required'
20427
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], SwitchInputFieldModel.prototype, "required", void 0);
20428
+ __decorate([schema.Field({
20429
+ defaultValue: false
20430
+ }), schema.Editor({
20431
+ field_type: schema.FieldType.BOOLEAN,
20432
+ label: 'Disabled',
20433
+ description: 'Whether the field is disabled'
20434
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], SwitchInputFieldModel.prototype, "disabled", void 0);
20435
+ __decorate([schema.Field(), schema.Editor({
20436
+ field_type: schema.FieldType.TEXT,
20437
+ label: 'Error',
20438
+ description: 'Error message to display'
20439
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "error", void 0);
20440
+ __decorate([schema.Field(), schema.Editor({
20441
+ field_type: schema.FieldType.TEXT,
20442
+ label: 'Helper Text',
20443
+ description: 'Helper text to display below the switch'
20444
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "helperText", void 0);
20445
+ __decorate([schema.Field({
20446
+ defaultValue: 'medium'
20447
+ }), schema.Editor({
20448
+ field_type: schema.FieldType.SELECT,
20449
+ label: 'Size',
20450
+ description: 'Size of the switch'
20451
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "size", void 0);
20452
+ __decorate([schema.Field({
20453
+ defaultValue: 'primary'
20454
+ }), schema.Editor({
20455
+ field_type: schema.FieldType.SELECT,
20456
+ label: 'Color',
20457
+ description: 'Color theme of the switch'
20458
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], SwitchInputFieldModel.prototype, "color", void 0);
20459
+ SwitchInputFieldModel = __decorate([schema.Schema('SwitchInputField', '1.0.0')], SwitchInputFieldModel);
20460
+ var SwitchInputFieldModel$1 = SwitchInputFieldModel;
20461
+
20462
+ // View component - handles the actual rendering
20463
+ function SwitchInputFieldView({
20464
+ label,
20465
+ checked = false,
20466
+ onChange,
20467
+ onFocus,
20468
+ required = false,
20469
+ disabled = false,
20470
+ error,
20471
+ helperText,
20472
+ size = 'medium',
20473
+ color = 'primary',
20474
+ ...restProps
20475
+ }) {
20476
+ const {
20477
+ styleProps,
20478
+ htmlProps
20479
+ } = useBaseProps(restProps);
20480
+ const handleChange = event => {
20481
+ if (onChange) {
20482
+ onChange(event.target.checked);
20483
+ }
20484
+ };
20485
+ return jsxRuntime.jsxs(material.FormControl, {
20486
+ ...htmlProps,
20487
+ ...styleProps,
20488
+ error: !!error,
20489
+ required: required,
20490
+ disabled: disabled,
20491
+ sx: {
20492
+ display: 'block',
20493
+ ...styleProps.sx
20494
+ },
20495
+ children: [jsxRuntime.jsx(material.FormControlLabel, {
20496
+ control: jsxRuntime.jsx(material.Switch, {
20497
+ checked: checked,
20498
+ onChange: handleChange,
20499
+ onFocus: onFocus,
20500
+ size: size,
20501
+ color: color,
20502
+ disabled: disabled
20503
+ }),
20504
+ label: label,
20505
+ disabled: disabled
20506
+ }), (error || helperText) && jsxRuntime.jsx(material.FormHelperText, {
20507
+ children: error || helperText
20508
+ })]
20509
+ });
20510
+ }
20511
+ /**
20512
+ * SwitchInputField component with data binding support
20513
+ * Supports both traditional props and dataSource-driven rendering
20514
+ */
20515
+ function SwitchInputField(props) {
20516
+ const {
20517
+ dataSource,
20518
+ bindingOptions,
20519
+ ...restProps
20520
+ } = props;
20521
+ // If no dataSource, use traditional props
20522
+ if (!dataSource) {
20523
+ return jsxRuntime.jsx(SwitchInputFieldView, {
20524
+ ...restProps
20525
+ });
20526
+ }
20527
+ // Use data binding
20528
+ const bindingResult = useDataBinding(dataSource, restProps, SwitchInputFieldModel$1.getSchema(), {
20529
+ cache: true,
20530
+ cacheTTL: 300000,
20531
+ strict: false,
20532
+ ...bindingOptions
20533
+ });
20534
+ // Check if we're still loading data using the metadata properties
20535
+ const bindingLoading = bindingResult.$loading;
20536
+ // Extract all the actual switch properties (excluding metadata)
20537
+ const {
20538
+ dataSource: _source,
20539
+ $loading,
20540
+ $error,
20541
+ $dataSource,
20542
+ $cached,
20543
+ cached,
20544
+ ...switchInputFieldProps
20545
+ } = bindingResult;
20546
+ const error = bindingResult.$error;
20547
+ // Show loading state while fetching data
20548
+ if (bindingLoading) {
20549
+ return jsxRuntime.jsxs(material.Paper, {
20550
+ variant: "outlined",
20551
+ sx: {
20552
+ p: 2,
20553
+ textAlign: 'center'
20554
+ },
20555
+ children: [jsxRuntime.jsx(material.Typography, {
20556
+ variant: "body2",
20557
+ children: "Loading SwitchInputField..."
20558
+ }), jsxRuntime.jsx(material.Typography, {
20559
+ variant: "caption",
20560
+ color: "text.secondary",
20561
+ children: "Loading switch field configuration from data source..."
20562
+ })]
20563
+ });
20564
+ }
20565
+ if (error) {
20566
+ console.error('Error loading switch input field:', error);
20567
+ {
20568
+ return jsxRuntime.jsx(material.Paper, {
20569
+ variant: "outlined",
20570
+ sx: {
20571
+ p: 2,
20572
+ textAlign: 'center',
20573
+ borderColor: 'error.main'
20574
+ },
20575
+ children: jsxRuntime.jsxs(material.Typography, {
20576
+ variant: "body2",
20577
+ color: "error",
20578
+ children: ["Error loading switch field: ", error.message]
20579
+ })
20580
+ });
20581
+ }
20582
+ }
20583
+ return jsxRuntime.jsx(SwitchInputFieldView, {
20584
+ ...switchInputFieldProps
20585
+ });
20586
+ }
20587
+ // Mark as QwickApp component
20588
+ SwitchInputField[QWICKAPP_COMPONENT] = true;
20589
+
19732
20590
  const TextField = /*#__PURE__*/React.forwardRef((props, ref) => {
19733
20591
  const {
19734
20592
  gridProps,
@@ -20225,7 +21083,7 @@ const FormPage = ({
20225
21083
  title: title,
20226
21084
  description: description,
20227
21085
  coverImage: coverImage,
20228
- form: form,
21086
+ children: form,
20229
21087
  footer: footer,
20230
21088
  status: status,
20231
21089
  message: message,
@@ -25018,6 +25876,8 @@ exports.Button = Button;
25018
25876
  exports.CardListGrid = CardListGrid;
25019
25877
  exports.ChoiceInputField = ChoiceInputField;
25020
25878
  exports.Code = Code;
25879
+ exports.CollapsibleLayout = CollapsibleLayout;
25880
+ exports.CollapsibleLayoutView = CollapsibleLayoutView;
25021
25881
  exports.Content = Content;
25022
25882
  exports.CoverImageHeader = CoverImageHeader;
25023
25883
  exports.DataProvider = DataProvider;
@@ -25053,16 +25913,19 @@ exports.QwickAppsLogo = QwickAppsLogo;
25053
25913
  exports.SafeSpan = SafeSpan;
25054
25914
  exports.Section = Section;
25055
25915
  exports.SelectInputField = SelectInputField;
25916
+ exports.SwitchInputField = SwitchInputField;
25056
25917
  exports.T = T;
25057
25918
  exports.TextField = TextField;
25058
25919
  exports.TextInputField = TextInputField;
25059
25920
  exports.ThemeProvider = ThemeProvider;
25060
25921
  exports.ThemeSwitcher = ThemeSwitcher;
25922
+ exports.animationConfigs = animationConfigs;
25061
25923
  exports.applyCustomPalette = applyCustomPalette;
25062
25924
  exports.clearUserPalettePreference = clearUserPalettePreference;
25063
25925
  exports.clearUserThemePreference = clearUserThemePreference;
25064
25926
  exports.createLogger = createLogger;
25065
25927
  exports.createPaletteFromCurrentTheme = createPaletteFromCurrentTheme;
25928
+ exports.defaultCollapsibleLayoutProps = defaultCollapsibleLayoutProps;
25066
25929
  exports.deleteCustomPalette = deleteCustomPalette;
25067
25930
  exports.exportPalette = exportPalette;
25068
25931
  exports.getCSSVariable = getCSSVariable;
@@ -25077,6 +25940,7 @@ exports.getThemePerformanceStats = getThemePerformanceStats;
25077
25940
  exports.importPalette = importPalette;
25078
25941
  exports.initializePalette = initializePalette;
25079
25942
  exports.initializeTheme = initializeTheme;
25943
+ exports.isCollapsibleLayoutProps = isCollapsibleLayoutProps;
25080
25944
  exports.loadUserPalettePreference = loadUserPalettePreference;
25081
25945
  exports.loadUserThemePreference = loadUserThemePreference;
25082
25946
  exports.logThemePerformanceStats = logThemePerformanceStats;
@@ -25094,10 +25958,12 @@ exports.saveUserThemePreference = saveUserThemePreference;
25094
25958
  exports.setCSSVariable = setCSSVariable;
25095
25959
  exports.setPalette = setPalette;
25096
25960
  exports.setTheme = setTheme;
25961
+ exports.spacingConfigs = spacingConfigs;
25097
25962
  exports.t = t;
25098
25963
  exports.useAccessibility = useAccessibility;
25099
25964
  exports.useBaseProps = useBaseProps;
25100
25965
  exports.useBreadcrumbs = useBreadcrumbs;
25966
+ exports.useCollapsibleState = useCollapsibleState;
25101
25967
  exports.useData = useData;
25102
25968
  exports.useDataBinding = useDataBinding;
25103
25969
  exports.useDataContext = useDataContext;