File tree Expand file tree Collapse file tree 7 files changed +227
-94
lines changed Expand file tree Collapse file tree 7 files changed +227
-94
lines changed Original file line number Diff line number Diff line change
1
+ import React from 'react' ;
2
+ import { useSettings } from '../../contexts/SettingsContext' ;
3
+
4
+ interface CheckboxProps {
5
+ id : string ;
6
+ label : string ;
7
+ helpText ?: string ;
8
+ error ?: string ;
9
+ required ?: boolean ;
10
+ checked : boolean ;
11
+ onChange : ( e : React . ChangeEvent < HTMLInputElement > ) => void ;
12
+ disabled ?: boolean ;
13
+ className ?: string ;
14
+ labelClassName ?: string ;
15
+ dataTestId ?: string ;
16
+ }
17
+
18
+ const Checkbox : React . FC < CheckboxProps > = ( {
19
+ id,
20
+ label,
21
+ helpText,
22
+ error,
23
+ required,
24
+ checked,
25
+ onChange,
26
+ disabled = false ,
27
+ className = '' ,
28
+ labelClassName = '' ,
29
+ dataTestId,
30
+ } ) => {
31
+ const { settings } = useSettings ( ) ;
32
+ const themeColor = settings . themeColor ;
33
+
34
+ return (
35
+ < div className = "mb-4" >
36
+ < div className = "flex items-center space-x-3" >
37
+ < input
38
+ id = { id }
39
+ type = "checkbox"
40
+ checked = { checked }
41
+ onChange = { onChange }
42
+ disabled = { disabled }
43
+ className = { `h-4 w-4 focus:ring-offset-2 border-gray-300 rounded ${ className } ` }
44
+ data-testid = { dataTestId }
45
+ style = { {
46
+ color : themeColor ,
47
+ '--tw-ring-color' : themeColor ,
48
+ accentColor : themeColor ,
49
+ } as React . CSSProperties }
50
+ />
51
+ < label htmlFor = { id } className = { `text-sm text-gray-700 ${ labelClassName } ` } >
52
+ { label }
53
+ { required && < span className = "text-red-500 ml-1" > *</ span > }
54
+ </ label >
55
+ </ div >
56
+ { error && < p className = "mt-1 text-sm text-red-500" > { error } </ p > }
57
+ { helpText && ! error && < p className = "mt-1 text-sm text-gray-500" > { helpText } </ p > }
58
+ </ div >
59
+ ) ;
60
+ } ;
61
+
62
+ export default Checkbox ;
Original file line number Diff line number Diff line change @@ -4,38 +4,38 @@ import { useSettings } from '../../contexts/SettingsContext';
4
4
interface InputProps {
5
5
id : string ;
6
6
label : string ;
7
+ helpText ?: string ;
8
+ error ?: string ;
9
+ required ?: boolean ;
7
10
type ?: string ;
8
11
value : string ;
9
- onChange : ( e : React . ChangeEvent < HTMLInputElement > ) => void ;
12
+ icon ?: React . ReactNode ;
13
+ placeholder ?: string ;
10
14
onKeyDown ?: ( e : React . KeyboardEvent ) => void ;
15
+ onChange : ( e : React . ChangeEvent < HTMLInputElement > ) => void ;
11
16
onFocus ?: ( e : React . FocusEvent < HTMLInputElement > ) => void ;
12
- placeholder ?: string ;
13
- required ?: boolean ;
14
17
disabled ?: boolean ;
15
- error ?: string ;
16
- helpText ?: string ;
17
18
className ?: string ;
18
19
labelClassName ?: string ;
19
- icon ?: React . ReactNode ;
20
20
dataTestId ?: string ;
21
21
}
22
22
23
23
const Input : React . FC < InputProps > = ( {
24
24
id,
25
25
label,
26
+ helpText,
27
+ error,
28
+ required,
26
29
type = 'text' ,
27
30
value,
28
- onChange,
31
+ icon,
32
+ placeholder = '' ,
29
33
onKeyDown,
34
+ onChange,
30
35
onFocus,
31
- placeholder = '' ,
32
- required = false ,
33
36
disabled = false ,
34
- error,
35
- helpText,
36
37
className = '' ,
37
38
labelClassName = '' ,
38
- icon,
39
39
dataTestId,
40
40
} ) => {
41
41
const { settings } = useSettings ( ) ;
Original file line number Diff line number Diff line change
1
+ import React from 'react' ;
2
+ import Markdown from 'react-markdown' ;
3
+ import remarkGfm from 'remark-gfm' ;
4
+
5
+ interface LabelProps {
6
+ content : string ;
7
+ className ?: string ;
8
+ dataTestId ?: string ;
9
+ }
10
+
11
+ const Label : React . FC < LabelProps > = ( {
12
+ content,
13
+ className = '' ,
14
+ dataTestId,
15
+ } ) => {
16
+ return (
17
+ < div className = { `mb-4 ${ className } ` } data-testid = { dataTestId } >
18
+ < div className = "prose prose-sm prose-gray max-w-none" >
19
+ < Markdown
20
+ remarkPlugins = { [ remarkGfm ] }
21
+ components = { {
22
+ a : ( { ...props } ) => (
23
+ < a
24
+ { ...props }
25
+ target = "_blank"
26
+ rel = "noopener noreferrer"
27
+ className = "text-blue-600 hover:text-blue-800 underline"
28
+ />
29
+ ) ,
30
+ } }
31
+ >
32
+ { content }
33
+ </ Markdown >
34
+ </ div >
35
+ </ div >
36
+ ) ;
37
+ } ;
38
+
39
+ export default Label ;
Original file line number Diff line number Diff line change
1
+ import React from 'react' ;
2
+ import { useSettings } from '../../contexts/SettingsContext' ;
3
+ import { AppConfigChildItem } from '../../types' ;
4
+
5
+ interface RadioProps {
6
+ id : string ;
7
+ label : string ;
8
+ helpText ?: string ;
9
+ error ?: string ;
10
+ required ?: boolean ;
11
+ value : string ;
12
+ options : AppConfigChildItem [ ] ;
13
+ onChange : ( e : React . ChangeEvent < HTMLInputElement > ) => void ;
14
+ disabled ?: boolean ;
15
+ className ?: string ;
16
+ labelClassName ?: string ;
17
+ }
18
+
19
+ const Radio : React . FC < RadioProps > = ( {
20
+ id,
21
+ label,
22
+ helpText,
23
+ error,
24
+ required,
25
+ value,
26
+ options,
27
+ onChange,
28
+ disabled = false ,
29
+ className = '' ,
30
+ labelClassName = '' ,
31
+ } ) => {
32
+ const { settings } = useSettings ( ) ;
33
+ const themeColor = settings . themeColor ;
34
+
35
+ return (
36
+ < div className = "mb-4" >
37
+ < label className = { `block text-sm font-medium text-gray-700 mb-2 ${ labelClassName } ` } >
38
+ { label }
39
+ { required && < span className = "text-red-500 ml-1" > *</ span > }
40
+ </ label >
41
+ < div className = "space-y-2" >
42
+ { options . map ( option => (
43
+ < div key = { option . name } className = "flex items-center" >
44
+ < input
45
+ type = "radio"
46
+ id = { option . name }
47
+ name = { id }
48
+ value = { option . name }
49
+ checked = { value === option . name }
50
+ onChange = { onChange }
51
+ disabled = { disabled }
52
+ className = { `h-4 w-4 focus:ring-offset-2 border-gray-300 ${ className } ` }
53
+ data-testid = { `radio-input-${ option . name } ` }
54
+ style = { {
55
+ color : themeColor ,
56
+ '--tw-ring-color' : themeColor ,
57
+ accentColor : themeColor ,
58
+ } as React . CSSProperties }
59
+ />
60
+ < label htmlFor = { option . name } className = "ml-3 text-sm text-gray-700" >
61
+ { option . title }
62
+ </ label >
63
+ </ div >
64
+ ) ) }
65
+ </ div >
66
+ { error && < p className = "mt-1 text-sm text-red-500" > { error } </ p > }
67
+ { helpText && ! error && < p className = "mt-1 text-sm text-gray-500" > { helpText } </ p > }
68
+ </ div >
69
+ ) ;
70
+ } ;
71
+
72
+ export default Radio ;
Original file line number Diff line number Diff line change @@ -4,14 +4,14 @@ import { useSettings } from '../../contexts/SettingsContext';
4
4
interface TextareaProps {
5
5
id : string ;
6
6
label : string ;
7
+ helpText ?: string ;
8
+ error ?: string ;
9
+ required ?: boolean ;
7
10
value : string ;
8
- onChange : ( e : ChangeEvent < HTMLTextAreaElement > ) => void ;
9
11
rows ?: number ;
10
12
placeholder ?: string ;
11
- required ?: boolean ;
13
+ onChange : ( e : ChangeEvent < HTMLTextAreaElement > ) => void ;
12
14
disabled ?: boolean ;
13
- error ?: string ;
14
- helpText ?: string ;
15
15
className ?: string ;
16
16
labelClassName ?: string ;
17
17
dataTestId ?: string ;
@@ -20,14 +20,14 @@ interface TextareaProps {
20
20
const Textarea = ( {
21
21
id,
22
22
label,
23
+ helpText,
24
+ error,
25
+ required = false ,
23
26
value,
24
- onChange,
25
27
rows = 4 ,
26
28
placeholder = '' ,
27
- required = false ,
29
+ onChange ,
28
30
disabled = false ,
29
- error,
30
- helpText,
31
31
className = '' ,
32
32
labelClassName = '' ,
33
33
dataTestId,
You can’t perform that action at this time.
0 commit comments