6.8 KiB
Standard View Components
Tokamak Component | Rendered on iOS as | Rendered on macOS as |
---|---|---|
Button |
UIButton |
NSButton |
CollectionView |
UICollectionView |
not available yet |
DatePicker |
UIDatePicker |
not available yet |
ImageView |
UIImageView |
not available yet |
Label |
UILabel |
NSTextView |
ListView |
UITableView |
not available yet |
ScrollView |
UIScrollView |
not available yet |
SegmentedControl |
UISegmentedControl |
not available yet |
Slider |
UISlider |
not available yet |
StackView |
UIStackView |
not available yet |
Stepper |
UIStepper |
not available yet |
Switch |
UISwitch |
not available yet |
TextField |
UITextField |
not available yet |
View |
UIView |
NSView |
Standard Presenter Components
Tokamak Component | Rendered on iOS as |
---|---|
ModalPresenter |
UIViewController with modal presentation |
NavigationPresenter |
UINavigationController |
TabPresenter |
UITabBarController |
Style
All of the standard view components get an optional argument Style
passed to their props (except the StackView
, which only affects layout, but
can't be styled). It
bundles all of the common styling configuration that can be applied to view
components, but is abstract from a specific renderer implementation. Thus, even
if you render to UIKit
you can use platform-independent layout structs such as
Point
, Size
,
Rectangle
and
Insets
,
as well as other styling configuration. For example
Color
is mapped to
UIColor
for
UIKit
, and when AppKitRenderer
is available would be mapped to
NSColor
.
Layout
Tokamak currently supports multiple layout approaches:
- Manual frame-based layout. You can pass precomputed layout information as
frame
argument toStyle
initializer, e.g.:
Label.node(.init(
Style(
Rectangle(
Point.zero,
Size(width: 200, height: 100)
)
)
), "label")
The downside of this approach is that you have to precompute all of the layout information yourself. It also has to be manually recomputed and updated when layout environment changes on device rotation or when the root window is resized. On the other hand, you're free to attach whatever layout engine you'd like to this API. One example could be flexbox support implemented with Yoga.
- Auto layout: a DSL for location and size constraints with values that can
be passed to
Style
initializer:
Label.node(.init(
Style([
Size.equal(to: Size(width: 200, height: 100),
Top.equal(to: .parent),
Leading.equal(to: .parent)
]
), "label")
UIKitRenderer
maps this DSL directly to native auto layout constraints and
reconciles any updates with existing constraints created during previous
renders. This allows UI to stay responsive to any dynamic changes and also has
native support for RTL scripts
with Leading
and Trailing
constraints.