@gnome-ui/react-native 1.8.0 → 1.10.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.
@@ -0,0 +1,92 @@
1
+ import { IconDefinition } from '@gnome-ui/icons';
2
+ import { ReactNode } from 'react';
3
+ import { StyleProp, ViewStyle } from 'react-native';
4
+ export interface WidgetDefinition {
5
+ /** Stable unique identifier. Also the value stored in `value`. */
6
+ id: string;
7
+ /** Row label shown in the picker catalog and above the widget once added. */
8
+ label: string;
9
+ /** Optional secondary line shown below `label` in the picker row. */
10
+ description?: string;
11
+ /** Icon shown in the picker row and in the widget's own header once added. */
12
+ icon?: IconDefinition;
13
+ /** Renders the widget's body once it has been added to the manager. */
14
+ render: () => ReactNode;
15
+ }
16
+ /**
17
+ * `@gnome-ui/react`'s `pickerSurface` calls this option `"modal"`, naming it
18
+ * after its own `Modal` component. This package's `Modal` counterpart is
19
+ * `Dialog` (RN's own `Modal` primitive is a different, lower-level thing —
20
+ * see the main `ROADMAP.md`'s note on that exact naming trap), so the option
21
+ * is named after what it actually renders here instead of ported verbatim.
22
+ */
23
+ export type WidgetManagerPickerSurface = 'dialog' | 'bottomSheet' | 'drawer';
24
+ export interface WidgetManagerProps {
25
+ /** Full catalog of widgets available to add. */
26
+ catalog: WidgetDefinition[];
27
+ /** Controlled list of added widget ids, in display order. */
28
+ value: string[];
29
+ /** Called with the new id list when the user confirms the picker. */
30
+ onChange: (value: string[]) => void;
31
+ /** Header title. */
32
+ title: string;
33
+ /** Icon shown at the leading edge of the header. */
34
+ icon?: IconDefinition;
35
+ /** Which overlay renders the catalog picker. Defaults to `"dialog"`. */
36
+ pickerSurface?: WidgetManagerPickerSurface;
37
+ /** Label for the dashed "add widget" trigger. Defaults to `"Add Widget"`. */
38
+ addTriggerLabel?: string;
39
+ /** Message shown when there are no widgets and not in edit mode. Defaults to `"No widgets added"`. */
40
+ emptyStateLabel?: string;
41
+ /** Heading of the picker overlay. Defaults to `"Widgets"`. */
42
+ pickerTitle?: string;
43
+ /** Label for a catalog row's add action. Defaults to `"Add"`. */
44
+ addLabel?: string;
45
+ /** Label for a catalog row's remove action (already staged). Defaults to `"Remove"`. */
46
+ removeLabel?: string;
47
+ /** Label for the picker's confirm action. Defaults to `"Accept"`. */
48
+ confirmLabel?: string;
49
+ /** Label for the picker's cancel action. Defaults to `"Cancel"`. */
50
+ cancelLabel?: string;
51
+ /** Accessible name of the header's edit-mode toggle button. Defaults to `"Edit widgets"`. */
52
+ editLabel?: string;
53
+ style?: StyleProp<ViewStyle>;
54
+ testID?: string;
55
+ }
56
+ /**
57
+ * Card that manages a controlled collection of "widgets" — pick which ones
58
+ * are visible from a catalog, each rendering its own arbitrary content.
59
+ * Mirrors `@gnome-ui/react`'s own `WidgetManager`.
60
+ *
61
+ * The header's edit button toggles a local `editing` state: in view mode
62
+ * only the added widgets (or an empty-state message) are shown; in edit
63
+ * mode a dashed "add widget" trigger also appears, opening a catalog picker
64
+ * (`pickerSurface`: `"dialog"`, `"bottomSheet"`, or `"drawer"`, each backed
65
+ * by the already-shipped `Dialog`/`BottomSheet`/`Drawer`). Adding/removing
66
+ * is staged inside the picker and only applied — via `onChange` — when the
67
+ * user confirms; canceling or dismissing the picker discards the staging.
68
+ * Widgets can only be removed through the picker, never inline in the card.
69
+ *
70
+ * The catalog list is wrapped in its own `ScrollView` (capped at 360dp)
71
+ * before being handed to whichever picker surface renders it — unlike the
72
+ * web version's `overflow-y: auto` on the `Modal`/`BottomSheet`/`Drawer`
73
+ * body, none of this package's three overlay components scroll their
74
+ * `children` for you, so a long catalog needs that scroll container built
75
+ * in here rather than assumed.
76
+ *
77
+ * `Dialog` already renders its own confirm/cancel action row from a
78
+ * `buttons` array, so only `bottomSheet`/`drawer` need the hand-rolled
79
+ * footer row the web version calls `pickerFooter` — the exact same split
80
+ * the web source itself documents ("Modal uses its own actions").
81
+ *
82
+ * Not ported: `aria-pressed` on the edit toggle — `Button`/`IconButton` set
83
+ * their own internal `accessibilityState={{ disabled }}` on the underlying
84
+ * `Pressable`, and RN merges a spread prop object outright rather than
85
+ * key-by-key, so passing a second `accessibilityState` here would silently
86
+ * replace rather than merge with it (the same `Popover`-trigger clobber
87
+ * `SplitButton` already worked around) — dropped rather than routed around
88
+ * for one decorative toggle-state announcement.
89
+ *
90
+ * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.WidgetManager.html
91
+ */
92
+ export declare const WidgetManager: ({ catalog, value, onChange, title, icon, pickerSurface, addTriggerLabel, emptyStateLabel, pickerTitle, addLabel, removeLabel, confirmLabel, cancelLabel, editLabel, style, testID, }: WidgetManagerProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { WidgetDefinition, WidgetManagerPickerSurface, WidgetManagerProps, } from './WidgetManager';
2
+ export { WidgetManager } from './WidgetManager';
@@ -0,0 +1 @@
1
+ export * from './useBreakpoint';
@@ -0,0 +1,79 @@
1
+ /**
2
+ * GNOME / libadwaita canonical breakpoints (in dp, assuming 1 sp = 1 dp at 1× density).
3
+ *
4
+ * | Name | Max width | Pattern triggered |
5
+ * |----------|-----------|--------------------|
6
+ * | `narrow` | ≤ 400 dp | Collapse split views; sidebar becomes overlay |
7
+ * | `medium` | ≤ 550 dp | Move ViewSwitcher to a bottom bar |
8
+ * | `wide` | ≤ 860 dp | Collapse outer pane in nested split views |
9
+ *
10
+ * Identical thresholds to `@gnome-ui/react`'s `useBreakpoint` — only the
11
+ * measurement source differs (`useWindowDimensions` instead of
12
+ * `window.innerWidth`/a `resize` listener).
13
+ *
14
+ * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.Breakpoint.html
15
+ */
16
+ export declare const GNOME_BREAKPOINTS: {
17
+ /** ≤ 400 dp — split views collapse to single pane */
18
+ readonly narrow: 400;
19
+ /** ≤ 550 dp — ViewSwitcher moves to bottom bar */
20
+ readonly medium: 550;
21
+ /** ≤ 860 dp — outer pane of nested split views collapses */
22
+ readonly wide: 860;
23
+ };
24
+ export type GnomeBreakpointName = keyof typeof GNOME_BREAKPOINTS;
25
+ export interface BreakpointState {
26
+ /** Width ≤ 400 dp — split views are collapsed. */
27
+ isNarrow: boolean;
28
+ /** Width ≤ 550 dp — medium or narrower. */
29
+ isMedium: boolean;
30
+ /** Width ≤ 860 dp — wide or narrower. */
31
+ isWide: boolean;
32
+ /** Current window width in dp. */
33
+ width: number;
34
+ }
35
+ /**
36
+ * Tracks the window width against GNOME / libadwaita breakpoints.
37
+ *
38
+ * Built on `useWindowDimensions` (not `Dimensions.get` + a manual listener),
39
+ * since it already re-renders its subscribers on every rotation/resize —
40
+ * there is no CSS media query to lean on here, unlike the web version.
41
+ *
42
+ * @example
43
+ * const { isNarrow, isMedium } = useBreakpoint();
44
+ * // isNarrow → true when the window is ≤ 400 dp wide (split views should collapse)
45
+ * // isMedium → true when ≤ 550 dp (use a bottom ViewSwitcher instead)
46
+ */
47
+ export declare function useBreakpoint(): BreakpointState;
48
+ /** The widest bucket, above every breakpoint, is `base`. */
49
+ export type GnomeBreakpointBucket = GnomeBreakpointName | 'base';
50
+ /**
51
+ * A value that may vary by breakpoint: either the value itself, or a map of
52
+ * breakpoint names to values.
53
+ *
54
+ * The buckets are max-widths, so the map reads like stacked `max-width`
55
+ * media queries — `base` is the widest, and the narrowest matching entry
56
+ * wins:
57
+ *
58
+ * ```ts
59
+ * { base: 3, wide: 2, narrow: 1 }
60
+ * // ≤ 400 dp → 1 | ≤ 860 dp → 2 | wider → 3
61
+ * // (550 dp matches `wide`, since no `medium` entry is given)
62
+ * ```
63
+ */
64
+ export type ResponsiveValue<T> = T | ({
65
+ base?: T;
66
+ } & Partial<Record<GnomeBreakpointName, T>>);
67
+ /**
68
+ * Bucket a width falls into. The same thresholds serve `useBreakpoint` and
69
+ * `BreakpointBin` — a breakpoint applies to whatever it's measured against,
70
+ * window or container alike.
71
+ *
72
+ * A width of `0` means "not measured yet" and reports `base`, so the first
73
+ * render matches the widest layout rather than flashing the narrowest one.
74
+ */
75
+ export declare function bucketForWidth(width: number): GnomeBreakpointBucket;
76
+ /** True when `value` is a breakpoint map rather than a plain value. */
77
+ export declare function isResponsiveMap<T>(value: ResponsiveValue<T> | undefined): boolean;
78
+ /** Pick the entry for `bucket`, falling back outwards to the wider ones. */
79
+ export declare function resolveResponsive<T>(value: ResponsiveValue<T> | undefined, bucket: GnomeBreakpointBucket, fallback: T): T;