storybook 10.2.0-alpha.13 → 10.2.0-alpha.15

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.
Files changed (74) hide show
  1. package/dist/_browser-chunks/{chunk-3PJE6VLG.js → chunk-ASKQZAOS.js} +1 -12
  2. package/dist/_browser-chunks/{chunk-BGSDJMFM.js → chunk-NVLTWT3B.js} +18 -6
  3. package/dist/_node-chunks/{builder-manager-YTW4R3NB.js → builder-manager-SOKYB5NF.js} +12 -12
  4. package/dist/_node-chunks/{camelcase-ALOK3DTL.js → camelcase-SXQWF7PW.js} +7 -7
  5. package/dist/_node-chunks/{chunk-QV7LTTOW.js → chunk-274OMYGE.js} +20 -20
  6. package/dist/_node-chunks/{chunk-B3NH4IRY.js → chunk-2BHD5YKF.js} +6 -6
  7. package/dist/_node-chunks/{chunk-FCBELYHM.js → chunk-2FQAOAQ6.js} +12 -12
  8. package/dist/_node-chunks/{chunk-NGFKU3PK.js → chunk-45UIB4YF.js} +7 -7
  9. package/dist/_node-chunks/{chunk-TWCN75ID.js → chunk-4GKVZO2T.js} +9 -9
  10. package/dist/_node-chunks/{chunk-KXFFKIVX.js → chunk-5KEIALUH.js} +6 -6
  11. package/dist/_node-chunks/{chunk-AOMUVL33.js → chunk-6SIUW3HU.js} +12 -12
  12. package/dist/_node-chunks/{chunk-L4JVY7CQ.js → chunk-AIIQJ6UR.js} +7 -7
  13. package/dist/_node-chunks/{chunk-5CARBEGS.js → chunk-BOY3TNPC.js} +9 -9
  14. package/dist/_node-chunks/{chunk-TOLCEUYZ.js → chunk-BRW7NFUP.js} +7 -7
  15. package/dist/_node-chunks/{chunk-ZSUT22UW.js → chunk-E3Y5MHXD.js} +7 -7
  16. package/dist/_node-chunks/{chunk-QMDFRT4S.js → chunk-ENNDE4GC.js} +10 -10
  17. package/dist/_node-chunks/{chunk-NL75DTGM.js → chunk-FKBWQGIF.js} +6 -6
  18. package/dist/_node-chunks/{chunk-NRCGIPSW.js → chunk-HFKM7JHQ.js} +6 -6
  19. package/dist/_node-chunks/{chunk-OOTLIMKW.js → chunk-K4YVLJRS.js} +6 -6
  20. package/dist/_node-chunks/{chunk-WKDY7YZY.js → chunk-KNGN3UEO.js} +7 -7
  21. package/dist/_node-chunks/{chunk-AE6TGTGX.js → chunk-MD52RVZX.js} +7 -7
  22. package/dist/_node-chunks/chunk-MM7Z4SG7.js +23 -0
  23. package/dist/_node-chunks/{chunk-XX6B7MPS.js → chunk-MQZLLJRG.js} +8 -8
  24. package/dist/_node-chunks/{chunk-OWZXELHP.js → chunk-PI7P5HFH.js} +13 -13
  25. package/dist/_node-chunks/{chunk-VOVBTC53.js → chunk-Q6WUEJ4S.js} +6 -6
  26. package/dist/_node-chunks/{chunk-2VHYFREG.js → chunk-QPKBPYOY.js} +7 -7
  27. package/dist/_node-chunks/chunk-RGWB6DD7.js +20 -0
  28. package/dist/_node-chunks/{chunk-BIJENBOW.js → chunk-SZWIX5YC.js} +9 -9
  29. package/dist/_node-chunks/{chunk-X2PNK4N4.js → chunk-T57UCO67.js} +7 -7
  30. package/dist/_node-chunks/{chunk-5E6TIJW7.js → chunk-TN3Q52LO.js} +6 -6
  31. package/dist/_node-chunks/chunk-TYSSQECX.js +61 -0
  32. package/dist/_node-chunks/chunk-YP34ARUD.js +18 -0
  33. package/dist/_node-chunks/{globby-RG2TFVNI.js → globby-LGQ5P2JB.js} +9 -9
  34. package/dist/_node-chunks/{lib-E2AGGQV3.js → lib-5LBLULG3.js} +7 -7
  35. package/dist/_node-chunks/{mdx-N42X6CFJ-SGUMZ4YL.js → mdx-N42X6CFJ-TAPL5IEO.js} +8 -8
  36. package/dist/_node-chunks/{p-limit-J4UZO65T.js → p-limit-GTMOHYQF.js} +7 -7
  37. package/dist/babel/index.js +10 -10
  38. package/dist/bin/core.js +12 -12
  39. package/dist/bin/dispatcher.js +11 -11
  40. package/dist/bin/loader.js +9 -9
  41. package/dist/cli/index.d.ts +176 -176
  42. package/dist/cli/index.js +18 -18
  43. package/dist/common/index.js +19 -19
  44. package/dist/components/index.d.ts +1 -0
  45. package/dist/components/index.js +167 -166
  46. package/dist/core-events/index.d.ts +4 -4
  47. package/dist/core-server/index.d.ts +11 -1
  48. package/dist/core-server/index.js +217 -76
  49. package/dist/core-server/presets/common-manager.js +176 -134
  50. package/dist/core-server/presets/common-override-preset.js +9 -9
  51. package/dist/core-server/presets/common-preset.js +27 -26
  52. package/dist/csf/index.d.ts +8 -6
  53. package/dist/csf/index.js +1 -1
  54. package/dist/csf-tools/index.js +10 -10
  55. package/dist/docs-tools/index.d.ts +2 -2
  56. package/dist/manager/globals-runtime.js +97 -94
  57. package/dist/manager/runtime.js +1755 -985
  58. package/dist/manager-api/index.d.ts +1 -1
  59. package/dist/manager-api/index.js +10 -8
  60. package/dist/mocking-utils/index.js +8 -8
  61. package/dist/node-logger/index.js +9 -9
  62. package/dist/preview/runtime.js +18 -6
  63. package/dist/preview-api/index.js +1 -1
  64. package/dist/server-errors.js +11 -11
  65. package/dist/telemetry/index.js +22 -22
  66. package/dist/types/index.d.ts +12 -6
  67. package/dist/viewport/index.d.ts +5 -3
  68. package/dist/viewport/index.js +12 -3
  69. package/package.json +2 -2
  70. package/dist/_node-chunks/chunk-5U7IR6W2.js +0 -61
  71. package/dist/_node-chunks/chunk-JUCUYWH2.js +0 -23
  72. package/dist/_node-chunks/chunk-KTAHXSER.js +0 -18
  73. package/dist/_node-chunks/chunk-XQU357NR.js +0 -20
  74. package/dist/_node-chunks/dist-I4XBT6AL.js +0 -121
@@ -2226,62 +2226,6 @@ var F = ["children"], G = ["children"], W = (function(e2) {
2226
2226
  })(Component);
2227
2227
  W.propTypes = { base: import_prop_types.default.object, bodyAttributes: import_prop_types.default.object, children: import_prop_types.default.oneOfType([import_prop_types.default.arrayOf(import_prop_types.default.node), import_prop_types.default.node]), defaultTitle: import_prop_types.default.string, defer: import_prop_types.default.bool, encodeSpecialCharacters: import_prop_types.default.bool, htmlAttributes: import_prop_types.default.object, link: import_prop_types.default.arrayOf(import_prop_types.default.object), meta: import_prop_types.default.arrayOf(import_prop_types.default.object), noscript: import_prop_types.default.arrayOf(import_prop_types.default.object), onChangeClientState: import_prop_types.default.func, script: import_prop_types.default.arrayOf(import_prop_types.default.object), style: import_prop_types.default.arrayOf(import_prop_types.default.object), title: import_prop_types.default.string, titleAttributes: import_prop_types.default.object, titleTemplate: import_prop_types.default.string, prioritizeSeoTags: import_prop_types.default.bool, helmetData: import_prop_types.default.object }, W.defaultProps = { defer: !0, encodeSpecialCharacters: !0, prioritizeSeoTags: !1 }, W.displayName = "Helmet";
2228
2228
 
2229
- // src/manager/constants.ts
2230
- var MEDIA_DESKTOP_BREAKPOINT = "@media (min-width: 600px)";
2231
-
2232
- // src/manager/hooks/useMedia.tsx
2233
- function useMediaQuery(query) {
2234
- let getMatches = (queryMatch) => typeof window < "u" ? window.matchMedia(queryMatch).matches : !1, [matches, setMatches] = useState(getMatches(query));
2235
- function handleChange() {
2236
- setMatches(getMatches(query));
2237
- }
2238
- return useEffect(() => {
2239
- let matchMedia = window.matchMedia(query);
2240
- return handleChange(), matchMedia.addEventListener("change", handleChange), () => {
2241
- matchMedia.removeEventListener("change", handleChange);
2242
- };
2243
- }, [query]), matches;
2244
- }
2245
-
2246
- // src/manager/components/layout/LayoutProvider.tsx
2247
- var LayoutContext = createContext({
2248
- isMobileMenuOpen: !1,
2249
- setMobileMenuOpen: () => {
2250
- },
2251
- isMobileAboutOpen: !1,
2252
- setMobileAboutOpen: () => {
2253
- },
2254
- isMobilePanelOpen: !1,
2255
- setMobilePanelOpen: () => {
2256
- },
2257
- isDesktop: !1,
2258
- isMobile: !1
2259
- }), LayoutProvider = ({ children, forceDesktop }) => {
2260
- let [isMobileMenuOpen, setMobileMenuOpen] = useState(!1), [isMobileAboutOpen, setMobileAboutOpen] = useState(!1), [isMobilePanelOpen, setMobilePanelOpen] = useState(!1), isDesktop = forceDesktop ?? useMediaQuery(`(min-width: ${600}px)`), isMobile2 = !isDesktop, contextValue = useMemo(
2261
- () => ({
2262
- isMobileMenuOpen,
2263
- setMobileMenuOpen,
2264
- isMobileAboutOpen,
2265
- setMobileAboutOpen,
2266
- isMobilePanelOpen,
2267
- setMobilePanelOpen,
2268
- isDesktop,
2269
- isMobile: isMobile2
2270
- }),
2271
- [
2272
- isMobileMenuOpen,
2273
- setMobileMenuOpen,
2274
- isMobileAboutOpen,
2275
- setMobileAboutOpen,
2276
- isMobilePanelOpen,
2277
- setMobilePanelOpen,
2278
- isDesktop,
2279
- isMobile2
2280
- ]
2281
- );
2282
- return react_default.createElement(LayoutContext.Provider, { value: contextValue }, children);
2283
- }, useLayout = () => useContext(LayoutContext);
2284
-
2285
2229
  // ../../node_modules/@babel/runtime/helpers/esm/extends.js
2286
2230
  function _extends() {
2287
2231
  return _extends = Object.assign ? Object.assign.bind() : function(n3) {
@@ -2356,19 +2300,19 @@ function _wrapNativeSuper(t2) {
2356
2300
  if (typeof t3 != "function") throw new TypeError("Super expression must either be null or a function");
2357
2301
  if (r3 !== void 0) {
2358
2302
  if (r3.has(t3)) return r3.get(t3);
2359
- r3.set(t3, Wrapper6);
2303
+ r3.set(t3, Wrapper8);
2360
2304
  }
2361
- function Wrapper6() {
2305
+ function Wrapper8() {
2362
2306
  return _construct(t3, arguments, _getPrototypeOf(this).constructor);
2363
2307
  }
2364
- return Wrapper6.prototype = Object.create(t3.prototype, {
2308
+ return Wrapper8.prototype = Object.create(t3.prototype, {
2365
2309
  constructor: {
2366
- value: Wrapper6,
2310
+ value: Wrapper8,
2367
2311
  enumerable: !1,
2368
2312
  writable: !0,
2369
2313
  configurable: !0
2370
2314
  }
2371
- }), _setPrototypeOf(Wrapper6, t3);
2315
+ }), _setPrototypeOf(Wrapper8, t3);
2372
2316
  }, _wrapNativeSuper(t2);
2373
2317
  }
2374
2318
 
@@ -2878,6 +2822,180 @@ function transparentize(amount, color2) {
2878
2822
  }
2879
2823
  var curriedTransparentize = curry(transparentize), curriedTransparentize$1 = curriedTransparentize;
2880
2824
 
2825
+ // src/manager/components/error-boundary/ManagerErrorBoundary.tsx
2826
+ var Container = styled.div(({ theme }) => ({
2827
+ display: "flex",
2828
+ justifyContent: "center",
2829
+ alignItems: "center",
2830
+ width: "100vw",
2831
+ height: "100vh",
2832
+ backgroundColor: theme.background.app,
2833
+ color: theme.color.defaultText,
2834
+ fontFamily: theme.typography.fonts.base
2835
+ })), Content = styled.div(({ theme }) => ({
2836
+ display: "flex",
2837
+ flexDirection: "column",
2838
+ justifyContent: "space-between",
2839
+ width: "80%",
2840
+ height: "80%",
2841
+ padding: 20,
2842
+ gap: 20,
2843
+ backgroundColor: theme.background.content,
2844
+ borderRadius: theme.appBorderRadius,
2845
+ border: `1px solid ${theme.color.negative}`,
2846
+ boxShadow: "0 0 64px rgba(0, 0, 0, 0.1)",
2847
+ overflow: "auto"
2848
+ })), Info = styled.div(({ theme }) => ({
2849
+ display: "flex",
2850
+ flexDirection: "column",
2851
+ alignItems: "start",
2852
+ gap: 15
2853
+ })), Heading = styled.h1(({ theme }) => ({
2854
+ display: "flex",
2855
+ alignItems: "center",
2856
+ margin: 0,
2857
+ gap: 10,
2858
+ fontSize: theme.typography.size.s2,
2859
+ fontWeight: theme.typography.weight.bold,
2860
+ color: theme.color.defaultText
2861
+ })), SubHeading = styled.p(({ theme }) => ({
2862
+ fontSize: theme.typography.size.s2,
2863
+ color: theme.textMutedColor,
2864
+ margin: 0,
2865
+ lineHeight: 1.4,
2866
+ textWrap: "balance"
2867
+ })), ErrorWrapper = styled.div(({ theme }) => ({
2868
+ display: "flex",
2869
+ flexDirection: "column-reverse",
2870
+ width: "100%",
2871
+ flex: "0 0 auto",
2872
+ border: `1px solid ${theme.appBorderColor}`,
2873
+ borderRadius: theme.appBorderRadius,
2874
+ pre: {
2875
+ borderRadius: 0
2876
+ }
2877
+ })), CollapseToggle = styled.div(({ theme }) => ({
2878
+ flex: "0 0 auto",
2879
+ display: "flex",
2880
+ alignItems: "center",
2881
+ gap: 10,
2882
+ height: 40,
2883
+ width: "100%",
2884
+ padding: "0 10px",
2885
+ cursor: "pointer",
2886
+ fontSize: theme.typography.size.s2,
2887
+ fontWeight: theme.typography.weight.bold,
2888
+ color: theme.color.defaultText,
2889
+ userSelect: "none",
2890
+ "&:hover": {
2891
+ backgroundColor: theme.base === "light" ? "rgba(0, 0, 0, 0.02)" : "rgba(255, 255, 255, 0.03)"
2892
+ },
2893
+ svg: {
2894
+ color: theme.textMutedColor
2895
+ }
2896
+ })), ErrorMessage = styled.pre(({ theme }) => ({
2897
+ order: 1,
2898
+ padding: "11px 15px",
2899
+ margin: 0,
2900
+ fontSize: theme.typography.size.s1,
2901
+ color: theme.color.negativeText,
2902
+ backgroundColor: curriedTransparentize$1(theme.base === "light" ? 0.95 : 0.9, theme.color.negative),
2903
+ borderBottom: `1px solid ${theme.appBorderColor}`,
2904
+ whiteSpace: "pre-wrap",
2905
+ wordBreak: "break-word",
2906
+ fontFamily: theme.typography.fonts.mono,
2907
+ lineHeight: "18px"
2908
+ })), ErrorStack = styled.pre(({ theme }) => ({
2909
+ padding: 15,
2910
+ margin: 0,
2911
+ fontSize: theme.typography.size.s1,
2912
+ color: theme.textMutedColor,
2913
+ borderBottom: `1px solid ${theme.appBorderColor}`,
2914
+ borderRadius: 0,
2915
+ whiteSpace: "pre-wrap",
2916
+ wordBreak: "break-word",
2917
+ fontFamily: theme.typography.fonts.mono
2918
+ })), ErrorFallback = ({ error, errorInfo }) => react_default.createElement(Container, { "data-testid": "manager-error-boundary" }, react_default.createElement(Content, null, react_default.createElement(Info, null, react_default.createElement(Heading, null, react_default.createElement(Badge, { status: "negative" }, "Error"), react_default.createElement("span", null, "Something went wrong")), react_default.createElement(SubHeading, null, "The Storybook Manager UI encountered an error. This is usually caused by custom addon code or configuration. Please check your browser console for more details. Try clearing browser storage if the issue persists."), react_default.createElement(Button, { asChild: !0, size: "medium" }, react_default.createElement("a", { href: window.location.origin + window.location.pathname.replace("iframe.html", "") }, react_default.createElement(SyncIcon, { size: 14 }), "Reload Storybook"))), react_default.createElement(ErrorWrapper, null, react_default.createElement(ErrorMessage, null, error.message || "Unknown error"), react_default.createElement(
2919
+ Collapsible,
2920
+ {
2921
+ collapsed: !0,
2922
+ summary: ({ isCollapsed, toggleCollapsed }) => react_default.createElement(CollapseToggle, { onClick: toggleCollapsed }, react_default.createElement(UnfoldIcon, null), isCollapsed ? "Expand error" : "Collapse error")
2923
+ },
2924
+ (error.stack || errorInfo?.componentStack) && react_default.createElement(ErrorStack, null, error.stack, errorInfo?.componentStack && `
2925
+
2926
+ Component Stack:${errorInfo.componentStack}`)
2927
+ )))), ManagerErrorBoundary = class extends Component {
2928
+ constructor(props) {
2929
+ super(props), this.state = { hasError: !1, error: null, errorInfo: null };
2930
+ }
2931
+ static getDerivedStateFromError(error) {
2932
+ return { hasError: !0, error };
2933
+ }
2934
+ componentDidCatch(error, errorInfo) {
2935
+ console.error("Storybook Manager UI Error:", error), console.error("Component Stack:", errorInfo.componentStack), this.setState({ errorInfo });
2936
+ }
2937
+ render() {
2938
+ let { hasError, error, errorInfo } = this.state, { children } = this.props;
2939
+ return hasError && error ? react_default.createElement(ErrorFallback, { error, errorInfo }) : children;
2940
+ }
2941
+ };
2942
+
2943
+ // src/manager/constants.ts
2944
+ var MEDIA_DESKTOP_BREAKPOINT = "@media (min-width: 600px)";
2945
+
2946
+ // src/manager/hooks/useMedia.tsx
2947
+ function useMediaQuery(query) {
2948
+ let getMatches = (queryMatch) => typeof window < "u" ? window.matchMedia(queryMatch).matches : !1, [matches, setMatches] = useState(getMatches(query));
2949
+ function handleChange() {
2950
+ setMatches(getMatches(query));
2951
+ }
2952
+ return useEffect(() => {
2953
+ let matchMedia = window.matchMedia(query);
2954
+ return handleChange(), matchMedia.addEventListener("change", handleChange), () => {
2955
+ matchMedia.removeEventListener("change", handleChange);
2956
+ };
2957
+ }, [query]), matches;
2958
+ }
2959
+
2960
+ // src/manager/components/layout/LayoutProvider.tsx
2961
+ var LayoutContext = createContext({
2962
+ isMobileMenuOpen: !1,
2963
+ setMobileMenuOpen: () => {
2964
+ },
2965
+ isMobileAboutOpen: !1,
2966
+ setMobileAboutOpen: () => {
2967
+ },
2968
+ isMobilePanelOpen: !1,
2969
+ setMobilePanelOpen: () => {
2970
+ },
2971
+ isDesktop: !1,
2972
+ isMobile: !1
2973
+ }), LayoutProvider = ({ children, forceDesktop }) => {
2974
+ let [isMobileMenuOpen, setMobileMenuOpen] = useState(!1), [isMobileAboutOpen, setMobileAboutOpen] = useState(!1), [isMobilePanelOpen, setMobilePanelOpen] = useState(!1), isDesktop = forceDesktop ?? useMediaQuery(`(min-width: ${600}px)`), isMobile2 = !isDesktop, contextValue = useMemo(
2975
+ () => ({
2976
+ isMobileMenuOpen,
2977
+ setMobileMenuOpen,
2978
+ isMobileAboutOpen,
2979
+ setMobileAboutOpen,
2980
+ isMobilePanelOpen,
2981
+ setMobilePanelOpen,
2982
+ isDesktop,
2983
+ isMobile: isMobile2
2984
+ }),
2985
+ [
2986
+ isMobileMenuOpen,
2987
+ setMobileMenuOpen,
2988
+ isMobileAboutOpen,
2989
+ setMobileAboutOpen,
2990
+ isMobilePanelOpen,
2991
+ setMobilePanelOpen,
2992
+ isDesktop,
2993
+ isMobile2
2994
+ ]
2995
+ );
2996
+ return react_default.createElement(LayoutContext.Provider, { value: contextValue }, children);
2997
+ }, useLayout = () => useContext(LayoutContext);
2998
+
2881
2999
  // src/manager/components/notifications/NotificationItem.tsx
2882
3000
  var slideIn = keyframes({
2883
3001
  "0%": {
@@ -3310,17 +3428,13 @@ $b4b717babfbb907b$var$focusableElements.push('[tabindex]:not([tabindex="-1"]):no
3310
3428
  var $b4b717babfbb907b$var$TABBABLE_ELEMENT_SELECTOR = $b4b717babfbb907b$var$focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
3311
3429
 
3312
3430
  // src/manager/components/mobile/navigation/MobileAddonsDrawer.tsx
3313
- var StyledModal = styled(Modal)(({ theme }) => ({
3314
- background: theme.background.content,
3315
- borderRadius: "10px 10px 0 0",
3316
- border: "none"
3317
- })), MobileAddonsDrawer = ({
3431
+ var MobileAddonsDrawer = ({
3318
3432
  children,
3319
3433
  id,
3320
3434
  isOpen,
3321
3435
  onOpenChange
3322
3436
  }) => react_default.createElement(
3323
- StyledModal,
3437
+ Modal,
3324
3438
  {
3325
3439
  ariaLabel: "Addon panel",
3326
3440
  transitionDuration: 300,
@@ -3466,8 +3580,8 @@ var updateState2 = (key, status, setStateMap, latestStateMap, timeoutId, onChang
3466
3580
  // src/manager/components/upgrade/UpgradeBlock.tsx
3467
3581
  var UpgradeBlock = ({ onNavigateToWhatsNew }) => {
3468
3582
  let api = useStorybookApi(), [activeTab, setActiveTab] = useState("npm");
3469
- return react_default.createElement(Container, null, react_default.createElement("strong", null, "You are on Storybook ", api.getCurrentVersion().version), react_default.createElement("p", null, "Run the following script to check for updates and upgrade to the latest version."), react_default.createElement(Tabs2, null, react_default.createElement(ButtonTab, { active: activeTab === "npm", onClick: () => setActiveTab("npm") }, "npm"), react_default.createElement(ButtonTab, { active: activeTab === "yarn", onClick: () => setActiveTab("yarn") }, "yarn"), react_default.createElement(ButtonTab, { active: activeTab === "pnpm", onClick: () => setActiveTab("pnpm") }, "pnpm")), react_default.createElement(Code2, null, activeTab === "npm" ? "npx storybook@latest upgrade" : `${activeTab} dlx storybook@latest upgrade`), onNavigateToWhatsNew && react_default.createElement(Link, { onClick: onNavigateToWhatsNew }, "See what's new in Storybook"));
3470
- }, Container = styled.div(({ theme }) => ({
3583
+ return react_default.createElement(Container2, null, react_default.createElement("strong", null, "You are on Storybook ", api.getCurrentVersion().version), react_default.createElement("p", null, "Run the following script to check for updates and upgrade to the latest version."), react_default.createElement(Tabs2, null, react_default.createElement(ButtonTab, { active: activeTab === "npm", onClick: () => setActiveTab("npm") }, "npm"), react_default.createElement(ButtonTab, { active: activeTab === "yarn", onClick: () => setActiveTab("yarn") }, "yarn"), react_default.createElement(ButtonTab, { active: activeTab === "pnpm", onClick: () => setActiveTab("pnpm") }, "pnpm")), react_default.createElement(Code2, null, activeTab === "npm" ? "npx storybook@latest upgrade" : `${activeTab} dlx storybook@latest upgrade`), onNavigateToWhatsNew && react_default.createElement(Link, { onClick: onNavigateToWhatsNew }, "See what's new in Storybook"));
3584
+ }, Container2 = styled.div(({ theme }) => ({
3471
3585
  border: "1px solid",
3472
3586
  borderRadius: 5,
3473
3587
  padding: 20,
@@ -3508,7 +3622,7 @@ var MobileAbout = () => {
3508
3622
  return useEffect(() => {
3509
3623
  toggle(isMobileAboutOpen);
3510
3624
  }, [isMobileAboutOpen, toggle]), state.isMounted ? react_default.createElement(
3511
- Container2,
3625
+ Container3,
3512
3626
  {
3513
3627
  ref: aboutRef,
3514
3628
  $status: state.status,
@@ -3569,11 +3683,12 @@ var MobileAbout = () => {
3569
3683
  opacity: 0,
3570
3684
  transform: "translate(20px, 0)"
3571
3685
  }
3572
- }), Container2 = styled.div(
3686
+ }), Container3 = styled.div(
3573
3687
  ({ theme, $status, $transitionDuration }) => ({
3574
3688
  position: "absolute",
3575
3689
  width: "100%",
3576
3690
  height: "100%",
3691
+ borderRadius: "10px 10px 0 0",
3577
3692
  top: 0,
3578
3693
  left: 0,
3579
3694
  zIndex: 11,
@@ -3613,17 +3728,13 @@ var MobileAbout = () => {
3613
3728
  });
3614
3729
 
3615
3730
  // src/manager/components/mobile/navigation/MobileMenuDrawer.tsx
3616
- var StyledModal2 = styled(Modal)(({ theme }) => ({
3617
- background: theme.background.content,
3618
- borderRadius: "10px 10px 0 0",
3619
- border: "none"
3620
- })), MobileMenuDrawer = ({
3731
+ var MobileMenuDrawer = ({
3621
3732
  children,
3622
3733
  id,
3623
3734
  isOpen,
3624
3735
  onOpenChange
3625
3736
  }) => react_default.createElement(
3626
- StyledModal2,
3737
+ Modal,
3627
3738
  {
3628
3739
  ariaLabel: "Menu",
3629
3740
  transitionDuration: 300,
@@ -3659,7 +3770,7 @@ var useFullStoryName = () => {
3659
3770
  ...props
3660
3771
  }) => {
3661
3772
  let { isMobileMenuOpen, isMobilePanelOpen, setMobileMenuOpen, setMobilePanelOpen } = useLayout(), fullStoryName = useFullStoryName(), headingId = $bdb11010cef70236$export$f680877a34711e37();
3662
- return react_default.createElement(Container3, { ...props }, react_default.createElement(
3773
+ return react_default.createElement(Container4, { ...props }, react_default.createElement(
3663
3774
  MobileMenuDrawer,
3664
3775
  {
3665
3776
  id: "storybook-mobile-menu",
@@ -3699,7 +3810,7 @@ var useFullStoryName = () => {
3699
3810
  },
3700
3811
  react_default.createElement(BottomBarToggleIcon, null)
3701
3812
  )));
3702
- }, Container3 = styled.div(({ theme }) => ({
3813
+ }, Container4 = styled.div(({ theme }) => ({
3703
3814
  bottom: 0,
3704
3815
  left: 0,
3705
3816
  width: "100%",
@@ -3753,7 +3864,7 @@ function useDragging({
3753
3864
  }) {
3754
3865
  let panelResizerRef = useRef(null), sidebarResizerRef = useRef(null);
3755
3866
  return useEffect(() => {
3756
- let panelResizer = panelResizerRef.current, sidebarResizer = sidebarResizerRef.current, previewIframe = document.querySelector("#storybook-preview-wrapper"), draggedElement = null, onDragStart = (e2) => {
3867
+ let panelResizer = panelResizerRef.current, sidebarResizer = sidebarResizerRef.current, previewIframe = document.querySelector("#storybook-preview-iframe"), draggedElement = null, onDragStart = (e2) => {
3757
3868
  e2.preventDefault(), setState((state) => ({
3758
3869
  ...state,
3759
3870
  isDragging: !0
@@ -4233,6 +4344,183 @@ var Panel = (props) => {
4233
4344
  // src/manager/container/Preview.tsx
4234
4345
  var import_memoizerific = __toESM(require_memoizerific(), 1);
4235
4346
 
4347
+ // src/viewport/constants.ts
4348
+ var ADDON_ID = "storybook/viewport", PARAM_KEY = "viewport", PANEL_ID = `${ADDON_ID}/panel`, TOOL_ID = `${ADDON_ID}/tool`;
4349
+
4350
+ // src/viewport/defaults.ts
4351
+ var MINIMAL_VIEWPORTS = {
4352
+ mobile1: {
4353
+ name: "Small mobile",
4354
+ styles: {
4355
+ height: "568px",
4356
+ width: "320px"
4357
+ },
4358
+ type: "mobile"
4359
+ },
4360
+ mobile2: {
4361
+ name: "Large mobile",
4362
+ styles: {
4363
+ height: "896px",
4364
+ width: "414px"
4365
+ },
4366
+ type: "mobile"
4367
+ },
4368
+ tablet: {
4369
+ name: "Tablet",
4370
+ styles: {
4371
+ height: "1112px",
4372
+ width: "834px"
4373
+ },
4374
+ type: "tablet"
4375
+ },
4376
+ desktop: {
4377
+ name: "Desktop",
4378
+ styles: {
4379
+ height: "1024px",
4380
+ width: "1280px"
4381
+ },
4382
+ type: "desktop"
4383
+ }
4384
+ };
4385
+
4386
+ // src/viewport/useViewport.ts
4387
+ var URL_VALUE_PATTERN = /^([0-9]{1,4})([a-z]{0,4})-([0-9]{1,4})([a-z]{0,4})$/, VIEWPORT_MIN_WIDTH = 40, VIEWPORT_MIN_HEIGHT = 40, cycle = (viewports, current, direction = 1) => {
4388
+ let keys = Object.keys(viewports), nextIndex = (current ? keys.indexOf(current) : -1) + direction;
4389
+ return nextIndex < 0 ? keys[keys.length - 1] : nextIndex >= keys.length ? keys[0] : keys[nextIndex];
4390
+ }, normalizeGlobal = (value, defaultIsRotated) => typeof value == "string" ? { value, isRotated: defaultIsRotated } : { value: value?.value, isRotated: value?.isRotated ?? defaultIsRotated }, parseGlobals = (globals, storyGlobals, userGlobals, options2, lastSelectedOption, disable, viewMode) => {
4391
+ if (viewMode !== "story")
4392
+ return {
4393
+ name: "Responsive",
4394
+ type: "desktop",
4395
+ width: "100%",
4396
+ height: "100%",
4397
+ value: "100pct-100pct",
4398
+ option: void 0,
4399
+ isCustom: !1,
4400
+ isDefault: !0,
4401
+ isLocked: !0,
4402
+ isRotated: !1
4403
+ };
4404
+ let global2 = normalizeGlobal(globals?.[PARAM_KEY]), userGlobal = normalizeGlobal(userGlobals?.[PARAM_KEY]), storyGlobal = normalizeGlobal(storyGlobals?.[PARAM_KEY]), value = userGlobal?.value ?? storyGlobal?.value ?? global2?.value, isRotated = userGlobal?.isRotated ?? storyGlobal?.isRotated ?? global2?.isRotated ?? !1, keys = Object.keys(options2), isLocked = disable || PARAM_KEY in storyGlobals || !keys.length, [match, vx, ux, vy, uy] = value?.match(URL_VALUE_PATTERN) || [];
4405
+ if (match) {
4406
+ let x2 = ux && ux !== "px" ? vx : Math.max(Number(vx), VIEWPORT_MIN_WIDTH), y2 = uy && uy !== "px" ? vy : Math.max(Number(vy), VIEWPORT_MIN_HEIGHT), width = `${x2}${ux === "pct" ? "%" : ux || "px"}`, height = `${y2}${uy === "pct" ? "%" : uy || "px"}`, selection = lastSelectedOption ? options2[lastSelectedOption] : void 0;
4407
+ return {
4408
+ name: selection?.name ?? "Custom",
4409
+ type: selection?.type ?? "other",
4410
+ width: isRotated ? height : width,
4411
+ height: isRotated ? width : height,
4412
+ value: match,
4413
+ option: void 0,
4414
+ isCustom: !0,
4415
+ isDefault: !1,
4416
+ isLocked,
4417
+ isRotated
4418
+ };
4419
+ }
4420
+ if (value && keys.length) {
4421
+ let { name, styles: styles2, type = "other" } = options2[value] ?? options2[keys[0]];
4422
+ return {
4423
+ name,
4424
+ type,
4425
+ width: isRotated ? styles2.height : styles2.width,
4426
+ height: isRotated ? styles2.width : styles2.height,
4427
+ value,
4428
+ option: value,
4429
+ isCustom: !1,
4430
+ isDefault: !1,
4431
+ isLocked,
4432
+ isRotated
4433
+ };
4434
+ }
4435
+ return {
4436
+ name: "Responsive",
4437
+ type: "desktop",
4438
+ width: "100%",
4439
+ height: "100%",
4440
+ value: "100pct-100pct",
4441
+ option: void 0,
4442
+ isCustom: !1,
4443
+ isDefault: !0,
4444
+ isLocked,
4445
+ isRotated: !1
4446
+ };
4447
+ }, useViewport = () => {
4448
+ let api = useStorybookApi(), { viewMode } = api.getUrlState(), lastSelectedOption = useRef(), parameter = useParameter(PARAM_KEY), [globals, updateGlobals, storyGlobals, userGlobals] = useGlobals(), { options: options2 = MINIMAL_VIEWPORTS, disable = !1 } = parameter || {}, { name, type, width, height, value, option, isCustom, isDefault, isLocked, isRotated } = parseGlobals(
4449
+ globals,
4450
+ storyGlobals,
4451
+ userGlobals,
4452
+ options2,
4453
+ lastSelectedOption.current,
4454
+ disable,
4455
+ viewMode
4456
+ ), update2 = useCallback(
4457
+ (input) => updateGlobals({ [PARAM_KEY]: input }),
4458
+ [updateGlobals]
4459
+ ), resize = useCallback(
4460
+ (width2, height2) => {
4461
+ let w2 = width2.replace(/px$/, "").replace(/%$/, "pct"), h2 = height2.replace(/px$/, "").replace(/%$/, "pct"), value2 = isRotated ? `${h2}-${w2}` : `${w2}-${h2}`, [match, vx, ux, vy, uy] = value2.match(URL_VALUE_PATTERN) || [];
4462
+ match && (ux || Number(vx) >= 40) && (uy || Number(vy) >= 40) && update2({ value: match, isRotated });
4463
+ },
4464
+ [update2, isRotated]
4465
+ );
4466
+ return useEffect(() => {
4467
+ PARAM_KEY in storyGlobals && (update2(normalizeGlobal(storyGlobals?.[PARAM_KEY], !1)), lastSelectedOption.current = void 0);
4468
+ }, [storyGlobals, update2]), useEffect(() => {
4469
+ option && (Object.hasOwn(options2, option) ? lastSelectedOption.current = option : (lastSelectedOption.current = void 0, update2(normalizeGlobal(storyGlobals?.[PARAM_KEY], !1))));
4470
+ }, [storyGlobals, options2, option, update2]), useEffect(() => {
4471
+ api.setAddonShortcut(ADDON_ID, {
4472
+ label: "Next viewport",
4473
+ defaultShortcut: ["alt", "V"],
4474
+ actionName: "next",
4475
+ action: () => update2({ value: cycle(options2, lastSelectedOption.current), isRotated })
4476
+ }), api.setAddonShortcut(ADDON_ID, {
4477
+ label: "Previous viewport",
4478
+ defaultShortcut: ["alt", "shift", "V"],
4479
+ actionName: "previous",
4480
+ action: () => update2({ value: cycle(options2, lastSelectedOption.current, -1), isRotated })
4481
+ }), api.setAddonShortcut(ADDON_ID, {
4482
+ label: "Reset viewport",
4483
+ defaultShortcut: ["alt", "control", "V"],
4484
+ actionName: "reset",
4485
+ action: () => update2({ value: void 0, isRotated: !1 })
4486
+ });
4487
+ }, [api, update2, options2, isRotated]), useMemo(
4488
+ () => ({
4489
+ name,
4490
+ type,
4491
+ width,
4492
+ height,
4493
+ value,
4494
+ option,
4495
+ isCustom,
4496
+ isDefault,
4497
+ isLocked,
4498
+ isRotated,
4499
+ options: options2,
4500
+ lastSelectedOption: lastSelectedOption.current,
4501
+ resize,
4502
+ reset: () => update2({ value: void 0, isRotated: !1 }),
4503
+ rotate: () => update2({ value, isRotated: !isRotated }),
4504
+ select: (value2) => update2({ value: value2, isRotated })
4505
+ }),
4506
+ [
4507
+ name,
4508
+ type,
4509
+ width,
4510
+ height,
4511
+ value,
4512
+ option,
4513
+ isCustom,
4514
+ isDefault,
4515
+ isRotated,
4516
+ isLocked,
4517
+ options2,
4518
+ resize,
4519
+ update2
4520
+ ]
4521
+ );
4522
+ };
4523
+
4236
4524
  // src/manager/components/preview/Iframe.tsx
4237
4525
  var StyledIframe = styled.iframe(({ theme }) => ({
4238
4526
  backgroundColor: theme.background.preview,
@@ -4240,11 +4528,10 @@ var StyledIframe = styled.iframe(({ theme }) => ({
4240
4528
  boxSizing: "content-box",
4241
4529
  height: "100%",
4242
4530
  width: "100%",
4243
- border: "0 none",
4531
+ border: "none",
4244
4532
  transition: "background-position 0s, visibility 0s",
4245
4533
  backgroundPosition: "-1px -1px, -1px -1px, -1px -1px, -1px -1px",
4246
- margin: "auto",
4247
- boxShadow: "0 0 100px 100vw rgba(0,0,0,0.5)"
4534
+ margin: "auto"
4248
4535
  }));
4249
4536
  function IFrame(props) {
4250
4537
  let { active, id, title: title2, src, allowFullScreen, scale, ...rest2 } = props, iFrameRef = react_default.useRef(null);
@@ -4264,38 +4551,422 @@ function IFrame(props) {
4264
4551
  ));
4265
4552
  }
4266
4553
 
4267
- // src/manager/components/preview/FramesRenderer.tsx
4268
- var getActive = (refId, refs) => refId && refs[refId] ? `storybook-ref-${refId}` : "storybook-preview-iframe", SkipToSidebarLink = styled(Button)(({ theme }) => ({
4269
- display: "none",
4270
- "@media (min-width: 600px)": {
4271
- position: "absolute",
4272
- display: "block",
4273
- top: 10,
4274
- right: 15,
4275
- padding: "10px 15px",
4554
+ // src/manager/components/preview/NumericInput.tsx
4555
+ var Wrapper = styled.div(
4556
+ ({ after: after2, before: before2, theme }) => ({
4557
+ position: "relative",
4558
+ display: "flex",
4559
+ alignItems: "center",
4560
+ width: "100%",
4561
+ height: 32,
4562
+ paddingInline: 9,
4276
4563
  fontSize: theme.typography.size.s1,
4277
- transform: "translateY(-100px)",
4278
- "&:focus": {
4279
- transform: "translateY(0)",
4280
- zIndex: 1
4281
- }
4282
- }
4283
- })), whenSidebarIsVisible = ({ api, state }) => ({
4284
- isFullscreen: api.getIsFullscreen(),
4285
- isNavShown: api.getIsNavShown(),
4286
- selectedStoryId: state.storyId
4287
- }), styles = {
4288
- '#root [data-is-storybook="false"]': {
4289
- display: "none"
4290
- },
4291
- '#root [data-is-storybook="true"]': {
4292
- display: "block"
4293
- }
4294
- }, FramesRenderer = ({
4295
- api,
4296
- refs,
4297
- scale,
4298
- viewMode = "story",
4564
+ color: theme.textMutedColor,
4565
+ background: theme.input.background,
4566
+ boxShadow: `${theme.input.border} 0 0 0 1px inset`,
4567
+ borderRadius: theme.input.borderRadius,
4568
+ svg: {
4569
+ display: "block"
4570
+ },
4571
+ input: {
4572
+ width: "100%",
4573
+ height: "100%",
4574
+ minHeight: "100%",
4575
+ flex: "1 1 auto",
4576
+ paddingInline: 0,
4577
+ fontSize: "inherit",
4578
+ background: "transparent",
4579
+ border: "none",
4580
+ boxShadow: "none",
4581
+ color: theme.input.color,
4582
+ "&:focus, &:focus-visible": {
4583
+ boxShadow: "none",
4584
+ outline: "none"
4585
+ }
4586
+ },
4587
+ "&:has(input:focus-visible)": {
4588
+ outline: `2px solid ${theme.color.secondary}`,
4589
+ outlineOffset: -2
4590
+ },
4591
+ ...after2 && { paddingRight: 2 },
4592
+ ...before2 && { paddingLeft: 2 }
4593
+ })
4594
+ ), NumericInput = forwardRef(function({
4595
+ label,
4596
+ before: before2,
4597
+ after: after2,
4598
+ value,
4599
+ setValue,
4600
+ minValue = -1 / 0,
4601
+ maxValue = 1 / 0,
4602
+ unit,
4603
+ baseUnit,
4604
+ className,
4605
+ style,
4606
+ ...props
4607
+ }, forwardedRef) {
4608
+ let baseUnitRegex = useMemo(() => baseUnit && new RegExp(`${baseUnit}$`), [baseUnit]), inputId = $bdb11010cef70236$export$f680877a34711e37(), inputRef = useRef(null), [inputValue, setInputValue] = useState(
4609
+ baseUnitRegex ? value.replace(baseUnitRegex, "") : value
4610
+ ), id = props.id || inputId;
4611
+ useImperativeHandle(forwardedRef, () => inputRef.current);
4612
+ let parseValue = useCallback(
4613
+ (value2) => {
4614
+ let [, inputValue2, inputUnit = unit || baseUnit || ""] = value2.match(/(-?\d+(?:\.\d+)?)(\%|[a-z]{0,4})?$/) || [];
4615
+ return { number: Math.max(minValue, Math.min(parseFloat(inputValue2), maxValue)), unit: inputUnit };
4616
+ },
4617
+ [minValue, maxValue, unit, baseUnit]
4618
+ ), updateValue = useCallback(
4619
+ (value2) => {
4620
+ let { number, unit: unit2 } = parseValue(value2);
4621
+ Number.isNaN(number) ? setInputValue(value2) : (setInputValue(`${number}${unit2 === baseUnit ? "" : unit2}`), setValue(`${number}${unit2}`));
4622
+ },
4623
+ [parseValue, setValue, baseUnit]
4624
+ ), onChange = useCallback(
4625
+ (e2) => updateValue(e2.target.value),
4626
+ [updateValue]
4627
+ ), setInputSelection = useCallback(() => {
4628
+ requestAnimationFrame(() => {
4629
+ let input = inputRef.current, index = input?.value.search(/[^-\d.]/) ?? -1;
4630
+ input && index >= 0 && input.setSelectionRange(index, index);
4631
+ });
4632
+ }, []), updateInputValue = useCallback(
4633
+ () => setInputValue(baseUnitRegex ? value.replace(baseUnitRegex, "") : value),
4634
+ [value, baseUnitRegex]
4635
+ );
4636
+ return useEffect(() => {
4637
+ inputRef.current !== document.activeElement && updateInputValue();
4638
+ }, [updateInputValue]), useEffect(() => {
4639
+ let handleKeyDown = (e2) => {
4640
+ if (e2.key !== "ArrowUp" && e2.key !== "ArrowDown")
4641
+ return;
4642
+ e2.preventDefault();
4643
+ let { number, unit: unit2 } = parseValue(inputValue);
4644
+ Number.isNaN(number) || (updateValue(`${e2.key === "ArrowUp" ? number + 1 : number - 1}${unit2}`), setInputSelection());
4645
+ }, input = inputRef.current;
4646
+ if (input)
4647
+ return input.addEventListener("keydown", handleKeyDown), () => input.removeEventListener("keydown", handleKeyDown);
4648
+ }, [inputValue, parseValue, updateValue, setInputSelection]), react_default.createElement(Wrapper, { after: after2, before: before2, className, style }, before2 && react_default.createElement("div", null, before2), label && react_default.createElement("label", { htmlFor: id, className: "sb-sr-only" }, label), react_default.createElement(
4649
+ Form.Input,
4650
+ {
4651
+ ...props,
4652
+ id,
4653
+ ref: inputRef,
4654
+ value: inputValue,
4655
+ onChange,
4656
+ onFocus: setInputSelection,
4657
+ onBlur: updateInputValue
4658
+ }
4659
+ ), after2 && react_default.createElement("div", null, after2));
4660
+ });
4661
+
4662
+ // src/manager/components/preview/Viewport.tsx
4663
+ var ViewportWrapper = styled.div(({ active, isDefault, theme }) => ({
4664
+ gridArea: "1 / 1",
4665
+ alignSelf: "start",
4666
+ justifySelf: "start",
4667
+ display: active ? "inline-flex" : "none",
4668
+ flexDirection: "column",
4669
+ gap: 6,
4670
+ width: "100%",
4671
+ height: "100%",
4672
+ paddingTop: isDefault ? 0 : 6,
4673
+ paddingBottom: isDefault ? 0 : 40,
4674
+ paddingInline: isDefault ? 0 : 40,
4675
+ '&:has([data-size-input="width"]:focus-visible)': {
4676
+ "[data-dragging]": {
4677
+ borderRightColor: theme.color.secondary,
4678
+ boxShadow: `4px 0 5px -2px ${theme.background.hoverable}`
4679
+ }
4680
+ },
4681
+ '&:has([data-size-input="height"]:focus-visible)': {
4682
+ "[data-dragging]": {
4683
+ borderBottomColor: theme.color.secondary,
4684
+ boxShadow: `0 4px 5px -2px ${theme.background.hoverable}`
4685
+ }
4686
+ }
4687
+ })), ViewportControls = styled.div({
4688
+ display: "flex",
4689
+ gap: 6
4690
+ }), ViewportDimensions = styled.div({
4691
+ display: "flex",
4692
+ gap: 2
4693
+ }), FrameWrapper = styled.div(({ isDefault, "data-dragging": dragging, theme }) => ({
4694
+ position: "relative",
4695
+ minWidth: VIEWPORT_MIN_WIDTH,
4696
+ minHeight: VIEWPORT_MIN_HEIGHT,
4697
+ boxSizing: "content-box",
4698
+ // we're sizing the contents, not the box itself
4699
+ border: `1px solid ${theme.button.border}`,
4700
+ borderWidth: isDefault ? 0 : 1,
4701
+ borderRadius: isDefault ? 0 : 4,
4702
+ transition: "border-color 0.2s, box-shadow 0.2s",
4703
+ '&:has([data-side="right"]:hover), &[data-dragging="right"]': {
4704
+ borderRightColor: theme.color.secondary,
4705
+ boxShadow: `4px 0 5px -2px ${theme.background.hoverable}`,
4706
+ '[data-side="right"]::after': {
4707
+ opacity: 1
4708
+ }
4709
+ },
4710
+ '&:has([data-side="bottom"]:hover), &[data-dragging="bottom"]': {
4711
+ borderBottomColor: theme.color.secondary,
4712
+ boxShadow: `0 4px 5px -2px ${theme.background.hoverable}`,
4713
+ '[data-side="bottom"]::after': {
4714
+ opacity: 1
4715
+ }
4716
+ },
4717
+ '&:has([data-side="both"]:hover), &[data-dragging="both"]': {
4718
+ boxShadow: `3px 3px 5px -2px ${theme.background.hoverable}`,
4719
+ "&::after, [data-side]::after": {
4720
+ opacity: 1
4721
+ }
4722
+ },
4723
+ "&::after": {
4724
+ content: '""',
4725
+ display: "block",
4726
+ position: "absolute",
4727
+ pointerEvents: "none",
4728
+ bottom: 1,
4729
+ right: 1,
4730
+ width: 12,
4731
+ height: 12,
4732
+ opacity: 0,
4733
+ transition: "opacity 0.2s",
4734
+ background: `linear-gradient(to top left,
4735
+ rgba(0,0,0,0) 0%,
4736
+ rgba(0,0,0,0) calc(25% - 1px),
4737
+ ${theme.color.secondary} 25%,
4738
+ rgba(0,0,0,0) calc(25% + 1px),
4739
+ rgba(0,0,0,0) calc(45% - 1px),
4740
+ ${theme.color.secondary} 45%,
4741
+ rgba(0,0,0,0) calc(45% + 1px),
4742
+ rgba(0,0,0,0) 100%)`
4743
+ },
4744
+ iframe: {
4745
+ pointerEvents: dragging === "none" ? "auto" : "none"
4746
+ }
4747
+ })), DragHandle = styled.div(
4748
+ { display: "none" },
4749
+ ({ theme, isDefault }) => !isDefault && {
4750
+ display: "block",
4751
+ position: "absolute",
4752
+ fontSize: 10,
4753
+ '&[data-side="both"]': {
4754
+ right: -12,
4755
+ bottom: -12,
4756
+ width: 25,
4757
+ height: 25,
4758
+ cursor: "nwse-resize"
4759
+ },
4760
+ '&[data-side="bottom"]': {
4761
+ left: 0,
4762
+ right: 13,
4763
+ bottom: -12,
4764
+ height: 20,
4765
+ cursor: "row-resize",
4766
+ "&::after": {
4767
+ content: "attr(data-value)",
4768
+ position: "absolute",
4769
+ top: "50%",
4770
+ left: "50%",
4771
+ transform: "translate(-50%, -50%)",
4772
+ borderRadius: 4,
4773
+ backgroundColor: theme.background.hoverable,
4774
+ padding: "2px 4px",
4775
+ opacity: 0,
4776
+ transition: "opacity 0.2s"
4777
+ }
4778
+ },
4779
+ '&[data-side="right"]': {
4780
+ top: 0,
4781
+ right: -12,
4782
+ bottom: 13,
4783
+ width: 20,
4784
+ cursor: "col-resize",
4785
+ "&::after": {
4786
+ content: "attr(data-value)",
4787
+ position: "absolute",
4788
+ top: "50%",
4789
+ left: "50%",
4790
+ transform: "translate(-50%, -50%)",
4791
+ borderRadius: 4,
4792
+ backgroundColor: theme.background.hoverable,
4793
+ padding: "2px 4px",
4794
+ opacity: 0,
4795
+ transition: "opacity 0.2s"
4796
+ }
4797
+ }
4798
+ }
4799
+ ), ScrollEdge = styled.div({
4800
+ position: "absolute",
4801
+ pointerEvents: "none",
4802
+ width: 0,
4803
+ height: 0,
4804
+ '&[data-edge="right"]': {
4805
+ right: -40,
4806
+ height: "100%"
4807
+ },
4808
+ '&[data-edge="bottom"]': {
4809
+ bottom: -40,
4810
+ width: "100%"
4811
+ },
4812
+ '&[data-edge="both"]': {
4813
+ right: -40,
4814
+ bottom: -40
4815
+ }
4816
+ }), SizeInput = styled(NumericInput)({
4817
+ width: 85,
4818
+ height: 28,
4819
+ minHeight: 28
4820
+ }), parseNumber = (value) => {
4821
+ let [match, number, unit] = value.match(/^(\d+(?:\.\d+)?)(\%|[a-z]{0,4})?$/) || [];
4822
+ return match ? { number: Number(number), unit } : void 0;
4823
+ }, Viewport = ({
4824
+ active,
4825
+ id,
4826
+ src,
4827
+ scale
4828
+ }) => {
4829
+ let { width, height, isCustom, isDefault, lastSelectedOption, resize, rotate, select } = useViewport(), [dragging, setDragging] = useState("none"), targetRef = useRef(null), dragRefX = useRef(null), dragRefY = useRef(null), dragRefXY = useRef(null), dragSide = useRef("none"), dragStart = useRef();
4830
+ useEffect(() => {
4831
+ let scrollRight = targetRef.current?.querySelector('[data-edge="right"]'), scrollBottom = targetRef.current?.querySelector('[data-edge="bottom"]'), scrollBoth = targetRef.current?.querySelector('[data-edge="both"]'), onDrag = (e2) => {
4832
+ (dragSide.current === "both" || dragSide.current === "right") && (targetRef.current.style.width = `${dragStart.current[0] + e2.clientX}px`, dragRefX.current.dataset.value = `${dragStart.current[0] + e2.clientX}`), (dragSide.current === "both" || dragSide.current === "bottom") && (targetRef.current.style.height = `${dragStart.current[1] + e2.clientY}px`, dragRefY.current.dataset.value = `${dragStart.current[1] + e2.clientY}`), dragSide.current === "both" && scrollBoth?.scrollIntoView({ block: "center", inline: "center" }), dragSide.current === "right" && scrollRight?.scrollIntoView({ block: "center", inline: "center" }), dragSide.current === "bottom" && scrollBottom?.scrollIntoView({ block: "center", inline: "center" });
4833
+ }, onEnd = () => {
4834
+ window.removeEventListener("mouseup", onEnd), window.removeEventListener("mousemove", onDrag), setDragging("none");
4835
+ let { clientWidth, clientHeight } = targetRef.current, scale2 = Number(targetRef.current.dataset.scale) || 1;
4836
+ resize(`${Math.round(clientWidth / scale2)}px`, `${Math.round(clientHeight / scale2)}px`), dragStart.current = void 0;
4837
+ }, onStart = (e2) => {
4838
+ e2.preventDefault(), window.addEventListener("mouseup", onEnd), window.addEventListener("mousemove", onDrag), dragSide.current = e2.currentTarget.dataset.side, dragStart.current = [
4839
+ (targetRef.current?.clientWidth ?? 0) - e2.clientX,
4840
+ (targetRef.current?.clientHeight ?? 0) - e2.clientY
4841
+ ], setDragging(dragSide.current);
4842
+ }, handles = [dragRefX.current, dragRefY.current, dragRefXY.current];
4843
+ return handles.forEach((el) => el?.addEventListener("mousedown", onStart)), () => handles.forEach((el) => el?.removeEventListener("mousedown", onStart));
4844
+ }, [resize]);
4845
+ let frameStyles = useMemo(() => {
4846
+ let { number: nx, unit: ux = "px" } = parseNumber(width) ?? { number: 0, unit: "px" }, { number: ny, unit: uy = "px" } = parseNumber(height) ?? { number: 0, unit: "px" };
4847
+ return {
4848
+ width: `${nx * scale}${ux}`,
4849
+ height: `${ny * scale}${uy}`
4850
+ };
4851
+ }, [width, height, scale]);
4852
+ return react_default.createElement(ViewportWrapper, { key: id, active, isDefault }, !isDefault && react_default.createElement(ViewportControls, null, react_default.createElement(ViewportDimensions, null, react_default.createElement(
4853
+ SizeInput,
4854
+ {
4855
+ "aria-label": "Viewport width",
4856
+ "data-size-input": "width",
4857
+ label: "Viewport width",
4858
+ before: react_default.createElement(ActionList.Action, { size: "small", readOnly: !0, "aria-hidden": !0 }, "W"),
4859
+ value: width,
4860
+ minValue: 0,
4861
+ setValue: (value) => resize(value, height)
4862
+ }
4863
+ ), react_default.createElement(
4864
+ ActionList.Button,
4865
+ {
4866
+ key: "viewport-rotate",
4867
+ size: "small",
4868
+ padding: "small",
4869
+ ariaLabel: "Rotate viewport",
4870
+ onClick: rotate
4871
+ },
4872
+ react_default.createElement(TransferIcon, null)
4873
+ ), react_default.createElement(
4874
+ SizeInput,
4875
+ {
4876
+ "aria-label": "Viewport height",
4877
+ "data-size-input": "height",
4878
+ label: "Viewport height",
4879
+ before: react_default.createElement(ActionList.Action, { size: "small", readOnly: !0, "aria-hidden": !0 }, "H"),
4880
+ value: height,
4881
+ minValue: 0,
4882
+ setValue: (value) => resize(width, value)
4883
+ }
4884
+ ), isCustom && lastSelectedOption && react_default.createElement(
4885
+ ActionList.Button,
4886
+ {
4887
+ key: "viewport-restore",
4888
+ size: "small",
4889
+ padding: "small",
4890
+ ariaLabel: "Restore viewport",
4891
+ onClick: () => select(lastSelectedOption)
4892
+ },
4893
+ react_default.createElement(UndoIcon, null)
4894
+ ))), react_default.createElement(
4895
+ FrameWrapper,
4896
+ {
4897
+ isDefault,
4898
+ "data-dragging": dragging,
4899
+ "data-scale": scale,
4900
+ style: isDefault ? { height: "100%", width: "100%" } : frameStyles,
4901
+ ref: targetRef
4902
+ },
4903
+ react_default.createElement(
4904
+ "div",
4905
+ {
4906
+ style: {
4907
+ height: `${1 / scale * 100}%`,
4908
+ width: `${1 / scale * 100}%`,
4909
+ transform: `scale(${scale})`,
4910
+ transformOrigin: "top left"
4911
+ }
4912
+ },
4913
+ react_default.createElement(IFrame, { allowFullScreen: !0, active, key: id, id, title: id, src, scale: 1 }),
4914
+ !isDefault && react_default.createElement(react_default.Fragment, null, react_default.createElement(ScrollEdge, { "data-edge": "right" }), react_default.createElement(ScrollEdge, { "data-edge": "bottom" }), react_default.createElement(ScrollEdge, { "data-edge": "both" }))
4915
+ ),
4916
+ react_default.createElement(
4917
+ DragHandle,
4918
+ {
4919
+ ref: dragRefX,
4920
+ isDefault,
4921
+ "data-side": "right",
4922
+ "data-value": width.replace("px", "")
4923
+ }
4924
+ ),
4925
+ react_default.createElement(
4926
+ DragHandle,
4927
+ {
4928
+ ref: dragRefY,
4929
+ isDefault,
4930
+ "data-side": "bottom",
4931
+ "data-value": height.replace("px", "")
4932
+ }
4933
+ ),
4934
+ react_default.createElement(DragHandle, { ref: dragRefXY, isDefault, "data-side": "both" })
4935
+ ));
4936
+ };
4937
+
4938
+ // src/manager/components/preview/FramesRenderer.tsx
4939
+ var getActive = (refId, refs) => refId && refs[refId] ? `storybook-ref-${refId}` : "storybook-preview-iframe", SkipToSidebarLink = styled(Button)(({ theme }) => ({
4940
+ display: "none",
4941
+ "@media (min-width: 600px)": {
4942
+ position: "absolute",
4943
+ display: "block",
4944
+ top: 10,
4945
+ right: 15,
4946
+ padding: "10px 15px",
4947
+ fontSize: theme.typography.size.s1,
4948
+ transform: "translateY(-100px)",
4949
+ "&:focus": {
4950
+ transform: "translateY(0)",
4951
+ zIndex: 1
4952
+ }
4953
+ }
4954
+ })), whenSidebarIsVisible = ({ api, state }) => ({
4955
+ isFullscreen: api.getIsFullscreen(),
4956
+ isNavShown: api.getIsNavShown(),
4957
+ selectedStoryId: state.storyId
4958
+ }), styles = {
4959
+ '#root [data-is-storybook="false"]': {
4960
+ display: "none"
4961
+ },
4962
+ '#root [data-is-storybook="true"]': {
4963
+ display: "block"
4964
+ }
4965
+ }, FramesRenderer = ({
4966
+ api,
4967
+ refs,
4968
+ scale,
4969
+ viewMode = "story",
4299
4970
  refId,
4300
4971
  queryParams = {},
4301
4972
  storyId = "*"
@@ -4312,18 +4983,7 @@ var getActive = (refId, refs) => refId && refs[refId] ? `storybook-ref-${refId}`
4312
4983
  refId: ref.id,
4313
4984
  viewMode
4314
4985
  }).previewHref);
4315
- }), react_default.createElement(Fragment, null, react_default.createElement(Global, { styles }), react_default.createElement(Consumer, { filter: whenSidebarIsVisible }, ({ isFullscreen, isNavShown, selectedStoryId }) => isFullscreen || !isNavShown || !selectedStoryId ? null : react_default.createElement(SkipToSidebarLink, { ariaLabel: !1, asChild: !0 }, react_default.createElement("a", { href: `#${selectedStoryId}`, tabIndex: 0, title: "Skip to sidebar" }, "Skip to sidebar"))), Object.entries(frames).map(([id, src]) => react_default.createElement(Fragment, { key: id }, react_default.createElement(
4316
- IFrame,
4317
- {
4318
- active: id === active,
4319
- key: id,
4320
- id,
4321
- title: id,
4322
- src,
4323
- allowFullScreen: !0,
4324
- scale
4325
- }
4326
- ))));
4986
+ }), react_default.createElement(Fragment, null, react_default.createElement(Global, { styles }), react_default.createElement(Consumer, { filter: whenSidebarIsVisible }, ({ isFullscreen, isNavShown, selectedStoryId }) => isFullscreen || !isNavShown || !selectedStoryId ? null : react_default.createElement(SkipToSidebarLink, { ariaLabel: !1, asChild: !0 }, react_default.createElement("a", { href: `#${selectedStoryId}`, tabIndex: 0, title: "Skip to sidebar" }, "Skip to sidebar"))), Object.entries(frames).map(([id, src]) => react_default.createElement(Viewport, { key: id, id, src, active: id === active, scale })));
4327
4987
  };
4328
4988
 
4329
4989
  // src/manager/components/preview/Toolbar.tsx
@@ -4451,8 +5111,8 @@ var PreviewContainer = styled.main({
4451
5111
  gridTemplateColumns: "100%",
4452
5112
  gridTemplateRows: "100%",
4453
5113
  position: "relative",
4454
- width: "100%",
4455
- height: "100%"
5114
+ minWidth: "100%",
5115
+ minHeight: "100%"
4456
5116
  },
4457
5117
  ({ show }) => ({ display: show ? "grid" : "none" })
4458
5118
  ), UnstyledLink = styled(Link2)({
@@ -4503,64 +5163,153 @@ var ApplyWrappers = ({
4503
5163
  }
4504
5164
  ];
4505
5165
 
5166
+ // src/manager/components/Shortcut.tsx
5167
+ var Wrapper2 = styled.span(({ theme }) => ({
5168
+ display: "inline-flex",
5169
+ alignItems: "center",
5170
+ justifyContent: "center",
5171
+ height: 16,
5172
+ fontSize: "11px",
5173
+ fontWeight: theme.typography.weight.regular,
5174
+ background: theme.base === "light" ? "rgba(0,0,0,0.05)" : "rgba(255,255,255,0.05)",
5175
+ color: theme.base === "light" ? theme.color.dark : theme.textMutedColor,
5176
+ borderRadius: 2,
5177
+ userSelect: "none",
5178
+ pointerEvents: "none",
5179
+ padding: "0 4px"
5180
+ })), Key = styled.kbd(({ theme }) => ({
5181
+ padding: 0,
5182
+ fontFamily: theme.typography.fonts.base,
5183
+ verticalAlign: "middle",
5184
+ "& + &": {
5185
+ marginLeft: 6
5186
+ }
5187
+ })), Shortcut = ({ keys }) => react_default.createElement(Wrapper2, null, keys.map((key) => react_default.createElement(Key, { key }, shortcutToHumanString([key]))));
5188
+
4506
5189
  // src/manager/components/preview/tools/zoom.tsx
4507
- var initialZoom = 1, Context = createContext({ value: initialZoom, set: (v2) => {
4508
- } }), ZoomProvider = class extends Component {
5190
+ var ZOOM_LEVELS = [0.25, 0.5, 0.75, 0.9, 1, 1.1, 1.25, 1.5, 2, 3, 4], INITIAL_ZOOM_LEVEL = 1, ZoomButton = styled(Button)({
5191
+ minWidth: 48
5192
+ }), Context = createContext({ value: INITIAL_ZOOM_LEVEL, set: (v2) => {
5193
+ } }), ZoomInput = styled(NumericInput)({
5194
+ input: {
5195
+ width: 100
5196
+ }
5197
+ }), ZoomConsumer = Context.Consumer, ZoomProvider = class extends Component {
4509
5198
  constructor() {
4510
5199
  super(...arguments);
4511
5200
  this.state = {
4512
- value: initialZoom
5201
+ value: INITIAL_ZOOM_LEVEL
4513
5202
  };
4514
5203
  this.set = (value) => this.setState({ value });
4515
5204
  }
4516
5205
  render() {
4517
5206
  let { children, shouldScale } = this.props, { set } = this, { value } = this.state;
4518
- return react_default.createElement(Context.Provider, { value: { value: shouldScale ? value : initialZoom, set } }, children);
5207
+ return react_default.createElement(Context.Provider, { value: { value: shouldScale ? value : INITIAL_ZOOM_LEVEL, set } }, children);
4519
5208
  }
4520
- }, { Consumer: ZoomConsumer } = Context, Zoom2 = memo(function({ zoomIn, zoomOut, reset }) {
4521
- return react_default.createElement(react_default.Fragment, null, react_default.createElement(Button, { key: "zoomin", padding: "small", variant: "ghost", onClick: zoomIn, ariaLabel: "Zoom in" }, react_default.createElement(ZoomIcon, null)), react_default.createElement(Button, { key: "zoomout", padding: "small", variant: "ghost", onClick: zoomOut, ariaLabel: "Zoom out" }, react_default.createElement(ZoomOutIcon, null)), react_default.createElement(
4522
- Button,
5209
+ }, Zoom2 = memo(function({ value, zoomIn, zoomOut, zoomTo }) {
5210
+ let inputRef = useRef(null);
5211
+ return react_default.createElement(
5212
+ PopoverProvider,
4523
5213
  {
4524
- key: "zoomreset",
4525
- padding: "small",
4526
- variant: "ghost",
4527
- onClick: reset,
4528
- ariaLabel: "Reset zoom"
4529
- },
4530
- react_default.createElement(ZoomResetIcon, null)
4531
- ));
4532
- });
4533
- var ZoomWrapper = memo(function({
4534
- set,
4535
- value
4536
- }) {
4537
- let zoomIn = useCallback(
4538
- (e2) => {
4539
- e2.preventDefault(), set(0.8 * value);
4540
- },
4541
- [set, value]
4542
- ), zoomOut = useCallback(
4543
- (e2) => {
4544
- e2.preventDefault(), set(1.25 * value);
5214
+ padding: "none",
5215
+ onVisibleChange: (isVisible) => {
5216
+ isVisible && requestAnimationFrame(() => inputRef.current?.select());
5217
+ },
5218
+ popover: react_default.createElement(react_default.Fragment, null, react_default.createElement(ActionList, null, react_default.createElement(ActionList.Item, null, react_default.createElement(
5219
+ ZoomInput,
5220
+ {
5221
+ "aria-label": "Zoom percentage",
5222
+ ref: inputRef,
5223
+ unit: "%",
5224
+ before: react_default.createElement(ActionList.Button, { size: "small", padding: "small", readOnly: !0, "aria-hidden": !0 }, react_default.createElement(ZoomIcon, null)),
5225
+ after: react_default.createElement(
5226
+ ActionList.Button,
5227
+ {
5228
+ size: "small",
5229
+ padding: "small",
5230
+ disabled: value === INITIAL_ZOOM_LEVEL,
5231
+ onClick: () => zoomTo(INITIAL_ZOOM_LEVEL),
5232
+ ariaLabel: "Reset zoom"
5233
+ },
5234
+ react_default.createElement(UndoIcon, null)
5235
+ ),
5236
+ value: `${Math.round(value * 100)}%`,
5237
+ minValue: 1,
5238
+ maxValue: 1e3,
5239
+ setValue: (value2) => {
5240
+ let zoomLevel = parseInt(value2, 10) / 100;
5241
+ Number.isNaN(zoomLevel) || zoomTo(zoomLevel);
5242
+ }
5243
+ }
5244
+ ))), react_default.createElement(ActionList, null, react_default.createElement(ActionList.Item, null, react_default.createElement(
5245
+ ActionList.Action,
5246
+ {
5247
+ onClick: zoomIn,
5248
+ ariaLabel: "Zoom in",
5249
+ disabled: value >= ZOOM_LEVELS.at(-1)
5250
+ },
5251
+ react_default.createElement(ActionList.Text, null, "Zoom in"),
5252
+ react_default.createElement(Shortcut, { keys: ["alt", "+"] })
5253
+ )), react_default.createElement(ActionList.Item, null, react_default.createElement(
5254
+ ActionList.Action,
5255
+ {
5256
+ onClick: zoomOut,
5257
+ ariaLabel: "Zoom out",
5258
+ disabled: value <= ZOOM_LEVELS.at(0)
5259
+ },
5260
+ react_default.createElement(ActionList.Text, null, "Zoom out"),
5261
+ react_default.createElement(Shortcut, { keys: ["alt", "-"] })
5262
+ )), react_default.createElement(ActionList.Item, { active: value === 0.5 }, react_default.createElement(ActionList.Action, { onClick: () => zoomTo(0.5), ariaLabel: "Zoom to 50%" }, react_default.createElement(ActionList.Text, null, "50%"))), react_default.createElement(ActionList.Item, { active: value === 1 }, react_default.createElement(ActionList.Action, { onClick: () => zoomTo(1), ariaLabel: "Zoom to 100%" }, react_default.createElement(ActionList.Text, null, "100%"), react_default.createElement(Shortcut, { keys: ["alt", "0"] }))), react_default.createElement(ActionList.Item, { active: value === 2 }, react_default.createElement(ActionList.Action, { onClick: () => zoomTo(2), ariaLabel: "Zoom to 200%" }, "200%"))))
4545
5263
  },
4546
- [set, value]
4547
- ), reset = useCallback(
4548
- (e2) => {
4549
- e2.preventDefault(), set(initialZoom);
5264
+ react_default.createElement(
5265
+ ZoomButton,
5266
+ {
5267
+ padding: "small",
5268
+ variant: "ghost",
5269
+ ariaLabel: "Change zoom level",
5270
+ active: value !== INITIAL_ZOOM_LEVEL
5271
+ },
5272
+ Math.round(value * 100),
5273
+ "%"
5274
+ )
5275
+ );
5276
+ }), ZoomWrapper = memo(function({ set, value }) {
5277
+ let api = useStorybookApi(), zoomIn = useCallback(() => {
5278
+ let higherZoomLevel = ZOOM_LEVELS.find((level) => level > value);
5279
+ higherZoomLevel && set(higherZoomLevel);
5280
+ }, [set, value]), zoomOut = useCallback(() => {
5281
+ let lowerZoomLevel = ZOOM_LEVELS.findLast((level) => level < value);
5282
+ lowerZoomLevel && set(lowerZoomLevel);
5283
+ }, [set, value]), zoomTo = useCallback(
5284
+ (value2) => {
5285
+ set(value2);
4550
5286
  },
4551
- [set, initialZoom]
5287
+ [set]
4552
5288
  );
4553
- return react_default.createElement(Zoom2, { key: "zoom", zoomIn, zoomOut, reset });
4554
- });
4555
- function ZoomToolRenderer() {
4556
- return react_default.createElement(react_default.Fragment, null, react_default.createElement(ZoomConsumer, null, ({ set, value }) => react_default.createElement(ZoomWrapper, { set, value })), react_default.createElement(Separator, null));
4557
- }
4558
- var zoomTool = {
5289
+ return useEffect(() => {
5290
+ api.setAddonShortcut("zoom", {
5291
+ label: "Zoom to 100%",
5292
+ defaultShortcut: ["alt", "0"],
5293
+ actionName: "zoomReset",
5294
+ action: () => zoomTo(1)
5295
+ }), api.setAddonShortcut("zoom", {
5296
+ label: "Zoom in",
5297
+ defaultShortcut: ["alt", "="],
5298
+ actionName: "zoomIn",
5299
+ action: zoomIn
5300
+ }), api.setAddonShortcut("zoom", {
5301
+ label: "Zoom out",
5302
+ defaultShortcut: ["alt", "-"],
5303
+ actionName: "zoomOut",
5304
+ action: zoomOut
5305
+ });
5306
+ }, [api, zoomIn, zoomOut, zoomTo]), react_default.createElement(Zoom2, { key: "zoom", value, zoomIn, zoomOut, zoomTo });
5307
+ }), zoomTool = {
4559
5308
  title: "zoom",
4560
5309
  id: "zoom",
4561
5310
  type: types.TOOL,
4562
5311
  match: ({ viewMode, tabId }) => viewMode === "story" && !tabId,
4563
- render: ZoomToolRenderer
5312
+ render: () => react_default.createElement(ZoomConsumer, null, (zoomContext) => react_default.createElement(ZoomWrapper, { ...zoomContext }))
4564
5313
  };
4565
5314
 
4566
5315
  // src/manager/components/preview/Preview.tsx
@@ -5647,229 +6396,532 @@ var QRCodeSVG = react_default.forwardRef(
5647
6396
  );
5648
6397
  QRCodeSVG.displayName = "QRCodeSVG";
5649
6398
 
5650
- // ../../node_modules/es-toolkit/dist/function/debounce.mjs
5651
- function debounce(func, debounceMs, { signal, edges } = {}) {
5652
- let pendingThis, pendingArgs = null, leading = edges != null && edges.includes("leading"), trailing = edges == null || edges.includes("trailing"), invoke = () => {
5653
- pendingArgs !== null && (func.apply(pendingThis, pendingArgs), pendingThis = void 0, pendingArgs = null);
5654
- }, onTimerEnd = () => {
5655
- trailing && invoke(), cancel();
5656
- }, timeoutId = null, schedule = () => {
5657
- timeoutId != null && clearTimeout(timeoutId), timeoutId = setTimeout(() => {
5658
- timeoutId = null, onTimerEnd();
5659
- }, debounceMs);
5660
- }, cancelTimer = () => {
5661
- timeoutId !== null && (clearTimeout(timeoutId), timeoutId = null);
5662
- }, cancel = () => {
5663
- cancelTimer(), pendingThis = void 0, pendingArgs = null;
5664
- }, flush = () => {
5665
- invoke();
5666
- }, debounced = function(...args) {
5667
- if (signal?.aborted)
5668
- return;
5669
- pendingThis = this, pendingArgs = args;
5670
- let isFirstCall = timeoutId == null;
5671
- schedule(), leading && isFirstCall && invoke();
5672
- };
5673
- return debounced.schedule = schedule, debounced.cancel = cancel, debounced.flush = flush, signal?.addEventListener("abort", cancel, { once: !0 }), debounced;
5674
- }
5675
-
5676
- // ../../node_modules/es-toolkit/dist/function/partial.mjs
5677
- function partial(func, ...partialArgs) {
5678
- return partialImpl(func, placeholderSymbol, ...partialArgs);
5679
- }
5680
- function partialImpl(func, placeholder, ...partialArgs) {
5681
- let partialed = function(...providedArgs) {
5682
- let providedArgsIndex = 0, substitutedArgs = partialArgs.slice().map((arg) => arg === placeholder ? providedArgs[providedArgsIndex++] : arg), remainingArgs = providedArgs.slice(providedArgsIndex);
5683
- return func.apply(this, substitutedArgs.concat(remainingArgs));
5684
- };
5685
- return func.prototype && (partialed.prototype = Object.create(func.prototype)), partialed;
5686
- }
5687
- var placeholderSymbol = Symbol("partial.placeholder");
5688
- partial.placeholder = placeholderSymbol;
5689
-
5690
- // ../../node_modules/es-toolkit/dist/function/partialRight.mjs
5691
- function partialRight(func, ...partialArgs) {
5692
- return partialRightImpl(func, placeholderSymbol2, ...partialArgs);
5693
- }
5694
- function partialRightImpl(func, placeholder, ...partialArgs) {
5695
- let partialedRight = function(...providedArgs) {
5696
- let placeholderLength = partialArgs.filter((arg) => arg === placeholder).length, rangeLength = Math.max(providedArgs.length - placeholderLength, 0), remainingArgs = providedArgs.slice(0, rangeLength), providedArgsIndex = rangeLength, substitutedArgs = partialArgs.slice().map((arg) => arg === placeholder ? providedArgs[providedArgsIndex++] : arg);
5697
- return func.apply(this, remainingArgs.concat(substitutedArgs));
5698
- };
5699
- return func.prototype && (partialedRight.prototype = Object.create(func.prototype)), partialedRight;
5700
- }
5701
- var placeholderSymbol2 = Symbol("partialRight.placeholder");
5702
- partialRight.placeholder = placeholderSymbol2;
5703
-
5704
- // ../../node_modules/es-toolkit/dist/function/retry.mjs
5705
- var DEFAULT_RETRIES = Number.POSITIVE_INFINITY;
6399
+ // src/manager/components/preview/tools/share.tsx
6400
+ var mapper3 = ({ api, state }) => {
6401
+ let { storyId, refId } = state;
6402
+ return { api, refId, storyId };
6403
+ }, QRContainer = styled.div(() => ({
6404
+ display: "flex",
6405
+ alignItems: "center",
6406
+ padding: 8,
6407
+ maxWidth: 200
6408
+ })), QRImageContainer = styled.div(() => ({
6409
+ width: 64,
6410
+ height: 64,
6411
+ marginRight: 12,
6412
+ backgroundColor: "white",
6413
+ padding: 2
6414
+ })), QRImage = ({ value }) => {
6415
+ let theme = useTheme();
6416
+ return react_default.createElement(QRImageContainer, null, react_default.createElement(QRCodeSVG, { value, marginSize: 0, size: 60, fgColor: theme.color.darkest }));
6417
+ }, QRContent = styled.div(() => ({})), QRTitle = styled.div(({ theme }) => ({
6418
+ fontWeight: theme.typography.weight.bold,
6419
+ fontSize: theme.typography.size.s1,
6420
+ marginBottom: 4
6421
+ })), QRDescription = styled.div(({ theme }) => ({
6422
+ fontSize: theme.typography.size.s1,
6423
+ color: theme.textMutedColor
6424
+ })), ShareMenu = react_default.memo(function({
6425
+ api,
6426
+ storyId,
6427
+ refId
6428
+ }) {
6429
+ let shortcutKeys = api.getShortcutKeys(), enableShortcuts = !!shortcutKeys, [copied, setCopied] = useState(!1), copyStoryLink = shortcutKeys?.copyStoryLink, openInIsolation = shortcutKeys?.openInIsolation, links = useMemo(() => {
6430
+ let copyTitle = copied ? "Copied!" : "Copy story link", originHrefs = api.getStoryHrefs(storyId, { base: "origin", refId }), networkHrefs = api.getStoryHrefs(storyId, { base: "network", refId });
6431
+ return [
6432
+ [
6433
+ {
6434
+ id: "copy-link",
6435
+ title: copyTitle,
6436
+ icon: react_default.createElement(LinkIcon, null),
6437
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: copyStoryLink }) : null,
6438
+ onClick: () => {
6439
+ (0, import_copy_to_clipboard.default)(originHrefs.managerHref), setCopied(!0), setTimeout(() => setCopied(!1), 2e3);
6440
+ }
6441
+ },
6442
+ {
6443
+ id: "open-new-tab",
6444
+ title: "Open in isolation mode",
6445
+ icon: react_default.createElement(ShareAltIcon, null),
6446
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: openInIsolation }) : null,
6447
+ href: originHrefs.previewHref,
6448
+ target: "_blank",
6449
+ rel: "noopener noreferrer"
6450
+ }
6451
+ ],
6452
+ [
6453
+ {
6454
+ id: "qr-section",
6455
+ content: react_default.createElement(QRContainer, null, react_default.createElement(QRImage, { value: networkHrefs.managerHref }), react_default.createElement(QRContent, null, react_default.createElement(QRTitle, null, "Scan to open"), react_default.createElement(QRDescription, null, scope.CONFIG_TYPE === "DEVELOPMENT" ? "Device must be on the same network." : "View story on another device.")))
6456
+ }
6457
+ ]
6458
+ ];
6459
+ }, [api, storyId, refId, copied, enableShortcuts, copyStoryLink, openInIsolation]);
6460
+ return react_default.createElement(TooltipLinkList, { links, style: { width: 240 } });
6461
+ }), shareTool = {
6462
+ title: "share",
6463
+ id: "share",
6464
+ type: types.TOOL,
6465
+ match: ({ viewMode, tabId }) => viewMode === "story" && !tabId,
6466
+ render: () => react_default.createElement(Consumer, { filter: mapper3 }, ({ api, storyId, refId }) => storyId ? react_default.createElement(
6467
+ PopoverProvider,
6468
+ {
6469
+ hasChrome: !0,
6470
+ placement: "bottom",
6471
+ padding: 0,
6472
+ popover: react_default.createElement(ShareMenu, { api, storyId, refId })
6473
+ },
6474
+ react_default.createElement(Button, { padding: "small", variant: "ghost", ariaLabel: "Share", tooltip: "Share..." }, react_default.createElement(ShareIcon, null))
6475
+ ) : null)
6476
+ };
5706
6477
 
5707
- // ../../node_modules/es-toolkit/dist/function/throttle.mjs
5708
- function throttle(func, throttleMs, { signal, edges = ["leading", "trailing"] } = {}) {
5709
- let pendingAt = null, debounced = debounce(function(...args) {
5710
- pendingAt = Date.now(), func.apply(this, args);
5711
- }, throttleMs, { signal, edges }), throttled = function(...args) {
5712
- if (pendingAt == null && (pendingAt = Date.now()), Date.now() - pendingAt >= throttleMs) {
5713
- pendingAt = Date.now(), func.apply(this, args), debounced.cancel(), debounced.schedule();
5714
- return;
5715
- }
5716
- debounced.apply(this, args);
6478
+ // src/manager/container/Preview.tsx
6479
+ var defaultTabs = [createCanvasTab()], defaultTools = [menuTool, remountTool], defaultToolsExtra = [zoomTool, addonsTool, fullScreenTool, shareTool, openInEditorTool], emptyTabsList = [], memoizedTabs = (0, import_memoizerific.default)(1)(
6480
+ (_2, tabElements, parameters, showTabs) => showTabs ? filterTabs([...defaultTabs, ...Object.values(tabElements)], parameters) : emptyTabsList
6481
+ ), memoizedTools = (0, import_memoizerific.default)(1)(
6482
+ (_2, toolElements, filterProps) => filterToolsSide([...defaultTools, ...Object.values(toolElements)], ...filterProps)
6483
+ ), memoizedExtra = (0, import_memoizerific.default)(1)(
6484
+ (_2, extraElements, filterProps) => filterToolsSide([...defaultToolsExtra, ...Object.values(extraElements)], ...filterProps)
6485
+ ), memoizedWrapper = (0, import_memoizerific.default)(1)((_2, previewElements) => [
6486
+ ...defaultWrappers,
6487
+ ...Object.values(previewElements)
6488
+ ]), { PREVIEW_URL } = scope, splitTitleAddExtraSpace = (input) => input.split("/").join(" / ").replace(/\s\s/, " "), getDescription = (item) => {
6489
+ if (item?.type === "story" || item?.type === "docs") {
6490
+ let { title: title2, name } = item;
6491
+ return title2 && name ? splitTitleAddExtraSpace(`${title2} - ${name} \u22C5 Storybook`) : "Storybook";
6492
+ }
6493
+ return item?.name ? `${item.name} \u22C5 Storybook` : "Storybook";
6494
+ }, mapper4 = ({
6495
+ api,
6496
+ state
6497
+ // @ts-expect-error (non strict)
6498
+ }) => {
6499
+ let { layout, location: location2, customQueryParams, storyId, refs, viewMode, path, refId } = state, entry = api.getData(storyId, refId), tabsList = Object.values(api.getElements(Addon_TypesEnum.TAB)), wrapperList = Object.values(api.getElements(Addon_TypesEnum.PREVIEW)), toolsList = Object.values(api.getElements(Addon_TypesEnum.TOOL)), toolsExtraList = Object.values(api.getElements(Addon_TypesEnum.TOOLEXTRA)), tabId = api.getQueryParam("tab"), tools = memoizedTools(toolsList.length, api.getElements(Addon_TypesEnum.TOOL), [
6500
+ entry,
6501
+ viewMode,
6502
+ location2,
6503
+ path,
6504
+ // @ts-expect-error (non strict)
6505
+ tabId
6506
+ ]), toolsExtra = memoizedExtra(
6507
+ toolsExtraList.length,
6508
+ api.getElements(Addon_TypesEnum.TOOLEXTRA),
6509
+ // @ts-expect-error (non strict)
6510
+ [entry, viewMode, location2, path, tabId]
6511
+ );
6512
+ return {
6513
+ api,
6514
+ entry,
6515
+ options: layout,
6516
+ description: getDescription(entry),
6517
+ viewMode,
6518
+ refs,
6519
+ storyId,
6520
+ baseUrl: PREVIEW_URL || "iframe.html",
6521
+ queryParams: customQueryParams,
6522
+ tools,
6523
+ toolsExtra,
6524
+ tabs: memoizedTabs(
6525
+ tabsList.length,
6526
+ api.getElements(Addon_TypesEnum.TAB),
6527
+ entry ? entry.parameters : void 0,
6528
+ layout.showTabs
6529
+ ),
6530
+ wrappers: memoizedWrapper(
6531
+ wrapperList.length,
6532
+ api.getElements(Addon_TypesEnum.PREVIEW)
6533
+ ),
6534
+ tabId
5717
6535
  };
5718
- return throttled.cancel = debounced.cancel, throttled.flush = debounced.flush, throttled;
5719
- }
5720
-
5721
- // ../addons/a11y/src/constants.ts
5722
- var ADDON_ID = "storybook/a11y", PANEL_ID = `${ADDON_ID}/panel`;
5723
- var UI_STATE_ID = `${ADDON_ID}/ui`, RESULT = `${ADDON_ID}/result`, REQUEST = `${ADDON_ID}/request`, RUNNING = `${ADDON_ID}/running`, ERROR = `${ADDON_ID}/error`, MANUAL = `${ADDON_ID}/manual`, SELECT = `${ADDON_ID}/select`, DOCUMENTATION_LINK = "writing-tests/accessibility-testing", DOCUMENTATION_DISCREPANCY_LINK = `${DOCUMENTATION_LINK}#why-are-my-tests-failing-in-different-environments`;
5724
-
5725
- // ../addons/onboarding/src/constants.ts
5726
- var ADDON_ID2 = "storybook/onboarding", ADDON_ONBOARDING_CHANNEL = `${ADDON_ID2}/channel`;
5727
-
5728
- // src/component-testing/constants.ts
5729
- var ADDON_ID3 = "storybook/interactions", PANEL_ID2 = `${ADDON_ID3}/panel`;
5730
- var DOCUMENTATION_LINK2 = "writing-tests/integrations/vitest-addon", DOCUMENTATION_DISCREPANCY_LINK2 = `${DOCUMENTATION_LINK2}#what-happens-when-there-are-different-test-results-in-multiple-environments`;
6536
+ }, PreviewConnected = react_default.memo(function(props) {
6537
+ return react_default.createElement(Consumer, { filter: mapper4 }, (fromState) => react_default.createElement(Preview, { ...props, ...fromState }));
6538
+ }), Preview_default = PreviewConnected;
5731
6539
 
5732
- // ../addons/vitest/src/constants.ts
5733
- var ADDON_ID4 = "storybook/test", TEST_PROVIDER_ID = `${ADDON_ID4}/test-provider`, STORYBOOK_ADDON_TEST_CHANNEL = `${ADDON_ID4}/channel`;
5734
- var DOCUMENTATION_LINK3 = "writing-tests/integrations/vitest-addon", DOCUMENTATION_FATAL_ERROR_LINK = `${DOCUMENTATION_LINK3}#what-happens-if-vitest-itself-has-an-error`;
5735
- var storeOptions = {
5736
- id: ADDON_ID4,
5737
- initialState: {
5738
- config: {
5739
- coverage: !1,
5740
- a11y: !1
5741
- },
5742
- watching: !1,
5743
- cancelling: !1,
5744
- fatalError: void 0,
5745
- indexUrl: void 0,
5746
- previewAnnotations: [],
5747
- currentRun: {
5748
- triggeredBy: void 0,
5749
- config: {
5750
- coverage: !1,
5751
- a11y: !1
5752
- },
5753
- componentTestCount: {
5754
- success: 0,
5755
- error: 0
5756
- },
5757
- a11yCount: {
5758
- success: 0,
5759
- warning: 0,
5760
- error: 0
5761
- },
5762
- storyIds: void 0,
5763
- totalTestCount: void 0,
5764
- startedAt: void 0,
5765
- finishedAt: void 0,
5766
- unhandledErrors: [],
5767
- coverageSummary: void 0
6540
+ // src/manager/components/Optional/Optional.tsx
6541
+ var Wrapper3 = styled.div({
6542
+ display: "inline-grid",
6543
+ gridTemplateColumns: "max-content",
6544
+ overflow: "hidden"
6545
+ }), Content2 = styled.div(({ isHidden }) => ({
6546
+ display: "inline-block",
6547
+ gridArea: "1/1",
6548
+ opacity: isHidden === null ? 0 : 1,
6549
+ visibility: isHidden ? "hidden" : "visible"
6550
+ })), Optional = ({
6551
+ content,
6552
+ fallback
6553
+ }) => {
6554
+ let contentRef = useRef(null), wrapperRef = useRef(null), [hidden, setHidden] = useState(null), contentWidth = useRef(contentRef.current?.offsetWidth ?? 0), wrapperWidth = useRef(wrapperRef.current?.offsetWidth ?? 0);
6555
+ return useEffect(() => {
6556
+ if (contentRef.current && wrapperRef.current) {
6557
+ let resizeObserver = new ResizeObserver(() => {
6558
+ wrapperWidth.current = wrapperRef.current?.offsetWidth || wrapperWidth.current, contentWidth.current = contentRef.current?.offsetWidth || contentWidth.current, setHidden(contentWidth.current > wrapperWidth.current);
6559
+ });
6560
+ return resizeObserver.observe(wrapperRef.current), () => resizeObserver.disconnect();
5768
6561
  }
5769
- }
6562
+ }, []), react_default.createElement(Wrapper3, { ref: wrapperRef }, react_default.createElement(Content2, { isHidden: hidden, ref: contentRef }, content), fallback && react_default.createElement(Content2, { isHidden: !hidden }, fallback));
5770
6563
  };
5771
- var STORE_CHANNEL_EVENT_NAME = `UNIVERSAL_STORE:${storeOptions.id}`;
5772
-
5773
- // src/cli/AddonVitestService.constants.ts
5774
- var SUPPORTED_FRAMEWORKS = [
5775
- "html-vite" /* HTML_VITE */,
5776
- "nextjs-vite" /* NEXTJS_VITE */,
5777
- "preact-vite" /* PREACT_VITE */,
5778
- "react-native-web-vite" /* REACT_NATIVE_WEB_VITE */,
5779
- "react-vite" /* REACT_VITE */,
5780
- "solid" /* SOLID */,
5781
- "svelte-vite" /* SVELTE_VITE */,
5782
- "sveltekit" /* SVELTEKIT */,
5783
- "vue3-vite" /* VUE3_VITE */,
5784
- "web-components-vite" /* WEB_COMPONENTS_VITE */
5785
- ];
5786
6564
 
5787
- // src/docs-tools/shared.ts
5788
- var ADDON_ID5 = "storybook/docs", PANEL_ID3 = `${ADDON_ID5}/panel`;
5789
- var SNIPPET_RENDERED = `${ADDON_ID5}/snippet-rendered`;
5790
-
5791
- // ../../node_modules/@gilbarbara/deep-equal/dist/index.mjs
5792
- function isOfType(type) {
5793
- return (value) => typeof value === type;
5794
- }
5795
- var isFunction = isOfType("function"), isNull = (value) => value === null, isRegex = (value) => Object.prototype.toString.call(value).slice(8, -1) === "RegExp", isObject = (value) => !isUndefined(value) && !isNull(value) && (isFunction(value) || typeof value == "object"), isUndefined = isOfType("undefined");
5796
- function equalArray(left, right) {
5797
- let { length } = left;
5798
- if (length !== right.length)
5799
- return !1;
5800
- for (let index = length; index-- !== 0; )
5801
- if (!equal(left[index], right[index]))
5802
- return !1;
5803
- return !0;
5804
- }
5805
- function equalArrayBuffer(left, right) {
5806
- if (left.byteLength !== right.byteLength)
5807
- return !1;
5808
- let view1 = new DataView(left.buffer), view2 = new DataView(right.buffer), index = left.byteLength;
5809
- for (; index--; )
5810
- if (view1.getUint8(index) !== view2.getUint8(index))
5811
- return !1;
5812
- return !0;
6565
+ // src/manager/components/Particles/Particles.tsx
6566
+ var Shape = styled.svg(({ color: color2 }) => ({
6567
+ fill: color2,
6568
+ position: "absolute",
6569
+ inset: "0",
6570
+ margin: "auto",
6571
+ width: "12px",
6572
+ height: "12px",
6573
+ pointerEvents: "none"
6574
+ })), Donut = (props) => react_default.createElement(Shape, { viewBox: "0 0 90 90", xmlns: "http://www.w3.org/2000/svg", color: "red", ...props }, react_default.createElement("path", { d: "M45 0c24.853 0 45 20.147 45 45S69.853 90 45 90 0 69.853 0 45 20.147 0 45 0zm.5 27C35.283 27 27 35.283 27 45.5S35.283 64 45.5 64 64 55.717 64 45.5 55.717 27 45.5 27z" })), L2 = (props) => react_default.createElement(Shape, { viewBox: "0 0 55 89", xmlns: "http://www.w3.org/2000/svg", color: "#66BF3C", ...props }, react_default.createElement("path", { d: "M55 3v83a3 3 0 01-3 3H3a3 3 0 01-3-3V64a3 3 0 013-3h21a3 3 0 003-3V3a3 3 0 013-3h22a3 3 0 013 3z" })), Slice = (props) => react_default.createElement(Shape, { viewBox: "0 0 92 92", xmlns: "http://www.w3.org/2000/svg", color: "#FF4785", ...props }, react_default.createElement("path", { d: "M92 89V3c0-3-2.056-3-3-3C39.294 0 0 39.294 0 89c0 0 0 3 3 3h86a3 3 0 003-3z" })), Square = ({ style, ...props }) => react_default.createElement(
6575
+ Shape,
6576
+ {
6577
+ viewBox: "0 0 90 90",
6578
+ xmlns: "http://www.w3.org/2000/svg",
6579
+ color: "#1EA7FD",
6580
+ ...props,
6581
+ style: { borderRadius: 5, ...style }
6582
+ },
6583
+ react_default.createElement("path", { d: "M0 0h90v90H0z" })
6584
+ ), Triangle = (props) => react_default.createElement(Shape, { viewBox: "0 0 96 88", xmlns: "http://www.w3.org/2000/svg", color: "#FFAE00", ...props }, react_default.createElement("path", { d: "M50.63 1.785l44.928 81.77A3 3 0 0192.928 88H3.072a3 3 0 01-2.629-4.445l44.929-81.77a3 3 0 015.258 0z" })), T2 = (props) => react_default.createElement(Shape, { viewBox: "0 0 92 62", xmlns: "http://www.w3.org/2000/svg", color: "#FC521F", ...props }, react_default.createElement("path", { d: "M63 3v25a3 3 0 003 3h23a3 3 0 013 3v25a3 3 0 01-3 3H3a3 3 0 01-3-3V34a3 3 0 013-3h24a3 3 0 003-3V3a3 3 0 013-3h27a3 3 0 013 3z" })), Z = (props) => react_default.createElement(Shape, { viewBox: "0 0 56 90", xmlns: "http://www.w3.org/2000/svg", color: "#6F2CAC", ...props }, react_default.createElement("path", { d: "M28 3v25a3 3 0 003 3h22a3 3 0 013 3v53a3 3 0 01-3 3H31a3 3 0 01-3-3V62a3 3 0 00-3-3H3a3 3 0 01-3-3V3a3 3 0 013-3h22a3 3 0 013 3z" })), fadeToTransparent = keyframes`
6585
+ to {
6586
+ opacity: 0;
6587
+ }
6588
+ `, disperse = keyframes`
6589
+ to {
6590
+ transform: translate(
6591
+ calc(cos(var(--angle)) * var(--distance)),
6592
+ calc(sin(var(--angle)) * var(--distance))
6593
+ ) rotate(var(--rotation));
6594
+ }
6595
+ `, slideDown = keyframes`
6596
+ to {
6597
+ transform: translateY(50px);
6598
+ }
6599
+ `, Container5 = styled.div({
6600
+ position: "absolute",
6601
+ display: "flex",
6602
+ flexDirection: "row",
6603
+ flexWrap: "wrap",
6604
+ gap: 10,
6605
+ "--particle-curve": "cubic-bezier(0.2, 0.56, 0, 1)",
6606
+ animation: `${slideDown} 1000ms forwards cubic-bezier(0.587, -0.381, 0.583, 0.599)`,
6607
+ animationDelay: "150ms",
6608
+ zIndex: 999,
6609
+ svg: {
6610
+ width: 15,
6611
+ height: 15,
6612
+ animation: `${fadeToTransparent} var(--fade-duration) forwards, ${disperse} 1000ms forwards var(--particle-curve)`
6613
+ }
6614
+ }), FADE_DURATION = 1200, NUM_OF_PARTICLES = 8, JITTER = 15, random = (min, max) => Math.random() * (max - min) + min, sortRandomly = (array) => array.sort(() => Math.random() - 0.5), Particles = memo(function({
6615
+ anchor: Anchor
6616
+ }) {
6617
+ let anchorRef = useRef(null), [left, setLeft] = useState(0), [top, setTop] = useState(0), shapes = sortRandomly([Donut, L2, Slice, Square, Triangle, T2, Z]), colors = sortRandomly([
6618
+ "#FF0000",
6619
+ "#FF4787",
6620
+ "#66BF3C",
6621
+ "#1EA7FD",
6622
+ "#FC521F",
6623
+ "#6F2CAC",
6624
+ "#FFAE00"
6625
+ ]);
6626
+ return useLayoutEffect(() => {
6627
+ let rect = anchorRef.current?.getBoundingClientRect();
6628
+ rect && (setLeft(rect.left + rect.width / 2), setTop(rect.top + rect.height / 2));
6629
+ }, []), react_default.createElement("div", { ref: anchorRef }, react_default.createElement(Anchor, null), createPortal(
6630
+ react_default.createElement(Container5, { style: { top: top + "px", left: left + "px" } }, shapes.map((Particle, index) => {
6631
+ let angle = 360 / NUM_OF_PARTICLES * index + random(-JITTER, JITTER), distance = random(50, 80), rotation = random(-360, 360), style = {
6632
+ "--angle": angle + "deg",
6633
+ "--distance": distance + "px",
6634
+ "--rotation": rotation + "deg",
6635
+ "--fade-duration": FADE_DURATION + "ms"
6636
+ };
6637
+ return react_default.createElement(Particle, { key: Particle.name, style, color: colors[index] });
6638
+ })),
6639
+ document.getElementById("root") ?? document.body
6640
+ ));
6641
+ });
6642
+
6643
+ // src/manager/components/TextFlip.tsx
6644
+ var slideIn2 = keyframes({
6645
+ from: {
6646
+ transform: "translateY(var(--slide-in-from))",
6647
+ opacity: 0
6648
+ }
6649
+ }), slideOut = keyframes({
6650
+ to: {
6651
+ transform: "translateY(var(--slide-out-to))",
6652
+ opacity: 0
6653
+ }
6654
+ }), Container6 = styled.div({
6655
+ display: "inline-grid",
6656
+ gridTemplateColumns: "1fr",
6657
+ justifyContent: "center",
6658
+ alignItems: "center"
6659
+ }), Placeholder2 = styled.div({
6660
+ gridArea: "1 / 1",
6661
+ userSelect: "none",
6662
+ visibility: "hidden"
6663
+ }), Text2 = styled.span(({ duration, isExiting, isEntering, reverse }) => {
6664
+ let animation;
6665
+ return isExiting ? animation = `${slideOut} ${duration}ms forwards` : isEntering && (animation = `${slideIn2} ${duration}ms forwards`), {
6666
+ gridArea: "1 / 1",
6667
+ animation,
6668
+ pointerEvents: isExiting ? "none" : "auto",
6669
+ userSelect: isExiting ? "none" : "text",
6670
+ "--slide-in-from": reverse ? "-100%" : "100%",
6671
+ "--slide-out-to": reverse ? "100%" : "-100%",
6672
+ "@media (prefers-reduced-motion: reduce)": {
6673
+ animation: "none",
6674
+ opacity: isExiting ? 0 : 1,
6675
+ transform: "translateY(0)"
6676
+ }
6677
+ };
6678
+ }), TextFlip = ({
6679
+ text,
6680
+ duration = 250,
6681
+ placeholder,
6682
+ ...props
6683
+ }) => {
6684
+ let textRef = useRef(text), [staleValue, setStaleValue] = useState(text), isAnimating = text !== staleValue, reverse = isAnimating && numericCompare(staleValue, text);
6685
+ return textRef.current = text, react_default.createElement(Container6, { ...props }, isAnimating && react_default.createElement(
6686
+ Text2,
6687
+ {
6688
+ "aria-hidden": !0,
6689
+ duration,
6690
+ reverse,
6691
+ isExiting: !0,
6692
+ onAnimationEnd: () => setStaleValue(textRef.current)
6693
+ },
6694
+ staleValue
6695
+ ), react_default.createElement(Text2, { duration, reverse, isEntering: isAnimating }, text), placeholder && react_default.createElement(Placeholder2, { "aria-hidden": !0 }, placeholder));
6696
+ };
6697
+ function numericCompare(a2, b2) {
6698
+ let na = Number(a2), nb = Number(b2);
6699
+ return Number.isNaN(na) || Number.isNaN(nb) ? a2.localeCompare(b2, void 0, { numeric: !0 }) > 0 : na > nb;
5813
6700
  }
5814
- function equalMap(left, right) {
5815
- if (left.size !== right.size)
5816
- return !1;
5817
- for (let index of left.entries())
5818
- if (!right.has(index[0]))
5819
- return !1;
5820
- for (let index of left.entries())
5821
- if (!equal(index[1], right.get(index[0])))
5822
- return !1;
5823
- return !0;
6701
+
6702
+ // ../../node_modules/es-toolkit/dist/function/debounce.mjs
6703
+ function debounce(func, debounceMs, { signal, edges } = {}) {
6704
+ let pendingThis, pendingArgs = null, leading = edges != null && edges.includes("leading"), trailing = edges == null || edges.includes("trailing"), invoke = () => {
6705
+ pendingArgs !== null && (func.apply(pendingThis, pendingArgs), pendingThis = void 0, pendingArgs = null);
6706
+ }, onTimerEnd = () => {
6707
+ trailing && invoke(), cancel();
6708
+ }, timeoutId = null, schedule = () => {
6709
+ timeoutId != null && clearTimeout(timeoutId), timeoutId = setTimeout(() => {
6710
+ timeoutId = null, onTimerEnd();
6711
+ }, debounceMs);
6712
+ }, cancelTimer = () => {
6713
+ timeoutId !== null && (clearTimeout(timeoutId), timeoutId = null);
6714
+ }, cancel = () => {
6715
+ cancelTimer(), pendingThis = void 0, pendingArgs = null;
6716
+ }, flush = () => {
6717
+ invoke();
6718
+ }, debounced = function(...args) {
6719
+ if (signal?.aborted)
6720
+ return;
6721
+ pendingThis = this, pendingArgs = args;
6722
+ let isFirstCall = timeoutId == null;
6723
+ schedule(), leading && isFirstCall && invoke();
6724
+ };
6725
+ return debounced.schedule = schedule, debounced.cancel = cancel, debounced.flush = flush, signal?.addEventListener("abort", cancel, { once: !0 }), debounced;
5824
6726
  }
5825
- function equalSet(left, right) {
5826
- if (left.size !== right.size)
5827
- return !1;
5828
- for (let index of left.entries())
5829
- if (!right.has(index[0]))
5830
- return !1;
5831
- return !0;
6727
+
6728
+ // ../../node_modules/es-toolkit/dist/function/partial.mjs
6729
+ function partial(func, ...partialArgs) {
6730
+ return partialImpl(func, placeholderSymbol, ...partialArgs);
5832
6731
  }
5833
- function equal(left, right) {
5834
- if (left === right)
5835
- return !0;
5836
- if (left && isObject(left) && right && isObject(right)) {
5837
- if (left.constructor !== right.constructor)
5838
- return !1;
5839
- if (Array.isArray(left) && Array.isArray(right))
5840
- return equalArray(left, right);
5841
- if (left instanceof Map && right instanceof Map)
5842
- return equalMap(left, right);
5843
- if (left instanceof Set && right instanceof Set)
5844
- return equalSet(left, right);
5845
- if (ArrayBuffer.isView(left) && ArrayBuffer.isView(right))
5846
- return equalArrayBuffer(left, right);
5847
- if (isRegex(left) && isRegex(right))
5848
- return left.source === right.source && left.flags === right.flags;
5849
- if (left.valueOf !== Object.prototype.valueOf)
5850
- return left.valueOf() === right.valueOf();
5851
- if (left.toString !== Object.prototype.toString)
5852
- return left.toString() === right.toString();
5853
- let leftKeys = Object.keys(left), rightKeys = Object.keys(right);
5854
- if (leftKeys.length !== rightKeys.length)
5855
- return !1;
5856
- for (let index = leftKeys.length; index-- !== 0; )
5857
- if (!Object.prototype.hasOwnProperty.call(right, leftKeys[index]))
5858
- return !1;
5859
- for (let index = leftKeys.length; index-- !== 0; ) {
5860
- let key = leftKeys[index];
5861
- if (!(key === "_owner" && left.$$typeof) && !equal(left[key], right[key]))
5862
- return !1;
6732
+ function partialImpl(func, placeholder, ...partialArgs) {
6733
+ let partialed = function(...providedArgs) {
6734
+ let providedArgsIndex = 0, substitutedArgs = partialArgs.slice().map((arg) => arg === placeholder ? providedArgs[providedArgsIndex++] : arg), remainingArgs = providedArgs.slice(providedArgsIndex);
6735
+ return func.apply(this, substitutedArgs.concat(remainingArgs));
6736
+ };
6737
+ return func.prototype && (partialed.prototype = Object.create(func.prototype)), partialed;
6738
+ }
6739
+ var placeholderSymbol = Symbol("partial.placeholder");
6740
+ partial.placeholder = placeholderSymbol;
6741
+
6742
+ // ../../node_modules/es-toolkit/dist/function/partialRight.mjs
6743
+ function partialRight(func, ...partialArgs) {
6744
+ return partialRightImpl(func, placeholderSymbol2, ...partialArgs);
6745
+ }
6746
+ function partialRightImpl(func, placeholder, ...partialArgs) {
6747
+ let partialedRight = function(...providedArgs) {
6748
+ let placeholderLength = partialArgs.filter((arg) => arg === placeholder).length, rangeLength = Math.max(providedArgs.length - placeholderLength, 0), remainingArgs = providedArgs.slice(0, rangeLength), providedArgsIndex = rangeLength, substitutedArgs = partialArgs.slice().map((arg) => arg === placeholder ? providedArgs[providedArgsIndex++] : arg);
6749
+ return func.apply(this, remainingArgs.concat(substitutedArgs));
6750
+ };
6751
+ return func.prototype && (partialedRight.prototype = Object.create(func.prototype)), partialedRight;
6752
+ }
6753
+ var placeholderSymbol2 = Symbol("partialRight.placeholder");
6754
+ partialRight.placeholder = placeholderSymbol2;
6755
+
6756
+ // ../../node_modules/es-toolkit/dist/function/retry.mjs
6757
+ var DEFAULT_RETRIES = Number.POSITIVE_INFINITY;
6758
+
6759
+ // ../../node_modules/es-toolkit/dist/function/throttle.mjs
6760
+ function throttle(func, throttleMs, { signal, edges = ["leading", "trailing"] } = {}) {
6761
+ let pendingAt = null, debounced = debounce(function(...args) {
6762
+ pendingAt = Date.now(), func.apply(this, args);
6763
+ }, throttleMs, { signal, edges }), throttled = function(...args) {
6764
+ if (pendingAt == null && (pendingAt = Date.now()), Date.now() - pendingAt >= throttleMs) {
6765
+ pendingAt = Date.now(), func.apply(this, args), debounced.cancel(), debounced.schedule();
6766
+ return;
5863
6767
  }
5864
- return !0;
5865
- }
5866
- return Number.isNaN(left) && Number.isNaN(right) ? !0 : left === right;
6768
+ debounced.apply(this, args);
6769
+ };
6770
+ return throttled.cancel = debounced.cancel, throttled.flush = debounced.flush, throttled;
5867
6771
  }
5868
6772
 
5869
- // ../../node_modules/is-lite/dist/index.mjs
5870
- var objectTypes = [
5871
- "Array",
5872
- "ArrayBuffer",
6773
+ // ../addons/a11y/src/constants.ts
6774
+ var ADDON_ID2 = "storybook/a11y", PANEL_ID2 = `${ADDON_ID2}/panel`;
6775
+ var UI_STATE_ID = `${ADDON_ID2}/ui`, RESULT = `${ADDON_ID2}/result`, REQUEST = `${ADDON_ID2}/request`, RUNNING = `${ADDON_ID2}/running`, ERROR = `${ADDON_ID2}/error`, MANUAL = `${ADDON_ID2}/manual`, SELECT = `${ADDON_ID2}/select`, DOCUMENTATION_LINK = "writing-tests/accessibility-testing", DOCUMENTATION_DISCREPANCY_LINK = `${DOCUMENTATION_LINK}#why-are-my-tests-failing-in-different-environments`;
6776
+
6777
+ // ../addons/onboarding/src/constants.ts
6778
+ var ADDON_ID3 = "storybook/onboarding", ADDON_ONBOARDING_CHANNEL = `${ADDON_ID3}/channel`;
6779
+
6780
+ // src/component-testing/constants.ts
6781
+ var ADDON_ID4 = "storybook/interactions", PANEL_ID3 = `${ADDON_ID4}/panel`;
6782
+ var DOCUMENTATION_LINK2 = "writing-tests/integrations/vitest-addon", DOCUMENTATION_DISCREPANCY_LINK2 = `${DOCUMENTATION_LINK2}#what-happens-when-there-are-different-test-results-in-multiple-environments`;
6783
+
6784
+ // ../addons/vitest/src/constants.ts
6785
+ var ADDON_ID5 = "storybook/test", TEST_PROVIDER_ID = `${ADDON_ID5}/test-provider`, STORYBOOK_ADDON_TEST_CHANNEL = `${ADDON_ID5}/channel`;
6786
+ var DOCUMENTATION_LINK3 = "writing-tests/integrations/vitest-addon", DOCUMENTATION_FATAL_ERROR_LINK = `${DOCUMENTATION_LINK3}#what-happens-if-vitest-itself-has-an-error`;
6787
+ var storeOptions = {
6788
+ id: ADDON_ID5,
6789
+ initialState: {
6790
+ config: {
6791
+ coverage: !1,
6792
+ a11y: !1
6793
+ },
6794
+ watching: !1,
6795
+ cancelling: !1,
6796
+ fatalError: void 0,
6797
+ indexUrl: void 0,
6798
+ previewAnnotations: [],
6799
+ currentRun: {
6800
+ triggeredBy: void 0,
6801
+ config: {
6802
+ coverage: !1,
6803
+ a11y: !1
6804
+ },
6805
+ componentTestCount: {
6806
+ success: 0,
6807
+ error: 0
6808
+ },
6809
+ a11yCount: {
6810
+ success: 0,
6811
+ warning: 0,
6812
+ error: 0
6813
+ },
6814
+ storyIds: void 0,
6815
+ totalTestCount: void 0,
6816
+ startedAt: void 0,
6817
+ finishedAt: void 0,
6818
+ unhandledErrors: [],
6819
+ coverageSummary: void 0
6820
+ }
6821
+ }
6822
+ };
6823
+ var STORE_CHANNEL_EVENT_NAME = `UNIVERSAL_STORE:${storeOptions.id}`;
6824
+
6825
+ // src/cli/AddonVitestService.constants.ts
6826
+ var SUPPORTED_FRAMEWORKS = [
6827
+ "html-vite" /* HTML_VITE */,
6828
+ "nextjs-vite" /* NEXTJS_VITE */,
6829
+ "preact-vite" /* PREACT_VITE */,
6830
+ "react-native-web-vite" /* REACT_NATIVE_WEB_VITE */,
6831
+ "react-vite" /* REACT_VITE */,
6832
+ "solid" /* SOLID */,
6833
+ "svelte-vite" /* SVELTE_VITE */,
6834
+ "sveltekit" /* SVELTEKIT */,
6835
+ "vue3-vite" /* VUE3_VITE */,
6836
+ "web-components-vite" /* WEB_COMPONENTS_VITE */
6837
+ ];
6838
+
6839
+ // src/docs-tools/shared.ts
6840
+ var ADDON_ID6 = "storybook/docs", PANEL_ID4 = `${ADDON_ID6}/panel`;
6841
+ var SNIPPET_RENDERED = `${ADDON_ID6}/snippet-rendered`;
6842
+
6843
+ // ../../node_modules/@gilbarbara/deep-equal/dist/index.mjs
6844
+ function isOfType(type) {
6845
+ return (value) => typeof value === type;
6846
+ }
6847
+ var isFunction = isOfType("function"), isNull = (value) => value === null, isRegex = (value) => Object.prototype.toString.call(value).slice(8, -1) === "RegExp", isObject = (value) => !isUndefined(value) && !isNull(value) && (isFunction(value) || typeof value == "object"), isUndefined = isOfType("undefined");
6848
+ function equalArray(left, right) {
6849
+ let { length } = left;
6850
+ if (length !== right.length)
6851
+ return !1;
6852
+ for (let index = length; index-- !== 0; )
6853
+ if (!equal(left[index], right[index]))
6854
+ return !1;
6855
+ return !0;
6856
+ }
6857
+ function equalArrayBuffer(left, right) {
6858
+ if (left.byteLength !== right.byteLength)
6859
+ return !1;
6860
+ let view1 = new DataView(left.buffer), view2 = new DataView(right.buffer), index = left.byteLength;
6861
+ for (; index--; )
6862
+ if (view1.getUint8(index) !== view2.getUint8(index))
6863
+ return !1;
6864
+ return !0;
6865
+ }
6866
+ function equalMap(left, right) {
6867
+ if (left.size !== right.size)
6868
+ return !1;
6869
+ for (let index of left.entries())
6870
+ if (!right.has(index[0]))
6871
+ return !1;
6872
+ for (let index of left.entries())
6873
+ if (!equal(index[1], right.get(index[0])))
6874
+ return !1;
6875
+ return !0;
6876
+ }
6877
+ function equalSet(left, right) {
6878
+ if (left.size !== right.size)
6879
+ return !1;
6880
+ for (let index of left.entries())
6881
+ if (!right.has(index[0]))
6882
+ return !1;
6883
+ return !0;
6884
+ }
6885
+ function equal(left, right) {
6886
+ if (left === right)
6887
+ return !0;
6888
+ if (left && isObject(left) && right && isObject(right)) {
6889
+ if (left.constructor !== right.constructor)
6890
+ return !1;
6891
+ if (Array.isArray(left) && Array.isArray(right))
6892
+ return equalArray(left, right);
6893
+ if (left instanceof Map && right instanceof Map)
6894
+ return equalMap(left, right);
6895
+ if (left instanceof Set && right instanceof Set)
6896
+ return equalSet(left, right);
6897
+ if (ArrayBuffer.isView(left) && ArrayBuffer.isView(right))
6898
+ return equalArrayBuffer(left, right);
6899
+ if (isRegex(left) && isRegex(right))
6900
+ return left.source === right.source && left.flags === right.flags;
6901
+ if (left.valueOf !== Object.prototype.valueOf)
6902
+ return left.valueOf() === right.valueOf();
6903
+ if (left.toString !== Object.prototype.toString)
6904
+ return left.toString() === right.toString();
6905
+ let leftKeys = Object.keys(left), rightKeys = Object.keys(right);
6906
+ if (leftKeys.length !== rightKeys.length)
6907
+ return !1;
6908
+ for (let index = leftKeys.length; index-- !== 0; )
6909
+ if (!Object.prototype.hasOwnProperty.call(right, leftKeys[index]))
6910
+ return !1;
6911
+ for (let index = leftKeys.length; index-- !== 0; ) {
6912
+ let key = leftKeys[index];
6913
+ if (!(key === "_owner" && left.$$typeof) && !equal(left[key], right[key]))
6914
+ return !1;
6915
+ }
6916
+ return !0;
6917
+ }
6918
+ return Number.isNaN(left) && Number.isNaN(right) ? !0 : left === right;
6919
+ }
6920
+
6921
+ // ../../node_modules/is-lite/dist/index.mjs
6922
+ var objectTypes = [
6923
+ "Array",
6924
+ "ArrayBuffer",
5873
6925
  "AsyncFunction",
5874
6926
  "AsyncGenerator",
5875
6927
  "AsyncGeneratorFunction",
@@ -9714,7 +10766,7 @@ function HighlightElement({
9714
10766
  var ONBOARDING_ARROW_STYLE_ID = "storybook-onboarding-arrow-style", TooltipBody = styled.div`
9715
10767
  padding: 15px;
9716
10768
  border-radius: 5px;
9717
- `, Wrapper = styled.div`
10769
+ `, Wrapper4 = styled.div`
9718
10770
  display: flex;
9719
10771
  flex-direction: column;
9720
10772
  align-items: flex-start;
@@ -9778,7 +10830,7 @@ var ONBOARDING_ARROW_STYLE_ID = "storybook-onboarding-arrow-style", TooltipBody
9778
10830
  .__floater__arrow span { flex-direction: column; }
9779
10831
  }
9780
10832
  `, document.head.appendChild(style), () => document.getElementById(ONBOARDING_ARROW_STYLE_ID)?.remove();
9781
- }, []), react_default.createElement(TooltipBody, { ...tooltipProps, style: step.styles?.tooltip }, react_default.createElement(Wrapper, null, react_default.createElement(TooltipHeader, null, step.title && react_default.createElement(TooltipTitle, null, step.title), react_default.createElement(
10833
+ }, []), react_default.createElement(TooltipBody, { ...tooltipProps, style: step.styles?.tooltip }, react_default.createElement(Wrapper4, null, react_default.createElement(TooltipHeader, null, step.title && react_default.createElement(TooltipTitle, null, step.title), react_default.createElement(
9782
10834
  Button,
9783
10835
  {
9784
10836
  ...closeProps,
@@ -9943,7 +10995,7 @@ var CodeWrapper = styled.div(({ theme }) => ({
9943
10995
  {
9944
10996
  id: "guidedTour",
9945
10997
  label: "Take the guided tour",
9946
- available: ({ index }) => !!index && "example-button--primary" in index && !!globalThis?.FEATURES?.controls && addons.experimental_getRegisteredAddons().includes(ADDON_ID2),
10998
+ available: ({ index }) => !!index && "example-button--primary" in index && !!globalThis?.FEATURES?.controls && addons.experimental_getRegisteredAddons().includes(ADDON_ID3),
9947
10999
  criteria: "Guided tour is completed",
9948
11000
  subscribe: ({ api, accept }) => api.on(ADDON_ONBOARDING_CHANNEL, ({ step, type }) => {
9949
11001
  type !== "dismiss" && ["6:IntentSurvey", "7:FinishedOnboarding"].includes(step) && accept();
@@ -9959,7 +11011,7 @@ var CodeWrapper = styled.div(({ theme }) => ({
9959
11011
  {
9960
11012
  id: "onboardingSurvey",
9961
11013
  label: "Complete the onboarding survey",
9962
- available: () => addons.experimental_getRegisteredAddons().includes(ADDON_ID2),
11014
+ available: () => addons.experimental_getRegisteredAddons().includes(ADDON_ID3),
9963
11015
  afterCompletion: "immutable",
9964
11016
  criteria: "Onboarding survey is completed",
9965
11017
  subscribe: ({ api, accept }) => api.on(ADDON_ONBOARDING_CHANNEL, ({ type }) => type === "survey" && accept()),
@@ -10219,7 +11271,7 @@ export default {
10219
11271
  available: () => !!globalThis.STORYBOOK_FRAMEWORK && SUPPORTED_FRAMEWORKS.includes(globalThis.STORYBOOK_FRAMEWORK),
10220
11272
  criteria: "@storybook/addon-vitest registered in .storybook/main.js|ts",
10221
11273
  subscribe: ({ done }) => {
10222
- addons.experimental_getRegisteredAddons().includes(ADDON_ID4) && done();
11274
+ addons.experimental_getRegisteredAddons().includes(ADDON_ID5) && done();
10223
11275
  },
10224
11276
  content: ({ api }) => react_default.createElement(react_default.Fragment, null, react_default.createElement("p", null, "Run this command to install the Vitest addon, enabling you to run component tests on your stories inside Storybook\u2019s UI:"), react_default.createElement(CodeSnippet, { language: "bash" }, "npx storybook add @storybook/addon-vitest"), react_default.createElement("p", null, react_default.createElement("em", null, "Restart your Storybook after installing the addon.")), react_default.createElement(
10225
11277
  "img",
@@ -10382,7 +11434,7 @@ export const Disabled: Story = {
10382
11434
  afterCompletion: "unavailable",
10383
11435
  criteria: "@storybook/addon-a11y registered in .storybook/main.js|ts",
10384
11436
  subscribe: ({ done }) => {
10385
- addons.experimental_getRegisteredAddons().includes(ADDON_ID) && done();
11437
+ addons.experimental_getRegisteredAddons().includes(ADDON_ID2) && done();
10386
11438
  },
10387
11439
  content: ({ api }) => react_default.createElement(react_default.Fragment, null, react_default.createElement("p", null, "Accessibility tests help ensure your UI is usable by everyone, no matter their ability."), react_default.createElement("p", null, "If you are not yet using the accessibility addon, run this command to install and set it up, enabling you to run accessibility checks alongside your component tests:"), react_default.createElement(CodeSnippet, { language: "bash" }, "npx storybook add @storybook/addon-a11y"), react_default.createElement("p", null, react_default.createElement("em", null, "Restart your Storybook after installing the addon.")), react_default.createElement("p", null, react_default.createElement(
10388
11440
  Link,
@@ -10568,7 +11620,7 @@ export const Disabled: Story = {
10568
11620
  afterCompletion: "unavailable",
10569
11621
  criteria: "@storybook/addon-docs registered in .storybook/main.js|ts",
10570
11622
  subscribe: ({ done }) => {
10571
- addons.experimental_getRegisteredAddons().includes(ADDON_ID5) && done();
11623
+ addons.experimental_getRegisteredAddons().includes(ADDON_ID6) && done();
10572
11624
  },
10573
11625
  content: ({ api }) => react_default.createElement(react_default.Fragment, null, react_default.createElement("p", null, "Storybook Docs transforms your Storybook stories into component documentation. Add the Docs addon to your Storybook project to get started:"), react_default.createElement(CodeSnippet, { language: "bash" }, "npx storybook add @storybook/addon-docs"), react_default.createElement("p", null, react_default.createElement("em", null, "Restart your Storybook after installing the addon.")), react_default.createElement("p", null, react_default.createElement(
10574
11626
  Link,
@@ -10749,529 +11801,45 @@ var subscriptions = /* @__PURE__ */ new Map(), useStoryIndex = () => {
10749
11801
  let availableItems = allItems.filter((item) => item.isAvailable), openItems = availableItems.filter((item) => item.isOpen), readyItems = openItems.filter((item) => item.isReady), nextItems = Object.values(
10750
11802
  readyItems.reduce((acc, item) => (acc[item.sectionId] ??= [], acc[item.sectionId].push({ ...item, itemIndex: acc[item.sectionId].length }), acc), {})
10751
11803
  ).flat().sort((a2, b2) => a2.itemIndex - b2.itemIndex).slice(0, 3).sort((a2, b2) => a2.sectionIndex - b2.sectionIndex), progress = availableItems.length ? Math.round((availableItems.length - openItems.length) / availableItems.length * 100) : 100;
10752
- return { availableItems, openItems, readyItems, nextItems, progress };
10753
- }, [allItems]);
10754
- return useEffect(() => {
10755
- if (!(!loaded || status !== experimental_UniversalStore.Status.READY))
10756
- for (let item of allItems) {
10757
- if (!item.subscribe)
10758
- continue;
10759
- let subscribed = subscriptions.has(item.id);
10760
- if (item.isOpen && item.isAvailable && !subscribed)
10761
- subscriptions.set(
10762
- item.id,
10763
- item.subscribe({
10764
- api,
10765
- item,
10766
- accept: () => internal_checklistStore.accept(item.id),
10767
- done: () => internal_checklistStore.done(item.id),
10768
- skip: () => internal_checklistStore.skip(item.id)
10769
- })
10770
- );
10771
- else if (subscribed && !(item.isOpen && item.isAvailable)) {
10772
- let unsubscribe = subscriptions.get(item.id);
10773
- subscriptions.delete(item.id), typeof unsubscribe == "function" && unsubscribe();
10774
- }
10775
- }
10776
- }, [api, loaded, status, allItems]), useEffect(() => {
10777
- let initialize = () => setInitialized(!0), timeout = setTimeout(initialize, 1e3);
10778
- return api.once(PREVIEW_INITIALIZED, initialize), () => {
10779
- clearTimeout(timeout), api.off(PREVIEW_INITIALIZED, initialize);
10780
- };
10781
- }, [api]), useEffect(() => {
10782
- initialized && items && status === experimental_UniversalStore.Status.READY && debounceReady();
10783
- }, [initialized, items, status, debounceReady]), {
10784
- ready,
10785
- allItems,
10786
- ...itemCollections,
10787
- ...internal_checklistStore,
10788
- ...checklistState
10789
- };
10790
- };
10791
-
10792
- // src/manager/container/Menu.tsx
10793
- var Key = styled.span(({ theme }) => ({
10794
- display: "inline-flex",
10795
- alignItems: "center",
10796
- justifyContent: "center",
10797
- height: 16,
10798
- fontSize: "11px",
10799
- fontWeight: theme.typography.weight.regular,
10800
- background: theme.base === "light" ? "rgba(0,0,0,0.05)" : "rgba(255,255,255,0.05)",
10801
- color: theme.base === "light" ? theme.color.dark : theme.textMutedColor,
10802
- borderRadius: 2,
10803
- userSelect: "none",
10804
- pointerEvents: "none",
10805
- padding: "0 4px"
10806
- })), KeyChild = styled.code(({ theme }) => ({
10807
- padding: 0,
10808
- fontFamily: theme.typography.fonts.base,
10809
- verticalAlign: "middle",
10810
- "& + &": {
10811
- marginLeft: 6
10812
- }
10813
- })), ProgressCircle = styled(ProgressSpinner)(({ theme }) => ({
10814
- color: theme.color.secondary
10815
- })), Shortcut = ({ keys }) => react_default.createElement(Key, null, keys.map((key) => react_default.createElement(KeyChild, { key }, shortcutToHumanString([key])))), useMenu = ({
10816
- api,
10817
- showToolbar,
10818
- isPanelShown,
10819
- isNavShown,
10820
- enableShortcuts
10821
- }) => {
10822
- let shortcutKeys = api.getShortcutKeys(), { progress } = useChecklist(), about = useMemo(
10823
- () => ({
10824
- id: "about",
10825
- title: "About your Storybook",
10826
- onClick: () => api.changeSettingsTab("about"),
10827
- closeOnClick: !0,
10828
- icon: react_default.createElement(InfoIcon, null)
10829
- }),
10830
- [api]
10831
- ), guide = useMemo(
10832
- () => ({
10833
- id: "guide",
10834
- title: "Onboarding guide",
10835
- onClick: () => api.changeSettingsTab("guide"),
10836
- closeOnClick: !0,
10837
- icon: react_default.createElement(ListUnorderedIcon, null),
10838
- right: progress < 100 && react_default.createElement(ActionList.Button, { as: "div", readOnly: !0, padding: "none", ariaLabel: `${progress}% completed` }, react_default.createElement(ProgressCircle, { percentage: progress, running: !1, size: 16, width: 1.5 }), progress, "%")
10839
- }),
10840
- [api, progress]
10841
- ), shortcuts = useMemo(
10842
- () => ({
10843
- id: "shortcuts",
10844
- title: "Keyboard shortcuts",
10845
- onClick: () => api.changeSettingsTab("shortcuts"),
10846
- closeOnClick: !0,
10847
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.shortcutsPage }) : null,
10848
- icon: react_default.createElement(CommandIcon, null)
10849
- }),
10850
- [api, enableShortcuts, shortcutKeys.shortcutsPage]
10851
- ), sidebarToggle = useMemo(
10852
- () => ({
10853
- id: "S",
10854
- title: "Show sidebar",
10855
- onClick: () => api.toggleNav(),
10856
- closeOnClick: !0,
10857
- active: isNavShown,
10858
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.toggleNav }) : null,
10859
- icon: isNavShown ? react_default.createElement(CheckIcon, null) : react_default.createElement(react_default.Fragment, null)
10860
- }),
10861
- [api, enableShortcuts, shortcutKeys, isNavShown]
10862
- ), toolbarToogle = useMemo(
10863
- () => ({
10864
- id: "T",
10865
- title: "Show toolbar",
10866
- onClick: () => api.toggleToolbar(),
10867
- active: showToolbar,
10868
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.toolbar }) : null,
10869
- icon: showToolbar ? react_default.createElement(CheckIcon, null) : react_default.createElement(react_default.Fragment, null)
10870
- }),
10871
- [api, enableShortcuts, shortcutKeys, showToolbar]
10872
- ), addonsToggle = useMemo(
10873
- () => ({
10874
- id: "A",
10875
- title: "Show addons panel",
10876
- onClick: () => api.togglePanel(),
10877
- active: isPanelShown,
10878
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.togglePanel }) : null,
10879
- icon: isPanelShown ? react_default.createElement(CheckIcon, null) : react_default.createElement(react_default.Fragment, null)
10880
- }),
10881
- [api, enableShortcuts, shortcutKeys, isPanelShown]
10882
- ), up = useMemo(
10883
- () => ({
10884
- id: "up",
10885
- title: "Previous component",
10886
- onClick: () => api.jumpToComponent(-1),
10887
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.prevComponent }) : null,
10888
- icon: react_default.createElement(react_default.Fragment, null)
10889
- }),
10890
- [api, enableShortcuts, shortcutKeys]
10891
- ), down = useMemo(
10892
- () => ({
10893
- id: "down",
10894
- title: "Next component",
10895
- onClick: () => api.jumpToComponent(1),
10896
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.nextComponent }) : null,
10897
- icon: react_default.createElement(react_default.Fragment, null)
10898
- }),
10899
- [api, enableShortcuts, shortcutKeys]
10900
- ), prev = useMemo(
10901
- () => ({
10902
- id: "prev",
10903
- title: "Previous story",
10904
- onClick: () => api.jumpToStory(-1),
10905
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.prevStory }) : null,
10906
- icon: react_default.createElement(react_default.Fragment, null)
10907
- }),
10908
- [api, enableShortcuts, shortcutKeys]
10909
- ), next = useMemo(
10910
- () => ({
10911
- id: "next",
10912
- title: "Next story",
10913
- onClick: () => api.jumpToStory(1),
10914
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.nextStory }) : null,
10915
- icon: react_default.createElement(react_default.Fragment, null)
10916
- }),
10917
- [api, enableShortcuts, shortcutKeys]
10918
- ), collapse = useMemo(
10919
- () => ({
10920
- id: "collapse",
10921
- title: "Collapse all",
10922
- onClick: () => api.emit(STORIES_COLLAPSE_ALL),
10923
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.collapseAll }) : null,
10924
- icon: react_default.createElement(react_default.Fragment, null)
10925
- }),
10926
- [api, enableShortcuts, shortcutKeys]
10927
- ), documentation = useMemo(() => ({
10928
- id: "documentation",
10929
- title: "Documentation",
10930
- closeOnClick: !0,
10931
- href: api.getDocsUrl({ versioned: !0, renderer: !0 }),
10932
- right: react_default.createElement(ActionList.Icon, null, react_default.createElement(ShareAltIcon, null)),
10933
- icon: react_default.createElement(DocumentIcon, null)
10934
- }), [api]), getAddonsShortcuts = useCallback(() => {
10935
- let addonsShortcuts = api.getAddonsShortcuts(), keys = shortcutKeys;
10936
- return Object.entries(addonsShortcuts).filter(([_2, { showInMenu }]) => showInMenu).map(([actionName, { label, action }]) => ({
10937
- id: actionName,
10938
- title: label,
10939
- onClick: () => action(),
10940
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: keys[actionName] }) : null
10941
- }));
10942
- }, [api, enableShortcuts, shortcutKeys]);
10943
- return useMemo(
10944
- () => [
10945
- [
10946
- about,
10947
- ...scope.CONFIG_TYPE === "DEVELOPMENT" ? [guide] : [],
10948
- ...enableShortcuts ? [shortcuts] : []
10949
- ],
10950
- [sidebarToggle, toolbarToogle, addonsToggle, up, down, prev, next, collapse],
10951
- getAddonsShortcuts(),
10952
- [documentation]
10953
- ],
10954
- [
10955
- about,
10956
- guide,
10957
- documentation,
10958
- shortcuts,
10959
- sidebarToggle,
10960
- toolbarToogle,
10961
- addonsToggle,
10962
- up,
10963
- down,
10964
- prev,
10965
- next,
10966
- collapse,
10967
- getAddonsShortcuts,
10968
- enableShortcuts
10969
- ]
10970
- );
10971
- };
10972
-
10973
- // src/manager/components/preview/tools/share.tsx
10974
- var mapper3 = ({ api, state }) => {
10975
- let { storyId, refId } = state;
10976
- return { api, refId, storyId };
10977
- }, QRContainer = styled.div(() => ({
10978
- display: "flex",
10979
- alignItems: "center",
10980
- padding: 8,
10981
- maxWidth: 200
10982
- })), QRImageContainer = styled.div(() => ({
10983
- width: 64,
10984
- height: 64,
10985
- marginRight: 12,
10986
- backgroundColor: "white",
10987
- padding: 2
10988
- })), QRImage = ({ value }) => {
10989
- let theme = useTheme();
10990
- return react_default.createElement(QRImageContainer, null, react_default.createElement(QRCodeSVG, { value, marginSize: 0, size: 60, fgColor: theme.color.darkest }));
10991
- }, QRContent = styled.div(() => ({})), QRTitle = styled.div(({ theme }) => ({
10992
- fontWeight: theme.typography.weight.bold,
10993
- fontSize: theme.typography.size.s1,
10994
- marginBottom: 4
10995
- })), QRDescription = styled.div(({ theme }) => ({
10996
- fontSize: theme.typography.size.s1,
10997
- color: theme.textMutedColor
10998
- })), ShareMenu = react_default.memo(function({
10999
- api,
11000
- storyId,
11001
- refId
11002
- }) {
11003
- let shortcutKeys = api.getShortcutKeys(), enableShortcuts = !!shortcutKeys, [copied, setCopied] = useState(!1), copyStoryLink = shortcutKeys?.copyStoryLink, openInIsolation = shortcutKeys?.openInIsolation, links = useMemo(() => {
11004
- let copyTitle = copied ? "Copied!" : "Copy story link", originHrefs = api.getStoryHrefs(storyId, { base: "origin", refId }), networkHrefs = api.getStoryHrefs(storyId, { base: "network", refId });
11005
- return [
11006
- [
11007
- {
11008
- id: "copy-link",
11009
- title: copyTitle,
11010
- icon: react_default.createElement(LinkIcon, null),
11011
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: copyStoryLink }) : null,
11012
- onClick: () => {
11013
- (0, import_copy_to_clipboard.default)(originHrefs.managerHref), setCopied(!0), setTimeout(() => setCopied(!1), 2e3);
11014
- }
11015
- },
11016
- {
11017
- id: "open-new-tab",
11018
- title: "Open in isolation mode",
11019
- icon: react_default.createElement(ShareAltIcon, null),
11020
- right: enableShortcuts ? react_default.createElement(Shortcut, { keys: openInIsolation }) : null,
11021
- href: originHrefs.previewHref,
11022
- target: "_blank",
11023
- rel: "noopener noreferrer"
11024
- }
11025
- ],
11026
- [
11027
- {
11028
- id: "qr-section",
11029
- content: react_default.createElement(QRContainer, null, react_default.createElement(QRImage, { value: networkHrefs.managerHref }), react_default.createElement(QRContent, null, react_default.createElement(QRTitle, null, "Scan to open"), react_default.createElement(QRDescription, null, scope.CONFIG_TYPE === "DEVELOPMENT" ? "Device must be on the same network." : "View story on another device.")))
11030
- }
11031
- ]
11032
- ];
11033
- }, [api, storyId, refId, copied, enableShortcuts, copyStoryLink, openInIsolation]);
11034
- return react_default.createElement(TooltipLinkList, { links, style: { width: 240 } });
11035
- }), shareTool = {
11036
- title: "share",
11037
- id: "share",
11038
- type: types.TOOL,
11039
- match: ({ viewMode, tabId }) => viewMode === "story" && !tabId,
11040
- render: () => react_default.createElement(Consumer, { filter: mapper3 }, ({ api, storyId, refId }) => storyId ? react_default.createElement(
11041
- PopoverProvider,
11042
- {
11043
- hasChrome: !0,
11044
- placement: "bottom",
11045
- padding: 0,
11046
- popover: react_default.createElement(ShareMenu, { api, storyId, refId })
11047
- },
11048
- react_default.createElement(Button, { padding: "small", variant: "ghost", ariaLabel: "Share", tooltip: "Share..." }, react_default.createElement(ShareIcon, null))
11049
- ) : null)
11050
- };
11051
-
11052
- // src/manager/container/Preview.tsx
11053
- var defaultTabs = [createCanvasTab()], defaultTools = [menuTool, remountTool, zoomTool], defaultToolsExtra = [addonsTool, fullScreenTool, shareTool, openInEditorTool], emptyTabsList = [], memoizedTabs = (0, import_memoizerific.default)(1)(
11054
- (_2, tabElements, parameters, showTabs) => showTabs ? filterTabs([...defaultTabs, ...Object.values(tabElements)], parameters) : emptyTabsList
11055
- ), memoizedTools = (0, import_memoizerific.default)(1)(
11056
- (_2, toolElements, filterProps) => filterToolsSide([...defaultTools, ...Object.values(toolElements)], ...filterProps)
11057
- ), memoizedExtra = (0, import_memoizerific.default)(1)(
11058
- (_2, extraElements, filterProps) => filterToolsSide([...defaultToolsExtra, ...Object.values(extraElements)], ...filterProps)
11059
- ), memoizedWrapper = (0, import_memoizerific.default)(1)((_2, previewElements) => [
11060
- ...defaultWrappers,
11061
- ...Object.values(previewElements)
11062
- ]), { PREVIEW_URL } = scope, splitTitleAddExtraSpace = (input) => input.split("/").join(" / ").replace(/\s\s/, " "), getDescription = (item) => {
11063
- if (item?.type === "story" || item?.type === "docs") {
11064
- let { title: title2, name } = item;
11065
- return title2 && name ? splitTitleAddExtraSpace(`${title2} - ${name} \u22C5 Storybook`) : "Storybook";
11066
- }
11067
- return item?.name ? `${item.name} \u22C5 Storybook` : "Storybook";
11068
- }, mapper4 = ({
11069
- api,
11070
- state
11071
- // @ts-expect-error (non strict)
11072
- }) => {
11073
- let { layout, location: location2, customQueryParams, storyId, refs, viewMode, path, refId } = state, entry = api.getData(storyId, refId), tabsList = Object.values(api.getElements(Addon_TypesEnum.TAB)), wrapperList = Object.values(api.getElements(Addon_TypesEnum.PREVIEW)), toolsList = Object.values(api.getElements(Addon_TypesEnum.TOOL)), toolsExtraList = Object.values(api.getElements(Addon_TypesEnum.TOOLEXTRA)), tabId = api.getQueryParam("tab"), tools = memoizedTools(toolsList.length, api.getElements(Addon_TypesEnum.TOOL), [
11074
- entry,
11075
- viewMode,
11076
- location2,
11077
- path,
11078
- // @ts-expect-error (non strict)
11079
- tabId
11080
- ]), toolsExtra = memoizedExtra(
11081
- toolsExtraList.length,
11082
- api.getElements(Addon_TypesEnum.TOOLEXTRA),
11083
- // @ts-expect-error (non strict)
11084
- [entry, viewMode, location2, path, tabId]
11085
- );
11086
- return {
11087
- api,
11088
- entry,
11089
- options: layout,
11090
- description: getDescription(entry),
11091
- viewMode,
11092
- refs,
11093
- storyId,
11094
- baseUrl: PREVIEW_URL || "iframe.html",
11095
- queryParams: customQueryParams,
11096
- tools,
11097
- toolsExtra,
11098
- tabs: memoizedTabs(
11099
- tabsList.length,
11100
- api.getElements(Addon_TypesEnum.TAB),
11101
- entry ? entry.parameters : void 0,
11102
- layout.showTabs
11103
- ),
11104
- wrappers: memoizedWrapper(
11105
- wrapperList.length,
11106
- api.getElements(Addon_TypesEnum.PREVIEW)
11107
- ),
11108
- tabId
11109
- };
11110
- }, PreviewConnected = react_default.memo(function(props) {
11111
- return react_default.createElement(Consumer, { filter: mapper4 }, (fromState) => react_default.createElement(Preview, { ...props, ...fromState }));
11112
- }), Preview_default = PreviewConnected;
11113
-
11114
- // src/manager/components/Optional/Optional.tsx
11115
- var Wrapper2 = styled.div({
11116
- display: "inline-grid",
11117
- gridTemplateColumns: "max-content",
11118
- overflow: "hidden"
11119
- }), Content = styled.div(({ isHidden }) => ({
11120
- display: "inline-block",
11121
- gridArea: "1/1",
11122
- opacity: isHidden === null ? 0 : 1,
11123
- visibility: isHidden ? "hidden" : "visible"
11124
- })), Optional = ({
11125
- content,
11126
- fallback
11127
- }) => {
11128
- let contentRef = useRef(null), wrapperRef = useRef(null), [hidden, setHidden] = useState(null), contentWidth = useRef(contentRef.current?.offsetWidth ?? 0), wrapperWidth = useRef(wrapperRef.current?.offsetWidth ?? 0);
11129
- return useEffect(() => {
11130
- if (contentRef.current && wrapperRef.current) {
11131
- let resizeObserver = new ResizeObserver(() => {
11132
- wrapperWidth.current = wrapperRef.current?.offsetWidth || wrapperWidth.current, contentWidth.current = contentRef.current?.offsetWidth || contentWidth.current, setHidden(contentWidth.current > wrapperWidth.current);
11133
- });
11134
- return resizeObserver.observe(wrapperRef.current), () => resizeObserver.disconnect();
11135
- }
11136
- }, []), react_default.createElement(Wrapper2, { ref: wrapperRef }, react_default.createElement(Content, { isHidden: hidden, ref: contentRef }, content), fallback && react_default.createElement(Content, { isHidden: !hidden }, fallback));
11137
- };
11138
-
11139
- // src/manager/components/Particles/Particles.tsx
11140
- var Shape = styled.svg(({ color: color2 }) => ({
11141
- fill: color2,
11142
- position: "absolute",
11143
- inset: "0",
11144
- margin: "auto",
11145
- width: "12px",
11146
- height: "12px",
11147
- pointerEvents: "none"
11148
- })), Donut = (props) => react_default.createElement(Shape, { viewBox: "0 0 90 90", xmlns: "http://www.w3.org/2000/svg", color: "red", ...props }, react_default.createElement("path", { d: "M45 0c24.853 0 45 20.147 45 45S69.853 90 45 90 0 69.853 0 45 20.147 0 45 0zm.5 27C35.283 27 27 35.283 27 45.5S35.283 64 45.5 64 64 55.717 64 45.5 55.717 27 45.5 27z" })), L2 = (props) => react_default.createElement(Shape, { viewBox: "0 0 55 89", xmlns: "http://www.w3.org/2000/svg", color: "#66BF3C", ...props }, react_default.createElement("path", { d: "M55 3v83a3 3 0 01-3 3H3a3 3 0 01-3-3V64a3 3 0 013-3h21a3 3 0 003-3V3a3 3 0 013-3h22a3 3 0 013 3z" })), Slice = (props) => react_default.createElement(Shape, { viewBox: "0 0 92 92", xmlns: "http://www.w3.org/2000/svg", color: "#FF4785", ...props }, react_default.createElement("path", { d: "M92 89V3c0-3-2.056-3-3-3C39.294 0 0 39.294 0 89c0 0 0 3 3 3h86a3 3 0 003-3z" })), Square = ({ style, ...props }) => react_default.createElement(
11149
- Shape,
11150
- {
11151
- viewBox: "0 0 90 90",
11152
- xmlns: "http://www.w3.org/2000/svg",
11153
- color: "#1EA7FD",
11154
- ...props,
11155
- style: { borderRadius: 5, ...style }
11156
- },
11157
- react_default.createElement("path", { d: "M0 0h90v90H0z" })
11158
- ), Triangle = (props) => react_default.createElement(Shape, { viewBox: "0 0 96 88", xmlns: "http://www.w3.org/2000/svg", color: "#FFAE00", ...props }, react_default.createElement("path", { d: "M50.63 1.785l44.928 81.77A3 3 0 0192.928 88H3.072a3 3 0 01-2.629-4.445l44.929-81.77a3 3 0 015.258 0z" })), T2 = (props) => react_default.createElement(Shape, { viewBox: "0 0 92 62", xmlns: "http://www.w3.org/2000/svg", color: "#FC521F", ...props }, react_default.createElement("path", { d: "M63 3v25a3 3 0 003 3h23a3 3 0 013 3v25a3 3 0 01-3 3H3a3 3 0 01-3-3V34a3 3 0 013-3h24a3 3 0 003-3V3a3 3 0 013-3h27a3 3 0 013 3z" })), Z = (props) => react_default.createElement(Shape, { viewBox: "0 0 56 90", xmlns: "http://www.w3.org/2000/svg", color: "#6F2CAC", ...props }, react_default.createElement("path", { d: "M28 3v25a3 3 0 003 3h22a3 3 0 013 3v53a3 3 0 01-3 3H31a3 3 0 01-3-3V62a3 3 0 00-3-3H3a3 3 0 01-3-3V3a3 3 0 013-3h22a3 3 0 013 3z" })), fadeToTransparent = keyframes`
11159
- to {
11160
- opacity: 0;
11161
- }
11162
- `, disperse = keyframes`
11163
- to {
11164
- transform: translate(
11165
- calc(cos(var(--angle)) * var(--distance)),
11166
- calc(sin(var(--angle)) * var(--distance))
11167
- ) rotate(var(--rotation));
11168
- }
11169
- `, slideDown = keyframes`
11170
- to {
11171
- transform: translateY(50px);
11172
- }
11173
- `, Container4 = styled.div({
11174
- position: "absolute",
11175
- display: "flex",
11176
- flexDirection: "row",
11177
- flexWrap: "wrap",
11178
- gap: 10,
11179
- "--particle-curve": "cubic-bezier(0.2, 0.56, 0, 1)",
11180
- animation: `${slideDown} 1000ms forwards cubic-bezier(0.587, -0.381, 0.583, 0.599)`,
11181
- animationDelay: "150ms",
11182
- zIndex: 999,
11183
- svg: {
11184
- width: 15,
11185
- height: 15,
11186
- animation: `${fadeToTransparent} var(--fade-duration) forwards, ${disperse} 1000ms forwards var(--particle-curve)`
11187
- }
11188
- }), FADE_DURATION = 1200, NUM_OF_PARTICLES = 8, JITTER = 15, random = (min, max) => Math.random() * (max - min) + min, sortRandomly = (array) => array.sort(() => Math.random() - 0.5), Particles = memo(function({
11189
- anchor: Anchor
11190
- }) {
11191
- let anchorRef = useRef(null), [left, setLeft] = useState(0), [top, setTop] = useState(0), shapes = sortRandomly([Donut, L2, Slice, Square, Triangle, T2, Z]), colors = sortRandomly([
11192
- "#FF0000",
11193
- "#FF4787",
11194
- "#66BF3C",
11195
- "#1EA7FD",
11196
- "#FC521F",
11197
- "#6F2CAC",
11198
- "#FFAE00"
11199
- ]);
11200
- return useLayoutEffect(() => {
11201
- let rect = anchorRef.current?.getBoundingClientRect();
11202
- rect && (setLeft(rect.left + rect.width / 2), setTop(rect.top + rect.height / 2));
11203
- }, []), react_default.createElement("div", { ref: anchorRef }, react_default.createElement(Anchor, null), createPortal(
11204
- react_default.createElement(Container4, { style: { top: top + "px", left: left + "px" } }, shapes.map((Particle, index) => {
11205
- let angle = 360 / NUM_OF_PARTICLES * index + random(-JITTER, JITTER), distance = random(50, 80), rotation = random(-360, 360), style = {
11206
- "--angle": angle + "deg",
11207
- "--distance": distance + "px",
11208
- "--rotation": rotation + "deg",
11209
- "--fade-duration": FADE_DURATION + "ms"
11210
- };
11211
- return react_default.createElement(Particle, { key: Particle.name, style, color: colors[index] });
11212
- })),
11213
- document.getElementById("root") ?? document.body
11214
- ));
11215
- });
11216
-
11217
- // src/manager/components/TextFlip.tsx
11218
- var slideIn2 = keyframes({
11219
- from: {
11220
- transform: "translateY(var(--slide-in-from))",
11221
- opacity: 0
11222
- }
11223
- }), slideOut = keyframes({
11224
- to: {
11225
- transform: "translateY(var(--slide-out-to))",
11226
- opacity: 0
11227
- }
11228
- }), Container5 = styled.div({
11229
- display: "inline-grid",
11230
- gridTemplateColumns: "1fr",
11231
- justifyContent: "center",
11232
- alignItems: "center"
11233
- }), Placeholder2 = styled.div({
11234
- gridArea: "1 / 1",
11235
- userSelect: "none",
11236
- visibility: "hidden"
11237
- }), Text2 = styled.span(({ duration, isExiting, isEntering, reverse }) => {
11238
- let animation;
11239
- return isExiting ? animation = `${slideOut} ${duration}ms forwards` : isEntering && (animation = `${slideIn2} ${duration}ms forwards`), {
11240
- gridArea: "1 / 1",
11241
- animation,
11242
- pointerEvents: isExiting ? "none" : "auto",
11243
- userSelect: isExiting ? "none" : "text",
11244
- "--slide-in-from": reverse ? "-100%" : "100%",
11245
- "--slide-out-to": reverse ? "100%" : "-100%",
11246
- "@media (prefers-reduced-motion: reduce)": {
11247
- animation: "none",
11248
- opacity: isExiting ? 0 : 1,
11249
- transform: "translateY(0)"
11250
- }
11804
+ return { availableItems, openItems, readyItems, nextItems, progress };
11805
+ }, [allItems]);
11806
+ return useEffect(() => {
11807
+ if (!(!loaded || status !== experimental_UniversalStore.Status.READY))
11808
+ for (let item of allItems) {
11809
+ if (!item.subscribe)
11810
+ continue;
11811
+ let subscribed = subscriptions.has(item.id);
11812
+ if (item.isOpen && item.isAvailable && !subscribed)
11813
+ subscriptions.set(
11814
+ item.id,
11815
+ item.subscribe({
11816
+ api,
11817
+ item,
11818
+ accept: () => internal_checklistStore.accept(item.id),
11819
+ done: () => internal_checklistStore.done(item.id),
11820
+ skip: () => internal_checklistStore.skip(item.id)
11821
+ })
11822
+ );
11823
+ else if (subscribed && !(item.isOpen && item.isAvailable)) {
11824
+ let unsubscribe = subscriptions.get(item.id);
11825
+ subscriptions.delete(item.id), typeof unsubscribe == "function" && unsubscribe();
11826
+ }
11827
+ }
11828
+ }, [api, loaded, status, allItems]), useEffect(() => {
11829
+ let initialize = () => setInitialized(!0), timeout = setTimeout(initialize, 1e3);
11830
+ return api.once(PREVIEW_INITIALIZED, initialize), () => {
11831
+ clearTimeout(timeout), api.off(PREVIEW_INITIALIZED, initialize);
11832
+ };
11833
+ }, [api]), useEffect(() => {
11834
+ initialized && items && status === experimental_UniversalStore.Status.READY && debounceReady();
11835
+ }, [initialized, items, status, debounceReady]), {
11836
+ ready,
11837
+ allItems,
11838
+ ...itemCollections,
11839
+ ...internal_checklistStore,
11840
+ ...checklistState
11251
11841
  };
11252
- }), TextFlip = ({
11253
- text,
11254
- duration = 250,
11255
- placeholder,
11256
- ...props
11257
- }) => {
11258
- let textRef = useRef(text), [staleValue, setStaleValue] = useState(text), isAnimating = text !== staleValue, reverse = isAnimating && numericCompare(staleValue, text);
11259
- return textRef.current = text, react_default.createElement(Container5, { ...props }, isAnimating && react_default.createElement(
11260
- Text2,
11261
- {
11262
- "aria-hidden": !0,
11263
- duration,
11264
- reverse,
11265
- isExiting: !0,
11266
- onAnimationEnd: () => setStaleValue(textRef.current)
11267
- },
11268
- staleValue
11269
- ), react_default.createElement(Text2, { duration, reverse, isEntering: isAnimating }, text), placeholder && react_default.createElement(Placeholder2, { "aria-hidden": !0 }, placeholder));
11270
11842
  };
11271
- function numericCompare(a2, b2) {
11272
- let na = Number(a2), nb = Number(b2);
11273
- return Number.isNaN(na) || Number.isNaN(nb) ? a2.localeCompare(b2, void 0, { numeric: !0 }) > 0 : na > nb;
11274
- }
11275
11843
 
11276
11844
  // src/manager/components/sidebar/ChecklistWidget.tsx
11277
11845
  var fadeScaleIn = keyframes`
@@ -11313,13 +11881,13 @@ var fadeScaleIn = keyframes`
11313
11881
  "&:hover #checklist-module-collapse-toggle": {
11314
11882
  opacity: 1
11315
11883
  }
11316
- }), CollapseToggle = styled(ActionList.Button)({
11884
+ }), CollapseToggle2 = styled(ActionList.Button)({
11317
11885
  opacity: 0,
11318
11886
  transition: "opacity var(--transition-duration, 0.2s)",
11319
11887
  "&:focus, &:hover": {
11320
11888
  opacity: 1
11321
11889
  }
11322
- }), ProgressCircle2 = styled(ProgressSpinner)(({ theme }) => ({
11890
+ }), ProgressCircle = styled(ProgressSpinner)(({ theme }) => ({
11323
11891
  color: theme.color.secondary
11324
11892
  })), Checked = styled(StatusPassIcon)(({ theme }) => ({
11325
11893
  padding: 1,
@@ -11336,6 +11904,7 @@ var fadeScaleIn = keyframes`
11336
11904
  transition: "color 500ms"
11337
11905
  }),
11338
11906
  ({ theme, isSkipped }) => isSkipped && {
11907
+ alignSelf: "flex-start",
11339
11908
  "&:after": {
11340
11909
  content: '""',
11341
11910
  position: "absolute",
@@ -11412,7 +11981,7 @@ var fadeScaleIn = keyframes`
11412
11981
  fallback: react_default.createElement(OpenGuideButton, null)
11413
11982
  }
11414
11983
  )), react_default.createElement(ActionList.Item, { as: "div" }, react_default.createElement(
11415
- CollapseToggle,
11984
+ CollapseToggle2,
11416
11985
  {
11417
11986
  ...toggleProps,
11418
11987
  id: "checklist-module-collapse-toggle",
@@ -11451,7 +12020,7 @@ var fadeScaleIn = keyframes`
11451
12020
  onClick: (e2) => e2.stopPropagation()
11452
12021
  },
11453
12022
  react_default.createElement(
11454
- ProgressCircle2,
12023
+ ProgressCircle,
11455
12024
  {
11456
12025
  percentage: progress,
11457
12026
  running: !1,
@@ -12879,7 +13448,7 @@ function getPath(item, ref) {
12879
13448
  return parent ? [...getPath(parent, ref), parent.name] : ref.id === DEFAULT_REF_ID ? [] : [ref.title || ref.id];
12880
13449
  }
12881
13450
  var searchItem = (item, ref) => ({ ...item, refId: ref.id, path: getPath(item, ref) });
12882
- function cycle(array, index, delta) {
13451
+ function cycle2(array, index, delta) {
12883
13452
  let next = index + delta % array.length;
12884
13453
  return next < 0 && (next = array.length + next), next >= array.length && (next -= array.length), next;
12885
13454
  }
@@ -13554,7 +14123,7 @@ var TypeIcon2 = styled.svg(
13554
14123
  "&:first-of-type": {
13555
14124
  marginTop: 0
13556
14125
  }
13557
- }), Wrapper3 = styled.div({
14126
+ }), Wrapper5 = styled.div({
13558
14127
  display: "flex",
13559
14128
  alignItems: "center",
13560
14129
  gap: 6,
@@ -13565,7 +14134,7 @@ var TypeIcon2 = styled.svg(
13565
14134
  isExpandable = !1,
13566
14135
  ...props
13567
14136
  }) {
13568
- return react_default.createElement(BranchNode, { isExpandable, tabIndex: -1, ...props }, react_default.createElement(Wrapper3, null, isExpandable && react_default.createElement(CollapseIcon2, { isExpanded }), react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "14", height: "14", type: "group" }, react_default.createElement(UseSymbol, { type: "group" }))), children);
14137
+ return react_default.createElement(BranchNode, { isExpandable, tabIndex: -1, ...props }, react_default.createElement(Wrapper5, null, isExpandable && react_default.createElement(CollapseIcon2, { isExpanded }), react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "14", height: "14", type: "group" }, react_default.createElement(UseSymbol, { type: "group" }))), children);
13569
14138
  }), ComponentNode = react_default.memo(
13570
14139
  function({
13571
14140
  theme,
@@ -13575,25 +14144,33 @@ var TypeIcon2 = styled.svg(
13575
14144
  isSelected,
13576
14145
  ...props
13577
14146
  }) {
13578
- return react_default.createElement(BranchNode, { isExpandable, tabIndex: -1, ...props }, react_default.createElement(Wrapper3, null, isExpandable && react_default.createElement(CollapseIcon2, { isExpanded }), react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "12", height: "12", type: "component" }, react_default.createElement(UseSymbol, { type: "component" }))), children);
14147
+ return react_default.createElement(BranchNode, { isExpandable, tabIndex: -1, ...props }, react_default.createElement(Wrapper5, null, isExpandable && react_default.createElement(CollapseIcon2, { isExpanded }), react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "12", height: "12", type: "component" }, react_default.createElement(UseSymbol, { type: "component" }))), children);
13579
14148
  }
13580
14149
  ), DocumentNode = react_default.memo(function({ theme, children, docsMode, ...props }) {
13581
- return react_default.createElement(LeafNode, { tabIndex: -1, ...props }, react_default.createElement(Wrapper3, null, react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "12", height: "12", type: "document" }, react_default.createElement(UseSymbol, { type: "document" }))), children);
13582
- }), StoryNode = react_default.memo(function({
14150
+ return react_default.createElement(LeafNode, { tabIndex: -1, rel: "canonical", ...props }, react_default.createElement(Wrapper5, null, react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "12", height: "12", type: "document" }, react_default.createElement(UseSymbol, { type: "document" }))), children);
14151
+ }), StoryBranchNode = react_default.memo(
14152
+ function({
14153
+ theme,
14154
+ children,
14155
+ isExpandable = !1,
14156
+ isExpanded = !1,
14157
+ isSelected,
14158
+ ...props
14159
+ }) {
14160
+ return react_default.createElement(BranchNode, { isExpandable, tabIndex: -1, ...props }, react_default.createElement(Wrapper5, null, isExpandable && react_default.createElement(CollapseIcon2, { isExpanded }), react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "12", height: "12", type: "story" }, react_default.createElement(UseSymbol, { type: "story" }))), children);
14161
+ }
14162
+ ), StoryLeafNode = react_default.memo(function({
13583
14163
  theme,
13584
14164
  children,
13585
- isExpandable = !1,
13586
- isExpanded = !1,
13587
- isSelected,
13588
14165
  ...props
13589
14166
  }) {
13590
- return react_default.createElement(BranchNode, { isExpandable, tabIndex: -1, ...props }, react_default.createElement(Wrapper3, null, isExpandable && react_default.createElement(CollapseIcon2, { isExpanded }), react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "12", height: "12", type: "story" }, react_default.createElement(UseSymbol, { type: "story" }))), children);
14167
+ return react_default.createElement(LeafNode, { tabIndex: -1, rel: "canonical", ...props }, react_default.createElement(Wrapper5, null, react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "12", height: "12", type: "story" }, react_default.createElement(UseSymbol, { type: "story" }))), children);
13591
14168
  }), TestNode = react_default.memo(function({
13592
14169
  theme,
13593
14170
  children,
13594
14171
  ...props
13595
14172
  }) {
13596
- return react_default.createElement(LeafNode, { tabIndex: -1, ...props }, react_default.createElement(Wrapper3, null, react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "12", height: "12", type: "test" }, react_default.createElement(UseSymbol, { type: "test" }))), children);
14173
+ return react_default.createElement(LeafNode, { tabIndex: -1, rel: "canonical", ...props }, react_default.createElement(Wrapper5, null, react_default.createElement(TypeIcon2, { viewBox: "0 0 14 14", width: "12", height: "12", type: "test" }, react_default.createElement(UseSymbol, { type: "test" }))), children);
13597
14174
  });
13598
14175
 
13599
14176
  // src/manager/keybinding.ts
@@ -13848,7 +14425,7 @@ var statusOrder = [
13848
14425
  })) : [], [item.id, item.type, onSelectStoryId, statuses]), id = createId(item.id, refId), contextMenu = refId === "storybook_internal" ? useContextMenu(item, statusLinks, api) : { node: null, onMouseEnter: () => {
13849
14426
  } };
13850
14427
  if (item.type === "story" && !("children" in item && item.children) && (!("subtype" in item) || item.subtype !== "test") || item.type === "docs") {
13851
- let LeafNode3 = item.type === "docs" ? DocumentNode : StoryNode, statusValue = getMostCriticalStatusValue(
14428
+ let LeafNode3 = item.type === "docs" ? DocumentNode : StoryLeafNode, statusValue = getMostCriticalStatusValue(
13852
14429
  Object.values(statuses || {}).map((s2) => s2.value)
13853
14430
  ), [icon, textColor] = getStatus(theme, statusValue);
13854
14431
  return react_default.createElement(
@@ -13947,7 +14524,7 @@ var statusOrder = [
13947
14524
  itemIcon
13948
14525
  ) : null;
13949
14526
  if (item.type === "component" || item.type === "group" || item.type === "story" && "children" in item && item.children) {
13950
- let { children = [] } = item, BranchNode2 = { component: ComponentNode, group: GroupNode, story: StoryNode }[item.type], status = getMostCriticalStatusValue([itemStatus, groupStatus?.[item.id]]), color2 = status ? getStatus(theme, status)[1] : null, showBranchStatus = status === "status-value:error" || status === "status-value:warning";
14527
+ let { children = [] } = item, BranchNode2 = { component: ComponentNode, group: GroupNode, story: StoryBranchNode }[item.type], status = getMostCriticalStatusValue([itemStatus, groupStatus?.[item.id]]), color2 = status ? getStatus(theme, status)[1] : null, showBranchStatus = status === "status-value:error" || status === "status-value:warning";
13951
14528
  return react_default.createElement(
13952
14529
  LeafNodeStyleWrapper,
13953
14530
  {
@@ -13998,7 +14575,7 @@ var statusOrder = [
13998
14575
  ) : itemStatusButton
13999
14576
  );
14000
14577
  }
14001
- let isTest = item.type === "story" && item.subtype === "test", LeafNode2 = isTest ? TestNode : { docs: DocumentNode, story: StoryNode }[item.type], nodeType = isTest ? "test" : { docs: "document", story: "story" }[item.type];
14578
+ let isTest = item.type === "story" && item.subtype === "test", LeafNode2 = isTest ? TestNode : { docs: DocumentNode, story: StoryLeafNode }[item.type], nodeType = isTest ? "test" : { docs: "document", story: "story" }[item.type];
14002
14579
  return react_default.createElement(
14003
14580
  LeafNodeStyleWrapper,
14004
14581
  {
@@ -14184,7 +14761,7 @@ var statusOrder = [
14184
14761
  });
14185
14762
 
14186
14763
  // src/manager/components/sidebar/Refs.tsx
14187
- var Wrapper4 = styled.div(({ isMain }) => ({
14764
+ var Wrapper6 = styled.div(({ isMain }) => ({
14188
14765
  position: "relative",
14189
14766
  marginTop: isMain ? void 0 : 0
14190
14767
  })), RefHead = styled.div(({ theme }) => ({
@@ -14259,7 +14836,7 @@ var Wrapper4 = styled.div(({ isMain }) => ({
14259
14836
  },
14260
14837
  react_default.createElement(CollapseButton2, { "data-action": "collapse-ref", onClick: handleClick }, react_default.createElement(CollapseIcon2, { isExpanded }), react_default.createElement(RefTitle, { title: title2 }, title2)),
14261
14838
  react_default.createElement(RefIndicator, { ...props, state, ref: indicatorRef })
14262
- ), isExpanded && react_default.createElement(Wrapper4, { "data-title": title2, isMain }, state === "auth" && react_default.createElement(AuthBlock, { id: refId, loginUrl }), state === "error" && react_default.createElement(ErrorBlock, { error: indexError }), state === "loading" && react_default.createElement(LoaderBlock, { isMain }), state === "empty" && react_default.createElement(EmptyBlock, { isMain, hasEntries }), state === "ready" && react_default.createElement(
14839
+ ), isExpanded && react_default.createElement(Wrapper6, { "data-title": title2, isMain }, state === "auth" && react_default.createElement(AuthBlock, { id: refId, loginUrl }), state === "error" && react_default.createElement(ErrorBlock, { error: indexError }), state === "loading" && react_default.createElement(LoaderBlock, { isMain }), state === "empty" && react_default.createElement(EmptyBlock, { isMain, hasEntries }), state === "ready" && react_default.createElement(
14263
14840
  Tree,
14264
14841
  {
14265
14842
  allStatuses,
@@ -14321,7 +14898,7 @@ var { document: document5, window: globalWindow4 } = scope, fromSelection = (sel
14321
14898
  containerRef.current?.querySelectorAll("[data-highlightable=true]") || []
14322
14899
  ), currentIndex = highlightable.findIndex(
14323
14900
  (el) => el.getAttribute("data-item-id") === highlightedRef.current?.itemId && el.getAttribute("data-ref-id") === highlightedRef.current?.refId
14324
- ), nextIndex = cycle(highlightable, currentIndex, isArrowUp ? -1 : 1), didRunAround = isArrowUp ? nextIndex === highlightable.length - 1 : nextIndex === 0;
14901
+ ), nextIndex = cycle2(highlightable, currentIndex, isArrowUp ? -1 : 1), didRunAround = isArrowUp ? nextIndex === highlightable.length - 1 : nextIndex === 0;
14325
14902
  if (highlightElement(highlightable[nextIndex], didRunAround), highlightable[nextIndex].getAttribute("data-nodetype") === "component") {
14326
14903
  let { itemId, refId } = highlightedRef.current, item = api.resolveStory(itemId, refId === "storybook_internal" ? void 0 : refId);
14327
14904
  item?.type === "component" && api.emit(PRELOAD_ENTRIES, {
@@ -14445,36 +15022,45 @@ var buttonStyleAdditions = ({
14445
15022
  box-shadow: 0 0 0 2px ${curriedTransparentize$1(0.88, theme.color.secondary)};
14446
15023
  }
14447
15024
  `}
14448
- `, Container6 = styled.div({
15025
+ `, Container7 = styled.div({
14449
15026
  minWidth: 250
14450
15027
  }), SidebarButton = styled(Button)(buttonStyleAdditions), SidebarToggleButton = styled(ToggleButton)(buttonStyleAdditions), MenuButtonGroup = styled.div({
14451
15028
  display: "flex",
14452
15029
  gap: 6
14453
- }), SidebarMenuList = ({ menu, onHide }) => react_default.createElement(Container6, null, menu.filter((links) => links.length).flatMap((links) => react_default.createElement(ActionList, { key: links.map((link) => link.id).join("_") }, links.map((link) => react_default.createElement(ActionList.Item, { key: link.id, active: link.active }, react_default.createElement(
14454
- ActionList.Action,
14455
- {
14456
- ...link.href && { as: "a", href: link.href, target: "_blank" },
14457
- ariaLabel: !1,
14458
- id: `list-item-${link.id}`,
14459
- disabled: link.disabled,
14460
- onClick: (e2) => {
14461
- if (link.disabled) {
14462
- e2.preventDefault();
14463
- return;
15030
+ }), SidebarMenuList = ({ menu, onHide }) => react_default.createElement(Container7, null, menu.filter((links) => links.length).flatMap((links) => react_default.createElement(ActionList, { key: links.map((link) => link.id).join("_") }, links.map((link) => {
15031
+ let linkContent = react_default.createElement(react_default.Fragment, null, (link.icon || link.input) && react_default.createElement(ActionList.Icon, null, link.icon || link.input), (link.title || link.center) && react_default.createElement(ActionList.Text, null, link.title || link.center), link.right);
15032
+ return react_default.createElement(ActionList.Item, { key: link.id, active: link.active }, react_default.createElement(
15033
+ ActionList.Action,
15034
+ {
15035
+ asChild: !!link.href,
15036
+ ariaLabel: !1,
15037
+ id: `list-item-${link.id}`,
15038
+ disabled: link.disabled,
15039
+ onClick: (e2) => {
15040
+ if (link.disabled) {
15041
+ e2.preventDefault();
15042
+ return;
15043
+ }
15044
+ link.href && link.internal && e2.preventDefault(), link.onClick?.(e2, {
15045
+ id: link.id,
15046
+ active: link.active,
15047
+ disabled: link.disabled,
15048
+ title: link.title,
15049
+ href: link.href
15050
+ }), link.closeOnClick && onHide();
14464
15051
  }
14465
- link.onClick?.(e2, {
14466
- id: link.id,
14467
- active: link.active,
14468
- disabled: link.disabled,
14469
- title: link.title,
14470
- href: link.href
14471
- }), link.closeOnClick && onHide();
14472
- }
14473
- },
14474
- (link.icon || link.input) && react_default.createElement(ActionList.Icon, null, link.icon || link.input),
14475
- (link.title || link.center) && react_default.createElement(ActionList.Text, null, link.title || link.center),
14476
- link.right
14477
- )))))), SidebarMenu = ({ menu, isHighlighted, onClick }) => {
15052
+ },
15053
+ link.href ? react_default.createElement(
15054
+ "a",
15055
+ {
15056
+ href: link.href,
15057
+ target: link.internal ? void 0 : "_blank",
15058
+ rel: link.internal ? "canonical" : "noreferrer"
15059
+ },
15060
+ linkContent
15061
+ ) : linkContent
15062
+ ));
15063
+ })))), SidebarMenu = ({ menu, isHighlighted, onClick }) => {
14478
15064
  let [isTooltipVisible, setIsTooltipVisible] = useState(!1), { isMobile: isMobile2, setMobileMenuOpen } = useLayout();
14479
15065
  return isMobile2 ? react_default.createElement(MenuButtonGroup, null, react_default.createElement(
14480
15066
  SidebarButton,
@@ -14483,10 +15069,13 @@ var buttonStyleAdditions = ({
14483
15069
  variant: "ghost",
14484
15070
  ariaLabel: "About Storybook",
14485
15071
  highlighted: !!isHighlighted,
14486
- onClick,
14487
- isMobile: !0
15072
+ onClick: (e2) => {
15073
+ onClick?.(e2), e2.preventDefault();
15074
+ },
15075
+ isMobile: !0,
15076
+ asChild: !0
14488
15077
  },
14489
- react_default.createElement(CogIcon, null)
15078
+ react_default.createElement("a", { href: "./?path=/settings/about", rel: "canonical" }, react_default.createElement(CogIcon, null))
14490
15079
  ), react_default.createElement(
14491
15080
  SidebarButton,
14492
15081
  {
@@ -14576,7 +15165,7 @@ var BrandArea = styled.div(({ theme }) => ({
14576
15165
  zIndex: 3
14577
15166
  }
14578
15167
  }
14579
- })), Heading = ({
15168
+ })), Heading2 = ({
14580
15169
  menuHighlighted = !1,
14581
15170
  menu,
14582
15171
  skipLinkHref,
@@ -16960,7 +17549,11 @@ var { document: document7 } = scope, ResultsList = styled.ol({
16960
17549
  flexDirection: "column"
16961
17550
  }), Mark = styled.mark(({ theme }) => ({
16962
17551
  background: "transparent",
16963
- color: theme.color.secondary
17552
+ color: theme.color.secondary,
17553
+ "@media (forced-colors: active)": {
17554
+ color: "HighlightText",
17555
+ background: "Highlight"
17556
+ }
16964
17557
  })), MoreWrapper = styled.div({
16965
17558
  marginTop: 8
16966
17559
  }), RecentlyOpenedTitle = styled.div(({ theme }) => ({
@@ -17135,7 +17728,7 @@ var DEFAULT_HEIGHT = 500, HoverCard2 = styled(Card)({
17135
17728
  }), Collapsible2 = styled.div(({ theme }) => ({
17136
17729
  overflow: "hidden",
17137
17730
  boxShadow: `inset 0 -1px 0 ${theme.appBorderColor}`
17138
- })), Content2 = styled.div({
17731
+ })), Content3 = styled.div({
17139
17732
  display: "flex",
17140
17733
  flexDirection: "column"
17141
17734
  }), Bar2 = styled.div(({ onClick }) => ({
@@ -17156,7 +17749,7 @@ var DEFAULT_HEIGHT = 500, HoverCard2 = styled(Card)({
17156
17749
  display: "flex",
17157
17750
  justifyContent: "flex-end",
17158
17751
  gap: 4
17159
- }), CollapseToggle2 = styled(ActionList.Button)({
17752
+ }), CollapseToggle3 = styled(ActionList.Button)({
17160
17753
  opacity: 0,
17161
17754
  transition: "opacity 250ms",
17162
17755
  "&:focus, &:hover": {
@@ -17272,7 +17865,7 @@ var DEFAULT_HEIGHT = 500, HoverCard2 = styled(Card)({
17272
17865
  fallback: react_default.createElement(RunButton, { isRunning, onRunAll })
17273
17866
  }
17274
17867
  )), react_default.createElement(Filters, null, hasTestProviders && react_default.createElement(
17275
- CollapseToggle2,
17868
+ CollapseToggle3,
17276
17869
  {
17277
17870
  onClick: (e2) => toggleCollapsed(e2),
17278
17871
  id: "testing-module-collapse-toggle",
@@ -17342,7 +17935,7 @@ var DEFAULT_HEIGHT = 500, HoverCard2 = styled(Card)({
17342
17935
  maxHeight: isCollapsed ? 0 : maxHeight
17343
17936
  }
17344
17937
  },
17345
- react_default.createElement(Content2, { ref: contentRef }, Object.values(registeredTestProviders).map((registeredTestProvider) => {
17938
+ react_default.createElement(Content3, { ref: contentRef }, Object.values(registeredTestProviders).map((registeredTestProvider) => {
17346
17939
  let { render: Render, id } = registeredTestProvider;
17347
17940
  return Render ? react_default.createElement(TestProvider, { key: id, "data-module-id": id }, react_default.createElement(Render, null)) : (once.warn(
17348
17941
  `No render function found for test provider with id '${id}', skipping...`
@@ -17357,7 +17950,7 @@ var SIDEBAR_BOTTOM_SPACER_ID = "sidebar-bottom-spacer", SIDEBAR_BOTTOM_WRAPPER_I
17357
17950
  ({ value }) => ["status-value:warning", "status-value:error"].includes(value)
17358
17951
  ), getFilter = (warningsActive = !1, errorsActive = !1) => warningsActive && errorsActive ? filterBoth : warningsActive ? filterWarn : errorsActive ? filterError : filterNone, Spacer = styled.div({
17359
17952
  pointerEvents: "none"
17360
- }), Content3 = styled.div(({ theme }) => ({
17953
+ }), Content4 = styled.div(({ theme }) => ({
17361
17954
  position: "absolute",
17362
17955
  zIndex: 1,
17363
17956
  bottom: 0,
@@ -17401,7 +17994,7 @@ var SIDEBAR_BOTTOM_SPACER_ID = "sidebar-bottom-spacer", SIDEBAR_BOTTOM_WRAPPER_I
17401
17994
  }, []), useEffect(() => {
17402
17995
  let filter = getFilter(warningCount > 0 && warningsActive, errorCount > 0 && errorsActive);
17403
17996
  api.experimental_setFilter("sidebar-bottom-filter", filter);
17404
- }, [api, warningCount, errorCount, warningsActive, errorsActive]), !warningCount && !errorCount && Object.values(registeredTestProviders).length === 0 && notifications.length === 0 ? null : react_default.createElement(Fragment, null, react_default.createElement(Spacer, { id: SIDEBAR_BOTTOM_SPACER_ID, ref: spacerRef }), react_default.createElement(Content3, { id: SIDEBAR_BOTTOM_WRAPPER_ID, ref: wrapperRef }, react_default.createElement(NotificationList, { notifications, clearNotification: api.clearNotification }), isDevelopment && react_default.createElement(
17997
+ }, [api, warningCount, errorCount, warningsActive, errorsActive]), !warningCount && !errorCount && Object.values(registeredTestProviders).length === 0 && notifications.length === 0 ? null : react_default.createElement(Fragment, null, react_default.createElement(Spacer, { id: SIDEBAR_BOTTOM_SPACER_ID, ref: spacerRef }), react_default.createElement(Content4, { id: SIDEBAR_BOTTOM_WRAPPER_ID, ref: wrapperRef }, react_default.createElement(NotificationList, { notifications, clearNotification: api.clearNotification }), isDevelopment && react_default.createElement(
17405
17998
  TestingWidget,
17406
17999
  {
17407
18000
  registeredTestProviders,
@@ -17452,7 +18045,7 @@ var SIDEBAR_BOTTOM_SPACER_ID = "sidebar-bottom-spacer", SIDEBAR_BOTTOM_WRAPPER_I
17452
18045
  var groupByType = (filters) => filters.reduce(
17453
18046
  (acc, filter) => (acc[filter.type] = acc[filter.type] || [], acc[filter.type].push(filter), acc),
17454
18047
  {}
17455
- ), Wrapper5 = styled.div({
18048
+ ), Wrapper7 = styled.div({
17456
18049
  minWidth: 240,
17457
18050
  maxWidth: 300,
17458
18051
  maxHeight: 15.5 * 32 + 8,
@@ -17505,7 +18098,7 @@ var groupByType = (filters) => filters.reduce(
17505
18098
  }, groups = groupByType(Object.values(filtersById)), links = Object.values(groups).map(
17506
18099
  (group) => group.sort((a2, b2) => a2.id.localeCompare(b2.id)).map((filter) => renderLink(filter)).filter((value) => !!value)
17507
18100
  ).filter((value) => value.length > 0), hasItems = links.length > 0, hasUserTags = Object.values(filtersById).some(({ type }) => type === "tag"), isNothingSelectedYet = includedFilters.size === 0 && excludedFilters.size === 0;
17508
- return react_default.createElement(Wrapper5, { ref }, hasItems && react_default.createElement(ActionList, { as: "div" }, react_default.createElement(ActionList.Item, { as: "div" }, isNothingSelectedYet ? react_default.createElement(
18101
+ return react_default.createElement(Wrapper7, { ref }, hasItems && react_default.createElement(ActionList, { as: "div" }, react_default.createElement(ActionList.Item, { as: "div" }, isNothingSelectedYet ? react_default.createElement(
17509
18102
  ActionList.Button,
17510
18103
  {
17511
18104
  ariaLabel: !1,
@@ -17719,7 +18312,7 @@ var import_store2 = __toESM(require_store2(), 1), save = debounce((value) => imp
17719
18312
  };
17720
18313
 
17721
18314
  // src/manager/components/sidebar/Sidebar.tsx
17722
- var DEFAULT_REF_ID = "storybook_internal", Container7 = styled.nav(({ theme }) => ({
18315
+ var DEFAULT_REF_ID = "storybook_internal", Container8 = styled.nav(({ theme }) => ({
17723
18316
  position: "absolute",
17724
18317
  zIndex: 1,
17725
18318
  left: 0,
@@ -17792,8 +18385,8 @@ var DEFAULT_REF_ID = "storybook_internal", Container7 = styled.nav(({ theme }) =
17792
18385
  }, {}),
17793
18386
  []
17794
18387
  );
17795
- return react_default.createElement(Container7, { className: "container sidebar-container", "aria-label": "Global" }, react_default.createElement(ScrollArea, { vertical: !0, offset: 3, scrollbarSize: 6, scrollPadding: "4rem" }, react_default.createElement(Stack, null, react_default.createElement("div", null, react_default.createElement(
17796
- Heading,
18388
+ return react_default.createElement(Container8, { className: "container sidebar-container", "aria-label": "Global" }, react_default.createElement(ScrollArea, { vertical: !0, offset: 3, scrollbarSize: 6, scrollPadding: "4rem" }, react_default.createElement(Stack, null, react_default.createElement("div", null, react_default.createElement(
18389
+ Heading2,
17797
18390
  {
17798
18391
  className: "sidebar-header",
17799
18392
  menuHighlighted,
@@ -17802,7 +18395,7 @@ var DEFAULT_REF_ID = "storybook_internal", Container7 = styled.nav(({ theme }) =
17802
18395
  isLoading,
17803
18396
  onMenuClick
17804
18397
  }
17805
- ), !isLoading && scope.CONFIG_TYPE === "DEVELOPMENT" && react_default.createElement(ChecklistWidget, null)), react_default.createElement(
18398
+ ), !isLoading && scope.CONFIG_TYPE === "DEVELOPMENT" && scope.FEATURES?.sidebarOnboardingChecklist !== !1 && react_default.createElement(ChecklistWidget, null)), react_default.createElement(
17806
18399
  Search,
17807
18400
  {
17808
18401
  dataset,
@@ -17863,6 +18456,173 @@ var DEFAULT_REF_ID = "storybook_internal", Container7 = styled.nav(({ theme }) =
17863
18456
  )), isMobile2 || isLoading ? null : react_default.createElement(SidebarBottom, { isDevelopment })));
17864
18457
  });
17865
18458
 
18459
+ // src/manager/container/Menu.tsx
18460
+ var ProgressCircle2 = styled(ProgressSpinner)(({ theme }) => ({
18461
+ color: theme.color.secondary
18462
+ })), useMenu = ({
18463
+ api,
18464
+ showToolbar,
18465
+ isPanelShown,
18466
+ isNavShown,
18467
+ enableShortcuts
18468
+ }) => {
18469
+ let shortcutKeys = api.getShortcutKeys(), { progress } = useChecklist(), about = useMemo(
18470
+ () => ({
18471
+ id: "about",
18472
+ title: "About your Storybook",
18473
+ onClick: () => api.changeSettingsTab("about"),
18474
+ href: "./?path=/settings/about",
18475
+ internal: !0,
18476
+ closeOnClick: !0,
18477
+ icon: react_default.createElement(InfoIcon, null)
18478
+ }),
18479
+ [api]
18480
+ ), guide = useMemo(
18481
+ () => ({
18482
+ id: "guide",
18483
+ title: "Onboarding guide",
18484
+ onClick: () => api.changeSettingsTab("guide"),
18485
+ href: "./?path=/settings/guide",
18486
+ internal: !0,
18487
+ closeOnClick: !0,
18488
+ icon: react_default.createElement(ListUnorderedIcon, null),
18489
+ right: progress < 100 && react_default.createElement(ActionList.Button, { as: "div", readOnly: !0, padding: "none", ariaLabel: `${progress}% completed` }, react_default.createElement(ProgressCircle2, { percentage: progress, running: !1, size: 16, width: 1.5 }), progress, "%")
18490
+ }),
18491
+ [api, progress]
18492
+ ), shortcuts = useMemo(
18493
+ () => ({
18494
+ id: "shortcuts",
18495
+ title: "Keyboard shortcuts",
18496
+ onClick: () => api.changeSettingsTab("shortcuts"),
18497
+ href: "./?path=/settings/shortcuts",
18498
+ internal: !0,
18499
+ closeOnClick: !0,
18500
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.shortcutsPage }) : null,
18501
+ icon: react_default.createElement(CommandIcon, null)
18502
+ }),
18503
+ [api, enableShortcuts, shortcutKeys.shortcutsPage]
18504
+ ), sidebarToggle = useMemo(
18505
+ () => ({
18506
+ id: "S",
18507
+ title: "Show sidebar",
18508
+ onClick: () => api.toggleNav(),
18509
+ closeOnClick: !0,
18510
+ active: isNavShown,
18511
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.toggleNav }) : null,
18512
+ icon: isNavShown ? react_default.createElement(CheckIcon, null) : react_default.createElement(react_default.Fragment, null)
18513
+ }),
18514
+ [api, enableShortcuts, shortcutKeys, isNavShown]
18515
+ ), toolbarToogle = useMemo(
18516
+ () => ({
18517
+ id: "T",
18518
+ title: "Show toolbar",
18519
+ onClick: () => api.toggleToolbar(),
18520
+ active: showToolbar,
18521
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.toolbar }) : null,
18522
+ icon: showToolbar ? react_default.createElement(CheckIcon, null) : react_default.createElement(react_default.Fragment, null)
18523
+ }),
18524
+ [api, enableShortcuts, shortcutKeys, showToolbar]
18525
+ ), addonsToggle = useMemo(
18526
+ () => ({
18527
+ id: "A",
18528
+ title: "Show addons panel",
18529
+ onClick: () => api.togglePanel(),
18530
+ active: isPanelShown,
18531
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.togglePanel }) : null,
18532
+ icon: isPanelShown ? react_default.createElement(CheckIcon, null) : react_default.createElement(react_default.Fragment, null)
18533
+ }),
18534
+ [api, enableShortcuts, shortcutKeys, isPanelShown]
18535
+ ), up = useMemo(
18536
+ () => ({
18537
+ id: "up",
18538
+ title: "Previous component",
18539
+ onClick: () => api.jumpToComponent(-1),
18540
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.prevComponent }) : null,
18541
+ icon: react_default.createElement(react_default.Fragment, null)
18542
+ }),
18543
+ [api, enableShortcuts, shortcutKeys]
18544
+ ), down = useMemo(
18545
+ () => ({
18546
+ id: "down",
18547
+ title: "Next component",
18548
+ onClick: () => api.jumpToComponent(1),
18549
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.nextComponent }) : null,
18550
+ icon: react_default.createElement(react_default.Fragment, null)
18551
+ }),
18552
+ [api, enableShortcuts, shortcutKeys]
18553
+ ), prev = useMemo(
18554
+ () => ({
18555
+ id: "prev",
18556
+ title: "Previous story",
18557
+ onClick: () => api.jumpToStory(-1),
18558
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.prevStory }) : null,
18559
+ icon: react_default.createElement(react_default.Fragment, null)
18560
+ }),
18561
+ [api, enableShortcuts, shortcutKeys]
18562
+ ), next = useMemo(
18563
+ () => ({
18564
+ id: "next",
18565
+ title: "Next story",
18566
+ onClick: () => api.jumpToStory(1),
18567
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.nextStory }) : null,
18568
+ icon: react_default.createElement(react_default.Fragment, null)
18569
+ }),
18570
+ [api, enableShortcuts, shortcutKeys]
18571
+ ), collapse = useMemo(
18572
+ () => ({
18573
+ id: "collapse",
18574
+ title: "Collapse all",
18575
+ onClick: () => api.emit(STORIES_COLLAPSE_ALL),
18576
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: shortcutKeys.collapseAll }) : null,
18577
+ icon: react_default.createElement(react_default.Fragment, null)
18578
+ }),
18579
+ [api, enableShortcuts, shortcutKeys]
18580
+ ), documentation = useMemo(() => ({
18581
+ id: "documentation",
18582
+ title: "Documentation",
18583
+ closeOnClick: !0,
18584
+ href: api.getDocsUrl({ versioned: !0, renderer: !0 }),
18585
+ right: react_default.createElement(ActionList.Icon, null, react_default.createElement(ShareAltIcon, null)),
18586
+ icon: react_default.createElement(DocumentIcon, null)
18587
+ }), [api]), getAddonsShortcuts = useCallback(() => {
18588
+ let addonsShortcuts = api.getAddonsShortcuts(), keys = shortcutKeys;
18589
+ return Object.entries(addonsShortcuts).filter(([_2, { showInMenu }]) => showInMenu).map(([actionName, { label, action }]) => ({
18590
+ id: actionName,
18591
+ title: label,
18592
+ onClick: () => action(),
18593
+ right: enableShortcuts ? react_default.createElement(Shortcut, { keys: keys[actionName] }) : null
18594
+ }));
18595
+ }, [api, enableShortcuts, shortcutKeys]);
18596
+ return useMemo(
18597
+ () => [
18598
+ [
18599
+ about,
18600
+ ...scope.CONFIG_TYPE === "DEVELOPMENT" ? [guide] : [],
18601
+ ...enableShortcuts ? [shortcuts] : []
18602
+ ],
18603
+ [sidebarToggle, toolbarToogle, addonsToggle, up, down, prev, next, collapse],
18604
+ getAddonsShortcuts(),
18605
+ [documentation]
18606
+ ],
18607
+ [
18608
+ about,
18609
+ guide,
18610
+ documentation,
18611
+ shortcuts,
18612
+ sidebarToggle,
18613
+ toolbarToogle,
18614
+ addonsToggle,
18615
+ up,
18616
+ down,
18617
+ prev,
18618
+ next,
18619
+ collapse,
18620
+ getAddonsShortcuts,
18621
+ enableShortcuts
18622
+ ]
18623
+ );
18624
+ };
18625
+
17866
18626
  // src/manager/container/Sidebar.tsx
17867
18627
  var Sidebar3 = react_default.memo(function({ onMenuClick }) {
17868
18628
  return react_default.createElement(Consumer, { filter: ({ state, api }) => {
@@ -17930,7 +18690,7 @@ var App = ({ managerLayoutState, setManagerLayoutState, pages, hasTab }) => {
17930
18690
  attributes: !0,
17931
18691
  attributeFilter: ["inert"]
17932
18692
  }), () => observer.disconnect();
17933
- }, []), react_default.createElement(react_default.Fragment, null, react_default.createElement(Global, { styles: createGlobal }), react_default.createElement(
18693
+ }, []), react_default.createElement(react_default.Fragment, null, react_default.createElement(Global, { styles: createGlobal }), react_default.createElement(ManagerErrorBoundary, null, react_default.createElement(
17934
18694
  Layout,
17935
18695
  {
17936
18696
  hasTab,
@@ -17939,9 +18699,9 @@ var App = ({ managerLayoutState, setManagerLayoutState, pages, hasTab }) => {
17939
18699
  slotMain: react_default.createElement(Preview_default, { id: "main", withLoader: !0 }),
17940
18700
  slotSidebar: react_default.createElement(Sidebar_default, { onMenuClick: () => setMobileAboutOpen((state) => !state) }),
17941
18701
  slotPanel: react_default.createElement(Panel_default, null),
17942
- slotPages: pages.map(({ id, render: Content5 }) => react_default.createElement(Content5, { key: id }))
18702
+ slotPages: pages.map(({ id, render: Content6 }) => react_default.createElement(Content6, { key: id }))
17943
18703
  }
17944
- ));
18704
+ )));
17945
18705
  };
17946
18706
 
17947
18707
  // src/manager/provider.ts
@@ -17958,7 +18718,7 @@ var Provider2 = class {
17958
18718
  };
17959
18719
 
17960
18720
  // src/manager/settings/About.tsx
17961
- var Container8 = styled.div({
18721
+ var Container9 = styled.div({
17962
18722
  display: "flex",
17963
18723
  alignItems: "center",
17964
18724
  flexDirection: "column",
@@ -17995,7 +18755,7 @@ var Container8 = styled.div({
17995
18755
  "&:hover": {
17996
18756
  color: theme.base === "light" ? theme.color.darkest : theme.color.lightest
17997
18757
  }
17998
- })), AboutScreen = ({ onNavigateToWhatsNew }) => react_default.createElement(Container8, null, react_default.createElement(Header, null, react_default.createElement(StorybookLogo, { alt: "Storybook" })), react_default.createElement(UpgradeBlock, { onNavigateToWhatsNew }), react_default.createElement(Footer, null, react_default.createElement(Actions2, null, react_default.createElement(Button, { ariaLabel: !1, asChild: !0 }, react_default.createElement("a", { href: "https://github.com/storybookjs/storybook" }, react_default.createElement(GithubIcon, null), "GitHub")), react_default.createElement(Button, { ariaLabel: !1, asChild: !0 }, react_default.createElement("a", { href: "https://storybook.js.org/docs?ref=ui" }, react_default.createElement(DocumentIcon, { style: { display: "inline", marginRight: 5 } }), "Documentation"))), react_default.createElement("div", null, "Open source software maintained by", " ", react_default.createElement(StyledLink, { href: "https://www.chromatic.com/" }, "Chromatic"), " and the", " ", react_default.createElement(StyledLink, { href: "https://github.com/storybookjs/storybook/graphs/contributors" }, "Storybook Community"))));
18758
+ })), AboutScreen = ({ onNavigateToWhatsNew }) => react_default.createElement(Container9, null, react_default.createElement(Header, null, react_default.createElement(StorybookLogo, { alt: "Storybook" })), react_default.createElement(UpgradeBlock, { onNavigateToWhatsNew }), react_default.createElement(Footer, null, react_default.createElement(Actions2, null, react_default.createElement(Button, { ariaLabel: !1, asChild: !0 }, react_default.createElement("a", { href: "https://github.com/storybookjs/storybook" }, react_default.createElement(GithubIcon, null), "GitHub")), react_default.createElement(Button, { ariaLabel: !1, asChild: !0 }, react_default.createElement("a", { href: "https://storybook.js.org/docs?ref=ui" }, react_default.createElement(DocumentIcon, { style: { display: "inline", marginRight: 5 } }), "Documentation"))), react_default.createElement("div", null, "Open source software maintained by", " ", react_default.createElement(StyledLink, { href: "https://www.chromatic.com/" }, "Chromatic"), " and the", " ", react_default.createElement(StyledLink, { href: "https://github.com/storybookjs/storybook/graphs/contributors" }, "Storybook Community"))));
17999
18759
 
18000
18760
  // src/manager/settings/AboutPage.tsx
18001
18761
  var NotificationClearer = class extends Component {
@@ -18404,7 +19164,7 @@ var Sections = styled.ol(({ theme }) => ({
18404
19164
  };
18405
19165
 
18406
19166
  // src/manager/settings/GuidePage.tsx
18407
- var Container9 = styled.div(({ theme }) => ({
19167
+ var Container10 = styled.div(({ theme }) => ({
18408
19168
  display: "flex",
18409
19169
  flexDirection: "column",
18410
19170
  maxWidth: 600,
@@ -18427,7 +19187,7 @@ var Container9 = styled.div(({ theme }) => ({
18427
19187
  }
18428
19188
  })), GuidePage = () => {
18429
19189
  let checklist = useChecklist();
18430
- return react_default.createElement(Container9, null, react_default.createElement(Intro, null, react_default.createElement("h1", null, "Guide"), react_default.createElement("p", null, "Whether you're just getting started or looking for ways to level up, this checklist will help you make the most of your Storybook.")), react_default.createElement(Checklist, { ...checklist }), checklist.openItems.length === 0 ? react_default.createElement("center", null, "Your work here is done!") : checklist.widget.disable || checklist.openItems.every((item) => item.isMuted) ? react_default.createElement("center", null, "Want to see this in the sidebar?", " ", react_default.createElement(Link, { onClick: () => checklist.disable(!1) }, "Show in sidebar")) : react_default.createElement("center", null, "Don't want to see this in the sidebar?", " ", react_default.createElement(Link, { onClick: () => checklist.mute(checklist.allItems.map(({ id }) => id)) }, "Remove from sidebar")));
19190
+ return react_default.createElement(Container10, null, react_default.createElement(Intro, null, react_default.createElement("h1", null, "Guide"), react_default.createElement("p", null, "Whether you're just getting started or looking for ways to level up, this checklist will help you make the most of your Storybook.")), react_default.createElement(Checklist, { ...checklist }), scope.FEATURES?.sidebarOnboardingChecklist !== !1 && react_default.createElement(react_default.Fragment, null, checklist.openItems.length === 0 ? react_default.createElement("center", null, "Your work here is done!") : checklist.widget.disable || checklist.openItems.every((item) => item.isMuted) ? react_default.createElement("center", null, "Want to see this in the sidebar?", " ", react_default.createElement(Link, { onClick: () => checklist.disable(!1) }, "Show in sidebar")) : react_default.createElement("center", null, "Don't want to see this in the sidebar?", " ", react_default.createElement(Link, { onClick: () => checklist.mute(checklist.allItems.map(({ id }) => id)) }, "Remove from sidebar"))));
18431
19191
  };
18432
19192
 
18433
19193
  // src/manager/settings/SettingsFooter.tsx
@@ -18512,7 +19272,7 @@ var Header2 = styled.header(({ theme }) => ({
18512
19272
  height: 14,
18513
19273
  width: 14
18514
19274
  }
18515
- ), Container10 = styled.div(({ theme }) => ({
19275
+ ), Container11 = styled.div(({ theme }) => ({
18516
19276
  fontSize: theme.typography.size.s2,
18517
19277
  padding: "3rem 20px",
18518
19278
  maxWidth: 600,
@@ -18646,7 +19406,7 @@ var ShortcutsScreen = class extends Component {
18646
19406
  }
18647
19407
  render() {
18648
19408
  let layout = this.renderKeyForm();
18649
- return react_default.createElement(Container10, null, react_default.createElement(Header2, null, "Keyboard shortcuts"), layout, react_default.createElement(
19409
+ return react_default.createElement(Container11, null, react_default.createElement(Header2, null, "Keyboard shortcuts"), layout, react_default.createElement(
18650
19410
  Button,
18651
19411
  {
18652
19412
  ariaLabel: !1,
@@ -18697,7 +19457,7 @@ var Centered = styled.div({
18697
19457
  margin: "0 auto",
18698
19458
  fontSize: `${theme.typography.size.s1}px`,
18699
19459
  lineHeight: "16px"
18700
- })), Container11 = styled.div(({ theme }) => ({
19460
+ })), Container12 = styled.div(({ theme }) => ({
18701
19461
  position: "absolute",
18702
19462
  width: "100%",
18703
19463
  height: 40,
@@ -18717,7 +19477,7 @@ var Centered = styled.div({
18717
19477
  let theme = useTheme(), [copyText, setCopyText] = useState("Copy Link"), copyLink = () => {
18718
19478
  onCopyLink(), setCopyText("Copied!"), setTimeout(() => setCopyText("Copy Link"), 4e3);
18719
19479
  };
18720
- return react_default.createElement(Container11, null, react_default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } }, react_default.createElement(HeartIcon, { color: theme.color.mediumdark }), react_default.createElement("div", null, "Share this with your team."), react_default.createElement(Button, { ariaLabel: !1, onClick: copyLink, size: "small", variant: "ghost" }, copyText)), isNotificationsEnabled ? react_default.createElement(Button, { ariaLabel: !1, size: "small", variant: "ghost", onClick: onToggleNotifications }, react_default.createElement(EyeCloseIcon, null), "Hide notifications") : react_default.createElement(Button, { ariaLabel: !1, size: "small", variant: "ghost", onClick: onToggleNotifications }, react_default.createElement(EyeIcon, null), "Show notifications"));
19480
+ return react_default.createElement(Container12, null, react_default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } }, react_default.createElement(HeartIcon, { color: theme.color.mediumdark }), react_default.createElement("div", null, "Share this with your team."), react_default.createElement(Button, { ariaLabel: !1, onClick: copyLink, size: "small", variant: "ghost" }, copyText)), isNotificationsEnabled ? react_default.createElement(Button, { ariaLabel: !1, size: "small", variant: "ghost", onClick: onToggleNotifications }, react_default.createElement(EyeCloseIcon, null), "Hide notifications") : react_default.createElement(Button, { ariaLabel: !1, size: "small", variant: "ghost", onClick: onToggleNotifications }, react_default.createElement(EyeIcon, null), "Show notifications"));
18721
19481
  }, Iframe = styled.iframe(
18722
19482
  {
18723
19483
  position: "absolute",
@@ -18785,9 +19545,19 @@ var Centered = styled.div({
18785
19545
  var WhatsNewPage = () => react_default.createElement(WhatsNewScreen, null);
18786
19546
 
18787
19547
  // src/manager/settings/index.tsx
18788
- var { document: document8 } = scope, Content4 = styled(ScrollArea)(({ theme }) => ({
19548
+ var { document: document8 } = scope, Content5 = styled(ScrollArea)(({ theme }) => ({
18789
19549
  background: theme.background.content
18790
- })), RouteWrapper = ({ children, path }) => react_default.createElement(Content4, { vertical: !0, horizontal: !1 }, react_default.createElement(Route, { path }, children)), Pages = ({ changeTab, onClose, enableShortcuts = !0, enableWhatsNew }) => {
19550
+ })), SidebarToggle = styled.div({
19551
+ // Extra specificity is necessary here
19552
+ "&&:has(*)": {
19553
+ order: 0,
19554
+ display: "flex",
19555
+ alignItems: "center",
19556
+ marginLeft: 10,
19557
+ marginRight: 6,
19558
+ gap: 6
19559
+ }
19560
+ }), RouteWrapper = ({ children, path }) => react_default.createElement(Content5, { vertical: !0, horizontal: !1 }, react_default.createElement(Route, { path }, children)), Pages = ({ changeTab, onClose, enableShortcuts = !0, enableWhatsNew }) => {
18791
19561
  react_default.useEffect(() => {
18792
19562
  let handleEscape = (event) => {
18793
19563
  !enableShortcuts || event.repeat || matchesModifiers(!1, event) && matchesKeyCode("Escape", event) && (event.preventDefault(), onClose());
@@ -18822,7 +19592,7 @@ var { document: document8 } = scope, Content4 = styled(ScrollArea)(({ theme }) =
18822
19592
  TabsView,
18823
19593
  {
18824
19594
  tabs,
18825
- tools: react_default.createElement(
19595
+ tools: react_default.createElement(react_default.Fragment, null, react_default.createElement(SidebarToggle, null, menuTool.render({})), react_default.createElement(
18826
19596
  Button,
18827
19597
  {
18828
19598
  padding: "small",
@@ -18831,7 +19601,7 @@ var { document: document8 } = scope, Content4 = styled(ScrollArea)(({ theme }) =
18831
19601
  ariaLabel: "Close settings page"
18832
19602
  },
18833
19603
  react_default.createElement(CloseIcon, null)
18834
- ),
19604
+ )),
18835
19605
  selected,
18836
19606
  onSelectionChange: changeTab
18837
19607
  }