@gjsify/adwaita-nativescript 0.36.0 → 0.38.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/index.js +1 -1
- package/lib/esm/widgets/accent-theme.js +2 -0
- package/lib/esm/widgets/adw-accent.js +1 -0
- package/lib/esm/widgets/adw-shortcut-label.js +1 -0
- package/lib/esm/widgets/index.js +1 -1
- package/lib/esm/widgets/shortcut-label.js +1 -0
- package/lib/types/accent-theme.spec.d.ts +2 -0
- package/lib/types/index.d.ts +2 -2
- package/lib/types/shortcut-label.spec.d.ts +2 -0
- package/lib/types/widgets/accent-theme.d.ts +30 -0
- package/lib/types/widgets/adw-accent.d.ts +12 -0
- package/lib/types/widgets/adw-action-row.d.ts +27 -43
- package/lib/types/widgets/adw-data-grid.d.ts +4 -10
- package/lib/types/widgets/adw-entry-row.d.ts +20 -29
- package/lib/types/widgets/adw-shortcut-label.d.ts +13 -0
- package/lib/types/widgets/button-content.d.ts +12 -21
- package/lib/types/widgets/carousel-state.d.ts +15 -18
- package/lib/types/widgets/chrome.d.ts +22 -47
- package/lib/types/widgets/data-grid-model.d.ts +25 -36
- package/lib/types/widgets/index.d.ts +6 -0
- package/lib/types/widgets/navigation-stack.d.ts +2 -13
- package/lib/types/widgets/preferences-group-state.d.ts +7 -13
- package/lib/types/widgets/preferences-search.d.ts +5 -5
- package/lib/types/widgets/row-state.d.ts +17 -33
- package/lib/types/widgets/shortcut-label.d.ts +54 -0
- package/lib/types/widgets/sidebar-model.d.ts +5 -7
- package/lib/types/widgets/split-button.d.ts +17 -34
- package/lib/types/widgets/split-view-base.d.ts +17 -24
- package/lib/types/widgets/split-view-state.d.ts +48 -76
- package/lib/types/widgets/split-view-width.d.ts +21 -32
- package/lib/types/widgets/status-page-content.d.ts +9 -14
- package/lib/types/widgets/tab-view-state.d.ts +18 -34
- package/lib/types/widgets/view-switcher-base.d.ts +11 -30
- package/lib/types/widgets/view-switcher-model.d.ts +17 -34
- package/lib/types/widgets/wrap-box-layout.d.ts +22 -37
- package/package.json +7 -7
- package/src/theme/adwaita.css +77 -0
|
@@ -5,10 +5,8 @@ import type { AdwViewSwitcherPageInit, ViewSwitcherStateChange } from '@gjsify/a
|
|
|
5
5
|
* One page registered with a view switcher.
|
|
6
6
|
*
|
|
7
7
|
* Mirrors `AdwViewStackPage`'s properties with their C defaults. `title` and
|
|
8
|
-
* `icon` are NULLABLE on purpose: a page with neither renders no button at all
|
|
9
|
-
*
|
|
10
|
-
* that rule is no longer expressible — which is why the old shape, with a
|
|
11
|
-
* required `title: string`, could not implement it.
|
|
8
|
+
* `icon` are NULLABLE on purpose: a page with neither renders no button at all, and
|
|
9
|
+
* an absent title flattened to `''` makes that rule inexpressible.
|
|
12
10
|
*
|
|
13
11
|
* `icon` is an Adwaita symbolic SVG DOCUMENT here, not a GTK icon name: `AdwIcon`
|
|
14
12
|
* rasterises the path data natively. The core treats the field as an opaque
|
|
@@ -16,12 +14,7 @@ import type { AdwViewSwitcherPageInit, ViewSwitcherStateChange } from '@gjsify/a
|
|
|
16
14
|
* the fallback sentinel it hands back.
|
|
17
15
|
*/
|
|
18
16
|
export interface AdwViewPage {
|
|
19
|
-
/**
|
|
20
|
-
* The switcher button label. ABSENT means the page has none — which is C's
|
|
21
|
-
* NULL, and the state the button-visibility rule turns on. Spelled as an
|
|
22
|
-
* optional `string` rather than `string | null` so the existing consumers
|
|
23
|
-
* that pass a plain `string` keep type-checking unchanged.
|
|
24
|
-
*/
|
|
17
|
+
/** The switcher button label. ABSENT is C's NULL — the state button visibility turns on. */
|
|
25
18
|
title?: string;
|
|
26
19
|
/** The page content view, shown when this page is selected. */
|
|
27
20
|
content: View;
|
|
@@ -47,9 +40,9 @@ export declare function createViewSwitcherBarState(): ViewSwitcherBarState;
|
|
|
47
40
|
/**
|
|
48
41
|
* Project one NS page onto the core's page init.
|
|
49
42
|
*
|
|
50
|
-
* A page without an explicit `name` gets its POSITION as the name
|
|
51
|
-
*
|
|
52
|
-
*
|
|
43
|
+
* A page without an explicit `name` gets its POSITION as the name: the NS API is
|
|
44
|
+
* positional (`setViews` takes an array), and the name-preserving rebuild needs a
|
|
45
|
+
* stable id to keep the selected page selected.
|
|
53
46
|
*/
|
|
54
47
|
export declare function viewSwitcherPageSpec(page: AdwViewPage, index: number): AdwViewSwitcherPageInit;
|
|
55
48
|
/** {@link viewSwitcherPageSpec} over a whole page list. */
|
|
@@ -57,11 +50,10 @@ export declare function viewSwitcherPageSpecs(pages: readonly AdwViewPage[]): Ad
|
|
|
57
50
|
/**
|
|
58
51
|
* Resolve the core's icon slot to something `AdwIcon` can rasterise.
|
|
59
52
|
*
|
|
60
|
-
* The core substitutes the NAME `image-missing` for an absent icon
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* else is already an SVG and passes through.
|
|
53
|
+
* The core substitutes the NAME `image-missing` for an absent icon. On the browser
|
|
54
|
+
* side that name becomes a CSS mask class; here it has to become the actual
|
|
55
|
+
* symbolic document, so the sentinel is swapped for the vendored
|
|
56
|
+
* `image-missing-symbolic` SVG. Anything else is already an SVG and passes through.
|
|
65
57
|
*/
|
|
66
58
|
export declare function nsIconSvg(iconName: string): string;
|
|
67
59
|
/**
|
|
@@ -76,24 +68,15 @@ export declare function applyViewSwitcherVisibility(pages: readonly AdwViewPage[
|
|
|
76
68
|
/** Which switcher is asking — the two apply different visibility rules. */
|
|
77
69
|
export type ViewSwitcherKind = 'switcher' | 'inline';
|
|
78
70
|
/**
|
|
79
|
-
* Whether a page gets a button/toggle at all.
|
|
71
|
+
* Whether a page gets a button/toggle at all. The two switchers genuinely differ:
|
|
80
72
|
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
73
|
+
* - `AdwViewSwitcher` needs a title or an icon ON TOP OF `visible`
|
|
74
|
+
* (`visible && (title != NULL || icon_name != NULL)`).
|
|
75
|
+
* - `AdwInlineViewSwitcher` gates on `visible` alone, so a page with neither still
|
|
76
|
+
* gets an empty toggle.
|
|
83
77
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* NULL))` (adw-view-switcher.c:178).
|
|
87
|
-
* - `AdwInlineViewSwitcher` does not. `populate_group` gates on `visible` alone
|
|
88
|
-
* (adw-inline-view-switcher.c:370-378), so a page with neither still gets an
|
|
89
|
-
* empty toggle.
|
|
90
|
-
*
|
|
91
|
-
* The inline widget inherited the stricter rule and silently dropped toggles
|
|
92
|
-
* libadwaita draws. `@gjsify/adwaita-core` had spelled this out in
|
|
93
|
-
* `buildInlineToggles`' doc and pinned it in `INLINE_TOGGLE_VECTORS` the whole
|
|
94
|
-
* time — the rule just lived in a class that `extends GridLayout`, which no
|
|
95
|
-
* spec can import, so nothing could reach it to check. That is why it is here
|
|
96
|
-
* and not there.
|
|
78
|
+
* The rule lives here rather than in the widget because a class that `extends
|
|
79
|
+
* GridLayout` cannot be imported by a spec.
|
|
97
80
|
*/
|
|
98
81
|
export declare function switcherButtonVisible(kind: ViewSwitcherKind, modelVisible: boolean, pageVisible: boolean): boolean;
|
|
99
82
|
/** The data half of the `notify::selected` event (minus NS's `eventName`/`object`). */
|
|
@@ -1,36 +1,25 @@
|
|
|
1
1
|
import { normalizeWrapBoxSpacing, type AdwWrapBoxJustify, type AdwWrapBoxOrientation, type AdwWrapBoxPackDirection, type AdwWrapPolicy } from '@gjsify/adwaita-core';
|
|
2
2
|
export { normalizeWrapBoxSpacing };
|
|
3
|
-
/**
|
|
4
|
-
* `Adw.WrapBox:child-spacing` / `:line-spacing` default, in DIPs.
|
|
5
|
-
*
|
|
6
|
-
* Both are `g_param_spec_int (…, 0, G_MAXINT, 0, …)` — adw-wrap-box.c:285-287
|
|
7
|
-
* and :393-395. The port used to default both to 6, so identical markup was
|
|
8
|
-
* looser on a phone than in the browser and an EMPTY wrap box was already 12
|
|
9
|
-
* DIPs tall.
|
|
10
|
-
*/
|
|
3
|
+
/** `Adw.WrapBox:child-spacing` / `:line-spacing` default, in DIPs. Both are 0 in C. */
|
|
11
4
|
export declare const DEFAULT_WRAP_BOX_SPACING = 0;
|
|
12
5
|
/**
|
|
13
6
|
* Whether writing `next` over `current` is a change the widget must act on.
|
|
14
7
|
*
|
|
15
|
-
* The comparison happens AFTER the clamp
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* whether every child's margin is rewritten.
|
|
8
|
+
* The comparison happens AFTER the clamp, so a negative value written over a
|
|
9
|
+
* spacing of 0 is an early return: it neither reaches the layout nor notifies. Here
|
|
10
|
+
* the same predicate decides whether every child's margin is rewritten.
|
|
19
11
|
*/
|
|
20
12
|
export declare function wrapBoxSpacingChanges(current: number, next: unknown): boolean;
|
|
21
13
|
/**
|
|
22
14
|
* The uniform margin that gives a `FlexboxLayout` child its share of the gaps.
|
|
23
15
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* children: half of it on each facing edge adds up to the whole gap between any
|
|
27
|
-
* two neighbours. The margin string is NS's `top right bottom left` shorthand.
|
|
16
|
+
* Half the spacing on each facing edge adds up to the whole gap between any two
|
|
17
|
+
* neighbours. The margin string is NS's `top right bottom left` shorthand.
|
|
28
18
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* subset can be trusted with.
|
|
19
|
+
* Knowingly looser than libadwaita: the halves on the OUTER edges are an inset
|
|
20
|
+
* `Adw.WrapBox` does not have. Invisible at the default spacing of 0 and bounded by
|
|
21
|
+
* half a gap otherwise; the alternative is negative margins on the container, which
|
|
22
|
+
* the NS CSS subset cannot be trusted with.
|
|
34
23
|
*/
|
|
35
24
|
export declare function wrapBoxChildMargin(childSpacing: number, lineSpacing: number): string;
|
|
36
25
|
/** The `FlexboxLayout` knobs a wrap box's properties resolve to. */
|
|
@@ -63,14 +52,12 @@ export interface WrapBoxFlexInput {
|
|
|
63
52
|
* The CONTAINER half of the decision, resolved onto `FlexboxLayout`.
|
|
64
53
|
*
|
|
65
54
|
* The line DECISION is `resolveWrapBoxLine` in `@gjsify/adwaita-core`, held to
|
|
66
|
-
* `WRAP_BOX_LINE_VECTORS
|
|
67
|
-
* has, exactly as the browser element maps it onto CSS.
|
|
55
|
+
* `WRAP_BOX_LINE_VECTORS`; this function only maps its answer onto the knobs NS has.
|
|
68
56
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* through {@link wrapBoxChildFlex}.
|
|
57
|
+
* `FlexboxLayout` has ONE `justifyContent` for every line, so it can only carry the
|
|
58
|
+
* COMPLETE-line rule. NativeScript offers no `:only-child` selector and no generated
|
|
59
|
+
* content, so the final-line rule has no container-level expression at all; the
|
|
60
|
+
* single-child case is reached through {@link wrapBoxChildFlex}.
|
|
74
61
|
*/
|
|
75
62
|
export declare function wrapBoxFlexStyle(input: WrapBoxFlexInput): WrapBoxFlexStyle;
|
|
76
63
|
/** What one child of the box gets set on it. */
|
|
@@ -83,15 +70,13 @@ export interface WrapBoxChildFlex {
|
|
|
83
70
|
/**
|
|
84
71
|
* The PER-CHILD half of the decision, which the container knobs cannot carry.
|
|
85
72
|
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* rather than spreading anything (`n_children > 1` guards the keep-at-minimum
|
|
91
|
-
* branch, adw-wrap-layout.c:338; adw-wrap-box.c:349-352 says so outright).
|
|
73
|
+
* A box with exactly ONE child has one line, that line is the LAST one, and its
|
|
74
|
+
* child is alone on it — so it is governed by `justify-last-line`, and `spread`
|
|
75
|
+
* STRETCHES it rather than spreading anything (C guards the keep-at-minimum branch
|
|
76
|
+
* with `n_children > 1`).
|
|
92
77
|
*
|
|
93
|
-
* `childCount` is the box's own child count,
|
|
94
|
-
*
|
|
95
|
-
*
|
|
78
|
+
* `childCount` is the box's own child count, the most a renderer knows without a
|
|
79
|
+
* layout pass: 1 is the lone-child-on-the-final-line case exactly, anything more
|
|
80
|
+
* means at least one complete line.
|
|
96
81
|
*/
|
|
97
82
|
export declare function wrapBoxChildFlex(input: WrapBoxFlexInput, childCount: number): WrapBoxChildFlex;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/adwaita-nativescript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.0",
|
|
4
4
|
"description": "Native Adwaita widgets for the NativeScript runtime — real NativeScript components (StackLayout/GridLayout/Switch/Label) styled like Libadwaita, not a webview",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
"design-system"
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@gjsify/adwaita-core": "^0.
|
|
51
|
-
"@gjsify/adwaita-fonts": "^0.
|
|
52
|
-
"@gjsify/adwaita-icons": "^0.
|
|
53
|
-
"@gjsify/native-platform": "^0.
|
|
50
|
+
"@gjsify/adwaita-core": "^0.38.0",
|
|
51
|
+
"@gjsify/adwaita-fonts": "^0.38.0",
|
|
52
|
+
"@gjsify/adwaita-icons": "^0.38.0",
|
|
53
|
+
"@gjsify/native-platform": "^0.38.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"@nativescript/core": "*"
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
}
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@gjsify/cli": "^0.
|
|
65
|
-
"@gjsify/unit": "^0.
|
|
64
|
+
"@gjsify/cli": "^0.38.0",
|
|
65
|
+
"@gjsify/unit": "^0.38.0",
|
|
66
66
|
"@types/node": "^25.9.2",
|
|
67
67
|
"typescript": "^6.0.3"
|
|
68
68
|
},
|
package/src/theme/adwaita.css
CHANGED
|
@@ -1371,6 +1371,66 @@ Page.adw-window {
|
|
|
1371
1371
|
margin: 0;
|
|
1372
1372
|
}
|
|
1373
1373
|
|
|
1374
|
+
/* ===== Shortcut label (keycaps) =====
|
|
1375
|
+
*
|
|
1376
|
+
* libadwaita: `_shortcuts-dialog.scss:33-58` — 6 spacing at BOTH levels, keycaps
|
|
1377
|
+
* filled with 10% of the current colour, an inset bottom edge, 6 radius, 6
|
|
1378
|
+
* padding, 20 minimum width, and `> .dimmed { padding: 6 0 }` so a separator
|
|
1379
|
+
* lines up with the caps beside it.
|
|
1380
|
+
*
|
|
1381
|
+
* Two substitutions the NS subset forces, both visible rather than silent:
|
|
1382
|
+
* - `color-mix(in srgb, currentColor 10%, transparent)` has no NS spelling, so
|
|
1383
|
+
* the fill is written out per scheme against that scheme's foreground;
|
|
1384
|
+
* - `box-shadow: inset 0 -2px` has none either (NS box-shadow is outer-only),
|
|
1385
|
+
* so the key's bottom edge is a 2 bottom BORDER. It occupies layout where the
|
|
1386
|
+
* shadow did not, which grows a keycap by 2 — the closest the subset gets.
|
|
1387
|
+
*/
|
|
1388
|
+
|
|
1389
|
+
.adw-shortcut-label {
|
|
1390
|
+
background-color: transparent;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
/* The 6 that GTK gets from `border-spacing`, which puts it BETWEEN children
|
|
1394
|
+
* only. NS has no `gap` and the subset no `:first-child`, so the widget adds
|
|
1395
|
+
* this class to every child after the first. */
|
|
1396
|
+
.adw-shortcut-label-spaced {
|
|
1397
|
+
margin-left: 6;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
/* Scoped, because `keycap` is libadwaita's generic name and this theme is one
|
|
1401
|
+
* flat file — an app with its own `.keycap` must not inherit these metrics. */
|
|
1402
|
+
.adw-shortcut-label .keycap {
|
|
1403
|
+
background-color: rgba(0, 0, 0, 0.08);
|
|
1404
|
+
border-radius: 6;
|
|
1405
|
+
border-bottom-width: 2;
|
|
1406
|
+
border-bottom-color: rgba(0, 0, 6, 0.07);
|
|
1407
|
+
padding: 6;
|
|
1408
|
+
min-width: 20;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
.adw-shortcut-label-cap-text {
|
|
1412
|
+
color: rgba(0, 0, 0, 0.8);
|
|
1413
|
+
font-size: 14;
|
|
1414
|
+
text-align: center;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
/* `%s <small><b>%s</b></small>` (adw-shortcut-label.c:195) — the L/R marker is
|
|
1418
|
+
* smaller and bold, and rides inside its keycap rather than beside it. */
|
|
1419
|
+
.adw-shortcut-label-side {
|
|
1420
|
+
color: rgba(0, 0, 0, 0.8);
|
|
1421
|
+
font-size: 11;
|
|
1422
|
+
font-weight: 700;
|
|
1423
|
+
margin-left: 2;
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
/* `dim_label` — `--dim-opacity: 55%` (`_colors.scss:319`). */
|
|
1427
|
+
.adw-shortcut-label .dimmed {
|
|
1428
|
+
color: rgba(0, 0, 0, 0.8);
|
|
1429
|
+
font-size: 14;
|
|
1430
|
+
opacity: 0.55;
|
|
1431
|
+
padding: 6 0 6 0;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1374
1434
|
/* ===== Dark variant (.ns-dark on the page/root) ===== */
|
|
1375
1435
|
|
|
1376
1436
|
.ns-dark .adw-window,
|
|
@@ -1893,3 +1953,20 @@ Page.ns-dark.adw-window {
|
|
|
1893
1953
|
.ns-dark .adw-preferences-dialog-close {
|
|
1894
1954
|
color: rgba(255, 255, 255, 0.55);
|
|
1895
1955
|
}
|
|
1956
|
+
|
|
1957
|
+
/* ===== Dark: shortcut label =====
|
|
1958
|
+
* The fill is 10% of the foreground, which is `#ffffff` here rather than the
|
|
1959
|
+
* light scheme's near-black — the one reason these rules exist at all. The
|
|
1960
|
+
* bottom edge follows `--card-shade-color`, which darkens in the dark theme
|
|
1961
|
+
* (`_theme.scss:28`: 0.36 against the light scheme's 0.07). */
|
|
1962
|
+
|
|
1963
|
+
.ns-dark .adw-shortcut-label .keycap {
|
|
1964
|
+
background-color: rgba(255, 255, 255, 0.1);
|
|
1965
|
+
border-bottom-color: rgba(0, 0, 6, 0.36);
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
.ns-dark .adw-shortcut-label-cap-text,
|
|
1969
|
+
.ns-dark .adw-shortcut-label-side,
|
|
1970
|
+
.ns-dark .adw-shortcut-label .dimmed {
|
|
1971
|
+
color: #ffffff;
|
|
1972
|
+
}
|