@madeja-studio/telar
Version:
UI component library by Madeja Studio
120 lines (119 loc) • 3.27 kB
JavaScript
"use strict";
import { animated } from '@react-spring/native';
import * as Haptics from 'expo-haptics';
import { forwardRef, useImperativeHandle, useRef } from 'react';
import { PanResponder, Text, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { fade, push, useAnimation, withDrag } from "../../animation/index.js";
import tw from "../../tailwind/index.js";
import { useTheme } from "../../theme/ThemeContextProvider.js";
import Button from "../Button/index.js";
import { Column } from "../layout/index.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const SWIPE_OUT_THRESHOLD = -20;
const OUT_OF_SCREEN_POSITION = -200;
export const Toast = /*#__PURE__*/forwardRef(({
onClose,
subtitle,
title,
variant
}, ref) => {
const {
top
} = useSafeAreaInsets();
const {
theme
} = useTheme();
const {
animatedStyle,
animationStop,
api
} = useAnimation([fade({
from: 0,
to: 1
}), push({
from: OUT_OF_SCREEN_POSITION,
to: 0
})], {
hasEnterTransition: true
});
useImperativeHandle(ref, () => ({
close: () => new Promise(resolve => {
animationStop({
onResolve: () => resolve()
});
})
}));
const panResponder = useRef(PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: async (_ev, state) => {
await Haptics.impactAsync();
api.start({
to: {
translationY: Math.round(state.dy)
}
});
},
onPanResponderMove: (_ev, state) => {
api.set({
translationY: withDrag({
threshold: 50,
value: Math.round(state.dy)
})
});
},
onPanResponderRelease: (_ev, state) => {
if (state.dy < SWIPE_OUT_THRESHOLD) {
api.start({
onResolve: onClose,
to: {
translationY: OUT_OF_SCREEN_POSITION
}
});
} else {
api.start({
to: {
translationY: 0
}
});
}
}
})).current;
return /*#__PURE__*/_jsx(View, {
pointerEvents: "box-none",
style: [tw`absolute top-0 right-0 left-0 bottom-0 flex-1 z-20`, {
top
}],
children: /*#__PURE__*/_jsx(View, {
...panResponder.panHandlers,
children: /*#__PURE__*/_jsxs(animated.View, {
style: [tw`flex flex-row p-4 rounded-2xl mx-4`, {
backgroundColor: theme.toast.color[variant].background
}, animatedStyle],
children: [/*#__PURE__*/_jsxs(Column, {
style: tw`flex-1 mr-2`,
children: [/*#__PURE__*/_jsx(Text, {
style: [tw`font-bold`, {
color: theme.toast.color[variant].text
}],
children: title
}), /*#__PURE__*/_jsx(Text, {
style: [tw`mt-2`, {
color: theme.toast.color[variant].text
}],
children: subtitle
})]
}), /*#__PURE__*/_jsx(Button.Icon, {
icon: {
family: 'Feather',
name: 'x'
},
iconTint: theme.toast.color[variant].text,
onPress: onClose,
variant: "text"
})]
})
})
});
});
//# sourceMappingURL=Toast.js.map