tailwindcss-custom-forms icon indicating copy to clipboard operation
tailwindcss-custom-forms copied to clipboard

Indeterminate state for checkboxes

Open stfcodes opened this issue 5 years ago • 9 comments

Hey @adamwathan, thanks for the amazing library and this plugin!

I'm writing here so I mostly don't forget, but it seems that .form-checkbox removes native stylings but doesn't add one for the indeterminate state.

Checkboxes can be checked, unchecked, as well as indeterminate. Indeterminate is not usually used, but has its visual benefits. More info on MDN.

Would be great if the form-checkbox class supports the indeterminate state.

stfcodes avatar Aug 06 '19 20:08 stfcodes

As a temporary workaround I added this to my tailwind config inside module.exports.theme:

    customForms: theme => ({
      default: {
        checkbox: {
          '&:indeterminate': {
            background: 'url("data:image/svg+xml,%3Csvg viewBox=\'0 0 16 16\' fill=\'white\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Crect width=\'8\' height=\'2\' x=\'4\' y=\'7\' rx=\'1\'/%3E%3C/svg%3E");',
            borderColor: 'transparent',
            backgroundColor: 'currentColor',
            backgroundSize: '100% 100%',
            backgroundPosition: 'center',
            backgroundRepeat: 'no-repeat',
          }
        }
      }
    })

image

molteber avatar Sep 12 '19 13:09 molteber

@molteber I actually can't get this working. I added literally what you posted above in the module.exports.theme and when indeterminate is added onto the checkbox, it stays the same. I'm using @tailwind/ui so thought that was the issue with something clashing maybe. Removed it and still same issue. Any suggestions on your code from above?

imjakechapman avatar Sep 23 '20 09:09 imjakechapman

@molteber I am not sure what is happening, but your overwrite messed with other components, for example regular input styling gets messed up with a different focus colour and border. I presume customForms overrides the defaults, resulting in this issue?

@imjakechapman indeterminate does work with this method tho, how are you setting the state of the checkbox?

doutatsu avatar Oct 08 '20 09:10 doutatsu

@doutatsu I actually haven't gotten this to work. I spoke with @adamwathan on twitter and he said he was going to be looking into this soon, in the mean time I've actually changed the functionality of the feature I was working on to be non indeterminate. But he mentioned just doing regular css for the styles.

imjakechapman avatar Oct 08 '20 09:10 imjakechapman

@imjakechapman Here is my custom component in Vue, in case it could give you an idea. Good to hear that Adam might be looking into this soon, the style override is a deal breaker for me atm, so having to find another method of doing this

<template lang="pug">
  .relative.flex.items-start
    .absolute.flex.items-center.h-5
      input.form-checkbox#checkbox(
        type='checkbox'
        :checked="value"
        :indeterminate.prop="indeterminate"
        @change="$emit('input', $event.target.checked)"
      )
    .pl-7.text-sm.leading-5(v-if='$slots.default')
      label.font-medium.text-gray-700(for="checkbox")
        slot
</template>

<script>
  export default {
    props: {
      value: {
        type: Boolean,
        required: true,
      },
      indeterminate: {
        type: Boolean,
        default: false,
      },
      label: {
        type: String,
        default: null,
      },
    },
  };
</script>

<style lang="scss" scoped>
  input {
    @apply h-4 w-4 text-blue-600 transition duration-150 ease-in-out;
  }
</style>

doutatsu avatar Oct 08 '20 09:10 doutatsu

Sorry, didn't see notifications @doutatsu @imjakechapman

This workaround was added before the initial v1 release i think. After this, you will have to put the content in the extended property.

Here is one working example:

module.exports = {
  future: {
    // removeDeprecatedGapUtilities: true,
    // purgeLayersByDefault: true,
  },
  purge: [],
  theme: {
    extend: {
      customForms: theme => ({
        default: {
          checkbox: {
            '&:indeterminate': {
              background: 'url("data:image/svg+xml,%3Csvg viewBox=\'0 0 16 16\' fill=\'white\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Crect width=\'8\' height=\'2\' x=\'4\' y=\'7\' rx=\'1\'/%3E%3C/svg%3E");',
              borderColor: 'transparent',
              backgroundColor: 'currentColor',
              backgroundSize: '100% 100%',
              backgroundPosition: 'center',
              backgroundRepeat: 'no-repeat',
            }
          }
        }
      })
    },
  },
  variants: {},
  plugins: [
    require('@tailwindcss/custom-forms'),
  ],
}
<!doctype html>
<html>
<head>
  <link rel="stylesheet" href="output.css" />
</head>
<body>
  Hello world
  <input type="checkbox" class="form-checkbox" id="test">
  <script>
    document.getElementById('test').indeterminate = true;
  </script>
</body>
</html>

Double checked compiled css, does not override other custom forms properties at least. This was also just thrown quickly together, FYI

molteber avatar Oct 08 '20 10:10 molteber

@molteber No worries, I knew it had to be added to extend, but it's just clashing with TailwindUI. I've just added this custom css into the component itself, which now works as intended without affecting the rest of TailwindUI styling.

Thanks for replying tho, for anyone else that would stumble upon this.

And for others who also use TailwindUI, here is what my component ended up looking like:

<template lang="pug">
  .relative.flex.items-start
    .absolute.flex.items-center.h-5
      input.form-checkbox#checkbox(
        type='checkbox'
        :checked="value"
        :indeterminate.prop="indeterminate"
        @change="$emit('input', $event.target.checked)"
      )
    .pl-7.text-sm.leading-5(v-if='$slots.default')
      label.font-medium.text-gray-700(for="checkbox")
        slot
</template>

<script>
  export default {
    props: {
      value: {
        type: Boolean,
        required: true,
      },
      indeterminate: {
        type: Boolean,
        default: false,
      },
      label: {
        type: String,
        default: null,
      },
    },
  };
</script>

<style lang="scss" scoped>
  input {
    @apply h-4 w-4 text-blue-600 transition duration-150 ease-in-out;

    &:indeterminate {
      @apply border-transparent bg-no-repeat bg-center;

      background: url("data:image/svg+xml,%3Csvg viewBox=\'0 0 16 16\' fill=\'white\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Crect width=\'8\' height=\'2\' x=\'4\' y=\'7\' rx=\'1\'/%3E%3C/svg%3E");
      background-color: currentColor;
      background-size: 100% 100%;
    }
  }
</style>

doutatsu avatar Oct 08 '20 10:10 doutatsu

The suggestions in this thread are not working in typescript. Typescript don't recognize :indeterminate param. so,

<input indeterminate />

emit error because indeterminate is not a proper param in input tag. Any suggestions would be appreciated

zzossig avatar Dec 05 '20 18:12 zzossig

@zzossig this was added with #86

Regarding the indeterminate as html attribute (https://github.com/tailwindlabs/tailwindcss-custom-forms/pull/86#issuecomment-725460049)

imjakechapman avatar Dec 07 '20 18:12 imjakechapman