Skip to content
Vy logo
Guidesβ€‹β€‹β€‹β€‹β€Œο»Ώβ€ο»Ώβ€‹β€β€‹β€β€Œβ€ο»Ώο»Ώβ€Œο»Ώβ€‹β€β€Œβ€β€β€Œβ€Œβ€β€Œο»Ώβ€Œβ€β€β€Œβ€Œβ€ο»Ώβ€β€‹β€β€‹β€β€‹ο»Ώβ€β€β€‹β€β€‹β€β€Œο»Ώβ€‹ο»Ώβ€Œβ€β€‹β€Œβ€Œβ€ο»Ώβ€β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€β€Œβ€‹β€ο»Ώβ€β€Œβ€β€β€Œβ€Œβ€ο»Ώο»Ώβ€‹β€β€‹β€β€‹β€ο»Ώβ€‹β€‹β€β€‹β€β€Œβ€β€β€‹β€Œο»Ώβ€‹β€β€Œβ€β€Œβ€Œβ€Œβ€β€Œβ€β€‹β€β€‹β€β€‹ο»Ώβ€β€β€‹β€β€‹β€β€Œβ€β€β€‹β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€‹β€‹β€‹ο»Ώβ€β€β€‹β€ο»Ώο»Ώβ€‹β€ο»Ώο»Ώβ€Œβ€ο»Ώβ€‹β€Œβ€ο»Ώο»Ώβ€Œβ€β€‹ο»Ώβ€Œβ€β€‹β€Œβ€Œβ€ο»Ώβ€‹β€Œβ€β€β€‹β€Œβ€ο»Ώο»Ώβ€Œο»Ώβ€‹ο»Ώβ€Œο»Ώβ€Œβ€‹β€‹ο»Ώβ€β€β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹β€ο»Ώο»Ώβ€Œβ€β€β€Œβ€Œβ€ο»Ώβ€β€Œο»Ώβ€Œβ€‹β€Œβ€β€Œβ€Œβ€Œβ€ο»Ώβ€β€Œο»Ώβ€Œβ€‹β€‹β€ο»Ώο»Ώβ€Œβ€β€Œβ€Œβ€Œβ€β€Œβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€‹β€‹β€ο»Ώο»Ώβ€Œβ€ο»Ώβ€Œβ€Œβ€ο»Ώο»Ώβ€Œβ€β€Œβ€‹β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώβ€Œβ€Œο»Ώβ€‹β€‹β€Œο»Ώβ€‹β€β€Œβ€β€Œβ€Œβ€Œο»Ώβ€‹ο»Ώβ€Œβ€β€Œβ€Œβ€Œβ€ο»Ώβ€β€Œο»Ώβ€Œβ€‹β€Œβ€β€‹β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œβ€ο»Ώο»Ώβ€Œβ€ο»Ώβ€β€‹ο»Ώβ€ο»Ώβ€Œβ€β€β€Œβ€Œβ€β€Œβ€‹β€‹ο»Ώο»Ώβ€Œβ€‹ο»Ώβ€β€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€Œβ€β€‹β€β€Œβ€β€Œβ€‹β€Œβ€β€‹β€Œβ€‹ο»Ώβ€‹ο»Ώβ€Œβ€β€‹ο»Ώβ€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€Œβ€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€β€‹β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€Œβ€‹β€Œβ€β€Œβ€Œβ€Œβ€β€‹β€Œβ€‹ο»Ώβ€Œβ€‹β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€β€Œβ€‹ο»Ώβ€‹β€β€‹ο»Ώβ€β€Œβ€Œβ€β€‹β€β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€‹β€‹β€‹ο»Ώβ€‹ο»Ώβ€‹ο»Ώβ€‹ο»Ώβ€‹ο»Ώβ€β€‹β€‹ο»Ώβ€Œο»Ώβ€Œβ€β€‹β€Œβ€Œβ€β€‹ο»Ώβ€‹ο»Ώβ€‹β€β€‹ο»Ώβ€Œο»Ώβ€‹ο»Ώβ€Œβ€β€‹ο»Ώβ€β€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€ο»Ώβ€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€β€Œβ€Œο»Ώβ€‹β€‹β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώβ€Œβ€Œβ€β€‹ο»Ώβ€Œβ€β€‹β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€Œβ€Œβ€Œβ€β€Œο»Ώβ€Œβ€ο»Ώο»Ώβ€Œο»Ώβ€‹β€β€Œο»Ώβ€β€Œβ€‹ο»Ώβ€ο»Ώβ€Œο»Ώβ€‹β€‹β€Œβ€β€‹β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€‹β€‹ο»Ώο»Ώβ€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€ο»Ώβ€‹β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώο»Ώβ€Œβ€β€‹β€β€Œβ€β€‹β€Œβ€Œο»Ώβ€‹ο»Ώβ€Œβ€β€Œβ€Œβ€Œβ€Œβ€Œβ€Œβ€Œο»Ώβ€‹β€β€Œβ€ο»Ώβ€‹β€‹ο»Ώο»Ώβ€Œβ€Œβ€β€β€‹β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€‹β€‹β€‹β€β€Œβ€Œβ€‹ο»Ώβ€‹ο»Ώβ€Œβ€‹β€‹β€Œβ€‹β€β€Œβ€Œβ€‹ο»Ώβ€‹β€β€Œβ€‹β€Œβ€β€‹β€β€Œβ€Œβ€‹ο»Ώβ€‹β€β€Œβ€‹β€Œβ€β€Œβ€ο»Ώβ€‹β€Œβ€ο»Ώο»Ώβ€Œβ€β€‹ο»Ώβ€Œβ€β€‹β€Œβ€Œβ€ο»Ώβ€‹β€Œβ€β€β€‹β€Œβ€ο»Ώο»Ώβ€Œο»Ώβ€‹ο»Ώβ€Œο»Ώβ€Œβ€‹β€‹β€β€Œβ€Œβ€‹ο»Ώβ€‹ο»Ώβ€Œβ€‹β€‹β€Œβ€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹β€β€Œβ€β€Œβ€β€β€Œβ€Œβ€β€Œβ€‹β€‹ο»Ώο»Ώβ€Œβ€‹ο»Ώβ€β€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€Œβ€β€‹β€β€Œβ€β€Œβ€‹β€Œβ€β€‹β€Œβ€‹ο»Ώβ€‹ο»Ώβ€Œβ€β€‹ο»Ώβ€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€Œβ€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€β€‹β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€Œβ€‹β€Œβ€β€Œβ€Œβ€Œβ€β€‹β€Œβ€‹ο»Ώβ€Œβ€‹β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€β€Œβ€‹ο»Ώβ€‹β€β€‹ο»Ώβ€β€Œβ€Œβ€β€‹β€β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€‹β€‹β€‹ο»Ώβ€‹ο»Ώβ€‹ο»Ώβ€‹ο»Ώβ€‹ο»Ώβ€β€‹β€‹ο»Ώβ€Œο»Ώβ€Œβ€β€‹β€Œβ€Œβ€β€‹ο»Ώβ€‹ο»Ώβ€‹β€β€‹ο»Ώβ€Œο»Ώβ€‹ο»Ώβ€Œβ€β€‹ο»Ώβ€β€‹β€‹ο»Ώβ€Œβ€‹β€‹β€β€Œβ€β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€β€Œβ€Œο»Ώβ€‹β€‹β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώβ€Œβ€Œβ€β€‹ο»Ώβ€Œβ€β€‹β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€Œβ€Œβ€Œβ€β€Œο»Ώβ€Œβ€ο»Ώο»Ώβ€Œο»Ώβ€‹β€β€Œο»Ώβ€β€Œβ€‹β€β€Œβ€β€Œο»Ώβ€‹β€‹β€Œβ€β€‹β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€‹β€‹ο»Ώο»Ώβ€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€ο»Ώβ€‹β€Œβ€β€Œβ€Œβ€‹β€β€Œβ€β€Œο»Ώβ€‹β€‹β€Œβ€β€Œβ€Œβ€Œο»Ώβ€‹β€β€Œο»Ώβ€‹ο»Ώβ€Œο»Ώβ€‹β€‹β€Œβ€β€Œβ€Œβ€Œβ€β€‹ο»Ώβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώβ€Œβ€Œο»Ώβ€‹β€‹β€Œο»Ώβ€Œβ€Œβ€Œβ€β€‹β€β€Œβ€ο»Ώβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€‹ο»Ώβ€Œβ€β€β€‹β€Œβ€β€Œβ€Œβ€Œβ€β€Œβ€‹β€‹β€β€‹β€β€Œο»Ώο»Ώβ€Œ

πŸ“± How to Create New React Native Componentsβ€‹β€‹β€‹β€‹β€Œο»Ώβ€ο»Ώβ€‹β€β€‹β€β€Œβ€ο»Ώο»Ώβ€Œο»Ώβ€‹β€β€Œβ€β€β€Œβ€Œβ€β€Œο»Ώβ€Œβ€β€β€Œβ€Œβ€ο»Ώβ€β€‹β€β€‹β€β€‹ο»Ώβ€β€β€‹β€β€‹β€β€Œο»Ώβ€‹ο»Ώβ€Œβ€β€‹β€Œβ€Œβ€ο»Ώβ€β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€β€Œβ€‹β€ο»Ώβ€β€Œβ€β€β€Œβ€Œβ€ο»Ώο»Ώβ€‹β€β€‹β€β€‹β€ο»Ώβ€‹β€‹β€β€‹β€β€Œβ€β€β€‹β€Œο»Ώβ€‹β€β€Œβ€β€Œβ€Œβ€Œβ€β€Œβ€β€‹β€β€‹β€β€‹ο»Ώβ€β€β€‹β€β€‹β€β€Œβ€β€β€‹β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€‹β€‹β€‹ο»Ώβ€β€β€‹β€ο»Ώο»Ώβ€‹β€ο»Ώο»Ώβ€Œβ€ο»Ώβ€‹β€Œβ€ο»Ώο»Ώβ€Œβ€β€‹ο»Ώβ€Œβ€β€‹β€Œβ€Œβ€ο»Ώβ€‹β€Œβ€β€β€‹β€Œβ€ο»Ώο»Ώβ€Œο»Ώβ€‹ο»Ώβ€Œο»Ώβ€Œβ€‹β€‹ο»Ώβ€β€β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹β€ο»Ώο»Ώβ€Œβ€β€β€Œβ€Œβ€ο»Ώβ€β€Œο»Ώβ€Œβ€‹β€Œβ€β€Œβ€Œβ€Œβ€ο»Ώβ€β€Œο»Ώβ€Œβ€‹β€‹β€ο»Ώο»Ώβ€Œβ€β€Œβ€Œβ€Œβ€β€Œβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€‹β€‹β€ο»Ώο»Ώβ€Œβ€ο»Ώβ€Œβ€Œβ€ο»Ώο»Ώβ€Œβ€β€Œβ€‹β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώβ€Œβ€Œο»Ώβ€‹β€‹β€Œο»Ώβ€‹β€β€Œβ€β€Œβ€Œβ€Œο»Ώβ€‹ο»Ώβ€Œβ€β€Œβ€Œβ€Œβ€ο»Ώβ€β€Œο»Ώβ€Œβ€‹β€Œβ€β€‹β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œβ€ο»Ώο»Ώβ€Œβ€ο»Ώβ€β€‹ο»Ώβ€ο»Ώβ€Œβ€β€β€Œβ€Œβ€β€Œβ€‹β€‹ο»Ώο»Ώβ€Œβ€Œβ€β€‹β€Œβ€Œβ€β€Œβ€β€‹ο»Ώβ€β€Œβ€‹ο»Ώβ€‹β€Œβ€‹ο»Ώβ€‹β€‹β€Œβ€β€‹ο»Ώβ€‹ο»Ώβ€‹ο»Ώβ€Œβ€β€‹ο»Ώβ€‹β€ο»Ώβ€Œβ€Œβ€β€Œβ€‹β€Œβ€β€Œβ€‹β€Œβ€β€Œβ€‹β€‹ο»Ώβ€Œβ€β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€Œβ€‹β€Œβ€β€‹β€β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€‹β€‹β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€β€‹β€Œβ€β€‹β€β€‹ο»Ώβ€Œο»Ώβ€‹ο»Ώβ€‹β€‹β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€β€‹β€‹ο»Ώβ€Œβ€β€‹ο»Ώβ€Œβ€Œβ€Œβ€β€Œβ€‹β€Œβ€β€Œβ€‹β€Œβ€β€Œβ€Œβ€Œβ€β€‹ο»Ώβ€‹ο»Ώβ€Œο»Ώβ€‹ο»Ώβ€‹β€β€‹ο»Ώβ€Œο»Ώβ€Œβ€β€Œβ€Œβ€‹ο»Ώβ€ο»Ώβ€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€β€Œβ€Œο»Ώβ€‹β€‹β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώβ€Œβ€Œβ€β€‹β€Œβ€Œο»Ώβ€‹β€β€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œβ€β€‹ο»Ώβ€Œβ€ο»Ώβ€‹β€Œβ€β€Œβ€Œβ€‹ο»Ώβ€ο»Ώβ€Œο»Ώβ€‹β€‹β€Œβ€β€‹β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€‹β€‹ο»Ώο»Ώβ€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€ο»Ώβ€‹β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώο»Ώβ€Œβ€β€‹β€β€Œβ€β€‹β€Œβ€Œο»Ώβ€‹ο»Ώβ€Œβ€β€Œβ€Œβ€Œβ€Œβ€Œβ€Œβ€Œο»Ώβ€‹β€β€Œβ€ο»Ώβ€‹β€‹ο»Ώο»Ώβ€Œβ€Œβ€β€β€‹β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€‹β€‹β€‹β€β€Œβ€Œβ€‹ο»Ώβ€‹ο»Ώβ€Œβ€‹β€‹β€Œβ€‹β€β€Œβ€Œβ€‹ο»Ώβ€‹β€β€Œβ€‹β€Œβ€β€‹β€β€Œβ€Œβ€‹ο»Ώβ€‹β€β€Œβ€‹β€Œβ€β€Œβ€ο»Ώβ€‹β€Œβ€ο»Ώο»Ώβ€Œβ€β€‹ο»Ώβ€Œβ€β€‹β€Œβ€Œβ€ο»Ώβ€‹β€Œβ€β€β€‹β€Œβ€ο»Ώο»Ώβ€Œο»Ώβ€‹ο»Ώβ€Œο»Ώβ€Œβ€‹β€‹β€β€Œβ€Œβ€‹ο»Ώβ€‹ο»Ώβ€Œβ€‹β€‹β€Œβ€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€Œβ€‹β€‹β€β€Œβ€β€Œβ€β€β€Œβ€Œβ€β€Œβ€‹β€‹ο»Ώο»Ώβ€Œβ€Œβ€β€‹β€Œβ€Œβ€β€Œβ€β€‹ο»Ώβ€β€Œβ€‹ο»Ώβ€‹β€Œβ€‹ο»Ώβ€‹β€‹β€Œβ€β€‹ο»Ώβ€‹ο»Ώβ€‹ο»Ώβ€Œβ€β€‹ο»Ώβ€‹β€ο»Ώβ€Œβ€Œβ€β€Œβ€‹β€Œβ€β€Œβ€‹β€Œβ€β€Œβ€‹β€‹ο»Ώβ€Œβ€β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€Œβ€‹β€Œβ€β€‹β€β€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€‹β€‹β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€β€‹β€Œβ€β€‹β€β€‹ο»Ώβ€Œο»Ώβ€‹ο»Ώβ€‹β€‹β€‹β€ο»Ώβ€Œβ€‹ο»Ώβ€Œβ€‹β€‹ο»Ώβ€β€‹β€‹ο»Ώβ€Œβ€β€‹ο»Ώβ€Œβ€Œβ€Œβ€β€Œβ€‹β€Œβ€β€Œβ€‹β€Œβ€β€Œβ€Œβ€Œβ€β€‹ο»Ώβ€‹ο»Ώβ€Œο»Ώβ€‹ο»Ώβ€‹β€β€‹ο»Ώβ€Œο»Ώβ€Œβ€β€Œβ€Œβ€‹β€β€Œβ€β€Œο»Ώβ€Œβ€‹β€Œο»Ώβ€β€Œβ€Œο»Ώβ€‹β€‹β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώβ€Œβ€Œβ€β€‹β€Œβ€Œο»Ώβ€‹β€β€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œβ€β€‹ο»Ώβ€Œβ€ο»Ώβ€‹β€Œβ€β€Œβ€Œβ€‹β€β€Œβ€β€Œο»Ώβ€‹β€‹β€Œβ€β€‹β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€‹β€‹ο»Ώο»Ώβ€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€‹β€Œβ€ο»Ώβ€‹β€Œβ€β€Œβ€Œβ€‹β€β€Œβ€β€Œο»Ώβ€‹β€‹β€Œβ€β€Œβ€Œβ€Œο»Ώβ€‹β€β€Œο»Ώβ€‹ο»Ώβ€Œο»Ώβ€‹β€‹β€Œβ€β€Œβ€Œβ€Œβ€β€‹ο»Ώβ€Œο»Ώβ€Œβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€Œβ€β€Œβ€β€Œβ€Œβ€‹ο»Ώο»Ώβ€Œβ€Œο»Ώβ€‹β€‹β€Œο»Ώβ€Œβ€Œβ€Œβ€β€‹β€β€Œβ€ο»Ώβ€‹β€Œβ€β€β€Œβ€Œο»Ώβ€‹ο»Ώβ€Œβ€β€β€‹β€Œβ€β€Œβ€Œβ€Œβ€β€Œβ€‹β€‹β€β€‹β€β€Œο»Ώο»Ώβ€Œ

Spor also has a React Native implementation! This guide walks you through how to contribute to the codebase and build new React Native components for Spor.

If you're planning to create a new React Native component for Spor, you’re in the right place. This guide covers where to put your code, naming conventions, structure, and best practices.

πŸ› Principles

Most of the React Native components in Spor should already exist in the React version. The React implementation serves as a reference, so you don’t need to invent names, abstraction levels, or prop structures from scratch.

  • Same component names and props should be used across web and mobile.
  • If the component does not exist in React, check with the Spor team or Team Kanaler before you start building.

πŸ”€ Naming Conventions

We follow three key naming conventions:

  • variant – Defines different visual styles unrelated to color (e.g., solid, outline, primary, secondary, ghost).
  • colorScheme – Defines color-related variations (e.g., teal, orange, light, dark).
  • size – Defines size variations. Always use t-shirt sizing (sm, md, lg, xl, 2xl). If only two sizes exist, use sm and lg.

πŸ“‚ Folder Structure & Code Organization

All Spor-related code lives in app/spor/ inside the salgsapp-react-native repository.

πŸ“Œ Steps to Create a New Component

1️⃣ Create a new folder inside app/spor/ that groups related components (e.g., button, card, layout).

  • Always use singular names (button, not buttons).

2️⃣ Inside that folder, create an index.tsx file to export the component.

  • Then, export this new index.tsx file in app/spor/index.tsx so others can import your component like this:
import { Button } from "app/spor";

πŸ— Component Structure

A component should be as simple as possible. If it becomes too complex, break it into smaller subcomponents that can be composed together.

For example, a Modal component might be split into:

  • Modal
  • ModalOverlay
  • ModalContent
  • ModalHeader
  • ModalBody
  • ModalFooter

You could then create a SimpleModal that works for most cases, while still allowing developers to use the parts individually for more flexibility.

πŸ“ Spacing Props

All components should support spacing props (e.g., margin, sometimes padding).

πŸ“Œ Use SpacingProps from app/spor:

type ExampleComponentProps = SpacingProps & { children: React.ReactNode };
export const ExampleComponent = (props: ExampleComponentProps) => {
return <Box {...props}> {/* Your component code here */} </Box>;
};

πŸ”Ή These spacing props should typically be spread onto the outermost <Box /> (imported from app/spor).

🎨 Styling with Restyle

We use a customized styling system based on Restyle.

1️⃣ Create a theme.tsx file inside the component folder. 2️⃣ Use our style helpers to define styles.

Here’s a complete example:

// Component structure (e.g., outer container + text component)
type Structure = {
container: BoxStyle;
text: TextStyle;
};
// Component props (e.g., variants and sizes)
type Args = {
variant: "solid" | "outline";
size: "sm" | "md" | "lg";
};
const { createGetStyles, createStyleConfig } = createStyleHelpers<Structure, Args>();
// Base styles
const baseStyles = createStyleConfig(() => ({
container: { backgroundColor: "darkTeal" },
text: { color: "white" },
}));
// Variant styles
const variantStyles = createStyleConfig(({ variant }) => {
switch (variant) {
case "outline":
return { container: { borderWidth: 1, borderColor: "primaryGreen", borderStyle: "solid" } };
default:
return {};
}
});
// Combine styles
export const getStyles = createGetStyles(baseStyles, variantStyles);

πŸ–Œ Applying Styles in a Component

const ExampleComponent = ({ children, variant, size }: ExampleComponentProps) => {
const styles = getStyles({ variant, size });
return (
<Box {...styles.container}>
<Text {...styles.text}>{children}</Text>
</Box>
);
};

πŸ”Ή If you need to extract individual styles, use useRestyleStyle:

const AnotherExampleComponent = () => {
const styles = getStyles();
const iconStyles = useRestyleStyle(styles.icon);
return <Svg style={iconStyles}>...</Svg>;
};

πŸš€ Exporting Your Component

πŸ“Œ Use named exports onlyβ€”no default exports.

Example:

export { Button } from "./button";

πŸ”§ Useful Utilities

Check out app/spor/utils/ before writing new utility functionsβ€”many helpful hooks and helpers already exist!

❓ Questions? Feedback?

This guide is a starting point for building React Native components in Spor. If you see areas for improvement, feel free to contribute! No suggestion is too small. πŸš€