@capillaryjs/capillary-ui 1.0.0-alpha.1
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/CHANGELOG.md +459 -0
- package/LICENSE +55 -0
- package/NOTICE +2 -0
- package/README.md +853 -0
- package/colors/README.md +63 -0
- package/colors/gray/colors.css +16 -0
- package/colors/green/colors.css +16 -0
- package/colors/iceblue/colors.css +19 -0
- package/colors/ocean/colors.css +16 -0
- package/colors/orange/colors.css +16 -0
- package/colors/purple/colors.css +16 -0
- package/colors/red/colors.css +16 -0
- package/colors/yellow/colors.css +16 -0
- package/dist/Components/Placeholder.d.ts +15 -0
- package/dist/Components/Placeholder.d.ts.map +1 -0
- package/dist/Components/app/app.d.ts +41 -0
- package/dist/Components/app/app.d.ts.map +1 -0
- package/dist/Components/component.d.ts +256 -0
- package/dist/Components/component.d.ts.map +1 -0
- package/dist/Components/controlUtils.d.ts +23 -0
- package/dist/Components/controlUtils.d.ts.map +1 -0
- package/dist/Components/data/descriptionList.d.ts +23 -0
- package/dist/Components/data/descriptionList.d.ts.map +1 -0
- package/dist/Components/data/filterState.d.ts +38 -0
- package/dist/Components/data/filterState.d.ts.map +1 -0
- package/dist/Components/data/infoPanel.d.ts +29 -0
- package/dist/Components/data/infoPanel.d.ts.map +1 -0
- package/dist/Components/data/listview/listview.d.ts +51 -0
- package/dist/Components/data/listview/listview.d.ts.map +1 -0
- package/dist/Components/data/selectionhandler.d.ts +87 -0
- package/dist/Components/data/selectionhandler.d.ts.map +1 -0
- package/dist/Components/data/table/DataTable.d.ts +79 -0
- package/dist/Components/data/table/DataTable.d.ts.map +1 -0
- package/dist/Components/data/table/FilterPanel.d.ts +41 -0
- package/dist/Components/data/table/FilterPanel.d.ts.map +1 -0
- package/dist/Components/data/table/TableHeader.d.ts +23 -0
- package/dist/Components/data/table/TableHeader.d.ts.map +1 -0
- package/dist/Components/data/table/TableHeaderCell.d.ts +41 -0
- package/dist/Components/data/table/TableHeaderCell.d.ts.map +1 -0
- package/dist/Components/data/table/tableDataSource.d.ts +49 -0
- package/dist/Components/data/table/tableDataSource.d.ts.map +1 -0
- package/dist/Components/data/table/tableQuery.d.ts +29 -0
- package/dist/Components/data/table/tableQuery.d.ts.map +1 -0
- package/dist/Components/data/treeview/treeModel.d.ts +23 -0
- package/dist/Components/data/treeview/treeModel.d.ts.map +1 -0
- package/dist/Components/data/treeview/treeitem.d.ts +21 -0
- package/dist/Components/data/treeview/treeitem.d.ts.map +1 -0
- package/dist/Components/data/treeview/treeview.d.ts +49 -0
- package/dist/Components/data/treeview/treeview.d.ts.map +1 -0
- package/dist/Components/dialog/dialog.d.ts +46 -0
- package/dist/Components/dialog/dialog.d.ts.map +1 -0
- package/dist/Components/layout/declarativeRegion.d.ts +30 -0
- package/dist/Components/layout/declarativeRegion.d.ts.map +1 -0
- package/dist/Components/layout/groupBox.d.ts +21 -0
- package/dist/Components/layout/groupBox.d.ts.map +1 -0
- package/dist/Components/layout/header.d.ts +20 -0
- package/dist/Components/layout/header.d.ts.map +1 -0
- package/dist/Components/layout/layout.d.ts +28 -0
- package/dist/Components/layout/layout.d.ts.map +1 -0
- package/dist/Components/layout/layoutTraits.d.ts +39 -0
- package/dist/Components/layout/layoutTraits.d.ts.map +1 -0
- package/dist/Components/layout/optionGroup.d.ts +35 -0
- package/dist/Components/layout/optionGroup.d.ts.map +1 -0
- package/dist/Components/layout/optionsBox.d.ts +12 -0
- package/dist/Components/layout/optionsBox.d.ts.map +1 -0
- package/dist/Components/layout/panel.d.ts +34 -0
- package/dist/Components/layout/panel.d.ts.map +1 -0
- package/dist/Components/layout/routedSelection.d.ts +10 -0
- package/dist/Components/layout/routedSelection.d.ts.map +1 -0
- package/dist/Components/layout/sidebar.d.ts +27 -0
- package/dist/Components/layout/sidebar.d.ts.map +1 -0
- package/dist/Components/layout/splitView.d.ts +82 -0
- package/dist/Components/layout/splitView.d.ts.map +1 -0
- package/dist/Components/layout/tabpanel/tab.d.ts +15 -0
- package/dist/Components/layout/tabpanel/tab.d.ts.map +1 -0
- package/dist/Components/layout/tabpanel/tabline.d.ts +31 -0
- package/dist/Components/layout/tabpanel/tabline.d.ts.map +1 -0
- package/dist/Components/layout/tabpanel/tabpanel.d.ts +44 -0
- package/dist/Components/layout/tabpanel/tabpanel.d.ts.map +1 -0
- package/dist/Components/lineinputs/CheckableControl.d.ts +7 -0
- package/dist/Components/lineinputs/CheckableControl.d.ts.map +1 -0
- package/dist/Components/lineinputs/LabeledInputControl.d.ts +7 -0
- package/dist/Components/lineinputs/LabeledInputControl.d.ts.map +1 -0
- package/dist/Components/lineinputs/SelectControl.d.ts +7 -0
- package/dist/Components/lineinputs/SelectControl.d.ts.map +1 -0
- package/dist/Components/lineinputs/checkbox/Checkbox.d.ts +46 -0
- package/dist/Components/lineinputs/checkbox/Checkbox.d.ts.map +1 -0
- package/dist/Components/lineinputs/checkbox/QuadCheckbox.d.ts +11 -0
- package/dist/Components/lineinputs/checkbox/QuadCheckbox.d.ts.map +1 -0
- package/dist/Components/lineinputs/checkbox/TriCheckbox.d.ts +11 -0
- package/dist/Components/lineinputs/checkbox/TriCheckbox.d.ts.map +1 -0
- package/dist/Components/lineinputs/datetime/Calendar.d.ts +23 -0
- package/dist/Components/lineinputs/datetime/Calendar.d.ts.map +1 -0
- package/dist/Components/lineinputs/datetime/DatePicker.d.ts +62 -0
- package/dist/Components/lineinputs/datetime/DatePicker.d.ts.map +1 -0
- package/dist/Components/lineinputs/datetime/DateTimePicker.d.ts +52 -0
- package/dist/Components/lineinputs/datetime/DateTimePicker.d.ts.map +1 -0
- package/dist/Components/lineinputs/datetime/TimePicker.d.ts +46 -0
- package/dist/Components/lineinputs/datetime/TimePicker.d.ts.map +1 -0
- package/dist/Components/lineinputs/datetime/civilDate.d.ts +37 -0
- package/dist/Components/lineinputs/datetime/civilDate.d.ts.map +1 -0
- package/dist/Components/lineinputs/datetime/timeString.d.ts +26 -0
- package/dist/Components/lineinputs/datetime/timeString.d.ts.map +1 -0
- package/dist/Components/lineinputs/dropdown.d.ts +49 -0
- package/dist/Components/lineinputs/dropdown.d.ts.map +1 -0
- package/dist/Components/lineinputs/label.d.ts +14 -0
- package/dist/Components/lineinputs/label.d.ts.map +1 -0
- package/dist/Components/lineinputs/radio.d.ts +69 -0
- package/dist/Components/lineinputs/radio.d.ts.map +1 -0
- package/dist/Components/lineinputs/textbox.d.ts +40 -0
- package/dist/Components/lineinputs/textbox.d.ts.map +1 -0
- package/dist/Components/lineinputs/toggle.d.ts +40 -0
- package/dist/Components/lineinputs/toggle.d.ts.map +1 -0
- package/dist/Components/menu/button.d.ts +31 -0
- package/dist/Components/menu/button.d.ts.map +1 -0
- package/dist/Components/menu/toolbar.d.ts +15 -0
- package/dist/Components/menu/toolbar.d.ts.map +1 -0
- package/dist/Components/navigation/breadcrumb.d.ts +31 -0
- package/dist/Components/navigation/breadcrumb.d.ts.map +1 -0
- package/dist/Components/navigation/navigationBar.d.ts +53 -0
- package/dist/Components/navigation/navigationBar.d.ts.map +1 -0
- package/dist/Components/status/progressBar.d.ts +23 -0
- package/dist/Components/status/progressBar.d.ts.map +1 -0
- package/dist/Components/status/statusPresentation.d.ts +21 -0
- package/dist/Components/status/statusPresentation.d.ts.map +1 -0
- package/dist/Components/theme/stylesheetPicker.d.ts +42 -0
- package/dist/Components/theme/stylesheetPicker.d.ts.map +1 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7736 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-dev-runtime-BAF7C1E1.js +1368 -0
- package/dist/jsx-dev-runtime-BAF7C1E1.js.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +2 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +6 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime.d.ts +26 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +9 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/localization.d.ts +76 -0
- package/dist/localization.d.ts.map +1 -0
- package/dist/routing/RouteLink.d.ts +18 -0
- package/dist/routing/RouteLink.d.ts.map +1 -0
- package/dist/routing/RouteOutlet.d.ts +38 -0
- package/dist/routing/RouteOutlet.d.ts.map +1 -0
- package/dist/routing/RouteQuery.d.ts +19 -0
- package/dist/routing/RouteQuery.d.ts.map +1 -0
- package/dist/routing/RouteScope.d.ts +18 -0
- package/dist/routing/RouteScope.d.ts.map +1 -0
- package/dist/routing/RouteValue.d.ts +19 -0
- package/dist/routing/RouteValue.d.ts.map +1 -0
- package/dist/routing/navigationAdapter.d.ts +33 -0
- package/dist/routing/navigationAdapter.d.ts.map +1 -0
- package/dist/routing/route.d.ts +64 -0
- package/dist/routing/route.d.ts.map +1 -0
- package/dist/routing/router.d.ts +109 -0
- package/dist/routing/router.d.ts.map +1 -0
- package/dist/runtime.d.ts +34 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/services.d.ts +45 -0
- package/dist/services.d.ts.map +1 -0
- package/dist/styling/styleRegistry.d.ts +15 -0
- package/dist/styling/styleRegistry.d.ts.map +1 -0
- package/dist/styling/theme.d.ts +39 -0
- package/dist/styling/theme.d.ts.map +1 -0
- package/dist/util/filterMode.d.ts +15 -0
- package/dist/util/filterMode.d.ts.map +1 -0
- package/docs/application-composition-guide.md +843 -0
- package/docs/application-layout-guide.md +553 -0
- package/package.json +90 -0
- package/styles/structural.css +2388 -0
- package/themes/README.md +99 -0
- package/themes/base.css +344 -0
- package/themes/java/theme.css +21 -0
- package/themes/minimal/theme.css +7 -0
- package/themes/shiny/theme.css +168 -0
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
# Capillary UI Application Layout Guidelines
|
|
2
|
+
|
|
3
|
+
These guidelines describe a recommended source layout for applications built with Capillary UI and Capillary. They are conventions rather than framework requirements.
|
|
4
|
+
|
|
5
|
+
For deciding how screens, components, state lifetimes, and visual layouts fit
|
|
6
|
+
together, see the companion [application composition guide](application-composition-guide.md).
|
|
7
|
+
|
|
8
|
+
The main goals are:
|
|
9
|
+
|
|
10
|
+
* make application structure easy to understand by browsing the repository;
|
|
11
|
+
* keep backend/API concerns separate from view-specific concerns;
|
|
12
|
+
* colocate code that changes together;
|
|
13
|
+
* keep Capillary UI components focused on presentation and interaction;
|
|
14
|
+
* avoid generic catch-all folders such as `core`;
|
|
15
|
+
* introduce abstraction only when the application actually needs it.
|
|
16
|
+
|
|
17
|
+
## Recommended structure
|
|
18
|
+
|
|
19
|
+
A typical application should start roughly like this:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
src/
|
|
23
|
+
app/
|
|
24
|
+
main.tsx
|
|
25
|
+
routing.ts
|
|
26
|
+
services.ts
|
|
27
|
+
appearance.ts
|
|
28
|
+
|
|
29
|
+
api/
|
|
30
|
+
dtos.ts
|
|
31
|
+
errors.ts
|
|
32
|
+
|
|
33
|
+
domain/
|
|
34
|
+
...
|
|
35
|
+
|
|
36
|
+
services/
|
|
37
|
+
ProjectsService.ts
|
|
38
|
+
WorkersService.ts
|
|
39
|
+
IssuesService.ts
|
|
40
|
+
|
|
41
|
+
views/
|
|
42
|
+
ProjectOverviewView/
|
|
43
|
+
ProjectOverviewView.tsx
|
|
44
|
+
projectOverviewViewService.ts
|
|
45
|
+
components/
|
|
46
|
+
...
|
|
47
|
+
|
|
48
|
+
ScheduleView/
|
|
49
|
+
ScheduleView.tsx
|
|
50
|
+
scheduleViewService.ts
|
|
51
|
+
components/
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
IssuesView/
|
|
55
|
+
IssuesView.tsx
|
|
56
|
+
issuesViewService.ts
|
|
57
|
+
components/
|
|
58
|
+
...
|
|
59
|
+
|
|
60
|
+
shared/
|
|
61
|
+
components/
|
|
62
|
+
...
|
|
63
|
+
|
|
64
|
+
styles/
|
|
65
|
+
...
|
|
66
|
+
|
|
67
|
+
index.ts
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Not every application needs every directory. Add a directory when there is an actual responsibility for it to contain.
|
|
71
|
+
|
|
72
|
+
## `app/`: application composition
|
|
73
|
+
|
|
74
|
+
`app/` contains application-wide composition and policy.
|
|
75
|
+
|
|
76
|
+
Typical responsibilities include:
|
|
77
|
+
|
|
78
|
+
* application startup;
|
|
79
|
+
* routing;
|
|
80
|
+
* application service registration;
|
|
81
|
+
* session/application lifetime;
|
|
82
|
+
* theme and appearance selection;
|
|
83
|
+
* other whole-application configuration.
|
|
84
|
+
|
|
85
|
+
Keep this directory small. It should connect the major parts of the application rather than becoming a container for general application logic.
|
|
86
|
+
|
|
87
|
+
## `api/`: backend contract
|
|
88
|
+
|
|
89
|
+
`api/` contains types and utilities describing communication with the backend.
|
|
90
|
+
|
|
91
|
+
Typical contents include:
|
|
92
|
+
|
|
93
|
+
* request and response DTOs;
|
|
94
|
+
* response validation/parsing;
|
|
95
|
+
* API-specific errors;
|
|
96
|
+
* shared wire-level types.
|
|
97
|
+
|
|
98
|
+
The API contract should not contain presentation logic or view-specific projections.
|
|
99
|
+
|
|
100
|
+
## `services/`: backend-facing services
|
|
101
|
+
|
|
102
|
+
Root-level services should represent the capabilities exposed by the backend.
|
|
103
|
+
|
|
104
|
+
For example:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
services/
|
|
108
|
+
ProjectsService.ts
|
|
109
|
+
WorkersService.ts
|
|
110
|
+
IssuesService.ts
|
|
111
|
+
ScheduleService.ts
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
A service may define Capillary endpoints, commands, serialization, parsing, and other concerns intrinsic to communicating with that backend API.
|
|
115
|
+
|
|
116
|
+
The service should remain a faithful application-facing representation of the backend rather than gradually becoming tailored to individual screens.
|
|
117
|
+
|
|
118
|
+
For example, a `ProjectsService` may expose:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
projects
|
|
122
|
+
project
|
|
123
|
+
createProject
|
|
124
|
+
updateProject
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
and an `IssuesService` may expose:
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
issues
|
|
131
|
+
issue
|
|
132
|
+
createIssue
|
|
133
|
+
resolveIssue
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
but root services should normally not expose things such as:
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
issuesVisibleForCurrentPhase
|
|
140
|
+
workersGroupedForSchedule
|
|
141
|
+
projectsForDashboardCards
|
|
142
|
+
filteredIssuesForAnalytics
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
unless those operations have genuine application-wide or domain meaning.
|
|
146
|
+
|
|
147
|
+
A useful rule is:
|
|
148
|
+
|
|
149
|
+
> Root services represent backend capabilities. View services represent what a particular view needs.
|
|
150
|
+
|
|
151
|
+
## `views/`: organize UI by feature
|
|
152
|
+
|
|
153
|
+
The UI should primarily be organized vertically by view or screen.
|
|
154
|
+
|
|
155
|
+
For example:
|
|
156
|
+
|
|
157
|
+
```text
|
|
158
|
+
views/
|
|
159
|
+
ScheduleView/
|
|
160
|
+
ScheduleView.tsx
|
|
161
|
+
scheduleViewService.ts
|
|
162
|
+
scheduleProjection.ts
|
|
163
|
+
components/
|
|
164
|
+
PhaseTimeline.tsx
|
|
165
|
+
WorkerAllocation.tsx
|
|
166
|
+
|
|
167
|
+
IssuesView/
|
|
168
|
+
IssuesView.tsx
|
|
169
|
+
issuesViewService.ts
|
|
170
|
+
issueGrouping.ts
|
|
171
|
+
components/
|
|
172
|
+
IssueDetails.tsx
|
|
173
|
+
IssueSummary.tsx
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Code used only by one view should normally live with that view.
|
|
177
|
+
|
|
178
|
+
This makes the location of functionality predictable and keeps related implementation together.
|
|
179
|
+
|
|
180
|
+
Prefer this over global directories such as:
|
|
181
|
+
|
|
182
|
+
```text
|
|
183
|
+
components/
|
|
184
|
+
models/
|
|
185
|
+
helpers/
|
|
186
|
+
viewModels/
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
that require developers to jump between several unrelated parts of the source tree when changing one screen.
|
|
190
|
+
|
|
191
|
+
## View services
|
|
192
|
+
|
|
193
|
+
A view may define its own service or state/coordinator object when the view needs derived state or composition beyond the raw backend API.
|
|
194
|
+
|
|
195
|
+
For example:
|
|
196
|
+
|
|
197
|
+
```text
|
|
198
|
+
IssuesService
|
|
199
|
+
WorkersService
|
|
200
|
+
│
|
|
201
|
+
▼
|
|
202
|
+
ScheduleViewService
|
|
203
|
+
│
|
|
204
|
+
▼
|
|
205
|
+
ScheduleView
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
`ScheduleViewService` may own:
|
|
209
|
+
|
|
210
|
+
* filtering;
|
|
211
|
+
* sorting;
|
|
212
|
+
* grouping;
|
|
213
|
+
* mappings;
|
|
214
|
+
* derived Capillary emitters;
|
|
215
|
+
* selection state;
|
|
216
|
+
* query arguments;
|
|
217
|
+
* projections;
|
|
218
|
+
* combinations of several backend services;
|
|
219
|
+
* other state or operations meaningful specifically to that view.
|
|
220
|
+
|
|
221
|
+
A view service should still be independent of rendering. It should not manipulate DOM nodes, Capillary UI component instances, CSS, or presentation markup.
|
|
222
|
+
|
|
223
|
+
It should expose meaningful values and operations that the view renders or interacts with.
|
|
224
|
+
|
|
225
|
+
## Reactive values may flow in both directions
|
|
226
|
+
|
|
227
|
+
Architectural ownership should not be confused with runtime data flow.
|
|
228
|
+
|
|
229
|
+
A Capillary UI application commonly has interactions such as:
|
|
230
|
+
|
|
231
|
+
```text
|
|
232
|
+
DataTable sort control
|
|
233
|
+
│
|
|
234
|
+
▼
|
|
235
|
+
sort Emitter
|
|
236
|
+
│
|
|
237
|
+
▼
|
|
238
|
+
query argument
|
|
239
|
+
│
|
|
240
|
+
▼
|
|
241
|
+
backend-facing service/query
|
|
242
|
+
│
|
|
243
|
+
▼
|
|
244
|
+
new rows
|
|
245
|
+
│
|
|
246
|
+
▼
|
|
247
|
+
DataTable
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Likewise:
|
|
251
|
+
|
|
252
|
+
```text
|
|
253
|
+
SearchInput
|
|
254
|
+
│
|
|
255
|
+
▼
|
|
256
|
+
searchText Emitter
|
|
257
|
+
│
|
|
258
|
+
▼
|
|
259
|
+
query argument
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
or:
|
|
263
|
+
|
|
264
|
+
```text
|
|
265
|
+
DateTimePicker
|
|
266
|
+
│
|
|
267
|
+
▼
|
|
268
|
+
selectedDate Emitter
|
|
269
|
+
│
|
|
270
|
+
▼
|
|
271
|
+
query/filter argument
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
This is normal and desirable.
|
|
275
|
+
|
|
276
|
+
Controls may expose writable Capillary values that feed into view services, derived emitters, query arguments, or backend queries. Query results then flow back into the components that render them.
|
|
277
|
+
|
|
278
|
+
The important architectural rule is therefore not that values only flow downward.
|
|
279
|
+
|
|
280
|
+
Instead:
|
|
281
|
+
|
|
282
|
+
> Higher-level application and domain concepts should not depend on the presentation details of the views that consume them.
|
|
283
|
+
|
|
284
|
+
A backend-facing service may accept an emitter or query argument originating from a view without knowing which control produced it.
|
|
285
|
+
|
|
286
|
+
For example:
|
|
287
|
+
|
|
288
|
+
```text
|
|
289
|
+
DataTable
|
|
290
|
+
│ sort Emitter
|
|
291
|
+
▼
|
|
292
|
+
ScheduleViewService
|
|
293
|
+
│ query argument
|
|
294
|
+
▼
|
|
295
|
+
ScheduleService
|
|
296
|
+
│ result
|
|
297
|
+
▼
|
|
298
|
+
ScheduleViewService
|
|
299
|
+
│ projected data
|
|
300
|
+
▼
|
|
301
|
+
DataTable
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
The runtime data flow forms a reactive loop, while ownership and knowledge remain cleanly separated.
|
|
305
|
+
|
|
306
|
+
The `ScheduleService` knows about schedule queries and their arguments. It should not know that the sort value originated from a `DataTable`, a dropdown, or some other Capillary UI component.
|
|
307
|
+
|
|
308
|
+
## Promote logic only when it is genuinely shared
|
|
309
|
+
|
|
310
|
+
Start feature-specific code inside the feature that needs it.
|
|
311
|
+
|
|
312
|
+
For example:
|
|
313
|
+
|
|
314
|
+
```text
|
|
315
|
+
views/
|
|
316
|
+
IssuesView/
|
|
317
|
+
components/
|
|
318
|
+
IssueDetails.tsx
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Do not move `IssueDetails` into `shared/components` merely because another view might eventually use it.
|
|
322
|
+
|
|
323
|
+
Move code upward only once it has a real broader responsibility.
|
|
324
|
+
|
|
325
|
+
A useful progression is:
|
|
326
|
+
|
|
327
|
+
```text
|
|
328
|
+
view-specific
|
|
329
|
+
↓ if genuinely reused
|
|
330
|
+
shared application code
|
|
331
|
+
↓ if it represents domain meaning
|
|
332
|
+
domain abstraction
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Two callers alone are not necessarily sufficient reason to create a shared abstraction.
|
|
336
|
+
|
|
337
|
+
## `domain/`: application/domain concepts
|
|
338
|
+
|
|
339
|
+
`domain/` contains logic that describes the application's problem domain rather than a particular screen or transport mechanism.
|
|
340
|
+
|
|
341
|
+
For a construction application this might include:
|
|
342
|
+
|
|
343
|
+
```text
|
|
344
|
+
domain/
|
|
345
|
+
project.ts
|
|
346
|
+
phase.ts
|
|
347
|
+
dependency.ts
|
|
348
|
+
calendar.ts
|
|
349
|
+
scheduling.ts
|
|
350
|
+
cost.ts
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Typical responsibilities include:
|
|
354
|
+
|
|
355
|
+
* domain models;
|
|
356
|
+
* calculations;
|
|
357
|
+
* scheduling rules;
|
|
358
|
+
* prerequisite/dependency rules;
|
|
359
|
+
* projections with domain meaning;
|
|
360
|
+
* classification rules;
|
|
361
|
+
* reusable domain transformations.
|
|
362
|
+
|
|
363
|
+
Domain code should ideally have no dependency on Capillary UI, DOM APIs, CSS, or HTTP.
|
|
364
|
+
|
|
365
|
+
Do not create additional hierarchy merely for architectural appearance. If the entire application is already about construction:
|
|
366
|
+
|
|
367
|
+
```text
|
|
368
|
+
domain/
|
|
369
|
+
phase.ts
|
|
370
|
+
scheduling.ts
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
is usually clearer than:
|
|
374
|
+
|
|
375
|
+
```text
|
|
376
|
+
domain/
|
|
377
|
+
construction/
|
|
378
|
+
phase.ts
|
|
379
|
+
scheduling.ts
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Add another level only when multiple genuinely distinct domains exist.
|
|
383
|
+
|
|
384
|
+
## `shared/`: use sparingly
|
|
385
|
+
|
|
386
|
+
`shared/` contains functionality genuinely shared by unrelated areas of the application.
|
|
387
|
+
|
|
388
|
+
Typical examples include:
|
|
389
|
+
|
|
390
|
+
```text
|
|
391
|
+
shared/
|
|
392
|
+
components/
|
|
393
|
+
ApplicationHeader.tsx
|
|
394
|
+
StatusBadge.tsx
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
`shared/` should not become a dumping ground.
|
|
398
|
+
|
|
399
|
+
Prefer keeping code inside a view until it clearly belongs to the wider application.
|
|
400
|
+
|
|
401
|
+
## Capillary UI components
|
|
402
|
+
|
|
403
|
+
Capillary UI components primarily own presentation and interaction.
|
|
404
|
+
|
|
405
|
+
They may:
|
|
406
|
+
|
|
407
|
+
* render application state;
|
|
408
|
+
* expose or bind controls to Capillary emitters;
|
|
409
|
+
* update writable Capillary values;
|
|
410
|
+
* invoke commands and callbacks;
|
|
411
|
+
* react to readable Capillary values;
|
|
412
|
+
* own short-lived presentation state.
|
|
413
|
+
|
|
414
|
+
For example, a table header may update a sort emitter, a search control may update a search-text emitter, and a date picker may update a date emitter. Those values may subsequently participate in derivations or backend queries.
|
|
415
|
+
|
|
416
|
+
Components should generally not acquire responsibilities such as:
|
|
417
|
+
|
|
418
|
+
* backend serialization;
|
|
419
|
+
* application-wide business rules;
|
|
420
|
+
* reusable domain calculations;
|
|
421
|
+
* backend-specific DTO conversion;
|
|
422
|
+
* screen-independent data transformations.
|
|
423
|
+
|
|
424
|
+
The component should consume and update state appropriate to its level rather than reconstructing application policy during rendering.
|
|
425
|
+
|
|
426
|
+
## Architectural dependencies versus reactive flow
|
|
427
|
+
|
|
428
|
+
It is useful to think about two different diagrams.
|
|
429
|
+
|
|
430
|
+
The architectural dependency structure may look roughly like:
|
|
431
|
+
|
|
432
|
+
```text
|
|
433
|
+
views/components
|
|
434
|
+
│
|
|
435
|
+
▼
|
|
436
|
+
view services
|
|
437
|
+
│
|
|
438
|
+
├────────► domain/shared logic
|
|
439
|
+
│
|
|
440
|
+
▼
|
|
441
|
+
backend-facing services
|
|
442
|
+
│
|
|
443
|
+
▼
|
|
444
|
+
API/transport
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
This describes what code knows about and imports.
|
|
448
|
+
|
|
449
|
+
Reactive runtime flow can travel through that structure in either direction:
|
|
450
|
+
|
|
451
|
+
```text
|
|
452
|
+
user interaction
|
|
453
|
+
↓
|
|
454
|
+
Emitter
|
|
455
|
+
↓
|
|
456
|
+
derivation/query argument
|
|
457
|
+
↓
|
|
458
|
+
query
|
|
459
|
+
↓
|
|
460
|
+
result
|
|
461
|
+
↓
|
|
462
|
+
view
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
A component can therefore initiate a change that eventually causes a backend query without the backend-facing service depending on that component.
|
|
466
|
+
|
|
467
|
+
Prefer clean knowledge and ownership boundaries rather than trying to force all runtime values into a single direction.
|
|
468
|
+
|
|
469
|
+
## Demo and development infrastructure
|
|
470
|
+
|
|
471
|
+
If an application contains substantial infrastructure purely to make a demo self-contained, keep it visibly separate from the example application itself.
|
|
472
|
+
|
|
473
|
+
For example:
|
|
474
|
+
|
|
475
|
+
```text
|
|
476
|
+
src/
|
|
477
|
+
... normal Capillary UI application ...
|
|
478
|
+
|
|
479
|
+
demo-support/
|
|
480
|
+
scenario/
|
|
481
|
+
transport/
|
|
482
|
+
worker/
|
|
483
|
+
server/
|
|
484
|
+
cli/
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
`src/` should demonstrate what an ordinary Capillary UI application looks like.
|
|
488
|
+
|
|
489
|
+
`demo-support/` may contain:
|
|
490
|
+
|
|
491
|
+
* deterministic scenario generators;
|
|
492
|
+
* simulated backends;
|
|
493
|
+
* embedded Fetch-compatible transports;
|
|
494
|
+
* Web Workers used to run the simulation;
|
|
495
|
+
* Node HTTP servers;
|
|
496
|
+
* scenario-generation CLI tools.
|
|
497
|
+
|
|
498
|
+
These exist to make the demo self-contained. They are not part of the recommended architecture of a normal Capillary UI application.
|
|
499
|
+
|
|
500
|
+
A developer should be able to inspect `src/` without getting the impression that scenario generation, an embedded server, or similar infrastructure is required by Capillary UI.
|
|
501
|
+
|
|
502
|
+
Ideally, the application source should still make architectural sense if `demo-support/` were replaced by a real backend.
|
|
503
|
+
|
|
504
|
+
## Naming
|
|
505
|
+
|
|
506
|
+
Prefer names that communicate responsibility directly.
|
|
507
|
+
|
|
508
|
+
Prefer:
|
|
509
|
+
|
|
510
|
+
```text
|
|
511
|
+
domain/
|
|
512
|
+
services/
|
|
513
|
+
views/
|
|
514
|
+
transport/
|
|
515
|
+
api/
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
over broad architectural names such as:
|
|
519
|
+
|
|
520
|
+
```text
|
|
521
|
+
core/
|
|
522
|
+
common/
|
|
523
|
+
logic/
|
|
524
|
+
misc/
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
Similarly, prefer explicit filenames such as:
|
|
528
|
+
|
|
529
|
+
```text
|
|
530
|
+
scheduleViewService.ts
|
|
531
|
+
scenarioApi.ts
|
|
532
|
+
ScenarioFetch.ts
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
over several unrelated files all named:
|
|
536
|
+
|
|
537
|
+
```text
|
|
538
|
+
contract.ts
|
|
539
|
+
model.ts
|
|
540
|
+
helpers.ts
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
when the more specific name improves navigation.
|
|
544
|
+
|
|
545
|
+
## General rule
|
|
546
|
+
|
|
547
|
+
The overarching convention is:
|
|
548
|
+
|
|
549
|
+
> Organize by architectural responsibility at the top level and by feature within the UI. Colocate code that changes together, keep backend-facing services faithful to the backend, put view-specific composition and derivation beside the view, and promote code into shared or domain layers only when it has genuinely broader meaning.
|
|
550
|
+
|
|
551
|
+
Do not confuse architectural dependency with reactive data flow. Capillary UI controls may write Capillary emitters that feed into derivations and queries, and query results may in turn update what those views display. This is a normal part of the Capillary/Capillary UI model.
|
|
552
|
+
|
|
553
|
+
A good Capillary UI application layout should reveal the application's own architecture without imposing a large framework-specific hierarchy.
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "module",
|
|
3
|
+
"name": "@capillaryjs/capillary-ui",
|
|
4
|
+
"private": false,
|
|
5
|
+
"version": "1.0.0-alpha.1",
|
|
6
|
+
"description": "Browser-only TypeScript component runtime, JSX controls, and semantic themes.",
|
|
7
|
+
"license": "Apache-2.0",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "Sylwell Software",
|
|
10
|
+
"email": "npm@sylwellsoftware.com",
|
|
11
|
+
"url": "https://sylwellsoftware.com"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/capillaryjs/capillaryjs.git",
|
|
16
|
+
"directory": "packages/capillary-ui"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/capillaryjs/capillaryjs#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/capillaryjs/capillaryjs/issues"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"components",
|
|
24
|
+
"jsx",
|
|
25
|
+
"reactive",
|
|
26
|
+
"typescript"
|
|
27
|
+
],
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"main": "dist/index.js",
|
|
32
|
+
"module": "dist/index.js",
|
|
33
|
+
"types": "dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./jsx-runtime": {
|
|
40
|
+
"types": "./dist/jsx-runtime.d.ts",
|
|
41
|
+
"import": "./dist/jsx-runtime.js"
|
|
42
|
+
},
|
|
43
|
+
"./jsx-dev-runtime": {
|
|
44
|
+
"types": "./dist/jsx-dev-runtime.d.ts",
|
|
45
|
+
"import": "./dist/jsx-dev-runtime.js"
|
|
46
|
+
},
|
|
47
|
+
"./styles/structural.css": "./styles/structural.css",
|
|
48
|
+
"./themes/base.css": "./themes/base.css",
|
|
49
|
+
"./themes/*/theme.css": "./themes/*/theme.css",
|
|
50
|
+
"./colors/*/colors.css": "./colors/*/colors.css"
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"dist",
|
|
54
|
+
"styles",
|
|
55
|
+
"themes",
|
|
56
|
+
"colors",
|
|
57
|
+
"docs/application-composition-guide.md",
|
|
58
|
+
"docs/application-layout-guide.md",
|
|
59
|
+
"CHANGELOG.md",
|
|
60
|
+
"LICENSE",
|
|
61
|
+
"NOTICE"
|
|
62
|
+
],
|
|
63
|
+
"sideEffects": [
|
|
64
|
+
"./styles/*.css",
|
|
65
|
+
"./colors/**/*.css",
|
|
66
|
+
"./themes/**/*.css"
|
|
67
|
+
],
|
|
68
|
+
"scripts": {
|
|
69
|
+
"build": "pnpm build:styles && vite build && tsc -p tsconfig.build.json",
|
|
70
|
+
"build:styles": "node --import tsx scripts/build-structural-css.mjs",
|
|
71
|
+
"prepack": "pnpm typecheck && pnpm test && pnpm build && pnpm test:types:consumer",
|
|
72
|
+
"test": "node --import tsx --test test/*.test.ts",
|
|
73
|
+
"test:types:consumer": "tsc -p test-types/consumer/tsconfig.json --noEmit",
|
|
74
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
75
|
+
"watch": "vite build --watch",
|
|
76
|
+
"dev": "vite"
|
|
77
|
+
},
|
|
78
|
+
"peerDependencies": {
|
|
79
|
+
"@capillaryjs/capillary": "^1.0.0-alpha.1"
|
|
80
|
+
},
|
|
81
|
+
"devDependencies": {
|
|
82
|
+
"@capillaryjs/capillary": "^1.0.0-alpha.1",
|
|
83
|
+
"vite": "^6.3.5"
|
|
84
|
+
},
|
|
85
|
+
"engines": {
|
|
86
|
+
"node": ">=22",
|
|
87
|
+
"pnpm": ">=10"
|
|
88
|
+
},
|
|
89
|
+
"packageManager": "pnpm@10.11.0"
|
|
90
|
+
}
|