chore: migrate components to typescript setup (#55)

Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
Sylvain Marroufin
2022-05-09 16:05:07 +02:00
committed by GitHub
parent 6c2f93f262
commit 39bf242f78
19 changed files with 1538 additions and 1684 deletions

View File

@@ -12,174 +12,159 @@
</component>
</template>
<script>
import { ref, computed } from 'vue'
import Link from '../elements/Link'
<script setup lang="ts">
import { ref, computed, useSlots } from 'vue'
import Icon from '../elements/Icon'
import { classNames } from '../../utils'
import NuxtLink from '#app/components/nuxt-link'
import $ui from '#build/ui'
export default {
components: {
Icon,
Link
const props = defineProps({
type: {
type: String,
default: 'button'
},
props: {
type: {
type: String,
default: 'button'
},
block: {
type: Boolean,
default: false
},
label: {
type: String,
default: null
},
loading: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
size: {
type: String,
default: 'md',
validator (value) {
return Object.keys($ui.button.size).includes(value)
}
},
variant: {
type: String,
default: 'primary',
validator (value) {
return Object.keys($ui.button.variant).includes(value)
}
},
icon: {
type: String,
default: null
},
loadingIcon: {
type: String,
default: () => $ui.button.icon.loading
},
trailing: {
type: Boolean,
default: false
},
leading: {
type: Boolean,
default: false
},
to: {
type: [String, Object],
default: null
},
target: {
type: String,
default: null
},
ariaLabel: {
type: String,
default: null
},
rounded: {
type: Boolean,
default: false
},
baseClass: {
type: String,
default: () => $ui.button.base
},
iconBaseClass: {
type: String,
default: () => $ui.button.icon.base
},
customClass: {
type: String,
default: null
},
square: {
type: Boolean,
default: false
},
truncate: {
type: Boolean,
default: false
block: {
type: Boolean,
default: false
},
label: {
type: String,
default: null
},
loading: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
size: {
type: String,
default: 'md',
validator (value: string) {
return Object.keys($ui.button.size).includes(value)
}
},
setup (props, { slots }) {
const button = ref(null)
const buttonIs = computed(() => {
if (props.to) {
return 'Link'
}
return 'button'
})
const buttonProps = computed(() => {
switch (buttonIs.value) {
case 'Link': return { to: props.to, target: props.target }
default: return { disabled: props.disabled || props.loading, type: props.type }
}
})
const isLeading = computed(() => {
return (props.icon && props.leading) || (props.icon && !props.trailing) || (props.loading && !props.trailing)
})
const isTrailing = computed(() => {
return (props.icon && props.trailing) || (props.loading && props.trailing)
})
const isSquare = computed(() => props.square || (!slots.default && !props.label))
const buttonClass = computed(() => {
return classNames(
props.baseClass,
$ui.button.size[props.size],
$ui.button[isSquare.value ? 'square' : 'spacing'][props.size],
$ui.button.variant[props.variant],
props.block ? 'w-full flex justify-center items-center' : 'inline-flex items-center',
props.rounded ? 'rounded-full' : 'rounded-md',
props.customClass
)
})
const iconName = computed(() => {
if (props.loading) {
return props.loadingIcon
}
return props.icon
})
const iconClass = computed(() => {
return classNames(
props.iconBaseClass,
$ui.button.icon.size[props.size],
isLeading.value && (!!slots.default || !!props.label?.length) && $ui.button.icon.leading.spacing[props.size],
isTrailing.value && (!!slots.default || !!props.label?.length) && $ui.button.icon.trailing.spacing[props.size],
props.loading && 'animate-spin'
)
})
return {
button,
buttonIs,
buttonProps,
buttonClass,
isLeading,
isTrailing,
iconName,
iconClass
variant: {
type: String,
default: 'primary',
validator (value: string) {
return Object.keys($ui.button.variant).includes(value)
}
},
icon: {
type: String,
default: null
},
loadingIcon: {
type: String,
default: () => $ui.button.icon.loading
},
trailing: {
type: Boolean,
default: false
},
leading: {
type: Boolean,
default: false
},
to: {
type: [String, Object],
default: null
},
target: {
type: String,
default: null
},
ariaLabel: {
type: String,
default: null
},
rounded: {
type: Boolean,
default: false
},
baseClass: {
type: String,
default: () => $ui.button.base
},
iconBaseClass: {
type: String,
default: () => $ui.button.icon.base
},
customClass: {
type: String,
default: null
},
square: {
type: Boolean,
default: false
},
truncate: {
type: Boolean,
default: false
}
}
})
const slots = useSlots()
const button = ref(null)
const buttonIs = computed(() => {
if (props.to) {
return NuxtLink
}
return 'button'
})
const buttonProps = computed(() => {
if (props.to) {
return { to: props.to, target: props.target }
} else {
return { disabled: props.disabled || props.loading, type: props.type }
}
})
const isLeading = computed(() => {
return (props.icon && props.leading) || (props.icon && !props.trailing) || (props.loading && !props.trailing)
})
const isTrailing = computed(() => {
return (props.icon && props.trailing) || (props.loading && props.trailing)
})
const isSquare = computed(() => props.square || (!slots.default && !props.label))
const buttonClass = computed(() => {
return classNames(
props.baseClass,
$ui.button.size[props.size],
$ui.button[isSquare.value ? 'square' : 'spacing'][props.size],
$ui.button.variant[props.variant],
props.block ? 'w-full flex justify-center items-center' : 'inline-flex items-center',
props.rounded ? 'rounded-full' : 'rounded-md',
props.customClass
)
})
const iconName = computed(() => {
if (props.loading) {
return props.loadingIcon
}
return props.icon
})
const iconClass = computed(() => {
return classNames(
props.iconBaseClass,
$ui.button.icon.size[props.size],
isLeading.value && (!!slots.default || !!props.label?.length) && $ui.button.icon.leading.spacing[props.size],
isTrailing.value && (!!slots.default || !!props.label?.length) && $ui.button.icon.trailing.spacing[props.size],
props.loading && 'animate-spin'
)
})
</script>