@xyd-js/atlas 0.0.0-build
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.
- package/.babelrc +6 -0
- package/.storybook/index.css +6 -0
- package/.storybook/main.ts +19 -0
- package/.storybook/preview.ts +17 -0
- package/.storybook/public/fonts/fustat-ext-500.woff2 +0 -0
- package/.storybook/public/fonts/fustat-ext-600.woff2 +0 -0
- package/.storybook/public/fonts/fustat-ext-700.woff2 +0 -0
- package/.storybook/public/fonts/fustat-regular.woff2 +0 -0
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +3 -0
- package/declarations.d.ts +4 -0
- package/dist/VideoGuide-BLUkXIOB-Dk2lkn4r.js +4 -0
- package/dist/VideoGuide-BLUkXIOB-Dk2lkn4r.js.map +1 -0
- package/dist/index.css +48 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +104 -0
- package/dist/tokens.css +60 -0
- package/dist/xydPlugin.d.ts +5 -0
- package/dist/xydPlugin.js +2 -0
- package/dist/xydPlugin.js.map +1 -0
- package/index.ts +2 -0
- package/package.json +68 -0
- package/packages/xyd-plugin/SidebarItem.tsx +27 -0
- package/packages/xyd-plugin/index.ts +20 -0
- package/postcss.config.cjs +5 -0
- package/rollup.config.js +120 -0
- package/src/components/ApiRef/ApiRefItem/ApiRefItem.styles.tsx +110 -0
- package/src/components/ApiRef/ApiRefItem/ApiRefItem.tsx +557 -0
- package/src/components/ApiRef/ApiRefItem/index.ts +7 -0
- package/src/components/ApiRef/ApiRefProperties/ApiRefProperties.styles.tsx +202 -0
- package/src/components/ApiRef/ApiRefProperties/ApiRefProperties.tsx +665 -0
- package/src/components/ApiRef/ApiRefProperties/index.ts +7 -0
- package/src/components/ApiRef/ApiRefSamples/ApiRefSamples.styles.tsx +28 -0
- package/src/components/ApiRef/ApiRefSamples/ApiRefSamples.tsx +69 -0
- package/src/components/ApiRef/ApiRefSamples/index.ts +7 -0
- package/src/components/ApiRef/index.ts +5 -0
- package/src/components/Atlas/Atlas.styles.tsx +5 -0
- package/src/components/Atlas/Atlas.tsx +43 -0
- package/src/components/Atlas/AtlasContext.tsx +47 -0
- package/src/components/Atlas/AtlasDecorator.styles.ts +22 -0
- package/src/components/Atlas/AtlasDecorator.tsx +15 -0
- package/src/components/Atlas/AtlasLazy/AtlasLazy.styles.tsx +9 -0
- package/src/components/Atlas/AtlasLazy/AtlasLazy.tsx +42 -0
- package/src/components/Atlas/AtlasLazy/hooks.ts +29 -0
- package/src/components/Atlas/AtlasLazy/index.ts +7 -0
- package/src/components/Atlas/AtlasPrimary.tsx +21 -0
- package/src/components/Atlas/AtlasSecondary.tsx +148 -0
- package/src/components/Atlas/index.ts +7 -0
- package/src/components/Atlas/types.ts +11 -0
- package/src/components/Code/CodeSampleButtons/CodeSampleButtons.styles.tsx +58 -0
- package/src/components/Code/CodeSampleButtons/CodeSampleButtons.tsx +97 -0
- package/src/components/Code/CodeSampleButtons/index.ts +7 -0
- package/src/components/Code/index.ts +2 -0
- package/src/components/Icon/index.tsx +386 -0
- package/src/docs/AtlasExample/AtlasExample.stories.tsx +47 -0
- package/src/docs/AtlasExample/todo-app.uniform.json +625 -0
- package/src/docs/AtlasExample/uniform-to-references.ts +101 -0
- package/src/styles/styles.css +104 -0
- package/src/styles/tokens.css +60 -0
- package/src/utils/mdx.ts +2 -0
- package/tsconfig.json +51 -0
- package/types.d.ts +22 -0
- package/vite.config.ts +25 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React, { useState, useMemo } from "react";
|
|
2
|
+
import { UXNode } from "openux-js";
|
|
3
|
+
|
|
4
|
+
import { ExampleRoot } from "@xyd-js/uniform";
|
|
5
|
+
import { CodeSample, type CodeThemeBlockProps } from "@xyd-js/components/coder";
|
|
6
|
+
|
|
7
|
+
import { CodeExampleButtons } from "@/components/Code";
|
|
8
|
+
import { useSyntaxHighlight } from "@/components/Atlas/AtlasContext";
|
|
9
|
+
|
|
10
|
+
import * as cn from "./ApiRefSamples.styles";
|
|
11
|
+
|
|
12
|
+
export interface ApiRefSamplesProps {
|
|
13
|
+
examples: ExampleRoot
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function ApiRefSamples({ examples }: ApiRefSamplesProps) {
|
|
17
|
+
const syntaxHighlight = useSyntaxHighlight()
|
|
18
|
+
const [activeExampleIndices, setActiveExampleIndices] = useState<Record<number, number>>({})
|
|
19
|
+
|
|
20
|
+
const handleExampleChange = (groupIndex: number, exampleIndex: number) => {
|
|
21
|
+
setActiveExampleIndices(prev => ({
|
|
22
|
+
...prev,
|
|
23
|
+
[groupIndex]: exampleIndex
|
|
24
|
+
}))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return <atlas-apiref-samples className={cn.ApiRefSamplesContainerHost}>
|
|
28
|
+
{
|
|
29
|
+
examples.groups?.map(({ description, examples: example }, i) => {
|
|
30
|
+
const activeExampleIndex = activeExampleIndices[i] || 0
|
|
31
|
+
const activeExample = example[activeExampleIndex]
|
|
32
|
+
|
|
33
|
+
const codeblocks = activeExample?.codeblock?.tabs?.map(tab => ({
|
|
34
|
+
value: String(tab.code || ""),
|
|
35
|
+
lang: String(tab.language || ""),
|
|
36
|
+
meta: String(tab.context || ""),
|
|
37
|
+
highlighted: tab.highlighted
|
|
38
|
+
} as CodeThemeBlockProps)) || []
|
|
39
|
+
|
|
40
|
+
return <UXNode
|
|
41
|
+
name="APIRefSample"
|
|
42
|
+
props={activeExample}
|
|
43
|
+
>
|
|
44
|
+
<div key={i} className={cn.ApiRefSamplesGroupHost}>
|
|
45
|
+
{
|
|
46
|
+
example?.length > 1
|
|
47
|
+
? <CodeExampleButtons
|
|
48
|
+
activeExample={activeExample}
|
|
49
|
+
examples={example}
|
|
50
|
+
onClick={(ex) => {
|
|
51
|
+
const index = example.findIndex(e => e === ex)
|
|
52
|
+
handleExampleChange(i, index)
|
|
53
|
+
}}
|
|
54
|
+
/>
|
|
55
|
+
: null
|
|
56
|
+
}
|
|
57
|
+
<CodeSample
|
|
58
|
+
name={String(i)}
|
|
59
|
+
description={description || ""}
|
|
60
|
+
codeblocks={codeblocks}
|
|
61
|
+
theme={syntaxHighlight || undefined}
|
|
62
|
+
// controlByMeta
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
</UXNode>
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
</atlas-apiref-samples>
|
|
69
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { MDXCommonAtlasProps } from "./types";
|
|
4
|
+
import { AtlasDecorator } from "./AtlasDecorator";
|
|
5
|
+
import { AtlasPrimary } from "./AtlasPrimary";
|
|
6
|
+
import { AtlasSecondary } from "./AtlasSecondary";
|
|
7
|
+
|
|
8
|
+
import * as cn from "./Atlas.styles";
|
|
9
|
+
|
|
10
|
+
interface AtlasProps<T> extends MDXCommonAtlasProps<T> {
|
|
11
|
+
kind: "secondary" | "primary" | undefined | null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function Atlas<T>(props: AtlasProps<T>) {
|
|
15
|
+
let AtlasComponent: React.FC<MDXCommonAtlasProps<T>>;
|
|
16
|
+
|
|
17
|
+
if (props.kind === "secondary") {
|
|
18
|
+
AtlasComponent = AtlasSecondary;
|
|
19
|
+
} else {
|
|
20
|
+
AtlasComponent = AtlasPrimary;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let references = props.references
|
|
24
|
+
{
|
|
25
|
+
// TODO: find better solution - if we pass from md then its string
|
|
26
|
+
if (references && typeof references === "string") { // TODO: DO IT BETTER
|
|
27
|
+
try {
|
|
28
|
+
references = JSON.parse(references)
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error("Error parsing references", error)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return <AtlasDecorator>
|
|
36
|
+
<div className={cn.AtlasHost}>
|
|
37
|
+
<AtlasComponent
|
|
38
|
+
references={references}
|
|
39
|
+
apiRefItemKind={props.apiRefItemKind}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
</AtlasDecorator>
|
|
43
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
|
|
3
|
+
import { type Theme } from "@code-hike/lighter";
|
|
4
|
+
|
|
5
|
+
export interface VariantToggleConfig {
|
|
6
|
+
key: string;
|
|
7
|
+
defaultValue: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const AtlasContext = createContext<{
|
|
11
|
+
syntaxHighlight: Theme | null,
|
|
12
|
+
baseMatch?: string,
|
|
13
|
+
variantToggles?: VariantToggleConfig[], // Array of toggle configurations
|
|
14
|
+
Link?: any
|
|
15
|
+
}>({
|
|
16
|
+
syntaxHighlight: null
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
export function useSyntaxHighlight() {
|
|
20
|
+
const context = useContext(AtlasContext)
|
|
21
|
+
|
|
22
|
+
if (!context) {
|
|
23
|
+
throw new Error("useSyntaxHighlight must be used within a AtlasContext")
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return context.syntaxHighlight
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function useBaseMatch() {
|
|
30
|
+
const context = useContext(AtlasContext)
|
|
31
|
+
|
|
32
|
+
if (!context) {
|
|
33
|
+
throw new Error("useBaseMatch must be used within a AtlasContext")
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return context.baseMatch
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function useVariantToggles() {
|
|
40
|
+
const context = useContext(AtlasContext)
|
|
41
|
+
|
|
42
|
+
if (!context) {
|
|
43
|
+
throw new Error("useVariantToggles must be used within a AtlasContext")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return context.variantToggles || []
|
|
47
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { css } from "@linaria/core";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
AtlasDecoratorHost: css`
|
|
5
|
+
@layer templates {
|
|
6
|
+
atlas-apiref-proptype {
|
|
7
|
+
font-size: var(--xyd-font-size-xsmall);
|
|
8
|
+
line-height: var(--xyd-line-height-xsmall);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
atlas-apiref-item-showcase {
|
|
12
|
+
font-size: var(--xyd-font-size-small);
|
|
13
|
+
line-height: var(--xyd-line-height-medium);
|
|
14
|
+
|
|
15
|
+
p {
|
|
16
|
+
font-size: var(--xyd-font-size-small);
|
|
17
|
+
line-height: var(--xyd-line-height-medium);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
`
|
|
22
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import cn from "./AtlasDecorator.styles";
|
|
4
|
+
|
|
5
|
+
interface AtlasDecoratorProps {
|
|
6
|
+
children: React.ReactNode
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function AtlasDecorator({ children }: AtlasDecoratorProps) {
|
|
10
|
+
return <atlas-decorator
|
|
11
|
+
className={cn.AtlasDecoratorHost}
|
|
12
|
+
>
|
|
13
|
+
{children}
|
|
14
|
+
</atlas-decorator>
|
|
15
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, {useEffect, useRef} from "react";
|
|
2
|
+
|
|
3
|
+
import {Reference} from "@xyd-js/uniform";
|
|
4
|
+
|
|
5
|
+
import {ApiRefItem} from "@/components/ApiRef";
|
|
6
|
+
|
|
7
|
+
import * as cn from "./AtlasLazy.styles";
|
|
8
|
+
|
|
9
|
+
export interface AtlasLazyProps {
|
|
10
|
+
references: Reference[]
|
|
11
|
+
urlPrefix: string
|
|
12
|
+
slug: string,
|
|
13
|
+
onLoaded?: () => void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function AtlasLazy(props: AtlasLazyProps) {
|
|
17
|
+
return props.references?.map((reference: any, i: number) => <>
|
|
18
|
+
<div
|
|
19
|
+
key={i}
|
|
20
|
+
// TODO: slug should be passed from reference or somrthing
|
|
21
|
+
// ref={`api-reference/${reference.title}` === slug ? targetRef : null} // Attach ref to the 30th item
|
|
22
|
+
className={`${cn.AtlasLazyItemHost} ${i === 0 && cn.AtlasLazyItemFirst}`}
|
|
23
|
+
// TODO: slug prefix props
|
|
24
|
+
data-slug={`${props.urlPrefix}/${reference.canonical?.title}`}
|
|
25
|
+
>
|
|
26
|
+
<ItemWrapper
|
|
27
|
+
reference={reference}
|
|
28
|
+
onLoad={i === props.references.length - 1 ? props.onLoaded : null}
|
|
29
|
+
/>
|
|
30
|
+
</div>
|
|
31
|
+
</>)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function ItemWrapper({reference, onLoad}) {
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
onLoad && onLoad()
|
|
37
|
+
}, []);
|
|
38
|
+
|
|
39
|
+
return <>
|
|
40
|
+
<ApiRefItem reference={reference}/>
|
|
41
|
+
</>
|
|
42
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {useEffect} from "react";
|
|
2
|
+
|
|
3
|
+
function getScrollPosition() {
|
|
4
|
+
return sessionStorage.getItem('scrollPosition');
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function useScrollRestoration() {
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const saveScrollPosition = () => {
|
|
10
|
+
sessionStorage.setItem('scrollPosition', window.scrollY.toString());
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
window.addEventListener('beforeunload', saveScrollPosition);
|
|
14
|
+
|
|
15
|
+
return () => {
|
|
16
|
+
window.removeEventListener('beforeunload', saveScrollPosition);
|
|
17
|
+
};
|
|
18
|
+
}, []);
|
|
19
|
+
|
|
20
|
+
return [
|
|
21
|
+
() => getScrollPosition(),
|
|
22
|
+
() => {
|
|
23
|
+
const scrollPosition = getScrollPosition();
|
|
24
|
+
if (scrollPosition) {
|
|
25
|
+
window.scrollTo(0, parseInt(scrollPosition, 10));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React, {} from "react";
|
|
2
|
+
|
|
3
|
+
import {ApiRefItem} from "@/components/ApiRef";
|
|
4
|
+
|
|
5
|
+
import {MDXCommonAtlasProps} from "./types";
|
|
6
|
+
|
|
7
|
+
export function AtlasPrimary<T>(props: MDXCommonAtlasProps<T>) {
|
|
8
|
+
return <>
|
|
9
|
+
{
|
|
10
|
+
props.references?.map((reference, i) =>
|
|
11
|
+
<ApiRefItem
|
|
12
|
+
key={i}
|
|
13
|
+
reference={{
|
|
14
|
+
...reference
|
|
15
|
+
}}
|
|
16
|
+
kind={props.apiRefItemKind || undefined}
|
|
17
|
+
/>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
</>
|
|
21
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
import {type Theme} from "@code-hike/lighter";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Heading,
|
|
7
|
+
Table,
|
|
8
|
+
Details,
|
|
9
|
+
Code,
|
|
10
|
+
} from "@xyd-js/components/writer";
|
|
11
|
+
import {CodeSample} from "@xyd-js/components/coder";
|
|
12
|
+
|
|
13
|
+
import {MDXCommonAtlasProps} from "@/components/Atlas/types";
|
|
14
|
+
import {useSyntaxHighlight} from "./AtlasContext";
|
|
15
|
+
import {IconQuote} from "@/components/Icon";
|
|
16
|
+
|
|
17
|
+
// TODO: interface should be imported from somewhere
|
|
18
|
+
interface CodeSourceContext {
|
|
19
|
+
fileName: string;
|
|
20
|
+
fileFullPath: string;
|
|
21
|
+
sourcecode: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const MAX_REFERENCES = 2;
|
|
25
|
+
|
|
26
|
+
interface ReferenceItemProps {
|
|
27
|
+
reference: any;
|
|
28
|
+
index: number;
|
|
29
|
+
syntaxHighlight: Theme | null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
export function AtlasSecondary<T>({references}: MDXCommonAtlasProps<T>) {
|
|
34
|
+
const syntaxHighlight = useSyntaxHighlight()
|
|
35
|
+
|
|
36
|
+
if (!references) return null;
|
|
37
|
+
|
|
38
|
+
const initialReferences = references.slice(0, MAX_REFERENCES);
|
|
39
|
+
const remainingReferences = references.slice(MAX_REFERENCES);
|
|
40
|
+
|
|
41
|
+
const showMoreText = remainingReferences.length > 0 ?
|
|
42
|
+
`Show more (${remainingReferences.length}) reference${remainingReferences.length === 1 ? '' : 's'}` :
|
|
43
|
+
'';
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<>
|
|
47
|
+
{initialReferences.map((reference, i) => (
|
|
48
|
+
<$ReferenceItem
|
|
49
|
+
key={i}
|
|
50
|
+
reference={reference}
|
|
51
|
+
index={i}
|
|
52
|
+
syntaxHighlight={syntaxHighlight}
|
|
53
|
+
/>
|
|
54
|
+
))}
|
|
55
|
+
|
|
56
|
+
{remainingReferences.length > 0 && (
|
|
57
|
+
<Details
|
|
58
|
+
label={showMoreText}
|
|
59
|
+
>
|
|
60
|
+
{remainingReferences.map((reference, i) => (
|
|
61
|
+
<$ReferenceItem
|
|
62
|
+
key={i + MAX_REFERENCES}
|
|
63
|
+
reference={reference}
|
|
64
|
+
index={i + MAX_REFERENCES}
|
|
65
|
+
syntaxHighlight={syntaxHighlight}
|
|
66
|
+
/>
|
|
67
|
+
))}
|
|
68
|
+
</Details>
|
|
69
|
+
)}
|
|
70
|
+
</>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function $ReferenceItem({reference, index, syntaxHighlight}: ReferenceItemProps) {
|
|
75
|
+
return (
|
|
76
|
+
<React.Fragment key={index}>
|
|
77
|
+
<Heading size={3}>
|
|
78
|
+
{reference.title}
|
|
79
|
+
</Heading>
|
|
80
|
+
|
|
81
|
+
{/*<p>*/}
|
|
82
|
+
{/* {uniformChild(reference.description)}*/}
|
|
83
|
+
{/*</p>*/}
|
|
84
|
+
|
|
85
|
+
{
|
|
86
|
+
reference.context?.fileName && <Details
|
|
87
|
+
label=""
|
|
88
|
+
kind="tertiary"
|
|
89
|
+
title={<>
|
|
90
|
+
Source code in <Code>{reference.context.fileFullPath}</Code>
|
|
91
|
+
</>}
|
|
92
|
+
icon={<IconQuote/>}>
|
|
93
|
+
<CodeSample
|
|
94
|
+
name={reference.context.fileName}
|
|
95
|
+
description={reference.context.sourcecode.description}
|
|
96
|
+
theme={syntaxHighlight || undefined}
|
|
97
|
+
codeblocks={[
|
|
98
|
+
{
|
|
99
|
+
lang: reference.context.sourcecode.lang,
|
|
100
|
+
meta: "",
|
|
101
|
+
value: reference.context.sourcecode.code
|
|
102
|
+
}
|
|
103
|
+
]}
|
|
104
|
+
/>
|
|
105
|
+
{/* {parseChild(reference.context.sourcecode)} */}
|
|
106
|
+
</Details>
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
{
|
|
110
|
+
reference.definitions.map((definition: any, index: number) => {
|
|
111
|
+
return (
|
|
112
|
+
<React.Fragment key={index}>
|
|
113
|
+
<Heading size={4}>
|
|
114
|
+
{definition.title}
|
|
115
|
+
</Heading>
|
|
116
|
+
<Table>
|
|
117
|
+
<Table.Head>
|
|
118
|
+
<Table.Tr>
|
|
119
|
+
<Table.Th>Name</Table.Th>
|
|
120
|
+
<Table.Th>Type</Table.Th>
|
|
121
|
+
<Table.Th>Description</Table.Th>
|
|
122
|
+
</Table.Tr>
|
|
123
|
+
</Table.Head>
|
|
124
|
+
<Table.Body>
|
|
125
|
+
{definition.properties?.map((property: any, propIndex: number) => (
|
|
126
|
+
<Table.Tr key={propIndex}>
|
|
127
|
+
<Table.Td>
|
|
128
|
+
<Code>{property.name}</Code>
|
|
129
|
+
</Table.Td>
|
|
130
|
+
<Table.Td>
|
|
131
|
+
<Code>{property.type}</Code>
|
|
132
|
+
</Table.Td>
|
|
133
|
+
<Table.Td muted>
|
|
134
|
+
{property.description}
|
|
135
|
+
</Table.Td>
|
|
136
|
+
</Table.Tr>
|
|
137
|
+
))}
|
|
138
|
+
</Table.Body>
|
|
139
|
+
</Table>
|
|
140
|
+
</React.Fragment>
|
|
141
|
+
)
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
<br/>
|
|
146
|
+
</React.Fragment>
|
|
147
|
+
)
|
|
148
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Reference } from "@xyd-js/uniform";
|
|
2
|
+
|
|
3
|
+
// TODO unify MDXCommonAtlasProps and AtlasProps
|
|
4
|
+
export interface MDXCommonAtlasProps<T> {
|
|
5
|
+
references: Reference<T>[] | []
|
|
6
|
+
apiRefItemKind?: "secondary"
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface AtlasProps {
|
|
10
|
+
references: Reference<any>[]
|
|
11
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {css} from "@linaria/core";
|
|
2
|
+
|
|
3
|
+
export const CodeSampleButtonsHost = css`
|
|
4
|
+
position: relative;
|
|
5
|
+
max-width: 100%;
|
|
6
|
+
`;
|
|
7
|
+
|
|
8
|
+
export const CodeSampleButtonsContainer = css`
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
width: 100%;
|
|
11
|
+
align-items: center;
|
|
12
|
+
border-radius: 8px;
|
|
13
|
+
background-color: var(--XydAtlas-Component-Code-SampleButtons__color-containerBackground);
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
export const CodeSampleButtonsArrowHost = css`
|
|
17
|
+
padding: 8px;
|
|
18
|
+
background-color: var(--white, #ffffff);
|
|
19
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
export const CodeSampleButtonsArrowIcon = css`
|
|
23
|
+
width: 16px;
|
|
24
|
+
height: 16px;
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
export const CodeSampleButtonsScrollerHost = css`
|
|
28
|
+
overflow-x: auto;
|
|
29
|
+
flex-grow: 1;
|
|
30
|
+
font-weight: var(--xyd-font-weight-semibold);
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
export const CodeSampleButtonsScrollerContainer = css`
|
|
34
|
+
display: inline-flex;
|
|
35
|
+
gap: 4px;
|
|
36
|
+
padding: 4px;
|
|
37
|
+
margin-left: 4px;
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
export const CodeSampleButtonsButtonHost = css`
|
|
41
|
+
padding: 4px 16px;
|
|
42
|
+
border-radius: 0.375rem;
|
|
43
|
+
white-space: nowrap;
|
|
44
|
+
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
|
45
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
46
|
+
transition-duration: 300ms;
|
|
47
|
+
color: var(--XydAtlas-Component-Code-SampleButtons__color);
|
|
48
|
+
|
|
49
|
+
&:hover {
|
|
50
|
+
color: var(--XydAtlas-Component-Code-SampleButtons__color--active);
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
export const CodeSampleButtonsButtonActive = css`
|
|
55
|
+
color: var(--XydAtlas-Component-Code-SampleButtons__color--active);
|
|
56
|
+
background-color: var(--XydAtlas-Component-Code-SampleButtons__color-background--active);
|
|
57
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
58
|
+
`;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import React, {useState, useRef, useEffect} from 'react'
|
|
2
|
+
import {ChevronLeft, ChevronRight} from "lucide-react"
|
|
3
|
+
|
|
4
|
+
import {Example} from "@xyd-js/uniform";
|
|
5
|
+
|
|
6
|
+
import * as cn from "./CodeSampleButtons.styles";
|
|
7
|
+
|
|
8
|
+
export interface CodeExampleButtonsProps {
|
|
9
|
+
examples: Example[]
|
|
10
|
+
activeExample: Example | null
|
|
11
|
+
onClick: (example: Example) => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function CodeExampleButtons({examples, activeExample, onClick}: CodeExampleButtonsProps) {
|
|
15
|
+
const [showLeftArrow, setShowLeftArrow] = useState(false)
|
|
16
|
+
const [showRightArrow, setShowRightArrow] = useState(false)
|
|
17
|
+
const scrollContainerRef = useRef<HTMLDivElement>(null)
|
|
18
|
+
|
|
19
|
+
const handleScroll = () => {
|
|
20
|
+
if (scrollContainerRef.current) {
|
|
21
|
+
const {scrollLeft, scrollWidth, clientWidth} = scrollContainerRef.current
|
|
22
|
+
setShowLeftArrow(scrollLeft > 0)
|
|
23
|
+
setShowRightArrow(scrollLeft < scrollWidth - clientWidth)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
handleScroll()
|
|
29
|
+
window.addEventListener('resize', handleScroll)
|
|
30
|
+
return () => window.removeEventListener('resize', handleScroll)
|
|
31
|
+
}, [])
|
|
32
|
+
|
|
33
|
+
const scroll = (direction: 'left' | 'right') => {
|
|
34
|
+
if (scrollContainerRef.current) {
|
|
35
|
+
const scrollAmount = direction === 'left' ? -200 : 200
|
|
36
|
+
scrollContainerRef.current.scrollBy({left: scrollAmount, behavior: 'smooth'})
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div className={cn.CodeSampleButtonsHost}>
|
|
42
|
+
<div className={cn.CodeSampleButtonsContainer}>
|
|
43
|
+
{showLeftArrow && (
|
|
44
|
+
<button
|
|
45
|
+
onClick={() => scroll('left')}
|
|
46
|
+
className={cn.CodeSampleButtonsArrowHost}
|
|
47
|
+
>
|
|
48
|
+
<ChevronLeft className={cn.CodeSampleButtonsArrowIcon}/>
|
|
49
|
+
</button>
|
|
50
|
+
)}
|
|
51
|
+
<div
|
|
52
|
+
ref={scrollContainerRef}
|
|
53
|
+
onScroll={handleScroll}
|
|
54
|
+
className={cn.CodeSampleButtonsScrollerHost}
|
|
55
|
+
>
|
|
56
|
+
<div className={cn.CodeSampleButtonsScrollerContainer}>
|
|
57
|
+
{examples?.map((example) => (
|
|
58
|
+
<SampleButton
|
|
59
|
+
key={example.codeblock.title}
|
|
60
|
+
onClick={() => onClick(example)}
|
|
61
|
+
example={example}
|
|
62
|
+
activeExample={activeExample}
|
|
63
|
+
>
|
|
64
|
+
{(example.codeblock.title || null)}
|
|
65
|
+
</SampleButton>
|
|
66
|
+
))}
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
{showRightArrow && (
|
|
70
|
+
<button
|
|
71
|
+
onClick={() => scroll('right')}
|
|
72
|
+
className={cn.CodeSampleButtonsArrowHost}
|
|
73
|
+
>
|
|
74
|
+
<ChevronRight className={cn.CodeSampleButtonsArrowIcon}/>
|
|
75
|
+
</button>
|
|
76
|
+
)}
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function SampleButton({onClick, children, activeExample, example}: {
|
|
83
|
+
onClick: () => void,
|
|
84
|
+
children: React.ReactNode,
|
|
85
|
+
example: Example,
|
|
86
|
+
activeExample: Example | null,
|
|
87
|
+
}) {
|
|
88
|
+
const markExampleAsActive = (activeExample?.description && activeExample?.description === example?.description) ||
|
|
89
|
+
(activeExample?.codeblock?.title && activeExample?.codeblock?.title === example.codeblock.title)
|
|
90
|
+
|
|
91
|
+
return <button
|
|
92
|
+
onClick={onClick}
|
|
93
|
+
className={`${cn.CodeSampleButtonsButtonHost} ${markExampleAsActive && cn.CodeSampleButtonsButtonActive}`}
|
|
94
|
+
>
|
|
95
|
+
{children}
|
|
96
|
+
</button>
|
|
97
|
+
}
|