@gtkx/css 0.14.0 → 0.16.0
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 +2 -1
- package/dist/css.d.ts +4 -4
- package/dist/css.js +19 -30
- package/dist/style-sheet.js +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -71,6 +71,7 @@ render(<App />, "com.example.counter");
|
|
|
71
71
|
- **React 19** — Hooks, concurrent features, and the component model you know
|
|
72
72
|
- **Native GTK4 widgets** — Real native controls, not web components in a webview
|
|
73
73
|
- **Adwaita support** — Modern GNOME styling with Libadwaita components
|
|
74
|
+
- **Declarative animations** — Framer Motion-like API using native Adwaita animations
|
|
74
75
|
- **Hot Module Replacement** — Fast refresh during development
|
|
75
76
|
- **TypeScript first** — Full type safety with auto-generated bindings
|
|
76
77
|
- **CSS-in-JS styling** — Familiar styling patterns adapted for GTK
|
|
@@ -80,11 +81,11 @@ render(<App />, "com.example.counter");
|
|
|
80
81
|
|
|
81
82
|
Explore complete applications in the [`examples/`](./examples) directory:
|
|
82
83
|
|
|
83
|
-
- **[browser](./examples/browser)** — Simple browser using WebKitWebView
|
|
84
84
|
- **[gtk-demo](./examples/gtk-demo)** — Full replica of the official GTK demo app
|
|
85
85
|
- **[hello-world](./examples/hello-world)** — Minimal application showing a counter
|
|
86
86
|
- **[todo](./examples/todo)** — Full-featured todo application with Adwaita styling and testing
|
|
87
87
|
- **[x-showcase](./examples/x-showcase)** — Showcase of all x.\* virtual components
|
|
88
|
+
- **[browser](./examples/browser)** — Simple browser using WebKitWebView
|
|
88
89
|
- **[deploying](./examples/deploying)** — Example of packaging and distributing a GTKX app
|
|
89
90
|
|
|
90
91
|
## Documentation
|
package/dist/css.d.ts
CHANGED
|
@@ -43,12 +43,12 @@ type CSSClassName = string & {
|
|
|
43
43
|
*/
|
|
44
44
|
export declare const css: (...args: CSSInterpolation[]) => CSSClassName;
|
|
45
45
|
/**
|
|
46
|
-
* Combines multiple class names into
|
|
46
|
+
* Combines multiple class names into an array for use with cssClasses prop.
|
|
47
47
|
*
|
|
48
48
|
* Filters out falsy values, allowing conditional class application.
|
|
49
49
|
*
|
|
50
50
|
* @param classNames - Class names, booleans, undefined, or null values
|
|
51
|
-
* @returns
|
|
51
|
+
* @returns Array of valid class names
|
|
52
52
|
*
|
|
53
53
|
* @example
|
|
54
54
|
* ```tsx
|
|
@@ -58,12 +58,12 @@ export declare const css: (...args: CSSInterpolation[]) => CSSClassName;
|
|
|
58
58
|
* const active = css({ backgroundColor: "@accent_bg_color" });
|
|
59
59
|
*
|
|
60
60
|
* <GtkButton
|
|
61
|
-
* cssClasses={
|
|
61
|
+
* cssClasses={cx(base, isActive && active, "custom-class")}
|
|
62
62
|
* label="Button"
|
|
63
63
|
* />
|
|
64
64
|
* ```
|
|
65
65
|
*/
|
|
66
|
-
export declare const cx: (...classNames: (string | boolean | undefined | null)[]) => string;
|
|
66
|
+
export declare const cx: (...classNames: (string | boolean | undefined | null)[]) => string[];
|
|
67
67
|
/**
|
|
68
68
|
* Injects global CSS styles without a wrapping class.
|
|
69
69
|
*
|
package/dist/css.js
CHANGED
|
@@ -4,48 +4,37 @@ function expandNestedRules(styles, className) {
|
|
|
4
4
|
const selector = `.${className}`;
|
|
5
5
|
const expandedStyles = styles.replace(/&/g, selector);
|
|
6
6
|
const rules = [];
|
|
7
|
-
let
|
|
7
|
+
let topLevelProperties = "";
|
|
8
|
+
let currentSegment = "";
|
|
8
9
|
let braceDepth = 0;
|
|
9
|
-
let inSelector = false;
|
|
10
|
-
let mainProperties = "";
|
|
11
10
|
for (let i = 0; i < expandedStyles.length; i++) {
|
|
12
11
|
const char = expandedStyles[i];
|
|
13
12
|
if (char === "{") {
|
|
13
|
+
currentSegment += char;
|
|
14
14
|
braceDepth++;
|
|
15
|
-
if (braceDepth === 1 && currentRule.includes(selector)) {
|
|
16
|
-
inSelector = true;
|
|
17
|
-
currentRule += char;
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
currentRule += char;
|
|
21
|
-
}
|
|
22
15
|
}
|
|
23
16
|
else if (char === "}") {
|
|
24
17
|
braceDepth--;
|
|
25
|
-
|
|
26
|
-
if (braceDepth === 0
|
|
27
|
-
rules.push(
|
|
28
|
-
|
|
29
|
-
inSelector = false;
|
|
18
|
+
currentSegment += char;
|
|
19
|
+
if (braceDepth === 0) {
|
|
20
|
+
rules.push(currentSegment.trim());
|
|
21
|
+
currentSegment = "";
|
|
30
22
|
}
|
|
31
23
|
}
|
|
32
|
-
else if (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
currentRule = "";
|
|
36
|
-
}
|
|
37
|
-
currentRule += char;
|
|
24
|
+
else if (char === ";" && braceDepth === 0) {
|
|
25
|
+
topLevelProperties += currentSegment + char;
|
|
26
|
+
currentSegment = "";
|
|
38
27
|
}
|
|
39
28
|
else {
|
|
40
|
-
|
|
29
|
+
currentSegment += char;
|
|
41
30
|
}
|
|
42
31
|
}
|
|
43
|
-
if (
|
|
44
|
-
|
|
32
|
+
if (currentSegment.trim() && braceDepth === 0) {
|
|
33
|
+
topLevelProperties += currentSegment;
|
|
45
34
|
}
|
|
46
35
|
const allRules = [];
|
|
47
|
-
if (
|
|
48
|
-
allRules.push(`${selector}{${
|
|
36
|
+
if (topLevelProperties.trim()) {
|
|
37
|
+
allRules.push(`${selector}{${topLevelProperties.trim()}}`);
|
|
49
38
|
}
|
|
50
39
|
allRules.push(...rules);
|
|
51
40
|
return allRules.join("\n");
|
|
@@ -99,12 +88,12 @@ export const css = (...args) => {
|
|
|
99
88
|
return className;
|
|
100
89
|
};
|
|
101
90
|
/**
|
|
102
|
-
* Combines multiple class names into
|
|
91
|
+
* Combines multiple class names into an array for use with cssClasses prop.
|
|
103
92
|
*
|
|
104
93
|
* Filters out falsy values, allowing conditional class application.
|
|
105
94
|
*
|
|
106
95
|
* @param classNames - Class names, booleans, undefined, or null values
|
|
107
|
-
* @returns
|
|
96
|
+
* @returns Array of valid class names
|
|
108
97
|
*
|
|
109
98
|
* @example
|
|
110
99
|
* ```tsx
|
|
@@ -114,12 +103,12 @@ export const css = (...args) => {
|
|
|
114
103
|
* const active = css({ backgroundColor: "@accent_bg_color" });
|
|
115
104
|
*
|
|
116
105
|
* <GtkButton
|
|
117
|
-
* cssClasses={
|
|
106
|
+
* cssClasses={cx(base, isActive && active, "custom-class")}
|
|
118
107
|
* label="Button"
|
|
119
108
|
* />
|
|
120
109
|
* ```
|
|
121
110
|
*/
|
|
122
|
-
export const cx = (...classNames) => classNames.filter((cn) => typeof cn === "string" && cn.length > 0)
|
|
111
|
+
export const cx = (...classNames) => classNames.filter((cn) => typeof cn === "string" && cn.length > 0);
|
|
123
112
|
/**
|
|
124
113
|
* Injects global CSS styles without a wrapping class.
|
|
125
114
|
*
|
package/dist/style-sheet.js
CHANGED
|
@@ -12,7 +12,7 @@ const flushPendingStyles = () => {
|
|
|
12
12
|
const registerStartListener = () => {
|
|
13
13
|
events.once("start", flushPendingStyles);
|
|
14
14
|
};
|
|
15
|
-
if (!isStarted
|
|
15
|
+
if (!isStarted) {
|
|
16
16
|
registerStartListener();
|
|
17
17
|
}
|
|
18
18
|
export class StyleSheet {
|
|
@@ -43,7 +43,7 @@ export class StyleSheet {
|
|
|
43
43
|
}
|
|
44
44
|
insert(rule) {
|
|
45
45
|
this.rules.push(rule);
|
|
46
|
-
if (isStarted
|
|
46
|
+
if (isStarted) {
|
|
47
47
|
this.ensureProvider();
|
|
48
48
|
this.updateProvider();
|
|
49
49
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/css",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Emotion-style CSS-in-JS for GTKX applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtkx",
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@emotion/cache": "^11.14.0",
|
|
41
41
|
"@emotion/serialize": "^1.3.3",
|
|
42
|
-
"@gtkx/ffi": "0.
|
|
42
|
+
"@gtkx/ffi": "0.16.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@gtkx/vitest": "0.
|
|
45
|
+
"@gtkx/vitest": "0.16.0"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsc -b && cp ../../README.md .",
|