@swan-io/lake 2.7.3 → 2.7.5
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/package.json +1 -1
- package/src/components/FixedListView.d.ts +4 -1
- package/src/components/FixedListView.js +41 -34
- package/src/components/FixedListViewCells.d.ts +4 -2
- package/src/components/FixedListViewCells.js +4 -4
- package/src/components/LakeAlert.d.ts +1 -1
- package/src/components/LakeAlert.js +8 -2
- package/src/components/LakeCombobox.js +6 -2
- package/src/components/LakeTextInput.d.ts +4 -2
- package/src/components/LakeTextInput.js +5 -5
- package/src/hooks/useDisclosure.d.ts +1 -1
- package/src/hooks/useDisclosure.js +5 -2
package/package.json
CHANGED
|
@@ -65,9 +65,11 @@ export type FixedListViewProps<T, ExtraInfo> = {
|
|
|
65
65
|
data: T[];
|
|
66
66
|
keyExtractor: (item: T, index: number) => string;
|
|
67
67
|
highlightedRowId?: string;
|
|
68
|
+
headerBackgroundColor?: string;
|
|
68
69
|
headerHeight: number;
|
|
69
70
|
rowHeight: number;
|
|
70
71
|
rowVerticalSpacing: number;
|
|
72
|
+
horizontalPadding?: number;
|
|
71
73
|
extraInfo: ExtraInfo;
|
|
72
74
|
stickedToStartColumns?: ColumnConfig<T, ExtraInfo>[];
|
|
73
75
|
columns: ColumnConfig<T, ExtraInfo>[];
|
|
@@ -82,7 +84,8 @@ export type FixedListViewProps<T, ExtraInfo> = {
|
|
|
82
84
|
count: number;
|
|
83
85
|
};
|
|
84
86
|
};
|
|
85
|
-
export declare const
|
|
87
|
+
export declare const SCROLLBAR_RESERVED_SPACE = 20;
|
|
88
|
+
export declare const FixedListView: <T, ExtraInfo>({ data: originalData, mode, keyExtractor, highlightedRowId, rowHeight, rowVerticalSpacing, horizontalPadding, headerBackgroundColor, headerHeight, renderThreshold, stickedToStartColumns: initialStickedToStartColumns, columns: initialColumns, stickedToEndColumns: initialStickedToEndColumns, extraInfo, onEndReached, onEndReachedThresholdPx, getRowLink, renderEmptyList, loading, }: FixedListViewProps<T, ExtraInfo>) => import("react/jsx-runtime").JSX.Element;
|
|
86
89
|
type PlaceholderProps = {
|
|
87
90
|
count: number;
|
|
88
91
|
rowHeight: number;
|
|
@@ -50,7 +50,7 @@ import { LakeHeading } from "./LakeHeading";
|
|
|
50
50
|
import { LakeText } from "./LakeText";
|
|
51
51
|
import { Space } from "./Space";
|
|
52
52
|
const HORIZONTAL_SAFE_AREA = 10;
|
|
53
|
-
const SCROLLBAR_RESERVED_SPACE = 20;
|
|
53
|
+
export const SCROLLBAR_RESERVED_SPACE = 20;
|
|
54
54
|
const styles = StyleSheet.create({
|
|
55
55
|
root: {
|
|
56
56
|
height: 1,
|
|
@@ -97,16 +97,12 @@ const styles = StyleSheet.create({
|
|
|
97
97
|
top: 0,
|
|
98
98
|
bottom: 0,
|
|
99
99
|
right: "100%",
|
|
100
|
-
width: HORIZONTAL_SAFE_AREA,
|
|
101
|
-
backgroundColor: backgroundColor.default,
|
|
102
100
|
},
|
|
103
101
|
stickyColumnEndOverflow: {
|
|
104
102
|
position: "absolute",
|
|
105
103
|
top: 0,
|
|
106
104
|
bottom: 0,
|
|
107
105
|
left: "100%",
|
|
108
|
-
width: HORIZONTAL_SAFE_AREA,
|
|
109
|
-
backgroundColor: backgroundColor.default,
|
|
110
106
|
},
|
|
111
107
|
rowSegment: {
|
|
112
108
|
position: "absolute",
|
|
@@ -128,7 +124,6 @@ const styles = StyleSheet.create({
|
|
|
128
124
|
flexDirection: "row",
|
|
129
125
|
alignItems: "stretch",
|
|
130
126
|
zIndex: 2,
|
|
131
|
-
backgroundColor: backgroundColor.default,
|
|
132
127
|
},
|
|
133
128
|
segment: {
|
|
134
129
|
flexDirection: "row",
|
|
@@ -177,9 +172,6 @@ const styles = StyleSheet.create({
|
|
|
177
172
|
flexDirection: "row",
|
|
178
173
|
alignItems: "stretch",
|
|
179
174
|
},
|
|
180
|
-
stickyRow: {
|
|
181
|
-
// overflow: "hidden",
|
|
182
|
-
},
|
|
183
175
|
evenRow: {
|
|
184
176
|
backgroundColor: backgroundColor.accented,
|
|
185
177
|
},
|
|
@@ -226,7 +218,6 @@ const styles = StyleSheet.create({
|
|
|
226
218
|
transitionTimingFunction: "ease-in-out",
|
|
227
219
|
},
|
|
228
220
|
rowBackgroundContainerPlain: {
|
|
229
|
-
backgroundColor: backgroundColor.default,
|
|
230
221
|
left: -10,
|
|
231
222
|
right: -10,
|
|
232
223
|
boxShadow: `inset 0 -1px ${colors.gray[100]}`,
|
|
@@ -414,14 +405,15 @@ const findNextFocusableElement = (sortedCellIds, currentCellIndex, direction) =>
|
|
|
414
405
|
};
|
|
415
406
|
const EMPTY_COLUMNS = [];
|
|
416
407
|
const ZERO = 0;
|
|
417
|
-
export const FixedListView = ({ data: originalData, mode = "tile", keyExtractor, highlightedRowId, rowHeight, rowVerticalSpacing, headerHeight, renderThreshold = 1000, stickedToStartColumns: initialStickedToStartColumns = EMPTY_COLUMNS, columns: initialColumns, stickedToEndColumns: initialStickedToEndColumns = EMPTY_COLUMNS, extraInfo, onEndReached, onEndReachedThresholdPx = 200, getRowLink, renderEmptyList, loading, }) => {
|
|
408
|
+
export const FixedListView = ({ data: originalData, mode = "tile", keyExtractor, highlightedRowId, rowHeight, rowVerticalSpacing, horizontalPadding = HORIZONTAL_SAFE_AREA, headerBackgroundColor = backgroundColor.default, headerHeight, renderThreshold = 1000, stickedToStartColumns: initialStickedToStartColumns = EMPTY_COLUMNS, columns: initialColumns, stickedToEndColumns: initialStickedToEndColumns = EMPTY_COLUMNS, extraInfo, onEndReached, onEndReachedThresholdPx = 200, getRowLink, renderEmptyList, loading, }) => {
|
|
418
409
|
const [viewId] = useState(() => uuid());
|
|
419
410
|
// Those three refs are used to synchronize the horizontal scroll in the center columns
|
|
420
411
|
const centerHeadersRef = useRef(null);
|
|
421
412
|
const centerColumnsRef = useRef(null);
|
|
422
413
|
const horizontalScrollbarRef = useRef(null);
|
|
423
414
|
const totalRowHeight = rowHeight + rowVerticalSpacing;
|
|
424
|
-
const
|
|
415
|
+
const rowsHeight = originalData.length * totalRowHeight;
|
|
416
|
+
const totalHeight = headerHeight + rowsHeight;
|
|
425
417
|
// It might seem off to use the range in state instead of storing scroll/layout and deriving it,
|
|
426
418
|
// but it saves a lot of render phases by allowing to bail out from rendering when the range doesn't change
|
|
427
419
|
const [{ data, range: [renderedRangeStartIndex, renderedRangeEndIndex], }, setDataAndRenderRange,] = useState({ data: originalData, range: [0, 20] });
|
|
@@ -560,7 +552,7 @@ export const FixedListView = ({ data: originalData, mode = "tile", keyExtractor,
|
|
|
560
552
|
now - lastHorizontalScroll.current.date > SCROLL_THRESHOLD_MS) {
|
|
561
553
|
const scrollLeft = centerColumns.scrollLeft;
|
|
562
554
|
setShouldShowStartGradient(scrollLeft > 0);
|
|
563
|
-
setShouldShowEndGradient(centerColumns.scrollWidth -
|
|
555
|
+
setShouldShowEndGradient(centerColumns.scrollWidth - horizontalPadding * 2 >=
|
|
564
556
|
scrollLeft + centerColumns.clientWidth);
|
|
565
557
|
centerHeaders.scrollLeft = scrollLeft;
|
|
566
558
|
horizontalScrollbar.scrollLeft = scrollLeft;
|
|
@@ -573,7 +565,7 @@ export const FixedListView = ({ data: originalData, mode = "tile", keyExtractor,
|
|
|
573
565
|
now - lastHorizontalScroll.current.date > SCROLL_THRESHOLD_MS) {
|
|
574
566
|
const scrollLeft = centerHeaders.scrollLeft;
|
|
575
567
|
setShouldShowStartGradient(scrollLeft > 0);
|
|
576
|
-
setShouldShowEndGradient(centerHeaders.scrollWidth -
|
|
568
|
+
setShouldShowEndGradient(centerHeaders.scrollWidth - horizontalPadding * 2 >=
|
|
577
569
|
scrollLeft + centerHeaders.clientWidth);
|
|
578
570
|
centerColumns.scrollLeft = scrollLeft;
|
|
579
571
|
horizontalScrollbar.scrollLeft = scrollLeft;
|
|
@@ -586,7 +578,7 @@ export const FixedListView = ({ data: originalData, mode = "tile", keyExtractor,
|
|
|
586
578
|
now - lastHorizontalScroll.current.date > SCROLL_THRESHOLD_MS) {
|
|
587
579
|
const scrollLeft = horizontalScrollbar.scrollLeft;
|
|
588
580
|
setShouldShowStartGradient(scrollLeft > 0);
|
|
589
|
-
setShouldShowEndGradient(horizontalScrollbar.scrollWidth -
|
|
581
|
+
setShouldShowEndGradient(horizontalScrollbar.scrollWidth - horizontalPadding * 2 >=
|
|
590
582
|
scrollLeft + horizontalScrollbar.clientWidth);
|
|
591
583
|
centerHeaders.scrollLeft = scrollLeft;
|
|
592
584
|
centerColumns.scrollLeft = scrollLeft;
|
|
@@ -602,7 +594,7 @@ export const FixedListView = ({ data: originalData, mode = "tile", keyExtractor,
|
|
|
602
594
|
horizontalScrollbar.removeEventListener("scroll", onScrollbarScroll);
|
|
603
595
|
};
|
|
604
596
|
}
|
|
605
|
-
}, []);
|
|
597
|
+
}, [horizontalPadding]);
|
|
606
598
|
const onKeyDown = useCallback((event) => {
|
|
607
599
|
const target = event.nativeEvent.target;
|
|
608
600
|
const currentTarget = event.nativeEvent.currentTarget;
|
|
@@ -743,9 +735,9 @@ export const FixedListView = ({ data: originalData, mode = "tile", keyExtractor,
|
|
|
743
735
|
], children: [_jsx(View, { "aria-busy": isLoading, style: [
|
|
744
736
|
styles.loadingPlaceholder,
|
|
745
737
|
{
|
|
746
|
-
top:
|
|
747
|
-
marginLeft:
|
|
748
|
-
marginRight:
|
|
738
|
+
top: rowsHeight,
|
|
739
|
+
marginLeft: horizontalPadding * 2,
|
|
740
|
+
marginRight: horizontalPadding * 2,
|
|
749
741
|
},
|
|
750
742
|
], children: isLoading
|
|
751
743
|
? match(mode)
|
|
@@ -755,30 +747,39 @@ export const FixedListView = ({ data: originalData, mode = "tile", keyExtractor,
|
|
|
755
747
|
: null }), _jsx(View, { style: [styles.backgroundRows, { top: headerHeight }], children: backgroundRows }), _jsxs(View, { style: styles.scrollContentContainer, ref: scrollContentsRef, children: [stickedToStartColumns.length > 0 ? (_jsxs(View, { style: [
|
|
756
748
|
styles.stickyColumn,
|
|
757
749
|
{
|
|
758
|
-
width: stickedToStartColumnsWidth +
|
|
759
|
-
paddingLeft:
|
|
750
|
+
width: stickedToStartColumnsWidth + horizontalPadding,
|
|
751
|
+
paddingLeft: horizontalPadding,
|
|
760
752
|
},
|
|
761
|
-
], children: [_jsxs(View, { style: [
|
|
753
|
+
], children: [_jsxs(View, { style: [
|
|
754
|
+
styles.headingSegment,
|
|
755
|
+
{ height: headerHeight, backgroundColor: headerBackgroundColor },
|
|
756
|
+
], children: [_jsx(HeaderSegment, { columns: stickedToStartColumns, extraInfo: extraInfo, viewId: viewId, width: stickedToStartColumnsWidth }), _jsx(View, { style: [
|
|
757
|
+
styles.stickyColumnStartOverflow,
|
|
758
|
+
{ width: horizontalPadding, backgroundColor: headerBackgroundColor },
|
|
759
|
+
] }), _jsx(View, { style: [styles.topGradient, isScrolled && styles.visibleTopGradient] })] }), _jsx(View, { style: { height: rowsHeight }, children: startRows })] })) : null, _jsxs(View, { style: [
|
|
762
760
|
styles.centerColumnsContainer,
|
|
763
761
|
{
|
|
764
|
-
paddingLeft: stickedToStartColumns.length === 0 ?
|
|
765
|
-
paddingRight: stickedToEndColumns.length === 0 ?
|
|
762
|
+
paddingLeft: stickedToStartColumns.length === 0 ? horizontalPadding : ZERO,
|
|
763
|
+
paddingRight: stickedToEndColumns.length === 0 ? horizontalPadding : ZERO,
|
|
766
764
|
},
|
|
767
|
-
], children: [_jsxs(View, { style: [
|
|
765
|
+
], children: [_jsxs(View, { style: [
|
|
766
|
+
styles.headingSegment,
|
|
767
|
+
{ height: headerHeight, backgroundColor: headerBackgroundColor },
|
|
768
|
+
], children: [_jsx(ScrollView, { ref: centerHeadersRef, horizontal: true, onLayout: onCenterTrackLayout, style: styles.centerColumns, contentContainerStyle: {
|
|
768
769
|
minWidth: centerColumnsWidth +
|
|
769
|
-
(stickedToStartColumns.length === 0 ?
|
|
770
|
-
(stickedToEndColumns.length === 0 ?
|
|
770
|
+
(stickedToStartColumns.length === 0 ? horizontalPadding : 0) +
|
|
771
|
+
(stickedToEndColumns.length === 0 ? horizontalPadding : 0),
|
|
771
772
|
}, children: _jsx(HeaderSegment, { columns: columns, extraInfo: extraInfo, viewId: viewId, width: centerColumnsWidth }) }), _jsx(View, { style: [styles.topGradient, isScrolled && styles.visibleTopGradient] })] }), _jsx(ScrollView, { horizontal: true, ref: centerColumnsRef, style: styles.centerColumns, contentContainerStyle: [
|
|
772
773
|
styles.centerColumnsContentContainer,
|
|
773
774
|
{
|
|
774
775
|
minWidth: centerColumnsWidth +
|
|
775
|
-
(stickedToStartColumns.length === 0 ?
|
|
776
|
-
(stickedToEndColumns.length === 0 ?
|
|
776
|
+
(stickedToStartColumns.length === 0 ? horizontalPadding : 0) +
|
|
777
|
+
(stickedToEndColumns.length === 0 ? horizontalPadding : 0),
|
|
777
778
|
},
|
|
778
779
|
], children: centerRows }), _jsx(ScrollView, { ref: horizontalScrollbarRef, horizontal: true, style: styles.horizontalScrollbar, contentContainerStyle: {
|
|
779
780
|
minWidth: centerColumnsWidth +
|
|
780
|
-
(stickedToStartColumns.length === 0 ?
|
|
781
|
-
(stickedToEndColumns.length === 0 ?
|
|
781
|
+
(stickedToStartColumns.length === 0 ? horizontalPadding : 0) +
|
|
782
|
+
(stickedToEndColumns.length === 0 ? horizontalPadding : 0),
|
|
782
783
|
} }), stickedToStartColumns.length > 0 && hasHorizontalScroll ? (_jsx(View, { style: [
|
|
783
784
|
styles.leftToRightGradient,
|
|
784
785
|
{
|
|
@@ -798,10 +799,16 @@ export const FixedListView = ({ data: originalData, mode = "tile", keyExtractor,
|
|
|
798
799
|
] })) : null] }), stickedToEndColumns.length > 0 ? (_jsxs(View, { style: [
|
|
799
800
|
styles.stickyColumn,
|
|
800
801
|
{
|
|
801
|
-
width: stickedToEndColumnsWidth +
|
|
802
|
-
paddingRight:
|
|
802
|
+
width: stickedToEndColumnsWidth + horizontalPadding,
|
|
803
|
+
paddingRight: horizontalPadding,
|
|
803
804
|
},
|
|
804
|
-
], children: [_jsxs(View, { style: [
|
|
805
|
+
], children: [_jsxs(View, { style: [
|
|
806
|
+
styles.headingSegment,
|
|
807
|
+
{ height: headerHeight, backgroundColor: headerBackgroundColor },
|
|
808
|
+
], children: [_jsx(View, { style: [
|
|
809
|
+
styles.stickyColumnEndOverflow,
|
|
810
|
+
{ width: horizontalPadding, backgroundColor: headerBackgroundColor },
|
|
811
|
+
] }), _jsx(HeaderSegment, { columns: stickedToEndColumns, extraInfo: extraInfo, viewId: viewId, width: stickedToEndColumnsWidth }), _jsx(View, { style: [styles.topGradient, isScrolled && styles.visibleTopGradient] })] }), _jsx(View, { style: { height: rowsHeight }, children: endRows })] })) : null] })] }), data.length === 0 && isNotNullish(renderEmptyList) && !isLoading ? (_jsx(View, { style: styles.emptyListContainer, children: renderEmptyList() })) : null, _jsx(View, { ref: endFocusAnchorRef, tabIndex: 0 })] }));
|
|
805
812
|
};
|
|
806
813
|
export const FixedListViewPlaceholder = ({ count, rowHeight, rowVerticalSpacing, groupHeaderHeight, headerHeight, paddingHorizontal = HORIZONTAL_SAFE_AREA, }) => {
|
|
807
814
|
const totalRowHeight = rowHeight + rowVerticalSpacing;
|
|
@@ -30,7 +30,7 @@ export declare const CopyableRegularTextCell: ({ variant, text, copyWording, cop
|
|
|
30
30
|
copyWording: string;
|
|
31
31
|
copiedWording: string;
|
|
32
32
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
33
|
-
export declare const BalanceCell: ({ value, currency, originalValue, formatCurrency, textAlign, }: {
|
|
33
|
+
export declare const BalanceCell: ({ value, currency, originalValue, formatCurrency, textAlign, variant, }: {
|
|
34
34
|
value: number;
|
|
35
35
|
currency: string;
|
|
36
36
|
originalValue?: {
|
|
@@ -39,11 +39,13 @@ export declare const BalanceCell: ({ value, currency, originalValue, formatCurre
|
|
|
39
39
|
} | undefined;
|
|
40
40
|
formatCurrency: (value: number, currency: string) => string;
|
|
41
41
|
textAlign?: "left" | "right" | "center" | undefined;
|
|
42
|
+
variant?: "light" | "semibold" | "medium" | "regular" | "smallSemibold" | "smallMedium" | "smallRegular" | undefined;
|
|
42
43
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
43
|
-
export declare const LinkCell: ({ children, external, onPress, }: {
|
|
44
|
+
export declare const LinkCell: ({ children, external, onPress, variant, }: {
|
|
44
45
|
children: ReactNode;
|
|
45
46
|
onPress: () => void;
|
|
46
47
|
external?: boolean | undefined;
|
|
48
|
+
variant?: "light" | "semibold" | "medium" | "regular" | "smallSemibold" | "smallMedium" | "smallRegular" | undefined;
|
|
47
49
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
48
50
|
export declare const StartAlignedCell: ({ children }: {
|
|
49
51
|
children: ReactNode;
|
|
@@ -123,8 +123,8 @@ export const CopyableRegularTextCell = ({ variant = "regular", text, copyWording
|
|
|
123
123
|
return (_jsxs(View, { style: styles.cell, children: [_jsx(LakeTooltip, { placement: "top", onHide: () => setVisibleState("copy"), togglableOnFocus: true, content: visibleState === "copy" ? copyWording : copiedWording, containerStyle: styles.iconContainer, children: _jsx(Pressable, { role: "button", "aria-label": copyWording, onPress: onPress, style: ({ hovered }) => [styles.icon, hovered && styles.underline], children: ({ hovered }) => (_jsx(Icon, { name: hovered ? "copy-filled" : "copy-regular", color: "currentColor", size: 14 })) }) }), _jsx(Space, { width: 4 }), _jsx(LakeText, { color: colors.gray[900], style: styles.regularText, variant: variant, children: text })] }));
|
|
124
124
|
};
|
|
125
125
|
// TODO: handle `+` sign properly
|
|
126
|
-
export const BalanceCell = ({ value, currency, originalValue, formatCurrency, textAlign = "right", }) => {
|
|
127
|
-
return (_jsxs(View, { style: styles.balanceCellContainer, children: [_jsx(View, { style: styles.cell, children: _jsxs(LakeText, { align: textAlign, color: colors.gray[900], variant:
|
|
126
|
+
export const BalanceCell = ({ value, currency, originalValue, formatCurrency, textAlign = "right", variant = "medium", }) => {
|
|
127
|
+
return (_jsxs(View, { style: styles.balanceCellContainer, children: [_jsx(View, { style: styles.cell, children: _jsxs(LakeText, { align: textAlign, color: colors.gray[900], variant: variant, style: [
|
|
128
128
|
styles.mediumText,
|
|
129
129
|
{
|
|
130
130
|
justifyContent: match(textAlign)
|
|
@@ -137,11 +137,11 @@ export const BalanceCell = ({ value, currency, originalValue, formatCurrency, te
|
|
|
137
137
|
value < 0 && { color: colors.negative.primary },
|
|
138
138
|
], children: [value > 0 && "+", formatCurrency(value, currency)] }) }), isNotNullish(originalValue) && originalValue.currency !== currency && (_jsx(View, { style: styles.cell, children: _jsxs(LakeText, { style: styles.mediumText, align: textAlign, color: colors.gray[500], variant: "smallRegular", children: [originalValue.value > 0 && "+", formatCurrency(originalValue.value, originalValue.currency)] }) }))] }));
|
|
139
139
|
};
|
|
140
|
-
export const LinkCell = ({ children, external = false, onPress, }) => {
|
|
140
|
+
export const LinkCell = ({ children, external = false, onPress, variant = "medium", }) => {
|
|
141
141
|
return (_jsxs(View, { style: styles.cell, children: [_jsx(Pressable, { style: ({ hovered }) => [styles.icon, hovered && styles.underline], onPress: event => {
|
|
142
142
|
event.preventDefault();
|
|
143
143
|
onPress();
|
|
144
|
-
}, children: _jsx(Icon, { size: 14, name: external ? "open-regular" : "arrow-right-filled" }) }), _jsx(Space, { width: 8 }), _jsx(LakeText, { color: colors.gray[900], variant:
|
|
144
|
+
}, children: _jsx(Icon, { size: 14, name: external ? "open-regular" : "arrow-right-filled" }) }), _jsx(Space, { width: 8 }), _jsx(LakeText, { color: colors.gray[900], variant: variant, style: styles.mediumText, children: children })] }));
|
|
145
145
|
};
|
|
146
146
|
export const StartAlignedCell = ({ children }) => {
|
|
147
147
|
return _jsx(View, { style: styles.cell, children: children });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
import { StyleProp, ViewStyle } from "react-native";
|
|
3
|
-
type AlertVariant = "info" | "warning" | "error" | "success";
|
|
3
|
+
type AlertVariant = "info" | "warning" | "error" | "success" | "neutral";
|
|
4
4
|
type Props = {
|
|
5
5
|
anchored?: boolean;
|
|
6
6
|
variant: AlertVariant;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { StyleSheet, View } from "react-native";
|
|
3
3
|
import { commonStyles } from "../constants/commonStyles";
|
|
4
4
|
import { colors, shadows } from "../constants/design";
|
|
@@ -38,38 +38,44 @@ const alertIcon = {
|
|
|
38
38
|
warning: "warning-regular",
|
|
39
39
|
error: "dismiss-circle-regular",
|
|
40
40
|
success: "checkmark-circle-regular",
|
|
41
|
+
neutral: undefined,
|
|
41
42
|
};
|
|
42
43
|
const alertColor = {
|
|
43
44
|
info: colors.shakespear[700],
|
|
44
45
|
warning: colors.warning[700],
|
|
45
46
|
error: colors.negative[700],
|
|
46
47
|
success: colors.positive[700],
|
|
48
|
+
neutral: colors.gray[700],
|
|
47
49
|
};
|
|
48
50
|
const alertBackground = {
|
|
49
51
|
info: colors.shakespear[0],
|
|
50
52
|
warning: colors.warning[0],
|
|
51
53
|
error: colors.negative[0],
|
|
52
54
|
success: colors.positive[0],
|
|
55
|
+
neutral: colors.gray[0],
|
|
53
56
|
};
|
|
54
57
|
const alertBorder = {
|
|
55
58
|
info: colors.shakespear[200],
|
|
56
59
|
warning: colors.warning[200],
|
|
57
60
|
error: colors.negative[200],
|
|
58
61
|
success: colors.positive[200],
|
|
62
|
+
neutral: colors.gray[200],
|
|
59
63
|
};
|
|
60
64
|
const alertLeftBorder = {
|
|
61
65
|
info: colors.shakespear[500],
|
|
62
66
|
warning: colors.warning[500],
|
|
63
67
|
error: colors.negative[500],
|
|
64
68
|
success: colors.positive[500],
|
|
69
|
+
neutral: colors.gray[500],
|
|
65
70
|
};
|
|
66
71
|
const isText = (node) => typeof node === "string" || typeof node === "number";
|
|
67
72
|
export const LakeAlert = ({ anchored = false, variant, title, subtitle, children, style, callToAction, }) => {
|
|
68
73
|
const color = alertColor[variant];
|
|
74
|
+
const icon = alertIcon[variant];
|
|
69
75
|
return (_jsxs(View, { style: [
|
|
70
76
|
styles.base,
|
|
71
77
|
{ backgroundColor: alertBackground[variant], borderColor: alertBorder[variant] },
|
|
72
78
|
anchored ? styles.anchored : { borderLeftColor: alertLeftBorder[variant] },
|
|
73
79
|
style,
|
|
74
|
-
], children: [_jsxs(Box, { direction: "row", alignItems: "center", children: [_jsx(Icon, { name:
|
|
80
|
+
], children: [_jsxs(Box, { direction: "row", alignItems: "center", children: [icon != null ? (_jsxs(_Fragment, { children: [_jsx(Icon, { name: icon, color: color, size: 20 }), _jsx(Space, { width: 20 })] })) : null, _jsxs(View, { style: commonStyles.fill, children: [_jsx(LakeText, { color: color, variant: icon != null ? "regular" : "medium", children: title }), isNotNullishOrEmpty(subtitle) && _jsx(LakeText, { color: color, children: subtitle })] }), isNotNullish(callToAction) && _jsx(View, { style: styles.callToAction, children: callToAction })] }), isNotNullish(children) && (_jsxs(View, { style: icon != null ? styles.content : null, children: [_jsx(Space, { height: 12 }), isText(children) ? _jsx(LakeText, { children: children }) : children] }))] }));
|
|
75
81
|
};
|
|
@@ -86,8 +86,9 @@ const LakeComboboxWithRef = ({ inputRef, value, items, itemHeight = DEFAULT_ELEM
|
|
|
86
86
|
const listRef = useRef(null);
|
|
87
87
|
const listContainerRef = useRef(null);
|
|
88
88
|
const blurTimeoutId = useRef(undefined);
|
|
89
|
-
const [isFocused, { open, close }] = useDisclosure(false);
|
|
89
|
+
const [isFocused, { open, close }] = useDisclosure(false, () => setHasChanged(false));
|
|
90
90
|
const [isFetchingAdditionalInfo, setIsFetchingAdditionalInfo] = useState(false);
|
|
91
|
+
const [hasChanged, setHasChanged] = useState(false);
|
|
91
92
|
useImperativeHandle(externalRef, () => {
|
|
92
93
|
return {
|
|
93
94
|
open,
|
|
@@ -141,7 +142,10 @@ const LakeComboboxWithRef = ({ inputRef, value, items, itemHeight = DEFAULT_ELEM
|
|
|
141
142
|
close();
|
|
142
143
|
}, 100);
|
|
143
144
|
}, [close]);
|
|
144
|
-
return (_jsxs(View, { children: [_jsx(LakeTextInput, {
|
|
145
|
+
return (_jsxs(View, { children: [_jsx(LakeTextInput, { containerRef: inputTextRef, style: styles.input, ariaExpanded: isFocused, ariaControls: isFocused ? suggestionsId : "", enterKeyHint: "search", icon: icon, role: "combobox", placeholder: placeholder, value: value, disabled: disabled, error: error, hideErrors: hideErrors, onChangeText: onValueChange, onChange: event => {
|
|
146
|
+
setHasChanged(true);
|
|
147
|
+
onChange?.(event);
|
|
148
|
+
}, onFocus: handleFocus, onBlur: handleBlur, onKeyPress: handleKeyPress, id: id, readOnly: readOnly }), _jsx(Popover, { id: suggestionsId, role: "listbox", matchReferenceWidth: true, onDismiss: close, referenceRef: ref, autoFocus: false, returnFocus: true, visible: isFocused && !items.isNotAsked() && hasChanged, underlay: false, forcedMode: "Dropdown", children: _jsx(View, { style: [styles.list, { maxHeight: itemHeight * nbItemsDisplayed }], children: items.match({
|
|
145
149
|
NotAsked: () => null,
|
|
146
150
|
Loading: () => _jsx(LoadingView, { style: styles.loader }),
|
|
147
151
|
Done: items => items.match({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ChangeEventHandler, ReactNode } from "react";
|
|
2
|
-
import { NativeSyntheticEvent, TextInput, TextInputFocusEventData, TextInputProps } from "react-native";
|
|
1
|
+
import { ChangeEventHandler, ReactNode, Ref } from "react";
|
|
2
|
+
import { NativeSyntheticEvent, TextInput, TextInputFocusEventData, TextInputProps, View } from "react-native";
|
|
3
3
|
import { Except } from "type-fest";
|
|
4
4
|
import { ColorVariants } from "../constants/design";
|
|
5
5
|
import { IconName } from "./Icon";
|
|
@@ -24,6 +24,7 @@ export type LakeTextInputProps = Except<TextInputProps, "editable" | "keyboardTy
|
|
|
24
24
|
maxCharCount?: number;
|
|
25
25
|
help?: string;
|
|
26
26
|
renderEnd?: () => ReactNode;
|
|
27
|
+
containerRef?: Ref<View>;
|
|
27
28
|
};
|
|
28
29
|
export declare const LakeTextInput: import("react").ForwardRefExoticComponent<{
|
|
29
30
|
allowFontScaling?: boolean | undefined;
|
|
@@ -236,4 +237,5 @@ export declare const LakeTextInput: import("react").ForwardRefExoticComponent<{
|
|
|
236
237
|
maxCharCount?: number | undefined;
|
|
237
238
|
help?: string | undefined;
|
|
238
239
|
renderEnd?: (() => ReactNode) | undefined;
|
|
240
|
+
containerRef?: Ref<View> | undefined;
|
|
239
241
|
} & import("react").RefAttributes<TextInput | null>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef, useCallback, useRef, useState } from "react";
|
|
2
|
+
import { forwardRef, useCallback, useRef, useState, } from "react";
|
|
3
3
|
import { ActivityIndicator, StyleSheet, TextInput, View, } from "react-native";
|
|
4
4
|
import { commonStyles } from "../constants/commonStyles";
|
|
5
5
|
import { backgroundColor, colors, radii, shadows, spacings, texts, } from "../constants/design";
|
|
@@ -43,11 +43,11 @@ const styles = StyleSheet.create({
|
|
|
43
43
|
placeholderTextColor: colors.gray[400],
|
|
44
44
|
color: colors.gray[900],
|
|
45
45
|
paddingHorizontal: spacings[8],
|
|
46
|
-
height:
|
|
46
|
+
height: 38,
|
|
47
47
|
minWidth: 0,
|
|
48
48
|
},
|
|
49
49
|
multilineInput: {
|
|
50
|
-
height: "
|
|
50
|
+
height: "100%",
|
|
51
51
|
padding: spacings[8],
|
|
52
52
|
},
|
|
53
53
|
inputWithUnit: {
|
|
@@ -121,7 +121,7 @@ const styles = StyleSheet.create({
|
|
|
121
121
|
paddingTop: spacings[4],
|
|
122
122
|
},
|
|
123
123
|
});
|
|
124
|
-
export const LakeTextInput = forwardRef(({ ariaExpanded, ariaControls, error, disabled = false, validating = false, valid = false, readOnly = false, icon, children, unit, color = "gray", inputMode = "text", hideErrors = false, onChange, pattern, style: stylesFromProps, onFocus: originalOnFocus, onBlur: originalOnBlur, value, defaultValue, multiline = false,
|
|
124
|
+
export const LakeTextInput = forwardRef(({ ariaExpanded, ariaControls, error, disabled = false, validating = false, valid = false, readOnly = false, icon, children, unit, color = "gray", inputMode = "text", hideErrors = false, onChange, pattern, style: stylesFromProps, onFocus: originalOnFocus, onBlur: originalOnBlur, value, defaultValue, multiline = false, containerRef,
|
|
125
125
|
//maxCharCount is different from maxLength(props inherited of TextInput)
|
|
126
126
|
//maxLength truncates the text in the limitation asked,
|
|
127
127
|
//maxCharCount doesn't have limitation but displays a counter of characters
|
|
@@ -158,7 +158,7 @@ maxCharCount, help, renderEnd, ...props }, forwardRef) => {
|
|
|
158
158
|
hasError && styles.error,
|
|
159
159
|
valid && styles.valid,
|
|
160
160
|
stylesFromProps,
|
|
161
|
-
], children: [isNotNullish(icon) && (_jsx(Icon, { name: icon, size: 20, color: colors.current.primary, style: styles.icon })), _jsx(TextInput, { "aria-expanded": ariaExpanded, "aria-controls": ariaControls, inputMode: inputMode,
|
|
161
|
+
], ref: containerRef, children: [isNotNullish(icon) && (_jsx(Icon, { name: icon, size: 20, color: colors.current.primary, style: styles.icon })), _jsx(TextInput, { "aria-expanded": ariaExpanded, "aria-controls": ariaControls, inputMode: inputMode, ...props, defaultValue: defaultValue, value: isNullish(defaultValue) ? value ?? "" : value, onFocus: onFocus, onBlur: onBlur, readOnly: !isInteractive, onChange: onChange, multiline: multiline, ref: mergedRef, style: [
|
|
162
162
|
styles.input,
|
|
163
163
|
multiline && styles.multilineInput,
|
|
164
164
|
readOnly && hasError && styles.readOnlyError,
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { useMemo, useState } from "react";
|
|
2
|
-
export const useDisclosure = (initialValue) => {
|
|
2
|
+
export const useDisclosure = (initialValue, onClose) => {
|
|
3
3
|
const [value, setValue] = useState(initialValue);
|
|
4
4
|
return [
|
|
5
5
|
value,
|
|
6
6
|
useMemo(() => ({
|
|
7
7
|
open: () => setValue(true),
|
|
8
|
-
close: () =>
|
|
8
|
+
close: () => {
|
|
9
|
+
setValue(false);
|
|
10
|
+
onClose?.();
|
|
11
|
+
},
|
|
9
12
|
toggle: () => setValue(prevValue => !prevValue),
|
|
10
13
|
}), []),
|
|
11
14
|
];
|