|
5 | 5 | VueUiScatter, |
6 | 6 | type VueUiScatterConfig, |
7 | 7 | type VueUiScatterDatasetItem, |
| 8 | + type VueUiScatterSeries, |
8 | 9 | } from 'vue-data-ui/vue-ui-scatter' |
9 | 10 | import { buildCompareScatterChartDataset } from '~/utils/compare-scatter-chart' |
10 | 11 | import { loadFile, copyAltTextForCompareScatterChart } from '~/utils/charts' |
@@ -285,6 +286,11 @@ function toggleAxisHighlight(state: AxisHighlight) { |
285 | 286 | highlightedAxis.value = state |
286 | 287 | } |
287 | 288 |
|
| 289 | +function toggleLegendItem(legendItem: VueUiScatterSeries) { |
| 290 | + legendItem.segregate() |
| 291 | + legendItem.onEnter() |
| 292 | +} |
| 293 | +
|
288 | 294 | const readyTeleport = shallowRef(false) |
289 | 295 |
|
290 | 296 | onMounted(async () => { |
@@ -389,26 +395,26 @@ onMounted(async () => { |
389 | 395 | : 'text-sm leading-6' |
390 | 396 | " |
391 | 397 | > |
392 | | - <li v-for="datapoint in legend" :key="datapoint.name"> |
| 398 | + <li v-for="legendItem in legend" :key="legendItem.id"> |
393 | 399 | <button |
394 | | - :aria-pressed="datapoint.isSegregated" |
395 | | - :aria-label="datapoint.name" |
| 400 | + :aria-pressed="legendItem.isSegregated" |
| 401 | + :aria-label="legendItem.name" |
396 | 402 | type="button" |
397 | 403 | class="flex gap-1.5 place-items-center" |
398 | | - @click="datapoint.segregate()" |
| 404 | + :class="legendItem.isSegregated ? 'line-through' : 'hover:underline'" |
| 405 | + @click="toggleLegendItem(legendItem)" |
| 406 | + @mouseenter="legendItem.onEnter()" |
| 407 | + @mouseleave="legendItem.onLeave()" |
| 408 | + @focus="legendItem.onEnter()" |
| 409 | + @blur="legendItem.onLeave()" |
399 | 410 | > |
400 | 411 | <div class="h-3 w-3" aria-hidden="true"> |
401 | 412 | <svg viewBox="0 0 2 2" class="w-full"> |
402 | | - <circle cx="1" cy="1" r="1" :fill="datapoint.color" /> |
| 413 | + <circle cx="1" cy="1" r="1" :fill="legendItem.color" /> |
403 | 414 | </svg> |
404 | 415 | </div> |
405 | | - <span |
406 | | - class="text-fg" |
407 | | - :style="{ |
408 | | - textDecoration: datapoint.isSegregated ? 'line-through' : undefined, |
409 | | - }" |
410 | | - > |
411 | | - {{ datapoint.name }} |
| 416 | + <span class="text-fg"> |
| 417 | + {{ legendItem.name }} |
412 | 418 | </span> |
413 | 419 | </button> |
414 | 420 | </li> |
@@ -559,14 +565,35 @@ onMounted(async () => { |
559 | 565 | </template> |
560 | 566 |
|
561 | 567 | <style scoped> |
| 568 | +:deep(.vue-data-ui-component) { |
| 569 | + --super-ease-out: cubic-bezier(0.15, 0.75, 0.35, 1); |
| 570 | +} |
| 571 | +
|
562 | 572 | :deep(.vue-data-ui-component svg:focus-visible) { |
563 | 573 | outline: 1px solid var(--accent) !important; |
564 | 574 | border-radius: 0.1rem; |
565 | 575 | outline-offset: 0; |
566 | 576 | } |
| 577 | +
|
567 | 578 | :deep(.vue-ui-user-options-button:focus-visible), |
568 | 579 | :deep(.vue-ui-user-options :first-child:focus-visible) { |
569 | 580 | outline: 0.1rem solid var(--accent) !important; |
570 | 581 | border-radius: 0.25rem; |
571 | 582 | } |
| 583 | +
|
| 584 | +:deep(.vue-ui-scatter-scale-group), |
| 585 | +:deep(.vue-ui-scatter-datapoint text), |
| 586 | +:deep(.vue-ui-scatter-datapoint circle), |
| 587 | +:deep(.vue-ui-scatter-datapoint-label) { |
| 588 | + transition: all 0.5s var(--super-ease-out) !important; |
| 589 | +} |
| 590 | +
|
| 591 | +@media (prefers-reduced-motion: reduce) { |
| 592 | + :deep(.vue-ui-scatter-scale-group), |
| 593 | + :deep(.vue-ui-scatter-datapoint text), |
| 594 | + :deep(.vue-ui-scatter-datapoint circle), |
| 595 | + :deep(.vue-ui-scatter-datapoint-label) { |
| 596 | + transition: none !important; |
| 597 | + } |
| 598 | +} |
572 | 599 | </style> |
0 commit comments