Repository: tailwindlabs/tailwindcss (TypeScript)

Issue:
Cannot use `theme()` within `calc()` in arbitrary value
**What version of Tailwind CSS are you using?**

v3.0.18

**What build tool (or framework if it abstracts the build tool) are you using?**

Next.js 12.0.8, Webpack ^5, PostCSS ^8.4.5

**What version of Node.js are you using?**

v16.13.1

**What browser are you using?**

Firefox, Chrome

**What operating system are you using?**

Ubuntu

**Reproduction URL**

https://play.tailwindcss.com/zsAHSyoNVo

**Describe your issue**

I posted to a closed issue, reposting here in the hopes that it doesn't get lost again: https://github.com/tailwindlabs/tailwindcss/issues/6791

> I'm facing this same issue trying to get calc() to work with theme() in an arbitrary value. According to the intellisense it's valid, but the css never actually gets generated/injected:
>
> `h-[calc(100%-theme('spacing.16'))]`


Hints:
Hey! You can make this work by getting rid of the quotes:

https://play.tailwindcss.com/mn0S0290Tm

Ideally we can make it work with quotes too though, will leave this open so we at least look into it a bit more.
Ah! It was my understanding that quotes were necessary in the postcss (and therefore in the arbitrary values as well). How does `theme(spacing.16)` work without the quotes, if there's a quick answer to that? (I see now doublechecking that previous closed issue that there were no quotes used within `theme()`, not sure why my brain decided to add them...)

In any case thank you for the workaround!

Patch:
diff --git a/src/lib/defaultExtractor.js b/src/lib/defaultExtractor.js
--- a/src/lib/defaultExtractor.js
+++ b/src/lib/defaultExtractor.js
@@ -8,6 +8,8 @@ const PATTERNS = [
   /([^<>"'`\s]*\[\w*\("[^"'`\s]*"\)\])/.source, // bg-[url("...")]
   /([^<>"'`\s]*\[\w*\('[^"`\s]*'\)\])/.source, // bg-[url('...'),url('...')]
   /([^<>"'`\s]*\[\w*\("[^'`\s]*"\)\])/.source, // bg-[url("..."),url("...")]
+  /([^<>"'`\s]*\[[^<>"'`\s]*\('[^"`\s]*'\)+\])/.source, // h-[calc(100%-theme('spacing.1'))]
+  /([^<>"'`\s]*\[[^<>"'`\s]*\("[^'`\s]*"\)+\])/.source, // h-[calc(100%-theme("spacing.1"))]
   /([^<>"'`\s]*\['[^"'`\s]*'\])/.source, // `content-['hello']` but not `content-['hello']']`
   /([^<>"'`\s]*\["[^"'`\s]*"\])/.source, // `content-["hello"]` but not `content-["hello"]"]`
   /([^<>"'`\s]*\[[^<>"'`\s]*:[^\]\s]*\])/.source, // `[attr:value]`


Test patch:
diff --git a/tests/arbitrary-values.test.js b/tests/arbitrary-values.test.js
--- a/tests/arbitrary-values.test.js
+++ b/tests/arbitrary-values.test.js
@@ -341,3 +341,32 @@ it('should be possible to read theme values in arbitrary values (with quotes)',
     `)
   })
 })
+
+it('should be possible to read theme values in arbitrary values (with quotes) when inside calc or similar functions', () => {
+  let config = {
+    content: [
+      {
+        raw: html`<div
+          class="w-[calc(100%-theme('spacing.1'))] w-[calc(100%-theme('spacing[0.5]'))]"
+        ></div>`,
+      },
+    ],
+    theme: {
+      spacing: {
+        0.5: 'calc(.5 * .25rem)',
+        1: 'calc(1 * .25rem)',
+      },
+    },
+  }
+
+  return run('@tailwind utilities', config).then((result) => {
+    return expect(result.css).toMatchFormattedCss(css`
+      .w-\[calc\(100\%-theme\(\'spacing\.1\'\)\)\] {
+        width: calc(100% - calc(1 * 0.25rem));
+      }
+      .w-\[calc\(100\%-theme\(\'spacing\[0\.5\]\'\)\)\] {
+        width: calc(100% - calc(0.5 * 0.25rem));
+      }
+    `)
+  })
+})
diff --git a/tests/default-extractor.test.js b/tests/default-extractor.test.js
--- a/tests/default-extractor.test.js
+++ b/tests/default-extractor.test.js
@@ -26,6 +26,8 @@ const input =
   <div class="hover:font-bold"></div>
   <div class="content-['>']"></div>
   <div class="[--y:theme(colors.blue.500)]">
+  <div class="w-[calc(100%-theme('spacing.1'))]">
+  <div class='w-[calc(100%-theme("spacing.2"))]'>
 
   <script>
     let classes01 = ["text-[10px]"]
@@ -90,6 +92,8 @@ const includes = [
   `hover:test`,
   `overflow-scroll`,
   `[--y:theme(colors.blue.500)]`,
+  `w-[calc(100%-theme('spacing.1'))]`,
+  `w-[calc(100%-theme("spacing.2"))]`,
 ]
 
 const excludes = [