zaniah 0.12.3 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 386e75cb5db3d2027ed3c94ca7bbb3df1d1f7c1980df89bf108456da24993255
4
- data.tar.gz: 7f546b6bda16e84eccd36310ff8bc1f065bead904ad8cd68c5ef26a45b6ef913
3
+ metadata.gz: 3650507aed861e96e016a6c2b33d629758512e9da2de9278122070a3a76151f9
4
+ data.tar.gz: de00322355b6736e94b7fe1f4856d2471c7838c3ed34e78db5169593a0e01b19
5
5
  SHA512:
6
- metadata.gz: 1e8b40e41c9f23d9d954e83fa78e8929cddbbc1e651244a409c30c9cfb14943821aaaf096b41febeba568e912761cbf2da18f768efc4c5c83642d6fb74a223bf
7
- data.tar.gz: adc23e2da904fff7f30520676dcf961f303f6295d3bb914fd994c928b97ef6091ce05981f85d4b8587f1048ff2fc0c13fb91f4739ff3fbc6d3d1821a8e049b4e
6
+ metadata.gz: 209714f65e39e7d50e9c47357de8bd9f20f970922e208c2dd4ba1624ff9c126aec4797b791e8955e0342e6ec41d170a0a49dd2862528e058ddba65d7c28e8bdf
7
+ data.tar.gz: 6022d62f59e2902e26ec232570f47a0221a5ee235820fb88d2cd5e4da68fa08fe0100927618385fec8a269f23225dc5449f4539750b855deadc8bd57faa955b7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.12.4 — 2026-10-02
4
+
5
+ - Let applications name tables, trees, groups, and other components for screen readers, and announce property editor labels consistently.
6
+ - Support localized dialog close buttons and command palette titles, with accessible close actions. Preserve nested controls in dialog and tab accessibility trees.
7
+ - Show selected option captions in dropdowns and select fields while retaining their underlying values.
8
+ - Restore keyboard focus immediately when a dialog is closed, and retain menu bar and command palette search focus across redraws.
9
+
3
10
  ## 0.12.3 — 2026-10-02
4
11
 
5
12
  - Improve redraw responsiveness in views with many styled controls.
@@ -11,12 +11,12 @@ module Zaniah
11
11
  def disabled(value = true) = (@disabled = !!value; self)
12
12
 
13
13
  def build(cx)
14
- return Button.new(@value ? @value.to_s : @label, variant: :secondary).disabled if @disabled
14
+ return Button.new(selected_label, variant: :secondary).disabled if @disabled
15
15
  super
16
16
  end
17
17
 
18
- def tui_cells(*) = "#{@label}: [#{@value || "choose"} ▾]"
19
- def accessibility_node(_cx) = node(:combobox, label: @label, value: @value,
18
+ def tui_cells(*) = "#{@label}: [#{@value.nil? ? "choose" : selected_label} ▾]"
19
+ def accessibility_node(_cx) = node(:combobox, label: @label, value: @value.nil? ? nil : selected_label,
20
20
  states: {expanded: false, disabled: @disabled}, actions: @disabled ? [] : [:press])
21
21
  end
22
22
 
@@ -23,6 +23,7 @@ module Zaniah
23
23
  @window_control = kind
24
24
  self
25
25
  end
26
+ def accessibility_label(value) = (@accessibility_label = value&.to_s; self)
26
27
  def accessibility_node(_cx) = nil
27
28
  def tui_cells(_bounds = nil, _cx = nil) = nil
28
29
  def focus_handle = @root&.focus_handle
@@ -68,10 +69,19 @@ module Zaniah
68
69
 
69
70
  attr_writer :parent
70
71
 
72
+ def child_node(pane, cx)
73
+ semantic = pane.accessibility_node(cx) if pane.respond_to?(:accessibility_node)
74
+ return semantic if semantic.is_a?(Accessibility::Node)
75
+ children = pane.respond_to?(:children) ? pane.children : []
76
+ nodes = children.filter_map { |child| child_node(child, cx) }
77
+ Accessibility.node(role: :group, children: nodes) unless nodes.empty?
78
+ end
79
+
80
+
71
81
  private
72
82
 
73
- def node(role, id: @test_id, label: nil, value: nil, states: {}, children: [], actions: [])
74
- result = Accessibility.node(role: role, id: id, label: label, value: value,
83
+ def node(role, id: @test_id, label: @accessibility_label, value: nil, states: {}, children: [], actions: [])
84
+ result = Accessibility.node(role: role, id: id, label: @accessibility_label || label, value: value,
75
85
  bounds: @layout_node&.bounds, states: states, children: children, actions: actions)
76
86
  Accessibility::NODE_OWNERS[result] = self
77
87
  result
@@ -5,8 +5,9 @@ module Zaniah
5
5
  class SegmentedControl < Component
6
6
  attr_reader :value
7
7
 
8
- def initialize(options, value: nil)
8
+ def initialize(options, value: nil, label: nil)
9
9
  super()
10
+ accessibility_label(label)
10
11
  @options = Array(options).map do |option|
11
12
  label, item = option.is_a?(Array) ? option : [option, option]
12
13
  [label.to_s, item]
@@ -32,7 +32,7 @@ module Zaniah
32
32
 
33
33
  def tui_cells(*) = "#{text(@first)} #{@orientation == :horizontal ? "│" : "─"} #{text(@second)}"
34
34
  def accessibility_node(cx)
35
- panes = [@first, @second].map { |pane| pane_node(pane, cx) }
35
+ panes = [@first, @second].map { |pane| child_node(pane, cx) }
36
36
  divider = Accessibility.node(role: :separator, value: @ratio,
37
37
  states: {orientation: @orientation}, actions: %i[increment decrement])
38
38
  node(:group, states: {orientation: @orientation}, children: [panes.first, divider, panes.last].compact)
@@ -40,14 +40,6 @@ module Zaniah
40
40
 
41
41
  private
42
42
 
43
- def pane_node(pane, cx)
44
- semantic = pane.accessibility_node(cx) if pane.respond_to?(:accessibility_node)
45
- return semantic if semantic.is_a?(Accessibility::Node)
46
- children = pane.respond_to?(:children) ? pane.children : []
47
- nodes = children.filter_map { |child| pane_node(child, cx) }
48
- Accessibility.node(role: :group, children: nodes) unless nodes.empty?
49
- end
50
-
51
43
  def drag(event, cx)
52
44
  return false unless @bounds
53
45
  size = @orientation == :horizontal ? @bounds.width : @bounds.height
@@ -3,9 +3,10 @@
3
3
  module Zaniah
4
4
  module UI
5
5
  class Modal < OverlayComponent
6
- def initialize(content, title: nil, open: true, close_on_scrim: true, width: 440)
6
+ def initialize(content, title: nil, open: true, close_on_scrim: true, width: 440, close_label: "Close")
7
7
  super(open: open, modal: true)
8
8
  @content, @title, @close_on_scrim, @panel_width = content, title&.to_s, !!close_on_scrim, width
9
+ @close_label = close_label.to_s
9
10
  @focus_scope.on_action = ->(action) { action == :dismiss && dismiss(nil, @cx) }
10
11
  end
11
12
 
@@ -19,7 +20,7 @@ module Zaniah
19
20
  if @title
20
21
  panel.child(Div.new.flex_row.items_center.gap(cx.theme.spacing[2])
21
22
  .child(Label.new(@title, size: :lg).flex_1)
22
- .child(IconButton.new(:close, label: "Close", variant: :ghost).on_click { |event, context| dismiss(event, context) }))
23
+ .child(@close_button ||= IconButton.new(:close, label: @close_label, variant: :ghost).on_click { |event, context| dismiss(event, context) }))
23
24
  end
24
25
  panel.child(@content)
25
26
  Overlay.new.items_center.justify_center.bg(cx.theme.colors.overlay_scrim)
@@ -28,7 +29,7 @@ module Zaniah
28
29
  end
29
30
 
30
31
  def tui_cells(*) = "┌ #{@title || "Dialog"} ┐\n#{@content.respond_to?(:tui_cells) ? @content.tui_cells : ""}\n└#{"─" * 8}┘"
31
- def accessibility_node(cx) = @open && node(:dialog, label: @title, states: {modal: true}, children: [@content.respond_to?(:accessibility_node) ? @content.accessibility_node(cx) : nil].compact, actions: [:dismiss])
32
+ def accessibility_node(cx) = @open && node(:dialog, label: @title, states: {modal: true}, children: [child_node(@content, cx), @close_button&.accessibility_node(cx)].compact, actions: [:dismiss])
32
33
  end
33
34
 
34
35
  class Dialog < Modal; end
@@ -126,19 +127,19 @@ module Zaniah
126
127
  new(commands, **options)
127
128
  end
128
129
 
129
- def initialize(commands, open: false, placeholder: "Type a command…", matcher: nil, keymap: nil)
130
+ def initialize(commands, open: false, placeholder: "Type a command…", matcher: nil, keymap: nil, title: "Command palette", close_label: "Close")
130
131
  @commands = commands.to_a.map { |label, callback, enabled, action| [label.to_s, callback, enabled, action] }
131
132
  @keymap = keymap
132
133
  @matcher = Matcher::Session.new(@commands.map(&:first), matcher || Zaniah.configuration.matcher || Matcher::Substring.new)
133
134
  @query, @placeholder, @selected_index = "", placeholder, 0
134
135
  @focus_search = !!open
135
- super(Div.new, title: "Command palette", open: open, width: 520)
136
+ super(Div.new, title: title, open: open, width: 520, close_label: close_label)
136
137
  @focus_scope.context[:in_palette] = true
137
138
  @focus_scope.on_action = ->(action) { palette_action(action) }
138
139
  end
139
140
 
140
141
  def build(cx)
141
- field = @search = SearchInput.new(@query, placeholder: @placeholder).on_change do |value, context|
142
+ field = @search ||= SearchInput.new(@query, placeholder: @placeholder).on_change do |value, context|
142
143
  @query = value
143
144
  @selected_index = 0
144
145
  context.window.request_frame
@@ -188,10 +189,11 @@ module Zaniah
188
189
  Accessibility.node(role: :listitem, id: "palette-option-#{match.index}", label: entry[0],
189
190
  states: {selected: index == @selected_index, disabled: !enabled}, actions: enabled ? [:press] : [])
190
191
  end
191
- node(:dialog, label: "Command palette", states: {modal: true}, children: [
192
+ node(:dialog, label: @title, states: {modal: true}, children: [
192
193
  Accessibility.node(role: :searchbox, label: @placeholder, value: @query),
193
- Accessibility.node(role: :list, states: {active_descendant: active && "palette-option-#{active}"}, children: items)
194
- ], actions: [:dismiss])
194
+ @close_button&.accessibility_node(cx),
195
+ Accessibility.node(role: :list, label: @title, states: {active_descendant: active && "palette-option-#{active}"}, children: items)
196
+ ].compact, actions: [:dismiss])
195
197
  end
196
198
 
197
199
  def accessibility_action(item, action)
@@ -53,6 +53,7 @@ module Zaniah
53
53
  @visible, @entered = true, false
54
54
  @cx&.window&.request_frame
55
55
  else
56
+ release_focus
56
57
  @cx ? animate_close(@cx) : @visible = false
57
58
  end
58
59
  self
@@ -80,9 +81,7 @@ module Zaniah
80
81
  target = tree.next
81
82
  cx.dispatcher.focus(target, origin: :keyboard) if target && !focused_inside
82
83
  elsif @trapped
83
- tree.release_trap(@focus_scope)
84
- @dispatcher.focus(@return_focus) if @return_focus&.focusable
85
- @trapped = false
84
+ release_focus
86
85
  end
87
86
  end
88
87
 
@@ -96,16 +95,21 @@ module Zaniah
96
95
  def dismiss(event = nil, cx = nil)
97
96
  return false unless @open
98
97
  @open = false
98
+ release_focus
99
99
  @on_close&.call(event, cx)
100
- cx&.dispatcher&.focus_tree&.release_trap(@focus_scope)
101
- cx&.dispatcher&.focus(@return_focus) if @return_focus&.focusable
102
- @trapped = false
103
100
  animate_close(cx) if cx
104
101
  @visible = false unless cx
105
102
  cx&.window&.request_frame
106
103
  true
107
104
  end
108
105
 
106
+ def release_focus
107
+ return unless @trapped
108
+ @dispatcher.focus_tree.release_trap(@focus_scope)
109
+ @dispatcher.focus(@return_focus) if @return_focus&.focusable
110
+ @trapped = false
111
+ end
112
+
109
113
  def viewport(cx) = Bounds.new(0, 0, cx.window.content_size.width, cx.window.content_size.height)
110
114
 
111
115
  def visibility_key = [:overlay, object_id]
@@ -313,14 +317,16 @@ module Zaniah
313
317
  super()
314
318
  @model = menus if menus.is_a?(Zaniah::Menu)
315
319
  @menus = @model ? [] : menus.to_a
320
+ @buttons = []
316
321
  end
317
322
 
318
323
  def build(cx)
319
324
  return build_model(cx) if @model
320
325
 
321
- Div.new.flex_row.items_center.gap(2).children(@menus.map do |label, items|
322
- Button.new(label.to_s, size: :sm, variant: :ghost).on_click { |_event, context| context.window.context_menu(items, position: @bounds ? Point.new(@bounds.x, @bounds.bottom) : Point.new(0, 0)) }
323
- end)
326
+ @buttons = @menus.map.with_index do |(label, items), index|
327
+ section_button(index, label.to_s).on_click { |_event, context| context.window.context_menu(items, position: @bounds ? Point.new(@bounds.x, @bounds.bottom) : Point.new(0, 0)) }
328
+ end
329
+ Div.new.flex_row.items_center.gap(2).children(@buttons)
324
330
  end
325
331
 
326
332
  def tui_cells(_bounds = nil, cx = nil)
@@ -336,6 +342,11 @@ module Zaniah
336
342
 
337
343
  private
338
344
 
345
+ def section_button(index, label)
346
+ button = @buttons[index]
347
+ button&.label == label ? button : Button.new(label, size: :sm, variant: :ghost)
348
+ end
349
+
339
350
  def resolved_sections(cx)
340
351
  @model.resolve(registry: cx&.window&.app&.actions, keymap: cx&.dispatcher&.keymap)
341
352
  end
@@ -357,9 +368,9 @@ module Zaniah
357
368
  @cx = cx
358
369
  sections = resolved_sections(cx)
359
370
  bar = Div.new.flex_row.items_center.gap(2).h(28)
360
- sections.each_with_index do |section, index|
371
+ @buttons = sections.map.with_index do |section, index|
361
372
  next unless section.title
362
- button = Button.new(section.title, size: :sm, variant: :ghost)
373
+ button = section_button(index, section.title).disabled(false)
363
374
  if section.submenu?
364
375
  button.on_click do |_event, context|
365
376
  target_focus = focus_target(context.dispatcher.previous_focused)
@@ -379,8 +390,9 @@ module Zaniah
379
390
  context.dispatcher.perform(section.action, source: :menu)
380
391
  end
381
392
  end
382
- bar.child(button)
393
+ button
383
394
  end
395
+ bar.children(@buttons.compact)
384
396
  bar.child(@active_menu) if @active_menu&.open?
385
397
  bar
386
398
  end
@@ -397,7 +409,7 @@ module Zaniah
397
409
  def on_change(&block) = (@on_change = block; self)
398
410
 
399
411
  def build(_cx)
400
- Button.new(@value ? @value.to_s : @label, variant: :secondary).icon(:menu, position: :trailing).on_click do |_event, context|
412
+ Button.new(selected_label, variant: :secondary).icon(:menu, position: :trailing).on_click do |_event, context|
401
413
  pairs = @items.map do |label, value = label|
402
414
  [label.to_s, ->(event = nil, cx = context) { @value = value; @on_change&.call(value, event, cx); cx.window.request_frame }]
403
415
  end
@@ -405,8 +417,18 @@ module Zaniah
405
417
  end
406
418
  end
407
419
 
408
- def tui_cells(*) = "#{@label}: #{@value || "▾"}"
409
- def accessibility_node(_cx) = node(:button, label: @label, value: @value, states: {expanded: false}, actions: [:press])
420
+ def tui_cells(*) = "#{@label}: #{@value.nil? ? "▾" : selected_label}"
421
+ def accessibility_node(_cx) = node(:button, label: @label, value: @value.nil? ? nil : selected_label, states: {expanded: false}, actions: [:press])
422
+
423
+ protected
424
+
425
+ def selected_label
426
+ return @label if @value.nil?
427
+ @items.each do |label, value = label|
428
+ return label.to_s if value == @value
429
+ end
430
+ @value.to_s
431
+ end
410
432
  end
411
433
  end
412
434
  end
@@ -8,8 +8,9 @@ module Zaniah
8
8
 
9
9
  attr_reader :values, :errors
10
10
 
11
- def initialize(schema, values = {}, height: 320, row_height: 52)
11
+ def initialize(schema, values = {}, height: 320, row_height: 52, label: nil)
12
12
  super()
13
+ accessibility_label(label)
13
14
  @properties = Array(schema).map { |entry| normalize(entry) }.freeze
14
15
  raise ArgumentError, "property keys must be unique" unless @properties.map(&:key).uniq.length == @properties.length
15
16
  @values = values.to_h.transform_keys(&:to_sym)
@@ -63,7 +64,7 @@ module Zaniah
63
64
  Accessibility.node(role: :row, id: [:property, property.key].freeze,
64
65
  states: {selected: index == @selected_index, invalid: !!error},
65
66
  children: [Accessibility.node(role: :rowheader, label: property.label),
66
- Accessibility.node(role: :cell, value: @drafts.fetch(property.key) { @values[property.key] },
67
+ Accessibility.node(role: :cell, label: property.label, value: @drafts.fetch(property.key) { @values[property.key] },
67
68
  children: [control, (Accessibility.node(role: :alert, label: error.join(", ")) if error)].compact)])
68
69
  end
69
70
  node(:table, states: {size: @properties.length}, children: children)
@@ -113,6 +114,7 @@ module Zaniah
113
114
  when :date then DatePicker.new(value || Date.today, label: "")
114
115
  when :time then TimePicker.new(value || "00:00", label: "")
115
116
  end
117
+ control.accessibility_label(label)
116
118
  control.on_change do |changed, *_args|
117
119
  if property.type == :number
118
120
  begin
@@ -28,7 +28,7 @@ module Zaniah
28
28
  def tui_cells(*) = "#{@items.map.with_index { |(label, _), index| index == @selected_index ? "[#{label}]" : label }.join(" ")}\n#{content_text}"
29
29
  def accessibility_node(cx)
30
30
  tabs = @items.map.with_index { |(label, _), index| Accessibility.node(role: :tab, label: label, states: {selected: index == @selected_index}, actions: [:select]) }
31
- node(:group, children: tabs + [Accessibility.node(role: :tabpanel, children: [@items[@selected_index][1].respond_to?(:accessibility_node) ? @items[@selected_index][1].accessibility_node(cx) : nil].compact)])
31
+ node(:group, children: tabs + [Accessibility.node(role: :tabpanel, children: [child_node(@items[@selected_index][1], cx)].compact)])
32
32
  end
33
33
 
34
34
  private
@@ -13,8 +13,9 @@ module Zaniah
13
13
 
14
14
  attr_reader :selected_id, :expanded
15
15
 
16
- def initialize(items, height: 320, row_height: 28, selected: nil)
16
+ def initialize(items, height: 320, row_height: 28, selected: nil, label: nil)
17
17
  super()
18
+ accessibility_label(label)
18
19
  @source, @height, @row_height = items.to_a, Float(height), Float(row_height)
19
20
  raise ArgumentError, "tree dimensions must be positive" unless @height.positive? && @row_height.positive?
20
21
 
@@ -6,8 +6,9 @@ module Zaniah
6
6
  class VirtualTable < Component
7
7
  attr_reader :selection, :sort_key, :sort_direction, :body
8
8
 
9
- def initialize(source, columns:, height: 320, row_height: 24, selection: :single, follow_tail: false)
9
+ def initialize(source, columns:, height: 320, row_height: 24, selection: :single, follow_tail: false, label: nil)
10
10
  super()
11
+ accessibility_label(label)
11
12
  raise ArgumentError, "source must provide count and cell" unless source.respond_to?(:count) && source.respond_to?(:cell)
12
13
  raise ArgumentError, "selection must be none, single, or multiple" unless %i[none single multiple].include?(selection)
13
14
  @source, @height, @row_height, @selection_mode = source, Float(height), Float(row_height), selection
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zaniah
4
- VERSION = "0.12.3"
4
+ VERSION = "0.12.4"
5
5
  end
data/sig/ui.rbs CHANGED
@@ -20,6 +20,7 @@ module Zaniah
20
20
  | (String value) -> self
21
21
  def style: (**Layout::style_value properties) -> self
22
22
  def window_control: (:close | :minimize | :maximize | :restore | :fullscreen kind) -> self
23
+ def accessibility_label: (String? value) -> self
23
24
  def accessibility_node: (FrameContext? context) -> Accessibility::Node?
24
25
  def tui_cells: (?Bounds? bounds, ?FrameContext? context) -> String?
25
26
  def focus_handle: () -> Input::FocusHandle?
@@ -138,7 +139,7 @@ module Zaniah
138
139
  end
139
140
  class SegmentedControl < Component
140
141
  attr_reader value: untyped
141
- def initialize: (Array[untyped] options, ?value: untyped) -> void
142
+ def initialize: (Array[untyped] options, ?value: untyped, ?label: String?) -> void
142
143
  def on_change: () { (untyped, Input::MouseDown?, FrameContext?) -> void } -> self
143
144
  end
144
145
  class Alert < Component
@@ -447,7 +448,7 @@ module Zaniah
447
448
  end
448
449
  attr_reader values: Hash[Symbol, untyped]
449
450
  attr_reader errors: Hash[Symbol, Array[String]]
450
- def initialize: (Array[untyped] schema, ?Hash[Symbol | String, untyped] values, ?height: Numeric, ?row_height: Numeric) -> void
451
+ def initialize: (Array[untyped] schema, ?Hash[Symbol | String, untyped] values, ?height: Numeric, ?row_height: Numeric, ?label: String?) -> void
451
452
  def on_change: () { (Symbol, untyped, Hash[Symbol, untyped], FrameContext?) -> void } -> self
452
453
  def set: (Symbol | String key, untyped value) -> bool
453
454
  end
@@ -461,7 +462,7 @@ module Zaniah
461
462
  end
462
463
 
463
464
  class Modal < OverlayComponent
464
- def initialize: (_Renderable content, ?title: String?, ?open: bool, ?close_on_scrim: bool, ?width: dimension) -> void
465
+ def initialize: (_Renderable content, ?title: String?, ?open: bool, ?close_on_scrim: bool, ?width: dimension, ?close_label: String) -> void
465
466
  end
466
467
  class Dialog < Modal
467
468
  end
@@ -483,7 +484,7 @@ module Zaniah
483
484
  class CommandPalette < Modal
484
485
  attr_reader query: String
485
486
  def self.from: (Input::ActionRegistry registry, **untyped options) -> CommandPalette
486
- def initialize: (Array[untyped] commands, ?open: bool, ?placeholder: String, ?matcher: Matcher::_Matcher?, ?keymap: Input::Keymap?) -> void
487
+ def initialize: (Array[untyped] commands, ?open: bool, ?placeholder: String, ?matcher: Matcher::_Matcher?, ?keymap: Input::Keymap?, ?title: String, ?close_label: String) -> void
487
488
  def accessibility_action: (Accessibility::Node item, Symbol action) -> bool?
488
489
  end
489
490
 
@@ -520,7 +521,7 @@ module Zaniah
520
521
  attr_reader sort_key: Symbol?
521
522
  attr_reader sort_direction: :asc | :desc
522
523
  attr_reader body: UniformList
523
- def initialize: (_VirtualTableSource source, columns: Array[untyped], ?height: Numeric, ?row_height: Numeric, ?selection: :none | :single | :multiple, ?follow_tail: bool) -> void
524
+ def initialize: (_VirtualTableSource source, columns: Array[untyped], ?height: Numeric, ?row_height: Numeric, ?selection: :none | :single | :multiple, ?follow_tail: bool, ?label: String?) -> void
524
525
  def columns: () -> Array[Hash[Symbol, untyped]]
525
526
  def on_sort: () { (Symbol, :asc | :desc, FrameContext?) -> void } -> self
526
527
  def on_select: () { (Integer, Input::MouseDown?, FrameContext?) -> void } -> self
@@ -556,7 +557,7 @@ module Zaniah
556
557
  end
557
558
  attr_reader selected_id: untyped
558
559
  attr_reader expanded: Set[untyped]
559
- def initialize: (Array[untyped] items, ?height: Numeric, ?row_height: Numeric, ?selected: untyped) -> void
560
+ def initialize: (Array[untyped] items, ?height: Numeric, ?row_height: Numeric, ?selected: untyped, ?label: String?) -> void
560
561
  def on_select: () { (untyped, Input::MouseDown?, FrameContext?) -> void } -> self
561
562
  def on_toggle: () { (untyped, bool) -> void } -> self
562
563
  def on_context_menu: () { (untyped, FrameContext) -> untyped } -> self
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zaniah
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.3
4
+ version: 0.12.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yudai Takada