Skip to content

Instantly share code, notes, and snippets.

@dontwork
Created May 9, 2020 21:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dontwork/c0c51e00b35e1821b433f9212d8596bd to your computer and use it in GitHub Desktop.
Save dontwork/c0c51e00b35e1821b433f9212d8596bd to your computer and use it in GitHub Desktop.
Btn
import m from 'mithril'
import { splitAttrs } from '../utils'
import { Icon } from '../Icon'
import loadingIcon from './loading.svg'
const sizes = {
shape: {
circle: {
size: {
sm: ['h-6', 'w-6', 'text-sm'],
md: ['h-8', 'w-8', 'text-md'],
lg: ['h-10', 'w-10', 'text-lg']
}
},
round: {
size: {
sm: ['px-2', 'py-1', 'text-sm'],
md: ['px-3', 'py-1', 'text-md'],
lg: ['px-4', 'py-2', 'text-lg']
}
},
normal: {
size: {
sm: ['px-2', 'py-1', 'text-sm'],
md: ['px-3', 'py-1', 'text-md'],
lg: ['px-4', 'py-2', 'text-lg']
}
}
}
}
const shapes = {
circle: ['rounded-full'],
round: ['rounded-full'],
normal: ['rounded-sm']
}
const styles = [
'relative',
'flex',
'items-center',
'justify-center',
'select-none',
'focus:outline-none',
'transition-all',
'duration-200'
]
const variants = {
primary: {
dark: {
disabled: [
'cursor-not-allowed',
'border',
'border-gray-700',
'bg-gray-800',
'text-gray-600'
],
normal: [
'border',
'border-indigo-600',
'bg-indigo-700',
'text-indigo-100',
'hover:bg-indigo-800',
'focus:bg-indigo-800',
'hover:border-indigo-700',
'focus:border-indigo-700',
'active:dec-outline-dark'
],
danger: [
'border',
'border-red-600',
'bg-red-700',
'text-red-100',
'hover:bg-red-800',
'focus:bg-red-800',
'hover:border-red-700',
'focus:border-red-700',
'active:dec-outline-danger-dark'
]
},
light: {
disabled: [
'cursor-not-allowed',
'border',
'border-gray-00',
'bg-gray-200',
'text-gray-500'
],
normal: [
'border',
'border-indigo-800',
'bg-indigo-600',
'text-white',
'button-shadow',
'hover:bg-indigo-500',
'focus:bg-indigo-500',
'hover:border-indigo-600',
'focus:border-indigo-600',
'active:dec-outline'
],
danger: [
'border',
'border-red-600',
'bg-red-500',
'text-white',
'button-shadow',
'hover:bg-red-400',
'focus:bg-red-400',
'hover:border-red-500',
'focus:border-red-500',
'active:dec-outline-danger'
]
}
},
default: {
dark: {
disabled: [
'cursor-not-allowed',
'border',
'border-gray-700',
'bg-gray-800',
'text-gray-600'
],
normal: [
'border',
'border-gray-700',
'bg-gray-800',
'text-gray-100',
'button-shadow',
'hover:border-indigo-700',
'hover:text-indigo-300',
'focus:border-indigo-700',
'focus:text-indigo-300',
'active:dec-outline-dark'
],
danger: [
'border',
'border-red-700',
'bg-gray-800',
'text-red-600',
'button-shadow',
'hover:border-red-800',
'hover:text-red-700',
'focus:border-red-800',
'focus:text-red-700',
'active:dec-outline-danger-dark'
]
},
light: {
disabled: [
'cursor-not-allowed',
'border',
'border-gray-400',
'bg-gray-200',
'text-gray-500'
],
normal: [
'border',
'bg-white',
'text-gray-700',
'button-shadow',
'hover:border-blue-500',
'hover:text-blue-500',
'focus:border-blue-500',
'focus:text-blue-500',
'active:dec-outline'
],
danger: [
'border',
'border-red-400',
'bg-white',
'text-red-500',
'button-shadow',
'hover:border-red-500',
'hover:text-red-500',
'focus:border-red-500',
'focus:text-red-500',
'active:dec-outline-danger'
]
}
},
dashed: {
dark: {
disabled: [
'cursor-not-allowed',
'border',
'border-gray-700',
'border-dashed',
'bg-gray-800',
'text-gray-600'
],
normal: [
'border',
'border-dashed',
'border-gray-700',
'bg-gray-800',
'text-gray-100',
'button-shadow',
'hover:border-indigo-700',
'hover:text-indigo-300',
'focus:border-indigo-700',
'focus:text-indigo-300',
'active:dec-outline-dark'
],
danger: [
'border',
'border-dashed',
'border-red-700',
'bg-gray-800',
'text-red-600',
'button-shadow',
'hover:border-red-800',
'hover:text-red-700',
'focus:border-red-800',
'focus:text-red-700',
'active:dec-outline-danger-dark'
]
},
light: {
disabled: [
'cursor-not-allowed',
'border',
'border-gray-400',
'border-dashed',
'bg-gray-200',
'text-gray-500'
],
normal: [
'border',
'border-gray-400',
'border-dashed',
'bg-white',
'text-gray-700',
'button-shadow',
'hover:border-blue-500',
'hover:text-blue-500',
'focus:border-blue-500',
'focus:text-blue-500',
'active:border-blue-800',
'active:text-blue-800',
'active:dec-outline'
],
danger: [
'border',
'border-red-400',
'border-dashed',
'bg-white',
'text-red-500',
'button-shadow',
'hover:border-red-500',
'hover:text-red-600',
'focus:border-red-500',
'focus:text-red-600',
'active:border-red-800',
'active:text-red-800',
'active:dec-outline-danger'
]
}
},
link: {
dark: {
disabled: [
'text-gray-500',
'cursor-not-allowed'
],
normal: [
'text-indigo-400',
'hover:bg-gray-800',
'hover:text-indigo-300',
'focus:bg-gray-800',
'focus:text-indigo-300',
'active:bg-gray-800',
'active:text-indigo-300'
],
danger: [
'text-red-600',
'hover:bg-gray-800',
'hover:text-red-700',
'focus:bg-gray-800',
'focus:text-red-300',
'active:bg-gray-800',
'active:text-red-300'
]
},
light: {
disabled: [
'text-gray-500',
'cursor-not-allowed'
],
normal: [
'text-blue-500',
'hover:bg-blue-100',
'hover:text-blue-700',
'focus:bg-blue-100',
'focus:text-blue-800',
'active:bg-blue-100',
'active:text-blue-800'
],
danger: [
'text-red-500',
'hover:bg-red-100',
'hover:text-red-700',
'focus:bg-red-100',
'focus:text-red-800',
'active:bg-red-100',
'active:text-red-800'
]
}
}
}
const loading = {
true: ['opacity-50', 'pointer-events-none'],
false: []
}
const icon = {
sm: ['pl-6'],
md: ['pl-8'],
lg: ['pl-10']
}
const ButtonAttrs = {
element: 'button',
size: 'md',
shape: 'normal',
disabled: false,
variant: 'default',
mode: window.decConfig.mode || 'light',
onclick: () => {},
icon: null,
danger: false,
loading: false
}
export const Button = () => {
return {
view ({ attrs = { }, children }) {
const { componentAttrs, proxiedAttrs, handle } = splitAttrs(attrs, ButtonAttrs, ['class'])
const isCircle = componentAttrs.shape === 'circle'
const isLoading = componentAttrs.loading
const style = componentAttrs.disabled ? 'disabled' : componentAttrs.danger ? 'danger' : 'normal'
return m(componentAttrs.element, {
class: [
...styles,
...sizes.shape[componentAttrs.shape].size[componentAttrs.size],
...variants[componentAttrs.variant][componentAttrs.mode][style],
...shapes[componentAttrs.shape],
...loading[isLoading],
...((componentAttrs.icon || isLoading) && !isCircle ? icon[componentAttrs.size] : []),
handle.class
].join(' '),
disabled: componentAttrs.disabled || isLoading,
onclick (e) {
componentAttrs.onclick(e)
},
...proxiedAttrs
}, [
(!!componentAttrs.icon || isLoading) &&
m('', {
class: [
isLoading ? 'fade-in' : '',
!isCircle ? 'absolute left-2' : ''
].join(' ')
}, [
m(Icon, {
size: componentAttrs.size,
icon: isLoading ? loadingIcon : componentAttrs.icon,
class: [
].join(' '),
spin: isLoading
})
]),
(!isCircle || !isLoading) &&
children
])
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment