@jsenv/navi 0.29.399 → 0.29.400
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/dist/dev/jsenv_navi.js +754 -233
- package/dist/dev/jsenv_navi.js.map +19 -18
- package/dist/jsenv_navi.js +754 -233
- package/dist/jsenv_navi.js.map +19 -18
- package/docs/AI_INSTRUCTIONS.md +10 -4
- package/docs/control_value.md +52 -6
- package/docs/drag_to_travel.md +32 -0
- package/docs/navigation.md +81 -1
- package/docs/popup_open.md +7 -9
- package/docs/scroll.md +3 -3
- package/package.json +2 -2
package/docs/AI_INSTRUCTIONS.md
CHANGED
|
@@ -71,9 +71,10 @@ to start when unsure which export solves a problem.
|
|
|
71
71
|
|
|
72
72
|
- `navigation.md` — the position of the user belongs in the URL by default,
|
|
73
73
|
and that decision is not retrofittable: routes, params, search params,
|
|
74
|
-
`<Route>`, tab rows, `navBack`, `RouteTravel`, where a navigation lands
|
|
75
|
-
`
|
|
76
|
-
say in its address. Read before
|
|
74
|
+
`<Route>`, tab rows, `navBack`, `RouteTravel`, where a navigation lands (a
|
|
75
|
+
`#id` landing on the element it names), a `SlideContainer` read from the URL,
|
|
76
|
+
and what a layer drawn over the screen may say in its address. Read before
|
|
77
|
+
writing any routing code, and before scrolling to an element on arrival.
|
|
77
78
|
- `route_transitions.md` — a transition states a relation the user reads as a
|
|
78
79
|
map; a pair of routes is animated by `RouteTravel` or by a transition, never
|
|
79
80
|
both; a test waits for the page arriving, never for its address. Read before
|
|
@@ -137,7 +138,9 @@ to start when unsure which export solves a problem.
|
|
|
137
138
|
`action`, `command` + `commandFor`). Read before writing any handler whose
|
|
138
139
|
body only assigns state.
|
|
139
140
|
- `control_value.md` — who holds a control's value; `--navi-update` for a
|
|
140
|
-
button proposing a value;
|
|
141
|
+
button proposing a value; a `defaultValue` follows the record it was read
|
|
142
|
+
from (no `key` to remount); drawing what a picker holds (`ui={Component}`,
|
|
143
|
+
not a signal of your own); empty keeps the shape of the question; what a
|
|
141
144
|
`stateSignal` brings; a time of day typed (`TimeSpin`) or turned
|
|
142
145
|
(`TimeWheel`). Read before wiring a value with `value` + `uiAction`.
|
|
143
146
|
- `control_object.md` — one value made of several controls: `ControlGroup`
|
|
@@ -259,6 +262,9 @@ to start when unsure which export solves a problem.
|
|
|
259
262
|
- **Routing is signal-based**: URL state (including search params) two-way
|
|
260
263
|
syncs with signals. Don't build parallel state for what a route/query
|
|
261
264
|
signal already tracks.
|
|
265
|
+
- **A link lands on an element by its fragment**: give the element an `id` and
|
|
266
|
+
link to `#id`. Never a search param plus `scrollIntoView` in an effect (see
|
|
267
|
+
`navigation.md`).
|
|
262
268
|
- **Actions** model async operations with a lifecycle (idle, running,
|
|
263
269
|
completed, failed, aborted). Components read an action's state via
|
|
264
270
|
`useAsyncData`, not by manually tracking loading/error booleans. Reading does
|
package/docs/control_value.md
CHANGED
|
@@ -10,6 +10,8 @@ somewhere else in the app.
|
|
|
10
10
|
- [A button that proposes a value is `--navi-update`](#a-button-that-proposes-a-value-is---navi-update)
|
|
11
11
|
- [`--navi-update:smooth`: the control is seen answering](#--navi-updatesmooth-the-control-is-seen-answering)
|
|
12
12
|
- [`signal` + `defaultValue`: the answer and where it starts](#signal--defaultvalue-the-answer-and-where-it-starts)
|
|
13
|
+
- [A `defaultValue` follows what it was read from](#a-defaultvalue-follows-what-it-was-read-from)
|
|
14
|
+
- [Drawing what a control holds](#drawing-what-a-control-holds)
|
|
13
15
|
- [What a signal holds, control by control](#what-a-signal-holds-control-by-control)
|
|
14
16
|
- [Empty keeps the shape of the question](#empty-keeps-the-shape-of-the-question)
|
|
15
17
|
- [Which controls take a `signal`](#which-controls-take-a-signal)
|
|
@@ -22,12 +24,12 @@ somewhere else in the app.
|
|
|
22
24
|
|
|
23
25
|
## The three answers
|
|
24
26
|
|
|
25
|
-
| what you pass | who holds the value | when the user acts
|
|
26
|
-
| ---------------------- | ------------------- |
|
|
27
|
-
| nothing | the control | it keeps it; `uiAction` tells you
|
|
28
|
-
| `defaultValue` | the control | same — the default is
|
|
29
|
-
| `signal` | the signal | the control writes it back, both ways
|
|
30
|
-
| `value` (or `checked`) | you | nothing moves until you hand a new one down
|
|
27
|
+
| what you pass | who holds the value | when the user acts |
|
|
28
|
+
| ---------------------- | ------------------- | ------------------------------------------------------------------------------------- |
|
|
29
|
+
| nothing | the control | it keeps it; `uiAction` tells you |
|
|
30
|
+
| `defaultValue` | the control | same — the default is where it starts, and a new one is taken while nothing is edited |
|
|
31
|
+
| `signal` | the signal | the control writes it back, both ways |
|
|
32
|
+
| `value` (or `checked`) | you | nothing moves until you hand a new one down |
|
|
31
33
|
|
|
32
34
|
A control given `value` and nothing to listen to it (`uiAction`, `action`, a
|
|
33
35
|
`signal`, a surrounding form) is read-only, and says so in dev: it is showing
|
|
@@ -228,6 +230,50 @@ default rather than leaving it blank — which is what makes "nothing decided
|
|
|
228
230
|
here, use the usual answer" expressible at all. Without a `defaultValue`, an
|
|
229
231
|
emptied signal empties the control.
|
|
230
232
|
|
|
233
|
+
## A `defaultValue` follows what it was read from
|
|
234
|
+
|
|
235
|
+
A field editing a record starts on that record, `defaultValue={user.first_name}`,
|
|
236
|
+
and the record moves after mount: the save comes back normalized (a trailing
|
|
237
|
+
space trimmed), another screen or device changed it, a refresh arrived. The
|
|
238
|
+
control takes the new default **while it holds no edit** — nothing typed, picked
|
|
239
|
+
or toggled since the value the outside last accepted. An edit is never undone:
|
|
240
|
+
the default waits, and lands once that edit is accepted (the action succeeded)
|
|
241
|
+
or taken back (the action failed, the popup was cancelled).
|
|
242
|
+
|
|
243
|
+
This holds for a control, for a group given a `defaultValue` (a selectable list,
|
|
244
|
+
a `ControlGroup`), and for everything inside a picker's popup, which stays
|
|
245
|
+
mounted while closed. So the record goes in as `defaultValue` and nothing
|
|
246
|
+
else: no `key` to remount the popup when it changes. A key is worse than
|
|
247
|
+
unnecessary here, since it also destroys whatever is being typed when the
|
|
248
|
+
answer to ANOTHER field arrives.
|
|
249
|
+
|
|
250
|
+
A picker's cancel follows the same line. It puts back what the picker held at
|
|
251
|
+
open, which undoes the person's edits, but what the outside moved during the
|
|
252
|
+
opening stays moved.
|
|
253
|
+
|
|
254
|
+
## Drawing what a control holds
|
|
255
|
+
|
|
256
|
+
A picker's trigger usually shows the choice (a label for a code, a summary of
|
|
257
|
+
an object). Read it from the picker rather than keeping a copy:
|
|
258
|
+
|
|
259
|
+
```jsx
|
|
260
|
+
const VisibilityLabel = ({ value }) => <Text>{labelOf(value)}</Text>;
|
|
261
|
+
|
|
262
|
+
<Picker name="visibility" defaultValue={user.visibility} ui={VisibilityLabel}>
|
|
263
|
+
…
|
|
264
|
+
</Picker>;
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
`ui={Component}` is handed `value`, `loading` and `interactive`. A `ui` given as
|
|
268
|
+
an element reads the same three with `usePickerState()`.
|
|
269
|
+
|
|
270
|
+
What not to write: `const s = useSignal(defaultValue)` bound as `signal={s}`,
|
|
271
|
+
just to have something to read. `useSignal` reads its argument once, so the
|
|
272
|
+
signal never hears the record move, and a bound signal takes precedence over the
|
|
273
|
+
control's own `defaultValue`. The field is stuck on its first value. A signal is
|
|
274
|
+
for a value the app owns and writes itself (a url param, state shared between
|
|
275
|
+
screens), not a mirror kept for drawing.
|
|
276
|
+
|
|
231
277
|
## What a signal holds, control by control
|
|
232
278
|
|
|
233
279
|
The signal holds what the control is ABOUT, which is not always its `value`
|
package/docs/drag_to_travel.md
CHANGED
|
@@ -59,6 +59,10 @@ and are referenced from here rather than restated.
|
|
|
59
59
|
because the picture alone decided. Only a release at rest, or a slow retreat,
|
|
60
60
|
is judged by the picture — about a third of a box — because there the
|
|
61
61
|
position is the only witness left.
|
|
62
|
+
- **A travel caught in flight and thrown on the way it was going asks for the
|
|
63
|
+
one after.** Two swipes the same way are two screens, however close
|
|
64
|
+
together: the second one is not a vote for the screen already arriving. See
|
|
65
|
+
[below](#a-hand-reaching-for-something-still-moving-is-reaching-for-that-thing).
|
|
62
66
|
- **The bars those verdicts compare against sit well below the speed the
|
|
63
67
|
fingertip actually has, and they must.** Velocity is averaged over a trailing
|
|
64
68
|
window (pointer events arrive irregularly, and the last one before a release
|
|
@@ -449,6 +453,26 @@ Taking over means the pictures stop where they are and answer the finger again,
|
|
|
449
453
|
from where they stand (`slack`) rather than from zero. Only one box is in hand,
|
|
450
454
|
and walking out of either of its ends is a travel of its own — see below.
|
|
451
455
|
|
|
456
|
+
What letting go of it again means is read from the hand, three ways:
|
|
457
|
+
|
|
458
|
+
- **merely touched** — a press that moved less than a gesture's worth: nobody
|
|
459
|
+
asked the travel to stop, it was asked to wait, and it carries on to where it
|
|
460
|
+
was going;
|
|
461
|
+
- **thrown back** — against the way it was going, fast: everything goes back;
|
|
462
|
+
- **thrown on** — the way it was already going, fast, having moved by more than
|
|
463
|
+
a tremor: that is a second push, and it asks for the screen AFTER the one
|
|
464
|
+
arriving (`thrownOn`). Read as a verdict on the box in hand, it only confirms
|
|
465
|
+
what was already arriving — the travel stops at the press and goes on to the
|
|
466
|
+
same place, and the hand feels its second swipe swallowed. So the gesture
|
|
467
|
+
asks for the next box at the release (`onEdge` with `thrown`), with the
|
|
468
|
+
picture still short of the end of the one in hand, and nothing on screen
|
|
469
|
+
moves for it: the travel goes on from where the hand left it, to one screen
|
|
470
|
+
further. It is the wheel's rule (a second push over the tail is a screen, not
|
|
471
|
+
credit towards one) said for a hand.
|
|
472
|
+
|
|
473
|
+
A slow hand going the same way and stopping before it lets go is not thrown:
|
|
474
|
+
there the picture decides, and the screen arriving arrives.
|
|
475
|
+
|
|
452
476
|
### A hand that does not stop at the end of a page is asking for the next one
|
|
453
477
|
|
|
454
478
|
One travel brings in one neighbour, but a gesture is not over because a travel
|
|
@@ -470,6 +494,14 @@ The two ends cost differently, and it is worth knowing which one is being felt:
|
|
|
470
494
|
one instead. The travel turns around where it stands, on the same transition,
|
|
471
495
|
and there is no gap at all.
|
|
472
496
|
|
|
497
|
+
That cost is a `RouteTravel` one: a `SlideContainer` has every slide mounted,
|
|
498
|
+
so handing over is only re-staging — the slide reached becomes the one dragged,
|
|
499
|
+
the one left stays beside it, the slide past it is put on the other side, and
|
|
500
|
+
nothing on screen moves. Which is also why only a `SlideContainer` answers a
|
|
501
|
+
throw (`thrown`, above): a `RouteTravel` would have to jump its pictures the
|
|
502
|
+
rest of the way before handing over, a page seen leaping, so it declines and
|
|
503
|
+
the page caught simply arrives.
|
|
504
|
+
|
|
473
505
|
What the browser will not turn around with it is everything ELSE the
|
|
474
506
|
transition carries — see [One gesture that bar cannot
|
|
475
507
|
follow](#one-gesture-that-bar-cannot-follow).
|
package/docs/navigation.md
CHANGED
|
@@ -16,6 +16,7 @@ linking to them, and turning them into tabs.
|
|
|
16
16
|
- [The back arrow: `navBack`](#the-back-arrow-navback)
|
|
17
17
|
- [Tabs that travel: `RouteTravel`](#tabs-that-travel-routetravel)
|
|
18
18
|
- [Where a navigation lands: the scroll](#where-a-navigation-lands-the-scroll)
|
|
19
|
+
- [Landing on an element: the fragment](#landing-on-an-element-the-fragment)
|
|
19
20
|
- [Creating something, then editing it](#creating-something-then-editing-it)
|
|
20
21
|
- [Tabs that are not routes](#tabs-that-are-not-routes)
|
|
21
22
|
- [A `SlideContainer` in the URL: a position that is not a place one came from](#a-slidecontainer-in-the-url-a-position-that-is-not-a-place-one-came-from)
|
|
@@ -694,7 +695,7 @@ the two, never both: see [route_transitions.md](./route_transitions.md).
|
|
|
694
695
|
|
|
695
696
|
## Where a navigation lands: the scroll
|
|
696
697
|
|
|
697
|
-
|
|
698
|
+
Five cases, and they are not a policy to configure but five different facts:
|
|
698
699
|
|
|
699
700
|
- **Going somewhere new** (a `<Link>`, anything that pushes to another path)
|
|
700
701
|
lands at the top. It is an arrival: the offset one had elsewhere means nothing
|
|
@@ -704,6 +705,10 @@ Four cases, and they are not a policy to configure but four different facts:
|
|
|
704
705
|
reader is scrolled in — a [layer](#a-layer-over-the-screen-what-its-address-may-say)
|
|
705
706
|
opening, a [state whose values are places](#a-state-whose-values-are-places-history-push)
|
|
706
707
|
written — and moves nothing, like a replace.
|
|
708
|
+
- **Going somewhere new, to an element** (`/places/le-set#tournaments`) lands
|
|
709
|
+
on the element whose `id` is the fragment, once it is rendered — even when it
|
|
710
|
+
arrives with the data a second later. See
|
|
711
|
+
[Landing on an element](#landing-on-an-element-the-fragment).
|
|
707
712
|
- **Going back or forward** (the browser's buttons, `navBack()`,
|
|
708
713
|
`history.back()`) lands where that page was left. navi keeps the position and
|
|
709
714
|
puts it back once the page is really rendered, which is what the browser
|
|
@@ -732,6 +737,81 @@ in a browser with no Navigation API — is `navBack()`. Where there may be
|
|
|
732
737
|
nothing to go back to (a shared link opened cold), decide what the arrow does
|
|
733
738
|
from the history, not from the link.
|
|
734
739
|
|
|
740
|
+
### Landing on an element: the fragment
|
|
741
|
+
|
|
742
|
+
A link meant to bring one element under the reader's eyes — a notification
|
|
743
|
+
pointing at a section several screens down, a shared link to a comment, a row
|
|
744
|
+
in a list — is an `id` on the element and a `#id` in the link. Nothing else:
|
|
745
|
+
|
|
746
|
+
```jsx
|
|
747
|
+
<Box id="tournaments">…</Box>
|
|
748
|
+
|
|
749
|
+
// anywhere else
|
|
750
|
+
<Link href={`${PLACE_ROUTE.buildUrl({ slug })}#tournaments`}>…</Link>
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
`<Link route>` builds no fragment, so the link spells its `href`.
|
|
754
|
+
|
|
755
|
+
The browser alone is not enough in an app. It answers a fragment when the
|
|
756
|
+
document finishes loading and on a fragment navigation within the page — both
|
|
757
|
+
before the data has drawn the element — and a navigation navi routes is not a
|
|
758
|
+
fragment navigation at all. So navi answers every URL carrying a hash itself:
|
|
759
|
+
|
|
760
|
+
- **It waits for the element, and for the page.** The element is reached when
|
|
761
|
+
it exists and shows something (`checkVisibility`): one still loading, or
|
|
762
|
+
rendered inside a closed tab or a folded `<details>`, has not arrived yet.
|
|
763
|
+
navi opens nothing to reach it, and reaches it as soon as it shows — the
|
|
764
|
+
reader opening the `<details>`, switching to the tab — while the wait lasts.
|
|
765
|
+
And it is reached once no route or action is loading: until then, what sits
|
|
766
|
+
above it may still be drawn and push it down — and a page reusing the node of
|
|
767
|
+
the page being left (`/places/a#tournaments` → `/places/b#tournaments`) holds
|
|
768
|
+
it before its own data has come.
|
|
769
|
+
- **It gives up.** Once the document has had no route or action loading for
|
|
770
|
+
`graceAfterIdle` (1 s). A link to an element that is gone lands where a link
|
|
771
|
+
without a fragment would — at the top of a page one arrives at — with no
|
|
772
|
+
mark. A document that never stops working is answered after `maxWait`
|
|
773
|
+
(10 s), with the element as it stands.
|
|
774
|
+
- **A return is not an arrival.** Back, forward and a reload land where the
|
|
775
|
+
page was left, as they do without a fragment; the fragment then only puts
|
|
776
|
+
`:target` on its element — no scroll, no ring, no focus.
|
|
777
|
+
- **It answers once per arrival.** What is watched is the path and the hash: a
|
|
778
|
+
search param written while the reader is there (a filter, a page) does not
|
|
779
|
+
throw them back to the element. Pressing the very link one is on answers
|
|
780
|
+
again.
|
|
781
|
+
- **What the reader gets**: the element against the top edge, instantly (what
|
|
782
|
+
the browser does with a fragment); the keyboard focus on it when it is itself
|
|
783
|
+
focusable — an `id` on the link or the button, not on a box around one; and a
|
|
784
|
+
fading ring, the element carrying `data-url-target` for `markDuration` (2 s).
|
|
785
|
+
The ring is coloured by `--navi-url-target-color` and lives in `@layer navi`:
|
|
786
|
+
an unlayered `[data-url-target] { … }` replaces it, `animation: none` removes
|
|
787
|
+
it. Its length is `markDuration`, which also publishes
|
|
788
|
+
`--navi-url-target-duration` to CSS — setting only the variable makes the ring
|
|
789
|
+
and the attribute disagree.
|
|
790
|
+
- **Adjusting it**: `setUrlTargetOptions()`, once, at the app's start — the
|
|
791
|
+
alignment (`block`), `behavior`, `markDuration`, `graceAfterIdle`, `maxWait`.
|
|
792
|
+
|
|
793
|
+
**`:target` is the lasting "this one"**, and `data-url-target` the moment it
|
|
794
|
+
arrived. navi sets `:target` on the element as it lands on it — the browser
|
|
795
|
+
alone never would after a navigation navi routes, nor for an element that
|
|
796
|
+
arrived after the load — and takes it off once the URL stops naming the
|
|
797
|
+
element, which the browser alone would not either: a search param written on
|
|
798
|
+
the page rebuilds the address without its fragment, a back returns to the page
|
|
799
|
+
without one. It stays on the element navi landed on; a node rendered in its
|
|
800
|
+
place later is another one. In JS, `useUrlTargetId()` is the id the hash
|
|
801
|
+
designates, `""` when there is none, re-rendering when it changes.
|
|
802
|
+
|
|
803
|
+
#### A fragment, or a search param
|
|
804
|
+
|
|
805
|
+
A fragment says where to look; a search param says what to show. When the page
|
|
806
|
+
draws something differently for the value — a filter, a selected row, an open
|
|
807
|
+
panel — it is a [search param](#search-params). When the page is the same and
|
|
808
|
+
only the reader's eyes should go somewhere, it is a fragment, down to a single
|
|
809
|
+
row (`#tournament_42`).
|
|
810
|
+
|
|
811
|
+
A search param plus a `scrollIntoView` in an effect rebuilds this, less well:
|
|
812
|
+
the effect fires at mount, before what sits above the element has laid out,
|
|
813
|
+
and nothing ever tells it to stop waiting.
|
|
814
|
+
|
|
735
815
|
### A row of tabs, where a replace IS an arrival
|
|
736
816
|
|
|
737
817
|
The tabs of a `<RouteTravel>` navigate by replacing, and yet each one is another
|
package/docs/popup_open.md
CHANGED
|
@@ -320,12 +320,6 @@ So a dialog whose content is seeded once — an uncontrolled field on a
|
|
|
320
320
|
first render. Learning it afterwards would mean mounting on the previous subject
|
|
321
321
|
and correcting it, which is a flicker at best and stale fields at worst.
|
|
322
322
|
|
|
323
|
-
One opening does not follow that order: a `mount="while-opened"` popup pressed on
|
|
324
|
-
its own `anchor` (a picker's trigger, an expandable's UI part) has its content
|
|
325
|
-
built by the press, ahead of the click (see
|
|
326
|
-
[what the popup holds while it is closed](#what-the-popup-holds-while-it-is-closed)). A popup opened ON something is
|
|
327
|
-
opened by a command pressed elsewhere, and keeps the order above.
|
|
328
|
-
|
|
329
323
|
The two other places one could listen are not that moment, and it is worth
|
|
330
324
|
knowing why:
|
|
331
325
|
|
|
@@ -1169,9 +1163,13 @@ off it, fields a surrounding form submits, a size measured from outside.
|
|
|
1169
1163
|
|
|
1170
1164
|
Whatever the value but `"while-opened"`, intent on the anchor — a pointer
|
|
1171
1165
|
entering it, focus landing in it — builds the content ahead of the click that
|
|
1172
|
-
will open it. A `"while-opened"` popup is warmed by a press on
|
|
1173
|
-
|
|
1174
|
-
|
|
1166
|
+
will open it. A `"while-opened"` popup is warmed only by a press on what opens
|
|
1167
|
+
it — a `--navi-open` button, a picker's trigger when a press opens it, an
|
|
1168
|
+
expandable's UI part — and a press that ends without opening it (a scroll, a
|
|
1169
|
+
drag, a release elsewhere) throws the content away: there is still one content
|
|
1170
|
+
at a time. A popup with an `onOpen` is never warmed, so the content is always
|
|
1171
|
+
built after it (see
|
|
1172
|
+
[`onOpen` runs before the popup has built anything](#onopen-runs-before-the-popup-has-built-anything)).
|
|
1175
1173
|
|
|
1176
1174
|
`"while-opened"` is what an uncontrolled field seeded from a `defaultValue`
|
|
1177
1175
|
needs: without it, a popup reopened after the underlying value changed still
|
package/docs/scroll.md
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
Where scrolling happens in a navi app, and how the pieces that live inside a
|
|
4
4
|
scrolling area (`Box header/body/footer`, `List`, a popup) are told about it.
|
|
5
5
|
|
|
6
|
-
Where a navigation LANDS is another subject — a push at the top, a
|
|
7
|
-
|
|
8
|
-
it was read at: see
|
|
6
|
+
Where a navigation LANDS is another subject — a push at the top, a push with a
|
|
7
|
+
`#id` on the element it names, a back or forward where the page was left, a row
|
|
8
|
+
of tabs giving each tab back the offset it was read at: see
|
|
9
9
|
[navigation.md](./navigation.md#where-a-navigation-lands-the-scroll).
|
|
10
10
|
|
|
11
11
|
- [What makes header/body/footer work: the overflow](#what-makes-headerbodyfooter-work-the-overflow)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/navi",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.400",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Library of components including navigation to create frontend applications",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"preact": "^11.0.0-rc.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@jsenv/dom": "0.17.
|
|
37
|
+
"@jsenv/dom": "0.17.76",
|
|
38
38
|
"@jsenv/humanize": "1.8.5",
|
|
39
39
|
"@jsenv/validity": "0.4.5"
|
|
40
40
|
},
|