Keg Components
- Base UI Components for the Keg Core and Tap extensions
Add to your project
yarn add @keg-hub/keg-components
npm install @keg-hub/keg-components
Developer setup
git clone https://github.com/keg-hub/keg-hub.git ~/keg-hub
cd ~/keg-hub/repos/keg-components
yarn install
-
yarn sb
- local storybook -
yarn sb:native
- native local storybook -
yarn sb:web
- web local storybook -
yarn format
- formats your code based on the config set inconfigs/eslint.config.js
&&configs/prettier.config.js
-
yarn eslint:watch
- watches any code change for any lint errors
Theming
Keg Components leverages re-theme for dynamic theming across platforms and viewport sizes
Theme objects
- For new components, create and export your theme objects in
src/theme/components
Using themes in components
-
Use the
useThemePath
hook:import { useThemePath } from '../../hooks' const FooBar = (props) => { // theme from `src/theme/components/fooBar.js` const fooBarTheme = useThemePath('fooBar') return ( <View style={fooBarTheme.main}> ... </View> ) }
Conventions
Folder structure:
- if you are creating a function that has a different implementation for
native
-
DO
- place them in a folder with the same name as the export
- add an alias for them in the
/configs/aliases.json
file - add a
index.js
exporting the alias
/src/components /linearGradient linearGradient.js linearGradient.native.js index.js // /configs/aliases.json { ...other aliases, "KegLinearGradient": "src/components/linearGradient/linearGradient${platform}.js", } // /src/components/linearGradient/index.js export * from 'KegLinearGradient'
-
DO
Every component implemented in keg-components that has a theme should define main
and content
styles:
/* src/theme/components/sampleButton.js */
export const sampleButton = {
main: { ... },
content: { ... }
}
- main: the root styles of the component
- content: the styles for content in the component
- Example: a simple Button component's
main
style would theme its root View component, whereas thecontent
style themes its inner Text component:/* src/components/button/sampleButton.js */ export const SampleButton = (props) => { const buttonTheme = useThemePath('sampleButton', props.style) return ( <View style={buttonTheme.main}> <Text style={buttonTheme.content}> { props.text } </Text> </View> ) }
Components sometimes import/consume other keg-components and then need to style those imported components within their styling context. These styles should be defined in the consumer's theme object
- Example: a button with an icon
/* src/theme/components/iconButton.js */
export const iconButton= {
main: { ... },
content: { ... },
icon: {
main: { ... },
content: { ... }
}
}
Use size keys (e.g. $small, $medium, etc.) and platform keys (e.g. $native, $web, $all, etc.) to wrap style properties only. This ensures that the shape of the theme object remains constant across all platforms and viewport sizes.
- DON'T do this:
export const button = {
$web: {
main: {
backgroundColor: 'coral'
},
},
$native: {
main: {
backgroundColor: 'green'
},
content: {
margin: 15
}
}
}
- DO this:
export const button = {
main: {
$native: {
backgroundColor: 'green'
},
$web: {
backgroundColor: 'coral'
}
},
content: {
$native: {
margin: 15
}
}
}
- In the first case, the theme object would not have the
content
styles on the$web
platform, making it inconsistent with$native
Icons
- TODO - add info on adding SVG's
Accessibility
- Mapping of accessibilityRole prop value to Web Element
- Example =>
<Link accessibilityRole='link'>
=><a role='link'>
article: 'article',
banner: 'header',
complementary: 'aside',
contentinfo: 'footer',
form: 'form',
link: 'a',
list: 'ul',
listitem: 'li',
main: 'main',
navigation: 'nav',
region: 'section',
adjustable: 'slider',
button: 'button',
// Heading mapping leverages the `aria-level` prop to determine the heading element
// Example <Text accessibilityRole='header' aria-level='1' > => <h1>
header: 'heading',
image: 'img',
link: 'link',
none: 'presentation',
search: 'search',
summary: 'region',
Create Element
- This library exports a
createElement
method - This method allows create custom native elements per platform, for needs such as:
- Defining
className
when on a web platform - Overwriting the
Text
component, but still taking advantage of theaccessability
props - TODO: Give more examples
- Defining