@draftbit/core 43.4.19 → 43.4.20-dec262.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/lib/commonjs/components/Banner.js +182 -0
- package/lib/commonjs/components/Banner.js.map +1 -0
- package/lib/commonjs/components/DeprecatedCardWrapper.js +14 -2
- package/lib/commonjs/components/DeprecatedCardWrapper.js.map +1 -1
- package/lib/commonjs/components/DeprecatedFAB.js +20 -4
- package/lib/commonjs/components/DeprecatedFAB.js.map +1 -1
- package/lib/commonjs/components/Divider.js +3 -13
- package/lib/commonjs/components/Divider.js.map +1 -1
- package/lib/commonjs/components/Elevation.js +3 -14
- package/lib/commonjs/components/Elevation.js.map +1 -1
- package/lib/commonjs/index.js +8 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/mappings/Banner.js +39 -0
- package/lib/commonjs/mappings/Banner.js.map +1 -0
- package/lib/commonjs/mappings/RowHeadlineImageCaption.js.map +1 -1
- package/lib/module/components/Banner.js +159 -0
- package/lib/module/components/Banner.js.map +1 -0
- package/lib/module/components/StepIndicator.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mappings/Banner.js +30 -0
- package/lib/module/mappings/Banner.js.map +1 -0
- package/lib/typescript/src/components/Banner.d.ts +22 -0
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/mappings/Banner.d.ts +48 -0
- package/package.json +2 -2
- package/src/components/Banner.js +109 -0
- package/src/components/Banner.tsx +204 -0
- package/src/index.js +1 -0
- package/src/index.tsx +1 -0
- package/src/mappings/Banner.js +29 -0
- package/src/mappings/Banner.ts +37 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Text,
|
|
5
|
+
View,
|
|
6
|
+
ViewStyle,
|
|
7
|
+
StyleSheet,
|
|
8
|
+
StyleProp,
|
|
9
|
+
Animated,
|
|
10
|
+
} from "react-native";
|
|
11
|
+
import Surface from "./Surface";
|
|
12
|
+
import type { IconSlot } from "../interfaces/Icon";
|
|
13
|
+
import shadow from "../styles/shadow";
|
|
14
|
+
import { withTheme } from "../theming";
|
|
15
|
+
import type { Theme } from "../styles/DefaultTheme";
|
|
16
|
+
|
|
17
|
+
const ELEVATION = 1;
|
|
18
|
+
const DEFAULT_MAX_WIDTH = 960;
|
|
19
|
+
|
|
20
|
+
type Props = {
|
|
21
|
+
initiallyVisible: boolean;
|
|
22
|
+
dismissable: boolean;
|
|
23
|
+
buttonColor?: string;
|
|
24
|
+
icon?: string;
|
|
25
|
+
content: string;
|
|
26
|
+
contentStyle?: StyleProp<ViewStyle>;
|
|
27
|
+
style?: StyleProp<ViewStyle>;
|
|
28
|
+
ref?: React.RefObject<View>;
|
|
29
|
+
/**
|
|
30
|
+
* @optional
|
|
31
|
+
*/
|
|
32
|
+
theme: Theme;
|
|
33
|
+
} & IconSlot;
|
|
34
|
+
|
|
35
|
+
type NativeEvent = {
|
|
36
|
+
nativeEvent: {
|
|
37
|
+
layout: {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const Banner: React.FC<Props> = ({
|
|
47
|
+
initiallyVisible,
|
|
48
|
+
icon,
|
|
49
|
+
buttonColor,
|
|
50
|
+
content,
|
|
51
|
+
contentStyle,
|
|
52
|
+
dismissable,
|
|
53
|
+
style,
|
|
54
|
+
theme,
|
|
55
|
+
Icon,
|
|
56
|
+
...rest
|
|
57
|
+
}) => {
|
|
58
|
+
const [visible, setVisible] = React.useState(initiallyVisible);
|
|
59
|
+
|
|
60
|
+
React.useEffect(() => {
|
|
61
|
+
if (initiallyVisible) {
|
|
62
|
+
setVisible(true);
|
|
63
|
+
}
|
|
64
|
+
}, [initiallyVisible]);
|
|
65
|
+
|
|
66
|
+
const { current: position } = React.useRef<Animated.Value>(
|
|
67
|
+
new Animated.Value(visible ? 1 : 0)
|
|
68
|
+
);
|
|
69
|
+
const [layout, setLayout] = React.useState<{
|
|
70
|
+
height: number;
|
|
71
|
+
measured: boolean;
|
|
72
|
+
}>({
|
|
73
|
+
height: 0,
|
|
74
|
+
measured: false,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
React.useEffect(() => {
|
|
78
|
+
if (visible) {
|
|
79
|
+
// show
|
|
80
|
+
Animated.timing(position, {
|
|
81
|
+
duration: 250,
|
|
82
|
+
toValue: 1,
|
|
83
|
+
useNativeDriver: false,
|
|
84
|
+
}).start();
|
|
85
|
+
} else {
|
|
86
|
+
// hide
|
|
87
|
+
Animated.timing(position, {
|
|
88
|
+
duration: 200,
|
|
89
|
+
toValue: 0,
|
|
90
|
+
useNativeDriver: false,
|
|
91
|
+
}).start();
|
|
92
|
+
}
|
|
93
|
+
}, [visible, position]);
|
|
94
|
+
|
|
95
|
+
const handleLayout = ({ nativeEvent }: NativeEvent) => {
|
|
96
|
+
const { height } = nativeEvent.layout;
|
|
97
|
+
setLayout({ height, measured: true });
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// The banner animation has 2 parts:
|
|
101
|
+
// 1. Blank spacer element which animates its height to move the content
|
|
102
|
+
// 2. Actual banner which animates its translateY
|
|
103
|
+
// In initial render, we position everything normally and measure the height of the banner
|
|
104
|
+
// Once we have the height, we apply the height to the spacer and switch the banner to position: absolute
|
|
105
|
+
// We need this because we need to move the content below as if banner's height was being animated
|
|
106
|
+
// However we can't animated banner's height directly as it'll also resize the content inside
|
|
107
|
+
const height = Animated.multiply(position, layout.height);
|
|
108
|
+
|
|
109
|
+
const translateY = Animated.multiply(
|
|
110
|
+
Animated.add(position, -1),
|
|
111
|
+
layout.height
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<Surface
|
|
116
|
+
{...rest}
|
|
117
|
+
style={[styles.container, shadow(ELEVATION) as ViewStyle, style]}
|
|
118
|
+
>
|
|
119
|
+
<View style={[styles.wrapper, contentStyle]}>
|
|
120
|
+
<Animated.View style={{ height }} />
|
|
121
|
+
<Animated.View
|
|
122
|
+
onLayout={handleLayout}
|
|
123
|
+
style={[
|
|
124
|
+
layout.measured || !visible
|
|
125
|
+
? // If we have measured banner's height or it's invisible,
|
|
126
|
+
// Position it absolutely, the layout will be taken care of the spacer
|
|
127
|
+
[styles.absolute, { transform: [{ translateY }] }]
|
|
128
|
+
: // Otherwise position it normally
|
|
129
|
+
null,
|
|
130
|
+
!layout.measured && !visible
|
|
131
|
+
? // If we haven't measured banner's height yet and it's invisible,
|
|
132
|
+
// hide it with opacity: 0 so user doesn't see it
|
|
133
|
+
{ opacity: 0 }
|
|
134
|
+
: null,
|
|
135
|
+
]}
|
|
136
|
+
>
|
|
137
|
+
<View
|
|
138
|
+
style={[styles.content, { marginBottom: dismissable ? 0 : 16 }]}
|
|
139
|
+
>
|
|
140
|
+
{icon ? (
|
|
141
|
+
<View style={styles.icon}>
|
|
142
|
+
<Icon name={icon} size={40} />
|
|
143
|
+
</View>
|
|
144
|
+
) : null}
|
|
145
|
+
<Text
|
|
146
|
+
style={[styles.message, { color: theme.colors.text }]}
|
|
147
|
+
accessibilityLiveRegion={visible ? "polite" : "none"}
|
|
148
|
+
accessibilityRole="alert"
|
|
149
|
+
>
|
|
150
|
+
{content}
|
|
151
|
+
</Text>
|
|
152
|
+
</View>
|
|
153
|
+
{dismissable ? (
|
|
154
|
+
<View style={styles.actions}>
|
|
155
|
+
<Button
|
|
156
|
+
color={buttonColor || theme.colors.primary}
|
|
157
|
+
title="Close"
|
|
158
|
+
onPress={() => setVisible(false)}
|
|
159
|
+
/>
|
|
160
|
+
</View>
|
|
161
|
+
) : null}
|
|
162
|
+
</Animated.View>
|
|
163
|
+
</View>
|
|
164
|
+
</Surface>
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const styles = StyleSheet.create({
|
|
169
|
+
container: {
|
|
170
|
+
elevation: ELEVATION,
|
|
171
|
+
},
|
|
172
|
+
wrapper: {
|
|
173
|
+
overflow: "hidden",
|
|
174
|
+
alignSelf: "center",
|
|
175
|
+
width: "100%",
|
|
176
|
+
maxWidth: DEFAULT_MAX_WIDTH,
|
|
177
|
+
},
|
|
178
|
+
absolute: {
|
|
179
|
+
position: "absolute",
|
|
180
|
+
top: 0,
|
|
181
|
+
width: "100%",
|
|
182
|
+
},
|
|
183
|
+
content: {
|
|
184
|
+
flexDirection: "row",
|
|
185
|
+
justifyContent: "flex-start",
|
|
186
|
+
marginHorizontal: 8,
|
|
187
|
+
marginTop: 16,
|
|
188
|
+
marginBottom: 0,
|
|
189
|
+
},
|
|
190
|
+
icon: {
|
|
191
|
+
margin: 8,
|
|
192
|
+
},
|
|
193
|
+
message: {
|
|
194
|
+
flex: 1,
|
|
195
|
+
margin: 8,
|
|
196
|
+
},
|
|
197
|
+
actions: {
|
|
198
|
+
flexDirection: "row",
|
|
199
|
+
justifyContent: "flex-end",
|
|
200
|
+
margin: 8,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
export default withTheme(Banner);
|
package/src/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { withTheme, ThemeProvider } from "./theming";
|
|
|
3
3
|
export { default as Provider } from "./Provider";
|
|
4
4
|
export { default as DefaultTheme } from "./styles/DefaultTheme";
|
|
5
5
|
export { Link } from "./components/Text";
|
|
6
|
+
export { default as Banner } from "./components/Banner";
|
|
6
7
|
export { ButtonSolid, ButtonOutline } from "./components/Button";
|
|
7
8
|
export { default as Avatar } from "./components/CircleImage";
|
|
8
9
|
export { default as AvatarEdit } from "./components/AvatarEdit";
|
package/src/index.tsx
CHANGED
|
@@ -4,6 +4,7 @@ export { default as Provider } from "./Provider";
|
|
|
4
4
|
export { default as DefaultTheme } from "./styles/DefaultTheme";
|
|
5
5
|
|
|
6
6
|
export { Link } from "./components/Text";
|
|
7
|
+
export { default as Banner } from "./components/Banner";
|
|
7
8
|
export { ButtonSolid, ButtonOutline } from "./components/Button";
|
|
8
9
|
export { default as Avatar } from "./components/CircleImage";
|
|
9
10
|
export { default as AvatarEdit } from "./components/AvatarEdit";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { COMPONENT_TYPES, createIconProp, createBoolProp, createColorProp, createTextProp, GROUPS, } from "@draftbit/types";
|
|
2
|
+
export const SEED_DATA = {
|
|
3
|
+
name: "Banner",
|
|
4
|
+
tag: "Banner",
|
|
5
|
+
category: COMPONENT_TYPES.button,
|
|
6
|
+
props: {
|
|
7
|
+
icon: createIconProp({
|
|
8
|
+
defaultValue: null,
|
|
9
|
+
required: false,
|
|
10
|
+
}),
|
|
11
|
+
content: createTextProp({
|
|
12
|
+
label: "Content",
|
|
13
|
+
description: "Banner text content",
|
|
14
|
+
}),
|
|
15
|
+
initiallyVisible: createBoolProp({
|
|
16
|
+
group: GROUPS.basic,
|
|
17
|
+
label: "Initially visible",
|
|
18
|
+
description: "Whether the banner should be visible",
|
|
19
|
+
}),
|
|
20
|
+
dismissable: createBoolProp({
|
|
21
|
+
group: GROUPS.basic,
|
|
22
|
+
label: "Dismissable",
|
|
23
|
+
description: "Whether the banner should be able to be closed",
|
|
24
|
+
}),
|
|
25
|
+
buttonColor: createColorProp({
|
|
26
|
+
label: "Button color",
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
COMPONENT_TYPES,
|
|
3
|
+
createIconProp,
|
|
4
|
+
createBoolProp,
|
|
5
|
+
createColorProp,
|
|
6
|
+
createTextProp,
|
|
7
|
+
GROUPS,
|
|
8
|
+
} from "@draftbit/types";
|
|
9
|
+
|
|
10
|
+
export const SEED_DATA = {
|
|
11
|
+
name: "Banner",
|
|
12
|
+
tag: "Banner",
|
|
13
|
+
category: COMPONENT_TYPES.button,
|
|
14
|
+
props: {
|
|
15
|
+
icon: createIconProp({
|
|
16
|
+
defaultValue: null,
|
|
17
|
+
required: false,
|
|
18
|
+
}),
|
|
19
|
+
content: createTextProp({
|
|
20
|
+
label: "Content",
|
|
21
|
+
description: "Banner text content",
|
|
22
|
+
}),
|
|
23
|
+
initiallyVisible: createBoolProp({
|
|
24
|
+
group: GROUPS.basic,
|
|
25
|
+
label: "Initially visible",
|
|
26
|
+
description: "Whether the banner should be visible",
|
|
27
|
+
}),
|
|
28
|
+
dismissable: createBoolProp({
|
|
29
|
+
group: GROUPS.basic,
|
|
30
|
+
label: "Dismissable",
|
|
31
|
+
description: "Whether the banner should be able to be closed",
|
|
32
|
+
}),
|
|
33
|
+
buttonColor: createColorProp({
|
|
34
|
+
label: "Button color",
|
|
35
|
+
}),
|
|
36
|
+
},
|
|
37
|
+
};
|