@umijs/plugin-docs 4.0.0-rc.13 → 4.0.0-rc.14

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.
@@ -44,7 +44,10 @@ export default (props: any) => {
44
44
  location: props.location,
45
45
  }}
46
46
  >
47
- <div className="flex flex-col dark:bg-gray-900 min-h-screen transition-all">
47
+ <div
48
+ className="flex flex-col dark:bg-gray-900 min-h-screen transition-all"
49
+ id={isHomePage ? 'home-page' : 'doc-page'}
50
+ >
48
51
  <div
49
52
  id="head-container"
50
53
  className="z-30 sticky top-0 dark:before:bg-gray-800 before:bg-white before:bg-opacity-[.85]
@@ -14,7 +14,10 @@ export default () => {
14
14
  <img src={Logo} className="w-8 h-8" alt="logo" />
15
15
  )}
16
16
  {typeof Logo === 'function' && <Logo />}
17
- <div className="text-xl font-extrabold ml-2 dark:text-white">
17
+ <div
18
+ id="header-title"
19
+ className="text-xl font-extrabold ml-2 dark:text-white"
20
+ >
18
21
  {themeConfig.title}
19
22
  </div>
20
23
  </div>
@@ -1,27 +1,70 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { useThemeContext } from './context';
3
3
  import useLanguage from './useLanguage';
4
4
 
5
5
  export default () => {
6
- const { components, themeConfig } = useThemeContext()!;
7
- const lang = useLanguage();
6
+ const { themeConfig } = useThemeContext()!;
8
7
  return (
9
8
  <ul className="flex">
10
- {themeConfig.navs.map((nav: any) => {
11
- return (
12
- <li key={nav.path} className="ml-4 dark:text-white">
9
+ {themeConfig.navs.map((nav: any) => (
10
+ <NavItem nav={nav} key={nav.path} />
11
+ ))}
12
+ </ul>
13
+ );
14
+ };
15
+
16
+ interface NavItemProps {
17
+ nav: {
18
+ path: string;
19
+ title: string;
20
+ dropdown?: {
21
+ title: string;
22
+ path: string;
23
+ }[];
24
+ };
25
+ }
26
+
27
+ function NavItem(props: NavItemProps) {
28
+ const { components } = useThemeContext()!;
29
+ const { nav } = props;
30
+ const lang = useLanguage();
31
+ const [isExpanded, setExpanded] = useState(false);
32
+ return (
33
+ <li
34
+ className="ml-8 dark:text-white relative"
35
+ onMouseEnter={() => nav.dropdown && setExpanded(true)}
36
+ onMouseLeave={() => nav.dropdown && setExpanded(false)}
37
+ >
38
+ <components.Link
39
+ to={
40
+ lang.isFromPath ? lang.currentLanguage?.locale + nav.path : nav.path
41
+ }
42
+ >
43
+ {lang.render(nav.title)}
44
+ </components.Link>
45
+ {nav.dropdown && (
46
+ <div
47
+ style={{ maxHeight: isExpanded ? nav.dropdown.length * 48 : 0 }}
48
+ className="absolute transition-all duration-300 w-32 rounded-lg
49
+ cursor-pointer shadow overflow-hidden top-8"
50
+ >
51
+ {nav.dropdown.map((n) => (
13
52
  <components.Link
53
+ key={n.path}
14
54
  to={
15
- lang.isFromPath
16
- ? lang.currentLanguage?.locale + nav.path
17
- : nav.path
55
+ lang.isFromPath ? lang.currentLanguage?.locale + n.path : n.path
18
56
  }
19
57
  >
20
- {lang.render(nav.title)}
58
+ <p
59
+ className="p-2 bg-white dark:bg-gray-700 dark:text-white
60
+ hover:bg-gray-50 transition duration-300"
61
+ >
62
+ {n.title}
63
+ </p>
21
64
  </components.Link>
22
- </li>
23
- );
24
- })}
25
- </ul>
65
+ ))}
66
+ </div>
67
+ )}
68
+ </li>
26
69
  );
27
- };
70
+ }
@@ -3,9 +3,11 @@ import key from 'keymaster';
3
3
  import React, { Fragment, useEffect, useState } from 'react';
4
4
  import { useThemeContext } from './context';
5
5
  import useLanguage from './useLanguage';
6
+ import getLinkFromTitle from './utils/getLinkFromTitle';
6
7
 
7
8
  export default () => {
8
- const { render } = useLanguage();
9
+ const { components } = useThemeContext()!;
10
+ const { isFromPath, currentLanguage, render } = useLanguage();
9
11
  const [isFocused, setIsFocused] = useState(false);
10
12
  const [keyword, setKeyword] = useState('');
11
13
 
@@ -34,6 +36,7 @@ export default () => {
34
36
  }
35
37
 
36
38
  useEffect(() => {
39
+ if (!themeConfig.searchHotKey) return;
37
40
  key.filter = () => true;
38
41
 
39
42
  // 在页面中按下 ⌘+k 可以打开搜索框
@@ -63,6 +66,7 @@ export default () => {
63
66
  return (
64
67
  <Fragment>
65
68
  <div
69
+ id="search-input-wrapper"
66
70
  className="rounded-lg w-40 lg:w-64 flex items-center pr-2 flex-row hover:bg-gray-50
67
71
  transition duration-300 bg-gray-100 border border-white focus-within:border-gray-100
68
72
  focus-within:bg-white dark:bg-gray-700 dark:border-gray-700 relative
@@ -72,18 +76,22 @@ export default () => {
72
76
  onFocus={() => setIsFocused(true)}
73
77
  onBlur={() => setIsFocused(false)}
74
78
  value={keyword}
79
+ autoComplete="off"
75
80
  onChange={(e) => setKeyword(e.target.value)}
76
81
  id="search-input"
77
82
  className="w-full bg-transparent outline-none text-sm px-4 py-2"
78
83
  placeholder={render('Search anything ...')}
79
84
  />
80
- <div
81
- className="bg-gray-200 rounded px-2 h-6 flex flex-row text-gray-400
85
+ {themeConfig.searchHotKey && (
86
+ <div
87
+ className="bg-gray-200 rounded px-2 h-6 flex flex-row text-gray-400
82
88
  items-center justify-center border border-gray-300 text-xs"
83
- >
84
- {isMac ? macSearchKey : windowsSearchKey}
85
- </div>
89
+ >
90
+ {isMac ? macSearchKey : windowsSearchKey}
91
+ </div>
92
+ )}
86
93
  <div
94
+ id="search-results-wrapper"
87
95
  className={cx(
88
96
  'absolute transition-all duration-500 top-12 w-96 rounded-lg',
89
97
  'cursor-pointer shadow overflow-hidden',
@@ -91,8 +99,8 @@ export default () => {
91
99
  )}
92
100
  >
93
101
  {result.map((r, i) => (
94
- <a
95
- href={r.href}
102
+ <components.Link
103
+ to={(isFromPath ? currentLanguage?.locale : '') + r.href}
96
104
  key={i}
97
105
  className="group outline-none search-result"
98
106
  onFocus={() => setIsFocused(true)}
@@ -104,7 +112,7 @@ export default () => {
104
112
  >
105
113
  {r.path}
106
114
  </p>
107
- </a>
115
+ </components.Link>
108
116
  ))}
109
117
  </div>
110
118
  </div>
@@ -122,9 +130,15 @@ function search(routes: any, keyword: string): SearchResultItem[] {
122
130
 
123
131
  const result: SearchResultItem[] = [];
124
132
 
133
+ function addResult(newResult: { path: string; href: string }) {
134
+ const { path, href } = newResult;
135
+ if (result.find((r) => r.path === path)) return;
136
+ result.push({ path, href });
137
+ }
138
+
125
139
  Object.keys(routes).map((path) => {
126
140
  if (path.toLowerCase().includes(keyword.toLowerCase())) {
127
- result.push({
141
+ addResult({
128
142
  path: path.split('/').slice(1).join(' > '),
129
143
  href: '/' + path,
130
144
  });
@@ -132,16 +146,21 @@ function search(routes: any, keyword: string): SearchResultItem[] {
132
146
 
133
147
  const route = routes[path];
134
148
  if (!route.titles) return;
135
- route.titles
136
- .filter((t: any) => t.level <= 2)
137
- .map((title: any) => {
138
- if (title.title.toLowerCase().includes(keyword.toLowerCase())) {
139
- result.push({
140
- path: path.split('/').slice(1).join(' > ') + ' > ' + title.title,
141
- href: '/' + path + '#' + title.title,
142
- });
143
- }
144
- });
149
+ route.titles.map((title: any) => {
150
+ if (title.title.toLowerCase().includes(keyword.toLowerCase())) {
151
+ addResult({
152
+ path:
153
+ path
154
+ .split('/')
155
+ .map((s) => s.replace(/\.[a-z]{2}-[A-Z]{2}\/?/g, ''))
156
+ .slice(1)
157
+ .join(' > ') +
158
+ ' > ' +
159
+ title.title,
160
+ href: '/' + path + '#' + getLinkFromTitle(title.title),
161
+ });
162
+ }
163
+ });
145
164
  });
146
165
 
147
166
  if (result.length > 8) return result.slice(0, 8);
@@ -49,7 +49,8 @@ export default (props: SidebarProps) => {
49
49
  if (to === window.location.pathname) {
50
50
  return (
51
51
  <div
52
- key={child}
52
+ id="active-nav-item"
53
+ key={route.path}
53
54
  className="my-2 hover:text-blue-400 transition-all
54
55
  bg-blue-50 text-blue-400 px-4 py-1
55
56
  rounded-lg cursor-default dark:bg-blue-900 dark:text-blue-200"
@@ -61,6 +62,7 @@ export default (props: SidebarProps) => {
61
62
 
62
63
  return (
63
64
  <components.Link
65
+ key={route.path}
64
66
  to={route.path}
65
67
  onClick={() =>
66
68
  props.setMenuOpened && props.setMenuOpened((o) => !o)
@@ -2,13 +2,8 @@ import React from 'react';
2
2
  import { Helmet } from 'react-helmet';
3
3
  import { useThemeContext } from './context';
4
4
  import useLanguage from './useLanguage';
5
-
6
- function getLinkFromTitle(title: string) {
7
- return title
8
- .toLowerCase()
9
- .replace(/\s/g, '-')
10
- .replace(/[()]/g, '');
11
- }
5
+ import getLinkFromTitle from './utils/getLinkFromTitle';
6
+ import getTocTitle from './utils/getTocTitle';
12
7
 
13
8
  export default () => {
14
9
  const { location, appData, themeConfig } = useThemeContext()!;
@@ -30,7 +25,7 @@ export default () => {
30
25
  return (
31
26
  <div
32
27
  className="w-full lg:m-12 mb-12 border
33
- border-gray-100 p-4 rounded-xl z-20"
28
+ border-gray-200 dark:border-neutral-700 py-4 rounded-lg z-20"
34
29
  >
35
30
  {/* @ts-ignore */}
36
31
  <Helmet>
@@ -38,22 +33,24 @@ export default () => {
38
33
  {route.titles[0].title} | {themeConfig.title}
39
34
  </title>
40
35
  </Helmet>
41
- <p className="text-lg font-extrabold dark:text-white">
42
- {route.titles[0].title}
36
+ <p className="text-lg font-extrabold text-gray-800 dark:text-neutral-50 pb-2 border-b border-gray-200 dark:border-neutral-700">
37
+ <span className="px-4">{route.titles[0].title}</span>
43
38
  </p>
44
- <ul className="max-h-[calc(100vh-360px)] overflow-y-auto py-2">
39
+ <ul className="max-h-[calc(100vh-360px)] overflow-y-auto px-4">
45
40
  {titles.map((item: any) => {
46
41
  return (
47
42
  <li
48
43
  style={{ paddingLeft: `${item.level - 2}rem` }}
49
- className="mt-3 text-gray-600 cursor-pointer dark:text-gray-400
44
+ className="mt-3 text-gray-600 cursor-pointer dark:text-neutral-400
50
45
  hover:text-blue-500 transition duration-300 dark:hover:text-blue-500"
51
46
  >
52
47
  <a
53
- className={item.level > 2 ? 'text-sm' : ''}
48
+ className={`${
49
+ item.level > 2 ? 'text-sm' : 'text-base'
50
+ } break-all 2xl:break-words`}
54
51
  href={'#' + getLinkFromTitle(item.title)}
55
52
  >
56
- {item.title}
53
+ {getTocTitle(item.title)}
57
54
  </a>
58
55
  </li>
59
56
  );
@@ -8,7 +8,7 @@ function Features(
8
8
  props: PropsWithChildren<{ title?: string; subtitle?: string }>,
9
9
  ) {
10
10
  return (
11
- <div className="w-screen py-36 features dark:features-dark min-h-screen">
11
+ <div className="w-full py-36 features dark:features-dark min-h-screen">
12
12
  {(props.title || props.subtitle) && (
13
13
  <div className="mb-24 px-4">
14
14
  {props.title && (
@@ -22,6 +22,7 @@ interface IContext {
22
22
  navs: {
23
23
  path: string;
24
24
  title: string;
25
+ dropdown?: { title: string; path: string }[];
25
26
  children: any[];
26
27
  }[];
27
28
  announcement?: {
@@ -51,33 +51,82 @@ article h2 a {
51
51
  @apply no-underline dark:text-white;
52
52
  }
53
53
 
54
+ /* 行内代码 */
54
55
  article code {
55
- @apply text-sky-800 dark:text-sky-300 bg-slate-800 bg-opacity-5 dark:bg-opacity-100 border border-black border-opacity-5 rounded-md;
56
+ @apply text-sky-600 dark:text-sky-300 bg-slate-800 bg-opacity-5 dark:bg-opacity-100 border border-black border-opacity-5 rounded-md;
56
57
  font-size: 0.9em;
57
58
  padding: 2px 0.25em;
58
59
  box-decoration-break: clone;
59
60
  font-feature-settings: 'rlig' 1, 'calt' 1, 'ss01' 1;
60
61
  }
61
62
 
62
- article inlinecode {
63
- @apply bg-black bg-opacity-5 border border-black border-opacity-5 rounded-md px-1.5 py-0.5 text-xs dark:text-white dark:bg-gray-700;
63
+ /* 行内高亮代码 */
64
+ article span[data-rehype-pretty-code-fragment] code {
65
+ @apply bg-zinc-900 dark:bg-zinc-900;
64
66
  }
65
67
 
68
+ /* 代码块 */
66
69
  article pre {
67
- /* content-visibility: auto; */
68
70
  contain: paint;
69
- @apply p-4 bg-zinc-900 dark:bg-zinc-900 rounded-xl my-4 overflow-x-auto font-medium subpixel-antialiased dark:text-white transition;
71
+ @apply my-4 bg-zinc-900 dark:bg-zinc-900 text-neutral-300 dark:text-neutral-300 rounded-md font-medium subpixel-antialiased transition;
72
+ }
73
+ article pre > code {
74
+ @apply grid leading-relaxed p-4 text-sm text-neutral-300 dark:text-neutral-300 bg-transparent dark:bg-transparent rounded-none border-none min-w-full overflow-x-auto;
75
+ }
76
+ article div[data-rehype-pretty-code-fragment] {
77
+ @apply my-4;
78
+ }
79
+
80
+ /* 代码块的标题部分 */
81
+ article
82
+ div[data-rehype-pretty-code-fragment]
83
+ > div[data-rehype-pretty-code-title] {
84
+ @apply pb-1 text-sm text-zinc-400 dark:text-neutral-400 text-center;
85
+ }
86
+
87
+ /* 代码块的代码部分 */
88
+ article div[data-rehype-pretty-code-fragment] > pre {
89
+ @apply pt-6 my-0;
90
+ }
91
+ article div[data-rehype-pretty-code-fragment] > pre > code {
92
+ @apply my-0 pt-0 px-0;
70
93
  }
71
94
 
72
- article pre code {
73
- line-height: 1.25rem;
74
- @apply relative p-0 text-sm text-neutral-300 dark:text-neutral-300 bg-transparent dark:bg-transparent rounded-none border-none inline-block min-w-full transition;
95
+ /* 代码块的使用语言 */
96
+ article div[data-rehype-pretty-code-fragment] > pre::before {
97
+ @apply fixed top-0 right-0 px-2 text-sm uppercase bg-neutral-300 text-zinc-900 bg-opacity-80 dark:bg-opacity-60 rounded-sm;
98
+ content: attr(data-language);
75
99
  }
76
100
 
77
- article pre code .line.highlighted {
78
- @apply before:block before:absolute before:h-5 before:bg-gray-500 before:bg-opacity-10 before:-inset-x-4 before:pointer-events-none before:select-none dark:text-white transition;
101
+ /* 代码块的代码行 */
102
+ article div[data-rehype-pretty-code-fragment] > pre > code .line {
103
+ @apply pl-3 pr-4;
79
104
  }
80
105
 
106
+ /* 代码块的行内高亮文字 */
107
+ article div[data-rehype-pretty-code-fragment] > pre > code .line .word {
108
+ @apply px-1.5 inline-block bg-neutral-300 bg-opacity-20 rounded-sm;
109
+ }
110
+
111
+ /* 代码块的行号 */
112
+ article div[data-rehype-pretty-code-fragment] > pre > code {
113
+ counter-reset: line;
114
+ }
115
+ article div[data-rehype-pretty-code-fragment] > pre > code > .line::before {
116
+ @apply text-neutral-600 w-4 mr-4 inline-block text-right;
117
+ counter-increment: line;
118
+ content: counter(line);
119
+ }
120
+
121
+ /* 代码块的高亮行 */
122
+ article div[data-rehype-pretty-code-fragment] pre > code > .line {
123
+ @apply border-l-2 border-transparent;
124
+ }
125
+ article div[data-rehype-pretty-code-fragment] pre > code > .line.highlighted {
126
+ @apply bg-neutral-100 dark:bg-neutral-300 bg-opacity-10 dark:bg-opacity-10 border-l-blue-400 dark:border-l-sky-600;
127
+ }
128
+
129
+ /* 链接 */
81
130
  article a {
82
131
  @apply mx-1 text-cyan-600 dark:text-fuchsia-200 hover:text-cyan-900 dark:hover:text-fuchsia-400 transition;
83
132
  background-image: linear-gradient(
@@ -85,9 +134,26 @@ article a {
85
134
  rgba(130, 199, 255, 0.28) 55%
86
135
  );
87
136
  }
137
+ .dark article a {
138
+ background-image: linear-gradient(
139
+ transparent 60%,
140
+ rgba(238, 157, 234, 0.28) 55%
141
+ );
142
+ }
88
143
 
89
- article a code {
144
+ /* 行内代码块链接 */
145
+ article a > code {
90
146
  @apply text-cyan-600 dark:text-fuchsia-200 hover:text-cyan-900 dark:hover:text-fuchsia-400 transition;
147
+ background-image: linear-gradient(
148
+ transparent 60%,
149
+ rgba(130, 199, 255, 0.28) 55%
150
+ );
151
+ }
152
+ .dark article a > code {
153
+ background-image: linear-gradient(
154
+ transparent 60%,
155
+ rgba(238, 157, 234, 0.28) 55%
156
+ );
91
157
  }
92
158
 
93
159
  article table {
@@ -673,6 +673,10 @@ Ensure the default browser behavior of the `hidden` attribute.
673
673
  top: 3rem;
674
674
  }
675
675
 
676
+ .top-8 {
677
+ top: 2rem;
678
+ }
679
+
676
680
  .right-2 {
677
681
  right: 0.5rem;
678
682
  }
@@ -731,6 +735,10 @@ Ensure the default browser behavior of the `hidden` attribute.
731
735
  margin-left: 1rem;
732
736
  }
733
737
 
738
+ .ml-8 {
739
+ margin-left: 2rem;
740
+ }
741
+
734
742
  .mb-12 {
735
743
  margin-bottom: 3rem;
736
744
  }
@@ -875,6 +883,10 @@ Ensure the default browser behavior of the `hidden` attribute.
875
883
  width: 2rem;
876
884
  }
877
885
 
886
+ .w-32 {
887
+ width: 8rem;
888
+ }
889
+
878
890
  .w-40 {
879
891
  width: 10rem;
880
892
  }
@@ -1034,6 +1046,10 @@ Ensure the default browser behavior of the `hidden` attribute.
1034
1046
  overflow-y: scroll;
1035
1047
  }
1036
1048
 
1049
+ .break-all {
1050
+ word-break: break-all;
1051
+ }
1052
+
1037
1053
  .rounded-lg {
1038
1054
  border-radius: 0.5rem;
1039
1055
  }
@@ -1058,6 +1074,10 @@ Ensure the default browser behavior of the `hidden` attribute.
1058
1074
  border-bottom-width: 2px;
1059
1075
  }
1060
1076
 
1077
+ .border-b {
1078
+ border-bottom-width: 1px;
1079
+ }
1080
+
1061
1081
  .border-white {
1062
1082
  --tw-border-opacity: 1;
1063
1083
  border-color: rgb(255 255 255 / var(--tw-border-opacity));
@@ -1068,9 +1088,9 @@ Ensure the default browser behavior of the `hidden` attribute.
1068
1088
  border-color: rgb(209 213 219 / var(--tw-border-opacity));
1069
1089
  }
1070
1090
 
1071
- .border-gray-100 {
1091
+ .border-gray-200 {
1072
1092
  --tw-border-opacity: 1;
1073
- border-color: rgb(243 244 246 / var(--tw-border-opacity));
1093
+ border-color: rgb(229 231 235 / var(--tw-border-opacity));
1074
1094
  }
1075
1095
 
1076
1096
  .border-b-gray-100 {
@@ -1174,6 +1194,11 @@ Ensure the default browser behavior of the `hidden` attribute.
1174
1194
  padding-right: 0.25rem;
1175
1195
  }
1176
1196
 
1197
+ .py-4 {
1198
+ padding-top: 1rem;
1199
+ padding-bottom: 1rem;
1200
+ }
1201
+
1177
1202
  .py-12 {
1178
1203
  padding-top: 3rem;
1179
1204
  padding-bottom: 3rem;
@@ -1218,6 +1243,10 @@ Ensure the default browser behavior of the `hidden` attribute.
1218
1243
  padding-bottom: 9rem;
1219
1244
  }
1220
1245
 
1246
+ .pb-2 {
1247
+ padding-bottom: 0.5rem;
1248
+ }
1249
+
1221
1250
  .pb-12 {
1222
1251
  padding-bottom: 3rem;
1223
1252
  }
@@ -1246,6 +1275,11 @@ Ensure the default browser behavior of the `hidden` attribute.
1246
1275
  line-height: 1.75rem;
1247
1276
  }
1248
1277
 
1278
+ .text-base {
1279
+ font-size: 1rem;
1280
+ line-height: 1.5rem;
1281
+ }
1282
+
1249
1283
  .text-3xl {
1250
1284
  font-size: 1.875rem;
1251
1285
  line-height: 2.25rem;
@@ -1284,6 +1318,11 @@ Ensure the default browser behavior of the `hidden` attribute.
1284
1318
  color: rgb(55 65 81 / var(--tw-text-opacity));
1285
1319
  }
1286
1320
 
1321
+ .text-gray-800 {
1322
+ --tw-text-opacity: 1;
1323
+ color: rgb(31 41 55 / var(--tw-text-opacity));
1324
+ }
1325
+
1287
1326
  .text-gray-600 {
1288
1327
  --tw-text-opacity: 1;
1289
1328
  color: rgb(75 85 99 / var(--tw-text-opacity));
@@ -1571,6 +1610,8 @@ article h2 a {
1571
1610
  color: rgb(255 255 255 / var(--tw-text-opacity));
1572
1611
  }
1573
1612
 
1613
+ /* 行内代码 */
1614
+
1574
1615
  article code {
1575
1616
  border-radius: 0.375rem;
1576
1617
  border-width: 1px;
@@ -1579,7 +1620,7 @@ article code {
1579
1620
  background-color: rgb(30 41 59 / var(--tw-bg-opacity));
1580
1621
  --tw-bg-opacity: 0.05;
1581
1622
  --tw-text-opacity: 1;
1582
- color: rgb(7 89 133 / var(--tw-text-opacity));
1623
+ color: rgb(2 132 199 / var(--tw-text-opacity));
1583
1624
  }
1584
1625
 
1585
1626
  .dark article code {
@@ -1596,39 +1637,30 @@ article code {
1596
1637
  font-feature-settings: 'rlig' 1, 'calt' 1, 'ss01' 1;
1597
1638
  }
1598
1639
 
1599
- article inlinecode {
1600
- border-radius: 0.375rem;
1601
- border-width: 1px;
1602
- border-color: rgb(0 0 0 / var(--tw-border-opacity));
1603
- --tw-border-opacity: 0.05;
1604
- background-color: rgb(0 0 0 / var(--tw-bg-opacity));
1605
- --tw-bg-opacity: 0.05;
1606
- padding-left: 0.375rem;
1607
- padding-right: 0.375rem;
1608
- padding-top: 0.125rem;
1609
- padding-bottom: 0.125rem;
1610
- font-size: 0.75rem;
1611
- line-height: 1rem;
1640
+ /* 行内高亮代码 */
1641
+
1642
+ article span[data-rehype-pretty-code-fragment] code {
1643
+ --tw-bg-opacity: 1;
1644
+ background-color: rgb(24 24 27 / var(--tw-bg-opacity));
1612
1645
  }
1613
1646
 
1614
- .dark article inlinecode {
1647
+ .dark article span[data-rehype-pretty-code-fragment] code {
1615
1648
  --tw-bg-opacity: 1;
1616
- background-color: rgb(55 65 81 / var(--tw-bg-opacity));
1617
- --tw-text-opacity: 1;
1618
- color: rgb(255 255 255 / var(--tw-text-opacity));
1649
+ background-color: rgb(24 24 27 / var(--tw-bg-opacity));
1619
1650
  }
1620
1651
 
1652
+ /* 代码块 */
1653
+
1621
1654
  article pre {
1622
- /* content-visibility: auto; */
1623
1655
  contain: paint;
1624
1656
  margin-top: 1rem;
1625
1657
  margin-bottom: 1rem;
1626
- overflow-x: auto;
1627
- border-radius: 0.75rem;
1658
+ border-radius: 0.375rem;
1628
1659
  --tw-bg-opacity: 1;
1629
1660
  background-color: rgb(24 24 27 / var(--tw-bg-opacity));
1630
- padding: 1rem;
1631
1661
  font-weight: 500;
1662
+ --tw-text-opacity: 1;
1663
+ color: rgb(212 212 212 / var(--tw-text-opacity));
1632
1664
  -webkit-font-smoothing: auto;
1633
1665
  -moz-osx-font-smoothing: auto;
1634
1666
  transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-text-decoration-color, -webkit-backdrop-filter;
@@ -1642,63 +1674,155 @@ article pre {
1642
1674
  --tw-bg-opacity: 1;
1643
1675
  background-color: rgb(24 24 27 / var(--tw-bg-opacity));
1644
1676
  --tw-text-opacity: 1;
1645
- color: rgb(255 255 255 / var(--tw-text-opacity));
1677
+ color: rgb(212 212 212 / var(--tw-text-opacity));
1646
1678
  }
1647
1679
 
1648
- article pre code {
1649
- position: relative;
1650
- display: inline-block;
1680
+ article pre > code {
1681
+ display: grid;
1651
1682
  min-width: 100%;
1683
+ overflow-x: auto;
1652
1684
  border-radius: 0px;
1653
1685
  border-style: none;
1654
1686
  background-color: transparent;
1655
- padding: 0px;
1687
+ padding: 1rem;
1656
1688
  font-size: 0.875rem;
1657
1689
  line-height: 1.25rem;
1690
+ line-height: 1.625;
1658
1691
  --tw-text-opacity: 1;
1659
1692
  color: rgb(212 212 212 / var(--tw-text-opacity));
1660
- transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-text-decoration-color, -webkit-backdrop-filter;
1661
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
1662
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-text-decoration-color, -webkit-backdrop-filter;
1663
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1664
- transition-duration: 150ms;
1665
1693
  }
1666
1694
 
1667
- .dark article pre code {
1695
+ .dark article pre > code {
1668
1696
  background-color: transparent;
1669
1697
  --tw-text-opacity: 1;
1670
1698
  color: rgb(212 212 212 / var(--tw-text-opacity));
1671
1699
  }
1672
1700
 
1673
- article pre code .line.highlighted {
1674
- transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-text-decoration-color, -webkit-backdrop-filter;
1675
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
1676
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-text-decoration-color, -webkit-backdrop-filter;
1677
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1678
- transition-duration: 150ms;
1701
+ article div[data-rehype-pretty-code-fragment] {
1702
+ margin-top: 1rem;
1703
+ margin-bottom: 1rem;
1679
1704
  }
1680
1705
 
1681
- article pre code .line.highlighted::before {
1682
- pointer-events: none;
1683
- position: absolute;
1684
- left: -1rem;
1685
- right: -1rem;
1686
- display: block;
1687
- height: 1.25rem;
1688
- -webkit-user-select: none;
1689
- -moz-user-select: none;
1690
- -ms-user-select: none;
1691
- user-select: none;
1692
- background-color: rgb(107 114 128 / var(--tw-bg-opacity));
1693
- content: var(--tw-content);
1694
- --tw-bg-opacity: 0.1;
1706
+ /* 代码块的标题部分 */
1707
+
1708
+ article
1709
+ div[data-rehype-pretty-code-fragment]
1710
+ > div[data-rehype-pretty-code-title] {
1711
+ padding-bottom: 0.25rem;
1712
+ text-align: center;
1713
+ font-size: 0.875rem;
1714
+ line-height: 1.25rem;
1715
+ --tw-text-opacity: 1;
1716
+ color: rgb(161 161 170 / var(--tw-text-opacity));
1695
1717
  }
1696
1718
 
1697
- .dark article pre code .line.highlighted {
1719
+ .dark article
1720
+ div[data-rehype-pretty-code-fragment]
1721
+ > div[data-rehype-pretty-code-title] {
1698
1722
  --tw-text-opacity: 1;
1699
- color: rgb(255 255 255 / var(--tw-text-opacity));
1723
+ color: rgb(163 163 163 / var(--tw-text-opacity));
1724
+ }
1725
+
1726
+ /* 代码块的代码部分 */
1727
+
1728
+ article div[data-rehype-pretty-code-fragment] > pre {
1729
+ margin-top: 0px;
1730
+ margin-bottom: 0px;
1731
+ padding-top: 1.5rem;
1732
+ }
1733
+
1734
+ article div[data-rehype-pretty-code-fragment] > pre > code {
1735
+ margin-top: 0px;
1736
+ margin-bottom: 0px;
1737
+ padding-left: 0px;
1738
+ padding-right: 0px;
1739
+ padding-top: 0px;
1740
+ }
1741
+
1742
+ /* 代码块的使用语言 */
1743
+
1744
+ article div[data-rehype-pretty-code-fragment] > pre::before {
1745
+ position: fixed;
1746
+ top: 0px;
1747
+ right: 0px;
1748
+ border-radius: 0.125rem;
1749
+ background-color: rgb(212 212 212 / var(--tw-bg-opacity));
1750
+ --tw-bg-opacity: 0.8;
1751
+ padding-left: 0.5rem;
1752
+ padding-right: 0.5rem;
1753
+ font-size: 0.875rem;
1754
+ line-height: 1.25rem;
1755
+ text-transform: uppercase;
1756
+ --tw-text-opacity: 1;
1757
+ color: rgb(24 24 27 / var(--tw-text-opacity));
1758
+ }
1759
+
1760
+ .dark article div[data-rehype-pretty-code-fragment] > pre::before {
1761
+ --tw-bg-opacity: 0.6;
1762
+ }
1763
+
1764
+ article div[data-rehype-pretty-code-fragment] > pre::before {
1765
+ content: attr(data-language);
1766
+ }
1767
+
1768
+ /* 代码块的代码行 */
1769
+
1770
+ article div[data-rehype-pretty-code-fragment] > pre > code .line {
1771
+ padding-left: 0.75rem;
1772
+ padding-right: 1rem;
1773
+ }
1774
+
1775
+ /* 代码块的行内高亮文字 */
1776
+
1777
+ article div[data-rehype-pretty-code-fragment] > pre > code .line .word {
1778
+ display: inline-block;
1779
+ border-radius: 0.125rem;
1780
+ background-color: rgb(212 212 212 / var(--tw-bg-opacity));
1781
+ --tw-bg-opacity: 0.2;
1782
+ padding-left: 0.375rem;
1783
+ padding-right: 0.375rem;
1784
+ }
1785
+
1786
+ /* 代码块的行号 */
1787
+
1788
+ article div[data-rehype-pretty-code-fragment] > pre > code {
1789
+ counter-reset: line;
1790
+ }
1791
+
1792
+ article div[data-rehype-pretty-code-fragment] > pre > code > .line::before {
1793
+ margin-right: 1rem;
1794
+ display: inline-block;
1795
+ width: 1rem;
1796
+ text-align: right;
1797
+ --tw-text-opacity: 1;
1798
+ color: rgb(82 82 82 / var(--tw-text-opacity));
1799
+ counter-increment: line;
1800
+ content: counter(line);
1801
+ }
1802
+
1803
+ /* 代码块的高亮行 */
1804
+
1805
+ article div[data-rehype-pretty-code-fragment] pre > code > .line {
1806
+ border-left-width: 2px;
1807
+ border-color: transparent;
1808
+ }
1809
+
1810
+ article div[data-rehype-pretty-code-fragment] pre > code > .line.highlighted {
1811
+ --tw-border-opacity: 1;
1812
+ border-left-color: rgb(96 165 250 / var(--tw-border-opacity));
1813
+ background-color: rgb(245 245 245 / var(--tw-bg-opacity));
1814
+ --tw-bg-opacity: 0.1;
1815
+ }
1816
+
1817
+ .dark article div[data-rehype-pretty-code-fragment] pre > code > .line.highlighted {
1818
+ --tw-border-opacity: 1;
1819
+ border-left-color: rgb(2 132 199 / var(--tw-border-opacity));
1820
+ background-color: rgb(212 212 212 / var(--tw-bg-opacity));
1821
+ --tw-bg-opacity: 0.1;
1700
1822
  }
1701
1823
 
1824
+ /* 链接 */
1825
+
1702
1826
  article a {
1703
1827
  margin-left: 0.25rem;
1704
1828
  margin-right: 0.25rem;
@@ -1733,7 +1857,16 @@ article a {
1733
1857
  );
1734
1858
  }
1735
1859
 
1736
- article a code {
1860
+ .dark article a {
1861
+ background-image: linear-gradient(
1862
+ transparent 60%,
1863
+ rgba(238, 157, 234, 0.28) 55%
1864
+ );
1865
+ }
1866
+
1867
+ /* 行内代码块链接 */
1868
+
1869
+ article a > code {
1737
1870
  --tw-text-opacity: 1;
1738
1871
  color: rgb(8 145 178 / var(--tw-text-opacity));
1739
1872
  transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-text-decoration-color, -webkit-backdrop-filter;
@@ -1743,21 +1876,35 @@ article a code {
1743
1876
  transition-duration: 150ms;
1744
1877
  }
1745
1878
 
1746
- article a code:hover {
1879
+ article a > code:hover {
1747
1880
  --tw-text-opacity: 1;
1748
1881
  color: rgb(22 78 99 / var(--tw-text-opacity));
1749
1882
  }
1750
1883
 
1751
- .dark article a code {
1884
+ .dark article a > code {
1752
1885
  --tw-text-opacity: 1;
1753
1886
  color: rgb(245 208 254 / var(--tw-text-opacity));
1754
1887
  }
1755
1888
 
1756
- .dark article a code:hover {
1889
+ .dark article a > code:hover {
1757
1890
  --tw-text-opacity: 1;
1758
1891
  color: rgb(232 121 249 / var(--tw-text-opacity));
1759
1892
  }
1760
1893
 
1894
+ article a > code {
1895
+ background-image: linear-gradient(
1896
+ transparent 60%,
1897
+ rgba(130, 199, 255, 0.28) 55%
1898
+ );
1899
+ }
1900
+
1901
+ .dark article a > code {
1902
+ background-image: linear-gradient(
1903
+ transparent 60%,
1904
+ rgba(238, 157, 234, 0.28) 55%
1905
+ );
1906
+ }
1907
+
1761
1908
  article table {
1762
1909
  margin-top: 2rem;
1763
1910
  margin-bottom: 2rem;
@@ -2016,6 +2163,11 @@ h6 {
2016
2163
  border-color: rgb(55 65 81 / var(--tw-border-opacity));
2017
2164
  }
2018
2165
 
2166
+ .dark .dark\:border-neutral-700 {
2167
+ --tw-border-opacity: 1;
2168
+ border-color: rgb(64 64 64 / var(--tw-border-opacity));
2169
+ }
2170
+
2019
2171
  .dark .dark\:border-gray-500 {
2020
2172
  --tw-border-opacity: 1;
2021
2173
  border-color: rgb(107 114 128 / var(--tw-border-opacity));
@@ -2066,9 +2218,14 @@ h6 {
2066
2218
  color: rgb(191 219 254 / var(--tw-text-opacity));
2067
2219
  }
2068
2220
 
2069
- .dark .dark\:text-gray-400 {
2221
+ .dark .dark\:text-neutral-50 {
2070
2222
  --tw-text-opacity: 1;
2071
- color: rgb(156 163 175 / var(--tw-text-opacity));
2223
+ color: rgb(250 250 250 / var(--tw-text-opacity));
2224
+ }
2225
+
2226
+ .dark .dark\:text-neutral-400 {
2227
+ --tw-text-opacity: 1;
2228
+ color: rgb(163 163 163 / var(--tw-text-opacity));
2072
2229
  }
2073
2230
 
2074
2231
  .dark .dark\:text-gray-200 {
@@ -2076,6 +2233,11 @@ h6 {
2076
2233
  color: rgb(229 231 235 / var(--tw-text-opacity));
2077
2234
  }
2078
2235
 
2236
+ .dark .dark\:text-gray-400 {
2237
+ --tw-text-opacity: 1;
2238
+ color: rgb(156 163 175 / var(--tw-text-opacity));
2239
+ }
2240
+
2079
2241
  .dark .dark\:text-gray-300 {
2080
2242
  --tw-text-opacity: 1;
2081
2243
  color: rgb(209 213 219 / var(--tw-text-opacity));
@@ -2239,3 +2401,9 @@ h6 {
2239
2401
  padding-right: 16rem;
2240
2402
  }
2241
2403
  }
2404
+
2405
+ @media (min-width: 1536px) {
2406
+ .\32xl\:break-words {
2407
+ overflow-wrap: break-word;
2408
+ }
2409
+ }
@@ -0,0 +1,15 @@
1
+ export default function getLinkFromTitle(title: string) {
2
+ return (
3
+ title
4
+ .toLowerCase()
5
+ .trim()
6
+ // not remove html tags
7
+ // .replace(/<[!\/a-z].*?>/gi, '')
8
+ // remove unwanted chars
9
+ .replace(
10
+ /[\u2000-\u206F\u2E00-\u2E7F\\'!!"#$%&()()*+,,.。/::;;<=>??@[\]^`{|}~]/g,
11
+ '',
12
+ )
13
+ .replace(/\s/g, '-')
14
+ );
15
+ }
@@ -0,0 +1,9 @@
1
+ export const getTocTitle = (title: string) => {
2
+ return title
3
+ .trim()
4
+ .replace(/\\{/g, '{')
5
+ .replace(/\\}/g, '}')
6
+ .replace(/[`]/g, '');
7
+ };
8
+
9
+ export default getTocTitle;
package/dist/compiler.js CHANGED
@@ -30,9 +30,16 @@ const rehypePrettyCodeOptions = {
30
30
  node.children = [{ type: 'text', value: ' ' }];
31
31
  }
32
32
  },
33
+ // 允许高亮代码行
34
+ // 对于高亮的代码行,设置为 highlighted 样式表类
33
35
  onVisitHighlightedLine(node) {
34
36
  node.properties.className.push('highlighted');
35
37
  },
38
+ // 允许高亮代码文字
39
+ // 对于高亮的代码文字,设置为 word 样式表类
40
+ onVisitHighlightedWord(node) {
41
+ node.properties.className = ['word'];
42
+ },
36
43
  };
37
44
  function compile(opts) {
38
45
  return __awaiter(this, void 0, void 0, function* () {
@@ -50,9 +57,14 @@ function MDXContent(props = {}) {
50
57
  useEffect(() => {
51
58
  if (window.location.hash.length !== 0) {
52
59
  const hash = window.location.hash;
53
- window.location.hash = '';
54
- window.location.hash = hash;
60
+ document.getElementById(hash.slice(1))?.scrollIntoView();
61
+ } else {
62
+ window.scrollTo(0, 0);
55
63
  }
64
+ document.getElementById('active-nav-item')?.scrollIntoView({
65
+ behavior: 'smooth',
66
+ block: 'center'
67
+ });
56
68
  }, []);
57
69
 
58
70
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umijs/plugin-docs",
3
- "version": "4.0.0-rc.13",
3
+ "version": "4.0.0-rc.14",
4
4
  "description": "@umijs/plugin-docs",
5
5
  "homepage": "https://github.com/umijs/umi-next/tree/master/packages/plugin-docs#readme",
6
6
  "bugs": "https://github.com/umijs/umi-next/issues",
@@ -19,11 +19,11 @@
19
19
  "scripts": {
20
20
  "build": "pnpm tsc",
21
21
  "build:css": "tailwindcss -i ./client/theme-doc/tailwind.css -o ./client/theme-doc/tailwind.out.css",
22
- "build:deps": "pnpm esno ../../scripts/bundleDeps.ts",
22
+ "build:deps": "umi-scripts bundleDeps",
23
23
  "build:extra": "pnpm build:css && pnpm build:deps",
24
24
  "dev": "pnpm build -- --watch",
25
25
  "dev:css": "pnpm build:css -- --watch",
26
- "test": "jest -c ../../jest.turbo.config.ts"
26
+ "test": "umi-scripts jest-turbo"
27
27
  },
28
28
  "dependencies": {
29
29
  "keymaster": "1.6.2",
@@ -39,7 +39,7 @@
39
39
  "rehype-slug": "5.0.1",
40
40
  "remark-gfm": "^3.0.1",
41
41
  "tailwindcss": "^3.0.23",
42
- "umi": "4.0.0-rc.13"
42
+ "umi": "4.0.0-rc.14"
43
43
  },
44
44
  "publishConfig": {
45
45
  "access": "public"