@99xt/first-born 中文文档教程

发布于 5年前 浏览 40 项目主页 更新于 3年前

first-born

first-born Logo

Getting Started

这些说明将为您提供一份出于开发和测试目的,项目在本地机器上启动并运行

Prerequisites

此模块只能在 React Native 应用程序中使用。 要使用它,您需要一个安装了依赖项的 React Native 应用程序。 还需要将以下模块添加为开发依赖项。

  • create-react-class
  • react-native-vector-icons

Installing

要安装 first-born,请在终端中运行以下命令;

npm install --save @99xt/first-born

您还需要安装以下模块。

npm install --save create-react-class react-native-vector-icons

按照本指南react-native-vector-icons配置你的项目。

不需要其他步骤为每个平台(Android/iOS)单独配置first-born

Development Testing

要测试 repo,首先克隆它;

git clone https://github.com/99xt/first-born.git

移入文件夹;

cd first-born

安装依赖;

npm install

并运行测试脚本;

npm run test

Usage

像这样导入组件;

import { Button } from "@99xt/first-born";

Utils

Colors

ColorAndroidiOS
white#FFF#FFF
black#000#000
primary#486c86#486c86
secondary#8dd9d5#8dd9d5
error#e74c3c#e74c3c
inputGreyrgba(33, 33, 33, 0.5)rgba(33, 33, 33, 0.5)
darkGreyrgba(33, 33, 33, 0.87)rgba(33, 33, 33, 0.87)
lightGreyrgba(33, 33, 33, 0.4)rgba(33, 33, 33, 0.4)
overlayrgba(68, 68, 68, 0.6)rgba(68, 68, 68, 0.6)
secondaryBackgroundrgba(125, 167, 217, 0.2)#ecf8fa

Atoms

Text

<Text>Hello</Text>
Android

Android Text

iOS

iOS Text

您可以使用任何 文本属性 和以下内容:

PropDescriptionDefault
sizeSize of the text, picked from predefined sizes, according to underlying platform.'p'
boldIf text is bold or not.false
colorColor of the text.black
marginIf the text requires a margin or not.false
alignAlignment of text ('left', 'right', 'center')'left'
SizeAndroidiOS
h19634
h26028
h34824
h43422
h52420
h62017
p1616
callout1516
sub_heading1415
footnote1313
caption_big1212
caption_small1111

Icon

react-native-vector 中的所有图标组件(所有字体样式) -icons 被使用。

<Icon name='heart'/>
Android

安卓图标

iOS

iOS Icon

您可以使用任何 TouchableOpacity 属性 和以下内容:

PropDescriptionDefault
sizeSize of the icon.18
nameSimilar to the name attribute in react-native-vector-icons. Does not require the prefix md or ios for Ionicons.None
colorColor of the icon.white
typeType of the icon font style. ('zocial', 'octicon', 'material', 'material-community', 'ionicon', 'foundation', 'evilicon', 'entypo', 'font-awesome', 'simple-line-icon', 'feather', 'antdesign')white

Badge

仅接受 TextIcon 原子和 react-native Image

<Badge>
    <Text>+1</Text>
</Badge>
<Badge color="red">
    <Icon name="heart" />
</Badge>
Android

安卓徽章

iOS

iOS Badge

您可以使用任何 View 属性 和以下内容:

PropDescriptionDefault
colorColor of the badge.primary
outlineIf the badge has the outline style.false

Thumbnail

显示方形或圆形图像的图像组件。

<Thumbnail source={require("path/to/image.png")}/>

您可以使用任何 Image 属性 和以下内容:

PropDescriptionDefault
sizeSize of the image. ('small', 'medium', 'large', 'exlarge')'medium'
customSizeSize of the image, if it does not fit the above defined sizes.None
roundedIf the image is to be a circle.false
onEditProps to handle an image change of the thumbnail. You can use all Button atom properties.None

Button

只接受 TextIcon 原子和 react-native Image

<Button onPress={this.handleButtonClick} block >
    <Text>Click Me</Text>
</Button>
Android

安卓按钮

iOS

iOS Button

您可以使用任何 TouchableOpacity 属性 和以下内容:

PropDescriptionDefault
sizeSize of the button, picked from predefined sizes small, default and large.'default'
colorColor of the button.primary
roundedIf the button has rounded corners.false
blockIf the button has full width.false
oulineIf the button is transparent, but with a colored border and children.false
roundedIf the button is transparent, but with colored children.false

DatePicker

呈现一个 Text,当onPress 方法被触发。

<DatePicker onDateChange={this.handleDateChange} />
Android

Android 日期选择器

iOS

iOS Date Picker

你可以使用任何TextInput 属性 和以下内容:

PropDescriptionDefault
placeholderDisplay this string if value not selected yet. iOS only.'Select Date'
formatChosenDateUser defined function that returns a formatted date.None
onDateChangeUser defined function to run when selected date changes.None
defaultDateInitially picked date.None
minimumDateMinimum in date range.None
maximumDateMaximum in date range.None
modalTransparentIf DatePicker modal is transparent. iOS only.true
animationTypeType of entry/exit animation for DatePicker modal. iOS only.'fade'
localeLocale of DatePicker. iOS only.None
modeType of picker ('date', 'time').'date'
colorColor of the TextInput when in focus.primary
isValidUser defined validation function, that returns true for valid inputNone
errorMessageError message to display below input, if validation failsNone
roundedIf DatePicker style is rounded edges.false
underlineIf DatePicker style is an underline.false
defaultStyleIf DatePicker style is default as seen above.true
noStyleIf DatePicker has no framework defined style.false
styleCustom DatePicker inactive style. (Style object)None
activeStyleCustom DatePicker active style. (Style object)None
errorStyleCustom DatePicker error style. (Style object)None
errorColorColor of DatePicker when validation failserror

Input

<Input onChangeText={this.handleTextChange} placeholder="Name" />
Android

安卓输入

iOS

iOS Input

您可以使用任何 TextInput 属性 和以下内容:

PropDescriptionDefault
colorColor of the TextInput when in focus.primary
isValidUser defined validation function, that returns true for valid textNone
errorMessageError message to display below input, if validation failsNone
roundedIf Input style is rounded edges.false
underlineIf Input style is an underline.false
defaultStyleIf Input style is default as seen above.true
noStyleIf Input has no framework defined style.false
styleCustom Input inactive style. (Style object)None
activeStyleCustom Input active style. (Style object)None
errorStyleCustom Input error style. (Style object)None
errorColorColor of Input when validation failserror
iconLeftIcon Atom to render on the left of the InputNone
iconRightIcon Atom to render on the right of the InputNone

Picker

在 Android 中,显示下拉选择器。 在 iOS 中,呈现一个 Text,它在 onPress 方法被触发时显示一个选择器模式。

<Picker onValueChange={this.handleValueChange} selectedValue={this.state.pickerValue}>
    <Picker.Item value="1" label="1" />
    <Picker.Item value="2" label="2" />
    <Picker.Item value="3" label="3" />
</Picker>
Android

Android Picker

iOS

iOS Picker

您可以使用任何 Picker 属性 和以下内容:

PropDescriptionDefault
placeholderDisplay this string if value not selected yet. iOS only.'Select Option'
modalTransparentIf Picker modal is transparent. iOS only.true
animationTypeType of entry/exit animation for Picker modal. iOS only.'fade'
modeType of picker mode ('dialog', 'dropdown'). Android only.'dropdown'
colorColor of the TextInput when in focus.primary
isValidUser defined validation function, that returns true for valid inputNone
errorMessageError message to display below input, if validation failsNone
roundedIf Picker style is rounded edges.false
underlineIf Picker style is an underline.false
defaultStyleIf Picker style is default as seen above.true
noStyleIf Picker has no framework defined style.false
styleCustom Picker inactive style. (Style object)None
activeStyleCustom Picker active style. (Style object)None
errorStyleCustom Picker error style. (Style object)None
errorColorColor of Picker when validation failserror

TextArea

呈现一个 TextInput,高度随高度增加输入的文本。

<TextArea onChangeText={this.handleTextChange} placeholder="Description" />
Android

Android TextArea

iOS

iOS TextArea

您可以使用任何 TextInput 属性 和以下内容:

PropDescriptionDefault
colorColor of the TextInput when in focus.primary
isValidUser defined validation function, that returns true for valid textNone
errorMessageError message to display below input, if validation failsNone
underlineIf TextArea style is an underline.false
defaultStyleIf TextArea style is default as seen above.true
noStyleIf TextArea has no framework defined style.false
styleCustom TextArea inactive style. (Style object)None
activeStyleCustom TextArea active style. (Style object)None
errorStyleCustom TextArea error style. (Style object)None
errorColorColor of TextArea when validation failserror

Molecules

Form Elements

FormDatePicker

使用 Atom DatePicker

<FormDatePicker onDateChange={this.handleDateChange} label="Date" />
Android

Android 表单日期选择器

iOS

iOS 表单日期选择器

附加道具;

PropDescriptionDefault
labelLabel to display name of input. (Required)None
FormInput

使用 Atom Input

<FormInput onChangeText={this.handleTextChange} label="Name" />
Android

Android 表单输入

iOS

iOS 表单输入

附加道具;

PropDescriptionDefault
labelLabel to display name of input. (Required)None
FormPicker

使用 Atom Picker

<FormPicker onValueChange={this.handleValueChange} selectedValue={pickerValue} label="Number" data={pickerData} />
Android

Android 表单选择器

iOS

iOS 表单选择器

附加道具;

PropDescriptionDefault
labelLabel to display name of input. (Required)None
dataAn array containing objects with values and labels for each Picker.Item.None
FormTextArea

使用 Atom TextArea

<FormTextArea onChangeText={this.handleTextChange} label="Description" />
Android

Android Form TextArea

iOS

iOS Form TextArea

附加道具;

PropDescriptionDefault
labelLabel to display name of input. (Required)None

Simple Notifications

<Notification ref={"alert"} />

要使用通知组件并向其传递数据,您需要在 componentDidMount 中注册一个通知管理器,并在 componentWillUnmount 中注销它。

componentDidMount() {
    NotificationBarManager.registerMessageBar(this.refs.alert);
}

componentWillUnmount() {
    NotificationBarManager.unregisterMessageBar();
}

要触发通知显示,您需要运行通知管理器方法 showAlert

handleShowNotification = () => {
    NotificationBarManager.showAlert({
        message: 'Your alert message goes here', // required
        icon: { name: "alert" },
        // image: { source: require("./assets/images/accessibility.png") }, // image prop
    });
}
Android

安卓通知

iOS

iOS Notification

可以传递给通知是;

PropDescriptionDefault
messageMessage to display. (Required)None
shouldHideAfterDelayIf notification should hide after display or keep being shown.true
durationToHideAnimation duration for the notification to completely hide.350
durationToShowAnimation duration for the notification to completely show.350
durationDuration of time to display the alert3000
imageImage to be displayed next to notification messageNone
iconIcon to be displayed next to notification message'alert'
colorBackground color of the Notification body.'#007bff'
textColorColor of the Notification text.white
fontSizeFont size of Notification text. Accepts text identifier of above Text atom, or specific number.'sub_heading'
fontWeightFont weight of the Notification text.'bold'

SnackBars

<SnackBar ref={"alert"} />

要使用 SnackBar 组件并将数据传递给它,您需要在 componentDidMount 中注册一个 SnackBar 管理器,并在 componentWillUnmount 中注销它。

componentDidMount() {
    SnackManager.registerMessageBar(this.refs.alert);
}

componentWillUnmount() {
    SnackManager.unregisterMessageBar();
}

要触发 SnackBar 显示,您需要运行 SnackBar 管理器方法 showAlert

handleShowSnackBar = () => {
    SnackManager.showAlert({
        message: 'Your alert message goes here' // required
    });
}
Android

Android SnackBar

iOS

iOS SnackBar

可以传递给SnackBar 是;

PropDescriptionDefault
messageMessage to display. (Required)None
shouldHideAfterDelayIf SnackBar should hide after display or keep being shown.true
durationToHideAnimation duration for the SnackBar to completely hide.350
durationToShowAnimation duration for the SnackBar to completely show.350
durationDuration of time to display the alert3000
backgroundColorBackground color of the SnackBar body.'#333333'
onClickDismissIf SnackBar should hide after clicking the action button.true
positionPosition of SnackBar notification ('bottom', 'top').'bottom'
actionAn object denoting the method to run when the snack alerts button is clicked .see below

要传递给 SnackBar 的 action prop 的数据;

PropDescriptionDefault
titleTitle of the button'Close'
onPressMethod to run when the button is clicked.internal method to hide alert
colorButton's text colorerror

ListItem

显示标题(必需)、描述和图像的列表项。 这个分子利用了 Text 原子。

<ListItem title="Heading" description="Description" image={{ source: require("path/to/image.png")}} >
    <ListItem title="Heading" onPress={this.handleButtonClick} description="Description" /> //Nested List Item
</ListItem>
Android

Android ListItem

iOS

iOS ListItem

您可以使用任何 TouchableOpacity 属性 和以下内容:

PropDescriptionDefault
titleDescription of List Item. (Required)None
descriptionDescription of List Item.None
imageImage to display in List Item. You can use all react-native Image properties.None
blockIf the List Item has full width of the device.false
backgroundColorBackground color of List Item.white
secondaryIf the List Item is nested inside another.false
roundedIf the image displayed on the ListItem is rouned or not.false

ThinListItem

显示标题(必需)、描述和图像的列表项。 这个分子利用了 Text 原子。 与上述分子类似,但更小并增加了一些功能

<ThinListItem title="Heading" description="Description" image={{ source: require("path/to/image.png") }} />

您可以使用任何 TouchableOpacity 属性 和以下:

PropDescriptionDefault
titleDescription of List Item. (Required)None
descriptionDescription of List Item.None
imageImage to display in List Item. You can use all react-native Image properties.None
iconIcon to display in List Item. You can use all Icon properties.None
arrowIf the List Item has an arrow at the right of the item.false
backgroundColorBackground color of List Item.white
roundedIf the image displayed on the ListItem is rouned or not.false

Floating Action Button

该分子使用TextIcon 原子。

One action
<FloatingButton onPress={this.handleAction} image={require("path/to/image.png")} />
Multiple actions
actions = [
    { text: 'Accessibility', image: require("path/to/image.png"), name: 'bt_accessibility', position: 2, onPress: () => this.handleAccessibility() },
    { text: 'Location', icon: "pin", name: 'bt_room', position: 1, onPress: () => this.handleLocation() },
    { text: 'Video', icon: "videocam", name: 'bt_videocam', position: 3, onPress: () => this.handleVideo() }
];

<FloatingButton actions={actions} />
Android

Android FAB Android FAB Expanded

iOS

iOS FAB iOS FAB Expanded

主要FloatingButton 是;

PropDescriptionDefault
colorBackground color of main button.primary
distanceToEdgeDistance from edge of device for FAB positioning.30
mainVerticalDistanceDistance of FAB from the bottom of the screen0
visibleIf the FAB and its children are visible.true
overlayColorThe overlay color of the background.overlay
positionThe position of the FAB (center, right).'right'
showBackgroundShow background behind the FAB.true
openOnMountIf FAB should be expanded when page mounts.false
actionsPaddingTopBottomSpacing between child action items.8
iconHeightHeight of button icon.15
iconWidthWidth of button icon.15
listenKeyboardIf listeners are to be added for the Keyboard component.false
dismissKeyboardOnPressIf keyboard should be dismissed on button click.false
onPressUser defined action to run when FAB main button is clicked.None
onCloseUser defined action to run when FAB is closed.None
onOpenUser defined action to run when FAB is expanded.None
onPressBackdropUser defined action to run when the background of the expanded FAB is clicked.None
onStateChangeUser defined action to run when the component state changesNone
imageImage to display on FAB main button.None
iconNameIcon to display on FAB main button.None
tabsIf the page also includes a footer navigationfalse
actionArray of objects which correlate to a FloatingButtonItemfalse

通过 actions 道具发送的嵌套 FloatingButtonItems 的道具是;

PropDescriptionDefault
colorBackground color of main button.primary
imageImage to display on FAB main button.None
iconIcon to display on FAB main button.None
nameUnique name for each button. (Required)None
textContainerStyleStyle of text containerNone
textText to be displayed next to button.None
textStyleStyle of text.None
textPropsOther text props.'right'
textBackgroundBackground color of text.white
textColorFont color of text.darkGrey
textElevationShadow of text element.5
positionThe position of the FAB (center, right).None
activeIf FAB is expanded or not.None
distanceToEdgeDistance from edge of device for FAB positioning.30
paddingTopBottomVertical padding of each action item.None
onPressUser defined action to run when FAB child action button is clicked.None
marginPadding right of each action item, if the position of FAB is 'right'8

Card

显示标题(必需)、说明和图像的卡片。

<Card title="Heading" description="Description" image={{ source: require("path/to/image.png")}} />
Android

Android Card

iOS

iOS Card

您可以使用任何 TouchableOpacity 属性 和以下内容:

PropDescriptionDefault
titleDescription of Card. (Required)None
descriptionDescription of Card.None
imageImage to display in Card. You can use all react-native Image properties.None
blockIf the Card has full width of the device.false
backgroundColorBackground color of Card.white

Organisms

Form

formElements = [
    { label: "Full Name", type: "text", onChangeText: (value) => this.handleTextChange(value), placeholder: "John Doe" },
    { label: "Email", type: "text", onChangeText: (value) => this.handleTextChange(value), placeholder: "john.doe@gmail.com", isValid: (value) => this.checkInputValidity(value) },
    { label: "Type", type: "picker", onValueChange: (value) => this.handleValueChange(value), pickerData: this.pickerData },
    { label: "Date", type: "date", onDateChange: (value) => this.handleDateChange(value) },
    { label: "Address", type: "textarea", onChangeText: (value) => this.handleTextChange(value) },
];

<Form formElements={formElements} />
Android

Android Form

iOS

iOS Form

Form 组件遍历 formElements 数组,渲染根据每个对象中指定的输入类型的字段。 表单对象只有一个额外的道具;

PropDescriptionDefault
colorColor of all form elements when in focus.primary
roundedIf form element style is rounded edges.false
underlineIf form element style is an underline.false
defaultStyleIf form element style is default as seen above.true
noStyleIf form element has no framework defined style.false
styleCustom form element inactive style. (Style object)None
activeStyleCustom form element active style. (Style object)None
errorStyleCustom form element error style. (Style object)None

但是每种类型的输入都有对应于下面命名的分子的 proptypes;

TypeMolecule Component
'text'FormInput
'textarea'FormTextArea
'date'FormDatePicker
'picker'FormPicker

ListView

ListItem 分子的垂直列表

listData = [
    { title: "Heading 1", description: "Description 1", image: { source: require("path/to/image.png")} },
    { title: "Heading 2", description: "Description 2", image: { source: require("path/to/image.png")} },
    { title: "Heading 3", description: "Description 3", image: { source: require("path/to/image.png")} }
];

<ListView data={listData} />

您还可以将自定义 renderItem 方法传递给 ListView,以使用其他 TouchableOpacityListItems code> 道具,例如 onPress

handleListItemClick = (title, description) => {
    Alert.alert(title, description);
}

<ListView data={listData} renderItem={({item}) => <ListItem {...item} onPress={() => handleListItemClick(item.title, item.description)} />} />
Android

Android ListView

iOS

iOS ListView

您可以使用任何 FlatList 属性 和以下内容:

PropDescriptionDefault
backgroundColorBackground color of all cards.white
thinIf the 'ThinListItem' is the component to be rendered.false
roundedIf the image displayed on the ListItem is rouned or not.false

要发送到 ListView 的数据需要包含与 props 相同的字段ListItem 组件。

CardList

卡片分子的垂直/水平列表。

listData = [
    { title: "Heading 1", description: "Description 1", image: { source: require("path/to/image.png")} },
    { title: "Heading 2", description: "Description 2", image: { source: require("path/to/image.png")} },
    { title: "Heading 3", description: "Description 3", image: { source: require("path/to/image.png")} }
];

<CardList data={listData} />

您还可以将自定义 renderItem 方法传递给 CardList,以使用其他 TouchableOpacity 道具呈现 Cards,例如 <代码>按下;

handleListItemClick = (title, description) => {
    Alert.alert(title, description);
}

<CardList data={listData} renderItem={({item}) => <Card {...item} onPress={() => handleListItemClick(item.title, item.description)} />} />
Android

Android CardList

iOS

iOS CardList

您可以使用任何 FlatList 属性 和以下内容:

PropDescriptionDefault
backgroundColorBackground color of all cards.white

要发送到 CardList 的数据需要包含与 props 相同的字段卡片 组件。

导航标头使用 TextIcon 原子。

<NavBar>
    <NavBarLeft>
        <NavBarButton type="drawer" />
    </NavBarLeft>
    <NavBarBody>
        <Text>Title</Text>
    </NavBarBody>
    <NavBarRight>
        <NavBarButton onPress={this.handleFavourites} >
            <Icon name="heart" />
        </NavBarButton>
    </NavBarRight>
</NavBar>
Android

安卓导航栏

iOS

iOS Nav Bar

NavBar 是标头的主要容器。 它使用 View 属性 和以下内容:

PropDescriptionDefault
transparentIf status bar above header is transparentNone
statusBarColorBackground color of the NavBar.primary for Android, '#F8F8F8' for iOS
statusBarColorContent type of the StatusBar.('light-content', 'dark-content')'light-content' for Android, 'dark-content' for iOS

NavBarBody 是在页眉中心显示其子项的容器。 它只接受文本标签内的页面标题。 它使用 View 属性 和以下内容:

PropDescriptionDefault
colorColor of the titleText.white for Android, black for iOS

NavBarLeft 显示它的子项在左侧,而 NavBarRight 则在标题的右侧显示其子项。 所有标头必须包含这三个标签,以统一呈现。

NavBarButton 是要在 NavBar 中使用的按钮元素。 它只接受原子 TextIconreact-native Image。 它包含与 TouchableOpacity 相同的属性。 它还带有用于常用功能的内置类型,这些功能是 'drawer''back''search'

PropDescriptionDefault
typeBuilt in UI implementation of common NavBar button (drawer, back, search)None
colorText and Icon color of button.white for Android, '#0a60ff' for iOS

TabBar

导航页脚使用 TextIcon 原子。

<TabBar>
    <TabItem active>
        <Icon name="heart" />
        <Text>Favorites</Text>
    </TabItem>
    <TabItem>
        <Icon name="add" />
        <Text>Add New</Text>
    </TabItem>
    <TabItem>
        <Icon name="camera" />
        <Text>Camera</Text>
    </TabItem>
    <TabItem>
        <Icon name="settings" />
        <Text>Settings</Text>
    </TabItem>
</TabBar>
Android

安卓标签栏

iOS

iOS 标签栏

TabBar 是页脚导航的主要容器。 它使用 View 属性 和以下内容:

PropDescriptionDefault
colorBackground color of the TabBar.primary for Android, '#F8F8F8' for iOS
activeColorText and Icon color of active tab.white for Android, '#0a60ff' for iOS
inactiveColorText and Icon color of inactive tab.'rgba(209, 216, 224, 0.8)' for Android, '#8e8e93' for iOS
topIf the TabBar is on top of the page. Android only.false

TabItem 是要在 TabBar 中使用的按钮元素。 它只接受原子 TextIconreact-native Image。 它包含与 TouchableOpacity 相同的属性。 此外,它还包含以下属性;

PropDescriptionDefault
activeColorText and Icon color of active tab.white for Android, '#0a60ff' for iOS
inactiveColorText and Icon color of inactive tab.'rgba(209, 216, 224, 0.8)' for Android, '#8e8e93' for iOS
activeIf current TabItem is active.false

PillBar

药丸导航栏。

pillScenes = [
    { scene: <Home /> },
    { scene: <CardList data={listData} /> },
    { scene: <ListView data={listData} /> },
    { scene: <View style={styles.innerContainer}><Form formElements={formElements} /></View> },
];

pillHeaders = [
    { title: 'Home', icon: "home" },
    { title: 'Card List', icon: "card" },
    { title: 'List View', icon: "list" },
    { title: 'Form', icon: "help" }
];

<PillView pillHeaders={pillHeaders} pillScenes={pillScenes} />
Android

安卓药丸栏

iOS

iOS Pill Bar

的索引pillHeader 对象,将用于在转换期间查询相应的 pillScene。

PillBar 是药丸导航的主要容器。 它使用 View 属性 和以下内容:

PropDescriptionDefault
colorActive color of the PillBar. Android only.primary for Android, '#0a60ff' for iOS

此属性 color, 将传递给子元素 PillItem 作为下面提到的 activeColor 道具

PillItem 是要在 中使用的按钮元素药丸条。 它只接受原子 TextIconreact-native Image。 它包含与 TouchableOpacity 相同的属性。 此外,它还包含以下属性;

PropDescriptionDefault
activeColorText and Icon color of active tab.white for Android, '#0a60ff' for iOS
inactiveColorText and Icon color of inactive tab. Android only.'#adadad'
activeIf current PillItem is active.false

Contributing

请阅读 CONTRIBUTING.md 了解我们的行为准则和提交流程的详细信息向我们提出请求。

Versioning

我们使用 SemVer 进行版本控制。

Authors

另请参阅参与此项目的贡献者列表。

License

该项目已获得 MIT 许可 - 请参阅 LICENSE.md 文件了解详细信息

first-born

first-born Logo

Getting Started

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes

Prerequisites

This module can only be used in a React Native app. To use it, you will need a React Native app with it's dependencies installed. The following modules need to be added as a dev dependency as well.

  • create-react-class
  • react-native-vector-icons

Installing

To install first-born run the following command in the terminal;

npm install --save @99xt/first-born

You will additionally require to install the following modules as well.

npm install --save create-react-class react-native-vector-icons

Follow this guide to configure react-native-vector-icons for your project.

No other steps are required to configure first-born separately for each platform (Android/iOS).

Development Testing

To test the repo, first clone it;

git clone https://github.com/99xt/first-born.git

Move into the folder;

cd first-born

Install dependencies;

npm install

And run the test script;

npm run test

Usage

Import components like this;

import { Button } from "@99xt/first-born";

Utils

Colors

ColorAndroidiOS
white#FFF#FFF
black#000#000
primary#486c86#486c86
secondary#8dd9d5#8dd9d5
error#e74c3c#e74c3c
inputGreyrgba(33, 33, 33, 0.5)rgba(33, 33, 33, 0.5)
darkGreyrgba(33, 33, 33, 0.87)rgba(33, 33, 33, 0.87)
lightGreyrgba(33, 33, 33, 0.4)rgba(33, 33, 33, 0.4)
overlayrgba(68, 68, 68, 0.6)rgba(68, 68, 68, 0.6)
secondaryBackgroundrgba(125, 167, 217, 0.2)#ecf8fa

Atoms

Text

<Text>Hello</Text>
Android

Android Text

iOS

iOS Text

You can use any Text property and the following:

PropDescriptionDefault
sizeSize of the text, picked from predefined sizes, according to underlying platform.'p'
boldIf text is bold or not.false
colorColor of the text.black
marginIf the text requires a margin or not.false
alignAlignment of text ('left', 'right', 'center')'left'
SizeAndroidiOS
h19634
h26028
h34824
h43422
h52420
h62017
p1616
callout1516
sub_heading1415
footnote1313
caption_big1212
caption_small1111

Icon

The All Icon components (all font styles) from react-native-vector-icons is used.

<Icon name='heart'/>
Android

Android Icon

iOS

iOS Icon

You can use any TouchableOpacity property and the following:

PropDescriptionDefault
sizeSize of the icon.18
nameSimilar to the name attribute in react-native-vector-icons. Does not require the prefix md or ios for Ionicons.None
colorColor of the icon.white
typeType of the icon font style. ('zocial', 'octicon', 'material', 'material-community', 'ionicon', 'foundation', 'evilicon', 'entypo', 'font-awesome', 'simple-line-icon', 'feather', 'antdesign')white

Badge

Only accepts Text and Icon atoms and react-native Image .

<Badge>
    <Text>+1</Text>
</Badge>
<Badge color="red">
    <Icon name="heart" />
</Badge>
Android

Android Badge

iOS

iOS Badge

You can use any View property and the following:

PropDescriptionDefault
colorColor of the badge.primary
outlineIf the badge has the outline style.false

Thumbnail

An Image component that displays either a square or circular image.

<Thumbnail source={require("path/to/image.png")}/>

You can use any Image property and the following:

PropDescriptionDefault
sizeSize of the image. ('small', 'medium', 'large', 'exlarge')'medium'
customSizeSize of the image, if it does not fit the above defined sizes.None
roundedIf the image is to be a circle.false
onEditProps to handle an image change of the thumbnail. You can use all Button atom properties.None

Button

Only accepts Text and Icon atoms and react-native Image .

<Button onPress={this.handleButtonClick} block >
    <Text>Click Me</Text>
</Button>
Android

Android Button

iOS

iOS Button

You can use any TouchableOpacity property and the following:

PropDescriptionDefault
sizeSize of the button, picked from predefined sizes small, default and large.'default'
colorColor of the button.primary
roundedIf the button has rounded corners.false
blockIf the button has full width.false
oulineIf the button is transparent, but with a colored border and children.false
roundedIf the button is transparent, but with colored children.false

DatePicker

Renders a Text, that displays a date picker modal when the onPress method is triggered.

<DatePicker onDateChange={this.handleDateChange} />
Android

Android Date Picker

iOS

iOS Date Picker

You can use any TextInput property and the following:

PropDescriptionDefault
placeholderDisplay this string if value not selected yet. iOS only.'Select Date'
formatChosenDateUser defined function that returns a formatted date.None
onDateChangeUser defined function to run when selected date changes.None
defaultDateInitially picked date.None
minimumDateMinimum in date range.None
maximumDateMaximum in date range.None
modalTransparentIf DatePicker modal is transparent. iOS only.true
animationTypeType of entry/exit animation for DatePicker modal. iOS only.'fade'
localeLocale of DatePicker. iOS only.None
modeType of picker ('date', 'time').'date'
colorColor of the TextInput when in focus.primary
isValidUser defined validation function, that returns true for valid inputNone
errorMessageError message to display below input, if validation failsNone
roundedIf DatePicker style is rounded edges.false
underlineIf DatePicker style is an underline.false
defaultStyleIf DatePicker style is default as seen above.true
noStyleIf DatePicker has no framework defined style.false
styleCustom DatePicker inactive style. (Style object)None
activeStyleCustom DatePicker active style. (Style object)None
errorStyleCustom DatePicker error style. (Style object)None
errorColorColor of DatePicker when validation failserror

Input

<Input onChangeText={this.handleTextChange} placeholder="Name" />
Android

Android Input

iOS

iOS Input

You can use any TextInput property and the following:

PropDescriptionDefault
colorColor of the TextInput when in focus.primary
isValidUser defined validation function, that returns true for valid textNone
errorMessageError message to display below input, if validation failsNone
roundedIf Input style is rounded edges.false
underlineIf Input style is an underline.false
defaultStyleIf Input style is default as seen above.true
noStyleIf Input has no framework defined style.false
styleCustom Input inactive style. (Style object)None
activeStyleCustom Input active style. (Style object)None
errorStyleCustom Input error style. (Style object)None
errorColorColor of Input when validation failserror
iconLeftIcon Atom to render on the left of the InputNone
iconRightIcon Atom to render on the right of the InputNone

Picker

In Android, display a dropdown picker. In iOS, renders a Text, that displays a picker modal when the onPress method is triggered.

<Picker onValueChange={this.handleValueChange} selectedValue={this.state.pickerValue}>
    <Picker.Item value="1" label="1" />
    <Picker.Item value="2" label="2" />
    <Picker.Item value="3" label="3" />
</Picker>
Android

Android Picker

iOS

iOS Picker

You can use any Picker property and the following:

PropDescriptionDefault
placeholderDisplay this string if value not selected yet. iOS only.'Select Option'
modalTransparentIf Picker modal is transparent. iOS only.true
animationTypeType of entry/exit animation for Picker modal. iOS only.'fade'
modeType of picker mode ('dialog', 'dropdown'). Android only.'dropdown'
colorColor of the TextInput when in focus.primary
isValidUser defined validation function, that returns true for valid inputNone
errorMessageError message to display below input, if validation failsNone
roundedIf Picker style is rounded edges.false
underlineIf Picker style is an underline.false
defaultStyleIf Picker style is default as seen above.true
noStyleIf Picker has no framework defined style.false
styleCustom Picker inactive style. (Style object)None
activeStyleCustom Picker active style. (Style object)None
errorStyleCustom Picker error style. (Style object)None
errorColorColor of Picker when validation failserror

TextArea

Renders a TextInput, that increases in height with the height of the text entered.

<TextArea onChangeText={this.handleTextChange} placeholder="Description" />
Android

Android TextArea

iOS

iOS TextArea

You can use any TextInput property and the following:

PropDescriptionDefault
colorColor of the TextInput when in focus.primary
isValidUser defined validation function, that returns true for valid textNone
errorMessageError message to display below input, if validation failsNone
underlineIf TextArea style is an underline.false
defaultStyleIf TextArea style is default as seen above.true
noStyleIf TextArea has no framework defined style.false
styleCustom TextArea inactive style. (Style object)None
activeStyleCustom TextArea active style. (Style object)None
errorStyleCustom TextArea error style. (Style object)None
errorColorColor of TextArea when validation failserror

Molecules

Form Elements

FormDatePicker

Uses the Atom DatePicker.

<FormDatePicker onDateChange={this.handleDateChange} label="Date" />
Android

Android Form Date Picker

iOS

iOS Form Date Picker

Additional Props;

PropDescriptionDefault
labelLabel to display name of input. (Required)None
FormInput

Uses the Atom Input.

<FormInput onChangeText={this.handleTextChange} label="Name" />
Android

Android Form Input

iOS

iOS Form Input

Additional Props;

PropDescriptionDefault
labelLabel to display name of input. (Required)None
FormPicker

Uses the Atom Picker.

<FormPicker onValueChange={this.handleValueChange} selectedValue={pickerValue} label="Number" data={pickerData} />
Android

Android Form Picker

iOS

iOS Form Picker

Additional Props;

PropDescriptionDefault
labelLabel to display name of input. (Required)None
dataAn array containing objects with values and labels for each Picker.Item.None
FormTextArea

Uses the Atom TextArea.

<FormTextArea onChangeText={this.handleTextChange} label="Description" />
Android

Android Form TextArea

iOS

iOS Form TextArea

Additional Props;

PropDescriptionDefault
labelLabel to display name of input. (Required)None

Simple Notifications

<Notification ref={"alert"} />

To use the Notification Component and pass data to it, you will need to register a Notification manager in componentDidMount and unregister it in componentWillUnmount.

componentDidMount() {
    NotificationBarManager.registerMessageBar(this.refs.alert);
}

componentWillUnmount() {
    NotificationBarManager.unregisterMessageBar();
}

To trigger the Notification display, you will need to run the Notification manager method showAlert.

handleShowNotification = () => {
    NotificationBarManager.showAlert({
        message: 'Your alert message goes here', // required
        icon: { name: "alert" },
        // image: { source: require("./assets/images/accessibility.png") }, // image prop
    });
}
Android

Android Notification

iOS

iOS Notification

The data that can be passed to the notification are;

PropDescriptionDefault
messageMessage to display. (Required)None
shouldHideAfterDelayIf notification should hide after display or keep being shown.true
durationToHideAnimation duration for the notification to completely hide.350
durationToShowAnimation duration for the notification to completely show.350
durationDuration of time to display the alert3000
imageImage to be displayed next to notification messageNone
iconIcon to be displayed next to notification message'alert'
colorBackground color of the Notification body.'#007bff'
textColorColor of the Notification text.white
fontSizeFont size of Notification text. Accepts text identifier of above Text atom, or specific number.'sub_heading'
fontWeightFont weight of the Notification text.'bold'

SnackBars

<SnackBar ref={"alert"} />

To use the SnackBar Component and pass data to it, you will need to register a SnackBar manager in componentDidMount and unregister it in componentWillUnmount.

componentDidMount() {
    SnackManager.registerMessageBar(this.refs.alert);
}

componentWillUnmount() {
    SnackManager.unregisterMessageBar();
}

To trigger the SnackBar display, you will need to run the SnackBar manager method showAlert.

handleShowSnackBar = () => {
    SnackManager.showAlert({
        message: 'Your alert message goes here' // required
    });
}
Android

Android SnackBar

iOS

iOS SnackBar

The data that can be passed to the SnackBar are;

PropDescriptionDefault
messageMessage to display. (Required)None
shouldHideAfterDelayIf SnackBar should hide after display or keep being shown.true
durationToHideAnimation duration for the SnackBar to completely hide.350
durationToShowAnimation duration for the SnackBar to completely show.350
durationDuration of time to display the alert3000
backgroundColorBackground color of the SnackBar body.'#333333'
onClickDismissIf SnackBar should hide after clicking the action button.true
positionPosition of SnackBar notification ('bottom', 'top').'bottom'
actionAn object denoting the method to run when the snack alerts button is clicked .see below

The data to be passed to the action prop of a SnackBar;

PropDescriptionDefault
titleTitle of the button'Close'
onPressMethod to run when the button is clicked.internal method to hide alert
colorButton's text colorerror

ListItem

A List Item that displays a title (required), description and image. This molecule makes use of the Text Atom.

<ListItem title="Heading" description="Description" image={{ source: require("path/to/image.png")}} >
    <ListItem title="Heading" onPress={this.handleButtonClick} description="Description" /> //Nested List Item
</ListItem>
Android

Android ListItem

iOS

iOS ListItem

You can use any TouchableOpacity property and the following:

PropDescriptionDefault
titleDescription of List Item. (Required)None
descriptionDescription of List Item.None
imageImage to display in List Item. You can use all react-native Image properties.None
blockIf the List Item has full width of the device.false
backgroundColorBackground color of List Item.white
secondaryIf the List Item is nested inside another.false
roundedIf the image displayed on the ListItem is rouned or not.false

ThinListItem

A List Item that displays a title (required), description and image. This molecule makes use of the Text Atom. Similar to the above molecule but smaller with a few added features

<ThinListItem title="Heading" description="Description" image={{ source: require("path/to/image.png") }} />

You can use any TouchableOpacity property and the following:

PropDescriptionDefault
titleDescription of List Item. (Required)None
descriptionDescription of List Item.None
imageImage to display in List Item. You can use all react-native Image properties.None
iconIcon to display in List Item. You can use all Icon properties.None
arrowIf the List Item has an arrow at the right of the item.false
backgroundColorBackground color of List Item.white
roundedIf the image displayed on the ListItem is rouned or not.false

Floating Action Button

This molecule makes use of the Text and Icon Atoms.

One action
<FloatingButton onPress={this.handleAction} image={require("path/to/image.png")} />
Multiple actions
actions = [
    { text: 'Accessibility', image: require("path/to/image.png"), name: 'bt_accessibility', position: 2, onPress: () => this.handleAccessibility() },
    { text: 'Location', icon: "pin", name: 'bt_room', position: 1, onPress: () => this.handleLocation() },
    { text: 'Video', icon: "videocam", name: 'bt_videocam', position: 3, onPress: () => this.handleVideo() }
];

<FloatingButton actions={actions} />
Android

Android FAB Android FAB Expanded

iOS

iOS FAB iOS FAB Expanded

The props for the main FloatingButton are;

PropDescriptionDefault
colorBackground color of main button.primary
distanceToEdgeDistance from edge of device for FAB positioning.30
mainVerticalDistanceDistance of FAB from the bottom of the screen0
visibleIf the FAB and its children are visible.true
overlayColorThe overlay color of the background.overlay
positionThe position of the FAB (center, right).'right'
showBackgroundShow background behind the FAB.true
openOnMountIf FAB should be expanded when page mounts.false
actionsPaddingTopBottomSpacing between child action items.8
iconHeightHeight of button icon.15
iconWidthWidth of button icon.15
listenKeyboardIf listeners are to be added for the Keyboard component.false
dismissKeyboardOnPressIf keyboard should be dismissed on button click.false
onPressUser defined action to run when FAB main button is clicked.None
onCloseUser defined action to run when FAB is closed.None
onOpenUser defined action to run when FAB is expanded.None
onPressBackdropUser defined action to run when the background of the expanded FAB is clicked.None
onStateChangeUser defined action to run when the component state changesNone
imageImage to display on FAB main button.None
iconNameIcon to display on FAB main button.None
tabsIf the page also includes a footer navigationfalse
actionArray of objects which correlate to a FloatingButtonItemfalse

The props for the nested FloatingButtonItems, which is being sent through the actions prop are;

PropDescriptionDefault
colorBackground color of main button.primary
imageImage to display on FAB main button.None
iconIcon to display on FAB main button.None
nameUnique name for each button. (Required)None
textContainerStyleStyle of text containerNone
textText to be displayed next to button.None
textStyleStyle of text.None
textPropsOther text props.'right'
textBackgroundBackground color of text.white
textColorFont color of text.darkGrey
textElevationShadow of text element.5
positionThe position of the FAB (center, right).None
activeIf FAB is expanded or not.None
distanceToEdgeDistance from edge of device for FAB positioning.30
paddingTopBottomVertical padding of each action item.None
onPressUser defined action to run when FAB child action button is clicked.None
marginPadding right of each action item, if the position of FAB is 'right'8

Card

A Card that displays a title (required), description and image.

<Card title="Heading" description="Description" image={{ source: require("path/to/image.png")}} />
Android

Android Card

iOS

iOS Card

You can use any TouchableOpacity property and the following:

PropDescriptionDefault
titleDescription of Card. (Required)None
descriptionDescription of Card.None
imageImage to display in Card. You can use all react-native Image properties.None
blockIf the Card has full width of the device.false
backgroundColorBackground color of Card.white

Organisms

Form

formElements = [
    { label: "Full Name", type: "text", onChangeText: (value) => this.handleTextChange(value), placeholder: "John Doe" },
    { label: "Email", type: "text", onChangeText: (value) => this.handleTextChange(value), placeholder: "john.doe@gmail.com", isValid: (value) => this.checkInputValidity(value) },
    { label: "Type", type: "picker", onValueChange: (value) => this.handleValueChange(value), pickerData: this.pickerData },
    { label: "Date", type: "date", onDateChange: (value) => this.handleDateChange(value) },
    { label: "Address", type: "textarea", onChangeText: (value) => this.handleTextChange(value) },
];

<Form formElements={formElements} />
Android

Android Form

iOS

iOS Form

The Form Component iterates through the formElements array, to render the fields according to the type of input specified in each object. The form object only has one extra prop;

PropDescriptionDefault
colorColor of all form elements when in focus.primary
roundedIf form element style is rounded edges.false
underlineIf form element style is an underline.false
defaultStyleIf form element style is default as seen above.true
noStyleIf form element has no framework defined style.false
styleCustom form element inactive style. (Style object)None
activeStyleCustom form element active style. (Style object)None
errorStyleCustom form element error style. (Style object)None

But each type of input has corresponding proptypes to the molecules named below;

TypeMolecule Component
'text'FormInput
'textarea'FormTextArea
'date'FormDatePicker
'picker'FormPicker

ListView

A vertical list of ListItem molecules

listData = [
    { title: "Heading 1", description: "Description 1", image: { source: require("path/to/image.png")} },
    { title: "Heading 2", description: "Description 2", image: { source: require("path/to/image.png")} },
    { title: "Heading 3", description: "Description 3", image: { source: require("path/to/image.png")} }
];

<ListView data={listData} />

You can also pass a custom renderItem method to the ListView, to render ListItems with other TouchableOpacity props, like onPress;

handleListItemClick = (title, description) => {
    Alert.alert(title, description);
}

<ListView data={listData} renderItem={({item}) => <ListItem {...item} onPress={() => handleListItemClick(item.title, item.description)} />} />
Android

Android ListView

iOS

iOS ListView

You can use any FlatList property and the following:

PropDescriptionDefault
backgroundColorBackground color of all cards.white
thinIf the 'ThinListItem' is the component to be rendered.false
roundedIf the image displayed on the ListItem is rouned or not.false

The data to be sent to the ListView needs to contain the same fields as the props of ListItem component.

CardList

A vertical/horizontal List of Card molecules.

listData = [
    { title: "Heading 1", description: "Description 1", image: { source: require("path/to/image.png")} },
    { title: "Heading 2", description: "Description 2", image: { source: require("path/to/image.png")} },
    { title: "Heading 3", description: "Description 3", image: { source: require("path/to/image.png")} }
];

<CardList data={listData} />

You can also pass a custom renderItem method to the CardList, to render Cards with other TouchableOpacity props, like onPress;

handleListItemClick = (title, description) => {
    Alert.alert(title, description);
}

<CardList data={listData} renderItem={({item}) => <Card {...item} onPress={() => handleListItemClick(item.title, item.description)} />} />
Android

Android CardList

iOS

iOS CardList

You can use any FlatList property and the following:

PropDescriptionDefault
backgroundColorBackground color of all cards.white

The data to be sent to the CardList needs to contain the same fields as the props of Card component.

The Navigation Header makes use of the Text and Icon atom.

<NavBar>
    <NavBarLeft>
        <NavBarButton type="drawer" />
    </NavBarLeft>
    <NavBarBody>
        <Text>Title</Text>
    </NavBarBody>
    <NavBarRight>
        <NavBarButton onPress={this.handleFavourites} >
            <Icon name="heart" />
        </NavBarButton>
    </NavBarRight>
</NavBar>
Android

Android Nav Bar

iOS

iOS Nav Bar

NavBar is the main container for the header. It makes use of the View property and the following:

PropDescriptionDefault
transparentIf status bar above header is transparentNone
statusBarColorBackground color of the NavBar.primary for Android, '#F8F8F8' for iOS
statusBarColorContent type of the StatusBar.('light-content', 'dark-content')'light-content' for Android, 'dark-content' for iOS

NavBarBody is a container that displays its children in the center of the header. It only accepts the title of the page within a Text tag. It makes use of the View property and the following:

PropDescriptionDefault
colorColor of the titleText.white for Android, black for iOS

NavBarLeft displays its children on the left while, NavBarRight is displays its children on the right side of the header. All headers must contain these three tags, to render uniformly.

NavBarButton is the button element to be used within the NavBar. It will only accept the atoms Text, Icon and a react-native Image. It contains the same property as a TouchableOpacity. It also comes with an inbuilt type for common features, which are 'drawer', 'back' and 'search'.

PropDescriptionDefault
typeBuilt in UI implementation of common NavBar button (drawer, back, search)None
colorText and Icon color of button.white for Android, '#0a60ff' for iOS

TabBar

The Navigation Footer makes use of the Text and Icon atom.

<TabBar>
    <TabItem active>
        <Icon name="heart" />
        <Text>Favorites</Text>
    </TabItem>
    <TabItem>
        <Icon name="add" />
        <Text>Add New</Text>
    </TabItem>
    <TabItem>
        <Icon name="camera" />
        <Text>Camera</Text>
    </TabItem>
    <TabItem>
        <Icon name="settings" />
        <Text>Settings</Text>
    </TabItem>
</TabBar>
Android

Android Tab Bar

iOS

iOS Tab Bar

TabBar is the main container for the footer navigation. It makes use of the View property and the following:

PropDescriptionDefault
colorBackground color of the TabBar.primary for Android, '#F8F8F8' for iOS
activeColorText and Icon color of active tab.white for Android, '#0a60ff' for iOS
inactiveColorText and Icon color of inactive tab.'rgba(209, 216, 224, 0.8)' for Android, '#8e8e93' for iOS
topIf the TabBar is on top of the page. Android only.false

TabItem is the button element to be used within the TabBar. It will only accept the atoms Text, Icon and a react-native Image. It contains the same property as a TouchableOpacity. In addition, it contains the following properties as well;

PropDescriptionDefault
activeColorText and Icon color of active tab.white for Android, '#0a60ff' for iOS
inactiveColorText and Icon color of inactive tab.'rgba(209, 216, 224, 0.8)' for Android, '#8e8e93' for iOS
activeIf current TabItem is active.false

PillBar

The Pill Navigation Bar.

pillScenes = [
    { scene: <Home /> },
    { scene: <CardList data={listData} /> },
    { scene: <ListView data={listData} /> },
    { scene: <View style={styles.innerContainer}><Form formElements={formElements} /></View> },
];

pillHeaders = [
    { title: 'Home', icon: "home" },
    { title: 'Card List', icon: "card" },
    { title: 'List View', icon: "list" },
    { title: 'Form', icon: "help" }
];

<PillView pillHeaders={pillHeaders} pillScenes={pillScenes} />
Android

Android Pill Bar

iOS

iOS Pill Bar

The index of the pillHeader object, will be used to query the corresponding pillScene, during transition.

PillBar is the main container for the pill navigation. It makes use of the View property and the following:

PropDescriptionDefault
colorActive color of the PillBar. Android only.primary for Android, '#0a60ff' for iOS

This property color, will be passed down to child element PillItem as the activeColor prop mentioned below

PillItem is the button element to be used within the PillBar. It will only accept the atoms Text, Icon and a react-native Image. It contains the same property as a TouchableOpacity. In addition, it contains the following properties as well;

PropDescriptionDefault
activeColorText and Icon color of active tab.white for Android, '#0a60ff' for iOS
inactiveColorText and Icon color of inactive tab. Android only.'#adadad'
activeIf current PillItem is active.false

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Versioning

We use SemVer for versioning.

Authors

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE.md file for details

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文