diff --git a/src/__tests__/native/box-shadow.test.tsx b/src/__tests__/native/box-shadow.test.tsx
index 48a387a4..4347c995 100644
--- a/src/__tests__/native/box-shadow.test.tsx
+++ b/src/__tests__/native/box-shadow.test.tsx
@@ -28,6 +28,96 @@ test("shadow values - single nested variables", () => {
});
});
+test("single shadow via runtime variable", () => {
+ registerCSS(
+ `.test {
+ --my-shadow: 0 4px 6px -1px #000;
+ box-shadow: var(--my-shadow);
+ }`,
+ { inlineVariables: false },
+ );
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ expect(component.props.style.boxShadow).toStrictEqual([
+ {
+ offsetX: 0,
+ offsetY: 4,
+ blurRadius: 6,
+ spreadDistance: -1,
+ color: "#000",
+ },
+ ]);
+});
+
+test("single shadow via multi-definition variable (theme switching)", () => {
+ registerCSS(`
+ :root { --themed-shadow: 0 4px 6px -1px #000; }
+ .dark { --themed-shadow: 0 4px 6px -1px #fff; }
+ .test { box-shadow: var(--themed-shadow); }
+ `);
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ expect(component.props.style.boxShadow).toStrictEqual([
+ {
+ offsetX: 0,
+ offsetY: 4,
+ blurRadius: 6,
+ spreadDistance: -1,
+ color: "#000",
+ },
+ ]);
+});
+
+test("transparent shadow via runtime variable is filtered", () => {
+ registerCSS(
+ `.test {
+ --my-shadow: 0 0 0 0 #0000;
+ box-shadow: var(--my-shadow);
+ }`,
+ { inlineVariables: false },
+ );
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ expect(component.props.style.boxShadow).toStrictEqual([]);
+});
+
+test("multi-shadow via runtime variables (comma-separated)", () => {
+ registerCSS(
+ `.test {
+ --shadow-a: 0 4px 6px -1px #000;
+ --shadow-b: 0 1px 2px 0 #333;
+ box-shadow: var(--shadow-a), var(--shadow-b);
+ }`,
+ { inlineVariables: false },
+ );
+
+ render();
+ const component = screen.getByTestId(testID);
+
+ expect(component.props.style.boxShadow).toStrictEqual([
+ {
+ offsetX: 0,
+ offsetY: 4,
+ blurRadius: 6,
+ spreadDistance: -1,
+ color: "#000",
+ },
+ {
+ offsetX: 0,
+ offsetY: 1,
+ blurRadius: 2,
+ spreadDistance: 0,
+ color: "#333",
+ },
+ ]);
+});
+
test("shadow values - multiple nested variables", () => {
registerCSS(`
:root {
diff --git a/src/native/styles/shorthands/box-shadow.ts b/src/native/styles/shorthands/box-shadow.ts
index f65a9370..4eeaf086 100644
--- a/src/native/styles/shorthands/box-shadow.ts
+++ b/src/native/styles/shorthands/box-shadow.ts
@@ -34,20 +34,32 @@ export const boxShadow: StyleFunctionResolver = (
if (!isStyleDescriptorArray(args)) {
return args;
- } else {
- return args
- .flatMap(flattenShadowDescriptor)
- .map((shadows) => {
- if (shadows === undefined) {
- return;
- } else {
- return omitTransparentShadows(
- handler(resolveValue, shadows, get, options),
- );
- }
- })
- .filter((v) => v !== undefined);
}
+
+ // A flat array of primitives (e.g. [0, 4, 6, -1, "#000"]) is a single shadow
+ // resolved from a runtime variable. Pass it directly to the pattern handler.
+ // A nested array (e.g. [[0, 4, 6, -1, "#000"], [...]]) is multiple shadows.
+ if (args.length > 0 && !Array.isArray(args[0])) {
+ const result = handler(resolveValue, args, get, options);
+ if (result === undefined) {
+ return [];
+ }
+ const filtered = omitTransparentShadows(result);
+ return filtered !== undefined ? [filtered] : [];
+ }
+
+ return args
+ .flatMap(flattenShadowDescriptor)
+ .map((shadows) => {
+ if (shadows === undefined) {
+ return;
+ } else {
+ return omitTransparentShadows(
+ handler(resolveValue, shadows, get, options),
+ );
+ }
+ })
+ .filter((v) => v !== undefined);
};
function flattenShadowDescriptor(arg: StyleDescriptor): StyleDescriptor[] {