Repository: tailwindlabs/tailwindcss

Problem statement:
Missing DEFAULT option for ringOffsetWidth and ringOffsetColor
### Describe the problem:

Trying to set a default ring with offset doesn't work.

### Link to a minimal reproduction:

https://play.tailwindcss.com/hNYXW0Qzj9
Missing DEFAULT option for ringOffsetWidth and ringOffsetColor
### Describe the problem:

Trying to set a default ring with offset doesn't work.

### Link to a minimal reproduction:

https://play.tailwindcss.com/hNYXW0Qzj9


Hints:
Hey! 👋

There is no offset specified in your Play example, only the `ring` itself (defaulting to 3px). 

The actual "default" for ring-offset is no offset. We make the assumption that there should be no offset, unless explicitly specified. The default color for ring offset is white. 👍

If you add a `ring-offset-2` for example, the ring will be offset by 2 pixels, as expected:

https://play.tailwindcss.com/W4SSmpZj4h
I'm aware of that, is it normal to use 4 classes for a ring? I thought we could setup defaults for the 4 elements of ring and use a single ``focus:ring`` class, otherwise the classes are gonna be huge, e.g. ``focus:ring-2 focus:ring-green-500 focus:ring-offset-2 focus:ring-offset-gray-800``.

Nothing that can't be solved with ``@apply``, just thought it would be a nice thing to have.
This is a valid request, will play with this more at some point soon and see if it makes sense to make it work this way 👍🏻 Thanks for bringing it up!
Hey! 👋

There is no offset specified in your Play example, only the `ring` itself (defaulting to 3px). 

The actual "default" for ring-offset is no offset. We make the assumption that there should be no offset, unless explicitly specified. The default color for ring offset is white. 👍

If you add a `ring-offset-2` for example, the ring will be offset by 2 pixels, as expected:

https://play.tailwindcss.com/W4SSmpZj4h
I'm aware of that, is it normal to use 4 classes for a ring? I thought we could setup defaults for the 4 elements of ring and use a single ``focus:ring`` class, otherwise the classes are gonna be huge, e.g. ``focus:ring-2 focus:ring-green-500 focus:ring-offset-2 focus:ring-offset-gray-800``.

Nothing that can't be solved with ``@apply``, just thought it would be a nice thing to have.
This is a valid request, will play with this more at some point soon and see if it makes sense to make it work this way 👍🏻 Thanks for bringing it up!

Patch:
diff --git a/src/plugins/ringOffsetColor.js b/src/plugins/ringOffsetColor.js
--- a/src/plugins/ringOffsetColor.js
+++ b/src/plugins/ringOffsetColor.js
@@ -7,7 +7,7 @@ export default function () {
   return function ({ addUtilities, theme, variants }) {
     const colors = flattenColorPalette(theme('ringOffsetColor'))
     const utilities = _.fromPairs(
-      _.map(colors, (value, modifier) => {
+      _.map(_.omit(colors, 'DEFAULT'), (value, modifier) => {
         return [
           nameClass('ring-offset', modifier),
           {
diff --git a/src/plugins/ringOffsetWidth.js b/src/plugins/ringOffsetWidth.js
--- a/src/plugins/ringOffsetWidth.js
+++ b/src/plugins/ringOffsetWidth.js
@@ -4,7 +4,7 @@ import nameClass from '../util/nameClass'
 export default function () {
   return function ({ addUtilities, theme, variants }) {
     const utilities = _.fromPairs(
-      _.map(theme('ringOffsetWidth'), (value, modifier) => {
+      _.map(_.omit(theme('ringOffsetWidth'), 'DEFAULT'), (value, modifier) => {
         return [
           nameClass('ring-offset', modifier),
           {
diff --git a/src/plugins/ringWidth.js b/src/plugins/ringWidth.js
--- a/src/plugins/ringWidth.js
+++ b/src/plugins/ringWidth.js
@@ -20,8 +20,8 @@ export default function () {
       {
         '*': {
           '--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
-          '--tw-ring-offset-width': '0px',
-          '--tw-ring-offset-color': '#fff',
+          '--tw-ring-offset-width': theme('ringOffsetWidth.DEFAULT', '0px'),
+          '--tw-ring-offset-color': theme('ringOffsetColor.DEFAULT', '#fff'),
           '--tw-ring-color': ringColorDefault,
           '--tw-ring-offset-shadow': '0 0 #0000',
           '--tw-ring-shadow': '0 0 #0000',


Test patch:
diff --git a/__tests__/plugins/ringWidth.test.js b/__tests__/plugins/ringWidth.test.js
new file mode 100644
--- /dev/null
+++ b/__tests__/plugins/ringWidth.test.js
@@ -0,0 +1,104 @@
+import invokePlugin from '../util/invokePlugin'
+import plugin from '../../src/plugins/ringWidth'
+
+test('ring widths', () => {
+  const config = {
+    theme: {
+      ringWidth: {
+        4: '4px',
+      },
+      ringOffsetWidth: {
+        4: '4px',
+      },
+      ringColor: {
+        black: '#000',
+      },
+      ringOffsetColor: {
+        white: '#fff',
+      },
+      ringOpacity: {
+        50: '.5',
+      },
+    },
+    variants: {
+      ringColor: [],
+    },
+  }
+
+  const { utilities } = invokePlugin(plugin(), config)
+  expect(utilities).toEqual([
+    [
+      {
+        '*': {
+          '--tw-ring-color': 'rgba(147, 197, 253, 0.5)',
+          '--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
+          '--tw-ring-offset-color': '#fff',
+          '--tw-ring-offset-shadow': '0 0 #0000',
+          '--tw-ring-offset-width': '0px',
+          '--tw-ring-shadow': '0 0 #0000',
+        },
+      },
+      {
+        respectImportant: false,
+      },
+    ],
+    [
+      {
+        '.ring-4': {
+          '--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(4px + var(--tw-ring-offset-width)) var(--tw-ring-color)',
+          'box-shadow':
+            'var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)',
+        },
+        '.ring-inset': {
+          '--tw-ring-inset': 'inset',
+        },
+      },
+      undefined,
+    ],
+  ])
+})
+
+test('ring widths with defaults', () => {
+  const config = {
+    theme: {
+      ringWidth: {},
+      ringOffsetWidth: {
+        DEFAULT: '2px',
+      },
+      ringOffsetColor: {
+        DEFAULT: 'pink',
+      },
+    },
+    variants: {
+      ringColor: [],
+    },
+  }
+
+  const { utilities } = invokePlugin(plugin(), config)
+  expect(utilities).toEqual([
+    [
+      {
+        '*': {
+          '--tw-ring-color': 'rgba(147, 197, 253, 0.5)',
+          '--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
+          '--tw-ring-offset-color': 'pink',
+          '--tw-ring-offset-shadow': '0 0 #0000',
+          '--tw-ring-offset-width': '2px',
+          '--tw-ring-shadow': '0 0 #0000',
+        },
+      },
+      { respectImportant: false },
+    ],
+    [
+      {
+        '.ring-inset': {
+          '--tw-ring-inset': 'inset',
+        },
+      },
+      undefined,
+    ],
+  ])
+})