Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: match button-icon to related plugin #52

Merged
merged 1 commit into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .playground/pages/tests/content/button-icon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<script setup lang="ts">
definePageMeta({
title: 'Button Icon',
icon: 'lucide:cpu',
description: 'Button Icon variations',
section: 'content',
})
</script>

<template>
<div
class="flex flex-col gap-12 [&>*]:p-8 [&>:nth-child(odd)]:bg-muted-100 dark:[&>:nth-child(odd)]:bg-muted-900 pb-32"
>
<div>
<BaseHeading size="xl" weight="medium" class="mb-10">
Button icon shape
</BaseHeading>
<div class="flex gap-2">
<BaseButtonIcon shape="straight">
<Icon name="ph:moon-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="rounded">
<Icon name="ph:github-logo-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="curved">
<Icon name="ph:game-controller-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
</div>
</div>
<div>
<BaseHeading size="xl" weight="medium" class="mb-10">
Button icon colors
</BaseHeading>
<div class="flex gap-2">
<BaseButtonIcon shape="full" color="default">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full" color="muted">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full" color="primary">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full" color="info">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full" color="success">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full" color="warning">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full" color="danger">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full" color="none">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
</div>
</div>
<div>
<BaseHeading size="xl" weight="medium" class="mb-10">
Button icon size
</BaseHeading>
<div class="flex gap-2">
<BaseButtonIcon shape="full" color="primary" size="sm">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full" color="primary" size="md">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
<BaseButtonIcon shape="full" color="primary" size="lg">
<Icon name="ph:heart-duotone" class="w-5 h-5" />
</BaseButtonIcon>
</div>
</div>
</div>
</template>
76 changes: 40 additions & 36 deletions components/base/BaseButtonIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,30 @@ const props = withDefaults(
/**
* The shape of the button or link.
*/
shape?: 'straight' | 'rounded' | 'curved' | 'full'
shape?: 'straight' | 'rounded' | 'smooth' | 'curved' | 'full'

/**
* The color of the button.
*/
color?: 'default' | 'muted' | 'primary'
color?:
| 'default'
| 'muted'
| 'primary'
| 'info'
| 'success'
| 'warning'
| 'danger'
| 'none'

/**
* Whether the button or link is in a loading state.
* The size of the button.
*/
loading?: boolean
size?: 'sm' | 'md' | 'lg'

/**
* Whether the button or link is small.
* Whether the button or link is in a loading state.
*/
condensed?: boolean
loading?: boolean
}>(),
{
color: 'default',
Expand All @@ -65,6 +73,7 @@ const props = withDefaults(
target: '',
loading: false,
condensed: false,
size: 'md',
}
)
const appConfig = useAppConfig()
Expand All @@ -74,45 +83,40 @@ const shape = computed(

const shapeStyle = {
straight: '',
rounded: 'rounded-md',
curved: 'rounded-lg',
full: 'rounded-full',
rounded: 'nui-button-rounded',
smooth: 'nui-button-smooth',
curved: 'nui-button-curved',
full: 'nui-button-full',
}
const sizeStyle = {
sm: 'nui-button-small',
md: 'nui-button-medium',
lg: 'nui-button-large',
}
const colorStyle = {
default: 'nui-button-default',
muted: 'nui-button-muted',
primary: 'nui-button-primary',
info: 'nui-button-info',
success: 'nui-button-success',
warning: 'nui-button-warning',
danger: 'nui-button-danger',
none: '',
}

const colorClass = computed(() => {
return [
props.color === 'muted' &&
'text-muted-500 bg-muted-200 dark:text-white dark:bg-muted-700 dark:hover:bg-muted-600 hover:bg-muted-100',

props.color === 'primary' &&
'text-primary-500 border-2 border-primary-500 hover:bg-primary-500/20',
props.color === 'default' &&
'text-muted-700 bg-white border border-muted-300 dark:text-white dark:bg-muted-700 dark:hover:bg-muted-600 dark:border-muted-600 hover:bg-muted-50',
].join(' ') // note the join(' ') here
})

const sizeClass = computed(() =>
props.condensed ? 'h-8 w-8 p-1' : 'h-10 w-10 p-2'
)

const iconButtonClasses = computed(() => [
'disabled:opacity-60 disabled:cursor-not-allowed hover:shadow-none',
props.loading ? '!text-transparent' : '',
colorClass.value,
const classes = computed(() => [
'nui-button-icon',
props.loading && 'nui-button-loading',
shape.value && shapeStyle[shape.value],
sizeClass.value,
sizeStyle[props.size],
colorStyle[props.color],
])

const { attributes, is } = useNinjaButton(props)
</script>

<template>
<component
:is="is"
v-bind="attributes"
:class="iconButtonClasses"
class="nui-focus relative inline-flex items-center justify-center space-x-1 font-sans text-sm font-normal leading-5 no-underline outline-none transition-all duration-300"
>
<component :is="is" v-bind="attributes" :class="classes">
<slot v-if="!props.loading"></slot>
<BasePlaceload v-else class="h-4 w-4 rounded-md" />
</component>
Expand Down