@teamturing/react-native-kit 1.2.3 → 1.3.0
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/lib/commonjs/component/Animation/implicit/OpacityAnimatedView.js +8 -5
- package/lib/commonjs/component/Animation/implicit/OpacityAnimatedView.js.map +1 -1
- package/lib/commonjs/component/ProfilePhoto/LightProfilePhoto.js +48 -0
- package/lib/commonjs/component/ProfilePhoto/LightProfilePhoto.js.map +1 -0
- package/lib/commonjs/component/ProfilePhoto/ProfileImageGroup.js +78 -0
- package/lib/commonjs/component/ProfilePhoto/ProfileImageGroup.js.map +1 -0
- package/lib/commonjs/component/ProfilePhoto/ProfilePhoto.js +68 -0
- package/lib/commonjs/component/ProfilePhoto/ProfilePhoto.js.map +1 -0
- package/lib/commonjs/component/ProfilePhoto/ProfilePhotoWithBorderGradient.js +53 -0
- package/lib/commonjs/component/ProfilePhoto/ProfilePhotoWithBorderGradient.js.map +1 -0
- package/lib/commonjs/component/ProfilePhoto/index.js +50 -0
- package/lib/commonjs/component/ProfilePhoto/index.js.map +1 -0
- package/lib/commonjs/component/ProfilePhoto/profile_outline_gray_90.png +0 -0
- package/lib/commonjs/component/ProfilePhoto/profile_outline_gray_90@2x.png +0 -0
- package/lib/commonjs/component/ProfilePhoto/profile_outline_gray_90@3x.png +0 -0
- package/lib/commonjs/component/index.js +11 -0
- package/lib/commonjs/component/index.js.map +1 -1
- package/lib/commonjs/util/WebImageUrlEnricher.js +27 -0
- package/lib/commonjs/util/WebImageUrlEnricher.js.map +1 -0
- package/lib/commonjs/util/WebImageUrlEnricher.test.js +22 -0
- package/lib/commonjs/util/WebImageUrlEnricher.test.js.map +1 -0
- package/lib/commonjs/util/index.js +11 -0
- package/lib/commonjs/util/index.js.map +1 -1
- package/lib/module/component/Animation/implicit/OpacityAnimatedView.js +9 -6
- package/lib/module/component/Animation/implicit/OpacityAnimatedView.js.map +1 -1
- package/lib/module/component/ProfilePhoto/LightProfilePhoto.js +44 -0
- package/lib/module/component/ProfilePhoto/LightProfilePhoto.js.map +1 -0
- package/lib/module/component/ProfilePhoto/ProfileImageGroup.js +74 -0
- package/lib/module/component/ProfilePhoto/ProfileImageGroup.js.map +1 -0
- package/lib/module/component/ProfilePhoto/ProfilePhoto.js +64 -0
- package/lib/module/component/ProfilePhoto/ProfilePhoto.js.map +1 -0
- package/lib/module/component/ProfilePhoto/ProfilePhotoWithBorderGradient.js +50 -0
- package/lib/module/component/ProfilePhoto/ProfilePhotoWithBorderGradient.js.map +1 -0
- package/lib/module/component/ProfilePhoto/index.js +7 -0
- package/lib/module/component/ProfilePhoto/index.js.map +1 -0
- package/lib/module/component/ProfilePhoto/profile_outline_gray_90.png +0 -0
- package/lib/module/component/ProfilePhoto/profile_outline_gray_90@2x.png +0 -0
- package/lib/module/component/ProfilePhoto/profile_outline_gray_90@3x.png +0 -0
- package/lib/module/component/index.js +1 -0
- package/lib/module/component/index.js.map +1 -1
- package/lib/module/util/WebImageUrlEnricher.js +23 -0
- package/lib/module/util/WebImageUrlEnricher.js.map +1 -0
- package/lib/module/util/WebImageUrlEnricher.test.js +22 -0
- package/lib/module/util/WebImageUrlEnricher.test.js.map +1 -0
- package/lib/module/util/index.js +1 -0
- package/lib/module/util/index.js.map +1 -1
- package/lib/typescript/commonjs/src/component/ProfilePhoto/LightProfilePhoto.d.ts +11 -0
- package/lib/typescript/commonjs/src/component/ProfilePhoto/LightProfilePhoto.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/component/ProfilePhoto/ProfileImageGroup.d.ts +20 -0
- package/lib/typescript/commonjs/src/component/ProfilePhoto/ProfileImageGroup.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/component/ProfilePhoto/ProfilePhoto.d.ts +14 -0
- package/lib/typescript/commonjs/src/component/ProfilePhoto/ProfilePhoto.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/component/ProfilePhoto/ProfilePhotoWithBorderGradient.d.ts +10 -0
- package/lib/typescript/commonjs/src/component/ProfilePhoto/ProfilePhotoWithBorderGradient.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/component/ProfilePhoto/index.d.ts +5 -0
- package/lib/typescript/commonjs/src/component/ProfilePhoto/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/component/index.d.ts +1 -0
- package/lib/typescript/commonjs/src/component/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/util/WebImageUrlEnricher.d.ts +12 -0
- package/lib/typescript/commonjs/src/util/WebImageUrlEnricher.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/util/WebImageUrlEnricher.test.d.ts +2 -0
- package/lib/typescript/commonjs/src/util/WebImageUrlEnricher.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/util/index.d.ts +1 -0
- package/lib/typescript/commonjs/src/util/index.d.ts.map +1 -1
- package/lib/typescript/module/src/component/ProfilePhoto/LightProfilePhoto.d.ts +11 -0
- package/lib/typescript/module/src/component/ProfilePhoto/LightProfilePhoto.d.ts.map +1 -0
- package/lib/typescript/module/src/component/ProfilePhoto/ProfileImageGroup.d.ts +20 -0
- package/lib/typescript/module/src/component/ProfilePhoto/ProfileImageGroup.d.ts.map +1 -0
- package/lib/typescript/module/src/component/ProfilePhoto/ProfilePhoto.d.ts +14 -0
- package/lib/typescript/module/src/component/ProfilePhoto/ProfilePhoto.d.ts.map +1 -0
- package/lib/typescript/module/src/component/ProfilePhoto/ProfilePhotoWithBorderGradient.d.ts +10 -0
- package/lib/typescript/module/src/component/ProfilePhoto/ProfilePhotoWithBorderGradient.d.ts.map +1 -0
- package/lib/typescript/module/src/component/ProfilePhoto/index.d.ts +5 -0
- package/lib/typescript/module/src/component/ProfilePhoto/index.d.ts.map +1 -0
- package/lib/typescript/module/src/component/index.d.ts +1 -0
- package/lib/typescript/module/src/component/index.d.ts.map +1 -1
- package/lib/typescript/module/src/util/WebImageUrlEnricher.d.ts +12 -0
- package/lib/typescript/module/src/util/WebImageUrlEnricher.d.ts.map +1 -0
- package/lib/typescript/module/src/util/WebImageUrlEnricher.test.d.ts +2 -0
- package/lib/typescript/module/src/util/WebImageUrlEnricher.test.d.ts.map +1 -0
- package/lib/typescript/module/src/util/index.d.ts +1 -0
- package/lib/typescript/module/src/util/index.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/component/Animation/implicit/OpacityAnimatedView.tsx +6 -6
- package/src/component/ProfilePhoto/LightProfilePhoto.tsx +59 -0
- package/src/component/ProfilePhoto/ProfileImageGroup.tsx +98 -0
- package/src/component/ProfilePhoto/ProfilePhoto.tsx +81 -0
- package/src/component/ProfilePhoto/ProfilePhotoWithBorderGradient.tsx +39 -0
- package/src/component/ProfilePhoto/index.ts +4 -0
- package/src/component/ProfilePhoto/profile_outline_gray_90.png +0 -0
- package/src/component/ProfilePhoto/profile_outline_gray_90@2x.png +0 -0
- package/src/component/ProfilePhoto/profile_outline_gray_90@3x.png +0 -0
- package/src/component/index.ts +1 -1
- package/src/util/WebImageUrlEnricher.test.ts +14 -0
- package/src/util/WebImageUrlEnricher.ts +31 -0
- package/src/util/index.ts +1 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
+
type Props = {
|
|
4
|
+
style?: StyleProp<ViewStyle>;
|
|
5
|
+
onPress?: () => void;
|
|
6
|
+
showIcon?: boolean;
|
|
7
|
+
pressable?: boolean;
|
|
8
|
+
length?: number;
|
|
9
|
+
testID?: string;
|
|
10
|
+
profileImageUrl?: string;
|
|
11
|
+
};
|
|
12
|
+
declare const ProfilePhoto: ({ style, onPress, showIcon, pressable, length: _length, testID, profileImageUrl, }: Props) => ReactElement;
|
|
13
|
+
export { ProfilePhoto };
|
|
14
|
+
//# sourceMappingURL=ProfilePhoto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProfilePhoto.d.ts","sourceRoot":"","sources":["../../../../../../src/component/ProfilePhoto/ProfilePhoto.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAQ,MAAM,cAAc,CAAC;AAWpE,KAAK,KAAK,GAAG;IACX,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AACF,QAAA,MAAM,YAAY,uFAQf,KAAK,KAAG,YAiDV,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { ColorValue } from 'react-native';
|
|
3
|
+
declare const ProfilePhotoWithBorderGradient: import("react").MemoExoticComponent<({ profileImageUrl, size, borderGradientColor, optimize, }: {
|
|
4
|
+
profileImageUrl: string;
|
|
5
|
+
size: number;
|
|
6
|
+
borderGradientColor?: ColorValue | undefined;
|
|
7
|
+
optimize?: boolean | undefined;
|
|
8
|
+
}) => import("react/jsx-runtime").JSX.Element>;
|
|
9
|
+
export { ProfilePhotoWithBorderGradient };
|
|
10
|
+
//# sourceMappingURL=ProfilePhotoWithBorderGradient.d.ts.map
|
package/lib/typescript/module/src/component/ProfilePhoto/ProfilePhotoWithBorderGradient.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProfilePhotoWithBorderGradient.d.ts","sourceRoot":"","sources":["../../../../../../src/component/ProfilePhoto/ProfilePhotoWithBorderGradient.tsx"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAQ/C,QAAA,MAAM,8BAA8B;qBAOf,MAAM;UACjB,MAAM;;;8CAmBf,CAAC;AAEF,OAAO,EAAE,8BAA8B,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/component/ProfilePhoto/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kCAAkC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/component/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,OAAO,CAAC;AACtB,cAAc,iBAAiB,CAAC;AAChC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/component/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,OAAO,CAAC;AACtB,cAAc,iBAAiB,CAAC;AAChC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ImageCrop = {
|
|
2
|
+
l: number;
|
|
3
|
+
r: number;
|
|
4
|
+
t: number;
|
|
5
|
+
b: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function appendImageSizeQueryParams({ url, desiredWidth, crop, }: {
|
|
8
|
+
url: string;
|
|
9
|
+
desiredWidth: number;
|
|
10
|
+
crop?: ImageCrop;
|
|
11
|
+
}): string;
|
|
12
|
+
//# sourceMappingURL=WebImageUrlEnricher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebImageUrlEnricher.d.ts","sourceRoot":"","sources":["../../../../../src/util/WebImageUrlEnricher.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACvE,wBAAgB,0BAA0B,CAAC,EACzC,GAAG,EACH,YAAY,EACZ,IAAI,GACL,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,GAAG,MAAM,CAgBT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebImageUrlEnricher.test.d.ts","sourceRoot":"","sources":["../../../../../src/util/WebImageUrlEnricher.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/util/index.ts"],"names":[],"mappings":"AAAA,cAAc,MAAM,CAAC;AACrB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,MAAM,CAAC;AACrB,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/util/index.ts"],"names":[],"mappings":"AAAA,cAAc,MAAM,CAAC;AACrB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,MAAM,CAAC;AACrB,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teamturing/react-native-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "React Native Common Module for Team Turing",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"example": "yarn workspace @teamturing/react-native-kit-example",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"@mj-studio/react-native-spannable-string": "^1.1.4",
|
|
19
19
|
"@react-native-community/hooks": "^3.0.0",
|
|
20
20
|
"@teamturing/icons": "^1.37.2",
|
|
21
|
+
"@teamturing/utils": "^1.2.1",
|
|
21
22
|
"polished": "^4.3.1"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
@@ -29,7 +30,8 @@
|
|
|
29
30
|
"@testing-library/react-native": "^12.6.0",
|
|
30
31
|
"@types/react": "^18.2.44",
|
|
31
32
|
"eslint-config-expo": "^7.1.2",
|
|
32
|
-
"eslint-import-resolver-typescript": "^3.6.
|
|
33
|
+
"eslint-import-resolver-typescript": "^3.6.3",
|
|
34
|
+
"eslint-plugin-import": "^2.29.1",
|
|
33
35
|
"lottie-react-native": "^6.7.2",
|
|
34
36
|
"moti": "^0.29.0",
|
|
35
37
|
"react": "18.2.0",
|
|
@@ -156,5 +158,5 @@
|
|
|
156
158
|
"bugs": {
|
|
157
159
|
"url": "https://github.com/weareteamturing/bombe/issues"
|
|
158
160
|
},
|
|
159
|
-
"gitHead": "
|
|
161
|
+
"gitHead": "024e45553815889f8ee7999ed6a62f6b4ec58694"
|
|
160
162
|
}
|
|
@@ -3,7 +3,7 @@ import { useRef, useEffect, useState } from 'react';
|
|
|
3
3
|
import type { ViewProps } from 'react-native';
|
|
4
4
|
import { Animated } from 'react-native';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { useTimeoutHandlers } from '../../../hook';
|
|
7
7
|
|
|
8
8
|
type Props = { opacity: number; duration?: number; dropChildrenWhenInvisible?: boolean } & ViewProps;
|
|
9
9
|
const OpacityAnimatedView = ({
|
|
@@ -15,22 +15,22 @@ const OpacityAnimatedView = ({
|
|
|
15
15
|
...rest
|
|
16
16
|
}: PropsWithChildren<Props>) => {
|
|
17
17
|
const opacityValue = useRef(new Animated.Value(opacity)).current;
|
|
18
|
-
const
|
|
18
|
+
const { clearAllTimers, setAutoClearTimeout } = useTimeoutHandlers();
|
|
19
19
|
const [dropChildren, setDropChildren] = useState(!!(dropChildrenWhenInvisible && opacity === 0));
|
|
20
20
|
useEffect(() => {
|
|
21
|
-
|
|
21
|
+
clearAllTimers();
|
|
22
22
|
const anim = Animated.timing(opacityValue, { useNativeDriver: true, toValue: opacity, duration });
|
|
23
23
|
anim.start();
|
|
24
24
|
if (opacity <= 0 && dropChildrenWhenInvisible) {
|
|
25
|
-
|
|
25
|
+
setAutoClearTimeout(() => setDropChildren(true), duration);
|
|
26
26
|
} else {
|
|
27
27
|
setDropChildren(false);
|
|
28
28
|
}
|
|
29
29
|
return () => {
|
|
30
|
-
|
|
30
|
+
clearAllTimers();
|
|
31
31
|
anim.stop();
|
|
32
32
|
};
|
|
33
|
-
}, [opacity, duration, opacityValue, dropChildrenWhenInvisible,
|
|
33
|
+
}, [opacity, duration, opacityValue, dropChildrenWhenInvisible, clearAllTimers, setAutoClearTimeout]);
|
|
34
34
|
|
|
35
35
|
return (
|
|
36
36
|
<Animated.View style={[style, { opacity: opacityValue }]} {...rest}>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { StyleProp, ViewStyle } from 'react-native';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { is, appendImageSizeQueryParams } from '../../util';
|
|
5
|
+
import { Img } from '../Img';
|
|
6
|
+
|
|
7
|
+
import defaultImage from './profile_outline_gray_90.png';
|
|
8
|
+
|
|
9
|
+
// this is used for just rendering character image in light component like list item(shouldn't be heavy)
|
|
10
|
+
const LightProfilePhoto = ({
|
|
11
|
+
profileImageUrl,
|
|
12
|
+
style,
|
|
13
|
+
size: _size,
|
|
14
|
+
borderColor,
|
|
15
|
+
borderWidth = 0,
|
|
16
|
+
optimize = true,
|
|
17
|
+
}: {
|
|
18
|
+
profileImageUrl: string;
|
|
19
|
+
style?: StyleProp<Omit<ViewStyle, 'borderWidth' | 'borderColor'>>;
|
|
20
|
+
size?: number;
|
|
21
|
+
borderWidth?: number;
|
|
22
|
+
borderColor?: string;
|
|
23
|
+
optimize?: boolean;
|
|
24
|
+
}) => {
|
|
25
|
+
const size = _size || 56;
|
|
26
|
+
return (
|
|
27
|
+
<View
|
|
28
|
+
key={profileImageUrl}
|
|
29
|
+
style={[
|
|
30
|
+
{
|
|
31
|
+
alignItems: 'center',
|
|
32
|
+
justifyContent: 'center',
|
|
33
|
+
},
|
|
34
|
+
style,
|
|
35
|
+
{
|
|
36
|
+
width: size,
|
|
37
|
+
height: size,
|
|
38
|
+
borderRadius: 9999,
|
|
39
|
+
borderWidth: 0,
|
|
40
|
+
},
|
|
41
|
+
]}
|
|
42
|
+
>
|
|
43
|
+
{Img.render(
|
|
44
|
+
is.notEmptyString(profileImageUrl)
|
|
45
|
+
? optimize
|
|
46
|
+
? appendImageSizeQueryParams({ url: profileImageUrl, desiredWidth: size })
|
|
47
|
+
: profileImageUrl
|
|
48
|
+
: defaultImage,
|
|
49
|
+
{
|
|
50
|
+
width: size,
|
|
51
|
+
height: size,
|
|
52
|
+
style: { borderWidth, borderColor, borderRadius: 999 },
|
|
53
|
+
},
|
|
54
|
+
)}
|
|
55
|
+
</View>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export { LightProfilePhoto };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { toKoreanNumberUnitString } from '@teamturing/utils';
|
|
2
|
+
import type { ImageSourcePropType, ColorValue } from 'react-native';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import { palette, spacing } from '../../theme';
|
|
6
|
+
import { is, appendImageSizeQueryParams, applyOpacity } from '../../util';
|
|
7
|
+
import { Img } from '../Img';
|
|
8
|
+
import { RowCenter } from '../Layout';
|
|
9
|
+
import { Txt } from '../Txt';
|
|
10
|
+
|
|
11
|
+
type Props = {
|
|
12
|
+
count?: number;
|
|
13
|
+
imageUrls: (ImageSourcePropType | string)[];
|
|
14
|
+
stackDirection?: 'left' | 'right';
|
|
15
|
+
size?: number;
|
|
16
|
+
backgroundColor?: string;
|
|
17
|
+
showBorder?: boolean;
|
|
18
|
+
maxCircleCount?: number;
|
|
19
|
+
showsMoreCount?: boolean;
|
|
20
|
+
|
|
21
|
+
borderWidth?: number;
|
|
22
|
+
borderPadding?: number;
|
|
23
|
+
borderColor?: ColorValue;
|
|
24
|
+
resizeNetworkImage?: boolean;
|
|
25
|
+
imageBorderWidth?: number;
|
|
26
|
+
imageBorderColor?: ColorValue;
|
|
27
|
+
};
|
|
28
|
+
const ProfileImageGroup = ({
|
|
29
|
+
count: countProp,
|
|
30
|
+
imageUrls: _imageUrls,
|
|
31
|
+
stackDirection = 'right',
|
|
32
|
+
size = 36,
|
|
33
|
+
backgroundColor = palette.gray100,
|
|
34
|
+
showBorder = true,
|
|
35
|
+
maxCircleCount = 3,
|
|
36
|
+
showsMoreCount = true,
|
|
37
|
+
|
|
38
|
+
borderWidth = 1,
|
|
39
|
+
borderPadding = spacing[0.5],
|
|
40
|
+
borderColor = palette.gray200,
|
|
41
|
+
resizeNetworkImage = true,
|
|
42
|
+
imageBorderWidth = 2,
|
|
43
|
+
imageBorderColor = backgroundColor,
|
|
44
|
+
}: Props) => {
|
|
45
|
+
const isReverse = stackDirection === 'left';
|
|
46
|
+
const imageUrls = isReverse ? [..._imageUrls].reverse() : _imageUrls;
|
|
47
|
+
|
|
48
|
+
const totalCount = countProp ?? imageUrls.length;
|
|
49
|
+
const visibleProfileCount = Math.min(imageUrls.length, maxCircleCount);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<RowCenter
|
|
53
|
+
reverse={isReverse}
|
|
54
|
+
style={showBorder ? { borderRadius: 999, borderWidth: borderWidth, padding: borderPadding, borderColor } : {}}
|
|
55
|
+
>
|
|
56
|
+
{imageUrls.slice(0, maxCircleCount).map((url, index) =>
|
|
57
|
+
Img.render(
|
|
58
|
+
resizeNetworkImage && is.string(url) ? appendImageSizeQueryParams({ url, desiredWidth: size }) : url,
|
|
59
|
+
{
|
|
60
|
+
key: index,
|
|
61
|
+
width: size,
|
|
62
|
+
height: size,
|
|
63
|
+
style: [
|
|
64
|
+
{
|
|
65
|
+
borderColor: imageBorderColor,
|
|
66
|
+
borderRadius: 999,
|
|
67
|
+
borderWidth: imageBorderWidth,
|
|
68
|
+
},
|
|
69
|
+
stackDirection === 'right'
|
|
70
|
+
? { marginLeft: index !== 0 ? -size / 2 : 0 }
|
|
71
|
+
: { marginRight: index !== 0 ? -size / 2 : 0 },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
),
|
|
75
|
+
)}
|
|
76
|
+
{showsMoreCount && totalCount > visibleProfileCount ? (
|
|
77
|
+
<View
|
|
78
|
+
style={[
|
|
79
|
+
{
|
|
80
|
+
width: size - 4,
|
|
81
|
+
height: size - 4,
|
|
82
|
+
position: 'absolute',
|
|
83
|
+
backgroundColor: applyOpacity(palette.black, 60),
|
|
84
|
+
borderRadius: 999,
|
|
85
|
+
alignItems: 'center',
|
|
86
|
+
justifyContent: 'center',
|
|
87
|
+
},
|
|
88
|
+
stackDirection === 'right' ? { right: spacing[showBorder ? 1 : 0] } : { left: spacing[showBorder ? 1 : 0] },
|
|
89
|
+
]}
|
|
90
|
+
>
|
|
91
|
+
{Txt.XXS.Bold.White.render(`+${toKoreanNumberUnitString(totalCount - (maxCircleCount - 1))}`)}
|
|
92
|
+
</View>
|
|
93
|
+
) : null}
|
|
94
|
+
</RowCenter>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export { ProfileImageGroup };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import { type StyleProp, type ViewStyle, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { palette } from '../../theme';
|
|
5
|
+
import { is } from '../../util';
|
|
6
|
+
import { Icon } from '../Icon';
|
|
7
|
+
import { Touch } from '../Pressable';
|
|
8
|
+
|
|
9
|
+
import { LightProfilePhoto } from './LightProfilePhoto';
|
|
10
|
+
|
|
11
|
+
const defaultLength = 90;
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
style?: StyleProp<ViewStyle>;
|
|
15
|
+
onPress?: () => void;
|
|
16
|
+
showIcon?: boolean;
|
|
17
|
+
pressable?: boolean;
|
|
18
|
+
length?: number;
|
|
19
|
+
testID?: string;
|
|
20
|
+
profileImageUrl?: string;
|
|
21
|
+
};
|
|
22
|
+
const ProfilePhoto = ({
|
|
23
|
+
style,
|
|
24
|
+
onPress,
|
|
25
|
+
showIcon,
|
|
26
|
+
pressable = false,
|
|
27
|
+
length: _length,
|
|
28
|
+
testID,
|
|
29
|
+
profileImageUrl,
|
|
30
|
+
}: Props): ReactElement => {
|
|
31
|
+
const length = is.number(_length) ? _length : defaultLength;
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<View
|
|
35
|
+
style={[
|
|
36
|
+
style,
|
|
37
|
+
{
|
|
38
|
+
justifyContent: 'center',
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
width: length,
|
|
41
|
+
height: length,
|
|
42
|
+
},
|
|
43
|
+
]}
|
|
44
|
+
>
|
|
45
|
+
<Touch
|
|
46
|
+
testID={testID || 'profile_photo_button'}
|
|
47
|
+
style={{
|
|
48
|
+
borderRadius: 9999,
|
|
49
|
+
width: '100%',
|
|
50
|
+
height: '100%',
|
|
51
|
+
}}
|
|
52
|
+
onPress={onPress}
|
|
53
|
+
disabled={!pressable}
|
|
54
|
+
>
|
|
55
|
+
<LightProfilePhoto profileImageUrl={profileImageUrl || ''} size={length} />
|
|
56
|
+
{showIcon ? (
|
|
57
|
+
<View
|
|
58
|
+
style={{
|
|
59
|
+
width: 32,
|
|
60
|
+
height: 32,
|
|
61
|
+
borderRadius: 16,
|
|
62
|
+
backgroundColor: palette.gray200,
|
|
63
|
+
alignItems: 'center',
|
|
64
|
+
justifyContent: 'center',
|
|
65
|
+
borderWidth: 2,
|
|
66
|
+
borderColor: palette.white,
|
|
67
|
+
position: 'absolute',
|
|
68
|
+
right: -6,
|
|
69
|
+
bottom: -6,
|
|
70
|
+
}}
|
|
71
|
+
pointerEvents={'none'}
|
|
72
|
+
>
|
|
73
|
+
<Icon name={'pen'} size={16} />
|
|
74
|
+
</View>
|
|
75
|
+
) : null}
|
|
76
|
+
</Touch>
|
|
77
|
+
</View>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export { ProfilePhoto };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { memo } from 'react';
|
|
2
|
+
import type { ColorValue } from 'react-native';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { Circle, Defs, RadialGradient, Stop, Svg } from 'react-native-svg';
|
|
5
|
+
|
|
6
|
+
import { is } from '../../util';
|
|
7
|
+
|
|
8
|
+
import { LightProfilePhoto } from './LightProfilePhoto';
|
|
9
|
+
|
|
10
|
+
const ProfilePhotoWithBorderGradient = memo(
|
|
11
|
+
({
|
|
12
|
+
profileImageUrl,
|
|
13
|
+
size,
|
|
14
|
+
borderGradientColor,
|
|
15
|
+
optimize,
|
|
16
|
+
}: {
|
|
17
|
+
profileImageUrl: string;
|
|
18
|
+
size: number;
|
|
19
|
+
borderGradientColor?: ColorValue;
|
|
20
|
+
optimize?: boolean;
|
|
21
|
+
}) => (
|
|
22
|
+
<View>
|
|
23
|
+
<LightProfilePhoto profileImageUrl={profileImageUrl} size={size} optimize={optimize} />
|
|
24
|
+
{is.string(borderGradientColor) ? (
|
|
25
|
+
<Svg height={size} width={size} style={{ position: 'absolute' }}>
|
|
26
|
+
<Defs>
|
|
27
|
+
<RadialGradient id={'grad'} cx={size / 2} cy={size / 2} gradientUnits={'userSpaceOnUse'}>
|
|
28
|
+
<Stop offset={'0.66'} stopColor={borderGradientColor} stopOpacity={0} />
|
|
29
|
+
<Stop offset={'1'} stopColor={borderGradientColor} stopOpacity={1} />
|
|
30
|
+
</RadialGradient>
|
|
31
|
+
</Defs>
|
|
32
|
+
<Circle r={size / 2 + 1} cx={size / 2} cy={size / 2} fill={'url(#grad)'} />
|
|
33
|
+
</Svg>
|
|
34
|
+
) : null}
|
|
35
|
+
</View>
|
|
36
|
+
),
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
export { ProfilePhotoWithBorderGradient };
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/component/index.ts
CHANGED
|
@@ -50,9 +50,9 @@ export * from './Img';
|
|
|
50
50
|
export * from './Icon';
|
|
51
51
|
export * from './Header';
|
|
52
52
|
export * from './FloatingRoundChip';
|
|
53
|
-
|
|
54
53
|
export * from './dialog';
|
|
55
54
|
export * from './Btn';
|
|
56
55
|
export * from './Box';
|
|
57
56
|
export * from './Banner';
|
|
58
57
|
export * from './Animation';
|
|
58
|
+
export * from './ProfilePhoto';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { appendImageSizeQueryParams } from './WebImageUrlEnricher';
|
|
2
|
+
|
|
3
|
+
describe('appendImageSizeQueryParams', () => {
|
|
4
|
+
it('url이 올바른 경우', () => {
|
|
5
|
+
expect(appendImageSizeQueryParams({ url: 'http://test.jpg', desiredWidth: 100 })).toBe('http://test.jpg?w=256');
|
|
6
|
+
expect(appendImageSizeQueryParams({ url: 'http://test.jpg?x=1&t=5', desiredWidth: 100 })).toBe(
|
|
7
|
+
'http://test.jpg?x=1&t=5&w=256',
|
|
8
|
+
);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('url이 올바르지 않은 경우', () => {
|
|
12
|
+
expect(appendImageSizeQueryParams({ url: 1 as any, desiredWidth: 100 })).toBe(1);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Dimensions } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import { is } from './is';
|
|
4
|
+
|
|
5
|
+
const scaleFactor = () => Math.min(2, Dimensions.get('window').scale);
|
|
6
|
+
export type ImageCrop = { l: number; r: number; t: number; b: number };
|
|
7
|
+
export function appendImageSizeQueryParams({
|
|
8
|
+
url,
|
|
9
|
+
desiredWidth,
|
|
10
|
+
crop,
|
|
11
|
+
}: {
|
|
12
|
+
url: string;
|
|
13
|
+
desiredWidth: number;
|
|
14
|
+
crop?: ImageCrop;
|
|
15
|
+
}): string {
|
|
16
|
+
if (!is.notEmptyString(url) || !url.startsWith('http')) {
|
|
17
|
+
return url;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const w = Math.max(128, Math.floor((desiredWidth * scaleFactor() + 128 - 1) / 128) * 128);
|
|
21
|
+
|
|
22
|
+
const cropQueryStrings = Object.entries(crop || {}).map(([key, value]) => `${key}=${Math.round(value)}`);
|
|
23
|
+
|
|
24
|
+
const queryString = [`w=${w}`, ...cropQueryStrings].join('&');
|
|
25
|
+
|
|
26
|
+
if (url.includes('?')) {
|
|
27
|
+
return `${url}&${queryString}`;
|
|
28
|
+
} else {
|
|
29
|
+
return `${url}?${queryString}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/util/index.ts
CHANGED