Repository: tailwindlabs/tailwindcss

Problem statement:
[Proposal] Add `stroke-width`
It's quite nice to customize feather icons using `stroke-width`. The default is `2`, but setting it to `1` make large icons much nicer to look at.

Could this be added to Tailwind?


Hints:
I found a solution and i'll make pull request

Patch:
diff --git a/src/corePlugins.js b/src/corePlugins.js
--- a/src/corePlugins.js
+++ b/src/corePlugins.js
@@ -50,6 +50,7 @@ import resize from './plugins/resize'
 import boxShadow from './plugins/boxShadow'
 import fill from './plugins/fill'
 import stroke from './plugins/stroke'
+import strokeWidth from './plugins/strokeWidth'
 import tableLayout from './plugins/tableLayout'
 import textAlign from './plugins/textAlign'
 import textColor from './plugins/textColor'
@@ -123,6 +124,7 @@ export default function({ corePlugins: corePluginConfig }) {
     boxShadow,
     fill,
     stroke,
+    strokeWidth,
     tableLayout,
     textAlign,
     textColor,
diff --git a/src/plugins/strokeWidth.js b/src/plugins/strokeWidth.js
new file mode 100644
--- /dev/null
+++ b/src/plugins/strokeWidth.js
@@ -0,0 +1,19 @@
+import _ from 'lodash'
+import flattenColorPalette from '../util/flattenColorPalette'
+
+export default function() {
+  return function({ addUtilities, e, theme, variants }) {
+    const utilities = _.fromPairs(
+      _.map(flattenColorPalette(theme('strokeWidth')), (value, modifier) => {
+        return [
+          `.${e(`stroke-w-${modifier}`)}`,
+          {
+            'stroke-width': value,
+          },
+        ]
+      })
+    )
+
+    addUtilities(utilities, variants('strokeWidth'))
+  }
+}
diff --git a/stubs/defaultConfig.stub.js b/stubs/defaultConfig.stub.js
--- a/stubs/defaultConfig.stub.js
+++ b/stubs/defaultConfig.stub.js
@@ -375,6 +375,13 @@ module.exports = {
     stroke: {
       current: 'currentColor',
     },
+    strokeWidth: {
+      '0': '0',      
+      '1': '1px',
+      '2': '2px',
+      '3': '3px',
+      '4': '4px',
+    },
     textColor: theme => theme('colors'),
     width: theme => ({
       auto: 'auto',
@@ -473,6 +480,7 @@ module.exports = {
     position: ['responsive'],
     resize: ['responsive'],
     stroke: ['responsive'],
+    strokeWidth: ['responsive'],
     tableLayout: ['responsive'],
     textAlign: ['responsive'],
     textColor: ['responsive', 'hover', 'focus'],


Test patch:
diff --git a/__tests__/fixtures/tailwind-output-important.css b/__tests__/fixtures/tailwind-output-important.css
--- a/__tests__/fixtures/tailwind-output-important.css
+++ b/__tests__/fixtures/tailwind-output-important.css
@@ -6758,6 +6758,26 @@ video {
   stroke: currentColor !important;
 }
 
+.stroke-w-0 {
+  stroke-width: 0 !important;
+}
+
+.stroke-w-1 {
+  stroke-width: 1px !important;
+}
+
+.stroke-w-2 {
+  stroke-width: 2px !important;
+}
+
+.stroke-w-3 {
+  stroke-width: 3px !important;
+}
+
+.stroke-w-4 {
+  stroke-width: 4px !important;
+}
+
 .table-auto {
   table-layout: auto !important;
 }
@@ -14493,6 +14513,26 @@ video {
     stroke: currentColor !important;
   }
 
+  .sm\:stroke-w-0 {
+    stroke-width: 0 !important;
+  }
+
+  .sm\:stroke-w-1 {
+    stroke-width: 1px !important;
+  }
+
+  .sm\:stroke-w-2 {
+    stroke-width: 2px !important;
+  }
+
+  .sm\:stroke-w-3 {
+    stroke-width: 3px !important;
+  }
+
+  .sm\:stroke-w-4 {
+    stroke-width: 4px !important;
+  }
+
   .sm\:table-auto {
     table-layout: auto !important;
   }
@@ -22229,6 +22269,26 @@ video {
     stroke: currentColor !important;
   }
 
+  .md\:stroke-w-0 {
+    stroke-width: 0 !important;
+  }
+
+  .md\:stroke-w-1 {
+    stroke-width: 1px !important;
+  }
+
+  .md\:stroke-w-2 {
+    stroke-width: 2px !important;
+  }
+
+  .md\:stroke-w-3 {
+    stroke-width: 3px !important;
+  }
+
+  .md\:stroke-w-4 {
+    stroke-width: 4px !important;
+  }
+
   .md\:table-auto {
     table-layout: auto !important;
   }
@@ -29965,6 +30025,26 @@ video {
     stroke: currentColor !important;
   }
 
+  .lg\:stroke-w-0 {
+    stroke-width: 0 !important;
+  }
+
+  .lg\:stroke-w-1 {
+    stroke-width: 1px !important;
+  }
+
+  .lg\:stroke-w-2 {
+    stroke-width: 2px !important;
+  }
+
+  .lg\:stroke-w-3 {
+    stroke-width: 3px !important;
+  }
+
+  .lg\:stroke-w-4 {
+    stroke-width: 4px !important;
+  }
+
   .lg\:table-auto {
     table-layout: auto !important;
   }
@@ -37701,6 +37781,26 @@ video {
     stroke: currentColor !important;
   }
 
+  .xl\:stroke-w-0 {
+    stroke-width: 0 !important;
+  }
+
+  .xl\:stroke-w-1 {
+    stroke-width: 1px !important;
+  }
+
+  .xl\:stroke-w-2 {
+    stroke-width: 2px !important;
+  }
+
+  .xl\:stroke-w-3 {
+    stroke-width: 3px !important;
+  }
+
+  .xl\:stroke-w-4 {
+    stroke-width: 4px !important;
+  }
+
   .xl\:table-auto {
     table-layout: auto !important;
   }
diff --git a/__tests__/fixtures/tailwind-output.css b/__tests__/fixtures/tailwind-output.css
--- a/__tests__/fixtures/tailwind-output.css
+++ b/__tests__/fixtures/tailwind-output.css
@@ -6758,6 +6758,26 @@ video {
   stroke: currentColor;
 }
 
+.stroke-w-0 {
+  stroke-width: 0;
+}
+
+.stroke-w-1 {
+  stroke-width: 1px;
+}
+
+.stroke-w-2 {
+  stroke-width: 2px;
+}
+
+.stroke-w-3 {
+  stroke-width: 3px;
+}
+
+.stroke-w-4 {
+  stroke-width: 4px;
+}
+
 .table-auto {
   table-layout: auto;
 }
@@ -14493,6 +14513,26 @@ video {
     stroke: currentColor;
   }
 
+  .sm\:stroke-w-0 {
+    stroke-width: 0;
+  }
+
+  .sm\:stroke-w-1 {
+    stroke-width: 1px;
+  }
+
+  .sm\:stroke-w-2 {
+    stroke-width: 2px;
+  }
+
+  .sm\:stroke-w-3 {
+    stroke-width: 3px;
+  }
+
+  .sm\:stroke-w-4 {
+    stroke-width: 4px;
+  }
+
   .sm\:table-auto {
     table-layout: auto;
   }
@@ -22229,6 +22269,26 @@ video {
     stroke: currentColor;
   }
 
+  .md\:stroke-w-0 {
+    stroke-width: 0;
+  }
+
+  .md\:stroke-w-1 {
+    stroke-width: 1px;
+  }
+
+  .md\:stroke-w-2 {
+    stroke-width: 2px;
+  }
+
+  .md\:stroke-w-3 {
+    stroke-width: 3px;
+  }
+
+  .md\:stroke-w-4 {
+    stroke-width: 4px;
+  }
+
   .md\:table-auto {
     table-layout: auto;
   }
@@ -29965,6 +30025,26 @@ video {
     stroke: currentColor;
   }
 
+  .lg\:stroke-w-0 {
+    stroke-width: 0;
+  }
+
+  .lg\:stroke-w-1 {
+    stroke-width: 1px;
+  }
+
+  .lg\:stroke-w-2 {
+    stroke-width: 2px;
+  }
+
+  .lg\:stroke-w-3 {
+    stroke-width: 3px;
+  }
+
+  .lg\:stroke-w-4 {
+    stroke-width: 4px;
+  }
+
   .lg\:table-auto {
     table-layout: auto;
   }
@@ -37701,6 +37781,26 @@ video {
     stroke: currentColor;
   }
 
+  .xl\:stroke-w-0 {
+    stroke-width: 0;
+  }
+
+  .xl\:stroke-w-1 {
+    stroke-width: 1px;
+  }
+
+  .xl\:stroke-w-2 {
+    stroke-width: 2px;
+  }
+
+  .xl\:stroke-w-3 {
+    stroke-width: 3px;
+  }
+
+  .xl\:stroke-w-4 {
+    stroke-width: 4px;
+  }
+
   .xl\:table-auto {
     table-layout: auto;
   }
diff --git a/__tests__/plugins/strokeWidth.test.js b/__tests__/plugins/strokeWidth.test.js
new file mode 100644
--- /dev/null
+++ b/__tests__/plugins/strokeWidth.test.js
@@ -0,0 +1,57 @@
+import _ from 'lodash'
+import escapeClassName from '../../src/util/escapeClassName'
+import plugin from '../../src/plugins/strokeWidth'
+
+test('the width of the stroke to be applied to the shape', () => {
+  const addedUtilities = []
+
+  const config = {
+    theme: {
+      strokeWidth: {
+        '0': '0',
+        '1': '1px',
+        '2': '2px',
+        '3': '3px',
+        '4': '4px',
+      },
+    },
+    variants: {
+      strokeWidth: ['responsive'],
+    },
+  }
+
+  const getConfigValue = (path, defaultValue) => _.get(config, path, defaultValue)
+  const pluginApi = {
+    config: getConfigValue,
+    e: escapeClassName,
+    theme: (path, defaultValue) => getConfigValue(`theme.${path}`, defaultValue),
+    variants: (path, defaultValue) => {
+      if (_.isArray(config.variants)) {
+        return config.variants
+      }
+
+      return getConfigValue(`variants.${path}`, defaultValue)
+    },
+    addUtilities(utilities, variants) {
+      addedUtilities.push({
+        utilities,
+        variants,
+      })
+    },
+  }
+
+  plugin()(pluginApi)
+
+  expect(addedUtilities).toEqual([
+    {
+      utilities: {
+        '.stroke-w-0': { 'stroke-width': '0' },
+        '.stroke-w-1': { 'stroke-width': '1px' },
+        '.stroke-w-2': { 'stroke-width': '2px' },
+        '.stroke-w-3': { 'stroke-width': '3px' },
+        '.stroke-w-4': { 'stroke-width': '4px' },
+      },
+      variants: ['responsive'],
+    },
+  ])
+})