@formicoidea/labre-core 0.48.0 → 0.49.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 (222) hide show
  1. package/dist/_pkgs/affine-block-data-view/configs/slash-menu.js +3 -1
  2. package/dist/_pkgs/affine-block-data-view/view.d.ts +17 -1
  3. package/dist/_pkgs/affine-block-data-view/view.js +21 -2
  4. package/dist/_pkgs/affine-block-database/commands.d.ts +2 -2
  5. package/dist/_pkgs/affine-block-database/commands.js +3 -3
  6. package/dist/_pkgs/affine-block-database/components/values-banner.d.ts +28 -0
  7. package/dist/_pkgs/affine-block-database/components/values-banner.js +199 -0
  8. package/dist/_pkgs/affine-block-database/configs/slash-menu.d.ts +6 -1
  9. package/dist/_pkgs/affine-block-database/configs/slash-menu.js +57 -70
  10. package/dist/_pkgs/affine-block-database/data-source.d.ts +9 -5
  11. package/dist/_pkgs/affine-block-database/data-source.js +11 -7
  12. package/dist/_pkgs/affine-block-database/database-block-styles.d.ts +2 -0
  13. package/dist/_pkgs/affine-block-database/database-block-styles.js +15 -0
  14. package/dist/_pkgs/affine-block-database/database-block.d.ts +23 -0
  15. package/dist/_pkgs/affine-block-database/database-block.js +141 -19
  16. package/dist/_pkgs/affine-block-database/effects.js +2 -0
  17. package/dist/_pkgs/affine-block-database/external-data-source.d.ts +69 -2
  18. package/dist/_pkgs/affine-block-database/external-data-source.js +88 -16
  19. package/dist/_pkgs/affine-block-database/index.d.ts +2 -0
  20. package/dist/_pkgs/affine-block-database/index.js +2 -0
  21. package/dist/_pkgs/affine-block-database/linked-view.d.ts +38 -0
  22. package/dist/_pkgs/affine-block-database/linked-view.js +109 -0
  23. package/dist/_pkgs/affine-block-database/properties/index.d.ts +2 -0
  24. package/dist/_pkgs/affine-block-database/properties/index.js +2 -0
  25. package/dist/_pkgs/affine-block-database/properties/text/hosted.d.ts +15 -0
  26. package/dist/_pkgs/affine-block-database/properties/text/hosted.js +24 -0
  27. package/dist/_pkgs/affine-block-database/properties/title/hosted.d.ts +16 -0
  28. package/dist/_pkgs/affine-block-database/properties/title/hosted.js +42 -0
  29. package/dist/_pkgs/affine-block-database/service/index.d.ts +3 -0
  30. package/dist/_pkgs/affine-block-database/service/index.js +3 -0
  31. package/dist/_pkgs/affine-block-database/service/new-row-menu.d.ts +49 -0
  32. package/dist/_pkgs/affine-block-database/service/new-row-menu.js +21 -0
  33. package/dist/_pkgs/affine-block-database/service/open-row.d.ts +77 -0
  34. package/dist/_pkgs/affine-block-database/service/open-row.js +62 -0
  35. package/dist/_pkgs/affine-block-database/service/properties-panel.d.ts +23 -0
  36. package/dist/_pkgs/affine-block-database/service/properties-panel.js +33 -0
  37. package/dist/_pkgs/affine-block-database/translations.d.ts +10 -0
  38. package/dist/_pkgs/affine-block-database/translations.js +35 -0
  39. package/dist/_pkgs/affine-block-database/view-creation.d.ts +10 -0
  40. package/dist/_pkgs/affine-block-database/view-creation.js +14 -0
  41. package/dist/_pkgs/affine-block-database/view.d.ts +31 -1
  42. package/dist/_pkgs/affine-block-database/view.js +44 -5
  43. package/dist/_pkgs/affine-block-database/views/index.d.ts +30 -3
  44. package/dist/_pkgs/affine-block-database/views/index.js +44 -3
  45. package/dist/_pkgs/affine-components/date-picker/date-picker.d.ts +20 -0
  46. package/dist/_pkgs/affine-components/date-picker/date-picker.js +60 -26
  47. package/dist/_pkgs/affine-components/date-picker/style.js +1 -0
  48. package/dist/_pkgs/affine-components/translations.d.ts +4 -0
  49. package/dist/_pkgs/affine-components/translations.js +26 -0
  50. package/dist/_pkgs/affine-fragment-doc-title/doc-title.d.ts +18 -0
  51. package/dist/_pkgs/affine-fragment-doc-title/doc-title.js +41 -2
  52. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.d.ts +8 -0
  53. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.js +12 -0
  54. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.d.ts +5 -0
  55. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.js +44 -4
  56. package/dist/_pkgs/affine-model/blocks/database/types.d.ts +16 -0
  57. package/dist/_pkgs/affine-model/blocks/database/types.js +5 -1
  58. package/dist/_pkgs/affine-shared/services/data-source-picker-service.d.ts +139 -0
  59. package/dist/_pkgs/affine-shared/services/data-source-picker-service.js +22 -0
  60. package/dist/_pkgs/affine-shared/services/index.d.ts +1 -0
  61. package/dist/_pkgs/affine-shared/services/index.js +1 -0
  62. package/dist/_pkgs/affine-shared/services/telemetry-service/database.d.ts +59 -0
  63. package/dist/_pkgs/affine-shared/services/title-band-service.d.ts +24 -0
  64. package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.d.ts +2 -0
  65. package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.js +16 -0
  66. package/dist/_pkgs/data-view/core/component/cell-status/cell-status.d.ts +10 -0
  67. package/dist/_pkgs/data-view/core/component/cell-status/cell-status.js +23 -0
  68. package/dist/_pkgs/data-view/core/component/index.d.ts +1 -0
  69. package/dist/_pkgs/data-view/core/component/index.js +1 -0
  70. package/dist/_pkgs/data-view/core/component/overflow/fit.d.ts +26 -0
  71. package/dist/_pkgs/data-view/core/component/overflow/fit.js +48 -0
  72. package/dist/_pkgs/data-view/core/component/overflow/overflow.d.ts +26 -3
  73. package/dist/_pkgs/data-view/core/component/overflow/overflow.js +84 -31
  74. package/dist/_pkgs/data-view/core/component/tags/colors.d.ts +7 -0
  75. package/dist/_pkgs/data-view/core/component/tags/colors.js +22 -10
  76. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.d.ts +18 -0
  77. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.js +63 -21
  78. package/dist/_pkgs/data-view/core/data-source/base.d.ts +5 -1
  79. package/dist/_pkgs/data-view/core/data-source/base.js +7 -1
  80. package/dist/_pkgs/data-view/core/data-source/hydration.d.ts +44 -0
  81. package/dist/_pkgs/data-view/core/data-source/hydration.js +31 -0
  82. package/dist/_pkgs/data-view/core/data-source/index.d.ts +1 -0
  83. package/dist/_pkgs/data-view/core/data-source/index.js +1 -0
  84. package/dist/_pkgs/data-view/core/data-view.d.ts +22 -2
  85. package/dist/_pkgs/data-view/core/data-view.js +14 -0
  86. package/dist/_pkgs/data-view/core/effect.js +2 -0
  87. package/dist/_pkgs/data-view/core/group-by/collapsed-state.d.ts +3 -0
  88. package/dist/_pkgs/data-view/core/group-by/collapsed-state.js +59 -0
  89. package/dist/_pkgs/data-view/core/group-by/group-properties.d.ts +21 -0
  90. package/dist/_pkgs/data-view/core/group-by/group-properties.js +38 -0
  91. package/dist/_pkgs/data-view/core/group-by/group-title.js +4 -0
  92. package/dist/_pkgs/data-view/core/group-by/group-visibility.d.ts +40 -0
  93. package/dist/_pkgs/data-view/core/group-by/group-visibility.js +291 -0
  94. package/dist/_pkgs/data-view/core/group-by/setting.d.ts +11 -3
  95. package/dist/_pkgs/data-view/core/group-by/setting.js +81 -8
  96. package/dist/_pkgs/data-view/core/group-by/trait.d.ts +22 -0
  97. package/dist/_pkgs/data-view/core/group-by/trait.js +62 -1
  98. package/dist/_pkgs/data-view/core/index.d.ts +3 -0
  99. package/dist/_pkgs/data-view/core/index.js +3 -0
  100. package/dist/_pkgs/data-view/core/property/base-cell.d.ts +15 -1
  101. package/dist/_pkgs/data-view/core/property/base-cell.js +28 -3
  102. package/dist/_pkgs/data-view/core/property/standalone-cell.d.ts +15 -1
  103. package/dist/_pkgs/data-view/core/property/standalone-cell.js +19 -1
  104. package/dist/_pkgs/data-view/core/telemetry.d.ts +16 -0
  105. package/dist/_pkgs/data-view/core/telemetry.js +22 -0
  106. package/dist/_pkgs/data-view/core/utils/new-tab-click.d.ts +2 -0
  107. package/dist/_pkgs/data-view/core/utils/new-tab-click.js +4 -0
  108. package/dist/_pkgs/data-view/core/utils/wording.d.ts +11 -0
  109. package/dist/_pkgs/data-view/core/utils/wording.js +9 -0
  110. package/dist/_pkgs/data-view/core/view/data-view.d.ts +7 -0
  111. package/dist/_pkgs/data-view/core/view/default-name.d.ts +10 -0
  112. package/dist/_pkgs/data-view/core/view/default-name.js +14 -0
  113. package/dist/_pkgs/data-view/core/view/index.d.ts +2 -0
  114. package/dist/_pkgs/data-view/core/view/index.js +2 -0
  115. package/dist/_pkgs/data-view/core/view/open-in.d.ts +27 -0
  116. package/dist/_pkgs/data-view/core/view/open-in.js +39 -0
  117. package/dist/_pkgs/data-view/core/view-manager/cell.d.ts +5 -0
  118. package/dist/_pkgs/data-view/core/view-manager/cell.js +11 -0
  119. package/dist/_pkgs/data-view/core/view-manager/index.d.ts +3 -0
  120. package/dist/_pkgs/data-view/core/view-manager/index.js +3 -0
  121. package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.d.ts +18 -0
  122. package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.js +2 -0
  123. package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.d.ts +8 -0
  124. package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.js +9 -0
  125. package/dist/_pkgs/data-view/core/view-manager/property.d.ts +8 -0
  126. package/dist/_pkgs/data-view/core/view-manager/single-view.d.ts +28 -1
  127. package/dist/_pkgs/data-view/core/view-manager/single-view.js +45 -1
  128. package/dist/_pkgs/data-view/core/view-manager/view-creation.d.ts +49 -0
  129. package/dist/_pkgs/data-view/core/view-manager/view-creation.js +40 -0
  130. package/dist/_pkgs/data-view/core/view-manager/view-manager.d.ts +6 -2
  131. package/dist/_pkgs/data-view/core/view-manager/view-manager.js +2 -2
  132. package/dist/_pkgs/data-view/property-presets/date/cell-renderer.d.ts +2 -0
  133. package/dist/_pkgs/data-view/property-presets/date/cell-renderer.js +11 -2
  134. package/dist/_pkgs/data-view/property-presets/multi-select/cell-renderer.js +2 -0
  135. package/dist/_pkgs/data-view/property-presets/select/cell-renderer.js +2 -0
  136. package/dist/_pkgs/data-view/translations.d.ts +55 -0
  137. package/dist/_pkgs/data-view/translations.js +181 -0
  138. package/dist/_pkgs/data-view/view-presets/calendar/define.js +3 -1
  139. package/dist/_pkgs/data-view/view-presets/convert.js +2 -0
  140. package/dist/_pkgs/data-view/view-presets/effect.js +4 -0
  141. package/dist/_pkgs/data-view/view-presets/flat/flat-converts.d.ts +2 -0
  142. package/dist/_pkgs/data-view/view-presets/flat/flat-converts.js +35 -0
  143. package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.d.ts +79 -0
  144. package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.js +194 -0
  145. package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.d.ts +56 -0
  146. package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.js +266 -0
  147. package/dist/_pkgs/data-view/view-presets/gallery/define.d.ts +14 -0
  148. package/dist/_pkgs/data-view/view-presets/gallery/define.js +15 -0
  149. package/dist/_pkgs/data-view/view-presets/gallery/effect.d.ts +1 -0
  150. package/dist/_pkgs/data-view/view-presets/gallery/effect.js +4 -0
  151. package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.d.ts +27 -0
  152. package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.js +179 -0
  153. package/dist/_pkgs/data-view/view-presets/gallery/index.d.ts +2 -0
  154. package/dist/_pkgs/data-view/view-presets/gallery/index.js +2 -0
  155. package/dist/_pkgs/data-view/view-presets/gallery/renderer.d.ts +1 -0
  156. package/dist/_pkgs/data-view/view-presets/gallery/renderer.js +11 -0
  157. package/dist/_pkgs/data-view/view-presets/index.d.ts +5 -0
  158. package/dist/_pkgs/data-view/view-presets/index.js +7 -0
  159. package/dist/_pkgs/data-view/view-presets/kanban/define.js +3 -1
  160. package/dist/_pkgs/data-view/view-presets/kanban/kanban-view-manager.js +5 -53
  161. package/dist/_pkgs/data-view/view-presets/kanban/mobile/card.js +8 -1
  162. package/dist/_pkgs/data-view/view-presets/kanban/mobile/cell.js +6 -1
  163. package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.d.ts +4 -2
  164. package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.js +52 -6
  165. package/dist/_pkgs/data-view/view-presets/kanban/mobile/kanban-view-ui-logic.js +5 -1
  166. package/dist/_pkgs/data-view/view-presets/kanban/pc/card.js +2 -0
  167. package/dist/_pkgs/data-view/view-presets/kanban/pc/cell.js +4 -0
  168. package/dist/_pkgs/data-view/view-presets/kanban/pc/group.d.ts +4 -2
  169. package/dist/_pkgs/data-view/view-presets/kanban/pc/group.js +51 -6
  170. package/dist/_pkgs/data-view/view-presets/kanban/pc/kanban-view-ui-logic.js +5 -1
  171. package/dist/_pkgs/data-view/view-presets/list/define.d.ts +14 -0
  172. package/dist/_pkgs/data-view/view-presets/list/define.js +15 -0
  173. package/dist/_pkgs/data-view/view-presets/list/effect.d.ts +1 -0
  174. package/dist/_pkgs/data-view/view-presets/list/effect.js +4 -0
  175. package/dist/_pkgs/data-view/view-presets/list/index.d.ts +2 -0
  176. package/dist/_pkgs/data-view/view-presets/list/index.js +2 -0
  177. package/dist/_pkgs/data-view/view-presets/list/list-view.d.ts +24 -0
  178. package/dist/_pkgs/data-view/view-presets/list/list-view.js +194 -0
  179. package/dist/_pkgs/data-view/view-presets/list/renderer.d.ts +1 -0
  180. package/dist/_pkgs/data-view/view-presets/list/renderer.js +11 -0
  181. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.d.ts +3 -14
  182. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.js +6 -30
  183. package/dist/_pkgs/data-view/view-presets/table/consts.d.ts +2 -0
  184. package/dist/_pkgs/data-view/view-presets/table/consts.js +2 -0
  185. package/dist/_pkgs/data-view/view-presets/table/define.js +3 -1
  186. package/dist/_pkgs/data-view/view-presets/table/mobile/cell.js +4 -1
  187. package/dist/_pkgs/data-view/view-presets/table/mobile/column-header.js +2 -2
  188. package/dist/_pkgs/data-view/view-presets/table/mobile/group.d.ts +3 -1
  189. package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +20 -5
  190. package/dist/_pkgs/data-view/view-presets/table/mobile/row.js +10 -2
  191. package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.js +4 -1
  192. package/dist/_pkgs/data-view/view-presets/table/pc/cell.js +4 -1
  193. package/dist/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.js +1 -1
  194. package/dist/_pkgs/data-view/view-presets/table/pc/group.d.ts +3 -1
  195. package/dist/_pkgs/data-view/view-presets/table/pc/group.js +20 -5
  196. package/dist/_pkgs/data-view/view-presets/table/pc/menu.d.ts +1 -1
  197. package/dist/_pkgs/data-view/view-presets/table/pc/menu.js +2 -1
  198. package/dist/_pkgs/data-view/view-presets/table/pc/row/row.js +3 -2
  199. package/dist/_pkgs/data-view/view-presets/table/pc/table-view-ui-logic.js +4 -1
  200. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.js +1 -1
  201. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.js +5 -1
  202. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +22 -19
  203. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.js +4 -1
  204. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/table-view-ui-logic.js +7 -2
  205. package/dist/_pkgs/data-view/view-presets/table/stats/column-stats-column.js +5 -1
  206. package/dist/_pkgs/data-view/view-presets/table/table-view-manager.js +5 -53
  207. package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.d.ts +1 -0
  208. package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.js +60 -2
  209. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.d.ts +18 -1
  210. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.js +121 -124
  211. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.d.ts +43 -0
  212. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.js +187 -0
  213. package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.d.ts +36 -3
  214. package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.js +187 -59
  215. package/dist/extensions/view.d.ts +2 -2
  216. package/dist/extensions/view.js +10 -3
  217. package/dist/flags.d.ts +8 -4
  218. package/dist/flags.js +8 -4
  219. package/dist/frameworks.d.ts +27 -0
  220. package/dist/frameworks.js +28 -0
  221. package/dist/translations.js +13 -1
  222. package/package.json +5 -1
@@ -0,0 +1,44 @@
1
+ import type { ReadonlySignal } from '@preact/signals-core';
2
+ /**
3
+ * Cell hydration (ADR 0035 §9e, issue B2): a widening of the data-source
4
+ * contract, not a seam.
5
+ *
6
+ * A host source whose values arrive after its rows (Labre keeps them in SQL,
7
+ * labre ADR-0047) says, per cell, whether the value it answers is the real one
8
+ * yet, and, for the whole source, whether values are still loading or failed.
9
+ * Every member is optional: a source that says nothing is `ready` at once,
10
+ * which is the inline source and every 0.48 host source, unchanged.
11
+ *
12
+ * Nothing is written in any state. A cell that is not `ready` mounts no
13
+ * renderer and refuses `valueSet`, so neither the user nor a paste, a fill or
14
+ * a kanban drop can write over a value the source has not delivered.
15
+ */
16
+ export type CellStatus = 'ready' | 'pending' | 'error';
17
+ export type ValuesStatus = 'loading' | 'ready' | 'error';
18
+ export interface ValuesState {
19
+ readonly status: ValuesStatus;
20
+ /** `Date.now()` when the source entered `status`. */
21
+ readonly since: number;
22
+ }
23
+ export interface DataSourceHydration {
24
+ cellStatus?(rowId: string, propertyId: string): CellStatus;
25
+ valuesState$?: ReadonlySignal<ValuesState>;
26
+ /** Present when the source can try again after an `error`. */
27
+ retryValues?(): void;
28
+ }
29
+ export declare const VALUES_READY: ValuesState;
30
+ /** How long values may load before a banner says so (REQ-DB-12). */
31
+ export declare const VALUES_SLOW_AFTER_MS = 3000;
32
+ export declare function cellStatusOf(source: DataSourceHydration, rowId: string, propertyId: string): CellStatus;
33
+ export declare function valuesStateOf(source: DataSourceHydration): ValuesState;
34
+ /** What a count shows while values are not ready. */
35
+ export declare const VALUES_PENDING_MARK = "\u2026";
36
+ /** Counts (group headers, column statistics) show an ellipsis until `true`. */
37
+ export declare function valuesReady(source: DataSourceHydration): boolean;
38
+ export type ValuesBanner = 'none' | 'slow' | 'error';
39
+ /**
40
+ * Which banner a view shows: none while values load for less than
41
+ * {@link VALUES_SLOW_AFTER_MS}, `slow` after, `error` as soon as loading
42
+ * failed. Pure, so the 3 s rule is tested without a timer.
43
+ */
44
+ export declare function valuesBannerOf(state: ValuesState, now: number): ValuesBanner;
@@ -0,0 +1,31 @@
1
+ export const VALUES_READY = Object.freeze({
2
+ status: 'ready',
3
+ since: 0,
4
+ });
5
+ /** How long values may load before a banner says so (REQ-DB-12). */
6
+ export const VALUES_SLOW_AFTER_MS = 3000;
7
+ export function cellStatusOf(source, rowId, propertyId) {
8
+ return source.cellStatus?.(rowId, propertyId) ?? 'ready';
9
+ }
10
+ export function valuesStateOf(source) {
11
+ return source.valuesState$?.value ?? VALUES_READY;
12
+ }
13
+ /** What a count shows while values are not ready. */
14
+ export const VALUES_PENDING_MARK = '…';
15
+ /** Counts (group headers, column statistics) show an ellipsis until `true`. */
16
+ export function valuesReady(source) {
17
+ return valuesStateOf(source).status === 'ready';
18
+ }
19
+ /**
20
+ * Which banner a view shows: none while values load for less than
21
+ * {@link VALUES_SLOW_AFTER_MS}, `slow` after, `error` as soon as loading
22
+ * failed. Pure, so the 3 s rule is tested without a timer.
23
+ */
24
+ export function valuesBannerOf(state, now) {
25
+ if (state.status === 'error')
26
+ return 'error';
27
+ if (state.status === 'loading' && now - state.since >= VALUES_SLOW_AFTER_MS) {
28
+ return 'slow';
29
+ }
30
+ return 'none';
31
+ }
@@ -1 +1,2 @@
1
1
  export * from './base.js';
2
+ export * from './hydration.js';
@@ -1 +1,2 @@
1
1
  export * from './base.js';
2
+ export * from './hydration.js';
@@ -2,6 +2,7 @@ import type { DatabaseAllEvents, EventTraceFn } from '../../affine-shared/servic
2
2
  import type { DisposableMember } from '../../global/disposable/index.js';
3
3
  import { type Clipboard, type DndController, type EventName, ShadowlessElement, type UIEventHandler } from '../../std/index.js';
4
4
  import { type ReadonlySignal } from '@preact/signals-core';
5
+ import { type TemplateResult } from 'lit';
5
6
  import type { DataSource } from './data-source/index.js';
6
7
  import type { DataViewSelection } from './types.js';
7
8
  import type { DataViewUILogicBase } from './view/data-view-base.js';
@@ -22,10 +23,22 @@ export type DataViewRendererConfig = {
22
23
  selection$: ReadonlySignal<DataViewSelection | undefined>;
23
24
  setSelection: (selection: DataViewSelection | undefined) => void;
24
25
  eventTrace: EventTraceFn<DatabaseAllEvents>;
26
+ /**
27
+ * Drawn instead of the current view, header widget included, when it
28
+ * returns something (a source the view names that the host cannot resolve,
29
+ * ADR 0035 §7): the caller draws what of its header still makes sense.
30
+ * Absent: every view draws as in 0.48.
31
+ */
32
+ viewPlaceholder?: (logic: DataViewUILogicBase) => TemplateResult | undefined;
25
33
  detailPanelConfig: {
26
34
  openDetailPanel: (target: HTMLElement, data: {
27
35
  view: SingleView;
28
36
  rowId: string;
37
+ /**
38
+ * A Ctrl/Cmd click: the host may open the row in a new tab (ADR 0035
39
+ * §9a). Absent for a gesture with no such modifier.
40
+ */
41
+ newTab?: boolean;
29
42
  }) => Promise<void>;
30
43
  };
31
44
  };
@@ -45,13 +58,19 @@ export declare class DataViewRootUILogic {
45
58
  readonly currentViewId$: ReadonlySignal<string | undefined>;
46
59
  readonly currentView$: ReadonlySignal<DataViewUILogicBase<SingleView, DataViewSelection> | undefined>;
47
60
  focusFirstCell: () => void;
61
+ /**
62
+ * The one way a view opens a row, whatever its preset (the database block
63
+ * routes it to the host's opener or to its own detail panel, ADR 0035 §9a).
64
+ * `newTab` says the gesture asked for a new tab (`isNewTabClick`).
65
+ */
48
66
  openDetailPanel: (ops: {
49
67
  view: SingleView;
50
68
  rowId: string;
69
+ newTab?: boolean;
51
70
  onClose?: () => void;
52
71
  }) => void;
53
72
  setupViewChangeListener(): () => void;
54
- render(): import("lit-html").TemplateResult;
73
+ render(): TemplateResult;
55
74
  }
56
75
  declare const DataViewRootUI_base: typeof ShadowlessElement & import("../../global/utils/types.js").Constructor<import("../../global/lit/with-disposable.js").DisposableClass>;
57
76
  export declare class DataViewRootUI extends DataViewRootUI_base {
@@ -62,10 +81,11 @@ export declare class DataViewRootUI extends DataViewRootUI_base {
62
81
  openDetailPanel: (ops: {
63
82
  view: SingleView;
64
83
  rowId: string;
84
+ newTab?: boolean;
65
85
  onClose?: () => void;
66
86
  }) => void;
67
87
  connectedCallback(): void;
68
- render(): import("lit-html").TemplateResult | undefined;
88
+ render(): TemplateResult | undefined;
69
89
  }
70
90
  declare global {
71
91
  interface HTMLElementTagNameMap {
@@ -110,6 +110,11 @@ export class DataViewRootUILogic {
110
110
  this.focusFirstCell = () => {
111
111
  this.currentView$.value?.focusFirstCell();
112
112
  };
113
+ /**
114
+ * The one way a view opens a row, whatever its preset (the database block
115
+ * routes it to the host's opener or to its own detail panel, ADR 0035 §9a).
116
+ * `newTab` says the gesture asked for a new tab (`isNewTabClick`).
117
+ */
113
118
  this.openDetailPanel = (ops) => {
114
119
  const openDetailPanel = this.config.detailPanelConfig.openDetailPanel;
115
120
  const target = this.dataViewRenderer;
@@ -117,6 +122,7 @@ export class DataViewRootUILogic {
117
122
  openDetailPanel(target, {
118
123
  view: ops.view,
119
124
  rowId: ops.rowId,
125
+ ...(ops.newTab ? { newTab: true } : {}),
120
126
  })
121
127
  .catch(console.error)
122
128
  .finally(ops.onClose);
@@ -197,6 +203,14 @@ let DataViewRootUI = (() => {
197
203
  if (!currentView) {
198
204
  return;
199
205
  }
206
+ const placeholder = this.logic.config.viewPlaceholder?.(currentView);
207
+ if (placeholder) {
208
+ return html `
209
+ <div style="display: contents" class="${containerClass}">
210
+ ${placeholder}
211
+ </div>
212
+ `;
213
+ }
200
214
  return html `
201
215
  <div style="display: contents" class="${containerClass}">
202
216
  ${renderUniLit(currentView.renderer, {
@@ -6,6 +6,7 @@ import { DataViewRootUI } from './data-view.js';
6
6
  import { RecordDetail } from './detail/detail.js';
7
7
  import { RecordField } from './detail/field.js';
8
8
  import { VariableRefView } from './expression/ref/ref-view.js';
9
+ import { DataViewHiddenGroups } from './group-by/group-visibility.js';
9
10
  import { BooleanGroupView } from './group-by/renderer/boolean-group.js';
10
11
  import { DateGroupView } from './group-by/renderer/date-group.js';
11
12
  import { NumberGroupView } from './group-by/renderer/number-group.js';
@@ -27,6 +28,7 @@ export function coreEffects() {
27
28
  customElements.define('data-view-group-title-number-view', NumberGroupView);
28
29
  customElements.define('affine-lit-icon', AffineLitIcon);
29
30
  customElements.define('data-view-group-setting', GroupSetting);
31
+ customElements.define('dv-hidden-groups', DataViewHiddenGroups);
30
32
  customElements.define('affine-multi-tag-select', MultiTagSelect);
31
33
  customElements.define('data-view-group-title-boolean-view', BooleanGroupView);
32
34
  customElements.define('data-view-group-title-date-view', DateGroupView);
@@ -0,0 +1,3 @@
1
+ import { type ReadonlySignal } from '@preact/signals-core';
2
+ export declare function groupCollapsed$(viewId: string, groupKey: string): ReadonlySignal<boolean>;
3
+ export declare function groupCollapsedSet(viewId: string, groupKey: string, collapsed: boolean): void;
@@ -0,0 +1,59 @@
1
+ import { signal } from '@preact/signals-core';
2
+ /**
3
+ * Whether a group of a view is folded, for every preset (ADR 0035 §8, B8,
4
+ * PRD REQ-DB-16). Personal and per device: kept in `localStorage`, never in
5
+ * the document, like the local hide of ADR 0031. A host seam was not chosen:
6
+ * it would be a row in the seams table forever for a device ergonomic, and a
7
+ * fold that follows the user across devices is not asked for.
8
+ *
9
+ * Only a folded group has an entry (`'1'`); unfolding removes it. Any other
10
+ * value, a storage that throws (private mode, blocked site data) or no
11
+ * storage at all reads as unfolded. One signal per key, shared by every
12
+ * element drawing that group, so a fold is seen everywhere at once.
13
+ *
14
+ * Until 0.49 the table kept this in `sessionStorage` under
15
+ * `affine:table-group:*`; those entries were per tab and are not read back.
16
+ */
17
+ const PREFIX = 'labre:data-view:group-collapsed:';
18
+ const storageKey = (viewId, groupKey) => `${PREFIX}${viewId}:${groupKey}`;
19
+ const states = new Map();
20
+ function readStored(key) {
21
+ try {
22
+ return globalThis.localStorage?.getItem(key) === '1';
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ function writeStored(key, collapsed) {
29
+ try {
30
+ if (collapsed) {
31
+ globalThis.localStorage?.setItem(key, '1');
32
+ }
33
+ else {
34
+ globalThis.localStorage?.removeItem(key);
35
+ }
36
+ }
37
+ catch {
38
+ // A storage that refuses keeps the fold for this session only.
39
+ }
40
+ }
41
+ function stateOf(viewId, groupKey) {
42
+ const key = storageKey(viewId, groupKey);
43
+ let state = states.get(key);
44
+ if (!state) {
45
+ state = signal(readStored(key));
46
+ states.set(key, state);
47
+ }
48
+ return state;
49
+ }
50
+ export function groupCollapsed$(viewId, groupKey) {
51
+ return stateOf(viewId, groupKey);
52
+ }
53
+ export function groupCollapsedSet(viewId, groupKey, collapsed) {
54
+ const state = stateOf(viewId, groupKey);
55
+ if (state.peek() === collapsed)
56
+ return;
57
+ state.value = collapsed;
58
+ writeStored(storageKey(viewId, groupKey), collapsed);
59
+ }
@@ -0,0 +1,21 @@
1
+ import type { GroupProperty } from '../common/types.js';
2
+ import type { Row } from '../view-manager/row.js';
3
+ /**
4
+ * The group ops every grouped preset hands its `GroupTrait`, over the view's
5
+ * stored `groupProperties` (the shape table and kanban have always stored:
6
+ * `{ key, hide, manuallyCardSort }`). One copy for table, kanban, gallery and
7
+ * list (ADR 0035 §8, B8), so a hidden group and a manual order read and write
8
+ * the same way in every view.
9
+ *
10
+ * Every write lists the entry of every group key it is given, so a hidden
11
+ * group keeps its `hide` and its card order through a reorder; nothing is
12
+ * written when the value would not change.
13
+ */
14
+ export declare const groupPropertiesOps: (read: () => GroupProperty[], write: (groupProperties: GroupProperty[]) => void) => {
15
+ sortGroup: (keys: string[]) => string[];
16
+ sortRow: (key: string, rows: Row[]) => Row[];
17
+ changeGroupSort: (keys: string[]) => void;
18
+ changeRowSort: (groupKeys: string[], groupKey: string, keys: string[]) => void;
19
+ groupHidden: (key: string) => boolean;
20
+ groupHideSet: (groupKeys: string[], groupKey: string, hide: boolean) => void;
21
+ };
@@ -0,0 +1,38 @@
1
+ import { sortByManually } from './trait.js';
2
+ /**
3
+ * The group ops every grouped preset hands its `GroupTrait`, over the view's
4
+ * stored `groupProperties` (the shape table and kanban have always stored:
5
+ * `{ key, hide, manuallyCardSort }`). One copy for table, kanban, gallery and
6
+ * list (ADR 0035 §8, B8), so a hidden group and a manual order read and write
7
+ * the same way in every view.
8
+ *
9
+ * Every write lists the entry of every group key it is given, so a hidden
10
+ * group keeps its `hide` and its card order through a reorder; nothing is
11
+ * written when the value would not change.
12
+ */
13
+ export const groupPropertiesOps = (read, write) => {
14
+ const entries = () => new Map(read().map(v => [v.key, v]));
15
+ const entry = (map, key) => map.get(key) ?? { key, hide: false, manuallyCardSort: [] };
16
+ const groupHidden = (key) => read().find(v => v.key === key)?.hide === true;
17
+ return {
18
+ sortGroup: (keys) => sortByManually(keys, v => v, read().map(v => v.key)),
19
+ sortRow: (key, rows) => sortByManually(rows, v => v.rowId, read().find(v => v.key === key)?.manuallyCardSort ?? []),
20
+ changeGroupSort: (keys) => {
21
+ const map = entries();
22
+ write(keys.map(key => entry(map, key)));
23
+ },
24
+ changeRowSort: (groupKeys, groupKey, keys) => {
25
+ const map = entries();
26
+ write(groupKeys.map(key => key === groupKey
27
+ ? { ...entry(map, key), manuallyCardSort: keys }
28
+ : entry(map, key)));
29
+ },
30
+ groupHidden,
31
+ groupHideSet: (groupKeys, groupKey, hide) => {
32
+ if (groupHidden(groupKey) === hide)
33
+ return;
34
+ const map = entries();
35
+ write(groupKeys.map(key => key === groupKey ? { ...entry(map, key), hide } : entry(map, key)));
36
+ },
37
+ };
38
+ };
@@ -3,8 +3,12 @@ import { IS_MOBILE } from '../../../global/env/index.js';
3
3
  import { MoreHorizontalIcon, PlusIcon } from '@blocksuite/icons/lit';
4
4
  import { nothing } from 'lit';
5
5
  import { html } from 'lit/static-html.js';
6
+ import { VALUES_PENDING_MARK, valuesReady } from '../data-source/hydration.js';
6
7
  import { renderUniLit } from '../utils/uni-component/uni-component.js';
7
8
  function GroupHeaderCount(group) {
9
+ if (!valuesReady(group.property.view.manager.dataSource)) {
10
+ return html ` <div class="group-header-count">${VALUES_PENDING_MARK}</div>`;
11
+ }
8
12
  const cards = group.rows;
9
13
  if (!cards.length) {
10
14
  return;
@@ -0,0 +1,40 @@
1
+ import { type MenuConfig } from '../../../affine-components/context-menu/index.js';
2
+ import { type BlockStdScope, ShadowlessElement } from '../../../std/index.js';
3
+ import { nothing } from 'lit';
4
+ import { type Wording } from '../utils/wording.js';
5
+ import type { Group, GroupTrait } from './trait.js';
6
+ /**
7
+ * The group chrome every grouped preset shares (ADR 0035 §8, B8, PRD
8
+ * REQ-DB-16): "Hide group" in a group's menu, the fold toggle of a group
9
+ * header, and the list of hidden groups drawn at the end of the view. Hiding
10
+ * is a view setting, shared by everyone; folding is personal
11
+ * (`collapsed-state.ts`).
12
+ */
13
+ /** "Hide group", for a group's own menu. Absent where the view hides none. */
14
+ export declare const hideGroupAction: (group: Group, wording: Wording) => MenuConfig;
15
+ /**
16
+ * A group header's fold button. Folding is never a write, so a read-only
17
+ * view folds too.
18
+ */
19
+ export declare const renderGroupToggle: (group: Group, wording: Wording) => import("lit-html").TemplateResult<1>;
20
+ export declare const groupToggleStyles: import("lit").CSSResult;
21
+ declare const DataViewHiddenGroups_base: typeof ShadowlessElement & import("../../../global/utils/types.js").Constructor<import("../../../global/lit/with-disposable.js").DisposableClass>;
22
+ /**
23
+ * The hidden groups of a view, at its end, each with a button that shows it
24
+ * again (PRD REQ-DB-16). Nothing when the view hides no group. A read-only
25
+ * view lists them without the button.
26
+ */
27
+ export declare class DataViewHiddenGroups extends DataViewHiddenGroups_base {
28
+ static styles: import("lit").CSSResult;
29
+ /** Absent outside an editor (a unit test): the wordings read English. */
30
+ accessor std: BlockStdScope;
31
+ accessor groupTrait: GroupTrait | undefined;
32
+ connectedCallback(): void;
33
+ render(): import("lit-html").TemplateResult<1> | typeof nothing;
34
+ }
35
+ declare global {
36
+ interface HTMLElementTagNameMap {
37
+ 'dv-hidden-groups': DataViewHiddenGroups;
38
+ }
39
+ }
40
+ export {};
@@ -0,0 +1,291 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { menu } from '../../../affine-components/context-menu/index.js';
36
+ import { SignalWatcher, WithDisposable } from '../../../global/lit/index.js';
37
+ import { InvisibleIcon, ToggleDownIcon, ToggleRightIcon, ViewIcon, } from '@blocksuite/icons/lit';
38
+ import { ShadowlessElement, stdContext } from '../../../std/index.js';
39
+ import { consume } from '@lit/context';
40
+ import { cssVarV2 } from '@toeverything/theme/v2';
41
+ import { css, html, nothing, unsafeCSS } from 'lit';
42
+ import { property } from 'lit/decorators.js';
43
+ import { repeat } from 'lit/directives/repeat.js';
44
+ import { DATA_VIEW_GROUP_COLLAPSE, DATA_VIEW_GROUP_EXPAND, DATA_VIEW_GROUP_HIDE, DATA_VIEW_GROUP_SHOW, DATA_VIEW_HIDDEN_GROUPS, } from '../../translations.js';
45
+ import { VALUES_PENDING_MARK, valuesReady } from '../data-source/hydration.js';
46
+ import { renderUniLit } from '../utils/uni-component/uni-component.js';
47
+ import { wordingOf } from '../utils/wording.js';
48
+ /**
49
+ * The group chrome every grouped preset shares (ADR 0035 §8, B8, PRD
50
+ * REQ-DB-16): "Hide group" in a group's menu, the fold toggle of a group
51
+ * header, and the list of hidden groups drawn at the end of the view. Hiding
52
+ * is a view setting, shared by everyone; folding is personal
53
+ * (`collapsed-state.ts`).
54
+ */
55
+ /** "Hide group", for a group's own menu. Absent where the view hides none. */
56
+ export const hideGroupAction = (group, wording) => menu.action({
57
+ name: wording(DATA_VIEW_GROUP_HIDE),
58
+ prefix: InvisibleIcon(),
59
+ hide: () => !group.manager.groupsCanHide,
60
+ select: () => {
61
+ group.manager.groupHideSet(group.key, true);
62
+ },
63
+ });
64
+ const groupCount = (group) => valuesReady(group.property.view.manager.dataSource)
65
+ ? group.rows.length
66
+ : VALUES_PENDING_MARK;
67
+ /**
68
+ * A group header's fold button. Folding is never a write, so a read-only
69
+ * view folds too.
70
+ */
71
+ export const renderGroupToggle = (group, wording) => {
72
+ const collapsed = group.manager.collapsed$(group.key).value;
73
+ const label = wording(collapsed ? DATA_VIEW_GROUP_EXPAND : DATA_VIEW_GROUP_COLLAPSE);
74
+ return html `<button
75
+ class="dv-group-toggle"
76
+ data-testid="dv-group-toggle"
77
+ aria-expanded="${collapsed ? 'false' : 'true'}"
78
+ aria-label="${label}"
79
+ title="${label}"
80
+ @click="${(event) => {
81
+ event.stopPropagation();
82
+ group.manager.collapsedSet(group.key, !collapsed);
83
+ }}"
84
+ >
85
+ ${collapsed ? ToggleRightIcon() : ToggleDownIcon()}
86
+ </button>`;
87
+ };
88
+ export const groupToggleStyles = css `
89
+ .dv-group-toggle {
90
+ display: flex;
91
+ flex-shrink: 0;
92
+ align-items: center;
93
+ justify-content: center;
94
+ width: 24px;
95
+ height: 24px;
96
+ padding: 0;
97
+ border: none;
98
+ border-radius: 4px;
99
+ background: transparent;
100
+ color: var(--affine-icon-color);
101
+ cursor: pointer;
102
+ }
103
+
104
+ .dv-group-toggle svg {
105
+ width: 16px;
106
+ height: 16px;
107
+ }
108
+
109
+ .dv-group-toggle:focus-visible {
110
+ outline: 2px solid var(--affine-primary-color);
111
+ outline-offset: 1px;
112
+ }
113
+
114
+ @media (hover: hover) {
115
+ .dv-group-toggle:hover {
116
+ background-color: var(--affine-hover-color);
117
+ }
118
+ }
119
+
120
+ @media (pointer: coarse) {
121
+ .dv-group-toggle {
122
+ width: 44px;
123
+ height: 44px;
124
+ }
125
+ }
126
+ `;
127
+ /**
128
+ * The hidden groups of a view, at its end, each with a button that shows it
129
+ * again (PRD REQ-DB-16). Nothing when the view hides no group. A read-only
130
+ * view lists them without the button.
131
+ */
132
+ let DataViewHiddenGroups = (() => {
133
+ let _classSuper = SignalWatcher(WithDisposable(ShadowlessElement));
134
+ let _std_decorators;
135
+ let _std_initializers = [];
136
+ let _std_extraInitializers = [];
137
+ let _groupTrait_decorators;
138
+ let _groupTrait_initializers = [];
139
+ let _groupTrait_extraInitializers = [];
140
+ return class DataViewHiddenGroups extends _classSuper {
141
+ static {
142
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
143
+ _std_decorators = [consume({ context: stdContext })];
144
+ _groupTrait_decorators = [property({ attribute: false })];
145
+ __esDecorate(this, null, _std_decorators, { kind: "accessor", name: "std", static: false, private: false, access: { has: obj => "std" in obj, get: obj => obj.std, set: (obj, value) => { obj.std = value; } }, metadata: _metadata }, _std_initializers, _std_extraInitializers);
146
+ __esDecorate(this, null, _groupTrait_decorators, { kind: "accessor", name: "groupTrait", static: false, private: false, access: { has: obj => "groupTrait" in obj, get: obj => obj.groupTrait, set: (obj, value) => { obj.groupTrait = value; } }, metadata: _metadata }, _groupTrait_initializers, _groupTrait_extraInitializers);
147
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
148
+ }
149
+ static { this.styles = css `
150
+ dv-hidden-groups {
151
+ display: block;
152
+ }
153
+
154
+ .dv-hidden-groups {
155
+ display: flex;
156
+ flex-direction: column;
157
+ gap: 2px;
158
+ padding: 8px 0;
159
+ }
160
+
161
+ .dv-hidden-groups-title {
162
+ display: flex;
163
+ align-items: center;
164
+ gap: 8px;
165
+ padding: 0 4px 4px;
166
+ font-size: 12px;
167
+ line-height: 20px;
168
+ color: var(--affine-text-secondary-color);
169
+ }
170
+
171
+ .dv-hidden-group {
172
+ display: flex;
173
+ align-items: center;
174
+ gap: 8px;
175
+ min-height: 32px;
176
+ padding: 0 4px;
177
+ border-radius: 4px;
178
+ }
179
+
180
+ .dv-hidden-group-title {
181
+ flex: 1 1 auto;
182
+ min-width: 0;
183
+ overflow: hidden;
184
+ opacity: 0.7;
185
+ }
186
+
187
+ .dv-hidden-group-count {
188
+ flex-shrink: 0;
189
+ font-size: 12px;
190
+ color: var(--affine-text-secondary-color);
191
+ }
192
+
193
+ .dv-hidden-group-show {
194
+ display: flex;
195
+ flex-shrink: 0;
196
+ align-items: center;
197
+ justify-content: center;
198
+ width: 28px;
199
+ height: 28px;
200
+ padding: 0;
201
+ border: 1px solid ${unsafeCSS(cssVarV2.layer.insideBorder.border)};
202
+ border-radius: 4px;
203
+ background: transparent;
204
+ color: var(--affine-icon-color);
205
+ cursor: pointer;
206
+ }
207
+
208
+ .dv-hidden-group-show svg {
209
+ width: 16px;
210
+ height: 16px;
211
+ }
212
+
213
+ .dv-hidden-group-show:focus-visible {
214
+ outline: 2px solid var(--affine-primary-color);
215
+ outline-offset: 1px;
216
+ }
217
+
218
+ @media (hover: hover) {
219
+ .dv-hidden-group-show:hover {
220
+ background-color: var(--affine-hover-color);
221
+ }
222
+ }
223
+
224
+ @media (pointer: coarse) {
225
+ .dv-hidden-group {
226
+ min-height: 44px;
227
+ }
228
+
229
+ .dv-hidden-group-show {
230
+ width: 44px;
231
+ height: 44px;
232
+ }
233
+ }
234
+ `; }
235
+ #std_accessor_storage = __runInitializers(this, _std_initializers, void 0);
236
+ /** Absent outside an editor (a unit test): the wordings read English. */
237
+ get std() { return this.#std_accessor_storage; }
238
+ set std(value) { this.#std_accessor_storage = value; }
239
+ #groupTrait_accessor_storage = (__runInitializers(this, _std_extraInitializers), __runInitializers(this, _groupTrait_initializers, undefined));
240
+ get groupTrait() { return this.#groupTrait_accessor_storage; }
241
+ set groupTrait(value) { this.#groupTrait_accessor_storage = value; }
242
+ connectedCallback() {
243
+ super.connectedCallback();
244
+ this.dataset.testid = 'dv-hidden-groups';
245
+ }
246
+ render() {
247
+ const trait = this.groupTrait;
248
+ const groups = trait?.hiddenGroups$.value ?? [];
249
+ if (!trait || !groups.length)
250
+ return nothing;
251
+ const wording = wordingOf(this.std);
252
+ const readonly = trait.view.readonly$.value;
253
+ const show = wording(DATA_VIEW_GROUP_SHOW);
254
+ return html `<div class="dv-hidden-groups">
255
+ <div class="dv-hidden-groups-title">
256
+ <span>${wording(DATA_VIEW_HIDDEN_GROUPS)}</span>
257
+ <span>${groups.length}</span>
258
+ </div>
259
+ ${repeat(groups, group => group.key, group => {
260
+ const props = { group, readonly: true };
261
+ return html `<div
262
+ class="dv-hidden-group"
263
+ data-testid="dv-hidden-group"
264
+ data-group-key="${group.key}"
265
+ >
266
+ <div class="dv-hidden-group-title">
267
+ ${renderUniLit(group.view, props)}
268
+ </div>
269
+ <span class="dv-hidden-group-count">${groupCount(group)}</span>
270
+ ${readonly
271
+ ? nothing
272
+ : html `<button
273
+ class="dv-hidden-group-show"
274
+ data-testid="dv-group-show"
275
+ aria-label="${show}"
276
+ title="${show}"
277
+ @click="${() => trait.groupHideSet(group.key, false)}"
278
+ >
279
+ ${ViewIcon()}
280
+ </button>`}
281
+ </div>`;
282
+ })}
283
+ </div>`;
284
+ }
285
+ constructor() {
286
+ super(...arguments);
287
+ __runInitializers(this, _groupTrait_extraInitializers);
288
+ }
289
+ };
290
+ })();
291
+ export { DataViewHiddenGroups };