@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.
Files changed (81) hide show
  1. package/dist/{chunk-WDSMJWKC.js → chunk-66WR57JJ.js} +35 -3
  2. package/dist/chunk-66WR57JJ.js.map +1 -0
  3. package/dist/index.cjs +2258 -384
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +134 -1
  6. package/dist/index.d.ts +134 -1
  7. package/dist/index.js +1959 -97
  8. package/dist/index.js.map +1 -1
  9. package/dist/web/index.cjs +30650 -1009
  10. package/dist/web/index.cjs.map +1 -1
  11. package/dist/web/index.css +78 -0
  12. package/dist/web/index.css.map +1 -0
  13. package/dist/web/index.d.cts +267 -6
  14. package/dist/web/index.d.ts +267 -6
  15. package/dist/web/index.js +30179 -601
  16. package/dist/web/index.js.map +1 -1
  17. package/package.json +5 -4
  18. package/src/components/Calendar.stories.tsx +337 -0
  19. package/src/components/Calendar.tsx +441 -0
  20. package/src/components/DatePicker.stories.tsx +219 -0
  21. package/src/components/DatePicker.tsx +366 -0
  22. package/src/components/Select.stories.tsx +134 -0
  23. package/src/components/Select.tsx +465 -0
  24. package/src/css.d.ts +1 -0
  25. package/src/icons/CalendarIcon.tsx +28 -0
  26. package/src/icons/CalendarIcon.web.tsx +34 -0
  27. package/src/icons/ChevronDownIcon.tsx +11 -4
  28. package/src/icons/ChevronDownIcon.web.tsx +6 -4
  29. package/src/icons/ChevronNavIcons.tsx +44 -0
  30. package/src/icons/ChevronNavIcons.web.tsx +57 -0
  31. package/src/icons/calendarIconPaths.ts +2 -0
  32. package/src/icons/chevronDownPath.ts +1 -0
  33. package/src/icons/chevronNavPaths.ts +2 -0
  34. package/src/index.ts +41 -0
  35. package/src/theme/calendar.ts +357 -0
  36. package/src/theme/select.ts +247 -0
  37. package/src/utils/calendarDays.ts +273 -0
  38. package/src/utils/calendarLocaleContext.tsx +95 -0
  39. package/src/utils/calendarLocalization.ts +187 -0
  40. package/src/utils/countryDropdownScrollStyles.ts +53 -13
  41. package/src/utils/formatMultiSelectDisplay.ts +56 -0
  42. package/src/web/components/Badge.stories.tsx +43 -0
  43. package/src/web/components/Badge.tsx +35 -0
  44. package/src/web/components/Pagination.stories.tsx +78 -0
  45. package/src/web/components/Pagination.tsx +153 -0
  46. package/src/web/components/StatusBadge.tsx +20 -0
  47. package/src/web/components/Table.stories.tsx +415 -0
  48. package/src/web/components/Table.tsx +3 -0
  49. package/src/web/components/TableActionButton.tsx +67 -0
  50. package/src/web/components/TableActionsMenu.tsx +208 -0
  51. package/src/web/components/TableIconText.tsx +23 -0
  52. package/src/web/components/TableRowStatusActions.tsx +33 -0
  53. package/src/web/components/TableStatusActionsCell.tsx +29 -0
  54. package/src/web/components/pagination-utils.ts +39 -0
  55. package/src/web/components/table/DataTable.tsx +123 -0
  56. package/src/web/components/table/TablePrimitives.tsx +214 -0
  57. package/src/web/components/table/TableScrollArea.tsx +51 -0
  58. package/src/web/components/table/constants.ts +59 -0
  59. package/src/web/components/table/data-table-class-names.ts +26 -0
  60. package/src/web/components/table/index.ts +44 -0
  61. package/src/web/components/table/table-row-context.tsx +19 -0
  62. package/src/web/components/table/use-horizontal-scroll-state.ts +72 -0
  63. package/src/web/components/table-scroll.css +81 -0
  64. package/src/web/hooks/useOnClickOutside.ts +20 -5
  65. package/src/web/icons/TableMenuActivateIcon.tsx +27 -0
  66. package/src/web/icons/TableMenuCheckIcon.tsx +27 -0
  67. package/src/web/icons/TableMenuCloseIcon.tsx +27 -0
  68. package/src/web/icons/TableMenuEditIcon.tsx +27 -0
  69. package/src/web/icons/TableMenuInfoIcon.tsx +27 -0
  70. package/src/web/icons/TableMenuRefreshIcon.tsx +27 -0
  71. package/src/web/icons/TableMenuSuspendIcon.tsx +34 -0
  72. package/src/web/icons/TableMenuTrashIcon.tsx +27 -0
  73. package/src/web/icons/TableMoreIcon.tsx +41 -0
  74. package/src/web/icons/TableSortIcon.tsx +37 -0
  75. package/src/web/index.ts +74 -0
  76. package/src/web/layout/AppHeader.stories.tsx +2 -0
  77. package/src/web/layout/AppHeader.tsx +18 -14
  78. package/src/web/layout/DashboardLayout.stories.tsx +1 -0
  79. package/src/web/layout/DashboardLayout.tsx +4 -4
  80. package/src/web/layout/story-helpers.tsx +10 -2
  81. package/dist/chunk-WDSMJWKC.js.map +0 -1
@@ -0,0 +1,441 @@
1
+ import { useMemo, useRef, useState, type ComponentRef } from "react";
2
+ import { Pressable, Text, View, type StyleProp, type TextStyle, type ViewStyle } from "react-native";
3
+ import { ChevronLeftIcon, ChevronRightIcon } from "../icons/ChevronNavIcons";
4
+ import {
5
+ CALENDAR_NAV_ICON_COLOR,
6
+ CALENDAR_NAV_ICON_SIZE,
7
+ CALENDAR_YEARS_PER_PAGE,
8
+ calendarDropdownMetrics,
9
+ } from "../theme/calendar";
10
+ import {
11
+ addMonths,
12
+ buildCalendarDays,
13
+ formatCalendarYear,
14
+ getYearPageStart,
15
+ isMonthDisabled,
16
+ isYearDisabled,
17
+ selectRangeDate,
18
+ type CalendarDayCell,
19
+ type DateRange,
20
+ } from "../utils/calendarDays";
21
+ import {
22
+ formatLocalizedCalendarMonthYear,
23
+ getCalendarMonthLabels,
24
+ getCalendarTranslations,
25
+ resolveWeekdayLabels,
26
+ type CalendarTranslations,
27
+ } from "../utils/calendarLocalization";
28
+ import { useCalendarLocale } from "../utils/calendarLocaleContext";
29
+ import { useApplyWebClassName } from "../utils/useApplyWebClassName";
30
+
31
+ export type { DateRange };
32
+
33
+ export type CalendarLabels = Partial<Pick<CalendarTranslations, CalendarTranslationKey>> & {
34
+ weekdays?: string[];
35
+ formatMonthYear?: (date: Date) => string;
36
+ };
37
+
38
+ type CalendarTranslationKey =
39
+ | "previousMonth"
40
+ | "nextMonth"
41
+ | "previousYear"
42
+ | "nextYear"
43
+ | "previousYears"
44
+ | "nextYears"
45
+ | "selectMonth"
46
+ | "selectYear"
47
+ | "closeCalendar";
48
+
49
+ type CalendarPickerView = "days" | "months" | "years";
50
+
51
+ type CalendarBaseProps = {
52
+ viewDate?: Date;
53
+ defaultViewDate?: Date;
54
+ onViewDateChange?: (date: Date) => void;
55
+ locale?: string;
56
+ labels?: CalendarLabels;
57
+ minDate?: Date;
58
+ maxDate?: Date;
59
+ today?: Date;
60
+ style?: StyleProp<ViewStyle>;
61
+ className?: string;
62
+ };
63
+
64
+ export type CalendarSingleProps = CalendarBaseProps & {
65
+ mode?: "single";
66
+ value?: Date;
67
+ onChange?: (date: Date) => void;
68
+ };
69
+
70
+ export type CalendarRangeProps = CalendarBaseProps & {
71
+ mode: "range";
72
+ value?: DateRange;
73
+ onChange?: (range: DateRange) => void;
74
+ };
75
+
76
+ export type CalendarProps = CalendarSingleProps | CalendarRangeProps;
77
+
78
+ function resolveDayCellStyle(day: CalendarDayCell): StyleProp<ViewStyle> {
79
+ if (day.isDisabled) {
80
+ return [calendarDropdownMetrics.dayCell];
81
+ }
82
+
83
+ if (day.isSelected) {
84
+ return [calendarDropdownMetrics.dayCell, calendarDropdownMetrics.dayCellSelected];
85
+ }
86
+
87
+ return [
88
+ calendarDropdownMetrics.dayCell,
89
+ day.inCurrentMonth && day.isPast && !day.isToday
90
+ ? calendarDropdownMetrics.dayCellPast
91
+ : null,
92
+ ];
93
+ }
94
+
95
+ function resolveDayLabelStyle(day: CalendarDayCell): StyleProp<TextStyle> {
96
+ if (day.isDisabled) {
97
+ return [calendarDropdownMetrics.dayLabel, calendarDropdownMetrics.dayLabelDisabled];
98
+ }
99
+
100
+ if (day.isSelected) {
101
+ return [calendarDropdownMetrics.dayLabel, calendarDropdownMetrics.dayLabelSelected];
102
+ }
103
+
104
+ if (!day.inCurrentMonth) {
105
+ return [calendarDropdownMetrics.dayLabel, calendarDropdownMetrics.dayLabelOutsideMonth];
106
+ }
107
+
108
+ if (day.isToday) {
109
+ return [calendarDropdownMetrics.dayLabel, calendarDropdownMetrics.dayLabelToday];
110
+ }
111
+
112
+ if (day.isPast) {
113
+ return [calendarDropdownMetrics.dayLabel, calendarDropdownMetrics.dayLabelMuted];
114
+ }
115
+
116
+ return [calendarDropdownMetrics.dayLabel, calendarDropdownMetrics.dayLabelFuture];
117
+ }
118
+
119
+ export function Calendar(props: CalendarProps) {
120
+ const rangeProps = props.mode === "range" ? (props as CalendarRangeProps) : null;
121
+ const singleProps = props.mode === "range" ? null : (props as CalendarSingleProps);
122
+ const {
123
+ viewDate,
124
+ defaultViewDate,
125
+ onViewDateChange,
126
+ locale,
127
+ labels,
128
+ minDate,
129
+ maxDate,
130
+ today = new Date(),
131
+ style,
132
+ className,
133
+ } = props;
134
+ const rootRef = useRef<ComponentRef<typeof View>>(null);
135
+ const [internalViewDate, setInternalViewDate] = useState(() => {
136
+ if (defaultViewDate) {
137
+ return defaultViewDate;
138
+ }
139
+
140
+ if (rangeProps) {
141
+ return rangeProps.value?.start ?? today;
142
+ }
143
+
144
+ return singleProps?.value ?? today;
145
+ });
146
+ const activeViewDate = viewDate ?? internalViewDate;
147
+ const [pickerView, setPickerView] = useState<CalendarPickerView>("days");
148
+ const [pickerYear, setPickerYear] = useState(() => activeViewDate.getFullYear());
149
+ const [yearPageStart, setYearPageStart] = useState(() =>
150
+ getYearPageStart(activeViewDate.getFullYear(), CALENDAR_YEARS_PER_PAGE),
151
+ );
152
+ const customWeekdayLabels = labels?.weekdays;
153
+ const formatMonthYearLabel = labels?.formatMonthYear;
154
+ const resolvedLocale = useCalendarLocale(locale);
155
+ const translations = useMemo(
156
+ () => getCalendarTranslations(resolvedLocale),
157
+ [resolvedLocale],
158
+ );
159
+
160
+ useApplyWebClassName(rootRef, className);
161
+
162
+ const weekdayLabels = useMemo(
163
+ () => customWeekdayLabels ?? resolveWeekdayLabels(resolvedLocale),
164
+ [customWeekdayLabels, resolvedLocale],
165
+ );
166
+
167
+ const monthLabels = useMemo(() => getCalendarMonthLabels(resolvedLocale), [resolvedLocale]);
168
+
169
+ const monthYearLabel = useMemo(() => {
170
+ if (formatMonthYearLabel) {
171
+ return formatMonthYearLabel(activeViewDate);
172
+ }
173
+
174
+ return formatLocalizedCalendarMonthYear(activeViewDate, resolvedLocale);
175
+ }, [activeViewDate, formatMonthYearLabel, resolvedLocale]);
176
+
177
+ const headerLabel = useMemo(() => {
178
+ if (pickerView === "months") {
179
+ return formatCalendarYear(pickerYear, resolvedLocale);
180
+ }
181
+
182
+ if (pickerView === "years") {
183
+ const endYear = yearPageStart + CALENDAR_YEARS_PER_PAGE - 1;
184
+ return `${yearPageStart} – ${endYear}`;
185
+ }
186
+
187
+ return monthYearLabel;
188
+ }, [monthYearLabel, pickerView, pickerYear, resolvedLocale, yearPageStart]);
189
+
190
+ const days = useMemo(
191
+ () =>
192
+ buildCalendarDays({
193
+ viewDate: activeViewDate,
194
+ selectedDate: singleProps?.value,
195
+ selectedRange: rangeProps?.value,
196
+ today,
197
+ minDate,
198
+ maxDate,
199
+ }),
200
+ [activeViewDate, maxDate, minDate, rangeProps?.value, singleProps?.value, today],
201
+ );
202
+
203
+ const yearOptions = useMemo(
204
+ () =>
205
+ Array.from({ length: CALENDAR_YEARS_PER_PAGE }, (_, index) => yearPageStart + index),
206
+ [yearPageStart],
207
+ );
208
+
209
+ function getLabel(key: CalendarTranslationKey): string {
210
+ return labels?.[key] ?? translations[key];
211
+ }
212
+
213
+ function setViewDate(nextDate: Date) {
214
+ if (viewDate === undefined) {
215
+ setInternalViewDate(nextDate);
216
+ }
217
+
218
+ onViewDateChange?.(nextDate);
219
+ }
220
+
221
+ function handlePrevious() {
222
+ if (pickerView === "months") {
223
+ setPickerYear((year) => year - 1);
224
+ return;
225
+ }
226
+
227
+ if (pickerView === "years") {
228
+ setYearPageStart((start) => start - CALENDAR_YEARS_PER_PAGE);
229
+ return;
230
+ }
231
+
232
+ setViewDate(addMonths(activeViewDate, -1));
233
+ }
234
+
235
+ function handleNext() {
236
+ if (pickerView === "months") {
237
+ setPickerYear((year) => year + 1);
238
+ return;
239
+ }
240
+
241
+ if (pickerView === "years") {
242
+ setYearPageStart((start) => start + CALENDAR_YEARS_PER_PAGE);
243
+ return;
244
+ }
245
+
246
+ setViewDate(addMonths(activeViewDate, 1));
247
+ }
248
+
249
+ function handleHeaderPress() {
250
+ if (pickerView === "days") {
251
+ setPickerYear(activeViewDate.getFullYear());
252
+ setPickerView("months");
253
+ return;
254
+ }
255
+
256
+ if (pickerView === "months") {
257
+ setYearPageStart(getYearPageStart(pickerYear, CALENDAR_YEARS_PER_PAGE));
258
+ setPickerView("years");
259
+ }
260
+ }
261
+
262
+ function handleMonthSelect(month: number) {
263
+ setViewDate(new Date(pickerYear, month, 1));
264
+ setPickerView("days");
265
+ }
266
+
267
+ function handleYearSelect(year: number) {
268
+ setPickerYear(year);
269
+ setPickerView("months");
270
+ }
271
+
272
+ function handleDayPress(date: Date) {
273
+ if (rangeProps) {
274
+ rangeProps.onChange?.(selectRangeDate(date, rangeProps.value));
275
+ return;
276
+ }
277
+
278
+ singleProps?.onChange?.(date);
279
+ }
280
+
281
+ const headerIsPressable = pickerView === "days" || pickerView === "months";
282
+
283
+ return (
284
+ <View ref={rootRef} style={[calendarDropdownMetrics.panel, style]}>
285
+ <View style={calendarDropdownMetrics.header}>
286
+ <Pressable
287
+ accessibilityRole="button"
288
+ accessibilityLabel={
289
+ pickerView === "months"
290
+ ? getLabel("previousYear")
291
+ : pickerView === "years"
292
+ ? getLabel("previousYears")
293
+ : getLabel("previousMonth")
294
+ }
295
+ onPress={handlePrevious}
296
+ style={calendarDropdownMetrics.navButton}
297
+ >
298
+ <ChevronLeftIcon size={CALENDAR_NAV_ICON_SIZE} color={CALENDAR_NAV_ICON_COLOR} />
299
+ </Pressable>
300
+
301
+ {headerIsPressable ? (
302
+ <Pressable
303
+ accessibilityRole="button"
304
+ accessibilityLabel={
305
+ pickerView === "days" ? getLabel("selectMonth") : getLabel("selectYear")
306
+ }
307
+ onPress={handleHeaderPress}
308
+ style={calendarDropdownMetrics.headerTitlePressable}
309
+ >
310
+ <Text style={calendarDropdownMetrics.headerTitle}>{headerLabel}</Text>
311
+ </Pressable>
312
+ ) : (
313
+ <View style={calendarDropdownMetrics.headerTitlePressable}>
314
+ <Text style={calendarDropdownMetrics.headerTitle}>{headerLabel}</Text>
315
+ </View>
316
+ )}
317
+
318
+ <Pressable
319
+ accessibilityRole="button"
320
+ accessibilityLabel={
321
+ pickerView === "months"
322
+ ? getLabel("nextYear")
323
+ : pickerView === "years"
324
+ ? getLabel("nextYears")
325
+ : getLabel("nextMonth")
326
+ }
327
+ onPress={handleNext}
328
+ style={calendarDropdownMetrics.navButton}
329
+ >
330
+ <ChevronRightIcon size={CALENDAR_NAV_ICON_SIZE} color={CALENDAR_NAV_ICON_COLOR} />
331
+ </Pressable>
332
+ </View>
333
+
334
+ {pickerView === "days" ? (
335
+ <>
336
+ <View style={calendarDropdownMetrics.weekdayRow}>
337
+ {weekdayLabels.map((weekday) => (
338
+ <View key={weekday} style={calendarDropdownMetrics.weekdayCell}>
339
+ <Text style={calendarDropdownMetrics.weekdayLabel}>{weekday}</Text>
340
+ </View>
341
+ ))}
342
+ </View>
343
+
344
+ <View style={calendarDropdownMetrics.dayGrid}>
345
+ {days.map((day) => (
346
+ <Pressable
347
+ key={day.date.toISOString()}
348
+ accessibilityRole="button"
349
+ accessibilityState={{
350
+ selected: day.isSelected,
351
+ disabled: day.isDisabled,
352
+ }}
353
+ disabled={day.isDisabled}
354
+ onPress={() => handleDayPress(day.date)}
355
+ style={resolveDayCellStyle(day)}
356
+ >
357
+ <Text style={resolveDayLabelStyle(day)}>{day.date.getDate()}</Text>
358
+ {day.isToday && day.inCurrentMonth && !day.isSelected ? (
359
+ <View style={calendarDropdownMetrics.todayDot} />
360
+ ) : null}
361
+ </Pressable>
362
+ ))}
363
+ </View>
364
+ </>
365
+ ) : (
366
+ <View style={calendarDropdownMetrics.pickerBody}>
367
+ <View style={calendarDropdownMetrics.pickerGrid}>
368
+ {pickerView === "months"
369
+ ? monthLabels.map((monthLabel, month) => {
370
+ const isSelected =
371
+ activeViewDate.getFullYear() === pickerYear &&
372
+ activeViewDate.getMonth() === month;
373
+ const isCurrent =
374
+ today.getFullYear() === pickerYear && today.getMonth() === month;
375
+ const disabled = isMonthDisabled(pickerYear, month, minDate, maxDate);
376
+
377
+ return (
378
+ <Pressable
379
+ key={monthLabel}
380
+ accessibilityRole="button"
381
+ accessibilityState={{ selected: isSelected, disabled }}
382
+ disabled={disabled}
383
+ onPress={() => handleMonthSelect(month)}
384
+ style={[
385
+ calendarDropdownMetrics.pickerCell,
386
+ isSelected ? calendarDropdownMetrics.pickerCellSelected : null,
387
+ ]}
388
+ >
389
+ <Text
390
+ style={[
391
+ calendarDropdownMetrics.pickerLabel,
392
+ isSelected ? calendarDropdownMetrics.pickerLabelSelected : null,
393
+ !isSelected && isCurrent
394
+ ? calendarDropdownMetrics.pickerLabelCurrent
395
+ : null,
396
+ disabled ? calendarDropdownMetrics.pickerLabelDisabled : null,
397
+ ]}
398
+ >
399
+ {monthLabel}
400
+ </Text>
401
+ </Pressable>
402
+ );
403
+ })
404
+ : yearOptions.map((year) => {
405
+ const isSelected = activeViewDate.getFullYear() === year;
406
+ const isCurrent = today.getFullYear() === year;
407
+ const disabled = isYearDisabled(year, minDate, maxDate);
408
+
409
+ return (
410
+ <Pressable
411
+ key={year}
412
+ accessibilityRole="button"
413
+ accessibilityState={{ selected: isSelected, disabled }}
414
+ disabled={disabled}
415
+ onPress={() => handleYearSelect(year)}
416
+ style={[
417
+ calendarDropdownMetrics.pickerCell,
418
+ isSelected ? calendarDropdownMetrics.pickerCellSelected : null,
419
+ ]}
420
+ >
421
+ <Text
422
+ style={[
423
+ calendarDropdownMetrics.pickerLabel,
424
+ isSelected ? calendarDropdownMetrics.pickerLabelSelected : null,
425
+ !isSelected && isCurrent
426
+ ? calendarDropdownMetrics.pickerLabelCurrent
427
+ : null,
428
+ disabled ? calendarDropdownMetrics.pickerLabelDisabled : null,
429
+ ]}
430
+ >
431
+ {year}
432
+ </Text>
433
+ </Pressable>
434
+ );
435
+ })}
436
+ </View>
437
+ </View>
438
+ )}
439
+ </View>
440
+ );
441
+ }
@@ -0,0 +1,219 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { useState } from "react";
3
+ import { View, StyleSheet } from "react-native";
4
+ import { formatLocalizedCalendarMonthYear } from "../utils/calendarLocalization";
5
+ import { DatePicker, type CalendarLabels, type DatePickerRangeProps, type DatePickerSingleProps, type DateRange } from "./DatePicker";
6
+
7
+ const figmaViewDate = new Date(2026, 5, 1);
8
+ const figmaSampleDate = new Date(2026, 5, 25);
9
+
10
+ function getCurrentMonthStart() {
11
+ const now = new Date();
12
+ return new Date(now.getFullYear(), now.getMonth(), 1);
13
+ }
14
+
15
+ function getSampleRange(): DateRange {
16
+ const now = new Date();
17
+ return {
18
+ start: new Date(now.getFullYear(), now.getMonth(), 20),
19
+ end: new Date(now.getFullYear(), now.getMonth(), 28),
20
+ };
21
+ }
22
+
23
+ const figmaLabels: CalendarLabels = {
24
+ weekdays: ["ԵՐ", "ԵՔ", "ՉՐ", "ՀՆ", "ՈՒՐ", "ՇԲ", "ԿՐ"],
25
+ formatMonthYear: (date) => formatLocalizedCalendarMonthYear(date, "hy-AM"),
26
+ };
27
+
28
+ const sharedDatePickerArgs = {
29
+ mode: "single" as const,
30
+ placeholder: "Ընտրել ամսաթիվ",
31
+ locale: "hy-AM" as const,
32
+ defaultViewDate: getCurrentMonthStart(),
33
+ defaultOpen: false,
34
+ };
35
+
36
+ const meta = {
37
+ title: "Components/DatePicker",
38
+ component: DatePicker,
39
+ parameters: {
40
+ layout: "centered",
41
+ },
42
+ args: sharedDatePickerArgs,
43
+ } satisfies Meta<DatePickerSingleProps>;
44
+
45
+ export default meta;
46
+ type Story = StoryObj<typeof meta>;
47
+
48
+ /** Default — closed field; click input to open calendar. */
49
+ export const Default: Story = {
50
+ render: function DefaultDatePickerStory() {
51
+ const [value, setValue] = useState<Date | undefined>();
52
+
53
+ return (
54
+ <View style={styles.field}>
55
+ <DatePicker {...sharedDatePickerArgs} value={value} onChange={setValue} />
56
+ </View>
57
+ );
58
+ },
59
+ };
60
+
61
+ export const WithSelectedDate: Story = {
62
+ render: function SelectedDatePickerStory() {
63
+ const [value, setValue] = useState<Date | undefined>(figmaSampleDate);
64
+
65
+ return (
66
+ <View style={styles.field}>
67
+ <DatePicker
68
+ {...sharedDatePickerArgs}
69
+ labels={figmaLabels}
70
+ defaultViewDate={figmaViewDate}
71
+ value={value}
72
+ onChange={setValue}
73
+ />
74
+ </View>
75
+ );
76
+ },
77
+ };
78
+
79
+ export const Open: Story = {
80
+ render: function OpenDatePickerStory() {
81
+ const [value, setValue] = useState<Date | undefined>();
82
+
83
+ return (
84
+ <View style={styles.canvas}>
85
+ <DatePicker {...sharedDatePickerArgs} defaultOpen value={value} onChange={setValue} />
86
+ </View>
87
+ );
88
+ },
89
+ };
90
+
91
+ export const WithLabel: Story = {
92
+ render: function LabeledDatePickerStory() {
93
+ const [value, setValue] = useState<Date | undefined>();
94
+
95
+ return (
96
+ <View style={styles.field}>
97
+ <DatePicker {...sharedDatePickerArgs} label="Ամսաթիվ" value={value} onChange={setValue} />
98
+ </View>
99
+ );
100
+ },
101
+ };
102
+
103
+ export const WithError: Story = {
104
+ render: function ErrorDatePickerStory() {
105
+ const [value, setValue] = useState<Date | undefined>();
106
+
107
+ return (
108
+ <View style={styles.field}>
109
+ <DatePicker
110
+ {...sharedDatePickerArgs}
111
+ error="Խնդրում ենք ընտրել ամսաթիվ"
112
+ invalid
113
+ value={value}
114
+ onChange={setValue}
115
+ />
116
+ </View>
117
+ );
118
+ },
119
+ };
120
+
121
+ export const Disabled: Story = {
122
+ render: function DisabledDatePickerStory() {
123
+ return (
124
+ <View style={styles.field}>
125
+ <DatePicker {...sharedDatePickerArgs} disabled value={figmaSampleDate} />
126
+ </View>
127
+ );
128
+ },
129
+ };
130
+
131
+ export const Range = {
132
+ render: function RangeDatePickerStory() {
133
+ const [value, setValue] = useState<DateRange | undefined>(getSampleRange);
134
+
135
+ return (
136
+ <View style={styles.field}>
137
+ <DatePicker
138
+ mode="range"
139
+ placeholder="Ընտրել ժամանակահատված"
140
+ locale="hy-AM"
141
+ defaultViewDate={getCurrentMonthStart()}
142
+ value={value}
143
+ onChange={setValue}
144
+ />
145
+ </View>
146
+ );
147
+ },
148
+ } satisfies StoryObj<DatePickerRangeProps>;
149
+
150
+ export const RangeOpen = {
151
+ render: function RangeOpenDatePickerStory() {
152
+ const [value, setValue] = useState<DateRange | undefined>(getSampleRange);
153
+
154
+ return (
155
+ <View style={styles.canvas}>
156
+ <DatePicker
157
+ mode="range"
158
+ locale="en-US"
159
+ defaultViewDate={getCurrentMonthStart()}
160
+ defaultOpen
161
+ closeOnRangeComplete={false}
162
+ value={value}
163
+ onChange={setValue}
164
+ />
165
+ </View>
166
+ );
167
+ },
168
+ } satisfies StoryObj<DatePickerRangeProps>;
169
+
170
+ export const RussianLocale: Story = {
171
+ render: function RussianDatePickerStory() {
172
+ const [value, setValue] = useState<Date | undefined>();
173
+
174
+ return (
175
+ <View style={styles.field}>
176
+ <DatePicker
177
+ mode="single"
178
+ locale="ru-RU"
179
+ defaultViewDate={getCurrentMonthStart()}
180
+ value={value}
181
+ onChange={setValue}
182
+ />
183
+ </View>
184
+ );
185
+ },
186
+ };
187
+
188
+ export const RangeInteractive = {
189
+ render: function RangeInteractiveDatePickerStory() {
190
+ const [value, setValue] = useState<DateRange | undefined>(getSampleRange);
191
+
192
+ return (
193
+ <View style={styles.canvas}>
194
+ <DatePicker
195
+ mode="range"
196
+ placeholder="Ընտրել ժամանակահատված"
197
+ locale="hy-AM"
198
+ defaultViewDate={getCurrentMonthStart()}
199
+ defaultOpen
200
+ closeOnRangeComplete={false}
201
+ value={value}
202
+ onChange={setValue}
203
+ />
204
+ </View>
205
+ );
206
+ },
207
+ } satisfies StoryObj<DatePickerRangeProps>;
208
+
209
+ const styles = StyleSheet.create({
210
+ field: {
211
+ width: 296,
212
+ maxWidth: "100%",
213
+ },
214
+ canvas: {
215
+ width: 296,
216
+ maxWidth: "100%",
217
+ minHeight: 520,
218
+ },
219
+ });