aboutsummaryrefslogtreecommitdiff
path: root/src/ui/c-buttons-select/c-buttons-select.vue
blob: 38fff66f68e1fb5205d97ec3dd2e4cf79c794bfc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<script setup lang="ts" generic="T extends unknown">
import type { CLabelProps } from '../c-label/c-label.types';
import type { CButtonSelectOption } from './c-buttons-select.types';

const props = withDefaults(
  defineProps<{
    options?: CButtonSelectOption<T>[] | string[]
    value?: T
    size?: 'small' | 'medium' | 'large'
  } & CLabelProps >(),
  {
    options: () => [],
    value: undefined,
    labelPosition: 'left',
    size: 'medium',
  },
);

const emits = defineEmits(['update:value']);

const { options: rawOptions, size } = toRefs(props);

const options = computed(() => {
  return rawOptions.value.map((option: string | CButtonSelectOption<T>) => {
    if (typeof option === 'string') {
      return { label: option, value: option };
    }

    return option;
  });
});

const value = useVModel(props, 'value', emits);

function selectOption(option: CButtonSelectOption<T>) {
  // @ts-expect-error vue template generic is a bit flacky thanks to withDefaults
  value.value = option.value;
}
</script>

<template>
  <c-label v-bind="props">
    <div class="flex gap-2">
      <c-tooltip
        v-for="option in options" :key="option.value"
        :tooltip="option.tooltip"
      >
        <c-button
          :test-id="option.value"
          :size="size"
          :type="option.value === value ? 'primary' : 'default'"
          @click="selectOption(option)"
        >
          {{ option.label }}
        </c-button>
      </c-tooltip>
    </div>
  </c-label>
</template>