@gjsify/gtk-host 0.45.0 → 0.46.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/lib/esm/conformance/diagnostics.js +1 -1
- package/lib/esm/conformance/index.js +1 -1
- package/lib/esm/descriptors/adw.js +1 -1
- package/lib/esm/generated/widgets.js +1 -1
- package/lib/esm/host.js +1 -1
- package/lib/esm/index.js +1 -1
- package/lib/esm/list/controller.js +1 -1
- package/lib/esm/policies.js +1 -1
- package/lib/esm/probe.js +1 -1
- package/lib/esm/props.js +1 -1
- package/lib/esm/registry.js +1 -1
- package/lib/esm/style/document.js +1 -0
- package/lib/esm/style/gtk-props.js +1 -1
- package/lib/esm/style/index.js +1 -1
- package/lib/esm/style/layout.js +1 -1
- package/lib/esm/style/paint.js +1 -1
- package/lib/esm/style/sheet.js +3 -3
- package/lib/esm/style/theme.js +3 -0
- package/lib/esm/style/tokens.js +1 -1
- package/lib/types/descriptors/index.d.ts +1 -1
- package/lib/types/generated/props.d.ts +611 -822
- package/lib/types/generated/widgets.d.ts +1 -1
- package/lib/types/generator/emit-types.d.mts +1 -1
- package/lib/types/generator/emit.d.mts +16 -6
- package/lib/types/generator/girs-vocabulary.d.mts +45 -0
- package/lib/types/generator/main.d.mts +16 -8
- package/lib/types/generator/model.d.mts +95 -0
- package/lib/types/generator/names.d.mts +19 -0
- package/lib/types/generator/vocabulary-dts.d.mts +47 -0
- package/lib/types/host.d.ts +1 -1
- package/lib/types/policies.d.ts +7 -1
- package/lib/types/props.d.ts +13 -1
- package/lib/types/registry.d.ts +1 -1
- package/lib/types/style/document.d.ts +22 -0
- package/lib/types/style/index.d.ts +6 -3
- package/lib/types/style/layout.d.ts +34 -0
- package/lib/types/style/sheet.d.ts +0 -5
- package/lib/types/style/theme.d.ts +158 -0
- package/lib/types/style/theme.spec.d.ts +2 -0
- package/lib/types/style/tokens.d.ts +76 -0
- package/lib/types/style/tokens.spec.d.ts +2 -0
- package/lib/types/types.d.ts +63 -0
- package/package.json +14 -15
- package/lib/types/generator/gir.d.mts +0 -190
- package/lib/types/generator/mini.fixture.d.mts +0 -30
- package/lib/types/generator/surface.d.mts +0 -62
- package/lib/types/generator/tsmap.d.mts +0 -73
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* arrives as `unknown` so using it fails (TS2345). A generated surface that
|
|
24
24
|
* typed handlers loosely would break every handler that names its parameter.
|
|
25
25
|
*/
|
|
26
|
-
import type { SurfaceModel } from './
|
|
26
|
+
import type { SurfaceModel } from './model.mjs';
|
|
27
27
|
/**
|
|
28
28
|
* Volar's own resolution rule, reproduced so the generator can SEE the gap.
|
|
29
29
|
*
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
* answer. The machine-INDEPENDENT check is the runtime one that already exists —
|
|
18
18
|
* `descriptorProblems()` against the installed typelib.
|
|
19
19
|
*/
|
|
20
|
-
import type {
|
|
21
|
-
import type { GirClass, GirNamespace } from './gir.mjs';
|
|
20
|
+
import type { WidgetDescriptor } from '../types.js';
|
|
22
21
|
/**
|
|
23
22
|
* The `gi://` import a generated table needs, per GIR namespace.
|
|
24
23
|
*
|
|
@@ -29,12 +28,23 @@ import type { GirClass, GirNamespace } from './gir.mjs';
|
|
|
29
28
|
* trust.
|
|
30
29
|
*/
|
|
31
30
|
export declare const GJS_MODULES: Readonly<Record<string, string>>;
|
|
31
|
+
/** What a widget row needs. Three fields, not a GIR class — see `girs-vocabulary.mts`. */
|
|
32
|
+
export interface WidgetRow {
|
|
33
|
+
readonly gtype: string;
|
|
34
|
+
readonly namespace: string;
|
|
35
|
+
readonly name: string;
|
|
36
|
+
}
|
|
32
37
|
export interface EmitInput {
|
|
33
|
-
|
|
34
|
-
readonly
|
|
38
|
+
/** The provenance line, verbatim: `Gtk-4.0/4.23.3 Adw-1/1.8.0`. */
|
|
39
|
+
readonly provenance: string;
|
|
40
|
+
readonly widgets: readonly WidgetRow[];
|
|
41
|
+
/**
|
|
42
|
+
* Every GType the vocabulary knows, widgets and bases alike. G1 asks whether a curated
|
|
43
|
+
* row names something that exists, and a widget-only set would report every curated
|
|
44
|
+
* base as missing.
|
|
45
|
+
*/
|
|
46
|
+
readonly knownGTypes: ReadonlySet<string>;
|
|
35
47
|
readonly curated: readonly WidgetDescriptor[];
|
|
36
|
-
/** `methodsOf` from the conformance module — one extractor, not a second copy. */
|
|
37
|
-
readonly methodsOf: (policy: ChildPolicy) => string[];
|
|
38
48
|
/** GIR namespace -> `gi://` import. Defaults to the GTK/Adwaita pair. */
|
|
39
49
|
readonly modules?: Readonly<Record<string, string>>;
|
|
40
50
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the widget vocabulary from `@girs/<ns>/vocabulary` and build the emitter's model.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS REPLACED A GIR READER. This package used to parse the `.gir` XML itself, which
|
|
5
|
+
* made it the SECOND reader of a format ts-for-gir already reads — and two readers of one
|
|
6
|
+
* format are two truths that drift apart silently. ADR 0029 moved the vocabulary into
|
|
7
|
+
* `@girs/*` so there is one. What stays here is the DIALECT: kebab tags, the camelCase
|
|
8
|
+
* second spelling, `on<Signal>` prop names, Vue's Volar aliases. None of that is in the
|
|
9
|
+
* vocabulary and none of it belongs there, as its own header says.
|
|
10
|
+
*
|
|
11
|
+
* WHY IT READS BOTH HALVES. The runtime `.js` carries the facts as values (`OWN_PROPS`,
|
|
12
|
+
* `DECLS`, `OWN_SIGNALS`, `ENUM_NICKS`), which is what a check can compare against a live
|
|
13
|
+
* typelib. The `.d.ts` carries the rendered TypeScript for each property, which no amount
|
|
14
|
+
* of runtime data can reconstruct: `GtkBaselinePositionNick | Gtk.BaselinePosition`
|
|
15
|
+
* depends on that file's own imports. So the types come from the declarations and the
|
|
16
|
+
* facts come from the values, and neither is re-derived from the other.
|
|
17
|
+
*
|
|
18
|
+
* The `.d.ts` half is READ in `vocabulary-dts.mts`, which touches no file and so
|
|
19
|
+
* imports no `gi://` — that is what lets `generator.spec.ts` pin its regexes against
|
|
20
|
+
* literal fixtures instead of against whichever `@girs` happens to be installed.
|
|
21
|
+
*/
|
|
22
|
+
import type { SurfaceModel } from './model.mjs';
|
|
23
|
+
/** The three fields `emit-types.mts` reads off a widget. Not a GIR class any more. */
|
|
24
|
+
export interface WidgetRef {
|
|
25
|
+
readonly gtype: string;
|
|
26
|
+
readonly namespace: string;
|
|
27
|
+
readonly name: string;
|
|
28
|
+
}
|
|
29
|
+
export interface VocabularySource {
|
|
30
|
+
/** Import name, e.g. `gtk-4.0`. */
|
|
31
|
+
readonly pkg: string;
|
|
32
|
+
/** GType prefix, e.g. `Gtk`. */
|
|
33
|
+
readonly prefix: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Load the vocabulary packages and build the model the emitters already consume.
|
|
37
|
+
*
|
|
38
|
+
* `dir` is the `node_modules/@girs` root; the caller resolves it, because a generator
|
|
39
|
+
* should not guess where its own dependencies live.
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildFromVocabulary(dir: string, sources: readonly VocabularySource[]): Promise<{
|
|
42
|
+
model: SurfaceModel;
|
|
43
|
+
widgets: WidgetRef[];
|
|
44
|
+
provenance: string;
|
|
45
|
+
}>;
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The generator CLI.
|
|
3
3
|
*
|
|
4
|
-
* gjsify run generate -- [--
|
|
4
|
+
* gjsify run generate -- [--girs-dir DIR] [--out DIR]
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* this repository
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
6
|
+
* WHERE THE VOCABULARY COMES FROM. The input used to be GIR XML: distro artefacts
|
|
7
|
+
* that are not in this repository, 6.2 MB for `Gtk-4.0.gir` alone, with four GTK
|
|
8
|
+
* versions on the maintainer workstation and no way to know which one a build saw.
|
|
9
|
+
* It is now the `@girs/<ns>/vocabulary` subpath (ADR 0029), which is an ordinary
|
|
10
|
+
* dependency, resolved like any other. That closes the provenance question the old
|
|
11
|
+
* route could only answer by convention: each vocabulary states the namespace,
|
|
12
|
+
* version and library version it was generated from, and this generator copies that
|
|
13
|
+
* into the artefact header instead of naming the files it happened to read.
|
|
14
|
+
*
|
|
15
|
+
* `--girs-dir` stays an argument so a locally built `@girs` can be generated against
|
|
16
|
+
* before it is published. Without it the directory is found by walking up from the
|
|
17
|
+
* working directory, which is what makes `npm run generate` work from the package.
|
|
18
|
+
*
|
|
19
|
+
* The ARTEFACT remains committed (ADR 0028 § Implementation): a fresh clone builds,
|
|
20
|
+
* checks, packs and tests without regenerating anything.
|
|
13
21
|
*
|
|
14
22
|
* THERE IS NO `--check` MODE, and the attempt to add one is worth recording: the
|
|
15
23
|
* `generate` script pipes the output through `gjsify format`, which reflows it
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The declaration graph the type surfaces are emitted from — the shape only.
|
|
3
|
+
*
|
|
4
|
+
* ONE INTERFACE PER DECLARATION, carrying its OWN members and extending its bases —
|
|
5
|
+
* not one flat interface per widget. The measurement decides it: the concrete widgets
|
|
6
|
+
* have thousands of writable property slots between them and a few hundred distinct
|
|
7
|
+
* property names. Flattening would emit the same `visible?: boolean` once per widget;
|
|
8
|
+
* mirroring the inheritance the vocabulary reports emits it once, on `GtkWidgetProps`,
|
|
9
|
+
* and the diff of a GTK update then shows what actually changed.
|
|
10
|
+
*
|
|
11
|
+
* WHO FILLS IT. `girs-vocabulary.mts`, from `@girs/<ns>/vocabulary`. This module used
|
|
12
|
+
* to hold a `buildSurface()` that filled the same shape from GIR XML this package
|
|
13
|
+
* parsed itself; ADR 0029 moved the vocabulary into `@girs/*` so there is one reader
|
|
14
|
+
* of that format instead of two. Only the shape survived, which is why the file is
|
|
15
|
+
* `model.mts` and no longer `surface.mts`: `surface` now names the `@girs` subpath.
|
|
16
|
+
*/
|
|
17
|
+
import type { WidgetRow } from './emit.mjs';
|
|
18
|
+
export interface PropMember {
|
|
19
|
+
readonly kebab: string;
|
|
20
|
+
readonly camel: string;
|
|
21
|
+
readonly ts: string;
|
|
22
|
+
/**
|
|
23
|
+
* The hover blurb, from the JSDoc above the property in the vocabulary's `.d.ts`.
|
|
24
|
+
*
|
|
25
|
+
* The typelib strips documentation by design — which is why gi-docgen reads the
|
|
26
|
+
* GIR — and hover text is what a published type surface is FOR (ADR 0028 § 6). So
|
|
27
|
+
* the doc travels with the rendered type, out of the half of the vocabulary that
|
|
28
|
+
* can carry it; the runtime half is values, and a value cannot hold a comment.
|
|
29
|
+
*/
|
|
30
|
+
readonly doc?: string;
|
|
31
|
+
readonly deprecated: boolean;
|
|
32
|
+
readonly since?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface SignalMember {
|
|
35
|
+
readonly signal: string;
|
|
36
|
+
readonly prop: string;
|
|
37
|
+
/** Already rendered — `Gtk.ListBox.SignalSignatures['row-activated']`. */
|
|
38
|
+
readonly ts: string;
|
|
39
|
+
readonly doc?: string;
|
|
40
|
+
readonly deprecated: boolean;
|
|
41
|
+
readonly since?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface Declaration {
|
|
44
|
+
/** Namespace-qualified — `Gtk.Box`. The graph is keyed on this, the way GIR references. */
|
|
45
|
+
readonly key: string;
|
|
46
|
+
readonly gtype: string;
|
|
47
|
+
readonly kind: 'class' | 'interface';
|
|
48
|
+
/** `GtkBoxProps`. */
|
|
49
|
+
readonly iface: string;
|
|
50
|
+
readonly bases: readonly string[];
|
|
51
|
+
readonly props: readonly PropMember[];
|
|
52
|
+
readonly signals: readonly SignalMember[];
|
|
53
|
+
readonly doc?: string;
|
|
54
|
+
/**
|
|
55
|
+
* The library release this TYPE arrived in, where GIR states one.
|
|
56
|
+
*
|
|
57
|
+
* Distinct from a member's `since`: it answers "does the installed library have
|
|
58
|
+
* this class at all", which is the question a bare `ctor()` returning `undefined`
|
|
59
|
+
* used to ask by crashing. Only about 11% of GIR classes carry a `version`, so an
|
|
60
|
+
* absent value means "not stated", never "has always existed".
|
|
61
|
+
*/
|
|
62
|
+
readonly since?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface SurfaceModel {
|
|
65
|
+
/**
|
|
66
|
+
* The widget rows, sorted by GType name.
|
|
67
|
+
*
|
|
68
|
+
* The same three fields the table emitter takes, so the type comes from there
|
|
69
|
+
* rather than being restated — a second spelling of a row is a second thing to
|
|
70
|
+
* keep in step with `girs-vocabulary.mts`, which fills both.
|
|
71
|
+
*/
|
|
72
|
+
readonly widgets: readonly WidgetRow[];
|
|
73
|
+
readonly declarations: ReadonlyMap<string, Declaration>;
|
|
74
|
+
/** Widget GType -> the GTypes of every declaration its members come from, self first. */
|
|
75
|
+
readonly closure: ReadonlyMap<string, readonly string[]>;
|
|
76
|
+
/** Enum GType -> nicks, for the emitted aliases and for the runtime nick check. */
|
|
77
|
+
readonly enumNicks: ReadonlyMap<string, readonly string[]>;
|
|
78
|
+
readonly namespacesUsed: ReadonlySet<string>;
|
|
79
|
+
/** Namespace -> the `@girs` package that types it, so the emitter needs no second source. */
|
|
80
|
+
readonly packages: Readonly<Record<string, string>>;
|
|
81
|
+
/**
|
|
82
|
+
* Base -> members it must not contribute, because a nearer declaration disagrees.
|
|
83
|
+
*
|
|
84
|
+
* EMPTY TODAY, AND NOT DEFENSIVE MACHINERY. TypeScript requires a multiply
|
|
85
|
+
* inherited member to be IDENTICAL in every base — `string` and `string | null`
|
|
86
|
+
* are not — and GTK's interfaces do redeclare class properties, so a base that
|
|
87
|
+
* loses a member has to be emitted as `Omit<Base, 'name'>`: a local redeclaration
|
|
88
|
+
* does NOT repair incompatible bases, it turns one error into another. The GIR
|
|
89
|
+
* route computed those conflicts here; the published vocabulary resolves them
|
|
90
|
+
* upstream, so the map now arrives empty. It stays because `emit-types.mts`
|
|
91
|
+
* renders `Omit<>` from it, and a vocabulary that reintroduces a conflict needs a
|
|
92
|
+
* way to say so — the alternative is a surface that does not compile.
|
|
93
|
+
*/
|
|
94
|
+
readonly omissions: ReadonlyMap<string, ReadonlyMap<string, readonly string[]>>;
|
|
95
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two name transforms this package's DIALECT owns.
|
|
3
|
+
*
|
|
4
|
+
* Everything else that used to live here — the GIR-type-to-TypeScript mapper, the
|
|
5
|
+
* enum-nick unions, the `@girs` package map — moved into `@girs/<ns>/vocabulary`
|
|
6
|
+
* with ADR 0029, which renders each property's type in its own `.d.ts` and ships
|
|
7
|
+
* the nicks as data. What no vocabulary can answer is how a FRAMEWORK spells a
|
|
8
|
+
* member, because every framework spells it differently; that is dialect, it stays
|
|
9
|
+
* here, and it is why this file is `names.mts` and no longer `tsmap.mts`.
|
|
10
|
+
*
|
|
11
|
+
* Both are also read by `generated.spec.ts`, which runs them against the host's own
|
|
12
|
+
* inverse (`toSignalName`) over every generated name. Two independent
|
|
13
|
+
* implementations checked against each other is the point: nothing made them agree,
|
|
14
|
+
* and the first run of that check found that they did not.
|
|
15
|
+
*/
|
|
16
|
+
/** `row-activated` -> `onRowActivated`; `notify` handled by the caller. */
|
|
17
|
+
export declare const eventPropOf: (signal: string) => string;
|
|
18
|
+
/** `can-focus` -> `canFocus`. The inverse of the host's `toPropertyName`. */
|
|
19
|
+
export declare const camelOf: (kebab: string) => string;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** One member, as the `.d.ts` renders it: the TS text plus whatever JSDoc sits above. */
|
|
2
|
+
export interface DeclaredProp {
|
|
3
|
+
readonly ts: string;
|
|
4
|
+
readonly doc?: string;
|
|
5
|
+
readonly since?: string;
|
|
6
|
+
readonly deprecated: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** One `export interface <GType>Props` — its own JSDoc, and its own members. */
|
|
9
|
+
export interface DeclaredInterface {
|
|
10
|
+
readonly doc?: string;
|
|
11
|
+
readonly props: Map<string, DeclaredProp>;
|
|
12
|
+
}
|
|
13
|
+
interface DocBlock {
|
|
14
|
+
readonly doc?: string;
|
|
15
|
+
readonly since?: string;
|
|
16
|
+
readonly deprecated: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The JSDoc block directly above a declaration, or nothing.
|
|
20
|
+
*
|
|
21
|
+
* ADJACENCY IS THE WHOLE RULE. `text` is everything preceding the declaration, so the
|
|
22
|
+
* nearest block above it may belong to a sibling several members up. Requiring
|
|
23
|
+
* whitespace only between that block's terminator and the declaration is what
|
|
24
|
+
* separates "this member is documented" from "some earlier member was".
|
|
25
|
+
*/
|
|
26
|
+
export declare function readDocBlock(text: string): DocBlock;
|
|
27
|
+
/**
|
|
28
|
+
* Read the namespace imports a vocabulary declares: `import type Gdk from
|
|
29
|
+
* '@girs/gdk-4.0'`.
|
|
30
|
+
*
|
|
31
|
+
* These are the only honest answer to "which namespaces do the rendered types reach
|
|
32
|
+
* into". Deriving it from the source list instead emitted `Gdk.RGBA` with no Gdk
|
|
33
|
+
* import — TS2503, in a file nobody edits by hand.
|
|
34
|
+
*/
|
|
35
|
+
export declare function readNamespaceImports(text: string, ownPkg: string): Map<string, string>;
|
|
36
|
+
/**
|
|
37
|
+
* The interfaces a vocabulary `.d.ts` declares, with each property's rendered type.
|
|
38
|
+
*
|
|
39
|
+
* Brace-matched rather than terminated on a closing brace at column 0: an interface
|
|
40
|
+
* body can contain a nested object type, and a reader that stops at the first one
|
|
41
|
+
* silently truncates it. That exact shortcut is already recorded as a defect in two
|
|
42
|
+
* sibling scripts.
|
|
43
|
+
*/
|
|
44
|
+
export declare function readDeclaredInterfaces(text: string): Map<string, DeclaredInterface>;
|
|
45
|
+
/** Property lines plus the JSDoc block immediately above each one. */
|
|
46
|
+
export declare function readProps(body: string): Map<string, DeclaredProp>;
|
|
47
|
+
export {};
|
package/lib/types/host.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import GObject from 'gi://GObject';
|
|
1
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
2
2
|
import type Gtk from '@girs/gtk-4.0';
|
|
3
3
|
import type { HostAnchor, HostElement, HostNode, HostText, WidgetDescriptor } from './types.js';
|
|
4
4
|
export declare function createElement(tag: string, props?: Record<string, unknown>): HostElement;
|
package/lib/types/policies.d.ts
CHANGED
|
@@ -9,8 +9,14 @@ export declare function addressOf(el: HostElement): Gtk.Widget;
|
|
|
9
9
|
* is the spelling anyone reaching for `activatable` or `selectable` uses, and
|
|
10
10
|
* wrapping a row inside a second row nests two selectable widgets and detaches
|
|
11
11
|
* activation from the one the author configured.
|
|
12
|
+
*
|
|
13
|
+
* A `slotted` policy reaches this too, per SLOT: an adder that hands the child to an
|
|
14
|
+
* inner `Gtk.ListBox` needs exactly the same wrap, and `Adw.ExpanderRow`'s `add_row` is
|
|
15
|
+
* one. The measurement behind that is on `ChildPolicy`'s `wrapSlots`; the short version
|
|
16
|
+
* is that `gtk_list_box_remove` does not unwrap, so without this the child leaks behind
|
|
17
|
+
* one `Gtk-WARNING` at unmount.
|
|
12
18
|
*/
|
|
13
|
-
export declare function makeWrapper(policy: ChildPolicy, child: Gtk.Widget): Gtk.Widget | null;
|
|
19
|
+
export declare function makeWrapper(policy: ChildPolicy, child: Gtk.Widget, slot: string | null): Gtk.Widget | null;
|
|
14
20
|
/**
|
|
15
21
|
* A container the host owns that no window shows — the DOM's detached `<div>`.
|
|
16
22
|
*
|
package/lib/types/props.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import GObject from 'gi://GObject';
|
|
1
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
2
2
|
import type { WidgetDescriptor } from './types.js';
|
|
3
3
|
/** `backgroundColor` and `background-color` both name the GObject property `background-color`. */
|
|
4
4
|
export declare function toPropertyName(name: string): string;
|
|
@@ -33,6 +33,18 @@ export declare function constructOnlyNames(klass: GObject.ObjectClass, gtypeName
|
|
|
33
33
|
* assumed. Also the primitive a renderer needs for a "did you mean" diagnostic.
|
|
34
34
|
*/
|
|
35
35
|
export declare const lookupEnumNick: (gtypeName: string, nick: string) => number | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* The member names an installed enum registers, or `undefined` if this host has none.
|
|
38
|
+
*
|
|
39
|
+
* The INVERSE of {@link lookupEnumNick}, and it exists for the one question that
|
|
40
|
+
* function cannot answer: a nick the vocabulary never emitted is absent from every
|
|
41
|
+
* list a check could iterate, so only the host's own members can reveal it. Read off
|
|
42
|
+
* the same `ENUM_NAMESPACES` table, so the two cannot disagree about where an enum
|
|
43
|
+
* lives — a second copy of that list is what made `Pango` missing once already.
|
|
44
|
+
*
|
|
45
|
+
* `$gtype` and anything non-numeric are not members; GJS puts both on the same object.
|
|
46
|
+
*/
|
|
47
|
+
export declare function enumMembers(gtypeName: string): string[] | undefined;
|
|
36
48
|
/**
|
|
37
49
|
* Turn an authored value into one GObject will actually store.
|
|
38
50
|
*
|
package/lib/types/registry.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import GObject from 'gi://GObject';
|
|
1
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
2
2
|
import type { WidgetDescriptor } from './types.js';
|
|
3
3
|
export declare function registerWidget(descriptor: WidgetDescriptor): void;
|
|
4
4
|
export declare function registerWidgets(descriptors: readonly WidgetDescriptor[]): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Gdk from 'gi://Gdk?version=4.0';
|
|
2
|
+
import Gtk from 'gi://Gtk?version=4.0';
|
|
3
|
+
/** A document GTK refused, or one that would have discarded what follows it. */
|
|
4
|
+
export declare class StyleSheetError extends Error {
|
|
5
|
+
readonly name = "StyleSheetError";
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Refuse a document that would take everything after it with it.
|
|
10
|
+
*
|
|
11
|
+
* `subject` names what is being loaded, because the two callers have very different
|
|
12
|
+
* readers: a generated rule is this package's bug, and an application's theme
|
|
13
|
+
* document is the application's.
|
|
14
|
+
*/
|
|
15
|
+
export declare function assertContained(document: string, subject: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Put a provider on a display at `priority`, and say which display that was.
|
|
18
|
+
*
|
|
19
|
+
* `subject` names what is being installed, because the failure a caller has to act
|
|
20
|
+
* on is "there is no display yet" and the fix depends on which document it is.
|
|
21
|
+
*/
|
|
22
|
+
export declare function installProvider(provider: Gtk.CssProvider, subject: string, display: Gdk.Display | null | undefined, priority: number): Gdk.Display;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
export { GTK_CSS_PROBES, GTK_CSS_PROPERTIES, NOT_GTK_CSS } from './gtk-css.js';
|
|
2
2
|
export { GTK_WIDGET_PROPERTIES, GTK_WIDGET_PROPERTY_PROBES, NOT_GTK_WIDGET_PROPERTIES } from './gtk-props.js';
|
|
3
|
-
export { MINIMAL_TOKENS, lookupToken, requireToken } from './tokens.js';
|
|
3
|
+
export { MINIMAL_TOKENS, TAILWIND_DEFAULT_TOKENS, lookupToken, mergeTokens, requireToken, tailwindDefaultHint, } from './tokens.js';
|
|
4
4
|
export type { Scale, StyleTokens } from './tokens.js';
|
|
5
5
|
export { UnknownUtilityError } from './errors.js';
|
|
6
6
|
export { PAINT_PROPERTIES, partitionPaint, resolvePaintUtility } from './paint.js';
|
|
7
7
|
export type { PaintProps } from './paint.js';
|
|
8
8
|
export { LAYOUT_PROPERTIES, partitionLayout, resolveLayoutUtility } from './layout.js';
|
|
9
|
-
export type { AlignValue, Edge, JustifyValue, LayoutIntent, LayoutPartition, LayoutProps, OverlayIntent, } from './layout.js';
|
|
9
|
+
export type { AlignValue, Edge, JustifyValue, LayoutIntent, LayoutPartition, LayoutProps, OverlayIntent, WrapIntent, } from './layout.js';
|
|
10
10
|
export { partition, resolveUtilities, resolveUtility } from './resolve.js';
|
|
11
11
|
export type { Partitioned, StyleProps } from './resolve.js';
|
|
12
|
-
export { StyleSheet,
|
|
12
|
+
export { StyleSheet, VARIANT_PSEUDO } from './sheet.js';
|
|
13
13
|
export type { StyleSheetOptions } from './sheet.js';
|
|
14
|
+
export { assertContained, StyleSheetError } from './document.js';
|
|
15
|
+
export { ADWAITA_NAMED_COLORS, NEUTRAL_THEME, NOT_ADWAITA_NAMED_COLORS, THEME_PROVIDER_PRIORITY, ThemeRegistry, } from './theme.js';
|
|
16
|
+
export type { Theme, ThemeRegistryOptions } from './theme.js';
|
|
@@ -27,6 +27,7 @@ export interface LayoutProps {
|
|
|
27
27
|
paddingBottom?: string;
|
|
28
28
|
paddingLeft?: string;
|
|
29
29
|
flexDirection?: 'row' | 'column';
|
|
30
|
+
flexWrap?: 'nowrap' | 'wrap';
|
|
30
31
|
flexGrow?: string;
|
|
31
32
|
alignItems?: AlignValue;
|
|
32
33
|
justifyContent?: JustifyValue;
|
|
@@ -114,6 +115,25 @@ export interface LayoutIntent {
|
|
|
114
115
|
* `relative` would make it undetectable.
|
|
115
116
|
*/
|
|
116
117
|
readonly overlay?: OverlayIntent;
|
|
118
|
+
/**
|
|
119
|
+
* `flex-wrap` — the element becomes a DIFFERENT WIDGET.
|
|
120
|
+
*
|
|
121
|
+
* A `Gtk.Box` lays its children on one line and has no second line to put
|
|
122
|
+
* anything on. Wrapping on GTK is `Gtk.FlowBox`, which is not another property
|
|
123
|
+
* on the box but another class — so this is the same shape as
|
|
124
|
+
* {@link LayoutIntent.distribute}'s `space-between`: L1 names the widget the
|
|
125
|
+
* answer needs and L2 swaps it, because L1 resolves properties for an element
|
|
126
|
+
* and has no say in what the element becomes.
|
|
127
|
+
*
|
|
128
|
+
* The SPACINGS travel with it, and that is the reason this field carries values
|
|
129
|
+
* at all rather than being a flag. `Gtk.FlowBox` has NO `spacing` (measured,
|
|
130
|
+
* `gtk-props.ts`) — it has `row-spacing` and `column-spacing`, both real at once
|
|
131
|
+
* — so a gap on a wrapping element cannot take the `Gtk.Box:spacing` route the
|
|
132
|
+
* gap routes below use, and the axis-qualified spellings stop being an
|
|
133
|
+
* orientation question. Routing them here is what keeps `gap-*` from emitting a
|
|
134
|
+
* property the widget does not install.
|
|
135
|
+
*/
|
|
136
|
+
readonly wrap?: WrapIntent;
|
|
117
137
|
/**
|
|
118
138
|
* `text-*` — only a text widget aligns text.
|
|
119
139
|
*
|
|
@@ -124,6 +144,20 @@ export interface LayoutIntent {
|
|
|
124
144
|
*/
|
|
125
145
|
readonly textAlign?: 'left' | 'center' | 'right' | 'justify';
|
|
126
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* `flex-nowrap` / `flex-wrap`, with the spacings a wrapping widget needs.
|
|
149
|
+
*
|
|
150
|
+
* `single` is carried rather than dropped for the reason `relative` is: it is the
|
|
151
|
+
* half L2 can hold the other half against, and a resolution that never sees it
|
|
152
|
+
* cannot tell "this element does not wrap" from "nobody asked".
|
|
153
|
+
*/
|
|
154
|
+
export type WrapIntent = {
|
|
155
|
+
readonly lines: 'single';
|
|
156
|
+
} | {
|
|
157
|
+
readonly lines: 'multi';
|
|
158
|
+
readonly rowSpacing?: number;
|
|
159
|
+
readonly columnSpacing?: number;
|
|
160
|
+
};
|
|
127
161
|
export type OverlayIntent = {
|
|
128
162
|
readonly role: 'context';
|
|
129
163
|
} | {
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import Gdk from 'gi://Gdk?version=4.0';
|
|
2
2
|
/** A variant this sheet knows how to express, and the pseudo-class it becomes. */
|
|
3
3
|
export declare const VARIANT_PSEUDO: Readonly<Record<string, string>>;
|
|
4
|
-
/** A rule GTK refused, or one that would have poisoned the document. */
|
|
5
|
-
export declare class StyleSheetError extends Error {
|
|
6
|
-
readonly name = "StyleSheetError";
|
|
7
|
-
constructor(message: string);
|
|
8
|
-
}
|
|
9
4
|
export interface StyleSheetOptions {
|
|
10
5
|
/**
|
|
11
6
|
* Where the provider is installed. Omitted means the default display — the
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import Gdk from 'gi://Gdk?version=4.0';
|
|
2
|
+
/**
|
|
3
|
+
* Where a theme document is installed. See decision 2 for why it is this number.
|
|
4
|
+
*
|
|
5
|
+
* Exported because it is the fact a reader has to check against their own providers,
|
|
6
|
+
* and because a consumer installing a fourth document needs to know what it has to
|
|
7
|
+
* sit between.
|
|
8
|
+
*/
|
|
9
|
+
export declare const THEME_PROVIDER_PRIORITY: number;
|
|
10
|
+
/**
|
|
11
|
+
* The named colours libadwaita defines, measured rather than read.
|
|
12
|
+
*
|
|
13
|
+
* MEASURED on libadwaita 1.9.3 by resolving `var(--<name>, <sentinel>)` on a real
|
|
14
|
+
* widget and checking the sentinel did NOT come back — the only test that
|
|
15
|
+
* distinguishes "the name exists" from "the name is a typo that defines nothing".
|
|
16
|
+
* `theme.spec.ts` re-measures both directions against the libadwaita that is
|
|
17
|
+
* running, so a release that renames one goes red here rather than in a window.
|
|
18
|
+
*
|
|
19
|
+
* The list is what a theme may OVERRIDE, and overriding a name libadwaita does not
|
|
20
|
+
* define is the exact silent failure this set exists to catch: `--acccent-bg-color`
|
|
21
|
+
* is a perfectly valid custom property that nothing ever reads.
|
|
22
|
+
*/
|
|
23
|
+
export declare const ADWAITA_NAMED_COLORS: readonly string[];
|
|
24
|
+
/**
|
|
25
|
+
* Names that are NOT custom properties, and the claim each one carries.
|
|
26
|
+
*
|
|
27
|
+
* Without this direction the set above could name every string in GTK and still
|
|
28
|
+
* pass. `borders` is the interesting row: it is a real Adwaita colour under the
|
|
29
|
+
* LEGACY `@define-color` mechanism and is not a CSS variable, which is exactly the
|
|
30
|
+
* confusion decision 1 is about. `accent_bg_color` is the same point in the other
|
|
31
|
+
* spelling — the underscored legacy name of a variable that does exist.
|
|
32
|
+
*/
|
|
33
|
+
export declare const NOT_ADWAITA_NAMED_COLORS: readonly string[];
|
|
34
|
+
/** One named look: a GTK CSS document, a palette, and which desktops default to it. */
|
|
35
|
+
export interface Theme {
|
|
36
|
+
/** How the application asks for it. Also what a refusal names. */
|
|
37
|
+
readonly name: string;
|
|
38
|
+
/**
|
|
39
|
+
* The application's own GTK CSS document.
|
|
40
|
+
*
|
|
41
|
+
* Goes through the same containment probe as a generated rule, and for a
|
|
42
|
+
* stronger reason: this is the document this package did not write.
|
|
43
|
+
*/
|
|
44
|
+
readonly css?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Adwaita named colours to redefine, WITHOUT the `--` prefix.
|
|
47
|
+
*
|
|
48
|
+
* `{ 'accent-bg-color': 'rgb(53 132 228)' }`. Emitted as a `:root` block ahead of
|
|
49
|
+
* {@link Theme.css}, so a rule in {@link Theme.css} redefining one of these names
|
|
50
|
+
* WINS — the last definition in a document is the one that applies.
|
|
51
|
+
*/
|
|
52
|
+
readonly namedColors?: Readonly<Record<string, string>>;
|
|
53
|
+
/**
|
|
54
|
+
* The `process.platform` values this theme is the default for, or `'*'` for any.
|
|
55
|
+
*
|
|
56
|
+
* Data on the theme rather than a table in the registry, because "this look
|
|
57
|
+
* belongs on macOS" is a fact about the look.
|
|
58
|
+
*
|
|
59
|
+
* `'*'` exists because `process.platform` has more values than the three desktops
|
|
60
|
+
* this project targets — `freebsd`, `openbsd`, `android`, `sunos`, … — and GTK
|
|
61
|
+
* runs on several of them. A registry that only knew `linux`/`darwin`/`win32`
|
|
62
|
+
* would make `selectDefault(process.platform)`, the call this seam is documented
|
|
63
|
+
* with, THROW on a platform where nothing is wrong. A fallback theme says so once
|
|
64
|
+
* instead, and a named theme still wins over it by being registered later.
|
|
65
|
+
*/
|
|
66
|
+
readonly defaultOn?: readonly string[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The one theme shipped now, and it deliberately changes nothing.
|
|
70
|
+
*
|
|
71
|
+
* A GTK application should look like the desktop it is running on, and the accent is
|
|
72
|
+
* the user's — they picked it in Settings and expect their applications to use it.
|
|
73
|
+
* So the neutral theme is an EMPTY document, and that is a statement rather than a
|
|
74
|
+
* placeholder: selecting it is how an application returns to Adwaita exactly, which
|
|
75
|
+
* is measurably true because reloading the provider to the empty string restores
|
|
76
|
+
* every named colour to libadwaita's own value.
|
|
77
|
+
*
|
|
78
|
+
* It is also what makes the registry useful with one theme registered: there is
|
|
79
|
+
* always something to switch back TO.
|
|
80
|
+
*/
|
|
81
|
+
export declare const NEUTRAL_THEME: Theme;
|
|
82
|
+
export interface ThemeRegistryOptions {
|
|
83
|
+
/**
|
|
84
|
+
* Where the provider is installed. Omitted means the default display — the right
|
|
85
|
+
* answer for an application and the wrong one for a test, which is why it is
|
|
86
|
+
* injectable at all.
|
|
87
|
+
*/
|
|
88
|
+
readonly display?: Gdk.Display | null;
|
|
89
|
+
/** Provider priority. Defaults to {@link THEME_PROVIDER_PRIORITY}; see decision 2. */
|
|
90
|
+
readonly priority?: number;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Named themes, one selected, swapped on a single provider.
|
|
94
|
+
*
|
|
95
|
+
* NOT a module-level singleton, unlike the token configuration one layer up. A
|
|
96
|
+
* registry holds a `Gdk.Display` and a `Gtk.CssProvider`, so a test that could not
|
|
97
|
+
* make its own would have to share the session's — and the registry is exactly the
|
|
98
|
+
* object whose whole behaviour is "what is installed on the display right now".
|
|
99
|
+
*/
|
|
100
|
+
export declare class ThemeRegistry {
|
|
101
|
+
#private;
|
|
102
|
+
constructor(options?: ThemeRegistryOptions);
|
|
103
|
+
/**
|
|
104
|
+
* Add a theme, refusing anything that would be a silent no-op.
|
|
105
|
+
*
|
|
106
|
+
* The document is PROBED here rather than at selection, so the error names the
|
|
107
|
+
* line that declared the theme instead of the line that switched to it — which
|
|
108
|
+
* may be a user clicking a row in the application's settings, hours later.
|
|
109
|
+
*/
|
|
110
|
+
register(theme: Theme): this;
|
|
111
|
+
/** The registered names, in registration order. */
|
|
112
|
+
get names(): readonly string[];
|
|
113
|
+
/** The selected theme's name, or null before anything is selected. */
|
|
114
|
+
get current(): string | null;
|
|
115
|
+
/** The document a theme produces. Exposed because a test that cannot read it proves nothing. */
|
|
116
|
+
documentOf(theme: Theme): string;
|
|
117
|
+
/**
|
|
118
|
+
* Switch to a registered theme, replacing whatever was loaded.
|
|
119
|
+
*
|
|
120
|
+
* Idempotent, and cheap enough to call from a settings row's handler: the
|
|
121
|
+
* document was probed at registration, so this is one `load_from_string` plus, on
|
|
122
|
+
* the first call only, one `add_provider_for_display`.
|
|
123
|
+
*/
|
|
124
|
+
select(name: string): void;
|
|
125
|
+
/**
|
|
126
|
+
* Select the theme that declares itself the default for `platform`.
|
|
127
|
+
*
|
|
128
|
+
* The platform is a PARAMETER and this module never reads `process.platform`
|
|
129
|
+
* itself — the same discipline the intent seam one layer up argues for. It keeps
|
|
130
|
+
* a `process` read (and the OS declaration that comes with one) out of a package
|
|
131
|
+
* whose job is GTK, and it lets a settings screen preview another desktop's look
|
|
132
|
+
* by passing that desktop's name.
|
|
133
|
+
*
|
|
134
|
+
* The last registered match wins, so an application registering its own theme
|
|
135
|
+
* after the neutral one gets its own — including over a theme that declares
|
|
136
|
+
* `'*'`, which is how the shipped neutral default stays a fallback rather than a
|
|
137
|
+
* ceiling.
|
|
138
|
+
*/
|
|
139
|
+
selectDefault(platform: string): void;
|
|
140
|
+
/**
|
|
141
|
+
* Take the theme document off the display, leaving nothing behind.
|
|
142
|
+
*
|
|
143
|
+
* Selecting the neutral theme reloads the document to empty, which is all an
|
|
144
|
+
* application needs. It is NOT all a TEST needs, and the difference was measured
|
|
145
|
+
* in this file's own spec: a vector that read "libadwaita's own accent" read the
|
|
146
|
+
* PREVIOUS vector's green instead, because that registry's provider was still on
|
|
147
|
+
* the shared display with a `--accent-bg-color` in it — and the assertion named
|
|
148
|
+
* "back to Adwaita exactly" then passed against the green. Ownership belongs with
|
|
149
|
+
* whoever created the registry, so there has to be a way to give it up.
|
|
150
|
+
*
|
|
151
|
+
* The provider is removed from the display it was INSTALLED on rather than from
|
|
152
|
+
* whatever `Gdk.Display.get_default()` answers now. A later `select()` installs
|
|
153
|
+
* again: position relative to the generated sheet is decided by the priority
|
|
154
|
+
* numbers, not by insertion order, so re-installing cannot land in the wrong
|
|
155
|
+
* place (decision 2).
|
|
156
|
+
*/
|
|
157
|
+
dispose(): void;
|
|
158
|
+
}
|