UiTabs.vue 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. <template>
  2. <div
  3. aria-role="tablist"
  4. class="
  5. ui-tabs
  6. text-gray-600
  7. dark:text-gray-200
  8. border-b
  9. flex
  10. space-x-1
  11. items-center
  12. relative
  13. "
  14. @mouseleave="showHoverIndicator = false"
  15. >
  16. <div
  17. v-show="showHoverIndicator"
  18. ref="hoverIndicator"
  19. class="
  20. ui-tabs__indicator
  21. z-0
  22. top-[5px]
  23. absolute
  24. left-0
  25. rounded-lg
  26. bg-box-transparent
  27. "
  28. ></div>
  29. <slot></slot>
  30. </div>
  31. </template>
  32. <script>
  33. import { provide, toRefs, ref } from 'vue';
  34. export default {
  35. props: {
  36. modelValue: {
  37. type: [String, Number],
  38. default: '',
  39. },
  40. small: Boolean,
  41. fill: Boolean,
  42. },
  43. emits: ['update:modelValue'],
  44. setup(props, { emit }) {
  45. const hoverIndicator = ref(null);
  46. const showHoverIndicator = ref(false);
  47. function updateActive(id) {
  48. emit('update:modelValue', id);
  49. }
  50. function hoverHandler({ target }) {
  51. const { height, width } = target.getBoundingClientRect();
  52. showHoverIndicator.value = true;
  53. hoverIndicator.value.style.width = `${width}px`;
  54. hoverIndicator.value.style.height = `${height - 11}px`;
  55. hoverIndicator.value.style.transform = `translateX(${target.offsetLeft}px)`;
  56. }
  57. provide('ui-tabs', {
  58. updateActive,
  59. hoverHandler,
  60. ...toRefs(props),
  61. });
  62. return {
  63. hoverIndicator,
  64. showHoverIndicator,
  65. };
  66. },
  67. };
  68. </script>
  69. <style>
  70. .ui-tabs__indicator {
  71. min-height: 24px;
  72. min-width: 50px;
  73. transition-duration: 200ms;
  74. transition-property: transform, width;
  75. transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  76. }
  77. </style>