@apify/ui-library 0.71.1-featcolortokens-178953.56 → 0.71.1-featcolortokens-178953.63

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 (134) hide show
  1. package/dist/src/design_system/colors/generated/{dark.d.ts → css_variables.dark.d.ts} +1 -1
  2. package/dist/src/design_system/colors/generated/css_variables.dark.d.ts.map +1 -0
  3. package/dist/src/design_system/colors/generated/{dark.js → css_variables.dark.js} +1 -1
  4. package/dist/src/design_system/colors/generated/css_variables.dark.js.map +1 -0
  5. package/dist/src/design_system/colors/generated/{light.d.ts → css_variables.light.d.ts} +1 -1
  6. package/dist/src/design_system/colors/generated/css_variables.light.d.ts.map +1 -0
  7. package/{src/design_system/colors/generated/light.ts → dist/src/design_system/colors/generated/css_variables.light.js} +1 -1
  8. package/dist/src/design_system/colors/generated/css_variables.light.js.map +1 -0
  9. package/dist/src/design_system/colors/generated/{palette.dark.d.ts → css_variables_palette.dark.d.ts} +1 -1
  10. package/dist/src/design_system/colors/generated/css_variables_palette.dark.d.ts.map +1 -0
  11. package/dist/src/design_system/colors/generated/{palette.dark.js → css_variables_palette.dark.js} +1 -1
  12. package/dist/src/design_system/colors/generated/css_variables_palette.dark.js.map +1 -0
  13. package/dist/src/design_system/colors/generated/{palette.light.d.ts → css_variables_palette.light.d.ts} +1 -1
  14. package/dist/src/design_system/colors/generated/css_variables_palette.light.d.ts.map +1 -0
  15. package/{src/design_system/colors/generated/palette.light.ts → dist/src/design_system/colors/generated/css_variables_palette.light.js} +1 -1
  16. package/dist/src/design_system/colors/generated/css_variables_palette.light.js.map +1 -0
  17. package/dist/src/design_system/colors/index.d.ts +4 -4
  18. package/dist/src/design_system/colors/index.d.ts.map +1 -1
  19. package/dist/src/design_system/colors/index.js +4 -4
  20. package/dist/src/design_system/colors/index.js.map +1 -1
  21. package/dist/tsconfig.build.tsbuildinfo +1 -0
  22. package/package.json +7 -5
  23. package/.stylelintrc +0 -12
  24. package/CHANGELOG.md +0 -3334
  25. package/CODEOWNERS +0 -7
  26. package/dist/src/design_system/colors/generated/dark.d.ts.map +0 -1
  27. package/dist/src/design_system/colors/generated/dark.js.map +0 -1
  28. package/dist/src/design_system/colors/generated/light.d.ts.map +0 -1
  29. package/dist/src/design_system/colors/generated/light.js +0 -147
  30. package/dist/src/design_system/colors/generated/light.js.map +0 -1
  31. package/dist/src/design_system/colors/generated/palette.dark.d.ts.map +0 -1
  32. package/dist/src/design_system/colors/generated/palette.dark.js.map +0 -1
  33. package/dist/src/design_system/colors/generated/palette.light.d.ts.map +0 -1
  34. package/dist/src/design_system/colors/generated/palette.light.js +0 -74
  35. package/dist/src/design_system/colors/generated/palette.light.js.map +0 -1
  36. package/dist/src/design_system/colors_theme.d.ts +0 -213
  37. package/dist/src/design_system/colors_theme.d.ts.map +0 -1
  38. package/dist/src/design_system/colors_theme.js +0 -213
  39. package/dist/src/design_system/colors_theme.js.map +0 -1
  40. package/dist/src/design_system/properties_theme.d.ts +0 -175
  41. package/dist/src/design_system/properties_theme.d.ts.map +0 -1
  42. package/dist/src/design_system/properties_theme.js +0 -315
  43. package/dist/src/design_system/properties_theme.js.map +0 -1
  44. package/eslint.config.mjs +0 -44
  45. package/src/codemods/generate_typograpy_tokens_files.mjs +0 -137
  46. package/src/components/action_link.tsx +0 -60
  47. package/src/components/actor_template_card.tsx +0 -116
  48. package/src/components/badge.tsx +0 -148
  49. package/src/components/banner.tsx +0 -94
  50. package/src/components/blog_article.tsx +0 -85
  51. package/src/components/box.tsx +0 -127
  52. package/src/components/button.tsx +0 -305
  53. package/src/components/chip.tsx +0 -128
  54. package/src/components/code/action_button.tsx +0 -96
  55. package/src/components/code/code_block/code_block.styled.tsx +0 -180
  56. package/src/components/code/code_block/code_block.tsx +0 -224
  57. package/src/components/code/code_block/code_block_with_tabs.tsx +0 -257
  58. package/src/components/code/code_block/utils.tsx +0 -67
  59. package/src/components/code/index.ts +0 -5
  60. package/src/components/code/inline_code/inline_code.tsx +0 -62
  61. package/src/components/code/one_line_code/one_line_code.tsx +0 -228
  62. package/src/components/code/prism_highlighter.tsx +0 -180
  63. package/src/components/color_wheel_gradient.tsx +0 -31
  64. package/src/components/floating/index.ts +0 -3
  65. package/src/components/floating/menu.tsx +0 -189
  66. package/src/components/floating/menu_common.tsx +0 -31
  67. package/src/components/floating/menu_components.tsx +0 -99
  68. package/src/components/image.tsx +0 -24
  69. package/src/components/index.ts +0 -22
  70. package/src/components/link.tsx +0 -114
  71. package/src/components/message.tsx +0 -153
  72. package/src/components/rating.tsx +0 -106
  73. package/src/components/readme_renderer/index.ts +0 -3
  74. package/src/components/readme_renderer/pythonize_value.ts +0 -76
  75. package/src/components/readme_renderer/table_of_contents.tsx +0 -272
  76. package/src/components/readme_renderer/utils.tsx +0 -46
  77. package/src/components/simple_markdown/index.ts +0 -2
  78. package/src/components/simple_markdown/simple_markdown.tsx +0 -214
  79. package/src/components/simple_markdown/simple_markdown_components.tsx +0 -293
  80. package/src/components/tabs/index.ts +0 -2
  81. package/src/components/tabs/tab.tsx +0 -217
  82. package/src/components/tabs/tabs.tsx +0 -169
  83. package/src/components/tag.tsx +0 -196
  84. package/src/components/text/heading_content.tsx +0 -56
  85. package/src/components/text/heading_marketing.tsx +0 -55
  86. package/src/components/text/heading_shared.tsx +0 -55
  87. package/src/components/text/index.ts +0 -19
  88. package/src/components/text/text_base.tsx +0 -52
  89. package/src/components/text/text_content.tsx +0 -104
  90. package/src/components/text/text_marketing.tsx +0 -152
  91. package/src/components/text/text_shared.tsx +0 -95
  92. package/src/components/tile/horizontal_tile.tsx +0 -77
  93. package/src/components/tile/index.ts +0 -2
  94. package/src/components/tile/shared.ts +0 -27
  95. package/src/components/tile/vertical_tile.tsx +0 -59
  96. package/src/components/to_consolidate/card.tsx +0 -141
  97. package/src/components/to_consolidate/index.ts +0 -4
  98. package/src/components/to_consolidate/markdown.tsx +0 -609
  99. package/src/components/to_consolidate/pagination.tsx +0 -136
  100. package/src/components/to_consolidate/tab_number_chip.tsx +0 -31
  101. package/src/design_system/colors/build_color_tokens.js +0 -175
  102. package/src/design_system/colors/figma_color_tokens.dark.json +0 -886
  103. package/src/design_system/colors/figma_color_tokens.light.json +0 -886
  104. package/src/design_system/colors/generated/colors_theme.dark.ts +0 -110
  105. package/src/design_system/colors/generated/colors_theme.light.ts +0 -110
  106. package/src/design_system/colors/generated/dark.ts +0 -147
  107. package/src/design_system/colors/generated/palette.dark.ts +0 -74
  108. package/src/design_system/colors/generated/properties_theme.ts +0 -179
  109. package/src/design_system/colors/index.ts +0 -7
  110. package/src/design_system/colors_theme.ts +0 -213
  111. package/src/design_system/properties_theme.ts +0 -453
  112. package/src/design_system/supernova_typography_tokens.json +0 -657
  113. package/src/design_system/theme.ts +0 -25
  114. package/src/design_system/tokens/index.ts +0 -5
  115. package/src/design_system/tokens/layouts.ts +0 -29
  116. package/src/design_system/tokens/radiuses.ts +0 -22
  117. package/src/design_system/tokens/shadows.ts +0 -22
  118. package/src/design_system/tokens/spaces.ts +0 -15
  119. package/src/design_system/tokens/transitions.ts +0 -19
  120. package/src/design_system/typography_theme.ts +0 -197
  121. package/src/index.ts +0 -8
  122. package/src/type_utils.ts +0 -7
  123. package/src/ui_dependency_provider.tsx +0 -58
  124. package/src/utils/copy_to_clipboard.ts +0 -24
  125. package/src/utils/image_color.ts +0 -42
  126. package/src/utils/index.ts +0 -4
  127. package/src/utils/resize_observer.ts +0 -18
  128. package/src/utils/sanitization.ts +0 -14
  129. package/tsconfig.build.json +0 -17
  130. package/tsconfig.json +0 -10
  131. /package/{src/design_system/colors/generated → style/colors}/dark.scss +0 -0
  132. /package/{src/design_system/colors/generated → style/colors}/light.scss +0 -0
  133. /package/{src/design_system/colors/generated → style/colors}/palette.dark.scss +0 -0
  134. /package/{src/design_system/colors/generated → style/colors}/palette.light.scss +0 -0
@@ -1,272 +0,0 @@
1
- import _ from 'lodash';
2
- import React, {
3
- useCallback,
4
- useMemo,
5
- } from 'react';
6
- import ReactMarkdown from 'react-markdown';
7
- import type { AllowElement } from 'react-markdown/lib/rehype-filter';
8
- import remarkToc from 'remark-toc';
9
- import styled from 'styled-components';
10
-
11
- import { theme } from '../../design_system/theme.js';
12
- import { inlineCodeStyles } from '../code/index.js';
13
- import { Link } from '../link.js';
14
- import { Text } from '../text/index.js';
15
- import { cleanMarkdown, slugifyHeadingChildren } from './utils.js';
16
-
17
- const TOC_HEADING_ID = 'Contents';
18
-
19
- const StyledTOCLink = styled(Text)`
20
- display: inline-block;
21
- color: ${theme.color.neutral.textMuted};
22
- text-decoration: none;
23
-
24
- /* Do no change the font style if the heading is defined as bold in the markdown and is wrapped in a <strong> tag */
25
- strong {
26
- font-size: inherit !important;
27
- line-height: inherit !important;
28
- font-weight: inherit !important;
29
- }
30
-
31
- &:hover, &.selected {
32
- color: ${theme.color.primary.text} !important;
33
- }
34
-
35
- &:before {
36
- content: " ";
37
- display: inline-block;
38
- height: 100%;
39
- left: 0;
40
- margin-top: -1px;
41
- position: absolute;
42
- width: 1px;
43
- background-color: ${theme.color.neutral.border};
44
- }
45
-
46
- &.selected:before {
47
- background-color: ${theme.color.primary.text};
48
- }
49
- `;
50
-
51
- const StyledTableOfContents = styled.div`
52
- position: relative;
53
- overflow: hidden;
54
-
55
- p {
56
- margin: 0;
57
- }
58
-
59
- .level-3 a {
60
- color: ${theme.color.neutral.textSubtle};
61
- }
62
-
63
- ul {
64
- padding-left: ${theme.space.space8} !important;
65
- list-style: none;
66
- margin: 0;
67
- overflow-y: auto;
68
-
69
- &.level-3 {
70
- padding-left: ${theme.space.space16} !important;
71
- max-height: 0;
72
- overflow: hidden;
73
- transition: all .3s ease-in-out;
74
-
75
- &.expanded {
76
- max-height: 1000px;
77
- }
78
- }
79
- }
80
-
81
- .inline-code {
82
- ${inlineCodeStyles}
83
- }
84
- `;
85
-
86
- interface CustomHTMLAnchorElement extends Omit<HTMLAnchorElement, 'children' | 'parentNode'> {
87
- hash: string;
88
- tagName: string;
89
- type: string;
90
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
- parentNode: any;
92
- }
93
-
94
- const handleScroll = (anchors: CustomHTMLAnchorElement[], headlines: HTMLElement[], anchorLists: HTMLUListElement[] | null, headingOffsetPx: number) => {
95
- if (!anchors || !headlines) return;
96
-
97
- // Items that are past scroll
98
- const headlinesPastScrollPosition = headlines.filter((headline) => {
99
- return headline.getBoundingClientRect().top - headingOffsetPx < 0;
100
- });
101
-
102
- // Last item that is past the scroll is current in view. If no headline is past the scroll, let's select the first one
103
- const currentHeadlineId = headlinesPastScrollPosition[headlinesPastScrollPosition.length - 1]?.id || headlines[0]?.id;
104
-
105
- // Highlighting anchor of current headline
106
- if (currentHeadlineId) {
107
- const currentHash = `#${currentHeadlineId}`;
108
-
109
- anchorLists?.forEach((anchorList) => anchorList.classList.remove('expanded'));
110
-
111
- // Remove selected class from all anchors and only add it to the current one
112
- anchors.forEach((anchor) => {
113
- anchor.classList.remove('selected');
114
- if (anchor.hash === currentHash) {
115
- anchor.classList.add('selected');
116
-
117
- const grandparent = anchor.parentNode?.parentNode;
118
-
119
- // Structure of the table of content is normalized so we can figure out if section should be expanded
120
- // by tag and className of neighboring nodes. There are two cases:
121
-
122
- // 1) If h2 is selected, we want to expand its section with h3 headings
123
- if (grandparent?.tagName === 'LI' && grandparent.children[1]?.tagName === 'UL' && grandparent.children[1]?.classList.contains('level-3')) {
124
- grandparent.children[1].classList.add('expanded');
125
- }
126
-
127
- // 2) We also want to expand section of h3 headings that follow h1 right away
128
- if (grandparent?.tagName === 'UL' && grandparent.classList.contains('level-3')) {
129
- grandparent.classList.add('expanded');
130
- }
131
- }
132
- });
133
- }
134
- };
135
-
136
- const assignHeadingLevelsRecursively = (
137
- {
138
- children,
139
- tagName,
140
- properties,
141
- }: {
142
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
143
- children: any[],
144
- tagName: string,
145
- properties: { className: string }
146
- },
147
- level: number,
148
- ) => {
149
- if (level > 3) return;
150
- let currentLevel = level;
151
- if (tagName === 'ul') {
152
- // eslint-disable-next-line no-param-reassign
153
- properties.className = `level-${currentLevel}`; // assign level className
154
- currentLevel += 1; // increase current heading level;
155
- }
156
-
157
- children?.forEach((child) => {
158
- // We only care about ul and li elements - we don't need to traverse any other
159
- if (child.type === 'element' && (tagName === 'ul' || tagName === 'li')) {
160
- assignHeadingLevelsRecursively(child, currentLevel);
161
- }
162
- });
163
- };
164
-
165
- export interface TableOfContentsProps {
166
- markdown: string;
167
- headingOffsetPx?: number; // How far from the top should the toc detect the current heading
168
- // Function where we can define which elements are allowed in the markdown. See https://github.com/remarkjs/react-markdown#props for more info
169
- allowElement?: AllowElement;
170
- }
171
-
172
- const TableOfContentsComponent = ({
173
- markdown,
174
- headingOffsetPx = 10,
175
- allowElement,
176
- ...rest
177
- }: TableOfContentsProps) => {
178
- const cleanedMarkdown = useMemo(() => {
179
- const cleanedMarkdownString = cleanMarkdown(markdown);
180
- return `### ${TOC_HEADING_ID}\n${cleanedMarkdownString}`;
181
- }, [markdown]);
182
-
183
- const hasTopLevelHeading = useMemo(() => !!cleanedMarkdown.match(/^#\s.+$/m), [cleanedMarkdown]);
184
-
185
- const tocRef = useCallback((node: HTMLElement | null) => {
186
- const anchors = node ? Array.from(node.querySelectorAll('a')) : [];
187
- const anchorLists = node ? Array.from(node.querySelectorAll('ul')) : null;
188
- const headlines = (anchors)
189
- .map((anchor) => document.getElementById(anchor.hash.substr(1)))
190
- .filter((headline) => headline !== undefined && headline !== null) as HTMLElement[];
191
-
192
- const scrollHandler = () => handleScroll(anchors, headlines, anchorLists, headingOffsetPx);
193
-
194
- // Callback refs cannot return cleanup functions - but they are called again with null on unmount
195
- if (node) {
196
- window.addEventListener('scroll', scrollHandler);
197
- } else {
198
- window.removeEventListener('scroll', scrollHandler);
199
- }
200
- scrollHandler(); // call for the first time so we select the first heading without scrolling
201
- }, [headingOffsetPx]);
202
-
203
- return (
204
- <StyledTableOfContents ref={tocRef} {...rest}>
205
- <ReactMarkdown
206
- allowElement={allowElement}
207
- remarkPlugins={[
208
- [remarkToc, { heading: TOC_HEADING_ID, maxDepth: 3 }],
209
- () => ({ children, ...nodeRest }) => {
210
- // TOC plug-ins only inject content table to existing markdown documents - only generating it is not a common use-case
211
- // To make is happen, we can just take the generated node where toc is located and throw away the rest.
212
- // children[0] is the heading where toc is placed (that's plug-in's requirement)
213
- // children[1] is the generated table of contents we can simply pick
214
-
215
- let tocContentNode = children[1];
216
-
217
- // If there is no H1 heading in the readme then assignHeadingLevelsRecursively does not work correctly.
218
- // We need to 'normalize' the final node to have all the levels we expect
219
- // - solution is to wrap the content in extra node that mimic this H1 group that remarkToc would normally create
220
- if (!hasTopLevelHeading) {
221
- tocContentNode = {
222
- type: 'list',
223
- ordered: false,
224
- spread: false,
225
- children: [
226
- {
227
- type: 'listItem',
228
- spread: true,
229
- children: [
230
- tocContentNode,
231
- ],
232
- },
233
- ],
234
- };
235
- }
236
-
237
- return {
238
- ...nodeRest,
239
- children: [
240
- tocContentNode,
241
- ],
242
- };
243
- },
244
- ]}
245
- rehypePlugins={[() => (input) => {
246
- // this plug-in already works with html node representation so we can assign classNames that we need
247
- // in order to allow hiding blocks with h3 headings that are out of the viewport
248
- assignHeadingLevelsRecursively(input.children[0], 1);
249
- return input;
250
- }]}
251
- components={{
252
- a: ({ children }) => (
253
- <StyledTOCLink
254
- forwardedAs={Link}
255
- to={`#${slugifyHeadingChildren(children)}`}
256
- py={'space4'}
257
- >
258
- {children}
259
- </StyledTOCLink>
260
- ),
261
- code: ({ children }) => (
262
- <code className="inline-code">{children}</code>
263
- ),
264
- }}
265
- >
266
- {cleanedMarkdown}
267
- </ReactMarkdown>
268
- </StyledTableOfContents>
269
- );
270
- };
271
-
272
- export const TableOfContents = React.memo(TableOfContentsComponent, (prevProps, nextProps) => _.isEqual(prevProps, nextProps));
@@ -1,46 +0,0 @@
1
- import React, { useCallback } from 'react';
2
- import type { AllowElement } from 'react-markdown/lib/rehype-filter';
3
- import slugify from 'slugify';
4
-
5
- export const slugifyHeadingChildren = (
6
- headingChildren: React.ReactNode,
7
- ): string | undefined => {
8
- if (!headingChildren) return undefined;
9
-
10
- const slugs: string[] = [];
11
- React.Children.forEach(headingChildren, (child) => {
12
- if (typeof child === 'string') {
13
- slugs.push(slugify(child, { lower: true, strict: true }));
14
- } else if (React.isValidElement(child) && child.props.children) {
15
- const nestedSlugs = slugifyHeadingChildren(child.props.children);
16
- if (nestedSlugs) slugs.push(nestedSlugs);
17
- }
18
- });
19
-
20
- return slugs.join('-');
21
- };
22
-
23
- export const cleanMarkdown = (markdown: string, removeFirstH1?: boolean): string => {
24
- // Remove the table of contents as we are generating our own
25
- let clean = markdown
26
- .replace(/<!-- toc start -->.*?<!-- toc end -->/s, '')
27
- .replace(/##.*content.*?\n*<!-- toc -->(.|[\r\n])*<!-- tocstop -->\n*/, '');
28
-
29
- // Remove first h1 if removeFirstH1 is true
30
- if (removeFirstH1) clean = clean.replace(removeFirstH1 ? /^#\s.+$/m : '', '');
31
-
32
- return clean.trim();
33
- };
34
-
35
- // This removes the first element if it's a `h1` containing exactly the Actor title
36
- export const useActorTitleHeadingFilter = (actorTitle: string): AllowElement => {
37
- return useCallback((element, index, parent) => {
38
- if (parent.type === 'root'
39
- && index === 0
40
- && element.tagName === 'h1'
41
- && element.children.length === 1
42
- && element.children[0].type === 'text'
43
- && element.children[0].value?.toLowerCase() === actorTitle.toLowerCase()) return false;
44
- return true;
45
- }, [actorTitle]);
46
- };
@@ -1,2 +0,0 @@
1
- export * from './simple_markdown.js';
2
- export * from './simple_markdown_components.js';
@@ -1,214 +0,0 @@
1
- import type { Element, Root, Text as TextNode } from 'hast';
2
- import React, { useCallback, useMemo, useRef } from 'react';
3
- import type { Components } from 'react-markdown';
4
- import ReactMarkdown, { uriTransformer } from 'react-markdown';
5
- import type { ReactMarkdownOptions } from 'react-markdown/lib/react-markdown';
6
- import rehypeRaw from 'rehype-raw';
7
- import rehypeSanitize from 'rehype-sanitize';
8
- import remarkGfm from 'remark-gfm';
9
- import styled from 'styled-components';
10
- import type { Pluggable, PluggableList } from 'unified';
11
- import { visit } from 'unist-util-visit';
12
-
13
- import { theme } from '../../design_system/theme.js';
14
- import { useSharedUiDependencies } from '../../ui_dependency_provider.js';
15
- import { Box } from '../box.js';
16
- import { isUrlExternal } from '../link.js';
17
- import { cleanMarkdown } from '../readme_renderer/utils.js';
18
- import { HeadingContent } from '../text/heading_content.js';
19
- import { Heading, Text } from '../text/index.js';
20
- import { TextContent } from '../text/text_content.js';
21
- import {
22
- MarkdownBlockQuote,
23
- MarkdownCode,
24
- MarkdownLink,
25
- MarkdownTable,
26
- } from './simple_markdown_components.js';
27
-
28
- export type SimpleMarkdownComponents = Components;
29
-
30
- export const defaultAllowedElements = [
31
- 'a',
32
- 'b',
33
- 'blockquote',
34
- 'br',
35
- 'center',
36
- 'code',
37
- 'del',
38
- 'em',
39
- 'h1',
40
- 'h2',
41
- 'h3',
42
- 'h4',
43
- 'h5',
44
- 'hr',
45
- 'i',
46
- 'img',
47
- 'li',
48
- 'ol',
49
- 'p',
50
- 'pre',
51
- 'span',
52
- 'strong',
53
- 'table',
54
- 'tbody',
55
- 'td',
56
- 'tfoot',
57
- 'th',
58
- 'thead',
59
- 'tr',
60
- 'u',
61
- 'ul',
62
- ];
63
-
64
- const StyledMarkdown = styled(ReactMarkdown)`
65
- scroll-margin-top: 10px;
66
-
67
- @font-face {
68
- font-family: "ellipsis-font";
69
- src: local("Courier");
70
- unicode-range: U+2026;
71
- size-adjust: 0%;
72
- }
73
-
74
- img {
75
- max-width: 100%;
76
- }
77
-
78
- hr {
79
- color: ${theme.color.neutral.border};
80
- }
81
- `;
82
-
83
- // Function to recursively process unsupported elements
84
- const unwrapUnsupportedElement = (node: Element): (Element | TextNode)[] => {
85
- return node.children.flatMap((child) => {
86
- if (child.type === 'text') {
87
- return child; // Keep text as is
88
- }
89
- if (child.type === 'element') {
90
- if (defaultAllowedElements.includes(child.tagName)) {
91
- return child; // Keep supported elements
92
- }
93
- return unwrapUnsupportedElement(child as Element);
94
- }
95
- return []; // Ignore other node types
96
- });
97
- };
98
-
99
- const getUnsupportedRehypeTagsSanitationPlugIn = (
100
- allowedElements: string[],
101
- ): Pluggable<unknown[]> => () => (tree: Root) => {
102
- visit(tree, 'element', (node, index, parent) => {
103
- if (!allowedElements.includes(node.tagName) && parent && typeof index === 'number') {
104
- // Replace unsupported element with its valid children
105
- parent.children.splice(index, 1, ...unwrapUnsupportedElement(node));
106
- }
107
- });
108
- };
109
-
110
- export const defaultRehypePlugins = [rehypeRaw];
111
- export const defaultRemarkPlugins = [remarkGfm];
112
-
113
- // TODO: Add Image component
114
- const regularMarkdownSizeComponents: Components = {
115
- h1: ({ children }) => <HeadingContent mt='space32' mb='space16' type='heading1'>{children}</HeadingContent>,
116
- h2: ({ children }) => <HeadingContent mt='space32' mb='space16' type='heading2'>{children}</HeadingContent>,
117
- h3: ({ children }) => <HeadingContent mt='space32' mb='space16' type='heading3'>{children}</HeadingContent>,
118
- h4: ({ children }) => <HeadingContent mt='space32' mb='space16' type='heading4'>{children}</HeadingContent>,
119
- h5: ({ children }) => <HeadingContent mt='space32' mb='space16' type='heading5'>{children}</HeadingContent>,
120
- h6: ({ children }) => <HeadingContent mt='space32' mb='space16' type='heading6'>{children}</HeadingContent>,
121
- p: ({ children }) => (<TextContent my='space16'>{children}</TextContent>),
122
- strong: ({ children }) => <TextContent as='strong' weight='bold'>{children}</TextContent>,
123
- b: ({ children }) => <TextContent as='b' weight='bold'>{children}</TextContent>,
124
- th: ({ children }) => <TextContent as='th' weight='bold'>{children}</TextContent>,
125
- blockquote: ({ children }) => <MarkdownBlockQuote>{children}</MarkdownBlockQuote>,
126
- table: ({ children }) => <MarkdownTable>{children}</MarkdownTable>,
127
- ul: ({ children }) => <Box as='ul' pl='space32'>{children}</Box>,
128
- ol: ({ children, start }) => <TextContent as='ol' pl='space32' start={start}>{children}</TextContent>,
129
- li: ({ children }) => <TextContent as='li' mt='space4'>{children}</TextContent>,
130
- a: ({ children, href }) => <MarkdownLink to={href}>{children}</MarkdownLink>,
131
- code: ({ children, inline }) => <MarkdownCode inline={inline} size='regular'>{children}</MarkdownCode>,
132
- };
133
-
134
- const smallMarkdownSizeComponents: Components = {
135
- h1: ({ children }) => <Heading mt='space32' mb='space16' type='title2xl'>{children}</Heading>,
136
- h2: ({ children }) => <Heading mt='space32' mb='space16' type='titleXl'>{children}</Heading>,
137
- h3: ({ children }) => <Heading mt='space32' mb='space16' type='titleL'>{children}</Heading>,
138
- h4: ({ children }) => <Heading mt='space32' mb='space16' type='titleM'>{children}</Heading>,
139
- h5: ({ children }) => <Heading mt='space32' mb='space16' type='titleS'>{children}</Heading>,
140
- h6: ({ children }) => <Heading mt='space32' mb='space16' type='titleXs'>{children}</Heading>,
141
- p: ({ children }) => (<Text my='space16'>{children}</Text>),
142
- strong: ({ children }) => <Text as='strong' weight='bold'>{children}</Text>,
143
- b: ({ children }) => <Text as='b' weight='bold'>{children}</Text>,
144
- th: ({ children }) => <Text as='th' weight='bold'>{children}</Text>,
145
- blockquote: ({ children }) => <MarkdownBlockQuote>{children}</MarkdownBlockQuote>,
146
- table: ({ children }) => <MarkdownTable>{children}</MarkdownTable>,
147
- ul: ({ children }) => <Box as='ul' pl='space32'>{children}</Box>,
148
- ol: ({ children, start }) => <Text as='ol' pl='space32' start={start}>{children}</Text>,
149
- li: ({ children }) => <Text as='li' mt='space4'>{children}</Text>,
150
- a: ({ children, href }) => <MarkdownLink to={href}>{children}</MarkdownLink>,
151
- code: ({ children, inline }) => <MarkdownCode inline={inline} size='small'>{children}</MarkdownCode>,
152
- };
153
-
154
- type MarkdownSize = 'regular' | 'small';
155
-
156
- interface SimpleMarkdownProps extends ReactMarkdownOptions {
157
- size?: MarkdownSize,
158
- }
159
-
160
- const useDefaultUrlTransform = () => {
161
- const { windowLocationHost } = useSharedUiDependencies();
162
-
163
- return useCallback((url: string) => {
164
- if (!isUrlExternal(url, windowLocationHost)) {
165
- // We want to make sure internal links will be relative links without https://host at the beginning because Link doesn't work with these
166
- return url.replace(/^(https?:\/\/)?(www\.)?[^/]+/, '') || '/';
167
- }
168
-
169
- return url;
170
- }, [windowLocationHost]);
171
- };
172
-
173
- export const SimpleMarkdown: React.FC<SimpleMarkdownProps> = ({
174
- size = 'regular', // small is default for console
175
- children: markdown,
176
- components,
177
- rehypePlugins,
178
- remarkPlugins,
179
- transformLinkUri,
180
- allowedElements,
181
- ...rest
182
- }) => {
183
- const cleanedMarkdown = useMemo(() => cleanMarkdown(markdown), [markdown]);
184
-
185
- const effectiveAllowedElements = useRef(allowedElements || defaultAllowedElements);
186
-
187
- const effectiveComponents = useRef({
188
- ...(size === 'regular' ? regularMarkdownSizeComponents : smallMarkdownSizeComponents),
189
- ...components,
190
- });
191
-
192
- const rehypePluginsRef = useRef<PluggableList>([
193
- ...(rehypePlugins || [...defaultRehypePlugins, getUnsupportedRehypeTagsSanitationPlugIn(effectiveAllowedElements.current)]),
194
- rehypeSanitize, // lets always sanitize the output
195
- ]);
196
-
197
- const defaultUrlTransform = useDefaultUrlTransform();
198
-
199
- return (
200
- <StyledMarkdown
201
- components={effectiveComponents.current}
202
- rehypePlugins={rehypePluginsRef.current}
203
- remarkPlugins={remarkPlugins || defaultRemarkPlugins}
204
- allowedElements={effectiveAllowedElements.current}
205
- transformLinkUri={(href, children, title) => {
206
- const transformed = transformLinkUri ? transformLinkUri(href, children, title) : defaultUrlTransform(href);
207
- return uriTransformer(transformed);
208
- }}
209
- {...rest}
210
- >
211
- {cleanedMarkdown}
212
- </StyledMarkdown>
213
- );
214
- };