@apify/ui-library 0.51.6-featurepublishuilibrary-0a4729.38266

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 (349) hide show
  1. package/.eslintrc +39 -0
  2. package/.stylelintrc +12 -0
  3. package/CHANGELOG.md +2804 -0
  4. package/README.md +15 -0
  5. package/dist/src/components/action_link.d.ts +5 -0
  6. package/dist/src/components/action_link.d.ts.map +1 -0
  7. package/dist/src/components/action_link.jsx +35 -0
  8. package/dist/src/components/action_link.jsx.map +1 -0
  9. package/dist/src/components/actor_template_card.d.ts +10 -0
  10. package/dist/src/components/actor_template_card.d.ts.map +1 -0
  11. package/dist/src/components/actor_template_card.jsx +73 -0
  12. package/dist/src/components/actor_template_card.jsx.map +1 -0
  13. package/dist/src/components/badge.d.ts +26 -0
  14. package/dist/src/components/badge.d.ts.map +1 -0
  15. package/dist/src/components/badge.jsx +96 -0
  16. package/dist/src/components/badge.jsx.map +1 -0
  17. package/dist/src/components/banner.d.ts +11 -0
  18. package/dist/src/components/banner.d.ts.map +1 -0
  19. package/dist/src/components/banner.jsx +73 -0
  20. package/dist/src/components/banner.jsx.map +1 -0
  21. package/dist/src/components/blog_article.d.ts +9 -0
  22. package/dist/src/components/blog_article.d.ts.map +1 -0
  23. package/dist/src/components/blog_article.jsx +73 -0
  24. package/dist/src/components/blog_article.jsx.map +1 -0
  25. package/dist/src/components/box.d.ts +41 -0
  26. package/dist/src/components/box.d.ts.map +1 -0
  27. package/dist/src/components/box.jsx +48 -0
  28. package/dist/src/components/box.jsx.map +1 -0
  29. package/dist/src/components/button.d.ts +35 -0
  30. package/dist/src/components/button.d.ts.map +1 -0
  31. package/dist/src/components/button.jsx +193 -0
  32. package/dist/src/components/button.jsx.map +1 -0
  33. package/dist/src/components/chip.d.ts +52 -0
  34. package/dist/src/components/chip.d.ts.map +1 -0
  35. package/dist/src/components/chip.jsx +89 -0
  36. package/dist/src/components/chip.jsx.map +1 -0
  37. package/dist/src/components/code/action_button.d.ts +11 -0
  38. package/dist/src/components/code/action_button.d.ts.map +1 -0
  39. package/dist/src/components/code/action_button.jsx +67 -0
  40. package/dist/src/components/code/action_button.jsx.map +1 -0
  41. package/dist/src/components/code/code_block/code_block.d.ts +38 -0
  42. package/dist/src/components/code/code_block/code_block.d.ts.map +1 -0
  43. package/dist/src/components/code/code_block/code_block.jsx +99 -0
  44. package/dist/src/components/code/code_block/code_block.jsx.map +1 -0
  45. package/dist/src/components/code/code_block/code_block.styled.d.ts +13 -0
  46. package/dist/src/components/code/code_block/code_block.styled.d.ts.map +1 -0
  47. package/dist/src/components/code/code_block/code_block.styled.jsx +215 -0
  48. package/dist/src/components/code/code_block/code_block.styled.jsx.map +1 -0
  49. package/dist/src/components/code/code_block/utils.d.ts +2 -0
  50. package/dist/src/components/code/code_block/utils.d.ts.map +1 -0
  51. package/dist/src/components/code/code_block/utils.js +20 -0
  52. package/dist/src/components/code/code_block/utils.js.map +1 -0
  53. package/dist/src/components/code/index.d.ts +4 -0
  54. package/dist/src/components/code/index.d.ts.map +1 -0
  55. package/dist/src/components/code/index.js +4 -0
  56. package/dist/src/components/code/index.js.map +1 -0
  57. package/dist/src/components/code/inline_code/inline_code.d.ts +11 -0
  58. package/dist/src/components/code/inline_code/inline_code.d.ts.map +1 -0
  59. package/dist/src/components/code/inline_code/inline_code.jsx +24 -0
  60. package/dist/src/components/code/inline_code/inline_code.jsx.map +1 -0
  61. package/dist/src/components/code/one_line_code/one_line_code.d.ts +27 -0
  62. package/dist/src/components/code/one_line_code/one_line_code.d.ts.map +1 -0
  63. package/dist/src/components/code/one_line_code/one_line_code.jsx +157 -0
  64. package/dist/src/components/code/one_line_code/one_line_code.jsx.map +1 -0
  65. package/dist/src/components/code/syntax_highlighter.d.ts +16 -0
  66. package/dist/src/components/code/syntax_highlighter.d.ts.map +1 -0
  67. package/dist/src/components/code/syntax_highlighter.jsx +94 -0
  68. package/dist/src/components/code/syntax_highlighter.jsx.map +1 -0
  69. package/dist/src/components/color_wheel_gradient.d.ts +9 -0
  70. package/dist/src/components/color_wheel_gradient.d.ts.map +1 -0
  71. package/dist/src/components/color_wheel_gradient.jsx +23 -0
  72. package/dist/src/components/color_wheel_gradient.jsx.map +1 -0
  73. package/dist/src/components/floating/index.d.ts +4 -0
  74. package/dist/src/components/floating/index.d.ts.map +1 -0
  75. package/dist/src/components/floating/index.js +4 -0
  76. package/dist/src/components/floating/index.js.map +1 -0
  77. package/dist/src/components/floating/menu.d.ts +33 -0
  78. package/dist/src/components/floating/menu.d.ts.map +1 -0
  79. package/dist/src/components/floating/menu.jsx +95 -0
  80. package/dist/src/components/floating/menu.jsx.map +1 -0
  81. package/dist/src/components/floating/menu_common.d.ts +42 -0
  82. package/dist/src/components/floating/menu_common.d.ts.map +1 -0
  83. package/dist/src/components/floating/menu_common.jsx +20 -0
  84. package/dist/src/components/floating/menu_common.jsx.map +1 -0
  85. package/dist/src/components/floating/menu_components.d.ts +29 -0
  86. package/dist/src/components/floating/menu_components.d.ts.map +1 -0
  87. package/dist/src/components/floating/menu_components.jsx +73 -0
  88. package/dist/src/components/floating/menu_components.jsx.map +1 -0
  89. package/dist/src/components/image.d.ts +12 -0
  90. package/dist/src/components/image.d.ts.map +1 -0
  91. package/dist/src/components/image.jsx +8 -0
  92. package/dist/src/components/image.jsx.map +1 -0
  93. package/dist/src/components/index.d.ts +21 -0
  94. package/dist/src/components/index.d.ts.map +1 -0
  95. package/dist/src/components/index.js +21 -0
  96. package/dist/src/components/index.js.map +1 -0
  97. package/dist/src/components/link.d.ts +24 -0
  98. package/dist/src/components/link.d.ts.map +1 -0
  99. package/dist/src/components/link.jsx +67 -0
  100. package/dist/src/components/link.jsx.map +1 -0
  101. package/dist/src/components/message.d.ts +31 -0
  102. package/dist/src/components/message.d.ts.map +1 -0
  103. package/dist/src/components/message.jsx +105 -0
  104. package/dist/src/components/message.jsx.map +1 -0
  105. package/dist/src/components/readme_renderer/index.d.ts +4 -0
  106. package/dist/src/components/readme_renderer/index.d.ts.map +1 -0
  107. package/dist/src/components/readme_renderer/index.js +4 -0
  108. package/dist/src/components/readme_renderer/index.js.map +1 -0
  109. package/dist/src/components/readme_renderer/pythonize_value.d.ts +3 -0
  110. package/dist/src/components/readme_renderer/pythonize_value.d.ts.map +1 -0
  111. package/dist/src/components/readme_renderer/pythonize_value.js +81 -0
  112. package/dist/src/components/readme_renderer/pythonize_value.js.map +1 -0
  113. package/dist/src/components/readme_renderer/table_of_contents.d.ts +10 -0
  114. package/dist/src/components/readme_renderer/table_of_contents.d.ts.map +1 -0
  115. package/dist/src/components/readme_renderer/table_of_contents.jsx +197 -0
  116. package/dist/src/components/readme_renderer/table_of_contents.jsx.map +1 -0
  117. package/dist/src/components/readme_renderer/utils.d.ts +6 -0
  118. package/dist/src/components/readme_renderer/utils.d.ts.map +1 -0
  119. package/dist/src/components/readme_renderer/utils.jsx +42 -0
  120. package/dist/src/components/readme_renderer/utils.jsx.map +1 -0
  121. package/dist/src/components/simple_markdown/index.d.ts +3 -0
  122. package/dist/src/components/simple_markdown/index.d.ts.map +1 -0
  123. package/dist/src/components/simple_markdown/index.jsx +3 -0
  124. package/dist/src/components/simple_markdown/index.jsx.map +1 -0
  125. package/dist/src/components/simple_markdown/simple_markdown.d.ts +16 -0
  126. package/dist/src/components/simple_markdown/simple_markdown.d.ts.map +1 -0
  127. package/dist/src/components/simple_markdown/simple_markdown.jsx +137 -0
  128. package/dist/src/components/simple_markdown/simple_markdown.jsx.map +1 -0
  129. package/dist/src/components/simple_markdown/simple_markdown_components.d.ts +26 -0
  130. package/dist/src/components/simple_markdown/simple_markdown_components.d.ts.map +1 -0
  131. package/dist/src/components/simple_markdown/simple_markdown_components.jsx +193 -0
  132. package/dist/src/components/simple_markdown/simple_markdown_components.jsx.map +1 -0
  133. package/dist/src/components/tag.d.ts +38 -0
  134. package/dist/src/components/tag.d.ts.map +1 -0
  135. package/dist/src/components/tag.jsx +126 -0
  136. package/dist/src/components/tag.jsx.map +1 -0
  137. package/dist/src/components/text/heading_content.d.ts +10 -0
  138. package/dist/src/components/text/heading_content.d.ts.map +1 -0
  139. package/dist/src/components/text/heading_content.jsx +31 -0
  140. package/dist/src/components/text/heading_content.jsx.map +1 -0
  141. package/dist/src/components/text/heading_marketing.d.ts +10 -0
  142. package/dist/src/components/text/heading_marketing.d.ts.map +1 -0
  143. package/dist/src/components/text/heading_marketing.jsx +31 -0
  144. package/dist/src/components/text/heading_marketing.jsx.map +1 -0
  145. package/dist/src/components/text/heading_shared.d.ts +10 -0
  146. package/dist/src/components/text/heading_shared.d.ts.map +1 -0
  147. package/dist/src/components/text/heading_shared.jsx +32 -0
  148. package/dist/src/components/text/heading_shared.jsx.map +1 -0
  149. package/dist/src/components/text/index.d.ts +12 -0
  150. package/dist/src/components/text/index.d.ts.map +1 -0
  151. package/dist/src/components/text/index.js +11 -0
  152. package/dist/src/components/text/index.js.map +1 -0
  153. package/dist/src/components/text/text_base.d.ts +13 -0
  154. package/dist/src/components/text/text_base.d.ts.map +1 -0
  155. package/dist/src/components/text/text_base.jsx +23 -0
  156. package/dist/src/components/text/text_base.jsx.map +1 -0
  157. package/dist/src/components/text/text_content.d.ts +11 -0
  158. package/dist/src/components/text/text_content.d.ts.map +1 -0
  159. package/dist/src/components/text/text_content.jsx +68 -0
  160. package/dist/src/components/text/text_content.jsx.map +1 -0
  161. package/dist/src/components/text/text_marketing.d.ts +11 -0
  162. package/dist/src/components/text/text_marketing.d.ts.map +1 -0
  163. package/dist/src/components/text/text_marketing.jsx +116 -0
  164. package/dist/src/components/text/text_marketing.jsx.map +1 -0
  165. package/dist/src/components/text/text_shared.d.ts +14 -0
  166. package/dist/src/components/text/text_shared.d.ts.map +1 -0
  167. package/dist/src/components/text/text_shared.jsx +55 -0
  168. package/dist/src/components/text/text_shared.jsx.map +1 -0
  169. package/dist/src/components/tile/horizontal_tile.d.ts +9 -0
  170. package/dist/src/components/tile/horizontal_tile.d.ts.map +1 -0
  171. package/dist/src/components/tile/horizontal_tile.jsx +43 -0
  172. package/dist/src/components/tile/horizontal_tile.jsx.map +1 -0
  173. package/dist/src/components/tile/index.d.ts +3 -0
  174. package/dist/src/components/tile/index.d.ts.map +1 -0
  175. package/dist/src/components/tile/index.js +3 -0
  176. package/dist/src/components/tile/index.js.map +1 -0
  177. package/dist/src/components/tile/shared.d.ts +17 -0
  178. package/dist/src/components/tile/shared.d.ts.map +1 -0
  179. package/dist/src/components/tile/shared.js +12 -0
  180. package/dist/src/components/tile/shared.js.map +1 -0
  181. package/dist/src/components/tile/vertical_tile.d.ts +10 -0
  182. package/dist/src/components/tile/vertical_tile.d.ts.map +1 -0
  183. package/dist/src/components/tile/vertical_tile.jsx +32 -0
  184. package/dist/src/components/tile/vertical_tile.jsx.map +1 -0
  185. package/dist/src/components/to_consolidate/card.d.ts +27 -0
  186. package/dist/src/components/to_consolidate/card.d.ts.map +1 -0
  187. package/dist/src/components/to_consolidate/card.jsx +93 -0
  188. package/dist/src/components/to_consolidate/card.jsx.map +1 -0
  189. package/dist/src/components/to_consolidate/index.d.ts +5 -0
  190. package/dist/src/components/to_consolidate/index.d.ts.map +1 -0
  191. package/dist/src/components/to_consolidate/index.js +5 -0
  192. package/dist/src/components/to_consolidate/index.js.map +1 -0
  193. package/dist/src/components/to_consolidate/markdown.d.ts +40 -0
  194. package/dist/src/components/to_consolidate/markdown.d.ts.map +1 -0
  195. package/dist/src/components/to_consolidate/markdown.jsx +454 -0
  196. package/dist/src/components/to_consolidate/markdown.jsx.map +1 -0
  197. package/dist/src/components/to_consolidate/pagination.d.ts +8 -0
  198. package/dist/src/components/to_consolidate/pagination.d.ts.map +1 -0
  199. package/dist/src/components/to_consolidate/pagination.jsx +88 -0
  200. package/dist/src/components/to_consolidate/pagination.jsx.map +1 -0
  201. package/dist/src/components/to_consolidate/tab_number_chip.d.ts +7 -0
  202. package/dist/src/components/to_consolidate/tab_number_chip.d.ts.map +1 -0
  203. package/dist/src/components/to_consolidate/tab_number_chip.jsx +22 -0
  204. package/dist/src/components/to_consolidate/tab_number_chip.jsx.map +1 -0
  205. package/dist/src/design_system/colors_theme.d.ts +213 -0
  206. package/dist/src/design_system/colors_theme.d.ts.map +1 -0
  207. package/dist/src/design_system/colors_theme.js +213 -0
  208. package/dist/src/design_system/colors_theme.js.map +1 -0
  209. package/dist/src/design_system/properties_theme.d.ts +175 -0
  210. package/dist/src/design_system/properties_theme.d.ts.map +1 -0
  211. package/dist/src/design_system/properties_theme.js +315 -0
  212. package/dist/src/design_system/properties_theme.js.map +1 -0
  213. package/dist/src/design_system/theme.d.ts +630 -0
  214. package/dist/src/design_system/theme.d.ts.map +1 -0
  215. package/dist/src/design_system/theme.js +17 -0
  216. package/dist/src/design_system/theme.js.map +1 -0
  217. package/dist/src/design_system/tokens/index.d.ts +6 -0
  218. package/dist/src/design_system/tokens/index.d.ts.map +1 -0
  219. package/dist/src/design_system/tokens/index.js +6 -0
  220. package/dist/src/design_system/tokens/index.js.map +1 -0
  221. package/dist/src/design_system/tokens/layouts.d.ts +29 -0
  222. package/dist/src/design_system/tokens/layouts.d.ts.map +1 -0
  223. package/dist/src/design_system/tokens/layouts.js +29 -0
  224. package/dist/src/design_system/tokens/layouts.js.map +1 -0
  225. package/dist/src/design_system/tokens/radiuses.d.ts +23 -0
  226. package/dist/src/design_system/tokens/radiuses.d.ts.map +1 -0
  227. package/dist/src/design_system/tokens/radiuses.js +23 -0
  228. package/dist/src/design_system/tokens/radiuses.js.map +1 -0
  229. package/dist/src/design_system/tokens/shadows.d.ts +23 -0
  230. package/dist/src/design_system/tokens/shadows.d.ts.map +1 -0
  231. package/dist/src/design_system/tokens/shadows.js +23 -0
  232. package/dist/src/design_system/tokens/shadows.js.map +1 -0
  233. package/dist/src/design_system/tokens/spaces.d.ts +15 -0
  234. package/dist/src/design_system/tokens/spaces.d.ts.map +1 -0
  235. package/dist/src/design_system/tokens/spaces.js +14 -0
  236. package/dist/src/design_system/tokens/spaces.js.map +1 -0
  237. package/dist/src/design_system/tokens/transitions.d.ts +20 -0
  238. package/dist/src/design_system/tokens/transitions.d.ts.map +1 -0
  239. package/dist/src/design_system/tokens/transitions.js +20 -0
  240. package/dist/src/design_system/tokens/transitions.js.map +1 -0
  241. package/dist/src/design_system/typography_theme.d.ts +189 -0
  242. package/dist/src/design_system/typography_theme.d.ts.map +1 -0
  243. package/dist/src/design_system/typography_theme.js +190 -0
  244. package/dist/src/design_system/typography_theme.js.map +1 -0
  245. package/dist/src/index.d.ts +7 -0
  246. package/dist/src/index.d.ts.map +1 -0
  247. package/dist/src/index.js +7 -0
  248. package/dist/src/index.js.map +1 -0
  249. package/dist/src/type_utils.d.ts +6 -0
  250. package/dist/src/type_utils.d.ts.map +1 -0
  251. package/dist/src/type_utils.js +2 -0
  252. package/dist/src/type_utils.js.map +1 -0
  253. package/dist/src/ui_dependency_provider.d.ts +29 -0
  254. package/dist/src/ui_dependency_provider.d.ts.map +1 -0
  255. package/dist/src/ui_dependency_provider.jsx +14 -0
  256. package/dist/src/ui_dependency_provider.jsx.map +1 -0
  257. package/dist/src/utils/copy_to_clipboard.d.ts +7 -0
  258. package/dist/src/utils/copy_to_clipboard.d.ts.map +1 -0
  259. package/dist/src/utils/copy_to_clipboard.js +16 -0
  260. package/dist/src/utils/copy_to_clipboard.js.map +1 -0
  261. package/dist/src/utils/image_color.d.ts +7 -0
  262. package/dist/src/utils/image_color.d.ts.map +1 -0
  263. package/dist/src/utils/image_color.js +35 -0
  264. package/dist/src/utils/image_color.js.map +1 -0
  265. package/dist/src/utils/index.d.ts +4 -0
  266. package/dist/src/utils/index.d.ts.map +1 -0
  267. package/dist/src/utils/index.js +4 -0
  268. package/dist/src/utils/index.js.map +1 -0
  269. package/dist/src/utils/sanitization.d.ts +11 -0
  270. package/dist/src/utils/sanitization.d.ts.map +1 -0
  271. package/dist/src/utils/sanitization.js +16 -0
  272. package/dist/src/utils/sanitization.js.map +1 -0
  273. package/dist/tsconfig.build.tsbuildinfo +1 -0
  274. package/package.json +71 -0
  275. package/src/codemods/generate_color_property_tokens.mjs +97 -0
  276. package/src/codemods/generate_color_theme_files.mjs +46 -0
  277. package/src/codemods/generate_typograpy_tokens_files.mjs +136 -0
  278. package/src/components/action_link.tsx +59 -0
  279. package/src/components/actor_template_card.tsx +99 -0
  280. package/src/components/badge.tsx +144 -0
  281. package/src/components/banner.tsx +95 -0
  282. package/src/components/blog_article.tsx +85 -0
  283. package/src/components/box.tsx +127 -0
  284. package/src/components/button.tsx +303 -0
  285. package/src/components/chip.tsx +121 -0
  286. package/src/components/code/action_button.tsx +96 -0
  287. package/src/components/code/code_block/code_block.styled.tsx +228 -0
  288. package/src/components/code/code_block/code_block.tsx +235 -0
  289. package/src/components/code/code_block/utils.ts +19 -0
  290. package/src/components/code/index.ts +3 -0
  291. package/src/components/code/inline_code/inline_code.tsx +44 -0
  292. package/src/components/code/one_line_code/one_line_code.tsx +232 -0
  293. package/src/components/code/syntax_highlighter.tsx +125 -0
  294. package/src/components/color_wheel_gradient.tsx +31 -0
  295. package/src/components/floating/index.ts +3 -0
  296. package/src/components/floating/menu.tsx +191 -0
  297. package/src/components/floating/menu_common.tsx +31 -0
  298. package/src/components/floating/menu_components.tsx +94 -0
  299. package/src/components/image.tsx +23 -0
  300. package/src/components/index.ts +20 -0
  301. package/src/components/link.tsx +114 -0
  302. package/src/components/message.tsx +157 -0
  303. package/src/components/readme_renderer/index.ts +3 -0
  304. package/src/components/readme_renderer/pythonize_value.ts +78 -0
  305. package/src/components/readme_renderer/table_of_contents.tsx +257 -0
  306. package/src/components/readme_renderer/utils.tsx +46 -0
  307. package/src/components/simple_markdown/index.tsx +2 -0
  308. package/src/components/simple_markdown/simple_markdown.tsx +181 -0
  309. package/src/components/simple_markdown/simple_markdown_components.tsx +295 -0
  310. package/src/components/tag.tsx +185 -0
  311. package/src/components/text/heading_content.tsx +56 -0
  312. package/src/components/text/heading_marketing.tsx +55 -0
  313. package/src/components/text/heading_shared.tsx +57 -0
  314. package/src/components/text/index.ts +18 -0
  315. package/src/components/text/text_base.tsx +52 -0
  316. package/src/components/text/text_content.tsx +104 -0
  317. package/src/components/text/text_marketing.tsx +152 -0
  318. package/src/components/text/text_shared.tsx +96 -0
  319. package/src/components/tile/horizontal_tile.tsx +76 -0
  320. package/src/components/tile/index.ts +2 -0
  321. package/src/components/tile/shared.ts +27 -0
  322. package/src/components/tile/vertical_tile.tsx +58 -0
  323. package/src/components/to_consolidate/card.tsx +141 -0
  324. package/src/components/to_consolidate/index.ts +4 -0
  325. package/src/components/to_consolidate/markdown.tsx +593 -0
  326. package/src/components/to_consolidate/pagination.tsx +139 -0
  327. package/src/components/to_consolidate/tab_number_chip.tsx +31 -0
  328. package/src/design_system/colors_theme.ts +213 -0
  329. package/src/design_system/generate_color_definitions.js +43 -0
  330. package/src/design_system/properties_theme.ts +453 -0
  331. package/src/design_system/supernova_color_tokens.json +1766 -0
  332. package/src/design_system/supernova_typography_tokens.json +657 -0
  333. package/src/design_system/theme.ts +26 -0
  334. package/src/design_system/tokens/index.ts +5 -0
  335. package/src/design_system/tokens/layouts.ts +29 -0
  336. package/src/design_system/tokens/radiuses.ts +22 -0
  337. package/src/design_system/tokens/shadows.ts +22 -0
  338. package/src/design_system/tokens/spaces.ts +15 -0
  339. package/src/design_system/tokens/transitions.ts +19 -0
  340. package/src/design_system/typography_theme.ts +197 -0
  341. package/src/index.ts +7 -0
  342. package/src/type_utils.ts +7 -0
  343. package/src/ui_dependency_provider.tsx +50 -0
  344. package/src/utils/copy_to_clipboard.ts +24 -0
  345. package/src/utils/image_color.ts +44 -0
  346. package/src/utils/index.ts +3 -0
  347. package/src/utils/sanitization.ts +14 -0
  348. package/tsconfig.build.json +18 -0
  349. package/tsconfig.json +10 -0
@@ -0,0 +1,593 @@
1
+ import clsx from 'clsx';
2
+ import _ from 'lodash';
3
+ import qs from 'query-string';
4
+ import React, { useMemo } from 'react';
5
+ import type { Components } from 'react-markdown';
6
+ import ReactMarkdown, { uriTransformer } from 'react-markdown';
7
+ import type { AllowElement } from 'react-markdown/lib/rehype-filter';
8
+ import rehypeRaw from 'rehype-raw';
9
+ import remarkGfm from 'remark-gfm';
10
+ import styled from 'styled-components';
11
+
12
+ import { Link16 } from '@apify/icons';
13
+
14
+ import type { UiThemeOption } from '../../design_system/theme';
15
+ import { theme } from '../../design_system/theme';
16
+ import { useCopyToClipboard } from '../../utils';
17
+ import { CodeBlock, OneLineCode, inlineCodeStyles } from '../code';
18
+ import { cleanMarkdown, slugifyHeadingChildren } from '../readme_renderer/utils';
19
+
20
+ interface StyledReadmeProps {
21
+ $scrollMarginTopPx: number;
22
+ }
23
+
24
+ const markdownClassNames = {
25
+ COPY_BUTTON: 'Markdown-CopyButton',
26
+ CODE_PRE: 'Markdown-CodePre',
27
+ VIDEO_WRAPPER: 'Markdown-VideoWrapper',
28
+ IFRAME_CONTAINER: 'Iframe-container',
29
+ HEADING_COPY_ICON: 'ReadmeRenderer-headingCopyIcon',
30
+ INLINE_CODE: 'Markdown-InlineCode',
31
+ } as const;
32
+
33
+ const StyledMarkdown = styled(ReactMarkdown) <StyledReadmeProps>`
34
+ @font-face {
35
+ font-family: "ellipsis-font";
36
+ src: local("Courier");
37
+ unicode-range: U+2026;
38
+ size-adjust: 0%;
39
+ }
40
+
41
+ &>:first-child {
42
+ margin-top: 0;
43
+ }
44
+
45
+ h1, h2, h3, h4, h5 {
46
+ scroll-margin-top: ${({ $scrollMarginTopPx }) => `${$scrollMarginTopPx}px`};
47
+ margin-top: ${theme.space.space32};
48
+ margin-bottom: ${theme.space.space16};
49
+ align-items: center;
50
+
51
+ & > .${markdownClassNames.INLINE_CODE} {
52
+ font-size: inherit !important;
53
+ line-height: inherit !important;
54
+ }
55
+
56
+ /* Do no change the font style if the heading is defined as bold in the markdown and is wrapped in a <strong> tag */
57
+ strong {
58
+ font-size: inherit !important;
59
+ line-height: inherit !important;
60
+ font-weight: inherit !important;
61
+ }
62
+
63
+ a {
64
+ text-decoration: none !important;
65
+ }
66
+
67
+ .${markdownClassNames.HEADING_COPY_ICON} {
68
+ display: none;
69
+ transform: translateX(${theme.space.space4});
70
+ color: ${theme.color.neutral.textSubtle};
71
+
72
+ svg {
73
+ stroke: ${theme.color.primary.text};
74
+ max-height: 1em !important;
75
+ }
76
+ }
77
+
78
+ &:hover {
79
+ .${markdownClassNames.HEADING_COPY_ICON} {
80
+ display: inline-block;
81
+ }
82
+ }
83
+ }
84
+
85
+ p, li, strong, b, table {
86
+ ${theme.typography.content.mobile.paragraph}
87
+ @media (min-width: ${theme.layout.tablet}) {
88
+ ${theme.typography.content.tablet.paragraph}
89
+ }
90
+ @media (min-width: ${theme.layout.desktop}) {
91
+ ${theme.typography.content.desktop.paragraph}
92
+ }
93
+ a {
94
+ overflow-wrap: break-word;
95
+ text-decoration: none;
96
+ &:hover {
97
+ text-decoration: underline;
98
+ }
99
+ }
100
+ }
101
+
102
+ p {
103
+ margin: ${theme.space.space16} 0;
104
+ }
105
+
106
+ h1 {
107
+ ${theme.typography.content.mobile.heading1}
108
+ @media (min-width: ${theme.layout.tablet}) {
109
+ ${theme.typography.content.tablet.heading1}
110
+ }
111
+ @media (min-width: ${theme.layout.desktop}) {
112
+ ${theme.typography.content.desktop.heading1}
113
+ }
114
+ }
115
+
116
+ h2 {
117
+ ${theme.typography.content.mobile.heading2}
118
+ @media (min-width: ${theme.layout.tablet}) {
119
+ ${theme.typography.content.tablet.heading2}
120
+ }
121
+ @media (min-width: ${theme.layout.desktop}) {
122
+ ${theme.typography.content.desktop.heading2}
123
+ }
124
+ }
125
+
126
+ h3 {
127
+ ${theme.typography.content.mobile.heading3}
128
+ @media (min-width: ${theme.layout.tablet}) {
129
+ ${theme.typography.content.tablet.heading3}
130
+ }
131
+ @media (min-width: ${theme.layout.desktop}) {
132
+ ${theme.typography.content.desktop.heading3}
133
+ }
134
+ }
135
+
136
+ h4 {
137
+ ${theme.typography.content.mobile.heading4}
138
+ @media (min-width: ${theme.layout.tablet}) {
139
+ ${theme.typography.content.tablet.heading4}
140
+ }
141
+ @media (min-width: ${theme.layout.desktop}) {
142
+ ${theme.typography.content.desktop.heading4}
143
+ }
144
+ }
145
+
146
+ h5 {
147
+ ${theme.typography.content.mobile.heading5}
148
+ @media (min-width: ${theme.layout.tablet}) {
149
+ ${theme.typography.content.tablet.heading5}
150
+ }
151
+ @media (min-width: ${theme.layout.desktop}) {
152
+ ${theme.typography.content.desktop.heading5}
153
+ }
154
+ }
155
+
156
+ h6 {
157
+ ${theme.typography.content.mobile.heading6}
158
+ @media (min-width: ${theme.layout.tablet}) {
159
+ ${theme.typography.content.tablet.heading6}
160
+ }
161
+ @media (min-width: ${theme.layout.desktop}) {
162
+ ${theme.typography.content.desktop.heading6}
163
+ }
164
+ }
165
+
166
+ img {
167
+ max-width: 100%;
168
+ }
169
+
170
+ ul, ol {
171
+ padding-left: ${theme.space.space32};
172
+ }
173
+
174
+ li {
175
+ margin-top: ${theme.space.space4};
176
+ }
177
+
178
+ hr {
179
+ color: ${theme.color.neutral.border};
180
+ }
181
+
182
+ strong {
183
+ ${theme.typography.content.mobile.paragraphStrong}
184
+ @media (min-width: ${theme.layout.tablet}) {
185
+ ${theme.typography.content.tablet.paragraphStrong}
186
+ }
187
+ @media (min-width: ${theme.layout.desktop}) {
188
+ ${theme.typography.content.desktop.paragraphStrong}
189
+ }
190
+ }
191
+
192
+ blockquote {
193
+ border-left: 2px solid ${theme.color.neutral.separatorSubtle};
194
+ padding-left: ${theme.space.space16};
195
+
196
+ color: ${theme.color.neutral.textMuted};
197
+
198
+ p {
199
+ margin-bottom: 0;
200
+ }
201
+ }
202
+
203
+ table {
204
+ display: block;
205
+ overflow: auto;
206
+ border-collapse: collapse;
207
+
208
+ td, th {
209
+ border: 1px solid ${theme.color.neutral.border};
210
+ padding: ${theme.space.space16};
211
+ text-align: left;
212
+ }
213
+
214
+ tr:nth-child(even):not([class]) {
215
+ > th, > td {
216
+ background-color: inherit;
217
+ }
218
+ }
219
+ }
220
+
221
+ th {
222
+ ${theme.typography.content.mobile.paragraphStrong}
223
+ @media (min-width: ${theme.layout.tablet}) {
224
+ ${theme.typography.content.tablet.paragraphStrong}
225
+ }
226
+ @media (min-width: ${theme.layout.desktop}) {
227
+ ${theme.typography.content.desktop.paragraphStrong}
228
+ }
229
+ }
230
+
231
+ a:hover {
232
+ text-decoration: underline;
233
+ }
234
+
235
+ .${markdownClassNames.VIDEO_WRAPPER} {
236
+ width: 65%;
237
+ display: block;
238
+
239
+ .${markdownClassNames.IFRAME_CONTAINER} {
240
+ position: relative;
241
+ overflow: hidden;
242
+ width: 100%;
243
+ padding-top: 56.25%;
244
+ display: block;
245
+
246
+ iframe {
247
+ position: absolute;
248
+ top: 0;
249
+ left: 0;
250
+ bottom: 0;
251
+ right: 0;
252
+ width: 100%;
253
+ height: 100%;
254
+ border: 0px;
255
+ }
256
+ }
257
+ }
258
+
259
+ .${markdownClassNames.INLINE_CODE} {
260
+ ${inlineCodeStyles}
261
+ ${theme.typography.content.mobile.snippet}
262
+ @media (min-width: ${theme.layout.tablet}) {
263
+ ${theme.typography.content.tablet.snippet}
264
+ }
265
+ @media (min-width: ${theme.layout.desktop}) {
266
+ ${theme.typography.content.desktop.snippet}
267
+ }
268
+ b, strong{
269
+ font-size: inherit !important;
270
+ line-height: inherit !important;
271
+ font-family: inherit !important;
272
+ }
273
+ }
274
+ `;
275
+
276
+ export interface HeadingRendererProps {
277
+ node: {
278
+ tagName: keyof JSX.IntrinsicElements;
279
+ };
280
+ children: React.ReactNode;
281
+ }
282
+
283
+ /**
284
+ * Adds ids to headings
285
+ */
286
+ const DefaultHeadingRenderer = ({ node, children }: HeadingRendererProps) => {
287
+ const Tag = node.tagName;
288
+ const id = slugifyHeadingChildren(children);
289
+ return <Tag id={id}>{children}</Tag>;
290
+ };
291
+
292
+ interface CodeRendererComponentProps {
293
+ inline: boolean;
294
+ className: string;
295
+ children: React.ReactNode;
296
+ }
297
+
298
+ function CodeRenderer({
299
+ inline,
300
+ className,
301
+ children,
302
+ }: CodeRendererComponentProps) {
303
+ if (inline) {
304
+ return <code className={clsx(className, markdownClassNames.INLINE_CODE)}>{children}</code>;
305
+ }
306
+
307
+ const code = String(children).replace(/\n$/, '').trim();
308
+ const match = /language-(\w+)/.exec(className || '');
309
+ const language = match?.[1]?.toLowerCase();
310
+ const isOneLineCode = code.split('\n').length <= 1;
311
+
312
+ if (isOneLineCode) {
313
+ return (
314
+ <OneLineCode
315
+ language={language}
316
+ fullWidth
317
+ >
318
+ {code}
319
+ </OneLineCode>
320
+ );
321
+ }
322
+
323
+ return (
324
+ <CodeBlock
325
+ content={code}
326
+ language={language}
327
+ hideLineNumbers
328
+ fullWidth
329
+ hideBashHeader
330
+ hideBashPromptPrefixes
331
+ />
332
+ );
333
+ }
334
+
335
+ const youtubeRegex = /^(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtube(?:-nocookie)?\.com|youtu\.be)\/(?:watch\?v=|embed\/|v\/)?([a-zA-Z0-9\-_]+)(?:\S*)?$/;
336
+ const vimeoRegex = /^((?:https?:\/\/)?(?:player\.)?vimeo\.com(?:\/video)?\/(\d+))$/;
337
+
338
+ const getVideoSrc = (link: string) => {
339
+ const youtubeLink = link.match(youtubeRegex);
340
+ const vimeoLink = link.match(vimeoRegex);
341
+ let src;
342
+ if (youtubeLink) {
343
+ // add rel=0 to disable related videos from other channels at the end of the video
344
+ // add enablejsapi=1 to enable tracking videos via API through Google Analytics
345
+ src = qs.stringifyUrl({ url: `https://www.youtube.com/embed/${youtubeLink[1]}`, query: { rel: 0, enablejsapi: 1 } });
346
+ }
347
+ if (vimeoLink) src = `https://player.vimeo.com/video/${vimeoLink[2]}`;
348
+
349
+ return src;
350
+ };
351
+
352
+ interface VideoProps {
353
+ src: string;
354
+ }
355
+ const Video = ({ src }: VideoProps) => {
356
+ return (
357
+ <span className={markdownClassNames.VIDEO_WRAPPER}>
358
+ <span className="Iframe-container">
359
+ <iframe loading="lazy" allowFullScreen src={src} />
360
+ </span>
361
+ </span>
362
+ );
363
+ };
364
+
365
+ export const APIFY_HOSTNAMES = [
366
+ 'apify.com',
367
+ 'docs.apify.com',
368
+ 'help.apify.com',
369
+ 'sdk.apify.com',
370
+ 'blog.apify.com',
371
+ 'kb.apify.com', // old knowledge base domain (redirects to help.apify.com)
372
+ 'my.apify.com', // old console.domain (redirects to console.apify.com)
373
+ 'console.apify.com',
374
+ 'crawlee.dev',
375
+ ];
376
+
377
+ interface LinkRendererProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
378
+ node: {
379
+ properties: {
380
+ enableEmbeddedVideo: boolean;
381
+ };
382
+ };
383
+ href: string;
384
+ }
385
+
386
+ interface LinkRendererOptions {
387
+ hostname?: string,
388
+ Link?: React.ElementType;
389
+ }
390
+
391
+ // We want no-follow for external links
392
+ // Also if link is a video from youtube or vimeo, we want to render it as iframe
393
+ // Allowing to pass hostname to check if the link is an Apify link to the same hostname (is needed for SSR on the web)
394
+ const DefaultLinkRenderer = ({ node, href, ...props }: LinkRendererProps, { hostname, Link }: LinkRendererOptions, isUserGeneratedContent?: boolean) => {
395
+ const videoSrc = node.properties.enableEmbeddedVideo && getVideoSrc(href);
396
+ if (videoSrc) return <Video src={videoSrc} />;
397
+
398
+ // check for anchor links, hash link are not parsable by URL constructor
399
+ const isHashLink = (href || '').startsWith('#');
400
+ if (isHashLink) return <a href={href} {...props} />;
401
+
402
+ let urlParsed: URL | undefined;
403
+ try { // TODO: replace with URL.canParse() when we have node 19+ 🥲
404
+ urlParsed = new URL(href);
405
+ } catch {
406
+ // Probably invalid url, go on as it doesn't make sense to track this error
407
+ // This component is used on all Actor pages - readmes.
408
+ // So it is mainly for the user-generated content - there can be many invalid links and we won't do anything about it anyway.
409
+ return <span>{href}</span>;
410
+ }
411
+
412
+ if (!hostname && (typeof window !== 'undefined' && !window?.location?.hostname)) return <a href={href} {...props} />;
413
+
414
+ const currentHostname = hostname || (typeof window !== 'undefined' && window?.location?.hostname.toLowerCase());
415
+ const hasDifferentHostname = urlParsed && (urlParsed.hostname.toLowerCase() !== currentHostname);
416
+ const isApifyLink = urlParsed
417
+ && APIFY_HOSTNAMES.includes(urlParsed.hostname.toLowerCase())
418
+ && urlParsed.protocol === 'https:'; // we want to disqualify links that have http: protocol. It's a mistake on users' side that we are penalized for.
419
+
420
+ let linkProps = {};
421
+ // If the link is an Apify link to the same hostname, we want to open in the same tab otherwise we want to open in a new tab
422
+ // If an external non-Apify link, we want to always open it in a new tab and add rel="noopener noreferrer nofollow"
423
+ // (and ugc if the link comes from the user-generated content)
424
+ if (isApifyLink && hasDifferentHostname) {
425
+ linkProps = { target: '_blank', rel: 'noopener noreferrer' };
426
+ } else if (!hasDifferentHostname && Link) { // Same host name, use the provided link for internal navigation
427
+ return <Link to={urlParsed} {...props} />;
428
+ } else {
429
+ // USG - User Generated Content (new rel attribute for nofollow links)
430
+ // Google says:
431
+ // It’s valid to use nofollow with the new attributes — such as rel=”nofollow ugc”
432
+ // — if you wish to be backwards-compatible with services that don’t support the new attributes.
433
+ linkProps = { target: '_blank', rel: clsx('noopener noreferrer nofollow', isUserGeneratedContent && 'ugc') };
434
+ }
435
+ return <a href={href} {...props} {...linkProps} />;
436
+ };
437
+
438
+ // node is just to omit from exported props
439
+ interface ParagraphRendererProps extends React.HTMLAttributes<HTMLParagraphElement> {
440
+ node?: {
441
+ children: {
442
+ tagName: keyof JSX.IntrinsicElements;
443
+ type: string;
444
+ value: string;
445
+ properties: {
446
+ enableEmbeddedVideo: boolean;
447
+ };
448
+ }[];
449
+ };
450
+ }
451
+
452
+ // If the paragraph is just a link to youtube or vimeo, we want to render it as iframe
453
+ const ParagraphRenderer = ({ node, ...props }: ParagraphRendererProps) => {
454
+ // We enable embedded video only is surrounded by new lines (will be rendered as only child in paragraph)
455
+ node?.children.forEach((child) => {
456
+ if (child.tagName === 'a') child.properties.enableEmbeddedVideo = node.children.length === 1; // This means the link is the only child
457
+ });
458
+ const child = node?.children[0];
459
+ const isText = child?.type === 'text';
460
+
461
+ const videoSrc = isText && getVideoSrc(child.value);
462
+ if (videoSrc) return <Video src={videoSrc} />;
463
+
464
+ return <p {...props} />;
465
+ };
466
+
467
+ const HeadingRendererWithAnchor = ({ node, children }: HeadingRendererProps) => {
468
+ const Tag = node.tagName;
469
+ const id = slugifyHeadingChildren(children);
470
+
471
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
472
+ const [_isCopied, handleClick] = useCopyToClipboard({
473
+ text: id ?? '',
474
+ // We want the whole URL to be copied, not just the ID
475
+ transform: (text) => {
476
+ const url = new URL(window.location.href);
477
+ url.hash = `#${text}`;
478
+ return url.toString();
479
+ },
480
+ });
481
+
482
+ return (
483
+ <Tag id={id}>
484
+ {children}
485
+ <a
486
+ onClick={handleClick}
487
+ href={`#${id}`}
488
+ className={`${markdownClassNames.HEADING_COPY_ICON}`}
489
+ >
490
+ <Link16 viewBox="0 0 16 16" />
491
+ </a>
492
+ </Tag>
493
+ );
494
+ };
495
+
496
+ export interface MarkdownProps {
497
+ markdown: string;
498
+ transformLinkUri?: (href: string) => string;
499
+ transformImageUri?: (src: string) => string;
500
+ className?: string;
501
+ theme?: UiThemeOption;
502
+ scrollMarginTopPx?: number; // Offset from top of page to account for sticky header
503
+ // Function where we can define which elements are allowed in the markdown. See // Function where we can define which elements are allowed in the markdown. See https://github.com/remarkjs/react-markdown#props for more info
504
+ allowElement?: AllowElement
505
+ isUserGeneratedContent?: boolean;
506
+ currentPathHostname?: string;
507
+ addHeadingAnchors?: boolean;
508
+ Link?: React.ElementType;
509
+ LinkRenderer?: (props: LinkRendererProps, options: LinkRendererOptions, isUserGeneratedContent?: boolean) => React.ReactElement;
510
+ lazyLoadImages?: boolean;
511
+ }
512
+
513
+ const Markdown = ({
514
+ markdown,
515
+ transformLinkUri,
516
+ transformImageUri,
517
+ className,
518
+ scrollMarginTopPx = 10,
519
+ allowElement,
520
+ currentPathHostname,
521
+ addHeadingAnchors,
522
+ isUserGeneratedContent,
523
+ Link,
524
+ LinkRenderer,
525
+ lazyLoadImages,
526
+ }: MarkdownProps) => {
527
+ const headingRenderer = addHeadingAnchors ? HeadingRendererWithAnchor : DefaultHeadingRenderer;
528
+ const cleanedMarkdown = useMemo(() => cleanMarkdown(markdown), [markdown]);
529
+ return (
530
+ <StyledMarkdown
531
+ $scrollMarginTopPx={scrollMarginTopPx}
532
+ className={className}
533
+ rehypePlugins={[rehypeRaw]}
534
+ remarkPlugins={[remarkGfm]}
535
+ allowedElements={[
536
+ 'a',
537
+ 'b',
538
+ 'blockquote',
539
+ 'br',
540
+ 'center',
541
+ 'code',
542
+ 'del',
543
+ 'em',
544
+ 'h1',
545
+ 'h2',
546
+ 'h3',
547
+ 'h4',
548
+ 'h5',
549
+ 'hr',
550
+ 'i',
551
+ 'img',
552
+ 'li',
553
+ 'ol',
554
+ 'p',
555
+ 'pre',
556
+ 'span',
557
+ 'strong',
558
+ 'table',
559
+ 'tbody',
560
+ 'td',
561
+ 'tfoot',
562
+ 'th',
563
+ 'thead',
564
+ 'tr',
565
+ 'u',
566
+ 'ul',
567
+ ]}
568
+ allowElement={allowElement}
569
+ components={{
570
+ h1: headingRenderer,
571
+ h2: headingRenderer,
572
+ h3: headingRenderer,
573
+ h4: headingRenderer,
574
+ h5: headingRenderer,
575
+ a: (linkProps: LinkRendererProps) => (
576
+ LinkRenderer
577
+ ? LinkRenderer(linkProps, { hostname: currentPathHostname, Link }, isUserGeneratedContent)
578
+ : DefaultLinkRenderer(linkProps, { hostname: currentPathHostname, Link }, isUserGeneratedContent)
579
+ ),
580
+ code: (codeProps: CodeRendererComponentProps) => CodeRenderer(codeProps),
581
+ p: ParagraphRenderer,
582
+ img: (imageProps: React.ImgHTMLAttributes<HTMLImageElement>) => <img {...imageProps} {...(lazyLoadImages ? { loading: 'lazy' } : {})} />,
583
+ } as unknown as Components}
584
+ transformLinkUri={(href) => (transformLinkUri ? uriTransformer(transformLinkUri(href)) : uriTransformer(href))}
585
+ transformImageUri={transformImageUri}
586
+ >
587
+ {cleanedMarkdown}
588
+ </StyledMarkdown>
589
+ );
590
+ };
591
+
592
+ const MemoizedMarkdown = React.memo(Markdown, (prevProps, nextProps) => _.isEqual(prevProps, nextProps));
593
+ export { MemoizedMarkdown as Markdown };