@redocly/theme 0.47.1 → 0.48.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/lib/components/Feedback/Mood.d.ts +2 -2
  2. package/lib/components/Feedback/Mood.js +20 -15
  3. package/lib/components/Feedback/Rating.d.ts +2 -2
  4. package/lib/components/Feedback/Rating.js +6 -6
  5. package/lib/components/Feedback/Scale.d.ts +2 -2
  6. package/lib/components/Feedback/Scale.js +6 -6
  7. package/lib/components/Feedback/Sentiment.d.ts +2 -2
  8. package/lib/components/Feedback/Sentiment.js +6 -6
  9. package/lib/components/Search/SearchDialog.js +17 -11
  10. package/lib/components/Search/SearchFilter.d.ts +3 -2
  11. package/lib/components/Search/SearchFilter.js +2 -2
  12. package/lib/components/Search/SearchFilterField.d.ts +3 -2
  13. package/lib/components/Search/SearchFilterField.js +2 -2
  14. package/lib/components/Search/SearchGroups.d.ts +5 -4
  15. package/lib/components/Search/SearchGroups.js +3 -3
  16. package/lib/components/Search/variables.js +4 -0
  17. package/lib/components/Segmented/Segmented.d.ts +4 -4
  18. package/lib/components/Segmented/Segmented.js +4 -7
  19. package/lib/components/Tag/Tag.d.ts +1 -0
  20. package/lib/components/Tag/Tag.js +3 -2
  21. package/lib/core/hooks/__mocks__/search/use-search-filter.d.ts +1 -1
  22. package/lib/core/hooks/__mocks__/search/use-search-filter.js +1 -1
  23. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.d.ts +1 -1
  24. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +10 -5
  25. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.d.ts +1 -2
  26. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.js +20 -15
  27. package/lib/core/hooks/code-walkthrough/use-code-walkthrough.d.ts +2 -7
  28. package/lib/core/hooks/code-walkthrough/use-code-walkthrough.js +10 -3
  29. package/lib/core/hooks/code-walkthrough/use-renderable-files.d.ts +9 -0
  30. package/lib/core/hooks/code-walkthrough/use-renderable-files.js +28 -0
  31. package/lib/core/hooks/index.d.ts +1 -0
  32. package/lib/core/hooks/index.js +1 -0
  33. package/lib/core/hooks/search/use-search-filter.d.ts +2 -2
  34. package/lib/core/hooks/search/use-search-filter.js +5 -5
  35. package/lib/core/types/hooks.d.ts +1 -0
  36. package/lib/core/types/l10n.d.ts +1 -1
  37. package/lib/core/types/search.d.ts +1 -2
  38. package/lib/core/utils/download-code-walkthrough.js +9 -1
  39. package/lib/core/utils/find-closest-common-directory.d.ts +6 -0
  40. package/lib/core/utils/find-closest-common-directory.js +51 -0
  41. package/lib/core/utils/get-file-icon.js +6 -0
  42. package/lib/core/utils/index.d.ts +1 -0
  43. package/lib/core/utils/index.js +1 -0
  44. package/lib/core/utils/replace-inputs-with-value.d.ts +1 -1
  45. package/lib/core/utils/replace-inputs-with-value.js +9 -10
  46. package/lib/icons/DocumentJavaIcon/DocumentJavaIcon.d.ts +9 -0
  47. package/lib/icons/DocumentJavaIcon/DocumentJavaIcon.js +22 -0
  48. package/lib/icons/DocumentJavaIcon/index.d.ts +1 -0
  49. package/lib/icons/DocumentJavaIcon/index.js +6 -0
  50. package/lib/icons/DocumentPythonIcon/DocumentPythonIcon.d.ts +9 -0
  51. package/lib/icons/DocumentPythonIcon/DocumentPythonIcon.js +23 -0
  52. package/lib/icons/DocumentPythonIcon/index.d.ts +1 -0
  53. package/lib/icons/DocumentPythonIcon/index.js +6 -0
  54. package/lib/icons/DocumentShellIcon/DocumentShellIcon.d.ts +9 -0
  55. package/lib/icons/DocumentShellIcon/DocumentShellIcon.js +22 -0
  56. package/lib/icons/DocumentShellIcon/index.d.ts +1 -0
  57. package/lib/icons/DocumentShellIcon/index.js +6 -0
  58. package/lib/icons/__tests__/IconTestUtils.d.ts +7 -0
  59. package/lib/icons/__tests__/IconTestUtils.js +33 -0
  60. package/lib/layouts/CodeWalkthroughLayout.js +4 -1
  61. package/lib/markdoc/components/CodeWalkthrough/CodeContainer.js +1 -1
  62. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +15 -2
  63. package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +1 -1
  64. package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.js +29 -23
  65. package/lib/markdoc/components/CodeWalkthrough/CodePanelPreview.js +1 -1
  66. package/lib/markdoc/components/CodeWalkthrough/CodePanelToolbar.js +1 -1
  67. package/lib/markdoc/components/CodeWalkthrough/CodeStep.js +6 -3
  68. package/lib/markdoc/components/CodeWalkthrough/CodeToggle.js +1 -1
  69. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +1 -1
  70. package/lib/markdoc/components/CodeWalkthrough/Input.js +4 -2
  71. package/lib/markdoc/tags/code-walkthrough.js +5 -0
  72. package/package.json +3 -3
  73. package/src/components/Feedback/Mood.tsx +25 -17
  74. package/src/components/Feedback/Rating.tsx +9 -10
  75. package/src/components/Feedback/Scale.tsx +9 -10
  76. package/src/components/Feedback/Sentiment.tsx +9 -10
  77. package/src/components/Search/SearchDialog.tsx +63 -42
  78. package/src/components/Search/SearchFilter.tsx +6 -3
  79. package/src/components/Search/SearchFilterField.tsx +4 -2
  80. package/src/components/Search/SearchGroups.tsx +13 -8
  81. package/src/components/Search/variables.ts +4 -0
  82. package/src/components/Segmented/Segmented.tsx +10 -10
  83. package/src/components/Tag/Tag.tsx +1 -1
  84. package/src/core/hooks/__mocks__/search/use-search-filter.ts +1 -1
  85. package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +9 -3
  86. package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +30 -18
  87. package/src/core/hooks/code-walkthrough/use-code-walkthrough.ts +13 -13
  88. package/src/core/hooks/code-walkthrough/use-renderable-files.ts +51 -0
  89. package/src/core/hooks/index.ts +1 -0
  90. package/src/core/hooks/search/use-search-filter.ts +9 -5
  91. package/src/core/types/hooks.ts +1 -0
  92. package/src/core/types/l10n.ts +5 -3
  93. package/src/core/types/search.ts +1 -2
  94. package/src/core/utils/download-code-walkthrough.ts +14 -2
  95. package/src/core/utils/find-closest-common-directory.ts +51 -0
  96. package/src/core/utils/get-file-icon.ts +7 -0
  97. package/src/core/utils/index.ts +1 -0
  98. package/src/core/utils/replace-inputs-with-value.ts +12 -9
  99. package/src/icons/DocumentJavaIcon/DocumentJavaIcon.tsx +33 -0
  100. package/src/icons/DocumentJavaIcon/index.ts +1 -0
  101. package/src/icons/DocumentPythonIcon/DocumentPythonIcon.tsx +37 -0
  102. package/src/icons/DocumentPythonIcon/index.ts +1 -0
  103. package/src/icons/DocumentShellIcon/DocumentShellIcon.tsx +33 -0
  104. package/src/icons/DocumentShellIcon/index.ts +1 -0
  105. package/src/icons/__tests__/IconTestUtils.tsx +31 -0
  106. package/src/layouts/CodeWalkthroughLayout.tsx +5 -1
  107. package/src/markdoc/components/CodeWalkthrough/CodeContainer.tsx +1 -0
  108. package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +19 -3
  109. package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +1 -1
  110. package/src/markdoc/components/CodeWalkthrough/CodePanelHeader.tsx +64 -47
  111. package/src/markdoc/components/CodeWalkthrough/CodePanelPreview.tsx +1 -1
  112. package/src/markdoc/components/CodeWalkthrough/CodePanelToolbar.tsx +1 -1
  113. package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +6 -2
  114. package/src/markdoc/components/CodeWalkthrough/CodeToggle.tsx +1 -1
  115. package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +4 -1
  116. package/src/markdoc/components/CodeWalkthrough/Input.tsx +4 -2
  117. package/src/markdoc/tags/code-walkthrough.ts +5 -0
@@ -1,10 +1,9 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
2
  import styled, { css } from 'styled-components';
3
3
 
4
4
  import type { CodeWalkthroughFile } from '@redocly/config';
5
5
 
6
- import { useThemeHooks } from '@redocly/theme/core/hooks';
7
- import { getFileIconByExt } from '@redocly/theme/core/utils';
6
+ import { useThemeHooks, useRenderableFiles, type RenderableFile } from '@redocly/theme/core/hooks';
8
7
  import { OverflowMenuVerticalIcon } from '@redocly/theme/icons/OverflowMenuVerticalIcon/OverflowMenuVerticalIcon';
9
8
  import { Dropdown } from '@redocly/theme/components/Dropdown/Dropdown';
10
9
  import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';
@@ -25,32 +24,45 @@ export function CodePanelHeader({
25
24
  activeTabName,
26
25
  onDownloadCode,
27
26
  }: CodePanelHeaderProps): JSX.Element {
27
+ const renderableFiles = useRenderableFiles(files);
28
28
  const { useTranslate } = useThemeHooks();
29
29
  const { translate } = useTranslate();
30
30
  const tabRefs = useRef<HTMLButtonElement[]>([]);
31
31
  const tabsWrapperRef = useRef<HTMLDivElement>(null);
32
- const [hiddenFiles, setHiddenFiles] = useState<CodeWalkthroughFile[]>([]);
32
+ const [hiddenFiles, setHiddenFiles] = useState<RenderableFile[]>([]);
33
33
 
34
34
  useEffect(() => {
35
35
  const activeTab = tabRefs.current.find((tab) => tab?.dataset.name === activeTabName);
36
- if (activeTab) {
37
- activeTab.scrollIntoView({ block: 'nearest', inline: 'center' });
36
+ const tabsWrapper = tabsWrapperRef.current;
37
+
38
+ if (activeTab && tabsWrapper) {
39
+ const { left: wrapperLeft, right: wrapperRight } = tabsWrapper.getBoundingClientRect();
40
+ const { left: tabLeft, right: tabRight } = activeTab.getBoundingClientRect();
41
+ const tabHidden = tabLeft < wrapperLeft || tabRight > wrapperRight;
42
+
43
+ if (tabHidden) {
44
+ activeTab.scrollIntoView({ block: 'nearest', inline: 'nearest' });
45
+ }
38
46
  }
39
- }, [activeTabName]);
40
47
 
41
- useEffect(() => {
42
48
  const calculateHiddenFiles = () => {
43
49
  if (!tabsWrapperRef.current) return;
44
50
  const { left: wrapperLeft, right: wrapperRight } =
45
51
  tabsWrapperRef.current.getBoundingClientRect();
46
52
 
47
- const hidden = files.filter((_, i) => {
53
+ const hidden: RenderableFile[] = [];
54
+
55
+ for (let i = 0; i < renderableFiles.length; i++) {
48
56
  const tab = tabRefs.current[i];
49
- if (!tab) return false;
57
+ if (!tab) continue;
58
+
50
59
  const { left: tabLeft, right: tabRight } = tab.getBoundingClientRect();
60
+ const visible = tabLeft > wrapperLeft && tabRight < wrapperRight;
51
61
 
52
- return tabLeft < wrapperLeft || tabRight > wrapperRight;
53
- });
62
+ if (!visible) {
63
+ hidden.push(renderableFiles[i]);
64
+ }
65
+ }
54
66
 
55
67
  setHiddenFiles(hidden);
56
68
  };
@@ -58,32 +70,29 @@ export function CodePanelHeader({
58
70
  calculateHiddenFiles();
59
71
  window.addEventListener('resize', calculateHiddenFiles);
60
72
  return () => window.removeEventListener('resize', calculateHiddenFiles);
61
- }, [files]);
62
-
63
- const getFileTypeIcon = useCallback((basename: string) => {
64
- const extension = basename.split('.').pop()?.toLowerCase() || '';
65
- return getFileIconByExt(extension);
66
- }, []);
73
+ }, [activeTabName, files, renderableFiles]);
67
74
 
68
75
  return (
69
76
  <CodePanelHeaderWrapper data-component-name="Markdoc/CodeWalkthrough/CodePanelHeader">
70
77
  <TabsWrapper ref={tabsWrapperRef}>
71
78
  <Tabs>
72
- {files.map(({ path, basename }, i) => {
73
- const FileIcon = getFileTypeIcon(basename);
74
- return (
75
- <Tab
76
- ref={(el: HTMLButtonElement) => (tabRefs.current[i] = el)}
77
- data-name={path}
78
- active={path === activeTabName}
79
- key={i}
80
- onClick={() => handleTabSwitch(path)}
81
- >
82
- <FileIcon />
83
- {basename}
84
- </Tab>
85
- );
86
- })}
79
+ {renderableFiles.map(
80
+ ({ path, basename, FileIcon, parentFolder, isNameDuplicate, inRootDir }, i) => {
81
+ return (
82
+ <Tab
83
+ ref={(el: HTMLButtonElement) => (tabRefs.current[i] = el)}
84
+ data-name={path}
85
+ active={path === activeTabName}
86
+ key={i}
87
+ onClick={() => handleTabSwitch(path)}
88
+ >
89
+ <FileIcon />
90
+ {basename}
91
+ {isNameDuplicate && !inRootDir ? <Dirname>{parentFolder}</Dirname> : null}
92
+ </Tab>
93
+ );
94
+ },
95
+ )}
87
96
  </Tabs>
88
97
  <Gradient />
89
98
  </TabsWrapper>
@@ -92,18 +101,21 @@ export function CodePanelHeader({
92
101
  {hiddenFiles.length ? (
93
102
  <Dropdown trigger={<StyledOverflowMenuVerticalIcon size="14px" />} alignment="end">
94
103
  <StyledDropdownMenu>
95
- {hiddenFiles.map(({ path, basename }, i) => {
96
- const FileIcon = getFileTypeIcon(basename);
97
- return (
98
- <DropdownMenuItem
99
- active={path === activeTabName}
100
- key={i}
101
- onAction={() => handleTabSwitch(path)}
102
- prefix={<FileIcon />}
103
- content={basename}
104
- />
105
- );
106
- })}
104
+ {hiddenFiles.map(
105
+ ({ path, basename, FileIcon, isNameDuplicate, inRootDir, parentFolder }, i) => {
106
+ return (
107
+ <DropdownMenuItem
108
+ active={path === activeTabName}
109
+ key={i}
110
+ onAction={() => handleTabSwitch(path)}
111
+ prefix={<FileIcon />}
112
+ content={
113
+ isNameDuplicate && !inRootDir ? `${parentFolder}/${basename}` : basename
114
+ }
115
+ />
116
+ );
117
+ },
118
+ )}
107
119
  </StyledDropdownMenu>
108
120
  </Dropdown>
109
121
  ) : null}
@@ -141,7 +153,7 @@ const Gradient = styled.div`
141
153
 
142
154
  const Tabs = styled.div`
143
155
  display: flex;
144
- overflow-x: auto;
156
+ overflow-x: hidden;
145
157
  padding-right: var(--spacing-base);
146
158
 
147
159
  &::-webkit-scrollbar {
@@ -149,6 +161,11 @@ const Tabs = styled.div`
149
161
  }
150
162
  `;
151
163
 
164
+ const Dirname = styled.span`
165
+ font-size: var(--font-size-sm);
166
+ color: var(--text-color-description);
167
+ `;
168
+
152
169
  const ActionBar = styled.div`
153
170
  display: flex;
154
171
  `;
@@ -164,7 +181,7 @@ const Tab = styled.button<{ active: boolean }>`
164
181
  gap: var(--spacing-xs);
165
182
  color: var(--text-color-secondary);
166
183
  white-space: nowrap;
167
-
184
+ scroll-margin-right: var(--spacing-base);
168
185
  ${({ active }) =>
169
186
  active
170
187
  ? css`
@@ -11,7 +11,7 @@ export function CodePanelPreview({ children }: PropsWithChildren): JSX.Element {
11
11
  const { translate } = useTranslate();
12
12
 
13
13
  return (
14
- <CodePanelPreviewWrapper>
14
+ <CodePanelPreviewWrapper data-component-name="Markdoc/CodeWalkthrough/CodePanelPreview">
15
15
  <PreviewDropdown onClick={() => setIsOpen(!isOpen)}>
16
16
  {translate('codeWalkthrough.preview', 'Preview')}
17
17
  {isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}
@@ -16,7 +16,7 @@ export function CodePanelToolbar({ file }: CodeToolbarProps): JSX.Element {
16
16
  const fileContent = getFileText(file);
17
17
 
18
18
  return (
19
- <CodeToolbarWrapper>
19
+ <CodeToolbarWrapper data-component-name="Markdoc/CodeWalkthrough/CodePanelToolbar">
20
20
  <CopyButton data={fileContent} type="compound" variant="secondary" size="medium" />
21
21
  </CodeToolbarWrapper>
22
22
  );
@@ -35,7 +35,7 @@ export function CodeStep({
35
35
  lockObserver.current = true;
36
36
 
37
37
  if (compRef.current) {
38
- compRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
38
+ compRef.current.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
39
39
  }
40
40
 
41
41
  setActiveStep(id);
@@ -70,7 +70,7 @@ export function CodeStep({
70
70
 
71
71
  const filtersElementHeight = filtersElementRef?.current?.clientHeight || 0;
72
72
  const navbarHeight = document.querySelector('nav')?.clientHeight || 0;
73
- setScrollMarginTop(filtersElementHeight + navbarHeight);
73
+ setScrollMarginTop(filtersElementHeight + navbarHeight + 10);
74
74
 
75
75
  return () => {
76
76
  if (currentCompRef) {
@@ -80,11 +80,15 @@ export function CodeStep({
80
80
  }, [activeStep, register, unregister, filtersElementRef]);
81
81
 
82
82
  if (!areConditionsMet({ when, unless })) {
83
+ if (isActive) {
84
+ setActiveStep(null);
85
+ }
83
86
  return null;
84
87
  }
85
88
 
86
89
  return (
87
90
  <StepWrapper
91
+ data-component-name="Markdoc/CodeWalkthrough/CodeStep"
88
92
  ref={compRef}
89
93
  isActive={isActive}
90
94
  scrollMarginTop={scrollMarginTop}
@@ -23,7 +23,7 @@ export function CodeToggle(props: CodeToggleProps) {
23
23
  const checked = toggleState.value;
24
24
 
25
25
  return (
26
- <ToggleWrapper>
26
+ <ToggleWrapper data-component-name="Markdoc/CodeWalkthrough/CodeToggle">
27
27
  <ToggleContentWrapper>
28
28
  <ToggleSubtitle>
29
29
  <Switch value={checked} onChange={(newValue) => changeToggleState(id, newValue)} />
@@ -28,7 +28,10 @@ export function CodeWalkthrough({ children, steps, preview, ...attributes }: Cod
28
28
  return (
29
29
  <CodeWalkthroughStepsContext.Provider value={stepsState}>
30
30
  <CodeWalkthroughControlsStateContext.Provider value={controlsState}>
31
- <CodeWalkthroughWrapper className="code-walkthrough">
31
+ <CodeWalkthroughWrapper
32
+ className="code-walkthrough"
33
+ data-component-name="Markdoc/CodeWalkthrough/CodeWalkthrough"
34
+ >
32
35
  <DocsPanel>
33
36
  <CodeFilters
34
37
  filters={activeFilters}
@@ -41,7 +41,7 @@ export function Input(props: InputProps) {
41
41
  };
42
42
 
43
43
  return (
44
- <InputWrapper>
44
+ <InputWrapper data-component-name="Markdoc/CodeWalkthrough/Input">
45
45
  {label && <Label>{label}</Label>}
46
46
  <StyledInput
47
47
  id={id}
@@ -57,7 +57,8 @@ export function Input(props: InputProps) {
57
57
  const InputWrapper = styled.div`
58
58
  display: flex;
59
59
  flex-direction: column;
60
- margin: var(--md-paragraph-margin);
60
+ margin-top: var(--spacing-base);
61
+ margin-bottom: var(--spacing-base);
61
62
  `;
62
63
 
63
64
  const Label = styled.p`
@@ -66,6 +67,7 @@ const Label = styled.p`
66
67
  line-height: var(--line-height-base);
67
68
  font-family: var(--font-family-base);
68
69
  font-weight: var(--font-weight-medium);
70
+ margin-bottom: var(--spacing-xxs) !important;
69
71
  `;
70
72
 
71
73
  const StyledInput = styled.input`
@@ -44,6 +44,11 @@ export const codeWalkthrough: MarkdocSchemaWrapper = {
44
44
  render: false,
45
45
  required: false,
46
46
  },
47
+ __idx: {
48
+ type: Number,
49
+ render: true,
50
+ required: false,
51
+ },
47
52
  },
48
53
  slots: {
49
54
  preview: { required: false, render: true },