├── example
├── assets
│ ├── styles
│ │ └── fonts.css
│ ├── images
│ │ ├── beach.jpg
│ │ ├── city.jpg
│ │ ├── avatar.png
│ │ ├── bridge.jpg
│ │ ├── favicon.png
│ │ ├── favorite.png
│ │ ├── forest.jpg
│ │ ├── chameleon.jpg
│ │ ├── email-icon.png
│ │ ├── strawberries.jpg
│ │ └── wrecked-ship.jpg
│ └── fonts
│ │ ├── HanaleiFill-Regular.ttf
│ │ └── Inconsolata-Regular.ttf
├── .gitignore
├── App.js
├── App.web.js
├── .eslintrc
├── index.d.ts
├── tsconfig.json
├── babel.config.js
├── .expo-shared
│ ├── README.md
│ └── assets.json
├── public
│ └── index.html
├── app.json
├── src
│ ├── utils
│ │ ├── ExamplePage.tsx
│ │ ├── ExampleSection.tsx
│ │ └── ExampleHeader.tsx
│ └── components
│ │ ├── Drawer.tsx
│ │ ├── Icon.tsx
│ │ ├── Snackbar.tsx
│ │ ├── Toggle.tsx
│ │ ├── Fab.tsx
│ │ ├── Skeleton.tsx
│ │ ├── Badge.tsx
│ │ ├── Overlay.tsx
│ │ ├── Tag.tsx
│ │ ├── Tooltip.tsx
│ │ └── Avatar.tsx
├── webpack.config.js
├── metro.config.js
└── package.json
├── .eslintignore
├── src
├── style
│ └── index.ts
├── index.tsx
├── ui
│ ├── tag
│ │ ├── tag.type.tsx
│ │ ├── tag.component.tsx
│ │ └── tag.style.tsx
│ ├── input
│ │ ├── textarea.type.tsx
│ │ └── input.type.tsx
│ ├── dropdown
│ │ ├── dropdown.option.type.tsx
│ │ ├── dropdown.type.tsx
│ │ ├── dropdown.option.component.tsx
│ │ └── dropdown.style.tsx
│ ├── carousel
│ │ ├── item.carousel.tsx
│ │ └── carousel.type.tsx
│ ├── header
│ │ ├── header.type.tsx
│ │ ├── header.style.tsx
│ │ └── header.component.tsx
│ ├── skeleton
│ │ ├── skeleton.type.tsx
│ │ └── skeleton.component.tsx
│ ├── portal
│ │ ├── portal.component.tsx
│ │ ├── consumer.component.tsx
│ │ ├── manager.component.tsx
│ │ └── hooks
│ │ │ └── useKey.ts
│ ├── animated
│ │ ├── animated.type.tsx
│ │ ├── animated.service.tsx
│ │ └── animated.style.tsx
│ ├── scrolldiv
│ │ └── scrolldiv.type.ts
│ ├── drawer
│ │ ├── drawer.type.tsx
│ │ └── drawer.style.tsx
│ ├── div
│ │ ├── div.spec.tsx
│ │ ├── div.type.tsx
│ │ └── div.style.tsx
│ ├── text
│ │ ├── text.type.ts
│ │ └── text.component.tsx
│ ├── avatar
│ │ ├── avatar.group.type.tsx
│ │ ├── avatar.type.tsx
│ │ └── avatar.group.component.tsx
│ ├── tooltip
│ │ ├── triangle.component.tsx
│ │ └── tooltip.type.tsx
│ ├── image
│ │ ├── image.type.tsx
│ │ ├── image.component.tsx
│ │ └── image.style.tsx
│ ├── overlay
│ │ ├── overlay.type.tsx
│ │ └── overlay.style.tsx
│ ├── toggle
│ │ ├── toggle.type.tsx
│ │ └── toggle.style.tsx
│ ├── button
│ │ ├── button.service.ts
│ │ └── button.type.ts
│ ├── badge
│ │ ├── badge.type.tsx
│ │ └── badge.style.tsx
│ ├── mention
│ │ ├── mention.type.tsx
│ │ └── mention.style.tsx
│ ├── radio
│ │ ├── radio.service.tsx
│ │ └── group.component.tsx
│ ├── collapse
│ │ ├── collapse.type.tsx
│ │ └── group.component.tsx
│ ├── select
│ │ ├── select.option.type.tsx
│ │ ├── select.style.tsx
│ │ └── select.type.tsx
│ ├── icon
│ │ ├── icon.type.tsx
│ │ ├── icon.style.tsx
│ │ └── icon.service.tsx
│ ├── modal
│ │ └── modal.style.tsx
│ ├── statusbar
│ │ └── statusbar.component.tsx
│ ├── fab
│ │ ├── fab.style.tsx
│ │ └── fab.type.tsx
│ ├── snackbar
│ │ ├── snackbar.type.tsx
│ │ └── snackbar.style.tsx
│ └── checkbox
│ │ ├── group.component.tsx
│ │ └── checkbox.type.tsx
├── theme
│ ├── theme.hook.ts
│ ├── index.ts
│ ├── theme.context.ts
│ ├── withTheme.tsx
│ └── theme.provider.tsx
└── utilities
│ ├── useDefaultProps.ts
│ └── withDefaultProps.tsx
├── docs
├── .prettierignore
├── postcss.config.js
├── static
│ └── images
│ │ ├── carbon.png
│ │ ├── hero.png
│ │ ├── ph-cat.png
│ │ ├── ellipse.png
│ │ ├── og-image.png
│ │ ├── preview.png
│ │ ├── docs
│ │ ├── div
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ ├── 5.png
│ │ │ ├── 6.png
│ │ │ └── 7.png
│ │ ├── fab
│ │ │ └── 1.gif
│ │ ├── icon
│ │ │ ├── 1.png
│ │ │ └── 2.png
│ │ ├── tag
│ │ │ └── 1.png
│ │ ├── text
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ └── 5.png
│ │ ├── avatar
│ │ │ └── 1.png
│ │ ├── badge
│ │ │ └── 1.png
│ │ ├── button
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ └── 5.png
│ │ ├── drawer
│ │ │ └── 1.gif
│ │ ├── header
│ │ │ ├── 1.png
│ │ │ └── 2.png
│ │ ├── image
│ │ │ └── 1.png
│ │ ├── input
│ │ │ ├── 1.png
│ │ │ └── 2.png
│ │ ├── modal
│ │ │ └── 1.gif
│ │ ├── radio
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ └── 3.png
│ │ ├── select
│ │ │ └── 1.gif
│ │ ├── toggle
│ │ │ └── 1.gif
│ │ ├── checkbox
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ └── 3.png
│ │ ├── collapse
│ │ │ └── 1.gif
│ │ ├── dropdown
│ │ │ ├── 1.gif
│ │ │ ├── 2.gif
│ │ │ ├── 3.gif
│ │ │ └── 4.png
│ │ ├── overlay
│ │ │ └── 1.gif
│ │ ├── skeleton
│ │ │ └── 1.gif
│ │ ├── snackbar
│ │ │ └── 1.gif
│ │ ├── tooltip
│ │ │ ├── 1.gif
│ │ │ └── 2.gif
│ │ ├── typography
│ │ │ └── 1.png
│ │ ├── colors-system
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ ├── 5.png
│ │ │ ├── 6.png
│ │ │ └── 7.png
│ │ └── examples
│ │ │ ├── example-3.jpeg
│ │ │ └── login-form.jpg
│ │ ├── google-icon.png
│ │ ├── composable-2.png
│ │ ├── dribbble-login.png
│ │ ├── favicon
│ │ ├── favicon.ico
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── mstile-150x150.png
│ │ ├── apple-touch-icon.png
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── browserconfig.xml
│ │ ├── site.webmanifest
│ │ └── safari-pinned-tab.svg
│ │ ├── theme-customization-2.png
│ │ ├── blogs
│ │ ├── using-formik-with-react-native-and-magnus
│ │ │ ├── 1.png
│ │ │ └── 2.gif
│ │ └── how-to-build-theme-switcher-in-react-native-with-magnus
│ │ │ ├── 1.png
│ │ │ └── 2.gif
│ │ ├── section-theme-header.svg
│ │ ├── components.svg
│ │ ├── logo.svg
│ │ ├── section-components-header.svg
│ │ ├── section-composable-header.svg
│ │ ├── typography.svg
│ │ ├── icon-system.svg
│ │ ├── atomic.svg
│ │ ├── spacing.svg
│ │ ├── section-api-header.svg
│ │ └── customization.svg
├── src
│ ├── images
│ │ ├── gatsby-icon.png
│ │ └── gatsby-astronaut.png
│ ├── assets
│ │ └── fonts
│ │ │ ├── icomoon.eot
│ │ │ ├── icomoon.ttf
│ │ │ └── icomoon.woff
│ ├── validators
│ │ └── snippetValidators.js
│ ├── constants
│ │ ├── categories.js
│ │ ├── firebase.js
│ │ ├── theme.js
│ │ └── example.js
│ ├── components
│ │ ├── common
│ │ │ ├── Image.js
│ │ │ ├── SidebarFilter.js
│ │ │ ├── Logo.js
│ │ │ ├── Breadcrumbs.js
│ │ │ ├── SearchResults.js
│ │ │ ├── Seo.js
│ │ │ └── UserDropdown.js
│ │ ├── layout
│ │ │ ├── Layout.js
│ │ │ └── Sidebar.js
│ │ └── home
│ │ │ ├── Colors.js
│ │ │ ├── Customizations.js
│ │ │ ├── Components.js
│ │ │ └── Composable.js
│ ├── services
│ │ └── SnippetService.js
│ └── pages
│ │ ├── 404.js
│ │ ├── index.js
│ │ └── blog.js
├── .prettierrc
├── content
│ ├── snippets
│ │ └── snippets.json
│ └── docs
│ │ ├── examples.md
│ │ ├── getting-started.md
│ │ ├── customization.md
│ │ ├── index.md
│ │ ├── typography.md
│ │ ├── shadows.md
│ │ ├── border-radius.md
│ │ ├── portal
│ │ └── index.md
│ │ ├── modal
│ │ └── index.md
│ │ ├── collapse
│ │ └── index.md
│ │ └── spacing.md
├── gatsby-browser.js
├── config
│ ├── search.js
│ └── mail.js
├── .editorconfig
├── gatsby-ssr.js
└── .gitignore
├── .gitattributes
├── commitlint.config.js
├── babel.config.js
├── .husky
├── pre-commit
└── commit-msg
├── .prettierrc.js
├── .eslintrc
├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── feature-request.md
│ ├── bug_report.md
│ └── documentation-improvement.md
└── workflows
│ └── expo.yml
├── tsconfig.json
├── .gitignore
└── LICENSE
/example/assets/styles/fonts.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # XDE
2 | #
3 | .expo/
4 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | docs/public
3 | lib/
4 |
--------------------------------------------------------------------------------
/example/App.js:
--------------------------------------------------------------------------------
1 | export { default } from './src/index';
2 |
--------------------------------------------------------------------------------
/src/style/index.ts:
--------------------------------------------------------------------------------
1 | export { defaultTheme } from './defaultTheme';
2 |
--------------------------------------------------------------------------------
/docs/.prettierignore:
--------------------------------------------------------------------------------
1 | .cache
2 | package.json
3 | package-lock.json
4 | public
5 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 | # specific for windows script files
3 | *.bat text eol=crlf
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-conventional'],
3 | };
4 |
--------------------------------------------------------------------------------
/docs/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = () => ({
2 | plugins: [require('tailwindcss')],
3 | });
4 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:metro-react-native-babel-preset'],
3 | };
4 |
--------------------------------------------------------------------------------
/example/App.web.js:
--------------------------------------------------------------------------------
1 | import './assets/styles/fonts.css';
2 |
3 | export { default } from './src/index';
4 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | yarn run pretty-quick --staged
5 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx --no -- commitlint --edit "${1}"
5 |
--------------------------------------------------------------------------------
/docs/static/images/carbon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/carbon.png
--------------------------------------------------------------------------------
/docs/static/images/hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/hero.png
--------------------------------------------------------------------------------
/docs/static/images/ph-cat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/ph-cat.png
--------------------------------------------------------------------------------
/docs/src/images/gatsby-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/src/images/gatsby-icon.png
--------------------------------------------------------------------------------
/docs/static/images/ellipse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/ellipse.png
--------------------------------------------------------------------------------
/docs/static/images/og-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/og-image.png
--------------------------------------------------------------------------------
/docs/static/images/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/preview.png
--------------------------------------------------------------------------------
/example/assets/images/beach.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/beach.jpg
--------------------------------------------------------------------------------
/example/assets/images/city.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/city.jpg
--------------------------------------------------------------------------------
/docs/src/assets/fonts/icomoon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/src/assets/fonts/icomoon.eot
--------------------------------------------------------------------------------
/docs/src/assets/fonts/icomoon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/src/assets/fonts/icomoon.ttf
--------------------------------------------------------------------------------
/docs/src/assets/fonts/icomoon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/src/assets/fonts/icomoon.woff
--------------------------------------------------------------------------------
/docs/static/images/docs/div/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/div/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/div/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/div/2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/div/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/div/3.png
--------------------------------------------------------------------------------
/docs/static/images/docs/div/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/div/4.png
--------------------------------------------------------------------------------
/docs/static/images/docs/div/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/div/5.png
--------------------------------------------------------------------------------
/docs/static/images/docs/div/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/div/6.png
--------------------------------------------------------------------------------
/docs/static/images/docs/div/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/div/7.png
--------------------------------------------------------------------------------
/docs/static/images/docs/fab/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/fab/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/icon/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/icon/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/icon/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/icon/2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/tag/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/tag/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/text/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/text/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/text/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/text/2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/text/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/text/3.png
--------------------------------------------------------------------------------
/docs/static/images/docs/text/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/text/4.png
--------------------------------------------------------------------------------
/docs/static/images/docs/text/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/text/5.png
--------------------------------------------------------------------------------
/docs/static/images/google-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/google-icon.png
--------------------------------------------------------------------------------
/example/assets/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/avatar.png
--------------------------------------------------------------------------------
/example/assets/images/bridge.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/bridge.jpg
--------------------------------------------------------------------------------
/example/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/favicon.png
--------------------------------------------------------------------------------
/example/assets/images/favorite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/favorite.png
--------------------------------------------------------------------------------
/example/assets/images/forest.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/forest.jpg
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './theme';
2 | export * from './ui';
3 | export * from './utilities';
4 | export * from './style';
5 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | singleQuote: true,
3 | tabWidth: 2,
4 | trailingComma: 'es5',
5 | useTabs: false,
6 | };
7 |
--------------------------------------------------------------------------------
/docs/src/images/gatsby-astronaut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/src/images/gatsby-astronaut.png
--------------------------------------------------------------------------------
/docs/static/images/composable-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/composable-2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/avatar/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/avatar/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/badge/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/badge/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/button/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/button/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/button/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/button/2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/button/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/button/3.png
--------------------------------------------------------------------------------
/docs/static/images/docs/button/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/button/4.png
--------------------------------------------------------------------------------
/docs/static/images/docs/button/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/button/5.png
--------------------------------------------------------------------------------
/docs/static/images/docs/drawer/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/drawer/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/header/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/header/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/header/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/header/2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/image/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/image/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/input/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/input/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/input/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/input/2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/modal/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/modal/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/radio/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/radio/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/radio/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/radio/2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/radio/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/radio/3.png
--------------------------------------------------------------------------------
/docs/static/images/docs/select/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/select/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/toggle/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/toggle/1.gif
--------------------------------------------------------------------------------
/example/assets/images/chameleon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/chameleon.jpg
--------------------------------------------------------------------------------
/example/assets/images/email-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/email-icon.png
--------------------------------------------------------------------------------
/src/ui/tag/tag.type.tsx:
--------------------------------------------------------------------------------
1 | import { ButtonProps } from '../button/button.type';
2 |
3 | export interface TagProps extends ButtonProps {}
4 |
--------------------------------------------------------------------------------
/docs/static/images/docs/checkbox/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/checkbox/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/checkbox/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/checkbox/2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/checkbox/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/checkbox/3.png
--------------------------------------------------------------------------------
/docs/static/images/docs/collapse/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/collapse/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/dropdown/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/dropdown/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/dropdown/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/dropdown/2.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/dropdown/3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/dropdown/3.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/dropdown/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/dropdown/4.png
--------------------------------------------------------------------------------
/docs/static/images/docs/overlay/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/overlay/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/skeleton/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/skeleton/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/snackbar/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/snackbar/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/tooltip/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/tooltip/1.gif
--------------------------------------------------------------------------------
/docs/static/images/docs/tooltip/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/tooltip/2.gif
--------------------------------------------------------------------------------
/docs/static/images/dribbble-login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/dribbble-login.png
--------------------------------------------------------------------------------
/docs/static/images/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/favicon/favicon.ico
--------------------------------------------------------------------------------
/example/assets/images/strawberries.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/strawberries.jpg
--------------------------------------------------------------------------------
/example/assets/images/wrecked-ship.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/images/wrecked-ship.jpg
--------------------------------------------------------------------------------
/src/ui/input/textarea.type.tsx:
--------------------------------------------------------------------------------
1 | import { InputProps } from './input.type';
2 |
3 | export interface TextareaProps extends InputProps {}
4 |
--------------------------------------------------------------------------------
/docs/static/images/docs/typography/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/typography/1.png
--------------------------------------------------------------------------------
/docs/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "endOfLine": "lf",
3 | "semi": true,
4 | "singleQuote": true,
5 | "tabWidth": 2,
6 | "trailingComma": "es5"
7 | }
8 |
--------------------------------------------------------------------------------
/docs/static/images/docs/colors-system/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/colors-system/1.png
--------------------------------------------------------------------------------
/docs/static/images/docs/colors-system/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/colors-system/2.png
--------------------------------------------------------------------------------
/docs/static/images/docs/colors-system/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/colors-system/3.png
--------------------------------------------------------------------------------
/docs/static/images/docs/colors-system/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/colors-system/4.png
--------------------------------------------------------------------------------
/docs/static/images/docs/colors-system/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/colors-system/5.png
--------------------------------------------------------------------------------
/docs/static/images/docs/colors-system/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/colors-system/6.png
--------------------------------------------------------------------------------
/docs/static/images/docs/colors-system/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/colors-system/7.png
--------------------------------------------------------------------------------
/docs/static/images/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/docs/static/images/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/docs/static/images/theme-customization-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/theme-customization-2.png
--------------------------------------------------------------------------------
/example/assets/fonts/HanaleiFill-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/fonts/HanaleiFill-Regular.ttf
--------------------------------------------------------------------------------
/example/assets/fonts/Inconsolata-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/example/assets/fonts/Inconsolata-Regular.ttf
--------------------------------------------------------------------------------
/docs/static/images/favicon/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/favicon/mstile-150x150.png
--------------------------------------------------------------------------------
/docs/content/snippets/snippets.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 1,
3 | "title": "title",
4 | "slug": "div",
5 | "category": "buttons",
6 | "published": true
7 | }
8 |
--------------------------------------------------------------------------------
/docs/static/images/docs/examples/example-3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/examples/example-3.jpeg
--------------------------------------------------------------------------------
/docs/static/images/docs/examples/login-form.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/docs/examples/login-form.jpg
--------------------------------------------------------------------------------
/docs/static/images/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/docs/static/images/favicon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/favicon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/docs/static/images/favicon/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/favicon/android-chrome-512x512.png
--------------------------------------------------------------------------------
/docs/src/validators/snippetValidators.js:
--------------------------------------------------------------------------------
1 | import * as yup from 'yup';
2 |
3 | export const submitSnippetValidator = yup.object().shape({
4 | embed: yup.string().required().min(1),
5 | });
6 |
--------------------------------------------------------------------------------
/example/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "settings": {
3 | "import/core-modules": [ "react-native-magnus" ]
4 | },
5 |
6 | "rules": {
7 | "react/prop-types": "off"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/docs/static/images/blogs/using-formik-with-react-native-and-magnus/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/blogs/using-formik-with-react-native-and-magnus/1.png
--------------------------------------------------------------------------------
/docs/static/images/blogs/using-formik-with-react-native-and-magnus/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/blogs/using-formik-with-react-native-and-magnus/2.gif
--------------------------------------------------------------------------------
/docs/gatsby-browser.js:
--------------------------------------------------------------------------------
1 | import 'prismjs/themes/prism.css';
2 | import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
3 | import './src/assets/fonts/icomoon.css';
4 | import './src/assets/css/tailwind.css';
5 |
--------------------------------------------------------------------------------
/example/index.d.ts:
--------------------------------------------------------------------------------
1 | type Toast = React.RefObject<
2 | import('react-native-magnus').SnackbarRef
3 | >['current'];
4 |
5 | interface Global {
6 | toast: Toast;
7 | }
8 |
9 | declare var global: Global;
10 |
--------------------------------------------------------------------------------
/src/ui/dropdown/dropdown.option.type.tsx:
--------------------------------------------------------------------------------
1 | import { ButtonProps } from '../button/button.type';
2 |
3 | export interface DropdownOptionProps extends ButtonProps {
4 | value: any;
5 | onSelect?: (value: any) => void;
6 | }
7 |
--------------------------------------------------------------------------------
/docs/config/search.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 |
3 | module.exports = {
4 | algolia: {
5 | app_id: process.env.GATSBY_ALGOLIA_APP_ID,
6 | admin_api_key: process.env.GATSBY_ALGOLIA_ADMIN_API_KEY,
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/docs/static/images/blogs/how-to-build-theme-switcher-in-react-native-with-magnus/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/blogs/how-to-build-theme-switcher-in-react-native-with-magnus/1.png
--------------------------------------------------------------------------------
/docs/static/images/blogs/how-to-build-theme-switcher-in-react-native-with-magnus/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/react-native-magnus/HEAD/docs/static/images/blogs/how-to-build-theme-switcher-in-react-native-with-magnus/2.gif
--------------------------------------------------------------------------------
/docs/config/mail.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 |
3 | module.exports = {
4 | mailchimp: {
5 | url: 'https://us3.api.mailchimp.com/3.0',
6 | key: process.env.MAILCHIMP_KEY,
7 | list: 'd7cb42178b',
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/src/theme/theme.hook.ts:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react';
2 |
3 | import { ThemeContext, ThemeContextType } from './theme.context';
4 |
5 | export const useTheme = (): ThemeContextType => {
6 | const themeContext = useContext(ThemeContext);
7 | return themeContext;
8 | };
9 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@react-native-community"],
3 | "rules": {
4 | "@typescript-eslint/no-unused-vars": [
5 | "warn",
6 | { "argsIgnorePattern": "^_" }
7 | ],
8 | "no-unused-vars": "off",
9 | "react-hooks/exhaustive-deps": "off"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/docs/src/constants/categories.js:
--------------------------------------------------------------------------------
1 | export const categories = [
2 | { label: 'Buttons', value: 'buttons' },
3 | { label: 'Forms', value: 'forms' },
4 | { label: 'Navigations', value: 'navigations' },
5 | { label: 'Pages', value: 'pages' },
6 | { label: 'Misc', value: 'misc' },
7 | ];
8 |
--------------------------------------------------------------------------------
/docs/src/components/common/Image.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default function Image({ src, footer = null }) {
4 | return (
5 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/src/ui/carousel/item.carousel.tsx:
--------------------------------------------------------------------------------
1 | import React, { ReactNode } from 'react';
2 |
3 | interface CarouselItemProps {
4 | children: ReactNode;
5 | }
6 |
7 | const CarouselItem = ({ children }: CarouselItemProps) => {
8 | return <>{children}>;
9 | };
10 |
11 | export default CarouselItem;
12 |
--------------------------------------------------------------------------------
/src/ui/header/header.type.tsx:
--------------------------------------------------------------------------------
1 | import { PrefixSuffixPropsType, TextPropsType } from '../../types';
2 | import { DivProps } from '../div/div.type';
3 |
4 | export interface HeaderProps
5 | extends DivProps,
6 | PrefixSuffixPropsType,
7 | TextPropsType {
8 | alignment?: 'center' | 'left';
9 | }
10 |
--------------------------------------------------------------------------------
/src/theme/index.ts:
--------------------------------------------------------------------------------
1 | export { withTheme } from './withTheme';
2 | export { ThemeContext } from './theme.context';
3 | export { ThemeProvider, ThemeProviderProps } from './theme.provider';
4 | export { getThemeProperty } from './theme.service';
5 | export { useTheme } from './theme.hook';
6 | export { ThemeType } from './type';
7 |
--------------------------------------------------------------------------------
/docs/static/images/favicon/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/static/images/section-theme-header.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 |
9 | indent_style = space
10 | indent_size = 2
11 |
12 | end_of_line = lf
13 | charset = utf-8
14 | trim_trailing_whitespace = true
15 | insert_final_newline = true
16 |
--------------------------------------------------------------------------------
/src/ui/skeleton/skeleton.type.tsx:
--------------------------------------------------------------------------------
1 | import { DivProps } from '../div/div.type';
2 | import { Skeleton, Circle } from './skeleton.component';
3 |
4 | export type CompundedSkeleton
= React.FunctionComponent
& {
5 | Box: typeof Skeleton;
6 | Circle: typeof Circle;
7 | };
8 |
9 | export interface SkeletonProps extends DivProps {
10 | duration?: number;
11 | }
12 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: 🚀 Getting started
4 | url: https://magnus-ui.com/docs/getting-started/
5 | about: Head over to this link to get started
6 | - name: 🤔 Questions and Help
7 | url: https://discord.com/invite/SYnXGEy
8 | about: Reach out to us on discord or our github discussions page.
9 |
--------------------------------------------------------------------------------
/docs/src/constants/firebase.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | apiKey: 'AIzaSyAVazACwi3rnYe7SKEG27VdW3i9nn8i7Bg',
3 | authDomain: 'magnus-ui-cbee6.firebaseapp.com',
4 | projectId: 'magnus-ui-cbee6',
5 | storageBucket: 'magnus-ui-cbee6.appspot.com',
6 | messagingSenderId: '169374965013',
7 | appId: '1:169374965013:web:9a9ab4c9964c7a24575d1c',
8 | };
9 |
10 | export default config;
11 |
--------------------------------------------------------------------------------
/docs/static/images/components.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/theme/theme.context.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { defaultTheme } from '../style';
3 |
4 | import { ThemeType } from './type';
5 |
6 | export interface ThemeContextType {
7 | theme: ThemeType;
8 | setTheme: (theme: ThemeType) => void;
9 | }
10 |
11 | export const ThemeContext: React.Context =
12 | React.createContext({
13 | theme: defaultTheme,
14 | setTheme: (_theme: ThemeType) => {},
15 | });
16 |
--------------------------------------------------------------------------------
/docs/static/images/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/theme/withTheme.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { ThemeContext } from './theme.context';
3 |
4 | /**
5 | * passes theme to prop of Component
6 | *
7 | * @param Component
8 | */
9 | export const withTheme = (Component: React.ComponentType) => (props: any) =>
10 | (
11 |
12 | {(contexts) => {
13 | return ;
14 | }}
15 |
16 | );
17 |
--------------------------------------------------------------------------------
/docs/src/components/common/SidebarFilter.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default function SidebarFilter({ onChange }) {
4 | return (
5 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/docs/static/images/section-components-header.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/docs/static/images/favicon/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "short_name": "",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/docs/static/images/section-composable-header.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/ui/portal/portal.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { Context } from './host.component';
4 | import { Consumer } from './consumer.component';
5 |
6 | interface IPortalProps {
7 | children: React.ReactNode;
8 | }
9 |
10 | export const Portal = ({ children }: IPortalProps): JSX.Element => (
11 |
12 | {(manager): JSX.Element => (
13 | {children}
14 | )}
15 |
16 | );
17 |
--------------------------------------------------------------------------------
/docs/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 |
9 | # change these settings to your own preference
10 | indent_style = space
11 | indent_size = 2
12 |
13 | # we recommend you to keep these unchanged
14 | end_of_line = lf
15 | charset = utf-8
16 | trim_trailing_whitespace = true
17 | insert_final_newline = true
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F6E0️ Feature request"
3 | about: Suggest an idea to improve magnus
4 | title: '[Feature]'
5 | labels: ''
6 | assignees: jsartisan
7 | ---
8 |
9 | ## Summary
10 |
11 | One paragraph description of the feature.
12 |
13 | ## Motivation
14 |
15 | Why should this be worked on? What problems or use cases does it solve or
16 | improve?
17 |
18 | ## Additional Context
19 |
20 | Any other context or screenshots or link that you
21 | pertain to the feature.
22 |
--------------------------------------------------------------------------------
/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "react-native-magnus": ["../src"]
7 | },
8 | "jsx": "react-native",
9 | "target": "esnext",
10 | "lib": ["esnext"],
11 | "allowJs": true,
12 | "skipLibCheck": true,
13 | "noEmit": true,
14 | "allowSyntheticDefaultImports": true,
15 | "resolveJsonModule": true,
16 | "esModuleInterop": true,
17 | "moduleResolution": "node"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F41B Bug report"
3 | about: Create a bug report to help us improve magnus
4 | title: '[Bug]'
5 | labels: Bug, Needs Triaging
6 | assignees: jsartisan
7 | ---
8 |
9 | ## Description
10 |
11 | [What happened]
12 |
13 | ### Steps to reproduce the behaviour:
14 |
15 | Add steps to reproduce this behaviour, include console / network logs & screenshots
16 |
17 | ### Important Details
18 |
19 | - Version: [Cloud / Self-Hosted vx.x]
20 | - OS: [e.g.MacOSX]
21 | - Browser [e.g. chrome, safari]
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/documentation-improvement.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F4D6 Documentation Improvement"
3 | about: Suggest improvements to our documentation
4 | title: '[Docs] '
5 | labels: Documentation
6 | assignees: jsartisan
7 | ---
8 |
9 | ## Documentation Link
10 |
11 | Add a link to the page which needs improvement (if relevant)
12 |
13 | ## Describe the problem
14 |
15 | Is the documentation missing? Or is it confusing? Why is it confusing?
16 |
17 | ## Describe the improvement
18 |
19 | A clear and concise description of the improvement.
20 |
--------------------------------------------------------------------------------
/src/ui/animated/animated.type.tsx:
--------------------------------------------------------------------------------
1 | import { DivProps } from '../div/div.type';
2 | import {
3 | BorderPropsType,
4 | SpacingPropsType,
5 | RoundedPropsType,
6 | ShadowPropsType,
7 | VariantPropsType,
8 | } from '../../types';
9 |
10 | export interface AnimatedProps
11 | extends DivProps,
12 | BorderPropsType,
13 | SpacingPropsType,
14 | RoundedPropsType,
15 | ShadowPropsType,
16 | VariantPropsType {
17 | animation?: 'fromRight' | 'fromLeft' | 'fromTop' | 'fromBottom' | 'fade';
18 | duration?: number;
19 | delay?: number;
20 | }
21 |
--------------------------------------------------------------------------------
/example/babel.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const pak = require('../package.json');
3 |
4 | module.exports = function (api) {
5 | api.cache(true);
6 |
7 | return {
8 | presets: ['babel-preset-expo'],
9 | plugins: [
10 | [
11 | 'module-resolver',
12 | {
13 | alias: {
14 | // For development, we want to alias the library to the source
15 | [pak.name]: path.join(__dirname, '..', pak.source),
16 | },
17 | },
18 | ],
19 | 'react-native-reanimated/plugin',
20 | ],
21 | };
22 | };
23 |
--------------------------------------------------------------------------------
/docs/src/components/layout/Layout.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Link } from 'gatsby';
3 |
4 | import Logo from '../common/Logo';
5 | import Footer from './Footer';
6 | import Header from './Header';
7 | import Sidebar from './Sidebar';
8 |
9 | const Layout = ({ children, type }) => {
10 | return (
11 |
12 |
13 | <>{children}>
14 |
15 | {type === 'docs' ? <>> :
}
16 |
17 | );
18 | };
19 |
20 | export default Layout;
21 |
--------------------------------------------------------------------------------
/example/.expo-shared/README.md:
--------------------------------------------------------------------------------
1 | > Why do I have a folder named ".expo-shared" in my project?
2 |
3 | The ".expo-shared" folder is created when running commands that produce state that is intended to be shared with all developers on the project. For example, "npx expo-optimize".
4 |
5 | > What does the "assets.json" file contain?
6 |
7 | The "assets.json" file describes the assets that have been optimized through "expo-optimize" and do not need to be processed again.
8 |
9 | > Should I commit the ".expo-shared" folder?
10 |
11 | Yes, you should share the ".expo-shared" folder with your collaborators.
12 |
--------------------------------------------------------------------------------
/example/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 | App
12 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/docs/src/components/common/Logo.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'gatsby';
3 |
4 | const Logo = ({
5 | hasText = false,
6 | hasImage = true,
7 | center = false,
8 | centerMobile = false,
9 | }) => (
10 |
11 |
12 | {hasImage && }
13 | {hasText && (
14 |
15 | magnus
16 |
17 | )}
18 |
19 |
20 | );
21 |
22 | export default Logo;
23 |
--------------------------------------------------------------------------------
/example/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "React Native Magnus Example",
4 | "description": "Example app for React Native Magnus: https://magnus-ui.com/",
5 | "slug": "react-native-magnus-example",
6 | "privacy": "public",
7 | "version": "1.0.0",
8 | "orientation": "default",
9 | "icon": "./assets/images/favicon.png",
10 | "primaryColor": "#cccccc",
11 | "userInterfaceStyle": "automatic",
12 | "notification": {
13 | "icon": "https://s3.amazonaws.com/exp-us-standard/placeholder-push-icon-blue-circle.png",
14 | "color": "#000000"
15 | },
16 | "platforms": ["android", "ios", "web"]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/example/src/utils/ExamplePage.tsx:
--------------------------------------------------------------------------------
1 | import React, { ReactNode } from 'react';
2 | import { SafeAreaView } from 'react-native';
3 | import { StatusBar, Div } from 'react-native-magnus';
4 |
5 | interface ExamplePageProps {
6 | children: ReactNode;
7 | }
8 |
9 | const ExamplePage = ({ children }: ExamplePageProps) => {
10 | return (
11 | <>
12 |
13 |
14 |
15 |
16 | {children}
17 |
18 |
19 | >
20 | );
21 | };
22 |
23 | export default ExamplePage;
24 |
--------------------------------------------------------------------------------
/src/ui/scrolldiv/scrolldiv.type.ts:
--------------------------------------------------------------------------------
1 | import { ScrollViewProps as RNScrollViewProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | DimensionPropsType,
5 | FlexPropsType,
6 | PositionPropsType,
7 | BorderPropsType,
8 | SpacingPropsType,
9 | RoundedPropsType,
10 | ShadowPropsType,
11 | VariantPropsType,
12 | } from '../../types';
13 |
14 | export interface ScrollDivProps
15 | extends RNScrollViewProps,
16 | BorderPropsType,
17 | SpacingPropsType,
18 | ShadowPropsType,
19 | RoundedPropsType,
20 | FlexPropsType,
21 | PositionPropsType,
22 | DimensionPropsType,
23 | BackgroundPropsType,
24 | VariantPropsType {}
25 |
--------------------------------------------------------------------------------
/src/ui/drawer/drawer.type.tsx:
--------------------------------------------------------------------------------
1 | import { ViewProps as RNViewProps } from 'react-native';
2 | import { ModalProps as RNModalProps } from '../modal/modal.type';
3 |
4 | import {
5 | BorderPropsType,
6 | RoundedPropsType,
7 | BackgroundPropsType,
8 | VariantPropsType,
9 | } from '../../types';
10 |
11 | export interface DrawerRef {
12 | close: () => void;
13 | open: () => void;
14 | }
15 |
16 | export interface DrawerProps
17 | extends Omit,
18 | RNViewProps,
19 | BorderPropsType,
20 | RoundedPropsType,
21 | Pick,
22 | VariantPropsType {
23 | direction?: 'left' | 'right';
24 | drawerPercentage?: number;
25 | animationTime?: number;
26 | }
27 |
--------------------------------------------------------------------------------
/src/ui/div/div.spec.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react-native';
3 |
4 | import { ThemeProvider } from '../../theme';
5 | import { Div } from './div.component';
6 | import { DivProps } from './div.type';
7 | import { Text } from '../text/text.component';
8 |
9 | describe('Div component', () => {
10 | const TestDiv: React.FC = (props) => (
11 |
12 |
13 |
14 | );
15 |
16 | it('should render component passed to children', () => {
17 | render(
18 |
19 | I love magnus ui
20 |
21 | );
22 |
23 | expect(screen.getByText('I love magnus ui')).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/ui/text/text.type.ts:
--------------------------------------------------------------------------------
1 | import { TextProps as RNTextProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | DimensionPropsType,
5 | FlexPropsType,
6 | OpacityPropsType,
7 | OverflowPropsType,
8 | TextPropsType,
9 | ZIndexPropsType,
10 | BorderPropsType,
11 | SpacingPropsType,
12 | RoundedPropsType,
13 | VariantPropsType,
14 | } from '../../types';
15 |
16 | export interface TextProps
17 | extends RNTextProps,
18 | SpacingPropsType,
19 | RoundedPropsType,
20 | BorderPropsType,
21 | TextPropsType,
22 | DimensionPropsType,
23 | OverflowPropsType,
24 | OpacityPropsType,
25 | ZIndexPropsType,
26 | Pick,
27 | Pick,
28 | VariantPropsType {}
29 |
--------------------------------------------------------------------------------
/src/ui/avatar/avatar.group.type.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | BackgroundPropsType,
3 | DimensionPropsType,
4 | FlexPropsType,
5 | OpacityPropsType,
6 | OverflowPropsType,
7 | PositionPropsType,
8 | ZIndexPropsType,
9 | BorderPropsType,
10 | SpacingPropsType,
11 | RoundedPropsType,
12 | ShadowPropsType,
13 | } from '../../types';
14 |
15 | export interface AvatarGroupProps
16 | extends BorderPropsType,
17 | SpacingPropsType,
18 | RoundedPropsType,
19 | ShadowPropsType,
20 | DimensionPropsType,
21 | BackgroundPropsType,
22 | FlexPropsType,
23 | PositionPropsType,
24 | OverflowPropsType,
25 | OpacityPropsType,
26 | ZIndexPropsType {
27 | offset?: string | number;
28 | children: React.ReactElement[] | React.ReactElement;
29 | }
30 |
--------------------------------------------------------------------------------
/docs/src/services/SnippetService.js:
--------------------------------------------------------------------------------
1 | import '@firebase/database';
2 | import { firebase } from '@firebase/app';
3 |
4 | import firebaseConfig from '../constants/firebase';
5 |
6 | if (!firebase.apps.length) {
7 | firebase.initializeApp(firebaseConfig);
8 | }
9 |
10 | const database = firebase.database();
11 | const db = database.ref('/snippets');
12 |
13 | class SnippetService {
14 | getAll() {
15 | return db;
16 | }
17 |
18 | create(tutorial) {
19 | return db.push(tutorial);
20 | }
21 |
22 | update(key, value) {
23 | return db.child(key).update(value);
24 | }
25 |
26 | delete(key) {
27 | return db.child(key).remove();
28 | }
29 |
30 | deleteAll() {
31 | return db.remove();
32 | }
33 | }
34 |
35 | export default new SnippetService();
36 |
--------------------------------------------------------------------------------
/src/ui/tooltip/triangle.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { View as RNView, StyleSheet } from 'react-native';
3 | import { useDefaultProps } from '../../utilities/useDefaultProps';
4 | import { TriangleProps } from './tooltip.type';
5 |
6 | const Triangle: React.FunctionComponent = (incomingProps) => {
7 | const props = useDefaultProps(null, incomingProps, {
8 | invert: true,
9 | });
10 |
11 | const { style, invert } = props;
12 | let computedStyle = style;
13 |
14 | if (invert) {
15 | computedStyle = StyleSheet.flatten([
16 | style,
17 | {
18 | transform: [{ rotate: '180deg' }],
19 | },
20 | ]);
21 | }
22 |
23 | return ;
24 | };
25 |
26 | export { Triangle };
27 |
--------------------------------------------------------------------------------
/src/ui/image/image.type.tsx:
--------------------------------------------------------------------------------
1 | import { ImageProps as RNImageProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | DimensionPropsType,
5 | FlexPropsType,
6 | OpacityPropsType,
7 | PositionPropsType,
8 | ZIndexPropsType,
9 | BorderPropsType,
10 | SpacingPropsType,
11 | RoundedPropsType,
12 | ShadowPropsType,
13 | VariantPropsType,
14 | } from '../../types';
15 |
16 | export interface ImageProps
17 | extends RNImageProps,
18 | BorderPropsType,
19 | SpacingPropsType,
20 | ShadowPropsType,
21 | RoundedPropsType,
22 | DimensionPropsType,
23 | PositionPropsType,
24 | OpacityPropsType,
25 | ZIndexPropsType,
26 | Pick,
27 | Pick,
28 | VariantPropsType {}
29 |
--------------------------------------------------------------------------------
/src/ui/div/div.type.tsx:
--------------------------------------------------------------------------------
1 | import { ViewProps as RNViewProps } from 'react-native';
2 |
3 | import {
4 | BorderPropsType,
5 | SpacingPropsType,
6 | RoundedPropsType,
7 | ShadowPropsType,
8 | DimensionPropsType,
9 | BackgroundPropsType,
10 | FlexPropsType,
11 | PositionPropsType,
12 | ZIndexPropsType,
13 | OverflowPropsType,
14 | OpacityPropsType,
15 | VariantPropsType,
16 | } from '../../types';
17 |
18 | export interface DivProps
19 | extends RNViewProps,
20 | BorderPropsType,
21 | SpacingPropsType,
22 | RoundedPropsType,
23 | ShadowPropsType,
24 | DimensionPropsType,
25 | BackgroundPropsType,
26 | FlexPropsType,
27 | PositionPropsType,
28 | ZIndexPropsType,
29 | OverflowPropsType,
30 | OpacityPropsType,
31 | VariantPropsType {}
32 |
--------------------------------------------------------------------------------
/example/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "804582a5e1d2e3587b17eecae610b2365798a0d5e9f6378a19144005e19feb59": true,
3 | "2c5c2b4da600282d60be1a0acf5f1a43b698d8670433a34b97175e5965e47b0b": true,
4 | "98532ebaa814a5da6dabb073711f8c0d9a6b9cef99d9ab117176962953cc53c0": true,
5 | "239809afd3d71d8e3cbe0487519561d347661ec0f508f368359b20b71e79c26f": true,
6 | "29da92e2d65a3f4f911fd1dcb5c7cb23d728c61cc553e210ce00056c0297bffe": true,
7 | "919c6b88f383a72f82dbd5a4835626857143e98fc52dfa75baccddd3caaf767b": true,
8 | "41e9368d29185999b484dcf266fd1cb5d7b05892a959cc3932aa7220a6a594d2": true,
9 | "b158b11c4da1fd7890c844bc01b5965230fb20a02634a58100ad7d10510c005f": true,
10 | "03a142de99d255f09929c0acd5730dd8675cb8dfb28a487e1ca9c8c586d8ebb7": true,
11 | "4b68d3294e8c0e0327755c766a7fc45894a2c802056042c544708570d4f3d5ea": true
12 | }
13 |
--------------------------------------------------------------------------------
/src/ui/tag/tag.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { TagProps } from './tag.type';
4 | import { useDefaultProps } from '../../utilities/useDefaultProps';
5 | import { Button } from '../button/button.component';
6 |
7 | const Tag: React.FunctionComponent = (incomingProps) => {
8 | const props = useDefaultProps('Tag', incomingProps, {
9 | px: 'lg',
10 | py: 'sm',
11 | bg: 'gray400',
12 | color: 'black',
13 | fontSize: 'lg',
14 | textAlign: 'auto',
15 | textTransform: 'none',
16 | rounded: 'md',
17 | borderWidth: 0,
18 | borderColor: 'transparent',
19 | onPress: () => {},
20 | });
21 |
22 | const { underlayColor, ...rest } = props;
23 |
24 | return ;
25 | };
26 |
27 | export { Tag };
28 |
--------------------------------------------------------------------------------
/example/src/utils/ExampleSection.tsx:
--------------------------------------------------------------------------------
1 | import React, { ReactNode } from 'react';
2 | import { Div, Text } from 'react-native-magnus';
3 |
4 | interface ExampleSectionProps {
5 | name: string;
6 | withoutSpacingOnContent?: boolean;
7 | children: ReactNode;
8 | }
9 |
10 | const ExampleSection = ({
11 | name,
12 | withoutSpacingOnContent,
13 | children,
14 | }: ExampleSectionProps) => {
15 | return (
16 |
17 |
26 | {name}
27 |
28 |
29 |
{children}
30 |
31 | );
32 | };
33 |
34 | export default ExampleSection;
35 |
--------------------------------------------------------------------------------
/src/ui/overlay/overlay.type.tsx:
--------------------------------------------------------------------------------
1 | import { ModalProps as RNModalProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | DimensionPropsType,
5 | FlexPropsType,
6 | OverlayPropsType,
7 | SpacingPropsType,
8 | RoundedPropsType,
9 | VariantPropsType,
10 | } from '../../types';
11 |
12 | export interface OverlayRef {
13 | close: () => void;
14 | open: () => void;
15 | }
16 |
17 | export interface OverlayProps
18 | extends RNModalProps,
19 | SpacingPropsType,
20 | RoundedPropsType,
21 | OverlayPropsType,
22 | Pick,
23 | Pick<
24 | FlexPropsType,
25 | 'flex' | 'justifyContent' | 'alignItems' | 'flexDir' | 'flexWrap'
26 | >,
27 | Pick,
28 | VariantPropsType {
29 | onBackdropPress?: () => void;
30 | }
31 |
--------------------------------------------------------------------------------
/src/ui/toggle/toggle.type.tsx:
--------------------------------------------------------------------------------
1 | import { TouchableOpacityProps as RNTouchableOpacityProps } from 'react-native';
2 |
3 | import {
4 | BackgroundPropsType,
5 | DimensionPropsType,
6 | DisabledPropsType,
7 | BorderPropsType,
8 | SpacingPropsType,
9 | RoundedPropsType,
10 | VariantPropsType,
11 | } from '../../types';
12 |
13 | export interface ToggleProps
14 | extends SpacingPropsType,
15 | RoundedPropsType,
16 | BorderPropsType,
17 | DisabledPropsType,
18 | Pick,
19 | Pick,
20 | Pick,
21 | DisabledPropsType,
22 | VariantPropsType {
23 | testID?: string;
24 | on?: boolean;
25 | onPress: () => void;
26 | activeBg?: string;
27 | circleBg?: string;
28 | activeCircleBg?: string;
29 | duration?: number;
30 | }
31 |
--------------------------------------------------------------------------------
/src/ui/carousel/carousel.type.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 | import {
3 | FlexPropsType,
4 | BorderPropsType,
5 | RoundedPropsType,
6 | ShadowPropsType,
7 | SpacingPropsType,
8 | VariantPropsType,
9 | } from '../../types';
10 |
11 | import CarouselItem from './item.carousel';
12 |
13 | interface CarouselIndicator {
14 | selectedPage: number;
15 | totalPages: number;
16 | }
17 |
18 | export interface CarouselProps
19 | extends BorderPropsType,
20 | RoundedPropsType,
21 | ShadowPropsType,
22 | SpacingPropsType,
23 | Pick,
24 | VariantPropsType {
25 | showIndicators?: boolean;
26 | renderIndicators?: (props: CarouselIndicator) => JSX.Element;
27 | children: ReactNode;
28 | }
29 |
30 | export interface CompoundedCarousel extends React.FC {
31 | Item: typeof CarouselItem;
32 | }
33 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "paths": {
5 | "react-native-magnus": ["./src/index"]
6 | },
7 | "allowUnreachableCode": false,
8 | "allowUnusedLabels": false,
9 | "esModuleInterop": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "jsx": "react",
12 | "lib": ["esnext"],
13 | "module": "esnext",
14 | "moduleResolution": "node",
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitReturns": true,
17 | "noImplicitUseStrict": false,
18 | "noStrictGenericChecks": false,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "resolveJsonModule": true,
22 | "skipLibCheck": true,
23 | "strict": true,
24 | "target": "esnext",
25 | "types": ["react-native", "jest"]
26 | },
27 | "exclude": ["./**/*.spec.ts", "./**/*.spec.tsx"]
28 | }
29 |
--------------------------------------------------------------------------------
/example/src/components/Drawer.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button, Drawer, Text, DrawerRef } from 'react-native-magnus';
3 |
4 | import ExamplePage from '../utils/ExamplePage';
5 | import ExampleHeader from '../utils/ExampleHeader';
6 | import ExampleSection from '../utils/ExampleSection';
7 |
8 | const DrawerComponent = () => {
9 | const drawerRef = React.useRef(null);
10 |
11 | return (
12 |
13 |
14 |
15 |
16 |
17 | Hello! I'm a drawer.
18 |
19 |
20 | drawerRef.current?.open()}>
21 | Open Drawer
22 |
23 |
24 |
25 | );
26 | };
27 |
28 | export default DrawerComponent;
29 |
--------------------------------------------------------------------------------
/docs/gatsby-ssr.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const config = require('./gatsby-config');
3 |
4 | exports.onRenderBody = ({ pathname, setHeadComponents }) => {
5 | setHeadComponents([
6 | ,
10 | ]);
11 | };
12 |
13 | exports.onPreRenderHTML = function onPreRenderHTML({
14 | getHeadComponents,
15 | replaceHeadComponents,
16 | }) {
17 | const headComponents = getHeadComponents();
18 | headComponents.sort((a, b) => {
19 | if (a.type === b.type || (a.type !== 'style' && b.type !== 'style')) {
20 | return 0;
21 | }
22 |
23 | if (a.type === 'style') {
24 | return 1;
25 | } else if (b.type === 'style') {
26 | return -1;
27 | }
28 |
29 | return 0;
30 | });
31 |
32 | replaceHeadComponents(headComponents);
33 | };
34 |
--------------------------------------------------------------------------------
/docs/static/images/typography.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/example/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const createExpoWebpackConfigAsync = require('@expo/webpack-config');
3 | const { resolver } = require('./metro.config');
4 |
5 | const root = path.resolve(__dirname, '..');
6 | const node_modules = path.join(__dirname, 'node_modules');
7 |
8 | module.exports = async function (env, argv) {
9 | const config = await createExpoWebpackConfigAsync(env, argv);
10 |
11 | config.module.rules.push({
12 | test: /\.(js|ts|tsx)$/,
13 | include: path.resolve(root, 'src'),
14 | use: 'babel-loader',
15 | });
16 |
17 | // We need to make sure that only one version is loaded for peerDependencies
18 | // So we alias them to the versions in example's node_modules
19 | Object.assign(config.resolve.alias, {
20 | ...resolver.extraNodeModules,
21 | 'react-native-web': path.resolve(node_modules, 'react-native-web'),
22 | });
23 |
24 | return config;
25 | };
26 |
--------------------------------------------------------------------------------
/docs/src/components/home/Colors.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default function Colors() {
4 | return (
5 |
6 |
7 |
8 |
9 |
Organize Your Colors with Collections
10 |
11 | Collections are groups of colors. You can create as many collections
12 | as you need to keep your colors organized.{' '}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/src/ui/button/button.service.ts:
--------------------------------------------------------------------------------
1 | import color from 'color';
2 |
3 | import { getThemeColor } from '../../theme/theme.service';
4 | import { ButtonProps } from './button.type';
5 | import { ThemeType } from '../../theme/type';
6 |
7 | /**
8 | * returns underlay color
9 | *
10 | * @param theme
11 | * @param props
12 | */
13 | export const getUnderlayColor = (theme: ThemeType, props: ButtonProps) => {
14 | return getThemeColor(
15 | theme.colors,
16 | props.underlayColor
17 | ? props.underlayColor
18 | : color(getThemeColor(theme.colors, props.bg)).darken(0.1).rgb().string()
19 | );
20 | };
21 |
22 | /**
23 | * return ripple color
24 | *
25 | * @param theme
26 | * @param props
27 | */
28 | export const getRippleColor = (theme: ThemeType, props: ButtonProps) => {
29 | return color(getThemeColor(theme.colors, props.rippleColor))
30 | .alpha(props.disabled ? 0 : 0.2)
31 | .rgb()
32 | .string();
33 | };
34 |
--------------------------------------------------------------------------------
/src/ui/badge/badge.type.tsx:
--------------------------------------------------------------------------------
1 | import { ViewProps as RNViewProps } from 'react-native';
2 | import {
3 | DimensionPropsType,
4 | FlexPropsType,
5 | OpacityPropsType,
6 | PositionPropsType,
7 | TextPropsType,
8 | ZIndexPropsType,
9 | BorderPropsType,
10 | SpacingPropsType,
11 | RoundedPropsType,
12 | ShadowPropsType,
13 | BackgroundPropsType,
14 | VariantPropsType,
15 | } from '../../types';
16 |
17 | export interface BadgeProps
18 | extends RNViewProps,
19 | BorderPropsType,
20 | SpacingPropsType,
21 | RoundedPropsType,
22 | ShadowPropsType,
23 | DimensionPropsType,
24 | PositionPropsType,
25 | OpacityPropsType,
26 | ZIndexPropsType,
27 | Pick,
28 | Pick,
29 | Pick,
30 | VariantPropsType {
31 | count?: string | number;
32 | }
33 |
--------------------------------------------------------------------------------
/src/ui/input/input.type.tsx:
--------------------------------------------------------------------------------
1 | import { TextInputProps as RNTextInputProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | DimensionPropsType,
5 | FlexPropsType,
6 | InputPropsType,
7 | LoadingPropsType,
8 | OpacityPropsType,
9 | PrefixSuffixPropsType,
10 | TextPropsType,
11 | ZIndexPropsType,
12 | BorderPropsType,
13 | SpacingPropsType,
14 | RoundedPropsType,
15 | ShadowPropsType,
16 | VariantPropsType,
17 | } from '../../types';
18 |
19 | export interface InputProps
20 | extends RNTextInputProps,
21 | BorderPropsType,
22 | SpacingPropsType,
23 | ShadowPropsType,
24 | RoundedPropsType,
25 | DimensionPropsType,
26 | LoadingPropsType,
27 | PrefixSuffixPropsType,
28 | ZIndexPropsType,
29 | OpacityPropsType,
30 | Pick,
31 | Pick,
32 | Omit,
33 | InputPropsType,
34 | VariantPropsType {}
35 |
--------------------------------------------------------------------------------
/src/ui/tooltip/tooltip.type.tsx:
--------------------------------------------------------------------------------
1 | import { ViewProps as RNViewProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | DimensionPropsType,
5 | TextPropsType,
6 | ZIndexPropsType,
7 | SpacingPropsType,
8 | RoundedPropsType,
9 | ShadowPropsType,
10 | OpacityPropsType,
11 | VariantPropsType,
12 | } from '../../types';
13 |
14 | export interface TooltipRef {
15 | hide: () => void;
16 | show: () => void;
17 | }
18 |
19 | export interface TooltipProps
20 | extends RNViewProps,
21 | SpacingPropsType,
22 | ShadowPropsType,
23 | RoundedPropsType,
24 | TextPropsType,
25 | DimensionPropsType,
26 | OpacityPropsType,
27 | ZIndexPropsType,
28 | Pick,
29 | VariantPropsType {
30 | animationDuration?: number;
31 | text: string | React.ReactNode;
32 | useNativeDriver?: boolean;
33 | }
34 |
35 | export interface TriangleProps extends RNViewProps {
36 | invert: boolean;
37 | }
38 |
--------------------------------------------------------------------------------
/src/theme/theme.provider.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { ThemeType } from './type';
4 | import { ThemeContext } from './theme.context';
5 | import { defaultTheme } from '../style';
6 | import deepmerge from 'deepmerge';
7 |
8 | export interface ThemeProviderProps {
9 | theme?: ThemeType;
10 | children: React.ReactNode;
11 | }
12 |
13 | export const ThemeProvider: React.FunctionComponent = (
14 | props
15 | ) => {
16 | const { theme: themeProp = {}, children } = props;
17 |
18 | const [themeState, setThemeState] = React.useState(
19 | deepmerge(defaultTheme, themeProp)
20 | );
21 |
22 | const setTheme = (newTheme: ThemeType) => {
23 | const mergedTheme = deepmerge(defaultTheme, newTheme);
24 | setThemeState(mergedTheme);
25 | };
26 |
27 | return (
28 |
29 | {children}
30 |
31 | );
32 | };
33 |
--------------------------------------------------------------------------------
/docs/src/components/common/Breadcrumbs.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Link } from 'gatsby';
3 |
4 | export default class Breadcrumbs extends Component {
5 | static defaultProps = {
6 | breadcrumbs: [],
7 | };
8 |
9 | render() {
10 | const { breadcrumbs } = this.props;
11 |
12 | return (
13 | <>
14 |
15 |
16 |
17 |
18 | {breadcrumbs.map((breadcrumb) => (
19 |
20 | /
21 |
22 | {breadcrumb.text}
23 |
24 |
25 | ))}
26 |
27 | >
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # XDE
6 | .expo/
7 |
8 | # VSCode
9 | .vscode/
10 | jsconfig.json
11 |
12 | # Xcode
13 | #
14 | build/
15 | *.pbxuser
16 | !default.pbxuser
17 | *.mode1v3
18 | !default.mode1v3
19 | *.mode2v3
20 | !default.mode2v3
21 | *.perspectivev3
22 | !default.perspectivev3
23 | xcuserdata
24 | *.xccheckout
25 | *.moved-aside
26 | DerivedData
27 | *.hmap
28 | *.ipa
29 | *.xcuserstate
30 | project.xcworkspace
31 |
32 | # Android/IJ
33 | #
34 | .idea
35 | .gradle
36 | local.properties
37 | android.iml
38 |
39 | # Cocoapods
40 | #
41 | example/ios/Pods
42 |
43 | # node.js
44 | #
45 | node_modules/
46 | npm-debug.log
47 | yarn-debug.log
48 | yarn-error.log
49 |
50 | # BUCK
51 | buck-out/
52 | \.buckd/
53 | android/app/libs
54 | android/keystores/debug.keystore
55 |
56 | # Expo
57 | .expo/*
58 |
59 | # generated by bob
60 | lib/
61 |
62 | .env.development
63 | .env.production
64 | .gitconfig
65 | example/yarn.lock
66 |
67 | .vercel
68 | TODO
69 |
--------------------------------------------------------------------------------
/docs/static/images/icon-system.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/ui/mention/mention.type.tsx:
--------------------------------------------------------------------------------
1 | import { FlatListProps, ListRenderItemInfo } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | LoadingPropsType,
5 | PositionPropsType,
6 | BorderPropsType,
7 | SpacingPropsType,
8 | RoundedPropsType,
9 | ShadowPropsType,
10 | VariantPropsType,
11 | } from '../../types';
12 |
13 | export interface MentionProps
14 | extends FlatListProps,
15 | BorderPropsType,
16 | SpacingPropsType,
17 | ShadowPropsType,
18 | RoundedPropsType,
19 | PositionPropsType,
20 | Pick,
21 | Pick,
22 | VariantPropsType {
23 | trigger?: any;
24 | h?: number;
25 | triggerLocation: 'new-word-only' | 'anywhere';
26 | onChangeText: (value: string) => void;
27 | triggerCallback: (lastKeyword: string) => void;
28 | children: React.ReactElement;
29 | onHide?: () => void;
30 | maxRow: number;
31 | renderItem: (rowData: ListRenderItemInfo) => any;
32 | }
33 |
--------------------------------------------------------------------------------
/src/ui/portal/consumer.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { IProvider } from './host.component';
4 |
5 | interface IConsumerProps {
6 | children: React.ReactNode;
7 | manager: IProvider | null;
8 | }
9 |
10 | export const Consumer = ({ children, manager }: IConsumerProps): null => {
11 | const key = React.useRef(undefined);
12 |
13 | const checkManager = (): void => {
14 | if (!manager) {
15 | throw new Error('No portal manager defined');
16 | }
17 | };
18 |
19 | const handleInit = (): void => {
20 | checkManager();
21 | key.current = manager?.mount(children);
22 | };
23 |
24 | React.useEffect(() => {
25 | checkManager();
26 | manager?.update(key.current, children);
27 | }, [children, manager]);
28 |
29 | React.useEffect(() => {
30 | handleInit();
31 |
32 | return (): void => {
33 | checkManager();
34 | manager?.unmount(key.current);
35 | };
36 | }, []);
37 |
38 | return null;
39 | };
40 |
--------------------------------------------------------------------------------
/src/ui/radio/radio.service.tsx:
--------------------------------------------------------------------------------
1 | import { ThemeType } from '../../theme';
2 | import { getThemeColor } from '../../theme/theme.service';
3 |
4 | /**
5 | * get icon name to be used based on checked state
6 | *
7 | * @param checked
8 | */
9 | export const getIconName = (checked: boolean = false) => {
10 | switch (true) {
11 | case checked:
12 | return 'radio-button-checked';
13 | default:
14 | return 'radio-button-unchecked';
15 | }
16 | };
17 |
18 | /**
19 | * get icon color based on state
20 | *
21 | * @param checked
22 | * @param disabled
23 | */
24 | export const getIconColor = (
25 | checked: any,
26 | disabled: any,
27 | activeColor: any,
28 | inactiveColor: any,
29 | theme: ThemeType
30 | ) => {
31 | switch (true) {
32 | case disabled:
33 | return getThemeColor(theme.colors, inactiveColor);
34 | case checked:
35 | return getThemeColor(theme.colors, activeColor);
36 | default:
37 | return getThemeColor(theme.colors, inactiveColor);
38 | }
39 | };
40 |
--------------------------------------------------------------------------------
/src/ui/button/button.type.ts:
--------------------------------------------------------------------------------
1 | import { PressableProps as RNButtonProps } from 'react-native';
2 | import {
3 | ButtonPropsType,
4 | DimensionPropsType,
5 | DisabledPropsType,
6 | FlexPropsType,
7 | LoadingPropsType,
8 | OpacityPropsType,
9 | PositionPropsType,
10 | PrefixSuffixPropsType,
11 | TextPropsType,
12 | ZIndexPropsType,
13 | BackgroundPropsType,
14 | BorderPropsType,
15 | SpacingPropsType,
16 | RoundedPropsType,
17 | ShadowPropsType,
18 | VariantPropsType,
19 | } from '../../types';
20 |
21 | export interface ButtonProps
22 | extends RNButtonProps,
23 | BorderPropsType,
24 | SpacingPropsType,
25 | ShadowPropsType,
26 | RoundedPropsType,
27 | DimensionPropsType,
28 | PositionPropsType,
29 | FlexPropsType,
30 | LoadingPropsType,
31 | PrefixSuffixPropsType,
32 | DisabledPropsType,
33 | TextPropsType,
34 | OpacityPropsType,
35 | ZIndexPropsType,
36 | ButtonPropsType,
37 | Pick,
38 | VariantPropsType {}
39 |
--------------------------------------------------------------------------------
/example/src/components/Icon.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ScrollView } from 'react-native';
3 | import { Div, Icon } from 'react-native-magnus';
4 |
5 | import ExamplePage from '../utils/ExamplePage';
6 | import ExampleHeader from '../utils/ExampleHeader';
7 | import ExampleSection from '../utils/ExampleSection';
8 |
9 | const IconComponent = () => {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
27 |
28 |
29 |
30 |
31 | );
32 | };
33 |
34 | export default IconComponent;
35 |
--------------------------------------------------------------------------------
/docs/content/docs/examples.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: Examples
4 | date: "2019-08-13"
5 | description: "Example"
6 | ---Here is few examples that will help you in understanding Magnus in a better way.
7 |
8 | ### Example 1
9 |
10 |
11 |
12 |
13 |
14 | [See it on Expo](https://snack.expo.io/@pawankumar2901/dribble-login-page)
15 |
16 | ### Example 2
17 |
18 |
19 |
20 |
21 |
22 | [See it on Expo](https://snack.expo.io/@pawankumar2901/login-page)
23 |
24 | ### Example 3
25 |
26 |
27 |
28 |
29 |
30 | [See it on Expo](https://snack.expo.io/@pawankumar2901/magnus---example-3)
31 |
--------------------------------------------------------------------------------
/docs/src/components/common/SearchResults.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'gatsby';
3 |
4 | const SearchResults = ({ hit }) => {
5 | const renderType = (type) => {
6 | switch (type) {
7 | case 'docs':
8 | return (
9 |
10 | docs
11 |
12 | );
13 | default:
14 | return (
15 |
16 | blog
17 |
18 | );
19 | }
20 | };
21 | return (
22 |
26 | {hit.title}
27 |
28 | {renderType(hit.type)}
29 |
30 | {hit.slug}
31 |
32 |
33 | {hit.description}
34 |
35 | );
36 | };
37 |
38 | export default SearchResults;
39 |
--------------------------------------------------------------------------------
/src/ui/avatar/avatar.type.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | ViewProps as RNViewProps,
3 | ImageSourcePropType as RNImageSourcePropType,
4 | } from 'react-native';
5 |
6 | import { AvatarGroup } from './avatar.group.component';
7 | import {
8 | BorderPropsType,
9 | SpacingPropsType,
10 | RoundedPropsType,
11 | ShadowPropsType,
12 | BackgroundPropsType,
13 | FlexPropsType,
14 | OpacityPropsType,
15 | PositionPropsType,
16 | TextPropsType,
17 | ZIndexPropsType,
18 | VariantPropsType,
19 | } from '../../types';
20 |
21 | export type CompoundedAvatar = React.FunctionComponent
& {
22 | Group: typeof AvatarGroup;
23 | };
24 |
25 | export interface AvatarProps
26 | extends RNViewProps,
27 | BorderPropsType,
28 | SpacingPropsType,
29 | RoundedPropsType,
30 | ShadowPropsType,
31 | PositionPropsType,
32 | ZIndexPropsType,
33 | OpacityPropsType,
34 | Pick,
35 | Pick,
36 | Pick,
37 | VariantPropsType {
38 | size?: number;
39 | source?: RNImageSourcePropType;
40 | }
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 jsartisan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/example/src/components/Snackbar.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ScrollView } from 'react-native';
3 | import { Button } from 'react-native-magnus';
4 |
5 | import ExamplePage from '../utils/ExamplePage';
6 | import ExampleHeader from '../utils/ExampleHeader';
7 | import ExampleSection from '../utils/ExampleSection';
8 |
9 | const SnackbarComponent = () => {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 | {
20 | global.toast?.show('Hello World', {
21 | duration: 5000,
22 | suffix: (
23 |
24 | Yay!
25 |
26 | ),
27 | });
28 | }}
29 | >
30 | Open Snackbar
31 |
32 |
33 |
34 |
35 | );
36 | };
37 |
38 | export default SnackbarComponent;
39 |
--------------------------------------------------------------------------------
/example/src/components/Toggle.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ScrollView } from 'react-native';
3 | import { Toggle } from 'react-native-magnus';
4 |
5 | import ExamplePage from '../utils/ExamplePage';
6 | import ExampleHeader from '../utils/ExampleHeader';
7 | import ExampleSection from '../utils/ExampleSection';
8 |
9 | const ToggleComponent = () => {
10 | const [on, toggle] = React.useState(false);
11 |
12 | return (
13 |
14 |
15 |
16 |
17 |
18 | toggle(!on)} />
19 |
20 |
21 |
22 | toggle(!on)}
25 | bg="white"
26 | circleBg="blue700"
27 | activeBg="blue700"
28 | activeCircleBg="white"
29 | h={30}
30 | w={60}
31 | />
32 |
33 |
34 |
35 | );
36 | };
37 |
38 | export default ToggleComponent;
39 |
--------------------------------------------------------------------------------
/src/ui/dropdown/dropdown.type.tsx:
--------------------------------------------------------------------------------
1 | import { ModalProps } from '../modal/modal.type';
2 |
3 | import { DropdownOption } from './dropdown.option.component';
4 | import {
5 | BorderPropsType,
6 | SpacingPropsType,
7 | RoundedPropsType,
8 | BackgroundPropsType,
9 | DimensionPropsType,
10 | FlexPropsType,
11 | OverflowPropsType,
12 | VariantPropsType,
13 | } from '../../types';
14 |
15 | export interface CompoundedDropdown
16 | extends React.ForwardRefExoticComponent<
17 | DropdownProps & React.RefAttributes
18 | > {
19 | Option: typeof DropdownOption;
20 | }
21 |
22 | export interface DropdownRef {
23 | open: () => void;
24 | close: () => void;
25 | }
26 |
27 | export interface DropdownProps
28 | extends ModalProps,
29 | BorderPropsType,
30 | SpacingPropsType,
31 | RoundedPropsType,
32 | DimensionPropsType,
33 | OverflowPropsType,
34 | Pick,
35 | Pick<
36 | FlexPropsType,
37 | 'justifyContent' | 'alignItems' | 'flexDir' | 'flexWrap'
38 | >,
39 | VariantPropsType {
40 | title?: string | React.ReactNode;
41 | showSwipeIndicator?: boolean;
42 | }
43 |
--------------------------------------------------------------------------------
/src/ui/collapse/collapse.type.tsx:
--------------------------------------------------------------------------------
1 | import { DivProps } from '../div/div.type';
2 | import { ButtonProps } from '../button/button.type';
3 | import { CollapseBody } from './collapse.body.component';
4 | import { CollapseHeader } from './collapse.header.component';
5 | import { CollapseGroup } from './group.component';
6 |
7 | export type CompoundedCollapse = React.FunctionComponent
& {
8 | Header: typeof CollapseHeader;
9 | Body: typeof CollapseBody;
10 | Group: typeof CollapseGroup;
11 | };
12 |
13 | export interface CollapseProps extends DivProps {
14 | id?: string | number;
15 | active?: boolean;
16 | defaultActive?: boolean;
17 | onChange?: (value: any) => void;
18 | }
19 |
20 | export interface CollapseBodyProps extends DivProps {
21 | expanded?: boolean;
22 | }
23 |
24 | export interface CollapseGroupProps extends DivProps {
25 | onChange?: (value: any) => void;
26 | defaultActive?: string | number;
27 | children: React.ReactElement[] | React.ReactElement;
28 | }
29 |
30 | export interface CollapseHeaderProps extends ButtonProps {
31 | active?: boolean;
32 | activeSuffix?: React.ReactNode;
33 | activePrefix?: React.ReactNode;
34 | }
35 |
--------------------------------------------------------------------------------
/docs/src/pages/404.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Hero from '../components/home/Hero';
4 | import Components from '../components/home/Components';
5 | import Customizations from '../components/home/Customizations';
6 | import Composable from '../components/home/Composable';
7 | import Example from '../components/home/Example';
8 |
9 | import Seo from '../components/common/Seo';
10 | import Layout from '../components/layout/Layout';
11 | import Header from '../components/layout/Header';
12 |
13 | const seo = {
14 | title: 'A Utility-First React Native UI Framework',
15 | description:
16 | 'Magnus is the ultimate UI framework that helps you in building consistent user interfaces effortlessly in react native.',
17 | url: 'https://magnus-ui.com',
18 | };
19 |
20 | const IndexPage = () => (
21 |
22 |
23 |
24 |
25 |
404
26 |
The page you are looking does not exist.
27 |
28 |
29 | );
30 |
31 | export default IndexPage;
32 |
--------------------------------------------------------------------------------
/src/utilities/useDefaultProps.ts:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ThemeType, useTheme } from '../theme';
3 | import { DefaultProps, VariantPropsType } from '../types';
4 |
5 | export const useDefaultProps = (
6 | componentName: keyof NonNullable | null,
7 | props: Props & VariantPropsType,
8 | defaultProps: DefaultProps
9 | ) => {
10 | const { theme } = useTheme();
11 |
12 | const finalProps = React.useMemo(() => {
13 | if (!componentName) {
14 | return {
15 | ...defaultProps,
16 | ...props,
17 | };
18 | }
19 |
20 | let propsFromTheme = {
21 | ...(theme.components?.[componentName] ?? {}),
22 | ...(props.variant &&
23 | (theme.components?.[componentName]?.variants?.[props.variant] ?? {})),
24 | };
25 |
26 | delete propsFromTheme.variants;
27 |
28 | const mergedProps = {
29 | ...defaultProps,
30 | ...propsFromTheme,
31 | ...props,
32 | };
33 |
34 | return mergedProps;
35 | }, [componentName, defaultProps, props, theme.components]);
36 |
37 | return finalProps as Props & Required;
38 | };
39 |
--------------------------------------------------------------------------------
/src/ui/animated/animated.service.tsx:
--------------------------------------------------------------------------------
1 | import * as Animatable from 'react-native-animatable';
2 |
3 | export const registerAnimations = () => {
4 | Animatable.initializeRegistryWithDefinitions({
5 | 'magnus-none': {
6 | 0: {},
7 | 1: {},
8 | },
9 | 'magnus-fade': {
10 | 0: {
11 | opacity: 0,
12 | },
13 | 1: {
14 | opacity: 1,
15 | },
16 | },
17 | 'magnus-fromRight': {
18 | 0: {
19 | opacity: 0,
20 | left: 30,
21 | },
22 | 1: {
23 | opacity: 1,
24 | left: 0,
25 | },
26 | },
27 | 'magnus-fromLeft': {
28 | 0: {
29 | opacity: 0,
30 | right: 30,
31 | },
32 | 1: {
33 | opacity: 1,
34 | right: 0,
35 | },
36 | },
37 | 'magnus-fromTop': {
38 | 0: {
39 | opacity: 0,
40 | bottom: 30,
41 | },
42 | 1: {
43 | opacity: 1,
44 | bottom: 0,
45 | },
46 | },
47 | 'magnus-fromBottom': {
48 | 0: {
49 | opacity: 0,
50 | top: 30,
51 | },
52 | 1: {
53 | opacity: 1,
54 | top: 0,
55 | },
56 | },
57 | });
58 | };
59 |
--------------------------------------------------------------------------------
/src/ui/select/select.option.type.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 | import { PressableProps as RNButtonProps } from 'react-native';
3 | import {
4 | BackgroundPropsType,
5 | ButtonPropsType,
6 | DimensionPropsType,
7 | DisabledPropsType,
8 | FlexPropsType,
9 | LoadingPropsType,
10 | PositionPropsType,
11 | PrefixSuffixPropsType,
12 | TextPropsType,
13 | BorderPropsType,
14 | SpacingPropsType,
15 | RoundedPropsType,
16 | ShadowPropsType,
17 | VariantPropsType,
18 | } from '../../types';
19 |
20 | export interface SelectOptionProps
21 | extends RNButtonProps,
22 | BorderPropsType,
23 | SpacingPropsType,
24 | ShadowPropsType,
25 | RoundedPropsType,
26 | LoadingPropsType,
27 | PositionPropsType,
28 | DisabledPropsType,
29 | FlexPropsType,
30 | ButtonPropsType,
31 | Pick,
32 | Pick,
33 | Pick,
34 | DimensionPropsType,
35 | Pick,
36 | VariantPropsType {
37 | center?: boolean;
38 | value: any;
39 | onSelect?: (value: any) => void;
40 | selectedValue?: any;
41 | children: ReactNode;
42 | }
43 |
--------------------------------------------------------------------------------
/docs/content/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Getting started
3 | date: '2019-08-13'
4 | description: ''
5 | ---
6 |
7 | ### Installation
8 |
9 | Open a Terminal in your project's folder and run,
10 |
11 | ```bash
12 | yarn add react-native-magnus
13 | ```
14 |
15 | After installing the `react-native-magnus`, make sure you install peer dependencies.
16 |
17 | ```bash
18 | yarn add react-native-animatable react-native-modal react-native-vector-icons
19 | ```
20 |
21 | After installing these dependencies, follow these instructions to add icons : https://github.com/oblador/react-native-vector-icons#installation
22 |
23 | Install pods
24 |
25 | ```bash
26 | cd ios && pod install
27 | ```
28 |
29 | ### Usage
30 |
31 | Wrap your root component in ThemeProvider from react-native-magnus.
32 |
33 | ```jsx
34 | import * as React from 'react';
35 | import { AppRegistry } from 'react-native';
36 | import { ThemeProvider } from 'react-native-magnus';
37 |
38 | import App from './src/App';
39 |
40 | export default function Main() {
41 | return (
42 |
43 |
44 |
45 | );
46 | }
47 |
48 | AppRegistry.registerComponent('main', () => Main);
49 | ```
50 |
51 |
52 |
--------------------------------------------------------------------------------
/src/ui/toggle/toggle.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createSpacingStyles,
6 | createBorderRadiusStyles,
7 | } from '../../theme/theme.service';
8 | import { ToggleProps } from './toggle.type';
9 |
10 | /**
11 | * computed style
12 | *
13 | * @param theme
14 | * @param props
15 | */
16 | export const getStyle = (theme: ThemeType, props: ToggleProps) => {
17 | const computedStyle: any = {};
18 |
19 | computedStyle.container = {
20 | flexDirection: 'row',
21 | height: props.h,
22 | width: props.w,
23 | alignItems: 'center',
24 | ...createSpacingStyles(props, theme.spacing),
25 | ...createBorderRadiusStyles(props, theme.borderRadius),
26 | };
27 |
28 | computedStyle.circle = {
29 | // @ts-ignore
30 | height: props.h - 6,
31 | // @ts-ignore
32 | width: props.h - 6,
33 | // @ts-ignore
34 | borderRadius: props.h - 6,
35 | };
36 |
37 | // merging style props to computed style
38 | if (props.style) {
39 | computedStyle.container = {
40 | ...computedStyle.container,
41 | // @ts-ignore
42 | ...props.style,
43 | };
44 | }
45 |
46 | return StyleSheet.create(computedStyle);
47 | };
48 |
--------------------------------------------------------------------------------
/src/ui/icon/icon.type.tsx:
--------------------------------------------------------------------------------
1 | import { ViewProps as RNViewProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | DimensionPropsType,
5 | FlexPropsType,
6 | OpacityPropsType,
7 | PositionPropsType,
8 | TextPropsType,
9 | ZIndexPropsType,
10 | BorderPropsType,
11 | SpacingPropsType,
12 | RoundedPropsType,
13 | ShadowPropsType,
14 | VariantPropsType,
15 | } from '../../types';
16 |
17 | export type iconFontFamilyType =
18 | | 'AntDesign'
19 | | 'Entypo'
20 | | 'EvilIcons'
21 | | 'Feather'
22 | | 'FontAwesome'
23 | | 'FontAwesome5'
24 | | 'Foundation'
25 | | 'Ionicons'
26 | | 'MaterialIcons'
27 | | 'MaterialCommunityIcons'
28 | | 'Octicons'
29 | | 'Zocial'
30 | | 'Fontisto'
31 | | 'SimpleLineIcons';
32 |
33 | export interface IconProps
34 | extends RNViewProps,
35 | BorderPropsType,
36 | SpacingPropsType,
37 | RoundedPropsType,
38 | ShadowPropsType,
39 | DimensionPropsType,
40 | PositionPropsType,
41 | ZIndexPropsType,
42 | OpacityPropsType,
43 | Pick,
44 | Pick,
45 | Pick,
46 | VariantPropsType {
47 | name: string;
48 | fontFamily?: iconFontFamilyType;
49 | }
50 |
--------------------------------------------------------------------------------
/src/ui/modal/modal.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 | import {
4 | createSpacingStyles,
5 | createBorderWidthStyles,
6 | createBorderColorStyles,
7 | createBorderRadiusStyles,
8 | } from '../../theme/theme.service';
9 | import { ModalProps } from './modal.type';
10 |
11 | /**
12 | * computed style
13 | *
14 | * @param theme
15 | * @param props
16 | */
17 | export const getStyle = (theme: ThemeType, props: ModalProps) => {
18 | const computedStyle: any = {};
19 |
20 | computedStyle.modal = {
21 | margin: 0,
22 | justifyContent: props.justifyContent,
23 | };
24 |
25 | computedStyle.container = {
26 | ...createBorderWidthStyles(props),
27 | ...createSpacingStyles(props, theme.spacing),
28 | ...createBorderColorStyles(props, theme.colors),
29 | ...createBorderRadiusStyles(props, theme.borderRadius),
30 | };
31 |
32 | computedStyle.safeView = {
33 | flex: 1,
34 | };
35 |
36 | // merging style props to computed style
37 | if (props.style) {
38 | computedStyle.modal = {
39 | ...computedStyle.modal,
40 | // @ts-ignore
41 | ...props.style,
42 | };
43 | }
44 |
45 | return StyleSheet.create(computedStyle);
46 | };
47 |
--------------------------------------------------------------------------------
/docs/src/pages/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Hero from '../components/home/Hero';
4 | import Components from '../components/home/Components';
5 | import Customizations from '../components/home/Customizations';
6 | import Composable from '../components/home/Composable';
7 | import Example from '../components/home/Example';
8 | import Preview from '../components/home/Preview';
9 | import Features from '../components/home/Features';
10 |
11 | import Seo from '../components/common/Seo';
12 | import Layout from '../components/layout/Layout';
13 | import Header from '../components/layout/Header';
14 |
15 | const seo = {
16 | title: 'A Utility-First React Native UI Framework',
17 | description:
18 | 'Magnus is the ultimate UI framework that helps you in building consistent user interfaces effortlessly in react native.',
19 | url: 'https://magnus-ui.com',
20 | };
21 |
22 | const IndexPage = () => (
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | );
38 |
39 | export default IndexPage;
40 |
--------------------------------------------------------------------------------
/src/ui/statusbar/statusbar.component.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StatusBar as RNStatusBar,
4 | StatusBarProps as RNStatusBarProps,
5 | } from 'react-native';
6 | import { useTheme } from '../../theme';
7 |
8 | import { getThemeColor } from '../../theme/theme.service';
9 | import { VariantPropsType } from '../../types';
10 | import { useDefaultProps } from '../../utilities/useDefaultProps';
11 |
12 | interface StatusBarComponent extends React.FC {
13 | currentHeight?: number;
14 | }
15 |
16 | const StatusBar: StatusBarComponent = (
17 | incomingProps
18 | ) => {
19 | const props = useDefaultProps('Statusbar', incomingProps, {
20 | animated: true,
21 | });
22 |
23 | const { backgroundColor } = props;
24 | const { theme } = useTheme();
25 |
26 | return (
27 |
35 | );
36 | };
37 |
38 | StatusBar.currentHeight = RNStatusBar.currentHeight;
39 |
40 | // StatusBar.defaultProps = {
41 | // animated: true,
42 | // };
43 |
44 | export { StatusBar };
45 |
--------------------------------------------------------------------------------
/.github/workflows/expo.yml:
--------------------------------------------------------------------------------
1 | name: Expo Publish
2 | on:
3 | push:
4 | branches:
5 | - master
6 | jobs:
7 | publish:
8 | name: Install and publish
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v1
13 |
14 | - name: Setup Node.js
15 | uses: actions/setup-node@v1
16 | with:
17 | node-version: 12.x
18 |
19 | - name: Setup Expo
20 | uses: expo/expo-github-action@v5
21 | with:
22 | expo-version: 3.x
23 | expo-username: ${{ secrets.EXPO_CLI_USERNAME }}
24 | expo-password: ${{ secrets.EXPO_CLI_PASSWORD }}
25 | expo-cache: true
26 |
27 | - name: Get yarn cache
28 | id: yarn-cache
29 | run: echo "::set-output name=dir::$(yarn cache dir)"
30 |
31 | - uses: actions/cache@v1
32 | with:
33 | path: ${{ steps.yarn-cache.outputs.dir }}
34 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
35 | restore-keys: |
36 | ${{ runner.os }}-yarn-
37 |
38 | - name: Install dependencies
39 | run: yarn bootstrap
40 |
41 | - name: Publish Expo app
42 | working-directory: ./example
43 | run: expo publish
44 |
--------------------------------------------------------------------------------
/docs/content/docs/customization.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Customization
3 | date: "2019-08-13"
4 | description: ""
5 | ---
6 |
7 | You can provide a custom theme to customize the colors, font sizes, border radius etc. with the Provider component. Check the default theme to see which customization options are supported.
8 |
9 | ```jsx
10 | import * as React from "react";
11 | import { AppRegistry } from "react-native";
12 | import { ThemeProvider } from "react-native-magnus";
13 | import App from "./src/App";
14 |
15 | // this is our custom theme
16 | const theme = {
17 | colors: {
18 | violet100: "#e1e1e1",
19 | },
20 | fontSize: {
21 | bigText100: 32,
22 | },
23 | spacing: {
24 | xs: 2,
25 | '5xl': 64
26 | },
27 | // components defaults can also be customized
28 | {
29 | components: {
30 | Text: {
31 | color: 'gray100'
32 | }
33 | }
34 | }
35 | };
36 |
37 | export default function Main() {
38 | return (
39 |
40 |
41 |
42 | );
43 | }
44 | ```
45 |
46 | Checkout the demo on Snack - https://snack.expo.io/@pawankumar2901/magnus---theme-customizations
47 |
--------------------------------------------------------------------------------
/src/ui/avatar/avatar.group.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { Div } from '../div/div.component';
4 | import { AvatarGroupProps } from './avatar.group.type';
5 | import { getThemeProperty, useTheme } from '../../theme';
6 | import { useDefaultProps } from '../../utilities/useDefaultProps';
7 |
8 | const AvatarGroup: React.FunctionComponent = (
9 | incomingProps
10 | ) => {
11 | const props = useDefaultProps('AvatarGroup', incomingProps, {
12 | row: true,
13 | ml: 'none',
14 | offset: 'lg',
15 | });
16 |
17 | const { children, ml, offset, ...rest } = props;
18 | const { theme } = useTheme();
19 | const calculatedOffset = getThemeProperty(theme.spacing, offset);
20 | const calculatedMarginLeft = getThemeProperty(theme.spacing, ml);
21 |
22 | return (
23 |
24 | {React.Children.map(children, (child: React.ReactElement) => {
25 | return React.cloneElement(child, {
26 | ml: -1 * calculatedOffset,
27 | });
28 | })}
29 |
30 | );
31 | };
32 |
33 | // AvatarGroup.defaultProps = {
34 | // row: true,
35 | // ml: 'none',
36 | // offset: 'lg',
37 | // };
38 |
39 | export { AvatarGroup };
40 |
--------------------------------------------------------------------------------
/example/metro.config.js:
--------------------------------------------------------------------------------
1 | // /* eslint-disable import/no-commonjs */
2 |
3 | const path = require('path');
4 | const blacklist = require('metro-config/src/defaults/exclusionList');
5 | const escape = require('escape-string-regexp');
6 | const pak = require('../package.json');
7 |
8 | const root = path.resolve(__dirname, '..');
9 |
10 | const modules = ['@expo/vector-icons', ...Object.keys(pak.peerDependencies)];
11 |
12 | module.exports = {
13 | projectRoot: __dirname,
14 | watchFolders: [root],
15 |
16 | // We need to make sure that only one version is loaded for peerDependencies
17 | // So we blacklist them at the root, and alias them to the versions in example's node_modules
18 | resolver: {
19 | blacklistRE: blacklist(
20 | modules.map(
21 | (m) =>
22 | new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`)
23 | )
24 | ),
25 |
26 | extraNodeModules: modules.reduce((acc, name) => {
27 | acc[name] = path.join(__dirname, 'node_modules', name);
28 | return acc;
29 | }, {}),
30 | },
31 |
32 | transformer: {
33 | getTransformOptions: async () => ({
34 | transform: {
35 | experimentalImportSupport: false,
36 | inlineRequires: true,
37 | },
38 | }),
39 | },
40 | };
41 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # dotenv environment variables file
55 | .env
56 |
57 | # gatsby files
58 | .cache/
59 | public
60 |
61 | # Mac files
62 | .DS_Store
63 |
64 | # Yarn
65 | yarn-error.log
66 | .pnp/
67 | .pnp.js
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | .now
--------------------------------------------------------------------------------
/src/ui/fab/fab.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Platform } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import { getThemeColor } from '../../theme/theme.service';
5 | import { FabProps } from './fab.type';
6 |
7 | /**
8 | * computed style
9 | *
10 | * @param theme
11 | * @param props
12 | */
13 | export const getStyle = (theme: ThemeType, props: FabProps) => {
14 | const computedStyle: any = {};
15 |
16 | computedStyle.button = {
17 | bottom: 0,
18 | right: 0,
19 | overflow: Platform.OS === 'ios' ? 'visible' : 'hidden',
20 | zIndex: 2,
21 | alignItems: 'center',
22 | justifyContent: 'center',
23 | elevation: 5,
24 | position: props.position,
25 | };
26 |
27 | computedStyle.actions = {
28 | position: 'absolute',
29 | zIndex: 10,
30 | };
31 |
32 | if (props.shadow) {
33 | computedStyle.button = {
34 | ...computedStyle.button,
35 | ...(theme.shadow && theme.shadow[props.shadow]),
36 | shadowColor: getThemeColor(theme.colors, props.shadowColor),
37 | };
38 | }
39 |
40 | computedStyle.overlay = {
41 | position: 'absolute',
42 | bottom: 0,
43 | left: 0,
44 | right: 0,
45 | top: 0,
46 | elevation: 0,
47 | zIndex: 0,
48 | };
49 |
50 | return StyleSheet.create(computedStyle);
51 | };
52 |
--------------------------------------------------------------------------------
/docs/content/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Advanced Design System for React Native
3 | date: "2019-08-13"
4 | ---
5 |
6 |
7 |
8 | > “The effort required to build a design system is tiny compared to the effort required to maintain it.”
9 |
10 | – Kyle Peatt
11 |
12 |
13 |
14 | Magnus UI is an design system for react-native based on the atomic design principle. It helps developers and designers to build consistent components quickly in terms of UI and UX.
15 |
16 |
17 |
18 | ### Before you start
19 |
20 | Before you dive into the framework, make sure you know about **What a design system is**, **Why do we even need it** and **What is a atom design principle**. Here is a good article on these questions -
21 |
22 |
23 |
24 |
32 |
--------------------------------------------------------------------------------
/docs/static/images/atomic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/example/src/components/Fab.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button, Div, Fab, Icon, Text } from 'react-native-magnus';
3 |
4 | import ExamplePage from '../utils/ExamplePage';
5 | import ExampleHeader from '../utils/ExampleHeader';
6 |
7 | const FabComponent = () => {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 | Cheer
16 |
17 |
26 |
27 |
28 |
29 |
30 | Boost
31 |
32 |
41 |
42 |
43 |
44 | );
45 | };
46 |
47 | export default FabComponent;
48 |
--------------------------------------------------------------------------------
/example/src/components/Skeleton.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ScrollView } from 'react-native';
3 | import { Div, Skeleton } from 'react-native-magnus';
4 |
5 | import ExamplePage from '../utils/ExamplePage';
6 | import ExampleHeader from '../utils/ExampleHeader';
7 | import ExampleSection from '../utils/ExampleSection';
8 |
9 | const SkeletonComponent = () => {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | );
37 | };
38 |
39 | export default SkeletonComponent;
40 |
--------------------------------------------------------------------------------
/example/src/components/Badge.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ScrollView } from 'react-native';
3 | import { Avatar, Badge, Div, Image } from 'react-native-magnus';
4 |
5 | import ExamplePage from '../utils/ExamplePage';
6 | import ExampleHeader from '../utils/ExampleHeader';
7 | import ExampleSection from '../utils/ExampleSection';
8 |
9 | const BadgeComponent = () => {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | A
20 |
21 |
22 |
1
23 |
24 | 99+
25 |
26 |
27 |
36 |
37 |
38 |
39 |
40 |
41 | );
42 | };
43 |
44 | export default BadgeComponent;
45 |
--------------------------------------------------------------------------------
/docs/content/docs/typography.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Typography
3 | date: "2019-08-13"
4 | description: ""
5 | ---
6 |
7 | The default theme of magnus consists of following font sizes:
8 |
9 |
10 |
11 | | Size | Value |
12 | | ---- | ----- |
13 | | xs | 11 |
14 | | sm | 12 |
15 | | md | 13 |
16 | | lg | 15 |
17 | | xl | 17 |
18 | | 2xl | 19 |
19 | | 3xl | 21 |
20 | | 4xl | 24 |
21 | | 5xl | 27 |
22 | | 6xl | 32 |
23 |
24 |
25 |
26 | ### Usage
27 |
28 | ```jsx
29 | import { Text } from "react-native-magnus";
30 |
31 | Text 6xl ;
32 | ```
33 |
34 |
35 |
36 | ### Adding custom font sizes
37 |
38 | You can add custom or customize the existing font sizes with the ThemeProvider component.
39 |
40 | ```jsx
41 | import React from "react";
42 | import { AppRegistry } from "react-native";
43 | import { ThemeProvider, Text } from "react-native-magnus";
44 | import App from "./src/App";
45 |
46 | // here we are adding our custom font sizes and
47 | // customizing xs
48 | const theme = {
49 | fontSize: {
50 | xs: 10,
51 | "7xl": 64,
52 | },
53 | };
54 |
55 | export default function Main() {
56 | return (
57 |
58 | Text 7xl
59 |
60 | );
61 | }
62 | ```
63 |
--------------------------------------------------------------------------------
/src/ui/fab/fab.type.tsx:
--------------------------------------------------------------------------------
1 | import { PressableProps as RNButtonProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | ButtonPropsType,
5 | DimensionPropsType,
6 | DisabledPropsType,
7 | FlexPropsType,
8 | LoadingPropsType,
9 | OverlayPropsType,
10 | PositionPropsType,
11 | TextPropsType,
12 | BorderPropsType,
13 | SpacingPropsType,
14 | RoundedPropsType,
15 | ShadowPropsType,
16 | VariantPropsType,
17 | } from '../../types';
18 |
19 | export interface FabProps
20 | extends Omit,
21 | BorderPropsType,
22 | SpacingPropsType,
23 | RoundedPropsType,
24 | ShadowPropsType,
25 | DimensionPropsType,
26 | FlexPropsType,
27 | LoadingPropsType,
28 | PositionPropsType,
29 | DisabledPropsType,
30 | OverlayPropsType,
31 | Pick,
32 | Pick,
33 | Pick,
34 | VariantPropsType {
35 | h?: number;
36 | center?: boolean;
37 | icon?: string | React.ReactNode;
38 | activeIcon?: string | React.ReactNode;
39 | showBackground?: boolean;
40 | openOnMount?: boolean;
41 | onClose?: () => void;
42 | onPressBackdrop?: () => void;
43 | animated?: boolean;
44 | onOpen?: () => void;
45 | useNativeDriver?: boolean;
46 | children: React.ReactElement | React.ReactElement[];
47 | }
48 |
--------------------------------------------------------------------------------
/docs/static/images/spacing.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/ui/collapse/group.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { useState } from 'react';
3 | import { useDefaultProps } from '../../utilities/useDefaultProps';
4 |
5 | import { Div } from '../div/div.component';
6 | import { CollapseGroupProps } from './collapse.type';
7 |
8 | const CollapseGroup: React.FunctionComponent = (
9 | incomingProps
10 | ) => {
11 | const props = useDefaultProps('CollapseGroup', incomingProps, {});
12 |
13 | const [activeId, setActiveId] = useState(props.defaultActive ?? null);
14 | const { children, onChange: onChangeProp, ...rest } = props;
15 |
16 | /**
17 | * checks if checked value is already in the state or not,
18 | * if it, remove it else add it
19 | *
20 | * @param value
21 | */
22 | const onChange = (optionId: any) => {
23 | setActiveId(optionId === activeId ? null : optionId);
24 |
25 | if (onChangeProp) {
26 | onChangeProp(optionId);
27 | }
28 | };
29 |
30 | /**
31 | * clones the children and add checked, onChange prop
32 | */
33 | const renderChildren = () => {
34 | return React.Children.map(children, (child: React.ReactElement) => {
35 | return React.cloneElement(child, {
36 | onChange,
37 | active: activeId === child.props.id,
38 | });
39 | });
40 | };
41 |
42 | return {renderChildren()}
;
43 | };
44 |
45 | export { CollapseGroup };
46 |
--------------------------------------------------------------------------------
/src/ui/radio/group.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { useState } from 'react';
3 |
4 | import { RadioGroupProps } from './radio.type';
5 | import { Div } from '../div/div.component';
6 | import { useDefaultProps } from '../../utilities/useDefaultProps';
7 |
8 | const RadioGroup: React.FunctionComponent = (
9 | incomingProps
10 | ) => {
11 | const props = useDefaultProps('RadioGroup', incomingProps, {});
12 |
13 | const [value, setValue] = useState(props.value ?? props.defaultValue ?? null);
14 | const {
15 | children,
16 | onChange: onChangeProp,
17 | value: propsValue,
18 | ...rest
19 | } = props;
20 |
21 | /**
22 | * checks if checked value is already in the state or not,
23 | * if it, remove it else add it
24 | *
25 | * @param value
26 | */
27 | const onChange = (optionValue: any) => {
28 | if (!('value' in props)) {
29 | setValue(optionValue);
30 | }
31 |
32 | if (onChangeProp) {
33 | onChangeProp(optionValue);
34 | }
35 | };
36 |
37 | /**
38 | * clones the children and add checked, onChange prop
39 | */
40 | const renderChildren = () => {
41 | return React.Children.map(children, (child: React.ReactElement) => {
42 | return React.cloneElement(child, {
43 | onChange,
44 | checked: value === child.props.value,
45 | });
46 | });
47 | };
48 |
49 | return {renderChildren()}
;
50 | };
51 |
52 | export { RadioGroup };
53 |
--------------------------------------------------------------------------------
/docs/src/components/home/Customizations.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'gatsby';
3 |
4 | export default function Features() {
5 | return (
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
22 |
23 | Theme Customizations
24 |
25 |
26 | You can easily add or customize the theme for your entire app.
27 |
28 |
32 | Check out about theme customizations →
33 |
34 |
35 |
36 |
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/src/ui/snackbar/snackbar.type.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 | import { StyleProp, ViewStyle } from 'react-native';
3 | import {
4 | BackgroundPropsType,
5 | DimensionPropsType,
6 | FlexPropsType,
7 | OpacityPropsType,
8 | PrefixSuffixPropsType,
9 | TextPropsType,
10 | BorderPropsType,
11 | SpacingPropsType,
12 | RoundedPropsType,
13 | ShadowPropsType,
14 | VariantPropsType,
15 | } from '../../types';
16 |
17 | export interface SnackbarRef {
18 | show: (message: string | JSX.Element, config?: SnackbarProps) => void;
19 | hide: (id: string) => void;
20 | update: (
21 | id: string,
22 | message: string | JSX.Element,
23 | config?: SnackbarProps
24 | ) => void;
25 | }
26 |
27 | export interface SnackbarProps
28 | extends BorderPropsType,
29 | SpacingPropsType,
30 | ShadowPropsType,
31 | RoundedPropsType,
32 | PrefixSuffixPropsType,
33 | DimensionPropsType,
34 | OpacityPropsType,
35 | FlexPropsType,
36 | Pick,
37 | Pick,
38 | VariantPropsType {
39 | id?: string;
40 | duration?: number;
41 | onClose?: () => void;
42 | style?: StyleProp;
43 | useNativeDriver?: boolean;
44 | children?: ReactNode;
45 | }
46 |
47 | export interface SnackbarContainerProps {
48 | placement: 'top' | 'bottom';
49 | offset?: number;
50 | }
51 |
52 | export interface SnackbarState {
53 | toasts: Array;
54 | }
55 |
--------------------------------------------------------------------------------
/src/ui/overlay/overlay.style.tsx:
--------------------------------------------------------------------------------
1 | import color from 'color';
2 | import { StyleSheet } from 'react-native';
3 | import { ThemeType } from '../../theme';
4 |
5 | import {
6 | createFlexStyles,
7 | createSpacingStyles,
8 | createBorderRadiusStyles,
9 | getThemeColor,
10 | } from '../../theme/theme.service';
11 | import { OverlayProps } from './overlay.type';
12 |
13 | /**
14 | * computed style
15 | *
16 | * @param theme
17 | * @param props
18 | */
19 | export const getStyle = (theme: ThemeType, props: OverlayProps) => {
20 | const computedStyle: any = {};
21 |
22 | computedStyle.modal = {
23 | backgroundColor: color(getThemeColor(theme.colors, props.overlayColor))
24 | .alpha(props.overlayOpacity ?? 50)
25 | .rgb()
26 | .string(),
27 | flex: 1,
28 | alignItems: 'center',
29 | justifyContent: 'center',
30 | };
31 |
32 | computedStyle.container = {
33 | backgroundColor: getThemeColor(theme.colors, props.bg),
34 | ...createFlexStyles(props),
35 | ...createSpacingStyles(props, theme.spacing),
36 | ...createBorderRadiusStyles(props, theme.borderRadius),
37 | width: props.w,
38 | height: props.h,
39 | alignItems: props.alignItems,
40 | justifyContent: props.justifyContent,
41 | };
42 |
43 | // merging style props to computed style
44 | if (props.style) {
45 | computedStyle.container = {
46 | ...computedStyle.container,
47 | // @ts-ignore
48 | ...props.style,
49 | };
50 | }
51 |
52 | return StyleSheet.create(computedStyle);
53 | };
54 |
--------------------------------------------------------------------------------
/src/ui/portal/manager.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { View, StyleSheet } from 'react-native';
3 |
4 | export interface IManagerHandles {
5 | mount(key: string, children: React.ReactNode): void;
6 | update(key?: string, children?: React.ReactNode): void;
7 | unmount(key?: string): void;
8 | }
9 |
10 | export const Manager = React.forwardRef((_, ref): any => {
11 | const [portals, setPortals] = React.useState<
12 | { key: string; children: React.ReactNode }[]
13 | >([]);
14 |
15 | React.useImperativeHandle(
16 | ref,
17 | (): IManagerHandles => ({
18 | mount(key: string, children: React.ReactNode): void {
19 | setPortals((prev) => [...prev, { key, children }]);
20 | },
21 |
22 | update(key: string, children: React.ReactNode): void {
23 | setPortals((prev) =>
24 | prev.map((item) => {
25 | if (item.key === key) {
26 | return { ...item, children };
27 | }
28 |
29 | return item;
30 | })
31 | );
32 | },
33 |
34 | unmount(key: string): void {
35 | setPortals((prev) => prev.filter((item) => item.key !== key));
36 | },
37 | })
38 | );
39 |
40 | return portals.map(({ key, children }, index: number) => (
41 |
47 | {children}
48 |
49 | ));
50 | });
51 |
--------------------------------------------------------------------------------
/src/ui/dropdown/dropdown.option.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { GestureResponderEvent as RNGestureResponderEvent } from 'react-native';
3 |
4 | import { DropdownOptionProps } from './dropdown.option.type';
5 | import { Button } from '../button/button.component';
6 | import { useDefaultProps } from '../../utilities/useDefaultProps';
7 |
8 | const DropdownOption: React.FunctionComponent = (
9 | incomingProps
10 | ) => {
11 | const props = useDefaultProps('DropdownOption', incomingProps, {
12 | onSelect: () => {},
13 | rounded: 0,
14 | bg: 'white',
15 | py: 'lg',
16 | px: '2xl',
17 | block: true,
18 | color: 'black',
19 | alignItems: 'center',
20 | justifyContent: 'flex-start',
21 | });
22 |
23 | const { children, value, onPress: onPressProp, onSelect, ...rest } = props;
24 |
25 | /**
26 | * on press select option
27 | *
28 | * @param e
29 | */
30 | const onPress = (event: RNGestureResponderEvent) => {
31 | if (onSelect) {
32 | onSelect(value);
33 | }
34 |
35 | if (onPressProp) {
36 | onPressProp(event);
37 | }
38 | };
39 |
40 | return (
41 |
42 | {children}
43 |
44 | );
45 | };
46 |
47 | // DropdownOption.defaultProps = {
48 | // onSelect: () => {},
49 | // rounded: 0,
50 | // bg: 'white',
51 | // p: 0,
52 | // color: 'black',
53 | // alignItems: 'flex-start',
54 | // justifyContent: 'flex-start',
55 | // };
56 |
57 | export { DropdownOption };
58 |
--------------------------------------------------------------------------------
/src/ui/portal/hooks/useKey.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | interface IUseKey {
4 | generateKey(): string;
5 | removeKey(key: string): void;
6 | }
7 |
8 | // Generates a random key
9 | const keyGenerator = (): string => {
10 | return `portalize_${Math.random().toString(36).substr(2, 16)}-${Math.random()
11 | .toString(36)
12 | .substr(2, 16)}-${Math.random().toString(36).substr(2, 16)}`;
13 | };
14 |
15 | // Custom hook that checks for uniqueness and retries if clashes
16 | export const useKey = (): IUseKey => {
17 | const usedKeys = React.useRef>([]);
18 |
19 | const generateKey = (): string => {
20 | let foundUniqueKey = false;
21 | let newKey = '';
22 | let tries = 0;
23 |
24 | while (!foundUniqueKey && tries < 3) {
25 | // limit number of tries to stop endless loop of pain
26 | tries++;
27 | newKey = keyGenerator();
28 |
29 | if (!usedKeys.current.includes(newKey)) {
30 | foundUniqueKey = true;
31 | }
32 | }
33 |
34 | // will only run if exited while loop without finding a unique key
35 | if (!foundUniqueKey) {
36 | newKey = `portalize_${Date.now()}_${Math.floor(Math.random() * 1000)}`; // fallback method
37 | }
38 |
39 | usedKeys.current.push(newKey);
40 | return newKey;
41 | };
42 |
43 | // Removes our key to make it 'available' again
44 | const removeKey = (key: string): void => {
45 | usedKeys.current = usedKeys.current.filter((k) => k !== key);
46 | };
47 |
48 | return { generateKey, removeKey };
49 | };
50 |
--------------------------------------------------------------------------------
/src/ui/image/image.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Image as RNImage } from 'react-native';
3 |
4 | import { getStyle } from './image.style';
5 | import { ImageProps } from './image.type';
6 | import { useTheme } from '../../theme';
7 | import { useDefaultProps } from '../../utilities/useDefaultProps';
8 |
9 | const Image: React.FunctionComponent = (incomingProps) => {
10 | const props = useDefaultProps('Image', incomingProps, {});
11 |
12 | const {
13 | h,
14 | w,
15 | m,
16 | mt,
17 | mr,
18 | mb,
19 | ml,
20 | ms,
21 | p,
22 | pr,
23 | pt,
24 | pb,
25 | pl,
26 | minH,
27 | minW,
28 | maxH,
29 | maxW,
30 | style,
31 | rounded,
32 | roundedTop,
33 | roundedRight,
34 | roundedBottom,
35 | roundedLeft,
36 | borderColor,
37 | borderBottomColor,
38 | borderLeftColor,
39 | borderTopColor,
40 | borderRightColor,
41 | borderWidth,
42 | borderLeftWidth,
43 | borderRightWidth,
44 | borderBottomWidth,
45 | borderTopWidth,
46 | borderEndWidth,
47 | flex,
48 | shadow,
49 | shadowColor,
50 | position,
51 | top,
52 | right,
53 | bottom,
54 | left,
55 | zIndex,
56 | opacity,
57 | alignSelf,
58 | ...rest
59 | } = props;
60 | const { theme } = useTheme();
61 | const computedStyle = getStyle(theme, props);
62 |
63 | return ;
64 | };
65 |
66 | // Image.defaultProps = {};
67 |
68 | export { Image };
69 |
--------------------------------------------------------------------------------
/example/src/components/Overlay.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react';
2 | import { ActivityIndicator, ScrollView } from 'react-native';
3 | import { Button, Div, Overlay, Text, OverlayRef } from 'react-native-magnus';
4 |
5 | import ExamplePage from '../utils/ExamplePage';
6 | import ExampleHeader from '../utils/ExampleHeader';
7 | import ExampleSection from '../utils/ExampleSection';
8 |
9 | const OverlayComponent = () => {
10 | const overlayRef = useRef(null);
11 |
12 | return (
13 |
14 |
15 |
16 |
17 |
18 | {
21 | overlayRef.current?.open();
22 |
23 | setTimeout(() => {
24 | overlayRef.current?.close();
25 | }, 3000);
26 | }}
27 | >
28 | Show Overlay
29 |
30 |
31 | overlayRef.current?.close()}
35 | >
36 |
37 |
38 |
39 | Loading...
40 |
41 |
42 |
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | export default OverlayComponent;
50 |
--------------------------------------------------------------------------------
/docs/static/images/section-api-header.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/utilities/withDefaultProps.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ThemeContext, ThemeType } from '../theme';
3 | import { DefaultProps, VariantPropsType } from '../types';
4 |
5 | export function withDefaultProps<
6 | Props extends object,
7 | Defaults extends DefaultProps = {}
8 | >(
9 | WrappedComponent: React.ComponentClass,
10 | componentName: keyof NonNullable,
11 | defaultProps: Defaults
12 | ) {
13 | type Variant = Props & VariantPropsType;
14 | return class extends React.PureComponent {
15 | static contextType = ThemeContext;
16 | // using `declare` requires babel plugin which doesn't seem to work
17 | // class related components & HOC's should be refactored anyway
18 | // @ts-ignore
19 | context!: React.ContextType;
20 |
21 | render() {
22 | const theme = this.context.theme;
23 |
24 | if (!componentName) {
25 | return ;
26 | }
27 |
28 | let propsFromTheme = {
29 | ...(theme.components?.[componentName] ?? {}),
30 | ...(this.props.variant &&
31 | //@ts-ignore
32 | (theme.components?.[componentName]?.variants?.[this.props.variant] ??
33 | {})),
34 | };
35 |
36 | delete propsFromTheme.variants;
37 |
38 | const mergedProps = {
39 | ...defaultProps,
40 | ...propsFromTheme,
41 | ...this.props,
42 | };
43 |
44 | return ;
45 | }
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/docs/src/components/common/Seo.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash';
2 | import React from 'react';
3 | import Helmet from 'react-helmet';
4 |
5 | function Seo({ seo }) {
6 | const meta = [
7 | {
8 | name: 'description',
9 | content: seo.description,
10 | },
11 | {
12 | property: 'og:title',
13 | content: seo.title,
14 | },
15 | {
16 | property: 'og:url',
17 | content: seo.url,
18 | },
19 | {
20 | property: 'og:description',
21 | content: seo.description,
22 | },
23 | {
24 | property: 'og:type',
25 | content: 'website',
26 | },
27 | {
28 | property: 'og:image',
29 | content: seo.image || 'https://magnus-ui.com/images/og-image.png',
30 | },
31 | {
32 | property: 'og:image:height',
33 | content: 630,
34 | },
35 | {
36 | property: 'og:image:width',
37 | content: 1200,
38 | },
39 | {
40 | name: 'twitter:card',
41 | content: 'summary_large_image',
42 | },
43 | {
44 | name: 'twitter:title',
45 | content: seo.title,
46 | },
47 | {
48 | name: 'twitter:description',
49 | content: seo.description,
50 | },
51 | {
52 | name: 'twitter:image',
53 | content: seo.image || 'https://magnus-ui.com/images/og-image.png',
54 | },
55 | ];
56 |
57 | return (
58 |
66 | );
67 | }
68 |
69 | export default Seo;
70 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-magnus-example",
3 | "version": "0.0.1",
4 | "description": "Example for React Native Magnus",
5 | "author": "",
6 | "private": true,
7 | "scripts": {
8 | "start": "expo start",
9 | "android": "expo android",
10 | "ios": "expo ios",
11 | "web": "expo start:web",
12 | "publish": "expo publish"
13 | },
14 | "main": "node_modules/expo/AppEntry.js",
15 | "dependencies": {
16 | "@expo/webpack-config": "^0.17.0",
17 | "@react-native-async-storage/async-storage": "1.17.10",
18 | "@react-navigation/drawer": "^6.4.4",
19 | "@react-navigation/native": "^6.0.12",
20 | "@react-navigation/stack": "^6.2.3",
21 | "deepmerge": "^4.2.2",
22 | "expo": "^46.0.0",
23 | "expo-font": "~10.2.0",
24 | "expo-splash-screen": "~0.16.2",
25 | "react": "18.0.0",
26 | "react-dom": "18.0.0",
27 | "react-native": "0.69.5",
28 | "react-native-animatable": "^1.3.3",
29 | "react-native-gesture-handler": "~2.5.0",
30 | "react-native-modal": "^13.0.1",
31 | "react-native-reanimated": "~2.9.1",
32 | "react-native-safe-area-context": "4.3.1",
33 | "react-native-screens": "~3.15.0",
34 | "react-native-vector-icons": "^9.2.0",
35 | "react-native-web": "~0.18.7"
36 | },
37 | "devDependencies": {
38 | "@babel/core": "^7.19.0",
39 | "@types/react": "^18.0.0",
40 | "@types/react-native": "^0.69.5",
41 | "babel-loader": "^8.2.5",
42 | "babel-plugin-module-resolver": "^4.1.0",
43 | "babel-preset-expo": "~9.2.0",
44 | "typescript": "^4.8.3"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/docs/src/components/common/UserDropdown.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { Link } from 'gatsby';
3 |
4 | import { logout } from '../../utilities/auth';
5 |
6 | const UserDropdown = (props) => {
7 | const { user } = props;
8 | const [open, setOpen] = useState(false);
9 |
10 | const hideDropdown = () => {
11 | setOpen(false);
12 | };
13 |
14 | useEffect(() => {
15 | window.addEventListener('click', hideDropdown);
16 | });
17 |
18 | return (
19 |
20 |
{
23 | e.stopPropagation();
24 | setOpen(true);
25 | }}
26 | >
27 |
32 |
33 |
34 |
52 |
53 | );
54 | };
55 |
56 | export default UserDropdown;
57 |
--------------------------------------------------------------------------------
/docs/src/components/home/Components.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'gatsby';
3 |
4 | export default function Features() {
5 | return (
6 |
10 |
11 |
12 |
13 |
14 |
20 |
21 | Consistent and Modular Components
22 |
23 |
24 | Magnus UI comes with a set of polished React Native components
25 | that just works out of the box.
26 |
27 |
31 | Check out full list of components →
32 |
33 |
34 |
35 | {/*
36 |
37 |
*/}
38 |
39 |
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/docs/src/components/home/Composable.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'gatsby';
3 |
4 | export default function C() {
5 | return (
6 |
10 |
11 |
12 |
34 |
35 |
39 |
40 |
41 |
42 |
43 | );
44 | }
45 |
--------------------------------------------------------------------------------
/src/ui/image/image.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createShadowStyles,
6 | createSpacingStyles,
7 | createPositionStyle,
8 | createBorderRadiusStyles,
9 | createBorderColorStyles,
10 | createBorderWidthStyles,
11 | getThemeColor,
12 | } from '../../theme/theme.service';
13 | import { ImageProps } from './image.type';
14 |
15 | /**
16 | * computed style
17 | *
18 | * @param theme
19 | * @param props
20 | */
21 | export const getStyle = (theme: ThemeType, props: ImageProps) => {
22 | const computedStyle: any = {};
23 |
24 | computedStyle.image = {
25 | flex: props.flex,
26 | height: props.h,
27 | width: props.w,
28 | minHeight: props.minH,
29 | minWidth: props.minH,
30 | maxWidth: props.maxW,
31 | maxHeight: props.maxH,
32 | position: props.position,
33 | zIndex: props.zIndex,
34 | alignSelf: props.alignSelf,
35 | ...createPositionStyle(props),
36 | ...createBorderWidthStyles(props),
37 | ...createShadowStyles(props, theme),
38 | ...createSpacingStyles(props, theme.spacing),
39 | ...createBorderColorStyles(props, theme.colors),
40 | ...createBorderRadiusStyles(props, theme.borderRadius),
41 | backgroundColor: getThemeColor(theme.colors, props.bg),
42 | };
43 |
44 | // merging style props to computed style
45 | if (props.style) {
46 | computedStyle.image = {
47 | ...computedStyle.image,
48 | // @ts-ignore
49 | ...props.style,
50 | };
51 | }
52 |
53 | return StyleSheet.create(computedStyle);
54 | };
55 |
--------------------------------------------------------------------------------
/docs/content/docs/shadows.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Shadows
3 | date: "2019-08-13"
4 | description: ""
5 | ---
6 |
7 |
8 |
9 | There are 6 values of shadows present in magnus's default theme - which are 1,2, 3, 4, 5 & 6.
10 |
11 |
12 |
13 | See it on Snack
14 |
15 | ```jsx
16 |
17 |
18 |
19 |
20 |
21 |
22 | ```
23 |
24 | > Make sure you add a background color when using shadow, otherwise it won't work in some cases.
25 |
26 | ### Adding custom shadows
27 |
28 | ```jsx
29 | import React from "react";
30 | import { AppRegistry } from "react-native";
31 | import { ThemeProvider, Text } from "react-native-magnus";
32 | import App from "./src/App";
33 |
34 | const theme = {
35 | shadows: {
36 | "3xl": {
37 | shadowOffset: {
38 | width: 0,
39 | height: 10,
40 | },
41 | shadowOpacity: 0.8,
42 | shadowRadius: 14,
43 |
44 | elevation: 25,
45 | },
46 | },
47 | };
48 |
49 | export default function Main() {
50 | return (
51 |
52 |
53 |
54 | );
55 | }
56 | ```
57 |
--------------------------------------------------------------------------------
/docs/src/constants/theme.js:
--------------------------------------------------------------------------------
1 | export const code = {
2 | plain: {
3 | color: '#393A34',
4 | backgroundColor: '#f7f8f9',
5 | },
6 | styles: [
7 | {
8 | types: ['comment', 'prolog', 'doctype', 'cdata'],
9 | style: {
10 | color: '#999988',
11 | fontStyle: 'italic',
12 | },
13 | },
14 | {
15 | types: ['namespace'],
16 | style: {
17 | opacity: 0.7,
18 | },
19 | },
20 | {
21 | types: ['string', 'attr-value'],
22 | style: {
23 | color: '#e3116c',
24 | },
25 | },
26 | {
27 | types: ['punctuation', 'operator'],
28 | style: {
29 | color: '#393A34',
30 | },
31 | },
32 | {
33 | types: [
34 | 'entity',
35 | 'url',
36 | 'symbol',
37 | 'number',
38 | 'boolean',
39 | 'variable',
40 | 'constant',
41 | 'property',
42 | 'regex',
43 | 'inserted',
44 | ],
45 | style: {
46 | color: '#36acaa',
47 | },
48 | },
49 | {
50 | types: ['atrule', 'keyword', 'attr-name', 'selector'],
51 | style: {
52 | color: '#00a4db',
53 | },
54 | },
55 | {
56 | types: ['function', 'deleted', 'tag'],
57 | style: {
58 | color: '#d73a49',
59 | },
60 | },
61 | {
62 | types: ['function-variable'],
63 | style: {
64 | color: '#6f42c1',
65 | },
66 | },
67 | {
68 | types: ['tag', 'selector', 'keyword'],
69 | style: {
70 | color: '#00009f',
71 | },
72 | },
73 | ],
74 | };
75 |
--------------------------------------------------------------------------------
/src/ui/drawer/drawer.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Dimensions } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createBorderColorStyles,
6 | createBorderWidthStyles,
7 | createBorderRadiusStyles,
8 | getThemeColor,
9 | } from '../../theme/theme.service';
10 | import { DrawerProps } from './drawer.type';
11 |
12 | const SCREEN_WIDTH = Dimensions.get('window').width;
13 | const SCREEN_HEIGHT = Dimensions.get('window').height;
14 |
15 | /**
16 | * computed style
17 | *
18 | * @param theme
19 | * @param props
20 | */
21 | export const getStyle = (theme: ThemeType, props: DrawerProps) => {
22 | const computedStyle: any = {};
23 |
24 | computedStyle.drawer = {
25 | margin: 0,
26 | };
27 |
28 | computedStyle.container = {
29 | position: 'absolute',
30 | height: SCREEN_HEIGHT,
31 | // @ts-ignore
32 | width: SCREEN_WIDTH * (props.drawerPercentage / 100),
33 | zIndex: 0,
34 | margin: 0,
35 | backgroundColor: getThemeColor(theme.colors, props.bg),
36 | ...createBorderWidthStyles(props),
37 | ...createBorderColorStyles(props, theme.colors),
38 | ...createBorderRadiusStyles(props, theme.borderRadius),
39 | };
40 |
41 | computedStyle.safeView = {
42 | flex: 1,
43 | };
44 |
45 | if (props.direction === 'right') {
46 | computedStyle.container = {
47 | ...computedStyle.container,
48 | right: 0,
49 | };
50 | } else {
51 | computedStyle.container = {
52 | ...computedStyle.container,
53 | left: 0,
54 | };
55 | }
56 |
57 | return StyleSheet.create(computedStyle);
58 | };
59 |
--------------------------------------------------------------------------------
/src/ui/select/select.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createSpacingStyles,
6 | createBorderRadiusStyles,
7 | createBorderColorStyles,
8 | createBorderWidthStyles,
9 | getThemeColor,
10 | } from '../../theme/theme.service';
11 | import { WINDOW_HEIGHT } from '../../utilities';
12 | import { SelectProps } from './select.type';
13 |
14 | /**
15 | * computed style
16 | *
17 | * @param theme
18 | * @param props
19 | */
20 | export const getStyle = (theme: ThemeType, props: SelectProps) => {
21 | const computedStyle: any = {};
22 |
23 | computedStyle.wrapper = {
24 | backgroundColor: getThemeColor(theme.colors, props.bg),
25 | ...createBorderWidthStyles(props),
26 | ...createBorderColorStyles(props, theme.colors),
27 | ...createBorderRadiusStyles(props, theme.borderRadius),
28 | height: WINDOW_HEIGHT * 0.7,
29 | overflow: 'hidden',
30 | };
31 |
32 | computedStyle.indicator = {
33 | alignSelf: 'center',
34 | marginVertical: 10,
35 | };
36 |
37 | computedStyle.container = {
38 | flex: 1,
39 | ...createSpacingStyles(props, theme.spacing),
40 | };
41 |
42 | if (props.h) {
43 | computedStyle.container = {
44 | ...computedStyle.container,
45 | height: props.h,
46 | };
47 | }
48 |
49 | // merging style props to computed style
50 | if (props.style) {
51 | computedStyle.container = {
52 | ...computedStyle.container,
53 | // @ts-ignore
54 | ...props.style,
55 | };
56 | }
57 | return StyleSheet.create(computedStyle);
58 | };
59 |
--------------------------------------------------------------------------------
/docs/content/docs/border-radius.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Border Radius
3 | date: "2019-08-13"
4 | description: ""
5 | ---
6 |
7 |
8 |
9 | There are 6 values of border radius available in the default theme - that are `none`, `xs`, `sm`, `md`, `lg`, `xl`, `2xl` and `circle`.
10 |
11 |
12 |
13 | See it on Snack
14 |
15 | ```jsx
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | ```
24 |
25 | | Size | Value |
26 | | ------ | ----- |
27 | | none | 0 |
28 | | xs | 2 |
29 | | sm | 4 |
30 | | md | 6 |
31 | | lg | 8 |
32 | | xl | 12 |
33 | | 2xl | 16 |
34 | | circle | 10000 |
35 |
36 | ### Adding border radius
37 |
38 | ```jsx
39 | import React from "react";
40 | import { AppRegistry } from "react-native";
41 | import { ThemeProvider, Text } from "react-native-magnus";
42 | import App from "./src/App";
43 |
44 | const theme = {
45 | borderRadius: {
46 | "3xl": 20,
47 | },
48 | };
49 |
50 | export default function Main() {
51 | return (
52 |
53 |
54 |
55 | );
56 | }
57 | ```
58 |
--------------------------------------------------------------------------------
/src/ui/snackbar/snackbar.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createShadowStyles,
6 | createSpacingStyles,
7 | createBorderColorStyles,
8 | createBorderWidthStyles,
9 | createBorderRadiusStyles,
10 | getThemeColor,
11 | } from '../../theme/theme.service';
12 | import { SnackbarProps } from './snackbar.type';
13 |
14 | /**
15 | * computed style
16 | *
17 | * @param theme
18 | * @param props
19 | */
20 | export const getStyle = (theme: ThemeType, props: SnackbarProps) => {
21 | const computedStyle: any = {};
22 |
23 | computedStyle.wrapper = {
24 | width: '100%',
25 | };
26 |
27 | computedStyle.text = {
28 | flex: 1,
29 | };
30 |
31 | computedStyle.prefix = {
32 | marginRight: 8,
33 | };
34 |
35 | computedStyle.suffix = {
36 | marginLeft: 8,
37 | };
38 |
39 | computedStyle.container = {
40 | flexDirection: props.flexDir,
41 | justifyContent: props.justifyContent,
42 | alignItems: props.justifyContent,
43 | alignSelf: props.alignSelf,
44 | width: props.w,
45 | height: props.h,
46 | minWidth: props.minW,
47 | minHeight: props.minH,
48 | maxWidth: props.maxW,
49 | maxHeight: props.maxH,
50 | opacity: props.opacity,
51 | ...createShadowStyles(props, theme),
52 | ...createBorderWidthStyles(props),
53 | ...createSpacingStyles(props, theme.spacing),
54 | ...createBorderColorStyles(props, theme.colors),
55 | ...createBorderRadiusStyles(props, theme.borderRadius),
56 | backgroundColor: getThemeColor(theme.colors, props.bg),
57 | };
58 |
59 | return StyleSheet.create(computedStyle);
60 | };
61 |
--------------------------------------------------------------------------------
/src/ui/select/select.type.tsx:
--------------------------------------------------------------------------------
1 | import { ViewProps as RNViewProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | DimensionPropsType,
5 | FlexPropsType,
6 | PositionPropsType,
7 | BorderPropsType,
8 | SpacingPropsType,
9 | RoundedPropsType,
10 | ShadowPropsType,
11 | VariantPropsType,
12 | } from '../../types';
13 | import { SelectOption } from './select.option.component';
14 |
15 | export interface CompoundedSelect
16 | extends React.ForwardRefExoticComponent<
17 | SelectProps & React.RefAttributes
18 | > {
19 | Option: typeof SelectOption;
20 | }
21 |
22 | export type SelectRef = {
23 | open: () => void;
24 | close: () => void;
25 | };
26 |
27 | export interface SelectProps
28 | extends RNViewProps,
29 | BorderPropsType,
30 | SpacingPropsType,
31 | RoundedPropsType,
32 | ShadowPropsType,
33 | BackgroundPropsType,
34 | FlexPropsType,
35 | PositionPropsType,
36 | DimensionPropsType,
37 | VariantPropsType {
38 | title?: string | React.ReactNode;
39 | message?: string | React.ReactNode;
40 |
41 | showScrollIndicator?: boolean;
42 |
43 | multiple?: boolean;
44 | value: any;
45 | footer?: React.ReactElement[] | React.ReactElement;
46 | onSelect: (value: any) => void;
47 | data: any[];
48 | renderItem: (item: any, index: number) => React.ReactElement;
49 | keyExtractor?: (item: any, index: number) => string;
50 | isVisible?: boolean;
51 |
52 | searchableProps?: '*' | string[];
53 | renderNoResultsView?: (searchTerm: string) => React.ReactElement;
54 | renderSubmitButton?: () => React.ReactElement;
55 | renderSearchInput?: (props: { clearText: () => void }) => React.ReactElement;
56 | }
57 |
--------------------------------------------------------------------------------
/src/ui/text/text.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Text as RNText } from 'react-native';
3 |
4 | import { TextProps } from './text.type';
5 | import { getStyle } from './text.style';
6 | import { useTheme } from '../../theme';
7 | import { useDefaultProps } from '../../utilities/useDefaultProps';
8 |
9 | const Text: React.FunctionComponent = (incomingProps) => {
10 | const props = useDefaultProps('Text', incomingProps, {
11 | color: 'gray900',
12 | textAlign: 'auto',
13 | textTransform: 'none',
14 | fontSize: 'md',
15 | overflow: 'hidden',
16 | textAlignVertical: 'center',
17 | });
18 |
19 | const {
20 | w,
21 | h,
22 | bg,
23 | m,
24 | mt,
25 | mr,
26 | mb,
27 | ml,
28 | ms,
29 | p,
30 | pr,
31 | pt,
32 | pb,
33 | pl,
34 | flex,
35 | minH,
36 | minW,
37 | color,
38 | fontSize,
39 | children,
40 | textAlign,
41 | fontWeight,
42 | lineHeight,
43 | letterSpacing,
44 | textTransform,
45 | textDecorColor,
46 | textDecorStyle,
47 | fontStyle,
48 | textDecorLine,
49 | textAlignVertical,
50 | overflow,
51 | opacity,
52 | zIndex,
53 | style,
54 | ...rest
55 | } = props;
56 | const { theme } = useTheme();
57 | const computedStyle = getStyle(theme, props);
58 |
59 | return (
60 |
61 | {children}
62 |
63 | );
64 | };
65 |
66 | // Text.defaultProps = {
67 | // color: 'gray900',
68 | // textAlign: 'auto',
69 | // textTransform: 'none',
70 | // fontSize: 'md',
71 | // overflow: 'hidden',
72 | // };
73 |
74 | export { Text };
75 |
--------------------------------------------------------------------------------
/src/ui/dropdown/dropdown.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createSpacingStyles,
6 | createBorderWidthStyles,
7 | createBorderColorStyles,
8 | createBorderRadiusStyles,
9 | getThemeColor,
10 | } from '../../theme/theme.service';
11 | import { DropdownProps } from './dropdown.type';
12 |
13 | /**
14 | * computed style
15 | *
16 | * @param theme
17 | * @param props
18 | */
19 | export const getStyle = (theme: ThemeType, props: DropdownProps) => {
20 | const computedStyle: any = {};
21 |
22 | computedStyle.wrapper = {
23 | height: props.h,
24 | width: props.w,
25 | minHeight: props.minH,
26 | minWidth: props.minW,
27 | alignSelf: 'center',
28 | overflow: props.overflow,
29 | backgroundColor: getThemeColor(theme.colors, props.bg),
30 | ...createBorderWidthStyles(props),
31 | ...createBorderColorStyles(props, theme.colors),
32 | ...createBorderRadiusStyles(props, theme.borderRadius),
33 | };
34 |
35 | computedStyle.indicator = {
36 | alignSelf: 'center',
37 | marginVertical: 10,
38 | };
39 |
40 | computedStyle.container = {
41 | ...createSpacingStyles(props, theme.spacing),
42 | };
43 |
44 | computedStyle.options = {
45 | flexWrap: props.flexWrap,
46 | flexDirection: props.flexDir,
47 | alignItems: props.alignItems,
48 | justifyContent: props.justifyContent,
49 | };
50 |
51 | // merging style props to computed style
52 | if (props.style) {
53 | computedStyle.container = {
54 | ...computedStyle.container,
55 | // @ts-ignore
56 | ...props.style,
57 | };
58 | }
59 |
60 | return StyleSheet.create(computedStyle);
61 | };
62 |
--------------------------------------------------------------------------------
/docs/static/images/favicon/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 | Created by potrace 1.11, written by Peter Selinger 2001-2013
9 |
10 |
12 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/ui/checkbox/group.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { useState } from 'react';
3 | import { useDefaultProps } from '../../utilities/useDefaultProps';
4 |
5 | import { Div } from '../div/div.component';
6 | import { CheckboxGroupProps } from './checkbox.type';
7 |
8 | const CheckboxGroup: React.FunctionComponent = (
9 | incomingProps
10 | ) => {
11 | const props = useDefaultProps('CheckboxGroup', incomingProps, {});
12 |
13 | const [value, setValue] = useState(props.value ?? props.defaultValue ?? []);
14 | const {
15 | children,
16 | onChange: onChangeProp,
17 | value: propsValue,
18 | ...rest
19 | } = props;
20 |
21 | /**
22 | * checks if checked value is already in the state or not,
23 | * if it, remove it else add it
24 | *
25 | * @param value
26 | */
27 | const onChange = (optionValue: any) => {
28 | const optionIndex = value.indexOf(optionValue);
29 | const newValue = [...value];
30 |
31 | if (optionIndex === -1) {
32 | newValue.push(optionValue);
33 | } else {
34 | newValue.splice(optionIndex, 1);
35 | }
36 |
37 | if (!('value' in props)) {
38 | setValue(newValue);
39 | }
40 |
41 | if (onChangeProp) {
42 | onChangeProp(newValue);
43 | }
44 | };
45 |
46 | /**
47 | * clones the children and add checked, onChange prop
48 | */
49 | const renderChildren = () => {
50 | return React.Children.map(children, (child: React.ReactElement) => {
51 | return React.cloneElement(child, {
52 | onChange,
53 | checked: value.indexOf(child.props.value) > -1,
54 | });
55 | });
56 | };
57 |
58 | return {renderChildren()}
;
59 | };
60 |
61 | export { CheckboxGroup };
62 |
--------------------------------------------------------------------------------
/docs/content/docs/portal/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Portal
3 | date: "2019-08-13"
4 | description: ""
5 | ---
6 |
7 | Portal helps rendering a component outside where it is defined. Generally used for Snackbar, Modals, Drawers.
8 |
9 | ```jsx
10 | import React from "react";
11 | import { Div, Text, Host, Portal } from "react-native-magnus";
12 |
13 | export const MyApp = () => (
14 |
15 |
16 |
Some copy here and there...
17 |
18 |
19 | A portal on top of the rest
20 |
21 |
22 |
23 | );
24 | ```
25 |
26 | ### Snackbar
27 |
28 | Example with Snackbar
29 |
30 | ```jsx
31 | import React from "react";
32 | import { Modal, Host, Portal, Div, Icon, SnackbarRef } from "react-native-magnus";
33 |
34 | const snackbarLightRef = React.createRef();
35 |
36 | export const App = () => (
37 |
38 |
39 |
{
41 | if (snackbarLightRef.current) {
42 | snackbarLightRef.current.show();
43 | }
44 | }}
45 | >
46 | Open snackbar
47 |
48 |
49 |
50 |
58 | }
59 | onDismiss={() => {}}
60 | ref={snackbarLightRef}
61 | bg="green300"
62 | color="green800"
63 | duration={2000}
64 | >
65 | Here is a light snack for you!
66 |
67 |
68 |
69 |
70 | );
71 | ```
72 |
73 | This will render the snackbar outside the `Div` component because we wrapped it inside `Portal` component.
74 |
--------------------------------------------------------------------------------
/src/ui/skeleton/skeleton.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import * as Animatable from 'react-native-animatable';
3 | import { useDefaultProps } from '../../utilities/useDefaultProps';
4 |
5 | import { Div } from '../div/div.component';
6 | import { SkeletonProps, CompundedSkeleton } from './skeleton.type';
7 |
8 | const Skeleton: CompundedSkeleton
= (incomingProps) => {
9 | const props = useDefaultProps('Skeleton', incomingProps, {
10 | bg: 'gray400',
11 | h: 15,
12 | w: '100%',
13 | rounded: 'lg',
14 | duration: 1000,
15 | });
16 |
17 | const { duration, ...rest } = props;
18 |
19 | Animatable.initializeRegistryWithDefinitions({
20 | fade: {
21 | 0: {
22 | opacity: 1,
23 | },
24 | 0.5: {
25 | opacity: 0.3,
26 | },
27 | 1: {
28 | opacity: 1,
29 | },
30 | },
31 | });
32 |
33 | return (
34 |
40 |
41 |
42 | );
43 | };
44 |
45 | export const Circle: React.FunctionComponent = (
46 | incomingProps
47 | ) => {
48 | const props = useDefaultProps('SkeletonCircle', incomingProps, {
49 | bg: 'gray400',
50 | h: 15,
51 | w: 15,
52 | rounded: 'circle',
53 | });
54 |
55 | return ;
56 | };
57 |
58 | Skeleton.defaultProps = {
59 | bg: 'gray400',
60 | h: 15,
61 | w: '100%',
62 | rounded: 'lg',
63 | duration: 1000,
64 | };
65 |
66 | Circle.defaultProps = {
67 | bg: 'gray400',
68 | h: 15,
69 | w: 15,
70 | rounded: 'circle',
71 | };
72 |
73 | Skeleton.Box = Skeleton;
74 | Skeleton.Circle = Circle;
75 |
76 | export { Skeleton };
77 |
--------------------------------------------------------------------------------
/src/ui/header/header.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import { HeaderProps } from './header.type';
5 |
6 | /**
7 | * computed styles
8 | *
9 | * @param theme
10 | * @param props
11 | */
12 | export const getStyle = (_theme: ThemeType, props: HeaderProps) => {
13 | const computedStyle: any = {};
14 |
15 | // merging style props to computed style
16 | if (props.style) {
17 | computedStyle.container = {
18 | ...computedStyle.container,
19 | // @ts-ignore
20 | ...props.style,
21 | };
22 | }
23 |
24 | computedStyle.center = {};
25 |
26 | if (props.suffix) {
27 | computedStyle.suffix = {
28 | zIndex: 1,
29 | flexDirection: 'row',
30 | alignItems: 'center',
31 | };
32 | }
33 |
34 | if (props.prefix) {
35 | computedStyle.prefix = {
36 | zIndex: 1,
37 | flexDirection: 'row',
38 | alignItems: 'center',
39 | };
40 | }
41 |
42 | if (props.alignment === 'center') {
43 | computedStyle.center = {
44 | ...computedStyle.center,
45 | justifyContent: 'center',
46 | alignItems: 'center',
47 | flex: 1,
48 | };
49 |
50 | computedStyle.container = {
51 | ...computedStyle.container,
52 | justifyContent: 'space-between',
53 | };
54 |
55 | if (props.suffix || props.prefix) {
56 | computedStyle.center = {
57 | ...computedStyle.center,
58 | ...StyleSheet.absoluteFillObject,
59 | };
60 |
61 | computedStyle.suffix = {
62 | ...computedStyle.suffix,
63 | flex: 1,
64 | justifyContent: 'flex-end',
65 | };
66 | }
67 | } else {
68 | computedStyle.center = {
69 | flex: 1,
70 | };
71 | }
72 |
73 | return StyleSheet.create(computedStyle);
74 | };
75 |
--------------------------------------------------------------------------------
/src/ui/icon/icon.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | getThemeProperty,
6 | createShadowStyles,
7 | createSpacingStyles,
8 | createBorderColorStyles,
9 | createBorderWidthStyles,
10 | createBorderRadiusStyles,
11 | getThemeColor,
12 | } from '../../theme/theme.service';
13 | import { IconProps } from './icon.type';
14 |
15 | /**
16 | * computed style
17 | *
18 | * @param theme
19 | * @param props
20 | */
21 | export const getStyle = (theme: ThemeType, props: IconProps) => {
22 | const computedStyle: any = {};
23 |
24 | computedStyle.container = {
25 | height: props.h,
26 | width: props.w,
27 | minHeight: props.minH,
28 | minWidth: props.minW,
29 | maxWidth: props.maxW,
30 | maxHeight: props.maxH,
31 | top: props.top,
32 | left: props.left,
33 | right: props.right,
34 | bottom: props.bottom,
35 | position: props.position,
36 | alignSelf: props.alignSelf,
37 | alignItems: 'center',
38 | justifyContent: 'center',
39 | opacity: props.opacity,
40 | color: getThemeColor(theme.colors, props.color),
41 | fontSize: getThemeProperty(theme.fontSize, props.fontSize),
42 | backgroundColor: getThemeColor(theme.colors, props.bg),
43 | ...createBorderWidthStyles(props),
44 | ...createSpacingStyles(props, theme.spacing),
45 | ...createBorderColorStyles(props, theme.colors),
46 | ...createBorderRadiusStyles(props, theme.borderRadius),
47 | ...createShadowStyles(props, theme),
48 | };
49 |
50 | // merging style props to computed style
51 | if (props.style) {
52 | computedStyle.container = {
53 | ...computedStyle.container,
54 | // @ts-ignore
55 | ...props.style,
56 | };
57 | }
58 |
59 | return StyleSheet.create(computedStyle);
60 | };
61 |
--------------------------------------------------------------------------------
/src/ui/animated/animated.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createFlexStyles,
6 | createShadowStyles,
7 | createPositionStyle,
8 | createSpacingStyles,
9 | createBorderWidthStyles,
10 | createBorderColorStyles,
11 | createBorderRadiusStyles,
12 | getThemeColor,
13 | } from '../../theme/theme.service';
14 |
15 | /**
16 | * computed style
17 | *
18 | * @param theme
19 | * @param props
20 | */
21 | export const getStyle = (theme: ThemeType, props: any) => {
22 | const computedStyle: any = {};
23 |
24 | computedStyle.div = {
25 | flexDirection: props.row ? 'row' : props.flexDir,
26 | flexWrap: props.flexWrap,
27 | alignItems: props.alignItems,
28 | justifyContent: props.justifyContent,
29 | height: props.h,
30 | width: props.w,
31 | minWidth: props.minW,
32 | minHeight: props.minH,
33 | alignSelf: props.alignSelf,
34 | maxWidth: props.maxW,
35 | maxHeight: props.maxH,
36 | opacity: props.opacity,
37 | overflow: props.overflow,
38 | zIndex: props.zIndex,
39 | borderStyle: props.borderStyle,
40 | backgroundColor: getThemeColor(theme.colors, props.bg),
41 | ...createFlexStyles(props),
42 | ...createPositionStyle(props),
43 | ...createShadowStyles(props, theme),
44 | ...createBorderWidthStyles(props),
45 | ...createSpacingStyles(props, theme.spacing),
46 | ...createBorderColorStyles(props, theme.colors),
47 | ...createBorderRadiusStyles(props, theme.borderRadius),
48 | };
49 |
50 | computedStyle.image = {
51 | ...createBorderRadiusStyles(props, theme.borderRadius),
52 | };
53 |
54 | // merging style props to computed style
55 | if (props.style) {
56 | computedStyle.div = {
57 | ...computedStyle.div,
58 | ...props.style,
59 | };
60 | }
61 |
62 | return StyleSheet.create(computedStyle);
63 | };
64 |
--------------------------------------------------------------------------------
/example/src/utils/ExampleHeader.tsx:
--------------------------------------------------------------------------------
1 | import { useNavigation } from '@react-navigation/native';
2 | import React from 'react';
3 | import {
4 | Button,
5 | Div,
6 | Header,
7 | Icon,
8 | Text,
9 | Toggle,
10 | useTheme,
11 | } from 'react-native-magnus';
12 | import { lightTheme, darkTheme, saveThemeName } from '../themes';
13 |
14 | interface ExampleHeaderProps {
15 | name: string;
16 | }
17 |
18 | const ExampleHeader = ({ name }: ExampleHeaderProps) => {
19 | const navigation = useNavigation();
20 | const { theme, setTheme } = useTheme();
21 |
22 | return (
23 | navigation.goBack()}
32 | >
33 |
34 |
35 | }
36 | suffix={
37 |
38 |
39 | {
44 | saveThemeName(
45 | theme.name === 'dark' ? lightTheme.name! : darkTheme.name!
46 | );
47 | setTheme(theme.name === 'dark' ? lightTheme : darkTheme);
48 | }}
49 | />
50 |
51 | }
52 | >
53 |
54 |
60 | {name}
61 |
62 | Examples
63 |
64 |
65 | );
66 | };
67 |
68 | export default ExampleHeader;
69 |
--------------------------------------------------------------------------------
/example/src/components/Tag.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ScrollView } from 'react-native';
3 | import { Div, Icon, Tag } from 'react-native-magnus';
4 | import ExampleHeader from '../utils/ExampleHeader';
5 | import ExamplePage from '../utils/ExamplePage';
6 | import ExampleSection from '../utils/ExampleSection';
7 |
8 | const TagComponent = () => {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 | Tag
16 |
17 |
18 |
19 |
20 |
23 | }
24 | >
25 | Close
26 |
27 |
31 | }
32 | >
33 | Edit
34 |
35 |
36 |
37 |
38 |
39 |
40 |
47 | Custom Tag 1
48 |
49 |
50 | Custom Tag 1
51 |
52 |
53 | Solid Tag
54 |
55 |
56 |
57 |
58 |
59 | );
60 | };
61 |
62 | export default TagComponent;
63 |
--------------------------------------------------------------------------------
/example/src/components/Tooltip.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ScrollView } from 'react-native';
3 | import {
4 | Button,
5 | Div,
6 | Icon,
7 | Text,
8 | Tooltip,
9 | TooltipRef,
10 | } from 'react-native-magnus';
11 |
12 | import ExamplePage from '../utils/ExamplePage';
13 | import ExampleHeader from '../utils/ExampleHeader';
14 | import ExampleSection from '../utils/ExampleSection';
15 |
16 | const TooltipComponent = () => {
17 | const tooltipRef1 = React.useRef(null);
18 | const tooltipRef2 = React.useRef(null);
19 |
20 | return (
21 |
22 |
23 |
24 |
25 |
26 |
27 | tooltipRef1.current?.show()}>
28 | Show Tooltip
29 |
30 |
31 |
32 |
33 |
34 |
45 |
46 |
47 | Custom tooltip content
48 |
49 |
50 | }
51 | bg="red500"
52 | >
53 |
tooltipRef2.current?.show()}>
54 | Show me tooltip
55 |
56 |
57 |
58 |
59 |
60 | );
61 | };
62 |
63 | export default TooltipComponent;
64 |
--------------------------------------------------------------------------------
/src/ui/div/div.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createShadowStyles,
6 | createPositionStyle,
7 | createSpacingStyles,
8 | createBorderWidthStyles,
9 | createBorderColorStyles,
10 | createBorderRadiusStyles,
11 | getThemeColor,
12 | } from '../../theme/theme.service';
13 | import { DivProps } from './div.type';
14 |
15 | /**
16 | * computed style
17 | *
18 | * @param theme
19 | * @param props
20 | */
21 | export const getStyle = (theme: ThemeType, props: DivProps) => {
22 | const computedStyle: any = {};
23 |
24 | computedStyle.div = {
25 | flexDirection: props.row ? 'row' : props.flexDir,
26 | flexWrap: props.flexWrap,
27 | alignItems: props.alignItems,
28 | justifyContent: props.justifyContent,
29 | height: props.h,
30 | width: props.w,
31 | minWidth: props.minW,
32 | minHeight: props.minH,
33 | alignSelf: props.alignSelf,
34 | maxWidth: props.maxW,
35 | maxHeight: props.maxH,
36 | opacity: props.opacity,
37 | overflow: props.overflow,
38 | zIndex: props.zIndex,
39 | borderStyle: props.borderStyle,
40 | backgroundColor: getThemeColor(theme.colors, props.bg),
41 | flex: props.flex,
42 | ...createPositionStyle(props),
43 | ...createShadowStyles(props, theme),
44 | ...createBorderWidthStyles(props),
45 | ...createSpacingStyles(props, theme.spacing),
46 | ...createBorderColorStyles(props, theme.colors),
47 | ...createBorderRadiusStyles(props, theme.borderRadius),
48 | };
49 |
50 | computedStyle.image = {
51 | ...createBorderRadiusStyles(props, theme.borderRadius),
52 | };
53 |
54 | // merging custom style props to computed style
55 | if (props.style) {
56 | computedStyle.div = {
57 | ...computedStyle.div,
58 | // @ts-ignore
59 | ...props.style,
60 | };
61 | }
62 |
63 | return StyleSheet.create(computedStyle);
64 | };
65 |
--------------------------------------------------------------------------------
/docs/src/constants/example.js:
--------------------------------------------------------------------------------
1 | const code = `
2 |
3 |
4 |
5 |
6 | Discover the world’s top Designers & Creatives.
7 |
8 | Art by Irina Valeeva
9 |
10 |
11 |
}>Sign-in with Twitter
12 |
}>Sign-in with Facebook
13 |
}>Sign-in with Google
14 |
15 |
16 |
Or With Email
17 |
18 |
19 |
20 |
21 | Sign in
22 | Sign up
23 |
24 |
25 |
26 |
27 | `;
28 |
29 | export default code;
30 |
--------------------------------------------------------------------------------
/docs/static/images/customization.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/docs/content/docs/modal/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Modal
3 | date: "2019-08-13"
4 | description: ""
5 | ---
6 |
7 | Wrapper around `
` of [react-native-modal](https://github.com/react-native-community/react-native-modal). It accepts all the props `react-native-modal` offers.
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ```jsx
16 | import React, { useState } from "react";
17 | import { SafeAreaView, StatusBar, FlatList } from "react-native";
18 | import { Div, Button, Icon, Modal, ThemeProvider } from "react-native-magnus";
19 |
20 | const App = () => {
21 | const [visible, setVisible] = useState(false);
22 |
23 | return (
24 |
25 |
26 |
27 | setVisible(true)}>
28 | Open Modal
29 |
30 |
31 |
32 | {
41 | setVisible(false);
42 | }}
43 | >
44 |
45 |
46 |
47 |
48 |
49 | );
50 | };
51 |
52 | export default App;
53 | ```
54 |
55 | ## Props
56 |
57 | | Property | Description | Type | Default |
58 | | -------- | ------------------- | -------- | ------- |
59 | | h | height of modal | `number` | `100%` |
60 | | bg | background of modal | `string` | `white` |
61 |
62 | Apart from these props, The `
` also accepts all props available in [react-native-modal](https://github.com/react-native-community/react-native-modal).
63 |
--------------------------------------------------------------------------------
/docs/src/pages/blog.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { graphql } from 'gatsby';
3 | import { Helmet } from 'react-helmet';
4 |
5 | import Layout from '../components/layout/Layout';
6 | import Header from '../components/layout/Header';
7 | import Seo from '../components/common/Seo';
8 | import BlogPostList from '../components/blogs/BlogPostList';
9 |
10 | const BlogPage = ({ data }) => {
11 | const blogs = data.allMarkdownRemark;
12 |
13 | const seo = {
14 | title: 'Blog',
15 | description:
16 | 'Magnus is the ultimate UI framework that helps you in building consistent user interfaces effortlessly in react native.',
17 | image: 'https://magnus-ui.com/images/hero.png',
18 | url: 'https://magnus-ui.com/blog',
19 | };
20 |
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
28 | Magnus Blog
29 |
30 |
31 |
32 | Read the latest news, tutorials, snippet and stories from the
33 | Magnus team
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | );
43 | };
44 |
45 | export const query = graphql`
46 | {
47 | allMarkdownRemark(filter: { fields: { type: { eq: "blogs" } } }) {
48 | edges {
49 | node {
50 | fields {
51 | slug
52 | }
53 | frontmatter {
54 | title
55 | featuredImg
56 | description
57 | }
58 | }
59 | }
60 | }
61 | }
62 | `;
63 |
64 | export default BlogPage;
65 |
--------------------------------------------------------------------------------
/src/ui/mention/mention.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createSpacingStyles,
6 | createBorderWidthStyles,
7 | createBorderColorStyles,
8 | createBorderRadiusStyles,
9 | createPositionStyle,
10 | getThemeColor,
11 | } from '../../theme/theme.service';
12 | import { MentionProps } from './mention.type';
13 |
14 | /**
15 | * computed style
16 | *
17 | * @param theme
18 | * @param props
19 | */
20 | export const getStyle = (theme: ThemeType, props: MentionProps) => {
21 | const computedStyle: any = {};
22 |
23 | computedStyle.list = {
24 | flex: 1,
25 | zIndex: 99,
26 | backgroundColor: getThemeColor(theme.colors, props.bg),
27 | ...createPositionStyle(props),
28 | ...createSpacingStyles(props, theme.spacing),
29 | ...createBorderWidthStyles(props),
30 | ...createBorderColorStyles(props, theme.colors),
31 | ...createBorderRadiusStyles(props, theme.borderRadius),
32 | };
33 |
34 | computedStyle.loading = {
35 | height: 60,
36 | marginTop: -60,
37 | zIndex: 99,
38 | alignItems: 'center',
39 | justifyContent: 'center',
40 | ...createSpacingStyles(props, theme.spacing),
41 | backgroundColor: getThemeColor(theme.colors, props.bg),
42 | ...createBorderWidthStyles(props),
43 | ...createBorderColorStyles(props, theme.colors),
44 | ...createBorderRadiusStyles(props, theme.borderRadius),
45 | flex: 1,
46 | };
47 |
48 | if (props.shadow) {
49 | computedStyle.list = {
50 | ...computedStyle.list,
51 | ...(theme.shadow && theme.shadow[props.shadow]),
52 | shadowColor: getThemeColor(theme.colors, props.shadowColor),
53 | };
54 | }
55 |
56 | // merging style props to computed style
57 | if (props.style) {
58 | computedStyle.container = {
59 | ...computedStyle.container,
60 | // @ts-ignore
61 | ...props.style,
62 | };
63 | }
64 |
65 | return StyleSheet.create(computedStyle);
66 | };
67 |
--------------------------------------------------------------------------------
/src/ui/badge/badge.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createShadowStyles,
6 | createSpacingStyles,
7 | createBorderWidthStyles,
8 | createBorderColorStyles,
9 | createBorderRadiusStyles,
10 | createPositionStyle,
11 | getThemeColor,
12 | } from '../../theme/theme.service';
13 | import { BadgeProps } from './badge.type';
14 |
15 | /**
16 | * computed style
17 | *
18 | * @param theme
19 | * @param props
20 | */
21 | export const getStyle = (
22 | theme: ThemeType,
23 | props: React.PropsWithChildren
24 | ) => {
25 | const computedStyle: any = {};
26 |
27 | computedStyle.container = {
28 | alignSelf: props.alignSelf,
29 | minHeight: typeof props.count === 'undefined' ? 10 : 30,
30 | minWidth: typeof props.count === 'undefined' ? 10 : 30,
31 | };
32 |
33 | computedStyle.div = {
34 | zIndex: 1,
35 | height: props.h,
36 | width: props.w,
37 | alignItems: 'center',
38 | justifyContent: 'center',
39 | alignSelf: 'flex-start',
40 | opacity: props.opacity,
41 | minHeight: typeof props.children === 'string' ? 30 : 10,
42 | backgroundColor: getThemeColor(theme.colors, props.bg),
43 | minWidth: typeof props.children === 'string' ? 30 : 10,
44 | ...createPositionStyle(props),
45 | ...createBorderWidthStyles(props),
46 | ...createShadowStyles(props, theme),
47 | ...createSpacingStyles(props, theme.spacing),
48 | ...createBorderColorStyles(props, theme.colors),
49 | ...createBorderRadiusStyles(props, theme.borderRadius),
50 | position: typeof props.children !== 'string' ? 'absolute' : props.position,
51 | };
52 |
53 | computedStyle.text = {
54 | paddingHorizontal: 10,
55 | };
56 |
57 | // merging style props to computed style
58 | if (props.style) {
59 | computedStyle.div = {
60 | ...computedStyle.div,
61 | // @ts-ignore
62 | ...props.style,
63 | };
64 | }
65 |
66 | return StyleSheet.create(computedStyle);
67 | };
68 |
--------------------------------------------------------------------------------
/src/ui/icon/icon.service.tsx:
--------------------------------------------------------------------------------
1 | import IconEntypo from 'react-native-vector-icons/Entypo';
2 | import IconZocial from 'react-native-vector-icons/Zocial';
3 | import IconFeather from 'react-native-vector-icons/Feather';
4 | import IconIonicons from 'react-native-vector-icons/Ionicons';
5 | import IconOcticons from 'react-native-vector-icons/Octicons';
6 | import IconAntDesign from 'react-native-vector-icons/AntDesign';
7 | import IconEvilIcons from 'react-native-vector-icons/EvilIcons';
8 | import IconFoundation from 'react-native-vector-icons/Foundation';
9 | import IconFontAwesome from 'react-native-vector-icons/FontAwesome';
10 | import IconFontAwesome5 from 'react-native-vector-icons/FontAwesome5';
11 | import IconMaterialIcons from 'react-native-vector-icons/MaterialIcons';
12 | import IconSimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons';
13 | import IconMaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
14 |
15 | import { iconFontFamilyType } from './icon.type';
16 |
17 | /**
18 | * get icon set
19 | */
20 | export const getIconSet = (fontFamily: iconFontFamilyType = 'FontAwesome') => {
21 | switch (fontFamily) {
22 | case 'AntDesign':
23 | return IconAntDesign;
24 | case 'Entypo':
25 | return IconEntypo;
26 | case 'EvilIcons':
27 | return IconEvilIcons;
28 | case 'Feather':
29 | return IconFeather;
30 | case 'FontAwesome':
31 | return IconFontAwesome;
32 | case 'FontAwesome5':
33 | return IconFontAwesome5;
34 | case 'Foundation':
35 | return IconFoundation;
36 | case 'Ionicons':
37 | return IconIonicons;
38 | case 'MaterialIcons':
39 | return IconMaterialIcons;
40 | case 'MaterialCommunityIcons':
41 | return IconMaterialCommunityIcons;
42 | case 'Zocial':
43 | return IconZocial;
44 | case 'SimpleLineIcons':
45 | return IconSimpleLineIcons;
46 | case 'Octicons':
47 | return IconOcticons;
48 | case 'Ionicons':
49 | return IconIonicons;
50 | default:
51 | return IconAntDesign;
52 | }
53 | };
54 |
--------------------------------------------------------------------------------
/example/src/components/Avatar.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ScrollView } from 'react-native';
3 | import { Avatar, Div, Icon } from 'react-native-magnus';
4 |
5 | import ExamplePage from '../utils/ExamplePage';
6 | import ExampleHeader from '../utils/ExampleHeader';
7 | import ExampleSection from '../utils/ExampleSection';
8 |
9 | const AvatarComponent = () => {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | A
19 |
20 |
21 |
22 | A
23 |
24 |
25 |
26 | A
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | A
50 |
51 |
52 | B
53 |
54 |
55 | C
56 |
57 |
58 |
59 |
60 |
61 | );
62 | };
63 |
64 | export default AvatarComponent;
65 |
--------------------------------------------------------------------------------
/src/ui/header/header.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Text } from '../text/text.component';
3 | import { getStyle } from './header.style';
4 | import { useTheme } from '../../theme';
5 | import { HeaderProps } from './header.type';
6 | import { getSpecificProps } from '../../utilities';
7 | import { textProps } from '../../types';
8 | import { useDefaultProps } from '../../utilities/useDefaultProps';
9 | import { Div } from '../div/div.component';
10 |
11 | const Header: React.FunctionComponent = (incomingProps) => {
12 | const props = useDefaultProps('Header', incomingProps, {
13 | minH: 70,
14 | p: 'lg',
15 | bg: 'white',
16 | rounded: 'none',
17 | flexDir: 'row',
18 | shadow: 'sm',
19 | shadowColor: 'gray900',
20 | position: 'relative',
21 | bgMode: 'cover',
22 | pointerEvents: 'auto',
23 | borderStyle: 'solid',
24 | alignItems: 'center',
25 | alignment: 'left',
26 | fontWeight: 'bold',
27 | fontSize: 'lg',
28 | textTransform: 'uppercase',
29 | });
30 |
31 | const { children, prefix, suffix, ...rest } = props;
32 |
33 | const { theme } = useTheme();
34 | const computedStyle = getStyle(theme, props);
35 |
36 | /**
37 | * renders children based on type
38 | */
39 | const renderChildren = () => {
40 | if (typeof children === 'string') {
41 | return (
42 |
46 | {children}
47 |
48 | );
49 | }
50 |
51 | return children;
52 | };
53 |
54 | const getPrefix = () => {
55 | if (props.alignment === 'center') {
56 | return prefix;
57 | }
58 | return prefix ??
;
59 | };
60 |
61 | return (
62 |
63 |
{getPrefix()}
64 |
{renderChildren()}
65 |
{suffix}
66 |
67 | );
68 | };
69 |
70 | export { Header };
71 |
--------------------------------------------------------------------------------
/src/ui/tag/tag.style.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { ThemeType } from '../../theme';
3 |
4 | import {
5 | createSpacingStyles,
6 | createBorderRadiusStyles,
7 | createBorderColorStyles,
8 | createBorderWidthStyles,
9 | getThemeColor,
10 | } from '../../theme/theme.service';
11 | import { TagProps } from './tag.type';
12 |
13 | /**
14 | * computed style
15 | *
16 | * @param theme
17 | * @param props
18 | */
19 | export const getStyle = (theme: ThemeType, props: TagProps) => {
20 | const computedStyle: any = {};
21 |
22 | computedStyle.div = {
23 | borderColor: getThemeColor(theme.colors, props.borderColor),
24 | borderWidth: props.borderWidth,
25 | justifyContent: 'center',
26 | alignItems: 'center',
27 | flexDirection: 'row',
28 | alignSelf: 'flex-start',
29 | backgroundColor: getThemeColor(theme.colors, props.bg),
30 | ...createBorderWidthStyles(props),
31 | ...createSpacingStyles(props, theme.spacing),
32 | ...createBorderColorStyles(props, theme.colors),
33 | ...createBorderRadiusStyles(props, theme.borderRadius),
34 | };
35 |
36 | computedStyle.prefix = {
37 | marginRight: 4,
38 | };
39 |
40 | computedStyle.suffix = {
41 | marginLeft: 4,
42 | };
43 |
44 | if (props.h) {
45 | computedStyle.div = {
46 | ...computedStyle.div,
47 | height: props.h,
48 | };
49 | }
50 |
51 | if (props.w) {
52 | computedStyle.div = {
53 | ...computedStyle.div,
54 | width: props.w,
55 | };
56 | }
57 |
58 | if (props.minH) {
59 | computedStyle.div = {
60 | ...computedStyle.div,
61 | minHeight: props.minH,
62 | };
63 | }
64 |
65 | if (props.minW) {
66 | computedStyle.div = {
67 | ...computedStyle.div,
68 | minWidth: props.minW,
69 | };
70 | }
71 |
72 | // merging style props to computed style
73 | if (props.style) {
74 | computedStyle.div = {
75 | ...computedStyle.div,
76 | // @ts-ignore
77 | ...props.style,
78 | };
79 | }
80 |
81 | return StyleSheet.create(computedStyle);
82 | };
83 |
--------------------------------------------------------------------------------
/docs/content/docs/collapse/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Collapse
3 | date: "2019-08-13"
4 | description: ""
5 | ---
6 |
7 | Custom component for rendering collapse panel.
8 |
9 |
10 |
11 |
12 | ```jsx
13 | import { Collapse } from "react-native-magnus";
14 |
15 |
16 | }
23 | >
24 | Header 1
25 |
26 |
27 |
28 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Minus nobis
29 | corporis ut, ex sed aperiam. Debitis, facere! Animi quis laudantium, odio
30 | nulla recusandae labore pariatur in, vitae corporis delectus repellendus.
31 |
32 |
33 | ;
34 | ```
35 |
36 |
37 |
38 | ## Props
39 |
40 | ### Collapse
41 |
42 | Collapse is basically a `Div` component. So it accepts all props of `Div` with the following extra props
43 |
44 | | Property | Description | Type | Default |
45 | | ------------- | ------------------------------------------------- | --------- | ------- |
46 | | defaultActive | shows the collapse as opened when true by default | `boolean` | `false` |
47 |
48 | ### Collapse.Header
49 |
50 | Collapse.Header is basically a `Button` component. So it accepts all props of `Button` with the following extra props
51 |
52 | | Property | Description | Type | Default |
53 | | ------------ | ------------------------------------------------------ | ----------- | ------- |
54 | | activeSuffix | Renders a component on the right of button when active | `ReactNode` | `-` |
55 | | activePrefix | Renders a component on the left of button when active | `ReactNode` | `-` |
56 |
57 | ### Collapse.Body
58 |
59 | CollapseHeader is basically a `Div` component. So it accepts all props of `Div`
60 |
--------------------------------------------------------------------------------
/src/ui/checkbox/checkbox.type.tsx:
--------------------------------------------------------------------------------
1 | import { PressableProps as RNButtonProps } from 'react-native';
2 | import {
3 | BackgroundPropsType,
4 | ButtonPropsType,
5 | DimensionPropsType,
6 | DisabledPropsType,
7 | FlexPropsType,
8 | LoadingPropsType,
9 | OpacityPropsType,
10 | PositionPropsType,
11 | PrefixSuffixPropsType,
12 | TextPropsType,
13 | ZIndexPropsType,
14 | BorderPropsType,
15 | SpacingPropsType,
16 | RoundedPropsType,
17 | ShadowPropsType,
18 | VariantPropsType,
19 | } from '../../types';
20 | import { DivProps } from '../div/div.type';
21 | import { CheckboxGroup } from './group.component';
22 |
23 | export type CompundedCheckbox = React.FunctionComponent
& {
24 | Group: typeof CheckboxGroup;
25 | };
26 |
27 | export interface CheckboxProps
28 | extends Omit,
29 | BorderPropsType,
30 | SpacingPropsType,
31 | ShadowPropsType,
32 | RoundedPropsType,
33 | DimensionPropsType,
34 | PositionPropsType,
35 | FlexPropsType,
36 | LoadingPropsType,
37 | PrefixSuffixPropsType,
38 | OpacityPropsType,
39 | ZIndexPropsType,
40 | DisabledPropsType,
41 | Pick,
42 | Pick,
43 | ButtonPropsType,
44 | VariantPropsType {
45 | highlightBg?: string;
46 | activeColor?: string;
47 | inactiveColor?: string;
48 | defaultChecked?: boolean;
49 | activeIcon?: string | React.ReactNode;
50 | inactiveIcon?: string | React.ReactNode;
51 | checked?: boolean;
52 | onChecked?: (newValue: boolean) => void;
53 | onChange?: (value: any) => void;
54 | value?: any;
55 | children?: ((states: CheckboxStates) => React.ReactNode) | React.ReactNode;
56 | }
57 |
58 | export interface CheckboxGroupProps extends DivProps {
59 | onChange?: (value: any[]) => void;
60 | value?: any[];
61 | defaultValue?: any[];
62 | children: React.ReactElement[] | React.ReactElement;
63 | }
64 |
65 | export interface CheckboxStates {
66 | focussed?: boolean;
67 | checked?: boolean;
68 | disabled?: boolean;
69 | loading?: boolean;
70 | }
71 |
--------------------------------------------------------------------------------
/docs/src/components/layout/Sidebar.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 |
3 | import { Link } from 'gatsby';
4 | import { menu } from '../../constants/sidebar';
5 | import Logo from '../common/Logo';
6 | import SidebarFilter from '../common/SidebarFilter';
7 |
8 | export default function Sidebar({ active, close }) {
9 | const [filteredMenu, setFilteredMenu] = useState(menu);
10 |
11 | /**
12 | * filter menu by text
13 | */
14 | const filterMenu = (e) => {
15 | const value = e.target.value;
16 | const filteredMenu = [];
17 |
18 | menu.forEach((menuitem) => {
19 | const filterdLinks = menuitem.links.filter((link) => {
20 | return link.text.toLowerCase().indexOf(value.toLowerCase()) > -1;
21 | });
22 |
23 | if (filterdLinks.length > 0) {
24 | filteredMenu.push({
25 | ...menuitem,
26 | links: filterdLinks,
27 | });
28 | }
29 | });
30 |
31 | setFilteredMenu(filteredMenu);
32 | };
33 |
34 | return (
35 |
44 |
45 | {filteredMenu.map((menuitem) => (
46 |
47 | {menuitem.text && (
48 |
52 | {menuitem.text}
53 |
54 | )}
55 |
56 | {menuitem.links.map((link) => (
57 |
63 | {link.text}
64 |
65 | ))}
66 |
67 |
68 | ))}
69 |
70 | );
71 | }
72 |
--------------------------------------------------------------------------------
/docs/content/docs/spacing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Spacing
3 | date: '2019-08-13'
4 | description: ''
5 | ---
6 |
7 | Magnus provides consistent spacing for margins and padding so that you can build applications quickly. You can also easily directional
8 |
9 | | Size | Value |
10 | | ---- | ----- |
11 | | none | 0 |
12 | | xs | 4 |
13 | | sm | 6 |
14 | | md | 8 |
15 | | lg | 12 |
16 | | xl | 24 |
17 | | 2xl | 32 |
18 | | 3xl | 64 |
19 | | -xs | -4 |
20 | | -sm | -6 |
21 | | -md | -8 |
22 | | -lg | -12 |
23 | | -xl | -24 |
24 | | -2xl | -32 |
25 | | -3xl | -64 |
26 |
27 | See it on Snack
28 |
29 |
30 |
31 | ### Examples
32 |
33 | ```jsx
34 | // Padding ( p = padding in all directions )
35 |
36 |
37 | // Padding Directional
38 | // px = horizontal padding, py = vertical padding
39 |
40 |
41 | // pt = padding top, pb = padding bottom
42 | // pl = padding left pr = padding right
43 |
44 |
45 | // Margin ( ( m = margin in all directions ))
46 |
47 |
48 | // Margin Directional
49 | // mt = margin top, mb = margin bottom
50 | // ml = margin left, mr = margin right
51 |
52 |
53 | ```
54 |
55 | You can also pass values as number if you want to use any arbitary values. But we still recommended you to use pre-defined theme values to maintain consistency.
56 |
57 | ```jsx
58 |
59 | ```
60 |
61 | ### Customizations
62 |
63 | You can add custom spacing also.
64 |
65 | ```jsx
66 | import React from 'react';
67 | import { AppRegistry } from 'react-native';
68 | import { ThemeProvider, Text } from 'react-native-magnus';
69 | import App from './src/App';
70 |
71 | const theme = {
72 | spacing: {
73 | xs: 2
74 | '4xl': 64
75 | }
76 | }
77 |
78 | export default function Main() {
79 | return (
80 |
81 |
82 |
83 |
84 | );
85 | }
86 | ```
87 |
--------------------------------------------------------------------------------