@super-calendar/native 2.1.4 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{DefaultMonthEvent-D2s0x2Bn.d.mts → DefaultMonthEvent-BlfDkmF5.d.mts} +61 -9
- package/dist/{DefaultMonthEvent-DaTEIcRs.d.ts → DefaultMonthEvent-Cagj4aBo.d.ts} +61 -9
- package/dist/{MonthList-oXiArmbu.js → MonthList-DWAjW5R7.js} +98 -31
- package/dist/{MonthList-DXvjxiyu.mjs → MonthList-DZx8rPle.mjs} +94 -33
- package/dist/index.d.mts +112 -8
- package/dist/index.d.ts +112 -8
- package/dist/index.js +476 -107
- package/dist/index.mjs +472 -110
- package/dist/picker.d.mts +1 -1
- package/dist/picker.d.ts +1 -1
- package/dist/picker.js +1 -1
- package/dist/picker.mjs +1 -1
- package/package.json +2 -2
- package/src/components/Agenda.tsx +2 -2
- package/src/components/AllDayLane.tsx +11 -2
- package/src/components/Calendar.tsx +38 -4
- package/src/components/DefaultEvent.tsx +68 -47
- package/src/components/DefaultMonthEvent.tsx +11 -8
- package/src/components/MonthList.tsx +16 -3
- package/src/components/MonthPager.tsx +19 -11
- package/src/components/MonthView.tsx +40 -11
- package/src/components/ResourceTimeline.tsx +441 -0
- package/src/components/TimeGrid.tsx +44 -7
- package/src/index.tsx +10 -0
- package/src/theme.ts +62 -1
- package/src/types.ts +9 -0
- package/src/utils/withEventAccessibilityLabel.tsx +30 -0
|
@@ -63,8 +63,11 @@ import {
|
|
|
63
63
|
snapDeltaMinutes,
|
|
64
64
|
} from "@super-calendar/core";
|
|
65
65
|
import { formatHour, layoutDayEvents, type PositionedEvent } from "@super-calendar/core";
|
|
66
|
+
import type { EventAccessibilityLabeler } from "@super-calendar/core";
|
|
67
|
+
import { type WeekdayFormat, weekdayFormatToken } from "@super-calendar/core";
|
|
66
68
|
import { useWebGridZoom } from "../utils/useWebGridZoom";
|
|
67
69
|
import { useWebPagerKeys } from "../utils/useWebPagerKeys";
|
|
70
|
+
import { withEventAccessibilityLabel } from "../utils/withEventAccessibilityLabel";
|
|
68
71
|
import { AllDayLane } from "./AllDayLane";
|
|
69
72
|
|
|
70
73
|
// Horizontal swipe paging doesn't translate to web; there we disable it and page
|
|
@@ -370,7 +373,9 @@ function AnimatedEventBox<T>({
|
|
|
370
373
|
!draggable && onLongPress ? () => onLongPress(positioned.event) : undefined;
|
|
371
374
|
|
|
372
375
|
const box = (
|
|
373
|
-
<Animated.View
|
|
376
|
+
<Animated.View
|
|
377
|
+
style={[styles.eventBox, { left, width }, boxStyle, theme.containers.timeGridEvent]}
|
|
378
|
+
>
|
|
374
379
|
<RenderEventComponent
|
|
375
380
|
event={positioned.event}
|
|
376
381
|
mode={mode}
|
|
@@ -493,6 +498,7 @@ type NowIndicatorProps = {
|
|
|
493
498
|
};
|
|
494
499
|
|
|
495
500
|
const NowIndicator = ({ cellHeight, nowHours, minHour, left, width, color }: NowIndicatorProps) => {
|
|
501
|
+
const theme = useCalendarTheme();
|
|
496
502
|
const animatedStyle = useAnimatedStyle(
|
|
497
503
|
() => ({ top: (nowHours - minHour) * cellHeight.value }),
|
|
498
504
|
[nowHours, minHour],
|
|
@@ -505,6 +511,7 @@ const NowIndicator = ({ cellHeight, nowHours, minHour, left, width, color }: Now
|
|
|
505
511
|
styles.nonInteractive,
|
|
506
512
|
{ left, width, backgroundColor: color },
|
|
507
513
|
animatedStyle,
|
|
514
|
+
theme.containers.nowIndicator,
|
|
508
515
|
]}
|
|
509
516
|
/>
|
|
510
517
|
);
|
|
@@ -1179,7 +1186,15 @@ export type TimeGridProps<T> = {
|
|
|
1179
1186
|
/** Initial per-hour row height in px; seeds scroll/zoom without reading the shared value during render. */
|
|
1180
1187
|
hourHeight?: number;
|
|
1181
1188
|
weekStartsOn: WeekStartsOn;
|
|
1189
|
+
/** Column-header weekday label width: `narrow` ("M"), `short` ("Mon", default), or `long` ("Monday"). */
|
|
1190
|
+
weekdayFormat?: WeekdayFormat;
|
|
1182
1191
|
renderEvent: RenderEvent<T>;
|
|
1192
|
+
/**
|
|
1193
|
+
* Override the screen-reader label for each event. Receives the event and a
|
|
1194
|
+
* `{ mode, isAllDay, ampm }` context; return the full text to announce. Defaults
|
|
1195
|
+
* to the built-in title-and-time label.
|
|
1196
|
+
*/
|
|
1197
|
+
eventAccessibilityLabel?: EventAccessibilityLabeler<T>;
|
|
1183
1198
|
keyExtractor: EventKeyExtractor<T>;
|
|
1184
1199
|
scrollOffsetMinutes?: number;
|
|
1185
1200
|
hourColumnWidth?: number;
|
|
@@ -1258,7 +1273,9 @@ function TimeGridInner<T>({
|
|
|
1258
1273
|
cellHeight,
|
|
1259
1274
|
hourHeight = DEFAULT_HOUR_HEIGHT,
|
|
1260
1275
|
weekStartsOn,
|
|
1276
|
+
weekdayFormat = "short",
|
|
1261
1277
|
renderEvent,
|
|
1278
|
+
eventAccessibilityLabel,
|
|
1262
1279
|
keyExtractor,
|
|
1263
1280
|
scrollOffsetMinutes = 0,
|
|
1264
1281
|
hourColumnWidth: hourColumnWidthProp = DEFAULT_HOUR_COLUMN_WIDTH,
|
|
@@ -1304,6 +1321,14 @@ function TimeGridInner<T>({
|
|
|
1304
1321
|
// Collapse the hour gutter to zero when hours are hidden.
|
|
1305
1322
|
const hourColumnWidth = hideHours ? 0 : hourColumnWidthProp;
|
|
1306
1323
|
|
|
1324
|
+
// Inject a consumer's `eventAccessibilityLabel` override into every event once,
|
|
1325
|
+
// so the timed columns and the all-day lane share it without threading a prop
|
|
1326
|
+
// through each. Passes the grid's `ampm` so the label can match the clock.
|
|
1327
|
+
const labeledRenderEvent = useMemo(
|
|
1328
|
+
() => withEventAccessibilityLabel(renderEvent, eventAccessibilityLabel, ampm),
|
|
1329
|
+
[renderEvent, eventAccessibilityLabel, ampm],
|
|
1330
|
+
);
|
|
1331
|
+
|
|
1307
1332
|
const { width, height } = useWindowDimensions();
|
|
1308
1333
|
const listRef = useRef<LegendListRef>(null);
|
|
1309
1334
|
// The grid's outer view; on web its ref resolves to the DOM node we attach the
|
|
@@ -1590,7 +1615,7 @@ function TimeGridInner<T>({
|
|
|
1590
1615
|
minHourHeight={minHourHeight}
|
|
1591
1616
|
maxHourHeight={maxHourHeight}
|
|
1592
1617
|
showNowIndicator={showNowIndicator}
|
|
1593
|
-
renderEvent={
|
|
1618
|
+
renderEvent={labeledRenderEvent}
|
|
1594
1619
|
keyExtractor={keyExtractor}
|
|
1595
1620
|
snapMinutes={Math.max(1, dragStepMinutes)}
|
|
1596
1621
|
showDragHandle={showDragHandle}
|
|
@@ -1634,7 +1659,7 @@ function TimeGridInner<T>({
|
|
|
1634
1659
|
minHourHeight,
|
|
1635
1660
|
maxHourHeight,
|
|
1636
1661
|
showNowIndicator,
|
|
1637
|
-
|
|
1662
|
+
labeledRenderEvent,
|
|
1638
1663
|
keyExtractor,
|
|
1639
1664
|
dragStepMinutes,
|
|
1640
1665
|
showDragHandle,
|
|
@@ -1667,6 +1692,7 @@ function TimeGridInner<T>({
|
|
|
1667
1692
|
hourColumnWidth={hourColumnWidth}
|
|
1668
1693
|
showWeekNumber={showWeekNumber}
|
|
1669
1694
|
weekNumberPrefix={weekNumberPrefix}
|
|
1695
|
+
weekdayFormat={weekdayFormat}
|
|
1670
1696
|
locale={locale}
|
|
1671
1697
|
activeDate={activeDate}
|
|
1672
1698
|
onPressDateHeader={onPressDateHeader}
|
|
@@ -1727,7 +1753,7 @@ function TimeGridInner<T>({
|
|
|
1727
1753
|
*
|
|
1728
1754
|
* @example
|
|
1729
1755
|
* ```tsx
|
|
1730
|
-
* import { TimeGrid } from "
|
|
1756
|
+
* import { TimeGrid } from "@super-calendar/native";
|
|
1731
1757
|
*
|
|
1732
1758
|
* <TimeGrid
|
|
1733
1759
|
* mode="week"
|
|
@@ -1747,6 +1773,7 @@ type DefaultHeaderProps = {
|
|
|
1747
1773
|
hourColumnWidth: number;
|
|
1748
1774
|
showWeekNumber?: boolean;
|
|
1749
1775
|
weekNumberPrefix?: string;
|
|
1776
|
+
weekdayFormat?: WeekdayFormat;
|
|
1750
1777
|
locale?: Locale;
|
|
1751
1778
|
activeDate?: Date;
|
|
1752
1779
|
onPressDateHeader?: (date: Date) => void;
|
|
@@ -1759,6 +1786,7 @@ const DefaultHeader = ({
|
|
|
1759
1786
|
hourColumnWidth,
|
|
1760
1787
|
showWeekNumber,
|
|
1761
1788
|
weekNumberPrefix = "W",
|
|
1789
|
+
weekdayFormat,
|
|
1762
1790
|
locale,
|
|
1763
1791
|
activeDate,
|
|
1764
1792
|
onPressDateHeader,
|
|
@@ -1785,6 +1813,7 @@ const DefaultHeader = ({
|
|
|
1785
1813
|
day={day}
|
|
1786
1814
|
mode={mode}
|
|
1787
1815
|
width={dayWidth}
|
|
1816
|
+
weekdayFormat={weekdayFormat}
|
|
1788
1817
|
locale={locale}
|
|
1789
1818
|
activeDate={activeDate}
|
|
1790
1819
|
onPressDateHeader={onPressDateHeader}
|
|
@@ -1798,12 +1827,20 @@ type DayHeaderProps = {
|
|
|
1798
1827
|
day: Date;
|
|
1799
1828
|
mode: CalendarMode;
|
|
1800
1829
|
width: number;
|
|
1830
|
+
weekdayFormat?: WeekdayFormat;
|
|
1801
1831
|
locale?: Locale;
|
|
1802
1832
|
activeDate?: Date;
|
|
1803
1833
|
onPressDateHeader?: (date: Date) => void;
|
|
1804
1834
|
};
|
|
1805
1835
|
|
|
1806
|
-
const DayHeader = ({
|
|
1836
|
+
const DayHeader = ({
|
|
1837
|
+
day,
|
|
1838
|
+
width,
|
|
1839
|
+
weekdayFormat = "short",
|
|
1840
|
+
locale,
|
|
1841
|
+
activeDate,
|
|
1842
|
+
onPressDateHeader,
|
|
1843
|
+
}: DayHeaderProps) => {
|
|
1807
1844
|
const theme = useCalendarTheme();
|
|
1808
1845
|
const isToday = getIsToday(day);
|
|
1809
1846
|
// Highlight the chosen `activeDate` when supplied, else the real today.
|
|
@@ -1811,7 +1848,7 @@ const DayHeader = ({ day, width, locale, activeDate, onPressDateHeader }: DayHea
|
|
|
1811
1848
|
|
|
1812
1849
|
return (
|
|
1813
1850
|
<Pressable
|
|
1814
|
-
style={[styles.dayHeader, { width }]}
|
|
1851
|
+
style={[styles.dayHeader, { width }, theme.containers.columnHeader]}
|
|
1815
1852
|
onPress={onPressDateHeader ? () => onPressDateHeader(day) : undefined}
|
|
1816
1853
|
disabled={!onPressDateHeader}
|
|
1817
1854
|
accessibilityRole={onPressDateHeader ? "button" : undefined}
|
|
@@ -1822,7 +1859,7 @@ const DayHeader = ({ day, width, locale, activeDate, onPressDateHeader }: DayHea
|
|
|
1822
1859
|
style={[styles.dayHeaderWeekday, { color: theme.colors.textMuted }]}
|
|
1823
1860
|
allowFontScaling={false}
|
|
1824
1861
|
>
|
|
1825
|
-
{format(day,
|
|
1862
|
+
{format(day, weekdayFormatToken(weekdayFormat), { locale })}
|
|
1826
1863
|
</Text>
|
|
1827
1864
|
<View
|
|
1828
1865
|
style={[
|
package/src/index.tsx
CHANGED
|
@@ -35,6 +35,12 @@ export {
|
|
|
35
35
|
} from "./components/TimeGrid";
|
|
36
36
|
export { DefaultEvent } from "./components/DefaultEvent";
|
|
37
37
|
export { DefaultMonthEvent } from "./components/DefaultMonthEvent";
|
|
38
|
+
export {
|
|
39
|
+
ResourceTimeline,
|
|
40
|
+
type ResourceTimelineProps,
|
|
41
|
+
type Resource,
|
|
42
|
+
type ResourceEventArgs,
|
|
43
|
+
} from "./components/ResourceTimeline";
|
|
38
44
|
export {
|
|
39
45
|
type CalendarTheme,
|
|
40
46
|
type PartialCalendarTheme,
|
|
@@ -48,6 +54,8 @@ export type {
|
|
|
48
54
|
BusinessHours,
|
|
49
55
|
CalendarEvent,
|
|
50
56
|
CalendarMode,
|
|
57
|
+
EventAccessibilityLabelContext,
|
|
58
|
+
EventAccessibilityLabeler,
|
|
51
59
|
EventKeyExtractor,
|
|
52
60
|
ICalendarEvent,
|
|
53
61
|
RecurrenceFrequency,
|
|
@@ -55,6 +63,7 @@ export type {
|
|
|
55
63
|
RenderEvent,
|
|
56
64
|
RenderEventArgs,
|
|
57
65
|
TimeGridMode,
|
|
66
|
+
WeekdayFormat,
|
|
58
67
|
WeekStartsOn,
|
|
59
68
|
} from "./types";
|
|
60
69
|
export {
|
|
@@ -77,6 +86,7 @@ export {
|
|
|
77
86
|
type MonthGridWeekday,
|
|
78
87
|
type UseMonthGridOptions,
|
|
79
88
|
useMonthGrid,
|
|
89
|
+
weekdayFormatToken,
|
|
80
90
|
} from "@super-calendar/core";
|
|
81
91
|
export { expandRecurringEvents } from "@super-calendar/core";
|
|
82
92
|
export { eventsInTimeZone, toZonedTime } from "@super-calendar/core";
|
package/src/theme.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type CalendarColors, darkColors, lightColors } from "@super-calendar/core";
|
|
2
2
|
import { type Context, createContext, useContext } from "react";
|
|
3
|
-
import type { TextStyle } from "react-native";
|
|
3
|
+
import type { TextStyle, ViewStyle } from "react-native";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* The full set of colours, text styles and metrics the calendar paints with.
|
|
@@ -16,6 +16,8 @@ export interface CalendarTheme {
|
|
|
16
16
|
dayNumber: TextStyle;
|
|
17
17
|
/** Short weekday label ("Mon") in headers. */
|
|
18
18
|
weekday: TextStyle;
|
|
19
|
+
/** The "MMMM yyyy" month title above the month grid. */
|
|
20
|
+
monthTitle: TextStyle;
|
|
19
21
|
/** Date number inside a month cell. */
|
|
20
22
|
dateCell: TextStyle;
|
|
21
23
|
/** Hour labels down the left of the time grid. */
|
|
@@ -25,6 +27,44 @@ export interface CalendarTheme {
|
|
|
25
27
|
/** Title inside the built-in default event box. */
|
|
26
28
|
eventTitle: TextStyle;
|
|
27
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* Per-part `ViewStyle` overrides for the renderer's container elements, the
|
|
32
|
+
* React Native counterpart of the web renderer's per-slot classes. Each is
|
|
33
|
+
* merged onto the built-in style, so you override only what you set. (Rolling
|
|
34
|
+
* out across the views; more slots as they land.)
|
|
35
|
+
*/
|
|
36
|
+
containers: {
|
|
37
|
+
/** The month view's outer container (title + weekday header + grid). */
|
|
38
|
+
monthContainer: ViewStyle;
|
|
39
|
+
/** The weekday-label header row above a month grid. */
|
|
40
|
+
weekdayHeader: ViewStyle;
|
|
41
|
+
/** Each week (row of 7 day cells) in the month grid. */
|
|
42
|
+
weekRow: ViewStyle;
|
|
43
|
+
/** Each day cell in the month grid. */
|
|
44
|
+
dayCell: ViewStyle;
|
|
45
|
+
/** The date badge (the circle) inside a month day cell. */
|
|
46
|
+
dayBadge: ViewStyle;
|
|
47
|
+
/** An event chip inside a month day cell. */
|
|
48
|
+
monthEvent: ViewStyle;
|
|
49
|
+
/** Each day's column header in the time grid. */
|
|
50
|
+
columnHeader: ViewStyle;
|
|
51
|
+
/** A timed event's positioned box in the time grid (and resource timeline). */
|
|
52
|
+
timeGridEvent: ViewStyle;
|
|
53
|
+
/** The current-time indicator line. */
|
|
54
|
+
nowIndicator: ViewStyle;
|
|
55
|
+
/** Each resource row in the resource timeline. */
|
|
56
|
+
resourceRow: ViewStyle;
|
|
57
|
+
/** The left-hand resource-label cell in the resource timeline. */
|
|
58
|
+
resourceLabel: ViewStyle;
|
|
59
|
+
/** The schedule/agenda list's outer container. */
|
|
60
|
+
agendaList: ViewStyle;
|
|
61
|
+
/** Each event row in the agenda list. */
|
|
62
|
+
agendaRow: ViewStyle;
|
|
63
|
+
/** The all-day lane above the time grid. */
|
|
64
|
+
allDayLane: ViewStyle;
|
|
65
|
+
/** Each day's column within the all-day lane. */
|
|
66
|
+
allDayColumn: ViewStyle;
|
|
67
|
+
};
|
|
28
68
|
/** Corner radius of the today badge. Use a large value for a circle. */
|
|
29
69
|
todayBadgeRadius: number;
|
|
30
70
|
/**
|
|
@@ -40,6 +80,7 @@ export const defaultTheme: CalendarTheme = {
|
|
|
40
80
|
text: {
|
|
41
81
|
dayNumber: { fontSize: 22, fontWeight: "700" },
|
|
42
82
|
weekday: { fontSize: 13, fontWeight: "700" },
|
|
83
|
+
monthTitle: { fontSize: 17, fontWeight: "700" },
|
|
43
84
|
dateCell: { fontSize: 13, fontWeight: "700" },
|
|
44
85
|
hourLabel: { fontSize: 10 },
|
|
45
86
|
more: { fontSize: 11, fontWeight: "700" },
|
|
@@ -47,6 +88,23 @@ export const defaultTheme: CalendarTheme = {
|
|
|
47
88
|
// whole number of lines (clipping on a line boundary, never mid-line).
|
|
48
89
|
eventTitle: { fontSize: 12, fontWeight: "700", lineHeight: 16 },
|
|
49
90
|
},
|
|
91
|
+
containers: {
|
|
92
|
+
monthContainer: {},
|
|
93
|
+
weekdayHeader: {},
|
|
94
|
+
weekRow: {},
|
|
95
|
+
dayCell: {},
|
|
96
|
+
dayBadge: {},
|
|
97
|
+
monthEvent: {},
|
|
98
|
+
columnHeader: {},
|
|
99
|
+
timeGridEvent: {},
|
|
100
|
+
nowIndicator: {},
|
|
101
|
+
resourceRow: {},
|
|
102
|
+
resourceLabel: {},
|
|
103
|
+
agendaList: {},
|
|
104
|
+
agendaRow: {},
|
|
105
|
+
allDayLane: {},
|
|
106
|
+
allDayColumn: {},
|
|
107
|
+
},
|
|
50
108
|
todayBadgeRadius: 999,
|
|
51
109
|
rangeBandHeight: 22,
|
|
52
110
|
};
|
|
@@ -59,6 +117,7 @@ export const defaultTheme: CalendarTheme = {
|
|
|
59
117
|
export const darkTheme: CalendarTheme = {
|
|
60
118
|
colors: darkColors,
|
|
61
119
|
text: defaultTheme.text,
|
|
120
|
+
containers: defaultTheme.containers,
|
|
62
121
|
todayBadgeRadius: defaultTheme.todayBadgeRadius,
|
|
63
122
|
rangeBandHeight: defaultTheme.rangeBandHeight,
|
|
64
123
|
};
|
|
@@ -69,6 +128,7 @@ export function mergeTheme(theme?: PartialCalendarTheme): CalendarTheme {
|
|
|
69
128
|
return {
|
|
70
129
|
colors: { ...defaultTheme.colors, ...theme.colors },
|
|
71
130
|
text: { ...defaultTheme.text, ...theme.text },
|
|
131
|
+
containers: { ...defaultTheme.containers, ...theme.containers },
|
|
72
132
|
todayBadgeRadius: theme.todayBadgeRadius ?? defaultTheme.todayBadgeRadius,
|
|
73
133
|
rangeBandHeight: theme.rangeBandHeight ?? defaultTheme.rangeBandHeight,
|
|
74
134
|
};
|
|
@@ -82,6 +142,7 @@ export function mergeTheme(theme?: PartialCalendarTheme): CalendarTheme {
|
|
|
82
142
|
export type PartialCalendarTheme = {
|
|
83
143
|
colors?: Partial<CalendarTheme["colors"]>;
|
|
84
144
|
text?: Partial<CalendarTheme["text"]>;
|
|
145
|
+
containers?: Partial<CalendarTheme["containers"]>;
|
|
85
146
|
todayBadgeRadius?: number;
|
|
86
147
|
rangeBandHeight?: number;
|
|
87
148
|
};
|
package/src/types.ts
CHANGED
|
@@ -9,11 +9,14 @@ export type {
|
|
|
9
9
|
BusinessHours,
|
|
10
10
|
CalendarEvent,
|
|
11
11
|
CalendarMode,
|
|
12
|
+
EventAccessibilityLabelContext,
|
|
13
|
+
EventAccessibilityLabeler,
|
|
12
14
|
EventKeyExtractor,
|
|
13
15
|
ICalendarEvent,
|
|
14
16
|
RecurrenceFrequency,
|
|
15
17
|
RecurrenceRule,
|
|
16
18
|
TimeGridMode,
|
|
19
|
+
WeekdayFormat,
|
|
17
20
|
WeekStartsOn,
|
|
18
21
|
} from "@super-calendar/core";
|
|
19
22
|
|
|
@@ -53,6 +56,12 @@ export type RenderEventArgs<T = unknown> = {
|
|
|
53
56
|
allDayLabel?: string;
|
|
54
57
|
/** Per-event style resolved from `eventCellStyle`; the built-in renderer merges it onto the box. */
|
|
55
58
|
cellStyle?: StyleProp<ViewStyle>;
|
|
59
|
+
/**
|
|
60
|
+
* Screen-reader label to announce for the event, injected by a consumer's
|
|
61
|
+
* `eventAccessibilityLabel` override. The built-in renderers use it in place of
|
|
62
|
+
* their default label; `undefined` falls back to that default.
|
|
63
|
+
*/
|
|
64
|
+
accessibilityLabel?: string;
|
|
56
65
|
onPress: () => void;
|
|
57
66
|
/** Wired when the consumer passes `onLongPressEvent`; otherwise undefined. */
|
|
58
67
|
onLongPress?: () => void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { EventAccessibilityLabeler } from "@super-calendar/core";
|
|
2
|
+
import type { RenderEvent, RenderEventArgs } from "../types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Wrap an event renderer so it injects a consumer's `eventAccessibilityLabel`
|
|
6
|
+
* override into `RenderEventArgs.accessibilityLabel`. The built-in renderers use
|
|
7
|
+
* that string in place of their default label, and custom renderers can read it
|
|
8
|
+
* too. Returns the renderer unchanged when no override is set, so the common path
|
|
9
|
+
* pays nothing.
|
|
10
|
+
*/
|
|
11
|
+
export function withEventAccessibilityLabel<T>(
|
|
12
|
+
renderEvent: RenderEvent<T>,
|
|
13
|
+
labeler: EventAccessibilityLabeler<T> | undefined,
|
|
14
|
+
ampm: boolean,
|
|
15
|
+
): RenderEvent<T> {
|
|
16
|
+
if (!labeler) return renderEvent;
|
|
17
|
+
const Base = renderEvent;
|
|
18
|
+
return function LabeledEvent(props: RenderEventArgs<T>) {
|
|
19
|
+
return (
|
|
20
|
+
<Base
|
|
21
|
+
{...props}
|
|
22
|
+
accessibilityLabel={labeler(props.event, {
|
|
23
|
+
mode: props.mode,
|
|
24
|
+
isAllDay: props.isAllDay ?? false,
|
|
25
|
+
ampm,
|
|
26
|
+
})}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
}
|