agroptima-design-system 0.29.2-beta.3 → 0.29.2-beta.4
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/package.json +1 -1
- package/src/atoms/Button/Button.scss +13 -2
- package/src/atoms/DatePicker/DateRangePicker.tsx +17 -12
- package/src/atoms/DatePicker/translations.ts +3 -1
- package/src/atoms/Select.scss +23 -20
- package/src/atoms/Select.tsx +4 -11
- package/src/stories/DatePicker.stories.ts +6 -0
- package/tests/DateRangePicker.spec.tsx +1 -0
package/package.json
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
@use '../../settings/color_alias';
|
|
2
2
|
@use '../../settings/typography/content' as typography;
|
|
3
3
|
@use '../../settings/config';
|
|
4
|
-
@use '../../settings/mixins';
|
|
5
4
|
|
|
6
5
|
@mixin button-style($main-color, $secondary-color, $hover-color) {
|
|
7
|
-
@include mixins.icon-color($secondary-color);
|
|
8
6
|
background: $main-color;
|
|
9
7
|
color: $secondary-color;
|
|
10
8
|
|
|
9
|
+
> .icon {
|
|
10
|
+
> svg {
|
|
11
|
+
fill: $secondary-color;
|
|
12
|
+
path {
|
|
13
|
+
fill: $secondary-color;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
11
18
|
&:not(:disabled):hover,
|
|
12
19
|
&:not(:disabled):active {
|
|
13
20
|
background: $hover-color;
|
|
@@ -32,6 +39,10 @@
|
|
|
32
39
|
margin-top: 2px;
|
|
33
40
|
width: config.$icon-size-3x;
|
|
34
41
|
height: config.$icon-size-3x;
|
|
42
|
+
> svg {
|
|
43
|
+
width: 100%;
|
|
44
|
+
height: 100%;
|
|
45
|
+
}
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
&.primary {
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { translations } from './translations'
|
|
12
12
|
|
|
13
13
|
export type Variant = 'primary'
|
|
14
|
+
export type DateType = 'single' | 'range' | 'multiple'
|
|
14
15
|
|
|
15
16
|
type DivPropsWithoutOnSelect = Omit<
|
|
16
17
|
React.ComponentPropsWithoutRef<'div'>,
|
|
@@ -31,6 +32,8 @@ export interface DateRangePickerProps extends DivPropsWithoutOnSelect {
|
|
|
31
32
|
onSelect: (dateRange: DateRange | undefined) => void
|
|
32
33
|
selected?: DateRange
|
|
33
34
|
lng: keyof typeof availableLocales
|
|
35
|
+
type: DateType
|
|
36
|
+
required?: boolean
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
export function DateRangePicker({
|
|
@@ -39,22 +42,22 @@ export function DateRangePicker({
|
|
|
39
42
|
onSelect = () => {},
|
|
40
43
|
selected: preselected,
|
|
41
44
|
lng,
|
|
45
|
+
type,
|
|
46
|
+
required = false,
|
|
42
47
|
}: DateRangePickerProps): React.JSX.Element {
|
|
43
48
|
const manageFooterText = (): string => {
|
|
44
49
|
const hasDatesFilter = selected && selected.from && selected.to
|
|
45
|
-
const isExactDate =
|
|
46
|
-
formatDatePickerParamsDate(selected?.from) ===
|
|
47
|
-
formatDatePickerParamsDate(selected?.to)
|
|
48
50
|
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
if (type === 'single') {
|
|
52
|
+
if (!hasDatesFilter) {
|
|
53
|
+
return translations[lng].pickDay
|
|
54
|
+
}
|
|
52
55
|
return translations[lng].selectedDate.replace(
|
|
53
56
|
'${date}',
|
|
54
57
|
formatDatePickerFooterDate(selected.from, lng as string),
|
|
55
58
|
)
|
|
56
59
|
}
|
|
57
|
-
|
|
60
|
+
if (!hasDatesFilter) return translations[lng].pickDate
|
|
58
61
|
return translations[lng].selectedRangeOfDates
|
|
59
62
|
.replace(
|
|
60
63
|
'${from}',
|
|
@@ -76,11 +79,11 @@ export function DateRangePicker({
|
|
|
76
79
|
}, [preselected])
|
|
77
80
|
|
|
78
81
|
function selectDate(dateRange: DateRange | undefined) {
|
|
79
|
-
const isSingleDaySelection = dateRange && !dateRange.to
|
|
82
|
+
// const isSingleDaySelection = dateRange && !dateRange.to
|
|
80
83
|
|
|
81
|
-
if (isSingleDaySelection) {
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
+
// if (isSingleDaySelection) {
|
|
85
|
+
// dateRange.to = dateRange.from
|
|
86
|
+
// }
|
|
84
87
|
|
|
85
88
|
setSelected(dateRange)
|
|
86
89
|
onSelect(dateRange)
|
|
@@ -92,8 +95,10 @@ export function DateRangePicker({
|
|
|
92
95
|
locale={availableLocales[lng]}
|
|
93
96
|
mode="range"
|
|
94
97
|
min={1}
|
|
98
|
+
max={type === 'single' ? 1 : undefined}
|
|
99
|
+
required={required}
|
|
95
100
|
selected={selected}
|
|
96
|
-
onSelect={(dateRange) =>
|
|
101
|
+
onSelect={selectDate as (dateRange: DateRange | undefined) => void}
|
|
97
102
|
footer={footer}
|
|
98
103
|
defaultMonth={selected?.from}
|
|
99
104
|
/>
|
|
@@ -5,11 +5,13 @@ interface Translation {
|
|
|
5
5
|
export const translations: Translation = {
|
|
6
6
|
en: {
|
|
7
7
|
pickDate: 'Pick a day or a range of dates',
|
|
8
|
+
pickDay: 'Pick a day',
|
|
8
9
|
selectedDate: 'Selected date: ${date}',
|
|
9
10
|
selectedRangeOfDates: 'Selected dates range: from ${from} to ${to}',
|
|
10
11
|
},
|
|
11
12
|
es: {
|
|
12
|
-
|
|
13
|
+
picDate: 'Selecciona un día o un rango de fechas',
|
|
14
|
+
pickDay: 'Selecciona un día',
|
|
13
15
|
selectedDate: 'Fecha seleccionada: ${date}',
|
|
14
16
|
selectedRangeOfDates: 'Rango de fechas seleccionado: desde ${from} a ${to}',
|
|
15
17
|
},
|
package/src/atoms/Select.scss
CHANGED
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
@use '../settings/typography/form' as typography;
|
|
3
3
|
@use '../settings/config';
|
|
4
4
|
@use '../settings/depth';
|
|
5
|
-
@use '../settings/mixins';
|
|
6
|
-
|
|
7
|
-
$selected-option-padding: config.$space-2x config.$space-3x;
|
|
8
|
-
$selected-option-height: config.$space-10x;
|
|
9
5
|
|
|
10
6
|
.select-group {
|
|
11
7
|
display: flex;
|
|
@@ -38,7 +34,15 @@ $selected-option-height: config.$space-10x;
|
|
|
38
34
|
border: 1px solid color_alias.$neutral-color-600;
|
|
39
35
|
background: color_alias.$neutral-white;
|
|
40
36
|
@include typography.select-text;
|
|
41
|
-
|
|
37
|
+
|
|
38
|
+
> .icon {
|
|
39
|
+
> svg {
|
|
40
|
+
fill: color_alias.$primary-color-600;
|
|
41
|
+
path {
|
|
42
|
+
fill: color_alias.$primary-color-600;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
42
46
|
|
|
43
47
|
&.filled {
|
|
44
48
|
@include typography.select-option-text;
|
|
@@ -57,7 +61,15 @@ $selected-option-height: config.$space-10x;
|
|
|
57
61
|
border: 1px solid color_alias.$neutral-color-400;
|
|
58
62
|
background: color_alias.$neutral-color-50;
|
|
59
63
|
color: color_alias.$neutral-color-400;
|
|
60
|
-
|
|
64
|
+
|
|
65
|
+
> .icon {
|
|
66
|
+
> svg {
|
|
67
|
+
fill: color_alias.$neutral-color-400;
|
|
68
|
+
path {
|
|
69
|
+
fill: color_alias.$neutral-color-400;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
61
73
|
}
|
|
62
74
|
}
|
|
63
75
|
|
|
@@ -105,7 +117,6 @@ $selected-option-height: config.$space-10x;
|
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
.selected-option {
|
|
108
|
-
min-height: $selected-option-height;
|
|
109
120
|
display: flex;
|
|
110
121
|
justify-content: space-between;
|
|
111
122
|
align-items: center;
|
|
@@ -117,7 +128,7 @@ $selected-option-height: config.$space-10x;
|
|
|
117
128
|
height: config.$icon-size-3x;
|
|
118
129
|
}
|
|
119
130
|
}
|
|
120
|
-
|
|
131
|
+
|
|
121
132
|
.select-options {
|
|
122
133
|
max-height: 256px;
|
|
123
134
|
overflow-y: auto;
|
|
@@ -130,7 +141,7 @@ $selected-option-height: config.$space-10x;
|
|
|
130
141
|
width: 100%;
|
|
131
142
|
|
|
132
143
|
.search {
|
|
133
|
-
margin:
|
|
144
|
+
margin: config.$space-2x config.$space-3x;
|
|
134
145
|
}
|
|
135
146
|
|
|
136
147
|
ul {
|
|
@@ -138,13 +149,13 @@ $selected-option-height: config.$space-10x;
|
|
|
138
149
|
margin: 0;
|
|
139
150
|
padding: 0;
|
|
140
151
|
}
|
|
141
|
-
|
|
152
|
+
|
|
142
153
|
.option {
|
|
143
154
|
display: flex;
|
|
144
155
|
align-items: center;
|
|
145
156
|
cursor: default;
|
|
146
157
|
list-style-type: none;
|
|
147
|
-
padding:
|
|
158
|
+
padding: config.$space-2x config.$space-3x;
|
|
148
159
|
|
|
149
160
|
> .icon {
|
|
150
161
|
width: config.$icon-size-4x;
|
|
@@ -152,13 +163,5 @@ $selected-option-height: config.$space-10x;
|
|
|
152
163
|
margin-right: config.$space-1x;
|
|
153
164
|
}
|
|
154
165
|
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.select-loader {
|
|
159
|
-
position: absolute;
|
|
160
|
-
padding: $selected-option-padding;
|
|
161
|
-
min-height: $selected-option-height;
|
|
162
|
-
display: flex;
|
|
163
|
-
align-items: center;
|
|
166
|
+
}
|
|
164
167
|
}
|
package/src/atoms/Select.tsx
CHANGED
|
@@ -31,7 +31,6 @@ export interface SelectProps extends InputPropsWithoutOnChange {
|
|
|
31
31
|
required?: boolean
|
|
32
32
|
isSearchable?: boolean
|
|
33
33
|
searchLabel?: string
|
|
34
|
-
loading?: boolean
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
const EMPTY_OPTION = { id: '', label: '' }
|
|
@@ -49,21 +48,20 @@ export function Select({
|
|
|
49
48
|
accessibilityLabel,
|
|
50
49
|
hideLabel = false,
|
|
51
50
|
onChange = () => {},
|
|
51
|
+
defaultValue,
|
|
52
52
|
required = false,
|
|
53
53
|
isSearchable = false,
|
|
54
|
-
loading = false,
|
|
55
54
|
searchLabel = 'Search',
|
|
56
55
|
...props
|
|
57
56
|
}: SelectProps): React.JSX.Element {
|
|
58
57
|
const helpTexts = buildHelpText(helpText, errors)
|
|
59
58
|
const { isOpen, close, toggle } = useOpen()
|
|
60
59
|
const defaultOption =
|
|
61
|
-
options.find((option) => option.id ===
|
|
60
|
+
options.find((option) => option.id === defaultValue) || EMPTY_OPTION
|
|
62
61
|
const [selectedOption, setSelectedOption] = useState<Option>(defaultOption)
|
|
63
62
|
const isEmpty = selectedOption.id === EMPTY_OPTION.id
|
|
64
63
|
const selectRef = useRef(null)
|
|
65
64
|
useOutsideClick(selectRef, close)
|
|
66
|
-
const displayedValue = loading ? '' : selectedOption.label || placeholder
|
|
67
65
|
|
|
68
66
|
const cssClasses = classNames('selected-option', {
|
|
69
67
|
open: isOpen,
|
|
@@ -100,11 +98,6 @@ export function Select({
|
|
|
100
98
|
)}
|
|
101
99
|
|
|
102
100
|
<div className="select-container" ref={selectRef}>
|
|
103
|
-
{loading && (
|
|
104
|
-
<div className="select-loader">
|
|
105
|
-
<Icon name="Loading" />
|
|
106
|
-
</div>
|
|
107
|
-
)}
|
|
108
101
|
<div
|
|
109
102
|
className={cssClasses}
|
|
110
103
|
tabIndex={0}
|
|
@@ -113,7 +106,7 @@ export function Select({
|
|
|
113
106
|
aria-live="assertive"
|
|
114
107
|
role="alert"
|
|
115
108
|
>
|
|
116
|
-
<span>{
|
|
109
|
+
<span>{selectedOption.label || placeholder}</span>
|
|
117
110
|
<Icon name={isOpen ? 'AngleUp' : 'AngleDown'} visible={isEmpty} />
|
|
118
111
|
<IconButton
|
|
119
112
|
icon="Close"
|
|
@@ -123,7 +116,7 @@ export function Select({
|
|
|
123
116
|
visible={!isEmpty}
|
|
124
117
|
/>
|
|
125
118
|
</div>
|
|
126
|
-
{isOpen &&
|
|
119
|
+
{isOpen && (
|
|
127
120
|
<OptionList
|
|
128
121
|
options={options}
|
|
129
122
|
selectedOption={selectedOption}
|
|
@@ -18,6 +18,9 @@ const meta = {
|
|
|
18
18
|
selected: {
|
|
19
19
|
description: 'Selected date or date range',
|
|
20
20
|
},
|
|
21
|
+
type: {
|
|
22
|
+
description: 'Type of date picker',
|
|
23
|
+
},
|
|
21
24
|
lng: {
|
|
22
25
|
description: 'String with the locale to be used on the translations',
|
|
23
26
|
},
|
|
@@ -39,6 +42,7 @@ export const Primary: Story = {
|
|
|
39
42
|
variant: 'primary',
|
|
40
43
|
onSelect: (date) => console.log('onSelect date:', date),
|
|
41
44
|
lng: 'en',
|
|
45
|
+
type: 'range',
|
|
42
46
|
},
|
|
43
47
|
parameters: figmaPrimaryDesign,
|
|
44
48
|
}
|
|
@@ -49,6 +53,7 @@ export const WithDateRangeSelected: Story = {
|
|
|
49
53
|
onSelect: (date) => console.log('onSelect date:', date),
|
|
50
54
|
selected: { from: new Date(2024, 1, 2), to: new Date(2024, 1, 15) },
|
|
51
55
|
lng: 'en',
|
|
56
|
+
type: 'range',
|
|
52
57
|
},
|
|
53
58
|
parameters: figmaPrimaryDesign,
|
|
54
59
|
}
|
|
@@ -59,6 +64,7 @@ export const WithSingleDaySelected: Story = {
|
|
|
59
64
|
onSelect: (date) => console.log('onSelect date:', date),
|
|
60
65
|
selected: { from: new Date(2024, 1, 2), to: new Date(2024, 1, 2) },
|
|
61
66
|
lng: 'en',
|
|
67
|
+
type: 'single',
|
|
62
68
|
},
|
|
63
69
|
parameters: figmaPrimaryDesign,
|
|
64
70
|
}
|