kodadot/nft-gallery

View on GitHub
libs/ui/src/components/NeoButton/NeoButton.vue

Summary

Maintainability
Test Coverage
<template>
  <o-button
    ref="button"
    :class="{
      'active': active,
      'is-fixed-width': fixedWidth,
      'no-shadow': noShadow,
      'loading-with-label': loadingWithLabel,
      'shiny': shiny,
      'pressing': pressing,
    }"
    :size="size"
    :icon-right="icon"
    :icon-left="iconLeft"
    :variant="variant"
    :disabled="disabled"
    :expanded="expanded"
    :icon-pack="iconPack"
    :label="label"
    class="is-neo"
    :rounded="rounded"
    :tag="tag"
    v-bind="$props"
  >
    <template
      v-if="$slots.default"
      #default
    >
      <slot />
    </template>
  </o-button>
</template>

<script lang="ts" setup>
import type { ComputedOptions, ConcreteComponent, MethodOptions } from 'vue'
import { OButton } from '@oruga-ui/oruga-next'
import { useMousePressed, useIntersectionObserver } from '@vueuse/core'
import type { NeoButtonVariant } from '../../types'

const props = withDefaults(
  defineProps<{
    size?: 'small' | 'medium' | 'large'
    disabled?: boolean
    expanded?: boolean
    icon?: string
    iconLeft?: string
    iconPack?: string
    label?: string
    active?: boolean
    fixedWidth?: boolean
    noShadow?: boolean
    variant?: NeoButtonVariant
    rounded?: boolean
    shiny?: boolean
    tag?:
      | string
      // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
      | ConcreteComponent<{}, any, any, ComputedOptions, MethodOptions>
    loadingWithLabel?: boolean
    withShortcut?: boolean
  }>(),
  {
    iconPack: 'fasr',
    shiny: false,
  },
)

const button = ref<HTMLButtonElement>()
const pressing = ref(false)

const { pressed } = useMousePressed({ target: button })

watch(pressed, (pressed) => {
  pressing.value = !pressed ? false : pressed && !props.active
})

if (props.withShortcut) {
  const shortcutWatcher = ref()

  useIntersectionObserver(button, ([{ isIntersecting: isVisible }]) => {
    if (!isVisible) {
      shortcutWatcher.value?.()
      shortcutWatcher.value = undefined
      return
    }

    if (!shortcutWatcher.value) {
      shortcutWatcher.value = onPressControlEnter(() => {
        if (!button.value?.disabled) {
          button.value?.$el?.click()
        }
      })
    }
  })
}
</script>

<style lang="scss">
@import './NeoButton.scss';
</style>