@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
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ComboRowProps } from "./types.js";
3
+ type ComboRowComponent = <T = unknown, S = unknown>(props: ComboRowProps<T, S>) => ReactNode;
4
+ /**
5
+ * Renders an `Adw.ComboRow` backed by a collection model, presenting the same choice as a
6
+ * `DropDown` in the shape of a preferences row, with customizable renderers for the row
7
+ * display, popup rows, and popup section headers, and controlled selection.
8
+ */
9
+ declare const ComboRow: ComboRowComponent;
10
+ export { ComboRow };
11
+ //# sourceMappingURL=combo-row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combo-row.d.ts","sourceRoot":"","sources":["../../src/adw/combo-row.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,KAAK,iBAAiB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;AAE7F;;;;GAIG;AACH,QAAA,MAAM,QAAQ,EAAE,iBAAqD,CAAC;AAMtE,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { AdwComboRow } from "@gtkx/jsx/adw";
3
+ import { DropDownBase } from "../internal/drop-down.js";
4
+ /**
5
+ * Renders an `Adw.ComboRow` backed by a collection model, presenting the same choice as a
6
+ * `DropDown` in the shape of a preferences row, with customizable renderers for the row
7
+ * display, popup rows, and popup section headers, and controlled selection.
8
+ */
9
+ const ComboRow = ComboRowImpl;
10
+ function ComboRowImpl(props) {
11
+ return _jsx(DropDownBase, { ...props, component: AdwComboRow });
12
+ }
13
+ export { ComboRow };
14
+ //# sourceMappingURL=combo-row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combo-row.js","sourceRoot":"","sources":["../../src/adw/combo-row.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIxD;;;;GAIG;AACH,MAAM,QAAQ,GAAsB,YAAiC,CAAC;AAEtE,SAAS,YAAY,CAAC,KAAwB;IAC1C,OAAO,KAAC,YAAY,OAAK,KAAK,EAAE,SAAS,EAAE,WAAW,GAAI,CAAC;AAC/D,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\nimport { AdwComboRow } from \"@gtkx/jsx/adw\";\nimport type { DropDownBaseProps } from \"../internal/drop-down.js\";\nimport type { ComboRowProps } from \"./types.js\";\nimport { DropDownBase } from \"../internal/drop-down.js\";\n\ntype ComboRowComponent = <T = unknown, S = unknown>(props: ComboRowProps<T, S>) => ReactNode;\n\n/**\n * Renders an `Adw.ComboRow` backed by a collection model, presenting the same choice as a\n * `DropDown` in the shape of a preferences row, with customizable renderers for the row\n * display, popup rows, and popup section headers, and controlled selection.\n */\nconst ComboRow: ComboRowComponent = ComboRowImpl as ComboRowComponent;\n\nfunction ComboRowImpl(props: DropDownBaseProps): ReactNode {\n return <DropDownBase {...props} component={AdwComboRow} />;\n}\n\nexport { ComboRow };\n"]}
@@ -0,0 +1,4 @@
1
+ export { ComboRow } from "./combo-row.js";
2
+ export { ToastProvider, useToast, useToastOverlay } from "./toast.js";
3
+ export type { ComboRowProps, ToastController, ToastOptions, ToastOverlayController, ToastProviderProps, } from "./types.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adw/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACtE,YAAY,EACR,aAAa,EACb,eAAe,EACf,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,GACrB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ComboRow } from "./combo-row.js";
2
+ export { ToastProvider, useToast, useToastOverlay } from "./toast.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adw/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC","sourcesContent":["export { ComboRow } from \"./combo-row.js\";\nexport { ToastProvider, useToast, useToastOverlay } from \"./toast.js\";\nexport type {\n ComboRowProps,\n ToastController,\n ToastOptions,\n ToastOverlayController,\n ToastProviderProps,\n} from \"./types.js\";\n"]}
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ToastController, ToastOverlayController, ToastProviderProps } from "./types.js";
3
+ /** Shares an Adw.ToastOverlay reference with the toast hooks in every descendant. */
4
+ declare function ToastProvider(props: ToastProviderProps): ReactNode;
5
+ /** Returns a {@link ToastController} that shows and dismisses toasts on the nearest provider's overlay. */
6
+ declare function useToast(): ToastController;
7
+ /** Returns a {@link ToastOverlayController} for the nearest provider's overlay as a whole. */
8
+ declare function useToastOverlay(): ToastOverlayController;
9
+ export { ToastProvider, useToast, useToastOverlay };
10
+ //# sourceMappingURL=toast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../src/adw/toast.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,OAAO,CAAC;AAGlD,OAAO,KAAK,EAAE,eAAe,EAAgB,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA+B5G,qFAAqF;AACrF,iBAAS,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAE3D;AAED,2GAA2G;AAC3G,iBAAS,QAAQ,IAAI,eAAe,CAiBnC;AAED,8FAA8F;AAC9F,iBAAS,eAAe,IAAI,sBAAsB,CAWjD;AAED,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as Adw from "@gtkx/gi/adw";
3
+ import { createContext, useContext, useMemo } from "react";
4
+ const ToastContext = createContext(null);
5
+ const useOverlayRef = () => {
6
+ const overlayRef = useContext(ToastContext);
7
+ if (overlayRef === null) {
8
+ throw new Error("useToast and useToastOverlay must be used within a ToastProvider");
9
+ }
10
+ return overlayRef;
11
+ };
12
+ const buildToast = (options) => {
13
+ const { onButtonClicked, onDismissed, ...props } = options;
14
+ const toast = new Adw.Toast(props);
15
+ if (onButtonClicked != null) {
16
+ toast.on("button-clicked", onButtonClicked);
17
+ }
18
+ if (onDismissed != null) {
19
+ toast.on("dismissed", onDismissed);
20
+ }
21
+ return toast;
22
+ };
23
+ /** Shares an Adw.ToastOverlay reference with the toast hooks in every descendant. */
24
+ function ToastProvider(props) {
25
+ return _jsx(ToastContext.Provider, { value: props.overlayRef, children: props.children });
26
+ }
27
+ /** Returns a {@link ToastController} that shows and dismisses toasts on the nearest provider's overlay. */
28
+ function useToast() {
29
+ const overlayRef = useOverlayRef();
30
+ return useMemo(() => ({
31
+ show: (options) => {
32
+ const toast = buildToast(options ?? {});
33
+ overlayRef.current?.addToast(toast);
34
+ return toast;
35
+ },
36
+ dismiss: (toast) => {
37
+ toast.dismiss();
38
+ },
39
+ }), [overlayRef]);
40
+ }
41
+ /** Returns a {@link ToastOverlayController} for the nearest provider's overlay as a whole. */
42
+ function useToastOverlay() {
43
+ const overlayRef = useOverlayRef();
44
+ return useMemo(() => ({
45
+ dismissAll: () => {
46
+ overlayRef.current?.dismissAll();
47
+ },
48
+ }), [overlayRef]);
49
+ }
50
+ export { ToastProvider, useToast, useToastOverlay };
51
+ //# sourceMappingURL=toast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast.js","sourceRoot":"","sources":["../../src/adw/toast.tsx"],"names":[],"mappings":";AACA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAK3D,MAAM,YAAY,GAAG,aAAa,CAAoB,IAAI,CAAC,CAAC;AAE5D,MAAM,aAAa,GAAG,GAAe,EAAE;IACnC,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IAE5C,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,OAAqB,EAAa,EAAE;IACpD,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAEnC,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;QACtB,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,qFAAqF;AACrF,SAAS,aAAa,CAAC,KAAyB;IAC5C,OAAO,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,CAAC,UAAU,YAAG,KAAK,CAAC,QAAQ,GAAyB,CAAC;AACpG,CAAC;AAED,2GAA2G;AAC3G,SAAS,QAAQ;IACb,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,OAAO,OAAO,CACV,GAAG,EAAE,CAAC,CAAC;QACH,IAAI,EAAE,CAAC,OAAsB,EAAE,EAAE;YAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YACxC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;YAEpC,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC,KAAgB,EAAE,EAAE;YAC1B,KAAK,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;KACJ,CAAC,EACF,CAAC,UAAU,CAAC,CACf,CAAC;AACN,CAAC;AAED,8FAA8F;AAC9F,SAAS,eAAe;IACpB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,OAAO,OAAO,CACV,GAAG,EAAE,CAAC,CAAC;QACH,UAAU,EAAE,GAAG,EAAE;YACb,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;QACrC,CAAC;KACJ,CAAC,EACF,CAAC,UAAU,CAAC,CACf,CAAC;AACN,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC","sourcesContent":["import type { ReactNode, RefObject } from \"react\";\nimport * as Adw from \"@gtkx/gi/adw\";\nimport { createContext, useContext, useMemo } from \"react\";\nimport type { ToastController, ToastOptions, ToastOverlayController, ToastProviderProps } from \"./types.js\";\n\ntype OverlayRef = RefObject<Adw.ToastOverlay | null>;\n\nconst ToastContext = createContext<OverlayRef | null>(null);\n\nconst useOverlayRef = (): OverlayRef => {\n const overlayRef = useContext(ToastContext);\n\n if (overlayRef === null) {\n throw new Error(\"useToast and useToastOverlay must be used within a ToastProvider\");\n }\n\n return overlayRef;\n};\n\nconst buildToast = (options: ToastOptions): Adw.Toast => {\n const { onButtonClicked, onDismissed, ...props } = options;\n const toast = new Adw.Toast(props);\n\n if (onButtonClicked != null) {\n toast.on(\"button-clicked\", onButtonClicked);\n }\n\n if (onDismissed != null) {\n toast.on(\"dismissed\", onDismissed);\n }\n\n return toast;\n};\n\n/** Shares an Adw.ToastOverlay reference with the toast hooks in every descendant. */\nfunction ToastProvider(props: ToastProviderProps): ReactNode {\n return <ToastContext.Provider value={props.overlayRef}>{props.children}</ToastContext.Provider>;\n}\n\n/** Returns a {@link ToastController} that shows and dismisses toasts on the nearest provider's overlay. */\nfunction useToast(): ToastController {\n const overlayRef = useOverlayRef();\n\n return useMemo<ToastController>(\n () => ({\n show: (options?: ToastOptions) => {\n const toast = buildToast(options ?? {});\n overlayRef.current?.addToast(toast);\n\n return toast;\n },\n dismiss: (toast: Adw.Toast) => {\n toast.dismiss();\n },\n }),\n [overlayRef],\n );\n}\n\n/** Returns a {@link ToastOverlayController} for the nearest provider's overlay as a whole. */\nfunction useToastOverlay(): ToastOverlayController {\n const overlayRef = useOverlayRef();\n\n return useMemo<ToastOverlayController>(\n () => ({\n dismissAll: () => {\n overlayRef.current?.dismissAll();\n },\n }),\n [overlayRef],\n );\n}\n\nexport { ToastProvider, useToast, useToastOverlay };\n"]}
@@ -0,0 +1,35 @@
1
+ import type * as Adw from "@gtkx/gi/adw";
2
+ import type { AdwComboRowProps, AdwToastProps } from "@gtkx/jsx/adw";
3
+ import type { ReactNode, RefObject } from "react";
4
+ import type { DropDownWidgetProps } from "../types.js";
5
+ /**
6
+ * Props for {@link ComboRow}. Combines the underlying Adw.ComboRow props with the declarative
7
+ * collection props: flat items or grouped sections, controlled single selection, and renderers
8
+ * for the row display, popup rows, and popup section headers.
9
+ */
10
+ type ComboRowProps<T = unknown, S = unknown> = DropDownWidgetProps<AdwComboRowProps, T, S>;
11
+ /**
12
+ * Describes a toast raised through {@link useToast}: the construct-time properties of an
13
+ * `Adw.Toast` plus its `button-clicked` and `dismissed` handlers.
14
+ */
15
+ type ToastOptions = Adw.ToastConstructorProps & Pick<AdwToastProps, "onButtonClicked" | "onDismissed">;
16
+ /** Imperative controls for individual toasts, returned by {@link useToast}. */
17
+ type ToastController = {
18
+ /** Builds a toast, shows it through the overlay, and returns it. */
19
+ show: (options?: ToastOptions) => Adw.Toast;
20
+ /** Dismisses a single toast, typically one returned by {@link ToastController.show}. */
21
+ dismiss: (toast: Adw.Toast) => void;
22
+ };
23
+ /** Imperative controls for the overlay as a whole, returned by {@link useToastOverlay}. */
24
+ type ToastOverlayController = {
25
+ /** Dismisses the shown toast and every queued one. */
26
+ dismissAll: () => void;
27
+ };
28
+ /** Props for {@link ToastProvider}. */
29
+ type ToastProviderProps = {
30
+ /** Ref also given to the `AdwToastOverlay` the toasts appear over. */
31
+ overlayRef: RefObject<Adw.ToastOverlay | null>;
32
+ children?: ReactNode | undefined;
33
+ };
34
+ export { type ComboRowProps, type ToastOptions, type ToastController, type ToastOverlayController, type ToastProviderProps, };
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adw/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD;;;;GAIG;AACH,KAAK,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI,mBAAmB,CAAC,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3F;;;GAGG;AACH,KAAK,YAAY,GAAG,GAAG,CAAC,qBAAqB,GAAG,IAAI,CAAC,aAAa,EAAE,iBAAiB,GAAG,aAAa,CAAC,CAAC;AAEvG,+EAA+E;AAC/E,KAAK,eAAe,GAAG;IACnB,oEAAoE;IACpE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,GAAG,CAAC,KAAK,CAAC;IAC5C,wFAAwF;IACxF,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,2FAA2F;AAC3F,KAAK,sBAAsB,GAAG;IAC1B,sDAAsD;IACtD,UAAU,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;AAEF,uCAAuC;AACvC,KAAK,kBAAkB,GAAG;IACtB,sEAAsE;IACtE,UAAU,EAAE,SAAS,CAAC,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC/C,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACpC,CAAC;AAEF,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,GAC1B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adw/types.ts"],"names":[],"mappings":"AAsCA,OAAO,EAMN,CAAC","sourcesContent":["import type * as Adw from \"@gtkx/gi/adw\";\nimport type { AdwComboRowProps, AdwToastProps } from \"@gtkx/jsx/adw\";\nimport type { ReactNode, RefObject } from \"react\";\nimport type { DropDownWidgetProps } from \"../types.js\";\n\n/**\n * Props for {@link ComboRow}. Combines the underlying Adw.ComboRow props with the declarative\n * collection props: flat items or grouped sections, controlled single selection, and renderers\n * for the row display, popup rows, and popup section headers.\n */\ntype ComboRowProps<T = unknown, S = unknown> = DropDownWidgetProps<AdwComboRowProps, T, S>;\n/**\n * Describes a toast raised through {@link useToast}: the construct-time properties of an\n * `Adw.Toast` plus its `button-clicked` and `dismissed` handlers.\n */\ntype ToastOptions = Adw.ToastConstructorProps & Pick<AdwToastProps, \"onButtonClicked\" | \"onDismissed\">;\n\n/** Imperative controls for individual toasts, returned by {@link useToast}. */\ntype ToastController = {\n /** Builds a toast, shows it through the overlay, and returns it. */\n show: (options?: ToastOptions) => Adw.Toast;\n /** Dismisses a single toast, typically one returned by {@link ToastController.show}. */\n dismiss: (toast: Adw.Toast) => void;\n};\n\n/** Imperative controls for the overlay as a whole, returned by {@link useToastOverlay}. */\ntype ToastOverlayController = {\n /** Dismisses the shown toast and every queued one. */\n dismissAll: () => void;\n};\n\n/** Props for {@link ToastProvider}. */\ntype ToastProviderProps = {\n /** Ref also given to the `AdwToastOverlay` the toasts appear over. */\n overlayRef: RefObject<Adw.ToastOverlay | null>;\n children?: ReactNode | undefined;\n};\n\nexport {\n type ComboRowProps,\n type ToastOptions,\n type ToastController,\n type ToastOverlayController,\n type ToastProviderProps,\n};\n"]}
@@ -1,32 +1,10 @@
1
- import type * as Gtk from "@gtkx/gi/gtk";
2
- import { type GtkColumnViewProps } from "@gtkx/jsx/gtk";
3
- import { type ReactNode } from "react";
4
- import { type ColumnDef } from "./column-view-column.js";
5
- import type { CollectionItemSizeProps, ControlledExpansionProps, ControlledSelectionProps, ItemNode, SectionNode } from "./types.js";
6
- export type { ColumnDef, ColumnDefDeclarativeProps } from "./column-view-column.js";
7
- export type ColumnViewSortProps = {
8
- sortColumn?: string | null | undefined;
9
- sortOrder?: Gtk.SortType | null | undefined;
10
- onSortChanged?: ((column: string | null, order: Gtk.SortType) => void) | null | undefined;
11
- };
12
- export type ColumnViewDeclarativeProps<T = unknown, S = unknown> = ColumnViewSortProps & Omit<CollectionItemSizeProps, "estimatedItemWidth"> & ControlledSelectionProps & ControlledExpansionProps & {
13
- items?: ItemNode<T>[] | undefined;
14
- sections?: SectionNode<S, T>[] | undefined;
15
- renderHeader?: ((info: {
16
- section: S;
17
- }) => ReactNode) | null | undefined;
18
- columns: ColumnDef<T>[];
19
- };
1
+ import type { ReactNode } from "react";
2
+ import type { ColumnViewProps } from "./types.js";
20
3
  /**
21
- * Props for {@link ColumnView}. Combines the underlying Gtk.ColumnView props with
22
- * declarative collection props: flat items or grouped sections, controlled selection
23
- * and expansion, sorting (sortColumn, sortOrder, onSortChanged), an optional section
24
- * header renderer, and the columns to render.
4
+ * Renders a Gtk.ColumnView from declarative items or sections and a columns array,
5
+ * with controlled selection, expansion, and sorting, per-column header menus, and
6
+ * section header rendering.
25
7
  */
26
- export type ColumnViewProps<T = unknown, S = unknown> = Omit<GtkColumnViewProps, "columns" | "model" | "headerFactory" | keyof ColumnViewDeclarativeProps<T, S>> & ColumnViewDeclarativeProps<T, S>;
27
- /**
28
- * Renders a Gtk.ColumnView: a multi-column, scrollable list backed by a collection
29
- * model. Columns are declared through the columns prop, each a {@link ColumnDef}.
30
- */
31
- export declare const ColumnView: <T = unknown, S = unknown>(props: ColumnViewProps<T, S>) => ReactNode;
8
+ declare function ColumnView<T = unknown, S = unknown>(props: ColumnViewProps<T, S>): ReactNode;
9
+ export { ColumnView };
32
10
  //# sourceMappingURL=column-view.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"column-view.d.ts","sourceRoot":"","sources":["../src/column-view.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AACzC,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,KAAK,SAAS,EAA4C,MAAM,OAAO,CAAC;AAEjF,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,yBAAyB,CAAC;AAI3E,OAAO,KAAK,EACR,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,EACxB,QAAQ,EACR,WAAW,EACd,MAAM,YAAY,CAAC;AAIpB,YAAY,EAAE,SAAS,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAMpF,MAAM,MAAM,mBAAmB,GAAG;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvC,SAAS,CAAC,EAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,aAAa,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;CAC7F,CAAC;AAEF,MAAM,MAAM,0BAA0B,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI,mBAAmB,GAClF,IAAI,CAAC,uBAAuB,EAAE,oBAAoB,CAAC,GACnD,wBAAwB,GACxB,wBAAwB,GAAG;IACvB,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC,CAAA;KAAE,KAAK,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACxE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;CAC3B,CAAC;AAEN;;;;;GAKG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI,IAAI,CACxD,kBAAkB,EAClB,SAAS,GAAG,OAAO,GAAG,eAAe,GAAG,MAAM,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,CACjF,GACG,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AA4FrC;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,SAAS,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,KAAG,SA2CnF,CAAC"}
1
+ {"version":3,"file":"column-view.d.ts","sourceRoot":"","sources":["../src/column-view.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,KAAK,EAAU,eAAe,EAAE,MAAM,YAAY,CAAC;AAiK1D;;;;GAIG;AACH,iBAAS,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CA6BrF;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -1,78 +1,106 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { GtkColumnView } from "@gtkx/jsx/gtk";
3
- import { useCallback, useMemo, useState } from "react";
4
- import { createTreeRenderContext, HeaderRenderHost } from "./cell.js";
5
- import { ColumnViewColumn } from "./column-view-column.js";
6
- import { makeFactoryInstaller, useCellContainers } from "./hooks/use-cell-containers.js";
7
- import { useCollectionWidget } from "./hooks/use-collection-widget.js";
8
- import { useSortHandler } from "./hooks/use-sort-handler.js";
9
- const headerFactoryInstaller = makeFactoryInstaller((widget, factory) => widget.setHeaderFactory(factory));
10
- const useColumnInstances = () => {
11
- const [instances, setInstances] = useState(() => new Map());
12
- const setInstance = useCallback((id, column) => {
13
- setInstances((current) => {
14
- if (column === null) {
15
- if (!current.has(id))
16
- return current;
17
- const next = new Map(current);
18
- next.delete(id);
19
- return next;
20
- }
21
- if (current.get(id) === column)
22
- return current;
23
- const next = new Map(current);
24
- next.set(id, column);
25
- return next;
26
- });
27
- }, []);
28
- return { instances, setInstance };
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as Gtk from "@gtkx/gi/gtk";
3
+ import { GtkColumnView, GtkColumnViewColumn, GtkCustomSorter, GtkSignalListItemFactory } from "@gtkx/jsx/gtk";
4
+ import { useSignal } from "@gtkx/react";
5
+ import { omit } from "@gtkx/utils";
6
+ import { useLayoutEffect, useRef } from "react";
7
+ import { HeaderPortals, ItemPortals, useHeaderCells, useItemCells } from "./internal/cells.js";
8
+ import { useCollection } from "./internal/use-collection.js";
9
+ import { useWidgetRef } from "./internal/use-widget-ref.js";
10
+ const COLUMN_VIEW_PROPS = [
11
+ "items",
12
+ "sections",
13
+ "renderHeader",
14
+ "columns",
15
+ "selectedIds",
16
+ "onSelectionChanged",
17
+ "selectionMode",
18
+ "expandedIds",
19
+ "onExpandedChange",
20
+ "sortColumn",
21
+ "sortOrder",
22
+ "onSortChanged",
23
+ "estimatedItemHeight",
24
+ "children",
25
+ "ref",
26
+ ];
27
+ const columnById = (view, id) => {
28
+ const columns = view.getColumns();
29
+ for (let index = 0; index < columns.getNItems(); index++) {
30
+ const column = columns.getItem(index);
31
+ if (column instanceof Gtk.ColumnViewColumn && column.getId() === id) {
32
+ return column;
33
+ }
34
+ }
35
+ return null;
29
36
  };
30
- const buildRegistrations = (columns, instances) => {
31
- const result = [];
32
- for (const column of columns) {
33
- const instance = instances.get(column.id);
34
- if (instance)
35
- result.push({ id: column.id, column: instance, sortable: column.sortable ?? false });
37
+ const getSortTarget = (view, sortColumn) => {
38
+ if (view === null || sortColumn === undefined) {
39
+ return null;
40
+ }
41
+ if (sortColumn === null) {
42
+ return { view, column: null };
36
43
  }
37
- return result;
44
+ const column = columnById(view, sortColumn);
45
+ return column === null ? null : { view, column };
38
46
  };
39
- const useColumnViewWiring = (props) => {
40
- const { widgetRef, setRef, collection } = useCollectionWidget(props);
41
- const useHeader = collection.useHeader;
42
- const headerStore = useCellContainers({
43
- object: useHeader ? widgetRef : null,
44
- installer: headerFactoryInstaller,
45
- estimatedHeight: props.estimatedItemHeight,
46
- });
47
- const { instances, setInstance } = useColumnInstances();
48
- const registrations = useMemo(() => buildRegistrations(props.columns, instances), [props.columns, instances]);
49
- useSortHandler({
50
- columnView: widgetRef,
51
- sortColumn: props.sortColumn,
52
- sortOrder: props.sortOrder,
53
- onSortChanged: props.onSortChanged,
54
- columns: registrations,
47
+ const applySort = (sorting, view, column, order) => {
48
+ sorting.current = true;
49
+ try {
50
+ view.sortByColumn(column, order ?? Gtk.SortType.ASCENDING);
51
+ }
52
+ finally {
53
+ sorting.current = false;
54
+ }
55
+ };
56
+ const emitSortChanged = (sorter, sorting, sort) => {
57
+ if (sorter === null || sorting.current) {
58
+ return;
59
+ }
60
+ sort.onSortChanged?.(sorter.getPrimarySortColumn()?.getId() ?? null, sorter.getPrimarySortOrder());
61
+ };
62
+ const syncSort = (sorting, view, sortColumn, sortOrder) => {
63
+ const target = getSortTarget(view, sortColumn);
64
+ if (target === null) {
65
+ return;
66
+ }
67
+ applySort(sorting, target.view, target.column, sortOrder);
68
+ };
69
+ const useColumnSorting = (view, sort, columns) => {
70
+ const sorting = useRef(false);
71
+ const sorter = view?.getSorter() ?? null;
72
+ const columnSorter = sorter instanceof Gtk.ColumnViewSorter ? sorter : null;
73
+ useSignal(columnSorter, "changed", () => {
74
+ emitSortChanged(columnSorter, sorting, sort);
55
75
  });
56
- const expandedIds = props.expandedIds;
57
- const tree = useMemo(() => createTreeRenderContext(expandedIds, collection.rowId), [expandedIds, collection.rowId]);
58
- return {
59
- setRef,
60
- useHeader,
61
- headerStore,
62
- headerResolver: collection.headerResolver,
63
- resolver: collection.resolver,
64
- tree,
65
- setInstance,
66
- };
76
+ const { sortColumn, sortOrder } = sort;
77
+ useLayoutEffect(() => {
78
+ syncSort(sorting, view, sortColumn, sortOrder);
79
+ }, [view, sortColumn, sortOrder, columns]);
80
+ };
81
+ const ColumnCells = ({ column, collection, expandedIds, size }) => {
82
+ const cells = useItemCells(size);
83
+ const rest = omit(column, ["id", "renderCell", "sortable"]);
84
+ return (_jsxs(_Fragment, { children: [_jsx(GtkColumnViewColumn, { id: column.id, factory: _jsx(GtkSignalListItemFactory, { ...cells.handlers }), sorter: column.sortable === true ? _jsx(GtkCustomSorter, {}) : null, ...rest }), _jsx(ItemPortals, { store: cells, render: column.renderCell, collection: collection, expandedIds: expandedIds })] }));
67
85
  };
86
+ const ColumnList = ({ columns, collection, expandedIds, size }) => columns.map((column) => (_jsx(ColumnCells, { column: column, collection: collection, expandedIds: expandedIds, size: size }, column.id)));
68
87
  /**
69
- * Renders a Gtk.ColumnView: a multi-column, scrollable list backed by a collection
70
- * model. Columns are declared through the columns prop, each a {@link ColumnDef}.
88
+ * Renders a Gtk.ColumnView from declarative items or sections and a columns array,
89
+ * with controlled selection, expansion, and sorting, per-column header menus, and
90
+ * section header rendering.
71
91
  */
72
- export const ColumnView = (props) => {
73
- const normalized = props;
74
- const wiring = useColumnViewWiring(normalized);
75
- const { ref, items, sections, columns, selectedIds, selectionMode, onSelectionChanged, expandedIds, onExpandedChange, sortColumn, sortOrder, onSortChanged, renderHeader, estimatedItemHeight, ...intrinsicProps } = normalized;
76
- return (_jsxs(_Fragment, { children: [_jsx(GtkColumnView, { ...intrinsicProps, ref: wiring.setRef, children: columns.map((column) => (_jsx(ColumnViewColumn, { ...column, resolver: wiring.resolver, tree: wiring.tree, estimatedItemHeight: estimatedItemHeight, onInstance: wiring.setInstance }, column.id))) }), _jsx(HeaderRenderHost, { useHeader: wiring.useHeader, store: wiring.headerStore, resolver: wiring.headerResolver, renderHeader: renderHeader })] }));
77
- };
92
+ function ColumnView(props) {
93
+ const { renderHeader, columns, expandedIds, sortColumn, sortOrder, onSortChanged, estimatedItemHeight, ref } = props;
94
+ const rest = omit(props, COLUMN_VIEW_PROPS);
95
+ const [view, refCallback] = useWidgetRef(ref);
96
+ const size = { width: -1, height: estimatedItemHeight ?? -1 };
97
+ const { collection, selection } = useCollection(props);
98
+ const headerCells = useHeaderCells(size);
99
+ const columnList = columns;
100
+ useColumnSorting(view, { sortColumn, sortOrder, onSortChanged }, columnList);
101
+ return (_jsxs(_Fragment, { children: [_jsx(GtkColumnView, { ref: refCallback, model: selection, ...(renderHeader != null && {
102
+ headerFactory: _jsx(GtkSignalListItemFactory, { ...headerCells.handlers }),
103
+ }), ...rest, children: _jsx(ColumnList, { columns: columnList, collection: collection, expandedIds: expandedIds, size: size }) }), renderHeader != null && (_jsx(HeaderPortals, { store: headerCells, render: renderHeader, collection: collection }))] }));
104
+ }
105
+ export { ColumnView };
78
106
  //# sourceMappingURL=column-view.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"column-view.js","sourceRoot":"","sources":["../src/column-view.tsx"],"names":[],"mappings":"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","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport { GtkColumnView, type GtkColumnViewProps } from \"@gtkx/jsx/gtk\";\nimport { type ReactNode, type Ref, useCallback, useMemo, useState } from \"react\";\nimport { createTreeRenderContext, HeaderRenderHost, type TreeRenderContext } from \"./cell.js\";\nimport { type ColumnDef, ColumnViewColumn } from \"./column-view-column.js\";\nimport { makeFactoryInstaller, useCellContainers } from \"./hooks/use-cell-containers.js\";\nimport { useCollectionWidget } from \"./hooks/use-collection-widget.js\";\nimport { type ColumnRegistration, useSortHandler } from \"./hooks/use-sort-handler.js\";\nimport type {\n CollectionItemSizeProps,\n ControlledExpansionProps,\n ControlledSelectionProps,\n ItemNode,\n SectionNode,\n} from \"./types.js\";\nimport type { CellContainerStore } from \"./utils/cell-container-store.js\";\nimport type { ItemResolver } from \"./utils/item-resolver.js\";\n\nexport type { ColumnDef, ColumnDefDeclarativeProps } from \"./column-view-column.js\";\n\nconst headerFactoryInstaller = makeFactoryInstaller<Gtk.ColumnView>((widget, factory) =>\n widget.setHeaderFactory(factory),\n);\n\nexport type ColumnViewSortProps = {\n sortColumn?: string | null | undefined;\n sortOrder?: Gtk.SortType | null | undefined;\n onSortChanged?: ((column: string | null, order: Gtk.SortType) => void) | null | undefined;\n};\n\nexport type ColumnViewDeclarativeProps<T = unknown, S = unknown> = ColumnViewSortProps &\n Omit<CollectionItemSizeProps, \"estimatedItemWidth\"> &\n ControlledSelectionProps &\n ControlledExpansionProps & {\n items?: ItemNode<T>[] | undefined;\n sections?: SectionNode<S, T>[] | undefined;\n renderHeader?: ((info: { section: S }) => ReactNode) | null | undefined;\n columns: ColumnDef<T>[];\n };\n\n/**\n * Props for {@link ColumnView}. Combines the underlying Gtk.ColumnView props with\n * declarative collection props: flat items or grouped sections, controlled selection\n * and expansion, sorting (sortColumn, sortOrder, onSortChanged), an optional section\n * header renderer, and the columns to render.\n */\nexport type ColumnViewProps<T = unknown, S = unknown> = Omit<\n GtkColumnViewProps,\n \"columns\" | \"model\" | \"headerFactory\" | keyof ColumnViewDeclarativeProps<T, S>\n> &\n ColumnViewDeclarativeProps<T, S>;\n\ntype NormalizedColumnViewProps<T, S> = ColumnViewDeclarativeProps<T, S> & {\n ref?: Ref<Gtk.ColumnView | null>;\n [key: string]: unknown;\n};\n\ninterface ColumnViewWiring<T, S> {\n setRef: (value: Gtk.ColumnView | null) => void;\n useHeader: boolean;\n headerStore: CellContainerStore;\n headerResolver: ItemResolver<T, S>;\n resolver: ItemResolver<unknown, unknown>;\n tree: TreeRenderContext;\n setInstance: (id: string, column: Gtk.ColumnViewColumn | null) => void;\n}\n\nconst useColumnInstances = (): {\n instances: Map<string, Gtk.ColumnViewColumn>;\n setInstance: (id: string, column: Gtk.ColumnViewColumn | null) => void;\n} => {\n const [instances, setInstances] = useState<Map<string, Gtk.ColumnViewColumn>>(() => new Map());\n const setInstance = useCallback((id: string, column: Gtk.ColumnViewColumn | null): void => {\n setInstances((current) => {\n if (column === null) {\n if (!current.has(id)) return current;\n const next = new Map(current);\n next.delete(id);\n return next;\n }\n if (current.get(id) === column) return current;\n const next = new Map(current);\n next.set(id, column);\n return next;\n });\n }, []);\n return { instances, setInstance };\n};\n\nconst buildRegistrations = <T,>(\n columns: ColumnDef<T>[],\n instances: Map<string, Gtk.ColumnViewColumn>,\n): ColumnRegistration[] => {\n const result: ColumnRegistration[] = [];\n for (const column of columns) {\n const instance = instances.get(column.id);\n if (instance) result.push({ id: column.id, column: instance, sortable: column.sortable ?? false });\n }\n return result;\n};\n\nconst useColumnViewWiring = <T, S>(props: NormalizedColumnViewProps<T, S>): ColumnViewWiring<T, S> => {\n const { widgetRef, setRef, collection } = useCollectionWidget<Gtk.ColumnView, T, S>(props);\n\n const useHeader = collection.useHeader;\n const headerStore = useCellContainers<Gtk.ColumnView>({\n object: useHeader ? widgetRef : null,\n installer: headerFactoryInstaller,\n estimatedHeight: props.estimatedItemHeight,\n });\n\n const { instances, setInstance } = useColumnInstances();\n const registrations = useMemo<ColumnRegistration[]>(\n () => buildRegistrations(props.columns, instances),\n [props.columns, instances],\n );\n\n useSortHandler({\n columnView: widgetRef,\n sortColumn: props.sortColumn,\n sortOrder: props.sortOrder,\n onSortChanged: props.onSortChanged,\n columns: registrations,\n });\n\n const expandedIds = props.expandedIds;\n const tree = useMemo<TreeRenderContext>(\n () => createTreeRenderContext(expandedIds, collection.rowId),\n [expandedIds, collection.rowId],\n );\n\n return {\n setRef,\n useHeader,\n headerStore,\n headerResolver: collection.headerResolver,\n resolver: collection.resolver as ItemResolver<unknown, unknown>,\n tree,\n setInstance,\n };\n};\n\n/**\n * Renders a Gtk.ColumnView: a multi-column, scrollable list backed by a collection\n * model. Columns are declared through the columns prop, each a {@link ColumnDef}.\n */\nexport const ColumnView = <T = unknown, S = unknown>(props: ColumnViewProps<T, S>): ReactNode => {\n const normalized = props as NormalizedColumnViewProps<T, S>;\n const wiring = useColumnViewWiring<T, S>(normalized);\n const {\n ref,\n items,\n sections,\n columns,\n selectedIds,\n selectionMode,\n onSelectionChanged,\n expandedIds,\n onExpandedChange,\n sortColumn,\n sortOrder,\n onSortChanged,\n renderHeader,\n estimatedItemHeight,\n ...intrinsicProps\n } = normalized;\n\n return (\n <>\n <GtkColumnView {...intrinsicProps} ref={wiring.setRef}>\n {columns.map((column) => (\n <ColumnViewColumn\n key={column.id}\n {...column}\n resolver={wiring.resolver}\n tree={wiring.tree}\n estimatedItemHeight={estimatedItemHeight}\n onInstance={wiring.setInstance}\n />\n ))}\n </GtkColumnView>\n <HeaderRenderHost\n useHeader={wiring.useHeader}\n store={wiring.headerStore}\n resolver={wiring.headerResolver}\n renderHeader={renderHeader}\n />\n </>\n );\n};\n"]}
1
+ {"version":3,"file":"column-view.js","sourceRoot":"","sources":["../src/column-view.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode } from \"react\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { GtkColumnView, GtkColumnViewColumn, GtkCustomSorter, GtkSignalListItemFactory } from \"@gtkx/jsx/gtk\";\nimport { useSignal } from \"@gtkx/react\";\nimport { omit } from \"@gtkx/utils\";\nimport { useLayoutEffect, useRef } from \"react\";\nimport type { CellSize } from \"./internal/cells.js\";\nimport type { Collection } from \"./internal/collection.js\";\nimport type { Column, ColumnViewProps } from \"./types.js\";\nimport { HeaderPortals, ItemPortals, useHeaderCells, useItemCells } from \"./internal/cells.js\";\nimport { useCollection } from \"./internal/use-collection.js\";\nimport { useWidgetRef } from \"./internal/use-widget-ref.js\";\n\ntype SortProps = {\n sortColumn?: string | null | undefined;\n sortOrder?: Gtk.SortType | null | undefined;\n onSortChanged?: ((column: string | null, order: Gtk.SortType) => void) | null | undefined;\n};\n\ntype SortTarget = { view: Gtk.ColumnView; column: Gtk.ColumnViewColumn | null };\n\ntype ColumnCellsProps = {\n column: Column<never>;\n collection: Collection;\n expandedIds: string[] | null | undefined;\n size: CellSize;\n};\n\ntype ColumnListProps = Omit<ColumnCellsProps, \"column\"> & {\n columns: Column<never>[];\n};\n\nconst COLUMN_VIEW_PROPS = [\n \"items\",\n \"sections\",\n \"renderHeader\",\n \"columns\",\n \"selectedIds\",\n \"onSelectionChanged\",\n \"selectionMode\",\n \"expandedIds\",\n \"onExpandedChange\",\n \"sortColumn\",\n \"sortOrder\",\n \"onSortChanged\",\n \"estimatedItemHeight\",\n \"children\",\n \"ref\",\n] as const satisfies (keyof ColumnViewProps)[];\n\nconst columnById = (view: Gtk.ColumnView, id: string): Gtk.ColumnViewColumn | null => {\n const columns = view.getColumns();\n\n for (let index = 0; index < columns.getNItems(); index++) {\n const column = columns.getItem(index);\n\n if (column instanceof Gtk.ColumnViewColumn && column.getId() === id) {\n return column;\n }\n }\n\n return null;\n};\n\nconst getSortTarget = (view: Gtk.ColumnView | null, sortColumn: string | null | undefined): SortTarget | null => {\n if (view === null || sortColumn === undefined) {\n return null;\n }\n\n if (sortColumn === null) {\n return { view, column: null };\n }\n\n const column = columnById(view, sortColumn);\n\n return column === null ? null : { view, column };\n};\n\nconst applySort = (\n sorting: { current: boolean },\n view: Gtk.ColumnView,\n column: Gtk.ColumnViewColumn | null,\n order: Gtk.SortType | null | undefined,\n): void => {\n sorting.current = true;\n\n try {\n view.sortByColumn(column, order ?? Gtk.SortType.ASCENDING);\n } finally {\n sorting.current = false;\n }\n};\n\nconst emitSortChanged = (\n sorter: Gtk.ColumnViewSorter | null,\n sorting: { current: boolean },\n sort: SortProps,\n): void => {\n if (sorter === null || sorting.current) {\n return;\n }\n\n sort.onSortChanged?.(sorter.getPrimarySortColumn()?.getId() ?? null, sorter.getPrimarySortOrder());\n};\n\nconst syncSort = (\n sorting: { current: boolean },\n view: Gtk.ColumnView | null,\n sortColumn: string | null | undefined,\n sortOrder: Gtk.SortType | null | undefined,\n): void => {\n const target = getSortTarget(view, sortColumn);\n\n if (target === null) {\n return;\n }\n\n applySort(sorting, target.view, target.column, sortOrder);\n};\n\nconst useColumnSorting = (view: Gtk.ColumnView | null, sort: SortProps, columns: Column<never>[]): void => {\n const sorting = useRef(false);\n const sorter = view?.getSorter() ?? null;\n const columnSorter = sorter instanceof Gtk.ColumnViewSorter ? sorter : null;\n\n useSignal(columnSorter, \"changed\", (): void => {\n emitSortChanged(columnSorter, sorting, sort);\n });\n\n const { sortColumn, sortOrder } = sort;\n\n useLayoutEffect(() => {\n syncSort(sorting, view, sortColumn, sortOrder);\n }, [view, sortColumn, sortOrder, columns]);\n};\n\nconst ColumnCells = ({ column, collection, expandedIds, size }: ColumnCellsProps): ReactNode => {\n const cells = useItemCells(size);\n const rest = omit(column, [\"id\", \"renderCell\", \"sortable\"]);\n\n return (\n <>\n <GtkColumnViewColumn\n id={column.id}\n factory={<GtkSignalListItemFactory {...cells.handlers} />}\n sorter={column.sortable === true ? <GtkCustomSorter /> : null}\n {...rest}\n />\n <ItemPortals\n store={cells}\n render={column.renderCell}\n collection={collection}\n expandedIds={expandedIds}\n />\n </>\n );\n};\n\nconst ColumnList = ({ columns, collection, expandedIds, size }: ColumnListProps): ReactNode =>\n columns.map((column) => (\n <ColumnCells\n key={column.id}\n column={column}\n collection={collection}\n expandedIds={expandedIds}\n size={size}\n />\n ));\n\n/**\n * Renders a Gtk.ColumnView from declarative items or sections and a columns array,\n * with controlled selection, expansion, and sorting, per-column header menus, and\n * section header rendering.\n */\nfunction ColumnView<T = unknown, S = unknown>(props: ColumnViewProps<T, S>): ReactNode {\n const { renderHeader, columns, expandedIds, sortColumn, sortOrder, onSortChanged, estimatedItemHeight, ref } =\n props;\n\n const rest = omit(props, COLUMN_VIEW_PROPS);\n const [view, refCallback] = useWidgetRef<Gtk.ColumnView>(ref);\n const size = { width: -1, height: estimatedItemHeight ?? -1 };\n const { collection, selection } = useCollection(props);\n const headerCells = useHeaderCells(size);\n const columnList = columns as Column<never>[];\n useColumnSorting(view, { sortColumn, sortOrder, onSortChanged }, columnList);\n\n return (\n <>\n <GtkColumnView\n ref={refCallback}\n model={selection}\n {...(renderHeader != null && {\n headerFactory: <GtkSignalListItemFactory {...headerCells.handlers} />,\n })}\n {...rest}\n >\n <ColumnList columns={columnList} collection={collection} expandedIds={expandedIds} size={size} />\n </GtkColumnView>\n {renderHeader != null && (\n <HeaderPortals store={headerCells} render={renderHeader} collection={collection} />\n )}\n </>\n );\n}\n\nexport { ColumnView };\n"]}
@@ -1,31 +1,10 @@
1
- import { GtkDropDown } from "@gtkx/jsx/gtk";
2
- import { type ElementType, type ReactNode } from "react";
3
- import type { ItemNode, RenderItemProps, SectionNode, WidgetProps } from "./types.js";
4
- export type DropDownItemRenderer<T> = (props: RenderItemProps<T>) => ReactNode;
5
- /** Declarative props for {@link DropDown}'s backing collection and cell rendering. */
6
- export type DropDownDeclarativeProps<T = unknown, S = unknown> = {
7
- items?: ItemNode<T>[] | undefined;
8
- sections?: SectionNode<S, T>[] | undefined;
9
- /** Id of the currently selected item, making the selection controlled. */
10
- selectedId?: string | null | undefined;
11
- onSelectionChanged?: ((id: string) => void) | null | undefined;
12
- renderItem?: DropDownItemRenderer<T> | null | undefined;
13
- /** Renderer for items in the open popup list, falling back to renderItem when omitted. */
14
- renderListItem?: DropDownItemRenderer<T> | null | undefined;
15
- /** Renderer for section headers in the popup list. */
16
- renderHeader?: ((info: {
17
- section: S;
18
- }) => ReactNode) | null | undefined;
19
- };
1
+ import type { ReactNode } from "react";
2
+ import type { DropDownProps } from "./types.js";
3
+ type DropDownComponent = <T = unknown, S = unknown>(props: DropDownProps<T, S>) => ReactNode;
20
4
  /**
21
- * Props for {@link DropDown}. The backing widget is chosen through the `component` prop, defaulting to
22
- * GtkDropDown, and its own props combine with {@link DropDownDeclarativeProps}.
5
+ * Renders a `Gtk.DropDown` backed by a collection model, with customizable renderers for the
6
+ * collapsed display, popup rows, and popup section headers, and controlled selection.
23
7
  */
24
- export type DropDownProps<T = unknown, S = unknown, C extends ElementType = typeof GtkDropDown> = WidgetProps<C, DropDownDeclarativeProps<T, S>, "model" | "factory" | "listFactory" | "headerFactory">;
25
- /**
26
- * Renders a drop-down widget (Gtk.DropDown by default, or the widget given as `component`) backed by a
27
- * collection model, with customizable rendering for the selected item, the popup list rows, and section
28
- * headers.
29
- */
30
- export declare const DropDown: <T = unknown, S = unknown, C extends ElementType = typeof GtkDropDown>(props: DropDownProps<T, S, C>) => ReactNode;
8
+ declare const DropDown: DropDownComponent;
9
+ export { DropDown };
31
10
  //# sourceMappingURL=drop-down.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"drop-down.d.ts","sourceRoot":"","sources":["../src/drop-down.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAY,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAA2C,MAAM,OAAO,CAAC;AAMlG,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAItF,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;AAkC/E,sFAAsF;AACtF,MAAM,MAAM,wBAAwB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI;IAC7D,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC;IAC3C,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvC,kBAAkB,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/D,UAAU,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACxD,0FAA0F;IAC1F,cAAc,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5D,sDAAsD;IACtD,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC,CAAA;KAAE,KAAK,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;CAC3E,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,WAAW,GAAG,OAAO,WAAW,IAAI,WAAW,CACzG,CAAC,EACD,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,EAC9B,OAAO,GAAG,SAAS,GAAG,aAAa,GAAG,eAAe,CACxD,CAAC;AAsEF;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,WAAW,GAAG,OAAO,WAAW,SAClF,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC9B,SA6CF,CAAC"}
1
+ {"version":3,"file":"drop-down.d.ts","sourceRoot":"","sources":["../src/drop-down.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,KAAK,iBAAiB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;AAE7F;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAAE,iBAAqD,CAAC;AAMtE,OAAO,EAAE,QAAQ,EAAE,CAAC"}