@developer_tribe/react-builder 1.2.43 → 1.2.44-test.1

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 (101) hide show
  1. package/dist/build-components/Checkbox/Checkbox.d.ts +6 -0
  2. package/dist/build-components/Checkbox/CheckboxProps.generated.d.ts +67 -0
  3. package/dist/build-components/FormCheckbox/FormCheckbox.d.ts +3 -0
  4. package/dist/build-components/FormCheckbox/FormCheckboxProps.generated.d.ts +69 -0
  5. package/dist/build-components/FormErrorText/FormErrorText.d.ts +3 -0
  6. package/dist/build-components/FormErrorText/FormErrorTextProps.generated.d.ts +61 -0
  7. package/dist/build-components/FormProvider/FormProvider.d.ts +11 -0
  8. package/dist/build-components/FormProvider/FormProviderProps.generated.d.ts +55 -0
  9. package/dist/build-components/FormSubmitButton/FormSubmitButton.d.ts +2 -0
  10. package/dist/build-components/FormSubmitButton/FormSubmitButtonProps.generated.d.ts +73 -0
  11. package/dist/build-components/GlobalProvider/GlobalContext.d.ts +28 -0
  12. package/dist/build-components/GlobalProvider/GlobalProvider.d.ts +5 -0
  13. package/dist/build-components/GlobalProvider/GlobalProviderProps.generated.d.ts +60 -0
  14. package/dist/build-components/GlobalProvider/globalProviderUtils.d.ts +37 -0
  15. package/dist/build-components/GlobalProvider/useGlobalNavigation.d.ts +19 -0
  16. package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +17 -10
  17. package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +2 -0
  18. package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +2 -0
  19. package/dist/build-components/SystemButton/SystemButton.d.ts +7 -0
  20. package/dist/build-components/SystemButton/SystemButtonProps.generated.d.ts +71 -0
  21. package/dist/build-components/SystemButton/usePlacementButtonEvents.d.ts +28 -0
  22. package/dist/build-components/TermsProvider/TermsProvider.d.ts +5 -0
  23. package/dist/build-components/TermsProvider/TermsProviderProps.generated.d.ts +55 -0
  24. package/dist/build-components/WebView/WebView.d.ts +2 -0
  25. package/dist/build-components/WebView/WebViewProps.generated.d.ts +59 -0
  26. package/dist/build-components/index.d.ts +10 -1
  27. package/dist/build-components/patterns.generated.d.ts +5639 -1686
  28. package/dist/index.cjs.js +1 -1
  29. package/dist/index.cjs.js.map +1 -1
  30. package/dist/index.esm.js +1 -1
  31. package/dist/index.esm.js.map +1 -1
  32. package/dist/index.web.cjs.js +5 -5
  33. package/dist/index.web.cjs.js.map +1 -1
  34. package/dist/index.web.d.ts +1 -0
  35. package/dist/index.web.esm.js +4 -4
  36. package/dist/index.web.esm.js.map +1 -1
  37. package/dist/mockOS/context/MockOSContextBase.d.ts +3 -1
  38. package/dist/styles.css +1 -1
  39. package/dist/types/PreviewConfig.d.ts +1 -1
  40. package/package.json +2 -1
  41. package/src/assets/meta.json +1 -1
  42. package/src/assets/prompt-scheme-onboard.generated.ts +1 -1
  43. package/src/assets/prompt-scheme-paywall.generated.ts +1 -1
  44. package/src/assets/samples/getSamples.ts +7 -0
  45. package/src/assets/samples/global-onboard-flow.json +729 -0
  46. package/src/assets/samples/terms-and-privacy-no-form.json +108 -0
  47. package/src/assets/samples/terms-and-privacy.json +130 -0
  48. package/src/build-components/Checkbox/Checkbox.tsx +165 -0
  49. package/src/build-components/Checkbox/CheckboxProps.generated.ts +84 -0
  50. package/src/build-components/Checkbox/pattern.json +83 -0
  51. package/src/build-components/FormCheckbox/FormCheckbox.tsx +106 -0
  52. package/src/build-components/FormCheckbox/FormCheckboxProps.generated.ts +86 -0
  53. package/src/build-components/FormCheckbox/pattern.json +39 -0
  54. package/src/build-components/FormErrorText/FormErrorText.tsx +34 -0
  55. package/src/build-components/FormErrorText/FormErrorTextProps.generated.ts +78 -0
  56. package/src/build-components/FormErrorText/pattern.json +21 -0
  57. package/src/build-components/FormProvider/FormProvider.tsx +131 -0
  58. package/src/build-components/FormProvider/FormProviderProps.generated.ts +72 -0
  59. package/src/build-components/FormProvider/pattern.json +33 -0
  60. package/src/build-components/FormSubmitButton/FormSubmitButton.tsx +49 -0
  61. package/src/build-components/FormSubmitButton/FormSubmitButtonProps.generated.ts +91 -0
  62. package/src/build-components/FormSubmitButton/pattern.json +33 -0
  63. package/src/build-components/GlobalProvider/GlobalContext.ts +48 -0
  64. package/src/build-components/GlobalProvider/GlobalProvider.tsx +191 -0
  65. package/src/build-components/GlobalProvider/GlobalProviderProps.generated.ts +78 -0
  66. package/src/build-components/GlobalProvider/globalProviderUtils.ts +163 -0
  67. package/src/build-components/GlobalProvider/pattern.json +55 -0
  68. package/src/build-components/GlobalProvider/useGlobalNavigation.ts +70 -0
  69. package/src/build-components/OnboardButton/OnboardButton.tsx +41 -36
  70. package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +17 -10
  71. package/src/build-components/OnboardButton/pattern.json +5 -4
  72. package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +12 -0
  73. package/src/build-components/OnboardProvider/pattern.json +9 -1
  74. package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +12 -0
  75. package/src/build-components/PaywallProvider/pattern.json +9 -1
  76. package/src/build-components/RenderNode.generated.tsx +46 -1
  77. package/src/build-components/SystemButton/SystemButton.tsx +71 -0
  78. package/src/build-components/SystemButton/SystemButtonProps.generated.ts +89 -0
  79. package/src/build-components/SystemButton/pattern.json +61 -0
  80. package/src/build-components/SystemButton/usePlacementButtonEvents.ts +101 -0
  81. package/src/build-components/TermsProvider/TermsProvider.tsx +45 -0
  82. package/src/build-components/TermsProvider/TermsProviderProps.generated.ts +82 -0
  83. package/src/build-components/TermsProvider/pattern.json +35 -0
  84. package/src/build-components/WebView/WebView.tsx +149 -0
  85. package/src/build-components/WebView/WebViewProps.generated.ts +76 -0
  86. package/src/build-components/WebView/pattern.json +71 -0
  87. package/src/build-components/index.ts +45 -0
  88. package/src/build-components/patterns.generated.ts +5701 -1559
  89. package/src/index.web.ts +3 -0
  90. package/src/mockOS/components/MockOSRouter.tsx +21 -0
  91. package/src/mockOS/context/MockOSContext.tsx +7 -0
  92. package/src/mockOS/context/MockOSContextBase.ts +4 -0
  93. package/src/styles/components/_checkbox.scss +19 -0
  94. package/src/styles/components/_global-provider.scss +131 -0
  95. package/src/styles/components/_webview.scss +52 -0
  96. package/src/styles/index.scss +4 -0
  97. package/src/types/PreviewConfig.ts +19 -0
  98. package/src/utils/analyseNodeByPatterns.ts +5 -2
  99. package/src/utils/projectColors.ts +4 -0
  100. package/src/.DS_Store +0 -0
  101. package/src/assets/.DS_Store +0 -0
@@ -0,0 +1,86 @@
1
+ /* AUTO-GENERATED FILE - DO NOT EDIT */
2
+
3
+ import type { NodeData } from '../../types/Node';
4
+
5
+ export type FlexDirectionOptionType = 'row' | 'column';
6
+ export type FlexWrapOptionType = 'nowrap' | 'wrap' | 'wrap-reverse';
7
+ export type AlignItemsOptionType =
8
+ | 'flex-start'
9
+ | 'center'
10
+ | 'flex-end'
11
+ | 'stretch'
12
+ | 'baseline';
13
+ export type JustifyContentOptionType =
14
+ | 'flex-start'
15
+ | 'center'
16
+ | 'flex-end'
17
+ | 'space-between'
18
+ | 'space-around'
19
+ | 'space-evenly';
20
+ export type PositionOptionType = 'relative' | 'absolute';
21
+
22
+ export interface FormCheckboxStyleGenerated {
23
+ borderRadius?: string;
24
+ checkIconSize?: number;
25
+ checkIconStrokeWidth?: number;
26
+ color?: string;
27
+ fontSize?: string;
28
+ fontFamily?: string;
29
+ fontWeight?: string;
30
+ textAlign?: string;
31
+ flexDirection?: FlexDirectionOptionType;
32
+ flexWrap?: FlexWrapOptionType;
33
+ alignItems?: AlignItemsOptionType;
34
+ justifyContent?: JustifyContentOptionType;
35
+ gap?: string;
36
+ padding?: string;
37
+ paddingHorizontal?: string;
38
+ paddingVertical?: string;
39
+ paddingTop?: string;
40
+ paddingBottom?: string;
41
+ paddingLeft?: string;
42
+ paddingRight?: string;
43
+ margin?: string;
44
+ marginHorizontal?: string;
45
+ marginVertical?: string;
46
+ marginTop?: string;
47
+ marginBottom?: string;
48
+ marginLeft?: string;
49
+ marginRight?: string;
50
+ backgroundColor?: string;
51
+ width?: string;
52
+ minWidth?: string;
53
+ maxWidth?: string;
54
+ height?: string;
55
+ minHeight?: string;
56
+ maxHeight?: string;
57
+ flex?: number;
58
+ position?: PositionOptionType;
59
+ top?: string;
60
+ bottom?: string;
61
+ left?: string;
62
+ right?: string;
63
+ zIndex?: number;
64
+ }
65
+
66
+ export interface FormCheckboxPropsGenerated {
67
+ child: string;
68
+ attributes: {
69
+ styles?: FormCheckboxStyleGenerated;
70
+ checked?: boolean;
71
+ label?: string;
72
+ checkedColor?: string;
73
+ syncTermsAccepted?: boolean;
74
+ adjustsFontSizeToFit?: boolean;
75
+ numberOfLines?: number;
76
+ translateCounter?: number;
77
+ scrollable?: boolean;
78
+ testID?: string;
79
+ name?: string;
80
+ validation?: string[];
81
+ };
82
+ }
83
+
84
+ export interface FormCheckboxComponentProps {
85
+ node: NodeData<FormCheckboxPropsGenerated['attributes']>;
86
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "pattern": {
4
+ "type": "FormCheckbox",
5
+ "title": "FormCheckbox",
6
+ "description": "Checkbox bound to FormProvider; supports validation (required, min, max).",
7
+ "children": "never",
8
+ "extends": "Checkbox",
9
+ "attributes": {
10
+ "name": "string",
11
+ "validation": "string[]"
12
+ }
13
+ },
14
+ "defaults": {
15
+ "styles": {
16
+ "flexDirection": "row",
17
+ "alignItems": "center"
18
+ }
19
+ },
20
+ "meta": {
21
+ "desiredParent": [">FormProvider"],
22
+ "label": "Form Checkbox",
23
+ "description": "Checkbox registered with form context; use name for form field (e.g. termsAccepted).",
24
+ "attributes": {
25
+ "name": {
26
+ "label": "Field name",
27
+ "description": "Form field name for react-hook-form (e.g. termsAccepted).",
28
+ "category": "other",
29
+ "sort": 5
30
+ },
31
+ "validation": {
32
+ "label": "Validation",
33
+ "description": "Validation rules as key-value pairs: e.g. ['required'] or ['min', 2], ['max', 5]. Builder must send min/max with their value in the next array slot.",
34
+ "category": "other",
35
+ "sort": 6
36
+ }
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,34 @@
1
+ import React, { useContext, useMemo } from 'react';
2
+ import type { FormErrorTextComponentProps } from './FormErrorTextProps.generated';
3
+ import { formContext } from '../FormProvider/FormProvider';
4
+ import { Text } from '../Text/Text';
5
+ import useNode from '../useNode';
6
+ import { useLogRender } from '../../utils/useLogRender';
7
+ import { useLocalize } from '../../hooks/useLocalize';
8
+
9
+ /** Renders FormProvider globalError as Text when present; only valid inside FormProvider. */
10
+ export function FormErrorText({ node }: FormErrorTextComponentProps) {
11
+ useLogRender('FormErrorText');
12
+ node = useNode(node);
13
+ const ctx = useContext(formContext);
14
+ const localize = useLocalize();
15
+
16
+ const displayMessage = useMemo(
17
+ () => (ctx?.globalError ? localize(ctx.globalError) : ''),
18
+ [ctx?.globalError, localize],
19
+ );
20
+
21
+ if (!ctx?.globalError || !displayMessage) return null;
22
+
23
+ const textNode = {
24
+ ...node,
25
+ type: 'Text',
26
+ children: displayMessage,
27
+ } as Parameters<typeof Text>[0]['node'];
28
+
29
+ return (
30
+ <div role="alert" aria-live="polite">
31
+ <Text node={textNode} />
32
+ </div>
33
+ );
34
+ }
@@ -0,0 +1,78 @@
1
+ /* AUTO-GENERATED FILE - DO NOT EDIT */
2
+
3
+ import type { NodeData } from '../../types/Node';
4
+
5
+ export type FlexDirectionOptionType = 'row' | 'column';
6
+ export type FlexWrapOptionType = 'nowrap' | 'wrap' | 'wrap-reverse';
7
+ export type AlignItemsOptionType =
8
+ | 'flex-start'
9
+ | 'center'
10
+ | 'flex-end'
11
+ | 'stretch'
12
+ | 'baseline';
13
+ export type JustifyContentOptionType =
14
+ | 'flex-start'
15
+ | 'center'
16
+ | 'flex-end'
17
+ | 'space-between'
18
+ | 'space-around'
19
+ | 'space-evenly';
20
+ export type PositionOptionType = 'relative' | 'absolute';
21
+
22
+ export interface FormErrorTextStyleGenerated {
23
+ color?: string;
24
+ fontSize?: string;
25
+ fontFamily?: string;
26
+ fontWeight?: string;
27
+ textAlign?: string;
28
+ flexDirection?: FlexDirectionOptionType;
29
+ flexWrap?: FlexWrapOptionType;
30
+ alignItems?: AlignItemsOptionType;
31
+ justifyContent?: JustifyContentOptionType;
32
+ gap?: string;
33
+ padding?: string;
34
+ paddingHorizontal?: string;
35
+ paddingVertical?: string;
36
+ paddingTop?: string;
37
+ paddingBottom?: string;
38
+ paddingLeft?: string;
39
+ paddingRight?: string;
40
+ margin?: string;
41
+ marginHorizontal?: string;
42
+ marginVertical?: string;
43
+ marginTop?: string;
44
+ marginBottom?: string;
45
+ marginLeft?: string;
46
+ marginRight?: string;
47
+ backgroundColor?: string;
48
+ borderRadius?: string;
49
+ width?: string;
50
+ minWidth?: string;
51
+ maxWidth?: string;
52
+ height?: string;
53
+ minHeight?: string;
54
+ maxHeight?: string;
55
+ flex?: number;
56
+ position?: PositionOptionType;
57
+ top?: string;
58
+ bottom?: string;
59
+ left?: string;
60
+ right?: string;
61
+ zIndex?: number;
62
+ }
63
+
64
+ export interface FormErrorTextPropsGenerated {
65
+ child: string;
66
+ attributes: {
67
+ styles?: FormErrorTextStyleGenerated;
68
+ adjustsFontSizeToFit?: boolean;
69
+ numberOfLines?: number;
70
+ translateCounter?: number;
71
+ scrollable?: boolean;
72
+ testID?: string;
73
+ };
74
+ }
75
+
76
+ export interface FormErrorTextComponentProps {
77
+ node: NodeData<FormErrorTextPropsGenerated['attributes']>;
78
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "pattern": {
4
+ "type": "FormErrorText",
5
+ "title": "FormErrorText",
6
+ "description": "Displays FormProvider global submit/async error as text. Only valid as child of FormProvider.",
7
+ "children": "never",
8
+ "extends": "Text"
9
+ },
10
+ "defaults": {
11
+ "styles": {
12
+ "color": "THEME_COLORS.FORM_ERROR_TEXT_COLOR",
13
+ "fontSize": "14@fs"
14
+ }
15
+ },
16
+ "meta": {
17
+ "desiredParent": [">FormProvider"],
18
+ "label": "Form Error Text",
19
+ "description": "Shows form global error (e.g. submit failure). Place inside FormProvider where the error should appear."
20
+ }
21
+ }
@@ -0,0 +1,131 @@
1
+ import React, { createContext, useCallback, useMemo, useState } from 'react';
2
+ import { FormProvider as RHFFormProvider, useForm } from 'react-hook-form';
3
+ import type { UseFormReturn } from 'react-hook-form';
4
+ import type { FormProviderComponentProps } from './FormProviderProps.generated';
5
+ import RenderNode from '../RenderNode.generated';
6
+ import useNode from '../useNode';
7
+ import { useLogRender } from '../../utils/useLogRender';
8
+ import { useExtractViewStyle } from '../../attribute-analyser/style/web/useExtractViewStyle';
9
+
10
+ export type FormContextValue = {
11
+ handleSubmit: (
12
+ callback: (data: Record<string, unknown>) => void | Promise<unknown>,
13
+ ) => (e?: React.BaseSyntheticEvent) => void;
14
+ isValid: boolean;
15
+ globalError: string | null;
16
+ control: UseFormReturn<Record<string, unknown>>['control'];
17
+ };
18
+
19
+ export const formContext = createContext<FormContextValue | null>(null);
20
+
21
+ function parseDefaultValues(raw: string | undefined): Record<string, unknown> {
22
+ if (raw == null || typeof raw !== 'string' || raw.trim() === '') {
23
+ return {};
24
+ }
25
+ try {
26
+ const parsed = JSON.parse(raw) as unknown;
27
+ return typeof parsed === 'object' &&
28
+ parsed !== null &&
29
+ !Array.isArray(parsed)
30
+ ? (parsed as Record<string, unknown>)
31
+ : {};
32
+ } catch (err) {
33
+ console.warn(
34
+ '[FormProvider] parseDefaultValues: invalid defaultValues JSON',
35
+ raw,
36
+ err,
37
+ );
38
+ return {};
39
+ }
40
+ }
41
+
42
+ function FormProviderInner({ node }: FormProviderComponentProps) {
43
+ useLogRender('FormProvider');
44
+ node = useNode(node);
45
+ const attrs = node.attributes;
46
+ const defaultValues = useMemo(
47
+ () => parseDefaultValues(attrs?.defaultValues as string | undefined),
48
+ [attrs?.defaultValues],
49
+ );
50
+
51
+ const form = useForm<Record<string, unknown>>({
52
+ defaultValues,
53
+ mode: 'onChange',
54
+ });
55
+
56
+ const [globalError, setGlobalError] = useState<string | null>(null);
57
+
58
+ const validationErrorKey =
59
+ (attrs?.validationErrorMessageKey as string | undefined) ??
60
+ 'form.error.validation_required';
61
+
62
+ const handleSubmit = useCallback(
63
+ (callback: (data: Record<string, unknown>) => void | Promise<unknown>) => {
64
+ const onValid = (data: Record<string, unknown>) => {
65
+ setGlobalError(null);
66
+ try {
67
+ const result = callback(data);
68
+ const promise =
69
+ result !== undefined &&
70
+ result !== null &&
71
+ typeof (result as Promise<unknown>).then === 'function'
72
+ ? (result as Promise<unknown>)
73
+ : null;
74
+ if (promise) {
75
+ promise.catch((e: unknown) => {
76
+ setGlobalError(e instanceof Error ? e.message : String(e));
77
+ throw e;
78
+ });
79
+ }
80
+ } catch (e) {
81
+ setGlobalError(e instanceof Error ? e.message : String(e));
82
+ throw e;
83
+ }
84
+ };
85
+ const onInvalid = () => {
86
+ setGlobalError(validationErrorKey);
87
+ };
88
+ return form.handleSubmit(onValid, onInvalid);
89
+ },
90
+ [form, validationErrorKey],
91
+ );
92
+
93
+ const contextValue = useMemo<FormContextValue>(
94
+ () => ({
95
+ handleSubmit,
96
+ isValid: form.formState.isValid,
97
+ globalError,
98
+ control: form.control,
99
+ }),
100
+ [handleSubmit, form.formState.isValid, form.control, globalError],
101
+ );
102
+
103
+ const viewStyle = useExtractViewStyle(node);
104
+
105
+ const onSubmit = (e: React.FormEvent) => {
106
+ e.preventDefault();
107
+ };
108
+
109
+ return (
110
+ <formContext.Provider value={contextValue}>
111
+ <RHFFormProvider {...form}>
112
+ <form
113
+ onSubmit={onSubmit}
114
+ style={viewStyle}
115
+ attribute-name={node.sourceType ?? node.type ?? 'FormProvider'}
116
+ attribute-key={node.key}
117
+ >
118
+ {node.children ? (
119
+ <RenderNode
120
+ node={node.children as Parameters<typeof RenderNode>[0]['node']}
121
+ />
122
+ ) : null}
123
+ </form>
124
+ </RHFFormProvider>
125
+ </formContext.Provider>
126
+ );
127
+ }
128
+
129
+ export function FormProvider(props: FormProviderComponentProps) {
130
+ return <FormProviderInner node={props.node} />;
131
+ }
@@ -0,0 +1,72 @@
1
+ /* AUTO-GENERATED FILE - DO NOT EDIT */
2
+
3
+ import type { NodeData } from '../../types/Node';
4
+
5
+ export type FlexDirectionOptionType = 'row' | 'column';
6
+ export type FlexWrapOptionType = 'nowrap' | 'wrap' | 'wrap-reverse';
7
+ export type AlignItemsOptionType =
8
+ | 'flex-start'
9
+ | 'center'
10
+ | 'flex-end'
11
+ | 'stretch'
12
+ | 'baseline';
13
+ export type JustifyContentOptionType =
14
+ | 'flex-start'
15
+ | 'center'
16
+ | 'flex-end'
17
+ | 'space-between'
18
+ | 'space-around'
19
+ | 'space-evenly';
20
+ export type PositionOptionType = 'relative' | 'absolute';
21
+
22
+ export interface FormProviderStyleGenerated {
23
+ flexDirection?: FlexDirectionOptionType;
24
+ flexWrap?: FlexWrapOptionType;
25
+ alignItems?: AlignItemsOptionType;
26
+ justifyContent?: JustifyContentOptionType;
27
+ gap?: string;
28
+ padding?: string;
29
+ paddingHorizontal?: string;
30
+ paddingVertical?: string;
31
+ paddingTop?: string;
32
+ paddingBottom?: string;
33
+ paddingLeft?: string;
34
+ paddingRight?: string;
35
+ margin?: string;
36
+ marginHorizontal?: string;
37
+ marginVertical?: string;
38
+ marginTop?: string;
39
+ marginBottom?: string;
40
+ marginLeft?: string;
41
+ marginRight?: string;
42
+ backgroundColor?: string;
43
+ borderRadius?: string;
44
+ width?: string;
45
+ minWidth?: string;
46
+ maxWidth?: string;
47
+ height?: string;
48
+ minHeight?: string;
49
+ maxHeight?: string;
50
+ flex?: number;
51
+ position?: PositionOptionType;
52
+ top?: string;
53
+ bottom?: string;
54
+ left?: string;
55
+ right?: string;
56
+ zIndex?: number;
57
+ }
58
+
59
+ export interface FormProviderPropsGenerated {
60
+ child: string;
61
+ attributes: {
62
+ styles?: FormProviderStyleGenerated;
63
+ scrollable?: boolean;
64
+ testID?: string;
65
+ defaultValues?: string;
66
+ validationErrorMessageKey?: string;
67
+ };
68
+ }
69
+
70
+ export interface FormProviderComponentProps {
71
+ node: NodeData<FormProviderPropsGenerated['attributes']>;
72
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "pattern": {
4
+ "type": "FormProvider",
5
+ "title": "FormProvider",
6
+ "description": "Form context provider using react-hook-form. Children (FormCheckbox, FormSubmitButton) use this context for validation and submit.",
7
+ "children": "node",
8
+ "extends": "View",
9
+ "attributes": {
10
+ "defaultValues": "string",
11
+ "validationErrorMessageKey": "string"
12
+ }
13
+ },
14
+ "meta": {
15
+ "desiredParent": ["root", "all"],
16
+ "label": "Form Provider",
17
+ "description": "Wraps form fields and submit button; provides validation state and handleSubmit.",
18
+ "attributes": {
19
+ "defaultValues": {
20
+ "label": "Default values",
21
+ "description": "Optional JSON string of field names to initial values (e.g. {\"termsAccepted\": false}).",
22
+ "category": "other",
23
+ "sort": 1
24
+ },
25
+ "validationErrorMessageKey": {
26
+ "label": "Validation error message key",
27
+ "description": "Localization key shown when submit is attempted with invalid form (e.g. view.terms.error.must_accept).",
28
+ "category": "other",
29
+ "sort": 2
30
+ }
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,49 @@
1
+ import React, { useContext } from 'react';
2
+ import type { FormSubmitButtonComponentProps } from './FormSubmitButtonProps.generated';
3
+ import { formContext } from '../FormProvider/FormProvider';
4
+ import { SystemButton } from '../SystemButton/SystemButton';
5
+ import useNode from '../useNode';
6
+ import { useLogRender } from '../../utils/useLogRender';
7
+ import { useMockOSContext, useMockPermission } from '../../mockOS';
8
+ import { usePlacementButtonEvents } from '../SystemButton/usePlacementButtonEvents';
9
+ import { useGlobalNavigation } from '../GlobalProvider/useGlobalNavigation';
10
+
11
+ export function FormSubmitButton({ node }: FormSubmitButtonComponentProps) {
12
+ useLogRender('FormSubmitButton');
13
+ node = useNode(node);
14
+ const ctx = useContext(formContext);
15
+ const context = useMockOSContext();
16
+ const mockPermissionManager = useMockPermission(context);
17
+ const globalNavigate = useGlobalNavigation();
18
+ const attrs = node.attributes;
19
+
20
+ const runPlacementEvents = usePlacementButtonEvents(attrs?.events, {
21
+ context,
22
+ requestPermission: (permission) =>
23
+ mockPermissionManager.requestPermission(permission),
24
+ globalNavigate,
25
+ });
26
+
27
+ const validationRequired =
28
+ (attrs as { validationRequired?: boolean })?.validationRequired === true;
29
+ const disableIfUnvalidated =
30
+ (attrs as { disableIfUnvalidated?: boolean })?.disableIfUnvalidated ===
31
+ true;
32
+ const disabled =
33
+ validationRequired && disableIfUnvalidated && ctx !== null && !ctx.isValid;
34
+
35
+ const handleClick =
36
+ ctx !== null
37
+ ? ctx.handleSubmit(() => {
38
+ runPlacementEvents();
39
+ })
40
+ : runPlacementEvents;
41
+
42
+ return (
43
+ <SystemButton
44
+ node={node as Parameters<typeof SystemButton>[0]['node']}
45
+ onClick={ctx !== null ? handleClick : undefined}
46
+ disabled={ctx !== null ? disabled : false}
47
+ />
48
+ );
49
+ }
@@ -0,0 +1,91 @@
1
+ /* AUTO-GENERATED FILE - DO NOT EDIT */
2
+
3
+ import type { NodeData } from '../../types/Node';
4
+
5
+ export type TypeOptionType = 'Permission' | 'Navigate' | 'Placement';
6
+ export type FlexDirectionOptionType = 'row' | 'column';
7
+ export type FlexWrapOptionType = 'nowrap' | 'wrap' | 'wrap-reverse';
8
+ export type AlignItemsOptionType =
9
+ | 'flex-start'
10
+ | 'center'
11
+ | 'flex-end'
12
+ | 'stretch'
13
+ | 'baseline';
14
+ export type JustifyContentOptionType =
15
+ | 'flex-start'
16
+ | 'center'
17
+ | 'flex-end'
18
+ | 'space-between'
19
+ | 'space-around'
20
+ | 'space-evenly';
21
+ export type PositionOptionType = 'relative' | 'absolute';
22
+
23
+ export interface EventObjectGenerated {
24
+ type?: TypeOptionType;
25
+ permission?: string;
26
+ navigate_to?: string;
27
+ targetIndex?: number;
28
+ placementKey?: string;
29
+ }
30
+
31
+ export interface FormSubmitButtonStyleGenerated {
32
+ color?: string;
33
+ backgroundColor?: string;
34
+ height?: string;
35
+ borderRadius?: string;
36
+ fontSize?: string;
37
+ fontWeight?: string;
38
+ fontFamily?: string;
39
+ textAlign?: string;
40
+ flexDirection?: FlexDirectionOptionType;
41
+ flexWrap?: FlexWrapOptionType;
42
+ alignItems?: AlignItemsOptionType;
43
+ justifyContent?: JustifyContentOptionType;
44
+ gap?: string;
45
+ padding?: string;
46
+ paddingHorizontal?: string;
47
+ paddingVertical?: string;
48
+ paddingTop?: string;
49
+ paddingBottom?: string;
50
+ paddingLeft?: string;
51
+ paddingRight?: string;
52
+ margin?: string;
53
+ marginHorizontal?: string;
54
+ marginVertical?: string;
55
+ marginTop?: string;
56
+ marginBottom?: string;
57
+ marginLeft?: string;
58
+ marginRight?: string;
59
+ width?: string;
60
+ minWidth?: string;
61
+ maxWidth?: string;
62
+ minHeight?: string;
63
+ maxHeight?: string;
64
+ flex?: number;
65
+ position?: PositionOptionType;
66
+ top?: string;
67
+ bottom?: string;
68
+ left?: string;
69
+ right?: string;
70
+ zIndex?: number;
71
+ }
72
+
73
+ export interface FormSubmitButtonPropsGenerated {
74
+ child: string;
75
+ attributes: {
76
+ styles?: FormSubmitButtonStyleGenerated;
77
+ labelKey?: string;
78
+ events?: EventObjectGenerated[];
79
+ testID?: string;
80
+ adjustsFontSizeToFit?: boolean;
81
+ numberOfLines?: number;
82
+ translateCounter?: number;
83
+ scrollable?: boolean;
84
+ disableIfUnvalidated?: boolean;
85
+ validationRequired?: boolean;
86
+ };
87
+ }
88
+
89
+ export interface FormSubmitButtonComponentProps {
90
+ node: NodeData<FormSubmitButtonPropsGenerated['attributes']>;
91
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "pattern": {
4
+ "type": "FormSubmitButton",
5
+ "title": "FormSubmitButton",
6
+ "description": "Submit button bound to FormProvider; can disable when form is invalid.",
7
+ "children": "never",
8
+ "extends": "SystemButton",
9
+ "attributes": {
10
+ "disableIfUnvalidated": "boolean",
11
+ "validationRequired": "boolean"
12
+ }
13
+ },
14
+ "meta": {
15
+ "desiredParent": [">FormProvider"],
16
+ "label": "Form Submit Button",
17
+ "description": "Submit button that runs form validation; when validationRequired and disableIfUnvalidated, disabled until form is valid.",
18
+ "attributes": {
19
+ "disableIfUnvalidated": {
20
+ "label": "Disable if unvalidated",
21
+ "description": "When true (and validationRequired is true), button is disabled until form is valid.",
22
+ "category": "other",
23
+ "sort": 4
24
+ },
25
+ "validationRequired": {
26
+ "label": "Validation required",
27
+ "description": "When true, button uses form validation state (e.g. for disableIfUnvalidated).",
28
+ "category": "other",
29
+ "sort": 5
30
+ }
31
+ }
32
+ }
33
+ }