@idealyst/datepicker 1.0.0 → 1.0.58
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 +10 -5
- package/src/DateInput/DateInput.native.tsx +80 -0
- package/src/DateInput/DateInput.styles.tsx +118 -0
- package/src/DateInput/DateInput.web.tsx +79 -0
- package/src/DateInput/DateInputBase.tsx +233 -0
- package/src/DateInput/index.native.ts +2 -0
- package/src/DateInput/index.ts +2 -0
- package/src/DateInput/types.ts +60 -0
- package/src/DatePicker/Calendar.native.tsx +180 -78
- package/src/DatePicker/Calendar.styles.tsx +73 -70
- package/src/DatePicker/DatePicker.native.tsx +24 -6
- package/src/DatePicker/DatePicker.styles.tsx +18 -11
- package/src/DatePicker/DatePicker.web.tsx +1 -1
- package/src/DatePicker/index.ts +1 -1
- package/src/DateRangePicker/RangeCalendar.native.tsx +143 -55
- package/src/DateRangePicker/RangeCalendar.styles.tsx +65 -39
- package/src/DateRangePicker/RangeCalendar.web.tsx +169 -60
- package/src/DateRangePicker/types.ts +9 -0
- package/src/DateTimePicker/DateTimePicker.native.tsx +11 -69
- package/src/DateTimePicker/DateTimePicker.tsx +12 -70
- package/src/DateTimePicker/DateTimePickerBase.tsx +204 -0
- package/src/DateTimePicker/TimePicker.native.tsx +9 -196
- package/src/DateTimePicker/TimePicker.styles.tsx +4 -2
- package/src/DateTimePicker/TimePicker.tsx +9 -401
- package/src/DateTimePicker/TimePickerBase.tsx +232 -0
- package/src/DateTimePicker/primitives/ClockFace.native.tsx +195 -0
- package/src/DateTimePicker/primitives/ClockFace.web.tsx +168 -0
- package/src/DateTimePicker/primitives/TimeInput.native.tsx +53 -0
- package/src/DateTimePicker/primitives/TimeInput.web.tsx +66 -0
- package/src/DateTimePicker/primitives/index.native.ts +2 -0
- package/src/DateTimePicker/primitives/index.ts +2 -0
- package/src/DateTimePicker/primitives/index.web.ts +2 -0
- package/src/DateTimePicker/types.ts +0 -4
- package/src/DateTimePicker/utils/dimensions.native.ts +9 -0
- package/src/DateTimePicker/utils/dimensions.ts +9 -0
- package/src/DateTimePicker/utils/dimensions.web.ts +33 -0
- package/src/DateTimeRangePicker/DateTimeRangePicker.native.tsx +10 -199
- package/src/DateTimeRangePicker/DateTimeRangePicker.styles.tsx +3 -0
- package/src/DateTimeRangePicker/DateTimeRangePicker.web.tsx +11 -131
- package/src/DateTimeRangePicker/DateTimeRangePickerBase.tsx +337 -0
- package/src/DateTimeRangePicker/types.ts +0 -2
- package/src/examples/DatePickerExamples.tsx +42 -118
- package/src/index.native.ts +4 -0
- package/src/index.ts +4 -0
- /package/src/DatePicker/{Calendar.tsx → Calendar.web.tsx} +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import React, { useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import { View, Button } from '@idealyst/components';
|
|
3
|
+
import { DateTimePickerProps } from './types';
|
|
4
|
+
import { dateTimePickerStyles } from './DateTimePicker.styles';
|
|
5
|
+
import { getDimensions, addEventListener } from './utils/dimensions';
|
|
6
|
+
|
|
7
|
+
interface DateTimePickerBaseProps extends DateTimePickerProps {
|
|
8
|
+
renderCalendar: (props: {
|
|
9
|
+
value: Date | undefined;
|
|
10
|
+
onChange: (date: Date) => void;
|
|
11
|
+
minDate?: Date;
|
|
12
|
+
maxDate?: Date;
|
|
13
|
+
disabled: boolean;
|
|
14
|
+
}) => React.ReactNode;
|
|
15
|
+
renderTimePicker: (props: {
|
|
16
|
+
value: Date;
|
|
17
|
+
onChange: (date: Date) => void;
|
|
18
|
+
disabled: boolean;
|
|
19
|
+
mode: '12h' | '24h';
|
|
20
|
+
step: number;
|
|
21
|
+
}) => React.ReactNode;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type ViewMode = 'responsive' | 'date' | 'time';
|
|
25
|
+
|
|
26
|
+
export const DateTimePickerBase: React.FC<DateTimePickerBaseProps> = ({
|
|
27
|
+
value,
|
|
28
|
+
onChange,
|
|
29
|
+
minDate,
|
|
30
|
+
maxDate,
|
|
31
|
+
disabled = false,
|
|
32
|
+
timeMode = '12h',
|
|
33
|
+
timeStep = 1,
|
|
34
|
+
style,
|
|
35
|
+
testID,
|
|
36
|
+
renderCalendar,
|
|
37
|
+
renderTimePicker,
|
|
38
|
+
}) => {
|
|
39
|
+
const [screenData, setScreenData] = useState(() => getDimensions());
|
|
40
|
+
const [viewMode, setViewMode] = useState<ViewMode>('responsive');
|
|
41
|
+
|
|
42
|
+
// Listen for screen dimension changes
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const subscription = addEventListener(({ window }) => {
|
|
45
|
+
setScreenData(window);
|
|
46
|
+
});
|
|
47
|
+
return () => subscription?.remove();
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
// Determine if we should use side-by-side layout
|
|
51
|
+
const shouldUseSideBySide = screenData.width >= 600; // Tablet width threshold
|
|
52
|
+
const canFitSideBySide = screenData.width >= 480; // Minimum for side-by-side
|
|
53
|
+
|
|
54
|
+
// Auto-adjust view mode based on screen size
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (shouldUseSideBySide) {
|
|
57
|
+
setViewMode('responsive');
|
|
58
|
+
} else if (viewMode === 'responsive' && !canFitSideBySide) {
|
|
59
|
+
setViewMode('date');
|
|
60
|
+
}
|
|
61
|
+
}, [shouldUseSideBySide, canFitSideBySide, viewMode]);
|
|
62
|
+
|
|
63
|
+
const handleDateChange = useCallback((newDate: Date) => {
|
|
64
|
+
if (value) {
|
|
65
|
+
// Preserve the time from current value
|
|
66
|
+
const updatedDate = new Date(newDate);
|
|
67
|
+
updatedDate.setHours(value.getHours(), value.getMinutes(), value.getSeconds());
|
|
68
|
+
onChange(updatedDate);
|
|
69
|
+
} else {
|
|
70
|
+
onChange(newDate);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Auto-advance to time selection on small screens after date selection
|
|
74
|
+
if (!canFitSideBySide && viewMode === 'date') {
|
|
75
|
+
setViewMode('time');
|
|
76
|
+
}
|
|
77
|
+
}, [value, onChange, canFitSideBySide, viewMode]);
|
|
78
|
+
|
|
79
|
+
const handleTimeChange = useCallback((newTime: Date) => {
|
|
80
|
+
if (value) {
|
|
81
|
+
// Update time while preserving the date
|
|
82
|
+
const updatedDate = new Date(value);
|
|
83
|
+
updatedDate.setHours(newTime.getHours(), newTime.getMinutes(), newTime.getSeconds());
|
|
84
|
+
onChange(updatedDate);
|
|
85
|
+
} else {
|
|
86
|
+
// If no date is selected, use today's date with the new time
|
|
87
|
+
const today = new Date();
|
|
88
|
+
today.setHours(newTime.getHours(), newTime.getMinutes(), newTime.getSeconds());
|
|
89
|
+
onChange(today);
|
|
90
|
+
}
|
|
91
|
+
}, [value, onChange]);
|
|
92
|
+
|
|
93
|
+
// Side-by-side layout for larger screens
|
|
94
|
+
if (viewMode === 'responsive' && shouldUseSideBySide) {
|
|
95
|
+
return (
|
|
96
|
+
<View style={[dateTimePickerStyles.container, style]} testID={testID} data-testid={testID}>
|
|
97
|
+
{/* Side by side layout */}
|
|
98
|
+
<View style={{
|
|
99
|
+
flexDirection: 'row',
|
|
100
|
+
gap: 16,
|
|
101
|
+
alignItems: 'flex-start',
|
|
102
|
+
_web: {
|
|
103
|
+
display: 'flex',
|
|
104
|
+
flexDirection: 'row',
|
|
105
|
+
gap: 16,
|
|
106
|
+
alignItems: 'flex-start',
|
|
107
|
+
}
|
|
108
|
+
}}>
|
|
109
|
+
{renderCalendar({
|
|
110
|
+
value,
|
|
111
|
+
onChange: handleDateChange,
|
|
112
|
+
minDate,
|
|
113
|
+
maxDate,
|
|
114
|
+
disabled,
|
|
115
|
+
})}
|
|
116
|
+
|
|
117
|
+
{renderTimePicker({
|
|
118
|
+
value: value || new Date(),
|
|
119
|
+
onChange: handleTimeChange,
|
|
120
|
+
disabled,
|
|
121
|
+
mode: timeMode,
|
|
122
|
+
step: timeStep,
|
|
123
|
+
})}
|
|
124
|
+
</View>
|
|
125
|
+
</View>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Step-by-step layout for smaller screens
|
|
130
|
+
const isDateStep = viewMode === 'date';
|
|
131
|
+
const isTimeStep = viewMode === 'time';
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<View style={[dateTimePickerStyles.container, style]} testID={testID} data-testid={testID}>
|
|
135
|
+
{/* Step Navigation */}
|
|
136
|
+
<View style={{
|
|
137
|
+
flexDirection: 'row',
|
|
138
|
+
gap: 8,
|
|
139
|
+
marginBottom: 8,
|
|
140
|
+
_web: {
|
|
141
|
+
display: 'flex',
|
|
142
|
+
flexDirection: 'row',
|
|
143
|
+
gap: 8,
|
|
144
|
+
}
|
|
145
|
+
}}>
|
|
146
|
+
<Button
|
|
147
|
+
variant={isDateStep ? 'primary' : 'outlined'}
|
|
148
|
+
size="small"
|
|
149
|
+
onPress={() => setViewMode('date')}
|
|
150
|
+
disabled={disabled}
|
|
151
|
+
style={{ flex: 1 }}
|
|
152
|
+
>
|
|
153
|
+
1. Date
|
|
154
|
+
</Button>
|
|
155
|
+
<Button
|
|
156
|
+
variant={isTimeStep ? 'primary' : 'outlined'}
|
|
157
|
+
size="small"
|
|
158
|
+
onPress={() => setViewMode('time')}
|
|
159
|
+
disabled={disabled || !value}
|
|
160
|
+
style={{ flex: 1 }}
|
|
161
|
+
>
|
|
162
|
+
2. Time
|
|
163
|
+
</Button>
|
|
164
|
+
</View>
|
|
165
|
+
|
|
166
|
+
{/* Step Content */}
|
|
167
|
+
{isDateStep && (
|
|
168
|
+
<View>
|
|
169
|
+
{renderCalendar({
|
|
170
|
+
value,
|
|
171
|
+
onChange: handleDateChange,
|
|
172
|
+
minDate,
|
|
173
|
+
maxDate,
|
|
174
|
+
disabled,
|
|
175
|
+
})}
|
|
176
|
+
</View>
|
|
177
|
+
)}
|
|
178
|
+
|
|
179
|
+
{isTimeStep && (
|
|
180
|
+
<View>
|
|
181
|
+
{renderTimePicker({
|
|
182
|
+
value: value || new Date(),
|
|
183
|
+
onChange: handleTimeChange,
|
|
184
|
+
disabled,
|
|
185
|
+
mode: timeMode,
|
|
186
|
+
step: timeStep,
|
|
187
|
+
})}
|
|
188
|
+
|
|
189
|
+
{/* Back to Date button */}
|
|
190
|
+
<View style={{ marginTop: 12, alignItems: 'flex-start' }}>
|
|
191
|
+
<Button
|
|
192
|
+
variant="text"
|
|
193
|
+
size="small"
|
|
194
|
+
onPress={() => setViewMode('date')}
|
|
195
|
+
disabled={disabled}
|
|
196
|
+
>
|
|
197
|
+
← Back to Date
|
|
198
|
+
</Button>
|
|
199
|
+
</View>
|
|
200
|
+
</View>
|
|
201
|
+
)}
|
|
202
|
+
</View>
|
|
203
|
+
);
|
|
204
|
+
};
|
|
@@ -1,204 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { View, Text, Button } from '@idealyst/components';
|
|
3
2
|
import { TimePickerProps } from './types';
|
|
3
|
+
import { TimePickerBase } from './TimePickerBase';
|
|
4
|
+
import { ClockFace, TimeInput } from './primitives';
|
|
4
5
|
import { timePickerStyles } from './TimePicker.styles';
|
|
5
6
|
|
|
6
|
-
export const TimePicker: React.FC<TimePickerProps> = ({
|
|
7
|
-
value = new Date(),
|
|
8
|
-
onChange,
|
|
9
|
-
disabled = false,
|
|
10
|
-
mode = '12h',
|
|
11
|
-
showSeconds = false,
|
|
12
|
-
step = 1,
|
|
13
|
-
style,
|
|
14
|
-
testID,
|
|
15
|
-
}) => {
|
|
16
|
-
const hours = value.getHours();
|
|
17
|
-
const minutes = value.getMinutes();
|
|
18
|
-
const seconds = value.getSeconds();
|
|
19
|
-
|
|
20
|
-
const displayHours = mode === '12h' ? (hours === 0 ? 12 : hours > 12 ? hours - 12 : hours) : hours;
|
|
21
|
-
const ampm = mode === '12h' ? (hours >= 12 ? 'PM' : 'AM') : null;
|
|
22
|
-
|
|
23
|
-
const updateTime = (newHours: number, newMinutes: number, newSeconds?: number) => {
|
|
24
|
-
const newDate = new Date(value);
|
|
25
|
-
newDate.setHours(newHours, newMinutes, newSeconds || 0);
|
|
26
|
-
onChange(newDate);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const handleHourChange = (delta: number) => {
|
|
30
|
-
let newHours = hours + delta;
|
|
31
|
-
if (mode === '12h') {
|
|
32
|
-
if (newHours < 0) newHours = 23;
|
|
33
|
-
if (newHours > 23) newHours = 0;
|
|
34
|
-
} else {
|
|
35
|
-
if (newHours < 0) newHours = 23;
|
|
36
|
-
if (newHours > 23) newHours = 0;
|
|
37
|
-
}
|
|
38
|
-
updateTime(newHours, minutes, seconds);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const handleMinuteChange = (delta: number) => {
|
|
42
|
-
let newMinutes = minutes + (delta * step);
|
|
43
|
-
let newHours = hours;
|
|
44
|
-
|
|
45
|
-
if (newMinutes < 0) {
|
|
46
|
-
newMinutes = 60 + newMinutes;
|
|
47
|
-
newHours = hours - 1;
|
|
48
|
-
if (newHours < 0) newHours = 23;
|
|
49
|
-
} else if (newMinutes >= 60) {
|
|
50
|
-
newMinutes = newMinutes - 60;
|
|
51
|
-
newHours = hours + 1;
|
|
52
|
-
if (newHours > 23) newHours = 0;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
updateTime(newHours, newMinutes, seconds);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const handleSecondChange = (delta: number) => {
|
|
59
|
-
let newSeconds = seconds + delta;
|
|
60
|
-
let newMinutes = minutes;
|
|
61
|
-
let newHours = hours;
|
|
62
|
-
|
|
63
|
-
if (newSeconds < 0) {
|
|
64
|
-
newSeconds = 59;
|
|
65
|
-
newMinutes = minutes - 1;
|
|
66
|
-
if (newMinutes < 0) {
|
|
67
|
-
newMinutes = 59;
|
|
68
|
-
newHours = hours - 1;
|
|
69
|
-
if (newHours < 0) newHours = 23;
|
|
70
|
-
}
|
|
71
|
-
} else if (newSeconds >= 60) {
|
|
72
|
-
newSeconds = 0;
|
|
73
|
-
newMinutes = minutes + 1;
|
|
74
|
-
if (newMinutes >= 60) {
|
|
75
|
-
newMinutes = 0;
|
|
76
|
-
newHours = hours + 1;
|
|
77
|
-
if (newHours > 23) newHours = 0;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
updateTime(newHours, newMinutes, newSeconds);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const toggleAmPm = () => {
|
|
85
|
-
if (mode === '12h') {
|
|
86
|
-
const newHours = hours >= 12 ? hours - 12 : hours + 12;
|
|
87
|
-
updateTime(newHours, minutes, seconds);
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
7
|
+
export const TimePicker: React.FC<TimePickerProps> = (props) => {
|
|
91
8
|
timePickerStyles.useVariants({});
|
|
92
|
-
|
|
9
|
+
|
|
93
10
|
return (
|
|
94
|
-
<
|
|
95
|
-
{
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
variant="text"
|
|
100
|
-
size="small"
|
|
101
|
-
onPress={() => handleHourChange(1)}
|
|
102
|
-
disabled={disabled}
|
|
103
|
-
style={timePickerStyles.stepperButton}
|
|
104
|
-
>
|
|
105
|
-
<Text style={timePickerStyles.stepperText}>▲</Text>
|
|
106
|
-
</Button>
|
|
107
|
-
<View style={timePickerStyles.timeInput}>
|
|
108
|
-
<Text style={{ textAlign: 'center', fontSize: 16, fontWeight: '600' }}>
|
|
109
|
-
{String(displayHours).padStart(2, '0')}
|
|
110
|
-
</Text>
|
|
111
|
-
</View>
|
|
112
|
-
<Button
|
|
113
|
-
variant="text"
|
|
114
|
-
size="small"
|
|
115
|
-
onPress={() => handleHourChange(-1)}
|
|
116
|
-
disabled={disabled}
|
|
117
|
-
style={timePickerStyles.stepperButton}
|
|
118
|
-
>
|
|
119
|
-
<Text style={timePickerStyles.stepperText}>▼</Text>
|
|
120
|
-
</Button>
|
|
121
|
-
</View>
|
|
122
|
-
</View>
|
|
123
|
-
|
|
124
|
-
{/* Separator */}
|
|
125
|
-
<Text style={timePickerStyles.timeSeparator}>:</Text>
|
|
126
|
-
|
|
127
|
-
{/* Minutes */}
|
|
128
|
-
<View style={timePickerStyles.timeSection}>
|
|
129
|
-
<View style={timePickerStyles.stepperContainer}>
|
|
130
|
-
<Button
|
|
131
|
-
variant="text"
|
|
132
|
-
size="small"
|
|
133
|
-
onPress={() => handleMinuteChange(1)}
|
|
134
|
-
disabled={disabled}
|
|
135
|
-
style={timePickerStyles.stepperButton}
|
|
136
|
-
>
|
|
137
|
-
<Text style={timePickerStyles.stepperText}>▲</Text>
|
|
138
|
-
</Button>
|
|
139
|
-
<View style={timePickerStyles.timeInput}>
|
|
140
|
-
<Text style={{ textAlign: 'center', fontSize: 16, fontWeight: '600' }}>
|
|
141
|
-
{String(minutes).padStart(2, '0')}
|
|
142
|
-
</Text>
|
|
143
|
-
</View>
|
|
144
|
-
<Button
|
|
145
|
-
variant="text"
|
|
146
|
-
size="small"
|
|
147
|
-
onPress={() => handleMinuteChange(-1)}
|
|
148
|
-
disabled={disabled}
|
|
149
|
-
style={timePickerStyles.stepperButton}
|
|
150
|
-
>
|
|
151
|
-
<Text style={timePickerStyles.stepperText}>▼</Text>
|
|
152
|
-
</Button>
|
|
153
|
-
</View>
|
|
154
|
-
</View>
|
|
155
|
-
|
|
156
|
-
{/* Seconds */}
|
|
157
|
-
{showSeconds && (
|
|
158
|
-
<>
|
|
159
|
-
<Text style={timePickerStyles.timeSeparator}>:</Text>
|
|
160
|
-
<View style={timePickerStyles.timeSection}>
|
|
161
|
-
<View style={timePickerStyles.stepperContainer}>
|
|
162
|
-
<Button
|
|
163
|
-
variant="text"
|
|
164
|
-
size="small"
|
|
165
|
-
onPress={() => handleSecondChange(1)}
|
|
166
|
-
disabled={disabled}
|
|
167
|
-
style={timePickerStyles.stepperButton}
|
|
168
|
-
>
|
|
169
|
-
<Text style={timePickerStyles.stepperText}>▲</Text>
|
|
170
|
-
</Button>
|
|
171
|
-
<View style={timePickerStyles.timeInput}>
|
|
172
|
-
<Text style={{ textAlign: 'center', fontSize: 16, fontWeight: '600' }}>
|
|
173
|
-
{String(seconds).padStart(2, '0')}
|
|
174
|
-
</Text>
|
|
175
|
-
</View>
|
|
176
|
-
<Button
|
|
177
|
-
variant="text"
|
|
178
|
-
size="small"
|
|
179
|
-
onPress={() => handleSecondChange(-1)}
|
|
180
|
-
disabled={disabled}
|
|
181
|
-
style={timePickerStyles.stepperButton}
|
|
182
|
-
>
|
|
183
|
-
<Text style={timePickerStyles.stepperText}>▼</Text>
|
|
184
|
-
</Button>
|
|
185
|
-
</View>
|
|
186
|
-
</View>
|
|
187
|
-
</>
|
|
188
|
-
)}
|
|
189
|
-
|
|
190
|
-
{/* AM/PM */}
|
|
191
|
-
{mode === '12h' && ampm && (
|
|
192
|
-
<Button
|
|
193
|
-
variant="outlined"
|
|
194
|
-
size="small"
|
|
195
|
-
onPress={toggleAmPm}
|
|
196
|
-
disabled={disabled}
|
|
197
|
-
style={timePickerStyles.ampmButton}
|
|
198
|
-
>
|
|
199
|
-
{ampm}
|
|
200
|
-
</Button>
|
|
201
|
-
)}
|
|
202
|
-
</View>
|
|
11
|
+
<TimePickerBase
|
|
12
|
+
{...props}
|
|
13
|
+
renderClock={(clockProps) => <ClockFace {...clockProps} />}
|
|
14
|
+
renderTimeInput={(inputProps) => <TimeInput {...inputProps} />}
|
|
15
|
+
/>
|
|
203
16
|
);
|
|
204
17
|
};
|
|
@@ -36,8 +36,8 @@ export const timePickerStyles = StyleSheet.create((theme) => ({
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
timeInput: {
|
|
39
|
-
width:
|
|
40
|
-
height:
|
|
39
|
+
width: 44,
|
|
40
|
+
height: 40,
|
|
41
41
|
textAlign: 'center',
|
|
42
42
|
fontSize: 16,
|
|
43
43
|
fontWeight: '600',
|
|
@@ -46,6 +46,8 @@ export const timePickerStyles = StyleSheet.create((theme) => ({
|
|
|
46
46
|
borderBottomWidth: 0,
|
|
47
47
|
borderRadius: 0,
|
|
48
48
|
backgroundColor: 'transparent',
|
|
49
|
+
paddingHorizontal: 0,
|
|
50
|
+
paddingVertical: 0,
|
|
49
51
|
|
|
50
52
|
_web: {
|
|
51
53
|
border: 'none',
|