-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e93205d
commit 7a8cf02
Showing
4 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { D9SplitButton } from "../index"; | ||
import { icons } from "../index"; | ||
|
||
export default { | ||
title: "Basics/SplitButton", | ||
component: D9SplitButton, | ||
argTypes: { | ||
color: { | ||
options: ["primary", "light", "dark", "danger"], | ||
}, | ||
size: { | ||
options: ["small", "medium", "large"], | ||
}, | ||
icon: { options: icons, control: { type: "select" } }, | ||
iconPosition: { options: ["left", "right"] }, | ||
onClick: { action: "clicked" }, | ||
}, | ||
}; | ||
|
||
const Template = (args: Record<string, unknown>) => ({ | ||
components: { D9SplitButton }, | ||
setup() { | ||
return { args }; | ||
}, | ||
template: '<D9SplitButton v-bind="args" />', | ||
}); | ||
|
||
export const Medium = Template.bind({}); | ||
Medium.args = { | ||
label: "Split Button", | ||
size: "medium", | ||
}; | ||
|
||
export const Small = Template.bind({}); | ||
Small.args = { | ||
size: "small", | ||
label: "Split Button", | ||
}; | ||
|
||
export const Large = Template.bind({}); | ||
Large.args = { | ||
size: "large", | ||
label: "Split Button", | ||
}; | ||
|
||
export const Disabled = Template.bind({}); | ||
Disabled.args = { | ||
label: "Split Button", | ||
isDisabled: true, | ||
}; | ||
|
||
export const Loading = Template.bind({}); | ||
Loading.args = { | ||
label: "Split Button", | ||
isLoading: true, | ||
}; | ||
|
||
export const LoadingAndDisabled = Template.bind({}); | ||
LoadingAndDisabled.args = { | ||
label: "Split Button", | ||
isDisabled: true, | ||
isLoading: true, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
<template> | ||
<div | ||
class="relative inline-flex items-center focus:outline-none focus:ring active:ring transition duration-150 ease-in-out rounded-lg overflow-hidden" | ||
> | ||
<button | ||
type="button" | ||
:aria-label="label" | ||
:tabindex="isDisabled ? '-1' : undefined" | ||
class="relative" | ||
:class="buttonClasses" | ||
@click="onClickMain" | ||
> | ||
<div :class="!isLoading || 'invisible'"> | ||
<span>{{ label }}</span> | ||
</div> | ||
|
||
<span | ||
v-if="isLoading" | ||
class="absolute inset-0 flex items-center justify-center" | ||
> | ||
<D9Icon class="ml-3 animate-spin" name="circle-notch" /> | ||
</span> | ||
</button> | ||
<button | ||
class="border-l-white/50 border-l" | ||
:class="[buttonClasses, splitButtonClasses]" | ||
@click="onClickSplit" | ||
> | ||
<D9Icon :class="[iconClasses]" :name="icon" /> | ||
</button> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import D9Icon from "../Icon/Icon.vue"; | ||
import { ColorScheme, Size } from "../types/types"; | ||
import { computed, withDefaults } from "vue"; | ||
interface ButtonProps { | ||
label: string; | ||
size?: Size; | ||
color?: ColorScheme; | ||
isLoading?: boolean; | ||
isDisabled?: boolean; | ||
icon?: string; | ||
} | ||
interface ButtonEmits { | ||
(e: "onClick"): void; | ||
(e: "onClickSplit"): void; | ||
} | ||
const emit = defineEmits<ButtonEmits>(); | ||
const props = withDefaults(defineProps<ButtonProps>(), { | ||
size: "medium", | ||
color: "primary", | ||
isLoading: false, | ||
isDisabled: false, | ||
icon: "plus", | ||
}); | ||
const buttonClasses = computed(() => { | ||
const colors = { | ||
"text-white bg-blue-600 border-transparent hover:bg-blue-700 active:bg-blue-700 dark:ring-blue-800 ring-offset-2 dark:ring-offset-grey-900": | ||
props.color === "primary", | ||
"text-blue-600 bg-grey-100 border-transparent hover:bg-blue-100 hover:text-blue-700 active:bg-grey-100 ring-blue-300 ring-offset-2 dark:ring-offset-grey-900": | ||
props.color === "light", | ||
"text-grey-50 bg-grey-700 border-transparent hover:bg-grey-800 active:bg-grey-700 ring-grey-500 dark:ring-grey-400 dark:ring-opacity-50 ring-offset-2 dark:ring-offset-grey-900": | ||
props.color === "dark", | ||
"text-red-50 bg-red-500 border-transparent hover:bg-red-600 active:bg-red-600 ring-red-400 dark:ring-red-400 dark:ring-opacity-50 ring-offset-2 dark:ring-offset-red-900": | ||
props.color === "danger", | ||
}; | ||
const sizes = { | ||
"px-4 py-1 text-xs leading-5 mono-100": props.size === "small", | ||
"px-5 py-2 text-sm leading-4 font-medium": props.size === "medium", | ||
"px-8 pr-4 py-3 text-base leading-6 font-medium": props.size === "large", | ||
}; | ||
const disabledClasses = { | ||
"pointer-events-none opacity-75 cursor-not-allowed": props.isDisabled, | ||
}; | ||
return { | ||
...colors, | ||
...disabledClasses, | ||
...sizes, | ||
}; | ||
}); | ||
const splitButtonClasses = computed(() => { | ||
const colors = { | ||
"border-l-white/50 border-l": props.color === "primary", | ||
"border-l-blue-100 border-l": props.color === "light", | ||
"border-l-grey-600 border-l": props.color === "dark", | ||
"border-l-red-600 border-l": props.color === "danger", | ||
}; | ||
const sizes = { | ||
"pl-2 pr-3": props.size === "small", | ||
"pl-3 pr-3": props.size === "medium", | ||
"pl-4 pr-5": props.size === "large", | ||
}; | ||
return { | ||
...colors, | ||
...sizes, | ||
}; | ||
}); | ||
const iconClasses = computed(() => { | ||
const colors = { | ||
"text-white": props.color === "primary", | ||
"text-blue-600": props.color === "light", | ||
"text-grey-50": props.color === "dark", | ||
}; | ||
return { | ||
...colors, | ||
}; | ||
}); | ||
function onClickMain() { | ||
if (props.isDisabled) { | ||
return; | ||
} | ||
emit("onClick"); | ||
} | ||
function onClickSplit() { | ||
if (props.isDisabled) { | ||
return; | ||
} | ||
emit("onClickSplit"); | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as D9SplitButton } from "./SplitButton.vue"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters