@scripso-homepad/ui 0.4.2 → 0.4.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/dist/{chunk-WDSMJWKC.js → chunk-66WR57JJ.js} +35 -3
- package/dist/chunk-66WR57JJ.js.map +1 -0
- package/dist/index.cjs +2258 -384
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +134 -1
- package/dist/index.d.ts +134 -1
- package/dist/index.js +1959 -97
- package/dist/index.js.map +1 -1
- package/dist/web/index.cjs +30650 -1009
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.css +78 -0
- package/dist/web/index.css.map +1 -0
- package/dist/web/index.d.cts +267 -6
- package/dist/web/index.d.ts +267 -6
- package/dist/web/index.js +30179 -601
- package/dist/web/index.js.map +1 -1
- package/package.json +5 -4
- package/src/components/Calendar.stories.tsx +337 -0
- package/src/components/Calendar.tsx +441 -0
- package/src/components/DatePicker.stories.tsx +219 -0
- package/src/components/DatePicker.tsx +366 -0
- package/src/components/Select.stories.tsx +134 -0
- package/src/components/Select.tsx +465 -0
- package/src/css.d.ts +1 -0
- package/src/icons/CalendarIcon.tsx +28 -0
- package/src/icons/CalendarIcon.web.tsx +34 -0
- package/src/icons/ChevronDownIcon.tsx +11 -4
- package/src/icons/ChevronDownIcon.web.tsx +6 -4
- package/src/icons/ChevronNavIcons.tsx +44 -0
- package/src/icons/ChevronNavIcons.web.tsx +57 -0
- package/src/icons/calendarIconPaths.ts +2 -0
- package/src/icons/chevronDownPath.ts +1 -0
- package/src/icons/chevronNavPaths.ts +2 -0
- package/src/index.ts +41 -0
- package/src/theme/calendar.ts +357 -0
- package/src/theme/select.ts +247 -0
- package/src/utils/calendarDays.ts +273 -0
- package/src/utils/calendarLocaleContext.tsx +95 -0
- package/src/utils/calendarLocalization.ts +187 -0
- package/src/utils/countryDropdownScrollStyles.ts +53 -13
- package/src/utils/formatMultiSelectDisplay.ts +56 -0
- package/src/web/components/Badge.stories.tsx +43 -0
- package/src/web/components/Badge.tsx +35 -0
- package/src/web/components/Pagination.stories.tsx +78 -0
- package/src/web/components/Pagination.tsx +153 -0
- package/src/web/components/StatusBadge.tsx +20 -0
- package/src/web/components/Table.stories.tsx +415 -0
- package/src/web/components/Table.tsx +3 -0
- package/src/web/components/TableActionButton.tsx +67 -0
- package/src/web/components/TableActionsMenu.tsx +208 -0
- package/src/web/components/TableIconText.tsx +23 -0
- package/src/web/components/TableRowStatusActions.tsx +33 -0
- package/src/web/components/TableStatusActionsCell.tsx +29 -0
- package/src/web/components/pagination-utils.ts +39 -0
- package/src/web/components/table/DataTable.tsx +123 -0
- package/src/web/components/table/TablePrimitives.tsx +214 -0
- package/src/web/components/table/TableScrollArea.tsx +51 -0
- package/src/web/components/table/constants.ts +59 -0
- package/src/web/components/table/data-table-class-names.ts +26 -0
- package/src/web/components/table/index.ts +44 -0
- package/src/web/components/table/table-row-context.tsx +19 -0
- package/src/web/components/table/use-horizontal-scroll-state.ts +72 -0
- package/src/web/components/table-scroll.css +81 -0
- package/src/web/hooks/useOnClickOutside.ts +20 -5
- package/src/web/icons/TableMenuActivateIcon.tsx +27 -0
- package/src/web/icons/TableMenuCheckIcon.tsx +27 -0
- package/src/web/icons/TableMenuCloseIcon.tsx +27 -0
- package/src/web/icons/TableMenuEditIcon.tsx +27 -0
- package/src/web/icons/TableMenuInfoIcon.tsx +27 -0
- package/src/web/icons/TableMenuRefreshIcon.tsx +27 -0
- package/src/web/icons/TableMenuSuspendIcon.tsx +34 -0
- package/src/web/icons/TableMenuTrashIcon.tsx +27 -0
- package/src/web/icons/TableMoreIcon.tsx +41 -0
- package/src/web/icons/TableSortIcon.tsx +37 -0
- package/src/web/index.ts +74 -0
- package/src/web/layout/AppHeader.stories.tsx +2 -0
- package/src/web/layout/AppHeader.tsx +18 -14
- package/src/web/layout/DashboardLayout.stories.tsx +1 -0
- package/src/web/layout/DashboardLayout.tsx +4 -4
- package/src/web/layout/story-helpers.tsx +10 -2
- package/dist/chunk-WDSMJWKC.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -8,12 +8,53 @@ export type {
|
|
|
8
8
|
export { Input } from "./components/Input";
|
|
9
9
|
export type { InputProps } from "./components/Input";
|
|
10
10
|
|
|
11
|
+
export { Select } from "./components/Select";
|
|
12
|
+
export type {
|
|
13
|
+
MultipleSelectProps,
|
|
14
|
+
SelectOption,
|
|
15
|
+
SelectProps,
|
|
16
|
+
SingleSelectProps,
|
|
17
|
+
} from "./components/Select";
|
|
18
|
+
|
|
11
19
|
export { PhoneInput } from "./components/PhoneInput";
|
|
12
20
|
export type { PhoneInputProps } from "./components/PhoneInput";
|
|
13
21
|
|
|
14
22
|
export { CountryCodeSelector } from "./components/CountryCodeSelector";
|
|
15
23
|
export type { CountryCodeSelectorProps } from "./components/CountryCodeSelector";
|
|
16
24
|
|
|
25
|
+
export { Calendar } from "./components/Calendar";
|
|
26
|
+
export type {
|
|
27
|
+
CalendarLabels,
|
|
28
|
+
CalendarProps,
|
|
29
|
+
CalendarRangeProps,
|
|
30
|
+
CalendarSingleProps,
|
|
31
|
+
DateRange,
|
|
32
|
+
} from "./components/Calendar";
|
|
33
|
+
export { CalendarLocaleProvider, useCalendarLocale } from "./utils/calendarLocaleContext";
|
|
34
|
+
export {
|
|
35
|
+
calendarTranslations,
|
|
36
|
+
formatLocalizedCalendarMonthYear,
|
|
37
|
+
getCalendarMonthLabels,
|
|
38
|
+
getCalendarTranslations,
|
|
39
|
+
resolveCalendarLocale,
|
|
40
|
+
resolveWeekdayLabels,
|
|
41
|
+
} from "./utils/calendarLocalization";
|
|
42
|
+
export type { CalendarLocaleProviderProps } from "./utils/calendarLocaleContext";
|
|
43
|
+
export type {
|
|
44
|
+
CalendarLocale,
|
|
45
|
+
CalendarTranslations,
|
|
46
|
+
CalendarTranslationKey,
|
|
47
|
+
} from "./utils/calendarLocalization";
|
|
48
|
+
|
|
49
|
+
export { DatePicker } from "./components/DatePicker";
|
|
50
|
+
export type {
|
|
51
|
+
DatePickerProps,
|
|
52
|
+
DatePickerRangeProps,
|
|
53
|
+
DatePickerSingleProps,
|
|
54
|
+
} from "./components/DatePicker";
|
|
55
|
+
|
|
56
|
+
export { CalendarIcon } from "./icons/CalendarIcon";
|
|
57
|
+
|
|
17
58
|
export {
|
|
18
59
|
countries,
|
|
19
60
|
defaultCountry,
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { Dimensions, Platform, StyleSheet, type TextStyle, type ViewStyle } from "react-native";
|
|
2
|
+
import { colors, fonts, fontSize, fontWeight, radii, spacing } from "./tokens";
|
|
3
|
+
|
|
4
|
+
export const CALENDAR_DROPDOWN_GAP = spacing.sm;
|
|
5
|
+
export const CALENDAR_PANEL_WIDTH = 296;
|
|
6
|
+
export const CALENDAR_PANEL_PADDING = spacing.md;
|
|
7
|
+
export const CALENDAR_PANEL_GAP = spacing.md;
|
|
8
|
+
export const CALENDAR_CONTENT_WIDTH =
|
|
9
|
+
CALENDAR_PANEL_WIDTH - CALENDAR_PANEL_PADDING * 2;
|
|
10
|
+
export const CALENDAR_HEADER_HEIGHT = 20;
|
|
11
|
+
export const CALENDAR_WEEKDAY_CELL_SIZE = 32;
|
|
12
|
+
export const CALENDAR_WEEKDAY_GAP = spacing.sm;
|
|
13
|
+
export const CALENDAR_WEEKDAY_RADIUS = 6;
|
|
14
|
+
export const CALENDAR_DAY_SIZE = CALENDAR_WEEKDAY_CELL_SIZE;
|
|
15
|
+
export const CALENDAR_DAY_GRID_WIDTH = CALENDAR_CONTENT_WIDTH;
|
|
16
|
+
export const CALENDAR_DAY_GAP_X = spacing.sm;
|
|
17
|
+
export const CALENDAR_DAY_GAP_Y = spacing.lg;
|
|
18
|
+
export const CALENDAR_DAY_ROWS = 6;
|
|
19
|
+
export const CALENDAR_DAY_GRID_HEIGHT =
|
|
20
|
+
CALENDAR_DAY_SIZE * CALENDAR_DAY_ROWS + CALENDAR_DAY_GAP_Y * (CALENDAR_DAY_ROWS - 1);
|
|
21
|
+
export const CALENDAR_PICKER_COLUMNS = 3;
|
|
22
|
+
export const CALENDAR_PICKER_ROWS = 4;
|
|
23
|
+
export const CALENDAR_YEARS_PER_PAGE = 12;
|
|
24
|
+
export const CALENDAR_PICKER_CELL_WIDTH =
|
|
25
|
+
(CALENDAR_DAY_GRID_WIDTH - CALENDAR_DAY_GAP_X * (CALENDAR_PICKER_COLUMNS - 1)) /
|
|
26
|
+
CALENDAR_PICKER_COLUMNS;
|
|
27
|
+
export const CALENDAR_PICKER_CELL_HEIGHT = 36;
|
|
28
|
+
export const CALENDAR_PICKER_BODY_HEIGHT =
|
|
29
|
+
CALENDAR_WEEKDAY_CELL_SIZE + CALENDAR_WEEKDAY_GAP + CALENDAR_DAY_GRID_HEIGHT;
|
|
30
|
+
export const CALENDAR_DAY_DOT_SIZE = 3;
|
|
31
|
+
export const CALENDAR_TODAY_TEXT_COLOR = "#082640";
|
|
32
|
+
export const CALENDAR_TODAY_DOT_COLOR = "#0033A0";
|
|
33
|
+
export const CALENDAR_NAV_ICON_SIZE = 20;
|
|
34
|
+
export const CALENDAR_NAV_ICON_COLOR = colors.stormGray850;
|
|
35
|
+
export const CALENDAR_FIELD_ICON_SIZE = 20;
|
|
36
|
+
export const CALENDAR_FIELD_WIDTH = CALENDAR_PANEL_WIDTH;
|
|
37
|
+
export const CALENDAR_FIELD_HEIGHT = 52;
|
|
38
|
+
export const CALENDAR_FIELD_PADDING = spacing.lg;
|
|
39
|
+
export const CALENDAR_FIELD_GAP = spacing.sm;
|
|
40
|
+
export const CALENDAR_FIELD_PLACEHOLDER_COLOR = colors.stormGray200;
|
|
41
|
+
|
|
42
|
+
/** @deprecated Use `CALENDAR_PANEL_WIDTH` */
|
|
43
|
+
export const CALENDAR_PANEL_MIN_WIDTH = CALENDAR_PANEL_WIDTH;
|
|
44
|
+
|
|
45
|
+
export const CALENDAR_PANEL_TOTAL_HEIGHT =
|
|
46
|
+
CALENDAR_PANEL_PADDING * 2 +
|
|
47
|
+
CALENDAR_HEADER_HEIGHT +
|
|
48
|
+
CALENDAR_PANEL_GAP * 2 +
|
|
49
|
+
CALENDAR_WEEKDAY_CELL_SIZE +
|
|
50
|
+
CALENDAR_DAY_GRID_HEIGHT;
|
|
51
|
+
export const CALENDAR_PANEL_HEIGHT = CALENDAR_PANEL_TOTAL_HEIGHT;
|
|
52
|
+
|
|
53
|
+
export const calendarLabelTypography = {
|
|
54
|
+
fontFamily: fonts.sans,
|
|
55
|
+
fontSize: fontSize.sm,
|
|
56
|
+
fontWeight: fontWeight.medium,
|
|
57
|
+
lineHeight: fontSize.sm,
|
|
58
|
+
letterSpacing: 0,
|
|
59
|
+
color: colors.slateBlue,
|
|
60
|
+
} as const;
|
|
61
|
+
|
|
62
|
+
export const calendarFieldTypography = {
|
|
63
|
+
fontFamily: fonts.sans,
|
|
64
|
+
fontSize: fontSize.md,
|
|
65
|
+
fontWeight: fontWeight.regular,
|
|
66
|
+
lineHeight: fontSize.md,
|
|
67
|
+
letterSpacing: 0,
|
|
68
|
+
textAlign: "left",
|
|
69
|
+
} as const;
|
|
70
|
+
|
|
71
|
+
export const calendarFieldPlaceholderTypography = {
|
|
72
|
+
...calendarFieldTypography,
|
|
73
|
+
color: CALENDAR_FIELD_PLACEHOLDER_COLOR,
|
|
74
|
+
} as const;
|
|
75
|
+
|
|
76
|
+
export const calendarDropdownMetrics = StyleSheet.create({
|
|
77
|
+
panel: {
|
|
78
|
+
width: CALENDAR_PANEL_WIDTH,
|
|
79
|
+
height: CALENDAR_PANEL_HEIGHT,
|
|
80
|
+
borderRadius: radii.lg,
|
|
81
|
+
borderWidth: 1,
|
|
82
|
+
borderColor: colors.stormGray50,
|
|
83
|
+
backgroundColor: colors.white,
|
|
84
|
+
padding: CALENDAR_PANEL_PADDING,
|
|
85
|
+
gap: CALENDAR_PANEL_GAP,
|
|
86
|
+
overflow: "hidden",
|
|
87
|
+
flexDirection: "column",
|
|
88
|
+
opacity: 1,
|
|
89
|
+
...(Platform.OS === "web"
|
|
90
|
+
? ({
|
|
91
|
+
boxSizing: "border-box",
|
|
92
|
+
} as ViewStyle)
|
|
93
|
+
: null),
|
|
94
|
+
},
|
|
95
|
+
header: {
|
|
96
|
+
flexDirection: "row",
|
|
97
|
+
alignItems: "center",
|
|
98
|
+
justifyContent: "space-between",
|
|
99
|
+
height: CALENDAR_HEADER_HEIGHT,
|
|
100
|
+
minHeight: CALENDAR_HEADER_HEIGHT,
|
|
101
|
+
maxHeight: CALENDAR_HEADER_HEIGHT,
|
|
102
|
+
},
|
|
103
|
+
headerTitle: {
|
|
104
|
+
textAlign: "center",
|
|
105
|
+
fontFamily: fonts.sans,
|
|
106
|
+
fontSize: fontSize.md,
|
|
107
|
+
fontWeight: fontWeight.bold,
|
|
108
|
+
lineHeight: 18,
|
|
109
|
+
letterSpacing: 0,
|
|
110
|
+
color: colors.stormGray850,
|
|
111
|
+
},
|
|
112
|
+
headerTitlePressable: {
|
|
113
|
+
flex: 1,
|
|
114
|
+
alignItems: "center",
|
|
115
|
+
justifyContent: "center",
|
|
116
|
+
minHeight: CALENDAR_HEADER_HEIGHT,
|
|
117
|
+
},
|
|
118
|
+
navButton: {
|
|
119
|
+
width: CALENDAR_NAV_ICON_SIZE,
|
|
120
|
+
height: CALENDAR_NAV_ICON_SIZE,
|
|
121
|
+
alignItems: "center",
|
|
122
|
+
justifyContent: "center",
|
|
123
|
+
},
|
|
124
|
+
weekdayRow: {
|
|
125
|
+
flexDirection: "row",
|
|
126
|
+
gap: CALENDAR_WEEKDAY_GAP,
|
|
127
|
+
height: CALENDAR_WEEKDAY_CELL_SIZE,
|
|
128
|
+
minHeight: CALENDAR_WEEKDAY_CELL_SIZE,
|
|
129
|
+
maxHeight: CALENDAR_WEEKDAY_CELL_SIZE,
|
|
130
|
+
opacity: 1,
|
|
131
|
+
},
|
|
132
|
+
weekdayCell: {
|
|
133
|
+
width: CALENDAR_WEEKDAY_CELL_SIZE,
|
|
134
|
+
height: CALENDAR_WEEKDAY_CELL_SIZE,
|
|
135
|
+
borderRadius: CALENDAR_WEEKDAY_RADIUS,
|
|
136
|
+
padding: spacing.xs,
|
|
137
|
+
backgroundColor: colors.stormGray0,
|
|
138
|
+
alignItems: "center",
|
|
139
|
+
justifyContent: "center",
|
|
140
|
+
opacity: 1,
|
|
141
|
+
...(Platform.OS === "web"
|
|
142
|
+
? ({
|
|
143
|
+
boxSizing: "border-box",
|
|
144
|
+
} as ViewStyle)
|
|
145
|
+
: null),
|
|
146
|
+
},
|
|
147
|
+
weekdayLabel: {
|
|
148
|
+
fontFamily: fonts.sans,
|
|
149
|
+
fontSize: fontSize.sm,
|
|
150
|
+
fontWeight: fontWeight.regular,
|
|
151
|
+
lineHeight: fontSize.sm,
|
|
152
|
+
letterSpacing: 0,
|
|
153
|
+
textAlign: "center",
|
|
154
|
+
color: colors.stormGray300,
|
|
155
|
+
textTransform: "uppercase",
|
|
156
|
+
},
|
|
157
|
+
dayGrid: {
|
|
158
|
+
width: CALENDAR_DAY_GRID_WIDTH,
|
|
159
|
+
height: CALENDAR_DAY_GRID_HEIGHT,
|
|
160
|
+
flexDirection: "row",
|
|
161
|
+
flexWrap: "wrap",
|
|
162
|
+
columnGap: CALENDAR_DAY_GAP_X,
|
|
163
|
+
rowGap: CALENDAR_DAY_GAP_Y,
|
|
164
|
+
alignContent: "flex-start",
|
|
165
|
+
opacity: 1,
|
|
166
|
+
},
|
|
167
|
+
dayCell: {
|
|
168
|
+
width: CALENDAR_DAY_SIZE,
|
|
169
|
+
height: CALENDAR_DAY_SIZE,
|
|
170
|
+
minHeight: CALENDAR_DAY_SIZE,
|
|
171
|
+
maxHeight: CALENDAR_DAY_SIZE,
|
|
172
|
+
alignItems: "center",
|
|
173
|
+
justifyContent: "center",
|
|
174
|
+
borderRadius: CALENDAR_WEEKDAY_RADIUS,
|
|
175
|
+
padding: spacing.xs,
|
|
176
|
+
backgroundColor: colors.white,
|
|
177
|
+
opacity: 1,
|
|
178
|
+
position: "relative",
|
|
179
|
+
...(Platform.OS === "web"
|
|
180
|
+
? ({
|
|
181
|
+
boxSizing: "border-box",
|
|
182
|
+
} as ViewStyle)
|
|
183
|
+
: null),
|
|
184
|
+
},
|
|
185
|
+
dayCellPast: {
|
|
186
|
+
backgroundColor: colors.stormGray50,
|
|
187
|
+
},
|
|
188
|
+
dayCellSelected: {
|
|
189
|
+
backgroundColor: colors.navy,
|
|
190
|
+
},
|
|
191
|
+
dayLabel: {
|
|
192
|
+
fontFamily: fonts.sans,
|
|
193
|
+
fontSize: fontSize.md,
|
|
194
|
+
fontWeight: fontWeight.regular,
|
|
195
|
+
lineHeight: 18,
|
|
196
|
+
letterSpacing: 0,
|
|
197
|
+
textAlign: "center",
|
|
198
|
+
color: colors.navy,
|
|
199
|
+
includeFontPadding: false,
|
|
200
|
+
textAlignVertical: "center",
|
|
201
|
+
},
|
|
202
|
+
dayLabelToday: {
|
|
203
|
+
color: CALENDAR_TODAY_TEXT_COLOR,
|
|
204
|
+
},
|
|
205
|
+
dayLabelSelected: {
|
|
206
|
+
fontWeight: fontWeight.semibold,
|
|
207
|
+
color: colors.white,
|
|
208
|
+
},
|
|
209
|
+
dayLabelFuture: {
|
|
210
|
+
color: colors.navy,
|
|
211
|
+
},
|
|
212
|
+
dayLabelMuted: {
|
|
213
|
+
color: colors.stormGray300,
|
|
214
|
+
},
|
|
215
|
+
dayLabelOutsideMonth: {
|
|
216
|
+
color: colors.stormGray300,
|
|
217
|
+
},
|
|
218
|
+
dayLabelDisabled: {
|
|
219
|
+
color: colors.stormGray300,
|
|
220
|
+
opacity: 0.5,
|
|
221
|
+
},
|
|
222
|
+
todayDot: {
|
|
223
|
+
position: "absolute",
|
|
224
|
+
bottom: 5,
|
|
225
|
+
left: "50%",
|
|
226
|
+
width: CALENDAR_DAY_DOT_SIZE,
|
|
227
|
+
height: CALENDAR_DAY_DOT_SIZE,
|
|
228
|
+
borderRadius: 15,
|
|
229
|
+
backgroundColor: CALENDAR_TODAY_DOT_COLOR,
|
|
230
|
+
marginLeft: -(CALENDAR_DAY_DOT_SIZE / 2),
|
|
231
|
+
zIndex: 1,
|
|
232
|
+
},
|
|
233
|
+
pickerBody: {
|
|
234
|
+
width: CALENDAR_DAY_GRID_WIDTH,
|
|
235
|
+
height: CALENDAR_PICKER_BODY_HEIGHT,
|
|
236
|
+
justifyContent: "center",
|
|
237
|
+
},
|
|
238
|
+
pickerGrid: {
|
|
239
|
+
width: CALENDAR_DAY_GRID_WIDTH,
|
|
240
|
+
flexDirection: "row",
|
|
241
|
+
flexWrap: "wrap",
|
|
242
|
+
columnGap: CALENDAR_DAY_GAP_X,
|
|
243
|
+
rowGap: CALENDAR_DAY_GAP_Y,
|
|
244
|
+
alignContent: "flex-start",
|
|
245
|
+
},
|
|
246
|
+
pickerCell: {
|
|
247
|
+
width: CALENDAR_PICKER_CELL_WIDTH,
|
|
248
|
+
minHeight: CALENDAR_PICKER_CELL_HEIGHT,
|
|
249
|
+
alignItems: "center",
|
|
250
|
+
justifyContent: "center",
|
|
251
|
+
borderRadius: CALENDAR_WEEKDAY_RADIUS,
|
|
252
|
+
paddingHorizontal: spacing.xs,
|
|
253
|
+
paddingVertical: spacing.xs,
|
|
254
|
+
backgroundColor: colors.white,
|
|
255
|
+
...(Platform.OS === "web"
|
|
256
|
+
? ({
|
|
257
|
+
boxSizing: "border-box",
|
|
258
|
+
} as ViewStyle)
|
|
259
|
+
: null),
|
|
260
|
+
},
|
|
261
|
+
pickerCellSelected: {
|
|
262
|
+
backgroundColor: colors.navy,
|
|
263
|
+
},
|
|
264
|
+
pickerLabel: {
|
|
265
|
+
fontFamily: fonts.sans,
|
|
266
|
+
fontSize: fontSize.md,
|
|
267
|
+
fontWeight: fontWeight.regular,
|
|
268
|
+
lineHeight: 18,
|
|
269
|
+
letterSpacing: 0,
|
|
270
|
+
textAlign: "center",
|
|
271
|
+
color: colors.navy,
|
|
272
|
+
includeFontPadding: false,
|
|
273
|
+
...(Platform.OS === "android" ? { textAlignVertical: "center" as const } : null),
|
|
274
|
+
},
|
|
275
|
+
pickerLabelSelected: {
|
|
276
|
+
fontWeight: fontWeight.semibold,
|
|
277
|
+
color: colors.white,
|
|
278
|
+
},
|
|
279
|
+
pickerLabelDisabled: {
|
|
280
|
+
color: colors.stormGray300,
|
|
281
|
+
opacity: 0.5,
|
|
282
|
+
},
|
|
283
|
+
pickerLabelCurrent: {
|
|
284
|
+
color: CALENDAR_TODAY_TEXT_COLOR,
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
export function resolveCalendarDropdownTop(
|
|
289
|
+
anchor: { y: number; height: number },
|
|
290
|
+
panelHeight: number = CALENDAR_PANEL_HEIGHT,
|
|
291
|
+
): number {
|
|
292
|
+
const windowHeight = Dimensions.get("window").height;
|
|
293
|
+
const spaceBelow = windowHeight - (anchor.y + anchor.height + CALENDAR_DROPDOWN_GAP);
|
|
294
|
+
const spaceAbove = anchor.y - CALENDAR_DROPDOWN_GAP;
|
|
295
|
+
const topBelow = anchor.y + anchor.height + CALENDAR_DROPDOWN_GAP;
|
|
296
|
+
const topAbove = anchor.y - CALENDAR_DROPDOWN_GAP - panelHeight;
|
|
297
|
+
|
|
298
|
+
if (spaceBelow >= panelHeight) {
|
|
299
|
+
return topBelow;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (spaceAbove >= panelHeight) {
|
|
303
|
+
return topAbove;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (spaceAbove > spaceBelow) {
|
|
307
|
+
return Math.max(0, topAbove);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return Math.max(0, Math.min(topBelow, windowHeight - panelHeight));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export function resolveCalendarDropdownLeft(
|
|
314
|
+
anchor: { x: number },
|
|
315
|
+
panelWidth: number = CALENDAR_PANEL_WIDTH,
|
|
316
|
+
): number {
|
|
317
|
+
const windowWidth = Dimensions.get("window").width;
|
|
318
|
+
const maxLeft = Math.max(0, windowWidth - panelWidth);
|
|
319
|
+
|
|
320
|
+
return Math.max(0, Math.min(anchor.x, maxLeft));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export const calendarFieldMetrics = StyleSheet.create({
|
|
324
|
+
container: {
|
|
325
|
+
flexDirection: "row",
|
|
326
|
+
alignItems: "center",
|
|
327
|
+
width: CALENDAR_FIELD_WIDTH,
|
|
328
|
+
minWidth: CALENDAR_FIELD_WIDTH,
|
|
329
|
+
maxWidth: CALENDAR_FIELD_WIDTH,
|
|
330
|
+
height: CALENDAR_FIELD_HEIGHT,
|
|
331
|
+
minHeight: CALENDAR_FIELD_HEIGHT,
|
|
332
|
+
maxHeight: CALENDAR_FIELD_HEIGHT,
|
|
333
|
+
borderRadius: radii.lg,
|
|
334
|
+
padding: CALENDAR_FIELD_PADDING,
|
|
335
|
+
gap: CALENDAR_FIELD_GAP,
|
|
336
|
+
opacity: 1,
|
|
337
|
+
...(Platform.OS === "web"
|
|
338
|
+
? ({
|
|
339
|
+
boxSizing: "border-box",
|
|
340
|
+
} as ViewStyle)
|
|
341
|
+
: null),
|
|
342
|
+
},
|
|
343
|
+
value: {
|
|
344
|
+
flex: 1,
|
|
345
|
+
minWidth: 0,
|
|
346
|
+
...calendarFieldTypography,
|
|
347
|
+
paddingVertical: 0,
|
|
348
|
+
paddingHorizontal: 0,
|
|
349
|
+
margin: 0,
|
|
350
|
+
...(Platform.OS === "android" ? { includeFontPadding: false } : null),
|
|
351
|
+
...(Platform.OS === "web"
|
|
352
|
+
? ({
|
|
353
|
+
outlineStyle: "none",
|
|
354
|
+
} as TextStyle)
|
|
355
|
+
: null),
|
|
356
|
+
},
|
|
357
|
+
});
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { Dimensions, Platform, StyleSheet, type TextStyle, type ViewStyle } from "react-native";
|
|
2
|
+
import {
|
|
3
|
+
resolveInputVisualState,
|
|
4
|
+
type InputStateFlags,
|
|
5
|
+
type InputVisualState,
|
|
6
|
+
} from "./input";
|
|
7
|
+
import { colors, fonts, fontSize, fontWeight, radii, spacing } from "./tokens";
|
|
8
|
+
|
|
9
|
+
export const SELECT_HEIGHT = 52;
|
|
10
|
+
export const SELECT_PADDING = 16;
|
|
11
|
+
export const SELECT_INNER_GAP = 10;
|
|
12
|
+
export const SELECT_ICON_SIZE = 20;
|
|
13
|
+
export const SELECT_LABEL_GAP = spacing.sm;
|
|
14
|
+
export const SELECT_DROPDOWN_GAP = spacing.sm;
|
|
15
|
+
export const SELECT_DROPDOWN_PADDING = spacing.sm;
|
|
16
|
+
export const SELECT_DROPDOWN_MAX_HEIGHT = 317;
|
|
17
|
+
export const SELECT_OPTION_HEIGHT = 43;
|
|
18
|
+
export const SELECT_OPTION_GAP = spacing.sm;
|
|
19
|
+
export const SELECT_CHEVRON_SIZE = 20;
|
|
20
|
+
export const SELECT_CHEVRON_COLOR = colors.stormGray150;
|
|
21
|
+
export const SELECT_CHEVRON_ROTATION_MS = 200;
|
|
22
|
+
|
|
23
|
+
export { resolveInputVisualState };
|
|
24
|
+
export type { InputStateFlags, InputVisualState };
|
|
25
|
+
|
|
26
|
+
export const selectLabelTypography = {
|
|
27
|
+
fontFamily: fonts.sans,
|
|
28
|
+
fontSize: fontSize.sm,
|
|
29
|
+
fontWeight: fontWeight.medium,
|
|
30
|
+
lineHeight: fontSize.sm,
|
|
31
|
+
letterSpacing: 0,
|
|
32
|
+
color: colors.slateBlue,
|
|
33
|
+
} as const;
|
|
34
|
+
|
|
35
|
+
export const selectValueTypography = {
|
|
36
|
+
fontFamily: fonts.sans,
|
|
37
|
+
fontSize: fontSize.md,
|
|
38
|
+
fontWeight: fontWeight.regular,
|
|
39
|
+
lineHeight: fontSize.md,
|
|
40
|
+
letterSpacing: 0,
|
|
41
|
+
textAlign: "left",
|
|
42
|
+
} as const;
|
|
43
|
+
|
|
44
|
+
interface SelectFieldStyleSet {
|
|
45
|
+
container: ViewStyle;
|
|
46
|
+
outline: ViewStyle;
|
|
47
|
+
value: TextStyle;
|
|
48
|
+
placeholder: string;
|
|
49
|
+
icon: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const INPUT_OUTLINE_WIDTH = 2;
|
|
53
|
+
|
|
54
|
+
function createOutlineStyle(ringColor: string): ViewStyle {
|
|
55
|
+
return {
|
|
56
|
+
borderRadius: radii.lg + INPUT_OUTLINE_WIDTH,
|
|
57
|
+
borderWidth: INPUT_OUTLINE_WIDTH,
|
|
58
|
+
borderColor: ringColor,
|
|
59
|
+
padding: 0,
|
|
60
|
+
backgroundColor: colors.transparent,
|
|
61
|
+
width: "100%",
|
|
62
|
+
alignSelf: "stretch",
|
|
63
|
+
...(Platform.OS !== "web" ? { overflow: "hidden" as const } : null),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const defaultOutline = createOutlineStyle(colors.transparent);
|
|
68
|
+
|
|
69
|
+
export function getSelectFieldStyles(state: InputVisualState): SelectFieldStyleSet {
|
|
70
|
+
const containerBase: ViewStyle = {
|
|
71
|
+
borderRadius: radii.lg,
|
|
72
|
+
...(Platform.OS !== "web" ? { overflow: "hidden" as const } : null),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const valueBase: TextStyle = {
|
|
76
|
+
...selectValueTypography,
|
|
77
|
+
color: colors.slateBlue,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
switch (state) {
|
|
81
|
+
case "disabled":
|
|
82
|
+
return {
|
|
83
|
+
outline: defaultOutline,
|
|
84
|
+
container: {
|
|
85
|
+
...containerBase,
|
|
86
|
+
borderWidth: 1,
|
|
87
|
+
borderColor: colors.stormGray50,
|
|
88
|
+
backgroundColor: colors.stormGray50,
|
|
89
|
+
},
|
|
90
|
+
value: { ...valueBase, color: colors.stormGray300 },
|
|
91
|
+
placeholder: colors.stormGray300,
|
|
92
|
+
icon: colors.stormGray150,
|
|
93
|
+
};
|
|
94
|
+
case "error":
|
|
95
|
+
return {
|
|
96
|
+
outline: createOutlineStyle(colors.inputOutlineError),
|
|
97
|
+
container: {
|
|
98
|
+
...containerBase,
|
|
99
|
+
borderWidth: 1,
|
|
100
|
+
borderColor: colors.inputError,
|
|
101
|
+
backgroundColor: colors.white,
|
|
102
|
+
},
|
|
103
|
+
value: { ...valueBase, color: colors.inputError },
|
|
104
|
+
placeholder: colors.stormGray200,
|
|
105
|
+
icon: colors.inputError,
|
|
106
|
+
};
|
|
107
|
+
case "focused":
|
|
108
|
+
return {
|
|
109
|
+
outline: createOutlineStyle(colors.inputOutlineFocus),
|
|
110
|
+
container: {
|
|
111
|
+
...containerBase,
|
|
112
|
+
borderWidth: 1,
|
|
113
|
+
borderColor: colors.navy,
|
|
114
|
+
backgroundColor: colors.white,
|
|
115
|
+
},
|
|
116
|
+
value: valueBase,
|
|
117
|
+
placeholder: colors.stormGray200,
|
|
118
|
+
icon: colors.navy,
|
|
119
|
+
};
|
|
120
|
+
default:
|
|
121
|
+
return {
|
|
122
|
+
outline: defaultOutline,
|
|
123
|
+
container: {
|
|
124
|
+
...containerBase,
|
|
125
|
+
borderWidth: 1,
|
|
126
|
+
borderColor: colors.stormGray50,
|
|
127
|
+
backgroundColor: colors.white,
|
|
128
|
+
},
|
|
129
|
+
value: valueBase,
|
|
130
|
+
placeholder: colors.stormGray200,
|
|
131
|
+
icon: colors.stormGray150,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export const selectFieldMetrics = StyleSheet.create({
|
|
137
|
+
container: {
|
|
138
|
+
flexDirection: "row",
|
|
139
|
+
alignItems: "center",
|
|
140
|
+
height: SELECT_HEIGHT,
|
|
141
|
+
borderRadius: radii.lg,
|
|
142
|
+
padding: SELECT_PADDING,
|
|
143
|
+
gap: SELECT_INNER_GAP,
|
|
144
|
+
...(Platform.OS === "web"
|
|
145
|
+
? ({
|
|
146
|
+
boxSizing: "border-box",
|
|
147
|
+
} as ViewStyle)
|
|
148
|
+
: null),
|
|
149
|
+
},
|
|
150
|
+
value: {
|
|
151
|
+
flex: 1,
|
|
152
|
+
minWidth: 0,
|
|
153
|
+
...selectValueTypography,
|
|
154
|
+
paddingVertical: 0,
|
|
155
|
+
paddingHorizontal: 0,
|
|
156
|
+
margin: 0,
|
|
157
|
+
...(Platform.OS === "android" ? { includeFontPadding: false } : null),
|
|
158
|
+
...(Platform.OS === "web"
|
|
159
|
+
? ({
|
|
160
|
+
outlineStyle: "none",
|
|
161
|
+
} as TextStyle)
|
|
162
|
+
: null),
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
export const selectDropdownMetrics = StyleSheet.create({
|
|
167
|
+
menu: {
|
|
168
|
+
borderRadius: radii.lg,
|
|
169
|
+
borderWidth: 1,
|
|
170
|
+
borderColor: colors.stormGray50,
|
|
171
|
+
backgroundColor: colors.white,
|
|
172
|
+
padding: SELECT_DROPDOWN_PADDING,
|
|
173
|
+
overflow: "hidden",
|
|
174
|
+
},
|
|
175
|
+
option: {
|
|
176
|
+
width: "100%",
|
|
177
|
+
height: SELECT_OPTION_HEIGHT,
|
|
178
|
+
minHeight: SELECT_OPTION_HEIGHT,
|
|
179
|
+
maxHeight: SELECT_OPTION_HEIGHT,
|
|
180
|
+
paddingTop: 12,
|
|
181
|
+
paddingRight: spacing.sm,
|
|
182
|
+
paddingBottom: 12,
|
|
183
|
+
paddingLeft: spacing.sm,
|
|
184
|
+
justifyContent: "center",
|
|
185
|
+
alignItems: "flex-start",
|
|
186
|
+
},
|
|
187
|
+
optionLabel: {
|
|
188
|
+
fontFamily: fonts.sans,
|
|
189
|
+
fontSize: fontSize.md,
|
|
190
|
+
fontWeight: fontWeight.regular,
|
|
191
|
+
lineHeight: fontSize.md,
|
|
192
|
+
letterSpacing: 0,
|
|
193
|
+
textAlign: "left",
|
|
194
|
+
color: colors.slateBlue,
|
|
195
|
+
width: "100%",
|
|
196
|
+
},
|
|
197
|
+
optionLabelSelected: {
|
|
198
|
+
fontWeight: fontWeight.medium,
|
|
199
|
+
color: colors.slateBlue,
|
|
200
|
+
},
|
|
201
|
+
optionSelected: {
|
|
202
|
+
opacity: 1,
|
|
203
|
+
borderRadius: radii.sm,
|
|
204
|
+
paddingTop: 12,
|
|
205
|
+
paddingRight: spacing.sm,
|
|
206
|
+
paddingBottom: 12,
|
|
207
|
+
paddingLeft: spacing.sm,
|
|
208
|
+
backgroundColor: colors.countrySelectorSelectedBg,
|
|
209
|
+
},
|
|
210
|
+
optionHighlighted: {
|
|
211
|
+
backgroundColor: colors.stormGray0,
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
export function resolveSelectDropdownHeight(optionCount: number): number {
|
|
216
|
+
const contentHeight =
|
|
217
|
+
optionCount * SELECT_OPTION_HEIGHT +
|
|
218
|
+
Math.max(0, optionCount - 1) * SELECT_OPTION_GAP +
|
|
219
|
+
SELECT_DROPDOWN_PADDING * 2;
|
|
220
|
+
|
|
221
|
+
return Math.min(contentHeight, SELECT_DROPDOWN_MAX_HEIGHT);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export function resolveSelectDropdownTop(
|
|
225
|
+
anchor: { y: number; height: number },
|
|
226
|
+
dropdownHeight: number,
|
|
227
|
+
): number {
|
|
228
|
+
const windowHeight = Dimensions.get("window").height;
|
|
229
|
+
const spaceBelow = windowHeight - (anchor.y + anchor.height + SELECT_DROPDOWN_GAP);
|
|
230
|
+
const spaceAbove = anchor.y - SELECT_DROPDOWN_GAP;
|
|
231
|
+
const topBelow = anchor.y + anchor.height + SELECT_DROPDOWN_GAP;
|
|
232
|
+
const topAbove = anchor.y - SELECT_DROPDOWN_GAP - dropdownHeight;
|
|
233
|
+
|
|
234
|
+
if (spaceBelow >= dropdownHeight) {
|
|
235
|
+
return topBelow;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (spaceAbove >= dropdownHeight) {
|
|
239
|
+
return topAbove;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (spaceAbove > spaceBelow) {
|
|
243
|
+
return Math.max(0, topAbove);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return Math.max(0, Math.min(topBelow, windowHeight - dropdownHeight));
|
|
247
|
+
}
|