diff --git a/src/__tests__/native/filters.test.tsx b/src/__tests__/native/filters.test.tsx
new file mode 100644
index 00000000..9ff55e48
--- /dev/null
+++ b/src/__tests__/native/filters.test.tsx
@@ -0,0 +1,181 @@
+import { render, screen } from "@testing-library/react-native";
+import { View } from "react-native-css/components/View";
+import { registerCSS, testID } from "react-native-css/jest";
+
+describe("filter: drop-shadow()", () => {
+ test("basic drop-shadow", () => {
+ registerCSS(`
+ .test { filter: drop-shadow(0 4px 6px #000); }
+ `);
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ // drop-shadow uses standardDeviation (not blurRadius) to match
+ // React Native's DropShadowValue type
+ expect(component.props.style.filter).toStrictEqual([
+ {
+ dropShadow: {
+ offsetX: 0,
+ offsetY: 4,
+ standardDeviation: 6,
+ color: "#000",
+ },
+ },
+ ]);
+ });
+
+ test("drop-shadow with color first", () => {
+ registerCSS(`
+ .test { filter: drop-shadow(#fb2c36 0 0 24px); }
+ `);
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ expect(component.props.style.filter).toStrictEqual([
+ {
+ dropShadow: {
+ color: "#fb2c36",
+ offsetX: 0,
+ offsetY: 0,
+ standardDeviation: 24,
+ },
+ },
+ ]);
+ });
+
+ test("drop-shadow without blur", () => {
+ registerCSS(`
+ .test { filter: drop-shadow(2px 4px #000); }
+ `);
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ expect(component.props.style.filter).toStrictEqual([
+ {
+ dropShadow: {
+ offsetX: 2,
+ offsetY: 4,
+ standardDeviation: 0,
+ color: "#000",
+ },
+ },
+ ]);
+ });
+
+ test("drop-shadow from CSS variable", () => {
+ registerCSS(`
+ :root { --my-shadow: 0 4px 6px #000; }
+ .test { filter: drop-shadow(var(--my-shadow)); }
+ `);
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ expect(component.props.style.filter).toStrictEqual([
+ {
+ dropShadow: {
+ offsetX: 0,
+ offsetY: 4,
+ standardDeviation: 6,
+ color: "#000",
+ },
+ },
+ ]);
+ });
+
+ test("drop-shadow from runtime variable", () => {
+ registerCSS(
+ `.test {
+ --my-shadow: 0 4px 6px #000;
+ filter: drop-shadow(var(--my-shadow));
+ }`,
+ { inlineVariables: false },
+ );
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ expect(component.props.style.filter).toStrictEqual([
+ {
+ dropShadow: {
+ offsetX: 0,
+ offsetY: 4,
+ standardDeviation: 6,
+ color: "#000",
+ },
+ },
+ ]);
+ });
+
+ test("drop-shadow with currentcolor resolves to PlatformColor", () => {
+ registerCSS(
+ `.test {
+ --my-shadow: 0 4px 6px currentcolor;
+ filter: drop-shadow(var(--my-shadow));
+ }`,
+ { inlineVariables: false },
+ );
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ // currentcolor resolves to a PlatformColor object — requires
+ // "color" type (not "string") in the shorthand handler pattern
+ expect(component.props.style.filter).toStrictEqual([
+ {
+ dropShadow: {
+ offsetX: 0,
+ offsetY: 4,
+ standardDeviation: 6,
+ color: { semantic: ["label", "labelColor"] },
+ },
+ },
+ ]);
+ });
+
+ test("Tailwind v4 drop-shadow pattern with @property", () => {
+ registerCSS(`
+ @property --tw-drop-shadow { syntax: "*"; inherits: false; }
+ :root { --drop-shadow-md: 0 3px 3px rgb(0 0 0 / 0.12); }
+ .test {
+ --tw-drop-shadow: drop-shadow(var(--drop-shadow-md));
+ filter: var(--tw-drop-shadow);
+ }
+ `);
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ expect(component.props.style.filter).toStrictEqual([
+ {
+ dropShadow: {
+ offsetX: 0,
+ offsetY: 3,
+ standardDeviation: 3,
+ color: "#0000001f",
+ },
+ },
+ ]);
+ });
+});
+
+describe("filter: opacity()", () => {
+ test("opacity function produces correct key", () => {
+ registerCSS(`
+ @property --tw-opacity { syntax: "*"; inherits: false; }
+ .test {
+ --tw-opacity: opacity(0.5);
+ filter: var(--tw-opacity);
+ }
+ `);
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ // Must produce { opacity: 0.5 }, not { hueRotate: 0.5 }
+ expect(component.props.style.filter).toStrictEqual([{ opacity: 0.5 }]);
+ });
+});
diff --git a/src/__tests__/vendor/tailwind/filters.test.tsx b/src/__tests__/vendor/tailwind/filters.test.tsx
index 24833fed..c7bbb4a6 100644
--- a/src/__tests__/vendor/tailwind/filters.test.tsx
+++ b/src/__tests__/vendor/tailwind/filters.test.tsx
@@ -63,7 +63,7 @@ describe("Filters - Drop Shadow", () => {
[
{
dropShadow: {
- blurRadius: 2,
+ standardDeviation: 2,
color: "#0000001a",
offsetX: 0,
offsetY: 1,
@@ -71,7 +71,7 @@ describe("Filters - Drop Shadow", () => {
},
{
dropShadow: {
- blurRadius: 1,
+ standardDeviation: 1,
color: "#0000000f",
offsetX: 0,
offsetY: 1,
diff --git a/src/native/styles/functions/filters.ts b/src/native/styles/functions/filters.ts
index 17def28e..98cf8fff 100644
--- a/src/native/styles/functions/filters.ts
+++ b/src/native/styles/functions/filters.ts
@@ -62,22 +62,22 @@ export const saturate: StyleFunctionResolver = (resolveValue, value) => {
export const opacity: StyleFunctionResolver = (resolveValue, value) => {
const args = resolveValue(value[2]);
return {
- hueRotate: (Array.isArray(args) ? args[0] : args) as unknown,
+ opacity: (Array.isArray(args) ? args[0] : args) as unknown,
};
};
-const color = ["color", "string"] as const;
+const color = ["color", "color"] as const;
const offsetX = ["offsetX", "number"] as const;
const offsetY = ["offsetY", "number"] as const;
-const blurRadius = ["blurRadius", "number"] as const;
+const standardDeviation = ["standardDeviation", "number"] as const;
const handler = shorthandHandler(
[
- [offsetX, offsetY, blurRadius, color],
+ [offsetX, offsetY, standardDeviation, color],
[color, offsetX, offsetY],
- [color, offsetX, offsetY, blurRadius],
+ [color, offsetX, offsetY, standardDeviation],
[offsetX, offsetY, color],
- [offsetX, offsetY, blurRadius, color],
+ [offsetX, offsetY, standardDeviation, color],
],
[],
"object",