@retor/react-native 0.2.0 → 0.3.1

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/index.mjs CHANGED
@@ -313,28 +313,52 @@ function Hud({ children }) {
313
313
  }
314
314
 
315
315
  // src/ProjectSheet.tsx
316
- import React4, { useEffect as useEffect2, useMemo as useMemo3, useRef as useRef2 } from "react";
317
- import { Pressable, ScrollView, StyleSheet as StyleSheet3, Text, View as View3 } from "react-native";
316
+ import React5, { useEffect as useEffect2, useMemo as useMemo3, useRef as useRef2, useState as useState2 } from "react";
317
+ import { Pressable, ScrollView, StyleSheet as StyleSheet4, Text, View as View4 } from "react-native";
318
318
  import { BottomSheetBackdrop, BottomSheetModal, BottomSheetView } from "@gorhom/bottom-sheet";
319
- function ProjectSheet({ snapPoints = ["20%", "60%"], renderHeader, children }) {
319
+ import { ArrowDown, ArrowUp } from "lucide-react-native";
320
+
321
+ // src/BlurBackground.tsx
322
+ import React4 from "react";
323
+ import { StyleSheet as StyleSheet3, View as View3 } from "react-native";
324
+ import { BlurView } from "expo-blur";
325
+ function BlurBackground({ style }) {
326
+ return /* @__PURE__ */ React4.createElement(View3, { style: [style, StyleSheet3.absoluteFill, { overflow: "hidden", borderTopLeftRadius: 24, borderTopRightRadius: 24 }] }, /* @__PURE__ */ React4.createElement(BlurView, { intensity: 60, tint: "dark", style: StyleSheet3.absoluteFill }), /* @__PURE__ */ React4.createElement(View3, { style: [StyleSheet3.absoluteFill, { backgroundColor: "rgba(20,20,20,0.55)" }] }));
327
+ }
328
+
329
+ // src/ProjectSheet.tsx
330
+ function ProjectSheet({ snapPoints = ["35%", "85%"], renderHeader, children }) {
320
331
  const { project, activeLineId, isAddNoteOpen } = useRetorBridge();
321
332
  const sheetRef = useRef2(null);
322
333
  const snapPointsArr = useMemo3(() => snapPoints, [snapPoints]);
334
+ const [minimized, setMinimized] = useState2(false);
323
335
  useEffect2(() => {
324
336
  if (activeLineId || isAddNoteOpen) {
325
337
  sheetRef.current?.dismiss();
326
338
  } else {
327
339
  sheetRef.current?.present();
340
+ setMinimized(false);
328
341
  }
329
342
  }, [activeLineId, isAddNoteOpen]);
330
- return /* @__PURE__ */ React4.createElement(
343
+ const handleSheetChange = (index) => {
344
+ setMinimized(index === 0);
345
+ };
346
+ const toggleMinimize = () => {
347
+ if (minimized) {
348
+ sheetRef.current?.snapToIndex(snapPointsArr.length - 1);
349
+ } else {
350
+ sheetRef.current?.snapToIndex(0);
351
+ }
352
+ };
353
+ return /* @__PURE__ */ React5.createElement(
331
354
  BottomSheetModal,
332
355
  {
333
356
  ref: sheetRef,
334
357
  snapPoints: snapPointsArr,
335
358
  enablePanDownToClose: false,
336
359
  enableDismissOnClose: false,
337
- backdropComponent: (props) => /* @__PURE__ */ React4.createElement(
360
+ onChange: handleSheetChange,
361
+ backdropComponent: (props) => /* @__PURE__ */ React5.createElement(
338
362
  BottomSheetBackdrop,
339
363
  {
340
364
  ...props,
@@ -345,48 +369,69 @@ function ProjectSheet({ snapPoints = ["20%", "60%"], renderHeader, children }) {
345
369
  }
346
370
  ),
347
371
  handleIndicatorStyle: styles2.handle,
348
- backgroundStyle: styles2.background
372
+ backgroundComponent: BlurBackground
349
373
  },
350
- /* @__PURE__ */ React4.createElement(BottomSheetView, { style: styles2.content }, renderHeader ? renderHeader({ name: project?.name, description: project?.description }) : /* @__PURE__ */ React4.createElement(View3, { style: styles2.header }, project?.name && /* @__PURE__ */ React4.createElement(Text, { style: styles2.title }, project.name), project?.description && /* @__PURE__ */ React4.createElement(Text, { style: styles2.subtitle, numberOfLines: 4 }, project.description)), children ?? /* @__PURE__ */ React4.createElement(DefaultLinesCarousel, null))
374
+ /* @__PURE__ */ React5.createElement(BottomSheetView, { style: styles2.content }, renderHeader ? renderHeader({ name: project?.name, description: project?.description }) : /* @__PURE__ */ React5.createElement(View4, { style: styles2.header }, /* @__PURE__ */ React5.createElement(View4, { style: { flex: 1, minWidth: 0 } }, project?.name && /* @__PURE__ */ React5.createElement(Text, { style: styles2.title, numberOfLines: 1 }, project.name), project?.description && /* @__PURE__ */ React5.createElement(Text, { style: styles2.subtitle, numberOfLines: 4 }, project.description)), /* @__PURE__ */ React5.createElement(Pressable, { style: styles2.iconBtn, onPress: toggleMinimize }, minimized ? /* @__PURE__ */ React5.createElement(ArrowUp, { size: 14, color: "rgba(255,255,255,0.6)" }) : /* @__PURE__ */ React5.createElement(ArrowDown, { size: 14, color: "rgba(255,255,255,0.6)" }))), children ?? /* @__PURE__ */ React5.createElement(DefaultLinesCarousel, null))
351
375
  );
352
376
  }
353
377
  function DefaultLinesCarousel() {
354
- return /* @__PURE__ */ React4.createElement(LinesCarousel, null, (line) => /* @__PURE__ */ React4.createElement(DefaultLineCard, { line }));
378
+ return /* @__PURE__ */ React5.createElement(LinesCarousel, null, (line) => /* @__PURE__ */ React5.createElement(DefaultLineCard, { line }));
355
379
  }
356
380
  function LinesCarousel({ children, gap = 12, paddingHorizontal = 16 }) {
357
381
  const { lines } = useRetorBridge();
358
382
  if (lines.length === 0) return null;
359
- return /* @__PURE__ */ React4.createElement(
383
+ return /* @__PURE__ */ React5.createElement(View4, { style: styles2.carouselWrap }, /* @__PURE__ */ React5.createElement(Text, { style: styles2.carouselLabel }, "Routes"), /* @__PURE__ */ React5.createElement(
360
384
  ScrollView,
361
385
  {
362
386
  horizontal: true,
363
387
  showsHorizontalScrollIndicator: false,
364
- contentContainerStyle: { paddingHorizontal, gap },
365
- style: styles2.carousel
388
+ contentContainerStyle: { paddingHorizontal, gap }
366
389
  },
367
- lines.map((line, idx) => /* @__PURE__ */ React4.createElement(React4.Fragment, { key: line._id }, children(line, idx)))
368
- );
390
+ lines.map((line, idx) => /* @__PURE__ */ React5.createElement(React5.Fragment, { key: line._id }, children(line, idx)))
391
+ ));
369
392
  }
370
393
  function DefaultLineCard({ line }) {
371
394
  const { controls } = useRetorBridge();
372
- return /* @__PURE__ */ React4.createElement(
395
+ return /* @__PURE__ */ React5.createElement(
373
396
  Pressable,
374
397
  {
375
398
  onPress: () => controls.openLine(line._id),
376
399
  style: styles2.lineCard
377
400
  },
378
- /* @__PURE__ */ React4.createElement(Text, { style: styles2.lineCardTitle, numberOfLines: 1 }, line.name || "Line"),
379
- line.subtitle && /* @__PURE__ */ React4.createElement(Text, { style: styles2.lineCardSubtitle, numberOfLines: 2 }, line.subtitle)
401
+ /* @__PURE__ */ React5.createElement(Text, { style: styles2.lineCardTitle, numberOfLines: 1 }, line.name || "Line"),
402
+ line.subtitle && /* @__PURE__ */ React5.createElement(Text, { style: styles2.lineCardSubtitle, numberOfLines: 2 }, line.subtitle)
380
403
  );
381
404
  }
382
- var styles2 = StyleSheet3.create({
383
- background: { backgroundColor: "rgba(20,20,20,0.95)" },
405
+ var styles2 = StyleSheet4.create({
384
406
  handle: { backgroundColor: "rgba(255,255,255,0.3)" },
385
407
  content: { flex: 1, paddingTop: 12, paddingBottom: 24 },
386
- header: { paddingHorizontal: 24, paddingBottom: 16 },
408
+ header: {
409
+ flexDirection: "row",
410
+ alignItems: "flex-start",
411
+ paddingHorizontal: 24,
412
+ paddingBottom: 16,
413
+ gap: 8
414
+ },
387
415
  title: { color: "white", fontSize: 18, fontWeight: "600", lineHeight: 22 },
388
416
  subtitle: { color: "rgba(255,255,255,0.6)", fontSize: 13, marginTop: 4, lineHeight: 18 },
389
- carousel: { marginTop: 8 },
417
+ iconBtn: {
418
+ width: 28,
419
+ height: 28,
420
+ borderRadius: 14,
421
+ backgroundColor: "rgba(255,255,255,0.1)",
422
+ alignItems: "center",
423
+ justifyContent: "center"
424
+ },
425
+ carouselWrap: { marginTop: 8 },
426
+ carouselLabel: {
427
+ color: "rgba(255,255,255,0.4)",
428
+ fontSize: 10,
429
+ textTransform: "uppercase",
430
+ letterSpacing: 1,
431
+ fontWeight: "500",
432
+ paddingHorizontal: 24,
433
+ marginBottom: 8
434
+ },
390
435
  lineCard: {
391
436
  width: 220,
392
437
  backgroundColor: "rgba(255,255,255,0.06)",
@@ -398,28 +443,54 @@ var styles2 = StyleSheet3.create({
398
443
  });
399
444
 
400
445
  // src/LineDetailSheet.tsx
401
- import React5, { useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3 } from "react";
402
- import { Pressable as Pressable2, StyleSheet as StyleSheet4, Text as Text2, View as View4 } from "react-native";
403
- import { BottomSheetBackdrop as BottomSheetBackdrop2, BottomSheetFlatList, BottomSheetModal as BottomSheetModal2, BottomSheetView as BottomSheetView2 } from "@gorhom/bottom-sheet";
404
- function LineDetailSheet({ snapPoints = ["25%", "75%"], renderHeader, children }) {
446
+ import React6, { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState3 } from "react";
447
+ import { Pressable as Pressable2, StyleSheet as StyleSheet5, Text as Text2, View as View5 } from "react-native";
448
+ import {
449
+ BottomSheetBackdrop as BottomSheetBackdrop2,
450
+ BottomSheetFlatList,
451
+ BottomSheetFooter,
452
+ BottomSheetModal as BottomSheetModal2
453
+ } from "@gorhom/bottom-sheet";
454
+ import Svg, { Circle } from "react-native-svg";
455
+ import { ArrowDown as ArrowDown2, ArrowUp as ArrowUp2, Pause, Play, Plus } from "lucide-react-native";
456
+ function LineDetailSheet({ snapPoints = ["35%", "85%"], renderHeader, children }) {
405
457
  const { activeLine, isAddNoteOpen, controls } = useRetorBridge();
406
458
  const sheetRef = useRef3(null);
407
459
  const snapPointsArr = useMemo4(() => snapPoints, [snapPoints]);
460
+ const [minimized, setMinimized] = useState3(false);
408
461
  useEffect3(() => {
409
462
  if (activeLine && !isAddNoteOpen) {
410
463
  sheetRef.current?.present();
464
+ setMinimized(false);
411
465
  } else {
412
466
  sheetRef.current?.dismiss();
413
467
  }
414
468
  }, [activeLine, isAddNoteOpen]);
415
- return /* @__PURE__ */ React5.createElement(
469
+ const handleSheetChange = (index) => {
470
+ setMinimized(index === 0);
471
+ };
472
+ const toggleMinimize = () => {
473
+ if (minimized) {
474
+ sheetRef.current?.snapToIndex(snapPointsArr.length - 1);
475
+ } else {
476
+ sheetRef.current?.snapToIndex(0);
477
+ }
478
+ };
479
+ const renderFooter = useCallback2(
480
+ (props) => /* @__PURE__ */ React6.createElement(BottomSheetFooter, { ...props, bottomInset: 0 }, /* @__PURE__ */ React6.createElement(View5, { style: styles3.footer }, /* @__PURE__ */ React6.createElement(Pressable2, { style: styles3.doneButton, onPress: () => controls.exitLine() }, /* @__PURE__ */ React6.createElement(Text2, { style: styles3.doneText }, "Done")))),
481
+ [controls]
482
+ );
483
+ const header = activeLine ? renderHeader ? renderHeader(activeLine) : /* @__PURE__ */ React6.createElement(DefaultHeader, { line: activeLine, minimized, onToggleMinimize: toggleMinimize }) : null;
484
+ return /* @__PURE__ */ React6.createElement(
416
485
  BottomSheetModal2,
417
486
  {
418
487
  ref: sheetRef,
419
488
  snapPoints: snapPointsArr,
420
489
  enablePanDownToClose: false,
421
490
  enableDismissOnClose: false,
422
- backdropComponent: (props) => /* @__PURE__ */ React5.createElement(
491
+ onChange: handleSheetChange,
492
+ footerComponent: renderFooter,
493
+ backdropComponent: (props) => /* @__PURE__ */ React6.createElement(
423
494
  BottomSheetBackdrop2,
424
495
  {
425
496
  ...props,
@@ -430,63 +501,158 @@ function LineDetailSheet({ snapPoints = ["25%", "75%"], renderHeader, children }
430
501
  }
431
502
  ),
432
503
  handleIndicatorStyle: styles3.handle,
433
- backgroundStyle: styles3.background
504
+ backgroundComponent: BlurBackground
434
505
  },
435
- /* @__PURE__ */ React5.createElement(BottomSheetView2, { style: styles3.content }, activeLine && (renderHeader ? renderHeader(activeLine) : /* @__PURE__ */ React5.createElement(View4, { style: styles3.header }, /* @__PURE__ */ React5.createElement(Text2, { style: styles3.title }, activeLine.name), activeLine.subtitle && /* @__PURE__ */ React5.createElement(Text2, { style: styles3.subtitle }, activeLine.subtitle), activeLine.description && /* @__PURE__ */ React5.createElement(Text2, { style: styles3.description, numberOfLines: 4 }, activeLine.description))), children ?? /* @__PURE__ */ React5.createElement(DefaultLineTagList, null), /* @__PURE__ */ React5.createElement(View4, { style: styles3.footer }, /* @__PURE__ */ React5.createElement(Pressable2, { style: styles3.doneButton, onPress: () => controls.exitLine() }, /* @__PURE__ */ React5.createElement(Text2, { style: styles3.doneText }, "Done"))))
506
+ activeLine && (children ?? /* @__PURE__ */ React6.createElement(DefaultLineTagList, { listHeader: header }))
436
507
  );
437
508
  }
438
- function DefaultLineTagList() {
439
- return /* @__PURE__ */ React5.createElement(LineTagList, null, (tag, isActive) => /* @__PURE__ */ React5.createElement(DefaultTagItem, { tag, isActive }));
509
+ function DefaultHeader({
510
+ line,
511
+ minimized,
512
+ onToggleMinimize
513
+ }) {
514
+ return /* @__PURE__ */ React6.createElement(View5, { style: styles3.header }, /* @__PURE__ */ React6.createElement(View5, { style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text2, { style: styles3.title, numberOfLines: 1 }, line.name), line.subtitle && /* @__PURE__ */ React6.createElement(Text2, { style: styles3.subtitle, numberOfLines: 1 }, line.subtitle), line.description && /* @__PURE__ */ React6.createElement(Text2, { style: styles3.description, numberOfLines: minimized ? 2 : 4 }, line.description)), /* @__PURE__ */ React6.createElement(View5, { style: styles3.headerActions }, /* @__PURE__ */ React6.createElement(AutoplayButton, null), /* @__PURE__ */ React6.createElement(Pressable2, { style: styles3.iconBtn, onPress: onToggleMinimize }, minimized ? /* @__PURE__ */ React6.createElement(ArrowUp2, { size: 14, color: "rgba(255,255,255,0.6)" }) : /* @__PURE__ */ React6.createElement(ArrowDown2, { size: 14, color: "rgba(255,255,255,0.6)" }))));
515
+ }
516
+ function AutoplayButton() {
517
+ const { isPlaying, progress, controls } = useRetorBridge();
518
+ const r = 12.5;
519
+ const c = 2 * Math.PI * r;
520
+ return /* @__PURE__ */ React6.createElement(Pressable2, { style: styles3.iconBtn, onPress: () => controls.toggleAutoplay() }, /* @__PURE__ */ React6.createElement(Svg, { width: 28, height: 28, style: StyleSheet5.absoluteFill }, /* @__PURE__ */ React6.createElement(
521
+ Circle,
522
+ {
523
+ cx: 14,
524
+ cy: 14,
525
+ r,
526
+ fill: "none",
527
+ stroke: "white",
528
+ strokeWidth: 2,
529
+ strokeDasharray: `${c}`,
530
+ strokeDashoffset: c * (1 - progress),
531
+ strokeLinecap: "round",
532
+ transform: "rotate(-90, 14, 14)"
533
+ }
534
+ )), isPlaying ? /* @__PURE__ */ React6.createElement(Pause, { size: 11, color: "white", fill: "white" }) : /* @__PURE__ */ React6.createElement(Play, { size: 11, color: "white", fill: "white", style: { marginLeft: 1 } }));
440
535
  }
441
- function LineTagList({ children }) {
536
+ function LineTagList({ children, listHeader }) {
442
537
  const { activeLine, closestTagId } = useRetorBridge();
538
+ const listRef = useRef3(null);
443
539
  const tags = useMemo4(
444
540
  () => (activeLine?.tags ?? []).filter((t) => t.name && t.name.trim().length > 0),
445
541
  [activeLine]
446
542
  );
543
+ useEffect3(() => {
544
+ if (!closestTagId) return;
545
+ const index = tags.findIndex((t2) => t2._id === closestTagId);
546
+ if (index < 0) return;
547
+ const t = setTimeout(() => {
548
+ try {
549
+ listRef.current?.scrollToIndex({ index, animated: true, viewPosition: 0 });
550
+ } catch {
551
+ }
552
+ }, 50);
553
+ return () => clearTimeout(t);
554
+ }, [closestTagId, tags]);
447
555
  if (!activeLine) return null;
448
- return /* @__PURE__ */ React5.createElement(
556
+ return /* @__PURE__ */ React6.createElement(
449
557
  BottomSheetFlatList,
450
558
  {
559
+ ref: listRef,
451
560
  data: tags,
452
561
  keyExtractor: (t) => t._id,
453
- renderItem: ({ item }) => /* @__PURE__ */ React5.createElement(View4, null, children(item, item._id === closestTagId)),
454
- contentContainerStyle: styles3.list
562
+ ListHeaderComponent: listHeader ? () => /* @__PURE__ */ React6.createElement(React6.Fragment, null, listHeader) : void 0,
563
+ renderItem: ({ item }) => /* @__PURE__ */ React6.createElement(View5, null, children(item, item._id === closestTagId)),
564
+ contentContainerStyle: styles3.list,
565
+ removeClippedSubviews: false,
566
+ onScrollToIndexFailed: (info) => {
567
+ const offset = info.averageItemLength * info.index;
568
+ listRef.current?.scrollToOffset({ offset, animated: false });
569
+ setTimeout(() => {
570
+ try {
571
+ listRef.current?.scrollToIndex({ index: info.index, animated: true, viewPosition: 0 });
572
+ } catch {
573
+ }
574
+ }, 100);
575
+ }
455
576
  }
456
577
  );
457
578
  }
579
+ function DefaultLineTagList({ listHeader }) {
580
+ return /* @__PURE__ */ React6.createElement(LineTagList, { listHeader }, (tag, isActive) => /* @__PURE__ */ React6.createElement(DefaultTagItem, { tag, isActive }));
581
+ }
458
582
  function DefaultTagItem({ tag, isActive }) {
459
- const { controls } = useRetorBridge();
460
- return /* @__PURE__ */ React5.createElement(
583
+ const { controls, openAddNote } = useRetorBridge();
584
+ return /* @__PURE__ */ React6.createElement(
461
585
  Pressable2,
462
586
  {
463
587
  onPress: () => controls.scrollToTag(tag._id),
464
588
  style: [styles3.tagItem, isActive && styles3.tagItemActive]
465
589
  },
466
- /* @__PURE__ */ React5.createElement(Text2, { style: [styles3.tagText, isActive && styles3.tagTextActive], numberOfLines: 1 }, tag.name),
467
- tag.subtitle && /* @__PURE__ */ React5.createElement(Text2, { style: styles3.tagSubtitle, numberOfLines: 1 }, tag.subtitle)
590
+ /* @__PURE__ */ React6.createElement(View5, { style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text2, { style: [styles3.tagText, isActive && styles3.tagTextActive], numberOfLines: 1 }, tag.name), isActive && tag.description && /* @__PURE__ */ React6.createElement(Text2, { style: styles3.tagDescription, numberOfLines: 2 }, tag.description)),
591
+ tag.subtitle && /* @__PURE__ */ React6.createElement(Text2, { style: styles3.tagSubtitle, numberOfLines: 1 }, tag.subtitle),
592
+ isActive && /* @__PURE__ */ React6.createElement(
593
+ Pressable2,
594
+ {
595
+ onPress: (e) => {
596
+ e.stopPropagation();
597
+ openAddNote(tag._id);
598
+ },
599
+ style: styles3.plusBtn
600
+ },
601
+ /* @__PURE__ */ React6.createElement(Plus, { size: 14, color: "white" })
602
+ )
468
603
  );
469
604
  }
470
- var styles3 = StyleSheet4.create({
471
- background: { backgroundColor: "rgba(20,20,20,0.95)" },
605
+ var styles3 = StyleSheet5.create({
472
606
  handle: { backgroundColor: "rgba(255,255,255,0.3)" },
473
- content: { flex: 1 },
474
- header: { paddingHorizontal: 24, paddingTop: 8, paddingBottom: 12 },
475
- title: { color: "white", fontSize: 20, fontWeight: "700" },
476
- subtitle: { color: "rgba(255,255,255,0.5)", fontSize: 12, marginTop: 4 },
477
- description: { color: "rgba(255,255,255,0.7)", fontSize: 13, marginTop: 8, lineHeight: 18 },
478
- list: { paddingHorizontal: 16, paddingBottom: 8 },
607
+ header: {
608
+ flexDirection: "row",
609
+ alignItems: "flex-start",
610
+ paddingHorizontal: 24,
611
+ paddingTop: 8,
612
+ paddingBottom: 16,
613
+ gap: 8
614
+ },
615
+ headerActions: { flexDirection: "row", alignItems: "center", gap: 6 },
616
+ title: { color: "white", fontSize: 18, fontWeight: "700" },
617
+ subtitle: { color: "rgba(255,255,255,0.5)", fontSize: 12, marginTop: 2 },
618
+ description: { color: "rgba(255,255,255,0.6)", fontSize: 12, marginTop: 6, lineHeight: 18 },
619
+ iconBtn: {
620
+ width: 28,
621
+ height: 28,
622
+ borderRadius: 14,
623
+ backgroundColor: "rgba(255,255,255,0.1)",
624
+ alignItems: "center",
625
+ justifyContent: "center",
626
+ position: "relative"
627
+ },
628
+ list: { paddingHorizontal: 16, paddingBottom: 96, gap: 4 },
479
629
  tagItem: {
630
+ flexDirection: "row",
631
+ alignItems: "center",
480
632
  paddingHorizontal: 12,
481
- paddingVertical: 10,
633
+ paddingVertical: 12,
482
634
  borderRadius: 12,
483
- marginBottom: 4
635
+ gap: 8
484
636
  },
485
637
  tagItemActive: { backgroundColor: "rgba(255,255,255,0.1)" },
486
- tagText: { color: "rgba(255,255,255,0.6)", fontSize: 14 },
638
+ tagText: { color: "rgba(255,255,255,0.6)", fontSize: 13 },
487
639
  tagTextActive: { color: "white", fontWeight: "600" },
488
- tagSubtitle: { color: "rgba(255,255,255,0.4)", fontSize: 10, marginTop: 2 },
489
- footer: { paddingHorizontal: 16, paddingBottom: 16, paddingTop: 8 },
640
+ tagDescription: { color: "rgba(255,255,255,0.4)", fontSize: 11, marginTop: 2, lineHeight: 14 },
641
+ tagSubtitle: { color: "rgba(255,255,255,0.4)", fontSize: 10 },
642
+ plusBtn: {
643
+ width: 24,
644
+ height: 24,
645
+ borderRadius: 12,
646
+ backgroundColor: "rgba(255,255,255,0.2)",
647
+ alignItems: "center",
648
+ justifyContent: "center"
649
+ },
650
+ footer: {
651
+ paddingHorizontal: 16,
652
+ paddingBottom: 24,
653
+ paddingTop: 8,
654
+ backgroundColor: "transparent"
655
+ },
490
656
  doneButton: {
491
657
  backgroundColor: "white",
492
658
  borderRadius: 14,
@@ -497,14 +663,15 @@ var styles3 = StyleSheet4.create({
497
663
  });
498
664
 
499
665
  // src/AddNoteSheet.tsx
500
- import React6, { useEffect as useEffect4, useMemo as useMemo5, useRef as useRef4, useState as useState2 } from "react";
501
- import { Pressable as Pressable3, StyleSheet as StyleSheet5, Text as Text3, View as View5 } from "react-native";
666
+ import React7, { useEffect as useEffect4, useMemo as useMemo5, useRef as useRef4, useState as useState4 } from "react";
667
+ import { Pressable as Pressable3, StyleSheet as StyleSheet6, Text as Text3, View as View6 } from "react-native";
502
668
  import {
503
669
  BottomSheetBackdrop as BottomSheetBackdrop3,
504
670
  BottomSheetModal as BottomSheetModal3,
505
671
  BottomSheetTextInput,
506
- BottomSheetView as BottomSheetView3
672
+ BottomSheetView as BottomSheetView2
507
673
  } from "@gorhom/bottom-sheet";
674
+ import { ArrowUp as ArrowUp3, X } from "lucide-react-native";
508
675
  function AddNoteSheet({
509
676
  snapPoints = ["50%"],
510
677
  maxLength = 280,
@@ -514,8 +681,8 @@ function AddNoteSheet({
514
681
  const { isAddNoteOpen, addNoteTagId, activeLine, closeAddNote, submitNote } = useRetorBridge();
515
682
  const sheetRef = useRef4(null);
516
683
  const snapPointsArr = useMemo5(() => snapPoints, [snapPoints]);
517
- const [text, setText] = useState2("");
518
- const [isPrivate, setPrivate] = useState2(true);
684
+ const [text, setText] = useState4("");
685
+ const [isPrivate, setPrivate] = useState4(true);
519
686
  useEffect4(() => {
520
687
  if (isAddNoteOpen) {
521
688
  sheetRef.current?.present();
@@ -545,14 +712,14 @@ function AddNoteSheet({
545
712
  close: closeAddNote,
546
713
  maxLength
547
714
  };
548
- return /* @__PURE__ */ React6.createElement(
715
+ return /* @__PURE__ */ React7.createElement(
549
716
  BottomSheetModal3,
550
717
  {
551
718
  ref: sheetRef,
552
719
  snapPoints: snapPointsArr,
553
720
  enablePanDownToClose: true,
554
721
  onDismiss: closeAddNote,
555
- backdropComponent: (props) => /* @__PURE__ */ React6.createElement(
722
+ backdropComponent: (props) => /* @__PURE__ */ React7.createElement(
556
723
  BottomSheetBackdrop3,
557
724
  {
558
725
  ...props,
@@ -562,9 +729,9 @@ function AddNoteSheet({
562
729
  }
563
730
  ),
564
731
  handleIndicatorStyle: styles4.handle,
565
- backgroundStyle: styles4.background
732
+ backgroundComponent: BlurBackground
566
733
  },
567
- /* @__PURE__ */ React6.createElement(BottomSheetView3, { style: styles4.content }, renderForm ? renderForm(formApi) : /* @__PURE__ */ React6.createElement(View5, { style: styles4.form }, /* @__PURE__ */ React6.createElement(View5, { style: styles4.headerRow }, /* @__PURE__ */ React6.createElement(View5, { style: { flex: 1 } }, activeLine && /* @__PURE__ */ React6.createElement(Text3, { style: styles4.title, numberOfLines: 1 }, activeLine.name), tag && /* @__PURE__ */ React6.createElement(Text3, { style: styles4.subtitle, numberOfLines: 1 }, tag.name)), /* @__PURE__ */ React6.createElement(Pressable3, { onPress: closeAddNote, style: styles4.closeBtn }, /* @__PURE__ */ React6.createElement(Text3, { style: styles4.closeBtnText }, "\u2715"))), /* @__PURE__ */ React6.createElement(
734
+ /* @__PURE__ */ React7.createElement(BottomSheetView2, { style: styles4.content }, renderForm ? renderForm(formApi) : /* @__PURE__ */ React7.createElement(View6, { style: styles4.form }, /* @__PURE__ */ React7.createElement(View6, { style: styles4.headerRow }, /* @__PURE__ */ React7.createElement(View6, { style: { flex: 1 } }, activeLine && /* @__PURE__ */ React7.createElement(Text3, { style: styles4.title, numberOfLines: 1 }, activeLine.name), tag && /* @__PURE__ */ React7.createElement(Text3, { style: styles4.subtitle, numberOfLines: 1 }, tag.name)), /* @__PURE__ */ React7.createElement(Pressable3, { onPress: closeAddNote, style: styles4.closeBtn }, /* @__PURE__ */ React7.createElement(X, { size: 14, color: "rgba(255,255,255,0.6)" }))), /* @__PURE__ */ React7.createElement(
568
735
  BottomSheetTextInput,
569
736
  {
570
737
  value: text,
@@ -577,26 +744,25 @@ function AddNoteSheet({
577
744
  style: styles4.input,
578
745
  autoFocus: true
579
746
  }
580
- ), /* @__PURE__ */ React6.createElement(View5, { style: styles4.footer }, /* @__PURE__ */ React6.createElement(Text3, { style: [styles4.counter, text.length > maxLength * 0.9 && { color: "#fbbf24" }] }, text.length, "/", maxLength), /* @__PURE__ */ React6.createElement(View5, { style: { flex: 1 } }), /* @__PURE__ */ React6.createElement(
747
+ ), /* @__PURE__ */ React7.createElement(View6, { style: styles4.footer }, /* @__PURE__ */ React7.createElement(Text3, { style: [styles4.counter, text.length > maxLength * 0.9 && { color: "#fbbf24" }] }, text.length, "/", maxLength), /* @__PURE__ */ React7.createElement(View6, { style: { flex: 1 } }), /* @__PURE__ */ React7.createElement(
581
748
  Pressable3,
582
749
  {
583
750
  onPress: () => setPrivate(!isPrivate),
584
751
  style: [styles4.pill, !isPrivate && styles4.pillActive]
585
752
  },
586
- /* @__PURE__ */ React6.createElement(Text3, { style: [styles4.pillText, !isPrivate && styles4.pillTextActive] }, isPrivate ? "Private" : "Public")
587
- ), /* @__PURE__ */ React6.createElement(
753
+ /* @__PURE__ */ React7.createElement(Text3, { style: [styles4.pillText, !isPrivate && styles4.pillTextActive] }, isPrivate ? "Private" : "Public")
754
+ ), /* @__PURE__ */ React7.createElement(
588
755
  Pressable3,
589
756
  {
590
757
  onPress: handleSubmit,
591
758
  disabled: !text.trim(),
592
759
  style: [styles4.submit, !text.trim() && styles4.submitDisabled]
593
760
  },
594
- /* @__PURE__ */ React6.createElement(Text3, { style: styles4.submitArrow }, "\u2191")
761
+ /* @__PURE__ */ React7.createElement(ArrowUp3, { size: 16, color: "black", strokeWidth: 2.5 })
595
762
  ))))
596
763
  );
597
764
  }
598
- var styles4 = StyleSheet5.create({
599
- background: { backgroundColor: "rgba(20,20,20,0.98)" },
765
+ var styles4 = StyleSheet6.create({
600
766
  handle: { backgroundColor: "rgba(255,255,255,0.3)" },
601
767
  content: { flex: 1, padding: 24 },
602
768
  form: { flex: 1 },
@@ -611,7 +777,6 @@ var styles4 = StyleSheet5.create({
611
777
  alignItems: "center",
612
778
  justifyContent: "center"
613
779
  },
614
- closeBtnText: { color: "rgba(255,255,255,0.6)", fontSize: 14 },
615
780
  input: {
616
781
  flex: 1,
617
782
  color: "white",
@@ -645,16 +810,15 @@ var styles4 = StyleSheet5.create({
645
810
  alignItems: "center",
646
811
  justifyContent: "center"
647
812
  },
648
- submitDisabled: { opacity: 0.3 },
649
- submitArrow: { color: "black", fontSize: 16, fontWeight: "700" }
813
+ submitDisabled: { opacity: 0.3 }
650
814
  });
651
815
 
652
816
  // src/CoverPhoto.tsx
653
- import React7 from "react";
817
+ import React8 from "react";
654
818
  import { WebView as WebView2 } from "react-native-webview";
655
819
  function CoverPhoto({ projectId, baseUrl = "https://retor.app", style }) {
656
820
  const uri = `${baseUrl}/p/${projectId}?cover=true`;
657
- return /* @__PURE__ */ React7.createElement(
821
+ return /* @__PURE__ */ React8.createElement(
658
822
  WebView2,
659
823
  {
660
824
  source: { uri },
@@ -668,6 +832,7 @@ function CoverPhoto({ projectId, baseUrl = "https://retor.app", style }) {
668
832
  }
669
833
  export {
670
834
  AddNoteSheet,
835
+ BlurBackground,
671
836
  CoverPhoto,
672
837
  Hud,
673
838
  LineDetailSheet,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retor/react-native",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "React Native SDK for embedding Retor 3D experiences",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -27,26 +27,37 @@
27
27
  "license": "MIT",
28
28
  "peerDependencies": {
29
29
  "@gorhom/bottom-sheet": ">=5",
30
+ "expo-blur": ">=14",
31
+ "lucide-react-native": ">=1",
30
32
  "react": ">=18",
31
33
  "react-native": ">=0.72",
32
34
  "react-native-gesture-handler": ">=2.12",
33
35
  "react-native-reanimated": ">=3.5",
36
+ "react-native-svg": ">=14",
34
37
  "react-native-webview": ">=13"
35
38
  },
39
+ "peerDependenciesMeta": {
40
+ "expo-blur": {
41
+ "optional": true
42
+ }
43
+ },
36
44
  "devDependencies": {
37
45
  "@gorhom/bottom-sheet": "^5.1.0",
38
46
  "@types/react": "^19.0.0",
47
+ "expo-blur": "^55.0.14",
48
+ "lucide-react-native": "^1.8.0",
39
49
  "react": "19.1.0",
40
50
  "react-native": "0.81.4",
41
51
  "react-native-gesture-handler": "^2.20.0",
42
52
  "react-native-reanimated": "^3.16.0",
53
+ "react-native-svg": "^15.8.0",
43
54
  "react-native-webview": "^13.13.0",
44
55
  "tsup": "^8.0.0",
45
56
  "typescript": "^5.4.0"
46
57
  },
47
58
  "scripts": {
48
- "build": "tsup src/index.tsx --format cjs,esm --dts --clean --external react --external react-native --external react-native-webview --external @gorhom/bottom-sheet --external react-native-gesture-handler --external react-native-reanimated",
49
- "dev": "tsup src/index.tsx --format cjs,esm --dts --watch --external react --external react-native --external react-native-webview --external @gorhom/bottom-sheet --external react-native-gesture-handler --external react-native-reanimated",
59
+ "build": "tsup src/index.tsx --format cjs,esm --dts --clean --external react --external react-native --external react-native-webview --external @gorhom/bottom-sheet --external react-native-gesture-handler --external react-native-reanimated --external react-native-svg --external lucide-react-native --external expo-blur",
60
+ "dev": "tsup src/index.tsx --format cjs,esm --dts --watch --external react --external react-native --external react-native-webview --external @gorhom/bottom-sheet --external react-native-gesture-handler --external react-native-reanimated --external react-native-svg --external lucide-react-native --external expo-blur",
50
61
  "typecheck": "tsc --noEmit"
51
62
  }
52
63
  }