@sakura-ui/sakura-ui 0.2.0 → 0.3.0
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/README.md +16 -6
- package/package.json +21 -15
- package/packages/core/package.json +26 -15
- package/packages/core/src/components/Button.tsx +33 -32
- package/packages/core/src/components/Card.tsx +29 -17
- package/packages/core/src/components/Code.tsx +6 -4
- package/packages/core/src/components/Faq.tsx +13 -7
- package/packages/core/src/components/Heading.tsx +42 -32
- package/packages/core/src/components/Icon.tsx +43 -13
- package/packages/core/src/components/IconButton.tsx +54 -43
- package/packages/core/src/components/LangSelector.tsx +135 -0
- package/packages/core/src/components/Link.tsx +38 -66
- package/packages/core/src/components/LinkCard.tsx +91 -0
- package/packages/core/src/components/List.tsx +14 -12
- package/packages/core/src/components/MenuButton.tsx +112 -0
- package/packages/core/src/components/NavigationItem.tsx +41 -0
- package/packages/core/src/components/OverflowContainer.tsx +24 -0
- package/packages/core/src/components/PopoverMenu.tsx +81 -0
- package/packages/core/src/components/Pre.tsx +6 -4
- package/packages/core/src/components/Table.tsx +31 -25
- package/packages/core/src/components/buttonStyle.ts +42 -31
- package/packages/core/src/components/index.ts +13 -25
- package/packages/core/src/icons/Close.tsx +21 -0
- package/packages/core/src/icons/CloseMobile.tsx +43 -0
- package/packages/core/src/icons/KeyboardArrowDown.tsx +24 -0
- package/packages/core/src/icons/Language.tsx +25 -0
- package/packages/core/src/icons/LanguageMobile.tsx +40 -0
- package/packages/core/src/icons/Menu.tsx +24 -0
- package/packages/core/src/icons/MenuMobile.tsx +40 -0
- package/packages/core/src/icons/index.ts +8 -0
- package/packages/core/src/icons/props.ts +5 -0
- package/packages/core/src/index.ts +9 -28
- package/packages/core/src/type.d.ts +1 -0
- package/packages/core/tests/Button.test.tsx +20 -10
- package/packages/core/tests/Card.test.tsx +16 -11
- package/packages/core/tests/IconButton.test.tsx +57 -0
- package/packages/core/tests/Link.test.tsx +60 -0
- package/packages/core/tests/vitest.setup.ts +1 -0
- package/packages/core/tsconfig.node.json +3 -2
- package/packages/forms/.turbo/turbo-build.log +22 -0
- package/packages/forms/dist/index.cjs.js +199 -120
- package/packages/forms/dist/index.es.js +890 -1023
- package/packages/forms/dist/types/components/Checkbox.d.ts +9 -4
- package/packages/forms/dist/types/components/Checkbox.d.ts.map +1 -1
- package/packages/forms/dist/types/components/FieldsetControl.d.ts +14 -9
- package/packages/forms/dist/types/components/FieldsetControl.d.ts.map +1 -1
- package/packages/forms/dist/types/components/FileInput.d.ts +10 -3
- package/packages/forms/dist/types/components/FileInput.d.ts.map +1 -1
- package/packages/forms/dist/types/components/Input.d.ts +9 -4
- package/packages/forms/dist/types/components/Input.d.ts.map +1 -1
- package/packages/forms/dist/types/components/LabelControl.d.ts +13 -8
- package/packages/forms/dist/types/components/LabelControl.d.ts.map +1 -1
- package/packages/forms/dist/types/components/Radio.d.ts +9 -4
- package/packages/forms/dist/types/components/Radio.d.ts.map +1 -1
- package/packages/forms/dist/types/components/Select.d.ts +9 -4
- package/packages/forms/dist/types/components/Select.d.ts.map +1 -1
- package/packages/forms/dist/types/components/Textarea.d.ts +8 -3
- package/packages/forms/dist/types/components/Textarea.d.ts.map +1 -1
- package/packages/forms/dist/types/components/controlled/CheckboxGroup.d.ts +16 -11
- package/packages/forms/dist/types/components/controlled/CheckboxGroup.d.ts.map +1 -1
- package/packages/forms/dist/types/components/controlled/RadioGroup.d.ts +17 -12
- package/packages/forms/dist/types/components/controlled/RadioGroup.d.ts.map +1 -1
- package/packages/forms/dist/types/components/index.d.ts +8 -8
- package/packages/forms/dist/types/components/index.d.ts.map +1 -1
- package/packages/forms/dist/types/components/inputStyle.d.ts +1 -1
- package/packages/forms/dist/types/components/inputStyle.d.ts.map +1 -1
- package/packages/forms/dist/types/index.d.ts +0 -1
- package/packages/forms/dist/types/index.d.ts.map +1 -1
- package/packages/forms/node_modules/.bin/autoprefixer +2 -2
- package/packages/forms/node_modules/.bin/tailwind +2 -2
- package/packages/forms/node_modules/.bin/tailwindcss +2 -2
- package/packages/forms/node_modules/.bin/ts-node +4 -4
- package/packages/forms/node_modules/.bin/ts-node-cwd +4 -4
- package/packages/forms/node_modules/.bin/ts-node-esm +4 -4
- package/packages/forms/node_modules/.bin/ts-node-script +4 -4
- package/packages/forms/node_modules/.bin/ts-node-transpile-only +4 -4
- package/packages/forms/node_modules/.bin/ts-script +4 -4
- package/packages/forms/node_modules/.bin/tsc +17 -0
- package/packages/forms/node_modules/.bin/tsserver +17 -0
- package/packages/forms/node_modules/.vite/vitest/results.json +1 -0
- package/packages/forms/package.json +17 -14
- package/packages/forms/src/components/Checkbox.tsx +76 -80
- package/packages/forms/src/components/FieldsetControl.tsx +21 -28
- package/packages/forms/src/components/FileInput.tsx +87 -63
- package/packages/forms/src/components/Input.tsx +29 -31
- package/packages/forms/src/components/LabelControl.tsx +19 -25
- package/packages/forms/src/components/Radio.tsx +66 -69
- package/packages/forms/src/components/Select.tsx +65 -65
- package/packages/forms/src/components/Textarea.tsx +49 -54
- package/packages/forms/src/components/controlled/CheckboxGroup.tsx +15 -17
- package/packages/forms/src/components/controlled/RadioGroup.tsx +16 -18
- package/packages/forms/src/components/index.ts +8 -8
- package/packages/forms/src/components/inputStyle.ts +7 -8
- package/packages/forms/src/index.ts +0 -11
- package/packages/forms/tests/Checkbox.test.tsx +44 -0
- package/packages/forms/tests/FieldsetControl.test.tsx +62 -11
- package/packages/forms/tests/FileInput.test.tsx +25 -0
- package/packages/forms/tests/Input.test.tsx +12 -83
- package/packages/forms/tests/LabelControl.test.tsx +82 -20
- package/packages/forms/tests/Radio.test.tsx +23 -78
- package/packages/forms/tests/Select.test.tsx +30 -0
- package/packages/forms/tests/Textarea.test.tsx +25 -0
- package/packages/forms/tests/vitest.setup.ts +1 -0
- package/packages/forms/tsconfig.node.json +3 -2
- package/packages/helper/.turbo/turbo-build.log +23 -0
- package/packages/helper/dist/index.cjs.js +78 -0
- package/packages/helper/dist/index.es.js +119 -0
- package/packages/helper/dist/types/calc.d.ts +2 -0
- package/packages/helper/dist/types/calc.d.ts.map +1 -0
- package/packages/{forms/dist/types/utils/class.d.ts → helper/dist/types/cx.d.ts} +1 -1
- package/packages/helper/dist/types/cx.d.ts.map +1 -0
- package/packages/helper/dist/types/index.d.ts +6 -0
- package/packages/helper/dist/types/index.d.ts.map +1 -0
- package/packages/helper/dist/types/querySelector.d.ts +2 -0
- package/packages/helper/dist/types/querySelector.d.ts.map +1 -0
- package/packages/helper/dist/types/styles.d.ts +22 -0
- package/packages/helper/dist/types/styles.d.ts.map +1 -0
- package/packages/helper/dist/types/treefy.d.ts +8 -0
- package/packages/helper/dist/types/treefy.d.ts.map +1 -0
- package/packages/helper/package.json +40 -0
- package/packages/helper/src/calc.ts +1 -0
- package/packages/helper/src/index.ts +5 -0
- package/packages/helper/src/querySelector.ts +20 -0
- package/packages/helper/src/styles.ts +116 -0
- package/packages/helper/src/treefy.ts +22 -0
- package/packages/helper/tsconfig.json +13 -0
- package/packages/helper/tsconfig.node.json +6 -0
- package/packages/helper/vite.config.ts +26 -0
- package/packages/markdown/.turbo/turbo-build.log +22 -0
- package/packages/markdown/README.md +129 -0
- package/packages/markdown/dist/index.cjs.js +175 -0
- package/packages/markdown/dist/index.es.js +17098 -0
- package/packages/markdown/dist/types/components/Markdown.d.ts +15 -0
- package/packages/markdown/dist/types/components/Markdown.d.ts.map +1 -0
- package/packages/markdown/dist/types/components/index.d.ts +2 -0
- package/packages/markdown/dist/types/components/index.d.ts.map +1 -0
- package/packages/markdown/dist/types/index.d.ts +2 -0
- package/packages/markdown/dist/types/index.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/attr.d.ts +3 -0
- package/packages/markdown/dist/types/plugins/attr.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/card.d.ts +3 -0
- package/packages/markdown/dist/types/plugins/card.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/cell.d.ts +3 -0
- package/packages/markdown/dist/types/plugins/cell.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/faq.d.ts +3 -0
- package/packages/markdown/dist/types/plugins/faq.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/grid.d.ts +3 -0
- package/packages/markdown/dist/types/plugins/grid.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/headings.d.ts +9 -0
- package/packages/markdown/dist/types/plugins/headings.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/helper.d.ts +9 -0
- package/packages/markdown/dist/types/plugins/helper.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/index.d.ts +9 -0
- package/packages/markdown/dist/types/plugins/index.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/linkButton.d.ts +3 -0
- package/packages/markdown/dist/types/plugins/linkButton.d.ts.map +1 -0
- package/packages/markdown/dist/types/plugins/youtube.d.ts +3 -0
- package/packages/markdown/dist/types/plugins/youtube.d.ts.map +1 -0
- package/packages/markdown/node_modules/.bin/autoprefixer +17 -0
- package/packages/markdown/node_modules/.bin/tailwind +17 -0
- package/packages/markdown/node_modules/.bin/tailwindcss +17 -0
- package/packages/markdown/node_modules/.bin/ts-node +17 -0
- package/packages/markdown/node_modules/.bin/ts-node-cwd +17 -0
- package/packages/markdown/node_modules/.bin/ts-node-esm +17 -0
- package/packages/markdown/node_modules/.bin/ts-node-script +17 -0
- package/packages/markdown/node_modules/.bin/ts-node-transpile-only +17 -0
- package/packages/markdown/node_modules/.bin/ts-script +17 -0
- package/packages/markdown/node_modules/.bin/tsc +17 -0
- package/packages/markdown/node_modules/.bin/tsserver +17 -0
- package/packages/markdown/package.json +83 -0
- package/packages/markdown/src/components/Markdown.tsx +361 -0
- package/packages/markdown/src/components/index.ts +1 -0
- package/packages/markdown/src/global.d.ts +9 -0
- package/packages/markdown/src/index.ts +1 -0
- package/packages/markdown/src/plugins/attr.ts +19 -0
- package/packages/markdown/src/plugins/card.ts +57 -0
- package/packages/markdown/src/plugins/cell.ts +47 -0
- package/packages/markdown/src/plugins/faq.ts +40 -0
- package/packages/markdown/src/plugins/grid.ts +51 -0
- package/packages/markdown/src/plugins/headings.ts +35 -0
- package/packages/markdown/src/plugins/helper.ts +27 -0
- package/packages/markdown/src/plugins/index.ts +8 -0
- package/packages/markdown/src/plugins/linkButton.ts +25 -0
- package/packages/markdown/src/plugins/youtube.ts +48 -0
- package/packages/markdown/tsconfig.json +13 -0
- package/packages/markdown/tsconfig.node.json +7 -0
- package/packages/markdown/vite.config.ts +30 -0
- package/packages/tailwind-theme-plugin/.turbo/turbo-build.log +22 -0
- package/packages/tailwind-theme-plugin/dist/index.cjs.js +1 -1
- package/packages/tailwind-theme-plugin/dist/index.es.js +5354 -6111
- package/packages/tailwind-theme-plugin/dist/types/index.d.ts +1 -1
- package/packages/tailwind-theme-plugin/dist/types/index.d.ts.map +1 -1
- package/packages/tailwind-theme-plugin/node_modules/.bin/autoprefixer +2 -2
- package/packages/tailwind-theme-plugin/node_modules/.bin/tailwind +2 -2
- package/packages/tailwind-theme-plugin/node_modules/.bin/tailwindcss +2 -2
- package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node +4 -4
- package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node-cwd +4 -4
- package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node-esm +4 -4
- package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node-script +4 -4
- package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node-transpile-only +4 -4
- package/packages/tailwind-theme-plugin/node_modules/.bin/ts-script +4 -4
- package/packages/tailwind-theme-plugin/node_modules/.bin/tsc +17 -0
- package/packages/tailwind-theme-plugin/node_modules/.bin/tsserver +17 -0
- package/packages/tailwind-theme-plugin/package.json +6 -6
- package/packages/tailwind-theme-plugin/src/index.ts +226 -291
- package/packages/core/src/libs/forward-ref.ts +0 -44
- package/packages/core/src/types/component.ts +0 -83
- package/packages/forms/dist/types/utils/class.d.ts.map +0 -1
- package/packages/forms/node_modules/.bin/acorn +0 -17
- package/packages/forms/node_modules/.bin/browserslist +0 -17
- package/packages/forms/node_modules/.bin/eslint +0 -17
- package/packages/forms/node_modules/.bin/vitest +0 -17
- package/packages/forms/src/utils/class.ts +0 -2
- package/packages/tailwind-theme-plugin/node_modules/.bin/browserslist +0 -17
- /package/packages/{core/src/libs → helper/src}/cx.ts +0 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import React, { Children } from 'react'
|
|
2
|
+
import * as production from 'react/jsx-runtime'
|
|
3
|
+
import { remark } from 'remark'
|
|
4
|
+
import { unified } from 'unified'
|
|
5
|
+
import remarkParse from 'remark-parse'
|
|
6
|
+
import remarkGfm from 'remark-gfm'
|
|
7
|
+
import remarkDirective from 'remark-directive'
|
|
8
|
+
import remarkRehype from 'remark-rehype'
|
|
9
|
+
import remarkBreaks from 'remark-breaks'
|
|
10
|
+
import rehypeRaw from 'rehype-raw'
|
|
11
|
+
import rehypeExternalLinks from 'rehype-external-links'
|
|
12
|
+
import rebypeShiftHeding from 'rehype-shift-heading'
|
|
13
|
+
import rehypeReact from 'rehype-react'
|
|
14
|
+
import rehypeSlug from 'rehype-slug'
|
|
15
|
+
import { cx } from '@sakura-ui/helper'
|
|
16
|
+
import {
|
|
17
|
+
Link,
|
|
18
|
+
H1,
|
|
19
|
+
H2,
|
|
20
|
+
H3,
|
|
21
|
+
H4,
|
|
22
|
+
H5,
|
|
23
|
+
H6,
|
|
24
|
+
Table,
|
|
25
|
+
Caption,
|
|
26
|
+
Thead,
|
|
27
|
+
Tbody,
|
|
28
|
+
Th,
|
|
29
|
+
Tr,
|
|
30
|
+
Td,
|
|
31
|
+
Ul,
|
|
32
|
+
Ol,
|
|
33
|
+
Pre,
|
|
34
|
+
Code,
|
|
35
|
+
Faq,
|
|
36
|
+
Question,
|
|
37
|
+
Answer,
|
|
38
|
+
Button,
|
|
39
|
+
Card,
|
|
40
|
+
CardImg,
|
|
41
|
+
CardBody,
|
|
42
|
+
CardFooter,
|
|
43
|
+
LinkCard,
|
|
44
|
+
LinkCardHeader,
|
|
45
|
+
OverflowContainer
|
|
46
|
+
} from '@sakura-ui/core'
|
|
47
|
+
import {
|
|
48
|
+
attrPlugin,
|
|
49
|
+
youtubePlugin,
|
|
50
|
+
linkButtonPlugin,
|
|
51
|
+
gridPlugin,
|
|
52
|
+
cellPlugin,
|
|
53
|
+
cardPlugin,
|
|
54
|
+
faqPlugin,
|
|
55
|
+
headingsPlugin,
|
|
56
|
+
type HeadingItem
|
|
57
|
+
} from '../plugins'
|
|
58
|
+
|
|
59
|
+
interface TocProps {
|
|
60
|
+
items: HeadingItem[]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const TableOfContents = ({ items }: TocProps) => {
|
|
64
|
+
return (
|
|
65
|
+
<>
|
|
66
|
+
{items.map((item) => {
|
|
67
|
+
return (
|
|
68
|
+
<li key={item.id}>
|
|
69
|
+
<Link href={`#${item.id}`}>{item.value}</Link>
|
|
70
|
+
{item.children ? (
|
|
71
|
+
<Ul>{<TableOfContents items={item.children} />}</Ul>
|
|
72
|
+
) : null}
|
|
73
|
+
</li>
|
|
74
|
+
)
|
|
75
|
+
})}
|
|
76
|
+
</>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
interface TableContainerProps extends React.ComponentPropsWithoutRef<'table'> {}
|
|
81
|
+
|
|
82
|
+
const TableContainer = (props: TableContainerProps) => {
|
|
83
|
+
const { className, children, ...restProps } = props
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<OverflowContainer>
|
|
87
|
+
<Table className={cx(className)} {...restProps}>
|
|
88
|
+
{children}
|
|
89
|
+
</Table>
|
|
90
|
+
</OverflowContainer>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
interface DataProps {
|
|
95
|
+
[key: `data-${string}`]: unknown
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface AnchorProps extends React.ComponentPropsWithoutRef<'a'>, DataProps {}
|
|
99
|
+
|
|
100
|
+
const Anchor = (props: AnchorProps) => {
|
|
101
|
+
const { children, href, ...restProps } = props
|
|
102
|
+
|
|
103
|
+
if (restProps['data-node'] === 'link-button') {
|
|
104
|
+
return (
|
|
105
|
+
<Button as="a" variant="secondary" href={href}>
|
|
106
|
+
{children}
|
|
107
|
+
</Button>
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<Link href={href} {...restProps}>
|
|
113
|
+
{children}
|
|
114
|
+
</Link>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface ArticleProps
|
|
119
|
+
extends React.ComponentPropsWithoutRef<'article'>,
|
|
120
|
+
DataProps {}
|
|
121
|
+
|
|
122
|
+
const Article = (props: ArticleProps) => {
|
|
123
|
+
const { children, className, ...restProps } = props
|
|
124
|
+
|
|
125
|
+
const node = restProps['data-node']
|
|
126
|
+
|
|
127
|
+
if (node === 'card') {
|
|
128
|
+
if (restProps['data-behavior'] === 'link') {
|
|
129
|
+
const href = restProps['data-href'] as string
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<LinkCard href={href} className={cx(className)}>
|
|
133
|
+
{children}
|
|
134
|
+
</LinkCard>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
return <Card className={cx(className)}>{children}</Card>
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<article className={className} {...restProps}>
|
|
142
|
+
{children}
|
|
143
|
+
</article>
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
interface DivProps extends React.ComponentPropsWithoutRef<'div'>, DataProps {}
|
|
148
|
+
|
|
149
|
+
const Div = (props: DivProps) => {
|
|
150
|
+
const { children, ...restProps } = props
|
|
151
|
+
|
|
152
|
+
const node = restProps['data-node']
|
|
153
|
+
|
|
154
|
+
if (node === 'card-title') {
|
|
155
|
+
return <LinkCardHeader>{children}</LinkCardHeader>
|
|
156
|
+
}
|
|
157
|
+
if (node === 'card-description') {
|
|
158
|
+
return <CardBody>{children}</CardBody>
|
|
159
|
+
}
|
|
160
|
+
if (node === 'card-footer') {
|
|
161
|
+
return <CardFooter>{children}</CardFooter>
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (restProps['data-behavior'] === 'list') {
|
|
165
|
+
// Set the css class configured for cells to the ul tag
|
|
166
|
+
return (
|
|
167
|
+
<ul className={restProps.className}>
|
|
168
|
+
{Children.map(children, (child) => (
|
|
169
|
+
<li className="sm:grid" key={Math.random()}>
|
|
170
|
+
{child}
|
|
171
|
+
</li>
|
|
172
|
+
))}
|
|
173
|
+
</ul>
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return <div {...restProps}>{children}</div>
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
interface ImgProps extends React.ComponentPropsWithoutRef<'img'>, DataProps {}
|
|
181
|
+
|
|
182
|
+
const Img = (props: ImgProps) => {
|
|
183
|
+
const { children, className, ...restProps } = props
|
|
184
|
+
|
|
185
|
+
if (restProps['data-node'] === 'card-img') {
|
|
186
|
+
return (
|
|
187
|
+
<CardImg
|
|
188
|
+
className={cx('w-full aspect-[352/226]', className)}
|
|
189
|
+
{...restProps}
|
|
190
|
+
/>
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (restProps['data-node'] === 'cell-img') {
|
|
195
|
+
return <img className={cx('mb-4', className)} {...restProps} />
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return <img className={className} {...restProps} />
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
interface IframeProps extends React.ComponentPropsWithoutRef<'iframe'> {}
|
|
202
|
+
|
|
203
|
+
const Iframe = (props: IframeProps) => {
|
|
204
|
+
const { className, children, ...restProps } = props
|
|
205
|
+
|
|
206
|
+
const styleMargin = `
|
|
207
|
+
my-8
|
|
208
|
+
`
|
|
209
|
+
|
|
210
|
+
let style = `
|
|
211
|
+
aspect-video
|
|
212
|
+
w-full
|
|
213
|
+
max-w-[470px]
|
|
214
|
+
`
|
|
215
|
+
|
|
216
|
+
if (props.width || props.height) {
|
|
217
|
+
style = `
|
|
218
|
+
aspect-video
|
|
219
|
+
w-full
|
|
220
|
+
lg:aspect-auto
|
|
221
|
+
lg:w-[${props.width}px]
|
|
222
|
+
lg:h-[${props.height}px]
|
|
223
|
+
`
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return (
|
|
227
|
+
<iframe className={cx(styleMargin, style, className)} {...restProps}>
|
|
228
|
+
{children}
|
|
229
|
+
</iframe>
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const sleep = (time: number) =>
|
|
234
|
+
new Promise((resolve) => setTimeout(resolve, time))
|
|
235
|
+
|
|
236
|
+
type Props = {
|
|
237
|
+
tocTitle?: string
|
|
238
|
+
showToc?: boolean
|
|
239
|
+
shiftHeding?: number
|
|
240
|
+
children: string
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export const Markdown = ({
|
|
244
|
+
children,
|
|
245
|
+
showToc,
|
|
246
|
+
tocTitle = '目次',
|
|
247
|
+
shiftHeding = 0
|
|
248
|
+
}: Props) => {
|
|
249
|
+
const [toc, setToc] = React.useState<HeadingItem[]>([])
|
|
250
|
+
const [element, setElement] = React.useState(<React.Fragment />)
|
|
251
|
+
|
|
252
|
+
const markdown2Headings = React.useCallback((md: string) => {
|
|
253
|
+
const result: any = remark().use(headingsPlugin).processSync(md)
|
|
254
|
+
|
|
255
|
+
const headings: HeadingItem[] = result.data.fm.headings.filter(
|
|
256
|
+
(obj: HeadingItem) => obj.depth < 3
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
return headings
|
|
260
|
+
}, [])
|
|
261
|
+
|
|
262
|
+
const markdown2ReactElements = React.useCallback(
|
|
263
|
+
(md: string) => {
|
|
264
|
+
const rhypeReactOptions = {
|
|
265
|
+
...production,
|
|
266
|
+
components: {
|
|
267
|
+
a: Anchor,
|
|
268
|
+
article: Article,
|
|
269
|
+
button: Button,
|
|
270
|
+
code: Code,
|
|
271
|
+
dl: Faq,
|
|
272
|
+
dt: Question,
|
|
273
|
+
dd: Answer,
|
|
274
|
+
h1: H1,
|
|
275
|
+
h2: H2,
|
|
276
|
+
h3: H3,
|
|
277
|
+
h4: H4,
|
|
278
|
+
h5: H5,
|
|
279
|
+
h6: H6,
|
|
280
|
+
iframe: Iframe,
|
|
281
|
+
img: Img,
|
|
282
|
+
ul: Ul,
|
|
283
|
+
ol: Ol,
|
|
284
|
+
pre: Pre,
|
|
285
|
+
table: TableContainer,
|
|
286
|
+
caption: Caption,
|
|
287
|
+
thead: Thead,
|
|
288
|
+
tbody: Tbody,
|
|
289
|
+
th: Th,
|
|
290
|
+
tr: Tr,
|
|
291
|
+
td: Td,
|
|
292
|
+
div: Div
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const elem = unified()
|
|
297
|
+
.use(remarkParse) // md -> mdast (Markdown Abstract Syntax Tree)
|
|
298
|
+
.use(remarkGfm) // mdast -> GFM mdast (GitHub Flavored Markdown Abstract Syntax Tree)
|
|
299
|
+
.use(remarkDirective) // support for directive syntax
|
|
300
|
+
.use(remarkBreaks)
|
|
301
|
+
.use(attrPlugin)
|
|
302
|
+
.use(youtubePlugin)
|
|
303
|
+
.use(linkButtonPlugin)
|
|
304
|
+
.use(cellPlugin)
|
|
305
|
+
.use(cardPlugin)
|
|
306
|
+
.use(faqPlugin)
|
|
307
|
+
.use(gridPlugin)
|
|
308
|
+
.use(remarkRehype, {
|
|
309
|
+
allowDangerousHtml: true
|
|
310
|
+
}) // mdast -> hast (HTML Abstract Syntax Tree)
|
|
311
|
+
.use(rehypeRaw) // hast -> hast
|
|
312
|
+
.use(rehypeExternalLinks, { target: '_blank' }) // hast -> hast
|
|
313
|
+
.use(rebypeShiftHeding, { shift: shiftHeding }) // hast -> hast
|
|
314
|
+
.use(rehypeSlug)
|
|
315
|
+
.use(rehypeReact, rhypeReactOptions as any) // hast -> React Elements
|
|
316
|
+
.processSync(md).result
|
|
317
|
+
return elem
|
|
318
|
+
},
|
|
319
|
+
[shiftHeding]
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
React.useEffect(() => {
|
|
323
|
+
setToc(markdown2Headings(children))
|
|
324
|
+
setElement(markdown2ReactElements(children))
|
|
325
|
+
}, [children, markdown2Headings, markdown2ReactElements])
|
|
326
|
+
|
|
327
|
+
React.useEffect(() => {
|
|
328
|
+
// Necessary to make in-page links work.
|
|
329
|
+
const scrollToHash = async () => {
|
|
330
|
+
await sleep(500)
|
|
331
|
+
if (location.hash) {
|
|
332
|
+
document
|
|
333
|
+
.getElementById(decodeURI(location.hash.substring(1)))
|
|
334
|
+
?.scrollIntoView()
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
scrollToHash()
|
|
338
|
+
}, [])
|
|
339
|
+
|
|
340
|
+
const style = `
|
|
341
|
+
rounded-3xl
|
|
342
|
+
p-10
|
|
343
|
+
bg-yellow-50
|
|
344
|
+
`
|
|
345
|
+
|
|
346
|
+
return (
|
|
347
|
+
<div className="py-8 flex flex-col gap-8">
|
|
348
|
+
{showToc && (
|
|
349
|
+
<nav className={style}>
|
|
350
|
+
<h2 className="mb-4 font-bold text-h-xs-m sm:text-h-xs">
|
|
351
|
+
{tocTitle}
|
|
352
|
+
</h2>
|
|
353
|
+
<Ul>
|
|
354
|
+
<TableOfContents items={toc} />
|
|
355
|
+
</Ul>
|
|
356
|
+
</nav>
|
|
357
|
+
)}
|
|
358
|
+
{element}
|
|
359
|
+
</div>
|
|
360
|
+
)
|
|
361
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Markdown } from './Markdown'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Markdown } from './components'
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Root } from 'mdast'
|
|
2
|
+
import { h } from 'hastscript'
|
|
3
|
+
import { visit } from 'unist-util-visit'
|
|
4
|
+
import type { Directives } from 'mdast-util-directive'
|
|
5
|
+
import { isDirective } from './helper'
|
|
6
|
+
|
|
7
|
+
// This plugin is an example to turn `::node` into divs, passing arbitrary
|
|
8
|
+
// attributes.
|
|
9
|
+
export const attrPlugin = () => {
|
|
10
|
+
return (tree: Root) => {
|
|
11
|
+
visit(tree, isDirective, (node: Directives) => {
|
|
12
|
+
node.data = node.data ?? {}
|
|
13
|
+
const hast = h(node.name, node.attributes || {})
|
|
14
|
+
|
|
15
|
+
node.data.hName = hast.tagName
|
|
16
|
+
node.data.hProperties = hast.properties
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Root } from 'mdast'
|
|
2
|
+
import { h } from 'hastscript'
|
|
3
|
+
import { visit } from 'unist-util-visit'
|
|
4
|
+
import type { Directives } from 'mdast-util-directive'
|
|
5
|
+
import { isDirective } from './helper'
|
|
6
|
+
|
|
7
|
+
// This plugin is to turn `:::card` into divs, passing arbitrary
|
|
8
|
+
// attributes.
|
|
9
|
+
export const cardPlugin = () => {
|
|
10
|
+
return (tree: Root) => {
|
|
11
|
+
visit(tree, isDirective, (node: Directives) => {
|
|
12
|
+
if (node.type !== 'containerDirective') {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
if (node.name !== 'card') {
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
node.data = node.data ?? {}
|
|
20
|
+
|
|
21
|
+
const tagName = 'article'
|
|
22
|
+
|
|
23
|
+
node.data.hName = tagName
|
|
24
|
+
|
|
25
|
+
node.attributes = node.attributes ?? {}
|
|
26
|
+
node.attributes['data-node'] = node.name
|
|
27
|
+
|
|
28
|
+
if (node.attributes.as === 'link') {
|
|
29
|
+
node.attributes.as = undefined
|
|
30
|
+
node.attributes['data-behavior'] = 'link'
|
|
31
|
+
node.attributes['data-href'] = node.attributes.href || ''
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
node.data.hProperties = h(tagName, node.attributes).properties
|
|
35
|
+
|
|
36
|
+
node.children.forEach((child) => {
|
|
37
|
+
if (!isDirective(child)) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
child.data = child.data ?? {}
|
|
42
|
+
|
|
43
|
+
let tagName = 'div'
|
|
44
|
+
if (child.name === 'card-img') {
|
|
45
|
+
tagName = 'img'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
child.data.hName = tagName
|
|
49
|
+
|
|
50
|
+
child.attributes = child.attributes ?? {}
|
|
51
|
+
child.attributes['data-node'] = child.name
|
|
52
|
+
|
|
53
|
+
child.data.hProperties = h(tagName, child.attributes).properties
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Root } from 'mdast'
|
|
2
|
+
import { h } from 'hastscript'
|
|
3
|
+
import { visit } from 'unist-util-visit'
|
|
4
|
+
import type { Directives } from 'mdast-util-directive'
|
|
5
|
+
import { isContainerDirective, isDirective } from './helper'
|
|
6
|
+
|
|
7
|
+
// This plugin is to turn `:::cell` into divs, passing arbitrary
|
|
8
|
+
// attributes.
|
|
9
|
+
export const cellPlugin = () => {
|
|
10
|
+
return (tree: Root) => {
|
|
11
|
+
visit(tree, isContainerDirective, (node: Directives) => {
|
|
12
|
+
if (node.name !== 'cell') {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
node.data = node.data ?? {}
|
|
17
|
+
const tagName = 'div'
|
|
18
|
+
|
|
19
|
+
node.data.hName = tagName
|
|
20
|
+
|
|
21
|
+
node.attributes = node.attributes ?? {}
|
|
22
|
+
node.attributes['data-node'] = node.name
|
|
23
|
+
|
|
24
|
+
node.data.hProperties = h(tagName, node.attributes).properties
|
|
25
|
+
|
|
26
|
+
node.children.forEach((child) => {
|
|
27
|
+
if (!isDirective(child)) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
if (child.name !== 'cell-img') {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
child.data = child.data ?? {}
|
|
35
|
+
|
|
36
|
+
const tagName = 'img'
|
|
37
|
+
|
|
38
|
+
child.data.hName = tagName
|
|
39
|
+
|
|
40
|
+
child.attributes = child.attributes ?? {}
|
|
41
|
+
child.attributes['data-node'] = child.name
|
|
42
|
+
|
|
43
|
+
child.data.hProperties = h(tagName, child.attributes).properties
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Root } from 'mdast'
|
|
2
|
+
import { h } from 'hastscript'
|
|
3
|
+
import { visit } from 'unist-util-visit'
|
|
4
|
+
import type { Directives } from 'mdast-util-directive'
|
|
5
|
+
import { isContainerDirective, isDirective } from './helper'
|
|
6
|
+
|
|
7
|
+
// This plugin is to turn `::linkButton` into divs, passing arbitrary
|
|
8
|
+
// attributes.
|
|
9
|
+
export const faqPlugin = () => {
|
|
10
|
+
return (tree: Root) => {
|
|
11
|
+
visit(tree, isContainerDirective, (node: Directives) => {
|
|
12
|
+
if (node.name !== 'faq') {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
node.data = node.data ?? {}
|
|
17
|
+
const tagName = 'dl'
|
|
18
|
+
|
|
19
|
+
node.data.hName = tagName
|
|
20
|
+
|
|
21
|
+
node.data.hProperties = h(tagName, node.attributes || {}).properties
|
|
22
|
+
|
|
23
|
+
node.children.forEach((child) => {
|
|
24
|
+
if (!isDirective(child)) {
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
if (child.name !== 'faq-q' && child.name !== 'faq-a') {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
child.data = child.data ?? {}
|
|
32
|
+
const tagName = child.name === 'faq-q' ? 'dt' : 'dd'
|
|
33
|
+
|
|
34
|
+
child.data.hName = tagName
|
|
35
|
+
|
|
36
|
+
child.data.hProperties = h(tagName, child.attributes || {}).properties
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Root } from 'mdast'
|
|
2
|
+
import { h } from 'hastscript'
|
|
3
|
+
import { visit } from 'unist-util-visit'
|
|
4
|
+
import type { Directives } from 'mdast-util-directive'
|
|
5
|
+
import { isContainerDirective } from './helper'
|
|
6
|
+
|
|
7
|
+
// This plugin is to turn `::linkButton` into divs, passing arbitrary
|
|
8
|
+
// attributes.
|
|
9
|
+
export const gridPlugin = () => {
|
|
10
|
+
return (tree: Root) => {
|
|
11
|
+
visit(tree, isContainerDirective, (node: Directives) => {
|
|
12
|
+
if (!node.name.startsWith('grid-cols-')) {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
node.attributes = node.attributes ?? {}
|
|
17
|
+
|
|
18
|
+
if (node.attributes.as === 'list') {
|
|
19
|
+
node.attributes.as = undefined
|
|
20
|
+
node.attributes['data-behavior'] = 'list'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const gridNum: number = Number.parseInt(node.name.split('-').pop() || '1')
|
|
24
|
+
|
|
25
|
+
// Tailwind doesn't generate CSS for string interpolation
|
|
26
|
+
const gridClass: { [key: number]: string } = {
|
|
27
|
+
1: 'md:grid-cols-1',
|
|
28
|
+
2: 'md:grid-cols-2',
|
|
29
|
+
3: 'md:grid-cols-3',
|
|
30
|
+
4: 'md:grid-cols-4',
|
|
31
|
+
5: 'md:grid-cols-5',
|
|
32
|
+
6: 'md:grid-cols-6',
|
|
33
|
+
7: 'md:grid-cols-6',
|
|
34
|
+
8: 'md:grid-cols-6',
|
|
35
|
+
9: 'md:grid-cols-6',
|
|
36
|
+
10: 'md:grid-cols-6',
|
|
37
|
+
11: 'md:grid-cols-6',
|
|
38
|
+
12: 'md:grid-cols-12'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
node.data = node.data ?? {}
|
|
42
|
+
const tagName = 'div'
|
|
43
|
+
|
|
44
|
+
node.data.hName = tagName
|
|
45
|
+
|
|
46
|
+
node.attributes.class = `flex flex-col md:grid ${gridClass[gridNum]} gap-8`
|
|
47
|
+
|
|
48
|
+
node.data.hProperties = h(tagName, node.attributes).properties
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Heading, Root } from 'mdast'
|
|
2
|
+
import Slugger from 'github-slugger'
|
|
3
|
+
import { visit } from 'unist-util-visit'
|
|
4
|
+
import { toString as mdastToString } from 'mdast-util-to-string'
|
|
5
|
+
import { treefy } from '@sakura-ui/helper'
|
|
6
|
+
import { isHeading } from './helper'
|
|
7
|
+
|
|
8
|
+
export type HeadingItem = {
|
|
9
|
+
id?: string
|
|
10
|
+
depth: number
|
|
11
|
+
value?: string
|
|
12
|
+
children?: Array<HeadingItem>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const headingsPlugin = () => {
|
|
16
|
+
return (tree: Root, vFile: any) => {
|
|
17
|
+
const headings: Array<HeadingItem> = []
|
|
18
|
+
const slugger = new Slugger()
|
|
19
|
+
|
|
20
|
+
const getFlatHeadingsList = (node: Heading) => {
|
|
21
|
+
const h: HeadingItem = {
|
|
22
|
+
id: slugger.slug(mdastToString(node)),
|
|
23
|
+
depth: node.depth,
|
|
24
|
+
value: mdastToString(node)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
headings.push(h)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
visit(tree, isHeading, getFlatHeadingsList)
|
|
31
|
+
|
|
32
|
+
if (!vFile.data.fm) vFile.data.fm = {}
|
|
33
|
+
vFile.data.fm.headings = treefy(headings)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Directives } from 'mdast-util-directive'
|
|
2
|
+
import type { Node } from 'unist'
|
|
3
|
+
import type { Heading } from 'mdast'
|
|
4
|
+
|
|
5
|
+
export const isDirective = (node: Node): node is Directives => {
|
|
6
|
+
return (
|
|
7
|
+
node.type === 'containerDirective' ||
|
|
8
|
+
node.type === 'leafDirective' ||
|
|
9
|
+
node.type === 'textDirective'
|
|
10
|
+
)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const isContainerDirective = (node: Node): node is Directives => {
|
|
14
|
+
return node.type === 'containerDirective'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const isLeafDirective = (node: Node): node is Directives => {
|
|
18
|
+
return node.type === 'leafDirective'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const isTextDirective = (node: Node): node is Directives => {
|
|
22
|
+
return node.type === 'textDirective'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const isHeading = (node: Node): node is Heading => {
|
|
26
|
+
return node.type === 'heading'
|
|
27
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { youtubePlugin } from './youtube'
|
|
2
|
+
export { attrPlugin } from './attr'
|
|
3
|
+
export { linkButtonPlugin } from './linkButton'
|
|
4
|
+
export { gridPlugin } from './grid'
|
|
5
|
+
export { cellPlugin } from './cell'
|
|
6
|
+
export { cardPlugin } from './card'
|
|
7
|
+
export { faqPlugin } from './faq'
|
|
8
|
+
export { headingsPlugin, type HeadingItem } from './headings'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Root } from 'mdast'
|
|
2
|
+
import { h } from 'hastscript'
|
|
3
|
+
import { visit } from 'unist-util-visit'
|
|
4
|
+
import type { Directives } from 'mdast-util-directive'
|
|
5
|
+
import { isTextDirective } from './helper'
|
|
6
|
+
|
|
7
|
+
// This plugin is to turn `::linkButton` into divs, passing arbitrary
|
|
8
|
+
// attributes.
|
|
9
|
+
export const linkButtonPlugin = () => {
|
|
10
|
+
return (tree: Root) => {
|
|
11
|
+
visit(tree, isTextDirective, (node: Directives) => {
|
|
12
|
+
if (node.name !== 'link-button') return
|
|
13
|
+
|
|
14
|
+
const data = node.data || (node.data = {})
|
|
15
|
+
const tagName = 'a'
|
|
16
|
+
|
|
17
|
+
data.hName = tagName
|
|
18
|
+
|
|
19
|
+
node.attributes = node.attributes ?? {}
|
|
20
|
+
node.attributes['data-node'] = node.name
|
|
21
|
+
|
|
22
|
+
data.hProperties = h(tagName, node.attributes).properties
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|