@gtkx/react 0.1.48 → 0.1.50

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 (48) hide show
  1. package/README.md +7 -12
  2. package/dist/codegen/jsx-generator.d.ts +12 -2
  3. package/dist/codegen/jsx-generator.js +40 -42
  4. package/dist/container-interfaces.d.ts +51 -0
  5. package/dist/container-interfaces.js +5 -0
  6. package/dist/factory.d.ts +1 -1
  7. package/dist/factory.js +17 -3
  8. package/dist/generated/internal.d.ts +7 -0
  9. package/dist/generated/internal.js +7818 -0
  10. package/dist/generated/jsx.d.ts +31 -22
  11. package/dist/generated/jsx.js +0 -7817
  12. package/dist/node.d.ts +4 -4
  13. package/dist/node.js +8 -7
  14. package/dist/nodes/about-dialog.d.ts +9 -0
  15. package/dist/nodes/about-dialog.js +14 -0
  16. package/dist/nodes/action-bar.d.ts +9 -0
  17. package/dist/nodes/action-bar.js +15 -0
  18. package/dist/nodes/column-view.d.ts +5 -4
  19. package/dist/nodes/column-view.js +28 -29
  20. package/dist/nodes/dropdown.d.ts +7 -17
  21. package/dist/nodes/dropdown.js +17 -10
  22. package/dist/nodes/flow-box.d.ts +9 -0
  23. package/dist/nodes/flow-box.js +25 -0
  24. package/dist/nodes/grid.d.ts +6 -3
  25. package/dist/nodes/grid.js +28 -26
  26. package/dist/nodes/list-box.d.ts +9 -0
  27. package/dist/nodes/list-box.js +21 -0
  28. package/dist/nodes/list.d.ts +4 -3
  29. package/dist/nodes/list.js +8 -7
  30. package/dist/nodes/notebook.d.ts +7 -3
  31. package/dist/nodes/notebook.js +31 -14
  32. package/dist/nodes/overlay.d.ts +2 -1
  33. package/dist/nodes/root.d.ts +2 -3
  34. package/dist/nodes/root.js +3 -3
  35. package/dist/nodes/slot.d.ts +1 -2
  36. package/dist/nodes/slot.js +2 -2
  37. package/dist/nodes/text-view.d.ts +2 -7
  38. package/dist/nodes/text-view.js +10 -49
  39. package/dist/nodes/widget.d.ts +6 -5
  40. package/dist/nodes/widget.js +9 -149
  41. package/dist/nodes/window.d.ts +11 -0
  42. package/dist/nodes/window.js +37 -0
  43. package/dist/props.d.ts +5 -0
  44. package/dist/props.js +10 -0
  45. package/dist/reconciler.d.ts +4 -1
  46. package/dist/reconciler.js +8 -6
  47. package/dist/types.d.ts +4 -4
  48. package/package.json +3 -3
package/README.md CHANGED
@@ -159,7 +159,9 @@ Query types: `ByRole`, `ByText`, `ByLabelText`, `ByTestId`
159
159
  - `userEvent.activate(element)` - Activate element (e.g., press Enter in input)
160
160
  - `userEvent.type(element, text)` - Type text into input
161
161
  - `userEvent.clear(element)` - Clear input text
162
- - `userEvent.setup()` - Create reusable instance
162
+ - `userEvent.tab(element, options?)` - Simulate Tab navigation
163
+ - `userEvent.selectOptions(element, values)` - Select options in ComboBox/ListBox
164
+ - `userEvent.deselectOptions(element, values)` - Deselect options in ListBox
163
165
 
164
166
  **Low-level Events**:
165
167
  - `fireEvent(element, signalName, ...args)` - Emit any GTK signal with optional arguments
@@ -170,14 +172,6 @@ Query types: `ByRole`, `ByText`, `ByLabelText`, `ByTestId`
170
172
 
171
173
  ## Examples
172
174
 
173
- ### Counter
174
-
175
- A minimal counter app demonstrating state management:
176
-
177
- ```bash
178
- turbo start --filter=counter-example
179
- ```
180
-
181
175
  ### GTK4 Demo
182
176
 
183
177
  A comprehensive showcase of GTK4 widgets and features:
@@ -186,12 +180,13 @@ A comprehensive showcase of GTK4 widgets and features:
186
180
  turbo start --filter=gtk4-demo
187
181
  ```
188
182
 
189
- ### List Example
183
+ ### Todo App
190
184
 
191
- Comprehensive showcase of ListView, GridView, and ColumnView with sorting:
185
+ A todo app demonstrating `@gtkx/testing` with realistic component tests:
192
186
 
193
187
  ```bash
194
- turbo start --filter=list-example
188
+ turbo start --filter=todo
189
+ turbo test --filter=todo
195
190
  ```
196
191
 
197
192
  ## Packages
@@ -6,6 +6,15 @@ interface JsxGeneratorOptions {
6
6
  /** Optional Prettier configuration for formatting output. */
7
7
  prettierConfig?: unknown;
8
8
  }
9
+ /**
10
+ * Result of the JSX generation containing both public and internal files.
11
+ */
12
+ interface JsxGeneratorResult {
13
+ /** Public JSX types and components for user consumption. */
14
+ jsx: string;
15
+ /** Internal metadata for reconciler use (not exported to users). */
16
+ internal: string;
17
+ }
9
18
  /**
10
19
  * Generates JSX type definitions for React components from GTK widget classes.
11
20
  * Creates TypeScript interfaces for props and augments React's JSX namespace.
@@ -29,10 +38,11 @@ export declare class JsxGenerator {
29
38
  * Generates JSX type definitions for all widgets in a namespace.
30
39
  * @param namespace - The parsed GIR namespace
31
40
  * @param classMap - Map of class names to class definitions
32
- * @returns Generated TypeScript code as a string
41
+ * @returns Generated TypeScript code as public jsx.ts and internal.ts files
33
42
  */
34
- generate(namespace: GirNamespace, classMap: Map<string, GirClass>): Promise<string>;
43
+ generate(namespace: GirNamespace, classMap: Map<string, GirClass>): Promise<JsxGeneratorResult>;
35
44
  private generateImports;
45
+ private generateInternalImports;
36
46
  private generateCommonTypes;
37
47
  private generateWidgetPropsContent;
38
48
  private buildContainerMetadata;
@@ -5,7 +5,6 @@ const COLUMN_VIEW_WIDGET = "ColumnView";
5
5
  const DROPDOWN_WIDGETS = new Set(["DropDown"]);
6
6
  const GRID_WIDGETS = new Set(["Grid"]);
7
7
  const NOTEBOOK_WIDGET = "Notebook";
8
- const TEXT_VIEW_WIDGET = "TextView";
9
8
  const INTERNALLY_PROVIDED_PARAMS = {
10
9
  ApplicationWindow: new Set(["application"]),
11
10
  };
@@ -34,7 +33,6 @@ const isColumnViewWidget = (widgetName) => widgetName === COLUMN_VIEW_WIDGET;
34
33
  const isDropDownWidget = (widgetName) => DROPDOWN_WIDGETS.has(widgetName);
35
34
  const isGridWidget = (widgetName) => GRID_WIDGETS.has(widgetName);
36
35
  const isNotebookWidget = (widgetName) => widgetName === NOTEBOOK_WIDGET;
37
- const isTextViewWidget = (widgetName) => widgetName === TEXT_VIEW_WIDGET;
38
36
  const sanitizeDoc = (doc) => {
39
37
  let result = doc;
40
38
  result = result.replace(/<picture>[\s\S]*?<\/picture>/gi, "");
@@ -100,7 +98,7 @@ export class JsxGenerator {
100
98
  * Generates JSX type definitions for all widgets in a namespace.
101
99
  * @param namespace - The parsed GIR namespace
102
100
  * @param classMap - Map of class names to class definitions
103
- * @returns Generated TypeScript code as a string
101
+ * @returns Generated TypeScript code as public jsx.ts and internal.ts files
104
102
  */
105
103
  async generate(namespace, classMap) {
106
104
  this.classMap = classMap;
@@ -113,18 +111,24 @@ export class JsxGenerator {
113
111
  this.widgetPropertyNames = new Set(widgetClass?.properties.map((p) => toCamelCase(p.name)) ?? []);
114
112
  this.widgetSignalNames = new Set(widgetClass?.signals.map((s) => toCamelCase(s.name)) ?? []);
115
113
  const widgetPropsInterfaces = this.generateWidgetPropsInterfaces(widgets, containerMetadata);
116
- const sections = [
114
+ const jsxSections = [
117
115
  this.generateImports(),
118
116
  this.generateCommonTypes(widgetClass),
119
117
  widgetPropsInterfaces,
120
- this.generateConstructorArgsMetadata(widgets),
121
- this.generatePropSettersMap(widgets),
122
- this.generateSetterGetterMap(widgets),
123
118
  this.generateExports(widgets, containerMetadata),
124
119
  this.generateJsxNamespace(widgets, containerMetadata),
125
120
  "export {};",
126
121
  ];
127
- return this.formatCode(sections.join("\n"));
122
+ const internalSections = [
123
+ this.generateInternalImports(),
124
+ this.generateConstructorArgsMetadata(widgets),
125
+ this.generatePropSettersMap(widgets),
126
+ this.generateSetterGetterMap(widgets),
127
+ ];
128
+ return {
129
+ jsx: await this.formatCode(jsxSections.join("\n")),
130
+ internal: await this.formatCode(internalSections.join("\n")),
131
+ };
128
132
  }
129
133
  generateImports() {
130
134
  const externalImports = [...this.usedExternalNamespaces]
@@ -140,6 +144,9 @@ export class JsxGenerator {
140
144
  "",
141
145
  ].join("\n");
142
146
  }
147
+ generateInternalImports() {
148
+ return "/** Internal metadata for the reconciler. Not part of the public API. */\n";
149
+ }
143
150
  generateCommonTypes(widgetClass) {
144
151
  const widgetPropsContent = this.generateWidgetPropsContent(widgetClass);
145
152
  return `
@@ -336,24 +343,14 @@ ${widgetPropsContent}
336
343
  lines.push(`\t * Render function for list items.`);
337
344
  lines.push(`\t * Called with null during setup (for loading state) and with the actual item during bind.`);
338
345
  lines.push(`\t */`);
339
- lines.push(`\t// biome-ignore lint/suspicious/noExplicitAny: Internal type, use generic ListView<T> export`);
340
- lines.push(`\trenderItem: (item: any) => import("react").ReactElement;`);
346
+ lines.push(`\trenderItem: (item: unknown) => import("react").ReactElement;`);
341
347
  }
342
348
  if (isDropDownWidget(widget.name)) {
343
349
  lines.push("");
344
350
  lines.push(`\t/** Function to convert item to display label */`);
345
- lines.push(`\t// biome-ignore lint/suspicious/noExplicitAny: Internal type, use generic DropDown<T> export`);
346
- lines.push(`\titemLabel?: (item: any) => string;`);
351
+ lines.push(`\titemLabel?: (item: unknown) => string;`);
347
352
  lines.push(`\t/** Called when selection changes */`);
348
- lines.push(`\t// biome-ignore lint/suspicious/noExplicitAny: Internal type, use generic DropDown<T> export`);
349
- lines.push(`\tonSelectionChanged?: (item: any, index: number) => void;`);
350
- }
351
- if (isTextViewWidget(widget.name)) {
352
- lines.push("");
353
- lines.push(`\t/** The contents of the text buffer. */`);
354
- lines.push(`\ttext?: string;`);
355
- lines.push(`\t/** Called when the text buffer content changes */`);
356
- lines.push(`\tonChanged?: (text: string) => void;`);
353
+ lines.push(`\tonSelectionChanged?: (item: unknown, index: number) => void;`);
357
354
  }
358
355
  lines.push("");
359
356
  lines.push(`\tref?: Ref<Gtk.${widgetName}>;`);
@@ -647,71 +644,72 @@ ${widgetPropsContent}
647
644
  const name = toPascalCase(widgetName);
648
645
  const lines = [];
649
646
  if (isListWidget(widgetName)) {
650
- // Props type for the generic Root component
647
+ lines.push(`/**`);
648
+ lines.push(` * Props for the ${name}.Root component with type-safe item rendering.`);
649
+ lines.push(` * @typeParam T - The type of items in the list.`);
650
+ lines.push(` */`);
651
651
  lines.push(`interface ${name}RootProps<T> extends Omit<${name}Props, "renderItem"> {`);
652
- lines.push(`\t/** Render function for list items. Called with null during setup. */`);
652
+ lines.push(`\t/** Render function for list items. Called with null during setup (for loading state). */`);
653
653
  lines.push(`\trenderItem: (item: T | null) => import("react").ReactElement;`);
654
654
  lines.push(`}`);
655
655
  lines.push(``);
656
- // Root wrapper component
657
656
  lines.push(`function ${name}Root<T>(props: ${name}RootProps<T>): import("react").ReactElement {`);
658
657
  lines.push(`\treturn createElement("${name}.Root", props);`);
659
658
  lines.push(`}`);
660
659
  lines.push(``);
661
- // Item wrapper component
662
660
  lines.push(`function ${name}Item<T>(props: ListItemProps<T>): import("react").ReactElement {`);
663
661
  lines.push(`\treturn createElement("${name}.Item", props);`);
664
662
  lines.push(`}`);
665
663
  }
666
664
  else if (isColumnViewWidget(widgetName)) {
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(`}`);
665
+ lines.push(`/**`);
666
+ lines.push(` * Props for the ${name}.Root component with type-safe item and column rendering.`);
667
+ lines.push(` * @typeParam T - The type of items in the column view.`);
668
+ lines.push(` * @typeParam C - The union type of column IDs for type-safe sorting.`);
669
+ lines.push(` */`);
670
+ lines.push(`interface ${name}RootPropsExtended<T = unknown, C extends string = string> extends ${name}Props, ColumnViewRootProps<T, C> {}`);
673
671
  lines.push(``);
674
- // Root wrapper (generic)
675
672
  lines.push(`function ${name}Root<T = unknown, C extends string = string>(props: ${name}RootPropsExtended<T, C>): import("react").ReactElement {`);
676
673
  lines.push(`\treturn createElement("${name}.Root", props);`);
677
674
  lines.push(`}`);
678
675
  lines.push(``);
679
- // Column props type - use GenericColumnProps to avoid conflict with imported ColumnViewColumnProps
676
+ lines.push(`/**`);
677
+ lines.push(` * Props for ${name}.Column with type-safe cell rendering.`);
678
+ lines.push(` * @typeParam T - The type of items passed to the renderCell function.`);
679
+ lines.push(` */`);
680
680
  lines.push(`interface ${name}GenericColumnProps<T> extends Omit<ColumnViewColumnProps, "renderCell"> {`);
681
- lines.push(`\t/** Render function for column cells. Called with null during setup. */`);
681
+ lines.push(`\t/** Render function for column cells. Called with null during setup (for loading state). */`);
682
682
  lines.push(`\trenderCell: (item: T | null) => import("react").ReactElement;`);
683
683
  lines.push(`}`);
684
684
  lines.push(``);
685
- // Column wrapper component
686
685
  lines.push(`function ${name}Column<T>(props: ${name}GenericColumnProps<T>): import("react").ReactElement {`);
687
686
  lines.push(`\treturn createElement("${name}.Column", props);`);
688
687
  lines.push(`}`);
689
688
  lines.push(``);
690
- // Item wrapper component
691
689
  lines.push(`function ${name}Item<T>(props: ListItemProps<T>): import("react").ReactElement {`);
692
690
  lines.push(`\treturn createElement("${name}.Item", props);`);
693
691
  lines.push(`}`);
694
692
  }
695
693
  else if (isDropDownWidget(widgetName)) {
696
- // Props type for the generic Root component
694
+ lines.push(`/**`);
695
+ lines.push(` * Props for the ${name}.Root component with type-safe item handling.`);
696
+ lines.push(` * @typeParam T - The type of items in the dropdown.`);
697
+ lines.push(` */`);
697
698
  lines.push(`interface ${name}RootProps<T> extends Omit<${name}Props, "itemLabel" | "onSelectionChanged"> {`);
698
- lines.push(`\t/** Function to convert item to display label */`);
699
+ lines.push(`\t/** Function to convert an item to its display label. */`);
699
700
  lines.push(`\titemLabel?: (item: T) => string;`);
700
- lines.push(`\t/** Called when selection changes */`);
701
+ lines.push(`\t/** Called when the selected item changes. */`);
701
702
  lines.push(`\tonSelectionChanged?: (item: T, index: number) => void;`);
702
703
  lines.push(`}`);
703
704
  lines.push(``);
704
- // Root wrapper component
705
705
  lines.push(`function ${name}Root<T>(props: ${name}RootProps<T>): import("react").ReactElement {`);
706
706
  lines.push(`\treturn createElement("${name}.Root", props);`);
707
707
  lines.push(`}`);
708
708
  lines.push(``);
709
- // Item wrapper component
710
709
  lines.push(`function ${name}Item<T>(props: ListItemProps<T>): import("react").ReactElement {`);
711
710
  lines.push(`\treturn createElement("${name}.Item", props);`);
712
711
  lines.push(`}`);
713
712
  }
714
- // Generate slot wrapper components
715
713
  for (const slot of metadata.namedChildSlots) {
716
714
  lines.push(``);
717
715
  lines.push(`function ${name}${slot.slotName}(props: SlotProps): import("react").ReactElement {`);
@@ -0,0 +1,51 @@
1
+ import type * as Gtk from "@gtkx/ffi/gtk";
2
+ import type { Node } from "./node.js";
3
+ /**
4
+ * Interface for containers that manage child widgets with attach/detach semantics.
5
+ * Used by ActionBar, FlowBox, ListBox, Overlay.
6
+ */
7
+ export interface ChildContainer {
8
+ attachChild(child: Gtk.Widget): void;
9
+ insertChildBefore(child: Gtk.Widget, before: Gtk.Widget): void;
10
+ detachChild(child: Gtk.Widget): void;
11
+ }
12
+ /**
13
+ * Interface for page-based containers like Notebook.
14
+ */
15
+ export interface PageContainer {
16
+ addPage(child: Gtk.Widget, label: string): void;
17
+ insertPageBefore(child: Gtk.Widget, label: string, beforeChild: Gtk.Widget): void;
18
+ removePage(child: Gtk.Widget): void;
19
+ updatePageLabel(child: Gtk.Widget, label: string): void;
20
+ }
21
+ /**
22
+ * Interface for grid-based containers.
23
+ */
24
+ export interface GridContainer {
25
+ attachToGrid(child: Gtk.Widget, column: number, row: number, colSpan: number, rowSpan: number): void;
26
+ removeFromGrid(child: Gtk.Widget): void;
27
+ }
28
+ /**
29
+ * Interface for item-based containers like ListView, ColumnView, DropDown.
30
+ */
31
+ export interface ItemContainer<T> {
32
+ addItem(item: T): void;
33
+ insertItemBefore(item: T, beforeItem: T): void;
34
+ removeItem(item: T): void;
35
+ }
36
+ /**
37
+ * Interface for column-based containers like ColumnView.
38
+ * Note: Column type is generic to support both raw Gtk.ColumnViewColumn and wrapper nodes.
39
+ */
40
+ export interface ColumnContainer {
41
+ addColumn(column: unknown): void;
42
+ insertColumnBefore(column: unknown, beforeColumn: unknown): void;
43
+ removeColumn(column: unknown): void;
44
+ getItems(): unknown[];
45
+ getSortFn(): ((a: unknown, b: unknown, columnId: string) => number) | null;
46
+ }
47
+ export declare const isChildContainer: (node: Node) => node is Node & ChildContainer;
48
+ export declare const isPageContainer: (node: Node) => node is Node & PageContainer;
49
+ export declare const isGridContainer: (node: Node) => node is Node & GridContainer;
50
+ export declare const isItemContainer: <T>(node: Node) => node is Node & ItemContainer<T>;
51
+ export declare const isColumnContainer: (node: Node) => node is Node & ColumnContainer;
@@ -0,0 +1,5 @@
1
+ export const isChildContainer = (node) => "attachChild" in node && "detachChild" in node && "insertChildBefore" in node;
2
+ export const isPageContainer = (node) => "addPage" in node && "removePage" in node && "insertPageBefore" in node && "updatePageLabel" in node;
3
+ export const isGridContainer = (node) => "attachToGrid" in node && "removeFromGrid" in node;
4
+ export const isItemContainer = (node) => "addItem" in node && "insertItemBefore" in node && "removeItem" in node;
5
+ export const isColumnContainer = (node) => "addColumn" in node && "removeColumn" in node && "getSortFn" in node;
package/dist/factory.d.ts CHANGED
@@ -3,4 +3,4 @@ import type { Node } from "./node.js";
3
3
  import { type ROOT_NODE_CONTAINER } from "./nodes/root.js";
4
4
  export type Props = Record<string, unknown>;
5
5
  export { ROOT_NODE_CONTAINER } from "./nodes/root.js";
6
- export declare const createNode: (type: string, props: Props, app: Gtk.Application, existingWidget?: Gtk.Widget | typeof ROOT_NODE_CONTAINER) => Node;
6
+ export declare const createNode: (type: string, props: Props, existingWidget?: Gtk.Widget | typeof ROOT_NODE_CONTAINER) => Node;
package/dist/factory.js CHANGED
@@ -1,16 +1,22 @@
1
+ import { AboutDialogNode } from "./nodes/about-dialog.js";
2
+ import { ActionBarNode } from "./nodes/action-bar.js";
1
3
  import { ColumnViewColumnNode, ColumnViewItemNode, ColumnViewNode } from "./nodes/column-view.js";
2
4
  import { DropDownItemNode, DropDownNode } from "./nodes/dropdown.js";
5
+ import { FlowBoxNode } from "./nodes/flow-box.js";
3
6
  import { GridChildNode, GridNode } from "./nodes/grid.js";
4
7
  import { ListItemNode, ListViewNode } from "./nodes/list.js";
8
+ import { ListBoxNode } from "./nodes/list-box.js";
5
9
  import { NotebookNode, NotebookPageNode } from "./nodes/notebook.js";
6
10
  import { OverlayNode } from "./nodes/overlay.js";
7
11
  import { RootNode } from "./nodes/root.js";
8
12
  import { SlotNode } from "./nodes/slot.js";
9
13
  import { TextViewNode } from "./nodes/text-view.js";
10
14
  import { WidgetNode } from "./nodes/widget.js";
15
+ import { WindowNode } from "./nodes/window.js";
11
16
  export { ROOT_NODE_CONTAINER } from "./nodes/root.js";
12
17
  const NODE_CLASSES = [
13
18
  RootNode,
19
+ // Virtual nodes (no widget)
14
20
  ColumnViewColumnNode,
15
21
  ColumnViewItemNode,
16
22
  ListItemNode,
@@ -18,19 +24,27 @@ const NODE_CLASSES = [
18
24
  GridChildNode,
19
25
  NotebookPageNode,
20
26
  SlotNode,
27
+ // Specialized widget nodes
28
+ WindowNode,
29
+ AboutDialogNode,
21
30
  TextViewNode,
31
+ // Container nodes
32
+ ActionBarNode,
33
+ FlowBoxNode,
34
+ ListBoxNode,
22
35
  DropDownNode,
23
36
  GridNode,
24
37
  OverlayNode,
25
38
  ColumnViewNode,
26
39
  ListViewNode,
27
40
  NotebookNode,
41
+ // Catch-all (must be last)
28
42
  WidgetNode,
29
43
  ];
30
- export const createNode = (type, props, app, existingWidget) => {
44
+ export const createNode = (type, props, existingWidget) => {
31
45
  for (const NodeClass of NODE_CLASSES) {
32
- if (NodeClass.matches(type, props, existingWidget)) {
33
- return new NodeClass(type, props, app, existingWidget);
46
+ if (NodeClass.matches(type, existingWidget)) {
47
+ return new NodeClass(type, props, existingWidget);
34
48
  }
35
49
  }
36
50
  throw new Error(`No matching node class for type: ${type}`);
@@ -0,0 +1,7 @@
1
+ /** Internal metadata for the reconciler. Not part of the public API. */
2
+ export declare const CONSTRUCTOR_PARAMS: Record<string, {
3
+ name: string;
4
+ hasDefault: boolean;
5
+ }[]>;
6
+ export declare const PROP_SETTERS: Record<string, Record<string, string>>;
7
+ export declare const SETTER_GETTERS: Record<string, Record<string, string>>;