|
1 | | -# Design System Mobile |
| 1 | +# EDS Mobile — Equinor Design System for React Native |
2 | 2 |
|
3 | | -Welcome to the Design System Mobile project! This monorepo contains a set of reusable components and utilities for building consistent mobile user interfaces. |
| 3 | +[](https://www.npmjs.com/package/@equinor/eds-mobile-components) |
| 4 | +[](./LICENSE) |
4 | 5 |
|
5 | | -## Project Structure |
6 | | - |
7 | | -- **/apps**: Contains application projects (e.g., documentation site, web app). |
8 | | -- **/packages/components**: Core component library with reusable UI components, hooks, and styling utilities. |
9 | | -- **/scripts**: Utility scripts for project maintenance. |
| 6 | +A React Native component library implementing the [Equinor Design System](https://eds.equinor.com/). Build consistent mobile experiences that match Equinor's design language. |
10 | 7 |
|
11 | 8 | ## Packages |
12 | 9 |
|
13 | | -### components |
14 | | - |
15 | | -Reusable React Native components, hooks, and utilities for mobile UI development. |
| 10 | +| Package | Description | |
| 11 | +| ------------------------------------------------------- | ---------------------- | |
| 12 | +| [@equinor/eds-mobile-components](./packages/components) | Core component library | |
16 | 13 |
|
17 | | -- Located in `packages/components` |
18 | | -- Includes: Accordion, Autocomplete, Button, Dialog, Icon, Input, Menu, Tabs, Typography, and more. |
| 14 | +## Apps |
19 | 15 |
|
20 | | -For detailed component documentation, see the files in this `/docs` folder or the README in each package. |
| 16 | +| App | Description | |
| 17 | +| ----------------------------- | ---------------------------------- | |
| 18 | +| [storybook](./apps/storybook) | Interactive component showcase app | |
21 | 19 |
|
22 | | -This is a library of EDS components for React Native. Using this library should feel similar as for |
23 | | -[EDS for React](https://www.npmjs.com/package/@equinor/eds-core-react). |
| 20 | +## Quick Start |
24 | 21 |
|
25 | | -## 🧑🏫 How to use |
| 22 | +### Install the component library |
26 | 23 |
|
27 | | -### Installation |
28 | | - |
29 | | ---- |
30 | | - |
31 | | -#### **_NOTE:_** |
| 24 | +```bash |
| 25 | +pnpm add @equinor/eds-mobile-components |
| 26 | +``` |
32 | 27 |
|
33 | | -THIS LIBRARY IS NOT YET AVAILABLE FOR USE. |
| 28 | +### Peer dependencies |
34 | 29 |
|
35 | | -The component library requires the following libraries to properly function: |
| 30 | +```bash |
| 31 | +pnpm add expo-font react-native-gesture-handler react-native-reanimated react-native-svg |
| 32 | +``` |
36 | 33 |
|
37 | | -- [`react-native-svg`](https://github.com/software-mansion/react-native-svg#installation) |
38 | | -- [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation) |
39 | | -- [`react-native-gesture-handler`](https://docs.swmansion.com/react-native-gesture-handler/docs/installation/) |
| 34 | +Follow the installation guides for each: |
40 | 35 |
|
41 | | -Please make sure to follow these installation instructions before using this package. |
| 36 | +- [react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/docs/fundamentals/installation/) |
| 37 | +- [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/) |
| 38 | +- [react-native-svg](https://github.com/software-mansion/react-native-svg#installation) |
42 | 39 |
|
43 | | -### Getting started |
| 40 | +### Basic usage |
44 | 41 |
|
45 | | -Before using the components in your app, make sure to load the fonts and assets required by the |
46 | | -library somewhere in your root component. It is also recommended that you wrap your app in the |
47 | | -`EDSProvider`. This will give you access to dynamically switching between `tablet` and `phone` mode |
48 | | -as well as `dark` and `light` mode support: |
| 42 | +Wrap your app in `EDSProvider` and load fonts with `useEDS`: |
49 | 43 |
|
50 | 44 | ```tsx |
| 45 | +import { EDSProvider, useEDS } from "@equinor/eds-mobile-components"; |
| 46 | +import { SafeAreaProvider } from "react-native-safe-area-context"; |
| 47 | + |
51 | 48 | export default function App() { |
52 | 49 | const [hasLoadedEds, edsLoadError] = useEDS(); |
| 50 | + |
53 | 51 | if (!hasLoadedEds) { |
54 | 52 | return null; |
55 | | - } else { |
56 | | - return ( |
57 | | - <SafeAreaProvider> |
58 | | - <EDSProvider colorScheme="light" density="phone"> |
59 | | - <Navigation colorScheme="light" /> |
60 | | - <StatusBar /> |
61 | | - </EDSProvider> |
62 | | - </SafeAreaProvider> |
63 | | - ); |
64 | 53 | } |
| 54 | + |
| 55 | + return ( |
| 56 | + <SafeAreaProvider> |
| 57 | + <EDSProvider colorScheme="light" density="phone"> |
| 58 | + <YourApp /> |
| 59 | + </EDSProvider> |
| 60 | + </SafeAreaProvider> |
| 61 | + ); |
65 | 62 | } |
66 | 63 | ``` |
67 | 64 |
|
68 | | -### 🖼️ Theming |
| 65 | +## Components |
| 66 | + |
| 67 | +The library includes 25+ components: |
| 68 | + |
| 69 | +| Category | Components | |
| 70 | +| -------------- | ------------------------------------------------------------------------------- | |
| 71 | +| **Layout** | Paper, Spacer, Scrim | |
| 72 | +| **Inputs** | Button, TextField, Input, Search, Select, Autocomplete, SelectionControls, Chip | |
| 73 | +| **Feedback** | Dialog, Progress, ProgressIndicator, OfflineBanner | |
| 74 | +| **Navigation** | Tabs, Menu, Accordion, Cell | |
| 75 | +| **Display** | Typography, Icon, Label, Popover, Environment | |
| 76 | +| **Utilities** | EDSProvider, Portal, ErrorBoundary, PressableHighlight | |
| 77 | + |
| 78 | +## Theming |
69 | 79 |
|
70 | | -Creating stylesheets that use EDS values is made to be easy and performant. Start by creating a |
71 | | -`EDSStyleSheet`, almost just like for a normal React Native StyleSheet: |
| 80 | +Create theme-aware stylesheets with `EDSStyleSheet`: |
72 | 81 |
|
73 | 82 | ```tsx |
| 83 | +import { EDSStyleSheet, useStyles } from "@equinor/eds-mobile-components"; |
| 84 | + |
74 | 85 | const themeStyles = EDSStyleSheet.create((theme) => ({ |
75 | 86 | container: { |
76 | 87 | backgroundColor: theme.colors.container.background, |
77 | 88 | borderRadius: theme.geometry.border.containerBorderRadius, |
78 | 89 | }, |
79 | 90 | })); |
80 | | -``` |
81 | | - |
82 | | -Notice that we pass `theme` into our style sheet. This is a resolved token based on the current |
83 | | -configuration of the app. This means that the value for `theme.colors.container` can change between |
84 | | -light/dark mode without you having to worry about anything 😎 |
85 | 91 |
|
86 | | -We resolve our stylesheet in our components using the provided `useStyles` hook: |
87 | | - |
88 | | -```tsx |
89 | 92 | const MyComponent = () => { |
90 | 93 | const styles = useStyles(themeStyles); |
91 | 94 | return <View style={styles.container} />; |
92 | 95 | }; |
93 | 96 | ``` |
94 | 97 |
|
95 | | -Ideally, all styling, be it conditional or not should happen outside of our components to reduce |
96 | | -clutter. The `EDSStyleSheet.create` callback method accepts a second optional argument which allows |
97 | | -you to pass any additional props into the style sheet: |
| 98 | +Styles automatically adapt to light/dark mode and phone/tablet density. |
| 99 | + |
| 100 | +### Conditional styling with props |
98 | 101 |
|
99 | 102 | ```tsx |
100 | | -// Notice that we type our second argument! |
101 | | -const themeStylesWithProps = EDSStyleSheet.create( |
102 | | - (theme, props: { color?: string }) => { |
103 | | - const backgroundColor = color ?? theme.colors.container.background; |
104 | | - |
105 | | - return { |
106 | | - container: { |
107 | | - backgroundColor, |
108 | | - }, |
109 | | - }; |
110 | | - } |
| 103 | +const themeStyles = EDSStyleSheet.create( |
| 104 | + (theme, props: { highlight?: boolean }) => ({ |
| 105 | + container: { |
| 106 | + backgroundColor: props.highlight |
| 107 | + ? theme.colors.interactive.primary |
| 108 | + : theme.colors.container.background, |
| 109 | + }, |
| 110 | + }) |
111 | 111 | ); |
112 | | -``` |
113 | | - |
114 | | -We are then required by our `useStyle` hook to pass these props in with the `EDSStyleSheet`: |
115 | 112 |
|
116 | | -```tsx |
117 | | -const MyOtherComponent = () => { |
118 | | - // Normally you'd pass some of your component props into this hook. |
119 | | - const styles = useStyles(themeStylesWithProps, { color: "red" }); |
| 113 | +const MyComponent = ({ highlight }: { highlight?: boolean }) => { |
| 114 | + const styles = useStyles(themeStyles, { highlight }); |
120 | 115 | return <View style={styles.container} />; |
121 | 116 | }; |
122 | 117 | ``` |
123 | 118 |
|
| 119 | +--- |
| 120 | + |
| 121 | +## Development |
| 122 | + |
| 123 | +This monorepo uses [pnpm](https://pnpm.io/) and [Turborepo](https://turbo.build/). |
| 124 | + |
| 125 | +### Prerequisites |
| 126 | + |
| 127 | +- [Node.js](https://nodejs.org/) v22 or higher |
| 128 | +- [pnpm](https://pnpm.io/) v10 or higher |
| 129 | +- For iOS: [Xcode](https://developer.apple.com/xcode/) and CocoaPods |
| 130 | +- For Android: [Android Studio](https://developer.android.com/studio) |
| 131 | + |
| 132 | +### Setup |
| 133 | + |
| 134 | +```bash |
| 135 | +# Clone the repository |
| 136 | +git clone https://github.com/equinor/design-system-mobile.git |
| 137 | +cd design-system-mobile |
| 138 | + |
| 139 | +# Install dependencies |
| 140 | +pnpm install |
| 141 | + |
| 142 | +# Build the component library |
| 143 | +pnpm build |
| 144 | +``` |
| 145 | + |
| 146 | +### Scripts |
| 147 | + |
| 148 | +| Command | Description | |
| 149 | +| --------------------- | --------------------------------------- | |
| 150 | +| `pnpm install` | Install all dependencies | |
| 151 | +| `pnpm build` | Build all packages | |
| 152 | +| `pnpm dev:storybook` | Run the storybook app | |
| 153 | +| `pnpm dev:components` | Watch mode for component library | |
| 154 | +| `pnpm lint` | Run ESLint | |
| 155 | +| `pnpm format` | Format code with Prettier | |
| 156 | +| `pnpm clean` | Remove build artifacts and node_modules | |
| 157 | +| `pnpm build:docs` | Serve documentation locally | |
| 158 | + |
| 159 | +### Project structure |
| 160 | + |
| 161 | +``` |
| 162 | +design-system-mobile/ |
| 163 | +├── apps/ |
| 164 | +│ └── storybook/ # Expo app showcasing components |
| 165 | +├── packages/ |
| 166 | +│ ├── components/ # @equinor/eds-mobile-components |
| 167 | +│ ├── eslint-config-eds-mobile/ # Shared ESLint config |
| 168 | +│ └── tsconfig/ # Shared TypeScript config |
| 169 | +├── docs/ # Component documentation (MkDocs) |
| 170 | +└── scripts/ # Maintenance scripts |
| 171 | +``` |
| 172 | + |
| 173 | +### Running the storybook app |
| 174 | + |
| 175 | +```bash |
| 176 | +# Build components first |
| 177 | +pnpm build |
| 178 | + |
| 179 | +# Start the storybook app |
| 180 | +pnpm dev:storybook |
| 181 | + |
| 182 | +# For iOS, install pods (first time only) |
| 183 | +cd apps/storybook/ios && pod install |
| 184 | +``` |
| 185 | + |
| 186 | +## Documentation |
| 187 | + |
| 188 | +- [Component documentation](./docs/) — Detailed docs for each component |
| 189 | +- [Storybook app](./apps/storybook/) — Interactive examples |
| 190 | +- [Equinor Design System](https://eds.equinor.com/) — Design guidelines |
| 191 | + |
124 | 192 | ## Contributing |
125 | 193 |
|
126 | | -- Please read the [CODE_OF_CONDUCT.md](../packages/components/CODE_OF_CONDUCT.md) before contributing. |
127 | | -- Open issues or pull requests for bugs, features, or improvements. |
| 194 | +We welcome contributions! Please read our [Code of Conduct](./packages/components/CODE_OF_CONDUCT.md) before contributing. |
128 | 195 |
|
129 | | -## License |
| 196 | +1. Fork the repository |
| 197 | +2. Create a feature branch (`git checkout -b feature/amazing-feature`) |
| 198 | +3. Commit your changes (`git commit -m 'Add amazing feature'`) |
| 199 | +4. Push to the branch (`git push origin feature/amazing-feature`) |
| 200 | +5. Open a Pull Request |
130 | 201 |
|
131 | | -This project is licensed under the [MIT License](../LICENSE). |
| 202 | +## License |
132 | 203 |
|
133 | | ---- |
| 204 | +This project is licensed under the [MIT License](./LICENSE). |
0 commit comments