Skip to content

Commit

Permalink
[#44] Adds a button component
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuapease committed Sep 24, 2024
1 parent 82acf58 commit dfd45c6
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 4 deletions.
107 changes: 107 additions & 0 deletions config/tailwind/buttons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import plugin from 'tailwindcss/plugin'

export default plugin(({ addComponents }) => {
// Base Styles
const base = {
// core
'@apply inline-flex items-center rounded font-bold transition text-base gap-12 cursor-pointer no-underline':
{},
// focus
'@apply focus:outline-none focus-visible:ring-4': {},
// disabled
'@apply disabled:opacity-20 disabled:pointer-events-none': {},
// icon
'& svg': {
'@apply size-20': {},
},
// text exempt
'&:not(.btn-text)': {
'@apply px-20 min-h-40': {},
},
}

const buttons = {
// Button Variants
'.btn-contained': {
...base,
[`@apply
bg-sky-600 text-white
hover:bg-sky-700
active:bg-sky-800
focus-visible:bg-sky-700 focus-visible:ring-sky-600/50
dark:bg-sky-200 dark:text-sky-800
dark:hover:bg-sky-50
dark:active:bg-sky-100
dark:focus-visible:bg-sky-50 dark:focus-visible:ring-white/50`]: {},
},

'.btn-outlined': {
...base,
[`@apply
border border-sky-600 bg-transparent text-sky-600
hover:bg-sky-100 hover:border-sky-700 hover:text-sky-700
active:bg-sky-200/80 active:text-sky-800
focus-visible:bg-sky-100 focus-visible:border-sky-700 focus-visible:ring-sky-600/50
dark:border-white dark:text-white
dark:hover:bg-white/25
dark:active:bg-white/30
dark:focus-visible:bg-sky-100/30 dark:focus-visible:ring-white/50`]: {},
},

'.btn-subtle': {
...base,
[`@apply
bg-transparent bg-transparent text-sky-600
hover:bg-sky-100 hover:text-sky-700
active:bg-sky-200/80 active:text-sky-800
focus-visible:bg-sky-100 focus-visible:border-sky-700 focus-visible:ring-sky-600/50
dark:text-white
dark:hover:bg-white/25
dark:active:bg-white/30
dark:focus-visible:bg-sky-100/30 dark:focus-visible:ring-white/75`]: {},
},

'.btn-text': {
...base,
[`@apply
bg-transparent text-sky-600
hover:text-sky-700 hover:underline
active:text-sky-800
focus-visible:bg-sky-100 focus-visible:ring-sky-600/50
dark:border-white dark:text-white
dark:hover:text-white/90
dark:active:text-white/80
dark:focus-visible:bg-sky-100/30 dark:focus-visible:ring-white/75`]:
{},
},

// Button Sizes
'.btn-sm': {
'@apply text-sm gap-8': {},
'& svg': {
'@apply size-16': {},
},
'&:not(.btn-text)': {
'@apply px-16 min-h-32': {},
},
},
'.btn-lg': {
'@apply text-xl gap-12': {},
'& svg': {
'@apply size-24': {},
},
'&:not(.btn-text)': {
'@apply px-32 min-h-56': {},
},
},

// Button Icon/Sizes
'.btn-icon': {
fontSize: '0 !important',
lineHeight: '0 !important',
'@apply !p-0 !gap-0 aspect-square justify-center items-center': {},
},
}

addComponents(buttons)
})
2 changes: 0 additions & 2 deletions src/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@

body {
font-family: 'Source Sans Pro', sans-serif;
background: black;
color: white;
}

strong {
Expand Down
42 changes: 40 additions & 2 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,46 @@
import buttons from './config/tailwind/buttons'

/**
Helper function to pair key and value together
Note: PostCSS Converts all `px` values to `rem`
*/
function pxPair(value) {
return { [value]: `${value}px` }
}

/** @type {import('tailwindcss').Config} */
export default {
content: ['./templates/**/*.twig', './src/**/*.{js,jsx,ts,tsx,svg}'],
content: ['./templates/**/*.{twig,html}', './src/**/*.{js,jsx,ts,tsx,svg}'],
theme: {
spacing: {
...pxPair(0),
...pxPair(1),
...pxPair(2),
...pxPair(4),
...pxPair(6),
...pxPair(8),
...pxPair(10),
...pxPair(12),
...pxPair(16),
...pxPair(20),
...pxPair(24),
...pxPair(28),
...pxPair(32),
...pxPair(36),
...pxPair(40),
...pxPair(44),
...pxPair(48),
...pxPair(52),
...pxPair(56),
...pxPair(60),
...pxPair(64),
...pxPair(80),
...pxPair(96),
...pxPair(112),
...pxPair(128),
},
extend: {},
},
plugins: [],
plugins: [buttons],
}
61 changes: 61 additions & 0 deletions templates/_components/button.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{% from '_macros/icon.twig' import icon %}

{# @var string|null as #}
{% set as = as ?? null %}

{# @var string variant #}
{% set variant = variant ?? 'contained' %}

{# @var string size #}
{% set size = size ?? 'md' %}

{# @var string|null title #}
{% set title = title ?? null %}

{# @var string|null icon The name of the icon to use #}
{% set icon = icon ?? null %}

{# @var boolean iconOnly #}
{% set iconOnly = iconOnly ?? false %}

{# @var string|null href #}
{% set href = href ?? null %}

{# @var string type #}
{% set type = type ?? 'button' %}

{# @var boolean disabled #}
{% set disabled = disabled ?? false %}

{# @var string|null class #}
{% set class = class ?? null %}

{# @var string|null text #}
{% set text = text ?? null %}

{# Determine element type #}
{% set el = as ?? (href and not disabled ? 'a' : 'button') %}

{% tag el with {
href: not disabled ? href : null,
disabled: disabled ? true : null,
type: el == 'button' ? type : null,
title: title,
class: classNames({
'btn-contained': variant == 'contained',
'btn-outlined': variant == 'outlined',
'btn-subtle': variant == 'subtle',
'btn-text': variant == 'text',
'btn-icon': iconOnly,
'btn-sm': size == 'sm',
'btn-lg': size == 'lg',
}, class),
} %}

{{ icon ? icon({
name: icon,
size: size,
}) }}

{{ text }}
{% endtag %}
107 changes: 107 additions & 0 deletions templates/parts-kit/button/default.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
{% extends 'viget-parts-kit/layout.twig' %}

{% set sizes = ['sm', 'md', 'lg'] %}

{% block main %}
<div class="flex flex-col gap-16">
{% for size in sizes %}
<div class="flex items-center gap-16">
<h3 class="text-lg font-bold">{{ size }}</h3>

{{ include('_components/button.twig', {
variant: 'contained',
text: 'Button',
size,
}) }}

{{ include('_components/button.twig', {
variant: 'outlined',
text: 'Button',
size,
}) }}

{{ include('_components/button.twig', {
variant: 'subtle',
text: 'Button',
size,
}) }}

{{ include('_components/button.twig', {
variant: 'text',
text: 'Button',
size,
}) }}
</div>
{% endfor %}
</div>

<hr class="my-32">

<div class="flex flex-col gap-16">
<h1 class="text-2xl font-bold">With Icon</h1>
{% for size in sizes %}
<div class="flex items-center gap-16">
<h3 class="text-lg font-bold">{{ size }}</h3>
{{ include('_components/button.twig', {
variant: 'contained',
text: 'Button',
size,
icon: 'arrow-right',
}) }}

{{ include('_components/button.twig', {
variant: 'contained',
text: 'Button',
size,
icon: 'arrow-right',
iconOnly: true,
}) }}

{{ include('_components/button.twig', {
variant: 'outlined',
text: 'Button',
size,
icon: 'arrow-right',
}) }}

{{ include('_components/button.twig', {
variant: 'outlined',
text: 'Button',
size,
icon: 'arrow-right',
iconOnly: true,
}) }}

{{ include('_components/button.twig', {
variant: 'subtle',
text: 'Button',
size,
icon: 'arrow-right',
}) }}

{{ include('_components/button.twig', {
variant: 'subtle',
iconOnly: true,
text: 'Button',
size,
icon: 'arrow-right',
}) }}

{{ include('_components/button.twig', {
variant: 'text',
text: 'Button',
size,
icon: 'arrow-right',
}) }}

{{ include('_components/button.twig', {
variant: 'text',
text: 'Button',
size,
icon: 'arrow-right',
iconOnly: true,
}) }}
</div>
{% endfor %}
</div>
{% endblock %}

0 comments on commit dfd45c6

Please sign in to comment.