@storybook/react-native-ui 8.4.3-alpha.1 → 8.4.3

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.d.ts CHANGED
@@ -219,4 +219,13 @@ declare const transformStoryIndexToStoriesHash: (input: API_PreparedStoryIndex |
219
219
  declare const transformStoryIndexV2toV3: (index: StoryIndexV2) => StoryIndexV3;
220
220
  declare const transformStoryIndexV3toV4: (index: StoryIndexV3) => API_PreparedStoryIndex;
221
221
 
222
- export { Button, ButtonIcon, ButtonProps, ButtonText, CombinedDataset, ComponentNode, Dataset, ExpandType, Explorer, ExplorerProps, GetSearchItemProps, GroupNode, Highlight, IconButton, Item, ItemRef, Layout, LayoutProvider, LeafNodeStyleWrapper, Node, NodeProps$1 as NodeProps, RefType, Refs, RootNode, RootNodeText, SearchChildrenFn, SearchItem, SearchResult, SearchResultProps, Selection, Sidebar, SidebarProps, StoryNode, StoryRef, Tree, isExpandType, transformStoryIndexToStoriesHash, transformStoryIndexV2toV3, transformStoryIndexV3toV4, useCombination, useLayout };
222
+ interface Storage {
223
+ getItem: (key: string) => Promise<string | null>;
224
+ setItem: (key: string, value: string) => Promise<void>;
225
+ }
226
+ declare const StorageProvider: FC<PropsWithChildren<{
227
+ storage: Storage;
228
+ }>>;
229
+ declare const useStorage: () => Storage;
230
+
231
+ export { Button, ButtonIcon, ButtonProps, ButtonText, CombinedDataset, ComponentNode, Dataset, ExpandType, Explorer, ExplorerProps, GetSearchItemProps, GroupNode, Highlight, IconButton, Item, ItemRef, Layout, LayoutProvider, LeafNodeStyleWrapper, Node, NodeProps$1 as NodeProps, RefType, Refs, RootNode, RootNodeText, SearchChildrenFn, SearchItem, SearchResult, SearchResultProps, Selection, Sidebar, SidebarProps, StorageProvider, StoryNode, StoryRef, Tree, isExpandType, transformStoryIndexToStoriesHash, transformStoryIndexV2toV3, transformStoryIndexV3toV4, useCombination, useLayout, useStorage };
package/dist/index.js CHANGED
@@ -2929,6 +2929,7 @@ __export(src_exports, {
2929
2929
  RootNode: () => RootNode,
2930
2930
  RootNodeText: () => RootNodeText,
2931
2931
  Sidebar: () => Sidebar,
2932
+ StorageProvider: () => StorageProvider,
2932
2933
  StoryNode: () => StoryNode,
2933
2934
  Tree: () => Tree,
2934
2935
  isExpandType: () => isExpandType,
@@ -2936,7 +2937,8 @@ __export(src_exports, {
2936
2937
  transformStoryIndexV2toV3: () => transformStoryIndexV2toV3,
2937
2938
  transformStoryIndexV3toV4: () => transformStoryIndexV3toV4,
2938
2939
  useCombination: () => useCombination,
2939
- useLayout: () => useLayout
2940
+ useLayout: () => useLayout,
2941
+ useStorage: () => useStorage
2940
2942
  });
2941
2943
  module.exports = __toCommonJS(src_exports);
2942
2944
 
@@ -3331,7 +3333,7 @@ var ExpandAllIcon = ({
3331
3333
  ) });
3332
3334
  };
3333
3335
 
3334
- // src/useExpanded.ts
3336
+ // src/hooks/useExpanded.ts
3335
3337
  var import_react4 = require("react");
3336
3338
 
3337
3339
  // src/util/tree.ts
@@ -3395,7 +3397,7 @@ var getStateType = (isLoading, isAuthRequired, isError, isEmpty) => {
3395
3397
  var removeNoiseFromName = (storyName) => storyName.replaceAll(/(\s|-|_)/gi, "");
3396
3398
  var isStoryHoistable = (storyName, componentName) => removeNoiseFromName(storyName) === removeNoiseFromName(componentName);
3397
3399
 
3398
- // src/useExpanded.ts
3400
+ // src/hooks/useExpanded.ts
3399
3401
  var initializeExpanded = ({
3400
3402
  initialExpanded,
3401
3403
  rootIds
@@ -4360,7 +4362,7 @@ var SearchResults = import_react11.default.memo(function SearchResults2({
4360
4362
  ] });
4361
4363
  });
4362
4364
 
4363
- // src/useLastViewed.ts
4365
+ // src/hooks/useLastViewed.ts
4364
4366
  var import_debounce = __toESM(require_debounce());
4365
4367
  var import_react13 = require("react");
4366
4368
  var import_store2 = __toESM(require("store2"));
@@ -4493,8 +4495,8 @@ var Sidebar = import_react14.default.memo(function Sidebar2({
4493
4495
  var import_core_events = require("@storybook/core/core-events");
4494
4496
  var import_manager_api2 = require("@storybook/core/manager-api");
4495
4497
  var import_react_native_theming15 = require("@storybook/react-native-theming");
4496
- var import_react17 = require("react");
4497
- var import_react_native8 = require("react-native");
4498
+ var import_react20 = require("react");
4499
+ var import_react_native9 = require("react-native");
4498
4500
  var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
4499
4501
 
4500
4502
  // src/MobileAddonsPanel.tsx
@@ -4746,48 +4748,70 @@ var BottomBarToggleIcon = ({
4746
4748
  ] });
4747
4749
  };
4748
4750
 
4749
- // src/icon/DarkLogo.tsx
4750
- var import_react_native_svg11 = __toESM(require("react-native-svg"));
4751
+ // src/icon/MenuIcon.tsx
4752
+ var import_react_native_svg11 = require("react-native-svg");
4751
4753
  var import_jsx_runtime23 = require("react/jsx-runtime");
4754
+ var MenuIcon = ({
4755
+ color = "currentColor",
4756
+ width = 14,
4757
+ height = 14,
4758
+ ...props
4759
+ }) => {
4760
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_svg11.Svg, { width, height, viewBox: "0 0 14 14", fill: "none", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4761
+ import_react_native_svg11.Path,
4762
+ {
4763
+ d: "M13 3.5a.5.5 0 010 1H1a.5.5 0 010-1h12zM13.5 10a.5.5 0 00-.5-.5H1a.5.5 0 000 1h12a.5.5 0 00.5-.5zM13 6.5a.5.5 0 010 1H1a.5.5 0 010-1h12z",
4764
+ fill: color
4765
+ }
4766
+ ) });
4767
+ };
4768
+
4769
+ // src/StorybookLogo.tsx
4770
+ var import_react17 = require("react");
4771
+ var import_react_native8 = require("react-native");
4772
+
4773
+ // src/icon/DarkLogo.tsx
4774
+ var import_react_native_svg12 = __toESM(require("react-native-svg"));
4775
+ var import_jsx_runtime24 = require("react/jsx-runtime");
4752
4776
  function DarkLogo({ width = 300, height = 60, ...props }) {
4753
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native_svg11.default, { width, height, viewBox: "0 0 300 60", ...props, children: [
4754
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native_svg11.Defs, { children: [
4755
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4756
- import_react_native_svg11.Path,
4777
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.default, { width, height, viewBox: "0 0 300 60", ...props, children: [
4778
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.Defs, { children: [
4779
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4780
+ import_react_native_svg12.Path,
4757
4781
  {
4758
4782
  id: "a",
4759
4783
  d: "M1.848 54.92L.002 5.723A2.997 2.997 0 012.81 2.621L44.654.006a2.997 2.997 0 013.183 2.99v53.607a2.997 2.997 0 01-3.13 2.994l-40-1.796a2.997 2.997 0 01-2.86-2.882z"
4760
4784
  }
4761
4785
  ),
4762
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4763
- import_react_native_svg11.Path,
4786
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4787
+ import_react_native_svg12.Path,
4764
4788
  {
4765
4789
  id: "c",
4766
4790
  d: "M1.848 54.92L.002 5.723A2.997 2.997 0 012.81 2.621L44.654.006a2.997 2.997 0 013.183 2.99v53.607a2.997 2.997 0 01-3.13 2.994l-40-1.796a2.997 2.997 0 01-2.86-2.882z"
4767
4791
  }
4768
4792
  )
4769
4793
  ] }),
4770
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native_svg11.G, { fill: "none", fillRule: "evenodd", children: [
4771
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4772
- import_react_native_svg11.Path,
4794
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.G, { fill: "none", fillRule: "evenodd", children: [
4795
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4796
+ import_react_native_svg12.Path,
4773
4797
  {
4774
4798
  fill: "#FFF",
4775
4799
  fillRule: "nonzero",
4776
4800
  d: "M80.387 47.178c-2.543 0-4.99-.342-7.343-1.025-2.352-.684-4.307-1.63-5.864-2.837l2.384-5.293c3.242 2.257 6.882 3.386 10.919 3.386 2.097 0 3.71-.342 4.84-1.026 1.128-.683 1.692-1.629 1.692-2.836 0-1.081-.517-1.924-1.55-2.528-1.033-.603-2.869-1.192-5.507-1.764-2.956-.604-5.316-1.335-7.08-2.193-1.765-.858-3.052-1.915-3.862-3.17-.811-1.256-1.216-2.806-1.216-4.65 0-2.034.564-3.846 1.692-5.435 1.129-1.59 2.71-2.837 4.744-3.743 2.035-.906 4.387-1.359 7.057-1.359 2.384 0 4.68.35 6.89 1.05 2.21.699 3.965 1.636 5.269 2.812l-2.384 5.293c-3.084-2.257-6.326-3.385-9.727-3.385-1.94 0-3.465.373-4.577 1.12-1.113.747-1.67 1.772-1.67 3.075 0 .763.215 1.391.644 1.884.43.492 1.145.93 2.146 1.31 1.001.382 2.424.78 4.267 1.193 4.323.954 7.43 2.177 9.322 3.671 1.891 1.494 2.837 3.56 2.837 6.199 0 3.178-1.224 5.682-3.672 7.51-2.447 1.827-5.864 2.74-10.25 2.74zm31.183-5.34c.731 0 1.494-.048 2.289-.143l-.382 5.244c-.922.128-1.844.191-2.765.191-3.56 0-6.159-.779-7.796-2.336-1.637-1.558-2.456-3.926-2.456-7.104v-8.964h-4.434v-5.388h4.434v-6.866h7.2v6.866h5.865v5.388h-5.865v8.916c0 2.797 1.303 4.196 3.91 4.196zm16.736 5.292c-2.48 0-4.657-.5-6.533-1.502-1.875-1.001-3.321-2.416-4.338-4.243-1.018-1.828-1.526-3.982-1.526-6.46 0-2.48.508-4.634 1.526-6.462 1.017-1.827 2.463-3.234 4.338-4.22 1.876-.985 4.053-1.477 6.533-1.477 2.479 0 4.656.492 6.532 1.478 1.875.985 3.321 2.392 4.339 4.22 1.017 1.827 1.525 3.98 1.525 6.46s-.508 4.633-1.525 6.46c-1.018 1.828-2.464 3.243-4.34 4.244-1.875 1.002-4.052 1.502-6.531 1.502zm0-5.483c3.496 0 5.244-2.24 5.244-6.723 0-2.257-.453-3.941-1.358-5.054-.906-1.113-2.202-1.669-3.886-1.669-3.497 0-5.245 2.241-5.245 6.723 0 4.482 1.748 6.723 5.245 6.723zm32.327-12.969l-4.053.43c-2.003.19-3.417.754-4.244 1.692-.826.938-1.24 2.185-1.24 3.743v12.206h-7.199V23.338h6.914v3.957c1.176-2.702 3.607-4.18 7.295-4.434l2.098-.143.429 5.96zm20.92-5.292h7.056L174.496 55.33H167.2l4.481-9.87-9.63-22.075h7.485l5.912 14.876 6.103-14.876zm23.744-.62c2.034 0 3.83.492 5.388 1.478 1.557.985 2.773 2.392 3.647 4.22.874 1.827 1.311 3.949 1.311 6.365 0 2.416-.437 4.553-1.31 6.413-.875 1.86-2.099 3.306-3.672 4.339-1.574 1.033-3.362 1.55-5.364 1.55-1.621 0-3.083-.343-4.387-1.026-1.303-.683-2.304-1.629-3.004-2.837v3.48h-7.104V13.135h7.2v13.35c.7-1.175 1.692-2.09 2.98-2.74 1.287-.652 2.726-.978 4.315-.978zm-2.098 18.881c1.685 0 2.988-.596 3.91-1.788.922-1.192 1.382-2.869 1.382-5.03 0-2.13-.46-3.759-1.382-4.887-.922-1.129-2.225-1.693-3.91-1.693s-2.988.58-3.91 1.74c-.922 1.16-1.383 2.805-1.383 4.935 0 2.162.461 3.822 1.383 4.983.922 1.16 2.225 1.74 3.91 1.74zm28.083 5.483c-2.479 0-4.656-.5-6.532-1.502-1.875-1.001-3.321-2.416-4.339-4.243-1.017-1.828-1.525-3.982-1.525-6.46 0-2.48.508-4.634 1.525-6.462 1.018-1.827 2.464-3.234 4.34-4.22 1.875-.985 4.052-1.477 6.531-1.477 2.48 0 4.657.492 6.533 1.478 1.875.985 3.321 2.392 4.339 4.22 1.017 1.827 1.525 3.98 1.525 6.46s-.508 4.633-1.525 6.46c-1.018 1.828-2.464 3.243-4.34 4.244-1.875 1.002-4.052 1.502-6.532 1.502zm0-5.483c3.497 0 5.245-2.24 5.245-6.723 0-2.257-.453-3.941-1.359-5.054-.906-1.113-2.2-1.669-3.886-1.669-3.496 0-5.244 2.241-5.244 6.723 0 4.482 1.748 6.723 5.244 6.723zm26.844 5.483c-2.48 0-4.656-.5-6.532-1.502-1.875-1.001-3.322-2.416-4.339-4.243-1.017-1.828-1.525-3.982-1.525-6.46 0-2.48.508-4.634 1.525-6.462 1.017-1.827 2.464-3.234 4.34-4.22 1.875-.985 4.052-1.477 6.531-1.477 2.48 0 4.657.492 6.532 1.478 1.876.985 3.322 2.392 4.34 4.22 1.017 1.827 1.525 3.98 1.525 6.46s-.508 4.633-1.526 6.46c-1.017 1.828-2.463 3.243-4.339 4.244-1.875 1.002-4.052 1.502-6.532 1.502zm0-5.483c3.497 0 5.245-2.24 5.245-6.723 0-2.257-.453-3.941-1.359-5.054-.906-1.113-2.201-1.669-3.886-1.669-3.496 0-5.244 2.241-5.244 6.723 0 4.482 1.748 6.723 5.244 6.723zM299 46.749h-8.82l-8.965-10.442v10.442h-7.2V13.134h7.2v20.217l8.63-9.965h8.583l-9.822 11.157L299 46.749z"
4777
4801
  }
4778
4802
  ),
4779
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4780
- import_react_native_svg11.Path,
4803
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4804
+ import_react_native_svg12.Path,
4781
4805
  {
4782
4806
  d: "M48.831 2.81c.004.062.006.124.006.187v53.606a2.997 2.997 0 01-3.13 2.994l-40-1.796a2.997 2.997 0 01-2.86-2.882L1.002 5.724A2.997 2.997 0 013.81 2.621L36.609.57l-.285 6.756a.447.447 0 00.05.223l.04.066c.15.196.43.235.627.085l2.623-1.99 2.217 1.746a.447.447 0 00.723-.367L42.356.211l3.298-.205A2.997 2.997 0 0148.83 2.81z",
4783
4807
  fill: "#FF4785",
4784
4808
  fillRule: "nonzero"
4785
4809
  }
4786
4810
  ),
4787
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native_svg11.G, { transform: "translate(1)", children: [
4788
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_svg11.Mask, { id: "b", fill: "#fff", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_svg11.Use, { xlinkHref: "#a" }) }),
4789
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4790
- import_react_native_svg11.Path,
4811
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.G, { transform: "translate(1)", children: [
4812
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_svg12.Mask, { id: "b", fill: "#fff", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_svg12.Use, { xlinkHref: "#a" }) }),
4813
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4814
+ import_react_native_svg12.Path,
4791
4815
  {
4792
4816
  fill: "#FFF",
4793
4817
  fillRule: "nonzero",
@@ -4796,10 +4820,10 @@ function DarkLogo({ width = 300, height = 60, ...props }) {
4796
4820
  }
4797
4821
  )
4798
4822
  ] }),
4799
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native_svg11.G, { transform: "translate(1)", children: [
4800
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_svg11.Mask, { id: "d", fill: "#fff", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_svg11.Use, { xlinkHref: "#c" }) }),
4801
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4802
- import_react_native_svg11.Path,
4823
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.G, { transform: "translate(1)", children: [
4824
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_svg12.Mask, { id: "d", fill: "#fff", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_svg12.Use, { xlinkHref: "#c" }) }),
4825
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4826
+ import_react_native_svg12.Path,
4803
4827
  {
4804
4828
  fill: "#FFF",
4805
4829
  fillRule: "nonzero",
@@ -4813,47 +4837,47 @@ function DarkLogo({ width = 300, height = 60, ...props }) {
4813
4837
  }
4814
4838
 
4815
4839
  // src/icon/Logo.tsx
4816
- var import_react_native_svg12 = __toESM(require("react-native-svg"));
4817
- var import_jsx_runtime24 = require("react/jsx-runtime");
4840
+ var import_react_native_svg13 = __toESM(require("react-native-svg"));
4841
+ var import_jsx_runtime25 = require("react/jsx-runtime");
4818
4842
  function Logo({ width = 300, height = 60, ...props }) {
4819
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.default, { width, height, viewBox: "0 0 300 60", ...props, children: [
4820
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.Defs, { children: [
4821
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4822
- import_react_native_svg12.Path,
4843
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native_svg13.default, { width, height, viewBox: "0 0 300 60", ...props, children: [
4844
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native_svg13.Defs, { children: [
4845
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4846
+ import_react_native_svg13.Path,
4823
4847
  {
4824
4848
  id: "a",
4825
4849
  d: "M1.848 54.92L.002 5.723A2.997 2.997 0 012.81 2.621L44.654.006a2.997 2.997 0 013.183 2.99v53.607a2.997 2.997 0 01-3.13 2.994l-40-1.796a2.997 2.997 0 01-2.86-2.882z"
4826
4850
  }
4827
4851
  ),
4828
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4829
- import_react_native_svg12.Path,
4852
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4853
+ import_react_native_svg13.Path,
4830
4854
  {
4831
4855
  id: "c",
4832
4856
  d: "M1.848 54.92L.002 5.723A2.997 2.997 0 012.81 2.621L44.654.006a2.997 2.997 0 013.183 2.99v53.607a2.997 2.997 0 01-3.13 2.994l-40-1.796a2.997 2.997 0 01-2.86-2.882z"
4833
4857
  }
4834
4858
  )
4835
4859
  ] }),
4836
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.G, { fill: "none", fillRule: "evenodd", children: [
4837
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4838
- import_react_native_svg12.Path,
4860
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native_svg13.G, { fill: "none", fillRule: "evenodd", children: [
4861
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4862
+ import_react_native_svg13.Path,
4839
4863
  {
4840
4864
  fill: "#333",
4841
4865
  fillRule: "nonzero",
4842
4866
  d: "M80.387 47.178c-2.543 0-4.99-.342-7.343-1.025-2.352-.684-4.307-1.63-5.864-2.837l2.384-5.293c3.242 2.257 6.882 3.386 10.919 3.386 2.097 0 3.71-.342 4.84-1.026 1.128-.683 1.692-1.629 1.692-2.836 0-1.081-.517-1.924-1.55-2.528-1.033-.603-2.869-1.192-5.507-1.764-2.956-.604-5.316-1.335-7.08-2.193-1.765-.858-3.052-1.915-3.862-3.17-.811-1.256-1.216-2.806-1.216-4.65 0-2.034.564-3.846 1.692-5.435 1.129-1.59 2.71-2.837 4.744-3.743 2.035-.906 4.387-1.359 7.057-1.359 2.384 0 4.68.35 6.89 1.05 2.21.699 3.965 1.636 5.269 2.812l-2.384 5.293c-3.084-2.257-6.326-3.385-9.727-3.385-1.94 0-3.465.373-4.577 1.12-1.113.747-1.67 1.772-1.67 3.075 0 .763.215 1.391.644 1.884.43.492 1.145.93 2.146 1.31 1.001.382 2.424.78 4.267 1.193 4.323.954 7.43 2.177 9.322 3.671 1.891 1.494 2.837 3.56 2.837 6.199 0 3.178-1.224 5.682-3.672 7.51-2.447 1.827-5.864 2.74-10.25 2.74zm31.183-5.34c.731 0 1.494-.048 2.289-.143l-.382 5.244c-.922.128-1.844.191-2.765.191-3.56 0-6.159-.779-7.796-2.336-1.637-1.558-2.456-3.926-2.456-7.104v-8.964h-4.434v-5.388h4.434v-6.866h7.2v6.866h5.865v5.388h-5.865v8.916c0 2.797 1.303 4.196 3.91 4.196zm16.736 5.292c-2.48 0-4.657-.5-6.533-1.502-1.875-1.001-3.321-2.416-4.338-4.243-1.018-1.828-1.526-3.982-1.526-6.46 0-2.48.508-4.634 1.526-6.462 1.017-1.827 2.463-3.234 4.338-4.22 1.876-.985 4.053-1.477 6.533-1.477 2.479 0 4.656.492 6.532 1.478 1.875.985 3.321 2.392 4.339 4.22 1.017 1.827 1.525 3.98 1.525 6.46s-.508 4.633-1.525 6.46c-1.018 1.828-2.464 3.243-4.34 4.244-1.875 1.002-4.052 1.502-6.531 1.502zm0-5.483c3.496 0 5.244-2.24 5.244-6.723 0-2.257-.453-3.941-1.358-5.054-.906-1.113-2.202-1.669-3.886-1.669-3.497 0-5.245 2.241-5.245 6.723 0 4.482 1.748 6.723 5.245 6.723zm32.327-12.969l-4.053.43c-2.003.19-3.417.754-4.244 1.692-.826.938-1.24 2.185-1.24 3.743v12.206h-7.199V23.338h6.914v3.957c1.176-2.702 3.607-4.18 7.295-4.434l2.098-.143.429 5.96zm20.92-5.292h7.056L174.496 55.33H167.2l4.481-9.87-9.63-22.075h7.485l5.912 14.876 6.103-14.876zm23.744-.62c2.034 0 3.83.492 5.388 1.478 1.557.985 2.773 2.392 3.647 4.22.874 1.827 1.311 3.949 1.311 6.365 0 2.416-.437 4.553-1.31 6.413-.875 1.86-2.099 3.306-3.672 4.339-1.574 1.033-3.362 1.55-5.364 1.55-1.621 0-3.083-.343-4.387-1.026-1.303-.683-2.304-1.629-3.004-2.837v3.48h-7.104V13.135h7.2v13.35c.7-1.175 1.692-2.09 2.98-2.74 1.287-.652 2.726-.978 4.315-.978zm-2.098 18.881c1.685 0 2.988-.596 3.91-1.788.922-1.192 1.382-2.869 1.382-5.03 0-2.13-.46-3.759-1.382-4.887-.922-1.129-2.225-1.693-3.91-1.693s-2.988.58-3.91 1.74c-.922 1.16-1.383 2.805-1.383 4.935 0 2.162.461 3.822 1.383 4.983.922 1.16 2.225 1.74 3.91 1.74zm28.083 5.483c-2.479 0-4.656-.5-6.532-1.502-1.875-1.001-3.321-2.416-4.339-4.243-1.017-1.828-1.525-3.982-1.525-6.46 0-2.48.508-4.634 1.525-6.462 1.018-1.827 2.464-3.234 4.34-4.22 1.875-.985 4.052-1.477 6.531-1.477 2.48 0 4.657.492 6.533 1.478 1.875.985 3.321 2.392 4.339 4.22 1.017 1.827 1.525 3.98 1.525 6.46s-.508 4.633-1.525 6.46c-1.018 1.828-2.464 3.243-4.34 4.244-1.875 1.002-4.052 1.502-6.532 1.502zm0-5.483c3.497 0 5.245-2.24 5.245-6.723 0-2.257-.453-3.941-1.359-5.054-.906-1.113-2.2-1.669-3.886-1.669-3.496 0-5.244 2.241-5.244 6.723 0 4.482 1.748 6.723 5.244 6.723zm26.844 5.483c-2.48 0-4.656-.5-6.532-1.502-1.875-1.001-3.322-2.416-4.339-4.243-1.017-1.828-1.525-3.982-1.525-6.46 0-2.48.508-4.634 1.525-6.462 1.017-1.827 2.464-3.234 4.34-4.22 1.875-.985 4.052-1.477 6.531-1.477 2.48 0 4.657.492 6.532 1.478 1.876.985 3.322 2.392 4.34 4.22 1.017 1.827 1.525 3.98 1.525 6.46s-.508 4.633-1.526 6.46c-1.017 1.828-2.463 3.243-4.339 4.244-1.875 1.002-4.052 1.502-6.532 1.502zm0-5.483c3.497 0 5.245-2.24 5.245-6.723 0-2.257-.453-3.941-1.359-5.054-.906-1.113-2.201-1.669-3.886-1.669-3.496 0-5.244 2.241-5.244 6.723 0 4.482 1.748 6.723 5.244 6.723zM299 46.749h-8.82l-8.965-10.442v10.442h-7.2V13.134h7.2v20.217l8.63-9.965h8.583l-9.822 11.157L299 46.749z"
4843
4867
  }
4844
4868
  ),
4845
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4846
- import_react_native_svg12.Path,
4869
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4870
+ import_react_native_svg13.Path,
4847
4871
  {
4848
4872
  d: "M48.831 2.81c.004.062.006.124.006.187v53.606a2.997 2.997 0 01-3.13 2.994l-40-1.796a2.997 2.997 0 01-2.86-2.882L1.002 5.724A2.997 2.997 0 013.81 2.621L36.609.57l-.285 6.756a.447.447 0 00.05.223l.04.066c.15.196.43.235.627.085l2.623-1.99 2.217 1.746a.447.447 0 00.723-.367L42.356.211l3.298-.205A2.997 2.997 0 0148.83 2.81z",
4849
4873
  fill: "#FF4785",
4850
4874
  fillRule: "nonzero"
4851
4875
  }
4852
4876
  ),
4853
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.G, { transform: "translate(1)", children: [
4854
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_svg12.Mask, { id: "b", fill: "#fff", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_svg12.Use, { xlinkHref: "#a" }) }),
4855
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4856
- import_react_native_svg12.Path,
4877
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native_svg13.G, { transform: "translate(1)", children: [
4878
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native_svg13.Mask, { id: "b", fill: "#fff", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native_svg13.Use, { xlinkHref: "#a" }) }),
4879
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4880
+ import_react_native_svg13.Path,
4857
4881
  {
4858
4882
  fill: "#FFF",
4859
4883
  fillRule: "nonzero",
@@ -4862,10 +4886,10 @@ function Logo({ width = 300, height = 60, ...props }) {
4862
4886
  }
4863
4887
  )
4864
4888
  ] }),
4865
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native_svg12.G, { transform: "translate(1)", children: [
4866
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_svg12.Mask, { id: "d", fill: "#fff", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_svg12.Use, { xlinkHref: "#c" }) }),
4867
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4868
- import_react_native_svg12.Path,
4889
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native_svg13.G, { transform: "translate(1)", children: [
4890
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native_svg13.Mask, { id: "d", fill: "#fff", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native_svg13.Use, { xlinkHref: "#c" }) }),
4891
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4892
+ import_react_native_svg13.Path,
4869
4893
  {
4870
4894
  fill: "#FFF",
4871
4895
  fillRule: "nonzero",
@@ -4878,41 +4902,148 @@ function Logo({ width = 300, height = 60, ...props }) {
4878
4902
  ] });
4879
4903
  }
4880
4904
 
4881
- // src/icon/MenuIcon.tsx
4882
- var import_react_native_svg13 = require("react-native-svg");
4883
- var import_jsx_runtime25 = require("react/jsx-runtime");
4884
- var MenuIcon = ({
4885
- color = "currentColor",
4886
- width = 14,
4887
- height = 14,
4888
- ...props
4889
- }) => {
4890
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native_svg13.Svg, { width, height, viewBox: "0 0 14 14", fill: "none", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4891
- import_react_native_svg13.Path,
4905
+ // src/StorybookLogo.tsx
4906
+ var import_jsx_runtime26 = require("react/jsx-runtime");
4907
+ var WIDTH = 125;
4908
+ var HEIGHT = 25;
4909
+ var NoBrandLogo = ({ theme }) => theme.base === "light" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Logo, { height: HEIGHT, width: WIDTH }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DarkLogo, { height: HEIGHT, width: WIDTH });
4910
+ function isElement(value) {
4911
+ return (0, import_react17.isValidElement)(value);
4912
+ }
4913
+ var BrandLogo = ({ theme }) => {
4914
+ 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));
4915
+ (0, import_react17.useEffect)(() => {
4916
+ if (imageHasNoWidthOrHeight) {
4917
+ console.warn(
4918
+ "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}}"
4919
+ );
4920
+ }
4921
+ }, [imageHasNoWidthOrHeight]);
4922
+ if (!theme.brand.image) {
4923
+ return null;
4924
+ }
4925
+ if (isElement(theme.brand.image)) {
4926
+ return theme.brand.image;
4927
+ }
4928
+ const image = /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4929
+ import_react_native8.Image,
4892
4930
  {
4893
- d: "M13 3.5a.5.5 0 010 1H1a.5.5 0 010-1h12zM13.5 10a.5.5 0 00-.5-.5H1a.5.5 0 000 1h12a.5.5 0 00.5-.5zM13 6.5a.5.5 0 010 1H1a.5.5 0 010-1h12z",
4894
- fill: color
4931
+ source: theme.brand.image,
4932
+ resizeMode: theme.brand.resizeMode ?? "contain",
4933
+ style: imageHasNoWidthOrHeight ? { width: WIDTH, height: HEIGHT } : void 0
4895
4934
  }
4896
- ) });
4935
+ );
4936
+ if (theme.brand.url) {
4937
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4938
+ import_react_native8.TouchableOpacity,
4939
+ {
4940
+ onPress: () => {
4941
+ if (theme.brand.url)
4942
+ import_react_native8.Linking.openURL(theme.brand.url);
4943
+ },
4944
+ children: image
4945
+ }
4946
+ );
4947
+ } else {
4948
+ return image;
4949
+ }
4950
+ };
4951
+ var BrandTitle = ({ theme }) => {
4952
+ const brandTitleStyle = (0, import_react17.useMemo)(() => {
4953
+ return {
4954
+ width: WIDTH,
4955
+ height: HEIGHT,
4956
+ color: theme.color.defaultText,
4957
+ fontSize: theme.typography.size.m1
4958
+ };
4959
+ }, [theme]);
4960
+ const title = /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.Text, { style: brandTitleStyle, numberOfLines: 1, ellipsizeMode: "tail", children: theme.brand.title });
4961
+ if (theme.brand.url) {
4962
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4963
+ import_react_native8.TouchableOpacity,
4964
+ {
4965
+ onPress: () => {
4966
+ if (theme.brand.url)
4967
+ import_react_native8.Linking.openURL(theme.brand.url);
4968
+ },
4969
+ children: title
4970
+ }
4971
+ );
4972
+ } else {
4973
+ return title;
4974
+ }
4975
+ };
4976
+ var StorybookLogo = ({ theme }) => {
4977
+ if (theme.brand?.image) {
4978
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BrandLogo, { theme });
4979
+ } else if (theme.brand?.title) {
4980
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BrandTitle, { theme });
4981
+ } else {
4982
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(NoBrandLogo, { theme });
4983
+ }
4984
+ };
4985
+
4986
+ // src/hooks/useStoreState.ts
4987
+ var import_react19 = require("react");
4988
+
4989
+ // src/StorageProvider.tsx
4990
+ var import_react18 = require("react");
4991
+ var import_jsx_runtime27 = require("react/jsx-runtime");
4992
+ var StorageContext = (0, import_react18.createContext)({
4993
+ getItem: async () => null,
4994
+ setItem: async () => {
4995
+ }
4996
+ });
4997
+ var StorageProvider = ({
4998
+ storage,
4999
+ children
5000
+ }) => {
5001
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(StorageContext.Provider, { value: storage, children });
5002
+ };
5003
+ var useStorage = () => (0, import_react18.useContext)(StorageContext);
5004
+
5005
+ // src/hooks/useStoreState.ts
5006
+ var useStoreBooleanState = (key, defaultValue) => {
5007
+ const storage = useStorage();
5008
+ const [val, setVal] = (0, import_react19.useState)(defaultValue);
5009
+ (0, import_react19.useEffect)(() => {
5010
+ storage.getItem(key).then((newVal) => {
5011
+ if (newVal === null || newVal === void 0) {
5012
+ setVal(defaultValue);
5013
+ } else {
5014
+ setVal(newVal === "true");
5015
+ }
5016
+ });
5017
+ }, [key, storage, defaultValue]);
5018
+ (0, import_react19.useEffect)(() => {
5019
+ storage.setItem(key, val.toString());
5020
+ }, [key, storage, val]);
5021
+ return [val, setVal];
4897
5022
  };
4898
5023
 
4899
5024
  // src/Layout.tsx
4900
- var import_jsx_runtime26 = require("react/jsx-runtime");
5025
+ var import_jsx_runtime28 = require("react/jsx-runtime");
4901
5026
  var Layout = ({
4902
5027
  storyHash,
4903
5028
  story,
4904
5029
  children
4905
5030
  }) => {
4906
5031
  const theme = (0, import_react_native_theming15.useTheme)();
4907
- const mobileMenuDrawerRef = (0, import_react17.useRef)(null);
4908
- const addonPanelRef = (0, import_react17.useRef)(null);
5032
+ const mobileMenuDrawerRef = (0, import_react20.useRef)(null);
5033
+ const addonPanelRef = (0, import_react20.useRef)(null);
4909
5034
  const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
4910
5035
  const { isDesktop } = useLayout();
4911
- const [desktopSidebarOpen, setDesktopSidebarOpen] = (0, import_react17.useState)(true);
4912
- const [desktopAddonsPanelOpen, setDesktopAddonsPanelOpen] = (0, import_react17.useState)(true);
5036
+ const [desktopSidebarOpen, setDesktopSidebarOpen] = useStoreBooleanState(
5037
+ "desktopSidebarState",
5038
+ true
5039
+ );
5040
+ const [desktopAddonsPanelOpen, setDesktopAddonsPanelOpen] = useStoreBooleanState(
5041
+ "desktopPanelState",
5042
+ true
5043
+ );
4913
5044
  if (isDesktop) {
4914
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4915
- import_react_native8.View,
5045
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5046
+ import_react_native9.View,
4916
5047
  {
4917
5048
  style: {
4918
5049
  flex: 1,
@@ -4921,8 +5052,8 @@ var Layout = ({
4921
5052
  flexDirection: "row"
4922
5053
  },
4923
5054
  children: [
4924
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4925
- import_react_native8.View,
5055
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5056
+ import_react_native9.View,
4926
5057
  {
4927
5058
  style: {
4928
5059
  width: desktopSidebarOpen ? 240 : void 0,
@@ -4930,16 +5061,16 @@ var Layout = ({
4930
5061
  borderColor: theme.appBorderColor,
4931
5062
  borderRightWidth: 1
4932
5063
  },
4933
- children: desktopSidebarOpen ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4934
- import_react_native8.ScrollView,
5064
+ children: desktopSidebarOpen ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5065
+ import_react_native9.ScrollView,
4935
5066
  {
4936
5067
  keyboardShouldPersistTaps: "handled",
4937
5068
  contentContainerStyle: {
4938
5069
  paddingBottom: insets.bottom
4939
5070
  },
4940
5071
  children: [
4941
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4942
- import_react_native8.View,
5072
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5073
+ import_react_native9.View,
4943
5074
  {
4944
5075
  style: {
4945
5076
  flexDirection: "row",
@@ -4951,12 +5082,12 @@ var Layout = ({
4951
5082
  justifyContent: "space-between"
4952
5083
  },
4953
5084
  children: [
4954
- theme.base === "light" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Logo, { height: 25, width: 125 }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DarkLogo, { height: 25, width: 125 }),
4955
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(IconButton, { onPress: () => setDesktopSidebarOpen(false), Icon: MenuIcon })
5085
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(StorybookLogo, { theme }),
5086
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IconButton, { onPress: () => setDesktopSidebarOpen(false), Icon: MenuIcon })
4956
5087
  ]
4957
5088
  }
4958
5089
  ),
4959
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5090
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4960
5091
  Sidebar,
4961
5092
  {
4962
5093
  extra: [],
@@ -4975,13 +5106,13 @@ var Layout = ({
4975
5106
  )
4976
5107
  ]
4977
5108
  }
4978
- ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(IconButton, { onPress: () => setDesktopSidebarOpen(true), Icon: MenuIcon })
5109
+ ) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IconButton, { onPress: () => setDesktopSidebarOpen(true), Icon: MenuIcon })
4979
5110
  }
4980
5111
  ),
4981
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native8.View, { style: { flex: 1 }, children: [
4982
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.View, { style: { flex: 1, overflow: "hidden" }, children }),
4983
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4984
- import_react_native8.View,
5112
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native9.View, { style: { flex: 1 }, children: [
5113
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native9.View, { style: { flex: 1, overflow: "hidden" }, children }),
5114
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5115
+ import_react_native9.View,
4985
5116
  {
4986
5117
  style: {
4987
5118
  height: desktopAddonsPanelOpen ? 300 : void 0,
@@ -4990,7 +5121,7 @@ var Layout = ({
4990
5121
  paddingTop: desktopAddonsPanelOpen ? 4 : 0,
4991
5122
  padding: desktopAddonsPanelOpen ? 0 : 10
4992
5123
  },
4993
- children: desktopAddonsPanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AddonsTabs, { storyId: story?.id, onClose: () => setDesktopAddonsPanelOpen(false) }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5124
+ children: desktopAddonsPanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(AddonsTabs, { storyId: story?.id, onClose: () => setDesktopAddonsPanelOpen(false) }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4994
5125
  IconButton,
4995
5126
  {
4996
5127
  style: { marginLeft: "auto" },
@@ -5005,10 +5136,10 @@ var Layout = ({
5005
5136
  }
5006
5137
  );
5007
5138
  }
5008
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native8.View, { style: { flex: 1, paddingTop: insets.top, backgroundColor: theme.background.content }, children: [
5009
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.View, { style: { flex: 1, overflow: "hidden" }, children }),
5010
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Container3, { style: { marginBottom: insets.bottom }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Nav, { children: [
5011
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5139
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native9.View, { style: { flex: 1, paddingTop: insets.top, backgroundColor: theme.background.content }, children: [
5140
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native9.View, { style: { flex: 1, overflow: "hidden" }, children }),
5141
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Container3, { style: { marginBottom: insets.bottom }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Nav, { children: [
5142
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5012
5143
  Button2,
5013
5144
  {
5014
5145
  style: { flexShrink: 1 },
@@ -5017,8 +5148,8 @@ var Layout = ({
5017
5148
  mobileMenuDrawerRef.current.setMobileMenuOpen(true);
5018
5149
  },
5019
5150
  children: [
5020
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MenuIcon, { color: theme.color.mediumdark }),
5021
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native8.Text, { style: { flexShrink: 1, color: theme.color.defaultText }, numberOfLines: 1, children: [
5151
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(MenuIcon, { color: theme.color.mediumdark }),
5152
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_native9.Text, { style: { flexShrink: 1, color: theme.color.defaultText }, numberOfLines: 1, children: [
5022
5153
  story?.title,
5023
5154
  "/",
5024
5155
  story?.name
@@ -5026,7 +5157,7 @@ var Layout = ({
5026
5157
  ]
5027
5158
  }
5028
5159
  ),
5029
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5160
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5030
5161
  IconButton,
5031
5162
  {
5032
5163
  onPress: () => addonPanelRef.current.setAddonsPanelOpen(true),
@@ -5034,9 +5165,9 @@ var Layout = ({
5034
5165
  }
5035
5166
  )
5036
5167
  ] }) }),
5037
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(MobileMenuDrawer, { ref: mobileMenuDrawerRef, children: [
5038
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native8.View, { style: { paddingLeft: 16, paddingTop: 4, paddingBottom: 4 }, children: theme.base === "light" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Logo, { height: 25, width: 125 }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DarkLogo, { height: 25, width: 125 }) }),
5039
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5168
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(MobileMenuDrawer, { ref: mobileMenuDrawerRef, children: [
5169
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native9.View, { style: { paddingLeft: 16, paddingTop: 4, paddingBottom: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(StorybookLogo, { theme }) }),
5170
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5040
5171
  Sidebar,
5041
5172
  {
5042
5173
  extra: [],
@@ -5054,7 +5185,7 @@ var Layout = ({
5054
5185
  }
5055
5186
  )
5056
5187
  ] }),
5057
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MobileAddonsPanel, { ref: addonPanelRef, storyId: story?.id })
5188
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(MobileAddonsPanel, { ref: addonPanelRef, storyId: story?.id })
5058
5189
  ] });
5059
5190
  };
5060
5191
  var Nav = import_react_native_theming15.styled.View({
@@ -5389,6 +5520,7 @@ var transformStoryIndexV3toV4 = (index) => {
5389
5520
  RootNode,
5390
5521
  RootNodeText,
5391
5522
  Sidebar,
5523
+ StorageProvider,
5392
5524
  StoryNode,
5393
5525
  Tree,
5394
5526
  isExpandType,
@@ -5396,5 +5528,6 @@ var transformStoryIndexV3toV4 = (index) => {
5396
5528
  transformStoryIndexV2toV3,
5397
5529
  transformStoryIndexV3toV4,
5398
5530
  useCombination,
5399
- useLayout
5531
+ useLayout,
5532
+ useStorage
5400
5533
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/react-native-ui",
3
- "version": "8.4.3-alpha.1",
3
+ "version": "8.4.3",
4
4
  "description": "ui components for react native storybook",
5
5
  "keywords": [
6
6
  "react",
@@ -60,7 +60,7 @@
60
60
  "dependencies": {
61
61
  "@storybook/core": "^8.4.2",
62
62
  "@storybook/react": "^8.4.2",
63
- "@storybook/react-native-theming": "^8.4.3-alpha.1",
63
+ "@storybook/react-native-theming": "^8.4.3",
64
64
  "fuse.js": "^7.0.0",
65
65
  "memoizerific": "^1.11.3",
66
66
  "polished": "^4.3.1",
@@ -81,5 +81,5 @@
81
81
  "publishConfig": {
82
82
  "access": "public"
83
83
  },
84
- "gitHead": "52feddc7a8059e56fa563c27f69a928bb852f96f"
84
+ "gitHead": "eacb2e3e0cd304f8a3fe151b0cb189ebdee7ce8e"
85
85
  }
package/src/Layout.tsx CHANGED
@@ -3,7 +3,7 @@ import { addons } from '@storybook/core/manager-api';
3
3
  import { type API_IndexHash, type Args, type StoryContext } from '@storybook/core/types';
4
4
  import type { ReactRenderer } from '@storybook/react';
5
5
  import { styled, useTheme } from '@storybook/react-native-theming';
6
- import { ReactNode, useRef, useState } from 'react';
6
+ import { ReactNode, useRef } from 'react';
7
7
  import { ScrollView, Text, View } from 'react-native';
8
8
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
9
9
  import { IconButton } from './IconButton';
@@ -13,9 +13,10 @@ import { MobileMenuDrawer, MobileMenuDrawerRef } from './MobileMenuDrawer';
13
13
  import { Sidebar } from './Sidebar';
14
14
  import { DEFAULT_REF_ID } from './constants';
15
15
  import { BottomBarToggleIcon } from './icon/BottomBarToggleIcon';
16
- import { DarkLogo } from './icon/DarkLogo';
17
- import { Logo } from './icon/Logo';
16
+
18
17
  import { MenuIcon } from './icon/MenuIcon';
18
+ import { StorybookLogo } from './StorybookLogo';
19
+ import { useStoreBooleanState } from './hooks/useStoreState';
19
20
 
20
21
  export const Layout = ({
21
22
  storyHash,
@@ -32,9 +33,15 @@ export const Layout = ({
32
33
  const insets = useSafeAreaInsets();
33
34
  const { isDesktop } = useLayout();
34
35
 
35
- const [desktopSidebarOpen, setDesktopSidebarOpen] = useState(true);
36
+ const [desktopSidebarOpen, setDesktopSidebarOpen] = useStoreBooleanState(
37
+ 'desktopSidebarState',
38
+ true
39
+ );
36
40
 
37
- const [desktopAddonsPanelOpen, setDesktopAddonsPanelOpen] = useState(true);
41
+ const [desktopAddonsPanelOpen, setDesktopAddonsPanelOpen] = useStoreBooleanState(
42
+ 'desktopPanelState',
43
+ true
44
+ );
38
45
 
39
46
  if (isDesktop) {
40
47
  return (
@@ -72,11 +79,7 @@ export const Layout = ({
72
79
  justifyContent: 'space-between',
73
80
  }}
74
81
  >
75
- {theme.base === 'light' ? (
76
- <Logo height={25} width={125} />
77
- ) : (
78
- <DarkLogo height={25} width={125} />
79
- )}
82
+ <StorybookLogo theme={theme} />
80
83
 
81
84
  <IconButton onPress={() => setDesktopSidebarOpen(false)} Icon={MenuIcon} />
82
85
  </View>
@@ -157,11 +160,7 @@ export const Layout = ({
157
160
 
158
161
  <MobileMenuDrawer ref={mobileMenuDrawerRef}>
159
162
  <View style={{ paddingLeft: 16, paddingTop: 4, paddingBottom: 4 }}>
160
- {theme.base === 'light' ? (
161
- <Logo height={25} width={125} />
162
- ) : (
163
- <DarkLogo height={25} width={125} />
164
- )}
163
+ <StorybookLogo theme={theme} />
165
164
  </View>
166
165
  <Sidebar
167
166
  extra={[]}
package/src/Sidebar.tsx CHANGED
@@ -10,7 +10,7 @@ import { Explorer } from './Explorer';
10
10
  import { Search } from './Search';
11
11
  import { SearchResults } from './SearchResults';
12
12
  import type { CombinedDataset, Selection } from './types';
13
- import { useLastViewed } from './useLastViewed';
13
+ import { useLastViewed } from './hooks/useLastViewed';
14
14
  import { DEFAULT_REF_ID } from './constants';
15
15
  import { View } from 'react-native';
16
16
 
@@ -0,0 +1,21 @@
1
+ import type { FC, PropsWithChildren } from 'react';
2
+ import { createContext, useContext } from 'react';
3
+
4
+ interface Storage {
5
+ getItem: (key: string) => Promise<string | null>;
6
+ setItem: (key: string, value: string) => Promise<void>;
7
+ }
8
+
9
+ const StorageContext = createContext<Storage>({
10
+ getItem: async () => null,
11
+ setItem: async () => {},
12
+ });
13
+
14
+ export const StorageProvider: FC<PropsWithChildren<{ storage: Storage }>> = ({
15
+ storage,
16
+ children,
17
+ }) => {
18
+ return <StorageContext.Provider value={storage}>{children}</StorageContext.Provider>;
19
+ };
20
+
21
+ export const useStorage = () => useContext(StorageContext);
@@ -0,0 +1,76 @@
1
+ import type { StoryObj, Meta } from '@storybook/react';
2
+ import { StorybookLogo } from './StorybookLogo';
3
+ import { Theme, theme } from '@storybook/react-native-theming';
4
+ import { Text } from 'react-native';
5
+
6
+ const meta = {
7
+ component: StorybookLogo,
8
+ title: 'UI/StorybookLogo',
9
+ args: {
10
+ theme: null,
11
+ },
12
+ } satisfies Meta<typeof StorybookLogo>;
13
+
14
+ export default meta;
15
+
16
+ type Story = StoryObj<typeof meta>;
17
+
18
+ export const TitleLogo: Story = {
19
+ args: {
20
+ theme: {
21
+ ...theme,
22
+ brand: { title: 'React Native' },
23
+ } satisfies Theme,
24
+ },
25
+ };
26
+
27
+ export const ImageLogo: Story = {
28
+ args: {
29
+ theme: {
30
+ ...theme,
31
+ brand: {
32
+ image: {
33
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/512px-React-icon.svg.png',
34
+ height: 25,
35
+ width: 25,
36
+ },
37
+ },
38
+ } satisfies Theme,
39
+ },
40
+ };
41
+
42
+ export const ImageUrlLogo: Story = {
43
+ args: {
44
+ theme: {
45
+ ...theme,
46
+ brand: {
47
+ image: {
48
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/512px-React-icon.svg.png',
49
+ width: 25,
50
+ height: 25,
51
+ },
52
+ title: 'React Native',
53
+ url: 'https://reactnative.dev',
54
+ },
55
+ } satisfies Theme,
56
+ },
57
+ };
58
+
59
+ export const ImageSourceLogo: Story = {
60
+ args: {
61
+ theme: {
62
+ ...theme,
63
+ brand: {
64
+ image: require('./assets/react-native-logo.png'),
65
+ resizeMode: 'contain',
66
+ url: 'https://reactnative.dev',
67
+ },
68
+ } satisfies Theme,
69
+ },
70
+ };
71
+
72
+ export const ImageElementLogo: Story = {
73
+ args: {
74
+ theme: { ...theme, brand: { image: <Text>Element</Text> } } satisfies Theme,
75
+ },
76
+ };
@@ -0,0 +1,106 @@
1
+ import { Theme } from '@storybook/react-native-theming';
2
+ import { FC, isValidElement, ReactElement, useEffect, useMemo } from 'react';
3
+ import { Image, Linking, StyleProp, Text, TextStyle, TouchableOpacity } from 'react-native';
4
+ import { DarkLogo } from './icon/DarkLogo';
5
+ import { Logo } from './icon/Logo';
6
+
7
+ const WIDTH = 125;
8
+ const HEIGHT = 25;
9
+
10
+ const NoBrandLogo: FC<{ theme: Theme }> = ({ theme }) =>
11
+ theme.base === 'light' ? (
12
+ <Logo height={HEIGHT} width={WIDTH} />
13
+ ) : (
14
+ <DarkLogo height={HEIGHT} width={WIDTH} />
15
+ );
16
+
17
+ function isElement(value: unknown): value is ReactElement {
18
+ return isValidElement(value);
19
+ }
20
+
21
+ const BrandLogo: FC<{ theme: Theme }> = ({ theme }) => {
22
+ const imageHasNoWidthOrHeight =
23
+ typeof theme.brand.image === 'object' &&
24
+ typeof theme.brand.image === 'object' &&
25
+ 'uri' in theme.brand.image &&
26
+ (!('height' in theme.brand.image) || !('width' in theme.brand.image));
27
+
28
+ useEffect(() => {
29
+ if (imageHasNoWidthOrHeight) {
30
+ console.warn(
31
+ "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}}"
32
+ );
33
+ }
34
+ }, [imageHasNoWidthOrHeight]);
35
+
36
+ if (!theme.brand.image) {
37
+ return null;
38
+ }
39
+
40
+ if (isElement(theme.brand.image)) {
41
+ return theme.brand.image;
42
+ }
43
+
44
+ const image = (
45
+ <Image
46
+ source={theme.brand.image}
47
+ resizeMode={theme.brand.resizeMode ?? 'contain'}
48
+ style={imageHasNoWidthOrHeight ? { width: WIDTH, height: HEIGHT } : undefined}
49
+ />
50
+ );
51
+
52
+ if (theme.brand.url) {
53
+ return (
54
+ <TouchableOpacity
55
+ onPress={() => {
56
+ if (theme.brand.url) Linking.openURL(theme.brand.url);
57
+ }}
58
+ >
59
+ {image}
60
+ </TouchableOpacity>
61
+ );
62
+ } else {
63
+ return image;
64
+ }
65
+ };
66
+
67
+ const BrandTitle: FC<{ theme: Theme }> = ({ theme }) => {
68
+ const brandTitleStyle = useMemo<StyleProp<TextStyle>>(() => {
69
+ return {
70
+ width: WIDTH,
71
+ height: HEIGHT,
72
+ color: theme.color.defaultText,
73
+ fontSize: theme.typography.size.m1,
74
+ };
75
+ }, [theme]);
76
+
77
+ const title = (
78
+ <Text style={brandTitleStyle} numberOfLines={1} ellipsizeMode="tail">
79
+ {theme.brand.title}
80
+ </Text>
81
+ );
82
+
83
+ if (theme.brand.url) {
84
+ return (
85
+ <TouchableOpacity
86
+ onPress={() => {
87
+ if (theme.brand.url) Linking.openURL(theme.brand.url);
88
+ }}
89
+ >
90
+ {title}
91
+ </TouchableOpacity>
92
+ );
93
+ } else {
94
+ return title;
95
+ }
96
+ };
97
+
98
+ export const StorybookLogo: FC<{ theme: Theme }> = ({ theme }) => {
99
+ if (theme.brand?.image) {
100
+ return <BrandLogo theme={theme} />;
101
+ } else if (theme.brand?.title) {
102
+ return <BrandTitle theme={theme} />;
103
+ } else {
104
+ return <NoBrandLogo theme={theme} />;
105
+ }
106
+ };
@@ -77,6 +77,7 @@ export const SingleStoryComponents: Story = {
77
77
  data={{
78
78
  ...{
79
79
  single: {
80
+ tags: [],
80
81
  type: 'component',
81
82
  name: 'Single',
82
83
  id: 'single',
package/src/Tree.tsx CHANGED
@@ -14,8 +14,8 @@ import { CollapseAllIcon } from './icon/CollapseAllIcon';
14
14
  import { CollapseIcon } from './icon/CollapseIcon';
15
15
  import { ExpandAllIcon } from './icon/ExpandAllIcon';
16
16
  import { Item } from './types';
17
- import type { ExpandAction, ExpandedState } from './useExpanded';
18
- import { useExpanded } from './useExpanded';
17
+ import type { ExpandAction, ExpandedState } from './hooks/useExpanded';
18
+ import { useExpanded } from './hooks/useExpanded';
19
19
  import { getGroupStatus, statusMapping } from './util/status';
20
20
  import { createId, getAncestorIds, getDescendantIds, isStoryHoistable } from './util/tree';
21
21
 
Binary file
@@ -1,7 +1,7 @@
1
1
  import type { StoriesHash } from '@storybook/core/manager-api';
2
2
  import type { Dispatch, Reducer } from 'react';
3
3
  import { useCallback, useEffect, useReducer } from 'react';
4
- import { getAncestorIds } from './util/tree';
4
+ import { getAncestorIds } from '../util/tree';
5
5
 
6
6
  export type ExpandedState = Record<string, boolean>;
7
7
 
@@ -2,7 +2,7 @@ import debounce from 'lodash/debounce.js';
2
2
  import { useCallback, useEffect, useMemo, useRef } from 'react';
3
3
  import store from 'store2';
4
4
 
5
- import type { Selection, StoryRef } from './types';
5
+ import type { Selection, StoryRef } from '../types';
6
6
 
7
7
  const save = debounce((value) => store.set('lastViewedStoryIds', value), 1000);
8
8
 
@@ -0,0 +1,27 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { useStorage } from '../StorageProvider';
3
+
4
+ export const useStoreBooleanState = (
5
+ key: string,
6
+ defaultValue: boolean
7
+ ): ReturnType<typeof useState<boolean>> => {
8
+ const storage = useStorage();
9
+
10
+ const [val, setVal] = useState<boolean>(defaultValue);
11
+
12
+ useEffect(() => {
13
+ storage.getItem(key).then((newVal) => {
14
+ if (newVal === null || newVal === undefined) {
15
+ setVal(defaultValue);
16
+ } else {
17
+ setVal(newVal === 'true');
18
+ }
19
+ });
20
+ }, [key, storage, defaultValue]);
21
+
22
+ useEffect(() => {
23
+ storage.setItem(key, val.toString());
24
+ }, [key, storage, val]);
25
+
26
+ return [val, setVal];
27
+ };
package/src/index.tsx CHANGED
@@ -8,3 +8,4 @@ export * from './Sidebar';
8
8
  export * from './types';
9
9
  export * from './Layout';
10
10
  export * from './util/StoryHash';
11
+ export * from './StorageProvider';