@dreamstack-us/kaal 0.0.2 → 0.0.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 (50) hide show
  1. package/README.md +165 -0
  2. package/lib/module/components/CalendarGrid/CalendarGrid.js +80 -18
  3. package/lib/module/components/CalendarGrid/CalendarGrid.js.map +1 -1
  4. package/lib/module/components/CalendarGrid/CalendarGrid.web.js +80 -18
  5. package/lib/module/components/CalendarGrid/CalendarGrid.web.js.map +1 -1
  6. package/lib/module/components/CalendarGrid/DayCell.js +17 -5
  7. package/lib/module/components/CalendarGrid/DayCell.js.map +1 -1
  8. package/lib/module/components/CalendarGrid/DayCell.web.js +17 -5
  9. package/lib/module/components/CalendarGrid/DayCell.web.js.map +1 -1
  10. package/lib/module/components/DatePicker/DatePicker.android.js +42 -19
  11. package/lib/module/components/DatePicker/DatePicker.android.js.map +1 -1
  12. package/lib/module/components/DatePicker/DatePicker.ios.js +44 -21
  13. package/lib/module/components/DatePicker/DatePicker.ios.js.map +1 -1
  14. package/lib/module/components/DatePicker/DatePicker.js.map +1 -1
  15. package/lib/module/components/DatePicker/DatePicker.web.js +40 -16
  16. package/lib/module/components/DatePicker/DatePicker.web.js.map +1 -1
  17. package/lib/module/index.js.map +1 -1
  18. package/lib/module/utils/date.js +3 -1
  19. package/lib/module/utils/date.js.map +1 -1
  20. package/lib/typescript/components/CalendarGrid/CalendarGrid.d.ts +19 -7
  21. package/lib/typescript/components/CalendarGrid/CalendarGrid.d.ts.map +1 -1
  22. package/lib/typescript/components/CalendarGrid/CalendarGrid.web.d.ts +19 -7
  23. package/lib/typescript/components/CalendarGrid/CalendarGrid.web.d.ts.map +1 -1
  24. package/lib/typescript/components/CalendarGrid/DayCell.d.ts +3 -0
  25. package/lib/typescript/components/CalendarGrid/DayCell.d.ts.map +1 -1
  26. package/lib/typescript/components/CalendarGrid/DayCell.web.d.ts +3 -0
  27. package/lib/typescript/components/CalendarGrid/DayCell.web.d.ts.map +1 -1
  28. package/lib/typescript/components/DatePicker/DatePicker.android.d.ts.map +1 -1
  29. package/lib/typescript/components/DatePicker/DatePicker.d.ts +20 -8
  30. package/lib/typescript/components/DatePicker/DatePicker.d.ts.map +1 -1
  31. package/lib/typescript/components/DatePicker/DatePicker.ios.d.ts.map +1 -1
  32. package/lib/typescript/components/DatePicker/DatePicker.web.d.ts.map +1 -1
  33. package/lib/typescript/index.d.ts +1 -1
  34. package/lib/typescript/index.d.ts.map +1 -1
  35. package/lib/typescript/types/datepicker.d.ts +37 -3
  36. package/lib/typescript/types/datepicker.d.ts.map +1 -1
  37. package/lib/typescript/utils/date.d.ts +2 -1
  38. package/lib/typescript/utils/date.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/components/CalendarGrid/CalendarGrid.tsx +216 -122
  41. package/src/components/CalendarGrid/CalendarGrid.web.tsx +227 -136
  42. package/src/components/CalendarGrid/DayCell.tsx +48 -6
  43. package/src/components/CalendarGrid/DayCell.web.tsx +48 -6
  44. package/src/components/DatePicker/DatePicker.android.tsx +39 -21
  45. package/src/components/DatePicker/DatePicker.ios.tsx +42 -24
  46. package/src/components/DatePicker/DatePicker.tsx +28 -8
  47. package/src/components/DatePicker/DatePicker.web.tsx +40 -16
  48. package/src/index.ts +2 -0
  49. package/src/types/datepicker.ts +43 -3
  50. package/src/utils/date.ts +4 -2
@@ -1,4 +1,4 @@
1
- import React, { Suspense, useCallback } from 'react';
1
+ import React, { Suspense } from 'react';
2
2
  import { ActivityIndicator, View } from 'react-native';
3
3
  import { ThemeOverrideProvider } from '../../context/ThemeOverrideContext';
4
4
  import { toISODateString } from '../../utils/date';
@@ -32,42 +32,60 @@ const ExpoDatePicker = React.lazy(async () => {
32
32
  }
33
33
  });
34
34
 
35
- export const DatePicker: React.FC<KaalDatePickerProps> = ({
36
- value,
37
- onChange,
38
- theme = 'native',
39
- minDate,
40
- maxDate,
41
- disabledDates,
42
- themeOverrides,
43
- weekStartsOn = 0,
44
- }) => {
45
- const handleDateChange = useCallback(
46
- (date: Date) => {
47
- onChange(date);
48
- },
49
- [onChange],
50
- );
35
+ export const DatePicker: React.FC<KaalDatePickerProps> = (props) => {
36
+ const {
37
+ theme = 'native',
38
+ minDate,
39
+ maxDate,
40
+ disabledDates,
41
+ themeOverrides,
42
+ weekStartsOn = 0,
43
+ } = props;
44
+
45
+ const themeMode = theme === 'native' ? 'android' : theme;
46
+
47
+ // Range mode
48
+ if (props.selectionMode === 'range') {
49
+ return (
50
+ <ThemeOverrideProvider value={{ datePicker: themeOverrides }}>
51
+ <CalendarGrid
52
+ selectionMode="range"
53
+ startDate={props.startDate}
54
+ endDate={props.endDate}
55
+ onRangeChange={props.onRangeChange}
56
+ minDate={minDate}
57
+ maxDate={maxDate}
58
+ disabledDates={disabledDates}
59
+ themeMode={themeMode}
60
+ weekStartsOn={weekStartsOn}
61
+ />
62
+ </ThemeOverrideProvider>
63
+ );
64
+ }
51
65
 
66
+ // Single selection mode
67
+ // Native picker only available for single selection
52
68
  if (theme === 'native') {
53
69
  return (
54
70
  <View style={styles.container}>
55
71
  <Suspense fallback={<ActivityIndicator />}>
56
- <ExpoDatePicker value={value} onChange={handleDateChange} />
72
+ <ExpoDatePicker value={props.value} onChange={props.onChange} />
57
73
  </Suspense>
58
74
  </View>
59
75
  );
60
76
  }
61
77
 
78
+ // Single selection with custom theme
62
79
  return (
63
80
  <ThemeOverrideProvider value={{ datePicker: themeOverrides }}>
64
81
  <CalendarGrid
65
- value={value}
66
- onChange={onChange}
82
+ selectionMode="single"
83
+ value={props.value}
84
+ onChange={props.onChange}
67
85
  minDate={minDate}
68
86
  maxDate={maxDate}
69
87
  disabledDates={disabledDates}
70
- themeMode={theme}
88
+ themeMode={themeMode}
71
89
  weekStartsOn={weekStartsOn}
72
90
  />
73
91
  </ThemeOverrideProvider>
@@ -1,4 +1,4 @@
1
- import React, { Suspense, useCallback } from 'react';
1
+ import React, { Suspense } from 'react';
2
2
  import { ActivityIndicator, View } from 'react-native';
3
3
  import { ThemeOverrideProvider } from '../../context/ThemeOverrideContext';
4
4
  import { toISODateString } from '../../utils/date';
@@ -35,32 +35,48 @@ const ExpoDatePicker = React.lazy(async () => {
35
35
  }
36
36
  });
37
37
 
38
- export const DatePicker: React.FC<KaalDatePickerProps> = ({
39
- value,
40
- onChange,
41
- mode = 'date',
42
- theme = 'native',
43
- variant = 'wheel',
44
- minDate,
45
- maxDate,
46
- disabledDates,
47
- themeOverrides,
48
- weekStartsOn = 0,
49
- }) => {
50
- const handleDateChange = useCallback(
51
- (date: Date) => {
52
- onChange(date);
53
- },
54
- [onChange],
55
- );
38
+ export const DatePicker: React.FC<KaalDatePickerProps> = (props) => {
39
+ const {
40
+ mode = 'date',
41
+ theme = 'native',
42
+ variant = 'wheel',
43
+ minDate,
44
+ maxDate,
45
+ disabledDates,
46
+ themeOverrides,
47
+ weekStartsOn = 0,
48
+ } = props;
49
+
50
+ const themeMode = theme === 'native' ? 'ios' : theme;
51
+
52
+ // Range mode
53
+ if (props.selectionMode === 'range') {
54
+ return (
55
+ <ThemeOverrideProvider value={{ datePicker: themeOverrides }}>
56
+ <CalendarGrid
57
+ selectionMode="range"
58
+ startDate={props.startDate}
59
+ endDate={props.endDate}
60
+ onRangeChange={props.onRangeChange}
61
+ minDate={minDate}
62
+ maxDate={maxDate}
63
+ disabledDates={disabledDates}
64
+ themeMode={themeMode}
65
+ weekStartsOn={weekStartsOn}
66
+ />
67
+ </ThemeOverrideProvider>
68
+ );
69
+ }
56
70
 
71
+ // Single selection mode
72
+ // Native picker only available for single selection
57
73
  if (theme === 'native') {
58
74
  return (
59
75
  <View style={styles.container}>
60
76
  <Suspense fallback={<ActivityIndicator />}>
61
77
  <ExpoDatePicker
62
- value={value}
63
- onChange={handleDateChange}
78
+ value={props.value}
79
+ onChange={props.onChange}
64
80
  variant={variant}
65
81
  />
66
82
  </Suspense>
@@ -68,15 +84,17 @@ export const DatePicker: React.FC<KaalDatePickerProps> = ({
68
84
  );
69
85
  }
70
86
 
87
+ // Single selection with custom theme
71
88
  return (
72
89
  <ThemeOverrideProvider value={{ datePicker: themeOverrides }}>
73
90
  <CalendarGrid
74
- value={value}
75
- onChange={onChange}
91
+ selectionMode="single"
92
+ value={props.value}
93
+ onChange={props.onChange}
76
94
  minDate={minDate}
77
95
  maxDate={maxDate}
78
96
  disabledDates={disabledDates}
79
- themeMode={theme}
97
+ themeMode={themeMode}
80
98
  weekStartsOn={weekStartsOn}
81
99
  />
82
100
  </ThemeOverrideProvider>
@@ -1,9 +1,11 @@
1
1
  import type React from 'react';
2
- import type { DatePickerMode, DatePickerThemeOverrides } from '../../types';
2
+ import type {
3
+ DatePickerMode,
4
+ DatePickerThemeOverrides,
5
+ DateRange,
6
+ } from '../../types';
3
7
 
4
- export interface KaalDatePickerProps {
5
- value: Date;
6
- onChange: (date: Date) => void;
8
+ interface KaalDatePickerBaseProps {
7
9
  mode?: DatePickerMode;
8
10
  theme?: 'native' | 'ios' | 'android' | 'custom';
9
11
  variant?: 'wheel' | 'calendar' | 'compact';
@@ -14,16 +16,34 @@ export interface KaalDatePickerProps {
14
16
  /**
15
17
  * First day of the week: 0 = Sunday, 1 = Monday
16
18
  * @default 0 (Sunday)
17
- *
18
- * TODO: This is a temporary solution. In the future, we need to add full
19
- * locale support to handle different calendar formats, layouts, and
20
- * localized day/month names across different regions.
21
19
  */
22
20
  weekStartsOn?: 0 | 1;
23
21
  /** Custom theme overrides for styling without matching Kaal's theme structure */
24
22
  themeOverrides?: DatePickerThemeOverrides;
25
23
  }
26
24
 
25
+ interface KaalDatePickerSingleProps extends KaalDatePickerBaseProps {
26
+ selectionMode?: 'single';
27
+ value: Date;
28
+ onChange: (date: Date) => void;
29
+ startDate?: never;
30
+ endDate?: never;
31
+ onRangeChange?: never;
32
+ }
33
+
34
+ interface KaalDatePickerRangeProps extends KaalDatePickerBaseProps {
35
+ selectionMode: 'range';
36
+ startDate: Date | null;
37
+ endDate: Date | null;
38
+ onRangeChange: (range: DateRange) => void;
39
+ value?: never;
40
+ onChange?: never;
41
+ }
42
+
43
+ export type KaalDatePickerProps =
44
+ | KaalDatePickerSingleProps
45
+ | KaalDatePickerRangeProps;
46
+
27
47
  // Platform-specific implementations are handled by Metro's file resolution
28
48
  // This file serves as the type definition and fallback
29
49
  export const DatePicker: React.FC<KaalDatePickerProps> = (_props) => {
@@ -4,23 +4,46 @@ import { CalendarGrid } from '../CalendarGrid';
4
4
  import { WheelPicker } from '../WheelPicker';
5
5
  import type { KaalDatePickerProps } from './DatePicker';
6
6
 
7
- export const DatePicker: React.FC<KaalDatePickerProps> = ({
8
- value,
9
- onChange,
10
- theme = 'ios',
11
- variant = 'calendar',
12
- minDate,
13
- maxDate,
14
- disabledDates,
15
- themeOverrides,
16
- weekStartsOn = 0,
17
- }) => {
7
+ export const DatePicker: React.FC<KaalDatePickerProps> = (props) => {
8
+ const {
9
+ theme = 'ios',
10
+ variant = 'calendar',
11
+ minDate,
12
+ maxDate,
13
+ disabledDates,
14
+ themeOverrides,
15
+ weekStartsOn = 0,
16
+ } = props;
17
+
18
+ const themeMode = theme === 'native' ? 'ios' : theme;
19
+
20
+ // Range mode
21
+ if (props.selectionMode === 'range') {
22
+ return (
23
+ <ThemeOverrideProvider value={{ datePicker: themeOverrides }}>
24
+ <CalendarGrid
25
+ selectionMode="range"
26
+ startDate={props.startDate}
27
+ endDate={props.endDate}
28
+ onRangeChange={props.onRangeChange}
29
+ minDate={minDate}
30
+ maxDate={maxDate}
31
+ disabledDates={disabledDates}
32
+ themeMode={themeMode}
33
+ weekStartsOn={weekStartsOn}
34
+ />
35
+ </ThemeOverrideProvider>
36
+ );
37
+ }
38
+
39
+ // Single selection mode (default)
40
+ // Wheel picker only supports single selection
18
41
  if (theme === 'ios' && variant === 'wheel') {
19
42
  return (
20
43
  <ThemeOverrideProvider value={{ datePicker: themeOverrides }}>
21
44
  <WheelPicker
22
- value={value}
23
- onChange={onChange}
45
+ value={props.value}
46
+ onChange={props.onChange}
24
47
  minDate={minDate}
25
48
  maxDate={maxDate}
26
49
  />
@@ -31,12 +54,13 @@ export const DatePicker: React.FC<KaalDatePickerProps> = ({
31
54
  return (
32
55
  <ThemeOverrideProvider value={{ datePicker: themeOverrides }}>
33
56
  <CalendarGrid
34
- value={value}
35
- onChange={onChange}
57
+ selectionMode="single"
58
+ value={props.value}
59
+ onChange={props.onChange}
36
60
  minDate={minDate}
37
61
  maxDate={maxDate}
38
62
  disabledDates={disabledDates}
39
- themeMode={theme === 'native' ? 'ios' : theme}
63
+ themeMode={themeMode}
40
64
  weekStartsOn={weekStartsOn}
41
65
  />
42
66
  </ThemeOverrideProvider>
package/src/index.ts CHANGED
@@ -64,8 +64,10 @@ export type {
64
64
  DatePickerMode,
65
65
  DatePickerTheme,
66
66
  DatePickerVariant,
67
+ DatePickerSelectionMode,
67
68
  DatePickerProps,
68
69
  DatePickerThemeOverrides,
70
+ DateRange as DatePickerDateRange,
69
71
  } from './types';
70
72
 
71
73
  // Time picker types
@@ -4,6 +4,13 @@ export type DatePickerTheme = 'native' | 'ios' | 'android' | 'custom';
4
4
 
5
5
  export type DatePickerVariant = 'wheel' | 'calendar' | 'compact';
6
6
 
7
+ export type DatePickerSelectionMode = 'single' | 'range';
8
+
9
+ export interface DateRange {
10
+ startDate: Date;
11
+ endDate: Date | null;
12
+ }
13
+
7
14
  /**
8
15
  * Theme overrides for DatePicker components.
9
16
  * These allow customizing colors without matching Kaal's internal theme structure.
@@ -35,11 +42,16 @@ export interface DatePickerThemeOverrides {
35
42
  cellBorderRadius?: number;
36
43
  /** Padding for calendar container */
37
44
  padding?: number;
45
+ /** Background color for dates in range (between start and end) */
46
+ cellInRangeColor?: string;
47
+ /** Text color for dates in range */
48
+ textInRangeColor?: string;
38
49
  }
39
50
 
40
- export interface DatePickerProps {
41
- value: Date;
42
- onChange: (date: Date) => void;
51
+ /**
52
+ * Base props shared between single and range selection modes
53
+ */
54
+ interface DatePickerBaseProps {
43
55
  mode?: DatePickerMode;
44
56
  theme?: DatePickerTheme;
45
57
  variant?: DatePickerVariant;
@@ -59,3 +71,31 @@ export interface DatePickerProps {
59
71
  /** Custom theme overrides for styling without matching Kaal's theme structure */
60
72
  themeOverrides?: DatePickerThemeOverrides;
61
73
  }
74
+
75
+ /**
76
+ * Props for single date selection mode (default)
77
+ */
78
+ interface DatePickerSingleProps extends DatePickerBaseProps {
79
+ selectionMode?: 'single';
80
+ value: Date;
81
+ onChange: (date: Date) => void;
82
+ // Range props should not be present
83
+ startDate?: never;
84
+ endDate?: never;
85
+ onRangeChange?: never;
86
+ }
87
+
88
+ /**
89
+ * Props for range selection mode
90
+ */
91
+ interface DatePickerRangeProps extends DatePickerBaseProps {
92
+ selectionMode: 'range';
93
+ startDate: Date | null;
94
+ endDate: Date | null;
95
+ onRangeChange: (range: DateRange) => void;
96
+ // Single props should not be present
97
+ value?: never;
98
+ onChange?: never;
99
+ }
100
+
101
+ export type DatePickerProps = DatePickerSingleProps | DatePickerRangeProps;
package/src/utils/date.ts CHANGED
@@ -157,9 +157,11 @@ export const getMonthDays = (year: number, month: number): Date[] => {
157
157
 
158
158
  /**
159
159
  * Gets the first day of the month
160
+ * Falls back to today if date is undefined/null
160
161
  */
161
- export const getFirstDayOfMonth = (date: Date): Date => {
162
- return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
162
+ export const getFirstDayOfMonth = (date: Date | null | undefined): Date => {
163
+ const d = date ?? today();
164
+ return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), 1));
163
165
  };
164
166
 
165
167
  /**