@gnome-ui/react-native 1.9.0 → 1.11.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 +414 -3
- package/dist/components/CopyButton/CopyButton.d.ts +44 -0
- package/dist/components/CopyButton/index.d.ts +2 -0
- package/dist/components/ScrollToTop/ScrollToTop.d.ts +105 -0
- package/dist/components/ScrollToTop/index.d.ts +2 -0
- package/dist/components/Spacer/Spacer.d.ts +25 -0
- package/dist/components/Spacer/index.d.ts +2 -0
- package/dist/components/SpinRow/SpinRow.d.ts +64 -0
- package/dist/components/SpinRow/index.d.ts +2 -0
- package/dist/components/SplitButton/SplitButton.d.ts +46 -0
- package/dist/components/SplitButton/index.d.ts +2 -0
- package/dist/components/StepIndicator/StepIndicator.d.ts +56 -0
- package/dist/components/StepIndicator/index.d.ts +2 -0
- package/dist/components/SwitchRow/SwitchRow.d.ts +43 -0
- package/dist/components/SwitchRow/index.d.ts +2 -0
- package/dist/components/TagInput/TagInput.d.ts +59 -0
- package/dist/components/TagInput/index.d.ts +2 -0
- package/dist/components/Timeline/Timeline.d.ts +87 -0
- package/dist/components/Timeline/index.d.ts +2 -0
- package/dist/components/Toolbar/Toolbar.d.ts +25 -0
- package/dist/components/Toolbar/index.d.ts +2 -0
- package/dist/components/WidgetManager/WidgetManager.d.ts +92 -0
- package/dist/components/WidgetManager/index.d.ts +2 -0
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.js +1611 -729
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
export interface SpinRowProps {
|
|
4
|
+
/** Primary label. */
|
|
5
|
+
title: string;
|
|
6
|
+
/** Secondary line below the title. */
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
/** Icon or image placed at the leading edge. */
|
|
9
|
+
leading?: ReactNode;
|
|
10
|
+
/** Current value (controlled). */
|
|
11
|
+
value?: number;
|
|
12
|
+
/** Initial value when uncontrolled. Defaults to `0`. */
|
|
13
|
+
defaultValue?: number;
|
|
14
|
+
/** Called when the value changes. */
|
|
15
|
+
onValueChange?: (value: number) => void;
|
|
16
|
+
/** Minimum allowed value. Defaults to `0`. */
|
|
17
|
+
min?: number;
|
|
18
|
+
/** Maximum allowed value. Defaults to `100`. */
|
|
19
|
+
max?: number;
|
|
20
|
+
/** Amount to increment/decrement per step. Defaults to `1`. */
|
|
21
|
+
step?: number;
|
|
22
|
+
/** Number of decimal places shown. Derived from `step` when omitted. */
|
|
23
|
+
decimals?: number;
|
|
24
|
+
/** Accessible name for the spin button. Defaults to `title`. */
|
|
25
|
+
accessibilityLabel?: string;
|
|
26
|
+
/** Disables the row and its spin button. */
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
style?: StyleProp<ViewStyle>;
|
|
29
|
+
testID?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Settings row with an integrated spin button for numeric values, mirroring
|
|
33
|
+
* `AdwSpinRow` and `@gnome-ui/react`'s own `SpinRow`. Use inside a
|
|
34
|
+
* `BoxedList` for settings with numeric ranges (volume, timeout duration,
|
|
35
|
+
* count limits, etc.).
|
|
36
|
+
*
|
|
37
|
+
* **This is a composition of `ActionRow` + `SpinButton`** — same reasoning
|
|
38
|
+
* as `ComboRow` (`ActionRow` + `Dropdown`): the row layout and the numeric
|
|
39
|
+
* stepper are each already shipped, verified components, so nothing here is
|
|
40
|
+
* rebuilt. `SpinButton` is controlled-only, so the uncontrolled `defaultValue`
|
|
41
|
+
* state lives here, one level up, the same shape `ComboRow` already
|
|
42
|
+
* established for `Dropdown`.
|
|
43
|
+
*
|
|
44
|
+
* The web version's keyboard interaction (↑/↓ one step, Page Up/Down ten
|
|
45
|
+
* steps, Home/End to bounds) drops as it does everywhere else in this
|
|
46
|
+
* package — `SpinButton` already provides the touch/screen-reader
|
|
47
|
+
* equivalents it was built with (tap the visible −/+ buttons, or the
|
|
48
|
+
* `accessibilityRole="adjustable"` increment/decrement actions).
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* <BoxedList>
|
|
52
|
+
* <SpinRow
|
|
53
|
+
* title="Volume"
|
|
54
|
+
* subtitle="Output level"
|
|
55
|
+
* value={volume}
|
|
56
|
+
* onValueChange={setVolume}
|
|
57
|
+
* min={0}
|
|
58
|
+
* max={100}
|
|
59
|
+
* />
|
|
60
|
+
* </BoxedList>
|
|
61
|
+
*
|
|
62
|
+
* @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.SpinRow.html
|
|
63
|
+
*/
|
|
64
|
+
export declare const SpinRow: ({ title, subtitle, leading, value: controlledValue, defaultValue, onValueChange, min, max, step, decimals, accessibilityLabel, disabled, style, testID, }: SpinRowProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { GestureResponderEvent, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
export type SplitButtonVariant = 'default' | 'suggested' | 'destructive';
|
|
4
|
+
export interface SplitButtonProps {
|
|
5
|
+
/** Label shown in the primary button. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Visual style. Applies to both the primary and toggle halves. */
|
|
8
|
+
variant?: SplitButtonVariant;
|
|
9
|
+
/** Content rendered inside the popover panel when the arrow is pressed. */
|
|
10
|
+
dropdownContent: ReactNode;
|
|
11
|
+
/** Accessible label for the dropdown toggle button. Defaults to `"More options"`. */
|
|
12
|
+
dropdownLabel?: string;
|
|
13
|
+
/** Called when the primary (label) half is pressed. */
|
|
14
|
+
onPress?: (event: GestureResponderEvent) => void;
|
|
15
|
+
/** Disables both halves. */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
style?: StyleProp<ViewStyle>;
|
|
18
|
+
testID?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Primary action button with an attached dropdown arrow, mirroring
|
|
22
|
+
* `AdwSplitButton` and `@gnome-ui/react`'s own `SplitButton`. Pressing the
|
|
23
|
+
* label half fires `onPress`; pressing the arrow half opens a floating
|
|
24
|
+
* panel with `dropdownContent` (menus, options, etc.).
|
|
25
|
+
*
|
|
26
|
+
* The primary half is a real `Button` — its resting/pressed/disabled colors
|
|
27
|
+
* come for free. The arrow half is a hand-rolled `Pressable` rather than a
|
|
28
|
+
* second `Button`: nesting `Popover` (whose `children` clones a prop-level
|
|
29
|
+
* `accessibilityState`/`onPress` onto its trigger) around a full `Button`
|
|
30
|
+
* would silently clobber `Button`'s own internal `accessibilityState={{
|
|
31
|
+
* disabled }}` — RN merges a spread prop object outright, it doesn't merge
|
|
32
|
+
* key-by-key — so the arrow half derives the exact same variant colors via
|
|
33
|
+
* `getVariantColors` above instead, and owns `accessibilityState` itself
|
|
34
|
+
* (only `{ disabled }`, letting `Popover`'s clone merge in `expanded`).
|
|
35
|
+
* The two halves are visually connected by zeroing the shared inner corner
|
|
36
|
+
* radii and painting a 1px separator between them, the RN equivalent of the
|
|
37
|
+
* web CSS's `border-radius` split + `.separator` span.
|
|
38
|
+
*
|
|
39
|
+
* `Popover` supplies the floating panel, `Modal`-based positioning,
|
|
40
|
+
* outside-tap dismissal, and Android back-button handling — no repositioning
|
|
41
|
+
* math of its own needed here, unlike the web version's manual
|
|
42
|
+
* `getBoundingClientRect`/scroll-and-resize-tracking `place()` effect.
|
|
43
|
+
*
|
|
44
|
+
* @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.SplitButton.html
|
|
45
|
+
*/
|
|
46
|
+
export declare const SplitButton: ({ label, variant, dropdownContent, dropdownLabel, onPress, disabled, style, testID, }: SplitButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
2
|
+
export type StepIndicatorOrientation = 'horizontal' | 'vertical';
|
|
3
|
+
export interface StepIndicatorProps {
|
|
4
|
+
/**
|
|
5
|
+
* Total number of steps, or an array of per-step labels rendered beside
|
|
6
|
+
* (vertical) or beneath (horizontal) each circle. Pass a plain number for
|
|
7
|
+
* an unlabelled sequence (only the "Step X of Y" caption is shown); pass
|
|
8
|
+
* an array of strings to label each step.
|
|
9
|
+
*/
|
|
10
|
+
steps: number | string[];
|
|
11
|
+
/** Zero-based index of the current/active step. */
|
|
12
|
+
currentStep: number;
|
|
13
|
+
/** Layout direction. Default: `"horizontal"`. */
|
|
14
|
+
orientation?: StepIndicatorOrientation;
|
|
15
|
+
/**
|
|
16
|
+
* Called when a completed step's circle is pressed, letting the user jump
|
|
17
|
+
* back to a step they've already finished. Omit to make steps
|
|
18
|
+
* non-interactive. The current and upcoming steps are never pressable.
|
|
19
|
+
*/
|
|
20
|
+
onStepClick?: (index: number) => void;
|
|
21
|
+
/** Accessible label for the indicator. Default: `"Progress"`. */
|
|
22
|
+
label?: string;
|
|
23
|
+
style?: StyleProp<ViewStyle>;
|
|
24
|
+
testID?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Numbered "Step X of Y" progress indicator for onboarding/wizard flows —
|
|
28
|
+
* mirrors `@gnome-ui/react`'s `StepIndicator`. Directly portable per this
|
|
29
|
+
* package's own ROADMAP note: no web-only APIs are involved, just derived
|
|
30
|
+
* dot/number state from `currentStep`.
|
|
31
|
+
*
|
|
32
|
+
* The outer container sets `role="navigation"` **without** `accessible` —
|
|
33
|
+
* the corrected pattern `ToggleGroup` established over the earlier
|
|
34
|
+
* `BoxedList`/`ViewSwitcher` precedent: `accessible` on a *grouping*
|
|
35
|
+
* container with multiple independently-focusable children (each step
|
|
36
|
+
* circle here) collapses the whole subtree into one VoiceOver stop on iOS.
|
|
37
|
+
* The role still groups on Android, and every step stays individually
|
|
38
|
+
* reachable; assert `element.props.role` on a `testID` in tests instead of
|
|
39
|
+
* `getByRole('navigation')`.
|
|
40
|
+
*
|
|
41
|
+
* The connecting line between circles reuses the exact CSS trick verbatim
|
|
42
|
+
* (`position: absolute; left: 50%; width: 100%` inside each equal-width
|
|
43
|
+
* flex item, so the line runs from one circle's center to the next's) —
|
|
44
|
+
* `left`/`width` percentages are supported for RN position/dimension
|
|
45
|
+
* props, unlike the `transform: translateX('50%')` trick this package has
|
|
46
|
+
* hit real bugs with elsewhere (that limitation is specific to `transform`).
|
|
47
|
+
*
|
|
48
|
+
* The web version's checkmark/number content swap and connector-line color
|
|
49
|
+
* change have no CSS `transition` at all (only `.circle`'s own
|
|
50
|
+
* `background-color`/`border-color` do), so only those two colors animate
|
|
51
|
+
* here — the content swap and connector recolor are instant, matching the
|
|
52
|
+
* source exactly rather than adding an unrequested fade.
|
|
53
|
+
*
|
|
54
|
+
* @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StepIndicator.html
|
|
55
|
+
*/
|
|
56
|
+
export declare const StepIndicator: ({ steps, currentStep, orientation, onStepClick, label, style, testID, }: StepIndicatorProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { PressableProps, StyleProp, View, ViewStyle } from 'react-native';
|
|
3
|
+
export interface SwitchRowProps extends Omit<PressableProps, 'children' | 'style' | 'onPress'> {
|
|
4
|
+
/** Primary label. */
|
|
5
|
+
title: string;
|
|
6
|
+
/** Secondary line below the title. */
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
/** Icon or image placed at the leading edge. */
|
|
9
|
+
leading?: ReactNode;
|
|
10
|
+
/** Controlled checked state. */
|
|
11
|
+
checked?: boolean;
|
|
12
|
+
/** Initial checked state when uncontrolled. Defaults to `false`. */
|
|
13
|
+
defaultChecked?: boolean;
|
|
14
|
+
/** Called with the next value when the row is pressed. */
|
|
15
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
16
|
+
style?: StyleProp<ViewStyle>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Activatable row with an integrated switch, mirroring `@gnome-ui/react`'s
|
|
20
|
+
* `SwitchRow`. The entire row is a single pressable — pressing anywhere
|
|
21
|
+
* toggles the switch, which is why this isn't `ActionRow` + a trailing
|
|
22
|
+
* `Switch` (the ROADMAP's own guess): `AdwSwitchRow` makes the whole row the
|
|
23
|
+
* interactive element, the same shape `CheckRow` already established for
|
|
24
|
+
* its checkbox. Prefer this over `CheckRow` for a single on/off setting,
|
|
25
|
+
* and `CheckRow` for selecting/deselecting individual items in a list.
|
|
26
|
+
*
|
|
27
|
+
* The switch visual reuses `Switch`'s exact track/thumb `Animated.Value`
|
|
28
|
+
* interpolation, but as plain non-interactive `Animated.View`s rather than
|
|
29
|
+
* importing the real `Switch` component — `Switch` is itself a `Pressable`,
|
|
30
|
+
* and nesting one touchable inside another (the row's own `Pressable`)
|
|
31
|
+
* would create two overlapping tap targets, the same reasoning `CheckRow`
|
|
32
|
+
* already applied to `Checkbox`. `aria-labelledby` (pointing the web
|
|
33
|
+
* button's `role="switch"` at the title/subtitle content) has no RN
|
|
34
|
+
* equivalent — `accessibilityLabel` combining title and subtitle is the
|
|
35
|
+
* substitution, same as `CheckRow`.
|
|
36
|
+
*
|
|
37
|
+
* Supports both controlled (`checked`) and uncontrolled (`defaultChecked`)
|
|
38
|
+
* modes, the same `isControlled`/internal-state-fallback shape already
|
|
39
|
+
* established by `Expander`/`ComboRow`/`Popover`/`CheckRow`.
|
|
40
|
+
*
|
|
41
|
+
* @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.SwitchRow.html
|
|
42
|
+
*/
|
|
43
|
+
export declare const SwitchRow: import('react').ForwardRefExoticComponent<SwitchRowProps & import('react').RefAttributes<View>>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
2
|
+
export interface TagInputProps {
|
|
3
|
+
/** Current list of tags. */
|
|
4
|
+
value: string[];
|
|
5
|
+
/** Called when a tag is added or removed. */
|
|
6
|
+
onChange: (value: string[]) => void;
|
|
7
|
+
/** Visible label rendered above the input. */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Placeholder shown in the draft input while empty. */
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
/** Helper text rendered below the input. Hidden when `error` is set. */
|
|
12
|
+
helperText?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Error message rendered below the input in place of `helperText`.
|
|
15
|
+
* Also applies the error visual state to the border.
|
|
16
|
+
*/
|
|
17
|
+
error?: string;
|
|
18
|
+
/** Maximum number of tags allowed. Once reached, the draft input is hidden. */
|
|
19
|
+
maxTags?: number;
|
|
20
|
+
/** Reject a new tag that already exists (case-insensitive). Defaults to `true`. */
|
|
21
|
+
preventDuplicates?: boolean;
|
|
22
|
+
/** Disables the whole control. */
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
style?: StyleProp<ViewStyle>;
|
|
25
|
+
testID?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Type-to-add multi-value input rendering entries as removable `Chip`s in a
|
|
29
|
+
* `WrapBox`, mirroring `@gnome-ui/react`'s own `TagInput`.
|
|
30
|
+
*
|
|
31
|
+
* `WrapBox`/`Chip` alone only support static, pre-populated display —
|
|
32
|
+
* `TagInput` adds interactive entry: type and press Return, or type a `,`,
|
|
33
|
+
* to commit a tag; paste a comma/newline-separated list to add several at
|
|
34
|
+
* once; Backspace on an empty draft removes the last one.
|
|
35
|
+
*
|
|
36
|
+
* The web version wires typed-`,` and pasted-list handling as two separate
|
|
37
|
+
* handlers (`onKeyDown`'s `,` case, `onPaste`). RN's `TextInput` has no
|
|
38
|
+
* `paste` event to mirror — but a paste still flows through `onChangeText`
|
|
39
|
+
* with the full resulting text, exactly like a typed `,` does, so both
|
|
40
|
+
* collapse into one `handleChangeText`: whenever the text contains a `,` or
|
|
41
|
+
* newline, split on it and commit every non-empty part (typing "foo,"
|
|
42
|
+
* commits "foo" via the same path a paste of "foo,bar" commits both).
|
|
43
|
+
* Return is handled separately via `onSubmitEditing`, since RN has no
|
|
44
|
+
* `Enter` keystroke to catch on a single-line field the way the web version
|
|
45
|
+
* catches it in `onKeyDown`. Backspace-on-empty uses `onKeyPress`, the one
|
|
46
|
+
* RN `TextInput` event that still fires with the field already empty
|
|
47
|
+
* (`onChangeText` doesn't fire deleting from nothing).
|
|
48
|
+
*
|
|
49
|
+
* The tag box is a `Pressable` (mirrors the web version's
|
|
50
|
+
* `onClick={() => inputRef.current?.focus()}` on the container) with
|
|
51
|
+
* `accessible={false}` explicitly — `Pressable` defaults `accessible` to
|
|
52
|
+
* `true`, which would collapse every `Chip`'s remove button and the draft
|
|
53
|
+
* input into a single VoiceOver stop, the same container-swallows-subtree
|
|
54
|
+
* trap already documented for `ToggleGroup`/`Sidebar`'s bare-`View`-plus-role
|
|
55
|
+
* case, here hit via `Pressable`'s own default instead.
|
|
56
|
+
*
|
|
57
|
+
* @see https://developer.gnome.org/hig/patterns/controls/text-fields.html
|
|
58
|
+
*/
|
|
59
|
+
export declare const TagInput: ({ value, onChange, label, placeholder, helperText, error, maxTags, preventDuplicates, disabled, style, testID, }: TagInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
export type TimelineOrientation = 'vertical' | 'horizontal';
|
|
4
|
+
export type TimelineVariant = 'default' | 'dotted' | 'none';
|
|
5
|
+
export interface TimelineItem {
|
|
6
|
+
/** Icon rendered inside the timeline node. Sized/colored by the consumer — see the component doc. */
|
|
7
|
+
icon?: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Content at the leading edge of the node.
|
|
10
|
+
* - **Vertical:** rendered to the left of the connector track.
|
|
11
|
+
* - **Horizontal:** rendered above the node.
|
|
12
|
+
*
|
|
13
|
+
* Typical use: timestamp, badge, short label.
|
|
14
|
+
*/
|
|
15
|
+
leading?: ReactNode;
|
|
16
|
+
/** Main event content rendered adjacent to the node (title, description…). */
|
|
17
|
+
content: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export interface TimelineProps {
|
|
20
|
+
/** Ordered list of timeline events. */
|
|
21
|
+
items: TimelineItem[];
|
|
22
|
+
/**
|
|
23
|
+
* Axis direction of the connector line.
|
|
24
|
+
* - `"vertical"` — events stack top-to-bottom (default).
|
|
25
|
+
* - `"horizontal"` — events flow left-to-right, in a horizontal `ScrollView`.
|
|
26
|
+
*/
|
|
27
|
+
orientation?: TimelineOrientation;
|
|
28
|
+
/**
|
|
29
|
+
* Visual style of the connector between nodes.
|
|
30
|
+
* - `"default"` — solid thin line.
|
|
31
|
+
* - `"dotted"` — dotted line; useful for future or pending events.
|
|
32
|
+
* - `"none"` — no connector; each node stands alone.
|
|
33
|
+
*/
|
|
34
|
+
variant?: TimelineVariant;
|
|
35
|
+
style?: StyleProp<ViewStyle>;
|
|
36
|
+
testID?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Ordered sequence of events connected by a visual timeline — mirrors
|
|
40
|
+
* `@gnome-ui/react`'s `Timeline`. An original composition (no direct
|
|
41
|
+
* libadwaita widget), following GNOME HIG activity-feed/stepper patterns.
|
|
42
|
+
*
|
|
43
|
+
* The web version aligns every item's `leading` column (vertical) or row
|
|
44
|
+
* (horizontal) via CSS subgrid, so timestamps/labels line up across items
|
|
45
|
+
* regardless of how wide/tall any single one of them is. RN/Yoga has no
|
|
46
|
+
* grid or subgrid at all, so that alignment is reproduced by measurement
|
|
47
|
+
* instead — the same `onLayout` + `Record<index, size>` +
|
|
48
|
+
* "largest-so-far wins" technique `Slider`'s mark labels already
|
|
49
|
+
* established: every item's `leading` cell (always rendered, even when
|
|
50
|
+
* empty, matching the web version's own "same 3 children" comment)
|
|
51
|
+
* reports its own rendered width (vertical) or height (horizontal), and
|
|
52
|
+
* every cell gets a `minWidth`/`minHeight` equal to the largest one
|
|
53
|
+
* measured so far, so the node column/row starts at the same position in
|
|
54
|
+
* every item. The node track itself additionally gets a *fixed*
|
|
55
|
+
* width (vertical, matching the source CSS's literal `24px` column) or
|
|
56
|
+
* height (horizontal, the larger of the dot/icon node sizes, since the
|
|
57
|
+
* source's row there is CSS `auto` with no fixed value to port) — without
|
|
58
|
+
* it, an item with an icon node (28 dp) and one with a plain dot (12 dp)
|
|
59
|
+
* would each size their own track differently, misaligning `content`'s
|
|
60
|
+
* start position between them.
|
|
61
|
+
*
|
|
62
|
+
* `orientation="horizontal"` wraps itself in a horizontal `ScrollView`,
|
|
63
|
+
* reimagining the web CSS's `overflow-x: auto` — the direct native
|
|
64
|
+
* equivalent for "scroll instead of overflow when items don't fit". The
|
|
65
|
+
* web version's `grid-auto-columns: minmax(72px, 1fr)` also grows items
|
|
66
|
+
* to fill leftover space when the row *doesn't* overflow; that half
|
|
67
|
+
* doesn't port (a `ScrollView`'s content isn't bounded the way a CSS grid
|
|
68
|
+
* track is, so there's no "leftover space" to distribute) — each item
|
|
69
|
+
* just gets a flat 72 dp `minWidth` instead, unconditionally scrollable
|
|
70
|
+
* like `overflow-x: auto`'s own fallback path.
|
|
71
|
+
*
|
|
72
|
+
* `icon`/`leading`/`content` are plain `ReactNode`, the same as
|
|
73
|
+
* `PathBar`'s segment `icon` — the consumer sizes and colors their own
|
|
74
|
+
* icon (e.g. `tintColor={theme.accentFgColor}` on their own `<Icon>`),
|
|
75
|
+
* since RN has no `currentColor` for this component to tint an arbitrary
|
|
76
|
+
* child with the way the web version's CSS `color: accent-fg-color`
|
|
77
|
+
* does via inheritance onto the icon's SVG.
|
|
78
|
+
*
|
|
79
|
+
* `role="list"`/`role="listitem"` are set **without** `accessible` — the
|
|
80
|
+
* `ToggleGroup`/`StepIndicator`-established pattern for a grouping role
|
|
81
|
+
* over children that may themselves contain focusable content (an
|
|
82
|
+
* item's `content` is arbitrary `ReactNode` and could include one), so
|
|
83
|
+
* nothing nested inside gets swallowed into a single VoiceOver stop.
|
|
84
|
+
* Assert `element.props.role` on a `testID` in tests instead of
|
|
85
|
+
* `getByRole('list'/'listitem')`.
|
|
86
|
+
*/
|
|
87
|
+
export declare const Timeline: ({ items, orientation, variant, style, testID, }: TimelineProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { StyleProp, View, ViewProps, ViewStyle } from 'react-native';
|
|
2
|
+
export interface ToolbarProps extends Omit<ViewProps, 'style'> {
|
|
3
|
+
style?: StyleProp<ViewStyle>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Horizontal action bar following the libadwaita `.toolbar` pattern —
|
|
7
|
+
* mirrors `@gnome-ui/react`'s `Toolbar`. Directly portable: no web-only
|
|
8
|
+
* APIs, just a flex row with fixed padding/gap.
|
|
9
|
+
*
|
|
10
|
+
* Provides `theme.space1` (6 dp) padding and gap — the standard spacing
|
|
11
|
+
* for rows of flat buttons in header bars, action bars, and tool rows.
|
|
12
|
+
* Place a `Spacer` between leading and trailing groups to push trailing
|
|
13
|
+
* items to the end. Use `Button variant="flat"` for buttons that blend
|
|
14
|
+
* into the bar, or `variant="raised"` for one that needs explicit
|
|
15
|
+
* elevation within a flat context.
|
|
16
|
+
*
|
|
17
|
+
* The web CSS's `color`/`font-family` on `.toolbar` are dropped — RN has
|
|
18
|
+
* no style inheritance from a parent `View` down to child `Text`
|
|
19
|
+
* elements the way CSS `color` cascades, so a value here would reach
|
|
20
|
+
* nothing (every child, e.g. `Button`, already sets its own explicit
|
|
21
|
+
* text/icon colors).
|
|
22
|
+
*
|
|
23
|
+
* @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1-latest/style-classes.html#toolbar-style-class
|
|
24
|
+
*/
|
|
25
|
+
export declare const Toolbar: import('react').ForwardRefExoticComponent<ToolbarProps & import('react').RefAttributes<View>>;
|
|
@@ -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;
|