react-native-tinyui 3.1.0 → 3.2.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 +76 -5
- package/ios/TipKit/TinyuiTipPopoverProvider.swift +29 -2
- package/ios/TipKit/TinyuiTipPopoverView.mm +10 -0
- package/ios/TipKit/TinyuiTipView.mm +9 -0
- package/ios/TipKit/TinyuiTipViewProvider.swift +8 -2
- package/ios/TipKit/TinyuiTipsRuntime.swift +12 -0
- package/lib/module/TipKit/Group.js +52 -0
- package/lib/module/TipKit/Group.js.map +1 -0
- package/lib/module/TipKit/Popover.js +15 -1
- package/lib/module/TipKit/Popover.js.map +1 -1
- package/lib/module/TipKit/TipPopoverNativeComponent.ts +7 -0
- package/lib/module/TipKit/TipViewNativeComponent.ts +6 -0
- package/lib/module/TipKit/View.js +13 -1
- package/lib/module/TipKit/View.js.map +1 -1
- package/lib/module/TipKit/index.js +2 -0
- package/lib/module/TipKit/index.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/TipKit/Group.d.ts +13 -0
- package/lib/typescript/src/TipKit/Group.d.ts.map +1 -0
- package/lib/typescript/src/TipKit/Popover.d.ts.map +1 -1
- package/lib/typescript/src/TipKit/TipPopoverNativeComponent.d.ts +5 -0
- package/lib/typescript/src/TipKit/TipPopoverNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/TipKit/TipViewNativeComponent.d.ts +4 -0
- package/lib/typescript/src/TipKit/TipViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/TipKit/View.d.ts.map +1 -1
- package/lib/typescript/src/TipKit/index.d.ts +3 -1
- package/lib/typescript/src/TipKit/index.d.ts.map +1 -1
- package/lib/typescript/src/TipKit/types.d.ts +18 -0
- package/lib/typescript/src/TipKit/types.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/TipKit/Group.tsx +76 -0
- package/src/TipKit/Popover.tsx +16 -2
- package/src/TipKit/TipPopoverNativeComponent.ts +7 -0
- package/src/TipKit/TipViewNativeComponent.ts +6 -0
- package/src/TipKit/View.tsx +14 -2
- package/src/TipKit/index.ts +4 -0
- package/src/TipKit/types.ts +24 -0
- package/src/index.tsx +2 -0
package/README.md
CHANGED
|
@@ -82,7 +82,7 @@ Available components:
|
|
|
82
82
|
- `Stepper`
|
|
83
83
|
- `ConcentricView`
|
|
84
84
|
- `SFSymbol`
|
|
85
|
-
- `TipKit` (enables `TipKit.View`, `TipKit.Popover`, `TipKit.configure`, `TipKit.resetDatastore` and `TipKit.invalidate`)
|
|
85
|
+
- `TipKit` (enables `TipKit.Group`, `TipKit.View`, `TipKit.Popover`, `TipKit.configure`, `TipKit.resetDatastore` and `TipKit.invalidate`)
|
|
86
86
|
|
|
87
87
|
`TipKit` is one optional module containing both native views,
|
|
88
88
|
`TinyuiTipPopoverView` and `TinyuiTipView`. Select it once in your app's
|
|
@@ -431,8 +431,77 @@ The remaining props are shared by both components:
|
|
|
431
431
|
| `ignoresDisplayFrequency` | Exempts this tip from the app-wide display interval | `false` |
|
|
432
432
|
| `arrowEdge` | `top`, `bottom`, `leading`, `trailing`; Popover also accepts `auto`, View accepts `none` | Popover: `auto`; View: `none` |
|
|
433
433
|
| `onActionPress` | Receives the selected `{ id, title }`; does not automatically invalidate | — |
|
|
434
|
+
| `onInvalidated` | Receives `{ reason }` when invalidated, including persisted invalidation on mount; Popover waits until dismissal finishes | — |
|
|
434
435
|
| `onError` | Receives `{ code, message }`; otherwise a warning is logged | — |
|
|
435
436
|
|
|
437
|
+
`TipKit.Popover` also accepts `invalidateOnOutsideDismiss`. It defaults to
|
|
438
|
+
`false`, or inherits its Group's value. When enabled, tapping outside the bubble
|
|
439
|
+
invalidates the tip with `tipClosed`. Programmatic hiding, disabling, unmounting
|
|
440
|
+
and leaving the screen do not themselves invalidate it.
|
|
441
|
+
|
|
442
|
+
### Ordered groups
|
|
443
|
+
|
|
444
|
+
`TipKit.Group` presents tips in the explicit `tipIds` order. It is a React
|
|
445
|
+
coordinator available on **iOS 17+**, backed by native TipKit eligibility and
|
|
446
|
+
persisted invalidation; it does not wrap Apple's iOS 18 `TipGroup` API.
|
|
447
|
+
`priority` currently supports only `ordered` and defaults to it. The Group adds
|
|
448
|
+
no layout view, so its tips can be nested in ordinary layout components.
|
|
449
|
+
|
|
450
|
+
```tsx
|
|
451
|
+
// At app startup, before mounting tips:
|
|
452
|
+
await TipKit.configure({ displayFrequency: 'immediate' });
|
|
453
|
+
|
|
454
|
+
// In your screen:
|
|
455
|
+
<TipKit.Group
|
|
456
|
+
priority="ordered"
|
|
457
|
+
tipIds={['favorite-v1', 'share-v1']}
|
|
458
|
+
enabled={isScreenFocused}
|
|
459
|
+
invalidateOnOutsideDismiss
|
|
460
|
+
>
|
|
461
|
+
<TipKit.Popover tipId="favorite-v1" title="Save your favorites">
|
|
462
|
+
<Button
|
|
463
|
+
title="Favorite"
|
|
464
|
+
onPress={async () => {
|
|
465
|
+
await TipKit.invalidate('favorite-v1', 'actionPerformed');
|
|
466
|
+
saveFavorite();
|
|
467
|
+
}}
|
|
468
|
+
/>
|
|
469
|
+
</TipKit.Popover>
|
|
470
|
+
<TipKit.Popover tipId="share-v1" title="Share with a friend">
|
|
471
|
+
<Button
|
|
472
|
+
title="Share"
|
|
473
|
+
onPress={async () => {
|
|
474
|
+
await TipKit.invalidate('share-v1', 'actionPerformed');
|
|
475
|
+
shareItem();
|
|
476
|
+
}}
|
|
477
|
+
/>
|
|
478
|
+
</TipKit.Popover>
|
|
479
|
+
</TipKit.Group>;
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
- The system close button, `TipKit.invalidate`, or native display limits complete
|
|
483
|
+
a step. The next tip is enabled after the preceding popover has finished
|
|
484
|
+
dismissing. Action buttons still require explicit invalidation.
|
|
485
|
+
- Outside dismissal does **not** complete a step by default. Opt in with
|
|
486
|
+
`invalidateOnOutsideDismiss`, either on the Group or an individual Popover.
|
|
487
|
+
An explicit Popover value overrides the Group's value.
|
|
488
|
+
- Already-invalidated tips are skipped when the group mounts again. Keep IDs
|
|
489
|
+
stable across launches. Progress is driven by native state, not JS storage.
|
|
490
|
+
- The next tip still obeys native eligibility and display frequency. Use
|
|
491
|
+
`immediate` at startup for consecutive tips; TinyUI otherwise defaults to
|
|
492
|
+
`daily`.
|
|
493
|
+
- Use each declared ID for one `TipKit.View` or `TipKit.Popover` in the group.
|
|
494
|
+
A missing, disabled or ineligible current tip blocks later tips. Keep the
|
|
495
|
+
current tip mounted and enabled until it reports invalidation; invalidate it
|
|
496
|
+
instead of immediately disabling it when its feature is used.
|
|
497
|
+
- `enabled={false}` pauses the group without completing a step. Groups are
|
|
498
|
+
independent; this is not a global queue for other tips, sheets or screens.
|
|
499
|
+
|
|
500
|
+
`onInvalidated` reports `actionPerformed`, `tipClosed`, `displayCountExceeded`,
|
|
501
|
+
`displayDurationExceeded`, or `unknown` for an unrecognized native reason.
|
|
502
|
+
It is a state notification, not an outside-dismiss callback, and can fire again
|
|
503
|
+
when an already-invalidated tip resumes observation.
|
|
504
|
+
|
|
436
505
|
Both components accept standard `ViewProps` and a native view ref. For Popover,
|
|
437
506
|
`style` lays out the anchor, not the bubble. UIKit chooses the bubble's size and may adapt
|
|
438
507
|
the arrow to available space; leading/trailing follow layout direction. Bubble
|
|
@@ -481,8 +550,9 @@ launch will erase users' tip history on every launch.
|
|
|
481
550
|
requires configuration first. It persistently invalidates the ID even when no
|
|
482
551
|
view for that tip is mounted. `reason` may be `actionPerformed` or `tipClosed`.
|
|
483
552
|
|
|
484
|
-
Both native views observe TipKit's `
|
|
485
|
-
the tip.
|
|
553
|
+
Both native views observe TipKit's `statusUpdates` to show or remove
|
|
554
|
+
the tip. Invalidation is sent to JavaScript through `onInvalidated`; other
|
|
555
|
+
eligibility and visibility changes are not sent to JavaScript.
|
|
486
556
|
Call `invalidate` with `actionPerformed` after the feature is used, or with
|
|
487
557
|
`tipClosed` to permanently dismiss the tip. TipKit also handles the system
|
|
488
558
|
close button and display limits.
|
|
@@ -496,7 +566,7 @@ with the same ID share their TipKit history. Keep `maxDisplayCount` and
|
|
|
496
566
|
tip. Hiding a tip, unmounting it or reconfiguring TinyUI never resets history.
|
|
497
567
|
|
|
498
568
|
Use `enabled={isScreenFocused && businessCondition}` with your navigation
|
|
499
|
-
library. Each mounted, enabled Popover anchor starts its own `
|
|
569
|
+
library. Each mounted, enabled Popover anchor starts its own `statusUpdates`
|
|
500
570
|
observation once it has a size and a parent view controller. Disabling,
|
|
501
571
|
detaching or recycling the component stops observation and dismisses its
|
|
502
572
|
bubble; changing `tipId` starts a new observation. This follows the independent
|
|
@@ -517,7 +587,8 @@ detached or recycled. They do not present a view controller or block interaction
|
|
|
517
587
|
with the rest of the screen. Both presentations use the same datastore; an
|
|
518
588
|
invalidation affects every instance of the same `tipId`.
|
|
519
589
|
|
|
520
|
-
Native rule/event builders and TipGroup are not exposed.
|
|
590
|
+
Native rule/event builders and Apple's TipGroup are not exposed. Use the
|
|
591
|
+
React `TipKit.Group` above for ordered presentation. The example's
|
|
521
592
|
**Inline view** switch toggles between both presentations. Its **New demo tip**
|
|
522
593
|
button deliberately creates another
|
|
523
594
|
ID for trying the behavior again without clearing the app's TipKit datastore.
|
|
@@ -4,6 +4,7 @@ import UIKit
|
|
|
4
4
|
@objc public protocol TinyuiTipPopoverDelegate: AnyObject {
|
|
5
5
|
func onTipAction(tipId: String, id: String, title: String)
|
|
6
6
|
func onTipError(tipId: String, code: String, message: String)
|
|
7
|
+
func onTipInvalidated(tipId: String, reason: String)
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
@MainActor
|
|
@@ -26,6 +27,8 @@ import UIKit
|
|
|
26
27
|
private var presentedTipId: String?
|
|
27
28
|
private var isPresenting = false
|
|
28
29
|
private var isDismissing = false
|
|
30
|
+
private var invalidateOnOutsideDismiss = false
|
|
31
|
+
private var pendingInvalidation: (tipId: String, reason: String)?
|
|
29
32
|
|
|
30
33
|
@objc public convenience init(delegate: TinyuiTipPopoverDelegate) {
|
|
31
34
|
self.init(frame: .zero)
|
|
@@ -34,6 +37,7 @@ import UIKit
|
|
|
34
37
|
|
|
35
38
|
@objc public func configure(_ configuration: [String: Any], enabled: Bool, arrowEdge: String) {
|
|
36
39
|
let nextTip = TinyuiTip(configuration: configuration)
|
|
40
|
+
if tip?.id != nextTip.id { pendingInvalidation = nil }
|
|
37
41
|
if tip?.id != nextTip.id || self.enabled != enabled {
|
|
38
42
|
stop()
|
|
39
43
|
lastError = nil
|
|
@@ -41,6 +45,7 @@ import UIKit
|
|
|
41
45
|
tip = nextTip
|
|
42
46
|
self.enabled = enabled
|
|
43
47
|
self.arrowEdge = arrowEdge
|
|
48
|
+
invalidateOnOutsideDismiss = configuration["invalidateOnOutsideDismiss"] as? Bool ?? false
|
|
44
49
|
// Validate changed options even when an observation is already running.
|
|
45
50
|
do {
|
|
46
51
|
try TinyuiTipsRuntime.shared.remember(nextTip)
|
|
@@ -87,10 +92,16 @@ import UIKit
|
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
observation = Task { @MainActor [weak self] in
|
|
90
|
-
|
|
95
|
+
var reportedInvalidation = false
|
|
96
|
+
for await status in tip.statusUpdates {
|
|
91
97
|
guard !Task.isCancelled, let self else { break }
|
|
92
|
-
self.shouldDisplay = shouldDisplay
|
|
98
|
+
if case .available = status { self.shouldDisplay = true } else { self.shouldDisplay = false }
|
|
99
|
+
if case .invalidated(let reason) = status, !reportedInvalidation {
|
|
100
|
+
reportedInvalidation = true
|
|
101
|
+
self.pendingInvalidation = (tip.id, TinyuiTipsRuntime.invalidationReason(reason))
|
|
102
|
+
}
|
|
93
103
|
self.updatePresentation()
|
|
104
|
+
self.reportInvalidationIfDismissed()
|
|
94
105
|
}
|
|
95
106
|
}
|
|
96
107
|
}
|
|
@@ -178,11 +189,25 @@ import UIKit
|
|
|
178
189
|
presentedTipId = nil
|
|
179
190
|
isPresenting = false
|
|
180
191
|
isDismissing = false
|
|
192
|
+
reportInvalidationIfDismissed()
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private func reportInvalidationIfDismissed() {
|
|
196
|
+
// The next grouped anchor must not present until this transition finishes.
|
|
197
|
+
guard controller == nil, let event = pendingInvalidation else { return }
|
|
198
|
+
pendingInvalidation = nil
|
|
199
|
+
delegate?.onTipInvalidated(tipId: event.tipId, reason: event.reason)
|
|
181
200
|
}
|
|
182
201
|
|
|
183
202
|
public func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
|
|
184
203
|
guard let controller, presentationController.presentedViewController === controller else { return }
|
|
204
|
+
let dismissedTip = presentedTipId == tip?.id ? tip : nil
|
|
205
|
+
let shouldInvalidate = invalidateOnOutsideDismiss && !isDismissing
|
|
185
206
|
finishDismissal(controller)
|
|
207
|
+
// Programmatic hiding, navigation and recycling do not complete a tip.
|
|
208
|
+
if shouldInvalidate, let dismissedTip, case .available = dismissedTip.status {
|
|
209
|
+
dismissedTip.invalidate(reason: .tipClosed)
|
|
210
|
+
}
|
|
186
211
|
}
|
|
187
212
|
|
|
188
213
|
public func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { .none }
|
|
@@ -199,6 +224,8 @@ import UIKit
|
|
|
199
224
|
enabled = false
|
|
200
225
|
tip = nil
|
|
201
226
|
lastError = nil
|
|
227
|
+
pendingInvalidation = nil
|
|
228
|
+
invalidateOnOutsideDismiss = false
|
|
202
229
|
stop()
|
|
203
230
|
parentViewController = nil
|
|
204
231
|
}
|
|
@@ -65,6 +65,7 @@ using namespace facebook::react;
|
|
|
65
65
|
@"actions": actions,
|
|
66
66
|
@"maxDisplayCount": @(next.maxDisplayCount),
|
|
67
67
|
@"ignoresDisplayFrequency": @(next.ignoresDisplayFrequency),
|
|
68
|
+
@"invalidateOnOutsideDismiss": @(next.invalidateOnOutsideDismiss),
|
|
68
69
|
} enabled:next.enabled arrowEdge:RCTNSStringFromString(next.arrowEdge)];
|
|
69
70
|
[super updateProps:props oldProps:oldProps];
|
|
70
71
|
}
|
|
@@ -87,6 +88,15 @@ using namespace facebook::react;
|
|
|
87
88
|
});
|
|
88
89
|
}
|
|
89
90
|
|
|
91
|
+
- (void)onTipInvalidatedWithTipId:(NSString *)tipId reason:(NSString *)reason
|
|
92
|
+
{
|
|
93
|
+
if (_eventEmitter == nullptr) return;
|
|
94
|
+
std::static_pointer_cast<const TinyuiTipPopoverViewEventEmitter>(_eventEmitter)->onTipInvalidated({
|
|
95
|
+
.tipId = std::string(tipId.UTF8String ?: ""),
|
|
96
|
+
.reason = std::string(reason.UTF8String ?: "unknown"),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
90
100
|
- (void)prepareForRecycle
|
|
91
101
|
{
|
|
92
102
|
[_provider reset];
|
|
@@ -83,6 +83,15 @@ using namespace facebook::react;
|
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
- (void)onTipInvalidatedWithTipId:(NSString *)tipId reason:(NSString *)reason
|
|
87
|
+
{
|
|
88
|
+
if (_eventEmitter == nullptr) return;
|
|
89
|
+
std::static_pointer_cast<const TinyuiTipViewEventEmitter>(_eventEmitter)->onTipInvalidated({
|
|
90
|
+
.tipId = std::string(tipId.UTF8String ?: ""),
|
|
91
|
+
.reason = std::string(reason.UTF8String ?: "unknown"),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
86
95
|
- (void)prepareForRecycle
|
|
87
96
|
{
|
|
88
97
|
_state.reset();
|
|
@@ -5,6 +5,7 @@ import UIKit
|
|
|
5
5
|
@objc public protocol TinyuiTipViewDelegate: AnyObject {
|
|
6
6
|
func onTipAction(tipId: String, id: String, title: String)
|
|
7
7
|
func onTipError(tipId: String, code: String, message: String)
|
|
8
|
+
func onTipInvalidated(tipId: String, reason: String)
|
|
8
9
|
// Fabric consumes this size directly; it is not a JavaScript event.
|
|
9
10
|
func onTipSizeChange(tipId: String, width: CGFloat, height: CGFloat)
|
|
10
11
|
}
|
|
@@ -69,9 +70,14 @@ import UIKit
|
|
|
69
70
|
return
|
|
70
71
|
}
|
|
71
72
|
observation = Task { @MainActor [weak self] in
|
|
72
|
-
|
|
73
|
+
var reportedInvalidation = false
|
|
74
|
+
for await status in tip.statusUpdates {
|
|
73
75
|
guard !Task.isCancelled, let self else { break }
|
|
74
|
-
if
|
|
76
|
+
if case .available = status { self.showTip() } else { self.removeTip() }
|
|
77
|
+
if case .invalidated(let reason) = status, !reportedInvalidation {
|
|
78
|
+
reportedInvalidation = true
|
|
79
|
+
self.delegate?.onTipInvalidated(tipId: tip.id, reason: TinyuiTipsRuntime.invalidationReason(reason))
|
|
80
|
+
}
|
|
75
81
|
}
|
|
76
82
|
}
|
|
77
83
|
}
|
|
@@ -80,6 +80,18 @@ import Foundation
|
|
|
80
80
|
])
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
static func invalidationReason(_ reason: Tips.InvalidationReason) -> String {
|
|
84
|
+
if #available(iOS 18.0, *), reason == .displayDurationExceeded {
|
|
85
|
+
return "displayDurationExceeded"
|
|
86
|
+
}
|
|
87
|
+
switch reason {
|
|
88
|
+
case .actionPerformed: return "actionPerformed"
|
|
89
|
+
case .tipClosed: return "tipClosed"
|
|
90
|
+
case .displayCountExceeded: return "displayCountExceeded"
|
|
91
|
+
default: return "unknown"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
83
95
|
func remember(_ tip: TinyuiTip) throws {
|
|
84
96
|
if let previous = knownTips[tip.id],
|
|
85
97
|
previous.maximumDisplayCount != tip.maximumDisplayCount || previous.ignoresFrequency != tip.ignoresFrequency {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
|
4
|
+
import { assertComponentEnabled } from "../utils/index.js";
|
|
5
|
+
import { validateTipId } from "./validation.js";
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
const GroupContext = /*#__PURE__*/createContext(null);
|
|
8
|
+
|
|
9
|
+
/** Orders tips by ID while native TipKit owns eligibility and persisted history. */
|
|
10
|
+
export function Group({
|
|
11
|
+
tipIds,
|
|
12
|
+
priority = 'ordered',
|
|
13
|
+
enabled = true,
|
|
14
|
+
invalidateOnOutsideDismiss = false,
|
|
15
|
+
children
|
|
16
|
+
}) {
|
|
17
|
+
assertComponentEnabled('TipKit');
|
|
18
|
+
if (priority !== 'ordered') {
|
|
19
|
+
throw new Error('[TinyUI] TipKit.Group only supports ordered priority.');
|
|
20
|
+
}
|
|
21
|
+
const ids = new Set();
|
|
22
|
+
for (const tipId of tipIds) {
|
|
23
|
+
validateTipId(tipId);
|
|
24
|
+
if (ids.has(tipId)) {
|
|
25
|
+
throw new Error('[TinyUI] TipKit.Group tipIds must be unique.');
|
|
26
|
+
}
|
|
27
|
+
ids.add(tipId);
|
|
28
|
+
}
|
|
29
|
+
const [completed, setCompleted] = useState(() => new Set());
|
|
30
|
+
const complete = useCallback(tipId => {
|
|
31
|
+
setCompleted(previous => previous.has(tipId) ? previous : new Set([...previous, tipId]));
|
|
32
|
+
}, []);
|
|
33
|
+
const value = useMemo(() => ({
|
|
34
|
+
tipIds: new Set(tipIds),
|
|
35
|
+
currentTipId: tipIds.find(id => !completed.has(id)),
|
|
36
|
+
enabled,
|
|
37
|
+
invalidateOnOutsideDismiss,
|
|
38
|
+
complete
|
|
39
|
+
}), [tipIds, completed, enabled, invalidateOnOutsideDismiss, complete]);
|
|
40
|
+
return /*#__PURE__*/_jsx(GroupContext.Provider, {
|
|
41
|
+
value: value,
|
|
42
|
+
children: children
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export function useTipGroup(tipId) {
|
|
46
|
+
const group = useContext(GroupContext);
|
|
47
|
+
if (group && !group.tipIds.has(tipId)) {
|
|
48
|
+
throw new Error(`[TinyUI] TipKit tipId "${tipId}" is missing from its Group's tipIds.`);
|
|
49
|
+
}
|
|
50
|
+
return group;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=Group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createContext","useCallback","useContext","useMemo","useState","assertComponentEnabled","validateTipId","jsx","_jsx","GroupContext","Group","tipIds","priority","enabled","invalidateOnOutsideDismiss","children","Error","ids","Set","tipId","has","add","completed","setCompleted","complete","previous","value","currentTipId","find","id","Provider","useTipGroup","group"],"sourceRoot":"../../../src","sources":["TipKit/Group.tsx"],"mappings":";;AAAA,SACEA,aAAa,EACbC,WAAW,EACXC,UAAU,EACVC,OAAO,EACPC,QAAQ,QACH,OAAO;AAEd,SAASC,sBAAsB,QAAQ,mBAAU;AAEjD,SAASC,aAAa,QAAQ,iBAAc;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAU7C,MAAMC,YAAY,gBAAGT,aAAa,CAA2B,IAAI,CAAC;;AAElE;AACA,OAAO,SAASU,KAAKA,CAAC;EACpBC,MAAM;EACNC,QAAQ,GAAG,SAAS;EACpBC,OAAO,GAAG,IAAI;EACdC,0BAA0B,GAAG,KAAK;EAClCC;AACa,CAAC,EAAE;EAChBV,sBAAsB,CAAC,QAAQ,CAAC;EAChC,IAAIO,QAAQ,KAAK,SAAS,EAAE;IAC1B,MAAM,IAAII,KAAK,CAAC,uDAAuD,CAAC;EAC1E;EACA,MAAMC,GAAG,GAAG,IAAIC,GAAG,CAAS,CAAC;EAC7B,KAAK,MAAMC,KAAK,IAAIR,MAAM,EAAE;IAC1BL,aAAa,CAACa,KAAK,CAAC;IACpB,IAAIF,GAAG,CAACG,GAAG,CAACD,KAAK,CAAC,EAAE;MAClB,MAAM,IAAIH,KAAK,CAAC,8CAA8C,CAAC;IACjE;IACAC,GAAG,CAACI,GAAG,CAACF,KAAK,CAAC;EAChB;EAEA,MAAM,CAACG,SAAS,EAAEC,YAAY,CAAC,GAAGnB,QAAQ,CACxC,MAAM,IAAIc,GAAG,CAAC,CAChB,CAAC;EACD,MAAMM,QAAQ,GAAGvB,WAAW,CAAEkB,KAAa,IAAK;IAC9CI,YAAY,CAAEE,QAAQ,IACpBA,QAAQ,CAACL,GAAG,CAACD,KAAK,CAAC,GAAGM,QAAQ,GAAG,IAAIP,GAAG,CAAC,CAAC,GAAGO,QAAQ,EAAEN,KAAK,CAAC,CAC/D,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EACN,MAAMO,KAAK,GAAGvB,OAAO,CACnB,OAAO;IACLQ,MAAM,EAAE,IAAIO,GAAG,CAACP,MAAM,CAAC;IACvBgB,YAAY,EAAEhB,MAAM,CAACiB,IAAI,CAAEC,EAAE,IAAK,CAACP,SAAS,CAACF,GAAG,CAACS,EAAE,CAAC,CAAC;IACrDhB,OAAO;IACPC,0BAA0B;IAC1BU;EACF,CAAC,CAAC,EACF,CAACb,MAAM,EAAEW,SAAS,EAAET,OAAO,EAAEC,0BAA0B,EAAEU,QAAQ,CACnE,CAAC;EAED,oBACEhB,IAAA,CAACC,YAAY,CAACqB,QAAQ;IAACJ,KAAK,EAAEA,KAAM;IAAAX,QAAA,EAAEA;EAAQ,CAAwB,CAAC;AAE3E;AAEA,OAAO,SAASgB,WAAWA,CAACZ,KAAa,EAAE;EACzC,MAAMa,KAAK,GAAG9B,UAAU,CAACO,YAAY,CAAC;EACtC,IAAIuB,KAAK,IAAI,CAACA,KAAK,CAACrB,MAAM,CAACS,GAAG,CAACD,KAAK,CAAC,EAAE;IACrC,MAAM,IAAIH,KAAK,CACb,0BAA0BG,KAAK,uCACjC,CAAC;EACH;EACA,OAAOa,KAAK;AACd","ignoreList":[]}
|
|
@@ -5,10 +5,12 @@ import { View } from 'react-native';
|
|
|
5
5
|
import { assertComponentEnabled } from "../utils/index.js";
|
|
6
6
|
import NativeTipPopoverView from './TipPopoverNativeComponent';
|
|
7
7
|
import { validateTip } from "./validation.js";
|
|
8
|
+
import { useTipGroup } from "./Group.js";
|
|
8
9
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
10
|
export const Popover = /*#__PURE__*/forwardRef(function TipPopoverRoot(props, ref) {
|
|
10
11
|
assertComponentEnabled('TipKit');
|
|
11
12
|
validateTip(props);
|
|
13
|
+
const group = useTipGroup(props.tipId);
|
|
12
14
|
const {
|
|
13
15
|
children,
|
|
14
16
|
tipId,
|
|
@@ -21,6 +23,8 @@ export const Popover = /*#__PURE__*/forwardRef(function TipPopoverRoot(props, re
|
|
|
21
23
|
ignoresDisplayFrequency = false,
|
|
22
24
|
arrowEdge = 'auto',
|
|
23
25
|
onActionPress,
|
|
26
|
+
onInvalidated,
|
|
27
|
+
invalidateOnOutsideDismiss = group?.invalidateOnOutsideDismiss ?? false,
|
|
24
28
|
onError,
|
|
25
29
|
...viewProps
|
|
26
30
|
} = props;
|
|
@@ -33,7 +37,8 @@ export const Popover = /*#__PURE__*/forwardRef(function TipPopoverRoot(props, re
|
|
|
33
37
|
message: message,
|
|
34
38
|
systemImage: systemImage,
|
|
35
39
|
actions: actions,
|
|
36
|
-
enabled: enabled,
|
|
40
|
+
enabled: enabled && (!group || group.enabled && group.currentTipId === tipId),
|
|
41
|
+
invalidateOnOutsideDismiss: invalidateOnOutsideDismiss,
|
|
37
42
|
maxDisplayCount: maxDisplayCount ?? 0,
|
|
38
43
|
ignoresDisplayFrequency: ignoresDisplayFrequency,
|
|
39
44
|
arrowEdge: arrowEdge,
|
|
@@ -47,6 +52,15 @@ export const Popover = /*#__PURE__*/forwardRef(function TipPopoverRoot(props, re
|
|
|
47
52
|
});
|
|
48
53
|
}
|
|
49
54
|
},
|
|
55
|
+
onTipInvalidated: ({
|
|
56
|
+
nativeEvent
|
|
57
|
+
}) => {
|
|
58
|
+
if (nativeEvent.tipId !== tipId) return;
|
|
59
|
+
group?.complete(tipId);
|
|
60
|
+
onInvalidated?.({
|
|
61
|
+
reason: nativeEvent.reason
|
|
62
|
+
});
|
|
63
|
+
},
|
|
50
64
|
onTipError: ({
|
|
51
65
|
nativeEvent
|
|
52
66
|
}) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["forwardRef","View","assertComponentEnabled","NativeTipPopoverView","validateTip","jsx","_jsx","Popover","TipPopoverRoot","props","ref","
|
|
1
|
+
{"version":3,"names":["forwardRef","View","assertComponentEnabled","NativeTipPopoverView","validateTip","useTipGroup","jsx","_jsx","Popover","TipPopoverRoot","props","ref","group","tipId","children","title","message","systemImage","actions","enabled","maxDisplayCount","ignoresDisplayFrequency","arrowEdge","onActionPress","onInvalidated","invalidateOnOutsideDismiss","onError","viewProps","collapsable","currentTipId","onTipAction","nativeEvent","id","onTipInvalidated","complete","reason","onTipError","error","code","console","warn","displayName"],"sourceRoot":"../../../src","sources":["TipKit/Popover.tsx"],"mappings":";;AAAA,SAASA,UAAU,QAA2B,OAAO;AACrD,SAASC,IAAI,QAAQ,cAAc;AAEnC,SAASC,sBAAsB,QAAQ,mBAAU;AACjD,OAAOC,oBAAoB,MAAM,6BAA6B;AAE9D,SAASC,WAAW,QAAQ,iBAAc;AAC1C,SAASC,WAAW,QAAQ,YAAS;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAEtC,OAAO,MAAMC,OAAO,gBAAGR,UAAU,CAC/B,SAASS,cAAcA,CAACC,KAAK,EAAEC,GAAG,EAAE;EAClCT,sBAAsB,CAAC,QAAQ,CAAC;EAChCE,WAAW,CAACM,KAAK,CAAC;EAClB,MAAME,KAAK,GAAGP,WAAW,CAACK,KAAK,CAACG,KAAK,CAAC;EACtC,MAAM;IACJC,QAAQ;IACRD,KAAK;IACLE,KAAK;IACLC,OAAO;IACPC,WAAW;IACXC,OAAO;IACPC,OAAO,GAAG,IAAI;IACdC,eAAe;IACfC,uBAAuB,GAAG,KAAK;IAC/BC,SAAS,GAAG,MAAM;IAClBC,aAAa;IACbC,aAAa;IACbC,0BAA0B,GAAGb,KAAK,EAAEa,0BAA0B,IAAI,KAAK;IACvEC,OAAO;IACP,GAAGC;EACL,CAAC,GAAGjB,KAAK;EAET,oBACEH,IAAA,CAACJ,oBAAoB;IAAA,GACfwB,SAAS;IACbhB,GAAG,EAAEA,GAAI;IACTiB,WAAW,EAAE,KAAM;IACnBf,KAAK,EAAEA,KAAM;IACbE,KAAK,EAAEA,KAAM;IACbC,OAAO,EAAEA,OAAQ;IACjBC,WAAW,EAAEA,WAAY;IACzBC,OAAO,EAAEA,OAAQ;IACjBC,OAAO,EACLA,OAAO,KAAK,CAACP,KAAK,IAAKA,KAAK,CAACO,OAAO,IAAIP,KAAK,CAACiB,YAAY,KAAKhB,KAAM,CACtE;IACDY,0BAA0B,EAAEA,0BAA2B;IACvDL,eAAe,EAAEA,eAAe,IAAI,CAAE;IACtCC,uBAAuB,EAAEA,uBAAwB;IACjDC,SAAS,EAAEA,SAAU;IACrBQ,WAAW,EAAEA,CAAC;MAAEC;IAAY,CAAC,KAAK;MAChC,IAAIA,WAAW,CAAClB,KAAK,KAAKA,KAAK,EAAE;QAC/BU,aAAa,GAAG;UAAES,EAAE,EAAED,WAAW,CAACC,EAAE;UAAEjB,KAAK,EAAEgB,WAAW,CAAChB;QAAM,CAAC,CAAC;MACnE;IACF,CAAE;IACFkB,gBAAgB,EAAEA,CAAC;MAAEF;IAAY,CAAC,KAAK;MACrC,IAAIA,WAAW,CAAClB,KAAK,KAAKA,KAAK,EAAE;MACjCD,KAAK,EAAEsB,QAAQ,CAACrB,KAAK,CAAC;MACtBW,aAAa,GAAG;QACdW,MAAM,EAAEJ,WAAW,CAACI;MACtB,CAAC,CAAC;IACJ,CAAE;IACFC,UAAU,EAAEA,CAAC;MAAEL;IAAY,CAAC,KAAK;MAC/B,IAAIA,WAAW,CAAClB,KAAK,KAAKA,KAAK,EAAE;MACjC,MAAMwB,KAAK,GAAG;QACZC,IAAI,EAAEP,WAAW,CAACO,IAAI;QACtBtB,OAAO,EAAEe,WAAW,CAACf;MACvB,CAAC;MACD,IAAIU,OAAO,EAAEA,OAAO,CAACW,KAAK,CAAC,CAAC,KAE1BE,OAAO,CAACC,IAAI,CACV,2BAA2BH,KAAK,CAACC,IAAI,KAAKD,KAAK,CAACrB,OAAO,EACzD,CAAC;IACL,CAAE;IAAAF,QAAA,eAEFP,IAAA,CAACN,IAAI;MAAC2B,WAAW,EAAE,KAAM;MAAAd,QAAA,EAAEA;IAAQ,CAAO;EAAC,CACvB,CAAC;AAE3B,CACF,CAAC;AAEDN,OAAO,CAACiC,WAAW,GAAG,gBAAgB","ignoreList":[]}
|
|
@@ -12,6 +12,7 @@ export interface NativeTipPopoverProps extends ViewProps {
|
|
|
12
12
|
systemImage?: string;
|
|
13
13
|
actions?: ReadonlyArray<Readonly<{ id: string; title: string }>>;
|
|
14
14
|
enabled?: boolean;
|
|
15
|
+
invalidateOnOutsideDismiss?: boolean;
|
|
15
16
|
maxDisplayCount?: CodegenTypes.Int32;
|
|
16
17
|
ignoresDisplayFrequency?: boolean;
|
|
17
18
|
arrowEdge?: string;
|
|
@@ -21,6 +22,12 @@ export interface NativeTipPopoverProps extends ViewProps {
|
|
|
21
22
|
onTipError?: DirectEventHandler<
|
|
22
23
|
Readonly<{ tipId: string; code: string; message: string }>
|
|
23
24
|
>;
|
|
25
|
+
onTipInvalidated?: DirectEventHandler<
|
|
26
|
+
Readonly<{
|
|
27
|
+
tipId: string;
|
|
28
|
+
reason: string;
|
|
29
|
+
}>
|
|
30
|
+
>;
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
export default codegenNativeComponent<NativeTipPopoverProps>(
|
|
@@ -21,6 +21,12 @@ export interface NativeTipViewProps extends ViewProps {
|
|
|
21
21
|
onTipError?: DirectEventHandler<
|
|
22
22
|
Readonly<{ tipId: string; code: string; message: string }>
|
|
23
23
|
>;
|
|
24
|
+
onTipInvalidated?: DirectEventHandler<
|
|
25
|
+
Readonly<{
|
|
26
|
+
tipId: string;
|
|
27
|
+
reason: string;
|
|
28
|
+
}>
|
|
29
|
+
>;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
export default codegenNativeComponent<NativeTipViewProps>('TinyuiTipView', {
|
|
@@ -4,10 +4,12 @@ import { forwardRef } from 'react';
|
|
|
4
4
|
import { assertComponentEnabled } from "../utils/index.js";
|
|
5
5
|
import NativeTipView from './TipViewNativeComponent';
|
|
6
6
|
import { validateTip } from "./validation.js";
|
|
7
|
+
import { useTipGroup } from "./Group.js";
|
|
7
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
9
|
export const View = /*#__PURE__*/forwardRef(function TipViewRoot(props, ref) {
|
|
9
10
|
assertComponentEnabled('TipKit');
|
|
10
11
|
validateTip(props, 'TipKit.View');
|
|
12
|
+
const group = useTipGroup(props.tipId);
|
|
11
13
|
const {
|
|
12
14
|
tipId,
|
|
13
15
|
title,
|
|
@@ -19,6 +21,7 @@ export const View = /*#__PURE__*/forwardRef(function TipViewRoot(props, ref) {
|
|
|
19
21
|
ignoresDisplayFrequency = false,
|
|
20
22
|
arrowEdge = 'none',
|
|
21
23
|
onActionPress,
|
|
24
|
+
onInvalidated,
|
|
22
25
|
onError,
|
|
23
26
|
...viewProps
|
|
24
27
|
} = props;
|
|
@@ -32,7 +35,7 @@ export const View = /*#__PURE__*/forwardRef(function TipViewRoot(props, ref) {
|
|
|
32
35
|
message: message,
|
|
33
36
|
systemImage: systemImage,
|
|
34
37
|
actions: actions,
|
|
35
|
-
enabled: enabled,
|
|
38
|
+
enabled: enabled && (!group || group.enabled && group.currentTipId === tipId),
|
|
36
39
|
maxDisplayCount: maxDisplayCount ?? 0,
|
|
37
40
|
ignoresDisplayFrequency: ignoresDisplayFrequency,
|
|
38
41
|
arrowEdge: arrowEdge,
|
|
@@ -46,6 +49,15 @@ export const View = /*#__PURE__*/forwardRef(function TipViewRoot(props, ref) {
|
|
|
46
49
|
});
|
|
47
50
|
}
|
|
48
51
|
},
|
|
52
|
+
onTipInvalidated: ({
|
|
53
|
+
nativeEvent
|
|
54
|
+
}) => {
|
|
55
|
+
if (nativeEvent.tipId !== tipId) return;
|
|
56
|
+
group?.complete(tipId);
|
|
57
|
+
onInvalidated?.({
|
|
58
|
+
reason: nativeEvent.reason
|
|
59
|
+
});
|
|
60
|
+
},
|
|
49
61
|
onTipError: ({
|
|
50
62
|
nativeEvent
|
|
51
63
|
}) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["forwardRef","assertComponentEnabled","NativeTipView","validateTip","jsx","_jsx","View","TipViewRoot","props","ref","tipId","title","message","systemImage","actions","enabled","maxDisplayCount","ignoresDisplayFrequency","arrowEdge","onActionPress","onError","viewProps","children","undefined","collapsable","onTipAction","nativeEvent","id","onTipError","error","code","console","warn","displayName"],"sourceRoot":"../../../src","sources":["TipKit/View.tsx"],"mappings":";;AAAA,SAASA,UAAU,QAA2B,OAAO;AAGrD,SAASC,sBAAsB,QAAQ,mBAAU;AACjD,OAAOC,aAAa,MAAM,0BAA0B;AAEpD,SAASC,WAAW,QAAQ,iBAAc;AAAC,SAAAC,GAAA,IAAAC,IAAA;
|
|
1
|
+
{"version":3,"names":["forwardRef","assertComponentEnabled","NativeTipView","validateTip","useTipGroup","jsx","_jsx","View","TipViewRoot","props","ref","group","tipId","title","message","systemImage","actions","enabled","maxDisplayCount","ignoresDisplayFrequency","arrowEdge","onActionPress","onInvalidated","onError","viewProps","children","undefined","collapsable","currentTipId","onTipAction","nativeEvent","id","onTipInvalidated","complete","reason","onTipError","error","code","console","warn","displayName"],"sourceRoot":"../../../src","sources":["TipKit/View.tsx"],"mappings":";;AAAA,SAASA,UAAU,QAA2B,OAAO;AAGrD,SAASC,sBAAsB,QAAQ,mBAAU;AACjD,OAAOC,aAAa,MAAM,0BAA0B;AAEpD,SAASC,WAAW,QAAQ,iBAAc;AAC1C,SAASC,WAAW,QAAQ,YAAS;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAEtC,OAAO,MAAMC,IAAI,gBAAGP,UAAU,CAG5B,SAASQ,WAAWA,CAACC,KAAK,EAAEC,GAAG,EAAE;EACjCT,sBAAsB,CAAC,QAAQ,CAAC;EAChCE,WAAW,CAACM,KAAK,EAAE,aAAa,CAAC;EACjC,MAAME,KAAK,GAAGP,WAAW,CAACK,KAAK,CAACG,KAAK,CAAC;EACtC,MAAM;IACJA,KAAK;IACLC,KAAK;IACLC,OAAO;IACPC,WAAW;IACXC,OAAO;IACPC,OAAO,GAAG,IAAI;IACdC,eAAe;IACfC,uBAAuB,GAAG,KAAK;IAC/BC,SAAS,GAAG,MAAM;IAClBC,aAAa;IACbC,aAAa;IACbC,OAAO;IACP,GAAGC;EACL,CAAC,GAAGf,KAAK;EAET,oBACEH,IAAA,CAACJ,aAAa;IAAA,GACRsB,SAAS;IACbC,QAAQ,EAAEC,SAAU;IACpBhB,GAAG,EAAEA,GAAI;IACTiB,WAAW,EAAE,KAAM;IACnBf,KAAK,EAAEA,KAAM;IACbC,KAAK,EAAEA,KAAM;IACbC,OAAO,EAAEA,OAAQ;IACjBC,WAAW,EAAEA,WAAY;IACzBC,OAAO,EAAEA,OAAQ;IACjBC,OAAO,EACLA,OAAO,KAAK,CAACN,KAAK,IAAKA,KAAK,CAACM,OAAO,IAAIN,KAAK,CAACiB,YAAY,KAAKhB,KAAM,CACtE;IACDM,eAAe,EAAEA,eAAe,IAAI,CAAE;IACtCC,uBAAuB,EAAEA,uBAAwB;IACjDC,SAAS,EAAEA,SAAU;IACrBS,WAAW,EAAEA,CAAC;MAAEC;IAAY,CAAC,KAAK;MAChC,IAAIA,WAAW,CAAClB,KAAK,KAAKA,KAAK,EAAE;QAC/BS,aAAa,GAAG;UAAEU,EAAE,EAAED,WAAW,CAACC,EAAE;UAAElB,KAAK,EAAEiB,WAAW,CAACjB;QAAM,CAAC,CAAC;MACnE;IACF,CAAE;IACFmB,gBAAgB,EAAEA,CAAC;MAAEF;IAAY,CAAC,KAAK;MACrC,IAAIA,WAAW,CAAClB,KAAK,KAAKA,KAAK,EAAE;MACjCD,KAAK,EAAEsB,QAAQ,CAACrB,KAAK,CAAC;MACtBU,aAAa,GAAG;QACdY,MAAM,EAAEJ,WAAW,CAACI;MACtB,CAAC,CAAC;IACJ,CAAE;IACFC,UAAU,EAAEA,CAAC;MAAEL;IAAY,CAAC,KAAK;MAC/B,IAAIA,WAAW,CAAClB,KAAK,KAAKA,KAAK,EAAE;MACjC,MAAMwB,KAAK,GAAG;QACZC,IAAI,EAAEP,WAAW,CAACO,IAAI;QACtBvB,OAAO,EAAEgB,WAAW,CAAChB;MACvB,CAAC;MACD,IAAIS,OAAO,EAAEA,OAAO,CAACa,KAAK,CAAC,CAAC,KAE1BE,OAAO,CAACC,IAAI,CAAC,wBAAwBH,KAAK,CAACC,IAAI,KAAKD,KAAK,CAACtB,OAAO,EAAE,CAAC;IACxE;EAAE,CACH,CAAC;AAEN,CAAC,CAAC;AAEFP,IAAI,CAACiC,WAAW,GAAG,aAAa","ignoreList":[]}
|
|
@@ -4,7 +4,9 @@ import { assertComponentEnabled, getNativeTinyui } from "../utils/index.js";
|
|
|
4
4
|
import { validateTipId } from "./validation.js";
|
|
5
5
|
import { Popover } from "./Popover.js";
|
|
6
6
|
import { View } from "./View.js";
|
|
7
|
+
import { Group } from "./Group.js";
|
|
7
8
|
export const TipKit = {
|
|
9
|
+
Group,
|
|
8
10
|
Popover,
|
|
9
11
|
View,
|
|
10
12
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["assertComponentEnabled","getNativeTinyui","validateTipId","Popover","View","TipKit","resetDatastore","resetTipsDatastore","configure","displayFrequency","includes","Error","configureTips","invalidate","tipId","reason","invalidateTip"],"sourceRoot":"../../../src","sources":["TipKit/index.ts"],"mappings":";;AAAA,SAASA,sBAAsB,EAAEC,eAAe,QAAQ,mBAAU;AAElE,SAASC,aAAa,QAAQ,iBAAc;AAC5C,SAASC,OAAO,QAAQ,cAAW;AACnC,SAASC,IAAI,QAAQ,WAAQ;
|
|
1
|
+
{"version":3,"names":["assertComponentEnabled","getNativeTinyui","validateTipId","Popover","View","Group","TipKit","resetDatastore","resetTipsDatastore","configure","displayFrequency","includes","Error","configureTips","invalidate","tipId","reason","invalidateTip"],"sourceRoot":"../../../src","sources":["TipKit/index.ts"],"mappings":";;AAAA,SAASA,sBAAsB,EAAEC,eAAe,QAAQ,mBAAU;AAElE,SAASC,aAAa,QAAQ,iBAAc;AAC5C,SAASC,OAAO,QAAQ,cAAW;AACnC,SAASC,IAAI,QAAQ,WAAQ;AAC7B,SAASC,KAAK,QAAQ,YAAS;AAE/B,OAAO,MAAMC,MAAM,GAAG;EACpBD,KAAK;EACLF,OAAO;EACPC,IAAI;EACJ;AACF;AACA;AACA;AACA;EACE,MAAMG,cAAcA,CAAA,EAAkB;IACpCP,sBAAsB,CAAC,QAAQ,CAAC;IAChC,MAAMC,eAAe,CAAC,CAAC,CAACO,kBAAkB,CAAC,CAAC;EAC9C,CAAC;EAED;EACA,MAAMC,SAASA,CAAC;IACdC,gBAAgB,GAAG;EACA,CAAC,GAAG,CAAC,CAAC,EAAiB;IAC1CV,sBAAsB,CAAC,QAAQ,CAAC;IAChC,IACE,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAACW,QAAQ,CAC7DD,gBACF,CAAC,EACD;MACA,MAAM,IAAIE,KAAK,CACb,iEACF,CAAC;IACH;IACA,MAAMX,eAAe,CAAC,CAAC,CAACY,aAAa,CAACH,gBAAgB,CAAC;EACzD,CAAC;EAED;EACA,MAAMI,UAAUA,CACdC,KAAa,EACbC,MAA6B,GAAG,iBAAiB,EAClC;IACfhB,sBAAsB,CAAC,QAAQ,CAAC;IAChCE,aAAa,CAACa,KAAK,CAAC;IACpB,IAAIC,MAAM,KAAK,iBAAiB,IAAIA,MAAM,KAAK,WAAW,EAAE;MAC1D,MAAM,IAAIJ,KAAK,CAAC,wDAAwD,CAAC;IAC3E;IACA,MAAMX,eAAe,CAAC,CAAC,CAACgB,aAAa,CAACF,KAAK,EAAEC,MAAM,CAAC;EACtD;AACF,CAAC","ignoreList":[]}
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Menu","SwipeActions","TipKit","Stepper","ConcentricView","SFSymbol","Popover","PopoverClose","getNativeTinyui","assertComponentEnabled","LiquidGlassText"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,IAAI,QAAQ,iBAAQ;AAC7B,SAASC,YAAY,QAAQ,yBAAgB;AAO7C,SAASC,MAAM,QAAQ,mBAAU;
|
|
1
|
+
{"version":3,"names":["Menu","SwipeActions","TipKit","Stepper","ConcentricView","SFSymbol","Popover","PopoverClose","getNativeTinyui","assertComponentEnabled","LiquidGlassText"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,IAAI,QAAQ,iBAAQ;AAC7B,SAASC,YAAY,QAAQ,yBAAgB;AAO7C,SAASC,MAAM,QAAQ,mBAAU;AAyBjC,SAASC,OAAO,QAAQ,oBAAW;AAGnC,SAASC,cAAc,QAAQ,2BAAkB;AAGjD,SAASC,QAAQ,QAAQ,qBAAY;AAWrC,SAASC,OAAO,EAAEC,YAAY,QAAQ,oBAAW;AAUjD,SAASC,eAAe,EAAEC,sBAAsB,QAAQ,kBAAS;AAGjE,SAASC,eAAe,QAAQ,4BAAmB","ignoreList":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TipGroupProps } from './types.js';
|
|
2
|
+
interface GroupContextValue {
|
|
3
|
+
tipIds: ReadonlySet<string>;
|
|
4
|
+
currentTipId: string | undefined;
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
invalidateOnOutsideDismiss: boolean;
|
|
7
|
+
complete: (tipId: string) => void;
|
|
8
|
+
}
|
|
9
|
+
/** Orders tips by ID while native TipKit owns eligibility and persisted history. */
|
|
10
|
+
export declare function Group({ tipIds, priority, enabled, invalidateOnOutsideDismiss, children, }: TipGroupProps): import("react").JSX.Element;
|
|
11
|
+
export declare function useTipGroup(tipId: string): GroupContextValue | null;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=Group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Group.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/Group.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAS,CAAC;AAG7C,UAAU,iBAAiB;IACzB,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,0BAA0B,EAAE,OAAO,CAAC;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAID,oFAAoF;AACpF,wBAAgB,KAAK,CAAC,EACpB,MAAM,EACN,QAAoB,EACpB,OAAc,EACd,0BAAkC,EAClC,QAAQ,GACT,EAAE,aAAa,+BAoCf;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,4BAQxC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/Popover.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/Popover.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAwB,MAAM,YAAS,CAAC;AAIrE,eAAO,MAAM,OAAO,6LAqEnB,CAAC"}
|
|
@@ -10,6 +10,7 @@ export interface NativeTipPopoverProps extends ViewProps {
|
|
|
10
10
|
title: string;
|
|
11
11
|
}>>;
|
|
12
12
|
enabled?: boolean;
|
|
13
|
+
invalidateOnOutsideDismiss?: boolean;
|
|
13
14
|
maxDisplayCount?: CodegenTypes.Int32;
|
|
14
15
|
ignoresDisplayFrequency?: boolean;
|
|
15
16
|
arrowEdge?: string;
|
|
@@ -23,6 +24,10 @@ export interface NativeTipPopoverProps extends ViewProps {
|
|
|
23
24
|
code: string;
|
|
24
25
|
message: string;
|
|
25
26
|
}>>;
|
|
27
|
+
onTipInvalidated?: DirectEventHandler<Readonly<{
|
|
28
|
+
tipId: string;
|
|
29
|
+
reason: string;
|
|
30
|
+
}>>;
|
|
26
31
|
}
|
|
27
32
|
declare const _default: import("react-native/types_generated/Libraries/Utilities/codegenNativeComponent").NativeComponentType<NativeTipPopoverProps>;
|
|
28
33
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TipPopoverNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/TipPopoverNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,MAAM,WAAW,qBAAsB,SAAQ,SAAS;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC;IACrC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,kBAAkB,CAC9B,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CACvD,CAAC;IACF,UAAU,CAAC,EAAE,kBAAkB,CAC7B,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAC3D,CAAC;CACH;;AAED,wBAKE"}
|
|
1
|
+
{"version":3,"file":"TipPopoverNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/TipPopoverNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,MAAM,WAAW,qBAAsB,SAAQ,SAAS;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,eAAe,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC;IACrC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,kBAAkB,CAC9B,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CACvD,CAAC;IACF,UAAU,CAAC,EAAE,kBAAkB,CAC7B,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAC3D,CAAC;IACF,gBAAgB,CAAC,EAAE,kBAAkB,CACnC,QAAQ,CAAC;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CACH,CAAC;CACH;;AAED,wBAKE"}
|
|
@@ -23,6 +23,10 @@ export interface NativeTipViewProps extends ViewProps {
|
|
|
23
23
|
code: string;
|
|
24
24
|
message: string;
|
|
25
25
|
}>>;
|
|
26
|
+
onTipInvalidated?: DirectEventHandler<Readonly<{
|
|
27
|
+
tipId: string;
|
|
28
|
+
reason: string;
|
|
29
|
+
}>>;
|
|
26
30
|
}
|
|
27
31
|
declare const _default: import("react-native/types_generated/Libraries/Utilities/codegenNativeComponent").NativeComponentType<NativeTipViewProps>;
|
|
28
32
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TipViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/TipViewNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC;IACrC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,kBAAkB,CAC9B,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CACvD,CAAC;IACF,UAAU,CAAC,EAAE,kBAAkB,CAC7B,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAC3D,CAAC;CACH;;AAED,wBAEG"}
|
|
1
|
+
{"version":3,"file":"TipViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/TipViewNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC;IACrC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,kBAAkB,CAC9B,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CACvD,CAAC;IACF,UAAU,CAAC,EAAE,kBAAkB,CAC7B,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAC3D,CAAC;IACF,gBAAgB,CAAC,EAAE,kBAAkB,CACnC,QAAQ,CAAC;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CACH,CAAC;CACH;;AAED,wBAEG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"View.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/View.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"View.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/View.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAwB,MAAM,YAAS,CAAC;AAIlE,eAAO,MAAM,IAAI,0LAgEf,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { TipInvalidationReason, TipKitConfiguration } from './types.js';
|
|
2
|
+
import { Group } from './Group.js';
|
|
2
3
|
export declare const TipKit: {
|
|
4
|
+
Group: typeof Group;
|
|
3
5
|
Popover: import("react").ForwardRefExoticComponent<import("./types.js").TipPopoverProps & import("react").RefAttributes<import("react-native/types_generated/src/private/webapis/dom/nodes/ReactNativeElement").default>>;
|
|
4
6
|
View: import("react").ForwardRefExoticComponent<import("./types.js").TipViewProps & import("react").RefAttributes<import("react-native/types_generated/src/private/webapis/dom/nodes/ReactNativeElement").default>>;
|
|
5
7
|
/**
|
|
@@ -13,5 +15,5 @@ export declare const TipKit: {
|
|
|
13
15
|
/** Persistently invalidate a tip, including when its view is not mounted. */
|
|
14
16
|
invalidate(tipId: string, reason?: TipInvalidationReason): Promise<void>;
|
|
15
17
|
};
|
|
16
|
-
export type { TipAction, TipDisplayFrequency, TipError, TipInvalidationReason, TipKitConfiguration, TipPopoverProps, TipViewProps, } from './types.js';
|
|
18
|
+
export type { TipAction, TipDisplayFrequency, TipError, TipInvalidationReason, TipInvalidationEvent, TipGroupProps, TipKitConfiguration, TipPopoverProps, TipViewProps, } from './types.js';
|
|
17
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,YAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,YAAS,CAAC;AAI1E,OAAO,EAAE,KAAK,EAAE,MAAM,YAAS,CAAC;AAEhC,eAAO,MAAM,MAAM;;;;IAIjB;;;;OAIG;sBACqB,OAAO,CAAC,IAAI,CAAC;IAKrC,sFAAsF;sCAGnF,mBAAmB,GAAQ,OAAO,CAAC,IAAI,CAAC;IAc3C,6EAA6E;sBAEpE,MAAM,WACL,qBAAqB,GAC5B,OAAO,CAAC,IAAI,CAAC;CAQjB,CAAC;AAEF,YAAY,EACV,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,YAAY,GACb,MAAM,YAAS,CAAC"}
|
|
@@ -6,6 +6,20 @@ export interface TipKitConfiguration {
|
|
|
6
6
|
displayFrequency?: TipDisplayFrequency;
|
|
7
7
|
}
|
|
8
8
|
export type TipInvalidationReason = 'actionPerformed' | 'tipClosed';
|
|
9
|
+
export interface TipInvalidationEvent {
|
|
10
|
+
reason: TipInvalidationReason | 'displayCountExceeded' | 'displayDurationExceeded' | 'unknown';
|
|
11
|
+
}
|
|
12
|
+
export interface TipGroupProps {
|
|
13
|
+
/** Stable tip IDs in presentation order, independent of the layout tree. */
|
|
14
|
+
tipIds: readonly string[];
|
|
15
|
+
/** Currently only ordered presentation is supported. Defaults to ordered. */
|
|
16
|
+
priority?: 'ordered';
|
|
17
|
+
/** Pause all tips in this group without completing them. Defaults to true. */
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
/** Treat tapping outside a popover as completion. Defaults to false. */
|
|
20
|
+
invalidateOnOutsideDismiss?: boolean;
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
}
|
|
9
23
|
export interface TipAction {
|
|
10
24
|
/** Unique nonempty identity within this tip, returned by `onActionPress`. */
|
|
11
25
|
id: string;
|
|
@@ -31,9 +45,13 @@ export interface TipContentProps extends Omit<ViewProps, 'children'> {
|
|
|
31
45
|
ignoresDisplayFrequency?: boolean;
|
|
32
46
|
/** Receives the tapped button's id and title; does not automatically invalidate the tip. */
|
|
33
47
|
onActionPress?: (action: TipAction) => void;
|
|
48
|
+
/** Called for native invalidation, including persisted invalidation on mount. */
|
|
49
|
+
onInvalidated?: (event: TipInvalidationEvent) => void;
|
|
34
50
|
onError?: (error: TipError) => void;
|
|
35
51
|
}
|
|
36
52
|
export interface TipPopoverProps extends TipContentProps {
|
|
53
|
+
/** Invalidate on outside dismissal. Inherits from Group; otherwise false. */
|
|
54
|
+
invalidateOnOutsideDismiss?: boolean;
|
|
37
55
|
/** Anchor content. Its existing touch handlers are preserved. */
|
|
38
56
|
children: ReactNode;
|
|
39
57
|
/** Preferred arrow edge on the bubble; UIKit may adapt to available space. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,mBAAmB,GAC7B,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;CACxC;AAED,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG,WAAW,CAAC;AAEpE,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAClE,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAC/B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,4FAA4F;IAC5F,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,iEAAiE;IACjE,QAAQ,EAAE,SAAS,CAAC;IACpB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CAChE;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,yEAAyE;IACzE,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CAChE"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/TipKit/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,mBAAmB,GAC7B,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;CACxC;AAED,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG,WAAW,CAAC;AAEpE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EACF,qBAAqB,GACrB,sBAAsB,GACtB,yBAAyB,GACzB,SAAS,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wEAAwE;IACxE,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAClE,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAC/B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,4FAA4F;IAC5F,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAC5C,iFAAiF;IACjF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,6EAA6E;IAC7E,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,iEAAiE;IACjE,QAAQ,EAAE,SAAS,CAAC;IACpB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CAChE;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,yEAAyE;IACzE,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CAChE"}
|
|
@@ -2,7 +2,7 @@ export { Menu } from './Menu/index.js';
|
|
|
2
2
|
export { SwipeActions } from './SwipeActions/index.js';
|
|
3
3
|
export type { SwipeAction, SwipeActionPressEvent, SwipeActionsEdge, SwipeActionsProps, } from './SwipeActions/index.js';
|
|
4
4
|
export { TipKit } from './TipKit/index.js';
|
|
5
|
-
export type { TipAction, TipDisplayFrequency, TipError, TipInvalidationReason, TipPopoverProps, TipViewProps, TipKitConfiguration, } from './TipKit/index.js';
|
|
5
|
+
export type { TipAction, TipDisplayFrequency, TipError, TipInvalidationReason, TipInvalidationEvent, TipGroupProps, TipPopoverProps, TipViewProps, TipKitConfiguration, } from './TipKit/index.js';
|
|
6
6
|
export type { MenuActionOption, MenuActionPressEvent, MenuActionPressEventData, MenuDividerOption, MenuItemState, MenuOption, MenuProps, MenuRef, MenuSectionOption, MenuSubmenuOption, } from './Menu/index.js';
|
|
7
7
|
export { Stepper } from './Stepper/index.js';
|
|
8
8
|
export type { StepperProps } from './Stepper/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAQ,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAgB,CAAC;AAC9C,YAAY,EACV,WAAW,EACX,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,yBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAU,CAAC;AAClC,YAAY,EACV,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,qBAAqB,EACrB,eAAe,EACf,YAAY,EACZ,mBAAmB,GACpB,MAAM,mBAAU,CAAC;AAClB,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,SAAS,EACT,OAAO,EACP,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,iBAAQ,CAAC;AAEhB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAW,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAAkB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAAkB,CAAC;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAY,CAAC;AACtC,YAAY,EACV,yBAAyB,EACzB,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,cAAc,GACf,MAAM,qBAAY,CAAC;AAEpB,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAW,CAAC;AAClD,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,cAAc,EACd,wBAAwB,EACxB,YAAY,GACb,MAAM,oBAAW,CAAC;AAEnB,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,kBAAS,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAS,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAAmB,CAAC;AACpD,YAAY,EACV,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,4BAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAQ,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAgB,CAAC;AAC9C,YAAY,EACV,WAAW,EACX,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,yBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAU,CAAC;AAClC,YAAY,EACV,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,mBAAmB,GACpB,MAAM,mBAAU,CAAC;AAClB,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,SAAS,EACT,OAAO,EACP,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,iBAAQ,CAAC;AAEhB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAW,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAAkB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAAkB,CAAC;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAY,CAAC;AACtC,YAAY,EACV,yBAAyB,EACzB,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,cAAc,GACf,MAAM,qBAAY,CAAC;AAEpB,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAW,CAAC;AAClD,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,cAAc,EACd,wBAAwB,EACxB,YAAY,GACb,MAAM,oBAAW,CAAC;AAEnB,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,kBAAS,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAS,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAAmB,CAAC;AACpD,YAAY,EACV,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,4BAAmB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-tinyui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Dependency-free native iOS Menu, SwipeActions, Popover, TipKit, Stepper, ConcentricView, SFSymbol and LiquidGlassText components for React Native",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useCallback,
|
|
4
|
+
useContext,
|
|
5
|
+
useMemo,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
8
|
+
|
|
9
|
+
import { assertComponentEnabled } from '../utils';
|
|
10
|
+
import type { TipGroupProps } from './types';
|
|
11
|
+
import { validateTipId } from './validation';
|
|
12
|
+
|
|
13
|
+
interface GroupContextValue {
|
|
14
|
+
tipIds: ReadonlySet<string>;
|
|
15
|
+
currentTipId: string | undefined;
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
invalidateOnOutsideDismiss: boolean;
|
|
18
|
+
complete: (tipId: string) => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const GroupContext = createContext<GroupContextValue | null>(null);
|
|
22
|
+
|
|
23
|
+
/** Orders tips by ID while native TipKit owns eligibility and persisted history. */
|
|
24
|
+
export function Group({
|
|
25
|
+
tipIds,
|
|
26
|
+
priority = 'ordered',
|
|
27
|
+
enabled = true,
|
|
28
|
+
invalidateOnOutsideDismiss = false,
|
|
29
|
+
children,
|
|
30
|
+
}: TipGroupProps) {
|
|
31
|
+
assertComponentEnabled('TipKit');
|
|
32
|
+
if (priority !== 'ordered') {
|
|
33
|
+
throw new Error('[TinyUI] TipKit.Group only supports ordered priority.');
|
|
34
|
+
}
|
|
35
|
+
const ids = new Set<string>();
|
|
36
|
+
for (const tipId of tipIds) {
|
|
37
|
+
validateTipId(tipId);
|
|
38
|
+
if (ids.has(tipId)) {
|
|
39
|
+
throw new Error('[TinyUI] TipKit.Group tipIds must be unique.');
|
|
40
|
+
}
|
|
41
|
+
ids.add(tipId);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const [completed, setCompleted] = useState<ReadonlySet<string>>(
|
|
45
|
+
() => new Set()
|
|
46
|
+
);
|
|
47
|
+
const complete = useCallback((tipId: string) => {
|
|
48
|
+
setCompleted((previous) =>
|
|
49
|
+
previous.has(tipId) ? previous : new Set([...previous, tipId])
|
|
50
|
+
);
|
|
51
|
+
}, []);
|
|
52
|
+
const value = useMemo(
|
|
53
|
+
() => ({
|
|
54
|
+
tipIds: new Set(tipIds),
|
|
55
|
+
currentTipId: tipIds.find((id) => !completed.has(id)),
|
|
56
|
+
enabled,
|
|
57
|
+
invalidateOnOutsideDismiss,
|
|
58
|
+
complete,
|
|
59
|
+
}),
|
|
60
|
+
[tipIds, completed, enabled, invalidateOnOutsideDismiss, complete]
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<GroupContext.Provider value={value}>{children}</GroupContext.Provider>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function useTipGroup(tipId: string) {
|
|
69
|
+
const group = useContext(GroupContext);
|
|
70
|
+
if (group && !group.tipIds.has(tipId)) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`[TinyUI] TipKit tipId "${tipId}" is missing from its Group's tipIds.`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return group;
|
|
76
|
+
}
|
package/src/TipKit/Popover.tsx
CHANGED
|
@@ -3,13 +3,15 @@ import { View } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
import { assertComponentEnabled } from '../utils';
|
|
5
5
|
import NativeTipPopoverView from './TipPopoverNativeComponent';
|
|
6
|
-
import type { TipPopoverProps } from './types';
|
|
6
|
+
import type { TipPopoverProps, TipInvalidationEvent } from './types';
|
|
7
7
|
import { validateTip } from './validation';
|
|
8
|
+
import { useTipGroup } from './Group';
|
|
8
9
|
|
|
9
10
|
export const Popover = forwardRef<ComponentRef<typeof View>, TipPopoverProps>(
|
|
10
11
|
function TipPopoverRoot(props, ref) {
|
|
11
12
|
assertComponentEnabled('TipKit');
|
|
12
13
|
validateTip(props);
|
|
14
|
+
const group = useTipGroup(props.tipId);
|
|
13
15
|
const {
|
|
14
16
|
children,
|
|
15
17
|
tipId,
|
|
@@ -22,6 +24,8 @@ export const Popover = forwardRef<ComponentRef<typeof View>, TipPopoverProps>(
|
|
|
22
24
|
ignoresDisplayFrequency = false,
|
|
23
25
|
arrowEdge = 'auto',
|
|
24
26
|
onActionPress,
|
|
27
|
+
onInvalidated,
|
|
28
|
+
invalidateOnOutsideDismiss = group?.invalidateOnOutsideDismiss ?? false,
|
|
25
29
|
onError,
|
|
26
30
|
...viewProps
|
|
27
31
|
} = props;
|
|
@@ -36,7 +40,10 @@ export const Popover = forwardRef<ComponentRef<typeof View>, TipPopoverProps>(
|
|
|
36
40
|
message={message}
|
|
37
41
|
systemImage={systemImage}
|
|
38
42
|
actions={actions}
|
|
39
|
-
enabled={
|
|
43
|
+
enabled={
|
|
44
|
+
enabled && (!group || (group.enabled && group.currentTipId === tipId))
|
|
45
|
+
}
|
|
46
|
+
invalidateOnOutsideDismiss={invalidateOnOutsideDismiss}
|
|
40
47
|
maxDisplayCount={maxDisplayCount ?? 0}
|
|
41
48
|
ignoresDisplayFrequency={ignoresDisplayFrequency}
|
|
42
49
|
arrowEdge={arrowEdge}
|
|
@@ -45,6 +52,13 @@ export const Popover = forwardRef<ComponentRef<typeof View>, TipPopoverProps>(
|
|
|
45
52
|
onActionPress?.({ id: nativeEvent.id, title: nativeEvent.title });
|
|
46
53
|
}
|
|
47
54
|
}}
|
|
55
|
+
onTipInvalidated={({ nativeEvent }) => {
|
|
56
|
+
if (nativeEvent.tipId !== tipId) return;
|
|
57
|
+
group?.complete(tipId);
|
|
58
|
+
onInvalidated?.({
|
|
59
|
+
reason: nativeEvent.reason as TipInvalidationEvent['reason'],
|
|
60
|
+
});
|
|
61
|
+
}}
|
|
48
62
|
onTipError={({ nativeEvent }) => {
|
|
49
63
|
if (nativeEvent.tipId !== tipId) return;
|
|
50
64
|
const error = {
|
|
@@ -12,6 +12,7 @@ export interface NativeTipPopoverProps extends ViewProps {
|
|
|
12
12
|
systemImage?: string;
|
|
13
13
|
actions?: ReadonlyArray<Readonly<{ id: string; title: string }>>;
|
|
14
14
|
enabled?: boolean;
|
|
15
|
+
invalidateOnOutsideDismiss?: boolean;
|
|
15
16
|
maxDisplayCount?: CodegenTypes.Int32;
|
|
16
17
|
ignoresDisplayFrequency?: boolean;
|
|
17
18
|
arrowEdge?: string;
|
|
@@ -21,6 +22,12 @@ export interface NativeTipPopoverProps extends ViewProps {
|
|
|
21
22
|
onTipError?: DirectEventHandler<
|
|
22
23
|
Readonly<{ tipId: string; code: string; message: string }>
|
|
23
24
|
>;
|
|
25
|
+
onTipInvalidated?: DirectEventHandler<
|
|
26
|
+
Readonly<{
|
|
27
|
+
tipId: string;
|
|
28
|
+
reason: string;
|
|
29
|
+
}>
|
|
30
|
+
>;
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
export default codegenNativeComponent<NativeTipPopoverProps>(
|
|
@@ -21,6 +21,12 @@ export interface NativeTipViewProps extends ViewProps {
|
|
|
21
21
|
onTipError?: DirectEventHandler<
|
|
22
22
|
Readonly<{ tipId: string; code: string; message: string }>
|
|
23
23
|
>;
|
|
24
|
+
onTipInvalidated?: DirectEventHandler<
|
|
25
|
+
Readonly<{
|
|
26
|
+
tipId: string;
|
|
27
|
+
reason: string;
|
|
28
|
+
}>
|
|
29
|
+
>;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
export default codegenNativeComponent<NativeTipViewProps>('TinyuiTipView', {
|
package/src/TipKit/View.tsx
CHANGED
|
@@ -3,8 +3,9 @@ import type { View as ReactNativeView } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
import { assertComponentEnabled } from '../utils';
|
|
5
5
|
import NativeTipView from './TipViewNativeComponent';
|
|
6
|
-
import type { TipViewProps } from './types';
|
|
6
|
+
import type { TipViewProps, TipInvalidationEvent } from './types';
|
|
7
7
|
import { validateTip } from './validation';
|
|
8
|
+
import { useTipGroup } from './Group';
|
|
8
9
|
|
|
9
10
|
export const View = forwardRef<
|
|
10
11
|
ComponentRef<typeof ReactNativeView>,
|
|
@@ -12,6 +13,7 @@ export const View = forwardRef<
|
|
|
12
13
|
>(function TipViewRoot(props, ref) {
|
|
13
14
|
assertComponentEnabled('TipKit');
|
|
14
15
|
validateTip(props, 'TipKit.View');
|
|
16
|
+
const group = useTipGroup(props.tipId);
|
|
15
17
|
const {
|
|
16
18
|
tipId,
|
|
17
19
|
title,
|
|
@@ -23,6 +25,7 @@ export const View = forwardRef<
|
|
|
23
25
|
ignoresDisplayFrequency = false,
|
|
24
26
|
arrowEdge = 'none',
|
|
25
27
|
onActionPress,
|
|
28
|
+
onInvalidated,
|
|
26
29
|
onError,
|
|
27
30
|
...viewProps
|
|
28
31
|
} = props;
|
|
@@ -38,7 +41,9 @@ export const View = forwardRef<
|
|
|
38
41
|
message={message}
|
|
39
42
|
systemImage={systemImage}
|
|
40
43
|
actions={actions}
|
|
41
|
-
enabled={
|
|
44
|
+
enabled={
|
|
45
|
+
enabled && (!group || (group.enabled && group.currentTipId === tipId))
|
|
46
|
+
}
|
|
42
47
|
maxDisplayCount={maxDisplayCount ?? 0}
|
|
43
48
|
ignoresDisplayFrequency={ignoresDisplayFrequency}
|
|
44
49
|
arrowEdge={arrowEdge}
|
|
@@ -47,6 +52,13 @@ export const View = forwardRef<
|
|
|
47
52
|
onActionPress?.({ id: nativeEvent.id, title: nativeEvent.title });
|
|
48
53
|
}
|
|
49
54
|
}}
|
|
55
|
+
onTipInvalidated={({ nativeEvent }) => {
|
|
56
|
+
if (nativeEvent.tipId !== tipId) return;
|
|
57
|
+
group?.complete(tipId);
|
|
58
|
+
onInvalidated?.({
|
|
59
|
+
reason: nativeEvent.reason as TipInvalidationEvent['reason'],
|
|
60
|
+
});
|
|
61
|
+
}}
|
|
50
62
|
onTipError={({ nativeEvent }) => {
|
|
51
63
|
if (nativeEvent.tipId !== tipId) return;
|
|
52
64
|
const error = {
|
package/src/TipKit/index.ts
CHANGED
|
@@ -3,8 +3,10 @@ import type { TipInvalidationReason, TipKitConfiguration } from './types';
|
|
|
3
3
|
import { validateTipId } from './validation';
|
|
4
4
|
import { Popover } from './Popover';
|
|
5
5
|
import { View } from './View';
|
|
6
|
+
import { Group } from './Group';
|
|
6
7
|
|
|
7
8
|
export const TipKit = {
|
|
9
|
+
Group,
|
|
8
10
|
Popover,
|
|
9
11
|
View,
|
|
10
12
|
/**
|
|
@@ -53,6 +55,8 @@ export type {
|
|
|
53
55
|
TipDisplayFrequency,
|
|
54
56
|
TipError,
|
|
55
57
|
TipInvalidationReason,
|
|
58
|
+
TipInvalidationEvent,
|
|
59
|
+
TipGroupProps,
|
|
56
60
|
TipKitConfiguration,
|
|
57
61
|
TipPopoverProps,
|
|
58
62
|
TipViewProps,
|
package/src/TipKit/types.ts
CHANGED
|
@@ -11,6 +11,26 @@ export interface TipKitConfiguration {
|
|
|
11
11
|
|
|
12
12
|
export type TipInvalidationReason = 'actionPerformed' | 'tipClosed';
|
|
13
13
|
|
|
14
|
+
export interface TipInvalidationEvent {
|
|
15
|
+
reason:
|
|
16
|
+
| TipInvalidationReason
|
|
17
|
+
| 'displayCountExceeded'
|
|
18
|
+
| 'displayDurationExceeded'
|
|
19
|
+
| 'unknown';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface TipGroupProps {
|
|
23
|
+
/** Stable tip IDs in presentation order, independent of the layout tree. */
|
|
24
|
+
tipIds: readonly string[];
|
|
25
|
+
/** Currently only ordered presentation is supported. Defaults to ordered. */
|
|
26
|
+
priority?: 'ordered';
|
|
27
|
+
/** Pause all tips in this group without completing them. Defaults to true. */
|
|
28
|
+
enabled?: boolean;
|
|
29
|
+
/** Treat tapping outside a popover as completion. Defaults to false. */
|
|
30
|
+
invalidateOnOutsideDismiss?: boolean;
|
|
31
|
+
children: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
14
34
|
export interface TipAction {
|
|
15
35
|
/** Unique nonempty identity within this tip, returned by `onActionPress`. */
|
|
16
36
|
id: string;
|
|
@@ -38,10 +58,14 @@ export interface TipContentProps extends Omit<ViewProps, 'children'> {
|
|
|
38
58
|
ignoresDisplayFrequency?: boolean;
|
|
39
59
|
/** Receives the tapped button's id and title; does not automatically invalidate the tip. */
|
|
40
60
|
onActionPress?: (action: TipAction) => void;
|
|
61
|
+
/** Called for native invalidation, including persisted invalidation on mount. */
|
|
62
|
+
onInvalidated?: (event: TipInvalidationEvent) => void;
|
|
41
63
|
onError?: (error: TipError) => void;
|
|
42
64
|
}
|
|
43
65
|
|
|
44
66
|
export interface TipPopoverProps extends TipContentProps {
|
|
67
|
+
/** Invalidate on outside dismissal. Inherits from Group; otherwise false. */
|
|
68
|
+
invalidateOnOutsideDismiss?: boolean;
|
|
45
69
|
/** Anchor content. Its existing touch handlers are preserved. */
|
|
46
70
|
children: ReactNode;
|
|
47
71
|
/** Preferred arrow edge on the bubble; UIKit may adapt to available space. */
|