@qwickapps/react-framework 1.7.0 → 1.8.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.
Files changed (33) hide show
  1. package/README.md +23 -0
  2. package/dist/components/blocks/ImageGallery.d.ts.map +1 -1
  3. package/dist/components/blocks/OptionSelector.d.ts.map +1 -1
  4. package/dist/components/blocks/ProductCard.d.ts +10 -2
  5. package/dist/components/blocks/ProductCard.d.ts.map +1 -1
  6. package/dist/components/forms/FormCheckbox.d.ts.map +1 -1
  7. package/dist/components/forms/FormField.d.ts.map +1 -1
  8. package/dist/components/forms/FormSelect.d.ts.map +1 -1
  9. package/dist/index.esm.js +257 -31
  10. package/dist/index.js +256 -30
  11. package/dist/palettes/manifest.json +22 -22
  12. package/package.json +1 -1
  13. package/src/components/blocks/ImageGallery.tsx +6 -5
  14. package/src/components/blocks/OptionSelector.tsx +18 -3
  15. package/src/components/blocks/ProductCard.tsx +283 -84
  16. package/src/components/forms/FormCheckbox.tsx +15 -0
  17. package/src/components/forms/FormField.tsx +15 -0
  18. package/src/components/forms/FormSelect.tsx +15 -0
  19. package/src/stories/ProductCard.stories.tsx +151 -1
  20. /package/dist/palettes/{palette-autumn.1.7.0.css → palette-autumn.1.8.0.css} +0 -0
  21. /package/dist/palettes/{palette-autumn.1.7.0.min.css → palette-autumn.1.8.0.min.css} +0 -0
  22. /package/dist/palettes/{palette-boutique.1.7.0.css → palette-boutique.1.8.0.css} +0 -0
  23. /package/dist/palettes/{palette-boutique.1.7.0.min.css → palette-boutique.1.8.0.min.css} +0 -0
  24. /package/dist/palettes/{palette-cosmic.1.7.0.css → palette-cosmic.1.8.0.css} +0 -0
  25. /package/dist/palettes/{palette-cosmic.1.7.0.min.css → palette-cosmic.1.8.0.min.css} +0 -0
  26. /package/dist/palettes/{palette-default.1.7.0.css → palette-default.1.8.0.css} +0 -0
  27. /package/dist/palettes/{palette-default.1.7.0.min.css → palette-default.1.8.0.min.css} +0 -0
  28. /package/dist/palettes/{palette-ocean.1.7.0.css → palette-ocean.1.8.0.css} +0 -0
  29. /package/dist/palettes/{palette-ocean.1.7.0.min.css → palette-ocean.1.8.0.min.css} +0 -0
  30. /package/dist/palettes/{palette-spring.1.7.0.css → palette-spring.1.8.0.css} +0 -0
  31. /package/dist/palettes/{palette-spring.1.7.0.min.css → palette-spring.1.8.0.min.css} +0 -0
  32. /package/dist/palettes/{palette-winter.1.7.0.css → palette-winter.1.8.0.css} +0 -0
  33. /package/dist/palettes/{palette-winter.1.7.0.min.css → palette-winter.1.8.0.min.css} +0 -0
package/dist/index.js CHANGED
@@ -21103,6 +21103,7 @@ function ProductCardView({
21103
21103
  showImage = true,
21104
21104
  showTechnologies = true,
21105
21105
  maxFeaturesCompact = 3,
21106
+ onAddToCart,
21106
21107
  ...restProps
21107
21108
  }) {
21108
21109
  const {
@@ -21112,6 +21113,16 @@ function ProductCardView({
21112
21113
  const theme = material.useTheme();
21113
21114
  // Return null if no product data
21114
21115
  if (!product) return null;
21116
+ // Detect product type: e-commerce products have price field
21117
+ const isEcommerce = product.price !== undefined;
21118
+ // E-commerce helpers
21119
+ const formatPrice = price => {
21120
+ return `$${price.toFixed(2)}`;
21121
+ };
21122
+ const calculateDiscount = () => {
21123
+ if (!product.price || !product.salePrice) return 0;
21124
+ return Math.round((product.price - product.salePrice) / product.price * 100);
21125
+ };
21115
21126
  const getStatusIcon = status => {
21116
21127
  switch (status) {
21117
21128
  case 'launched':
@@ -21142,11 +21153,26 @@ function ProductCardView({
21142
21153
  const handleProductClick = () => {
21143
21154
  if (onClick) {
21144
21155
  onClick();
21145
- } else if (product.status === 'launched' && product.url?.startsWith('http')) {
21146
- window.open(product.url, '_blank', 'noopener,noreferrer');
21147
21156
  }
21157
+ // Note: Navigation is handled by parent wrapper (e.g., Next.js Link in BlockRenderer)
21158
+ // For standalone usage, provide onClick prop with navigation logic
21148
21159
  };
21149
21160
  const getDefaultActions = () => {
21161
+ // E-commerce products get "Add to Cart" action
21162
+ if (isEcommerce) {
21163
+ return [{
21164
+ id: 'add-to-cart',
21165
+ label: 'Add to Cart',
21166
+ variant: 'contained',
21167
+ color: 'primary',
21168
+ onClick: () => {
21169
+ if (onAddToCart && product) {
21170
+ onAddToCart(product);
21171
+ }
21172
+ }
21173
+ }];
21174
+ }
21175
+ // Software products get status-based actions
21150
21176
  const actions = [{
21151
21177
  id: 'primary',
21152
21178
  label: product.status === 'launched' ? 'Learn More' : product.status === 'beta' ? 'Try Beta' : product.status === 'coming-soon' ? 'Coming Soon' : product.status,
@@ -21230,7 +21256,7 @@ function ProductCardView({
21230
21256
  })]
21231
21257
  });
21232
21258
  })();
21233
- const technologiesSectionElement = !showTechnologies || variant === 'compact' ? null : jsxRuntime.jsxs(material.Box, {
21259
+ const technologiesSectionElement = !showTechnologies || variant === 'compact' || !product.technologies ? null : jsxRuntime.jsxs(material.Box, {
21234
21260
  sx: {
21235
21261
  mb: 3
21236
21262
  },
@@ -21264,26 +21290,25 @@ function ProductCardView({
21264
21290
  className: styleProps.className || "product-card",
21265
21291
  onClick: htmlProps.onClick || (variant === 'compact' ? handleProductClick : undefined),
21266
21292
  sx: {
21267
- p: 3,
21268
- // padding="large" equivalent
21269
- borderRadius: 3,
21270
- border: '1px solid',
21271
- borderColor: 'divider',
21272
- cursor: variant === 'compact' ? 'pointer' : 'default',
21273
- position: 'relative',
21274
21293
  height: '100%',
21275
21294
  display: 'flex',
21276
21295
  flexDirection: 'column',
21277
21296
  backgroundColor: 'background.paper',
21278
- transition: 'transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out',
21297
+ borderRadius: isEcommerce ? 2 : 3,
21298
+ border: '1px solid',
21299
+ borderColor: 'divider',
21300
+ overflow: 'hidden',
21301
+ position: 'relative',
21302
+ cursor: variant === 'compact' ? 'pointer' : 'default',
21303
+ transition: 'transform 0.2s ease, box-shadow 0.2s ease',
21279
21304
  '&:hover': variant === 'compact' ? {
21280
21305
  transform: 'translateY(-4px)',
21281
- boxShadow: 8
21306
+ boxShadow: 3
21282
21307
  } : {},
21283
21308
  ...(styleProps.sx || {})
21284
21309
  },
21285
21310
  style: styleProps.style,
21286
- children: [jsxRuntime.jsx(material.Chip, {
21311
+ children: [!isEcommerce && jsxRuntime.jsx(material.Chip, {
21287
21312
  icon: getStatusIcon(product.status),
21288
21313
  label: product.status.replace('-', ' '),
21289
21314
  sx: {
@@ -21302,16 +21327,14 @@ function ProductCardView({
21302
21327
  color: 'white'
21303
21328
  }
21304
21329
  }
21305
- }), showImage && product.image && jsxRuntime.jsx(material.Box, {
21330
+ }), showImage && product.image && jsxRuntime.jsxs(material.Box, {
21306
21331
  sx: {
21307
21332
  width: '100%',
21308
- height: variant === 'detailed' ? 240 : 200,
21309
- mb: 2.5,
21310
- borderRadius: 1,
21311
- overflow: 'hidden',
21312
- backgroundColor: 'divider'
21333
+ height: isEcommerce ? 280 : variant === 'detailed' ? 240 : 200,
21334
+ backgroundColor: 'divider',
21335
+ position: 'relative'
21313
21336
  },
21314
- children: jsxRuntime.jsx(material.Box, {
21337
+ children: [jsxRuntime.jsx(material.Box, {
21315
21338
  component: "img",
21316
21339
  src: product.image,
21317
21340
  alt: product.name,
@@ -21328,14 +21351,153 @@ function ProductCardView({
21328
21351
  target.parentElement.innerHTML = `<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: white; font-size: 1.5rem; font-weight: bold;">${product.name}</div>`;
21329
21352
  }
21330
21353
  }
21331
- })
21354
+ }), isEcommerce && jsxRuntime.jsxs(jsxRuntime.Fragment, {
21355
+ children: [jsxRuntime.jsxs(material.Box, {
21356
+ sx: {
21357
+ position: 'absolute',
21358
+ top: 12,
21359
+ left: 12,
21360
+ display: 'flex',
21361
+ flexDirection: 'column',
21362
+ gap: 0.5
21363
+ },
21364
+ children: [product.isNew && jsxRuntime.jsx(material.Chip, {
21365
+ label: "NEW",
21366
+ sx: {
21367
+ backgroundColor: 'primary.main',
21368
+ color: 'white',
21369
+ fontSize: '0.75rem',
21370
+ fontWeight: 600,
21371
+ height: '24px',
21372
+ px: 1
21373
+ }
21374
+ }), product.featured && jsxRuntime.jsx(material.Chip, {
21375
+ label: "POPULAR",
21376
+ sx: {
21377
+ backgroundColor: 'warning.main',
21378
+ color: 'white',
21379
+ fontSize: '0.75rem',
21380
+ fontWeight: 600,
21381
+ height: '24px',
21382
+ px: 1
21383
+ }
21384
+ })]
21385
+ }), jsxRuntime.jsx(material.Box, {
21386
+ sx: {
21387
+ position: 'absolute',
21388
+ top: 12,
21389
+ right: 12,
21390
+ display: 'flex',
21391
+ flexDirection: 'column',
21392
+ gap: 0.5
21393
+ },
21394
+ children: product.salePrice && product.price && jsxRuntime.jsxs(jsxRuntime.Fragment, {
21395
+ children: [jsxRuntime.jsx(material.Chip, {
21396
+ label: "ON SALE",
21397
+ sx: {
21398
+ backgroundColor: 'error.main',
21399
+ color: 'white',
21400
+ fontSize: '0.75rem',
21401
+ fontWeight: 600,
21402
+ height: '24px',
21403
+ px: 1
21404
+ }
21405
+ }), jsxRuntime.jsx(material.Chip, {
21406
+ label: `-${calculateDiscount()}%`,
21407
+ sx: {
21408
+ backgroundColor: 'error.dark',
21409
+ color: 'white',
21410
+ fontSize: '0.75rem',
21411
+ fontWeight: 600,
21412
+ height: '24px',
21413
+ px: 1
21414
+ }
21415
+ })]
21416
+ })
21417
+ })]
21418
+ })]
21332
21419
  }), jsxRuntime.jsxs(material.Box, {
21333
21420
  sx: {
21334
21421
  flex: 1,
21335
21422
  display: 'flex',
21336
- flexDirection: 'column'
21423
+ flexDirection: 'column',
21424
+ p: isEcommerce ? 2 : 3
21337
21425
  },
21338
- children: [jsxRuntime.jsxs(material.Box, {
21426
+ children: [isEcommerce ? (/* E-commerce product info */
21427
+ jsxRuntime.jsxs(material.Box, {
21428
+ children: [product.category && jsxRuntime.jsx(material.Typography, {
21429
+ variant: "caption",
21430
+ sx: {
21431
+ mb: 0.5,
21432
+ color: 'text.secondary',
21433
+ display: 'block'
21434
+ },
21435
+ children: product.category
21436
+ }), jsxRuntime.jsx(material.Typography, {
21437
+ variant: "h6",
21438
+ component: "h3",
21439
+ sx: {
21440
+ mb: 1,
21441
+ fontSize: '1rem',
21442
+ fontWeight: 500,
21443
+ lineHeight: 1.3,
21444
+ overflow: 'hidden',
21445
+ textOverflow: 'ellipsis',
21446
+ display: '-webkit-box',
21447
+ WebkitLineClamp: 2,
21448
+ WebkitBoxOrient: 'vertical'
21449
+ },
21450
+ children: product.name
21451
+ }), product.rating !== undefined && product.rating > 0 && jsxRuntime.jsxs(material.Box, {
21452
+ sx: {
21453
+ display: 'flex',
21454
+ alignItems: 'center',
21455
+ gap: 0.5,
21456
+ mb: 1
21457
+ },
21458
+ children: [jsxRuntime.jsx(material.Rating, {
21459
+ value: product.rating,
21460
+ readOnly: true,
21461
+ size: "small",
21462
+ precision: 0.5,
21463
+ emptyIcon: jsxRuntime.jsx(Star, {
21464
+ style: {
21465
+ opacity: 0.3
21466
+ },
21467
+ fontSize: "inherit"
21468
+ })
21469
+ }), product.reviewCount !== undefined && product.reviewCount > 0 && jsxRuntime.jsxs(material.Typography, {
21470
+ variant: "caption",
21471
+ sx: {
21472
+ color: 'text.secondary'
21473
+ },
21474
+ children: ["(", product.reviewCount, ")"]
21475
+ })]
21476
+ }), jsxRuntime.jsxs(material.Box, {
21477
+ sx: {
21478
+ mt: 'auto',
21479
+ display: 'flex',
21480
+ alignItems: 'center',
21481
+ gap: 1
21482
+ },
21483
+ children: [jsxRuntime.jsx(material.Typography, {
21484
+ variant: "h6",
21485
+ sx: {
21486
+ fontWeight: 600,
21487
+ color: product.salePrice ? 'primary.main' : 'inherit'
21488
+ },
21489
+ children: formatPrice(product.salePrice || product.price)
21490
+ }), product.salePrice && jsxRuntime.jsx(material.Typography, {
21491
+ variant: "body2",
21492
+ sx: {
21493
+ color: 'text.secondary',
21494
+ textDecoration: 'line-through'
21495
+ },
21496
+ children: formatPrice(product.price)
21497
+ })]
21498
+ })]
21499
+ })) : (/* Software product info */
21500
+ jsxRuntime.jsxs(material.Box, {
21339
21501
  sx: {
21340
21502
  mb: 3
21341
21503
  },
@@ -21367,7 +21529,7 @@ function ProductCardView({
21367
21529
  },
21368
21530
  children: variant === 'detailed' ? product.description : product.shortDescription || product.description
21369
21531
  })]
21370
- }), product.features && product.features.length > 0 && featuresListElement, product.technologies && product.technologies.length > 0 && technologiesSectionElement, jsxRuntime.jsx(material.Box, {
21532
+ })), !isEcommerce && product.features && product.features.length > 0 && featuresListElement, !isEcommerce && product.technologies && product.technologies.length > 0 && technologiesSectionElement, jsxRuntime.jsx(material.Box, {
21371
21533
  sx: {
21372
21534
  display: 'flex',
21373
21535
  gap: 1.5,
@@ -21380,7 +21542,12 @@ function ProductCardView({
21380
21542
  variant: action.variant || 'contained',
21381
21543
  // color={action.color || 'primary'}
21382
21544
  disabled: action.disabled,
21383
- onClick: action.onClick,
21545
+ onClick: e => {
21546
+ // Prevent Link navigation when clicking button (e.g., Add to Cart)
21547
+ e.stopPropagation();
21548
+ e.preventDefault();
21549
+ action.onClick();
21550
+ },
21384
21551
  ...(variant === 'compact' && {
21385
21552
  fullWidth: true
21386
21553
  }),
@@ -21745,11 +21912,10 @@ function ImageGalleryView({
21745
21912
  if (variant === 'grid') {
21746
21913
  return jsxRuntime.jsxs(material.Box, {
21747
21914
  ...restProps,
21748
- children: [jsxRuntime.jsx(material.Grid, {
21749
- container: true,
21750
- spacing: 2,
21751
- children: displayImages.map((image, index) => jsxRuntime.jsx(material.Grid, {
21752
- item: true,
21915
+ children: [jsxRuntime.jsx(GridLayout, {
21916
+ columns: 4,
21917
+ spacing: "medium",
21918
+ children: displayImages.map((image, index) => jsxRuntime.jsx(GridCell, {
21753
21919
  xs: 6,
21754
21920
  sm: 4,
21755
21921
  md: 3,
@@ -21809,6 +21975,21 @@ function OptionSelectorView({
21809
21975
  label = 'Select Option',
21810
21976
  dataSource,
21811
21977
  bindingOptions,
21978
+ // Exclude ViewProps that conflict with MUI FormControl types
21979
+ margin: _margin,
21980
+ marginTop: _marginTop,
21981
+ marginRight: _marginRight,
21982
+ marginBottom: _marginBottom,
21983
+ marginLeft: _marginLeft,
21984
+ marginX: _marginX,
21985
+ marginY: _marginY,
21986
+ padding: _padding,
21987
+ paddingTop: _paddingTop,
21988
+ paddingRight: _paddingRight,
21989
+ paddingBottom: _paddingBottom,
21990
+ paddingLeft: _paddingLeft,
21991
+ paddingX: _paddingX,
21992
+ paddingY: _paddingY,
21812
21993
  ...restProps
21813
21994
  }) {
21814
21995
  const handleOptionClick = React.useCallback((optionId, available) => {
@@ -23037,6 +23218,21 @@ function FormFieldView({
23037
23218
  startAdornment,
23038
23219
  endAdornment,
23039
23220
  inputProps,
23221
+ // Exclude ViewProps that conflict with MUI FormControl types
23222
+ margin: _margin,
23223
+ marginTop: _marginTop,
23224
+ marginRight: _marginRight,
23225
+ marginBottom: _marginBottom,
23226
+ marginLeft: _marginLeft,
23227
+ marginX: _marginX,
23228
+ marginY: _marginY,
23229
+ padding: _padding,
23230
+ paddingTop: _paddingTop,
23231
+ paddingRight: _paddingRight,
23232
+ paddingBottom: _paddingBottom,
23233
+ paddingLeft: _paddingLeft,
23234
+ paddingX: _paddingX,
23235
+ paddingY: _paddingY,
23040
23236
  ...restProps
23041
23237
  }) {
23042
23238
  const fieldId = React.useId();
@@ -23133,6 +23329,21 @@ function FormSelectView({
23133
23329
  fullWidth = true,
23134
23330
  size = 'small',
23135
23331
  placeholder,
23332
+ // Exclude ViewProps that conflict with MUI FormControl types
23333
+ margin: _margin,
23334
+ marginTop: _marginTop,
23335
+ marginRight: _marginRight,
23336
+ marginBottom: _marginBottom,
23337
+ marginLeft: _marginLeft,
23338
+ marginX: _marginX,
23339
+ marginY: _marginY,
23340
+ padding: _padding,
23341
+ paddingTop: _paddingTop,
23342
+ paddingRight: _paddingRight,
23343
+ paddingBottom: _paddingBottom,
23344
+ paddingLeft: _paddingLeft,
23345
+ paddingX: _paddingX,
23346
+ paddingY: _paddingY,
23136
23347
  ...restProps
23137
23348
  }) {
23138
23349
  const handleChange = e => {
@@ -23207,6 +23418,21 @@ function FormCheckboxView({
23207
23418
  helperText,
23208
23419
  required = false,
23209
23420
  disabled = false,
23421
+ // Exclude ViewProps that conflict with MUI FormControl types
23422
+ margin: _margin,
23423
+ marginTop: _marginTop,
23424
+ marginRight: _marginRight,
23425
+ marginBottom: _marginBottom,
23426
+ marginLeft: _marginLeft,
23427
+ marginX: _marginX,
23428
+ marginY: _marginY,
23429
+ padding: _padding,
23430
+ paddingTop: _paddingTop,
23431
+ paddingRight: _paddingRight,
23432
+ paddingBottom: _paddingBottom,
23433
+ paddingLeft: _paddingLeft,
23434
+ paddingX: _paddingX,
23435
+ paddingY: _paddingY,
23210
23436
  ...restProps
23211
23437
  }) {
23212
23438
  const handleChange = e => {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./manifest.schema.json",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "palettes": [
5
5
  {
6
6
  "id": "default",
@@ -8,11 +8,11 @@
8
8
  "description": "Classic blue and neutral color scheme - the original QwickApps palette",
9
9
  "author": "QwickApps",
10
10
  "license": "PolyForm-Shield-1.0.0",
11
- "version": "1.7.0",
12
- "file": "palette-default.1.7.0.css",
11
+ "version": "1.8.0",
12
+ "file": "palette-default.1.8.0.css",
13
13
  "primaryColor": "#007bff",
14
14
  "inlined": true,
15
- "fileMinified": "palette-default.1.7.0.min.css",
15
+ "fileMinified": "palette-default.1.8.0.min.css",
16
16
  "fileLatest": "palette-default.latest.css",
17
17
  "fileLatestMinified": "palette-default.latest.min.css"
18
18
  },
@@ -22,11 +22,11 @@
22
22
  "description": "Warm oranges, golden yellows, and earthy browns - inspired by fall foliage",
23
23
  "author": "QwickApps",
24
24
  "license": "PolyForm-Shield-1.0.0",
25
- "version": "1.7.0",
26
- "file": "palette-autumn.1.7.0.css",
25
+ "version": "1.8.0",
26
+ "file": "palette-autumn.1.8.0.css",
27
27
  "primaryColor": "#ea580c",
28
28
  "inlined": false,
29
- "fileMinified": "palette-autumn.1.7.0.min.css",
29
+ "fileMinified": "palette-autumn.1.8.0.min.css",
30
30
  "fileLatest": "palette-autumn.latest.css",
31
31
  "fileLatestMinified": "palette-autumn.latest.min.css"
32
32
  },
@@ -36,11 +36,11 @@
36
36
  "description": "Sophisticated teal, bronze, and navy - perfect for premium retail and fashion brands",
37
37
  "author": "QwickApps",
38
38
  "license": "PolyForm-Shield-1.0.0",
39
- "version": "1.7.0",
40
- "file": "palette-boutique.1.7.0.css",
39
+ "version": "1.8.0",
40
+ "file": "palette-boutique.1.8.0.css",
41
41
  "primaryColor": "#3ca6b6",
42
42
  "inlined": false,
43
- "fileMinified": "palette-boutique.1.7.0.min.css",
43
+ "fileMinified": "palette-boutique.1.8.0.min.css",
44
44
  "fileLatest": "palette-boutique.latest.css",
45
45
  "fileLatestMinified": "palette-boutique.latest.min.css"
46
46
  },
@@ -50,11 +50,11 @@
50
50
  "description": "Modern purple gradient for creative and tech brands - inspired by cosmic nebulae",
51
51
  "author": "QwickApps",
52
52
  "license": "PolyForm-Shield-1.0.0",
53
- "version": "1.7.0",
54
- "file": "palette-cosmic.1.7.0.css",
53
+ "version": "1.8.0",
54
+ "file": "palette-cosmic.1.8.0.css",
55
55
  "primaryColor": "#8b5cf6",
56
56
  "inlined": false,
57
- "fileMinified": "palette-cosmic.1.7.0.min.css",
57
+ "fileMinified": "palette-cosmic.1.8.0.min.css",
58
58
  "fileLatest": "palette-cosmic.latest.css",
59
59
  "fileLatestMinified": "palette-cosmic.latest.min.css"
60
60
  },
@@ -64,11 +64,11 @@
64
64
  "description": "Deep blues, aqua teals, and seafoam greens - inspired by ocean depths",
65
65
  "author": "QwickApps",
66
66
  "license": "PolyForm-Shield-1.0.0",
67
- "version": "1.7.0",
68
- "file": "palette-ocean.1.7.0.css",
67
+ "version": "1.8.0",
68
+ "file": "palette-ocean.1.8.0.css",
69
69
  "primaryColor": "#0891b2",
70
70
  "inlined": false,
71
- "fileMinified": "palette-ocean.1.7.0.min.css",
71
+ "fileMinified": "palette-ocean.1.8.0.min.css",
72
72
  "fileLatest": "palette-ocean.latest.css",
73
73
  "fileLatestMinified": "palette-ocean.latest.min.css"
74
74
  },
@@ -78,11 +78,11 @@
78
78
  "description": "Fresh greens, soft pinks, and bright yellows - inspired by spring blooms",
79
79
  "author": "QwickApps",
80
80
  "license": "PolyForm-Shield-1.0.0",
81
- "version": "1.7.0",
82
- "file": "palette-spring.1.7.0.css",
81
+ "version": "1.8.0",
82
+ "file": "palette-spring.1.8.0.css",
83
83
  "primaryColor": "#16a34a",
84
84
  "inlined": false,
85
- "fileMinified": "palette-spring.1.7.0.min.css",
85
+ "fileMinified": "palette-spring.1.8.0.min.css",
86
86
  "fileLatest": "palette-spring.latest.css",
87
87
  "fileLatestMinified": "palette-spring.latest.min.css"
88
88
  },
@@ -92,11 +92,11 @@
92
92
  "description": "Cool blues, icy whites, and frosty grays - inspired by winter landscapes",
93
93
  "author": "QwickApps",
94
94
  "license": "PolyForm-Shield-1.0.0",
95
- "version": "1.7.0",
96
- "file": "palette-winter.1.7.0.css",
95
+ "version": "1.8.0",
96
+ "file": "palette-winter.1.8.0.css",
97
97
  "primaryColor": "#0077be",
98
98
  "inlined": false,
99
- "fileMinified": "palette-winter.1.7.0.min.css",
99
+ "fileMinified": "palette-winter.1.8.0.min.css",
100
100
  "fileLatest": "palette-winter.latest.css",
101
101
  "fileLatestMinified": "palette-winter.latest.min.css"
102
102
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qwickapps/react-framework",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Complete React framework with responsive navigation, flexible layouts, theming system, and reusable components for building modern applications.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -29,7 +29,8 @@
29
29
  */
30
30
 
31
31
  import React, { useState, useCallback } from 'react';
32
- import { Box, IconButton, Modal, Grid, Skeleton } from '@mui/material';
32
+ import { Box, IconButton, Modal, Skeleton } from '@mui/material';
33
+ import { GridLayout, GridCell } from '../layout';
33
34
  import CloseIcon from '@mui/icons-material/Close';
34
35
  import ZoomInIcon from '@mui/icons-material/ZoomIn';
35
36
  import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
@@ -409,9 +410,9 @@ function ImageGalleryView({
409
410
  if (variant === 'grid') {
410
411
  return (
411
412
  <Box {...restProps}>
412
- <Grid container spacing={2}>
413
+ <GridLayout columns={4} spacing="medium">
413
414
  {displayImages.map((image, index) => (
414
- <Grid item xs={6} sm={4} md={3} key={index}>
415
+ <GridCell xs={6} sm={4} md={3} key={index}>
415
416
  <Box
416
417
  onClick={() => {
417
418
  setSelectedIndex(index);
@@ -441,9 +442,9 @@ function ImageGalleryView({
441
442
  }}
442
443
  />
443
444
  </Box>
444
- </Grid>
445
+ </GridCell>
445
446
  ))}
446
- </Grid>
447
+ </GridLayout>
447
448
  {renderZoomModal()}
448
449
  </Box>
449
450
  );
@@ -123,6 +123,21 @@ function OptionSelectorView({
123
123
  label = 'Select Option',
124
124
  dataSource,
125
125
  bindingOptions,
126
+ // Exclude ViewProps that conflict with MUI FormControl types
127
+ margin: _margin,
128
+ marginTop: _marginTop,
129
+ marginRight: _marginRight,
130
+ marginBottom: _marginBottom,
131
+ marginLeft: _marginLeft,
132
+ marginX: _marginX,
133
+ marginY: _marginY,
134
+ padding: _padding,
135
+ paddingTop: _paddingTop,
136
+ paddingRight: _paddingRight,
137
+ paddingBottom: _paddingBottom,
138
+ paddingLeft: _paddingLeft,
139
+ paddingX: _paddingX,
140
+ paddingY: _paddingY,
126
141
  ...restProps
127
142
  }: OptionSelectorProps) {
128
143
  const handleOptionClick = useCallback((optionId: string, available: boolean) => {
@@ -226,14 +241,14 @@ function OptionSelectorView({
226
241
  }
227
242
 
228
243
  // Buttons/Grid variant with visual modes
229
- const getLayoutStyles = () => {
244
+ const getLayoutStyles = (): React.CSSProperties => {
230
245
  if (variant === 'grid') {
231
246
  const minWidth = displayMode === 'text' ? 60 : sizeInPx + 16;
232
247
  return {
233
248
  display: 'grid',
234
249
  gridTemplateColumns: `repeat(auto-fill, minmax(${minWidth}px, 1fr))`,
235
250
  gap: displayMode === 'text' ? 1 : 2,
236
- };
251
+ } as React.CSSProperties;
237
252
  }
238
253
 
239
254
  return {
@@ -241,7 +256,7 @@ function OptionSelectorView({
241
256
  flexDirection: layout === 'vertical' ? 'column' : 'row',
242
257
  flexWrap: layout === 'wrap' ? 'wrap' : 'nowrap',
243
258
  gap: 1,
244
- };
259
+ } as React.CSSProperties;
245
260
  };
246
261
 
247
262
  return (