Skip to content

Commit 7d9a4f0

Browse files
committed
refactor: make rings configurable
1 parent 02ef4f9 commit 7d9a4f0

File tree

3 files changed

+44
-24
lines changed

3 files changed

+44
-24
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,13 @@ plugins: [
113113
require("@tailwindcss/forms")({
114114
strategy: 'base', // only generate global styles
115115
strategy: 'class', // only generate classes
116+
disableOutlines: true, // don't generate outlines and rings, defaults to false
116117
}),
117118
],
118119
```
119120

120121
When using the `base` strategy, form elements are styled globally, and no `form-{name}` classes are generated.
121122

122123
When using the `class` strategy, form elements are not styled globally, and instead must be styled using the generated `form-{name}` classes.
124+
125+
When `disableOutlines` is set to `true`, this plugin won't generate any outlines and rings in focused states.

src/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
declare function plugin(options?: Partial<{ strategy: 'base' | 'class' }>): { handler: () => void }
1+
declare function plugin(options?: Partial<{ strategy: 'base' | 'class', disableOutlines: boolean }>): { handler: () => void }
22

33
declare namespace plugin {
44
const __isOptionsFunction: true

src/index.js

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,22 @@ function resolveColor(color, opacityVariableName) {
99
return color.replace('<alpha-value>', `var(${opacityVariableName}, 1)`)
1010
}
1111

12-
const forms = plugin.withOptions(function (options = { strategy: undefined }) {
12+
/**
13+
* @template T
14+
* @param {boolean} bool
15+
* @param {T} value
16+
*/
17+
function maybe(bool, value) {
18+
return bool ? value : undefined
19+
}
20+
21+
function getEmptyRule() {
22+
return { base: [], class: [], styles: {} }
23+
}
24+
25+
const forms = plugin.withOptions(function (
26+
options = { strategy: undefined, disableOutlines: undefined }
27+
) {
1328
return function ({ addBase, addComponents, theme }) {
1429
function resolveChevronColor(color, fallback) {
1530
let resolved = theme(color)
@@ -22,6 +37,7 @@ const forms = plugin.withOptions(function (options = { strategy: undefined }) {
2237
}
2338

2439
const strategy = options.strategy === undefined ? ['base', 'class'] : [options.strategy]
40+
const disableOutlines = options.disableOutlines === undefined ? false : options.disableOutlines
2541

2642
const rules = [
2743
{
@@ -60,24 +76,25 @@ const forms = plugin.withOptions(function (options = { strategy: undefined }) {
6076
'font-size': baseFontSize,
6177
'line-height': baseLineHeight,
6278
'--tw-shadow': '0 0 #0000',
63-
'&:focus': {
64-
outline: '2px solid transparent',
65-
'outline-offset': '2px',
66-
'--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
67-
'--tw-ring-offset-width': '0px',
68-
'--tw-ring-offset-color': '#fff',
69-
'--tw-ring-color': resolveColor(
70-
theme('colors.blue.600', colors.blue[600]),
71-
'--tw-ring-opacity'
72-
),
73-
'--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
74-
'--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
75-
'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
76-
'border-color': resolveColor(
77-
theme('colors.blue.600', colors.blue[600]),
78-
'--tw-border-opacity'
79-
),
80-
},
79+
'&:focus':
80+
maybe(disableOutlines, {
81+
outline: '2px solid transparent',
82+
'outline-offset': '2px',
83+
'--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
84+
'--tw-ring-offset-width': '0px',
85+
'--tw-ring-offset-color': '#fff',
86+
'--tw-ring-color': resolveColor(
87+
theme('colors.blue.600', colors.blue[600]),
88+
'--tw-ring-opacity'
89+
),
90+
'--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
91+
'--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
92+
'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
93+
'border-color': resolveColor(
94+
theme('colors.blue.600', colors.blue[600]),
95+
'--tw-border-opacity'
96+
),
97+
}) || {},
8198
},
8299
},
83100
{
@@ -225,7 +242,7 @@ const forms = plugin.withOptions(function (options = { strategy: undefined }) {
225242
'border-radius': '100%',
226243
},
227244
},
228-
{
245+
maybe(!disableOutlines, {
229246
base: [`[type='checkbox']:focus`, `[type='radio']:focus`],
230247
class: ['.form-checkbox:focus', '.form-radio:focus'],
231248
styles: {
@@ -242,7 +259,7 @@ const forms = plugin.withOptions(function (options = { strategy: undefined }) {
242259
'--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
243260
'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
244261
},
245-
},
262+
}) || getEmptyRule(),
246263
{
247264
base: [`[type='checkbox']:checked`, `[type='radio']:checked`],
248265
class: ['.form-checkbox:checked', '.form-radio:checked'],
@@ -337,13 +354,13 @@ const forms = plugin.withOptions(function (options = { strategy: undefined }) {
337354
'line-height': 'inherit',
338355
},
339356
},
340-
{
357+
maybe(!disableOutlines, {
341358
base: [`[type='file']:focus`],
342359
class: null,
343360
styles: {
344361
outline: [`1px solid ButtonText`, `1px auto -webkit-focus-ring-color`],
345362
},
346-
},
363+
}) || getEmptyRule(),
347364
]
348365

349366
const getStrategyRules = (strategy) =>

0 commit comments

Comments
 (0)