@keepkit/ui 0.25.0 → 0.26.2

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
@@ -196,7 +196,11 @@ var DE_LABELS = {
196
196
  archiveScopeActive: "Aktiv",
197
197
  archiveScopeArchived: "Archiviert",
198
198
  archiveScopeAll: "Alle Elemente",
199
- undoReorder: "Sortierung r\xFCckg\xE4ngig machen"
199
+ undoReorder: "Sortierung r\xFCckg\xE4ngig machen",
200
+ toolbarStart: "Sammlungsaktionen",
201
+ toolbarQuery: "Suchen und sortieren",
202
+ toolbarFilters: "Filter",
203
+ toolbarEnd: "Zus\xE4tzliche Aktionen"
200
204
  };
201
205
 
202
206
  // src/locales/en.ts
@@ -300,7 +304,11 @@ var EN_LABELS = {
300
304
  archiveScopeActive: "Active",
301
305
  archiveScopeArchived: "Archived",
302
306
  archiveScopeAll: "All items",
303
- undoReorder: "Undo reorder"
307
+ undoReorder: "Undo reorder",
308
+ toolbarStart: "Collection actions",
309
+ toolbarQuery: "Search and sort",
310
+ toolbarFilters: "Filters",
311
+ toolbarEnd: "Additional actions"
304
312
  };
305
313
 
306
314
  // src/locales/es.ts
@@ -404,7 +412,11 @@ var ES_LABELS = {
404
412
  archiveScopeActive: "Activos",
405
413
  archiveScopeArchived: "Archivados",
406
414
  archiveScopeAll: "Todos los elementos",
407
- undoReorder: "Deshacer ordenaci\xF3n"
415
+ undoReorder: "Deshacer ordenaci\xF3n",
416
+ toolbarStart: "Acciones de la colecci\xF3n",
417
+ toolbarQuery: "Buscar y ordenar",
418
+ toolbarFilters: "Filtros",
419
+ toolbarEnd: "Acciones adicionales"
408
420
  };
409
421
 
410
422
  // src/locales/fil.ts
@@ -508,7 +520,11 @@ var FIL_LABELS = {
508
520
  archiveScopeActive: "Aktibo",
509
521
  archiveScopeArchived: "Naka-archive",
510
522
  archiveScopeAll: "Lahat ng item",
511
- undoReorder: "I-undo ang pag-aayos"
523
+ undoReorder: "I-undo ang pag-aayos",
524
+ toolbarStart: "Mga aksyon ng koleksyon",
525
+ toolbarQuery: "Maghanap at mag-ayos",
526
+ toolbarFilters: "Mga filter",
527
+ toolbarEnd: "Mga karagdagang aksyon"
512
528
  };
513
529
 
514
530
  // src/locales/fr.ts
@@ -612,7 +628,11 @@ var FR_LABELS = {
612
628
  archiveScopeActive: "Actifs",
613
629
  archiveScopeArchived: "Archiv\xE9s",
614
630
  archiveScopeAll: "Tous les \xE9l\xE9ments",
615
- undoReorder: "Annuler le r\xE9ordonnancement"
631
+ undoReorder: "Annuler le r\xE9ordonnancement",
632
+ toolbarStart: "Actions de la collection",
633
+ toolbarQuery: "Recherche et tri",
634
+ toolbarFilters: "Filtres",
635
+ toolbarEnd: "Actions suppl\xE9mentaires"
616
636
  };
617
637
 
618
638
  // src/locales/id.ts
@@ -716,7 +736,11 @@ var ID_LABELS = {
716
736
  archiveScopeActive: "Aktif",
717
737
  archiveScopeArchived: "Diarsipkan",
718
738
  archiveScopeAll: "Semua item",
719
- undoReorder: "Batalkan pengurutan"
739
+ undoReorder: "Batalkan pengurutan",
740
+ toolbarStart: "Tindakan koleksi",
741
+ toolbarQuery: "Cari dan urutkan",
742
+ toolbarFilters: "Filter",
743
+ toolbarEnd: "Tindakan tambahan"
720
744
  };
721
745
 
722
746
  // src/locales/it.ts
@@ -820,7 +844,11 @@ var IT_LABELS = {
820
844
  archiveScopeActive: "Attivi",
821
845
  archiveScopeArchived: "Archiviati",
822
846
  archiveScopeAll: "Tutti gli elementi",
823
- undoReorder: "Annulla riordinamento"
847
+ undoReorder: "Annulla riordinamento",
848
+ toolbarStart: "Azioni della raccolta",
849
+ toolbarQuery: "Cerca e ordina",
850
+ toolbarFilters: "Filtri",
851
+ toolbarEnd: "Azioni aggiuntive"
824
852
  };
825
853
 
826
854
  // src/locales/ja.ts
@@ -924,7 +952,11 @@ var JA_LABELS = {
924
952
  archiveScopeActive: "\u4FDD\u5B58\u4E2D",
925
953
  archiveScopeArchived: "\u30A2\u30FC\u30AB\u30A4\u30D6\u6E08\u307F",
926
954
  archiveScopeAll: "\u3059\u3079\u3066",
927
- undoReorder: "\u4E26\u3073\u66FF\u3048\u3092\u5143\u306B\u623B\u3059"
955
+ undoReorder: "\u4E26\u3073\u66FF\u3048\u3092\u5143\u306B\u623B\u3059",
956
+ toolbarStart: "\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u306E\u64CD\u4F5C",
957
+ toolbarQuery: "\u691C\u7D22\u3068\u4E26\u3073\u66FF\u3048",
958
+ toolbarFilters: "\u7D5E\u308A\u8FBC\u307F",
959
+ toolbarEnd: "\u8FFD\u52A0\u306E\u64CD\u4F5C"
928
960
  };
929
961
 
930
962
  // src/locales/ko.ts
@@ -1028,7 +1060,11 @@ var KO_LABELS = {
1028
1060
  archiveScopeActive: "\uD65C\uC131",
1029
1061
  archiveScopeArchived: "\uBCF4\uAD00\uB428",
1030
1062
  archiveScopeAll: "\uBAA8\uB4E0 \uD56D\uBAA9",
1031
- undoReorder: "\uC815\uB82C \uC2E4\uD589 \uCDE8\uC18C"
1063
+ undoReorder: "\uC815\uB82C \uC2E4\uD589 \uCDE8\uC18C",
1064
+ toolbarStart: "\uCEEC\uB809\uC158 \uC791\uC5C5",
1065
+ toolbarQuery: "\uAC80\uC0C9 \uBC0F \uC815\uB82C",
1066
+ toolbarFilters: "\uD544\uD130",
1067
+ toolbarEnd: "\uCD94\uAC00 \uC791\uC5C5"
1032
1068
  };
1033
1069
 
1034
1070
  // src/locales/ms.ts
@@ -1132,7 +1168,11 @@ var MS_LABELS = {
1132
1168
  archiveScopeActive: "Aktif",
1133
1169
  archiveScopeArchived: "Diarkibkan",
1134
1170
  archiveScopeAll: "Semua item",
1135
- undoReorder: "Buat asal susunan"
1171
+ undoReorder: "Buat asal susunan",
1172
+ toolbarStart: "Tindakan koleksi",
1173
+ toolbarQuery: "Cari dan susun",
1174
+ toolbarFilters: "Penapis",
1175
+ toolbarEnd: "Tindakan tambahan"
1136
1176
  };
1137
1177
 
1138
1178
  // src/locales/pt-BR.ts
@@ -1236,7 +1276,11 @@ var PT_BR_LABELS = {
1236
1276
  archiveScopeActive: "Ativos",
1237
1277
  archiveScopeArchived: "Arquivados",
1238
1278
  archiveScopeAll: "Todos os itens",
1239
- undoReorder: "Desfazer reordena\xE7\xE3o"
1279
+ undoReorder: "Desfazer reordena\xE7\xE3o",
1280
+ toolbarStart: "A\xE7\xF5es da cole\xE7\xE3o",
1281
+ toolbarQuery: "Pesquisar e ordenar",
1282
+ toolbarFilters: "Filtros",
1283
+ toolbarEnd: "A\xE7\xF5es adicionais"
1240
1284
  };
1241
1285
 
1242
1286
  // src/locales/ru.ts
@@ -1340,7 +1384,11 @@ var RU_LABELS = {
1340
1384
  archiveScopeActive: "\u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0435",
1341
1385
  archiveScopeArchived: "\u0412 \u0430\u0440\u0445\u0438\u0432\u0435",
1342
1386
  archiveScopeAll: "\u0412\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B",
1343
- undoReorder: "\u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0443"
1387
+ undoReorder: "\u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0443",
1388
+ toolbarStart: "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044F \u043A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u0438",
1389
+ toolbarQuery: "\u041F\u043E\u0438\u0441\u043A \u0438 \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430",
1390
+ toolbarFilters: "\u0424\u0438\u043B\u044C\u0442\u0440\u044B",
1391
+ toolbarEnd: "\u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044F"
1344
1392
  };
1345
1393
 
1346
1394
  // src/locales/th.ts
@@ -1444,7 +1492,11 @@ var TH_LABELS = {
1444
1492
  archiveScopeActive: "\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E2D\u0E22\u0E39\u0E48",
1445
1493
  archiveScopeArchived: "\u0E40\u0E01\u0E47\u0E1A\u0E16\u0E32\u0E27\u0E23\u0E41\u0E25\u0E49\u0E27",
1446
1494
  archiveScopeAll: "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
1447
- undoReorder: "\u0E40\u0E25\u0E34\u0E01\u0E17\u0E33\u0E01\u0E32\u0E23\u0E08\u0E31\u0E14\u0E40\u0E23\u0E35\u0E22\u0E07"
1495
+ undoReorder: "\u0E40\u0E25\u0E34\u0E01\u0E17\u0E33\u0E01\u0E32\u0E23\u0E08\u0E31\u0E14\u0E40\u0E23\u0E35\u0E22\u0E07",
1496
+ toolbarStart: "\u0E01\u0E32\u0E23\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23\u0E02\u0E2D\u0E07\u0E04\u0E2D\u0E25\u0E40\u0E25\u0E01\u0E0A\u0E31\u0E19",
1497
+ toolbarQuery: "\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E41\u0E25\u0E30\u0E08\u0E31\u0E14\u0E40\u0E23\u0E35\u0E22\u0E07",
1498
+ toolbarFilters: "\u0E15\u0E31\u0E27\u0E01\u0E23\u0E2D\u0E07",
1499
+ toolbarEnd: "\u0E01\u0E32\u0E23\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E40\u0E15\u0E34\u0E21"
1448
1500
  };
1449
1501
 
1450
1502
  // src/locales/vi.ts
@@ -1548,7 +1600,11 @@ var VI_LABELS = {
1548
1600
  archiveScopeActive: "\u0110ang ho\u1EA1t \u0111\u1ED9ng",
1549
1601
  archiveScopeArchived: "\u0110\xE3 l\u01B0u tr\u1EEF",
1550
1602
  archiveScopeAll: "T\u1EA5t c\u1EA3 m\u1EE5c",
1551
- undoReorder: "Ho\xE0n t\xE1c s\u1EAFp x\u1EBFp"
1603
+ undoReorder: "Ho\xE0n t\xE1c s\u1EAFp x\u1EBFp",
1604
+ toolbarStart: "Thao t\xE1c b\u1ED9 s\u01B0u t\u1EADp",
1605
+ toolbarQuery: "T\xECm ki\u1EBFm v\xE0 s\u1EAFp x\u1EBFp",
1606
+ toolbarFilters: "B\u1ED9 l\u1ECDc",
1607
+ toolbarEnd: "Thao t\xE1c b\u1ED5 sung"
1552
1608
  };
1553
1609
 
1554
1610
  // src/locales/zh-Hans.ts
@@ -1652,7 +1708,11 @@ var ZH_HANS_LABELS = {
1652
1708
  archiveScopeActive: "\u4FDD\u5B58\u4E2D",
1653
1709
  archiveScopeArchived: "\u5DF2\u5F52\u6863",
1654
1710
  archiveScopeAll: "\u5168\u90E8\u9879\u76EE",
1655
- undoReorder: "\u64A4\u9500\u6392\u5E8F"
1711
+ undoReorder: "\u64A4\u9500\u6392\u5E8F",
1712
+ toolbarStart: "\u96C6\u5408\u64CD\u4F5C",
1713
+ toolbarQuery: "\u641C\u7D22\u548C\u6392\u5E8F",
1714
+ toolbarFilters: "\u7B5B\u9009",
1715
+ toolbarEnd: "\u5176\u4ED6\u64CD\u4F5C"
1656
1716
  };
1657
1717
 
1658
1718
  // src/locales/zh-Hant.ts
@@ -1756,7 +1816,11 @@ var ZH_HANT_LABELS = {
1756
1816
  archiveScopeActive: "\u4FDD\u5B58\u4E2D",
1757
1817
  archiveScopeArchived: "\u5DF2\u5C01\u5B58",
1758
1818
  archiveScopeAll: "\u6240\u6709\u9805\u76EE",
1759
- undoReorder: "\u5FA9\u539F\u6392\u5E8F"
1819
+ undoReorder: "\u5FA9\u539F\u6392\u5E8F",
1820
+ toolbarStart: "\u96C6\u5408\u64CD\u4F5C",
1821
+ toolbarQuery: "\u641C\u5C0B\u8207\u6392\u5E8F",
1822
+ toolbarFilters: "\u7BE9\u9078",
1823
+ toolbarEnd: "\u5176\u4ED6\u64CD\u4F5C"
1760
1824
  };
1761
1825
 
1762
1826
  // src/locales/index.ts
@@ -2076,11 +2140,12 @@ function getErrorMessage(error) {
2076
2140
  import {
2077
2141
  cloneElement,
2078
2142
  createContext as createContext2,
2143
+ Fragment,
2079
2144
  isValidElement,
2080
2145
  useContext as useContext2,
2081
2146
  useMemo as useMemo2
2082
2147
  } from "react";
2083
- import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
2148
+ import { Fragment as Fragment2, jsx as jsx3 } from "react/jsx-runtime";
2084
2149
  var KeepSearchQueryContext = createContext2(void 0);
2085
2150
  function KeepSearchQueryProvider({ query, children }) {
2086
2151
  return /* @__PURE__ */ jsx3(KeepSearchQueryContext.Provider, { value: query, children });
@@ -2117,7 +2182,7 @@ function highlightText(text, query) {
2117
2182
  }
2118
2183
  if (lastIndex === 0) return text;
2119
2184
  if (lastIndex < text.length) parts.push(text.slice(lastIndex));
2120
- return /* @__PURE__ */ jsx3(Fragment, { children: parts });
2185
+ return /* @__PURE__ */ jsx3(Fragment2, { children: parts });
2121
2186
  }
2122
2187
  function escapeRegExp(value) {
2123
2188
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -2148,6 +2213,15 @@ function sortToValue(sort) {
2148
2213
  function resolveContent(content, state) {
2149
2214
  return typeof content === "function" ? content(state) : content;
2150
2215
  }
2216
+ function hasRenderableContent(content) {
2217
+ if (content === null || content === void 0 || typeof content === "boolean") return false;
2218
+ if (typeof content === "string") return content.length > 0;
2219
+ if (Array.isArray(content)) return content.some(hasRenderableContent);
2220
+ if (isValidElement(content) && content.type === Fragment) {
2221
+ return hasRenderableContent(content.props.children);
2222
+ }
2223
+ return true;
2224
+ }
2151
2225
  function composeRefs(...refs) {
2152
2226
  return (value) => {
2153
2227
  for (const ref of refs) {
@@ -2354,7 +2428,7 @@ function getItemLabel(item) {
2354
2428
  }
2355
2429
 
2356
2430
  // src/features/actions/KeepBulkActions.tsx
2357
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
2431
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
2358
2432
  function KeepBulkActions({
2359
2433
  query,
2360
2434
  selectedIds: controlledSelectedIds,
@@ -2377,7 +2451,7 @@ function KeepBulkActions({
2377
2451
  controlledScope,
2378
2452
  onSelectionScopeChange
2379
2453
  });
2380
- const body = render ? render(state) : typeof children === "function" ? children(state) : children ?? /* @__PURE__ */ jsxs3(Fragment2, { children: [
2454
+ const body = render ? render(state) : typeof children === "function" ? children(state) : children ?? /* @__PURE__ */ jsxs3(Fragment3, { children: [
2381
2455
  /* @__PURE__ */ jsxs3("fieldset", { children: [
2382
2456
  /* @__PURE__ */ jsx5("legend", { children: labels.selectItems }),
2383
2457
  /* @__PURE__ */ jsxs3("label", { children: [
@@ -2495,7 +2569,7 @@ function useKeepButton({ item, labels, icons, children }) {
2495
2569
  }
2496
2570
 
2497
2571
  // src/features/actions/KeepButton.tsx
2498
- import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
2572
+ import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
2499
2573
  function KeepButton({
2500
2574
  labels,
2501
2575
  icons,
@@ -2540,7 +2614,7 @@ function KeepButton({
2540
2614
  const label = state.error ? labels?.error ?? view.labels.error : state.isMutating ? labels?.loading ?? view.labels.loading : state.isSaved ? labels?.saved ?? view.labels.saved : labels?.unsaved ?? view.labels.save;
2541
2615
  if (!icons) return label;
2542
2616
  const icon = state.error ? icons.error : state.isMutating ? icons.loading : state.isSaved ? icons.remove ?? icons.saved : icons.save;
2543
- return /* @__PURE__ */ jsxs4(Fragment3, { children: [
2617
+ return /* @__PURE__ */ jsxs4(Fragment4, { children: [
2544
2618
  renderIcon(icon, iconClassName),
2545
2619
  showLabel && !iconOnly ? label : null
2546
2620
  ] });
@@ -2568,7 +2642,7 @@ function KeepButton({
2568
2642
  unsavedAriaLabel: labels?.unsavedAriaLabel ?? props.unsavedAriaLabel
2569
2643
  };
2570
2644
  if (!view.customStateLabel) return /* @__PURE__ */ jsx6(CoreKeepButton, { ...sharedProps });
2571
- return /* @__PURE__ */ jsx6(CoreKeepButton, { ...sharedProps, children: (state) => /* @__PURE__ */ jsx6(Fragment3, { children: getStateContent(state) }) });
2645
+ return /* @__PURE__ */ jsx6(CoreKeepButton, { ...sharedProps, children: (state) => /* @__PURE__ */ jsx6(Fragment4, { children: getStateContent(state) }) });
2572
2646
  }
2573
2647
  function renderIcon(icon, className) {
2574
2648
  if (typeof icon === "function") return createElement(icon, { "aria-hidden": true, className });
@@ -2593,7 +2667,7 @@ import {
2593
2667
  useRef as useRef4,
2594
2668
  useState as useState3
2595
2669
  } from "react";
2596
- import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
2670
+ import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
2597
2671
  function useKeepQuickEditor(item, options = {}) {
2598
2672
  const { debounceMs = 300, onSaved, onSaveError } = options;
2599
2673
  const itemState = useKeepItem3(item);
@@ -2750,7 +2824,7 @@ function KeepQuickEditorView({
2750
2824
  if (event.key === "Tab") trapFocus(event, focusScopeRef?.current ?? rootRef.current);
2751
2825
  };
2752
2826
  const statusMessage = state.saveStatus === "dirty" ? unsavedChangesLabel : state.saveStatus === "saving" ? savingLabel : state.saveStatus === "saved" ? savedLabel : state.saveStatus === "error" ? getErrorMessage2(state.error, errorLabel) : null;
2753
- const body = typeof children === "function" ? children(state) : children ?? /* @__PURE__ */ jsxs5(Fragment4, { children: [
2827
+ const body = typeof children === "function" ? children(state) : children ?? /* @__PURE__ */ jsxs5(Fragment5, { children: [
2754
2828
  /* @__PURE__ */ jsxs5("label", { children: [
2755
2829
  noteLabel,
2756
2830
  /* @__PURE__ */ jsx7("textarea", { value: state.note, onChange: (event) => state.setNote(event.currentTarget.value) })
@@ -3061,14 +3135,14 @@ function KeepUndo({ children, label, ...props }) {
3061
3135
 
3062
3136
  // src/features/collection/KeepCollection.tsx
3063
3137
  import { KeepErrorBoundary as KeepErrorBoundary2 } from "@keepkit/core/react";
3064
- import { useEffect as useEffect10, useState as useState14 } from "react";
3138
+ import { useEffect as useEffect10, useId as useId3, useState as useState14 } from "react";
3065
3139
 
3066
3140
  // src/features/query/KeepActiveFiltersSummary.tsx
3067
3141
  import {
3068
3142
  isValidElement as isValidElement2,
3069
3143
  useRef as useRef6
3070
3144
  } from "react";
3071
- import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
3145
+ import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
3072
3146
  function KeepActiveFiltersSummary({
3073
3147
  query,
3074
3148
  search: providedSearch,
@@ -3129,7 +3203,7 @@ function KeepActiveFiltersSummary({
3129
3203
  removeTag: (tag) => onTagChange?.(tag)
3130
3204
  };
3131
3205
  const contentChildren = asChild && isElement(children) ? void 0 : children;
3132
- const body = typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? (hasFilters ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
3206
+ const body = typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? (hasFilters ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
3133
3207
  /* @__PURE__ */ jsx10("span", { "data-active-filters-label": "true", children: activeFiltersLabel }),
3134
3208
  /* @__PURE__ */ jsxs8("ul", { "data-active-filters-list": "true", children: [
3135
3209
  search ? /* @__PURE__ */ jsxs8("li", { "data-filter-kind": "search", children: [
@@ -3512,7 +3586,7 @@ function getVisiblePages(currentPage, pageCount, maxPageButtons) {
3512
3586
  }
3513
3587
 
3514
3588
  // src/features/query/query-controls.tsx
3515
- import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
3589
+ import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
3516
3590
  function KeepSearchInput({
3517
3591
  value: controlledValue,
3518
3592
  defaultValue = "",
@@ -3548,7 +3622,7 @@ function KeepSortSelect({
3548
3622
  ...props
3549
3623
  }) {
3550
3624
  const view = useKeepSortSelect({ controlledValue, defaultValue, onValueChange });
3551
- const options = children ?? /* @__PURE__ */ jsxs12(Fragment6, { children: [
3625
+ const options = children ?? /* @__PURE__ */ jsxs12(Fragment7, { children: [
3552
3626
  /* @__PURE__ */ jsx14("option", { value: "updatedAt:desc", children: view.labels.updatedNewest }),
3553
3627
  /* @__PURE__ */ jsx14("option", { value: "updatedAt:asc", children: view.labels.updatedOldest }),
3554
3628
  /* @__PURE__ */ jsx14("option", { value: "savedAt:desc", children: view.labels.savedNewest }),
@@ -3805,7 +3879,7 @@ function getDisplayStatus(status) {
3805
3879
  }
3806
3880
 
3807
3881
  // src/features/item/KeepItemStatusBadge.tsx
3808
- import { Fragment as Fragment7, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
3882
+ import { Fragment as Fragment8, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
3809
3883
  function KeepItemStatusBadge({ status = "available", label, className, ...props }) {
3810
3884
  const view = useKeepItemStatusBadge(status);
3811
3885
  return /* @__PURE__ */ jsxs13(
@@ -3842,15 +3916,15 @@ function StatusIcon({ name }) {
3842
3916
  focusable: "false",
3843
3917
  children: [
3844
3918
  name === "check" ? /* @__PURE__ */ jsx15("path", { d: "m5 12 4 4L19 6" }) : null,
3845
- name === "clock" ? /* @__PURE__ */ jsxs13(Fragment7, { children: [
3919
+ name === "clock" ? /* @__PURE__ */ jsxs13(Fragment8, { children: [
3846
3920
  /* @__PURE__ */ jsx15("circle", { cx: "12", cy: "12", r: "8" }),
3847
3921
  /* @__PURE__ */ jsx15("path", { d: "M12 7v5l3 2" })
3848
3922
  ] }) : null,
3849
- name === "ban" ? /* @__PURE__ */ jsxs13(Fragment7, { children: [
3923
+ name === "ban" ? /* @__PURE__ */ jsxs13(Fragment8, { children: [
3850
3924
  /* @__PURE__ */ jsx15("circle", { cx: "12", cy: "12", r: "8" }),
3851
3925
  /* @__PURE__ */ jsx15("path", { d: "m6.5 6.5 11 11" })
3852
3926
  ] }) : null,
3853
- name === "lock" ? /* @__PURE__ */ jsxs13(Fragment7, { children: [
3927
+ name === "lock" ? /* @__PURE__ */ jsxs13(Fragment8, { children: [
3854
3928
  /* @__PURE__ */ jsx15("rect", { x: "5", y: "10", width: "14", height: "10", rx: "2" }),
3855
3929
  /* @__PURE__ */ jsx15("path", { d: "M8 10V7a4 4 0 0 1 8 0v3" })
3856
3930
  ] }) : null
@@ -4111,7 +4185,7 @@ function getDisplayStatus2(status) {
4111
4185
  }
4112
4186
 
4113
4187
  // src/features/item/KeepItemCard.tsx
4114
- import { Fragment as Fragment8, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
4188
+ import { Fragment as Fragment9, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
4115
4189
  var KeepItemCardContext = createContext3(null);
4116
4190
  function useKeepItemCardCompound(part) {
4117
4191
  const context = useContext3(KeepItemCardContext);
@@ -4151,6 +4225,7 @@ function KeepItemCardRoot({
4151
4225
  linkTargetAttribute,
4152
4226
  linkRel,
4153
4227
  highlightQuery,
4228
+ cardVariant = "outlined",
4154
4229
  className,
4155
4230
  ...rootProps
4156
4231
  }) {
@@ -4226,8 +4301,8 @@ function KeepItemCardRoot({
4226
4301
  /* @__PURE__ */ jsx17("time", { dateTime: new Date(item.savedAt).toISOString(), children: formatSavedAt(item.savedAt) })
4227
4302
  ] }) : null;
4228
4303
  const error = view.itemState.error ? /* @__PURE__ */ jsx17("p", { role: "alert", children: getErrorMessage3(view.itemState.error, view.labels.error) }) : null;
4229
- const actions = view.statusLabel ? /* @__PURE__ */ jsx17(KeepStaleNotice, { item, onRetry, onRemoved }) : /* @__PURE__ */ jsxs15(Fragment8, { children: [
4230
- showEditButton ? /* @__PURE__ */ jsxs15(Fragment8, { children: [
4304
+ const actions = view.statusLabel ? /* @__PURE__ */ jsx17(KeepStaleNotice, { item, onRetry, onRemoved }) : /* @__PURE__ */ jsxs15(Fragment9, { children: [
4305
+ showEditButton ? /* @__PURE__ */ jsxs15(Fragment9, { children: [
4231
4306
  /* @__PURE__ */ jsx17(
4232
4307
  "button",
4233
4308
  {
@@ -4273,7 +4348,7 @@ function KeepItemCardRoot({
4273
4348
  saveAriaLabel: `${view.labels.remove} ${String(view.resolvedTitle)}`,
4274
4349
  renderText: (content) => /* @__PURE__ */ jsx17(KeepHighlight, { query: searchQuery, children: content })
4275
4350
  };
4276
- const defaultBody = /* @__PURE__ */ jsxs15(Fragment8, { children: [
4351
+ const defaultBody = /* @__PURE__ */ jsxs15(Fragment9, { children: [
4277
4352
  /* @__PURE__ */ jsx17(KeepItemCardMedia, {}),
4278
4353
  /* @__PURE__ */ jsx17(KeepItemCardContent, {}),
4279
4354
  /* @__PURE__ */ jsx17(KeepItemCardActions, {})
@@ -4292,6 +4367,7 @@ function KeepItemCardRoot({
4292
4367
  "data-state": view.itemState.error ? "error" : view.itemState.isSaved ? "saved" : "unsaved",
4293
4368
  "data-status": item.status ?? "available",
4294
4369
  "data-item-status": view.displayStatus,
4370
+ "data-card-variant": cardVariant !== "outlined" ? cardVariant : void 0,
4295
4371
  "data-loading": view.itemState.isMutating ? "true" : void 0
4296
4372
  },
4297
4373
  linkedBody,
@@ -4305,7 +4381,7 @@ function KeepItemCardMedia({ children, fallback, ...props }) {
4305
4381
  }
4306
4382
  function KeepItemCardContent({ children, ...props }) {
4307
4383
  const context = useKeepItemCardCompound("Content");
4308
- return /* @__PURE__ */ jsx17("div", { ...props, "data-keep-card-part": "content", children: children === void 0 ? /* @__PURE__ */ jsxs15(Fragment8, { children: [
4384
+ return /* @__PURE__ */ jsx17("div", { ...props, "data-keep-card-part": "content", children: children === void 0 ? /* @__PURE__ */ jsxs15(Fragment9, { children: [
4309
4385
  /* @__PURE__ */ jsx17(KeepItemCardTitle, {}),
4310
4386
  context.meta,
4311
4387
  /* @__PURE__ */ jsx17(KeepItemCardTags, {}),
@@ -4420,7 +4496,7 @@ function getErrorMessage3(error, fallback) {
4420
4496
 
4421
4497
  // src/features/status/KeepEmptyState.tsx
4422
4498
  import { isValidElement as isValidElement5 } from "react";
4423
- import { Fragment as Fragment9, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
4499
+ import { Fragment as Fragment10, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
4424
4500
  function KeepEmptyState({
4425
4501
  title,
4426
4502
  description,
@@ -4439,7 +4515,7 @@ function KeepEmptyState({
4439
4515
  );
4440
4516
  const clearLabel = useUiLabel("clearFilters");
4441
4517
  const contentChildren = asChild && isValidElement5(children) ? void 0 : children;
4442
- const body = contentChildren ?? /* @__PURE__ */ jsxs16(Fragment9, { children: [
4518
+ const body = contentChildren ?? /* @__PURE__ */ jsxs16(Fragment10, { children: [
4443
4519
  /* @__PURE__ */ jsx18("h2", { children: title ?? defaultTitle }),
4444
4520
  description ?? /* @__PURE__ */ jsx18("p", { children: defaultDescription }),
4445
4521
  action ?? (resolvedVariant === "empty-filtered" && onClearFilters ? /* @__PURE__ */ jsx18("button", { type: "button", "data-keep-action": "clear-filters", onClick: onClearFilters, children: clearLabel }) : null)
@@ -4644,7 +4720,7 @@ function KeepReorderableList({
4644
4720
  }
4645
4721
 
4646
4722
  // src/features/collection/KeepList.tsx
4647
- import { Fragment as Fragment10, jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
4723
+ import { Fragment as Fragment11, jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
4648
4724
  function KeepList(props) {
4649
4725
  const { fallback, onBoundaryError, boundaryResetKey, ...listProps } = props;
4650
4726
  const content = /* @__PURE__ */ jsx20(KeepListContent, { ...listProps });
@@ -4729,7 +4805,7 @@ function getListBody(state, options) {
4729
4805
  if (state.isLoading && !state.isHydrated) {
4730
4806
  if (options.loading !== void 0) return resolveContent(options.loading, state);
4731
4807
  const count = Number.isFinite(options.loadingCount) ? Math.max(0, Math.floor(options.loadingCount)) : 6;
4732
- return /* @__PURE__ */ jsxs17(Fragment10, { children: [
4808
+ return /* @__PURE__ */ jsxs17(Fragment11, { children: [
4733
4809
  /* @__PURE__ */ jsx20("span", { role: "status", "data-keepkit": "loading-label", children: options.loadingLabel }),
4734
4810
  /* @__PURE__ */ jsx20("ul", { "data-keepkit": "skeleton-list", "data-layout": options.layout, children: Array.from({ length: count }, (_, index) => (
4735
4811
  // biome-ignore lint/suspicious/noArrayIndexKey: Static loading placeholders never reorder.
@@ -4758,7 +4834,7 @@ function getListBody(state, options) {
4758
4834
  await options.reorder(orderedIds);
4759
4835
  await options.onReorder?.(orderedIds);
4760
4836
  },
4761
- renderItem: (item, reorderState) => /* @__PURE__ */ jsxs17(Fragment10, { children: [
4837
+ renderItem: (item, reorderState) => /* @__PURE__ */ jsxs17(Fragment11, { children: [
4762
4838
  /* @__PURE__ */ jsx20("button", { type: "button", ...reorderState.dragHandleProps, children: "\u2195" }),
4763
4839
  options.renderItem ? options.renderItem(item, state) : /* @__PURE__ */ jsx20(KeepItemCard, { item, ...options.itemCardProps })
4764
4840
  ] }),
@@ -4778,7 +4854,7 @@ function hasActiveQueryFilters(query) {
4778
4854
  }
4779
4855
 
4780
4856
  // src/features/collection/KeepCollection.tsx
4781
- import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
4857
+ import { Fragment as Fragment12, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
4782
4858
  function KeepCollection(props) {
4783
4859
  const { fallback, onBoundaryError, boundaryResetKey, ...collectionProps } = props;
4784
4860
  const content = /* @__PURE__ */ jsx21(KeepCollectionContent, { ...collectionProps });
@@ -4789,6 +4865,8 @@ function KeepCollectionContent({
4789
4865
  query = {},
4790
4866
  pageSize = 20,
4791
4867
  layout = "list",
4868
+ toolbarVariant = "plain",
4869
+ toolbarLayout = "flat",
4792
4870
  urlSync = false,
4793
4871
  urlAdapter,
4794
4872
  archiveScope,
@@ -4796,6 +4874,7 @@ function KeepCollectionContent({
4796
4874
  reorderable = false,
4797
4875
  onReorder,
4798
4876
  features,
4877
+ slots,
4799
4878
  collectionLabels,
4800
4879
  renderItem,
4801
4880
  itemCardProps,
@@ -4839,6 +4918,68 @@ function KeepCollectionContent({
4839
4918
  showPinButton: itemCardProps?.showPinButton ?? view.enabled.pin,
4840
4919
  showArchiveButton: itemCardProps?.showArchiveButton ?? view.enabled.archive
4841
4920
  };
4921
+ const toolbarId = useId3();
4922
+ const structuredToolbar = toolbarLayout === "grouped" || toolbarVariant === "panel" || slots?.toolbarStart !== void 0 || slots?.toolbarEnd !== void 0;
4923
+ const hasQueryControls = view.enabled.search || view.enabled.sort;
4924
+ const hasFilterControls = view.enabled.tagFilter || view.enabled.collectionFilter || archiveScope !== void 0;
4925
+ const queryControls = hasQueryControls ? /* @__PURE__ */ jsxs18(Fragment12, { children: [
4926
+ view.enabled.search ? /* @__PURE__ */ jsx21(KeepSearchInput, { value: view.searchValue, onValueChange: view.setSearchValue }) : null,
4927
+ view.enabled.sort ? /* @__PURE__ */ jsx21(KeepSortSelect, { value: view.sortValue, onValueChange: view.setSortValue }) : null
4928
+ ] }) : null;
4929
+ const filterControls = hasFilterControls ? /* @__PURE__ */ jsxs18(Fragment12, { children: [
4930
+ view.enabled.tagFilter ? /* @__PURE__ */ jsx21(KeepTagFilter, { query, value: view.activeTags[0], onValueChange: view.setTag }) : null,
4931
+ view.enabled.collectionFilter ? /* @__PURE__ */ jsx21(
4932
+ KeepCollectionFilter,
4933
+ {
4934
+ value: view.activeCollection,
4935
+ onValueChange: view.setCollection,
4936
+ collectionLabels
4937
+ }
4938
+ ) : null,
4939
+ archiveScope !== void 0 ? /* @__PURE__ */ jsx21(
4940
+ KeepArchiveScopeSelect,
4941
+ {
4942
+ value: view.archiveScope,
4943
+ onValueChange: (next) => {
4944
+ view.setArchiveScope(next);
4945
+ onArchiveScopeChange?.(next);
4946
+ }
4947
+ }
4948
+ ) : null
4949
+ ] }) : null;
4950
+ const toolbarStartLabel = useUiLabel("toolbarStart");
4951
+ const toolbarQueryLabel = useUiLabel("toolbarQuery");
4952
+ const toolbarFiltersLabel = useUiLabel("toolbarFilters");
4953
+ const toolbarEndLabel = useUiLabel("toolbarEnd");
4954
+ const toolbarStartContent = slots?.toolbarStart === void 0 ? null : resolveContent(slots.toolbarStart, view.list);
4955
+ const toolbarEndContent = slots?.toolbarEnd === void 0 ? null : resolveContent(slots.toolbarEnd, view.list);
4956
+ const hasToolbarContent = hasQueryControls || hasFilterControls || hasRenderableContent(toolbarStartContent) || hasRenderableContent(toolbarEndContent);
4957
+ const renderToolbarGroup = (group, content, label) => {
4958
+ if (!hasRenderableContent(content)) return null;
4959
+ const labelId = `${toolbarId}-${group}`;
4960
+ return /* @__PURE__ */ jsxs18(
4961
+ "fieldset",
4962
+ {
4963
+ "data-keepkit": "collection-toolbar-group",
4964
+ "data-group": group,
4965
+ role: "group",
4966
+ "aria-labelledby": labelId,
4967
+ children: [
4968
+ /* @__PURE__ */ jsx21("legend", { id: labelId, "data-keepkit": "collection-toolbar-label", children: label }),
4969
+ /* @__PURE__ */ jsx21("div", { "data-keepkit": "collection-toolbar-content", children: content })
4970
+ ]
4971
+ }
4972
+ );
4973
+ };
4974
+ const toolbar = !structuredToolbar ? /* @__PURE__ */ jsxs18("div", { children: [
4975
+ queryControls,
4976
+ filterControls
4977
+ ] }) : !hasToolbarContent ? null : /* @__PURE__ */ jsxs18("div", { "data-keepkit": "collection-toolbar", "data-variant": toolbarVariant, "data-layout": toolbarLayout, children: [
4978
+ renderToolbarGroup("toolbarStart", toolbarStartContent, toolbarStartLabel),
4979
+ renderToolbarGroup("query", queryControls, toolbarQueryLabel),
4980
+ renderToolbarGroup("filters", filterControls, toolbarFiltersLabel),
4981
+ renderToolbarGroup("toolbarEnd", toolbarEndContent, toolbarEndLabel)
4982
+ ] });
4842
4983
  return /* @__PURE__ */ jsxs18(
4843
4984
  "section",
4844
4985
  {
@@ -4846,33 +4987,13 @@ function KeepCollectionContent({
4846
4987
  className,
4847
4988
  "data-keepkit": "collection",
4848
4989
  "data-layout": layout,
4990
+ "data-toolbar-variant": toolbarVariant !== "plain" ? toolbarVariant : void 0,
4991
+ "data-toolbar-layout": toolbarLayout !== "flat" ? toolbarLayout : void 0,
4849
4992
  "aria-busy": view.list.isLoading || view.list.isMutating || rootProps["aria-busy"],
4850
4993
  "data-state": getCollectionState(view.list),
4851
4994
  "data-loading": view.list.isLoading || view.list.isMutating ? "true" : void 0,
4852
4995
  children: [
4853
- /* @__PURE__ */ jsxs18("div", { children: [
4854
- view.enabled.search ? /* @__PURE__ */ jsx21(KeepSearchInput, { value: view.searchValue, onValueChange: view.setSearchValue }) : null,
4855
- view.enabled.sort ? /* @__PURE__ */ jsx21(KeepSortSelect, { value: view.sortValue, onValueChange: view.setSortValue }) : null,
4856
- view.enabled.tagFilter ? /* @__PURE__ */ jsx21(KeepTagFilter, { query, value: view.activeTags[0], onValueChange: view.setTag }) : null,
4857
- view.enabled.collectionFilter ? /* @__PURE__ */ jsx21(
4858
- KeepCollectionFilter,
4859
- {
4860
- value: view.activeCollection,
4861
- onValueChange: view.setCollection,
4862
- collectionLabels
4863
- }
4864
- ) : null,
4865
- archiveScope !== void 0 ? /* @__PURE__ */ jsx21(
4866
- KeepArchiveScopeSelect,
4867
- {
4868
- value: view.archiveScope,
4869
- onValueChange: (next) => {
4870
- view.setArchiveScope(next);
4871
- onArchiveScopeChange?.(next);
4872
- }
4873
- }
4874
- ) : null
4875
- ] }),
4996
+ toolbar,
4876
4997
  activeFilters === void 0 ? /* @__PURE__ */ jsx21(
4877
4998
  KeepActiveFiltersSummary,
4878
4999
  {
@@ -5027,7 +5148,7 @@ function useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError }) {
5027
5148
  }
5028
5149
 
5029
5150
  // src/features/editor/KeepNoteEditor.tsx
5030
- import { Fragment as Fragment11, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
5151
+ import { Fragment as Fragment13, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
5031
5152
  function KeepNoteEditor({
5032
5153
  item,
5033
5154
  label,
@@ -5046,7 +5167,7 @@ function KeepNoteEditor({
5046
5167
  const view = useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError });
5047
5168
  const { error, isDirty, isSaving, note, setNote } = view.state;
5048
5169
  const contentChildren = asChild && isValidElement7(children) ? void 0 : children;
5049
- const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */ jsxs20(Fragment11, { children: [
5170
+ const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */ jsxs20(Fragment13, { children: [
5050
5171
  /* @__PURE__ */ jsxs20("label", { children: [
5051
5172
  label ?? view.labels.note,
5052
5173
  /* @__PURE__ */ jsx24(
@@ -5160,7 +5281,7 @@ function useKeepTagEditor({ item, onSaved, onSaveError }) {
5160
5281
  }
5161
5282
 
5162
5283
  // src/features/editor/KeepTagEditor.tsx
5163
- import { Fragment as Fragment12, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
5284
+ import { Fragment as Fragment14, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
5164
5285
  function KeepTagEditor({
5165
5286
  item,
5166
5287
  availableTags = [],
@@ -5171,7 +5292,7 @@ function KeepTagEditor({
5171
5292
  }) {
5172
5293
  const view = useKeepTagEditor({ item, onSaved, onSaveError });
5173
5294
  const { isSaving, tags } = view.state;
5174
- const body = render ? render(view.state) : /* @__PURE__ */ jsxs21(Fragment12, { children: [
5295
+ const body = render ? render(view.state) : /* @__PURE__ */ jsxs21(Fragment14, { children: [
5175
5296
  /* @__PURE__ */ jsxs21("label", { children: [
5176
5297
  view.labels.tags,
5177
5298
  /* @__PURE__ */ jsx25(
@@ -5235,7 +5356,7 @@ function useKeepToastFeedback(showToast) {
5235
5356
 
5236
5357
  // src/features/navigation/KeepTourBar.tsx
5237
5358
  import { useKeepNavigator } from "@keepkit/core/react";
5238
- import { useId as useId3 } from "react";
5359
+ import { useId as useId4 } from "react";
5239
5360
 
5240
5361
  // src/features/navigation/hooks/useKeepTourShortcuts.ts
5241
5362
  import { useEffect as useEffect13 } from "react";
@@ -5270,7 +5391,7 @@ function isEditableTarget(target) {
5270
5391
  }
5271
5392
 
5272
5393
  // src/features/navigation/KeepTourBar.tsx
5273
- import { Fragment as Fragment13, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
5394
+ import { Fragment as Fragment15, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
5274
5395
  function KeepTourBar({
5275
5396
  navigation: providedNavigation,
5276
5397
  currentId,
@@ -5340,7 +5461,7 @@ function KeepTourBar({
5340
5461
  return resolvedPrev();
5341
5462
  }
5342
5463
  });
5343
- const body = /* @__PURE__ */ jsxs22(Fragment13, { children: [
5464
+ const body = /* @__PURE__ */ jsxs22(Fragment15, { children: [
5344
5465
  showProgress ? /* @__PURE__ */ jsx26("span", { "data-keepkit": "tour-progress", "aria-live": "polite", children: progress ?? `${navigation.currentPosition ?? 0} / ${navigation.items.length}` }) : null,
5345
5466
  /* @__PURE__ */ jsx26(
5346
5467
  TourAction,
@@ -5350,7 +5471,7 @@ function KeepTourBar({
5350
5471
  onClick: resolvedPrevHref ? notifyPrevNavigation : resolvedPrev,
5351
5472
  "data-keep-action": "tour-prev",
5352
5473
  shortcut: showShortcutHint ? shortcutOptions?.prevKeys?.[0] ?? "K" : void 0,
5353
- preview: navigation.prevItem ? /* @__PURE__ */ jsxs22(Fragment13, { children: [
5474
+ preview: navigation.prevItem ? /* @__PURE__ */ jsxs22(Fragment15, { children: [
5354
5475
  previousLabel,
5355
5476
  ": ",
5356
5477
  getItemTitle(navigation.prevItem)
@@ -5366,7 +5487,7 @@ function KeepTourBar({
5366
5487
  onClick: resolvedNextHref ? notifyNextNavigation : resolvedNext,
5367
5488
  "data-keep-action": "tour-next",
5368
5489
  shortcut: showShortcutHint ? shortcutOptions?.nextKeys?.[0] ?? "J" : void 0,
5369
- preview: navigation.nextItem ? /* @__PURE__ */ jsxs22(Fragment13, { children: [
5490
+ preview: navigation.nextItem ? /* @__PURE__ */ jsxs22(Fragment15, { children: [
5370
5491
  nextItemLabel,
5371
5492
  ": ",
5372
5493
  getItemTitle(navigation.nextItem)
@@ -5385,8 +5506,8 @@ function KeepTourBar({
5385
5506
  );
5386
5507
  }
5387
5508
  function TourAction({ href, disabled = false, onClick, children, preview, shortcut, ...props }) {
5388
- const previewId = useId3();
5389
- const content = /* @__PURE__ */ jsxs22(Fragment13, { children: [
5509
+ const previewId = useId4();
5510
+ const content = /* @__PURE__ */ jsxs22(Fragment15, { children: [
5390
5511
  /* @__PURE__ */ jsx26("span", { "data-tour-label": "true", children }),
5391
5512
  shortcut ? /* @__PURE__ */ jsx26(KeepShortcutHint, { shortcut }) : null,
5392
5513
  preview ? /* @__PURE__ */ jsx26("small", { id: previewId, "data-tour-preview": "true", children: preview }) : null
@@ -5865,6 +5986,8 @@ import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
5865
5986
  function KeepWorkspace({
5866
5987
  preset = "standard",
5867
5988
  modules,
5989
+ surface,
5990
+ sectionGap,
5868
5991
  collectionProps,
5869
5992
  syncStatusProps,
5870
5993
  recoveryProps,
@@ -5893,38 +6016,64 @@ function KeepWorkspace({
5893
6016
  ...collectionProps,
5894
6017
  features: { ...view.collectionFeatures, ...collectionProps?.features }
5895
6018
  };
5896
- return /* @__PURE__ */ jsxs25("section", { ...props, className, "data-keepkit": "workspace", "data-preset": preset, children: [
5897
- resolveOptionalSlot(slots?.before, state),
5898
- view.modules.syncStatus ? resolveSlot(
5899
- slots?.syncStatus,
5900
- /* @__PURE__ */ jsx30(KeepSyncStatusBanner, { ...syncStatusProps, onResolveConflicts: view.openRecovery }),
5901
- state
5902
- ) : null,
5903
- resolveSlot(slots?.collection, /* @__PURE__ */ jsx30(KeepCollection, { ...resolvedCollectionProps }), state),
5904
- view.modules.backup || view.modules.stalePrune ? resolveSlot(
5905
- slots?.actions,
5906
- /* @__PURE__ */ jsxs25("div", { "data-keepkit": "workspace-actions", children: [
5907
- view.modules.stalePrune ? /* @__PURE__ */ jsx30(KeepPruneStaleButton, { ...stalePruneProps }) : null,
5908
- view.modules.backup ? /* @__PURE__ */ jsx30(KeepBackup, { ...backupProps }) : null
5909
- ] }),
5910
- state
5911
- ) : null,
5912
- view.modules.undo ? resolveSlot(slots?.undo, /* @__PURE__ */ jsx30(KeepUndo, { ...undoProps }), state) : null,
5913
- view.modules.recovery ? resolveSlot(
5914
- slots?.recovery,
5915
- /* @__PURE__ */ jsx30(
5916
- KeepSyncRecoveryDialog,
5917
- {
5918
- ...recoveryProps,
5919
- open: view.recoveryOpen,
5920
- onOpenChange: view.setRecoveryOpen
5921
- }
5922
- ),
5923
- state
5924
- ) : null,
5925
- resolveOptionalSlot(children, state),
5926
- resolveOptionalSlot(slots?.after, state)
5927
- ] });
6019
+ const structuredRegions = surface !== void 0 && surface !== "plain";
6020
+ const region = (name, content) => {
6021
+ if (!structuredRegions) return content;
6022
+ if (!hasRenderableContent(content)) return null;
6023
+ const resolvedSurface = typeof surface === "string" ? surface : surface[name] ?? "plain";
6024
+ return /* @__PURE__ */ jsx30("div", { "data-keepkit": "workspace-region", "data-region": name, "data-surface": resolvedSurface, children: content });
6025
+ };
6026
+ const before = resolveOptionalSlot(slots?.before, state);
6027
+ const syncStatus = view.modules.syncStatus ? resolveSlot(
6028
+ slots?.syncStatus,
6029
+ /* @__PURE__ */ jsx30(KeepSyncStatusBanner, { ...syncStatusProps, onResolveConflicts: view.openRecovery }),
6030
+ state
6031
+ ) : null;
6032
+ const collection = resolveSlot(slots?.collection, /* @__PURE__ */ jsx30(KeepCollection, { ...resolvedCollectionProps }), state);
6033
+ const actions = view.modules.backup || view.modules.stalePrune ? resolveSlot(
6034
+ slots?.actions,
6035
+ /* @__PURE__ */ jsxs25("div", { "data-keepkit": "workspace-actions", children: [
6036
+ view.modules.stalePrune ? /* @__PURE__ */ jsx30(KeepPruneStaleButton, { ...stalePruneProps }) : null,
6037
+ view.modules.backup ? /* @__PURE__ */ jsx30(KeepBackup, { ...backupProps }) : null
6038
+ ] }),
6039
+ state
6040
+ ) : null;
6041
+ const undo = view.modules.undo ? resolveSlot(slots?.undo, /* @__PURE__ */ jsx30(KeepUndo, { ...undoProps }), state) : null;
6042
+ const recovery = view.modules.recovery ? resolveSlot(
6043
+ slots?.recovery,
6044
+ /* @__PURE__ */ jsx30(
6045
+ KeepSyncRecoveryDialog,
6046
+ {
6047
+ ...recoveryProps,
6048
+ open: view.recoveryOpen,
6049
+ onOpenChange: view.setRecoveryOpen
6050
+ }
6051
+ ),
6052
+ state
6053
+ ) : null;
6054
+ const additionalContent = resolveOptionalSlot(children, state);
6055
+ const after = resolveOptionalSlot(slots?.after, state);
6056
+ return /* @__PURE__ */ jsxs25(
6057
+ "section",
6058
+ {
6059
+ ...props,
6060
+ className,
6061
+ "data-keepkit": "workspace",
6062
+ "data-preset": preset,
6063
+ "data-surface": surface !== void 0 ? typeof surface === "string" ? surface : "custom" : void 0,
6064
+ "data-section-gap": sectionGap,
6065
+ children: [
6066
+ region("before", before),
6067
+ region("syncStatus", syncStatus),
6068
+ region("collection", collection),
6069
+ region("actions", actions),
6070
+ region("undo", undo),
6071
+ region("recovery", recovery),
6072
+ region("children", additionalContent),
6073
+ region("after", after)
6074
+ ]
6075
+ }
6076
+ );
5928
6077
  }
5929
6078
  function resolveSlot(slot, fallback, state) {
5930
6079
  if (slot === void 0) return fallback;