@xyd-js/components 0.1.0-build.168

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 (314) hide show
  1. package/.idea/git_toolbox_blame.xml +6 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/vcs.xml +6 -0
  4. package/.idea/xyd-components.iml +12 -0
  5. package/CHANGELOG.md +1369 -0
  6. package/LICENSE +21 -0
  7. package/README.md +3 -0
  8. package/TODO.md +1 -0
  9. package/coder.ts +1 -0
  10. package/content.ts +1 -0
  11. package/dist/Button-BLA2ghHZ.js +2 -0
  12. package/dist/Button-BLA2ghHZ.js.map +1 -0
  13. package/dist/Button-BTJ2hIal.js +2 -0
  14. package/dist/Button-BTJ2hIal.js.map +1 -0
  15. package/dist/Button-r4BCrEjy.js +2 -0
  16. package/dist/Button-r4BCrEjy.js.map +1 -0
  17. package/dist/CodeSample-BZ5tvyWY.js +2 -0
  18. package/dist/CodeSample-BZ5tvyWY.js.map +1 -0
  19. package/dist/CodeSample-BqXDbWdi.js +2 -0
  20. package/dist/CodeSample-BqXDbWdi.js.map +1 -0
  21. package/dist/CodeSample-Cqv86IdN.js +2 -0
  22. package/dist/CodeSample-Cqv86IdN.js.map +1 -0
  23. package/dist/Icon--77MqplU.js +2 -0
  24. package/dist/Icon--77MqplU.js.map +1 -0
  25. package/dist/Icon-DbNmvK_Q.js +2 -0
  26. package/dist/Icon-DbNmvK_Q.js.map +1 -0
  27. package/dist/Icon-uVIU1LW6.js +2 -0
  28. package/dist/Icon-uVIU1LW6.js.map +1 -0
  29. package/dist/PageFirstSlide-BDNmCTiJ.js +2 -0
  30. package/dist/PageFirstSlide-BDNmCTiJ.js.map +1 -0
  31. package/dist/PageFirstSlide-BpZ42bEU.js +2 -0
  32. package/dist/PageFirstSlide-BpZ42bEU.js.map +1 -0
  33. package/dist/PageFirstSlide-CqxiyK57.js +2 -0
  34. package/dist/PageFirstSlide-CqxiyK57.js.map +1 -0
  35. package/dist/TabsAnalytics-B_JYpawG.js +2 -0
  36. package/dist/TabsAnalytics-B_JYpawG.js.map +1 -0
  37. package/dist/TabsAnalytics-DAOfTZgv.js +2 -0
  38. package/dist/TabsAnalytics-DAOfTZgv.js.map +1 -0
  39. package/dist/TabsAnalytics-Dhyadlbu.js +2 -0
  40. package/dist/TabsAnalytics-Dhyadlbu.js.map +1 -0
  41. package/dist/Update-53fEhmjh.js +2 -0
  42. package/dist/Update-53fEhmjh.js.map +1 -0
  43. package/dist/Update-CFi6uapq.js +2 -0
  44. package/dist/Update-CFi6uapq.js.map +1 -0
  45. package/dist/Update-CiMIOgZi.js +2 -0
  46. package/dist/Update-CiMIOgZi.js.map +1 -0
  47. package/dist/VideoGuide-C0K9fFar.js +2 -0
  48. package/dist/VideoGuide-C0K9fFar.js.map +1 -0
  49. package/dist/VideoGuide-CJYkuLst.js +2 -0
  50. package/dist/VideoGuide-CJYkuLst.js.map +1 -0
  51. package/dist/VideoGuide-DBY-EyxG.js +2 -0
  52. package/dist/VideoGuide-DBY-EyxG.js.map +1 -0
  53. package/dist/_rollupPluginBabelHelpers-CvhQFv1t.js +4 -0
  54. package/dist/_rollupPluginBabelHelpers-CvhQFv1t.js.map +1 -0
  55. package/dist/_rollupPluginBabelHelpers-DSwDY1Dm.js +4 -0
  56. package/dist/_rollupPluginBabelHelpers-DSwDY1Dm.js.map +1 -0
  57. package/dist/_rollupPluginBabelHelpers-Dc-ocx4G.js +4 -0
  58. package/dist/_rollupPluginBabelHelpers-Dc-ocx4G.js.map +1 -0
  59. package/dist/coder/themes/classic.css +57 -0
  60. package/dist/coder/themes/classic.d.ts +96 -0
  61. package/dist/coder/themes/classic.js +2 -0
  62. package/dist/coder/themes/classic.js.map +1 -0
  63. package/dist/coder/themes/cosmo.css +64 -0
  64. package/dist/coder/themes/cosmo.d.ts +96 -0
  65. package/dist/coder/themes/cosmo.js +2 -0
  66. package/dist/coder/themes/cosmo.js.map +1 -0
  67. package/dist/coder.d.ts +94 -0
  68. package/dist/coder.js +2 -0
  69. package/dist/coder.js.map +1 -0
  70. package/dist/content.d.ts +411 -0
  71. package/dist/content.js +2 -0
  72. package/dist/content.js.map +1 -0
  73. package/dist/index.css +282 -0
  74. package/dist/index.d.ts +2 -0
  75. package/dist/index.js +2 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/layouts.d.ts +33 -0
  78. package/dist/layouts.js +2 -0
  79. package/dist/layouts.js.map +1 -0
  80. package/dist/pages.d.ts +176 -0
  81. package/dist/pages.js +2 -0
  82. package/dist/pages.js.map +1 -0
  83. package/dist/system.d.ts +45 -0
  84. package/dist/system.js +2 -0
  85. package/dist/system.js.map +1 -0
  86. package/dist/useUXClick-DK3cTAMR.js +2 -0
  87. package/dist/useUXClick-DK3cTAMR.js.map +1 -0
  88. package/dist/useUXClick-DO6qBcRy.js +2 -0
  89. package/dist/useUXClick-DO6qBcRy.js.map +1 -0
  90. package/dist/useUXClick-NwpsiuK9.js +2 -0
  91. package/dist/useUXClick-NwpsiuK9.js.map +1 -0
  92. package/dist/useUXEvents-CJtgGV4R.js +2 -0
  93. package/dist/useUXEvents-CJtgGV4R.js.map +1 -0
  94. package/dist/useUXEvents-Cxgl7xb-.js +2 -0
  95. package/dist/useUXEvents-Cxgl7xb-.js.map +1 -0
  96. package/dist/useUXEvents-XqAGxoEj.js +2 -0
  97. package/dist/useUXEvents-XqAGxoEj.js.map +1 -0
  98. package/dist/useUXScrollDepth-3rk3Z95r.js +2 -0
  99. package/dist/useUXScrollDepth-3rk3Z95r.js.map +1 -0
  100. package/dist/useUXScrollDepth-BwK-XOBg.js +2 -0
  101. package/dist/useUXScrollDepth-BwK-XOBg.js.map +1 -0
  102. package/dist/useUXScrollDepth-DKre7PBz.js +2 -0
  103. package/dist/useUXScrollDepth-DKre7PBz.js.map +1 -0
  104. package/dist/uxsdk.d.ts +53 -0
  105. package/dist/uxsdk.js +2 -0
  106. package/dist/uxsdk.js.map +1 -0
  107. package/dist/views.d.ts +18 -0
  108. package/dist/views.js +2 -0
  109. package/dist/views.js.map +1 -0
  110. package/dist/writer.d.ts +580 -0
  111. package/dist/writer.js +2 -0
  112. package/dist/writer.js.map +1 -0
  113. package/docs/.nojekyll +1 -0
  114. package/docs/assets/hierarchy.js +1 -0
  115. package/docs/assets/highlight.css +22 -0
  116. package/docs/assets/icons.js +18 -0
  117. package/docs/assets/icons.svg +1 -0
  118. package/docs/assets/main.js +60 -0
  119. package/docs/assets/navigation.js +1 -0
  120. package/docs/assets/search.js +1 -0
  121. package/docs/assets/style.css +1640 -0
  122. package/docs/functions/GuideCard.html +6 -0
  123. package/docs/hierarchy.html +1 -0
  124. package/docs/index.html +2 -0
  125. package/docs/interfaces/GuideCardProps.html +18 -0
  126. package/docs/modules.html +1 -0
  127. package/index.ts +0 -0
  128. package/layouts.ts +1 -0
  129. package/output.txt +13 -0
  130. package/package.json +81 -0
  131. package/pages.ts +1 -0
  132. package/postcss.config.cjs +5 -0
  133. package/rollup.config.js +195 -0
  134. package/src/coder/Code/Code.styles.tsx +151 -0
  135. package/src/coder/Code/Code.tsx +171 -0
  136. package/src/coder/Code/CodeLoader.tsx +10 -0
  137. package/src/coder/Code/annotations.tsx +51 -0
  138. package/src/coder/Code/highlight.ts +208 -0
  139. package/src/coder/Code/index.ts +16 -0
  140. package/src/coder/CodeCopy/CodeCopy.styles.tsx +21 -0
  141. package/src/coder/CodeCopy/CodeCopy.tsx +36 -0
  142. package/src/coder/CodeCopy/index.ts +7 -0
  143. package/src/coder/CodeSample/CodeSample.tsx +118 -0
  144. package/src/coder/CodeSample/CodeSampleAnalytics.tsx +112 -0
  145. package/src/coder/CodeSample/index.ts +11 -0
  146. package/src/coder/CodeSample/withLocalStored.tsx +50 -0
  147. package/src/coder/CodeTabs/CodeTabs.styles.tsx +126 -0
  148. package/src/coder/CodeTabs/CodeTabs.tsx +128 -0
  149. package/src/coder/CodeTabs/index.ts +6 -0
  150. package/src/coder/CodeTheme/CodeTheme.tsx +126 -0
  151. package/src/coder/CodeTheme/index.ts +7 -0
  152. package/src/coder/CoderProvider.tsx +26 -0
  153. package/src/coder/README.md +1 -0
  154. package/src/coder/hooks/highlight.ts +182 -0
  155. package/src/coder/index.ts +37 -0
  156. package/src/coder/themes/classic.css +57 -0
  157. package/src/coder/themes/classic.ts +270 -0
  158. package/src/coder/themes/cosmo.css +64 -0
  159. package/src/coder/themes/cosmo.ts +264 -0
  160. package/src/content/AppearanceDecorator.styles.tsx +11 -0
  161. package/src/content/ContentDecoator.styles.tsx +180 -0
  162. package/src/content/ContentDecorator.tsx +17 -0
  163. package/src/content/GridDecorator.styles.tsx +86 -0
  164. package/src/content/GridDecorator.tsx +23 -0
  165. package/src/content/ReactContent.tsx +671 -0
  166. package/src/content/TODO.md +1 -0
  167. package/src/content/index.ts +13 -0
  168. package/src/kit/Loader/Loader.styles.tsx +53 -0
  169. package/src/kit/Loader/Loader.tsx +22 -0
  170. package/src/kit/TODO.md +2 -0
  171. package/src/kit/index.ts +1 -0
  172. package/src/layouts/LayoutPrimary/LayoutPrimary.styles.tsx +325 -0
  173. package/src/layouts/LayoutPrimary/LayoutPrimary.tsx +252 -0
  174. package/src/layouts/LayoutPrimary/index.ts +3 -0
  175. package/src/layouts/index.ts +6 -0
  176. package/src/pages/PageBlogHome/PageBlogHome.styles.tsx +67 -0
  177. package/src/pages/PageBlogHome/PageBlogHome.tsx +64 -0
  178. package/src/pages/PageBlogHome/index.ts +3 -0
  179. package/src/pages/PageBlogHome/types.ts +35 -0
  180. package/src/pages/PageBlogPost/PageBlogPost.styles.tsx +4 -0
  181. package/src/pages/PageBlogPost/PageBlogPost.tsx +9 -0
  182. package/src/pages/PageBlogPost/index.ts +3 -0
  183. package/src/pages/PageFirstSlide/PageFirstSlide.styles.tsx +134 -0
  184. package/src/pages/PageFirstSlide/PageFirstSlide.tsx +56 -0
  185. package/src/pages/PageFirstSlide/index.ts +1 -0
  186. package/src/pages/PageFirstSlide/types.ts +67 -0
  187. package/src/pages/PageHome/PageHome.styles.tsx +51 -0
  188. package/src/pages/PageHome/PageHome.tsx +62 -0
  189. package/src/pages/PageHome/index.ts +3 -0
  190. package/src/pages/PageHome/types.ts +79 -0
  191. package/src/pages/index.ts +7 -0
  192. package/src/system/Baseline/Baseline.styles.tsx +128 -0
  193. package/src/system/Baseline/Baseline.tsx +40 -0
  194. package/src/system/Baseline/bun.svg +1 -0
  195. package/src/system/Baseline/check.svg +1 -0
  196. package/src/system/Baseline/index.ts +1 -0
  197. package/src/system/Baseline/logo.svg +1 -0
  198. package/src/system/Baseline/node.svg +7 -0
  199. package/src/system/Baseline/npm.svg +5 -0
  200. package/src/system/Baseline/pnpm.svg +1 -0
  201. package/src/system/Footer/Footer.styles.tsx +213 -0
  202. package/src/system/Footer/Footer.tsx +105 -0
  203. package/src/system/Footer/index.ts +1 -0
  204. package/src/system/SearchButton/SearchButton.styles.tsx +89 -0
  205. package/src/system/SearchButton/SearchButton.tsx +118 -0
  206. package/src/system/SearchButton/index.ts +1 -0
  207. package/src/system/index.ts +3 -0
  208. package/src/utils/useStyle.ts +19 -0
  209. package/src/uxsdk/const.ts +1 -0
  210. package/src/uxsdk/index.ts +21 -0
  211. package/src/uxsdk/useUXClick.ts +21 -0
  212. package/src/uxsdk/useUXEvents.ts +105 -0
  213. package/src/uxsdk/useUXScrollDepth.ts +49 -0
  214. package/src/uxsdk/useUXUnreachableElementTracker.ts +100 -0
  215. package/src/views/HomeView/HomeView.styles.tsx +37 -0
  216. package/src/views/HomeView/HomeView.tsx +34 -0
  217. package/src/views/HomeView/index.ts +3 -0
  218. package/src/writer/Anchor/Anchor.styles.tsx +26 -0
  219. package/src/writer/Anchor/Anchor.tsx +51 -0
  220. package/src/writer/Anchor/index.tsx +1 -0
  221. package/src/writer/Badge/Badge.styles.tsx +44 -0
  222. package/src/writer/Badge/Badge.tsx +47 -0
  223. package/src/writer/Badge/index.ts +7 -0
  224. package/src/writer/Banner/Banner.styles.tsx +111 -0
  225. package/src/writer/Banner/Banner.tsx +151 -0
  226. package/src/writer/Banner/index.ts +1 -0
  227. package/src/writer/Blockquote/Blockquote.styles.tsx +20 -0
  228. package/src/writer/Blockquote/Blockquote.tsx +38 -0
  229. package/src/writer/Blockquote/index.ts +7 -0
  230. package/src/writer/BlogCard/BlogCard.styles.tsx +4 -0
  231. package/src/writer/BlogCard/BlogCard.tsx +9 -0
  232. package/src/writer/BlogCard/index.ts +3 -0
  233. package/src/writer/Breadcrumbs/Breadcrumbs.styles.ts +24 -0
  234. package/src/writer/Breadcrumbs/Breadcrumbs.tsx +57 -0
  235. package/src/writer/Breadcrumbs/index.ts +7 -0
  236. package/src/writer/Button/Button.styles.tsx +149 -0
  237. package/src/writer/Button/Button.tsx +82 -0
  238. package/src/writer/Button/index.ts +2 -0
  239. package/src/writer/Callout/Callout.styles.tsx +102 -0
  240. package/src/writer/Callout/Callout.tsx +166 -0
  241. package/src/writer/Callout/index.tsx +3 -0
  242. package/src/writer/Card/Card.styles.tsx +110 -0
  243. package/src/writer/Card/Card.tsx +94 -0
  244. package/src/writer/Card/index.ts +1 -0
  245. package/src/writer/Code/Code.styles.tsx +16 -0
  246. package/src/writer/Code/Code.tsx +16 -0
  247. package/src/writer/Code/index.ts +3 -0
  248. package/src/writer/ColorSchemeButton/ColorSchemeButton.tsx +191 -0
  249. package/src/writer/ColorSchemeButton/index.ts +1 -0
  250. package/src/writer/Details/Details.styles.tsx +101 -0
  251. package/src/writer/Details/Details.tsx +168 -0
  252. package/src/writer/Details/DetailsProps.tsx +34 -0
  253. package/src/writer/Details/index.ts +6 -0
  254. package/src/writer/GuideCard/GuideCard.styles.tsx +129 -0
  255. package/src/writer/GuideCard/GuideCard.tsx +123 -0
  256. package/src/writer/GuideCard/index.ts +1 -0
  257. package/src/writer/Heading/Heading.styles.tsx +93 -0
  258. package/src/writer/Heading/Heading.tsx +123 -0
  259. package/src/writer/Heading/index.ts +7 -0
  260. package/src/writer/Hr/Hr.styles.tsx +7 -0
  261. package/src/writer/Hr/Hr.tsx +10 -0
  262. package/src/writer/Hr/index.ts +3 -0
  263. package/src/writer/Icon/Icon.styles.tsx +15 -0
  264. package/src/writer/Icon/Icon.tsx +99 -0
  265. package/src/writer/Icon/index.ts +1 -0
  266. package/src/writer/IconSocial/IconSocial.tsx +107 -0
  267. package/src/writer/IconSocial/index.ts +1 -0
  268. package/src/writer/Image/Image.styles.tsx +9 -0
  269. package/src/writer/Image/Image.tsx +35 -0
  270. package/src/writer/Image/index.ts +1 -0
  271. package/src/writer/List/List.styles.tsx +47 -0
  272. package/src/writer/List/List.tsx +29 -0
  273. package/src/writer/List/index.ts +4 -0
  274. package/src/writer/NavLinks/NavLinks.styles.ts +32 -0
  275. package/src/writer/NavLinks/NavLinks.tsx +95 -0
  276. package/src/writer/NavLinks/index.ts +7 -0
  277. package/src/writer/Pre/Pre.styles.tsx +13 -0
  278. package/src/writer/Pre/Pre.tsx +14 -0
  279. package/src/writer/Pre/index.ts +3 -0
  280. package/src/writer/README.md +1 -0
  281. package/src/writer/Steps/Steps.styles.tsx +91 -0
  282. package/src/writer/Steps/Steps.tsx +75 -0
  283. package/src/writer/Steps/index.ts +5 -0
  284. package/src/writer/Table/Table.styles.tsx +100 -0
  285. package/src/writer/Table/Table.tsx +158 -0
  286. package/src/writer/Table/index.ts +3 -0
  287. package/src/writer/Tabs/Tabs.tsx +67 -0
  288. package/src/writer/Tabs/TabsAnalytics.tsx +25 -0
  289. package/src/writer/Tabs/TabsPrimary.styles.tsx +187 -0
  290. package/src/writer/Tabs/TabsPrimary.tsx +215 -0
  291. package/src/writer/Tabs/TabsProps.tsx +13 -0
  292. package/src/writer/Tabs/TabsSecondary.styles.tsx +78 -0
  293. package/src/writer/Tabs/TabsSecondary.tsx +176 -0
  294. package/src/writer/Tabs/index.ts +2 -0
  295. package/src/writer/Tabs/useValueChange.ts +84 -0
  296. package/src/writer/Text/Text.styles.tsx +66 -0
  297. package/src/writer/Text/Text.tsx +79 -0
  298. package/src/writer/Text/index.ts +3 -0
  299. package/src/writer/TocCard/TocCard.module.css +44 -0
  300. package/src/writer/TocCard/TocCard.tsx +42 -0
  301. package/src/writer/TocCard/index.ts +3 -0
  302. package/src/writer/Update/Update.styles.tsx +33 -0
  303. package/src/writer/Update/Update.tsx +37 -0
  304. package/src/writer/Update/index.ts +1 -0
  305. package/src/writer/VideoGuide/VideoGuide.module.css +105 -0
  306. package/src/writer/VideoGuide/VideoGuide.tsx +75 -0
  307. package/src/writer/VideoGuide/index.ts +1 -0
  308. package/src/writer/index.ts +53 -0
  309. package/system.ts +1 -0
  310. package/tsconfig.json +46 -0
  311. package/types.d.ts +52 -0
  312. package/uxsdk.ts +1 -0
  313. package/views.ts +2 -0
  314. package/writer.ts +1 -0
@@ -0,0 +1,112 @@
1
+ import React, { useEffect, useRef, useState } from "react";
2
+
3
+ import { UXNode } from "openux-js";
4
+
5
+ import { useTabsAnalytics } from "../../writer/Tabs/TabsAnalytics";
6
+ import { EVENT_COMPONENT_TAB_CHANGE, useUXEvents, useUXScrollDepth } from "../../uxsdk";
7
+
8
+ const CodeSampleAnalyticsContext = React.createContext<{
9
+ ref: React.RefObject<HTMLPreElement | null>
10
+
11
+ setActiveTab: (tab: string) => void
12
+
13
+ setActiveExample: (example: string) => void
14
+ }>({
15
+ ref: {
16
+ current: null
17
+ },
18
+
19
+ setActiveTab: () => {
20
+ },
21
+
22
+ setActiveExample: () => {
23
+ }
24
+ })
25
+
26
+ export function useCodeSampleAnalytics() {
27
+ return React.useContext(CodeSampleAnalyticsContext)
28
+ }
29
+
30
+ export function CodeSampleAnalytics({ children }: { children: React.ReactNode }) {
31
+ const ref = useRef<HTMLPreElement>(null);
32
+ const [activeTab, setActiveTab] = useState("")
33
+ const [activeExample, setActiveExample] = useState("")
34
+
35
+ const tabs = useTabsAnalytics()
36
+
37
+ useEffect(() => {
38
+ setActiveExample(tabs.value)
39
+ }, [tabs.value])
40
+
41
+ return (
42
+ <CodeSampleAnalyticsContext value={{
43
+ ref,
44
+ setActiveTab,
45
+ setActiveExample
46
+ }}>
47
+ <UXNode
48
+ name="CodeSample"
49
+ props={{
50
+ tab: activeTab,
51
+ example: activeExample,
52
+ code: ""
53
+ }}
54
+ >
55
+ <CodeSampleAnalyticsHooks>
56
+ {children}
57
+ </CodeSampleAnalyticsHooks>
58
+ </UXNode>
59
+ </CodeSampleAnalyticsContext>
60
+ );
61
+ }
62
+
63
+ function CodeSampleAnalyticsHooks({ children }: { children: React.ReactNode }) {
64
+ useExampleTabChange()
65
+ useCodeSampleScroll()
66
+
67
+ return children
68
+ }
69
+
70
+ // TODO: better API
71
+ function useExampleTabChange() {
72
+ const tabs = useTabsAnalytics()
73
+ const ux = useUXEvents();
74
+
75
+ useEffect(() => {
76
+ const tabsElement = tabs.tabsRef.current;
77
+ if (!tabsElement) {
78
+ return
79
+ }
80
+
81
+ function handleTabChange(event: CustomEvent) {
82
+ const { value } = event.detail;
83
+ ux.docs.code.example_change({
84
+ example: value,
85
+ })
86
+ };
87
+
88
+ tabsElement.addEventListener(EVENT_COMPONENT_TAB_CHANGE, handleTabChange as EventListener);
89
+
90
+ return () => {
91
+ tabsElement.removeEventListener(EVENT_COMPONENT_TAB_CHANGE, handleTabChange as EventListener);
92
+ };
93
+ }, [tabs.tabsRef.current]);
94
+ }
95
+
96
+ function useCodeSampleScroll() {
97
+ const codeSampleAnalytics = useCodeSampleAnalytics();
98
+ const ux = useUXEvents();
99
+
100
+ useUXScrollDepth(codeSampleAnalytics.ref, {
101
+ onDepthReached: (depth) => {
102
+ if (depth === 100) {
103
+ ux.docs.code.scroll_100({});
104
+ }
105
+
106
+ ux.docs.code.scroll_depth({
107
+ depth: depth,
108
+ });
109
+ },
110
+ });
111
+ }
112
+
@@ -0,0 +1,11 @@
1
+ export {
2
+ CodeSample,
3
+ } from './CodeSample';
4
+
5
+ export {
6
+ withLocalStored,
7
+ } from './withLocalStored';
8
+
9
+ export type {
10
+ CodeSampleProps,
11
+ } from "./CodeSample";
@@ -0,0 +1,50 @@
1
+ import React, {useState, useEffect} from "react"
2
+
3
+ export interface CodeTabsProps {
4
+ $localStorageKey: string
5
+ $defaultValue: string
6
+
7
+ children: React.ReactNode
8
+ }
9
+
10
+ // TODO: move to CodeTabs?
11
+ export function withLocalStored(Component: any) {
12
+ return function LocalStored(props: CodeTabsProps) {
13
+ const [value, setValue] = useState(
14
+ typeof localStorage !== "undefined"
15
+ ? localStorage?.getItem(props.$localStorageKey) || props.$defaultValue
16
+ : props.$defaultValue,
17
+ )
18
+
19
+ useEffect(() => {
20
+ const handler = (e: StorageEvent) => {
21
+ if (e.key === props.$localStorageKey) {
22
+ setValue(e.newValue || props.$defaultValue)
23
+ }
24
+ }
25
+ window.addEventListener("storage", handler)
26
+ return () => {
27
+ window.removeEventListener("storage", handler)
28
+ }
29
+ }, [props.$localStorageKey])
30
+
31
+ function onValueChange(value: string) {
32
+ localStorage.setItem(props.$localStorageKey, value)
33
+ window.dispatchEvent(
34
+ new StorageEvent("storage", {
35
+ key: props.$localStorageKey,
36
+ newValue: value,
37
+ }),
38
+ )
39
+ }
40
+
41
+ return (
42
+ <Component
43
+ onValueChange={onValueChange}
44
+ value={value}
45
+ >
46
+ {props.children}
47
+ </Component>
48
+ )
49
+ }
50
+ }
@@ -0,0 +1,126 @@
1
+ import { css } from "@linaria/core";
2
+
3
+ export const CodeTabsHost = css`
4
+ display: grid;
5
+ `
6
+
7
+ export const CodeTabsRoot = css`
8
+ @layer defaults {
9
+ overflow: hidden;
10
+ min-width: 0;
11
+
12
+ border: 1px solid var(--xyd-codetabs-border-color);
13
+ border-radius: 16px;
14
+
15
+ &[data-single="true"] [part="pre"] {
16
+ border: none;
17
+ }
18
+
19
+ &[data-nodescription="true"] {
20
+ xyd-codetabs-languages [part="languages-list"] {
21
+ justify-content: flex-start;
22
+ }
23
+ }
24
+ }
25
+ `;
26
+
27
+ export const CodeTabsLanguagesHost = css`
28
+ @layer defaults {
29
+ --codetabs-color: var(--user-codetabs-color, var(--xyd-codetabs-color));
30
+ --codetabs-color--active: var(--user-codetabs-color--active, var(--xyd-codetabs-color--active));
31
+ --codetabs-color--hover: var(--user-codetabs-color--hover, var(--xyd-codetabs-color--hover));
32
+
33
+ position: relative;
34
+ display: flex;
35
+ justify-content: space-between;
36
+ flex: 1 1 0%;
37
+
38
+ background: var(--user-codetabs-bgcolor, var(--xyd-codetabs-bgcolor));
39
+
40
+ border-top-right-radius: 10px;
41
+ border-top-left-radius: 10px;
42
+ border-bottom: 0px;
43
+
44
+ min-width: 0;
45
+
46
+ font-weight: var(--xyd-font-weight-semibold);
47
+ font-size: var(--xyd-font-size-xsmall);
48
+
49
+ &[data-single="true"] {
50
+ height: 0;
51
+ }
52
+
53
+ [part="description"] {
54
+ display: flex;
55
+ flex: 1;
56
+ align-items: center;
57
+ gap: 4px;
58
+
59
+ color: var(--codetabs-color);
60
+
61
+ margin-left: 4px;
62
+ margin-right: 4px;
63
+ }
64
+
65
+ [part="description-item"] {
66
+ display: flex;
67
+ padding-left: 16px;
68
+ padding-right: 16px;
69
+ flex: 1 1 0%;
70
+ gap: 16px;
71
+ border-radius: 4px;
72
+ }
73
+
74
+ [part="copy"] {
75
+ display: none;
76
+ }
77
+
78
+ [part="languages-list"] {
79
+ display: flex;
80
+ gap: 8px;
81
+ padding: 0 10px;
82
+ overflow: auto;
83
+ }
84
+
85
+ [part="language-trigger"] {
86
+ all: unset;
87
+
88
+ cursor: pointer;
89
+
90
+ display: flex;
91
+ align-items: center;
92
+ justify-content: center;
93
+
94
+ border-radius: 6px;
95
+ padding: 6px;
96
+
97
+ color: var(--codetabs-color);
98
+
99
+ &[data-state="active"] {
100
+ color: var(--codetabs-color--active);
101
+ border-bottom: 1px solid var(--codetabs-color--active);
102
+ border-bottom-left-radius: 0px;
103
+ border-bottom-right-radius: 0px;
104
+ }
105
+
106
+ &:hover {
107
+ transition: ease-in 0.1s;
108
+ background: var(--codetabs-color--hover);
109
+ }
110
+ }
111
+
112
+ [part="copy"] {
113
+ display: flex;
114
+ padding-left: 8px;
115
+ padding-right: 8px;
116
+ align-items: center;
117
+ }
118
+ &[data-single="true"] [part="copy"] {
119
+ position: absolute;
120
+ right: 0;
121
+ }
122
+ }
123
+ `;
124
+
125
+
126
+
@@ -0,0 +1,128 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import {Tabs as TabsPrimitive} from "radix-ui"; // TODO: remove and use separation
3
+ import {
4
+ HighlightedCode,
5
+ } from "codehike/code"
6
+
7
+ import {
8
+ CodeCopy,
9
+ } from "../CodeCopy";
10
+ import * as cn from "./CodeTabs.styles"; // TODO: style by highlighted?
11
+ import { SyntaxHighlightedCode } from "../CodeTheme/CodeTheme";
12
+ import { useCodeSampleAnalytics } from "../CodeSample/CodeSampleAnalytics";
13
+ import { useUXEvents } from "../../uxsdk";
14
+
15
+ export interface CodeTabsProps {
16
+ description: string;
17
+ highlighted: SyntaxHighlightedCode[]
18
+ className?: string
19
+ controlByMeta?: boolean // TODO: BETTER IN THE FUTURE
20
+ }
21
+
22
+ export function withCodeTabs(PreComponent) {
23
+ return function CodeTabs(props: CodeTabsProps) {
24
+ const isSingle = props?.highlighted?.length === 1 && !props.description
25
+ const defaultValue = props.highlighted[0]?.meta || props.highlighted[0]?.lang
26
+ const [activeTab, setActiveTab] = useState(defaultValue)
27
+
28
+ const codeSampleAnalytics = useCodeSampleAnalytics()
29
+ const ux = useUXEvents()
30
+
31
+ // Reset active tab when highlighted prop changes
32
+ useEffect(() => {
33
+ setActiveTab(defaultValue)
34
+ }, [defaultValue])
35
+
36
+ useEffect(() => {
37
+ codeSampleAnalytics.setActiveTab(activeTab)
38
+ }, [])
39
+
40
+ function changeTab(value: string) {
41
+ setActiveTab(value)
42
+ codeSampleAnalytics.setActiveTab(value)
43
+ ux.docs.code.tab_change({tab: value})
44
+ }
45
+
46
+ if (props?.highlighted?.length === 0) {
47
+ return null
48
+ }
49
+
50
+ return (
51
+ <xyd-codetabs className={`${cn.CodeTabsHost} ${props.className || ""}`}>
52
+ <TabsPrimitive.Root
53
+ part="root"
54
+ data-single={String(isSingle)}
55
+ data-nodescription={!props.description ? "true" : undefined}
56
+ className={`${cn.CodeTabsRoot}`}
57
+ style={props.highlighted[0]?.style}
58
+ value={activeTab}
59
+ onValueChange={changeTab}
60
+ >
61
+ <$LanguageTabSwitcher
62
+ description={props.description}
63
+ highlighted={props.highlighted}
64
+ />
65
+
66
+ {props.highlighted?.map((codeblock, i) => (
67
+ <TabsPrimitive.Content value={codeblock.meta || codeblock.lang} key={i}>
68
+ <PreComponent
69
+ style={codeblock?.style || codeblock?.style}
70
+ codeblock={codeblock}
71
+ />
72
+ </TabsPrimitive.Content>
73
+ ))}
74
+ </TabsPrimitive.Root>
75
+ </xyd-codetabs>
76
+ )
77
+ }
78
+ }
79
+
80
+ interface LanguageTabSwitcherProps {
81
+ description: string;
82
+ highlighted: HighlightedCode[]
83
+ }
84
+
85
+ function $LanguageTabSwitcher(props: LanguageTabSwitcherProps) {
86
+ const isSingle = props?.highlighted?.length === 1 && !props.description
87
+
88
+ const highlighted = props.highlighted.filter((item, index, self) =>
89
+ index === self.findIndex((t) => (t.meta || t.lang) === (item.meta || item.lang))
90
+ );
91
+ return <xyd-codetabs-languages
92
+ data-single={String(isSingle)}
93
+ className={`
94
+ ${cn.CodeTabsLanguagesHost}
95
+ `}>
96
+
97
+ {
98
+ props.description && <div part="description">
99
+ <div part="description-item">
100
+ {props.description}
101
+ </div>
102
+ </div>
103
+ }
104
+
105
+ <TabsPrimitive.List part="languages-list">
106
+ {highlighted?.map(({ meta, lang }, i) => {
107
+ if (isSingle) {
108
+ return null
109
+ }
110
+ return <TabsPrimitive.Trigger
111
+ part="language-trigger"
112
+ value={meta || lang}
113
+ key={i}
114
+ >
115
+ {meta || lang}
116
+ </TabsPrimitive.Trigger>
117
+ })}
118
+ </TabsPrimitive.List>
119
+
120
+ <div part="copy">
121
+ {highlighted?.map((codeblock, i) => (
122
+ <TabsPrimitive.Content value={codeblock.meta || codeblock.lang} asChild key={i}>
123
+ <CodeCopy text={codeblock.value} />
124
+ </TabsPrimitive.Content>
125
+ ))}
126
+ </div>
127
+ </xyd-codetabs-languages>
128
+ }
@@ -0,0 +1,6 @@
1
+ export type {
2
+ CodeTabsProps
3
+ } from "./CodeTabs";
4
+ export {
5
+ withCodeTabs
6
+ } from "./CodeTabs";
@@ -0,0 +1,126 @@
1
+ import React, { createContext, useState, use, useEffect, Suspense } from "react";
2
+ import { Theme } from "@code-hike/lighter";
3
+ import { highlight } from "codehike/code";
4
+ import type { HighlightedCode as CodeHikeHighlightedCode } from "codehike/code";
5
+
6
+ import defaultTheme from "../themes/cosmo"
7
+ import { Loader } from "../../kit";
8
+
9
+ export interface CodeThemeProps {
10
+ codeblocks?: CodeThemeBlockProps[];
11
+ theme?: Theme
12
+ children: React.ReactNode;
13
+ }
14
+
15
+ export interface SyntaxHighlightedCode extends CodeHikeHighlightedCode {
16
+ title?: string
17
+ }
18
+
19
+ export interface CodeThemeBlockProps {
20
+ /** This is the raw code. May include annotation comments. */
21
+ value: string;
22
+ /** The programming language. */
23
+ lang: string;
24
+ /** Metadata string (the content after the language name in a markdown codeblock). */
25
+ meta: string;
26
+
27
+ title?: string
28
+
29
+ /** The highlighted code. */
30
+ highlighted?: SyntaxHighlightedCode
31
+ }
32
+
33
+ const CodeThemeProvider = createContext<{
34
+ highlighted: SyntaxHighlightedCode[];
35
+ }>({
36
+ highlighted: [],
37
+ });
38
+
39
+ export function useCodeTheme() {
40
+ return use(CodeThemeProvider);
41
+ }
42
+
43
+ // TODO: lazy-loading - some codeblocks on server and another on client
44
+ // TODO: lazdy client loading only on specific codeblock
45
+ export function CodeTheme(props: CodeThemeProps) {
46
+ // Initialize with server-side highlighted codeblocks
47
+ const [highlighted, setHighlighted] = useState<HighlightedCode[] | undefined>(initializeHighlighted(props.codeblocks));
48
+ const [clientSideFetch, setClientSideFetch] = useState(true)
49
+
50
+ useEffect(() => {
51
+ setHighlighted(initializeHighlighted(props.codeblocks))
52
+ }, [props.codeblocks])
53
+
54
+ useEffect(() => {
55
+ if (!props.codeblocks) {
56
+ return;
57
+ }
58
+
59
+ // Check if we need to highlight any codeblocks
60
+ const needsHighlighting = props.codeblocks.some(
61
+ codeblock => !codeblock.highlighted || !codeblock.highlighted.tokens
62
+ );
63
+
64
+ if (needsHighlighting) {
65
+ clientSideHighlight();
66
+ }
67
+ }, [props.codeblocks]);
68
+
69
+ function initializeHighlighted(codeblocks: any) {
70
+ if (!codeblocks) return [];
71
+
72
+ return codeblocks.map(codeblock => {
73
+ if (codeblock.highlighted && codeblock.highlighted.tokens) {
74
+ return {
75
+ ...codeblock.highlighted,
76
+ meta: codeblock.highlighted?.meta || codeblock.meta,
77
+ title: codeblock.title
78
+ };
79
+ }
80
+
81
+ return null
82
+ }).filter(Boolean) as SyntaxHighlightedCode[]
83
+ }
84
+
85
+ async function clientSideHighlight() {
86
+ if (!props.codeblocks) {
87
+ return;
88
+ }
89
+
90
+ const allHighlighted = props.codeblocks.every(codeblock => codeblock.highlighted)
91
+ if (allHighlighted) {
92
+ return;
93
+ }
94
+
95
+ const newHighlighted = await fetchHighlight(props.codeblocks, props.theme || defaultTheme);
96
+ setHighlighted(newHighlighted)
97
+
98
+ setClientSideFetch(false)
99
+ }
100
+
101
+ const withTheme = <CodeThemeProvider
102
+ value={{
103
+ highlighted: highlighted || [],
104
+ }}
105
+ >
106
+ {props.children}
107
+ </CodeThemeProvider>
108
+
109
+ const allHighlighted = props.codeblocks?.every(codeblock => codeblock.highlighted)
110
+ if (allHighlighted) {
111
+ return withTheme
112
+ }
113
+
114
+ if (clientSideFetch) {
115
+ return <Loader />
116
+ }
117
+
118
+ return withTheme
119
+ }
120
+
121
+ // TODO: own server with grammars (codehike)
122
+ async function fetchHighlight(codeblocks: CodeThemeBlockProps[], theme: Theme) {
123
+ return await Promise.all(
124
+ codeblocks?.map((codeblock) => highlight(codeblock, theme))
125
+ );
126
+ }
@@ -0,0 +1,7 @@
1
+ export type {CodeThemeProps, CodeThemeBlockProps} from "./CodeTheme";
2
+
3
+ export {
4
+ CodeTheme,
5
+
6
+ useCodeTheme
7
+ } from "./CodeTheme";
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ import { createContext, useContext } from "react";
3
+
4
+ const CoderContext = createContext<{
5
+ lines?: boolean
6
+ scroll?: boolean
7
+ }>({
8
+ lines: undefined,
9
+ scroll: undefined,
10
+ })
11
+
12
+
13
+ interface CoderProviderProps {
14
+ children: React.ReactNode
15
+
16
+ lines?: boolean
17
+
18
+ scroll?: boolean
19
+ }
20
+ export function CoderProvider({ children, lines, scroll }: CoderProviderProps) {
21
+ return <CoderContext.Provider value={{ lines, scroll }}>{children}</CoderContext.Provider>
22
+ }
23
+
24
+ export function useCoder() {
25
+ return useContext(CoderContext)
26
+ }
@@ -0,0 +1 @@
1
+ # @xyd-js/components/coder