@fountain-ui/lab 2.0.0-beta.50 → 2.0.0-beta.52

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.
Files changed (39) hide show
  1. package/build/commonjs/BottomSheet/BottomSheetNative.js +6 -4
  2. package/build/commonjs/BottomSheet/BottomSheetNative.js.map +1 -1
  3. package/build/commonjs/BottomSheet/BottomSheetProps.js.map +1 -1
  4. package/build/commonjs/BottomSheet/BottomSheetWeb.js +6 -3
  5. package/build/commonjs/BottomSheet/BottomSheetWeb.js.map +1 -1
  6. package/build/commonjs/ComicViewer/ComicViewer.js +31 -65
  7. package/build/commonjs/ComicViewer/ComicViewer.js.map +1 -1
  8. package/build/commonjs/ComicViewer/ComicViewerProps.js.map +1 -1
  9. package/build/commonjs/ComicViewer/ViewerItem.js +2 -0
  10. package/build/commonjs/ComicViewer/ViewerItem.js.map +1 -1
  11. package/build/commonjs/ComicViewer/index.js.map +1 -1
  12. package/build/commonjs/DateTimePicker/DateTimePicker.js +10 -1
  13. package/build/commonjs/DateTimePicker/DateTimePicker.js.map +1 -1
  14. package/build/module/BottomSheet/BottomSheetNative.js +6 -4
  15. package/build/module/BottomSheet/BottomSheetNative.js.map +1 -1
  16. package/build/module/BottomSheet/BottomSheetProps.js.map +1 -1
  17. package/build/module/BottomSheet/BottomSheetWeb.js +6 -3
  18. package/build/module/BottomSheet/BottomSheetWeb.js.map +1 -1
  19. package/build/module/ComicViewer/ComicViewer.js +31 -64
  20. package/build/module/ComicViewer/ComicViewer.js.map +1 -1
  21. package/build/module/ComicViewer/ComicViewerProps.js.map +1 -1
  22. package/build/module/ComicViewer/ViewerItem.js +2 -0
  23. package/build/module/ComicViewer/ViewerItem.js.map +1 -1
  24. package/build/module/ComicViewer/index.js.map +1 -1
  25. package/build/module/DateTimePicker/DateTimePicker.js +11 -2
  26. package/build/module/DateTimePicker/DateTimePicker.js.map +1 -1
  27. package/build/typescript/BottomSheet/BottomSheetProps.d.ts +10 -0
  28. package/build/typescript/ComicViewer/ComicViewerProps.d.ts +6 -6
  29. package/build/typescript/ComicViewer/ViewerItem.d.ts +4 -0
  30. package/build/typescript/ComicViewer/index.d.ts +1 -1
  31. package/package.json +2 -2
  32. package/src/BottomSheet/BottomSheetNative.tsx +5 -3
  33. package/src/BottomSheet/BottomSheetProps.ts +12 -0
  34. package/src/BottomSheet/BottomSheetWeb.tsx +4 -1
  35. package/src/ComicViewer/ComicViewer.tsx +39 -72
  36. package/src/ComicViewer/ComicViewerProps.ts +7 -7
  37. package/src/ComicViewer/ViewerItem.tsx +7 -0
  38. package/src/ComicViewer/index.ts +1 -1
  39. package/src/DateTimePicker/DateTimePicker.tsx +9 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/lab",
3
- "version": "2.0.0-beta.50",
3
+ "version": "2.0.0-beta.52",
4
4
  "private": false,
5
5
  "author": "Fountain-UI Team",
6
6
  "description": "Incubator for Fountain-UI React components.",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "e88aa7213f667ee522d4c1e7d684d5f935df6f2a"
73
+ "gitHead": "ba0faed7f492a6b00b7614c06f23f2fab290e01e"
74
74
  }
@@ -23,6 +23,8 @@ export default function BottomSheet(props: BottomSheetProps) {
23
23
  maxHeightNormalizedRatio = 0.9,
24
24
  onChange,
25
25
  snapPoints = [],
26
+ disableDefaultBackgroundColor = false,
27
+ disableDefaultShadow = false,
26
28
  } = props;
27
29
 
28
30
  const indexRef = React.useRef<number>(-1);
@@ -62,14 +64,14 @@ export default function BottomSheet(props: BottomSheetProps) {
62
64
  const shadow = theme.shadow[12];
63
65
  const modalStyle = {
64
66
  backgroundColor: '#ffffff00',
65
- ...Platform.select<object>({
67
+ ...(disableDefaultShadow ? {} : Platform.select<object>({
66
68
  android: shadow?.elevation,
67
69
  ios: shadow?.shadow,
68
70
  web: shadow?.boxShadow,
69
- }),
71
+ })),
70
72
  };
71
73
  const backgroundStyle = {
72
- backgroundColor: theme.palette.paper.default,
74
+ backgroundColor: disableDefaultBackgroundColor ? '#ffffff00' : theme.palette.paper.default,
73
75
  };
74
76
  const contentWrapperStyle = {
75
77
  flex: 1,
@@ -49,4 +49,16 @@ export default interface BottomSheetProps extends ComponentProps<{
49
49
  * @default []
50
50
  */
51
51
  snapPoints?: Array<number | string>;
52
+
53
+ /**
54
+ * Disable default backgroundColor.
55
+ * @default false
56
+ */
57
+ disableDefaultBackgroundColor?: boolean;
58
+
59
+ /**
60
+ * Disable default shadow.
61
+ * @default false
62
+ */
63
+ disableDefaultShadow?: boolean;
52
64
  }> {}
@@ -40,6 +40,8 @@ export default function BottomSheet(props: BottomSheetProps) {
40
40
  maxHeightNormalizedRatio = 0.9,
41
41
  onChange,
42
42
  snapPoints = [],
43
+ disableDefaultBackgroundColor = false,
44
+ disableDefaultShadow = false,
43
45
  } = props;
44
46
 
45
47
  const styles = useStyles();
@@ -79,8 +81,9 @@ export default function BottomSheet(props: BottomSheetProps) {
79
81
  translateY={translateY}
80
82
  >
81
83
  <Paper
82
- elevation={12}
84
+ elevation={disableDefaultShadow ? 0 : 12}
83
85
  style={paperStyles}
86
+ colorValue={disableDefaultBackgroundColor ? '#ffffff00' : undefined}
84
87
  >
85
88
  <ScrollView
86
89
  onContentSizeChange={handleContentSizeChange}
@@ -1,8 +1,7 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { FlatList, ListRenderItem, NativeScrollEvent, NativeSyntheticEvent, ViewToken } from 'react-native';
3
3
  import * as R from 'ramda';
4
- import { useDebounce } from '@fountain-ui/core';
5
- import { default as ComicViewerProps, Dimension } from './ComicViewerProps';
4
+ import { default as ComicViewerProps, Dimension, IntrinsicImage } from './ComicViewerProps';
6
5
  import ViewerItem from './ViewerItem';
7
6
  import FastScroll from './FastScroll';
8
7
 
@@ -17,23 +16,28 @@ interface UrlState {
17
16
  }
18
17
 
19
18
  interface ImageState {
20
- urlState?: UrlState;
21
- isNewUrlIncoming: boolean;
19
+ urlState: UrlState;
22
20
  totalErrorCount: number;
23
21
  dimension: Dimension;
22
+ tryRenderingMillis: number;
24
23
  }
25
24
 
26
25
  interface ItemState {
27
26
  index: number;
28
27
  url?: string;
28
+ imageKey: string;
29
29
  reloadButtonVisible: boolean;
30
30
  dimension: Dimension;
31
31
  }
32
32
 
33
- const createInitialImageState = (dimension: Dimension): ImageState => ({
34
- isNewUrlIncoming: false,
33
+ const createInitialImageState = (image: IntrinsicImage): ImageState => ({
35
34
  totalErrorCount: 0,
36
- dimension,
35
+ dimension: image.dimension,
36
+ tryRenderingMillis: 0,
37
+ urlState: {
38
+ url: image.url,
39
+ validity: 'unknown',
40
+ },
37
41
  });
38
42
 
39
43
  const mapImageStateToItemState = (
@@ -43,11 +47,12 @@ const mapImageStateToItemState = (
43
47
  ): ItemState => ({
44
48
  index,
45
49
  url: imageState.urlState?.url,
50
+ imageKey: `${imageState.tryRenderingMillis}-${index}`,
46
51
  reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,
47
52
  dimension: imageState.dimension,
48
53
  });
49
54
 
50
- const mapIndexed = R.addIndex<Dimension>(R.map);
55
+ const mapIndexed = R.addIndex<IntrinsicImage>(R.map);
51
56
 
52
57
  const MAXIMUM_WIDTH = 720;
53
58
 
@@ -58,11 +63,10 @@ export default function ComicViewer(props: ComicViewerProps) {
58
63
  debounceMillis = 100,
59
64
  autoHandleErrorCount = 3,
60
65
  fastScrollOptions,
61
- getUrlByIndex,
62
66
  initialNumToRender = 1,
63
67
  initialScrollPercentage = 0,
64
68
  itemVisiblePercentThreshold = 0,
65
- intrinsicDimensions,
69
+ intrinsicImages,
66
70
  maxContentWidth = MAXIMUM_WIDTH,
67
71
  onItemPress,
68
72
  onScroll,
@@ -82,7 +86,8 @@ export default function ComicViewer(props: ComicViewerProps) {
82
86
 
83
87
  const actualImageWidth = Math.min(viewportWidth, maxContentWidth);
84
88
 
85
- const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);
89
+ const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicImages), []);
90
+
86
91
  const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);
87
92
 
88
93
  const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {
@@ -96,14 +101,14 @@ export default function ComicViewer(props: ComicViewerProps) {
96
101
  });
97
102
 
98
103
  const renderedDimensions = useMemo<Array<Dimension>>(() => {
99
- return mapIndexed((intrinsicDimension, index) => {
100
- const height = (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width + (index === 0 ? invisiblePaddingTop : 0);
104
+ return mapIndexed((intrinsicImage, index) => {
105
+ const height = (intrinsicImage.dimension.height * actualImageWidth) / intrinsicImage.dimension.width + (index === 0 ? invisiblePaddingTop : 0);
101
106
 
102
107
  return {
103
108
  width: actualImageWidth,
104
109
  height: isNaN(height) ? 0 : height,
105
110
  };
106
- }, intrinsicDimensions);
111
+ }, intrinsicImages);
107
112
  }, [actualImageWidth]);
108
113
 
109
114
  const layoutFromDimensions = useCallback(() => {
@@ -142,60 +147,31 @@ export default function ComicViewer(props: ComicViewerProps) {
142
147
  });
143
148
  };
144
149
 
145
- const loadUrlByIndex = async (indexes: number[]) => {
146
- const filteredIndexes = R.filter(index => {
147
- const state = imageStatesRef.current[index];
148
-
149
- return !state.isNewUrlIncoming
150
- && (R.isNil(state.urlState) || state.urlState?.validity === 'invalid');
151
- }, indexes);
150
+ const updateItems = (indexes: number[]) => {
151
+ const tryRenderingMillis = new Date().getTime();
152
152
 
153
153
  updateImageState((imageState, i) => {
154
- return R.includes(i, filteredIndexes)
155
- ? { ...imageState, isNewUrlIncoming: true }
156
- : imageState;
157
- });
158
-
159
- try {
160
- const urls = await getUrlByIndex(filteredIndexes);
161
-
162
- updateImageState((imageState, i) => {
163
- const newUrl = urls?.get(i);
164
- const urlState = imageState.urlState;
165
-
166
- if (newUrl !== undefined && urlState?.validity !== 'valid') {
167
- return {
168
- ...imageState,
169
- urlState: {
170
- url: newUrl,
171
- validity: 'unknown',
172
- },
173
- };
174
- }
154
+ const urlState = imageState.urlState;
155
+ const shouldRerender = R.includes(i, R.defaultTo([], indexes));
156
+
157
+ if (shouldRerender && urlState?.validity !== 'valid') {
158
+ return {
159
+ ...imageState,
160
+ tryRenderingMillis,
161
+ };
162
+ }
175
163
 
176
- return imageState;
177
- });
178
- } catch (e) {
179
- // ignore
180
- } finally {
181
- updateImageState((imageState, i) => {
182
- return R.includes(i, filteredIndexes)
183
- ? { ...imageState, isNewUrlIncoming: false }
184
- : imageState;
185
- });
186
- }
164
+ return imageState;
165
+ });
187
166
  };
188
167
 
189
- const loadMaybeLoadableItems = () => {
168
+ const renderMaybeLoadableItems = () => {
190
169
  const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
191
170
  const affectedIndexes = R.range(startIndex, endIndex);
192
171
 
193
- loadUrlByIndex(affectedIndexes);
172
+ updateItems(affectedIndexes);
194
173
  };
195
174
 
196
- const ignoreDebounce = useRef(true);
197
- const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);
198
-
199
175
  const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {
200
176
  const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);
201
177
 
@@ -211,14 +187,7 @@ export default function ComicViewer(props: ComicViewerProps) {
211
187
 
212
188
  maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];
213
189
 
214
- if (ignoreDebounce.current) {
215
- loadMaybeLoadableItems();
216
-
217
- ignoreDebounce.current = false;
218
- return;
219
- }
220
-
221
- loadItemsDebounce();
190
+ renderMaybeLoadableItems();
222
191
  });
223
192
 
224
193
  const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {
@@ -241,7 +210,7 @@ export default function ComicViewer(props: ComicViewerProps) {
241
210
  updateImageState((imageState, i) => {
242
211
  const urlState = imageState.urlState;
243
212
 
244
- if (i === index && urlState !== undefined) {
213
+ if (i === index) {
245
214
  return {
246
215
  ...imageState,
247
216
  totalErrorCount: imageState.totalErrorCount + 1,
@@ -261,17 +230,14 @@ export default function ComicViewer(props: ComicViewerProps) {
261
230
 
262
231
  const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
263
232
  if (index >= startIndex || index < endIndex) {
264
- loadItemsDebounce();
233
+ renderMaybeLoadableItems();
265
234
  }
266
235
  };
267
236
 
268
237
  const handleReloadPress = () => {
269
238
  onReloadPress && onReloadPress();
270
239
 
271
- const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
272
- if (index >= startIndex || index < endIndex) {
273
- loadUrlByIndex([index]);
274
- }
240
+ updateItems([index]);
275
241
  };
276
242
 
277
243
  const onLoad = () => {
@@ -299,6 +265,7 @@ export default function ComicViewer(props: ComicViewerProps) {
299
265
  onPress={onItemPress}
300
266
  onReloadPress={handleReloadPress}
301
267
  url={item.url}
268
+ imageKey={item.imageKey}
302
269
  invisiblePaddingTop={index === 0 ? invisiblePaddingTop : 0}
303
270
  width={renderedDimensions[index]?.width ?? 0}
304
271
  height={renderedDimensions[index]?.height ?? 0}
@@ -8,6 +8,11 @@ export interface Dimension {
8
8
  height: number;
9
9
  }
10
10
 
11
+ export interface IntrinsicImage {
12
+ dimension: Dimension;
13
+ url: string;
14
+ }
15
+
11
16
  export default interface ComicViewerProps extends ComponentProps <{
12
17
  /**
13
18
  * Delay Time to call the error handler.
@@ -41,9 +46,9 @@ export default interface ComicViewerProps extends ComponentProps <{
41
46
  itemVisiblePercentThreshold?: number;
42
47
 
43
48
  /**
44
- * Dimensions of each Image considering viewport.
49
+ * Dimensions and url info of each Image considering viewport.
45
50
  */
46
- intrinsicDimensions: Array<Dimension>;
51
+ intrinsicImages: Array<IntrinsicImage>;
47
52
 
48
53
  /**
49
54
  * Need invisible paddingTop viewer vertically expanded.
@@ -73,11 +78,6 @@ export default interface ComicViewerProps extends ComponentProps <{
73
78
  */
74
79
  fastScrollOptions: FastScrollOptions;
75
80
 
76
- /**
77
- * Get contents urls by indexes.
78
- */
79
- getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;
80
-
81
81
  /**
82
82
  * Handle scroll event.
83
83
  * @param event Scroll event.
@@ -50,6 +50,11 @@ export interface ViewerItemProps {
50
50
  * @default false
51
51
  */
52
52
  reloadButtonVisible?: boolean;
53
+
54
+ /**
55
+ * FuiImage key for trigger image rerender.
56
+ */
57
+ imageKey: string;
53
58
  }
54
59
 
55
60
  export default function ViewerItem(props: ViewerItemProps) {
@@ -57,6 +62,7 @@ export default function ViewerItem(props: ViewerItemProps) {
57
62
  height,
58
63
  url,
59
64
  width,
65
+ imageKey,
60
66
  invisiblePaddingTop,
61
67
  onError,
62
68
  onLoad,
@@ -89,6 +95,7 @@ export default function ViewerItem(props: ViewerItemProps) {
89
95
  <TouchableWithoutFeedback onPress={onPress}>
90
96
  <View style={styles.view}>
91
97
  <FuiImage
98
+ key={imageKey}
92
99
  cache={'web'}
93
100
  disableDrag={true}
94
101
  disableLongClick={true}
@@ -1,5 +1,5 @@
1
1
  export { default } from './ComicViewer';
2
- export type { Dimension, default as ComicViewerProps } from './ComicViewerProps';
2
+ export type { Dimension, IntrinsicImage, default as ComicViewerProps } from './ComicViewerProps';
3
3
  export type { ViewerItemProps } from './ViewerItem';
4
4
  export type {
5
5
  AbsolutePosition,
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { format } from 'date-fns';
3
3
  //@ts-ignore
4
4
  import { Calendar, LocaleConfig } from 'react-native-calendars';
5
- import { Button, Typography } from '@fountain-ui/core';
5
+ import { Button, createFontStyle, Typography } from '@fountain-ui/core';
6
6
  import { useTheme } from '@fountain-ui/styles';
7
7
  import YearPicker from './YearPicker';
8
8
  import { DateTimePickerContext } from './DateTimePickerProvider';
@@ -26,6 +26,8 @@ export default function DateTimePicker(props: DateTimePickerProps) {
26
26
 
27
27
  const theme = useTheme();
28
28
 
29
+ const textDayFontStyle = createFontStyle(theme, { selector: (typo) => typo.body2 });
30
+
29
31
  const [yearPickerVisible, setYearPickerVisible] = React.useState(false);
30
32
  const { locales } = useDateTimePicker();
31
33
 
@@ -86,6 +88,12 @@ export default function DateTimePicker(props: DateTimePickerProps) {
86
88
  calendarBackground: theme.palette.paper.default,
87
89
  dayTextColor: theme.palette.text.primary,
88
90
  textDisabledColor: theme.palette.text.hint,
91
+ textDayFontFamily: textDayFontStyle.fontFamily,
92
+ textDayFontSize: textDayFontStyle.fontSize,
93
+ textDayFontWeight: textDayFontStyle.fontWeight,
94
+ textDayHeaderFontFamily: textDayFontStyle.fontFamily,
95
+ textDayHeaderFontSize: textDayFontStyle.fontSize,
96
+ textDayHeaderFontWeight: textDayFontStyle.fontWeight,
89
97
  }}
90
98
  />
91
99
  );