@363045841yyt/klinechart 0.8.0 → 0.8.1-alpha.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.
@@ -0,0 +1,478 @@
1
+ <template>
2
+ <div ref="chipWrapRef" class="symbol-chip-wrap">
3
+ <button
4
+ type="button"
5
+ class="symbol-chip"
6
+ :class="{ 'is-open': showPopup }"
7
+ :title="symbol"
8
+ :aria-expanded="showPopup"
9
+ aria-haspopup="dialog"
10
+ @click="togglePopup"
11
+ >
12
+ <span class="symbol-chip__code">{{ symbol }}</span>
13
+ <span v-if="loading" class="symbol-chip__spinner" aria-hidden="true" />
14
+ <IconTablerAlertTriangle v-else-if="error" class="symbol-chip__warn" aria-hidden="true" />
15
+ </button>
16
+ <Transition name="symbol-popover">
17
+ <div v-if="showPopup" class="symbol-popover" role="dialog" aria-label="切换合约">
18
+ <div class="symbol-search">
19
+ <span class="symbol-search__icon" aria-hidden="true">
20
+ <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
21
+ <circle cx="6.5" cy="6.5" r="5" stroke="currentColor" stroke-width="1.6" />
22
+ <line
23
+ x1="10.5"
24
+ y1="10.5"
25
+ x2="14.5"
26
+ y2="14.5"
27
+ stroke="currentColor"
28
+ stroke-width="1.6"
29
+ stroke-linecap="round"
30
+ />
31
+ </svg>
32
+ </span>
33
+ <input
34
+ ref="searchInputRef"
35
+ v-model="searchQuery"
36
+ class="symbol-search__input"
37
+ type="text"
38
+ placeholder="搜索代码或名称…"
39
+ autocomplete="off"
40
+ spellcheck="false"
41
+ aria-label="搜索商品"
42
+ @input="onSearchInput"
43
+ />
44
+ <button
45
+ v-if="searchQuery"
46
+ type="button"
47
+ class="symbol-search__clear"
48
+ aria-label="清空搜索"
49
+ @click="clearSearch"
50
+ >
51
+ <svg class="delete-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
52
+ <path d="M3 6h18" />
53
+ <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
54
+ <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
55
+ </svg>
56
+ </button>
57
+ </div>
58
+
59
+ <div class="symbol-list" role="listbox" aria-label="商品列表">
60
+ <div v-if="filteredSymbols.length === 0" class="symbol-list__empty">
61
+ <svg
62
+ width="32"
63
+ height="32"
64
+ viewBox="0 0 32 32"
65
+ fill="none"
66
+ style="margin-bottom: 8px; opacity: 0.35"
67
+ >
68
+ <circle cx="13" cy="13" r="10" stroke="currentColor" stroke-width="2" />
69
+ <line
70
+ x1="21"
71
+ y1="21"
72
+ x2="29"
73
+ y2="29"
74
+ stroke="currentColor"
75
+ stroke-width="2"
76
+ stroke-linecap="round"
77
+ />
78
+ </svg>
79
+ <span>未找到相关商品</span>
80
+ </div>
81
+ <button
82
+ v-for="item in filteredSymbols"
83
+ :key="item.code"
84
+ type="button"
85
+ class="symbol-list__item"
86
+ :class="{ 'is-active': item.code === symbol }"
87
+ role="option"
88
+ :aria-selected="item.code === symbol"
89
+ @click="selectSymbol(item)"
90
+ >
91
+ <span class="symbol-list__left">
92
+ <span class="symbol-list__code">{{ item.code }}</span>
93
+ <span class="symbol-list__desc">{{ item.description }}</span>
94
+ </span>
95
+ <span class="symbol-list__exchange">{{ item.exchange }}</span>
96
+ </button>
97
+ </div>
98
+ </div>
99
+ </Transition>
100
+ </div>
101
+ </template>
102
+
103
+ <script setup lang="ts">
104
+ import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'
105
+ import IconTablerAlertTriangle from '~icons/tabler/alert-triangle'
106
+
107
+ export interface SymbolItem {
108
+ code: string
109
+ description: string
110
+ exchange: string
111
+ source: string
112
+ }
113
+
114
+ const props = defineProps<{
115
+ symbol: string
116
+ symbols: SymbolItem[]
117
+ loading?: boolean
118
+ error?: boolean
119
+ }>()
120
+
121
+ const emit = defineEmits<{
122
+ (e: 'change', symbol: SymbolItem): void
123
+ }>()
124
+
125
+ const showPopup = ref(false)
126
+ const searchQuery = ref('')
127
+ const searchInputRef = ref<HTMLInputElement | null>(null)
128
+ const chipWrapRef = ref<HTMLElement | null>(null)
129
+
130
+ const filteredSymbols = computed<SymbolItem[]>(() => {
131
+ const q = searchQuery.value.trim().toLowerCase()
132
+ if (!q) return props.symbols
133
+ return props.symbols.filter(
134
+ (s) =>
135
+ s.code.toLowerCase().includes(q) ||
136
+ s.description.toLowerCase().includes(q) ||
137
+ s.exchange.toLowerCase().includes(q),
138
+ )
139
+ })
140
+
141
+ function togglePopup() {
142
+ showPopup.value = !showPopup.value
143
+ if (showPopup.value) {
144
+ nextTick(() => searchInputRef.value?.focus())
145
+ }
146
+ }
147
+
148
+ function clearSearch() {
149
+ searchQuery.value = ''
150
+ searchInputRef.value?.focus()
151
+ }
152
+
153
+ function onSearchInput() {
154
+ }
155
+
156
+ function selectSymbol(item: SymbolItem) {
157
+ emit('change', item)
158
+ showPopup.value = false
159
+ searchQuery.value = ''
160
+ }
161
+
162
+ function onDocumentClick(e: MouseEvent) {
163
+ if (chipWrapRef.value && !chipWrapRef.value.contains(e.target as Node)) {
164
+ showPopup.value = false
165
+ }
166
+ }
167
+
168
+ onMounted(() => document.addEventListener('mousedown', onDocumentClick))
169
+ onBeforeUnmount(() => document.removeEventListener('mousedown', onDocumentClick))
170
+
171
+ watch(() => props.symbol, () => {
172
+ showPopup.value = false
173
+ searchQuery.value = ''
174
+ })
175
+ </script>
176
+
177
+ <style scoped>
178
+ .symbol-chip-wrap {
179
+ position: relative;
180
+ display: inline-flex;
181
+ flex: 0 0 auto;
182
+ }
183
+
184
+ .symbol-chip {
185
+ height: 28px;
186
+ display: inline-flex;
187
+ align-items: center;
188
+ justify-content: center;
189
+ max-width: 160px;
190
+ padding: 0 10px;
191
+ gap: 5px;
192
+ border: 1px solid transparent;
193
+ border-radius: 4px;
194
+ background: transparent;
195
+ color: var(--klc-color-foreground);
196
+ font: inherit;
197
+ cursor: pointer;
198
+ transition:
199
+ background 0.15s ease,
200
+ border-color 0.15s ease,
201
+ color 0.15s ease;
202
+ }
203
+
204
+ .symbol-chip:hover,
205
+ .symbol-chip.is-open {
206
+ border-color: var(--klc-color-border-button);
207
+ background: var(--klc-color-grid-minor);
208
+ }
209
+
210
+ .symbol-chip.is-open .symbol-chip__arrow {
211
+ transform: rotate(180deg);
212
+ }
213
+
214
+ .symbol-chip__code {
215
+ overflow: hidden;
216
+ text-overflow: ellipsis;
217
+ white-space: nowrap;
218
+ font-size: 14px;
219
+ font-weight: 600;
220
+ line-height: 1;
221
+ letter-spacing: 0.01em;
222
+ }
223
+
224
+ .symbol-chip__arrow {
225
+ color: var(--klc-color-axis-text);
226
+ font-size: 12px;
227
+ line-height: 1;
228
+ transition: transform 0.15s ease;
229
+ }
230
+
231
+ .symbol-popover {
232
+ position: absolute;
233
+ top: calc(100% + 8px);
234
+ left: 0;
235
+ z-index: 20;
236
+ width: min(320px, calc(100vw - 24px));
237
+ padding: 14px;
238
+ border: 1px solid var(--klc-color-border-button);
239
+ border-radius: 3px;
240
+ background: var(--klc-color-tag-bg-white);
241
+ color: var(--klc-color-foreground);
242
+
243
+ box-sizing: border-box;
244
+ display: flex;
245
+ flex-direction: column;
246
+ gap: 10px;
247
+ }
248
+
249
+ .symbol-search {
250
+ position: relative;
251
+ display: flex;
252
+ align-items: center;
253
+ gap: 6px;
254
+ padding: 0 10px;
255
+ height: 32px;
256
+ border: 1px solid var(--klc-color-border-button);
257
+ border-radius: 8px;
258
+ background: var(--klc-color-background);
259
+ transition:
260
+ border-color 0.15s ease,
261
+ box-shadow 0.15s ease;
262
+ }
263
+
264
+ .symbol-search:focus-within {
265
+ border-color: var(--klc-color-axis-text);
266
+ }
267
+
268
+ .symbol-search__icon {
269
+ flex: 0 0 auto;
270
+ display: flex;
271
+ align-items: center;
272
+ color: var(--klc-color-axis-text);
273
+ }
274
+
275
+ .symbol-search__input {
276
+ flex: 1 1 0;
277
+ min-width: 0;
278
+ border: none;
279
+ outline: none;
280
+ background: transparent;
281
+ color: var(--klc-color-foreground);
282
+ font: inherit;
283
+ font-size: 13px;
284
+ line-height: 1;
285
+ }
286
+
287
+ .symbol-search__input::placeholder {
288
+ color: var(--klc-color-axis-text);
289
+ opacity: 0.7;
290
+ }
291
+
292
+ .symbol-search__clear {
293
+ flex: 0 0 auto;
294
+ display: inline-flex;
295
+ align-items: center;
296
+ justify-content: center;
297
+ width: 24px;
298
+ height: 24px;
299
+ padding: 0;
300
+ border: 1px solid transparent;
301
+ border-radius: 4px;
302
+ background: transparent;
303
+ color: var(--klc-color-axis-text);
304
+ cursor: pointer;
305
+ transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
306
+ }
307
+
308
+ .symbol-search__clear:hover {
309
+ border-color: var(--klc-color-axis-line);
310
+ background: var(--klc-color-grid-minor);
311
+ color: var(--klc-color-foreground);
312
+ }
313
+
314
+ .symbol-search__clear .delete-icon {
315
+ width: 14px;
316
+ height: 14px;
317
+ }
318
+
319
+ .symbol-list {
320
+ max-height: 280px;
321
+ overflow-y: auto;
322
+ overflow-x: hidden;
323
+ display: flex;
324
+ flex-direction: column;
325
+ margin: 0 -4px;
326
+ }
327
+
328
+ .symbol-list::-webkit-scrollbar {
329
+ width: 6px;
330
+ }
331
+ .symbol-list::-webkit-scrollbar-thumb {
332
+ background: var(--klc-color-border-button);
333
+ border-radius: 999px;
334
+ }
335
+
336
+ .symbol-list__empty {
337
+ display: flex;
338
+ flex-direction: column;
339
+ align-items: center;
340
+ justify-content: center;
341
+ padding: 28px 0;
342
+ color: var(--klc-color-axis-text);
343
+ font-size: 13px;
344
+ text-align: center;
345
+ gap: 2px;
346
+ }
347
+
348
+ .symbol-list__item {
349
+ display: flex;
350
+ align-items: center;
351
+ justify-content: space-between;
352
+ gap: 8px;
353
+ padding: 9px 10px;
354
+ margin: 0 4px;
355
+ border: none;
356
+ border-radius: 7px;
357
+ background: transparent;
358
+ color: var(--klc-color-foreground);
359
+ font: inherit;
360
+ cursor: pointer;
361
+ text-align: left;
362
+ transition: background 0.12s ease;
363
+ flex-shrink: 0;
364
+ }
365
+
366
+ .symbol-list__item:hover {
367
+ background: var(--klc-color-grid-minor);
368
+ }
369
+
370
+ .symbol-list__item.is-active {
371
+ background: color-mix(in srgb, var(--klc-color-alert-active) 10%, transparent);
372
+ }
373
+
374
+ .symbol-list__left {
375
+ display: flex;
376
+ flex-direction: column;
377
+ gap: 3px;
378
+ min-width: 0;
379
+ flex: 1 1 0;
380
+ }
381
+
382
+ .symbol-list__code {
383
+ font-size: 13px;
384
+ font-weight: 700;
385
+ line-height: 1.2;
386
+ letter-spacing: 0.01em;
387
+ color: var(--klc-color-foreground);
388
+ overflow: hidden;
389
+ text-overflow: ellipsis;
390
+ white-space: nowrap;
391
+ }
392
+
393
+ .symbol-list__desc {
394
+ font-size: 11px;
395
+ font-weight: 400;
396
+ line-height: 1.2;
397
+ color: var(--klc-color-axis-text);
398
+ overflow: hidden;
399
+ text-overflow: ellipsis;
400
+ white-space: nowrap;
401
+ }
402
+
403
+ .symbol-list__exchange {
404
+ flex: 0 0 auto;
405
+ padding: 2px 7px;
406
+ border-radius: 4px;
407
+ background: var(--klc-color-grid-major);
408
+ color: var(--klc-color-axis-text);
409
+ font-size: 10px;
410
+ font-weight: 600;
411
+ line-height: 1.4;
412
+ letter-spacing: 0.03em;
413
+ text-transform: uppercase;
414
+ white-space: nowrap;
415
+ }
416
+
417
+ .symbol-list__item.is-active .symbol-list__exchange {
418
+ background: color-mix(in srgb, var(--klc-color-alert-active) 16%, transparent);
419
+ color: var(--klc-color-alert-active);
420
+ }
421
+
422
+ .symbol-popover-enter-active,
423
+ .symbol-popover-leave-active {
424
+ transition:
425
+ opacity 0.15s ease,
426
+ transform 0.15s ease;
427
+ }
428
+
429
+ .symbol-popover-enter-from,
430
+ .symbol-popover-leave-to {
431
+ opacity: 0;
432
+ transform: translateY(-4px);
433
+ }
434
+
435
+ @media (max-width: 768px), (max-height: 640px) {
436
+ .symbol-chip {
437
+ height: 26px;
438
+ max-width: 120px;
439
+ padding: 0 8px;
440
+ }
441
+
442
+ .symbol-chip__code {
443
+ font-size: 13px;
444
+ }
445
+
446
+ .symbol-popover {
447
+ width: min(292px, calc(100vw - 16px));
448
+ padding: 12px;
449
+ gap: 8px;
450
+ }
451
+
452
+ .symbol-list {
453
+ max-height: 220px;
454
+ }
455
+ }
456
+
457
+ .symbol-chip__spinner {
458
+ width: 12px;
459
+ height: 12px;
460
+ border: 2px solid var(--klc-color-axis-text);
461
+ border-top-color: transparent;
462
+ border-radius: 50%;
463
+ animation: symbol-spin 0.6s linear infinite;
464
+ }
465
+
466
+ @keyframes symbol-spin {
467
+ to {
468
+ transform: rotate(360deg);
469
+ }
470
+ }
471
+
472
+ .symbol-chip__warn {
473
+ width: 14px;
474
+ height: 14px;
475
+ color: var(--klc-color-danger, #e53935);
476
+ flex-shrink: 0;
477
+ }
478
+ </style>
@@ -1,19 +1,27 @@
1
1
  <template>
2
2
  <div class="top-toolbar">
3
- <button v-if="displaySymbol" type="button" class="symbol-chip" :title="displaySymbol">
4
- <span class="symbol-chip__code">{{ displaySymbol }}</span>
5
- </button>
3
+ <SymbolSelector
4
+ v-if="displaySymbol"
5
+ :symbol="displaySymbol"
6
+ :symbols="symbolPool"
7
+ :loading="symbolLoading"
8
+ :error="symbolError"
9
+ @change="onSymbolSelectorChange"
10
+ />
6
11
  <button
7
12
  type="button"
8
13
  class="overlay-symbol-button"
9
- title="添加叠加商品"
10
- aria-label="添加叠加商品"
14
+ title="添加比较商品"
15
+ aria-label="添加比较商品"
11
16
  @click="emit('addOverlaySymbol')"
12
17
  >
13
18
  <span class="overlay-symbol-button__icon" aria-hidden="true">+</span>
14
- <span class="overlay-symbol-button__text">添加叠加商品</span>
19
+ <span class="overlay-symbol-button__text">添加比较商品</span>
15
20
  </button>
16
- <KLineLevelDropdown :model-value="kLineLevel" @update:model-value="emit('kLineLevelChange', $event)" />
21
+ <KLineLevelDropdown
22
+ :model-value="kLineLevel"
23
+ @update:model-value="emit('kLineLevelChange', $event)"
24
+ />
17
25
  <button
18
26
  type="button"
19
27
  class="indicator-button"
@@ -30,23 +38,61 @@
30
38
  <script setup lang="ts">
31
39
  import { computed } from 'vue'
32
40
  import KLineLevelDropdown, { type KLineLevel } from './KLineLevelDropdown.vue'
41
+ import SymbolSelector from './SymbolSelector.vue'
42
+ import type { SymbolItem } from './SymbolSelector.vue'
43
+
44
+ export type { SymbolItem }
33
45
 
34
46
  const props = defineProps<{
35
47
  symbol?: string
36
48
  kLineLevel?: string
49
+ symbols?: SymbolItem[]
50
+ symbolLoading?: boolean
51
+ symbolError?: boolean
37
52
  }>()
38
53
 
39
54
  const emit = defineEmits<{
40
55
  (e: 'addOverlaySymbol'): void
41
56
  (e: 'kLineLevelChange', level: KLineLevel): void
42
57
  (e: 'toggleIndicator'): void
58
+ (e: 'symbolChange', symbol: SymbolItem): void
43
59
  }>()
44
60
 
61
+ const MOCK_SYMBOLS: SymbolItem[] = [
62
+ { code: 'AAPL', description: 'Apple Inc.', exchange: 'NASDAQ', source: 'baostock' },
63
+ { code: 'TSLA', description: 'Tesla, Inc.', exchange: 'NASDAQ', source: 'baostock' },
64
+ { code: 'GOOGL', description: 'Alphabet Inc.', exchange: 'NASDAQ', source: 'baostock' },
65
+ { code: 'MSFT', description: 'Microsoft Corporation', exchange: 'NASDAQ', source: 'baostock' },
66
+ { code: 'AMZN', description: 'Amazon.com, Inc.', exchange: 'NASDAQ', source: 'baostock' },
67
+ { code: 'NVDA', description: 'NVIDIA Corporation', exchange: 'NASDAQ', source: 'baostock' },
68
+ { code: 'META', description: 'Meta Platforms, Inc.', exchange: 'NASDAQ', source: 'baostock' },
69
+ { code: 'BRK.B', description: 'Berkshire Hathaway Inc.', exchange: 'NYSE', source: 'baostock' },
70
+ { code: 'JPM', description: 'JPMorgan Chase & Co.', exchange: 'NYSE', source: 'baostock' },
71
+ { code: 'V', description: 'Visa Inc.', exchange: 'NYSE', source: 'baostock' },
72
+ { code: 'BTCUSDT', description: 'Bitcoin / Tether', exchange: 'BINANCE', source: 'baostock' },
73
+ { code: 'ETHUSDT', description: 'Ethereum / Tether', exchange: 'BINANCE', source: 'baostock' },
74
+ { code: 'sh.601360', description: '三六零', exchange: 'SSE', source: 'baostock' },
75
+ { code: 'sh.600519', description: '贵州茅台', exchange: 'SSE', source: 'baostock' },
76
+ { code: '000858', description: '五 粮 液', exchange: 'SZSE', source: 'baostock' },
77
+ { code: '000001', description: '平安银行', exchange: 'SZSE', source: 'baostock' },
78
+ { code: 'MOCK-100', description: 'Mock 100 条', exchange: 'MOCK', source: 'mock-100' },
79
+ { code: 'MOCK-10000', description: 'Mock 10000 条', exchange: 'MOCK', source: 'mock-10000' },
80
+ ]
81
+
45
82
  const displaySymbol = computed(() => props.symbol?.trim() ?? '')
83
+
84
+ const symbolPool = computed<SymbolItem[]>(() =>
85
+ props.symbols && props.symbols.length ? props.symbols : MOCK_SYMBOLS,
86
+ )
87
+
88
+ function onSymbolSelectorChange(item: SymbolItem) {
89
+ emit('symbolChange', item)
90
+ }
46
91
  </script>
47
92
 
48
93
  <style scoped>
49
94
  .top-toolbar {
95
+ position: relative;
50
96
  width: 95%;
51
97
  height: 40px;
52
98
  display: flex;
@@ -62,37 +108,6 @@ const displaySymbol = computed(() => props.symbol?.trim() ?? '')
62
108
  user-select: none;
63
109
  }
64
110
 
65
- .symbol-chip {
66
- height: 28px;
67
- display: inline-flex;
68
- align-items: center;
69
- justify-content: center;
70
- max-width: 160px;
71
- padding: 0 10px;
72
- border: 1px solid transparent;
73
- border-radius: 4px;
74
- background: transparent;
75
- color: var(--klc-color-foreground);
76
- font: inherit;
77
- cursor: default;
78
- transition: background 0.15s ease, border-color 0.15s ease;
79
- }
80
-
81
- .symbol-chip:hover {
82
- border-color: var(--klc-color-border-button);
83
- background: var(--klc-color-grid-minor);
84
- }
85
-
86
- .symbol-chip__code {
87
- overflow: hidden;
88
- text-overflow: ellipsis;
89
- white-space: nowrap;
90
- font-size: 14px;
91
- font-weight: 600;
92
- line-height: 1;
93
- letter-spacing: 0.01em;
94
- }
95
-
96
111
  .overlay-symbol-button {
97
112
  height: 28px;
98
113
  display: inline-flex;
@@ -107,7 +122,10 @@ const displaySymbol = computed(() => props.symbol?.trim() ?? '')
107
122
  color: var(--klc-color-foreground);
108
123
  font: inherit;
109
124
  cursor: pointer;
110
- transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
125
+ transition:
126
+ background 0.15s ease,
127
+ border-color 0.15s ease,
128
+ color 0.15s ease;
111
129
  }
112
130
 
113
131
  .overlay-symbol-button:hover {
@@ -150,7 +168,10 @@ const displaySymbol = computed(() => props.symbol?.trim() ?? '')
150
168
  color: var(--klc-color-foreground);
151
169
  font: inherit;
152
170
  cursor: pointer;
153
- transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
171
+ transition:
172
+ background 0.15s ease,
173
+ border-color 0.15s ease,
174
+ color 0.15s ease;
154
175
  }
155
176
 
156
177
  .indicator-button:hover {
@@ -181,50 +202,7 @@ const displaySymbol = computed(() => props.symbol?.trim() ?? '')
181
202
  }
182
203
 
183
204
  @media (max-width: 768px), (max-height: 640px) {
184
- .top-toolbar {
185
- height: 36px;
186
- padding: 0 6px;
187
- border-radius: 3px;
188
- }
189
-
190
- .symbol-chip {
191
- height: 26px;
192
- max-width: 120px;
193
- padding: 0 8px;
194
- }
195
-
196
- .symbol-chip__code {
197
- font-size: 13px;
198
- }
199
-
200
- .overlay-symbol-button {
201
- height: 26px;
202
- gap: 4px;
203
- padding: 0 8px;
204
- }
205
-
206
- .overlay-symbol-button__icon {
207
- width: 15px;
208
- height: 15px;
209
- font-size: 12px;
210
- }
211
-
212
- .overlay-symbol-button__text {
213
- display: none;
214
- }
215
-
216
- .indicator-button {
217
- height: 26px;
218
- gap: 4px;
219
- padding: 0 8px;
220
- }
221
-
222
- .indicator-button__icon {
223
- width: 15px;
224
- height: 15px;
225
- font-size: 9px;
226
- }
227
-
205
+ .overlay-symbol-button__text,
228
206
  .indicator-button__text {
229
207
  display: none;
230
208
  }