@keepkit/ui 0.25.0 → 0.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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
@@ -3061,7 +3125,7 @@ function KeepUndo({ children, label, ...props }) {
3061
3125
 
3062
3126
  // src/features/collection/KeepCollection.tsx
3063
3127
  import { KeepErrorBoundary as KeepErrorBoundary2 } from "@keepkit/core/react";
3064
- import { useEffect as useEffect10, useState as useState14 } from "react";
3128
+ import { useEffect as useEffect10, useId as useId3, useState as useState14 } from "react";
3065
3129
 
3066
3130
  // src/features/query/KeepActiveFiltersSummary.tsx
3067
3131
  import {
@@ -4151,6 +4215,7 @@ function KeepItemCardRoot({
4151
4215
  linkTargetAttribute,
4152
4216
  linkRel,
4153
4217
  highlightQuery,
4218
+ cardVariant = "outlined",
4154
4219
  className,
4155
4220
  ...rootProps
4156
4221
  }) {
@@ -4292,6 +4357,7 @@ function KeepItemCardRoot({
4292
4357
  "data-state": view.itemState.error ? "error" : view.itemState.isSaved ? "saved" : "unsaved",
4293
4358
  "data-status": item.status ?? "available",
4294
4359
  "data-item-status": view.displayStatus,
4360
+ "data-card-variant": cardVariant !== "outlined" ? cardVariant : void 0,
4295
4361
  "data-loading": view.itemState.isMutating ? "true" : void 0
4296
4362
  },
4297
4363
  linkedBody,
@@ -4778,7 +4844,7 @@ function hasActiveQueryFilters(query) {
4778
4844
  }
4779
4845
 
4780
4846
  // src/features/collection/KeepCollection.tsx
4781
- import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
4847
+ import { Fragment as Fragment11, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
4782
4848
  function KeepCollection(props) {
4783
4849
  const { fallback, onBoundaryError, boundaryResetKey, ...collectionProps } = props;
4784
4850
  const content = /* @__PURE__ */ jsx21(KeepCollectionContent, { ...collectionProps });
@@ -4789,6 +4855,8 @@ function KeepCollectionContent({
4789
4855
  query = {},
4790
4856
  pageSize = 20,
4791
4857
  layout = "list",
4858
+ toolbarVariant = "plain",
4859
+ toolbarLayout = "flat",
4792
4860
  urlSync = false,
4793
4861
  urlAdapter,
4794
4862
  archiveScope,
@@ -4796,6 +4864,7 @@ function KeepCollectionContent({
4796
4864
  reorderable = false,
4797
4865
  onReorder,
4798
4866
  features,
4867
+ slots,
4799
4868
  collectionLabels,
4800
4869
  renderItem,
4801
4870
  itemCardProps,
@@ -4839,6 +4908,59 @@ function KeepCollectionContent({
4839
4908
  showPinButton: itemCardProps?.showPinButton ?? view.enabled.pin,
4840
4909
  showArchiveButton: itemCardProps?.showArchiveButton ?? view.enabled.archive
4841
4910
  };
4911
+ const toolbarId = useId3();
4912
+ const structuredToolbar = toolbarLayout === "grouped" || toolbarVariant === "panel" || slots?.toolbarStart !== void 0 || slots?.toolbarEnd !== void 0;
4913
+ const hasQueryControls = view.enabled.search || view.enabled.sort;
4914
+ const hasFilterControls = view.enabled.tagFilter || view.enabled.collectionFilter || archiveScope !== void 0;
4915
+ const queryControls = hasQueryControls ? /* @__PURE__ */ jsxs18(Fragment11, { children: [
4916
+ view.enabled.search ? /* @__PURE__ */ jsx21(KeepSearchInput, { value: view.searchValue, onValueChange: view.setSearchValue }) : null,
4917
+ view.enabled.sort ? /* @__PURE__ */ jsx21(KeepSortSelect, { value: view.sortValue, onValueChange: view.setSortValue }) : null
4918
+ ] }) : null;
4919
+ const filterControls = hasFilterControls ? /* @__PURE__ */ jsxs18(Fragment11, { children: [
4920
+ view.enabled.tagFilter ? /* @__PURE__ */ jsx21(KeepTagFilter, { query, value: view.activeTags[0], onValueChange: view.setTag }) : null,
4921
+ view.enabled.collectionFilter ? /* @__PURE__ */ jsx21(
4922
+ KeepCollectionFilter,
4923
+ {
4924
+ value: view.activeCollection,
4925
+ onValueChange: view.setCollection,
4926
+ collectionLabels
4927
+ }
4928
+ ) : null,
4929
+ archiveScope !== void 0 ? /* @__PURE__ */ jsx21(
4930
+ KeepArchiveScopeSelect,
4931
+ {
4932
+ value: view.archiveScope,
4933
+ onValueChange: (next) => {
4934
+ view.setArchiveScope(next);
4935
+ onArchiveScopeChange?.(next);
4936
+ }
4937
+ }
4938
+ ) : null
4939
+ ] }) : null;
4940
+ const toolbarStartLabel = useUiLabel("toolbarStart");
4941
+ const toolbarQueryLabel = useUiLabel("toolbarQuery");
4942
+ const toolbarFiltersLabel = useUiLabel("toolbarFilters");
4943
+ const toolbarEndLabel = useUiLabel("toolbarEnd");
4944
+ const toolbarStartContent = slots?.toolbarStart === void 0 ? null : resolveContent(slots.toolbarStart, view.list);
4945
+ const toolbarEndContent = slots?.toolbarEnd === void 0 ? null : resolveContent(slots.toolbarEnd, view.list);
4946
+ const hasToolbarContent = hasQueryControls || hasFilterControls || hasRenderableContent(toolbarStartContent) || hasRenderableContent(toolbarEndContent);
4947
+ const renderToolbarGroup = (group, content, label) => {
4948
+ if (!hasRenderableContent(content)) return null;
4949
+ const labelId = `${toolbarId}-${group}`;
4950
+ return /* @__PURE__ */ jsxs18("fieldset", { "data-keepkit": "collection-toolbar-group", "data-group": group, "aria-labelledby": labelId, children: [
4951
+ /* @__PURE__ */ jsx21("legend", { id: labelId, "data-keepkit": "collection-toolbar-label", children: label }),
4952
+ /* @__PURE__ */ jsx21("div", { "data-keepkit": "collection-toolbar-content", children: content })
4953
+ ] });
4954
+ };
4955
+ const toolbar = !structuredToolbar ? /* @__PURE__ */ jsxs18("div", { children: [
4956
+ queryControls,
4957
+ filterControls
4958
+ ] }) : !hasToolbarContent ? null : /* @__PURE__ */ jsxs18("div", { "data-keepkit": "collection-toolbar", "data-variant": toolbarVariant, "data-layout": toolbarLayout, children: [
4959
+ renderToolbarGroup("toolbarStart", toolbarStartContent, toolbarStartLabel),
4960
+ renderToolbarGroup("query", queryControls, toolbarQueryLabel),
4961
+ renderToolbarGroup("filters", filterControls, toolbarFiltersLabel),
4962
+ renderToolbarGroup("toolbarEnd", toolbarEndContent, toolbarEndLabel)
4963
+ ] });
4842
4964
  return /* @__PURE__ */ jsxs18(
4843
4965
  "section",
4844
4966
  {
@@ -4846,33 +4968,13 @@ function KeepCollectionContent({
4846
4968
  className,
4847
4969
  "data-keepkit": "collection",
4848
4970
  "data-layout": layout,
4971
+ "data-toolbar-variant": toolbarVariant !== "plain" ? toolbarVariant : void 0,
4972
+ "data-toolbar-layout": toolbarLayout !== "flat" ? toolbarLayout : void 0,
4849
4973
  "aria-busy": view.list.isLoading || view.list.isMutating || rootProps["aria-busy"],
4850
4974
  "data-state": getCollectionState(view.list),
4851
4975
  "data-loading": view.list.isLoading || view.list.isMutating ? "true" : void 0,
4852
4976
  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
- ] }),
4977
+ toolbar,
4876
4978
  activeFilters === void 0 ? /* @__PURE__ */ jsx21(
4877
4979
  KeepActiveFiltersSummary,
4878
4980
  {
@@ -4921,6 +5023,9 @@ function getCollectionState(list) {
4921
5023
  if (list.isHydrated && list.items.length === 0) return "empty";
4922
5024
  return "ready";
4923
5025
  }
5026
+ function hasRenderableContent(content) {
5027
+ return content !== null && content !== void 0 && content !== false && content !== true && content !== "";
5028
+ }
4924
5029
 
4925
5030
  // src/features/collection/KeepLayout.tsx
4926
5031
  import { jsx as jsx22 } from "react/jsx-runtime";
@@ -5027,7 +5132,7 @@ function useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError }) {
5027
5132
  }
5028
5133
 
5029
5134
  // src/features/editor/KeepNoteEditor.tsx
5030
- import { Fragment as Fragment11, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
5135
+ import { Fragment as Fragment12, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
5031
5136
  function KeepNoteEditor({
5032
5137
  item,
5033
5138
  label,
@@ -5046,7 +5151,7 @@ function KeepNoteEditor({
5046
5151
  const view = useKeepNoteEditor({ item, debounceMs, onSaved, onSaveError });
5047
5152
  const { error, isDirty, isSaving, note, setNote } = view.state;
5048
5153
  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: [
5154
+ const body = render ? render(view.state) : typeof contentChildren === "function" ? contentChildren(view.state) : contentChildren ?? /* @__PURE__ */ jsxs20(Fragment12, { children: [
5050
5155
  /* @__PURE__ */ jsxs20("label", { children: [
5051
5156
  label ?? view.labels.note,
5052
5157
  /* @__PURE__ */ jsx24(
@@ -5160,7 +5265,7 @@ function useKeepTagEditor({ item, onSaved, onSaveError }) {
5160
5265
  }
5161
5266
 
5162
5267
  // src/features/editor/KeepTagEditor.tsx
5163
- import { Fragment as Fragment12, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
5268
+ import { Fragment as Fragment13, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
5164
5269
  function KeepTagEditor({
5165
5270
  item,
5166
5271
  availableTags = [],
@@ -5171,7 +5276,7 @@ function KeepTagEditor({
5171
5276
  }) {
5172
5277
  const view = useKeepTagEditor({ item, onSaved, onSaveError });
5173
5278
  const { isSaving, tags } = view.state;
5174
- const body = render ? render(view.state) : /* @__PURE__ */ jsxs21(Fragment12, { children: [
5279
+ const body = render ? render(view.state) : /* @__PURE__ */ jsxs21(Fragment13, { children: [
5175
5280
  /* @__PURE__ */ jsxs21("label", { children: [
5176
5281
  view.labels.tags,
5177
5282
  /* @__PURE__ */ jsx25(
@@ -5235,7 +5340,7 @@ function useKeepToastFeedback(showToast) {
5235
5340
 
5236
5341
  // src/features/navigation/KeepTourBar.tsx
5237
5342
  import { useKeepNavigator } from "@keepkit/core/react";
5238
- import { useId as useId3 } from "react";
5343
+ import { useId as useId4 } from "react";
5239
5344
 
5240
5345
  // src/features/navigation/hooks/useKeepTourShortcuts.ts
5241
5346
  import { useEffect as useEffect13 } from "react";
@@ -5270,7 +5375,7 @@ function isEditableTarget(target) {
5270
5375
  }
5271
5376
 
5272
5377
  // src/features/navigation/KeepTourBar.tsx
5273
- import { Fragment as Fragment13, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
5378
+ import { Fragment as Fragment14, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
5274
5379
  function KeepTourBar({
5275
5380
  navigation: providedNavigation,
5276
5381
  currentId,
@@ -5340,7 +5445,7 @@ function KeepTourBar({
5340
5445
  return resolvedPrev();
5341
5446
  }
5342
5447
  });
5343
- const body = /* @__PURE__ */ jsxs22(Fragment13, { children: [
5448
+ const body = /* @__PURE__ */ jsxs22(Fragment14, { children: [
5344
5449
  showProgress ? /* @__PURE__ */ jsx26("span", { "data-keepkit": "tour-progress", "aria-live": "polite", children: progress ?? `${navigation.currentPosition ?? 0} / ${navigation.items.length}` }) : null,
5345
5450
  /* @__PURE__ */ jsx26(
5346
5451
  TourAction,
@@ -5350,7 +5455,7 @@ function KeepTourBar({
5350
5455
  onClick: resolvedPrevHref ? notifyPrevNavigation : resolvedPrev,
5351
5456
  "data-keep-action": "tour-prev",
5352
5457
  shortcut: showShortcutHint ? shortcutOptions?.prevKeys?.[0] ?? "K" : void 0,
5353
- preview: navigation.prevItem ? /* @__PURE__ */ jsxs22(Fragment13, { children: [
5458
+ preview: navigation.prevItem ? /* @__PURE__ */ jsxs22(Fragment14, { children: [
5354
5459
  previousLabel,
5355
5460
  ": ",
5356
5461
  getItemTitle(navigation.prevItem)
@@ -5366,7 +5471,7 @@ function KeepTourBar({
5366
5471
  onClick: resolvedNextHref ? notifyNextNavigation : resolvedNext,
5367
5472
  "data-keep-action": "tour-next",
5368
5473
  shortcut: showShortcutHint ? shortcutOptions?.nextKeys?.[0] ?? "J" : void 0,
5369
- preview: navigation.nextItem ? /* @__PURE__ */ jsxs22(Fragment13, { children: [
5474
+ preview: navigation.nextItem ? /* @__PURE__ */ jsxs22(Fragment14, { children: [
5370
5475
  nextItemLabel,
5371
5476
  ": ",
5372
5477
  getItemTitle(navigation.nextItem)
@@ -5385,8 +5490,8 @@ function KeepTourBar({
5385
5490
  );
5386
5491
  }
5387
5492
  function TourAction({ href, disabled = false, onClick, children, preview, shortcut, ...props }) {
5388
- const previewId = useId3();
5389
- const content = /* @__PURE__ */ jsxs22(Fragment13, { children: [
5493
+ const previewId = useId4();
5494
+ const content = /* @__PURE__ */ jsxs22(Fragment14, { children: [
5390
5495
  /* @__PURE__ */ jsx26("span", { "data-tour-label": "true", children }),
5391
5496
  shortcut ? /* @__PURE__ */ jsx26(KeepShortcutHint, { shortcut }) : null,
5392
5497
  preview ? /* @__PURE__ */ jsx26("small", { id: previewId, "data-tour-preview": "true", children: preview }) : null
@@ -5865,6 +5970,8 @@ import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
5865
5970
  function KeepWorkspace({
5866
5971
  preset = "standard",
5867
5972
  modules,
5973
+ surface,
5974
+ sectionGap,
5868
5975
  collectionProps,
5869
5976
  syncStatusProps,
5870
5977
  recoveryProps,
@@ -5893,38 +6000,64 @@ function KeepWorkspace({
5893
6000
  ...collectionProps,
5894
6001
  features: { ...view.collectionFeatures, ...collectionProps?.features }
5895
6002
  };
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
- ] });
6003
+ const structuredRegions = surface !== void 0 && surface !== "plain";
6004
+ const region = (name, content) => {
6005
+ if (!structuredRegions) return content;
6006
+ if (content === null || content === void 0 || content === false) return null;
6007
+ const resolvedSurface = typeof surface === "string" ? surface : surface[name] ?? "plain";
6008
+ return /* @__PURE__ */ jsx30("div", { "data-keepkit": "workspace-region", "data-region": name, "data-surface": resolvedSurface, children: content });
6009
+ };
6010
+ const before = resolveOptionalSlot(slots?.before, state);
6011
+ const syncStatus = view.modules.syncStatus ? resolveSlot(
6012
+ slots?.syncStatus,
6013
+ /* @__PURE__ */ jsx30(KeepSyncStatusBanner, { ...syncStatusProps, onResolveConflicts: view.openRecovery }),
6014
+ state
6015
+ ) : null;
6016
+ const collection = resolveSlot(slots?.collection, /* @__PURE__ */ jsx30(KeepCollection, { ...resolvedCollectionProps }), state);
6017
+ const actions = view.modules.backup || view.modules.stalePrune ? resolveSlot(
6018
+ slots?.actions,
6019
+ /* @__PURE__ */ jsxs25("div", { "data-keepkit": "workspace-actions", children: [
6020
+ view.modules.stalePrune ? /* @__PURE__ */ jsx30(KeepPruneStaleButton, { ...stalePruneProps }) : null,
6021
+ view.modules.backup ? /* @__PURE__ */ jsx30(KeepBackup, { ...backupProps }) : null
6022
+ ] }),
6023
+ state
6024
+ ) : null;
6025
+ const undo = view.modules.undo ? resolveSlot(slots?.undo, /* @__PURE__ */ jsx30(KeepUndo, { ...undoProps }), state) : null;
6026
+ const recovery = view.modules.recovery ? resolveSlot(
6027
+ slots?.recovery,
6028
+ /* @__PURE__ */ jsx30(
6029
+ KeepSyncRecoveryDialog,
6030
+ {
6031
+ ...recoveryProps,
6032
+ open: view.recoveryOpen,
6033
+ onOpenChange: view.setRecoveryOpen
6034
+ }
6035
+ ),
6036
+ state
6037
+ ) : null;
6038
+ const additionalContent = resolveOptionalSlot(children, state);
6039
+ const after = resolveOptionalSlot(slots?.after, state);
6040
+ return /* @__PURE__ */ jsxs25(
6041
+ "section",
6042
+ {
6043
+ ...props,
6044
+ className,
6045
+ "data-keepkit": "workspace",
6046
+ "data-preset": preset,
6047
+ "data-surface": surface !== void 0 ? typeof surface === "string" ? surface : "custom" : void 0,
6048
+ "data-section-gap": sectionGap,
6049
+ children: [
6050
+ region("before", before),
6051
+ region("syncStatus", syncStatus),
6052
+ region("collection", collection),
6053
+ region("actions", actions),
6054
+ region("undo", undo),
6055
+ region("recovery", recovery),
6056
+ region("children", additionalContent),
6057
+ region("after", after)
6058
+ ]
6059
+ }
6060
+ );
5928
6061
  }
5929
6062
  function resolveSlot(slot, fallback, state) {
5930
6063
  if (slot === void 0) return fallback;