@qwickapps/react-framework 1.5.13 → 1.7.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 (91) hide show
  1. package/dist/components/Scaffold.d.ts +2 -2
  2. package/dist/components/Scaffold.d.ts.map +1 -1
  3. package/dist/components/forms/Captcha.d.ts +33 -28
  4. package/dist/components/forms/Captcha.d.ts.map +1 -1
  5. package/dist/components/forms/FormCheckbox.d.ts +15 -12
  6. package/dist/components/forms/FormCheckbox.d.ts.map +1 -1
  7. package/dist/components/forms/FormField.d.ts +20 -23
  8. package/dist/components/forms/FormField.d.ts.map +1 -1
  9. package/dist/components/forms/FormSelect.d.ts +16 -15
  10. package/dist/components/forms/FormSelect.d.ts.map +1 -1
  11. package/dist/contexts/QwickAppContext.d.ts +1 -1
  12. package/dist/contexts/QwickAppContext.d.ts.map +1 -1
  13. package/dist/hooks/useBaseProps.d.ts +27 -1172
  14. package/dist/hooks/useBaseProps.d.ts.map +1 -1
  15. package/dist/index.css +1 -1
  16. package/dist/index.esm.css +1 -1
  17. package/dist/index.esm.js +393 -160
  18. package/dist/index.js +393 -159
  19. package/dist/palettes/PaletteBoutique.d.ts +10 -0
  20. package/dist/palettes/PaletteBoutique.d.ts.map +1 -0
  21. package/dist/palettes/index.d.ts +1 -0
  22. package/dist/palettes/index.d.ts.map +1 -1
  23. package/dist/palettes/manifest.json +33 -19
  24. package/dist/palettes/{palette-autumn.1.5.13.css → palette-autumn.1.7.0.css} +3 -1
  25. package/dist/palettes/palette-autumn.1.7.0.min.css +1 -0
  26. package/dist/palettes/palette-autumn.latest.css +3 -1
  27. package/dist/palettes/palette-autumn.latest.min.css +1 -1
  28. package/dist/palettes/palette-boutique.1.7.0.css +176 -0
  29. package/dist/palettes/palette-boutique.1.7.0.min.css +1 -0
  30. package/dist/palettes/palette-boutique.latest.css +176 -0
  31. package/dist/palettes/palette-boutique.latest.min.css +1 -0
  32. package/dist/palettes/{palette-cosmic.1.5.13.css → palette-cosmic.1.7.0.css} +3 -1
  33. package/dist/palettes/palette-cosmic.1.7.0.min.css +1 -0
  34. package/dist/palettes/palette-cosmic.latest.css +3 -1
  35. package/dist/palettes/palette-cosmic.latest.min.css +1 -1
  36. package/dist/palettes/{palette-ocean.1.5.13.css → palette-ocean.1.7.0.css} +3 -1
  37. package/dist/palettes/palette-ocean.1.7.0.min.css +1 -0
  38. package/dist/palettes/palette-ocean.latest.css +3 -1
  39. package/dist/palettes/palette-ocean.latest.min.css +1 -1
  40. package/dist/palettes/{palette-spring.1.5.13.css → palette-spring.1.7.0.css} +3 -1
  41. package/dist/palettes/palette-spring.1.7.0.min.css +1 -0
  42. package/dist/palettes/palette-spring.latest.css +3 -1
  43. package/dist/palettes/palette-spring.latest.min.css +1 -1
  44. package/dist/palettes/{palette-winter.1.5.13.css → palette-winter.1.7.0.css} +3 -1
  45. package/dist/palettes/palette-winter.1.7.0.min.css +1 -0
  46. package/dist/palettes/palette-winter.latest.css +3 -1
  47. package/dist/palettes/palette-winter.latest.min.css +1 -1
  48. package/dist/schemas/CaptchaSchema.d.ts +16 -0
  49. package/dist/schemas/CaptchaSchema.d.ts.map +1 -0
  50. package/dist/schemas/FormCheckboxSchema.d.ts +16 -0
  51. package/dist/schemas/FormCheckboxSchema.d.ts.map +1 -0
  52. package/dist/schemas/FormFieldSchema.d.ts +23 -0
  53. package/dist/schemas/FormFieldSchema.d.ts.map +1 -0
  54. package/dist/schemas/FormSelectSchema.d.ts +20 -0
  55. package/dist/schemas/FormSelectSchema.d.ts.map +1 -0
  56. package/dist/schemas/index.d.ts +4 -0
  57. package/dist/schemas/index.d.ts.map +1 -1
  58. package/dist/schemas/transformers/ComponentTransformer.d.ts +1 -0
  59. package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -1
  60. package/package.json +2 -1
  61. package/src/components/QwickApp.css +22 -0
  62. package/src/components/Scaffold.css +5 -0
  63. package/src/components/Scaffold.tsx +5 -3
  64. package/src/components/forms/Captcha.tsx +57 -63
  65. package/src/components/forms/FormCheckbox.tsx +35 -43
  66. package/src/components/forms/FormField.tsx +50 -66
  67. package/src/components/forms/FormSelect.tsx +41 -49
  68. package/src/contexts/QwickAppContext.tsx +1 -1
  69. package/src/hooks/useBaseProps.ts +34 -1
  70. package/src/palettes/PaletteAutumn.css +3 -1
  71. package/src/palettes/PaletteBoutique.css +176 -0
  72. package/src/palettes/PaletteBoutique.ts +16 -0
  73. package/src/palettes/PaletteCosmic.css +3 -1
  74. package/src/palettes/PaletteOcean.css +3 -1
  75. package/src/palettes/PaletteSpring.css +3 -1
  76. package/src/palettes/PaletteWinter.css +3 -1
  77. package/src/palettes/index.ts +3 -0
  78. package/src/palettes/manifest.json +12 -1
  79. package/src/schemas/CaptchaSchema.ts +65 -0
  80. package/src/schemas/FormCheckboxSchema.ts +65 -0
  81. package/src/schemas/FormFieldSchema.ts +140 -0
  82. package/src/schemas/FormSelectSchema.ts +108 -0
  83. package/src/schemas/index.ts +4 -0
  84. package/src/schemas/transformers/ComponentTransformer.ts +32 -2
  85. package/dist/palettes/palette-autumn.1.5.13.min.css +0 -1
  86. package/dist/palettes/palette-cosmic.1.5.13.min.css +0 -1
  87. package/dist/palettes/palette-ocean.1.5.13.min.css +0 -1
  88. package/dist/palettes/palette-spring.1.5.13.min.css +0 -1
  89. package/dist/palettes/palette-winter.1.5.13.min.css +0 -1
  90. /package/dist/palettes/{palette-default.1.5.13.css → palette-default.1.7.0.css} +0 -0
  91. /package/dist/palettes/{palette-default.1.5.13.min.css → palette-default.1.7.0.min.css} +0 -0
package/dist/index.js CHANGED
@@ -1274,6 +1274,18 @@ const PaletteAutumn = {
1274
1274
  primaryColor: '#ea580c'
1275
1275
  };
1276
1276
 
1277
+ /**
1278
+ * Boutique Palette Configuration
1279
+ *
1280
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
1281
+ */
1282
+ const PaletteBoutique = {
1283
+ id: 'boutique',
1284
+ name: 'Boutique',
1285
+ description: 'Sophisticated teal, bronze, and navy - perfect for premium retail and fashion brands',
1286
+ primaryColor: '#3ca6b6'
1287
+ };
1288
+
1277
1289
  /**
1278
1290
  * Ocean Palette Configuration
1279
1291
  *
@@ -1327,7 +1339,7 @@ const PaletteCosmic = {
1327
1339
  *
1328
1340
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
1329
1341
  */
1330
- const AllPalettes = [PaletteDefault, PaletteOcean, PaletteCosmic, PaletteWinter, PaletteAutumn, PaletteSpring];
1342
+ const AllPalettes = [PaletteDefault, PaletteBoutique, PaletteOcean, PaletteCosmic, PaletteWinter, PaletteAutumn, PaletteSpring];
1331
1343
 
1332
1344
  /**
1333
1345
  * Persistence utilities for theme and palette preferences
@@ -18495,6 +18507,20 @@ class ReactNodeTransformer {
18495
18507
  *
18496
18508
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
18497
18509
  */
18510
+ // Import linkedom for server-side HTML parsing
18511
+ let parseHTML = null;
18512
+ if (typeof window === 'undefined') {
18513
+ // Server-side: use linkedom
18514
+ try {
18515
+ const {
18516
+ parseHTML: parse
18517
+ } = require('linkedom');
18518
+ parseHTML = html => parse(html).document;
18519
+ } catch (e) {
18520
+ // linkedom not available, will fall back to client-only rendering
18521
+ console.warn('linkedom not available for SSR HTML parsing');
18522
+ }
18523
+ }
18498
18524
  /**
18499
18525
  * Registry for component classes that support serialization
18500
18526
  */
@@ -18803,13 +18829,27 @@ let ComponentTransformer$1 = class ComponentTransformer {
18803
18829
  }
18804
18830
  /**
18805
18831
  * Transform HTML string to React nodes using registered patterns
18832
+ * Supports both server-side (linkedom) and client-side (DOMParser) rendering
18806
18833
  * @param html - HTML string to transform
18807
18834
  * @returns Array of React nodes
18808
18835
  */
18809
18836
  static transformHTML(html) {
18810
18837
  if (!html.trim()) return [];
18811
- const parser = new DOMParser();
18812
- const doc = parser.parseFromString(html, 'text/html');
18838
+ let doc;
18839
+ // Server-side: use linkedom if available
18840
+ if (typeof window === 'undefined') {
18841
+ if (parseHTML) {
18842
+ doc = parseHTML(html);
18843
+ } else {
18844
+ // linkedom not available, return empty for client-side rendering
18845
+ console.warn('SSR HTML parsing unavailable - content will render client-side only');
18846
+ return [];
18847
+ }
18848
+ } else {
18849
+ // Client-side: use DOMParser
18850
+ const parser = new DOMParser();
18851
+ doc = parser.parseFromString(html, 'text/html');
18852
+ }
18813
18853
  return Array.from(doc.body.children).map((element, index) => ComponentTransformer.transformElement(element, `element-${index}`));
18814
18854
  }
18815
18855
  /**
@@ -22976,36 +23016,31 @@ function DialogContentText({
22976
23016
  });
22977
23017
  }
22978
23018
 
22979
- const FormField = /*#__PURE__*/React.forwardRef((props, ref) => {
22980
- const {
22981
- gridProps,
22982
- styleProps,
22983
- htmlProps,
22984
- restProps
22985
- } = useBaseProps(props);
22986
- const {
22987
- label,
22988
- value,
22989
- onChange,
22990
- onChangeRaw,
22991
- type = 'text',
22992
- helperText,
22993
- required = false,
22994
- readOnly = false,
22995
- disabled = false,
22996
- disabledColor,
22997
- fullWidth = true,
22998
- multiline = false,
22999
- rows,
23000
- placeholder,
23001
- startAdornment,
23002
- endAdornment,
23003
- inputProps
23004
- } = restProps;
23005
- // Generate a unique ID for the input field
23019
+ /**
23020
+ * FormFieldView - Pure view component that renders the input field
23021
+ */
23022
+ function FormFieldView({
23023
+ label,
23024
+ value,
23025
+ onChange,
23026
+ onChangeRaw,
23027
+ type = 'text',
23028
+ helperText,
23029
+ required = false,
23030
+ readOnly = false,
23031
+ disabled = false,
23032
+ disabledColor,
23033
+ fullWidth = true,
23034
+ multiline = false,
23035
+ rows,
23036
+ placeholder,
23037
+ startAdornment,
23038
+ endAdornment,
23039
+ inputProps,
23040
+ ...restProps
23041
+ }) {
23006
23042
  const fieldId = React.useId();
23007
23043
  const handleChange = e => {
23008
- // If onChangeRaw is provided, use it instead
23009
23044
  if (onChangeRaw) {
23010
23045
  onChangeRaw(e);
23011
23046
  return;
@@ -23029,8 +23064,7 @@ const FormField = /*#__PURE__*/React.forwardRef((props, ref) => {
23029
23064
  '& input.Mui-disabled': disabledColor ? {
23030
23065
  color: disabledColor,
23031
23066
  WebkitTextFillColor: disabledColor
23032
- } : undefined,
23033
- ...styleProps.sx
23067
+ } : undefined
23034
23068
  };
23035
23069
  const labelStyles = {
23036
23070
  left: -12,
@@ -23041,18 +23075,8 @@ const FormField = /*#__PURE__*/React.forwardRef((props, ref) => {
23041
23075
  color: 'var(--theme-secondary)'
23042
23076
  };
23043
23077
  return jsxRuntime.jsxs(material.FormControl, {
23044
- ref: ref,
23045
23078
  fullWidth: fullWidth,
23046
- ...htmlProps,
23047
- ...styleProps,
23048
- ...(gridProps && {
23049
- 'data-grid-span': gridProps.span,
23050
- 'data-grid-xs': gridProps.xs,
23051
- 'data-grid-sm': gridProps.sm,
23052
- 'data-grid-md': gridProps.md,
23053
- 'data-grid-lg': gridProps.lg,
23054
- 'data-grid-xl': gridProps.xl
23055
- }),
23079
+ ...restProps,
23056
23080
  children: [jsxRuntime.jsx(material.InputLabel, {
23057
23081
  htmlFor: fieldId,
23058
23082
  sx: labelStyles,
@@ -23084,32 +23108,33 @@ const FormField = /*#__PURE__*/React.forwardRef((props, ref) => {
23084
23108
  children: helperText
23085
23109
  })]
23086
23110
  });
23087
- });
23088
- FormField.displayName = 'FormField';
23089
- // Mark as QwickApp component
23090
- Object.assign(FormField, {
23091
- [QWICKAPP_COMPONENT]: true
23111
+ }
23112
+ /**
23113
+ * Create FormField component using the factory pattern
23114
+ */
23115
+ const FormField = createSerializableView({
23116
+ tagName: 'FormField',
23117
+ version: '1.0.0',
23118
+ role: 'input',
23119
+ View: FormFieldView
23092
23120
  });
23093
23121
 
23094
- const FormSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
23095
- const {
23096
- gridProps,
23097
- styleProps,
23098
- htmlProps,
23099
- restProps
23100
- } = useBaseProps(props);
23101
- const {
23102
- label,
23103
- value,
23104
- onChange,
23105
- options,
23106
- helperText,
23107
- required = false,
23108
- disabled = false,
23109
- fullWidth = true,
23110
- size = 'small',
23111
- placeholder
23112
- } = restProps;
23122
+ /**
23123
+ * FormSelectView - Pure view component that renders the select field
23124
+ */
23125
+ function FormSelectView({
23126
+ label,
23127
+ value,
23128
+ onChange,
23129
+ options,
23130
+ helperText,
23131
+ required = false,
23132
+ disabled = false,
23133
+ fullWidth = true,
23134
+ size = 'small',
23135
+ placeholder,
23136
+ ...restProps
23137
+ }) {
23113
23138
  const handleChange = e => {
23114
23139
  onChange(e.target.value);
23115
23140
  };
@@ -23123,8 +23148,7 @@ const FormSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
23123
23148
  backgroundColor: 'var(--theme-surface-variant)',
23124
23149
  borderColor: 'var(--theme-surface)',
23125
23150
  color: 'var(--theme-text-primary)',
23126
- borderRadius: 1,
23127
- ...styleProps.sx
23151
+ borderRadius: 1
23128
23152
  };
23129
23153
  const labelStyles = {
23130
23154
  left: -12,
@@ -23135,19 +23159,9 @@ const FormSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
23135
23159
  color: 'var(--theme-secondary)'
23136
23160
  };
23137
23161
  return jsxRuntime.jsxs(material.FormControl, {
23138
- ref: ref,
23139
23162
  fullWidth: fullWidth,
23140
23163
  size: size,
23141
- ...htmlProps,
23142
- ...styleProps,
23143
- ...(gridProps && {
23144
- 'data-grid-span': gridProps.span,
23145
- 'data-grid-xs': gridProps.xs,
23146
- 'data-grid-sm': gridProps.sm,
23147
- 'data-grid-md': gridProps.md,
23148
- 'data-grid-lg': gridProps.lg,
23149
- 'data-grid-xl': gridProps.xl
23150
- }),
23164
+ ...restProps,
23151
23165
  children: [label && jsxRuntime.jsx(material.InputLabel, {
23152
23166
  sx: labelStyles,
23153
23167
  shrink: true,
@@ -23172,28 +23186,29 @@ const FormSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
23172
23186
  children: helperText
23173
23187
  })]
23174
23188
  });
23175
- });
23176
- FormSelect.displayName = 'FormSelect';
23177
- // Mark as QwickApp component
23178
- Object.assign(FormSelect, {
23179
- [QWICKAPP_COMPONENT]: true
23189
+ }
23190
+ /**
23191
+ * Create FormSelect component using the factory pattern
23192
+ */
23193
+ const FormSelect = createSerializableView({
23194
+ tagName: 'FormSelect',
23195
+ version: '1.0.0',
23196
+ role: 'input',
23197
+ View: FormSelectView
23180
23198
  });
23181
23199
 
23182
- const FormCheckbox = /*#__PURE__*/React.forwardRef((props, ref) => {
23183
- const {
23184
- gridProps,
23185
- styleProps,
23186
- htmlProps,
23187
- restProps
23188
- } = useBaseProps(props);
23189
- const {
23190
- label,
23191
- checked,
23192
- onChange,
23193
- helperText,
23194
- required = false,
23195
- disabled = false
23196
- } = restProps;
23200
+ /**
23201
+ * FormCheckboxView - Pure view component that renders the checkbox
23202
+ */
23203
+ function FormCheckboxView({
23204
+ label,
23205
+ checked,
23206
+ onChange,
23207
+ helperText,
23208
+ required = false,
23209
+ disabled = false,
23210
+ ...restProps
23211
+ }) {
23197
23212
  const handleChange = e => {
23198
23213
  onChange(e.target.checked);
23199
23214
  };
@@ -23213,25 +23228,14 @@ const FormCheckbox = /*#__PURE__*/React.forwardRef((props, ref) => {
23213
23228
  },
23214
23229
  '& .MuiFormControlLabel-label.Mui-disabled': {
23215
23230
  color: 'var(--theme-text-disabled)'
23216
- },
23217
- ...styleProps.sx
23231
+ }
23218
23232
  };
23219
23233
  const helperTextStyles = {
23220
23234
  color: 'var(--theme-secondary)',
23221
- marginLeft: '32px' // Align with checkbox + label
23235
+ marginLeft: '32px'
23222
23236
  };
23223
23237
  return jsxRuntime.jsxs(material.FormControl, {
23224
- ref: ref,
23225
- ...htmlProps,
23226
- ...styleProps,
23227
- ...(gridProps && {
23228
- 'data-grid-span': gridProps.span,
23229
- 'data-grid-xs': gridProps.xs,
23230
- 'data-grid-sm': gridProps.sm,
23231
- 'data-grid-md': gridProps.md,
23232
- 'data-grid-lg': gridProps.lg,
23233
- 'data-grid-xl': gridProps.xl
23234
- }),
23238
+ ...restProps,
23235
23239
  children: [jsxRuntime.jsx(material.FormControlLabel, {
23236
23240
  control: jsxRuntime.jsx(material.Checkbox, {
23237
23241
  checked: checked,
@@ -23247,30 +23251,31 @@ const FormCheckbox = /*#__PURE__*/React.forwardRef((props, ref) => {
23247
23251
  children: helperText
23248
23252
  })]
23249
23253
  });
23250
- });
23251
- FormCheckbox.displayName = 'FormCheckbox';
23252
- // Mark as QwickApp component
23253
- Object.assign(FormCheckbox, {
23254
- [QWICKAPP_COMPONENT]: true
23254
+ }
23255
+ /**
23256
+ * Create FormCheckbox component using the factory pattern
23257
+ */
23258
+ const FormCheckbox = createSerializableView({
23259
+ tagName: 'FormCheckbox',
23260
+ version: '1.0.0',
23261
+ role: 'input',
23262
+ View: FormCheckboxView
23255
23263
  });
23256
23264
 
23257
- const Captcha = /*#__PURE__*/React.forwardRef((props, ref) => {
23258
- const {
23259
- gridProps,
23260
- styleProps,
23261
- htmlProps,
23262
- restProps
23263
- } = useBaseProps(props);
23264
- const {
23265
- provider,
23266
- siteKey,
23267
- onVerify,
23268
- onExpire,
23269
- onError,
23270
- theme = 'light',
23271
- size = 'normal',
23272
- action = 'submit'
23273
- } = restProps;
23265
+ /**
23266
+ * CaptchaView - Pure view component that renders the CAPTCHA widget
23267
+ */
23268
+ function CaptchaView({
23269
+ provider,
23270
+ siteKey,
23271
+ onVerify,
23272
+ onExpire,
23273
+ onError,
23274
+ theme = 'light',
23275
+ size = 'normal',
23276
+ action = 'submit',
23277
+ ...restProps
23278
+ }) {
23274
23279
  const containerRef = React.useRef(null);
23275
23280
  const widgetIdRef = React.useRef(null);
23276
23281
  const [isLoaded, setIsLoaded] = React.useState(false);
@@ -23343,7 +23348,7 @@ const Captcha = /*#__PURE__*/React.forwardRef((props, ref) => {
23343
23348
  try {
23344
23349
  switch (provider) {
23345
23350
  case 'recaptcha-v2':
23346
- if (window.grecaptcha && window.grecaptcha.render) {
23351
+ if (window.grecaptcha?.render) {
23347
23352
  widgetIdRef.current = window.grecaptcha.render(containerRef.current, {
23348
23353
  sitekey: siteKey,
23349
23354
  callback: onVerify,
@@ -23360,7 +23365,7 @@ const Captcha = /*#__PURE__*/React.forwardRef((props, ref) => {
23360
23365
  break;
23361
23366
  case 'recaptcha-v3':
23362
23367
  // reCAPTCHA v3 is invisible and executes programmatically
23363
- if (window.grecaptcha && window.grecaptcha.execute) {
23368
+ if (window.grecaptcha?.execute) {
23364
23369
  window.grecaptcha.execute(siteKey, {
23365
23370
  action
23366
23371
  }).then(token => {
@@ -23372,7 +23377,7 @@ const Captcha = /*#__PURE__*/React.forwardRef((props, ref) => {
23372
23377
  }
23373
23378
  break;
23374
23379
  case 'hcaptcha':
23375
- if (window.hcaptcha && window.hcaptcha.render) {
23380
+ if (window.hcaptcha?.render) {
23376
23381
  widgetIdRef.current = window.hcaptcha.render(containerRef.current, {
23377
23382
  sitekey: siteKey,
23378
23383
  callback: onVerify,
@@ -23388,7 +23393,7 @@ const Captcha = /*#__PURE__*/React.forwardRef((props, ref) => {
23388
23393
  }
23389
23394
  break;
23390
23395
  case 'turnstile':
23391
- if (window.turnstile && window.turnstile.render) {
23396
+ if (window.turnstile?.render) {
23392
23397
  widgetIdRef.current = window.turnstile.render(containerRef.current, {
23393
23398
  sitekey: siteKey,
23394
23399
  callback: onVerify,
@@ -23439,20 +23444,10 @@ const Captcha = /*#__PURE__*/React.forwardRef((props, ref) => {
23439
23444
  return null;
23440
23445
  }
23441
23446
  return jsxRuntime.jsxs(material.Box, {
23442
- ref: ref,
23443
- ...htmlProps,
23447
+ ...restProps,
23444
23448
  sx: {
23445
- my: 2,
23446
- ...styleProps.sx
23449
+ my: 2
23447
23450
  },
23448
- ...(gridProps && {
23449
- 'data-grid-span': gridProps.span,
23450
- 'data-grid-xs': gridProps.xs,
23451
- 'data-grid-sm': gridProps.sm,
23452
- 'data-grid-md': gridProps.md,
23453
- 'data-grid-lg': gridProps.lg,
23454
- 'data-grid-xl': gridProps.xl
23455
- }),
23456
23451
  children: [error && jsxRuntime.jsx(material.Alert, {
23457
23452
  severity: "error",
23458
23453
  sx: {
@@ -23463,11 +23458,15 @@ const Captcha = /*#__PURE__*/React.forwardRef((props, ref) => {
23463
23458
  ref: containerRef
23464
23459
  })]
23465
23460
  });
23466
- });
23467
- Captcha.displayName = 'Captcha';
23468
- // Mark as QwickApp component
23469
- Object.assign(Captcha, {
23470
- [QWICKAPP_COMPONENT]: true
23461
+ }
23462
+ /**
23463
+ * Create Captcha component using the factory pattern
23464
+ */
23465
+ const Captcha = createSerializableView({
23466
+ tagName: 'Captcha',
23467
+ version: '1.0.0',
23468
+ role: 'input',
23469
+ View: CaptchaView
23471
23470
  });
23472
23471
 
23473
23472
  /**
@@ -24595,7 +24594,7 @@ const Scaffold = ({
24595
24594
  className: "appbar-right",
24596
24595
  children: [enhancedAppBar?.actions && jsxRuntime.jsx("div", {
24597
24596
  className: "appbar-actions",
24598
- children: enhancedAppBar.actions
24597
+ children: typeof enhancedAppBar.actions === 'function' ? enhancedAppBar.actions() : enhancedAppBar.actions
24599
24598
  }, "appbar-actions"), jsxRuntime.jsxs("div", {
24600
24599
  className: "appbar-theme-controls",
24601
24600
  children: [showThemeSwitcher && jsxRuntime.jsx(ThemeSwitcher, {}, "theme-switcher"), showPaletteSwitcher && jsxRuntime.jsx(PaletteSwitcher, {}, "palette-switcher")]
@@ -31066,6 +31065,240 @@ __decorate([schema.Field(), schema.Editor({
31066
31065
  }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], exports.FormBlockModel.prototype, "backgroundImage", void 0);
31067
31066
  exports.FormBlockModel = __decorate([schema.Schema('FormBlock', '1.0.0')], exports.FormBlockModel);
31068
31067
 
31068
+ /**
31069
+ * Schema for FormSelect component - Themed dropdown select input
31070
+ *
31071
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
31072
+ */
31073
+ exports.FormSelectModel = class FormSelectModel extends ViewSchema {};
31074
+ __decorate([schema.Field(), schema.Editor({
31075
+ field_type: schema.FieldType.TEXT,
31076
+ label: 'Label',
31077
+ description: 'Label text for the select field',
31078
+ placeholder: 'Enter label...'
31079
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], exports.FormSelectModel.prototype, "label", void 0);
31080
+ __decorate([schema.Field(), schema.Editor({
31081
+ field_type: schema.FieldType.TEXT,
31082
+ label: 'Value',
31083
+ description: 'Current selected value',
31084
+ placeholder: ''
31085
+ }), classValidator.IsString(), __metadata("design:type", Object)], exports.FormSelectModel.prototype, "value", void 0);
31086
+ __decorate([schema.Field(), schema.Editor({
31087
+ field_type: schema.FieldType.TEXTAREA,
31088
+ label: 'Options',
31089
+ description: 'Select options as JSON array: [{"value": "1", "label": "Option 1"}]',
31090
+ placeholder: '[{"value": "1", "label": "Option 1"}]'
31091
+ }), classValidator.IsString(), __metadata("design:type", String)], exports.FormSelectModel.prototype, "options", void 0);
31092
+ __decorate([schema.Field(), schema.Editor({
31093
+ field_type: schema.FieldType.TEXT,
31094
+ label: 'Helper Text',
31095
+ description: 'Helper text displayed below the select',
31096
+ placeholder: 'Enter helper text...'
31097
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], exports.FormSelectModel.prototype, "helperText", void 0);
31098
+ __decorate([schema.Field({
31099
+ defaultValue: false
31100
+ }), schema.Editor({
31101
+ field_type: schema.FieldType.BOOLEAN,
31102
+ label: 'Required',
31103
+ description: 'Mark field as required'
31104
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormSelectModel.prototype, "required", void 0);
31105
+ __decorate([schema.Field({
31106
+ defaultValue: false
31107
+ }), schema.Editor({
31108
+ field_type: schema.FieldType.BOOLEAN,
31109
+ label: 'Disabled',
31110
+ description: 'Disable the select field'
31111
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormSelectModel.prototype, "disabled", void 0);
31112
+ __decorate([schema.Field({
31113
+ defaultValue: true
31114
+ }), schema.Editor({
31115
+ field_type: schema.FieldType.BOOLEAN,
31116
+ label: 'Full Width',
31117
+ description: 'Make select take full width of container'
31118
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormSelectModel.prototype, "fullWidth", void 0);
31119
+ __decorate([schema.Field({
31120
+ defaultValue: 'small'
31121
+ }), schema.Editor({
31122
+ field_type: schema.FieldType.SELECT,
31123
+ label: 'Size',
31124
+ description: 'Size variant of the select field'
31125
+ }), classValidator.IsOptional(), classValidator.IsIn(['small', 'medium']), __metadata("design:type", String)], exports.FormSelectModel.prototype, "size", void 0);
31126
+ __decorate([schema.Field(), schema.Editor({
31127
+ field_type: schema.FieldType.TEXT,
31128
+ label: 'Placeholder',
31129
+ description: 'Placeholder text when no value is selected',
31130
+ placeholder: 'Select an option...'
31131
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], exports.FormSelectModel.prototype, "placeholder", void 0);
31132
+ exports.FormSelectModel = __decorate([schema.Schema('FormSelect', '1.0.0')], exports.FormSelectModel);
31133
+
31134
+ /**
31135
+ * Schema for FormField component - Themed text/number input field
31136
+ *
31137
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
31138
+ */
31139
+ exports.FormFieldModel = class FormFieldModel extends ViewSchema {};
31140
+ __decorate([schema.Field(), schema.Editor({
31141
+ field_type: schema.FieldType.TEXT,
31142
+ label: 'Label',
31143
+ description: 'Label text for the input field',
31144
+ placeholder: 'Enter label...'
31145
+ }), classValidator.IsString(), __metadata("design:type", String)], exports.FormFieldModel.prototype, "label", void 0);
31146
+ __decorate([schema.Field(), schema.Editor({
31147
+ field_type: schema.FieldType.TEXT,
31148
+ label: 'Value',
31149
+ description: 'Current input value',
31150
+ placeholder: ''
31151
+ }), classValidator.IsString(), __metadata("design:type", Object)], exports.FormFieldModel.prototype, "value", void 0);
31152
+ __decorate([schema.Field({
31153
+ defaultValue: 'text'
31154
+ }), schema.Editor({
31155
+ field_type: schema.FieldType.SELECT,
31156
+ label: 'Input Type',
31157
+ description: 'Type of input field'
31158
+ }), classValidator.IsOptional(), classValidator.IsIn(['text', 'number', 'password', 'email', 'tel']), __metadata("design:type", String)], exports.FormFieldModel.prototype, "type", void 0);
31159
+ __decorate([schema.Field(), schema.Editor({
31160
+ field_type: schema.FieldType.TEXT,
31161
+ label: 'Helper Text',
31162
+ description: 'Helper text displayed below the input',
31163
+ placeholder: 'Enter helper text...'
31164
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], exports.FormFieldModel.prototype, "helperText", void 0);
31165
+ __decorate([schema.Field({
31166
+ defaultValue: false
31167
+ }), schema.Editor({
31168
+ field_type: schema.FieldType.BOOLEAN,
31169
+ label: 'Required',
31170
+ description: 'Mark field as required'
31171
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormFieldModel.prototype, "required", void 0);
31172
+ __decorate([schema.Field({
31173
+ defaultValue: false
31174
+ }), schema.Editor({
31175
+ field_type: schema.FieldType.BOOLEAN,
31176
+ label: 'Read Only',
31177
+ description: 'Make field read-only'
31178
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormFieldModel.prototype, "readOnly", void 0);
31179
+ __decorate([schema.Field({
31180
+ defaultValue: false
31181
+ }), schema.Editor({
31182
+ field_type: schema.FieldType.BOOLEAN,
31183
+ label: 'Disabled',
31184
+ description: 'Disable the input field'
31185
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormFieldModel.prototype, "disabled", void 0);
31186
+ __decorate([schema.Field(), schema.Editor({
31187
+ field_type: schema.FieldType.TEXT,
31188
+ label: 'Disabled Color',
31189
+ description: 'Custom color for disabled state (CSS color value)',
31190
+ placeholder: 'var(--theme-text-disabled)'
31191
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], exports.FormFieldModel.prototype, "disabledColor", void 0);
31192
+ __decorate([schema.Field({
31193
+ defaultValue: true
31194
+ }), schema.Editor({
31195
+ field_type: schema.FieldType.BOOLEAN,
31196
+ label: 'Full Width',
31197
+ description: 'Make input take full width of container'
31198
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormFieldModel.prototype, "fullWidth", void 0);
31199
+ __decorate([schema.Field({
31200
+ defaultValue: false
31201
+ }), schema.Editor({
31202
+ field_type: schema.FieldType.BOOLEAN,
31203
+ label: 'Multiline',
31204
+ description: 'Enable multiline textarea mode'
31205
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormFieldModel.prototype, "multiline", void 0);
31206
+ __decorate([schema.Field(), schema.Editor({
31207
+ field_type: schema.FieldType.TEXT,
31208
+ label: 'Rows',
31209
+ description: 'Number of rows for multiline textarea',
31210
+ placeholder: '4'
31211
+ }), classValidator.IsOptional(), classValidator.IsInt(), classValidator.Min(1), __metadata("design:type", Number)], exports.FormFieldModel.prototype, "rows", void 0);
31212
+ __decorate([schema.Field(), schema.Editor({
31213
+ field_type: schema.FieldType.TEXT,
31214
+ label: 'Placeholder',
31215
+ description: 'Placeholder text',
31216
+ placeholder: 'Enter text...'
31217
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], exports.FormFieldModel.prototype, "placeholder", void 0);
31218
+ exports.FormFieldModel = __decorate([schema.Schema('FormField', '1.0.0')], exports.FormFieldModel);
31219
+
31220
+ /**
31221
+ * Schema for FormCheckbox component - Themed checkbox input
31222
+ *
31223
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
31224
+ */
31225
+ exports.FormCheckboxModel = class FormCheckboxModel extends ViewSchema {};
31226
+ __decorate([schema.Field(), schema.Editor({
31227
+ field_type: schema.FieldType.TEXT,
31228
+ label: 'Label',
31229
+ description: 'Label text for the checkbox',
31230
+ placeholder: 'Enter label...'
31231
+ }), classValidator.IsString(), __metadata("design:type", String)], exports.FormCheckboxModel.prototype, "label", void 0);
31232
+ __decorate([schema.Field({
31233
+ defaultValue: false
31234
+ }), schema.Editor({
31235
+ field_type: schema.FieldType.BOOLEAN,
31236
+ label: 'Checked',
31237
+ description: 'Checkbox checked state'
31238
+ }), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormCheckboxModel.prototype, "checked", void 0);
31239
+ __decorate([schema.Field(), schema.Editor({
31240
+ field_type: schema.FieldType.TEXT,
31241
+ label: 'Helper Text',
31242
+ description: 'Helper text displayed below the checkbox',
31243
+ placeholder: 'Enter helper text...'
31244
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], exports.FormCheckboxModel.prototype, "helperText", void 0);
31245
+ __decorate([schema.Field({
31246
+ defaultValue: false
31247
+ }), schema.Editor({
31248
+ field_type: schema.FieldType.BOOLEAN,
31249
+ label: 'Required',
31250
+ description: 'Mark checkbox as required'
31251
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormCheckboxModel.prototype, "required", void 0);
31252
+ __decorate([schema.Field({
31253
+ defaultValue: false
31254
+ }), schema.Editor({
31255
+ field_type: schema.FieldType.BOOLEAN,
31256
+ label: 'Disabled',
31257
+ description: 'Disable the checkbox'
31258
+ }), classValidator.IsOptional(), classValidator.IsBoolean(), __metadata("design:type", Boolean)], exports.FormCheckboxModel.prototype, "disabled", void 0);
31259
+ exports.FormCheckboxModel = __decorate([schema.Schema('FormCheckbox', '1.0.0')], exports.FormCheckboxModel);
31260
+
31261
+ /**
31262
+ * Schema for Captcha component - Universal CAPTCHA widget
31263
+ *
31264
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
31265
+ */
31266
+ exports.CaptchaModel = class CaptchaModel extends ViewSchema {};
31267
+ __decorate([schema.Field(), schema.Editor({
31268
+ field_type: schema.FieldType.SELECT,
31269
+ label: 'CAPTCHA Provider',
31270
+ description: 'Which CAPTCHA service to use'
31271
+ }), classValidator.IsIn(['recaptcha-v2', 'recaptcha-v3', 'hcaptcha', 'turnstile']), __metadata("design:type", String)], exports.CaptchaModel.prototype, "provider", void 0);
31272
+ __decorate([schema.Field(), schema.Editor({
31273
+ field_type: schema.FieldType.TEXT,
31274
+ label: 'Site Key',
31275
+ description: 'Public site key from CAPTCHA provider',
31276
+ placeholder: 'Enter site key...'
31277
+ }), classValidator.IsString(), __metadata("design:type", String)], exports.CaptchaModel.prototype, "siteKey", void 0);
31278
+ __decorate([schema.Field({
31279
+ defaultValue: 'light'
31280
+ }), schema.Editor({
31281
+ field_type: schema.FieldType.SELECT,
31282
+ label: 'Theme',
31283
+ description: 'CAPTCHA widget theme'
31284
+ }), classValidator.IsOptional(), classValidator.IsIn(['light', 'dark']), __metadata("design:type", String)], exports.CaptchaModel.prototype, "theme", void 0);
31285
+ __decorate([schema.Field({
31286
+ defaultValue: 'normal'
31287
+ }), schema.Editor({
31288
+ field_type: schema.FieldType.SELECT,
31289
+ label: 'Size',
31290
+ description: 'CAPTCHA widget size'
31291
+ }), classValidator.IsOptional(), classValidator.IsIn(['normal', 'compact', 'invisible']), __metadata("design:type", String)], exports.CaptchaModel.prototype, "size", void 0);
31292
+ __decorate([schema.Field({
31293
+ defaultValue: 'submit'
31294
+ }), schema.Editor({
31295
+ field_type: schema.FieldType.TEXT,
31296
+ label: 'Action',
31297
+ description: 'reCAPTCHA v3 action name',
31298
+ placeholder: 'submit'
31299
+ }), classValidator.IsOptional(), classValidator.IsString(), __metadata("design:type", String)], exports.CaptchaModel.prototype, "action", void 0);
31300
+ exports.CaptchaModel = __decorate([schema.Schema('Captcha', '1.0.0')], exports.CaptchaModel);
31301
+
31069
31302
  /**
31070
31303
  * FooterSection Schema - Defines data structure for footer sections
31071
31304
  *
@@ -33293,6 +33526,7 @@ exports.OptionSelector = OptionSelector;
33293
33526
  exports.Page = Page;
33294
33527
  exports.PageBannerHeader = PageBannerHeader;
33295
33528
  exports.PaletteAutumn = PaletteAutumn;
33529
+ exports.PaletteBoutique = PaletteBoutique;
33296
33530
  exports.PaletteCosmic = PaletteCosmic;
33297
33531
  exports.PaletteDefault = PaletteDefault;
33298
33532
  exports.PaletteOcean = PaletteOcean;