@swan-io/lake 1.0.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/HISTORY.md +3 -0
- package/LICENSE +21 -0
- package/README.md +49 -0
- package/package.json +60 -0
- package/src/components/Alert.d.ts +10 -0
- package/src/components/Alert.js +36 -0
- package/src/components/AppOpeningAnimation.d.ts +10 -0
- package/src/components/AppOpeningAnimation.js +50 -0
- package/src/components/AutoWidthImage.d.ts +8 -0
- package/src/components/AutoWidthImage.js +26 -0
- package/src/components/Avatar.d.ts +7 -0
- package/src/components/Avatar.js +42 -0
- package/src/components/BorderedButton.d.ts +16 -0
- package/src/components/BorderedButton.js +98 -0
- package/src/components/BorderedIcon.d.ts +12 -0
- package/src/components/BorderedIcon.js +25 -0
- package/src/components/BottomPanel.d.ts +9 -0
- package/src/components/BottomPanel.js +94 -0
- package/src/components/Box.d.ts +65 -0
- package/src/components/Box.js +31 -0
- package/src/components/Breadcrumbs.d.ts +18 -0
- package/src/components/Breadcrumbs.js +362 -0
- package/src/components/Button.d.ts +15 -0
- package/src/components/Button.js +83 -0
- package/src/components/Caption.d.ts +6 -0
- package/src/components/Caption.js +11 -0
- package/src/components/Checkbox.d.ts +12 -0
- package/src/components/Checkbox.js +83 -0
- package/src/components/ChoicePicker.d.ts +11 -0
- package/src/components/ChoicePicker.js +99 -0
- package/src/components/Combobox.d.ts +29 -0
- package/src/components/Combobox.js +182 -0
- package/src/components/FailureIcon.d.ts +8 -0
- package/src/components/FailureIcon.js +4 -0
- package/src/components/FileTile.d.ts +11 -0
- package/src/components/FileTile.js +37 -0
- package/src/components/Fill.d.ts +8 -0
- package/src/components/Fill.js +24 -0
- package/src/components/FilterChooser.d.ts +15 -0
- package/src/components/FilterChooser.js +52 -0
- package/src/components/Filters.d.ts +57 -0
- package/src/components/Filters.js +229 -0
- package/src/components/FixedListView.d.ts +104 -0
- package/src/components/FixedListView.js +821 -0
- package/src/components/FixedListViewCells.d.ts +55 -0
- package/src/components/FixedListViewCells.js +157 -0
- package/src/components/Flag.d.ts +8 -0
- package/src/components/Flag.js +36 -0
- package/src/components/FlowPresentation.d.ts +12 -0
- package/src/components/FlowPresentation.js +70 -0
- package/src/components/FocusTrap.d.ts +16 -0
- package/src/components/FocusTrap.js +90 -0
- package/src/components/Form.d.ts +8 -0
- package/src/components/Form.js +17 -0
- package/src/components/FullViewportLayer.d.ts +7 -0
- package/src/components/FullViewportLayer.js +91 -0
- package/src/components/Grid.d.ts +13 -0
- package/src/components/Grid.js +33 -0
- package/src/components/Heading.d.ts +61 -0
- package/src/components/Heading.js +27 -0
- package/src/components/Icon.d.ts +191 -0
- package/src/components/Icon.js +11 -0
- package/src/components/Input.d.ts +34 -0
- package/src/components/Input.js +115 -0
- package/src/components/InputError.d.ts +8 -0
- package/src/components/InputError.js +16 -0
- package/src/components/Label.d.ts +10 -0
- package/src/components/Label.js +19 -0
- package/src/components/LakeAlert.d.ts +14 -0
- package/src/components/LakeAlert.js +75 -0
- package/src/components/LakeButton.d.ts +36 -0
- package/src/components/LakeButton.js +171 -0
- package/src/components/LakeCheckbox.d.ts +16 -0
- package/src/components/LakeCheckbox.js +54 -0
- package/src/components/LakeCombobox.d.ts +28 -0
- package/src/components/LakeCombobox.js +166 -0
- package/src/components/LakeCopyButton.d.ts +10 -0
- package/src/components/LakeCopyButton.js +16 -0
- package/src/components/LakeDownloadButton.d.ts +8 -0
- package/src/components/LakeDownloadButton.js +6 -0
- package/src/components/LakeHeading.d.ts +10 -0
- package/src/components/LakeHeading.js +19 -0
- package/src/components/LakeLabel.d.ts +19 -0
- package/src/components/LakeLabel.js +43 -0
- package/src/components/LakeModal.d.ts +14 -0
- package/src/components/LakeModal.js +132 -0
- package/src/components/LakeRadio.d.ts +9 -0
- package/src/components/LakeRadio.js +44 -0
- package/src/components/LakeScrollView.d.ts +10 -0
- package/src/components/LakeScrollView.js +35 -0
- package/src/components/LakeSearchField.d.ts +10 -0
- package/src/components/LakeSearchField.js +111 -0
- package/src/components/LakeSelect.d.ts +30 -0
- package/src/components/LakeSelect.js +183 -0
- package/src/components/LakeSlider.d.ts +12 -0
- package/src/components/LakeSlider.js +31 -0
- package/src/components/LakeStepper.d.ts +21 -0
- package/src/components/LakeStepper.js +134 -0
- package/src/components/LakeText.d.ts +19 -0
- package/src/components/LakeText.js +20 -0
- package/src/components/LakeTextInput.d.ts +36 -0
- package/src/components/LakeTextInput.js +154 -0
- package/src/components/LakeTooltip.d.ts +24 -0
- package/src/components/LakeTooltip.js +188 -0
- package/src/components/Link.d.ts +138 -0
- package/src/components/Link.js +23 -0
- package/src/components/ListRightPanel.d.ts +17 -0
- package/src/components/ListRightPanel.js +79 -0
- package/src/components/LoadingView.d.ts +9 -0
- package/src/components/LoadingView.js +24 -0
- package/src/components/Modal.d.ts +12 -0
- package/src/components/Modal.js +80 -0
- package/src/components/MultiSelect.d.ts +27 -0
- package/src/components/MultiSelect.js +223 -0
- package/src/components/MultilineInput.d.ts +15 -0
- package/src/components/MultilineInput.js +55 -0
- package/src/components/Picker.d.ts +26 -0
- package/src/components/Picker.js +116 -0
- package/src/components/PlainListView.d.ts +36 -0
- package/src/components/PlainListView.js +208 -0
- package/src/components/Popover.d.ts +23 -0
- package/src/components/Popover.js +147 -0
- package/src/components/PopoverContent.d.ts +8 -0
- package/src/components/PopoverContent.js +9 -0
- package/src/components/Portal.d.ts +7 -0
- package/src/components/Portal.js +9 -0
- package/src/components/Pressable.d.ts +348 -0
- package/src/components/Pressable.js +91 -0
- package/src/components/ProgressBar.d.ts +11 -0
- package/src/components/ProgressBar.js +46 -0
- package/src/components/ProjectEnvTag.d.ts +7 -0
- package/src/components/ProjectEnvTag.js +12 -0
- package/src/components/QuickActions.d.ts +15 -0
- package/src/components/QuickActions.js +38 -0
- package/src/components/RadioGroup.d.ts +16 -0
- package/src/components/RadioGroup.js +34 -0
- package/src/components/ReadOnlyFieldList.d.ts +6 -0
- package/src/components/ReadOnlyFieldList.js +8 -0
- package/src/components/ResponsiveContainer.d.ts +13 -0
- package/src/components/ResponsiveContainer.js +23 -0
- package/src/components/RightPanel.d.ts +10 -0
- package/src/components/RightPanel.js +102 -0
- package/src/components/SegmentedControl.d.ts +19 -0
- package/src/components/SegmentedControl.js +74 -0
- package/src/components/Separator.d.ts +10 -0
- package/src/components/Separator.js +19 -0
- package/src/components/SidebarNavigationTracker.d.ts +13 -0
- package/src/components/SidebarNavigationTracker.js +93 -0
- package/src/components/Slider.d.ts +11 -0
- package/src/components/Slider.js +119 -0
- package/src/components/SmsOpeningAnimation.d.ts +8 -0
- package/src/components/SmsOpeningAnimation.js +52 -0
- package/src/components/Space.d.ts +10 -0
- package/src/components/Space.js +23 -0
- package/src/components/Stack.d.ts +12 -0
- package/src/components/Stack.js +23 -0
- package/src/components/StepDots.d.ts +7 -0
- package/src/components/StepDots.js +24 -0
- package/src/components/Stepper.d.ts +9 -0
- package/src/components/Stepper.js +67 -0
- package/src/components/SuccessIcon.d.ts +8 -0
- package/src/components/SuccessIcon.js +4 -0
- package/src/components/Svg.d.ts +145 -0
- package/src/components/Svg.js +24 -0
- package/src/components/SwanLogo.d.ts +8 -0
- package/src/components/SwanLogo.js +11 -0
- package/src/components/Switch.d.ts +9 -0
- package/src/components/Switch.js +74 -0
- package/src/components/TabView.d.ts +16 -0
- package/src/components/TabView.js +398 -0
- package/src/components/Table.d.ts +34 -0
- package/src/components/Table.js +79 -0
- package/src/components/Tag.d.ts +17 -0
- package/src/components/Tag.js +76 -0
- package/src/components/Tile.d.ts +34 -0
- package/src/components/Tile.js +130 -0
- package/src/components/TilePlaceholder.d.ts +6 -0
- package/src/components/TilePlaceholder.js +51 -0
- package/src/components/ToastStack.d.ts +2 -0
- package/src/components/ToastStack.js +96 -0
- package/src/components/Tooltip.d.ts +18 -0
- package/src/components/Tooltip.js +162 -0
- package/src/components/TransitionGroupView.d.ts +12 -0
- package/src/components/TransitionGroupView.js +43 -0
- package/src/components/TransitionView.d.ts +12 -0
- package/src/components/TransitionView.js +43 -0
- package/src/components/WithCurrentColor.d.ts +12 -0
- package/src/components/WithCurrentColor.js +65 -0
- package/src/components/WithPartnerAccentColor.d.ts +7 -0
- package/src/components/WithPartnerAccentColor.js +91 -0
- package/src/constants/colors.d.ts +42 -0
- package/src/constants/colors.js +42 -0
- package/src/constants/commonStyles.d.ts +66 -0
- package/src/constants/commonStyles.js +45 -0
- package/src/constants/design.d.ts +168 -0
- package/src/constants/design.js +564 -0
- package/src/constants/insets.d.ts +10 -0
- package/src/constants/insets.js +22 -0
- package/src/constants/typography.d.ts +26 -0
- package/src/constants/typography.js +54 -0
- package/src/hooks/useAnimatedValue.d.ts +2 -0
- package/src/hooks/useAnimatedValue.js +3 -0
- package/src/hooks/useBodyClassName.d.ts +3 -0
- package/src/hooks/useBodyClassName.js +14 -0
- package/src/hooks/useBoolean.d.ts +8 -0
- package/src/hooks/useBoolean.js +12 -0
- package/src/hooks/useComputedColors.d.ts +10 -0
- package/src/hooks/useComputedColors.js +42 -0
- package/src/hooks/useDebounce.d.ts +1 -0
- package/src/hooks/useDebounce.js +12 -0
- package/src/hooks/useDisclosure.d.ts +8 -0
- package/src/hooks/useDisclosure.js +12 -0
- package/src/hooks/useFirstMountState.d.ts +1 -0
- package/src/hooks/useFirstMountState.js +9 -0
- package/src/hooks/useForceableState.d.ts +1 -0
- package/src/hooks/useForceableState.js +6 -0
- package/src/hooks/useHover.d.ts +11 -0
- package/src/hooks/useHover.js +4 -0
- package/src/hooks/useInterval.d.ts +1 -0
- package/src/hooks/useInterval.js +11 -0
- package/src/hooks/useLazyRef.d.ts +2 -0
- package/src/hooks/useLazyRef.js +9 -0
- package/src/hooks/useMergeRefs.d.ts +2 -0
- package/src/hooks/useMergeRefs.js +5 -0
- package/src/hooks/useNativeProp.d.ts +2 -0
- package/src/hooks/useNativeProp.js +9 -0
- package/src/hooks/useOutsideClick.d.ts +8 -0
- package/src/hooks/useOutsideClick.js +54 -0
- package/src/hooks/usePersistedState.d.ts +1 -0
- package/src/hooks/usePersistedState.js +21 -0
- package/src/hooks/usePressEvents.d.ts +31 -0
- package/src/hooks/usePressEvents.js +4 -0
- package/src/hooks/usePreviousValue.d.ts +1 -0
- package/src/hooks/usePreviousValue.js +8 -0
- package/src/hooks/useResponsive.d.ts +7 -0
- package/src/hooks/useResponsive.js +20 -0
- package/src/hooks/useUpdateEffect.d.ts +2 -0
- package/src/hooks/useUpdateEffect.js +10 -0
- package/src/hooks/useUrqlMutation.d.ts +4 -0
- package/src/hooks/useUrqlMutation.js +30 -0
- package/src/hooks/useUrqlQuery.d.ts +19 -0
- package/src/hooks/useUrqlQuery.js +73 -0
- package/src/state/toasts.d.ts +21 -0
- package/src/state/toasts.js +61 -0
- package/src/utils/__tests__/array.test.d.ts +1 -0
- package/src/utils/__tests__/array.test.js +127 -0
- package/src/utils/__tests__/base64.test.d.ts +1 -0
- package/src/utils/__tests__/base64.test.js +27 -0
- package/src/utils/__tests__/function.test.d.ts +1 -0
- package/src/utils/__tests__/function.test.js +36 -0
- package/src/utils/__tests__/object.test.d.ts +1 -0
- package/src/utils/__tests__/object.test.js +17 -0
- package/src/utils/__tests__/rifm.test.d.ts +1 -0
- package/src/utils/__tests__/rifm.test.js +124 -0
- package/src/utils/__tests__/string.test.d.ts +1 -0
- package/src/utils/__tests__/string.test.js +16 -0
- package/src/utils/a11y.d.ts +1 -0
- package/src/utils/a11y.js +18 -0
- package/src/utils/array.d.ts +6 -0
- package/src/utils/array.js +71 -0
- package/src/utils/base64.d.ts +2 -0
- package/src/utils/base64.js +20 -0
- package/src/utils/file.d.ts +2 -0
- package/src/utils/file.js +10 -0
- package/src/utils/flagCountry.d.ts +1 -0
- package/src/utils/flagCountry.js +1 -0
- package/src/utils/function.d.ts +4 -0
- package/src/utils/function.js +19 -0
- package/src/utils/math.d.ts +16 -0
- package/src/utils/math.js +47 -0
- package/src/utils/nullish.d.ts +10 -0
- package/src/utils/nullish.js +8 -0
- package/src/utils/object.d.ts +2 -0
- package/src/utils/object.js +7 -0
- package/src/utils/popper.d.ts +3 -0
- package/src/utils/popper.js +30 -0
- package/src/utils/rifm.d.ts +14 -0
- package/src/utils/rifm.js +53 -0
- package/src/utils/string.d.ts +4 -0
- package/src/utils/string.js +233 -0
- package/src/utils/timer.d.ts +11 -0
- package/src/utils/timer.js +46 -0
- package/src/utils/types.d.ts +8 -0
- package/src/utils/types.js +1 -0
- package/src/utils/userAgent.d.ts +4 -0
- package/src/utils/userAgent.js +9 -0
- package/src/utils/viewport.d.ts +1 -0
- package/src/utils/viewport.js +12 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import dayjs from "dayjs";
|
|
3
|
+
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
4
|
+
import { FlatList, Pressable, StyleSheet, Text, View } from "react-native";
|
|
5
|
+
import { hasDefinedKeys, useForm } from "react-ux-form";
|
|
6
|
+
import { Rifm } from "rifm";
|
|
7
|
+
import { match, P } from "ts-pattern";
|
|
8
|
+
import { colors, shadows, spacings } from "../constants/design";
|
|
9
|
+
import { useDisclosure } from "../hooks/useDisclosure";
|
|
10
|
+
import { useMergeRefs } from "../hooks/useMergeRefs";
|
|
11
|
+
import { usePreviousValue } from "../hooks/usePreviousValue";
|
|
12
|
+
import { isNotNullish } from "../utils/nullish";
|
|
13
|
+
import { Box } from "./Box";
|
|
14
|
+
import { Icon } from "./Icon";
|
|
15
|
+
import { Input } from "./Input";
|
|
16
|
+
import { LakeButton } from "./LakeButton";
|
|
17
|
+
import { LakeCheckbox } from "./LakeCheckbox";
|
|
18
|
+
import { LakeRadio } from "./LakeRadio";
|
|
19
|
+
import { Popover } from "./Popover";
|
|
20
|
+
import { Space } from "./Space";
|
|
21
|
+
import { Stack } from "./Stack";
|
|
22
|
+
import { Tag } from "./Tag";
|
|
23
|
+
const styles = StyleSheet.create({
|
|
24
|
+
container: {
|
|
25
|
+
paddingRight: 12,
|
|
26
|
+
paddingBottom: 8,
|
|
27
|
+
},
|
|
28
|
+
shadowed: {
|
|
29
|
+
position: "absolute",
|
|
30
|
+
opacity: 0,
|
|
31
|
+
width: "100%",
|
|
32
|
+
height: "100%",
|
|
33
|
+
borderRadius: 4,
|
|
34
|
+
boxShadow: shadows.tile,
|
|
35
|
+
transitionDuration: "150ms",
|
|
36
|
+
transitionProperty: "opacity",
|
|
37
|
+
},
|
|
38
|
+
hovered: {
|
|
39
|
+
opacity: 1,
|
|
40
|
+
},
|
|
41
|
+
dropdown: {
|
|
42
|
+
marginTop: 4,
|
|
43
|
+
maxHeight: 400,
|
|
44
|
+
minWidth: 200,
|
|
45
|
+
},
|
|
46
|
+
itemHovered: {
|
|
47
|
+
backgroundColor: colors.gray[50],
|
|
48
|
+
},
|
|
49
|
+
content: {
|
|
50
|
+
paddingVertical: 12,
|
|
51
|
+
},
|
|
52
|
+
inputContent: {
|
|
53
|
+
padding: 24,
|
|
54
|
+
},
|
|
55
|
+
radio: {
|
|
56
|
+
display: "flex",
|
|
57
|
+
flexDirection: "row",
|
|
58
|
+
alignItems: "center",
|
|
59
|
+
height: 32,
|
|
60
|
+
paddingHorizontal: 24,
|
|
61
|
+
},
|
|
62
|
+
dateInput: {
|
|
63
|
+
width: 200,
|
|
64
|
+
},
|
|
65
|
+
value: {
|
|
66
|
+
maxWidth: 130,
|
|
67
|
+
whiteSpace: "nowrap",
|
|
68
|
+
},
|
|
69
|
+
buttonContainer: {
|
|
70
|
+
paddingHorizontal: spacings[24],
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
const FilterTag = forwardRef(({ onPress, onPressRemove, label, value = "", isActive }, forwardRef) => {
|
|
74
|
+
const ref = useRef(null);
|
|
75
|
+
const mergedRef = useMergeRefs(ref, forwardRef);
|
|
76
|
+
return (_jsx(Pressable, { ref: mergedRef, onPress: onPress, children: ({ hovered }) => (_jsxs(_Fragment, { children: [_jsx(View, { style: [styles.shadowed, hovered && styles.hovered] }), _jsx(Tag, { label: label, color: "current", onPressRemove: onPressRemove, children: _jsxs(Box, { direction: "row", alignItems: "center", children: [_jsx(Text, { numberOfLines: 1, style: styles.value, children: value }), _jsx(Space, { width: 4 }), _jsx(Icon, { color: colors.current.primary, name: isActive ? "chevron-up-filled" : "chevron-down-filled", size: 16 })] }) })] })) }));
|
|
77
|
+
});
|
|
78
|
+
function FilterRadio({ label, items, value, onValueChange, onPressRemove, autoOpen = false, }) {
|
|
79
|
+
const inputRef = useRef(null);
|
|
80
|
+
const [visible, { close, toggle }] = useDisclosure(autoOpen);
|
|
81
|
+
const currentValue = useMemo(() => items.find(i => i.value === value), [items, value]);
|
|
82
|
+
return (_jsxs(View, { style: styles.container, children: [_jsx(FilterTag, { label: label, onPress: toggle, ref: inputRef, onPressRemove: onPressRemove, isActive: visible, value: currentValue?.label }), _jsx(Popover, { role: "listbox", matchReferenceWidth: false, onDismiss: close, referenceRef: inputRef, returnFocus: false, visible: visible, children: _jsx(View, { style: styles.dropdown, children: _jsx(FlatList, { accessibilityRole: "list", data: items, contentContainerStyle: styles.content, keyExtractor: (_, index) => `filter-item-${index}`, renderItem: ({ item }) => {
|
|
83
|
+
const isSelected = value === item.value;
|
|
84
|
+
return (_jsxs(Pressable, { accessibilityRole: "radio", accessibilityChecked: isSelected, style: ({ hovered }) => [styles.radio, hovered && styles.itemHovered], onPress: () => {
|
|
85
|
+
onValueChange(item.value);
|
|
86
|
+
close();
|
|
87
|
+
}, children: [_jsx(LakeRadio, { value: isSelected }), _jsx(Space, { width: 12 }), _jsx(Text, { children: item.label })] }));
|
|
88
|
+
} }) }) })] }));
|
|
89
|
+
}
|
|
90
|
+
function FilterCheckbox({ label, items, checkAllLabel, value, onValueChange, applyButtonLabel, onPressRemove, autoOpen = false, }) {
|
|
91
|
+
const inputRef = useRef(null);
|
|
92
|
+
const [visible, { close, toggle }] = useDisclosure(autoOpen);
|
|
93
|
+
const [localValue, setLocalValue] = useState(value);
|
|
94
|
+
const values = useMemo(() => new Set(localValue), [localValue]);
|
|
95
|
+
const currentValue = useMemo(() => items.filter(item => values.has(item.value)), [items, values]);
|
|
96
|
+
const allChecked = checkAllLabel != null && values.size === items.length;
|
|
97
|
+
const listItems = useMemo(() => {
|
|
98
|
+
if (checkAllLabel == null) {
|
|
99
|
+
return items;
|
|
100
|
+
}
|
|
101
|
+
const checked = values.size === 0 ? false : values.size === items.length ? true : "mixed";
|
|
102
|
+
const checkAllItem = {
|
|
103
|
+
label: checkAllLabel,
|
|
104
|
+
checked,
|
|
105
|
+
};
|
|
106
|
+
return [checkAllItem, ...items];
|
|
107
|
+
}, [items, checkAllLabel, values]);
|
|
108
|
+
const save = useCallback(() => {
|
|
109
|
+
onValueChange(localValue);
|
|
110
|
+
close();
|
|
111
|
+
}, [onValueChange, localValue, close]);
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (!visible) {
|
|
114
|
+
setLocalValue(value);
|
|
115
|
+
}
|
|
116
|
+
}, [visible, value]);
|
|
117
|
+
return (_jsxs(View, { style: styles.container, children: [_jsx(FilterTag, { label: label, onPress: toggle, ref: inputRef, onPressRemove: onPressRemove, isActive: visible, value: allChecked ? checkAllLabel : currentValue.map(item => item.label).join(", ") }), _jsx(Popover, { role: "listbox", matchReferenceWidth: false, onDismiss: close, referenceRef: inputRef, returnFocus: false, visible: visible, children: _jsxs(View, { style: styles.dropdown, children: [_jsx(FlatList, { accessibilityRole: "list", data: listItems, contentContainerStyle: styles.content, keyExtractor: (_, index) => `filter-item-${index}`, renderItem: ({ item }) => {
|
|
118
|
+
const isSelected = match(item)
|
|
119
|
+
.with({ checked: P.any }, ({ checked }) => checked)
|
|
120
|
+
.with({ value: P.any }, ({ value }) => values.has(value))
|
|
121
|
+
.exhaustive();
|
|
122
|
+
const onPress = match(item)
|
|
123
|
+
// Check all item
|
|
124
|
+
.with({ checked: P.any }, ({ checked }) => () => {
|
|
125
|
+
if (checked === true) {
|
|
126
|
+
setLocalValue(undefined);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
setLocalValue(items.map(item => item.value));
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
// Regular item
|
|
133
|
+
.with({ value: P.any }, ({ value }) => () => {
|
|
134
|
+
const nextValues = new Set([...values]);
|
|
135
|
+
if (isSelected === true) {
|
|
136
|
+
nextValues.delete(value);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
nextValues.add(value);
|
|
140
|
+
}
|
|
141
|
+
if (nextValues.size === 0) {
|
|
142
|
+
setLocalValue(undefined);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
setLocalValue([...nextValues]);
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
.exhaustive();
|
|
149
|
+
return (_jsxs(Pressable, { accessibilityRole: "radio", accessibilityChecked: isSelected, style: ({ hovered }) => [styles.radio, hovered && styles.itemHovered], onPress: onPress, children: [_jsx(LakeCheckbox, { value: isSelected }), _jsx(Space, { width: 12 }), _jsx(Text, { children: item.label })] }));
|
|
150
|
+
} }), _jsx(Space, { height: 8 }), _jsx(View, { style: styles.buttonContainer, children: _jsx(LakeButton, { color: "current", onPress: save, children: applyButtonLabel }) }), _jsx(Space, { height: 24 })] }) })] }));
|
|
151
|
+
}
|
|
152
|
+
function FilterDate({ label, initialValue, noValueText, submitText, dateFormat, rifmProps, validate, onSave, onPressRemove, autoOpen = false, }) {
|
|
153
|
+
const inputRef = useRef(null);
|
|
154
|
+
const [visible, { close, toggle }] = useDisclosure(autoOpen);
|
|
155
|
+
const { Field, submitForm, setFieldValue } = useForm({
|
|
156
|
+
date: {
|
|
157
|
+
initialValue: isNotNullish(initialValue) ? dayjs(initialValue).format(dateFormat) : "",
|
|
158
|
+
validate,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
setFieldValue("date", isNotNullish(initialValue) ? dayjs(initialValue).format(dateFormat) : "");
|
|
163
|
+
}, [initialValue, dateFormat, setFieldValue]);
|
|
164
|
+
const onSubmit = () => {
|
|
165
|
+
submitForm(values => {
|
|
166
|
+
if (hasDefinedKeys(values, ["date"])) {
|
|
167
|
+
const date = dayjs(values.date, dateFormat, true).toJSON();
|
|
168
|
+
onSave(date);
|
|
169
|
+
close();
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
};
|
|
173
|
+
return (_jsxs(View, { style: styles.container, children: [_jsx(FilterTag, { label: label, onPress: toggle, ref: inputRef, onPressRemove: onPressRemove, isActive: visible, value: isNotNullish(initialValue) ? dayjs(initialValue).format(dateFormat) : noValueText }), _jsx(Popover, { role: "listbox", matchReferenceWidth: false, onDismiss: close, referenceRef: inputRef, returnFocus: false, visible: visible, children: _jsxs(View, { style: [styles.dropdown, styles.inputContent], children: [_jsx(Field, { name: "date", children: ({ value, onChange, error }) => (_jsx(Rifm, { value: value, onChange: onChange, ...rifmProps, children: ({ value, onChange }) => (_jsx(Input, { label: label, error: error, size: "small", style: styles.dateInput, placeholder: dateFormat, value: value, onChange: onChange })) })) }), _jsx(LakeButton, { color: "current", onPress: onSubmit, children: submitText })] }) })] }));
|
|
174
|
+
}
|
|
175
|
+
function FilterInput({ label, initialValue = "", noValueText, submitText, autoOpen = false, placeholder, validate, onSave, onPressRemove, }) {
|
|
176
|
+
const inputRef = useRef(null);
|
|
177
|
+
const [visible, { close, toggle }] = useDisclosure(autoOpen);
|
|
178
|
+
const [value, setValue] = useState(initialValue);
|
|
179
|
+
const { Field, submitForm } = useForm({
|
|
180
|
+
input: {
|
|
181
|
+
initialValue,
|
|
182
|
+
validate,
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
const onSubmit = () => {
|
|
186
|
+
submitForm(values => {
|
|
187
|
+
if (hasDefinedKeys(values, ["input"])) {
|
|
188
|
+
setValue(values.input);
|
|
189
|
+
onSave(values.input);
|
|
190
|
+
close();
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
return (_jsxs(View, { style: styles.container, children: [_jsx(FilterTag, { label: label, onPress: toggle, ref: inputRef, onPressRemove: onPressRemove, isActive: visible, value: value === "" ? noValueText : value }), _jsx(Popover, { role: "listbox", matchReferenceWidth: false, onDismiss: close, referenceRef: inputRef, returnFocus: false, visible: visible, children: _jsxs(View, { style: [styles.dropdown, styles.inputContent], children: [_jsx(Field, { name: "input", children: ({ error, value, onChange }) => (_jsx(Input, { label: label, size: "small", error: error, style: styles.dateInput, placeholder: placeholder, value: value, onValueChange: onChange })) }), _jsx(LakeButton, { size: "small", color: "current", onPress: onSubmit, children: submitText })] }) })] }));
|
|
195
|
+
}
|
|
196
|
+
const getFilterValue = (_type, filters, name) => filters[name];
|
|
197
|
+
export const FiltersStack = ({ filters, openedFilters, definition, onChangeOpened, onChangeFilters, }) => {
|
|
198
|
+
const previousOpened = usePreviousValue(openedFilters);
|
|
199
|
+
const lastOpenedFilter = openedFilters.length > previousOpened.length
|
|
200
|
+
? openedFilters[openedFilters.length - 1]
|
|
201
|
+
: undefined;
|
|
202
|
+
if (openedFilters.length === 0) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
return (_jsx(Stack, { direction: "row", wrap: true, children: openedFilters.map(filterName => {
|
|
206
|
+
const filterDefinition = definition[filterName];
|
|
207
|
+
if (typeof filterName !== "string" || filterDefinition == null) {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
return (_jsx(View, { children: match(filterDefinition)
|
|
211
|
+
.with({ type: "radio" }, ({ type, label, items }) => (_jsx(FilterRadio, { label: label, items: items, autoOpen: lastOpenedFilter === filterName, onPressRemove: () => {
|
|
212
|
+
onChangeFilters({ ...filters, [filterName]: undefined });
|
|
213
|
+
onChangeOpened(openedFilters.filter(f => f !== filterName));
|
|
214
|
+
}, value: getFilterValue(type, filters, filterName), onValueChange: value => onChangeFilters({ ...filters, [filterName]: value }) })))
|
|
215
|
+
.with({ type: "checkbox" }, ({ type, label, items, checkAllLabel, submitText }) => (_jsx(FilterCheckbox, { label: label, items: items, checkAllLabel: checkAllLabel, autoOpen: lastOpenedFilter === filterName, applyButtonLabel: submitText, value: getFilterValue(type, filters, filterName), onValueChange: value => onChangeFilters({ ...filters, [filterName]: value }), onPressRemove: () => {
|
|
216
|
+
onChangeFilters({ ...filters, [filterName]: undefined });
|
|
217
|
+
onChangeOpened(openedFilters.filter(f => f !== filterName));
|
|
218
|
+
} })))
|
|
219
|
+
.with({ type: "date" }, ({ type, label, noValueText, submitText, dateFormat, rifmProps, validate }) => (_jsx(FilterDate, { label: label, noValueText: noValueText, submitText: submitText, autoOpen: lastOpenedFilter === filterName, dateFormat: dateFormat, rifmProps: rifmProps, validate: validate, initialValue: getFilterValue(type, filters, filterName), onSave: value => onChangeFilters({ ...filters, [filterName]: value }), onPressRemove: () => {
|
|
220
|
+
onChangeFilters({ ...filters, [filterName]: undefined });
|
|
221
|
+
onChangeOpened(openedFilters.filter(f => f !== filterName));
|
|
222
|
+
} })))
|
|
223
|
+
.with({ type: "input" }, ({ type, label, placeholder, noValueText, submitText, validate }) => (_jsx(FilterInput, { label: label, placeholder: placeholder, noValueText: noValueText, submitText: submitText, autoOpen: lastOpenedFilter === filterName, validate: validate, initialValue: getFilterValue(type, filters, filterName), onSave: value => onChangeFilters({ ...filters, [filterName]: value }), onPressRemove: () => {
|
|
224
|
+
onChangeFilters({ ...filters, [filterName]: undefined });
|
|
225
|
+
onChangeOpened(openedFilters.filter(f => f !== filterName));
|
|
226
|
+
} })))
|
|
227
|
+
.exhaustive() }, filterName));
|
|
228
|
+
}) }));
|
|
229
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ## FixedListView
|
|
3
|
+
*
|
|
4
|
+
* The FixedListView is a component designed to render big amounts of tabular data.
|
|
5
|
+
*
|
|
6
|
+
* For usability, the data can be display in three types of columns:
|
|
7
|
+
*
|
|
8
|
+
* - Sticked to start columns (usually the main identifier, always visible)
|
|
9
|
+
* - Center columns (scrollable columns, with additional information)
|
|
10
|
+
* - Sticked to end columns (so that some actions are always accesible at the end of each line)
|
|
11
|
+
*
|
|
12
|
+
* ┌────────────────────────────────────────────────────────────────────────────────────────┐
|
|
13
|
+
* │ ┌────────────────┐ ┌────────────────────────────────────────┐ ┌────────────────┐ │
|
|
14
|
+
* │ │ ╔════════════╗ │ │ ╔════════════════════════════════════╗ │ │ ╔════════════╗ │ │
|
|
15
|
+
* │ │ ║ Header ║ │ │ ║ Header ║ │ │ ║ Header ║ │ ▲ │
|
|
16
|
+
* │ │ ║ ║ │ │ ║◀──────────────────────────────────▶║ │ │ ║ ║ │ │ │
|
|
17
|
+
* │ │ ╚════════════╝ │ │ ╚════════════════════════════════════╝ │ │ ╚════════════╝ │ │ │
|
|
18
|
+
* │ │ │ │ │ │ │ │ │
|
|
19
|
+
* │ │ ┌───────────┐ │ │ ┌────────────────────────────────────┐ │ │ ┌────────────┐ │ │ │
|
|
20
|
+
* │ │ │ Cell A1 │──┼─┼▷│ Cell B1 ├─┼─┼─▷ Cell C1 │ │ │ │
|
|
21
|
+
* │ │ └───────────┘ │ │ └────────────────────────────────────┘ │ │ └────────────┘ │ │ │
|
|
22
|
+
* │ │ ┌───────────┐ │ │ ┌────────────────────────────────────┐ │ │ ┌────────────┐ │ │ │
|
|
23
|
+
* │ │ │ Cell A2 │──┼─┼▷│ Cell B2 │─┼─┼─▷ Cell C2 │ │ │ │
|
|
24
|
+
* │ │ └───────────┘ │ │ └────────────────────────────────────┘ │ │ └────────────┘ │ │ │
|
|
25
|
+
* │ │ │ │ │ │ │ │ │
|
|
26
|
+
* │ │ │ │ ◀────────────────────────────────────▶ │ │ │ ▼ │
|
|
27
|
+
* └─┴────────────────┴─┴────────────────────────────────────────┴─┴────────────────┴───────┘
|
|
28
|
+
*
|
|
29
|
+
* ╔════╗
|
|
30
|
+
* ║ ║ Sticky
|
|
31
|
+
* ╚════╝
|
|
32
|
+
* ◀────▶ Scrollable
|
|
33
|
+
* ─────▷ Emulated tab order
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
import { ReactElement, ReactNode } from "react";
|
|
37
|
+
import { IconName } from "./Icon";
|
|
38
|
+
export type ColumnTitleConfig<ExtraInfo> = {
|
|
39
|
+
title: string;
|
|
40
|
+
extraInfo: ExtraInfo;
|
|
41
|
+
id: string;
|
|
42
|
+
};
|
|
43
|
+
export type ColumnCellConfig<T, ExtraInfo> = {
|
|
44
|
+
columnId: string;
|
|
45
|
+
item: T;
|
|
46
|
+
index: number;
|
|
47
|
+
extraInfo: ExtraInfo;
|
|
48
|
+
isHovered: boolean;
|
|
49
|
+
};
|
|
50
|
+
export type LinkConfig<T, ExtraInfo> = {
|
|
51
|
+
item: T;
|
|
52
|
+
index: number;
|
|
53
|
+
extraInfo: ExtraInfo;
|
|
54
|
+
};
|
|
55
|
+
export type ColumnConfig<T, ExtraInfo> = {
|
|
56
|
+
id: string;
|
|
57
|
+
width: number;
|
|
58
|
+
title: string;
|
|
59
|
+
renderTitle: (props: ColumnTitleConfig<ExtraInfo>) => ReactNode;
|
|
60
|
+
renderCell: (props: ColumnCellConfig<T, ExtraInfo>) => ReactNode;
|
|
61
|
+
};
|
|
62
|
+
type Mode = "tile" | "plain";
|
|
63
|
+
export type FixedListViewProps<T, ExtraInfo> = {
|
|
64
|
+
mode?: Mode;
|
|
65
|
+
data: T[];
|
|
66
|
+
keyExtractor: (item: T, index: number) => string;
|
|
67
|
+
highlightedRowId?: string;
|
|
68
|
+
headerHeight: number;
|
|
69
|
+
rowHeight: number;
|
|
70
|
+
rowVerticalSpacing: number;
|
|
71
|
+
extraInfo: ExtraInfo;
|
|
72
|
+
stickedToStartColumns?: ColumnConfig<T, ExtraInfo>[];
|
|
73
|
+
columns: ColumnConfig<T, ExtraInfo>[];
|
|
74
|
+
stickedToEndColumns?: ColumnConfig<T, ExtraInfo>[];
|
|
75
|
+
renderThreshold?: number;
|
|
76
|
+
onEndReached?: () => void;
|
|
77
|
+
onEndReachedThresholdPx?: number;
|
|
78
|
+
getRowLink?: (config: LinkConfig<T, ExtraInfo>) => ReactElement | undefined;
|
|
79
|
+
renderEmptyList?: () => ReactNode;
|
|
80
|
+
loading?: {
|
|
81
|
+
isLoading: boolean;
|
|
82
|
+
count: number;
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
export declare const FixedListView: <T, ExtraInfo>({ data: originalData, mode, keyExtractor, highlightedRowId, rowHeight, rowVerticalSpacing, headerHeight, renderThreshold, stickedToStartColumns: initialStickedToStartColumns, columns: initialColumns, stickedToEndColumns: initialStickedToEndColumns, extraInfo, onEndReached, onEndReachedThresholdPx, getRowLink, renderEmptyList, loading, }: FixedListViewProps<T, ExtraInfo>) => JSX.Element;
|
|
86
|
+
type PlaceholderProps = {
|
|
87
|
+
count: number;
|
|
88
|
+
rowHeight: number;
|
|
89
|
+
rowVerticalSpacing: number;
|
|
90
|
+
groupHeaderHeight?: number;
|
|
91
|
+
headerHeight?: number;
|
|
92
|
+
paddingHorizontal?: number;
|
|
93
|
+
};
|
|
94
|
+
export declare const FixedListViewPlaceholder: ({ count, rowHeight, rowVerticalSpacing, groupHeaderHeight, headerHeight, paddingHorizontal, }: PlaceholderProps) => JSX.Element;
|
|
95
|
+
export declare const PlainListViewPlaceholder: ({ count, rowHeight, rowVerticalSpacing, groupHeaderHeight, headerHeight, paddingHorizontal, }: PlaceholderProps) => JSX.Element;
|
|
96
|
+
type EmptyProps = {
|
|
97
|
+
icon: IconName;
|
|
98
|
+
borderedIcon?: boolean;
|
|
99
|
+
title?: string;
|
|
100
|
+
subtitle?: ReactNode;
|
|
101
|
+
children?: ReactNode;
|
|
102
|
+
};
|
|
103
|
+
export declare const FixedListViewEmpty: ({ icon, borderedIcon, title, subtitle, children, }: EmptyProps) => JSX.Element;
|
|
104
|
+
export {};
|