vireuikit 0.6.0 → 0.8.0
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 +106 -4
- package/dist/chunk-VY5MD3CX.js +684 -0
- package/dist/chunk-VY5MD3CX.js.map +1 -0
- package/dist/context-DQaAcRq-.d.cts +104 -0
- package/dist/context-DQaAcRq-.d.ts +104 -0
- package/dist/index.cjs +751 -151
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +533 -98
- package/dist/index.d.ts +533 -98
- package/dist/index.js +250 -1
- package/dist/index.js.map +1 -1
- package/dist/web.cjs +1347 -83
- package/dist/web.cjs.map +1 -1
- package/dist/web.d.cts +39 -3
- package/dist/web.d.ts +39 -3
- package/dist/web.js +924 -37
- package/dist/web.js.map +1 -1
- package/package.json +1 -1
- package/dist/a11y-D3SS74I3.d.cts +0 -25
- package/dist/a11y-D3SS74I3.d.ts +0 -25
- package/dist/chunk-I3BD3XGC.js +0 -392
- package/dist/chunk-I3BD3XGC.js.map +0 -1
package/README.md
CHANGED
|
@@ -43,6 +43,63 @@ const frame = growthFrame(sourceShape, targetShape, anchorPoint, growthPhase(sta
|
|
|
43
43
|
// frame.body: the shape to draw as glass this frame.
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
The default timing is fitted to Apple's reference of a menu growing out of its toolbar. The menu itself is a model
|
|
47
|
+
too, so every target shares its keyboard, where it sits and what its surface is on each frame:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { MENU_CLOSED, menuPlacement, menuSurfaceFrame, stepMenu } from 'vireuikit';
|
|
51
|
+
|
|
52
|
+
const step = stepMenu(MENU_CLOSED, { type: 'open', focus: 'first' }, items); // items: { label, disabled, focusable? }[]
|
|
53
|
+
// step.focus says where focus goes; a choice always closes the menu.
|
|
54
|
+
const { rect, anchor } = menuPlacement(triggerRect, menuSize, segment); // the trigger's segment of the window, or the viewport
|
|
55
|
+
const surface = menuSurfaceFrame(triggerBox, { ...rect, radius }, anchor, growthPhase(state));
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Adaptive model
|
|
59
|
+
|
|
60
|
+
What every atom and pattern becomes across window classes, input and posture is one pure model, so every target
|
|
61
|
+
decides the same way. The context is the window in dp, the input in three layers (the primary pointer, any coarse
|
|
62
|
+
input, hover, a keyboard), the posture of a folding screen and reduced motion; the functions turn it into forms.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { adaptiveContext, halfOpen, INPUT_MIXED, navigationForm, paneLayout, presentationForm } from 'vireuikit';
|
|
66
|
+
|
|
67
|
+
const window = { width: 673, height: 841 };
|
|
68
|
+
const ctx = adaptiveContext({ window, input: INPUT_MIXED, posture: halfOpen('book', window) });
|
|
69
|
+
|
|
70
|
+
navigationForm(ctx, { primary: 4, secondary: 2, search: true }).form; // 'rail'
|
|
71
|
+
paneLayout(ctx, { selected: true, showing: 'detail' }).split; // { kind: 'fold', gap }: the panes split at the fold
|
|
72
|
+
presentationForm('sheet', ctx).form; // 'bottom-sheet'; a side sheet from 840 dp
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- `classifyWindow` holds every threshold: widths 600, 840, 1200 and 1600 dp, heights 480 and 900.
|
|
76
|
+
- `navigationForm`: a bar on a compact width and in tabletop, a rail on medium, expanded and a compact height, a
|
|
77
|
+
sidebar from large; the same primary destinations on every form, at most five bar slots with search, no "More".
|
|
78
|
+
`bottomAccessory` places a strip above the bar, in its row or along the content.
|
|
79
|
+
- `presentationForm` for a menu, picker, popover, sheet, modal sheet, alert or dialog: a popover is a sheet grown from
|
|
80
|
+
its source below 600, a supplementary sheet is a bottom sheet below 840 and a side sheet from there, sheets fill
|
|
81
|
+
the window on a compact height, and every surface lives in one segment, never across the fold.
|
|
82
|
+
- `paneLayout` (list-detail: one pane below 840, a 360 or 412 dp list beside the detail, split at the fold in book
|
|
83
|
+
posture), `supportingPane` (beside the content from large, over it on expanded, remembered), `postureSplit`.
|
|
84
|
+
- `toolbarLayout` fits a toolbar into its container: neighbours merge, then the lowest priority goes into "…";
|
|
85
|
+
badged items and the main action stay. `toolbarPlacement` says where the window puts it.
|
|
86
|
+
- `sizeTier` follows the primary pointer and `hitTarget` any coarse input, so a laptop with a touch screen gets the
|
|
87
|
+
pointer tier with a 44 dp hit area.
|
|
88
|
+
- `formMorph`, `stepFormMorph` and `formMorphFrame` flow one body into its new form on the growth's springs; turned
|
|
89
|
+
back mid-way it runs back from where it is, and under reduced motion it lands in one frame.
|
|
90
|
+
|
|
91
|
+
On the web the elements collect their part of the context themselves. A shell that lays itself out from the model
|
|
92
|
+
watches its root:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { setInputOverride, setViewportOverride, watchAdaptiveContext } from 'vireuikit/web';
|
|
96
|
+
|
|
97
|
+
const stop = watchAdaptiveContext(shell, (ctx) => render(ctx)); // told now and on every change
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`setInputOverride` lets a host that knows its input better decide the layers, and `setViewportOverride` makes an
|
|
101
|
+
element the window, with its own segments; the lab's adaptive stage simulates devices with both.
|
|
102
|
+
|
|
46
103
|
## Web elements
|
|
47
104
|
|
|
48
105
|
`vireuikit/web` upgrades native controls with custom elements. The control inside works before the
|
|
@@ -61,13 +118,15 @@ defineVireElements({ nonce: cspNonce });
|
|
|
61
118
|
setA11yOverride({ reduceTransparency: true });
|
|
62
119
|
```
|
|
63
120
|
|
|
64
|
-
- `<vire-button>` is an action: it sinks and grows slightly under press, and nothing opens out of it
|
|
121
|
+
- `<vire-button>` is an action: it sinks and grows slightly under press, and nothing opens out of it unless it is the
|
|
122
|
+
trigger of a `<vire-menu>`.
|
|
65
123
|
- `<vire-icon-button>` lifts into the glass under the finger; the lens response is visible while the
|
|
66
124
|
press is held.
|
|
67
125
|
- Attributes: `glass` (empty or `present`: a lens at rest; `touch`: a lens only under the finger; absent: no
|
|
68
|
-
glass), `size` (`touch`, `small`, `medium`, `large`, `xlarge`; by default `touch`
|
|
69
|
-
`medium` otherwise), `disabled`.
|
|
70
|
-
-
|
|
126
|
+
glass), `size` (`touch`, `small`, `medium`, `large`, `xlarge`; by default `touch` when the primary pointer is
|
|
127
|
+
coarse and `medium` otherwise), `disabled`.
|
|
128
|
+
- Wherever a coarse input is present, a touch screen on a laptop too, every size keeps a hit area of at least 44 dp
|
|
129
|
+
without changing layout. Hover comes from the pointer that entered: a mouse on a tablet hovers, a finger never does.
|
|
71
130
|
- The lens reads the backdrop from declared colours and cannot see an image, a video or a canvas. A host that knows
|
|
72
131
|
what lies under the control sets the element's `sample` (a `BackdropSample` from `vireglass`), at any time; `null`
|
|
73
132
|
hands it back to the probe.
|
|
@@ -93,6 +152,49 @@ setA11yOverride({ reduceTransparency: true });
|
|
|
93
152
|
- Importing the module touches no DOM, so it is safe on a server; `defineVireElements()` is the only call
|
|
94
153
|
that registers anything. An element defined before its markup is parsed waits for its button.
|
|
95
154
|
|
|
155
|
+
### Menu
|
|
156
|
+
|
|
157
|
+
`<vire-menu>` wraps a platform popover menu: a trigger button with `popovertarget` (bare, or inside `<vire-button>` or
|
|
158
|
+
`<vire-icon-button>`) and a `popover` list of item buttons.
|
|
159
|
+
|
|
160
|
+
```html
|
|
161
|
+
<vire-menu glass>
|
|
162
|
+
<vire-icon-button glass>
|
|
163
|
+
<button popovertarget="more" aria-label="More">…</button>
|
|
164
|
+
</vire-icon-button>
|
|
165
|
+
<div id="more" popover>
|
|
166
|
+
<button popovertarget="more" popovertargetaction="hide"><svg>…</svg>Copy link</button>
|
|
167
|
+
<button popovertarget="more" popovertargetaction="hide">Rename</button>
|
|
168
|
+
<button popovertarget="more" popovertargetaction="hide" disabled>Delete</button>
|
|
169
|
+
</div>
|
|
170
|
+
</vire-menu>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
- Before the element is defined the browser runs it: the trigger toggles the list, a choice clicks the item and closes
|
|
174
|
+
it, Escape and a press outside dismiss it, and focus comes back to the trigger. Write the markup without menu roles.
|
|
175
|
+
- After the upgrade the element adds the menu-button roles (`aria-haspopup`, `aria-expanded`, `menu`, `menuitem`)
|
|
176
|
+
together with their keyboard: Enter, Space or ArrowDown open on the first item and ArrowUp on the last; the arrows,
|
|
177
|
+
Home, End and typeahead move over the items; Escape and a choice return focus to the trigger; Tab closes and moves
|
|
178
|
+
on. A pointer opens it with focus on the menu. Removing the element restores the markup.
|
|
179
|
+
- Disabled items are yours to set and clear at any time; the element never rewrites them. A `disabled` item cannot take
|
|
180
|
+
focus, so the keyboard passes over it; an `aria-disabled="true"` item stays focusable, the WAI-ARIA APG way. Neither can
|
|
181
|
+
be chosen.
|
|
182
|
+
- The press that opened the menu chooses nothing: a pointer click on an item counts once the menu has arrived, a key
|
|
183
|
+
once its content shows, and neither the second click of a double click nor a held key ever counts.
|
|
184
|
+
- The list's own `beforetoggle` and `toggle` events fire when it leaves the top layer, after the growth has run back;
|
|
185
|
+
`aria-expanded` turns false as the closing begins.
|
|
186
|
+
- The menu grows out of its trigger and covers it: the trigger's body contracts into a drop, the drop grows into the
|
|
187
|
+
menu with a small overshoot, and the content comes into focus near size. A choice closes it, and closing runs the
|
|
188
|
+
same path back into the trigger. Reduced motion opens and closes it in one frame. A menu that has to stay open for
|
|
189
|
+
several picks is a popover, which is another atom.
|
|
190
|
+
- While the menu is out, the trigger hands its body to the menu's surface (`setCarried` on `<vire-button>` and
|
|
191
|
+
`<vire-icon-button>`), so there is never glass on glass.
|
|
192
|
+
- Attributes: `glass` (empty, `present` or `touch`: the surface is a lens; absent or anything else: an opaque surface), `size` (as for the buttons; rows are as tall
|
|
193
|
+
as the tier), `corner` (`top-left`, `top-right`, `bottom-left`, `bottom-right`: the trigger corner the menu pins to;
|
|
194
|
+
by default the one facing the nearest corner of the trigger's segment of the window). On a folding screen the menu
|
|
195
|
+
stays in its trigger's half, every frame of its growth included, and scrolls if it is taller. `sample` works as on the buttons; without one, the backdrop
|
|
196
|
+
under the menu is read once as it opens and held while it is out.
|
|
197
|
+
|
|
96
198
|
Sizes, behaviour state machines and accessibility modes are exported from `vireuikit` and shared by every
|
|
97
199
|
target. How an atom is accepted:
|
|
98
200
|
[design](https://github.com/pruffit/vireuikit/blob/main/docs/design.md),
|