Module: Tuile::Component::HasValue
- Includes:
- HasValidation
- Included in:
- AbstractStringField, AbstractWrappingField, Checkbox, CheckboxGroup, ComboBox, DateTimeField, RadioGroup, Select
- Defined in:
- lib/tuile/component/has_value.rb,
sig/tuile.rbs
Overview
The value seam every input component shares: a settable/gettable #value
of any type, an #on_value_change listener, #empty?, and #clear. A
form (a future binder) drives a mix of field types uniformly through it,
not caring that a TextField's value is a String while another field's
is a domain object.
field.on_value_change = ->(v) { puts "now: #{v.inspect}" }
field.value = "hello" # fires the listener
field.clear # value = empty_value, fires again
The default #value=/#value keep the value in @value and are enough
for a component with nothing more natural — you get a repaint and the
listener for free. An includer whose value lives elsewhere overrides both
(AbstractStringField backs them with its text buffer). Override #empty_value
when the empty sentinel isn't nil (a text field's is "").
HasValidation comes with it, so every field carries the
error_message a validator writes and paints its own error ink.
Implementation details
Deliberately smaller than Vaadin's HasValue: read-only,
required-indicator, the from-client/old-value event payload, and
converters all belong to the not-yet-built form layer, not here.
Instance Attribute Summary collapse
-
#on_value_change ⇒ Proc, ...
@return — one-arg callable fired with the new value whenever #value actually changes — never on a no-op set.
Attributes included from HasValidation
Instance Method Summary collapse
-
#clear ⇒ void
Resets #value to #empty_value.
-
#empty? ⇒ Boolean
Empty of value: a field whose parse is partial reports
truewhile the user is looking at glyphs it could not use, so ask Tuile::Component::HasBadInput#bad_input? first. - #empty_value ⇒ Object
-
#error_bg_color ⇒ Color?
The invalid well, picked up by everything this component paints — including the inner face of a composed field and the List of a group, neither of which forwards anything: both declare no background of their own, so the ordinary chain walks up to this (overrides #error_bg_color).
-
#error_ink? ⇒ Boolean
Whether to paint the invalid well right now.
-
#error_message ⇒ StyledString?
@return — why the field is invalid, or
nilwhen it is not;niluntil something sets it. -
#error_message= ⇒ void
Sets the verdict and repaints the field in Theme#error_color;
nilclears it. -
#focusable? ⇒ Boolean
Input fields are focusable by default (overrides #focusable?); a read-only display field could override back to
false. -
#inspect_details ⇒ ::Array[String]
Adds
value=…to #inspect, omitted while the value is nil. -
#value ⇒ Object
@return — the current value;
niluntil first set. -
#value=(new_value) ⇒ void
No-op (no repaint, no listener) when equal to the current value.
Instance Attribute Details
#on_value_change ⇒ Proc, ...
@return — one-arg callable fired with the new value whenever #value actually changes — never on a no-op set.
33 34 35 |
# File 'lib/tuile/component/has_value.rb', line 33 def on_value_change @on_value_change end |
Instance Method Details
#clear ⇒ void
This method returns an undefined value.
Resets #value to #empty_value.
An includer whose input can outrun its value (Tuile::Component::HasBadInput) must clear
the input: a field holding bad input already reads empty_value, so
inheriting this default — over a #value= that returns early on a no-op
set — is a clear that leaves the garbage on screen.
62 |
# File 'lib/tuile/component/has_value.rb', line 62 def clear = (self.value = empty_value) |
#empty? ⇒ Boolean
Empty of value: a field whose parse is partial reports true while the
user is looking at glyphs it could not use, so ask
Tuile::Component::HasBadInput#bad_input? first.
@return — true iff #value equals #empty_value.
53 |
# File 'lib/tuile/component/has_value.rb', line 53 def empty? = value == empty_value |
#empty_value ⇒ Object
66 |
# File 'lib/tuile/component/has_value.rb', line 66 def empty_value = nil |
#error_bg_color ⇒ Color?
The invalid well, picked up by everything this component paints — including the inner face of a composed field and the List of a group, neither of which forwards anything: both declare no background of their own, so the ordinary chain walks up to this (overrides Tuile::Component#error_bg_color).
6733 |
# File 'sig/tuile.rbs', line 6733
def error_bg_color: () -> Color?
|
#error_ink? ⇒ Boolean
Whether to paint the invalid well right now. Its own hook because Tuile::Component::HasBadInput widens it: a field holding input its value cannot represent is invalid on the face too, even with no verdict written.
6738 |
# File 'sig/tuile.rbs', line 6738
def error_ink?: () -> bool
|
#error_message ⇒ StyledString?
@return — why the field is invalid, or nil when it
is not; nil until something sets it.
6716 |
# File 'sig/tuile.rbs', line 6716
def error_message: () -> StyledString?
|
#error_message= ⇒ void
This method returns an undefined value.
Sets the verdict and repaints the field in Theme#error_color; nil
clears it. No-op (no repaint, no listener) when unchanged. A String is
parsed via StyledString.parse, as Tuile::Component::HasCaption#caption= does.
Safe on a detached field — an app validates a form it assembled but has not mounted, and Tuile::Component#invalidate is already a no-op there.
@param new_message
6726 |
# File 'sig/tuile.rbs', line 6726
def error_message=: ((String | StyledString)? new_message) -> void
|
#focusable? ⇒ Boolean
Input fields are focusable by default (overrides Tuile::Component#focusable?);
a read-only display field could override back to false. Only
focusable? lives here — tab_stop? diverges between leaf fields and
composing wrappers, so it stays per-class (design/decisions.md
D_integer_field).
74 |
# File 'lib/tuile/component/has_value.rb', line 74 def focusable? = true |
#inspect_details ⇒ ::Array[String]
Adds value=… to Tuile::Component#inspect, omitted while the value is nil.
80 81 82 83 84 85 86 87 88 |
# File 'lib/tuile/component/has_value.rb', line 80 def inspect_details v = value return super if v.nil? # Truncate before #inspect, not after: a TextArea's value is its whole # buffer. v = "#{v[0, 40]}…" if v.is_a?(String) && v.length > 40 super + ["value=#{v.inspect}"] end |
#value ⇒ Object
@return — the current value; nil until first set.
36 |
# File 'lib/tuile/component/has_value.rb', line 36 def value = @value |
#value=(new_value) ⇒ void
This method returns an undefined value.
No-op (no repaint, no listener) when equal to the current value.
@param new_value
41 42 43 44 45 46 47 |
# File 'lib/tuile/component/has_value.rb', line 41 def value=(new_value) return if value == new_value @value = new_value invalidate on_value_change&.call(new_value) end |