@qwickapps/react-framework 1.5.13 → 1.6.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 (46) hide show
  1. package/dist/components/forms/Captcha.d.ts +33 -28
  2. package/dist/components/forms/Captcha.d.ts.map +1 -1
  3. package/dist/components/forms/FormCheckbox.d.ts +15 -12
  4. package/dist/components/forms/FormCheckbox.d.ts.map +1 -1
  5. package/dist/components/forms/FormField.d.ts +20 -23
  6. package/dist/components/forms/FormField.d.ts.map +1 -1
  7. package/dist/components/forms/FormSelect.d.ts +16 -15
  8. package/dist/components/forms/FormSelect.d.ts.map +1 -1
  9. package/dist/hooks/useBaseProps.d.ts +27 -1172
  10. package/dist/hooks/useBaseProps.d.ts.map +1 -1
  11. package/dist/index.esm.js +349 -156
  12. package/dist/index.js +348 -155
  13. package/dist/palettes/manifest.json +19 -19
  14. package/dist/schemas/CaptchaSchema.d.ts +16 -0
  15. package/dist/schemas/CaptchaSchema.d.ts.map +1 -0
  16. package/dist/schemas/FormCheckboxSchema.d.ts +16 -0
  17. package/dist/schemas/FormCheckboxSchema.d.ts.map +1 -0
  18. package/dist/schemas/FormFieldSchema.d.ts +23 -0
  19. package/dist/schemas/FormFieldSchema.d.ts.map +1 -0
  20. package/dist/schemas/FormSelectSchema.d.ts +20 -0
  21. package/dist/schemas/FormSelectSchema.d.ts.map +1 -0
  22. package/dist/schemas/index.d.ts +4 -0
  23. package/dist/schemas/index.d.ts.map +1 -1
  24. package/package.json +1 -1
  25. package/src/components/forms/Captcha.tsx +57 -63
  26. package/src/components/forms/FormCheckbox.tsx +35 -43
  27. package/src/components/forms/FormField.tsx +50 -66
  28. package/src/components/forms/FormSelect.tsx +41 -49
  29. package/src/hooks/useBaseProps.ts +34 -1
  30. package/src/schemas/CaptchaSchema.ts +65 -0
  31. package/src/schemas/FormCheckboxSchema.ts +65 -0
  32. package/src/schemas/FormFieldSchema.ts +140 -0
  33. package/src/schemas/FormSelectSchema.ts +108 -0
  34. package/src/schemas/index.ts +4 -0
  35. /package/dist/palettes/{palette-autumn.1.5.13.css → palette-autumn.1.6.0.css} +0 -0
  36. /package/dist/palettes/{palette-autumn.1.5.13.min.css → palette-autumn.1.6.0.min.css} +0 -0
  37. /package/dist/palettes/{palette-cosmic.1.5.13.css → palette-cosmic.1.6.0.css} +0 -0
  38. /package/dist/palettes/{palette-cosmic.1.5.13.min.css → palette-cosmic.1.6.0.min.css} +0 -0
  39. /package/dist/palettes/{palette-default.1.5.13.css → palette-default.1.6.0.css} +0 -0
  40. /package/dist/palettes/{palette-default.1.5.13.min.css → palette-default.1.6.0.min.css} +0 -0
  41. /package/dist/palettes/{palette-ocean.1.5.13.css → palette-ocean.1.6.0.css} +0 -0
  42. /package/dist/palettes/{palette-ocean.1.5.13.min.css → palette-ocean.1.6.0.min.css} +0 -0
  43. /package/dist/palettes/{palette-spring.1.5.13.css → palette-spring.1.6.0.css} +0 -0
  44. /package/dist/palettes/{palette-spring.1.5.13.min.css → palette-spring.1.6.0.min.css} +0 -0
  45. /package/dist/palettes/{palette-winter.1.5.13.css → palette-winter.1.6.0.css} +0 -0
  46. /package/dist/palettes/{palette-winter.1.5.13.min.css → palette-winter.1.6.0.min.css} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./manifest.schema.json",
3
- "version": "1.5.13",
3
+ "version": "1.6.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.5.13",
12
- "file": "palette-default.1.5.13.css",
11
+ "version": "1.6.0",
12
+ "file": "palette-default.1.6.0.css",
13
13
  "primaryColor": "#007bff",
14
14
  "inlined": true,
15
- "fileMinified": "palette-default.1.5.13.min.css",
15
+ "fileMinified": "palette-default.1.6.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.5.13",
26
- "file": "palette-autumn.1.5.13.css",
25
+ "version": "1.6.0",
26
+ "file": "palette-autumn.1.6.0.css",
27
27
  "primaryColor": "#ea580c",
28
28
  "inlined": false,
29
- "fileMinified": "palette-autumn.1.5.13.min.css",
29
+ "fileMinified": "palette-autumn.1.6.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": "Modern purple gradient for creative and tech brands - inspired by cosmic nebulae",
37
37
  "author": "QwickApps",
38
38
  "license": "PolyForm-Shield-1.0.0",
39
- "version": "1.5.13",
40
- "file": "palette-cosmic.1.5.13.css",
39
+ "version": "1.6.0",
40
+ "file": "palette-cosmic.1.6.0.css",
41
41
  "primaryColor": "#8b5cf6",
42
42
  "inlined": false,
43
- "fileMinified": "palette-cosmic.1.5.13.min.css",
43
+ "fileMinified": "palette-cosmic.1.6.0.min.css",
44
44
  "fileLatest": "palette-cosmic.latest.css",
45
45
  "fileLatestMinified": "palette-cosmic.latest.min.css"
46
46
  },
@@ -50,11 +50,11 @@
50
50
  "description": "Deep blues, aqua teals, and seafoam greens - inspired by ocean depths",
51
51
  "author": "QwickApps",
52
52
  "license": "PolyForm-Shield-1.0.0",
53
- "version": "1.5.13",
54
- "file": "palette-ocean.1.5.13.css",
53
+ "version": "1.6.0",
54
+ "file": "palette-ocean.1.6.0.css",
55
55
  "primaryColor": "#0891b2",
56
56
  "inlined": false,
57
- "fileMinified": "palette-ocean.1.5.13.min.css",
57
+ "fileMinified": "palette-ocean.1.6.0.min.css",
58
58
  "fileLatest": "palette-ocean.latest.css",
59
59
  "fileLatestMinified": "palette-ocean.latest.min.css"
60
60
  },
@@ -64,11 +64,11 @@
64
64
  "description": "Fresh greens, soft pinks, and bright yellows - inspired by spring blooms",
65
65
  "author": "QwickApps",
66
66
  "license": "PolyForm-Shield-1.0.0",
67
- "version": "1.5.13",
68
- "file": "palette-spring.1.5.13.css",
67
+ "version": "1.6.0",
68
+ "file": "palette-spring.1.6.0.css",
69
69
  "primaryColor": "#16a34a",
70
70
  "inlined": false,
71
- "fileMinified": "palette-spring.1.5.13.min.css",
71
+ "fileMinified": "palette-spring.1.6.0.min.css",
72
72
  "fileLatest": "palette-spring.latest.css",
73
73
  "fileLatestMinified": "palette-spring.latest.min.css"
74
74
  },
@@ -78,11 +78,11 @@
78
78
  "description": "Cool blues, icy whites, and frosty grays - inspired by winter landscapes",
79
79
  "author": "QwickApps",
80
80
  "license": "PolyForm-Shield-1.0.0",
81
- "version": "1.5.13",
82
- "file": "palette-winter.1.5.13.css",
81
+ "version": "1.6.0",
82
+ "file": "palette-winter.1.6.0.css",
83
83
  "primaryColor": "#0077be",
84
84
  "inlined": false,
85
- "fileMinified": "palette-winter.1.5.13.min.css",
85
+ "fileMinified": "palette-winter.1.6.0.min.css",
86
86
  "fileLatest": "palette-winter.latest.css",
87
87
  "fileLatestMinified": "palette-winter.latest.min.css"
88
88
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Schema for Captcha component - Universal CAPTCHA widget
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ import 'reflect-metadata';
7
+ import ViewSchema from './ViewSchema';
8
+ export declare class CaptchaModel extends ViewSchema {
9
+ provider: 'recaptcha-v2' | 'recaptcha-v3' | 'hcaptcha' | 'turnstile';
10
+ siteKey: string;
11
+ theme?: 'light' | 'dark';
12
+ size?: 'normal' | 'compact' | 'invisible';
13
+ action?: string;
14
+ }
15
+ export default CaptchaModel;
16
+ //# sourceMappingURL=CaptchaSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CaptchaSchema.d.ts","sourceRoot":"","sources":["../../src/schemas/CaptchaSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,qBACa,YAAa,SAAQ,UAAU;IAQ1C,QAAQ,EAAG,cAAc,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;IAUtE,OAAO,EAAG,MAAM,CAAC;IAUjB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAUzB,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IAW1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Schema for FormCheckbox component - Themed checkbox input
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ import 'reflect-metadata';
7
+ import ViewSchema from './ViewSchema';
8
+ export declare class FormCheckboxModel extends ViewSchema {
9
+ label: string;
10
+ checked: boolean;
11
+ helperText?: string;
12
+ required?: boolean;
13
+ disabled?: boolean;
14
+ }
15
+ export default FormCheckboxModel;
16
+ //# sourceMappingURL=FormCheckboxSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormCheckboxSchema.d.ts","sourceRoot":"","sources":["../../src/schemas/FormCheckboxSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,qBACa,iBAAkB,SAAQ,UAAU;IAS/C,KAAK,EAAG,MAAM,CAAC;IASf,OAAO,EAAG,OAAO,CAAC;IAWlB,UAAU,CAAC,EAAE,MAAM,CAAC;IAUpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAUnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Schema for FormField component - Themed text/number input field
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ import 'reflect-metadata';
7
+ import ViewSchema from './ViewSchema';
8
+ export declare class FormFieldModel extends ViewSchema {
9
+ label: string;
10
+ value: string | number;
11
+ type?: 'text' | 'number' | 'password' | 'email' | 'tel';
12
+ helperText?: string;
13
+ required?: boolean;
14
+ readOnly?: boolean;
15
+ disabled?: boolean;
16
+ disabledColor?: string;
17
+ fullWidth?: boolean;
18
+ multiline?: boolean;
19
+ rows?: number;
20
+ placeholder?: string;
21
+ }
22
+ export default FormFieldModel;
23
+ //# sourceMappingURL=FormFieldSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormFieldSchema.d.ts","sourceRoot":"","sources":["../../src/schemas/FormFieldSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,qBACa,cAAe,SAAQ,UAAU;IAS5C,KAAK,EAAG,MAAM,CAAC;IAUf,KAAK,EAAG,MAAM,GAAG,MAAM,CAAC;IAUxB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IAWxD,UAAU,CAAC,EAAE,MAAM,CAAC;IAUpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAUnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAUnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAWnB,aAAa,CAAC,EAAE,MAAM,CAAC;IAUvB,SAAS,CAAC,EAAE,OAAO,CAAC;IAUpB,SAAS,CAAC,EAAE,OAAO,CAAC;IAYpB,IAAI,CAAC,EAAE,MAAM,CAAC;IAWd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Schema for FormSelect component - Themed dropdown select input
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ import 'reflect-metadata';
7
+ import ViewSchema from './ViewSchema';
8
+ export declare class FormSelectModel extends ViewSchema {
9
+ label?: string;
10
+ value: string | number;
11
+ options: string;
12
+ helperText?: string;
13
+ required?: boolean;
14
+ disabled?: boolean;
15
+ fullWidth?: boolean;
16
+ size?: 'small' | 'medium';
17
+ placeholder?: string;
18
+ }
19
+ export default FormSelectModel;
20
+ //# sourceMappingURL=FormSelectSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormSelectSchema.d.ts","sourceRoot":"","sources":["../../src/schemas/FormSelectSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,qBACa,eAAgB,SAAQ,UAAU;IAU7C,KAAK,CAAC,EAAE,MAAM,CAAC;IAUf,KAAK,EAAG,MAAM,GAAG,MAAM,CAAC;IAUxB,OAAO,EAAG,MAAM,CAAC;IAWjB,UAAU,CAAC,EAAE,MAAM,CAAC;IAUpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAUnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAUnB,SAAS,CAAC,EAAE,OAAO,CAAC;IAUpB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAW1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAe,eAAe,CAAC"}
@@ -23,6 +23,10 @@ export * from './FeatureGridSchema';
23
23
  export * from './FeatureItemSchema';
24
24
  export * from './FooterItemSchema';
25
25
  export * from './FormBlockSchema';
26
+ export * from './FormSelectSchema';
27
+ export * from './FormFieldSchema';
28
+ export * from './FormCheckboxSchema';
29
+ export * from './CaptchaSchema';
26
30
  export * from './FooterSchema';
27
31
  export * from './FooterSectionSchema';
28
32
  export * from './GridCellSchema';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,yBAAyB,CAAC;AAGjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AAGtC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,yBAAyB,CAAC;AAGjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AAGtC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qwickapps/react-framework",
3
- "version": "1.5.13",
3
+ "version": "1.6.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",
@@ -11,7 +11,7 @@
11
11
  * - Provider-agnostic API
12
12
  * - Automatic script loading
13
13
  * - TypeScript support
14
- * - Themed styling with base props support
14
+ * - Themed styling with schema-driven architecture
15
15
  * - Grid behavior support
16
16
  * - Error handling
17
17
  *
@@ -20,57 +20,57 @@
20
20
 
21
21
  import React, { useEffect, useRef, useState } from 'react';
22
22
  import { Box, Alert } from '@mui/material';
23
- import { useBaseProps, WithBaseProps, QWICKAPP_COMPONENT } from '../../hooks/useBaseProps';
23
+ import type { SchemaProps } from '@qwickapps/schema';
24
+ import CaptchaModel from '../../schemas/CaptchaSchema';
25
+ import { ViewProps } from '../shared/viewProps';
26
+ import { createSerializableView, SerializableComponent } from '../shared/createSerializableView';
24
27
 
25
- export type CaptchaProvider = 'recaptcha-v2' | 'recaptcha-v3' | 'hcaptcha' | 'turnstile';
28
+ // Declare global interfaces for CAPTCHA providers
29
+ declare global {
30
+ interface Window {
31
+ grecaptcha?: {
32
+ render?: (container: HTMLElement | null, params: Record<string, unknown>) => string | number;
33
+ execute?: (siteKey: string, options: { action: string }) => Promise<string>;
34
+ reset?: (widgetId: string | number) => void;
35
+ };
36
+ hcaptcha?: {
37
+ render?: (container: HTMLElement | null, params: Record<string, unknown>) => string | number;
38
+ remove?: (widgetId: string | number) => void;
39
+ };
40
+ turnstile?: {
41
+ render?: (container: HTMLElement | null, params: Record<string, unknown>) => string | number;
42
+ remove?: (widgetId: string | number) => void;
43
+ };
44
+ }
45
+ }
26
46
 
27
- interface CaptchaBaseProps {
28
- /** CAPTCHA provider */
29
- provider: CaptchaProvider;
30
- /** Site key (public key) */
31
- siteKey: string;
47
+ /**
48
+ * Props interface for Captcha component
49
+ * Combines schema props with callback handlers
50
+ */
51
+ export interface CaptchaProps extends ViewProps, SchemaProps<typeof CaptchaModel> {
32
52
  /** Callback when CAPTCHA is successfully completed */
33
53
  onVerify: (token: string) => void;
34
54
  /** Callback when CAPTCHA expires or fails */
35
55
  onExpire?: () => void;
36
56
  /** Callback when CAPTCHA encounters an error */
37
57
  onError?: (error: Error) => void;
38
- /** Theme for the widget (light or dark) */
39
- theme?: 'light' | 'dark';
40
- /** Size of the widget */
41
- size?: 'normal' | 'compact' | 'invisible';
42
- /** reCAPTCHA v3 action name */
43
- action?: string;
44
58
  }
45
59
 
46
- export interface CaptchaProps extends WithBaseProps<CaptchaBaseProps> {}
47
-
48
- // Declare global interfaces for CAPTCHA providers
49
- declare global {
50
- interface Window {
51
- grecaptcha?: unknown;
52
- hcaptcha?: unknown;
53
- turnstile?: unknown;
54
- onRecaptchaLoad?: () => void;
55
- onHcaptchaLoad?: () => void;
56
- onTurnstileLoad?: () => void;
57
- }
58
- }
59
-
60
- export const Captcha = React.forwardRef<HTMLDivElement, CaptchaProps>((props, ref) => {
61
- const { gridProps, styleProps, htmlProps, restProps } = useBaseProps(props);
62
-
63
- const {
64
- provider,
65
- siteKey,
66
- onVerify,
67
- onExpire,
68
- onError,
69
- theme = 'light',
70
- size = 'normal',
71
- action = 'submit',
72
- } = restProps as CaptchaBaseProps;
73
-
60
+ /**
61
+ * CaptchaView - Pure view component that renders the CAPTCHA widget
62
+ */
63
+ function CaptchaView({
64
+ provider,
65
+ siteKey,
66
+ onVerify,
67
+ onExpire,
68
+ onError,
69
+ theme = 'light',
70
+ size = 'normal',
71
+ action = 'submit',
72
+ ...restProps
73
+ }: CaptchaProps) {
74
74
  const containerRef = useRef<HTMLDivElement>(null);
75
75
  const widgetIdRef = useRef<string | number | null>(null);
76
76
  const [isLoaded, setIsLoaded] = useState(false);
@@ -155,7 +155,7 @@ export const Captcha = React.forwardRef<HTMLDivElement, CaptchaProps>((props, re
155
155
  try {
156
156
  switch (provider) {
157
157
  case 'recaptcha-v2':
158
- if (window.grecaptcha && window.grecaptcha.render) {
158
+ if (window.grecaptcha?.render) {
159
159
  widgetIdRef.current = window.grecaptcha.render(containerRef.current, {
160
160
  sitekey: siteKey,
161
161
  callback: onVerify,
@@ -173,7 +173,7 @@ export const Captcha = React.forwardRef<HTMLDivElement, CaptchaProps>((props, re
173
173
 
174
174
  case 'recaptcha-v3':
175
175
  // reCAPTCHA v3 is invisible and executes programmatically
176
- if (window.grecaptcha && window.grecaptcha.execute) {
176
+ if (window.grecaptcha?.execute) {
177
177
  window.grecaptcha.execute(siteKey, { action }).then((token: string) => {
178
178
  onVerify(token);
179
179
  }).catch((err: Error) => {
@@ -184,7 +184,7 @@ export const Captcha = React.forwardRef<HTMLDivElement, CaptchaProps>((props, re
184
184
  break;
185
185
 
186
186
  case 'hcaptcha':
187
- if (window.hcaptcha && window.hcaptcha.render) {
187
+ if (window.hcaptcha?.render) {
188
188
  widgetIdRef.current = window.hcaptcha.render(containerRef.current, {
189
189
  sitekey: siteKey,
190
190
  callback: onVerify,
@@ -201,7 +201,7 @@ export const Captcha = React.forwardRef<HTMLDivElement, CaptchaProps>((props, re
201
201
  break;
202
202
 
203
203
  case 'turnstile':
204
- if (window.turnstile && window.turnstile.render) {
204
+ if (window.turnstile?.render) {
205
205
  widgetIdRef.current = window.turnstile.render(containerRef.current, {
206
206
  sitekey: siteKey,
207
207
  callback: onVerify,
@@ -257,21 +257,10 @@ export const Captcha = React.forwardRef<HTMLDivElement, CaptchaProps>((props, re
257
257
 
258
258
  return (
259
259
  <Box
260
- ref={ref}
261
- {...htmlProps}
260
+ {...restProps}
262
261
  sx={{
263
262
  my: 2,
264
- ...styleProps.sx,
265
263
  }}
266
- // Store grid props as data attributes for ColumnLayout to pick up
267
- {...(gridProps && {
268
- 'data-grid-span': gridProps.span,
269
- 'data-grid-xs': gridProps.xs,
270
- 'data-grid-sm': gridProps.sm,
271
- 'data-grid-md': gridProps.md,
272
- 'data-grid-lg': gridProps.lg,
273
- 'data-grid-xl': gridProps.xl,
274
- })}
275
264
  >
276
265
  {error && (
277
266
  <Alert severity="error" sx={{ mb: 2 }}>
@@ -281,11 +270,16 @@ export const Captcha = React.forwardRef<HTMLDivElement, CaptchaProps>((props, re
281
270
  <div ref={containerRef} />
282
271
  </Box>
283
272
  );
284
- });
285
-
286
- Captcha.displayName = 'Captcha';
273
+ }
287
274
 
288
- // Mark as QwickApp component
289
- Object.assign(Captcha, { [QWICKAPP_COMPONENT]: true });
275
+ /**
276
+ * Create Captcha component using the factory pattern
277
+ */
278
+ export const Captcha: SerializableComponent<CaptchaProps> = createSerializableView<CaptchaProps>({
279
+ tagName: 'Captcha',
280
+ version: '1.0.0',
281
+ role: 'input',
282
+ View: CaptchaView,
283
+ });
290
284
 
291
285
  export default Captcha;
@@ -6,7 +6,7 @@
6
6
  * - Supports FormControlLabel for proper label positioning
7
7
  * - Handles required and disabled states
8
8
  * - Helper text support
9
- * - Base props support for grid behavior and styling
9
+ * - Schema-driven architecture with serialization support
10
10
  *
11
11
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
12
12
  */
@@ -18,31 +18,32 @@ import {
18
18
  Checkbox,
19
19
  FormHelperText,
20
20
  } from '@mui/material';
21
- import { useBaseProps, WithBaseProps, QWICKAPP_COMPONENT } from '../../hooks/useBaseProps';
21
+ import type { SchemaProps } from '@qwickapps/schema';
22
+ import FormCheckboxModel from '../../schemas/FormCheckboxSchema';
23
+ import { ViewProps } from '../shared/viewProps';
24
+ import { createSerializableView, SerializableComponent } from '../shared/createSerializableView';
22
25
 
23
- interface FormCheckboxBaseProps {
24
- label: string;
25
- checked: boolean;
26
+ /**
27
+ * Props interface for FormCheckbox component
28
+ * Combines schema props with callback handler
29
+ */
30
+ export interface FormCheckboxProps extends ViewProps, SchemaProps<typeof FormCheckboxModel> {
31
+ /** Callback when checkbox state changes */
26
32
  onChange: (checked: boolean) => void;
27
- helperText?: string;
28
- required?: boolean;
29
- disabled?: boolean;
30
33
  }
31
34
 
32
- export interface FormCheckboxProps extends WithBaseProps<FormCheckboxBaseProps> {}
33
-
34
- export const FormCheckbox = React.forwardRef<HTMLDivElement, FormCheckboxProps>((props, ref) => {
35
- const { gridProps, styleProps, htmlProps, restProps } = useBaseProps(props);
36
-
37
- const {
38
- label,
39
- checked,
40
- onChange,
41
- helperText,
42
- required = false,
43
- disabled = false,
44
- } = restProps as FormCheckboxBaseProps;
45
-
35
+ /**
36
+ * FormCheckboxView - Pure view component that renders the checkbox
37
+ */
38
+ function FormCheckboxView({
39
+ label,
40
+ checked,
41
+ onChange,
42
+ helperText,
43
+ required = false,
44
+ disabled = false,
45
+ ...restProps
46
+ }: FormCheckboxProps) {
46
47
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
47
48
  onChange(e.target.checked);
48
49
  };
@@ -65,29 +66,15 @@ export const FormCheckbox = React.forwardRef<HTMLDivElement, FormCheckboxProps>(
65
66
  '& .MuiFormControlLabel-label.Mui-disabled': {
66
67
  color: 'var(--theme-text-disabled)',
67
68
  },
68
- ...styleProps.sx,
69
69
  };
70
70
 
71
71
  const helperTextStyles = {
72
72
  color: 'var(--theme-secondary)',
73
- marginLeft: '32px', // Align with checkbox + label
73
+ marginLeft: '32px',
74
74
  };
75
75
 
76
76
  return (
77
- <FormControl
78
- ref={ref}
79
- {...htmlProps}
80
- {...styleProps}
81
- // Store grid props as data attributes for ColumnLayout to pick up
82
- {...(gridProps && {
83
- 'data-grid-span': gridProps.span,
84
- 'data-grid-xs': gridProps.xs,
85
- 'data-grid-sm': gridProps.sm,
86
- 'data-grid-md': gridProps.md,
87
- 'data-grid-lg': gridProps.lg,
88
- 'data-grid-xl': gridProps.xl,
89
- })}
90
- >
77
+ <FormControl {...restProps}>
91
78
  <FormControlLabel
92
79
  control={
93
80
  <Checkbox
@@ -106,11 +93,16 @@ export const FormCheckbox = React.forwardRef<HTMLDivElement, FormCheckboxProps>(
106
93
  )}
107
94
  </FormControl>
108
95
  );
109
- });
110
-
111
- FormCheckbox.displayName = 'FormCheckbox';
96
+ }
112
97
 
113
- // Mark as QwickApp component
114
- Object.assign(FormCheckbox, { [QWICKAPP_COMPONENT]: true });
98
+ /**
99
+ * Create FormCheckbox component using the factory pattern
100
+ */
101
+ export const FormCheckbox: SerializableComponent<FormCheckboxProps> = createSerializableView<FormCheckboxProps>({
102
+ tagName: 'FormCheckbox',
103
+ version: '1.0.0',
104
+ role: 'input',
105
+ View: FormCheckboxView,
106
+ });
115
107
 
116
108
  export default FormCheckbox;