|
1 | | -# Supported Tags (v0.4+) |
| 1 | +# Supported Tags |
2 | 2 |
|
3 | 3 | > Starting with 0.5 some tags support attributes. |
4 | 4 | > Unknown attributes result in `compile_error!`. |
5 | | -
|
6 | | -### `Hyperlink` |
7 | | -Clickable link widget. Generates `ui.hyperlink(url)` or `ui.hyperlink_to(label, url)`. |
8 | | - |
9 | | -**Attributes** |
10 | | - |
11 | | -- `url="..."` — destination address (string, required). |
12 | | -- `open_external="true|false"` — open link in system browser (default true). |
13 | | -- `color="name|#RRGGBB[AA]"` — link text color. |
14 | | -- `underline="true|false"` — underline link text (default true). |
15 | | -- `tooltip="text"` — hover tooltip. |
16 | | - |
17 | | -Cross-platform usage |
18 | | - |
19 | | -- **Web:** renders as standard `<a>` link. |
20 | | -- **Desktop (eframe, bevy_egui):** opens system browser via `ui.hyperlink(...)`. |
21 | | -- **Game/tool overlays:** convenient way to link to docs, repos, or help. |
22 | | -- **Offline apps:** with custom URL schemes (e.g. `help://topic`) may open in-app help instead of browser. |
23 | | - |
24 | | -```rust |
25 | | -use efx_core::doc_prelude::*; |
26 | | -use efx::*; |
27 | | - |
28 | | -efx!(Ui::default(), r##" |
29 | | - <Column> |
30 | | - <Hyperlink url="https://efxui.com" color="#66CCFF" tooltip="Project site"/> |
31 | | - <Hyperlink url="help://about" open_external="false">About</Hyperlink> |
32 | | - </Column> |
33 | | -"##); |
34 | | -``` |
35 | | - |
36 | | ---- |
37 | | - |
38 | | -### `TextField` |
39 | | -Single-line or multi-line text input. Generates `egui::TextEdit` and inserts it via `ui.add(...)`. Must be self-closing (no children). |
40 | | - |
41 | | -**Attributes** |
42 | | - |
43 | | -- `value="<expr>"` — **required**. Rust lvalue expression of type `String`, e.g. `state.name`. The generator takes `&mut (<expr>)` automatically. |
44 | | -- `hint="text"` — placeholder text shown when empty. |
45 | | -- `password="true|false"` — mask characters (applies to single-line; ignored with `multiline="true"`). |
46 | | -- `width="N"` — desired width in points (f32). |
47 | | -- `multiline="true|false"` — multi-line editor (`TextEdit::multiline`). |
48 | | - |
49 | | -```rust |
50 | | -use efx_core::doc_prelude::*; |
51 | | -use efx::*; |
52 | | - |
53 | | -#[derive(Default)] |
54 | | -struct State { name: String } |
55 | | - |
56 | | -let mut state = State::default(); |
57 | | - |
58 | | -// Single-line with placeholder and width |
59 | | -efx!(Ui::default(), r#"<TextField value="state.name" hint="Your name" width="220"/>"#); |
60 | | - |
61 | | -// Password field (single-line) |
62 | | -efx!(Ui::default(), r#"<TextField value="state.name" password="true"/>"#); |
63 | | - |
64 | | -// Multiline editor |
65 | | -efx!(Ui::default(), r#"<TextField value="state.name" multiline="true" width="320"/>"#); |
66 | | -``` |
67 | | - |
68 | | ---- |
69 | | - |
70 | | -### `<Resize>` |
71 | | - |
72 | | -A resizable container that lets the user drag a handle to change the size of its content. |
73 | | -Useful for side views, inspectors, consoles, etc., when a full docked panel is too heavy. |
74 | | - |
75 | | -**Children:** rendered inside the resizable area. |
76 | | - |
77 | | -**Required attributes** |
78 | | -- `id="string"` — egui `Id` salt to persist the size across frames. |
79 | | - |
80 | | -**Behavior** |
81 | | -- `resizable="true|false"` — enable/disable user resizing (default: `true` in egui). |
82 | | - |
83 | | -**Sizing** |
84 | | -- `default-width="number"`, `default-height="number"` — initial size. |
85 | | -- `min-width="number"`, `min-height="number"` — lower bounds. |
86 | | -- `max-width="number"`, `max-height="number"` — upper bounds. |
87 | | - |
88 | | -> Each dimension is optional. If only one dimension is provided, the other falls back to `0.0` (for min/default) or `∞` (for max). |
89 | | -
|
90 | | -**Example** |
91 | | -```xml |
92 | | -<CentralPanel fill="#101014"> |
93 | | - <Resize id="console" default-height="200" min-height="120"> |
94 | | - <ScrollArea axis="vertical" max_height="9999" id="console-scroll"> |
95 | | - <Column gap="6" padding="6"> |
96 | | - <Label monospace="true">[12:00:01] Ready.</Label> |
97 | | - <Label monospace="true">[12:00:02] Build succeeded.</Label> |
98 | | - </Column> |
99 | | - </ScrollArea> |
100 | | - </Resize> |
101 | | -</CentralPanel> |
102 | | -``` |
103 | | - |
104 | | ---- |
105 | | - |
106 | | -### `Heading` |
107 | | - |
108 | | -Text heading. Generates `ui.heading(text)` with optional style overrides. |
109 | | - |
110 | | -**Attributes** |
111 | | - |
112 | | -- `level="1..6"` — heading level (integer). |
113 | | - *Default:* `1`. Maps to predefined `egui` text styles. |
114 | | -- `size="N"` — overrides the font size (f32). |
115 | | -- `color="name|#RRGGBB[AA]"` — text color. |
116 | | -- `tooltip="text"` — hover tooltip. |
117 | | - |
118 | | -```rust |
119 | | -use efx_core::doc_prelude::*; |
120 | | -use efx::*; |
121 | | - |
122 | | -efx!(Ui::default(), r##" |
123 | | - <Column gap="8"> |
124 | | - <Heading level="1">Main title</Heading> |
125 | | - <Heading level="2" color="#66CCFF">Section</Heading> |
126 | | - <Heading level="3" size="14" tooltip="Subheading">Small note</Heading> |
127 | | - </Column> |
128 | | -"##); |
129 | | -``` |
130 | | -The level attribute controls the base style (h1–h6), while size and color can further adjust the appearance. |
131 | | - |
132 | | ---- |
133 | | - |
134 | | -## `<Image>` |
135 | | - |
136 | | -Display a bitmap/texture in the UI. Works both with a preloaded texture handle/id (recommended for desktop) and with a URI-like source (useful on web or when you have your own loader). |
137 | | - |
138 | | -### Syntax |
139 | | - |
140 | | -```xml |
141 | | -<Image |
142 | | - texture="self.logo_tex_id" |
143 | | - width="128" |
144 | | - height="128" |
145 | | - rounding="6" |
146 | | - clickable="true" |
147 | | - tooltip="Click to open" |
148 | | -/> |
149 | | -``` |
150 | | - |
151 | | -or |
152 | | - |
153 | | -```xml |
154 | | -<Image |
155 | | - src="assets/logo.png" |
156 | | - max-width="256" |
157 | | - maintain-aspect="true" |
158 | | - id="logo-1" |
159 | | -/> |
160 | | -``` |
161 | | - |
162 | | -### Attributes |
163 | | - |
164 | | -| Name | Type | Default | Description | |
165 | | -|-------------------|------------------------------------------------------------------------------|---------|-----------------------------------------------------------------------| |
166 | | -| `texture` | **expr** (`egui::TextureId`, `&egui::TextureHandle`, or `egui::ImageSource`) | — | Source texture/handle. Mutually exclusive with `src`. | |
167 | | -| `src` | string (URI/path) | — | Image URI/path. Mutually exclusive with `texture`. | |
168 | | -| `width` | f32 | — | Target width. If both `width` and `height` are set, uses exact size. | |
169 | | -| `height` | f32 | — | Target height. If both `width` and `height` are set, uses exact size. | |
170 | | -| `max-width` | f32 | `∞` | Max width (used if exact size isn’t specified). | |
171 | | -| `max-height` | f32 | `∞` | Max height (used if exact size isn’t specified). | |
172 | | -| `maintain-aspect` | bool | `false` | Keep original aspect ratio when fitting. | |
173 | | -| `rounding` | u8 | — | Uniform corner radius. | |
174 | | -| `tint` | color | — | Multiplies image color (e.g. `#FFFFFF80` for 50% fade). | |
175 | | -| `bg-fill` | color | — | Background fill behind the image rect. | |
176 | | -| `id` | string | — | Stable id seed (`id_source`) for consistent layout/caching. | |
177 | | -| `clickable` | bool | `false` | If `true`, image responds to clicks (`Sense::click`). | |
178 | | -| `tooltip` | string | — | Hover text shown on the image. | |
179 | | - |
180 | | -> Either `texture` **or** `src` must be provided (not both). `<Image>` does not accept children. |
181 | | -
|
182 | | -### Behavior & sizing rules |
183 | | - |
184 | | -* **Exact size**: if both `width` and `height` are set → the image is fit to that exact `vec2(width, height)`. |
185 | | -* **Max size**: otherwise, a max box is computed from `max-width`/`max-height` (falling back to `width`/`height` if only one side is provided). |
186 | | -* **Aspect**: `maintain-aspect="true"` keeps the original ratio when fitting. |
187 | | -* **Interactivity**: with `clickable="true"` the tag returns a normal `Response` you can query (`.clicked()`, etc.). Tooltips are applied via `on_hover_text`. |
188 | | - |
189 | | -### Examples |
190 | | - |
191 | | -**URI/path source (web / custom loader):** |
192 | | - |
193 | | -```xml |
194 | | -<Image src="assets/logo.png" max-width="200" maintain-aspect="true" id="logo-main"/> |
195 | | -``` |
196 | | - |
197 | | -**Tint + background fill:** |
198 | | - |
199 | | -```xml |
200 | | -<Image texture="self.icon_tex" tint="#FFFFFFCC" bg-fill="#00000022" rounding="4"/> |
201 | | -``` |
202 | | - |
203 | | -### Notes |
204 | | - |
205 | | -* `rounding` is uniform; per-corner radii can be added later if needed. |
206 | | -* `id` helps egui keep the same widget identity across frames when the source is otherwise dynamic. |
207 | | -* On desktop, prefer `texture` with a previously allocated `TextureId`/`TextureHandle` for performance and control. On web, `src` can be convenient alongside your asset loader. |
208 | | - |
209 | | ---- |
210 | | - |
211 | | -## `<Tabs>` and `<Tab>` |
212 | | - |
213 | | -Tabbed container. Controlled via a string-like `active` binding that holds the id of the currently selected tab. |
214 | | - |
215 | | -**Syntax** |
216 | | -```xml |
217 | | -<Tabs active="self.active_tab" gap="8"> |
218 | | - <Tab id="home" title="Home"> |
219 | | - <Label>Welcome home!</Label> |
220 | | - </Tab> |
221 | | - <Tab id="logs" title="Logs"> |
222 | | - <ScrollArea axis="vertical" max-height="180"> |
223 | | - <Label monospace="true">[12:00:01] Ready.</Label> |
224 | | - </ScrollArea> |
225 | | - </Tab> |
226 | | - <Tab id="about" title="About" enabled="false"> |
227 | | - <Label>This tab is disabled</Label> |
228 | | - </Tab> |
229 | | -</Tabs> |
230 | | -``` |
231 | | - |
232 | | -**Attributes – `<Tabs>`** |
233 | | - |
234 | | -| Name | Type | Default | Description | |
235 | | -|----------|------|-------------------------------|--------------------------------------------------------------------------------| |
236 | | -| `active` | expr | required | String/\&str expression with the id of the active tab (`"home"`, `"logs"`, …). | |
237 | | -| `gap` | f32 | `ui.spacing().item_spacing.x` | Space between tab headers (px). | |
238 | | - |
239 | | -**Attributes – `<Tab>`** |
240 | | - |
241 | | -| Name | Type | Default | Description | |
242 | | -|-----------|--------|---------|------------------------------------------------------------------| |
243 | | -| `id` | string | — | Unique tab id. Used for matching and as default title. | |
244 | | -| `title` | string | `id` | Header text. | |
245 | | -| `enabled` | bool | `true` | When `false`, the tab header is disabled and cannot be selected. | |
246 | | - |
247 | | -**Behavior** |
248 | | - |
249 | | -- Clicking a tab header updates active to that tab’s `id`. You can read `active` from your state to switch content. |
250 | | - |
251 | | -- `<Tab>` is only allowed as a child of `<Tabs>` and may contain any regular EFx content in its body. |
252 | | - |
253 | | -- Returns `()` (container). |
254 | | - |
255 | | ---- |
256 | | - |
257 | | -## `<Table>`, `<Tr>`, `<Td>` |
258 | | - |
259 | | -Lightweight tables built on top of `egui::Grid`. Suitable for most static layouts. For resizable/feature-rich tables we plan a `<DataTable>` based on `egui_extras::TableBuilder` (future work). |
260 | | - |
261 | | -**Syntax** |
262 | | -```xml |
263 | | -<Table columns="3" striped="true" spacing-x="8" spacing-y="4" cell-align="left" cell-padding="4" id="users"> |
264 | | - <Tr> |
265 | | - <Td><Label bold="true">Name</Label></Td> |
266 | | - <Td><Label bold="true">Email</Label></Td> |
267 | | - <Td><Label bold="true">Role</Label></Td> |
268 | | - </Tr> |
269 | | - |
270 | | - <Tr> |
271 | | - <Td><Label>Alice</Label></Td> |
272 | | - < Td>< Label> [email protected]</ Label></ Td> |
273 | | - <Td><Label>Admin</Label></Td> |
274 | | - </Tr> |
275 | | -</Table> |
276 | | -``` |
277 | | - |
278 | | -**Attributes – `<Table>`** |
279 | | - |
280 | | -| Name | Type | Default | Description | |
281 | | -|----------------|--------|----------|--------------------------------------------------| |
282 | | -| `columns` | int | required | Number of columns (must be ≥ 1). | |
283 | | -| `striped` | bool | `false` | Alternate row background. | |
284 | | -| `spacing-x` | f32 | `8` | Horizontal spacing between columns (px). | |
285 | | -| `spacing-y` | f32 | `4` | Vertical spacing between rows (px). | |
286 | | -| `cell-padding` | f32 | `0` | Padding inside each cell (px). | |
287 | | -| `cell-align` | enum | `left` | Horizontal alignment: `left`, `center`, `right`. | |
288 | | -| `id` | string | — | Stable id for grid instance. | |
289 | | - |
290 | | -**Rules** |
291 | | - |
292 | | -- Only `<Tr>` children are allowed inside `<Table>`. |
293 | | -- `<Tr>` may only contain `<Td>` elements. |
294 | | -- `colspan` / `rowspan` are not supported in this version (a compile error is emitted if used). |
295 | | - |
296 | | -Returns `()` (container). Content inside `<Td>` can be any EFx widgets. |
297 | | - |
298 | | -**Notes** |
299 | | - |
300 | | -- This implementation uses `egui::Grid` to keep dependencies minimal and performance high. |
301 | | -- If you need column resizing, multi-row headers, scrolling inside the table, etc., we’ll introduce a `<DataTable>` tag based on `egui_extras::TableBuilder` behind an optional feature flag in a follow-up. |
302 | | - |
303 | | ---- |
304 | | - |
305 | | -## `<DataTable>` (requires `features = ["extras"]`) |
306 | | - |
307 | | -Feature-rich table built on top of `egui_extras::TableBuilder`. |
308 | | - |
309 | | -**Columns** |
310 | | -Declare columns via `<Columns>` and `<Column>`: |
311 | | -- `mode="auto|initial|exact|remainder"` |
312 | | -- `width="..."` (required for `initial` / `exact`) |
313 | | -- `resizable="true|false"` (defaults to table’s `default-resizable`) |
314 | | -- `clip="true|false"` |
315 | | - |
316 | | -**Header** |
317 | | -Single header row specified via `<Header>` with `<Td>` children (one per column). |
318 | | - |
319 | | -**Body** |
320 | | -Body consists of `<Tr>` rows with `<Td>` cells (missing cells are filled with blanks). Per-row height can be set via `height` on `<Tr>`. |
321 | | - |
322 | | -**Example** |
323 | | -```xml |
324 | | -<DataTable id="users" striped="true" resizable="true" |
325 | | - default-resizable="true" header-height="24" row-height="22" |
326 | | - cell-align="left" cell-padding="4"> |
327 | | - <Columns> |
328 | | - <Column mode="initial" width="160" resizable="true"/> |
329 | | - <Column mode="auto"/> |
330 | | - <Column mode="remainder" resizable="true" clip="true"/> |
331 | | - </Columns> |
332 | | - |
333 | | - <Header> |
334 | | - <Td><Label bold="true">Name</Label></Td> |
335 | | - <Td><Label bold="true">Email</Label></Td> |
336 | | - <Td><Label bold="true">Role</Label></Td> |
337 | | - </Header> |
338 | | - |
339 | | - <Tr> |
340 | | - <Td><Label>Alice</Label></Td> |
341 | | - < Td>< Label> [email protected]</ Label></ Td> |
342 | | - <Td><Label>Admin</Label></Td> |
343 | | - </Tr> |
344 | | - |
345 | | - <Tr> |
346 | | - <Td><Label>Bob</Label></Td> |
347 | | - < Td>< Label> [email protected]</ Label></ Td> |
348 | | - <Td><Label>User</Label></Td> |
349 | | - </Tr> |
350 | | -</DataTable> |
351 | | -``` |
352 | | - |
353 | | -**Attributes – `<DataTable>`** |
354 | | - |
355 | | -| Name | Type | Default | Description | |
356 | | -|---------------------|--------|---------|------------------------------------------------------------------| |
357 | | -| `id` | string | — | Stable id (`push_id`) wrapping the whole table. | |
358 | | -| `striped` | bool | `false` | Alternate row background. | |
359 | | -| `resizable` | bool | `false` | Enables column resizing globally (can be overridden per column). | |
360 | | -| `default-resizable` | bool | — | Default `resizable` for each `<Column>` if not set. | |
361 | | -| `header-height` | f32 | `22` | Header row height (px). | |
362 | | -| `row-height` | f32 | `22` | Default body row height (px). | |
363 | | -| `cell-padding` | f32 | `0` | Inner padding per cell, in px (applied on both sides). | |
364 | | -| `cell-align` | enum | `left` | Horizontal alignment in cells: `left`, `center`, `right`. | |
365 | | - |
366 | | -**Children order** |
367 | | -`<Columns>` → optional `<Header>` → `<Tr>*`. |
368 | | - |
369 | | -Multiple `<Header>` are not allowed; `<Header>` must have exactly one row, with exactly one `<Td>` per column. |
370 | | - |
371 | | -**Notes** |
372 | | -- `colspan` / `rowspan` are not supported in this version (compile error if used). |
373 | | -- Returns `()` (container). |
374 | | - |
375 | | ---- |
376 | | - |
0 commit comments