@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.
- package/dist/components/forms/Captcha.d.ts +33 -28
- package/dist/components/forms/Captcha.d.ts.map +1 -1
- package/dist/components/forms/FormCheckbox.d.ts +15 -12
- package/dist/components/forms/FormCheckbox.d.ts.map +1 -1
- package/dist/components/forms/FormField.d.ts +20 -23
- package/dist/components/forms/FormField.d.ts.map +1 -1
- package/dist/components/forms/FormSelect.d.ts +16 -15
- package/dist/components/forms/FormSelect.d.ts.map +1 -1
- package/dist/hooks/useBaseProps.d.ts +27 -1172
- package/dist/hooks/useBaseProps.d.ts.map +1 -1
- package/dist/index.esm.js +349 -156
- package/dist/index.js +348 -155
- package/dist/palettes/manifest.json +19 -19
- package/dist/schemas/CaptchaSchema.d.ts +16 -0
- package/dist/schemas/CaptchaSchema.d.ts.map +1 -0
- package/dist/schemas/FormCheckboxSchema.d.ts +16 -0
- package/dist/schemas/FormCheckboxSchema.d.ts.map +1 -0
- package/dist/schemas/FormFieldSchema.d.ts +23 -0
- package/dist/schemas/FormFieldSchema.d.ts.map +1 -0
- package/dist/schemas/FormSelectSchema.d.ts +20 -0
- package/dist/schemas/FormSelectSchema.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +4 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/forms/Captcha.tsx +57 -63
- package/src/components/forms/FormCheckbox.tsx +35 -43
- package/src/components/forms/FormField.tsx +50 -66
- package/src/components/forms/FormSelect.tsx +41 -49
- package/src/hooks/useBaseProps.ts +34 -1
- package/src/schemas/CaptchaSchema.ts +65 -0
- package/src/schemas/FormCheckboxSchema.ts +65 -0
- package/src/schemas/FormFieldSchema.ts +140 -0
- package/src/schemas/FormSelectSchema.ts +108 -0
- package/src/schemas/index.ts +4 -0
- /package/dist/palettes/{palette-autumn.1.5.13.css → palette-autumn.1.6.0.css} +0 -0
- /package/dist/palettes/{palette-autumn.1.5.13.min.css → palette-autumn.1.6.0.min.css} +0 -0
- /package/dist/palettes/{palette-cosmic.1.5.13.css → palette-cosmic.1.6.0.css} +0 -0
- /package/dist/palettes/{palette-cosmic.1.5.13.min.css → palette-cosmic.1.6.0.min.css} +0 -0
- /package/dist/palettes/{palette-default.1.5.13.css → palette-default.1.6.0.css} +0 -0
- /package/dist/palettes/{palette-default.1.5.13.min.css → palette-default.1.6.0.min.css} +0 -0
- /package/dist/palettes/{palette-ocean.1.5.13.css → palette-ocean.1.6.0.css} +0 -0
- /package/dist/palettes/{palette-ocean.1.5.13.min.css → palette-ocean.1.6.0.min.css} +0 -0
- /package/dist/palettes/{palette-spring.1.5.13.css → palette-spring.1.6.0.css} +0 -0
- /package/dist/palettes/{palette-spring.1.5.13.min.css → palette-spring.1.6.0.min.css} +0 -0
- /package/dist/palettes/{palette-winter.1.5.13.css → palette-winter.1.6.0.css} +0 -0
- /package/dist/palettes/{palette-winter.1.5.13.min.css → palette-winter.1.6.0.min.css} +0 -0
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* Features:
|
|
5
5
|
* - Uses QwickApps CSS theme variables for consistent styling
|
|
6
6
|
* - Supports text, number, password, and email input types
|
|
7
|
-
* - Integrated with MUI FormControl, Input
|
|
7
|
+
* - Integrated with MUI FormControl, Input
|
|
8
8
|
* - Handles readonly, disabled, and required states
|
|
9
9
|
* - Support for adornments and helper text
|
|
10
|
-
* -
|
|
10
|
+
* - Schema-driven architecture with serialization support
|
|
11
11
|
*
|
|
12
12
|
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
13
13
|
*/
|
|
@@ -20,63 +20,54 @@ import {
|
|
|
20
20
|
FormHelperText,
|
|
21
21
|
InputAdornment,
|
|
22
22
|
} from '@mui/material';
|
|
23
|
-
import {
|
|
23
|
+
import type { SchemaProps } from '@qwickapps/schema';
|
|
24
|
+
import FormFieldModel from '../../schemas/FormFieldSchema';
|
|
25
|
+
import { ViewProps } from '../shared/viewProps';
|
|
26
|
+
import { createSerializableView, SerializableComponent } from '../shared/createSerializableView';
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
label: string;
|
|
32
|
-
value: string | number;
|
|
28
|
+
/**
|
|
29
|
+
* Props interface for FormField component
|
|
30
|
+
* Combines schema props with callback handlers and adornments
|
|
31
|
+
*/
|
|
32
|
+
export interface FormFieldProps extends ViewProps, SchemaProps<typeof FormFieldModel> {
|
|
33
|
+
/** Callback when value changes */
|
|
33
34
|
onChange?: (value: string | number) => void;
|
|
35
|
+
/** Raw change handler with event */
|
|
34
36
|
onChangeRaw?: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
35
|
-
|
|
36
|
-
helperText?: string;
|
|
37
|
-
required?: boolean;
|
|
38
|
-
readOnly?: boolean;
|
|
39
|
-
disabled?: boolean;
|
|
40
|
-
disabledColor?: string;
|
|
41
|
-
fullWidth?: boolean;
|
|
42
|
-
multiline?: boolean;
|
|
43
|
-
rows?: number;
|
|
44
|
-
placeholder?: string;
|
|
37
|
+
/** Start adornment (icon, text, etc.) */
|
|
45
38
|
startAdornment?: React.ReactNode;
|
|
39
|
+
/** End adornment (icon, text, etc.) */
|
|
46
40
|
endAdornment?: React.ReactNode;
|
|
41
|
+
/** Additional input props */
|
|
47
42
|
inputProps?: unknown;
|
|
48
43
|
}
|
|
49
44
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} = restProps as FormFieldBaseProps;
|
|
74
|
-
|
|
75
|
-
// Generate a unique ID for the input field
|
|
45
|
+
/**
|
|
46
|
+
* FormFieldView - Pure view component that renders the input field
|
|
47
|
+
*/
|
|
48
|
+
function FormFieldView({
|
|
49
|
+
label,
|
|
50
|
+
value,
|
|
51
|
+
onChange,
|
|
52
|
+
onChangeRaw,
|
|
53
|
+
type = 'text',
|
|
54
|
+
helperText,
|
|
55
|
+
required = false,
|
|
56
|
+
readOnly = false,
|
|
57
|
+
disabled = false,
|
|
58
|
+
disabledColor,
|
|
59
|
+
fullWidth = true,
|
|
60
|
+
multiline = false,
|
|
61
|
+
rows,
|
|
62
|
+
placeholder,
|
|
63
|
+
startAdornment,
|
|
64
|
+
endAdornment,
|
|
65
|
+
inputProps,
|
|
66
|
+
...restProps
|
|
67
|
+
}: FormFieldProps) {
|
|
76
68
|
const fieldId = React.useId();
|
|
77
69
|
|
|
78
70
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
79
|
-
// If onChangeRaw is provided, use it instead
|
|
80
71
|
if (onChangeRaw) {
|
|
81
72
|
onChangeRaw(e);
|
|
82
73
|
return;
|
|
@@ -107,7 +98,6 @@ export const FormField = React.forwardRef<HTMLDivElement, FormFieldProps>((props
|
|
|
107
98
|
color: disabledColor,
|
|
108
99
|
WebkitTextFillColor: disabledColor,
|
|
109
100
|
} : undefined,
|
|
110
|
-
...styleProps.sx,
|
|
111
101
|
};
|
|
112
102
|
|
|
113
103
|
const labelStyles = {
|
|
@@ -122,19 +112,8 @@ export const FormField = React.forwardRef<HTMLDivElement, FormFieldProps>((props
|
|
|
122
112
|
|
|
123
113
|
return (
|
|
124
114
|
<FormControl
|
|
125
|
-
ref={ref}
|
|
126
115
|
fullWidth={fullWidth}
|
|
127
|
-
{...
|
|
128
|
-
{...styleProps}
|
|
129
|
-
// Store grid props as data attributes for ColumnLayout to pick up
|
|
130
|
-
{...(gridProps && {
|
|
131
|
-
'data-grid-span': gridProps.span,
|
|
132
|
-
'data-grid-xs': gridProps.xs,
|
|
133
|
-
'data-grid-sm': gridProps.sm,
|
|
134
|
-
'data-grid-md': gridProps.md,
|
|
135
|
-
'data-grid-lg': gridProps.lg,
|
|
136
|
-
'data-grid-xl': gridProps.xl,
|
|
137
|
-
})}
|
|
116
|
+
{...restProps}
|
|
138
117
|
>
|
|
139
118
|
<InputLabel htmlFor={fieldId} sx={labelStyles} shrink>
|
|
140
119
|
{label}
|
|
@@ -170,11 +149,16 @@ export const FormField = React.forwardRef<HTMLDivElement, FormFieldProps>((props
|
|
|
170
149
|
)}
|
|
171
150
|
</FormControl>
|
|
172
151
|
);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
FormField.displayName = 'FormField';
|
|
152
|
+
}
|
|
176
153
|
|
|
177
|
-
|
|
178
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Create FormField component using the factory pattern
|
|
156
|
+
*/
|
|
157
|
+
export const FormField: SerializableComponent<FormFieldProps> = createSerializableView<FormFieldProps>({
|
|
158
|
+
tagName: 'FormField',
|
|
159
|
+
version: '1.0.0',
|
|
160
|
+
role: 'input',
|
|
161
|
+
View: FormFieldView,
|
|
162
|
+
});
|
|
179
163
|
|
|
180
164
|
export default FormField;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - Simplified select-only interface (use FormField for mixed inputs)
|
|
7
7
|
* - Support for placeholder, size variants, and helper text
|
|
8
8
|
* - Integrated with MUI FormControl and Select
|
|
9
|
-
* -
|
|
9
|
+
* - Schema-driven architecture with serialization support
|
|
10
10
|
*
|
|
11
11
|
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
12
12
|
*/
|
|
@@ -19,46 +19,45 @@ import {
|
|
|
19
19
|
MenuItem,
|
|
20
20
|
FormHelperText,
|
|
21
21
|
} from '@mui/material';
|
|
22
|
-
import {
|
|
22
|
+
import type { SchemaProps } from '@qwickapps/schema';
|
|
23
|
+
import FormSelectModel from '../../schemas/FormSelectSchema';
|
|
24
|
+
import { ViewProps } from '../shared/viewProps';
|
|
25
|
+
import { createSerializableView, SerializableComponent } from '../shared/createSerializableView';
|
|
23
26
|
|
|
24
27
|
export interface FormSelectOption {
|
|
25
28
|
value: string | number;
|
|
26
29
|
label: string;
|
|
27
30
|
}
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Props interface for FormSelect component
|
|
34
|
+
* Combines schema props with callback handlers
|
|
35
|
+
*/
|
|
36
|
+
export interface FormSelectProps extends ViewProps, SchemaProps<typeof FormSelectModel> {
|
|
37
|
+
/** Callback when value changes */
|
|
32
38
|
onChange: (value: string | number) => void;
|
|
39
|
+
/** Options array (runtime prop, overrides schema) */
|
|
33
40
|
options: FormSelectOption[];
|
|
34
|
-
helperText?: string;
|
|
35
|
-
required?: boolean;
|
|
36
|
-
disabled?: boolean;
|
|
37
|
-
fullWidth?: boolean;
|
|
38
|
-
size?: 'small' | 'medium';
|
|
39
|
-
placeholder?: string;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const handleChange = (e: unknown) => {
|
|
61
|
-
onChange(e.target.value);
|
|
43
|
+
/**
|
|
44
|
+
* FormSelectView - Pure view component that renders the select field
|
|
45
|
+
*/
|
|
46
|
+
function FormSelectView({
|
|
47
|
+
label,
|
|
48
|
+
value,
|
|
49
|
+
onChange,
|
|
50
|
+
options,
|
|
51
|
+
helperText,
|
|
52
|
+
required = false,
|
|
53
|
+
disabled = false,
|
|
54
|
+
fullWidth = true,
|
|
55
|
+
size = 'small',
|
|
56
|
+
placeholder,
|
|
57
|
+
...restProps
|
|
58
|
+
}: FormSelectProps) {
|
|
59
|
+
const handleChange = (e: { target: { value: unknown } }) => {
|
|
60
|
+
onChange(e.target.value as string | number);
|
|
62
61
|
};
|
|
63
62
|
|
|
64
63
|
const selectStyles = {
|
|
@@ -69,7 +68,6 @@ export const FormSelect = React.forwardRef<HTMLDivElement, FormSelectProps>((pro
|
|
|
69
68
|
borderColor: 'var(--theme-surface)',
|
|
70
69
|
color: 'var(--theme-text-primary)',
|
|
71
70
|
borderRadius: 1,
|
|
72
|
-
...styleProps.sx,
|
|
73
71
|
};
|
|
74
72
|
|
|
75
73
|
const labelStyles = {
|
|
@@ -84,20 +82,9 @@ export const FormSelect = React.forwardRef<HTMLDivElement, FormSelectProps>((pro
|
|
|
84
82
|
|
|
85
83
|
return (
|
|
86
84
|
<FormControl
|
|
87
|
-
ref={ref}
|
|
88
85
|
fullWidth={fullWidth}
|
|
89
86
|
size={size}
|
|
90
|
-
{...
|
|
91
|
-
{...styleProps}
|
|
92
|
-
// Store grid props as data attributes for ColumnLayout to pick up
|
|
93
|
-
{...(gridProps && {
|
|
94
|
-
'data-grid-span': gridProps.span,
|
|
95
|
-
'data-grid-xs': gridProps.xs,
|
|
96
|
-
'data-grid-sm': gridProps.sm,
|
|
97
|
-
'data-grid-md': gridProps.md,
|
|
98
|
-
'data-grid-lg': gridProps.lg,
|
|
99
|
-
'data-grid-xl': gridProps.xl,
|
|
100
|
-
})}
|
|
87
|
+
{...restProps}
|
|
101
88
|
>
|
|
102
89
|
{label && (
|
|
103
90
|
<InputLabel sx={labelStyles} shrink>
|
|
@@ -130,11 +117,16 @@ export const FormSelect = React.forwardRef<HTMLDivElement, FormSelectProps>((pro
|
|
|
130
117
|
)}
|
|
131
118
|
</FormControl>
|
|
132
119
|
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
FormSelect.displayName = 'FormSelect';
|
|
120
|
+
}
|
|
136
121
|
|
|
137
|
-
|
|
138
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Create FormSelect component using the factory pattern
|
|
124
|
+
*/
|
|
125
|
+
export const FormSelect: SerializableComponent<FormSelectProps> = createSerializableView<FormSelectProps>({
|
|
126
|
+
tagName: 'FormSelect',
|
|
127
|
+
version: '1.0.0',
|
|
128
|
+
role: 'input',
|
|
129
|
+
View: FormSelectView,
|
|
130
|
+
});
|
|
139
131
|
|
|
140
132
|
export default FormSelect;
|
|
@@ -82,10 +82,43 @@ export interface BaseComponentProps {
|
|
|
82
82
|
*/
|
|
83
83
|
export const QWICKAPP_COMPONENT = Symbol('QwickAppComponent');
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Return type for useBaseProps hook
|
|
87
|
+
*/
|
|
88
|
+
export interface BasePropsResult<T extends BaseComponentProps> {
|
|
89
|
+
gridProps: {
|
|
90
|
+
span?: number | 'auto' | 'grow';
|
|
91
|
+
xs?: number | 'auto';
|
|
92
|
+
sm?: number | 'auto';
|
|
93
|
+
md?: number | 'auto';
|
|
94
|
+
lg?: number | 'auto';
|
|
95
|
+
xl?: number | 'auto';
|
|
96
|
+
} | null;
|
|
97
|
+
styleProps: {
|
|
98
|
+
className?: string;
|
|
99
|
+
sx?: SxProps<Theme>;
|
|
100
|
+
style?: React.CSSProperties;
|
|
101
|
+
};
|
|
102
|
+
htmlProps: {
|
|
103
|
+
id?: string;
|
|
104
|
+
role?: string;
|
|
105
|
+
'aria-label'?: string;
|
|
106
|
+
'aria-labelledby'?: string;
|
|
107
|
+
'aria-describedby'?: string;
|
|
108
|
+
'data-testid'?: string;
|
|
109
|
+
onClick?: React.MouseEventHandler<unknown>;
|
|
110
|
+
onMouseEnter?: React.MouseEventHandler<unknown>;
|
|
111
|
+
onMouseLeave?: React.MouseEventHandler<unknown>;
|
|
112
|
+
onFocus?: React.FocusEventHandler<unknown>;
|
|
113
|
+
onBlur?: React.FocusEventHandler<unknown>;
|
|
114
|
+
};
|
|
115
|
+
restProps: Omit<T, keyof BaseComponentProps>;
|
|
116
|
+
}
|
|
117
|
+
|
|
85
118
|
/**
|
|
86
119
|
* Hook to process base component props
|
|
87
120
|
*/
|
|
88
|
-
export function useBaseProps<T extends BaseComponentProps>(props: T) {
|
|
121
|
+
export function useBaseProps<T extends BaseComponentProps>(props: T): BasePropsResult<T> {
|
|
89
122
|
const {
|
|
90
123
|
// Grid props
|
|
91
124
|
span,
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema for Captcha component - Universal CAPTCHA widget
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { IsIn, IsOptional, IsString } from 'class-validator';
|
|
8
|
+
import 'reflect-metadata';
|
|
9
|
+
import { Editor, Field, Schema, FieldType } from '@qwickapps/schema';
|
|
10
|
+
import ViewSchema from './ViewSchema';
|
|
11
|
+
|
|
12
|
+
@Schema('Captcha', '1.0.0')
|
|
13
|
+
export class CaptchaModel extends ViewSchema {
|
|
14
|
+
@Field()
|
|
15
|
+
@Editor({
|
|
16
|
+
field_type: FieldType.SELECT,
|
|
17
|
+
label: 'CAPTCHA Provider',
|
|
18
|
+
description: 'Which CAPTCHA service to use'
|
|
19
|
+
})
|
|
20
|
+
@IsIn(['recaptcha-v2', 'recaptcha-v3', 'hcaptcha', 'turnstile'])
|
|
21
|
+
provider!: 'recaptcha-v2' | 'recaptcha-v3' | 'hcaptcha' | 'turnstile';
|
|
22
|
+
|
|
23
|
+
@Field()
|
|
24
|
+
@Editor({
|
|
25
|
+
field_type: FieldType.TEXT,
|
|
26
|
+
label: 'Site Key',
|
|
27
|
+
description: 'Public site key from CAPTCHA provider',
|
|
28
|
+
placeholder: 'Enter site key...'
|
|
29
|
+
})
|
|
30
|
+
@IsString()
|
|
31
|
+
siteKey!: string;
|
|
32
|
+
|
|
33
|
+
@Field({ defaultValue: 'light' })
|
|
34
|
+
@Editor({
|
|
35
|
+
field_type: FieldType.SELECT,
|
|
36
|
+
label: 'Theme',
|
|
37
|
+
description: 'CAPTCHA widget theme'
|
|
38
|
+
})
|
|
39
|
+
@IsOptional()
|
|
40
|
+
@IsIn(['light', 'dark'])
|
|
41
|
+
theme?: 'light' | 'dark';
|
|
42
|
+
|
|
43
|
+
@Field({ defaultValue: 'normal' })
|
|
44
|
+
@Editor({
|
|
45
|
+
field_type: FieldType.SELECT,
|
|
46
|
+
label: 'Size',
|
|
47
|
+
description: 'CAPTCHA widget size'
|
|
48
|
+
})
|
|
49
|
+
@IsOptional()
|
|
50
|
+
@IsIn(['normal', 'compact', 'invisible'])
|
|
51
|
+
size?: 'normal' | 'compact' | 'invisible';
|
|
52
|
+
|
|
53
|
+
@Field({ defaultValue: 'submit' })
|
|
54
|
+
@Editor({
|
|
55
|
+
field_type: FieldType.TEXT,
|
|
56
|
+
label: 'Action',
|
|
57
|
+
description: 'reCAPTCHA v3 action name',
|
|
58
|
+
placeholder: 'submit'
|
|
59
|
+
})
|
|
60
|
+
@IsOptional()
|
|
61
|
+
@IsString()
|
|
62
|
+
action?: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default CaptchaModel;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema for FormCheckbox component - Themed checkbox input
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { IsBoolean, IsOptional, IsString } from 'class-validator';
|
|
8
|
+
import 'reflect-metadata';
|
|
9
|
+
import { Editor, Field, Schema, FieldType } from '@qwickapps/schema';
|
|
10
|
+
import ViewSchema from './ViewSchema';
|
|
11
|
+
|
|
12
|
+
@Schema('FormCheckbox', '1.0.0')
|
|
13
|
+
export class FormCheckboxModel extends ViewSchema {
|
|
14
|
+
@Field()
|
|
15
|
+
@Editor({
|
|
16
|
+
field_type: FieldType.TEXT,
|
|
17
|
+
label: 'Label',
|
|
18
|
+
description: 'Label text for the checkbox',
|
|
19
|
+
placeholder: 'Enter label...'
|
|
20
|
+
})
|
|
21
|
+
@IsString()
|
|
22
|
+
label!: string;
|
|
23
|
+
|
|
24
|
+
@Field({ defaultValue: false })
|
|
25
|
+
@Editor({
|
|
26
|
+
field_type: FieldType.BOOLEAN,
|
|
27
|
+
label: 'Checked',
|
|
28
|
+
description: 'Checkbox checked state'
|
|
29
|
+
})
|
|
30
|
+
@IsBoolean()
|
|
31
|
+
checked!: boolean;
|
|
32
|
+
|
|
33
|
+
@Field()
|
|
34
|
+
@Editor({
|
|
35
|
+
field_type: FieldType.TEXT,
|
|
36
|
+
label: 'Helper Text',
|
|
37
|
+
description: 'Helper text displayed below the checkbox',
|
|
38
|
+
placeholder: 'Enter helper text...'
|
|
39
|
+
})
|
|
40
|
+
@IsOptional()
|
|
41
|
+
@IsString()
|
|
42
|
+
helperText?: string;
|
|
43
|
+
|
|
44
|
+
@Field({ defaultValue: false })
|
|
45
|
+
@Editor({
|
|
46
|
+
field_type: FieldType.BOOLEAN,
|
|
47
|
+
label: 'Required',
|
|
48
|
+
description: 'Mark checkbox as required'
|
|
49
|
+
})
|
|
50
|
+
@IsOptional()
|
|
51
|
+
@IsBoolean()
|
|
52
|
+
required?: boolean;
|
|
53
|
+
|
|
54
|
+
@Field({ defaultValue: false })
|
|
55
|
+
@Editor({
|
|
56
|
+
field_type: FieldType.BOOLEAN,
|
|
57
|
+
label: 'Disabled',
|
|
58
|
+
description: 'Disable the checkbox'
|
|
59
|
+
})
|
|
60
|
+
@IsOptional()
|
|
61
|
+
@IsBoolean()
|
|
62
|
+
disabled?: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default FormCheckboxModel;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema for FormField component - Themed text/number input field
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { IsBoolean, IsIn, IsInt, IsOptional, IsString, Min } from 'class-validator';
|
|
8
|
+
import 'reflect-metadata';
|
|
9
|
+
import { Editor, Field, Schema, FieldType } from '@qwickapps/schema';
|
|
10
|
+
import ViewSchema from './ViewSchema';
|
|
11
|
+
|
|
12
|
+
@Schema('FormField', '1.0.0')
|
|
13
|
+
export class FormFieldModel extends ViewSchema {
|
|
14
|
+
@Field()
|
|
15
|
+
@Editor({
|
|
16
|
+
field_type: FieldType.TEXT,
|
|
17
|
+
label: 'Label',
|
|
18
|
+
description: 'Label text for the input field',
|
|
19
|
+
placeholder: 'Enter label...'
|
|
20
|
+
})
|
|
21
|
+
@IsString()
|
|
22
|
+
label!: string;
|
|
23
|
+
|
|
24
|
+
@Field()
|
|
25
|
+
@Editor({
|
|
26
|
+
field_type: FieldType.TEXT,
|
|
27
|
+
label: 'Value',
|
|
28
|
+
description: 'Current input value',
|
|
29
|
+
placeholder: ''
|
|
30
|
+
})
|
|
31
|
+
@IsString()
|
|
32
|
+
value!: string | number;
|
|
33
|
+
|
|
34
|
+
@Field({ defaultValue: 'text' })
|
|
35
|
+
@Editor({
|
|
36
|
+
field_type: FieldType.SELECT,
|
|
37
|
+
label: 'Input Type',
|
|
38
|
+
description: 'Type of input field'
|
|
39
|
+
})
|
|
40
|
+
@IsOptional()
|
|
41
|
+
@IsIn(['text', 'number', 'password', 'email', 'tel'])
|
|
42
|
+
type?: 'text' | 'number' | 'password' | 'email' | 'tel';
|
|
43
|
+
|
|
44
|
+
@Field()
|
|
45
|
+
@Editor({
|
|
46
|
+
field_type: FieldType.TEXT,
|
|
47
|
+
label: 'Helper Text',
|
|
48
|
+
description: 'Helper text displayed below the input',
|
|
49
|
+
placeholder: 'Enter helper text...'
|
|
50
|
+
})
|
|
51
|
+
@IsOptional()
|
|
52
|
+
@IsString()
|
|
53
|
+
helperText?: string;
|
|
54
|
+
|
|
55
|
+
@Field({ defaultValue: false })
|
|
56
|
+
@Editor({
|
|
57
|
+
field_type: FieldType.BOOLEAN,
|
|
58
|
+
label: 'Required',
|
|
59
|
+
description: 'Mark field as required'
|
|
60
|
+
})
|
|
61
|
+
@IsOptional()
|
|
62
|
+
@IsBoolean()
|
|
63
|
+
required?: boolean;
|
|
64
|
+
|
|
65
|
+
@Field({ defaultValue: false })
|
|
66
|
+
@Editor({
|
|
67
|
+
field_type: FieldType.BOOLEAN,
|
|
68
|
+
label: 'Read Only',
|
|
69
|
+
description: 'Make field read-only'
|
|
70
|
+
})
|
|
71
|
+
@IsOptional()
|
|
72
|
+
@IsBoolean()
|
|
73
|
+
readOnly?: boolean;
|
|
74
|
+
|
|
75
|
+
@Field({ defaultValue: false })
|
|
76
|
+
@Editor({
|
|
77
|
+
field_type: FieldType.BOOLEAN,
|
|
78
|
+
label: 'Disabled',
|
|
79
|
+
description: 'Disable the input field'
|
|
80
|
+
})
|
|
81
|
+
@IsOptional()
|
|
82
|
+
@IsBoolean()
|
|
83
|
+
disabled?: boolean;
|
|
84
|
+
|
|
85
|
+
@Field()
|
|
86
|
+
@Editor({
|
|
87
|
+
field_type: FieldType.TEXT,
|
|
88
|
+
label: 'Disabled Color',
|
|
89
|
+
description: 'Custom color for disabled state (CSS color value)',
|
|
90
|
+
placeholder: 'var(--theme-text-disabled)'
|
|
91
|
+
})
|
|
92
|
+
@IsOptional()
|
|
93
|
+
@IsString()
|
|
94
|
+
disabledColor?: string;
|
|
95
|
+
|
|
96
|
+
@Field({ defaultValue: true })
|
|
97
|
+
@Editor({
|
|
98
|
+
field_type: FieldType.BOOLEAN,
|
|
99
|
+
label: 'Full Width',
|
|
100
|
+
description: 'Make input take full width of container'
|
|
101
|
+
})
|
|
102
|
+
@IsOptional()
|
|
103
|
+
@IsBoolean()
|
|
104
|
+
fullWidth?: boolean;
|
|
105
|
+
|
|
106
|
+
@Field({ defaultValue: false })
|
|
107
|
+
@Editor({
|
|
108
|
+
field_type: FieldType.BOOLEAN,
|
|
109
|
+
label: 'Multiline',
|
|
110
|
+
description: 'Enable multiline textarea mode'
|
|
111
|
+
})
|
|
112
|
+
@IsOptional()
|
|
113
|
+
@IsBoolean()
|
|
114
|
+
multiline?: boolean;
|
|
115
|
+
|
|
116
|
+
@Field()
|
|
117
|
+
@Editor({
|
|
118
|
+
field_type: FieldType.TEXT,
|
|
119
|
+
label: 'Rows',
|
|
120
|
+
description: 'Number of rows for multiline textarea',
|
|
121
|
+
placeholder: '4'
|
|
122
|
+
})
|
|
123
|
+
@IsOptional()
|
|
124
|
+
@IsInt()
|
|
125
|
+
@Min(1)
|
|
126
|
+
rows?: number;
|
|
127
|
+
|
|
128
|
+
@Field()
|
|
129
|
+
@Editor({
|
|
130
|
+
field_type: FieldType.TEXT,
|
|
131
|
+
label: 'Placeholder',
|
|
132
|
+
description: 'Placeholder text',
|
|
133
|
+
placeholder: 'Enter text...'
|
|
134
|
+
})
|
|
135
|
+
@IsOptional()
|
|
136
|
+
@IsString()
|
|
137
|
+
placeholder?: string;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export default FormFieldModel;
|