Repository: tailwindlabs/tailwindcss (TypeScript)

Issue:
Tailwind error when using theme() in css
Adding following styles to css leads to an error:

```
.test {
  --shadow: theme("boxShadow.glow-8/28/20");
  box-shadow: var(---shadow);
}
```

error:
```
'boxShadow.glow-8/28' does not exist in your theme config. Did you mean 'boxShadow.glow-8/28/20'?
```

**What version of Tailwind CSS are you using?**

v3.1.5

**What build tool (or framework if it abstracts the build tool) are you using?**

NextJS 12.1.0

**What version of Node.js are you using?**

v16.2.0

**What browser are you using?**

N/A

**What operating system are you using?**

Windows

**Reproduction URL**

https://play.tailwindcss.com/xlki3pMe9n?file=css

**Describe your issue**

Adding styles that contain more than one forward slash `/` returns an error when it's used via `theme()` function, for example: `theme("boxShadow.glow-6/30/40")`




Hints:

Patch:
diff --git a/src/lib/evaluateTailwindFunctions.js b/src/lib/evaluateTailwindFunctions.js
--- a/src/lib/evaluateTailwindFunctions.js
+++ b/src/lib/evaluateTailwindFunctions.js
@@ -157,26 +157,52 @@ let nodeTypePropertyMap = {
   decl: 'value',
 }
 
-export default function ({ tailwindConfig: config }) {
-  let functions = {
-    theme: (node, path, ...defaultValue) => {
-      // Strip quotes from beginning and end of string
-      // This allows the alpha value to be present inside of quotes
-      path = path.replace(/^['"]+|['"]+$/g, '')
+/**
+ * @param {string} path
+ * @returns {Iterable<[path: string, alpha: string|undefined]>}
+ */
+function* toPaths(path) {
+  // Strip quotes from beginning and end of string
+  // This allows the alpha value to be present inside of quotes
+  path = path.replace(/^['"]+|['"]+$/g, '')
 
-      let matches = path.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/)
-      let alpha = undefined
+  let matches = path.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/)
+  let alpha = undefined
 
-      if (matches) {
-        path = matches[1]
-        alpha = matches[2]
-      }
+  yield [path, undefined]
+
+  if (matches) {
+    path = matches[1]
+    alpha = matches[2]
+
+    yield [path, alpha]
+  }
+}
 
-      let { isValid, value, error } = validatePath(
+/**
+ *
+ * @param {any} config
+ * @param {string} path
+ * @param {any} defaultValue
+ */
+function resolvePath(config, path, defaultValue) {
+  const results = Array.from(toPaths(path)).map(([path, alpha]) => {
+    return Object.assign(validatePath(config, path, defaultValue, { opacityValue: alpha }), {
+      resolvedPath: path,
+      alpha,
+    })
+  })
+
+  return results.find((result) => result.isValid) ?? results[0]
+}
+
+export default function ({ tailwindConfig: config }) {
+  let functions = {
+    theme: (node, path, ...defaultValue) => {
+      let { isValid, value, error, alpha } = resolvePath(
         config,
         path,
-        defaultValue.length ? defaultValue : undefined,
-        { opacityValue: alpha }
+        defaultValue.length ? defaultValue : undefined
       )
 
       if (!isValid) {


Test patch:
diff --git a/tests/evaluateTailwindFunctions.test.js b/tests/evaluateTailwindFunctions.test.js
--- a/tests/evaluateTailwindFunctions.test.js
+++ b/tests/evaluateTailwindFunctions.test.js
@@ -1135,3 +1135,51 @@ test('Theme functions with alpha with quotes value around color only', () => {
     expect(result.warnings().length).toBe(0)
   })
 })
+
+it('can find values with slashes in the theme key while still allowing for alpha values ', () => {
+  let input = css`
+    .foo00 {
+      color: theme(colors.foo-5);
+    }
+    .foo01 {
+      color: theme(colors.foo-5/10);
+    }
+    .foo02 {
+      color: theme(colors.foo-5/10/25);
+    }
+    .foo03 {
+      color: theme(colors.foo-5 / 10);
+    }
+    .foo04 {
+      color: theme(colors.foo-5/10 / 25);
+    }
+  `
+
+  return runFull(input, {
+    theme: {
+      colors: {
+        'foo-5': '#050000',
+        'foo-5/10': '#051000',
+        'foo-5/10/25': '#051025',
+      },
+    },
+  }).then((result) => {
+    expect(result.css).toMatchCss(css`
+      .foo00 {
+        color: #050000;
+      }
+      .foo01 {
+        color: #051000;
+      }
+      .foo02 {
+        color: #051025;
+      }
+      .foo03 {
+        color: rgb(5 0 0 / 10);
+      }
+      .foo04 {
+        color: rgb(5 16 0 / 25);
+      }
+    `)
+  })
+})