gis-view-webgl2 0.1.0 → 0.1.2
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 +40 -8
- package/dist/gis-view.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1036 -249
- package/dist/index.js +1 -1
- package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +194 -0
- package/docs/GisView.md +9 -8
- package/docs/GisView/345/256/236/347/216/260/345/216/237/347/220/206.md +2 -2
- package/docs/ai/06-/344/274/232/350/257/235/347/264/242/345/274/225/344/270/216/345/244/215/346/237/245/346/226/271/346/263/225.md +172 -0
- package/docs/api/index.html +545 -59
- package/docs/demos/BackendSyncDemo.vue +10 -8
- package/docs/demos/BasicDemo.vue +101 -101
- package/docs/demos/BatchAddDemo.vue +5 -5
- package/docs/demos/ChannelDemo.vue +617 -10
- package/docs/demos/ConnectDemo.vue +392 -0
- package/docs/demos/CopyMergeDemo.vue +980 -929
- package/docs/demos/DecorationDraftDemo.vue +1300 -0
- package/docs/demos/DemoShell.vue +569 -240
- package/docs/demos/DragDropDemo.vue +11 -11
- package/docs/demos/EffectsDemo.vue +6 -6
- package/docs/demos/EventDemo.vue +327 -327
- package/docs/demos/ExtensionDemo.vue +458 -0
- package/docs/demos/GisViewDemo.vue +61 -48
- package/docs/demos/GraphicDemo.vue +338 -0
- package/docs/demos/LabelDemo.vue +553 -497
- package/docs/demos/MinimapDemo.vue +358 -0
- package/docs/demos/PerfDemo.vue +29 -0
- package/docs/demos/SearchFilterDemo.vue +412 -0
- package/docs/demos/StyleDemo.vue +121 -121
- package/docs/demos/api-index.js +98 -77
- package/docs/demos/demos.js +159 -135
- package/docs/demos/shared/demoData.js +107 -107
- package/docs/demos/shared/demoStyle.css +249 -249
- package/docs/demos/shared/fakeBackend.js +93 -6
- package/docs/format/03-/346/213/220/347/202/271/350/243/205/351/245/260/344/270/216/346/240/267/345/274/217.md +28 -8
- package/docs/format/04-/351/200/232/351/201/223/344/270/216/346/240/207/347/255/276.md +5 -4
- package/docs/format/06-/345/257/274/345/205/245/345/257/274/345/207/272/344/270/216/346/240/207/345/207/206/346/226/207/346/241/243.md +8 -6
- package/docs/format/07-/344/272/213/344/273/266/350/275/275/350/215/267/344/270/216/347/244/272/344/276/213/346/225/260/346/215/256.md +6 -6
- package/docs/guide/sample-document.html +4 -4
- package/docs/index.html +180 -9
- package/docs/internals/11-/350/246/206/347/233/226/345/261/202/346/240/207/347/255/276/344/270/216/346/217/220/347/244/272.md +1 -1
- package/docs/internals/13-/351/271/260/347/234/274/345/233/276.md +3 -2
- package/docs/internals/15-03-/351/200/220/350/275/256/350/256/260/345/275/225-/346/200/247/350/203/275/344/270/216/344/277/256/345/244/215-/344/270/213.md +16 -0
- package/docs/internals/16-03-/344/274/230/345/214/226/344/270/216/345/217/226/350/210/215-/344/270/213.md +11 -0
- package/docs/internals/17-/350/260/203/350/257/225/344/270/216/346/211/251/345/261/225/345/273/272/350/256/256.md +1 -1
- package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +18 -4
- package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +110 -25
- package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +13 -8
- package/docs/manual/06-/346/225/260/346/215/256/344/270/216/345/234/272/346/231/257/346/233/264/346/226/260.md +111 -10
- package/docs/manual/07-/346/214/207/351/222/210/344/270/216/350/246/201/347/264/240/347/274/226/350/276/221.md +47 -9
- package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +17 -15
- package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +61 -11
- package/docs/manual/10-/351/200/232/351/201/223/347/274/226/350/276/221/344/270/216/346/226/260/345/242/236.md +74 -7
- package/docs/manual/11-/346/240/267/345/274/217/344/270/216/350/247/204/345/210/231.md +3 -2
- package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +260 -3
- package/docs/manual/13-/345/212/250/346/225/210/344/270/216/345/233/276/345/205/203.md +6 -5
- package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +27 -14
- package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +142 -49
- package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +31 -29
- package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +55 -39
- package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +189 -64
- package/docs/manual/19-/350/257/273/346/225/260/344/270/216/346/213/226/346/213/275/351/242/204/350/247/210.md +4 -4
- package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +42 -2
- package/docs/manual/21-/350/257/264/346/230/216/344/270/216/345/270/270/350/247/201/351/227/256/351/242/230.md +22 -6
- package/docs/playground/index.html +5 -5
- package/docs/steps/README.md +14 -10
- package/docs/steps/check-doc-truth.mjs +1 -1
- package/docs/steps/selftest-actions.html +10 -10
- package/docs/steps/selftest-data.html +96 -14
- package/docs/steps/selftest-decoration.html +577 -0
- package/docs/steps/selftest-demo.html +6 -5
- package/docs/steps/selftest-demos.html +2201 -1612
- package/docs/steps/selftest-docs.html +89 -16
- package/docs/steps/selftest-effects.html +5 -5
- package/docs/steps/selftest-features.html +757 -86
- package/docs/steps/selftest-full.html +583 -583
- package/docs/steps/selftest-labels.html +1034 -652
- package/docs/steps/selftest-perf.html +1899 -1844
- package/docs/steps/selftest-scale.html +117 -7
- package/docs/steps/selftest-select.html +24 -17
- package/docs/steps/step-10-full.js +1 -1
- package/docs//346/216/245/345/217/243/345/215/217/350/256/256.md +167 -17
- package/docs//346/225/260/346/215/256/346/240/274/345/274/217.md +1 -1
- package/package.json +43 -43
- package/docs/demos/HistoryDemo.vue +0 -230
- package/docs/demos/InterfaceDemo.vue +0 -309
- package/docs/demos/SampleDemo.vue +0 -283
package/docs/demos/DemoShell.vue
CHANGED
|
@@ -1,337 +1,666 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
/**
|
|
3
|
-
* 演示外壳:分组页签 + 一句说明 + 当前演示(动态组件)。
|
|
4
|
-
*
|
|
5
|
-
* 每个演示都是一个独立组件(BasicDemo / LabelDemo / ... / GisViewDemo),
|
|
6
|
-
* 切到哪个才 import 哪个 —— 综合示例那份最大,不点进去就不会下载。
|
|
7
|
-
* 组件卸载即销毁各自的视图(各演示自己 onBeforeUnmount destroy()),来回切不会漏画布。
|
|
8
|
-
*
|
|
9
|
-
* 外壳只管「怎么找演示」:页签按 DEMO_GROUPS 分组、每句说明旁边给一条对应文档的直达链接、
|
|
10
|
-
* 地址栏可点播(`?demo=labels`)、记不住地址就接着上次看的(localStorage),
|
|
11
|
-
* 键盘 `[` / `]` 前后翻页签(焦点在输入框里时不抢键)。
|
|
12
|
-
*/
|
|
13
|
-
import { computed, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'
|
|
14
|
-
import { DEFAULT_DEMO_ID, DEMO_GROUPS, DEMOS } from './demos.js'
|
|
15
|
-
|
|
16
|
-
const publicBase = String(import.meta.env?.BASE_URL ?? '/').replace(/\/?$/, '/')
|
|
17
|
-
/** 外壳顶部的五个常驻入口:看文档、查 API、跑步进代码、看拆解、跑自测,都不用先离开当前演示 */
|
|
18
|
-
const quickLinks = [
|
|
19
|
-
{ label: '文档中心', href: `${publicBase}docs/index.html`, title: '按章节阅读全部文档' },
|
|
20
|
-
{ label: 'API 速查', href: `${publicBase}docs/api/index.html`, title: '搜索实例方法、属性与 options' },
|
|
21
|
-
{ label: '调试页', href: `${publicBase}docs/playground/index.html`, title: '在可运行实例上改代码' },
|
|
22
|
-
{ label: '分步演示', href: `${publicBase}docs/steps/index.html`, title: '从空画布到完整组件的十三步' },
|
|
23
|
-
{ label: '自测', href: `${publicBase}docs/steps/selftest-demos.html`, title: '打开演示页的 PASS / FAIL 清单' }
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
/** 地址栏可以点播:`?demo=labels` 直接进标签演示(文档里给链接、自测页切页签都靠它) */
|
|
27
|
-
const requestedId = typeof window === 'undefined' ? '' : new URLSearchParams(window.location.search).get('demo')
|
|
28
|
-
/** 上次看过的演示:地址栏没点播时接着它;读不出来(隐私模式 / 禁掉存储)就当没记过 */
|
|
29
|
-
const DEMO_STORAGE_KEY = 'gis-view:last-demo'
|
|
30
|
-
const storedId = (() => {
|
|
31
|
-
try {
|
|
32
|
-
return window.localStorage.getItem(DEMO_STORAGE_KEY) ?? ''
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
return ''
|
|
36
|
-
}
|
|
37
|
-
})()
|
|
38
|
-
const currentId = ref(
|
|
39
|
-
DEMOS.some(item => item.id === requestedId) ? requestedId
|
|
40
|
-
: DEMOS.some(item => item.id === storedId) ? storedId
|
|
41
|
-
: DEFAULT_DEMO_ID
|
|
42
|
-
)
|
|
43
|
-
const current = computed(() => DEMOS.find(item => item.id === currentId.value) ?? DEMOS[0])
|
|
44
|
-
|
|
1
|
+
<script setup>
|
|
2
|
+
/**
|
|
3
|
+
* 演示外壳:分组页签 + 一句说明 + 当前演示(动态组件)。
|
|
4
|
+
*
|
|
5
|
+
* 每个演示都是一个独立组件(BasicDemo / LabelDemo / ... / GisViewDemo),
|
|
6
|
+
* 切到哪个才 import 哪个 —— 综合示例那份最大,不点进去就不会下载。
|
|
7
|
+
* 组件卸载即销毁各自的视图(各演示自己 onBeforeUnmount destroy()),来回切不会漏画布。
|
|
8
|
+
*
|
|
9
|
+
* 外壳只管「怎么找演示」:页签按 DEMO_GROUPS 分组、每句说明旁边给一条对应文档的直达链接、
|
|
10
|
+
* 地址栏可点播(`?demo=labels`)、记不住地址就接着上次看的(localStorage),
|
|
11
|
+
* 键盘 `[` / `]` 前后翻页签(焦点在输入框里时不抢键)。
|
|
12
|
+
*/
|
|
13
|
+
import { computed, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'
|
|
14
|
+
import { DEFAULT_DEMO_ID, DEMO_GROUPS, DEMOS } from './demos.js'
|
|
15
|
+
|
|
16
|
+
const publicBase = String(import.meta.env?.BASE_URL ?? '/').replace(/\/?$/, '/')
|
|
17
|
+
/** 外壳顶部的五个常驻入口:看文档、查 API、跑步进代码、看拆解、跑自测,都不用先离开当前演示 */
|
|
18
|
+
const quickLinks = [
|
|
19
|
+
{ label: '文档中心', href: `${publicBase}docs/index.html`, title: '按章节阅读全部文档' },
|
|
20
|
+
{ label: 'API 速查', href: `${publicBase}docs/api/index.html`, title: '搜索实例方法、属性与 options' },
|
|
21
|
+
{ label: '调试页', href: `${publicBase}docs/playground/index.html`, title: '在可运行实例上改代码' },
|
|
22
|
+
{ label: '分步演示', href: `${publicBase}docs/steps/index.html`, title: '从空画布到完整组件的十三步' },
|
|
23
|
+
{ label: '自测', href: `${publicBase}docs/steps/selftest-demos.html`, title: '打开演示页的 PASS / FAIL 清单' }
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
/** 地址栏可以点播:`?demo=labels` 直接进标签演示(文档里给链接、自测页切页签都靠它) */
|
|
27
|
+
const requestedId = typeof window === 'undefined' ? '' : new URLSearchParams(window.location.search).get('demo')
|
|
28
|
+
/** 上次看过的演示:地址栏没点播时接着它;读不出来(隐私模式 / 禁掉存储)就当没记过 */
|
|
29
|
+
const DEMO_STORAGE_KEY = 'gis-view:last-demo'
|
|
30
|
+
const storedId = (() => {
|
|
31
|
+
try {
|
|
32
|
+
return window.localStorage.getItem(DEMO_STORAGE_KEY) ?? ''
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return ''
|
|
36
|
+
}
|
|
37
|
+
})()
|
|
38
|
+
const currentId = ref(
|
|
39
|
+
DEMOS.some(item => item.id === requestedId) ? requestedId
|
|
40
|
+
: DEMOS.some(item => item.id === storedId) ? storedId
|
|
41
|
+
: DEFAULT_DEMO_ID
|
|
42
|
+
)
|
|
43
|
+
const current = computed(() => DEMOS.find(item => item.id === currentId.value) ?? DEMOS[0])
|
|
44
|
+
const currentIndex = computed(() => Math.max(0, DEMOS.findIndex(item => item.id === current.value.id)))
|
|
45
|
+
const currentGroup = computed(() => DEMO_GROUPS.find(group => group.id === current.value.group) ?? DEMO_GROUPS[0])
|
|
46
|
+
/** 上一个 / 下一步:按钮与键盘共用,到了头尾就绕回另一端 */
|
|
47
|
+
const stepDemo = (step) => {
|
|
48
|
+
const next = DEMOS[(currentIndex.value + step + DEMOS.length) % DEMOS.length]
|
|
49
|
+
currentId.value = next.id
|
|
50
|
+
}
|
|
51
|
+
/** 按 DEMO_GROUPS 的次序把演示分组:外壳一个循环画出「组名 + 组里的页签」 */
|
|
45
52
|
const groupedDemos = computed(() => DEMO_GROUPS
|
|
46
53
|
.map(group => ({ ...group, items: DEMOS.filter(item => item.group === group.id) }))
|
|
47
54
|
.filter(group => group.items.length > 0))
|
|
55
|
+
/** 分组按钮:切到该组的第一项;当前项本来就在这组时保持不动 */
|
|
56
|
+
const selectGroup = (group) => {
|
|
57
|
+
if (!group.items.some(item => item.id === currentId.value) && group.items[0]) {
|
|
58
|
+
currentId.value = group.items[0].id
|
|
59
|
+
}
|
|
60
|
+
}
|
|
48
61
|
const loaded = shallowRef(null)
|
|
49
62
|
const loading = ref(true)
|
|
63
|
+
const loadError = ref('')
|
|
50
64
|
let requestSeq = 0
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
/** 已经拉过的演示模块:切回来直接用缓存,失败的那一条删掉,重试时重新请求 */
|
|
66
|
+
const moduleCache = new Map()
|
|
67
|
+
const loadDemoModule = (demo) => {
|
|
68
|
+
let task = moduleCache.get(demo.id)
|
|
69
|
+
if (!task) {
|
|
70
|
+
task = Promise.resolve()
|
|
71
|
+
.then(() => demo.component())
|
|
72
|
+
.then(module => module.default ?? module)
|
|
73
|
+
moduleCache.set(demo.id, task)
|
|
74
|
+
task.catch(() => {
|
|
75
|
+
if (moduleCache.get(demo.id) === task) {
|
|
76
|
+
moduleCache.delete(demo.id)
|
|
77
|
+
}
|
|
78
|
+
})
|
|
60
79
|
}
|
|
61
|
-
|
|
62
|
-
loading.value = false
|
|
63
|
-
}, { immediate: true })
|
|
64
|
-
|
|
65
|
-
/** 组件自己报一句读数(比如「已加载 N 个节点」):外壳只负责显示,不掺和演示内部 */
|
|
66
|
-
const notice = ref('')
|
|
67
|
-
const notify = (text) => {
|
|
68
|
-
notice.value = text ?? ''
|
|
80
|
+
return task
|
|
69
81
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
watch(currentId, (id) => {
|
|
75
|
-
if (typeof window === 'undefined') {
|
|
82
|
+
/** 当前演示加载完之后,空闲时把前后两份也拉下来:首次切过去不用再等网络 */
|
|
83
|
+
let idleHandle = 0
|
|
84
|
+
const clearIdleWarmup = () => {
|
|
85
|
+
if (!idleHandle) {
|
|
76
86
|
return
|
|
77
87
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
window.history.replaceState(null, '', url)
|
|
81
|
-
try {
|
|
82
|
-
window.localStorage.setItem(DEMO_STORAGE_KEY, id)
|
|
88
|
+
if (typeof window.cancelIdleCallback === 'function') {
|
|
89
|
+
window.cancelIdleCallback(idleHandle)
|
|
83
90
|
}
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
else {
|
|
92
|
+
window.clearTimeout(idleHandle)
|
|
86
93
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const handleDemoKeys = (event) => {
|
|
93
|
-
if (event.defaultPrevented || event.ctrlKey || event.metaKey || event.altKey) {
|
|
94
|
+
idleHandle = 0
|
|
95
|
+
}
|
|
96
|
+
const warmAdjacentDemos = () => {
|
|
97
|
+
clearIdleWarmup()
|
|
98
|
+
if (typeof window === 'undefined') {
|
|
94
99
|
return
|
|
95
100
|
}
|
|
96
|
-
|
|
97
|
-
|
|
101
|
+
const run = () => {
|
|
102
|
+
idleHandle = 0
|
|
103
|
+
const next = DEMOS[(currentIndex.value + 1) % DEMOS.length]
|
|
104
|
+
const previous = DEMOS[(currentIndex.value - 1 + DEMOS.length) % DEMOS.length]
|
|
105
|
+
for (const demo of [next, previous]) {
|
|
106
|
+
if (demo && demo.id !== current.value.id) {
|
|
107
|
+
loadDemoModule(demo).catch(() => {})
|
|
108
|
+
}
|
|
109
|
+
}
|
|
98
110
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
111
|
+
idleHandle = typeof window.requestIdleCallback === 'function'
|
|
112
|
+
? window.requestIdleCallback(run, { timeout: 2500 })
|
|
113
|
+
: window.setTimeout(run, 600)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const loadCurrent = async () => {
|
|
117
|
+
clearIdleWarmup()
|
|
118
|
+
const seq = (requestSeq += 1)
|
|
119
|
+
loading.value = true
|
|
120
|
+
loadError.value = ''
|
|
121
|
+
loaded.value = null
|
|
122
|
+
try {
|
|
123
|
+
const component = await loadDemoModule(current.value)
|
|
124
|
+
// 加载期间用户又切了页签:这一份迟到的结果直接丢掉,别把当前演示顶掉
|
|
125
|
+
if (seq !== requestSeq) {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
loaded.value = component
|
|
129
|
+
loading.value = false
|
|
130
|
+
warmAdjacentDemos()
|
|
102
131
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
132
|
+
catch (error) {
|
|
133
|
+
if (seq !== requestSeq) {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
loadError.value = error instanceof Error ? error.message : String(error)
|
|
137
|
+
loading.value = false
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
watch(currentId, loadCurrent, { immediate: true })
|
|
141
|
+
/** 断网 / 部署路径写错这类失败之后不用刷新整页:清掉这一条的缓存再拉一次 */
|
|
142
|
+
const retryCurrent = () => {
|
|
143
|
+
moduleCache.delete(currentId.value)
|
|
144
|
+
loadCurrent()
|
|
107
145
|
}
|
|
146
|
+
|
|
147
|
+
/** 组件自己报一句读数(比如「已加载 N 个节点」):外壳只负责显示,不掺和演示内部 */
|
|
148
|
+
const notice = ref('')
|
|
149
|
+
const notify = (text) => {
|
|
150
|
+
notice.value = text ?? ''
|
|
151
|
+
}
|
|
152
|
+
// 切演示时把上一份的读数清掉,免得看着像新演示报的
|
|
153
|
+
watch(currentId, () => { notice.value = '' })
|
|
154
|
+
|
|
155
|
+
// 切页签时把当前演示写进地址栏:刷新 / 分享链接还停在同一个演示上
|
|
156
|
+
watch(currentId, (id) => {
|
|
157
|
+
if (typeof window === 'undefined') {
|
|
158
|
+
return
|
|
159
|
+
}
|
|
160
|
+
const url = new URL(window.location.href)
|
|
161
|
+
url.searchParams.set('demo', id)
|
|
162
|
+
window.history.replaceState(null, '', url)
|
|
163
|
+
try {
|
|
164
|
+
window.localStorage.setItem(DEMO_STORAGE_KEY, id)
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// 存不了就算了:只是少一次「接着上次看」的回忆
|
|
168
|
+
}
|
|
169
|
+
}, { immediate: true })
|
|
170
|
+
/**
|
|
171
|
+
* 键盘翻页签:`[` / `]` 前后一个(到头绕回)。焦点在输入框 / 可编辑元素里时不抢键 ——
|
|
172
|
+
* 演示面板里到处是输入框,抢键会让「打一个方括号」变成切演示。
|
|
173
|
+
*/
|
|
174
|
+
const handleDemoKeys = (event) => {
|
|
175
|
+
if (event.defaultPrevented || event.ctrlKey || event.metaKey || event.altKey) {
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
if (event.key !== '[' && event.key !== ']') {
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
const target = event.target
|
|
182
|
+
if (target instanceof HTMLElement && (target.isContentEditable || target.closest('input, textarea, select'))) {
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
const step = event.key === ']' ? 1 : -1
|
|
186
|
+
stepDemo(step)
|
|
187
|
+
}
|
|
108
188
|
onMounted(() => window.addEventListener('keydown', handleDemoKeys))
|
|
109
189
|
onBeforeUnmount(() => {
|
|
110
190
|
requestSeq += 1
|
|
191
|
+
clearIdleWarmup()
|
|
111
192
|
window.removeEventListener('keydown', handleDemoKeys)
|
|
112
193
|
})
|
|
113
194
|
</script>
|
|
114
195
|
|
|
115
196
|
<template>
|
|
116
|
-
<section class="demo-shell">
|
|
197
|
+
<section class="demo-shell" :aria-busy="loading">
|
|
117
198
|
<div class="demo-shell__sticky">
|
|
118
|
-
<nav class="demo-
|
|
119
|
-
<
|
|
199
|
+
<nav class="demo-shell__groups" aria-label="演示分组">
|
|
200
|
+
<button
|
|
201
|
+
v-for="group in groupedDemos"
|
|
202
|
+
:key="group.id"
|
|
203
|
+
type="button"
|
|
204
|
+
class="demo-shell__group-tab"
|
|
205
|
+
:class="{ 'demo-shell__group-tab--active': group.id === currentGroup.id }"
|
|
206
|
+
:aria-pressed="group.id === currentGroup.id"
|
|
207
|
+
:data-demo-group="group.id"
|
|
208
|
+
:title="`${group.label}(${group.items.length} 个演示)`"
|
|
209
|
+
@click="selectGroup(group)"
|
|
210
|
+
>
|
|
120
211
|
<span class="demo-shell__group-label">{{ group.label }}</span>
|
|
212
|
+
<span class="demo-shell__group-count">{{ group.items.length }}</span>
|
|
213
|
+
</button>
|
|
214
|
+
</nav>
|
|
215
|
+
<nav class="demo-shell__tabs" aria-label="当前分组的演示">
|
|
216
|
+
<div
|
|
217
|
+
v-for="group in groupedDemos"
|
|
218
|
+
:key="group.id"
|
|
219
|
+
class="demo-shell__group"
|
|
220
|
+
:class="{ 'demo-shell__group--active': group.id === currentGroup.id }"
|
|
221
|
+
>
|
|
121
222
|
<button
|
|
122
|
-
v-for="item in group.items"
|
|
123
|
-
:key="item.id"
|
|
124
|
-
type="button"
|
|
125
|
-
class="demo-shell__tab"
|
|
126
|
-
:class="{ 'demo-shell__tab--active': item.id === currentId }"
|
|
127
|
-
:aria-current="item.id === currentId ? 'page' : undefined"
|
|
128
|
-
:title="item.blurb"
|
|
129
|
-
@click="currentId = item.id"
|
|
130
|
-
>
|
|
223
|
+
v-for="item in group.items"
|
|
224
|
+
:key="item.id"
|
|
225
|
+
type="button"
|
|
226
|
+
class="demo-shell__tab"
|
|
227
|
+
:class="{ 'demo-shell__tab--active': item.id === currentId }"
|
|
228
|
+
:aria-current="item.id === currentId ? 'page' : undefined"
|
|
229
|
+
:title="item.blurb"
|
|
230
|
+
@click="currentId = item.id"
|
|
231
|
+
>
|
|
131
232
|
{{ item.title }}
|
|
132
233
|
</button>
|
|
133
234
|
</div>
|
|
134
|
-
</nav>
|
|
135
|
-
<div class="demo-shell__quick" aria-label="快捷入口">
|
|
136
|
-
<span class="demo-shell__quick-label">快速入口</span>
|
|
137
|
-
<a
|
|
138
|
-
v-for="link in quickLinks"
|
|
139
|
-
:key="link.href"
|
|
140
|
-
class="demo-shell__quick-link"
|
|
141
|
-
:href="link.href"
|
|
142
|
-
:title="link.title"
|
|
143
|
-
target="_blank"
|
|
144
|
-
rel="noreferrer"
|
|
145
|
-
>{{ link.label }}</a>
|
|
146
|
-
</div>
|
|
147
|
-
</div>
|
|
148
|
-
<p class="demo-shell__blurb">
|
|
149
|
-
<
|
|
150
|
-
<
|
|
151
|
-
<span
|
|
152
|
-
<
|
|
153
|
-
|
|
235
|
+
</nav>
|
|
236
|
+
<div class="demo-shell__quick" aria-label="快捷入口">
|
|
237
|
+
<span class="demo-shell__quick-label">快速入口</span>
|
|
238
|
+
<a
|
|
239
|
+
v-for="link in quickLinks"
|
|
240
|
+
:key="link.href"
|
|
241
|
+
class="demo-shell__quick-link"
|
|
242
|
+
:href="link.href"
|
|
243
|
+
:title="link.title"
|
|
244
|
+
target="_blank"
|
|
245
|
+
rel="noreferrer"
|
|
246
|
+
>{{ link.label }}</a>
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
<p class="demo-shell__blurb">
|
|
250
|
+
<span class='demo-shell__eyebrow'>{{ currentGroup.label }} · {{ currentIndex + 1 }} / {{ DEMOS.length }}</span>
|
|
251
|
+
<strong>{{ current.title }}</strong>
|
|
252
|
+
<span>{{ current.blurb }}</span>
|
|
253
|
+
<span class='demo-shell__step'>
|
|
254
|
+
<button type='button' class='demo-shell__step-btn' data-demo='demo-prev' title='上一个演示([)' @click='stepDemo(-1)'>← 上一项</button>
|
|
255
|
+
<button type='button' class='demo-shell__step-btn' data-demo='demo-next' title='下一个演示(])' @click='stepDemo(1)'>下一项 →</button>
|
|
256
|
+
</span>
|
|
257
|
+
<span v-if="notice" class="demo-shell__notice">{{ notice }}</span>
|
|
258
|
+
<a class="demo-shell__doc" :href="current.doc.href" target="_blank" rel="noreferrer">对应文档 · {{ current.doc.label }}</a>
|
|
259
|
+
<span class="demo-shell__keys">[ / ] 切换</span>
|
|
260
|
+
</p>
|
|
261
|
+
<component :is="loaded" v-if="loaded" :key="current.id" @notice="notify" />
|
|
262
|
+
<p v-else-if="loading" class="demo-shell__loading" aria-live="polite">
|
|
263
|
+
<span class="demo-shell__spinner" aria-hidden="true"></span>
|
|
264
|
+
正在加载「{{ current.title }}」…
|
|
154
265
|
</p>
|
|
155
|
-
<
|
|
156
|
-
|
|
266
|
+
<div v-else-if="loadError" class="demo-shell__error" role="alert">
|
|
267
|
+
<strong>「{{ current.title }}」加载失败</strong>
|
|
268
|
+
<p>{{ loadError }}</p>
|
|
269
|
+
<button type="button" class="demo-shell__retry" @click="retryCurrent">重新加载</button>
|
|
270
|
+
<span class="demo-shell__error-hint">检查网络或部署路径后重试,不会影响其它页签。</span>
|
|
271
|
+
</div>
|
|
157
272
|
</section>
|
|
158
273
|
</template>
|
|
159
|
-
|
|
160
|
-
<style scoped>
|
|
161
|
-
.demo-shell {
|
|
162
|
-
min-width: 0;
|
|
163
|
-
max-width: 100%;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.demo-shell__sticky {
|
|
167
|
-
position: sticky;
|
|
168
|
-
top: 0;
|
|
169
|
-
z-index: 20;
|
|
274
|
+
|
|
275
|
+
<style scoped>
|
|
276
|
+
.demo-shell {
|
|
277
|
+
min-width: 0;
|
|
278
|
+
max-width: 100%;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.demo-shell__sticky {
|
|
282
|
+
position: sticky;
|
|
283
|
+
top: 0;
|
|
284
|
+
z-index: 20;
|
|
285
|
+
display: flex;
|
|
286
|
+
flex-direction: column;
|
|
287
|
+
gap: 6px;
|
|
288
|
+
min-width: 0;
|
|
289
|
+
max-width: 100%;
|
|
290
|
+
margin: -4px -10px 9px;
|
|
291
|
+
padding: 8px 10px 9px;
|
|
292
|
+
border: 1px solid rgba(214, 224, 236, 0.9);
|
|
293
|
+
border-radius: 10px;
|
|
294
|
+
background: rgba(244, 247, 251, 0.94);
|
|
295
|
+
box-shadow: 0 6px 22px rgba(31, 62, 105, 0.1);
|
|
296
|
+
backdrop-filter: blur(10px);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.demo-shell__tabs {
|
|
170
300
|
display: flex;
|
|
171
|
-
|
|
301
|
+
align-items: center;
|
|
172
302
|
gap: 6px;
|
|
173
303
|
min-width: 0;
|
|
174
304
|
max-width: 100%;
|
|
175
|
-
|
|
176
|
-
padding: 8px 10px 9px;
|
|
177
|
-
border: 1px solid rgba(214, 224, 236, 0.9);
|
|
178
|
-
border-radius: 10px;
|
|
179
|
-
background: rgba(244, 247, 251, 0.94);
|
|
180
|
-
box-shadow: 0 6px 22px rgba(31, 62, 105, 0.1);
|
|
181
|
-
backdrop-filter: blur(10px);
|
|
305
|
+
padding-top: 2px;
|
|
182
306
|
}
|
|
183
307
|
|
|
184
|
-
.demo-
|
|
308
|
+
.demo-shell__groups {
|
|
185
309
|
display: flex;
|
|
186
310
|
align-items: center;
|
|
187
311
|
flex-wrap: wrap;
|
|
188
|
-
gap:
|
|
312
|
+
gap: 4px;
|
|
189
313
|
min-width: 0;
|
|
190
|
-
max-width: 100%;
|
|
191
314
|
}
|
|
192
315
|
|
|
193
|
-
.demo-shell__group {
|
|
194
|
-
display: flex;
|
|
316
|
+
.demo-shell__group-tab {
|
|
317
|
+
display: inline-flex;
|
|
195
318
|
align-items: center;
|
|
196
319
|
gap: 6px;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
.demo-shell__group-label {
|
|
200
|
-
padding: 1px 7px;
|
|
201
|
-
border-radius: 4px;
|
|
202
|
-
background: #eef2f7;
|
|
203
|
-
color: #8a9ab4;
|
|
204
|
-
font-size: 11px;
|
|
205
|
-
line-height: 18px;
|
|
206
|
-
white-space: nowrap;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.demo-shell__tab {
|
|
210
|
-
padding: 7px 13px;
|
|
320
|
+
padding: 3px 9px 3px 7px;
|
|
211
321
|
border: 1px solid #d6e0ec;
|
|
212
322
|
border-radius: 999px;
|
|
213
323
|
background: #fff;
|
|
214
|
-
color:
|
|
215
|
-
font
|
|
324
|
+
color: var(--demo-group);
|
|
325
|
+
font: inherit;
|
|
326
|
+
font-size: 12px;
|
|
327
|
+
line-height: 1.6;
|
|
216
328
|
cursor: pointer;
|
|
329
|
+
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
|
|
217
330
|
}
|
|
218
331
|
|
|
219
|
-
.demo-
|
|
220
|
-
|
|
332
|
+
.demo-shell__group-tab:hover {
|
|
333
|
+
border-color: var(--demo-group);
|
|
334
|
+
background: var(--demo-group-soft);
|
|
221
335
|
}
|
|
222
336
|
|
|
223
|
-
.demo-
|
|
224
|
-
border-color:
|
|
225
|
-
background:
|
|
337
|
+
.demo-shell__group-tab--active {
|
|
338
|
+
border-color: var(--demo-group);
|
|
339
|
+
background: var(--demo-group);
|
|
226
340
|
color: #fff;
|
|
227
341
|
font-weight: 600;
|
|
228
342
|
}
|
|
229
343
|
|
|
230
|
-
.demo-
|
|
231
|
-
|
|
344
|
+
.demo-shell__group-tab:nth-child(1) {
|
|
345
|
+
--demo-group: #3678bf;
|
|
346
|
+
--demo-group-soft: #eaf2fc;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.demo-shell__group-tab:nth-child(2) {
|
|
350
|
+
--demo-group: #2f8668;
|
|
351
|
+
--demo-group-soft: #e7f5ef;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.demo-shell__group-tab:nth-child(3) {
|
|
355
|
+
--demo-group: #7959bd;
|
|
356
|
+
--demo-group-soft: #f0ebfb;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.demo-shell__group-tab:nth-child(4) {
|
|
360
|
+
--demo-group: #a86418;
|
|
361
|
+
--demo-group-soft: #fbf1e4;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.demo-shell__group-tab:nth-child(5) {
|
|
365
|
+
--demo-group: #b24b5d;
|
|
366
|
+
--demo-group-soft: #fbecef;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.demo-shell__group-tab:nth-child(6) {
|
|
370
|
+
--demo-group: #4c5f91;
|
|
371
|
+
--demo-group-soft: #ebeff7;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.demo-shell__group {
|
|
375
|
+
display: none;
|
|
232
376
|
align-items: center;
|
|
233
377
|
flex-wrap: wrap;
|
|
234
|
-
gap:
|
|
235
|
-
|
|
236
|
-
|
|
378
|
+
gap: 6px;
|
|
379
|
+
--demo-group: #3678bf;
|
|
380
|
+
--demo-group-soft: #eaf2fc;
|
|
237
381
|
}
|
|
238
382
|
|
|
239
|
-
.demo-
|
|
240
|
-
|
|
241
|
-
color: #93a2b9;
|
|
242
|
-
font-size: 11px;
|
|
243
|
-
white-space: nowrap;
|
|
383
|
+
.demo-shell__group--active {
|
|
384
|
+
display: flex;
|
|
244
385
|
}
|
|
245
|
-
|
|
246
|
-
.demo-
|
|
247
|
-
|
|
386
|
+
|
|
387
|
+
.demo-shell__group:nth-child(1) {
|
|
388
|
+
--demo-group: #3678bf;
|
|
389
|
+
--demo-group-soft: #eaf2fc;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.demo-shell__group:nth-child(2) {
|
|
393
|
+
--demo-group: #2f8668;
|
|
394
|
+
--demo-group-soft: #e7f5ef;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.demo-shell__group:nth-child(3) {
|
|
398
|
+
--demo-group: #7959bd;
|
|
399
|
+
--demo-group-soft: #f0ebfb;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.demo-shell__group:nth-child(4) {
|
|
403
|
+
--demo-group: #a86418;
|
|
404
|
+
--demo-group-soft: #fbf1e4;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.demo-shell__group:nth-child(5) {
|
|
408
|
+
--demo-group: #b24b5d;
|
|
409
|
+
--demo-group-soft: #fbecef;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.demo-shell__group:nth-child(6) {
|
|
413
|
+
--demo-group: #4c5f91;
|
|
414
|
+
--demo-group-soft: #ebeff7;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.demo-shell__group-count {
|
|
418
|
+
min-width: 16px;
|
|
419
|
+
padding: 0 4px;
|
|
248
420
|
border-radius: 999px;
|
|
249
|
-
background:
|
|
250
|
-
color:
|
|
251
|
-
font-size:
|
|
252
|
-
|
|
253
|
-
|
|
421
|
+
background: var(--demo-group-soft);
|
|
422
|
+
color: var(--demo-group);
|
|
423
|
+
font-size: 10px;
|
|
424
|
+
line-height: 16px;
|
|
425
|
+
text-align: center;
|
|
426
|
+
font-variant-numeric: tabular-nums;
|
|
254
427
|
}
|
|
255
428
|
|
|
256
|
-
.demo-
|
|
257
|
-
background:
|
|
429
|
+
.demo-shell__group-tab--active .demo-shell__group-count {
|
|
430
|
+
background: rgba(255, 255, 255, 0.2);
|
|
258
431
|
color: #fff;
|
|
259
432
|
}
|
|
260
|
-
|
|
261
|
-
.demo-
|
|
433
|
+
|
|
434
|
+
.demo-shell__tab {
|
|
435
|
+
padding: 7px 13px;
|
|
436
|
+
border: 1px solid #d6e0ec;
|
|
437
|
+
border-radius: 999px;
|
|
438
|
+
background: #fff;
|
|
439
|
+
color: var(--demo-group);
|
|
440
|
+
font-size: 13px;
|
|
441
|
+
cursor: pointer;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.demo-shell__tab:hover {
|
|
445
|
+
background: var(--demo-group-soft);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.demo-shell__tab--active {
|
|
449
|
+
border-color: var(--demo-group);
|
|
450
|
+
background: var(--demo-group);
|
|
451
|
+
color: #fff;
|
|
452
|
+
font-weight: 600;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.demo-shell__quick {
|
|
456
|
+
display: flex;
|
|
457
|
+
align-items: center;
|
|
458
|
+
flex-wrap: wrap;
|
|
459
|
+
gap: 5px;
|
|
460
|
+
padding-top: 6px;
|
|
461
|
+
border-top: 1px dashed #dce6f1;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.demo-shell__quick-label {
|
|
465
|
+
margin-right: 2px;
|
|
466
|
+
color: #93a2b9;
|
|
467
|
+
font-size: 11px;
|
|
468
|
+
white-space: nowrap;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.demo-shell__quick-link {
|
|
472
|
+
padding: 2px 8px;
|
|
473
|
+
border-radius: 999px;
|
|
474
|
+
background: #eaf2fc;
|
|
475
|
+
color: #2f5e94;
|
|
476
|
+
font-size: 11px;
|
|
477
|
+
text-decoration: none;
|
|
478
|
+
transition: background 0.12s ease, color 0.12s ease;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.demo-shell__quick-link:hover {
|
|
482
|
+
background: #3678bf;
|
|
483
|
+
color: #fff;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
.demo-shell__blurb {
|
|
487
|
+
display: flex;
|
|
488
|
+
align-items: baseline;
|
|
489
|
+
flex-wrap: wrap;
|
|
490
|
+
gap: 8px;
|
|
491
|
+
margin: 0 0 12px;
|
|
492
|
+
color: #71809d;
|
|
493
|
+
font-size: 13px;
|
|
494
|
+
line-height: 1.6;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.demo-shell__blurb strong {
|
|
498
|
+
color: #17233d;
|
|
499
|
+
font-size: 14px;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.demo-shell__eyebrow {
|
|
503
|
+
padding: 1px 8px;
|
|
504
|
+
border-radius: 999px;
|
|
505
|
+
background: #eaf2fc;
|
|
506
|
+
color: #5a7296;
|
|
507
|
+
font-size: 11px;
|
|
508
|
+
line-height: 1.8;
|
|
509
|
+
font-variant-numeric: tabular-nums;
|
|
510
|
+
white-space: nowrap;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.demo-shell__step {
|
|
514
|
+
display: inline-flex;
|
|
515
|
+
gap: 4px;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
.demo-shell__step-btn {
|
|
519
|
+
padding: 2px 8px;
|
|
520
|
+
border: 1px solid #d6e0ec;
|
|
521
|
+
border-radius: 999px;
|
|
522
|
+
background: #fff;
|
|
523
|
+
color: #2f5e94;
|
|
524
|
+
font-size: 11px;
|
|
525
|
+
line-height: 1.7;
|
|
526
|
+
cursor: pointer;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.demo-shell__step-btn:hover {
|
|
530
|
+
background: #eef4fc;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.demo-shell__notice {
|
|
534
|
+
padding: 2px 8px;
|
|
535
|
+
border-radius: 999px;
|
|
536
|
+
background: #eaf2fc;
|
|
537
|
+
color: #2f5e94;
|
|
538
|
+
font-size: 11px;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
.demo-shell__doc {
|
|
542
|
+
color: #3678bf;
|
|
543
|
+
font-size: 12px;
|
|
544
|
+
text-decoration: none;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.demo-shell__doc:hover {
|
|
548
|
+
text-decoration: underline;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
.demo-shell__keys {
|
|
552
|
+
margin-left: auto;
|
|
553
|
+
padding: 1px 8px;
|
|
554
|
+
border: 1px solid #e2e8f1;
|
|
555
|
+
border-radius: 999px;
|
|
556
|
+
color: #9aa7bc;
|
|
557
|
+
font-size: 11px;
|
|
558
|
+
white-space: nowrap;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
.demo-shell__loading {
|
|
262
562
|
display: flex;
|
|
263
|
-
align-items:
|
|
264
|
-
|
|
265
|
-
gap:
|
|
266
|
-
margin: 0
|
|
267
|
-
|
|
563
|
+
align-items: center;
|
|
564
|
+
justify-content: center;
|
|
565
|
+
gap: 9px;
|
|
566
|
+
margin: 0;
|
|
567
|
+
padding: 28px;
|
|
568
|
+
border: 1px dashed #d6e0ec;
|
|
569
|
+
border-radius: 10px;
|
|
570
|
+
background: #fff;
|
|
571
|
+
color: #8191a8;
|
|
572
|
+
font-size: 13px;
|
|
573
|
+
text-align: center;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
.demo-shell__spinner {
|
|
577
|
+
width: 14px;
|
|
578
|
+
height: 14px;
|
|
579
|
+
border: 2px solid #c8d9ee;
|
|
580
|
+
border-top-color: #3678bf;
|
|
581
|
+
border-radius: 50%;
|
|
582
|
+
animation: demo-shell-spin 0.7s linear infinite;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
@keyframes demo-shell-spin {
|
|
586
|
+
to {
|
|
587
|
+
transform: rotate(1turn);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.demo-shell__error {
|
|
592
|
+
margin: 0;
|
|
593
|
+
padding: 20px;
|
|
594
|
+
border: 1px solid #efcccc;
|
|
595
|
+
border-radius: 10px;
|
|
596
|
+
background: #fff8f8;
|
|
597
|
+
color: #874242;
|
|
268
598
|
font-size: 13px;
|
|
269
|
-
line-height: 1.
|
|
599
|
+
line-height: 1.7;
|
|
270
600
|
}
|
|
271
601
|
|
|
272
|
-
.demo-
|
|
273
|
-
color: #
|
|
602
|
+
.demo-shell__error strong {
|
|
603
|
+
color: #9c2f2f;
|
|
274
604
|
font-size: 14px;
|
|
275
605
|
}
|
|
276
606
|
|
|
277
|
-
.demo-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
font-size: 11px;
|
|
607
|
+
.demo-shell__error p {
|
|
608
|
+
margin: 6px 0 12px;
|
|
609
|
+
font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
|
|
610
|
+
font-size: 12px;
|
|
611
|
+
overflow-wrap: anywhere;
|
|
283
612
|
}
|
|
284
613
|
|
|
285
|
-
.demo-
|
|
286
|
-
|
|
614
|
+
.demo-shell__retry {
|
|
615
|
+
padding: 6px 13px;
|
|
616
|
+
border: 1px solid #b84949;
|
|
617
|
+
border-radius: 999px;
|
|
618
|
+
background: #b84949;
|
|
619
|
+
color: #fff;
|
|
287
620
|
font-size: 12px;
|
|
288
|
-
|
|
621
|
+
cursor: pointer;
|
|
289
622
|
}
|
|
290
623
|
|
|
291
|
-
.demo-
|
|
292
|
-
|
|
624
|
+
.demo-shell__retry:hover {
|
|
625
|
+
background: #9e3939;
|
|
293
626
|
}
|
|
294
627
|
|
|
295
|
-
.demo-
|
|
296
|
-
margin-left:
|
|
297
|
-
|
|
298
|
-
border: 1px solid #e2e8f1;
|
|
299
|
-
border-radius: 999px;
|
|
300
|
-
color: #9aa7bc;
|
|
628
|
+
.demo-shell__error-hint {
|
|
629
|
+
margin-left: 10px;
|
|
630
|
+
color: #a46d6d;
|
|
301
631
|
font-size: 11px;
|
|
302
|
-
white-space: nowrap;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
.demo-shell__loading {
|
|
306
|
-
margin: 0;
|
|
307
|
-
padding: 28px;
|
|
308
|
-
border: 1px dashed #d6e0ec;
|
|
309
|
-
border-radius: 10px;
|
|
310
|
-
background: #fff;
|
|
311
|
-
color: #8191a8;
|
|
312
|
-
font-size: 13px;
|
|
313
|
-
text-align: center;
|
|
314
632
|
}
|
|
315
633
|
|
|
316
634
|
@media (max-width: 760px) {
|
|
317
|
-
.demo-shell__sticky {
|
|
318
|
-
position: static;
|
|
319
|
-
margin: -4px 0 9px;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
.demo-
|
|
635
|
+
.demo-shell__sticky {
|
|
636
|
+
position: static;
|
|
637
|
+
margin: -4px 0 9px;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
.demo-shell__groups {
|
|
323
641
|
flex-wrap: nowrap;
|
|
324
642
|
width: 100%;
|
|
325
643
|
overflow-x: auto;
|
|
326
644
|
padding-bottom: 3px;
|
|
327
645
|
}
|
|
328
646
|
|
|
329
|
-
.demo-shell__group {
|
|
647
|
+
.demo-shell__group-tab {
|
|
330
648
|
flex: none;
|
|
331
649
|
}
|
|
332
650
|
|
|
333
|
-
.demo-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
651
|
+
.demo-shell__tabs {
|
|
652
|
+
flex-wrap: nowrap;
|
|
653
|
+
width: 100%;
|
|
654
|
+
overflow-x: auto;
|
|
655
|
+
padding-bottom: 3px;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
.demo-shell__group {
|
|
659
|
+
flex: none;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
.demo-shell__keys {
|
|
663
|
+
margin-left: 0;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
</style>
|