bleam 0.0.13 → 0.0.14
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/dist/ai.cjs +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.js +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/elements-DX_YUveu.d.ts +341 -0
- package/dist/elements-gEI8YGl1.d.cts +341 -0
- package/dist/elements.cjs +582 -54
- package/dist/elements.d.cts +2 -2
- package/dist/elements.d.ts +2 -2
- package/dist/elements.js +560 -55
- package/dist/files.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/{state-BZYyrE2-.cjs → state-Bm9GiRnU.cjs} +58 -7
- package/dist/{state-DkaRFkZJ.js → state-D8Firo9w.js} +57 -7
- package/dist/state.cjs +1 -1
- package/dist/state.d.ts +1 -1
- package/dist/state.js +1 -1
- package/dist/window.d.cts +1 -1
- package/dist/window.d.ts +3 -3
- package/package.json +4 -6
- package/templates/basic/app/index.tsx +7 -129
- package/templates/foundation-models/app/index.tsx +100 -41
- package/templates/native/ios/Podfile.lock +6 -0
- package/templates/native/package.json +6 -1
- package/templates/native/yarn.lock +5392 -3749
- package/dist/elements-CFk0QHw0.d.cts +0 -127
- package/dist/elements-ClGQ41Sc.d.ts +0 -127
- package/dist/native-sqlite-Dw--FI9a.cjs +0 -66
- package/dist/native-sqlite-WzRNzCSh.js +0 -64
- /package/dist/{config-Cms0rvqg.d.ts → config-Chi-flpJ.d.ts} +0 -0
- /package/dist/{files-4ZEoAWiv.d.ts → files-VrkQlKIT.d.ts} +0 -0
- /package/dist/{schema-LxnzAfgw.d.ts → schema-DsXZBnvc.d.ts} +0 -0
package/dist/elements.cjs
CHANGED
|
@@ -1,10 +1,63 @@
|
|
|
1
1
|
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
2
|
const require_native_runtime = require('./native-runtime-CsXnXkQn.cjs');
|
|
3
|
+
let react = require("react");
|
|
4
|
+
react = require_chunk.__toESM(react);
|
|
3
5
|
let react_native = require("react-native");
|
|
4
6
|
react_native = require_chunk.__toESM(react_native);
|
|
5
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
8
|
react_jsx_runtime = require_chunk.__toESM(react_jsx_runtime);
|
|
7
9
|
|
|
10
|
+
//#region src/elements/ai-status.ts
|
|
11
|
+
function messageStatusDisplay(status) {
|
|
12
|
+
switch (status) {
|
|
13
|
+
case "queued": return {
|
|
14
|
+
symbol: "clock",
|
|
15
|
+
label: "Queued",
|
|
16
|
+
color: "systemGray"
|
|
17
|
+
};
|
|
18
|
+
case "generating": return {
|
|
19
|
+
symbol: "ellipsis",
|
|
20
|
+
label: "Generating",
|
|
21
|
+
color: "systemBlue"
|
|
22
|
+
};
|
|
23
|
+
case "canceling": return {
|
|
24
|
+
symbol: "xmark.circle",
|
|
25
|
+
label: "Canceling",
|
|
26
|
+
color: "systemOrange"
|
|
27
|
+
};
|
|
28
|
+
case "failed": return {
|
|
29
|
+
symbol: "exclamationmark.triangle",
|
|
30
|
+
label: "Failed",
|
|
31
|
+
color: "systemRed"
|
|
32
|
+
};
|
|
33
|
+
case "canceled": return {
|
|
34
|
+
symbol: "xmark.circle",
|
|
35
|
+
label: "Canceled",
|
|
36
|
+
color: "systemOrange"
|
|
37
|
+
};
|
|
38
|
+
default: return {
|
|
39
|
+
symbol: "checkmark",
|
|
40
|
+
label: "Completed",
|
|
41
|
+
color: "systemGray"
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function promptStatusGenerating(status) {
|
|
46
|
+
return status === "queued" || status === "generating" || status === "canceling";
|
|
47
|
+
}
|
|
48
|
+
function promptStatusSymbol(status, generating) {
|
|
49
|
+
if (generating) return "stop.fill";
|
|
50
|
+
if (status === "failed" || status === "canceled") return "exclamationmark.arrow.triangle.2.circlepath";
|
|
51
|
+
return "arrow.up";
|
|
52
|
+
}
|
|
53
|
+
function promptStatusLabel(status, generating) {
|
|
54
|
+
if (generating) return "Stop generating";
|
|
55
|
+
if (status === "failed") return "Send after failure";
|
|
56
|
+
if (status === "canceled") return "Send after cancellation";
|
|
57
|
+
return "Send message";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
8
61
|
//#region src/elements/shared.ts
|
|
9
62
|
function textFromChildren(children) {
|
|
10
63
|
if (typeof children === "string" || typeof children === "number") return String(children);
|
|
@@ -246,7 +299,7 @@ const glassCornerRadius = {
|
|
|
246
299
|
regular: 10,
|
|
247
300
|
large: 12
|
|
248
301
|
};
|
|
249
|
-
function resolveStyle(style, state) {
|
|
302
|
+
function resolveStyle$2(style, state) {
|
|
250
303
|
return typeof style === "function" ? style(state) : style;
|
|
251
304
|
}
|
|
252
305
|
function ButtonContent({ icon, label, labelStyle, loading, size, variant }) {
|
|
@@ -261,9 +314,9 @@ function ButtonContent({ icon, label, labelStyle, loading, size, variant }) {
|
|
|
261
314
|
}) : null, label ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
262
315
|
numberOfLines: 1,
|
|
263
316
|
style: [
|
|
264
|
-
styles.label,
|
|
317
|
+
styles$3.label,
|
|
265
318
|
labelSizeStyles[size],
|
|
266
|
-
variant ? labelVariantStyles[variant] : styles.glassLabel,
|
|
319
|
+
variant ? labelVariantStyles[variant] : styles$3.glassLabel,
|
|
267
320
|
labelStyle
|
|
268
321
|
],
|
|
269
322
|
children: label
|
|
@@ -277,10 +330,10 @@ function Button({ accessibilityRole = "button", accessibilityState, activeOpacit
|
|
|
277
330
|
accessibilityState: buttonAccessibilityState(accessibilityState, disabled, loading),
|
|
278
331
|
disabled: inactive,
|
|
279
332
|
style: (state) => [
|
|
280
|
-
styles.button,
|
|
333
|
+
styles$3.button,
|
|
281
334
|
sizeStyles[size],
|
|
282
335
|
buttonVariantStyles[variant],
|
|
283
|
-
resolveStyle(style, state),
|
|
336
|
+
resolveStyle$2(style, state),
|
|
284
337
|
{ opacity: buttonOpacity({
|
|
285
338
|
...state,
|
|
286
339
|
disabled,
|
|
@@ -290,7 +343,7 @@ function Button({ accessibilityRole = "button", accessibilityState, activeOpacit
|
|
|
290
343
|
],
|
|
291
344
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
292
345
|
pointerEvents: "none",
|
|
293
|
-
style: styles.content,
|
|
346
|
+
style: styles$3.content,
|
|
294
347
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonContent, {
|
|
295
348
|
icon,
|
|
296
349
|
label,
|
|
@@ -310,10 +363,10 @@ function GlassButton({ accessibilityRole = "button", accessibilityState, activeO
|
|
|
310
363
|
accessibilityState: buttonAccessibilityState(accessibilityState, disabled, loading),
|
|
311
364
|
disabled: inactive,
|
|
312
365
|
style: (state) => [
|
|
313
|
-
styles.button,
|
|
366
|
+
styles$3.button,
|
|
314
367
|
sizeStyles[size],
|
|
315
|
-
styles.glassButton,
|
|
316
|
-
resolveStyle(style, state),
|
|
368
|
+
styles$3.glassButton,
|
|
369
|
+
resolveStyle$2(style, state),
|
|
317
370
|
{ opacity: buttonOpacity({
|
|
318
371
|
...state,
|
|
319
372
|
disabled,
|
|
@@ -323,7 +376,7 @@ function GlassButton({ accessibilityRole = "button", accessibilityState, activeO
|
|
|
323
376
|
],
|
|
324
377
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
325
378
|
pointerEvents: "none",
|
|
326
|
-
style: styles.glassBackground,
|
|
379
|
+
style: styles$3.glassBackground,
|
|
327
380
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlassView, {
|
|
328
381
|
glassEffectStyle,
|
|
329
382
|
glassStyle: {
|
|
@@ -331,12 +384,12 @@ function GlassButton({ accessibilityRole = "button", accessibilityState, activeO
|
|
|
331
384
|
...glassStyle
|
|
332
385
|
},
|
|
333
386
|
isInteractive: false,
|
|
334
|
-
style: styles.glass,
|
|
387
|
+
style: styles$3.glass,
|
|
335
388
|
tintColor
|
|
336
389
|
})
|
|
337
390
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
338
391
|
pointerEvents: "none",
|
|
339
|
-
style: styles.content,
|
|
392
|
+
style: styles$3.content,
|
|
340
393
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonContent, {
|
|
341
394
|
icon,
|
|
342
395
|
label,
|
|
@@ -347,7 +400,7 @@ function GlassButton({ accessibilityRole = "button", accessibilityState, activeO
|
|
|
347
400
|
})]
|
|
348
401
|
});
|
|
349
402
|
}
|
|
350
|
-
const styles = react_native.StyleSheet.create({
|
|
403
|
+
const styles$3 = react_native.StyleSheet.create({
|
|
351
404
|
button: {
|
|
352
405
|
alignItems: "center",
|
|
353
406
|
borderRadius: 10,
|
|
@@ -382,6 +435,242 @@ const labelVariantStyles = react_native.StyleSheet.create({
|
|
|
382
435
|
plain: { color: (0, react_native.PlatformColor)("systemBlue") }
|
|
383
436
|
});
|
|
384
437
|
|
|
438
|
+
//#endregion
|
|
439
|
+
//#region src/elements/symbol.tsx
|
|
440
|
+
function symbolWeight(weight) {
|
|
441
|
+
switch (weight) {
|
|
442
|
+
case "ultraLight": return UIImageSymbolWeight.UltraLight;
|
|
443
|
+
case "thin": return UIImageSymbolWeight.Thin;
|
|
444
|
+
case "light": return UIImageSymbolWeight.Light;
|
|
445
|
+
case "medium": return UIImageSymbolWeight.Medium;
|
|
446
|
+
case "semibold": return UIImageSymbolWeight.Semibold;
|
|
447
|
+
case "bold": return UIImageSymbolWeight.Bold;
|
|
448
|
+
case "heavy": return UIImageSymbolWeight.Heavy;
|
|
449
|
+
case "black": return UIImageSymbolWeight.Black;
|
|
450
|
+
default: return UIImageSymbolWeight.Regular;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function symbolScale(scale) {
|
|
454
|
+
if (scale === "small") return UIImageSymbolScale.Small;
|
|
455
|
+
if (scale === "large") return UIImageSymbolScale.Large;
|
|
456
|
+
return UIImageSymbolScale.Medium;
|
|
457
|
+
}
|
|
458
|
+
function symbolConfiguration(props, style) {
|
|
459
|
+
const size = props.size ?? style?.fontSize ?? 17;
|
|
460
|
+
return UIImageSymbolConfiguration.configurationWithPointSizeWeightScale(size, symbolWeight(props.weight), symbolScale(props.scale));
|
|
461
|
+
}
|
|
462
|
+
function symbolImage(name, configuration) {
|
|
463
|
+
if (configuration) return UIImage.systemImageNamedWithConfiguration(name, configuration);
|
|
464
|
+
return UIImage.systemImageNamed(name);
|
|
465
|
+
}
|
|
466
|
+
const SFSymbol = require_native_runtime.ensureNativeScript().defineUIKitView({
|
|
467
|
+
name: "SFSymbol",
|
|
468
|
+
layout: {
|
|
469
|
+
sizing: "intrinsic",
|
|
470
|
+
defaultSize: {
|
|
471
|
+
width: 17,
|
|
472
|
+
height: 17
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
create() {
|
|
476
|
+
const imageView = UIImageView.new();
|
|
477
|
+
imageView.contentMode = UIViewContentMode.ScaleAspectFit;
|
|
478
|
+
return imageView;
|
|
479
|
+
},
|
|
480
|
+
update(imageView, props, _previousProps, ctx) {
|
|
481
|
+
const style = styleFromProps(props.style);
|
|
482
|
+
const configuration = symbolConfiguration(props, style);
|
|
483
|
+
imageView.image = symbolImage(props.symbol, configuration);
|
|
484
|
+
imageView.tintColor = colorFromStyle(props.color) ?? colorFromStyle(style?.tintColor) ?? colorFromStyle(style?.color) ?? UIColor.labelColor;
|
|
485
|
+
ctx?.invalidateLayout();
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
//#endregion
|
|
490
|
+
//#region src/elements/conversation.tsx
|
|
491
|
+
const ConversationContext = (0, react.createContext)(null);
|
|
492
|
+
const scrollEndThreshold = 48;
|
|
493
|
+
function useConversation() {
|
|
494
|
+
const context = (0, react.useContext)(ConversationContext);
|
|
495
|
+
if (!context) throw new Error("Conversation elements must be rendered inside <Conversation>");
|
|
496
|
+
return context;
|
|
497
|
+
}
|
|
498
|
+
function Conversation({ children, defaultFollowOutput = true, followOutput, onFollowOutputChange, style,...props }) {
|
|
499
|
+
const controlled = followOutput !== void 0;
|
|
500
|
+
const generation = (0, react.useRef)(0);
|
|
501
|
+
const [internalFollowing, setInternalFollowing] = (0, react.useState)(defaultFollowOutput);
|
|
502
|
+
const [isAtBottom, setIsAtBottom] = (0, react.useState)(true);
|
|
503
|
+
const [followGeneration, setFollowGeneration] = (0, react.useState)(0);
|
|
504
|
+
const following = controlled ? followOutput : internalFollowing;
|
|
505
|
+
const setFollowing = (0, react.useCallback)((value) => {
|
|
506
|
+
if (!controlled) setInternalFollowing(value);
|
|
507
|
+
onFollowOutputChange?.(value);
|
|
508
|
+
}, [controlled, onFollowOutputChange]);
|
|
509
|
+
const updateAtBottom = (0, react.useCallback)((value) => {
|
|
510
|
+
setIsAtBottom(value);
|
|
511
|
+
if (following !== value) setFollowing(value);
|
|
512
|
+
}, [following, setFollowing]);
|
|
513
|
+
const requestFollow = (0, react.useCallback)(() => {
|
|
514
|
+
generation.current += 1;
|
|
515
|
+
setFollowGeneration(generation.current);
|
|
516
|
+
setFollowing(true);
|
|
517
|
+
}, [setFollowing]);
|
|
518
|
+
const context = (0, react.useMemo)(() => ({
|
|
519
|
+
followGeneration,
|
|
520
|
+
following,
|
|
521
|
+
isAtBottom,
|
|
522
|
+
updateAtBottom,
|
|
523
|
+
requestFollow
|
|
524
|
+
}), [
|
|
525
|
+
followGeneration,
|
|
526
|
+
following,
|
|
527
|
+
isAtBottom,
|
|
528
|
+
updateAtBottom,
|
|
529
|
+
requestFollow
|
|
530
|
+
]);
|
|
531
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConversationContext.Provider, {
|
|
532
|
+
value: context,
|
|
533
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
534
|
+
...props,
|
|
535
|
+
style: [styles$2.conversation, style],
|
|
536
|
+
children
|
|
537
|
+
})
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
function ConversationContent({ contentContainerStyle, data, keyboardShouldPersistTaps = "handled", onContentSizeChange, onScroll, renderItem, scrollEventThrottle = 16,...props }) {
|
|
541
|
+
const context = useConversation();
|
|
542
|
+
const list = (0, react.useRef)(null);
|
|
543
|
+
const following = (0, react.useRef)(context.following);
|
|
544
|
+
const previousHeight = (0, react.useRef)(0);
|
|
545
|
+
const previousFollowGeneration = (0, react.useRef)(context.followGeneration);
|
|
546
|
+
following.current = context.following;
|
|
547
|
+
(0, react.useEffect)(() => {
|
|
548
|
+
if (context.following && context.followGeneration > previousFollowGeneration.current) {
|
|
549
|
+
previousFollowGeneration.current = context.followGeneration;
|
|
550
|
+
list.current?.scrollToEnd({ animated: true });
|
|
551
|
+
}
|
|
552
|
+
}, [context.followGeneration, context.following]);
|
|
553
|
+
const handleScroll = (0, react.useCallback)((event) => {
|
|
554
|
+
const { contentOffset, contentSize, layoutMeasurement } = event.nativeEvent;
|
|
555
|
+
const distance = contentSize.height - (contentOffset.y + layoutMeasurement.height);
|
|
556
|
+
context.updateAtBottom(distance <= scrollEndThreshold);
|
|
557
|
+
onScroll?.(event);
|
|
558
|
+
}, [context, onScroll]);
|
|
559
|
+
const handleContentSizeChange = (0, react.useCallback)((width, height) => {
|
|
560
|
+
const newFollowRequested = context.followGeneration > previousFollowGeneration.current;
|
|
561
|
+
const shouldScroll = following.current && (previousHeight.current === 0 || height > previousHeight.current || newFollowRequested);
|
|
562
|
+
previousHeight.current = height;
|
|
563
|
+
previousFollowGeneration.current = context.followGeneration;
|
|
564
|
+
if (shouldScroll) list.current?.scrollToEnd({ animated: true });
|
|
565
|
+
onContentSizeChange?.(width, height);
|
|
566
|
+
}, [context.followGeneration, onContentSizeChange]);
|
|
567
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.FlatList, {
|
|
568
|
+
...props,
|
|
569
|
+
data,
|
|
570
|
+
keyboardShouldPersistTaps,
|
|
571
|
+
onContentSizeChange: handleContentSizeChange,
|
|
572
|
+
onScroll: handleScroll,
|
|
573
|
+
ref: list,
|
|
574
|
+
renderItem,
|
|
575
|
+
scrollEventThrottle,
|
|
576
|
+
style: [styles$2.content, props.style],
|
|
577
|
+
contentContainerStyle: [styles$2.contentContainer, contentContainerStyle]
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
function ConversationEmptyState({ children, description = "Start a conversation to see messages here.", descriptionStyle, icon, style, title = "No messages yet", titleStyle,...props }) {
|
|
581
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
|
|
582
|
+
...props,
|
|
583
|
+
style: [styles$2.emptyState, style],
|
|
584
|
+
children: [
|
|
585
|
+
icon ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
586
|
+
accessibilityElementsHidden: true,
|
|
587
|
+
style: styles$2.emptyIcon,
|
|
588
|
+
children: icon
|
|
589
|
+
}) : null,
|
|
590
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
591
|
+
style: [styles$2.emptyTitle, titleStyle],
|
|
592
|
+
children: title
|
|
593
|
+
}),
|
|
594
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
595
|
+
style: [styles$2.emptyDescription, descriptionStyle],
|
|
596
|
+
children: description
|
|
597
|
+
}),
|
|
598
|
+
children
|
|
599
|
+
]
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
function ConversationScrollButton({ accessibilityLabel = "Scroll to latest message", activeOpacity = .2, children, onPress, style,...props }) {
|
|
603
|
+
const context = useConversation();
|
|
604
|
+
if (context.isAtBottom) return null;
|
|
605
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
|
|
606
|
+
...props,
|
|
607
|
+
accessibilityLabel,
|
|
608
|
+
accessibilityRole: "button",
|
|
609
|
+
onPress: () => {
|
|
610
|
+
context.requestFollow();
|
|
611
|
+
onPress?.();
|
|
612
|
+
},
|
|
613
|
+
style: (state) => [
|
|
614
|
+
styles$2.scrollButton,
|
|
615
|
+
resolveStyle$1(style, state),
|
|
616
|
+
state.pressed && { opacity: activeOpacity }
|
|
617
|
+
],
|
|
618
|
+
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SFSymbol, {
|
|
619
|
+
color: (0, react_native.PlatformColor)("systemBlue"),
|
|
620
|
+
size: 16,
|
|
621
|
+
symbol: "arrow.down"
|
|
622
|
+
})
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
function resolveStyle$1(style, state) {
|
|
626
|
+
return typeof style === "function" ? style(state) : style;
|
|
627
|
+
}
|
|
628
|
+
const styles$2 = react_native.StyleSheet.create({
|
|
629
|
+
conversation: {
|
|
630
|
+
flex: 1,
|
|
631
|
+
minHeight: 0,
|
|
632
|
+
position: "relative"
|
|
633
|
+
},
|
|
634
|
+
content: { flex: 1 },
|
|
635
|
+
contentContainer: {
|
|
636
|
+
gap: 16,
|
|
637
|
+
padding: 16
|
|
638
|
+
},
|
|
639
|
+
emptyState: {
|
|
640
|
+
alignItems: "center",
|
|
641
|
+
alignSelf: "center",
|
|
642
|
+
gap: 8,
|
|
643
|
+
justifyContent: "center",
|
|
644
|
+
maxWidth: 320,
|
|
645
|
+
padding: 32
|
|
646
|
+
},
|
|
647
|
+
emptyIcon: { marginBottom: 8 },
|
|
648
|
+
emptyTitle: {
|
|
649
|
+
color: (0, react_native.PlatformColor)("label"),
|
|
650
|
+
fontSize: 17,
|
|
651
|
+
fontWeight: "600",
|
|
652
|
+
textAlign: "center"
|
|
653
|
+
},
|
|
654
|
+
emptyDescription: {
|
|
655
|
+
color: (0, react_native.PlatformColor)("secondaryLabel"),
|
|
656
|
+
fontSize: 15,
|
|
657
|
+
textAlign: "center"
|
|
658
|
+
},
|
|
659
|
+
scrollButton: {
|
|
660
|
+
alignItems: "center",
|
|
661
|
+
backgroundColor: (0, react_native.PlatformColor)("secondarySystemBackground"),
|
|
662
|
+
borderColor: (0, react_native.PlatformColor)("separator"),
|
|
663
|
+
borderRadius: 18,
|
|
664
|
+
borderWidth: react_native.StyleSheet.hairlineWidth,
|
|
665
|
+
bottom: 16,
|
|
666
|
+
height: 36,
|
|
667
|
+
justifyContent: "center",
|
|
668
|
+
position: "absolute",
|
|
669
|
+
right: 16,
|
|
670
|
+
width: 36
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
|
|
385
674
|
//#endregion
|
|
386
675
|
//#region src/elements/glass-container.tsx
|
|
387
676
|
const GlassContainer = require_native_runtime.ensureNativeScript().defineUIKitContainer({
|
|
@@ -443,61 +732,300 @@ const Label = require_native_runtime.ensureNativeScript().defineUIKitView({
|
|
|
443
732
|
});
|
|
444
733
|
|
|
445
734
|
//#endregion
|
|
446
|
-
//#region src/elements/
|
|
447
|
-
function
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
735
|
+
//#region src/elements/message.tsx
|
|
736
|
+
function Message({ children, from = "assistant", style,...props }) {
|
|
737
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
738
|
+
...props,
|
|
739
|
+
style: [
|
|
740
|
+
styles$1.message,
|
|
741
|
+
from === "user" ? styles$1.userMessage : styles$1.assistantMessage,
|
|
742
|
+
style
|
|
743
|
+
],
|
|
744
|
+
children
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
function MessageContent({ children, style,...props }) {
|
|
748
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
749
|
+
...props,
|
|
750
|
+
style: [styles$1.content, style],
|
|
751
|
+
children
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
function MessageText({ style,...props }) {
|
|
755
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
756
|
+
...props,
|
|
757
|
+
style: [styles$1.text, style]
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
function MessageStatus({ label, showSymbol = true, status, style,...props }) {
|
|
761
|
+
const display = messageStatusDisplay(status);
|
|
762
|
+
const color = (0, react_native.PlatformColor)(display.color);
|
|
763
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
|
|
764
|
+
style: styles$1.status,
|
|
765
|
+
children: [showSymbol ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SFSymbol, {
|
|
766
|
+
color,
|
|
767
|
+
size: 12,
|
|
768
|
+
symbol: display.symbol
|
|
769
|
+
}) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
770
|
+
...props,
|
|
771
|
+
style: [
|
|
772
|
+
styles$1.statusText,
|
|
773
|
+
{ color },
|
|
774
|
+
style
|
|
775
|
+
],
|
|
776
|
+
children: label ?? display.label
|
|
777
|
+
})]
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
function MessageActions({ children, style,...props }) {
|
|
781
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
782
|
+
...props,
|
|
783
|
+
style: [styles$1.actions, style],
|
|
784
|
+
children
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
const styles$1 = react_native.StyleSheet.create({
|
|
788
|
+
message: {
|
|
789
|
+
gap: 6,
|
|
790
|
+
maxWidth: "85%"
|
|
791
|
+
},
|
|
792
|
+
userMessage: { alignSelf: "flex-end" },
|
|
793
|
+
assistantMessage: { alignSelf: "stretch" },
|
|
794
|
+
content: {
|
|
795
|
+
backgroundColor: (0, react_native.PlatformColor)("secondarySystemFill"),
|
|
796
|
+
borderRadius: 16,
|
|
797
|
+
paddingHorizontal: 14,
|
|
798
|
+
paddingVertical: 10
|
|
799
|
+
},
|
|
800
|
+
text: {
|
|
801
|
+
color: (0, react_native.PlatformColor)("label"),
|
|
802
|
+
fontSize: 15,
|
|
803
|
+
lineHeight: 21
|
|
804
|
+
},
|
|
805
|
+
status: {
|
|
806
|
+
alignItems: "center",
|
|
807
|
+
flexDirection: "row",
|
|
808
|
+
gap: 5
|
|
809
|
+
},
|
|
810
|
+
statusText: {
|
|
811
|
+
fontSize: 12,
|
|
812
|
+
fontWeight: "500"
|
|
813
|
+
},
|
|
814
|
+
actions: {
|
|
815
|
+
flexDirection: "row",
|
|
816
|
+
flexWrap: "wrap",
|
|
817
|
+
gap: 8
|
|
458
818
|
}
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
//#endregion
|
|
822
|
+
//#region src/elements/prompt-input.tsx
|
|
823
|
+
const PromptInputContext = (0, react.createContext)(null);
|
|
824
|
+
function usePromptInput() {
|
|
825
|
+
const context = (0, react.useContext)(PromptInputContext);
|
|
826
|
+
if (!context) throw new Error("Prompt input elements must be rendered inside <PromptInput>");
|
|
827
|
+
return context;
|
|
459
828
|
}
|
|
460
|
-
function
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
829
|
+
function PromptInput({ children, defaultValue = "", disabled = false, onChangeText, onSubmit, status, style, value,...props }) {
|
|
830
|
+
const controlled = value !== void 0;
|
|
831
|
+
const [internalText, setInternalText] = (0, react.useState)(defaultValue);
|
|
832
|
+
const text = controlled ? value : internalText;
|
|
833
|
+
const setText = (0, react.useCallback)((nextText) => {
|
|
834
|
+
if (!controlled) setInternalText(nextText);
|
|
835
|
+
onChangeText?.(nextText);
|
|
836
|
+
}, [controlled, onChangeText]);
|
|
837
|
+
const submit = (0, react.useCallback)(() => {
|
|
838
|
+
if (disabled) return;
|
|
839
|
+
onSubmit?.({ text });
|
|
840
|
+
}, [
|
|
841
|
+
disabled,
|
|
842
|
+
onSubmit,
|
|
843
|
+
text
|
|
844
|
+
]);
|
|
845
|
+
const context = (0, react.useMemo)(() => ({
|
|
846
|
+
disabled,
|
|
847
|
+
generating: promptStatusGenerating(status),
|
|
848
|
+
setText,
|
|
849
|
+
status,
|
|
850
|
+
submit,
|
|
851
|
+
text
|
|
852
|
+
}), [
|
|
853
|
+
disabled,
|
|
854
|
+
setText,
|
|
855
|
+
status,
|
|
856
|
+
submit,
|
|
857
|
+
text
|
|
858
|
+
]);
|
|
859
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PromptInputContext.Provider, {
|
|
860
|
+
value: context,
|
|
861
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
862
|
+
...props,
|
|
863
|
+
style: [styles.input, style],
|
|
864
|
+
children
|
|
865
|
+
})
|
|
866
|
+
});
|
|
464
867
|
}
|
|
465
|
-
function
|
|
466
|
-
|
|
467
|
-
|
|
868
|
+
function PromptInputHeader({ children, style,...props }) {
|
|
869
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
870
|
+
...props,
|
|
871
|
+
style: [styles.header, style],
|
|
872
|
+
children
|
|
873
|
+
});
|
|
468
874
|
}
|
|
469
|
-
function
|
|
470
|
-
|
|
471
|
-
|
|
875
|
+
function PromptInputBody({ children, style,...props }) {
|
|
876
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
877
|
+
...props,
|
|
878
|
+
style: [styles.body, style],
|
|
879
|
+
children
|
|
880
|
+
});
|
|
472
881
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
882
|
+
function PromptInputFooter({ children, style,...props }) {
|
|
883
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
884
|
+
...props,
|
|
885
|
+
style: [styles.footer, style],
|
|
886
|
+
children
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
function PromptInputTools({ children, style,...props }) {
|
|
890
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
|
|
891
|
+
...props,
|
|
892
|
+
style: [styles.tools, style],
|
|
893
|
+
children
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
function PromptInputTextarea({ multiline = true, onChangeText, onSubmitEditing, placeholder = "Send a message", placeholderTextColor = (0, react_native.PlatformColor)("placeholderText"), returnKeyType = "send", style, submitOnEnter = !multiline, value,...props }) {
|
|
897
|
+
const context = usePromptInput();
|
|
898
|
+
const text = value !== void 0 ? value : context.text;
|
|
899
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.TextInput, {
|
|
900
|
+
...props,
|
|
901
|
+
editable: !context.disabled && props.editable !== false,
|
|
902
|
+
multiline,
|
|
903
|
+
onChangeText: (nextText) => {
|
|
904
|
+
context.setText(nextText);
|
|
905
|
+
onChangeText?.(nextText);
|
|
906
|
+
},
|
|
907
|
+
onSubmitEditing: (event) => {
|
|
908
|
+
onSubmitEditing?.(event);
|
|
909
|
+
if (submitOnEnter) context.submit();
|
|
910
|
+
},
|
|
911
|
+
placeholder,
|
|
912
|
+
placeholderTextColor,
|
|
913
|
+
returnKeyType,
|
|
914
|
+
style: [styles.textarea, style],
|
|
915
|
+
submitBehavior: multiline && !submitOnEnter ? "newline" : "submit",
|
|
916
|
+
value: text
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
function PromptInputSubmit({ accessibilityLabel, accessibilityState, activeOpacity = .2, children, disabled: disabledProp, generating, loading = false, onPress, status, style,...props }) {
|
|
920
|
+
const context = usePromptInput();
|
|
921
|
+
const resolvedStatus = status ?? context.status;
|
|
922
|
+
const resolvedGenerating = generating ?? loading ?? promptStatusGenerating(resolvedStatus);
|
|
923
|
+
const disabled = context.disabled || buttonDisabled(disabledProp === true, loading);
|
|
924
|
+
const resolvedChildren = typeof children === "function" ? children({ generating: resolvedGenerating }) : children;
|
|
925
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Pressable, {
|
|
926
|
+
...props,
|
|
927
|
+
accessibilityLabel: accessibilityLabel ?? promptStatusLabel(resolvedStatus, resolvedGenerating),
|
|
928
|
+
accessibilityRole: "button",
|
|
929
|
+
accessibilityState: {
|
|
930
|
+
...accessibilityState,
|
|
931
|
+
busy: resolvedGenerating,
|
|
932
|
+
disabled
|
|
933
|
+
},
|
|
934
|
+
disabled,
|
|
935
|
+
onPress: () => {
|
|
936
|
+
if (onPress) onPress({ text: context.text });
|
|
937
|
+
else context.submit();
|
|
938
|
+
},
|
|
939
|
+
style: (state) => [
|
|
940
|
+
styles.submit,
|
|
941
|
+
resolveStyle(style, state),
|
|
942
|
+
{ opacity: buttonOpacity({
|
|
943
|
+
...state,
|
|
944
|
+
disabled,
|
|
945
|
+
loading,
|
|
946
|
+
activeOpacity
|
|
947
|
+
}) }
|
|
948
|
+
],
|
|
949
|
+
children: resolvedChildren ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SFSymbol, {
|
|
950
|
+
color: "#ffffff",
|
|
951
|
+
size: 16,
|
|
952
|
+
symbol: promptStatusSymbol(resolvedStatus, resolvedGenerating),
|
|
953
|
+
weight: "semibold"
|
|
954
|
+
})
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
function resolveStyle(style, state) {
|
|
958
|
+
return typeof style === "function" ? style(state) : style;
|
|
959
|
+
}
|
|
960
|
+
const styles = react_native.StyleSheet.create({
|
|
961
|
+
input: {
|
|
962
|
+
backgroundColor: (0, react_native.PlatformColor)("secondarySystemBackground"),
|
|
963
|
+
borderColor: (0, react_native.PlatformColor)("separator"),
|
|
964
|
+
borderRadius: 18,
|
|
965
|
+
borderWidth: react_native.StyleSheet.hairlineWidth,
|
|
966
|
+
gap: 8,
|
|
967
|
+
padding: 10
|
|
481
968
|
},
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
969
|
+
header: { gap: 8 },
|
|
970
|
+
body: { gap: 8 },
|
|
971
|
+
footer: {
|
|
972
|
+
alignItems: "center",
|
|
973
|
+
flexDirection: "row",
|
|
974
|
+
gap: 8,
|
|
975
|
+
justifyContent: "space-between"
|
|
486
976
|
},
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
977
|
+
tools: {
|
|
978
|
+
alignItems: "center",
|
|
979
|
+
flexDirection: "row",
|
|
980
|
+
flex: 1,
|
|
981
|
+
flexWrap: "wrap",
|
|
982
|
+
gap: 8
|
|
983
|
+
},
|
|
984
|
+
textarea: {
|
|
985
|
+
color: (0, react_native.PlatformColor)("label"),
|
|
986
|
+
fontSize: 15,
|
|
987
|
+
minHeight: 40,
|
|
988
|
+
padding: 4
|
|
989
|
+
},
|
|
990
|
+
submit: {
|
|
991
|
+
alignItems: "center",
|
|
992
|
+
alignSelf: "flex-end",
|
|
993
|
+
backgroundColor: (0, react_native.PlatformColor)("systemBlue"),
|
|
994
|
+
borderRadius: 18,
|
|
995
|
+
height: 36,
|
|
996
|
+
justifyContent: "center",
|
|
997
|
+
minWidth: 36,
|
|
998
|
+
paddingHorizontal: 9
|
|
493
999
|
}
|
|
494
1000
|
});
|
|
495
1001
|
|
|
496
1002
|
//#endregion
|
|
497
1003
|
exports.BlurView = BlurView;
|
|
498
1004
|
exports.Button = Button;
|
|
1005
|
+
exports.Conversation = Conversation;
|
|
1006
|
+
exports.ConversationContent = ConversationContent;
|
|
1007
|
+
exports.ConversationEmptyState = ConversationEmptyState;
|
|
1008
|
+
exports.ConversationScrollButton = ConversationScrollButton;
|
|
499
1009
|
exports.GlassButton = GlassButton;
|
|
500
1010
|
exports.GlassContainer = GlassContainer;
|
|
501
1011
|
exports.GlassView = GlassView;
|
|
502
1012
|
exports.Label = Label;
|
|
503
|
-
exports.
|
|
1013
|
+
exports.Message = Message;
|
|
1014
|
+
exports.MessageActions = MessageActions;
|
|
1015
|
+
exports.MessageContent = MessageContent;
|
|
1016
|
+
exports.MessageStatus = MessageStatus;
|
|
1017
|
+
exports.MessageText = MessageText;
|
|
1018
|
+
exports.PromptInput = PromptInput;
|
|
1019
|
+
exports.PromptInputBody = PromptInputBody;
|
|
1020
|
+
exports.PromptInputFooter = PromptInputFooter;
|
|
1021
|
+
exports.PromptInputHeader = PromptInputHeader;
|
|
1022
|
+
exports.PromptInputSubmit = PromptInputSubmit;
|
|
1023
|
+
exports.PromptInputTextarea = PromptInputTextarea;
|
|
1024
|
+
exports.PromptInputTools = PromptInputTools;
|
|
1025
|
+
exports.SFSymbol = SFSymbol;
|
|
1026
|
+
exports.messageStatusDisplay = messageStatusDisplay;
|
|
1027
|
+
exports.promptStatusGenerating = promptStatusGenerating;
|
|
1028
|
+
exports.promptStatusLabel = promptStatusLabel;
|
|
1029
|
+
exports.promptStatusSymbol = promptStatusSymbol;
|
|
1030
|
+
exports.useConversation = useConversation;
|
|
1031
|
+
exports.usePromptInput = usePromptInput;
|