@peachy/hooks 0.0.10 → 0.0.12
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/CHANGELOG.md +8 -0
- package/README.md +8 -18
- package/dist/adw/index.mjs +1 -2
- package/dist/adw/use-accent-color.d.mts +4 -4
- package/dist/adw/use-accent-color.mjs +3 -5
- package/dist/adw/use-dark-mode.d.mts +1 -1
- package/dist/adw/use-dark-mode.mjs +2 -4
- package/dist/base/index.mjs +1 -2
- package/dist/base/use-reference.d.mts +2 -2
- package/dist/base/use-reference.mjs +1 -3
- package/dist/gio/index.mjs +1 -2
- package/dist/gio/use-network-monitor.mjs +12 -13
- package/dist/gio/use-setting.mjs +15 -13
- package/dist/gobject/index.mjs +1 -2
- package/dist/gobject/use-binding.d.mts +5 -3
- package/dist/gobject/use-binding.mjs +5 -12
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +1 -2
- package/package.json +6 -6
- package/src/adw/use-accent-color.ts +3 -6
- package/src/adw/use-dark-mode.ts +4 -4
- package/src/base/use-reference.ts +1 -4
- package/src/gio/use-network-monitor.ts +13 -10
- package/src/gio/use-setting.ts +18 -9
- package/src/gobject/use-binding.ts +29 -45
- package/tsconfig.json +1 -1
- package/tsdown.config.mjs +3 -1
- package/dist/types.d.mts +0 -1
- package/dist/types.mjs +0 -1
- package/src/types.ts +0 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -24,11 +24,7 @@ import { useNetworkMonitor } from "@peachy/hooks";
|
|
|
24
24
|
const App = () => {
|
|
25
25
|
const { connected } = useNetworkMonitor();
|
|
26
26
|
|
|
27
|
-
return
|
|
28
|
-
<Gtk.Label>
|
|
29
|
-
{connected ? "Connected" : "Disconnected"}
|
|
30
|
-
</Gtk.Label>
|
|
31
|
-
);
|
|
27
|
+
return <Gtk.Label>{connected ? "Connected" : "Disconnected"}</Gtk.Label>;
|
|
32
28
|
};
|
|
33
29
|
```
|
|
34
30
|
|
|
@@ -51,12 +47,8 @@ const App = () => {
|
|
|
51
47
|
|
|
52
48
|
return (
|
|
53
49
|
<Gtk.Box>
|
|
54
|
-
<Gtk.Label>
|
|
55
|
-
|
|
56
|
-
</Gtk.Label>
|
|
57
|
-
<Gtk.Button onClick={() => changeValue("Adwaita-dark")}>
|
|
58
|
-
Change Theme
|
|
59
|
-
</Gtk.Button>
|
|
50
|
+
<Gtk.Label>Theme: {value}</Gtk.Label>
|
|
51
|
+
<Gtk.Button onClick={() => changeValue("Adwaita-dark")}>Change Theme</Gtk.Button>
|
|
60
52
|
</Gtk.Box>
|
|
61
53
|
);
|
|
62
54
|
};
|
|
@@ -68,6 +60,8 @@ const App = () => {
|
|
|
68
60
|
|
|
69
61
|
Bind to a property, and listen for changes.
|
|
70
62
|
|
|
63
|
+
NOTE: You can provide a default value for the hook as third parameter
|
|
64
|
+
|
|
71
65
|
```tsx
|
|
72
66
|
import Adw from "gi://Adw?version=1";
|
|
73
67
|
|
|
@@ -81,13 +75,9 @@ const App = () => {
|
|
|
81
75
|
|
|
82
76
|
return (
|
|
83
77
|
<Gtk.Box>
|
|
84
|
-
<Gtk.Label>
|
|
85
|
-
|
|
86
|
-
</Gtk.Label>
|
|
87
|
-
|
|
88
|
-
<Gtk.Label>
|
|
89
|
-
Accent Color: {accentColor}
|
|
90
|
-
</Gtk.Label>
|
|
78
|
+
<Gtk.Label>Theme: {darkMode ? "Dark" : "Light"}</Gtk.Label>
|
|
79
|
+
|
|
80
|
+
<Gtk.Label>Accent Color: {accentColor}</Gtk.Label>
|
|
91
81
|
</Gtk.Box>
|
|
92
82
|
);
|
|
93
83
|
};
|
package/dist/adw/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//#region src/adw/use-accent-color.d.ts
|
|
2
2
|
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
declare function useAccentColor():
|
|
3
|
+
* Query the system's accent color if supported
|
|
4
|
+
* @returns [accentColor] - accent color or null
|
|
5
|
+
*/
|
|
6
|
+
declare function useAccentColor(): [accentColor: number | null];
|
|
7
7
|
//#endregion
|
|
8
8
|
export { useAccentColor };
|
|
@@ -2,7 +2,6 @@ import { useBinding } from "../gobject/use-binding.mjs";
|
|
|
2
2
|
import "../gobject/index.mjs";
|
|
3
3
|
import { useRef } from "react";
|
|
4
4
|
import Adw from "gi://Adw?version=1";
|
|
5
|
-
|
|
6
5
|
//#region src/adw/use-accent-color.ts
|
|
7
6
|
/**
|
|
8
7
|
* Query the system's accent color if supported
|
|
@@ -10,10 +9,9 @@ import Adw from "gi://Adw?version=1";
|
|
|
10
9
|
*/
|
|
11
10
|
function useAccentColor() {
|
|
12
11
|
const styleManager = useRef(Adw.StyleManager.get_default());
|
|
13
|
-
const [accentColor] = useBinding(styleManager, "
|
|
14
|
-
const [systemSupportsAccentColors] = useBinding(styleManager, "
|
|
12
|
+
const [accentColor] = useBinding(styleManager, "accent-color");
|
|
13
|
+
const [systemSupportsAccentColors] = useBinding(styleManager, "system-supports-accent-colors");
|
|
15
14
|
return [systemSupportsAccentColors ? accentColor : null];
|
|
16
15
|
}
|
|
17
|
-
|
|
18
16
|
//#endregion
|
|
19
|
-
export { useAccentColor };
|
|
17
|
+
export { useAccentColor };
|
|
@@ -2,15 +2,13 @@ import { useBinding } from "../gobject/use-binding.mjs";
|
|
|
2
2
|
import "../gobject/index.mjs";
|
|
3
3
|
import { useCallback, useRef } from "react";
|
|
4
4
|
import Adw from "gi://Adw?version=1";
|
|
5
|
-
|
|
6
5
|
//#region src/adw/use-dark-mode.ts
|
|
7
6
|
function useDarkMode() {
|
|
8
7
|
const styleManager = useRef(Adw.StyleManager.get_default());
|
|
9
|
-
const [isDark] = useBinding(styleManager, "dark"
|
|
8
|
+
const [isDark] = useBinding(styleManager, "dark");
|
|
10
9
|
return [isDark, useCallback((value) => {
|
|
11
10
|
styleManager.current.set_color_scheme(value ? Adw.ColorScheme.PREFER_DARK : Adw.ColorScheme.PREFER_LIGHT);
|
|
12
11
|
}, [styleManager])];
|
|
13
12
|
}
|
|
14
|
-
|
|
15
13
|
//#endregion
|
|
16
|
-
export { useDarkMode };
|
|
14
|
+
export { useDarkMode };
|
package/dist/base/index.mjs
CHANGED
|
@@ -2,8 +2,8 @@ import { RefObject } from "react";
|
|
|
2
2
|
|
|
3
3
|
//#region src/base/use-reference.d.ts
|
|
4
4
|
/**
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
* Returns the value inside a `ref`, correctly checking it after the initial render
|
|
6
|
+
*/
|
|
7
7
|
declare function useReference<T>(value: T | RefObject<T>, defaultValue?: T): T | null;
|
|
8
8
|
//#endregion
|
|
9
9
|
export { useReference };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
-
|
|
3
2
|
//#region src/base/use-reference.ts
|
|
4
3
|
/**
|
|
5
4
|
* Returns the value inside a `ref`, correctly checking it after the initial render
|
|
@@ -19,6 +18,5 @@ function getValue(object) {
|
|
|
19
18
|
function isRef(object) {
|
|
20
19
|
return typeof object === "object" && object !== null && "current" in object;
|
|
21
20
|
}
|
|
22
|
-
|
|
23
21
|
//#endregion
|
|
24
|
-
export { useReference };
|
|
22
|
+
export { useReference };
|
package/dist/gio/index.mjs
CHANGED
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from "react";
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
2
|
import Gio from "gi://Gio?version=2.0";
|
|
3
|
-
|
|
4
3
|
//#region src/gio/use-network-monitor.ts
|
|
5
4
|
function useNetworkMonitor() {
|
|
6
|
-
const monitor = Gio.NetworkMonitor.get_default();
|
|
5
|
+
const monitor = useRef(Gio.NetworkMonitor.get_default());
|
|
7
6
|
const [state, setState] = useState(() => calculateState());
|
|
8
7
|
const calculateState = useCallback(() => {
|
|
9
8
|
return {
|
|
10
|
-
available: monitor.
|
|
11
|
-
connected: monitor.connectivity === Gio.NetworkConnectivity.FULL,
|
|
12
|
-
state: monitor.connectivity,
|
|
13
|
-
metered: monitor.
|
|
9
|
+
available: monitor.current.networkAvailable,
|
|
10
|
+
connected: monitor.current.connectivity === Gio.NetworkConnectivity.FULL,
|
|
11
|
+
state: monitor.current.connectivity,
|
|
12
|
+
metered: monitor.current.networkMetered
|
|
14
13
|
};
|
|
15
|
-
}, []);
|
|
14
|
+
}, [monitor]);
|
|
16
15
|
useEffect(() => {
|
|
17
|
-
const
|
|
16
|
+
const monitorObj = monitor.current;
|
|
17
|
+
const id = monitorObj.connect("network-changed", () => {
|
|
18
18
|
setState(calculateState());
|
|
19
19
|
});
|
|
20
20
|
return () => {
|
|
21
|
-
|
|
21
|
+
monitorObj.disconnect(id);
|
|
22
22
|
};
|
|
23
|
-
}, []);
|
|
23
|
+
}, [calculateState]);
|
|
24
24
|
return state;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
26
|
//#endregion
|
|
28
|
-
export { useNetworkMonitor };
|
|
27
|
+
export { useNetworkMonitor };
|
package/dist/gio/use-setting.mjs
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
2
|
import Gio from "gi://Gio?version=2.0";
|
|
3
|
-
|
|
4
3
|
//#region src/gio/use-setting.ts
|
|
5
4
|
function useSetting(schema, key) {
|
|
6
|
-
const settings = Gio.Settings.new(schema);
|
|
7
|
-
const getValue = () => settings.get_value(key).recursiveUnpack();
|
|
5
|
+
const settings = useRef(Gio.Settings.new(schema));
|
|
6
|
+
const getValue = useCallback(() => settings.current.get_value(key).recursiveUnpack(), [key, settings]);
|
|
8
7
|
const [value, setValue] = useState(() => getValue());
|
|
9
8
|
useEffect(() => {
|
|
10
|
-
|
|
9
|
+
let settingsObj = settings.current;
|
|
10
|
+
const handler = settingsObj.connect(`changed::${key}`, () => {
|
|
11
11
|
setValue(getValue());
|
|
12
12
|
});
|
|
13
|
-
return () =>
|
|
14
|
-
}, [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
return () => settingsObj.disconnect(handler);
|
|
14
|
+
}, [
|
|
15
|
+
settings,
|
|
16
|
+
key,
|
|
17
|
+
getValue
|
|
18
|
+
]);
|
|
19
|
+
return [value, useCallback(() => (newValue) => {
|
|
20
|
+
settings.current.set_value(key, newValue);
|
|
21
|
+
}, [key])];
|
|
19
22
|
}
|
|
20
|
-
|
|
21
23
|
//#endregion
|
|
22
|
-
export { useSetting };
|
|
24
|
+
export { useSetting };
|
package/dist/gobject/index.mjs
CHANGED
|
@@ -2,8 +2,10 @@ import { RefObject } from "react";
|
|
|
2
2
|
import GObject from "gi://GObject?version=2.0";
|
|
3
3
|
|
|
4
4
|
//#region src/gobject/use-binding.d.ts
|
|
5
|
-
type
|
|
6
|
-
|
|
7
|
-
declare function useBinding<T extends GObject.Object, Prop extends
|
|
5
|
+
type PropertyOf<T extends GObject.Object> = Extract<keyof T["$readableProperties"], string>;
|
|
6
|
+
type PropertyType<T, Prop extends keyof T> = T["$readableProperties"][Prop];
|
|
7
|
+
declare function useBinding<T extends GObject.Object, Prop extends PropertyOf<T>, PropType extends PropertyType<T, Prop>>(object: T | RefObject<T>, property: Prop, defaultValue?: null): [PropType];
|
|
8
|
+
declare function useBinding<T extends GObject.Object, Prop extends PropertyOf<T>, PropType extends PropertyType<T, Prop>>(object: T | RefObject<T | null>, property: Prop, defaultValue: PropType): [PropType];
|
|
9
|
+
declare function useBinding<T extends GObject.Object, Prop extends PropertyOf<T>, PropType extends PropertyType<T, Prop>>(object: T | RefObject<T | null>, property: Prop, defaultValue?: null): [PropType | null];
|
|
8
10
|
//#endregion
|
|
9
11
|
export { useBinding };
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { useReference } from "../base/use-reference.mjs";
|
|
2
2
|
import "../base/index.mjs";
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
|
-
|
|
5
4
|
//#region src/gobject/use-binding.ts
|
|
6
|
-
function useBinding(object,
|
|
7
|
-
const property = toKebabCase(_property);
|
|
5
|
+
function useBinding(object, property, defaultValue) {
|
|
8
6
|
const value = useReference(object);
|
|
9
7
|
const [result, setResult] = useState(() => {
|
|
10
|
-
if (!value) return defaultValue;
|
|
11
|
-
|
|
12
|
-
return converter ? converter(initialResult) : initialResult;
|
|
8
|
+
if (!value) return defaultValue ?? null;
|
|
9
|
+
return value[property];
|
|
13
10
|
});
|
|
14
11
|
useEffect(() => {
|
|
15
12
|
if (!value) return;
|
|
@@ -19,12 +16,8 @@ function useBinding(object, _property, defaultValue, converter) {
|
|
|
19
16
|
return () => {
|
|
20
17
|
value.disconnect(id);
|
|
21
18
|
};
|
|
22
|
-
}, [value]);
|
|
19
|
+
}, [value, property]);
|
|
23
20
|
return [result];
|
|
24
21
|
}
|
|
25
|
-
function toKebabCase(str) {
|
|
26
|
-
return str.replace(/([A-Z])/g, "-$1").replace(/_/g, "-").toLowerCase();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
22
|
//#endregion
|
|
30
|
-
export { useBinding };
|
|
23
|
+
export { useBinding };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { useAccentColor } from "./adw/use-accent-color.mjs";
|
|
2
2
|
import { useDarkMode } from "./adw/use-dark-mode.mjs";
|
|
3
3
|
import { useReference } from "./base/use-reference.mjs";
|
|
4
|
-
import "./base/index.mjs";
|
|
5
4
|
import { useBinding } from "./gobject/use-binding.mjs";
|
|
6
|
-
import "./gobject/index.mjs";
|
|
7
5
|
export { useAccentColor, useBinding, useDarkMode, useReference };
|
package/dist/index.mjs
CHANGED
|
@@ -5,5 +5,4 @@ import "./gobject/index.mjs";
|
|
|
5
5
|
import { useAccentColor } from "./adw/use-accent-color.mjs";
|
|
6
6
|
import { useDarkMode } from "./adw/use-dark-mode.mjs";
|
|
7
7
|
import "./adw/index.mjs";
|
|
8
|
-
|
|
9
|
-
export { useAccentColor, useBinding, useDarkMode, useReference };
|
|
8
|
+
export { useAccentColor, useBinding, useDarkMode, useReference };
|
package/package.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peachy/hooks",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "",
|
|
5
7
|
"main": "./dist/index.mjs",
|
|
6
8
|
"exports": {
|
|
7
9
|
".": {
|
|
@@ -13,14 +15,12 @@
|
|
|
13
15
|
"types": "./dist/*/index.d.mts"
|
|
14
16
|
}
|
|
15
17
|
},
|
|
16
|
-
"author": "",
|
|
17
|
-
"license": "MIT",
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@types/react": "^19.2.
|
|
19
|
+
"@types/react": "^19.2.14",
|
|
20
20
|
"react": "^19.2.4",
|
|
21
|
-
"tsdown": "0.
|
|
21
|
+
"tsdown": "0.21.0",
|
|
22
22
|
"typescript": "^5.9.3",
|
|
23
|
-
"@peachy/react": "0.0.
|
|
23
|
+
"@peachy/react": "0.0.12"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"react": "^19.2.0"
|
|
@@ -8,14 +8,11 @@ import { useBinding } from "../gobject";
|
|
|
8
8
|
* Query the system's accent color if supported
|
|
9
9
|
* @returns [accentColor] - accent color or null
|
|
10
10
|
*/
|
|
11
|
-
export function useAccentColor() {
|
|
11
|
+
export function useAccentColor(): [accentColor: number | null] {
|
|
12
12
|
const styleManager = useRef(Adw.StyleManager.get_default());
|
|
13
13
|
|
|
14
|
-
const [accentColor] = useBinding(styleManager, "
|
|
15
|
-
const [systemSupportsAccentColors] = useBinding(
|
|
16
|
-
styleManager,
|
|
17
|
-
"systemSupportsAccentColors",
|
|
18
|
-
);
|
|
14
|
+
const [accentColor] = useBinding(styleManager, "accent-color");
|
|
15
|
+
const [systemSupportsAccentColors] = useBinding(styleManager, "system-supports-accent-colors");
|
|
19
16
|
|
|
20
17
|
return [systemSupportsAccentColors ? accentColor : null];
|
|
21
18
|
}
|
package/src/adw/use-dark-mode.ts
CHANGED
|
@@ -4,12 +4,12 @@ import { useCallback, useRef } from "react";
|
|
|
4
4
|
|
|
5
5
|
import { useBinding } from "../gobject";
|
|
6
6
|
|
|
7
|
-
export function useDarkMode() {
|
|
7
|
+
export function useDarkMode(): [isDark: boolean, setDarkMode: (value: boolean) => void] {
|
|
8
8
|
const styleManager = useRef(Adw.StyleManager.get_default());
|
|
9
9
|
|
|
10
|
-
const [isDark] = useBinding(styleManager, "dark"
|
|
10
|
+
const [isDark] = useBinding(styleManager, "dark");
|
|
11
11
|
const setDarkMode = useCallback(
|
|
12
|
-
(value: boolean) => {
|
|
12
|
+
(value: boolean): void => {
|
|
13
13
|
styleManager.current.set_color_scheme(
|
|
14
14
|
value ? Adw.ColorScheme.PREFER_DARK : Adw.ColorScheme.PREFER_LIGHT,
|
|
15
15
|
);
|
|
@@ -17,5 +17,5 @@ export function useDarkMode() {
|
|
|
17
17
|
[styleManager],
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
-
return [isDark, setDarkMode];
|
|
20
|
+
return [isDark, setDarkMode] as const;
|
|
21
21
|
}
|
|
@@ -3,10 +3,7 @@ import { RefObject, useEffect, useState } from "react";
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns the value inside a `ref`, correctly checking it after the initial render
|
|
5
5
|
*/
|
|
6
|
-
export function useReference<T>(
|
|
7
|
-
value: T | RefObject<T>,
|
|
8
|
-
defaultValue?: T,
|
|
9
|
-
): T | null {
|
|
6
|
+
export function useReference<T>(value: T | RefObject<T>, defaultValue?: T): T | null {
|
|
10
7
|
const [result, setResult] = useState<T | null>(() => {
|
|
11
8
|
return getValue(value) ?? (defaultValue || null);
|
|
12
9
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Gio from "gi://Gio?version=2.0";
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
4
|
|
|
4
5
|
interface NetworkMonitor {
|
|
5
6
|
connected: boolean;
|
|
@@ -9,27 +10,29 @@ interface NetworkMonitor {
|
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export function useNetworkMonitor(): NetworkMonitor {
|
|
12
|
-
const monitor = Gio.NetworkMonitor.get_default();
|
|
13
|
+
const monitor = useRef(Gio.NetworkMonitor.get_default());
|
|
13
14
|
const [state, setState] = useState(() => calculateState());
|
|
14
15
|
|
|
15
16
|
const calculateState = useCallback(() => {
|
|
16
17
|
return {
|
|
17
|
-
available: monitor.
|
|
18
|
-
connected: monitor.connectivity === Gio.NetworkConnectivity.FULL,
|
|
19
|
-
state: monitor.connectivity,
|
|
20
|
-
metered: monitor.
|
|
18
|
+
available: monitor.current.networkAvailable,
|
|
19
|
+
connected: monitor.current.connectivity === Gio.NetworkConnectivity.FULL,
|
|
20
|
+
state: monitor.current.connectivity,
|
|
21
|
+
metered: monitor.current.networkMetered,
|
|
21
22
|
} as NetworkMonitor;
|
|
22
|
-
}, []);
|
|
23
|
+
}, [monitor]);
|
|
23
24
|
|
|
24
25
|
useEffect(() => {
|
|
25
|
-
const
|
|
26
|
+
const monitorObj = monitor.current;
|
|
27
|
+
|
|
28
|
+
const id = monitorObj.connect("network-changed", () => {
|
|
26
29
|
setState(calculateState());
|
|
27
30
|
});
|
|
28
31
|
|
|
29
32
|
return () => {
|
|
30
|
-
|
|
33
|
+
monitorObj.disconnect(id);
|
|
31
34
|
};
|
|
32
|
-
}, []);
|
|
35
|
+
}, [calculateState]);
|
|
33
36
|
|
|
34
37
|
return state;
|
|
35
38
|
}
|
package/src/gio/use-setting.ts
CHANGED
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
import Gio from "gi://Gio?version=2.0";
|
|
2
2
|
import GLib from "gi://GLib?version=2.0";
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
5
|
|
|
5
6
|
export function useSetting<T = unknown>(schema: string, key: string) {
|
|
6
|
-
const settings = Gio.Settings.new(schema);
|
|
7
|
+
const settings = useRef(Gio.Settings.new(schema));
|
|
7
8
|
|
|
8
|
-
const getValue = (
|
|
9
|
+
const getValue = useCallback(
|
|
10
|
+
() => settings.current.get_value(key).recursiveUnpack() as T,
|
|
11
|
+
[key, settings],
|
|
12
|
+
);
|
|
9
13
|
|
|
10
14
|
const [value, setValue] = useState<T>(() => getValue());
|
|
11
15
|
|
|
12
16
|
useEffect(() => {
|
|
13
|
-
|
|
17
|
+
let settingsObj = settings.current;
|
|
18
|
+
|
|
19
|
+
const handler = settingsObj.connect(`changed::${key}`, () => {
|
|
14
20
|
setValue(getValue());
|
|
15
21
|
});
|
|
16
22
|
|
|
17
|
-
return () =>
|
|
18
|
-
}, [settings, key]);
|
|
23
|
+
return () => settingsObj.disconnect(handler);
|
|
24
|
+
}, [settings, key, getValue]);
|
|
19
25
|
|
|
20
|
-
const changeValue = (
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
const changeValue = useCallback(
|
|
27
|
+
() => (newValue: GLib.Variant) => {
|
|
28
|
+
settings.current.set_value(key, newValue);
|
|
29
|
+
},
|
|
30
|
+
[key],
|
|
31
|
+
);
|
|
23
32
|
|
|
24
33
|
return [value, changeValue] as [T, (newValue: GLib.Variant) => void];
|
|
25
34
|
}
|
|
@@ -1,53 +1,43 @@
|
|
|
1
1
|
import GObject from "gi://GObject?version=2.0";
|
|
2
|
+
|
|
2
3
|
import { RefObject, useEffect, useState } from "react";
|
|
4
|
+
|
|
3
5
|
import { useReference } from "../base";
|
|
4
6
|
|
|
5
|
-
type
|
|
6
|
-
[K in keyof T]: T[K] extends Function
|
|
7
|
-
? never
|
|
8
|
-
: K extends Symbol
|
|
9
|
-
? never
|
|
10
|
-
: K extends number
|
|
11
|
-
? never
|
|
12
|
-
: K;
|
|
13
|
-
}[keyof T];
|
|
7
|
+
type PropertyOf<T extends GObject.Object> = Extract<keyof T["$readableProperties"], string>;
|
|
14
8
|
|
|
9
|
+
/// @ts-expect-error broken
|
|
10
|
+
type PropertyType<T, Prop extends keyof T> = T["$readableProperties"][Prop];
|
|
11
|
+
|
|
12
|
+
// when your ref is non-nullable, the result is never null
|
|
15
13
|
export function useBinding<
|
|
16
14
|
T extends GObject.Object,
|
|
17
|
-
Prop extends
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
defaultValue?: T[Prop],
|
|
22
|
-
converter?: undefined,
|
|
23
|
-
): [T[Prop]];
|
|
15
|
+
Prop extends PropertyOf<T>,
|
|
16
|
+
PropType extends PropertyType<T, Prop>,
|
|
17
|
+
>(object: T | RefObject<T>, property: Prop, defaultValue?: null): [PropType];
|
|
18
|
+
// when the ref is nullable but you provided a default value, the result is never null
|
|
24
19
|
export function useBinding<
|
|
25
20
|
T extends GObject.Object,
|
|
26
|
-
Prop extends
|
|
27
|
-
|
|
28
|
-
>(
|
|
29
|
-
|
|
30
|
-
property: Prop,
|
|
31
|
-
defaultValue: T[Prop] | undefined,
|
|
32
|
-
converter: Converter,
|
|
33
|
-
): [ReturnType<Converter>];
|
|
21
|
+
Prop extends PropertyOf<T>,
|
|
22
|
+
PropType extends PropertyType<T, Prop>,
|
|
23
|
+
>(object: T | RefObject<T | null>, property: Prop, defaultValue: PropType): [PropType];
|
|
24
|
+
// when you didn't provide a default value, the result can be null
|
|
34
25
|
export function useBinding<
|
|
35
26
|
T extends GObject.Object,
|
|
36
|
-
Prop extends
|
|
37
|
-
|
|
38
|
-
>(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
27
|
+
Prop extends PropertyOf<T>,
|
|
28
|
+
PropType extends PropertyType<T, Prop>,
|
|
29
|
+
>(object: T | RefObject<T | null>, property: Prop, defaultValue?: null): [PropType | null];
|
|
30
|
+
// base implementation
|
|
31
|
+
export function useBinding<
|
|
32
|
+
T extends GObject.Object,
|
|
33
|
+
Prop extends PropertyOf<T>,
|
|
34
|
+
PropType extends PropertyType<T, Prop>,
|
|
35
|
+
>(object: T | RefObject<T>, property: Prop, defaultValue?: PropType): any {
|
|
45
36
|
const value = useReference(object);
|
|
46
37
|
|
|
47
38
|
const [result, setResult] = useState(() => {
|
|
48
|
-
if (!value) return defaultValue;
|
|
49
|
-
|
|
50
|
-
return converter ? converter(initialResult) : initialResult;
|
|
39
|
+
if (!value) return defaultValue ?? null;
|
|
40
|
+
return value[property];
|
|
51
41
|
});
|
|
52
42
|
|
|
53
43
|
// run this on initial render
|
|
@@ -56,21 +46,15 @@ export function useBinding<
|
|
|
56
46
|
return;
|
|
57
47
|
}
|
|
58
48
|
|
|
49
|
+
// @ts-expect-error trust me, we are listening to a property
|
|
59
50
|
const id = value.connect(`notify::${property}`, () => {
|
|
60
|
-
setResult(value[property
|
|
51
|
+
setResult(value[property]);
|
|
61
52
|
});
|
|
62
53
|
|
|
63
54
|
return () => {
|
|
64
55
|
value.disconnect(id);
|
|
65
56
|
};
|
|
66
|
-
}, [value]);
|
|
57
|
+
}, [value, property]);
|
|
67
58
|
|
|
68
59
|
return [result] as const;
|
|
69
60
|
}
|
|
70
|
-
|
|
71
|
-
function toKebabCase(str: string): string {
|
|
72
|
-
return str
|
|
73
|
-
.replace(/([A-Z])/g, "-$1")
|
|
74
|
-
.replace(/_/g, "-")
|
|
75
|
-
.toLowerCase();
|
|
76
|
-
}
|
package/tsconfig.json
CHANGED
package/tsdown.config.mjs
CHANGED
package/dist/types.d.mts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
package/dist/types.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
package/src/types.ts
DELETED
|
File without changes
|