first-born
is a React Native UI Component Framework, which follows the design methodology Atomic Design by Brad Frost.
first-born
是React Native UI组件框架,它遵循Brad Frost的设计方法Atomic Design 。
Version 1.0.0 was recently published as an npm module on the 1st of April (it ain’t no joke though…).
1.0.0版最近在4月1日作为npm模块发布(尽管这不是在开玩笑……)。
In this article, we will see a demo of the existing components offered by first-born
.
在这篇文章中,我们将看到通过提供现有组件的演示first-born
。
设计方法论 (The Design Methodology)
The Atomic Design methodology follows the principle that user interfaces can be deconstructed to 5 different phases.
原子设计方法遵循以下原则:可以将用户界面分解为5个不同的阶段。
According to this design methodology, the phases are described as follows:
根据此设计方法,阶段描述如下:
- Atoms: The basic, standalone elements, like Text, Icons, Buttons or TextInput boxes. 原子:基本的独立元素,例如文本,图标,按钮或TextInput框。
- Molecules: A combination of different atoms, which together have better operational value. For example, a TextInput with a Text label to explain the content or display an error in data entered. 分子:不同原子的组合,它们在一起具有更好的操作价值。 例如,带有文本标签的TextInput可以解释内容或在输入的数据中显示错误。
- Organisms: A combination of different molecules functioning together to form complex structures. For example, a form of many TextInput molecules. 有机体:不同分子的组合在一起起作用,以形成复杂的结构。 例如,许多TextInput分子的形式。
- Template: A combination of different organisms that form the basis of the page. This includes the layout and context of these organisms. 模板:构成页面基础的不同生物的组合。 这包括这些生物的布局和背景。
- Page: All the above working together in a single real-life instance, gives rise to a page. It is also the actual implementation of the template. 页面:以上所有内容在一个真实的实例中协同工作,形成了一个页面。 这也是模板的实际实现。
入门 (Getting Started)
Let us first create a new React Native app using the CLI:
让我们首先使用CLI创建一个新的React Native应用程序:
react-native init firstBornExample
Once it is created, move into the app folder:
创建完成后,移至应用程序文件夹:
cd firstBornExample
To add first-born
into the app, install it like this:
要将first-born
应用添加到应用中,请按以下方式安装它:
npm i --save @99xt/first-born
first-born
has two other dependencies we will need to install ourselves.
first-born
还有另外两个依赖关系,我们需要自行安装。
npm i --save create-react-class react-native-vector-icons
We will then need to follow this guide to set up react-native-vector-icons
for the app.
然后,我们将需要遵循此指南来为该应用设置react-native-vector-icons
。
create-react-class does not have additional set-up steps.
create-react-class没有其他设置步骤。
And we’re good to go!
而且我们很好!
用法 (Usage)
To import the components, the statement will look like this:
要导入组件,该语句将如下所示:
import { <name of component> } from '@99xt/first-born'
The module comes with the following inbuilt components:
该模块带有以下内置组件:
原子 (Atoms)
The Text
atom has a fixed set of sizes. These sizes differ depending on the underlying app platform. We can also pass a color to this Text
atom.
Text
原子具有一组固定的大小。 这些大小取决于基础应用程序平台而有所不同。 我们还可以将颜色传递给此Text
原子。
<Text size="h4">first-born example</Text>
The Icon
atom is built on top of react-native-vector-icons
Ionicons class. Ionicons come with two different renditions of one icon for both Android and iOS. This class will render the icon according to the underlying platform.
Icon
原子建立在react-native-vector-icons
Ionicons类的顶部。 Ionicons带有两个图标,分别适用于Android和iOS。 此类将根据基础平台渲染图标。
<Icon name="heart" color="red"/>
The Button
atom can be rendered in multiple ways. It only accepts Texts
, Icons
, and Images
as child items to display. It has 3 different sizes, as well as 4 different tags that will render the button in many combinations.
Button
原子可以多种方式呈现。 它仅接受Texts
, Icons
和Images
作为要显示的子项。 它具有3种不同的大小,以及4种不同的标签,这些标签将以多种组合呈现按钮。
render() {
return (
<View style={styles.container}>
<Button size="small">
<Text>Small</Text>
</Button>
<Button >
<Text>Default</Text>
</Button>
<Button size="large">
<Text>Large</Text>
</Button>
<Button >
<Icon name="heart" />
<Text>Default</Text>
</Button>
<Button rounded>
<Icon name="heart" />
<Text>Rounded</Text>
</Button>
<Button block>
<Icon name="heart" />
<Text>Block</Text>
</Button>
<Button rounded block>
<Icon name="heart" />
<Text>{"Rounded & Block"}</Text>
</Button>
<Button outline>
<Icon name="heart" />
<Text>Outline</Text>
</Button>
<Button outline transparent>
<Icon name="heart" />
<Text>{"Outline & Transparent"}</Text>
</Button>
</View>
);
}
The Input
atom is a styled react-native TextInput
. It displays a colored border to the user if the TextInput is in focus. The onChangeText
method is mandatory.
Input
原子是样式react-native TextInput
。 如果TextInput处于焦点,它将向用户显示彩色边框。 onChangeText
方法是强制性的。
<Input placeholder="Name" onChangeText={this.handleTextChange} />
...
handleTextChange = (text) => {
this.setState({ text: text })
}
This also supports indicating an error to the user. To use this feature, we will need to create a validation method. This method should return a boolean depending on the validity of the text entered. One such scenario is checking if an email address follows the conventional format. This method is that passed in the isValid
property.
这也支持向用户指示错误。 要使用此功能,我们将需要创建一种验证方法。 此方法应根据输入的文本的有效性返回一个布尔值。 一种这样的情况是检查电子邮件地址是否遵循常规格式。 此方法是在isValid
属性中传递的。
checkInputValidity = (text) => {
const regex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
return regex.test(text);
}
...
<Input placeholder="Email" isValid={this.checkInputValidity} />
The TextArea
atom is a styled react-native TextInput
. It displays a colored border to the user if the TextInput is in focus. It also increases in height with more data entered.
TextArea
原子是样式react-native TextInput
。 如果TextInput处于焦点,它将向用户显示彩色边框。 输入更多数据后,高度也会增加。
<TextArea placeholder="Description"/>
The Picker
atom is a styled react-native Picker
component. On Android, the picker is a dropdown that extends from the initial Picker
component. On iOS, clicking the first-born Picker
will open a modal for the user to pick the value.
Picker
原子是样式react-native Picker
组件。 在Android上,选择器是从初始“ Picker
组件扩展而来的下拉列表。 在iOS上,单击第first-born Picker
将打开一个模式供用户选择值。
<Picker>
<Picker.Item value="1" label="1" />
<Picker.Item value="2" label="2" />
<Picker.Item value="3" label="3" />
</Picker>
The DatePicker
atom is a styled react-native View
component, which looks like a TextInput
. On Android, when the View
is clicked, it runs the DatePickerAndroid
API. On iOS, clicking the View
will open a modal for the user to pick the date from the DatePickerIOS
component.
DatePicker
原子是样式react-native View
组件,看起来像TextInput
。 在Android上,单击“ View
,它将运行DatePickerAndroid
API 。 在iOS上,单击“ View
将打开一个模式,供用户从DatePickerIOS
组件中选择日期。
<DatePicker />
分子 (Molecules)
This molecule uses the DatePicker
atom and includes the Text
atom as a label. The label property of this element is mandatory.
该分子使用DatePicker
原子,并包括Text
原子作为标签。 此元素的label属性是必需的。
<FormDatePicker label="Date" />
This molecule uses the Picker
atom and includes the Text
atom as a label. The label property of this element is mandatory.
该分子使用Picker
原子,并包含Text
原子作为标签。 此元素的label属性是必需的。
<FormPicker label="Number">
<Picker.Item value="1" label="1" />
<Picker.Item value="2" label="2" />
<Picker.Item value="3" label="3" />
</FormPicker>
We can also pass data as an array of objects, which have the keys’ value
and label
. The data in both keys need to be of type String.
我们还可以将数据作为对象的数组传递,这些对象具有键的value
和label
。 两个键中的数据都必须为String类型。
pickerData = [
{
value: "1",
label: "1"
},
{
value: "2",
label: "2"
},
{
value: "3",
label: "3"
}
];
...
<FormPicker label="Number" pickerData={this.pickerData} />
This molecule uses the Input
atom and includes the Text
atom as a label. The label property of this element is mandatory.
该分子使用Input
原子,并包括Text
原子作为标签。 此元素的label属性是必需的。
<FormInput label="Name" />
This molecule uses the TextArea
atom and includes the Text
atom as a label. The label property of this element is mandatory.
该分子使用TextArea
原子,并包括Text
原子作为标签。 此元素的label属性是必需的。
<FormTextArea label="Description" />
The Card
molecule displays a View
with an image, heading, and description. Of the three, the heading is mandatory. The style of this molecule differs according to the underlying platform.
Card
分子显示带有图像,标题和描述的View
。 在这三个中,标题是强制性的。 该分子的样式根据基础平台而不同。
<Card title="Heading Only" />
<Card title="Heading" description="And Description" />
<Card title="Heading" description="Description" image={require("./path/to/an/image.png")} />
The ListItem
molecule displays a View
with an image, heading, and description. Of the three, the heading is mandatory. The style of this molecule differs according to the underlying platform.
ListItem
分子显示带有图像,标题和描述的View
。 在这三个中,标题是强制性的。 该分子的样式根据基础平台而不同。
<ListItem title="Heading Only" />
<ListItem title="Heading" description="And Description" />
<ListItem title="Heading" description="Description" image={require("./path/to/an/image.png")} />
The Notification
molecule displays a banner at the top of the page. The reference to the component is passed to the NotificationManager
. Invoking the showAlert
method of this manager, we can send the message to be displayed to the user.
Notification
分子在页面顶部显示横幅。 对组件的引用将传递给NotificationManager
。 调用此管理器的showAlert
方法,我们可以将要显示的消息发送给用户。
Add the Notification
as the very last element of the parent View
.
将Notification
添加为父View
最后一个元素。
<Notification ref={"alert"} />
We will need to register this Notification
molecule when the page mounts. This is to pass the reference of the Notification
to the manager.
页面装入后,我们将需要注册此Notification
分子。 这是为了将Notification
的引用传递给管理器。
componentDidMount() {
NotificationBarManager.registerMessageBar(this.refs.alert);
}
To clean up, we will also need to unregister this molecule as the page is unmounted.
为了清理,我们还需要在卸载页面时注销该分子。
componentWillUnmount() {
NotificationBarManager.unregisterMessageBar();
}
To display the Notification
bar, run the below method, passing the message to be displayed.
要显示Notification
栏,请运行以下方法,并传递要显示的消息。
NotificationBarManager.showAlert({
message: 'Your alert message goes here'
});
This molecule is equivalent to the Android Floating Action Button (FAB). It can be either a singular action or expand to display many actions.
该分子等效于Android浮动操作按钮(FAB)。 它可以是单个动作,也可以扩展为显示许多动作。
If the FAB contains a singular action, we use the onPress
property to pass the method to be run when the button is clicked.
如果FAB包含单个动作,则使用onPress
属性传递单击按钮时要运行的方法。
<FloatingButton onPress={this.handleShowNotification} />
If the FAB needs to expand to display many actions, and action array needs to be created. Each action object in the array needs to contain at a minimum:
如果FAB需要扩展以显示许多动作,则需要创建动作数组。 数组中的每个操作对象至少需要包含:
Unique
name
唯一
name
icon
orimage
icon
或image
position
from the top (starts at 1) when the FAB is expandedFAB展开时从顶部开始的
position
(从1开始)method to run
onPress
在
onPress
上运行的方法
const actions = [
{
icon: 'help',
name: 'bt_accessibility',
position: 2,
onPress: () => Alert.alert('Hello', 'Accessibility')
},
{
icon: 'pin',
name: 'bt_room',
position: 1,
onPress: () => Alert.alert('Hello', 'Location')
},
{
icon: 'videocam',
name: 'bt_videocam',
position: 3,
onPress: () => Alert.alert('Hello', 'Video')
}
];
We then pass the array to the FloatingButton
in the property actions
:
然后,我们将数组传递给属性actions
的FloatingButton
:
<FloatingButton actions={this.actions} />
生物体 (Organisms)
Form
形成
The Form
organism is built of the form molecules, FormInput
, FormPicker
, FormDatePicker
, and FormTextArea
.
Form
生物体是由表单分子FormInput
, FormPicker
, FormDatePicker
和FormTextArea
。
To render this organism, an array containing details of each field needs to be passed. The child components are rendered according to the type
specified in each object.
为了渲染这种生物,需要传递包含每个字段细节的数组。 子组件根据每个对象中指定的type
进行渲染。
The mapping is as follows:
映射如下:
‘text’ —
FormInput
'
FormInput
-FormInput
‘textarea’ —
FormTextArea
'textarea'—
FormTextArea
‘date’ —
FormDatePicker
'
FormDatePicker
-FormDatePicker
‘picker’ —
FormPicker
'
FormPicker
-FormPicker
The object of each field can only contain the properties specified to the mapped field type. In simpler terms, an object of type
‘text’, must only contain the properties that the FormInput
molecule accepts.
每个字段的对象只能包含为映射的字段类型指定的属性。 简单来说,“文本” type
的对象必须仅包含FormInput
分子接受的属性。
This organism currently renders a read-only list of Cards
, either horizontally or vertically. It requires an array of objects which have the same properties as a Card
molecule.
该生物当前呈现水平或垂直的Cards
只读列表。 它需要一系列与Card
分子具有相同属性的对象。
const listData = [
{
title: "Heading 1",
description: "Description 1",
image: require("./path/to/an/image.png")
},
{
title: "Heading 2",
description: "Description 2",
image: require("./path/to/an/image.png")
},
{
title: "Heading 3",
description: "Description 3",
image: require("./path/to/an/image.png")
}
];
To render the list, pass the array above to the data property. Add the boolean property horizontal
, if we wish for a horizontally scrolling list.
要呈现列表,请将上面的数组传递给data属性。 如果希望水平滚动列表,请添加boolean属性horizontal
。
<CardList data={this.listData} />
<CardList data={this.listData} horizontal />
This organism currently renders a read-only list of ListItem’s
vertically. It requires an array of objects which have the same properties as a ListItem
molecule. The same list used for a CardList
can be used here as well.
该生物当前ListItem's
垂直方向上呈现ListItem's
只读列表。 它需要具有与ListItem
分子具有相同属性的对象数组。 也可以在这里使用与CardList
相同的列表。
<ListView data={this.listData} />
The NavBar
organism is a page header that renders according to the underlying platform. It is rendered at the top of the page, right inside the page’s main View
component.
NavBar
生物是根据底层平台呈现的页面标题。 它呈现在页面顶部,就在页面的主要View
组件内部。
To form the NavBar
, all three child elements (NavBarRight
, NavBarLeft
, and NavBarBody
) need to be included to align the elements correctly.
要形成NavBar
,需要包括所有三个子元素( NavBarRight
, NavBarLeft
和NavBarBody
)以正确对齐元素。
<NavBar>
<NavBarLeft />
<NavBarBody>
<Text>Title</Text>
</NavBarBody>
<NavBarRight/>
</NavBar>
We can also include buttons to the header with the NavBarButton
component. This button can be added as children to the NavBarRight
and NavBarLeft
components.
我们还可以在NavBarButton
组件的标题中包含按钮。 可以将此按钮作为子级添加到NavBarRight
和NavBarLeft
组件中。
The NavBarButton
can be used in two ways:
NavBarButton
可以通过两种方式使用:
It has a property
type
, that accepts the values ‘back, ‘drawer’ and ‘search’. This renders the corresponding icons to each type by default.它具有属性
type
,它接受值'back,'drawer'和'search'。 默认情况下,这会将相应的图标呈现给每种类型。We can create a custom button by including either
Texts
,Icons
orImages
as children in theNavBarButton
component.我们可以通过在
NavBarButton
组件NavBarButton
Texts
,Icons
或Images
作为子项来创建自定义按钮。
<NavBar>
<NavBarLeft >
<NavBarButton type="drawer" />
</NavBarLeft>
<NavBarBody>
<Text>Title</Text>
</NavBarBody>
<NavBarRight>
<NavBarButton>
<Icon name="heart" />
</NavBarButton>
</NavBarRight>
</NavBar>
The TabBar
organism is a page footer that renders according to the underlying platform. It is rendered at the very bottom of the page, right before the closing tag of the page’s main View
component.
TabBar
生物是根据基础平台呈现的页脚。 它呈现在页面的最底部,就在页面主View
组件的关闭标记之前。
The TabBar contains multiple TabItems, depending on the number of pages in the tab navigation. A TabItem accepts either Texts
, Icons
or Images
as children.
TabBar包含多个TabItem,具体取决于选项卡导航中的页面数。 TabItem接受Texts
, Icons
或Images
作为子级。
<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>
The PillView
navigation is used to display different sections on a page. On Android, it renders as a header tab bar. On iOS, it renders as pills.
PillView
导航用于在页面上显示不同的部分。 在Android上,它呈现为标题标签栏。 在iOS上,它呈现为药丸。
It requires two arrays to be passed to it, to successfully render the organism. One is a list of the scenes it will display. The second is the components to be displayed in the header (PillBar
).
它需要传递两个数组才能成功渲染生物体。 一个是它将显示的场景列表。 第二个是要在标题( PillBar
)中显示的组件。
The pill scene only requires one key in the object. It is used to denote the scene to display on the view when the corresponding PillItem
is clicked.
药丸场景只需要在对象中输入一键即可。 它用于表示单击相应的PillItem
时要在视图上显示的场景。
The pill header will require at least one of either Text, Icon or Image to render on the PillItem
.
药丸标头至少需要Text,Icon或Image之一才能在PillItem
上呈现。
const pillScenes = [
{ scene: <CardList data={this.listData} /> },
{ scene: <ListView data={this.listData} /> },
{ scene:
<View style={styles.innerContainer}>
<Form formElements={this.formElements} />
</View>
}
];
const pillHeaders = [
{
title: 'Card List',
icon: "card"
},
{
title: 'List View',
icon: "list"
},
{
title: 'Form',
icon: "help"
}
];
We will then pass the two arrays to the PillView
item like this:
然后,我们将两个数组传递给PillView
项目,如下所示:
<PillView pillHeaders={this.pillHeaders} pillScenes={this.pillScenes} />
And that is all the components first-born
has to offer (so far…).
这就是first-born
所必须提供的所有组件(到目前为止……)。
Once the code is a bit better assembled, we would end up with an app similar to this:
一旦代码汇编得更好,我们最终将得到一个类似于以下的应用程序:
Give first-born
a try and please do let me know how it goes for you.
就给first-born
一个尝试,请让我知道如何去为您服务。
Find the Demo repo here.
在此处找到演示仓库。
If you wish to see how first-born Navigation elements work with external navigation modules, have a look at the following repos;
如果您想了解第一个导航元素如何与外部导航模块一起使用,请查看以下存储库;
React Navigation: first-born-react-navigation-example
React Navigation: 第一个出生的React导航示例
React Native Router Flux: first-born-rnrf-example
React Native Router Flux: 第一个出生的RNRF示例