@k2b/ui 0.22.0 → 0.24.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.
Files changed (117) hide show
  1. package/dist/browser/content/Calendar.js +1122 -1065
  2. package/dist/browser/content/Calendar.js.map +1 -1
  3. package/dist/browser/content/CalendarDayView.js +1187 -0
  4. package/dist/browser/content/CalendarDayView.js.map +1 -0
  5. package/dist/browser/content/CalendarWeekView.js +1593 -0
  6. package/dist/browser/content/CalendarWeekView.js.map +1 -0
  7. package/dist/browser/content/ChartExplorer.js +174 -82
  8. package/dist/browser/content/ChartExplorer.js.map +1 -1
  9. package/dist/browser/content/ChartFilterControls.js +90 -33
  10. package/dist/browser/content/ChartFilterControls.js.map +1 -1
  11. package/dist/browser/content/DataTable.js +235 -197
  12. package/dist/browser/content/DataTable.js.map +1 -1
  13. package/dist/browser/content/calendar-day-scroll.js +111 -0
  14. package/dist/browser/content/calendar-day-scroll.js.map +1 -0
  15. package/dist/browser/content/calendar-days.js +408 -0
  16. package/dist/browser/content/calendar-days.js.map +1 -0
  17. package/dist/browser/content/calendar-dialogs.js +236 -0
  18. package/dist/browser/content/calendar-dialogs.js.map +1 -0
  19. package/dist/browser/content/calendar-messages.js +210 -2
  20. package/dist/browser/content/calendar-messages.js.map +1 -1
  21. package/dist/browser/content/calendar-pointer.js +15 -3
  22. package/dist/browser/content/calendar-pointer.js.map +1 -1
  23. package/dist/browser/content/calendar-shared.js +328 -0
  24. package/dist/browser/content/calendar-shared.js.map +1 -0
  25. package/dist/browser/content/calendar-time-view.js +1654 -0
  26. package/dist/browser/content/calendar-time-view.js.map +1 -0
  27. package/dist/browser/content/chart-messages.js +10 -0
  28. package/dist/browser/content/chart-messages.js.map +1 -1
  29. package/dist/browser/content/index.js.map +1 -1
  30. package/dist/browser/inputs/Combobox.js +0 -1
  31. package/dist/browser/inputs/Combobox.js.map +1 -1
  32. package/dist/browser/layout/AppWorkspace.js +125 -97
  33. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  34. package/dist/browser/layout/Navigation.js +18 -3
  35. package/dist/browser/layout/Navigation.js.map +1 -1
  36. package/dist/browser/layout/PageTitle.js +18 -1
  37. package/dist/browser/layout/PageTitle.js.map +1 -1
  38. package/dist/browser/layout/SidebarSwitcher.js +505 -0
  39. package/dist/browser/layout/SidebarSwitcher.js.map +1 -0
  40. package/dist/browser/layout/app-workspace-controller.js +174 -86
  41. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  42. package/dist/browser/layout/index.js +1 -0
  43. package/dist/browser/layout/index.js.map +1 -1
  44. package/dist/browser/layout/navigation-model.js +1 -0
  45. package/dist/browser/layout/navigation-model.js.map +1 -1
  46. package/dist/browser/surfaces/StatCell.js +18 -6
  47. package/dist/browser/surfaces/StatCell.js.map +1 -1
  48. package/dist/ssr/content/Calendar.js +553 -341
  49. package/dist/ssr/content/Calendar.js.map +1 -1
  50. package/dist/ssr/content/CalendarDayView.js +800 -0
  51. package/dist/ssr/content/CalendarDayView.js.map +1 -0
  52. package/dist/ssr/content/CalendarWeekView.js +1090 -0
  53. package/dist/ssr/content/CalendarWeekView.js.map +1 -0
  54. package/dist/ssr/content/ChartExplorer.js +93 -34
  55. package/dist/ssr/content/ChartExplorer.js.map +1 -1
  56. package/dist/ssr/content/ChartFilterControls.js +49 -7
  57. package/dist/ssr/content/ChartFilterControls.js.map +1 -1
  58. package/dist/ssr/content/DataTable.js +88 -66
  59. package/dist/ssr/content/DataTable.js.map +1 -1
  60. package/dist/ssr/content/calendar-day-scroll.js +111 -0
  61. package/dist/ssr/content/calendar-day-scroll.js.map +1 -0
  62. package/dist/ssr/content/calendar-days.js +408 -0
  63. package/dist/ssr/content/calendar-days.js.map +1 -0
  64. package/dist/ssr/content/calendar-dialogs.js +159 -0
  65. package/dist/ssr/content/calendar-dialogs.js.map +1 -0
  66. package/dist/ssr/content/calendar-messages.js +210 -2
  67. package/dist/ssr/content/calendar-messages.js.map +1 -1
  68. package/dist/ssr/content/calendar-pointer.js +15 -3
  69. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  70. package/dist/ssr/content/calendar-shared.js +261 -0
  71. package/dist/ssr/content/calendar-shared.js.map +1 -0
  72. package/dist/ssr/content/calendar-time-view.js +1311 -0
  73. package/dist/ssr/content/calendar-time-view.js.map +1 -0
  74. package/dist/ssr/content/chart-messages.js +10 -0
  75. package/dist/ssr/content/chart-messages.js.map +1 -1
  76. package/dist/ssr/content/index.js.map +1 -1
  77. package/dist/ssr/inputs/Combobox.js.map +1 -1
  78. package/dist/ssr/layout/AppWorkspace.js +40 -29
  79. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  80. package/dist/ssr/layout/Navigation.js +12 -2
  81. package/dist/ssr/layout/Navigation.js.map +1 -1
  82. package/dist/ssr/layout/PageTitle.js +18 -1
  83. package/dist/ssr/layout/PageTitle.js.map +1 -1
  84. package/dist/ssr/layout/SidebarSwitcher.js +271 -0
  85. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -0
  86. package/dist/ssr/layout/app-workspace-controller.js +174 -86
  87. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  88. package/dist/ssr/layout/index.js +1 -0
  89. package/dist/ssr/layout/index.js.map +1 -1
  90. package/dist/ssr/layout/navigation-model.js +1 -0
  91. package/dist/ssr/layout/navigation-model.js.map +1 -1
  92. package/dist/ssr/surfaces/StatCell.js +2 -2
  93. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  94. package/dist/styles.css +1 -1
  95. package/dist/types/content/Calendar.d.ts +95 -1
  96. package/dist/types/content/CalendarDayView.d.ts +7 -0
  97. package/dist/types/content/CalendarWeekView.d.ts +7 -0
  98. package/dist/types/content/ChartExplorer.d.ts +36 -1
  99. package/dist/types/content/ChartFilterControls.d.ts +6 -1
  100. package/dist/types/content/DataTable.d.ts +14 -0
  101. package/dist/types/content/calendar-day-scroll.d.ts +47 -0
  102. package/dist/types/content/calendar-days.d.ts +192 -0
  103. package/dist/types/content/calendar-dialogs.d.ts +22 -0
  104. package/dist/types/content/calendar-messages.d.ts +99 -0
  105. package/dist/types/content/calendar-pointer.d.ts +9 -0
  106. package/dist/types/content/calendar-shared.d.ts +69 -0
  107. package/dist/types/content/calendar-time-view.d.ts +252 -0
  108. package/dist/types/content/chart-messages.d.ts +5 -0
  109. package/dist/types/content/index.d.ts +2 -2
  110. package/dist/types/layout/AppWorkspace.d.ts +27 -3
  111. package/dist/types/layout/PageTitle.d.ts +2 -1
  112. package/dist/types/layout/SidebarSwitcher.d.ts +65 -0
  113. package/dist/types/layout/app-workspace-controller.d.ts +9 -1
  114. package/dist/types/layout/index.d.ts +1 -0
  115. package/dist/types/layout/navigation-model.d.ts +4 -0
  116. package/dist/types/surfaces/StatCell.d.ts +5 -0
  117. package/package.json +3 -3
@@ -63,14 +63,17 @@ var _tmpl$ = /*#__PURE__*/_$template(`<button type=button class=k2b-app-workspac
63
63
  _tmpl$43 = /*#__PURE__*/_$template(`<i aria-hidden=true>`),
64
64
  _tmpl$44 = /*#__PURE__*/_$template(`<i class="ti ti-layout-sidebar"aria-hidden=true>`),
65
65
  _tmpl$45 = /*#__PURE__*/_$template(`<div class=k2b-app-workspace__head><!$><!/><!$><!/>`),
66
- _tmpl$46 = /*#__PURE__*/_$template(`<div data-k2b-app-workspace><!$><!/><!$><!/>`);
66
+ _tmpl$46 = /*#__PURE__*/_$template(`<h1 class=k2b-app-workspace__head-heading data-k2b-page-trail-title>`),
67
+ _tmpl$47 = /*#__PURE__*/_$template(`<div data-k2b-app-workspace><!$><!/><!$><!/>`);
67
68
  import { Link } from "@k2b/ssr/nav";
68
69
  import { children, createContext, createEffect, createMemo, createSignal, createUniqueId, For, mergeProps, onCleanup, onMount, Show, useContext } from "solid-js";
70
+ import { isServer } from "solid-js/web";
69
71
  import { IconButton } from "../actions/Button";
70
72
  import { APP_WORKSPACE_DETAIL_CLOSE_EVENT, APP_WORKSPACE_DETAIL_STEP_EVENT, APP_WORKSPACE_SIDEBAR_HIDE_EVENT, installAppWorkspaceController } from "./app-workspace-controller";
71
73
  import { APP_WORKSPACE_DETAIL_DEFAULT, APP_WORKSPACE_DETAIL_MAX, APP_WORKSPACE_DETAIL_MIN, APP_WORKSPACE_DRAWER_DEFAULT, APP_WORKSPACE_DRAWER_MAX, APP_WORKSPACE_DRAWER_MIN, APP_WORKSPACE_PANE_DEFAULT, APP_WORKSPACE_PANE_MAX, APP_WORKSPACE_PANE_MIN, APP_WORKSPACE_SIDEBAR_COLLAPSED, APP_WORKSPACE_SIDEBAR_DEFAULT, APP_WORKSPACE_SIDEBAR_MAX, APP_WORKSPACE_SIDEBAR_MIN, appWorkspaceLayoutStyle, appWorkspacePanelVariable } from "./app-workspace-state";
72
74
  import { PageTitle, usePageTrail } from "./PageTitle";
73
75
  import { SidebarItemPreview } from "./SidebarItemPreview";
76
+ import { AppWorkspaceSidebarSwitcher } from "./SidebarSwitcher";
74
77
  import { createScrollFade } from "./scroll-fade";
75
78
  import { assertStableUiId, assertUniqueStableUiIds } from "./stable-id";
76
79
  import { useWorkspaceMessages } from "./workspace-messages";
@@ -398,20 +401,22 @@ function AppWorkspaceDetail(props) {
398
401
  "--k2b-workspace-panel-min": `${minWidth()}px`,
399
402
  "--k2b-workspace-panel-max": `${maxWidth()}px`
400
403
  });
401
- // The panel floats over the content area, and `Main` beside it makes room
402
- // in CSS alone, so a server-rendered page arrives in its final geometry. A
403
- // sibling cannot read the panel's own variables, so this rule hands the
404
- // open panel's size to the content area around it.
405
- const contentRule = () => {
404
+ // An open panel takes a column at the workspace's end, sized in CSS alone,
405
+ // so a server-rendered page arrives in its final geometry. The workspace
406
+ // cannot read the panel's own variables, so this rule hands the open
407
+ // panel's size to its workspace.
408
+ const workspaceRule = () => {
406
409
  const open = `#${domId()}:not([hidden])`;
407
- return `.k2b-app-workspace__content:has(> ${open}, > :is(solid-island, solid-client) > ${open}){--k2b-detail-size:${size()};--k2b-detail-min:${minWidth()}px;--k2b-detail-max:${maxWidth()}px}`;
410
+ return `.k2b-app-workspace:has(> .k2b-app-workspace__content > ${open}, > .k2b-app-workspace__content > :is(solid-island, solid-client) > ${open}){--k2b-detail-size:${size()};--k2b-detail-min:${minWidth()}px;--k2b-detail-max:${maxWidth()}px}`;
408
411
  };
409
412
  let aside;
410
413
  onMount(() => {
411
414
  const close = () => props.onClose?.();
415
+ const isStep = detail => typeof detail === "object" && detail !== null && "direction" in detail && (detail.direction === 1 || detail.direction === -1);
412
416
  const step = event => {
413
- const direction = event instanceof CustomEvent ? event.detail?.direction : undefined;
414
- if (direction === 1 || direction === -1) props.onStep?.(direction);
417
+ if (!(event instanceof CustomEvent) || !isStep(event.detail)) return;
418
+ const item = props.onStep?.(event.detail.direction);
419
+ if (item instanceof HTMLElement) event.detail.item = item;
415
420
  };
416
421
  aside?.addEventListener(APP_WORKSPACE_DETAIL_CLOSE_EVENT, close);
417
422
  aside?.addEventListener(APP_WORKSPACE_DETAIL_STEP_EVENT, step);
@@ -422,7 +427,7 @@ function AppWorkspaceDetail(props) {
422
427
  });
423
428
  return [(() => {
424
429
  var _el$5 = _$getNextElement(_tmpl$5);
425
- _$effect(() => _$setProperty(_el$5, "innerHTML", contentRule()));
430
+ _$effect(() => _$setProperty(_el$5, "innerHTML", workspaceRule()));
426
431
  return _el$5;
427
432
  })(), _$createComponent(Show, {
428
433
  get when() {
@@ -682,11 +687,12 @@ const AppWorkspaceSidebarDesktop = props => ({
682
687
  // hydrates. Islands load asynchronously and server-only sidebars never mount,
683
688
  // so `onMount` would be too late or never run. The memory is one
684
689
  // `sessionStorage` entry per path segment and sidebar position and ends with
685
- // the tab. A stored offset is applied first; the current item is then kept in
686
- // view, which is a no-op when the offset already shows it. The frame callback
690
+ // the tab. A stored offset is applied first; the current item, or on a deeper
691
+ // page the item that contains it, is then kept in view, which is a no-op when
692
+ // the offset already shows it. The frame callback
687
693
  // repeats the restore once the whole document is parsed, because content that
688
694
  // follows the sidebar can still change its height before the first paint.
689
- const SIDEBAR_SCROLL_MEMORY_SCRIPT = ["(function(){", "var body=document.currentScript&&document.currentScript.previousElementSibling;if(!body)return;", "var storage;try{storage=window.sessionStorage}catch(_){return}", 'var key="k2b-sidebar-scroll:"+location.pathname.split("/")[1]+":"+document.querySelectorAll(".k2b-app-workspace__sidebar-body").length;', "var restore=function(){", "var stored=storage.getItem(key);if(stored!==null)body.scrollTop=Number(stored);", 'var current=body.querySelector(\'[aria-current="page"]\');if(current)current.scrollIntoView({block:"nearest"});', "};", "restore();requestAnimationFrame(restore);", "var frame=0;", 'body.addEventListener("scroll",function(){if(frame)return;frame=requestAnimationFrame(function(){frame=0;try{storage.setItem(key,String(body.scrollTop))}catch(_){}})},{passive:true});', "})();"].join("");
695
+ const SIDEBAR_SCROLL_MEMORY_SCRIPT = ["(function(){", "var body=document.currentScript&&document.currentScript.previousElementSibling;if(!body)return;", "var storage;try{storage=window.sessionStorage}catch(_){return}", 'var key="k2b-sidebar-scroll:"+location.pathname.split("/")[1]+":"+document.querySelectorAll(".k2b-app-workspace__sidebar-body").length;', "var restore=function(){", "var stored=storage.getItem(key);if(stored!==null)body.scrollTop=Number(stored);", 'var current=body.querySelector(\'[aria-current="page"]\')||body.querySelector(\'[aria-current="true"]\');if(current)current.scrollIntoView({block:"nearest"});', "};", "restore();requestAnimationFrame(restore);", "var frame=0;", 'body.addEventListener("scroll",function(){if(frame)return;frame=requestAnimationFrame(function(){frame=0;try{storage.setItem(key,String(body.scrollTop))}catch(_){}})},{passive:true});', "})();"].join("");
690
696
  const AppWorkspaceSidebarBody = props => {
691
697
  let body;
692
698
  createScrollFade(() => body, () => props.scrollFade !== false);
@@ -851,11 +857,12 @@ const AppWorkspaceSidebarItemActions = props => (() => {
851
857
  })();
852
858
  const AppWorkspaceSidebarItemStatus = props => {
853
859
  const workspaceMessages = useWorkspaceMessages();
854
- const count = () => typeof props.unread === "number" && props.unread >= 1 ? Math.floor(props.unread) : 0;
855
- const dot = () => props.unread === true;
860
+ const waiting = () => props.waiting && Number.isFinite(props.waiting.count) ? Math.max(0, Math.floor(props.waiting.count)) : null;
861
+ const count = () => waiting() ?? (typeof props.unread === "number" && props.unread >= 1 ? Math.floor(props.unread) : 0);
862
+ const dot = () => waiting() === null && props.unread === true;
856
863
  // The marks are decorative; the row's accessible name gets one phrase instead,
857
864
  // which says no more than the "99+" a capped count shows.
858
- const description = () => [count() > 99 ? workspaceMessages().sidebarUnreadMany : count() ? workspaceMessages().sidebarUnread({
865
+ const description = () => [waiting() !== null ? props.waiting?.label ?? "" : count() > 99 ? workspaceMessages().sidebarUnreadMany : count() ? workspaceMessages().sidebarUnread({
859
866
  count: count()
860
867
  }) : dot() ? workspaceMessages().sidebarNewActivity : "", props.mention ? workspaceMessages().sidebarMentioned : "", props.muted ? workspaceMessages().sidebarMuted : ""].filter(Boolean).join(", ");
861
868
  // The unread slot stays reserved at the end, and the marks that change most
@@ -893,7 +900,7 @@ const AppWorkspaceSidebarItemStatus = props => {
893
900
  }), _el$45, _co$8);
894
901
  _$insert(_el$36, _$createComponent(Show, {
895
902
  get when() {
896
- return count();
903
+ return count() || waiting() === 0;
897
904
  },
898
905
  get fallback() {
899
906
  return _$createComponent(Show, {
@@ -916,7 +923,16 @@ const AppWorkspaceSidebarItemStatus = props => {
916
923
  }
917
924
  }));
918
925
  _$insert(_el$38, description, _el$41, _co$6);
919
- _$effect(() => _$setAttribute(_el$33, "data-unread", count() ? "count" : dot() ? "dot" : undefined));
926
+ _$effect(_p$ => {
927
+ var _v$51 = waiting() !== null ? undefined : count() ? "count" : dot() ? "dot" : undefined,
928
+ _v$52 = waiting() === null ? undefined : waiting() ? "count" : "zero";
929
+ _v$51 !== _p$.e && _$setAttribute(_el$33, "data-unread", _p$.e = _v$51);
930
+ _v$52 !== _p$.t && _$setAttribute(_el$33, "data-waiting", _p$.t = _v$52);
931
+ return _p$;
932
+ }, {
933
+ e: undefined,
934
+ t: undefined
935
+ });
920
936
  return _el$33;
921
937
  }
922
938
  });
@@ -935,7 +951,7 @@ function AppWorkspaceSidebarRow(props) {
935
951
  },
936
952
  ...data()
937
953
  });
938
- const current = () => props.active ? "page" : undefined;
954
+ const current = () => props.active === "ancestor" ? "true" : props.active ? "page" : undefined;
939
955
  const Control = control => {
940
956
  const attrs = () => control.grouped ? {
941
957
  class: "k2b-app-workspace__sidebar-item-main"
@@ -1141,10 +1157,10 @@ function AppWorkspaceSidebarItem(props) {
1141
1157
  var _el$68 = _$getNextElement(_tmpl$30);
1142
1158
  _$insert(_el$68, meta);
1143
1159
  _$effect(_p$ => {
1144
- var _v$51 = props.preview?.trigger === "row" ? metaId : undefined,
1145
- _v$52 = metaVisibility() === "hover" ? "hover" : undefined;
1146
- _v$51 !== _p$.e && _$setAttribute(_el$68, "id", _p$.e = _v$51);
1147
- _v$52 !== _p$.t && _$setAttribute(_el$68, "data-visibility", _p$.t = _v$52);
1160
+ var _v$53 = props.preview?.trigger === "row" ? metaId : undefined,
1161
+ _v$54 = metaVisibility() === "hover" ? "hover" : undefined;
1162
+ _v$53 !== _p$.e && _$setAttribute(_el$68, "id", _p$.e = _v$53);
1163
+ _v$54 !== _p$.t && _$setAttribute(_el$68, "data-visibility", _p$.t = _v$54);
1148
1164
  return _p$;
1149
1165
  }, {
1150
1166
  e: undefined,
@@ -1185,12 +1201,12 @@ function AppWorkspaceSidebarItem(props) {
1185
1201
  _el$72.$$click = select;
1186
1202
  _$insert(_el$72, content);
1187
1203
  _$effect(_p$ => {
1188
- var _v$56 = actionSlot()?.disabled,
1189
- _v$57 = actionSlot()?.visibility === "hover" ? "hover" : undefined,
1190
- _v$58 = label();
1191
- _v$56 !== _p$.e && _$setProperty(_el$72, "disabled", _p$.e = _v$56);
1192
- _v$57 !== _p$.t && _$setAttribute(_el$72, "data-visibility", _p$.t = _v$57);
1193
- _v$58 !== _p$.a && _$setAttribute(_el$72, "aria-label", _p$.a = _v$58);
1204
+ var _v$58 = actionSlot()?.disabled,
1205
+ _v$59 = actionSlot()?.visibility === "hover" ? "hover" : undefined,
1206
+ _v$60 = label();
1207
+ _v$58 !== _p$.e && _$setProperty(_el$72, "disabled", _p$.e = _v$58);
1208
+ _v$59 !== _p$.t && _$setAttribute(_el$72, "data-visibility", _p$.t = _v$59);
1209
+ _v$60 !== _p$.a && _$setAttribute(_el$72, "aria-label", _p$.a = _v$60);
1194
1210
  return _p$;
1195
1211
  }, {
1196
1212
  e: undefined,
@@ -1206,12 +1222,12 @@ function AppWorkspaceSidebarItem(props) {
1206
1222
  _el$71.$$click = select;
1207
1223
  _$insert(_el$71, content);
1208
1224
  _$effect(_p$ => {
1209
- var _v$53 = actionSlot()?.href,
1210
- _v$54 = actionSlot()?.visibility === "hover" ? "hover" : undefined,
1211
- _v$55 = label();
1212
- _v$53 !== _p$.e && _$setAttribute(_el$71, "href", _p$.e = _v$53);
1213
- _v$54 !== _p$.t && _$setAttribute(_el$71, "data-visibility", _p$.t = _v$54);
1214
- _v$55 !== _p$.a && _$setAttribute(_el$71, "aria-label", _p$.a = _v$55);
1225
+ var _v$55 = actionSlot()?.href,
1226
+ _v$56 = actionSlot()?.visibility === "hover" ? "hover" : undefined,
1227
+ _v$57 = label();
1228
+ _v$55 !== _p$.e && _$setAttribute(_el$71, "href", _p$.e = _v$55);
1229
+ _v$56 !== _p$.t && _$setAttribute(_el$71, "data-visibility", _p$.t = _v$56);
1230
+ _v$57 !== _p$.a && _$setAttribute(_el$71, "aria-label", _p$.a = _v$57);
1215
1231
  return _p$;
1216
1232
  }, {
1217
1233
  e: undefined,
@@ -1560,10 +1576,10 @@ const AppWorkspaceNavTree = props => {
1560
1576
  var _el$79 = _$getNextElement(_tmpl$36);
1561
1577
  _$insert(_el$79, () => item.meta);
1562
1578
  _$effect(_p$ => {
1563
- var _v$59 = `k2b-app-workspace__sidebar-item-meta ${hasChildren() ? "" : "k2b-app-workspace__nav-tree-leaf-meta"}`,
1564
- _v$60 = item.metaVisibility === "hover" ? "hover" : undefined;
1565
- _v$59 !== _p$.e && _$className(_el$79, _p$.e = _v$59);
1566
- _v$60 !== _p$.t && _$setAttribute(_el$79, "data-visibility", _p$.t = _v$60);
1579
+ var _v$61 = `k2b-app-workspace__sidebar-item-meta ${hasChildren() ? "" : "k2b-app-workspace__nav-tree-leaf-meta"}`,
1580
+ _v$62 = item.metaVisibility === "hover" ? "hover" : undefined;
1581
+ _v$61 !== _p$.e && _$className(_el$79, _p$.e = _v$61);
1582
+ _v$62 !== _p$.t && _$setAttribute(_el$79, "data-visibility", _p$.t = _v$62);
1567
1583
  return _p$;
1568
1584
  }, {
1569
1585
  e: undefined,
@@ -1715,28 +1731,28 @@ const AppWorkspaceNavTree = props => {
1715
1731
  }
1716
1732
  }), _el$89, _co$13);
1717
1733
  _$effect(_p$ => {
1718
- var _v$61 = siblings().length,
1719
- _v$62 = place() + 1,
1720
- _v$63 = selected(),
1721
- _v$64 = hasChildren() ? isExpanded(item.id) : undefined,
1722
- _v$65 = item.disabled ? "true" : undefined,
1723
- _v$66 = item.disabled ? -1 : tabStopId() === item.id ? 0 : -1,
1724
- _v$67 = movable() ? true : undefined,
1725
- _v$68 = item.id,
1726
- _v$69 = dragged()?.id === item.id ? "" : undefined,
1727
- _v$70 = dropTarget()?.id === item.id ? dropTarget().side : undefined,
1728
- _v$71 = String(props.indented === false ? 0 : depth);
1729
- _v$61 !== _p$.e && _$setAttribute(_el$84, "aria-setsize", _p$.e = _v$61);
1730
- _v$62 !== _p$.t && _$setAttribute(_el$84, "aria-posinset", _p$.t = _v$62);
1731
- _v$63 !== _p$.a && _$setAttribute(_el$84, "aria-selected", _p$.a = _v$63);
1732
- _v$64 !== _p$.o && _$setAttribute(_el$84, "aria-expanded", _p$.o = _v$64);
1733
- _v$65 !== _p$.i && _$setAttribute(_el$84, "aria-disabled", _p$.i = _v$65);
1734
- _v$66 !== _p$.n && _$setAttribute(_el$84, "tabindex", _p$.n = _v$66);
1735
- _v$67 !== _p$.s && _$setAttribute(_el$84, "draggable", _p$.s = _v$67);
1736
- _v$68 !== _p$.h && _$setAttribute(_el$84, "data-k2b-nav-tree-id", _p$.h = _v$68);
1737
- _v$69 !== _p$.r && _$setAttribute(_el$84, "data-k2b-nav-tree-dragging", _p$.r = _v$69);
1738
- _v$70 !== _p$.d && _$setAttribute(_el$84, "data-k2b-nav-tree-drop", _p$.d = _v$70);
1739
- _v$71 !== _p$.l && _$setStyleProperty(_el$84, "--k2b-nav-tree-depth", _p$.l = _v$71);
1734
+ var _v$63 = siblings().length,
1735
+ _v$64 = place() + 1,
1736
+ _v$65 = selected(),
1737
+ _v$66 = hasChildren() ? isExpanded(item.id) : undefined,
1738
+ _v$67 = item.disabled ? "true" : undefined,
1739
+ _v$68 = item.disabled ? -1 : tabStopId() === item.id ? 0 : -1,
1740
+ _v$69 = movable() ? true : undefined,
1741
+ _v$70 = item.id,
1742
+ _v$71 = dragged()?.id === item.id ? "" : undefined,
1743
+ _v$72 = dropTarget()?.id === item.id ? dropTarget().side : undefined,
1744
+ _v$73 = String(props.indented === false ? 0 : depth);
1745
+ _v$63 !== _p$.e && _$setAttribute(_el$84, "aria-setsize", _p$.e = _v$63);
1746
+ _v$64 !== _p$.t && _$setAttribute(_el$84, "aria-posinset", _p$.t = _v$64);
1747
+ _v$65 !== _p$.a && _$setAttribute(_el$84, "aria-selected", _p$.a = _v$65);
1748
+ _v$66 !== _p$.o && _$setAttribute(_el$84, "aria-expanded", _p$.o = _v$66);
1749
+ _v$67 !== _p$.i && _$setAttribute(_el$84, "aria-disabled", _p$.i = _v$67);
1750
+ _v$68 !== _p$.n && _$setAttribute(_el$84, "tabindex", _p$.n = _v$68);
1751
+ _v$69 !== _p$.s && _$setAttribute(_el$84, "draggable", _p$.s = _v$69);
1752
+ _v$70 !== _p$.h && _$setAttribute(_el$84, "data-k2b-nav-tree-id", _p$.h = _v$70);
1753
+ _v$71 !== _p$.r && _$setAttribute(_el$84, "data-k2b-nav-tree-dragging", _p$.r = _v$71);
1754
+ _v$72 !== _p$.d && _$setAttribute(_el$84, "data-k2b-nav-tree-drop", _p$.d = _v$72);
1755
+ _v$73 !== _p$.l && _$setStyleProperty(_el$84, "--k2b-nav-tree-depth", _p$.l = _v$73);
1740
1756
  return _p$;
1741
1757
  }, {
1742
1758
  e: undefined,
@@ -1790,10 +1806,10 @@ const AppWorkspaceNavTree = props => {
1790
1806
  typeof _ref$5 === "function" ? _$use(_ref$5, _el$90) : root = _el$90;
1791
1807
  _$insert(_el$90, () => renderItems(roots, 0));
1792
1808
  _$effect(_p$ => {
1793
- var _v$72 = `k2b-app-workspace__nav-tree ${props.class ?? ""}`,
1794
- _v$73 = props.ariaLabel;
1795
- _v$72 !== _p$.e && _$className(_el$90, _p$.e = _v$72);
1796
- _v$73 !== _p$.t && _$setAttribute(_el$90, "aria-label", _p$.t = _v$73);
1809
+ var _v$74 = `k2b-app-workspace__nav-tree ${props.class ?? ""}`,
1810
+ _v$75 = props.ariaLabel;
1811
+ _v$74 !== _p$.e && _$className(_el$90, _p$.e = _v$74);
1812
+ _v$75 !== _p$.t && _$setAttribute(_el$90, "aria-label", _p$.t = _v$75);
1797
1813
  return _p$;
1798
1814
  }, {
1799
1815
  e: undefined,
@@ -1895,11 +1911,14 @@ const AppWorkspaceSidebarIconAction = props => {
1895
1911
  };
1896
1912
  /**
1897
1913
  * The row above the work area. From 48 to 64 rem it holds the button that
1898
- * opens the overlay sidebar. On a page with a page above it, at every width,
1899
- * it shows the host's page title with the way up (see `PageTitle`); the
1900
- * page's own `PageTitle` takes its place. It is one fixed height and draws no
1901
- * line; CSS decides when it shows, so the server-rendered page already has
1902
- * its final geometry.
1914
+ * opens the overlay sidebar. On a page with a page above it, it shows the
1915
+ * host's page title with the way up (see `PageTitle`); the page's own
1916
+ * `PageTitle` takes its place. The visible title is no heading, because many
1917
+ * pages render their own `h1`. From 64 rem a sidebar that marks the current
1918
+ * page names it already: the row hides, and only on a page without its own
1919
+ * `h1` its heading stays for assistive technology. It is one fixed height
1920
+ * and draws no line; CSS decides when it shows, so the server-rendered page
1921
+ * already has its final geometry.
1903
1922
  */
1904
1923
  function AppWorkspaceHead(props) {
1905
1924
  const messages = useWorkspaceMessages();
@@ -1929,13 +1948,18 @@ function AppWorkspaceHead(props) {
1929
1948
  get when() {
1930
1949
  return trail();
1931
1950
  },
1932
- children: current => _$createComponent(PageTitle, {
1951
+ children: current => [_$createComponent(PageTitle, {
1933
1952
  get trail() {
1934
1953
  return current();
1935
1954
  },
1936
1955
  as: "p",
1937
1956
  fallback: true
1938
- })
1957
+ }), (() => {
1958
+ var _el$105 = _$getNextElement(_tmpl$46);
1959
+ _$setAttribute(_el$105, "data-k2b-server", isServer ? "" : undefined);
1960
+ _$insert(_el$105, () => current().title);
1961
+ return _el$105;
1962
+ })()]
1939
1963
  }), _el$104, _co$16);
1940
1964
  _$effect(() => _$setAttribute(_el$99, "data-trail", trail()?.ancestors.length ? "up" : trail() ? "title" : undefined));
1941
1965
  return _el$99;
@@ -1973,38 +1997,41 @@ const AppWorkspace = props => {
1973
1997
  return _$createComponent(WorkspaceContext.Provider, {
1974
1998
  value: workspace,
1975
1999
  get children() {
1976
- var _el$105 = _$getNextElement(_tmpl$46),
1977
- _el$106 = _el$105.firstChild,
1978
- [_el$107, _co$17] = _$getNextMarker(_el$106.nextSibling),
1979
- _el$108 = _el$107.nextSibling,
1980
- [_el$109, _co$18] = _$getNextMarker(_el$108.nextSibling);
2000
+ var _el$106 = _$getNextElement(_tmpl$47),
2001
+ _el$107 = _el$106.firstChild,
2002
+ [_el$108, _co$17] = _$getNextMarker(_el$107.nextSibling),
2003
+ _el$109 = _el$108.nextSibling,
2004
+ [_el$110, _co$18] = _$getNextMarker(_el$109.nextSibling);
1981
2005
  var _ref$6 = root;
1982
- typeof _ref$6 === "function" ? _$use(_ref$6, _el$105) : root = _el$105;
1983
- _$insert(_el$105, _$createComponent(AppWorkspaceHead, {
2006
+ typeof _ref$6 === "function" ? _$use(_ref$6, _el$106) : root = _el$106;
2007
+ _$insert(_el$106, _$createComponent(AppWorkspaceHead, {
1984
2008
  sidebarId: sidebarId,
1985
2009
  nested: nested
1986
- }), _el$107, _co$17);
1987
- _$insert(_el$105, () => props.children, _el$109, _co$18);
2010
+ }), _el$108, _co$17);
2011
+ _$insert(_el$106, () => props.children, _el$110, _co$18);
1988
2012
  _$effect(_p$ => {
1989
- var _v$74 = `k2b-app-workspace ${props.class ?? ""}`,
1990
- _v$75 = props.mobileSurface,
1991
- _v$76 = initialLayoutState()?.sidebarCollapsed === undefined ? undefined : String(initialLayoutState()?.sidebarCollapsed),
1992
- _v$77 = props.resizable === false ? "false" : "true",
1993
- _v$78 = appWorkspaceLayoutStyle(initialLayoutState());
1994
- _v$74 !== _p$.e && _$className(_el$105, _p$.e = _v$74);
1995
- _v$75 !== _p$.t && _$setAttribute(_el$105, "data-mobile-surface", _p$.t = _v$75);
1996
- _v$76 !== _p$.a && _$setAttribute(_el$105, "data-sidebar-collapsed", _p$.a = _v$76);
1997
- _v$77 !== _p$.o && _$setAttribute(_el$105, "data-workspace-resizable", _p$.o = _v$77);
1998
- _p$.i = _$style(_el$105, _v$78, _p$.i);
2013
+ var _v$76 = `k2b-app-workspace ${props.class ?? ""}`,
2014
+ _v$77 = props.mobileSurface,
2015
+ _v$78 = props.flat ? "true" : undefined,
2016
+ _v$79 = initialLayoutState()?.sidebarCollapsed === undefined ? undefined : String(initialLayoutState()?.sidebarCollapsed),
2017
+ _v$80 = props.resizable === false ? "false" : "true",
2018
+ _v$81 = appWorkspaceLayoutStyle(initialLayoutState());
2019
+ _v$76 !== _p$.e && _$className(_el$106, _p$.e = _v$76);
2020
+ _v$77 !== _p$.t && _$setAttribute(_el$106, "data-mobile-surface", _p$.t = _v$77);
2021
+ _v$78 !== _p$.a && _$setAttribute(_el$106, "data-flat", _p$.a = _v$78);
2022
+ _v$79 !== _p$.o && _$setAttribute(_el$106, "data-sidebar-collapsed", _p$.o = _v$79);
2023
+ _v$80 !== _p$.i && _$setAttribute(_el$106, "data-workspace-resizable", _p$.i = _v$80);
2024
+ _p$.n = _$style(_el$106, _v$81, _p$.n);
1999
2025
  return _p$;
2000
2026
  }, {
2001
2027
  e: undefined,
2002
2028
  t: undefined,
2003
2029
  a: undefined,
2004
2030
  o: undefined,
2005
- i: undefined
2031
+ i: undefined,
2032
+ n: undefined
2006
2033
  });
2007
- return _el$105;
2034
+ return _el$106;
2008
2035
  }
2009
2036
  });
2010
2037
  }
@@ -2019,10 +2046,10 @@ AppWorkspace.LayoutStateProvider = props => _$createComponent(LayoutStateContext
2019
2046
  }
2020
2047
  });
2021
2048
  AppWorkspace.Content = props => (() => {
2022
- var _el$110 = _$getNextElement(_tmpl$2);
2023
- _$insert(_el$110, () => props.children);
2024
- _$effect(() => _$className(_el$110, `k2b-app-workspace__content ${props.class ?? ""}`));
2025
- return _el$110;
2049
+ var _el$111 = _$getNextElement(_tmpl$2);
2050
+ _$insert(_el$111, () => props.children);
2051
+ _$effect(() => _$className(_el$111, `k2b-app-workspace__content ${props.class ?? ""}`));
2052
+ return _el$111;
2026
2053
  })();
2027
2054
  AppWorkspace.Main = AppWorkspaceMain;
2028
2055
  AppWorkspace.MainPane = AppWorkspaceMainPane;
@@ -2030,6 +2057,7 @@ AppWorkspace.Detail = AppWorkspaceDetail;
2030
2057
  AppWorkspace.BottomDrawer = AppWorkspaceBottomDrawer;
2031
2058
  AppWorkspace.Sidebar = AppWorkspaceSidebar;
2032
2059
  AppWorkspace.SidebarDesktop = AppWorkspaceSidebarDesktop;
2060
+ AppWorkspace.SidebarSwitcher = AppWorkspaceSidebarSwitcher;
2033
2061
  AppWorkspace.SidebarSection = AppWorkspaceSidebarSection;
2034
2062
  AppWorkspace.SidebarBody = AppWorkspaceSidebarBody;
2035
2063
  AppWorkspace.SidebarFooter = AppWorkspaceSidebarFooter;