Mn Button uses Tamagui button and add ablility to add loading state and shaped button (square)
import { Separator, XStack, YStack } from 'tamagui'
import { MnButton } from 'yourpath/ui'
const DemoButton = () => {
return (
<>
<YStack
minHeight={250}
overflow="hidden"
margin="$3"
padding="$2"
justifyContent="space-between"
>
<XStack gap={'$4'}>
<MnButton loading>Loading</MnButton>
<MnButton size={'$10'}>Normal Button</MnButton>
<MnButton size={'$10'} circular>
A
</MnButton>
</XStack>
<XStack gap={'$2'}>
<XStack gap={'$4'}>
<MnButton size={'$1'} circular>
A
</MnButton>
<MnButton size={'$2'} circular>
B
</MnButton>
<MnButton size={'$3'} circular>
C
</MnButton>
<MnButton size={'$4'} circular>
D
</MnButton>
<MnButton size={'$5'} circular>
E
</MnButton>
<MnButton size={'$6'} circular>
F
</MnButton>
</XStack>
<XStack gap={'$4'}>
<MnButton size={'$6'} square>
F
</MnButton>
<MnButton size={'$5'} square>
E
</MnButton>
<MnButton size={'$4'} square>
D
</MnButton>
<MnButton size={'$3'} square>
C
</MnButton>
<MnButton size={'$2'} square>
B
</MnButton>
<MnButton size={'$1'} square>
A
</MnButton>
</XStack>
</XStack>
</YStack>
</>
)
}
export default DemoButton
Props
Button Code
import { SizeTokens, styled, TokensParsed } from '@tamagui/web'
import { FunctionComponent } from 'react'
import { Button, ButtonProps, getTokens, Spinner } from 'tamagui'
type InputComponentIconProps = { color?: any; size?: any }
type IconProp = JSX.Element | FunctionComponent<InputComponentIconProps> | null
export interface IMnButtonProps extends ButtonProps {
loading?: boolean
loadingIcon?: IconProp
loadingIconAligment?: 'left' | 'right'
square?: boolean
}
export const getSquareShapeSize = (size, { tokens }) => {
const width = tokens.size[size] ?? size
const height = tokens.size[size] ?? size
return {
width,
height,
minWidth: width,
maxWidth: width,
maxHeight: height,
minHeight: height,
padding: 0,
}
}
const getShapeSize = ({
size,
tokens,
shape,
}: {
size: number | SizeTokens | undefined
tokens: TokensParsed
shape?: 'square'
}) => {
if (!shape) {
return {}
}
return getSquareShapeSize(size, {
tokens,
})
}
export const MnButton = (props: IMnButtonProps) => {
const {
loading = false,
loadingIcon = Spinner,
loadingIconAligment,
children,
square = false,
...rest
} = props
const size = props.size || (props.unstyled ? undefined : '$true')
const tokens = getTokens({ prefixed: true })
const shapeSize = getShapeSize({
size,
tokens,
shape: square ? 'square' : undefined,
})
return (
// @ts-ignore
<Button
size={size}
{...rest}
disabled={loading}
{...(loading
? loadingIconAligment === 'left'
? { left: Spinner, opacity: 0.5 }
: { iconAfter: Spinner, opacity: 0.5 }
: {})}
{...(square && shapeSize)}
>
{children}
</Button>
)
}