🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

react-native-surveys

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-native-surveys - npm Package Compare versions

Comparing version
1.1.1
to
1.1.3
+85
Forms/blocks/Date.js
import React, { memo, useState, useEffect } from "react";
import { View, StyleSheet } from "react-native";
import { colors, MAX_FORM_WIDTH } from "../theme";
import QuestionHeader from "../components/QuestionHeader";
import DatePicker from "../components/DatePicker";
import { getDayFormat, returnTimeZone } from "../components/DatePicker/time";
import {
DATE_HOURS_CONFIG,
DEFAULT_DATE_CONFIG
} from "../components/DatePicker/dataSource";
const DatePickerBlock = ({
block,
form,
isPreview,
currentPageIndex,
blockIndex,
allBlocks
}) => {
const [date, updateDate] = useState(block.time || new Date().getTime());
const { color = colors.main, textColor = colors.primary } = form;
const { hours } = block;
const timezone = block.timezone || returnTimeZone();
useEffect(() => {
const pickedDate = block.time || new Date().getTime();
block.value = getDayFormat(new Date(pickedDate), hours, timezone);
block.time = pickedDate;
block.timezone = timezone;
updateDate(pickedDate);
}, [block, hours, timezone]);
const _onDateSelect = date => {
const pickedDate = date.getTime();
block.value = getDayFormat(date, hours, timezone);
block.time = pickedDate;
block.timezone = timezone;
updateDate(pickedDate);
};
return React.createElement(
View,
{
style: styles.container
},
React.createElement(QuestionHeader, {
form: form,
block: block,
currentPageIndex: currentPageIndex,
blockIndex: blockIndex,
allBlocks: allBlocks
}),
React.createElement(
View,
{
style: styles.inputContainer
},
React.createElement(DatePicker, {
value: new Date(date),
onChange: _onDateSelect,
dateConfig: hours ? DATE_HOURS_CONFIG : DEFAULT_DATE_CONFIG,
color: color,
textColor: textColor,
isPreview: isPreview
})
)
);
};
const styles = StyleSheet.create({
container: {
display: "flex",
flexDirection: "column",
alignItems: "center"
},
inputContainer: {
display: "flex",
width: "100%",
backgroundColor: "transparent",
alignItems: "flex-start",
maxWidth: MAX_FORM_WIDTH,
paddingHorizontal: 12,
paddingVertical: 24
}
});
export default memo(DatePickerBlock);
export const DEFAULT_DATE_CONFIG = {
year: {
format: "YYYY",
caption: "Year",
step: 1
},
month: {
format: "M",
caption: "Month",
step: 1
},
date: {
format: "D",
caption: "Day",
step: 1
}
};
export const DATE_HOURS_CONFIG = {
year: {
format: "YYYY",
caption: "Year",
step: 1
},
month: {
format: "M",
caption: "Month",
step: 1
},
date: {
format: "D",
caption: "Day",
step: 1
},
hour: {
format: "hh",
caption: "Hour",
step: 1
},
minute: {
format: "mm",
caption: "Min",
step: 1
}
};
export const MONTHS_MAP = {
1: "Jan",
2: "Feb",
3: "Mar",
4: "Apr",
5: "May",
6: "Jun",
7: "Jul",
8: "Aug",
9: "Sept",
10: "Oct",
11: "Nov",
12: "Dec"
};
export const defaultProps = {
isPopup: true,
isOpen: false,
theme: "default",
value: new Date(),
min: new Date(1970, 0, 1),
max: new Date(2050, 0, 1),
showFooter: true,
showHeader: true,
showCaption: false,
dateConfig: {
year: {
format: "YYYY",
caption: "Year",
step: 1
},
month: {
format: "M",
caption: "Mon",
step: 1
},
date: {
format: "D",
caption: "Day",
step: 1
}
},
confirmText: "完成",
cancelText: "取消",
onChange: () => {},
onSelect: () => {},
onCancel: () => {}
};
export const dateConfigMap = {
year: {
format: "YYYY",
caption: "Year",
step: 1
},
month: {
format: "M",
caption: "Mon",
step: 1
},
date: {
format: "D",
caption: "Day",
step: 1
},
hour: {
format: "hh",
caption: "Hour",
step: 1
},
minute: {
format: "mm",
caption: "Min",
step: 1
},
second: {
format: "hh",
caption: "Sec",
step: 1
}
};
function _extends() {
_extends =
Object.assign ||
function(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
import React, { Component } from "react";
import { View, Text, StyleSheet, PanResponder, Platform } from "react-native";
import * as TimeUtil from "./time.js";
import { shallowEqual } from "./pureRender.js";
import { colors } from "../../theme";
import { MONTHS_MAP } from "./dataSource";
const DATE_HEIGHT = 40;
const DATE_LENGTH = 10;
const MIDDLE_INDEX = Math.floor(DATE_LENGTH / 2);
const MIDDLE_Y = -DATE_HEIGHT * MIDDLE_INDEX;
const isFunction = val =>
Object.prototype.toString.apply(val) === "[object Function]";
class DatePickerItem extends Component {
constructor(props) {
super(props);
this.touchY = 0;
this.translateY = 0;
this.currentIndex = MIDDLE_INDEX;
this.moveDateCount = 0;
this.state = {
translateY: MIDDLE_Y,
marginTop: (this.currentIndex - MIDDLE_INDEX) * DATE_HEIGHT
};
this.renderDatepickerItem = this.renderDatepickerItem.bind(this);
this.handleContentTouch = this.handleContentTouch.bind(this);
this._panResponder = PanResponder.create({
// Ask to be the responder:
onPanResponderTerminationRequest: () => false,
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
onPanResponderGrant: (evt, gestureState) => {
this.handleContentTouch(gestureState, "start");
},
onPanResponderMove: (evt, gestureState) => {
this.handleContentTouch(gestureState, "move");
},
onPanResponderRelease: (evt, gestureState) => {
this.handleContentTouch(gestureState, "end");
},
onPanResponderTerminate: (evt, gestureState) => {
this.handleContentTouch(gestureState, "end");
}
});
}
componentWillMount() {
this._iniDates(this.props.value);
}
componentWillReceiveProps(nextProps) {
if (nextProps.value.getTime() === this.props.value.getTime()) {
return;
}
this._iniDates(nextProps.value);
this.currentIndex = MIDDLE_INDEX;
this.setState({
translateY: MIDDLE_Y,
marginTop: (this.currentIndex - MIDDLE_INDEX) * DATE_HEIGHT
});
}
shouldComponentUpdate(nextProps, nextState) {
return (
nextProps.value.getTime() !== this.props.value.getTime() ||
!shallowEqual(nextState, this.state)
);
}
_iniDates(date) {
const typeName = this.props.type;
const dates = Array(...Array(DATE_LENGTH)).map((value, index) =>
TimeUtil[`next${typeName}`](
date,
(index - MIDDLE_INDEX) * this.props.step
)
);
this.setState({
dates
});
}
_updateDates(direction) {
const typeName = this.props.type;
const { dates } = this.state;
if (direction === 1) {
this.currentIndex++;
this.setState({
dates: [
...dates.slice(1),
TimeUtil[`next${typeName}`](dates[dates.length - 1], this.props.step)
],
marginTop: (this.currentIndex - MIDDLE_INDEX) * DATE_HEIGHT
});
} else {
this.currentIndex--;
this.setState({
dates: [
TimeUtil[`next${typeName}`](dates[0], -this.props.step),
...dates.slice(0, dates.length - 1)
],
marginTop: (this.currentIndex - MIDDLE_INDEX) * DATE_HEIGHT
});
}
}
_checkIsUpdateDates(direction, translateY) {
return direction === 1
? this.currentIndex * DATE_HEIGHT + DATE_HEIGHT / 2 < -translateY
: this.currentIndex * DATE_HEIGHT - DATE_HEIGHT / 2 > -translateY;
}
_moveToNext(direction) {
const date = this.state.dates[MIDDLE_INDEX];
const { max, min } = this.props;
if (
direction === -1 &&
date.getTime() < min.getTime() &&
this.moveDateCount
) {
this._updateDates(1);
} else if (
direction === 1 &&
date.getTime() > max.getTime() &&
this.moveDateCount
) {
this._updateDates(-1);
}
this._moveTo(this.refs.scroll, this.currentIndex);
}
_moveTo(obj, currentIndex) {
this.props.onSelect(this.state.dates[MIDDLE_INDEX]);
this.setState({
translateY: -currentIndex * DATE_HEIGHT
});
}
handleStart(event) {
this.touchY = event.dy;
this.translateY = this.state.translateY;
this.moveDateCount = 0;
}
handleMove(event) {
const touchY = event.dy;
const dir = touchY - this.touchY;
const translateY = this.translateY + dir;
const direction = dir > 0 ? -1 : 1;
const date = this.state.dates[MIDDLE_INDEX];
const { max, min } = this.props;
if (date.getTime() < min.getTime() || date.getTime() > max.getTime()) {
return;
}
if (this._checkIsUpdateDates(direction, translateY)) {
this.moveDateCount =
direction > 0 ? this.moveDateCount + 1 : this.moveDateCount - 1;
this._updateDates(direction);
}
this.setState({
translateY
});
}
handleEnd(event) {
const touchY = event.dy;
const dir = touchY - this.touchY;
const direction = dir > 0 ? -1 : 1;
this._moveToNext(direction);
}
handleContentTouch(event, type) {
if (this.props.isPreview) return;
if (type === "start") {
this.handleStart(event);
} else if (type === "move") {
this.handleMove(event);
} else if (type === "end") {
this.handleEnd(event);
}
}
renderDatepickerItem(date, index) {
let formatDate;
if (isFunction(this.props.format)) {
formatDate = this.props.format(date);
} else {
formatDate = TimeUtil.convertDate(date, this.props.format);
}
if (this.props.format === "M") {
formatDate = MONTHS_MAP[formatDate];
}
const textStyle = {
color: this.props.textColor
};
const cursor =
Platform.OS === "web"
? {
cursor: "pointer"
}
: {};
return React.createElement(
Text,
{
style: [textStyle, styles.text, cursor],
key: index
},
formatDate
);
}
render() {
const wheelStyle = {
borderTopColor: this.props.isPreview
? colors.buttonBorder
: this.props.color,
borderBottomColor: this.props.isPreview
? colors.buttonBorder
: this.props.color
};
const select =
Platform.OS === "web"
? {
userSelect: "none"
}
: {};
return React.createElement(
View,
{
style: styles.column
},
React.createElement(
View,
_extends({}, this._panResponder.panHandlers, {
style: styles.viewport
}),
React.createElement(
View,
{
style: [wheelStyle, styles.wheel, select]
},
React.createElement(
View,
{
style: {
transform: [
{
translateY: this.state.translateY
}
],
marginTop: this.state.marginTop
}
},
this.state.dates.map(this.renderDatepickerItem)
)
)
)
);
}
}
const styles = StyleSheet.create({
text: {
height: 40,
lineHeight: 40,
fontSize: 19,
display: "flex",
flexDirection: "column",
textAlign: "center"
},
wheel: {
position: "absolute",
height: 40,
top: "50%",
marginTop: -20,
width: "100%",
borderTopWidth: 1,
borderBottomWidth: 1,
borderStyle: "solid"
},
column: {
flex: 1,
marginHorizontal: 4
},
viewport: {
height: 200,
position: "relative",
overflow: "hidden"
}
});
export default DatePickerItem;
import React, { Component } from "react";
import { View, Text, StyleSheet } from "react-native";
import DatePickerItem from "./DatePickerItem.js";
import PureRender from "./pureRender.js";
import { nextDate } from "./time.js";
import { dateConfigMap, defaultProps } from "./dataSource";
const capitalize = ([first, ...rest]) => first.toUpperCase() + rest.join("");
const isArray = val =>
Object.prototype.toString.apply(val) === "[object Array]";
class DatePicker extends Component {
constructor(props) {
super(props);
this.state = {
value: nextDate(this.props.value)
};
this.handleDateSelect = this.handleDateSelect.bind(this);
}
componentWillReceiveProps(nextProps) {
// update value of state
const date = nextDate(nextProps.value);
if (date.getTime() !== this.state.value.getTime()) {
this.setState({
value: date
});
}
}
componentDidUpdate() {
const value = this.state.value;
const { min, max } = this.props;
if (value.getTime() > max.getTime()) {
this.setState({
value: max
});
}
if (value.getTime() < min.getTime()) {
this.setState({
value: min
});
}
}
shouldComponentUpdate(nextProps, nextState) {
const date = nextDate(nextState.value);
return (
date.getTime() !== this.state.value.getTime() ||
PureRender.shouldComponentUpdate(
nextProps,
nextState,
this.props,
this.state
)
);
}
handleDateSelect(value) {
this.setState(
{
value
},
() => {
this.props.onChange(value);
}
);
}
normalizeDateConfig(dataConfig) {
const configList = [];
if (isArray(dataConfig)) {
for (let i = 0; i < dataConfig.length; i++) {
const value = dataConfig[i];
if (typeof value === "string") {
const lowerCaseKey = value.toLocaleLowerCase();
configList.push({
...dateConfigMap[lowerCaseKey],
type: capitalize(lowerCaseKey)
});
}
}
} else {
for (const key in dataConfig) {
if (dataConfig.hasOwnProperty(key)) {
const lowerCaseKey = key.toLocaleLowerCase();
if (dateConfigMap.hasOwnProperty(lowerCaseKey)) {
configList.push({
...dateConfigMap[lowerCaseKey],
...dataConfig[key],
type: capitalize(lowerCaseKey)
});
}
}
}
}
return configList;
}
render() {
const { min, max, dateConfig, color, textColor, isPreview } = this.props;
const value = this.state.value;
const dataConfigList = this.normalizeDateConfig(dateConfig);
const captionStyle = {
color: textColor + "99"
};
return React.createElement(
View,
{
style: styles.container
},
React.createElement(
View,
{
style: styles.captionContainer
},
dataConfigList.map((item, index) =>
React.createElement(
Text,
{
key: index,
style: [styles.caption, captionStyle]
},
item.caption
)
)
),
React.createElement(
View,
{
style: styles.content
},
dataConfigList.map((item, index) =>
React.createElement(DatePickerItem, {
key: index,
value: value,
min: min,
max: max,
step: item.step,
type: item.type,
format: item.format,
color: color,
textColor: textColor,
onSelect: this.handleDateSelect,
isPreview: isPreview
})
)
)
);
}
}
const styles = StyleSheet.create({
container: {
width: "100%"
},
captionContainer: {
display: "flex",
flexDirection: "row",
paddingTop: 8,
paddingHorizontal: 4
},
caption: {
flex: 1,
marginHorizontal: 4,
textAlign: "center",
height: 30,
lineHeight: 30,
fontSize: 16
},
content: {
display: "flex",
flexDirection: "row",
paddingVertical: 8,
paddingHorizontal: 4
}
});
DatePicker.defaultProps = defaultProps;
export default DatePicker;
export function shallowEqual(prev, next) {
if (prev === next) return true;
const prevKeys = Object.keys(prev);
const nextKeys = Object.keys(next);
if (prevKeys.length !== nextKeys.length) return false;
return prevKeys.every(key => {
return prev.hasOwnProperty(key) && prev[key] === next[key];
});
}
function PureRender(Component) {
Component.prototype.shouldComponentUpdate = function(nextProps, nextState) {
return PureRender.shouldComponentUpdate(
nextProps,
nextState,
this.props,
this.state
);
};
}
PureRender.shouldComponentUpdate = function(
nextProps,
nextState,
preProps,
preState
) {
return (
!shallowEqual(preProps, nextProps) || !shallowEqual(preState, nextState)
);
};
export default PureRender;
function throwIfInvalidDate(date) {
if (Object.prototype.toString.call(date, null) !== "[object Date]") {
throw new Error("参数类型不对");
}
}
function daysInMonth(year, month) {
return new Date(year, month + 1, 0).getDate();
}
export function convertDate(date, format = "YYYY/MM/DD") {
let str = format;
const o = {
"M+": date.getMonth() + 1,
"D+": date.getDate(),
"h+": date.getHours(),
"m+": date.getMinutes(),
"s+": date.getSeconds()
};
if (/(Y+)/.test(format)) {
str = str.replace(
RegExp.$1,
date
.getFullYear()
.toString()
.substr(4 - RegExp.$1.length)
);
}
for (const k in o) {
// eslint-disable-line
if (new RegExp(`(${k})`).test(format)) {
str = str.replace(
RegExp.$1,
RegExp.$1.length === 1
? o[k]
: `00${o[k]}`.substr(o[k].toString().length)
);
}
}
return str;
}
export const getDayFormat = (date = new Date(), hasHours, timezone) => {
const day = dayOfWeekAsString(date.getDay());
const number = getNumberWithOrdinal(date.getDate());
const month = monthAsString(date.getMonth());
const year = date.getFullYear();
let hours = "";
let zone = "";
if (hasHours) {
hours = getHoursAndMinutes(date) + " ";
zone = timezone;
}
return hours + day + ", " + month + " " + number + " " + year + " " + zone;
};
function addZero(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
export function getHoursAndMinutes(d) {
if (!d) d = new Date();
const h = addZero(d.getHours());
const m = addZero(d.getMinutes());
return h + ":" + m;
}
function dayOfWeekAsString(dayIndex) {
return [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
][dayIndex];
}
function monthAsString(monthIndex) {
return [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
][monthIndex];
}
function getNumberWithOrdinal(n) {
const s = ["th", "st", "nd", "rd"],
v = n % 100;
return n + (s[(v - 20) % 10] || s[v] || s[0]);
}
export function returnTimeZone(date = "") {
if (date) {
if (date.split(",")[1]) return date.split(",")[1].substring(7);
}
return /\((.*)\)/.exec(new Date().toString())[1];
}
export function nextYear(now, index = 0) {
throwIfInvalidDate(now);
return new Date(
now.getFullYear() + index,
now.getMonth(),
now.getDate(),
now.getHours(),
now.getMinutes(),
now.getSeconds()
);
}
export function nextMonth(now, index = 0) {
throwIfInvalidDate(now);
const year = now.getFullYear();
const month = now.getMonth() + index;
const dayOfMonth = Math.min(now.getDate(), daysInMonth(year, month));
return new Date(
year,
month,
dayOfMonth,
now.getHours(),
now.getMinutes(),
now.getSeconds()
);
}
export function nextDate(now, index = 0) {
throwIfInvalidDate(now);
return new Date(now.getTime() + index * 24 * 60 * 60 * 1000);
}
export function nextHour(now, index = 0) {
throwIfInvalidDate(now);
return new Date(now.getTime() + index * 60 * 60 * 1000);
}
export function nextMinute(now, index = 0) {
throwIfInvalidDate(now);
return new Date(now.getTime() + index * 60 * 1000);
}
export function nextSecond(now, index = 0) {
throwIfInvalidDate(now);
return new Date(now.getTime() + index * 1000);
}
+12
-12

@@ -12,2 +12,3 @@ import React from "react";

import FilesUploadMobile from "./FilesUpload/Mobile";
import Date from "./Date";
export function clearFormValues(form) {

@@ -41,2 +42,10 @@ const pages = form.pages || [];

}
if (block.time) {
delete block.time;
}
if (block.timezone) {
delete block.timezone;
}
}

@@ -70,8 +79,2 @@ }

case "video":
return "Video";
case "iframe":
return "IFrame";
case "description":

@@ -226,8 +229,2 @@ return "Description";

case "video":
return "WATCH VIDEO BELOW";
case "iframe":
return "VISIT PAGE BELOW";
default:

@@ -289,2 +286,5 @@ return "";

case "date":
return React.createElement(Date, props);
case "files":

@@ -291,0 +291,0 @@ return Platform.OS === "web"

@@ -93,3 +93,4 @@ import React, { memo, useState } from "react";

extraScrollHeight: 120,
enableOnAndroid: true
enableOnAndroid: true,
bounces: false
},

@@ -96,0 +97,0 @@ questionsCount <= 0 &&

@@ -21,4 +21,2 @@ import React, { Fragment, memo } from "react";

let questionNumber = blockIndex + 1;
const hideQuestionsNumber =
type === "description" ? true : form.hideQuestionsNumber;

@@ -48,5 +46,2 @@ for (let i = 0; i < currentPageIndex; i++) {

};
const numberStyle = {
color: color || colors.main
};
return React.createElement(

@@ -70,13 +65,2 @@ Fragment,

},
!hideQuestionsNumber &&
React.createElement(
Text,
{
style: [numberStyle, styles.questionNumber]
},
"Q",
questionNumber,
".",
" "
),
question,

@@ -129,8 +113,2 @@ " ",

},
questionNumber: {
fontSize: 13,
fontWeight: "bold",
marginRight: 4,
marginLeft: -4
},
required: {

@@ -137,0 +115,0 @@ color: colors.required,

@@ -39,3 +39,3 @@ import * as React from "react";

if (window.ReactNativeWebView) {
if (window.ReactNativeWebView || window.INTERCOM) {
top = 20;

@@ -42,0 +42,0 @@ }

@@ -49,5 +49,9 @@ import React, { useState, memo, Fragment, useEffect } from "react";

useEffect(() => {
if (window.INTERCOM_MESSENGER_SHEET_LIBRARY) {
window.INTERCOM_MESSENGER_SHEET_LIBRARY.setTitle(label || "NativeForms");
}
if (!isPreview && !isTemplate && !livePreview && !editMode) {
if (window && window.document) {
window.document.title = label || "Forms.com";
window.document.title = label || "NativeForms";
}

@@ -96,2 +100,3 @@ }

form.sourceURL = getParentURL() || "";
form.intercom = window.INTERCOM || false;
form.platform =

@@ -98,0 +103,0 @@ Platform.OS === "web"

{
"name": "react-native-surveys",
"version": "1.1.1",
"version": "1.1.3",
"description": "Build your own forms, surveys and polls for your React Native apps.",

@@ -5,0 +5,0 @@ "main": "index.js",