|
1 | 1 | --- |
2 | 2 | title: Components |
3 | | -description: Build pages with the shipped solverforge-ui base components and helpers. |
| 3 | +description: > |
| 4 | + Core factories, return values, and helpers in the shipped solverforge-ui |
| 5 | + surface. |
4 | 6 | weight: 2 |
5 | 7 | --- |
6 | 8 |
|
7 | 9 | # Components |
8 | 10 |
|
9 | | -`solverforge-ui` ships a base component surface for common scheduling and operations UIs. |
| 11 | +`solverforge-ui` ships a verified component surface for common scheduling and |
| 12 | +operations UIs. |
10 | 13 |
|
11 | | -## Core Factory Functions |
| 14 | +## Core Factories |
12 | 15 |
|
13 | | -### Header |
| 16 | +The current public API documents these factories: |
14 | 17 |
|
15 | | -Use `SF.createHeader` for page titles, subtitle context, and top-level action areas. |
| 18 | +| Factory | Returns | Description | |
| 19 | +| ----------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | |
| 20 | +| `SF.createHeader(config)` | `HTMLElement` | Sticky header with logo, title, nav tabs, and solve/stop/analyze actions | |
| 21 | +| `SF.createStatusBar(config)` | `{el, bindHeader, updateScore, setSolving, updateMoves, colorDotsFromAnalysis}` | Score display with constraint indicators | |
| 22 | +| `SF.createButton(config)` | `HTMLButtonElement` | Button with variant, size, icon, and shape modifiers | |
| 23 | +| `SF.createModal(config)` | `{el, body, open, close, setBody}` | Dialog with backdrop and header | |
| 24 | +| `SF.createTable(config)` | `HTMLElement` | Data table with headers and row click support | |
| 25 | +| `SF.createTabs(config)` | `{el, show}` | Tab panel container with instance-scoped tab switching | |
| 26 | +| `SF.createFooter(config)` | `HTMLElement` | Footer with links and version | |
| 27 | +| `SF.createApiGuide(config)` | `HTMLElement` | REST API documentation panel | |
| 28 | +| `SF.showToast(config)` | `void` | Auto-dismissing toast notification | |
| 29 | +| `SF.showError(title, detail)` | `void` | Error toast shorthand | |
| 30 | +| `SF.showTab(tabId, root?)` | `void` | Activate tab panels globally or within one root | |
16 | 31 |
|
17 | | -```js |
18 | | -SF.createHeader(document.getElementById('header'), { |
19 | | - title: 'Plant Schedule', |
20 | | - subtitle: 'Line 3 · Morning Shift' |
21 | | -}); |
22 | | -``` |
23 | | - |
24 | | -### Status Bar |
25 | | - |
26 | | -Use `SF.createStatusBar` for run state, sync state, and user-facing health messages. |
27 | | - |
28 | | -```js |
29 | | -const status = SF.createStatusBar(document.getElementById('status')); |
30 | | -status.setStatus('ok', 'Data loaded'); |
31 | | -``` |
32 | | - |
33 | | -### Button |
34 | | - |
35 | | -Use `SF.createButton` for standardized button rendering and behavior. |
36 | | - |
37 | | -```js |
38 | | -const runBtn = SF.createButton({ |
39 | | - label: 'Run Solver', |
40 | | - icon: 'fa-solid fa-play', |
41 | | - onClick: () => runSolver() |
42 | | -}); |
43 | | -document.getElementById('actions').append(runBtn); |
44 | | -``` |
45 | | - |
46 | | -### Modal |
47 | | - |
48 | | -Use `SF.createModal` for confirmations, detail panes, and error drill-downs. |
49 | | - |
50 | | -```js |
51 | | -const modal = SF.createModal({ title: 'Schedule Details' }); |
52 | | -modal.setBody('<p>Batch A starts at 08:00.</p>'); |
53 | | -modal.open(); |
54 | | -``` |
55 | | - |
56 | | -### Table |
57 | | - |
58 | | -Use `SF.createTable` to render structured rows with consistent styles. |
59 | | - |
60 | | -```js |
61 | | -SF.createTable(document.getElementById('table'), { |
62 | | - columns: ['Job', 'Line', 'Start', 'End'], |
63 | | - rows: [ |
64 | | - ['J-102', 'L3', '08:00', '09:20'], |
65 | | - ['J-103', 'L2', '08:15', '10:00'] |
66 | | - ] |
67 | | -}); |
68 | | -``` |
69 | | - |
70 | | -### Tabs |
71 | | - |
72 | | -Use `SF.createTabs` for view switching and section organization. |
| 32 | +## Composition Example |
73 | 33 |
|
74 | 34 | ```js |
75 | | -SF.createTabs(document.getElementById('tabs'), { |
| 35 | +var tabs = SF.createTabs({ |
76 | 36 | tabs: [ |
77 | | - { id: 'overview', label: 'Overview', active: true }, |
78 | | - { id: 'timeline', label: 'Timeline' }, |
79 | | - { id: 'analysis', label: 'Analysis' } |
80 | | - ] |
| 37 | + { id: 'plan', content: '<div>Plan view</div>', active: true }, |
| 38 | + { id: 'gantt', content: '<div>Gantt view</div>' }, |
| 39 | + ], |
81 | 40 | }); |
82 | | -``` |
83 | | - |
84 | | -### Footer |
| 41 | +document.body.appendChild(tabs.el); |
85 | 42 |
|
86 | | -Use `SF.createFooter` for build/version info and support links. |
87 | | - |
88 | | -```js |
89 | | -SF.createFooter(document.getElementById('footer'), { |
90 | | - text: 'SolverForge UI · Production' |
| 43 | +var header = SF.createHeader({ |
| 44 | + title: 'My Scheduler', |
| 45 | + subtitle: 'by SolverForge', |
| 46 | + tabs: [ |
| 47 | + { id: 'plan', label: 'Plan', active: true }, |
| 48 | + { id: 'gantt', label: 'Gantt' }, |
| 49 | + ], |
| 50 | + onTabChange: function (id) { |
| 51 | + tabs.show(id); |
| 52 | + }, |
91 | 53 | }); |
92 | | -``` |
93 | | - |
94 | | -### API Guide |
95 | | - |
96 | | -Use `SF.createApiGuide` for built-in API reference panels in operator tools. |
| 54 | +document.body.prepend(header); |
97 | 55 |
|
98 | | -```js |
99 | | -SF.createApiGuide(document.getElementById('api-guide'), { |
100 | | - title: 'Scheduler API', |
101 | | - sections: [] |
102 | | -}); |
| 56 | +var statusBar = SF.createStatusBar({ header: header, constraints: [] }); |
| 57 | +header.after(statusBar.el); |
103 | 58 | ``` |
104 | 59 |
|
105 | | -### Toasts and Error Helpers |
106 | | - |
107 | | -Use `SF.showToast` for transient notifications and `SF.showError` for consistent error presentation. |
| 60 | +## Unsafe HTML APIs |
108 | 61 |
|
109 | | -```js |
110 | | -SF.showToast('Schedule queued'); |
| 62 | +Default content is text-rendered. These opt-ins accept trusted HTML: |
111 | 63 |
|
112 | | -try { |
113 | | - await doWork(); |
114 | | -} catch (err) { |
115 | | - SF.showError(err); |
116 | | -} |
117 | | -``` |
| 64 | +| Factory | Unsafe HTML field | |
| 65 | +| ------------------------- | ------------------------------------------------------ | |
| 66 | +| `SF.el(tag, attrs, ...)` | `unsafeHtml` | |
| 67 | +| `SF.createModal(config)` | `unsafeBody` | |
| 68 | +| `SF.createTabs(config)` | `tabs[].content.unsafeHtml` | |
| 69 | +| `SF.createTable(config)` | `cells[].unsafeHtml` | |
| 70 | +| `SF.gantt.create(config)` | `unsafePopupHtml`, `columns[].render(task).unsafeHtml` | |
118 | 71 |
|
119 | | -### Tab Switching |
| 72 | +Escape user-provided content before interpolation. `SF.escHtml(...)` is the |
| 73 | +shipped helper for that. |
120 | 74 |
|
121 | | -Use `SF.showTab` to activate a tab and its related content region. |
| 75 | +## Button Variants |
122 | 76 |
|
123 | 77 | ```js |
124 | | -SF.showTab('timeline'); |
| 78 | +SF.createButton({ text: 'Solve', variant: 'success' }); |
| 79 | +SF.createButton({ text: 'Stop', variant: 'danger' }); |
| 80 | +SF.createButton({ text: 'Save', variant: 'primary' }); |
| 81 | +SF.createButton({ text: 'Cancel', variant: 'default' }); |
| 82 | +SF.createButton({ icon: 'fa-gear', variant: 'ghost', circle: true }); |
125 | 83 | ``` |
126 | 84 |
|
127 | | -## Unsafe HTML APIs |
128 | | - |
129 | | -Some component APIs accept HTML strings (for example, custom modal body content). Treat untrusted user data as unsafe. |
130 | | - |
131 | | -- Escape user-provided text before injecting into HTML. |
132 | | -- Prefer text-only rendering paths when possible. |
133 | | -- Only pass trusted HTML if it is sanitized. |
134 | | - |
135 | | -A practical helper pattern is `SF.escHtml` before interpolation. |
136 | | - |
137 | 85 | ## Useful Helpers |
138 | 86 |
|
139 | | -The following helpers are optional but often useful in real pages: |
| 87 | +These helpers are documented in the current public API: |
140 | 88 |
|
141 | | -- `SF.score.*` for score formatting and display helpers |
142 | | -- `SF.colors.*` for consistent palette usage |
143 | | -- `SF.escHtml` for HTML escaping |
144 | | -- `SF.el` for lightweight DOM element creation |
| 89 | +- `SF.score.parseHard`, `parseSoft`, `parseMedium`, `getComponents`, |
| 90 | + `colorClass` |
| 91 | +- `SF.colors.pick`, `project`, `reset` |
| 92 | +- `SF.escHtml(...)` for safe HTML escaping |
| 93 | +- `SF.el(tag, attrs, ...children)` for lightweight DOM element creation |
0 commit comments