zaniah 0.11.0 → 0.12.1
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 +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +9 -28
- data/assets/fonts/NotoSans-LICENSE.txt +94 -0
- data/assets/fonts/NotoSans-Regular.ttf +0 -0
- data/docs/_templates/page.erb +123 -0
- data/docs/components.md +13 -5
- data/docs/gallery/command-palette-dark.png +0 -0
- data/docs/gallery/command-palette-light.png +0 -0
- data/docs/gallery/components-dark.png +0 -0
- data/docs/gallery/components-high_contrast.png +0 -0
- data/docs/gallery/components-light.png +0 -0
- data/docs/gallery/dialog-dark.png +0 -0
- data/docs/gallery/dialog-light.png +0 -0
- data/docs/gallery/hover-card-dark.png +0 -0
- data/docs/gallery/hover-card-high_contrast.png +0 -0
- data/docs/gallery/hover-card-light.png +0 -0
- data/docs/gallery/modal-dark.png +0 -0
- data/docs/gallery/modal-light.png +0 -0
- data/docs/gallery/popover-bottom-dark.png +0 -0
- data/docs/gallery/popover-bottom-light.png +0 -0
- data/docs/gallery/popover-left-dark.png +0 -0
- data/docs/gallery/popover-left-high_contrast.png +0 -0
- data/docs/gallery/popover-left-light.png +0 -0
- data/docs/gallery/popover-right-dark.png +0 -0
- data/docs/gallery/popover-right-light.png +0 -0
- data/docs/gallery/popover-top-dark.png +0 -0
- data/docs/gallery/popover-top-light.png +0 -0
- data/docs/gallery/toast-danger-dark.png +0 -0
- data/docs/gallery/toast-danger-light.png +0 -0
- data/docs/gallery/toast-info-dark.png +0 -0
- data/docs/gallery/toast-info-light.png +0 -0
- data/docs/gallery/toast-success-dark.png +0 -0
- data/docs/gallery/toast-success-light.png +0 -0
- data/docs/gallery/toast-warning-dark.png +0 -0
- data/docs/gallery/toast-warning-light.png +0 -0
- data/docs/gallery/tooltip-bottom-dark.png +0 -0
- data/docs/gallery/tooltip-bottom-light.png +0 -0
- data/docs/gallery/tooltip-left-dark.png +0 -0
- data/docs/gallery/tooltip-left-light.png +0 -0
- data/docs/gallery/tooltip-right-dark.png +0 -0
- data/docs/gallery/tooltip-right-light.png +0 -0
- data/docs/gallery/tooltip-top-dark.png +0 -0
- data/docs/gallery/tooltip-top-light.png +0 -0
- data/docs/inspection.md +3 -1
- data/docs/layout.md +0 -8
- data/docs/native.md +12 -17
- data/docs/pages.yml +949 -0
- data/docs/previews/actions.png +0 -0
- data/docs/previews/choices.png +0 -0
- data/docs/previews/command-palette-dark.png +0 -0
- data/docs/previews/data.png +0 -0
- data/docs/previews/dialog-dark.png +0 -0
- data/docs/previews/drawer-right-dark.png +0 -0
- data/docs/previews/editors.png +0 -0
- data/docs/previews/feedback.png +0 -0
- data/docs/previews/forms.png +0 -0
- data/docs/previews/foundation.png +0 -0
- data/docs/previews/grid.png +0 -0
- data/docs/previews/hex-view.png +0 -0
- data/docs/previews/menu-dark.png +0 -0
- data/docs/previews/navigation.png +0 -0
- data/docs/previews/pane-grid.png +0 -0
- data/docs/previews/popover-right-dark.png +0 -0
- data/docs/previews/structure.png +0 -0
- data/docs/previews/text-input.png +0 -0
- data/docs/previews/toast-success-dark.png +0 -0
- data/docs/previews/tooltip-bottom-dark.png +0 -0
- data/docs/previews/values.png +0 -0
- data/docs/previews/variants.png +0 -0
- data/docs/previews/workspace.png +0 -0
- data/docs/process_pool.md +1 -6
- data/docs/site.css +89 -29
- data/docs/text.md +0 -10
- data/docs/tui.md +3 -2
- data/docs/vector_and_list.md +15 -7
- data/examples/gallery.rb +4 -4
- data/lib/zaniah/accessibility/linux/service.rb +1 -1
- data/lib/zaniah/accessibility/mac.rb +1 -0
- data/lib/zaniah/accessibility/node.rb +2 -0
- data/lib/zaniah/accessibility/tree.rb +3 -2
- data/lib/zaniah/accessibility/windows/provider.rb +1 -0
- data/lib/zaniah/gpu/software.rb +26 -8
- data/lib/zaniah/input/dispatcher.rb +6 -0
- data/lib/zaniah/input/keymap.rb +16 -0
- data/lib/zaniah/inspection.rb +9 -2
- data/lib/zaniah/layout/engine.rb +1 -1
- data/lib/zaniah/list/height_index.rb +14 -0
- data/lib/zaniah/list.rb +24 -3
- data/lib/zaniah/platform/file_dialog_options.rb +26 -0
- data/lib/zaniah/platform/headless/window.rb +2 -2
- data/lib/zaniah/platform/linux/window.rb +9 -1
- data/lib/zaniah/platform/mac/window.rb +11 -1
- data/lib/zaniah/platform/windows/window.rb +23 -5
- data/lib/zaniah/scene.rb +2 -2
- data/lib/zaniah/ui/component.rb +3 -1
- data/lib/zaniah/ui/hex_view.rb +185 -0
- data/lib/zaniah/ui/layout_components.rb +9 -1
- data/lib/zaniah/ui/text_inputs.rb +130 -9
- data/lib/zaniah/ui/tree_view.rb +37 -7
- data/lib/zaniah/ui/virtual_table.rb +227 -0
- data/lib/zaniah/ui.rb +2 -0
- data/lib/zaniah/uniform_list.rb +33 -3
- data/lib/zaniah/version.rb +1 -1
- data/sig/elements.rbs +10 -3
- data/sig/gpu.rbs +1 -1
- data/sig/native.rbs +4 -4
- data/sig/ui.rbs +57 -0
- data/tools/build_docs.rb +101 -0
- data/tools/generate_component_gallery.rb +18 -10
- data/tools/generate_doc_previews.rb +69 -0
- metadata +37 -3
- data/docs/index.html +0 -74
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2880a0bf76786c774939df0c5d8c02cc287789607221c6a1739d71b50fcc2248
|
|
4
|
+
data.tar.gz: f2ccf99f464295d8e7af77e61a0b38911f133728b979f868b4ede8ce2f4a5fdd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e1a950ab9299a1a0121469d98310c945b7dbefb611b87f286c28d769fbbcdb3d14fb3cc20d12c135b5620071cbcc1ac75dc3ac083bc4c6c4978558d1fd75fb36
|
|
7
|
+
data.tar.gz: d31dd8cd5722a4bccccdc73f54e0cff07770d1094fe67a5d3ef000f097b950228f8b6a9f9ac05b0adc380d61a393c82ef24b66ff3810ffda3b8fdd8e3a904c8c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.12.1 — 2026-10-02
|
|
4
|
+
|
|
5
|
+
- Prevent obsolete focus controls from accumulating across redraws, reducing memory use and keeping keyboard navigation on current controls.
|
|
6
|
+
|
|
7
|
+
## 0.12.0 — 2026-10-02
|
|
8
|
+
|
|
9
|
+
- Add streaming virtual tables with lazy cells, stable selection, row styling, configurable columns, and tail following.
|
|
10
|
+
- Add virtual hexadecimal and ASCII byte views with linked selection, highlights, keyboard navigation, and copying.
|
|
11
|
+
- Preserve scrolling and height measurements when virtual list counts change, with optional bottom following.
|
|
12
|
+
- Avoid stale rows and duplicated drawing when scrolling keyed virtual lists.
|
|
13
|
+
- Reduce layout work for fixed-size containers and reuse unchanged visible byte rows for faster redraws.
|
|
14
|
+
- Speed up vector recording by reusing resolved paint colors.
|
|
15
|
+
- Add text-field validation states and token completion with keyboard selection and Unicode-safe replacement.
|
|
16
|
+
- Add programmatic tree selection and item context menus.
|
|
17
|
+
- Add suggested filenames, starting directories, and extension filters for native file dialogs.
|
|
18
|
+
- Fix inspection snapshots for nested UI components, including select controls in dialogs.
|
|
19
|
+
- Preserve accessible content and actions inside wrapped split panes.
|
|
20
|
+
|
|
3
21
|
## 0.11.0 — 2026-09-25
|
|
4
22
|
|
|
5
23
|
- Add segmented controls, alerts, hover cards, calendar and date-range inputs.
|
data/README.md
CHANGED
|
@@ -114,7 +114,7 @@ For an interactive window, choose `backend: :mac`, `:linux`, `:windows`, or
|
|
|
114
114
|
| `:tui` | ANSI terminal | Text-grid rendering and terminal input |
|
|
115
115
|
|
|
116
116
|
Native backends use the operating system libraries through Ruby's Fiddle. See
|
|
117
|
-
[Native backends](docs/native.
|
|
117
|
+
[Native backends](https://noxdea.github.io/zaniah/docs/guides/native.html) for platform requirements.
|
|
118
118
|
|
|
119
119
|
Native macOS, Windows, and X11 windows can be moved to a display returned by
|
|
120
120
|
`Zaniah::Platform.displays` with `window.move_to_display(display)`. Headless and
|
|
@@ -124,37 +124,18 @@ compositor to fullscreen on that output, but the compositor may choose otherwise
|
|
|
124
124
|
|
|
125
125
|
## Documentation
|
|
126
126
|
|
|
127
|
-
- [
|
|
128
|
-
- [
|
|
129
|
-
- [
|
|
130
|
-
- [
|
|
131
|
-
- [
|
|
132
|
-
- [
|
|
133
|
-
- [Themes](docs/theme.md) — semantic tokens and state styles
|
|
134
|
-
- [Components](docs/components.md) — controls, overlays, data views, charts, and forms
|
|
135
|
-
- [Animation](docs/animation.md) — easing, springs, transitions, and reduced motion
|
|
136
|
-
- [Accessibility](docs/accessibility.md) — semantic trees, diffs, and native bridges
|
|
137
|
-
- [Terminal UI](docs/tui.md) — deterministic component degradation
|
|
138
|
-
- [CPU process workers](docs/process_pool.md) — portable background CPU work
|
|
139
|
-
- [Declarative elements](docs/describe.md) — validated vocabularies, event routing, diffs, and surfaces
|
|
140
|
-
- [Architecture decisions](docs/adr) — design records and rationale
|
|
127
|
+
- [Getting started](https://noxdea.github.io/zaniah/docs/) — installation and your first render
|
|
128
|
+
- [Guides](https://noxdea.github.io/zaniah/docs/guides/) — platforms, layout, text, themes, accessibility, and advanced APIs
|
|
129
|
+
- [Components](https://noxdea.github.io/zaniah/docs/components/) — rendered examples, code, and API summaries
|
|
130
|
+
- [Component API reference](https://noxdea.github.io/zaniah/docs/guides/component-reference.html) — all constructors and variants in one table
|
|
131
|
+
- [Contributing guidelines](.github/CONTRIBUTING.md) — development and platform checks
|
|
132
|
+
- [Architecture decisions](docs/adr) — implementation rationale
|
|
141
133
|
- [RBS declarations](sig) — public API signatures
|
|
142
134
|
|
|
143
|
-
## Development
|
|
144
|
-
|
|
145
|
-
```sh
|
|
146
|
-
bundle install
|
|
147
|
-
bundle exec rake test
|
|
148
|
-
bundle exec rake bench
|
|
149
|
-
gem build --strict zaniah.gemspec
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Set `BUDGET=1` to enable benchmark assertions.
|
|
153
|
-
|
|
154
135
|
## Contributing
|
|
155
136
|
|
|
156
|
-
Bug reports and pull requests are welcome
|
|
157
|
-
[
|
|
137
|
+
Bug reports and pull requests are welcome. See the
|
|
138
|
+
[contributing guidelines](.github/CONTRIBUTING.md) for checks and documentation updates.
|
|
158
139
|
|
|
159
140
|
## License
|
|
160
141
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Copyright 2018 The Noto Project Authors (github.com/googlei18n/noto-fonts)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License,
|
|
4
|
+
Version 1.1.
|
|
5
|
+
|
|
6
|
+
This license is copied below, and is also available with a FAQ at:
|
|
7
|
+
http://scripts.sil.org/OFL
|
|
8
|
+
|
|
9
|
+
-----------------------------------------------------------
|
|
10
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
11
|
+
-----------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
PREAMBLE
|
|
14
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
15
|
+
development of collaborative font projects, to support the font
|
|
16
|
+
creation efforts of academic and linguistic communities, and to
|
|
17
|
+
provide a free and open framework in which fonts may be shared and
|
|
18
|
+
improved in partnership with others.
|
|
19
|
+
|
|
20
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
21
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
22
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
23
|
+
redistributed and/or sold with any software provided that any reserved
|
|
24
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
25
|
+
however, cannot be released under any other type of license. The
|
|
26
|
+
requirement for fonts to remain under this license does not apply to
|
|
27
|
+
any document created using the fonts or their derivatives.
|
|
28
|
+
|
|
29
|
+
DEFINITIONS
|
|
30
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
31
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
32
|
+
include source files, build scripts and documentation.
|
|
33
|
+
|
|
34
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
35
|
+
copyright statement(s).
|
|
36
|
+
|
|
37
|
+
"Original Version" refers to the collection of Font Software
|
|
38
|
+
components as distributed by the Copyright Holder(s).
|
|
39
|
+
|
|
40
|
+
"Modified Version" refers to any derivative made by adding to,
|
|
41
|
+
deleting, or substituting -- in part or in whole -- any of the
|
|
42
|
+
components of the Original Version, by changing formats or by porting
|
|
43
|
+
the Font Software to a new environment.
|
|
44
|
+
|
|
45
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
46
|
+
writer or other person who contributed to the Font Software.
|
|
47
|
+
|
|
48
|
+
PERMISSION & CONDITIONS
|
|
49
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
50
|
+
a copy of the Font Software, to use, study, copy, merge, embed,
|
|
51
|
+
modify, redistribute, and sell modified and unmodified copies of the
|
|
52
|
+
Font Software, subject to the following conditions:
|
|
53
|
+
|
|
54
|
+
1) Neither the Font Software nor any of its individual components, in
|
|
55
|
+
Original or Modified Versions, may be sold by itself.
|
|
56
|
+
|
|
57
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
58
|
+
redistributed and/or sold with any software, provided that each copy
|
|
59
|
+
contains the above copyright notice and this license. These can be
|
|
60
|
+
included either as stand-alone text files, human-readable headers or
|
|
61
|
+
in the appropriate machine-readable metadata fields within text or
|
|
62
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
63
|
+
|
|
64
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
65
|
+
Name(s) unless explicit written permission is granted by the
|
|
66
|
+
corresponding Copyright Holder. This restriction only applies to the
|
|
67
|
+
primary font name as presented to the users.
|
|
68
|
+
|
|
69
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
70
|
+
Software shall not be used to promote, endorse or advertise any
|
|
71
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
72
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
73
|
+
permission.
|
|
74
|
+
|
|
75
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
76
|
+
must be distributed entirely under this license, and must not be
|
|
77
|
+
distributed under any other license. The requirement for fonts to
|
|
78
|
+
remain under this license does not apply to any document created using
|
|
79
|
+
the Font Software.
|
|
80
|
+
|
|
81
|
+
TERMINATION
|
|
82
|
+
This license becomes null and void if any of the above conditions are
|
|
83
|
+
not met.
|
|
84
|
+
|
|
85
|
+
DISCLAIMER
|
|
86
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
87
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
88
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
89
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
90
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
91
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
92
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
93
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
94
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
Binary file
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<meta name="description" content="<%= h(page.fetch("lead")) %>">
|
|
7
|
+
<meta name="theme-color" content="#0b1220">
|
|
8
|
+
<link rel="canonical" href="https://noxdea.github.io/zaniah/docs/<%= path == "index.html" ? "" : path %>">
|
|
9
|
+
<link rel="stylesheet" href="<%= link_from(path, "site.css") %>">
|
|
10
|
+
<title><%= h(page.fetch("title")) %> · Zaniah Docs</title>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<a class="skip-link" href="#content">Skip to content</a>
|
|
14
|
+
<header class="site-header">
|
|
15
|
+
<div class="header-inner">
|
|
16
|
+
<a class="brand" href="<%= link_from(path, "index.html") %>" aria-label="Zaniah documentation home"><span class="brand-symbol" aria-hidden="true">Z</span><span>Zaniah <small>Docs</small></span></a>
|
|
17
|
+
<nav class="header-links" aria-label="Global navigation">
|
|
18
|
+
<a href="<%= link_from(path, "index.html") %>">Docs</a>
|
|
19
|
+
<a href="<%= link_from(path, "guides/index.html") %>">Guides</a>
|
|
20
|
+
<a href="<%= link_from(path, "components/index.html") %>">Components</a>
|
|
21
|
+
<a href="https://github.com/noxdea/zaniah">GitHub</a>
|
|
22
|
+
</nav>
|
|
23
|
+
</div>
|
|
24
|
+
</header>
|
|
25
|
+
|
|
26
|
+
<div class="docs-shell">
|
|
27
|
+
<aside class="sidebar" aria-label="Documentation navigation">
|
|
28
|
+
<% groups.each do |group, items| %>
|
|
29
|
+
<div class="nav-group"><h2><%= h(group) %></h2>
|
|
30
|
+
<% items.each do |item| %>
|
|
31
|
+
<a href="<%= link_from(path, item.fetch("path")) %>"<%= ' aria-current="page"' if item["path"] == path %>><%= h(item.fetch("title")) %></a>
|
|
32
|
+
<% end %>
|
|
33
|
+
</div>
|
|
34
|
+
<% end %>
|
|
35
|
+
</aside>
|
|
36
|
+
|
|
37
|
+
<main id="content" class="content">
|
|
38
|
+
<details class="mobile-nav"><summary>Browse documentation</summary><nav aria-label="Mobile documentation navigation">
|
|
39
|
+
<% groups.each do |group, items| %>
|
|
40
|
+
<strong><%= h(group) %></strong>
|
|
41
|
+
<% items.each do |item| %>
|
|
42
|
+
<a href="<%= link_from(path, item.fetch("path")) %>"<%= ' aria-current="page"' if item["path"] == path %>><%= h(item.fetch("title")) %></a>
|
|
43
|
+
<% end %>
|
|
44
|
+
<% end %>
|
|
45
|
+
</nav></details>
|
|
46
|
+
<div class="page-heading">
|
|
47
|
+
<p class="breadcrumb"><a href="<%= link_from(path, "index.html") %>">Docs</a><span aria-hidden="true">/</span><%= h(page.fetch("group")) %></p>
|
|
48
|
+
<h1><%= h(page.fetch("title")) %></h1>
|
|
49
|
+
<p class="lead"><%= inline(page.fetch("lead")) %></p>
|
|
50
|
+
</div>
|
|
51
|
+
<% if page["kind"] == "component" %>
|
|
52
|
+
<section class="doc-section" id="import"><h2>Import</h2>
|
|
53
|
+
<p>Load the optional component layer before using the examples below.</p>
|
|
54
|
+
<div class="code-example"><div class="code-label">Ruby</div><pre><code>require "zaniah/ui"</code></pre></div>
|
|
55
|
+
</section>
|
|
56
|
+
<% end %>
|
|
57
|
+
|
|
58
|
+
<% if page["kind"] == "index" %>
|
|
59
|
+
<% index_groups.each do |group| %>
|
|
60
|
+
<% items = groups.fetch(group) %>
|
|
61
|
+
<% items = items.reject { |item| item["kind"] == "index" } %>
|
|
62
|
+
<section class="doc-section" id="<%= h(group.downcase.gsub(/[^a-z0-9]+/, "-")) %>">
|
|
63
|
+
<h2><%= h(group) %></h2>
|
|
64
|
+
<div class="directory">
|
|
65
|
+
<% items.each do |item| %>
|
|
66
|
+
<a href="<%= link_from(path, item.fetch("path")) %>"><strong><%= h(item.fetch("title")) %></strong><span><%= h(item.fetch("lead")) %></span></a>
|
|
67
|
+
<% end %>
|
|
68
|
+
</div>
|
|
69
|
+
</section>
|
|
70
|
+
<% end %>
|
|
71
|
+
<% elsif page["kind"] == "markdown" %>
|
|
72
|
+
<article class="markdown"><%= guide_html %></article>
|
|
73
|
+
<% else %>
|
|
74
|
+
<% page.fetch("sections", []).each do |section| %>
|
|
75
|
+
<section class="doc-section" id="<%= section_id(section) %>">
|
|
76
|
+
<h2><%= h(section.fetch("heading")) %></h2>
|
|
77
|
+
<% Array(section["text"]).each do |paragraph| %><p><%= inline(paragraph) %></p><% end %>
|
|
78
|
+
<% if section["image"] %>
|
|
79
|
+
<% image_width, image_height = image_dimensions(section.fetch("image")) %>
|
|
80
|
+
<figure class="example"><div class="example-label">Rendered example</div><img src="<%= link_from(path, section.fetch("image")) %>" alt="<%= h(section.fetch("alt")) %>" width="<%= image_width %>" height="<%= image_height %>" loading="lazy"><figcaption>Rendered by Zaniah's headless backend.</figcaption></figure>
|
|
81
|
+
<% end %>
|
|
82
|
+
<% if section["code"] %>
|
|
83
|
+
<div class="code-example"><div class="code-label"><%= h(section.fetch("code_label", "Ruby")) %></div><pre><code><%= h(section.fetch("code")) %></code></pre></div>
|
|
84
|
+
<% end %>
|
|
85
|
+
<% if section["note"] %><p class="note"><%= inline(section.fetch("note")) %></p><% end %>
|
|
86
|
+
</section>
|
|
87
|
+
<% end %>
|
|
88
|
+
<% if page["kind"] == "component" %>
|
|
89
|
+
<section class="doc-section" id="api"><h2>API summary</h2><p>Constructor options and behaviors are drawn from the <a href="<%= link_from(path, "guides/component-reference.html") %>">component reference</a>.</p>
|
|
90
|
+
<div class="table-scroll"><table><thead><tr><th>Component</th><th>Constructor and methods</th><th>Variants or behavior</th></tr></thead><tbody>
|
|
91
|
+
<% rows.each do |row| %><tr><td><code><%= h(row[:names].join(", ")) %></code></td><td><%= inline(row[:constructor]) %></td><td><%= inline(row[:variants]) %></td></tr><% end %>
|
|
92
|
+
</tbody></table></div>
|
|
93
|
+
</section>
|
|
94
|
+
<section class="doc-section" id="accessibility"><h2>Accessibility</h2>
|
|
95
|
+
<% if page["a11y"] %><p><%= inline(page["a11y"]) %></p><% end %>
|
|
96
|
+
<div class="table-scroll"><table><thead><tr><th>Component</th><th>Semantic role</th></tr></thead><tbody>
|
|
97
|
+
<% rows.each do |row| %><tr><td><code><%= h(row[:names].join(", ")) %></code></td><td><%= h(row[:role]) %></td></tr><% end %>
|
|
98
|
+
</tbody></table></div>
|
|
99
|
+
</section>
|
|
100
|
+
<% end %>
|
|
101
|
+
<% end %>
|
|
102
|
+
|
|
103
|
+
<nav class="pagination" aria-label="Adjacent pages">
|
|
104
|
+
<% if previous_page %><a href="<%= link_from(path, previous_page.fetch("path")) %>"><small>Previous</small><strong><%= h(previous_page.fetch("title")) %></strong></a><% end %>
|
|
105
|
+
<% if next_page %><a href="<%= link_from(path, next_page.fetch("path")) %>"><small>Next</small><strong><%= h(next_page.fetch("title")) %></strong></a><% end %>
|
|
106
|
+
</nav>
|
|
107
|
+
</main>
|
|
108
|
+
|
|
109
|
+
<aside class="toc" aria-label="On this page"><p>On this page</p>
|
|
110
|
+
<% if page["kind"] == "index" %>
|
|
111
|
+
<% index_groups.each do |group| %><a href="#<%= h(group.downcase.gsub(/[^a-z0-9]+/, "-")) %>"><%= h(group) %></a><% end %>
|
|
112
|
+
<% elsif page["kind"] == "markdown" %>
|
|
113
|
+
<% guide_toc.each do |anchor, heading| %><a href="#<%= h(anchor) %>"><%= heading %></a><% end %>
|
|
114
|
+
<% else %>
|
|
115
|
+
<% if page["kind"] == "component" %><a href="#import">Import</a><% end %>
|
|
116
|
+
<% page.fetch("sections", []).each do |section| %><a href="#<%= section_id(section) %>"><%= h(section.fetch("heading")) %></a><% end %>
|
|
117
|
+
<% if page["kind"] == "component" %><a href="#api">API summary</a><a href="#accessibility">Accessibility</a><% end %>
|
|
118
|
+
<% end %>
|
|
119
|
+
</aside>
|
|
120
|
+
</div>
|
|
121
|
+
<footer class="site-footer"><span>Zaniah is open source under the MIT License.</span><a href="https://github.com/noxdea/zaniah">Source on GitHub</a></footer>
|
|
122
|
+
</body>
|
|
123
|
+
</html>
|
data/docs/components.md
CHANGED
|
@@ -21,10 +21,21 @@ Zaniah::UI::Button.variants[:variant][:brand] = ->(theme) {
|
|
|
21
21
|
}
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
`VirtualTable`, `HexView`, and `TreeView` accept `viewport_height=` when a window
|
|
25
|
+
or split pane resizes. This updates their internal list viewport while retaining
|
|
26
|
+
scroll state and selection. `VirtualTable#follow_tail=` toggles bottom following;
|
|
27
|
+
call `scroll_to(source.count - 1, align: :end)` to resume immediately from elsewhere.
|
|
28
|
+
|
|
29
|
+
`TreeView#on_context_menu { |item, cx| menu }` selects the item under a right
|
|
30
|
+
click before opening the returned menu at the pointer. The callback receives the
|
|
31
|
+
same item value as `on_select`.
|
|
32
|
+
|
|
24
33
|
## Component reference
|
|
25
34
|
|
|
26
35
|
| Layer | Component | Main constructor/options | Variants | Accessibility role |
|
|
27
36
|
| --- | --- | --- | --- | --- |
|
|
37
|
+
| L4 | `VirtualTable` | `(source, columns:, height:, row_height:, selection:, follow_tail:)`; lazy `count`/`cell` source | stable row IDs, sortable/resizable headers, column visibility/order, row colors | table |
|
|
38
|
+
| L4 | `HexView` | `(bytes, bytes_per_row:, group:, offset_digits:, height:)`; `highlights=`, `select`, `scroll_to_offset` | viewport rows; synchronized hex/ASCII selection and copying | group |
|
|
28
39
|
| L0 | `Label` | `(text, tone:, size:, wrap:)` | tone: default/muted/inverse; size: xs–xl | text |
|
|
29
40
|
| L0 | `Icon` | `(source, size:, color:, label:)` | bundled: check/close/search/menu/info/warning | image when labeled |
|
|
30
41
|
| L0 | `Divider` | `(axis:)` | horizontal/vertical | separator |
|
|
@@ -56,7 +67,7 @@ Zaniah::UI::Button.variants[:variant][:brand] = ->(theme) {
|
|
|
56
67
|
| L2 | `ContextMenu`, `Menu` | `(items, anchor:, open:)` | pointer + arrows/Home/End/Enter/Esc | menu/menuitem |
|
|
57
68
|
| L2 | `MenuBar` | `(menus)` or `.from(app.menu_bar)` | declarative menu model or legacy pairs | menubar |
|
|
58
69
|
| L2 | `Dropdown` | `(label, items:, value:)`; `on_change` | menu-backed | button |
|
|
59
|
-
| L2 | `TextField` | `(value, placeholder:, label:, prefix:, suffix:, error:, max_length:, clearable:)` | IME, selection, counter | textbox |
|
|
70
|
+
| L2 | `TextField` | `(value, placeholder:, label:, prefix:, suffix:, error:, max_length:, clearable:)`; `status(kind, message:)`, `completion(provider)` | IME, selection, counter, validation, token completion | textbox |
|
|
60
71
|
| L2 | `TextArea` | TextField plus `rows:` | multiline/wrapped | textbox/multiline |
|
|
61
72
|
| L2 | `SearchInput` | TextField options | search + clear icons | searchbox |
|
|
62
73
|
| L2 | `PasswordInput` | TextField options | masked display | textbox |
|
|
@@ -93,7 +104,7 @@ Zaniah::UI::Button.variants[:variant][:brand] = ->(theme) {
|
|
|
93
104
|
| L3 | `ListView` | `(items, height:, row_height:, selected:)`; `on_select` | virtual rows and keyboard selection | list/listitem |
|
|
94
105
|
| L4 | `Table`, `DataGrid` | `(rows, columns:, height:, selection:, row_key:)`; `on_sort`, `on_select`, `on_edit`, `on_copy`, `on_paste` | virtual rows, sorting, resizing, editing, typed clipboard hooks | table/row/cell |
|
|
95
106
|
| L4 | `Grid` | `(rows:, columns:, row_height:, column_width:, frozen_rows:, frozen_columns:)`; `scroll_to`, range `selection`, `on_select`, `on_edit`, `on_fill`, `on_resize`, `on_copy`, `on_paste` | two-axis virtualization, frozen panes, visible-cell resize/fill and typed clipboard hooks | table |
|
|
96
|
-
| L4 | `TreeView` | `(items, height:, selected:)`; `expand`, `collapse`, `replace`, `replace_children`, `invalidate`, lazy `children` proc | arrows/Home/End | tree/treeitem |
|
|
107
|
+
| L4 | `TreeView` | `(items, height:, selected:)`; `select_id`, `on_context_menu`, `expand`, `collapse`, `replace`, `replace_children`, `invalidate`, lazy `children` proc | arrows/Home/End | tree/treeitem |
|
|
97
108
|
| L4 | `PropertyGrid` | `(schema, values, height:, row_height:)`; `on_change`, `set` | typed existing controls, `Validation`, virtual rows | table/row/cell |
|
|
98
109
|
| L5 | `Sparkline` | `(values, width:, height:, color:, label:)` | line + tooltip | image |
|
|
99
110
|
| L5 | `LineChart`, `BarChart`, `StackedBarChart`, `AreaChart` | `(series, width:, height:, colors:, label:)`; `AreaChart(stacked:)` | shared axes, ticks, grid lines, color-keyed legend, tooltip | image |
|
|
@@ -199,6 +210,3 @@ resize. Grid and Table clipboard hooks receive half-open `Grid::Area` ranges;
|
|
|
199
210
|
Table areas follow the current display order without changing its stable-ID
|
|
200
211
|
selection. See [Layout](layout.md#two-axis-virtual-grid). Tree views use Up/Down to select, Right to expand or enter the first child,
|
|
201
212
|
and Left to collapse or return to the parent.
|
|
202
|
-
|
|
203
|
-
Run `bundle exec ruby tools/generate_component_gallery.rb` to rebuild the dark,
|
|
204
|
-
light, and high-contrast component sheets plus overlay variants in all three themes.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/docs/gallery/modal-dark.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/docs/inspection.md
CHANGED
|
@@ -16,4 +16,6 @@ Zaniah::Inspection.perform(window, node, :press)
|
|
|
16
16
|
|
|
17
17
|
The snapshot containers and copied collections are frozen. `entry.element` is deliberately a live element reference: use it only in the same frame, because the next render may replace it. Accessibility nodes are copied for inspection; pass one to `Inspection.perform` to invoke an action on its current source node. Actions require a node from the current frame. To wait for a settled UI, call `Zaniah::Inspection.idle?(app)` after draining queued work and rendering dirty windows.
|
|
18
18
|
|
|
19
|
-
The public API is declared in [`sig/inspection.rbs`](../sig/inspection.rbs)
|
|
19
|
+
The public API is declared in [`sig/inspection.rbs`](../sig/inspection.rbs).
|
|
20
|
+
Breaking changes receive at least one minor version of deprecation during 0.x,
|
|
21
|
+
as recorded in [ADR 013](adr/013-public-inspection-api.md).
|
data/docs/layout.md
CHANGED
|
@@ -96,14 +96,6 @@ remains a set of stable row IDs; hook arguments are `Grid::Area` ranges in the
|
|
|
96
96
|
current sorted display order, covering all columns. Disjoint selected rows
|
|
97
97
|
produce separate areas. The application retains ownership of table data.
|
|
98
98
|
|
|
99
|
-
`bench/grid.rb` measures a headless 800×600 viewport over a 1,000,000×16,000
|
|
100
|
-
grid at 23 sequential scroll positions, including cell construction, layout,
|
|
101
|
-
prepaint, and paint. `BUDGET=1 ruby bench/grid.rb` asserts a 16.67 ms median
|
|
102
|
-
frame limit. A local run on 2026-09-23 measured 12.964 ms and constructed an
|
|
103
|
-
average of 250 cells per frame. This microbenchmark does not include an
|
|
104
|
-
application's backing store, expensive cell renderers, or a native compositor;
|
|
105
|
-
rerun it on target hardware for deployment decisions.
|
|
106
|
-
|
|
107
99
|
`ScrollView` accepts one child and clips it to the viewport. Its `axis` is
|
|
108
100
|
`:vertical`, `:horizontal`, or `:both`; use `scroll_to` for programmatic
|
|
109
101
|
scrolling and `scroll_state` for offsets and edge checks.
|
data/docs/native.md
CHANGED
|
@@ -42,6 +42,18 @@ file drops, fullscreen, cursors, URL opening, file dialogs, appearance changes,
|
|
|
42
42
|
and PNG capture. Platform availability differs; see [the RBS declarations](../sig/native.rbs)
|
|
43
43
|
and [platform declarations](../sig/platform.rbs) for the exact API.
|
|
44
44
|
|
|
45
|
+
## File dialogs
|
|
46
|
+
|
|
47
|
+
Native file dialogs accept a starting directory, suggested filename, and extension filters:
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
window.prompt_for_paths(save: true, default_name: "capture.pcapng", directory: Dir.home,
|
|
51
|
+
filters: [{label: "Capture files", patterns: ["*.pcapng", "*.pcap"]}])
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Patterns support `*` and `*.extension`. macOS combines the allowed extensions;
|
|
55
|
+
Linux and Windows also show each named filter. Cancel returns an empty array.
|
|
56
|
+
|
|
45
57
|
## Clipboard representations
|
|
46
58
|
|
|
47
59
|
`Clipboard::Item` holds eager MIME-keyed data. `text/*` values are UTF-8 text;
|
|
@@ -145,20 +157,3 @@ On Windows, require `zaniah/platform/windows/terminal` to use
|
|
|
145
157
|
`Zaniah::Platform::Windows::Terminal`, which wraps ConPTY. It supports starting
|
|
146
158
|
a child process, nonblocking reads, writes, resizing, liveness checks, and
|
|
147
159
|
explicit cleanup. ConPTY requires Windows 10 version 1809 or later.
|
|
148
|
-
|
|
149
|
-
## Development checks
|
|
150
|
-
|
|
151
|
-
Run checks on the matching host and display server:
|
|
152
|
-
|
|
153
|
-
```sh
|
|
154
|
-
ruby examples/native_smoke.rb --check /tmp/zaniah.png
|
|
155
|
-
ruby examples/native_smoke.rb --gl --check /tmp/zaniah-gl.png
|
|
156
|
-
ruby examples/linux_smoke.rb
|
|
157
|
-
ruby examples/linux_smoke.rb --wayland
|
|
158
|
-
ruby examples/native_watch.rb
|
|
159
|
-
ruby examples/native_menu.rb # macOS only
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Linux XIM composition is exercised in CI with Xvfb and IBus/KKC. Native input,
|
|
163
|
-
IME on macOS and Windows, dialogs, and terminal integration also require manual
|
|
164
|
-
checks on the target operating system.
|