Skip to content

Commit b9d8cf0

Browse files
authored
Docs: Add New Examples Package (#195)
1 parent 8a96bc1 commit b9d8cf0

184 files changed

Lines changed: 19080 additions & 919 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ xx.xx.xxxx
3434

3535
### Query
3636
* **Bug** - Fixed `instanceof` checks failing for `Query.wrap()` instances — brand property was a class field (set only in constructor) but `wrap()` uses `Object.create()`. Moved to prototype getter so all prototype-chain objects pass the check regardless of construction path.
37+
* **Bug** - Fixed `.position({ type: 'global' })` placing elements with the wrong offset when a CSS containing block (transform/filter/perspective/etc.) lived outside the element's shadow DOM — `positioningParent` now pierces shadow boundaries so the math matches what the browser actually uses. `isInView` now does the same for its default clipping viewport.
3738
* **Feature** - Added `includeMargin`, `includePadding`, and `includeBorder` options to `naturalWidth()` and `naturalHeight()` — allows measuring unconstrained intrinsic dimensions while preserving the element's box model.
3839

3940
### Utils

ai/skills/authoring/example-curriculum.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -211,28 +211,29 @@ Proves SUI's reactivity works at animation speed — a `reaction()` drives `requ
211211

212212
---
213213

214-
### 15. `event-data`Dynamic Signal Access
214+
### 15. `solar-system-3d`Wrapping a Graphics Pipeline
215215

216-
Uses `data-*` attributes to dynamically select which signal and which mutation method to call. A single event handler handles all cases via bracket notation.
216+
A WebGL fragment shader rendering the solar system, with the component owning the canvas, the drag-to-orbit input, keyboard controls, and per-frame uniform uploads. Same reactivity-driven animation loop as the ball simulation, but extended into a full Processing.js-style imperative pipeline — keybindings, settings, and reactivity sit alongside the shader without fighting it. Sells SUI as a comfortable wrapper for graphics code.
217217

218-
**New patterns:** `state[dimension][helper](settings.delta)` dynamic signal access, data-driven event dispatch.
218+
**New patterns:** Static `keys` with multi-character bindings (`'=, +'`), pointer-capture drag, sub-module imports (`fragment.js` / `vertex.js` / `webgl.js`), `state.frame.increment()` to tick the animation reaction, external preset orchestration via `$().settings({ visible: [...] })`.
219219

220220
**What to notice:**
221-
- `state[dimension][helper](settings.delta)``dimension` and `helper` come from `data-dimension` and `data-helper` attributes on the button. One handler, many behaviors.
222-
- This pattern eliminates repetitive event handlers. Instead of separate handlers for each action, one handler reads data attributes to determine what to do.
221+
- Same `reaction()` + `requestAnimationFrame` shape as the ball simulation, but the tick is explicit: `state.frame.increment()` at the end of `render` advances the signal the reaction depends on.
222+
- Keybindings as first-class framework concerns. `'=, +'` and `'-, _'` bind both characters at once; `space` pauses; `o`/`s` toggle settings. Each handler mutates a setting that the next render reads as a shader uniform.
223+
- Shader source is a plain string exported from `fragment.js`. Sub-modules import into `component.js` the same way subtemplates do — the framework doesn't care that the strings happen to be GLSL.
224+
- `page.js` ships preset visibility arrays through a `ui-menu` and pipes the selection into the component: `$('solar-system-3d').settings({ visible: presets[value] })`. Settings are reactive, so the shader picks up the change on the next frame.
223225

224226
---
225227

226-
### 16. `dropdown`Real-World Form Component
228+
### 16. `event-data`Dynamic Signal Access
227229

228-
Form integration with hidden inputs, click-away dismissal, JSON arrays as HTML attributes.
230+
Uses `data-*` attributes to dynamically select which signal and which mutation method to call. A single event handler handles all cases via bracket notation.
229231

230-
**New patterns:** Hidden `<input>` for forms, `onChange` callback alongside `dispatchEvent`, `el.contains(event.target)`, JSON in attributes, `{classIf}`.
232+
**New patterns:** `state[dimension][helper](settings.delta)` dynamic signal access, data-driven event dispatch.
231233

232234
**What to notice:**
233-
- `options='[{"value": "apple", "text": "Apple"}]'` — JSON in HTML attributes, auto-parsed for array/object settings.
234-
- `settings.onChange` alongside `dispatchEvent` — supports both callbacks and DOM events.
235-
- `{classIf isOpen 'visible'}` — simpler than `classMap` for a single conditional class.
235+
- `state[dimension][helper](settings.delta)``dimension` and `helper` come from `data-dimension` and `data-helper` attributes on the button. One handler, many behaviors.
236+
- This pattern eliminates repetitive event handlers. Instead of separate handlers for each action, one handler reads data attributes to determine what to do.
236237

237238
---
238239

@@ -296,7 +297,7 @@ SVG rendering and the `interval` helper with automatic lifecycle cleanup.
296297
| `'global event target'` | `context-menu` |
297298
| `'deep event selector'` | `context-menu` |
298299
| `{>slot}` content projection | `context-menu` |
299-
| `classMap` / `activeIf` / `selectedIf` / `classIf` | `emoji-reactions` / `todo-list` / `dropdown` |
300+
| `classMap` / `activeIf` / `selectedIf` / `classIf` | `emoji-reactions` / `todo-list` |
300301
| `reaction()` for side effects | `todo-list` |
301302
| `peek()` for non-reactive reads | `context-menu` |
302303
| `dispatchEvent` (→ `event.detail`) | `context-menu` |
@@ -320,8 +321,8 @@ SVG rendering and the `interval` helper with automatic lifecycle cleanup.
320321
| Lisp-style expressions | `async-search` |
321322
| JS-style expressions | `card-search` |
322323
| `afterFlush` | `todo-list` |
323-
| JSON in HTML attributes | `dropdown` |
324-
| Form integration (hidden input) | `dropdown` |
324+
| Sub-module imports (shader / data files) | `solar-system-3d` |
325+
| WebGL inside shadow DOM | `solar-system-3d` |
325326
| `{#each ... else}` | `card-search` |
326327
| `range()` helper | `rating-slider` |
327328
| `{both x y}` compound conditional | `progress-bar` |

docs/src/components/SpecimenExplorer/SpecimenExplorer.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<ui-panel size="280px" min-size="200px" max-size="400px">
3131
<ui-panels direction="vertical" class="control-panels">
3232
{#each group in getControlGroups}
33-
<ui-panel size="{#if group.last}grow{else}natural{/if}" label="{group.label}">
33+
<ui-panel size="{#if true}grow{/if}" label="{group.label}">
3434
<div class="section-controls">
3535
{#each control in group.controls}
3636
{#if is control.type 'radio'}

docs/src/examples/component/advanced-ball-simulation/component.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ const createComponent = ({ self, $, reaction, settings, state }) => ({
262262
},
263263
getPointerPosition(event) {
264264
const canvas = self.getCanvas();
265-
const rect = canvas.getBoundingClientRect();
265+
const rect = $('canvas').bounds();
266266
const scaleX = canvas.width / rect.width;
267267
const scaleY = canvas.height / rect.height;
268268
return {
@@ -272,7 +272,7 @@ const createComponent = ({ self, $, reaction, settings, state }) => ({
272272
},
273273
});
274274

275-
const onRendered = ({ state, data, settings, self }) => {
275+
const onRendered = ({ self }) => {
276276
self.drawInitialBalls();
277277
self.startAnimation();
278278
};

docs/src/examples/component/async-search/component.css

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
display: block;
66

77
.results {
8-
margin-top: 5px;
8+
position: absolute;
9+
top: 100%;
10+
left: 0;
11+
right: 0;
12+
z-index: var(--float-layer);
13+
margin-top: var(--margin-3xs);
914
box-shadow: var(--floating-shadow);
1015
border: var(--strong-border);
1116
background-color: var(--inverted-100);

docs/src/examples/component/async-search/component.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ const createComponent = ({ $, state, settings, self, timeout }) => ({
7373
selectCurrent() {
7474
const index = state.selectedIndex.get();
7575
const result = self.results[index];
76-
console.log(index, result);
7776
if (result) {
7877
self.clearSearch();
7978
self.setValue(result);

docs/src/examples/component/card-search/card.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const css = await getText('./card.css');
44
const template = await getText('./card.html');
55

66
export const card = defineComponent({
7-
renderingEngine: 'native',
87
template,
98
css,
109
});

docs/src/examples/component/card-search/component.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
role=friend.role
1212
joined=friend.joined
1313
image=friend.image
14-
contacts=friend.contacts
1514
}
1615
{else}
1716
No {filter != 'all' ? filter : ''} results for "{searchTerm}"

docs/src/examples/component/card-search/component.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { defineComponent, getText } from '@semantic-ui/component';
2-
import { each, escapeRegExp, get, weightedObjectSearch } from '@semantic-ui/utils';
2+
import { weightedObjectSearch } from '@semantic-ui/utils';
33

44
// sub templates
55
import { card } from './card.js';
@@ -48,15 +48,14 @@ const events = {
4848
'change ui-menu'({ state, data }) {
4949
state.filter.set(data.value);
5050
},
51-
'input ui-input'({ state, value, target }) {
51+
'input ui-input'({ state, value }) {
5252
state.searchTerm.set(value);
5353
},
5454
};
5555

5656
defineComponent({
5757
tagName: 'friend-directory',
5858
template,
59-
renderingEngine: 'native',
6059
css,
6160
defaultState,
6261
events,

docs/src/examples/component/context-menu/component.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
<div class="trigger">
22
{>slot}
33
</div>
4-
<div class="{classMap getMenuStates} menu" style="{getMenuStyle}" role="menu" part="menu">
4+
<div class="{classIf visible 'visible'} menu" style="width: {width}px;" role="menu" part="menu">
55
<div class="items">
6-
{#each item in items}
7-
{#if isDivider item}
8-
<div class="divider" data-divider="true"></div>
6+
{#each item, index in items}
7+
{#if item.divider}
8+
<div class="divider"></div>
99
{else}
10-
<div
11-
class="item {classMap getItemStates index}"
10+
<div
11+
class="item {activeIf (activeIndex == index)}"
1212
data-index="{index}"
1313
role="menuitem"
1414
part="menu-item"
15-
tabindex="{(isItemActive(index) ? '0' : '-1')}"
15+
tabindex="{activeIndex == index ? '0' : '-1'}"
1616
>
17-
{#if hasIcon item}
17+
{#if item.icon}
1818
<span class="icon" part="icon">
1919
<ui-icon icon="{item.icon}"></ui-icon>
2020
</span>
2121
{/if}
2222
<span class="label" part="label">{item.label}</span>
23-
{#if hasShortcut item}
23+
{#if item.shortcut}
2424
<span class="shortcut" part="shortcut">{item.shortcut}</span>
2525
{/if}
2626
</div>

0 commit comments

Comments
 (0)