Repository: streamlit/streamlit

Issue:
st.dataframe "Could not parse color" when a dataframe is styled with hex or rgb values
### Summary

As of streamlit 1.10.0, pandas dataframes that are styled using a hex or rgb value (as apposed to referencing colours using plantext) are not rendered correctly in the browser.

### Steps to reproduce

Code snippet:

```
# This dataframe will render correctly in the browser, with the background set to blue
st.dataframe(df.style.set_properties(**{'background-color': 'blue'}))

# This dataframe will render with white blocks on the table and will throw an error when a user interacts with it
st.dataframe(df.style.set_properties(**{'background-color': 'rgb(255, 0, 0)'}))
```

**Expected behavior:**

The code above should display the same dataframe in the browser twice, once with a blue background, and another time with a red background.

**Actual behavior:**

When the dataframe is displayed using "{'background-color': 'rgb(255, 0, 0)'}", it is initially shown as a plain dataframe, with white blocks covering some of the data. 

![image](https://user-images.githubusercontent.com/108280745/184631626-4b4fae8f-3138-4402-bb37-b43c6979568f.png)

Once a user interacts with the dataframe, an error is displayed stating that the colour could not be parsed.

![image](https://user-images.githubusercontent.com/108280745/184631845-6f51f82a-56f0-485a-b251-45df20e9ec36.png)

### Is this a regression?

Yes, this method of styling and displaying dataframes was working as of streamlit 1.9.2.

### Debug info

- Streamlit version: 1.10.0
- Python version: 3.7.13
- Using Pipenv.
- OS version: The issue has been replicated on MacOS Big Sur, Windows 10 and CentOS.
- Browser version: Chrome



Discussion:

Resolving patch:
diff --git a/e2e/scripts/st_arrow_dataframe_canvas_rendering.py b/e2e/scripts/st_arrow_dataframe_canvas_rendering.py
--- a/e2e/scripts/st_arrow_dataframe_canvas_rendering.py
+++ b/e2e/scripts/st_arrow_dataframe_canvas_rendering.py
@@ -95,14 +95,17 @@ def highlight_max(s, props=""):
     return np.where(s == np.nanmax(s.values), props, "")
 
 
-styled_df = df.style.applymap(style_negative, props="color:red;").applymap(
+# Passing style values w/ all color formats to test css-style-string parsing robustness.
+styled_df = df.style.applymap(style_negative, props="color:#FF0000;").applymap(
     lambda v: "opacity: 20%;" if (v < 0.3) and (v > -0.3) else None
 )
 
-styled_df.apply(highlight_max, props="color:white;background-color:darkblue", axis=0)
+styled_df.apply(
+    highlight_max, props="color:white;background-color:rgb(255, 0, 0)", axis=0
+)
 
 styled_df.apply(
-    highlight_max, props="color:white;background-color:pink;", axis=1
+    highlight_max, props="color:white;background-color:hsl(273, 98%, 60%);", axis=1
 ).apply(highlight_max, props="color:white;background-color:purple", axis=None)
 
 st._arrow_dataframe(styled_df)


Test patch:
diff --git a/frontend/src/components/widgets/DataFrame/DataFrameCells.test.tsx b/frontend/src/components/widgets/DataFrame/DataFrameCells.test.tsx
--- a/frontend/src/components/widgets/DataFrame/DataFrameCells.test.tsx
+++ b/frontend/src/components/widgets/DataFrame/DataFrameCells.test.tsx
@@ -26,18 +26,27 @@ test("extractCssProperty should extract the correct property value", () => {
   #T_f116e_row3_col3, #T_f116e_row12_col1 { color: white; background-color: darkblue; color: white; background-color: pink }
   #T_f116e_row11_col10, #T_f116e_row11_col10 {  background-color: darkblue }`
 
+  // All color-value formats
   const cssStyle2 = `
   #T_7e5cc_row6_col0 { background-color: #f8fcc9; color: #000000 }
   #T_7e5cc_row7_col1 { background-color: #1c2d81; color: #f1f1f1 }
   #T_7e5cc_row8_col0 { background-color: #289cc1; color: #f1f1f1 }
   #T_7e5cc_row8_col1 { background-color: #2165ab; color: #f1f1f1 }
-  #T_7e5cc_row9_col0 { background-color: #f0f9b8; color: #000000 }`
+  #T_7e5cc_row9_col0 { background-color: #f0f9b8; color: #000000 }
+  #T_f116e_row12_col14 { background-color: blue }
+  #T_f116e_row13_col14 { background-color: #f1f1f1 }
+  #T_f116e_row14_col1 { background-color: rgba(72 122 180 / .2); }
+  #T_f116e_row15_col1 { background-color: rgba(255, 0, 12, .2)}
+  #T_f116e_row16_col14 { background-color: hsla(240, 100%, 90%) }
+  #T_f116e_row17_col1 { background-color: hsl(255, 0, 12)}`
 
   // Badly Formatted
   const cssStyle3 = `
   #T_f116e_row10_col0,#T_7e5cc_row6_col0   {   background-color: #f8fcc9;     color: #000000 }
   #T_7e5cc_row7_col1{ background-color:#1c2d81; color: #f1f1f1 }
-  #T_7e5cc_row8_col0{background-color: #289cc1;color: #f1f1f1}`
+  #T_7e5cc_row8_col0{background-color: #289cc1;color: #f1f1f1}
+  #T_f116e_row18_col1, #T_f116e_row18_col14 { background-color: hsla(240, 100%,    90%) }
+  #T_f116e_row19_col1, #T_f116e_row19_col14 { background-color: hsl(240, 100%,90%) }`
 
   expect(extractCssProperty("#T_f116e_row10_col1", "color", cssStyle1)).toBe(
     "red"
@@ -66,6 +75,24 @@ test("extractCssProperty should extract the correct property value", () => {
   expect(extractCssProperty("#T_7e5cc_row9_col0", "color", cssStyle2)).toBe(
     "#000000"
   )
+  expect(
+    extractCssProperty("#T_f116e_row12_col14", "background-color", cssStyle2)
+  ).toBe("blue")
+  expect(
+    extractCssProperty("#T_f116e_row13_col14", "background-color", cssStyle2)
+  ).toBe("#f1f1f1")
+  expect(
+    extractCssProperty("#T_f116e_row14_col1", "background-color", cssStyle2)
+  ).toBe("rgba(72 122 180 / .2)")
+  expect(
+    extractCssProperty("#T_f116e_row15_col1", "background-color", cssStyle2)
+  ).toBe("rgba(255, 0, 12, .2)")
+  expect(
+    extractCssProperty("#T_f116e_row16_col14", "background-color", cssStyle2)
+  ).toBe("hsla(240, 100%, 90%)")
+  expect(
+    extractCssProperty("#T_f116e_row17_col1", "background-color", cssStyle2)
+  ).toBe("hsl(255, 0, 12)")
 
   expect(
     extractCssProperty("#T_f116e_row10_col0", "background-color", cssStyle3)
@@ -73,6 +100,12 @@ test("extractCssProperty should extract the correct property value", () => {
   expect(
     extractCssProperty("#T_7e5cc_row8_col0", "background-color", cssStyle3)
   ).toBe("#289cc1")
+  expect(
+    extractCssProperty("#T_f116e_row18_col14", "background-color", cssStyle3)
+  ).toBe("hsla(240, 100%,    90%)")
+  expect(
+    extractCssProperty("#T_f116e_row19_col14", "background-color", cssStyle3)
+  ).toBe("hsl(240, 100%,90%)")
   expect(extractCssProperty("#T_7e5cc_row8_col0", "color", cssStyle3)).toBe(
     "#f1f1f1"
   )