Tokamak/tokamak.dev/StandardComponents.md

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:

  1. Manual frame-based layout. You can pass precomputed layout information as frame argument to Style 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.

  1. 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.