ice-web-components 1.3.0 → 1.4.0

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.
package/README.md CHANGED
@@ -27,11 +27,12 @@ rings and shadows) is drawn by the engine.
27
27
  - **Bootstrap 5 token theme** (plus a dark theme) — swap with one call.
28
28
  - **No name collisions with the engine** — the package’s runtime exports are
29
29
  disjoint from `ice-render`’s (there is a regression test for it).
30
- - **Actually tested** — 769 unit tests (103 suites: form validation, overlay
30
+ - **Actually tested** — 825 unit tests (107 suites: form validation, overlay
31
31
  positioning, keyboard navigation, sort/hover/focus edge cases, the Minesweeper,
32
32
  Tetris, Snake, 2048 and CHIP-8 rule/machine models, the pixel canvas and the undo
33
- stack, and the console BIOS) plus six browser QA suites (`qa:admin`, `qa:gallery`,
34
- `qa:workbench`, `qa:xp`, `qa:arcade`, `qa:pixel` — 246 assertions) that drive the demo pages with
33
+ stack, the console BIOS, the trace player + sorting/pathfinding and the DOS terminal)
34
+ plus eight browser QA suites (`qa:admin`, `qa:gallery`, `qa:workbench`, `qa:xp`,
35
+ `qa:arcade`, `qa:pixel`, `qa:algo`, `qa:dos` — 277 assertions) that drive the demo pages with
35
36
  real mouse and keyboard events and fail on any console error.
36
37
 
37
38
  ## Quick start
@@ -374,6 +375,71 @@ The three decisions worth stealing:
374
375
  > proper `setSize(rows, cols, cellSize?)` that updates the internals, the state and the
375
376
  > default width/height in one go, and clears the old cell data.
376
377
 
378
+ ### `algorithm-sandbox.html` — ICE Algorithm Sandbox
379
+
380
+ Sorting and pathfinding, visualised as **recorded traces**: each algorithm runs to
381
+ completion up front and produces a list of frames; the page then plays them back with
382
+ play / pause / single-step / rewind / speed control.
383
+
384
+ | Sorting (`quick sort`, mid-run) | Pathfinding (`A*`) |
385
+ |---|---|
386
+ | ![Algorithm sandbox · sorting](docs/images/algorithm-sandbox.png) | ![Algorithm sandbox · A*](docs/images/algorithm-maze.png) |
387
+
388
+ ```ts
389
+ import { ICESortModel, ICEMazeModel, ICETracePlayerModel } from 'ice-web-components';
390
+
391
+ const sort = new ICESortModel({ size: 24, max: 32 });
392
+ const frames = sort.run('quick'); // 一帧 = 当前数组 + 正在比较/交换的下标 + 已就位的位置
393
+ const player = new ICETracePlayerModel({ speed: 8 });
394
+ player.load(frames); // 回放:play / pause / stepForward / seek / setSpeed / tick(dt)
395
+
396
+ const maze = new ICEMazeModel({ rows: 16, cols: 24 });
397
+ maze.randomWalls(0.24);
398
+ maze.solve('astar'); // 同样是一串帧:访问过的格子 / 边界 / 最终路径
399
+ ```
400
+
401
+ Why “record a trace first, play it back later” instead of painting while the algorithm
402
+ runs: the algorithm becomes a plain function with a testable output (is the last frame
403
+ sorted? does every frame contain the same multiset? do BFS and A* agree on the shortest
404
+ path?), and the player gives pause/step/rewind for free. Four algorithms are covered on
405
+ each side — bubble / insertion / selection / merge / quick, and BFS / DFS / Dijkstra / A* —
406
+ with `ICETracePlayerModel` owning the clock (1–60 steps per second, auto-stop at the end).
407
+
408
+ Both visualisations are single `ICETileMap` nodes: the sorting bars are a `max × n` grid
409
+ where each column is filled from the bottom (blue = untouched, amber = comparing, red =
410
+ swapping, green = settled), and the maze is a grid of cell states. The A* comparison in
411
+ the QA is the honest one: same shortest path as BFS, **fewer cells visited** (the tie-break
412
+ among equal `f` values is what makes A* actually faster on an open grid).
413
+
414
+ ### `dos-terminal.html` — ICE-DOS Terminal
415
+
416
+ A terminal you can actually type into: a virtual filesystem plus 16 commands, all in a
417
+ pure model (`ICEDosModel`) that never touches the DOM.
418
+
419
+ ![ICE-DOS Terminal](docs/images/dos-terminal.png)
420
+
421
+ ```ts
422
+ import { ICEDosModel } from 'ice-web-components';
423
+
424
+ const dos = new ICEDosModel();
425
+ dos.run('cd games'); // 路径解析:\ / .. . 与大小写不敏感
426
+ dos.run('dir'); // { lines: [{ text, type: 'output' | 'error' }], effect? }
427
+ dos.run('echo hi > note.txt'); // 重定向(> 覆盖 / >> 追加)
428
+ dos.complete('type TET'); // Tab 补全 → 'type TETRIS.EXE'
429
+ dos.historyPrev(); // ↑ 历史
430
+ ```
431
+
432
+ `run()` never throws — a typo becomes one `error` line, so the terminal cannot be crashed
433
+ by typing. The page owns the three things a terminal needs on top of that: echoing the
434
+ command line, auto-scrolling to the bottom, and a blinking cursor that **simulates** a
435
+ keyboard buffer (TAB is completion, ↑↓ is history, `Ctrl+L` clears, `exit` shows a
436
+ “powered off” overlay, any key boots again).
437
+
438
+ > This page deliberately does **not** start `ICEFocusManager` (same call as the arcade
439
+ > page): the focus manager treats TAB as “rotate focus”, which steals the terminal’s
440
+ > completion key — and once focus lands on the window’s “重新开机” button, pressing Enter
441
+ > to run a command reboots the machine instead.
442
+
377
443
  ## Components
378
444
 
379
445
  | Group | Components |
@@ -385,7 +451,7 @@ The three decisions worth stealing:
385
451
  | Feedback & status | `ICEAlert` `ICEModal` `ICEDrawer` `ICEMessage` `ICENotification` `ICETooltip` `ICEPopover` `ICEPopconfirm` `ICETour` `ICEFloatButton` `ICEEmpty` `ICESkeleton` `ICESpin` `ICEResult` `ICESteps` `ICEOverlayManager` |
386
452
  | Navigation | `ICEMenu` `ICEBreadcrumb` `ICEAnchor` `ICEBackTop` `ICEDropdown` `ICEPagination` `ICETabs` |
387
453
  | Layout & core | `ICEWidget` `ICEContainer` `ICEHoverManager` `ICEFocusManager` `ICEMessageManager` `ICEManager` (`ICEPainter` / `ICELayoutManager` are types) |
388
- | Models | `ICEButtonModel` `ICEToggleModel` `ICEBoundedRangeModel` `ICESelectionModel` `ICEFormModel` `ICEBiosModel` `ICEHistoryModel` `ICEPixelModel` `ICETetrisModel` `ICESnakeModel` `ICE2048Model` `ICEChip8Model` `ICEMinesweeperModel` `ICEHighScoreModel` |
454
+ | Models | `ICEButtonModel` `ICEToggleModel` `ICEBoundedRangeModel` `ICESelectionModel` `ICEFormModel` `ICEBiosModel` `ICEHistoryModel` `ICEPixelModel` `ICETracePlayerModel` `ICESortModel` `ICEMazeModel` `ICEDosModel` `ICETetrisModel` `ICESnakeModel` `ICE2048Model` `ICEChip8Model` `ICEMinesweeperModel` `ICEHighScoreModel` |
389
455
 
390
456
  Helper functions: `attachTooltip` `attachPopover` `attachPopconfirm` `attachDropdown`
391
457
  `openModal` `openDrawer` `getICEOverlayManager` `getICEFocusManager` `getICEMessageManager`
@@ -530,6 +596,14 @@ npm run qa:arcade
530
596
  # PNG (IHDR-checked) / SVG exports
531
597
  npm run qa:pixel
532
598
 
599
+ # browser QA for examples/algorithm-sandbox.html: playback (play/pause/step/space),
600
+ # switching algorithms, the A*-vs-BFS comparison, and painting walls with a real drag
601
+ npm run qa:algo
602
+
603
+ # browser QA for examples/dos-terminal.html: typing commands, TAB completion, history,
604
+ # redirection, Ctrl+L, exit/reboot and auto-scroll
605
+ npm run qa:dos
606
+
533
607
  # docs: regenerate the API reference and check relative links
534
608
  npm run docs
535
609
  ```