@keepkit/ui 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -2
- package/dist/index.d.ts +459 -40
- package/dist/index.js +872 -174
- package/dist/index.js.map +1 -1
- package/dist/styles/base.css +5 -0
- package/dist/styles/collection.css +180 -8
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -6,12 +6,32 @@ import {
|
|
|
6
6
|
createKeepKit as createCoreKeepKit
|
|
7
7
|
} from "@keepkit/core/react";
|
|
8
8
|
|
|
9
|
+
// src/hooks/useKeepToastFeedback.ts
|
|
10
|
+
import { useCallback } from "react";
|
|
11
|
+
function useKeepToastFeedback(showToast) {
|
|
12
|
+
return useCallback(
|
|
13
|
+
(event) => {
|
|
14
|
+
if (!("undo" in event)) {
|
|
15
|
+
showToast(event.message);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
showToast(event.message, {
|
|
19
|
+
action: {
|
|
20
|
+
label: event.undoLabel,
|
|
21
|
+
onClick: () => void event.undo()
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
[showToast]
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
9
29
|
// src/hooks/useKeepBackup.ts
|
|
10
30
|
import { useKeepContext } from "@keepkit/core/react";
|
|
11
31
|
import { useRef, useState } from "react";
|
|
12
32
|
|
|
13
33
|
// src/ui-context.tsx
|
|
14
|
-
import { createContext, useContext, useMemo } from "react";
|
|
34
|
+
import { createContext, useCallback as useCallback2, useContext, useMemo } from "react";
|
|
15
35
|
|
|
16
36
|
// src/locales/de.ts
|
|
17
37
|
var DE_LABELS = {
|
|
@@ -49,6 +69,9 @@ var DE_LABELS = {
|
|
|
49
69
|
applyTags: "Tags anwenden",
|
|
50
70
|
savedMessage: "Element gespeichert.",
|
|
51
71
|
removedMessage: "Element entfernt.",
|
|
72
|
+
restoredMessage: "Element wiederhergestellt.",
|
|
73
|
+
syncFailedMessage: "Synchronisierung fehlgeschlagen.",
|
|
74
|
+
stalePrunedMessage: "Nicht verf\xFCgbare Elemente entfernt.",
|
|
52
75
|
undo: "R\xFCckg\xE4ngig",
|
|
53
76
|
undoAvailable: "Element entfernt. R\xFCckg\xE4ngig machen?",
|
|
54
77
|
selectionScope: "Auswahlbereich",
|
|
@@ -125,6 +148,9 @@ var EN_LABELS = {
|
|
|
125
148
|
applyTags: "Apply tags",
|
|
126
149
|
savedMessage: "Item saved.",
|
|
127
150
|
removedMessage: "Item removed.",
|
|
151
|
+
restoredMessage: "Item restored.",
|
|
152
|
+
syncFailedMessage: "Sync failed.",
|
|
153
|
+
stalePrunedMessage: "Unavailable items removed.",
|
|
128
154
|
undo: "Undo",
|
|
129
155
|
undoAvailable: "Item removed. Undo?",
|
|
130
156
|
selectionScope: "Selection scope",
|
|
@@ -201,6 +227,9 @@ var ES_LABELS = {
|
|
|
201
227
|
applyTags: "Aplicar etiquetas",
|
|
202
228
|
savedMessage: "Elemento guardado.",
|
|
203
229
|
removedMessage: "Elemento eliminado.",
|
|
230
|
+
restoredMessage: "Elemento restaurado.",
|
|
231
|
+
syncFailedMessage: "Error de sincronizaci\xF3n.",
|
|
232
|
+
stalePrunedMessage: "Elementos no disponibles eliminados.",
|
|
204
233
|
undo: "Deshacer",
|
|
205
234
|
undoAvailable: "Elemento eliminado. \xBFDeshacer?",
|
|
206
235
|
selectionScope: "\xC1mbito de selecci\xF3n",
|
|
@@ -277,6 +306,9 @@ var FIL_LABELS = {
|
|
|
277
306
|
applyTags: "Ilapat ang mga tag",
|
|
278
307
|
savedMessage: "Na-save ang item.",
|
|
279
308
|
removedMessage: "Inalis ang item.",
|
|
309
|
+
restoredMessage: "Naibalik ang item.",
|
|
310
|
+
syncFailedMessage: "Hindi nagtagumpay ang pag-sync.",
|
|
311
|
+
stalePrunedMessage: "Inalis ang mga hindi available na item.",
|
|
280
312
|
undo: "I-undo",
|
|
281
313
|
undoAvailable: "Inalis ang item. I-undo?",
|
|
282
314
|
selectionScope: "Saklaw ng pagpili",
|
|
@@ -353,6 +385,9 @@ var FR_LABELS = {
|
|
|
353
385
|
applyTags: "Appliquer les \xE9tiquettes",
|
|
354
386
|
savedMessage: "\xC9l\xE9ment enregistr\xE9.",
|
|
355
387
|
removedMessage: "\xC9l\xE9ment supprim\xE9.",
|
|
388
|
+
restoredMessage: "\xC9l\xE9ment restaur\xE9.",
|
|
389
|
+
syncFailedMessage: "\xC9chec de la synchronisation.",
|
|
390
|
+
stalePrunedMessage: "\xC9l\xE9ments indisponibles supprim\xE9s.",
|
|
356
391
|
undo: "Annuler",
|
|
357
392
|
undoAvailable: "\xC9l\xE9ment supprim\xE9. Annuler ?",
|
|
358
393
|
selectionScope: "Port\xE9e de la s\xE9lection",
|
|
@@ -429,6 +464,9 @@ var ID_LABELS = {
|
|
|
429
464
|
applyTags: "Terapkan tag",
|
|
430
465
|
savedMessage: "Item tersimpan.",
|
|
431
466
|
removedMessage: "Item dihapus.",
|
|
467
|
+
restoredMessage: "Item dipulihkan.",
|
|
468
|
+
syncFailedMessage: "Sinkronisasi gagal.",
|
|
469
|
+
stalePrunedMessage: "Item yang tidak tersedia dihapus.",
|
|
432
470
|
undo: "Urungkan",
|
|
433
471
|
undoAvailable: "Item dihapus. Urungkan?",
|
|
434
472
|
selectionScope: "Cakupan pilihan",
|
|
@@ -505,6 +543,9 @@ var IT_LABELS = {
|
|
|
505
543
|
applyTags: "Applica tag",
|
|
506
544
|
savedMessage: "Elemento salvato.",
|
|
507
545
|
removedMessage: "Elemento rimosso.",
|
|
546
|
+
restoredMessage: "Elemento ripristinato.",
|
|
547
|
+
syncFailedMessage: "Sincronizzazione non riuscita.",
|
|
548
|
+
stalePrunedMessage: "Elementi non disponibili rimossi.",
|
|
508
549
|
undo: "Annulla",
|
|
509
550
|
undoAvailable: "Elemento rimosso. Annullare?",
|
|
510
551
|
selectionScope: "Ambito della selezione",
|
|
@@ -581,6 +622,9 @@ var JA_LABELS = {
|
|
|
581
622
|
applyTags: "\u30BF\u30B0\u3092\u9069\u7528",
|
|
582
623
|
savedMessage: "\u30A2\u30A4\u30C6\u30E0\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F\u3002",
|
|
583
624
|
removedMessage: "\u30A2\u30A4\u30C6\u30E0\u3092\u524A\u9664\u3057\u307E\u3057\u305F\u3002",
|
|
625
|
+
restoredMessage: "\u30A2\u30A4\u30C6\u30E0\u3092\u5FA9\u5143\u3057\u307E\u3057\u305F\u3002",
|
|
626
|
+
syncFailedMessage: "\u540C\u671F\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002",
|
|
627
|
+
stalePrunedMessage: "\u5229\u7528\u3067\u304D\u306A\u3044\u30A2\u30A4\u30C6\u30E0\u3092\u524A\u9664\u3057\u307E\u3057\u305F\u3002",
|
|
584
628
|
undo: "\u5143\u306B\u623B\u3059",
|
|
585
629
|
undoAvailable: "\u30A2\u30A4\u30C6\u30E0\u3092\u524A\u9664\u3057\u307E\u3057\u305F\u3002\u5143\u306B\u623B\u3057\u307E\u3059\u304B\uFF1F",
|
|
586
630
|
selectionScope: "\u9078\u629E\u7BC4\u56F2",
|
|
@@ -657,6 +701,9 @@ var KO_LABELS = {
|
|
|
657
701
|
applyTags: "\uD0DC\uADF8 \uC801\uC6A9",
|
|
658
702
|
savedMessage: "\uD56D\uBAA9\uC744 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4.",
|
|
659
703
|
removedMessage: "\uD56D\uBAA9\uC744 \uC0AD\uC81C\uD588\uC2B5\uB2C8\uB2E4.",
|
|
704
|
+
restoredMessage: "\uD56D\uBAA9\uC744 \uBCF5\uC6D0\uD588\uC2B5\uB2C8\uB2E4.",
|
|
705
|
+
syncFailedMessage: "\uB3D9\uAE30\uD654\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
|
|
706
|
+
stalePrunedMessage: "\uC0AC\uC6A9\uD560 \uC218 \uC5C6\uB294 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD588\uC2B5\uB2C8\uB2E4.",
|
|
660
707
|
undo: "\uC2E4\uD589 \uCDE8\uC18C",
|
|
661
708
|
undoAvailable: "\uD56D\uBAA9\uC744 \uC0AD\uC81C\uD588\uC2B5\uB2C8\uB2E4. \uC2E4\uD589 \uCDE8\uC18C\uD560\uAE4C\uC694?",
|
|
662
709
|
selectionScope: "\uC120\uD0DD \uBC94\uC704",
|
|
@@ -733,6 +780,9 @@ var MS_LABELS = {
|
|
|
733
780
|
applyTags: "Gunakan tag",
|
|
734
781
|
savedMessage: "Item disimpan.",
|
|
735
782
|
removedMessage: "Item dibuang.",
|
|
783
|
+
restoredMessage: "Item dipulihkan.",
|
|
784
|
+
syncFailedMessage: "Penyegerakan gagal.",
|
|
785
|
+
stalePrunedMessage: "Item yang tidak tersedia dibuang.",
|
|
736
786
|
undo: "Buat asal",
|
|
737
787
|
undoAvailable: "Item dibuang. Buat asal?",
|
|
738
788
|
selectionScope: "Skop pilihan",
|
|
@@ -809,6 +859,9 @@ var PT_BR_LABELS = {
|
|
|
809
859
|
applyTags: "Aplicar tags",
|
|
810
860
|
savedMessage: "Item salvo.",
|
|
811
861
|
removedMessage: "Item removido.",
|
|
862
|
+
restoredMessage: "Item restaurado.",
|
|
863
|
+
syncFailedMessage: "Falha na sincroniza\xE7\xE3o.",
|
|
864
|
+
stalePrunedMessage: "Itens indispon\xEDveis removidos.",
|
|
812
865
|
undo: "Desfazer",
|
|
813
866
|
undoAvailable: "Item removido. Desfazer?",
|
|
814
867
|
selectionScope: "Escopo da sele\xE7\xE3o",
|
|
@@ -885,6 +938,9 @@ var RU_LABELS = {
|
|
|
885
938
|
applyTags: "\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C \u0442\u0435\u0433\u0438",
|
|
886
939
|
savedMessage: "\u042D\u043B\u0435\u043C\u0435\u043D\u0442 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D.",
|
|
887
940
|
removedMessage: "\u042D\u043B\u0435\u043C\u0435\u043D\u0442 \u0443\u0434\u0430\u043B\u0451\u043D.",
|
|
941
|
+
restoredMessage: "\u042D\u043B\u0435\u043C\u0435\u043D\u0442 \u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D.",
|
|
942
|
+
syncFailedMessage: "\u0421\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0430\u0446\u0438\u044F \u043D\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0430.",
|
|
943
|
+
stalePrunedMessage: "\u041D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B \u0443\u0434\u0430\u043B\u0435\u043D\u044B.",
|
|
888
944
|
undo: "\u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C",
|
|
889
945
|
undoAvailable: "\u042D\u043B\u0435\u043C\u0435\u043D\u0442 \u0443\u0434\u0430\u043B\u0451\u043D. \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C?",
|
|
890
946
|
selectionScope: "\u041E\u0431\u043B\u0430\u0441\u0442\u044C \u0432\u044B\u0431\u043E\u0440\u0430",
|
|
@@ -961,6 +1017,9 @@ var TH_LABELS = {
|
|
|
961
1017
|
applyTags: "\u0E43\u0E0A\u0E49\u0E41\u0E17\u0E47\u0E01",
|
|
962
1018
|
savedMessage: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27",
|
|
963
1019
|
removedMessage: "\u0E25\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27",
|
|
1020
|
+
restoredMessage: "\u0E01\u0E39\u0E49\u0E04\u0E37\u0E19\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27",
|
|
1021
|
+
syncFailedMessage: "\u0E0B\u0E34\u0E07\u0E04\u0E4C\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",
|
|
1022
|
+
stalePrunedMessage: "\u0E25\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E43\u0E0A\u0E49\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E41\u0E25\u0E49\u0E27",
|
|
964
1023
|
undo: "\u0E40\u0E25\u0E34\u0E01\u0E17\u0E33",
|
|
965
1024
|
undoAvailable: "\u0E25\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27 \u0E15\u0E49\u0E2D\u0E07\u0E01\u0E32\u0E23\u0E40\u0E25\u0E34\u0E01\u0E17\u0E33\u0E2B\u0E23\u0E37\u0E2D\u0E44\u0E21\u0E48",
|
|
966
1025
|
selectionScope: "\u0E02\u0E2D\u0E1A\u0E40\u0E02\u0E15\u0E01\u0E32\u0E23\u0E40\u0E25\u0E37\u0E2D\u0E01",
|
|
@@ -1037,6 +1096,9 @@ var VI_LABELS = {
|
|
|
1037
1096
|
applyTags: "\xC1p d\u1EE5ng th\u1EBB",
|
|
1038
1097
|
savedMessage: "\u0110\xE3 l\u01B0u m\u1EE5c.",
|
|
1039
1098
|
removedMessage: "\u0110\xE3 x\xF3a m\u1EE5c.",
|
|
1099
|
+
restoredMessage: "\u0110\xE3 kh\xF4i ph\u1EE5c m\u1EE5c.",
|
|
1100
|
+
syncFailedMessage: "\u0110\u1ED3ng b\u1ED9 kh\xF4ng th\xE0nh c\xF4ng.",
|
|
1101
|
+
stalePrunedMessage: "\u0110\xE3 x\xF3a c\xE1c m\u1EE5c kh\xF4ng kh\u1EA3 d\u1EE5ng.",
|
|
1040
1102
|
undo: "Ho\xE0n t\xE1c",
|
|
1041
1103
|
undoAvailable: "\u0110\xE3 x\xF3a m\u1EE5c. Ho\xE0n t\xE1c?",
|
|
1042
1104
|
selectionScope: "Ph\u1EA1m vi l\u1EF1a ch\u1ECDn",
|
|
@@ -1113,6 +1175,9 @@ var ZH_HANS_LABELS = {
|
|
|
1113
1175
|
applyTags: "\u5E94\u7528\u6807\u7B7E",
|
|
1114
1176
|
savedMessage: "\u9879\u76EE\u5DF2\u4FDD\u5B58\u3002",
|
|
1115
1177
|
removedMessage: "\u9879\u76EE\u5DF2\u5220\u9664\u3002",
|
|
1178
|
+
restoredMessage: "\u9879\u76EE\u5DF2\u6062\u590D\u3002",
|
|
1179
|
+
syncFailedMessage: "\u540C\u6B65\u5931\u8D25\u3002",
|
|
1180
|
+
stalePrunedMessage: "\u4E0D\u53EF\u7528\u9879\u76EE\u5DF2\u5220\u9664\u3002",
|
|
1116
1181
|
undo: "\u64A4\u9500",
|
|
1117
1182
|
undoAvailable: "\u9879\u76EE\u5DF2\u5220\u9664\u3002\u8981\u64A4\u9500\u5417\uFF1F",
|
|
1118
1183
|
selectionScope: "\u9009\u62E9\u8303\u56F4",
|
|
@@ -1189,6 +1254,9 @@ var ZH_HANT_LABELS = {
|
|
|
1189
1254
|
applyTags: "\u5957\u7528\u6A19\u7C64",
|
|
1190
1255
|
savedMessage: "\u9805\u76EE\u5DF2\u5132\u5B58\u3002",
|
|
1191
1256
|
removedMessage: "\u9805\u76EE\u5DF2\u522A\u9664\u3002",
|
|
1257
|
+
restoredMessage: "\u9805\u76EE\u5DF2\u9084\u539F\u3002",
|
|
1258
|
+
syncFailedMessage: "\u540C\u6B65\u5931\u6557\u3002",
|
|
1259
|
+
stalePrunedMessage: "\u7121\u6CD5\u4F7F\u7528\u7684\u9805\u76EE\u5DF2\u522A\u9664\u3002",
|
|
1192
1260
|
undo: "\u5FA9\u539F",
|
|
1193
1261
|
undoAvailable: "\u9805\u76EE\u5DF2\u522A\u9664\u3002\u8981\u5FA9\u539F\u55CE\uFF1F",
|
|
1194
1262
|
selectionScope: "\u9078\u53D6\u7BC4\u570D",
|
|
@@ -1291,14 +1359,29 @@ function getKeepLocaleLabels(locale) {
|
|
|
1291
1359
|
// src/ui-context.tsx
|
|
1292
1360
|
import { jsx } from "react/jsx-runtime";
|
|
1293
1361
|
var DEFAULT_LABELS = KEEP_LOCALE_LABELS.en;
|
|
1294
|
-
var KeepUiLabelsContext = createContext({
|
|
1295
|
-
|
|
1362
|
+
var KeepUiLabelsContext = createContext({
|
|
1363
|
+
labels: DEFAULT_LABELS,
|
|
1364
|
+
emitFeedback: () => void 0
|
|
1365
|
+
});
|
|
1366
|
+
function KeepUiProvider({
|
|
1367
|
+
labels,
|
|
1368
|
+
locale,
|
|
1369
|
+
labelResolver,
|
|
1370
|
+
onFeedback,
|
|
1371
|
+
children
|
|
1372
|
+
}) {
|
|
1373
|
+
const emitFeedback = useCallback2(
|
|
1374
|
+
(event) => {
|
|
1375
|
+
onFeedback?.(event);
|
|
1376
|
+
},
|
|
1377
|
+
[onFeedback]
|
|
1378
|
+
);
|
|
1296
1379
|
const value = useMemo(() => {
|
|
1297
1380
|
const resolvedLocale = normalizeKeepLocale(locale);
|
|
1298
1381
|
const dictionary = getKeepLocaleLabels(resolvedLocale);
|
|
1299
1382
|
const resolved = { ...DEFAULT_LABELS, ...dictionary, ...labels };
|
|
1300
|
-
return { locale: locale ?? resolvedLocale, labels: resolved, customLabels: labels, labelResolver };
|
|
1301
|
-
}, [labelResolver, labels, locale]);
|
|
1383
|
+
return { locale: locale ?? resolvedLocale, labels: resolved, customLabels: labels, labelResolver, emitFeedback };
|
|
1384
|
+
}, [emitFeedback, labelResolver, labels, locale]);
|
|
1302
1385
|
return /* @__PURE__ */ jsx(KeepUiLabelsContext.Provider, { value, children });
|
|
1303
1386
|
}
|
|
1304
1387
|
function useKeepUiLabels() {
|
|
@@ -1308,6 +1391,10 @@ function useUiLabel(key, override) {
|
|
|
1308
1391
|
const context = useKeepUiLabels();
|
|
1309
1392
|
return override ?? context.customLabels?.[key] ?? context.labelResolver?.(key, { locale: context.locale }) ?? context.labels[key];
|
|
1310
1393
|
}
|
|
1394
|
+
function useKeepUiFeedback() {
|
|
1395
|
+
const { emitFeedback } = useKeepUiLabels();
|
|
1396
|
+
return useCallback2((event) => emitFeedback(event), [emitFeedback]);
|
|
1397
|
+
}
|
|
1311
1398
|
|
|
1312
1399
|
// src/hooks/useKeepBackup.ts
|
|
1313
1400
|
function useKeepBackup({ filename, onExport, onImported }) {
|
|
@@ -1453,9 +1540,49 @@ import { useState as useState2 } from "react";
|
|
|
1453
1540
|
// src/shared.tsx
|
|
1454
1541
|
import {
|
|
1455
1542
|
cloneElement,
|
|
1456
|
-
|
|
1543
|
+
createContext as createContext2,
|
|
1544
|
+
isValidElement,
|
|
1545
|
+
useContext as useContext2
|
|
1457
1546
|
} from "react";
|
|
1458
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1547
|
+
import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
|
|
1548
|
+
var KeepSearchQueryContext = createContext2(void 0);
|
|
1549
|
+
function KeepSearchQueryProvider({ query, children }) {
|
|
1550
|
+
return /* @__PURE__ */ jsx3(KeepSearchQueryContext.Provider, { value: query, children });
|
|
1551
|
+
}
|
|
1552
|
+
function useKeepSearchQuery() {
|
|
1553
|
+
return useContext2(KeepSearchQueryContext);
|
|
1554
|
+
}
|
|
1555
|
+
function KeepHighlight({ children, query }) {
|
|
1556
|
+
const contextQuery = useKeepSearchQuery();
|
|
1557
|
+
const resolvedQuery = query ?? contextQuery;
|
|
1558
|
+
if (typeof children !== "string" || !resolvedQuery?.trim()) return children ?? null;
|
|
1559
|
+
return highlightText(children, resolvedQuery);
|
|
1560
|
+
}
|
|
1561
|
+
function highlightText(text, query) {
|
|
1562
|
+
const normalizedQuery = query.trim();
|
|
1563
|
+
if (!normalizedQuery) return text;
|
|
1564
|
+
const matcher = new RegExp(escapeRegExp(normalizedQuery), "gi");
|
|
1565
|
+
const parts = [];
|
|
1566
|
+
let lastIndex = 0;
|
|
1567
|
+
let matchIndex = 0;
|
|
1568
|
+
while (true) {
|
|
1569
|
+
const match = matcher.exec(text);
|
|
1570
|
+
if (match === null) break;
|
|
1571
|
+
const index = match.index;
|
|
1572
|
+
if (index > lastIndex) parts.push(text.slice(lastIndex, index));
|
|
1573
|
+
parts.push(
|
|
1574
|
+
/* @__PURE__ */ jsx3("mark", { className: "keep-highlight", "data-highlight": "true", children: match[0] }, `highlight-${matchIndex}`)
|
|
1575
|
+
);
|
|
1576
|
+
lastIndex = index + match[0].length;
|
|
1577
|
+
matchIndex += 1;
|
|
1578
|
+
}
|
|
1579
|
+
if (lastIndex === 0) return text;
|
|
1580
|
+
if (lastIndex < text.length) parts.push(text.slice(lastIndex));
|
|
1581
|
+
return /* @__PURE__ */ jsx3(Fragment, { children: parts });
|
|
1582
|
+
}
|
|
1583
|
+
function escapeRegExp(value) {
|
|
1584
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1585
|
+
}
|
|
1459
1586
|
function toKeepButtonItem(item) {
|
|
1460
1587
|
return {
|
|
1461
1588
|
id: item.id,
|
|
@@ -1614,7 +1741,7 @@ function getItemLabel(item) {
|
|
|
1614
1741
|
}
|
|
1615
1742
|
|
|
1616
1743
|
// src/KeepBulkActions.tsx
|
|
1617
|
-
import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1744
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1618
1745
|
function KeepBulkActions({
|
|
1619
1746
|
query,
|
|
1620
1747
|
selectedIds: controlledSelectedIds,
|
|
@@ -1637,7 +1764,7 @@ function KeepBulkActions({
|
|
|
1637
1764
|
controlledScope,
|
|
1638
1765
|
onSelectionScopeChange
|
|
1639
1766
|
});
|
|
1640
|
-
const body = render ? render(state) : typeof children === "function" ? children(state) : children ?? /* @__PURE__ */ jsxs2(
|
|
1767
|
+
const body = render ? render(state) : typeof children === "function" ? children(state) : children ?? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1641
1768
|
/* @__PURE__ */ jsxs2("fieldset", { children: [
|
|
1642
1769
|
/* @__PURE__ */ jsx5("legend", { children: labels.selectItems }),
|
|
1643
1770
|
/* @__PURE__ */ jsxs2("label", { children: [
|
|
@@ -1732,47 +1859,91 @@ function KeepBulkActions({
|
|
|
1732
1859
|
import {
|
|
1733
1860
|
KeepButton as CoreKeepButton
|
|
1734
1861
|
} from "@keepkit/core/react";
|
|
1735
|
-
import { createElement } from "react";
|
|
1862
|
+
import { createElement, useEffect, useRef as useRef2 } from "react";
|
|
1736
1863
|
|
|
1737
1864
|
// src/hooks/useKeepButton.ts
|
|
1738
1865
|
import { useKeepItem } from "@keepkit/core/react";
|
|
1739
1866
|
function useKeepButton({ item, labels, icons, children }) {
|
|
1740
1867
|
return {
|
|
1741
1868
|
buttonState: useKeepItem(item),
|
|
1869
|
+
emitFeedback: useKeepUiFeedback(),
|
|
1742
1870
|
customStateLabel: labels?.loading !== void 0 || labels?.error !== void 0 || icons !== void 0 && children === void 0,
|
|
1743
1871
|
labels: {
|
|
1744
1872
|
save: useUiLabel("save", typeof labels?.unsaved === "string" ? labels.unsaved : void 0),
|
|
1745
1873
|
saved: useUiLabel("saved", typeof labels?.saved === "string" ? labels.saved : void 0),
|
|
1746
1874
|
loading: useUiLabel("loading", typeof labels?.loading === "string" ? labels.loading : void 0),
|
|
1747
|
-
error: useUiLabel("error", typeof labels?.error === "string" ? labels.error : void 0)
|
|
1875
|
+
error: useUiLabel("error", typeof labels?.error === "string" ? labels.error : void 0),
|
|
1876
|
+
savedMessage: useUiLabel("savedMessage"),
|
|
1877
|
+
removedMessage: useUiLabel("removedMessage"),
|
|
1878
|
+
restoredMessage: useUiLabel("restoredMessage"),
|
|
1879
|
+
undo: useUiLabel("undo")
|
|
1748
1880
|
}
|
|
1749
1881
|
};
|
|
1750
1882
|
}
|
|
1751
1883
|
|
|
1752
1884
|
// src/KeepButton.tsx
|
|
1753
|
-
import { Fragment as
|
|
1885
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1754
1886
|
function KeepButton({
|
|
1755
1887
|
labels,
|
|
1756
1888
|
icons,
|
|
1757
1889
|
iconOnly = false,
|
|
1758
1890
|
showLabel = true,
|
|
1759
1891
|
iconClassName,
|
|
1892
|
+
onClick,
|
|
1893
|
+
onToggleError,
|
|
1760
1894
|
...props
|
|
1761
1895
|
}) {
|
|
1762
1896
|
const view = useKeepButton({ item: props.item, labels, icons, children: props.children });
|
|
1897
|
+
const pendingToggle = useRef2(null);
|
|
1898
|
+
useEffect(() => {
|
|
1899
|
+
const pending = pendingToggle.current;
|
|
1900
|
+
if (!pending || view.buttonState.isMutating || pending.wasSaved === view.buttonState.isSaved) return;
|
|
1901
|
+
pendingToggle.current = null;
|
|
1902
|
+
if (view.buttonState.isSaved && view.buttonState.item) {
|
|
1903
|
+
view.emitFeedback({ type: "item-saved", item: view.buttonState.item, message: view.labels.savedMessage });
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
if (!pending.item) return;
|
|
1907
|
+
const removedItem = pending.item;
|
|
1908
|
+
view.emitFeedback({
|
|
1909
|
+
type: "item-removed",
|
|
1910
|
+
item: removedItem,
|
|
1911
|
+
message: view.labels.removedMessage,
|
|
1912
|
+
undoLabel: view.labels.undo,
|
|
1913
|
+
undo: async () => {
|
|
1914
|
+
await view.buttonState.save();
|
|
1915
|
+
view.emitFeedback({
|
|
1916
|
+
type: "item-restored",
|
|
1917
|
+
item: removedItem,
|
|
1918
|
+
items: [removedItem],
|
|
1919
|
+
message: view.labels.restoredMessage
|
|
1920
|
+
});
|
|
1921
|
+
}
|
|
1922
|
+
});
|
|
1923
|
+
}, [view]);
|
|
1763
1924
|
const getStateContent = (state) => {
|
|
1764
1925
|
if (typeof props.children === "function") return props.children(state);
|
|
1765
1926
|
if (props.children !== void 0) return props.children;
|
|
1766
1927
|
const label = state.error ? labels?.error ?? view.labels.error : state.isMutating ? labels?.loading ?? view.labels.loading : state.isSaved ? labels?.saved ?? view.labels.saved : labels?.unsaved ?? view.labels.save;
|
|
1767
1928
|
if (!icons) return label;
|
|
1768
1929
|
const icon = state.error ? icons.error : state.isMutating ? icons.loading : state.isSaved ? icons.remove ?? icons.saved : icons.save;
|
|
1769
|
-
return /* @__PURE__ */ jsxs3(
|
|
1930
|
+
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
1770
1931
|
renderIcon(icon, iconClassName),
|
|
1771
1932
|
showLabel && !iconOnly ? label : null
|
|
1772
1933
|
] });
|
|
1773
1934
|
};
|
|
1774
1935
|
const sharedProps = {
|
|
1775
1936
|
...props,
|
|
1937
|
+
onClick: (event) => {
|
|
1938
|
+
onClick?.(event);
|
|
1939
|
+
if (!event.defaultPrevented) {
|
|
1940
|
+
pendingToggle.current = { wasSaved: view.buttonState.isSaved, item: view.buttonState.item };
|
|
1941
|
+
}
|
|
1942
|
+
},
|
|
1943
|
+
onToggleError: (error) => {
|
|
1944
|
+
pendingToggle.current = null;
|
|
1945
|
+
onToggleError?.(error);
|
|
1946
|
+
},
|
|
1776
1947
|
"data-keepkit": "button",
|
|
1777
1948
|
"data-keep-action": "toggle-save",
|
|
1778
1949
|
"data-has-custom-icon": icons ? "true" : void 0,
|
|
@@ -1784,7 +1955,7 @@ function KeepButton({
|
|
|
1784
1955
|
unsavedAriaLabel: labels?.unsavedAriaLabel ?? props.unsavedAriaLabel
|
|
1785
1956
|
};
|
|
1786
1957
|
if (!view.customStateLabel) return /* @__PURE__ */ jsx6(CoreKeepButton, { ...sharedProps });
|
|
1787
|
-
return /* @__PURE__ */ jsx6(CoreKeepButton, { ...sharedProps, children: (state) => /* @__PURE__ */ jsx6(
|
|
1958
|
+
return /* @__PURE__ */ jsx6(CoreKeepButton, { ...sharedProps, children: (state) => /* @__PURE__ */ jsx6(Fragment3, { children: getStateContent(state) }) });
|
|
1788
1959
|
}
|
|
1789
1960
|
function renderIcon(icon, className) {
|
|
1790
1961
|
if (typeof icon === "function") return createElement(icon, { "aria-hidden": true, className });
|
|
@@ -1804,7 +1975,7 @@ import {
|
|
|
1804
1975
|
decodeKeepListQuery,
|
|
1805
1976
|
encodeKeepListQuery
|
|
1806
1977
|
} from "@keepkit/core/core";
|
|
1807
|
-
import { useEffect, useRef as
|
|
1978
|
+
import { useEffect as useEffect2, useRef as useRef3 } from "react";
|
|
1808
1979
|
function createNextPagesRouterAdapter(router) {
|
|
1809
1980
|
const getUrl = () => router.asPath ?? (typeof window === "undefined" ? "/" : window.location.href);
|
|
1810
1981
|
return {
|
|
@@ -1825,13 +1996,13 @@ function useKeepUrlSync({
|
|
|
1825
1996
|
options = {},
|
|
1826
1997
|
adapter: providedAdapter
|
|
1827
1998
|
}) {
|
|
1828
|
-
const browserAdapterRef =
|
|
1999
|
+
const browserAdapterRef = useRef3(getBrowserAdapter());
|
|
1829
2000
|
const adapter = providedAdapter ?? browserAdapterRef.current;
|
|
1830
|
-
const onQueryChangeRef =
|
|
2001
|
+
const onQueryChangeRef = useRef3(onQueryChange);
|
|
1831
2002
|
onQueryChangeRef.current = onQueryChange;
|
|
1832
|
-
const skipWriteRef =
|
|
2003
|
+
const skipWriteRef = useRef3(true);
|
|
1833
2004
|
const params = options.params;
|
|
1834
|
-
|
|
2005
|
+
useEffect2(() => {
|
|
1835
2006
|
if (!enabled) return;
|
|
1836
2007
|
const read = () => {
|
|
1837
2008
|
const url = adapter.getUrl();
|
|
@@ -1848,7 +2019,7 @@ function useKeepUrlSync({
|
|
|
1848
2019
|
read();
|
|
1849
2020
|
return adapter.subscribe?.(read);
|
|
1850
2021
|
}, [adapter, enabled, params]);
|
|
1851
|
-
|
|
2022
|
+
useEffect2(() => {
|
|
1852
2023
|
if (!enabled) return;
|
|
1853
2024
|
if (skipWriteRef.current) {
|
|
1854
2025
|
skipWriteRef.current = false;
|
|
@@ -1966,9 +2137,79 @@ function useKeepListView(query) {
|
|
|
1966
2137
|
};
|
|
1967
2138
|
}
|
|
1968
2139
|
|
|
2140
|
+
// src/hooks/useRovingTabIndex.ts
|
|
2141
|
+
import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef4 } from "react";
|
|
2142
|
+
function useRovingTabIndex() {
|
|
2143
|
+
const ref = useRef4(null);
|
|
2144
|
+
const getItems = useCallback3(() => {
|
|
2145
|
+
const root = ref.current;
|
|
2146
|
+
if (!root) return [];
|
|
2147
|
+
return Array.from(root.querySelectorAll('[data-keepkit="card"]')).filter(
|
|
2148
|
+
(item) => item.getAttribute("aria-hidden") !== "true" && item.getAttribute("data-roving-disabled") !== "true"
|
|
2149
|
+
);
|
|
2150
|
+
}, []);
|
|
2151
|
+
const syncTabIndices = useCallback3(() => {
|
|
2152
|
+
const items = getItems();
|
|
2153
|
+
if (items.length === 0) return;
|
|
2154
|
+
const activeElement = document.activeElement;
|
|
2155
|
+
const activeItem = items.find((item) => item === activeElement || item.contains(activeElement));
|
|
2156
|
+
const activeIndex = activeItem ? items.indexOf(activeItem) : 0;
|
|
2157
|
+
items.forEach((item, index) => {
|
|
2158
|
+
item.tabIndex = index === activeIndex ? 0 : -1;
|
|
2159
|
+
});
|
|
2160
|
+
}, [getItems]);
|
|
2161
|
+
useEffect3(() => {
|
|
2162
|
+
const root = ref.current;
|
|
2163
|
+
if (!root) return;
|
|
2164
|
+
syncTabIndices();
|
|
2165
|
+
const observer = new MutationObserver(syncTabIndices);
|
|
2166
|
+
observer.observe(root, { childList: true, subtree: true });
|
|
2167
|
+
return () => observer.disconnect();
|
|
2168
|
+
}, [syncTabIndices]);
|
|
2169
|
+
const onFocusCapture = useCallback3(
|
|
2170
|
+
(event) => {
|
|
2171
|
+
if (!(event.target instanceof HTMLElement)) return;
|
|
2172
|
+
const item = event.target.closest('[data-keepkit="card"]');
|
|
2173
|
+
if (!item || !ref.current?.contains(item)) return;
|
|
2174
|
+
getItems().forEach((candidate) => {
|
|
2175
|
+
candidate.tabIndex = candidate === item ? 0 : -1;
|
|
2176
|
+
});
|
|
2177
|
+
},
|
|
2178
|
+
[getItems]
|
|
2179
|
+
);
|
|
2180
|
+
const onKeyDown = useCallback3(
|
|
2181
|
+
(event) => {
|
|
2182
|
+
if (event.defaultPrevented) return;
|
|
2183
|
+
const items = getItems();
|
|
2184
|
+
if (!(event.target instanceof HTMLElement)) return;
|
|
2185
|
+
const current = event.target.closest('[data-keepkit="card"]');
|
|
2186
|
+
if (!current || current !== event.target || !ref.current?.contains(current)) return;
|
|
2187
|
+
const currentIndex = items.indexOf(current);
|
|
2188
|
+
if (currentIndex < 0) return;
|
|
2189
|
+
let nextIndex;
|
|
2190
|
+
if (event.key === "Home") nextIndex = 0;
|
|
2191
|
+
if (event.key === "End") nextIndex = items.length - 1;
|
|
2192
|
+
if (event.key === "ArrowRight" || event.key === "ArrowDown")
|
|
2193
|
+
nextIndex = Math.min(currentIndex + 1, items.length - 1);
|
|
2194
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowUp") nextIndex = Math.max(currentIndex - 1, 0);
|
|
2195
|
+
if (nextIndex === void 0) return;
|
|
2196
|
+
event.preventDefault();
|
|
2197
|
+
if (nextIndex === currentIndex) return;
|
|
2198
|
+
items[nextIndex]?.focus();
|
|
2199
|
+
},
|
|
2200
|
+
[getItems]
|
|
2201
|
+
);
|
|
2202
|
+
return { ref, onKeyDown, onFocusCapture };
|
|
2203
|
+
}
|
|
2204
|
+
|
|
1969
2205
|
// src/KeepItemCard.tsx
|
|
1970
2206
|
import {
|
|
1971
|
-
|
|
2207
|
+
createContext as createContext3,
|
|
2208
|
+
createElement as createElement2,
|
|
2209
|
+
isValidElement as isValidElement2,
|
|
2210
|
+
useContext as useContext3,
|
|
2211
|
+
useEffect as useEffect4,
|
|
2212
|
+
useState as useState5
|
|
1972
2213
|
} from "react";
|
|
1973
2214
|
|
|
1974
2215
|
// src/hooks/useKeepItemCard.ts
|
|
@@ -1986,6 +2227,10 @@ function useKeepItemCard(options) {
|
|
|
1986
2227
|
onRemoved
|
|
1987
2228
|
} = options;
|
|
1988
2229
|
const itemState = useKeepItem2(item);
|
|
2230
|
+
const emitFeedback = useKeepUiFeedback();
|
|
2231
|
+
const removedMessage = useUiLabel("removedMessage");
|
|
2232
|
+
const restoredMessage = useUiLabel("restoredMessage");
|
|
2233
|
+
const undoLabel = useUiLabel("undo");
|
|
1989
2234
|
const resolvedTitle = typeof title === "function" ? title(item) : title ?? getTitle?.(item) ?? getMetaTitle(item.meta) ?? item.id;
|
|
1990
2235
|
const imageProps = getImageProps?.(item, resolvedTitle);
|
|
1991
2236
|
const href = typeof hrefOption === "function" ? hrefOption(item) : hrefOption;
|
|
@@ -1993,12 +2238,32 @@ function useKeepItemCard(options) {
|
|
|
1993
2238
|
const isExternalLink = href ? /^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(href) : false;
|
|
1994
2239
|
const statusLabelKey = item.status && item.status !== "available" ? getStatusLabelKey(item.status) : "statusUnknown";
|
|
1995
2240
|
const unavailableLabel = useUiLabel(statusLabelKey);
|
|
2241
|
+
const remove = async () => {
|
|
2242
|
+
const wasSaved = itemState.isSaved;
|
|
2243
|
+
try {
|
|
2244
|
+
await itemState.removeWithUndo();
|
|
2245
|
+
onRemoved?.(item);
|
|
2246
|
+
if (!wasSaved) return;
|
|
2247
|
+
emitFeedback({
|
|
2248
|
+
type: "item-removed",
|
|
2249
|
+
item,
|
|
2250
|
+
message: removedMessage,
|
|
2251
|
+
undoLabel,
|
|
2252
|
+
undo: async () => {
|
|
2253
|
+
await itemState.undo();
|
|
2254
|
+
emitFeedback({ type: "item-restored", item, items: [item], message: restoredMessage });
|
|
2255
|
+
}
|
|
2256
|
+
});
|
|
2257
|
+
} catch (cause) {
|
|
2258
|
+
onRemoveError?.(cause);
|
|
2259
|
+
}
|
|
2260
|
+
};
|
|
1996
2261
|
const state = {
|
|
1997
2262
|
item,
|
|
1998
2263
|
isSaved: itemState.isSaved,
|
|
1999
2264
|
isMutating: itemState.isMutating,
|
|
2000
2265
|
error: itemState.error,
|
|
2001
|
-
remove
|
|
2266
|
+
remove,
|
|
2002
2267
|
status: item.status
|
|
2003
2268
|
};
|
|
2004
2269
|
return {
|
|
@@ -2012,14 +2277,7 @@ function useKeepItemCard(options) {
|
|
|
2012
2277
|
resolvedLinkTarget: linkTargetAttribute ?? (isExternalLink ? "_blank" : void 0),
|
|
2013
2278
|
resolvedLinkRel: linkRel ?? (isExternalLink ? "noreferrer" : void 0),
|
|
2014
2279
|
statusLabel: item.status && item.status !== "available" ? unavailableLabel : void 0,
|
|
2015
|
-
remove
|
|
2016
|
-
try {
|
|
2017
|
-
await itemState.remove();
|
|
2018
|
-
onRemoved?.(item);
|
|
2019
|
-
} catch (cause) {
|
|
2020
|
-
onRemoveError?.(cause);
|
|
2021
|
-
}
|
|
2022
|
-
},
|
|
2280
|
+
remove,
|
|
2023
2281
|
labels: {
|
|
2024
2282
|
save: useUiLabel("save"),
|
|
2025
2283
|
savedAt: useUiLabel("saved"),
|
|
@@ -2055,6 +2313,10 @@ import { useKeepContext as useKeepContext2 } from "@keepkit/core/react";
|
|
|
2055
2313
|
import { useState as useState4 } from "react";
|
|
2056
2314
|
function useKeepStaleNotice({ item, onRetry, onRemoved }) {
|
|
2057
2315
|
const context = useKeepContext2();
|
|
2316
|
+
const emitFeedback = useKeepUiFeedback();
|
|
2317
|
+
const removedMessage = useUiLabel("removedMessage");
|
|
2318
|
+
const restoredMessage = useUiLabel("restoredMessage");
|
|
2319
|
+
const undoLabel = useUiLabel("undo");
|
|
2058
2320
|
const [isRetrying, setIsRetrying] = useState4(false);
|
|
2059
2321
|
const [error, setError] = useState4(null);
|
|
2060
2322
|
async function retry() {
|
|
@@ -2073,6 +2335,16 @@ function useKeepStaleNotice({ item, onRetry, onRemoved }) {
|
|
|
2073
2335
|
try {
|
|
2074
2336
|
await context.removeItemWithUndo(item.id);
|
|
2075
2337
|
onRemoved?.(item);
|
|
2338
|
+
emitFeedback({
|
|
2339
|
+
type: "item-removed",
|
|
2340
|
+
item,
|
|
2341
|
+
message: removedMessage,
|
|
2342
|
+
undoLabel,
|
|
2343
|
+
undo: async () => {
|
|
2344
|
+
await context.undoLastRemoval();
|
|
2345
|
+
emitFeedback({ type: "item-restored", item, items: [item], message: restoredMessage });
|
|
2346
|
+
}
|
|
2347
|
+
});
|
|
2076
2348
|
} catch (cause) {
|
|
2077
2349
|
setError(cause);
|
|
2078
2350
|
}
|
|
@@ -2093,15 +2365,34 @@ function useKeepStaleNotice({ item, onRetry, onRemoved }) {
|
|
|
2093
2365
|
}
|
|
2094
2366
|
function useKeepPruneStale({ statuses, onPruned }) {
|
|
2095
2367
|
const context = useKeepContext2();
|
|
2096
|
-
const
|
|
2368
|
+
const emitFeedback = useKeepUiFeedback();
|
|
2369
|
+
const staleItems = context.items.filter((item) => item.status && statuses.includes(item.status));
|
|
2370
|
+
const staleIds = staleItems.map((item) => item.id);
|
|
2371
|
+
const restoredMessage = useUiLabel("restoredMessage");
|
|
2372
|
+
const prunedMessage = useUiLabel("stalePrunedMessage");
|
|
2373
|
+
const undoLabel = useUiLabel("undo");
|
|
2097
2374
|
return {
|
|
2098
2375
|
staleIds,
|
|
2099
2376
|
isMutating: context.isMutating,
|
|
2100
2377
|
label: useUiLabel("pruneStale"),
|
|
2101
2378
|
prune: async () => {
|
|
2102
2379
|
const ids = [...staleIds];
|
|
2380
|
+
const items = [...staleItems];
|
|
2103
2381
|
await context.removeItemsWithUndo(ids);
|
|
2104
2382
|
onPruned?.(ids);
|
|
2383
|
+
if (items.length > 0) {
|
|
2384
|
+
emitFeedback({
|
|
2385
|
+
type: "stale-pruned",
|
|
2386
|
+
item: items[0],
|
|
2387
|
+
items,
|
|
2388
|
+
message: prunedMessage,
|
|
2389
|
+
undoLabel,
|
|
2390
|
+
undo: async () => {
|
|
2391
|
+
await context.undoLastRemoval();
|
|
2392
|
+
emitFeedback({ type: "item-restored", item: items[0], items, message: restoredMessage });
|
|
2393
|
+
}
|
|
2394
|
+
});
|
|
2395
|
+
}
|
|
2105
2396
|
}
|
|
2106
2397
|
};
|
|
2107
2398
|
}
|
|
@@ -2219,8 +2510,14 @@ function KeepPruneStaleButton({
|
|
|
2219
2510
|
}
|
|
2220
2511
|
|
|
2221
2512
|
// src/KeepItemCard.tsx
|
|
2222
|
-
import { Fragment as
|
|
2223
|
-
|
|
2513
|
+
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2514
|
+
var KeepItemCardContext = createContext3(null);
|
|
2515
|
+
function useKeepItemCardCompound(part) {
|
|
2516
|
+
const context = useContext3(KeepItemCardContext);
|
|
2517
|
+
if (!context) throw new Error(`KeepItemCard.${part} must be rendered inside KeepItemCard.`);
|
|
2518
|
+
return context;
|
|
2519
|
+
}
|
|
2520
|
+
function KeepItemCardRoot({
|
|
2224
2521
|
item,
|
|
2225
2522
|
title,
|
|
2226
2523
|
getTitle,
|
|
@@ -2246,6 +2543,7 @@ function KeepItemCard({
|
|
|
2246
2543
|
linkComponent: LinkComponent,
|
|
2247
2544
|
linkTargetAttribute,
|
|
2248
2545
|
linkRel,
|
|
2546
|
+
highlightQuery,
|
|
2249
2547
|
className,
|
|
2250
2548
|
...rootProps
|
|
2251
2549
|
}) {
|
|
@@ -2260,6 +2558,8 @@ function KeepItemCard({
|
|
|
2260
2558
|
onRemoveError,
|
|
2261
2559
|
onRemoved
|
|
2262
2560
|
});
|
|
2561
|
+
const contextQuery = useKeepSearchQuery();
|
|
2562
|
+
const searchQuery = highlightQuery ?? contextQuery;
|
|
2263
2563
|
const contentChildren = asChild && isValidElement2(children) ? void 0 : children;
|
|
2264
2564
|
function renderLink(content) {
|
|
2265
2565
|
if (!view.href || !view.isAvailable) return content;
|
|
@@ -2272,21 +2572,47 @@ function KeepItemCard({
|
|
|
2272
2572
|
};
|
|
2273
2573
|
return LinkComponent ? /* @__PURE__ */ jsx9(LinkComponent, { ...linkProps }) : /* @__PURE__ */ jsx9("a", { ...linkProps });
|
|
2274
2574
|
}
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2575
|
+
function renderTitle(content) {
|
|
2576
|
+
if (linkTarget !== "title") return content;
|
|
2577
|
+
if (view.isAvailable) return renderLink(content);
|
|
2578
|
+
return view.href ? /* @__PURE__ */ jsx9("span", { "aria-disabled": "true", "data-link-disabled": "true", children: content }) : content;
|
|
2579
|
+
}
|
|
2580
|
+
const resolvedImageProps = view.imageProps ? { ...view.imageProps, alt: imageAlt ?? view.imageProps.alt } : void 0;
|
|
2581
|
+
const imageSource = resolvedImageProps?.src;
|
|
2582
|
+
const [imageStatus, setImageStatus] = useState5(imageSource ? "loading" : "error");
|
|
2583
|
+
useEffect4(() => {
|
|
2584
|
+
setImageStatus(imageSource ? "loading" : "error");
|
|
2585
|
+
}, [imageSource]);
|
|
2586
|
+
let image = null;
|
|
2587
|
+
if (resolvedImageProps) {
|
|
2588
|
+
const imagePropsWithHandlers = {
|
|
2589
|
+
...resolvedImageProps,
|
|
2590
|
+
src: resolvedImageProps.src,
|
|
2591
|
+
alt: imageAlt ?? resolvedImageProps.alt,
|
|
2592
|
+
onLoad: (event) => {
|
|
2593
|
+
resolvedImageProps.onLoad?.(event);
|
|
2594
|
+
setImageStatus("loaded");
|
|
2595
|
+
},
|
|
2596
|
+
onError: (event) => {
|
|
2597
|
+
resolvedImageProps.onError?.(event);
|
|
2598
|
+
setImageStatus("error");
|
|
2599
|
+
}
|
|
2600
|
+
};
|
|
2601
|
+
image = renderImage?.(imagePropsWithHandlers, item) ?? (ImageComponent ? /* @__PURE__ */ jsx9(ImageComponent, { ...imagePropsWithHandlers }) : /* @__PURE__ */ jsx9("img", { ...imagePropsWithHandlers, alt: imagePropsWithHandlers.alt }));
|
|
2602
|
+
}
|
|
2603
|
+
const tags = showTags ? item.tags ?? [] : [];
|
|
2604
|
+
const renderedTags = showTags && tags.length > 0 ? renderTags?.(tags, item) ?? null : null;
|
|
2605
|
+
const meta = showSavedAt ? /* @__PURE__ */ jsxs5("div", { "data-card-meta": true, children: [
|
|
2606
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
2607
|
+
view.labels.savedAt,
|
|
2608
|
+
":"
|
|
2609
|
+
] }),
|
|
2610
|
+
" ",
|
|
2611
|
+
/* @__PURE__ */ jsx9("time", { dateTime: new Date(item.savedAt).toISOString(), children: formatSavedAt(item.savedAt) })
|
|
2612
|
+
] }) : null;
|
|
2613
|
+
const error = view.itemState.error ? /* @__PURE__ */ jsx9("p", { role: "alert", children: getErrorMessage2(view.itemState.error, view.labels.error) }) : null;
|
|
2614
|
+
const actions = view.statusLabel ? /* @__PURE__ */ jsx9(KeepStaleNotice, { item, onRetry, onRemoved }) : /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
2615
|
+
showSaveButton ? /* @__PURE__ */ jsx9(
|
|
2290
2616
|
KeepButton,
|
|
2291
2617
|
{
|
|
2292
2618
|
item: toKeepButtonItem(item),
|
|
@@ -2294,7 +2620,7 @@ function KeepItemCard({
|
|
|
2294
2620
|
getAriaLabel: (buttonState) => `${buttonState.isSaved ? view.labels.remove : view.labels.save} ${String(view.resolvedTitle)}`
|
|
2295
2621
|
}
|
|
2296
2622
|
) : null,
|
|
2297
|
-
|
|
2623
|
+
/* @__PURE__ */ jsx9(
|
|
2298
2624
|
"button",
|
|
2299
2625
|
{
|
|
2300
2626
|
type: "button",
|
|
@@ -2303,10 +2629,30 @@ function KeepItemCard({
|
|
|
2303
2629
|
disabled: view.itemState.isMutating,
|
|
2304
2630
|
children: removeLabel ?? view.labels.remove
|
|
2305
2631
|
}
|
|
2306
|
-
)
|
|
2632
|
+
)
|
|
2633
|
+
] });
|
|
2634
|
+
const compoundValue = {
|
|
2635
|
+
resolvedTitle: view.resolvedTitle,
|
|
2636
|
+
renderTitle,
|
|
2637
|
+
image: imageStatus === "error" ? null : image,
|
|
2638
|
+
imageStatus,
|
|
2639
|
+
fallbackLabel: String(view.resolvedTitle),
|
|
2640
|
+
tags,
|
|
2641
|
+
tagsLabel: view.labels.tags,
|
|
2642
|
+
renderedTags,
|
|
2643
|
+
meta,
|
|
2644
|
+
error,
|
|
2645
|
+
actions,
|
|
2646
|
+
renderText: (content) => /* @__PURE__ */ jsx9(KeepHighlight, { query: searchQuery, children: content })
|
|
2647
|
+
};
|
|
2648
|
+
const defaultBody = /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
2649
|
+
/* @__PURE__ */ jsx9(KeepItemCardMedia, {}),
|
|
2650
|
+
/* @__PURE__ */ jsx9(KeepItemCardContent, {}),
|
|
2651
|
+
/* @__PURE__ */ jsx9(KeepItemCardActions, {})
|
|
2307
2652
|
] });
|
|
2653
|
+
const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? defaultBody;
|
|
2308
2654
|
const linkedBody = linkTarget === "card" && view.isAvailable ? renderLink(body) : body;
|
|
2309
|
-
|
|
2655
|
+
const root = renderRoot(
|
|
2310
2656
|
asChild,
|
|
2311
2657
|
isValidElement2(children) ? children : void 0,
|
|
2312
2658
|
{
|
|
@@ -2323,6 +2669,68 @@ function KeepItemCard({
|
|
|
2323
2669
|
linkedBody,
|
|
2324
2670
|
"KeepItemCard"
|
|
2325
2671
|
);
|
|
2672
|
+
return /* @__PURE__ */ jsx9(KeepItemCardContext.Provider, { value: compoundValue, children: root });
|
|
2673
|
+
}
|
|
2674
|
+
function KeepItemCardMedia({ children, fallback, ...props }) {
|
|
2675
|
+
const context = useKeepItemCardCompound("Media");
|
|
2676
|
+
return /* @__PURE__ */ jsx9("div", { ...props, "data-keep-card-part": "media", "data-media-status": context.imageStatus, children: children ?? context.image ?? /* @__PURE__ */ jsx9("span", { role: "img", "aria-label": context.fallbackLabel, "data-keep-card-fallback": "true", children: fallback ?? /* @__PURE__ */ jsx9(KeepMediaPlaceholderIcon, {}) }) });
|
|
2677
|
+
}
|
|
2678
|
+
function KeepItemCardContent({ children, ...props }) {
|
|
2679
|
+
const context = useKeepItemCardCompound("Content");
|
|
2680
|
+
return /* @__PURE__ */ jsx9("div", { ...props, "data-keep-card-part": "content", children: children === void 0 ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
2681
|
+
/* @__PURE__ */ jsx9(KeepItemCardTitle, {}),
|
|
2682
|
+
context.meta,
|
|
2683
|
+
/* @__PURE__ */ jsx9(KeepItemCardTags, {}),
|
|
2684
|
+
context.error
|
|
2685
|
+
] }) : context.renderText(children) });
|
|
2686
|
+
}
|
|
2687
|
+
function KeepItemCardTitle({ as = "h3", children, ...props }) {
|
|
2688
|
+
const context = useKeepItemCardCompound("Title");
|
|
2689
|
+
return createElement2(
|
|
2690
|
+
as,
|
|
2691
|
+
{ ...props, "data-keep-card-part": "title" },
|
|
2692
|
+
context.renderTitle(context.renderText(children ?? context.resolvedTitle))
|
|
2693
|
+
);
|
|
2694
|
+
}
|
|
2695
|
+
function KeepMediaPlaceholderIcon() {
|
|
2696
|
+
return /* @__PURE__ */ jsxs5("svg", { "data-media-fallback-icon": "true", viewBox: "0 0 24 24", "aria-hidden": "true", children: [
|
|
2697
|
+
/* @__PURE__ */ jsx9(
|
|
2698
|
+
"path",
|
|
2699
|
+
{
|
|
2700
|
+
d: "M4 5.5A1.5 1.5 0 0 1 5.5 4h13A1.5 1.5 0 0 1 20 5.5v13a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 4 18.5v-13Z",
|
|
2701
|
+
fill: "none",
|
|
2702
|
+
stroke: "currentColor"
|
|
2703
|
+
}
|
|
2704
|
+
),
|
|
2705
|
+
/* @__PURE__ */ jsx9("circle", { cx: "9", cy: "9", r: "1.5", fill: "currentColor" }),
|
|
2706
|
+
/* @__PURE__ */ jsx9("path", { d: "m5.5 18 4.5-4.5 3 3 2-2L19 18", fill: "none", stroke: "currentColor" })
|
|
2707
|
+
] });
|
|
2708
|
+
}
|
|
2709
|
+
function KeepItemCardTags({ children, ...props }) {
|
|
2710
|
+
const context = useKeepItemCardCompound("Tags");
|
|
2711
|
+
if (children === void 0 && context.renderedTags) return context.renderedTags;
|
|
2712
|
+
if (children === void 0 && context.tags.length === 0) return null;
|
|
2713
|
+
return /* @__PURE__ */ jsx9("ul", { ...props, "aria-label": props["aria-label"] ?? context.tagsLabel, "data-keep-card-part": "tags", children: children ?? context.tags.map((tag) => /* @__PURE__ */ jsx9("li", { children: tag }, tag)) });
|
|
2714
|
+
}
|
|
2715
|
+
function KeepItemCardActions({ children, ...props }) {
|
|
2716
|
+
const context = useKeepItemCardCompound("Actions");
|
|
2717
|
+
return /* @__PURE__ */ jsx9("div", { ...props, "data-keep-card-part": "actions", children: children ?? context.actions });
|
|
2718
|
+
}
|
|
2719
|
+
var KeepItemCard = Object.assign(KeepItemCardRoot, {
|
|
2720
|
+
Media: KeepItemCardMedia,
|
|
2721
|
+
Content: KeepItemCardContent,
|
|
2722
|
+
Title: KeepItemCardTitle,
|
|
2723
|
+
Tags: KeepItemCardTags,
|
|
2724
|
+
Actions: KeepItemCardActions
|
|
2725
|
+
});
|
|
2726
|
+
function KeepItemCardSkeleton({ layout = "list", ...props }) {
|
|
2727
|
+
return /* @__PURE__ */ jsxs5("article", { ...props, "aria-hidden": "true", "data-keepkit": "card-skeleton", "data-layout": layout, "data-state": "loading", children: [
|
|
2728
|
+
/* @__PURE__ */ jsx9("span", { "data-skeleton-part": "media" }),
|
|
2729
|
+
/* @__PURE__ */ jsx9("span", { "data-skeleton-part": "title" }),
|
|
2730
|
+
/* @__PURE__ */ jsx9("span", { "data-skeleton-part": "meta" }),
|
|
2731
|
+
/* @__PURE__ */ jsx9("span", { "data-skeleton-part": "tag" }),
|
|
2732
|
+
/* @__PURE__ */ jsx9("span", { "data-skeleton-part": "tag" })
|
|
2733
|
+
] });
|
|
2326
2734
|
}
|
|
2327
2735
|
function formatSavedAt(timestamp) {
|
|
2328
2736
|
return new Date(timestamp).toISOString().slice(0, 10);
|
|
@@ -2332,7 +2740,7 @@ function getErrorMessage2(error, fallback) {
|
|
|
2332
2740
|
}
|
|
2333
2741
|
|
|
2334
2742
|
// src/KeepList.tsx
|
|
2335
|
-
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
2743
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2336
2744
|
function KeepList(props) {
|
|
2337
2745
|
const { fallback, onBoundaryError, boundaryResetKey, ...listProps } = props;
|
|
2338
2746
|
const content = /* @__PURE__ */ jsx10(KeepListContent, { ...listProps });
|
|
@@ -2344,20 +2752,27 @@ function KeepListContent({
|
|
|
2344
2752
|
children,
|
|
2345
2753
|
renderItem,
|
|
2346
2754
|
loading,
|
|
2755
|
+
renderLoading,
|
|
2756
|
+
loadingCount = 6,
|
|
2347
2757
|
empty,
|
|
2348
2758
|
error: errorContent,
|
|
2349
2759
|
itemCardProps,
|
|
2350
2760
|
layout = "list",
|
|
2351
2761
|
asChild = false,
|
|
2762
|
+
onKeyDown,
|
|
2763
|
+
onFocusCapture,
|
|
2352
2764
|
className,
|
|
2353
2765
|
...rootProps
|
|
2354
2766
|
}) {
|
|
2355
2767
|
const view = useKeepListView(query);
|
|
2768
|
+
const roving = useRovingTabIndex();
|
|
2356
2769
|
const { state } = view;
|
|
2357
2770
|
const body = getListBody(state, {
|
|
2358
2771
|
children,
|
|
2359
2772
|
renderItem,
|
|
2360
|
-
loading:
|
|
2773
|
+
loading: renderLoading !== void 0 ? renderLoading : loading,
|
|
2774
|
+
loadingCount,
|
|
2775
|
+
loadingLabel: view.labels.loading,
|
|
2361
2776
|
empty: empty ?? view.labels.empty,
|
|
2362
2777
|
error: errorContent ?? view.labels.error,
|
|
2363
2778
|
itemCardProps,
|
|
@@ -2373,9 +2788,20 @@ function KeepListContent({
|
|
|
2373
2788
|
"data-layout": layout,
|
|
2374
2789
|
"aria-busy": state.isLoading || rootProps["aria-busy"],
|
|
2375
2790
|
"data-state": getListState(state),
|
|
2376
|
-
"data-loading": state.isLoading ? "true" : void 0
|
|
2791
|
+
"data-loading": state.isLoading ? "true" : void 0,
|
|
2792
|
+
"data-roving-tabindex": "true",
|
|
2793
|
+
role: rootProps.role ?? "group",
|
|
2794
|
+
ref: roving.ref,
|
|
2795
|
+
onKeyDown: (event) => {
|
|
2796
|
+
onKeyDown?.(event);
|
|
2797
|
+
if (!event.defaultPrevented) roving.onKeyDown(event);
|
|
2798
|
+
},
|
|
2799
|
+
onFocusCapture: (event) => {
|
|
2800
|
+
onFocusCapture?.(event);
|
|
2801
|
+
if (!event.defaultPrevented) roving.onFocusCapture(event);
|
|
2802
|
+
}
|
|
2377
2803
|
},
|
|
2378
|
-
body,
|
|
2804
|
+
/* @__PURE__ */ jsx10(KeepSearchQueryProvider, { query: query?.search?.query, children: body }),
|
|
2379
2805
|
"KeepList"
|
|
2380
2806
|
);
|
|
2381
2807
|
}
|
|
@@ -2387,7 +2813,17 @@ function getListState(state) {
|
|
|
2387
2813
|
}
|
|
2388
2814
|
function getListBody(state, options) {
|
|
2389
2815
|
if (state.error && state.items.length === 0) return resolveContent(options.error, state);
|
|
2390
|
-
if (state.isLoading && !state.isHydrated)
|
|
2816
|
+
if (state.isLoading && !state.isHydrated) {
|
|
2817
|
+
if (options.loading !== void 0) return resolveContent(options.loading, state);
|
|
2818
|
+
const count = Number.isFinite(options.loadingCount) ? Math.max(0, Math.floor(options.loadingCount)) : 6;
|
|
2819
|
+
return /* @__PURE__ */ jsxs6(Fragment5, { children: [
|
|
2820
|
+
/* @__PURE__ */ jsx10("span", { role: "status", "data-keepkit": "loading-label", children: options.loadingLabel }),
|
|
2821
|
+
/* @__PURE__ */ jsx10("ul", { "data-keepkit": "skeleton-list", "data-layout": options.layout, children: Array.from({ length: count }, (_, index) => (
|
|
2822
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: Static loading placeholders never reorder.
|
|
2823
|
+
/* @__PURE__ */ jsx10("li", { children: /* @__PURE__ */ jsx10(KeepItemCardSkeleton, { layout: options.layout }) }, index)
|
|
2824
|
+
)) })
|
|
2825
|
+
] });
|
|
2826
|
+
}
|
|
2391
2827
|
if (state.isHydrated && state.items.length === 0) return resolveContent(options.empty, state);
|
|
2392
2828
|
if (typeof options.children === "function") return options.children(state);
|
|
2393
2829
|
if (options.children !== void 0 && !isValidElement3(options.children)) return options.children;
|
|
@@ -2401,16 +2837,16 @@ import { isValidElement as isValidElement4 } from "react";
|
|
|
2401
2837
|
|
|
2402
2838
|
// src/hooks/useKeepTagFilter.ts
|
|
2403
2839
|
import { useKeepList as useKeepList4 } from "@keepkit/core/react";
|
|
2404
|
-
import { useCallback, useMemo as useMemo3, useState as
|
|
2840
|
+
import { useCallback as useCallback4, useMemo as useMemo3, useState as useState6 } from "react";
|
|
2405
2841
|
function useKeepTagFilter(options) {
|
|
2406
2842
|
const { query, controlledValue, defaultValue, onChange, onValueChange } = options;
|
|
2407
|
-
const [uncontrolledValue, setUncontrolledValue] =
|
|
2843
|
+
const [uncontrolledValue, setUncontrolledValue] = useState6(defaultValue);
|
|
2408
2844
|
const resolvedValue = controlledValue ?? uncontrolledValue;
|
|
2409
2845
|
const list = useKeepList4({
|
|
2410
2846
|
...query,
|
|
2411
2847
|
tags: resolvedValue ? [...query?.tags ?? [], resolvedValue] : query?.tags
|
|
2412
2848
|
});
|
|
2413
|
-
const select =
|
|
2849
|
+
const select = useCallback4(
|
|
2414
2850
|
(tag) => {
|
|
2415
2851
|
if (controlledValue === void 0) setUncontrolledValue(tag);
|
|
2416
2852
|
onChange?.(tag);
|
|
@@ -2430,7 +2866,7 @@ function useKeepTagFilter(options) {
|
|
|
2430
2866
|
}
|
|
2431
2867
|
|
|
2432
2868
|
// src/KeepTagFilter.tsx
|
|
2433
|
-
import { jsx as jsx11, jsxs as
|
|
2869
|
+
import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2434
2870
|
function KeepTagFilter({
|
|
2435
2871
|
query,
|
|
2436
2872
|
value: controlledValue,
|
|
@@ -2448,7 +2884,7 @@ function KeepTagFilter({
|
|
|
2448
2884
|
}) {
|
|
2449
2885
|
const view = useKeepTagFilter({ query, controlledValue, defaultValue, onChange, onValueChange });
|
|
2450
2886
|
const contentChildren = asChild && isValidElement4(children) ? void 0 : children;
|
|
2451
|
-
const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */
|
|
2887
|
+
const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */ jsxs7("fieldset", { children: [
|
|
2452
2888
|
/* @__PURE__ */ jsx11("legend", { children: ariaLabel ?? view.labels.aria }),
|
|
2453
2889
|
/* @__PURE__ */ jsx11(
|
|
2454
2890
|
"button",
|
|
@@ -2460,7 +2896,7 @@ function KeepTagFilter({
|
|
|
2460
2896
|
children: allLabel ?? view.labels.all
|
|
2461
2897
|
}
|
|
2462
2898
|
),
|
|
2463
|
-
view.state.tags.map((tag) => /* @__PURE__ */
|
|
2899
|
+
view.state.tags.map((tag) => /* @__PURE__ */ jsxs7(
|
|
2464
2900
|
"button",
|
|
2465
2901
|
{
|
|
2466
2902
|
type: "button",
|
|
@@ -2469,7 +2905,7 @@ function KeepTagFilter({
|
|
|
2469
2905
|
onClick: () => view.state.select(tag),
|
|
2470
2906
|
children: [
|
|
2471
2907
|
renderTag ? renderTag(tag, view.state.tagCounts[tag] ?? 0, view.state.value === tag) : tag,
|
|
2472
|
-
/* @__PURE__ */
|
|
2908
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2473
2909
|
" (",
|
|
2474
2910
|
view.state.tagCounts[tag] ?? 0,
|
|
2475
2911
|
")"
|
|
@@ -2495,12 +2931,12 @@ function KeepTagFilter({
|
|
|
2495
2931
|
}
|
|
2496
2932
|
|
|
2497
2933
|
// src/hooks/useQueryControls.ts
|
|
2498
|
-
import { useEffect as
|
|
2934
|
+
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
2499
2935
|
function useKeepSearchInput(options) {
|
|
2500
2936
|
const { controlledValue, defaultValue, debounceMs, onValueChange } = options;
|
|
2501
|
-
const [uncontrolledValue, setUncontrolledValue] =
|
|
2937
|
+
const [uncontrolledValue, setUncontrolledValue] = useState7(defaultValue);
|
|
2502
2938
|
const value = controlledValue ?? uncontrolledValue;
|
|
2503
|
-
|
|
2939
|
+
useEffect5(() => {
|
|
2504
2940
|
if (!onValueChange) return;
|
|
2505
2941
|
if (debounceMs <= 0) {
|
|
2506
2942
|
onValueChange(value);
|
|
@@ -2519,7 +2955,7 @@ function useKeepSearchInput(options) {
|
|
|
2519
2955
|
}
|
|
2520
2956
|
function useKeepSortSelect(options) {
|
|
2521
2957
|
const { controlledValue, defaultValue, onValueChange } = options;
|
|
2522
|
-
const [uncontrolledValue, setUncontrolledValue] =
|
|
2958
|
+
const [uncontrolledValue, setUncontrolledValue] = useState7(defaultValue);
|
|
2523
2959
|
const value = controlledValue ?? uncontrolledValue;
|
|
2524
2960
|
return {
|
|
2525
2961
|
value,
|
|
@@ -2567,7 +3003,7 @@ function getVisiblePages(currentPage, pageCount, maxPageButtons) {
|
|
|
2567
3003
|
}
|
|
2568
3004
|
|
|
2569
3005
|
// src/query-controls.tsx
|
|
2570
|
-
import { Fragment as
|
|
3006
|
+
import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2571
3007
|
function KeepSearchInput({
|
|
2572
3008
|
value: controlledValue,
|
|
2573
3009
|
defaultValue = "",
|
|
@@ -2603,7 +3039,7 @@ function KeepSortSelect({
|
|
|
2603
3039
|
...props
|
|
2604
3040
|
}) {
|
|
2605
3041
|
const view = useKeepSortSelect({ controlledValue, defaultValue, onValueChange });
|
|
2606
|
-
const options = children ?? /* @__PURE__ */
|
|
3042
|
+
const options = children ?? /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
2607
3043
|
/* @__PURE__ */ jsx12("option", { value: "updatedAt:desc", children: view.labels.updatedNewest }),
|
|
2608
3044
|
/* @__PURE__ */ jsx12("option", { value: "updatedAt:asc", children: view.labels.updatedOldest }),
|
|
2609
3045
|
/* @__PURE__ */ jsx12("option", { value: "savedAt:desc", children: view.labels.savedNewest }),
|
|
@@ -2642,7 +3078,7 @@ function KeepPagination({
|
|
|
2642
3078
|
};
|
|
2643
3079
|
if (render)
|
|
2644
3080
|
return /* @__PURE__ */ jsx12("nav", { ...navProps, children: render({ page: view.currentPage, pageCount: view.pageCount, goToPage: view.goToPage }) });
|
|
2645
|
-
return /* @__PURE__ */
|
|
3081
|
+
return /* @__PURE__ */ jsxs8("nav", { ...navProps, children: [
|
|
2646
3082
|
/* @__PURE__ */ jsx12(
|
|
2647
3083
|
"button",
|
|
2648
3084
|
{
|
|
@@ -2679,7 +3115,7 @@ function KeepPagination({
|
|
|
2679
3115
|
}
|
|
2680
3116
|
|
|
2681
3117
|
// src/KeepCollection.tsx
|
|
2682
|
-
import { jsx as jsx13, jsxs as
|
|
3118
|
+
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2683
3119
|
function KeepCollection(props) {
|
|
2684
3120
|
const { fallback, onBoundaryError, boundaryResetKey, ...collectionProps } = props;
|
|
2685
3121
|
const content = /* @__PURE__ */ jsx13(KeepCollectionContent, { ...collectionProps });
|
|
@@ -2696,13 +3132,15 @@ function KeepCollectionContent({
|
|
|
2696
3132
|
renderItem,
|
|
2697
3133
|
itemCardProps,
|
|
2698
3134
|
loading,
|
|
3135
|
+
renderLoading,
|
|
3136
|
+
loadingCount,
|
|
2699
3137
|
empty,
|
|
2700
3138
|
error,
|
|
2701
3139
|
className,
|
|
2702
3140
|
...rootProps
|
|
2703
3141
|
}) {
|
|
2704
3142
|
const view = useKeepCollection({ query, pageSize, urlSync, urlAdapter, features });
|
|
2705
|
-
return /* @__PURE__ */
|
|
3143
|
+
return /* @__PURE__ */ jsxs9(
|
|
2706
3144
|
"section",
|
|
2707
3145
|
{
|
|
2708
3146
|
...rootProps,
|
|
@@ -2713,7 +3151,7 @@ function KeepCollectionContent({
|
|
|
2713
3151
|
"data-state": getCollectionState(view.list),
|
|
2714
3152
|
"data-loading": view.list.isLoading || view.list.isMutating ? "true" : void 0,
|
|
2715
3153
|
children: [
|
|
2716
|
-
/* @__PURE__ */
|
|
3154
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2717
3155
|
view.enabled.search ? /* @__PURE__ */ jsx13(KeepSearchInput, { value: view.searchValue, onValueChange: view.setSearchValue }) : null,
|
|
2718
3156
|
view.enabled.sort ? /* @__PURE__ */ jsx13(KeepSortSelect, { value: view.sortValue, onValueChange: view.setSortValue }) : null,
|
|
2719
3157
|
view.enabled.tagFilter ? /* @__PURE__ */ jsx13(KeepTagFilter, { query, value: view.tag, onValueChange: view.setTag }) : null
|
|
@@ -2726,6 +3164,8 @@ function KeepCollectionContent({
|
|
|
2726
3164
|
itemCardProps,
|
|
2727
3165
|
layout,
|
|
2728
3166
|
loading,
|
|
3167
|
+
renderLoading,
|
|
3168
|
+
loadingCount,
|
|
2729
3169
|
empty,
|
|
2730
3170
|
error
|
|
2731
3171
|
}
|
|
@@ -2753,8 +3193,31 @@ function getCollectionState(list) {
|
|
|
2753
3193
|
|
|
2754
3194
|
// src/KeepLayout.tsx
|
|
2755
3195
|
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
2756
|
-
function KeepLayout({ layout = "list", children, ...props }) {
|
|
2757
|
-
|
|
3196
|
+
function KeepLayout({ layout = "list", children, onKeyDown, onFocusCapture, ...props }) {
|
|
3197
|
+
const roving = useRovingTabIndex();
|
|
3198
|
+
return (
|
|
3199
|
+
// biome-ignore lint/a11y/noStaticElementInteractions: The group manages keyboard focus for descendant cards.
|
|
3200
|
+
/* @__PURE__ */ jsx14(
|
|
3201
|
+
"div",
|
|
3202
|
+
{
|
|
3203
|
+
...props,
|
|
3204
|
+
ref: roving.ref,
|
|
3205
|
+
"data-keepkit": "layout",
|
|
3206
|
+
"data-layout": layout,
|
|
3207
|
+
"data-roving-tabindex": "true",
|
|
3208
|
+
role: props.role ?? "group",
|
|
3209
|
+
onKeyDown: (event) => {
|
|
3210
|
+
onKeyDown?.(event);
|
|
3211
|
+
if (!event.defaultPrevented) roving.onKeyDown(event);
|
|
3212
|
+
},
|
|
3213
|
+
onFocusCapture: (event) => {
|
|
3214
|
+
onFocusCapture?.(event);
|
|
3215
|
+
if (!event.defaultPrevented) roving.onFocusCapture(event);
|
|
3216
|
+
},
|
|
3217
|
+
children
|
|
3218
|
+
}
|
|
3219
|
+
)
|
|
3220
|
+
);
|
|
2758
3221
|
}
|
|
2759
3222
|
|
|
2760
3223
|
// src/KeepNoteEditor.tsx
|
|
@@ -2762,16 +3225,16 @@ import { isValidElement as isValidElement5 } from "react";
|
|
|
2762
3225
|
|
|
2763
3226
|
// src/hooks/useKeepNoteEditor.ts
|
|
2764
3227
|
import { useKeepItem as useKeepItem3 } from "@keepkit/core/react";
|
|
2765
|
-
import { useCallback as
|
|
3228
|
+
import { useCallback as useCallback5, useEffect as useEffect6, useRef as useRef5, useState as useState8 } from "react";
|
|
2766
3229
|
function useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError }) {
|
|
2767
3230
|
const itemState = useKeepItem3(item);
|
|
2768
3231
|
const { error, isMutating, item: savedItem, updateNote } = itemState;
|
|
2769
|
-
const [note, setNote] =
|
|
3232
|
+
const [note, setNote] = useState8(item.note ?? "");
|
|
2770
3233
|
const baselineNote = savedItem?.note ?? item.note ?? "";
|
|
2771
3234
|
const isDirty = note !== baselineNote;
|
|
2772
|
-
const lastSavedNoteRef =
|
|
2773
|
-
|
|
2774
|
-
const save =
|
|
3235
|
+
const lastSavedNoteRef = useRef5(void 0);
|
|
3236
|
+
useEffect6(() => setNote(baselineNote), [baselineNote]);
|
|
3237
|
+
const save = useCallback5(async () => {
|
|
2775
3238
|
const nextNote = note.trim() || void 0;
|
|
2776
3239
|
try {
|
|
2777
3240
|
await updateNote(nextNote);
|
|
@@ -2782,7 +3245,7 @@ function useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError }) {
|
|
|
2782
3245
|
throw cause;
|
|
2783
3246
|
}
|
|
2784
3247
|
}, [note, onSaveError, onSaved, updateNote]);
|
|
2785
|
-
|
|
3248
|
+
useEffect6(() => {
|
|
2786
3249
|
if (!isDirty || debounceMs <= 0 || lastSavedNoteRef.current === note) return;
|
|
2787
3250
|
const timer = window.setTimeout(() => void save().catch(() => void 0), debounceMs);
|
|
2788
3251
|
return () => window.clearTimeout(timer);
|
|
@@ -2817,7 +3280,7 @@ function useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError }) {
|
|
|
2817
3280
|
}
|
|
2818
3281
|
|
|
2819
3282
|
// src/KeepNoteEditor.tsx
|
|
2820
|
-
import { Fragment as
|
|
3283
|
+
import { Fragment as Fragment7, jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2821
3284
|
function KeepNoteEditor({
|
|
2822
3285
|
item,
|
|
2823
3286
|
label,
|
|
@@ -2835,8 +3298,8 @@ function KeepNoteEditor({
|
|
|
2835
3298
|
const view = useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError });
|
|
2836
3299
|
const { error, isDirty, isSaving, note, setNote } = view.state;
|
|
2837
3300
|
const contentChildren = asChild && isValidElement5(children) ? void 0 : children;
|
|
2838
|
-
const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */
|
|
2839
|
-
/* @__PURE__ */
|
|
3301
|
+
const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */ jsxs10(Fragment7, { children: [
|
|
3302
|
+
/* @__PURE__ */ jsxs10("label", { children: [
|
|
2840
3303
|
label ?? view.labels.note,
|
|
2841
3304
|
/* @__PURE__ */ jsx15(
|
|
2842
3305
|
"textarea",
|
|
@@ -2853,7 +3316,7 @@ function KeepNoteEditor({
|
|
|
2853
3316
|
/* @__PURE__ */ jsx15("button", { type: "submit", "data-keep-action": "save-note", disabled: isSaving, "aria-busy": isSaving, children: saveLabel ?? view.labels.save })
|
|
2854
3317
|
] });
|
|
2855
3318
|
if (!asChild) {
|
|
2856
|
-
return /* @__PURE__ */
|
|
3319
|
+
return /* @__PURE__ */ jsxs10(
|
|
2857
3320
|
"form",
|
|
2858
3321
|
{
|
|
2859
3322
|
...formProps,
|
|
@@ -2892,18 +3355,119 @@ function getErrorMessage3(error, fallback) {
|
|
|
2892
3355
|
return error instanceof Error ? error.message : fallback;
|
|
2893
3356
|
}
|
|
2894
3357
|
|
|
2895
|
-
// src/
|
|
3358
|
+
// src/KeepReorderableList.tsx
|
|
3359
|
+
import { useState as useState9 } from "react";
|
|
3360
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
3361
|
+
function KeepReorderableList({
|
|
3362
|
+
items,
|
|
3363
|
+
onReorder,
|
|
3364
|
+
renderItem,
|
|
3365
|
+
itemLabel = (_item, index) => `Move item ${index + 1}`,
|
|
3366
|
+
...props
|
|
3367
|
+
}) {
|
|
3368
|
+
const [draggedId, setDraggedId] = useState9(null);
|
|
3369
|
+
const ids = items.map((item) => item.id);
|
|
3370
|
+
function commit(nextIds) {
|
|
3371
|
+
void onReorder(nextIds);
|
|
3372
|
+
}
|
|
3373
|
+
function move(index, targetIndex) {
|
|
3374
|
+
if (targetIndex < 0 || targetIndex >= ids.length || targetIndex === index) return;
|
|
3375
|
+
const next = [...ids];
|
|
3376
|
+
const [id] = next.splice(index, 1);
|
|
3377
|
+
if (id === void 0) return;
|
|
3378
|
+
next.splice(targetIndex, 0, id);
|
|
3379
|
+
commit(next);
|
|
3380
|
+
}
|
|
3381
|
+
return /* @__PURE__ */ jsx16("ul", { ...props, "data-keepkit": "reorderable-list", children: items.map((item, index) => {
|
|
3382
|
+
const moveUp = () => move(index, index - 1);
|
|
3383
|
+
const moveDown = () => move(index, index + 1);
|
|
3384
|
+
const onHandleKeyDown = (event) => {
|
|
3385
|
+
if (event.key === "ArrowUp") {
|
|
3386
|
+
event.preventDefault();
|
|
3387
|
+
moveUp();
|
|
3388
|
+
} else if (event.key === "ArrowDown") {
|
|
3389
|
+
event.preventDefault();
|
|
3390
|
+
moveDown();
|
|
3391
|
+
}
|
|
3392
|
+
};
|
|
3393
|
+
const state = {
|
|
3394
|
+
index,
|
|
3395
|
+
isDragging: draggedId === item.id,
|
|
3396
|
+
moveUp,
|
|
3397
|
+
moveDown,
|
|
3398
|
+
dragHandleProps: {
|
|
3399
|
+
role: "button",
|
|
3400
|
+
tabIndex: 0,
|
|
3401
|
+
draggable: true,
|
|
3402
|
+
"aria-label": itemLabel(item, index),
|
|
3403
|
+
"aria-grabbed": draggedId === item.id,
|
|
3404
|
+
onDragStart: () => setDraggedId(item.id),
|
|
3405
|
+
onDragEnd: () => setDraggedId(null),
|
|
3406
|
+
onKeyDown: onHandleKeyDown
|
|
3407
|
+
}
|
|
3408
|
+
};
|
|
3409
|
+
return /* @__PURE__ */ jsx16(
|
|
3410
|
+
"li",
|
|
3411
|
+
{
|
|
3412
|
+
"data-reorder-index": index,
|
|
3413
|
+
"data-dragging": draggedId === item.id ? "true" : void 0,
|
|
3414
|
+
onDragOver: (event) => {
|
|
3415
|
+
if (draggedId && draggedId !== item.id) event.preventDefault();
|
|
3416
|
+
},
|
|
3417
|
+
onDrop: (event) => {
|
|
3418
|
+
event.preventDefault();
|
|
3419
|
+
if (!draggedId || draggedId === item.id) return;
|
|
3420
|
+
const sourceIndex = ids.indexOf(draggedId);
|
|
3421
|
+
setDraggedId(null);
|
|
3422
|
+
move(sourceIndex, index);
|
|
3423
|
+
},
|
|
3424
|
+
children: renderItem(item, state)
|
|
3425
|
+
},
|
|
3426
|
+
item.id
|
|
3427
|
+
);
|
|
3428
|
+
}) });
|
|
3429
|
+
}
|
|
3430
|
+
|
|
3431
|
+
// src/hooks/useKeepSyncFeedback.ts
|
|
2896
3432
|
import { useKeepContext as useKeepContext3 } from "@keepkit/core/react";
|
|
2897
|
-
import { useEffect as
|
|
3433
|
+
import { useEffect as useEffect7, useRef as useRef6 } from "react";
|
|
3434
|
+
function useKeepSyncFeedback() {
|
|
3435
|
+
const { syncState } = useKeepContext3();
|
|
3436
|
+
const emitFeedback = useKeepUiFeedback();
|
|
3437
|
+
const completedMessage = useUiLabel("syncSynced");
|
|
3438
|
+
const failedMessage = useUiLabel("syncFailedMessage");
|
|
3439
|
+
const previousStatus = useRef6("idle");
|
|
3440
|
+
useEffect7(() => {
|
|
3441
|
+
const previous = previousStatus.current;
|
|
3442
|
+
previousStatus.current = syncState.status;
|
|
3443
|
+
if (syncState.status === "error" && previous !== "error") {
|
|
3444
|
+
emitFeedback({ type: "sync-failed", error: syncState.error, message: failedMessage });
|
|
3445
|
+
return;
|
|
3446
|
+
}
|
|
3447
|
+
if (syncState.status === "synced" && (previous === "pending" || previous === "syncing" || previous === "conflict" || previous === "error")) {
|
|
3448
|
+
emitFeedback({ type: "sync-completed", message: completedMessage });
|
|
3449
|
+
}
|
|
3450
|
+
}, [completedMessage, emitFeedback, failedMessage, syncState.error, syncState.status]);
|
|
3451
|
+
}
|
|
3452
|
+
|
|
3453
|
+
// src/KeepSyncFeedbackObserver.tsx
|
|
3454
|
+
function KeepSyncFeedbackObserver() {
|
|
3455
|
+
useKeepSyncFeedback();
|
|
3456
|
+
return null;
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3459
|
+
// src/hooks/useKeepSyncRecoveryDialog.ts
|
|
3460
|
+
import { useKeepContext as useKeepContext4 } from "@keepkit/core/react";
|
|
3461
|
+
import { useEffect as useEffect8, useState as useState10 } from "react";
|
|
2898
3462
|
function useKeepSyncRecoveryDialog(options) {
|
|
2899
3463
|
const { open, onOpenChange, conflicts, onManualMerge } = options;
|
|
2900
|
-
const context =
|
|
3464
|
+
const context = useKeepContext4();
|
|
2901
3465
|
const conflictList = conflicts ?? context.syncState.conflicts ?? [];
|
|
2902
3466
|
const hasRecovery = conflictList.length > 0 || context.syncState.status === "error" || Boolean(context.error);
|
|
2903
|
-
const [dismissed, setDismissed] =
|
|
2904
|
-
const [busyId, setBusyId] =
|
|
2905
|
-
const [error, setError] =
|
|
2906
|
-
|
|
3467
|
+
const [dismissed, setDismissed] = useState10(false);
|
|
3468
|
+
const [busyId, setBusyId] = useState10();
|
|
3469
|
+
const [error, setError] = useState10();
|
|
3470
|
+
useEffect8(() => {
|
|
2907
3471
|
if (hasRecovery) setDismissed(false);
|
|
2908
3472
|
}, [hasRecovery]);
|
|
2909
3473
|
return {
|
|
@@ -2948,7 +3512,7 @@ function useKeepSyncRecoveryDialog(options) {
|
|
|
2948
3512
|
}
|
|
2949
3513
|
|
|
2950
3514
|
// src/KeepSyncRecoveryDialog.tsx
|
|
2951
|
-
import { jsx as
|
|
3515
|
+
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2952
3516
|
function KeepSyncRecoveryDialog({
|
|
2953
3517
|
open,
|
|
2954
3518
|
onOpenChange,
|
|
@@ -2963,7 +3527,7 @@ function KeepSyncRecoveryDialog({
|
|
|
2963
3527
|
}) {
|
|
2964
3528
|
const view = useKeepSyncRecoveryDialog({ open, onOpenChange, conflicts, onManualMerge });
|
|
2965
3529
|
if (!view.isOpen) return null;
|
|
2966
|
-
return /* @__PURE__ */
|
|
3530
|
+
return /* @__PURE__ */ jsxs11(
|
|
2967
3531
|
"section",
|
|
2968
3532
|
{
|
|
2969
3533
|
...props,
|
|
@@ -2977,17 +3541,17 @@ function KeepSyncRecoveryDialog({
|
|
|
2977
3541
|
"data-state": view.conflictList.length > 0 ? "conflict" : "error",
|
|
2978
3542
|
"data-loading": view.busyId !== void 0 ? "true" : void 0,
|
|
2979
3543
|
children: [
|
|
2980
|
-
/* @__PURE__ */
|
|
2981
|
-
/* @__PURE__ */
|
|
2982
|
-
/* @__PURE__ */
|
|
3544
|
+
/* @__PURE__ */ jsxs11("header", { children: [
|
|
3545
|
+
/* @__PURE__ */ jsx17("h2", { id: "keepkit-sync-recovery-title", children: title ?? view.labels.title }),
|
|
3546
|
+
/* @__PURE__ */ jsx17("button", { type: "button", "data-keep-action": "close-dialog", onClick: view.close, "aria-label": view.labels.close, children: view.labels.close })
|
|
2983
3547
|
] }),
|
|
2984
3548
|
children,
|
|
2985
|
-
view.conflictList.length > 0 ? /* @__PURE__ */
|
|
2986
|
-
/* @__PURE__ */
|
|
2987
|
-
view.conflictList.map((conflict) => /* @__PURE__ */
|
|
2988
|
-
/* @__PURE__ */
|
|
2989
|
-
/* @__PURE__ */
|
|
2990
|
-
/* @__PURE__ */
|
|
3549
|
+
view.conflictList.length > 0 ? /* @__PURE__ */ jsxs11("div", { children: [
|
|
3550
|
+
/* @__PURE__ */ jsx17("p", { children: view.labels.conflict }),
|
|
3551
|
+
view.conflictList.map((conflict) => /* @__PURE__ */ jsxs11("article", { "data-conflict-id": conflict.id, children: [
|
|
3552
|
+
/* @__PURE__ */ jsx17("h3", { children: getMetaTitle(conflict.operation.item?.meta) ?? conflict.id }),
|
|
3553
|
+
/* @__PURE__ */ jsxs11("div", { "data-conflict-preview": true, children: [
|
|
3554
|
+
/* @__PURE__ */ jsx17(
|
|
2991
3555
|
ConflictPreview,
|
|
2992
3556
|
{
|
|
2993
3557
|
item: conflict.operation.item,
|
|
@@ -2997,7 +3561,7 @@ function KeepSyncRecoveryDialog({
|
|
|
2997
3561
|
side: "local"
|
|
2998
3562
|
}
|
|
2999
3563
|
),
|
|
3000
|
-
/* @__PURE__ */
|
|
3564
|
+
/* @__PURE__ */ jsx17(
|
|
3001
3565
|
ConflictPreview,
|
|
3002
3566
|
{
|
|
3003
3567
|
item: conflict.remote,
|
|
@@ -3008,8 +3572,8 @@ function KeepSyncRecoveryDialog({
|
|
|
3008
3572
|
}
|
|
3009
3573
|
)
|
|
3010
3574
|
] }),
|
|
3011
|
-
/* @__PURE__ */
|
|
3012
|
-
/* @__PURE__ */
|
|
3575
|
+
/* @__PURE__ */ jsxs11("div", { children: [
|
|
3576
|
+
/* @__PURE__ */ jsx17(
|
|
3013
3577
|
"button",
|
|
3014
3578
|
{
|
|
3015
3579
|
type: "button",
|
|
@@ -3019,7 +3583,7 @@ function KeepSyncRecoveryDialog({
|
|
|
3019
3583
|
children: view.labels.keepLocal
|
|
3020
3584
|
}
|
|
3021
3585
|
),
|
|
3022
|
-
/* @__PURE__ */
|
|
3586
|
+
/* @__PURE__ */ jsx17(
|
|
3023
3587
|
"button",
|
|
3024
3588
|
{
|
|
3025
3589
|
type: "button",
|
|
@@ -3029,7 +3593,7 @@ function KeepSyncRecoveryDialog({
|
|
|
3029
3593
|
children: view.labels.useServer
|
|
3030
3594
|
}
|
|
3031
3595
|
),
|
|
3032
|
-
/* @__PURE__ */
|
|
3596
|
+
/* @__PURE__ */ jsx17(
|
|
3033
3597
|
"button",
|
|
3034
3598
|
{
|
|
3035
3599
|
type: "button",
|
|
@@ -3042,12 +3606,12 @@ function KeepSyncRecoveryDialog({
|
|
|
3042
3606
|
] })
|
|
3043
3607
|
] }, conflict.id))
|
|
3044
3608
|
] }) : null,
|
|
3045
|
-
view.showBackupRecovery ? /* @__PURE__ */
|
|
3046
|
-
/* @__PURE__ */
|
|
3047
|
-
/* @__PURE__ */
|
|
3048
|
-
backup ?? (showBackupControls ? /* @__PURE__ */
|
|
3609
|
+
view.showBackupRecovery ? /* @__PURE__ */ jsxs11("section", { "data-recovery": "backup", children: [
|
|
3610
|
+
/* @__PURE__ */ jsx17("h3", { children: view.labels.backupRecovery }),
|
|
3611
|
+
/* @__PURE__ */ jsx17("p", { children: view.labels.backupRecoveryDescription }),
|
|
3612
|
+
backup ?? (showBackupControls ? /* @__PURE__ */ jsx17(KeepBackup, {}) : null)
|
|
3049
3613
|
] }) : null,
|
|
3050
|
-
view.error ? /* @__PURE__ */
|
|
3614
|
+
view.error ? /* @__PURE__ */ jsx17("p", { id: "keepkit-sync-recovery-error", role: "alert", "aria-live": "assertive", children: view.error instanceof Error ? view.error.message : view.labels.error }) : null
|
|
3051
3615
|
]
|
|
3052
3616
|
}
|
|
3053
3617
|
);
|
|
@@ -3059,16 +3623,16 @@ function ConflictPreview({
|
|
|
3059
3623
|
noteLabel,
|
|
3060
3624
|
side
|
|
3061
3625
|
}) {
|
|
3062
|
-
return /* @__PURE__ */
|
|
3063
|
-
/* @__PURE__ */
|
|
3064
|
-
/* @__PURE__ */
|
|
3065
|
-
/* @__PURE__ */
|
|
3066
|
-
/* @__PURE__ */
|
|
3067
|
-
/* @__PURE__ */
|
|
3626
|
+
return /* @__PURE__ */ jsxs11("article", { "data-conflict-version": side, "aria-label": heading, children: [
|
|
3627
|
+
/* @__PURE__ */ jsx17("h4", { children: heading }),
|
|
3628
|
+
/* @__PURE__ */ jsxs11("dl", { children: [
|
|
3629
|
+
/* @__PURE__ */ jsxs11("div", { children: [
|
|
3630
|
+
/* @__PURE__ */ jsx17("dt", { children: updatedAtLabel }),
|
|
3631
|
+
/* @__PURE__ */ jsx17("dd", { children: item ? /* @__PURE__ */ jsx17("time", { dateTime: new Date(item.updatedAt).toISOString(), children: formatConflictDate(item.updatedAt) }) : "\u2014" })
|
|
3068
3632
|
] }),
|
|
3069
|
-
/* @__PURE__ */
|
|
3070
|
-
/* @__PURE__ */
|
|
3071
|
-
/* @__PURE__ */
|
|
3633
|
+
/* @__PURE__ */ jsxs11("div", { children: [
|
|
3634
|
+
/* @__PURE__ */ jsx17("dt", { children: noteLabel }),
|
|
3635
|
+
/* @__PURE__ */ jsx17("dd", { children: item?.note || "\u2014" })
|
|
3072
3636
|
] })
|
|
3073
3637
|
] })
|
|
3074
3638
|
] });
|
|
@@ -3078,9 +3642,9 @@ function formatConflictDate(timestamp) {
|
|
|
3078
3642
|
}
|
|
3079
3643
|
|
|
3080
3644
|
// src/hooks/useKeepSyncStatusBanner.ts
|
|
3081
|
-
import { useKeepContext as
|
|
3645
|
+
import { useKeepContext as useKeepContext5 } from "@keepkit/core/react";
|
|
3082
3646
|
function useKeepSyncStatusBanner({ onRetry, children }) {
|
|
3083
|
-
const context =
|
|
3647
|
+
const context = useKeepContext5();
|
|
3084
3648
|
const retryLabel = useUiLabel("retrySync");
|
|
3085
3649
|
const resolveLabel = useUiLabel("resolveSync");
|
|
3086
3650
|
const conflictLabel = useUiLabel("syncConflict");
|
|
@@ -3112,7 +3676,7 @@ function getErrorMessage4(error) {
|
|
|
3112
3676
|
}
|
|
3113
3677
|
|
|
3114
3678
|
// src/KeepSyncStatusBanner.tsx
|
|
3115
|
-
import { jsx as
|
|
3679
|
+
import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3116
3680
|
function KeepSyncStatusBanner({
|
|
3117
3681
|
onRetry,
|
|
3118
3682
|
onResolveConflicts,
|
|
@@ -3122,7 +3686,7 @@ function KeepSyncStatusBanner({
|
|
|
3122
3686
|
}) {
|
|
3123
3687
|
const view = useKeepSyncStatusBanner({ onRetry, children });
|
|
3124
3688
|
if (view.status === "idle" && !view.hasConflicts) return null;
|
|
3125
|
-
return /* @__PURE__ */
|
|
3689
|
+
return /* @__PURE__ */ jsxs12(
|
|
3126
3690
|
"aside",
|
|
3127
3691
|
{
|
|
3128
3692
|
...props,
|
|
@@ -3132,8 +3696,8 @@ function KeepSyncStatusBanner({
|
|
|
3132
3696
|
"data-keepkit": "sync-status",
|
|
3133
3697
|
"data-state": view.status,
|
|
3134
3698
|
children: [
|
|
3135
|
-
/* @__PURE__ */
|
|
3136
|
-
view.showRetry ? /* @__PURE__ */
|
|
3699
|
+
/* @__PURE__ */ jsx18("p", { children: view.message }),
|
|
3700
|
+
view.showRetry ? /* @__PURE__ */ jsx18(
|
|
3137
3701
|
"button",
|
|
3138
3702
|
{
|
|
3139
3703
|
type: "button",
|
|
@@ -3143,7 +3707,7 @@ function KeepSyncStatusBanner({
|
|
|
3143
3707
|
children: view.retryLabel
|
|
3144
3708
|
}
|
|
3145
3709
|
) : null,
|
|
3146
|
-
view.hasConflicts ? /* @__PURE__ */
|
|
3710
|
+
view.hasConflicts ? /* @__PURE__ */ jsx18(
|
|
3147
3711
|
"button",
|
|
3148
3712
|
{
|
|
3149
3713
|
type: "button",
|
|
@@ -3160,13 +3724,13 @@ function KeepSyncStatusBanner({
|
|
|
3160
3724
|
|
|
3161
3725
|
// src/hooks/useKeepTagEditor.ts
|
|
3162
3726
|
import { useKeepItem as useKeepItem4 } from "@keepkit/core/react";
|
|
3163
|
-
import { useCallback as
|
|
3727
|
+
import { useCallback as useCallback6, useEffect as useEffect9, useState as useState11 } from "react";
|
|
3164
3728
|
function useKeepTagEditor({ item, onSaved, onSaveError }) {
|
|
3165
3729
|
const itemState = useKeepItem4(item);
|
|
3166
|
-
const [tags, setTags] =
|
|
3167
|
-
const [input, setInput] =
|
|
3168
|
-
|
|
3169
|
-
const save =
|
|
3730
|
+
const [tags, setTags] = useState11(item.tags ?? []);
|
|
3731
|
+
const [input, setInput] = useState11("");
|
|
3732
|
+
useEffect9(() => setTags(itemState.item?.tags ?? item.tags ?? []), [item.tags, itemState.item?.tags]);
|
|
3733
|
+
const save = useCallback6(async () => {
|
|
3170
3734
|
const nextTags = normalizeUiTags(tags);
|
|
3171
3735
|
try {
|
|
3172
3736
|
await itemState.updateTags(nextTags);
|
|
@@ -3212,7 +3776,7 @@ function useKeepTagEditor({ item, onSaved, onSaveError }) {
|
|
|
3212
3776
|
}
|
|
3213
3777
|
|
|
3214
3778
|
// src/KeepTagEditor.tsx
|
|
3215
|
-
import { Fragment as
|
|
3779
|
+
import { Fragment as Fragment8, jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3216
3780
|
function KeepTagEditor({
|
|
3217
3781
|
item,
|
|
3218
3782
|
availableTags = [],
|
|
@@ -3223,10 +3787,10 @@ function KeepTagEditor({
|
|
|
3223
3787
|
}) {
|
|
3224
3788
|
const view = useKeepTagEditor({ item, onSaved, onSaveError });
|
|
3225
3789
|
const { isSaving, tags } = view.state;
|
|
3226
|
-
const body = render ? render(view.state) : /* @__PURE__ */
|
|
3227
|
-
/* @__PURE__ */
|
|
3790
|
+
const body = render ? render(view.state) : /* @__PURE__ */ jsxs13(Fragment8, { children: [
|
|
3791
|
+
/* @__PURE__ */ jsxs13("label", { children: [
|
|
3228
3792
|
view.labels.tags,
|
|
3229
|
-
/* @__PURE__ */
|
|
3793
|
+
/* @__PURE__ */ jsx19(
|
|
3230
3794
|
"input",
|
|
3231
3795
|
{
|
|
3232
3796
|
"data-keep-action": "edit-tags",
|
|
@@ -3237,14 +3801,14 @@ function KeepTagEditor({
|
|
|
3237
3801
|
}
|
|
3238
3802
|
)
|
|
3239
3803
|
] }),
|
|
3240
|
-
availableTags.length > 0 ? /* @__PURE__ */
|
|
3241
|
-
/* @__PURE__ */
|
|
3804
|
+
availableTags.length > 0 ? /* @__PURE__ */ jsx19("datalist", { id: `keep-tags-${item.id}`, children: availableTags.map((tag) => /* @__PURE__ */ jsx19("option", { value: tag }, tag)) }) : null,
|
|
3805
|
+
/* @__PURE__ */ jsx19("ul", { "aria-label": view.labels.tags, children: tags.map((tag) => /* @__PURE__ */ jsxs13("li", { children: [
|
|
3242
3806
|
tag,
|
|
3243
|
-
/* @__PURE__ */
|
|
3807
|
+
/* @__PURE__ */ jsx19("button", { type: "button", "data-keep-action": "remove-tag", onClick: () => view.removeTag(tag), children: view.labels.remove })
|
|
3244
3808
|
] }, tag)) }),
|
|
3245
|
-
/* @__PURE__ */
|
|
3809
|
+
/* @__PURE__ */ jsx19("button", { type: "submit", "data-keep-action": "apply-tags", disabled: isSaving, "aria-busy": isSaving, children: view.labels.apply })
|
|
3246
3810
|
] });
|
|
3247
|
-
return /* @__PURE__ */
|
|
3811
|
+
return /* @__PURE__ */ jsxs13(
|
|
3248
3812
|
"form",
|
|
3249
3813
|
{
|
|
3250
3814
|
...props,
|
|
@@ -3256,7 +3820,7 @@ function KeepTagEditor({
|
|
|
3256
3820
|
"data-disabled": isSaving ? "true" : void 0,
|
|
3257
3821
|
children: [
|
|
3258
3822
|
body,
|
|
3259
|
-
view.error ? /* @__PURE__ */
|
|
3823
|
+
view.error ? /* @__PURE__ */ jsx19("p", { role: "alert", children: getErrorMessage5(view.error, view.labels.error) }) : null
|
|
3260
3824
|
]
|
|
3261
3825
|
}
|
|
3262
3826
|
);
|
|
@@ -3265,26 +3829,145 @@ function getErrorMessage5(error, fallback) {
|
|
|
3265
3829
|
return error instanceof Error ? error.message : fallback;
|
|
3266
3830
|
}
|
|
3267
3831
|
|
|
3832
|
+
// src/KeepTourBar.tsx
|
|
3833
|
+
import { useKeepNavigator } from "@keepkit/core/react";
|
|
3834
|
+
|
|
3835
|
+
// src/hooks/useKeepTourShortcuts.ts
|
|
3836
|
+
import { useEffect as useEffect10 } from "react";
|
|
3837
|
+
function useKeepTourShortcuts({
|
|
3838
|
+
onNext,
|
|
3839
|
+
onPrev,
|
|
3840
|
+
enabled = true,
|
|
3841
|
+
allowInEditable = false,
|
|
3842
|
+
preventDefault = true,
|
|
3843
|
+
nextKeys = ["j", "]"],
|
|
3844
|
+
prevKeys = ["k", "["],
|
|
3845
|
+
onError
|
|
3846
|
+
}) {
|
|
3847
|
+
useEffect10(() => {
|
|
3848
|
+
if (!enabled) return;
|
|
3849
|
+
const handleKeyDown = (event) => {
|
|
3850
|
+
if (!allowInEditable && isEditableTarget(event.target)) return;
|
|
3851
|
+
if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
|
|
3852
|
+
const key = event.key.toLocaleLowerCase();
|
|
3853
|
+
const action = nextKeys.some((candidate) => candidate.toLocaleLowerCase() === key) ? onNext : prevKeys.some((candidate) => candidate.toLocaleLowerCase() === key) ? onPrev : void 0;
|
|
3854
|
+
if (!action) return;
|
|
3855
|
+
if (preventDefault) event.preventDefault();
|
|
3856
|
+
void Promise.resolve(action()).catch((error) => onError?.(error));
|
|
3857
|
+
};
|
|
3858
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
3859
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
3860
|
+
}, [allowInEditable, enabled, nextKeys, onError, onNext, onPrev, preventDefault, prevKeys]);
|
|
3861
|
+
}
|
|
3862
|
+
function isEditableTarget(target) {
|
|
3863
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
3864
|
+
return target.isContentEditable || target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT";
|
|
3865
|
+
}
|
|
3866
|
+
|
|
3867
|
+
// src/KeepTourBar.tsx
|
|
3868
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3869
|
+
function KeepTourBar({
|
|
3870
|
+
navigation: providedNavigation,
|
|
3871
|
+
currentId,
|
|
3872
|
+
initialIndex,
|
|
3873
|
+
showProgress = true,
|
|
3874
|
+
prevHref,
|
|
3875
|
+
nextHref,
|
|
3876
|
+
backHref,
|
|
3877
|
+
onPrev,
|
|
3878
|
+
onNext,
|
|
3879
|
+
onBack,
|
|
3880
|
+
prevLabel,
|
|
3881
|
+
nextLabel,
|
|
3882
|
+
backLabel,
|
|
3883
|
+
keyboardShortcuts = false,
|
|
3884
|
+
shortcutOptions,
|
|
3885
|
+
progress,
|
|
3886
|
+
...props
|
|
3887
|
+
}) {
|
|
3888
|
+
const ownNavigation = useKeepNavigator({ currentId, initialIndex });
|
|
3889
|
+
const navigation = providedNavigation ?? ownNavigation;
|
|
3890
|
+
const previousLabel = useUiLabel("previousPage", prevLabel);
|
|
3891
|
+
const nextItemLabel = useUiLabel("nextPage", nextLabel);
|
|
3892
|
+
const listLabel = useUiLabel("allItems", backLabel);
|
|
3893
|
+
const { labels } = useKeepUiLabels();
|
|
3894
|
+
const resolvedPrev = onPrev ?? (() => navigateTo(navigation.goToPrev(), prevHref));
|
|
3895
|
+
const resolvedNext = onNext ?? (() => navigateTo(navigation.goToNext(), nextHref));
|
|
3896
|
+
useKeepTourShortcuts({
|
|
3897
|
+
...shortcutOptions,
|
|
3898
|
+
enabled: keyboardShortcuts && (shortcutOptions?.enabled ?? true),
|
|
3899
|
+
onNext: () => {
|
|
3900
|
+
return resolvedNext();
|
|
3901
|
+
},
|
|
3902
|
+
onPrev: () => {
|
|
3903
|
+
return resolvedPrev();
|
|
3904
|
+
}
|
|
3905
|
+
});
|
|
3906
|
+
return /* @__PURE__ */ jsxs14("nav", { ...props, "data-keepkit": "tour-bar", "aria-label": props["aria-label"] ?? labels.pagination, children: [
|
|
3907
|
+
showProgress ? /* @__PURE__ */ jsx20("span", { "data-keepkit": "tour-progress", "aria-live": "polite", children: progress ?? `${navigation.currentPosition ?? 0} / ${navigation.items.length}` }) : null,
|
|
3908
|
+
/* @__PURE__ */ jsx20(
|
|
3909
|
+
TourAction,
|
|
3910
|
+
{
|
|
3911
|
+
href: prevHref,
|
|
3912
|
+
disabled: !navigation.hasPrev,
|
|
3913
|
+
onClick: prevHref ? onPrev : resolvedPrev,
|
|
3914
|
+
"data-keep-action": "tour-prev",
|
|
3915
|
+
children: previousLabel
|
|
3916
|
+
}
|
|
3917
|
+
),
|
|
3918
|
+
/* @__PURE__ */ jsx20(
|
|
3919
|
+
TourAction,
|
|
3920
|
+
{
|
|
3921
|
+
href: nextHref,
|
|
3922
|
+
disabled: !navigation.hasNext,
|
|
3923
|
+
onClick: nextHref ? onNext : resolvedNext,
|
|
3924
|
+
"data-keep-action": "tour-next",
|
|
3925
|
+
children: nextItemLabel
|
|
3926
|
+
}
|
|
3927
|
+
),
|
|
3928
|
+
backHref || onBack ? /* @__PURE__ */ jsx20(TourAction, { href: backHref, onClick: onBack, "data-keep-action": "tour-back", children: listLabel }) : null
|
|
3929
|
+
] });
|
|
3930
|
+
}
|
|
3931
|
+
function TourAction({ href, disabled = false, onClick, children, ...props }) {
|
|
3932
|
+
if (href && !disabled) {
|
|
3933
|
+
return /* @__PURE__ */ jsx20("a", { ...props, href, onClick: () => void onClick?.(), children });
|
|
3934
|
+
}
|
|
3935
|
+
return /* @__PURE__ */ jsx20("button", { ...props, type: "button", disabled, onClick: () => void onClick?.(), children });
|
|
3936
|
+
}
|
|
3937
|
+
var KeepNavigator = KeepTourBar;
|
|
3938
|
+
function navigateTo(item, href) {
|
|
3939
|
+
if (!item || !href || typeof window === "undefined") return;
|
|
3940
|
+
window.location.assign(href);
|
|
3941
|
+
}
|
|
3942
|
+
|
|
3268
3943
|
// src/hooks/useKeepUndo.ts
|
|
3269
|
-
import { useKeepContext as
|
|
3944
|
+
import { useKeepContext as useKeepContext6 } from "@keepkit/core/react";
|
|
3270
3945
|
function useKeepUndo() {
|
|
3271
|
-
const context =
|
|
3946
|
+
const context = useKeepContext6();
|
|
3947
|
+
const emitFeedback = useKeepUiFeedback();
|
|
3948
|
+
const restoredMessage = useUiLabel("restoredMessage");
|
|
3272
3949
|
return {
|
|
3273
3950
|
canUndo: context.undo.canUndo,
|
|
3274
|
-
undo: () =>
|
|
3951
|
+
undo: async () => {
|
|
3952
|
+
const items = context.lastChange?.items ?? (context.lastChange?.item ? [context.lastChange.item] : []);
|
|
3953
|
+
await context.undoLastRemoval();
|
|
3954
|
+
if (items.length > 0) {
|
|
3955
|
+
emitFeedback({ type: "item-restored", item: items[0], items, message: restoredMessage });
|
|
3956
|
+
}
|
|
3957
|
+
},
|
|
3275
3958
|
message: useUiLabel("undoAvailable"),
|
|
3276
3959
|
label: useUiLabel("undo")
|
|
3277
3960
|
};
|
|
3278
3961
|
}
|
|
3279
3962
|
|
|
3280
3963
|
// src/KeepUndo.tsx
|
|
3281
|
-
import { jsx as
|
|
3964
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3282
3965
|
function KeepUndo({ children, label, ...props }) {
|
|
3283
3966
|
const view = useKeepUndo();
|
|
3284
3967
|
if (!view.canUndo) return null;
|
|
3285
|
-
return /* @__PURE__ */
|
|
3968
|
+
return /* @__PURE__ */ jsxs15("div", { ...props, role: "status", "aria-live": "polite", "data-keepkit": "undo", "data-state": "available", children: [
|
|
3286
3969
|
children ?? view.message,
|
|
3287
|
-
/* @__PURE__ */
|
|
3970
|
+
/* @__PURE__ */ jsx21("button", { type: "button", "data-keep-action": "undo", onClick: () => void view.undo(), children: label ?? view.label })
|
|
3288
3971
|
] });
|
|
3289
3972
|
}
|
|
3290
3973
|
|
|
@@ -3292,13 +3975,13 @@ function KeepUndo({ children, label, ...props }) {
|
|
|
3292
3975
|
import { isValidElement as isValidElement6 } from "react";
|
|
3293
3976
|
|
|
3294
3977
|
// src/hooks/useStatusViews.ts
|
|
3295
|
-
import { useKeepContext as
|
|
3296
|
-
import { useEffect as
|
|
3978
|
+
import { useKeepContext as useKeepContext7 } from "@keepkit/core/react";
|
|
3979
|
+
import { useEffect as useEffect11, useRef as useRef7, useState as useState12 } from "react";
|
|
3297
3980
|
function useKeepEmptyState() {
|
|
3298
3981
|
return useUiLabel("noItems").replace(/\.$/, "");
|
|
3299
3982
|
}
|
|
3300
3983
|
function useKeepStatus(status) {
|
|
3301
|
-
const context =
|
|
3984
|
+
const context = useKeepContext7();
|
|
3302
3985
|
const resolvedStatus = status ?? getDerivedStatus(context);
|
|
3303
3986
|
const state = {
|
|
3304
3987
|
status: resolvedStatus,
|
|
@@ -3309,13 +3992,13 @@ function useKeepStatus(status) {
|
|
|
3309
3992
|
return { state, defaultLabel: useUiLabel(getStatusLabelKey3(resolvedStatus)) };
|
|
3310
3993
|
}
|
|
3311
3994
|
function useKeepAnnouncements(messages) {
|
|
3312
|
-
const context =
|
|
3995
|
+
const context = useKeepContext7();
|
|
3313
3996
|
const savedMessage = useUiLabel("savedMessage", messages?.save);
|
|
3314
3997
|
const removedMessage = useUiLabel("removedMessage", messages?.remove);
|
|
3315
3998
|
const noteSavedMessage = useUiLabel("noteSavedMessage", messages?.note);
|
|
3316
|
-
const [message, setMessage] =
|
|
3317
|
-
const lastChangeRef =
|
|
3318
|
-
|
|
3999
|
+
const [message, setMessage] = useState12("");
|
|
4000
|
+
const lastChangeRef = useRef7(void 0);
|
|
4001
|
+
useEffect11(() => {
|
|
3319
4002
|
const change = context.lastChange;
|
|
3320
4003
|
if (!change || change === lastChangeRef.current) return;
|
|
3321
4004
|
lastChangeRef.current = change;
|
|
@@ -3343,7 +4026,7 @@ function getStatusLabelKey3(status) {
|
|
|
3343
4026
|
}
|
|
3344
4027
|
|
|
3345
4028
|
// src/status.tsx
|
|
3346
|
-
import { Fragment as
|
|
4029
|
+
import { Fragment as Fragment9, jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3347
4030
|
function KeepEmptyState({
|
|
3348
4031
|
title,
|
|
3349
4032
|
description,
|
|
@@ -3355,9 +4038,9 @@ function KeepEmptyState({
|
|
|
3355
4038
|
}) {
|
|
3356
4039
|
const defaultTitle = useKeepEmptyState();
|
|
3357
4040
|
const contentChildren = asChild && isValidElement6(children) ? void 0 : children;
|
|
3358
|
-
const body = contentChildren ?? /* @__PURE__ */
|
|
3359
|
-
/* @__PURE__ */
|
|
3360
|
-
description ? /* @__PURE__ */
|
|
4041
|
+
const body = contentChildren ?? /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
4042
|
+
/* @__PURE__ */ jsx22("h2", { children: title ?? defaultTitle }),
|
|
4043
|
+
description ? /* @__PURE__ */ jsx22("p", { children: description }) : null,
|
|
3361
4044
|
action
|
|
3362
4045
|
] });
|
|
3363
4046
|
return renderRoot(
|
|
@@ -3399,7 +4082,7 @@ function KeepStatus({
|
|
|
3399
4082
|
}
|
|
3400
4083
|
function KeepAnnouncements({ messages, ...props }) {
|
|
3401
4084
|
const message = useKeepAnnouncements(messages);
|
|
3402
|
-
return /* @__PURE__ */
|
|
4085
|
+
return /* @__PURE__ */ jsx22(
|
|
3403
4086
|
"div",
|
|
3404
4087
|
{
|
|
3405
4088
|
...props,
|
|
@@ -3416,7 +4099,7 @@ var KeepAnnouncer = KeepAnnouncements;
|
|
|
3416
4099
|
|
|
3417
4100
|
// src/theme.tsx
|
|
3418
4101
|
import { cloneElement as cloneElement2, isValidElement as isValidElement7 } from "react";
|
|
3419
|
-
import { jsx as
|
|
4102
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
3420
4103
|
var keepThemeNames = [
|
|
3421
4104
|
"default",
|
|
3422
4105
|
"ocean",
|
|
@@ -3475,7 +4158,7 @@ function KeepThemeProvider({
|
|
|
3475
4158
|
throw new Error("KeepThemeProvider with asChild requires a single React element child.");
|
|
3476
4159
|
return cloneElement2(children, rootProps);
|
|
3477
4160
|
}
|
|
3478
|
-
return /* @__PURE__ */
|
|
4161
|
+
return /* @__PURE__ */ jsx23("div", { ...rootProps, children });
|
|
3479
4162
|
}
|
|
3480
4163
|
|
|
3481
4164
|
// src/index.tsx
|
|
@@ -3483,9 +4166,10 @@ import { createAuthenticatedSyncKit } from "@keepkit/core/core";
|
|
|
3483
4166
|
import {
|
|
3484
4167
|
KeepErrorBoundary as KeepErrorBoundary3,
|
|
3485
4168
|
KeepProvider,
|
|
3486
|
-
useKeepContext as
|
|
4169
|
+
useKeepContext as useKeepContext8,
|
|
3487
4170
|
useKeepItem as useKeepItem5,
|
|
3488
4171
|
useKeepList as useKeepList5,
|
|
4172
|
+
useKeepNavigator as useKeepNavigator2,
|
|
3489
4173
|
useKeepShortcut
|
|
3490
4174
|
} from "@keepkit/core/react";
|
|
3491
4175
|
import {
|
|
@@ -3498,11 +4182,12 @@ import {
|
|
|
3498
4182
|
LocalStorageSyncQueueAdapter,
|
|
3499
4183
|
SyncStorageAdapter
|
|
3500
4184
|
} from "@keepkit/core/storage";
|
|
3501
|
-
import { jsx as
|
|
4185
|
+
import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3502
4186
|
function KeepKitProvider({
|
|
3503
4187
|
labels,
|
|
3504
4188
|
locale,
|
|
3505
4189
|
labelResolver,
|
|
4190
|
+
onFeedback,
|
|
3506
4191
|
theme,
|
|
3507
4192
|
mode,
|
|
3508
4193
|
density,
|
|
@@ -3517,7 +4202,7 @@ function KeepKitProvider({
|
|
|
3517
4202
|
children,
|
|
3518
4203
|
...providerProps
|
|
3519
4204
|
}) {
|
|
3520
|
-
return /* @__PURE__ */
|
|
4205
|
+
return /* @__PURE__ */ jsx24(KeepUiProvider, { labels, locale, labelResolver, onFeedback, children: /* @__PURE__ */ jsx24(
|
|
3521
4206
|
KeepThemeProvider,
|
|
3522
4207
|
{
|
|
3523
4208
|
theme,
|
|
@@ -3531,9 +4216,10 @@ function KeepKitProvider({
|
|
|
3531
4216
|
className: themeClassName,
|
|
3532
4217
|
style: themeStyle,
|
|
3533
4218
|
asChild: themeAsChild,
|
|
3534
|
-
children: /* @__PURE__ */
|
|
4219
|
+
children: /* @__PURE__ */ jsxs17(CoreKeepProvider, { ...providerProps, children: [
|
|
4220
|
+
/* @__PURE__ */ jsx24(KeepSyncFeedbackObserver, {}),
|
|
3535
4221
|
children,
|
|
3536
|
-
/* @__PURE__ */
|
|
4222
|
+
/* @__PURE__ */ jsx24(KeepAnnouncements, {})
|
|
3537
4223
|
] })
|
|
3538
4224
|
}
|
|
3539
4225
|
) });
|
|
@@ -3543,6 +4229,7 @@ function createKeepKit(options = {}) {
|
|
|
3543
4229
|
labels,
|
|
3544
4230
|
locale,
|
|
3545
4231
|
labelResolver,
|
|
4232
|
+
onFeedback,
|
|
3546
4233
|
theme,
|
|
3547
4234
|
mode,
|
|
3548
4235
|
density,
|
|
@@ -3559,13 +4246,14 @@ function createKeepKit(options = {}) {
|
|
|
3559
4246
|
} = options;
|
|
3560
4247
|
const coreKit = createCoreKeepKit(coreOptions);
|
|
3561
4248
|
return {
|
|
3562
|
-
Provider: (props) => /* @__PURE__ */
|
|
4249
|
+
Provider: (props) => /* @__PURE__ */ jsx24(
|
|
3563
4250
|
KeepKitProvider,
|
|
3564
4251
|
{
|
|
3565
4252
|
...coreOptions,
|
|
3566
4253
|
labels,
|
|
3567
4254
|
locale,
|
|
3568
4255
|
labelResolver,
|
|
4256
|
+
onFeedback,
|
|
3569
4257
|
theme,
|
|
3570
4258
|
mode,
|
|
3571
4259
|
density,
|
|
@@ -3579,9 +4267,9 @@ function createKeepKit(options = {}) {
|
|
|
3579
4267
|
...props
|
|
3580
4268
|
}
|
|
3581
4269
|
),
|
|
3582
|
-
Button: (props) => /* @__PURE__ */
|
|
3583
|
-
Backup: (props) => /* @__PURE__ */
|
|
3584
|
-
Collection: (props) => /* @__PURE__ */
|
|
4270
|
+
Button: (props) => /* @__PURE__ */ jsx24(KeepButton, { ...props }),
|
|
4271
|
+
Backup: (props) => /* @__PURE__ */ jsx24(KeepBackup, { ...props }),
|
|
4272
|
+
Collection: (props) => /* @__PURE__ */ jsx24(
|
|
3585
4273
|
KeepCollection,
|
|
3586
4274
|
{
|
|
3587
4275
|
...props,
|
|
@@ -3595,6 +4283,7 @@ function createKeepKit(options = {}) {
|
|
|
3595
4283
|
useContext: () => coreKit.useContext(),
|
|
3596
4284
|
useItem: (item) => coreKit.useItem(item),
|
|
3597
4285
|
useList: (query) => coreKit.useList(query),
|
|
4286
|
+
useNavigator: (navigatorOptions) => coreKit.useNavigator(navigatorOptions),
|
|
3598
4287
|
useShortcut: (shortcutOptions) => coreKit.useShortcut(shortcutOptions)
|
|
3599
4288
|
};
|
|
3600
4289
|
}
|
|
@@ -3610,16 +4299,20 @@ export {
|
|
|
3610
4299
|
KeepCollection,
|
|
3611
4300
|
KeepEmptyState,
|
|
3612
4301
|
KeepErrorBoundary3 as KeepErrorBoundary,
|
|
4302
|
+
KeepHighlight,
|
|
3613
4303
|
KeepItemCard,
|
|
4304
|
+
KeepItemCardSkeleton,
|
|
3614
4305
|
KeepItemCheckbox,
|
|
3615
4306
|
KeepItemStatusBadge,
|
|
3616
4307
|
KeepKitProvider,
|
|
3617
4308
|
KeepLayout,
|
|
3618
4309
|
KeepList,
|
|
4310
|
+
KeepNavigator,
|
|
3619
4311
|
KeepNoteEditor,
|
|
3620
4312
|
KeepPagination,
|
|
3621
4313
|
KeepProvider,
|
|
3622
4314
|
KeepPruneStaleButton,
|
|
4315
|
+
KeepReorderableList,
|
|
3623
4316
|
KeepSearchInput,
|
|
3624
4317
|
KeepSortSelect,
|
|
3625
4318
|
KeepStaleNotice,
|
|
@@ -3629,6 +4322,7 @@ export {
|
|
|
3629
4322
|
KeepTagEditor,
|
|
3630
4323
|
KeepTagFilter,
|
|
3631
4324
|
KeepThemeProvider,
|
|
4325
|
+
KeepTourBar,
|
|
3632
4326
|
KeepUiProvider,
|
|
3633
4327
|
KeepUndo,
|
|
3634
4328
|
LocalStorageAdapter,
|
|
@@ -3640,13 +4334,17 @@ export {
|
|
|
3640
4334
|
createNextPagesRouterAdapter,
|
|
3641
4335
|
createStorageAdapter,
|
|
3642
4336
|
getKeepLocaleLabels,
|
|
4337
|
+
highlightText,
|
|
3643
4338
|
isAllSelected,
|
|
3644
4339
|
keepThemeNames,
|
|
3645
4340
|
toggleSelectAll,
|
|
3646
|
-
|
|
4341
|
+
useKeepContext8 as useKeepContext,
|
|
3647
4342
|
useKeepItem5 as useKeepItem,
|
|
3648
4343
|
useKeepList5 as useKeepList,
|
|
4344
|
+
useKeepNavigator2 as useKeepNavigator,
|
|
3649
4345
|
useKeepShortcut,
|
|
4346
|
+
useKeepToastFeedback,
|
|
4347
|
+
useKeepTourShortcuts,
|
|
3650
4348
|
useKeepUiLabels,
|
|
3651
4349
|
useKeepUrlSync
|
|
3652
4350
|
};
|