Picture.vue 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <template>
  2. <div
  3. tabindex="0"
  4. class="relative flex items-center justify-center cursor-pointer focus:outline-none focus-visible:ring focus-visible:ring-primaryDark"
  5. :class="[`rounded-${rounded}`, `w-${size} h-${size}`]"
  6. >
  7. <img
  8. v-if="url"
  9. class="absolute object-cover object-center transition bg-primaryDark"
  10. :class="[`rounded-${rounded}`, `w-${size} h-${size}`]"
  11. :src="url"
  12. :alt="alt"
  13. loading="lazy"
  14. />
  15. <div
  16. v-else
  17. class="absolute flex items-center justify-center object-cover object-center transition bg-primaryDark text-accentContrast"
  18. :class="[`rounded-${rounded}`, `w-${size} h-${size}`]"
  19. :style="`background-color: ${toHex(initial)}`"
  20. >
  21. {{ initial.charAt(0).toUpperCase() }}
  22. </div>
  23. <span
  24. v-if="indicator"
  25. class="border-primary border-2 h-2.5 -top-0.5 -right-0.5 w-2.5 absolute"
  26. :class="[`rounded-${rounded}`, indicatorStyles]"
  27. ></span>
  28. <!-- w-5 h-5 rounded-lg -->
  29. </div>
  30. </template>
  31. <script>
  32. import { defineComponent } from "@nuxtjs/composition-api"
  33. export default defineComponent({
  34. props: {
  35. url: {
  36. type: String,
  37. default: "",
  38. },
  39. alt: {
  40. type: String,
  41. default: "Profile picture",
  42. },
  43. indicator: {
  44. type: Boolean,
  45. default: false,
  46. },
  47. indicatorStyles: {
  48. type: String,
  49. default: "bg-green-500",
  50. },
  51. rounded: {
  52. type: String,
  53. default: "full",
  54. },
  55. size: {
  56. type: String,
  57. default: "5",
  58. },
  59. initial: {
  60. type: String,
  61. default: "",
  62. },
  63. },
  64. methods: {
  65. toHex(initial) {
  66. let hash = 0
  67. if (initial.length === 0) return hash
  68. for (let i = 0; i < initial.length; i++) {
  69. hash = initial.charCodeAt(i) + ((hash << 5) - hash)
  70. hash = hash & hash
  71. }
  72. let color = "#"
  73. for (let i = 0; i < 3; i++) {
  74. const value = (hash >> (i * 8)) & 255
  75. color += `00${value.toString(16)}`.slice(-2)
  76. }
  77. return color
  78. },
  79. },
  80. })
  81. </script>