diff --git a/package.json b/package.json
index 75483dd..4060d30 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@tailwindcss/forms",
- "version": "0.5.0",
+ "version": "0.6.0",
"main": "src/index.js",
"license": "MIT",
"repository": "https://github.com/tailwindlabs/tailwindcss-forms",
diff --git a/src/index.js b/src/index.js
index ee60f72..efa3441 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,303 +2,316 @@ const svgToDataUri = require('mini-svg-data-uri')
const plugin = require('tailwindcss/plugin')
const defaultTheme = require('tailwindcss/defaultTheme')
const colors = require('tailwindcss/colors')
-const [baseFontSize, { lineHeight: baseLineHeight }] = defaultTheme.fontSize.base
-const { spacing, borderWidth, borderRadius } = defaultTheme
+const [baseFontSize, {lineHeight: baseLineHeight}] = defaultTheme.fontSize.base
+const {spacing, borderWidth, borderRadius} = defaultTheme
-const forms = plugin.withOptions(function (options = { strategy: undefined }) {
- return function ({ addBase, addComponents, theme }) {
- const strategy = options.strategy === undefined ? ['base', 'class'] : [options.strategy]
+const forms = plugin.withOptions(function ({
+ appearance,
+ backgroundColor,
+ borderColor,
+ outline,
+ outlineOffset,
+ placeholderColor,
+ primaryColor: primaryColorArg,
+ ringColor,
+ ringOffsetColor,
+ secondaryColor: secondaryColorArg,
+ selectColor,
+ strategy
+ }) {
+ return function ({addBase, addComponents, theme}) {
+ const strategy = strategy === undefined ? ['base', 'class'] : [strategy]
+ const primaryColor = primaryColorArg || theme('colors.blue.600', colors.blue[600]);
+ const secondaryColor = secondaryColorArg || theme('colors.gray.500', colors.gray[500]);
- const rules = [
- {
- base: [
- "[type='text']",
- "[type='email']",
- "[type='url']",
- "[type='password']",
- "[type='number']",
- "[type='date']",
- "[type='datetime-local']",
- "[type='month']",
- "[type='search']",
- "[type='tel']",
- "[type='time']",
- "[type='week']",
- '[multiple]',
- 'textarea',
- 'select',
- ],
- class: ['.form-input', '.form-textarea', '.form-select', '.form-multiselect'],
- styles: {
- appearance: 'none',
- 'background-color': '#fff',
- 'border-color': theme('colors.gray.500', colors.gray[500]),
- 'border-width': borderWidth['DEFAULT'],
- 'border-radius': borderRadius.none,
- 'padding-top': spacing[2],
- 'padding-right': spacing[3],
- 'padding-bottom': spacing[2],
- 'padding-left': spacing[3],
- 'font-size': baseFontSize,
- 'line-height': baseLineHeight,
- '--tw-shadow': '0 0 #0000',
- '&:focus': {
- outline: '2px solid transparent',
- 'outline-offset': '2px',
- '--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
- '--tw-ring-offset-width': '0px',
- '--tw-ring-offset-color': '#fff',
- '--tw-ring-color': theme('colors.blue.600', colors.blue[600]),
- '--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
- '--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
- 'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
- 'border-color': theme('colors.blue.600', colors.blue[600]),
- },
- },
- },
- {
- base: ['input::placeholder', 'textarea::placeholder'],
- class: ['.form-input::placeholder', '.form-textarea::placeholder'],
- styles: {
- color: theme('colors.gray.500', colors.gray[500]),
- opacity: '1',
- },
- },
- {
- base: ['::-webkit-datetime-edit-fields-wrapper'],
- class: ['.form-input::-webkit-datetime-edit-fields-wrapper'],
- styles: {
- padding: '0',
- },
- },
- {
- // Unfortunate hack until https://bugs.webkit.org/show_bug.cgi?id=198959 is fixed.
- // This sucks because users can't change line-height with a utility on date inputs now.
- // Reference: https://github.com/twbs/bootstrap/pull/31993
- base: ['::-webkit-date-and-time-value'],
- class: ['.form-input::-webkit-date-and-time-value'],
- styles: {
- 'min-height': '1.5em',
- },
- },
- {
- // In Safari on macOS date time inputs are 4px taller than normal inputs
- // This is because there is extra padding on the datetime-edit and datetime-edit-{part}-field pseudo elements
- // See https://github.com/tailwindlabs/tailwindcss-forms/issues/95
- base: [
- '::-webkit-datetime-edit',
- '::-webkit-datetime-edit-year-field',
- '::-webkit-datetime-edit-month-field',
- '::-webkit-datetime-edit-day-field',
- '::-webkit-datetime-edit-hour-field',
- '::-webkit-datetime-edit-minute-field',
- '::-webkit-datetime-edit-second-field',
- '::-webkit-datetime-edit-millisecond-field',
- '::-webkit-datetime-edit-meridiem-field',
- ],
- class: [
- '.form-input::-webkit-datetime-edit',
- '.form-input::-webkit-datetime-edit-year-field',
- '.form-input::-webkit-datetime-edit-month-field',
- '.form-input::-webkit-datetime-edit-day-field',
- '.form-input::-webkit-datetime-edit-hour-field',
- '.form-input::-webkit-datetime-edit-minute-field',
- '.form-input::-webkit-datetime-edit-second-field',
- '.form-input::-webkit-datetime-edit-millisecond-field',
- '.form-input::-webkit-datetime-edit-meridiem-field',
- ],
- styles: {
- 'padding-top': 0,
- 'padding-bottom': 0,
- },
- },
- {
- base: ['select'],
- class: ['.form-select'],
- styles: {
- 'background-image': `url("${svgToDataUri(
- ``
- )}")`,
- 'background-position': `right ${spacing[2]} center`,
- 'background-repeat': `no-repeat`,
- 'background-size': `1.5em 1.5em`,
- 'padding-right': spacing[10],
- 'color-adjust': `exact`,
- },
- },
- {
- base: ['[multiple]'],
- class: null,
- styles: {
- 'background-image': 'initial',
- 'background-position': 'initial',
- 'background-repeat': 'unset',
- 'background-size': 'initial',
- 'padding-right': spacing[3],
- 'color-adjust': 'unset',
- },
- },
- {
- base: [`[type='checkbox']`, `[type='radio']`],
- class: ['.form-checkbox', '.form-radio'],
- styles: {
- appearance: 'none',
- padding: '0',
- 'color-adjust': 'exact',
- display: 'inline-block',
- 'vertical-align': 'middle',
- 'background-origin': 'border-box',
- 'user-select': 'none',
- 'flex-shrink': '0',
- height: spacing[4],
- width: spacing[4],
- color: theme('colors.blue.600', colors.blue[600]),
- 'background-color': '#fff',
- 'border-color': theme('colors.gray.500', colors.gray[500]),
- 'border-width': borderWidth['DEFAULT'],
- '--tw-shadow': '0 0 #0000',
- },
- },
- {
- base: [`[type='checkbox']`],
- class: ['.form-checkbox'],
- styles: {
- 'border-radius': borderRadius['none'],
- },
- },
- {
- base: [`[type='radio']`],
- class: ['.form-radio'],
- styles: {
- 'border-radius': '100%',
- },
- },
- {
- base: [`[type='checkbox']:focus`, `[type='radio']:focus`],
- class: ['.form-checkbox:focus', '.form-radio:focus'],
- styles: {
- outline: '2px solid transparent',
- 'outline-offset': '2px',
- '--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
- '--tw-ring-offset-width': '2px',
- '--tw-ring-offset-color': '#fff',
- '--tw-ring-color': theme('colors.blue.600', colors.blue[600]),
- '--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
- '--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
- 'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
- },
- },
- {
- base: [`[type='checkbox']:checked`, `[type='radio']:checked`],
- class: ['.form-checkbox:checked', '.form-radio:checked'],
- styles: {
- 'border-color': `transparent`,
- 'background-color': `currentColor`,
- 'background-size': `100% 100%`,
- 'background-position': `center`,
- 'background-repeat': `no-repeat`,
- },
- },
- {
- base: [`[type='checkbox']:checked`],
- class: ['.form-checkbox:checked'],
- styles: {
- 'background-image': `url("${svgToDataUri(
- ``
- )}")`,
- },
- },
- {
- base: [`[type='radio']:checked`],
- class: ['.form-radio:checked'],
- styles: {
- 'background-image': `url("${svgToDataUri(
- ``
- )}")`,
- },
- },
- {
- base: [
- `[type='checkbox']:checked:hover`,
- `[type='checkbox']:checked:focus`,
- `[type='radio']:checked:hover`,
- `[type='radio']:checked:focus`,
- ],
- class: [
- '.form-checkbox:checked:hover',
- '.form-checkbox:checked:focus',
- '.form-radio:checked:hover',
- '.form-radio:checked:focus',
- ],
- styles: {
- 'border-color': 'transparent',
- 'background-color': 'currentColor',
- },
- },
- {
- base: [`[type='checkbox']:indeterminate`],
- class: ['.form-checkbox:indeterminate'],
- styles: {
- 'background-image': `url("${svgToDataUri(
- ``
- )}")`,
- 'border-color': `transparent`,
- 'background-color': `currentColor`,
- 'background-size': `100% 100%`,
- 'background-position': `center`,
- 'background-repeat': `no-repeat`,
- },
- },
- {
- base: [`[type='checkbox']:indeterminate:hover`, `[type='checkbox']:indeterminate:focus`],
- class: ['.form-checkbox:indeterminate:hover', '.form-checkbox:indeterminate:focus'],
- styles: {
- 'border-color': 'transparent',
- 'background-color': 'currentColor',
- },
- },
- {
- base: [`[type='file']`],
- class: null,
- styles: {
- background: 'unset',
- 'border-color': 'inherit',
- 'border-width': '0',
- 'border-radius': '0',
- padding: '0',
- 'font-size': 'unset',
- 'line-height': 'inherit',
- },
- },
- {
- base: [`[type='file']:focus`],
- class: null,
- styles: {
- outline: `1px solid ButtonText`,
- outline: `1px auto -webkit-focus-ring-color`,
- },
- },
- ]
+ const rules = [
+ {
+ base: [
+ "[type='text']",
+ "[type='email']",
+ "[type='url']",
+ "[type='password']",
+ "[type='number']",
+ "[type='date']",
+ "[type='datetime-local']",
+ "[type='month']",
+ "[type='search']",
+ "[type='tel']",
+ "[type='time']",
+ "[type='week']",
+ '[multiple]',
+ 'textarea',
+ 'select',
+ ],
+ class: ['.form-input', '.form-textarea', '.form-select', '.form-multiselect'],
+ styles: {
+ appearance: appearance || 'none',
+ 'background-color': backgroundColor || '#fff',
+ 'border-color': borderColor || secondaryColor,
+ 'border-width': borderWidth['DEFAULT'],
+ 'border-radius': borderRadius.none,
+ 'padding-top': spacing[2],
+ 'padding-right': spacing[3],
+ 'padding-bottom': spacing[2],
+ 'padding-left': spacing[3],
+ 'font-size': baseFontSize,
+ 'line-height': baseLineHeight,
+ '--tw-shadow': '0 0 #0000',
+ '&:focus': {
+ outline: outline || (outlineOffset || '2px') + ' solid transparent',
+ 'outline-offset': outlineOffset || '2px',
+ '--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
+ '--tw-ring-offset-width': '0px',
+ '--tw-ring-offset-color': ringOffsetColor || '#fff',
+ '--tw-ring-color': ringColor || primaryColor,
+ '--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
+ '--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
+ 'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
+ 'border-color': borderColor || primaryColor,
+ },
+ },
+ },
+ {
+ base: ['input::placeholder', 'textarea::placeholder'],
+ class: ['.form-input::placeholder', '.form-textarea::placeholder'],
+ styles: {
+ color: placeholderColor || secondaryColor,
+ opacity: '1',
+ },
+ },
+ {
+ base: ['::-webkit-datetime-edit-fields-wrapper'],
+ class: ['.form-input::-webkit-datetime-edit-fields-wrapper'],
+ styles: {
+ padding: '0',
+ },
+ },
+ {
+ // Unfortunate hack until https://bugs.webkit.org/show_bug.cgi?id=198959 is fixed.
+ // This sucks because users can't change line-height with a utility on date inputs now.
+ // Reference: https://github.com/twbs/bootstrap/pull/31993
+ base: ['::-webkit-date-and-time-value'],
+ class: ['.form-input::-webkit-date-and-time-value'],
+ styles: {
+ 'min-height': '1.5em',
+ },
+ },
+ {
+ // In Safari on macOS date time inputs are 4px taller than normal inputs
+ // This is because there is extra padding on the datetime-edit and datetime-edit-{part}-field pseudo elements
+ // See https://github.com/tailwindlabs/tailwindcss-forms/issues/95
+ base: [
+ '::-webkit-datetime-edit',
+ '::-webkit-datetime-edit-year-field',
+ '::-webkit-datetime-edit-month-field',
+ '::-webkit-datetime-edit-day-field',
+ '::-webkit-datetime-edit-hour-field',
+ '::-webkit-datetime-edit-minute-field',
+ '::-webkit-datetime-edit-second-field',
+ '::-webkit-datetime-edit-millisecond-field',
+ '::-webkit-datetime-edit-meridiem-field',
+ ],
+ class: [
+ '.form-input::-webkit-datetime-edit',
+ '.form-input::-webkit-datetime-edit-year-field',
+ '.form-input::-webkit-datetime-edit-month-field',
+ '.form-input::-webkit-datetime-edit-day-field',
+ '.form-input::-webkit-datetime-edit-hour-field',
+ '.form-input::-webkit-datetime-edit-minute-field',
+ '.form-input::-webkit-datetime-edit-second-field',
+ '.form-input::-webkit-datetime-edit-millisecond-field',
+ '.form-input::-webkit-datetime-edit-meridiem-field',
+ ],
+ styles: {
+ 'padding-top': 0,
+ 'padding-bottom': 0,
+ },
+ },
+ {
+ base: ['select'],
+ class: ['.form-select'],
+ styles: {
+ 'background-image': `url("${svgToDataUri(
+ ``
+ )}")`,
+ 'background-position': `right ${spacing[2]} center`,
+ 'background-repeat': `no-repeat`,
+ 'background-size': `1.5em 1.5em`,
+ 'padding-right': spacing[10],
+ 'color-adjust': `exact`,
+ },
+ },
+ {
+ base: ['[multiple]'],
+ class: null,
+ styles: {
+ 'background-image': 'initial',
+ 'background-position': 'initial',
+ 'background-repeat': 'unset',
+ 'background-size': 'initial',
+ 'padding-right': spacing[3],
+ 'color-adjust': 'unset',
+ },
+ },
+ {
+ base: [`[type='checkbox']`, `[type='radio']`],
+ class: ['.form-checkbox', '.form-radio'],
+ styles: {
+ appearance: 'none',
+ padding: '0',
+ 'color-adjust': 'exact',
+ display: 'inline-block',
+ 'vertical-align': 'middle',
+ 'background-origin': 'border-box',
+ 'user-select': 'none',
+ 'flex-shrink': '0',
+ height: spacing[4],
+ width: spacing[4],
+ color: selectColor || primaryColor,
+ 'background-color': backgroundColor || '#fff',
+ 'border-color': selectColor || primaryColor,
+ 'border-width': borderWidth['DEFAULT'],
+ '--tw-shadow': '0 0 #0000',
+ },
+ },
+ {
+ base: [`[type='checkbox']`],
+ class: ['.form-checkbox'],
+ styles: {
+ 'border-radius': borderRadius['none'],
+ },
+ },
+ {
+ base: [`[type='radio']`],
+ class: ['.form-radio'],
+ styles: {
+ 'border-radius': '100%',
+ },
+ },
+ {
+ base: [`[type='checkbox']:focus`, `[type='radio']:focus`],
+ class: ['.form-checkbox:focus', '.form-radio:focus'],
+ styles: {
+ outline: '2px solid transparent',
+ 'outline-offset': '2px',
+ '--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
+ '--tw-ring-offset-width': '2px',
+ '--tw-ring-offset-color': ringOffsetColor || '#fff',
+ '--tw-ring-color': ringColor || primaryColor,
+ '--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
+ '--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
+ 'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
+ },
+ },
+ {
+ base: [`[type='checkbox']:checked`, `[type='radio']:checked`],
+ class: ['.form-checkbox:checked', '.form-radio:checked'],
+ styles: {
+ 'border-color': `transparent`,
+ 'background-color': `currentColor`,
+ 'background-size': `100% 100%`,
+ 'background-position': `center`,
+ 'background-repeat': `no-repeat`,
+ },
+ },
+ {
+ base: [`[type='checkbox']:checked`],
+ class: ['.form-checkbox:checked'],
+ styles: {
+ 'background-image': `url("${svgToDataUri(
+ ``
+ )}")`,
+ },
+ },
+ {
+ base: [`[type='radio']:checked`],
+ class: ['.form-radio:checked'],
+ styles: {
+ 'background-image': `url("${svgToDataUri(
+ ``
+ )}")`,
+ },
+ },
+ {
+ base: [
+ `[type='checkbox']:checked:hover`,
+ `[type='checkbox']:checked:focus`,
+ `[type='radio']:checked:hover`,
+ `[type='radio']:checked:focus`,
+ ],
+ class: [
+ '.form-checkbox:checked:hover',
+ '.form-checkbox:checked:focus',
+ '.form-radio:checked:hover',
+ '.form-radio:checked:focus',
+ ],
+ styles: {
+ 'border-color': 'transparent',
+ 'background-color': 'currentColor',
+ },
+ },
+ {
+ base: [`[type='checkbox']:indeterminate`],
+ class: ['.form-checkbox:indeterminate'],
+ styles: {
+ 'background-image': `url("${svgToDataUri(
+ ``
+ )}")`,
+ 'border-color': `transparent`,
+ 'background-color': `currentColor`,
+ 'background-size': `100% 100%`,
+ 'background-position': `center`,
+ 'background-repeat': `no-repeat`,
+ },
+ },
+ {
+ base: [`[type='checkbox']:indeterminate:hover`, `[type='checkbox']:indeterminate:focus`],
+ class: ['.form-checkbox:indeterminate:hover', '.form-checkbox:indeterminate:focus'],
+ styles: {
+ 'border-color': 'transparent',
+ 'background-color': 'currentColor',
+ },
+ },
+ {
+ base: [`[type='file']`],
+ class: null,
+ styles: {
+ background: 'unset',
+ 'border-color': 'inherit',
+ 'border-width': '0',
+ 'border-radius': '0',
+ padding: '0',
+ 'font-size': 'unset',
+ 'line-height': 'inherit',
+ },
+ },
+ {
+ base: [`[type='file']:focus`],
+ class: null,
+ styles: {
+ outline: `1px solid ButtonText`,
+ outline: `1px auto -webkit-focus-ring-color`,
+ },
+ },
+ ]
- const getStrategyRules = (strategy) => rules
- .map((rule) => {
- if (rule[strategy] === null) return null
+ const getStrategyRules = (strategy) => rules
+ .map((rule) => {
+ if (rule[strategy] === null) return null
- return { [rule[strategy]]: rule.styles }
- })
- .filter(Boolean)
+ return {[rule[strategy]]: rule.styles}
+ })
+ .filter(Boolean)
- if (strategy.includes('base')) {
- addBase(getStrategyRules('base'))
- }
+ if (strategy.includes('base')) {
+ addBase(getStrategyRules('base'))
+ }
- if (strategy.includes('class')) {
- addComponents(getStrategyRules('class'))
+ if (strategy.includes('class')) {
+ addComponents(getStrategyRules('class'))
+ }
}
- }
})
module.exports = forms