@gtkx/components 1.0.0-rc.1 → 1.0.0-rc.3

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 (220) hide show
  1. package/dist/adw/combo-row.d.ts +11 -0
  2. package/dist/adw/combo-row.d.ts.map +1 -0
  3. package/dist/adw/combo-row.js +14 -0
  4. package/dist/adw/combo-row.js.map +1 -0
  5. package/dist/adw/index.d.ts +4 -0
  6. package/dist/adw/index.d.ts.map +1 -0
  7. package/dist/adw/index.js +3 -0
  8. package/dist/adw/index.js.map +1 -0
  9. package/dist/adw/toast.d.ts +10 -0
  10. package/dist/adw/toast.d.ts.map +1 -0
  11. package/dist/adw/toast.js +51 -0
  12. package/dist/adw/toast.js.map +1 -0
  13. package/dist/adw/types.d.ts +35 -0
  14. package/dist/adw/types.d.ts.map +1 -0
  15. package/dist/adw/types.js +2 -0
  16. package/dist/adw/types.js.map +1 -0
  17. package/dist/column-view.d.ts +7 -29
  18. package/dist/column-view.d.ts.map +1 -1
  19. package/dist/column-view.js +98 -70
  20. package/dist/column-view.js.map +1 -1
  21. package/dist/drop-down.d.ts +7 -28
  22. package/dist/drop-down.d.ts.map +1 -1
  23. package/dist/drop-down.js +10 -86
  24. package/dist/drop-down.js.map +1 -1
  25. package/dist/grid-view.d.ts +6 -16
  26. package/dist/grid-view.d.ts.map +1 -1
  27. package/dist/grid-view.js +25 -33
  28. package/dist/grid-view.js.map +1 -1
  29. package/dist/index.d.ts +6 -12
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -6
  32. package/dist/index.js.map +1 -1
  33. package/dist/internal/cells.d.ts +50 -0
  34. package/dist/internal/cells.d.ts.map +1 -0
  35. package/dist/internal/cells.js +185 -0
  36. package/dist/internal/cells.js.map +1 -0
  37. package/dist/internal/collection-index.d.ts +21 -0
  38. package/dist/internal/collection-index.d.ts.map +1 -0
  39. package/dist/internal/collection-index.js +106 -0
  40. package/dist/internal/collection-index.js.map +1 -0
  41. package/dist/internal/collection-model.d.ts +12 -0
  42. package/dist/internal/collection-model.d.ts.map +1 -0
  43. package/dist/internal/collection-model.js +164 -0
  44. package/dist/internal/collection-model.js.map +1 -0
  45. package/dist/internal/collection.d.ts +18 -0
  46. package/dist/internal/collection.d.ts.map +1 -0
  47. package/dist/internal/collection.js +64 -0
  48. package/dist/internal/collection.js.map +1 -0
  49. package/dist/internal/drop-down.d.ts +16 -0
  50. package/dist/internal/drop-down.d.ts.map +1 -0
  51. package/dist/internal/drop-down.js +110 -0
  52. package/dist/internal/drop-down.js.map +1 -0
  53. package/dist/internal/expansion.d.ts +9 -0
  54. package/dist/internal/expansion.d.ts.map +1 -0
  55. package/dist/internal/expansion.js +74 -0
  56. package/dist/internal/expansion.js.map +1 -0
  57. package/dist/internal/selection.d.ts +13 -0
  58. package/dist/internal/selection.d.ts.map +1 -0
  59. package/dist/internal/selection.js +100 -0
  60. package/dist/internal/selection.js.map +1 -0
  61. package/dist/internal/use-collection.d.ts +17 -0
  62. package/dist/internal/use-collection.d.ts.map +1 -0
  63. package/dist/internal/use-collection.js +34 -0
  64. package/dist/internal/use-collection.js.map +1 -0
  65. package/dist/internal/use-widget-ref.d.ts +4 -0
  66. package/dist/internal/use-widget-ref.d.ts.map +1 -0
  67. package/dist/internal/use-widget-ref.js +8 -0
  68. package/dist/internal/use-widget-ref.js.map +1 -0
  69. package/dist/list-view.d.ts +5 -20
  70. package/dist/list-view.d.ts.map +1 -1
  71. package/dist/list-view.js +32 -53
  72. package/dist/list-view.js.map +1 -1
  73. package/dist/size-group.d.ts +8 -16
  74. package/dist/size-group.d.ts.map +1 -1
  75. package/dist/size-group.js +35 -51
  76. package/dist/size-group.js.map +1 -1
  77. package/dist/types.d.ts +98 -27
  78. package/dist/types.d.ts.map +1 -1
  79. package/dist/types.js.map +1 -1
  80. package/package.json +17 -6
  81. package/src/adw/combo-row.tsx +20 -0
  82. package/src/adw/index.ts +9 -0
  83. package/src/adw/toast.tsx +74 -0
  84. package/src/adw/types.ts +45 -0
  85. package/src/column-view.tsx +176 -160
  86. package/src/drop-down.tsx +12 -185
  87. package/src/grid-view.tsx +29 -73
  88. package/src/index.ts +18 -26
  89. package/src/internal/cells.tsx +345 -0
  90. package/src/internal/collection-index.ts +168 -0
  91. package/src/internal/collection-model.ts +246 -0
  92. package/src/internal/collection.ts +104 -0
  93. package/src/internal/drop-down.tsx +186 -0
  94. package/src/internal/expansion.ts +122 -0
  95. package/src/internal/selection.tsx +162 -0
  96. package/src/internal/use-collection.tsx +57 -0
  97. package/src/internal/use-widget-ref.ts +11 -0
  98. package/src/list-view.tsx +43 -139
  99. package/src/size-group.tsx +63 -82
  100. package/src/types.ts +158 -28
  101. package/dist/cell.d.ts +0 -30
  102. package/dist/cell.d.ts.map +0 -1
  103. package/dist/cell.js +0 -45
  104. package/dist/cell.js.map +0 -1
  105. package/dist/column-view-column.d.ts +0 -27
  106. package/dist/column-view-column.d.ts.map +0 -1
  107. package/dist/column-view-column.js +0 -30
  108. package/dist/column-view-column.js.map +0 -1
  109. package/dist/constraint-layout-apply.d.ts +0 -55
  110. package/dist/constraint-layout-apply.d.ts.map +0 -1
  111. package/dist/constraint-layout-apply.js +0 -107
  112. package/dist/constraint-layout-apply.js.map +0 -1
  113. package/dist/constraint-layout.d.ts +0 -20
  114. package/dist/constraint-layout.d.ts.map +0 -1
  115. package/dist/constraint-layout.js +0 -88
  116. package/dist/constraint-layout.js.map +0 -1
  117. package/dist/fixed.d.ts +0 -26
  118. package/dist/fixed.d.ts.map +0 -1
  119. package/dist/fixed.js +0 -40
  120. package/dist/fixed.js.map +0 -1
  121. package/dist/grid.d.ts +0 -27
  122. package/dist/grid.d.ts.map +0 -1
  123. package/dist/grid.js +0 -48
  124. package/dist/grid.js.map +0 -1
  125. package/dist/hooks/use-cell-containers.d.ts +0 -18
  126. package/dist/hooks/use-cell-containers.d.ts.map +0 -1
  127. package/dist/hooks/use-cell-containers.js +0 -67
  128. package/dist/hooks/use-cell-containers.js.map +0 -1
  129. package/dist/hooks/use-collection-model.d.ts +0 -26
  130. package/dist/hooks/use-collection-model.d.ts.map +0 -1
  131. package/dist/hooks/use-collection-model.js +0 -35
  132. package/dist/hooks/use-collection-model.js.map +0 -1
  133. package/dist/hooks/use-collection-widget.d.ts +0 -28
  134. package/dist/hooks/use-collection-widget.d.ts.map +0 -1
  135. package/dist/hooks/use-collection-widget.js +0 -21
  136. package/dist/hooks/use-collection-widget.js.map +0 -1
  137. package/dist/hooks/use-drop-down-selection.d.ts +0 -16
  138. package/dist/hooks/use-drop-down-selection.d.ts.map +0 -1
  139. package/dist/hooks/use-drop-down-selection.js +0 -35
  140. package/dist/hooks/use-drop-down-selection.js.map +0 -1
  141. package/dist/hooks/use-expansion-model.d.ts +0 -12
  142. package/dist/hooks/use-expansion-model.d.ts.map +0 -1
  143. package/dist/hooks/use-expansion-model.js +0 -71
  144. package/dist/hooks/use-expansion-model.js.map +0 -1
  145. package/dist/hooks/use-header-menu.d.ts +0 -4
  146. package/dist/hooks/use-header-menu.d.ts.map +0 -1
  147. package/dist/hooks/use-header-menu.js +0 -20
  148. package/dist/hooks/use-header-menu.js.map +0 -1
  149. package/dist/hooks/use-installed-model.d.ts +0 -4
  150. package/dist/hooks/use-installed-model.d.ts.map +0 -1
  151. package/dist/hooks/use-installed-model.js +0 -15
  152. package/dist/hooks/use-installed-model.js.map +0 -1
  153. package/dist/hooks/use-list-model.d.ts +0 -19
  154. package/dist/hooks/use-list-model.d.ts.map +0 -1
  155. package/dist/hooks/use-list-model.js +0 -97
  156. package/dist/hooks/use-list-model.js.map +0 -1
  157. package/dist/hooks/use-placed-child.d.ts +0 -18
  158. package/dist/hooks/use-placed-child.d.ts.map +0 -1
  159. package/dist/hooks/use-placed-child.js +0 -47
  160. package/dist/hooks/use-placed-child.js.map +0 -1
  161. package/dist/hooks/use-selection-model.d.ts +0 -13
  162. package/dist/hooks/use-selection-model.d.ts.map +0 -1
  163. package/dist/hooks/use-selection-model.js +0 -103
  164. package/dist/hooks/use-selection-model.js.map +0 -1
  165. package/dist/hooks/use-sort-handler.d.ts +0 -17
  166. package/dist/hooks/use-sort-handler.d.ts.map +0 -1
  167. package/dist/hooks/use-sort-handler.js +0 -87
  168. package/dist/hooks/use-sort-handler.js.map +0 -1
  169. package/dist/menu-items.d.ts +0 -5
  170. package/dist/menu-items.d.ts.map +0 -1
  171. package/dist/menu-items.js +0 -48
  172. package/dist/menu-items.js.map +0 -1
  173. package/dist/menu.d.ts +0 -14
  174. package/dist/menu.d.ts.map +0 -1
  175. package/dist/menu.js +0 -24
  176. package/dist/menu.js.map +0 -1
  177. package/dist/overlay.d.ts +0 -24
  178. package/dist/overlay.d.ts.map +0 -1
  179. package/dist/overlay.js +0 -49
  180. package/dist/overlay.js.map +0 -1
  181. package/dist/utils/cell-container-store.d.ts +0 -28
  182. package/dist/utils/cell-container-store.d.ts.map +0 -1
  183. package/dist/utils/cell-container-store.js +0 -98
  184. package/dist/utils/cell-container-store.js.map +0 -1
  185. package/dist/utils/item-models.d.ts +0 -10
  186. package/dist/utils/item-models.d.ts.map +0 -1
  187. package/dist/utils/item-models.js +0 -82
  188. package/dist/utils/item-models.js.map +0 -1
  189. package/dist/utils/item-resolver.d.ts +0 -25
  190. package/dist/utils/item-resolver.d.ts.map +0 -1
  191. package/dist/utils/item-resolver.js +0 -102
  192. package/dist/utils/item-resolver.js.map +0 -1
  193. package/dist/utils/list-item-flatten.d.ts +0 -24
  194. package/dist/utils/list-item-flatten.d.ts.map +0 -1
  195. package/dist/utils/list-item-flatten.js +0 -68
  196. package/dist/utils/list-item-flatten.js.map +0 -1
  197. package/src/cell.tsx +0 -144
  198. package/src/column-view-column.tsx +0 -82
  199. package/src/constraint-layout-apply.ts +0 -173
  200. package/src/constraint-layout.tsx +0 -135
  201. package/src/fixed.tsx +0 -86
  202. package/src/grid.tsx +0 -88
  203. package/src/hooks/use-cell-containers.ts +0 -93
  204. package/src/hooks/use-collection-model.ts +0 -60
  205. package/src/hooks/use-collection-widget.ts +0 -47
  206. package/src/hooks/use-drop-down-selection.ts +0 -52
  207. package/src/hooks/use-expansion-model.ts +0 -82
  208. package/src/hooks/use-header-menu.ts +0 -34
  209. package/src/hooks/use-installed-model.ts +0 -20
  210. package/src/hooks/use-list-model.ts +0 -161
  211. package/src/hooks/use-placed-child.ts +0 -79
  212. package/src/hooks/use-selection-model.ts +0 -114
  213. package/src/hooks/use-sort-handler.ts +0 -107
  214. package/src/menu-items.ts +0 -48
  215. package/src/menu.tsx +0 -32
  216. package/src/overlay.tsx +0 -88
  217. package/src/utils/cell-container-store.ts +0 -114
  218. package/src/utils/item-models.ts +0 -113
  219. package/src/utils/item-resolver.ts +0 -138
  220. package/src/utils/list-item-flatten.ts +0 -90
@@ -1,102 +0,0 @@
1
- import { countDescendants, flattenListItems } from "./list-item-flatten.js";
2
- const NO_TREE_METADATA = { hideExpander: false, indentForDepth: true, indentForIcon: true };
3
- const treeItemCache = new WeakMap();
4
- const treeRowItem = (treeRow) => {
5
- const cached = treeItemCache.get(treeRow);
6
- if (cached !== undefined)
7
- return cached;
8
- const item = treeRow.getItem();
9
- if (item !== null)
10
- treeItemCache.set(treeRow, item);
11
- return item;
12
- };
13
- export const rowIdOf = (rowValues, row) => {
14
- const item = row.getItem();
15
- return item === null ? undefined : rowValues.get(item)?.id;
16
- };
17
- export const createItemResolver = (items, flattenTreeChildren, rowValues) => {
18
- const flattened = flattenListItems(items, flattenTreeChildren);
19
- return {
20
- positionOfId(id) {
21
- const position = flattened.idToPosition.get(id);
22
- return position === undefined ? -1 : position;
23
- },
24
- idOf(position) {
25
- return flattened.positionToId.get(position);
26
- },
27
- resolve(position, treeRow) {
28
- if (treeRow !== null && !flattenTreeChildren) {
29
- const rowItem = treeRowItem(treeRow);
30
- if (rowItem !== null) {
31
- const tagged = rowValues.get(rowItem);
32
- if (tagged !== undefined) {
33
- return {
34
- value: tagged.value,
35
- present: true,
36
- isHeader: false,
37
- metadata: tagged.metadata,
38
- };
39
- }
40
- }
41
- }
42
- const record = flattened.records[position];
43
- if (record === undefined) {
44
- return {
45
- value: undefined,
46
- present: false,
47
- isHeader: false,
48
- metadata: NO_TREE_METADATA,
49
- };
50
- }
51
- return {
52
- value: record.value,
53
- present: true,
54
- isHeader: false,
55
- metadata: record.metadata,
56
- };
57
- },
58
- };
59
- };
60
- export const createSectionHeaderResolver = (sections) => {
61
- const valueByStart = new Map();
62
- let start = 0;
63
- for (const section of sections ?? []) {
64
- valueByStart.set(start, section.value);
65
- start += countDescendants(section.data);
66
- }
67
- return {
68
- positionOfId: () => -1,
69
- idOf: () => undefined,
70
- resolve(position) {
71
- if (!valueByStart.has(position)) {
72
- return { value: undefined, present: false, isHeader: true, metadata: NO_TREE_METADATA };
73
- }
74
- return {
75
- value: valueByStart.get(position),
76
- present: true,
77
- isHeader: true,
78
- metadata: NO_TREE_METADATA,
79
- };
80
- },
81
- };
82
- };
83
- export const createTreeResolver = (items, rowValues, model) => {
84
- const base = createItemResolver(items, false, rowValues);
85
- return {
86
- resolve: base.resolve,
87
- idOf: (position) => {
88
- const row = model.getRow(position);
89
- return row === null ? undefined : rowIdOf(rowValues, row);
90
- },
91
- positionOfId: (id) => {
92
- const count = model.getNItems();
93
- for (let position = 0; position < count; position++) {
94
- const row = model.getRow(position);
95
- if (row !== null && rowIdOf(rowValues, row) === id)
96
- return position;
97
- }
98
- return -1;
99
- },
100
- };
101
- };
102
- //# sourceMappingURL=item-resolver.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"item-resolver.js","sourceRoot":"","sources":["../../src/utils/item-resolver.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAyB,MAAM,wBAAwB,CAAC;AAEnG,MAAM,gBAAgB,GAAqB,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AAE9G,MAAM,aAAa,GAAG,IAAI,OAAO,EAAmC,CAAC;AAErE,MAAM,WAAW,GAAG,CAAC,OAAwB,EAAyB,EAAE;IACpE,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAC/B,IAAI,IAAI,KAAK,IAAI;QAAE,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAqBF,MAAM,CAAC,MAAM,OAAO,GAAG,CACnB,SAA+C,EAC/C,GAAoB,EACF,EAAE;IACpB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;IAC3B,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;AAC/D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAC9B,KAAgC,EAChC,mBAA4B,EAC5B,SAA+C,EAC7B,EAAE;IACpB,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;IAC/D,OAAO;QACH,YAAY,CAAC,EAAU;YACnB,MAAM,QAAQ,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChD,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,QAAgB;YACjB,OAAO,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,CAAC,QAAgB,EAAE,OAA+B;YACrD,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3C,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;gBACrC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;oBACnB,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACtC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;wBACvB,OAAO;4BACH,KAAK,EAAE,MAAM,CAAC,KAAK;4BACnB,OAAO,EAAE,IAAI;4BACb,QAAQ,EAAE,KAAK;4BACf,QAAQ,EAAE,MAAM,CAAC,QAAQ;yBAC5B,CAAC;oBACN,CAAC;gBACL,CAAC;YACL,CAAC;YACD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC3C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO;oBACH,KAAK,EAAE,SAAS;oBAChB,OAAO,EAAE,KAAK;oBACd,QAAQ,EAAE,KAAK;oBACf,QAAQ,EAAE,gBAAgB;iBAC7B,CAAC;YACN,CAAC;YACD,OAAO;gBACH,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,KAAK;gBACf,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC5B,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAO,QAAyC,EAAsB,EAAE;IAC/G,MAAM,YAAY,GAAG,IAAI,GAAG,EAAa,CAAC;IAC1C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,OAAO,IAAI,QAAQ,IAAI,EAAE,EAAE,CAAC;QACnC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACvC,KAAK,IAAI,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO;QACH,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACtB,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;QACrB,OAAO,CAAC,QAAgB;YACpB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;YAC5F,CAAC;YACD,OAAO;gBACH,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;gBACjC,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,gBAAgB;aAC7B,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAC9B,KAAgC,EAChC,SAA+C,EAC/C,KAAwB,EACN,EAAE;IACpB,MAAM,IAAI,GAAG,kBAAkB,CAAO,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAC/D,OAAO;QACH,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,CAAC,QAAgB,EAAsB,EAAE;YAC3C,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACnC,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QACD,YAAY,EAAE,CAAC,EAAU,EAAU,EAAE;YACjC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YAChC,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC;gBAClD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACnC,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,EAAE;oBAAE,OAAO,QAAQ,CAAC;YACxE,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;QACd,CAAC;KACJ,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type * as GObject from \"@gtkx/gi/gobject\";\nimport type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { ItemNode, SectionNode } from \"../types.js\";\nimport { countDescendants, flattenListItems, type TreeItemMetadata } from \"./list-item-flatten.js\";\n\nconst NO_TREE_METADATA: TreeItemMetadata = { hideExpander: false, indentForDepth: true, indentForIcon: true };\n\nconst treeItemCache = new WeakMap<Gtk.TreeListRow, GObject.Object>();\n\nconst treeRowItem = (treeRow: Gtk.TreeListRow): GObject.Object | null => {\n const cached = treeItemCache.get(treeRow);\n if (cached !== undefined) return cached;\n const item = treeRow.getItem();\n if (item !== null) treeItemCache.set(treeRow, item);\n return item;\n};\n\nexport type Resolved<T = unknown, S = unknown> = {\n value: T | S | undefined;\n present: boolean;\n isHeader: boolean;\n metadata: TreeItemMetadata;\n};\n\nexport type ItemResolver<T = unknown, S = unknown> = {\n resolve(position: number, treeRow: Gtk.TreeListRow | null): Resolved<T, S>;\n positionOfId(id: string): number;\n idOf(position: number): string | undefined;\n};\n\nexport type RowValue<T = unknown> = {\n id: string;\n value: T;\n metadata: TreeItemMetadata;\n};\n\nexport const rowIdOf = <T>(\n rowValues: WeakMap<GObject.Object, RowValue<T>>,\n row: Gtk.TreeListRow,\n): string | undefined => {\n const item = row.getItem();\n return item === null ? undefined : rowValues.get(item)?.id;\n};\n\nexport const createItemResolver = <T, S>(\n items: ItemNode<T>[] | undefined,\n flattenTreeChildren: boolean,\n rowValues: WeakMap<GObject.Object, RowValue<T>>,\n): ItemResolver<T, S> => {\n const flattened = flattenListItems(items, flattenTreeChildren);\n return {\n positionOfId(id: string): number {\n const position = flattened.idToPosition.get(id);\n return position === undefined ? -1 : position;\n },\n idOf(position: number): string | undefined {\n return flattened.positionToId.get(position);\n },\n resolve(position: number, treeRow: Gtk.TreeListRow | null): Resolved<T, S> {\n if (treeRow !== null && !flattenTreeChildren) {\n const rowItem = treeRowItem(treeRow);\n if (rowItem !== null) {\n const tagged = rowValues.get(rowItem);\n if (tagged !== undefined) {\n return {\n value: tagged.value,\n present: true,\n isHeader: false,\n metadata: tagged.metadata,\n };\n }\n }\n }\n const record = flattened.records[position];\n if (record === undefined) {\n return {\n value: undefined,\n present: false,\n isHeader: false,\n metadata: NO_TREE_METADATA,\n };\n }\n return {\n value: record.value,\n present: true,\n isHeader: false,\n metadata: record.metadata,\n };\n },\n };\n};\n\nexport const createSectionHeaderResolver = <T, S>(sections: SectionNode<S, T>[] | undefined): ItemResolver<T, S> => {\n const valueByStart = new Map<number, S>();\n let start = 0;\n for (const section of sections ?? []) {\n valueByStart.set(start, section.value);\n start += countDescendants(section.data);\n }\n return {\n positionOfId: () => -1,\n idOf: () => undefined,\n resolve(position: number): Resolved<T, S> {\n if (!valueByStart.has(position)) {\n return { value: undefined, present: false, isHeader: true, metadata: NO_TREE_METADATA };\n }\n return {\n value: valueByStart.get(position),\n present: true,\n isHeader: true,\n metadata: NO_TREE_METADATA,\n };\n },\n };\n};\n\nexport const createTreeResolver = <T, S>(\n items: ItemNode<T>[] | undefined,\n rowValues: WeakMap<GObject.Object, RowValue<T>>,\n model: Gtk.TreeListModel,\n): ItemResolver<T, S> => {\n const base = createItemResolver<T, S>(items, false, rowValues);\n return {\n resolve: base.resolve,\n idOf: (position: number): string | undefined => {\n const row = model.getRow(position);\n return row === null ? undefined : rowIdOf(rowValues, row);\n },\n positionOfId: (id: string): number => {\n const count = model.getNItems();\n for (let position = 0; position < count; position++) {\n const row = model.getRow(position);\n if (row !== null && rowIdOf(rowValues, row) === id) return position;\n }\n return -1;\n },\n };\n};\n"]}
@@ -1,24 +0,0 @@
1
- import type { ItemNode } from "../types.js";
2
- export type TreeItemMetadata = {
3
- hideExpander: boolean;
4
- indentForDepth: boolean;
5
- indentForIcon: boolean;
6
- };
7
- type FlattenedRecord<T = unknown> = {
8
- id: string;
9
- value: T;
10
- metadata: TreeItemMetadata;
11
- };
12
- type FlattenResult<T = unknown> = {
13
- records: FlattenedRecord<T>[];
14
- idToPosition: Map<string, number>;
15
- positionToId: Map<number, string>;
16
- };
17
- export type ListStructure = "flat" | "tree";
18
- export declare const detectStructure: <T>(items: ItemNode<T>[] | undefined) => ListStructure;
19
- export declare const structuralSignature: <T>(items: ItemNode<T>[] | undefined) => string;
20
- export declare const countDescendants: <T>(items: ItemNode<T>[]) => number;
21
- export declare const treeItemMetadata: <T>(item: ItemNode<T>) => TreeItemMetadata;
22
- export declare const flattenListItems: <T>(items: ItemNode<T>[] | undefined, flattenTreeChildren: boolean) => FlattenResult<T>;
23
- export {};
24
- //# sourceMappingURL=list-item-flatten.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"list-item-flatten.d.ts","sourceRoot":"","sources":["../../src/utils/list-item-flatten.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,MAAM,gBAAgB,GAAG;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,KAAK,eAAe,CAAC,CAAC,GAAG,OAAO,IAAI;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,gBAAgB,CAAC;CAC9B,CAAC;AAEF,KAAK,aAAa,CAAC,CAAC,GAAG,OAAO,IAAI;IAC9B,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,KAAG,aAMrE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,KAAG,MAczE,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAG,MAO1D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,CAAC,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAG,gBAItD,CAAC;AAgBH,eAAO,MAAM,gBAAgB,GAAI,CAAC,SACvB,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,uBACX,OAAO,KAC7B,aAAa,CAAC,CAAC,CAWjB,CAAC"}
@@ -1,68 +0,0 @@
1
- export const detectStructure = (items) => {
2
- if (items === undefined)
3
- return "flat";
4
- for (const item of items) {
5
- if (item.children !== undefined && item.children.length > 0)
6
- return "tree";
7
- }
8
- return "flat";
9
- };
10
- export const structuralSignature = (items) => {
11
- if (items === undefined)
12
- return "";
13
- const parts = [];
14
- const walk = (list) => {
15
- parts.push("[");
16
- for (const item of list) {
17
- const hidden = item.hideExpander === true;
18
- parts.push(`${item.id}|${hidden ? 1 : 0}`);
19
- if (item.children !== undefined && item.children.length > 0)
20
- walk(item.children);
21
- }
22
- parts.push("]");
23
- };
24
- walk(items);
25
- return parts.join(",");
26
- };
27
- export const countDescendants = (items) => {
28
- let total = 0;
29
- for (const item of items) {
30
- total += 1;
31
- if (item.children !== undefined && item.children.length > 0)
32
- total += countDescendants(item.children);
33
- }
34
- return total;
35
- };
36
- export const treeItemMetadata = (item) => ({
37
- hideExpander: item.hideExpander ?? false,
38
- indentForDepth: item.indentForDepth ?? true,
39
- indentForIcon: item.indentForIcon ?? true,
40
- });
41
- const appendRecord = (item, result, includeChildren) => {
42
- const position = result.records.length;
43
- result.idToPosition.set(item.id, position);
44
- result.positionToId.set(position, item.id);
45
- result.records.push({
46
- id: item.id,
47
- value: item.value,
48
- metadata: treeItemMetadata(item),
49
- });
50
- if (includeChildren && item.children !== undefined) {
51
- for (const child of item.children)
52
- appendRecord(child, result, includeChildren);
53
- }
54
- };
55
- export const flattenListItems = (items, flattenTreeChildren) => {
56
- const result = {
57
- records: [],
58
- idToPosition: new Map(),
59
- positionToId: new Map(),
60
- };
61
- if (items === undefined)
62
- return result;
63
- for (const item of items) {
64
- appendRecord(item, result, flattenTreeChildren);
65
- }
66
- return result;
67
- };
68
- //# sourceMappingURL=list-item-flatten.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"list-item-flatten.js","sourceRoot":"","sources":["../../src/utils/list-item-flatten.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,KAAgC,EAAiB,EAAE;IAClF,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,MAAM,CAAC;IAC/E,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAI,KAAgC,EAAU,EAAE;IAC/E,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,CAAC,IAAmB,EAAQ,EAAE;QACvC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3C,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrF,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,CAAC;IACF,IAAI,CAAC,KAAK,CAAC,CAAC;IACZ,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAI,KAAoB,EAAU,EAAE;IAChE,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,KAAK,IAAI,CAAC,CAAC;QACX,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1G,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAI,IAAiB,EAAoB,EAAE,CAAC,CAAC;IACzE,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,KAAK;IACxC,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI;IAC3C,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI;CAC5C,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,CAAI,IAAiB,EAAE,MAAwB,EAAE,eAAwB,EAAQ,EAAE;IACpG,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;IACvC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC3C,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;QAChB,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC;KACnC,CAAC,CAAC;IACH,IAAI,eAAe,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACjD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;YAAE,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IACpF,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC5B,KAAgC,EAChC,mBAA4B,EACZ,EAAE;IAClB,MAAM,MAAM,GAAqB;QAC7B,OAAO,EAAE,EAAE;QACX,YAAY,EAAE,IAAI,GAAG,EAAE;QACvB,YAAY,EAAE,IAAI,GAAG,EAAE;KAC1B,CAAC;IACF,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC","sourcesContent":["import type { ItemNode } from \"../types.js\";\n\nexport type TreeItemMetadata = {\n hideExpander: boolean;\n indentForDepth: boolean;\n indentForIcon: boolean;\n};\n\ntype FlattenedRecord<T = unknown> = {\n id: string;\n value: T;\n metadata: TreeItemMetadata;\n};\n\ntype FlattenResult<T = unknown> = {\n records: FlattenedRecord<T>[];\n idToPosition: Map<string, number>;\n positionToId: Map<number, string>;\n};\n\nexport type ListStructure = \"flat\" | \"tree\";\n\nexport const detectStructure = <T>(items: ItemNode<T>[] | undefined): ListStructure => {\n if (items === undefined) return \"flat\";\n for (const item of items) {\n if (item.children !== undefined && item.children.length > 0) return \"tree\";\n }\n return \"flat\";\n};\n\nexport const structuralSignature = <T>(items: ItemNode<T>[] | undefined): string => {\n if (items === undefined) return \"\";\n const parts: string[] = [];\n const walk = (list: ItemNode<T>[]): void => {\n parts.push(\"[\");\n for (const item of list) {\n const hidden = item.hideExpander === true;\n parts.push(`${item.id}|${hidden ? 1 : 0}`);\n if (item.children !== undefined && item.children.length > 0) walk(item.children);\n }\n parts.push(\"]\");\n };\n walk(items);\n return parts.join(\",\");\n};\n\nexport const countDescendants = <T>(items: ItemNode<T>[]): number => {\n let total = 0;\n for (const item of items) {\n total += 1;\n if (item.children !== undefined && item.children.length > 0) total += countDescendants(item.children);\n }\n return total;\n};\n\nexport const treeItemMetadata = <T>(item: ItemNode<T>): TreeItemMetadata => ({\n hideExpander: item.hideExpander ?? false,\n indentForDepth: item.indentForDepth ?? true,\n indentForIcon: item.indentForIcon ?? true,\n});\n\nconst appendRecord = <T>(item: ItemNode<T>, result: FlattenResult<T>, includeChildren: boolean): void => {\n const position = result.records.length;\n result.idToPosition.set(item.id, position);\n result.positionToId.set(position, item.id);\n result.records.push({\n id: item.id,\n value: item.value,\n metadata: treeItemMetadata(item),\n });\n if (includeChildren && item.children !== undefined) {\n for (const child of item.children) appendRecord(child, result, includeChildren);\n }\n};\n\nexport const flattenListItems = <T>(\n items: ItemNode<T>[] | undefined,\n flattenTreeChildren: boolean,\n): FlattenResult<T> => {\n const result: FlattenResult<T> = {\n records: [],\n idToPosition: new Map(),\n positionToId: new Map(),\n };\n if (items === undefined) return result;\n for (const item of items) {\n appendRecord(item, result, flattenTreeChildren);\n }\n return result;\n};\n"]}
package/src/cell.tsx DELETED
@@ -1,144 +0,0 @@
1
- import type * as GObject from "@gtkx/gi/gobject";
2
- import type * as Gtk from "@gtkx/gi/gtk";
3
- import { GtkTreeExpander } from "@gtkx/jsx/gtk";
4
- import { createPortal } from "@gtkx/react";
5
- import { Fragment, memo, type ReactNode, useCallback, useSyncExternalStore } from "react";
6
- import type { RenderItemProps } from "./types.js";
7
- import type { CellContainerStore, CellEntry } from "./utils/cell-container-store.js";
8
- import type { ItemResolver } from "./utils/item-resolver.js";
9
- import type { TreeItemMetadata } from "./utils/list-item-flatten.js";
10
-
11
- export type CellRenderer<T, S> = (
12
- value: T | S | undefined,
13
- treeRow: Gtk.TreeListRow | null,
14
- position: number,
15
- ) => ReactNode;
16
-
17
- interface CellProps<T, S> {
18
- container: GObject.Object;
19
- store: CellContainerStore;
20
- resolver: ItemResolver<T, S>;
21
- render: CellRenderer<T, S>;
22
- }
23
-
24
- interface CellRenderHostProps<T, S> {
25
- store: CellContainerStore;
26
- resolver: ItemResolver<T, S>;
27
- render: CellRenderer<T, S>;
28
- }
29
-
30
- interface TreeExpanderCellProps {
31
- treeRow: Gtk.TreeListRow;
32
- metadata: TreeItemMetadata;
33
- children: ReactNode;
34
- }
35
-
36
- const TreeExpanderCell = ({ treeRow, metadata, children }: TreeExpanderCellProps): ReactNode => (
37
- <GtkTreeExpander
38
- ref={(expander: Gtk.TreeExpander | null) => {
39
- if (expander !== null) expander.setListRow(treeRow);
40
- }}
41
- hideExpander={metadata.hideExpander}
42
- indentForDepth={metadata.indentForDepth}
43
- indentForIcon={metadata.indentForIcon}
44
- >
45
- {children}
46
- </GtkTreeExpander>
47
- );
48
-
49
- const Cell = memo(<T, S>({ container, store, resolver, render }: CellProps<T, S>): ReactNode => {
50
- const subscribe = useCallback(
51
- (onChange: () => void) => store.subscribePosition(container, onChange),
52
- [store, container],
53
- );
54
- const getSnapshot = useCallback((): CellEntry => store.getPosition(container), [store, container]);
55
- const entry = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
56
-
57
- if (entry.position < 0) return null;
58
- const resolved = resolver.resolve(entry.position, entry.treeRow);
59
- if (!resolved.present) return null;
60
- const content = render(resolved.value, entry.treeRow, entry.position);
61
- const portalled =
62
- entry.treeRow !== null && !resolved.isHeader ? (
63
- <TreeExpanderCell treeRow={entry.treeRow} metadata={resolved.metadata}>
64
- {content}
65
- </TreeExpanderCell>
66
- ) : (
67
- content
68
- );
69
- return createPortal(portalled, container, store.keyFor(container));
70
- }) as <T, S>(props: CellProps<T, S>) => ReactNode;
71
-
72
- export const CellRenderHost = <T, S>({ store, resolver, render }: CellRenderHostProps<T, S>): ReactNode => {
73
- const containers = useSyncExternalStore(
74
- store.subscribeSet,
75
- store.getContainersSnapshot,
76
- store.getContainersSnapshot,
77
- );
78
- return (
79
- <Fragment>
80
- {containers.map((container) => (
81
- <Cell
82
- key={store.keyFor(container)}
83
- container={container}
84
- store={store}
85
- resolver={resolver}
86
- render={render}
87
- />
88
- ))}
89
- </Fragment>
90
- );
91
- };
92
-
93
- export type TreeRenderContext = {
94
- controlled: boolean;
95
- expandedIds: Set<string>;
96
- rowId: (row: Gtk.TreeListRow) => string | undefined;
97
- };
98
-
99
- export const createTreeRenderContext = (
100
- expandedIds: string[] | null | undefined,
101
- rowId: (row: Gtk.TreeListRow) => string | undefined,
102
- ): TreeRenderContext => ({
103
- controlled: expandedIds !== undefined && expandedIds !== null,
104
- expandedIds: new Set(expandedIds ?? []),
105
- rowId,
106
- });
107
-
108
- const treeFields = (
109
- treeRow: Gtk.TreeListRow | null,
110
- context: TreeRenderContext | undefined,
111
- ): { depth?: number; isExpanded?: boolean } => {
112
- if (treeRow === null) return {};
113
- const depth = treeRow.getDepth();
114
- if (context === undefined || !treeRow.isExpandable()) return { depth };
115
- const isExpanded = context.controlled
116
- ? context.expandedIds.has(context.rowId(treeRow) ?? "")
117
- : treeRow.getExpanded();
118
- return { depth, isExpanded };
119
- };
120
-
121
- export const itemRenderer =
122
- <T, S>(render: (props: RenderItemProps<T>) => ReactNode, context?: TreeRenderContext): CellRenderer<T, S> =>
123
- (value, treeRow, position) =>
124
- render({ item: value as T, index: position, ...treeFields(treeRow, context) });
125
-
126
- const headerRenderer =
127
- <T, S>(renderHeader: ((info: { section: S }) => ReactNode) | null | undefined): CellRenderer<T, S> =>
128
- (value) =>
129
- renderHeader ? renderHeader({ section: value as S }) : null;
130
-
131
- interface HeaderRenderHostProps<T, S> {
132
- useHeader: boolean;
133
- store: CellContainerStore;
134
- resolver: ItemResolver<T, S>;
135
- renderHeader: ((info: { section: S }) => ReactNode) | null | undefined;
136
- }
137
-
138
- export const HeaderRenderHost = <T, S>({
139
- useHeader,
140
- store,
141
- resolver,
142
- renderHeader,
143
- }: HeaderRenderHostProps<T, S>): ReactNode =>
144
- useHeader ? <CellRenderHost store={store} resolver={resolver} render={headerRenderer<T, S>(renderHeader)} /> : null;
@@ -1,82 +0,0 @@
1
- import type * as Gtk from "@gtkx/gi/gtk";
2
- import { GtkColumnViewColumn, type GtkColumnViewColumnProps } from "@gtkx/jsx/gtk";
3
- import { useMergeRefs } from "@gtkx/react/internal";
4
- import { type ReactNode, useLayoutEffect, useRef, useState } from "react";
5
- import { type CellRenderer, CellRenderHost, itemRenderer, type TreeRenderContext } from "./cell.js";
6
- import { makeFactoryInstaller, useCellContainers } from "./hooks/use-cell-containers.js";
7
- import { useHeaderMenu } from "./hooks/use-header-menu.js";
8
- import type { RenderItemProps } from "./types.js";
9
- import type { ItemResolver } from "./utils/item-resolver.js";
10
-
11
- const factoryInstaller = makeFactoryInstaller<Gtk.ColumnViewColumn>((column, factory) => column.setFactory(factory));
12
-
13
- export type ColumnDefDeclarativeProps<T = unknown> = {
14
- title: string;
15
- expand?: boolean | undefined;
16
- resizable?: boolean | undefined;
17
- fixedWidth?: number | undefined;
18
- id: string;
19
- sortable?: boolean | undefined;
20
- visible?: boolean | undefined;
21
- renderCell: (props: RenderItemProps<T>) => ReactNode;
22
- headerMenu?: ReactNode;
23
- };
24
-
25
- export type ColumnDef<T = unknown> = Omit<GtkColumnViewColumnProps, "factory" | "sorter"> &
26
- ColumnDefDeclarativeProps<T>;
27
-
28
- type ColumnViewColumnProps<T = unknown> = ColumnDef<T> & {
29
- resolver: ItemResolver<unknown, unknown>;
30
- tree: TreeRenderContext;
31
- estimatedItemHeight?: number | undefined;
32
- onInstance: (id: string, column: Gtk.ColumnViewColumn | null) => void;
33
- };
34
-
35
- export const ColumnViewColumn = <T = unknown>(props: ColumnViewColumnProps<T>): ReactNode => {
36
- const {
37
- id,
38
- title,
39
- sortable,
40
- renderCell,
41
- headerMenu,
42
- resolver,
43
- tree,
44
- estimatedItemHeight,
45
- onInstance,
46
- ref,
47
- ...intrinsicProps
48
- } = props as ColumnViewColumnProps<T> & { [key: string]: unknown };
49
- const [column, setColumn] = useState<Gtk.ColumnViewColumn | null>(null);
50
-
51
- const captureColumn = useMergeRefs<Gtk.ColumnViewColumn>(ref, setColumn);
52
-
53
- const store = useCellContainers<Gtk.ColumnViewColumn>({
54
- object: column,
55
- installer: factoryInstaller,
56
- estimatedHeight: estimatedItemHeight,
57
- });
58
-
59
- const onInstanceRef = useRef(onInstance);
60
- onInstanceRef.current = onInstance;
61
-
62
- useLayoutEffect(() => {
63
- if (column === null) return;
64
- onInstanceRef.current(id, column);
65
- return () => onInstanceRef.current(id, null);
66
- }, [column, id]);
67
-
68
- const headerMenuPortal = useHeaderMenu(column, headerMenu);
69
-
70
- const cellRenderer: CellRenderer<unknown, unknown> = itemRenderer<unknown, unknown>(
71
- (cellProps) => renderCell({ ...cellProps, item: cellProps.item as T }),
72
- tree,
73
- );
74
-
75
- return (
76
- <>
77
- <GtkColumnViewColumn {...intrinsicProps} id={id} title={title} ref={captureColumn} />
78
- <CellRenderHost store={store} resolver={resolver} render={cellRenderer} />
79
- {headerMenuPortal}
80
- </>
81
- );
82
- };
@@ -1,173 +0,0 @@
1
- import * as GObject from "@gtkx/gi/gobject";
2
- import * as Gtk from "@gtkx/gi/gtk";
3
-
4
- /**
5
- * Describes one constraint added by `<ConstraintLayout.Constraint>`, relating a
6
- * target widget attribute to a source attribute of another widget or guide.
7
- */
8
- export type ConstraintProps = {
9
- /** Name of the target widget or guide. Use "super" or omit to reference the layout's own widget. */
10
- target?: string;
11
- targetAttribute: Gtk.ConstraintAttribute;
12
- /** Relation between the target and source attributes (defaults to equality). */
13
- relation?: Gtk.ConstraintRelation;
14
- /** Name of the source widget or guide. Use "super" or omit for a constant constraint. */
15
- source?: string;
16
- sourceAttribute?: Gtk.ConstraintAttribute;
17
- /** Factor applied to the source attribute (defaults to 1). */
18
- multiplier?: number;
19
- /** Constant offset added to the relation (defaults to 0). */
20
- constant?: number;
21
- /** Constraint strength, higher values winning conflicts (defaults to required). */
22
- strength?: number;
23
- };
24
-
25
- /**
26
- * Describes an invisible spacing guide added by `<ConstraintLayout.Guide>`,
27
- * usable as a constraint target under its id.
28
- */
29
- export type ConstraintGuideProps = {
30
- /** Identifier used to reference this guide from constraints. */
31
- id: string;
32
- minWidth?: number;
33
- minHeight?: number;
34
- /** Preferred (natural) width. */
35
- natWidth?: number;
36
- /** Preferred (natural) height. */
37
- natHeight?: number;
38
- maxWidth?: number;
39
- maxHeight?: number;
40
- /** Strength of the guide's own size constraints. */
41
- strength?: Gtk.ConstraintStrength;
42
- };
43
-
44
- /**
45
- * Describes constraints authored with the Visual Format Language (VFL), applied by
46
- * `<ConstraintLayout.Vfl>`.
47
- */
48
- export type ConstraintVflProps = {
49
- /** VFL lines describing the constraints between named widgets and guides. */
50
- lines: string[];
51
- /** Default horizontal spacing used by the layout operator (defaults to 0). */
52
- hspacing?: number;
53
- /** Default vertical spacing used by the layout operator (defaults to 0). */
54
- vspacing?: number;
55
- };
56
-
57
- const SUPER_ID = "super";
58
-
59
- const unknownIdMessage = (role: string, id: string): string =>
60
- `<ConstraintLayout.Constraint> references unknown id '${id}'. ` +
61
- `Set name="${id}" on the ${role} widget, or add a <ConstraintLayout.Guide id="${id}">.`;
62
-
63
- const guideRegistry = new WeakMap<Gtk.ConstraintLayout, Map<string, Gtk.ConstraintGuide>>();
64
-
65
- const guidesFor = (layout: Gtk.ConstraintLayout): Map<string, Gtk.ConstraintGuide> => {
66
- let map = guideRegistry.get(layout);
67
- if (!map) {
68
- map = new Map<string, Gtk.ConstraintGuide>();
69
- guideRegistry.set(layout, map);
70
- }
71
- return map;
72
- };
73
-
74
- const explicitWidgetName = (widget: Gtk.Widget): string | null => {
75
- const value = new GObject.Value();
76
- value.init(GObject.TYPE_STRING);
77
- widget.getProperty("name", value);
78
- const name = value.getString();
79
- return name !== null && name.length > 0 ? name : null;
80
- };
81
-
82
- function* namedChildren(layout: Gtk.ConstraintLayout): Generator<[string, Gtk.Widget]> {
83
- const host = layout.getWidget();
84
- if (!host) return;
85
- for (let child = host.getFirstChild(); child; child = child.getNextSibling()) {
86
- const name = explicitWidgetName(child);
87
- if (name !== null) yield [name, child];
88
- }
89
- }
90
-
91
- const findChildByName = (layout: Gtk.ConstraintLayout, id: string): Gtk.Widget | undefined => {
92
- for (const [name, child] of namedChildren(layout)) {
93
- if (name === id) return child;
94
- }
95
- return undefined;
96
- };
97
-
98
- const resolveConstraintTarget = (
99
- layout: Gtk.ConstraintLayout,
100
- id: string | undefined,
101
- ): Gtk.ConstraintTarget | null | undefined => {
102
- if (id === undefined || id === SUPER_ID) return null;
103
- return findChildByName(layout, id) ?? guidesFor(layout).get(id);
104
- };
105
-
106
- const constraintViews = (layout: Gtk.ConstraintLayout): Map<string, Gtk.ConstraintTarget> => {
107
- const views = new Map<string, Gtk.ConstraintTarget>();
108
- for (const [name, child] of namedChildren(layout)) views.set(name, child);
109
- for (const [name, guide] of guidesFor(layout)) {
110
- if (!views.has(name)) views.set(name, guide);
111
- }
112
- return views;
113
- };
114
-
115
- const isLayoutLive = (layout: Gtk.ConstraintLayout): boolean => layout.getWidget() !== null;
116
-
117
- export function applyConstraint(layout: Gtk.ConstraintLayout, props: ConstraintProps): () => void {
118
- const target = resolveConstraintTarget(layout, props.target);
119
- if (target === undefined) throw new Error(unknownIdMessage("target", String(props.target)));
120
- const source = resolveConstraintTarget(layout, props.source);
121
- if (source === undefined) throw new Error(unknownIdMessage("source", String(props.source)));
122
-
123
- const constraint = new Gtk.Constraint({
124
- target,
125
- targetAttribute: props.targetAttribute,
126
- relation: props.relation ?? Gtk.ConstraintRelation.EQ,
127
- source,
128
- sourceAttribute: props.sourceAttribute ?? Gtk.ConstraintAttribute.NONE,
129
- multiplier: props.multiplier ?? 1,
130
- constant: props.constant ?? 0,
131
- strength: props.strength ?? Gtk.ConstraintStrength.REQUIRED,
132
- });
133
- layout.addConstraint(constraint);
134
-
135
- return () => {
136
- if (isLayoutLive(layout)) layout.removeConstraint(constraint);
137
- };
138
- }
139
-
140
- export function applyVfl(layout: Gtk.ConstraintLayout, props: ConstraintVflProps): () => void {
141
- const views = constraintViews(layout);
142
- const constraints = layout.addConstraintsFromDescription(
143
- props.lines,
144
- props.hspacing ?? 0,
145
- props.vspacing ?? 0,
146
- views,
147
- );
148
-
149
- return () => {
150
- if (!isLayoutLive(layout)) return;
151
- for (const constraint of constraints) layout.removeConstraint(constraint);
152
- };
153
- }
154
-
155
- export function applyGuide(layout: Gtk.ConstraintLayout, props: ConstraintGuideProps): () => void {
156
- const guide = new Gtk.ConstraintGuide({
157
- name: props.id,
158
- minWidth: props.minWidth,
159
- minHeight: props.minHeight,
160
- natWidth: props.natWidth,
161
- natHeight: props.natHeight,
162
- maxWidth: props.maxWidth,
163
- maxHeight: props.maxHeight,
164
- strength: props.strength,
165
- });
166
- layout.addGuide(guide);
167
- guidesFor(layout).set(props.id, guide);
168
-
169
- return () => {
170
- guidesFor(layout).delete(props.id);
171
- if (isLayoutLive(layout)) layout.removeGuide(guide);
172
- };
173
- }