@gtkx/navigation 2.0.0-beta.12 → 2.0.0-beta.13

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 (86) hide show
  1. package/README.md +1 -1
  2. package/dist/drawer/create-drawer-navigator.d.ts +3 -1
  3. package/dist/drawer/create-drawer-navigator.d.ts.map +1 -1
  4. package/dist/drawer/create-drawer-navigator.js +10 -10
  5. package/dist/drawer/create-drawer-navigator.js.map +1 -1
  6. package/dist/drawer/drawer-view.js +2 -2
  7. package/dist/drawer/drawer-view.js.map +1 -1
  8. package/dist/index.d.ts +5 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +4 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/shared/scene-page.d.ts.map +1 -1
  13. package/dist/shared/scene-page.js +2 -5
  14. package/dist/shared/scene-page.js.map +1 -1
  15. package/dist/shared/use-has-loaded.d.ts +3 -0
  16. package/dist/shared/use-has-loaded.d.ts.map +1 -0
  17. package/dist/shared/use-has-loaded.js +10 -0
  18. package/dist/shared/use-has-loaded.js.map +1 -0
  19. package/dist/split-view/create-split-view-navigator.d.ts +7 -2
  20. package/dist/split-view/create-split-view-navigator.d.ts.map +1 -1
  21. package/dist/split-view/create-split-view-navigator.js +2 -6
  22. package/dist/split-view/create-split-view-navigator.js.map +1 -1
  23. package/dist/split-view/split-view-collapsed.d.ts +11 -0
  24. package/dist/split-view/split-view-collapsed.d.ts.map +1 -0
  25. package/dist/split-view/split-view-collapsed.js +17 -0
  26. package/dist/split-view/split-view-collapsed.js.map +1 -0
  27. package/dist/split-view/split-view.d.ts.map +1 -1
  28. package/dist/split-view/split-view.js +39 -14
  29. package/dist/split-view/split-view.js.map +1 -1
  30. package/dist/split-view/types.d.ts +9 -2
  31. package/dist/split-view/types.d.ts.map +1 -1
  32. package/dist/split-view/types.js.map +1 -1
  33. package/dist/stack/create-stack-navigator.d.ts +3 -1
  34. package/dist/stack/create-stack-navigator.d.ts.map +1 -1
  35. package/dist/stack/create-stack-navigator.js +0 -1
  36. package/dist/stack/create-stack-navigator.js.map +1 -1
  37. package/dist/stack/stack-view.js +1 -1
  38. package/dist/stack/stack-view.js.map +1 -1
  39. package/dist/tab-view/create-tab-view-navigator.d.ts +32 -0
  40. package/dist/tab-view/create-tab-view-navigator.d.ts.map +1 -0
  41. package/dist/tab-view/create-tab-view-navigator.js +21 -0
  42. package/dist/tab-view/create-tab-view-navigator.js.map +1 -0
  43. package/dist/tab-view/page-registry.d.ts +34 -0
  44. package/dist/tab-view/page-registry.d.ts.map +1 -0
  45. package/dist/tab-view/page-registry.js +70 -0
  46. package/dist/tab-view/page-registry.js.map +1 -0
  47. package/dist/tab-view/tab-view-host.d.ts +25 -0
  48. package/dist/tab-view/tab-view-host.d.ts.map +1 -0
  49. package/dist/tab-view/tab-view-host.js +284 -0
  50. package/dist/tab-view/tab-view-host.js.map +1 -0
  51. package/dist/tab-view/tab-view-router.d.ts +34 -0
  52. package/dist/tab-view/tab-view-router.d.ts.map +1 -0
  53. package/dist/tab-view/tab-view-router.js +359 -0
  54. package/dist/tab-view/tab-view-router.js.map +1 -0
  55. package/dist/tab-view/types.d.ts +240 -0
  56. package/dist/tab-view/types.d.ts.map +1 -0
  57. package/dist/tab-view/types.js +2 -0
  58. package/dist/tab-view/types.js.map +1 -0
  59. package/dist/tabs/create-tab-navigator.d.ts +3 -1
  60. package/dist/tabs/create-tab-navigator.d.ts.map +1 -1
  61. package/dist/tabs/create-tab-navigator.js +0 -1
  62. package/dist/tabs/create-tab-navigator.js.map +1 -1
  63. package/dist/tabs/tab-view.js +1 -1
  64. package/dist/tabs/tab-view.js.map +1 -1
  65. package/dist/theme.js +2 -2
  66. package/dist/theme.js.map +1 -1
  67. package/package.json +6 -6
  68. package/src/drawer/create-drawer-navigator.tsx +23 -11
  69. package/src/drawer/drawer-view.tsx +2 -2
  70. package/src/index.ts +30 -0
  71. package/src/shared/scene-page.tsx +2 -6
  72. package/src/shared/use-has-loaded.ts +13 -0
  73. package/src/split-view/create-split-view-navigator.tsx +16 -1
  74. package/src/split-view/split-view-collapsed.ts +21 -0
  75. package/src/split-view/split-view.tsx +92 -45
  76. package/src/split-view/types.ts +9 -2
  77. package/src/stack/create-stack-navigator.tsx +11 -1
  78. package/src/stack/stack-view.tsx +1 -1
  79. package/src/tab-view/create-tab-view-navigator.tsx +122 -0
  80. package/src/tab-view/page-registry.ts +139 -0
  81. package/src/tab-view/tab-view-host.tsx +474 -0
  82. package/src/tab-view/tab-view-router.ts +528 -0
  83. package/src/tab-view/types.ts +291 -0
  84. package/src/tabs/create-tab-navigator.tsx +11 -1
  85. package/src/tabs/tab-view.tsx +2 -2
  86. package/src/theme.ts +2 -2
@@ -0,0 +1,291 @@
1
+ import type * as Adw from "@gtkx/gi/adw";
2
+ import type * as Gio from "@gtkx/gi/gio";
3
+ import type * as GObject from "@gtkx/gi/gobject";
4
+ import type { AdwTabDropProps } from "@gtkx/react/internal";
5
+ import type {
6
+ DefaultNavigatorOptions,
7
+ Descriptor,
8
+ NavigationHelpers,
9
+ NavigationProp,
10
+ NavigationState,
11
+ ParamListBase,
12
+ RouteProp,
13
+ } from "@react-navigation/core";
14
+ import type { ReactNode } from "react";
15
+ import type { HeaderOptions } from "../shared/types.js";
16
+
17
+ /** Navigation state of a tab view navigator. Pinned routes come first in `routes`, in `pinnedKeys` order. */
18
+ type TabViewNavigationState<ParamList extends ParamListBase> = NavigationState<ParamList> & {
19
+ /** Type of the router, in this case `tabview`. */
20
+ type: "tabview";
21
+ /** Keys of the pinned routes. */
22
+ pinnedKeys: string[];
23
+ /** Key of the tab each tab was opened from, by route key. */
24
+ parents: Record<string, string>;
25
+ };
26
+
27
+ /** Options accepted when opening a tab. */
28
+ type TabViewOpenOptions = {
29
+ /** Key of the tab the new one is opened from; the new tab follows that tab and its descendants, which are selected again when it closes. */
30
+ parent?: string;
31
+ /** Whether the new tab is selected; defaults to `true`. */
32
+ select?: boolean;
33
+ /** Position among the unpinned tabs; defaults to the end. */
34
+ position?: number;
35
+ };
36
+
37
+ /** Actions specific to the tab view router. */
38
+ type TabViewActionType =
39
+ | {
40
+ type: "OPEN_TAB";
41
+ payload: {
42
+ name: string;
43
+ params?: object;
44
+ key?: string;
45
+ parent?: string;
46
+ select?: boolean;
47
+ position?: number;
48
+ pinned?: boolean;
49
+ };
50
+ }
51
+ | { type: "CLOSE_TAB"; payload: { key?: string } }
52
+ | { type: "CLOSE_OTHER_TABS"; payload: { key?: string } }
53
+ | { type: "CLOSE_TABS_BEFORE"; payload: { key?: string } }
54
+ | { type: "CLOSE_TABS_AFTER"; payload: { key?: string } }
55
+ | { type: "SELECT_TAB"; payload: { key: string } }
56
+ | { type: "REORDER_TAB"; payload: { key: string; position: number } }
57
+ | { type: "PIN_TAB"; payload: { key: string; pinned: boolean } };
58
+
59
+ /** Action helpers added to the navigation object of tab view screens. Keys default to the selected tab. */
60
+ type TabViewActionHelpers<ParamList extends ParamListBase> = {
61
+ /** Opens a new tab for a screen, or selects the open tab whose `getId` matches. */
62
+ openTab<RouteName extends keyof ParamList>(
63
+ name: RouteName,
64
+ params?: ParamList[RouteName],
65
+ options?: TabViewOpenOptions,
66
+ ): void;
67
+ /** Closes a tab. Closing the last tab is left to the parent navigator or `onUnhandledAction`. */
68
+ closeTab(key?: string): void;
69
+ /** Closes every unpinned tab except one. */
70
+ closeOtherTabs(key?: string): void;
71
+ /** Closes the unpinned tabs before one. */
72
+ closeTabsBefore(key?: string): void;
73
+ /** Closes the unpinned tabs after one. */
74
+ closeTabsAfter(key?: string): void;
75
+ /** Selects a tab. */
76
+ selectTab(key: string): void;
77
+ /** Moves a tab within its pinned or unpinned group. */
78
+ reorderTab(key: string, position: number): void;
79
+ /** Pins a tab, moving it after the other pinned tabs, or unpins it, moving it before the unpinned tabs. */
80
+ pinTab(key: string, pinned: boolean): void;
81
+ };
82
+
83
+ /** Events the tab view navigator emits on top of React Navigation's core events. */
84
+ type TabViewNavigationEventMap = {
85
+ /** The user selected a tab natively. */
86
+ tabPress: {
87
+ /** No payload. */
88
+ data: undefined;
89
+ /** Calling `preventDefault` keeps the current tab. */
90
+ canPreventDefault: true;
91
+ };
92
+ /** The user activated the tab's indicator icon. */
93
+ indicatorActivated: {
94
+ /** No payload. */
95
+ data: undefined;
96
+ };
97
+ };
98
+
99
+ /** An icon given by theme name or as a `Gio.Icon`. */
100
+ type TabViewIcon = string | Gio.Icon;
101
+
102
+ /** Per-screen options of the tab view navigator. */
103
+ type TabViewNavigationOptions = HeaderOptions & {
104
+ /** Renders a custom top bar instead of the default `AdwHeaderBar`. */
105
+ header?: (props: TabViewHeaderProps) => ReactNode;
106
+ /** Icon shown in the tab; `null` shows the view's default icon. */
107
+ icon?: TabViewIcon | null;
108
+ /** Tooltip of the tab; supports Pango markup. */
109
+ tooltip?: string;
110
+ /** Search keyword for the tab overview. */
111
+ keyword?: string;
112
+ /** Whether the tab shows a loading spinner instead of its icon. */
113
+ loading?: boolean;
114
+ /** Whether the tab is highlighted as needing attention. */
115
+ needsAttention?: boolean;
116
+ /** Indicator icon shown at the end of the tab. */
117
+ indicatorIcon?: TabViewIcon | null;
118
+ /** Whether clicking the indicator emits `indicatorActivated`. */
119
+ indicatorActivatable?: boolean;
120
+ /** Tooltip of the indicator icon; supports Pango markup. */
121
+ indicatorTooltip?: string;
122
+ /** Whether the overview thumbnail stays live while the tab is not selected. */
123
+ liveThumbnail?: boolean;
124
+ /** Horizontal alignment of the overview thumbnail, from 0 to 1. */
125
+ thumbnailXalign?: number;
126
+ /** Vertical alignment of the overview thumbnail, from 0 to 1. */
127
+ thumbnailYalign?: number;
128
+ /** Whether the screen mounts on first selection instead of as soon as the tab opens; defaults to `true`. */
129
+ lazy?: boolean;
130
+ };
131
+
132
+ /** The screen a new tab opens, as returned by the overview's `onCreateTab`. */
133
+ type TabViewTarget = {
134
+ /** Name of the screen to open. */
135
+ name: string;
136
+ /** Params of the new tab. */
137
+ params?: object;
138
+ };
139
+
140
+ /** Settings of the `AdwTabOverview` rendered around the view. */
141
+ type TabViewOverviewConfig = {
142
+ /**
143
+ * Whether the overview is open. When given, the overview follows it: the user opening or closing the overview
144
+ * calls `onOpenChange`, and a value the app does not update is restored. Leave it out to let the overview open
145
+ * and close on its own.
146
+ */
147
+ open?: boolean;
148
+ /** Called when the overview opens or closes natively. */
149
+ onOpenChange?: (open: boolean) => void;
150
+ /** Whether the overview shows a new tab button; defaults to `false`. */
151
+ enableNewTab?: boolean;
152
+ /** Whether the overview offers search; defaults to `true`. */
153
+ enableSearch?: boolean;
154
+ /** Returns the screen the new tab button opens. */
155
+ onCreateTab?: () => TabViewTarget;
156
+ };
157
+
158
+ /** Additional drop target of the tab bar and overview. */
159
+ type TabViewExtraDropTarget = NonNullable<AdwTabDropProps["extraDropTarget"]>;
160
+
161
+ /** Props of the tab view navigator beyond the options every navigator shares. */
162
+ type TabViewNavigationConfig = {
163
+ /** A view created before the navigator renders, such as one returned from a `create-window` handler. */
164
+ view?: Adw.TabView;
165
+ /** Whether the tab bar renders; defaults to `true`. */
166
+ tabBarVisible?: boolean;
167
+ /** Whether the tab bar hides with a single tab; defaults to `true`. */
168
+ tabBarAutohide?: boolean;
169
+ /** Whether tabs expand to fill the bar; defaults to `true`. */
170
+ tabBarExpand?: boolean;
171
+ /** Whether close buttons sit at the start of tabs; defaults to `false`. */
172
+ tabBarInverted?: boolean;
173
+ /** Renders an `AdwTabOverview` around the view. */
174
+ overview?: TabViewOverviewConfig;
175
+ /** An existing menu model to use as the tabs' context menu. Use `renderMenu` to declare the menu in JSX instead. */
176
+ menuModel?: Gio.MenuModel | null;
177
+ /**
178
+ * Renders the tabs' context menu. Attach `ref` to a `GMenu`, or to any menu model element, anywhere in the
179
+ * returned tree; the navigator renders the tree outside the widget hierarchy and uses that model. A navigator
180
+ * given both `renderMenu` and a `menuModel` throws.
181
+ */
182
+ renderMenu?: (ref: (menu: Gio.MenuModel | null) => void) => ReactNode;
183
+ /** Additional content accepted by drops on tabs. */
184
+ extraDropTarget?: TabViewExtraDropTarget | null;
185
+ /** Handles content dropped on a tab; returns whether the drop was accepted. */
186
+ onExtraDragDrop?: (route: RouteProp<ParamListBase>, value: GObject.Value) => boolean;
187
+ /** Returns the view of a new window when a tab is dragged out of this one. */
188
+ onCreateWindow?: () => Adw.TabView | null;
189
+ /** Called with the tab whose context menu opens, or `null` when it closes, after the chosen menu action has run. */
190
+ onSetupMenu?: (route: RouteProp<ParamListBase> | null) => void;
191
+ /** Keyboard shortcuts the view handles. */
192
+ shortcuts?: Adw.TabViewShortcuts;
193
+ /** Icon of tabs without an `icon` option. */
194
+ defaultIcon?: TabViewIcon | null;
195
+ };
196
+
197
+ /** Options of the tab view router. */
198
+ type TabViewRouterOptions = {
199
+ /** Screen of the tab opened when the view starts empty; defaults to the first screen. */
200
+ initialRouteName?: string;
201
+ /**
202
+ * Whether closing the last tab replaces it with a new tab of the initial route, instead of leaving that close
203
+ * unhandled for a parent navigator or the container's `onUnhandledAction`. Use it for a tab view inside a section
204
+ * of the app rather than a window of its own; defaults to `false`.
205
+ */
206
+ replaceLastTab?: boolean;
207
+ };
208
+
209
+ /** Navigation object of a tab view screen. */
210
+ type TabViewNavigationProp<
211
+ ParamList extends ParamListBase,
212
+ RouteName extends keyof ParamList = keyof ParamList,
213
+ NavigatorID extends string | undefined = undefined,
214
+ > = NavigationProp<
215
+ ParamList,
216
+ RouteName,
217
+ NavigatorID,
218
+ TabViewNavigationState<ParamList>,
219
+ TabViewNavigationOptions,
220
+ TabViewNavigationEventMap
221
+ > &
222
+ TabViewActionHelpers<ParamList>;
223
+
224
+ /** Props a tab view screen component receives. */
225
+ type TabViewScreenProps<
226
+ ParamList extends ParamListBase,
227
+ RouteName extends keyof ParamList = keyof ParamList,
228
+ NavigatorID extends string | undefined = undefined,
229
+ > = {
230
+ /** Navigation object of the screen. */
231
+ navigation: TabViewNavigationProp<ParamList, RouteName, NavigatorID>;
232
+ /** The route the screen renders. */
233
+ route: RouteProp<ParamList, RouteName>;
234
+ };
235
+
236
+ /** Arguments of a custom tab view `header` renderer. */
237
+ type TabViewHeaderProps = {
238
+ /** The selected route. */
239
+ route: RouteProp<ParamListBase>;
240
+ /** Navigation object of the selected route. */
241
+ navigation: TabViewNavigationProp<ParamListBase>;
242
+ /** Resolved options of the selected route. */
243
+ options: TabViewNavigationOptions;
244
+ };
245
+
246
+ /** Navigation helpers of the tab view navigator itself. */
247
+ type TabViewNavigationHelpers = NavigationHelpers<ParamListBase, TabViewNavigationEventMap> &
248
+ TabViewActionHelpers<ParamListBase>;
249
+
250
+ /** Descriptor of one tab view route. */
251
+ type TabViewDescriptor = Descriptor<
252
+ TabViewNavigationOptions,
253
+ TabViewNavigationProp<ParamListBase>,
254
+ RouteProp<ParamListBase>
255
+ >;
256
+ /** Descriptors of the tab view routes, keyed by route key. */
257
+ type TabViewDescriptorMap = Record<string, TabViewDescriptor>;
258
+
259
+ /** Props of the tab view `Navigator` component. */
260
+ type TabViewNavigatorProps = DefaultNavigatorOptions<
261
+ ParamListBase,
262
+ string | undefined,
263
+ TabViewNavigationState<ParamListBase>,
264
+ TabViewNavigationOptions,
265
+ TabViewNavigationEventMap,
266
+ TabViewNavigationProp<ParamListBase>
267
+ > &
268
+ TabViewRouterOptions &
269
+ TabViewNavigationConfig;
270
+
271
+ export type {
272
+ TabViewActionHelpers,
273
+ TabViewActionType,
274
+ TabViewDescriptor,
275
+ TabViewDescriptorMap,
276
+ TabViewExtraDropTarget,
277
+ TabViewHeaderProps,
278
+ TabViewIcon,
279
+ TabViewNavigationConfig,
280
+ TabViewNavigationEventMap,
281
+ TabViewNavigationHelpers,
282
+ TabViewNavigationOptions,
283
+ TabViewNavigationProp,
284
+ TabViewNavigationState,
285
+ TabViewNavigatorProps,
286
+ TabViewOpenOptions,
287
+ TabViewOverviewConfig,
288
+ TabViewRouterOptions,
289
+ TabViewScreenProps,
290
+ TabViewTarget,
291
+ };
@@ -59,7 +59,17 @@ function createTabNavigator<
59
59
  const ParamList extends ParamListBase,
60
60
  const NavigatorID extends string | undefined = string | undefined,
61
61
  const TypeBag extends NavigatorTypeBagBase = TabTypeBag<ParamList, NavigatorID>,
62
- const Config extends StaticConfig<TypeBag> | undefined = undefined,
62
+ >(): TypedNavigator<TypeBag, undefined>;
63
+ /** Creates a tab navigator rendered with `AdwViewStack` and an `AdwViewSwitcher`. */
64
+ function createTabNavigator<
65
+ const ParamList extends ParamListBase,
66
+ const NavigatorID extends string | undefined = string | undefined,
67
+ const TypeBag extends NavigatorTypeBagBase = TabTypeBag<ParamList, NavigatorID>,
68
+ const Config extends StaticConfig<TypeBag> = StaticConfig<TypeBag>,
69
+ >(config: Config): TypedNavigator<TypeBag, Config>;
70
+ function createTabNavigator<
71
+ const TypeBag extends NavigatorTypeBagBase,
72
+ const Config extends StaticConfig<TypeBag> | undefined,
63
73
  >(config?: Config): TypedNavigator<TypeBag, Config> {
64
74
  return createNavigatorFactory(TabNavigator)(config) as TypedNavigator<TypeBag, Config>;
65
75
  }
@@ -103,10 +103,10 @@ const TabView = ({ state, navigation, descriptors, tabBarPosition = "top" }: Tab
103
103
 
104
104
  return (
105
105
  <AdwToolbarView
106
- topBar={
106
+ top={
107
107
  <TabHeader descriptor={descriptor} viewSwitcher={tabBarPosition === "top" ? viewSwitcher : undefined} />
108
108
  }
109
- bottomBar={hasSwitcherBar ? <AdwViewSwitcherBar stack={stack} reveal /> : undefined}
109
+ bottom={hasSwitcherBar ? <AdwViewSwitcherBar stack={stack} reveal /> : undefined}
110
110
  >
111
111
  <AdwViewStack
112
112
  ref={setStack}
package/src/theme.ts CHANGED
@@ -21,8 +21,8 @@ const DarkTheme: AdwaitaTheme = { dark: true, highContrast: false };
21
21
 
22
22
  const useAdwaitaTheme = (): AdwaitaTheme => {
23
23
  const manager = Adw.StyleManager.getDefault();
24
- const isDark = useProperty(manager, "dark") ?? manager.getDark();
25
- const isHighContrast = useProperty(manager, "highContrast") ?? manager.getHighContrast();
24
+ const isDark = useProperty(manager, "dark");
25
+ const isHighContrast = useProperty(manager, "highContrast");
26
26
 
27
27
  return useMemo(() => ({ dark: isDark, highContrast: isHighContrast }), [isDark, isHighContrast]);
28
28
  };