@keepkit/ui 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -107,6 +107,13 @@ var DE_LABELS = {
107
107
  allTags: "Alle",
108
108
  tags: "Tags",
109
109
  filterTags: "Gespeicherte Elemente nach Tag filtern",
110
+ activeFilters: "Aktive Filter",
111
+ clearFilters: "Filter l\xF6schen",
112
+ clearAllFilters: "Alle Filter l\xF6schen",
113
+ removeFilter: "entfernen",
114
+ noFilteredItems: "Keine passenden Elemente gefunden.",
115
+ noFilteredItemsDescription: "Passe die Suche an oder entferne einen Tag-Filter.",
116
+ emptyStorageDescription: "Speichere ein Element, damit es hier angezeigt wird.",
110
117
  note: "Notiz",
111
118
  saveNote: "Notiz speichern",
112
119
  noItems: "Keine gespeicherten Elemente.",
@@ -186,6 +193,13 @@ var EN_LABELS = {
186
193
  allTags: "All",
187
194
  tags: "Tags",
188
195
  filterTags: "Filter saved items by tag",
196
+ activeFilters: "Active filters",
197
+ clearFilters: "Clear filters",
198
+ clearAllFilters: "Clear all filters",
199
+ removeFilter: "Remove",
200
+ noFilteredItems: "No matching items found.",
201
+ noFilteredItemsDescription: "Try adjusting your search or removing a tag filter.",
202
+ emptyStorageDescription: "Save an item to see it here.",
189
203
  note: "Note",
190
204
  saveNote: "Save note",
191
205
  noItems: "No saved items.",
@@ -265,6 +279,13 @@ var ES_LABELS = {
265
279
  allTags: "Todos",
266
280
  tags: "Etiquetas",
267
281
  filterTags: "Filtrar elementos guardados por etiqueta",
282
+ activeFilters: "Filtros activos",
283
+ clearFilters: "Borrar filtros",
284
+ clearAllFilters: "Borrar todos los filtros",
285
+ removeFilter: "quitar",
286
+ noFilteredItems: "No se encontraron elementos coincidentes.",
287
+ noFilteredItemsDescription: "Ajusta la b\xFAsqueda o quita un filtro de etiqueta.",
288
+ emptyStorageDescription: "Guarda un elemento para verlo aqu\xED.",
268
289
  note: "Nota",
269
290
  saveNote: "Guardar nota",
270
291
  noItems: "No hay elementos guardados.",
@@ -344,6 +365,13 @@ var FIL_LABELS = {
344
365
  allTags: "Lahat",
345
366
  tags: "Mga tag",
346
367
  filterTags: "I-filter ang mga naka-save na item ayon sa tag",
368
+ activeFilters: "Mga aktibong filter",
369
+ clearFilters: "I-clear ang mga filter",
370
+ clearAllFilters: "I-clear ang lahat ng filter",
371
+ removeFilter: "alisin",
372
+ noFilteredItems: "Walang nakitang tumutugmang item.",
373
+ noFilteredItemsDescription: "Baguhin ang paghahanap o alisin ang filter ng tag.",
374
+ emptyStorageDescription: "Mag-save ng item para makita ito rito.",
347
375
  note: "Tala",
348
376
  saveNote: "I-save ang tala",
349
377
  noItems: "Walang naka-save na item.",
@@ -423,6 +451,13 @@ var FR_LABELS = {
423
451
  allTags: "Tous",
424
452
  tags: "\xC9tiquettes",
425
453
  filterTags: "Filtrer les \xE9l\xE9ments enregistr\xE9s par \xE9tiquette",
454
+ activeFilters: "Filtres actifs",
455
+ clearFilters: "Effacer les filtres",
456
+ clearAllFilters: "Effacer tous les filtres",
457
+ removeFilter: "supprimer",
458
+ noFilteredItems: "Aucun \xE9l\xE9ment correspondant trouv\xE9.",
459
+ noFilteredItemsDescription: "Modifiez votre recherche ou supprimez un filtre de tag.",
460
+ emptyStorageDescription: "Enregistrez un \xE9l\xE9ment pour le voir ici.",
426
461
  note: "Note",
427
462
  saveNote: "Enregistrer la note",
428
463
  noItems: "Aucun \xE9l\xE9ment enregistr\xE9.",
@@ -502,6 +537,13 @@ var ID_LABELS = {
502
537
  allTags: "Semua",
503
538
  tags: "Tag",
504
539
  filterTags: "Filter item tersimpan berdasarkan tag",
540
+ activeFilters: "Filter aktif",
541
+ clearFilters: "Hapus filter",
542
+ clearAllFilters: "Hapus semua filter",
543
+ removeFilter: "hapus",
544
+ noFilteredItems: "Tidak ada item yang cocok.",
545
+ noFilteredItemsDescription: "Ubah pencarian atau hapus filter tag.",
546
+ emptyStorageDescription: "Simpan item untuk melihatnya di sini.",
505
547
  note: "Catatan",
506
548
  saveNote: "Simpan catatan",
507
549
  noItems: "Belum ada item tersimpan.",
@@ -581,6 +623,13 @@ var IT_LABELS = {
581
623
  allTags: "Tutti",
582
624
  tags: "Tag",
583
625
  filterTags: "Filtra gli elementi salvati per tag",
626
+ activeFilters: "Filtri attivi",
627
+ clearFilters: "Cancella filtri",
628
+ clearAllFilters: "Cancella tutti i filtri",
629
+ removeFilter: "rimuovi",
630
+ noFilteredItems: "Nessun elemento corrispondente trovato.",
631
+ noFilteredItemsDescription: "Modifica la ricerca o rimuovi un filtro tag.",
632
+ emptyStorageDescription: "Salva un elemento per visualizzarlo qui.",
584
633
  note: "Nota",
585
634
  saveNote: "Salva nota",
586
635
  noItems: "Nessun elemento salvato.",
@@ -660,6 +709,13 @@ var JA_LABELS = {
660
709
  allTags: "\u3059\u3079\u3066",
661
710
  tags: "\u30BF\u30B0",
662
711
  filterTags: "\u4FDD\u5B58\u30A2\u30A4\u30C6\u30E0\u3092\u30BF\u30B0\u3067\u7D5E\u308A\u8FBC\u3080",
712
+ activeFilters: "\u9069\u7528\u4E2D\u306E\u6761\u4EF6",
713
+ clearFilters: "\u30D5\u30A3\u30EB\u30BF\u30FC\u3092\u30AF\u30EA\u30A2",
714
+ clearAllFilters: "\u3059\u3079\u3066\u306E\u6761\u4EF6\u3092\u30AF\u30EA\u30A2",
715
+ removeFilter: "\u3092\u89E3\u9664",
716
+ noFilteredItems: "\u4E00\u81F4\u3059\u308B\u30A2\u30A4\u30C6\u30E0\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F",
717
+ noFilteredItemsDescription: "\u691C\u7D22\u8A9E\u3092\u5909\u66F4\u3059\u308B\u304B\u3001\u30BF\u30B0\u306E\u7D5E\u308A\u8FBC\u307F\u3092\u89E3\u9664\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
718
+ emptyStorageDescription: "\u30A2\u30A4\u30C6\u30E0\u3092\u4FDD\u5B58\u3059\u308B\u3068\u3001\u3053\u3053\u306B\u8868\u793A\u3055\u308C\u307E\u3059\u3002",
663
719
  note: "\u30E1\u30E2",
664
720
  saveNote: "\u30E1\u30E2\u3092\u4FDD\u5B58",
665
721
  noItems: "\u4FDD\u5B58\u3055\u308C\u305F\u30A2\u30A4\u30C6\u30E0\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
@@ -739,6 +795,13 @@ var KO_LABELS = {
739
795
  allTags: "\uBAA8\uB450",
740
796
  tags: "\uD0DC\uADF8",
741
797
  filterTags: "\uD0DC\uADF8\uB85C \uC800\uC7A5 \uD56D\uBAA9 \uD544\uD130\uB9C1",
798
+ activeFilters: "\uD65C\uC131 \uD544\uD130",
799
+ clearFilters: "\uD544\uD130 \uC9C0\uC6B0\uAE30",
800
+ clearAllFilters: "\uBAA8\uB4E0 \uD544\uD130 \uC9C0\uC6B0\uAE30",
801
+ removeFilter: "\uC81C\uAC70",
802
+ noFilteredItems: "\uC77C\uCE58\uD558\uB294 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
803
+ noFilteredItemsDescription: "\uAC80\uC0C9\uC5B4\uB97C \uBC14\uAFB8\uAC70\uB098 \uD0DC\uADF8 \uD544\uD130\uB97C \uC81C\uAC70\uD574 \uBCF4\uC138\uC694.",
804
+ emptyStorageDescription: "\uD56D\uBAA9\uC744 \uC800\uC7A5\uD558\uBA74 \uC5EC\uAE30\uC5D0 \uD45C\uC2DC\uB429\uB2C8\uB2E4.",
742
805
  note: "\uBA54\uBAA8",
743
806
  saveNote: "\uBA54\uBAA8 \uC800\uC7A5",
744
807
  noItems: "\uC800\uC7A5\uB41C \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -818,6 +881,13 @@ var MS_LABELS = {
818
881
  allTags: "Semua",
819
882
  tags: "Tag",
820
883
  filterTags: "Tapis item yang disimpan mengikut tag",
884
+ activeFilters: "Penapis aktif",
885
+ clearFilters: "Kosongkan penapis",
886
+ clearAllFilters: "Kosongkan semua penapis",
887
+ removeFilter: "alih keluar",
888
+ noFilteredItems: "Tiada item yang sepadan ditemui.",
889
+ noFilteredItemsDescription: "Laraskan carian atau alih keluar penapis tag.",
890
+ emptyStorageDescription: "Simpan item untuk melihatnya di sini.",
821
891
  note: "Nota",
822
892
  saveNote: "Simpan nota",
823
893
  noItems: "Tiada item disimpan.",
@@ -897,6 +967,13 @@ var PT_BR_LABELS = {
897
967
  allTags: "Todos",
898
968
  tags: "Tags",
899
969
  filterTags: "Filtrar itens salvos por tag",
970
+ activeFilters: "Filtros ativos",
971
+ clearFilters: "Limpar filtros",
972
+ clearAllFilters: "Limpar todos os filtros",
973
+ removeFilter: "remover",
974
+ noFilteredItems: "Nenhum item correspondente encontrado.",
975
+ noFilteredItemsDescription: "Ajuste sua busca ou remova um filtro de tag.",
976
+ emptyStorageDescription: "Salve um item para v\xEA-lo aqui.",
900
977
  note: "Nota",
901
978
  saveNote: "Salvar nota",
902
979
  noItems: "Nenhum item salvo.",
@@ -976,6 +1053,13 @@ var RU_LABELS = {
976
1053
  allTags: "\u0412\u0441\u0435",
977
1054
  tags: "\u0422\u0435\u0433\u0438",
978
1055
  filterTags: "\u0424\u0438\u043B\u044C\u0442\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B \u043F\u043E \u0442\u0435\u0433\u0443",
1056
+ activeFilters: "\u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0435 \u0444\u0438\u043B\u044C\u0442\u0440\u044B",
1057
+ clearFilters: "\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u0444\u0438\u043B\u044C\u0442\u0440\u044B",
1058
+ clearAllFilters: "\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u0432\u0441\u0435 \u0444\u0438\u043B\u044C\u0442\u0440\u044B",
1059
+ removeFilter: "\u0443\u0434\u0430\u043B\u0438\u0442\u044C",
1060
+ noFilteredItems: "\u041F\u043E\u0434\u0445\u043E\u0434\u044F\u0449\u0438\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u044B.",
1061
+ noFilteredItemsDescription: "\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u0435 \u043F\u043E\u0438\u0441\u043A \u0438\u043B\u0438 \u0443\u0434\u0430\u043B\u0438\u0442\u0435 \u0444\u0438\u043B\u044C\u0442\u0440 \u0442\u0435\u0433\u0430.",
1062
+ emptyStorageDescription: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442, \u0447\u0442\u043E\u0431\u044B \u0443\u0432\u0438\u0434\u0435\u0442\u044C \u0435\u0433\u043E \u0437\u0434\u0435\u0441\u044C.",
979
1063
  note: "\u0417\u0430\u043C\u0435\u0442\u043A\u0430",
980
1064
  saveNote: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u0437\u0430\u043C\u0435\u0442\u043A\u0443",
981
1065
  noItems: "\u041D\u0435\u0442 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0445 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432.",
@@ -1055,6 +1139,13 @@ var TH_LABELS = {
1055
1139
  allTags: "\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
1056
1140
  tags: "\u0E41\u0E17\u0E47\u0E01",
1057
1141
  filterTags: "\u0E01\u0E23\u0E2D\u0E07\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E14\u0E49\u0E27\u0E22\u0E41\u0E17\u0E47\u0E01",
1142
+ activeFilters: "\u0E15\u0E31\u0E27\u0E01\u0E23\u0E2D\u0E07\u0E17\u0E35\u0E48\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E2D\u0E22\u0E39\u0E48",
1143
+ clearFilters: "\u0E25\u0E49\u0E32\u0E07\u0E15\u0E31\u0E27\u0E01\u0E23\u0E2D\u0E07",
1144
+ clearAllFilters: "\u0E25\u0E49\u0E32\u0E07\u0E15\u0E31\u0E27\u0E01\u0E23\u0E2D\u0E07\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
1145
+ removeFilter: "\u0E19\u0E33\u0E2D\u0E2D\u0E01",
1146
+ noFilteredItems: "\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E15\u0E23\u0E07\u0E01\u0E31\u0E19",
1147
+ noFilteredItemsDescription: "\u0E25\u0E2D\u0E07\u0E1B\u0E23\u0E31\u0E1A\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E2B\u0E23\u0E37\u0E2D\u0E19\u0E33\u0E15\u0E31\u0E27\u0E01\u0E23\u0E2D\u0E07\u0E41\u0E17\u0E47\u0E01\u0E2D\u0E2D\u0E01",
1148
+ emptyStorageDescription: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E14\u0E39\u0E17\u0E35\u0E48\u0E19\u0E35\u0E48",
1058
1149
  note: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E22\u0E48\u0E2D",
1059
1150
  saveNote: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E22\u0E48\u0E2D",
1060
1151
  noItems: "\u0E44\u0E21\u0E48\u0E21\u0E35\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E44\u0E27\u0E49",
@@ -1134,6 +1225,13 @@ var VI_LABELS = {
1134
1225
  allTags: "T\u1EA5t c\u1EA3",
1135
1226
  tags: "Th\u1EBB",
1136
1227
  filterTags: "L\u1ECDc m\u1EE5c \u0111\xE3 l\u01B0u theo th\u1EBB",
1228
+ activeFilters: "B\u1ED9 l\u1ECDc \u0111ang d\xF9ng",
1229
+ clearFilters: "X\xF3a b\u1ED9 l\u1ECDc",
1230
+ clearAllFilters: "X\xF3a t\u1EA5t c\u1EA3 b\u1ED9 l\u1ECDc",
1231
+ removeFilter: "x\xF3a",
1232
+ noFilteredItems: "Kh\xF4ng t\xECm th\u1EA5y m\u1EE5c ph\xF9 h\u1EE3p.",
1233
+ noFilteredItemsDescription: "H\xE3y \u0111i\u1EC1u ch\u1EC9nh t\xECm ki\u1EBFm ho\u1EB7c x\xF3a b\u1ED9 l\u1ECDc th\u1EBB.",
1234
+ emptyStorageDescription: "L\u01B0u m\u1ED9t m\u1EE5c \u0111\u1EC3 xem m\u1EE5c \u0111\xF3 t\u1EA1i \u0111\xE2y.",
1137
1235
  note: "Ghi ch\xFA",
1138
1236
  saveNote: "L\u01B0u ghi ch\xFA",
1139
1237
  noItems: "Ch\u01B0a c\xF3 m\u1EE5c n\xE0o \u0111\u01B0\u1EE3c l\u01B0u.",
@@ -1213,6 +1311,13 @@ var ZH_HANS_LABELS = {
1213
1311
  allTags: "\u5168\u90E8",
1214
1312
  tags: "\u6807\u7B7E",
1215
1313
  filterTags: "\u6309\u6807\u7B7E\u7B5B\u9009\u5DF2\u4FDD\u5B58\u9879\u76EE",
1314
+ activeFilters: "\u5F53\u524D\u7B5B\u9009\u6761\u4EF6",
1315
+ clearFilters: "\u6E05\u9664\u7B5B\u9009",
1316
+ clearAllFilters: "\u6E05\u9664\u6240\u6709\u7B5B\u9009\u6761\u4EF6",
1317
+ removeFilter: "\u79FB\u9664",
1318
+ noFilteredItems: "\u672A\u627E\u5230\u5339\u914D\u9879\u76EE\u3002",
1319
+ noFilteredItemsDescription: "\u8BF7\u8C03\u6574\u641C\u7D22\u6761\u4EF6\u6216\u79FB\u9664\u6807\u7B7E\u7B5B\u9009\u3002",
1320
+ emptyStorageDescription: "\u4FDD\u5B58\u9879\u76EE\u540E\u4F1A\u663E\u793A\u5728\u8FD9\u91CC\u3002",
1216
1321
  note: "\u5907\u6CE8",
1217
1322
  saveNote: "\u4FDD\u5B58\u5907\u6CE8",
1218
1323
  noItems: "\u6CA1\u6709\u5DF2\u4FDD\u5B58\u7684\u9879\u76EE\u3002",
@@ -1292,6 +1397,13 @@ var ZH_HANT_LABELS = {
1292
1397
  allTags: "\u5168\u90E8",
1293
1398
  tags: "\u6A19\u7C64",
1294
1399
  filterTags: "\u4F9D\u6A19\u7C64\u7BE9\u9078\u5DF2\u5132\u5B58\u9805\u76EE",
1400
+ activeFilters: "\u76EE\u524D\u7BE9\u9078\u689D\u4EF6",
1401
+ clearFilters: "\u6E05\u9664\u7BE9\u9078",
1402
+ clearAllFilters: "\u6E05\u9664\u6240\u6709\u7BE9\u9078\u689D\u4EF6",
1403
+ removeFilter: "\u79FB\u9664",
1404
+ noFilteredItems: "\u627E\u4E0D\u5230\u76F8\u7B26\u9805\u76EE\u3002",
1405
+ noFilteredItemsDescription: "\u8ACB\u8ABF\u6574\u641C\u5C0B\u689D\u4EF6\u6216\u79FB\u9664\u6A19\u7C64\u7BE9\u9078\u3002",
1406
+ emptyStorageDescription: "\u5132\u5B58\u9805\u76EE\u5F8C\u6703\u986F\u793A\u5728\u9019\u88E1\u3002",
1295
1407
  note: "\u5099\u8A3B",
1296
1408
  saveNote: "\u5132\u5B58\u5099\u8A3B",
1297
1409
  noItems: "\u6C92\u6709\u5DF2\u5132\u5B58\u7684\u9805\u76EE\u3002",
@@ -1600,7 +1712,8 @@ import {
1600
1712
  cloneElement,
1601
1713
  createContext as createContext2,
1602
1714
  isValidElement,
1603
- useContext as useContext2
1715
+ useContext as useContext2,
1716
+ useMemo as useMemo2
1604
1717
  } from "react";
1605
1718
  import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
1606
1719
  var KeepSearchQueryContext = createContext2(void 0);
@@ -1613,8 +1726,11 @@ function useKeepSearchQuery() {
1613
1726
  function KeepHighlight({ children, query }) {
1614
1727
  const contextQuery = useKeepSearchQuery();
1615
1728
  const resolvedQuery = query ?? contextQuery;
1616
- if (typeof children !== "string" || !resolvedQuery?.trim()) return children ?? null;
1617
- return highlightText(children, resolvedQuery);
1729
+ const normalizedQuery = resolvedQuery?.trim() ?? "";
1730
+ return useMemo2(() => {
1731
+ if (typeof children !== "string" || !normalizedQuery) return children ?? null;
1732
+ return highlightText(children, normalizedQuery);
1733
+ }, [children, normalizedQuery]);
1618
1734
  }
1619
1735
  function highlightText(text, query) {
1620
1736
  const normalizedQuery = query.trim();
@@ -1664,10 +1780,79 @@ function sortToValue(sort) {
1664
1780
  function resolveContent(content, state) {
1665
1781
  return typeof content === "function" ? content(state) : content;
1666
1782
  }
1783
+ function composeRefs(...refs) {
1784
+ return (value) => {
1785
+ for (const ref of refs) {
1786
+ if (typeof ref === "function") {
1787
+ ref(value);
1788
+ } else if (ref !== null && ref !== void 0) {
1789
+ ref.current = value;
1790
+ }
1791
+ }
1792
+ };
1793
+ }
1794
+ function chainedFunction(childHandler, parentHandler) {
1795
+ if (!childHandler) return parentHandler;
1796
+ if (!parentHandler) return childHandler;
1797
+ return ((...args) => {
1798
+ childHandler(...args);
1799
+ parentHandler(...args);
1800
+ });
1801
+ }
1802
+ function mergeProps(childProps, parentProps) {
1803
+ const merged = { ...parentProps, ...childProps };
1804
+ if ("ref" in childProps || "ref" in parentProps) {
1805
+ merged.ref = composeRefs(
1806
+ childProps.ref,
1807
+ parentProps.ref
1808
+ );
1809
+ }
1810
+ const className = mergeClassNames(childProps.className, parentProps.className);
1811
+ if (className) merged.className = className;
1812
+ const style = mergeStyles(childProps.style, parentProps.style);
1813
+ if (style) merged.style = style;
1814
+ for (const key of Object.keys(parentProps)) {
1815
+ if (!isEventProp(key)) continue;
1816
+ const chained = chainedFunction(getHandler(childProps[key]), getHandler(parentProps[key]));
1817
+ if (chained) merged[key] = chained;
1818
+ }
1819
+ for (const [key, value] of Object.entries(merged)) {
1820
+ if (value === void 0 && key.startsWith("aria-") && childProps[key] !== void 0) {
1821
+ merged[key] = childProps[key];
1822
+ }
1823
+ }
1824
+ return merged;
1825
+ }
1826
+ function getHandler(value) {
1827
+ return typeof value === "function" ? value : void 0;
1828
+ }
1829
+ function isEventProp(key) {
1830
+ return key.startsWith("on") && key.length > 2 && key[2] === key[2]?.toUpperCase();
1831
+ }
1832
+ function mergeClassNames(childClassName, parentClassName) {
1833
+ const values = [childClassName, parentClassName].filter(
1834
+ (value) => typeof value === "string" && Boolean(value)
1835
+ );
1836
+ return values.length > 0 ? values.join(" ") : void 0;
1837
+ }
1838
+ function mergeStyles(childStyle, parentStyle) {
1839
+ if (!childStyle && !parentStyle) return void 0;
1840
+ return {
1841
+ ...isObject(childStyle) ? childStyle : {},
1842
+ ...isObject(parentStyle) ? parentStyle : {}
1843
+ };
1844
+ }
1845
+ function isObject(value) {
1846
+ return typeof value === "object" && value !== null;
1847
+ }
1848
+ function createSlot(child, props, body) {
1849
+ const nextProps = body === void 0 ? props : { ...props, children: body };
1850
+ return cloneElement(child, mergeProps(child.props, nextProps));
1851
+ }
1667
1852
  function renderRoot(asChild, child, props, body, componentName) {
1668
1853
  if (asChild) {
1669
1854
  if (!isValidElement(child)) throw new Error(`${componentName} with asChild requires a single React element child.`);
1670
- return cloneElement(child, { ...props, children: body });
1855
+ return createSlot(child, props, body);
1671
1856
  }
1672
1857
  return /* @__PURE__ */ jsx3("div", { ...props, children: body });
1673
1858
  }
@@ -2087,12 +2272,157 @@ function KeepUndo({ children, label, ...props }) {
2087
2272
  // src/features/collection/KeepCollection.tsx
2088
2273
  import { KeepErrorBoundary as KeepErrorBoundary2 } from "@keepkit/core/react";
2089
2274
 
2275
+ // src/features/query/KeepActiveFiltersSummary.tsx
2276
+ import {
2277
+ isValidElement as isValidElement2,
2278
+ useRef as useRef4
2279
+ } from "react";
2280
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
2281
+ function KeepActiveFiltersSummary({
2282
+ query,
2283
+ search: providedSearch,
2284
+ tags: providedTags,
2285
+ onSearchChange,
2286
+ onTagChange,
2287
+ onClear,
2288
+ children,
2289
+ asChild = false,
2290
+ className,
2291
+ ...rootProps
2292
+ }) {
2293
+ const search = (providedSearch ?? query?.search?.query ?? "").trim();
2294
+ const tags = normalizeTags(providedTags ?? query?.tags ?? []);
2295
+ const hasFilters = Boolean(search) || tags.length > 0;
2296
+ const activeFiltersLabel = useUiLabel("activeFilters");
2297
+ const clearAllLabel = useUiLabel("clearAllFilters");
2298
+ const clearLabel = useUiLabel("clearFilters");
2299
+ const removeLabel = useUiLabel("removeFilter");
2300
+ const chipRefs = useRef4([]);
2301
+ const filterCount = Number(Boolean(search)) + tags.length;
2302
+ function focusChip(index) {
2303
+ chipRefs.current[index]?.focus();
2304
+ }
2305
+ function focusAfterRemoval(index, source) {
2306
+ const summaryRoot = source.closest('[data-keepkit="active-filters"]');
2307
+ const fallbackScope = source.closest('[data-keepkit="collection"]') ?? summaryRoot?.parentElement ?? source.parentElement;
2308
+ queueMicrotask(() => {
2309
+ const nextIndex = index < filterCount - 1 ? index : index - 1;
2310
+ const nextChip = nextIndex >= 0 ? chipRefs.current[nextIndex] : null;
2311
+ if (nextChip?.isConnected) {
2312
+ nextChip.focus();
2313
+ return;
2314
+ }
2315
+ focusFilterFallback(fallbackScope);
2316
+ });
2317
+ }
2318
+ function handleChipKeyDown(event, index) {
2319
+ const nextIndex = event.key === "ArrowRight" ? index + 1 : event.key === "ArrowLeft" ? index - 1 : -1;
2320
+ if (nextIndex < 0 || nextIndex >= filterCount || !chipRefs.current[nextIndex]) return;
2321
+ event.preventDefault();
2322
+ focusChip(nextIndex);
2323
+ }
2324
+ function removeSearch(event) {
2325
+ focusAfterRemoval(0, event.currentTarget);
2326
+ onSearchChange?.("");
2327
+ }
2328
+ function removeTag(tag, index, event) {
2329
+ focusAfterRemoval(index, event.currentTarget);
2330
+ onTagChange?.(tag);
2331
+ }
2332
+ const state = {
2333
+ search,
2334
+ tags,
2335
+ hasFilters,
2336
+ clear: () => onClear?.(),
2337
+ removeSearch: () => onSearchChange?.(""),
2338
+ removeTag: (tag) => onTagChange?.(tag)
2339
+ };
2340
+ const contentChildren = asChild && isElement(children) ? void 0 : children;
2341
+ const body = typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? (hasFilters ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
2342
+ /* @__PURE__ */ jsx8("span", { "data-active-filters-label": "true", children: activeFiltersLabel }),
2343
+ /* @__PURE__ */ jsxs5("ul", { "data-active-filters-list": "true", children: [
2344
+ search ? /* @__PURE__ */ jsxs5("li", { "data-filter-kind": "search", children: [
2345
+ /* @__PURE__ */ jsx8("span", { "data-filter-value": "true", children: search }),
2346
+ /* @__PURE__ */ jsx8(
2347
+ "button",
2348
+ {
2349
+ type: "button",
2350
+ "data-keep-action": "remove-search-filter",
2351
+ "aria-label": `${search} ${removeLabel}`,
2352
+ ref: (element) => {
2353
+ chipRefs.current[0] = element;
2354
+ },
2355
+ onKeyDown: (event) => handleChipKeyDown(event, 0),
2356
+ onClick: removeSearch,
2357
+ children: "\xD7"
2358
+ }
2359
+ )
2360
+ ] }) : null,
2361
+ tags.map((tag, tagIndex) => /* @__PURE__ */ jsxs5("li", { "data-filter-kind": "tag", children: [
2362
+ /* @__PURE__ */ jsx8("span", { "data-filter-value": "true", children: tag }),
2363
+ /* @__PURE__ */ jsx8(
2364
+ "button",
2365
+ {
2366
+ type: "button",
2367
+ "data-keep-action": "remove-tag-filter",
2368
+ "aria-label": `${tag} ${removeLabel}`,
2369
+ ref: (element) => {
2370
+ chipRefs.current[tagIndex + Number(Boolean(search))] = element;
2371
+ },
2372
+ onKeyDown: (event) => handleChipKeyDown(event, tagIndex + Number(Boolean(search))),
2373
+ onClick: (event) => removeTag(tag, tagIndex + Number(Boolean(search)), event),
2374
+ children: "\xD7"
2375
+ }
2376
+ )
2377
+ ] }, tag))
2378
+ ] }),
2379
+ /* @__PURE__ */ jsx8("button", { type: "button", "data-keep-action": "clear-filters", onClick: state.clear, children: clearAllLabel || clearLabel })
2380
+ ] }) : null);
2381
+ if (!hasFilters && !asChild && contentChildren === void 0) return null;
2382
+ return renderRoot(
2383
+ asChild,
2384
+ isElement(children) ? children : void 0,
2385
+ {
2386
+ ...rootProps,
2387
+ className,
2388
+ "data-keepkit": "active-filters",
2389
+ "data-state": hasFilters ? "active" : "idle",
2390
+ "aria-label": rootProps["aria-label"] ?? activeFiltersLabel
2391
+ },
2392
+ body,
2393
+ "KeepActiveFiltersSummary"
2394
+ );
2395
+ }
2396
+ function normalizeTags(tags) {
2397
+ return [...new Set(tags.map((tag) => tag.trim()).filter(Boolean))];
2398
+ }
2399
+ function isElement(value) {
2400
+ return isValidElement2(value);
2401
+ }
2402
+ function focusFilterFallback(scope) {
2403
+ const searchInput = scope?.querySelector('[data-keep-action="search"]');
2404
+ if (searchInput) {
2405
+ searchInput.focus();
2406
+ return;
2407
+ }
2408
+ const listCard = scope?.querySelector('[data-keepkit="card"][tabindex="0"]');
2409
+ if (listCard) {
2410
+ listCard.focus();
2411
+ return;
2412
+ }
2413
+ const list = scope?.querySelector('[data-keepkit="list"]');
2414
+ if (list) {
2415
+ if (!list.hasAttribute("tabindex")) list.tabIndex = -1;
2416
+ list.focus();
2417
+ }
2418
+ }
2419
+
2090
2420
  // src/features/query/KeepTagFilter.tsx
2091
- import { isValidElement as isValidElement2 } from "react";
2421
+ import { isValidElement as isValidElement3 } from "react";
2092
2422
 
2093
2423
  // src/features/query/hooks/useKeepTagFilter.ts
2094
2424
  import { useKeepList as useKeepList2 } from "@keepkit/core/react";
2095
- import { useCallback as useCallback2, useMemo as useMemo2, useState as useState4 } from "react";
2425
+ import { useCallback as useCallback2, useMemo as useMemo3, useState as useState4 } from "react";
2096
2426
  function useKeepTagFilter(options) {
2097
2427
  const { query, controlledValue, defaultValue, onChange, onValueChange } = options;
2098
2428
  const [uncontrolledValue, setUncontrolledValue] = useState4(defaultValue);
@@ -2109,7 +2439,7 @@ function useKeepTagFilter(options) {
2109
2439
  },
2110
2440
  [controlledValue, onChange, onValueChange]
2111
2441
  );
2112
- const state = useMemo2(
2442
+ const state = useMemo3(
2113
2443
  () => ({ tags: list.tags, tagCounts: list.tagCounts, value: resolvedValue, select }),
2114
2444
  [list.tagCounts, list.tags, resolvedValue, select]
2115
2445
  );
@@ -2121,7 +2451,7 @@ function useKeepTagFilter(options) {
2121
2451
  }
2122
2452
 
2123
2453
  // src/features/query/KeepTagFilter.tsx
2124
- import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
2454
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2125
2455
  function KeepTagFilter({
2126
2456
  query,
2127
2457
  value: controlledValue,
@@ -2138,10 +2468,10 @@ function KeepTagFilter({
2138
2468
  ...rootProps
2139
2469
  }) {
2140
2470
  const view = useKeepTagFilter({ query, controlledValue, defaultValue, onChange, onValueChange });
2141
- const contentChildren = asChild && isValidElement2(children) ? void 0 : children;
2142
- const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */ jsxs5("fieldset", { children: [
2143
- /* @__PURE__ */ jsx8("legend", { children: ariaLabel ?? view.labels.aria }),
2144
- /* @__PURE__ */ jsx8(
2471
+ const contentChildren = asChild && isValidElement3(children) ? void 0 : children;
2472
+ const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */ jsxs6("fieldset", { children: [
2473
+ /* @__PURE__ */ jsx9("legend", { children: ariaLabel ?? view.labels.aria }),
2474
+ /* @__PURE__ */ jsx9(
2145
2475
  "button",
2146
2476
  {
2147
2477
  type: "button",
@@ -2151,7 +2481,7 @@ function KeepTagFilter({
2151
2481
  children: allLabel ?? view.labels.all
2152
2482
  }
2153
2483
  ),
2154
- view.state.tags.map((tag) => /* @__PURE__ */ jsxs5(
2484
+ view.state.tags.map((tag) => /* @__PURE__ */ jsxs6(
2155
2485
  "button",
2156
2486
  {
2157
2487
  type: "button",
@@ -2160,7 +2490,7 @@ function KeepTagFilter({
2160
2490
  onClick: () => view.state.select(tag),
2161
2491
  children: [
2162
2492
  renderTag ? renderTag(tag, view.state.tagCounts[tag] ?? 0, view.state.value === tag) : tag,
2163
- /* @__PURE__ */ jsxs5("span", { children: [
2493
+ /* @__PURE__ */ jsxs6("span", { children: [
2164
2494
  " (",
2165
2495
  view.state.tagCounts[tag] ?? 0,
2166
2496
  ")"
@@ -2172,7 +2502,7 @@ function KeepTagFilter({
2172
2502
  ] });
2173
2503
  return renderRoot(
2174
2504
  asChild,
2175
- isValidElement2(children) ? children : void 0,
2505
+ isValidElement3(children) ? children : void 0,
2176
2506
  {
2177
2507
  ...rootProps,
2178
2508
  className,
@@ -2258,7 +2588,7 @@ function getVisiblePages(currentPage, pageCount, maxPageButtons) {
2258
2588
  }
2259
2589
 
2260
2590
  // src/features/query/query-controls.tsx
2261
- import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2591
+ import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
2262
2592
  function KeepSearchInput({
2263
2593
  value: controlledValue,
2264
2594
  defaultValue = "",
@@ -2269,7 +2599,7 @@ function KeepSearchInput({
2269
2599
  ...props
2270
2600
  }) {
2271
2601
  const view = useKeepSearchInput({ controlledValue, defaultValue, debounceMs, onValueChange });
2272
- return /* @__PURE__ */ jsx9(
2602
+ return /* @__PURE__ */ jsx10(
2273
2603
  "input",
2274
2604
  {
2275
2605
  ...props,
@@ -2294,13 +2624,13 @@ function KeepSortSelect({
2294
2624
  ...props
2295
2625
  }) {
2296
2626
  const view = useKeepSortSelect({ controlledValue, defaultValue, onValueChange });
2297
- const options = children ?? /* @__PURE__ */ jsxs6(Fragment4, { children: [
2298
- /* @__PURE__ */ jsx9("option", { value: "updatedAt:desc", children: view.labels.updatedNewest }),
2299
- /* @__PURE__ */ jsx9("option", { value: "updatedAt:asc", children: view.labels.updatedOldest }),
2300
- /* @__PURE__ */ jsx9("option", { value: "savedAt:desc", children: view.labels.savedNewest }),
2301
- /* @__PURE__ */ jsx9("option", { value: "savedAt:asc", children: view.labels.savedOldest })
2627
+ const options = children ?? /* @__PURE__ */ jsxs7(Fragment5, { children: [
2628
+ /* @__PURE__ */ jsx10("option", { value: "updatedAt:desc", children: view.labels.updatedNewest }),
2629
+ /* @__PURE__ */ jsx10("option", { value: "updatedAt:asc", children: view.labels.updatedOldest }),
2630
+ /* @__PURE__ */ jsx10("option", { value: "savedAt:desc", children: view.labels.savedNewest }),
2631
+ /* @__PURE__ */ jsx10("option", { value: "savedAt:asc", children: view.labels.savedOldest })
2302
2632
  ] });
2303
- return /* @__PURE__ */ jsx9(
2633
+ return /* @__PURE__ */ jsx10(
2304
2634
  "select",
2305
2635
  {
2306
2636
  ...props,
@@ -2332,9 +2662,9 @@ function KeepPagination({
2332
2662
  "data-state": view.pageCount > 1 ? "active" : "idle"
2333
2663
  };
2334
2664
  if (render)
2335
- return /* @__PURE__ */ jsx9("nav", { ...navProps, children: render({ page: view.currentPage, pageCount: view.pageCount, goToPage: view.goToPage }) });
2336
- return /* @__PURE__ */ jsxs6("nav", { ...navProps, children: [
2337
- /* @__PURE__ */ jsx9(
2665
+ return /* @__PURE__ */ jsx10("nav", { ...navProps, children: render({ page: view.currentPage, pageCount: view.pageCount, goToPage: view.goToPage }) });
2666
+ return /* @__PURE__ */ jsxs7("nav", { ...navProps, children: [
2667
+ /* @__PURE__ */ jsx10(
2338
2668
  "button",
2339
2669
  {
2340
2670
  type: "button",
@@ -2344,7 +2674,7 @@ function KeepPagination({
2344
2674
  children: view.labels.previous
2345
2675
  }
2346
2676
  ),
2347
- view.visiblePages.map((nextPage) => /* @__PURE__ */ jsx9(
2677
+ view.visiblePages.map((nextPage) => /* @__PURE__ */ jsx10(
2348
2678
  "button",
2349
2679
  {
2350
2680
  type: "button",
@@ -2356,7 +2686,7 @@ function KeepPagination({
2356
2686
  },
2357
2687
  nextPage
2358
2688
  )),
2359
- /* @__PURE__ */ jsx9(
2689
+ /* @__PURE__ */ jsx10(
2360
2690
  "button",
2361
2691
  {
2362
2692
  type: "button",
@@ -2371,7 +2701,7 @@ function KeepPagination({
2371
2701
 
2372
2702
  // src/features/collection/hooks/useKeepCollection.ts
2373
2703
  import { useKeepList as useKeepList3 } from "@keepkit/core/react";
2374
- import { useMemo as useMemo3, useState as useState6 } from "react";
2704
+ import { useMemo as useMemo4, useState as useState6 } from "react";
2375
2705
  function useKeepCollection({
2376
2706
  query,
2377
2707
  pageSize,
@@ -2389,18 +2719,18 @@ function useKeepCollection({
2389
2719
  };
2390
2720
  const [searchValue, setSearchValue] = useState6(query.search?.query ?? "");
2391
2721
  const [sort, setSort] = useState6(query.sort ?? { by: "updatedAt", direction: "desc" });
2392
- const [tag, setTag] = useState6(query.tags?.[0]);
2722
+ const [activeTags, setActiveTags] = useState6(query.tags ?? []);
2393
2723
  const [page, setPage] = useState6(query.pagination?.page ?? 1);
2394
2724
  const resolvedPageSize = query.pagination?.pageSize ?? pageSize;
2395
- const resolvedQuery = useMemo3(
2725
+ const resolvedQuery = useMemo4(
2396
2726
  () => ({
2397
2727
  ...query,
2398
2728
  search: enabled.search ? { ...query.search, query: searchValue } : query.search,
2399
2729
  sort: enabled.sort ? sort : query.sort,
2400
- tags: tag ? [.../* @__PURE__ */ new Set([...query.tags ?? [], tag])] : query.tags,
2730
+ tags: activeTags.length > 0 ? activeTags : void 0,
2401
2731
  pagination: enabled.pagination ? { ...query.pagination, page, pageSize: resolvedPageSize } : query.pagination
2402
2732
  }),
2403
- [enabled.pagination, enabled.search, enabled.sort, page, query, resolvedPageSize, searchValue, sort, tag]
2733
+ [activeTags, enabled.pagination, enabled.search, enabled.sort, page, query, resolvedPageSize, searchValue, sort]
2404
2734
  );
2405
2735
  useKeepUrlSync({
2406
2736
  enabled: Boolean(urlSync),
@@ -2409,21 +2739,23 @@ function useKeepCollection({
2409
2739
  const next = typeof nextOrUpdater === "function" ? nextOrUpdater(resolvedQuery) : nextOrUpdater;
2410
2740
  setSearchValue(next.search?.query ?? "");
2411
2741
  setSort(next.sort ?? { by: "updatedAt", direction: "desc" });
2412
- setTag(next.tags?.[0]);
2742
+ setActiveTags(next.tags ?? []);
2413
2743
  setPage(next.pagination?.page ?? 1);
2414
2744
  },
2415
2745
  options: typeof urlSync === "object" ? urlSync : {},
2416
2746
  adapter: urlAdapter
2417
2747
  });
2418
2748
  const list = useKeepList3(resolvedQuery);
2749
+ const allState = useKeepList3({});
2419
2750
  return {
2420
2751
  enabled,
2421
2752
  searchValue,
2422
2753
  sortValue: sortToValue(sort),
2423
- tag,
2754
+ activeTags,
2424
2755
  resolvedPageSize,
2425
2756
  resolvedQuery,
2426
2757
  list,
2758
+ allState,
2427
2759
  setSearchValue: (value) => {
2428
2760
  setSearchValue(value);
2429
2761
  setPage(1);
@@ -2433,7 +2765,16 @@ function useKeepCollection({
2433
2765
  setPage(1);
2434
2766
  },
2435
2767
  setTag: (value) => {
2436
- setTag(value);
2768
+ setActiveTags(value ? [value] : []);
2769
+ setPage(1);
2770
+ },
2771
+ removeTag: (tagToRemove) => {
2772
+ setActiveTags((current) => current.filter((tag) => tag !== tagToRemove));
2773
+ setPage(1);
2774
+ },
2775
+ clearFilters: () => {
2776
+ setSearchValue("");
2777
+ setActiveTags([]);
2437
2778
  setPage(1);
2438
2779
  },
2439
2780
  setPage
@@ -2442,13 +2783,13 @@ function useKeepCollection({
2442
2783
 
2443
2784
  // src/features/collection/KeepList.tsx
2444
2785
  import { KeepErrorBoundary } from "@keepkit/core/react";
2445
- import { isValidElement as isValidElement4 } from "react";
2786
+ import { isValidElement as isValidElement6 } from "react";
2446
2787
 
2447
2788
  // src/features/item/KeepItemCard.tsx
2448
2789
  import {
2449
2790
  createContext as createContext3,
2450
2791
  createElement as createElement2,
2451
- isValidElement as isValidElement3,
2792
+ isValidElement as isValidElement4,
2452
2793
  useContext as useContext3,
2453
2794
  useEffect as useEffect5,
2454
2795
  useState as useState8
@@ -2494,10 +2835,10 @@ function getDisplayStatus(status) {
2494
2835
  }
2495
2836
 
2496
2837
  // src/features/item/KeepItemStatusBadge.tsx
2497
- import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
2838
+ import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
2498
2839
  function KeepItemStatusBadge({ status = "available", label, className, ...props }) {
2499
2840
  const view = useKeepItemStatusBadge(status);
2500
- return /* @__PURE__ */ jsxs7(
2841
+ return /* @__PURE__ */ jsxs8(
2501
2842
  "span",
2502
2843
  {
2503
2844
  ...props,
@@ -2508,14 +2849,14 @@ function KeepItemStatusBadge({ status = "available", label, className, ...props
2508
2849
  "data-status": status,
2509
2850
  "data-item-status": view.resolvedStatus,
2510
2851
  children: [
2511
- /* @__PURE__ */ jsx10(StatusIcon, { name: view.icon }),
2512
- /* @__PURE__ */ jsx10("span", { "data-status-label": "true", children: label ?? view.statusLabel })
2852
+ /* @__PURE__ */ jsx11(StatusIcon, { name: view.icon }),
2853
+ /* @__PURE__ */ jsx11("span", { "data-status-label": "true", children: label ?? view.statusLabel })
2513
2854
  ]
2514
2855
  }
2515
2856
  );
2516
2857
  }
2517
2858
  function StatusIcon({ name }) {
2518
- return /* @__PURE__ */ jsxs7(
2859
+ return /* @__PURE__ */ jsxs8(
2519
2860
  "svg",
2520
2861
  {
2521
2862
  "data-status-icon": name,
@@ -2530,18 +2871,18 @@ function StatusIcon({ name }) {
2530
2871
  "aria-hidden": "true",
2531
2872
  focusable: "false",
2532
2873
  children: [
2533
- name === "check" ? /* @__PURE__ */ jsx10("path", { d: "m5 12 4 4L19 6" }) : null,
2534
- name === "clock" ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
2535
- /* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "8" }),
2536
- /* @__PURE__ */ jsx10("path", { d: "M12 7v5l3 2" })
2874
+ name === "check" ? /* @__PURE__ */ jsx11("path", { d: "m5 12 4 4L19 6" }) : null,
2875
+ name === "clock" ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
2876
+ /* @__PURE__ */ jsx11("circle", { cx: "12", cy: "12", r: "8" }),
2877
+ /* @__PURE__ */ jsx11("path", { d: "M12 7v5l3 2" })
2537
2878
  ] }) : null,
2538
- name === "ban" ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
2539
- /* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "8" }),
2540
- /* @__PURE__ */ jsx10("path", { d: "m6.5 6.5 11 11" })
2879
+ name === "ban" ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
2880
+ /* @__PURE__ */ jsx11("circle", { cx: "12", cy: "12", r: "8" }),
2881
+ /* @__PURE__ */ jsx11("path", { d: "m6.5 6.5 11 11" })
2541
2882
  ] }) : null,
2542
- name === "lock" ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
2543
- /* @__PURE__ */ jsx10("rect", { x: "5", y: "10", width: "14", height: "10", rx: "2" }),
2544
- /* @__PURE__ */ jsx10("path", { d: "M8 10V7a4 4 0 0 1 8 0v3" })
2883
+ name === "lock" ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
2884
+ /* @__PURE__ */ jsx11("rect", { x: "5", y: "10", width: "14", height: "10", rx: "2" }),
2885
+ /* @__PURE__ */ jsx11("path", { d: "M8 10V7a4 4 0 0 1 8 0v3" })
2545
2886
  ] }) : null
2546
2887
  ]
2547
2888
  }
@@ -2638,7 +2979,7 @@ function useKeepPruneStale({ statuses, onPruned }) {
2638
2979
  }
2639
2980
 
2640
2981
  // src/features/status/KeepStaleNotice.tsx
2641
- import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
2982
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
2642
2983
  function KeepStaleNotice({
2643
2984
  item,
2644
2985
  onRetry,
@@ -2650,11 +2991,11 @@ function KeepStaleNotice({
2650
2991
  ...props
2651
2992
  }) {
2652
2993
  const view = useKeepStaleNotice({ item, onRetry, onRemoved });
2653
- return /* @__PURE__ */ jsxs8("aside", { ...props, className, "data-keepkit": "stale-notice", "data-state": view.error ? "error" : "stale", children: [
2654
- /* @__PURE__ */ jsx11(KeepItemStatusBadge, { status: view.status }),
2655
- children ?? (item.statusReason ? /* @__PURE__ */ jsx11("p", { children: item.statusReason }) : null),
2656
- /* @__PURE__ */ jsxs8("div", { children: [
2657
- /* @__PURE__ */ jsx11(
2994
+ return /* @__PURE__ */ jsxs9("aside", { ...props, className, "data-keepkit": "stale-notice", "data-state": view.error ? "error" : "stale", children: [
2995
+ /* @__PURE__ */ jsx12(KeepItemStatusBadge, { status: view.status }),
2996
+ children ?? (item.statusReason ? /* @__PURE__ */ jsx12("p", { children: item.statusReason }) : null),
2997
+ /* @__PURE__ */ jsxs9("div", { children: [
2998
+ /* @__PURE__ */ jsx12(
2658
2999
  "button",
2659
3000
  {
2660
3001
  type: "button",
@@ -2664,7 +3005,7 @@ function KeepStaleNotice({
2664
3005
  children: retryLabel ?? view.labels.retry
2665
3006
  }
2666
3007
  ),
2667
- /* @__PURE__ */ jsx11(
3008
+ /* @__PURE__ */ jsx12(
2668
3009
  "button",
2669
3010
  {
2670
3011
  type: "button",
@@ -2675,7 +3016,7 @@ function KeepStaleNotice({
2675
3016
  }
2676
3017
  )
2677
3018
  ] }),
2678
- view.error ? /* @__PURE__ */ jsx11("p", { role: "alert", children: view.error instanceof Error ? view.error.message : view.labels.error }) : null
3019
+ view.error ? /* @__PURE__ */ jsx12("p", { role: "alert", children: view.error instanceof Error ? view.error.message : view.labels.error }) : null
2679
3020
  ] });
2680
3021
  }
2681
3022
  function KeepPruneStaleButton({
@@ -2687,7 +3028,7 @@ function KeepPruneStaleButton({
2687
3028
  ...props
2688
3029
  }) {
2689
3030
  const view = useKeepPruneStale({ statuses, onPruned });
2690
- return /* @__PURE__ */ jsx11(
3031
+ return /* @__PURE__ */ jsx12(
2691
3032
  "button",
2692
3033
  {
2693
3034
  ...props,
@@ -2800,7 +3141,7 @@ function getDisplayStatus2(status) {
2800
3141
  }
2801
3142
 
2802
3143
  // src/features/item/KeepItemCard.tsx
2803
- import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
3144
+ import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
2804
3145
  var KeepItemCardContext = createContext3(null);
2805
3146
  function useKeepItemCardCompound(part) {
2806
3147
  const context = useContext3(KeepItemCardContext);
@@ -2850,7 +3191,7 @@ function KeepItemCardRoot({
2850
3191
  });
2851
3192
  const contextQuery = useKeepSearchQuery();
2852
3193
  const searchQuery = highlightQuery ?? contextQuery;
2853
- const contentChildren = asChild && isValidElement3(children) ? void 0 : children;
3194
+ const contentChildren = asChild && isValidElement4(children) ? void 0 : children;
2854
3195
  function renderLink(content) {
2855
3196
  if (!view.href || !view.isAvailable) return content;
2856
3197
  const linkProps = {
@@ -2860,12 +3201,12 @@ function KeepItemCardRoot({
2860
3201
  onClick: (event) => onOpen?.(item, event),
2861
3202
  children: content
2862
3203
  };
2863
- return LinkComponent ? /* @__PURE__ */ jsx12(LinkComponent, { ...linkProps }) : /* @__PURE__ */ jsx12("a", { ...linkProps });
3204
+ return LinkComponent ? /* @__PURE__ */ jsx13(LinkComponent, { ...linkProps }) : /* @__PURE__ */ jsx13("a", { ...linkProps });
2864
3205
  }
2865
3206
  function renderTitle(content) {
2866
3207
  if (linkTarget !== "title") return content;
2867
3208
  if (view.isAvailable) return renderLink(content);
2868
- return view.href ? /* @__PURE__ */ jsx12("span", { "aria-disabled": "true", "data-link-disabled": "true", children: content }) : content;
3209
+ return view.href ? /* @__PURE__ */ jsx13("span", { "aria-disabled": "true", "data-link-disabled": "true", children: content }) : content;
2869
3210
  }
2870
3211
  const resolvedImageProps = view.imageProps ? { ...view.imageProps, alt: imageAlt ?? view.imageProps.alt } : void 0;
2871
3212
  const imageSource = resolvedImageProps?.src;
@@ -2888,21 +3229,21 @@ function KeepItemCardRoot({
2888
3229
  setImageStatus("error");
2889
3230
  }
2890
3231
  };
2891
- image = renderImage?.(imagePropsWithHandlers, item) ?? (ImageComponent ? /* @__PURE__ */ jsx12(ImageComponent, { ...imagePropsWithHandlers }) : /* @__PURE__ */ jsx12("img", { ...imagePropsWithHandlers, alt: imagePropsWithHandlers.alt }));
3232
+ image = renderImage?.(imagePropsWithHandlers, item) ?? (ImageComponent ? /* @__PURE__ */ jsx13(ImageComponent, { ...imagePropsWithHandlers }) : /* @__PURE__ */ jsx13("img", { ...imagePropsWithHandlers, alt: imagePropsWithHandlers.alt }));
2892
3233
  }
2893
3234
  const tags = showTags ? item.tags ?? [] : [];
2894
3235
  const renderedTags = showTags && tags.length > 0 ? renderTags?.(tags, item) ?? null : null;
2895
- const meta = showSavedAt ? /* @__PURE__ */ jsxs9("div", { "data-card-meta": true, children: [
2896
- /* @__PURE__ */ jsxs9("span", { children: [
3236
+ const meta = showSavedAt ? /* @__PURE__ */ jsxs10("div", { "data-card-meta": true, children: [
3237
+ /* @__PURE__ */ jsxs10("span", { children: [
2897
3238
  view.labels.savedAt,
2898
3239
  ":"
2899
3240
  ] }),
2900
3241
  " ",
2901
- /* @__PURE__ */ jsx12("time", { dateTime: new Date(item.savedAt).toISOString(), children: formatSavedAt(item.savedAt) })
3242
+ /* @__PURE__ */ jsx13("time", { dateTime: new Date(item.savedAt).toISOString(), children: formatSavedAt(item.savedAt) })
2902
3243
  ] }) : null;
2903
- const error = view.itemState.error ? /* @__PURE__ */ jsx12("p", { role: "alert", children: getErrorMessage2(view.itemState.error, view.labels.error) }) : null;
2904
- const actions = view.statusLabel ? /* @__PURE__ */ jsx12(KeepStaleNotice, { item, onRetry, onRemoved }) : /* @__PURE__ */ jsxs9(Fragment6, { children: [
2905
- showSaveButton ? /* @__PURE__ */ jsx12(
3244
+ const error = view.itemState.error ? /* @__PURE__ */ jsx13("p", { role: "alert", children: getErrorMessage2(view.itemState.error, view.labels.error) }) : null;
3245
+ const actions = view.statusLabel ? /* @__PURE__ */ jsx13(KeepStaleNotice, { item, onRetry, onRemoved }) : /* @__PURE__ */ jsxs10(Fragment7, { children: [
3246
+ showSaveButton ? /* @__PURE__ */ jsx13(
2906
3247
  KeepButton,
2907
3248
  {
2908
3249
  item: toKeepButtonItem(item),
@@ -2910,7 +3251,7 @@ function KeepItemCardRoot({
2910
3251
  getAriaLabel: (buttonState) => `${buttonState.isSaved ? view.labels.remove : view.labels.save} ${String(view.resolvedTitle)}`
2911
3252
  }
2912
3253
  ) : null,
2913
- /* @__PURE__ */ jsx12(
3254
+ /* @__PURE__ */ jsx13(
2914
3255
  "button",
2915
3256
  {
2916
3257
  type: "button",
@@ -2933,18 +3274,18 @@ function KeepItemCardRoot({
2933
3274
  meta,
2934
3275
  error,
2935
3276
  actions,
2936
- renderText: (content) => /* @__PURE__ */ jsx12(KeepHighlight, { query: searchQuery, children: content })
3277
+ renderText: (content) => /* @__PURE__ */ jsx13(KeepHighlight, { query: searchQuery, children: content })
2937
3278
  };
2938
- const defaultBody = /* @__PURE__ */ jsxs9(Fragment6, { children: [
2939
- /* @__PURE__ */ jsx12(KeepItemCardMedia, {}),
2940
- /* @__PURE__ */ jsx12(KeepItemCardContent, {}),
2941
- /* @__PURE__ */ jsx12(KeepItemCardActions, {})
3279
+ const defaultBody = /* @__PURE__ */ jsxs10(Fragment7, { children: [
3280
+ /* @__PURE__ */ jsx13(KeepItemCardMedia, {}),
3281
+ /* @__PURE__ */ jsx13(KeepItemCardContent, {}),
3282
+ /* @__PURE__ */ jsx13(KeepItemCardActions, {})
2942
3283
  ] });
2943
3284
  const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? defaultBody;
2944
3285
  const linkedBody = linkTarget === "card" && view.isAvailable ? renderLink(body) : body;
2945
3286
  const root = renderRoot(
2946
3287
  asChild,
2947
- isValidElement3(children) ? children : void 0,
3288
+ isValidElement4(children) ? children : void 0,
2948
3289
  {
2949
3290
  ...rootProps,
2950
3291
  className,
@@ -2959,18 +3300,18 @@ function KeepItemCardRoot({
2959
3300
  linkedBody,
2960
3301
  "KeepItemCard"
2961
3302
  );
2962
- return /* @__PURE__ */ jsx12(KeepItemCardContext.Provider, { value: compoundValue, children: root });
3303
+ return /* @__PURE__ */ jsx13(KeepItemCardContext.Provider, { value: compoundValue, children: root });
2963
3304
  }
2964
3305
  function KeepItemCardMedia({ children, fallback, ...props }) {
2965
3306
  const context = useKeepItemCardCompound("Media");
2966
- return /* @__PURE__ */ jsx12("div", { ...props, "data-keep-card-part": "media", "data-media-status": context.imageStatus, "data-aspect-ratio": "1/1", children: children ?? context.image ?? /* @__PURE__ */ jsx12("span", { role: "img", "aria-label": context.fallbackLabel, "data-keep-card-fallback": "true", children: fallback ?? /* @__PURE__ */ jsx12(KeepMediaPlaceholderIcon, {}) }) });
3307
+ return /* @__PURE__ */ jsx13("div", { ...props, "data-keep-card-part": "media", "data-media-status": context.imageStatus, "data-aspect-ratio": "1/1", children: children ?? context.image ?? /* @__PURE__ */ jsx13("span", { role: "img", "aria-label": context.fallbackLabel, "data-keep-card-fallback": "true", children: fallback ?? /* @__PURE__ */ jsx13(KeepMediaPlaceholderIcon, {}) }) });
2967
3308
  }
2968
3309
  function KeepItemCardContent({ children, ...props }) {
2969
3310
  const context = useKeepItemCardCompound("Content");
2970
- return /* @__PURE__ */ jsx12("div", { ...props, "data-keep-card-part": "content", children: children === void 0 ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
2971
- /* @__PURE__ */ jsx12(KeepItemCardTitle, {}),
3311
+ return /* @__PURE__ */ jsx13("div", { ...props, "data-keep-card-part": "content", children: children === void 0 ? /* @__PURE__ */ jsxs10(Fragment7, { children: [
3312
+ /* @__PURE__ */ jsx13(KeepItemCardTitle, {}),
2972
3313
  context.meta,
2973
- /* @__PURE__ */ jsx12(KeepItemCardTags, {}),
3314
+ /* @__PURE__ */ jsx13(KeepItemCardTags, {}),
2974
3315
  context.error
2975
3316
  ] }) : context.renderText(children) });
2976
3317
  }
@@ -2983,8 +3324,8 @@ function KeepItemCardTitle({ as = "h3", children, ...props }) {
2983
3324
  );
2984
3325
  }
2985
3326
  function KeepMediaPlaceholderIcon() {
2986
- return /* @__PURE__ */ jsxs9("svg", { "data-media-fallback-icon": "true", viewBox: "0 0 24 24", "aria-hidden": "true", children: [
2987
- /* @__PURE__ */ jsx12(
3327
+ return /* @__PURE__ */ jsxs10("svg", { "data-media-fallback-icon": "true", viewBox: "0 0 24 24", "aria-hidden": "true", children: [
3328
+ /* @__PURE__ */ jsx13(
2988
3329
  "path",
2989
3330
  {
2990
3331
  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",
@@ -2992,19 +3333,19 @@ function KeepMediaPlaceholderIcon() {
2992
3333
  stroke: "currentColor"
2993
3334
  }
2994
3335
  ),
2995
- /* @__PURE__ */ jsx12("circle", { cx: "9", cy: "9", r: "1.5", fill: "currentColor" }),
2996
- /* @__PURE__ */ jsx12("path", { d: "m5.5 18 4.5-4.5 3 3 2-2L19 18", fill: "none", stroke: "currentColor" })
3336
+ /* @__PURE__ */ jsx13("circle", { cx: "9", cy: "9", r: "1.5", fill: "currentColor" }),
3337
+ /* @__PURE__ */ jsx13("path", { d: "m5.5 18 4.5-4.5 3 3 2-2L19 18", fill: "none", stroke: "currentColor" })
2997
3338
  ] });
2998
3339
  }
2999
3340
  function KeepItemCardTags({ children, ...props }) {
3000
3341
  const context = useKeepItemCardCompound("Tags");
3001
3342
  if (children === void 0 && context.renderedTags) return context.renderedTags;
3002
3343
  if (children === void 0 && context.tags.length === 0) return null;
3003
- return /* @__PURE__ */ jsx12("ul", { ...props, "aria-label": props["aria-label"] ?? context.tagsLabel, "data-keep-card-part": "tags", children: children ?? context.tags.map((tag) => /* @__PURE__ */ jsx12("li", { children: tag }, tag)) });
3344
+ return /* @__PURE__ */ jsx13("ul", { ...props, "aria-label": props["aria-label"] ?? context.tagsLabel, "data-keep-card-part": "tags", children: children ?? context.tags.map((tag) => /* @__PURE__ */ jsx13("li", { children: tag }, tag)) });
3004
3345
  }
3005
3346
  function KeepItemCardActions({ children, ...props }) {
3006
3347
  const context = useKeepItemCardCompound("Actions");
3007
- return /* @__PURE__ */ jsx12("div", { ...props, "data-keep-card-part": "actions", children: children ?? context.actions });
3348
+ return /* @__PURE__ */ jsx13("div", { ...props, "data-keep-card-part": "actions", children: children ?? context.actions });
3008
3349
  }
3009
3350
  var KeepItemCard = Object.assign(KeepItemCardRoot, {
3010
3351
  Media: KeepItemCardMedia,
@@ -3014,12 +3355,12 @@ var KeepItemCard = Object.assign(KeepItemCardRoot, {
3014
3355
  Actions: KeepItemCardActions
3015
3356
  });
3016
3357
  function KeepItemCardSkeleton({ layout = "list", ...props }) {
3017
- return /* @__PURE__ */ jsxs9("article", { ...props, "aria-hidden": "true", "data-keepkit": "card-skeleton", "data-layout": layout, "data-state": "loading", children: [
3018
- /* @__PURE__ */ jsx12("span", { "data-skeleton-part": "media" }),
3019
- /* @__PURE__ */ jsx12("span", { "data-skeleton-part": "title" }),
3020
- /* @__PURE__ */ jsx12("span", { "data-skeleton-part": "meta" }),
3021
- /* @__PURE__ */ jsx12("span", { "data-skeleton-part": "tag" }),
3022
- /* @__PURE__ */ jsx12("span", { "data-skeleton-part": "tag" })
3358
+ return /* @__PURE__ */ jsxs10("article", { ...props, "aria-hidden": "true", "data-keepkit": "card-skeleton", "data-layout": layout, "data-state": "loading", children: [
3359
+ /* @__PURE__ */ jsx13("span", { "data-skeleton-part": "media" }),
3360
+ /* @__PURE__ */ jsx13("span", { "data-skeleton-part": "title" }),
3361
+ /* @__PURE__ */ jsx13("span", { "data-skeleton-part": "meta" }),
3362
+ /* @__PURE__ */ jsx13("span", { "data-skeleton-part": "tag" }),
3363
+ /* @__PURE__ */ jsx13("span", { "data-skeleton-part": "tag" })
3023
3364
  ] });
3024
3365
  }
3025
3366
  function formatSavedAt(timestamp) {
@@ -3029,11 +3370,47 @@ function getErrorMessage2(error, fallback) {
3029
3370
  return error instanceof Error ? error.message : fallback;
3030
3371
  }
3031
3372
 
3373
+ // src/features/status/KeepEmptyState.tsx
3374
+ import { isValidElement as isValidElement5 } from "react";
3375
+ import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
3376
+ function KeepEmptyState({
3377
+ title,
3378
+ description,
3379
+ action,
3380
+ children,
3381
+ variant,
3382
+ onClearFilters,
3383
+ asChild = false,
3384
+ className,
3385
+ ...rootProps
3386
+ }) {
3387
+ const resolvedVariant = variant ?? "empty-storage";
3388
+ const defaultTitle = useUiLabel(resolvedVariant === "empty-filtered" ? "noFilteredItems" : "noItems");
3389
+ const defaultDescription = useUiLabel(
3390
+ resolvedVariant === "empty-filtered" ? "noFilteredItemsDescription" : "emptyStorageDescription"
3391
+ );
3392
+ const clearLabel = useUiLabel("clearFilters");
3393
+ const contentChildren = asChild && isValidElement5(children) ? void 0 : children;
3394
+ const body = contentChildren ?? /* @__PURE__ */ jsxs11(Fragment8, { children: [
3395
+ /* @__PURE__ */ jsx14("h2", { children: title ?? defaultTitle }),
3396
+ description ?? /* @__PURE__ */ jsx14("p", { children: defaultDescription }),
3397
+ action ?? (resolvedVariant === "empty-filtered" && onClearFilters ? /* @__PURE__ */ jsx14("button", { type: "button", "data-keep-action": "clear-filters", onClick: onClearFilters, children: clearLabel }) : null)
3398
+ ] });
3399
+ return renderRoot(
3400
+ asChild,
3401
+ children,
3402
+ { ...rootProps, className, "data-keepkit": "empty-state", "data-state": variant ?? "empty" },
3403
+ body,
3404
+ "KeepEmptyState"
3405
+ );
3406
+ }
3407
+
3032
3408
  // src/features/collection/hooks/useKeepListView.ts
3033
3409
  import { useKeepList as useKeepList4 } from "@keepkit/core/react";
3034
3410
  function useKeepListView(query) {
3035
3411
  return {
3036
3412
  state: useKeepList4(query),
3413
+ allState: useKeepList4({}),
3037
3414
  labels: {
3038
3415
  loading: useUiLabel("loadingItems"),
3039
3416
  empty: useUiLabel("noItems"),
@@ -3043,9 +3420,9 @@ function useKeepListView(query) {
3043
3420
  }
3044
3421
 
3045
3422
  // src/features/collection/hooks/useRovingTabIndex.ts
3046
- import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef4 } from "react";
3423
+ import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef5 } from "react";
3047
3424
  function useRovingTabIndex() {
3048
- const ref = useRef4(null);
3425
+ const ref = useRef5(null);
3049
3426
  const getItems = useCallback3(() => {
3050
3427
  const root = ref.current;
3051
3428
  if (!root) return [];
@@ -3108,12 +3485,12 @@ function useRovingTabIndex() {
3108
3485
  }
3109
3486
 
3110
3487
  // src/features/collection/KeepList.tsx
3111
- import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
3488
+ import { Fragment as Fragment9, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
3112
3489
  function KeepList(props) {
3113
3490
  const { fallback, onBoundaryError, boundaryResetKey, ...listProps } = props;
3114
- const content = /* @__PURE__ */ jsx13(KeepListContent, { ...listProps });
3491
+ const content = /* @__PURE__ */ jsx15(KeepListContent, { ...listProps });
3115
3492
  if (fallback === void 0 && onBoundaryError === void 0) return content;
3116
- return /* @__PURE__ */ jsx13(KeepErrorBoundary, { fallback, onError: onBoundaryError, resetKey: boundaryResetKey, children: content });
3493
+ return /* @__PURE__ */ jsx15(KeepErrorBoundary, { fallback, onError: onBoundaryError, resetKey: boundaryResetKey, children: content });
3117
3494
  }
3118
3495
  function KeepListContent({
3119
3496
  query,
@@ -3124,6 +3501,7 @@ function KeepListContent({
3124
3501
  loadingCount = 6,
3125
3502
  empty,
3126
3503
  error: errorContent,
3504
+ onClearFilters,
3127
3505
  itemCardProps,
3128
3506
  layout = "list",
3129
3507
  asChild = false,
@@ -3141,14 +3519,17 @@ function KeepListContent({
3141
3519
  loading: renderLoading !== void 0 ? renderLoading : loading,
3142
3520
  loadingCount,
3143
3521
  loadingLabel: view.labels.loading,
3144
- empty: empty ?? view.labels.empty,
3522
+ empty,
3145
3523
  error: errorContent ?? view.labels.error,
3524
+ onClearFilters,
3525
+ allItemCount: view.allState.totalCount,
3526
+ query,
3146
3527
  itemCardProps,
3147
3528
  layout
3148
3529
  });
3149
3530
  return renderRoot(
3150
3531
  asChild,
3151
- asChild && isValidElement4(children) ? children : void 0,
3532
+ asChild && isValidElement6(children) ? children : void 0,
3152
3533
  {
3153
3534
  ...rootProps,
3154
3535
  className,
@@ -3159,7 +3540,7 @@ function KeepListContent({
3159
3540
  "data-loading": state.isLoading ? "true" : void 0,
3160
3541
  "data-roving-tabindex": "true",
3161
3542
  role: rootProps.role ?? "group",
3162
- ref: roving.ref,
3543
+ ref: composeRefs(roving.ref, rootProps.ref),
3163
3544
  onKeyDown: (event) => {
3164
3545
  onKeyDown?.(event);
3165
3546
  if (!event.defaultPrevented) roving.onKeyDown(event);
@@ -3169,7 +3550,7 @@ function KeepListContent({
3169
3550
  if (!event.defaultPrevented) roving.onFocusCapture(event);
3170
3551
  }
3171
3552
  },
3172
- /* @__PURE__ */ jsx13(KeepSearchQueryProvider, { query: query?.search?.query, children: body }),
3553
+ /* @__PURE__ */ jsx15(KeepSearchQueryProvider, { query: query?.search?.query, children: body }),
3173
3554
  "KeepList"
3174
3555
  );
3175
3556
  }
@@ -3184,29 +3565,44 @@ function getListBody(state, options) {
3184
3565
  if (state.isLoading && !state.isHydrated) {
3185
3566
  if (options.loading !== void 0) return resolveContent(options.loading, state);
3186
3567
  const count = Number.isFinite(options.loadingCount) ? Math.max(0, Math.floor(options.loadingCount)) : 6;
3187
- return /* @__PURE__ */ jsxs10(Fragment7, { children: [
3188
- /* @__PURE__ */ jsx13("span", { role: "status", "data-keepkit": "loading-label", children: options.loadingLabel }),
3189
- /* @__PURE__ */ jsx13("ul", { "data-keepkit": "skeleton-list", "data-layout": options.layout, children: Array.from({ length: count }, (_, index) => (
3568
+ return /* @__PURE__ */ jsxs12(Fragment9, { children: [
3569
+ /* @__PURE__ */ jsx15("span", { role: "status", "data-keepkit": "loading-label", children: options.loadingLabel }),
3570
+ /* @__PURE__ */ jsx15("ul", { "data-keepkit": "skeleton-list", "data-layout": options.layout, children: Array.from({ length: count }, (_, index) => (
3190
3571
  // biome-ignore lint/suspicious/noArrayIndexKey: Static loading placeholders never reorder.
3191
- /* @__PURE__ */ jsx13("li", { children: /* @__PURE__ */ jsx13(KeepItemCardSkeleton, { layout: options.layout }) }, index)
3572
+ /* @__PURE__ */ jsx15("li", { children: /* @__PURE__ */ jsx15(KeepItemCardSkeleton, { layout: options.layout }) }, index)
3192
3573
  )) })
3193
3574
  ] });
3194
3575
  }
3195
- if (state.isHydrated && state.items.length === 0) return resolveContent(options.empty, state);
3576
+ if (state.isHydrated && state.items.length === 0) {
3577
+ if (options.empty !== void 0) return resolveContent(options.empty, state);
3578
+ return /* @__PURE__ */ jsx15(
3579
+ KeepEmptyState,
3580
+ {
3581
+ variant: options.allItemCount > 0 && hasActiveQueryFilters(options.query) ? "empty-filtered" : "empty-storage",
3582
+ onClearFilters: options.onClearFilters
3583
+ }
3584
+ );
3585
+ }
3196
3586
  if (typeof options.children === "function") return options.children(state);
3197
- if (options.children !== void 0 && !isValidElement4(options.children)) return options.children;
3198
- return /* @__PURE__ */ jsx13("ul", { "data-layout": options.layout, children: state.items.map(
3199
- (item) => options.renderItem ? options.renderItem(item, state) : /* @__PURE__ */ jsx13("li", { children: /* @__PURE__ */ jsx13(KeepItemCard, { item, ...options.itemCardProps }) }, item.id)
3587
+ if (options.children !== void 0 && !isValidElement6(options.children)) return options.children;
3588
+ return /* @__PURE__ */ jsx15("ul", { "data-layout": options.layout, children: state.items.map(
3589
+ (item) => options.renderItem ? options.renderItem(item, state) : /* @__PURE__ */ jsx15("li", { children: /* @__PURE__ */ jsx15(KeepItemCard, { item, ...options.itemCardProps }) }, item.id)
3200
3590
  ) });
3201
3591
  }
3592
+ function hasActiveQueryFilters(query) {
3593
+ if (!query) return false;
3594
+ return Boolean(
3595
+ query.search?.query?.trim() || query.tags?.some((tag) => tag.trim()) || query.targetType || query.savedBetween || query.filter
3596
+ );
3597
+ }
3202
3598
 
3203
3599
  // src/features/collection/KeepCollection.tsx
3204
- import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
3600
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
3205
3601
  function KeepCollection(props) {
3206
3602
  const { fallback, onBoundaryError, boundaryResetKey, ...collectionProps } = props;
3207
- const content = /* @__PURE__ */ jsx14(KeepCollectionContent, { ...collectionProps });
3603
+ const content = /* @__PURE__ */ jsx16(KeepCollectionContent, { ...collectionProps });
3208
3604
  if (fallback === void 0 && onBoundaryError === void 0) return content;
3209
- return /* @__PURE__ */ jsx14(KeepErrorBoundary2, { fallback, onError: onBoundaryError, resetKey: boundaryResetKey, children: content });
3605
+ return /* @__PURE__ */ jsx16(KeepErrorBoundary2, { fallback, onError: onBoundaryError, resetKey: boundaryResetKey, children: content });
3210
3606
  }
3211
3607
  function KeepCollectionContent({
3212
3608
  query = {},
@@ -3220,13 +3616,14 @@ function KeepCollectionContent({
3220
3616
  loading,
3221
3617
  renderLoading,
3222
3618
  loadingCount,
3619
+ activeFilters,
3223
3620
  empty,
3224
3621
  error,
3225
3622
  className,
3226
3623
  ...rootProps
3227
3624
  }) {
3228
3625
  const view = useKeepCollection({ query, pageSize, urlSync, urlAdapter, features });
3229
- return /* @__PURE__ */ jsxs11(
3626
+ return /* @__PURE__ */ jsxs13(
3230
3627
  "section",
3231
3628
  {
3232
3629
  ...rootProps,
@@ -3237,12 +3634,22 @@ function KeepCollectionContent({
3237
3634
  "data-state": getCollectionState(view.list),
3238
3635
  "data-loading": view.list.isLoading || view.list.isMutating ? "true" : void 0,
3239
3636
  children: [
3240
- /* @__PURE__ */ jsxs11("div", { children: [
3241
- view.enabled.search ? /* @__PURE__ */ jsx14(KeepSearchInput, { value: view.searchValue, onValueChange: view.setSearchValue }) : null,
3242
- view.enabled.sort ? /* @__PURE__ */ jsx14(KeepSortSelect, { value: view.sortValue, onValueChange: view.setSortValue }) : null,
3243
- view.enabled.tagFilter ? /* @__PURE__ */ jsx14(KeepTagFilter, { query, value: view.tag, onValueChange: view.setTag }) : null
3637
+ /* @__PURE__ */ jsxs13("div", { children: [
3638
+ view.enabled.search ? /* @__PURE__ */ jsx16(KeepSearchInput, { value: view.searchValue, onValueChange: view.setSearchValue }) : null,
3639
+ view.enabled.sort ? /* @__PURE__ */ jsx16(KeepSortSelect, { value: view.sortValue, onValueChange: view.setSortValue }) : null,
3640
+ view.enabled.tagFilter ? /* @__PURE__ */ jsx16(KeepTagFilter, { query, value: view.activeTags[0], onValueChange: view.setTag }) : null
3244
3641
  ] }),
3245
- /* @__PURE__ */ jsx14(
3642
+ activeFilters === void 0 ? /* @__PURE__ */ jsx16(
3643
+ KeepActiveFiltersSummary,
3644
+ {
3645
+ search: view.searchValue,
3646
+ tags: view.activeTags,
3647
+ onSearchChange: view.setSearchValue,
3648
+ onTagChange: view.removeTag,
3649
+ onClear: view.clearFilters
3650
+ }
3651
+ ) : resolveContent(activeFilters, view.list),
3652
+ /* @__PURE__ */ jsx16(
3246
3653
  KeepList,
3247
3654
  {
3248
3655
  query: view.resolvedQuery,
@@ -3252,11 +3659,12 @@ function KeepCollectionContent({
3252
3659
  loading,
3253
3660
  renderLoading,
3254
3661
  loadingCount,
3255
- empty,
3662
+ onClearFilters: view.clearFilters,
3663
+ empty: view.list.totalCount === 0 && view.allState.totalCount > 0 ? void 0 : empty,
3256
3664
  error
3257
3665
  }
3258
3666
  ),
3259
- view.enabled.pagination ? /* @__PURE__ */ jsx14(
3667
+ view.enabled.pagination ? /* @__PURE__ */ jsx16(
3260
3668
  KeepPagination,
3261
3669
  {
3262
3670
  totalCount: view.list.totalCount,
@@ -3265,7 +3673,7 @@ function KeepCollectionContent({
3265
3673
  onPageChange: view.setPage
3266
3674
  }
3267
3675
  ) : null,
3268
- view.enabled.bulkActions ? /* @__PURE__ */ jsx14(KeepBulkActions, { query: view.resolvedQuery }) : null
3676
+ view.enabled.bulkActions ? /* @__PURE__ */ jsx16(KeepBulkActions, { query: view.resolvedQuery }) : null
3269
3677
  ]
3270
3678
  }
3271
3679
  );
@@ -3278,12 +3686,12 @@ function getCollectionState(list) {
3278
3686
  }
3279
3687
 
3280
3688
  // src/features/collection/KeepLayout.tsx
3281
- import { jsx as jsx15 } from "react/jsx-runtime";
3689
+ import { jsx as jsx17 } from "react/jsx-runtime";
3282
3690
  function KeepLayout({ layout = "list", children, onKeyDown, onFocusCapture, ...props }) {
3283
3691
  const roving = useRovingTabIndex();
3284
3692
  return (
3285
3693
  // biome-ignore lint/a11y/noStaticElementInteractions: The group manages keyboard focus for descendant cards.
3286
- /* @__PURE__ */ jsx15(
3694
+ /* @__PURE__ */ jsx17(
3287
3695
  "div",
3288
3696
  {
3289
3697
  ...props,
@@ -3308,7 +3716,7 @@ function KeepLayout({ layout = "list", children, onKeyDown, onFocusCapture, ...p
3308
3716
 
3309
3717
  // src/features/collection/KeepReorderableList.tsx
3310
3718
  import { useState as useState9 } from "react";
3311
- import { jsx as jsx16 } from "react/jsx-runtime";
3719
+ import { jsx as jsx18 } from "react/jsx-runtime";
3312
3720
  function KeepReorderableList({
3313
3721
  items,
3314
3722
  onReorder,
@@ -3342,7 +3750,7 @@ function KeepReorderableList({
3342
3750
  if (next[index] === id) return;
3343
3751
  commit(next);
3344
3752
  }
3345
- return /* @__PURE__ */ jsx16("ul", { ...props, "data-keepkit": "reorderable-list", children: items.map((item, index) => {
3753
+ return /* @__PURE__ */ jsx18("ul", { ...props, "data-keepkit": "reorderable-list", children: items.map((item, index) => {
3346
3754
  const moveUp = () => move(index, index - 1);
3347
3755
  const moveDown = () => move(index, index + 1);
3348
3756
  const onHandleKeyDown = (event) => {
@@ -3377,7 +3785,7 @@ function KeepReorderableList({
3377
3785
  onKeyDown: onHandleKeyDown
3378
3786
  }
3379
3787
  };
3380
- return /* @__PURE__ */ jsx16(
3788
+ return /* @__PURE__ */ jsx18(
3381
3789
  "li",
3382
3790
  {
3383
3791
  "data-reorder-index": index,
@@ -3409,18 +3817,34 @@ function KeepReorderableList({
3409
3817
  }
3410
3818
 
3411
3819
  // src/features/editor/KeepNoteEditor.tsx
3412
- import { isValidElement as isValidElement5 } from "react";
3820
+ import { isValidElement as isValidElement7 } from "react";
3821
+
3822
+ // src/features/navigation/KeepShortcutHint.tsx
3823
+ import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
3824
+ function KeepShortcutHint({ shortcut, separator = "+", ...props }) {
3825
+ const keys = typeof shortcut === "string" ? shortcut.split("+") : [...shortcut];
3826
+ const occurrences = /* @__PURE__ */ new Map();
3827
+ const keyedKeys = keys.map((key) => {
3828
+ const occurrence = occurrences.get(key) ?? 0;
3829
+ occurrences.set(key, occurrence + 1);
3830
+ return { id: `${key}-${occurrence}`, value: key };
3831
+ });
3832
+ return /* @__PURE__ */ jsx19("span", { ...props, "data-keepkit": "shortcut-hint", "aria-hidden": props["aria-hidden"] ?? true, children: keyedKeys.map((key, index) => /* @__PURE__ */ jsxs14("span", { children: [
3833
+ index > 0 ? /* @__PURE__ */ jsx19("span", { "data-shortcut-separator": "true", children: separator }) : null,
3834
+ /* @__PURE__ */ jsx19("kbd", { children: key.value.trim() })
3835
+ ] }, key.id)) });
3836
+ }
3413
3837
 
3414
3838
  // src/features/editor/hooks/useKeepNoteEditor.ts
3415
3839
  import { useKeepItem as useKeepItem3 } from "@keepkit/core/react";
3416
- import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef5, useState as useState10 } from "react";
3840
+ import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef6, useState as useState10 } from "react";
3417
3841
  function useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError }) {
3418
3842
  const itemState = useKeepItem3(item);
3419
3843
  const { error, isMutating, item: savedItem, updateNote } = itemState;
3420
3844
  const [note, setNote] = useState10(item.note ?? "");
3421
3845
  const baselineNote = savedItem?.note ?? item.note ?? "";
3422
3846
  const isDirty = note !== baselineNote;
3423
- const lastSavedNoteRef = useRef5(void 0);
3847
+ const lastSavedNoteRef = useRef6(void 0);
3424
3848
  useEffect7(() => setNote(baselineNote), [baselineNote]);
3425
3849
  const save = useCallback4(async () => {
3426
3850
  const nextNote = note.trim() || void 0;
@@ -3468,13 +3892,14 @@ function useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError }) {
3468
3892
  }
3469
3893
 
3470
3894
  // src/features/editor/KeepNoteEditor.tsx
3471
- import { Fragment as Fragment8, jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
3895
+ import { Fragment as Fragment10, jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
3472
3896
  function KeepNoteEditor({
3473
3897
  item,
3474
3898
  label,
3475
3899
  saveLabel,
3476
3900
  placeholder,
3477
3901
  debounceMs = 300,
3902
+ showShortcutHint = false,
3478
3903
  onSaved,
3479
3904
  onSaveError,
3480
3905
  render,
@@ -3485,11 +3910,11 @@ function KeepNoteEditor({
3485
3910
  }) {
3486
3911
  const view = useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError });
3487
3912
  const { error, isDirty, isSaving, note, setNote } = view.state;
3488
- const contentChildren = asChild && isValidElement5(children) ? void 0 : children;
3489
- const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */ jsxs12(Fragment8, { children: [
3490
- /* @__PURE__ */ jsxs12("label", { children: [
3913
+ const contentChildren = asChild && isValidElement7(children) ? void 0 : children;
3914
+ const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */ jsxs15(Fragment10, { children: [
3915
+ /* @__PURE__ */ jsxs15("label", { children: [
3491
3916
  label ?? view.labels.note,
3492
- /* @__PURE__ */ jsx17(
3917
+ /* @__PURE__ */ jsx20(
3493
3918
  "textarea",
3494
3919
  {
3495
3920
  "data-keep-action": "edit-note",
@@ -3501,10 +3926,13 @@ function KeepNoteEditor({
3501
3926
  }
3502
3927
  )
3503
3928
  ] }),
3504
- /* @__PURE__ */ jsx17("button", { type: "submit", "data-keep-action": "save-note", disabled: isSaving, "aria-busy": isSaving, children: saveLabel ?? view.labels.save })
3929
+ /* @__PURE__ */ jsxs15("button", { type: "submit", "data-keep-action": "save-note", disabled: isSaving, "aria-busy": isSaving, children: [
3930
+ saveLabel ?? view.labels.save,
3931
+ showShortcutHint ? /* @__PURE__ */ jsx20(KeepShortcutHint, { shortcut: "Ctrl+Enter" }) : null
3932
+ ] })
3505
3933
  ] });
3506
3934
  if (!asChild) {
3507
- return /* @__PURE__ */ jsxs12(
3935
+ return /* @__PURE__ */ jsxs15(
3508
3936
  "form",
3509
3937
  {
3510
3938
  ...formProps,
@@ -3517,14 +3945,14 @@ function KeepNoteEditor({
3517
3945
  "data-disabled": isSaving ? "true" : void 0,
3518
3946
  children: [
3519
3947
  body,
3520
- error ? /* @__PURE__ */ jsx17("p", { role: "alert", children: getErrorMessage3(error, view.labels.error) }) : null
3948
+ error ? /* @__PURE__ */ jsx20("p", { role: "alert", children: getErrorMessage3(error, view.labels.error) }) : null
3521
3949
  ]
3522
3950
  }
3523
3951
  );
3524
3952
  }
3525
3953
  return renderRoot(
3526
3954
  true,
3527
- isValidElement5(children) ? children : void 0,
3955
+ isValidElement7(children) ? children : void 0,
3528
3956
  {
3529
3957
  ...formProps,
3530
3958
  className,
@@ -3597,7 +4025,7 @@ function useKeepTagEditor({ item, onSaved, onSaveError }) {
3597
4025
  }
3598
4026
 
3599
4027
  // src/features/editor/KeepTagEditor.tsx
3600
- import { Fragment as Fragment9, jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
4028
+ import { Fragment as Fragment11, jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
3601
4029
  function KeepTagEditor({
3602
4030
  item,
3603
4031
  availableTags = [],
@@ -3608,10 +4036,10 @@ function KeepTagEditor({
3608
4036
  }) {
3609
4037
  const view = useKeepTagEditor({ item, onSaved, onSaveError });
3610
4038
  const { isSaving, tags } = view.state;
3611
- const body = render ? render(view.state) : /* @__PURE__ */ jsxs13(Fragment9, { children: [
3612
- /* @__PURE__ */ jsxs13("label", { children: [
4039
+ const body = render ? render(view.state) : /* @__PURE__ */ jsxs16(Fragment11, { children: [
4040
+ /* @__PURE__ */ jsxs16("label", { children: [
3613
4041
  view.labels.tags,
3614
- /* @__PURE__ */ jsx18(
4042
+ /* @__PURE__ */ jsx21(
3615
4043
  "input",
3616
4044
  {
3617
4045
  "data-keep-action": "edit-tags",
@@ -3622,14 +4050,14 @@ function KeepTagEditor({
3622
4050
  }
3623
4051
  )
3624
4052
  ] }),
3625
- availableTags.length > 0 ? /* @__PURE__ */ jsx18("datalist", { id: `keep-tags-${item.id}`, children: availableTags.map((tag) => /* @__PURE__ */ jsx18("option", { value: tag }, tag)) }) : null,
3626
- /* @__PURE__ */ jsx18("ul", { "aria-label": view.labels.tags, children: tags.map((tag) => /* @__PURE__ */ jsxs13("li", { children: [
4053
+ availableTags.length > 0 ? /* @__PURE__ */ jsx21("datalist", { id: `keep-tags-${item.id}`, children: availableTags.map((tag) => /* @__PURE__ */ jsx21("option", { value: tag }, tag)) }) : null,
4054
+ /* @__PURE__ */ jsx21("ul", { "aria-label": view.labels.tags, children: tags.map((tag) => /* @__PURE__ */ jsxs16("li", { children: [
3627
4055
  tag,
3628
- /* @__PURE__ */ jsx18("button", { type: "button", "data-keep-action": "remove-tag", onClick: () => view.removeTag(tag), children: view.labels.remove })
4056
+ /* @__PURE__ */ jsx21("button", { type: "button", "data-keep-action": "remove-tag", onClick: () => view.removeTag(tag), children: view.labels.remove })
3629
4057
  ] }, tag)) }),
3630
- /* @__PURE__ */ jsx18("button", { type: "submit", "data-keep-action": "apply-tags", disabled: isSaving, "aria-busy": isSaving, children: view.labels.apply })
4058
+ /* @__PURE__ */ jsx21("button", { type: "submit", "data-keep-action": "apply-tags", disabled: isSaving, "aria-busy": isSaving, children: view.labels.apply })
3631
4059
  ] });
3632
- return /* @__PURE__ */ jsxs13(
4060
+ return /* @__PURE__ */ jsxs16(
3633
4061
  "form",
3634
4062
  {
3635
4063
  ...props,
@@ -3641,7 +4069,7 @@ function KeepTagEditor({
3641
4069
  "data-disabled": isSaving ? "true" : void 0,
3642
4070
  children: [
3643
4071
  body,
3644
- view.error ? /* @__PURE__ */ jsx18("p", { role: "alert", children: getErrorMessage4(view.error, view.labels.error) }) : null
4072
+ view.error ? /* @__PURE__ */ jsx21("p", { role: "alert", children: getErrorMessage4(view.error, view.labels.error) }) : null
3645
4073
  ]
3646
4074
  }
3647
4075
  );
@@ -3707,7 +4135,7 @@ function isEditableTarget(target) {
3707
4135
  }
3708
4136
 
3709
4137
  // src/features/navigation/KeepTourBar.tsx
3710
- import { Fragment as Fragment10, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
4138
+ import { Fragment as Fragment12, jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
3711
4139
  function KeepTourBar({
3712
4140
  navigation: providedNavigation,
3713
4141
  currentId,
@@ -3723,9 +4151,12 @@ function KeepTourBar({
3723
4151
  nextLabel,
3724
4152
  backLabel,
3725
4153
  keyboardShortcuts = false,
4154
+ showShortcutHint = false,
3726
4155
  shortcutOptions,
3727
4156
  progress,
3728
4157
  getItemTitle = (item) => getMetaTitle(item.meta) ?? item.id,
4158
+ children,
4159
+ asChild = false,
3729
4160
  ...props
3730
4161
  }) {
3731
4162
  const ownNavigation = useKeepNavigator({ currentId, initialIndex });
@@ -3746,16 +4177,17 @@ function KeepTourBar({
3746
4177
  return resolvedPrev();
3747
4178
  }
3748
4179
  });
3749
- return /* @__PURE__ */ jsxs14("nav", { ...props, "data-keepkit": "tour-bar", "aria-label": props["aria-label"] ?? labels.pagination, children: [
3750
- showProgress ? /* @__PURE__ */ jsx19("span", { "data-keepkit": "tour-progress", "aria-live": "polite", children: progress ?? `${navigation.currentPosition ?? 0} / ${navigation.items.length}` }) : null,
3751
- /* @__PURE__ */ jsx19(
4180
+ const body = /* @__PURE__ */ jsxs17(Fragment12, { children: [
4181
+ showProgress ? /* @__PURE__ */ jsx22("span", { "data-keepkit": "tour-progress", "aria-live": "polite", children: progress ?? `${navigation.currentPosition ?? 0} / ${navigation.items.length}` }) : null,
4182
+ /* @__PURE__ */ jsx22(
3752
4183
  TourAction,
3753
4184
  {
3754
4185
  href: prevHref,
3755
4186
  disabled: !navigation.hasPrev,
3756
4187
  onClick: prevHref ? onPrev : resolvedPrev,
3757
4188
  "data-keep-action": "tour-prev",
3758
- preview: navigation.prevItem ? /* @__PURE__ */ jsxs14(Fragment10, { children: [
4189
+ shortcut: showShortcutHint ? shortcutOptions?.prevKeys?.[0] ?? "K" : void 0,
4190
+ preview: navigation.prevItem ? /* @__PURE__ */ jsxs17(Fragment12, { children: [
3759
4191
  previousLabel,
3760
4192
  ": ",
3761
4193
  getItemTitle(navigation.prevItem)
@@ -3763,14 +4195,15 @@ function KeepTourBar({
3763
4195
  children: previousLabel
3764
4196
  }
3765
4197
  ),
3766
- /* @__PURE__ */ jsx19(
4198
+ /* @__PURE__ */ jsx22(
3767
4199
  TourAction,
3768
4200
  {
3769
4201
  href: nextHref,
3770
4202
  disabled: !navigation.hasNext,
3771
4203
  onClick: nextHref ? onNext : resolvedNext,
3772
4204
  "data-keep-action": "tour-next",
3773
- preview: navigation.nextItem ? /* @__PURE__ */ jsxs14(Fragment10, { children: [
4205
+ shortcut: showShortcutHint ? shortcutOptions?.nextKeys?.[0] ?? "J" : void 0,
4206
+ preview: navigation.nextItem ? /* @__PURE__ */ jsxs17(Fragment12, { children: [
3774
4207
  nextItemLabel,
3775
4208
  ": ",
3776
4209
  getItemTitle(navigation.nextItem)
@@ -3778,17 +4211,25 @@ function KeepTourBar({
3778
4211
  children: nextItemLabel
3779
4212
  }
3780
4213
  ),
3781
- backHref || onBack ? /* @__PURE__ */ jsx19(TourAction, { href: backHref, onClick: onBack, "data-keep-action": "tour-back", children: listLabel }) : null
4214
+ backHref || onBack ? /* @__PURE__ */ jsx22(TourAction, { href: backHref, onClick: onBack, "data-keep-action": "tour-back", children: listLabel }) : null
3782
4215
  ] });
4216
+ return renderRoot(
4217
+ asChild,
4218
+ children,
4219
+ { ...props, "data-keepkit": "tour-bar", "aria-label": props["aria-label"] ?? labels.pagination },
4220
+ body,
4221
+ "KeepTourBar"
4222
+ );
3783
4223
  }
3784
- function TourAction({ href, disabled = false, onClick, children, preview, ...props }) {
4224
+ function TourAction({ href, disabled = false, onClick, children, preview, shortcut, ...props }) {
3785
4225
  const previewId = useId();
3786
- const content = /* @__PURE__ */ jsxs14(Fragment10, { children: [
3787
- /* @__PURE__ */ jsx19("span", { "data-tour-label": "true", children }),
3788
- preview ? /* @__PURE__ */ jsx19("small", { id: previewId, "data-tour-preview": "true", children: preview }) : null
4226
+ const content = /* @__PURE__ */ jsxs17(Fragment12, { children: [
4227
+ /* @__PURE__ */ jsx22("span", { "data-tour-label": "true", children }),
4228
+ shortcut ? /* @__PURE__ */ jsx22(KeepShortcutHint, { shortcut }) : null,
4229
+ preview ? /* @__PURE__ */ jsx22("small", { id: previewId, "data-tour-preview": "true", children: preview }) : null
3789
4230
  ] });
3790
4231
  if (href && !disabled) {
3791
- return /* @__PURE__ */ jsx19(
4232
+ return /* @__PURE__ */ jsx22(
3792
4233
  "a",
3793
4234
  {
3794
4235
  ...props,
@@ -3800,7 +4241,7 @@ function TourAction({ href, disabled = false, onClick, children, preview, ...pro
3800
4241
  }
3801
4242
  );
3802
4243
  }
3803
- return /* @__PURE__ */ jsx19(
4244
+ return /* @__PURE__ */ jsx22(
3804
4245
  "button",
3805
4246
  {
3806
4247
  ...props,
@@ -3820,14 +4261,11 @@ function navigateTo(item, href) {
3820
4261
  }
3821
4262
 
3822
4263
  // src/features/status/status.tsx
3823
- import { isValidElement as isValidElement6 } from "react";
4264
+ import { isValidElement as isValidElement8 } from "react";
3824
4265
 
3825
4266
  // src/features/status/hooks/useStatusViews.ts
3826
4267
  import { useKeepContext as useKeepContext4 } from "@keepkit/core/react";
3827
- import { useEffect as useEffect10, useRef as useRef6, useState as useState12 } from "react";
3828
- function useKeepEmptyState() {
3829
- return useUiLabel("noItems").replace(/\.$/, "");
3830
- }
4268
+ import { useEffect as useEffect10, useRef as useRef7, useState as useState12 } from "react";
3831
4269
  function useKeepStatus(status) {
3832
4270
  const context = useKeepContext4();
3833
4271
  const resolvedStatus = status ?? getDerivedStatus(context);
@@ -3845,7 +4283,7 @@ function useKeepAnnouncements(messages) {
3845
4283
  const removedMessage = useUiLabel("removedMessage", messages?.remove);
3846
4284
  const noteSavedMessage = useUiLabel("noteSavedMessage", messages?.note);
3847
4285
  const [message, setMessage] = useState12("");
3848
- const lastChangeRef = useRef6(void 0);
4286
+ const lastChangeRef = useRef7(void 0);
3849
4287
  useEffect10(() => {
3850
4288
  const change = context.lastChange;
3851
4289
  if (!change || change === lastChangeRef.current) return;
@@ -3874,31 +4312,7 @@ function getStatusLabelKey3(status) {
3874
4312
  }
3875
4313
 
3876
4314
  // src/features/status/status.tsx
3877
- import { Fragment as Fragment11, jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
3878
- function KeepEmptyState({
3879
- title,
3880
- description,
3881
- action,
3882
- children,
3883
- asChild = false,
3884
- className,
3885
- ...rootProps
3886
- }) {
3887
- const defaultTitle = useKeepEmptyState();
3888
- const contentChildren = asChild && isValidElement6(children) ? void 0 : children;
3889
- const body = contentChildren ?? /* @__PURE__ */ jsxs15(Fragment11, { children: [
3890
- /* @__PURE__ */ jsx20("h2", { children: title ?? defaultTitle }),
3891
- description ? /* @__PURE__ */ jsx20("p", { children: description }) : null,
3892
- action
3893
- ] });
3894
- return renderRoot(
3895
- asChild,
3896
- children,
3897
- { ...rootProps, className, "data-keepkit": "empty-state", "data-state": "empty" },
3898
- body,
3899
- "KeepEmptyState"
3900
- );
3901
- }
4315
+ import { jsx as jsx23 } from "react/jsx-runtime";
3902
4316
  function KeepStatus({
3903
4317
  status,
3904
4318
  labels,
@@ -3909,12 +4323,12 @@ function KeepStatus({
3909
4323
  ...rootProps
3910
4324
  }) {
3911
4325
  const view = useKeepStatus(status);
3912
- const contentChildren = asChild && isValidElement6(children) ? void 0 : children;
4326
+ const contentChildren = asChild && isValidElement8(children) ? void 0 : children;
3913
4327
  const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? labels?.[view.state.status] ?? view.defaultLabel;
3914
4328
  const role = rootProps.role ?? (view.state.status === "error" ? "alert" : "status");
3915
4329
  return renderRoot(
3916
4330
  asChild,
3917
- isValidElement6(children) ? children : void 0,
4331
+ isValidElement8(children) ? children : void 0,
3918
4332
  {
3919
4333
  ...rootProps,
3920
4334
  className,
@@ -3930,7 +4344,7 @@ function KeepStatus({
3930
4344
  }
3931
4345
  function KeepAnnouncements({ messages, ...props }) {
3932
4346
  const message = useKeepAnnouncements(messages);
3933
- return /* @__PURE__ */ jsx20(
4347
+ return /* @__PURE__ */ jsx23(
3934
4348
  "div",
3935
4349
  {
3936
4350
  ...props,
@@ -3947,13 +4361,13 @@ var KeepAnnouncer = KeepAnnouncements;
3947
4361
 
3948
4362
  // src/features/sync/hooks/useKeepSyncFeedback.ts
3949
4363
  import { useKeepContext as useKeepContext5 } from "@keepkit/core/react";
3950
- import { useEffect as useEffect11, useRef as useRef7 } from "react";
4364
+ import { useEffect as useEffect11, useRef as useRef8 } from "react";
3951
4365
  function useKeepSyncFeedback() {
3952
4366
  const { syncState } = useKeepContext5();
3953
4367
  const emitFeedback = useKeepUiFeedback();
3954
4368
  const completedMessage = useUiLabel("syncSynced");
3955
4369
  const failedMessage = useUiLabel("syncFailedMessage");
3956
- const previousStatus = useRef7("idle");
4370
+ const previousStatus = useRef8("idle");
3957
4371
  useEffect11(() => {
3958
4372
  const previous = previousStatus.current;
3959
4373
  previousStatus.current = syncState.status;
@@ -4029,7 +4443,7 @@ function useKeepSyncRecoveryDialog(options) {
4029
4443
  }
4030
4444
 
4031
4445
  // src/features/sync/KeepSyncRecoveryDialog.tsx
4032
- import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
4446
+ import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
4033
4447
  function KeepSyncRecoveryDialog({
4034
4448
  open,
4035
4449
  onOpenChange,
@@ -4044,7 +4458,7 @@ function KeepSyncRecoveryDialog({
4044
4458
  }) {
4045
4459
  const view = useKeepSyncRecoveryDialog({ open, onOpenChange, conflicts, onManualMerge });
4046
4460
  if (!view.isOpen) return null;
4047
- return /* @__PURE__ */ jsxs16(
4461
+ return /* @__PURE__ */ jsxs18(
4048
4462
  "section",
4049
4463
  {
4050
4464
  ...props,
@@ -4058,17 +4472,17 @@ function KeepSyncRecoveryDialog({
4058
4472
  "data-state": view.conflictList.length > 0 ? "conflict" : "error",
4059
4473
  "data-loading": view.busyId !== void 0 ? "true" : void 0,
4060
4474
  children: [
4061
- /* @__PURE__ */ jsxs16("header", { children: [
4062
- /* @__PURE__ */ jsx21("h2", { id: "keepkit-sync-recovery-title", children: title ?? view.labels.title }),
4063
- /* @__PURE__ */ jsx21("button", { type: "button", "data-keep-action": "close-dialog", onClick: view.close, "aria-label": view.labels.close, children: view.labels.close })
4475
+ /* @__PURE__ */ jsxs18("header", { children: [
4476
+ /* @__PURE__ */ jsx24("h2", { id: "keepkit-sync-recovery-title", children: title ?? view.labels.title }),
4477
+ /* @__PURE__ */ jsx24("button", { type: "button", "data-keep-action": "close-dialog", onClick: view.close, "aria-label": view.labels.close, children: view.labels.close })
4064
4478
  ] }),
4065
4479
  children,
4066
- view.conflictList.length > 0 ? /* @__PURE__ */ jsxs16("div", { children: [
4067
- /* @__PURE__ */ jsx21("p", { children: view.labels.conflict }),
4068
- view.conflictList.map((conflict) => /* @__PURE__ */ jsxs16("article", { "data-conflict-id": conflict.id, children: [
4069
- /* @__PURE__ */ jsx21("h3", { children: getMetaTitle(conflict.operation.item?.meta) ?? conflict.id }),
4070
- /* @__PURE__ */ jsxs16("div", { "data-conflict-preview": true, children: [
4071
- /* @__PURE__ */ jsx21(
4480
+ view.conflictList.length > 0 ? /* @__PURE__ */ jsxs18("div", { children: [
4481
+ /* @__PURE__ */ jsx24("p", { children: view.labels.conflict }),
4482
+ view.conflictList.map((conflict) => /* @__PURE__ */ jsxs18("article", { "data-conflict-id": conflict.id, children: [
4483
+ /* @__PURE__ */ jsx24("h3", { children: getMetaTitle(conflict.operation.item?.meta) ?? conflict.id }),
4484
+ /* @__PURE__ */ jsxs18("div", { "data-conflict-preview": true, children: [
4485
+ /* @__PURE__ */ jsx24(
4072
4486
  ConflictPreview,
4073
4487
  {
4074
4488
  item: conflict.operation.item,
@@ -4078,7 +4492,7 @@ function KeepSyncRecoveryDialog({
4078
4492
  side: "local"
4079
4493
  }
4080
4494
  ),
4081
- /* @__PURE__ */ jsx21(
4495
+ /* @__PURE__ */ jsx24(
4082
4496
  ConflictPreview,
4083
4497
  {
4084
4498
  item: conflict.remote,
@@ -4089,8 +4503,8 @@ function KeepSyncRecoveryDialog({
4089
4503
  }
4090
4504
  )
4091
4505
  ] }),
4092
- /* @__PURE__ */ jsxs16("div", { children: [
4093
- /* @__PURE__ */ jsx21(
4506
+ /* @__PURE__ */ jsxs18("div", { children: [
4507
+ /* @__PURE__ */ jsx24(
4094
4508
  "button",
4095
4509
  {
4096
4510
  type: "button",
@@ -4100,7 +4514,7 @@ function KeepSyncRecoveryDialog({
4100
4514
  children: view.labels.keepLocal
4101
4515
  }
4102
4516
  ),
4103
- /* @__PURE__ */ jsx21(
4517
+ /* @__PURE__ */ jsx24(
4104
4518
  "button",
4105
4519
  {
4106
4520
  type: "button",
@@ -4110,7 +4524,7 @@ function KeepSyncRecoveryDialog({
4110
4524
  children: view.labels.useServer
4111
4525
  }
4112
4526
  ),
4113
- /* @__PURE__ */ jsx21(
4527
+ /* @__PURE__ */ jsx24(
4114
4528
  "button",
4115
4529
  {
4116
4530
  type: "button",
@@ -4123,12 +4537,12 @@ function KeepSyncRecoveryDialog({
4123
4537
  ] })
4124
4538
  ] }, conflict.id))
4125
4539
  ] }) : null,
4126
- view.showBackupRecovery ? /* @__PURE__ */ jsxs16("section", { "data-recovery": "backup", children: [
4127
- /* @__PURE__ */ jsx21("h3", { children: view.labels.backupRecovery }),
4128
- /* @__PURE__ */ jsx21("p", { children: view.labels.backupRecoveryDescription }),
4129
- backup ?? (showBackupControls ? /* @__PURE__ */ jsx21(KeepBackup, {}) : null)
4540
+ view.showBackupRecovery ? /* @__PURE__ */ jsxs18("section", { "data-recovery": "backup", children: [
4541
+ /* @__PURE__ */ jsx24("h3", { children: view.labels.backupRecovery }),
4542
+ /* @__PURE__ */ jsx24("p", { children: view.labels.backupRecoveryDescription }),
4543
+ backup ?? (showBackupControls ? /* @__PURE__ */ jsx24(KeepBackup, {}) : null)
4130
4544
  ] }) : null,
4131
- view.error ? /* @__PURE__ */ jsx21("p", { id: "keepkit-sync-recovery-error", role: "alert", "aria-live": "assertive", children: view.error instanceof Error ? view.error.message : view.labels.error }) : null
4545
+ view.error ? /* @__PURE__ */ jsx24("p", { id: "keepkit-sync-recovery-error", role: "alert", "aria-live": "assertive", children: view.error instanceof Error ? view.error.message : view.labels.error }) : null
4132
4546
  ]
4133
4547
  }
4134
4548
  );
@@ -4140,16 +4554,16 @@ function ConflictPreview({
4140
4554
  noteLabel,
4141
4555
  side
4142
4556
  }) {
4143
- return /* @__PURE__ */ jsxs16("article", { "data-conflict-version": side, "aria-label": heading, children: [
4144
- /* @__PURE__ */ jsx21("h4", { children: heading }),
4145
- /* @__PURE__ */ jsxs16("dl", { children: [
4146
- /* @__PURE__ */ jsxs16("div", { children: [
4147
- /* @__PURE__ */ jsx21("dt", { children: updatedAtLabel }),
4148
- /* @__PURE__ */ jsx21("dd", { children: item ? /* @__PURE__ */ jsx21("time", { dateTime: new Date(item.updatedAt).toISOString(), children: formatConflictDate(item.updatedAt) }) : "\u2014" })
4557
+ return /* @__PURE__ */ jsxs18("article", { "data-conflict-version": side, "aria-label": heading, children: [
4558
+ /* @__PURE__ */ jsx24("h4", { children: heading }),
4559
+ /* @__PURE__ */ jsxs18("dl", { children: [
4560
+ /* @__PURE__ */ jsxs18("div", { children: [
4561
+ /* @__PURE__ */ jsx24("dt", { children: updatedAtLabel }),
4562
+ /* @__PURE__ */ jsx24("dd", { children: item ? /* @__PURE__ */ jsx24("time", { dateTime: new Date(item.updatedAt).toISOString(), children: formatConflictDate(item.updatedAt) }) : "\u2014" })
4149
4563
  ] }),
4150
- /* @__PURE__ */ jsxs16("div", { children: [
4151
- /* @__PURE__ */ jsx21("dt", { children: noteLabel }),
4152
- /* @__PURE__ */ jsx21("dd", { children: item?.note || "\u2014" })
4564
+ /* @__PURE__ */ jsxs18("div", { children: [
4565
+ /* @__PURE__ */ jsx24("dt", { children: noteLabel }),
4566
+ /* @__PURE__ */ jsx24("dd", { children: item?.note || "\u2014" })
4153
4567
  ] })
4154
4568
  ] })
4155
4569
  ] });
@@ -4193,7 +4607,7 @@ function getErrorMessage5(error) {
4193
4607
  }
4194
4608
 
4195
4609
  // src/features/sync/KeepSyncStatusBanner.tsx
4196
- import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
4610
+ import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
4197
4611
  function KeepSyncStatusBanner({
4198
4612
  onRetry,
4199
4613
  onResolveConflicts,
@@ -4203,7 +4617,7 @@ function KeepSyncStatusBanner({
4203
4617
  }) {
4204
4618
  const view = useKeepSyncStatusBanner({ onRetry, children });
4205
4619
  if (view.status === "idle" && !view.hasConflicts) return null;
4206
- return /* @__PURE__ */ jsxs17(
4620
+ return /* @__PURE__ */ jsxs19(
4207
4621
  "aside",
4208
4622
  {
4209
4623
  ...props,
@@ -4213,8 +4627,8 @@ function KeepSyncStatusBanner({
4213
4627
  "data-keepkit": "sync-status",
4214
4628
  "data-state": view.status,
4215
4629
  children: [
4216
- /* @__PURE__ */ jsx22("p", { children: view.message }),
4217
- view.showRetry ? /* @__PURE__ */ jsx22(
4630
+ /* @__PURE__ */ jsx25("p", { children: view.message }),
4631
+ view.showRetry ? /* @__PURE__ */ jsx25(
4218
4632
  "button",
4219
4633
  {
4220
4634
  type: "button",
@@ -4224,7 +4638,7 @@ function KeepSyncStatusBanner({
4224
4638
  children: view.retryLabel
4225
4639
  }
4226
4640
  ) : null,
4227
- view.hasConflicts ? /* @__PURE__ */ jsx22(
4641
+ view.hasConflicts ? /* @__PURE__ */ jsx25(
4228
4642
  "button",
4229
4643
  {
4230
4644
  type: "button",
@@ -4240,8 +4654,8 @@ function KeepSyncStatusBanner({
4240
4654
  }
4241
4655
 
4242
4656
  // src/foundation/theme.tsx
4243
- import { cloneElement as cloneElement2, isValidElement as isValidElement7 } from "react";
4244
- import { jsx as jsx23 } from "react/jsx-runtime";
4657
+ import { isValidElement as isValidElement9 } from "react";
4658
+ import { jsx as jsx26 } from "react/jsx-runtime";
4245
4659
  var keepThemeNames = [
4246
4660
  "default",
4247
4661
  "ocean",
@@ -4296,11 +4710,11 @@ function KeepThemeProvider({
4296
4710
  "data-reduced-motion": reducedMotion ? "true" : void 0
4297
4711
  };
4298
4712
  if (asChild) {
4299
- if (!isValidElement7(children))
4713
+ if (!isValidElement9(children))
4300
4714
  throw new Error("KeepThemeProvider with asChild requires a single React element child.");
4301
- return cloneElement2(children, rootProps);
4715
+ return createSlot(children, rootProps);
4302
4716
  }
4303
- return /* @__PURE__ */ jsx23("div", { ...rootProps, children });
4717
+ return /* @__PURE__ */ jsx26("div", { ...rootProps, children });
4304
4718
  }
4305
4719
 
4306
4720
  // src/index.tsx
@@ -4324,7 +4738,7 @@ import {
4324
4738
  LocalStorageSyncQueueAdapter,
4325
4739
  SyncStorageAdapter
4326
4740
  } from "@keepkit/core/storage";
4327
- import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
4741
+ import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
4328
4742
  function KeepKitProvider({
4329
4743
  labels,
4330
4744
  locale,
@@ -4344,7 +4758,7 @@ function KeepKitProvider({
4344
4758
  children,
4345
4759
  ...providerProps
4346
4760
  }) {
4347
- return /* @__PURE__ */ jsx24(KeepUiProvider, { labels, locale, labelResolver, onFeedback, children: /* @__PURE__ */ jsx24(
4761
+ return /* @__PURE__ */ jsx27(KeepUiProvider, { labels, locale, labelResolver, onFeedback, children: /* @__PURE__ */ jsx27(
4348
4762
  KeepThemeProvider,
4349
4763
  {
4350
4764
  theme,
@@ -4358,10 +4772,10 @@ function KeepKitProvider({
4358
4772
  className: themeClassName,
4359
4773
  style: themeStyle,
4360
4774
  asChild: themeAsChild,
4361
- children: /* @__PURE__ */ jsxs18(CoreKeepProvider, { ...providerProps, children: [
4362
- /* @__PURE__ */ jsx24(KeepSyncFeedbackObserver, {}),
4775
+ children: /* @__PURE__ */ jsxs20(CoreKeepProvider, { ...providerProps, children: [
4776
+ /* @__PURE__ */ jsx27(KeepSyncFeedbackObserver, {}),
4363
4777
  children,
4364
- /* @__PURE__ */ jsx24(KeepAnnouncements, {})
4778
+ /* @__PURE__ */ jsx27(KeepAnnouncements, {})
4365
4779
  ] })
4366
4780
  }
4367
4781
  ) });
@@ -4388,7 +4802,7 @@ function createKeepKit(options = {}) {
4388
4802
  } = options;
4389
4803
  const coreKit = createCoreKeepKit(coreOptions);
4390
4804
  return {
4391
- Provider: (props) => /* @__PURE__ */ jsx24(
4805
+ Provider: (props) => /* @__PURE__ */ jsx27(
4392
4806
  KeepKitProvider,
4393
4807
  {
4394
4808
  ...coreOptions,
@@ -4409,9 +4823,9 @@ function createKeepKit(options = {}) {
4409
4823
  ...props
4410
4824
  }
4411
4825
  ),
4412
- Button: (props) => /* @__PURE__ */ jsx24(KeepButton, { ...props }),
4413
- Backup: (props) => /* @__PURE__ */ jsx24(KeepBackup, { ...props }),
4414
- Collection: (props) => /* @__PURE__ */ jsx24(
4826
+ Button: (props) => /* @__PURE__ */ jsx27(KeepButton, { ...props }),
4827
+ Backup: (props) => /* @__PURE__ */ jsx27(KeepBackup, { ...props }),
4828
+ Collection: (props) => /* @__PURE__ */ jsx27(
4415
4829
  KeepCollection,
4416
4830
  {
4417
4831
  ...props,
@@ -4433,6 +4847,7 @@ export {
4433
4847
  FallbackStorageAdapter,
4434
4848
  IndexedDBAdapter,
4435
4849
  IndexedDBSyncQueueAdapter,
4850
+ KeepActiveFiltersSummary,
4436
4851
  KeepAnnouncements,
4437
4852
  KeepAnnouncer,
4438
4853
  KeepBackup,
@@ -4456,6 +4871,7 @@ export {
4456
4871
  KeepPruneStaleButton,
4457
4872
  KeepReorderableList,
4458
4873
  KeepSearchInput,
4874
+ KeepShortcutHint,
4459
4875
  KeepSortSelect,
4460
4876
  KeepStaleNotice,
4461
4877
  KeepStatus,
@@ -4470,15 +4886,19 @@ export {
4470
4886
  LocalStorageAdapter,
4471
4887
  LocalStorageSyncQueueAdapter,
4472
4888
  SyncStorageAdapter,
4889
+ chainedFunction,
4890
+ composeRefs,
4473
4891
  createAuthenticatedSyncKit,
4474
4892
  createBrowserStorageAdapter,
4475
4893
  createKeepKit,
4476
4894
  createNextPagesRouterAdapter,
4895
+ createSlot,
4477
4896
  createStorageAdapter,
4478
4897
  getKeepLocaleLabels,
4479
4898
  highlightText,
4480
4899
  isAllSelected,
4481
4900
  keepThemeNames,
4901
+ mergeProps,
4482
4902
  toggleSelectAll,
4483
4903
  useKeepContext8 as useKeepContext,
4484
4904
  useKeepItem5 as useKeepItem,