
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
@kiwicom/orbit-react-native
Advanced tools
Orbit React Native Components are a component library which provide developers with the easiest possible way of building Kiwi.com’s products.
Component library compatible with Expo/React Native projects.
View
and Text
) to make sure the whole page follows not only the visual style of Orbit but also the UX.yarn add @kiwicom/orbit-react-native
Roboto
font (Roboto-Regular
, Roboto-RegularItalic
, Roboto-Medium
, Roboto-MediumItalic
, Roboto-Bold
, Roboto-BoldItalic
) to your project.Also, make sure to import the orbit-icons
font, which you can find here: https://orbit.kiwi/visual-style/icons/
How to do it in Expo: https://docs.expo.io/versions/latest/guides/using-custom-fonts/
Make sure that the fonts are loaded, before you start using any ORN components!
CircularPro
), make sure that the appropriate weights and styles are imported in your environment, and the theme is defined on the app level:import { ThemeProvider, defaultTheme } from '@kiwicom/orbit-react-native';
function MyApp() {
return (
<ThemeProvider
theme={{
...defaultTheme,
fontFamily: {
'400-normal': 'CircularPro-Book',
'400-italic': 'CircularPro-BookItalic',
'500-normal': 'CircularPro-Medium',
'500-italic': 'CircularPro-MediumItalic',
'700-normal': 'CircularPro-Bold',
// Map bold & italic text to be just bold for readability
'700-italic': 'CircularPro-Bold',
},
}}
>
{/* Your code using CircularPro goes here */}
</ThemeProvider>
);
}
import { Card } from '@kiwicom/orbit-react-native';
function MyComponent() {
return (
<Card title="Cool" onPress={pressHandler}>
Cool component
</Card>
);
}
yarn
yarn workspace @kiwicom/orbit-react-native-docs start
src
folder, there should be a single directory for each public component.
UpperCamelCase
,lowercase-with-dashes
,UpperCamelCase
.index.js
for each component.
UpperCamelCase
,components
sub-folder)orbit-react-native/src/
├── index.js # All public components are re-exported here (by hand)
└── Card/ # Single component folder of the Card
├── components/ # Folder with private components
│ └── Circle.js # Private Circle component
├── __tests__/ # Jest unit tests go here
│ └── Card.test.js # Test file for Card
├── index.js # File for exporting all public components
├── README.md # Information about component for users
├── CardHeader.js # Public component, exported as { CardHeader }
├── Card.js # Public component (it should be the main one), exported as { Card }
├── Card.helpers.js # Helper functions
├── Card.stories.js # Defines stories for Storybook
└── Card.types.js # All types for whole component bundle (which means Card, CardHeader and Circle in this case)
Some components require files to be generated based on some external data, eg: list of icons.
We have a simple mechanism to help with the generation, just run:
yarn workspace @kiwicom/orbit-react-native generate
What this script does, is the following:
__templates__
within src/
{
output: string /* path relative to package root */,
input?: string /* path relative to package root */,
generate: (
anythingThatInputExports,
HEADER /* block comment to be inserted at the top of each generated file */
) => string
}
require()
whatever is in input
and feed it to generate()
generate()
and write it to output
__templates__
folder,*.template.js
,*.generated.js
master
and all the tests have passed.version
in orbit-react-native/package.json
,orbit-react-native-docs/package.json
's' "@kiwicom/orbit-react-native": "^x.x.x"
to match.orbit-react-native/4.2.0
or orn/4.2.0
.CHANGELOG.md
file and add all the changes that are new in this release.git
history of orbit-react-native
and orbit-react-native-docs
to make sure that all changes are shown in the file.master
,ORN: Release x.x.x
,deploy hash orn expo
build pipeline job.cc @vepor @honza @will
for a final review,master
.deploy
step,latest
.cc
part.babel-preset-kiwicom
eslint-config-kiwicom
monorepo-npm-publisher
orbit-react-native
react-native
@adeira/js
(used for invariant()
, should be replaced by @kiwicom/js
- can't yet due to webpack/babel/monorepo issues with RN)orbit-react-native-docs
react-native-syntax-highlighter
react-native-storybook-loader
- see Auto-generating filesThe Storybook installation related to this project is stored in a several package and folder.
There is a very simple reason for this, the monorepo-npm-publisher
that comes with the Universe Monorepo has some restrictions that we couldn't get around without crazy hacks:
monorepo-npm-publisher
requires main
to be set to src/index
in package.json
main
to be set to AppEntry
.Another simple reason is that we didn't want to bundle any of Storybook's or Expo's dependencies with the library, that is the responsibility of the app that uses ORN.
There is one crazy hack in place:
orbit-react-native/src/**/*.stories.js
files actually belong to orbit-react-native-docs
and are imported using the dreaded ../../orbit-react-native/src/...
technique.
This way we have the stories of each component together with their code, but still get around the limitations of the npm published.
React is evolving we should evolve with it, always try to use the latest recommended patterns to make sure the code will be easy to maintain for future developers.
If we follow this same convention everywhere, the exported names should already contain some information on what is being exported, instead of generic names.
const
s and Flow
definitions, DRY./**
* Example on how to have an enum used for Flow types,
* and JS code as well.
*/
// This object will not be used directly outside of the definitions
const spacingsObj = Object.freeze({
none: 0,
extraTight: 1,
tight: 2,
condensed: 3,
compact: 4,
natural: 5,
comfy: 6,
loose: 7,
extraLoose: 8,
});
// Array of possible values
const spacings: string[] = Object.keys(spacingsObj);
// Flow type that can be used for argument validation
type spacingType = $Keys<typeof spacingsObj>;
When working on a library (as opposed to an application), we have to make sure to minimize dependencies on external projects:
We were thinking about how to pre-generate our styles for Orbit React Native, so that everything gets nicely cached and we have a sane API.
Finding #1 - StyleSheet.create() is basically the same as (styles) => styles
There is no caching going on here, no StyleRegistry and no IDs returned. See the YOLO-prefixed commit that was merged in 2018 April, over a year ago... - https://github.com/facebook/react-native/commit/a8e3c7f5780516eb0297830632862484ad032c10
Finding #2 - Passing style objects or references to style objects are just as fast.
We have a small benchmark, comparing styled-components to StyleSheet, and with a quick modification, we can see the difference between rendering something using the 'proper-way' StyleSheet.create() vs just passing the inline objects - https://github.com/sampi/expo-stylesheet-vs-styled-components/tree/full-inline
Our findings were that:
Conclusion - It's ok to use inline style objects in RN.
If we don't have to pre-generate the styles, then we can just write code, like we would do it normally for web or any native mobile app, instead of having to pre-generate the styles, and make sure everything is ready before we can use it. It also means (especially for Orbit React Native), that we don't need convoluted APIs all over the place, just so we can handle buttons, that could be 10 different types, with 2 separate boolean switches (that's a lot of pre-generated styles taking up memory.)
Later we found out that RNW does actually cache the values for each call to
StyleSheet.create()
but we are not using it in this project, so that is not an issue right now.
When working with Orbit Design Tokens, some values are not the correct type required by RN, we have some helpers available for this.
// cwd: orbit-react-native/src/SomeComponent
import {
ucCase, //convert dash-case to UpperCamelCase
capitalize, // capitalize the first character of any string
secondsToMs, // convert a second duration string to millisecond number
msToSeconds, // convert a millisecond number to a second duration string
} from '../common/utils';
When working with other units, we recommend using parseFloat()
to make them compatible with RN.
When working with colors, RN accepts rrggbbaa
format, so it's easy to add opacity to existing colors.
To use different font weights, we have some helpers available.
// cwd: orbit-react-native/src/SomeComponent
import { getTextStyles } from '../styles';
function getStyles({ theme }) {
return {
smallText: { ...getTextStyles({ theme, fontSize: 'small' }) },
smallItalicText: { ...getTextStyles({ theme, fontSize: 'small', italic: true }) },
smallBoldText: { ...getTextStyles({ theme, fontSize: 'small', fontWeight: 'bold' }) },
smallBoldItalicText: {
...getTextStyles({ theme, fontSize: 'small', fontWeight: 'bold', italic: true }),
},
normalText: { ...getTextStyles({ theme }) },
normalItalicText: { ...getTextStyles({ theme, italic: true }) },
boldText: { ...getTextStyles({ theme, fontWeight: 'bold' }) },
boldItalicText: { ...getTextStyles({ theme, fontWeight: 'bold', italic: true }) },
largeText: { ...getTextStyles({ theme, fontSize: 'large' }) },
largeItalicText: { ...getTextStyles({ theme, fontSize: 'large', italic: true }) },
largeBoldText: { ...getTextStyles({ theme, fontSize: 'large', fontWeight: 'bold' }) },
largeBoldItalicText: {
...getTextStyles({ theme, fontSize: 'large', fontWeight: 'bold', italic: true }),
},
};
}
If you want to share code between components, first make sure that it is actually something that is being shared. Don't try to optimize in advance.
Place the shared code in these folders:
orbit-react-native/src/common/components/
,orbit-react-native/src/common/helpers/
,orbit-react-native/src/common/hooks/
,orbit-react-native/src/common/styles/
, (TODO: merge with other style helpers),orbit-react-native/src/styles/
,orbit-react-native/src/common/
.The plan was to do minimal unit testing, and cover most of our use cases using cross-platform screenshot testing. (still in TODO)
getStyles()
is called on each render.We decided that the performance overhead of generating inline styles on each render is not going to be a bottleneck. If the project wants to enable RNW usage again, this will be a major refactoring point.
We tried our best to remove all RNW code from the repo but some components might still have references to web
versions or maybe some code is still structured in a way that enables different rendering for different platforms.
<a>
inside of <p>
in RN, so it needs to be hacked somehow. For example, even small, simple components are wrapped in multiple divs, even button is basically a bunch of divs.FAQs
Orbit React Native Components are a component library which provide developers with the easiest possible way of building Kiwi.com’s products.
We found that @kiwicom/orbit-react-native demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 16 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.