@gnome-ui/react-native 1.3.0 → 1.4.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/README.md +324 -4
- package/dist/components/Avatar/Avatar.d.ts +53 -0
- package/dist/components/Avatar/index.d.ts +2 -0
- package/dist/components/Badge/Badge.d.ts +48 -0
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/BottomSheet/BottomSheet.d.ts +82 -0
- package/dist/components/BottomSheet/index.d.ts +2 -0
- package/dist/components/Divider/Divider.d.ts +36 -0
- package/dist/components/Divider/index.d.ts +2 -0
- package/dist/components/Expander/Expander.d.ts +64 -0
- package/dist/components/Expander/index.d.ts +2 -0
- package/dist/components/Highlight/Highlight.d.ts +42 -0
- package/dist/components/Highlight/index.d.ts +2 -0
- package/dist/components/LevelBar/LevelBar.d.ts +72 -0
- package/dist/components/LevelBar/index.d.ts +2 -0
- package/dist/components/Overlay/Overlay.d.ts +41 -0
- package/dist/components/Overlay/index.d.ts +2 -0
- package/dist/components/Popover/Popover.d.ts +91 -0
- package/dist/components/Popover/index.d.ts +2 -0
- package/dist/components/SpinButton/SpinButton.d.ts +57 -0
- package/dist/components/SpinButton/index.d.ts +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +1395 -444
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { TextProps } from '../Text';
|
|
2
|
+
export interface HighlightProps extends Omit<TextProps, 'children'> {
|
|
3
|
+
/** Full text to render. */
|
|
4
|
+
text: string;
|
|
5
|
+
/**
|
|
6
|
+
* Term or terms to highlight within `text`. Pass an array to highlight
|
|
7
|
+
* multiple distinct terms at once (e.g. each word of a multi-word search
|
|
8
|
+
* query). Empty or whitespace-only terms are ignored.
|
|
9
|
+
*/
|
|
10
|
+
query: string | string[];
|
|
11
|
+
/** Match case-sensitively. Defaults to `false`. */
|
|
12
|
+
caseSensitive?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Wraps every occurrence of `query` within `text` in a highlighted inline
|
|
16
|
+
* run — mirrors `@gnome-ui/react`'s `Highlight`, which wraps matches in a
|
|
17
|
+
* `<mark>`. Pairs with `SearchBar`'s suggestion list and any filterable
|
|
18
|
+
* list to show users which part of a result matched what they typed.
|
|
19
|
+
*
|
|
20
|
+
* The outer span is the themed `Text` component (so callers get the same
|
|
21
|
+
* `variant`/`color` API as everywhere else), but each matched run is a
|
|
22
|
+
* plain, unthemed RN `Text` carrying only the highlight's own overrides —
|
|
23
|
+
* RN's `Text` is the one primitive that inherits ambient `fontSize`/
|
|
24
|
+
* `color`/`fontFamily` from a parent `Text` when nested, the same way the
|
|
25
|
+
* web version's `<mark>` inherits from its surrounding text and only
|
|
26
|
+
* overrides `background-color`/`font-weight`. Reaching for the themed
|
|
27
|
+
* `Text` for the marked runs too would reset them to its own default
|
|
28
|
+
* `variant="body"` sizing instead of inheriting whatever variant the
|
|
29
|
+
* caller chose for the whole string.
|
|
30
|
+
*
|
|
31
|
+
* The web version's translucent `color-mix(in srgb, accent 30%,
|
|
32
|
+
* transparent)` background has no RN equivalent (`color-mix` is CSS-only)
|
|
33
|
+
* — resolved to a literal 8-digit `#RRGGBBAA` hex instead, since
|
|
34
|
+
* `accentBgColor` is always a plain 6-digit hex across all four theme
|
|
35
|
+
* variants. `border-radius` on the `<mark>` has no reliable port either:
|
|
36
|
+
* RN only paints `backgroundColor` on an inline (nested) `Text` run, not
|
|
37
|
+
* `borderRadius` — a decorative nicety dropped here, not a behavior gap.
|
|
38
|
+
* `prefers-contrast: more`'s solid-background/white-text swap ports via
|
|
39
|
+
* `useResolvedContrast()`, the same hook `Button` already uses for its own
|
|
40
|
+
* high-contrast branching.
|
|
41
|
+
*/
|
|
42
|
+
export declare const Highlight: ({ text, query, caseSensitive, ...textProps }: HighlightProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
2
|
+
export type LevelBarVariant = 'accent' | 'success' | 'warning' | 'error';
|
|
3
|
+
export interface LevelBarProps {
|
|
4
|
+
/** Current value, between `min` and `max`. */
|
|
5
|
+
value: number;
|
|
6
|
+
/** Minimum value. Defaults to `0`. */
|
|
7
|
+
min?: number;
|
|
8
|
+
/** Maximum value. Defaults to `1`. */
|
|
9
|
+
max?: number;
|
|
10
|
+
/** Threshold at or below which the bar renders in `lowVariant`. */
|
|
11
|
+
low?: number;
|
|
12
|
+
/** Color used when `value <= low`. Defaults to `"warning"`. */
|
|
13
|
+
lowVariant?: LevelBarVariant;
|
|
14
|
+
/** Threshold at or above which the bar renders in `highVariant`. */
|
|
15
|
+
high?: number;
|
|
16
|
+
/** Color used when `value >= high`. Defaults to `"error"`. */
|
|
17
|
+
highVariant?: LevelBarVariant;
|
|
18
|
+
/** Color used between `low` and `high`. Defaults to `"accent"`. */
|
|
19
|
+
variant?: LevelBarVariant;
|
|
20
|
+
/**
|
|
21
|
+
* Render as a row of discrete blocks instead of a continuous fill —
|
|
22
|
+
* mirrors `GtkLevelBar`'s discrete mode (e.g. signal-strength indicators).
|
|
23
|
+
*/
|
|
24
|
+
discrete?: boolean;
|
|
25
|
+
/** Number of blocks when `discrete` is true. Defaults to `10`. */
|
|
26
|
+
numBlocks?: number;
|
|
27
|
+
/** Accessible label describing what the level represents. */
|
|
28
|
+
accessibilityLabel?: string;
|
|
29
|
+
style?: StyleProp<ViewStyle>;
|
|
30
|
+
testID?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Discrete level indicator with color-coded low/high offset zones —
|
|
34
|
+
* mirrors `GtkLevelBar` and `@gnome-ui/react`'s `LevelBar`. Use for a
|
|
35
|
+
* gauge/measurement display (disk usage, battery, signal strength), not
|
|
36
|
+
* for task progress (see `ProgressBar`) or a proportional category
|
|
37
|
+
* breakdown (see `SegmentedBar`).
|
|
38
|
+
*
|
|
39
|
+
* The continuous fill reuses `ProgressBar`'s exact animation technique
|
|
40
|
+
* rather than animating `width` directly: a fixed `width: '100%'` fill
|
|
41
|
+
* with `transformOrigin: 'left'` and an animated `transform: [{ scaleX }]`,
|
|
42
|
+
* so the whole thing runs on `useNativeDriver: true` — a JS-driven
|
|
43
|
+
* (`useNativeDriver: false`) `width` animation schedules its next frame via
|
|
44
|
+
* a plain `setTimeout` that routinely fires after a test's `render()`
|
|
45
|
+
* returns but before unmount, producing a real "update not wrapped in
|
|
46
|
+
* act()" warning, the same reasoning `ProgressBar`'s own docstring
|
|
47
|
+
* documents. `useReducedMotion()` mirrors `ProgressBar`'s determinate
|
|
48
|
+
* behavior: the transition duration drops to `0` (an immediate jump)
|
|
49
|
+
* rather than the animation being skipped in some other way.
|
|
50
|
+
*
|
|
51
|
+
* Discrete mode's per-block `background-color` transition has no port —
|
|
52
|
+
* unlike the continuous fill's width change, a value change in discrete
|
|
53
|
+
* mode is a binary color swap per block with no established `Animated`
|
|
54
|
+
* color-interpolation precedent elsewhere in this package, so it's a
|
|
55
|
+
* plain, unanimated style swap; a decorative nicety, not a behavior gap.
|
|
56
|
+
* Discrete blocks are hidden from the accessibility tree
|
|
57
|
+
* (`accessibilityElementsHidden`/`importantForAccessibility="no"`,
|
|
58
|
+
* mirroring the web version's `aria-hidden`) since the meter's value is
|
|
59
|
+
* already exposed once via `accessibilityValue` on the container.
|
|
60
|
+
*
|
|
61
|
+
* `role="meter"` ports 1:1 from RN's newer web-aligned `Role` union (unlike
|
|
62
|
+
* `AccessibilityRole`, which has no `"meter"` value at all) — the same
|
|
63
|
+
* precedent `Dialog`/`Avatar`/`Badge` already established for reaching for
|
|
64
|
+
* `role` over `accessibilityRole` when only the newer union has the value
|
|
65
|
+
* needed. Web's `aria-labelledby` (an id-relationship prop) has no RN
|
|
66
|
+
* equivalent — RN has no DOM ids — so only `aria-label`
|
|
67
|
+
* (`accessibilityLabel`) is ported, the same `ProgressBar`/`Slider`
|
|
68
|
+
* precedent.
|
|
69
|
+
*
|
|
70
|
+
* @see https://developer.gnome.org/hig/patterns/feedback/progress.html
|
|
71
|
+
*/
|
|
72
|
+
export declare const LevelBar: ({ value, min, max, low, lowVariant, high, highVariant, variant, discrete, numBlocks, accessibilityLabel, style, testID, }: LevelBarProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -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,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,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;
|