@liguelead/design-system 0.0.10 → 0.0.11
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/components/Button/Button.appearance.ts +20 -16
- package/components/Button/Button.sizes.ts +18 -17
- package/components/Button/Button.styles.ts +7 -11
- package/components/Button/Button.tsx +5 -5
- package/components/Button/Button.types.ts +3 -3
- package/components/Checkbox/Checkbox.styles.ts +84 -35
- package/components/Checkbox/Checkbox.tsx +62 -5
- package/components/Checkbox/Checkbox.types.ts +1 -0
- package/components/IconButton/IconButton.sizes.ts +6 -13
- package/components/IconButton/IconButton.tsx +5 -5
- package/components/InputOpt/InputOpt.styles.ts +75 -0
- package/components/InputOpt/InputOpt.tsx +153 -0
- package/components/InputOpt/InputOpt.types.ts +14 -0
- package/components/InputOpt/index.ts +1 -0
- package/components/InputOpt/utils/focusManagement.ts +31 -0
- package/components/InputOpt/utils/index.ts +2 -0
- package/components/InputOpt/utils/inputValidation.ts +14 -0
- package/components/LinkButton/LinkButton.size.ts +39 -0
- package/components/LinkButton/LinkButton.style.ts +45 -0
- package/components/LinkButton/LinkButton.tsx +75 -0
- package/components/LinkButton/LinkButton.types.ts +11 -0
- package/components/LinkButton/index.ts +1 -0
- package/components/RadioButton/RadioButton.inputVariants.ts +133 -0
- package/components/RadioButton/RadioButton.styles.ts +78 -0
- package/components/RadioButton/RadioButton.tsx +88 -0
- package/components/RadioButton/RadioButton.types.ts +33 -0
- package/components/RadioButton/RadioButton.variants.ts +67 -0
- package/components/RadioButton/index.ts +1 -0
- package/components/SegmentedButton/SegmentedButton.tsx +0 -6
- package/components/Select/Select.sizes.ts +10 -11
- package/components/Select/Select.states.tsx +8 -37
- package/components/Select/Select.styles.ts +53 -39
- package/components/Select/Select.tsx +30 -23
- package/components/Select/Select.types.ts +1 -2
- package/components/Text/Text.styles.ts +11 -8
- package/components/Text/Text.tsx +2 -2
- package/components/Text/Text.types.ts +3 -1
- package/components/TextField/TextField.sizes.ts +3 -9
- package/components/TextField/TextField.states.tsx +11 -11
- package/components/TextField/TextField.styles.ts +4 -0
- package/components/TextField/TextField.tsx +5 -2
- package/components/index.ts +3 -0
- package/package.json +2 -2
- package/utils/darkenOrLighen.ts +1 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FieldValues, UseFormRegisterReturn } from 'react-hook-form'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
export type RadioButtonVariant = 'default' | 'box'
|
|
5
|
+
|
|
6
|
+
export interface RadioButtonProps<TFieldValues extends FieldValues = FieldValues>
|
|
7
|
+
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {
|
|
8
|
+
label: string
|
|
9
|
+
description?: string
|
|
10
|
+
value: string
|
|
11
|
+
checked?: boolean
|
|
12
|
+
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
|
|
13
|
+
disabled?: boolean
|
|
14
|
+
className?: string
|
|
15
|
+
name?: string
|
|
16
|
+
error?: TFieldValues
|
|
17
|
+
register?: UseFormRegisterReturn<string>
|
|
18
|
+
rightIcon?: React.ReactNode
|
|
19
|
+
variant?: RadioButtonVariant
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface RadioButtonVariantProps {
|
|
23
|
+
$disabled?: boolean
|
|
24
|
+
$error?: boolean
|
|
25
|
+
$checked?: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface RadioWrapperProps {
|
|
29
|
+
$disabled?: boolean
|
|
30
|
+
$error?: boolean
|
|
31
|
+
$variant?: 'default' | 'box'
|
|
32
|
+
$checked?: boolean
|
|
33
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { css } from 'styled-components'
|
|
2
|
+
import { parseColor } from '../../utils'
|
|
3
|
+
import { RadioButtonVariantProps } from './RadioButton.types'
|
|
4
|
+
import { spacing, radius} from "@liguelead/foundation"
|
|
5
|
+
|
|
6
|
+
export const RadioButtonVariant = (variant: 'default' | 'box') => {
|
|
7
|
+
const variants = {
|
|
8
|
+
default: css<RadioButtonVariantProps>`
|
|
9
|
+
/* Estilo padrão - sem bordas adicionais no wrapper */
|
|
10
|
+
`,
|
|
11
|
+
|
|
12
|
+
box: css<RadioButtonVariantProps>`
|
|
13
|
+
padding: ${spacing.spacing12}px;
|
|
14
|
+
border: 1px solid ${({ theme, $error }) =>
|
|
15
|
+
$error
|
|
16
|
+
? parseColor(theme.colors.danger200)
|
|
17
|
+
: parseColor(theme.colors.neutral400)
|
|
18
|
+
};
|
|
19
|
+
border-radius: ${radius.radius8}px;
|
|
20
|
+
background: ${({ theme }) => parseColor(theme.colors.white)};
|
|
21
|
+
|
|
22
|
+
/* Quando o input interno está checked, muda o estilo do wrapper */
|
|
23
|
+
input[type="radio"]:checked ~ * {
|
|
24
|
+
/* Força re-render no wrapper quando input muda */
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Usa seletor CSS para detectar radio checked */
|
|
28
|
+
&:has(input[type="radio"]:checked) {
|
|
29
|
+
border-color: ${({ theme, $error }) =>
|
|
30
|
+
$error
|
|
31
|
+
? parseColor(theme.colors.danger200)
|
|
32
|
+
: parseColor(theme.colors.primary)
|
|
33
|
+
};
|
|
34
|
+
background: ${({ theme, $error }) =>
|
|
35
|
+
$error
|
|
36
|
+
? parseColor(theme.colors.white)
|
|
37
|
+
: `${parseColor(theme.colors.primaryLight)}`
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&:hover {
|
|
42
|
+
border-color: ${({ theme, $error }) =>
|
|
43
|
+
$error
|
|
44
|
+
? parseColor(theme.colors.danger200)
|
|
45
|
+
: parseColor(theme.colors.primary)
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
&:has(input[type="radio"]:checked) {
|
|
49
|
+
background: ${({ theme, $error }) =>
|
|
50
|
+
$error
|
|
51
|
+
? parseColor(theme.colors.white)
|
|
52
|
+
: `${parseColor(theme.colors.primaryLight)}`
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&:not(:has(input[type="radio"]:checked)) {
|
|
57
|
+
background: ${({ theme, $error }) =>
|
|
58
|
+
$error
|
|
59
|
+
? `${parseColor(theme.colors.danger200)}10`
|
|
60
|
+
: `${parseColor(theme.colors.white)}`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return variants[variant] || variants.default
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './RadioButton'
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
RightButton,
|
|
5
5
|
WrapperSegmentedButton
|
|
6
6
|
} from './SegmentedButton.styles'
|
|
7
|
-
import { useState } from 'react'
|
|
8
7
|
|
|
9
8
|
const SegmentedButton: React.FC<SegmentedButtonProps> = ({
|
|
10
9
|
options,
|
|
@@ -14,17 +13,14 @@ const SegmentedButton: React.FC<SegmentedButtonProps> = ({
|
|
|
14
13
|
...rest
|
|
15
14
|
}) => {
|
|
16
15
|
const { leftButton, rightButton } = options
|
|
17
|
-
const [selected, setSelected] = useState<string>('left')
|
|
18
16
|
|
|
19
17
|
return (
|
|
20
18
|
<WrapperSegmentedButton {...rest}>
|
|
21
19
|
<LeftButton
|
|
22
20
|
color={color}
|
|
23
21
|
disabled={disabled}
|
|
24
|
-
appearance={selected === 'left' ? 'solid' : 'outline'}
|
|
25
22
|
size={size}
|
|
26
23
|
onClick={() => {
|
|
27
|
-
setSelected('left')
|
|
28
24
|
leftButton.action?.()
|
|
29
25
|
}}
|
|
30
26
|
type="button">
|
|
@@ -32,10 +28,8 @@ const SegmentedButton: React.FC<SegmentedButtonProps> = ({
|
|
|
32
28
|
</LeftButton>
|
|
33
29
|
<RightButton
|
|
34
30
|
color={color}
|
|
35
|
-
appearance={selected === 'right' ? 'solid' : 'outline'}
|
|
36
31
|
disabled={disabled}
|
|
37
32
|
onClick={() => {
|
|
38
|
-
setSelected('right')
|
|
39
33
|
rightButton.action?.()
|
|
40
34
|
}}
|
|
41
35
|
size={size}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fontSize, lineHeight, spacing } from '@liguelead/foundation'
|
|
1
|
+
import { fontSize, lineHeight, spacing, fontWeight } from '@liguelead/foundation'
|
|
2
2
|
import { TextFieldSize } from './Select.types'
|
|
3
3
|
|
|
4
4
|
export const textFieldSizes = (
|
|
@@ -16,15 +16,16 @@ export const textFieldSizes = (
|
|
|
16
16
|
const sizes = {
|
|
17
17
|
sm: {
|
|
18
18
|
input: `
|
|
19
|
-
font-size: ${fontSize.fontSize14}px;
|
|
20
|
-
line-height: ${lineHeight.lineHeight22}px;
|
|
19
|
+
font-size: ${fontSize.fontSize14}px;
|
|
20
|
+
line-height: ${lineHeight.lineHeight22}px;
|
|
21
21
|
padding: ${spacing.spacing8}px ${spacing.spacing12}px;
|
|
22
22
|
padding-left: ${leftIcon ? withIconPadding.sm : spacing.spacing12}px;
|
|
23
23
|
padding-right: ${rightIcon ? withIconPadding.sm : spacing.spacing12}px;
|
|
24
|
-
|
|
25
|
-
label: `
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
`,
|
|
25
|
+
label: `
|
|
26
|
+
font-size: ${fontSize.fontSize14}px;
|
|
27
|
+
font-weight: ${fontWeight.fontWeight500};
|
|
28
|
+
`
|
|
28
29
|
},
|
|
29
30
|
md: {
|
|
30
31
|
input: `
|
|
@@ -35,8 +36,7 @@ export const textFieldSizes = (
|
|
|
35
36
|
padding-right: ${rightIcon ? withIconPadding.md : spacing.spacing16}px;
|
|
36
37
|
`,
|
|
37
38
|
label: `font-size: ${fontSize.fontSize14}px;
|
|
38
|
-
|
|
39
|
-
margin-right: ${rightIcon ? withIconMargin : 0}px;`
|
|
39
|
+
font-weight: ${fontWeight.fontWeight500}`
|
|
40
40
|
},
|
|
41
41
|
lg: {
|
|
42
42
|
input: `
|
|
@@ -47,8 +47,7 @@ export const textFieldSizes = (
|
|
|
47
47
|
padding-right: ${rightIcon ? withIconPadding.lg : spacing.spacing16}px;
|
|
48
48
|
`,
|
|
49
49
|
label: `font-size: ${fontSize.fontSize16}px;
|
|
50
|
-
|
|
51
|
-
margin-right: ${rightIcon ? withIconMargin : 0}px;`
|
|
50
|
+
font-weight: ${fontWeight.fontWeight500}`
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
53
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { parseColor } from '../../utils'
|
|
2
2
|
import { useTheme } from 'styled-components'
|
|
3
|
-
import { fontWeight, fontSize } from '@liguelead/foundation'
|
|
4
3
|
import { TextFieldStates } from './Select.types'
|
|
5
4
|
|
|
6
5
|
export const SelectStates = (state: keyof TextFieldStates) => {
|
|
@@ -9,60 +8,32 @@ export const SelectStates = (state: keyof TextFieldStates) => {
|
|
|
9
8
|
error: {
|
|
10
9
|
input: `
|
|
11
10
|
border: 1px solid ${parseColor(theme.colors.danger100)};
|
|
12
|
-
color: ${parseColor(theme.colors.
|
|
11
|
+
color: ${parseColor(theme.colors.textDark)};
|
|
13
12
|
&:focus {
|
|
14
13
|
border-color: ${parseColor(theme.colors.danger100)};
|
|
15
14
|
}
|
|
16
|
-
&:focus + label {
|
|
17
|
-
color: ${parseColor(theme.colors.danger100)};
|
|
18
|
-
}
|
|
19
15
|
`,
|
|
20
16
|
label: `color: ${parseColor(theme.colors.danger100)};`,
|
|
21
|
-
helperText: `color: ${parseColor(theme.colors.danger100)}
|
|
22
|
-
animation: `
|
|
23
|
-
&:focus div + label,
|
|
24
|
-
&:not(:placeholder-shown) + label {
|
|
25
|
-
top: 0px;
|
|
26
|
-
left: 12px;
|
|
27
|
-
font-size: ${fontSize.fontSize12}px;
|
|
28
|
-
}`
|
|
17
|
+
helperText: `color: ${parseColor(theme.colors.danger100)};`
|
|
29
18
|
},
|
|
30
19
|
default: {
|
|
31
20
|
input: `
|
|
32
21
|
border: 1px solid ${parseColor(theme.colors.neutral700)};
|
|
33
|
-
color: ${parseColor(theme.colors.
|
|
34
|
-
|
|
22
|
+
color: ${parseColor(theme.colors.textDark)};
|
|
35
23
|
&:focus {
|
|
36
24
|
border-color: ${parseColor(theme.colors.primary)};
|
|
37
25
|
}
|
|
38
|
-
&:focus label,
|
|
39
|
-
&:focus-within label {
|
|
40
|
-
color: ${parseColor(theme.colors.primary)} !important;
|
|
41
|
-
font-weight: ${fontWeight.fontWeight600};
|
|
42
|
-
.select-label {
|
|
43
|
-
color: ${parseColor(theme.colors.primary)};
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
26
|
`,
|
|
47
|
-
label: `color: ${parseColor(theme.colors.
|
|
48
|
-
helperText: `color: ${parseColor(theme.colors.
|
|
49
|
-
animation: `
|
|
50
|
-
&:focus + label,
|
|
51
|
-
&:not(:placeholder-shown) + label {
|
|
52
|
-
top: 0px;
|
|
53
|
-
left: 12px;
|
|
54
|
-
font-size: ${fontSize.fontSize12}px;
|
|
55
|
-
}`
|
|
27
|
+
label: `color: ${parseColor(theme.colors.textDark)};`,
|
|
28
|
+
helperText: `color: ${parseColor(theme.colors.textMedium)};`
|
|
56
29
|
},
|
|
57
30
|
disabled: {
|
|
58
31
|
input: `
|
|
59
|
-
border:
|
|
32
|
+
border: 1px solid ${parseColor(theme.colors.neutral400)};
|
|
60
33
|
color: ${parseColor(theme.colors.neutral600)};
|
|
61
34
|
`,
|
|
62
|
-
label: `color: ${parseColor(theme.colors.
|
|
63
|
-
|
|
64
|
-
helperText: `color: ${parseColor(theme.colors.neutral500)};`,
|
|
65
|
-
animation: ``
|
|
35
|
+
label: `color: ${parseColor(theme.colors.neutral1100)};`,
|
|
36
|
+
helperText: `color: ${parseColor(theme.colors.textMedium)};`
|
|
66
37
|
}
|
|
67
38
|
}
|
|
68
39
|
return states[state]
|
|
@@ -4,7 +4,8 @@ import {
|
|
|
4
4
|
fontSize,
|
|
5
5
|
fontWeight,
|
|
6
6
|
lineHeight,
|
|
7
|
-
spacing
|
|
7
|
+
spacing,
|
|
8
|
+
shadow
|
|
8
9
|
} from '@liguelead/foundation'
|
|
9
10
|
import { parseColor } from '../../utils'
|
|
10
11
|
import { Content, Item } from '@radix-ui/react-select'
|
|
@@ -19,28 +20,23 @@ export const InputWrapper = styled.div`
|
|
|
19
20
|
width: 100%;
|
|
20
21
|
`
|
|
21
22
|
|
|
22
|
-
export const
|
|
23
|
-
|
|
24
|
-
top: 50%;
|
|
25
|
-
left: 12px;
|
|
26
|
-
transform: translateY(-50%);
|
|
23
|
+
export const Label = styled.label`
|
|
24
|
+
display: block;
|
|
27
25
|
font-weight: ${fontWeight.fontWeight600};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
background-color: white;
|
|
31
|
-
padding: 0 4px;
|
|
32
|
-
&.is-open {
|
|
33
|
-
color: ${({ theme }) => parseColor(theme.colors.primary)} !important;
|
|
34
|
-
}
|
|
26
|
+
margin-bottom: ${spacing.spacing4}px;
|
|
27
|
+
font-size: ${fontSize.fontSize14}px;
|
|
35
28
|
`
|
|
36
29
|
|
|
37
30
|
export const HelperText = styled.span<{ error?: boolean }>`
|
|
38
31
|
font-size: ${fontSize.fontSize12}px;
|
|
39
32
|
line-height: ${lineHeight.lineHeight12}px;
|
|
40
|
-
padding-left: ${spacing.spacing16}px;
|
|
41
33
|
`
|
|
42
34
|
|
|
43
|
-
export const IconWrapper = styled.div<{
|
|
35
|
+
export const IconWrapper = styled.div<{
|
|
36
|
+
$right?: boolean;
|
|
37
|
+
$error?: boolean;
|
|
38
|
+
$disabled?: boolean;
|
|
39
|
+
}>` ${({theme, $error, $disabled, $right }) =>`
|
|
44
40
|
display: flex;
|
|
45
41
|
align-items: center;
|
|
46
42
|
justify-content: space-between;
|
|
@@ -48,18 +44,21 @@ export const IconWrapper = styled.div<{ $right?: boolean; $error?: boolean }>`
|
|
|
48
44
|
top: 0px;
|
|
49
45
|
height: 100%;
|
|
50
46
|
cursor: pointer;
|
|
51
|
-
${
|
|
47
|
+
${$right ? 'right: 0px;' : 'left: 0px;'}
|
|
52
48
|
padding: 0px ${spacing.spacing16}px;
|
|
53
49
|
|
|
54
50
|
& svg {
|
|
55
|
-
width:
|
|
56
|
-
height:
|
|
57
|
-
fill: ${
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
width: 16px;
|
|
52
|
+
height: 16px;
|
|
53
|
+
fill: ${$error
|
|
54
|
+
? parseColor(theme.colors.danger200)
|
|
55
|
+
: $disabled
|
|
56
|
+
? parseColor(theme.colors.neutral400)
|
|
57
|
+
: parseColor(theme.colors.neutral800)};
|
|
61
58
|
transition: fill 0.2s ease;
|
|
59
|
+
cursor: ${$disabled ? 'not-allowed' : 'pointer'};
|
|
62
60
|
}
|
|
61
|
+
`}
|
|
63
62
|
`
|
|
64
63
|
|
|
65
64
|
export const StyledContent = styled(Content)`
|
|
@@ -73,6 +72,7 @@ export const StyledContent = styled(Content)`
|
|
|
73
72
|
max-height: var(--radix-select-content-height, 314px);
|
|
74
73
|
overflow-y: scroll !important;
|
|
75
74
|
z-index: 10;
|
|
75
|
+
|
|
76
76
|
& .RadixSelectViewport {
|
|
77
77
|
max-height: 200px; /* Limite de altura do dropdown */
|
|
78
78
|
overflow-y: auto; /* Adiciona o scroll quando necessário */
|
|
@@ -84,15 +84,19 @@ export const StyledItem = styled(Item)`
|
|
|
84
84
|
padding: ${spacing.spacing12}px ${spacing.spacing20}px;
|
|
85
85
|
display: flex;
|
|
86
86
|
align-items: center;
|
|
87
|
-
|
|
87
|
+
justify-content: space-between;
|
|
88
|
+
gap: 8px; /* mantém espaçamento interno caso adicionemos ícones à esquerda futuramente */
|
|
88
89
|
transition: all 0.2s ease;
|
|
89
90
|
cursor: pointer;
|
|
91
|
+
|
|
90
92
|
&:hover {
|
|
91
|
-
background-color: ${({ theme }) => parseColor(theme.colors.
|
|
93
|
+
background-color: ${({ theme }) => parseColor(theme.colors.primaryLight)};
|
|
92
94
|
}
|
|
95
|
+
|
|
93
96
|
&[data-state='checked'] {
|
|
94
97
|
background-color: ${({ theme }) =>
|
|
95
|
-
parseColor(theme.colors.
|
|
98
|
+
parseColor(theme.colors.primary)};
|
|
99
|
+
color: ${({ theme }) => parseColor(theme.colors.white)};
|
|
96
100
|
}
|
|
97
101
|
`
|
|
98
102
|
|
|
@@ -104,9 +108,20 @@ export const StyledInput = styled.input.withConfig({
|
|
|
104
108
|
outline: none;
|
|
105
109
|
transition: border-color 0.2s ease;
|
|
106
110
|
background: transparent;
|
|
111
|
+
cursor: pointer;
|
|
112
|
+
|
|
113
|
+
&:focus {
|
|
114
|
+
box-shadow: ${shadow.focusShadow}
|
|
115
|
+
}
|
|
116
|
+
|
|
107
117
|
&.is-open {
|
|
108
118
|
border-color: ${({ theme }) =>
|
|
109
|
-
parseColor(theme.colors.
|
|
119
|
+
parseColor(theme.colors.neutral800)} !important;
|
|
120
|
+
box-shadow: ${shadow.focusShadow}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
&:disabled {
|
|
124
|
+
cursor: not-allowed;
|
|
110
125
|
}
|
|
111
126
|
`
|
|
112
127
|
|
|
@@ -132,17 +147,16 @@ export const Wrapper = styled.div<StyledInputProps>`
|
|
|
132
147
|
width: 100%;
|
|
133
148
|
cursor: pointer;
|
|
134
149
|
${({ $themefication, size }) => `
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
${
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
${
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
`}
|
|
150
|
+
${StyledInput} {
|
|
151
|
+
${$themefication.input}
|
|
152
|
+
${size.input}
|
|
153
|
+
}
|
|
154
|
+
${HelperText} {
|
|
155
|
+
${$themefication.helperText}
|
|
156
|
+
}
|
|
157
|
+
${Label} {
|
|
158
|
+
${$themefication.label}
|
|
159
|
+
${size.label}
|
|
160
|
+
}
|
|
161
|
+
`}
|
|
148
162
|
`
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { forwardRef, useState } from 'react'
|
|
2
2
|
import * as RadixSelect from '@radix-ui/react-select'
|
|
3
|
-
import {
|
|
3
|
+
import { CaretDownIcon, CheckIcon } from '@phosphor-icons/react'
|
|
4
4
|
import {
|
|
5
|
-
FloatingLabel,
|
|
6
5
|
HelperText,
|
|
7
6
|
IconWrapper,
|
|
8
7
|
InputWrapper,
|
|
9
8
|
StyledContent,
|
|
10
9
|
StyledInput,
|
|
11
10
|
StyledItem,
|
|
12
|
-
Wrapper
|
|
11
|
+
Wrapper,
|
|
12
|
+
Label
|
|
13
13
|
} from './Select.styles'
|
|
14
14
|
import { SelectStates } from './Select.states'
|
|
15
15
|
import { textFieldSizes } from './Select.sizes'
|
|
16
|
-
import TextField from '../TextField/TextField'
|
|
17
16
|
import { SelectProps, StateInterface } from './Select.types'
|
|
18
17
|
import getState from '../TextField/utils/getState'
|
|
19
18
|
|
|
@@ -76,7 +75,25 @@ const Select = forwardRef<HTMLInputElement, SelectProps>(
|
|
|
76
75
|
onChange={register?.onChange}
|
|
77
76
|
onBlur={register?.onBlur}
|
|
78
77
|
/>
|
|
79
|
-
{
|
|
78
|
+
<Label>{label}</Label>
|
|
79
|
+
{disabled ? (
|
|
80
|
+
<InputWrapper className="is-disabled">
|
|
81
|
+
{leftIcon && (
|
|
82
|
+
<IconWrapper onClick={handleLeftIcon} $disabled={disabled}>
|
|
83
|
+
{leftIcon}
|
|
84
|
+
</IconWrapper>
|
|
85
|
+
)}
|
|
86
|
+
<IconWrapper $right $error={!!error} $disabled={disabled}>
|
|
87
|
+
<CaretDownIcon weight="fill" size={14} />
|
|
88
|
+
</IconWrapper>
|
|
89
|
+
<StyledInput
|
|
90
|
+
disabled
|
|
91
|
+
readOnly
|
|
92
|
+
value={selectedLabel}
|
|
93
|
+
className="is-disabled"
|
|
94
|
+
/>
|
|
95
|
+
</InputWrapper>
|
|
96
|
+
) : (
|
|
80
97
|
<RadixSelect.Root
|
|
81
98
|
value={selectValue}
|
|
82
99
|
onOpenChange={open => setOpen(open)}
|
|
@@ -84,7 +101,7 @@ const Select = forwardRef<HTMLInputElement, SelectProps>(
|
|
|
84
101
|
onValueChange={(value: string) =>
|
|
85
102
|
handleOnChange(value)
|
|
86
103
|
}>
|
|
87
|
-
<RadixSelect.Trigger asChild>
|
|
104
|
+
<RadixSelect.Trigger asChild disabled={disabled}>
|
|
88
105
|
<InputWrapper>
|
|
89
106
|
{leftIcon && (
|
|
90
107
|
<IconWrapper onClick={handleLeftIcon}>
|
|
@@ -92,19 +109,14 @@ const Select = forwardRef<HTMLInputElement, SelectProps>(
|
|
|
92
109
|
</IconWrapper>
|
|
93
110
|
)}
|
|
94
111
|
<IconWrapper $right $error={!!error}>
|
|
95
|
-
<
|
|
112
|
+
<CaretDownIcon weight="fill" size={14} />
|
|
96
113
|
</IconWrapper>
|
|
97
114
|
<StyledInput
|
|
98
115
|
readOnly
|
|
99
116
|
style={{ cursor: 'pointer !important' }}
|
|
100
117
|
value={selectedLabel}
|
|
101
|
-
placeholder=" "
|
|
102
118
|
className={open ? 'is-open' : ''}
|
|
103
119
|
/>
|
|
104
|
-
<FloatingLabel
|
|
105
|
-
className={open ? 'is-open' : ''}>
|
|
106
|
-
{label}
|
|
107
|
-
</FloatingLabel>
|
|
108
120
|
</InputWrapper>
|
|
109
121
|
</RadixSelect.Trigger>
|
|
110
122
|
<StyledContent
|
|
@@ -117,22 +129,17 @@ const Select = forwardRef<HTMLInputElement, SelectProps>(
|
|
|
117
129
|
{options.map(option => (
|
|
118
130
|
<StyledItem
|
|
119
131
|
key={option.value}
|
|
120
|
-
value={option.value}
|
|
121
|
-
|
|
122
|
-
{option.label}
|
|
132
|
+
value={option.value}
|
|
133
|
+
>
|
|
134
|
+
<span>{option.label}</span>
|
|
135
|
+
{option.value === selectValue && (
|
|
136
|
+
<CheckIcon weight="bold" />
|
|
137
|
+
)}
|
|
123
138
|
</StyledItem>
|
|
124
139
|
))}
|
|
125
140
|
</RadixSelect.Viewport>
|
|
126
141
|
</StyledContent>
|
|
127
142
|
</RadixSelect.Root>
|
|
128
|
-
) : (
|
|
129
|
-
<TextField
|
|
130
|
-
leftIcon={leftIcon}
|
|
131
|
-
rightIcon={<CaretDown weight="fill" size={14} />}
|
|
132
|
-
label={label}
|
|
133
|
-
size={size}
|
|
134
|
-
disabled
|
|
135
|
-
/>
|
|
136
143
|
)}
|
|
137
144
|
{(helperText || error) && (
|
|
138
145
|
<HelperText>{error?.message || helperText}</HelperText>
|
|
@@ -3,7 +3,7 @@ export interface SelectProps<TFieldValues extends FieldValues = FieldValues> {
|
|
|
3
3
|
className?: string
|
|
4
4
|
disabled?: boolean
|
|
5
5
|
error?: TFieldValues
|
|
6
|
-
label
|
|
6
|
+
label?: string
|
|
7
7
|
options: Array<{ label: string; value: string }>
|
|
8
8
|
value?: string
|
|
9
9
|
defaultValue?: string
|
|
@@ -19,7 +19,6 @@ export interface StateInterface {
|
|
|
19
19
|
input: string
|
|
20
20
|
label: string
|
|
21
21
|
helperText: string
|
|
22
|
-
animation?: string
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
export interface TextFieldStates {
|
|
@@ -20,22 +20,25 @@ const Body = styled.p.withConfig({
|
|
|
20
20
|
|
|
21
21
|
${({
|
|
22
22
|
align = 'left',
|
|
23
|
-
color = '
|
|
23
|
+
color = 'textMedium',
|
|
24
24
|
isTitle,
|
|
25
25
|
theme,
|
|
26
|
-
size = 'body01'
|
|
26
|
+
size = 'body01',
|
|
27
|
+
weight
|
|
27
28
|
}) => css`
|
|
28
29
|
text-align: ${align};
|
|
29
|
-
color: ${parseColor(theme.colors[color] || theme.colors.
|
|
30
|
+
color: ${parseColor(theme.colors[color] || theme.colors.textMedium)};
|
|
30
31
|
font-family: '${isTitle
|
|
31
|
-
? fontFamily[theme.fonts
|
|
32
|
-
: fontFamily[theme.fonts
|
|
32
|
+
? fontFamily[theme.fonts?.headings as keyof typeof fontFamily]
|
|
33
|
+
: fontFamily[theme.fonts?.default as keyof typeof fontFamily]}',
|
|
33
34
|
sans-serif;
|
|
34
|
-
font-weight: ${
|
|
35
|
+
font-weight: ${weight
|
|
36
|
+
? fontWeight[weight as keyof typeof fontWeight]
|
|
37
|
+
: fontWeight[theme.typography[size]?.fontWeight as keyof typeof fontWeight] ||
|
|
35
38
|
'normal'};
|
|
36
|
-
font-size: ${fontSize[theme.typography[size]?.fontSize] ||
|
|
39
|
+
font-size: ${fontSize[theme.typography[size]?.fontSize as keyof typeof fontSize] ||
|
|
37
40
|
fontSize.fontSize16}px;
|
|
38
|
-
line-height: ${lineHeight[theme.typography[size]?.lineHeight] ||
|
|
41
|
+
line-height: ${lineHeight[theme.typography[size]?.lineHeight as keyof typeof lineHeight] ||
|
|
39
42
|
lineHeight.lineHeight24}px;
|
|
40
43
|
`}
|
|
41
44
|
`
|
package/components/Text/Text.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import { TextProps } from './Text.types'
|
|
|
5
5
|
const Text: React.FC<TextProps> = ({
|
|
6
6
|
align,
|
|
7
7
|
children,
|
|
8
|
-
color = '
|
|
8
|
+
color = 'textDark',
|
|
9
9
|
isTitle = false,
|
|
10
10
|
tag = 'p',
|
|
11
11
|
size,
|
|
@@ -15,7 +15,7 @@ const Text: React.FC<TextProps> = ({
|
|
|
15
15
|
<Body
|
|
16
16
|
as={isTitle ? 'h2' : tag}
|
|
17
17
|
align={align}
|
|
18
|
-
color={color}
|
|
18
|
+
color={color as string}
|
|
19
19
|
size={size}
|
|
20
20
|
isTitle={isTitle}
|
|
21
21
|
{...rest}>
|
|
@@ -30,6 +30,8 @@ type TagType =
|
|
|
30
30
|
| 'div'
|
|
31
31
|
| 'a'
|
|
32
32
|
|
|
33
|
+
type WeightType = 'fontWeight400' | 'fontWeight500' | 'fontWeight600' | 'fontWeight700'
|
|
34
|
+
|
|
33
35
|
export interface TextProps {
|
|
34
36
|
align?: AlignType
|
|
35
37
|
children?: ReactNode
|
|
@@ -37,6 +39,6 @@ export interface TextProps {
|
|
|
37
39
|
isTitle?: boolean
|
|
38
40
|
tag?: TagType
|
|
39
41
|
size?: SizeType
|
|
40
|
-
weight?:
|
|
42
|
+
weight?: WeightType
|
|
41
43
|
className?: string
|
|
42
44
|
}
|
|
@@ -24,9 +24,7 @@ export const textFieldSizes = (size: TextFieldSize, leftIcon: boolean, rightIcon
|
|
|
24
24
|
padding-left: ${leftIcon ? withIconPadding.sm : spacing.spacing12}px;
|
|
25
25
|
padding-right: ${rightIcon ? withIconPadding.sm : spacing.spacing12}px;
|
|
26
26
|
`,
|
|
27
|
-
label: `font-size: ${fontSize.fontSize14}px
|
|
28
|
-
margin-left: ${leftIcon ? withIconMargin : 0}px;
|
|
29
|
-
margin-right: ${rightIcon ? withIconMargin : 0}px;`
|
|
27
|
+
label: `font-size: ${fontSize.fontSize14}px;`
|
|
30
28
|
},
|
|
31
29
|
md: {
|
|
32
30
|
input: `
|
|
@@ -36,9 +34,7 @@ export const textFieldSizes = (size: TextFieldSize, leftIcon: boolean, rightIcon
|
|
|
36
34
|
padding-left: ${leftIcon ? withIconPadding.md : spacing.spacing16}px;
|
|
37
35
|
padding-right: ${rightIcon ? withIconPadding.md : spacing.spacing16}px;
|
|
38
36
|
`,
|
|
39
|
-
label: `font-size: ${fontSize.fontSize14}px
|
|
40
|
-
margin-left: ${leftIcon ? withIconMargin : 0}px;
|
|
41
|
-
margin-right: ${rightIcon ? withIconMargin : 0}px;`
|
|
37
|
+
label: `font-size: ${fontSize.fontSize14}px;`
|
|
42
38
|
},
|
|
43
39
|
lg: {
|
|
44
40
|
input: `
|
|
@@ -48,9 +44,7 @@ export const textFieldSizes = (size: TextFieldSize, leftIcon: boolean, rightIcon
|
|
|
48
44
|
padding-left: ${leftIcon ? withIconPadding.lg : spacing.spacing16}px;
|
|
49
45
|
padding-right: ${rightIcon ? withIconPadding.lg : spacing.spacing16}px;
|
|
50
46
|
`,
|
|
51
|
-
label: `font-size: ${fontSize.fontSize16}px
|
|
52
|
-
margin-left: ${leftIcon ? withIconMargin : 0}px;
|
|
53
|
-
margin-right: ${rightIcon ? withIconMargin : 0}px;`
|
|
47
|
+
label: `font-size: ${fontSize.fontSize16}px;`
|
|
54
48
|
}
|
|
55
49
|
}
|
|
56
50
|
|