Components
Reusable components with props, outputs, events and context.
Contents:
k.Component: The only kind of reusable object: a subclass with props (k.Prop[T], inputs), static fields (name: T = default), outs (k.Out[T], outputs as signals) and events (k.Event), plus abuild()that runs once and returns the visual.k.Prop: Declares a reactive component prop:power: k.Prop[float] = k.prop(0.0).k.Out: Declares a continuous component output:soc: k.Out[float].k.Event: Declares an event on a component or ak.State:full: k.Eventor, with a typed payload,bounce: k.Event[Impact].k.field: Validated default for a static component field:k.field(0.2, range=(0, 1))ork.field("a", choices=[...]).k.prop: Validated default for a reactive prop:k.prop(0.0, range=(-5, 5)).k.context: Declares a context (at module level): a value that many components need (clock, scale, unit), supplied withk.provideinstead of passed down prop by prop.k.Context:Clock = k.context("clock", default=k.time), declared at module level.k.provide:withblock that supplies a context value to the components constructed inside it.k.from_context: Prop or field default that reads a context:time: k.Prop[float] = k.from_context(Clock).
Back to the reference index.
k.Component (class)#
k.Component(*, name: str | None = None, **kwargs: object)
Written as: class Name(k.Component)
The only kind of reusable object: a subclass with props (k.Prop[T], inputs), static fields (name: T = default), outs (k.Out[T], outputs as signals) and events (k.Event), plus a build() that runs once and returns the visual. Parts stored on self.* are addressable from outside. Verbs use enter()/exit()/indicate() when the component defines them.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
name |
str | None |
None |
|
**kwargs |
object |
variadic |
Props inherited from k.Node: x, y, rotate, scale, scale_x, scale_y, anchor, opacity, z, visible.
Example:
class Tag(k.Component):
text: str = "kinemo"
def build(self) -> k.Node:
self.box = k.RoundedRect(w=3, h=1)
self.label = k.Text(self.text).place(inside=self.box)
return k.Group(self.box, self.label)
@k.scene
def component(s: k.Scene):
tag = Tag(text="Hello").place(at="center")
s.play(k.draw(tag))
s.play(tag.box.to(color=k.BLUE))
See also: k.Prop, k.Out, k.Event, k.clip.
Members:
build: Return the component's visual (a node built from the props); runs once, at construction.copy: Rebuilds the component with the same arguments.
Inherited from k.Group: children, to, swap, insert, pop, fit.
Inherited from k.Node: set, unbind, edge, age, entered, exited, place, to_place, unpin.
k.Component.build (method)
component.build() -> Node
Return the component's visual (a node built from the props); runs once, at construction.
k.Component.copy (method)
component.copy(frozen: bool = False) -> Component
Rebuilds the component with the same arguments.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
frozen |
bool |
False |
k.Prop (class)#
k.Prop()
Written as: name: k.Prop[T] = default
Declares a reactive component prop: power: k.Prop[float] = k.prop(0.0). Inside the component it is always a signal (Signal[float]), even if the author passed a constant; from outside, it accepts a value, signal or lambda and animates with comp.to(power=...). The default via k.prop is what passes Pyright strict.
Example:
class Gauge(k.Component):
value: k.Prop[float] = k.prop(0.0)
def build(self) -> k.Node:
return k.Rect(w=0.6, h=self.value + 0.01, fill=k.GREEN, fill_opacity=1)
@k.scene
def gauge(s: k.Scene):
m = Gauge(value=1.0).place(at="center")
s.add(m)
s.play(m.to(value=3))
See also: k.Component, k.prop, k.field.
k.Out (class)#
k.Out()
Written as: name: k.Out[T]
Declares a continuous component output: soc: k.Out[float]. It must be assigned in build() (error K0602) and is read from outside as a read-only signal (bat.soc).
Example:
class Counter(k.Component):
total: k.Out[float]
def build(self) -> k.Node:
self.total = k.integrate(0.5)
return k.Text(lambda: f"{self.total():.1f}")
@k.scene
def output(s: k.Scene):
c = Counter().place(at="center")
bar = k.Rect(w=0.5, h=c.total + 0.01).place(below=c, gap=0.3)
s.add(c, bar)
s.wait(3)
See also: k.Component, k.integrate.
k.Event (class)#
k.Event()
Written as: name: k.Event · name: k.Event[Payload]
Declares an event on a component or a k.State: full: k.Event or, with a typed payload, bounce: k.Event[Impact]. Fire it with k.when(cond, self.full) or self.full.emit(); react with @obj.full.on or s.wait_for(obj.full). String-based events do not exist.
Example:
class Alarm(k.Component):
rang: k.Event
def build(self) -> k.Node:
k.when(k.time >= 2, self.rang)
return k.Circle(r=0.5, fill=k.RED, fill_opacity=1)
@k.scene
def event(s: k.Scene):
alarm = Alarm().place(at="center")
s.add(alarm)
s.wait_for(alarm.rang, timeout=5)
s.play(k.flash(alarm))
See also: event.on, k.when, s.wait_for.
k.field (function)#
k.field(
default: T,
*,
range: tuple[float, float] | None = None,
choices: Sequence[T] | None = None,
) -> T
k.field(
*,
range: tuple[float, float] | None = None,
choices: Sequence[Any] | None = None,
) -> Any
Validated default for a static component field: k.field(0.2, range=(0, 1)) or k.field("a", choices=[...]). Out-of-range values are an error at construction; static fields reject signals (K0601).
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
default |
T |
required | |
range |
tuple[float, float] | None |
None |
Validated default for a static component field: k.field(0.2, range=(0, 1)) or k.field("a", choices=[...]). |
choices |
Sequence[T] | None |
None |
Validated default for a static component field: k.field(0.2, range=(0, 1)) or k.field("a", choices=[...]). |
Example:
class Ring(k.Component):
thickness: float = k.field(0.2, range=(0.05, 1))
def build(self) -> k.Node:
return k.Circle(r=1, stroke_width=self.thickness * 20)
@k.scene
def ring(s: k.Scene):
r = Ring(thickness=0.4).place(at="center")
s.play(k.draw(r))
See also: k.prop, k.Component.
k.prop (function)#
k.prop(default: bool, *, range: tuple[float, float] | None = None) -> Prop[bool]
k.prop(default: float, *, range: tuple[float, float] | None = None) -> Prop[float]
k.prop(default: T, *, range: tuple[float, float] | None = None) -> Prop[T]
Validated default for a reactive prop: k.prop(0.0, range=(-5, 5)). Constants are validated at construction; for reactive values, lint W0602 samples the timeline.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
default |
bool |
required | |
range |
tuple[float, float] | None |
None |
Validated default for a reactive prop: k.prop(0.0, range=(-5, 5)). |
Example:
class Needle(k.Component):
angle: k.Prop[float] = k.prop(0.0, range=(0, 360))
def build(self) -> k.Node:
return k.Line(start=(0, 0), end=(2, 0), rotate=self.angle)
@k.scene
def needle(s: k.Scene):
p = Needle(angle=30)
s.add(p)
s.play(p.to(angle=150))
k.context (function)#
k.context(name: str, default: T) -> Context[T]
k.context(name: str) -> Context[Any]
Declares a context (at module level): a value that many components need (clock, scale, unit), supplied with k.provide instead of passed down prop by prop. The theme is a built-in context.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
name |
str |
required | |
default |
T |
required |
Example:
Scale = k.context("scale", default=1.0)
class Point(k.Component):
r: k.Prop[float] = k.from_context(Scale)
def build(self) -> k.Node:
return k.Dot(r=self.r * 0.2)
@k.scene
def context(s: k.Scene):
with k.provide(Scale, 2.0):
p = Point().place(at="center")
s.play(k.fade_in(p))
See also: k.provide, k.from_context.
k.Context (class)#
k.Context(name: str, default: T)
Clock = k.context("clock", default=k.time), declared at module level.
Documented together with k.context.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
name |
str |
required | |
default |
T |
required | Clock = k.context("clock", default=k.time), declared at module level. |
Members:
get: Value provided for this context in the enclosingk.provideblock, or the default.
k.Context.get (method)
context.get() -> T
Value provided for this context in the enclosing k.provide block, or the default.
k.provide (function)#
k.provide(ctx: Context[T], value: Val[T]) -> Iterator[None]
with block that supplies a context value to the components constructed inside it. It is resolved at construction (lexical scope of the build phase); passing the prop explicitly always wins over the context.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
ctx |
Context[T] |
required | Components constructed inside the block receive value for ctx. |
value |
Val[T] |
required | Components constructed inside the block receive value for ctx. |
Example: same as k.context.
See also: k.context, k.from_context.
k.from_context (function)#
k.from_context(ctx: Context[Any]) -> Any
Prop or field default that reads a context: time: k.Prop[float] = k.from_context(Clock). Without k.provide, the context's default= applies.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
ctx |
Context[Any] |
required | Default of a prop or field read from ctx at construction. |
Example: same as k.context.