@startlibs/form 1.0.11 → 1.1.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/lib/AutoComplete.mjs +550 -0
- package/lib/AutoComplete.mjs.map +1 -0
- package/lib/Checkbox.mjs +76 -0
- package/lib/Checkbox.mjs.map +1 -0
- package/lib/Combobox.mjs +544 -0
- package/lib/Combobox.mjs.map +1 -0
- package/lib/ComboboxWithCustom.mjs +77 -0
- package/lib/ComboboxWithCustom.mjs.map +1 -0
- package/lib/DatePicker.mjs +625 -0
- package/lib/DatePicker.mjs.map +1 -0
- package/lib/EditableBox.mjs +496 -0
- package/lib/EditableBox.mjs.map +1 -0
- package/lib/Errors.mjs +176 -0
- package/lib/Errors.mjs.map +1 -0
- package/lib/ExpandableBox.mjs +209 -0
- package/lib/ExpandableBox.mjs.map +1 -0
- package/lib/Field.mjs +65 -0
- package/lib/Field.mjs.map +1 -0
- package/lib/FieldBox.mjs +80 -0
- package/lib/FieldBox.mjs.map +1 -0
- package/lib/Form.mjs +322 -0
- package/lib/Form.mjs.map +1 -0
- package/lib/FormValue.mjs +111 -0
- package/lib/FormValue.mjs.map +1 -0
- package/lib/InputboxGroup.mjs +104 -0
- package/lib/InputboxGroup.mjs.map +1 -0
- package/lib/Radiobox.mjs +67 -0
- package/lib/Radiobox.mjs.map +1 -0
- package/lib/RichText.mjs +634 -0
- package/lib/RichText.mjs.map +1 -0
- package/lib/TextInput.mjs +359 -0
- package/lib/TextInput.mjs.map +1 -0
- package/lib/alt/checkbox/SimpleCheckbox.mjs +82 -0
- package/lib/alt/checkbox/SimpleCheckbox.mjs.map +1 -0
- package/lib/alt/checkbox/ToggleCheckbox.mjs +68 -0
- package/lib/alt/checkbox/ToggleCheckbox.mjs.map +1 -0
- package/lib/alt/radiobox/CleanTabRadiobox.mjs +44 -0
- package/lib/alt/radiobox/CleanTabRadiobox.mjs.map +1 -0
- package/lib/alt/radiobox/IconRadioBox.mjs +52 -0
- package/lib/alt/radiobox/IconRadioBox.mjs.map +1 -0
- package/lib/alt/radiobox/SimpleRadiobox.mjs +61 -0
- package/lib/alt/radiobox/SimpleRadiobox.mjs.map +1 -0
- package/lib/alt/radiobox/TabRadiobox.mjs +54 -0
- package/lib/alt/radiobox/TabRadiobox.mjs.map +1 -0
- package/lib/enhanceInput.mjs +131 -0
- package/lib/enhanceInput.mjs.map +1 -0
- package/lib/index.cjs +5345 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.mjs +28 -0
- package/lib/index.mjs.map +1 -0
- package/lib/useConfirmDialog.mjs +117 -0
- package/lib/useConfirmDialog.mjs.map +1 -0
- package/lib/useDraftConfirmation.mjs +56 -0
- package/lib/useDraftConfirmation.mjs.map +1 -0
- package/lib/validation.mjs +91 -0
- package/lib/validation.mjs.map +1 -0
- package/lib/withFormImageInput.mjs +281 -0
- package/lib/withFormImageInput.mjs.map +1 -0
- package/package.json +44 -25
- package/src/AutoComplete.jsx +642 -0
- package/src/Checkbox.jsx +45 -0
- package/src/Combobox.jsx +606 -0
- package/src/ComboboxWithCustom.jsx +68 -0
- package/src/DatePicker.jsx +733 -0
- package/src/EditableBox.jsx +502 -0
- package/src/Errors.jsx +174 -0
- package/src/ExpandableBox.jsx +207 -0
- package/src/Field.jsx +76 -0
- package/src/FieldBox.jsx +136 -0
- package/src/Form.jsx +291 -0
- package/src/FormValue.jsx +67 -0
- package/src/IconRadioBoxOldHubt.jsx +93 -0
- package/src/InputboxGroup.jsx +121 -0
- package/src/Radiobox.jsx +33 -0
- package/src/RichText.jsx +812 -0
- package/src/TextInput.jsx +519 -0
- package/src/alt/checkbox/SimpleCheckbox.jsx +162 -0
- package/src/alt/checkbox/ToggleCheckbox.jsx +143 -0
- package/src/alt/radiobox/CleanTabRadiobox.jsx +46 -0
- package/src/alt/radiobox/IconRadioBox.jsx +93 -0
- package/src/alt/radiobox/SimpleRadiobox.jsx +153 -0
- package/src/alt/radiobox/TabRadiobox.jsx +73 -0
- package/src/enhanceInput.jsx +107 -0
- package/src/index.js +27 -0
- package/src/useConfirmDialog.jsx +105 -0
- package/src/useDraftConfirmation.jsx +60 -0
- package/src/validation.js +92 -0
- package/src/withFormImageInput.jsx +297 -0
- package/.babelrc +0 -28
- package/lib/index.js +0 -6255
- package/rollup.config.js +0 -43
- package/yarn-error.log +0 -1607
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import styled, {css} from 'styled-components'
|
|
3
|
+
import {Checkbox} from '../../Checkbox'
|
|
4
|
+
import {HelpText} from '../../Field'
|
|
5
|
+
import {customTheme, getColor} from '@startlibs/utils'
|
|
6
|
+
import {darken} from 'polished';
|
|
7
|
+
import { TransitionDiv } from '@startlibs/components';
|
|
8
|
+
const ToggleContainer = styled.div `
|
|
9
|
+
`
|
|
10
|
+
|
|
11
|
+
const Toggle = styled.div `
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
flex-shrink: 0;
|
|
14
|
+
margin-left: 1rem;
|
|
15
|
+
float: right;
|
|
16
|
+
transition: 0.25s ease;
|
|
17
|
+
width: 2.75rem;
|
|
18
|
+
height: 18px;
|
|
19
|
+
border-radius: 18px;
|
|
20
|
+
background: ${props => props.checked ? getColor('main') : 'rgba(0,0,0,0.14)'};
|
|
21
|
+
display: inline-block;
|
|
22
|
+
position: relative;
|
|
23
|
+
font-weight: 600;
|
|
24
|
+
:after {
|
|
25
|
+
content: '';
|
|
26
|
+
transition: 0.25s ease;
|
|
27
|
+
border-radius: 50%;
|
|
28
|
+
display: block;
|
|
29
|
+
position: absolute;
|
|
30
|
+
top: 50%;
|
|
31
|
+
transform: translateY(-50%);
|
|
32
|
+
width: 14px;
|
|
33
|
+
height: 14px;
|
|
34
|
+
background: white;
|
|
35
|
+
${props => props.checked ? css`
|
|
36
|
+
margin-left: -2px;
|
|
37
|
+
left: 100%;
|
|
38
|
+
transform: translate(-100%,-50%);
|
|
39
|
+
` : css`
|
|
40
|
+
margin-left: 2px;
|
|
41
|
+
left: 0;
|
|
42
|
+
`}
|
|
43
|
+
}
|
|
44
|
+
${customTheme('ToggleCheckbox')}
|
|
45
|
+
`
|
|
46
|
+
const ToggleLabel = styled.div `
|
|
47
|
+
flex-basis: 0;
|
|
48
|
+
flex-grow: 1;
|
|
49
|
+
display: inline-block;
|
|
50
|
+
font-size: 15px;
|
|
51
|
+
`
|
|
52
|
+
const DescText = styled.div `
|
|
53
|
+
font-weight: 400;
|
|
54
|
+
color: rgba(0,0,0,0.4);
|
|
55
|
+
font-size: 12px;
|
|
56
|
+
margin-top: 0.25rem;
|
|
57
|
+
`
|
|
58
|
+
const ToggleCheckboxStyled = styled(Checkbox)`
|
|
59
|
+
position:relative;
|
|
60
|
+
border-radius: 8px;
|
|
61
|
+
padding: 1rem;
|
|
62
|
+
min-height: 42px;
|
|
63
|
+
font-weight: 550;
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
display: flex;
|
|
66
|
+
align-items: center;
|
|
67
|
+
justify-content: space-between;
|
|
68
|
+
transition: background 0.2s linear;
|
|
69
|
+
& ~ & {
|
|
70
|
+
margin-top: -1rem;
|
|
71
|
+
}
|
|
72
|
+
${props => props.margin ? css`
|
|
73
|
+
margin-bottom: ${props => props.margin}px;
|
|
74
|
+
`: css`
|
|
75
|
+
margin-bottom: 1.5rem;
|
|
76
|
+
& ~ & {
|
|
77
|
+
margin-top: -1rem;
|
|
78
|
+
}
|
|
79
|
+
`}
|
|
80
|
+
${props => props.gray ? `
|
|
81
|
+
background-color: rgba(0,0,0,0.06);
|
|
82
|
+
:hover {
|
|
83
|
+
background-color: rgba(0,0,0,0.08);
|
|
84
|
+
}
|
|
85
|
+
:active {
|
|
86
|
+
background-color: rgba(0,0,0,0.1);
|
|
87
|
+
transition: none;
|
|
88
|
+
}
|
|
89
|
+
`:css`
|
|
90
|
+
background-color: ${getColor('lightBluishGray')};
|
|
91
|
+
:hover {
|
|
92
|
+
background: ${props => darken(0.035, getColor('lightBluishGray')(props))};
|
|
93
|
+
}
|
|
94
|
+
:active {
|
|
95
|
+
background: ${props => darken(0.05, getColor('lightBluishGray')(props))};
|
|
96
|
+
transition: none;
|
|
97
|
+
}
|
|
98
|
+
`}
|
|
99
|
+
${props => !props.noFocus && css`
|
|
100
|
+
:focus-within {
|
|
101
|
+
background-color: rgba(0,0,0,0.09);
|
|
102
|
+
:after{
|
|
103
|
+
content: '';
|
|
104
|
+
pointer-events: none;
|
|
105
|
+
position: absolute;
|
|
106
|
+
top: -3px;
|
|
107
|
+
right: -3px;
|
|
108
|
+
left: -3px;
|
|
109
|
+
bottom: -3px;
|
|
110
|
+
border-radius: 9px;
|
|
111
|
+
border: 2px solid rgba(0, 0, 0, 0.15);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
`}
|
|
115
|
+
${props => props.disabled && `
|
|
116
|
+
opacity: 0.8;
|
|
117
|
+
pointer-events:none;
|
|
118
|
+
`}
|
|
119
|
+
${customTheme('ToggleCheckboxBox')}
|
|
120
|
+
`
|
|
121
|
+
|
|
122
|
+
export const ToggleCheckbox = styled(({path, disabled, rightInfo, label, descText, helpText, tabIndex,noFocus, margin, className,...rest}) =>
|
|
123
|
+
<ToggleCheckboxStyled
|
|
124
|
+
path={path}
|
|
125
|
+
tabIndex={tabIndex}
|
|
126
|
+
disabled={disabled}
|
|
127
|
+
noFocus={noFocus}
|
|
128
|
+
className={className}
|
|
129
|
+
margin={margin}
|
|
130
|
+
{...rest}
|
|
131
|
+
>{({disabled, checked, hasErrors, focused}) =>
|
|
132
|
+
<>
|
|
133
|
+
<ToggleLabel>
|
|
134
|
+
{label}{helpText && <HelpText> {helpText}</HelpText>}
|
|
135
|
+
<TransitionDiv block>{descText && <DescText>{descText}</DescText>}</TransitionDiv>
|
|
136
|
+
</ToggleLabel>
|
|
137
|
+
{rightInfo}
|
|
138
|
+
<Toggle checked={checked}/>
|
|
139
|
+
</>
|
|
140
|
+
}
|
|
141
|
+
</ToggleCheckboxStyled>
|
|
142
|
+
)`
|
|
143
|
+
`
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import styled, {css} from 'styled-components'
|
|
3
|
+
import {getColor, customTheme} from '@startlibs/utils'
|
|
4
|
+
import {Radiobox} from '../../Radiobox'
|
|
5
|
+
|
|
6
|
+
export const Tab = styled.div`
|
|
7
|
+
width:100%;
|
|
8
|
+
font-size: 16px;
|
|
9
|
+
color: ${getColor("gray120")};
|
|
10
|
+
font-weight: 500;
|
|
11
|
+
margin-left: 0;
|
|
12
|
+
padding: 12px 2.5rem;
|
|
13
|
+
flex-grow: 1;
|
|
14
|
+
height: 100%;
|
|
15
|
+
border-bottom: 1px solid ${getColor("gray210")};
|
|
16
|
+
position: relative;
|
|
17
|
+
${props => props.checked ? css`
|
|
18
|
+
color: ${getColor("main")};
|
|
19
|
+
:after {
|
|
20
|
+
content: '';
|
|
21
|
+
position: absolute;
|
|
22
|
+
bottom: -2px;
|
|
23
|
+
left: 0;
|
|
24
|
+
right: 0;
|
|
25
|
+
height: 3px;
|
|
26
|
+
background: ${getColor("main")};
|
|
27
|
+
border-radius: 10px;
|
|
28
|
+
}
|
|
29
|
+
`: css`
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
:hover {
|
|
32
|
+
color: ${getColor("gray90")};
|
|
33
|
+
}
|
|
34
|
+
`}
|
|
35
|
+
${customTheme('CleanTabButton')}
|
|
36
|
+
`
|
|
37
|
+
|
|
38
|
+
const InnerButton = styled.a``
|
|
39
|
+
|
|
40
|
+
export const CleanTabRadiobox = styled(({label, white,icon,...props}) =>
|
|
41
|
+
<Radiobox {...props}>{({disabled, checked, hasErrors, focused}) =>
|
|
42
|
+
<Tab innerAs={InnerButton} tabIndex={-1} focused={focused} checked={checked} disabled={disabled}>{label}</Tab>
|
|
43
|
+
}</Radiobox>
|
|
44
|
+
)`
|
|
45
|
+
display: inline-block;
|
|
46
|
+
`
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import styled, {css} from 'styled-components'
|
|
3
|
+
import {Icon} from '@startlibs/components'
|
|
4
|
+
import {customTheme, getColor} from '@startlibs/utils'
|
|
5
|
+
import {Radiobox} from '../../Radiobox'
|
|
6
|
+
import {lighten, desaturate} from 'polished'
|
|
7
|
+
|
|
8
|
+
export const IconRadioBoxText = styled.div`
|
|
9
|
+
flex-grow: 1;
|
|
10
|
+
padding: 0 0.5rem 0.5rem;
|
|
11
|
+
min-height: 2rem;
|
|
12
|
+
display: flex;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
align-items: center;
|
|
15
|
+
text-align: center;
|
|
16
|
+
font-size: 12px;
|
|
17
|
+
color: ${getColor('gray120')};
|
|
18
|
+
${props => props.checked && css`
|
|
19
|
+
color: ${getColor('main')};
|
|
20
|
+
`}
|
|
21
|
+
${props => props.highlightedDesc && css`
|
|
22
|
+
background: ${getColor('gray240')};
|
|
23
|
+
padding: 0.25rem 0.5rem;
|
|
24
|
+
min-height: 3rem;
|
|
25
|
+
${props => props.checked && css`
|
|
26
|
+
background: ${props => desaturate(0.3, lighten(0.52, getColor("main")(props)))};
|
|
27
|
+
`}
|
|
28
|
+
`}
|
|
29
|
+
`
|
|
30
|
+
|
|
31
|
+
export const IconRadioBoxIconContainer = styled.div`
|
|
32
|
+
display: flex;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
align-items: center;
|
|
35
|
+
text-align: center;
|
|
36
|
+
`
|
|
37
|
+
|
|
38
|
+
const Wrapper = styled.div`
|
|
39
|
+
width: 100%;
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
cursor: pointer;
|
|
43
|
+
border-radius: 8px;
|
|
44
|
+
background-color: white;
|
|
45
|
+
border: 1px solid ${getColor('gray210')};
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
color: ${getColor('gray150')};
|
|
48
|
+
|
|
49
|
+
${Icon} {
|
|
50
|
+
font-size: 100px;
|
|
51
|
+
line-height: 50px;
|
|
52
|
+
line-height: 76px;
|
|
53
|
+
width: 100%;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
${props => props.checked && css`
|
|
57
|
+
color: ${getColor('main')};
|
|
58
|
+
border-color: ${getColor('main')};
|
|
59
|
+
`}
|
|
60
|
+
|
|
61
|
+
input {
|
|
62
|
+
opacity: 0;
|
|
63
|
+
position: absolute;
|
|
64
|
+
left: -20000000px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
${props => props.focused && `
|
|
68
|
+
${IconRadioBoxIconContainer}::after {
|
|
69
|
+
content: '';
|
|
70
|
+
position: absolute;
|
|
71
|
+
top: -4px;
|
|
72
|
+
right: -4px;
|
|
73
|
+
left: -4px;
|
|
74
|
+
bottom: -4px;
|
|
75
|
+
border-radius: 10px;
|
|
76
|
+
border: 3px solid rgba(0, 0, 0, 0.15);
|
|
77
|
+
}`}
|
|
78
|
+
|
|
79
|
+
${customTheme("IconRadioBox")}
|
|
80
|
+
`
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
export const IconRadioBox = styled(({icon, label, highlightedDesc,...props}) =>
|
|
84
|
+
<Radiobox {...props}>{({checked, focused, hasErrors, disabled}) =>
|
|
85
|
+
<Wrapper checked={checked} focused={focused}>
|
|
86
|
+
<IconRadioBoxIconContainer><Icon icon={icon}/></IconRadioBoxIconContainer>
|
|
87
|
+
{checked}
|
|
88
|
+
<IconRadioBoxText highlightedDesc={highlightedDesc} checked={checked}>
|
|
89
|
+
{label}
|
|
90
|
+
</IconRadioBoxText>
|
|
91
|
+
</Wrapper>
|
|
92
|
+
}</Radiobox>
|
|
93
|
+
)`outline: none;`
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { getColor, ifProp, media } from '@startlibs/utils';
|
|
4
|
+
import styled, {css} from 'styled-components'
|
|
5
|
+
import {lighten, desaturate} from 'polished'
|
|
6
|
+
import {HelpText} from '../../Field'
|
|
7
|
+
import {Radiobox} from '../../Radiobox'
|
|
8
|
+
|
|
9
|
+
const CssCircle = styled.div`
|
|
10
|
+
border-radius: 50%;
|
|
11
|
+
content: '';
|
|
12
|
+
border: 1px solid ${getColor('gray210')};
|
|
13
|
+
width: 18px;
|
|
14
|
+
height: 18px;
|
|
15
|
+
background-color: white;
|
|
16
|
+
position: absolute;
|
|
17
|
+
left: -2rem;
|
|
18
|
+
top: 50%;
|
|
19
|
+
transform: translateY(-50%);
|
|
20
|
+
|
|
21
|
+
${ifProp('focused', css`
|
|
22
|
+
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
|
|
23
|
+
border-color: ${getColor('gray180')};
|
|
24
|
+
`)}
|
|
25
|
+
|
|
26
|
+
${ifProp('checked', css`
|
|
27
|
+
:before {
|
|
28
|
+
content: '';
|
|
29
|
+
width: 8px;
|
|
30
|
+
height: 8px;
|
|
31
|
+
top: 50%;
|
|
32
|
+
transform: translateY(-50%);
|
|
33
|
+
left: 4px;
|
|
34
|
+
border-radius: 50%;
|
|
35
|
+
position: absolute;
|
|
36
|
+
background-color: ${getColor('gray90')};
|
|
37
|
+
}
|
|
38
|
+
`)}
|
|
39
|
+
|
|
40
|
+
`
|
|
41
|
+
const TextLabel = styled.span `
|
|
42
|
+
font-size: 13px;
|
|
43
|
+
line-height: 16px;
|
|
44
|
+
margin: 2px 0.25rem 2px 0;
|
|
45
|
+
display: block;
|
|
46
|
+
`
|
|
47
|
+
const DescText = styled.div `
|
|
48
|
+
color: rgba(0,0,0,0.4);
|
|
49
|
+
display: block;
|
|
50
|
+
font-size: 12px;
|
|
51
|
+
font-weight: 400;
|
|
52
|
+
`
|
|
53
|
+
const TextLabelContainer = styled.div `
|
|
54
|
+
display: flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
position: relative;
|
|
57
|
+
flex-wrap: wrap;
|
|
58
|
+
`
|
|
59
|
+
const RadioboxContent = styled.div `
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
position: relative;
|
|
62
|
+
padding-left: 2rem;
|
|
63
|
+
transition: background 0.2s linear;
|
|
64
|
+
${props => props.framed && css`
|
|
65
|
+
border: 1px solid ${getColor('gray210')};
|
|
66
|
+
border-radius: 8px;
|
|
67
|
+
min-height: 3rem;
|
|
68
|
+
min-width: 8rem;
|
|
69
|
+
background: white;
|
|
70
|
+
width: 100%;
|
|
71
|
+
align-items: center;
|
|
72
|
+
display: flex;
|
|
73
|
+
:hover {
|
|
74
|
+
background: rgb(245,245,245);
|
|
75
|
+
}
|
|
76
|
+
:active {
|
|
77
|
+
background: rgb(235,235,235);
|
|
78
|
+
transition: none;
|
|
79
|
+
}
|
|
80
|
+
padding: 10px 12px 10px 32px;
|
|
81
|
+
${media.desktop`
|
|
82
|
+
padding: 7px 12px 7px 32px;
|
|
83
|
+
`}
|
|
84
|
+
${props => props.hasErrors && css`
|
|
85
|
+
border-color: ${getColor('alert')} !important;
|
|
86
|
+
`}
|
|
87
|
+
${props => props.checked && props.highlightSelected && css`
|
|
88
|
+
border-color: ${getColor('main')};
|
|
89
|
+
background: ${props => desaturate(0.3, lighten(0.52, getColor("main")(props)))};
|
|
90
|
+
:hover {
|
|
91
|
+
background: ${props => desaturate(0.3, lighten(0.52, getColor("main")(props)))};
|
|
92
|
+
}
|
|
93
|
+
${CssCircle} {
|
|
94
|
+
:before {
|
|
95
|
+
background-color: ${getColor('main')};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
`}
|
|
99
|
+
${props => props.checked && props.ultraHighlightSelected && css`
|
|
100
|
+
border-color: ${getColor('main')};
|
|
101
|
+
background: ${getColor('main')};
|
|
102
|
+
color: white;
|
|
103
|
+
:hover {
|
|
104
|
+
background: ${getColor('main')};
|
|
105
|
+
}
|
|
106
|
+
${CssCircle} {
|
|
107
|
+
:before {
|
|
108
|
+
background-color: ${getColor('main')};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
${HelpText} {
|
|
112
|
+
color: rgba(255, 255, 255, 0.65);
|
|
113
|
+
}
|
|
114
|
+
${DescText} {
|
|
115
|
+
color: rgba(255, 255, 255, 0.65);
|
|
116
|
+
}
|
|
117
|
+
`}
|
|
118
|
+
${props => props.disabled && css`
|
|
119
|
+
background-color: rgba(0,0,0,0.075) !important;
|
|
120
|
+
&[disabled] {
|
|
121
|
+
opacity: 0.75 !important;
|
|
122
|
+
}
|
|
123
|
+
${CssCircle} {
|
|
124
|
+
background: rgba(255,255,255,0.25);
|
|
125
|
+
}
|
|
126
|
+
`}
|
|
127
|
+
`}
|
|
128
|
+
`
|
|
129
|
+
|
|
130
|
+
export const SimpleRadiobox = styled((props) =>
|
|
131
|
+
<Radiobox {...props}>{({disabled, checked, hasErrors, focused, tabIndex, framedBoxes, highlightSelected, ultraHighlightSelected}) =>
|
|
132
|
+
<RadioboxContent checked={checked} framed={props.framedBoxes} highlightSelected={props.highlightSelected} ultraHighlightSelected={props.ultraHighlightSelected} hasErrors={hasErrors} disabled={disabled}>
|
|
133
|
+
<div className="textContainer">
|
|
134
|
+
<TextLabelContainer>
|
|
135
|
+
<CssCircle checked={checked} focused={focused} tabIndex={tabIndex}/>
|
|
136
|
+
<TextLabel>{props.label}</TextLabel>{props.helpText && <HelpText> {props.helpText}</HelpText>}
|
|
137
|
+
</TextLabelContainer>
|
|
138
|
+
{props.descText && <DescText>{props.descText}</DescText>}
|
|
139
|
+
</div>
|
|
140
|
+
</RadioboxContent>
|
|
141
|
+
}</Radiobox>
|
|
142
|
+
)`
|
|
143
|
+
cursor: pointer;
|
|
144
|
+
position: relative;
|
|
145
|
+
margin-bottom: 1rem;
|
|
146
|
+
display: flex;
|
|
147
|
+
${ifProp('disabled', css`
|
|
148
|
+
pointer-events: none;
|
|
149
|
+
`)}
|
|
150
|
+
.textContainer {
|
|
151
|
+
width: 100%;
|
|
152
|
+
}
|
|
153
|
+
`
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import styled, {css} from 'styled-components'
|
|
3
|
+
import {Button} from '@startlibs/components'
|
|
4
|
+
import {ifProp, getColor, media, customTheme} from '@startlibs/utils'
|
|
5
|
+
import {Radiobox} from '../../Radiobox'
|
|
6
|
+
import {lighten, desaturate} from 'polished'
|
|
7
|
+
|
|
8
|
+
export const TabButton = styled(Button)`
|
|
9
|
+
width:100%;
|
|
10
|
+
margin-left: 0;
|
|
11
|
+
padding: 9px 1rem;
|
|
12
|
+
flex-grow: 1;
|
|
13
|
+
background: ${props => props.white ? 'white' : getColor('gray240')};
|
|
14
|
+
box-shadow: none;
|
|
15
|
+
color: ${getColor('gray120')};
|
|
16
|
+
border: 1px solid ${getColor('gray210')};
|
|
17
|
+
border-left-width: 0;
|
|
18
|
+
height: 100%;
|
|
19
|
+
:hover {
|
|
20
|
+
background: ${props => desaturate(0.6, lighten(0.5, getColor("main")(props)))};
|
|
21
|
+
}
|
|
22
|
+
${ifProp('checked', css`
|
|
23
|
+
&, &:hover {
|
|
24
|
+
border-color: ${getColor('main')};
|
|
25
|
+
background-color: ${getColor('main')};
|
|
26
|
+
border-left-width: 1px;
|
|
27
|
+
color: #fff;
|
|
28
|
+
cursor: default;
|
|
29
|
+
}
|
|
30
|
+
`)}
|
|
31
|
+
|
|
32
|
+
${props => props.isFirst && `
|
|
33
|
+
border-left-width: 1px;
|
|
34
|
+
`}
|
|
35
|
+
${props => props.isFirst!==undefined && !props.isFirst && `
|
|
36
|
+
border-bottom-left-radius: 0;
|
|
37
|
+
border-top-left-radius: 0;
|
|
38
|
+
:focus:after{
|
|
39
|
+
border-bottom-left-radius: 2px;
|
|
40
|
+
border-top-left-radius: 2px;
|
|
41
|
+
}
|
|
42
|
+
`}
|
|
43
|
+
${props => props.isLast!==undefined && !props.isLast && `
|
|
44
|
+
border-bottom-right-radius: 0;
|
|
45
|
+
border-top-right-radius: 0;
|
|
46
|
+
:focus:after{
|
|
47
|
+
border-bottom-right-radius: 2px;
|
|
48
|
+
border-top-right-radius: 2px;
|
|
49
|
+
z-index: 2;
|
|
50
|
+
}
|
|
51
|
+
`}
|
|
52
|
+
${media.mobile`
|
|
53
|
+
min-width: 0;
|
|
54
|
+
${props => props.icon ? `
|
|
55
|
+
padding-left: 1.25rem;
|
|
56
|
+
padding-right: 1rem;
|
|
57
|
+
`:`
|
|
58
|
+
padding-left: 0.25rem;
|
|
59
|
+
padding-right: 0.25rem;
|
|
60
|
+
`}
|
|
61
|
+
`}
|
|
62
|
+
${customTheme('TabButton')}
|
|
63
|
+
`
|
|
64
|
+
|
|
65
|
+
const InnerButton = styled.a``
|
|
66
|
+
|
|
67
|
+
export const TabRadiobox = styled(({isLast, isFirst, label, white,icon,...props}) =>
|
|
68
|
+
<Radiobox {...props}>{({disabled, checked, hasErrors, focused}) =>
|
|
69
|
+
<TabButton innerAs={InnerButton} tabIndex={-1} focused={focused} isFirst={isFirst} isLast={isLast} checked={checked} disabled={disabled} white={white} icon={icon}>{label}</TabButton>
|
|
70
|
+
}</Radiobox>
|
|
71
|
+
)`
|
|
72
|
+
display: inline-block;
|
|
73
|
+
`
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import React, {useContext, useEffect, useState} from 'react'
|
|
3
|
+
import _ from 'lodash/fp'
|
|
4
|
+
import {_s, callIfFunction, formatPath, ifUndefined} from '@startlibs/utils'
|
|
5
|
+
import {ErrorsContext} from './Errors'
|
|
6
|
+
import {useFormValue} from './Form'
|
|
7
|
+
|
|
8
|
+
export const PathContext = React.createContext([])
|
|
9
|
+
export const enhancedInputDisplayName = 'EnhancedInput'
|
|
10
|
+
|
|
11
|
+
const undefinedToDefault = (v, defaultValue) => v === undefined ? defaultValue : v
|
|
12
|
+
const pathToStr = (v) => Array.isArray(v) ? v.join('.') : v
|
|
13
|
+
const skipValidation = () => true
|
|
14
|
+
|
|
15
|
+
const formInput = ({undefinedPlaceholder, isChecked = _.identity, truthSource = useFormValue, transform = _.identity, validation = skipValidation, onChange, fieldValue, path: propPath}) => {
|
|
16
|
+
const contextPath = useContext(PathContext)
|
|
17
|
+
const {paths} = useContext(ErrorsContext)
|
|
18
|
+
const path = ifUndefined(propPath, contextPath)
|
|
19
|
+
const formattedPath = formatPath(path)
|
|
20
|
+
const [formValue, setFormValue] = truthSource(formattedPath)
|
|
21
|
+
|
|
22
|
+
const setValue = (value, element) => {
|
|
23
|
+
const opts = {path,prevValue:formValue,element}
|
|
24
|
+
if (!validation(value,opts)) { return }
|
|
25
|
+
const transformedValue = transform(callIfFunction(value,formValue),opts)
|
|
26
|
+
setFormValue(transformedValue)
|
|
27
|
+
callIfFunction(onChange, transformedValue, opts)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const setValueFromEventTarget = (e) => setValue(e.currentTarget.value, e.currentTarget)
|
|
31
|
+
|
|
32
|
+
const setFromField = () => setValue(fieldValue)
|
|
33
|
+
|
|
34
|
+
const toggle = () => setValue(!isChecked(formValue) ? (fieldValue || true) : (!!fieldValue && undefined))
|
|
35
|
+
|
|
36
|
+
const toggleItem = () => setValue(_s.itemToggle(fieldValue))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
return [ifUndefined(formValue,undefinedPlaceholder), setValue, {
|
|
40
|
+
hasErrors:paths.has(formattedPath),
|
|
41
|
+
setFromField,
|
|
42
|
+
toggle,
|
|
43
|
+
toggleItem,
|
|
44
|
+
name:formattedPath,
|
|
45
|
+
setValueFromEventTarget
|
|
46
|
+
}]
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const rawInput = ({value, path, isChecked = _.identity, name, setValue: setValueProp, validation = skipValidation, transform = _.identity, onChange, fieldValue, defaultValue}) => {
|
|
51
|
+
const [rawValue, setRawValue] = useState(ifUndefined(value,defaultValue))
|
|
52
|
+
const errorUtils = useContext(ErrorsContext)
|
|
53
|
+
const formattedPath = formatPath(path)
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
setRawValue(value)
|
|
57
|
+
}, [value])
|
|
58
|
+
|
|
59
|
+
const setValue = (value, element) => {
|
|
60
|
+
if (!validation(value,{prevValue:rawValue})) { return }
|
|
61
|
+
const transformedValue = transform(value)
|
|
62
|
+
setValueProp(
|
|
63
|
+
transformedValue,
|
|
64
|
+
element
|
|
65
|
+
)
|
|
66
|
+
callIfFunction(onChange, transformedValue, rawValue, {element})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const setValueFromEventTarget = (e) => setValue(e.currentTarget.value, e.currentTarget)
|
|
70
|
+
|
|
71
|
+
const setFromField = () => setValue(fieldValue)
|
|
72
|
+
|
|
73
|
+
const toggle = () => setValue(!isChecked(rawValue))
|
|
74
|
+
|
|
75
|
+
const toggleItem = () => setValue(_s.itemToggle(fieldValue))
|
|
76
|
+
|
|
77
|
+
return [value, setValue, {
|
|
78
|
+
hasErrors:errorUtils?.paths?.has(formattedPath),
|
|
79
|
+
setFromField,
|
|
80
|
+
name,
|
|
81
|
+
toggle,
|
|
82
|
+
toggleItem,
|
|
83
|
+
setValueFromEventTarget
|
|
84
|
+
}]
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const useInput = (props,raw) => {
|
|
89
|
+
const [isRaw] = useState(raw)
|
|
90
|
+
return isRaw ? rawInput(props) : formInput(props)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const EnhanceInput = ({raw,...props}) => {
|
|
94
|
+
const [value,setValue,utils] = useInput(props,raw)
|
|
95
|
+
return props.children({
|
|
96
|
+
path:props.path,
|
|
97
|
+
value,
|
|
98
|
+
setValue,
|
|
99
|
+
...utils
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const enhanceInput = (InputComponent) => React.forwardRef(({...props}, ref) =>
|
|
104
|
+
<EnhanceInput {...props}>{(formInput) =>
|
|
105
|
+
<InputComponent {...props} ref={ref} formInput={formInput}/>
|
|
106
|
+
}</EnhanceInput>
|
|
107
|
+
)
|
package/src/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export * from './Form'
|
|
2
|
+
export * from './enhanceInput'
|
|
3
|
+
export * from './Field'
|
|
4
|
+
export * from './FieldBox'
|
|
5
|
+
export * from './useConfirmDialog'
|
|
6
|
+
export * from './TextInput'
|
|
7
|
+
export * from './Errors'
|
|
8
|
+
export * from './withFormImageInput'
|
|
9
|
+
export * from './Checkbox'
|
|
10
|
+
export * from './Combobox'
|
|
11
|
+
export * from './ComboboxWithCustom'
|
|
12
|
+
export * from './AutoComplete'
|
|
13
|
+
export * from './EditableBox'
|
|
14
|
+
export * from './FormValue'
|
|
15
|
+
export * from './Radiobox'
|
|
16
|
+
export * from './InputboxGroup'
|
|
17
|
+
export * from './DatePicker'
|
|
18
|
+
export * from './ExpandableBox'
|
|
19
|
+
export * from './RichText'
|
|
20
|
+
export * from './alt/radiobox/IconRadioBox'
|
|
21
|
+
export * from './alt/checkbox/SimpleCheckbox'
|
|
22
|
+
export * from './alt/checkbox/ToggleCheckbox'
|
|
23
|
+
export * from './alt/radiobox/TabRadiobox'
|
|
24
|
+
export * from './alt/radiobox/CleanTabRadiobox'
|
|
25
|
+
export * from './alt/radiobox/SimpleRadiobox'
|
|
26
|
+
export * from './useDraftConfirmation'
|
|
27
|
+
export {validation} from './validation'
|