@stoplight/elements-core 7.6.0 → 7.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
- import { TableOfContentsDivider, TableOfContentsExternalLink, TableOfContentsGroup, TableOfContentsItem, TableOfContentsNode, TableOfContentsNodeGroup } from './types';
1
+ import { TableOfContentsDivider, TableOfContentsExternalLink, TableOfContentsGroup, TableOfContentsGroupItem, TableOfContentsItem, TableOfContentsNode, TableOfContentsNodeGroup } from './types';
2
2
  export declare function getHtmlIdFromItemId(id: string): string;
3
3
  export declare function isGroupOpenByDefault(depth: number, item: TableOfContentsGroup | TableOfContentsNodeGroup, activeId?: string, maxDepthOpenByDefault?: number): boolean | "" | undefined;
4
+ export declare function hasActiveItem(items: TableOfContentsGroupItem[], activeId: string): boolean;
4
5
  export declare function findFirstNode(items: TableOfContentsItem[]): TableOfContentsNode | TableOfContentsNodeGroup | void;
5
6
  export declare function isDivider(item: TableOfContentsItem): item is TableOfContentsDivider;
6
7
  export declare function isGroup(item: TableOfContentsItem): item is TableOfContentsGroup;
@@ -0,0 +1 @@
1
+ export declare function useFirstRender(): boolean;
package/index.esm.js CHANGED
@@ -2561,6 +2561,13 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
2561
2561
  return (React__default.createElement(HashLink, { to: href, title: title }, children));
2562
2562
  };
2563
2563
 
2564
+ function useFirstRender() {
2565
+ const ref = React__default.useRef(true);
2566
+ const firstRender = ref.current;
2567
+ ref.current = false;
2568
+ return firstRender;
2569
+ }
2570
+
2564
2571
  const NODE_TYPE_TITLE_ICON = {
2565
2572
  http_service: faCloud,
2566
2573
  };
@@ -2638,16 +2645,20 @@ const LinkContext = React.createContext(undefined);
2638
2645
  const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefault, externalScrollbar = false, onLinkClick }) => {
2639
2646
  const container = React.useRef(null);
2640
2647
  const child = React.useRef(null);
2648
+ const firstRender = useFirstRender();
2641
2649
  React.useEffect(() => {
2642
- const tocHasScrollbar = externalScrollbar ||
2643
- (container.current && child.current && container.current.offsetHeight < child.current.offsetHeight);
2644
- if (activeId && typeof window !== 'undefined' && tocHasScrollbar) {
2645
- const elem = window.document.getElementById(getHtmlIdFromItemId(activeId));
2646
- if (elem && 'scrollIntoView' in elem) {
2647
- elem.scrollIntoView({ block: 'center' });
2650
+ setTimeout(() => {
2651
+ const scrollPosition = firstRender ? 'center' : 'nearest';
2652
+ const tocHasScrollbar = externalScrollbar ||
2653
+ (container.current && child.current && container.current.offsetHeight < child.current.offsetHeight);
2654
+ if (activeId && typeof window !== 'undefined' && tocHasScrollbar) {
2655
+ const elem = window.document.getElementById(getHtmlIdFromItemId(activeId));
2656
+ if (elem && 'scrollIntoView' in elem) {
2657
+ elem.scrollIntoView({ block: scrollPosition });
2658
+ }
2648
2659
  }
2649
- }
2650
- }, []);
2660
+ }, 0);
2661
+ }, [activeId]);
2651
2662
  return (React.createElement(Box, { ref: container, w: "full", bg: "canvas-100", overflowY: "auto" },
2652
2663
  React.createElement(Box, { ref: child, my: 3 },
2653
2664
  React.createElement(LinkContext.Provider, { value: Link },
@@ -2678,9 +2689,19 @@ const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, onLinkClick
2678
2689
  });
2679
2690
  const Group = React.memo(({ depth, item, maxDepthOpenByDefault, onLinkClick = () => { } }) => {
2680
2691
  const activeId = React.useContext(ActiveIdContext);
2681
- const [isOpen, setIsOpen] = React.useState(() => {
2682
- return isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault);
2683
- });
2692
+ const [isOpen, setIsOpen] = React.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
2693
+ const hasActive = !!activeId && hasActiveItem(item.items, activeId);
2694
+ React.useEffect(() => {
2695
+ const openByDefault = isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault);
2696
+ if (isOpen !== openByDefault) {
2697
+ setIsOpen(openByDefault);
2698
+ }
2699
+ }, [depth, maxDepthOpenByDefault]);
2700
+ React.useEffect(() => {
2701
+ if (hasActive) {
2702
+ setIsOpen(true);
2703
+ }
2704
+ }, [hasActive]);
2684
2705
  const handleClick = (e, forceOpen) => {
2685
2706
  setIsOpen(forceOpen ? true : !isOpen);
2686
2707
  };
@@ -2691,12 +2712,13 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, onLinkClick = ()
2691
2712
  e.preventDefault();
2692
2713
  handleClick();
2693
2714
  } })));
2715
+ const showAsActive = hasActive && !isOpen;
2694
2716
  let elem;
2695
2717
  if (isNodeGroup(item)) {
2696
- elem = React.createElement(Node, { depth: depth, item: item, meta: meta, onClick: handleClick, onLinkClick: onLinkClick });
2718
+ elem = (React.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick }));
2697
2719
  }
2698
2720
  else {
2699
- elem = React.createElement(Item, { title: item.title, meta: meta, onClick: handleClick, depth: depth });
2721
+ elem = React.createElement(Item, { title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive });
2700
2722
  }
2701
2723
  return (React.createElement(React.Fragment, null,
2702
2724
  elem,
@@ -2711,7 +2733,7 @@ const Item = React.memo(({ depth, isActive, id, title, meta, icon, onClick }) =>
2711
2733
  React.createElement(Box, { alignItems: "center", flex: 1, mr: meta ? 1.5 : undefined, ml: icon && 1.5, textOverflow: "truncate" }, title),
2712
2734
  React.createElement(Flex, { alignItems: "center", fontSize: "xs" }, meta)));
2713
2735
  });
2714
- const Node = React.memo(({ item, depth, meta, onClick, onLinkClick = () => { } }) => {
2736
+ const Node = React.memo(({ item, depth, meta, showAsActive, onClick, onLinkClick = () => { } }) => {
2715
2737
  const activeId = React.useContext(ActiveIdContext);
2716
2738
  const isActive = activeId === item.slug || activeId === item.id;
2717
2739
  const LinkComponent = React.useContext(LinkContext);
@@ -2728,7 +2750,7 @@ const Node = React.memo(({ item, depth, meta, onClick, onLinkClick = () => { } }
2728
2750
  }
2729
2751
  };
2730
2752
  return (React.createElement(Box, { as: LinkComponent, to: item.slug, display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
2731
- React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, onClick: handleClick })));
2753
+ React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, onClick: handleClick })));
2732
2754
  });
2733
2755
  const Version = ({ value }) => {
2734
2756
  return (React.createElement(Box, { mr: 2 },
package/index.js CHANGED
@@ -2615,6 +2615,13 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
2615
2615
  return (React__default["default"].createElement(reactRouterHashLink.HashLink, { to: href, title: title }, children));
2616
2616
  };
2617
2617
 
2618
+ function useFirstRender() {
2619
+ const ref = React__default["default"].useRef(true);
2620
+ const firstRender = ref.current;
2621
+ ref.current = false;
2622
+ return firstRender;
2623
+ }
2624
+
2618
2625
  const NODE_TYPE_TITLE_ICON = {
2619
2626
  http_service: faCloud,
2620
2627
  };
@@ -2692,16 +2699,20 @@ const LinkContext = React__namespace.createContext(undefined);
2692
2699
  const TableOfContents = React__namespace.memo(({ tree, activeId, Link, maxDepthOpenByDefault, externalScrollbar = false, onLinkClick }) => {
2693
2700
  const container = React__namespace.useRef(null);
2694
2701
  const child = React__namespace.useRef(null);
2702
+ const firstRender = useFirstRender();
2695
2703
  React__namespace.useEffect(() => {
2696
- const tocHasScrollbar = externalScrollbar ||
2697
- (container.current && child.current && container.current.offsetHeight < child.current.offsetHeight);
2698
- if (activeId && typeof window !== 'undefined' && tocHasScrollbar) {
2699
- const elem = window.document.getElementById(getHtmlIdFromItemId(activeId));
2700
- if (elem && 'scrollIntoView' in elem) {
2701
- elem.scrollIntoView({ block: 'center' });
2704
+ setTimeout(() => {
2705
+ const scrollPosition = firstRender ? 'center' : 'nearest';
2706
+ const tocHasScrollbar = externalScrollbar ||
2707
+ (container.current && child.current && container.current.offsetHeight < child.current.offsetHeight);
2708
+ if (activeId && typeof window !== 'undefined' && tocHasScrollbar) {
2709
+ const elem = window.document.getElementById(getHtmlIdFromItemId(activeId));
2710
+ if (elem && 'scrollIntoView' in elem) {
2711
+ elem.scrollIntoView({ block: scrollPosition });
2712
+ }
2702
2713
  }
2703
- }
2704
- }, []);
2714
+ }, 0);
2715
+ }, [activeId]);
2705
2716
  return (React__namespace.createElement(mosaic.Box, { ref: container, w: "full", bg: "canvas-100", overflowY: "auto" },
2706
2717
  React__namespace.createElement(mosaic.Box, { ref: child, my: 3 },
2707
2718
  React__namespace.createElement(LinkContext.Provider, { value: Link },
@@ -2732,9 +2743,19 @@ const GroupItem = React__namespace.memo(({ item, depth, maxDepthOpenByDefault, o
2732
2743
  });
2733
2744
  const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, onLinkClick = () => { } }) => {
2734
2745
  const activeId = React__namespace.useContext(ActiveIdContext);
2735
- const [isOpen, setIsOpen] = React__namespace.useState(() => {
2736
- return isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault);
2737
- });
2746
+ const [isOpen, setIsOpen] = React__namespace.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
2747
+ const hasActive = !!activeId && hasActiveItem(item.items, activeId);
2748
+ React__namespace.useEffect(() => {
2749
+ const openByDefault = isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault);
2750
+ if (isOpen !== openByDefault) {
2751
+ setIsOpen(openByDefault);
2752
+ }
2753
+ }, [depth, maxDepthOpenByDefault]);
2754
+ React__namespace.useEffect(() => {
2755
+ if (hasActive) {
2756
+ setIsOpen(true);
2757
+ }
2758
+ }, [hasActive]);
2738
2759
  const handleClick = (e, forceOpen) => {
2739
2760
  setIsOpen(forceOpen ? true : !isOpen);
2740
2761
  };
@@ -2745,12 +2766,13 @@ const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, onLin
2745
2766
  e.preventDefault();
2746
2767
  handleClick();
2747
2768
  } })));
2769
+ const showAsActive = hasActive && !isOpen;
2748
2770
  let elem;
2749
2771
  if (isNodeGroup(item)) {
2750
- elem = React__namespace.createElement(Node, { depth: depth, item: item, meta: meta, onClick: handleClick, onLinkClick: onLinkClick });
2772
+ elem = (React__namespace.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick }));
2751
2773
  }
2752
2774
  else {
2753
- elem = React__namespace.createElement(Item, { title: item.title, meta: meta, onClick: handleClick, depth: depth });
2775
+ elem = React__namespace.createElement(Item, { title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive });
2754
2776
  }
2755
2777
  return (React__namespace.createElement(React__namespace.Fragment, null,
2756
2778
  elem,
@@ -2765,7 +2787,7 @@ const Item = React__namespace.memo(({ depth, isActive, id, title, meta, icon, on
2765
2787
  React__namespace.createElement(mosaic.Box, { alignItems: "center", flex: 1, mr: meta ? 1.5 : undefined, ml: icon && 1.5, textOverflow: "truncate" }, title),
2766
2788
  React__namespace.createElement(mosaic.Flex, { alignItems: "center", fontSize: "xs" }, meta)));
2767
2789
  });
2768
- const Node = React__namespace.memo(({ item, depth, meta, onClick, onLinkClick = () => { } }) => {
2790
+ const Node = React__namespace.memo(({ item, depth, meta, showAsActive, onClick, onLinkClick = () => { } }) => {
2769
2791
  const activeId = React__namespace.useContext(ActiveIdContext);
2770
2792
  const isActive = activeId === item.slug || activeId === item.id;
2771
2793
  const LinkComponent = React__namespace.useContext(LinkContext);
@@ -2782,7 +2804,7 @@ const Node = React__namespace.memo(({ item, depth, meta, onClick, onLinkClick =
2782
2804
  }
2783
2805
  };
2784
2806
  return (React__namespace.createElement(mosaic.Box, { as: LinkComponent, to: item.slug, display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
2785
- React__namespace.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, onClick: handleClick })));
2807
+ React__namespace.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, onClick: handleClick })));
2786
2808
  });
2787
2809
  const Version = ({ value }) => {
2788
2810
  return (React__namespace.createElement(mosaic.Box, { mr: 2 },
package/index.mjs CHANGED
@@ -2561,6 +2561,13 @@ const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
2561
2561
  return (React__default.createElement(HashLink, { to: href, title: title }, children));
2562
2562
  };
2563
2563
 
2564
+ function useFirstRender() {
2565
+ const ref = React__default.useRef(true);
2566
+ const firstRender = ref.current;
2567
+ ref.current = false;
2568
+ return firstRender;
2569
+ }
2570
+
2564
2571
  const NODE_TYPE_TITLE_ICON = {
2565
2572
  http_service: faCloud,
2566
2573
  };
@@ -2638,16 +2645,20 @@ const LinkContext = React.createContext(undefined);
2638
2645
  const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefault, externalScrollbar = false, onLinkClick }) => {
2639
2646
  const container = React.useRef(null);
2640
2647
  const child = React.useRef(null);
2648
+ const firstRender = useFirstRender();
2641
2649
  React.useEffect(() => {
2642
- const tocHasScrollbar = externalScrollbar ||
2643
- (container.current && child.current && container.current.offsetHeight < child.current.offsetHeight);
2644
- if (activeId && typeof window !== 'undefined' && tocHasScrollbar) {
2645
- const elem = window.document.getElementById(getHtmlIdFromItemId(activeId));
2646
- if (elem && 'scrollIntoView' in elem) {
2647
- elem.scrollIntoView({ block: 'center' });
2650
+ setTimeout(() => {
2651
+ const scrollPosition = firstRender ? 'center' : 'nearest';
2652
+ const tocHasScrollbar = externalScrollbar ||
2653
+ (container.current && child.current && container.current.offsetHeight < child.current.offsetHeight);
2654
+ if (activeId && typeof window !== 'undefined' && tocHasScrollbar) {
2655
+ const elem = window.document.getElementById(getHtmlIdFromItemId(activeId));
2656
+ if (elem && 'scrollIntoView' in elem) {
2657
+ elem.scrollIntoView({ block: scrollPosition });
2658
+ }
2648
2659
  }
2649
- }
2650
- }, []);
2660
+ }, 0);
2661
+ }, [activeId]);
2651
2662
  return (React.createElement(Box, { ref: container, w: "full", bg: "canvas-100", overflowY: "auto" },
2652
2663
  React.createElement(Box, { ref: child, my: 3 },
2653
2664
  React.createElement(LinkContext.Provider, { value: Link },
@@ -2678,9 +2689,19 @@ const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, onLinkClick
2678
2689
  });
2679
2690
  const Group = React.memo(({ depth, item, maxDepthOpenByDefault, onLinkClick = () => { } }) => {
2680
2691
  const activeId = React.useContext(ActiveIdContext);
2681
- const [isOpen, setIsOpen] = React.useState(() => {
2682
- return isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault);
2683
- });
2692
+ const [isOpen, setIsOpen] = React.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
2693
+ const hasActive = !!activeId && hasActiveItem(item.items, activeId);
2694
+ React.useEffect(() => {
2695
+ const openByDefault = isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault);
2696
+ if (isOpen !== openByDefault) {
2697
+ setIsOpen(openByDefault);
2698
+ }
2699
+ }, [depth, maxDepthOpenByDefault]);
2700
+ React.useEffect(() => {
2701
+ if (hasActive) {
2702
+ setIsOpen(true);
2703
+ }
2704
+ }, [hasActive]);
2684
2705
  const handleClick = (e, forceOpen) => {
2685
2706
  setIsOpen(forceOpen ? true : !isOpen);
2686
2707
  };
@@ -2691,12 +2712,13 @@ const Group = React.memo(({ depth, item, maxDepthOpenByDefault, onLinkClick = ()
2691
2712
  e.preventDefault();
2692
2713
  handleClick();
2693
2714
  } })));
2715
+ const showAsActive = hasActive && !isOpen;
2694
2716
  let elem;
2695
2717
  if (isNodeGroup(item)) {
2696
- elem = React.createElement(Node, { depth: depth, item: item, meta: meta, onClick: handleClick, onLinkClick: onLinkClick });
2718
+ elem = (React.createElement(Node, { depth: depth, item: item, meta: meta, showAsActive: showAsActive, onClick: handleClick, onLinkClick: onLinkClick }));
2697
2719
  }
2698
2720
  else {
2699
- elem = React.createElement(Item, { title: item.title, meta: meta, onClick: handleClick, depth: depth });
2721
+ elem = React.createElement(Item, { title: item.title, meta: meta, onClick: handleClick, depth: depth, isActive: showAsActive });
2700
2722
  }
2701
2723
  return (React.createElement(React.Fragment, null,
2702
2724
  elem,
@@ -2711,7 +2733,7 @@ const Item = React.memo(({ depth, isActive, id, title, meta, icon, onClick }) =>
2711
2733
  React.createElement(Box, { alignItems: "center", flex: 1, mr: meta ? 1.5 : undefined, ml: icon && 1.5, textOverflow: "truncate" }, title),
2712
2734
  React.createElement(Flex, { alignItems: "center", fontSize: "xs" }, meta)));
2713
2735
  });
2714
- const Node = React.memo(({ item, depth, meta, onClick, onLinkClick = () => { } }) => {
2736
+ const Node = React.memo(({ item, depth, meta, showAsActive, onClick, onLinkClick = () => { } }) => {
2715
2737
  const activeId = React.useContext(ActiveIdContext);
2716
2738
  const isActive = activeId === item.slug || activeId === item.id;
2717
2739
  const LinkComponent = React.useContext(LinkContext);
@@ -2728,7 +2750,7 @@ const Node = React.memo(({ item, depth, meta, onClick, onLinkClick = () => { } }
2728
2750
  }
2729
2751
  };
2730
2752
  return (React.createElement(Box, { as: LinkComponent, to: item.slug, display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
2731
- React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, onClick: handleClick })));
2753
+ React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, onClick: handleClick })));
2732
2754
  });
2733
2755
  const Version = ({ value }) => {
2734
2756
  return (React.createElement(Box, { mr: 2 },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stoplight/elements-core",
3
- "version": "7.6.0",
3
+ "version": "7.6.3",
4
4
  "main": "./index.js",
5
5
  "sideEffects": [
6
6
  "web-components.min.js",
@@ -27,11 +27,11 @@
27
27
  "@stoplight/json": "^3.18.1",
28
28
  "@stoplight/json-schema-ref-parser": "^9.0.5",
29
29
  "@stoplight/json-schema-sampler": "0.2.2",
30
- "@stoplight/json-schema-viewer": "^4.7.0",
30
+ "@stoplight/json-schema-viewer": "^4.7.1",
31
31
  "@stoplight/markdown-viewer": "^5.5.0",
32
- "@stoplight/mosaic": "^1.24.0",
33
- "@stoplight/mosaic-code-editor": "^1.24.0",
34
- "@stoplight/mosaic-code-viewer": "^1.24.0",
32
+ "@stoplight/mosaic": "^1.24.2",
33
+ "@stoplight/mosaic-code-editor": "^1.24.2",
34
+ "@stoplight/mosaic-code-viewer": "^1.24.2",
35
35
  "@stoplight/path": "^1.3.2",
36
36
  "@stoplight/react-error-boundary": "^2.0.0",
37
37
  "@stoplight/types": "^13.0.0",