@swiftbrowser/react 0.17.5 → 0.17.7

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 CHANGED
@@ -397,19 +397,33 @@ systemName="star.fill" /> }`) come back from `resolveSymbol` and draw with
397
397
  `drawSymbol` at a point, under the context's transform and opacity; they are
398
398
  real views laid over the canvas, so they draw above its other commands. `useAVPlayer(url)` is an `AVPlayer` (play, pause, seek,
399
399
  mute, volume, rate) that `VideoPlayer` shows in the page's `<video>`; the
400
- position is read or observed without re-rendering.
400
+ position is read or observed without re-rendering. A player shown by no
401
+ view plays nothing, so an audio app (a playlist, a podcast) puts an
402
+ `<AudioPlayer player={…} />` somewhere that stays mounted: the player at
403
+ no size, out of the way of taps, playing on wherever the screens go.
404
+ `new AVQueuePlayer(urls)` plays its items one after another (`items()`,
405
+ `advanceToNextItem`, `insert`, `remove`), at the same rate, and pauses
406
+ after the last. What plays goes on the lock screen and the media keys
407
+ through the browser's own `navigator.mediaSession`, which the native app
408
+ has too (`@swiftbrowser/native`, "Now playing"). `Slider`'s `onEditingChanged` says when a drag begins and
409
+ ends, so a scrubber bound to the position can stop following it while the
410
+ thumb is held.
401
411
 
402
412
  An image is inert, as a SwiftUI image is. `<AsyncImage url={…}
403
413
  webInteractions />` gives a remote picture the browser's own image
404
414
  interactions back: a long press's Save / Share / Copy on iOS, dragging it
405
415
  out of the page, the right-click menu. Use it on an image with no tap,
406
416
  gesture or context menu of its own. `placeholder` shows until the image
407
- loaded (a box at the picture's aspect ratio keeps the row from shifting),
408
- `failure` when it could not, and `loadingIndicator` goes over the
417
+ loaded, `failure` when it could not, and `loadingIndicator` goes over the
409
418
  placeholder once a load has run for `loadingIndicatorDelay` ms (300 by
410
419
  default): a `<ProgressView />` for a big picture on a slow connection,
411
- nothing for one that comes quickly or from the cache. All three show in a
412
- SwiftBrowser Native app too.
420
+ nothing for one that comes quickly or from the cache. The image's
421
+ modifiers apply in every phase, as a SwiftUI `AsyncImage`'s do: a
422
+ thumbnail with `frame={{ width: 72, height: 48 }}` keeps its box while it
423
+ loads (with no placeholder, an empty one), so the text beside it does not
424
+ move when the picture arrives; a `placeholder` at the picture's aspect
425
+ ratio does the same for a picture drawn at its own shape. All three show
426
+ in a SwiftBrowser Native app too.
413
427
 
414
428
  `keyboardType`, `textContentType`, `textInputAutocapitalization` and
415
429
  `autocorrectionDisabled` are SwiftUI's text input hints, for the field they
@@ -595,7 +609,7 @@ read with a hook). Props, callbacks and external stores need no bridging.
595
609
  styles, `LabeledContent`, `Link`, `Color` as a view, shapes (built-in,
596
610
  custom paths, `UnevenRoundedRectangle`, `ContainerRelativeShape`) with
597
611
  fills, strokes and gradients, `Canvas`, `TimelineView`, `VideoPlayer`,
598
- `Gauge`, `ProgressView`, Swift Charts.
612
+ `AudioPlayer` and `AVQueuePlayer`, `Gauge`, `ProgressView`, Swift Charts.
599
613
  - **Controls**: `Button` (styles, roles, sizes), `Toggle`, `Picker`,
600
614
  `Slider`, `Stepper`, `TextField` and `SecureField` (focus bindings, submit
601
615
  labels), `TextEditor`, `DatePicker`, `ColorPicker`, `ShareLink`, `Menu`,
@@ -41,6 +41,8 @@ export declare function plainText(element: ReactElement): string;
41
41
  export interface SliderProps extends ViewModifiers {
42
42
  value: BindingValue<number>;
43
43
  onChange?: (value: number) => void;
44
+ /** `onEditingChanged`: true as a drag begins, false as it ends (a scrubber stops following the position while the thumb is held). */
45
+ onEditingChanged?: (editing: boolean) => void;
44
46
  /** `in: 0...1` */
45
47
  range?: readonly [number, number];
46
48
  step?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../../src/components/controls.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../../src/components/controls.tsx"],"names":[],"mappings":"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"}
@@ -6,9 +6,14 @@ export interface AsyncImageProps extends ViewModifiers {
6
6
  url: string;
7
7
  /** `.resizable()` on the loaded image. */
8
8
  resizable?: boolean;
9
- /** Shown until the image loaded (nothing by default). */
9
+ /**
10
+ * Shown until the image loaded (nothing by default). The image's modifiers
11
+ * (its frame, aspect ratio, corner radius) apply to it as they do to the
12
+ * picture, as a SwiftUI `AsyncImage`'s do in every phase: a framed image
13
+ * keeps its box while it loads, so the row beside it does not move.
14
+ */
10
15
  placeholder?: ReactNode;
11
- /** Shown when the image failed to load (the placeholder by default). */
16
+ /** Shown when the image failed to load (the placeholder by default), under the same modifiers. */
12
17
  failure?: ReactNode;
13
18
  /**
14
19
  * Shown over the placeholder once a load has run for `loadingIndicatorDelay`
@@ -1 +1 @@
1
- {"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/components/images.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAG9E,4DAA4D;AAC5D,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yDAAyD;IACzD,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,wEAAwE;IACxE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAmBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,CAqD5D"}
1
+ {"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/components/images.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAG9E,4DAA4D;AAC5D,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,kGAAkG;IAClG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAmBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,CA2D5D"}
@@ -1,4 +1,4 @@
1
- /** `TimelineView` and `VideoPlayer` with `useAVPlayer`. */
1
+ /** `TimelineView`, and `VideoPlayer` and `AudioPlayer` with `useAVPlayer` and `AVQueuePlayer`. */
2
2
  import type { RendererEvent } from '@swiftbrowser/web/src/protocol';
3
3
  import { type ReactNode } from 'react';
4
4
  import { type ViewModifiers } from '../modifiers';
@@ -48,7 +48,7 @@ interface PlayerState {
48
48
  * reports a second) re-renders nothing: read it or listen with `onTime`.
49
49
  */
50
50
  export declare class AVPlayer {
51
- private state;
51
+ protected state: PlayerState;
52
52
  private listeners;
53
53
  private timeListeners;
54
54
  private time;
@@ -84,7 +84,31 @@ export declare class AVPlayer {
84
84
  onTime(listener: (time: number) => void): () => void;
85
85
  /** @internal The page's report for a view showing this player. */
86
86
  handle(event: VideoEvent): void;
87
- private update;
87
+ /** The item played to its end: a looping player plays on, the others pause (`actionAtItemEnd: .pause`; a queue advances). */
88
+ protected ended(): void;
89
+ protected update(changes: Partial<PlayerState>): void;
90
+ }
91
+ /**
92
+ * `AVQueuePlayer`: a player with the items to play after the current one.
93
+ * When the current item ends the next plays (`actionAtItemEnd: .advance`),
94
+ * at the same rate; with none left the player pauses at the end. `items()`
95
+ * is the current item and the rest; `insert` and `remove` edit the rest.
96
+ */
97
+ export declare class AVQueuePlayer extends AVPlayer {
98
+ private upcoming;
99
+ constructor(urls?: readonly string[], options?: {
100
+ loop?: boolean;
101
+ });
102
+ /** The current item (if any) and the items after it. */
103
+ items(): string[];
104
+ /** Plays the next item, or ends with nothing (`currentItem` null, paused) when there is none. */
105
+ advanceToNextItem(): void;
106
+ /** Adds `url` after `after` (an item in the queue), or at the end; `after` null puts it first, as `insert(_:after: nil)` does. */
107
+ insert(url: string, after?: string | null): void;
108
+ /** Removes a queued item, or the current one, which advances. */
109
+ remove(url: string): void;
110
+ removeAllItems(): void;
111
+ protected ended(): void;
88
112
  }
89
113
  /** A player kept for the component's life, re-rendering it when what it plays changes. */
90
114
  export declare function useAVPlayer(url?: string | null, options?: {
@@ -101,5 +125,16 @@ export interface VideoPlayerProps extends ViewModifiers {
101
125
  }
102
126
  /** `VideoPlayer(player:)`: the page's `<video>` showing the player, or black without one. */
103
127
  export declare function VideoPlayer(props: VideoPlayerProps): ReactNode;
128
+ /**
129
+ * A player that plays with no view: the element at no size and out of the
130
+ * way of taps, so an audio player (a playlist, a podcast)
131
+ * keeps playing wherever the app's screens go. Put one anywhere in the
132
+ * tree that stays mounted (the root), since a player shown by no
133
+ * `VideoPlayer` or `AudioPlayer` plays nothing. iOS plays a player's sound
134
+ * with no layer the same way.
135
+ */
136
+ export declare function AudioPlayer({ player }: {
137
+ player: AVPlayer | null;
138
+ }): ReactNode;
104
139
  export {};
105
140
  //# sourceMappingURL=media.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/components/media.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/components/media.tsx"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2998,7 +2998,18 @@ function Slider(props) {
2998
2998
  children.push(/* @__PURE__ */ jsx(Fragment, { children: own.minimumValueLabel }, "min"), /* @__PURE__ */ jsx(Fragment, { children: own.maximumValueLabel }, "max"));
2999
2999
  }
3000
3000
  return applyModifiers(
3001
- sb("slider", { value, min, max, step: own.step ?? null, labels }, { slide: (event) => setValue(event.value) }, children.length ? children : void 0),
3001
+ sb(
3002
+ "slider",
3003
+ { value, min, max, step: own.step ?? null, labels },
3004
+ {
3005
+ slide: (event) => {
3006
+ if (event.editing === true) own.onEditingChanged?.(true);
3007
+ setValue(event.value);
3008
+ if (event.editing === false) own.onEditingChanged?.(false);
3009
+ }
3010
+ },
3011
+ children.length ? children : void 0
3012
+ ),
3002
3013
  modifiers
3003
3014
  );
3004
3015
  }
@@ -3450,14 +3461,14 @@ function AsyncImage(props) {
3450
3461
  return applyModifiers(sb("image", { ...imageProps(own), url: own.url, width: 0, height: 0 }), modifiers);
3451
3462
  }
3452
3463
  if (state === null) {
3453
- const placeholder2 = own.placeholder ?? null;
3454
- if (!slow || !hasIndicator) return placeholder2;
3455
- return /* @__PURE__ */ jsxs(ZStack, { children: [
3464
+ const placeholder2 = own.placeholder ?? /* @__PURE__ */ jsx(ZStack, {});
3465
+ const shown = slow && hasIndicator ? /* @__PURE__ */ jsxs(ZStack, { children: [
3456
3466
  placeholder2,
3457
3467
  own.loadingIndicator
3458
- ] });
3468
+ ] }) : placeholder2;
3469
+ return applyModifiers(shown, modifiers);
3459
3470
  }
3460
- if (state === "failed") return own.failure ?? own.placeholder ?? null;
3471
+ if (state === "failed") return applyModifiers(own.failure ?? own.placeholder ?? /* @__PURE__ */ jsx(ZStack, {}), modifiers);
3461
3472
  return applyModifiers(sb("image", { ...imageProps(own), url: state.url, width: state.width, height: state.height }), modifiers);
3462
3473
  }
3463
3474
  function imageProps(own) {
@@ -4436,18 +4447,73 @@ class AVPlayer {
4436
4447
  if (event.rate !== void 0) this.update({ rate: event.rate });
4437
4448
  break;
4438
4449
  case "ended":
4439
- if (!this.state.loop) this.update({ rate: 0 });
4450
+ this.ended();
4440
4451
  break;
4441
4452
  case "error":
4442
4453
  this.update({ failed: event.message ?? "error", rate: 0 });
4443
4454
  break;
4444
4455
  }
4445
4456
  }
4457
+ /** The item played to its end: a looping player plays on, the others pause (`actionAtItemEnd: .pause`; a queue advances). */
4458
+ ended() {
4459
+ if (!this.state.loop) this.update({ rate: 0 });
4460
+ }
4446
4461
  update(changes) {
4447
4462
  this.state = { ...this.state, ...changes };
4448
4463
  for (const listener of this.listeners) listener();
4449
4464
  }
4450
4465
  }
4466
+ class AVQueuePlayer extends AVPlayer {
4467
+ upcoming = [];
4468
+ constructor(urls = [], options = {}) {
4469
+ super(urls[0] ?? null, options);
4470
+ this.upcoming = urls.slice(1);
4471
+ }
4472
+ /** The current item (if any) and the items after it. */
4473
+ items() {
4474
+ return this.url === null ? [...this.upcoming] : [this.url, ...this.upcoming];
4475
+ }
4476
+ /** Plays the next item, or ends with nothing (`currentItem` null, paused) when there is none. */
4477
+ advanceToNextItem() {
4478
+ const next = this.upcoming.shift();
4479
+ if (next === void 0) {
4480
+ this.replaceCurrentItem(null);
4481
+ this.update({ rate: 0 });
4482
+ return;
4483
+ }
4484
+ this.replaceCurrentItem(next);
4485
+ }
4486
+ /** Adds `url` after `after` (an item in the queue), or at the end; `after` null puts it first, as `insert(_:after: nil)` does. */
4487
+ insert(url, after = null) {
4488
+ if (after === null) {
4489
+ this.upcoming.unshift(url);
4490
+ } else {
4491
+ const at = this.upcoming.indexOf(after);
4492
+ if (at === -1) this.upcoming.push(url);
4493
+ else this.upcoming.splice(at + 1, 0, url);
4494
+ }
4495
+ this.update({});
4496
+ }
4497
+ /** Removes a queued item, or the current one, which advances. */
4498
+ remove(url) {
4499
+ if (url === this.url) {
4500
+ this.advanceToNextItem();
4501
+ return;
4502
+ }
4503
+ const at = this.upcoming.indexOf(url);
4504
+ if (at !== -1) this.upcoming.splice(at, 1);
4505
+ this.update({});
4506
+ }
4507
+ removeAllItems() {
4508
+ this.upcoming = [];
4509
+ this.replaceCurrentItem(null);
4510
+ this.update({ rate: 0 });
4511
+ }
4512
+ ended() {
4513
+ if (this.state.loop) return;
4514
+ this.advanceToNextItem();
4515
+ }
4516
+ }
4451
4517
  function useAVPlayer(url = null, options = {}) {
4452
4518
  const ref = useRef(null);
4453
4519
  ref.current ??= new AVPlayer(url, options);
@@ -4458,16 +4524,8 @@ function useAVPlayer(url = null, options = {}) {
4458
4524
  }, [player, url]);
4459
4525
  return player;
4460
4526
  }
4461
- function VideoPlayer(props) {
4462
- const { own, modifiers } = splitProps(props);
4463
- const player = own.player;
4464
- const state = useSyncExternalStore(
4465
- player?.subscribe ?? NO_SUBSCRIBE,
4466
- () => player?.snapshot ?? null,
4467
- () => player?.snapshot ?? null
4468
- );
4469
- if (!player || !state || !state.url) return applyModifiers(sb("color", { color: { r: 0, g: 0, b: 0, a: 1 } }), modifiers);
4470
- const video = sb(
4527
+ function videoElement(player, state, options) {
4528
+ return sb(
4471
4529
  "video",
4472
4530
  {
4473
4531
  url: state.url,
@@ -4476,13 +4534,24 @@ function VideoPlayer(props) {
4476
4534
  volume: state.volume,
4477
4535
  rate: state.rate > 0 ? state.rate : 1,
4478
4536
  loop: state.loop,
4479
- gravity: own.gravity ?? "resizeAspect",
4480
- controls: own.controls ?? true,
4537
+ gravity: options.gravity ?? "resizeAspect",
4538
+ controls: options.controls,
4481
4539
  seek: state.seek,
4482
4540
  ...state.size ? { width: state.size.width, height: state.size.height } : {}
4483
4541
  },
4484
4542
  { video: (event) => player.handle(event) }
4485
4543
  );
4544
+ }
4545
+ function VideoPlayer(props) {
4546
+ const { own, modifiers } = splitProps(props);
4547
+ const player = own.player;
4548
+ const state = useSyncExternalStore(
4549
+ player?.subscribe ?? NO_SUBSCRIBE,
4550
+ () => player?.snapshot ?? null,
4551
+ () => player?.snapshot ?? null
4552
+ );
4553
+ if (!player || !state || !state.url) return applyModifiers(sb("color", { color: { r: 0, g: 0, b: 0, a: 1 } }), modifiers);
4554
+ const video = videoElement(player, { ...state, url: state.url }, { gravity: own.gravity, controls: own.controls ?? true });
4486
4555
  if (own.videoOverlay === void 0) return applyModifiers(video, modifiers);
4487
4556
  return applyModifiers(
4488
4557
  sb("zstack", { alignment: "center" }, void 0, [/* @__PURE__ */ jsx(Fragment, { children: video }, "video"), /* @__PURE__ */ jsx(Fragment, { children: own.videoOverlay }, "overlay")]),
@@ -4491,6 +4560,20 @@ function VideoPlayer(props) {
4491
4560
  }
4492
4561
  const NO_SUBSCRIBE = () => () => {
4493
4562
  };
4563
+ function AudioPlayer({ player }) {
4564
+ const state = useSyncExternalStore(
4565
+ player?.subscribe ?? NO_SUBSCRIBE,
4566
+ () => player?.snapshot ?? null,
4567
+ () => player?.snapshot ?? null
4568
+ );
4569
+ if (!player || !state || !state.url) return null;
4570
+ return applyModifiers(videoElement(player, { ...state, url: state.url }, { gravity: "resizeAspect", controls: false }), [
4571
+ ["frame", { width: 0, height: 0 }],
4572
+ ["clipped", true],
4573
+ ["opacity", 0],
4574
+ ["allowsHitTesting", false]
4575
+ ]);
4576
+ }
4494
4577
  function PhaseAnimator({ phases, trigger, animation, children }) {
4495
4578
  const [index, setIndex] = useState(0);
4496
4579
  const hasTrigger = trigger !== void 0;
@@ -4605,9 +4688,11 @@ function KeyframeAnimator({
4605
4688
  }
4606
4689
  export {
4607
4690
  AVPlayer,
4691
+ AVQueuePlayer,
4608
4692
  AngularGradient,
4609
4693
  AreaMark,
4610
4694
  AsyncImage,
4695
+ AudioPlayer,
4611
4696
  BarMark,
4612
4697
  Button,
4613
4698
  Canvas,