@gjsify/adwaita-nativescript 0.46.0 → 0.48.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.
Files changed (51) hide show
  1. package/lib/esm/_virtual/_rolldown/runtime.js +1 -1
  2. package/lib/esm/index.js +1 -1
  3. package/lib/esm/namespace/adw.js +1 -0
  4. package/lib/esm/namespace/gtk.js +1 -0
  5. package/lib/esm/widgets/adw-button-content.js +1 -1
  6. package/lib/esm/widgets/adw-button-row.js +1 -1
  7. package/lib/esm/widgets/adw-combo-row.js +1 -1
  8. package/lib/esm/widgets/adw-entry-row.js +1 -1
  9. package/lib/esm/widgets/adw-expander-row.js +1 -1
  10. package/lib/esm/widgets/adw-slider-row.js +1 -1
  11. package/lib/esm/widgets/adw-spin-row.js +1 -1
  12. package/lib/esm/widgets/adw-split-button.js +1 -1
  13. package/lib/esm/widgets/adw-status-page.js +1 -1
  14. package/lib/esm/widgets/adw-tab-view.js +1 -1
  15. package/lib/esm/widgets/adw-toggle-group.js +1 -1
  16. package/lib/esm/widgets/adw-view-switcher-bar.js +1 -1
  17. package/lib/esm/widgets/entry-row-view.js +1 -1
  18. package/lib/esm/widgets/gtk-drop-down.js +1 -1
  19. package/lib/esm/widgets/gtk-image.js +1 -0
  20. package/lib/esm/widgets/gtk-menu-button.js +1 -1
  21. package/lib/esm/widgets/index.js +1 -1
  22. package/lib/esm/widgets/menu-sheet.js +1 -0
  23. package/lib/esm/widgets/split-button.js +1 -1
  24. package/lib/esm/widgets/view-switcher-base.js +1 -1
  25. package/lib/types/index.d.ts +4 -3
  26. package/lib/types/namespace/adw.d.ts +38 -0
  27. package/lib/types/namespace/gtk.d.ts +5 -0
  28. package/lib/types/widgets/adw-button-content.d.ts +2 -2
  29. package/lib/types/widgets/adw-button-row.d.ts +4 -4
  30. package/lib/types/widgets/adw-combo-row.d.ts +6 -6
  31. package/lib/types/widgets/adw-entry-row.d.ts +3 -3
  32. package/lib/types/widgets/adw-expander-row.d.ts +2 -2
  33. package/lib/types/widgets/adw-slider-row.d.ts +15 -17
  34. package/lib/types/widgets/adw-spin-row.d.ts +16 -13
  35. package/lib/types/widgets/adw-split-button.d.ts +45 -10
  36. package/lib/types/widgets/adw-status-page.d.ts +2 -2
  37. package/lib/types/widgets/entry-row-view.d.ts +1 -1
  38. package/lib/types/widgets/gtk-drop-down.d.ts +6 -6
  39. package/lib/types/widgets/{adw-icon.d.ts → gtk-image.d.ts} +2 -2
  40. package/lib/types/widgets/gtk-menu-button.d.ts +27 -17
  41. package/lib/types/widgets/index.d.ts +4 -2
  42. package/lib/types/widgets/menu-sheet.d.ts +58 -0
  43. package/lib/types/widgets/row-state.d.ts +1 -1
  44. package/lib/types/widgets/split-button.d.ts +2 -21
  45. package/lib/types/widgets/status-page-content.d.ts +1 -1
  46. package/lib/types/widgets/view-switcher-model.d.ts +2 -2
  47. package/package.json +14 -10
  48. package/src/theme/adwaita.css +8 -8
  49. package/lib/esm/namespace.js +0 -1
  50. package/lib/esm/widgets/adw-icon.js +0 -1
  51. package/lib/types/namespace.d.ts +0 -92
@@ -1,7 +1,7 @@
1
1
  import { Label, StackLayout, TextField, type EventData, type View } from '@nativescript/core';
2
2
  import { EntryRowState, type EntryRowRenderState } from '@gjsify/adwaita-core';
3
3
  import { AdwActionRow } from './adw-action-row.js';
4
- import { AdwIcon } from './adw-icon.js';
4
+ import { GtkImage } from './gtk-image.js';
5
5
  import { AdwImageButton } from './adw-image-button.js';
6
6
  export { EntryRowState } from '@gjsify/adwaita-core';
7
7
  export type { EntryRowRenderState, EntryRowActivation } from '@gjsify/adwaita-core';
@@ -44,9 +44,9 @@ export declare class AdwEntryRow extends AdwActionRow {
44
44
  /** The trailing affordance box — `Adw.EntryRow`'s suffixes BOX, not a slot. */
45
45
  protected readonly _suffixes: StackLayout;
46
46
  /** The pencil (`edit_icon`). Non-interactive, like its `can-target=False` original. */
47
- protected readonly _editIcon: AdwIcon;
47
+ protected readonly _editIcon: GtkImage;
48
48
  /** The caps-lock warning slot (`indicator`). */
49
- protected readonly _indicator: AdwIcon;
49
+ protected readonly _indicator: GtkImage;
50
50
  protected readonly _applyButton: AdwImageButton;
51
51
  /** The suffix installed through the inherited single-slot {@link setSuffix}. */
52
52
  private _slotSuffix;
@@ -1,7 +1,7 @@
1
1
  import type { View } from '@nativescript/core';
2
2
  import { ItemSpec, StackLayout, type EventData } from '@nativescript/core';
3
3
  import { AdwActionRow } from './adw-action-row.js';
4
- import { AdwIcon } from './adw-icon.js';
4
+ import { GtkImage } from './gtk-image.js';
5
5
  export { ExpanderState } from '@gjsify/adwaita-core';
6
6
  export type { ExpanderStateListener } from '@gjsify/adwaita-core';
7
7
  /** Event name emitted when {@link AdwExpanderRow.expanded} changes. Mirrors GObject `notify::expanded`. */
@@ -16,7 +16,7 @@ export declare class AdwExpanderRow extends AdwActionRow {
16
16
  * (adw-expander-row.c:72), so the search does not consult a subtitle here. */
17
17
  readonly isActionRow: boolean;
18
18
  /** The disclosure chevron (suffix) — a plain symbolic icon, like Adw.ExpanderRow. */
19
- protected readonly _toggle: AdwIcon;
19
+ protected readonly _toggle: GtkImage;
20
20
  /** The container of revealed child rows (second grid row). */
21
21
  protected readonly _disclosure: StackLayout;
22
22
  /** The headless expanded/collapsed disclosure state machine (ADR 0004). */
@@ -1,9 +1,10 @@
1
1
  import { Label, Slider, StackLayout, type EventData } from '@nativescript/core';
2
+ import type { AdwAdjustment, AdwAdjustmentInput } from '@gjsify/adwaita-core';
2
3
  /** Event name emitted when {@link AdwSliderRow.value} changes. Mirrors GObject `notify::value`. */
3
4
  export declare const NOTIFY_SLIDER_VALUE = "notify::value";
4
5
  /** Payload of the `notify::value` event. */
5
6
  export interface NotifySliderValueEventData extends EventData {
6
- /** The new numeric value (already clamped to `[min, max]` and snapped to `step`). */
7
+ /** The new numeric value (already clamped into the adjustment's range and snapped to a tick). */
7
8
  value: number;
8
9
  }
9
10
  export declare class AdwSliderRow extends StackLayout {
@@ -13,32 +14,29 @@ export declare class AdwSliderRow extends StackLayout {
13
14
  protected readonly _valueLabel: Label;
14
15
  /** The horizontal slider. */
15
16
  protected readonly _slider: Slider;
16
- private _value;
17
- private _min;
18
- private _max;
19
- private _step;
17
+ /** The headless adjustment: clamp, step and the two signals (ADR 0004, ADR 0047). */
18
+ private readonly _state;
20
19
  /** Guards the slider's `valueChange` while we programmatically set its value. */
21
20
  private _suppress;
22
21
  constructor();
23
- /** Clamp to `[min, max]` then snap to the nearest `step` from `min`. */
24
- private _snap;
25
22
  /** Push the current value to the slider + label without emitting. */
26
23
  private _sync;
27
24
  /** The group title shown in the header (left). */
28
25
  get title(): string;
29
26
  set title(value: string);
30
- /** The current numeric value (always within `[min, max]`, snapped to `step`). */
27
+ /** The current numeric value (always within the adjustment's range, snapped to a tick). */
31
28
  get value(): number;
32
29
  set value(raw: number | string);
33
- /** Lower bound. Re-clamps the current value if it now falls below. */
34
- get min(): number;
35
- set min(raw: number | string);
36
- /** Upper bound. Re-clamps the current value if it now falls above. */
37
- get max(): number;
38
- set max(raw: number | string);
39
- /** Snap granularity applied as the slider is dragged. */
40
- get step(): number;
41
- set step(raw: number | string);
30
+ /**
31
+ * The numeric range this row slides through — the `Gtk.Adjustment` a `Gtk.Scale` is
32
+ * handed, under the same key the spin row uses.
33
+ *
34
+ * Reads back whole; writes MERGE, so `adjustment = { upper: 20 }` moves one bound and
35
+ * leaves the rest. From XML it is a JSON object —
36
+ * `adjustment='{"lower":0,"upper":20,"stepIncrement":5}'`.
37
+ */
38
+ get adjustment(): AdwAdjustment;
39
+ set adjustment(v: AdwAdjustmentInput | string);
42
40
  /** The underlying {@link Slider} (e.g. to tweak styling). */
43
41
  get slider(): Slider;
44
42
  }
@@ -1,14 +1,15 @@
1
1
  import { Label } from '@nativescript/core';
2
2
  import type { EventData } from '@nativescript/core';
3
+ import type { AdwAdjustment, AdwAdjustmentInput } from '@gjsify/adwaita-core';
3
4
  import { AdwActionRow } from './adw-action-row.js';
4
5
  import { AdwImageButton } from './adw-image-button.js';
5
6
  export { SpinState } from '@gjsify/adwaita-core';
6
- export type { SpinStateChange, SpinStateListener } from '@gjsify/adwaita-core';
7
+ export type { AdwAdjustment, AdwAdjustmentInput, SpinStateChange, SpinStateListener } from '@gjsify/adwaita-core';
7
8
  /** Event name emitted when {@link AdwSpinRow.value} changes. Mirrors GObject `notify::value`. */
8
9
  export declare const NOTIFY_VALUE = "notify::value";
9
10
  /** Payload of the `notify::value` event. */
10
11
  export interface NotifyValueEventData extends EventData {
11
- /** The new numeric value (already clamped to `[min, max]`). */
12
+ /** The new numeric value (already clamped into the adjustment's range). */
12
13
  value: number;
13
14
  }
14
15
  export declare class AdwSpinRow extends AdwActionRow {
@@ -18,19 +19,21 @@ export declare class AdwSpinRow extends AdwActionRow {
18
19
  protected readonly _plusButton: AdwImageButton;
19
20
  /** The value display before the stepper buttons. */
20
21
  protected readonly _valueLabel: Label;
21
- /** The headless value/min/max/step clamp-and-step state machine (ADR 0004). */
22
+ /** The headless adjustment: clamp, step and the two signals (ADR 0004, ADR 0047). */
22
23
  private readonly _state;
23
24
  constructor();
24
- /** The current numeric value (always within `[min, max]`). */
25
+ /** The current numeric value (always within the adjustment's range). */
25
26
  get value(): number;
26
27
  set value(v: number | string);
27
- /** Lower bound. Re-clamps the current value if it now falls below. */
28
- get min(): number;
29
- set min(v: number | string);
30
- /** Upper bound. Re-clamps the current value if it now falls above. */
31
- get max(): number;
32
- set max(v: number | string);
33
- /** Increment/decrement step applied per button press. */
34
- get step(): number;
35
- set step(v: number | string);
28
+ /**
29
+ * The numeric range this row steps through — `Adw.SpinRow:adjustment`.
30
+ *
31
+ * Reads back whole; writes MERGE, so `adjustment = { upper: 20 }` moves one bound and
32
+ * leaves the rest, the value included (re-clamped if the move came under it). From XML
33
+ * it is a JSON object — `adjustment='{"lower":1,"upper":20}'` — which is why the setter
34
+ * takes a string: NativeScript's XML builder assigns attributes verbatim, so a
35
+ * non-string property needs its own door (see `xml-values.ts`).
36
+ */
37
+ get adjustment(): AdwAdjustment;
38
+ set adjustment(v: AdwAdjustmentInput | string);
36
39
  }
@@ -1,6 +1,6 @@
1
1
  import { GridLayout, Label, StackLayout, type EventData } from '@nativescript/core';
2
- import type { AdwMenuEntry, SplitButtonDirection } from '@gjsify/adwaita-core';
3
- import { AdwIcon } from './adw-icon.js';
2
+ import type { AdwMenuActions, AdwMenuInput, AdwMenuModel, SplitButtonDirection } from '@gjsify/adwaita-core';
3
+ import { GtkImage } from './gtk-image.js';
4
4
  /** Event name emitted when the main action part is tapped. Mirrors `Adw.SplitButton::clicked`. */
5
5
  export declare const CLICKED = "clicked";
6
6
  /** Event name emitted when a dropdown menu item is chosen. */
@@ -9,9 +9,15 @@ export declare const MENU_TAPPED = "menuTapped";
9
9
  export interface MenuTappedEventData extends EventData {
10
10
  /** The chosen menu item label. */
11
11
  item: string;
12
- /** The chosen item's index in {@link AdwSplitButton.menu} — its GMenuModel POSITION. */
13
- index: number;
14
- /** The chosen item's detailed action name, when the entry carried one. */
12
+ /** The chosen item's id, falling back to its label. */
13
+ id: string;
14
+ /**
15
+ * Where the item sits in {@link AdwSplitButton.menuModel} — its `GMenuModel`
16
+ * POSITION, as a PATH since ADR 0042: a submenu is a model of its own, so `[2, 0]`
17
+ * is the first item of the third entry and a flat index cannot name it.
18
+ */
19
+ path: readonly number[];
20
+ /** The chosen item's detailed action name, when the item carried one. */
15
21
  action?: string;
16
22
  }
17
23
  export declare class AdwSplitButton extends GridLayout {
@@ -20,12 +26,13 @@ export declare class AdwSplitButton extends GridLayout {
20
26
  /** The action label (shown in label mode). */
21
27
  protected readonly _actionLabel: Label;
22
28
  /** The action symbolic icon (shown in icon mode). */
23
- protected readonly _actionIcon: AdwIcon;
29
+ protected readonly _actionIcon: GtkImage;
24
30
  /** The dropdown-arrow part (column 1). */
25
31
  protected readonly _dropdownPart: GridLayout;
26
32
  /** The direction arrow. */
27
- protected readonly _chevron: AdwIcon;
33
+ protected readonly _chevron: GtkImage;
28
34
  private readonly _state;
35
+ private _actions;
29
36
  /** Which of the two action views is currently parented. */
30
37
  private _showingIcon;
31
38
  /**
@@ -64,9 +71,37 @@ export declare class AdwSplitButton extends GridLayout {
64
71
  */
65
72
  get iconName(): string;
66
73
  set iconName(svg: string);
67
- /** The dropdown menu entries (opened as a native `action()` sheet on arrow tap). */
68
- get menu(): readonly AdwMenuEntry[];
69
- set menu(value: readonly (string | AdwMenuEntry)[]);
74
+ /**
75
+ * The dropdown menu, normalised (ADR 0042) — opened as a native `action()` sheet on
76
+ * an arrow tap.
77
+ *
78
+ * Accepts everything the portable model does, INCLUDING the bare `string[]` this
79
+ * widget used to be alone in taking: that shorthand is now one of the model's own
80
+ * input forms rather than a NativeScript-only shape, so the same value works on
81
+ * every surface.
82
+ *
83
+ * IT DOES NOT TAKE A JSON STRING, which the browser element's `menu-model`
84
+ * ATTRIBUTE does. Not an oversight: NativeScript's Builder writes an XML attribute
85
+ * straight onto the property, so accepting one here would open the XML door — and
86
+ * the gallery probe that would have to prove it compares a read-back by IDENTITY
87
+ * (`gallery-page.ts`), which no structured value can satisfy. An input form nothing
88
+ * can run is a claim, not a feature.
89
+ *
90
+ * AND IT SAYS SO. Left to `normalizeMenuModel`, a string is "not an array" and
91
+ * becomes an EMPTY menu — so an XML author writing `menuModel="[…]"` would get a
92
+ * button whose dropdown is dead, with nothing anywhere saying why. A shut door that
93
+ * is silent is worse than one that is open.
94
+ */
95
+ get menuModel(): AdwMenuModel;
96
+ set menuModel(value: AdwMenuInput);
97
+ /**
98
+ * What the action group publishes about the actions this menu names — the portable
99
+ * stand-in for a `GActionGroup`, and the only source of a menu's enabled/checked
100
+ * state (ADR 0042). A sheet has no disabled row, so an insensitive item is not
101
+ * offered; a checked one wears a tick.
102
+ */
103
+ get actions(): AdwMenuActions | null;
104
+ set actions(value: AdwMenuActions | null);
70
105
  /** The direction the arrow points (and, on GTK, the popup opens). */
71
106
  get direction(): SplitButtonDirection;
72
107
  set direction(value: SplitButtonDirection);
@@ -1,11 +1,11 @@
1
1
  import type { View } from '@nativescript/core';
2
2
  import { GridLayout, Label, StackLayout } from '@nativescript/core';
3
- import { AdwIcon } from './adw-icon.js';
3
+ import { GtkImage } from './gtk-image.js';
4
4
  export declare class AdwStatusPage extends GridLayout {
5
5
  /** The centered vertical stack. */
6
6
  protected readonly _stack: StackLayout;
7
7
  /** The large symbolic icon (shown when an `icon` SVG is set). */
8
- protected readonly _icon: AdwIcon;
8
+ protected readonly _icon: GtkImage;
9
9
  private _iconSvg;
10
10
  /** The large glyph label (shown when `iconText` is set — the legacy fallback). */
11
11
  protected readonly _iconLabel: Label;
@@ -47,7 +47,7 @@ export declare const NS_ENTRY_ROW_CLASS = "adw-row adw-action-row adw-entry-row"
47
47
  /** Base class list of a password entry row. */
48
48
  export declare const NS_PASSWORD_ENTRY_ROW_CLASS = "adw-row adw-action-row adw-entry-row adw-password-entry-row";
49
49
  /** Class list of the trailing pencil. */
50
- export declare const NS_EDIT_ICON_CLASS = "adw-icon adw-entry-edit";
50
+ export declare const NS_EDIT_ICON_CLASS = "gtk-image adw-entry-edit";
51
51
  /**
52
52
  * Marker class for a desensitized part. NS has no insensitive state, so the
53
53
  * class is only a styling hook — {@link NS_INSENSITIVE_OPACITY} is what the user
@@ -1,6 +1,6 @@
1
1
  import { Label, StackLayout, type EventData } from '@nativescript/core';
2
- import type { AdwComboOption } from '@gjsify/adwaita-core';
3
- import { AdwIcon } from './adw-icon.js';
2
+ import type { AdwComboOption, AdwListModelInput } from '@gjsify/adwaita-core';
3
+ import { GtkImage } from './gtk-image.js';
4
4
  /** Event name emitted when {@link GtkDropDown.selected} changes through a pick. Mirrors GObject `notify::selected`. */
5
5
  export declare const NOTIFY_SELECTED = "notify::selected";
6
6
  /** Payload of the `notify::selected` event. */
@@ -16,7 +16,7 @@ export declare class GtkDropDown extends StackLayout {
16
16
  /** The button label — the selected option. */
17
17
  protected readonly _label: Label;
18
18
  /** The down-chevron — a real Adwaita `pan-down-symbolic` icon. */
19
- protected readonly _chevron: AdwIcon;
19
+ protected readonly _chevron: GtkImage;
20
20
  /** The headless options list + selectedIndex↔selectedValue state machine (ADR 0004). */
21
21
  private readonly _state;
22
22
  /** Title shown atop the substituted `action()` sheet. */
@@ -24,9 +24,9 @@ export declare class GtkDropDown extends StackLayout {
24
24
  constructor();
25
25
  /** Open the native chooser and apply the picked option. */
26
26
  private _openChooser;
27
- /** The selectable options. Updates the button label. */
28
- get options(): AdwComboOption[];
29
- set options(value: AdwComboOption[]);
27
+ /** The list model (`Gtk.DropDown:model`). Updates the button label. */
28
+ get model(): AdwComboOption[];
29
+ set model(value: AdwListModelInput);
30
30
  /** The selected option index (`Gtk.DropDown:selected`). */
31
31
  get selected(): number;
32
32
  set selected(raw: number | string);
@@ -1,7 +1,7 @@
1
1
  import { Image } from '@nativescript/core';
2
2
  /** Default decorative-icon size, in DIPs — the Adwaita 16px symbolic grid. */
3
- export declare const DEFAULT_ADW_ICON_SIZE = 16;
4
- export declare class AdwIcon extends Image {
3
+ export declare const DEFAULT_GTK_IMAGE_SIZE = 16;
4
+ export declare class GtkImage extends Image {
5
5
  private _iconSvg;
6
6
  private _iconColor;
7
7
  private _explicitColor;
@@ -1,34 +1,44 @@
1
- import type { AdwMenuEntry } from '@gjsify/adwaita-core';
1
+ import type { AdwMenuActions, AdwMenuInput, AdwMenuModel } from '@gjsify/adwaita-core';
2
2
  import { type EventData } from '@nativescript/core';
3
3
  import { AdwImageButton } from './adw-image-button.js';
4
4
  /** Event name emitted when a menu item is chosen. */
5
5
  export declare const MENU_ITEM_ACTIVATED = "menuItemActivated";
6
- /**
7
- * One entry in an {@link GtkMenuButton}'s menu — `@gjsify/adwaita-core`'s
8
- * {@link AdwMenuEntry}, under the name this widget has always used.
9
- *
10
- * It used to be a THIRD declaration of the same shape (the browser element had a
11
- * second, and the core the original), and this one was missing `icon` — so a menu
12
- * written for one renderer was not the same object on the other. The browser side
13
- * adopted the core type in #1191; this is its twin.
14
- */
15
- export type AdwMenuItem = AdwMenuEntry;
16
6
  /** Payload of the {@link MENU_ITEM_ACTIVATED} event. */
17
7
  export interface MenuItemActivatedEventData extends EventData {
18
8
  /** The chosen item's id (or its label when no id was given). */
19
9
  id: string;
20
10
  /** The chosen item's label. */
21
11
  label: string;
22
- /** The chosen item's index in {@link GtkMenuButton.menuItems}. */
23
- index: number;
12
+ /**
13
+ * Where the item sits in {@link GtkMenuButton.menuModel} — a PATH since ADR 0042,
14
+ * because a submenu is a model of its own and a flat index cannot name one.
15
+ */
16
+ path: readonly number[];
17
+ /** The chosen item's detailed action name, when the item carried one. */
18
+ action?: string;
24
19
  }
25
20
  export declare class GtkMenuButton extends AdwImageButton {
26
- private _items;
21
+ private _model;
22
+ private _actions;
27
23
  private _menuTitle;
28
24
  constructor();
29
- /** The menu items (opened as a native `action()` sheet on tap). */
30
- get menuItems(): AdwMenuItem[];
31
- set menuItems(value: AdwMenuItem[]);
25
+ /**
26
+ * The menu, normalised (ADR 0042) — opened as a native `action()` sheet on tap.
27
+ *
28
+ * Accepts every input form the portable model does, a bare `string[]` included —
29
+ * but NOT a JSON string; see `AdwSplitButton.menuModel` for why the XML door stays
30
+ * shut until a probe can prove it, and why being shut is not the same as being
31
+ * silent.
32
+ */
33
+ get menuModel(): AdwMenuModel;
34
+ set menuModel(value: AdwMenuInput);
35
+ /**
36
+ * What the action group publishes about the actions this menu names — the portable
37
+ * stand-in for a `GActionGroup`, and the only source of a menu's enabled/checked
38
+ * state (ADR 0042).
39
+ */
40
+ get actions(): AdwMenuActions | null;
41
+ set actions(value: AdwMenuActions | null);
32
42
  /** Optional title shown atop the native menu sheet. */
33
43
  get menuTitle(): string;
34
44
  set menuTitle(value: string);
@@ -22,8 +22,10 @@ export { GtkButton } from './gtk-button.js';
22
22
  export type { AdwButtonVariant } from './gtk-button.js';
23
23
  export { AdwImageButton, DEFAULT_ICON_BUTTON_ICON_SIZE } from './adw-image-button.js';
24
24
  export { GtkMenuButton, MENU_ITEM_ACTIVATED } from './gtk-menu-button.js';
25
- export type { AdwMenuItem, MenuItemActivatedEventData } from './gtk-menu-button.js';
26
- export { AdwIcon, DEFAULT_ADW_ICON_SIZE } from './adw-icon.js';
25
+ export type { MenuItemActivatedEventData } from './gtk-menu-button.js';
26
+ export { MENU_CANCEL_LABEL, menuSheetActions, menuSheetRows, presentMenuSheet, resolveMenuChoice, } from './menu-sheet.js';
27
+ export type { MenuSheetPresenter, MenuSheetRow } from './menu-sheet.js';
28
+ export { GtkImage, DEFAULT_GTK_IMAGE_SIZE } from './gtk-image.js';
27
29
  export { AdwBanner, BUTTON_CLICKED } from './adw-banner.js';
28
30
  export { AdwAvatar, DEFAULT_AVATAR_SIZE, avatarInitials } from './adw-avatar.js';
29
31
  export { AdwWindowTitle } from './adw-window-title.js';
@@ -0,0 +1,58 @@
1
+ import type { AdwMenuActions, AdwMenuModel, AdwMenuPath } from '@gjsify/adwaita-core';
2
+ /** Text of the sheet's dismiss button. */
3
+ export declare const MENU_CANCEL_LABEL = "Cancel";
4
+ /** One row of the sheet: the string presented, and where in the model it came from. */
5
+ export interface MenuSheetRow {
6
+ /** The string handed to `action()`, unique within the page. */
7
+ readonly action: string;
8
+ readonly path: AdwMenuPath;
9
+ /** Whether choosing it opens another sheet rather than activating an item. */
10
+ readonly submenu: boolean;
11
+ }
12
+ /**
13
+ * The rows of ONE page — the model's root, or the submenu at `page`.
14
+ *
15
+ * `cancelLabel` seeds the uniqueness set, which is what makes a menu item literally
16
+ * called "Cancel" distinguishable from the reader dismissing the sheet.
17
+ */
18
+ export declare function menuSheetRows(model: AdwMenuModel, page?: AdwMenuPath, actions?: AdwMenuActions, cancelLabel?: string): MenuSheetRow[];
19
+ /** Just the strings, in order — what `action()` takes. */
20
+ export declare const menuSheetActions: (rows: readonly MenuSheetRow[]) => string[];
21
+ /**
22
+ * The row the reader chose, or `null` when the sheet was dismissed. Feed it the SAME
23
+ * rows {@link menuSheetRows} produced, or the lookup is a guess.
24
+ */
25
+ export declare function resolveMenuChoice(rows: readonly MenuSheetRow[], chosen: string | null | undefined): MenuSheetRow | null;
26
+ /** What a caller supplies so this module never imports `@nativescript/core`. */
27
+ export type MenuSheetPresenter = (options: {
28
+ title?: string;
29
+ cancelButtonText: string;
30
+ actions: string[];
31
+ }) => Promise<string | undefined>;
32
+ /**
33
+ * Present the menu, descending into submenus, and answer with the chosen item's PATH.
34
+ *
35
+ * The loop is what makes a submenu a real submenu on a surface that has only one list:
36
+ * choosing a submenu row presents that submenu's rows, with the submenu's own label as
37
+ * the sheet title so the reader can see where they are. A dismissal at any depth ends
38
+ * the interaction — there is no "back" button on a platform sheet, and inventing one as
39
+ * a row would be a menu entry the model does not have.
40
+ */
41
+ export declare function presentMenuSheet(present: MenuSheetPresenter, model: AdwMenuModel, options?: {
42
+ title?: string;
43
+ actions?: AdwMenuActions;
44
+ cancelLabel?: string;
45
+ }): Promise<AdwMenuPath | null>;
46
+ /**
47
+ * Refuse a JSON STRING where a menu model belongs, loudly.
48
+ *
49
+ * NativeScript's `Builder` assigns an XML attribute straight onto the property, so a
50
+ * `menuModel="[…]"` in a view file lands here as a string. The model does not accept one
51
+ * — the gallery probe that would have to prove the XML door compares a read-back by
52
+ * IDENTITY, which no structured value satisfies — and left to `normalizeMenuModel` a
53
+ * string is simply "not an array", so the author would get an EMPTY menu and no
54
+ * diagnostic at all.
55
+ *
56
+ * A door that is shut may not also be silent. This is the sentence that says which.
57
+ */
58
+ export declare function refuseMenuString(value: unknown, widget: string): void;
@@ -37,7 +37,7 @@ export interface NsButtonRowIconVisuals {
37
37
  * title through a second state object would give one label two sources of truth.
38
38
  * {@link rowLabelVisuals} paints it.
39
39
  *
40
- * The icon payload is the symbolic SVG SOURCE, not GTK's icon name, because `AdwIcon`
40
+ * The icon payload is the symbolic SVG SOURCE, not GTK's icon name, because `GtkImage`
41
41
  * renders SVG rather than resolving a name. `ButtonRowState` is indifferent: its rule
42
42
  * is `string_is_not_empty`, which reads the first byte.
43
43
  */
@@ -1,30 +1,11 @@
1
- import type { AdwArrowIcon, AdwMenuEntry, SplitButtonDirection, SplitButtonState } from '@gjsify/adwaita-core';
2
- export type { AdwMenuEntry, SplitButtonDirection };
3
- /** Text of the sheet's dismiss button. */
4
- export declare const MENU_CANCEL_LABEL = "Cancel";
1
+ import type { AdwArrowIcon, SplitButtonDirection, SplitButtonState } from '@gjsify/adwaita-core';
2
+ export type { SplitButtonDirection };
5
3
  /**
6
4
  * The libadwaita arrow glyph names mapped to real Adwaita symbolic SVGs. Keyed by
7
5
  * {@link AdwArrowIcon} and therefore TOTAL: which glyph a direction gets is decided in
8
6
  * core, and a glyph with no SVG here is a compile error rather than a fallback arrow.
9
7
  */
10
8
  export declare const ARROW_SVGS: Readonly<Record<AdwArrowIcon, string>>;
11
- /**
12
- * Normalise a menu assigned from XML or app code into entries. A bare `string[]` is
13
- * accepted (the storybook passes one) and widens to the shared {@link AdwMenuEntry}.
14
- */
15
- export declare function toMenuEntries(value: readonly (string | AdwMenuEntry)[] | null | undefined): AdwMenuEntry[];
16
- /**
17
- * The strings handed to `Dialogs.action()`, one per entry and each unique: a label
18
- * that collides with another entry — or with the dismiss button — gets zero-width
19
- * spaces appended until it is distinct, so {@link resolveMenuChoice} can tell them
20
- * apart.
21
- */
22
- export declare function menuSheetActions(entries: readonly AdwMenuEntry[], cancelLabel?: string): string[];
23
- /**
24
- * The position the user chose, or `-1` when the sheet was dismissed. Feed it the SAME
25
- * array {@link menuSheetActions} produced, or the lookup is a guess.
26
- */
27
- export declare function resolveMenuChoice(sheetActions: readonly string[], chosen: string | null | undefined): number;
28
9
  /** The arrow SVG for a direction; the split button's `none` is the down caret, not a hamburger. */
29
10
  export declare function splitButtonArrowSvg(direction: SplitButtonDirection): string;
30
11
  /**
@@ -10,7 +10,7 @@ export declare function statusPageLabelVisibility(text: string | null | undefine
10
10
  * `has_image`, bound to the image's `visible`.
11
11
  *
12
12
  * C is `paintable || (icon_name && icon_name[0])`; this port has no `paintable`
13
- * counterpart (the icon is an SVG string handed to `AdwIcon`), so only the second
13
+ * counterpart (the icon is an SVG string handed to `GtkImage`), so only the second
14
14
  * half applies. Kept as its own predicate rather than folded into
15
15
  * {@link statusPageLabelVisibility} because upstream really are two closures, and
16
16
  * the missing half is a real gap rather than a simplification.
@@ -8,7 +8,7 @@ import type { AdwViewSwitcherPageInit, ViewSwitcherStateChange } from '@gjsify/a
8
8
  * `icon` are NULLABLE on purpose: a page with neither renders no button at all, and
9
9
  * an absent title flattened to `''` makes that rule inexpressible.
10
10
  *
11
- * `icon` is an Adwaita symbolic SVG DOCUMENT here, not a GTK icon name: `AdwIcon`
11
+ * `icon` is an Adwaita symbolic SVG DOCUMENT here, not a GTK icon name: `GtkImage`
12
12
  * rasterises the path data natively. The core treats the field as an opaque
13
13
  * handle and only ever interprets "absent or empty"; {@link nsIconSvg} resolves
14
14
  * the fallback sentinel it hands back.
@@ -48,7 +48,7 @@ export declare function viewSwitcherPageSpec(page: AdwViewPage, index: number):
48
48
  /** {@link viewSwitcherPageSpec} over a whole page list. */
49
49
  export declare function viewSwitcherPageSpecs(pages: readonly AdwViewPage[]): AdwViewSwitcherPageInit[];
50
50
  /**
51
- * Resolve the core's icon slot to something `AdwIcon` can rasterise.
51
+ * Resolve the core's icon slot to something `GtkImage` can rasterise.
52
52
  *
53
53
  * The core substitutes the NAME `image-missing` for an absent icon. On the browser
54
54
  * side that name becomes a CSS mask class; here it has to become the actual
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/adwaita-nativescript",
3
- "version": "0.46.0",
3
+ "version": "0.48.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",
@@ -10,9 +10,13 @@
10
10
  "types": "./lib/types/index.d.ts",
11
11
  "default": "./lib/esm/index.js"
12
12
  },
13
- "./widgets": {
14
- "types": "./lib/types/widgets/index.d.ts",
15
- "default": "./lib/esm/widgets/index.js"
13
+ "./adw": {
14
+ "types": "./lib/types/namespace/adw.d.ts",
15
+ "default": "./lib/esm/namespace/adw.js"
16
+ },
17
+ "./gtk": {
18
+ "types": "./lib/types/namespace/gtk.d.ts",
19
+ "default": "./lib/esm/namespace/gtk.js"
16
20
  },
17
21
  "./theme/adwaita.css": "./src/theme/adwaita.css",
18
22
  "./fonts": {
@@ -47,10 +51,10 @@
47
51
  "design-system"
48
52
  ],
49
53
  "dependencies": {
50
- "@gjsify/adwaita-core": "^0.46.0",
51
- "@gjsify/adwaita-fonts": "^0.46.0",
52
- "@gjsify/adwaita-icons": "^0.46.0",
53
- "@gjsify/native-platform": "^0.46.0"
54
+ "@gjsify/adwaita-core": "^0.48.0",
55
+ "@gjsify/adwaita-fonts": "^0.48.0",
56
+ "@gjsify/adwaita-icons": "^0.48.0",
57
+ "@gjsify/native-platform": "^0.48.0"
54
58
  },
55
59
  "peerDependencies": {
56
60
  "@nativescript/core": "*"
@@ -61,8 +65,8 @@
61
65
  }
62
66
  },
63
67
  "devDependencies": {
64
- "@gjsify/cli": "^0.46.0",
65
- "@gjsify/unit": "^0.46.0",
68
+ "@gjsify/cli": "^0.48.0",
69
+ "@gjsify/unit": "^0.48.0",
66
70
  "@types/node": "^25.9.2",
67
71
  "typescript": "^6.0.3"
68
72
  },
@@ -264,7 +264,7 @@ Page.adw-window {
264
264
  * Their 24×24 + 5 padding box (_lists.scss:194-198) is deliberately NOT
265
265
  * reproduced. It is a hit/alignment box around a 16 glyph, and NS would read a
266
266
  * `min-width` on an `Image` as room to SCALE the bitmap into — an icon half
267
- * again too large rather than a roomier one. The glyph size is AdwIcon's own. */
267
+ * again too large rather than a roomier one. The glyph size is GtkImage's own. */
268
268
  .adw-entry-indicator,
269
269
  .adw-entry-edit {
270
270
  margin: 0 0 0 6;
@@ -329,7 +329,7 @@ Page.adw-window {
329
329
  }
330
330
 
331
331
  .adw-combo-chevron {
332
- /* An AdwIcon (Image) rendering `pan-down-symbolic`; size + dim colour are set
332
+ /* A GtkImage (Image) rendering `pan-down-symbolic`; size + dim colour are set
333
333
  * on the widget. Only the gap to the value label is styled here. */
334
334
  margin: 0 0 0 2;
335
335
  vertical-align: middle;
@@ -362,7 +362,7 @@ Page.adw-window {
362
362
 
363
363
  /* `dropdown > button > box { border-spacing: 6px }` (_dropdowns.scss:2-3) — the
364
364
  * gap between label and arrow. The arrow's 16px size (_dropdowns.scss:10-13) is
365
- * the AdwIcon default, and its colour follows the light/dark scheme, so neither
365
+ * the GtkImage default, and its colour follows the light/dark scheme, so neither
366
366
  * is set anywhere. */
367
367
  .adw-drop-down-chevron {
368
368
  margin: 0 0 0 6;
@@ -448,7 +448,7 @@ Page.adw-window {
448
448
  *
449
449
  * The `width: 32` / `height: 32` that used to be here NEVER APPLIED. NativeScript
450
450
  * ignores a CSS value for a property the widget has set as a LOCAL one
451
- * (properties/index.js:585-598), and `AdwIcon` assigns `width`/`height` in its
451
+ * (properties/index.js:585-598), and `GtkImage` assigns `width`/`height` in its
452
452
  * constructor — so the chevron has always been the 16 `expander`'s own minimum
453
453
  * asks for (_expanders.scss:2-3), which is right, while the stylesheet claimed
454
454
  * a 32 tap target it never got. `color` and `font-size` were dead for the other
@@ -911,7 +911,7 @@ Page.adw-window {
911
911
  padding: 24 32 24 32;
912
912
  }
913
913
 
914
- /* The symbolic icon (AdwIcon) — only spacing; size/colour are baked by AdwIcon. */
914
+ /* The symbolic icon (GtkImage) — only spacing; size/colour are baked by GtkImage. */
915
915
  .adw-status-page-icon {
916
916
  margin: 0 0 12 0;
917
917
  }
@@ -961,7 +961,7 @@ Page.adw-window {
961
961
  * three children with `border-spacing: 6px` (_lists.scss:458-462), which the NS
962
962
  * subset has no property for — so the 6 rides on the icons, mirrored.
963
963
  *
964
- * MARGIN ONLY. Both are `AdwIcon`s, i.e. `Image`s showing a bitmap that was
964
+ * MARGIN ONLY. Both are `GtkImage`s, i.e. `Image`s showing a bitmap that was
965
965
  * rendered in its fill colour, so `color` here reaches nothing and `font-size`
966
966
  * has no text to size. They used to be declared anyway, which put a dead accent
967
967
  * declaration in the runtime-accent table as well; the colour now follows the
@@ -1012,7 +1012,7 @@ Page.adw-window {
1012
1012
 
1013
1013
  /* On a suggested/destructive button the label must take the button's foreground
1014
1014
  * (the explicit dark label colour above would otherwise win over the inherited
1015
- * one). The matching ICON colour is pre-baked by the caller via AdwIcon.iconColor. */
1015
+ * one). The matching ICON colour is pre-baked by the caller via GtkImage.iconColor. */
1016
1016
  .adw-button.suggested-action .adw-button-content-label {
1017
1017
  color: #ffffff;
1018
1018
  }
@@ -1711,7 +1711,7 @@ Page.ns-dark.adw-window {
1711
1711
  /* ===== Dark: expander row ===== */
1712
1712
 
1713
1713
  /* No dark counterpart for the chevron: the 70% is an alpha over whatever the
1714
- * bitmap was rendered in, and AdwIcon re-renders that on a scheme change. The
1714
+ * bitmap was rendered in, and GtkImage re-renders that on a scheme change. The
1715
1715
  * `color` this rule used to set reached an `Image` and did nothing. */
1716
1716
 
1717
1717
  .ns-dark .adw-expander-disclosure {