@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,82 @@
1
+ import { ReactNode } from 'react';
2
+ import { StyleProp, ViewStyle } from 'react-native';
3
+ export interface BottomSheetProps {
4
+ /** Whether the sheet is visible. */
5
+ open: boolean;
6
+ /** Optional heading shown below the drag handle. */
7
+ title?: ReactNode;
8
+ children?: ReactNode;
9
+ /** Called when the user dismisses the sheet (backdrop press, Android back button, or drag down). */
10
+ onClose?: () => void;
11
+ /** Whether pressing the backdrop closes the sheet. Defaults to `true`. */
12
+ closeOnBackdrop?: boolean;
13
+ style?: StyleProp<ViewStyle>;
14
+ /** Applied to the backdrop, mirroring `Dialog`'s own `testID`. */
15
+ testID?: string;
16
+ }
17
+ /**
18
+ * Slide-up panel that overlays content from the bottom edge, mirroring
19
+ * `AdwBottomSheet` (libadwaita 1.6+) and `@gnome-ui/react`'s `BottomSheet`.
20
+ *
21
+ * Rebuilt with `View`/`Modal`/`PanResponder` rather than ported from the web
22
+ * version's DOM `Portal` + manual focus trap + raw pointer events —
23
+ * reusing this package's own established pieces: `Dialog`'s backdrop-
24
+ * opacity-on-an-`AnimatedPressable` + no-op-`Pressable`-around-the-card
25
+ * (so a tap on the card never bubbles to the backdrop) recipe, and
26
+ * `BackHandler`'s `hardwareBackPress` as the Android analog of the web
27
+ * version's Escape listener (same pattern `Dialog`/`Popover` already use).
28
+ * Focus-trapping and focus-restore-on-close have no port — no DOM
29
+ * `document.activeElement`/`querySelector` equivalent exists in RN, the
30
+ * same gap already present in every other floating component here.
31
+ *
32
+ * **Real drag-to-dismiss, not a fixed-panel simplification**: unlike the
33
+ * web version's raw `PointerEvent` handlers directly mutating
34
+ * `style.transform`, this uses `PanResponder` (the same core RN API
35
+ * `Slider` already proved handles a threshold-based drag gesture) driving
36
+ * a single `Animated.Value` — the *same* value used for the slide-in/
37
+ * slide-out entrance animation. `PanResponder`'s `gestureState.dy` is the
38
+ * cumulative vertical delta since the gesture started, so a plain
39
+ * `translateY.setValue(Math.max(0, gestureState.dy))` during
40
+ * `onPanResponderMove` reproduces the web version's own
41
+ * `Math.max(0, e.clientY - dragStartY.current)` clamp exactly, and a
42
+ * release past `DRAG_CLOSE_THRESHOLD` (150 px, same constant as the web
43
+ * version) animates the rest of the way down before calling `onClose`,
44
+ * otherwise it springs back to `0`. The gesture responder is attached only
45
+ * to the handle bar `View`, not the whole sheet, mirroring the web
46
+ * version's `onPointerDown` being scoped to `.handle` alone.
47
+ *
48
+ * **A real slide-up needs the sheet's own height first** — RN's
49
+ * `transform` has no percentage-of-self units (the same `Slider`/`Avatar`
50
+ * pitfall), unlike the web version's `translateY(100%)`. The sheet renders
51
+ * once off-screen (measured via `onLayout`, starting `translateY` at that
52
+ * measured height) before animating to `0` — the same "resolve own
53
+ * rendered size, then animate" two-step every other sized-on-open
54
+ * component in this package (`Dialog`, `Dropdown`, `Popover`) already
55
+ * needs, just for a transform offset instead of a floating position.
56
+ *
57
+ * **Real, timed exit animation, unlike `Dialog`**: `Dialog`'s web source
58
+ * has no exit keyframes at all (`Modal`'s `visible={false}` unmounts
59
+ * immediately, matching the web version's plain `return null`) — but
60
+ * `BottomSheet`'s web source explicitly animates both the backdrop fade
61
+ * and the sheet's slide-out before removing it. Ported with a local
62
+ * `visible` state that lags one animation behind the `open` prop: closing
63
+ * starts the exit `Animated.timing`s and only flips `visible` to `false`
64
+ * (unmounting the `Modal`'s content) in the animation's own completion
65
+ * callback — not a `setTimeout` racing a hardcoded duration like the web
66
+ * version, since `Animated`'s callback already fires exactly when the
67
+ * animation actually finishes.
68
+ *
69
+ * The web version's `backdrop-filter: blur(4px)` has no port — this
70
+ * package has no native blur view dependency, the same reasoning that
71
+ * already dropped `Sidebar`'s blurred `variant`. `useBodyScrollLock` has no
72
+ * RN equivalent needed: `Modal` already blocks all interaction with
73
+ * whatever's behind it, there is no scrollable "body" to lock separately.
74
+ *
75
+ * `role="dialog"` + `accessibilityViewIsModal` port 1:1 from `Dialog`'s own
76
+ * precedent. `children`, when a plain string, must be wrapped in `Text`
77
+ * before rendering — RN throws if a raw string is a `View`'s child, unlike
78
+ * the web version's `<div>{children}</div>`, which needed no such check.
79
+ *
80
+ * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.BottomSheet.html
81
+ */
82
+ export declare const BottomSheet: ({ open, title, children, onClose, closeOnBackdrop, style, testID, }: BottomSheetProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,2 @@
1
+ export type { BottomSheetProps } from './BottomSheet';
2
+ export { BottomSheet } from './BottomSheet';
@@ -0,0 +1,63 @@
1
+ import { IconDefinition } from '@gnome-ui/icons';
2
+ import { StyleProp, ViewStyle } from 'react-native';
3
+ export interface ChipProps {
4
+ /** Text label displayed inside the chip. */
5
+ label: string;
6
+ /** Leading icon from `@gnome-ui/icons`. */
7
+ icon?: IconDefinition;
8
+ /**
9
+ * When provided, renders a remove (×) button and calls this handler.
10
+ * The chip root becomes a plain `View`; only the remove button is
11
+ * interactive.
12
+ */
13
+ onRemove?: () => void;
14
+ /**
15
+ * When true the chip renders as a toggle button.
16
+ * Use `selected` + `onToggle` to control its state.
17
+ */
18
+ selectable?: boolean;
19
+ /** Active/selected state. Only relevant when `selectable` is true. */
20
+ selected?: boolean;
21
+ /**
22
+ * Called when a selectable chip is pressed.
23
+ * Only relevant when `selectable` is true.
24
+ */
25
+ onToggle?: () => void;
26
+ /** Disabled state — applies to both selectable chips and the remove button. */
27
+ disabled?: boolean;
28
+ style?: StyleProp<ViewStyle>;
29
+ testID?: string;
30
+ }
31
+ /**
32
+ * Compact pill-shaped label for tags, filters, and selection states.
33
+ * Mirrors `@gnome-ui/react`'s `Chip`.
34
+ *
35
+ * Three usage modes:
36
+ * - **Static** — just a visual label (no `onRemove`, no `selectable`).
37
+ * - **Removable** — add `onRemove` to show a × button.
38
+ * - **Selectable** — add `selectable` + `selected` + `onToggle` for toggle
39
+ * behavior. Same `isInteractive = selectable && !onRemove` precedence as
40
+ * the web version: passing both `selectable` and `onRemove` renders the
41
+ * remove button, not a toggle.
42
+ *
43
+ * Pair with `WrapBox` for multi-chip layouts.
44
+ *
45
+ * Rebuilt with `Pressable`/`View`/`Text` rather than ported from
46
+ * `@gnome-ui/react`'s `<button>`/`<span>`: the selected background/border
47
+ * tint (`color-mix(in srgb, accent 15%/50%, transparent)`) has no RN
48
+ * equivalent, resolved to a literal 8-digit `#RRGGBBAA` hex instead — the
49
+ * same `Highlight` precedent, since `accentBgColor` is always a plain
50
+ * 6-digit hex. The `:hover`/`:active` background transitions collapse into
51
+ * a single pressed-state overlay tinted by `theme.activeOverlay` (the same
52
+ * `ActionRow`/`Card` recipe), since touch has no hover. The leading icon
53
+ * and remove (×) icon don't recolor to match the selected accent text
54
+ * (`color: inherit` on the web) — RN's `Icon` has no `currentColor`
55
+ * equivalent and only accepts a fixed named-swatch palette, none of which
56
+ * tracks the app's configurable accent color, so both icons stay in the
57
+ * default foreground color; a decorative nicety dropped, not a behavior
58
+ * gap. `accessibilityRole="checkbox"` on the selectable form ports 1:1
59
+ * (the same `Checkbox` precedent).
60
+ *
61
+ * @see https://developer.gnome.org/hig/patterns/selection.html
62
+ */
63
+ export declare const Chip: ({ label, icon, onRemove, selectable, selected, onToggle, disabled, style, testID, }: ChipProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { ChipProps } from './Chip';
2
+ export { Chip } from './Chip';
@@ -0,0 +1,36 @@
1
+ import { ReactNode } from 'react';
2
+ import { StyleProp, ViewStyle } from 'react-native';
3
+ export interface DividerProps {
4
+ /** Optional centered label (e.g. `"OR"`, `"Continue with"`). */
5
+ children?: ReactNode;
6
+ /** Accessible name. Defaults to `children` when it's a string. */
7
+ accessibilityLabel?: string;
8
+ style?: StyleProp<ViewStyle>;
9
+ testID?: string;
10
+ }
11
+ /**
12
+ * Horizontal rule with an optional centered label — common auth/login-form
13
+ * pattern ("Sign in" / **OR** / "Continue with Google"). Mirrors
14
+ * `@gnome-ui/react`'s `Divider`.
15
+ *
16
+ * For a bare dividing line with no label, use `Separator` instead — it also
17
+ * supports a vertical orientation, which `Divider` does not.
18
+ *
19
+ * `role="separator"` ports 1:1 from RN's newer web-aligned `Role` union
20
+ * (the same one `Avatar`/`Badge`/`LevelBar` already reach for), unlike
21
+ * `Separator`'s own choice to render as `accessible={false}` — that
22
+ * component is purely decorative with nothing for a screen reader to
23
+ * announce, while a labelled `Divider` ("OR") is exactly the kind of
24
+ * content a screen reader user needs read aloud, so it stays in the
25
+ * accessibility tree instead. The label reuses `Text`'s `variant="caption"
26
+ * color="dim"` verbatim rather than hand-rolled styles, since that
27
+ * combination already resolves to the same font-size/weight/dim-opacity
28
+ * the web version's `.label` class hard-codes.
29
+ *
30
+ * The web version's `aria-orientation="horizontal"` has no port — `Divider`
31
+ * has no `orientation` prop at all (unlike `Separator`), so there is only
32
+ * ever one orientation to announce.
33
+ *
34
+ * @see https://developer.gnome.org/hig/patterns/containers.html
35
+ */
36
+ export declare const Divider: ({ children, accessibilityLabel, style, testID }: DividerProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { DividerProps } from './Divider';
2
+ export { Divider } from './Divider';
@@ -0,0 +1,117 @@
1
+ import { IconDefinition } from '@gnome-ui/icons';
2
+ import { ReactNode } from 'react';
3
+ import { StyleProp, ViewStyle } from 'react-native';
4
+ export type DrawerSide = 'left' | 'right';
5
+ export type DrawerSize = 'classic' | 'wide';
6
+ export interface DrawerRailItem {
7
+ /** Stable unique identifier. */
8
+ id: string;
9
+ /** Icon shown for this rail entry. */
10
+ icon: IconDefinition;
11
+ /** Accessible name, also used as the tooltip. */
12
+ label: string;
13
+ /** Whether this entry represents the currently visible drawer/panel. */
14
+ active?: boolean;
15
+ disabled?: boolean;
16
+ onPress: () => void;
17
+ }
18
+ export interface DrawerProps {
19
+ /** Whether the drawer is visible. */
20
+ open: boolean;
21
+ /** Edge that the drawer slides in from. Defaults to `"right"`. */
22
+ side?: DrawerSide;
23
+ /** Preset drawer width. Defaults to `"classic"`. */
24
+ size?: DrawerSize;
25
+ /** Optional drawer heading. */
26
+ title?: ReactNode;
27
+ /** Drawer content when a prop is preferred over `children`. */
28
+ content?: ReactNode;
29
+ /** Drawer content. Used when `content` is not provided. */
30
+ children?: ReactNode;
31
+ /** Called when the user dismisses the drawer with the Android back button or the backdrop. */
32
+ onClose?: () => void;
33
+ /** Whether pressing the backdrop closes the drawer. Defaults to `true`. */
34
+ closeOnBackdrop?: boolean;
35
+ /**
36
+ * Narrow icon rail rendered on the drawer's inner edge (the edge facing
37
+ * the backdrop), for switching between related drawers or panels without
38
+ * closing the drawer. Purely presentational — pressing an entry only
39
+ * calls its `onPress`; the caller decides what happens (swap `content`,
40
+ * open a different drawer, etc).
41
+ */
42
+ rail?: DrawerRailItem[];
43
+ style?: StyleProp<ViewStyle>;
44
+ /** Forwarded to the backdrop — useful for testing. */
45
+ testID?: string;
46
+ }
47
+ /**
48
+ * Slide-in panel for supplementary content, anchored to the left or right
49
+ * edge. Mirrors `@gnome-ui/react`'s `Drawer`.
50
+ *
51
+ * Rebuilt with `View`/`Modal` rather than ported from the web version's
52
+ * `createPortal(document.body)` + manual focus trap + Escape listener:
53
+ * `Modal` already floats above everything with no portal target needed,
54
+ * and `BackHandler`'s `hardwareBackPress` is the Android analog of the
55
+ * Escape listener (the same `Dialog`/`BottomSheet` precedent). Focus
56
+ * trapping has no port — no DOM `Tab`/`document.activeElement` concept in
57
+ * RN's touch-first model.
58
+ *
59
+ * **Floats with a margin on every side, all four corners rounded** — the
60
+ * backdrop `Pressable` carries `padding: theme.space3` (matching the
61
+ * `@gnome-ui/react` source's own recent update to the same floating-card
62
+ * look, not a divergence), and the drawer itself gets a uniform
63
+ * `borderRadius` instead of the flat-edge-on-the-anchored-side look a
64
+ * flush-to-the-screen-edge panel would need. Positioning within that
65
+ * padded backdrop uses `justifyContent: 'flex-end'`/`'flex-start'` on the
66
+ * backdrop (not the web CSS's `margin-left/right: auto` on the drawer
67
+ * itself) — confirmed empirically (a throwaway build with saturated debug
68
+ * colors standing in for the real theme colors, screenshotted on-device)
69
+ * that `justifyContent` renders correctly while auto-margins were, at
70
+ * best, unverified for this RN/Yoga version; `BottomSheet` already proves
71
+ * the same `justifyContent: 'flex-end'` mechanism works on this exact
72
+ * setup, just on the vertical axis instead of horizontal. On a phone-width
73
+ * screen the `classic`/`wide` presets (420/640, sized for wider viewports)
74
+ * get capped to fill essentially the entire available width after the
75
+ * margin either way, so the anchored side becomes visually obvious mainly
76
+ * on tablets — the same responsive behavior the web version would show at
77
+ * an equally narrow browser width, not an RN-specific gap.
78
+ *
79
+ * **No drag-to-dismiss, unlike `BottomSheet`**: the web source only
80
+ * defines entrance keyframes for both the backdrop and the panel, so this
81
+ * follows `Dialog`'s simpler shape (a single `progress` `Animated.Value`
82
+ * replayed via `useEffect` keyed on `open`, no separate exit animation or
83
+ * lagging `visible` state) rather than `BottomSheet`'s
84
+ * `PanResponder`-plus-timed-exit machinery.
85
+ *
86
+ * **The slide distance needs no `onLayout` measurement**, unlike
87
+ * `BottomSheet`'s content-driven height: the drawer's width is a value
88
+ * this component already computes in JS (`size`'s preset, scaled down by
89
+ * `DrawerDepthContext` depth, capped by the available space after the
90
+ * backdrop's margin) — RN's `transform` has no percentage-of-self units
91
+ * (the same `BottomSheet`/`Avatar`/`Slider` pitfall), but since the exact
92
+ * pixel width is already known synchronously, `translateX` can animate
93
+ * from that known offset to `0` immediately, with no first-frame
94
+ * imprecision to accept.
95
+ *
96
+ * **`DrawerDepthContext` (nested-drawer width auto-scaling) ports 1:1** —
97
+ * pure React Context state, no DOM dependency at all. A `Drawer` opened
98
+ * from within another drawer's `content`/`children` is detected via
99
+ * context and scales its own preset width down (`0.85^depth`, floored at
100
+ * `DRAWER_MIN_WIDTH`) so stacked drawers read as a drill-in hierarchy
101
+ * instead of identical overlapping panels.
102
+ *
103
+ * **`rail` reuses the newly-added `IconButton`** (itself just `Button` +
104
+ * `Icon` + optional `Tooltip`, the same composition `@gnome-ui/react`'s own
105
+ * `IconButton` already is) — `aria-pressed` becomes
106
+ * `accessibilityState={{ selected: item.active }}`, the closest RN
107
+ * equivalent for a toggleable icon button with no dedicated visual
108
+ * "pressed" style on either platform's source.
109
+ *
110
+ * `backdrop-filter: blur(4px)` has no port — no native blur view
111
+ * dependency exists in this package, the same gap already dropped from
112
+ * `Sidebar`'s blurred `variant`/`BottomSheet`'s backdrop. `role="dialog"` +
113
+ * `accessibilityViewIsModal` port 1:1 from `Dialog`'s own precedent.
114
+ *
115
+ * @see https://developer.gnome.org/hig/patterns/containers.html
116
+ */
117
+ export declare const Drawer: ({ open, side, size, title, content, children, onClose, closeOnBackdrop, rail, style, testID, }: DrawerProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { DrawerProps, DrawerRailItem, DrawerSide, DrawerSize } from './Drawer';
2
+ export { Drawer } from './Drawer';
@@ -0,0 +1,64 @@
1
+ import { ReactNode } from 'react';
2
+ import { StyleProp, ViewStyle } from 'react-native';
3
+ export interface ExpanderProps {
4
+ /** Clickable header label. String children render as a themed `Text` label; other nodes render as-is. */
5
+ label: ReactNode;
6
+ /** Content revealed when expanded. */
7
+ children?: ReactNode;
8
+ /** Controlled expanded state. */
9
+ expanded?: boolean;
10
+ /** Initial expanded state when uncontrolled. Defaults to `false`. */
11
+ defaultExpanded?: boolean;
12
+ /** Called when the expanded state changes. */
13
+ onExpandedChange?: (expanded: boolean) => void;
14
+ /** Disables the toggle. */
15
+ disabled?: boolean;
16
+ style?: StyleProp<ViewStyle>;
17
+ testID?: string;
18
+ }
19
+ /**
20
+ * Standalone disclosure triangle + collapsible content — mirrors
21
+ * `GtkExpander` and `@gnome-ui/react`'s `Expander`.
22
+ *
23
+ * A bare, unstyled counterpart to `ExpanderRow`. Use `Expander` outside a
24
+ * settings-row context, e.g. "Show advanced options" in a form, or "Show
25
+ * details" under an error message.
26
+ *
27
+ * The web version clips the panel with a CSS grid-height animation and
28
+ * rides the content's `padding-top` on a second, separate transition (so a
29
+ * collapsed expander doesn't reserve blank space for padding that belongs
30
+ * to hidden content). RN has no CSS grid to lean on, so the panel is a
31
+ * single `Animated.View` whose numeric `height` is driven directly —
32
+ * `useNativeDriver: false`, the same accepted (and documented) trade-off
33
+ * `Checkbox`/`RadioButton`/`Switch`/`AnimatedIcon` already make for
34
+ * non-transform properties. Because the inner content `View`'s `onLayout`
35
+ * measurement already includes its own `paddingTop`, animating that single
36
+ * height value reproduces the web version's two-transition result with one
37
+ * `Animated.Value` instead of two. Content stays mounted while collapsed
38
+ * (matching the web version's `inert`, unmounted-from-the-tab-order-only
39
+ * behavior) — `accessibilityElementsHidden` / `importantForAccessibility`
40
+ * is RN's closest equivalent, applied to the panel wrapper.
41
+ *
42
+ * On first mount with `defaultExpanded`, the panel briefly renders at its
43
+ * natural (unmeasured) height instead of the animated value, so the initial
44
+ * reveal doesn't start from a wrong, pre-measurement `0` and pop once
45
+ * `onLayout` resolves — the same "let layout report the truth once, then
46
+ * hand control to `Animated`" shape `Dropdown`/`Tooltip` use for their own
47
+ * `onLayout`-measured dimensions.
48
+ *
49
+ * The chevron is `PanEnd` (GNOME's own `pan-end-symbolic` disclosure
50
+ * triangle) rather than a chevron glyph, matching the web version's
51
+ * hand-drawn arrow shape. It rotates 0deg → 90deg on an `Animated.Value`
52
+ * (the same `interpolate`-to-`rotate` recipe `Spinner` uses for its own
53
+ * indeterminate spin), unlike `Dropdown`'s chevron, which snaps instantly
54
+ * since that panel's own reveal has no comparable "settle" affordance.
55
+ *
56
+ * `role="region"` on the panel and `accessibilityState={{ expanded }}` on
57
+ * the header port 1:1 from the web version's `aria-controls`/`aria-expanded`
58
+ * pair — RN has no DOM ids, so the id-based `aria-labelledby`/`aria-controls`
59
+ * relationship itself has no port, the same `ProgressBar`/`LevelBar`
60
+ * precedent for dropping id-relationship-only ARIA props.
61
+ *
62
+ * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.Expander.html
63
+ */
64
+ export declare const Expander: ({ label, children, expanded: controlledExpanded, defaultExpanded, onExpandedChange, disabled, style, testID, }: ExpanderProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export type { ExpanderProps } from './Expander';
2
+ export { Expander } from './Expander';
@@ -0,0 +1,45 @@
1
+ import { StyleProp, ViewStyle } from 'react-native';
2
+ import { IconSize } from '../Icon';
3
+ export interface FileTypeIconProps {
4
+ /** File name (e.g. `"report.pdf"`) — resolves the icon from its extension. */
5
+ name?: string;
6
+ /**
7
+ * MIME type (e.g. `"application/pdf"`, `"inode/directory"`).
8
+ * Takes precedence over `name` when both are provided.
9
+ */
10
+ mimeType?: string;
11
+ /** Renders the folder icon regardless of `name`/`mimeType`. */
12
+ isFolder?: boolean;
13
+ /** Thumbnail image URL. When provided, renders the image instead of the resolved icon. */
14
+ thumbnail?: string;
15
+ /** Accessible label. Defaults to a generated description (e.g. `"PDF document"`). */
16
+ label?: string;
17
+ /** Icon size. Defaults to `"md"`. */
18
+ size?: IconSize;
19
+ style?: StyleProp<ViewStyle>;
20
+ testID?: string;
21
+ }
22
+ /**
23
+ * Small icon — optionally a thumbnail — resolved from a file's MIME type
24
+ * or name extension. Useful for file-manager-style listings. Mirrors
25
+ * `@gnome-ui/react`'s `FileTypeIcon`.
26
+ *
27
+ * Falls back to the generic file icon (mirrors freedesktop's
28
+ * `text-x-generic`) when the type can't be resolved.
29
+ *
30
+ * `fileType.ts`'s category-resolution logic (MIME type / extension → one of
31
+ * 13 categories, plus the freedesktop icon and generated label per
32
+ * category) is pure, DOM-free TS — duplicated verbatim from
33
+ * `@gnome-ui/react` rather than imported cross-package, the same
34
+ * `isIconDefinition`/`Icon.tsx` precedent already established for
35
+ * DOM-independent logic that still isn't worth a shared package for one
36
+ * function's worth of code.
37
+ *
38
+ * `role="img"` + `accessibilityLabel` ports 1:1 (the same `Avatar`/
39
+ * `LevelBar` precedent for RN's newer web-aligned `Role` union). The
40
+ * thumbnail reuses `Avatar`'s own `Image`/`resizeMode="cover"` recipe,
41
+ * sized from `Icon`'s own `ICON_SIZE_MAP` so swapping between the resolved
42
+ * icon and a thumbnail never shifts layout — the same reasoning the web
43
+ * version's `.sm`/`.md`/`.lg` classes document.
44
+ */
45
+ export declare const FileTypeIcon: ({ name, mimeType, isFolder, thumbnail, label, size, style, testID, }: FileTypeIconProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { IconDefinition } from '@gnome-ui/icons';
2
+ export type FileTypeCategory = 'folder' | 'image' | 'audio' | 'video' | 'text' | 'pdf' | 'archive' | 'document' | 'spreadsheet' | 'presentation' | 'font' | 'executable' | 'unknown';
3
+ /** Resolves a file-type category from a MIME type (e.g. `"image/png"`). */
4
+ export declare function categoryFromMimeType(mimeType: string): FileTypeCategory | null;
5
+ /** Resolves a file-type category from a file name's extension (e.g. `"report.pdf"`). */
6
+ export declare function categoryFromName(name: string): FileTypeCategory | null;
7
+ export declare function getFileTypeIcon(category: FileTypeCategory): IconDefinition;
8
+ export declare function getFileTypeLabel(category: FileTypeCategory): string;
@@ -0,0 +1,3 @@
1
+ export type { FileTypeIconProps } from './FileTypeIcon';
2
+ export { FileTypeIcon } from './FileTypeIcon';
3
+ export type { FileTypeCategory } from './fileType';
@@ -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,2 @@
1
+ export type { HighlightProps } from './Highlight';
2
+ export { Highlight } from './Highlight';
@@ -0,0 +1,34 @@
1
+ import { IconDefinition } from '@gnome-ui/icons';
2
+ import { View } from 'react-native';
3
+ import { ButtonProps, ButtonSize, ButtonVariant } from '../Button';
4
+ import { IconSize } from '../Icon';
5
+ import { TooltipPlacement } from '../Tooltip';
6
+ export type IconButtonVariant = ButtonVariant | 'osd';
7
+ export type IconButtonSize = ButtonSize;
8
+ export interface IconButtonProps extends Omit<ButtonProps, 'accessibilityLabel' | 'children' | 'leadingIcon' | 'osd' | 'shape' | 'trailingIcon' | 'variant'> {
9
+ /** Icon definition imported from `@gnome-ui/icons`. */
10
+ icon: IconDefinition;
11
+ /** Accessible name for the icon-only button. */
12
+ label: string;
13
+ /** Visual style of the button. Use `"osd"` for media overlay controls. */
14
+ variant?: IconButtonVariant;
15
+ /** Size of the button. */
16
+ size?: IconButtonSize;
17
+ /** Override the rendered icon size. Defaults to a size matched to `size`. */
18
+ iconSize?: IconSize;
19
+ /** Optional tooltip label shown on long-press/hover/focus. */
20
+ tooltip?: string;
21
+ /** Preferred tooltip placement. */
22
+ tooltipPlacement?: TooltipPlacement;
23
+ /** Tooltip delay in milliseconds. */
24
+ tooltipDelay?: number;
25
+ }
26
+ /**
27
+ * Icon-only action button composed from `Button`, `Icon`, and optionally
28
+ * `Tooltip` — mirrors `@gnome-ui/react`'s `IconButton`, itself already just
29
+ * a thin composition of those same three pieces (its own JSDoc example
30
+ * shows the identical `<Tooltip><Button><Icon /></Button></Tooltip>`
31
+ * nesting `IconButton` here just formalizes into a named, reusable export).
32
+ * `label` is required since the button has no visible text.
33
+ */
34
+ export declare const IconButton: import('react').ForwardRefExoticComponent<IconButtonProps & import('react').RefAttributes<View>>;
@@ -0,0 +1,2 @@
1
+ export type { IconButtonProps, IconButtonSize, IconButtonVariant } from './IconButton';
2
+ export { IconButton } from './IconButton';
@@ -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,2 @@
1
+ export type { LevelBarProps, LevelBarVariant } from './LevelBar';
2
+ export { LevelBar } from './LevelBar';