Skip to content

Commit fe14a40

Browse files
committed
refactor: make rings configurable
1 parent ad3f056 commit fe14a40

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ More customization examples and best practices coming soon.
7070
In addition to the global styles, we also generate a set of corresponding classes which can be used to explicitly apply the form styles to an element. This can be useful in situations where you need to make a non-form element, such as a `<div>`, look like a form element.
7171

7272
```html
73-
<input type="email" class="form-input px-4 py-3 rounded-full">
73+
<input type="email" class="form-input px-4 py-3 rounded-full" />
7474

7575
<select class="form-select px-4 py-3 rounded-full">
7676
<!-- ... -->
@@ -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,9 +9,25 @@ 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
const strategy = options.strategy === undefined ? ['base', 'class'] : [options.strategy]
30+
const disableOutlines = options.disableOutlines === undefined ? false : options.disableOutlines
1531

1632
const rules = [
1733
{
@@ -50,24 +66,25 @@ const forms = plugin.withOptions(function (options = { strategy: undefined }) {
5066
'font-size': baseFontSize,
5167
'line-height': baseLineHeight,
5268
'--tw-shadow': '0 0 #0000',
53-
'&:focus': {
54-
outline: '2px solid transparent',
55-
'outline-offset': '2px',
56-
'--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
57-
'--tw-ring-offset-width': '0px',
58-
'--tw-ring-offset-color': '#fff',
59-
'--tw-ring-color': resolveColor(
60-
theme('colors.blue.600', colors.blue[600]),
61-
'--tw-ring-opacity'
62-
),
63-
'--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
64-
'--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
65-
'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
66-
'border-color': resolveColor(
67-
theme('colors.blue.600', colors.blue[600]),
68-
'--tw-border-opacity'
69-
),
70-
},
69+
'&:focus':
70+
maybe({
71+
outline: '2px solid transparent',
72+
'outline-offset': '2px',
73+
'--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
74+
'--tw-ring-offset-width': '0px',
75+
'--tw-ring-offset-color': '#fff',
76+
'--tw-ring-color': resolveColor(
77+
theme('colors.blue.600', colors.blue[600]),
78+
'--tw-ring-opacity'
79+
),
80+
'--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
81+
'--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
82+
'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
83+
'border-color': resolveColor(
84+
theme('colors.blue.600', colors.blue[600]),
85+
'--tw-border-opacity'
86+
),
87+
}) || {},
7188
},
7289
},
7390
{
@@ -215,7 +232,7 @@ const forms = plugin.withOptions(function (options = { strategy: undefined }) {
215232
'border-radius': '100%',
216233
},
217234
},
218-
{
235+
maybe(!disableOutlines, {
219236
base: [`[type='checkbox']:focus`, `[type='radio']:focus`],
220237
class: ['.form-checkbox:focus', '.form-radio:focus'],
221238
styles: {
@@ -232,7 +249,7 @@ const forms = plugin.withOptions(function (options = { strategy: undefined }) {
232249
'--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
233250
'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
234251
},
235-
},
252+
}) || getEmptyRule(),
236253
{
237254
base: [`[type='checkbox']:checked`, `[type='radio']:checked`],
238255
class: ['.form-checkbox:checked', '.form-radio:checked'],
@@ -315,13 +332,13 @@ const forms = plugin.withOptions(function (options = { strategy: undefined }) {
315332
'line-height': 'inherit',
316333
},
317334
},
318-
{
335+
maybe(!disableOutlines, {
319336
base: [`[type='file']:focus`],
320337
class: null,
321338
styles: {
322339
outline: [`1px solid ButtonText`, `1px auto -webkit-focus-ring-color`],
323340
},
324-
},
341+
}) || getEmptyRule(),
325342
]
326343

327344
const getStrategyRules = (strategy) =>

0 commit comments

Comments
 (0)