@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.
Files changed (190) hide show
  1. package/docs/adoption-matrix.mdx +4 -3
  2. package/docs/date-picker.mdx +24 -0
  3. package/docs/locale.mdx +46 -0
  4. package/docs/provider.mdx +11 -0
  5. package/lib/commonjs/calendar/shared.js +5 -11
  6. package/lib/commonjs/calendar/shared.js.map +1 -1
  7. package/lib/commonjs/date-picker/Calendar.js +12 -1
  8. package/lib/commonjs/date-picker/Calendar.js.map +1 -1
  9. package/lib/commonjs/date-picker/CalendarMonth.js +4 -2
  10. package/lib/commonjs/date-picker/CalendarMonth.js.map +1 -1
  11. package/lib/commonjs/date-picker/DatePicker.js +15 -3
  12. package/lib/commonjs/date-picker/DatePicker.js.map +1 -1
  13. package/lib/commonjs/date-picker/DateRangePicker.js +21 -9
  14. package/lib/commonjs/date-picker/DateRangePicker.js.map +1 -1
  15. package/lib/commonjs/date-picker/MeetingScheduler.js +19 -13
  16. package/lib/commonjs/date-picker/MeetingScheduler.js.map +1 -1
  17. package/lib/commonjs/date-picker/PickerShell.js +4 -2
  18. package/lib/commonjs/date-picker/PickerShell.js.map +1 -1
  19. package/lib/commonjs/date-picker/calendar-grid.js +15 -21
  20. package/lib/commonjs/date-picker/calendar-grid.js.map +1 -1
  21. package/lib/commonjs/date-picker/messages.js +526 -0
  22. package/lib/commonjs/date-picker/messages.js.map +1 -0
  23. package/lib/commonjs/index.js +1063 -1034
  24. package/lib/commonjs/index.js.map +1 -1
  25. package/lib/commonjs/index.web.js +1063 -1034
  26. package/lib/commonjs/index.web.js.map +1 -1
  27. package/lib/commonjs/locale/context.js +35 -0
  28. package/lib/commonjs/locale/context.js.map +1 -0
  29. package/lib/commonjs/locale/format-date.js +34 -0
  30. package/lib/commonjs/locale/format-date.js.map +1 -0
  31. package/lib/commonjs/locale/index.js +32 -0
  32. package/lib/commonjs/locale/index.js.map +1 -0
  33. package/lib/commonjs/locale/languages.js +35 -0
  34. package/lib/commonjs/locale/languages.js.map +1 -0
  35. package/lib/commonjs/locale/messages.js +34 -0
  36. package/lib/commonjs/locale/messages.js.map +1 -0
  37. package/lib/commonjs/locale/plural.js +53 -0
  38. package/lib/commonjs/locale/plural.js.map +1 -0
  39. package/lib/commonjs/provider/BloomProvider.js +18 -13
  40. package/lib/commonjs/provider/BloomProvider.js.map +1 -1
  41. package/lib/module/calendar/shared.js +5 -11
  42. package/lib/module/calendar/shared.js.map +1 -1
  43. package/lib/module/date-picker/Calendar.js +12 -1
  44. package/lib/module/date-picker/Calendar.js.map +1 -1
  45. package/lib/module/date-picker/CalendarMonth.js +4 -2
  46. package/lib/module/date-picker/CalendarMonth.js.map +1 -1
  47. package/lib/module/date-picker/DatePicker.js +15 -3
  48. package/lib/module/date-picker/DatePicker.js.map +1 -1
  49. package/lib/module/date-picker/DateRangePicker.js +21 -9
  50. package/lib/module/date-picker/DateRangePicker.js.map +1 -1
  51. package/lib/module/date-picker/MeetingScheduler.js +19 -13
  52. package/lib/module/date-picker/MeetingScheduler.js.map +1 -1
  53. package/lib/module/date-picker/PickerShell.js +4 -2
  54. package/lib/module/date-picker/PickerShell.js.map +1 -1
  55. package/lib/module/date-picker/calendar-grid.js +15 -21
  56. package/lib/module/date-picker/calendar-grid.js.map +1 -1
  57. package/lib/module/date-picker/messages.js +523 -0
  58. package/lib/module/date-picker/messages.js.map +1 -0
  59. package/lib/module/index.js +1 -0
  60. package/lib/module/index.js.map +1 -1
  61. package/lib/module/index.web.js +1 -0
  62. package/lib/module/index.web.js.map +1 -1
  63. package/lib/module/locale/context.js +30 -0
  64. package/lib/module/locale/context.js.map +1 -0
  65. package/lib/module/locale/format-date.js +30 -0
  66. package/lib/module/locale/format-date.js.map +1 -0
  67. package/lib/module/locale/index.js +7 -0
  68. package/lib/module/locale/index.js.map +1 -0
  69. package/lib/module/locale/languages.js +29 -0
  70. package/lib/module/locale/languages.js.map +1 -0
  71. package/lib/module/locale/messages.js +30 -0
  72. package/lib/module/locale/messages.js.map +1 -0
  73. package/lib/module/locale/plural.js +48 -0
  74. package/lib/module/locale/plural.js.map +1 -0
  75. package/lib/module/provider/BloomProvider.js +16 -11
  76. package/lib/module/provider/BloomProvider.js.map +1 -1
  77. package/lib/typescript/commonjs/calendar/shared.d.ts.map +1 -1
  78. package/lib/typescript/commonjs/date-picker/Calendar.d.ts.map +1 -1
  79. package/lib/typescript/commonjs/date-picker/CalendarMonth.d.ts +4 -1
  80. package/lib/typescript/commonjs/date-picker/CalendarMonth.d.ts.map +1 -1
  81. package/lib/typescript/commonjs/date-picker/DatePicker.d.ts +1 -1
  82. package/lib/typescript/commonjs/date-picker/DatePicker.d.ts.map +1 -1
  83. package/lib/typescript/commonjs/date-picker/DateRangePicker.d.ts +1 -1
  84. package/lib/typescript/commonjs/date-picker/DateRangePicker.d.ts.map +1 -1
  85. package/lib/typescript/commonjs/date-picker/MeetingScheduler.d.ts +1 -1
  86. package/lib/typescript/commonjs/date-picker/MeetingScheduler.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/date-picker/PickerShell.d.ts +3 -1
  88. package/lib/typescript/commonjs/date-picker/PickerShell.d.ts.map +1 -1
  89. package/lib/typescript/commonjs/date-picker/calendar-grid.d.ts +3 -3
  90. package/lib/typescript/commonjs/date-picker/calendar-grid.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/date-picker/index.d.ts +1 -1
  92. package/lib/typescript/commonjs/date-picker/index.d.ts.map +1 -1
  93. package/lib/typescript/commonjs/date-picker/messages.d.ts +31 -0
  94. package/lib/typescript/commonjs/date-picker/messages.d.ts.map +1 -0
  95. package/lib/typescript/commonjs/date-picker/types.d.ts +54 -12
  96. package/lib/typescript/commonjs/date-picker/types.d.ts.map +1 -1
  97. package/lib/typescript/commonjs/index.d.ts +2 -0
  98. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  99. package/lib/typescript/commonjs/index.web.d.ts +2 -0
  100. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  101. package/lib/typescript/commonjs/locale/context.d.ts +18 -0
  102. package/lib/typescript/commonjs/locale/context.d.ts.map +1 -0
  103. package/lib/typescript/commonjs/locale/format-date.d.ts +13 -0
  104. package/lib/typescript/commonjs/locale/format-date.d.ts.map +1 -0
  105. package/lib/typescript/commonjs/locale/index.d.ts +3 -0
  106. package/lib/typescript/commonjs/locale/index.d.ts.map +1 -0
  107. package/lib/typescript/commonjs/locale/languages.d.ts +16 -0
  108. package/lib/typescript/commonjs/locale/languages.d.ts.map +1 -0
  109. package/lib/typescript/commonjs/locale/messages.d.ts +18 -0
  110. package/lib/typescript/commonjs/locale/messages.d.ts.map +1 -0
  111. package/lib/typescript/commonjs/locale/plural.d.ts +19 -0
  112. package/lib/typescript/commonjs/locale/plural.d.ts.map +1 -0
  113. package/lib/typescript/commonjs/provider/BloomProvider.d.ts +1 -1
  114. package/lib/typescript/commonjs/provider/BloomProvider.d.ts.map +1 -1
  115. package/lib/typescript/commonjs/provider/types.d.ts +6 -0
  116. package/lib/typescript/commonjs/provider/types.d.ts.map +1 -1
  117. package/lib/typescript/module/calendar/shared.d.ts.map +1 -1
  118. package/lib/typescript/module/date-picker/Calendar.d.ts.map +1 -1
  119. package/lib/typescript/module/date-picker/CalendarMonth.d.ts +4 -1
  120. package/lib/typescript/module/date-picker/CalendarMonth.d.ts.map +1 -1
  121. package/lib/typescript/module/date-picker/DatePicker.d.ts +1 -1
  122. package/lib/typescript/module/date-picker/DatePicker.d.ts.map +1 -1
  123. package/lib/typescript/module/date-picker/DateRangePicker.d.ts +1 -1
  124. package/lib/typescript/module/date-picker/DateRangePicker.d.ts.map +1 -1
  125. package/lib/typescript/module/date-picker/MeetingScheduler.d.ts +1 -1
  126. package/lib/typescript/module/date-picker/MeetingScheduler.d.ts.map +1 -1
  127. package/lib/typescript/module/date-picker/PickerShell.d.ts +3 -1
  128. package/lib/typescript/module/date-picker/PickerShell.d.ts.map +1 -1
  129. package/lib/typescript/module/date-picker/calendar-grid.d.ts +3 -3
  130. package/lib/typescript/module/date-picker/calendar-grid.d.ts.map +1 -1
  131. package/lib/typescript/module/date-picker/index.d.ts +1 -1
  132. package/lib/typescript/module/date-picker/index.d.ts.map +1 -1
  133. package/lib/typescript/module/date-picker/messages.d.ts +31 -0
  134. package/lib/typescript/module/date-picker/messages.d.ts.map +1 -0
  135. package/lib/typescript/module/date-picker/types.d.ts +54 -12
  136. package/lib/typescript/module/date-picker/types.d.ts.map +1 -1
  137. package/lib/typescript/module/index.d.ts +2 -0
  138. package/lib/typescript/module/index.d.ts.map +1 -1
  139. package/lib/typescript/module/index.web.d.ts +2 -0
  140. package/lib/typescript/module/index.web.d.ts.map +1 -1
  141. package/lib/typescript/module/locale/context.d.ts +18 -0
  142. package/lib/typescript/module/locale/context.d.ts.map +1 -0
  143. package/lib/typescript/module/locale/format-date.d.ts +13 -0
  144. package/lib/typescript/module/locale/format-date.d.ts.map +1 -0
  145. package/lib/typescript/module/locale/index.d.ts +3 -0
  146. package/lib/typescript/module/locale/index.d.ts.map +1 -0
  147. package/lib/typescript/module/locale/languages.d.ts +16 -0
  148. package/lib/typescript/module/locale/languages.d.ts.map +1 -0
  149. package/lib/typescript/module/locale/messages.d.ts +18 -0
  150. package/lib/typescript/module/locale/messages.d.ts.map +1 -0
  151. package/lib/typescript/module/locale/plural.d.ts +19 -0
  152. package/lib/typescript/module/locale/plural.d.ts.map +1 -0
  153. package/lib/typescript/module/provider/BloomProvider.d.ts +1 -1
  154. package/lib/typescript/module/provider/BloomProvider.d.ts.map +1 -1
  155. package/lib/typescript/module/provider/types.d.ts +6 -0
  156. package/lib/typescript/module/provider/types.d.ts.map +1 -1
  157. package/package.json +18 -1
  158. package/src/calendar/shared.ts +5 -12
  159. package/src/date-picker/Calendar.tsx +17 -2
  160. package/src/date-picker/CalendarMonth.tsx +7 -2
  161. package/src/date-picker/DatePicker.tsx +12 -3
  162. package/src/date-picker/DateRangePicker.tsx +17 -8
  163. package/src/date-picker/MeetingScheduler.tsx +18 -11
  164. package/src/date-picker/PickerShell.tsx +6 -2
  165. package/src/date-picker/calendar-grid.ts +19 -24
  166. package/src/date-picker/index.ts +4 -0
  167. package/src/date-picker/messages.ts +470 -0
  168. package/src/date-picker/types.ts +66 -12
  169. package/src/index.ts +2 -0
  170. package/src/index.web.ts +2 -0
  171. package/src/locale/context.ts +23 -0
  172. package/src/locale/format-date.ts +28 -0
  173. package/src/locale/index.ts +4 -0
  174. package/src/locale/languages.ts +45 -0
  175. package/src/locale/messages.ts +29 -0
  176. package/src/locale/plural.ts +53 -0
  177. package/src/provider/BloomProvider.tsx +39 -35
  178. package/src/provider/types.ts +6 -0
  179. package/src/__tests__/support/adoption-matrix.ts +0 -708
  180. package/src/__tests__/support/collision-fixture-barrel.ts +0 -20
  181. package/src/__tests__/support/commerce-harness.tsx +0 -97
  182. package/src/__tests__/support/composite.ts +0 -68
  183. package/src/__tests__/support/constructed-style-sheets.ts +0 -68
  184. package/src/__tests__/support/press-host.ts +0 -30
  185. package/src/__tests__/support/rendered-style.ts +0 -99
  186. package/src/__tests__/support/unread-hook-fixture.ts +0 -33
  187. package/src/__tests__/support/worklet-capture-fixture.tsx +0 -28
  188. package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +0 -9346
  189. package/src/theme/__tests__/__fixtures__/tonal-glass-primary-failures.json +0 -69
  190. package/src/theme/__tests__/fixtures/color-engine-golden.json +0 -1
@@ -0,0 +1,470 @@
1
+ import type { MessageCatalog } from '../locale/messages';
2
+ import { plural } from '../locale/plural';
3
+ import type { DateRangePreset } from './types';
4
+
5
+ /**
6
+ * Every fixed string the date-picker family draws or announces, in each Bloom
7
+ * language. Month titles, weekday names and dates come from `Intl` instead; a
8
+ * caller's `labels` prop still wins over any entry here.
9
+ */
10
+ export interface DatePickerMessages {
11
+ cancel: string;
12
+ apply: string;
13
+ previousMonth: string;
14
+ nextMonth: string;
15
+ /** `DatePicker`'s empty trigger and its name. */
16
+ datePlaceholder: string;
17
+ dateLabel: string;
18
+ /** `DateRangePicker`'s empty trigger and its name. */
19
+ rangePlaceholder: string;
20
+ rangeLabel: string;
21
+ startDate: string;
22
+ endDate: string;
23
+ daysSelected: (days: number) => string;
24
+ presets: Record<DateRangePreset, string>;
25
+ /** `MeetingScheduler`'s trigger, its name, its commit button and its empty time chip. */
26
+ meetingTrigger: string;
27
+ meetingLabel: string;
28
+ send: string;
29
+ selectTime: string;
30
+ duration: (minutes: number) => string;
31
+ }
32
+
33
+ export const DATE_PICKER_MESSAGES: MessageCatalog<DatePickerMessages> = {
34
+ en: {
35
+ cancel: 'Cancel',
36
+ apply: 'Apply',
37
+ previousMonth: 'Previous month',
38
+ nextMonth: 'Next month',
39
+ datePlaceholder: 'Select date',
40
+ dateLabel: 'Date',
41
+ rangePlaceholder: 'Select date range',
42
+ rangeLabel: 'Date range',
43
+ startDate: 'Start date',
44
+ endDate: 'End date',
45
+ daysSelected: (n) => plural('en', n, { one: '{n} day selected', other: '{n} days selected' }),
46
+ presets: {
47
+ today: 'Today',
48
+ yesterday: 'Yesterday',
49
+ lastWeek: 'Last week',
50
+ thisMonth: 'This month',
51
+ lastMonth: 'Last month',
52
+ thisYear: 'This year',
53
+ lastYear: 'Last year',
54
+ allTime: 'All time',
55
+ },
56
+ meetingTrigger: 'Schedule a meeting',
57
+ meetingLabel: 'Schedule meeting',
58
+ send: 'Send meeting',
59
+ selectTime: 'Select a time',
60
+ duration: (n) => plural('en', n, { one: '{n} minute', other: '{n} minutes' }),
61
+ },
62
+ es: {
63
+ cancel: 'Cancelar',
64
+ apply: 'Aplicar',
65
+ previousMonth: 'Mes anterior',
66
+ nextMonth: 'Mes siguiente',
67
+ datePlaceholder: 'Seleccionar fecha',
68
+ dateLabel: 'Fecha',
69
+ rangePlaceholder: 'Seleccionar intervalo de fechas',
70
+ rangeLabel: 'Intervalo de fechas',
71
+ startDate: 'Fecha de inicio',
72
+ endDate: 'Fecha de fin',
73
+ daysSelected: (n) => plural('es', n, { one: '{n} día seleccionado', other: '{n} días seleccionados' }),
74
+ presets: {
75
+ today: 'Hoy',
76
+ yesterday: 'Ayer',
77
+ lastWeek: 'La semana pasada',
78
+ thisMonth: 'Este mes',
79
+ lastMonth: 'El mes pasado',
80
+ thisYear: 'Este año',
81
+ lastYear: 'El año pasado',
82
+ allTime: 'Todo',
83
+ },
84
+ meetingTrigger: 'Programar una reunión',
85
+ meetingLabel: 'Programar reunión',
86
+ send: 'Enviar invitación',
87
+ selectTime: 'Seleccionar hora',
88
+ duration: (n) => plural('es', n, { one: '{n} minuto', other: '{n} minutos' }),
89
+ },
90
+ ca: {
91
+ cancel: 'Cancel·la',
92
+ apply: 'Aplica',
93
+ previousMonth: 'Mes anterior',
94
+ nextMonth: 'Mes següent',
95
+ datePlaceholder: 'Selecciona una data',
96
+ dateLabel: 'Data',
97
+ rangePlaceholder: 'Selecciona un interval de dates',
98
+ rangeLabel: 'Interval de dates',
99
+ startDate: "Data d'inici",
100
+ endDate: 'Data de fi',
101
+ daysSelected: (n) => plural('ca', n, { one: '{n} dia seleccionat', other: '{n} dies seleccionats' }),
102
+ presets: {
103
+ today: 'Avui',
104
+ yesterday: 'Ahir',
105
+ lastWeek: 'La setmana passada',
106
+ thisMonth: 'Aquest mes',
107
+ lastMonth: 'El mes passat',
108
+ thisYear: 'Aquest any',
109
+ lastYear: "L'any passat",
110
+ allTime: 'Tot',
111
+ },
112
+ meetingTrigger: 'Programa una reunió',
113
+ meetingLabel: 'Programar reunió',
114
+ send: 'Envia la invitació',
115
+ selectTime: 'Selecciona una hora',
116
+ duration: (n) => plural('ca', n, { one: '{n} minut', other: '{n} minuts' }),
117
+ },
118
+ de: {
119
+ cancel: 'Abbrechen',
120
+ apply: 'Übernehmen',
121
+ previousMonth: 'Vorheriger Monat',
122
+ nextMonth: 'Nächster Monat',
123
+ datePlaceholder: 'Datum auswählen',
124
+ dateLabel: 'Datum',
125
+ rangePlaceholder: 'Zeitraum auswählen',
126
+ rangeLabel: 'Zeitraum',
127
+ startDate: 'Startdatum',
128
+ endDate: 'Enddatum',
129
+ daysSelected: (n) => plural('de', n, { one: '{n} Tag ausgewählt', other: '{n} Tage ausgewählt' }),
130
+ presets: {
131
+ today: 'Heute',
132
+ yesterday: 'Gestern',
133
+ lastWeek: 'Letzte Woche',
134
+ thisMonth: 'Dieser Monat',
135
+ lastMonth: 'Letzter Monat',
136
+ thisYear: 'Dieses Jahr',
137
+ lastYear: 'Letztes Jahr',
138
+ allTime: 'Gesamter Zeitraum',
139
+ },
140
+ meetingTrigger: 'Meeting planen',
141
+ meetingLabel: 'Meeting planen',
142
+ send: 'Einladung senden',
143
+ selectTime: 'Uhrzeit auswählen',
144
+ duration: (n) => plural('de', n, { one: '{n} Minute', other: '{n} Minuten' }),
145
+ },
146
+ fr: {
147
+ cancel: 'Annuler',
148
+ apply: 'Appliquer',
149
+ previousMonth: 'Mois précédent',
150
+ nextMonth: 'Mois suivant',
151
+ datePlaceholder: 'Sélectionner une date',
152
+ dateLabel: 'Date',
153
+ rangePlaceholder: 'Sélectionner une période',
154
+ rangeLabel: 'Période',
155
+ startDate: 'Date de début',
156
+ endDate: 'Date de fin',
157
+ daysSelected: (n) => plural('fr', n, { one: '{n} jour sélectionné', other: '{n} jours sélectionnés' }),
158
+ presets: {
159
+ today: "Aujourd'hui",
160
+ yesterday: 'Hier',
161
+ lastWeek: 'La semaine dernière',
162
+ thisMonth: 'Ce mois-ci',
163
+ lastMonth: 'Le mois dernier',
164
+ thisYear: 'Cette année',
165
+ lastYear: "L'année dernière",
166
+ allTime: 'Depuis toujours',
167
+ },
168
+ meetingTrigger: 'Planifier une réunion',
169
+ meetingLabel: 'Planifier une réunion',
170
+ send: "Envoyer l'invitation",
171
+ selectTime: 'Sélectionner une heure',
172
+ duration: (n) => plural('fr', n, { one: '{n} minute', other: '{n} minutes' }),
173
+ },
174
+ it: {
175
+ cancel: 'Annulla',
176
+ apply: 'Applica',
177
+ previousMonth: 'Mese precedente',
178
+ nextMonth: 'Mese successivo',
179
+ datePlaceholder: 'Seleziona una data',
180
+ dateLabel: 'Data',
181
+ rangePlaceholder: 'Seleziona un intervallo di date',
182
+ rangeLabel: 'Intervallo di date',
183
+ startDate: 'Data di inizio',
184
+ endDate: 'Data di fine',
185
+ daysSelected: (n) => plural('it', n, { one: '{n} giorno selezionato', other: '{n} giorni selezionati' }),
186
+ presets: {
187
+ today: 'Oggi',
188
+ yesterday: 'Ieri',
189
+ lastWeek: 'Settimana scorsa',
190
+ thisMonth: 'Questo mese',
191
+ lastMonth: 'Mese scorso',
192
+ thisYear: "Quest'anno",
193
+ lastYear: 'Anno scorso',
194
+ allTime: 'Sempre',
195
+ },
196
+ meetingTrigger: 'Pianifica una riunione',
197
+ meetingLabel: 'Pianifica riunione',
198
+ send: 'Invia invito',
199
+ selectTime: 'Seleziona un orario',
200
+ duration: (n) => plural('it', n, { one: '{n} minuto', other: '{n} minuti' }),
201
+ },
202
+ pt: {
203
+ cancel: 'Cancelar',
204
+ apply: 'Aplicar',
205
+ previousMonth: 'Mês anterior',
206
+ nextMonth: 'Próximo mês',
207
+ datePlaceholder: 'Selecionar data',
208
+ dateLabel: 'Data',
209
+ rangePlaceholder: 'Selecionar período',
210
+ rangeLabel: 'Período',
211
+ startDate: 'Data de início',
212
+ endDate: 'Data de término',
213
+ daysSelected: (n) => plural('pt', n, { one: '{n} dia selecionado', other: '{n} dias selecionados' }),
214
+ presets: {
215
+ today: 'Hoje',
216
+ yesterday: 'Ontem',
217
+ lastWeek: 'Semana passada',
218
+ thisMonth: 'Este mês',
219
+ lastMonth: 'Mês passado',
220
+ thisYear: 'Este ano',
221
+ lastYear: 'Ano passado',
222
+ allTime: 'Todo o período',
223
+ },
224
+ meetingTrigger: 'Agendar uma reunião',
225
+ meetingLabel: 'Agendar reunião',
226
+ send: 'Enviar convite',
227
+ selectTime: 'Selecionar horário',
228
+ duration: (n) => plural('pt', n, { one: '{n} minuto', other: '{n} minutos' }),
229
+ },
230
+ ru: {
231
+ cancel: 'Отмена',
232
+ apply: 'Применить',
233
+ previousMonth: 'Предыдущий месяц',
234
+ nextMonth: 'Следующий месяц',
235
+ datePlaceholder: 'Выберите дату',
236
+ dateLabel: 'Дата',
237
+ rangePlaceholder: 'Выберите период',
238
+ rangeLabel: 'Период',
239
+ startDate: 'Дата начала',
240
+ endDate: 'Дата окончания',
241
+ daysSelected: (n) =>
242
+ plural('ru', n, { one: 'Выбран {n} день', few: 'Выбрано {n} дня', many: 'Выбрано {n} дней', other: 'Выбрано {n} дня' }),
243
+ presets: {
244
+ today: 'Сегодня',
245
+ yesterday: 'Вчера',
246
+ lastWeek: 'Прошлая неделя',
247
+ thisMonth: 'Этот месяц',
248
+ lastMonth: 'Прошлый месяц',
249
+ thisYear: 'Этот год',
250
+ lastYear: 'Прошлый год',
251
+ allTime: 'Всё время',
252
+ },
253
+ meetingTrigger: 'Запланировать встречу',
254
+ meetingLabel: 'Запланировать встречу',
255
+ send: 'Отправить приглашение',
256
+ selectTime: 'Выберите время',
257
+ duration: (n) => plural('ru', n, { one: '{n} минута', few: '{n} минуты', many: '{n} минут', other: '{n} минуты' }),
258
+ },
259
+ tr: {
260
+ cancel: 'İptal',
261
+ apply: 'Uygula',
262
+ previousMonth: 'Önceki ay',
263
+ nextMonth: 'Sonraki ay',
264
+ datePlaceholder: 'Tarih seçin',
265
+ dateLabel: 'Tarih',
266
+ rangePlaceholder: 'Tarih aralığı seçin',
267
+ rangeLabel: 'Tarih aralığı',
268
+ startDate: 'Başlangıç tarihi',
269
+ endDate: 'Bitiş tarihi',
270
+ daysSelected: (n) => plural('tr', n, { other: '{n} gün seçildi' }),
271
+ presets: {
272
+ today: 'Bugün',
273
+ yesterday: 'Dün',
274
+ lastWeek: 'Geçen hafta',
275
+ thisMonth: 'Bu ay',
276
+ lastMonth: 'Geçen ay',
277
+ thisYear: 'Bu yıl',
278
+ lastYear: 'Geçen yıl',
279
+ allTime: 'Tüm zamanlar',
280
+ },
281
+ meetingTrigger: 'Toplantı planla',
282
+ meetingLabel: 'Toplantı planla',
283
+ send: 'Davet gönder',
284
+ selectTime: 'Saat seçin',
285
+ duration: (n) => plural('tr', n, { other: '{n} dakika' }),
286
+ },
287
+ ja: {
288
+ cancel: 'キャンセル',
289
+ apply: '適用',
290
+ previousMonth: '前の月',
291
+ nextMonth: '次の月',
292
+ datePlaceholder: '日付を選択',
293
+ dateLabel: '日付',
294
+ rangePlaceholder: '期間を選択',
295
+ rangeLabel: '期間',
296
+ startDate: '開始日',
297
+ endDate: '終了日',
298
+ daysSelected: (n) => plural('ja', n, { other: '{n}日間を選択' }),
299
+ presets: {
300
+ today: '今日',
301
+ yesterday: '昨日',
302
+ lastWeek: '先週',
303
+ thisMonth: '今月',
304
+ lastMonth: '先月',
305
+ thisYear: '今年',
306
+ lastYear: '昨年',
307
+ allTime: '全期間',
308
+ },
309
+ meetingTrigger: 'ミーティングを予約',
310
+ meetingLabel: 'ミーティングの予約',
311
+ send: '招待を送信',
312
+ selectTime: '時間を選択',
313
+ duration: (n) => plural('ja', n, { other: '{n}分' }),
314
+ },
315
+ zh: {
316
+ cancel: '取消',
317
+ apply: '应用',
318
+ previousMonth: '上个月',
319
+ nextMonth: '下个月',
320
+ datePlaceholder: '选择日期',
321
+ dateLabel: '日期',
322
+ rangePlaceholder: '选择日期范围',
323
+ rangeLabel: '日期范围',
324
+ startDate: '开始日期',
325
+ endDate: '结束日期',
326
+ daysSelected: (n) => plural('zh', n, { other: '已选择 {n} 天' }),
327
+ presets: {
328
+ today: '今天',
329
+ yesterday: '昨天',
330
+ lastWeek: '上周',
331
+ thisMonth: '本月',
332
+ lastMonth: '上个月',
333
+ thisYear: '今年',
334
+ lastYear: '去年',
335
+ allTime: '全部时间',
336
+ },
337
+ meetingTrigger: '安排会议',
338
+ meetingLabel: '安排会议',
339
+ send: '发送邀请',
340
+ selectTime: '选择时间',
341
+ duration: (n) => plural('zh', n, { other: '{n} 分钟' }),
342
+ },
343
+ ar: {
344
+ cancel: 'إلغاء',
345
+ apply: 'تطبيق',
346
+ previousMonth: 'الشهر السابق',
347
+ nextMonth: 'الشهر التالي',
348
+ datePlaceholder: 'اختر تاريخًا',
349
+ dateLabel: 'التاريخ',
350
+ rangePlaceholder: 'اختر نطاقًا زمنيًا',
351
+ rangeLabel: 'النطاق الزمني',
352
+ startDate: 'تاريخ البدء',
353
+ endDate: 'تاريخ الانتهاء',
354
+ daysSelected: (n) =>
355
+ plural('ar', n, {
356
+ zero: 'لم يتم تحديد أي يوم',
357
+ one: 'تم تحديد يوم واحد',
358
+ two: 'تم تحديد يومين',
359
+ few: 'تم تحديد {n} أيام',
360
+ many: 'تم تحديد {n} يومًا',
361
+ other: 'تم تحديد {n} يوم',
362
+ }),
363
+ presets: {
364
+ today: 'اليوم',
365
+ yesterday: 'أمس',
366
+ lastWeek: 'الأسبوع الماضي',
367
+ thisMonth: 'هذا الشهر',
368
+ lastMonth: 'الشهر الماضي',
369
+ thisYear: 'هذا العام',
370
+ lastYear: 'العام الماضي',
371
+ allTime: 'كل الأوقات',
372
+ },
373
+ meetingTrigger: 'جدولة اجتماع',
374
+ meetingLabel: 'جدولة اجتماع',
375
+ send: 'إرسال الدعوة',
376
+ selectTime: 'اختر وقتًا',
377
+ duration: (n) =>
378
+ plural('ar', n, {
379
+ one: 'دقيقة واحدة',
380
+ two: 'دقيقتان',
381
+ few: '{n} دقائق',
382
+ many: '{n} دقيقة',
383
+ other: '{n} دقيقة',
384
+ }),
385
+ },
386
+ hi: {
387
+ cancel: 'रद्द करें',
388
+ apply: 'लागू करें',
389
+ previousMonth: 'पिछला महीना',
390
+ nextMonth: 'अगला महीना',
391
+ datePlaceholder: 'तारीख़ चुनें',
392
+ dateLabel: 'तारीख़',
393
+ rangePlaceholder: 'तारीख़ की सीमा चुनें',
394
+ rangeLabel: 'तारीख़ की सीमा',
395
+ startDate: 'शुरू होने की तारीख़',
396
+ endDate: 'ख़त्म होने की तारीख़',
397
+ daysSelected: (n) => plural('hi', n, { one: '{n} दिन चुना गया', other: '{n} दिन चुने गए' }),
398
+ presets: {
399
+ today: 'आज',
400
+ yesterday: 'बीता कल',
401
+ lastWeek: 'पिछला सप्ताह',
402
+ thisMonth: 'इस महीने',
403
+ lastMonth: 'पिछला महीना',
404
+ thisYear: 'इस साल',
405
+ lastYear: 'पिछला साल',
406
+ allTime: 'पूरा समय',
407
+ },
408
+ meetingTrigger: 'मीटिंग शेड्यूल करें',
409
+ meetingLabel: 'मीटिंग शेड्यूल करें',
410
+ send: 'आमंत्रण भेजें',
411
+ selectTime: 'समय चुनें',
412
+ duration: (n) => plural('hi', n, { other: '{n} मिनट' }),
413
+ },
414
+ bn: {
415
+ cancel: 'বাতিল',
416
+ apply: 'প্রয়োগ করুন',
417
+ previousMonth: 'আগের মাস',
418
+ nextMonth: 'পরের মাস',
419
+ datePlaceholder: 'তারিখ বেছে নিন',
420
+ dateLabel: 'তারিখ',
421
+ rangePlaceholder: 'তারিখের পরিসর বেছে নিন',
422
+ rangeLabel: 'তারিখের পরিসর',
423
+ startDate: 'শুরুর তারিখ',
424
+ endDate: 'শেষের তারিখ',
425
+ daysSelected: (n) => plural('bn', n, { other: '{n} দিন নির্বাচিত' }),
426
+ presets: {
427
+ today: 'আজ',
428
+ yesterday: 'গতকাল',
429
+ lastWeek: 'গত সপ্তাহ',
430
+ thisMonth: 'এই মাস',
431
+ lastMonth: 'গত মাস',
432
+ thisYear: 'এই বছর',
433
+ lastYear: 'গত বছর',
434
+ allTime: 'সব সময়',
435
+ },
436
+ meetingTrigger: 'মিটিং নির্ধারণ করুন',
437
+ meetingLabel: 'মিটিং নির্ধারণ করুন',
438
+ send: 'আমন্ত্রণ পাঠান',
439
+ selectTime: 'সময় বেছে নিন',
440
+ duration: (n) => plural('bn', n, { other: '{n} মিনিট' }),
441
+ },
442
+ id: {
443
+ cancel: 'Batal',
444
+ apply: 'Terapkan',
445
+ previousMonth: 'Bulan sebelumnya',
446
+ nextMonth: 'Bulan berikutnya',
447
+ datePlaceholder: 'Pilih tanggal',
448
+ dateLabel: 'Tanggal',
449
+ rangePlaceholder: 'Pilih rentang tanggal',
450
+ rangeLabel: 'Rentang tanggal',
451
+ startDate: 'Tanggal mulai',
452
+ endDate: 'Tanggal selesai',
453
+ daysSelected: (n) => plural('id', n, { other: '{n} hari dipilih' }),
454
+ presets: {
455
+ today: 'Hari ini',
456
+ yesterday: 'Kemarin',
457
+ lastWeek: 'Minggu lalu',
458
+ thisMonth: 'Bulan ini',
459
+ lastMonth: 'Bulan lalu',
460
+ thisYear: 'Tahun ini',
461
+ lastYear: 'Tahun lalu',
462
+ allTime: 'Sepanjang waktu',
463
+ },
464
+ meetingTrigger: 'Jadwalkan rapat',
465
+ meetingLabel: 'Jadwalkan rapat',
466
+ send: 'Kirim undangan',
467
+ selectTime: 'Pilih waktu',
468
+ duration: (n) => plural('id', n, { other: '{n} menit' }),
469
+ },
470
+ };
@@ -19,15 +19,31 @@ export interface CalendarConstraintProps {
19
19
  isDateUnavailable?: (date: Date) => boolean;
20
20
  /** First column of the grid. Defaults to `0` (Sunday). */
21
21
  weekStartsOn?: WeekStart;
22
- /** BCP 47 locale for month, weekday and trigger text. Defaults to the runtime's. */
22
+ /**
23
+ * BCP 47 locale for month, weekday and trigger text, and for Bloom's own
24
+ * strings (Cancel, Apply, …). Defaults to `BloomProvider`'s `locale`, else the
25
+ * runtime's.
26
+ */
23
27
  locale?: string;
24
28
  }
25
29
 
30
+ /**
31
+ * Overrides for the month panels' fixed strings. Bloom already speaks them in
32
+ * the picker's `locale`; pass these only for wording of your own.
33
+ */
34
+ export interface CalendarLabels {
35
+ /** Names the previous-month chevron (`'Previous month'` in English). */
36
+ previousMonth?: string;
37
+ /** Names the next-month chevron (`'Next month'` in English). */
38
+ nextMonth?: string;
39
+ }
40
+
26
41
  interface CalendarBaseProps extends CalendarConstraintProps {
27
42
  /** Month shown first. Defaults to the selected day's month, else today's. */
28
43
  defaultMonth?: Date;
29
44
  /** Names the calendar grid. Defaults to the month title. */
30
45
  accessibilityLabel?: string;
46
+ labels?: CalendarLabels;
31
47
  style?: StyleProp<ViewStyle>;
32
48
  testID?: string;
33
49
  }
@@ -68,6 +84,40 @@ interface PickerBaseProps extends CalendarConstraintProps {
68
84
  testID?: string;
69
85
  }
70
86
 
87
+ /** Overrides for `DatePicker`'s fixed strings, which Bloom already speaks in `locale`. */
88
+ export interface DatePickerLabels extends CalendarLabels {
89
+ /** The footer's dismiss button (`'Cancel'` in English). */
90
+ cancel?: string;
91
+ /** The footer's commit button (`'Apply'` in English). */
92
+ apply?: string;
93
+ }
94
+
95
+ /** The quick-select column's rows, in the order they are drawn. */
96
+ export type DateRangePreset =
97
+ | 'today'
98
+ | 'yesterday'
99
+ | 'lastWeek'
100
+ | 'thisMonth'
101
+ | 'lastMonth'
102
+ | 'thisYear'
103
+ | 'lastYear'
104
+ | 'allTime';
105
+
106
+ /** Overrides for `DateRangePicker`'s fixed strings, which Bloom already speaks in `locale`. */
107
+ export interface DateRangePickerLabels extends DatePickerLabels {
108
+ /**
109
+ * The footer pill. Receives the count; Bloom's own pluralises per language
110
+ * (`'14 days selected'` in English).
111
+ */
112
+ daysSelected?: (days: number) => string;
113
+ /** Names the start-date chip (`'Start date'` in English). */
114
+ startDate?: string;
115
+ /** Names the end-date chip (`'End date'` in English). */
116
+ endDate?: string;
117
+ /** Quick-select rows; any left out keep Bloom's (`'Today'`, `'Last week'`, … in English). */
118
+ presets?: Partial<Record<DateRangePreset, string>>;
119
+ }
120
+
71
121
  export interface DatePickerProps extends PickerBaseProps {
72
122
  /** Committed day (controlled). `null` for none. */
73
123
  value?: Date | null;
@@ -75,10 +125,12 @@ export interface DatePickerProps extends PickerBaseProps {
75
125
  defaultValue?: Date | null;
76
126
  /** Called on Apply with the chosen day. */
77
127
  onChange?: (date: Date | null) => void;
78
- /** Trigger text with no day committed. Defaults to `'Select date'`. */
128
+ /** Trigger text with no day committed. Defaults to Bloom's (`'Select date'` in English). */
79
129
  placeholder?: string;
80
- /** Names the popup and its calendar. Defaults to `'Date'`. */
130
+ /** Names the popup and its calendar. Defaults to Bloom's (`'Date'` in English). */
81
131
  accessibilityLabel?: string;
132
+ /** Footer buttons and month chevrons. */
133
+ labels?: DatePickerLabels;
82
134
  }
83
135
 
84
136
  export interface DateRangePickerProps extends PickerBaseProps {
@@ -88,12 +140,14 @@ export interface DateRangePickerProps extends PickerBaseProps {
88
140
  defaultValue?: DateRange | null;
89
141
  /** Called on Apply with the chosen range. */
90
142
  onChange?: (range: DateRange | null) => void;
91
- /** Trigger text with no range committed. Defaults to `'Select date range'`. */
143
+ /** Trigger text with no range committed. Defaults to Bloom's (`'Select date range'` in English). */
92
144
  placeholder?: string;
93
- /** Names the popup and its calendar. Defaults to `'Date range'`. */
145
+ /** Names the popup and its calendar. Defaults to Bloom's (`'Date range'` in English). */
94
146
  accessibilityLabel?: string;
95
147
  /** Show the quick-select column (Today, Last week, …). Defaults to `true`. */
96
148
  quickSelect?: boolean;
149
+ /** Footer buttons and pill, date chips, quick-select rows and month chevrons. */
150
+ labels?: DateRangePickerLabels;
97
151
  }
98
152
 
99
153
  /** The person the meeting is booked with. */
@@ -135,13 +189,13 @@ export type HourFormat = '12h' | '24h';
135
189
  /** The hour-format toggle. An alias of {@link HourFormat}. */
136
190
  export type MeetingSchedulerHourFormat = HourFormat;
137
191
 
138
- /** Fixed strings, overridable for localisation. */
139
- export interface MeetingSchedulerLabels {
140
- /** Default `'Send meeting'`. */
192
+ /** Overrides for `MeetingScheduler`'s fixed strings, which Bloom already speaks in `locale`. */
193
+ export interface MeetingSchedulerLabels extends CalendarLabels {
194
+ /** `'Send meeting'` in English. */
141
195
  send?: string;
142
- /** Chip text before a time is picked. Default `'Select a time'`. */
196
+ /** Chip text before a time is picked (`'Select a time'` in English). */
143
197
  selectTime?: string;
144
- /** `{n} minutes`. Default `(n) => \`${n} minutes\``. */
198
+ /** The duration row (`'30 minutes'` in English). */
145
199
  duration?: (minutes: number) => string;
146
200
  }
147
201
 
@@ -162,9 +216,9 @@ export interface MeetingSchedulerProps extends CalendarConstraintProps {
162
216
  onChange?: (value: MeetingSchedulerValue | null) => void;
163
217
  /** Initial hour format. Defaults to `'24h'`. */
164
218
  defaultHourFormat?: MeetingSchedulerHourFormat;
165
- /** Trigger text. Defaults to `'Schedule a meeting'`. */
219
+ /** Trigger text. Defaults to Bloom's (`'Schedule a meeting'` in English). */
166
220
  triggerLabel?: string;
167
- /** Names the popup and its calendar. Defaults to `'Schedule meeting'`. */
221
+ /** Names the popup and its calendar. Defaults to Bloom's (`'Schedule meeting'` in English). */
168
222
  accessibilityLabel?: string;
169
223
  labels?: MeetingSchedulerLabels;
170
224
  disabled?: boolean;
package/src/index.ts CHANGED
@@ -80,6 +80,8 @@ export type { BloomIconComponent } from './icons/icon-component';
80
80
  // App-wide plumbing (pure JS — no peer beyond what this barrel already links)
81
81
  export { ImageResolverProvider, useImageResolver, isImageUrl } from './image-resolver';
82
82
  export type { ImageResolver } from './image-resolver';
83
+ export { LocaleProvider, useBloomLocale, BLOOM_LANGUAGES, resolveBloomLanguage } from './locale';
84
+ export type { BloomLanguage } from './locale';
83
85
  // A namespace, not seven loose verbs: `getAspectRatio`/`setAspectRatio`/
84
86
  // `hasAspectRatio` are exactly the collision-prone shape the namespace rule
85
87
  // covers.
package/src/index.web.ts CHANGED
@@ -85,6 +85,8 @@ export type { BloomIconComponent } from './icons/icon-component';
85
85
  // App-wide plumbing (pure JS — no peer beyond what this barrel already links)
86
86
  export { ImageResolverProvider, useImageResolver, isImageUrl } from './image-resolver';
87
87
  export type { ImageResolver } from './image-resolver';
88
+ export { LocaleProvider, useBloomLocale, BLOOM_LANGUAGES, resolveBloomLanguage } from './locale';
89
+ export type { BloomLanguage } from './locale';
88
90
  // A namespace, not seven loose verbs: `getAspectRatio`/`setAspectRatio`/
89
91
  // `hasAspectRatio` are exactly the collision-prone shape the namespace rule
90
92
  // covers.
@@ -0,0 +1,23 @@
1
+ import { createContext, createElement, useContext, type ReactNode } from 'react';
2
+
3
+ const LocaleContext = createContext<string | undefined>(undefined);
4
+
5
+ /**
6
+ * Sets the locale every Bloom component below it formats and speaks in —
7
+ * month names, dates, and Bloom's own fixed strings (Cancel, Apply, …).
8
+ * `BloomProvider`'s `locale` prop mounts one; mount another to scope a subtree.
9
+ * Unset, components follow the runtime's locale.
10
+ */
11
+ export function LocaleProvider({ locale, children }: { locale?: string; children?: ReactNode }) {
12
+ return createElement(LocaleContext.Provider, { value: locale }, children);
13
+ }
14
+
15
+ /**
16
+ * The locale a component should use: its own `locale` prop, else the nearest
17
+ * `LocaleProvider`'s, else `undefined` — which `Intl` and the message catalogs
18
+ * both read as "the runtime's".
19
+ */
20
+ export function useBloomLocale(locale?: string): string | undefined {
21
+ const inherited = useContext(LocaleContext);
22
+ return locale ?? inherited;
23
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `Intl.DateTimeFormat` pinned to the GREGORIAN calendar, keeping the locale's
3
+ * language, digits and order.
4
+ *
5
+ * Bloom's grids lay out and return Gregorian `Date`s. A locale whose default
6
+ * calendar is another one — `fa-IR` (Persian, year 1405), `th-TH` (Buddhist,
7
+ * 2569), some `ar-*` — would otherwise title a Gregorian September with
8
+ * another calendar's month and year, so the day a reader picks and the day the
9
+ * app receives disagree. `null` when the runtime cannot format at all (a bad
10
+ * tag), for the caller's own fallback.
11
+ */
12
+ export function formatGregorian(
13
+ date: Date,
14
+ locale: string | undefined,
15
+ options: Intl.DateTimeFormatOptions,
16
+ ): string | null {
17
+ try {
18
+ return new Intl.DateTimeFormat(locale, { ...options, calendar: 'gregory' }).format(date);
19
+ } catch {
20
+ // An engine that rejects the `calendar` option still formats the locale's
21
+ // words; only a tag it cannot read at all falls through to `null`.
22
+ try {
23
+ return new Intl.DateTimeFormat(locale, options).format(date);
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,4 @@
1
+ export { LocaleProvider, useBloomLocale } from './context';
2
+ export { BLOOM_LANGUAGES, resolveBloomLanguage, type BloomLanguage } from './languages';
3
+ // `messages.ts` and `plural.ts` are how families localise themselves, not app
4
+ // API: an app speaks through `locale` and each family's `labels` overrides.