@reventlessdev/reventless-ui-slots 3.0.0-alpha.2 → 3.0.0-alpha.3
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 +12 -5
- package/package.json +2 -2
- package/src/ReventlessSlots.res +16 -1
- package/src/ReventlessSlots.res.mjs +27 -5
- package/src/ReventlessSlots.resi +31 -6
- package/src/index.d.ts +16 -8
package/README.md
CHANGED
|
@@ -145,6 +145,11 @@ the question.
|
|
|
145
145
|
| `tracker.summary` | row | the line beside one row's name; its summary fields |
|
|
146
146
|
| `detail.media` | row | the media column of a `detailLayout: "media"` page; the record's picture |
|
|
147
147
|
| `detail.aside` | row | above the field set on a `detailLayout: "media"` page; nothing by default |
|
|
148
|
+
| `list.selection` | view | the bar over a list whose rows the caller can pick out: what is picked, a way to empty it, and the one command that takes the lot |
|
|
149
|
+
|
|
150
|
+
`list.selection` is the one id that is not `<mode>.<region>`: it belongs to the
|
|
151
|
+
list itself rather than to a mode, which is what lets a picking made in the table
|
|
152
|
+
survive a switch to cards.
|
|
148
153
|
|
|
149
154
|
An id nothing offers is reported to the console at boot — a renderer nothing will
|
|
150
155
|
ever call is a mistake the running app would otherwise never mention.
|
|
@@ -156,7 +161,7 @@ ever call is a mistake the running app would otherwise never mention.
|
|
|
156
161
|
{ row, label?, image?, open?, actions? }
|
|
157
162
|
|
|
158
163
|
// view slot
|
|
159
|
-
{ rows, total?, selection?, run? }
|
|
164
|
+
{ rows, total?, selection?, picked?, run? }
|
|
160
165
|
```
|
|
161
166
|
|
|
162
167
|
`row` is the read model's own JSON. `image` is already resolved for this
|
|
@@ -164,10 +169,12 @@ deployment's asset origins. `actions` are already resolved against the
|
|
|
164
169
|
deployment's declarations, the caller's permissions and the row's lifecycle
|
|
165
170
|
state. `open` drills into the row.
|
|
166
171
|
|
|
167
|
-
`selection`
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
a
|
|
172
|
+
`selection` is the picked row **ids**; `picked` is the rows behind them, each as
|
|
173
|
+
the same row-slot payload above. Both, and not just the ids, because a list's
|
|
174
|
+
window is replaced page by page: a row picked on page 1 is gone from `rows` by
|
|
175
|
+
the time the caller is on page 3, and a bar whose job is to name what is in it
|
|
176
|
+
cannot look one up. `run` takes the command's name and opens its form with the
|
|
177
|
+
picked ids already in place.
|
|
171
178
|
|
|
172
179
|
## What a slot may not do
|
|
173
180
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-ui-slots",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.3",
|
|
4
4
|
"description": "Types and one runtime helper for writing custom renderers into the regions of Reventless AutoUI's standard view modes.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"react-dom": "^18.3.1",
|
|
55
55
|
"rescript": "^12.3.0"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "d2a7156f66c7f5f42837c6d5c13faf6d33a6df7e"
|
|
58
58
|
}
|
package/src/ReventlessSlots.res
CHANGED
|
@@ -20,6 +20,7 @@ type viewPayload = {
|
|
|
20
20
|
rows: array<JSON.t>,
|
|
21
21
|
total?: int,
|
|
22
22
|
selection?: array<string>,
|
|
23
|
+
picked?: array<rowPayload>,
|
|
23
24
|
run?: string => unit,
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -144,6 +145,19 @@ module Format = {
|
|
|
144
145
|
let at = Date.fromString(iso)
|
|
145
146
|
Float.isNaN(Date.getTime(at)) ? "" : Date.toLocaleDateString(at)
|
|
146
147
|
}
|
|
148
|
+
|
|
149
|
+
let pad = (n: int): string => n < 10 ? "0" ++ Int.toString(n) : Int.toString(n)
|
|
150
|
+
|
|
151
|
+
let isoDay = (iso: string): string => {
|
|
152
|
+
let at = Date.fromString(iso)
|
|
153
|
+
Float.isNaN(Date.getTime(at))
|
|
154
|
+
? ""
|
|
155
|
+
: Int.toString(Date.getFullYear(at)) ++
|
|
156
|
+
"-" ++
|
|
157
|
+
pad(Date.getMonth(at) + 1) ++
|
|
158
|
+
"-" ++
|
|
159
|
+
pad(Date.getDate(at))
|
|
160
|
+
}
|
|
147
161
|
}
|
|
148
162
|
|
|
149
163
|
let titleOf = (payload: rowPayload): string =>
|
|
@@ -208,5 +222,6 @@ module RowSlot = {
|
|
|
208
222
|
module ViewSlot = {
|
|
209
223
|
let cardsEmpty = "cards.empty"
|
|
210
224
|
let galleryEmpty = "gallery.empty"
|
|
211
|
-
let
|
|
225
|
+
let listSelection = "list.selection"
|
|
226
|
+
let all = [cardsEmpty, galleryEmpty, listSelection]
|
|
212
227
|
}
|
|
@@ -121,10 +121,22 @@ function day(iso) {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
124
|
+
function pad(n) {
|
|
125
|
+
if (n < 10) {
|
|
126
|
+
return "0" + n.toString();
|
|
127
|
+
} else {
|
|
128
|
+
return n.toString();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function isoDay(iso) {
|
|
133
|
+
let at = new Date(iso);
|
|
134
|
+
if (Number.isNaN(at.getTime())) {
|
|
135
|
+
return "";
|
|
136
|
+
} else {
|
|
137
|
+
return at.getFullYear().toString() + "-" + pad(at.getMonth() + 1 | 0) + "-" + pad(at.getDate());
|
|
138
|
+
}
|
|
139
|
+
}
|
|
128
140
|
|
|
129
141
|
function titleOf(payload) {
|
|
130
142
|
let label = payload.label;
|
|
@@ -189,17 +201,27 @@ let cardsEmpty = "cards.empty";
|
|
|
189
201
|
|
|
190
202
|
let galleryEmpty = "gallery.empty";
|
|
191
203
|
|
|
204
|
+
let listSelection = "list.selection";
|
|
205
|
+
|
|
192
206
|
let all$1 = [
|
|
193
207
|
cardsEmpty,
|
|
194
|
-
galleryEmpty
|
|
208
|
+
galleryEmpty,
|
|
209
|
+
listSelection
|
|
195
210
|
];
|
|
196
211
|
|
|
197
212
|
let ViewSlot = {
|
|
198
213
|
cardsEmpty: cardsEmpty,
|
|
199
214
|
galleryEmpty: galleryEmpty,
|
|
215
|
+
listSelection: listSelection,
|
|
200
216
|
all: all$1
|
|
201
217
|
};
|
|
202
218
|
|
|
219
|
+
let Format = {
|
|
220
|
+
money: money$1,
|
|
221
|
+
day: day,
|
|
222
|
+
isoDay: isoDay
|
|
223
|
+
};
|
|
224
|
+
|
|
203
225
|
export {
|
|
204
226
|
h,
|
|
205
227
|
RowSlot,
|
package/src/ReventlessSlots.resi
CHANGED
|
@@ -42,17 +42,21 @@ type rowPayload = {
|
|
|
42
42
|
actions?: array<action>,
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
/** What a per-view region is handed.
|
|
46
|
-
filled by nothing yet — cross-row selection is its own piece of work. They
|
|
47
|
-
are in the contract from the start because discovering that a region needs a
|
|
48
|
-
second arity after publishing would be a breaking change. */
|
|
45
|
+
/** What a per-view region is handed. */
|
|
49
46
|
type viewPayload = {
|
|
50
47
|
/** The rows the mode is currently drawing — its page window, not the table. */
|
|
51
48
|
rows: array<JSON.t>,
|
|
52
49
|
/** How many rows that window holds. */
|
|
53
50
|
total?: int,
|
|
54
|
-
/** Row ids the caller has picked out, where the
|
|
51
|
+
/** Row ids the caller has picked out, where the view offers picking. */
|
|
55
52
|
selection?: array<string>,
|
|
53
|
+
/** The rows behind `selection`, as they were when picked.
|
|
54
|
+
|
|
55
|
+
A list's window is replaced page by page, so a row picked on page 1 is
|
|
56
|
+
gone from `rows` by the time the caller is on page 3 — and a bar whose job
|
|
57
|
+
is to name what is in it cannot look one up. So the rows travel, each as
|
|
58
|
+
the same `rowPayload` a per-row region is handed. */
|
|
59
|
+
picked?: array<rowPayload>,
|
|
56
60
|
/** Start the region's one command, by name. */
|
|
57
61
|
run?: string => unit,
|
|
58
62
|
}
|
|
@@ -187,8 +191,21 @@ module Format: {
|
|
|
187
191
|
most currencies and quietly wrong for JPY and TND. */
|
|
188
192
|
let money: ((float, string)) => string
|
|
189
193
|
|
|
190
|
-
/** An ISO instant as a short
|
|
194
|
+
/** An ISO instant as a short date **in the viewer's own locale**.
|
|
195
|
+
|
|
196
|
+
Which format that is comes from the runtime, not from you or from the
|
|
197
|
+
deployment: the same order reads `9/4/2026` to one customer and `04/09/2026`
|
|
198
|
+
to another, and a screenshot never matches CI. That is right for a surface
|
|
199
|
+
whose readers are the public, and wrong wherever a date has to be
|
|
200
|
+
unambiguous or stable — take `isoDay` there. */
|
|
191
201
|
let day: string => string
|
|
202
|
+
|
|
203
|
+
/** An ISO instant as `YYYY-MM-DD`, the same everywhere.
|
|
204
|
+
|
|
205
|
+
Built from the **local** calendar parts rather than by slicing the string,
|
|
206
|
+
which would silently publish the UTC date and land a day out either side of
|
|
207
|
+
midnight for most of the world. */
|
|
208
|
+
let isoDay: string => string
|
|
192
209
|
}
|
|
193
210
|
|
|
194
211
|
/** What the mode would have titled this row, else the row's own `name`.
|
|
@@ -216,5 +233,13 @@ module ViewSlot: {
|
|
|
216
233
|
let cardsEmpty: string
|
|
217
234
|
/** The tile grid when the view has no rows. */
|
|
218
235
|
let galleryEmpty: string
|
|
236
|
+
/** The bar over a list whose rows the caller can pick out: what is picked, a
|
|
237
|
+
way to empty it, and the one command that takes the lot.
|
|
238
|
+
|
|
239
|
+
Offered by the list producer rather than by a view mode — the first id
|
|
240
|
+
that is not `<mode>.<region>`. The list renders the mode inside its own
|
|
241
|
+
chrome and the bar is that chrome, so a picking made in the table survives
|
|
242
|
+
a switch to cards and the bar has to outlive both. */
|
|
243
|
+
let listSelection: string
|
|
219
244
|
let all: array<string>
|
|
220
245
|
}
|
package/src/index.d.ts
CHANGED
|
@@ -48,19 +48,21 @@ export interface RowPayload<Row = Record<string, unknown>> {
|
|
|
48
48
|
actions?: SlotAction[]
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
/** What a per-view region is handed.
|
|
52
|
-
*
|
|
53
|
-
* `selection` and `run` are declared and filled by nothing yet: cross-row
|
|
54
|
-
* selection is its own piece of work. They are here from the start because
|
|
55
|
-
* discovering that a region needs a second arity after the contract is
|
|
56
|
-
* published would be a breaking change. */
|
|
51
|
+
/** What a per-view region is handed. */
|
|
57
52
|
export interface ViewPayload<Row = Record<string, unknown>> {
|
|
58
53
|
/** The rows the mode is currently drawing — its page window, not the table. */
|
|
59
54
|
rows: Row[]
|
|
60
55
|
/** How many rows that window holds. */
|
|
61
56
|
total?: number
|
|
62
|
-
/** Row ids the caller has picked out, where the
|
|
57
|
+
/** Row ids the caller has picked out, where the view offers picking. */
|
|
63
58
|
selection?: string[]
|
|
59
|
+
/** The rows behind `selection`, as they were when picked.
|
|
60
|
+
*
|
|
61
|
+
* A list's window is replaced page by page, so a row picked on page 1 is gone
|
|
62
|
+
* from `rows` by the time the caller is on page 3 — and a bar whose job is to
|
|
63
|
+
* name what is in it cannot look one up. So the rows travel, each as the same
|
|
64
|
+
* `RowPayload` a per-row region is handed. */
|
|
65
|
+
picked?: RowPayload<Row>[]
|
|
64
66
|
/** Start the region's one command, by name. */
|
|
65
67
|
run?: (command: string) => void
|
|
66
68
|
}
|
|
@@ -126,8 +128,14 @@ export type RowSlotId =
|
|
|
126
128
|
* | --- | --- |
|
|
127
129
|
* | `cards.empty` | the card grid when the view has no rows |
|
|
128
130
|
* | `gallery.empty` | the tile grid when the view has no rows |
|
|
131
|
+
* | `list.selection` | the bar over a list whose rows the caller can pick out |
|
|
132
|
+
*
|
|
133
|
+
* `list.selection` is the one id that is not `<mode>.<region>`: it belongs to
|
|
134
|
+
* the list producer, not to a mode. The list renders the mode inside its own
|
|
135
|
+
* chrome and the bar is that chrome, so a picking made in the table survives a
|
|
136
|
+
* switch to cards and the bar has to outlive both.
|
|
129
137
|
*/
|
|
130
|
-
export type ViewSlotId = 'cards.empty' | 'gallery.empty'
|
|
138
|
+
export type ViewSlotId = 'cards.empty' | 'gallery.empty' | 'list.selection'
|
|
131
139
|
|
|
132
140
|
/**
|
|
133
141
|
* Identity helper: type-checks a `register` function without changing it.
|