@gnome-ui/react-native 1.3.0 → 1.5.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 (38) hide show
  1. package/README.md +463 -4
  2. package/dist/components/Avatar/Avatar.d.ts +53 -0
  3. package/dist/components/Avatar/index.d.ts +2 -0
  4. package/dist/components/Badge/Badge.d.ts +48 -0
  5. package/dist/components/Badge/index.d.ts +2 -0
  6. package/dist/components/BottomSheet/BottomSheet.d.ts +82 -0
  7. package/dist/components/BottomSheet/index.d.ts +2 -0
  8. package/dist/components/Chip/Chip.d.ts +63 -0
  9. package/dist/components/Chip/index.d.ts +2 -0
  10. package/dist/components/Divider/Divider.d.ts +36 -0
  11. package/dist/components/Divider/index.d.ts +2 -0
  12. package/dist/components/Drawer/Drawer.d.ts +117 -0
  13. package/dist/components/Drawer/index.d.ts +2 -0
  14. package/dist/components/Expander/Expander.d.ts +64 -0
  15. package/dist/components/Expander/index.d.ts +2 -0
  16. package/dist/components/FileTypeIcon/FileTypeIcon.d.ts +45 -0
  17. package/dist/components/FileTypeIcon/fileType.d.ts +8 -0
  18. package/dist/components/FileTypeIcon/index.d.ts +3 -0
  19. package/dist/components/Highlight/Highlight.d.ts +42 -0
  20. package/dist/components/Highlight/index.d.ts +2 -0
  21. package/dist/components/IconButton/IconButton.d.ts +34 -0
  22. package/dist/components/IconButton/index.d.ts +2 -0
  23. package/dist/components/LevelBar/LevelBar.d.ts +72 -0
  24. package/dist/components/LevelBar/index.d.ts +2 -0
  25. package/dist/components/Overlay/Overlay.d.ts +41 -0
  26. package/dist/components/Overlay/index.d.ts +2 -0
  27. package/dist/components/Popover/Popover.d.ts +91 -0
  28. package/dist/components/Popover/index.d.ts +2 -0
  29. package/dist/components/SegmentedBar/SegmentedBar.d.ts +64 -0
  30. package/dist/components/SegmentedBar/index.d.ts +2 -0
  31. package/dist/components/SpinButton/SpinButton.d.ts +57 -0
  32. package/dist/components/SpinButton/index.d.ts +2 -0
  33. package/dist/index.cjs +1 -1
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.ts +15 -0
  36. package/dist/index.js +2089 -662
  37. package/dist/index.js.map +1 -1
  38. package/package.json +1 -1
@@ -0,0 +1,41 @@
1
+ import { ReactNode } from 'react';
2
+ import { StyleProp, ViewStyle } from 'react-native';
3
+ export interface OverlayProps {
4
+ /** Whether the overlay is visible. */
5
+ open: boolean;
6
+ /** Called when the backdrop itself (not its content) is pressed. */
7
+ onDismiss?: () => void;
8
+ children?: ReactNode;
9
+ style?: StyleProp<ViewStyle>;
10
+ testID?: string;
11
+ }
12
+ /**
13
+ * Standalone backdrop/scrim layer with a fade transition and
14
+ * press-to-dismiss — the shared building block behind `Dialog`,
15
+ * `Dropdown`, `Popover`, and `BottomSheet`'s backdrops, extracted here for
16
+ * building custom overlay UI, mirroring `@gnome-ui/react`'s `Overlay`.
17
+ *
18
+ * Deliberately minimal, same as the web version: no focus trap, no
19
+ * `BackHandler`/Escape handling, no `role`. Use `Dialog`/`Popover`/
20
+ * `BottomSheet` directly when you need those — this is only the fade +
21
+ * dismiss-on-backdrop-tap primitive underneath them.
22
+ *
23
+ * Built on `Modal` rather than the web version's `createPortal` — no
24
+ * `container` prop exists here, since RN's `Modal` has no equivalent
25
+ * mount-target concept (it always renders at the top of the native view
26
+ * hierarchy). Reuses `Dialog`'s exact backdrop recipe: an
27
+ * `AnimatedPressable` backdrop whose `onPress` fires `onDismiss`, wrapping
28
+ * `children` in a no-op `Pressable` so a tap on the content itself never
29
+ * bubbles to the backdrop and dismisses it — the RN analog of the web
30
+ * version's `e.target === e.currentTarget` check, which has no meaning in
31
+ * RN's touch-responder model.
32
+ *
33
+ * **Real, timed exit animation, same technique as `BottomSheet`**: a local
34
+ * `visible` state lags one animation behind the `open` prop, flipping to
35
+ * `false` only in the fade-out `Animated.timing`'s own completion callback
36
+ * — not a `setTimeout` racing a hardcoded duration like the web version,
37
+ * since `Animated`'s callback already fires exactly when the animation
38
+ * actually finishes. `useBodyScrollLock` has no RN equivalent needed —
39
+ * `Modal` already blocks all interaction with whatever's behind it.
40
+ */
41
+ export declare const Overlay: ({ open, onDismiss, children, style, testID }: OverlayProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,2 @@
1
+ export type { OverlayProps } from './Overlay';
2
+ export { Overlay } from './Overlay';
@@ -0,0 +1,91 @@
1
+ import { ReactElement, ReactNode, Ref } from 'react';
2
+ import { PressableProps, StyleProp, ViewStyle, View } from 'react-native';
3
+ export type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';
4
+ export interface PopoverProps {
5
+ /**
6
+ * The rich content rendered inside the popover panel.
7
+ * Can include interactive elements (buttons, links, forms).
8
+ */
9
+ content: ReactNode;
10
+ /**
11
+ * Preferred placement relative to the trigger.
12
+ * Flips automatically when there is not enough viewport space.
13
+ * Defaults to `"bottom"`.
14
+ */
15
+ placement?: PopoverPlacement;
16
+ /**
17
+ * Whether the popover is open (controlled mode).
18
+ * Omit to use uncontrolled mode where the trigger toggles it.
19
+ */
20
+ open?: boolean;
21
+ /** Called when open state should change. */
22
+ onOpenChange?: (open: boolean) => void;
23
+ /** Extra style on the popover panel itself. */
24
+ panelStyle?: StyleProp<ViewStyle>;
25
+ /**
26
+ * The trigger element. Must be a single element built on `Pressable`
27
+ * (e.g. `Button`, `Card`) that forwards its `ref` to the underlying `View`.
28
+ */
29
+ children: ReactElement<PressableProps & {
30
+ ref?: Ref<View>;
31
+ }>;
32
+ }
33
+ /**
34
+ * Floating panel anchored to a trigger element, following the Adwaita
35
+ * `GtkPopover` pattern. Unlike `Tooltip`, a popover can contain rich
36
+ * interactive content (buttons, links, forms).
37
+ *
38
+ * Rebuilt with `View`/`Pressable`/`Modal` rather than ported from
39
+ * `@gnome-ui/react`'s DOM `Portal` + manual focus trap, reusing this
40
+ * package's own established pieces rather than re-deriving them: `Tooltip`'s
41
+ * `cloneElement`-onto-an-arbitrary-trigger architecture and 4-placement
42
+ * fallback-cascade positioning (`computePosition`, same shape, no arrow-
43
+ * offset-shift-when-clamped complexity — same simplification `Tooltip`
44
+ * already accepted), and `Dropdown`'s toggle-on-press + full-screen backdrop
45
+ * `Pressable` that closes on an outside tap (the RN analog of the web
46
+ * version's document-level "click outside" listener) plus reduced-motion
47
+ * fade-in.
48
+ *
49
+ * **Deliberate divergence from `Dropdown`'s backdrop structure**: `Dropdown`
50
+ * nests its panel directly inside the backdrop `Pressable` and gets away
51
+ * with it because almost every pixel of its panel is itself a `Pressable`
52
+ * option row, which claims the touch responder before it can bubble to the
53
+ * backdrop. A popover's `content` is arbitrary — likely to have inert
54
+ * padding/whitespace/text with no `Pressable` of its own — so nesting the
55
+ * same way would let a tap on inert panel space fall through to the
56
+ * backdrop and close the popover, unlike the web version's `.contains()`
57
+ * check (which never closes on *any* tap inside the panel). Fixed with
58
+ * `onStartShouldSetResponder={() => true}` on the panel itself: it claims
59
+ * the touch responder for any touch RN's negotiation hasn't already given to
60
+ * a deeper `Pressable` inside `content`, without making the panel itself
61
+ * behave like a button.
62
+ *
63
+ * `BackHandler`'s `hardwareBackPress` (wired the same way `Dialog` already
64
+ * does) is the Android analog of the web version's document-level Escape
65
+ * listener — there is no keyboard `Escape` to catch on a touch-first device.
66
+ * Focus-trapping and focus-restore-on-close have no port: there is no DOM
67
+ * `document.activeElement`/`querySelector` equivalent in RN, the same gap
68
+ * that already left every other floating component in this package (
69
+ * `Dialog`, `Tooltip`, `Dropdown`) without them.
70
+ *
71
+ * The web version's rotated-square-with-matching-background arrow (relying
72
+ * on same-color blending across a straddled panel edge and CSS stacking
73
+ * order) is replaced with `Tooltip`'s simpler transparent-border-triangle
74
+ * technique — same visual affordance (a pointer toward the trigger), a much
75
+ * simpler RN-native primitive.
76
+ *
77
+ * `role="dialog"` on the panel ports 1:1 from RN's newer web-aligned `Role`
78
+ * union (the same one `Dialog`/`Tooltip` already use) — no substitution
79
+ * needed. `aria-haspopup`/`aria-controls` have no RN equivalent (no
80
+ * cross-platform relationship-attribute prop); only `accessibilityState.
81
+ * expanded` is wired on the trigger, the same subset `Dropdown`'s own
82
+ * trigger already exposes.
83
+ *
84
+ * @example
85
+ * <Popover content={<Text>Rich content here</Text>}>
86
+ * <Button>Open</Button>
87
+ * </Popover>
88
+ *
89
+ * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.Popover.html
90
+ */
91
+ export declare const Popover: ({ content, placement: preferredPlacement, open: controlledOpen, onOpenChange, panelStyle, children, }: PopoverProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { PopoverPlacement, PopoverProps } from './Popover';
2
+ export { Popover } from './Popover';
@@ -0,0 +1,64 @@
1
+ import { StyleProp, ViewStyle } from 'react-native';
2
+ export interface SegmentedBarSegment {
3
+ /** Category name shown in the tooltip. */
4
+ label: string;
5
+ /**
6
+ * Percentage value 0–100.
7
+ * The sum of all segments should equal 100.
8
+ * If it does not, values are redistributed proportionally.
9
+ */
10
+ value: number;
11
+ /**
12
+ * Color for this segment.
13
+ * When omitted, a cycling palette of GNOME design tokens is used.
14
+ */
15
+ color?: string;
16
+ }
17
+ export interface SegmentedBarProps {
18
+ /** Segments to display. Each segment contributes its share of the full bar width. */
19
+ values: SegmentedBarSegment[];
20
+ /**
21
+ * Accessible label for the bar as a whole.
22
+ * Auto-generated from `values` when omitted (e.g. "TypeScript 60%, JavaScript 30%").
23
+ */
24
+ accessibilityLabel?: string;
25
+ style?: StyleProp<ViewStyle>;
26
+ testID?: string;
27
+ }
28
+ /**
29
+ * Horizontal bar split into proportional segments, one per category.
30
+ * Mirrors `@gnome-ui/react`'s `SegmentedBar`. Typical use case: repository
31
+ * language distribution.
32
+ *
33
+ * ```tsx
34
+ * <SegmentedBar
35
+ * values={[
36
+ * { label: 'TypeScript', value: 60, color: '#3178c6' },
37
+ * { label: 'JavaScript', value: 30, color: '#f7df1e' },
38
+ * { label: 'CSS', value: 10, color: '#563d7c' },
39
+ * ]}
40
+ * />
41
+ * ```
42
+ *
43
+ * The web version's hover interaction (dim every segment but the one under
44
+ * the pointer, brighten that one via `filter: brightness()`) is rebuilt for
45
+ * touch rather than dropped: each segment is a `Pressable`, and touching
46
+ * one dims the rest immediately via `onPressIn`/`onPressOut` — deliberately
47
+ * not gated behind `Tooltip`'s own long-press delay, since this feedback is
48
+ * the RN analog of a `Pressable`'s own instant `pressed` state, not the
49
+ * "peek" affordance a tooltip reveal is. Each segment is also wrapped in
50
+ * `Tooltip` (`label`/`placement="top"`/`delay={200}`, ported 1:1 from the
51
+ * web version's own tooltip) for the actual label/percentage readout,
52
+ * composing cleanly with the dim/highlight `onPressIn`/`onPressOut` since
53
+ * `Tooltip` clones its own handlers onto the child *and* still calls the
54
+ * child's original ones. `filter: brightness(1.15)` on the actively-touched
55
+ * segment has no RN equivalent (no `filter` support) — dropped as a
56
+ * decorative nicety, since the touched segment already reads as
57
+ * highlighted by contrast once every other segment dims to 35% opacity.
58
+ *
59
+ * `role="img"` + `accessibilityLabel` ports 1:1 from RN's newer web-aligned
60
+ * `Role` union (the same `Avatar`/`LevelBar` precedent).
61
+ *
62
+ * @see https://developer.gnome.org/hig/patterns/feedback/progress.html
63
+ */
64
+ export declare const SegmentedBar: ({ values, accessibilityLabel, style, testID }: SegmentedBarProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { SegmentedBarProps, SegmentedBarSegment } from './SegmentedBar';
2
+ export { SegmentedBar } from './SegmentedBar';
@@ -0,0 +1,57 @@
1
+ import { StyleProp, ViewStyle } from 'react-native';
2
+ export interface SpinButtonProps {
3
+ /** Current value. */
4
+ value: number;
5
+ /** Called when the value changes. */
6
+ onChange: (value: number) => void;
7
+ /** Minimum allowed value. Defaults to `0`. */
8
+ min?: number;
9
+ /** Maximum allowed value. Defaults to `100`. */
10
+ max?: number;
11
+ /** Amount to increment/decrement per step. Defaults to `1`. */
12
+ step?: number;
13
+ /** Number of decimal places shown. Derived from `step` when omitted. */
14
+ decimals?: number;
15
+ /**
16
+ * Wrap around instead of clamping at the edges — stepping past `max` returns
17
+ * to `min` and vice versa, and the −/+ buttons never disable. Mirrors
18
+ * `GtkSpinButton:wrap`; used for cyclic values like hours and minutes.
19
+ */
20
+ wrap?: boolean;
21
+ /**
22
+ * Custom display formatter for the current value (e.g. zero-padding, or
23
+ * mapping a numeric value to `AM`/`PM`). Defaults to fixed-decimal text. When
24
+ * provided, its result is also exposed as the accessibility value's `text`.
25
+ */
26
+ format?: (value: number) => string;
27
+ /** Disables the control. */
28
+ disabled?: boolean;
29
+ /** Accessible label. Required — RN has no visible-label association to fall back on. */
30
+ accessibilityLabel?: string;
31
+ style?: StyleProp<ViewStyle>;
32
+ }
33
+ /**
34
+ * Numeric input with − and + buttons following the Adwaita `GtkSpinButton` style.
35
+ *
36
+ * Rebuilt with `View`/`Pressable`/`Text` rather than ported from
37
+ * `@gnome-ui/react`'s DOM-based JSX, but mirrors its prop API and clamp/wrap/
38
+ * decimal math (pure JS, ported verbatim).
39
+ *
40
+ * The primary interaction is tapping the visible −/+ buttons, same as a
41
+ * sighted mouse user on the web version. The web version's keyboard
42
+ * interaction (↑/↓ one step, Page Up/Down ten steps, Home/End to bounds) has
43
+ * no RN equivalent — a touch-first device has no keyboard to drive it, the
44
+ * same reasoning `Slider` already applied. Rather than dropping value
45
+ * adjustment accessibility entirely, single-step increment/decrement is
46
+ * wired through `accessibilityRole="adjustable"` + `onAccessibilityAction`
47
+ * (VoiceOver's swipe-up/down, TalkBack's local-context menu), reusing the
48
+ * exact recipe `Slider` already proved works — the bigger Page Up/Down and
49
+ * Home/End jumps have no equivalent screen-reader gesture on either
50
+ * platform, so those alone are dropped, same as `Slider`. The visible
51
+ * buttons are hidden from the accessibility tree (mirrors the web version's
52
+ * `aria-hidden`/`tabIndex={-1}` on both `<button>`s) so a screen reader user
53
+ * gets one adjustable stop, not three.
54
+ *
55
+ * @see https://developer.gnome.org/hig/patterns/controls/spin-buttons.html
56
+ */
57
+ export declare const SpinButton: ({ value, onChange, min, max, step, decimals, wrap, format, disabled, accessibilityLabel, style, }: SpinButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { SpinButtonProps } from './SpinButton';
2
+ export { SpinButton } from './SpinButton';