AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻譯準備中
UECA-React Showcase - 大約五十個基於 UECA-React 的元件,使用純 HTML 與 CSS:提供即時展示與練習場,支援亮色與暗色主題。
AI 翻譯
UECA-React Showcase - some fifty components built on UECA-React with plain HTML and CSS: a live Showcase and a Playground, in light and dark themes.
開發工具TypeScript · CSSGitHub @nekutuzov上線中營運者未確認
試用過了嗎? 點一下就好,不需要登入。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證UECA-React 2.0 demo: Framework replacing React hooks with message bus, automatic events, property bindings, and black-box components. Vite + TypeScript + React + MobX.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A working application built with UECA-React: a component library of some fifty components on plain HTML, CSS and SVG, a live Showcase of every one of them, and a Playground where a component's properties and its source change together. It runs in a light and a dark theme, and every screen, service and control in it follows the same UECA component shape.檢視完整 README ↗A working application built with UECA-React: a component library of some fifty components on plain HTML, CSS and SVG, a live Showcase of every one of them, and a Playground where a component's properties and its source change together. It runs in a light and a dark theme, and every screen, service and control in it follows the same UECA component shape.
Live demo: https://nekutuzov.github.io/ueca-react-app-demo2/
UECA-React gives every React component the same explicit structure: props, children, methods, events, messages and a View, in that order. On top of that it adds stable component IDs, automatic change events for every property, one- and two-way property bindings, lifecycle hooks and a typed message bus. State is reactive (MobX, abstracted away): you assign to a property and the views that read it update.
node_modules/ueca-react/docs/raw/index.mdnpm install
npm run dev
Then open http://localhost:5001/ueca-react-app-demo2/.
| Script | What it does |
|---|---|
npm run dev | Vite dev server on port 5001 |
npm run build | Type-check and production build into dist/ |
npm run lint | ESLint |
npm test | Run the test suite once |
npm run test:watch | Run the tests in watch mode |
npm run coverage | Run the tests with a coverage report in coverage/ |
npm run preview | Serve the production build |
npm run deploy | Build, then publish dist/ to the gh-pages branch with the gh-pages package |
The UECA agent skills shipped with ueca-react are installed by npx ueca-react-skills. A plain npm install runs it through the postinstall; a targeted npm install ueca-react@… does not, so run it yourself after an upgrade.
src/
├── main.tsx # Entry point: global settings, error handler, render
├── tokens.css # Non-colour design tokens: type, spacing, radii, motion, z-index
├── themes.css # Colour tokens per theme (ueca-light, ueca-dark) and the control voice
├── theme.css # Page surface, markdown and code highlighting
├── test/ # Test setup and helpers (mount, settle, stubMessages, browser stubs)
├── integration/ # Whole-application tests: sign-in, routing, history, theme, services
├── api/ # REST client and MSW mocks
├── components/ # The component library
│ ├── base/ # useBase → useUIBase → useEditBase / useScreenBase
│ ├── buttons/ # Button, IconButton, toolbar shorthands
│ ├── data/ # Table, VirtualList, FilterableList
│ ├── flyouts/ # Alert, Snackbar, AlertToast, Drawer, EditDrawer, AlertDrawer
│ ├── inputs/ # TextField, NumberField, SearchField, Select, Checkbox, Switch, RadioGroup
│ ├── layout/ # Block, Row, Col, Grid, GridCell, Card
│ ├── menus/ # Menu, MenuItem
│ ├── misc/ # Icon, StatusLabel, ProgressBar, Spinner, MarkdownPreview, DropZone, …
│ ├── navigation/ # Router, NavLink, NavItem, NavItemExpandable, Breadcrumbs
│ ├── panels/ # Panel
│ ├── popups/ # Dialog, AlertDialog, Popover
│ └── tabs/ # TabsContainer, Tab
├── core/ # The application shell and its services
│ ├── infrastructure/ # Application, AppUI, router, routes, browsing history, security,
│ │ # dialogs, alerts, tooltip, busy display, theme manager, message contract
│ ├── appLayout/ # Sidebar, menu, layouts
│ ├── screenLayout/ # Screen frame: top bar, breadcrumbs, CRUD and tabbed screens
│ ├── appComponents/ # CodeSample, ThemeToggle, UECAContacts
│ └── misc/ # Icon set and role registry, overlay positioning and stacking
└── screens/
├── home/ # Landing page
├── common/ # ScreenPage: the shared eyebrow / title / lead / pager frame
├── showcase/ # One screen per topic; showcaseTopics.tsx lists them
└── playground/ # Button, Text field and Table editors; playgroundTopics.tsx lists them
showcaseTopics.tsx and playgroundTopics.tsx are the single source for each page's route, menu entry, title, lead and previous/next links. Adding a page means adding an entry there and a route in appRoutes.tsx.
Tests run on Vitest with jsdom and Testing Library. Each component, service and screen has its tests beside it (button.tsx → button.test.tsx), and src/integration/ drives the whole application: signing in, deep links, navigation, Back and Forward, the theme and the app services.
A UECA component draws nothing on its first render, so a test mounts it and waits:
const { model } = await mount(Button, { id: "save", contentView: "Save", onClick });
await userEvent.click(screen.getByRole("button", { name: "Save" }));
expect(onClick).toHaveBeenCalledWith(model);
model.disabled = true;
await settle();
expect(screen.getByRole("button")).toBeDisabled();
stubMessages stands in for a service on the message bus, and any error UECA would otherwise swallow — a View that throws, a failing hook — fails the test. Known defects are recorded as it.fails tests marked // BUG:.
tokens.css holds everything that is not colour; themes.css holds one colour block per theme, selected by <html data-theme>. A theme is added by adding a block there and an entry in core/infrastructure/appTheme.ts.themes.css, so every control in a form changes together.<Icon name="delete" />); core/misc/iconRegistry.ts decides which glyph backs it.import * as UECA from "ueca-react";
import { UIBaseModel, UIBaseParams, UIBaseStruct, useUIBase } from "@components";
type CounterStruct = UIBaseStruct<{
props: { count: number };
methods: { increment: () => void };
}>;
type CounterParams = UIBaseParams<CounterStruct>;
type CounterModel = UIBaseModel<CounterStruct>;
function useCounter(params?: CounterParams): CounterModel {
const struct: CounterStruct = {
props: {
id: useCounter.name,
count: 0
},
methods: {
increment: () => {
model.count++;
}
},
View: () => (
<button id={model.htmlId()} onClick={() => model.increment()}>
Clicked {model.count} times
</button>
)
};
const model = useUIBase(struct, params);
return model;
}
const Counter = UECA.getFC(useCounter);
export { CounterParams, CounterModel, useCounter, Counter };
Services are components too: they declare messages handlers and render nothing, and the rest of the app reaches them over the bus.
await model.bus.unicast("Alert.Success", { message: "Saved" });
const ok = await model.bus.unicast("Dialog.Confirmation", { title: "Delete", message: "Are you sure?" });
await model.bus.unicast("App.Router.GoToRoute", { path: "/playground/table" });
Every message is declared in core/infrastructure/appMessage.ts.
@components → src/components@core → src/core@api → src/api@screens → src/screensISC