@antv/dumi-theme-antv 0.1.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.
Files changed (111) hide show
  1. package/README.md +9 -0
  2. package/es/antv/404/index.js +20 -0
  3. package/es/antv/Banner/Banner.module.less +412 -0
  4. package/es/antv/Banner/Notification.js +44 -0
  5. package/es/antv/Banner/Notification.module.less +108 -0
  6. package/es/antv/Banner/index.js +115 -0
  7. package/es/antv/Cases/Cases.js +124 -0
  8. package/es/antv/Cases/Cases.module.less +203 -0
  9. package/es/antv/Features/FeatureCard.js +25 -0
  10. package/es/antv/Features/FeatureCard.module.less +51 -0
  11. package/es/antv/Features/Features.module.less +169 -0
  12. package/es/antv/Features/index.js +102 -0
  13. package/es/antv/Footer/Footer.module.less +36 -0
  14. package/es/antv/Footer/index.js +232 -0
  15. package/es/antv/Header/Logo.js +130 -0
  16. package/es/antv/Products/Product.js +61 -0
  17. package/es/antv/Products/Product.module.less +146 -0
  18. package/es/antv/Products/getNewProducts.js +41 -0
  19. package/es/antv/Products/getProducts.js +466 -0
  20. package/es/antv/Products/index.js +81 -0
  21. package/es/antv/hooks.js +81 -0
  22. package/es/antv/mixins.less +21 -0
  23. package/es/antv/utils.js +49 -0
  24. package/es/builtins/API.js +37 -0
  25. package/es/builtins/Alert.js +9 -0
  26. package/es/builtins/Alert.less +62 -0
  27. package/es/builtins/Badge.js +9 -0
  28. package/es/builtins/Badge.less +31 -0
  29. package/es/builtins/Example.js +48 -0
  30. package/es/builtins/Example.less +47 -0
  31. package/es/builtins/Previewer.js +225 -0
  32. package/es/builtins/Previewer.less +406 -0
  33. package/es/builtins/SourceCode.js +72 -0
  34. package/es/builtins/SourceCode.less +103 -0
  35. package/es/builtins/Table.js +56 -0
  36. package/es/builtins/Table.less +43 -0
  37. package/es/builtins/Tree.js +219 -0
  38. package/es/builtins/Tree.less +159 -0
  39. package/es/components/Dark.js +125 -0
  40. package/es/components/Dark.less +121 -0
  41. package/es/components/LocaleSelect.js +53 -0
  42. package/es/components/LocaleSelect.less +59 -0
  43. package/es/components/Navbar.js +155 -0
  44. package/es/components/Navbar.less +180 -0
  45. package/es/components/SearchBar.js +83 -0
  46. package/es/components/SearchBar.less +165 -0
  47. package/es/components/SideMenu.js +99 -0
  48. package/es/components/SideMenu.less +379 -0
  49. package/es/components/SlugList.js +33 -0
  50. package/es/components/SlugList.less +18 -0
  51. package/es/layout.js +276 -0
  52. package/es/style/layout.less +402 -0
  53. package/es/style/markdown.less +240 -0
  54. package/es/style/variables.less +37 -0
  55. package/package.json +58 -0
  56. package/src/antv/404/index.tsx +25 -0
  57. package/src/antv/Banner/Banner.module.less +412 -0
  58. package/src/antv/Banner/Notification.module.less +108 -0
  59. package/src/antv/Banner/Notification.tsx +45 -0
  60. package/src/antv/Banner/index.tsx +121 -0
  61. package/src/antv/Cases/Cases.module.less +203 -0
  62. package/src/antv/Cases/Cases.tsx +116 -0
  63. package/src/antv/Features/FeatureCard.module.less +51 -0
  64. package/src/antv/Features/FeatureCard.tsx +24 -0
  65. package/src/antv/Features/Features.module.less +169 -0
  66. package/src/antv/Features/index.tsx +86 -0
  67. package/src/antv/Footer/Footer.module.less +36 -0
  68. package/src/antv/Footer/index.tsx +272 -0
  69. package/src/antv/Header/Logo.tsx +85 -0
  70. package/src/antv/Products/Product.module.less +146 -0
  71. package/src/antv/Products/Product.tsx +80 -0
  72. package/src/antv/Products/getNewProducts.tsx +53 -0
  73. package/src/antv/Products/getProducts.tsx +626 -0
  74. package/src/antv/Products/index.tsx +70 -0
  75. package/src/antv/hooks.ts +87 -0
  76. package/src/antv/mixins.less +21 -0
  77. package/src/antv/utils.ts +44 -0
  78. package/src/builtins/API.tsx +57 -0
  79. package/src/builtins/Alert.less +62 -0
  80. package/src/builtins/Alert.tsx +4 -0
  81. package/src/builtins/Badge.less +31 -0
  82. package/src/builtins/Badge.tsx +4 -0
  83. package/src/builtins/Example.less +47 -0
  84. package/src/builtins/Example.tsx +34 -0
  85. package/src/builtins/Previewer.less +406 -0
  86. package/src/builtins/Previewer.tsx +264 -0
  87. package/src/builtins/SourceCode.less +103 -0
  88. package/src/builtins/SourceCode.tsx +55 -0
  89. package/src/builtins/Table.less +43 -0
  90. package/src/builtins/Table.tsx +42 -0
  91. package/src/builtins/Tree.less +159 -0
  92. package/src/builtins/Tree.tsx +130 -0
  93. package/src/components/Dark.less +121 -0
  94. package/src/components/Dark.tsx +78 -0
  95. package/src/components/LocaleSelect.less +59 -0
  96. package/src/components/LocaleSelect.tsx +53 -0
  97. package/src/components/Navbar.less +180 -0
  98. package/src/components/Navbar.tsx +152 -0
  99. package/src/components/SearchBar.less +165 -0
  100. package/src/components/SearchBar.tsx +68 -0
  101. package/src/components/SideMenu.less +379 -0
  102. package/src/components/SideMenu.tsx +148 -0
  103. package/src/components/SlugList.less +18 -0
  104. package/src/components/SlugList.tsx +20 -0
  105. package/src/layout.tsx +225 -0
  106. package/src/style/layout.less +402 -0
  107. package/src/style/markdown.less +240 -0
  108. package/src/style/variables.less +37 -0
  109. package/src/test/SearchBar.test.ts +32 -0
  110. package/src/test/Table.test.tsx +41 -0
  111. package/src/test/index.test.tsx +377 -0
@@ -0,0 +1,103 @@
1
+ @import (reference) '../style/variables.less';
2
+
3
+ .@{prefix}-code-block {
4
+ position: relative;
5
+ font-size: 14px;
6
+ background-color: @c-light-bg;
7
+
8
+ [data-prefers-color=dark] & {
9
+ color: @c-text-dark;
10
+ background: #262626;
11
+ }
12
+
13
+ & + &,
14
+ & + table {
15
+ margin-top: 16px;
16
+ }
17
+
18
+ > pre[class*='language-'] {
19
+ margin: 0;
20
+ background: transparent;
21
+
22
+ .token-line:not(:last-child) .plain:empty {
23
+ display: inline-block;
24
+ min-height: 1em;
25
+ }
26
+ }
27
+
28
+ &-copy-btn {
29
+ position: absolute;
30
+ top: 1.1em;
31
+ right: 1em;
32
+ display: inline-block;
33
+ width: 16px;
34
+ height: 16px;
35
+ padding: 0;
36
+ border: 0;
37
+ outline: none;
38
+ cursor: pointer;
39
+ opacity: 0.6;
40
+ transition: opacity 0.2s, background 0.2s;
41
+
42
+ &:hover {
43
+ opacity: 0.8;
44
+ }
45
+
46
+ &:active {
47
+ opacity: 0.9;
48
+ }
49
+
50
+ &[data-status='ready'] {
51
+ background-position: -54px 0;
52
+ }
53
+
54
+ &[data-status='copied'] {
55
+ opacity: 1;
56
+ pointer-events: none;
57
+ background-position: -54px -16px;
58
+ }
59
+ }
60
+
61
+ &:not(:hover) &-copy-btn {
62
+ visibility: hidden;
63
+ opacity: 0;
64
+ }
65
+ }
66
+
67
+ code[class*="language-"], pre[class*="language-"] {
68
+ &::selection, & ::selection{
69
+ color: inherit;
70
+ }
71
+ }
72
+
73
+ [data-prefers-color=dark] {
74
+ code[class*="language-"], pre[class*="language-"] {
75
+ color: @c-text-dark;
76
+ text-shadow: 0 1px #000;
77
+
78
+ &::selection, & ::selection{
79
+ background-color: #364a63;
80
+ }
81
+ }
82
+ .token.operator, .token.entity, .token.url, .language-css .token.string, .style .token.string {
83
+ background: transparent;
84
+ }
85
+ .token.property, .token.tag, .token.constant, .token.symbol, .token.deleted {
86
+ color: #f92672;
87
+ }
88
+ .token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.inserted {
89
+ color: #a6e22e;
90
+ }
91
+ .token.atrule, .token.attr-value, .token.keyword {
92
+ color: #e6db74;
93
+ }
94
+ .token.punctuation {
95
+ color: @c-text-dark;
96
+ }
97
+ .token.keyword {
98
+ color: #66d9ef;
99
+ }
100
+ .token.boolean, .token.number {
101
+ color: #ae81ff;
102
+ }
103
+ }
@@ -0,0 +1,55 @@
1
+ import { useCopy } from 'dumi/theme';
2
+ import type { Language } from 'prism-react-renderer';
3
+ import Highlight, { defaultProps } from 'prism-react-renderer';
4
+ import 'prismjs/themes/prism.css';
5
+ import React from 'react';
6
+ import './SourceCode.less';
7
+
8
+ /**
9
+ * define DSL which can be highlighted as similar language
10
+ */
11
+ const SIMILAR_DSL = {
12
+ acss: 'css',
13
+ axml: 'xml',
14
+ };
15
+
16
+ export interface ICodeBlockProps {
17
+ code: string;
18
+ lang: Language;
19
+ showCopy?: boolean;
20
+ }
21
+
22
+ export default ({ code, lang, showCopy = true }: ICodeBlockProps) => {
23
+ const [copyCode, copyStatus] = useCopy();
24
+
25
+ return (
26
+ <div className="__dumi-default-code-block">
27
+ {/** @ts-ignore */}
28
+ <Highlight
29
+ {...defaultProps}
30
+ code={code}
31
+ language={SIMILAR_DSL[lang] || lang}
32
+ theme={undefined}
33
+ >
34
+ {({ className, style, tokens, getLineProps, getTokenProps }) => (
35
+ <pre className={className} style={style}>
36
+ {showCopy && (
37
+ <button
38
+ className="__dumi-default-icon __dumi-default-code-block-copy-btn"
39
+ data-status={copyStatus}
40
+ onClick={() => copyCode(code)}
41
+ />
42
+ )}
43
+ {tokens.map((line, i) => (
44
+ <div {...getLineProps({ line, key: i })}>
45
+ {line.map((token, key) => (
46
+ <span {...getTokenProps({ token, key })} />
47
+ ))}
48
+ </div>
49
+ ))}
50
+ </pre>
51
+ )}
52
+ </Highlight>
53
+ </div>
54
+ );
55
+ };
@@ -0,0 +1,43 @@
1
+ .__dumi-default-table {
2
+ margin: 16px 0 32px;
3
+ transform: translate(0, 0);
4
+
5
+ &-content {
6
+ overflow: auto;
7
+
8
+ &::before,
9
+ &::after {
10
+ content: '';
11
+ display: block;
12
+ position: fixed;
13
+ z-index: 1;
14
+ top: 0;
15
+ bottom: 0;
16
+ width: 6px;
17
+ pointer-events: none;
18
+ }
19
+
20
+ &[data-left-folded]::before {
21
+ left: 0;
22
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));
23
+
24
+ [data-prefers-color=dark] & {
25
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
26
+ }
27
+ }
28
+
29
+ &[data-right-folded]::after {
30
+ right: 0;
31
+ background-image: linear-gradient(to left, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));
32
+
33
+ [data-prefers-color=dark] & {
34
+ background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
35
+ }
36
+ }
37
+
38
+ > table > thead > tr > th,
39
+ > table > tr > th {
40
+ white-space: nowrap;
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,42 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import throttle from 'lodash.throttle';
3
+ import './Table.less';
4
+
5
+ const Table: React.FC = ({ children }) => {
6
+ const container = useRef<HTMLDivElement>();
7
+ const [leftFolded, setLeftFolded] = useState(false);
8
+ const [rightFolded, setRightFolded] = useState(false);
9
+
10
+ // watch content scroll to render folded shadow
11
+ useEffect(() => {
12
+ const elm = container.current;
13
+ const handler = throttle(() => {
14
+ setLeftFolded(elm.scrollLeft > 0);
15
+ setRightFolded(elm.scrollLeft < elm.scrollWidth - elm.offsetWidth);
16
+ }, 100);
17
+
18
+ handler();
19
+ elm.addEventListener('scroll', handler);
20
+ window.addEventListener('resize', handler);
21
+
22
+ return () => {
23
+ elm.removeEventListener('scroll', handler);
24
+ window.removeEventListener('resize', handler);
25
+ }
26
+ }, []);
27
+
28
+ return (
29
+ <div className="__dumi-default-table">
30
+ <div
31
+ className="__dumi-default-table-content"
32
+ ref={container}
33
+ data-left-folded={leftFolded || undefined}
34
+ data-right-folded={rightFolded || undefined}
35
+ >
36
+ <table>{children}</table>
37
+ </div>
38
+ </div>
39
+ );
40
+ };
41
+
42
+ export default Table;
@@ -0,0 +1,159 @@
1
+ @import (reference) '../style/variables.less';
2
+ @treePrefixCls: ~'rc-tree';
3
+ @treeNodePrefixCls: ~'@{treePrefixCls}-treenode';
4
+
5
+ .__dumi-site-tree {
6
+ padding: 16px;
7
+ background-color: @c-light-bg;
8
+ border: 1px solid @c-border;
9
+ border-radius: 2px;
10
+
11
+ [data-prefers-color='dark'] & {
12
+ color: @c-text-dark;
13
+ background-color: @c-light-bg-dark;
14
+ border-color: @c-border-dark;
15
+ }
16
+
17
+ small {
18
+ padding-left: 24px;
19
+ color: @c-secondary;
20
+ font-size: 14px;
21
+
22
+ [data-prefers-color='dark'] & {
23
+ color: @c-secondary-dark;
24
+ }
25
+
26
+ &::before {
27
+ content: '# ';
28
+ }
29
+ }
30
+
31
+ &.@{treePrefixCls} {
32
+ transition: all 0.3s;
33
+ line-height: 1.5715;
34
+ list-style: none;
35
+ font-size: 14px;
36
+
37
+ .@{treeNodePrefixCls} {
38
+ position: relative;
39
+ display: flex;
40
+ align-items: flex-start;
41
+ padding-bottom: 4px;
42
+ &:before {
43
+ position: absolute;
44
+ top: 0;
45
+ right: 0;
46
+ bottom: 4px;
47
+ left: 0;
48
+ transition: background 0.3s;
49
+ content: '';
50
+ }
51
+ &:hover:before {
52
+ background: #f5f5f5;
53
+
54
+ [data-prefers-color='dark'] & {
55
+ background: @c-light-bg-dark;
56
+ }
57
+ }
58
+ > * {
59
+ z-index: 1;
60
+ }
61
+ }
62
+
63
+ .@{treeNodePrefixCls} span.@{treePrefixCls}-switcher {
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: center;
67
+ width: 24px;
68
+ height: 24px;
69
+ margin-right: 2px;
70
+ line-height: 24px;
71
+ background: transparent;
72
+ cursor: pointer;
73
+ }
74
+
75
+ .@{treeNodePrefixCls} .@{treePrefixCls}-node-content-wrapper {
76
+ flex: auto;
77
+ min-height: 24px;
78
+ margin: 0;
79
+ padding: 0 4px;
80
+ line-height: 24px;
81
+ cursor: pointer;
82
+ .@{treePrefixCls}-iconEle {
83
+ margin-right: 6px;
84
+ vertical-align: 0;
85
+ }
86
+ }
87
+
88
+ &.@{treePrefixCls}-show-line {
89
+ .@{treePrefixCls}-indent {
90
+ display: inline-block;
91
+ height: 0;
92
+ vertical-align: bottom;
93
+
94
+ &-unit {
95
+ position: relative;
96
+ display: inline-block;
97
+ width: 24px;
98
+ height: 24px;
99
+
100
+ &::before {
101
+ position: absolute;
102
+ top: 0;
103
+ right: 12px;
104
+ bottom: -4px;
105
+ border-right: 1px solid #d9d9d9;
106
+ content: '';
107
+ }
108
+
109
+ &-end::before {
110
+ display: none;
111
+ }
112
+ }
113
+ }
114
+
115
+ .tree-switcher-leaf-line {
116
+ position: relative;
117
+ z-index: 1;
118
+ display: inline-block;
119
+ width: 100%;
120
+ height: 100%;
121
+ text-align: center;
122
+ &::before {
123
+ position: absolute;
124
+ top: 0;
125
+ bottom: -4px;
126
+ margin-left: -1px;
127
+ border-left: 1px solid #d9d9d9;
128
+ content: ' ';
129
+ }
130
+
131
+ &::after {
132
+ position: absolute;
133
+ top: 0;
134
+ bottom: 10px;
135
+ width: 12px;
136
+ margin-left: -1px;
137
+ border-bottom: 1px solid #d9d9d9;
138
+ content: ' ';
139
+ }
140
+ }
141
+
142
+ .@{treeNodePrefixCls}-leaf-last {
143
+ .tree-switcher-leaf-line::before {
144
+ height: 14px;
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ &-icon {
151
+ width: 16px;
152
+ color: @c-text;
153
+ vertical-align: -0.225em;
154
+
155
+ [data-prefers-color='dark'] & {
156
+ color: @c-text-dark;
157
+ }
158
+ }
159
+ }
@@ -0,0 +1,130 @@
1
+ import type { ReactNode, ComponentProps } from 'react';
2
+ import React, { useEffect, useState, createRef } from 'react';
3
+ import type { TreeProps } from 'rc-tree';
4
+ import Tree from 'rc-tree';
5
+ import type { EventDataNode } from 'rc-tree/lib/interface';
6
+ import type { CSSMotionProps, MotionEventHandler, MotionEndEventHandler } from 'rc-motion';
7
+ import './Tree.less';
8
+
9
+ const FileOutlined = <svg xmlns="http://www.w3.org/2000/svg" className="__dumi-site-tree-icon icon-file" fill="currentcolor" viewBox="0 0 1024 1024"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0 0 42 42h216v494z"/></svg>;
10
+ const FolderOpenOutlined = <svg xmlns="http://www.w3.org/2000/svg" className="__dumi-site-tree-icon icon-folder-open" fill="currentcolor" viewBox="0 0 1024 1024"><path d="M928 444H820V330.4c0-17.7-14.3-32-32-32H473L355.7 186.2a8.15 8.15 0 0 0-5.5-2.2H96c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h698c13 0 24.8-7.9 29.7-20l134-332c1.5-3.8 2.3-7.9 2.3-12 0-17.7-14.3-32-32-32zM136 256h188.5l119.6 114.4H748V444H238c-13 0-24.8 7.9-29.7 20L136 643.2V256zm635.3 512H159l103.3-256h612.4L771.3 768z"/></svg>;
11
+ const FolderOutlined = <svg xmlns="http://www.w3.org/2000/svg" className="__dumi-site-tree-icon icon-folder" fill="currentcolor" viewBox="0 0 1024 1024"><path d="M880 298.4H521L403.7 186.2a8.15 8.15 0 0 0-5.5-2.2H144c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V330.4c0-17.7-14.3-32-32-32zM840 768H184V256h188.5l119.6 114.4H840V768z"/></svg>;
12
+ const MinusSquareOutlined = <svg xmlns="http://www.w3.org/2000/svg" className="__dumi-site-tree-icon icon-minus-square" fill="currentcolor" viewBox="0 0 1024 1024"><path d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"/><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"/></svg>;
13
+ const PlusSquareOutlined = <svg xmlns="http://www.w3.org/2000/svg" className="__dumi-site-tree-icon icon-plus-square" fill="currentcolor" viewBox="0 0 1024 1024"><path d="M328 544h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"/><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"/></svg>;
14
+
15
+ function getTreeFromList(nodes: ReactNode, prefix = '') {
16
+ const data: TreeProps['treeData'] = [];
17
+
18
+ [].concat(nodes).forEach((node, i) => {
19
+ const key = `${prefix ? `${prefix}-` : ''}${i}`;
20
+
21
+ switch (node.type) {
22
+ case 'ul':
23
+ const parent = data[data.length - 1]?.children || data;
24
+ const ulLeafs = getTreeFromList(node.props.children || [], key);
25
+
26
+ parent.push(...ulLeafs);
27
+ break;
28
+
29
+ case 'li':
30
+ const liLeafs = getTreeFromList(node.props.children, key);
31
+
32
+ data.push({
33
+ title: [].concat(node.props.children).filter(child => child.type !== 'ul'),
34
+ key,
35
+ children: liLeafs,
36
+ isLeaf: !liLeafs.length,
37
+ });
38
+ break;
39
+
40
+ default:
41
+ }
42
+ });
43
+
44
+ return data;
45
+ }
46
+
47
+ const useListToTree = (nodes: ReactNode) => {
48
+ const [tree, setTree] = useState(getTreeFromList(nodes));
49
+
50
+ useEffect(() => {
51
+ setTree(getTreeFromList(nodes));
52
+ }, [nodes]);
53
+
54
+ return tree;
55
+ };
56
+
57
+ const getIcon = (props) => {
58
+ const { isLeaf, expanded } = props;
59
+ if (isLeaf) {
60
+ return FileOutlined;
61
+ }
62
+ return expanded ? FolderOpenOutlined : FolderOutlined;
63
+ }
64
+
65
+ const renderSwitcherIcon = (props) => {
66
+ const { isLeaf, expanded } = props;
67
+ if (isLeaf) {
68
+ return <span className={`tree-switcher-leaf-line`} />;
69
+ }
70
+ return expanded ? (
71
+ <span className={`tree-switcher-line-icon`}>{MinusSquareOutlined}</span>
72
+ ) : (
73
+ <span className={`tree-switcher-line-icon`}>{PlusSquareOutlined}</span>
74
+ );
75
+ }
76
+
77
+ // ================== Collapse Motion ==================
78
+ const getCollapsedHeight: MotionEventHandler = () => ({ height: 0, opacity: 0 });
79
+ const getRealHeight: MotionEventHandler = node => ({ height: node.scrollHeight, opacity: 1 });
80
+ const getCurrentHeight: MotionEventHandler = node => ({ height: node.offsetHeight });
81
+ const skipOpacityTransition: MotionEndEventHandler = (_, event) =>
82
+ (event as TransitionEvent).propertyName === 'height';
83
+
84
+ const collapseMotion: CSSMotionProps = {
85
+ motionName: 'ant-motion-collapse',
86
+ onAppearStart: getCollapsedHeight,
87
+ onEnterStart: getCollapsedHeight,
88
+ onAppearActive: getRealHeight,
89
+ onEnterActive: getRealHeight,
90
+ onLeaveStart: getCurrentHeight,
91
+ onLeaveActive: getCollapsedHeight,
92
+ onAppearEnd: skipOpacityTransition,
93
+ onEnterEnd: skipOpacityTransition,
94
+ onLeaveEnd: skipOpacityTransition,
95
+ motionDeadline: 500,
96
+ };
97
+
98
+ export default (props: ComponentProps<'div'>) => {
99
+ const data = useListToTree(props.children);
100
+
101
+ const treeRef = createRef<Tree>();
102
+
103
+ const onClick = (event: React.MouseEvent<HTMLElement>, node: EventDataNode) =>{
104
+ const { isLeaf } = node;
105
+
106
+ if (isLeaf || event.shiftKey || event.metaKey || event.ctrlKey) {
107
+ return;
108
+ }
109
+ treeRef.current!.onNodeExpand(event as any, node);
110
+ };
111
+
112
+ return (
113
+ <Tree
114
+ className="__dumi-site-tree"
115
+ icon={getIcon}
116
+ ref={treeRef}
117
+ itemHeight={20}
118
+ showLine={true}
119
+ selectable={false}
120
+ motion={{
121
+ ...collapseMotion,
122
+ motionAppear: false
123
+ }}
124
+ onClick={onClick}
125
+ treeData={[{ key: '0', title: props.title || '<root>', children: data }]}
126
+ defaultExpandAll
127
+ switcherIcon={renderSwitcherIcon}
128
+ />
129
+ );
130
+ };
@@ -0,0 +1,121 @@
1
+ @import (reference) '../style/variables.less';
2
+
3
+ .@{prefix}-dark {
4
+ position: fixed;
5
+ right: 20px;
6
+ top: 16px;
7
+
8
+ [data-mode="doc"] & {
9
+ position: relative;
10
+ top: 0;
11
+ right: 0;
12
+ display: inline-block;
13
+ }
14
+
15
+ @media @mobile {
16
+ position: relative;
17
+ top: 6px;
18
+ right: auto;
19
+ display: flex;
20
+ justify-content: center;
21
+
22
+ .@{prefix}-navbar & {
23
+ display: none;
24
+ }
25
+ }
26
+
27
+ &-sun,
28
+ &-moon,
29
+ &-auto {
30
+ position: relative;
31
+ border-radius: 50%;
32
+ outline: none;
33
+ cursor: pointer;
34
+ width: 30px;
35
+ height: 30px;
36
+ display: flex;
37
+ justify-content: center;
38
+ align-items: center;
39
+
40
+ svg {
41
+ transition: all 0.3s linear;
42
+ &:hover {
43
+ transform: scale(1.2);
44
+ }
45
+ }
46
+ }
47
+
48
+ &-sun,
49
+ &-moon,
50
+ &-auto {
51
+ border: 1px solid @c-btn-border;
52
+ background-color: @c-light-bg;
53
+
54
+ svg {
55
+ fill: @c-text;
56
+ [data-prefers-color=dark] & {
57
+ fill: @c-text-dark;
58
+ }
59
+ }
60
+
61
+ [data-prefers-color=dark] & {
62
+ border-color: @c-btn-border-dark;
63
+ background-color: @c-bg-dark;
64
+ }
65
+ }
66
+
67
+ &-switch {
68
+ [data-mode=doc] & {
69
+ display: flex;
70
+ button + button {
71
+ margin-left: 4px;
72
+ }
73
+ }
74
+
75
+ @media @mobile {
76
+ display: flex;
77
+ button + button {
78
+ margin-left: 10px;
79
+ }
80
+ }
81
+
82
+ &-active {
83
+ .@{prefix}-menu & {
84
+ border-color: @c-primary;
85
+ [data-prefers-color=dark] & {
86
+ border-color: @c-primary-dark;
87
+ }
88
+ }
89
+ }
90
+
91
+ [data-mode=doc][data-mobile-show=true] & {
92
+ margin-bottom: 10px;
93
+ }
94
+
95
+ button {
96
+ z-index: 102;
97
+ }
98
+
99
+ &-list {
100
+ animation: dropDown 0.2s linear 0s 1;
101
+
102
+ button {
103
+ z-index: 101;
104
+ margin-top: 4px;
105
+ }
106
+
107
+ [data-mode="doc"] & {
108
+ position: absolute;
109
+ }
110
+ }
111
+ }
112
+ }
113
+
114
+ @keyframes dropDown {
115
+ 0% {
116
+ margin-top: -100%;
117
+ }
118
+ 100% {
119
+ margin-top: 0;
120
+ }
121
+ }