abstract class UI::View

Overview

Abstract base class for all UI views.

Crystal prohibits recursive structs, so View must be a class. VStack/HStack/ZStack children arrays contain View references, creating a recursive type relationship.

Direct Known Subclasses

Defined in:

ui/view.cr

Instance Method Summary

Instance Method Detail

abstract def accept(visitor : PlatformVisitor) #

Accept a platform visitor for rendering dispatch. Each concrete view type calls visitor.visit(self).


[View source]
def accessibility_label : String | Nil #

Accessibility label read by screen readers


[View source]
def accessibility_label=(accessibility_label : String | Nil) #

Accessibility label read by screen readers


[View source]
def background : Color | Nil #

Background color, nil means transparent/inherited


[View source]
def background=(background : Color | Nil) #

Background color, nil means transparent/inherited


[View source]
def blur_radius : Float64 #

Blur modifier


[View source]
def blur_radius=(blur_radius : Float64) #

Blur modifier


[View source]
def border_color : Color | Nil #

[View source]
def border_color=(border_color : Color | Nil) #

[View source]
def border_width : Float64 #

Border modifier


[View source]
def border_width=(border_width : Float64) #

Border modifier


[View source]
def clip_to_bounds : Bool #

[View source]
def clip_to_bounds=(clip_to_bounds : Bool) #

[View source]
def container_query(name : String) : self #

Chainable setter: mark this view as a container-query root. Renderers that support container queries emit container-type: inline-size and container-name: <name> on this element so descendant rules of the form @container <name> (min-width: ...) resolve against this box.


[View source]
def container_query_name : String | Nil #

Container query name. When set, the web renderer emits container-type: inline-size; container-name: <name> on the element so nested @container <name> (...) blocks resolve against this view's box rather than the viewport.


[View source]
def container_query_name=(container_query_name : String | Nil) #

Container query name. When set, the web renderer emits container-type: inline-size; container-name: <name> on the element so nested @container <name> (...) blocks resolve against this view's box rather than the viewport.


[View source]
def corner_radius : Float64 #

Shape modifiers


[View source]
def corner_radius=(corner_radius : Float64) #

Shape modifiers


[View source]
def fill_screen! : self #

Chainable shortcut for self.root_fill = true. Returns self.


[View source]
def fluid_height(min : String | Number, ideal : String | Number, max : String | Number) : self #

Chainable setter: set a fluid vertical size. See #fluid_width.


[View source]
def fluid_height : UI::Fluid | Nil #

[View source]
def fluid_height=(fluid_height : UI::Fluid | Nil) #

[View source]
def fluid_width(min : String | Number, ideal : String | Number, max : String | Number) : self #

Chainable setter: set a fluid horizontal size. Accepts CSS-compatible strings (e.g. "60vw", "20rem") or numeric pixel values, which are emitted as Npx. Returns self so calls can be chained.


[View source]
def fluid_width : UI::Fluid | Nil #

Fluid (responsive) size constraints. When set, the web renderer emits a width: clamp(min, ideal, max) (resp. height:) declaration instead of the literal minimum_* / maximum_* pair. Native renderers will adopt platform-idiomatic size class translations in later phases.


[View source]
def fluid_width=(fluid_width : UI::Fluid | Nil) #

Fluid (responsive) size constraints. When set, the web renderer emits a width: clamp(min, ideal, max) (resp. height:) declaration instead of the literal minimum_* / maximum_* pair. Native renderers will adopt platform-idiomatic size class translations in later phases.


[View source]
def hidden : Bool #

Whether the view is hidden from display


[View source]
def hidden=(hidden : Bool) #

Whether the view is hidden from display


[View source]
def id : String | Nil #

Optional identifier for this view, used for lookup and testing


[View source]
def id=(id : String | Nil) #

Optional identifier for this view, used for lookup and testing


[View source]
def maximum_height : Float64 | Nil #

[View source]
def maximum_height=(maximum_height : Float64 | Nil) #

[View source]
def maximum_width : Float64 | Nil #

[View source]
def maximum_width=(maximum_width : Float64 | Nil) #

[View source]
def minimum_height : Float64 | Nil #

[View source]
def minimum_height=(minimum_height : Float64 | Nil) #

[View source]
def minimum_width : Float64 | Nil #

Size constraints


[View source]
def minimum_width=(minimum_width : Float64 | Nil) #

Size constraints


[View source]
def opacity : Float64 #

Opacity from 0.0 (fully transparent) to 1.0 (fully opaque)


[View source]
def opacity=(opacity : Float64) #

Opacity from 0.0 (fully transparent) to 1.0 (fully opaque)


[View source]
def padding : EdgeInsets #

Padding around the view content


[View source]
def padding=(padding : EdgeInsets) #

Padding around the view content


[View source]
def root_fill : Bool #

Phase 6.10 Rem 4 (Item 2D) — root-fill flag.

When true, the renderer treats this view as a full-screen root and:

  • iOS / macOS: pins the view's width to the device screen width and lets its height grow to the screen height (or scroll if content exceeds it). Replaces the brittle hardcoded content_width = 340.0 pattern.
  • Web: emits min-height: 100dvh + width: 100% (CSS dvh respects mobile address-bar resizing).

Set via view.root_fill = true or the chainable shortcut view.fill_screen! (returns self for chaining).

The renderer-side honoring is best-effort — a #root_fill view nested deep inside another stack is still constrained by its parent's bounds. The intent is the OUTER root of an iOS / macOS screen.


[View source]
def root_fill=(root_fill : Bool) #

Phase 6.10 Rem 4 (Item 2D) — root-fill flag.

When true, the renderer treats this view as a full-screen root and:

  • iOS / macOS: pins the view's width to the device screen width and lets its height grow to the screen height (or scroll if content exceeds it). Replaces the brittle hardcoded content_width = 340.0 pattern.
  • Web: emits min-height: 100dvh + width: 100% (CSS dvh respects mobile address-bar resizing).

Set via view.root_fill = true or the chainable shortcut view.fill_screen! (returns self for chaining).

The renderer-side honoring is best-effort — a #root_fill view nested deep inside another stack is still constrained by its parent's bounds. The intent is the OUTER root of an iOS / macOS screen.


[View source]
def shadow_color : Color | Nil #

[View source]
def shadow_color=(shadow_color : Color | Nil) #

[View source]
def shadow_offset_x : Float64 #

[View source]
def shadow_offset_x=(shadow_offset_x : Float64) #

[View source]
def shadow_offset_y : Float64 #

[View source]
def shadow_offset_y=(shadow_offset_y : Float64) #

[View source]
def shadow_radius : Float64 #

Shadow modifier


[View source]
def shadow_radius=(shadow_radius : Float64) #

Shadow modifier


[View source]
def swiftkit_state_handle : Pointer(Void) | Nil #

SwiftKit reactive-state opaque pointer (Phase 3 Remediation 4).

Populated by the AppKit / UIKit renderer's visit method for views that participate in the reactive surface (today: UI::Label, UI::Button, UI::Toggle, UI::Slider). It mirrors the same pointer held on the underlying NativeHandle so Crystal-side widget mutators (e.g. UI::Label#text=) can dispatch through LibSwiftKitBridge.apsk_*_set_* without having to thread the NativeHandle back to user code. Nil for views that haven't been rendered yet, weren't rendered by a SwiftKit renderer (Web / Android), or aren't reactive widgets.

Lifetime: the pointer is +1 retained on the Swift side. The NativeHandle.release! path drops the retain via apsk_state_release; the View doesn't need to participate.


[View source]
def swiftkit_state_handle=(swiftkit_state_handle : Pointer(Void) | Nil) #

SwiftKit reactive-state opaque pointer (Phase 3 Remediation 4).

Populated by the AppKit / UIKit renderer's visit method for views that participate in the reactive surface (today: UI::Label, UI::Button, UI::Toggle, UI::Slider). It mirrors the same pointer held on the underlying NativeHandle so Crystal-side widget mutators (e.g. UI::Label#text=) can dispatch through LibSwiftKitBridge.apsk_*_set_* without having to thread the NativeHandle back to user code. Nil for views that haven't been rendered yet, weren't rendered by a SwiftKit renderer (Web / Android), or aren't reactive widgets.

Lifetime: the pointer is +1 retained on the Swift side. The NativeHandle.release! path drops the retain via apsk_state_release; the View doesn't need to participate.


[View source]
def test_id : String | Nil #

Test identifier for automated UI testing, maps to native test attributes


[View source]
def test_id=(test_id : String | Nil) #

Test identifier for automated UI testing, maps to native test attributes


[View source]