@oxy.so/bloom 4.31.0 → 4.33.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/docs/adoption-matrix.mdx +4 -3
- package/docs/date-picker.mdx +24 -0
- package/docs/locale.mdx +46 -0
- package/docs/provider.mdx +11 -0
- package/lib/commonjs/calendar/shared.js +5 -11
- package/lib/commonjs/calendar/shared.js.map +1 -1
- package/lib/commonjs/date-picker/Calendar.js +12 -1
- package/lib/commonjs/date-picker/Calendar.js.map +1 -1
- package/lib/commonjs/date-picker/CalendarMonth.js +4 -2
- package/lib/commonjs/date-picker/CalendarMonth.js.map +1 -1
- package/lib/commonjs/date-picker/DatePicker.js +15 -3
- package/lib/commonjs/date-picker/DatePicker.js.map +1 -1
- package/lib/commonjs/date-picker/DateRangePicker.js +21 -9
- package/lib/commonjs/date-picker/DateRangePicker.js.map +1 -1
- package/lib/commonjs/date-picker/MeetingScheduler.js +19 -13
- package/lib/commonjs/date-picker/MeetingScheduler.js.map +1 -1
- package/lib/commonjs/date-picker/PickerShell.js +4 -2
- package/lib/commonjs/date-picker/PickerShell.js.map +1 -1
- package/lib/commonjs/date-picker/calendar-grid.js +15 -21
- package/lib/commonjs/date-picker/calendar-grid.js.map +1 -1
- package/lib/commonjs/date-picker/messages.js +526 -0
- package/lib/commonjs/date-picker/messages.js.map +1 -0
- package/lib/commonjs/index.js +1063 -1034
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +1063 -1034
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/locale/context.js +35 -0
- package/lib/commonjs/locale/context.js.map +1 -0
- package/lib/commonjs/locale/format-date.js +34 -0
- package/lib/commonjs/locale/format-date.js.map +1 -0
- package/lib/commonjs/locale/index.js +32 -0
- package/lib/commonjs/locale/index.js.map +1 -0
- package/lib/commonjs/locale/languages.js +35 -0
- package/lib/commonjs/locale/languages.js.map +1 -0
- package/lib/commonjs/locale/messages.js +34 -0
- package/lib/commonjs/locale/messages.js.map +1 -0
- package/lib/commonjs/locale/plural.js +53 -0
- package/lib/commonjs/locale/plural.js.map +1 -0
- package/lib/commonjs/provider/BloomProvider.js +18 -13
- package/lib/commonjs/provider/BloomProvider.js.map +1 -1
- package/lib/module/calendar/shared.js +5 -11
- package/lib/module/calendar/shared.js.map +1 -1
- package/lib/module/date-picker/Calendar.js +12 -1
- package/lib/module/date-picker/Calendar.js.map +1 -1
- package/lib/module/date-picker/CalendarMonth.js +4 -2
- package/lib/module/date-picker/CalendarMonth.js.map +1 -1
- package/lib/module/date-picker/DatePicker.js +15 -3
- package/lib/module/date-picker/DatePicker.js.map +1 -1
- package/lib/module/date-picker/DateRangePicker.js +21 -9
- package/lib/module/date-picker/DateRangePicker.js.map +1 -1
- package/lib/module/date-picker/MeetingScheduler.js +19 -13
- package/lib/module/date-picker/MeetingScheduler.js.map +1 -1
- package/lib/module/date-picker/PickerShell.js +4 -2
- package/lib/module/date-picker/PickerShell.js.map +1 -1
- package/lib/module/date-picker/calendar-grid.js +15 -21
- package/lib/module/date-picker/calendar-grid.js.map +1 -1
- package/lib/module/date-picker/messages.js +523 -0
- package/lib/module/date-picker/messages.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +1 -0
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/locale/context.js +30 -0
- package/lib/module/locale/context.js.map +1 -0
- package/lib/module/locale/format-date.js +30 -0
- package/lib/module/locale/format-date.js.map +1 -0
- package/lib/module/locale/index.js +7 -0
- package/lib/module/locale/index.js.map +1 -0
- package/lib/module/locale/languages.js +29 -0
- package/lib/module/locale/languages.js.map +1 -0
- package/lib/module/locale/messages.js +30 -0
- package/lib/module/locale/messages.js.map +1 -0
- package/lib/module/locale/plural.js +48 -0
- package/lib/module/locale/plural.js.map +1 -0
- package/lib/module/provider/BloomProvider.js +16 -11
- package/lib/module/provider/BloomProvider.js.map +1 -1
- package/lib/typescript/commonjs/calendar/shared.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/Calendar.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/CalendarMonth.d.ts +4 -1
- package/lib/typescript/commonjs/date-picker/CalendarMonth.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/DatePicker.d.ts +1 -1
- package/lib/typescript/commonjs/date-picker/DatePicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/DateRangePicker.d.ts +1 -1
- package/lib/typescript/commonjs/date-picker/DateRangePicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/MeetingScheduler.d.ts +1 -1
- package/lib/typescript/commonjs/date-picker/MeetingScheduler.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/PickerShell.d.ts +3 -1
- package/lib/typescript/commonjs/date-picker/PickerShell.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/calendar-grid.d.ts +3 -3
- package/lib/typescript/commonjs/date-picker/calendar-grid.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/index.d.ts +1 -1
- package/lib/typescript/commonjs/date-picker/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/date-picker/messages.d.ts +31 -0
- package/lib/typescript/commonjs/date-picker/messages.d.ts.map +1 -0
- package/lib/typescript/commonjs/date-picker/types.d.ts +54 -12
- package/lib/typescript/commonjs/date-picker/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +2 -0
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/context.d.ts +18 -0
- package/lib/typescript/commonjs/locale/context.d.ts.map +1 -0
- package/lib/typescript/commonjs/locale/format-date.d.ts +13 -0
- package/lib/typescript/commonjs/locale/format-date.d.ts.map +1 -0
- package/lib/typescript/commonjs/locale/index.d.ts +3 -0
- package/lib/typescript/commonjs/locale/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/locale/languages.d.ts +16 -0
- package/lib/typescript/commonjs/locale/languages.d.ts.map +1 -0
- package/lib/typescript/commonjs/locale/messages.d.ts +18 -0
- package/lib/typescript/commonjs/locale/messages.d.ts.map +1 -0
- package/lib/typescript/commonjs/locale/plural.d.ts +19 -0
- package/lib/typescript/commonjs/locale/plural.d.ts.map +1 -0
- package/lib/typescript/commonjs/provider/BloomProvider.d.ts +1 -1
- package/lib/typescript/commonjs/provider/BloomProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/provider/types.d.ts +6 -0
- package/lib/typescript/commonjs/provider/types.d.ts.map +1 -1
- package/lib/typescript/module/calendar/shared.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/Calendar.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/CalendarMonth.d.ts +4 -1
- package/lib/typescript/module/date-picker/CalendarMonth.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/DatePicker.d.ts +1 -1
- package/lib/typescript/module/date-picker/DatePicker.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/DateRangePicker.d.ts +1 -1
- package/lib/typescript/module/date-picker/DateRangePicker.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/MeetingScheduler.d.ts +1 -1
- package/lib/typescript/module/date-picker/MeetingScheduler.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/PickerShell.d.ts +3 -1
- package/lib/typescript/module/date-picker/PickerShell.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/calendar-grid.d.ts +3 -3
- package/lib/typescript/module/date-picker/calendar-grid.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/index.d.ts +1 -1
- package/lib/typescript/module/date-picker/index.d.ts.map +1 -1
- package/lib/typescript/module/date-picker/messages.d.ts +31 -0
- package/lib/typescript/module/date-picker/messages.d.ts.map +1 -0
- package/lib/typescript/module/date-picker/types.d.ts +54 -12
- package/lib/typescript/module/date-picker/types.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +2 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +2 -0
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/locale/context.d.ts +18 -0
- package/lib/typescript/module/locale/context.d.ts.map +1 -0
- package/lib/typescript/module/locale/format-date.d.ts +13 -0
- package/lib/typescript/module/locale/format-date.d.ts.map +1 -0
- package/lib/typescript/module/locale/index.d.ts +3 -0
- package/lib/typescript/module/locale/index.d.ts.map +1 -0
- package/lib/typescript/module/locale/languages.d.ts +16 -0
- package/lib/typescript/module/locale/languages.d.ts.map +1 -0
- package/lib/typescript/module/locale/messages.d.ts +18 -0
- package/lib/typescript/module/locale/messages.d.ts.map +1 -0
- package/lib/typescript/module/locale/plural.d.ts +19 -0
- package/lib/typescript/module/locale/plural.d.ts.map +1 -0
- package/lib/typescript/module/provider/BloomProvider.d.ts +1 -1
- package/lib/typescript/module/provider/BloomProvider.d.ts.map +1 -1
- package/lib/typescript/module/provider/types.d.ts +6 -0
- package/lib/typescript/module/provider/types.d.ts.map +1 -1
- package/package.json +18 -1
- package/src/calendar/shared.ts +5 -12
- package/src/date-picker/Calendar.tsx +17 -2
- package/src/date-picker/CalendarMonth.tsx +7 -2
- package/src/date-picker/DatePicker.tsx +12 -3
- package/src/date-picker/DateRangePicker.tsx +17 -8
- package/src/date-picker/MeetingScheduler.tsx +18 -11
- package/src/date-picker/PickerShell.tsx +6 -2
- package/src/date-picker/calendar-grid.ts +19 -24
- package/src/date-picker/index.ts +4 -0
- package/src/date-picker/messages.ts +470 -0
- package/src/date-picker/types.ts +66 -12
- package/src/index.ts +2 -0
- package/src/index.web.ts +2 -0
- package/src/locale/context.ts +23 -0
- package/src/locale/format-date.ts +28 -0
- package/src/locale/index.ts +4 -0
- package/src/locale/languages.ts +45 -0
- package/src/locale/messages.ts +29 -0
- package/src/locale/plural.ts +53 -0
- package/src/provider/BloomProvider.tsx +39 -35
- package/src/provider/types.ts +6 -0
- package/src/__tests__/support/adoption-matrix.ts +0 -708
- package/src/__tests__/support/collision-fixture-barrel.ts +0 -20
- package/src/__tests__/support/commerce-harness.tsx +0 -97
- package/src/__tests__/support/composite.ts +0 -68
- package/src/__tests__/support/constructed-style-sheets.ts +0 -68
- package/src/__tests__/support/press-host.ts +0 -30
- package/src/__tests__/support/rendered-style.ts +0 -99
- package/src/__tests__/support/unread-hook-fixture.ts +0 -33
- package/src/__tests__/support/worklet-capture-fixture.tsx +0 -28
- package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +0 -9346
- package/src/theme/__tests__/__fixtures__/tonal-glass-primary-failures.json +0 -69
- package/src/theme/__tests__/fixtures/color-engine-golden.json +0 -1
|
@@ -14,5 +14,11 @@ export interface BloomProviderProps extends Omit<BloomThemeProviderProps, 'child
|
|
|
14
14
|
imageResolver?: ImageResolver;
|
|
15
15
|
/** `false` disables haptic feedback app-wide (honored by every `useHaptics()` call). */
|
|
16
16
|
haptics?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* BCP 47 locale for every Bloom component below — dates, month names and
|
|
19
|
+
* Bloom's own strings (Cancel, Apply, …). A component's own `locale` prop
|
|
20
|
+
* wins. Unset, components follow the runtime's locale.
|
|
21
|
+
*/
|
|
22
|
+
locale?: string;
|
|
17
23
|
}
|
|
18
24
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/provider/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC;IACnF,QAAQ,EAAE,SAAS,CAAC;IACpB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/provider/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC;IACnF,QAAQ,EAAE,SAAS,CAAC;IACpB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxy.so/bloom",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.33.0",
|
|
4
4
|
"packageManager": "bun@1.3.14",
|
|
5
5
|
"description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
|
|
6
6
|
"main": "lib/commonjs/index.js",
|
|
@@ -79,6 +79,20 @@
|
|
|
79
79
|
"default": "./lib/commonjs/image-resolver/index.js"
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
|
+
"./locale": {
|
|
83
|
+
"react-native": {
|
|
84
|
+
"types": "./lib/typescript/module/locale/index.d.ts",
|
|
85
|
+
"default": "./src/locale/index.ts"
|
|
86
|
+
},
|
|
87
|
+
"import": {
|
|
88
|
+
"types": "./lib/typescript/module/locale/index.d.ts",
|
|
89
|
+
"default": "./lib/module/locale/index.js"
|
|
90
|
+
},
|
|
91
|
+
"require": {
|
|
92
|
+
"types": "./lib/typescript/commonjs/locale/index.d.ts",
|
|
93
|
+
"default": "./lib/commonjs/locale/index.js"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
82
96
|
"./image-aspect-ratio-cache": {
|
|
83
97
|
"react-native": {
|
|
84
98
|
"types": "./lib/typescript/module/image-aspect-ratio-cache/index.d.ts",
|
|
@@ -3452,6 +3466,9 @@
|
|
|
3452
3466
|
"image-resolver": [
|
|
3453
3467
|
"./lib/typescript/module/image-resolver/index.d.ts"
|
|
3454
3468
|
],
|
|
3469
|
+
"locale": [
|
|
3470
|
+
"./lib/typescript/module/locale/index.d.ts"
|
|
3471
|
+
],
|
|
3455
3472
|
"image-aspect-ratio-cache": [
|
|
3456
3473
|
"./lib/typescript/module/image-aspect-ratio-cache/index.d.ts"
|
|
3457
3474
|
],
|
package/src/calendar/shared.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Platform, useWindowDimensions } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
import { addDays, buildMonthGrid, isSameMonth, startOfDay } from '../date-picker/calendar-grid';
|
|
5
5
|
import type { CalendarViewEvent } from './types';
|
|
6
|
+
import { formatGregorian } from '../locale/format-date';
|
|
6
7
|
|
|
7
8
|
export const IS_WEB = Platform.OS === 'web';
|
|
8
9
|
|
|
@@ -95,18 +96,10 @@ export function currentGmtLabel(now: Date = new Date()): string {
|
|
|
95
96
|
return `GMT${offset >= 0 ? '+' : ''}${offset}`;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
function format(date: Date, locale: string | undefined, options: Intl.DateTimeFormatOptions): string | null {
|
|
99
|
-
try {
|
|
100
|
-
return new Intl.DateTimeFormat(locale, options).format(date);
|
|
101
|
-
} catch {
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
99
|
/** `Tue, Aug 11` — the details panel's date line. */
|
|
107
100
|
export function formatEventDate(date: Date, locale?: string): string {
|
|
108
101
|
return (
|
|
109
|
-
|
|
102
|
+
formatGregorian(date, locale, {
|
|
110
103
|
weekday: 'short',
|
|
111
104
|
month: 'short',
|
|
112
105
|
day: 'numeric',
|
|
@@ -116,7 +109,7 @@ export function formatEventDate(date: Date, locale?: string): string {
|
|
|
116
109
|
|
|
117
110
|
/** `Aug` — the month switcher's label below `sm`. */
|
|
118
111
|
export function formatShortMonth(date: Date, locale?: string): string {
|
|
119
|
-
return
|
|
112
|
+
return formatGregorian(date, locale, { month: 'short' }) ?? String(date.getMonth() + 1);
|
|
120
113
|
}
|
|
121
114
|
|
|
122
115
|
/** `Sun` … `Sat` — the month grid's weekday pills. */
|
|
@@ -126,8 +119,8 @@ export function weekdayShortLabels(locale?: string): { short: string; long: stri
|
|
|
126
119
|
return fallback.map((name, index) => {
|
|
127
120
|
const date = addDays(sunday, index);
|
|
128
121
|
return {
|
|
129
|
-
short:
|
|
130
|
-
long:
|
|
122
|
+
short: formatGregorian(date, locale, { weekday: 'short' }) ?? name,
|
|
123
|
+
long: formatGregorian(date, locale, { weekday: 'long' }) ?? name,
|
|
131
124
|
};
|
|
132
125
|
});
|
|
133
126
|
}
|
|
@@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
|
2
2
|
import { View, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { useControllableState } from '../hooks/use-controllable-state';
|
|
5
|
+
import { useMessages } from '../locale/messages';
|
|
5
6
|
import { adoptStyleSheet } from '../styles/adopt-style-sheet';
|
|
6
7
|
import { useTheme } from '../theme/use-theme';
|
|
7
8
|
import {
|
|
@@ -21,8 +22,15 @@ import {
|
|
|
21
22
|
type DayCellState,
|
|
22
23
|
} from './calendar-grid';
|
|
23
24
|
import { CALENDAR_CSS, CalendarMonth, dayKey } from './CalendarMonth';
|
|
25
|
+
import { DATE_PICKER_MESSAGES } from './messages';
|
|
24
26
|
import { resolveCalendarPalette } from './palette';
|
|
25
|
-
import type {
|
|
27
|
+
import type {
|
|
28
|
+
CalendarConstraintProps,
|
|
29
|
+
CalendarLabels,
|
|
30
|
+
CalendarProps,
|
|
31
|
+
DateRange,
|
|
32
|
+
RangeCalendarProps,
|
|
33
|
+
} from './types';
|
|
26
34
|
|
|
27
35
|
/**
|
|
28
36
|
* `Calendar` (one day) and `RangeCalendar` (a span of days): month panels
|
|
@@ -51,6 +59,7 @@ interface CalendarFrameProps extends CalendarConstraintProps {
|
|
|
51
59
|
/** The day under the pointer, or under keyboard focus. */
|
|
52
60
|
onPreviewDay?: (date: Date | null) => void;
|
|
53
61
|
accessibilityLabel?: string;
|
|
62
|
+
labels?: CalendarLabels;
|
|
54
63
|
style?: StyleProp<ViewStyle>;
|
|
55
64
|
testID?: string;
|
|
56
65
|
}
|
|
@@ -66,12 +75,16 @@ function CalendarFrame({
|
|
|
66
75
|
maxDate,
|
|
67
76
|
isDateUnavailable,
|
|
68
77
|
weekStartsOn = 0,
|
|
69
|
-
locale,
|
|
78
|
+
locale: localeProp,
|
|
70
79
|
accessibilityLabel,
|
|
80
|
+
labels,
|
|
71
81
|
style,
|
|
72
82
|
testID,
|
|
73
83
|
}: CalendarFrameProps) {
|
|
74
84
|
const theme = useTheme();
|
|
85
|
+
const { locale, messages } = useMessages(DATE_PICKER_MESSAGES, localeProp);
|
|
86
|
+
const previousLabel = labels?.previousMonth ?? messages.previousMonth;
|
|
87
|
+
const nextLabel = labels?.nextMonth ?? messages.nextMonth;
|
|
75
88
|
const palette = useMemo(() => resolveCalendarPalette(theme), [theme]);
|
|
76
89
|
const [firstMonth, setFirstMonth] = useState(() => startOfMonth(initialDate));
|
|
77
90
|
const [focusedDate, setFocusedDate] = useState(() => startOfDay(initialDate));
|
|
@@ -194,6 +207,8 @@ function CalendarFrame({
|
|
|
194
207
|
onKeyDown={onKeyDown}
|
|
195
208
|
registerNode={registerNode}
|
|
196
209
|
accessibilityLabel={accessibilityLabel}
|
|
210
|
+
previousLabel={previousLabel}
|
|
211
|
+
nextLabel={nextLabel}
|
|
197
212
|
testID={testID ? `${testID}-month-${index}` : undefined}
|
|
198
213
|
/>
|
|
199
214
|
))}
|
|
@@ -281,6 +281,9 @@ export interface CalendarMonthProps {
|
|
|
281
281
|
onKeyDown: (key: string, preventDefault: () => void) => void;
|
|
282
282
|
registerNode: (key: string, node: View | null) => void;
|
|
283
283
|
accessibilityLabel?: string;
|
|
284
|
+
/** The chevrons' names, already localised by the calendar. */
|
|
285
|
+
previousLabel: string;
|
|
286
|
+
nextLabel: string;
|
|
284
287
|
testID?: string;
|
|
285
288
|
}
|
|
286
289
|
|
|
@@ -308,6 +311,8 @@ export function CalendarMonth({
|
|
|
308
311
|
onKeyDown,
|
|
309
312
|
registerNode,
|
|
310
313
|
accessibilityLabel,
|
|
314
|
+
previousLabel,
|
|
315
|
+
nextLabel,
|
|
311
316
|
testID,
|
|
312
317
|
}: CalendarMonthProps) {
|
|
313
318
|
const title = formatMonthTitle(month, locale);
|
|
@@ -339,7 +344,7 @@ export function CalendarMonth({
|
|
|
339
344
|
{onPrevious ? (
|
|
340
345
|
<NavButton
|
|
341
346
|
direction="left"
|
|
342
|
-
label=
|
|
347
|
+
label={previousLabel}
|
|
343
348
|
onPress={onPrevious}
|
|
344
349
|
disabled={previousDisabled}
|
|
345
350
|
palette={palette}
|
|
@@ -356,7 +361,7 @@ export function CalendarMonth({
|
|
|
356
361
|
{onNext ? (
|
|
357
362
|
<NavButton
|
|
358
363
|
direction="right"
|
|
359
|
-
label=
|
|
364
|
+
label={nextLabel}
|
|
360
365
|
onPress={onNext}
|
|
361
366
|
disabled={nextDisabled}
|
|
362
367
|
palette={palette}
|
|
@@ -2,9 +2,11 @@ import React, { useState } from 'react';
|
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { useControllableState } from '../hooks/use-controllable-state';
|
|
5
|
+
import { useMessages } from '../locale/messages';
|
|
5
6
|
import { Calendar } from './Calendar';
|
|
6
7
|
import { formatTriggerDate } from './calendar-grid';
|
|
7
8
|
import { DateChipInput } from './DateChipInput';
|
|
9
|
+
import { DATE_PICKER_MESSAGES } from './messages';
|
|
8
10
|
import { PickerActions, PickerShell, usePickerPalette } from './PickerShell';
|
|
9
11
|
import { SummaryPresence } from './SummaryPresence';
|
|
10
12
|
import type { DatePickerProps } from './types';
|
|
@@ -27,8 +29,9 @@ export function DatePicker({
|
|
|
27
29
|
value,
|
|
28
30
|
defaultValue = null,
|
|
29
31
|
onChange,
|
|
30
|
-
placeholder
|
|
31
|
-
accessibilityLabel
|
|
32
|
+
placeholder: placeholderProp,
|
|
33
|
+
accessibilityLabel: accessibilityLabelProp,
|
|
34
|
+
labels,
|
|
32
35
|
disabled,
|
|
33
36
|
open: openProp,
|
|
34
37
|
defaultOpen = false,
|
|
@@ -37,11 +40,14 @@ export function DatePicker({
|
|
|
37
40
|
maxDate,
|
|
38
41
|
isDateUnavailable,
|
|
39
42
|
weekStartsOn,
|
|
40
|
-
locale,
|
|
43
|
+
locale: localeProp,
|
|
41
44
|
style,
|
|
42
45
|
testID,
|
|
43
46
|
}: DatePickerProps) {
|
|
44
47
|
const palette = usePickerPalette();
|
|
48
|
+
const { locale, messages } = useMessages(DATE_PICKER_MESSAGES, localeProp);
|
|
49
|
+
const placeholder = placeholderProp ?? messages.datePlaceholder;
|
|
50
|
+
const accessibilityLabel = accessibilityLabelProp ?? messages.dateLabel;
|
|
45
51
|
const [committed, setCommitted] = useControllableState<Date | null>({
|
|
46
52
|
value,
|
|
47
53
|
defaultValue,
|
|
@@ -91,6 +97,7 @@ export function DatePicker({
|
|
|
91
97
|
weekStartsOn={weekStartsOn}
|
|
92
98
|
locale={locale}
|
|
93
99
|
accessibilityLabel={accessibilityLabel}
|
|
100
|
+
labels={labels}
|
|
94
101
|
testID={testID ? `${testID}-calendar` : undefined}
|
|
95
102
|
/>
|
|
96
103
|
<View
|
|
@@ -126,6 +133,8 @@ export function DatePicker({
|
|
|
126
133
|
setOpenState(false);
|
|
127
134
|
}}
|
|
128
135
|
applyDisabled={!pending}
|
|
136
|
+
cancelLabel={labels?.cancel ?? messages.cancel}
|
|
137
|
+
applyLabel={labels?.apply ?? messages.apply}
|
|
129
138
|
testID={testID}
|
|
130
139
|
/>
|
|
131
140
|
</View>
|
|
@@ -2,6 +2,7 @@ import React, { useMemo, useState } from 'react';
|
|
|
2
2
|
import { Platform, Pressable, View, useWindowDimensions, type TextStyle } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { useControllableState } from '../hooks/use-controllable-state';
|
|
5
|
+
import { useMessages } from '../locale/messages';
|
|
5
6
|
import type { WebCssStyle } from '../styles/web-view-style';
|
|
6
7
|
import { Text, TYPE_SCALE } from '../typography';
|
|
7
8
|
import {
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
import { RangeCalendar } from './Calendar';
|
|
14
15
|
import { MONTH_PANEL_WIDTH } from './CalendarMonth';
|
|
15
16
|
import { DateChipInput } from './DateChipInput';
|
|
17
|
+
import { DATE_PICKER_MESSAGES } from './messages';
|
|
16
18
|
import type { CalendarPalette } from './palette';
|
|
17
19
|
import { PickerActions, PickerShell, usePickerPalette } from './PickerShell';
|
|
18
20
|
import { SummaryPresence } from './SummaryPresence';
|
|
@@ -85,9 +87,10 @@ export function DateRangePicker({
|
|
|
85
87
|
value,
|
|
86
88
|
defaultValue = null,
|
|
87
89
|
onChange,
|
|
88
|
-
placeholder
|
|
89
|
-
accessibilityLabel
|
|
90
|
+
placeholder: placeholderProp,
|
|
91
|
+
accessibilityLabel: accessibilityLabelProp,
|
|
90
92
|
quickSelect = true,
|
|
93
|
+
labels,
|
|
91
94
|
disabled,
|
|
92
95
|
open: openProp,
|
|
93
96
|
defaultOpen = false,
|
|
@@ -96,11 +99,14 @@ export function DateRangePicker({
|
|
|
96
99
|
maxDate,
|
|
97
100
|
isDateUnavailable,
|
|
98
101
|
weekStartsOn,
|
|
99
|
-
locale,
|
|
102
|
+
locale: localeProp,
|
|
100
103
|
style,
|
|
101
104
|
testID,
|
|
102
105
|
}: DateRangePickerProps) {
|
|
103
106
|
const palette = usePickerPalette();
|
|
107
|
+
const { locale, messages } = useMessages(DATE_PICKER_MESSAGES, localeProp);
|
|
108
|
+
const placeholder = placeholderProp ?? messages.rangePlaceholder;
|
|
109
|
+
const accessibilityLabel = accessibilityLabelProp ?? messages.rangeLabel;
|
|
104
110
|
const { width: windowWidth } = useWindowDimensions();
|
|
105
111
|
const [committed, setCommitted] = useControllableState<DateRange | null>({
|
|
106
112
|
value,
|
|
@@ -154,8 +160,8 @@ export function DateRangePicker({
|
|
|
154
160
|
<View style={{ width: 118, gap: 6 }}>
|
|
155
161
|
{presets.map((preset) => (
|
|
156
162
|
<PresetRow
|
|
157
|
-
key={preset.
|
|
158
|
-
label={preset.
|
|
163
|
+
key={preset.key}
|
|
164
|
+
label={labels?.presets?.[preset.key] ?? messages.presets[preset.key]}
|
|
159
165
|
active={isSameRange(pending, preset.range)}
|
|
160
166
|
onPress={() => choose(preset.range)}
|
|
161
167
|
palette={palette}
|
|
@@ -183,6 +189,7 @@ export function DateRangePicker({
|
|
|
183
189
|
weekStartsOn={weekStartsOn}
|
|
184
190
|
locale={locale}
|
|
185
191
|
accessibilityLabel={accessibilityLabel}
|
|
192
|
+
labels={labels}
|
|
186
193
|
testID={testID ? `${testID}-calendar` : undefined}
|
|
187
194
|
/>
|
|
188
195
|
<View
|
|
@@ -206,7 +213,7 @@ export function DateRangePicker({
|
|
|
206
213
|
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
|
|
207
214
|
<DateChipInput
|
|
208
215
|
date={pending.start}
|
|
209
|
-
label=
|
|
216
|
+
label={labels?.startDate ?? messages.startDate}
|
|
210
217
|
palette={palette}
|
|
211
218
|
onCommit={(start) =>
|
|
212
219
|
setPending({ start, end: start > pending.end ? start : pending.end })
|
|
@@ -215,7 +222,7 @@ export function DateRangePicker({
|
|
|
215
222
|
<Text style={{ ...BODY, color: palette.secondaryText }}>-</Text>
|
|
216
223
|
<DateChipInput
|
|
217
224
|
date={pending.end}
|
|
218
|
-
label=
|
|
225
|
+
label={labels?.endDate ?? messages.endDate}
|
|
219
226
|
palette={palette}
|
|
220
227
|
onCommit={(end) =>
|
|
221
228
|
setPending({ start: end < pending.start ? end : pending.start, end })
|
|
@@ -234,7 +241,7 @@ export function DateRangePicker({
|
|
|
234
241
|
}}
|
|
235
242
|
>
|
|
236
243
|
<Text style={{ ...BODY, color: palette.secondaryText }}>
|
|
237
|
-
{
|
|
244
|
+
{(labels?.daysSelected ?? messages.daysSelected)(days)}
|
|
238
245
|
</Text>
|
|
239
246
|
</View>
|
|
240
247
|
) : null}
|
|
@@ -252,6 +259,8 @@ export function DateRangePicker({
|
|
|
252
259
|
setOpenState(false);
|
|
253
260
|
}}
|
|
254
261
|
applyDisabled={!pending}
|
|
262
|
+
cancelLabel={labels?.cancel ?? messages.cancel}
|
|
263
|
+
applyLabel={labels?.apply ?? messages.apply}
|
|
255
264
|
testID={testID}
|
|
256
265
|
/>
|
|
257
266
|
</View>
|
|
@@ -16,11 +16,14 @@ import { useControllableState } from '../hooks/use-controllable-state';
|
|
|
16
16
|
import { RiFlagLine } from '../icons/remix/RiFlagLine';
|
|
17
17
|
import { RiGlobalLine } from '../icons/remix/RiGlobalLine';
|
|
18
18
|
import { RiVideoLine } from '../icons/remix/RiVideoLine';
|
|
19
|
+
import { formatGregorian } from '../locale/format-date';
|
|
20
|
+
import { useMessages } from '../locale/messages';
|
|
19
21
|
import type { WebCssStyle } from '../styles/web-view-style';
|
|
20
22
|
import { useTheme } from '../theme/use-theme';
|
|
21
23
|
import { Text, TYPE_SCALE } from '../typography';
|
|
22
24
|
import { Calendar } from './Calendar';
|
|
23
25
|
import { formatTriggerDate, today } from './calendar-grid';
|
|
26
|
+
import { DATE_PICKER_MESSAGES } from './messages';
|
|
24
27
|
import type { CalendarPalette } from './palette';
|
|
25
28
|
import { PickerShell, usePickerPalette } from './PickerShell';
|
|
26
29
|
import type {
|
|
@@ -95,11 +98,11 @@ function formatTime(time: string, format: MeetingSchedulerHourFormat): string {
|
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
function weekdayShort(date: Date, locale?: string): string {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
return (
|
|
102
|
+
formatGregorian(date, locale, { weekday: 'short' })?.slice(0, 2) ??
|
|
103
|
+
['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'][date.getDay()] ??
|
|
104
|
+
''
|
|
105
|
+
);
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
// ---------------------------------------------------------------------------
|
|
@@ -352,8 +355,8 @@ export function MeetingScheduler({
|
|
|
352
355
|
defaultValue,
|
|
353
356
|
onChange,
|
|
354
357
|
defaultHourFormat = '24h',
|
|
355
|
-
triggerLabel
|
|
356
|
-
accessibilityLabel
|
|
358
|
+
triggerLabel: triggerLabelProp,
|
|
359
|
+
accessibilityLabel: accessibilityLabelProp,
|
|
357
360
|
labels,
|
|
358
361
|
disabled,
|
|
359
362
|
open: openProp,
|
|
@@ -363,11 +366,14 @@ export function MeetingScheduler({
|
|
|
363
366
|
maxDate,
|
|
364
367
|
isDateUnavailable,
|
|
365
368
|
weekStartsOn,
|
|
366
|
-
locale,
|
|
369
|
+
locale: localeProp,
|
|
367
370
|
style,
|
|
368
371
|
testID,
|
|
369
372
|
}: MeetingSchedulerProps) {
|
|
370
373
|
const theme = useTheme();
|
|
374
|
+
const { locale, messages } = useMessages(DATE_PICKER_MESSAGES, localeProp);
|
|
375
|
+
const triggerLabel = triggerLabelProp ?? messages.meetingTrigger;
|
|
376
|
+
const accessibilityLabel = accessibilityLabelProp ?? messages.meetingLabel;
|
|
371
377
|
const palette = usePickerPalette();
|
|
372
378
|
const { width: windowWidth } = useWindowDimensions();
|
|
373
379
|
const slots = useMemo(() => timeSlots ?? defaultTimeSlots(), [timeSlots]);
|
|
@@ -397,8 +403,8 @@ export function MeetingScheduler({
|
|
|
397
403
|
|
|
398
404
|
const wide = windowWidth >= WIDE_WIDTH + 32;
|
|
399
405
|
const shadow2xs = theme.isDark ? SHADOW_2XS.dark : SHADOW_2XS.light;
|
|
400
|
-
const sendLabel = labels?.send ??
|
|
401
|
-
const durationText = (labels?.duration ??
|
|
406
|
+
const sendLabel = labels?.send ?? messages.send;
|
|
407
|
+
const durationText = (labels?.duration ?? messages.duration)(meeting.durationMinutes);
|
|
402
408
|
const chevron = useMemo(() => ({ open, color: palette.secondaryText }), [open, palette.secondaryText]);
|
|
403
409
|
|
|
404
410
|
const hostColumn = (
|
|
@@ -469,6 +475,7 @@ export function MeetingScheduler({
|
|
|
469
475
|
weekStartsOn={weekStartsOn}
|
|
470
476
|
locale={locale}
|
|
471
477
|
accessibilityLabel={accessibilityLabel}
|
|
478
|
+
labels={labels}
|
|
472
479
|
testID={testID ? `${testID}-calendar` : undefined}
|
|
473
480
|
/>
|
|
474
481
|
<View
|
|
@@ -504,7 +511,7 @@ export function MeetingScheduler({
|
|
|
504
511
|
{formatTriggerDate(pending.date, locale)}
|
|
505
512
|
</Text>
|
|
506
513
|
<Text style={[BODY_MEDIUM, { color: palette.secondaryText }]}>
|
|
507
|
-
{pending.time ?? labels?.selectTime ??
|
|
514
|
+
{pending.time ?? labels?.selectTime ?? messages.selectTime}
|
|
508
515
|
</Text>
|
|
509
516
|
</>
|
|
510
517
|
) : null}
|
|
@@ -99,20 +99,24 @@ export function PickerActions({
|
|
|
99
99
|
onCancel,
|
|
100
100
|
onApply,
|
|
101
101
|
applyDisabled,
|
|
102
|
+
cancelLabel,
|
|
103
|
+
applyLabel,
|
|
102
104
|
testID,
|
|
103
105
|
}: {
|
|
104
106
|
onCancel: () => void;
|
|
105
107
|
onApply: () => void;
|
|
106
108
|
applyDisabled: boolean;
|
|
109
|
+
cancelLabel: string;
|
|
110
|
+
applyLabel: string;
|
|
107
111
|
testID?: string;
|
|
108
112
|
}) {
|
|
109
113
|
return (
|
|
110
114
|
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10 }}>
|
|
111
115
|
<Button onPress={onCancel} testID={testID ? `${testID}-cancel` : undefined} appearance="subtle" tone="neutral">
|
|
112
|
-
|
|
116
|
+
{cancelLabel}
|
|
113
117
|
</Button>
|
|
114
118
|
<Button onPress={onApply} disabled={applyDisabled} testID={testID ? `${testID}-apply` : undefined}>
|
|
115
|
-
|
|
119
|
+
{applyLabel}
|
|
116
120
|
</Button>
|
|
117
121
|
</View>
|
|
118
122
|
);
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* internal state. The time of day on an input is ignored.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import type { DateRange, WeekStart } from './types';
|
|
13
|
+
import type { DateRange, DateRangePreset, WeekStart } from './types';
|
|
14
|
+
import { formatGregorian } from '../locale/format-date';
|
|
14
15
|
|
|
15
16
|
const MS_PER_DAY = 86_400_000;
|
|
16
17
|
|
|
@@ -130,37 +131,29 @@ export function weekdayLabels(
|
|
|
130
131
|
const sunday = new Date(2023, 0, 1);
|
|
131
132
|
return Array.from({ length: 7 }, (_, column) => {
|
|
132
133
|
const date = addDays(sunday, (weekStartsOn + column) % 7);
|
|
133
|
-
const long =
|
|
134
|
-
const short =
|
|
134
|
+
const long = formatGregorian(date, locale, { weekday: 'long' }) ?? FALLBACK_WEEKDAYS[date.getDay()]!;
|
|
135
|
+
const short = formatGregorian(date, locale, { weekday: 'short' }) ?? long;
|
|
135
136
|
return { short: short.slice(0, 2), long };
|
|
136
137
|
});
|
|
137
138
|
}
|
|
138
139
|
|
|
139
|
-
function format(date: Date, locale: string | undefined, options: Intl.DateTimeFormatOptions): string | null {
|
|
140
|
-
try {
|
|
141
|
-
return new Intl.DateTimeFormat(locale, options).format(date);
|
|
142
|
-
} catch {
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
140
|
/** `September 2026` — the month panel's title. */
|
|
148
141
|
export function formatMonthTitle(month: Date, locale?: string): string {
|
|
149
142
|
return (
|
|
150
|
-
|
|
143
|
+
formatGregorian(month, locale, { month: 'long', year: 'numeric' }) ??
|
|
151
144
|
`${month.getMonth() + 1}/${month.getFullYear()}`
|
|
152
145
|
);
|
|
153
146
|
}
|
|
154
147
|
|
|
155
148
|
/** `Sep 16, 2026` — the trigger's label. */
|
|
156
149
|
export function formatTriggerDate(date: Date, locale?: string): string {
|
|
157
|
-
return
|
|
150
|
+
return formatGregorian(date, locale, { month: 'short', day: 'numeric', year: 'numeric' }) ?? formatChipDate(date);
|
|
158
151
|
}
|
|
159
152
|
|
|
160
153
|
/** `Wednesday, September 16, 2026` — a day button's accessible name. */
|
|
161
154
|
export function formatAccessibleDate(date: Date, locale?: string): string {
|
|
162
155
|
return (
|
|
163
|
-
|
|
156
|
+
formatGregorian(date, locale, { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' }) ??
|
|
164
157
|
formatChipDate(date)
|
|
165
158
|
);
|
|
166
159
|
}
|
|
@@ -334,20 +327,22 @@ export function clampDate(date: Date, { minDate, maxDate }: DateConstraints): Da
|
|
|
334
327
|
return startOfDay(date);
|
|
335
328
|
}
|
|
336
329
|
|
|
337
|
-
/** Quick-select presets, relative to `now`. */
|
|
338
|
-
export function quickSelectPresets(
|
|
330
|
+
/** Quick-select presets, relative to `now`. Their names are `DatePickerMessages.presets`. */
|
|
331
|
+
export function quickSelectPresets(
|
|
332
|
+
now: Date = today(),
|
|
333
|
+
): { key: DateRangePreset; range: DateRange }[] {
|
|
339
334
|
const lastMonth = addMonths(now, -1);
|
|
340
335
|
const lastYear = new Date(now.getFullYear() - 1, now.getMonth(), 1);
|
|
341
336
|
const yesterday = addDays(now, -1);
|
|
342
337
|
return [
|
|
343
|
-
{
|
|
344
|
-
{
|
|
345
|
-
{
|
|
346
|
-
{
|
|
347
|
-
{
|
|
348
|
-
{
|
|
349
|
-
{
|
|
350
|
-
{
|
|
338
|
+
{ key: 'today', range: { start: now, end: now } },
|
|
339
|
+
{ key: 'yesterday', range: { start: yesterday, end: yesterday } },
|
|
340
|
+
{ key: 'lastWeek', range: { start: addDays(now, -7), end: yesterday } },
|
|
341
|
+
{ key: 'thisMonth', range: { start: startOfMonth(now), end: endOfMonth(now) } },
|
|
342
|
+
{ key: 'lastMonth', range: { start: startOfMonth(lastMonth), end: endOfMonth(lastMonth) } },
|
|
343
|
+
{ key: 'thisYear', range: { start: startOfYear(now), end: endOfYear(now) } },
|
|
344
|
+
{ key: 'lastYear', range: { start: startOfYear(lastYear), end: endOfYear(lastYear) } },
|
|
345
|
+
{ key: 'allTime', range: { start: addMonths(now, -120), end: now } },
|
|
351
346
|
];
|
|
352
347
|
}
|
|
353
348
|
|
package/src/date-picker/index.ts
CHANGED
|
@@ -8,10 +8,14 @@ export { TimeField } from './TimeField';
|
|
|
8
8
|
|
|
9
9
|
export type {
|
|
10
10
|
CalendarConstraintProps,
|
|
11
|
+
CalendarLabels,
|
|
11
12
|
CalendarProps,
|
|
13
|
+
DatePickerLabels,
|
|
12
14
|
DatePickerProps,
|
|
13
15
|
DateRange,
|
|
16
|
+
DateRangePickerLabels,
|
|
14
17
|
DateRangePickerProps,
|
|
18
|
+
DateRangePreset,
|
|
15
19
|
HourFormat,
|
|
16
20
|
MeetingSchedulerDetails,
|
|
17
21
|
MeetingSchedulerHost,
|