Playing Next Lesson In
seconds

EdgeJS Components #3.2

Adding Button Size Options

In This Lesson

We'll add four size options to our base button large, base, small, and extra small. These sizes will then automatically be available as we add our button variants and styles.

Created by
@tomgobich
Published

Next, let’s add size options to our button. We’re going to have four different size options, which we’ll define directly inside our base button.

  1. lg: Large

  2. base: Base (which we already have)

  3. sm: Small

  4. xs: Extra small

Defining our Button Sizes

The first thing we’ll want to do is remove the current size-based classes from our base button, we’ll then use these classes to define our base size option.

As a reminder, here’s what we currently have for our base button component:

<button 
  {{ $props.serializeExcept(['type', 'class']) }}
  x-data
  type="{{ type || 'button' }}"
  class="{{ $props.class }} inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none">
  {{{ await $slots.main() }}}
</button>
Copied!
  • resources
  • views
  • components
  • button
  • index.edge

So, we’ll want to cut the following size-based classes from our class attribute: px-4 py-2 text-sm, then we’ll define a variable using @set called sizes. This will be an object, where the key is the size name and the value is the size’s classes.

++@set('sizes', {
  base: 'px-4 py-2 text-sm',
})

<button 
  {{ $props.serializeExcept(['type', 'class']) }}
  x-data
  type="{{ type || 'button' }}"
  class="{{ $props.class }} inline-flex items-center justify-center font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none">
  class="{{ $props.class }} inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none">
  {{{ await $slots.main() }}}
</button>
Copied!
  • resources
  • views
  • components
  • button
  • index.edge

Then, we’ll add in the other three sizes to our sizes object, in the same manner as our base button.

@set('sizes', {
  xs: 'px-2.5 py-1 text-xs',
  sm: 'px-3 py-1.5 text-sm',
  base: 'px-4 py-2 text-sm',
  lg: 'px-5 py-2.5 text-base'
})

<button 
  {{ $props.serializeExcept(['type', 'class']) }}
  x-data
  type="{{ type || 'button' }}"
  class="{{ $props.class }} inline-flex items-center justify-center font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none">
  {{{ await $slots.main() }}}
</button>
Copied!
  • resources
  • views
  • components
  • button
  • index.edge

Applying A Size

Lastly, we’ll need to actually apply one of the values from our sizes object into our class list. To do this, we’ll accept a prop called size, however, we’ll also want to have a default value for size set to base.

++@set('size', size || 'base')
@set('sizes', {
  xs: 'px-2.5 py-1 text-xs',
  sm: 'px-3 py-1.5 text-sm',
  base: 'px-4 py-2 text-sm',
  lg: 'px-5 py-2.5 text-base'
})

<button 
  {{ $props.serializeExcept(['type', 'class']) }}
  x-data
  type="{{ type || 'button' }}"
  class="{{ $props.class }} inline-flex items-center justify-center font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none">
  {{{ await $slots.main() }}}
</button>
Copied!
  • resources
  • views
  • components
  • button
  • index.edge

Then, we can use size to reach for a key in sizes to apply a value into our class list.

@set('size', size || 'base')
@set('sizes', {
  xs: 'px-2.5 py-1 text-xs',
  sm: 'px-3 py-1.5 text-sm',
  base: 'px-4 py-2 text-sm',
  lg: 'px-5 py-2.5 text-base'
})

<button 
  {{ $props.serializeExcept(['type', 'class']) }}
  x-data
  type="{{ type || 'button' }}"
  class="{{ sizes[size] }} {{ $props.class }} inline-flex items-center justify-center font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none">
  class="{{ $props.class }} inline-flex items-center justify-center font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none">
  {{{ await $slots.main() }}}
</button>
Copied!
  • resources
  • views
  • components
  • button
  • index.edge

Now we can make use of our sizes as follows

@layout.app({ title: request.params().name })

  <h3 class="font-bold">Base Button</h3>
  <div x-data @click="alert('Thanks for clicking!')" class="mb-8 space-x-3 space-y-3">
    @button()
      Default, Base Button
    @end
  </div>

  <h3 class="font-bold">Sizes</h3>
  <div class="mb-8 space-x-3 space-y-3">
    @button({ size: 'lg' })
      LG Button
    @end
    
    @button({ size: 'base' })
      Base Button
    @end

    @button({ size: 'sm' })
      SM Button
    @end

    @button({ size: 'xs' })
      XS Button
    @end
  </div>

@end
Copied!
  • resources
  • views
  • pages
  • components
  • buttons.edge

Join the Discussion 0 comments

Create a free account to join in on the discussion
robot comment bubble

Be the first to comment!