ferns-ui 0.14.0 → 0.15.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/dist/Avatar.d.ts CHANGED
@@ -23,6 +23,19 @@ interface AvatarProps {
23
23
  * The URL of the user's image.
24
24
  */
25
25
  src?: string;
26
+ /**
27
+ * The fit for the image within the Avatar: "cover" | "contain" | "none".
28
+ * Default is undefined. See Image.tsx for more info
29
+ */
30
+ imageFit?: "cover" | "contain" | "none";
31
+ /**
32
+ * Allow user to edit the image of the avatar
33
+ */
34
+ editAvatarImage?: boolean;
35
+ /**
36
+ * Function to handle the avatar image edit
37
+ */
38
+ onChange?: (val: any) => void;
26
39
  }
27
40
  export declare const Avatar: (props: AvatarProps) => React.ReactElement;
28
41
  export {};
package/dist/Avatar.js CHANGED
@@ -1,6 +1,9 @@
1
+ import { launchImageLibraryAsync, MediaTypeOptions } from "expo-image-picker";
1
2
  import React, { useState } from "react";
2
3
  import { Image, Text, View } from "react-native";
3
4
  import { Box } from "./Box";
5
+ import { iconSizeToNumber } from "./Common";
6
+ import { Icon } from "./Icon";
4
7
  import { Unifier } from "./Unifier";
5
8
  const sizes = {
6
9
  xs: 24,
@@ -10,9 +13,10 @@ const sizes = {
10
13
  xl: 120,
11
14
  };
12
15
  export const Avatar = (props) => {
13
- var _a;
16
+ var _a, _b;
14
17
  const [isImageLoaded, setIsImageLoaded] = useState(true);
15
- const { name, initials, outline, size = "md", src } = props;
18
+ const [src, setSrc] = useState((_a = props.src) !== null && _a !== void 0 ? _a : undefined);
19
+ const { name, initials, outline, size = "md", imageFit = "contain", editAvatarImage, onChange, } = props;
16
20
  const width = sizes[size];
17
21
  const height = sizes[size];
18
22
  const radius = sizes[size] / 2;
@@ -24,28 +28,44 @@ export const Avatar = (props) => {
24
28
  .join("")
25
29
  .toLocaleUpperCase();
26
30
  const handleImageError = () => setIsImageLoaded(false);
27
- return (React.createElement(Box, { border: outline ? "white" : undefined, height: height, overflow: "hidden", position: "relative", rounding: "circle", width: width }, src && isImageLoaded ? (
28
- // TODO: Make our Image component rounding work so that we can use it for Avatar. Currently it creates an
29
- // unrounded box around the Image.
30
- React.createElement(Image, { resizeMode: "contain", source: { uri: src, cache: "force-cache" }, style: {
31
- borderRadius: radius,
32
- height,
33
- width,
34
- display: "flex",
35
- alignItems: "center",
36
- justifyContent: "center",
37
- overflow: "hidden",
38
- }, onError: handleImageError })) : (React.createElement(View, { style: {
39
- height,
40
- width,
41
- borderRadius: radius,
42
- display: "flex",
43
- alignItems: "center",
44
- justifyContent: "center",
45
- backgroundColor: props.backgroundColor
46
- ? Unifier.theme[props.backgroundColor]
47
- : Unifier.theme.gray,
48
- } },
49
- React.createElement(Text, { style: { fontSize, color: (_a = props.textColor) !== null && _a !== void 0 ? _a : Unifier.theme.darkGray } }, computedInitials)))));
31
+ const pickImage = async () => {
32
+ // TODO: Add permission request to use camera to take a picture
33
+ const result = await launchImageLibraryAsync({
34
+ mediaTypes: MediaTypeOptions.Images,
35
+ allowsEditing: true,
36
+ });
37
+ if (!result.cancelled) {
38
+ setSrc(result.uri);
39
+ if (onChange) {
40
+ onChange(result);
41
+ }
42
+ }
43
+ };
44
+ return (React.createElement(Box, { border: outline ? "white" : undefined, height: height, overflow: "hidden", position: "relative", rounding: "circle", width: editAvatarImage ? width + iconSizeToNumber(size) : width },
45
+ editAvatarImage && (React.createElement(Box, { bottom: true, position: "absolute", right: true, zIndex: 5, onClick: pickImage },
46
+ React.createElement(Icon, { color: "black", name: "edit", size: size }))),
47
+ src && isImageLoaded ? (
48
+ // TODO: Make our Image component rounding work so that we can use it for Avatar. Currently it creates an
49
+ // unrounded box around the Image.
50
+ React.createElement(Image, { resizeMode: imageFit, source: { uri: src, cache: "force-cache" }, style: {
51
+ borderRadius: radius,
52
+ height,
53
+ width,
54
+ display: "flex",
55
+ alignItems: "center",
56
+ justifyContent: "center",
57
+ overflow: "hidden",
58
+ }, onError: handleImageError })) : (React.createElement(View, { style: {
59
+ height,
60
+ width,
61
+ borderRadius: radius,
62
+ display: "flex",
63
+ alignItems: "center",
64
+ justifyContent: "center",
65
+ backgroundColor: props.backgroundColor
66
+ ? Unifier.theme[props.backgroundColor]
67
+ : Unifier.theme.gray,
68
+ } },
69
+ React.createElement(Text, { style: { fontSize, color: (_b = props.textColor) !== null && _b !== void 0 ? _b : Unifier.theme.darkGray } }, computedInitials)))));
50
70
  };
51
71
  //# sourceMappingURL=Avatar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../src/Avatar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../src/Avatar.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ferns-ui",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "main": "dist/index.js",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
@@ -145,6 +145,7 @@
145
145
  "eslint-plugin-unused-imports": "2.0.0",
146
146
  "expo-font": "^10.0.5",
147
147
  "expo-haptics": "~11.3.0",
148
+ "expo-image-picker": "^13.3.1",
148
149
  "lodash": "^4.17.21",
149
150
  "mixpanel-browser": "^2.38.0",
150
151
  "moment-timezone": "^0.5.35",
@@ -176,13 +177,14 @@
176
177
  "@react-native-picker/picker": "2.4.4",
177
178
  "expo-font": "^10.0.5",
178
179
  "expo-haptics": "~11.3.0",
180
+ "expo-image-picker": "^13.3.1",
179
181
  "lodash": "^4.17.21",
180
182
  "mixpanel-browser": "^2.38.0",
181
183
  "moment-timezone": "^0.5.35",
182
184
  "react": "^18.2.0",
183
185
  "react-app-polyfill": "^3.0.0",
184
- "react-dev-utils": "^12.0.1",
185
186
  "react-datetime-picker": "^4.0.1",
187
+ "react-dev-utils": "^12.0.1",
186
188
  "react-dom": "18.2.0",
187
189
  "react-native": "0.69.4",
188
190
  "react-native-calendars": "^1.1288.2",
package/src/Avatar.tsx CHANGED
@@ -1,8 +1,10 @@
1
+ import {launchImageLibraryAsync, MediaTypeOptions} from "expo-image-picker";
1
2
  import React, {useState} from "react";
2
- import {Image, Text, View} from "react-native";
3
+ import {Image, ImageResizeMode, Text, View} from "react-native";
3
4
 
4
5
  import {Box} from "./Box";
5
- import {AllColors} from "./Common";
6
+ import {AllColors, iconSizeToNumber} from "./Common";
7
+ import {Icon} from "./Icon";
6
8
  import {Unifier} from "./Unifier";
7
9
 
8
10
  const sizes = {
@@ -38,11 +40,33 @@ interface AvatarProps {
38
40
  * The URL of the user's image.
39
41
  */
40
42
  src?: string;
43
+ /**
44
+ * The fit for the image within the Avatar: "cover" | "contain" | "none".
45
+ * Default is undefined. See Image.tsx for more info
46
+ */
47
+ imageFit?: "cover" | "contain" | "none";
48
+ /**
49
+ * Allow user to edit the image of the avatar
50
+ */
51
+ editAvatarImage?: boolean;
52
+ /**
53
+ * Function to handle the avatar image edit
54
+ */
55
+ onChange?: (val: any) => void;
41
56
  }
42
57
 
43
58
  export const Avatar = (props: AvatarProps): React.ReactElement => {
44
59
  const [isImageLoaded, setIsImageLoaded] = useState(true);
45
- const {name, initials, outline, size = "md", src} = props;
60
+ const [src, setSrc] = useState(props.src ?? undefined);
61
+ const {
62
+ name,
63
+ initials,
64
+ outline,
65
+ size = "md",
66
+ imageFit = "contain",
67
+ editAvatarImage,
68
+ onChange,
69
+ } = props;
46
70
  const width = sizes[size];
47
71
  const height = sizes[size];
48
72
  const radius = sizes[size] / 2;
@@ -57,6 +81,22 @@ export const Avatar = (props: AvatarProps): React.ReactElement => {
57
81
  .toLocaleUpperCase();
58
82
 
59
83
  const handleImageError = () => setIsImageLoaded(false);
84
+
85
+ const pickImage = async () => {
86
+ // TODO: Add permission request to use camera to take a picture
87
+ const result = await launchImageLibraryAsync({
88
+ mediaTypes: MediaTypeOptions.Images,
89
+ allowsEditing: true,
90
+ });
91
+
92
+ if (!result.cancelled) {
93
+ setSrc(result.uri);
94
+ if (onChange) {
95
+ onChange(result);
96
+ }
97
+ }
98
+ };
99
+
60
100
  return (
61
101
  <Box
62
102
  border={outline ? "white" : undefined}
@@ -64,13 +104,18 @@ export const Avatar = (props: AvatarProps): React.ReactElement => {
64
104
  overflow="hidden"
65
105
  position="relative"
66
106
  rounding="circle"
67
- width={width}
107
+ width={editAvatarImage ? width + iconSizeToNumber(size) : width}
68
108
  >
109
+ {editAvatarImage && (
110
+ <Box bottom position="absolute" right zIndex={5} onClick={pickImage}>
111
+ <Icon color="black" name="edit" size={size} />
112
+ </Box>
113
+ )}
69
114
  {src && isImageLoaded ? (
70
115
  // TODO: Make our Image component rounding work so that we can use it for Avatar. Currently it creates an
71
- // unrounded box around the Image.
116
+ // unrounded box around the Image.
72
117
  <Image
73
- resizeMode="contain"
118
+ resizeMode={imageFit as ImageResizeMode}
74
119
  source={{uri: src, cache: "force-cache"}}
75
120
  style={{
76
121
  borderRadius: radius,