@gnome-ui/react-native 1.7.0 → 1.8.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 +326 -3
- package/dist/components/Blockquote/Blockquote.d.ts +40 -0
- package/dist/components/Blockquote/index.d.ts +2 -0
- package/dist/components/BottomTabBar/BottomTabBar.d.ts +106 -0
- package/dist/components/BottomTabBar/index.d.ts +2 -0
- package/dist/components/ButtonRow/ButtonRow.d.ts +41 -0
- package/dist/components/ButtonRow/index.d.ts +2 -0
- package/dist/components/Callout/Callout.d.ts +36 -0
- package/dist/components/Callout/index.d.ts +2 -0
- package/dist/components/CheckRow/CheckRow.d.ts +47 -0
- package/dist/components/CheckRow/index.d.ts +2 -0
- package/dist/components/ExpanderRow/ExpanderRow.d.ts +58 -0
- package/dist/components/ExpanderRow/index.d.ts +2 -0
- package/dist/components/FieldGroup/FieldGroup.d.ts +52 -0
- package/dist/components/FieldGroup/index.d.ts +2 -0
- package/dist/components/FilterableMultiSelectDropdown/FilterableMultiSelectDropdown.d.ts +46 -0
- package/dist/components/FilterableMultiSelectDropdown/index.d.ts +2 -0
- package/dist/components/Icon/Icon.d.ts +11 -1
- package/dist/components/MultiSelectDropdown/MultiSelectDropdown.d.ts +55 -0
- package/dist/components/MultiSelectDropdown/index.d.ts +2 -0
- package/dist/components/PasswordField/PasswordField.d.ts +48 -0
- package/dist/components/PasswordField/index.d.ts +2 -0
- package/dist/components/RangeSlider/RangeSlider.d.ts +73 -0
- package/dist/components/RangeSlider/index.d.ts +2 -0
- package/dist/components/StatusBadge/StatusBadge.d.ts +47 -0
- package/dist/components/StatusBadge/index.d.ts +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.js +1884 -526
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,9 +26,18 @@ React Native component library following the [GNOME Human Interface Guidelines](
|
|
|
26
26
|
> `Clamp` (Tier 6), `Box` (Tier 20), `WrapBox`/`ToggleGroup` (Tier 7), and
|
|
27
27
|
> `InlineViewSwitcher` (Tier 8), `PreferencesGroup` (Tier 13), and
|
|
28
28
|
> `EntryRow`/`PasswordEntryRow`/`ComboRow` (Tier 12), `ColorPicker`
|
|
29
|
-
> (Tier 20),
|
|
30
|
-
>
|
|
31
|
-
>
|
|
29
|
+
> (Tier 20), `Bin` (Tier 15), `Blockquote` (Tier 20), `ButtonRow`
|
|
30
|
+
> (Tier 8), `Callout` (Tier 20), `CheckRow` (Tier 12), `ExpanderRow`
|
|
31
|
+
> (Tier 8), `FieldGroup` (Tier 20), and `MultiSelectDropdown` (Tier 20)
|
|
32
|
+
> also shipped, along with `FilterableMultiSelectDropdown` — an original
|
|
33
|
+
> `@gnome-ui/react`-only component (not a GNOME HIG port) built once its
|
|
34
|
+
> prerequisite `MultiSelectDropdown` landed — and `PasswordField`/
|
|
35
|
+
> `RangeSlider`/`StatusBadge` (all Tier 20). `BottomTabBar` also shipped —
|
|
36
|
+
> a React Native-only original with no `@gnome-ui/react` source at all
|
|
37
|
+
> (desktop apps don't have a bottom tab bar pattern to mirror), built on
|
|
38
|
+
> explicit request for the iOS/Android fixed bottom-navigation shape.
|
|
39
|
+
> Component ports from `@gnome-ui/react` continue tier by tier — see this
|
|
40
|
+
> package's own [ROADMAP.md](./ROADMAP.md) for full
|
|
32
41
|
> per-tier status against all 130 `@gnome-ui/react` components, and the
|
|
33
42
|
> main [ROADMAP.md](../../ROADMAP.md) Priority 3 for the framework
|
|
34
43
|
> expansion this package belongs to.
|
|
@@ -2074,6 +2083,320 @@ already has no default visual styling — no background, no border — so
|
|
|
2074
2083
|
unlike the web port there's no CSS reset to strip; this is a pure
|
|
2075
2084
|
passthrough.
|
|
2076
2085
|
|
|
2086
|
+
### Blockquote
|
|
2087
|
+
|
|
2088
|
+
```tsx
|
|
2089
|
+
import { Blockquote } from '@gnome-ui/react-native';
|
|
2090
|
+
|
|
2091
|
+
<Blockquote variant="info" cite="Ada Lovelace, 1842">
|
|
2092
|
+
The Analytical Engine has no pretensions to originate anything.
|
|
2093
|
+
</Blockquote>
|
|
2094
|
+
```
|
|
2095
|
+
|
|
2096
|
+
Pull-quote with a colored left border, mirroring `@gnome-ui/react`'s
|
|
2097
|
+
`Blockquote`. Five visual variants (`default`/`info`/`warning`/`error`/
|
|
2098
|
+
`success`) share the same severity scale as `Banner`/`Chip`, with an
|
|
2099
|
+
optional leading `icon` and a `cite` attribution line rendered below the
|
|
2100
|
+
quote. The web version's `color-mix(in srgb, <color> 8%/14%, transparent)`
|
|
2101
|
+
tinted backgrounds have no RN equivalent — resolved as an 8-digit
|
|
2102
|
+
`#RRGGBBAA` alpha suffix on the variant's own hex token instead, the same
|
|
2103
|
+
substitution `Chip`'s selected-state tint already established. `<blockquote>`/
|
|
2104
|
+
`<footer>`/`<cite>` have no RN element equivalent, so this renders as a
|
|
2105
|
+
plain `View` with no semantic role.
|
|
2106
|
+
|
|
2107
|
+
### ButtonRow
|
|
2108
|
+
|
|
2109
|
+
```tsx
|
|
2110
|
+
import { BoxedList, ButtonRow } from '@gnome-ui/react-native';
|
|
2111
|
+
|
|
2112
|
+
<BoxedList>
|
|
2113
|
+
<ButtonRow title="Save changes" variant="suggested" onPress={handleSave} />
|
|
2114
|
+
<ButtonRow title="Delete account" variant="destructive" onPress={handleDelete} />
|
|
2115
|
+
</BoxedList>
|
|
2116
|
+
```
|
|
2117
|
+
|
|
2118
|
+
Full-width activatable row styled as a button, for use inside a `BoxedList`
|
|
2119
|
+
— mirrors `AdwButtonRow` and `@gnome-ui/react`'s own `ButtonRow`. Use when
|
|
2120
|
+
an entire list row should trigger a single action with a centered label;
|
|
2121
|
+
prefer `ActionRow` with `interactive` when the row also needs a
|
|
2122
|
+
title/subtitle layout. Rebuilt with `Pressable` rather than ported from the
|
|
2123
|
+
web `<button>` — the same pressed-state-overlay recipe `ActionRow`/`Card`
|
|
2124
|
+
already established (`theme.activeOverlay` stands in for the web's
|
|
2125
|
+
`:hover`/`:active` background transition). The title's color reuses `Text`'s
|
|
2126
|
+
own `TextColor` union (`"accent"`/`"destructive"` resolve to the exact same
|
|
2127
|
+
tokens the source CSS's `suggested`/`destructive` variants reference), and
|
|
2128
|
+
gets `flex: 1` + `textAlign: 'center'` — ported straight from the source
|
|
2129
|
+
CSS's `.title` — so the label stays centered even when only one of
|
|
2130
|
+
`leading`/`trailing` is present. The variant color does not propagate to
|
|
2131
|
+
`leading`/`trailing` icons (no `currentColor` equivalent in RN), the same
|
|
2132
|
+
dropped nicety `Chip` already accepted for its own icons.
|
|
2133
|
+
|
|
2134
|
+
### Callout
|
|
2135
|
+
|
|
2136
|
+
```tsx
|
|
2137
|
+
import { Callout } from '@gnome-ui/react-native';
|
|
2138
|
+
|
|
2139
|
+
<Callout variant="tip" dismissible onDismiss={() => setVisible(false)}>
|
|
2140
|
+
Press and hold a row to reveal more actions.
|
|
2141
|
+
</Callout>
|
|
2142
|
+
```
|
|
2143
|
+
|
|
2144
|
+
Inline, dismissible admonition box for contextual help text within forms
|
|
2145
|
+
and cards — mirrors `@gnome-ui/react`'s `Callout`. Unlike `Banner` (a
|
|
2146
|
+
persistent, edge-to-edge strip at the top of a view) and `Toast` (a
|
|
2147
|
+
temporary notification), `Callout` is a contained, tinted box meant to sit
|
|
2148
|
+
inline alongside the content it annotates. Three variants (`info`/
|
|
2149
|
+
`warning`/`tip`) each pair a tinted background/border with a leading icon;
|
|
2150
|
+
`Icon`'s fixed named palette (`blue`/`yellow`/`green`) stands in for the
|
|
2151
|
+
web's arbitrary `color-mix()` icon tint — `blue3`/`green4` happen to match
|
|
2152
|
+
`accentBgColor`/`successBgColor` exactly in every theme this package
|
|
2153
|
+
ships, so it's not an approximation for `info`/`tip`. `role="note"` ports
|
|
2154
|
+
1:1 from RN's web-aligned `Role` union (same as `Dialog`/`Tooltip`).
|
|
2155
|
+
|
|
2156
|
+
### CheckRow
|
|
2157
|
+
|
|
2158
|
+
```tsx
|
|
2159
|
+
import { BoxedList, CheckRow } from '@gnome-ui/react-native';
|
|
2160
|
+
|
|
2161
|
+
<BoxedList>
|
|
2162
|
+
<CheckRow
|
|
2163
|
+
title="Wi-Fi"
|
|
2164
|
+
subtitle="Home Network"
|
|
2165
|
+
checked={wifi}
|
|
2166
|
+
onCheckedChange={setWifi}
|
|
2167
|
+
/>
|
|
2168
|
+
</BoxedList>
|
|
2169
|
+
```
|
|
2170
|
+
|
|
2171
|
+
Activatable row with an integrated checkbox, for use inside a `BoxedList`
|
|
2172
|
+
— mirrors `@gnome-ui/react`'s `CheckRow`. The entire row is a single
|
|
2173
|
+
pressable; pressing anywhere toggles the checked state. Use for multi-select
|
|
2174
|
+
scenarios; prefer a single `Switch` row for a standalone on/off setting.
|
|
2175
|
+
Supports both controlled (`checked`) and uncontrolled (`defaultChecked`)
|
|
2176
|
+
modes, the same `isControlled`/internal-state-fallback shape already used
|
|
2177
|
+
by `Expander`/`ComboRow`/`Popover`. The checkbox visual reuses `Checkbox`'s
|
|
2178
|
+
exact border/background animation and checkmark-fade-in recipe, but as a
|
|
2179
|
+
plain non-interactive `View` rather than the real `Checkbox` component —
|
|
2180
|
+
nesting one `Pressable` inside another would create two overlapping tap
|
|
2181
|
+
targets. `aria-labelledby` has no RN equivalent, so `accessibilityLabel`
|
|
2182
|
+
combines the title and subtitle instead.
|
|
2183
|
+
|
|
2184
|
+
### ExpanderRow
|
|
2185
|
+
|
|
2186
|
+
```tsx
|
|
2187
|
+
import { ActionRow, BoxedList, ExpanderRow } from '@gnome-ui/react-native';
|
|
2188
|
+
|
|
2189
|
+
<BoxedList>
|
|
2190
|
+
<ExpanderRow title="Advanced" subtitle="Proxy, DNS, and MTU settings">
|
|
2191
|
+
<ActionRow title="Proxy" subtitle="Automatic" />
|
|
2192
|
+
<ActionRow title="DNS" subtitle="Automatic" />
|
|
2193
|
+
</ExpanderRow>
|
|
2194
|
+
</BoxedList>
|
|
2195
|
+
```
|
|
2196
|
+
|
|
2197
|
+
Collapsible `ActionRow` that reveals nested rows on activation — mirrors
|
|
2198
|
+
`@gnome-ui/react`'s `ExpanderRow`. The header row toggles a smooth reveal
|
|
2199
|
+
animation exposing child rows; supports both controlled (`expanded`) and
|
|
2200
|
+
uncontrolled (`defaultExpanded`) modes. The reveal panel reuses the
|
|
2201
|
+
standalone `Expander`'s exact `Animated.View` height-driven recipe almost
|
|
2202
|
+
verbatim — only the chevron differs, using `PanDown` (rotating 0deg →
|
|
2203
|
+
180deg, matching the source CSS's straight down-arrow) instead of
|
|
2204
|
+
`Expander`'s own `PanEnd` triangle. Nested children get a real `Separator`
|
|
2205
|
+
inserted before each one automatically. Use `trailing` for a value label
|
|
2206
|
+
or a `Switch`; stop event propagation inside interactive trailing widgets
|
|
2207
|
+
so the row's own toggle isn't triggered. Unlike `CheckRow`/`ButtonRow`,
|
|
2208
|
+
there is no `disabled` prop — the source component doesn't expose one.
|
|
2209
|
+
|
|
2210
|
+
### FieldGroup
|
|
2211
|
+
|
|
2212
|
+
```tsx
|
|
2213
|
+
import { FieldGroup, RadioButton } from '@gnome-ui/react-native';
|
|
2214
|
+
|
|
2215
|
+
<FieldGroup label="Notification method" helperText="Choose how you want to be notified.">
|
|
2216
|
+
<LabeledRadio label="Email" selected={method === 'email'} onSelect={() => setMethod('email')} />
|
|
2217
|
+
<LabeledRadio label="SMS" selected={method === 'sms'} onSelect={() => setMethod('sms')} />
|
|
2218
|
+
</FieldGroup>
|
|
2219
|
+
```
|
|
2220
|
+
|
|
2221
|
+
Generic form-field grouping with a shared label, help text, and error
|
|
2222
|
+
message, for arbitrary fields outside a `BoxedList` — mirrors
|
|
2223
|
+
`@gnome-ui/react`'s `FieldGroup`. `PreferencesGroup` is scoped specifically
|
|
2224
|
+
to wrapping settings rows inside a `BoxedList`; use `FieldGroup` for a
|
|
2225
|
+
plain labeled grouping around any set of related form controls (e.g. a
|
|
2226
|
+
`RadioButton` group or several `Checkbox`es sharing one label and error),
|
|
2227
|
+
independent of the settings-page layout. `<fieldset>`/`<legend>` have no
|
|
2228
|
+
RN element equivalent — this renders as a `View` with `role="group"` and a
|
|
2229
|
+
themed `Text` label. The hint/error text reuses `TextField`'s exact
|
|
2230
|
+
`error ?? helperText` recipe. Unlike the web version's native
|
|
2231
|
+
`<fieldset disabled>`, `disabled` here only dims the group visually — RN
|
|
2232
|
+
has no equivalent of a fieldset automatically disabling every descendant
|
|
2233
|
+
control, so each child still needs disabling individually.
|
|
2234
|
+
|
|
2235
|
+
### MultiSelectDropdown
|
|
2236
|
+
|
|
2237
|
+
```tsx
|
|
2238
|
+
import { MultiSelectDropdown } from '@gnome-ui/react-native';
|
|
2239
|
+
|
|
2240
|
+
<MultiSelectDropdown
|
|
2241
|
+
options={[
|
|
2242
|
+
{ value: 'wifi', label: 'Wi-Fi' },
|
|
2243
|
+
{ value: 'bluetooth', label: 'Bluetooth' },
|
|
2244
|
+
]}
|
|
2245
|
+
value={permissions}
|
|
2246
|
+
onChange={setPermissions}
|
|
2247
|
+
placeholder="Select permissions"
|
|
2248
|
+
/>
|
|
2249
|
+
```
|
|
2250
|
+
|
|
2251
|
+
Checkbox-list variant of `Dropdown` for selecting multiple values from a
|
|
2252
|
+
single trigger — mirrors `@gnome-ui/react`'s `MultiSelectDropdown`. Use it
|
|
2253
|
+
over `Dropdown`/`ComboRow` (single-select only) whenever more than one
|
|
2254
|
+
value can be chosen at once. Toggling an option keeps the panel open, so
|
|
2255
|
+
the user can pick several in a row; close it via a backdrop tap. Reuses
|
|
2256
|
+
`Dropdown`'s `Modal` + backdrop + independently-measured trigger-rect/
|
|
2257
|
+
panel-height positioning almost verbatim, and gives each option row a
|
|
2258
|
+
leading checkbox-square visual instead of `Dropdown`'s single trailing
|
|
2259
|
+
checkmark.
|
|
2260
|
+
|
|
2261
|
+
### FilterableMultiSelectDropdown
|
|
2262
|
+
|
|
2263
|
+
```tsx
|
|
2264
|
+
import { FilterableMultiSelectDropdown } from '@gnome-ui/react-native';
|
|
2265
|
+
|
|
2266
|
+
<FilterableMultiSelectDropdown
|
|
2267
|
+
options={languages}
|
|
2268
|
+
value={selected}
|
|
2269
|
+
onChange={setSelected}
|
|
2270
|
+
filterPlaceholder="Search languages…"
|
|
2271
|
+
/>
|
|
2272
|
+
```
|
|
2273
|
+
|
|
2274
|
+
`MultiSelectDropdown` plus a filter field for narrowing long option lists
|
|
2275
|
+
— mirrors `@gnome-ui/react`'s `FilterableMultiSelectDropdown`, an original
|
|
2276
|
+
component specific to that package (not a GNOME HIG port). Opening the
|
|
2277
|
+
panel auto-focuses a filter `TextInput` pinned above the list; typing
|
|
2278
|
+
narrows the options to those whose label or description contains the
|
|
2279
|
+
query (case-insensitive) — filtering only affects what's shown, values
|
|
2280
|
+
selected before a query hides their option stay selected. An empty
|
|
2281
|
+
filtered result shows a centered "No results" message. The web version's
|
|
2282
|
+
filter-field keyboard navigation (↑/↓ roving highlight, Home/End,
|
|
2283
|
+
Enter-to-toggle) has no RN port, the same "no keyboard focus to drive it"
|
|
2284
|
+
reasoning `Dropdown` already established — the `TextInput` and its
|
|
2285
|
+
software keyboard still work natively, only the roving-highlight layer on
|
|
2286
|
+
top is dropped.
|
|
2287
|
+
|
|
2288
|
+
### PasswordField
|
|
2289
|
+
|
|
2290
|
+
```tsx
|
|
2291
|
+
import { PasswordField } from '@gnome-ui/react-native';
|
|
2292
|
+
|
|
2293
|
+
<PasswordField
|
|
2294
|
+
label="Password"
|
|
2295
|
+
value={password}
|
|
2296
|
+
onChangeText={setPassword}
|
|
2297
|
+
helperText="At least 8 characters"
|
|
2298
|
+
autoComplete="new-password"
|
|
2299
|
+
/>
|
|
2300
|
+
```
|
|
2301
|
+
|
|
2302
|
+
Single-line password input with a peek toggle to reveal the value as plain
|
|
2303
|
+
text — mirrors `@gnome-ui/react`'s `PasswordField`. `TextField` plus the
|
|
2304
|
+
exact `secureTextEntry`/`IconButton` reveal recipe `PasswordEntryRow`
|
|
2305
|
+
already established, at `size="sm"` (28 dp circular), positioned
|
|
2306
|
+
absolutely at the input's trailing edge and vertically centered — the
|
|
2307
|
+
input gets extra trailing padding so typed text never runs under the
|
|
2308
|
+
button. Use this over `TextField` with a manually-set `secureTextEntry`
|
|
2309
|
+
(which has no reveal affordance). Pass `revealable={false}` to hide the
|
|
2310
|
+
toggle entirely (e.g. for a PIN field).
|
|
2311
|
+
|
|
2312
|
+
### RangeSlider
|
|
2313
|
+
|
|
2314
|
+
```tsx
|
|
2315
|
+
import { RangeSlider } from '@gnome-ui/react-native';
|
|
2316
|
+
|
|
2317
|
+
<RangeSlider
|
|
2318
|
+
value={priceRange}
|
|
2319
|
+
onChange={setPriceRange}
|
|
2320
|
+
minLabel="Minimum price"
|
|
2321
|
+
maxLabel="Maximum price"
|
|
2322
|
+
/>
|
|
2323
|
+
```
|
|
2324
|
+
|
|
2325
|
+
Dual-thumb slider for selecting a min/max range — mirrors
|
|
2326
|
+
`@gnome-ui/react`'s `RangeSlider`. Distinct from `Slider` (a single value)
|
|
2327
|
+
— use this for range filters (price, date range, age, etc.) where both
|
|
2328
|
+
bounds are adjustable. Reuses `Slider`'s exact `PanResponder`/`locationX`
|
|
2329
|
+
pixel-positioning technique: a single responder spans the whole track and,
|
|
2330
|
+
on touch-down, picks whichever thumb is nearer — that thumb then stays
|
|
2331
|
+
locked to the gesture for the rest of the drag, even if the touch drifts
|
|
2332
|
+
closer to the other thumb. Touching anywhere on the track immediately
|
|
2333
|
+
jumps the nearest thumb there, so there's no separate "drag the track"
|
|
2334
|
+
affordance to port. `minDistance` keeps the two thumbs from crossing or
|
|
2335
|
+
overlapping. The web's keyboard navigation has no RN port — replaced by
|
|
2336
|
+
two independent `accessibilityRole="adjustable"` elements (one per thumb),
|
|
2337
|
+
the same VoiceOver/TalkBack increment/decrement analog `Slider` already
|
|
2338
|
+
established.
|
|
2339
|
+
|
|
2340
|
+
### StatusBadge
|
|
2341
|
+
|
|
2342
|
+
```tsx
|
|
2343
|
+
import { StatusBadge } from '@gnome-ui/react-native';
|
|
2344
|
+
|
|
2345
|
+
<StatusBadge variant="success">published</StatusBadge>
|
|
2346
|
+
<StatusBadge variant="warning">beta</StatusBadge>
|
|
2347
|
+
<StatusBadge variant="new">new</StatusBadge>
|
|
2348
|
+
```
|
|
2349
|
+
|
|
2350
|
+
Pill-shaped text label for entity status — published, beta, new, etc. —
|
|
2351
|
+
mirrors `@gnome-ui/react`'s `StatusBadge`. Unlike `Badge` (numeric counts,
|
|
2352
|
+
optional anchor/dot mode), this is a simpler sibling designed purely for
|
|
2353
|
+
short human-readable state labels: no anchor positioning, no dot mode, no
|
|
2354
|
+
counter. Six variants (`success`/`warning`/`error`/`new`/`accent`/
|
|
2355
|
+
`neutral`) reuse `Badge`'s exact color-mapping shape, plus a `new` (purple)
|
|
2356
|
+
variant `Badge` doesn't have.
|
|
2357
|
+
|
|
2358
|
+
### BottomTabBar
|
|
2359
|
+
|
|
2360
|
+
```tsx
|
|
2361
|
+
import { BottomTabBar } from '@gnome-ui/react-native';
|
|
2362
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
2363
|
+
|
|
2364
|
+
const insets = useSafeAreaInsets();
|
|
2365
|
+
|
|
2366
|
+
<BottomTabBar
|
|
2367
|
+
items={[
|
|
2368
|
+
{ value: 'home', label: 'Home', icon: HomeOutline, activeIcon: HomeFilled },
|
|
2369
|
+
{ value: 'search', label: 'Search', icon: Search },
|
|
2370
|
+
{ value: 'profile', label: 'Profile', icon: Person, badge: true },
|
|
2371
|
+
]}
|
|
2372
|
+
value={tab}
|
|
2373
|
+
onChange={setTab}
|
|
2374
|
+
bottomInset={insets.bottom}
|
|
2375
|
+
/>
|
|
2376
|
+
```
|
|
2377
|
+
|
|
2378
|
+
Fixed bottom navigation bar — the iOS/Android "tab bar" pattern (Music,
|
|
2379
|
+
Instagram, most system apps): a small, fixed set of top-level
|
|
2380
|
+
destinations, each an icon + label, always visible at the foot of the
|
|
2381
|
+
screen. No GNOME/libadwaita widget mirrors this, so it's an original
|
|
2382
|
+
component for this package, not a port.
|
|
2383
|
+
|
|
2384
|
+
Distinct from the existing `TabBar`/`TabItem` (an in-page, horizontally
|
|
2385
|
+
scrollable content switcher) — that one signals "active" purely via a
|
|
2386
|
+
background pill + bold weight + accent underline, never by tinting the
|
|
2387
|
+
icon/label themselves. A bottom tab bar's whole visual signature is the
|
|
2388
|
+
opposite: the active icon+label *are* the app's accent color, so this is
|
|
2389
|
+
the first consumer of `Icon`'s new `tintColor` prop (an arbitrary-fill
|
|
2390
|
+
override, since `color="blue"` always means a fixed swatch, never
|
|
2391
|
+
whatever accent the app actually configured via `GnomeProvider
|
|
2392
|
+
accentColor`). Pass `activeIcon` for the filled-vs-outline convention iOS/
|
|
2393
|
+
Android system tab bars both use; omit it to reuse `icon` for both states,
|
|
2394
|
+
tinted differently. `badge` reuses the real `Badge` component's `anchor`
|
|
2395
|
+
mode — `true` for a dot, a number for a count (capped at `"99+"`).
|
|
2396
|
+
`bottomInset` lets you thread in your own `useSafeAreaInsets().bottom` —
|
|
2397
|
+
this package takes no dependency on `react-native-safe-area-context`
|
|
2398
|
+
itself.
|
|
2399
|
+
|
|
2077
2400
|
## Installation
|
|
2078
2401
|
|
|
2079
2402
|
```bash
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { StyleProp, ViewProps, ViewStyle } from 'react-native';
|
|
3
|
+
export type BlockquoteVariant = 'default' | 'info' | 'warning' | 'error' | 'success';
|
|
4
|
+
export interface BlockquoteProps extends Omit<ViewProps, 'style'> {
|
|
5
|
+
/**
|
|
6
|
+
* Visual emphasis style.
|
|
7
|
+
* - `"default"` (default) — neutral left border; use for general quotations.
|
|
8
|
+
* - `"info"` — accent blue; use for tips and noteworthy passages.
|
|
9
|
+
* - `"warning"` — yellow; use for cautionary content.
|
|
10
|
+
* - `"error"` — red; use for critical or deprecated content.
|
|
11
|
+
* - `"success"` — green; use for positive or approved content.
|
|
12
|
+
*/
|
|
13
|
+
variant?: BlockquoteVariant;
|
|
14
|
+
/** Optional icon rendered to the left of the quoted text, e.g. an `<Icon>`. */
|
|
15
|
+
icon?: ReactNode;
|
|
16
|
+
/** Attribution rendered below the quote — author name, source title, etc. */
|
|
17
|
+
cite?: ReactNode;
|
|
18
|
+
/** The quoted content. */
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
style?: StyleProp<ViewStyle>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Styled pull-quote with a colored left border, mirroring `@gnome-ui/react`'s
|
|
24
|
+
* `Blockquote`. Five visual variants share the same severity scale as
|
|
25
|
+
* `Banner`/`Chip`.
|
|
26
|
+
*
|
|
27
|
+
* `<blockquote>`/`<footer>`/`<cite>` have no RN element equivalent — this
|
|
28
|
+
* renders as a plain `View` with no semantic role, the same "no landmark
|
|
29
|
+
* role available" gap `PathBar`'s dropped `<nav>` and `HeaderBar`'s dropped
|
|
30
|
+
* `<header>` already established; the quoted text and citation are plain
|
|
31
|
+
* `Text` reads with no assistive-tech grouping to port.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* <Blockquote variant="info" cite="Ada Lovelace, 1842">
|
|
35
|
+
* The Analytical Engine has no pretensions to originate anything.
|
|
36
|
+
* </Blockquote>
|
|
37
|
+
*
|
|
38
|
+
* @see https://developer.gnome.org/hig/
|
|
39
|
+
*/
|
|
40
|
+
export declare const Blockquote: ({ variant, icon, cite, children, style, ...viewProps }: BlockquoteProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { AnyIconDefinition } from '@gnome-ui/icons';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
export interface BottomTabBarItem<V extends string = string> {
|
|
4
|
+
/** The value reported to `onChange` when this tab is pressed. */
|
|
5
|
+
value: V;
|
|
6
|
+
/** Label shown below the icon. */
|
|
7
|
+
label: string;
|
|
8
|
+
/** Icon shown while this tab is not the selected one. */
|
|
9
|
+
icon: AnyIconDefinition;
|
|
10
|
+
/**
|
|
11
|
+
* Icon shown while this tab *is* selected — the filled-vs-outline
|
|
12
|
+
* convention iOS/Android system tab bars both use (e.g. a hollow heart
|
|
13
|
+
* outline that becomes solid when active). Optional: omit to reuse
|
|
14
|
+
* `icon` for both states, tinted differently.
|
|
15
|
+
*/
|
|
16
|
+
activeIcon?: AnyIconDefinition;
|
|
17
|
+
/**
|
|
18
|
+
* Notification indicator. `true` renders a small dot (unread/pending,
|
|
19
|
+
* no count); a `number` renders a counted badge (values above 99 render
|
|
20
|
+
* as `"99+"`, matching `TabItem`'s own count-badge convention).
|
|
21
|
+
*/
|
|
22
|
+
badge?: number | boolean;
|
|
23
|
+
/** Disables this one tab. */
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface BottomTabBarProps<V extends string = string> {
|
|
27
|
+
/** The tabs to render, in order. */
|
|
28
|
+
items: BottomTabBarItem<V>[];
|
|
29
|
+
/** The currently selected tab's value. */
|
|
30
|
+
value: V;
|
|
31
|
+
/** Called when the user presses a tab. */
|
|
32
|
+
onChange: (value: V) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Extra bottom padding, in addition to the bar's own vertical padding —
|
|
35
|
+
* pass your own `useSafeAreaInsets().bottom` here so the bar clears the
|
|
36
|
+
* home indicator / gesture area on notched devices. This package takes
|
|
37
|
+
* no dependency on `react-native-safe-area-context` itself (the same
|
|
38
|
+
* "no new peer dependency without a deliberate decision" standard
|
|
39
|
+
* `AnimatedIcon`'s `react-native-svg` addition was held to) — the
|
|
40
|
+
* consumer's own app almost certainly already has it for its root
|
|
41
|
+
* layout, so threading the value in here is cheaper than this package
|
|
42
|
+
* depending on it too. Defaults to `0`.
|
|
43
|
+
*/
|
|
44
|
+
bottomInset?: number;
|
|
45
|
+
style?: StyleProp<ViewStyle>;
|
|
46
|
+
testID?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Fixed bottom navigation bar — the iOS/Android "tab bar" pattern (Music,
|
|
50
|
+
* Instagram, most system apps): a small, fixed set of top-level
|
|
51
|
+
* destinations, each an icon + label, always visible at the foot of the
|
|
52
|
+
* screen. No GNOME/libadwaita widget mirrors this (desktop apps don't use
|
|
53
|
+
* bottom navigation), so this is an original component for this package,
|
|
54
|
+
* not a port — built to fill a real gap once mobile "modern app shell"
|
|
55
|
+
* navigation was requested.
|
|
56
|
+
*
|
|
57
|
+
* Distinct from the existing `TabBar`/`TabItem` (an in-page, horizontally
|
|
58
|
+
* scrollable content switcher mirroring `@gnome-ui/react`'s `Tabs`) — that
|
|
59
|
+
* one reuses `headerbarFgColor` for every tab's label regardless of
|
|
60
|
+
* selection state, signaling "active" purely via a background pill +
|
|
61
|
+
* bold weight + accent underline, never by tinting the icon/label
|
|
62
|
+
* themselves. A bottom tab bar's whole visual signature is the opposite:
|
|
63
|
+
* the active icon+label *are* the app's accent color. `Icon`'s `color`
|
|
64
|
+
* prop can't express that on its own — it only resolves to a fixed
|
|
65
|
+
* named-palette swatch (`color="blue"` always means `theme.blue3`, never
|
|
66
|
+
* whatever accent the app actually configured via `GnomeProvider
|
|
67
|
+
* accentColor`) — so this is the first consumer of `Icon`'s new
|
|
68
|
+
* `tintColor` prop, passing `theme.accentColor` directly for the selected
|
|
69
|
+
* tab and leaving it unset (dimmed default) for the rest.
|
|
70
|
+
*
|
|
71
|
+
* The optional notification indicator reuses the real `Badge` component
|
|
72
|
+
* for the dot/pill itself, but positions it manually rather than through
|
|
73
|
+
* `Badge`'s own `anchor` mode — `anchor` wraps `[anchor, badge]` in a
|
|
74
|
+
* `View` with a hardcoded `alignSelf: 'flex-start'`, which is fine for
|
|
75
|
+
* `Badge`'s usual context (a row where the anchor is meant to hug the
|
|
76
|
+
* start) but silently broke centering here: a bare icon (no badge) is a
|
|
77
|
+
* direct child of this component's centered column, while a badged icon's
|
|
78
|
+
* extra `anchor`-mode wrapper overrode that centering and pinned itself to
|
|
79
|
+
* the left edge — the two looked visibly misaligned side by side. Every
|
|
80
|
+
* tab now gets the identical `position: 'relative'` wrapper shape
|
|
81
|
+
* regardless of whether it has a badge, so centering behaves identically
|
|
82
|
+
* across all of them; the badge itself is a plain (non-`anchor`) `Badge`,
|
|
83
|
+
* absolutely positioned and re-sized for this icon's actual scale (`size="lg"`
|
|
84
|
+
* is only 20px — `Badge`'s own default dot/offset sizing assumes a much
|
|
85
|
+
* larger anchor like an avatar or `IconButton`, and would otherwise nearly
|
|
86
|
+
* cover the icon rather than sit as a small corner accent). Press feedback
|
|
87
|
+
* is the same `pressed ? theme.activeOverlay : 'transparent'` recipe every
|
|
88
|
+
* other `Pressable` in this package already uses.
|
|
89
|
+
*
|
|
90
|
+
* `bottomInset` stands in for real safe-area awareness without this
|
|
91
|
+
* package taking on `react-native-safe-area-context` as a dependency —
|
|
92
|
+
* see its own doc comment.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* <BottomTabBar
|
|
96
|
+
* items={[
|
|
97
|
+
* { value: 'home', label: 'Home', icon: HomeOutline, activeIcon: HomeFilled },
|
|
98
|
+
* { value: 'search', label: 'Search', icon: Search },
|
|
99
|
+
* { value: 'profile', label: 'Profile', icon: Person, badge: true },
|
|
100
|
+
* ]}
|
|
101
|
+
* value={tab}
|
|
102
|
+
* onChange={setTab}
|
|
103
|
+
* bottomInset={insets.bottom}
|
|
104
|
+
* />
|
|
105
|
+
*/
|
|
106
|
+
export declare const BottomTabBar: <V extends string = string>({ items, value, onChange, bottomInset, style, testID, }: BottomTabBarProps<V>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { PressableProps, StyleProp, View, ViewStyle } from 'react-native';
|
|
3
|
+
export type ButtonRowVariant = 'default' | 'suggested' | 'destructive';
|
|
4
|
+
export interface ButtonRowProps extends Omit<PressableProps, 'children' | 'style'> {
|
|
5
|
+
/** Label displayed centered in the row. */
|
|
6
|
+
title: string;
|
|
7
|
+
/** Visual style that colours the title text. */
|
|
8
|
+
variant?: ButtonRowVariant;
|
|
9
|
+
/** Icon placed at the leading edge. Rendered as-is — size/color it yourself. */
|
|
10
|
+
leading?: ReactNode;
|
|
11
|
+
/** Icon placed at the trailing edge. Rendered as-is — size/color it yourself. */
|
|
12
|
+
trailing?: ReactNode;
|
|
13
|
+
style?: StyleProp<ViewStyle>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Full-width activatable row styled as a button, for use inside a
|
|
17
|
+
* `BoxedList`. Mirrors `AdwButtonRow` and `@gnome-ui/react`'s own
|
|
18
|
+
* `ButtonRow` — use when an entire list row should trigger a single action
|
|
19
|
+
* with a centered label; prefer `ActionRow` with `interactive` when the row
|
|
20
|
+
* also needs a title/subtitle layout.
|
|
21
|
+
*
|
|
22
|
+
* Rebuilt with `Pressable` rather than ported from the web `<button>` —
|
|
23
|
+
* same pressed-state-overlay recipe `ActionRow`/`Card` already established
|
|
24
|
+
* (`theme.activeOverlay` stands in for the web's `:hover`/`:active`
|
|
25
|
+
* `background-color` transition, since RN has no hover state). The title's
|
|
26
|
+
* color reuses `Text`'s own `TextColor` union (`"accent"`/`"destructive"`
|
|
27
|
+
* already resolve to the exact same `theme.accentColor`/`destructiveColor`
|
|
28
|
+
* tokens the source CSS's `suggested`/`destructive` variants reference) —
|
|
29
|
+
* no separate color-resolution logic needed. Unlike the web version, the
|
|
30
|
+
* variant color does *not* propagate to `leading`/`trailing` — RN's `Icon`
|
|
31
|
+
* has no `currentColor` equivalent and only accepts a fixed named-swatch
|
|
32
|
+
* palette, the same dropped nicety `Chip` already accepted for its own
|
|
33
|
+
* leading/remove icons. The title gets `flex: 1` + `textAlign: 'center'`
|
|
34
|
+
* (the source CSS's own `.title { flex: 1; text-align: center }`) rather
|
|
35
|
+
* than centering the row via `justifyContent` — that keeps the label
|
|
36
|
+
* centered in the row's full width even when only one of `leading`/
|
|
37
|
+
* `trailing` is present, matching the web behavior exactly.
|
|
38
|
+
*
|
|
39
|
+
* @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.ButtonRow.html
|
|
40
|
+
*/
|
|
41
|
+
export declare const ButtonRow: import('react').ForwardRefExoticComponent<ButtonRowProps & import('react').RefAttributes<View>>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { StyleProp, ViewProps, ViewStyle } from 'react-native';
|
|
3
|
+
export type CalloutVariant = 'info' | 'warning' | 'tip';
|
|
4
|
+
export interface CalloutProps extends Omit<ViewProps, 'style'> {
|
|
5
|
+
/**
|
|
6
|
+
* Visual emphasis level.
|
|
7
|
+
* - `info` (default) — neutral, accent-colored. General contextual notes.
|
|
8
|
+
* - `warning` — yellow. Recoverable problems or things to double-check.
|
|
9
|
+
* - `tip` — green. Optional suggestions or shortcuts.
|
|
10
|
+
*/
|
|
11
|
+
variant?: CalloutVariant;
|
|
12
|
+
/** The message content. */
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
/** When true a dismiss (×) button is shown at the trailing edge. */
|
|
15
|
+
dismissible?: boolean;
|
|
16
|
+
/** Called when the user presses the dismiss button. */
|
|
17
|
+
onDismiss?: () => void;
|
|
18
|
+
style?: StyleProp<ViewStyle>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Inline, dismissible admonition box for contextual help text within forms
|
|
22
|
+
* and cards. Mirrors `@gnome-ui/react`'s `Callout`.
|
|
23
|
+
*
|
|
24
|
+
* Unlike `Banner` (a persistent, edge-to-edge strip at the top of a view)
|
|
25
|
+
* and `Toast` (a temporary notification), `Callout` is a contained, tinted
|
|
26
|
+
* box meant to sit inline alongside the content it annotates.
|
|
27
|
+
*
|
|
28
|
+
* `role="note"` ports 1:1 from RN's newer web-aligned `Role` union (the
|
|
29
|
+
* same one `Dialog`/`Tooltip` already use) — `accessible` is set alongside
|
|
30
|
+
* it, per the `BoxedList` lesson that a bare `View` isn't an accessibility
|
|
31
|
+
* element by default. The leading icon is decorative, hidden from
|
|
32
|
+
* assistive tech the same way `Blockquote`'s own icon is.
|
|
33
|
+
*
|
|
34
|
+
* @see https://developer.gnome.org/hig/patterns/feedback/
|
|
35
|
+
*/
|
|
36
|
+
export declare const Callout: ({ variant, children, dismissible, onDismiss, style, ...viewProps }: CalloutProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { PressableProps, StyleProp, View, ViewStyle } from 'react-native';
|
|
3
|
+
export interface CheckRowProps 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, after the checkbox. */
|
|
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 checkbox, mirroring
|
|
20
|
+
* `@gnome-ui/react`'s `CheckRow`. The entire row is a single pressable —
|
|
21
|
+
* pressing anywhere toggles the checked state. Use inside a `BoxedList`
|
|
22
|
+
* when a user must select or deselect individual items in a list; prefer a
|
|
23
|
+
* `SwitchRow` (once ported) for a single on/off setting.
|
|
24
|
+
*
|
|
25
|
+
* Supports both controlled (`checked`) and uncontrolled (`defaultChecked`)
|
|
26
|
+
* modes, the same `isControlled`/internal-state-fallback shape already
|
|
27
|
+
* established by `Expander`/`ComboRow`/`Popover`.
|
|
28
|
+
*
|
|
29
|
+
* The checkbox visual reuses `Checkbox`'s exact border/background
|
|
30
|
+
* `Animated.Value` interpolation and checkmark-fade-in recipe — but as a
|
|
31
|
+
* plain, non-interactive `View` rather than importing the real `Checkbox`
|
|
32
|
+
* component, since `Checkbox` is itself a `Pressable` and nesting one
|
|
33
|
+
* touchable inside another (the row's own `Pressable`) would create two
|
|
34
|
+
* overlapping tap targets. `aria-labelledby` (pointing the web button's
|
|
35
|
+
* `role="checkbox"` at the title/subtitle content) has no RN equivalent —
|
|
36
|
+
* `accessibilityLabel` combining title and subtitle is the substitution,
|
|
37
|
+
* the same "no relationship attribute" gap `Tooltip`'s dropped
|
|
38
|
+
* `aria-describedby` already established. The title reads `theme.cardFgColor`
|
|
39
|
+
* directly (not `Text`'s own `"default"`, which resolves to
|
|
40
|
+
* `windowFgColor`) to match the source CSS's `--gnome-card-fg-color`
|
|
41
|
+
* ambient row color exactly — the two tokens happen to share the same
|
|
42
|
+
* value in every theme this package ships, but the source CSS's intent is
|
|
43
|
+
* specifically "card foreground," so the port keeps that distinction.
|
|
44
|
+
*
|
|
45
|
+
* @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.CheckButton.html
|
|
46
|
+
*/
|
|
47
|
+
export declare const CheckRow: import('react').ForwardRefExoticComponent<CheckRowProps & import('react').RefAttributes<View>>;
|