@proyecto-viviana/solid-stately 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/calendar/createDateFieldState.d.ts +56 -18
- package/dist/calendar/createRangeCalendarState.d.ts +10 -0
- package/dist/calendar/createTimeFieldState.d.ts +38 -67
- package/dist/calendar/intl/index.d.ts +10 -0
- package/dist/collections/ListCollection.d.ts +8 -0
- package/dist/collections/createListState.d.ts +12 -0
- package/dist/collections/getChildNodes.d.ts +8 -0
- package/dist/collections/index.d.ts +2 -2
- package/dist/collections/types.d.ts +9 -0
- package/dist/color/intl/index.d.ts +14 -0
- package/dist/dnd/createDroppableCollectionState.d.ts +17 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3444 -1304
- package/dist/index.js.map +1 -1
- package/dist/selection/SelectionManager.d.ts +9 -0
- package/package.json +1 -1
- package/src/calendar/createCalendarState.ts +26 -4
- package/src/calendar/createDateFieldState.ts +614 -459
- package/src/calendar/createRangeCalendarState.ts +212 -11
- package/src/calendar/createTimeFieldState.ts +179 -467
- package/src/calendar/intl/index.ts +364 -0
- package/src/collections/ListCollection.ts +31 -0
- package/src/collections/createListState.ts +92 -1
- package/src/collections/getChildNodes.ts +31 -0
- package/src/collections/index.ts +3 -0
- package/src/collections/types.ts +10 -0
- package/src/color/Color.ts +104 -133
- package/src/color/intl/index.ts +1409 -0
- package/src/combobox/createComboBoxState.ts +30 -13
- package/src/dnd/createDroppableCollectionState.ts +125 -6
- package/src/index.ts +3 -0
- package/src/selection/SelectionManager.ts +15 -0
- package/src/steplist/createStepListState.ts +27 -4
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
// DateField validation-message catalog, ported verbatim from @react-stately/datepicker's
|
|
2
|
+
// intl/*.json (34 locales). Keep in sync with the vendored react-spectrum source on every
|
|
3
|
+
// pin bump. Hand-rolled resolver so solid-stately needs no @internationalized/string dep.
|
|
4
|
+
|
|
5
|
+
export type DateFieldErrorKey =
|
|
6
|
+
| "rangeUnderflow"
|
|
7
|
+
| "rangeOverflow"
|
|
8
|
+
| "rangeReversed"
|
|
9
|
+
| "unavailableDate";
|
|
10
|
+
|
|
11
|
+
type DateFieldErrorArgs = { minValue?: string; maxValue?: string };
|
|
12
|
+
type DateFieldErrorMessage = string | ((args: DateFieldErrorArgs) => string);
|
|
13
|
+
|
|
14
|
+
const errorStrings: Record<string, Record<DateFieldErrorKey, DateFieldErrorMessage>> = {
|
|
15
|
+
"ar-AE": {
|
|
16
|
+
"rangeOverflow": (args)=>`\u{64A}\u{62C}\u{628} \u{623}\u{646} \u{62A}\u{643}\u{648}\u{646} \u{627}\u{644}\u{642}\u{64A}\u{645}\u{629} ${args.maxValue} \u{623}\u{648} \u{642}\u{628}\u{644} \u{630}\u{644}\u{643}.`,
|
|
17
|
+
"rangeReversed": `\u{62A}\u{627}\u{631}\u{64A}\u{62E} \u{627}\u{644}\u{628}\u{62F}\u{621} \u{64A}\u{62C}\u{628} \u{623}\u{646} \u{64A}\u{643}\u{648}\u{646} \u{642}\u{628}\u{644} \u{62A}\u{627}\u{631}\u{64A}\u{62E} \u{627}\u{644}\u{627}\u{646}\u{62A}\u{647}\u{627}\u{621}.`,
|
|
18
|
+
"rangeUnderflow": (args)=>`\u{64A}\u{62C}\u{628} \u{623}\u{646} \u{62A}\u{643}\u{648}\u{646} \u{627}\u{644}\u{642}\u{64A}\u{645}\u{629} ${args.minValue} \u{623}\u{648} \u{628}\u{639}\u{62F} \u{630}\u{644}\u{643}.`,
|
|
19
|
+
"unavailableDate": `\u{627}\u{644}\u{628}\u{64A}\u{627}\u{646}\u{627}\u{62A} \u{627}\u{644}\u{645}\u{62D}\u{62F}\u{62F}\u{629} \u{63A}\u{64A}\u{631} \u{645}\u{62A}\u{627}\u{62D}\u{629}.`
|
|
20
|
+
},
|
|
21
|
+
"bg-BG": {
|
|
22
|
+
"rangeOverflow": (args)=>`\u{421}\u{442}\u{43E}\u{439}\u{43D}\u{43E}\u{441}\u{442}\u{442}\u{430} \u{442}\u{440}\u{44F}\u{431}\u{432}\u{430} \u{434}\u{430} \u{435} ${args.maxValue} \u{438}\u{43B}\u{438} \u{43F}\u{43E}-\u{440}\u{430}\u{43D}\u{43D}\u{430}.`,
|
|
23
|
+
"rangeReversed": `\u{41D}\u{430}\u{447}\u{430}\u{43B}\u{43D}\u{430}\u{442}\u{430} \u{434}\u{430}\u{442}\u{430} \u{442}\u{440}\u{44F}\u{431}\u{432}\u{430} \u{434}\u{430} \u{435} \u{43F}\u{440}\u{435}\u{434}\u{438} \u{43A}\u{440}\u{430}\u{439}\u{43D}\u{430}\u{442}\u{430}.`,
|
|
24
|
+
"rangeUnderflow": (args)=>`\u{421}\u{442}\u{43E}\u{439}\u{43D}\u{43E}\u{441}\u{442}\u{442}\u{430} \u{442}\u{440}\u{44F}\u{431}\u{432}\u{430} \u{434}\u{430} \u{435} ${args.minValue} \u{438}\u{43B}\u{438} \u{43F}\u{43E}-\u{43A}\u{44A}\u{441}\u{43D}\u{43E}.`,
|
|
25
|
+
"unavailableDate": `\u{418}\u{437}\u{431}\u{440}\u{430}\u{43D}\u{430}\u{442}\u{430} \u{434}\u{430}\u{442}\u{430} \u{43D}\u{435} \u{435} \u{43D}\u{430}\u{43B}\u{438}\u{447}\u{43D}\u{430}.`
|
|
26
|
+
},
|
|
27
|
+
"cs-CZ": {
|
|
28
|
+
"rangeOverflow": (args)=>`Hodnota mus\xed b\xfdt ${args.maxValue} nebo d\u{159}\xedv\u{11B}j\u{161}\xed.`,
|
|
29
|
+
"rangeReversed": `Datum zah\xe1jen\xed mus\xed p\u{159}edch\xe1zet datu ukon\u{10D}en\xed.`,
|
|
30
|
+
"rangeUnderflow": (args)=>`Hodnota mus\xed b\xfdt ${args.minValue} nebo pozd\u{11B}j\u{161}\xed.`,
|
|
31
|
+
"unavailableDate": `Vybran\xe9 datum nen\xed k dispozici.`
|
|
32
|
+
},
|
|
33
|
+
"da-DK": {
|
|
34
|
+
"rangeOverflow": (args)=>`V\xe6rdien skal v\xe6re ${args.maxValue} eller tidligere.`,
|
|
35
|
+
"rangeReversed": `Startdatoen skal v\xe6re f\xf8r slutdatoen.`,
|
|
36
|
+
"rangeUnderflow": (args)=>`V\xe6rdien skal v\xe6re ${args.minValue} eller nyere.`,
|
|
37
|
+
"unavailableDate": `Den valgte dato er ikke tilg\xe6ngelig.`
|
|
38
|
+
},
|
|
39
|
+
"de-DE": {
|
|
40
|
+
"rangeOverflow": (args)=>`Der Wert muss ${args.maxValue} oder fr\xfcher sein.`,
|
|
41
|
+
"rangeReversed": `Das Startdatum muss vor dem Enddatum liegen.`,
|
|
42
|
+
"rangeUnderflow": (args)=>`Der Wert muss ${args.minValue} oder sp\xe4ter sein.`,
|
|
43
|
+
"unavailableDate": `Das ausgew\xe4hlte Datum ist nicht verf\xfcgbar.`
|
|
44
|
+
},
|
|
45
|
+
"el-GR": {
|
|
46
|
+
"rangeOverflow": (args)=>`\u{397} \u{3C4}\u{3B9}\u{3BC}\u{3AE} \u{3C0}\u{3C1}\u{3AD}\u{3C0}\u{3B5}\u{3B9} \u{3BD}\u{3B1} \u{3B5}\u{3AF}\u{3BD}\u{3B1}\u{3B9} ${args.maxValue} \u{3AE} \u{3C0}\u{3B1}\u{3BB}\u{3B1}\u{3B9}\u{3CC}\u{3C4}\u{3B5}\u{3C1}\u{3B7}.`,
|
|
47
|
+
"rangeReversed": `\u{397} \u{3B7}\u{3BC}\u{3B5}\u{3C1}\u{3BF}\u{3BC}\u{3B7}\u{3BD}\u{3AF}\u{3B1} \u{3AD}\u{3BD}\u{3B1}\u{3C1}\u{3BE}\u{3B7}\u{3C2} \u{3C0}\u{3C1}\u{3AD}\u{3C0}\u{3B5}\u{3B9} \u{3BD}\u{3B1} \u{3B5}\u{3AF}\u{3BD}\u{3B1}\u{3B9} \u{3C0}\u{3C1}\u{3B9}\u{3BD} \u{3B1}\u{3C0}\u{3CC} \u{3C4}\u{3B7}\u{3BD} \u{3B7}\u{3BC}\u{3B5}\u{3C1}\u{3BF}\u{3BC}\u{3B7}\u{3BD}\u{3AF}\u{3B1} \u{3BB}\u{3AE}\u{3BE}\u{3B7}\u{3C2}.`,
|
|
48
|
+
"rangeUnderflow": (args)=>`\u{397} \u{3C4}\u{3B9}\u{3BC}\u{3AE} \u{3C0}\u{3C1}\u{3AD}\u{3C0}\u{3B5}\u{3B9} \u{3BD}\u{3B1} \u{3B5}\u{3AF}\u{3BD}\u{3B1}\u{3B9} ${args.minValue} \u{3AE} \u{3BC}\u{3B5}\u{3C4}\u{3B1}\u{3B3}\u{3B5}\u{3BD}\u{3AD}\u{3C3}\u{3C4}\u{3B5}\u{3C1}\u{3B7}.`,
|
|
49
|
+
"unavailableDate": `\u{397} \u{3B5}\u{3C0}\u{3B9}\u{3BB}\u{3B5}\u{3B3}\u{3BC}\u{3AD}\u{3BD}\u{3B7} \u{3B7}\u{3BC}\u{3B5}\u{3C1}\u{3BF}\u{3BC}\u{3B7}\u{3BD}\u{3AF}\u{3B1} \u{3B4}\u{3B5}\u{3BD} \u{3B5}\u{3AF}\u{3BD}\u{3B1}\u{3B9} \u{3B4}\u{3B9}\u{3B1}\u{3B8}\u{3AD}\u{3C3}\u{3B9}\u{3BC}\u{3B7}.`
|
|
50
|
+
},
|
|
51
|
+
"en-US": {
|
|
52
|
+
"rangeUnderflow": (args)=>`Value must be ${args.minValue} or later.`,
|
|
53
|
+
"rangeOverflow": (args)=>`Value must be ${args.maxValue} or earlier.`,
|
|
54
|
+
"rangeReversed": `Start date must be before end date.`,
|
|
55
|
+
"unavailableDate": `Selected date unavailable.`
|
|
56
|
+
},
|
|
57
|
+
"es-ES": {
|
|
58
|
+
"rangeOverflow": (args)=>`El valor debe ser ${args.maxValue} o anterior.`,
|
|
59
|
+
"rangeReversed": `La fecha de inicio debe ser anterior a la fecha de finalizaci\xf3n.`,
|
|
60
|
+
"rangeUnderflow": (args)=>`El valor debe ser ${args.minValue} o posterior.`,
|
|
61
|
+
"unavailableDate": `Fecha seleccionada no disponible.`
|
|
62
|
+
},
|
|
63
|
+
"et-EE": {
|
|
64
|
+
"rangeOverflow": (args)=>`V\xe4\xe4rtus peab olema ${args.maxValue} v\xf5i varasem.`,
|
|
65
|
+
"rangeReversed": `Alguskuup\xe4ev peab olema enne l\xf5ppkuup\xe4eva.`,
|
|
66
|
+
"rangeUnderflow": (args)=>`V\xe4\xe4rtus peab olema ${args.minValue} v\xf5i hilisem.`,
|
|
67
|
+
"unavailableDate": `Valitud kuup\xe4ev pole saadaval.`
|
|
68
|
+
},
|
|
69
|
+
"fi-FI": {
|
|
70
|
+
"rangeOverflow": (args)=>`Arvon on oltava ${args.maxValue} tai sit\xe4 aikaisempi.`,
|
|
71
|
+
"rangeReversed": `Aloitusp\xe4iv\xe4n on oltava ennen lopetusp\xe4iv\xe4\xe4.`,
|
|
72
|
+
"rangeUnderflow": (args)=>`Arvon on oltava ${args.minValue} tai sit\xe4 my\xf6h\xe4isempi.`,
|
|
73
|
+
"unavailableDate": `Valittu p\xe4iv\xe4m\xe4\xe4r\xe4 ei ole k\xe4ytett\xe4viss\xe4.`
|
|
74
|
+
},
|
|
75
|
+
"fr-FR": {
|
|
76
|
+
"rangeOverflow": (args)=>`La valeur doit \xeatre ${args.maxValue} ou ant\xe9rieure.`,
|
|
77
|
+
"rangeReversed": `La date de d\xe9but doit \xeatre ant\xe9rieure \xe0 la date de fin.`,
|
|
78
|
+
"rangeUnderflow": (args)=>`La valeur doit \xeatre ${args.minValue} ou ult\xe9rieure.`,
|
|
79
|
+
"unavailableDate": `La date s\xe9lectionn\xe9e n\u{2019}est pas disponible.`
|
|
80
|
+
},
|
|
81
|
+
"he-IL": {
|
|
82
|
+
"rangeOverflow": (args)=>`\u{5D4}\u{5E2}\u{5E8}\u{5DA} \u{5D7}\u{5D9}\u{5D9}\u{5D1} \u{5DC}\u{5D4}\u{5D9}\u{5D5}\u{5EA} ${args.maxValue} \u{5D0}\u{5D5} \u{5DE}\u{5D5}\u{5E7}\u{5D3}\u{5DD} \u{5D9}\u{5D5}\u{5EA}\u{5E8}.`,
|
|
83
|
+
"rangeReversed": `\u{5EA}\u{5D0}\u{5E8}\u{5D9}\u{5DA} \u{5D4}\u{5D4}\u{5EA}\u{5D7}\u{5DC}\u{5D4} \u{5D7}\u{5D9}\u{5D9}\u{5D1} \u{5DC}\u{5D4}\u{5D9}\u{5D5}\u{5EA} \u{5DC}\u{5E4}\u{5E0}\u{5D9} \u{5EA}\u{5D0}\u{5E8}\u{5D9}\u{5DA} \u{5D4}\u{5E1}\u{5D9}\u{5D5}\u{5DD}.`,
|
|
84
|
+
"rangeUnderflow": (args)=>`\u{5D4}\u{5E2}\u{5E8}\u{5DA} \u{5D7}\u{5D9}\u{5D9}\u{5D1} \u{5DC}\u{5D4}\u{5D9}\u{5D5}\u{5EA} ${args.minValue} \u{5D0}\u{5D5} \u{5DE}\u{5D0}\u{5D5}\u{5D7}\u{5E8} \u{5D9}\u{5D5}\u{5EA}\u{5E8}.`,
|
|
85
|
+
"unavailableDate": `\u{5D4}\u{5EA}\u{5D0}\u{5E8}\u{5D9}\u{5DA} \u{5D4}\u{5E0}\u{5D1}\u{5D7}\u{5E8} \u{5D0}\u{5D9}\u{5E0}\u{5D5} \u{5D6}\u{5DE}\u{5D9}\u{5DF}.`
|
|
86
|
+
},
|
|
87
|
+
"hr-HR": {
|
|
88
|
+
"rangeOverflow": (args)=>`Vrijednost mora biti ${args.maxValue} ili ranije.`,
|
|
89
|
+
"rangeReversed": `Datum po\u{10D}etka mora biti prije datuma zavr\u{161}etka.`,
|
|
90
|
+
"rangeUnderflow": (args)=>`Vrijednost mora biti ${args.minValue} ili kasnije.`,
|
|
91
|
+
"unavailableDate": `Odabrani datum nije dostupan.`
|
|
92
|
+
},
|
|
93
|
+
"hu-HU": {
|
|
94
|
+
"rangeOverflow": (args)=>`Az \xe9rt\xe9knek ${args.maxValue} vagy kor\xe1bbinak kell lennie.`,
|
|
95
|
+
"rangeReversed": `A kezd\u{151} d\xe1tumnak a befejez\u{151} d\xe1tumn\xe1l kor\xe1bbinak kell lennie.`,
|
|
96
|
+
"rangeUnderflow": (args)=>`Az \xe9rt\xe9knek ${args.minValue} vagy k\xe9s\u{151}bbinek kell lennie.`,
|
|
97
|
+
"unavailableDate": `A kiv\xe1lasztott d\xe1tum nem \xe9rhet\u{151} el.`
|
|
98
|
+
},
|
|
99
|
+
"it-IT": {
|
|
100
|
+
"rangeOverflow": (args)=>`Il valore deve essere ${args.maxValue} o precedente.`,
|
|
101
|
+
"rangeReversed": `La data di inizio deve essere antecedente alla data di fine.`,
|
|
102
|
+
"rangeUnderflow": (args)=>`Il valore deve essere ${args.minValue} o successivo.`,
|
|
103
|
+
"unavailableDate": `Data selezionata non disponibile.`
|
|
104
|
+
},
|
|
105
|
+
"ja-JP": {
|
|
106
|
+
"rangeOverflow": (args)=>`\u{5024}\u{306F} ${args.maxValue} \u{4EE5}\u{4E0B}\u{306B}\u{3059}\u{308B}\u{5FC5}\u{8981}\u{304C}\u{3042}\u{308A}\u{307E}\u{3059}\u{3002}`,
|
|
107
|
+
"rangeReversed": `\u{958B}\u{59CB}\u{65E5}\u{306F}\u{7D42}\u{4E86}\u{65E5}\u{3088}\u{308A}\u{524D}\u{306B}\u{3059}\u{308B}\u{5FC5}\u{8981}\u{304C}\u{3042}\u{308A}\u{307E}\u{3059}\u{3002}`,
|
|
108
|
+
"rangeUnderflow": (args)=>`\u{5024}\u{306F} ${args.minValue} \u{4EE5}\u{4E0A}\u{306B}\u{3059}\u{308B}\u{5FC5}\u{8981}\u{304C}\u{3042}\u{308A}\u{307E}\u{3059}\u{3002}`,
|
|
109
|
+
"unavailableDate": `\u{9078}\u{629E}\u{3057}\u{305F}\u{65E5}\u{4ED8}\u{306F}\u{4F7F}\u{7528}\u{3067}\u{304D}\u{307E}\u{305B}\u{3093}\u{3002}`
|
|
110
|
+
},
|
|
111
|
+
"ko-KR": {
|
|
112
|
+
"rangeOverflow": (args)=>`\u{AC12}\u{C740} ${args.maxValue} \u{C774}\u{C804}\u{C774}\u{C5B4}\u{C57C} \u{D569}\u{B2C8}\u{B2E4}.`,
|
|
113
|
+
"rangeReversed": `\u{C2DC}\u{C791}\u{C77C}\u{C740} \u{C885}\u{B8CC}\u{C77C} \u{C774}\u{C804}\u{C774}\u{C5B4}\u{C57C} \u{D569}\u{B2C8}\u{B2E4}.`,
|
|
114
|
+
"rangeUnderflow": (args)=>`\u{AC12}\u{C740} ${args.minValue} \u{C774}\u{D6C4}\u{C5EC}\u{C57C} \u{D569}\u{B2C8}\u{B2E4}.`,
|
|
115
|
+
"unavailableDate": `\u{C120}\u{D0DD}\u{D55C} \u{B0A0}\u{C9DC}\u{B97C} \u{C0AC}\u{C6A9}\u{D560} \u{C218} \u{C5C6}\u{C2B5}\u{B2C8}\u{B2E4}.`
|
|
116
|
+
},
|
|
117
|
+
"lt-LT": {
|
|
118
|
+
"rangeOverflow": (args)=>`Reik\u{161}m\u{117} turi b\u{16B}ti ${args.maxValue} arba ankstesn\u{117}.`,
|
|
119
|
+
"rangeReversed": `Prad\u{17E}ios data turi b\u{16B}ti ankstesn\u{117} nei pabaigos data.`,
|
|
120
|
+
"rangeUnderflow": (args)=>`Reik\u{161}m\u{117} turi b\u{16B}ti ${args.minValue} arba naujesn\u{117}.`,
|
|
121
|
+
"unavailableDate": `Pasirinkta data nepasiekiama.`
|
|
122
|
+
},
|
|
123
|
+
"lv-LV": {
|
|
124
|
+
"rangeOverflow": (args)=>`V\u{113}rt\u{12B}bai ir j\u{101}b\u{16B}t ${args.maxValue} vai agr\u{101}kai.`,
|
|
125
|
+
"rangeReversed": `S\u{101}kuma datumam ir j\u{101}b\u{16B}t pirms beigu datuma.`,
|
|
126
|
+
"rangeUnderflow": (args)=>`V\u{113}rt\u{12B}bai ir j\u{101}b\u{16B}t ${args.minValue} vai v\u{113}l\u{101}kai.`,
|
|
127
|
+
"unavailableDate": `Atlas\u{12B}tais datums nav pieejams.`
|
|
128
|
+
},
|
|
129
|
+
"nb-NO": {
|
|
130
|
+
"rangeOverflow": (args)=>`Verdien m\xe5 v\xe6re ${args.maxValue} eller tidligere.`,
|
|
131
|
+
"rangeReversed": `Startdatoen m\xe5 v\xe6re f\xf8r sluttdatoen.`,
|
|
132
|
+
"rangeUnderflow": (args)=>`Verdien m\xe5 v\xe6re ${args.minValue} eller senere.`,
|
|
133
|
+
"unavailableDate": `Valgt dato utilgjengelig.`
|
|
134
|
+
},
|
|
135
|
+
"nl-NL": {
|
|
136
|
+
"rangeOverflow": (args)=>`Waarde moet ${args.maxValue} of eerder zijn.`,
|
|
137
|
+
"rangeReversed": `De startdatum moet voor de einddatum liggen.`,
|
|
138
|
+
"rangeUnderflow": (args)=>`Waarde moet ${args.minValue} of later zijn.`,
|
|
139
|
+
"unavailableDate": `Geselecteerde datum niet beschikbaar.`
|
|
140
|
+
},
|
|
141
|
+
"pl-PL": {
|
|
142
|
+
"rangeOverflow": (args)=>`Warto\u{15B}\u{107} musi mie\u{107} warto\u{15B}\u{107} ${args.maxValue} lub wcze\u{15B}niejsz\u{105}.`,
|
|
143
|
+
"rangeReversed": `Data rozpocz\u{119}cia musi by\u{107} wcze\u{15B}niejsza ni\u{17C} data zako\u{144}czenia.`,
|
|
144
|
+
"rangeUnderflow": (args)=>`Warto\u{15B}\u{107} musi mie\u{107} warto\u{15B}\u{107} ${args.minValue} lub p\xf3\u{17A}niejsz\u{105}.`,
|
|
145
|
+
"unavailableDate": `Wybrana data jest niedost\u{119}pna.`
|
|
146
|
+
},
|
|
147
|
+
"pt-BR": {
|
|
148
|
+
"rangeOverflow": (args)=>`O valor deve ser ${args.maxValue} ou anterior.`,
|
|
149
|
+
"rangeReversed": `A data inicial deve ser anterior \xe0 data final.`,
|
|
150
|
+
"rangeUnderflow": (args)=>`O valor deve ser ${args.minValue} ou posterior.`,
|
|
151
|
+
"unavailableDate": `Data selecionada indispon\xedvel.`
|
|
152
|
+
},
|
|
153
|
+
"pt-PT": {
|
|
154
|
+
"rangeOverflow": (args)=>`O valor tem de ser ${args.maxValue} ou anterior.`,
|
|
155
|
+
"rangeReversed": `A data de in\xedcio deve ser anterior \xe0 data de fim.`,
|
|
156
|
+
"rangeUnderflow": (args)=>`O valor tem de ser ${args.minValue} ou posterior.`,
|
|
157
|
+
"unavailableDate": `Data selecionada indispon\xedvel.`
|
|
158
|
+
},
|
|
159
|
+
"ro-RO": {
|
|
160
|
+
"rangeOverflow": (args)=>`Valoarea trebuie s\u{103} fie ${args.maxValue} sau anterioar\u{103}.`,
|
|
161
|
+
"rangeReversed": `Data de \xeenceput trebuie s\u{103} fie anterioar\u{103} datei de sf\xe2r\u{219}it.`,
|
|
162
|
+
"rangeUnderflow": (args)=>`Valoarea trebuie s\u{103} fie ${args.minValue} sau ulterioar\u{103}.`,
|
|
163
|
+
"unavailableDate": `Data selectat\u{103} nu este disponibil\u{103}.`
|
|
164
|
+
},
|
|
165
|
+
"ru-RU": {
|
|
166
|
+
"rangeOverflow": (args)=>`\u{417}\u{43D}\u{430}\u{447}\u{435}\u{43D}\u{438}\u{435} \u{434}\u{43E}\u{43B}\u{436}\u{43D}\u{43E} \u{431}\u{44B}\u{442}\u{44C} \u{43D}\u{435} \u{43F}\u{43E}\u{437}\u{436}\u{435} ${args.maxValue}.`,
|
|
167
|
+
"rangeReversed": `\u{414}\u{430}\u{442}\u{430} \u{43D}\u{430}\u{447}\u{430}\u{43B}\u{430} \u{434}\u{43E}\u{43B}\u{436}\u{43D}\u{430} \u{43F}\u{440}\u{435}\u{434}\u{448}\u{435}\u{441}\u{442}\u{432}\u{43E}\u{432}\u{430}\u{442}\u{44C} \u{434}\u{430}\u{442}\u{435} \u{43E}\u{43A}\u{43E}\u{43D}\u{447}\u{430}\u{43D}\u{438}\u{44F}.`,
|
|
168
|
+
"rangeUnderflow": (args)=>`\u{417}\u{43D}\u{430}\u{447}\u{435}\u{43D}\u{438}\u{435} \u{434}\u{43E}\u{43B}\u{436}\u{43D}\u{43E} \u{431}\u{44B}\u{442}\u{44C} \u{43D}\u{435} \u{440}\u{430}\u{43D}\u{44C}\u{448}\u{435} ${args.minValue}.`,
|
|
169
|
+
"unavailableDate": `\u{412}\u{44B}\u{431}\u{440}\u{430}\u{43D}\u{43D}\u{430}\u{44F} \u{434}\u{430}\u{442}\u{430} \u{43D}\u{435}\u{434}\u{43E}\u{441}\u{442}\u{443}\u{43F}\u{43D}\u{430}.`
|
|
170
|
+
},
|
|
171
|
+
"sk-SK": {
|
|
172
|
+
"rangeOverflow": (args)=>`Hodnota mus\xed by\u{165} ${args.maxValue} alebo skor\u{161}ia.`,
|
|
173
|
+
"rangeReversed": `D\xe1tum za\u{10D}iatku mus\xed by\u{165} skor\u{161}\xed ako d\xe1tum konca.`,
|
|
174
|
+
"rangeUnderflow": (args)=>`Hodnota mus\xed by\u{165} ${args.minValue} alebo neskor\u{161}ia.`,
|
|
175
|
+
"unavailableDate": `Vybrat\xfd d\xe1tum je nedostupn\xfd.`
|
|
176
|
+
},
|
|
177
|
+
"sl-SI": {
|
|
178
|
+
"rangeOverflow": (args)=>`Vrednost mora biti ${args.maxValue} ali starej\u{161}a.`,
|
|
179
|
+
"rangeReversed": `Za\u{10D}etni datum mora biti pred kon\u{10D}nim datumom.`,
|
|
180
|
+
"rangeUnderflow": (args)=>`Vrednost mora biti ${args.minValue} ali novej\u{161}a.`,
|
|
181
|
+
"unavailableDate": `Izbrani datum ni na voljo.`
|
|
182
|
+
},
|
|
183
|
+
"sr-SP": {
|
|
184
|
+
"rangeOverflow": (args)=>`Vrednost mora da bude ${args.maxValue} ili starija.`,
|
|
185
|
+
"rangeReversed": `Datum po\u{10D}etka mora biti pre datuma zavr\u{161}etka.`,
|
|
186
|
+
"rangeUnderflow": (args)=>`Vrednost mora da bude ${args.minValue} ili novija.`,
|
|
187
|
+
"unavailableDate": `Izabrani datum nije dostupan.`
|
|
188
|
+
},
|
|
189
|
+
"sv-SE": {
|
|
190
|
+
"rangeOverflow": (args)=>`V\xe4rdet m\xe5ste vara ${args.maxValue} eller tidigare.`,
|
|
191
|
+
"rangeReversed": `Startdatumet m\xe5ste vara f\xf6re slutdatumet.`,
|
|
192
|
+
"rangeUnderflow": (args)=>`V\xe4rdet m\xe5ste vara ${args.minValue} eller senare.`,
|
|
193
|
+
"unavailableDate": `Det valda datumet \xe4r inte tillg\xe4ngligt.`
|
|
194
|
+
},
|
|
195
|
+
"tr-TR": {
|
|
196
|
+
"rangeOverflow": (args)=>`De\u{11F}er, ${args.maxValue} veya \xf6ncesi olmal\u{131}d\u{131}r.`,
|
|
197
|
+
"rangeReversed": `Ba\u{15F}lang\u{131}\xe7 tarihi biti\u{15F} tarihinden \xf6nce olmal\u{131}d\u{131}r.`,
|
|
198
|
+
"rangeUnderflow": (args)=>`De\u{11F}er, ${args.minValue} veya sonras\u{131} olmal\u{131}d\u{131}r.`,
|
|
199
|
+
"unavailableDate": `Se\xe7ilen tarih kullan\u{131}lam\u{131}yor.`
|
|
200
|
+
},
|
|
201
|
+
"uk-UA": {
|
|
202
|
+
"rangeOverflow": (args)=>`\u{417}\u{43D}\u{430}\u{447}\u{435}\u{43D}\u{43D}\u{44F} \u{43C}\u{430}\u{454} \u{431}\u{443}\u{442}\u{438} \u{43D}\u{435} \u{43F}\u{456}\u{437}\u{43D}\u{456}\u{448}\u{435} ${args.maxValue}.`,
|
|
203
|
+
"rangeReversed": `\u{414}\u{430}\u{442}\u{430} \u{43F}\u{43E}\u{447}\u{430}\u{442}\u{43A}\u{443} \u{43C}\u{430}\u{454} \u{43F}\u{435}\u{440}\u{435}\u{434}\u{443}\u{432}\u{430}\u{442}\u{438} \u{434}\u{430}\u{442}\u{456} \u{437}\u{430}\u{432}\u{435}\u{440}\u{448}\u{435}\u{43D}\u{43D}\u{44F}.`,
|
|
204
|
+
"rangeUnderflow": (args)=>`\u{417}\u{43D}\u{430}\u{447}\u{435}\u{43D}\u{43D}\u{44F} \u{43C}\u{430}\u{454} \u{431}\u{443}\u{442}\u{438} \u{43D}\u{435} \u{440}\u{430}\u{43D}\u{456}\u{448}\u{435} ${args.minValue}.`,
|
|
205
|
+
"unavailableDate": `\u{412}\u{438}\u{431}\u{440}\u{430}\u{43D}\u{430} \u{434}\u{430}\u{442}\u{430} \u{43D}\u{435}\u{434}\u{43E}\u{441}\u{442}\u{443}\u{43F}\u{43D}\u{430}.`
|
|
206
|
+
},
|
|
207
|
+
"zh-CN": {
|
|
208
|
+
"rangeOverflow": (args)=>`\u{503C}\u{5FC5}\u{987B}\u{662F} ${args.maxValue} \u{6216}\u{66F4}\u{65E9}\u{65E5}\u{671F}\u{3002}`,
|
|
209
|
+
"rangeReversed": `\u{5F00}\u{59CB}\u{65E5}\u{671F}\u{5FC5}\u{987B}\u{65E9}\u{4E8E}\u{7ED3}\u{675F}\u{65E5}\u{671F}\u{3002}`,
|
|
210
|
+
"rangeUnderflow": (args)=>`\u{503C}\u{5FC5}\u{987B}\u{662F} ${args.minValue} \u{6216}\u{66F4}\u{665A}\u{65E5}\u{671F}\u{3002}`,
|
|
211
|
+
"unavailableDate": `\u{6240}\u{9009}\u{65E5}\u{671F}\u{4E0D}\u{53EF}\u{7528}\u{3002}`
|
|
212
|
+
},
|
|
213
|
+
"zh-TW": {
|
|
214
|
+
"rangeOverflow": (args)=>`\u{503C}\u{5FC5}\u{9808}\u{662F} ${args.maxValue} \u{6216}\u{66F4}\u{65E9}\u{3002}`,
|
|
215
|
+
"rangeReversed": `\u{958B}\u{59CB}\u{65E5}\u{671F}\u{5FC5}\u{9808}\u{5728}\u{7D50}\u{675F}\u{65E5}\u{671F}\u{4E4B}\u{524D}\u{3002}`,
|
|
216
|
+
"rangeUnderflow": (args)=>`\u{503C}\u{5FC5}\u{9808}\u{662F} ${args.minValue} \u{6216}\u{66F4}\u{665A}\u{3002}`,
|
|
217
|
+
"unavailableDate": `\u{6240}\u{9078}\u{65E5}\u{671F}\u{7121}\u{6CD5}\u{4F7F}\u{7528}\u{3002}`
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const DEFAULT_LOCALE = "en-US";
|
|
222
|
+
|
|
223
|
+
function getMessageForLocale(
|
|
224
|
+
key: DateFieldErrorKey,
|
|
225
|
+
locale: string,
|
|
226
|
+
): DateFieldErrorMessage {
|
|
227
|
+
const exact = errorStrings[locale];
|
|
228
|
+
if (exact && exact[key] != null) return exact[key];
|
|
229
|
+
|
|
230
|
+
const language = locale.split("-")[0];
|
|
231
|
+
const match = Object.keys(errorStrings).find((l) => l.split("-")[0] === language);
|
|
232
|
+
if (match && errorStrings[match][key] != null) return errorStrings[match][key];
|
|
233
|
+
|
|
234
|
+
return errorStrings[DEFAULT_LOCALE][key];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Mirrors LocalizedStringFormatter.format for the datepicker validation messages. */
|
|
238
|
+
export function formatDateFieldError(
|
|
239
|
+
locale: string,
|
|
240
|
+
key: DateFieldErrorKey,
|
|
241
|
+
args?: DateFieldErrorArgs,
|
|
242
|
+
): string {
|
|
243
|
+
const message = getMessageForLocale(key, locale);
|
|
244
|
+
return typeof message === "function" ? message(args ?? {}) : message;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ---------------------------------------------------------------------------
|
|
248
|
+
// Placeholder-text catalog, ported verbatim from @react-stately/datepicker's
|
|
249
|
+
// placeholders.ts. Based on the <input type="date"> placeholders used by Chrome
|
|
250
|
+
// and Firefox; more languages than React Spectrum's usual translations. Default
|
|
251
|
+
// locale is "en".
|
|
252
|
+
// ---------------------------------------------------------------------------
|
|
253
|
+
|
|
254
|
+
const placeholderStrings: Record<string, { year: string; month: string; day: string }> = {
|
|
255
|
+
ach: { year: "mwaka", month: "dwe", day: "nino" },
|
|
256
|
+
af: { year: "jjjj", month: "mm", day: "dd" },
|
|
257
|
+
am: { year: "ዓዓዓዓ", month: "ሚሜ", day: "ቀቀ" },
|
|
258
|
+
an: { year: "aaaa", month: "mm", day: "dd" },
|
|
259
|
+
ar: { year: "سنة", month: "شهر", day: "يوم" },
|
|
260
|
+
ast: { year: "aaaa", month: "mm", day: "dd" },
|
|
261
|
+
az: { year: "iiii", month: "aa", day: "gg" },
|
|
262
|
+
be: { year: "гггг", month: "мм", day: "дд" },
|
|
263
|
+
bg: { year: "гггг", month: "мм", day: "дд" },
|
|
264
|
+
bn: { year: "yyyy", month: "মিমি", day: "dd" },
|
|
265
|
+
br: { year: "bbbb", month: "mm", day: "dd" },
|
|
266
|
+
bs: { year: "gggg", month: "mm", day: "dd" },
|
|
267
|
+
ca: { year: "aaaa", month: "mm", day: "dd" },
|
|
268
|
+
cak: { year: "jjjj", month: "ii", day: "q'q'" },
|
|
269
|
+
ckb: { year: "ساڵ", month: "مانگ", day: "ڕۆژ" },
|
|
270
|
+
cs: { year: "rrrr", month: "mm", day: "dd" },
|
|
271
|
+
cy: { year: "bbbb", month: "mm", day: "dd" },
|
|
272
|
+
da: { year: "åååå", month: "mm", day: "dd" },
|
|
273
|
+
de: { year: "jjjj", month: "mm", day: "tt" },
|
|
274
|
+
dsb: { year: "llll", month: "mm", day: "źź" },
|
|
275
|
+
el: { year: "εεεε", month: "μμ", day: "ηη" },
|
|
276
|
+
en: { year: "yyyy", month: "mm", day: "dd" },
|
|
277
|
+
eo: { year: "jjjj", month: "mm", day: "tt" },
|
|
278
|
+
es: { year: "aaaa", month: "mm", day: "dd" },
|
|
279
|
+
et: { year: "aaaa", month: "kk", day: "pp" },
|
|
280
|
+
eu: { year: "uuuu", month: "hh", day: "ee" },
|
|
281
|
+
fa: { year: "سال", month: "ماه", day: "روز" },
|
|
282
|
+
ff: { year: "hhhh", month: "ll", day: "ññ" },
|
|
283
|
+
fi: { year: "vvvv", month: "kk", day: "pp" },
|
|
284
|
+
fr: { year: "aaaa", month: "mm", day: "jj" },
|
|
285
|
+
fy: { year: "jjjj", month: "mm", day: "dd" },
|
|
286
|
+
ga: { year: "bbbb", month: "mm", day: "ll" },
|
|
287
|
+
gd: { year: "bbbb", month: "mm", day: "ll" },
|
|
288
|
+
gl: { year: "aaaa", month: "mm", day: "dd" },
|
|
289
|
+
he: { year: "שנה", month: "חודש", day: "יום" },
|
|
290
|
+
hr: { year: "gggg", month: "mm", day: "dd" },
|
|
291
|
+
hsb: { year: "llll", month: "mm", day: "dd" },
|
|
292
|
+
hu: { year: "éééé", month: "hh", day: "nn" },
|
|
293
|
+
ia: { year: "aaaa", month: "mm", day: "dd" },
|
|
294
|
+
id: { year: "tttt", month: "bb", day: "hh" },
|
|
295
|
+
is: { year: "áááá", month: "mm", day: "dd" },
|
|
296
|
+
it: { year: "aaaa", month: "mm", day: "gg" },
|
|
297
|
+
ja: { year: "年", month: "月", day: "日" },
|
|
298
|
+
ka: { year: "წწწწ", month: "თთ", day: "რრ" },
|
|
299
|
+
kk: { year: "жжжж", month: "аа", day: "кк" },
|
|
300
|
+
kn: { year: "ವವವವ", month: "ಮಿಮೀ", day: "ದಿದಿ" },
|
|
301
|
+
ko: { year: "연도", month: "월", day: "일" },
|
|
302
|
+
lb: { year: "jjjj", month: "mm", day: "dd" },
|
|
303
|
+
lo: { year: "ປປປປ", month: "ດດ", day: "ວວ" },
|
|
304
|
+
lt: { year: "mmmm", month: "mm", day: "dd" },
|
|
305
|
+
lv: { year: "gggg", month: "mm", day: "dd" },
|
|
306
|
+
meh: { year: "aaaa", month: "mm", day: "dd" },
|
|
307
|
+
ml: { year: "വർഷം", month: "മാസം", day: "തീയതി" },
|
|
308
|
+
ms: { year: "tttt", month: "mm", day: "hh" },
|
|
309
|
+
nb: { year: "åååå", month: "mm", day: "dd" },
|
|
310
|
+
nl: { year: "jjjj", month: "mm", day: "dd" },
|
|
311
|
+
nn: { year: "åååå", month: "mm", day: "dd" },
|
|
312
|
+
no: { year: "åååå", month: "mm", day: "dd" },
|
|
313
|
+
oc: { year: "aaaa", month: "mm", day: "jj" },
|
|
314
|
+
pl: { year: "rrrr", month: "mm", day: "dd" },
|
|
315
|
+
pt: { year: "aaaa", month: "mm", day: "dd" },
|
|
316
|
+
rm: { year: "oooo", month: "mm", day: "dd" },
|
|
317
|
+
ro: { year: "aaaa", month: "ll", day: "zz" },
|
|
318
|
+
ru: { year: "гггг", month: "мм", day: "дд" },
|
|
319
|
+
sc: { year: "aaaa", month: "mm", day: "dd" },
|
|
320
|
+
scn: { year: "aaaa", month: "mm", day: "jj" },
|
|
321
|
+
sk: { year: "rrrr", month: "mm", day: "dd" },
|
|
322
|
+
sl: { year: "llll", month: "mm", day: "dd" },
|
|
323
|
+
sr: { year: "гггг", month: "мм", day: "дд" },
|
|
324
|
+
"sr-Latn": { year: "gggg", month: "mm", day: "dd" },
|
|
325
|
+
sv: { year: "åååå", month: "mm", day: "dd" },
|
|
326
|
+
szl: { year: "rrrr", month: "mm", day: "dd" },
|
|
327
|
+
tg: { year: "сссс", month: "мм", day: "рр" },
|
|
328
|
+
th: { year: "ปปปป", month: "ดด", day: "วว" },
|
|
329
|
+
tr: { year: "yyyy", month: "aa", day: "gg" },
|
|
330
|
+
uk: { year: "рррр", month: "мм", day: "дд" },
|
|
331
|
+
"zh-CN": { year: "年", month: "月", day: "日" },
|
|
332
|
+
"zh-TW": { year: "年", month: "月", day: "日" },
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const PLACEHOLDER_DEFAULT_LOCALE = "en";
|
|
336
|
+
|
|
337
|
+
function getPlaceholderStringForLocale(field: "year" | "month" | "day", locale: string): string {
|
|
338
|
+
const exact = placeholderStrings[locale];
|
|
339
|
+
if (exact) return exact[field];
|
|
340
|
+
|
|
341
|
+
const language = locale.split("-")[0];
|
|
342
|
+
const direct = placeholderStrings[language];
|
|
343
|
+
if (direct) return direct[field];
|
|
344
|
+
|
|
345
|
+
const scan = Object.keys(placeholderStrings).find((l) => l.split("-")[0] === language);
|
|
346
|
+
if (scan) return placeholderStrings[scan][field];
|
|
347
|
+
|
|
348
|
+
return placeholderStrings[PLACEHOLDER_DEFAULT_LOCALE][field];
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/** Mirrors @react-stately/datepicker getPlaceholder. */
|
|
352
|
+
export function getPlaceholder(field: string, value: string, locale: string): string {
|
|
353
|
+
// Use the actual placeholder value for the era and day period fields.
|
|
354
|
+
if (field === "era" || field === "dayPeriod") {
|
|
355
|
+
return value;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (field === "year" || field === "month" || field === "day") {
|
|
359
|
+
return getPlaceholderStringForLocale(field, locale);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// For time fields (e.g. hour, minute, etc.), use two dashes as the placeholder.
|
|
363
|
+
return "––";
|
|
364
|
+
}
|
|
@@ -90,6 +90,37 @@ export class ListCollection<T = unknown> implements Collection<T> {
|
|
|
90
90
|
return this.getItem(key)?.textValue ?? "";
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Filter the collection, returning a new `ListCollection` containing only the
|
|
95
|
+
* item nodes for which `filterFn(node.textValue, node)` returns true. Sections
|
|
96
|
+
* whose children are all filtered out are dropped; surviving sections are
|
|
97
|
+
* rebuilt with their filtered children. Node order is preserved. Mirrors the
|
|
98
|
+
* behaviour of @react-aria/collections `BaseCollection.filter`.
|
|
99
|
+
*/
|
|
100
|
+
filter(filterFn: (nodeValue: string, node: CollectionNode<T>) => boolean): ListCollection<T> {
|
|
101
|
+
const filterNodes = (nodes: CollectionNode<T>[]): CollectionNode<T>[] => {
|
|
102
|
+
const result: CollectionNode<T>[] = [];
|
|
103
|
+
for (const node of nodes) {
|
|
104
|
+
if (node.type === "section") {
|
|
105
|
+
const children = filterNodes(node.childNodes ?? []);
|
|
106
|
+
if (children.length > 0) {
|
|
107
|
+
result.push({ ...node, childNodes: children, hasChildNodes: true });
|
|
108
|
+
}
|
|
109
|
+
} else if (node.type === "item") {
|
|
110
|
+
if (filterFn(node.textValue, node)) {
|
|
111
|
+
result.push(node);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
// Non-item, non-section nodes (e.g. separators) pass through unfiltered.
|
|
115
|
+
result.push(node);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
return new ListCollection<T>(filterNodes(this.nodes));
|
|
122
|
+
}
|
|
123
|
+
|
|
93
124
|
/**
|
|
94
125
|
* Get all items (excluding sections, including items within sections).
|
|
95
126
|
*/
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Based on @react-stately/list.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { createMemo, type Accessor } from "solid-js";
|
|
7
|
+
import { createMemo, createEffect, untrack, type Accessor } from "solid-js";
|
|
8
8
|
import { access, type MaybeAccessor } from "../utils";
|
|
9
9
|
import { ListCollection } from "./ListCollection";
|
|
10
10
|
import type { SelectionState, SelectionPressEvent } from "./createSelectionState";
|
|
@@ -199,6 +199,97 @@ export function createListState<T = unknown>(
|
|
|
199
199
|
};
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
/** A collection filter predicate: `(nodeTextValue, node) => keep`. */
|
|
203
|
+
export type ListFilterFn<T = unknown> = (nodeValue: string, node: CollectionNode<T>) => boolean;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Wraps a {@link ListState} so its collection is filtered by `filterFn`, returning
|
|
207
|
+
* a new (reactive) ListState. Mirrors @react-stately's `UNSTABLE_useFilteredListState`
|
|
208
|
+
* (used by Autocomplete): the filter re-runs as the predicate — which typically
|
|
209
|
+
* closes over the current input value — or the base collection changes; a single
|
|
210
|
+
* stable, collection-aware manager reads the narrowed collection live and shares
|
|
211
|
+
* the base selection/focus state; and the focused key is reset to the nearest
|
|
212
|
+
* surviving item when the current one is filtered out.
|
|
213
|
+
*/
|
|
214
|
+
export function createFilteredListState<T = unknown>(
|
|
215
|
+
state: ListState<T>,
|
|
216
|
+
filterFn: Accessor<ListFilterFn<T> | null | undefined>,
|
|
217
|
+
): ListState<T> {
|
|
218
|
+
const collection: Accessor<Collection<T>> = createMemo(() => {
|
|
219
|
+
const fn = filterFn();
|
|
220
|
+
const base = state.collection();
|
|
221
|
+
return fn && base.filter ? base.filter(fn) : base;
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// One stable manager reading the filtered collection live; shares the base
|
|
225
|
+
// manager's underlying selection/focus state and retains the unfiltered
|
|
226
|
+
// collection as `fullCollection` (so select-all still covers filtered-out keys).
|
|
227
|
+
const selectionManager = state.selectionManager.withCollectionAccessor(() => collection());
|
|
228
|
+
|
|
229
|
+
// Reset the focused key if the item it points at was filtered out, walking
|
|
230
|
+
// forward (then backward) through the previous collection to the nearest
|
|
231
|
+
// surviving, enabled item. Mirrors @react-stately's useFocusedKeyReset.
|
|
232
|
+
let cachedCollection: Collection<T> | null = null;
|
|
233
|
+
createEffect(() => {
|
|
234
|
+
const coll = collection();
|
|
235
|
+
const focusedKey = untrack(() => state.focusedKey());
|
|
236
|
+
if (focusedKey != null && !coll.getItem(focusedKey) && cachedCollection) {
|
|
237
|
+
let key = cachedCollection.getKeyAfter(focusedKey);
|
|
238
|
+
let nextFocusedKey: Key | null = null;
|
|
239
|
+
while (key != null) {
|
|
240
|
+
const node = coll.getItem(key);
|
|
241
|
+
if (node && node.type === "item" && !selectionManager.isDisabled(key)) {
|
|
242
|
+
nextFocusedKey = key;
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
key = cachedCollection.getKeyAfter(key);
|
|
246
|
+
}
|
|
247
|
+
if (nextFocusedKey == null) {
|
|
248
|
+
key = cachedCollection.getKeyBefore(focusedKey);
|
|
249
|
+
while (key != null) {
|
|
250
|
+
const node = coll.getItem(key);
|
|
251
|
+
if (node && node.type === "item" && !selectionManager.isDisabled(key)) {
|
|
252
|
+
nextFocusedKey = key;
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
key = cachedCollection.getKeyBefore(key);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
untrack(() => state.setFocusedKey(nextFocusedKey));
|
|
259
|
+
}
|
|
260
|
+
cachedCollection = coll;
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Spread the base state for type completeness + shared focus fields, then
|
|
264
|
+
// override the collection and every collection-aware operation so navigation,
|
|
265
|
+
// selection, and disabled checks all see the narrowed collection.
|
|
266
|
+
return {
|
|
267
|
+
...state,
|
|
268
|
+
collection,
|
|
269
|
+
selectionManager,
|
|
270
|
+
setFocusedKey: (key: Key | null, childStrategy?: FocusStrategy) =>
|
|
271
|
+
selectionManager.setFocusedKey(key, childStrategy),
|
|
272
|
+
selectionMode: () => selectionManager.selectionMode,
|
|
273
|
+
selectionBehavior: () => selectionManager.selectionBehavior,
|
|
274
|
+
disallowEmptySelection: () => selectionManager.disallowEmptySelection,
|
|
275
|
+
disabledKeys: () => selectionManager.disabledKeys,
|
|
276
|
+
isEmpty: () => selectionManager.isEmpty,
|
|
277
|
+
isSelectAll: () => selectionManager.isSelectAll,
|
|
278
|
+
isSelected: (key: Key) => selectionManager.isSelected(key),
|
|
279
|
+
isDisabled: (key: Key) => selectionManager.isDisabled(key),
|
|
280
|
+
setSelectionBehavior: (behavior: SelectionBehavior) =>
|
|
281
|
+
selectionManager.setSelectionBehavior(behavior),
|
|
282
|
+
toggleSelection: (key: Key) => selectionManager.toggleSelection(key),
|
|
283
|
+
replaceSelection: (key: Key) => selectionManager.replaceSelection(key),
|
|
284
|
+
setSelectedKeys: (keys: Iterable<Key>) => selectionManager.setSelectedKeys(keys),
|
|
285
|
+
selectAll: () => selectionManager.selectAll(),
|
|
286
|
+
clearSelection: () => selectionManager.clearSelection(),
|
|
287
|
+
toggleSelectAll: () => selectionManager.toggleSelectAll(),
|
|
288
|
+
extendSelection: (toKey: Key) => selectionManager.extendSelection(toKey),
|
|
289
|
+
select: (key: Key, e?: SelectionPressEvent) => selectionManager.select(key, e),
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
202
293
|
/**
|
|
203
294
|
* Props for single selection list state.
|
|
204
295
|
*/
|
|
@@ -47,6 +47,37 @@ export function getLastItem<T>(iterable: Iterable<T>): T | undefined {
|
|
|
47
47
|
return lastItem;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
const itemCountCache = new WeakMap<Collection<unknown>, number>();
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Counts the item nodes (recursing into sections, ignoring section headers and
|
|
54
|
+
* other non-item nodes) in a collection. Faithful port of
|
|
55
|
+
* @react-stately/collections `getItemCount`; used by createOption to populate
|
|
56
|
+
* `aria-setsize` when the listbox is virtualized. Cached per (immutable)
|
|
57
|
+
* collection identity, exactly like upstream.
|
|
58
|
+
*/
|
|
59
|
+
export function getItemCount<T>(collection: Collection<T>): number {
|
|
60
|
+
const cached = itemCountCache.get(collection);
|
|
61
|
+
if (cached != null) {
|
|
62
|
+
return cached;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let counter = 0;
|
|
66
|
+
const countItems = (items: Iterable<CollectionNode<T>>) => {
|
|
67
|
+
for (const item of items) {
|
|
68
|
+
if (item.type === "section") {
|
|
69
|
+
countItems(getChildNodes(item, collection));
|
|
70
|
+
} else if (item.type === "item") {
|
|
71
|
+
counter++;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
countItems(collection);
|
|
77
|
+
itemCountCache.set(collection, counter);
|
|
78
|
+
return counter;
|
|
79
|
+
}
|
|
80
|
+
|
|
50
81
|
export function compareNodeOrder<T>(
|
|
51
82
|
collection: Collection<T>,
|
|
52
83
|
a: CollectionNode<T>,
|
package/src/collections/index.ts
CHANGED
|
@@ -21,6 +21,7 @@ export {
|
|
|
21
21
|
getFirstItem,
|
|
22
22
|
getNthItem,
|
|
23
23
|
getLastItem,
|
|
24
|
+
getItemCount,
|
|
24
25
|
compareNodeOrder,
|
|
25
26
|
} from "./getChildNodes";
|
|
26
27
|
|
|
@@ -33,9 +34,11 @@ export {
|
|
|
33
34
|
|
|
34
35
|
export {
|
|
35
36
|
createListState,
|
|
37
|
+
createFilteredListState,
|
|
36
38
|
createSingleSelectListState,
|
|
37
39
|
type ListStateProps,
|
|
38
40
|
type ListState,
|
|
41
|
+
type ListFilterFn,
|
|
39
42
|
type SingleSelectListStateProps,
|
|
40
43
|
type SingleSelectListState,
|
|
41
44
|
} from "./createListState";
|
package/src/collections/types.ts
CHANGED
|
@@ -88,6 +88,16 @@ export interface Collection<T = unknown> extends Iterable<CollectionNode<T>> {
|
|
|
88
88
|
|
|
89
89
|
/** Get the text value for a key. */
|
|
90
90
|
getTextValue(key: Key): string;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Filter the collection, returning a new collection containing only the item
|
|
94
|
+
* nodes for which `filterFn` returns true. Sections whose children are all
|
|
95
|
+
* filtered out are dropped. Mirrors @react-aria/collections
|
|
96
|
+
* `BaseCollection.filter` (and the optional `Collection.filter` in
|
|
97
|
+
* @react-types/shared). Used by Autocomplete to narrow the collection as the
|
|
98
|
+
* user types.
|
|
99
|
+
*/
|
|
100
|
+
filter?(filterFn: (nodeValue: string, node: CollectionNode<T>) => boolean): Collection<T>;
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
/**
|