ApiPreference.vue 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <script setup lang="ts">
  2. import { useLocalStorage } from '@vueuse/core'
  3. const props = defineProps<{
  4. options: string[]
  5. defaultOption: string
  6. screenMenu?: boolean
  7. }>()
  8. // reactivity isn't needed for props here
  9. const key = removeSpaces(`api-preference-${props.options.join('-')}`)
  10. const name = key + (props.screenMenu ? '-screen-menu' : '')
  11. const selected = useLocalStorage(key, () => props.defaultOption)
  12. const optionsWithKeys = props.options.map((option) => ({
  13. key: name + '-' + removeSpaces(option),
  14. value: option
  15. }))
  16. function removeSpaces(str: string) {
  17. return str.replace(/\s/g, '_')
  18. }
  19. </script>
  20. <template>
  21. <div class="VPApiPreference" :class="{ 'screen-menu': screenMenu }">
  22. <template v-for="option in optionsWithKeys" :key="option">
  23. <input
  24. type="radio"
  25. :id="option.key"
  26. :name
  27. :value="option.value"
  28. v-model="selected"
  29. />
  30. <label :for="option.key">{{ option.value }}</label>
  31. </template>
  32. </div>
  33. </template>
  34. <style scoped>
  35. .VPApiPreference {
  36. display: flex;
  37. margin: 12px 0;
  38. border: 1px solid var(--vp-c-border);
  39. border-radius: 6px;
  40. font-size: 14px;
  41. color: var(--vp-c-text-1);
  42. }
  43. .VPApiPreference:first-child {
  44. margin-top: 0;
  45. }
  46. .VPApiPreference:last-child {
  47. margin-bottom: 0;
  48. }
  49. .VPApiPreference.screen-menu {
  50. margin: 12px 0 0 12px;
  51. }
  52. .VPApiPreference input[type='radio'] {
  53. pointer-events: none;
  54. position: fixed;
  55. opacity: 0;
  56. }
  57. .VPApiPreference label {
  58. flex: 1;
  59. margin: 2px;
  60. padding: 4px 12px;
  61. cursor: pointer;
  62. border-radius: 4px;
  63. text-align: center;
  64. }
  65. .VPApiPreference input[type='radio']:checked + label {
  66. background-color: var(--vp-c-default-soft);
  67. color: var(--vp-c-brand-1);
  68. }
  69. </style>