@gtkx/react 0.1.46 → 0.1.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -68,7 +68,7 @@ export const App = () => {
68
68
  defaultHeight={300}
69
69
  onCloseRequest={quit}
70
70
  >
71
- <Box orientation={Orientation.VERTICAL} spacing={12} margin={20}>
71
+ <Box orientation={Orientation.VERTICAL} spacing={12} marginStart={20} marginEnd={20} marginTop={20} marginBottom={20}>
72
72
  <Label.Root label={`Count: ${count}`} />
73
73
  <Button
74
74
  label="Increment"
@@ -186,6 +186,14 @@ A comprehensive showcase of GTK4 widgets and features:
186
186
  turbo start --filter=gtk4-demo
187
187
  ```
188
188
 
189
+ ### List Example
190
+
191
+ Comprehensive showcase of ListView, GridView, and ColumnView with sorting:
192
+
193
+ ```bash
194
+ turbo start --filter=list-example
195
+ ```
196
+
189
197
  ## Packages
190
198
 
191
199
  | Package | Description |
@@ -44,6 +44,7 @@ export declare class JsxGenerator {
44
44
  private getRequiredConstructorParams;
45
45
  private getConstructorParams;
46
46
  private generateConstructorArgsMetadata;
47
+ private generatePropSettersMap;
47
48
  private generateSetterGetterMap;
48
49
  private collectAllProperties;
49
50
  private getAncestorInterfaces;
@@ -118,6 +118,7 @@ export class JsxGenerator {
118
118
  this.generateCommonTypes(widgetClass),
119
119
  widgetPropsInterfaces,
120
120
  this.generateConstructorArgsMetadata(widgets),
121
+ this.generatePropSettersMap(widgets),
121
122
  this.generateSetterGetterMap(widgets),
122
123
  this.generateExports(widgets, containerMetadata),
123
124
  this.generateJsxNamespace(widgets, containerMetadata),
@@ -135,14 +136,14 @@ export class JsxGenerator {
135
136
  `import type { ReactNode, Ref } from "react";`,
136
137
  ...externalImports,
137
138
  `import type * as Gtk from "@gtkx/ffi/gtk";`,
138
- `import type { ColumnViewColumnProps, GridChildProps, ListItemProps, ListViewRenderProps, NotebookPageProps, SlotProps } from "../types.js";`,
139
+ `import type { ColumnViewColumnProps, ColumnViewRootProps, GridChildProps, ListItemProps, ListViewRenderProps, NotebookPageProps, SlotProps } from "../types.js";`,
139
140
  "",
140
141
  ].join("\n");
141
142
  }
142
143
  generateCommonTypes(widgetClass) {
143
144
  const widgetPropsContent = this.generateWidgetPropsContent(widgetClass);
144
145
  return `
145
- export { ColumnViewColumnProps, GridChildProps, ListItemProps, ListViewRenderProps, NotebookPageProps, SlotProps };
146
+ export { ColumnViewColumnProps, ColumnViewRootProps, GridChildProps, ListItemProps, ListViewRenderProps, NotebookPageProps, SlotProps };
146
147
 
147
148
  ${widgetPropsContent}
148
149
  `;
@@ -410,6 +411,28 @@ ${widgetPropsContent}
410
411
  }
411
412
  return `export const CONSTRUCTOR_PARAMS: Record<string, { name: string; hasDefault: boolean }[]> = {\n${entries.join(",\n")},\n};\n`;
412
413
  }
414
+ generatePropSettersMap(widgets) {
415
+ const widgetEntries = [];
416
+ for (const widget of widgets) {
417
+ const propSetterPairs = [];
418
+ const allProps = this.collectAllProperties(widget);
419
+ for (const prop of allProps) {
420
+ if (prop.setter) {
421
+ const propName = toCamelCase(prop.name);
422
+ const setterName = toCamelCase(prop.setter);
423
+ propSetterPairs.push(`"${propName}": "${setterName}"`);
424
+ }
425
+ }
426
+ if (propSetterPairs.length > 0) {
427
+ const widgetName = toPascalCase(widget.name);
428
+ widgetEntries.push(`\t${widgetName}: { ${propSetterPairs.join(", ")} }`);
429
+ }
430
+ }
431
+ if (widgetEntries.length === 0) {
432
+ return `export const PROP_SETTERS: Record<string, Record<string, string>> = {};\n`;
433
+ }
434
+ return `export const PROP_SETTERS: Record<string, Record<string, string>> = {\n${widgetEntries.join(",\n")},\n};\n`;
435
+ }
413
436
  generateSetterGetterMap(widgets) {
414
437
  const widgetEntries = [];
415
438
  for (const widget of widgets) {
@@ -440,7 +463,7 @@ ${widgetPropsContent}
440
463
  for (const prop of current.properties) {
441
464
  if (!seen.has(prop.name)) {
442
465
  seen.add(prop.name);
443
- props.push({ setter: prop.setter, getter: prop.getter });
466
+ props.push({ name: prop.name, setter: prop.setter, getter: prop.getter });
444
467
  }
445
468
  }
446
469
  for (const ifaceName of current.implements) {
@@ -449,7 +472,7 @@ ${widgetPropsContent}
449
472
  for (const prop of iface.properties) {
450
473
  if (!seen.has(prop.name)) {
451
474
  seen.add(prop.name);
452
- props.push({ setter: prop.setter, getter: prop.getter });
475
+ props.push({ name: prop.name, setter: prop.setter, getter: prop.getter });
453
476
  }
454
477
  }
455
478
  }
@@ -641,8 +664,15 @@ ${widgetPropsContent}
641
664
  lines.push(`}`);
642
665
  }
643
666
  else if (isColumnViewWidget(widgetName)) {
644
- // Root wrapper (non-generic)
645
- lines.push(`function ${name}Root(props: ${name}Props): import("react").ReactElement {`);
667
+ // Root props type - extends with ColumnViewRootProps for sorting support
668
+ // Uses generics: T for item type, C for column ID union type
669
+ lines.push(`interface ${name}RootPropsExtended<T = unknown, C extends string = string> extends ${name}Props, ColumnViewRootProps<C> {`);
670
+ lines.push(`\t/** Comparison function for sorting items by column. Takes item a, item b, and column id. */`);
671
+ lines.push(`\tsortFn?: (a: T, b: T, columnId: C) => number;`);
672
+ lines.push(`}`);
673
+ lines.push(``);
674
+ // Root wrapper (generic)
675
+ lines.push(`function ${name}Root<T = unknown, C extends string = string>(props: ${name}RootPropsExtended<T, C>): import("react").ReactElement {`);
646
676
  lines.push(`\treturn createElement("${name}.Root", props);`);
647
677
  lines.push(`}`);
648
678
  lines.push(``);
@@ -3,8 +3,8 @@ import type { ReactNode, Ref } from "react";
3
3
  import type * as Gdk from "@gtkx/ffi/gdk";
4
4
  import type * as Gio from "@gtkx/ffi/gio";
5
5
  import type * as Gtk from "@gtkx/ffi/gtk";
6
- import type { ColumnViewColumnProps, GridChildProps, ListItemProps, ListViewRenderProps, NotebookPageProps, SlotProps } from "../types.js";
7
- export { ColumnViewColumnProps, GridChildProps, ListItemProps, ListViewRenderProps, NotebookPageProps, SlotProps, };
6
+ import type { ColumnViewColumnProps, ColumnViewRootProps, GridChildProps, ListItemProps, ListViewRenderProps, NotebookPageProps, SlotProps } from "../types.js";
7
+ export { ColumnViewColumnProps, ColumnViewRootProps, GridChildProps, ListItemProps, ListViewRenderProps, NotebookPageProps, SlotProps, };
8
8
  /**
9
9
  * The base class for all widgets.
10
10
  *
@@ -5933,6 +5933,7 @@ export declare const CONSTRUCTOR_PARAMS: Record<string, {
5933
5933
  name: string;
5934
5934
  hasDefault: boolean;
5935
5935
  }[]>;
5936
+ export declare const PROP_SETTERS: Record<string, Record<string, string>>;
5936
5937
  export declare const SETTER_GETTERS: Record<string, Record<string, string>>;
5937
5938
  /**
5938
5939
  * The base class for all widgets.
@@ -7074,7 +7075,11 @@ export declare const ColorChooserWidget: "ColorChooserWidget";
7074
7075
  * it gets the .color style class.
7075
7076
  */
7076
7077
  export declare const ColorDialogButton: "ColorDialogButton";
7077
- declare function ColumnViewRoot(props: ColumnViewProps): import("react").ReactElement;
7078
+ interface ColumnViewRootPropsExtended<T = unknown, C extends string = string> extends ColumnViewProps, ColumnViewRootProps<C> {
7079
+ /** Comparison function for sorting items by column. Takes item a, item b, and column id. */
7080
+ sortFn?: (a: T, b: T, columnId: C) => number;
7081
+ }
7082
+ declare function ColumnViewRoot<T = unknown, C extends string = string>(props: ColumnViewRootPropsExtended<T, C>): import("react").ReactElement;
7078
7083
  interface ColumnViewGenericColumnProps<T> extends Omit<ColumnViewColumnProps, "renderCell"> {
7079
7084
  /** Render function for column cells. Called with null during setup. */
7080
7085
  renderCell: (item: T | null) => import("react").ReactElement;