@storybook/react-native-ui-lite 10.2.1 → 10.2.2-alpha.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.js CHANGED
@@ -319,7 +319,7 @@ function StoryIcon({
319
319
  var import_jsx_runtime2 = require("react/jsx-runtime");
320
320
  var BranchNodeText = import_react_native_theming2.styled.Text(({ theme }) => ({
321
321
  textAlign: "left",
322
- fontSize: theme.typography.size.s2,
322
+ fontSize: theme.typography.size.s2 + 1,
323
323
  flexShrink: 1,
324
324
  color: theme.color.defaultText
325
325
  }));
@@ -329,15 +329,14 @@ var BranchNode = import_react_native_theming2.styled.TouchableOpacity(({ depth =
329
329
  cursor: "pointer",
330
330
  display: "flex",
331
331
  flexDirection: "row",
332
- alignItems: "flex-start",
333
- alignSelf: "flex-start",
332
+ alignItems: "center",
334
333
  paddingLeft: (isExpandable ? 8 : 22) + depth * 18,
335
334
  backgroundColor: "transparent",
336
- minHeight: 28,
335
+ minHeight: 34,
337
336
  borderRadius: 4,
338
337
  gap: 6,
339
- paddingTop: 5,
340
- paddingBottom: 4,
338
+ paddingTop: 8,
339
+ paddingBottom: 7,
341
340
  // will this actually do anything?
342
341
  "&:hover, &:focus": {
343
342
  backgroundColor: (0, import_polished.transparentize)(0.93, theme.color.secondary),
@@ -346,26 +345,25 @@ var BranchNode = import_react_native_theming2.styled.TouchableOpacity(({ depth =
346
345
  }));
347
346
  var LeafNode = import_react_native_theming2.styled.TouchableOpacity(
348
347
  ({ depth = 0, selected, theme }) => ({
349
- alignSelf: "flex-start",
350
348
  cursor: "pointer",
351
349
  color: "inherit",
352
350
  display: "flex",
353
351
  gap: 6,
354
352
  flexDirection: "row",
355
- alignItems: "flex-start",
353
+ alignItems: "center",
356
354
  paddingLeft: 22 + depth * 18,
357
- paddingTop: 5,
358
- paddingBottom: 4,
355
+ paddingTop: 8,
356
+ paddingBottom: 7,
359
357
  backgroundColor: selected ? theme.color.secondary : void 0,
360
358
  // not sure 👇
361
359
  width: "100%",
362
360
  borderRadius: 4,
363
361
  paddingRight: 20,
364
- minHeight: 28
362
+ minHeight: 34
365
363
  })
366
364
  );
367
365
  var LeafNodeText = import_react_native_theming2.styled.Text(({ theme, selected }) => ({
368
- fontSize: theme.typography.size.s2,
366
+ fontSize: theme.typography.size.s2 + 1,
369
367
  flexShrink: 1,
370
368
  fontWeight: selected ? "bold" : "normal",
371
369
  color: selected ? theme.color.lightest : theme.color.defaultText
@@ -374,8 +372,7 @@ var Wrapper = import_react_native_theming2.styled.View({
374
372
  display: "flex",
375
373
  flexDirection: "row",
376
374
  alignItems: "center",
377
- gap: 6,
378
- marginTop: 2
375
+ gap: 6
379
376
  });
380
377
  var GroupNode = import_react2.default.memo(function GroupNode2({
381
378
  children,
@@ -392,7 +389,7 @@ var GroupNode = import_react2.default.memo(function GroupNode2({
392
389
  isExpandable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CollapseIcon, { isExpanded }),
393
390
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GroupIcon, { width: 14, height: 14, color })
394
391
  ] }, `group-${props.id}-${color}`),
395
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BranchNodeText, { children })
392
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BranchNodeText, { numberOfLines: 1, children })
396
393
  ] });
397
394
  });
398
395
  var ComponentNode = import_react2.default.memo(
@@ -406,7 +403,7 @@ var ComponentNode = import_react2.default.memo(
406
403
  isExpandable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CollapseIcon, { isExpanded }),
407
404
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ComponentIcon, { width: 12, height: 12, color })
408
405
  ] }, `component-${props.id}-${color}`),
409
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BranchNodeText, { children })
406
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BranchNodeText, { numberOfLines: 1, children })
410
407
  ] });
411
408
  }
412
409
  );
@@ -418,7 +415,7 @@ var StoryNode = import_react2.default.memo(
418
415
  }, [props.selected, theme.color.lightest, theme.color.seafoam]);
419
416
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(LeafNode, { ...props, ref, children: [
420
417
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Wrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StoryIcon, { width: 14, height: 14, color }) }, `story-${props.id}-${color}`),
421
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LeafNodeText, { selected: props.selected, children })
418
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LeafNodeText, { selected: props.selected, numberOfLines: 1, children })
422
419
  ] });
423
420
  })
424
421
  );
@@ -428,44 +425,36 @@ StoryNode.displayName = "StoryNode";
428
425
  var import_react_native_theming3 = require("@storybook/react-native-theming");
429
426
  var import_react_native_ui_common = require("@storybook/react-native-ui-common");
430
427
  var import_react4 = __toESM(require("react"));
428
+ var import_react_native2 = require("react-native");
429
+ var import_list = require("@legendapp/list");
430
+ var import_react_native_safe_area_context = require("react-native-safe-area-context");
431
431
 
432
432
  // src/SelectedNodeProvider.tsx
433
433
  var import_react3 = require("react");
434
434
  var import_jsx_runtime3 = require("react/jsx-runtime");
435
435
  var SelectedNodeContext = (0, import_react3.createContext)({
436
- nodeRef: { current: null },
437
- setNodeRef: () => {
438
- },
439
- scrollToSelectedNode: () => {
436
+ registerCallback: () => {
440
437
  },
441
- scrollRef: null
438
+ scrollCallback: () => {
439
+ }
442
440
  });
443
441
  var SelectedNodeProvider = ({ children }) => {
444
- const nodeRef = (0, import_react3.useRef)(null);
445
- const setNodeRef = (0, import_react3.useCallback)((node) => {
446
- nodeRef.current = node;
447
- }, []);
448
- const scrollRef = (0, import_react3.useRef)(null);
449
- const scrollToSelectedNode = (0, import_react3.useCallback)(() => {
450
- setTimeout(() => {
451
- if (nodeRef?.current && scrollRef?.current) {
452
- try {
453
- nodeRef.current.measureLayout?.(scrollRef.current, (_x, y) => {
454
- scrollRef.current?.scrollTo({ y: y - 100, animated: true });
455
- });
456
- } catch (_error) {
457
- }
458
- }
459
- }, 500);
442
+ const [scrollCallbackValue, setScrollCallback] = (0, import_react3.useState)(null);
443
+ const registerCallback = (0, import_react3.useCallback)((callback) => {
444
+ setScrollCallback(() => callback);
460
445
  }, []);
446
+ const scrollCallback = (0, import_react3.useCallback)(
447
+ (options) => {
448
+ scrollCallbackValue?.(options);
449
+ },
450
+ [scrollCallbackValue]
451
+ );
461
452
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
462
453
  SelectedNodeContext.Provider,
463
454
  {
464
455
  value: {
465
- nodeRef,
466
- setNodeRef,
467
- scrollToSelectedNode,
468
- scrollRef
456
+ scrollCallback,
457
+ registerCallback
469
458
  },
470
459
  children
471
460
  }
@@ -476,13 +465,14 @@ var useSelectedNode = () => (0, import_react3.useContext)(SelectedNodeContext);
476
465
  // src/Tree.tsx
477
466
  var import_jsx_runtime4 = require("react/jsx-runtime");
478
467
  var TextItem = import_react_native_theming3.styled.Text(({ theme }) => ({
468
+ fontSize: theme.typography.size.s2 + 1,
479
469
  color: theme.color.defaultText
480
470
  }));
481
471
  var Node = import_react4.default.memo(function Node2({
482
472
  item,
483
473
  refId,
484
- isOrphan,
485
- isDisplayed,
474
+ isOrphan: _isOrphan,
475
+ isDisplayed: _isDisplayed,
486
476
  isSelected,
487
477
  isFullyExpanded,
488
478
  color: _2,
@@ -491,27 +481,14 @@ var Node = import_react4.default.memo(function Node2({
491
481
  setExpanded,
492
482
  onSelectStoryId
493
483
  }) {
494
- const { setNodeRef } = useSelectedNode();
495
- const setRef = (0, import_react4.useCallback)(
496
- (node) => {
497
- if (isSelected && node) {
498
- setNodeRef(node);
499
- }
500
- },
501
- [isSelected, setNodeRef]
502
- );
503
- if (!isDisplayed) {
504
- return null;
505
- }
506
484
  const id = (0, import_react_native_ui_common.createId)(item.id, refId);
507
485
  if (item.type === "story") {
508
486
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LeafNodeStyleWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
509
487
  StoryNode,
510
488
  {
511
- ref: setRef,
512
489
  selected: isSelected,
513
490
  id,
514
- depth: isOrphan ? item.depth : item.depth - 1,
491
+ depth: item.depth,
515
492
  onPress: () => {
516
493
  onSelectStoryId(item.id);
517
494
  },
@@ -526,6 +503,7 @@ var Node = import_react4.default.memo(function Node2({
526
503
  CollapseButton,
527
504
  {
528
505
  "data-action": "collapse-root",
506
+ hitSlop: { top: 10, bottom: 10, left: 10, right: 10 },
529
507
  onPress: (event) => {
530
508
  event.preventDefault();
531
509
  setExpanded({ ids: [item.id], value: !isExpanded });
@@ -543,6 +521,7 @@ var Node = import_react4.default.memo(function Node2({
543
521
  "aria-label": isFullyExpanded ? "Expand" : "Collapse",
544
522
  "data-action": "expand-all",
545
523
  "data-expanded": isFullyExpanded,
524
+ hitSlop: { top: 10, bottom: 10, left: 10, right: 10 },
546
525
  onPress: (event) => {
547
526
  event.preventDefault();
548
527
  setFullyExpanded();
@@ -560,7 +539,7 @@ var Node = import_react4.default.memo(function Node2({
560
539
  id,
561
540
  "aria-controls": item.children && item.children[0],
562
541
  "aria-expanded": isExpanded,
563
- depth: isOrphan ? item.depth : item.depth - 1,
542
+ depth: item.depth,
564
543
  isComponent: item.type === "component",
565
544
  isExpandable: item.children && item.children.length > 0,
566
545
  isExpanded,
@@ -584,7 +563,7 @@ var LeafNodeStyleWrapper = import_react_native_theming3.styled.View(({ theme })
584
563
  paddingRight: 20,
585
564
  color: theme.color.defaultText,
586
565
  backgroundColor: "transparent",
587
- minHeight: 28,
566
+ minHeight: 34,
588
567
  borderRadius: 4
589
568
  }));
590
569
  var RootNode = import_react_native_theming3.styled.View(() => ({
@@ -594,7 +573,7 @@ var RootNode = import_react_native_theming3.styled.View(() => ({
594
573
  justifyContent: "space-between",
595
574
  marginTop: 16,
596
575
  marginBottom: 4,
597
- minHeight: 28
576
+ minHeight: 34
598
577
  }));
599
578
  var RootNodeText = import_react_native_theming3.styled.Text(({ theme }) => ({
600
579
  fontSize: theme.typography.size.s1 - 1,
@@ -605,18 +584,29 @@ var RootNodeText = import_react_native_theming3.styled.Text(({ theme }) => ({
605
584
  textTransform: "uppercase"
606
585
  }));
607
586
  var CollapseButton = import_react_native_theming3.styled.TouchableOpacity(() => ({
587
+ flex: 1,
608
588
  display: "flex",
609
589
  flexDirection: "row",
610
- paddingVertical: 0,
611
590
  paddingHorizontal: 8,
591
+ paddingTop: 8,
592
+ paddingBottom: 7,
612
593
  borderRadius: 4,
613
594
  gap: 6,
614
595
  alignItems: "center",
615
596
  cursor: "pointer",
616
- height: 28
597
+ minHeight: 34
617
598
  }));
599
+ var flexStyle = { flex: 1 };
600
+ var ITEM_HEIGHT = 34;
601
+ var ROOT_ITEM_HEIGHT = 54;
602
+ var getEstimatedItemSize = (item, _index) => {
603
+ return item?.isRoot ? ROOT_ITEM_HEIGHT : ITEM_HEIGHT;
604
+ };
618
605
  var Tree = import_react4.default.memo(function Tree2({ isMain, refId, data, status, docsMode, selectedStoryId, onSelectStoryId }) {
619
- const containerRef = (0, import_react4.useRef)(null);
606
+ const { registerCallback } = useSelectedNode();
607
+ const [idToScrolllOnMount, setIdToScrolllOnMount] = (0, import_react4.useState)(null);
608
+ const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
609
+ const listRef = (0, import_react4.useRef)(null);
620
610
  const [rootIds, orphanIds, initialExpanded] = (0, import_react4.useMemo)(
621
611
  () => Object.keys(data).reduce(
622
612
  (acc, id) => {
@@ -655,9 +645,7 @@ var Tree = import_react4.default.memo(function Tree2({ isMain, refId, data, stat
655
645
  }, [data]);
656
646
  const collapsedItems = (0, import_react4.useMemo)(
657
647
  () => Object.keys(data).filter((id) => !singleStoryComponentIds.includes(id)),
658
- // eslint-disable-next-line react-compiler/react-compiler
659
- // eslint-disable-next-line react-hooks/exhaustive-deps
660
- [singleStoryComponentIds]
648
+ [singleStoryComponentIds, data]
661
649
  );
662
650
  const collapsedData = (0, import_react4.useMemo)(() => {
663
651
  return singleStoryComponentIds.reduce(
@@ -679,13 +667,7 @@ var Tree = import_react4.default.memo(function Tree2({ isMain, refId, data, stat
679
667
  },
680
668
  { ...data }
681
669
  );
682
- }, [data]);
683
- const ancestry = (0, import_react4.useMemo)(() => {
684
- return collapsedItems.reduce(
685
- (acc, id) => Object.assign(acc, { [id]: (0, import_react_native_ui_common.getAncestorIds)(collapsedData, id) }),
686
- {}
687
- );
688
- }, [collapsedItems, collapsedData]);
670
+ }, [data, singleStoryComponentIds]);
689
671
  const [expanded, setExpanded] = (0, import_react_native_ui_common.useExpanded)({
690
672
  refId,
691
673
  data: collapsedData,
@@ -694,13 +676,58 @@ var Tree = import_react4.default.memo(function Tree2({ isMain, refId, data, stat
694
676
  selectedStoryId,
695
677
  onSelectStoryId
696
678
  });
697
- const treeItems = (0, import_react4.useMemo)(() => {
679
+ const parentMap = (0, import_react4.useMemo)(() => {
680
+ const map = {};
681
+ collapsedItems.forEach((id) => {
682
+ const item = collapsedData[id];
683
+ map[id] = "parent" in item && item.parent || null;
684
+ });
685
+ return map;
686
+ }, [collapsedItems, collapsedData]);
687
+ const isItemVisible = (0, import_react4.useCallback)(
688
+ (itemId) => {
689
+ const item = collapsedData[itemId];
690
+ if (item.type === "root") return true;
691
+ if (!("parent" in item) || !item.parent) return true;
692
+ let currentId = item.parent;
693
+ while (currentId) {
694
+ if (!expanded[currentId]) return false;
695
+ currentId = parentMap[currentId];
696
+ }
697
+ return true;
698
+ },
699
+ [collapsedData, expanded, parentMap]
700
+ );
701
+ const treeData = (0, import_react4.useMemo)(() => {
698
702
  return collapsedItems.map((itemId) => {
699
703
  const item = collapsedData[itemId];
700
- const id = (0, import_react_native_ui_common.createId)(itemId, refId);
704
+ if (!isItemVisible(itemId)) {
705
+ return null;
706
+ }
701
707
  if (item.type === "root") {
702
708
  const descendants = expandableDescendants[item.id];
703
709
  const isFullyExpanded = descendants.every((d) => expanded[d]);
710
+ return {
711
+ itemId,
712
+ item,
713
+ isRoot: true,
714
+ isFullyExpanded,
715
+ descendants
716
+ };
717
+ }
718
+ return {
719
+ itemId,
720
+ item,
721
+ isRoot: false,
722
+ isOrphan: orphanIds.some((oid) => itemId === oid || itemId.startsWith(`${oid}-`))
723
+ };
724
+ }).filter(Boolean);
725
+ }, [collapsedData, collapsedItems, expandableDescendants, expanded, isItemVisible, orphanIds]);
726
+ const renderItem = (0, import_react4.useCallback)(
727
+ ({ item: treeItem }) => {
728
+ const { itemId, item, isRoot } = treeItem;
729
+ const id = (0, import_react_native_ui_common.createId)(itemId, refId);
730
+ if (isRoot) {
704
731
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
705
732
  Root,
706
733
  {
@@ -711,8 +738,8 @@ var Tree = import_react4.default.memo(function Tree2({ isMain, refId, data, stat
711
738
  isSelected: selectedStoryId === itemId,
712
739
  isExpanded: !!expanded[itemId],
713
740
  setExpanded,
714
- isFullyExpanded,
715
- expandableDescendants: descendants,
741
+ isFullyExpanded: treeItem.isFullyExpanded,
742
+ expandableDescendants: treeItem.descendants,
716
743
  onSelectStoryId,
717
744
  docsMode: false,
718
745
  color: "",
@@ -721,7 +748,6 @@ var Tree = import_react4.default.memo(function Tree2({ isMain, refId, data, stat
721
748
  id
722
749
  );
723
750
  }
724
- const isDisplayed = !item.parent || ancestry[itemId].every((a) => expanded[a]);
725
751
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
726
752
  Node,
727
753
  {
@@ -730,8 +756,8 @@ var Tree = import_react4.default.memo(function Tree2({ isMain, refId, data, stat
730
756
  refId,
731
757
  color: null,
732
758
  docsMode,
733
- isOrphan: orphanIds.some((oid) => itemId === oid || itemId.startsWith(`${oid}-`)),
734
- isDisplayed,
759
+ isOrphan: treeItem.isOrphan,
760
+ isDisplayed: true,
735
761
  isSelected: selectedStoryId === itemId,
736
762
  isExpanded: !!expanded[itemId],
737
763
  setExpanded,
@@ -739,27 +765,62 @@ var Tree = import_react4.default.memo(function Tree2({ isMain, refId, data, stat
739
765
  },
740
766
  id
741
767
  );
768
+ },
769
+ [docsMode, expanded, onSelectStoryId, refId, selectedStoryId, setExpanded, status]
770
+ );
771
+ const keyExtractor = (0, import_react4.useCallback)(
772
+ (item) => {
773
+ return (0, import_react_native_ui_common.createId)(item.itemId, refId);
774
+ },
775
+ [refId]
776
+ );
777
+ const contentContainerStyle2 = (0, import_react4.useMemo)(
778
+ () => ({
779
+ marginTop: isMain && orphanIds.length > 0 ? 20 : 0,
780
+ paddingBottom: insets.bottom + 20,
781
+ paddingLeft: 6
782
+ }),
783
+ [isMain, orphanIds.length, insets.bottom]
784
+ );
785
+ (0, import_react4.useLayoutEffect)(() => {
786
+ registerCallback(({ id: nextId, animated }) => {
787
+ const targetId = nextId ?? selectedStoryId;
788
+ const ancestorIds = (0, import_react_native_ui_common.getAncestorIds)(collapsedData, targetId);
789
+ setExpanded({ ids: [...ancestorIds, targetId], value: true });
790
+ setIdToScrolllOnMount(targetId);
742
791
  });
743
- }, [
744
- ancestry,
745
- collapsedData,
746
- collapsedItems,
747
- docsMode,
748
- expandableDescendants,
749
- expanded,
750
- onSelectStoryId,
751
- orphanIds,
752
- refId,
753
- selectedStoryId,
754
- setExpanded,
755
- status
756
- ]);
757
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Container, { ref: containerRef, hasOrphans: isMain && orphanIds.length > 0, children: treeItems });
792
+ }, [collapsedData, registerCallback, selectedStoryId, setExpanded]);
793
+ (0, import_react4.useEffect)(() => {
794
+ if (idToScrolllOnMount) {
795
+ const index = treeData.findIndex((item) => {
796
+ return item.itemId === idToScrolllOnMount;
797
+ });
798
+ if (index >= 0) {
799
+ listRef.current?.scrollToIndex({
800
+ index,
801
+ animated: false,
802
+ viewPosition: 0.5,
803
+ viewOffset: 100
804
+ });
805
+ setIdToScrolllOnMount(null);
806
+ }
807
+ }
808
+ }, [idToScrolllOnMount, treeData]);
809
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native2.View, { style: flexStyle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
810
+ import_list.LegendList,
811
+ {
812
+ ref: listRef,
813
+ style: flexStyle,
814
+ data: treeData,
815
+ renderItem,
816
+ keyExtractor,
817
+ contentContainerStyle: contentContainerStyle2,
818
+ getFixedItemSize: getEstimatedItemSize,
819
+ keyboardShouldPersistTaps: "handled",
820
+ recycleItems: true
821
+ }
822
+ ) });
758
823
  });
759
- var Container = import_react_native_theming3.styled.View((props) => ({
760
- marginTop: props.hasOrphans ? 20 : 0,
761
- marginBottom: 20
762
- }));
763
824
  var Root = import_react4.default.memo(function Root2({
764
825
  setExpanded,
765
826
  isFullyExpanded,
@@ -790,7 +851,7 @@ var import_react_native_theming4 = require("@storybook/react-native-theming");
790
851
  var import_react_native_ui_common2 = require("@storybook/react-native-ui-common");
791
852
  var import_jsx_runtime5 = require("react/jsx-runtime");
792
853
  var Wrapper2 = import_react_native_theming4.styled.View(() => ({
793
- position: "relative"
854
+ flex: 1
794
855
  }));
795
856
  var Ref = import_react5.default.memo(
796
857
  function Ref2(props) {
@@ -844,9 +905,10 @@ var Ref = import_react5.default.memo(
844
905
  );
845
906
 
846
907
  // src/Explorer.tsx
847
- var import_react_native2 = require("react-native");
908
+ var import_react_native3 = require("react-native");
848
909
  var import_jsx_runtime6 = require("react/jsx-runtime");
849
910
  var import_react7 = require("react");
911
+ var containerStyle = { flex: 1 };
850
912
  var Explorer = import_react6.default.memo(function Explorer2({
851
913
  isLoading,
852
914
  isBrowsing,
@@ -855,7 +917,7 @@ var Explorer = import_react6.default.memo(function Explorer2({
855
917
  setSelection
856
918
  }) {
857
919
  const containerRef = (0, import_react6.useRef)(null);
858
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native2.View, { ref: containerRef, id: "storybook-explorer-tree", children: dataset.entries.map(([refId, ref]) => /* @__PURE__ */ (0, import_react7.createElement)(
920
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.View, { ref: containerRef, style: containerStyle, children: dataset.entries.map(([refId, ref]) => /* @__PURE__ */ (0, import_react7.createElement)(
859
921
  Ref,
860
922
  {
861
923
  ...ref,
@@ -872,7 +934,7 @@ var Explorer = import_react6.default.memo(function Explorer2({
872
934
  var import_react_native_theming7 = require("@storybook/react-native-theming");
873
935
  var import_react_native_ui_common5 = require("@storybook/react-native-ui-common");
874
936
  var import_react11 = __toESM(require("react"));
875
- var import_react_native5 = require("react-native");
937
+ var import_react_native6 = require("react-native");
876
938
 
877
939
  // src/constants.ts
878
940
  var BREAKPOINT = 1e3;
@@ -881,28 +943,12 @@ var DEFAULT_REF_ID = "storybook_internal";
881
943
 
882
944
  // src/Search.tsx
883
945
  var import_react_native_theming5 = require("@storybook/react-native-theming");
884
- var import_fuse = __toESM(require("fuse.js"));
885
- var import_react8 = __toESM(require("react"));
886
- var import_react_native3 = require("react-native");
946
+ var import_react8 = require("@nozbe/microfuzz/react");
947
+ var import_react9 = __toESM(require("react"));
948
+ var import_react_native4 = require("react-native");
887
949
  var import_react_native_ui_common3 = require("@storybook/react-native-ui-common");
888
950
  var import_jsx_runtime7 = require("react/jsx-runtime");
889
951
  var DEFAULT_MAX_SEARCH_RESULTS = 50;
890
- var options = {
891
- shouldSort: true,
892
- tokenize: true,
893
- findAllMatches: true,
894
- includeScore: true,
895
- includeMatches: true,
896
- threshold: 0.2,
897
- location: 0,
898
- distance: 100,
899
- maxPatternLength: 32,
900
- minMatchCharLength: 1,
901
- keys: [
902
- { name: "name", weight: 0.7 },
903
- { name: "path", weight: 0.3 }
904
- ]
905
- };
906
952
  var SearchIconWrapper = import_react_native_theming5.styled.View({
907
953
  position: "absolute",
908
954
  top: 0,
@@ -915,11 +961,9 @@ var SearchIconWrapper = import_react_native_theming5.styled.View({
915
961
  height: "100%"
916
962
  });
917
963
  var SearchField = import_react_native_theming5.styled.View({
918
- display: "flex",
919
- flexDirection: "column",
920
- position: "relative"
964
+ flexShrink: 0
921
965
  });
922
- var inputPlatformSpecificStyles = import_react_native3.Platform.select({
966
+ var inputPlatformSpecificStyles = import_react_native4.Platform.select({
923
967
  macos: {
924
968
  paddingVertical: 6
925
969
  },
@@ -931,7 +975,7 @@ var inputPlatformSpecificStyles = import_react_native3.Platform.select({
931
975
  height: 32
932
976
  }
933
977
  });
934
- var Input = (0, import_react_native_theming5.styled)(import_react_native3.TextInput)(({ theme }) => ({
978
+ var Input = (0, import_react_native_theming5.styled)(import_react_native4.TextInput)(({ theme }) => ({
935
979
  ...inputPlatformSpecificStyles,
936
980
  paddingLeft: 28,
937
981
  paddingRight: 28,
@@ -947,36 +991,39 @@ var ClearIcon = import_react_native_theming5.styled.TouchableOpacity(({ theme })
947
991
  position: "absolute",
948
992
  top: 0,
949
993
  bottom: 0,
950
- right: 8,
994
+ right: 0,
951
995
  zIndex: 1,
952
996
  color: theme.textMutedColor,
953
997
  cursor: "pointer",
954
998
  display: "flex",
955
999
  alignItems: "center",
956
1000
  justifyContent: "center",
957
- height: "100%"
1001
+ height: "100%",
1002
+ paddingHorizontal: 12
958
1003
  }));
959
- var Search = import_react8.default.memo(function Search2({ children, dataset, setSelection, getLastViewed, initialQuery = "" }) {
960
- const inputRef = (0, import_react8.useRef)(null);
961
- const [inputValue, setInputValue] = (0, import_react8.useState)(initialQuery);
962
- const [isOpen, setIsOpen] = (0, import_react8.useState)(false);
963
- const [allComponents, showAllComponents] = (0, import_react8.useState)(false);
964
- const { scrollToSelectedNode } = useSelectedNode();
965
- const selectStory = (0, import_react8.useCallback)(
1004
+ var flexStyle2 = { flex: 1 };
1005
+ var searchFieldWrapperStyle = { paddingHorizontal: 10, marginBottom: 4 };
1006
+ var Search = import_react9.default.memo(function Search2({ children, dataset, setSelection, getLastViewed, initialQuery = "" }) {
1007
+ const theme = (0, import_react_native_theming5.useTheme)();
1008
+ const inputRef = (0, import_react9.useRef)(null);
1009
+ const [inputValue, setInputValue] = (0, import_react9.useState)(initialQuery);
1010
+ const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
1011
+ const [allComponents, showAllComponents] = (0, import_react9.useState)(false);
1012
+ const { scrollCallback } = useSelectedNode();
1013
+ const selectStory = (0, import_react9.useCallback)(
966
1014
  (id, refId) => {
967
1015
  setSelection({ storyId: id, refId });
968
1016
  inputRef.current?.blur();
969
1017
  setIsOpen(false);
970
1018
  showAllComponents(false);
971
- scrollToSelectedNode();
1019
+ scrollCallback({ id, animated: false });
972
1020
  },
973
- [scrollToSelectedNode, setSelection]
1021
+ [scrollCallback, setSelection]
974
1022
  );
975
- const getItemProps = (0, import_react8.useCallback)(
1023
+ const getItemProps = (0, import_react9.useCallback)(
976
1024
  ({ item: result }) => {
977
1025
  return {
978
1026
  icon: result?.item?.type === "component" ? "component" : "story",
979
- result,
980
1027
  onPress: () => {
981
1028
  if (result?.item?.type === "story") {
982
1029
  selectStory(result.item.id, result.item.refId);
@@ -987,7 +1034,6 @@ var Search = import_react8.default.memo(function Search2({ children, dataset, se
987
1034
  }
988
1035
  },
989
1036
  score: result.score,
990
- refIndex: result.refIndex,
991
1037
  item: result.item,
992
1038
  matches: result.matches,
993
1039
  isHighlighted: false
@@ -995,65 +1041,71 @@ var Search = import_react8.default.memo(function Search2({ children, dataset, se
995
1041
  },
996
1042
  [selectStory]
997
1043
  );
998
- const makeFuse = (0, import_react8.useCallback)(() => {
999
- const list = dataset.entries.reduce((acc, [refId, { index }]) => {
1044
+ const deferredDataset = (0, import_react9.useDeferredValue)(dataset);
1045
+ const searchList = (0, import_react9.useMemo)(() => {
1046
+ return deferredDataset.entries.reduce((acc, [refId, { index }]) => {
1000
1047
  if (index) {
1001
1048
  acc.push(
1002
1049
  ...Object.values(index).map((item) => {
1003
- return (0, import_react_native_ui_common3.searchItem)(item, dataset.hash[refId]);
1050
+ return (0, import_react_native_ui_common3.searchItem)(item, deferredDataset.hash[refId]);
1004
1051
  })
1005
1052
  );
1006
1053
  }
1007
1054
  return acc;
1008
1055
  }, []);
1009
- return new import_fuse.default(list, options);
1010
- }, [dataset]);
1011
- const getResults = (0, import_react8.useCallback)(
1012
- (input2) => {
1013
- const fuse = makeFuse();
1014
- if (!input2) return [];
1015
- let results2 = [];
1016
- const resultIds = /* @__PURE__ */ new Set();
1017
- const distinctResults = fuse.search(input2).filter(({ item }) => {
1018
- if (!(item.type === "component" || item.type === "docs" || item.type === "story") || resultIds.has(item.parent)) {
1019
- return false;
1020
- }
1021
- resultIds.add(item.id);
1022
- return true;
1023
- });
1024
- if (distinctResults.length) {
1025
- results2 = distinctResults.slice(0, allComponents ? 1e3 : DEFAULT_MAX_SEARCH_RESULTS);
1026
- if (distinctResults.length > DEFAULT_MAX_SEARCH_RESULTS && !allComponents) {
1027
- results2.push({
1028
- showAll: () => showAllComponents(true),
1029
- totalCount: distinctResults.length,
1030
- moreCount: distinctResults.length - DEFAULT_MAX_SEARCH_RESULTS
1031
- });
1032
- }
1056
+ }, [deferredDataset]);
1057
+ const deferredQuery = (0, import_react9.useDeferredValue)(inputValue);
1058
+ const queryText = (0, import_react9.useMemo)(() => deferredQuery ? deferredQuery.trim() : "", [deferredQuery]);
1059
+ const getText = (0, import_react9.useCallback)((item) => [item.name, item.path?.join(" ") ?? ""], []);
1060
+ const mapResultItem = (0, import_react9.useCallback)(
1061
+ ({
1062
+ item,
1063
+ score,
1064
+ matches
1065
+ }) => ({
1066
+ item,
1067
+ score,
1068
+ matches: matches ?? []
1069
+ }),
1070
+ []
1071
+ );
1072
+ const fuzzyResults = (0, import_react8.useFuzzySearchList)({
1073
+ list: searchList,
1074
+ queryText,
1075
+ getText,
1076
+ mapResultItem
1077
+ });
1078
+ const results = (0, import_react9.useMemo)(() => {
1079
+ if (!queryText) return [];
1080
+ const maxResults = allComponents ? 1e3 : DEFAULT_MAX_SEARCH_RESULTS;
1081
+ const processedResults = [];
1082
+ const resultIds = /* @__PURE__ */ new Set();
1083
+ let totalDistinctCount = 0;
1084
+ for (const result of fuzzyResults) {
1085
+ const { item } = result;
1086
+ if (!(item.type === "component" || item.type === "docs" || item.type === "story") || resultIds.has(item.parent)) {
1087
+ continue;
1033
1088
  }
1034
- const lastViewed = !input2 && getLastViewed();
1035
- if (lastViewed && lastViewed.length) {
1036
- results2 = lastViewed.reduce((acc, { storyId, refId }) => {
1037
- const data = dataset.hash[refId];
1038
- if (data && data.index && data.index[storyId]) {
1039
- const story = data.index[storyId];
1040
- const item = story.type === "story" ? data.index[story.parent] : story;
1041
- if (!acc.some((res) => res.item.refId === refId && res.item.id === item.id)) {
1042
- acc.push({ item: (0, import_react_native_ui_common3.searchItem)(item, dataset.hash[refId]), matches: [], score: 0 });
1043
- }
1044
- }
1045
- return acc;
1046
- }, []);
1089
+ resultIds.add(item.id);
1090
+ totalDistinctCount++;
1091
+ if (processedResults.length < maxResults) {
1092
+ processedResults.push(result);
1047
1093
  }
1048
- return results2;
1049
- },
1050
- [allComponents, dataset.hash, getLastViewed, makeFuse]
1051
- );
1052
- const deferredQuery = (0, import_react8.useDeferredValue)(inputValue);
1053
- const input = deferredQuery ? deferredQuery.trim() : "";
1054
- const results = input ? getResults(input) : [];
1055
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native3.View, { style: { flex: 1 }, children: [
1056
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(SearchField, { children: [
1094
+ if (allComponents && processedResults.length >= maxResults) {
1095
+ break;
1096
+ }
1097
+ }
1098
+ if (!allComponents && totalDistinctCount > DEFAULT_MAX_SEARCH_RESULTS) {
1099
+ processedResults.push({
1100
+ showAll: () => showAllComponents(true),
1101
+ totalCount: totalDistinctCount,
1102
+ moreCount: totalDistinctCount - DEFAULT_MAX_SEARCH_RESULTS
1103
+ });
1104
+ }
1105
+ return processedResults;
1106
+ }, [queryText, fuzzyResults, allComponents]);
1107
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native4.View, { style: flexStyle2, children: [
1108
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native4.View, { style: searchFieldWrapperStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(SearchField, { children: [
1057
1109
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SearchIconWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SearchIcon, {}) }),
1058
1110
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1059
1111
  Input,
@@ -1071,35 +1123,34 @@ var Search = import_react8.default.memo(function Search2({ children, dataset, se
1071
1123
  setInputValue("");
1072
1124
  inputRef.current.clear();
1073
1125
  },
1074
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CloseIcon, {})
1126
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CloseIcon, { color: theme.textMutedColor })
1075
1127
  }
1076
1128
  )
1077
- ] }),
1078
- children({
1079
- query: input,
1129
+ ] }) }),
1130
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native4.View, { style: flexStyle2, children: children({
1131
+ query: queryText,
1080
1132
  results,
1081
1133
  isBrowsing: !isOpen || !inputValue.length,
1082
1134
  closeMenu: () => {
1083
1135
  },
1084
1136
  getItemProps,
1085
1137
  highlightedIndex: null
1086
- })
1138
+ }) })
1087
1139
  ] });
1088
1140
  });
1089
1141
 
1090
1142
  // src/SearchResults.tsx
1143
+ var import_list2 = require("@legendapp/list");
1091
1144
  var import_react_native_theming6 = require("@storybook/react-native-theming");
1092
1145
  var import_react_native_ui_common4 = require("@storybook/react-native-ui-common");
1093
1146
  var import_polished2 = require("polished");
1094
- var import_react9 = __toESM(require("react"));
1095
- var import_react_native4 = require("react-native");
1147
+ var import_react10 = __toESM(require("react"));
1148
+ var import_react_native5 = require("react-native");
1149
+ var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
1096
1150
  var import_jsx_runtime8 = require("react/jsx-runtime");
1097
- var import_react10 = require("react");
1098
- var ResultsList = import_react_native_theming6.styled.View({
1099
- margin: 0,
1100
- padding: 0,
1101
- marginTop: 8
1102
- });
1151
+ var isWeb = import_react_native5.Platform.OS === "web";
1152
+ var noResultsFirstLineStyle = { marginBottom: 4 };
1153
+ var flexStyle3 = { flex: 1 };
1103
1154
  var ResultRow = import_react_native_theming6.styled.TouchableOpacity(
1104
1155
  ({ theme, isHighlighted }) => ({
1105
1156
  width: "100%",
@@ -1112,10 +1163,10 @@ var ResultRow = import_react_native_theming6.styled.TouchableOpacity(
1112
1163
  color: theme.color.defaultText,
1113
1164
  fontSize: theme.typography.size.s2,
1114
1165
  backgroundColor: isHighlighted ? theme.background.hoverable : "transparent",
1115
- minHeight: 28,
1166
+ minHeight: 34,
1116
1167
  borderRadius: 4,
1117
1168
  gap: 6,
1118
- paddingTop: 7,
1169
+ paddingTop: 8,
1119
1170
  paddingBottom: 7,
1120
1171
  paddingLeft: 8,
1121
1172
  paddingRight: 8,
@@ -1134,11 +1185,16 @@ var ResultRowContent = import_react_native_theming6.styled.View(() => ({
1134
1185
  }));
1135
1186
  var NoResults = import_react_native_theming6.styled.View(({ theme }) => ({
1136
1187
  marginTop: 20,
1137
- textAlign: "center",
1188
+ alignItems: "center",
1138
1189
  fontSize: theme.typography.size.s2,
1139
1190
  lineHeight: 18,
1140
1191
  color: theme.color.defaultText
1141
1192
  }));
1193
+ var NoResultsText = import_react_native_theming6.styled.Text(({ theme }) => ({
1194
+ fontSize: theme.typography.size.s2,
1195
+ color: theme.textMutedColor,
1196
+ textAlign: "center"
1197
+ }));
1142
1198
  var Mark = import_react_native_theming6.styled.Text(({ theme }) => ({
1143
1199
  backgroundColor: "transparent",
1144
1200
  color: theme.color.secondary
@@ -1152,7 +1208,7 @@ var RecentlyOpenedTitle = import_react_native_theming6.styled.View(({ theme }) =
1152
1208
  justifyContent: "space-between",
1153
1209
  fontSize: theme.typography.size.s1 - 1,
1154
1210
  fontWeight: theme.typography.weight.bold,
1155
- minHeight: 28,
1211
+ minHeight: 34,
1156
1212
  // letterSpacing: '0.16em', <-- todo
1157
1213
  textTransform: "uppercase",
1158
1214
  color: theme.textMutedColor,
@@ -1160,28 +1216,29 @@ var RecentlyOpenedTitle = import_react_native_theming6.styled.View(({ theme }) =
1160
1216
  marginBottom: 4,
1161
1217
  alignItems: "center"
1162
1218
  }));
1163
- var Highlight = import_react9.default.memo(
1164
- function Highlight2({ children, match }) {
1165
- if (!match) return children;
1166
- const { value, indices } = match;
1167
- const { nodes: result } = indices.reduce(
1219
+ var Highlight = import_react10.default.memo(
1220
+ function Highlight2({ children, text, ranges }) {
1221
+ if (!ranges || ranges.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: children ?? text });
1222
+ const { nodes: result } = ranges.reduce(
1168
1223
  ({ cursor, nodes }, [start, end], index, { length }) => {
1169
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: value.slice(cursor, start) }, `text-${index}`));
1170
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Mark, { children: value.slice(start, end + 1) }, `mark-${index}`));
1171
- if (index === length - 1) {
1172
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: value.slice(end + 1) }, `last-${index}`));
1224
+ if (cursor < start) {
1225
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: text.slice(cursor, start) }, `text-${index}`));
1226
+ }
1227
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Mark, { children: text.slice(start, end + 1) }, `mark-${index}`));
1228
+ if (index === length - 1 && end + 1 < text.length) {
1229
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: text.slice(end + 1) }, `last-${index}`));
1173
1230
  }
1174
1231
  return { cursor: end + 1, nodes };
1175
1232
  },
1176
1233
  { cursor: 0, nodes: [] }
1177
1234
  );
1178
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: result }, `end-${match.key}`);
1235
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: result });
1179
1236
  }
1180
1237
  );
1181
1238
  var Title = import_react_native_theming6.styled.Text(({ theme }) => ({
1182
1239
  justifyContent: "flex-start",
1183
1240
  color: theme.textMutedColor,
1184
- fontSize: theme.typography.size.s2
1241
+ fontSize: theme.typography.size.s2 + 1
1185
1242
  }));
1186
1243
  var Path = import_react_native_theming6.styled.View(({ theme }) => ({
1187
1244
  justifyContent: "flex-start",
@@ -1194,46 +1251,38 @@ var PathText = import_react_native_theming6.styled.Text(({ theme }) => ({
1194
1251
  fontSize: theme.typography.size.s1 - 1,
1195
1252
  color: theme.textMutedColor
1196
1253
  }));
1197
- var Result = import_react9.default.memo(function Result2({
1254
+ var Result = import_react10.default.memo(function Result2({
1198
1255
  item,
1199
1256
  matches,
1200
1257
  icon: _icon,
1201
1258
  onPress,
1202
1259
  ...props
1203
1260
  }) {
1204
- const press = (0, import_react9.useCallback)(
1261
+ const theme = (0, import_react_native_theming6.useTheme)();
1262
+ const press = (0, import_react10.useCallback)(
1205
1263
  (event) => {
1206
1264
  event.preventDefault();
1207
1265
  onPress?.(event);
1208
1266
  },
1209
1267
  [onPress]
1210
1268
  );
1211
- const nameMatch = matches.find((match) => match.key === "name");
1212
- const pathMatches = matches.filter((match) => match.key === "path");
1269
+ const nameHighlights = matches?.[0];
1270
+ const pathString = item.path?.join(" ") ?? "";
1213
1271
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ResultRow, { ...props, onPress: press, children: [
1214
1272
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(IconWrapper, { children: [
1215
- item.type === "component" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComponentIcon, { width: 14, height: 14 }),
1216
- item.type === "story" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StoryIcon, { width: 14, height: 14 })
1273
+ item.type === "component" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComponentIcon, { width: 14, height: 14, color: theme.color.secondary }),
1274
+ item.type === "story" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StoryIcon, { width: 14, height: 14, color: theme.color.seafoam })
1217
1275
  ] }),
1218
1276
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ResultRowContent, { testID: "search-result-item--label", children: [
1219
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Title, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Highlight, { match: nameMatch, children: item.name }, "search-result-item--label-highlight") }),
1220
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Path, { children: item.path.map((group, index) => {
1221
- const pathSeparator = index === item.path.length - 1 ? "" : "/";
1222
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native4.View, { style: { flexShrink: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PathText, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1223
- Highlight,
1224
- {
1225
- match: pathMatches.find((match) => match.refIndex === index),
1226
- children: `${group}${pathSeparator}`
1227
- }
1228
- ) }) }, index);
1229
- }) })
1277
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Title, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Highlight, { text: item.name, ranges: nameHighlights, children: item.name }) }),
1278
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Path, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PathText, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Highlight, { text: pathString, ranges: matches?.[1], children: item.path?.join(" / ") }) }) })
1230
1279
  ] })
1231
1280
  ] });
1232
1281
  });
1233
1282
  var Text = import_react_native_theming6.styled.Text(({ theme }) => ({
1234
1283
  color: theme.color.defaultText
1235
1284
  }));
1236
- var SearchResults = import_react9.default.memo(function SearchResults2({
1285
+ var SearchResults = import_react10.default.memo(function SearchResults2({
1237
1286
  query,
1238
1287
  results,
1239
1288
  closeMenu,
@@ -1241,70 +1290,140 @@ var SearchResults = import_react9.default.memo(function SearchResults2({
1241
1290
  highlightedIndex,
1242
1291
  clearLastViewed
1243
1292
  }) {
1244
- const handleClearLastViewed = () => {
1293
+ const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
1294
+ const handleClearLastViewed = (0, import_react10.useCallback)(() => {
1245
1295
  clearLastViewed();
1246
1296
  closeMenu();
1247
- };
1248
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ResultsList, { children: [
1249
- results.length > 0 && !query ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(RecentlyOpenedTitle, { children: [
1250
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: "Recently opened" }),
1251
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_ui_common4.IconButton, { onPress: handleClearLastViewed })
1252
- ] }) : null,
1253
- results.length === 0 && query ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native4.View, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(NoResults, { children: [
1254
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { style: { marginBottom: 8 }, children: "No components found" }),
1255
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: "Find components by name or path." })
1256
- ] }) }) : null,
1257
- results.map((result, index) => {
1297
+ }, [clearLastViewed, closeMenu]);
1298
+ const contentContainerStyle2 = (0, import_react10.useMemo)(
1299
+ () => ({
1300
+ paddingHorizontal: 10,
1301
+ paddingTop: 8,
1302
+ paddingBottom: insets.bottom + 20
1303
+ }),
1304
+ [insets.bottom]
1305
+ );
1306
+ const listData = (0, import_react10.useMemo)(() => {
1307
+ const items = [];
1308
+ if (results.length > 0 && !query) {
1309
+ items.push({ type: "header", clearLastViewed: handleClearLastViewed });
1310
+ }
1311
+ if (results.length === 0 && query) {
1312
+ items.push({ type: "noResults" });
1313
+ }
1314
+ results.forEach((result, index) => {
1258
1315
  if ((0, import_react_native_ui_common4.isExpandType)(result)) {
1259
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MoreWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1260
- import_react_native_ui_common4.Button,
1261
- {
1262
- ...result,
1263
- ...getItemProps({ key: `${index}`, index, item: result }),
1264
- size: "small",
1265
- text: `Show ${result.moreCount} more results`
1266
- }
1267
- ) }, "search-result-expand");
1316
+ items.push({ type: "expand", result, index });
1317
+ } else {
1318
+ items.push({ type: "result", result, index });
1268
1319
  }
1269
- const { item } = result;
1270
- const key = `${item.refId}::${item.id}`;
1271
- return /* @__PURE__ */ (0, import_react10.createElement)(
1272
- Result,
1273
- {
1274
- ...result,
1275
- ...getItemProps({ key, index, item: result }),
1276
- isHighlighted: highlightedIndex === index,
1277
- key: item.id
1320
+ });
1321
+ return items;
1322
+ }, [results, query, handleClearLastViewed]);
1323
+ const keyExtractor = (0, import_react10.useCallback)((item) => {
1324
+ switch (item.type) {
1325
+ case "header":
1326
+ return "header";
1327
+ case "noResults":
1328
+ return "no-results";
1329
+ case "expand":
1330
+ return "expand";
1331
+ case "result": {
1332
+ const { item: resultItem } = item.result;
1333
+ return `${resultItem.refId}::${resultItem.id}`;
1334
+ }
1335
+ }
1336
+ }, []);
1337
+ const renderItem = (0, import_react10.useCallback)(
1338
+ ({ item: listItem }) => {
1339
+ switch (listItem.type) {
1340
+ case "header":
1341
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(RecentlyOpenedTitle, { children: [
1342
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: "Recently opened" }),
1343
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_ui_common4.IconButton, { onPress: listItem.clearLastViewed })
1344
+ ] });
1345
+ case "noResults":
1346
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(NoResults, { children: [
1347
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NoResultsText, { style: noResultsFirstLineStyle, children: "No components found" }),
1348
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NoResultsText, { children: "Find components by name or path." })
1349
+ ] });
1350
+ case "expand": {
1351
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MoreWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1352
+ import_react_native_ui_common4.Button,
1353
+ {
1354
+ ...listItem.result,
1355
+ ...getItemProps({
1356
+ key: `${listItem.index}`,
1357
+ index: listItem.index,
1358
+ item: listItem.result
1359
+ }),
1360
+ size: "small",
1361
+ text: `Show ${listItem.result.moreCount} more results`
1362
+ }
1363
+ ) });
1278
1364
  }
1279
- );
1280
- })
1281
- ] });
1365
+ case "result": {
1366
+ const { item: resultItem } = listItem.result;
1367
+ const key = `${resultItem.refId}::${resultItem.id}`;
1368
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1369
+ Result,
1370
+ {
1371
+ ...listItem.result,
1372
+ ...getItemProps({ key, index: listItem.index, item: listItem.result }),
1373
+ isHighlighted: highlightedIndex === listItem.index
1374
+ }
1375
+ );
1376
+ }
1377
+ }
1378
+ },
1379
+ [getItemProps, highlightedIndex]
1380
+ );
1381
+ if (isWeb) {
1382
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native5.View, { style: flexStyle3, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { flex: 1, overflow: "auto", ...contentContainerStyle2 }, children: listData.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { children: renderItem({ item }) }, keyExtractor(item))) }) });
1383
+ }
1384
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native5.View, { style: flexStyle3, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1385
+ import_list2.LegendList,
1386
+ {
1387
+ style: flexStyle3,
1388
+ data: listData,
1389
+ renderItem,
1390
+ keyExtractor,
1391
+ contentContainerStyle: contentContainerStyle2,
1392
+ estimatedItemSize: 50,
1393
+ keyboardShouldPersistTaps: "handled",
1394
+ recycleItems: true
1395
+ }
1396
+ ) });
1282
1397
  });
1283
1398
 
1284
1399
  // src/Sidebar.tsx
1285
1400
  var import_jsx_runtime9 = require("react/jsx-runtime");
1286
- var Container2 = import_react_native_theming7.styled.View(({ theme }) => ({
1287
- width: "100%",
1288
- height: "100%",
1289
- display: "flex",
1401
+ var Container = import_react_native_theming7.styled.View(({ theme }) => ({
1402
+ flex: 1,
1290
1403
  flexDirection: "column",
1291
1404
  backgroundColor: theme.background.content
1292
1405
  }));
1293
1406
  var Top = import_react_native_theming7.styled.View({
1294
- paddingLeft: 4,
1295
- paddingRight: 4,
1296
- paddingTop: 16,
1297
- flex: 1,
1298
- flexDirection: "row"
1407
+ paddingTop: 8,
1408
+ flex: 1
1299
1409
  });
1410
+ var flexStyle4 = { flex: 1 };
1411
+ var noneStyle = {
1412
+ // display: 'none',
1413
+ height: 1,
1414
+ width: 0,
1415
+ opacity: 0
1416
+ };
1300
1417
  var Swap = import_react11.default.memo(function Swap2({
1301
1418
  children,
1302
1419
  condition
1303
1420
  }) {
1304
1421
  const [a, b] = import_react11.default.Children.toArray(children);
1422
+ const aStyle = (0, import_react11.useMemo)(() => condition ? flexStyle4 : noneStyle, [condition]);
1423
+ const bStyle = (0, import_react11.useMemo)(() => condition ? noneStyle : flexStyle4, [condition]);
1305
1424
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1306
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native5.View, { style: { display: condition ? "flex" : "none" }, children: a }),
1307
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native5.View, { style: { display: condition ? "none" : "flex" }, children: b })
1425
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native6.View, { style: aStyle, children: a }),
1426
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native6.View, { style: bStyle, children: b })
1308
1427
  ] });
1309
1428
  });
1310
1429
  var useCombination = (index, indexError, previewInitialized, status, refs) => {
@@ -1338,7 +1457,7 @@ var Sidebar = import_react11.default.memo(function Sidebar2({
1338
1457
  const selected = (0, import_react11.useMemo)(() => storyId && { storyId, refId }, [storyId, refId]);
1339
1458
  const dataset = useCombination(index, indexError, previewInitialized, status, refs);
1340
1459
  const lastViewedProps = (0, import_react_native_ui_common5.useLastViewed)(selected);
1341
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Container2, { style: { paddingHorizontal: 10 }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Top, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Search, { dataset, setSelection, ...lastViewedProps, children: ({ query, results, isBrowsing, closeMenu, getItemProps, highlightedIndex }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Swap, { condition: isBrowsing, children: [
1460
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Container, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Top, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Search, { dataset, setSelection, ...lastViewedProps, children: ({ query, results, isBrowsing, closeMenu, getItemProps, highlightedIndex }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Swap, { condition: isBrowsing, children: [
1342
1461
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1343
1462
  Explorer,
1344
1463
  {
@@ -1365,12 +1484,12 @@ var Sidebar = import_react11.default.memo(function Sidebar2({
1365
1484
  });
1366
1485
 
1367
1486
  // src/Layout.tsx
1368
- var import_portal = require("@gorhom/portal");
1369
- var import_react_native_theming10 = require("@storybook/react-native-theming");
1487
+ var import_portal2 = require("@gorhom/portal");
1488
+ var import_react_native_theming11 = require("@storybook/react-native-theming");
1370
1489
  var import_react_native_ui_common7 = require("@storybook/react-native-ui-common");
1371
- var import_react16 = require("react");
1372
- var import_react_native10 = require("react-native");
1373
- var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
1490
+ var import_react17 = require("react");
1491
+ var import_react_native12 = require("react-native");
1492
+ var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
1374
1493
  var import_core_events = require("storybook/internal/core-events");
1375
1494
  var import_manager_api2 = require("storybook/manager-api");
1376
1495
 
@@ -1378,28 +1497,28 @@ var import_manager_api2 = require("storybook/manager-api");
1378
1497
  var import_react_native_theming8 = require("@storybook/react-native-theming");
1379
1498
  var import_react_native_ui_common6 = require("@storybook/react-native-ui-common");
1380
1499
  var import_react13 = require("react");
1381
- var import_react_native7 = require("react-native");
1500
+ var import_react_native8 = require("react-native");
1382
1501
  var import_manager_api = require("storybook/manager-api");
1383
1502
  var import_types = require("storybook/internal/types");
1384
1503
 
1385
1504
  // src/useAnimatedValue.ts
1386
1505
  var import_react12 = require("react");
1387
- var import_react_native6 = require("react-native");
1506
+ var import_react_native7 = require("react-native");
1388
1507
  function useAnimatedValue(initialValue, config) {
1389
1508
  const ref = (0, import_react12.useRef)(null);
1390
1509
  if (ref.current == null) {
1391
- ref.current = new import_react_native6.Animated.Value(initialValue, config);
1510
+ ref.current = new import_react_native7.Animated.Value(initialValue, config);
1392
1511
  }
1393
1512
  return ref.current;
1394
1513
  }
1395
1514
 
1396
1515
  // src/MobileAddonsPanel.tsx
1397
- var import_react_native_safe_area_context = require("react-native-safe-area-context");
1516
+ var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
1398
1517
  var import_jsx_runtime10 = require("react/jsx-runtime");
1399
1518
  var MobileAddonsPanel = (0, import_react13.forwardRef)(
1400
1519
  ({ storyId }, ref) => {
1401
1520
  const theme = (0, import_react_native_theming8.useTheme)();
1402
- const { height } = (0, import_react_native7.useWindowDimensions)();
1521
+ const { height } = (0, import_react_native8.useWindowDimensions)();
1403
1522
  const panelHeight = useAnimatedValue(0);
1404
1523
  const positionBottomAnimation = useAnimatedValue(height / 2);
1405
1524
  const [isOpen, setIsOpen] = (0, import_react13.useState)(false);
@@ -1407,34 +1526,34 @@ var MobileAddonsPanel = (0, import_react13.forwardRef)(
1407
1526
  (open) => {
1408
1527
  setIsOpen(open);
1409
1528
  if (open) {
1410
- import_react_native7.Animated.parallel([
1411
- import_react_native7.Animated.timing(positionBottomAnimation, {
1529
+ import_react_native8.Animated.parallel([
1530
+ import_react_native8.Animated.timing(positionBottomAnimation, {
1412
1531
  toValue: 0,
1413
1532
  // Negative to move up
1414
1533
  duration: 350,
1415
1534
  useNativeDriver: false,
1416
- easing: import_react_native7.Easing.inOut(import_react_native7.Easing.cubic)
1535
+ easing: import_react_native8.Easing.inOut(import_react_native8.Easing.cubic)
1417
1536
  }),
1418
- import_react_native7.Animated.timing(panelHeight, {
1537
+ import_react_native8.Animated.timing(panelHeight, {
1419
1538
  toValue: height / 2,
1420
1539
  duration: 350,
1421
1540
  useNativeDriver: false,
1422
- easing: import_react_native7.Easing.inOut(import_react_native7.Easing.cubic)
1541
+ easing: import_react_native8.Easing.inOut(import_react_native8.Easing.cubic)
1423
1542
  })
1424
1543
  ]).start();
1425
1544
  } else {
1426
- import_react_native7.Animated.parallel([
1427
- import_react_native7.Animated.timing(positionBottomAnimation, {
1545
+ import_react_native8.Animated.parallel([
1546
+ import_react_native8.Animated.timing(positionBottomAnimation, {
1428
1547
  toValue: height / 2,
1429
1548
  duration: 350,
1430
1549
  useNativeDriver: false,
1431
- easing: import_react_native7.Easing.inOut(import_react_native7.Easing.cubic)
1550
+ easing: import_react_native8.Easing.inOut(import_react_native8.Easing.cubic)
1432
1551
  }),
1433
- import_react_native7.Animated.timing(panelHeight, {
1552
+ import_react_native8.Animated.timing(panelHeight, {
1434
1553
  toValue: 0,
1435
1554
  duration: 350,
1436
1555
  useNativeDriver: false,
1437
- easing: import_react_native7.Easing.inOut(import_react_native7.Easing.cubic)
1556
+ easing: import_react_native8.Easing.inOut(import_react_native8.Easing.cubic)
1438
1557
  })
1439
1558
  ]).start();
1440
1559
  }
@@ -1444,46 +1563,46 @@ var MobileAddonsPanel = (0, import_react13.forwardRef)(
1444
1563
  (0, import_react13.useEffect)(() => {
1445
1564
  const handleKeyboardShow = ({ endCoordinates, duration, easing }) => {
1446
1565
  if (isOpen) {
1447
- import_react_native7.Animated.parallel([
1448
- import_react_native7.Animated.timing(panelHeight, {
1566
+ import_react_native8.Animated.parallel([
1567
+ import_react_native8.Animated.timing(panelHeight, {
1449
1568
  toValue: (height - endCoordinates.height) / 2,
1450
1569
  duration,
1451
1570
  useNativeDriver: false,
1452
- easing: import_react_native7.Easing[easing] || import_react_native7.Easing.out(import_react_native7.Easing.ease)
1571
+ easing: import_react_native8.Easing[easing] || import_react_native8.Easing.out(import_react_native8.Easing.ease)
1453
1572
  }),
1454
- import_react_native7.Animated.timing(positionBottomAnimation, {
1573
+ import_react_native8.Animated.timing(positionBottomAnimation, {
1455
1574
  toValue: -endCoordinates.height,
1456
1575
  // Negative to move up
1457
1576
  duration,
1458
1577
  useNativeDriver: false,
1459
- easing: import_react_native7.Easing[easing] || import_react_native7.Easing.out(import_react_native7.Easing.ease)
1578
+ easing: import_react_native8.Easing[easing] || import_react_native8.Easing.out(import_react_native8.Easing.ease)
1460
1579
  })
1461
1580
  ]).start();
1462
1581
  }
1463
1582
  };
1464
1583
  const handleKeyboardHide = ({ duration, easing }) => {
1465
1584
  if (isOpen) {
1466
- import_react_native7.Animated.parallel([
1467
- import_react_native7.Animated.timing(positionBottomAnimation, {
1585
+ import_react_native8.Animated.parallel([
1586
+ import_react_native8.Animated.timing(positionBottomAnimation, {
1468
1587
  toValue: 0,
1469
1588
  // Back to original position
1470
1589
  duration,
1471
1590
  useNativeDriver: false,
1472
- easing: import_react_native7.Easing[easing] || import_react_native7.Easing.out(import_react_native7.Easing.ease)
1591
+ easing: import_react_native8.Easing[easing] || import_react_native8.Easing.out(import_react_native8.Easing.ease)
1473
1592
  }),
1474
- import_react_native7.Animated.timing(panelHeight, {
1593
+ import_react_native8.Animated.timing(panelHeight, {
1475
1594
  toValue: height / 2,
1476
1595
  duration,
1477
1596
  useNativeDriver: false,
1478
- easing: import_react_native7.Easing[easing] || import_react_native7.Easing.out(import_react_native7.Easing.ease)
1597
+ easing: import_react_native8.Easing[easing] || import_react_native8.Easing.out(import_react_native8.Easing.ease)
1479
1598
  })
1480
1599
  ]).start();
1481
1600
  }
1482
1601
  };
1483
- const showSubscription = import_react_native7.Keyboard.addListener("keyboardDidShow", handleKeyboardShow);
1484
- const willShowSubscription = import_react_native7.Keyboard.addListener("keyboardWillShow", handleKeyboardShow);
1485
- const hideSubscription = import_react_native7.Keyboard.addListener("keyboardWillHide", handleKeyboardHide);
1486
- const didHideSubscription = import_react_native7.Keyboard.addListener("keyboardDidHide", handleKeyboardHide);
1602
+ const showSubscription = import_react_native8.Keyboard.addListener("keyboardDidShow", handleKeyboardShow);
1603
+ const willShowSubscription = import_react_native8.Keyboard.addListener("keyboardWillShow", handleKeyboardShow);
1604
+ const hideSubscription = import_react_native8.Keyboard.addListener("keyboardWillHide", handleKeyboardHide);
1605
+ const didHideSubscription = import_react_native8.Keyboard.addListener("keyboardDidHide", handleKeyboardHide);
1487
1606
  return () => {
1488
1607
  showSubscription.remove();
1489
1608
  willShowSubscription.remove();
@@ -1501,7 +1620,7 @@ var MobileAddonsPanel = (0, import_react13.forwardRef)(
1501
1620
  }
1502
1621
  }));
1503
1622
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1504
- import_react_native7.Animated.View,
1623
+ import_react_native8.Animated.View,
1505
1624
  {
1506
1625
  style: {
1507
1626
  position: "absolute",
@@ -1512,13 +1631,13 @@ var MobileAddonsPanel = (0, import_react13.forwardRef)(
1512
1631
  transform: [{ translateY: positionBottomAnimation }]
1513
1632
  },
1514
1633
  children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1515
- import_react_native7.View,
1634
+ import_react_native8.View,
1516
1635
  {
1517
1636
  style: {
1518
1637
  justifyContent: "flex-end"
1519
1638
  },
1520
1639
  children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1521
- import_react_native7.View,
1640
+ import_react_native8.View,
1522
1641
  {
1523
1642
  style: {
1524
1643
  height: "100%",
@@ -1526,14 +1645,14 @@ var MobileAddonsPanel = (0, import_react13.forwardRef)(
1526
1645
  paddingTop: 10,
1527
1646
  borderTopColor: theme.appBorderColor,
1528
1647
  borderTopWidth: 1,
1529
- paddingBottom: import_react_native7.Platform.OS === "android" ? 16 : 0
1648
+ paddingBottom: import_react_native8.Platform.OS === "android" ? 16 : 0
1530
1649
  },
1531
1650
  children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1532
1651
  AddonsTabs,
1533
1652
  {
1534
1653
  onClose: () => {
1535
1654
  setMobileMenuOpen(false);
1536
- import_react_native7.Keyboard.dismiss();
1655
+ import_react_native8.Keyboard.dismiss();
1537
1656
  },
1538
1657
  storyId
1539
1658
  }
@@ -1574,14 +1693,14 @@ var centeredStyle = {
1574
1693
  var hitSlop = { top: 10, right: 10, bottom: 10, left: 10 };
1575
1694
  var AddonsTabs = ({ onClose, storyId }) => {
1576
1695
  const panels = import_manager_api.addons.getElements(import_types.Addon_TypesEnum.PANEL);
1577
- const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
1696
+ const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
1578
1697
  const [addonSelected, setAddonSelected] = (0, import_react13.useState)(Object.keys(panels)[0]);
1579
1698
  const panel = (0, import_react13.useMemo)(() => {
1580
1699
  if (!storyId) {
1581
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native7.View, { style: centeredStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native7.Text, { children: "No Story Selected" }) });
1700
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native8.View, { style: centeredStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native8.Text, { children: "No Story Selected" }) });
1582
1701
  }
1583
1702
  if (Object.keys(panels).length === 0) {
1584
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native7.View, { style: centeredStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native7.Text, { children: "No addons loaded." }) });
1703
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native8.View, { style: centeredStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native8.Text, { children: "No addons loaded." }) });
1585
1704
  }
1586
1705
  return panels[addonSelected].render({ active: true });
1587
1706
  }, [addonSelected, panels, storyId]);
@@ -1591,10 +1710,10 @@ var AddonsTabs = ({ onClose, storyId }) => {
1591
1710
  }),
1592
1711
  [insets]
1593
1712
  );
1594
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native7.View, { style: addonsTabsContainerStyle, children: [
1595
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native7.View, { style: addonsTabsStyle, children: [
1713
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native8.View, { style: addonsTabsContainerStyle, children: [
1714
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native8.View, { style: addonsTabsStyle, children: [
1596
1715
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1597
- import_react_native7.ScrollView,
1716
+ import_react_native8.ScrollView,
1598
1717
  {
1599
1718
  horizontal: true,
1600
1719
  showsHorizontalScrollIndicator: false,
@@ -1625,7 +1744,7 @@ var AddonsTabs = ({ onClose, storyId }) => {
1625
1744
  )
1626
1745
  ] }),
1627
1746
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1628
- import_react_native7.ScrollView,
1747
+ import_react_native8.ScrollView,
1629
1748
  {
1630
1749
  style: addonsScrollStyle,
1631
1750
  contentContainerStyle: scrollContentContainerStyle,
@@ -1655,51 +1774,64 @@ var TabText = import_react_native_theming8.styled.Text(({ theme, active }) => ({
1655
1774
  }));
1656
1775
 
1657
1776
  // src/MobileMenuDrawer.tsx
1777
+ var import_portal = require("@gorhom/portal");
1658
1778
  var import_react_native_theming9 = require("@storybook/react-native-theming");
1659
1779
  var import_react14 = require("react");
1660
- var import_react_native8 = require("react-native");
1780
+ var import_react_native9 = require("react-native");
1661
1781
  var import_jsx_runtime11 = require("react/jsx-runtime");
1782
+ var flexStyle5 = { flex: 1 };
1783
+ var portalContainerStyle = {
1784
+ flex: 1,
1785
+ position: "absolute",
1786
+ top: 0,
1787
+ left: 0,
1788
+ right: 0,
1789
+ bottom: 0,
1790
+ zIndex: 1e3
1791
+ };
1662
1792
  var useAnimatedModalHeight = () => {
1663
- const { height } = (0, import_react_native8.useWindowDimensions)();
1793
+ const { height } = (0, import_react_native9.useWindowDimensions)();
1664
1794
  const animatedHeight = useAnimatedValue(0.65 * height);
1665
1795
  (0, import_react14.useEffect)(() => {
1666
1796
  const modalHeight = 0.65 * height;
1667
1797
  const maxModalHeight = 0.85 * height;
1668
- const expand = (duration = 250) => import_react_native8.Animated.timing(animatedHeight, {
1798
+ const expand = (duration = 250) => import_react_native9.Animated.timing(animatedHeight, {
1669
1799
  toValue: maxModalHeight,
1670
1800
  duration,
1801
+ easing: import_react_native9.Easing.out(import_react_native9.Easing.quad),
1671
1802
  useNativeDriver: false
1672
1803
  }).start();
1673
- const collapse = (duration = 250) => import_react_native8.Animated.timing(animatedHeight, {
1804
+ const collapse = (duration = 250) => import_react_native9.Animated.timing(animatedHeight, {
1674
1805
  toValue: modalHeight,
1675
1806
  duration,
1807
+ easing: import_react_native9.Easing.out(import_react_native9.Easing.quad),
1676
1808
  useNativeDriver: false
1677
1809
  }).start();
1678
1810
  const handleKeyboardWillShow = (e) => {
1679
- if (import_react_native8.Platform.OS === "ios") {
1811
+ if (import_react_native9.Platform.OS === "ios") {
1680
1812
  expand(e.duration);
1681
1813
  }
1682
1814
  };
1683
1815
  const handleKeyboardDidShow = (e) => {
1684
- if (import_react_native8.Platform.OS === "android") {
1816
+ if (import_react_native9.Platform.OS === "android") {
1685
1817
  expand();
1686
1818
  }
1687
1819
  };
1688
1820
  const handleKeyboardWillHide = (e) => {
1689
- if (import_react_native8.Platform.OS === "ios") {
1821
+ if (import_react_native9.Platform.OS === "ios") {
1690
1822
  collapse(e.duration);
1691
1823
  }
1692
1824
  };
1693
1825
  const handleKeyboardDidHide = (e) => {
1694
- if (import_react_native8.Platform.OS === "android") {
1826
+ if (import_react_native9.Platform.OS === "android") {
1695
1827
  collapse();
1696
1828
  }
1697
1829
  };
1698
1830
  const subscriptions = [
1699
- import_react_native8.Keyboard.addListener("keyboardWillShow", handleKeyboardWillShow),
1700
- import_react_native8.Keyboard.addListener("keyboardDidShow", handleKeyboardDidShow),
1701
- import_react_native8.Keyboard.addListener("keyboardWillHide", handleKeyboardWillHide),
1702
- import_react_native8.Keyboard.addListener("keyboardDidHide", handleKeyboardDidHide)
1831
+ import_react_native9.Keyboard.addListener("keyboardWillShow", handleKeyboardWillShow),
1832
+ import_react_native9.Keyboard.addListener("keyboardDidShow", handleKeyboardDidShow),
1833
+ import_react_native9.Keyboard.addListener("keyboardWillHide", handleKeyboardWillHide),
1834
+ import_react_native9.Keyboard.addListener("keyboardDidHide", handleKeyboardDidHide)
1703
1835
  ];
1704
1836
  return () => {
1705
1837
  subscriptions.forEach((subscription) => subscription.remove());
@@ -1709,13 +1841,43 @@ var useAnimatedModalHeight = () => {
1709
1841
  };
1710
1842
  var MobileMenuDrawer = (0, import_react14.memo)(
1711
1843
  (0, import_react14.forwardRef)(({ children }, ref) => {
1712
- const [mobileMenuOpen, setMobileMenuOpen] = (0, import_react14.useState)(false);
1713
- const { scrollToSelectedNode, scrollRef } = useSelectedNode();
1844
+ const [isVisible, setIsVisible] = (0, import_react14.useState)(false);
1845
+ const { scrollCallback } = useSelectedNode();
1714
1846
  const theme = (0, import_react_native_theming9.useTheme)();
1847
+ const { height } = (0, import_react_native9.useWindowDimensions)();
1715
1848
  const animatedHeight = useAnimatedModalHeight();
1849
+ const slideAnim = useAnimatedValue(height);
1716
1850
  const dragY = useAnimatedValue(0);
1717
- const panResponder = (0, import_react14.useRef)(
1718
- import_react_native8.PanResponder.create({
1851
+ const openDrawer = (0, import_react14.useCallback)(() => {
1852
+ dragY.setValue(0);
1853
+ slideAnim.setValue(height);
1854
+ setIsVisible(true);
1855
+ import_react_native9.Animated.timing(slideAnim, {
1856
+ toValue: 0,
1857
+ duration: 300,
1858
+ easing: import_react_native9.Easing.out(import_react_native9.Easing.quad),
1859
+ useNativeDriver: true
1860
+ }).start(({ finished }) => {
1861
+ if (finished) {
1862
+ scrollCallback({ animated: false, id: void 0 });
1863
+ }
1864
+ });
1865
+ }, [dragY, height, scrollCallback, slideAnim]);
1866
+ const closeDrawer = (0, import_react14.useCallback)(() => {
1867
+ import_react_native9.Keyboard.dismiss();
1868
+ import_react_native9.Animated.timing(slideAnim, {
1869
+ toValue: height,
1870
+ duration: 300,
1871
+ easing: import_react_native9.Easing.in(import_react_native9.Easing.quad),
1872
+ useNativeDriver: true
1873
+ }).start(({ finished }) => {
1874
+ if (finished) {
1875
+ setIsVisible(false);
1876
+ }
1877
+ });
1878
+ }, [height, slideAnim]);
1879
+ const panResponder = (0, import_react14.useMemo)(
1880
+ () => import_react_native9.PanResponder.create({
1719
1881
  onStartShouldSetPanResponder: () => true,
1720
1882
  onMoveShouldSetPanResponder: (_, gestureState) => {
1721
1883
  return gestureState.dy > 0;
@@ -1727,26 +1889,25 @@ var MobileMenuDrawer = (0, import_react14.memo)(
1727
1889
  },
1728
1890
  onPanResponderRelease: (_, gestureState) => {
1729
1891
  if (gestureState.dy > 50) {
1730
- import_react_native8.Keyboard.dismiss();
1731
- setMobileMenuOpen(false);
1892
+ closeDrawer();
1893
+ } else {
1894
+ import_react_native9.Animated.timing(dragY, {
1895
+ toValue: 0,
1896
+ duration: 300,
1897
+ easing: import_react_native9.Easing.out(import_react_native9.Easing.quad),
1898
+ useNativeDriver: true
1899
+ }).start();
1732
1900
  }
1733
- import_react_native8.Animated.timing(dragY, {
1734
- toValue: 0,
1735
- duration: 300,
1736
- useNativeDriver: true
1737
- }).start();
1738
1901
  }
1739
- })
1740
- ).current;
1902
+ }),
1903
+ [closeDrawer, dragY]
1904
+ );
1741
1905
  (0, import_react14.useImperativeHandle)(ref, () => ({
1742
1906
  setMobileMenuOpen: (open) => {
1743
1907
  if (open) {
1744
- dragY.setValue(0);
1745
- scrollToSelectedNode();
1746
- setMobileMenuOpen(true);
1908
+ openDrawer();
1747
1909
  } else {
1748
- import_react_native8.Keyboard.dismiss();
1749
- setMobileMenuOpen(false);
1910
+ closeDrawer();
1750
1911
  }
1751
1912
  }
1752
1913
  }));
@@ -1756,86 +1917,148 @@ var MobileMenuDrawer = (0, import_react14.memo)(
1756
1917
  height: 5,
1757
1918
  backgroundColor: theme.color.mediumdark,
1758
1919
  borderRadius: 2.5,
1759
- alignSelf: "center",
1760
- // TypeScript needs this to recognize 'center' as a valid FlexAlignType
1761
- marginVertical: 8
1920
+ alignSelf: "center"
1762
1921
  }),
1763
1922
  [theme.color.mediumdark]
1764
1923
  );
1765
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1766
- import_react_native8.Modal,
1924
+ const drawerContainerStyle = (0, import_react14.useMemo)(
1925
+ () => ({
1926
+ flex: 1,
1927
+ borderTopColor: theme.appBorderColor,
1928
+ borderTopWidth: 1,
1929
+ borderStyle: "solid",
1930
+ backgroundColor: theme.background.content,
1931
+ elevation: 8,
1932
+ boxShadow: `0 16px 32px 0 ${theme.color.border}`
1933
+ }),
1934
+ [theme.appBorderColor, theme.background.content, theme.color.border]
1935
+ );
1936
+ const dragHandleWrapperStyle = (0, import_react14.useMemo)(
1937
+ () => ({
1938
+ alignItems: "center",
1939
+ justifyContent: "center",
1940
+ paddingBottom: 16,
1941
+ paddingTop: 10,
1942
+ backgroundColor: theme.background.content
1943
+ }),
1944
+ [theme.background.content]
1945
+ );
1946
+ const childrenWrapperStyle = (0, import_react14.useMemo)(
1947
+ () => ({
1948
+ flex: 1,
1949
+ backgroundColor: theme.background.content
1950
+ }),
1951
+ [theme.background.content]
1952
+ );
1953
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_portal.Portal, { hostName: "storybook-lite-ui-root", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1954
+ import_react_native9.Animated.View,
1767
1955
  {
1768
- visible: mobileMenuOpen,
1769
- animationType: "slide",
1770
- transparent: true,
1771
- statusBarTranslucent: true,
1772
- onRequestClose: () => setMobileMenuOpen(false),
1773
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native8.Animated.View, { style: { flex: 1 }, children: [
1774
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native8.View, { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native8.Pressable, { style: { flex: 1 }, onPress: () => setMobileMenuOpen(false) }) }),
1775
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native8.Animated.View, { style: { height: animatedHeight }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1776
- import_react_native8.Animated.View,
1956
+ style: [portalContainerStyle, { transform: [{ translateY: slideAnim }] }],
1957
+ pointerEvents: isVisible ? "auto" : "none",
1958
+ children: [
1959
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native9.View, { style: flexStyle5, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native9.Pressable, { style: flexStyle5, onPress: closeDrawer }) }),
1960
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1961
+ import_react_native9.Animated.View,
1777
1962
  {
1778
- style: [
1779
- {
1780
- flex: 1,
1781
- borderTopColor: theme.appBorderColor,
1782
- borderTopWidth: 1,
1783
- borderStyle: "solid",
1784
- backgroundColor: theme.background.content,
1785
- elevation: 8
1786
- },
1787
- { transform: [{ translateY: dragY }] }
1788
- ],
1789
- children: [
1790
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1791
- import_react_native8.View,
1792
- {
1793
- ...panResponder.panHandlers,
1794
- style: {
1795
- alignItems: "center",
1796
- justifyContent: "center",
1797
- backgroundColor: theme.background.content
1798
- },
1799
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native8.View, { style: handleStyle })
1800
- }
1801
- ),
1802
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1803
- import_react_native8.ScrollView,
1804
- {
1805
- ref: scrollRef,
1806
- keyboardShouldPersistTaps: "handled",
1807
- style: {
1808
- flex: 1,
1809
- paddingBottom: 150,
1810
- alignSelf: "flex-end",
1811
- width: "100%",
1812
- backgroundColor: theme.background.content
1813
- },
1814
- children
1815
- }
1816
- )
1817
- ]
1963
+ style: {
1964
+ height: animatedHeight
1965
+ },
1966
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native9.Animated.View, { style: [drawerContainerStyle, { transform: [{ translateY: dragY }] }], children: [
1967
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native9.View, { ...panResponder.panHandlers, style: dragHandleWrapperStyle, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native9.View, { style: handleStyle }) }),
1968
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native9.View, { style: childrenWrapperStyle, children })
1969
+ ] })
1818
1970
  }
1819
- ) })
1820
- ] })
1971
+ )
1972
+ ]
1821
1973
  }
1822
- );
1974
+ ) });
1823
1975
  })
1824
1976
  );
1825
1977
 
1826
- // src/StorybookLogo.tsx
1978
+ // src/ResizeHandle.tsx
1979
+ var import_react_native_theming10 = require("@storybook/react-native-theming");
1827
1980
  var import_react15 = require("react");
1828
- var import_react_native9 = require("react-native");
1981
+ var import_react_native10 = require("react-native");
1829
1982
  var import_jsx_runtime12 = require("react/jsx-runtime");
1983
+ var ResizeHandle = (0, import_react15.memo)(function ResizeHandle2({
1984
+ direction,
1985
+ onResize,
1986
+ onResizeStart,
1987
+ onResizeEnd
1988
+ }) {
1989
+ const theme = (0, import_react_native_theming10.useTheme)();
1990
+ const [active, setActive] = (0, import_react15.useState)(false);
1991
+ const startValueRef = (0, import_react15.useRef)(0);
1992
+ const isHorizontal = direction === "horizontal";
1993
+ const panResponder = (0, import_react15.useMemo)(
1994
+ () => import_react_native10.PanResponder.create({
1995
+ onStartShouldSetPanResponder: () => true,
1996
+ onMoveShouldSetPanResponder: () => true,
1997
+ onPanResponderTerminationRequest: () => false,
1998
+ onShouldBlockNativeResponder: () => true,
1999
+ onPanResponderGrant: () => {
2000
+ startValueRef.current = 0;
2001
+ setActive(true);
2002
+ onResizeStart?.();
2003
+ },
2004
+ onPanResponderMove: (_, gestureState) => {
2005
+ const delta = isHorizontal ? gestureState.dx : gestureState.dy;
2006
+ const diff = delta - startValueRef.current;
2007
+ startValueRef.current = delta;
2008
+ onResize(diff);
2009
+ },
2010
+ onPanResponderRelease: () => {
2011
+ setActive(false);
2012
+ onResizeEnd?.();
2013
+ },
2014
+ onPanResponderTerminate: () => {
2015
+ setActive(false);
2016
+ onResizeEnd?.();
2017
+ }
2018
+ }),
2019
+ [isHorizontal, onResize, onResizeStart, onResizeEnd]
2020
+ );
2021
+ const style = (0, import_react15.useMemo)(() => {
2022
+ const borderColor = active ? theme.barSelectedColor : theme.appBorderColor;
2023
+ if (isHorizontal) {
2024
+ return {
2025
+ width: 5,
2026
+ alignSelf: "stretch",
2027
+ justifyContent: "center",
2028
+ borderLeftWidth: 1,
2029
+ borderLeftColor: borderColor,
2030
+ backgroundColor: active ? theme.barSelectedColor : "transparent",
2031
+ // @ts-expect-error - cursor is supported on web and desktop platforms
2032
+ cursor: "col-resize"
2033
+ };
2034
+ }
2035
+ return {
2036
+ height: 5,
2037
+ alignSelf: "stretch",
2038
+ justifyContent: "center",
2039
+ borderTopWidth: 1,
2040
+ borderTopColor: borderColor,
2041
+ backgroundColor: active ? theme.barSelectedColor : "transparent",
2042
+ // @ts-expect-error - cursor is supported on web and desktop platforms
2043
+ cursor: "row-resize"
2044
+ };
2045
+ }, [active, isHorizontal, theme.appBorderColor, theme.barSelectedColor]);
2046
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native10.View, { ...panResponder.panHandlers, style });
2047
+ });
2048
+
2049
+ // src/StorybookLogo.tsx
2050
+ var import_react16 = require("react");
2051
+ var import_react_native11 = require("react-native");
2052
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1830
2053
  var WIDTH = 125;
1831
2054
  var HEIGHT = 25;
1832
- var NoBrandLogo = ({ theme }) => theme.base === "light" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Logo, { height: HEIGHT, width: WIDTH }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DarkLogo, { height: HEIGHT, width: WIDTH });
2055
+ var NoBrandLogo = ({ theme }) => theme.base === "light" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Logo, { height: HEIGHT, width: WIDTH }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DarkLogo, { height: HEIGHT, width: WIDTH });
1833
2056
  function isElement(value) {
1834
- return (0, import_react15.isValidElement)(value);
2057
+ return (0, import_react16.isValidElement)(value);
1835
2058
  }
1836
2059
  var BrandLogo = ({ theme }) => {
1837
2060
  const imageHasNoWidthOrHeight = typeof theme.brand.image === "object" && typeof theme.brand.image === "object" && "uri" in theme.brand.image && (!("height" in theme.brand.image) || !("width" in theme.brand.image));
1838
- (0, import_react15.useEffect)(() => {
2061
+ (0, import_react16.useEffect)(() => {
1839
2062
  if (imageHasNoWidthOrHeight) {
1840
2063
  console.warn(
1841
2064
  "STORYBOOK: When using a remote image as the brand logo, you must also set the width and height.\nFor example: brand: { image: { uri: 'https://sb.com/img.png', height: 25, width: 25}}"
@@ -1848,8 +2071,8 @@ var BrandLogo = ({ theme }) => {
1848
2071
  if (isElement(theme.brand.image)) {
1849
2072
  return theme.brand.image;
1850
2073
  }
1851
- const image = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1852
- import_react_native9.Image,
2074
+ const image = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2075
+ import_react_native11.Image,
1853
2076
  {
1854
2077
  source: theme.brand.image,
1855
2078
  resizeMode: theme.brand.resizeMode ?? "contain",
@@ -1857,11 +2080,11 @@ var BrandLogo = ({ theme }) => {
1857
2080
  }
1858
2081
  );
1859
2082
  if (theme.brand.url) {
1860
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1861
- import_react_native9.TouchableOpacity,
2083
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2084
+ import_react_native11.TouchableOpacity,
1862
2085
  {
1863
2086
  onPress: () => {
1864
- if (theme.brand.url) import_react_native9.Linking.openURL(theme.brand.url);
2087
+ if (theme.brand.url) import_react_native11.Linking.openURL(theme.brand.url);
1865
2088
  },
1866
2089
  children: image
1867
2090
  }
@@ -1871,7 +2094,7 @@ var BrandLogo = ({ theme }) => {
1871
2094
  }
1872
2095
  };
1873
2096
  var BrandTitle = ({ theme }) => {
1874
- const brandTitleStyle = (0, import_react15.useMemo)(() => {
2097
+ const brandTitleStyle = (0, import_react16.useMemo)(() => {
1875
2098
  return {
1876
2099
  width: WIDTH,
1877
2100
  height: HEIGHT,
@@ -1879,13 +2102,13 @@ var BrandTitle = ({ theme }) => {
1879
2102
  fontSize: theme.typography.size.m1
1880
2103
  };
1881
2104
  }, [theme]);
1882
- const title = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native9.Text, { style: brandTitleStyle, numberOfLines: 1, ellipsizeMode: "tail", children: theme.brand.title });
2105
+ const title = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native11.Text, { style: brandTitleStyle, numberOfLines: 1, ellipsizeMode: "tail", children: theme.brand.title });
1883
2106
  if (theme.brand.url) {
1884
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1885
- import_react_native9.TouchableOpacity,
2107
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2108
+ import_react_native11.TouchableOpacity,
1886
2109
  {
1887
2110
  onPress: () => {
1888
- if (theme.brand.url) import_react_native9.Linking.openURL(theme.brand.url);
2111
+ if (theme.brand.url) import_react_native11.Linking.openURL(theme.brand.url);
1889
2112
  },
1890
2113
  children: title
1891
2114
  }
@@ -1895,19 +2118,19 @@ var BrandTitle = ({ theme }) => {
1895
2118
  }
1896
2119
  };
1897
2120
  var StorybookLogo = ({ theme }) => {
1898
- const image = (0, import_react15.useMemo)(() => theme.brand?.image, [theme.brand?.image]);
1899
- const title = (0, import_react15.useMemo)(() => theme.brand?.title, [theme.brand?.title]);
2121
+ const image = (0, import_react16.useMemo)(() => theme.brand?.image, [theme.brand?.image]);
2122
+ const title = (0, import_react16.useMemo)(() => theme.brand?.title, [theme.brand?.title]);
1900
2123
  if (image) {
1901
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(BrandLogo, { theme });
2124
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(BrandLogo, { theme });
1902
2125
  } else if (title) {
1903
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(BrandTitle, { theme });
2126
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(BrandTitle, { theme });
1904
2127
  } else {
1905
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NoBrandLogo, { theme });
2128
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NoBrandLogo, { theme });
1906
2129
  }
1907
2130
  };
1908
2131
 
1909
2132
  // src/Layout.tsx
1910
- var import_jsx_runtime13 = require("react/jsx-runtime");
2133
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1911
2134
  var desktopLogoContainer = {
1912
2135
  flexDirection: "row",
1913
2136
  alignItems: "center",
@@ -1921,25 +2144,26 @@ var contentContainerStyle = { flex: 1, overflow: "hidden" };
1921
2144
  var mobileContentStyle = { flex: 1, overflow: "hidden" };
1922
2145
  var placeholderObject = {};
1923
2146
  var iconFloatRightStyle = { marginLeft: "auto" };
1924
- var navButtonStyle = { flexShrink: 1 };
1925
- var navButtonHitSlop = { bottom: 10, left: 10, right: 10, top: 10 };
2147
+ var navButtonStyle = { flex: 1 };
2148
+ var navButtonHitSlop = { bottom: 10, left: 10, top: 10 };
2149
+ var addonButtonHitSlop = { bottom: 10, left: 10, right: 10, top: 10 };
1926
2150
  var mobileMenuDrawerContentStyle = {
1927
2151
  paddingLeft: 16,
1928
- paddingTop: 4,
1929
2152
  paddingBottom: 4
1930
2153
  };
1931
- var LiteUI = ({ storage, theme, storyHash, story, children }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_safe_area_context2.SafeAreaProvider, { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_theming10.ThemeProvider, { theme, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_ui_common7.StorageProvider, { storage, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_ui_common7.LayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_portal.PortalProvider, { shouldAddRootHost: false, children: [
1932
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Layout, { storyHash, story, children }),
1933
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_portal.PortalHost, { name: "storybook-lite-ui-root" })
1934
- ] }) }) }) }) });
2154
+ var flexStyle6 = { flex: 1 };
2155
+ var LiteUI = ({ storage, theme, storyHash, story, children }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_safe_area_context4.SafeAreaProvider, { style: flexStyle6, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SelectedNodeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_theming11.ThemeProvider, { theme, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_ui_common7.StorageProvider, { storage, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_ui_common7.LayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_portal2.PortalProvider, { shouldAddRootHost: false, children: [
2156
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Layout, { storyHash, story, children }),
2157
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_portal2.PortalHost, { name: "storybook-lite-ui-root" })
2158
+ ] }) }) }) }) }) });
1935
2159
  var Layout = ({
1936
2160
  storyHash,
1937
2161
  story,
1938
2162
  children
1939
2163
  }) => {
1940
- const theme = (0, import_react_native_theming10.useTheme)();
2164
+ const theme = (0, import_react_native_theming11.useTheme)();
1941
2165
  const { isDesktop } = (0, import_react_native_ui_common7.useLayout)();
1942
- const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
2166
+ const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
1943
2167
  const [desktopSidebarOpen, setDesktopSidebarOpen] = (0, import_react_native_ui_common7.useStoreBooleanState)(
1944
2168
  "desktopSidebarState",
1945
2169
  true
@@ -1948,30 +2172,51 @@ var Layout = ({
1948
2172
  "desktopPanelState",
1949
2173
  true
1950
2174
  );
1951
- const [uiHidden, setUiHidden] = (0, import_react16.useState)(false);
1952
- (0, import_react16.useLayoutEffect)(() => {
2175
+ const [sidebarWidth, setSidebarWidth] = (0, import_react_native_ui_common7.useStoreNumberState)("desktopSidebarWidth", 240);
2176
+ const [addonsPanelHeight, setAddonsPanelHeight] = (0, import_react_native_ui_common7.useStoreNumberState)(
2177
+ "desktopAddonsPanelHeight",
2178
+ 300
2179
+ );
2180
+ const { width: windowWidth, height: windowHeight } = (0, import_react_native12.useWindowDimensions)();
2181
+ const handleSidebarResize = (0, import_react17.useCallback)(
2182
+ (delta) => {
2183
+ setSidebarWidth((prev) => Math.min(Math.max(prev + delta, 180), windowWidth * 0.5));
2184
+ },
2185
+ [setSidebarWidth, windowWidth]
2186
+ );
2187
+ const handleAddonsPanelResize = (0, import_react17.useCallback)(
2188
+ (delta) => {
2189
+ setAddonsPanelHeight((prev) => Math.min(Math.max(prev - delta, 100), windowHeight * 0.6));
2190
+ },
2191
+ [setAddonsPanelHeight, windowHeight]
2192
+ );
2193
+ const [isResizing, setIsResizing] = (0, import_react17.useState)(false);
2194
+ const onResizeStart = (0, import_react17.useCallback)(() => setIsResizing(true), []);
2195
+ const onResizeEnd = (0, import_react17.useCallback)(() => setIsResizing(false), []);
2196
+ const [uiHidden, setUiHidden] = (0, import_react17.useState)(false);
2197
+ (0, import_react17.useLayoutEffect)(() => {
1953
2198
  setUiHidden(story?.parameters?.storybookUIVisibility === "hidden");
1954
2199
  }, [story?.parameters?.storybookUIVisibility]);
1955
2200
  const desktopSidebarStyle = (0, import_react_native_ui_common7.useStyle)(
1956
2201
  () => ({
1957
- width: desktopSidebarOpen ? 240 : void 0,
2202
+ width: desktopSidebarOpen ? sidebarWidth : void 0,
1958
2203
  padding: desktopSidebarOpen ? 0 : 10,
1959
2204
  borderColor: theme.appBorderColor,
1960
- borderRightWidth: 1
2205
+ borderRightWidth: desktopSidebarOpen ? 0 : 1
1961
2206
  }),
1962
- [desktopSidebarOpen, theme.appBorderColor]
2207
+ [desktopSidebarOpen, sidebarWidth, theme.appBorderColor]
1963
2208
  );
1964
2209
  const desktopAddonsPanelStyle = (0, import_react_native_ui_common7.useStyle)(
1965
2210
  () => ({
1966
- height: desktopAddonsPanelOpen ? 300 : void 0,
1967
- borderTopWidth: 1,
2211
+ height: desktopAddonsPanelOpen ? addonsPanelHeight : void 0,
2212
+ borderTopWidth: desktopAddonsPanelOpen ? 0 : 1,
1968
2213
  borderColor: theme.appBorderColor,
1969
2214
  paddingTop: desktopAddonsPanelOpen ? 4 : 0,
1970
2215
  padding: desktopAddonsPanelOpen ? 0 : 10
1971
2216
  }),
1972
- [desktopAddonsPanelOpen, theme.appBorderColor]
2217
+ [desktopAddonsPanelOpen, addonsPanelHeight, theme.appBorderColor]
1973
2218
  );
1974
- const containerStyle = (0, import_react_native_ui_common7.useStyle)(() => {
2219
+ const containerStyle2 = (0, import_react_native_ui_common7.useStyle)(() => {
1975
2220
  if (isDesktop) {
1976
2221
  return {
1977
2222
  flex: 1,
@@ -2011,53 +2256,76 @@ var Layout = ({
2011
2256
  }),
2012
2257
  [theme.barTextColor]
2013
2258
  );
2014
- const mobileMenuDrawerRef = (0, import_react16.useRef)(null);
2015
- const addonPanelRef = (0, import_react16.useRef)(null);
2016
- const setSelection = (0, import_react16.useCallback)(({ storyId: newStoryId }) => {
2259
+ const mobileMenuDrawerRef = (0, import_react17.useRef)(null);
2260
+ const addonPanelRef = (0, import_react17.useRef)(null);
2261
+ const setSelection = (0, import_react17.useCallback)(({ storyId: newStoryId }) => {
2017
2262
  const channel = import_manager_api2.addons.getChannel();
2018
2263
  channel.emit(import_core_events.SET_CURRENT_STORY, { storyId: newStoryId });
2019
2264
  }, []);
2020
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native10.View, { style: containerStyle, children: [
2021
- isDesktop ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native10.View, { style: desktopSidebarStyle, children: desktopSidebarOpen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native10.ScrollView, { keyboardShouldPersistTaps: "handled", children: [
2022
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native10.View, { style: desktopLogoContainer, children: [
2023
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StorybookLogo, { theme }),
2024
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_ui_common7.IconButton, { onPress: () => setDesktopSidebarOpen(false), Icon: MenuIcon })
2025
- ] }),
2026
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2027
- Sidebar,
2265
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native12.View, { style: containerStyle2, children: [
2266
+ isDesktop ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
2267
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native12.View, { style: desktopSidebarStyle, pointerEvents: isResizing ? "none" : "auto", children: desktopSidebarOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
2268
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native12.View, { style: desktopLogoContainer, children: [
2269
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StorybookLogo, { theme }),
2270
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_ui_common7.IconButton, { onPress: () => setDesktopSidebarOpen(false), Icon: MenuIcon })
2271
+ ] }),
2272
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native12.View, { style: flexStyle6, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2273
+ Sidebar,
2274
+ {
2275
+ previewInitialized: true,
2276
+ indexError: void 0,
2277
+ refs: placeholderObject,
2278
+ setSelection,
2279
+ status: placeholderObject,
2280
+ index: storyHash,
2281
+ storyId: story?.id,
2282
+ refId: DEFAULT_REF_ID
2283
+ }
2284
+ ) })
2285
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_ui_common7.IconButton, { onPress: () => setDesktopSidebarOpen(true), Icon: MenuIcon }) }),
2286
+ desktopSidebarOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2287
+ ResizeHandle,
2028
2288
  {
2029
- previewInitialized: true,
2030
- indexError: void 0,
2031
- refs: placeholderObject,
2032
- setSelection,
2033
- status: placeholderObject,
2034
- index: storyHash,
2035
- storyId: story?.id,
2036
- refId: DEFAULT_REF_ID
2289
+ direction: "horizontal",
2290
+ onResize: handleSidebarResize,
2291
+ onResizeStart,
2292
+ onResizeEnd
2037
2293
  }
2038
- )
2039
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_ui_common7.IconButton, { onPress: () => setDesktopSidebarOpen(true), Icon: MenuIcon }) }) : null,
2040
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native10.View, { style: mobileContentStyle, children: [
2041
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native10.View, { style: contentContainerStyle, children }),
2042
- story?.parameters?.hideFullScreenButton || isDesktop ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2043
- import_react_native10.TouchableOpacity,
2294
+ ) : null
2295
+ ] }) : null,
2296
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native12.View, { style: mobileContentStyle, children: [
2297
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native12.View, { style: contentContainerStyle, pointerEvents: isResizing ? "none" : "auto", children }),
2298
+ story?.parameters?.hideFullScreenButton || isDesktop ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2299
+ import_react_native12.TouchableOpacity,
2044
2300
  {
2045
2301
  style: fullScreenButtonStyle,
2302
+ hitSlop: { top: 10, bottom: 10, left: 10, right: 10 },
2046
2303
  onPress: () => setUiHidden((prev) => !prev),
2047
- children: uiHidden ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CloseFullscreenIcon, { color: theme.color.mediumdark }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FullscreenIcon, { color: theme.color.mediumdark })
2304
+ children: uiHidden ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseFullscreenIcon, { color: theme.color.mediumdark }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(FullscreenIcon, { color: theme.color.mediumdark })
2048
2305
  }
2049
2306
  ),
2050
- isDesktop ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native10.View, { style: desktopAddonsPanelStyle, children: desktopAddonsPanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AddonsTabs, { storyId: story?.id, onClose: () => setDesktopAddonsPanelOpen(false) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2051
- import_react_native_ui_common7.IconButton,
2052
- {
2053
- style: iconFloatRightStyle,
2054
- onPress: () => setDesktopAddonsPanelOpen(true),
2055
- Icon: BottomBarToggleIcon
2056
- }
2057
- ) }) : null
2307
+ isDesktop ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
2308
+ desktopAddonsPanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2309
+ ResizeHandle,
2310
+ {
2311
+ direction: "vertical",
2312
+ onResize: handleAddonsPanelResize,
2313
+ onResizeStart,
2314
+ onResizeEnd
2315
+ }
2316
+ ) : null,
2317
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native12.View, { style: desktopAddonsPanelStyle, pointerEvents: isResizing ? "none" : "auto", children: desktopAddonsPanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AddonsTabs, { storyId: story?.id, onClose: () => setDesktopAddonsPanelOpen(false) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2318
+ import_react_native_ui_common7.IconButton,
2319
+ {
2320
+ style: iconFloatRightStyle,
2321
+ onPress: () => setDesktopAddonsPanelOpen(true),
2322
+ Icon: BottomBarToggleIcon
2323
+ }
2324
+ ) })
2325
+ ] }) : null
2058
2326
  ] }),
2059
- !uiHidden && !isDesktop ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Container3, { style: navContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Nav, { children: [
2060
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2327
+ !uiHidden && !isDesktop ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Container2, { style: navContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Nav, { children: [
2328
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2061
2329
  Button2,
2062
2330
  {
2063
2331
  testID: "mobile-menu-button",
@@ -2065,8 +2333,8 @@ var Layout = ({
2065
2333
  hitSlop: navButtonHitSlop,
2066
2334
  onPress: () => mobileMenuDrawerRef.current?.setMobileMenuOpen(true),
2067
2335
  children: [
2068
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MenuIcon, { color: theme.color.mediumdark }),
2069
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native10.Text, { style: navButtonTextStyle, numberOfLines: 1, children: [
2336
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MenuIcon, { color: theme.color.mediumdark }),
2337
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native12.Text, { style: navButtonTextStyle, numberOfLines: 1, children: [
2070
2338
  story?.title,
2071
2339
  "/",
2072
2340
  story?.name
@@ -2074,18 +2342,19 @@ var Layout = ({
2074
2342
  ]
2075
2343
  }
2076
2344
  ),
2077
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2345
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2078
2346
  import_react_native_ui_common7.IconButton,
2079
2347
  {
2080
2348
  testID: "mobile-addons-button",
2349
+ hitSlop: addonButtonHitSlop,
2081
2350
  onPress: () => addonPanelRef.current.setAddonsPanelOpen(true),
2082
2351
  Icon: BottomBarToggleIcon
2083
2352
  }
2084
2353
  )
2085
2354
  ] }) }) : null,
2086
- isDesktop ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectedNodeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(MobileMenuDrawer, { ref: mobileMenuDrawerRef, children: [
2087
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native10.View, { style: mobileMenuDrawerContentStyle, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StorybookLogo, { theme }) }),
2088
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2355
+ isDesktop ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(MobileMenuDrawer, { ref: mobileMenuDrawerRef, children: [
2356
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native12.View, { style: mobileMenuDrawerContentStyle, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StorybookLogo, { theme }) }),
2357
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2089
2358
  Sidebar,
2090
2359
  {
2091
2360
  previewInitialized: true,
@@ -2098,11 +2367,11 @@ var Layout = ({
2098
2367
  refId: DEFAULT_REF_ID
2099
2368
  }
2100
2369
  )
2101
- ] }) }),
2102
- isDesktop ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MobileAddonsPanel, { ref: addonPanelRef, storyId: story?.id })
2370
+ ] }),
2371
+ isDesktop ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MobileAddonsPanel, { ref: addonPanelRef, storyId: story?.id })
2103
2372
  ] });
2104
2373
  };
2105
- var Nav = import_react_native_theming10.styled.View({
2374
+ var Nav = import_react_native_theming11.styled.View({
2106
2375
  display: "flex",
2107
2376
  flexDirection: "row",
2108
2377
  alignItems: "center",
@@ -2111,14 +2380,14 @@ var Nav = import_react_native_theming10.styled.View({
2111
2380
  height: 40,
2112
2381
  paddingHorizontal: 6
2113
2382
  });
2114
- var Container3 = import_react_native_theming10.styled.View(({ theme }) => ({
2383
+ var Container2 = import_react_native_theming11.styled.View(({ theme }) => ({
2115
2384
  alignSelf: "flex-end",
2116
2385
  width: "100%",
2117
2386
  backgroundColor: theme.barBg,
2118
2387
  borderTopColor: theme.appBorderColor,
2119
2388
  borderTopWidth: 1
2120
2389
  }));
2121
- var Button2 = import_react_native_theming10.styled.TouchableOpacity(({ theme }) => ({
2390
+ var Button2 = import_react_native_theming11.styled.TouchableOpacity(({ theme }) => ({
2122
2391
  display: "flex",
2123
2392
  flexDirection: "row",
2124
2393
  alignItems: "center",