ui icon indicating copy to clipboard operation
ui copied to clipboard

Buttons size based on device?

Open jeannen opened this issue 1 year ago • 9 comments
trafficstars

For what version of Nuxt UI are you asking this question?

v2.x

Description

Hi!

I was wondering if there was an easy way to change variants/sizes etc for components (particularly buttons) based on the user's device

For example,

<UButton size="sm xl:lg"/>

There are lots of instances where a button need to be smaller on mobile, so would be nice to have that! I didn't found anything in the docs

P.S. bought Nuxt UI Pro a couple of days ago to support the team. Keep up the great work! 😄

jeannen avatar Oct 16 '24 03:10 jeannen

I think there are two options

  1. you can create a computed prop that gets updated on resize
<script setup>
const windowWidth = ref(window?.innerWidth);
onMounted(() => {
  window.addEventListener('resize', () => {
    windowWidth.value = window.innerWidth;
  });
});
const btnSize = computed(() => {
  if (windowWidth.value < 800) {
    return 'md';
  } else {
    return 'xl';
  }
});
</script>
<template>
  <UContainer class="min-h-screen flex items-center">
    <UButton :size="btnSize">Button Size</UButton>
  </UContainer>
</template>
  1. or just update the defaults and add responsive breakpoints
padding: {
  '2xs': 'px-1 py-0.5 lg:px-2 lg:py-1',
  xs: 'px-2 py-1 lg:px-2.5 lg:py-1.5',
  sm: 'px-2 py-1 lg:px-2.5 lg:py-1.5',
  md: 'px-2 py-1.5 lg:px-3 lg:py-2',
  lg: 'px-2.5 py-1.5 lg:px-3.5 lg:py-2.5',
  xl: 'px-3 py-1.5 lg:px-4 lg:py-2.5',
},

gregorvoinov avatar Oct 17 '24 11:10 gregorvoinov

Option 1 would means adding a computed value for every different button, so that would be a bit overkill

And Option 2 would not really works, some buttons need to keep the same size and others need to get bigger

jeannen avatar Oct 17 '24 12:10 jeannen

for sure you have to wrap this around another component let's call it responsiveButton

//responsiveButton.vue
<script setup>
  const props = {
    size: {
      default: 'md',
    },
  };
</script>

<template>
  <UButton 
    :size="props.size"
    :ui={
      padding: {
        '2xs': 'px-1 py-0.5 lg:px-2 lg:py-1',
        xs: 'px-2 py-1 lg:px-2.5 lg:py-1.5',
        sm: 'px-2 py-1 lg:px-2.5 lg:py-1.5',
        md: 'px-2 py-1.5 lg:px-3 lg:py-2',
        lg: 'px-2.5 py-1.5 lg:px-3.5 lg:py-2.5',
        xl: 'px-3 py-1.5 lg:px-4 lg:py-2.5',
      }
    }
  >
    <slot></slot>
  </UButton>
</template>

also for variant 1 you should create a wrapper component around your logic

gregorvoinov avatar Oct 17 '24 12:10 gregorvoinov

Note that you could use useBreakpoints() from VueUse to help you with this

noook avatar Oct 17 '24 13:10 noook

In v3, we might be able to solve this by using Tailwind Variants responsive variants: https://www.tailwind-variants.org/docs/variants#responsive-variants

However, it's not supported yet for Tailwind CSS v4: https://github.com/nextui-org/tailwind-variants/issues/217

benjamincanac avatar Nov 15 '24 11:11 benjamincanac

This is really needed. Especially for buttons, I find myself using :ui frequently to adjust button sizes. A large button on large devices really needs to go to md on small devices. I'm hoping to see this happening when Tailwind Variants catch up. 🙏

Youhan avatar Dec 05 '24 05:12 Youhan

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Feb 14 '25 01:02 github-actions[bot]

I agree this feature is really needed. It's weird but I find it easier to have 2 buttons and hide/show them with tailwind (that could be wrapped via a UResponsiveButton too)

jedjebari avatar Apr 05 '25 09:04 jedjebari

Re: customizing "padding"

:ui={
      padding: {
        '2xs': 'px-1 py-0.5 lg:px-2 lg:py-1',
        xs: 'px-2 py-1 lg:px-2.5 lg:py-1.5',
        sm: 'px-2 py-1 lg:px-2.5 lg:py-1.5',
        md: 'px-2 py-1.5 lg:px-3 lg:py-2',
        lg: 'px-2.5 py-1.5 lg:px-3.5 lg:py-2.5',
        xl: 'px-3 py-1.5 lg:px-4 lg:py-2.5',
      }
 }

Is this a proposal or does it already exist?

kalnode avatar Apr 06 '25 13:04 kalnode