react-native-audio-browser 0.2.0-next.21 → 0.2.0-next.23
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 +1 -1
- package/android/src/main/java/com/audiobrowser/browser/InertStyleDiagnostic.kt +28 -7
- package/android/src/main/java/com/audiobrowser/util/StyleWire.kt +2 -0
- package/android/src/test/java/com/audiobrowser/browser/InertStyleDiagnosticTest.kt +32 -8
- package/android/src/test/java/com/audiobrowser/browser/JsonStyleTest.kt +21 -0
- package/android/src/test/java/com/audiobrowser/browser/StyleResolverTest.kt +6 -0
- package/ios/Browser/InertStyleDiagnostic.swift +25 -8
- package/ios/Browser/SectionPresentation.swift +18 -5
- package/ios/CarPlay/CPInterfaceController+Safe.swift +93 -23
- package/ios/CarPlay/CarPlayListItemFactory.swift +74 -54
- package/ios/CarPlay/TopTemplateReplacer.swift +96 -0
- package/ios/Model/NitroTypeStubs.swift +3 -0
- package/ios/Tests/InertStyleDiagnosticTests.swift +17 -8
- package/ios/Tests/JsonModelsTests.swift +14 -0
- package/ios/Tests/SectionPresentationTests.swift +21 -13
- package/ios/Tests/StyleResolverTests.swift +5 -0
- package/ios/Tests/TopTemplateReplacerTests.swift +172 -0
- package/lib/typescript/src/types/browser-nodes.d.ts +28 -21
- package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JGridTile.hpp +3 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/GridTile.kt +3 -2
- package/nitrogen/generated/ios/swift/GridTile.swift +4 -0
- package/nitrogen/generated/shared/c++/GridTile.hpp +6 -2
- package/package.json +1 -1
- package/src/types/browser-nodes.ts +28 -21
- package/website/guide/artwork.md +1 -1
- package/website/guide/browser.md +11 -5
- package/website/guide/carplay.md +30 -0
- package/website/guide/track.md +1 -1
|
@@ -23,7 +23,7 @@ export type StyleDisplay = 'list' | 'grid';
|
|
|
23
23
|
*/
|
|
24
24
|
export type ArtworkRendering = 'original' | 'stencil';
|
|
25
25
|
/**
|
|
26
|
-
* The shape
|
|
26
|
+
* The shape an image or condensed grid tile's artwork is cropped to.
|
|
27
27
|
*
|
|
28
28
|
* - `'rounded-rectangle'` (default) — the standard tile crop.
|
|
29
29
|
* - `'circular'` — the standard presentation for *people* (artists, hosts,
|
|
@@ -38,26 +38,31 @@ export type ImageShape = 'circular' | 'rounded-rectangle';
|
|
|
38
38
|
/**
|
|
39
39
|
* The kind of tile a grid renders.
|
|
40
40
|
*
|
|
41
|
-
* - `'plain'` (default) — artwork tiles with a title
|
|
41
|
+
* - `'plain'` (default) — large artwork tiles with a title and subtitle
|
|
42
|
+
* below. No shape and no accessory.
|
|
43
|
+
* - `'image'` — artwork tiles with a title and no subtitle; takes
|
|
44
|
+
* {@link TrackStyle.imageShape} and {@link TrackStyle.accessorySymbol}.
|
|
45
|
+
* The grid of round tiles for people is `'image'` with
|
|
46
|
+
* `imageShape: 'circular'`.
|
|
42
47
|
* - `'card'` — a larger card with title/subtitle and a
|
|
43
48
|
* {@link TrackStyle.cardTint} color; its image mode is
|
|
44
|
-
* {@link TrackStyle.cardImage}. Cards have no shape.
|
|
45
|
-
* - `'condensed'` — a denser cell carrying title + subtitle
|
|
46
|
-
* {@link TrackStyle.imageShape} and
|
|
47
|
-
*
|
|
49
|
+
* {@link TrackStyle.cardImage}. Cards have no shape and no accessory.
|
|
50
|
+
* - `'condensed'` — a denser cell carrying title + subtitle beside a small
|
|
51
|
+
* image; takes {@link TrackStyle.imageShape} and
|
|
52
|
+
* {@link TrackStyle.accessorySymbol}.
|
|
48
53
|
*
|
|
49
54
|
* Element families are mutually exclusive within a container, so this is
|
|
50
55
|
* a container property — hence the enum, and the `grid` prefix.
|
|
51
56
|
*/
|
|
52
|
-
export type GridTile = 'plain' | 'card' | 'condensed';
|
|
57
|
+
export type GridTile = 'plain' | 'image' | 'card' | 'condensed';
|
|
53
58
|
/**
|
|
54
59
|
* How a card tile uses its image.
|
|
55
60
|
*
|
|
56
|
-
* - `'normal'` (default) — image above the labels;
|
|
57
|
-
* {@link TrackStyle.cardTint} colors
|
|
61
|
+
* - `'normal'` (default) — a square image inset above the labels;
|
|
62
|
+
* {@link TrackStyle.cardTint} colors the whole card.
|
|
58
63
|
* - `'background'` — the image fills the card full-height with the labels
|
|
59
|
-
* overlaid; `cardTint`
|
|
60
|
-
*
|
|
64
|
+
* overlaid; `cardTint` fades in behind them. Selects the larger artwork
|
|
65
|
+
* target size.
|
|
61
66
|
*
|
|
62
67
|
* An enum rather than a boolean: it names the card's image mode and
|
|
63
68
|
* leaves room for future modes.
|
|
@@ -120,12 +125,13 @@ export interface TrackStyle {
|
|
|
120
125
|
*/
|
|
121
126
|
artworkRendering?: ArtworkRendering;
|
|
122
127
|
/**
|
|
123
|
-
* Inherited (`track ?? section ?? page`): the shape
|
|
124
|
-
* artwork is cropped to — `'circular'` for people,
|
|
125
|
-
* `'rounded-rectangle'` for everything else. Shape follows
|
|
126
|
-
* wherever it travels: a circular artist stays circular in
|
|
127
|
-
* grid renders it next. Inert where the presentation has
|
|
128
|
-
* (list rows, pre-26 CarPlay, Android
|
|
128
|
+
* Inherited (`track ?? section ?? page`): the shape an image or
|
|
129
|
+
* condensed grid tile's artwork is cropped to — `'circular'` for people,
|
|
130
|
+
* the default `'rounded-rectangle'` for everything else. Shape follows
|
|
131
|
+
* the item wherever it travels: a circular artist stays circular in
|
|
132
|
+
* whatever shaped grid renders it next. Inert where the presentation has
|
|
133
|
+
* no shape (list rows, plain and card tiles, pre-26 CarPlay, Android
|
|
134
|
+
* Auto).
|
|
129
135
|
*
|
|
130
136
|
* @default 'rounded-rectangle'
|
|
131
137
|
*
|
|
@@ -135,8 +141,9 @@ export interface TrackStyle {
|
|
|
135
141
|
/**
|
|
136
142
|
* Inherited (`track ?? section ?? page`): an SF Symbol name drawn as
|
|
137
143
|
* the item's accessory wherever the current presentation supports one —
|
|
138
|
-
* the trailing edge of a list row
|
|
139
|
-
* tile (placement is the platform's choice per
|
|
144
|
+
* the trailing edge of a list row or an iOS 26 condensed tile, leading
|
|
145
|
+
* the title on an image tile (placement is the platform's choice per
|
|
146
|
+
* surface); plain and card tiles have no slot for one. A resolved
|
|
140
147
|
* symbol replaces the derived accessory (the disclosure chevron a
|
|
141
148
|
* browsable row gets); `'none'` clears an inherited value, restoring
|
|
142
149
|
* the derived behavior — inheritance has no other escape, and no SF
|
|
@@ -148,8 +155,8 @@ export interface TrackStyle {
|
|
|
148
155
|
accessorySymbol?: string;
|
|
149
156
|
/**
|
|
150
157
|
* Inherited (`track ?? section ?? page`): the card treatment's tint
|
|
151
|
-
* color (hex, e.g. `'#1e3a8a'`) —
|
|
152
|
-
*
|
|
158
|
+
* color (hex, e.g. `'#1e3a8a'`) — the card's own color, or the color
|
|
159
|
+
* that fades in behind the labels when {@link TrackStyle.cardImage} is
|
|
153
160
|
* `'background'`. Card-prefixed: inert unless the container renders
|
|
154
161
|
* `gridTile: 'card'`.
|
|
155
162
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-nodes.d.ts","sourceRoot":"","sources":["../../../../src/types/browser-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE1E;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAA;AAE1C;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,CAAA;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,mBAAmB,CAAA;AAEzD
|
|
1
|
+
{"version":3,"file":"browser-nodes.d.ts","sourceRoot":"","sources":["../../../../src/types/browser-nodes.ts"],"names":[],"mappings":"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"}
|
|
@@ -45,6 +45,9 @@ namespace margelo::nitro::audiobrowser {
|
|
|
45
45
|
case GridTile::PLAIN:
|
|
46
46
|
static const auto fieldPLAIN = clazz->getStaticField<JGridTile>("PLAIN");
|
|
47
47
|
return clazz->getStaticFieldValue(fieldPLAIN);
|
|
48
|
+
case GridTile::IMAGE:
|
|
49
|
+
static const auto fieldIMAGE = clazz->getStaticField<JGridTile>("IMAGE");
|
|
50
|
+
return clazz->getStaticFieldValue(fieldIMAGE);
|
|
48
51
|
case GridTile::CARD:
|
|
49
52
|
static const auto fieldCARD = clazz->getStaticField<JGridTile>("CARD");
|
|
50
53
|
return clazz->getStaticFieldValue(fieldCARD);
|
|
@@ -19,6 +19,8 @@ public extension GridTile {
|
|
|
19
19
|
switch string {
|
|
20
20
|
case "plain":
|
|
21
21
|
self = .plain
|
|
22
|
+
case "image":
|
|
23
|
+
self = .image
|
|
22
24
|
case "card":
|
|
23
25
|
self = .card
|
|
24
26
|
case "condensed":
|
|
@@ -35,6 +37,8 @@ public extension GridTile {
|
|
|
35
37
|
switch self {
|
|
36
38
|
case .plain:
|
|
37
39
|
return "plain"
|
|
40
|
+
case .image:
|
|
41
|
+
return "image"
|
|
38
42
|
case .card:
|
|
39
43
|
return "card"
|
|
40
44
|
case .condensed:
|
|
@@ -30,8 +30,9 @@ namespace margelo::nitro::audiobrowser {
|
|
|
30
30
|
*/
|
|
31
31
|
enum class GridTile {
|
|
32
32
|
PLAIN SWIFT_NAME(plain) = 0,
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
IMAGE SWIFT_NAME(image) = 1,
|
|
34
|
+
CARD SWIFT_NAME(card) = 2,
|
|
35
|
+
CONDENSED SWIFT_NAME(condensed) = 3,
|
|
35
36
|
} CLOSED_ENUM;
|
|
36
37
|
|
|
37
38
|
} // namespace margelo::nitro::audiobrowser
|
|
@@ -45,6 +46,7 @@ namespace margelo::nitro {
|
|
|
45
46
|
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
|
|
46
47
|
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
47
48
|
case hashString("plain"): return margelo::nitro::audiobrowser::GridTile::PLAIN;
|
|
49
|
+
case hashString("image"): return margelo::nitro::audiobrowser::GridTile::IMAGE;
|
|
48
50
|
case hashString("card"): return margelo::nitro::audiobrowser::GridTile::CARD;
|
|
49
51
|
case hashString("condensed"): return margelo::nitro::audiobrowser::GridTile::CONDENSED;
|
|
50
52
|
default: [[unlikely]]
|
|
@@ -54,6 +56,7 @@ namespace margelo::nitro {
|
|
|
54
56
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::audiobrowser::GridTile arg) {
|
|
55
57
|
switch (arg) {
|
|
56
58
|
case margelo::nitro::audiobrowser::GridTile::PLAIN: return JSIConverter<std::string>::toJSI(runtime, "plain");
|
|
59
|
+
case margelo::nitro::audiobrowser::GridTile::IMAGE: return JSIConverter<std::string>::toJSI(runtime, "image");
|
|
57
60
|
case margelo::nitro::audiobrowser::GridTile::CARD: return JSIConverter<std::string>::toJSI(runtime, "card");
|
|
58
61
|
case margelo::nitro::audiobrowser::GridTile::CONDENSED: return JSIConverter<std::string>::toJSI(runtime, "condensed");
|
|
59
62
|
default: [[unlikely]]
|
|
@@ -68,6 +71,7 @@ namespace margelo::nitro {
|
|
|
68
71
|
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);
|
|
69
72
|
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
70
73
|
case hashString("plain"):
|
|
74
|
+
case hashString("image"):
|
|
71
75
|
case hashString("card"):
|
|
72
76
|
case hashString("condensed"):
|
|
73
77
|
return true;
|
package/package.json
CHANGED
|
@@ -26,7 +26,7 @@ export type StyleDisplay = 'list' | 'grid'
|
|
|
26
26
|
export type ArtworkRendering = 'original' | 'stencil'
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* The shape
|
|
29
|
+
* The shape an image or condensed grid tile's artwork is cropped to.
|
|
30
30
|
*
|
|
31
31
|
* - `'rounded-rectangle'` (default) — the standard tile crop.
|
|
32
32
|
* - `'circular'` — the standard presentation for *people* (artists, hosts,
|
|
@@ -42,27 +42,32 @@ export type ImageShape = 'circular' | 'rounded-rectangle'
|
|
|
42
42
|
/**
|
|
43
43
|
* The kind of tile a grid renders.
|
|
44
44
|
*
|
|
45
|
-
* - `'plain'` (default) — artwork tiles with a title
|
|
45
|
+
* - `'plain'` (default) — large artwork tiles with a title and subtitle
|
|
46
|
+
* below. No shape and no accessory.
|
|
47
|
+
* - `'image'` — artwork tiles with a title and no subtitle; takes
|
|
48
|
+
* {@link TrackStyle.imageShape} and {@link TrackStyle.accessorySymbol}.
|
|
49
|
+
* The grid of round tiles for people is `'image'` with
|
|
50
|
+
* `imageShape: 'circular'`.
|
|
46
51
|
* - `'card'` — a larger card with title/subtitle and a
|
|
47
52
|
* {@link TrackStyle.cardTint} color; its image mode is
|
|
48
|
-
* {@link TrackStyle.cardImage}. Cards have no shape.
|
|
49
|
-
* - `'condensed'` — a denser cell carrying title + subtitle
|
|
50
|
-
* {@link TrackStyle.imageShape} and
|
|
51
|
-
*
|
|
53
|
+
* {@link TrackStyle.cardImage}. Cards have no shape and no accessory.
|
|
54
|
+
* - `'condensed'` — a denser cell carrying title + subtitle beside a small
|
|
55
|
+
* image; takes {@link TrackStyle.imageShape} and
|
|
56
|
+
* {@link TrackStyle.accessorySymbol}.
|
|
52
57
|
*
|
|
53
58
|
* Element families are mutually exclusive within a container, so this is
|
|
54
59
|
* a container property — hence the enum, and the `grid` prefix.
|
|
55
60
|
*/
|
|
56
|
-
export type GridTile = 'plain' | 'card' | 'condensed'
|
|
61
|
+
export type GridTile = 'plain' | 'image' | 'card' | 'condensed'
|
|
57
62
|
|
|
58
63
|
/**
|
|
59
64
|
* How a card tile uses its image.
|
|
60
65
|
*
|
|
61
|
-
* - `'normal'` (default) — image above the labels;
|
|
62
|
-
* {@link TrackStyle.cardTint} colors
|
|
66
|
+
* - `'normal'` (default) — a square image inset above the labels;
|
|
67
|
+
* {@link TrackStyle.cardTint} colors the whole card.
|
|
63
68
|
* - `'background'` — the image fills the card full-height with the labels
|
|
64
|
-
* overlaid; `cardTint`
|
|
65
|
-
*
|
|
69
|
+
* overlaid; `cardTint` fades in behind them. Selects the larger artwork
|
|
70
|
+
* target size.
|
|
66
71
|
*
|
|
67
72
|
* An enum rather than a boolean: it names the card's image mode and
|
|
68
73
|
* leaves room for future modes.
|
|
@@ -128,12 +133,13 @@ export interface TrackStyle {
|
|
|
128
133
|
artworkRendering?: ArtworkRendering
|
|
129
134
|
|
|
130
135
|
/**
|
|
131
|
-
* Inherited (`track ?? section ?? page`): the shape
|
|
132
|
-
* artwork is cropped to — `'circular'` for people,
|
|
133
|
-
* `'rounded-rectangle'` for everything else. Shape follows
|
|
134
|
-
* wherever it travels: a circular artist stays circular in
|
|
135
|
-
* grid renders it next. Inert where the presentation has
|
|
136
|
-
* (list rows, pre-26 CarPlay, Android
|
|
136
|
+
* Inherited (`track ?? section ?? page`): the shape an image or
|
|
137
|
+
* condensed grid tile's artwork is cropped to — `'circular'` for people,
|
|
138
|
+
* the default `'rounded-rectangle'` for everything else. Shape follows
|
|
139
|
+
* the item wherever it travels: a circular artist stays circular in
|
|
140
|
+
* whatever shaped grid renders it next. Inert where the presentation has
|
|
141
|
+
* no shape (list rows, plain and card tiles, pre-26 CarPlay, Android
|
|
142
|
+
* Auto).
|
|
137
143
|
*
|
|
138
144
|
* @default 'rounded-rectangle'
|
|
139
145
|
*
|
|
@@ -144,8 +150,9 @@ export interface TrackStyle {
|
|
|
144
150
|
/**
|
|
145
151
|
* Inherited (`track ?? section ?? page`): an SF Symbol name drawn as
|
|
146
152
|
* the item's accessory wherever the current presentation supports one —
|
|
147
|
-
* the trailing edge of a list row
|
|
148
|
-
* tile (placement is the platform's choice per
|
|
153
|
+
* the trailing edge of a list row or an iOS 26 condensed tile, leading
|
|
154
|
+
* the title on an image tile (placement is the platform's choice per
|
|
155
|
+
* surface); plain and card tiles have no slot for one. A resolved
|
|
149
156
|
* symbol replaces the derived accessory (the disclosure chevron a
|
|
150
157
|
* browsable row gets); `'none'` clears an inherited value, restoring
|
|
151
158
|
* the derived behavior — inheritance has no other escape, and no SF
|
|
@@ -158,8 +165,8 @@ export interface TrackStyle {
|
|
|
158
165
|
|
|
159
166
|
/**
|
|
160
167
|
* Inherited (`track ?? section ?? page`): the card treatment's tint
|
|
161
|
-
* color (hex, e.g. `'#1e3a8a'`) —
|
|
162
|
-
*
|
|
168
|
+
* color (hex, e.g. `'#1e3a8a'`) — the card's own color, or the color
|
|
169
|
+
* that fades in behind the labels when {@link TrackStyle.cardImage} is
|
|
163
170
|
* `'background'`. Card-prefixed: inert unless the container renders
|
|
164
171
|
* `gridTile: 'card'`.
|
|
165
172
|
*
|
package/website/guide/artwork.md
CHANGED
|
@@ -238,7 +238,7 @@ A page's [`Section`](/api/types/browser-nodes/#section) can render its tracks as
|
|
|
238
238
|
}
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
-
Each tile is an ordinary Track, so its `artwork` runs through the same pipeline as any other. Tile styles presume artwork: a track without any renders as a placeholder tile plus its title — the artwork `resolve` hook is the place to supply fallback art. On CarPlay a single-line grid (`gridWrap: false`) shows the tiles that fit (
|
|
241
|
+
Each tile is an ordinary Track, so its `artwork` runs through the same pipeline as any other. Tile styles presume artwork: a track without any renders as a placeholder tile plus its title — the artwork `resolve` hook is the place to supply fallback art. On CarPlay a single-line grid (`gridWrap: false`) shows the tiles that fit on one line (seven on a wide screen, or two condensed cells; the rest are truncated) and a wrapping grid takes as many lines as it needs on iOS 26+ (rendering as a list before that); Android Auto's grid always wraps, so it renders both identically. See [Browser → Presentation](/guide/browser#presentation) for the full per-surface rundown.
|
|
242
242
|
|
|
243
243
|
## API summary
|
|
244
244
|
|
package/website/guide/browser.md
CHANGED
|
@@ -521,9 +521,9 @@ Presentation lives in `style` blocks, separate from content, plus a few Track fi
|
|
|
521
521
|
| `style` (same block) | a page | declaration for the whole page — a section overrides it for its own children | all |
|
|
522
522
|
| `style: { display: 'grid' }` | a browsable track | the layout of the page it opens — Android Auto reads it from the parent item | Android Auto / AAOS |
|
|
523
523
|
| `style: { artworkRendering: 'stencil' }` | a track / section / page | tint monochrome artwork to the surface appearance | CarPlay |
|
|
524
|
-
| `style: { imageShape: 'circular' }` | a track / section / page | crop
|
|
525
|
-
| `style: { accessorySymbol: 'lock.fill' }` | a track / section / page | SF Symbol accessory on rows and
|
|
526
|
-
| `style: { gridTile: 'card' }` | a section / page | the grid's tile kind: `'plain'` (default), `'card'`, or `'condensed'`
|
|
524
|
+
| `style: { imageShape: 'circular' }` | a track / section / page | crop `'image'` and `'condensed'` tile artwork circular (people) | CarPlay (iOS 26+) |
|
|
525
|
+
| `style: { accessorySymbol: 'lock.fill' }` | a track / section / page | SF Symbol accessory on rows and on `'image'` / `'condensed'` tiles | CarPlay |
|
|
526
|
+
| `style: { gridTile: 'card' }` | a section / page | the grid's tile kind: `'plain'` (default), `'image'`, `'card'`, or `'condensed'` | CarPlay (iOS 26+) |
|
|
527
527
|
| `style: { cardTint: '#1e3a8a' }` (+ `cardImage`) | a track / section / page | card color and image mode (`'background'` fills the card full-height) | CarPlay (iOS 26+) |
|
|
528
528
|
| `disabled: true` | a track | unavailable: never plays; grayed where drawable, hidden elsewhere | all |
|
|
529
529
|
| `artwork: 'sf:heart.fill'` | any item | SF Symbol icon (supports `?bg=…&fg=…`) | iOS |
|
|
@@ -532,11 +532,11 @@ Presentation lives in `style` blocks, separate from content, plus a few Track fi
|
|
|
532
532
|
| `albumPath` + `resolveAlbumPath` | track + config | make the now-playing album line tappable | CarPlay |
|
|
533
533
|
|
|
534
534
|
::: info Caveats from the table
|
|
535
|
-
**`albumPath` requires `album`** — CarPlay renders the tappable line from the album metadata, so without an `album` there is no line to tap. **\*Layouts render each platform's nearest supported form** — a single-line grid (`gridWrap: false`) on CarPlay shows the tiles that fit (
|
|
535
|
+
**`albumPath` requires `album`** — CarPlay renders the tappable line from the album metadata, so without an `album` there is no line to tap. **\*Layouts render each platform's nearest supported form** — a single-line grid (`gridWrap: false`) on CarPlay shows the tiles that fit on one line (seven on a wide screen, or two condensed cells) and truncates the rest; a wrapping grid takes as many lines as it needs on iOS 26+ and renders as a list before that. Android Auto's grid always wraps, so it shows more, never less. No car surface scrolls horizontally; an app UI typically renders `gridWrap: false` as a horizontal scroller. Truncation is visual only: tapping a tile queues the whole section (see [Playback behavior](#playback-behavior)). Item properties like `artworkRendering`, `imageShape`, and `accessorySymbol` are inherited — `track ?? section ?? page`, per property — so a section-wide value can be overridden per item; `accessorySymbol: 'none'` is the per-item escape from an inherited symbol, and where the accessory draws is the platform's choice per surface (trailing on list rows and condensed tiles, leading the title on image tiles). On an iOS 26 grid, which tile draws what is `gridTile`'s choice: `'plain'` has a subtitle but no shape and no accessory, `'image'` has a shape and an accessory but no subtitle, `'condensed'` has all three beside a small image, and `'card'` has a subtitle, a tint and an image mode. `display` is never inherited: it always describes the children of whatever it's set on. On a page or section it lays out that page or section; on a browsable track it declares the layout of the page that track opens — Android Auto needs it there, or that page renders as a list. `gridWrap` is inert unless `display` is `'grid'`. One AAOS caveat: AOSP-based Automotive units honor only the parent item's `display`, so a page mixing grid and list sections renders uniformly there — see [Android Auto → Browse display](/guide/android-auto#browse-display).
|
|
536
536
|
:::
|
|
537
537
|
|
|
538
538
|
::: tip Inert declarations are logged in debug builds
|
|
539
|
-
A combination that can never render — `gridWrap` or `gridTile` outside a grid, `cardTint` with no card treatment in scope, `imageShape`
|
|
539
|
+
A combination that can never render — `gridWrap` or `gridTile` outside a grid, `cardTint` with no card treatment in scope, `imageShape` anywhere but an image or condensed grid, `accessorySymbol` on a plain or card grid, `display` on a track that renders playable — is inert, not an error, so nothing breaks. In a **debug build**, each one is logged once per page resolution (`Timber` on Android, `os.log` on iOS) naming the section, the effective style, and the fix:
|
|
540
540
|
|
|
541
541
|
```
|
|
542
542
|
Inert style declaration on page '/home': `style.gridWrap` on section 'Featured'
|
|
@@ -557,6 +557,8 @@ A property a _surface_ can't draw is never reported — that's the aspirational
|
|
|
557
557
|
title: 'Home',
|
|
558
558
|
sections: [
|
|
559
559
|
{ title: 'Popular', style: { display: 'grid', gridWrap: false }, path: '/popular', children: [...] },
|
|
560
|
+
// Round tiles for people: the image tile is the one with a shape.
|
|
561
|
+
{ title: 'Artists', style: { display: 'grid', gridTile: 'image', imageShape: 'circular' }, children: [...] },
|
|
560
562
|
{ title: 'All stations', children: [...] }
|
|
561
563
|
]
|
|
562
564
|
}
|
|
@@ -567,6 +569,10 @@ A property a _surface_ can't draw is never reported — that's the aspirational
|
|
|
567
569
|
}
|
|
568
570
|
```
|
|
569
571
|
|
|
572
|
+
::: tip See every style rendered
|
|
573
|
+
The example app's **Style Lab** tab draws each `style` declaration on CarPlay: one page per `gridTile` value, plus pages for section headers and for inheritance from page to section to track. Every shelf is titled with the block it renders, so what you see on screen names what to copy. The pages are plain route data in [`style-lab.ts`](https://github.com/radio-garden/react-native-audio-browser/blob/main/apps/example-native/src/utils/style-lab.ts), with a comment on each example saying what it shows.
|
|
574
|
+
:::
|
|
575
|
+
|
|
570
576
|
Two config-level platform options round it out: `carPlayLoadingTitle` (localized "Loading…" on older CarPlay) and `androidControllerOfflineError`. The album-line tap needs both `albumPath` on the track and a `resolveAlbumPath` callback in the config that maps it to a browse path — see [CarPlay](/guide/carplay) and [Android Auto](/guide/android-auto) for the platform setup these build on.
|
|
571
577
|
|
|
572
578
|
## Where to go next
|
package/website/guide/carplay.md
CHANGED
|
@@ -601,6 +601,36 @@ Return a browse path to enable the album line for that track, or `undefined` to
|
|
|
601
601
|
CarPlay renders the tappable album/artist button as a **separate line built from the track's `album`** (visible as the third metadata line, with a chevron). Tracks without an `album` have no string for CarPlay to turn into a button — the artist line alone is never tappable. Set `album` on any track that should offer album-line navigation. See [Now Playing](/guide/now-playing) for the full field-by-surface rendering matrix.
|
|
602
602
|
:::
|
|
603
603
|
|
|
604
|
+
## Template Depth
|
|
605
|
+
|
|
606
|
+
CarPlay limits an audio app's template stack to **five templates, the tab bar included** (CarPlay App Programming Guide, p. 15), so the stack is full four pushes in. Now Playing and Up Next each take a slot like any list. A browse tree with a fixed shape (tabs → show → episodes) never gets there; one that can be drilled without end — a place, a place near it, a place near that — does.
|
|
607
|
+
|
|
608
|
+
At the limit, the library replaces the **top** page with the new one, so a push always lands:
|
|
609
|
+
|
|
610
|
+
```
|
|
611
|
+
[tabs, A, B, C, D] + push E
|
|
612
|
+
[tabs, A, B, C, E]
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
- **Forward never blocks.** A deeper list, Now Playing and Up Next all open at full depth.
|
|
616
|
+
- **Back skips one page.** From `E` it goes to `C`: `D`, the page the listener came from, is the one that was replaced. Below full depth, back works as usual.
|
|
617
|
+
- **The swap is a pop and a push.** CarPlay can't replace a template in place, so the library pops the top one without animation and then pushes the new one.
|
|
618
|
+
|
|
619
|
+
Each replacement is logged under the `com.audiobrowser` subsystem, category `TemplateStack`:
|
|
620
|
+
|
|
621
|
+
```
|
|
622
|
+
push at the depth limit: replacing the top, CPListTemplate, with CPListTemplate
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
To watch for it on the simulator:
|
|
626
|
+
|
|
627
|
+
```sh
|
|
628
|
+
xcrun simctl spawn booted log stream --level info \
|
|
629
|
+
--predicate 'subsystem == "com.audiobrowser" AND category == "TemplateStack"'
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
An `error` line in that category means the pop or the push failed; it names the template involved.
|
|
633
|
+
|
|
604
634
|
## Testing
|
|
605
635
|
|
|
606
636
|
Test your app in the `CarPlay Simulator.app`, which is part of the [Additional Tools for Xcode](https://developer.apple.com/download/all/?q=additional%20tools%20for%20xcode). Siri voice search works there, so you can exercise the full intent flow without a car. CarPlay support on the iOS Simulator can be a little flaky — if something looks broken, retry or fall back to a physical device for final verification.
|
package/website/guide/track.md
CHANGED
|
@@ -142,7 +142,7 @@ Optional fields that change how a Track renders on CarPlay / Android Auto. Each
|
|
|
142
142
|
| ------------------------------------------ | ---------------------------------------------------------------------- | -------------------------- |
|
|
143
143
|
| `style: { display: 'list' \| 'grid' }` | on a browsable track: the layout of the page it opens | Android Auto / AAOS |
|
|
144
144
|
| `style: { artworkRendering: 'stencil' }` | tint monochrome artwork to the surface appearance | CarPlay |
|
|
145
|
-
| `style: { imageShape: 'circular' }` | crop
|
|
145
|
+
| `style: { imageShape: 'circular' }` | crop `'image'` and `'condensed'` tile artwork circular (people) | CarPlay (iOS 26+) |
|
|
146
146
|
| `style: { accessorySymbol: '…' }` | SF Symbol accessory; `'none'` restores the derived accessory | CarPlay |
|
|
147
147
|
| `style: { cardTint: '…', cardImage: '…' }` | card color and image mode, when the section renders `gridTile: 'card'` | CarPlay (iOS 26+) |
|
|
148
148
|
| `disabled` | unavailable: never plays; grayed where drawable, hidden elsewhere | all |
|