cpk-ui 0.7.0 → 0.8.0-beta.1

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 (52) hide show
  1. package/README.md +15 -14
  2. package/components/modals/AlertDialog/AlertDialog.d.ts +11 -5
  3. package/components/modals/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/components/modals/AlertDialog/AlertDialog.js +46 -36
  5. package/components/uis/Button/Button.d.ts.map +1 -1
  6. package/components/uis/Button/Button.js +16 -13
  7. package/components/uis/Calendar/Calendar.d.ts +6 -0
  8. package/components/uis/Calendar/Calendar.d.ts.map +1 -0
  9. package/components/uis/Calendar/Calendar.js +482 -0
  10. package/components/uis/Calendar/CalendarDay.d.ts +21 -0
  11. package/components/uis/Calendar/CalendarDay.d.ts.map +1 -0
  12. package/components/uis/Calendar/CalendarDay.js +172 -0
  13. package/components/uis/Calendar/CalendarHeader.d.ts +22 -0
  14. package/components/uis/Calendar/CalendarHeader.d.ts.map +1 -0
  15. package/components/uis/Calendar/CalendarHeader.js +40 -0
  16. package/components/uis/Calendar/CalendarPage.d.ts +46 -0
  17. package/components/uis/Calendar/CalendarPage.d.ts.map +1 -0
  18. package/components/uis/Calendar/CalendarPage.js +34 -0
  19. package/components/uis/Calendar/CalendarPager.d.ts +11 -0
  20. package/components/uis/Calendar/CalendarPager.d.ts.map +1 -0
  21. package/components/uis/Calendar/CalendarPager.js +115 -0
  22. package/components/uis/Calendar/CalendarPager.web.d.ts +11 -0
  23. package/components/uis/Calendar/CalendarPager.web.d.ts.map +1 -0
  24. package/components/uis/Calendar/CalendarPager.web.js +72 -0
  25. package/components/uis/Calendar/CalendarWeekRow.d.ts +20 -0
  26. package/components/uis/Calendar/CalendarWeekRow.d.ts.map +1 -0
  27. package/components/uis/Calendar/CalendarWeekRow.js +64 -0
  28. package/components/uis/Calendar/CalendarWeekdayRow.d.ts +24 -0
  29. package/components/uis/Calendar/CalendarWeekdayRow.d.ts.map +1 -0
  30. package/components/uis/Calendar/CalendarWeekdayRow.js +45 -0
  31. package/components/uis/Calendar/intl.d.ts +18 -0
  32. package/components/uis/Calendar/intl.d.ts.map +1 -0
  33. package/components/uis/Calendar/intl.js +146 -0
  34. package/components/uis/Calendar/palette.d.ts +10 -0
  35. package/components/uis/Calendar/palette.d.ts.map +1 -0
  36. package/components/uis/Calendar/palette.js +93 -0
  37. package/components/uis/Calendar/types.d.ts +286 -0
  38. package/components/uis/Calendar/types.d.ts.map +1 -0
  39. package/components/uis/Calendar/types.js +1 -0
  40. package/components/uis/Calendar/useCalendarState.d.ts +66 -0
  41. package/components/uis/Calendar/useCalendarState.d.ts.map +1 -0
  42. package/components/uis/Calendar/useCalendarState.js +211 -0
  43. package/components/uis/Calendar/utils.d.ts +114 -0
  44. package/components/uis/Calendar/utils.d.ts.map +1 -0
  45. package/components/uis/Calendar/utils.js +429 -0
  46. package/components/uis/ParallaxHeader/ParallaxHeader.d.ts +44 -0
  47. package/components/uis/ParallaxHeader/ParallaxHeader.d.ts.map +1 -0
  48. package/components/uis/ParallaxHeader/ParallaxHeader.js +142 -0
  49. package/index.d.ts +2 -0
  50. package/index.d.ts.map +1 -1
  51. package/index.js +2 -0
  52. package/package.json +2 -1
@@ -0,0 +1,22 @@
1
+ import React, { type ReactElement, type ReactNode } from 'react';
2
+ import type { CalendarHeaderContext, CalendarLabels, CalendarMetrics, CalendarPalette, CalendarStyles, CalendarViewMode } from './types';
3
+ export type CalendarHeaderProps = {
4
+ title: string;
5
+ mode: CalendarViewMode;
6
+ palette: CalendarPalette;
7
+ metrics: CalendarMetrics;
8
+ labels: Required<CalendarLabels>;
9
+ styles: CalendarStyles;
10
+ maxFontSizeMultiplier: number;
11
+ showNavigationButtons: boolean;
12
+ canGoPrevious: boolean;
13
+ canGoNext: boolean;
14
+ onPrevious: () => void;
15
+ onNext: () => void;
16
+ renderHeader?: (ctx: CalendarHeaderContext) => ReactNode;
17
+ headerContext: CalendarHeaderContext;
18
+ };
19
+ declare function CalendarHeaderContainer({ title, mode, palette, metrics, labels, styles, maxFontSizeMultiplier, showNavigationButtons, canGoPrevious, canGoNext, onPrevious, onNext, renderHeader, headerContext, }: CalendarHeaderProps): ReactElement;
20
+ export declare const CalendarHeader: React.MemoExoticComponent<typeof CalendarHeaderContainer>;
21
+ export default CalendarHeader;
22
+ //# sourceMappingURL=CalendarHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarHeader.d.ts","sourceRoot":"","sources":["../../../../src/components/uis/Calendar/CalendarHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,KAAK,YAAY,EAAE,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAM/D,OAAO,KAAK,EACV,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,EACd,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAyBjB,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,SAAS,CAAC;IACzD,aAAa,EAAE,qBAAqB,CAAC;CACtC,CAAC;AAEF,iBAAS,uBAAuB,CAAC,EAC/B,KAAK,EACL,IAAI,EACJ,OAAO,EACP,OAAO,EACP,MAAM,EACN,MAAM,EACN,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,SAAS,EACT,UAAU,EACV,MAAM,EACN,YAAY,EACZ,aAAa,GACd,EAAE,mBAAmB,GAAG,YAAY,CAiEpC;AAED,eAAO,MAAM,cAAc,2DAAsC,CAAC;AAElE,eAAe,cAAc,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { Text, View } from 'react-native';
4
+ import { css } from 'kstyled';
5
+ import { Icon } from '../Icon/Icon';
6
+ import { IconButton } from '../IconButton/IconButton';
7
+ const HEADER = css `
8
+ flex-direction: row;
9
+ align-items: center;
10
+ justify-content: space-between;
11
+ gap: 4px;
12
+ `;
13
+ const TITLE = css `
14
+ flex: 1;
15
+ text-align: center;
16
+ font-weight: 600;
17
+ `;
18
+ const NAV_BUTTON = css `
19
+ background-color: transparent;
20
+ border-color: transparent;
21
+ padding: 4px;
22
+ `;
23
+ const SPACER = css `
24
+ width: 40px;
25
+ `;
26
+ function CalendarHeaderContainer({ title, mode, palette, metrics, labels, styles, maxFontSizeMultiplier, showNavigationButtons, canGoPrevious, canGoNext, onPrevious, onNext, renderHeader, headerContext, }) {
27
+ if (renderHeader) {
28
+ return _jsx(View, { testID: "calendar-header", children: renderHeader(headerContext) });
29
+ }
30
+ const iconSize = Math.round(metrics.headerFontSize * 1.1);
31
+ const previousLabel = mode === 'week' ? labels.previousWeek : labels.previousMonth;
32
+ const nextLabel = mode === 'week' ? labels.nextWeek : labels.nextMonth;
33
+ return (_jsxs(View, { style: [HEADER, { height: metrics.headerHeight }, styles.header], testID: "calendar-header", children: [showNavigationButtons ? (_jsx(IconButton, { accessibilityLabel: previousLabel, disabled: !canGoPrevious, iconElement: _jsx(Icon, { color: palette.navIcon, name: "CaretLeft", size: iconSize }), onPress: onPrevious, size: iconSize, styles: { container: NAV_BUTTON, disabled: NAV_BUTTON }, testID: "calendar-prev", type: "text" })) : (_jsx(View, { style: SPACER })), _jsx(Text, { accessibilityLiveRegion: "polite", accessibilityRole: "header", maxFontSizeMultiplier: maxFontSizeMultiplier, numberOfLines: 1, style: [
34
+ TITLE,
35
+ { color: palette.headerText, fontSize: metrics.headerFontSize },
36
+ styles.headerTitle,
37
+ ], testID: "calendar-header-title", children: title }), showNavigationButtons ? (_jsx(IconButton, { accessibilityLabel: nextLabel, disabled: !canGoNext, iconElement: _jsx(Icon, { color: palette.navIcon, name: "CaretRight", size: iconSize }), onPress: onNext, size: iconSize, styles: { container: NAV_BUTTON, disabled: NAV_BUTTON }, testID: "calendar-next", type: "text" })) : (_jsx(View, { style: SPACER }))] }));
38
+ }
39
+ export const CalendarHeader = React.memo(CalendarHeaderContainer);
40
+ export default CalendarHeader;
@@ -0,0 +1,46 @@
1
+ import React, { type ReactElement, type ReactNode } from 'react';
2
+ import type { CalendarChrome, CalendarCollapseProgress, CalendarDateKey, CalendarDisabledResolver, CalendarMarkerMap } from './types';
3
+ import type { CalendarGrid } from './utils';
4
+ export type CalendarPageProps = {
5
+ grid: CalendarGrid;
6
+ markers: CalendarMarkerMap;
7
+ chrome: CalendarChrome;
8
+ selectedKey: CalendarDateKey | null;
9
+ todayKey: CalendarDateKey;
10
+ tabbableKey: CalendarDateKey | null;
11
+ isDisabled: CalendarDisabledResolver;
12
+ disabledVersion: number;
13
+ showOutsideDays: boolean;
14
+ showWeekNumbers: boolean;
15
+ collapse: CalendarCollapseProgress;
16
+ activeRow: CalendarCollapseProgress;
17
+ /** Disables the collapse wrappers entirely when the page can never collapse. */
18
+ collapsible: boolean;
19
+ testID?: string;
20
+ };
21
+ declare function CalendarPageContainer({ grid, markers, chrome, selectedKey, todayKey, tabbableKey, isDisabled, disabledVersion, showOutsideDays, showWeekNumbers, collapse, activeRow, collapsible, testID, }: CalendarPageProps): ReactElement;
22
+ export declare const CalendarPage: React.MemoExoticComponent<typeof CalendarPageContainer>;
23
+ /** One mounted pager slot. `offset` is -1 (previous), 0 (current) or 1 (next). */
24
+ export type CalendarPagerSlot = {
25
+ key: string;
26
+ offset: number;
27
+ node: ReactNode;
28
+ };
29
+ /**
30
+ * Shared by `CalendarPager.tsx` (gesture driven) and `CalendarPager.web.tsx`
31
+ * (scroll snap). Declared here so neither implementation has to import the other.
32
+ */
33
+ export type CalendarPagerProps = {
34
+ slots: readonly CalendarPagerSlot[];
35
+ rowCount: number;
36
+ rowHeight: number;
37
+ collapse: CalendarCollapseProgress;
38
+ activeRow: CalendarCollapseProgress;
39
+ swipeEnabled: boolean;
40
+ reduceMotion: boolean;
41
+ /** `delta` is +1 for the next page, -1 for the previous one. */
42
+ onCommit: (delta: number) => void;
43
+ testID?: string;
44
+ };
45
+ export default CalendarPage;
46
+ //# sourceMappingURL=CalendarPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarPage.d.ts","sourceRoot":"","sources":["../../../../src/components/uis/Calendar/CalendarPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,KAAK,YAAY,EAAE,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAM/D,OAAO,KAAK,EACV,cAAc,EACd,wBAAwB,EACxB,eAAe,EACf,wBAAwB,EACxB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AAyC1C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,QAAQ,EAAE,eAAe,CAAC;IAC1B,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,wBAAwB,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,SAAS,EAAE,wBAAwB,CAAC;IACpC,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,iBAAS,qBAAqB,CAAC,EAC7B,IAAI,EACJ,OAAO,EACP,MAAM,EACN,WAAW,EACX,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,eAAe,EACf,eAAe,EACf,QAAQ,EACR,SAAS,EACT,WAAW,EACX,MAAM,GACP,EAAE,iBAAiB,GAAG,YAAY,CAkClC;AAED,eAAO,MAAM,YAAY,yDAAoC,CAAC;AAE9D,kFAAkF;AAClF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,SAAS,EAAE,wBAAwB,CAAC;IACpC,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,gEAAgE;IAChE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { View } from 'react-native';
4
+ import { css } from 'kstyled';
5
+ import Animated, { useAnimatedStyle } from 'react-native-reanimated';
6
+ import { CalendarWeekRow } from './CalendarWeekRow';
7
+ const GRID = css `
8
+ align-self: stretch;
9
+ `;
10
+ const COLLAPSE_FADE_END = 0.6;
11
+ /**
12
+ * The week view is the month grid, clipped. Only this opacity and the frame
13
+ * transform move while the calendar collapses, so the transition costs zero
14
+ * React renders and zero remounts.
15
+ */
16
+ function CollapsingRow({ weekIndex, collapse, activeRow, children, }) {
17
+ const animatedStyle = useAnimatedStyle(() => {
18
+ const progress = collapse.value;
19
+ if (progress <= 0 || weekIndex === activeRow.value) {
20
+ return { opacity: 1 };
21
+ }
22
+ const faded = progress / COLLAPSE_FADE_END;
23
+ return { opacity: 1 - (faded > 1 ? 1 : faded) };
24
+ });
25
+ return _jsx(Animated.View, { style: animatedStyle, children: children });
26
+ }
27
+ function CalendarPageContainer({ grid, markers, chrome, selectedKey, todayKey, tabbableKey, isDisabled, disabledVersion, showOutsideDays, showWeekNumbers, collapse, activeRow, collapsible, testID, }) {
28
+ return (_jsx(View, { style: GRID, testID: testID, children: grid.rows.map((row) => {
29
+ const weekRow = (_jsx(CalendarWeekRow, { chrome: chrome, disabledVersion: disabledVersion, isDisabled: isDisabled, markers: markers, row: row, selectedKey: selectedKey, showOutsideDays: showOutsideDays, showWeekNumbers: showWeekNumbers, tabbableKey: tabbableKey, todayKey: todayKey }));
30
+ return collapsible ? (_jsx(CollapsingRow, { activeRow: activeRow, collapse: collapse, weekIndex: row.weekIndex, children: weekRow }, row.days[0].key)) : (_jsx(View, { children: weekRow }, row.days[0].key));
31
+ }) }));
32
+ }
33
+ export const CalendarPage = React.memo(CalendarPageContainer);
34
+ export default CalendarPage;
@@ -0,0 +1,11 @@
1
+ import React, { type ReactElement } from 'react';
2
+ import type { CalendarPagerProps } from './CalendarPage';
3
+ /**
4
+ * Three pages are mounted and moved by one shared value. There is no `scrollTo`
5
+ * and no re-centering pass: the spring resets `pagerX` to 0 in the same frame the
6
+ * page model shifts, so a swipe never causes a visible jump.
7
+ */
8
+ declare function CalendarPagerContainer({ slots, rowCount, rowHeight, collapse, activeRow, swipeEnabled, reduceMotion, onCommit, testID, }: CalendarPagerProps): ReactElement;
9
+ export declare const CalendarPager: React.MemoExoticComponent<typeof CalendarPagerContainer>;
10
+ export default CalendarPager;
11
+ //# sourceMappingURL=CalendarPager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarPager.d.ts","sourceRoot":"","sources":["../../../../src/components/uis/Calendar/CalendarPager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAuB,KAAK,YAAY,EAAC,MAAM,OAAO,CAAC;AAarE,OAAO,KAAK,EAAC,kBAAkB,EAAoB,MAAM,gBAAgB,CAAC;AAqE1E;;;;GAIG;AACH,iBAAS,sBAAsB,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,MAAM,GACP,EAAE,kBAAkB,GAAG,YAAY,CAkInC;AAED,eAAO,MAAM,aAAa,0DAAqC,CAAC;AAEhE,eAAe,aAAa,CAAC"}
@@ -0,0 +1,115 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useCallback, useMemo } from 'react';
3
+ import { I18nManager, useWindowDimensions } from 'react-native';
4
+ import { css } from 'kstyled';
5
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler';
6
+ import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withSpring, withTiming, } from 'react-native-reanimated';
7
+ const CONTAINER = css `
8
+ align-self: stretch;
9
+ overflow: hidden;
10
+ `;
11
+ const PAGE = css `
12
+ position: absolute;
13
+ top: 0;
14
+ start: 0;
15
+ end: 0;
16
+ `;
17
+ const SPRING = {
18
+ damping: 22,
19
+ stiffness: 220,
20
+ mass: 0.7,
21
+ overshootClamping: true,
22
+ };
23
+ const INSTANT = { duration: 0 };
24
+ /** Fraction of the page width, plus projected velocity, that commits a page turn. */
25
+ const COMMIT_RATIO = 0.28;
26
+ const VELOCITY_PROJECTION = 0.15;
27
+ function PagerPage({ slot, direction, pageWidth, pagerX, collapse, activeRow, rowHeight, height, }) {
28
+ const { offset } = slot;
29
+ const animatedStyle = useAnimatedStyle(() => {
30
+ const transform = [
31
+ { translateX: offset * pageWidth.value * direction + pagerX.value },
32
+ { translateY: -activeRow.value * rowHeight * collapse.value },
33
+ ];
34
+ return { transform };
35
+ });
36
+ return (_jsx(Animated.View, { pointerEvents: offset === 0 ? 'auto' : 'none', style: [PAGE, { height }, animatedStyle], children: slot.node }));
37
+ }
38
+ /**
39
+ * Three pages are mounted and moved by one shared value. There is no `scrollTo`
40
+ * and no re-centering pass: the spring resets `pagerX` to 0 in the same frame the
41
+ * page model shifts, so a swipe never causes a visible jump.
42
+ */
43
+ function CalendarPagerContainer({ slots, rowCount, rowHeight, collapse, activeRow, swipeEnabled, reduceMotion, onCommit, testID, }) {
44
+ const { width: windowWidth } = useWindowDimensions();
45
+ const direction = I18nManager.isRTL ? -1 : 1;
46
+ const pageWidth = useSharedValue(windowWidth);
47
+ const pagerX = useSharedValue(0);
48
+ const handleLayout = useCallback((event) => {
49
+ const nextWidth = event.nativeEvent.layout.width;
50
+ if (nextWidth > 0 && Math.abs(nextWidth - pageWidth.value) >= 0.5) {
51
+ // Shared value write only. A rotation or split view resize re-renders no cell.
52
+ pageWidth.value = nextWidth;
53
+ }
54
+ }, [pageWidth]);
55
+ const containerStyle = useAnimatedStyle(() => ({
56
+ height: rowHeight * (rowCount - (rowCount - 1) * collapse.value),
57
+ }));
58
+ const panGesture = useMemo(() => Gesture.Pan()
59
+ .enabled(swipeEnabled)
60
+ .activeOffsetX([-12, 12])
61
+ .failOffsetY([-8, 8])
62
+ .onUpdate((event) => {
63
+ 'worklet';
64
+ if (collapse.value > 0.02 && collapse.value < 0.98) {
65
+ return;
66
+ }
67
+ pagerX.value = event.translationX;
68
+ })
69
+ .onEnd((event) => {
70
+ 'worklet';
71
+ const width = pageWidth.value;
72
+ if (width <= 0 || (collapse.value > 0.02 && collapse.value < 0.98)) {
73
+ pagerX.value = 0;
74
+ return;
75
+ }
76
+ const projected = direction *
77
+ (event.translationX + event.velocityX * VELOCITY_PROJECTION);
78
+ const threshold = width * COMMIT_RATIO;
79
+ const delta = projected < -threshold ? 1 : projected > threshold ? -1 : 0;
80
+ if (delta === 0) {
81
+ pagerX.value = reduceMotion
82
+ ? withTiming(0, INSTANT)
83
+ : withSpring(0, SPRING);
84
+ return;
85
+ }
86
+ const target = -delta * width * direction;
87
+ const settle = (finished) => {
88
+ 'worklet';
89
+ if (!finished) {
90
+ return;
91
+ }
92
+ pagerX.value = 0;
93
+ runOnJS(onCommit)(delta);
94
+ };
95
+ pagerX.value = reduceMotion
96
+ ? withTiming(target, INSTANT, settle)
97
+ : withSpring(target, SPRING, settle);
98
+ }), [
99
+ collapse,
100
+ direction,
101
+ onCommit,
102
+ pageWidth,
103
+ pagerX,
104
+ reduceMotion,
105
+ swipeEnabled,
106
+ ]);
107
+ const height = rowCount * rowHeight;
108
+ const pages = slots.map((slot) => (_jsx(PagerPage, { activeRow: activeRow, collapse: collapse, direction: direction, height: height, pageWidth: pageWidth, pagerX: pagerX, rowHeight: rowHeight, slot: slot }, slot.key)));
109
+ if (!swipeEnabled) {
110
+ return (_jsx(Animated.View, { onLayout: handleLayout, style: [CONTAINER, containerStyle], testID: testID, children: pages }));
111
+ }
112
+ return (_jsx(GestureDetector, { gesture: panGesture, children: _jsx(Animated.View, { onLayout: handleLayout, style: [CONTAINER, containerStyle], testID: testID, children: pages }) }));
113
+ }
114
+ export const CalendarPager = React.memo(CalendarPagerContainer);
115
+ export default CalendarPager;
@@ -0,0 +1,11 @@
1
+ import React, { type ReactElement } from 'react';
2
+ import type { CalendarPagerProps } from './CalendarPage';
3
+ /**
4
+ * Web build. Gesture handler needs a `GestureHandlerRootView` that a plain web
5
+ * consumer may not have mounted, so paging here is a scroll snap container that
6
+ * commits on settle. The collapse still runs through the same shared values.
7
+ */
8
+ declare function CalendarPagerWebContainer({ slots, rowCount, rowHeight, collapse, activeRow, swipeEnabled, onCommit, testID, }: CalendarPagerProps): ReactElement;
9
+ export declare const CalendarPager: React.MemoExoticComponent<typeof CalendarPagerWebContainer>;
10
+ export default CalendarPager;
11
+ //# sourceMappingURL=CalendarPager.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarPager.web.d.ts","sourceRoot":"","sources":["../../../../src/components/uis/Calendar/CalendarPager.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAKZ,KAAK,YAAY,EAClB,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAevD;;;;GAIG;AACH,iBAAS,yBAAyB,CAAC,EACjC,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,MAAM,GACP,EAAE,kBAAkB,GAAG,YAAY,CA6FnC;AAED,eAAO,MAAM,aAAa,6DAAwC,CAAC;AAEnE,eAAe,aAAa,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useCallback, useEffect, useRef, useState, } from 'react';
3
+ import { ScrollView, useWindowDimensions, View } from 'react-native';
4
+ import { css } from 'kstyled';
5
+ import Animated, { useAnimatedStyle } from 'react-native-reanimated';
6
+ const CONTAINER = css `
7
+ align-self: stretch;
8
+ overflow: hidden;
9
+ `;
10
+ const CONTENT = css `
11
+ flex-direction: row;
12
+ align-items: flex-start;
13
+ `;
14
+ /** Time after the last scroll event at which the page is considered settled. */
15
+ const SETTLE_DELAY = 140;
16
+ /**
17
+ * Web build. Gesture handler needs a `GestureHandlerRootView` that a plain web
18
+ * consumer may not have mounted, so paging here is a scroll snap container that
19
+ * commits on settle. The collapse still runs through the same shared values.
20
+ */
21
+ function CalendarPagerWebContainer({ slots, rowCount, rowHeight, collapse, activeRow, swipeEnabled, onCommit, testID, }) {
22
+ const { width: windowWidth } = useWindowDimensions();
23
+ const [pageWidth, setPageWidth] = useState(windowWidth);
24
+ const scrollRef = useRef(null);
25
+ const settleTimer = useRef(null);
26
+ const centerIndex = slots.findIndex((slot) => slot.offset === 0);
27
+ const restingOffset = Math.max(centerIndex, 0) * pageWidth;
28
+ const handleLayout = useCallback((event) => {
29
+ const nextWidth = event.nativeEvent.layout.width;
30
+ setPageWidth((current) => nextWidth > 0 && Math.abs(nextWidth - current) >= 0.5
31
+ ? nextWidth
32
+ : current);
33
+ }, []);
34
+ const recenter = useCallback(() => {
35
+ scrollRef.current?.scrollTo({ x: restingOffset, y: 0, animated: false });
36
+ }, [restingOffset]);
37
+ useEffect(() => {
38
+ recenter();
39
+ }, [recenter, slots]);
40
+ useEffect(() => () => {
41
+ if (settleTimer.current) {
42
+ clearTimeout(settleTimer.current);
43
+ }
44
+ }, []);
45
+ const handleScroll = useCallback((event) => {
46
+ const offsetX = event.nativeEvent.contentOffset.x;
47
+ if (settleTimer.current) {
48
+ clearTimeout(settleTimer.current);
49
+ }
50
+ settleTimer.current = setTimeout(() => {
51
+ if (pageWidth <= 0) {
52
+ return;
53
+ }
54
+ const index = Math.round(offsetX / pageWidth);
55
+ const delta = index - Math.max(centerIndex, 0);
56
+ recenter();
57
+ if (delta !== 0) {
58
+ onCommit(delta);
59
+ }
60
+ }, SETTLE_DELAY);
61
+ }, [centerIndex, onCommit, pageWidth, recenter]);
62
+ const containerStyle = useAnimatedStyle(() => ({
63
+ height: rowHeight * (rowCount - (rowCount - 1) * collapse.value),
64
+ }));
65
+ const pageStyle = useAnimatedStyle(() => ({
66
+ transform: [{ translateY: -activeRow.value * rowHeight * collapse.value }],
67
+ }));
68
+ const height = rowCount * rowHeight;
69
+ return (_jsx(Animated.View, { style: [CONTAINER, containerStyle], testID: testID, children: _jsx(ScrollView, { contentContainerStyle: CONTENT, horizontal: true, onLayout: handleLayout, onScroll: handleScroll, pagingEnabled: true, ref: scrollRef, scrollEnabled: swipeEnabled, scrollEventThrottle: 16, showsHorizontalScrollIndicator: false, children: slots.map((slot) => (_jsx(View, { style: { width: pageWidth, height }, children: _jsx(Animated.View, { style: pageStyle, children: slot.node }) }, slot.key))) }) }));
70
+ }
71
+ export const CalendarPager = React.memo(CalendarPagerWebContainer);
72
+ export default CalendarPager;
@@ -0,0 +1,20 @@
1
+ import React, { type ReactElement } from 'react';
2
+ import type { CalendarChrome, CalendarDateKey, CalendarDisabledResolver, CalendarMarkerMap } from './types';
3
+ import type { CalendarGridRow } from './utils';
4
+ export type CalendarWeekRowProps = {
5
+ row: CalendarGridRow;
6
+ markers: CalendarMarkerMap;
7
+ chrome: CalendarChrome;
8
+ selectedKey: CalendarDateKey | null;
9
+ todayKey: CalendarDateKey;
10
+ tabbableKey: CalendarDateKey | null;
11
+ isDisabled: CalendarDisabledResolver;
12
+ /** Bumped whenever min/max/disabledDates/predicate identity changes. */
13
+ disabledVersion: number;
14
+ showOutsideDays: boolean;
15
+ showWeekNumbers: boolean;
16
+ };
17
+ declare function CalendarWeekRowContainer({ row, markers, chrome, selectedKey, todayKey, tabbableKey, isDisabled, showOutsideDays, showWeekNumbers, }: CalendarWeekRowProps): ReactElement;
18
+ export declare const CalendarWeekRow: React.MemoExoticComponent<typeof CalendarWeekRowContainer>;
19
+ export default CalendarWeekRow;
20
+ //# sourceMappingURL=CalendarWeekRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarWeekRow.d.ts","sourceRoot":"","sources":["../../../../src/components/uis/Calendar/CalendarWeekRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,KAAK,YAAY,EAAC,MAAM,OAAO,CAAC;AAK/C,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,wBAAwB,EACxB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,SAAS,CAAC;AAiB7C,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,eAAe,CAAC;IACrB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,QAAQ,EAAE,eAAe,CAAC;IAC1B,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,wBAAwB,CAAC;IACrC,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,iBAAS,wBAAwB,CAAC,EAChC,GAAG,EACH,OAAO,EACP,MAAM,EACN,WAAW,EACX,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,eAAe,GAChB,EAAE,oBAAoB,GAAG,YAAY,CAiErC;AAmCD,eAAO,MAAM,eAAe,4DAG3B,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { Text, View } from 'react-native';
4
+ import { css } from 'kstyled';
5
+ import { CalendarDay } from './CalendarDay';
6
+ import { rowHasKey } from './utils';
7
+ const ROW = css `
8
+ flex-direction: row;
9
+ align-items: stretch;
10
+ `;
11
+ const WEEK_NUMBER = css `
12
+ align-items: center;
13
+ justify-content: center;
14
+ `;
15
+ const WEEK_NUMBER_TEXT = css `
16
+ text-align: center;
17
+ `;
18
+ function CalendarWeekRowContainer({ row, markers, chrome, selectedKey, todayKey, tabbableKey, isDisabled, showOutsideDays, showWeekNumbers, }) {
19
+ const { labels, geometry, palette } = chrome;
20
+ const cells = [];
21
+ for (let index = 0; index < row.days.length; index++) {
22
+ const day = row.days[index];
23
+ const marker = markers[day.key];
24
+ const isToday = day.key === todayKey;
25
+ const isSelected = day.key === selectedKey;
26
+ const disabled = isDisabled(day, marker);
27
+ let accessibilityLabel = row.a11yLabels[index];
28
+ if (isToday) {
29
+ accessibilityLabel = `${accessibilityLabel}, ${labels.today}`;
30
+ }
31
+ if (marker?.accessibilityHint) {
32
+ accessibilityLabel = `${accessibilityLabel}, ${marker.accessibilityHint}`;
33
+ }
34
+ cells.push(_jsx(CalendarDay, { accessibilityLabel: accessibilityLabel, chrome: chrome, day: day, dayLabel: row.dayLabels[index], isDisabled: disabled, isHidden: day.isOutside && !showOutsideDays, isSelected: isSelected, isTabbable: day.key === tabbableKey, isToday: isToday, marker: marker }, day.key));
35
+ }
36
+ return (_jsxs(View, { accessibilityRole: "none", style: [ROW, geometry.row, chrome.styles.weekRow], testID: `calendar-week-${row.days[0].key}`, children: [showWeekNumbers ? (_jsx(View, { accessibilityLabel: `${labels.weekNumber} ${row.weekNumber}`, style: [WEEK_NUMBER, geometry.weekNumber], children: _jsx(Text, { maxFontSizeMultiplier: chrome.maxFontSizeMultiplier, numberOfLines: 1, style: [
37
+ WEEK_NUMBER_TEXT,
38
+ geometry.weekNumberText,
39
+ { color: palette.weekNumberLabel },
40
+ ], children: row.weekNumber }) })) : null, cells] }));
41
+ }
42
+ /**
43
+ * `prev`/`next` are compared for presence in this row first. A selection moving
44
+ * inside one row re-renders that row only, moving across a boundary re-renders two.
45
+ */
46
+ const hasSameKeyPresence = (row, prev, next) => {
47
+ const inPrev = rowHasKey(row.days, prev);
48
+ const inNext = rowHasKey(row.days, next);
49
+ if (inPrev !== inNext) {
50
+ return false;
51
+ }
52
+ return !inNext || prev === next;
53
+ };
54
+ const areRowsEqual = (a, b) => a.row === b.row &&
55
+ a.chrome === b.chrome &&
56
+ a.markers === b.markers &&
57
+ a.disabledVersion === b.disabledVersion &&
58
+ a.showOutsideDays === b.showOutsideDays &&
59
+ a.showWeekNumbers === b.showWeekNumbers &&
60
+ hasSameKeyPresence(a.row, a.selectedKey, b.selectedKey) &&
61
+ hasSameKeyPresence(a.row, a.todayKey, b.todayKey) &&
62
+ hasSameKeyPresence(a.row, a.tabbableKey, b.tabbableKey);
63
+ export const CalendarWeekRow = React.memo(CalendarWeekRowContainer, areRowsEqual);
64
+ export default CalendarWeekRow;
@@ -0,0 +1,24 @@
1
+ import React, { type ReactElement, type ReactNode } from 'react';
2
+ import type { CalendarMetrics, CalendarPalette, CalendarStyles, CalendarWeekday, WeekStart } from './types';
3
+ export type CalendarWeekdayRowProps = {
4
+ /** Seven precomputed labels, already rotated to start at `weekStart`. */
5
+ weekdayLabels: readonly string[];
6
+ weekStart: WeekStart;
7
+ palette: CalendarPalette;
8
+ metrics: CalendarMetrics;
9
+ styles: CalendarStyles;
10
+ maxFontSizeMultiplier: number;
11
+ showWeekNumbers: boolean;
12
+ renderWeekdayLabel?: (ctx: {
13
+ weekday: CalendarWeekday;
14
+ label: string;
15
+ }) => ReactNode;
16
+ };
17
+ /**
18
+ * Hidden from assistive tech: every day cell already announces its weekday, so
19
+ * reading "S M T W T F S" before the grid is pure noise. Web keeps the semantics.
20
+ */
21
+ declare function CalendarWeekdayRowContainer({ weekdayLabels, weekStart, palette, metrics, styles, maxFontSizeMultiplier, showWeekNumbers, renderWeekdayLabel, }: CalendarWeekdayRowProps): ReactElement;
22
+ export declare const CalendarWeekdayRow: React.MemoExoticComponent<typeof CalendarWeekdayRowContainer>;
23
+ export default CalendarWeekdayRow;
24
+ //# sourceMappingURL=CalendarWeekdayRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarWeekdayRow.d.ts","sourceRoot":"","sources":["../../../../src/components/uis/Calendar/CalendarWeekdayRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,KAAK,YAAY,EAAE,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAI/D,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,cAAc,EACd,eAAe,EACf,SAAS,EACV,MAAM,SAAS,CAAC;AAuBjB,MAAM,MAAM,uBAAuB,GAAG;IACpC,yEAAyE;IACzE,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE;QACzB,OAAO,EAAE,eAAe,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC;KACf,KAAK,SAAS,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,iBAAS,2BAA2B,CAAC,EACnC,aAAa,EACb,SAAS,EACT,OAAO,EACP,OAAO,EACP,MAAM,EACN,qBAAqB,EACrB,eAAe,EACf,kBAAkB,GACnB,EAAE,uBAAuB,GAAG,YAAY,CAqDxC;AAED,eAAO,MAAM,kBAAkB,+DAA0C,CAAC;AAE1E,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { Platform, Text, View } from 'react-native';
4
+ import { css } from 'kstyled';
5
+ const ROW = css `
6
+ flex-direction: row;
7
+ align-items: center;
8
+ `;
9
+ const LABEL_CELL = css `
10
+ flex: 1;
11
+ align-items: center;
12
+ justify-content: center;
13
+ `;
14
+ const LABEL_TEXT = css `
15
+ text-align: center;
16
+ font-weight: 500;
17
+ `;
18
+ const WEEK_NUMBER_SPACER = css `
19
+ align-items: center;
20
+ justify-content: center;
21
+ `;
22
+ /**
23
+ * Hidden from assistive tech: every day cell already announces its weekday, so
24
+ * reading "S M T W T F S" before the grid is pure noise. Web keeps the semantics.
25
+ */
26
+ function CalendarWeekdayRowContainer({ weekdayLabels, weekStart, palette, metrics, styles, maxFontSizeMultiplier, showWeekNumbers, renderWeekdayLabel, }) {
27
+ const isWeb = Platform.OS === 'web';
28
+ return (_jsxs(View, { accessibilityElementsHidden: !isWeb, importantForAccessibility: isWeb ? 'auto' : 'no-hide-descendants', role: isWeb ? 'row' : undefined, style: [ROW, { height: metrics.weekdayRowHeight }, styles.weekdayRow], testID: "calendar-weekday-row", children: [showWeekNumbers ? (_jsx(View, { style: [WEEK_NUMBER_SPACER, { width: metrics.weekNumberWidth }] })) : null, weekdayLabels.map((label, index) => {
29
+ const weekday = (((weekStart + index) % 7) + 7) % 7;
30
+ return (_jsx(View, { role: isWeb ? 'columnheader' : undefined, style: LABEL_CELL, testID: `calendar-weekday-${index}`, children: renderWeekdayLabel ? (renderWeekdayLabel({ weekday: weekday, label })) : (_jsx(Text, { maxFontSizeMultiplier: maxFontSizeMultiplier, numberOfLines: 1, style: [
31
+ LABEL_TEXT,
32
+ {
33
+ color: weekday === 0
34
+ ? palette.sundayText
35
+ : weekday === 6
36
+ ? palette.saturdayText
37
+ : palette.weekdayLabel,
38
+ fontSize: metrics.weekdayFontSize,
39
+ },
40
+ styles.weekdayLabel,
41
+ ], children: label })) }, `calendar-weekday-${index}`));
42
+ })] }));
43
+ }
44
+ export const CalendarWeekdayRow = React.memo(CalendarWeekdayRowContainer);
45
+ export default CalendarWeekdayRow;
@@ -0,0 +1,18 @@
1
+ import type { CalendarFormatters } from './types';
2
+ /**
3
+ * All localized text comes from `Intl.DateTimeFormat`, which Hermes ships on both
4
+ * platforms. Constructing a formatter is the expensive part (~100us), formatting on a
5
+ * cached instance is ~1us, so every instance is created once per (locale, shape).
6
+ */
7
+ type Shape = 'monthTitle' | 'weekdayNarrow' | 'dayNumber' | 'dayFull' | 'rangeDay';
8
+ export declare function getFormat(locale: string, shape: Shape): Intl.DateTimeFormat | null;
9
+ /** The device locale, or `en-US` when the runtime has no `Intl`. */
10
+ export declare function resolveLocale(): string;
11
+ export declare const DEFAULT_FORMATTERS: CalendarFormatters;
12
+ /**
13
+ * A stable id per formatters object, so the grid LRU key changes when a caller
14
+ * swaps in different formatters but not when it re-renders with the same ones.
15
+ */
16
+ export declare function getFormattersId(formatters: CalendarFormatters): string;
17
+ export {};
18
+ //# sourceMappingURL=intl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intl.d.ts","sourceRoot":"","sources":["../../../../src/components/uis/Calendar/intl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAEhD;;;;GAIG;AACH,KAAK,KAAK,GACN,YAAY,GACZ,eAAe,GACf,WAAW,GACX,SAAS,GACT,UAAU,CAAC;AAef,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,GACX,IAAI,CAAC,cAAc,GAAG,IAAI,CA2B5B;AAED,oEAAoE;AACpE,wBAAgB,aAAa,IAAI,MAAM,CAUtC;AAkGD,eAAO,MAAM,kBAAkB,EAAE,kBAM/B,CAAC;AAKH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM,CActE"}