@draftbit/core 42.1.5 → 42.1.7-71d4c6.1

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 (127) hide show
  1. package/LICENSE +21 -0
  2. package/lib/commonjs/components/DatePicker/DatePicker.js +6 -1
  3. package/lib/commonjs/components/DatePicker/DatePicker.js.map +1 -1
  4. package/lib/commonjs/components/DatePicker/DatePickerComponentType.js +2 -0
  5. package/lib/commonjs/components/Divider.js +18 -5
  6. package/lib/commonjs/components/Divider.js.map +1 -1
  7. package/lib/commonjs/components/Elevation.js +14 -3
  8. package/lib/commonjs/components/Elevation.js.map +1 -1
  9. package/lib/commonjs/components/Justification.js +3 -0
  10. package/lib/commonjs/components/Picker/PickerComponent.android.js +4 -1
  11. package/lib/commonjs/components/Picker/PickerComponent.android.js.map +1 -1
  12. package/lib/commonjs/components/Picker/PickerComponent.web.js +4 -1
  13. package/lib/commonjs/components/Picker/PickerComponent.web.js.map +1 -1
  14. package/lib/commonjs/components/Picker/PickerTypes.js +3 -0
  15. package/lib/commonjs/components/Portal/PortalHost.js.map +1 -1
  16. package/lib/commonjs/components/ResizeMode.js +3 -0
  17. package/lib/module/components/DatePicker/DatePicker.js +6 -1
  18. package/lib/module/components/DatePicker/DatePicker.js.map +1 -1
  19. package/lib/module/components/DatePicker/DatePickerComponentType.js +1 -1
  20. package/lib/module/components/Justification.js +1 -1
  21. package/lib/module/components/Picker/PickerComponent.android.js +4 -1
  22. package/lib/module/components/Picker/PickerComponent.android.js.map +1 -1
  23. package/lib/module/components/Picker/PickerComponent.web.js +4 -1
  24. package/lib/module/components/Picker/PickerComponent.web.js.map +1 -1
  25. package/lib/module/components/Picker/PickerTypes.js +1 -1
  26. package/lib/module/components/ResizeMode.js +1 -1
  27. package/package.json +3 -2
  28. package/src/Provider.js +9 -0
  29. package/src/components/Accordion/AccordionGroup.js +94 -0
  30. package/src/components/Accordion/AccordionItem.js +48 -0
  31. package/src/components/Accordion/index.js +2 -0
  32. package/src/components/ActionSheet/ActionSheet.js +57 -0
  33. package/src/components/ActionSheet/ActionSheetCancel.js +28 -0
  34. package/src/components/ActionSheet/ActionSheetItem.js +49 -0
  35. package/src/components/ActionSheet/index.js +3 -0
  36. package/src/components/AnimatedCircularProgress.js +43 -0
  37. package/src/components/AspectRatio.js +18 -0
  38. package/src/components/AvatarEdit.js +67 -0
  39. package/src/components/Button.js +187 -0
  40. package/src/components/Card.js +109 -0
  41. package/src/components/CardBlock.js +176 -0
  42. package/src/components/CardContainer.js +171 -0
  43. package/src/components/CardContainerRating.js +203 -0
  44. package/src/components/CardContainerShortImage.js +151 -0
  45. package/src/components/CardInline.js +87 -0
  46. package/src/components/Carousel.js +85 -0
  47. package/src/components/Checkbox/Checkbox.js +114 -0
  48. package/src/components/Checkbox/CheckboxGroup.js +46 -0
  49. package/src/components/Checkbox/CheckboxRow.js +109 -0
  50. package/src/components/Checkbox/context.js +14 -0
  51. package/src/components/Checkbox/index.js +3 -0
  52. package/src/components/CircleImage.js +32 -0
  53. package/src/components/CircularProgress.js +78 -0
  54. package/src/components/Config.js +63 -0
  55. package/src/components/Container.js +73 -0
  56. package/src/components/DatePicker/DatePicker.js +379 -0
  57. package/src/components/DatePicker/DatePicker.tsx +7 -1
  58. package/src/components/DatePicker/DatePickerComponent.js +13 -0
  59. package/src/components/DatePicker/DatePickerComponent.web.js +30 -0
  60. package/src/components/DatePicker/DatePickerComponentType.js +1 -0
  61. package/src/components/DeprecatedButton.js +201 -0
  62. package/src/components/DeprecatedCardWrapper.js +18 -0
  63. package/src/components/DeprecatedFAB.js +261 -0
  64. package/src/components/Divider.js +39 -0
  65. package/src/components/Elevation.js +20 -0
  66. package/src/components/FAB.js +82 -0
  67. package/src/components/FieldSearchBarFull.js +92 -0
  68. package/src/components/FormRow.js +19 -0
  69. package/src/components/Header.js +44 -0
  70. package/src/components/HeaderLarge.js +35 -0
  71. package/src/components/HeaderMedium.js +61 -0
  72. package/src/components/HeaderOverline.js +61 -0
  73. package/src/components/IconButton.js +65 -0
  74. package/src/components/Image.js +62 -0
  75. package/src/components/Justification.js +1 -0
  76. package/src/components/Layout.js +245 -0
  77. package/src/components/Picker/Picker.js +204 -0
  78. package/src/components/Picker/PickerComponent.android.js +68 -0
  79. package/src/components/Picker/PickerComponent.android.tsx +6 -1
  80. package/src/components/Picker/PickerComponent.ios.js +72 -0
  81. package/src/components/Picker/PickerComponent.web.js +68 -0
  82. package/src/components/Picker/PickerComponent.web.tsx +6 -1
  83. package/src/components/Picker/PickerTypes.js +1 -0
  84. package/src/components/Portal/Portal.js +35 -0
  85. package/src/components/Portal/PortalConsumer.js +28 -0
  86. package/src/components/Portal/PortalHost.js +105 -0
  87. package/src/components/Portal/PortalManager.js +29 -0
  88. package/src/components/ProgressBar.js +218 -0
  89. package/src/components/ProgressCircle.js +121 -0
  90. package/src/components/ProgressIndicator.js +207 -0
  91. package/src/components/RadioButton/RadioButton.js +66 -0
  92. package/src/components/RadioButton/RadioButtonFieldGroup.js +17 -0
  93. package/src/components/RadioButton/RadioButtonGroup.js +43 -0
  94. package/src/components/RadioButton/RadioButtonRow.js +111 -0
  95. package/src/components/RadioButton/context.js +14 -0
  96. package/src/components/RadioButton/index.js +4 -0
  97. package/src/components/ResizeMode.js +1 -0
  98. package/src/components/Row.js +48 -0
  99. package/src/components/RowBodyIcon.js +83 -0
  100. package/src/components/RowHeadlineImageCaption.js +179 -0
  101. package/src/components/RowHeadlineImageIcon.js +113 -0
  102. package/src/components/ScreenContainer.js +35 -0
  103. package/src/components/Slider.js +114 -0
  104. package/src/components/StarRating.js +80 -0
  105. package/src/components/StepIndicator.js +346 -0
  106. package/src/components/Stepper.js +69 -0
  107. package/src/components/Surface.js +36 -0
  108. package/src/components/Switch.js +59 -0
  109. package/src/components/Text.js +232 -0
  110. package/src/components/TextField.js +552 -0
  111. package/src/components/TextInput.js +13 -0
  112. package/src/components/ToggleButton.js +75 -0
  113. package/src/components/Touchable.js +24 -0
  114. package/src/components/Touchable.web.js +2 -0
  115. package/src/components/Typography.js +36 -0
  116. package/src/components/useAuthState.js +31 -0
  117. package/src/constants.js +10 -0
  118. package/src/hooks.js +12 -0
  119. package/src/index.js +48 -0
  120. package/src/interfaces/Icon.js +8 -0
  121. package/src/styles/DarkTheme.js +26 -0
  122. package/src/styles/DefaultTheme.js +111 -0
  123. package/src/styles/fonts.js +62 -0
  124. package/src/styles/overlay.js +60 -0
  125. package/src/styles/shadow.js +51 -0
  126. package/src/theming.js +3 -0
  127. package/src/utilities.js +42 -0
@@ -0,0 +1,552 @@
1
+ import * as React from "react";
2
+ import { View, Animated, TextInput as NativeTextInput, StyleSheet, Text, I18nManager, } from "react-native";
3
+ import { withTheme } from "../theming";
4
+ import { GROUPS, COMPONENT_TYPES, FORM_TYPES, PROP_TYPES, FIELD_NAME, TEXT_INPUT_PROPS, Triggers, } from "@draftbit/types";
5
+ import { applyStyles, extractStyles } from "../utilities";
6
+ const AnimatedText = Animated.createAnimatedComponent(Text);
7
+ const FOCUS_ANIMATION_DURATION = 150;
8
+ const BLUR_ANIMATION_DURATION = 180;
9
+ const ICON_SIZE = 24;
10
+ class TextField extends React.Component {
11
+ static getDerivedStateFromProps(nextProps, prevState) {
12
+ return {
13
+ value: typeof nextProps.value !== "undefined"
14
+ ? nextProps.value
15
+ : prevState.value,
16
+ };
17
+ }
18
+ state = {
19
+ labeled: new Animated.Value(this.props.value || this.props.error ? 0 : 1),
20
+ focused: false,
21
+ placeholder: this.props.error ? this.props.placeholder : "",
22
+ labelLayout: {
23
+ measured: false,
24
+ width: 0,
25
+ },
26
+ };
27
+ componentDidMount() {
28
+ if (this.props.initialValue) {
29
+ this._handleChangeText(this.props.initialValue);
30
+ }
31
+ if (this.props.placeholder) {
32
+ this._minmizeLabel();
33
+ }
34
+ }
35
+ componentDidUpdate(prevProps, prevState) {
36
+ if (prevState.focused !== this.state.focused ||
37
+ prevState.value !== this.state.value) {
38
+ // The label should be minimized if the text input is focused, or has text
39
+ // In minimized mode, the label moves up and becomes small
40
+ if (this.state.value ||
41
+ this.state.focused ||
42
+ this.props.error ||
43
+ this.props.placeholder) {
44
+ this._minmizeLabel();
45
+ }
46
+ else {
47
+ this._restoreLabel();
48
+ }
49
+ }
50
+ if (prevState.focused !== this.state.focused ||
51
+ prevProps.label !== this.props.label) {
52
+ // Show placeholder text only if the input is focused, or has error, or there's no label
53
+ // We don't show placeholder if there's a label because the label acts as placeholder
54
+ // When focused, the label moves up, so we can show a placeholder
55
+ if (this.state.focused || this.props.error || !this.props.label) {
56
+ this._showPlaceholder();
57
+ }
58
+ else {
59
+ this._hidePlaceholder();
60
+ }
61
+ }
62
+ }
63
+ _timer = setTimeout(() => { }, 0);
64
+ componentWillUnmount() {
65
+ clearTimeout(this._timer);
66
+ }
67
+ _showPlaceholder = () => {
68
+ clearTimeout(this._timer);
69
+ // Set the placeholder in a delay to offset the label animation
70
+ // If we show it immediately, they'll overlap and look ugly
71
+ this._timer = setTimeout(() => this.setState({
72
+ placeholder: this.props.placeholder,
73
+ }), 50);
74
+ };
75
+ _hidePlaceholder = () => this.setState({
76
+ placeholder: "",
77
+ });
78
+ _restoreLabel = () => Animated.timing(this.state.labeled, {
79
+ toValue: 1,
80
+ duration: FOCUS_ANIMATION_DURATION,
81
+ useNativeDriver: true,
82
+ }).start();
83
+ _minmizeLabel = () => Animated.timing(this.state.labeled, {
84
+ toValue: 0,
85
+ duration: BLUR_ANIMATION_DURATION,
86
+ useNativeDriver: true,
87
+ }).start();
88
+ _handleFocus = () => {
89
+ if (this.props.disabled) {
90
+ return;
91
+ }
92
+ this.setState({ focused: true });
93
+ };
94
+ _handleBlur = () => {
95
+ if (this.props.disabled) {
96
+ return;
97
+ }
98
+ this.setState({ focused: false });
99
+ };
100
+ _handleChangeText = (value) => {
101
+ if (this.props.disabled) {
102
+ return;
103
+ }
104
+ this.setState({ value: value });
105
+ this.props.onChangeText && this.props.onChangeText(value);
106
+ };
107
+ toggleFocus() {
108
+ this.setState((prevState) => ({ focused: !prevState.focused }));
109
+ }
110
+ _root = undefined;
111
+ /**
112
+ * @internal
113
+ */
114
+ setNativeProps(args) {
115
+ return this._root && this._root.setNativeProps(args);
116
+ }
117
+ isFocused() {
118
+ return this._root && this._root.isFocused();
119
+ }
120
+ clear() {
121
+ return this._root && this._root.clear();
122
+ }
123
+ focus() {
124
+ return this._root && this._root.focus();
125
+ }
126
+ blur() {
127
+ return this._root && this._root.blur();
128
+ }
129
+ render() {
130
+ const { Icon, type = "underline", disabled = false, label, error = false, leftIconName, leftIconMode, rightIconName, assistiveText, multiline = false, style, theme: { colors, typography, roundness, disabledOpacity }, render = (props) => React.createElement(NativeTextInput, { ...props }), ...rest } = this.props;
131
+ const MINIMIZED_LABEL_Y_OFFSET = -(typography.caption.lineHeight + 4);
132
+ const OUTLINE_MINIMIZED_LABEL_Y_OFFSET = -(16 * 0.5 + 4);
133
+ const MAXIMIZED_LABEL_FONT_SIZE = typography.subtitle1.fontSize;
134
+ const MINIMIZED_LABEL_FONT_SIZE = typography.caption.fontSize;
135
+ const hasActiveOutline = this.state.focused || error;
136
+ let inputTextColor, activeColor, underlineColor, borderColor, placeholderColor, containerStyle, backgroundColor, inputStyle;
137
+ inputTextColor = colors.strong;
138
+ if (disabled) {
139
+ activeColor = colors.light;
140
+ placeholderColor = colors.light;
141
+ borderColor = "transparent";
142
+ underlineColor = "transparent";
143
+ backgroundColor = colors.divider;
144
+ }
145
+ else {
146
+ activeColor = error ? colors.error : colors.primary;
147
+ placeholderColor = borderColor = colors.light;
148
+ underlineColor = colors.light;
149
+ backgroundColor = colors.background;
150
+ }
151
+ if (rest.placeholderTextColor) {
152
+ placeholderColor = rest.placeholderTextColor;
153
+ }
154
+ const { lineHeight, ...subtitle1 } = typography.subtitle1;
155
+ inputStyle = {
156
+ paddingVertical: 0,
157
+ color: inputTextColor,
158
+ paddingLeft: leftIconName && leftIconMode === "inset"
159
+ ? ICON_SIZE + 12 + (type === "solid" ? 16 : 0)
160
+ : 0,
161
+ paddingRight: rightIconName ? ICON_SIZE + 16 + 4 : 12,
162
+ ...subtitle1,
163
+ };
164
+ if (!multiline) {
165
+ inputStyle.height = lineHeight;
166
+ }
167
+ let assistiveTextLeftMargin;
168
+ if (type === "underline") {
169
+ containerStyle = {
170
+ borderTopLeftRadius: roundness,
171
+ borderTopRightRadius: roundness,
172
+ paddingBottom: 12,
173
+ marginTop: 16,
174
+ };
175
+ if (leftIconName && leftIconMode === "outset") {
176
+ assistiveTextLeftMargin = ICON_SIZE + 8;
177
+ }
178
+ else {
179
+ assistiveTextLeftMargin = 0;
180
+ }
181
+ }
182
+ else {
183
+ containerStyle = {
184
+ borderRadius: roundness,
185
+ borderColor: hasActiveOutline ? activeColor : borderColor,
186
+ borderWidth: 1,
187
+ paddingTop: label ? 16 * 1.5 : 16,
188
+ paddingBottom: label ? 16 * 0.5 : 16,
189
+ opacity: disabled ? disabledOpacity : 1,
190
+ backgroundColor,
191
+ };
192
+ if (leftIconName && leftIconMode === "inset") {
193
+ assistiveTextLeftMargin = 16 + 4;
194
+ }
195
+ else if (leftIconName && leftIconMode === "outset") {
196
+ assistiveTextLeftMargin = ICON_SIZE + 8 + 12;
197
+ }
198
+ else {
199
+ assistiveTextLeftMargin = 12;
200
+ }
201
+ inputStyle.paddingHorizontal = 12;
202
+ }
203
+ if (leftIconName && leftIconMode === "outset") {
204
+ containerStyle.marginLeft = ICON_SIZE + 8;
205
+ }
206
+ let leftIconColor;
207
+ if (error) {
208
+ leftIconColor = colors.error;
209
+ }
210
+ else if (this.state.focused) {
211
+ leftIconColor = colors.primary;
212
+ }
213
+ else {
214
+ leftIconColor = colors.light;
215
+ }
216
+ const leftIconProps = {
217
+ size: 24,
218
+ color: leftIconColor,
219
+ name: leftIconName || "",
220
+ };
221
+ const leftIconStyle = {
222
+ position: "absolute",
223
+ marginTop: type === "solid"
224
+ ? MINIMIZED_LABEL_FONT_SIZE + 4
225
+ : leftIconMode === "outset"
226
+ ? 16
227
+ : 0,
228
+ };
229
+ const labelStyle = {
230
+ ...typography.subtitle1,
231
+ top: type === "solid" ? 16 : 0,
232
+ left: leftIconName && leftIconMode === "inset"
233
+ ? ICON_SIZE + (type === "solid" ? 16 : 12)
234
+ : 0,
235
+ transform: [
236
+ {
237
+ // Move label to top
238
+ translateY: this.state.labeled.interpolate({
239
+ inputRange: [0, 1],
240
+ outputRange: [
241
+ type === "solid"
242
+ ? OUTLINE_MINIMIZED_LABEL_Y_OFFSET
243
+ : MINIMIZED_LABEL_Y_OFFSET,
244
+ 0,
245
+ ],
246
+ }),
247
+ },
248
+ {
249
+ // Make label smaller
250
+ scale: this.state.labeled.interpolate({
251
+ inputRange: [0, 1],
252
+ outputRange: [
253
+ MINIMIZED_LABEL_FONT_SIZE / MAXIMIZED_LABEL_FONT_SIZE,
254
+ 1,
255
+ ],
256
+ }),
257
+ },
258
+ {
259
+ // Offset label scale since RN doesn't support transform origin
260
+ translateX: this.state.labeled.interpolate({
261
+ inputRange: [0, 1],
262
+ outputRange: [
263
+ -(1 - MINIMIZED_LABEL_FONT_SIZE / MAXIMIZED_LABEL_FONT_SIZE) *
264
+ (this.state.labelLayout.width / 2),
265
+ 0,
266
+ ],
267
+ }),
268
+ },
269
+ ],
270
+ };
271
+ const { textStyles } = extractStyles(style);
272
+ const inputStyles = applyStyles([
273
+ styles.input,
274
+ inputStyle,
275
+ type === "solid" ? { marginHorizontal: 12 } : {},
276
+ ], textStyles);
277
+ const { backgroundColor: bgColor, padding, paddingTop, paddingBottom, paddingLeft, paddingRight, borderRadius, borderWidth, borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, borderColor: borderCol, ...styleProp } = StyleSheet.flatten(style || {});
278
+ return (React.createElement(View, { style: [styles.container, styleProp] },
279
+ leftIconName && leftIconMode === "outset" ? (React.createElement(Icon, { ...leftIconProps, style: leftIconStyle })) : null,
280
+ React.createElement(View, { style: applyStyles([containerStyle], {
281
+ height: style?.height,
282
+ backgroundColor: bgColor,
283
+ padding,
284
+ paddingTop,
285
+ paddingBottom,
286
+ paddingLeft,
287
+ paddingRight,
288
+ borderRadius,
289
+ borderWidth,
290
+ borderTopWidth,
291
+ borderRightWidth,
292
+ borderBottomWidth,
293
+ borderLeftWidth,
294
+ borderColor: borderCol,
295
+ }) },
296
+ type === "underline" ? (
297
+ // When type === 'flat', render an underline
298
+ React.createElement(Animated.View, { style: [
299
+ styles.underline,
300
+ {
301
+ backgroundColor: bgColor ||
302
+ (error
303
+ ? colors.error
304
+ : this.state.focused
305
+ ? activeColor
306
+ : underlineColor),
307
+ // Underlines is thinner when input is not focused
308
+ transform: [{ scaleY: this.state.focused ? 1 : 0.5 }],
309
+ },
310
+ ] })) : null,
311
+ label ? (
312
+ // Position colored placeholder and gray placeholder on top of each other and crossfade them
313
+ // This gives the effect of animating the color, but allows us to use native driver
314
+ React.createElement(View, { pointerEvents: "none", style: [
315
+ StyleSheet.absoluteFill,
316
+ {
317
+ opacity:
318
+ // Hide the label in minimized state until we measure its width
319
+ this.state.value || this.state.focused
320
+ ? this.state.labelLayout.measured
321
+ ? 1
322
+ : 0
323
+ : 1,
324
+ },
325
+ ] },
326
+ React.createElement(AnimatedText, { onLayout: (e) => this.setState({
327
+ labelLayout: {
328
+ width: e.nativeEvent.layout.width,
329
+ measured: true,
330
+ },
331
+ }), style: [
332
+ styles.placeholder,
333
+ type === "solid" ? { paddingHorizontal: 12 } : {},
334
+ labelStyle,
335
+ {
336
+ color: placeholderColor,
337
+ opacity: this.state.labeled.interpolate({
338
+ inputRange: [0, 1],
339
+ outputRange: [hasActiveOutline ? 1 : 0, 0],
340
+ }),
341
+ },
342
+ ], numberOfLines: 1 }, label),
343
+ React.createElement(AnimatedText, { style: [
344
+ styles.placeholder,
345
+ type === "solid" ? { paddingHorizontal: 12 } : {},
346
+ labelStyle,
347
+ {
348
+ color: placeholderColor,
349
+ opacity: hasActiveOutline ? this.state.labeled : 1,
350
+ },
351
+ ], numberOfLines: 1 }, label))) : null,
352
+ leftIconName && leftIconMode === "inset" ? (React.createElement(Icon, { ...leftIconProps, style: {
353
+ ...leftIconStyle,
354
+ marginLeft: type === "solid" ? 16 : 0,
355
+ } })) : null,
356
+ render({
357
+ ref: (c) => {
358
+ this._root = c;
359
+ },
360
+ onChange: this._handleChangeText,
361
+ placeholder: label
362
+ ? this.state.placeholder
363
+ : this.props.placeholder,
364
+ placeholderTextColor: placeholderColor,
365
+ editable: !disabled,
366
+ selectionColor: activeColor,
367
+ multiline,
368
+ onFocus: this._handleFocus,
369
+ onBlur: this._handleBlur,
370
+ underlineColorAndroid: "transparent",
371
+ style: inputStyles,
372
+ ...rest,
373
+ value: this.state.value,
374
+ })),
375
+ rightIconName ? (React.createElement(Icon, { name: rightIconName, size: ICON_SIZE, color: colors.light, style: {
376
+ position: "absolute",
377
+ right: 16,
378
+ marginTop: type === "solid" ? MINIMIZED_LABEL_FONT_SIZE + 4 : 16,
379
+ } })) : null,
380
+ assistiveText ? (React.createElement(Text, { style: [
381
+ {
382
+ color: error ? colors.error : colors.light,
383
+ marginTop: 8,
384
+ marginLeft: assistiveTextLeftMargin,
385
+ },
386
+ ] }, assistiveText)) : null));
387
+ }
388
+ }
389
+ export default withTheme(TextField);
390
+ const styles = StyleSheet.create({
391
+ container: {
392
+ alignSelf: "stretch",
393
+ },
394
+ placeholder: {
395
+ position: "absolute",
396
+ left: 0,
397
+ },
398
+ underline: {
399
+ position: "absolute",
400
+ left: 0,
401
+ right: 0,
402
+ bottom: 0,
403
+ height: 2,
404
+ },
405
+ input: {
406
+ flexGrow: 1,
407
+ justifyContent: "center",
408
+ textAlignVertical: "center",
409
+ margin: 0,
410
+ textAlign: I18nManager.isRTL ? "right" : "left",
411
+ },
412
+ });
413
+ const SEED_DATA_PROPS = {
414
+ ...TEXT_INPUT_PROPS,
415
+ label: {
416
+ group: GROUPS.data,
417
+ label: "Label",
418
+ description: "The label to be displayed on the text field",
419
+ formType: FORM_TYPES.string,
420
+ propType: PROP_TYPES.STRING,
421
+ defaultValue: null,
422
+ editable: true,
423
+ required: true,
424
+ },
425
+ assistiveText: {
426
+ group: GROUPS.basic,
427
+ label: "Assistive text",
428
+ description: "Helper text to display below the input",
429
+ formType: FORM_TYPES.string,
430
+ propType: PROP_TYPES.STRING,
431
+ defaultValue: null,
432
+ editable: true,
433
+ required: false,
434
+ },
435
+ error: {
436
+ group: GROUPS.data,
437
+ label: "Error",
438
+ description: "Whether the input should display the error state",
439
+ formType: FORM_TYPES.boolean,
440
+ propType: PROP_TYPES.BOOLEAN,
441
+ defaultValue: null,
442
+ editable: true,
443
+ required: false,
444
+ },
445
+ leftIconName: {
446
+ group: GROUPS.basic,
447
+ label: "Left icon name",
448
+ description: "The icon to display on the left",
449
+ formType: FORM_TYPES.icon,
450
+ propType: PROP_TYPES.ASSET,
451
+ defaultValue: null,
452
+ editable: true,
453
+ required: false,
454
+ },
455
+ leftIconMode: {
456
+ group: GROUPS.basic,
457
+ label: "Left icon mode",
458
+ description: "The mode of the icon to display on the left. 'inset' or 'outset'.",
459
+ formType: FORM_TYPES.flatArray,
460
+ propType: PROP_TYPES.STRING,
461
+ defaultValue: null /* inset */,
462
+ options: ["inset", "outset"],
463
+ editable: true,
464
+ required: true,
465
+ },
466
+ rightIconName: {
467
+ group: GROUPS.basic,
468
+ label: "Right icon name",
469
+ description: "The icon to display on the right",
470
+ formType: FORM_TYPES.icon,
471
+ propType: PROP_TYPES.ASSET,
472
+ defaultValue: null,
473
+ editable: true,
474
+ required: false,
475
+ },
476
+ fieldName: {
477
+ ...FIELD_NAME,
478
+ handlerPropName: "onChangeText",
479
+ defaultValue: "textFieldValue",
480
+ },
481
+ };
482
+ const SEED_DATA_TRIGGERS = [Triggers.OnChangeText];
483
+ export const SEED_DATA = [
484
+ {
485
+ name: "Text Field",
486
+ tag: "TextField",
487
+ description: "A text input with a solid border or underline",
488
+ category: COMPONENT_TYPES.input,
489
+ preview_image_url: "{CLOUDINARY_URL}/Textfield.png",
490
+ supports_list_render: false,
491
+ triggers: SEED_DATA_TRIGGERS,
492
+ props: {
493
+ ...SEED_DATA_PROPS,
494
+ type: {
495
+ label: "Appearance",
496
+ description: "Type of Datepicker",
497
+ formType: FORM_TYPES.flatArray,
498
+ propType: PROP_TYPES.STRING,
499
+ defaultValue: "solid",
500
+ options: ["solid", "underline"],
501
+ editable: true,
502
+ required: true,
503
+ group: GROUPS.basic,
504
+ },
505
+ secureTextEntry: {
506
+ group: GROUPS.basic,
507
+ label: "Password field",
508
+ description: "If true, this turns the field into a password field, hiding the text",
509
+ formType: FORM_TYPES.boolean,
510
+ propType: PROP_TYPES.BOOLEAN,
511
+ defaultValue: null,
512
+ editable: true,
513
+ required: false,
514
+ },
515
+ },
516
+ layout: {},
517
+ },
518
+ {
519
+ name: "Text Area",
520
+ tag: "TextField",
521
+ description: "A text area with a solid border or underline",
522
+ category: COMPONENT_TYPES.input,
523
+ preview_image_url: "{CLOUDINARY_URL}/TextArea.png",
524
+ supports_list_render: false,
525
+ triggers: SEED_DATA_TRIGGERS,
526
+ props: {
527
+ ...SEED_DATA_PROPS,
528
+ type: {
529
+ label: "Appearance",
530
+ description: "Type of Datepicker",
531
+ formType: FORM_TYPES.flatArray,
532
+ propType: PROP_TYPES.STRING,
533
+ defaultValue: "solid",
534
+ options: ["solid", "underline"],
535
+ editable: true,
536
+ required: true,
537
+ group: GROUPS.basic,
538
+ },
539
+ multiline: {
540
+ label: "Multiline",
541
+ description: "Multiline",
542
+ group: GROUPS.uncategorized,
543
+ formType: FORM_TYPES.boolean,
544
+ propType: PROP_TYPES.BOOLEAN,
545
+ defaultValue: true,
546
+ editable: false,
547
+ required: false,
548
+ },
549
+ },
550
+ layout: {},
551
+ },
552
+ ];
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import { TextInput as NativeTextInput } from "react-native";
3
+ import { usePrevious } from "../hooks";
4
+ const TextInput = ({ initialValue, onChangeText, ...props }) => {
5
+ const previousInitialValue = usePrevious(initialValue);
6
+ React.useEffect(() => {
7
+ if (initialValue !== previousInitialValue) {
8
+ onChangeText(initialValue);
9
+ }
10
+ }, [initialValue, previousInitialValue, onChangeText]);
11
+ return React.createElement(NativeTextInput, { onChangeText: onChangeText, ...props });
12
+ };
13
+ export default TextInput;
@@ -0,0 +1,75 @@
1
+ import * as React from "react";
2
+ import { withTheme } from "../theming";
3
+ import { GROUPS } from "@draftbit/types";
4
+ import { StyleSheet } from "react-native";
5
+ import IconButton from "./IconButton";
6
+ import { COMPONENT_TYPES, createIconProp, createBoolProp, createColorProp, createStaticNumberProp, createFieldNameProp, createIconSizeProp, createActionProp, Triggers, } from "@draftbit/types";
7
+ import { usePrevious } from "../hooks";
8
+ const ToggleButton = ({ Icon, icon, toggled = false, onPress = () => { }, initialValue, disabled = false, color = "primary", colorSecondary = "surface", borderColor = "divider", iconSize = 25, width = 50, height = 50, theme: { colors }, style, ...rest }) => {
9
+ const previousInitialValue = usePrevious(initialValue);
10
+ React.useEffect(() => {
11
+ if (initialValue !== previousInitialValue) {
12
+ onPress(initialValue);
13
+ }
14
+ }, [initialValue, previousInitialValue, onPress]);
15
+ return (React.createElement(IconButton, { Icon: Icon, icon: icon, size: iconSize, color: toggled ? colors[color] : colors[colorSecondary], onPress: () => onPress(!toggled), disabled: disabled, style: [
16
+ styles.mainContainer,
17
+ {
18
+ width,
19
+ height,
20
+ backgroundColor: toggled ? colors[colorSecondary] : colors[color],
21
+ borderColor: colors[borderColor],
22
+ },
23
+ style,
24
+ ], ...rest }));
25
+ };
26
+ const styles = StyleSheet.create({
27
+ mainContainer: {
28
+ borderWidth: 1,
29
+ },
30
+ });
31
+ export default withTheme(ToggleButton);
32
+ export const SEED_DATA = {
33
+ name: "Toggle Button",
34
+ tag: "ToggleButton",
35
+ category: COMPONENT_TYPES.button,
36
+ layout: {},
37
+ triggers: [Triggers.OnPress],
38
+ props: {
39
+ onPress: createActionProp(),
40
+ icon: createIconProp({
41
+ required: true,
42
+ }),
43
+ iconSize: createIconSizeProp(),
44
+ fieldName: createFieldNameProp({
45
+ defaultValue: false,
46
+ valuePropName: "toggled",
47
+ }),
48
+ disabled: createBoolProp({
49
+ label: "Disabled",
50
+ description: "Whether the button should be disabled",
51
+ group: GROUPS.basic,
52
+ }),
53
+ color: createColorProp({
54
+ group: GROUPS.basic,
55
+ }),
56
+ colorSecondary: createColorProp({
57
+ label: "Secondary Color",
58
+ group: GROUPS.basic,
59
+ }),
60
+ borderColor: createColorProp({
61
+ label: "Border Color",
62
+ group: GROUPS.basic,
63
+ }),
64
+ width: createStaticNumberProp({
65
+ label: "Width",
66
+ description: "Width",
67
+ defaultValue: 50,
68
+ }),
69
+ height: createStaticNumberProp({
70
+ label: "Height",
71
+ description: "Height",
72
+ defaultValue: 50,
73
+ }),
74
+ },
75
+ };
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ import { Pressable } from "react-native";
3
+ import { COMPONENT_TYPES, createActionProp, Triggers } from "@draftbit/types";
4
+ export default function Touchable({ children, disabled, onPress, style, ...props }) {
5
+ return (React.createElement(Pressable, { onPress: onPress, disabled: disabled, hitSlop: 8, style: ({ pressed }) => {
6
+ return [
7
+ {
8
+ opacity: pressed || disabled ? 0.75 : 1,
9
+ },
10
+ style,
11
+ ];
12
+ }, ...props }, children));
13
+ }
14
+ export const SEED_DATA = {
15
+ name: "Touchable",
16
+ tag: "Touchable",
17
+ description: "Simple button with no styles",
18
+ category: COMPONENT_TYPES.button,
19
+ layout: {},
20
+ triggers: [Triggers.OnPress],
21
+ props: {
22
+ onPress: createActionProp(),
23
+ },
24
+ };
@@ -0,0 +1,2 @@
1
+ import { TouchableOpacity } from "react-native";
2
+ export default TouchableOpacity;