@fluentui-react-native/experimental-shadow 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.json +16 -1
- package/CHANGELOG.md +10 -2
- package/lib/Shadow.d.ts +2 -2
- package/lib/Shadow.d.ts.map +1 -1
- package/lib/Shadow.js +28 -22
- package/lib/Shadow.js.map +1 -1
- package/lib/Shadow.types.d.ts +2 -1
- package/lib/Shadow.types.d.ts.map +1 -1
- package/lib/Shadow.types.js +1 -1
- package/lib/Shadow.types.js.map +1 -1
- package/lib/__tests__/Shadow.test.js +86 -5
- package/lib/__tests__/Shadow.test.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/shadowStyle.d.ts +25 -0
- package/lib/shadowStyle.d.ts.map +1 -0
- package/lib/shadowStyle.js +36 -0
- package/lib/shadowStyle.js.map +1 -0
- package/lib-commonjs/Shadow.d.ts +2 -2
- package/lib-commonjs/Shadow.d.ts.map +1 -1
- package/lib-commonjs/Shadow.js +28 -23
- package/lib-commonjs/Shadow.js.map +1 -1
- package/lib-commonjs/Shadow.types.d.ts +2 -1
- package/lib-commonjs/Shadow.types.d.ts.map +1 -1
- package/lib-commonjs/Shadow.types.js +2 -0
- package/lib-commonjs/Shadow.types.js.map +1 -1
- package/lib-commonjs/__tests__/Shadow.test.js +86 -5
- package/lib-commonjs/__tests__/Shadow.test.js.map +1 -1
- package/lib-commonjs/index.d.ts +1 -0
- package/lib-commonjs/index.d.ts.map +1 -1
- package/lib-commonjs/index.js +3 -1
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/shadowStyle.d.ts +25 -0
- package/lib-commonjs/shadowStyle.d.ts.map +1 -0
- package/lib-commonjs/shadowStyle.js +39 -0
- package/lib-commonjs/shadowStyle.js.map +1 -0
- package/package.json +4 -1
- package/src/Shadow.tsx +19 -26
- package/src/Shadow.types.ts +15 -1
- package/src/__tests__/Shadow.test.tsx +137 -5
- package/src/__tests__/__snapshots__/Shadow.test.tsx.snap +402 -4
- package/src/index.ts +1 -0
- package/src/shadowStyle.ts +43 -0
package/lib-commonjs/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Shadow = void 0;
|
|
3
|
+
exports.getShadowTokenStyleSet = exports.Shadow = void 0;
|
|
4
4
|
var Shadow_1 = require("./Shadow");
|
|
5
5
|
Object.defineProperty(exports, "Shadow", { enumerable: true, get: function () { return Shadow_1.Shadow; } });
|
|
6
|
+
var shadowStyle_1 = require("./shadowStyle");
|
|
7
|
+
Object.defineProperty(exports, "getShadowTokenStyleSet", { enumerable: true, get: function () { return shadowStyle_1.getShadowTokenStyleSet; } });
|
|
6
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAkC;AAAzB,gGAAA,MAAM,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AAEf,6CAAuD;AAA9C,qHAAA,sBAAsB,OAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Theme } from '@fluentui-react-native/framework';
|
|
2
|
+
import { ShadowDepth } from './Shadow.types';
|
|
3
|
+
export declare const getShadowTokenStyleSet: typeof getShadowTokenStyleSetWorker;
|
|
4
|
+
declare function getShadowTokenStyleSetWorker(t: Theme, depth: ShadowDepth): {
|
|
5
|
+
key: {
|
|
6
|
+
shadowColor: string;
|
|
7
|
+
shadowOpacity: number;
|
|
8
|
+
shadowRadius: number;
|
|
9
|
+
shadowOffset: {
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
ambient: {
|
|
15
|
+
shadowColor: string;
|
|
16
|
+
shadowOpacity: number;
|
|
17
|
+
shadowRadius: number;
|
|
18
|
+
shadowOffset: {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=shadowStyle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadowStyle.d.ts","sourceRoot":"","sources":["../src/shadowStyle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAW,MAAM,kCAAkC,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,eAAO,MAAM,sBAAsB,qCAAwC,CAAC;AAE5E,iBAAS,4BAA4B,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW;;;;;;;;;;;;;;;;;;;EAwBjE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getShadowTokenStyleSet = void 0;
|
|
4
|
+
var framework_1 = require("@fluentui-react-native/framework");
|
|
5
|
+
exports.getShadowTokenStyleSet = (0, framework_1.memoize)(getShadowTokenStyleSetWorker);
|
|
6
|
+
function getShadowTokenStyleSetWorker(t, depth) {
|
|
7
|
+
var keyShadow = t.shadows[depth.toString()].key;
|
|
8
|
+
var ambientShadow = t.shadows[depth.toString()].ambient;
|
|
9
|
+
return {
|
|
10
|
+
key: {
|
|
11
|
+
shadowColor: shadowColorFromRGBAColor(keyShadow.color),
|
|
12
|
+
shadowOpacity: shadowOpacityFromRGBAColor(keyShadow.color),
|
|
13
|
+
shadowRadius: keyShadow.blur,
|
|
14
|
+
shadowOffset: {
|
|
15
|
+
width: keyShadow.x,
|
|
16
|
+
height: keyShadow.y,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
ambient: {
|
|
20
|
+
shadowColor: shadowColorFromRGBAColor(ambientShadow.color),
|
|
21
|
+
shadowOpacity: shadowOpacityFromRGBAColor(ambientShadow.color),
|
|
22
|
+
shadowRadius: ambientShadow.blur,
|
|
23
|
+
shadowOffset: {
|
|
24
|
+
width: ambientShadow.x,
|
|
25
|
+
height: ambientShadow.y,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
var shadowColorFromRGBAColor = function (rgbaColor) {
|
|
31
|
+
return rgbaColor.toString().substring(0, 7);
|
|
32
|
+
};
|
|
33
|
+
var shadowOpacityFromRGBAColor = function (rgbaColor) {
|
|
34
|
+
var opacityAsHex = '0x' + rgbaColor.toString().substring(7);
|
|
35
|
+
var opacityAsDecimal = Number(opacityAsHex) / 255.0;
|
|
36
|
+
// Round to two decimal places
|
|
37
|
+
return Math.round(opacityAsDecimal * 100) / 100;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=shadowStyle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadowStyle.js","sourceRoot":"","sources":["../src/shadowStyle.ts"],"names":[],"mappings":";;;AAAA,8DAAkE;AAIrD,QAAA,sBAAsB,GAAG,IAAA,mBAAO,EAAC,4BAA4B,CAAC,CAAC;AAE5E,SAAS,4BAA4B,CAAC,CAAQ,EAAE,KAAkB;IAChE,IAAM,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC;IAClD,IAAM,aAAa,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC;IAE1D,OAAO;QACL,GAAG,EAAE;YACH,WAAW,EAAE,wBAAwB,CAAC,SAAS,CAAC,KAAK,CAAC;YACtD,aAAa,EAAE,0BAA0B,CAAC,SAAS,CAAC,KAAK,CAAC;YAC1D,YAAY,EAAE,SAAS,CAAC,IAAI;YAC5B,YAAY,EAAE;gBACZ,KAAK,EAAE,SAAS,CAAC,CAAC;gBAClB,MAAM,EAAE,SAAS,CAAC,CAAC;aACpB;SACF;QACD,OAAO,EAAE;YACP,WAAW,EAAE,wBAAwB,CAAC,aAAa,CAAC,KAAK,CAAC;YAC1D,aAAa,EAAE,0BAA0B,CAAC,aAAa,CAAC,KAAK,CAAC;YAC9D,YAAY,EAAE,aAAa,CAAC,IAAI;YAChC,YAAY,EAAE;gBACZ,KAAK,EAAE,aAAa,CAAC,CAAC;gBACtB,MAAM,EAAE,aAAa,CAAC,CAAC;aACxB;SACF;KACF,CAAC;AACJ,CAAC;AAED,IAAM,wBAAwB,GAAG,UAAC,SAAqB;IACrD,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9C,CAAC,CAAC;AAEF,IAAM,0BAA0B,GAAG,UAAC,SAAqB;IACvD,IAAM,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC9D,IAAM,gBAAgB,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC;IAEtD,8BAA8B;IAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AAClD,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluentui-react-native/experimental-shadow",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A cross-platform Shadow component using the Fluent Design System",
|
|
5
5
|
"main": "lib-commonjs/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
"url": "https://github.com/microsoft/fluentui-react-native.git",
|
|
22
22
|
"directory": "packages/experimental/Shadow"
|
|
23
23
|
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@fluentui-react-native/framework": "0.7.31"
|
|
26
|
+
},
|
|
24
27
|
"devDependencies": {
|
|
25
28
|
"@fluentui-react-native/eslint-config-rules": "^0.1.1",
|
|
26
29
|
"@fluentui-react-native/test-tools": ">=0.1.1 <1.0.0",
|
package/src/Shadow.tsx
CHANGED
|
@@ -1,31 +1,24 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
|
-
import { ShadowProps } from './Shadow.types';
|
|
3
|
+
import { ShadowProps, shadowName } from './Shadow.types';
|
|
4
|
+
import { useFluentTheme, mergeProps, stagedComponent } from '@fluentui-react-native/framework';
|
|
5
|
+
import { getShadowTokenStyleSet } from './shadowStyle';
|
|
4
6
|
|
|
5
|
-
export const Shadow
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const keyShadow = {
|
|
18
|
-
'2': { shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.14, shadowRadius: 2 },
|
|
19
|
-
'4': { shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.14, shadowRadius: 4 },
|
|
20
|
-
'8': { shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.14, shadowRadius: 8 },
|
|
21
|
-
'16': { shadowOffset: { width: 0, height: 8 }, shadowOpacity: 0.14, shadowRadius: 16 },
|
|
22
|
-
'28': { shadowOffset: { width: 0, height: 14 }, shadowOpacity: 0.24, shadowRadius: 28 },
|
|
23
|
-
'64': { shadowOffset: { width: 0, height: 32 }, shadowOpacity: 0.24, shadowRadius: 64 },
|
|
7
|
+
export const Shadow = stagedComponent((props: ShadowProps) => {
|
|
8
|
+
const theme = useFluentTheme();
|
|
9
|
+
|
|
10
|
+
return (final: ShadowProps, ...children: React.ReactNode[]) => {
|
|
11
|
+
const shadowTokenStyleSet = getShadowTokenStyleSet(theme, props.depth);
|
|
12
|
+
const mergedProps = mergeProps(final, { style: shadowTokenStyleSet.key });
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<View style={shadowTokenStyleSet.ambient}>
|
|
16
|
+
<View {...mergedProps}>{children}</View>
|
|
17
|
+
</View>
|
|
18
|
+
);
|
|
24
19
|
};
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
Shadow.displayName = shadowName;
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
<View style={ambientShadow[props.depth]}>
|
|
28
|
-
<View style={keyShadow[props.depth]}>{props.children}</View>
|
|
29
|
-
</View>
|
|
30
|
-
);
|
|
31
|
-
};
|
|
24
|
+
export default Shadow;
|
package/src/Shadow.types.ts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { ViewProps } from 'react-native';
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export const shadowName = 'Shadow';
|
|
4
|
+
|
|
5
|
+
export type ShadowDepth =
|
|
6
|
+
| 'shadow2'
|
|
7
|
+
| 'shadow4'
|
|
8
|
+
| 'shadow8'
|
|
9
|
+
| 'shadow16'
|
|
10
|
+
| 'shadow28'
|
|
11
|
+
| 'shadow64'
|
|
12
|
+
| 'shadow2brand'
|
|
13
|
+
| 'shadow4brand'
|
|
14
|
+
| 'shadow8brand'
|
|
15
|
+
| 'shadow16brand'
|
|
16
|
+
| 'shadow28brand'
|
|
17
|
+
| 'shadow64brand';
|
|
4
18
|
|
|
5
19
|
export interface ShadowProps extends ViewProps {
|
|
6
20
|
depth?: ShadowDepth;
|
|
@@ -5,21 +5,153 @@ import * as renderer from 'react-test-renderer';
|
|
|
5
5
|
import { checkRenderConsistency, checkReRender } from '@fluentui-react-native/test-tools';
|
|
6
6
|
|
|
7
7
|
describe('Shadow component tests', () => {
|
|
8
|
-
it('Shadow
|
|
8
|
+
it('Shadow (depth=2)', () => {
|
|
9
9
|
const tree = renderer
|
|
10
10
|
.create(
|
|
11
|
-
<Shadow>
|
|
12
|
-
<Text>Shadow
|
|
11
|
+
<Shadow depth="shadow2">
|
|
12
|
+
<Text>Shadow (depth=2) </Text>
|
|
13
13
|
</Shadow>,
|
|
14
14
|
)
|
|
15
15
|
.toJSON();
|
|
16
16
|
expect(tree).toMatchSnapshot();
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
it('Shadow (depth=4)', () => {
|
|
20
|
+
const tree = renderer
|
|
21
|
+
.create(
|
|
22
|
+
<Shadow depth="shadow4">
|
|
23
|
+
<Text>Shadow (depth=4)</Text>
|
|
24
|
+
</Shadow>,
|
|
25
|
+
)
|
|
26
|
+
.toJSON();
|
|
27
|
+
expect(tree).toMatchSnapshot();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('Shadow (depth=8)', () => {
|
|
31
|
+
const tree = renderer
|
|
32
|
+
.create(
|
|
33
|
+
<Shadow depth="shadow8">
|
|
34
|
+
<Text>Shadow (depth=8) </Text>
|
|
35
|
+
</Shadow>,
|
|
36
|
+
)
|
|
37
|
+
.toJSON();
|
|
38
|
+
expect(tree).toMatchSnapshot();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('Shadow (depth=16)', () => {
|
|
42
|
+
const tree = renderer
|
|
43
|
+
.create(
|
|
44
|
+
<Shadow depth="shadow16">
|
|
45
|
+
<Text>Shadow (depth=16)</Text>
|
|
46
|
+
</Shadow>,
|
|
47
|
+
)
|
|
48
|
+
.toJSON();
|
|
49
|
+
expect(tree).toMatchSnapshot();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('Shadow (depth=28)', () => {
|
|
53
|
+
const tree = renderer
|
|
54
|
+
.create(
|
|
55
|
+
<Shadow depth="shadow28">
|
|
56
|
+
<Text>Shadow (depth=28) </Text>
|
|
57
|
+
</Shadow>,
|
|
58
|
+
)
|
|
59
|
+
.toJSON();
|
|
60
|
+
expect(tree).toMatchSnapshot();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('Shadow (depth=64)', () => {
|
|
64
|
+
const tree = renderer
|
|
65
|
+
.create(
|
|
66
|
+
<Shadow depth="shadow64">
|
|
67
|
+
<Text>Shadow (depth=64)</Text>
|
|
68
|
+
</Shadow>,
|
|
69
|
+
)
|
|
70
|
+
.toJSON();
|
|
71
|
+
expect(tree).toMatchSnapshot();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('Brand shadow (depth=2)', () => {
|
|
75
|
+
const tree = renderer
|
|
76
|
+
.create(
|
|
77
|
+
<Shadow depth="shadow2brand">
|
|
78
|
+
<Text>Brand shadow (depth=2)</Text>
|
|
79
|
+
</Shadow>,
|
|
80
|
+
)
|
|
81
|
+
.toJSON();
|
|
82
|
+
expect(tree).toMatchSnapshot();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('Brand shadow (depth=4)', () => {
|
|
86
|
+
const tree = renderer
|
|
87
|
+
.create(
|
|
88
|
+
<Shadow depth="shadow4brand">
|
|
89
|
+
<Text>Brand shadow (depth=4)</Text>
|
|
90
|
+
</Shadow>,
|
|
91
|
+
)
|
|
92
|
+
.toJSON();
|
|
93
|
+
expect(tree).toMatchSnapshot();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('Brand shadow (depth=8)', () => {
|
|
97
|
+
const tree = renderer
|
|
98
|
+
.create(
|
|
99
|
+
<Shadow depth="shadow8brand">
|
|
100
|
+
<Text>Brand shadow (depth=8)</Text>
|
|
101
|
+
</Shadow>,
|
|
102
|
+
)
|
|
103
|
+
.toJSON();
|
|
104
|
+
expect(tree).toMatchSnapshot();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('Brand shadow (depth=16)', () => {
|
|
108
|
+
const tree = renderer
|
|
109
|
+
.create(
|
|
110
|
+
<Shadow depth="shadow16brand">
|
|
111
|
+
<Text>Brand shadow (depth=16)</Text>
|
|
112
|
+
</Shadow>,
|
|
113
|
+
)
|
|
114
|
+
.toJSON();
|
|
115
|
+
expect(tree).toMatchSnapshot();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('Brand shadow (depth=28)', () => {
|
|
119
|
+
const tree = renderer
|
|
120
|
+
.create(
|
|
121
|
+
<Shadow depth="shadow28brand">
|
|
122
|
+
<Text>Brand shadow (depth=28)</Text>
|
|
123
|
+
</Shadow>,
|
|
124
|
+
)
|
|
125
|
+
.toJSON();
|
|
126
|
+
expect(tree).toMatchSnapshot();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('Brand shadow (depth=64)', () => {
|
|
130
|
+
const tree = renderer
|
|
131
|
+
.create(
|
|
132
|
+
<Shadow depth="shadow64brand">
|
|
133
|
+
<Text>Brand shadow (depth=64)</Text>
|
|
134
|
+
</Shadow>,
|
|
135
|
+
)
|
|
136
|
+
.toJSON();
|
|
137
|
+
expect(tree).toMatchSnapshot();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('Shadow simple rendering does not invalidate styling', () => {
|
|
141
|
+
checkRenderConsistency(
|
|
142
|
+
() => (
|
|
143
|
+
<Shadow depth="shadow2">
|
|
144
|
+
<Text>Shadow render test</Text>
|
|
145
|
+
</Shadow>
|
|
146
|
+
),
|
|
147
|
+
2,
|
|
148
|
+
);
|
|
149
|
+
});
|
|
150
|
+
|
|
19
151
|
it('Shadow simple rendering does not invalidate styling', () => {
|
|
20
152
|
checkRenderConsistency(
|
|
21
153
|
() => (
|
|
22
|
-
<Shadow>
|
|
154
|
+
<Shadow depth="shadow2">
|
|
23
155
|
<Text>Shadow render test</Text>
|
|
24
156
|
</Shadow>
|
|
25
157
|
),
|
|
@@ -30,7 +162,7 @@ describe('Shadow component tests', () => {
|
|
|
30
162
|
it('Shadow re-renders correctly', () => {
|
|
31
163
|
checkReRender(
|
|
32
164
|
() => (
|
|
33
|
-
<Shadow>
|
|
165
|
+
<Shadow depth="shadow2">
|
|
34
166
|
<Text>Shadow render twice test</Text>
|
|
35
167
|
</Shadow>
|
|
36
168
|
),
|