@korsolutions/ui 0.0.20 → 0.0.22

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 (46) hide show
  1. package/dist/components/index.d.mts +50 -2
  2. package/dist/components/index.mjs +177 -4
  3. package/dist/hooks/index.d.mts +32 -2
  4. package/dist/hooks/index.mjs +79 -2
  5. package/dist/{index-CGY0mO6z.d.mts → index-vgnXBa4Z.d.mts} +98 -10
  6. package/dist/index.d.mts +3 -3
  7. package/dist/index.mjs +3 -2
  8. package/dist/primitives/index.d.mts +3 -2
  9. package/dist/primitives/index.mjs +3 -2
  10. package/dist/{primitives-P_8clvQr.mjs → primitives-ApsPS0vU.mjs} +335 -118
  11. package/dist/{toast-manager-DSo9oN8w.mjs → toast-manager-Cdhl1ep0.mjs} +1 -1
  12. package/dist/use-numeric-mask-B9WZG25o.d.mts +33 -0
  13. package/dist/use-numeric-mask-BQlz1Pus.mjs +113 -0
  14. package/dist/use-relative-position-BTKEyT1F.mjs +106 -0
  15. package/dist/use-relative-position-DBzhrBU7.d.mts +61 -0
  16. package/package.json +1 -1
  17. package/src/components/calendar/calendar.tsx +31 -0
  18. package/src/components/calendar/index.ts +1 -0
  19. package/src/components/calendar/variants/default.tsx +127 -0
  20. package/src/components/calendar/variants/index.ts +5 -0
  21. package/src/components/index.ts +2 -1
  22. package/src/components/input/index.ts +2 -0
  23. package/src/components/input/numeric-input.tsx +73 -0
  24. package/src/hooks/index.ts +4 -1
  25. package/src/hooks/use-currency-mask.ts +141 -0
  26. package/src/hooks/use-numeric-mask.ts +202 -0
  27. package/src/primitives/calendar/calendar-day.tsx +64 -0
  28. package/src/primitives/calendar/calendar-header.tsx +21 -0
  29. package/src/primitives/calendar/calendar-nav-button.tsx +60 -0
  30. package/src/primitives/calendar/calendar-root.tsx +41 -0
  31. package/src/primitives/calendar/calendar-title.tsx +23 -0
  32. package/src/primitives/calendar/calendar-week-labels.tsx +45 -0
  33. package/src/primitives/calendar/calendar-weeks.tsx +47 -0
  34. package/src/primitives/calendar/context.ts +23 -0
  35. package/src/primitives/calendar/index.ts +26 -0
  36. package/src/primitives/calendar/types.ts +39 -0
  37. package/src/primitives/dropdown-menu/context.ts +1 -1
  38. package/src/primitives/dropdown-menu/dropdown-menu-content.tsx +1 -1
  39. package/src/primitives/dropdown-menu/dropdown-menu-root.tsx +1 -1
  40. package/src/primitives/index.ts +1 -0
  41. package/src/primitives/popover/context.ts +1 -1
  42. package/src/primitives/popover/popover-content.tsx +1 -1
  43. package/src/primitives/popover/popover-root.tsx +1 -1
  44. package/src/utils/date-utils.ts +113 -0
  45. /package/src/hooks/{useRelativePosition.ts → use-relative-position.ts} +0 -0
  46. /package/src/hooks/{useScreenSize.ts → use-screen-size.ts} +0 -0
@@ -0,0 +1,202 @@
1
+ import { useState, useCallback } from "react";
2
+
3
+ export type NumericMaskFormat = "currency" | "decimal" | "integer" | "percentage";
4
+
5
+ export interface UseNumericMaskOptions {
6
+ format?: NumericMaskFormat;
7
+ locale?: string;
8
+ currency?: string;
9
+ precision?: number;
10
+ min?: number;
11
+ max?: number;
12
+ allowNegative?: boolean;
13
+ onChange?: (value: number | null) => void;
14
+ }
15
+
16
+ export interface UseNumericMaskReturn {
17
+ value: string;
18
+ numericValue: number | null;
19
+ onChangeText: (text: string) => void;
20
+ onBlur: () => void;
21
+ onFocus: () => void;
22
+ keyboardType: "numeric" | "decimal-pad" | "number-pad";
23
+ setValue: (value: number | null) => void;
24
+ }
25
+
26
+ export function useNumericMask({
27
+ format = "decimal",
28
+ locale = "en-US",
29
+ currency = "USD",
30
+ precision = 2,
31
+ min,
32
+ max,
33
+ allowNegative = true,
34
+ onChange,
35
+ }: UseNumericMaskOptions = {}): UseNumericMaskReturn {
36
+ const [numericValue, setNumericValue] = useState<number | null>(null);
37
+ const [displayValue, setDisplayValue] = useState("");
38
+ const [isFocused, setIsFocused] = useState(false);
39
+
40
+ // Determine actual precision based on format
41
+ const effectivePrecision = format === "integer" ? 0 : precision;
42
+
43
+ const formatValue = useCallback(
44
+ (num: number | null): string => {
45
+ if (num === null || isNaN(num)) return "";
46
+
47
+ switch (format) {
48
+ case "currency":
49
+ return new Intl.NumberFormat(locale, {
50
+ style: "currency",
51
+ currency,
52
+ minimumFractionDigits: effectivePrecision,
53
+ maximumFractionDigits: effectivePrecision,
54
+ }).format(num);
55
+
56
+ case "percentage":
57
+ return new Intl.NumberFormat(locale, {
58
+ style: "percent",
59
+ minimumFractionDigits: effectivePrecision,
60
+ maximumFractionDigits: effectivePrecision,
61
+ }).format(num / 100);
62
+
63
+ case "integer":
64
+ return new Intl.NumberFormat(locale, {
65
+ minimumFractionDigits: 0,
66
+ maximumFractionDigits: 0,
67
+ }).format(num);
68
+
69
+ case "decimal":
70
+ default:
71
+ return new Intl.NumberFormat(locale, {
72
+ minimumFractionDigits: effectivePrecision,
73
+ maximumFractionDigits: effectivePrecision,
74
+ }).format(num);
75
+ }
76
+ },
77
+ [format, locale, currency, effectivePrecision]
78
+ );
79
+
80
+ const parseValue = useCallback(
81
+ (text: string): number | null => {
82
+ // Remove currency symbols, spaces, thousand separators, and percentage signs
83
+ let cleaned = text.replace(/[^\d.-]/g, "");
84
+
85
+ // Handle negative sign
86
+ if (!allowNegative) {
87
+ cleaned = cleaned.replace(/-/g, "");
88
+ }
89
+
90
+ const parsed = parseFloat(cleaned);
91
+
92
+ if (isNaN(parsed) || cleaned === "" || cleaned === "-") return null;
93
+
94
+ // Apply min/max constraints
95
+ let constrained = parsed;
96
+ if (min !== undefined && constrained < min) constrained = min;
97
+ if (max !== undefined && constrained > max) constrained = max;
98
+
99
+ return constrained;
100
+ },
101
+ [min, max, allowNegative]
102
+ );
103
+
104
+ const handleChangeText = useCallback(
105
+ (text: string) => {
106
+ // When focused, validate input before allowing it
107
+ if (isFocused) {
108
+ // Remove formatting characters to get raw input
109
+ let cleaned = text.replace(/[^\d.-]/g, "");
110
+
111
+ // Validate negative sign
112
+ if (!allowNegative && cleaned.includes("-")) {
113
+ return;
114
+ }
115
+
116
+ // Ensure negative sign is only at the start
117
+ if (allowNegative) {
118
+ const negativeCount = (cleaned.match(/-/g) || []).length;
119
+ if (negativeCount > 1 || (cleaned.includes("-") && cleaned.indexOf("-") !== 0)) {
120
+ return;
121
+ }
122
+ }
123
+
124
+ // Check decimal precision (skip for integer format)
125
+ if (effectivePrecision >= 0) {
126
+ const decimalIndex = cleaned.indexOf(".");
127
+ if (decimalIndex !== -1) {
128
+ const decimalPart = cleaned.substring(decimalIndex + 1);
129
+
130
+ // Prevent typing more decimals than allowed precision
131
+ if (decimalPart.length > effectivePrecision) {
132
+ return;
133
+ }
134
+ }
135
+
136
+ // Prevent multiple decimal points
137
+ const decimalCount = (cleaned.match(/\./g) || []).length;
138
+ if (decimalCount > 1) {
139
+ return;
140
+ }
141
+
142
+ // Prevent decimal point for integer format
143
+ if (format === "integer" && cleaned.includes(".")) {
144
+ return;
145
+ }
146
+ }
147
+ }
148
+
149
+ setDisplayValue(text);
150
+ const value = parseValue(text);
151
+ setNumericValue(value);
152
+ onChange?.(value);
153
+ },
154
+ [parseValue, onChange, isFocused, effectivePrecision, allowNegative, format]
155
+ );
156
+
157
+ const handleBlur = useCallback(() => {
158
+ setIsFocused(false);
159
+ if (numericValue !== null) {
160
+ setDisplayValue(formatValue(numericValue));
161
+ } else {
162
+ setDisplayValue("");
163
+ }
164
+ }, [numericValue, formatValue]);
165
+
166
+ const handleFocus = useCallback(() => {
167
+ setIsFocused(true);
168
+ if (numericValue !== null) {
169
+ setDisplayValue(numericValue.toString());
170
+ }
171
+ }, [numericValue]);
172
+
173
+ const setValue = useCallback(
174
+ (value: number | null) => {
175
+ setNumericValue(value);
176
+ if (value !== null) {
177
+ if (isFocused) {
178
+ setDisplayValue(value.toString());
179
+ } else {
180
+ setDisplayValue(formatValue(value));
181
+ }
182
+ } else {
183
+ setDisplayValue("");
184
+ }
185
+ onChange?.(value);
186
+ },
187
+ [isFocused, formatValue, onChange]
188
+ );
189
+
190
+ // Determine keyboard type based on format
191
+ const keyboardType = format === "integer" ? (allowNegative ? ("numeric" as const) : ("number-pad" as const)) : ("decimal-pad" as const);
192
+
193
+ return {
194
+ value: displayValue,
195
+ numericValue,
196
+ onChangeText: handleChangeText,
197
+ onBlur: handleBlur,
198
+ onFocus: handleFocus,
199
+ keyboardType,
200
+ setValue,
201
+ };
202
+ }
@@ -0,0 +1,64 @@
1
+ import React, { useMemo, useState } from "react";
2
+ import { Text, StyleProp, TextStyle, ViewStyle, Pressable } from "react-native";
3
+ import { formatDate, isDateSameDay, isDateToday, isDateBefore, isDateAfter, isSameMonth } from "@/utils/date-utils";
4
+ import { useCalendarContext } from "./context";
5
+ import { CalendarDayState } from "./types";
6
+
7
+ export interface CalendarDayProps {
8
+ date: Date;
9
+ onPress?: () => void;
10
+
11
+ style?: StyleProp<ViewStyle>;
12
+ textStyle?: StyleProp<TextStyle>;
13
+ }
14
+
15
+ const calculateState = (
16
+ date: Date,
17
+ selected: Date | undefined,
18
+ isCurrentMonth: boolean,
19
+ isDisabled: boolean,
20
+ isHovered: boolean
21
+ ): CalendarDayState => {
22
+ if (isDisabled) return "disabled";
23
+ if (selected && isDateSameDay(date, selected)) return "selected";
24
+ if (isDateToday(date)) return "today";
25
+ if (isHovered) return "hovered";
26
+ if (!isCurrentMonth) return "deprioritized";
27
+ return "default";
28
+ };
29
+
30
+ export function CalendarDay(props: CalendarDayProps) {
31
+ const calendar = useCalendarContext();
32
+ const [isHovered, setIsHovered] = useState(false);
33
+
34
+ const isCurrentMonth = isSameMonth(props.date, calendar.currentMonth);
35
+
36
+ const isDisabled = useMemo(() => {
37
+ if (calendar.minDate && isDateBefore(props.date, calendar.minDate)) return true;
38
+ if (calendar.maxDate && isDateAfter(props.date, calendar.maxDate)) return true;
39
+ return false;
40
+ }, [props.date, calendar.minDate, calendar.maxDate]);
41
+
42
+ const state = calculateState(props.date, calendar.value, isCurrentMonth, isDisabled, isHovered);
43
+
44
+ const handlePress = () => {
45
+ console.log("Day pressed:", isDisabled, calendar.onChange);
46
+ if (isDisabled || !calendar.onChange) return;
47
+ calendar.onChange(props.date);
48
+ };
49
+
50
+ const composedStyle = [calendar.styles?.dayButton?.default, calendar.styles?.dayButton?.[state], props.style];
51
+ const composedTextStyle = [calendar.styles?.dayText?.default, calendar.styles?.dayText?.[state], props.textStyle];
52
+
53
+ return (
54
+ <Pressable
55
+ onPress={handlePress}
56
+ onHoverIn={() => setIsHovered(true)}
57
+ onHoverOut={() => setIsHovered(false)}
58
+ disabled={isDisabled}
59
+ style={composedStyle}
60
+ >
61
+ <Text style={composedTextStyle}>{formatDate(props.date, "d")}</Text>
62
+ </Pressable>
63
+ );
64
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { View, ViewProps, StyleProp, ViewStyle } from "react-native";
3
+ import { useCalendarContext } from "./context";
4
+
5
+ export interface CalendarHeaderProps extends ViewProps {
6
+ children?: React.ReactNode;
7
+ style?: StyleProp<ViewStyle>;
8
+ }
9
+
10
+ export function CalendarHeader(props: CalendarHeaderProps) {
11
+ const { children, style, ...viewProps } = props;
12
+ const { styles } = useCalendarContext();
13
+
14
+ const headerStyle = [styles?.header, style];
15
+
16
+ return (
17
+ <View {...viewProps} style={headerStyle}>
18
+ {children}
19
+ </View>
20
+ );
21
+ }
@@ -0,0 +1,60 @@
1
+ import React, { useState } from "react";
2
+ import { Pressable, PressableProps, Text, StyleProp, ViewStyle, TextStyle } from "react-native";
3
+ import { addMonths, subMonths } from "../../utils/date-utils";
4
+ import { useCalendarContext } from "./context";
5
+ import { CalendarNavButtonState } from "./types";
6
+
7
+ export interface CalendarNavButtonProps extends PressableProps {
8
+ children?: React.ReactNode;
9
+ direction: "prev" | "next";
10
+ style?: StyleProp<ViewStyle>;
11
+ textStyle?: StyleProp<TextStyle>;
12
+ }
13
+
14
+ const calculateState = (isDisabled: boolean, isHovered: boolean): CalendarNavButtonState => {
15
+ if (isDisabled) return "disabled";
16
+ if (isHovered) return "hovered";
17
+ return "default";
18
+ };
19
+
20
+ export function CalendarNavButton(props: CalendarNavButtonProps) {
21
+ const { children = props.direction === "prev" ? "‹" : "›", direction, style, textStyle, ...pressableProps } = props;
22
+ const { currentMonth, setCurrentMonth, minDate, maxDate, styles } = useCalendarContext();
23
+ const [isHovered, setIsHovered] = useState(false);
24
+
25
+ const isDisabled = React.useMemo(() => {
26
+ if (direction === "prev" && minDate) {
27
+ const prevMonth = subMonths(currentMonth, 1);
28
+ return prevMonth < minDate;
29
+ }
30
+ if (direction === "next" && maxDate) {
31
+ const nextMonth = addMonths(currentMonth, 1);
32
+ return nextMonth > maxDate;
33
+ }
34
+ return false;
35
+ }, [direction, currentMonth, minDate, maxDate]);
36
+
37
+ const state = calculateState(isDisabled, isHovered);
38
+
39
+ const handlePress = () => {
40
+ if (isDisabled) return;
41
+ const newMonth = direction === "prev" ? subMonths(currentMonth, 1) : addMonths(currentMonth, 1);
42
+ setCurrentMonth(newMonth);
43
+ };
44
+
45
+ const buttonStyle = [styles?.navButton?.default, styles?.navButton?.[state], style];
46
+ const textStyleCombined = [styles?.navButtonText?.default, styles?.navButtonText?.[state], textStyle];
47
+
48
+ return (
49
+ <Pressable
50
+ {...pressableProps}
51
+ onPress={handlePress}
52
+ onHoverIn={() => setIsHovered(true)}
53
+ onHoverOut={() => setIsHovered(false)}
54
+ disabled={isDisabled}
55
+ style={buttonStyle}
56
+ >
57
+ <Text style={textStyleCombined}>{children}</Text>
58
+ </Pressable>
59
+ );
60
+ }
@@ -0,0 +1,41 @@
1
+ import React, { useState } from "react";
2
+ import { View, StyleProp, ViewStyle } from "react-native";
3
+ import { CalendarStyles } from "./types";
4
+ import { CalendarContext } from "./context";
5
+
6
+ export interface CalendarRootProps {
7
+ children?: React.ReactNode;
8
+ value?: Date;
9
+ onChange?: (date: Date | undefined) => void;
10
+ defaultMonth?: Date;
11
+ minDate?: Date;
12
+ maxDate?: Date;
13
+ style?: StyleProp<ViewStyle>;
14
+ styles?: CalendarStyles;
15
+ }
16
+
17
+ export function CalendarRoot(props: CalendarRootProps) {
18
+ const { children, value, onChange, defaultMonth = new Date(), minDate, maxDate, style, styles, ...viewProps } = props;
19
+
20
+ const [currentMonth, setCurrentMonth] = useState<Date>(defaultMonth);
21
+
22
+ const containerStyle = [styles?.root, style];
23
+
24
+ return (
25
+ <CalendarContext.Provider
26
+ value={{
27
+ value,
28
+ onChange,
29
+ currentMonth,
30
+ setCurrentMonth,
31
+ styles,
32
+ minDate,
33
+ maxDate,
34
+ }}
35
+ >
36
+ <View {...viewProps} style={containerStyle}>
37
+ {children}
38
+ </View>
39
+ </CalendarContext.Provider>
40
+ );
41
+ }
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ import { Text, TextProps, StyleProp, TextStyle } from "react-native";
3
+ import { formatDate } from "../../utils/date-utils";
4
+ import { useCalendarContext } from "./context";
5
+
6
+ export interface CalendarTitleProps extends TextProps {
7
+ children?: React.ReactNode;
8
+ style?: StyleProp<TextStyle>;
9
+ formatStr?: string;
10
+ }
11
+
12
+ export function CalendarTitle(props: CalendarTitleProps) {
13
+ const { children, style, formatStr = "MMMM yyyy", ...textProps } = props;
14
+ const { currentMonth, styles } = useCalendarContext();
15
+
16
+ const titleStyle = [styles?.headerTitle, style];
17
+
18
+ return (
19
+ <Text {...textProps} style={titleStyle}>
20
+ {children ?? formatDate(currentMonth, formatStr)}
21
+ </Text>
22
+ );
23
+ }
@@ -0,0 +1,45 @@
1
+ import React from "react";
2
+ import { View, Text, StyleProp, ViewStyle, TextStyle } from "react-native";
3
+ import { useCalendarContext } from "./context";
4
+
5
+ export interface CalendarWeekLabelProps {
6
+ children: string;
7
+ style?: StyleProp<TextStyle>;
8
+ }
9
+
10
+ function CalendarWeekLabel(props: CalendarWeekLabelProps) {
11
+ const { styles } = useCalendarContext();
12
+
13
+ const composedStyle = [styles?.weekLabel, props.style];
14
+
15
+ return (
16
+ <Text numberOfLines={1} style={composedStyle}>
17
+ {props.children}
18
+ </Text>
19
+ );
20
+ }
21
+
22
+ export interface CalendarWeekLabelsProps {
23
+ weekDays?: string[];
24
+
25
+ style?: StyleProp<ViewStyle>;
26
+ }
27
+
28
+ const DEFAULT_WEEK_DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
29
+
30
+ export function CalendarWeekLabels(props: CalendarWeekLabelsProps) {
31
+ const { weekDays = DEFAULT_WEEK_DAYS, style } = props;
32
+ const { styles } = useCalendarContext();
33
+
34
+ const composedStyle = [styles?.weekLabels, style];
35
+
36
+ return (
37
+ <View style={composedStyle}>
38
+ {weekDays.map((day, index) => (
39
+ <CalendarWeekLabel key={index} style={styles?.weekLabel}>
40
+ {day}
41
+ </CalendarWeekLabel>
42
+ ))}
43
+ </View>
44
+ );
45
+ }
@@ -0,0 +1,47 @@
1
+ import React from "react";
2
+ import { View, ViewProps, StyleProp, ViewStyle } from "react-native";
3
+ import { getWeekDays, getWeeksInMonth } from "@/utils/date-utils";
4
+ import { useCalendarContext } from "./context";
5
+ import { CalendarDay } from "./calendar-day";
6
+
7
+ export interface CalendarWeekProps extends ViewProps {
8
+ index: number;
9
+
10
+ style?: StyleProp<ViewStyle>;
11
+ }
12
+
13
+ function CalendarWeek(props: CalendarWeekProps) {
14
+ const { style, ...viewProps } = props;
15
+ const { currentMonth, styles } = useCalendarContext();
16
+
17
+ const days = getWeekDays(currentMonth.getMonth(), currentMonth.getFullYear(), props.index);
18
+
19
+ const composedStyle = [styles?.week, style];
20
+ return (
21
+ <View {...viewProps} style={composedStyle}>
22
+ {days.map((day, index) => {
23
+ return <CalendarDay key={index} date={day} />;
24
+ })}
25
+ </View>
26
+ );
27
+ }
28
+
29
+ export interface CalendarWeeksProps extends ViewProps {
30
+ style?: StyleProp<ViewStyle>;
31
+ }
32
+
33
+ export function CalendarWeeks(props: CalendarWeeksProps) {
34
+ const { currentMonth, styles } = useCalendarContext();
35
+
36
+ const weeks = getWeeksInMonth(currentMonth);
37
+
38
+ const composedStyle = [styles?.weeks, props.style];
39
+
40
+ return (
41
+ <View style={composedStyle}>
42
+ {Array.from({ length: weeks }).map((_, index) => {
43
+ return <CalendarWeek key={index} index={index} />;
44
+ })}
45
+ </View>
46
+ );
47
+ }
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ import { CalendarStyles } from "./types";
3
+
4
+ export interface CalendarContextValue {
5
+ value?: Date;
6
+ onChange?: (date: Date | undefined) => void;
7
+ currentMonth: Date;
8
+ setCurrentMonth: (month: Date) => void;
9
+ minDate?: Date;
10
+ maxDate?: Date;
11
+
12
+ styles?: CalendarStyles;
13
+ }
14
+
15
+ export const CalendarContext = React.createContext<CalendarContextValue | undefined>(undefined);
16
+
17
+ export const useCalendarContext = () => {
18
+ const context = React.useContext(CalendarContext);
19
+ if (!context) {
20
+ throw new Error("Calendar components must be used within CalendarRoot");
21
+ }
22
+ return context;
23
+ };
@@ -0,0 +1,26 @@
1
+ import { CalendarRoot } from "./calendar-root";
2
+ import { CalendarHeader } from "./calendar-header";
3
+ import { CalendarTitle } from "./calendar-title";
4
+ import { CalendarNavButton } from "./calendar-nav-button";
5
+ import { CalendarWeekLabels } from "./calendar-week-labels";
6
+ import { CalendarWeeks } from "./calendar-weeks";
7
+ import { CalendarDay } from "./calendar-day";
8
+
9
+ export const CalendarPrimitive = {
10
+ Root: CalendarRoot,
11
+ Header: CalendarHeader,
12
+ Title: CalendarTitle,
13
+ NavButton: CalendarNavButton,
14
+ CalendarWeekLabels: CalendarWeekLabels,
15
+ Weeks: CalendarWeeks,
16
+ Day: CalendarDay,
17
+ };
18
+
19
+ export type { CalendarRootProps } from "./calendar-root";
20
+ export type { CalendarHeaderProps } from "./calendar-header";
21
+ export type { CalendarTitleProps } from "./calendar-title";
22
+ export type { CalendarNavButtonProps } from "./calendar-nav-button";
23
+ export type { CalendarWeekLabelsProps } from "./calendar-week-labels";
24
+ export type { CalendarWeeksProps } from "./calendar-weeks";
25
+ export type { CalendarDayProps } from "./calendar-day";
26
+ export type { CalendarStyles, CalendarDayState } from "./types";
@@ -0,0 +1,39 @@
1
+ import { ViewStyle, TextStyle } from "react-native";
2
+ import { CalendarWeekProps, CalendarWeeksProps } from "./calendar-weeks";
3
+ import { CalendarWeekLabelProps, CalendarWeekLabelsProps } from "./calendar-week-labels";
4
+ import { CalendarDayProps } from "./calendar-day";
5
+ import { CalendarRootProps } from "./calendar-root";
6
+ import { CalendarHeaderProps } from "./calendar-header";
7
+ import { CalendarTitleProps } from "./calendar-title";
8
+
9
+ export type CalendarDayState = "default" | "selected" | "today" | "disabled" | "deprioritized" | "hovered";
10
+ export type CalendarNavButtonState = "default" | "disabled" | "hovered";
11
+
12
+ export interface CalendarStyles {
13
+ root?: CalendarRootProps["style"];
14
+ header?: CalendarHeaderProps["style"];
15
+ headerTitle?: CalendarTitleProps["style"];
16
+ navButton?: Partial<Record<CalendarNavButtonState, ViewStyle>>;
17
+ navButtonText?: Partial<Record<CalendarNavButtonState, TextStyle>>;
18
+ weekLabels: CalendarWeekLabelsProps["style"];
19
+ weekLabel?: CalendarWeekLabelProps["style"];
20
+ weeks?: CalendarWeekProps["style"];
21
+ week?: CalendarWeeksProps["style"];
22
+ dayButton?: Partial<Record<CalendarDayState, CalendarDayProps["style"]>>;
23
+ dayText?: Partial<Record<CalendarDayState, CalendarDayProps["textStyle"]>>;
24
+ }
25
+
26
+ export type Months = [
27
+ january: number,
28
+ february: number,
29
+ march: number,
30
+ april: number,
31
+ may: number,
32
+ june: number,
33
+ july: number,
34
+ august: number,
35
+ september: number,
36
+ october: number,
37
+ november: number,
38
+ december: number
39
+ ];
@@ -1,7 +1,7 @@
1
1
  import { createContext, Dispatch, useContext } from "react";
2
2
  import { LayoutRectangle } from "react-native";
3
3
  import { DropdownMenuStyles } from "./types";
4
- import { LayoutPosition } from "@/hooks/useRelativePosition";
4
+ import { LayoutPosition } from "@/hooks/use-relative-position";
5
5
 
6
6
  export interface DropdownMenuContext {
7
7
  isOpen: boolean;
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { StyleProp, View, ViewStyle } from "react-native";
3
3
  import { useDropdownMenu } from "./context";
4
- import { useRelativePosition } from "@/hooks/useRelativePosition";
4
+ import { useRelativePosition } from "@/hooks/use-relative-position";
5
5
 
6
6
  export interface DropdownMenuContentProps {
7
7
  children?: React.ReactNode;
@@ -2,7 +2,7 @@ import React, { useState } from "react";
2
2
  import { LayoutRectangle } from "react-native";
3
3
  import { DropdownMenuStyles } from "./types";
4
4
  import { DropdownMenuContext } from "./context";
5
- import { DEFAULT_LAYOUT, DEFAULT_POSITION, LayoutPosition } from "@/hooks/useRelativePosition";
5
+ import { DEFAULT_LAYOUT, DEFAULT_POSITION, LayoutPosition } from "@/hooks/use-relative-position";
6
6
 
7
7
  export interface DropdownMenuRootProps {
8
8
  children?: React.ReactNode;
@@ -10,3 +10,4 @@ export * from "./badge";
10
10
  export * from "./textarea";
11
11
  export * from "./dropdown-menu";
12
12
  export * from "./popover";
13
+ export * from "./calendar";
@@ -1,7 +1,7 @@
1
1
  import { createContext, Dispatch, useContext } from "react";
2
2
  import { PopoverStyles } from "./types";
3
3
  import { LayoutRectangle } from "react-native";
4
- import { LayoutPosition } from "@/hooks/useRelativePosition";
4
+ import { LayoutPosition } from "@/hooks/use-relative-position";
5
5
 
6
6
  export interface PopoverContext {
7
7
  isOpen: boolean;
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { StyleProp, View, ViewStyle } from "react-native";
3
3
  import { usePopover } from "./context";
4
- import { useRelativePosition } from "@/hooks/useRelativePosition";
4
+ import { useRelativePosition } from "@/hooks/use-relative-position";
5
5
 
6
6
  export interface PopoverContentProps {
7
7
  children?: React.ReactNode;
@@ -2,7 +2,7 @@ import React, { useState } from "react";
2
2
  import { PopoverContext } from "./context";
3
3
  import { PopoverStyles } from "./types";
4
4
  import { LayoutRectangle } from "react-native";
5
- import { DEFAULT_LAYOUT, DEFAULT_POSITION, LayoutPosition } from "@/hooks/useRelativePosition";
5
+ import { DEFAULT_LAYOUT, DEFAULT_POSITION, LayoutPosition } from "@/hooks/use-relative-position";
6
6
 
7
7
  export interface PopoverRootProps {
8
8
  children?: React.ReactNode;