@redocly/theme 0.55.0-next.1 → 0.55.0-next.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.
Files changed (47) hide show
  1. package/lib/components/JsonViewer/JsonViewer.d.ts +2 -0
  2. package/lib/components/JsonViewer/JsonViewer.js +3 -1
  3. package/lib/components/Marker/Marker.d.ts +10 -0
  4. package/lib/components/Marker/Marker.js +62 -0
  5. package/lib/core/contexts/CodeWalkthrough/CodeWalkthroughStepsContext.d.ts +1 -1
  6. package/lib/core/contexts/CodeWalkthrough/CodeWalkthroughStepsContext.js +5 -2
  7. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.d.ts +17 -9
  8. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.js +242 -47
  9. package/lib/core/hooks/code-walkthrough/use-code-walkthrough.d.ts +9 -2
  10. package/lib/core/hooks/code-walkthrough/use-code-walkthrough.js +2 -2
  11. package/lib/core/hooks/index.d.ts +1 -1
  12. package/lib/core/hooks/index.js +1 -1
  13. package/lib/core/hooks/use-active-page-version.d.ts +1 -0
  14. package/lib/core/hooks/{use-page-active-version.js → use-active-page-version.js} +3 -3
  15. package/lib/core/types/code-walkthrough.d.ts +13 -0
  16. package/lib/core/types/code-walkthrough.js +3 -0
  17. package/lib/core/types/index.d.ts +2 -0
  18. package/lib/core/types/index.js +2 -0
  19. package/lib/core/types/marker.d.ts +4 -0
  20. package/lib/core/types/marker.js +3 -0
  21. package/lib/core/utils/js-utils.d.ts +18 -0
  22. package/lib/core/utils/js-utils.js +31 -0
  23. package/lib/index.d.ts +1 -0
  24. package/lib/index.js +1 -0
  25. package/lib/markdoc/components/CodeWalkthrough/CodeStep.d.ts +1 -2
  26. package/lib/markdoc/components/CodeWalkthrough/CodeStep.js +26 -20
  27. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +32 -3
  28. package/lib/markdoc/tags/code-step.js +0 -3
  29. package/lib/markdoc/tags/code-walkthrough.js +0 -1
  30. package/package.json +1 -1
  31. package/src/components/JsonViewer/JsonViewer.tsx +6 -0
  32. package/src/components/Marker/Marker.tsx +53 -0
  33. package/src/core/contexts/CodeWalkthrough/CodeWalkthroughStepsContext.tsx +6 -3
  34. package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +326 -65
  35. package/src/core/hooks/code-walkthrough/use-code-walkthrough.ts +9 -6
  36. package/src/core/hooks/index.ts +1 -1
  37. package/src/core/hooks/{use-page-active-version.ts → use-active-page-version.ts} +1 -1
  38. package/src/core/types/code-walkthrough.ts +15 -0
  39. package/src/core/types/index.ts +2 -0
  40. package/src/core/types/marker.ts +4 -0
  41. package/src/core/utils/js-utils.ts +31 -0
  42. package/src/index.ts +1 -0
  43. package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +76 -36
  44. package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +8 -3
  45. package/src/markdoc/tags/code-step.ts +0 -3
  46. package/src/markdoc/tags/code-walkthrough.ts +0 -1
  47. package/lib/core/hooks/use-page-active-version.d.ts +0 -1
@@ -1,8 +1,17 @@
1
- import React, { useContext, useRef, type PropsWithChildren, useEffect, useState } from 'react';
1
+ import React, {
2
+ useContext,
3
+ useRef,
4
+ type PropsWithChildren,
5
+ useEffect,
6
+ useState,
7
+ useMemo,
8
+ useCallback,
9
+ } from 'react';
2
10
  import styled from 'styled-components';
3
11
 
4
12
  import type { WithConditions } from '@redocly/config';
5
13
 
14
+ import { Marker } from '@redocly/theme/components/Marker/Marker';
6
15
  import {
7
16
  CodeWalkthroughControlsStateContext,
8
17
  CodeWalkthroughStepsContext,
@@ -10,32 +19,46 @@ import {
10
19
 
11
20
  export type CodeStepProps = WithConditions<{
12
21
  id: string;
13
- stepKey: number;
14
22
  heading?: string;
15
23
  }>;
16
24
 
17
25
  export function CodeStep({
18
26
  id,
19
27
  heading,
20
- stepKey,
21
28
  when,
22
29
  unless,
23
30
  children,
24
31
  }: PropsWithChildren<CodeStepProps>) {
25
32
  const compRef = useRef<HTMLDivElement | null>(null);
33
+ const markerRef = useRef<HTMLDivElement | null>(null);
34
+
26
35
  const { areConditionsMet } = useContext(CodeWalkthroughControlsStateContext);
27
- const { activeStep, setActiveStep, register, unregister, lockObserver, filtersElementRef } =
28
- useContext(CodeWalkthroughStepsContext);
36
+ const {
37
+ activeStep,
38
+ setActiveStep,
39
+ markers,
40
+ registerStep,
41
+ removeStep,
42
+ registerMarker,
43
+ removeMarker,
44
+ lockObserver,
45
+ filtersElementRef,
46
+ } = useContext(CodeWalkthroughStepsContext);
29
47
  const isActive = activeStep === id;
30
48
 
31
49
  const [scrollMarginTop, setScrollMarginTop] = useState(0);
50
+ const marker = useMemo(() => markers[id], [markers, id]);
51
+ const isVisible = useMemo(
52
+ () => areConditionsMet({ when, unless }),
53
+ [areConditionsMet, when, unless],
54
+ );
32
55
 
33
- const handleActivateStep = () => {
56
+ const handleActivateStep = useCallback(() => {
34
57
  if (lockObserver) {
35
58
  lockObserver.current = true;
36
59
 
37
- if (compRef.current) {
38
- compRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
60
+ if (markerRef.current) {
61
+ markerRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
39
62
  }
40
63
 
41
64
  setActiveStep(id);
@@ -43,7 +66,17 @@ export function CodeStep({
43
66
  lockObserver.current = false;
44
67
  }, 1000);
45
68
  }
46
- };
69
+ }, [setActiveStep, lockObserver, id]);
70
+
71
+ const handleRegisterMarker = useCallback(
72
+ (element: HTMLElement) => registerMarker(id, element),
73
+ [registerMarker, id],
74
+ );
75
+
76
+ const handleRemoveMarker = useCallback(
77
+ (element: HTMLElement) => removeMarker(id, element),
78
+ [removeMarker, id],
79
+ );
47
80
 
48
81
  useEffect(() => {
49
82
  // If the step is active during first render, scroll to it
@@ -59,14 +92,14 @@ export function CodeStep({
59
92
 
60
93
  useEffect(() => {
61
94
  const currentCompRef = compRef.current;
62
- if (currentCompRef) {
95
+ if (currentCompRef && isVisible) {
63
96
  currentCompRef
64
97
  .querySelectorAll<HTMLElement>('a, button, input, textarea, select, [tabindex]')
65
98
  .forEach((el) => {
66
99
  el.setAttribute('tabindex', '-1');
67
100
  });
68
101
 
69
- register(currentCompRef);
102
+ registerStep(id, currentCompRef);
70
103
  }
71
104
 
72
105
  const filtersElementHeight = filtersElementRef?.current?.clientHeight || 0;
@@ -74,37 +107,44 @@ export function CodeStep({
74
107
  setScrollMarginTop(filtersElementHeight + navbarHeight + 10);
75
108
 
76
109
  return () => {
77
- if (currentCompRef) {
78
- unregister(currentCompRef);
79
- }
110
+ removeStep(id);
80
111
  };
81
- }, [activeStep, register, unregister, filtersElementRef]);
112
+ }, [filtersElementRef, registerStep, removeStep, id, isVisible]);
82
113
 
83
- if (!areConditionsMet({ when, unless })) {
84
- if (isActive) {
85
- setActiveStep(null);
86
- }
114
+ if (!isVisible) {
87
115
  return null;
88
116
  }
89
117
 
90
118
  return (
91
- <StepWrapper
92
- data-component-name="Markdoc/CodeWalkthrough/CodeStep"
93
- ref={compRef}
94
- isActive={isActive}
95
- scrollMarginTop={scrollMarginTop}
96
- data-step-key={stepKey}
97
- data-step-active={isActive}
98
- onClick={handleActivateStep}
99
- onFocus={handleActivateStep}
100
- tabIndex={0}
101
- className="code-step-wrapper"
102
- >
103
- <StepContent isActive={isActive}>
104
- {heading ? <StepHeading>{heading}</StepHeading> : null}
105
- {children}
106
- </StepContent>
107
- </StepWrapper>
119
+ <>
120
+ {marker && (
121
+ <Marker
122
+ ref={markerRef}
123
+ marker={marker}
124
+ registerMarker={handleRegisterMarker}
125
+ removeMarker={handleRemoveMarker}
126
+ dataAttribures={{
127
+ 'data-step-id': id,
128
+ 'data-step-active': isActive,
129
+ }}
130
+ />
131
+ )}
132
+ <StepWrapper
133
+ data-component-name="Markdoc/CodeWalkthrough/CodeStep"
134
+ ref={compRef}
135
+ isActive={isActive}
136
+ scrollMarginTop={scrollMarginTop}
137
+ onClick={handleActivateStep}
138
+ onFocus={handleActivateStep}
139
+ tabIndex={0}
140
+ className="code-step-wrapper"
141
+ >
142
+ <StepContent isActive={isActive}>
143
+ {heading ? <StepHeading>{heading}</StepHeading> : null}
144
+ {children}
145
+ </StepContent>
146
+ </StepWrapper>
147
+ </>
108
148
  );
109
149
  }
110
150
 
@@ -1,4 +1,4 @@
1
- import React, { type PropsWithChildren } from 'react';
1
+ import React, { useRef, type PropsWithChildren } from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { CodeWalkthroughAttr } from '@redocly/config';
@@ -17,10 +17,13 @@ import {
17
17
  export type CodeWalkthroughProps = PropsWithChildren<CodeWalkthroughAttr>;
18
18
 
19
19
  export function CodeWalkthrough({ children, steps, preview, ...attributes }: CodeWalkthroughProps) {
20
- const { controlsState, stepsState, files, downloadAssociatedFiles } = useCodeWalkthrough(
20
+ const root = useRef<HTMLDivElement>(null);
21
+
22
+ const { controlsState, stepsState, files, downloadAssociatedFiles } = useCodeWalkthrough({
21
23
  steps,
22
24
  attributes,
23
- );
25
+ root,
26
+ });
24
27
  const { activeFilters, getControlState, changeControlState } = controlsState;
25
28
  const { filtersElementRef } = stepsState;
26
29
 
@@ -28,6 +31,7 @@ export function CodeWalkthrough({ children, steps, preview, ...attributes }: Cod
28
31
  <CodeWalkthroughStepsContext.Provider value={stepsState}>
29
32
  <CodeWalkthroughControlsStateContext.Provider value={controlsState}>
30
33
  <CodeWalkthroughWrapper
34
+ ref={root}
31
35
  className="code-walkthrough"
32
36
  data-component-name="Markdoc/CodeWalkthrough/CodeWalkthrough"
33
37
  >
@@ -53,6 +57,7 @@ export function CodeWalkthrough({ children, steps, preview, ...attributes }: Cod
53
57
  }
54
58
 
55
59
  const CodeWalkthroughWrapper = styled.div`
60
+ position: relative;
56
61
  display: grid;
57
62
  grid-template-columns: 4fr 6fr;
58
63
 
@@ -17,9 +17,6 @@ export const codeStep: MarkdocSchemaWrapper = {
17
17
  unless: {
18
18
  type: Object,
19
19
  },
20
- stepKey: {
21
- type: Number, // internal
22
- },
23
20
  },
24
21
 
25
22
  render: 'CodeStep',
@@ -187,7 +187,6 @@ export function collectStepsFromChildren(
187
187
  ): RenderableTreeNode[] {
188
188
  return children.flatMap((child) => {
189
189
  if (child instanceof markdoc.Tag && child.name === 'CodeStep') {
190
- child.attributes.stepKey = idx++;
191
190
  return [child];
192
191
  }
193
192
 
@@ -1 +0,0 @@
1
- export declare function usePageActiveVersion(): string | undefined;