@super-calendar/native 2.1.5 → 2.3.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/dist/{DefaultMonthEvent-C-BiOsXb.d.mts → DefaultMonthEvent-BW6qy50X.d.ts} +62 -8
- package/dist/{DefaultMonthEvent-CcZLyfps.d.ts → DefaultMonthEvent-BbCMc60z.d.mts} +62 -8
- package/dist/{MonthList-BKlLes2B.mjs → MonthList-BidXJMfm.mjs} +98 -32
- package/dist/{MonthList-ege6HsEP.js → MonthList-CFXm7BK_.js} +102 -30
- package/dist/index.d.mts +110 -6
- package/dist/index.d.ts +110 -6
- package/dist/index.js +480 -113
- package/dist/index.mjs +476 -116
- 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 +37 -3
- package/src/components/DefaultEvent.tsx +68 -47
- package/src/components/DefaultMonthEvent.tsx +11 -8
- package/src/components/MonthList.tsx +15 -2
- package/src/components/MonthPager.tsx +18 -10
- package/src/components/MonthView.tsx +39 -10
- package/src/components/ResourceTimeline.tsx +441 -0
- package/src/components/TimeGrid.tsx +54 -17
- package/src/index.tsx +10 -0
- package/src/theme.ts +74 -4
- package/src/types.ts +9 -0
- package/src/utils/withEventAccessibilityLabel.tsx +30 -0
package/dist/picker.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as CalendarThemeProvider, D as mergeTheme, E as defaultTheme, O as useCalendarTheme, S as CalendarTheme, T as darkTheme, _ as RenderEvent, a as MonthPagerProps, b as WeekStartsOn, i as MonthPager, l as CalendarEvent, m as ICalendarEvent, n as MonthList, o as MonthView, p as EventKeyExtractor, r as MonthListProps, s as MonthViewProps, t as DefaultMonthEvent, u as CalendarMode, v as RenderEventArgs, w as PartialCalendarTheme } from "./DefaultMonthEvent-BbCMc60z.mjs";
|
|
2
2
|
import { DateRange, DateSelectionConstraints, DaySelectionState, MonthGrid, MonthGridDay, MonthGridWeek, MonthGridWeekday, UseDateRangeOptions, UseMonthGridOptions, buildMonthGrid, buildMonthWeeks, daySelectionState, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, minutesIntoDay, nextDateRange, useDateRange, useMonthGrid } from "@super-calendar/core";
|
|
3
3
|
export { type CalendarEvent, type CalendarMode, type CalendarTheme, CalendarThemeProvider, type DateRange, type DateSelectionConstraints, type DaySelectionState, DefaultMonthEvent, type EventKeyExtractor, type ICalendarEvent, type MonthGrid, type MonthGridDay, type MonthGridWeek, type MonthGridWeekday, MonthList, type MonthListProps, MonthPager, type MonthPagerProps, MonthView, type MonthViewProps, type PartialCalendarTheme, type RenderEvent, type RenderEventArgs, type UseDateRangeOptions, type UseMonthGridOptions, type WeekStartsOn, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, mergeTheme, minutesIntoDay, nextDateRange, useCalendarTheme, useDateRange, useMonthGrid };
|
package/dist/picker.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as CalendarThemeProvider, D as mergeTheme, E as defaultTheme, O as useCalendarTheme, S as CalendarTheme, T as darkTheme, _ as RenderEvent, a as MonthPagerProps, b as WeekStartsOn, i as MonthPager, l as CalendarEvent, m as ICalendarEvent, n as MonthList, o as MonthView, p as EventKeyExtractor, r as MonthListProps, s as MonthViewProps, t as DefaultMonthEvent, u as CalendarMode, v as RenderEventArgs, w as PartialCalendarTheme } from "./DefaultMonthEvent-BW6qy50X.js";
|
|
2
2
|
import { DateRange, DateSelectionConstraints, DaySelectionState, MonthGrid, MonthGridDay, MonthGridWeek, MonthGridWeekday, UseDateRangeOptions, UseMonthGridOptions, buildMonthGrid, buildMonthWeeks, daySelectionState, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, minutesIntoDay, nextDateRange, useDateRange, useMonthGrid } from "@super-calendar/core";
|
|
3
3
|
export { type CalendarEvent, type CalendarMode, type CalendarTheme, CalendarThemeProvider, type DateRange, type DateSelectionConstraints, type DaySelectionState, DefaultMonthEvent, type EventKeyExtractor, type ICalendarEvent, type MonthGrid, type MonthGridDay, type MonthGridWeek, type MonthGridWeekday, MonthList, type MonthListProps, MonthPager, type MonthPagerProps, MonthView, type MonthViewProps, type PartialCalendarTheme, type RenderEvent, type RenderEventArgs, type UseDateRangeOptions, type UseMonthGridOptions, type WeekStartsOn, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, mergeTheme, minutesIntoDay, nextDateRange, useCalendarTheme, useDateRange, useMonthGrid };
|
package/dist/picker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_MonthList = require("./MonthList-
|
|
2
|
+
const require_MonthList = require("./MonthList-CFXm7BK_.js");
|
|
3
3
|
let _super_calendar_core = require("@super-calendar/core");
|
|
4
4
|
exports.CalendarThemeProvider = require_MonthList.CalendarThemeProvider;
|
|
5
5
|
exports.DefaultMonthEvent = require_MonthList.DefaultMonthEvent;
|
package/dist/picker.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { c as
|
|
1
|
+
import { c as darkTheme, d as useCalendarTheme, i as MonthView, l as defaultTheme, n as DefaultMonthEvent, r as MonthPager, s as CalendarThemeProvider, t as MonthList, u as mergeTheme } from "./MonthList-BidXJMfm.mjs";
|
|
2
2
|
import { buildMonthGrid, buildMonthWeeks, daySelectionState, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, minutesIntoDay, nextDateRange, useDateRange, useMonthGrid } from "@super-calendar/core";
|
|
3
3
|
export { CalendarThemeProvider, DefaultMonthEvent, MonthList, MonthPager, MonthView, buildMonthGrid, buildMonthWeeks, darkTheme, daySelectionState, defaultTheme, getIsToday, getWeekDays, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, mergeTheme, minutesIntoDay, nextDateRange, useCalendarTheme, useDateRange, useMonthGrid };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@super-calendar/native",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Gesture-driven, virtualized month / week / day calendar and date picker for React Native (and web via react-native-web).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agenda",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"access": "public"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@super-calendar/core": "2.
|
|
67
|
+
"@super-calendar/core": "2.3.0"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"@legendapp/list": ">=3",
|
|
@@ -78,7 +78,7 @@ export function Agenda<T>({
|
|
|
78
78
|
);
|
|
79
79
|
}
|
|
80
80
|
return (
|
|
81
|
-
<View style={styles.eventRow}>
|
|
81
|
+
<View style={[styles.eventRow, theme.containers.agendaRow]}>
|
|
82
82
|
<RenderEventComponent
|
|
83
83
|
event={item.event}
|
|
84
84
|
mode="schedule"
|
|
@@ -98,7 +98,7 @@ export function Agenda<T>({
|
|
|
98
98
|
|
|
99
99
|
return (
|
|
100
100
|
<LegendList
|
|
101
|
-
style={styles.list}
|
|
101
|
+
style={[styles.list, theme.containers.agendaList]}
|
|
102
102
|
data={rows}
|
|
103
103
|
keyExtractor={keyExtractorRow}
|
|
104
104
|
renderItem={renderItem}
|
|
@@ -46,7 +46,13 @@ export function AllDayLane<T>({
|
|
|
46
46
|
if (perDay.every((list) => list.length === 0)) return null;
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
|
-
<View
|
|
49
|
+
<View
|
|
50
|
+
style={[
|
|
51
|
+
styles.lane,
|
|
52
|
+
{ borderBottomColor: theme.colors.gridLine },
|
|
53
|
+
theme.containers.allDayLane,
|
|
54
|
+
]}
|
|
55
|
+
>
|
|
50
56
|
<View style={[styles.gutter, { width: hourColumnWidth }]}>
|
|
51
57
|
{/* The "all-day" gutter label, mirroring the dom renderer: small, muted,
|
|
52
58
|
and right-aligned against the timed columns. Centered vertically so it
|
|
@@ -56,7 +62,10 @@ export function AllDayLane<T>({
|
|
|
56
62
|
</Text>
|
|
57
63
|
</View>
|
|
58
64
|
{days.map((day, dayIndex) => (
|
|
59
|
-
<View
|
|
65
|
+
<View
|
|
66
|
+
key={day.toISOString()}
|
|
67
|
+
style={[styles.column, { width: dayWidth }, theme.containers.allDayColumn]}
|
|
68
|
+
>
|
|
60
69
|
{perDay[dayIndex].map((event, index) => (
|
|
61
70
|
<View key={keyExtractor(event, index)} style={styles.chip}>
|
|
62
71
|
<RenderEventComponent
|
|
@@ -20,7 +20,11 @@ import type {
|
|
|
20
20
|
RenderEventArgs,
|
|
21
21
|
WeekStartsOn,
|
|
22
22
|
} from "../types";
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
type EventAccessibilityLabeler,
|
|
25
|
+
type WeekdayFormat,
|
|
26
|
+
getViewDays,
|
|
27
|
+
} from "@super-calendar/core";
|
|
24
28
|
import { Agenda } from "./Agenda";
|
|
25
29
|
import { DefaultEvent } from "./DefaultEvent";
|
|
26
30
|
import { MonthPager } from "./MonthPager";
|
|
@@ -104,6 +108,8 @@ export type CalendarProps<T> = {
|
|
|
104
108
|
disableMonthEventCellPress?: boolean;
|
|
105
109
|
/** First day of the week. Sunday = 0 (default) … Saturday = 6. */
|
|
106
110
|
weekStartsOn?: WeekStartsOn;
|
|
111
|
+
/** Weekday header label width: `narrow` ("M"), `short` ("Mon", default), or `long` ("Monday"). */
|
|
112
|
+
weekdayFormat?: WeekdayFormat;
|
|
107
113
|
/** Number of day columns when `mode="custom"`. Ignored by other modes. Default 1. */
|
|
108
114
|
numberOfDays?: number;
|
|
109
115
|
/**
|
|
@@ -114,6 +120,12 @@ export type CalendarProps<T> = {
|
|
|
114
120
|
weekEndsOn?: WeekStartsOn;
|
|
115
121
|
/** Replace the built-in event box. Return a `flex: 1` element. */
|
|
116
122
|
renderEvent?: RenderEvent<T>;
|
|
123
|
+
/**
|
|
124
|
+
* Override the screen-reader label for each event. Receives the event and a
|
|
125
|
+
* `{ mode, isAllDay, ampm }` context; return the full text to announce. Applies
|
|
126
|
+
* across every view. Defaults to the built-in title-and-time label.
|
|
127
|
+
*/
|
|
128
|
+
eventAccessibilityLabel?: EventAccessibilityLabeler<T>;
|
|
117
129
|
/** Per-event style merged onto the built-in event box (static or a function of the event). */
|
|
118
130
|
eventCellStyle?: StyleProp<ViewStyle> | ((event: CalendarEvent<T>) => StyleProp<ViewStyle>);
|
|
119
131
|
/** Per-date style for month cells and week/day columns (e.g. shade specific dates). */
|
|
@@ -284,9 +296,11 @@ export function Calendar<T>({
|
|
|
284
296
|
showAdjacentMonths,
|
|
285
297
|
disableMonthEventCellPress,
|
|
286
298
|
weekStartsOn = 0,
|
|
299
|
+
weekdayFormat,
|
|
287
300
|
numberOfDays,
|
|
288
301
|
weekEndsOn,
|
|
289
302
|
renderEvent = DefaultEvent,
|
|
303
|
+
eventAccessibilityLabel,
|
|
290
304
|
eventCellStyle,
|
|
291
305
|
calendarCellStyle,
|
|
292
306
|
businessHours,
|
|
@@ -365,7 +379,8 @@ export function Calendar<T>({
|
|
|
365
379
|
ampm == null &&
|
|
366
380
|
showTime == null &&
|
|
367
381
|
ellipsizeTitle == null &&
|
|
368
|
-
allDayLabel == null
|
|
382
|
+
allDayLabel == null &&
|
|
383
|
+
eventAccessibilityLabel == null
|
|
369
384
|
)
|
|
370
385
|
return renderEvent;
|
|
371
386
|
const Base = renderEvent;
|
|
@@ -380,10 +395,27 @@ export function Calendar<T>({
|
|
|
380
395
|
showTime={showTime}
|
|
381
396
|
ellipsizeTitle={ellipsizeTitle}
|
|
382
397
|
allDayLabel={allDayLabel}
|
|
398
|
+
accessibilityLabel={
|
|
399
|
+
eventAccessibilityLabel
|
|
400
|
+
? eventAccessibilityLabel(props.event, {
|
|
401
|
+
mode: props.mode,
|
|
402
|
+
isAllDay: props.isAllDay ?? false,
|
|
403
|
+
ampm: ampm ?? false,
|
|
404
|
+
})
|
|
405
|
+
: props.accessibilityLabel
|
|
406
|
+
}
|
|
383
407
|
/>
|
|
384
408
|
);
|
|
385
409
|
};
|
|
386
|
-
}, [
|
|
410
|
+
}, [
|
|
411
|
+
renderEvent,
|
|
412
|
+
eventCellStyle,
|
|
413
|
+
ampm,
|
|
414
|
+
showTime,
|
|
415
|
+
ellipsizeTitle,
|
|
416
|
+
allDayLabel,
|
|
417
|
+
eventAccessibilityLabel,
|
|
418
|
+
]);
|
|
387
419
|
|
|
388
420
|
return (
|
|
389
421
|
<CalendarThemeProvider value={mergedTheme}>
|
|
@@ -393,6 +425,7 @@ export function Calendar<T>({
|
|
|
393
425
|
events={events}
|
|
394
426
|
maxVisibleEventCount={maxVisibleEventCount}
|
|
395
427
|
weekStartsOn={weekStartsOn}
|
|
428
|
+
weekdayFormat={weekdayFormat}
|
|
396
429
|
locale={locale}
|
|
397
430
|
sortedMonthView={sortedMonthView}
|
|
398
431
|
moreLabel={moreLabel}
|
|
@@ -437,6 +470,7 @@ export function Calendar<T>({
|
|
|
437
470
|
cellHeight={cellHeight}
|
|
438
471
|
hourHeight={hourHeight}
|
|
439
472
|
weekStartsOn={weekStartsOn}
|
|
473
|
+
weekdayFormat={weekdayFormat}
|
|
440
474
|
renderEvent={resolvedRenderEvent}
|
|
441
475
|
keyExtractor={keyExtractor}
|
|
442
476
|
scrollOffsetMinutes={scrollOffsetMinutes}
|
|
@@ -38,6 +38,7 @@ export function DefaultEvent<T>({
|
|
|
38
38
|
showTime = true,
|
|
39
39
|
ellipsizeTitle = false,
|
|
40
40
|
allDayLabel,
|
|
41
|
+
accessibilityLabel: accessibilityLabelProp,
|
|
41
42
|
cellStyle,
|
|
42
43
|
onPress,
|
|
43
44
|
onLongPress,
|
|
@@ -60,15 +61,19 @@ export function DefaultEvent<T>({
|
|
|
60
61
|
);
|
|
61
62
|
|
|
62
63
|
// Announce the full event to screen readers: title plus the all-day label or
|
|
63
|
-
// the time range (which is otherwise only shown visually).
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
// the time range (which is otherwise only shown visually). A consumer's
|
|
65
|
+
// `eventAccessibilityLabel` override, threaded in as `accessibilityLabelProp`,
|
|
66
|
+
// takes precedence.
|
|
67
|
+
const accessibilityLabel =
|
|
68
|
+
accessibilityLabelProp ??
|
|
69
|
+
eventAccessibilityLabel({
|
|
70
|
+
title: event.title,
|
|
71
|
+
isAllDay: isAllDayEvent,
|
|
72
|
+
start: event.start,
|
|
73
|
+
end: event.end,
|
|
74
|
+
ampm,
|
|
75
|
+
allDayLabel,
|
|
76
|
+
});
|
|
72
77
|
|
|
73
78
|
// Month cells and the all-day lane get a single clipped line; the timed grid
|
|
74
79
|
// (and the roomy schedule rows) wrap to fill the box. `titleNumberOfLines`
|
|
@@ -106,6 +111,14 @@ export function DefaultEvent<T>({
|
|
|
106
111
|
return { display: layout.value.showTime ? "flex" : "none" };
|
|
107
112
|
}, [layout]);
|
|
108
113
|
|
|
114
|
+
// A chip reduced to a single title line (no time) centers it vertically, so a
|
|
115
|
+
// very short event reads balanced instead of hugging the top edge. Layout is
|
|
116
|
+
// recomputed on the UI thread, so the alignment tracks pinch-zoom live.
|
|
117
|
+
const contentStyle = useAnimatedStyle(() => {
|
|
118
|
+
const { titleMaxLines, showTime } = layout.value;
|
|
119
|
+
return { justifyContent: titleMaxLines === 1 && !showTime ? "center" : "flex-start" };
|
|
120
|
+
}, [layout]);
|
|
121
|
+
|
|
109
122
|
return (
|
|
110
123
|
<TouchableOpacity
|
|
111
124
|
style={[
|
|
@@ -122,56 +135,58 @@ export function DefaultEvent<T>({
|
|
|
122
135
|
accessibilityLabel={accessibilityLabel}
|
|
123
136
|
accessibilityState={{ disabled: event.disabled ?? false }}
|
|
124
137
|
>
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
138
|
+
<Animated.View testID="event-chip-content" style={[styles.content, contentStyle]}>
|
|
139
|
+
{event.title ? (
|
|
140
|
+
fixedTitleLines == null ? (
|
|
141
|
+
<Animated.View style={[styles.titleClip, titleClipStyle]}>
|
|
142
|
+
<Text
|
|
143
|
+
style={[
|
|
144
|
+
theme.text.eventTitle,
|
|
145
|
+
isSchedule && styles.scheduleTitle,
|
|
146
|
+
{ color: theme.colors.eventText },
|
|
147
|
+
]}
|
|
148
|
+
ellipsizeMode={ellipsizeMode}
|
|
149
|
+
allowFontScaling={false}
|
|
150
|
+
>
|
|
151
|
+
{event.title}
|
|
152
|
+
</Text>
|
|
153
|
+
</Animated.View>
|
|
154
|
+
) : (
|
|
128
155
|
<Text
|
|
129
156
|
style={[
|
|
130
157
|
theme.text.eventTitle,
|
|
158
|
+
styles.title,
|
|
131
159
|
isSchedule && styles.scheduleTitle,
|
|
132
160
|
{ color: theme.colors.eventText },
|
|
133
161
|
]}
|
|
162
|
+
// Month cells and the all-day lane are compact: a single clipped line.
|
|
163
|
+
numberOfLines={fixedTitleLines}
|
|
134
164
|
ellipsizeMode={ellipsizeMode}
|
|
135
165
|
allowFontScaling={false}
|
|
136
166
|
>
|
|
137
167
|
{event.title}
|
|
138
168
|
</Text>
|
|
169
|
+
)
|
|
170
|
+
) : null}
|
|
171
|
+
{timeLabel ? (
|
|
172
|
+
<Animated.View style={timeStyle}>
|
|
173
|
+
<Text
|
|
174
|
+
style={[
|
|
175
|
+
styles.time,
|
|
176
|
+
isSchedule && styles.scheduleTime,
|
|
177
|
+
{ color: theme.colors.eventText },
|
|
178
|
+
]}
|
|
179
|
+
// Wrap rather than clip horizontally: a narrow column shows the full
|
|
180
|
+
// range across two lines instead of a cut-off "11:00 - 1".
|
|
181
|
+
numberOfLines={2}
|
|
182
|
+
ellipsizeMode={ellipsizeMode}
|
|
183
|
+
allowFontScaling={false}
|
|
184
|
+
>
|
|
185
|
+
{timeLabel}
|
|
186
|
+
</Text>
|
|
139
187
|
</Animated.View>
|
|
140
|
-
) :
|
|
141
|
-
|
|
142
|
-
style={[
|
|
143
|
-
theme.text.eventTitle,
|
|
144
|
-
styles.title,
|
|
145
|
-
isSchedule && styles.scheduleTitle,
|
|
146
|
-
{ color: theme.colors.eventText },
|
|
147
|
-
]}
|
|
148
|
-
// Month cells and the all-day lane are compact: a single clipped line.
|
|
149
|
-
numberOfLines={fixedTitleLines}
|
|
150
|
-
ellipsizeMode={ellipsizeMode}
|
|
151
|
-
allowFontScaling={false}
|
|
152
|
-
>
|
|
153
|
-
{event.title}
|
|
154
|
-
</Text>
|
|
155
|
-
)
|
|
156
|
-
) : null}
|
|
157
|
-
{timeLabel ? (
|
|
158
|
-
<Animated.View style={timeStyle}>
|
|
159
|
-
<Text
|
|
160
|
-
style={[
|
|
161
|
-
styles.time,
|
|
162
|
-
isSchedule && styles.scheduleTime,
|
|
163
|
-
{ color: theme.colors.eventText },
|
|
164
|
-
]}
|
|
165
|
-
// Wrap rather than clip horizontally: a narrow column shows the full
|
|
166
|
-
// range across two lines instead of a cut-off "11:00 - 1".
|
|
167
|
-
numberOfLines={2}
|
|
168
|
-
ellipsizeMode={ellipsizeMode}
|
|
169
|
-
allowFontScaling={false}
|
|
170
|
-
>
|
|
171
|
-
{timeLabel}
|
|
172
|
-
</Text>
|
|
173
|
-
</Animated.View>
|
|
174
|
-
) : null}
|
|
188
|
+
) : null}
|
|
189
|
+
</Animated.View>
|
|
175
190
|
</TouchableOpacity>
|
|
176
191
|
);
|
|
177
192
|
}
|
|
@@ -205,6 +220,12 @@ const styles = StyleSheet.create({
|
|
|
205
220
|
lineHeight: 18,
|
|
206
221
|
opacity: 0.75,
|
|
207
222
|
},
|
|
223
|
+
// The title/time column; grows into the grid's sized box so a lone title line
|
|
224
|
+
// can center vertically, and shrinks with it (content-sized chips unaffected).
|
|
225
|
+
content: {
|
|
226
|
+
flexGrow: 1,
|
|
227
|
+
flexShrink: 1,
|
|
228
|
+
},
|
|
208
229
|
// Clips the wrapped title to the animated whole-line max-height.
|
|
209
230
|
titleClip: {
|
|
210
231
|
overflow: "hidden",
|
|
@@ -24,6 +24,7 @@ export function DefaultMonthEvent<T>({
|
|
|
24
24
|
showTime = true,
|
|
25
25
|
ellipsizeTitle = false,
|
|
26
26
|
allDayLabel,
|
|
27
|
+
accessibilityLabel: accessibilityLabelProp,
|
|
27
28
|
cellStyle,
|
|
28
29
|
onPress,
|
|
29
30
|
onLongPress,
|
|
@@ -40,14 +41,16 @@ export function DefaultMonthEvent<T>({
|
|
|
40
41
|
allDayLabel,
|
|
41
42
|
});
|
|
42
43
|
const ellipsizeMode = titleEllipsizeMode(ellipsizeTitle);
|
|
43
|
-
const accessibilityLabel =
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
const accessibilityLabel =
|
|
45
|
+
accessibilityLabelProp ??
|
|
46
|
+
eventAccessibilityLabel({
|
|
47
|
+
title: event.title,
|
|
48
|
+
isAllDay: isAllDayEvent,
|
|
49
|
+
start: event.start,
|
|
50
|
+
end: event.end,
|
|
51
|
+
ampm,
|
|
52
|
+
allDayLabel,
|
|
53
|
+
});
|
|
51
54
|
|
|
52
55
|
return (
|
|
53
56
|
<TouchableOpacity
|
|
@@ -31,9 +31,11 @@ import {
|
|
|
31
31
|
type CalendarSelection,
|
|
32
32
|
CalendarSelectionProvider,
|
|
33
33
|
type DateRange,
|
|
34
|
+
type EventAccessibilityLabeler,
|
|
35
|
+
type WeekdayFormat,
|
|
34
36
|
isDateSelectable,
|
|
35
37
|
} from "@super-calendar/core";
|
|
36
|
-
import { buildMonthWeeks, getWeekDays } from "@super-calendar/core";
|
|
38
|
+
import { buildMonthWeeks, getWeekDays, weekdayFormatToken } from "@super-calendar/core";
|
|
37
39
|
import { DefaultMonthEvent } from "./DefaultMonthEvent";
|
|
38
40
|
import { MonthView } from "./MonthView";
|
|
39
41
|
|
|
@@ -76,6 +78,8 @@ export type MonthListProps<T> = {
|
|
|
76
78
|
/** Events to render in the grids. Omit for an events-free date picker. */
|
|
77
79
|
events?: CalendarEvent<T>[];
|
|
78
80
|
weekStartsOn: WeekStartsOn;
|
|
81
|
+
/** Weekday header label width: `narrow` ("M"), `short` ("Mon", default), or `long` ("Monday"). */
|
|
82
|
+
weekdayFormat?: WeekdayFormat;
|
|
79
83
|
/**
|
|
80
84
|
* Height of each week row (px). The month block sizes to its row count. Defaults
|
|
81
85
|
* to a taller row when `events` are shown (so a day fits ~3 chips) and a compact
|
|
@@ -106,6 +110,12 @@ export type MonthListProps<T> = {
|
|
|
106
110
|
calendarCellStyle?: (date: Date) => StyleProp<ViewStyle>;
|
|
107
111
|
/** Replace the built-in event box. Defaults to `DefaultEvent`. */
|
|
108
112
|
renderEvent?: RenderEvent<T>;
|
|
113
|
+
/**
|
|
114
|
+
* Override the screen-reader label for each event chip. Receives the event and a
|
|
115
|
+
* `{ mode: "month", isAllDay, ampm: false }` context; return the full text to
|
|
116
|
+
* announce. Defaults to the built-in title-and-time label.
|
|
117
|
+
*/
|
|
118
|
+
eventAccessibilityLabel?: EventAccessibilityLabeler<T>;
|
|
109
119
|
/** Stable key per event. Defaults to start-time + index. */
|
|
110
120
|
keyExtractor?: EventKeyExtractor<T>;
|
|
111
121
|
onPressDay?: (date: Date) => void;
|
|
@@ -129,6 +139,7 @@ function MonthListInner<T>({
|
|
|
129
139
|
date,
|
|
130
140
|
events = NO_EVENTS as CalendarEvent<T>[],
|
|
131
141
|
weekStartsOn,
|
|
142
|
+
weekdayFormat = "short",
|
|
132
143
|
weekRowHeight: weekRowHeightProp,
|
|
133
144
|
monthHeaderHeight = DEFAULT_MONTH_HEADER_HEIGHT,
|
|
134
145
|
maxVisibleEventCount,
|
|
@@ -147,6 +158,7 @@ function MonthListInner<T>({
|
|
|
147
158
|
isDateDisabled,
|
|
148
159
|
calendarCellStyle,
|
|
149
160
|
renderEvent = DefaultMonthEvent,
|
|
161
|
+
eventAccessibilityLabel,
|
|
150
162
|
keyExtractor = defaultKeyExtractor as EventKeyExtractor<T>,
|
|
151
163
|
onPressDay,
|
|
152
164
|
onLongPressDay,
|
|
@@ -430,6 +442,7 @@ function MonthListInner<T>({
|
|
|
430
442
|
fillCellOnSelection={fillCellOnSelection}
|
|
431
443
|
calendarCellStyle={calendarCellStyle}
|
|
432
444
|
renderEvent={renderEvent}
|
|
445
|
+
eventAccessibilityLabel={eventAccessibilityLabel}
|
|
433
446
|
keyExtractor={keyExtractor}
|
|
434
447
|
onPressDay={dragEnabled ? handlePressDay : onPressDay}
|
|
435
448
|
onLongPressDay={onLongPressDay}
|
|
@@ -511,7 +524,7 @@ function MonthListInner<T>({
|
|
|
511
524
|
style={[styles.weekdayLabel, { color: theme.colors.textMuted }]}
|
|
512
525
|
allowFontScaling={false}
|
|
513
526
|
>
|
|
514
|
-
{format(day,
|
|
527
|
+
{format(day, weekdayFormatToken(weekdayFormat), { locale })}
|
|
515
528
|
</Text>
|
|
516
529
|
))}
|
|
517
530
|
</View>
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from "react-native";
|
|
18
18
|
import { useCalendarTheme } from "../theme";
|
|
19
19
|
import type { CalendarEvent, EventKeyExtractor, RenderEvent, WeekStartsOn } from "../types";
|
|
20
|
-
import { getWeekDays } from "@super-calendar/core";
|
|
20
|
+
import { type WeekdayFormat, getWeekDays, weekdayFormatToken } from "@super-calendar/core";
|
|
21
21
|
import { useWebPagerKeys } from "../utils/useWebPagerKeys";
|
|
22
22
|
import { MonthView } from "./MonthView";
|
|
23
23
|
|
|
@@ -40,6 +40,7 @@ export type MonthPagerProps<T> = {
|
|
|
40
40
|
events: CalendarEvent<T>[];
|
|
41
41
|
maxVisibleEventCount?: number;
|
|
42
42
|
weekStartsOn: WeekStartsOn;
|
|
43
|
+
weekdayFormat?: WeekdayFormat;
|
|
43
44
|
locale?: Locale;
|
|
44
45
|
sortedMonthView?: boolean;
|
|
45
46
|
moreLabel?: string;
|
|
@@ -70,6 +71,7 @@ function MonthPagerInner<T>({
|
|
|
70
71
|
events,
|
|
71
72
|
maxVisibleEventCount,
|
|
72
73
|
weekStartsOn,
|
|
74
|
+
weekdayFormat = "short",
|
|
73
75
|
locale,
|
|
74
76
|
sortedMonthView,
|
|
75
77
|
moreLabel,
|
|
@@ -266,16 +268,19 @@ function MonthPagerInner<T>({
|
|
|
266
268
|
);
|
|
267
269
|
|
|
268
270
|
return (
|
|
269
|
-
<View ref={containerRef} style={styles.container}>
|
|
271
|
+
<View ref={containerRef} style={[styles.container, theme.containers.monthContainer]}>
|
|
270
272
|
{/* The active month's title, above the (shared) weekday header — mirrors the
|
|
271
273
|
dom MonthView's title. The grids below omit their own title/weekdays. */}
|
|
272
|
-
<Text
|
|
274
|
+
<Text
|
|
275
|
+
style={[styles.monthTitle, theme.text.monthTitle, { color: theme.colors.text }]}
|
|
276
|
+
allowFontScaling={false}
|
|
277
|
+
>
|
|
273
278
|
{format(date, "MMMM yyyy", locale ? { locale } : undefined)}
|
|
274
279
|
</Text>
|
|
275
280
|
{renderHeaderForMonthView ? (
|
|
276
281
|
renderHeaderForMonthView(weekDays)
|
|
277
282
|
) : (
|
|
278
|
-
<MonthWeekdayHeader weekDays={weekDays} locale={locale} />
|
|
283
|
+
<MonthWeekdayHeader weekDays={weekDays} weekdayFormat={weekdayFormat} locale={locale} />
|
|
279
284
|
)}
|
|
280
285
|
<View
|
|
281
286
|
style={styles.pager}
|
|
@@ -341,22 +346,27 @@ export const MonthPager = memo(MonthPagerInner) as typeof MonthPagerInner;
|
|
|
341
346
|
|
|
342
347
|
type MonthWeekdayHeaderProps = {
|
|
343
348
|
weekDays: Date[];
|
|
349
|
+
weekdayFormat?: WeekdayFormat;
|
|
344
350
|
locale?: Locale;
|
|
345
351
|
};
|
|
346
352
|
|
|
347
353
|
// The default weekday-label row above the month grid (e.g. "Mon Tue Wed…"),
|
|
348
354
|
// one flex column per day to line up with the grid cells below.
|
|
349
|
-
const MonthWeekdayHeader = ({
|
|
355
|
+
const MonthWeekdayHeader = ({
|
|
356
|
+
weekDays,
|
|
357
|
+
weekdayFormat = "short",
|
|
358
|
+
locale,
|
|
359
|
+
}: MonthWeekdayHeaderProps) => {
|
|
350
360
|
const theme = useCalendarTheme();
|
|
351
361
|
return (
|
|
352
|
-
<View style={styles.weekdayHeader}>
|
|
362
|
+
<View style={[styles.weekdayHeader, theme.containers.weekdayHeader]}>
|
|
353
363
|
{weekDays.map((day) => (
|
|
354
364
|
<Text
|
|
355
365
|
key={day.toISOString()}
|
|
356
366
|
style={[theme.text.weekday, styles.weekdayLabel, { color: theme.colors.textMuted }]}
|
|
357
367
|
allowFontScaling={false}
|
|
358
368
|
>
|
|
359
|
-
{format(day,
|
|
369
|
+
{format(day, weekdayFormatToken(weekdayFormat), { locale })}
|
|
360
370
|
</Text>
|
|
361
371
|
))}
|
|
362
372
|
</View>
|
|
@@ -377,10 +387,8 @@ const styles = StyleSheet.create({
|
|
|
377
387
|
webNoScroll: {
|
|
378
388
|
overflow: "hidden",
|
|
379
389
|
},
|
|
380
|
-
//
|
|
390
|
+
// Layout only; the font is themeable via `theme.text.monthTitle`.
|
|
381
391
|
monthTitle: {
|
|
382
|
-
fontSize: 17,
|
|
383
|
-
fontWeight: "700",
|
|
384
392
|
paddingTop: 10,
|
|
385
393
|
paddingHorizontal: 14,
|
|
386
394
|
paddingBottom: 6,
|