@net-advantage/jo-ui-menu 0.0.0-stage → 1.3.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 +57 -3
- package/package.json +43 -6
package/README.md
CHANGED
|
@@ -1,3 +1,57 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# @net-advantage/jo-ui-menu
|
|
2
|
+
|
|
3
|
+
Menu button for JourneyOf. `DropdownMenu` and `MenuButton` are the same control: a button that opens a menu of actions.
|
|
4
|
+
|
|
5
|
+
The control follows a strict MVVM split. The model places the menu and resolves keyboard movement. The view-model owns open state, focus, and outside clicks. The view renders the view-model.
|
|
6
|
+
|
|
7
|
+
Colours, radii, and focus come from `--jo-color-*` and `--jo-radius-*` tokens.
|
|
8
|
+
|
|
9
|
+
## MVVM
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart LR
|
|
13
|
+
Props["DropdownMenuProps"] --> ViewModel["useMenuViewModel"]
|
|
14
|
+
Model["jo-ui-menu.model.ts"] --> ViewModel
|
|
15
|
+
ViewModel --> View["DropdownMenu.tsx"]
|
|
16
|
+
View -->|"keys, click, hover"| ViewModel
|
|
17
|
+
ViewModel -->|"onSelect"| Host["Host application"]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
| Layer | File | Responsibility |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| Contract | [jo-ui-menu.types.ts](src/jo-ui-menu.types.ts) | Props, items, and the menu view-model |
|
|
23
|
+
| Model | [jo-ui-menu.model.ts](src/jo-ui-menu.model.ts) | Class names, enabled indexes, typeahead, and viewport placement |
|
|
24
|
+
| View-model | [jo-ui-menu.view-model.ts](src/jo-ui-menu.view-model.ts) | `useMenuViewModel`: open state, keyboard, focus return, outside click |
|
|
25
|
+
| View | [DropdownMenu.tsx](src/DropdownMenu.tsx) | Render the menu button and the menu |
|
|
26
|
+
|
|
27
|
+
## Models
|
|
28
|
+
|
|
29
|
+
```mermaid
|
|
30
|
+
flowchart TD
|
|
31
|
+
Items["MenuItem[]"] --> Enabled["enabled indexes"]
|
|
32
|
+
Items --> Typeahead["typeahead match"]
|
|
33
|
+
Trigger["trigger box"] --> Place["placeMenu"]
|
|
34
|
+
Viewport["viewport"] --> Place
|
|
35
|
+
Enabled --> ViewModel["MenuViewModel"]
|
|
36
|
+
Typeahead --> ViewModel
|
|
37
|
+
Place --> ViewModel
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- The button uses `aria-haspopup="menu"`, `aria-expanded`, and `aria-controls`. The popup is `role="menu"` and each action is `role="menuitem"`.
|
|
41
|
+
- Arrow keys, Home, and End move among enabled items. Typeahead selects by the typed prefix. Enter and Space activate the active item.
|
|
42
|
+
- Escape closes the menu and returns focus to the button. Tab closes the menu and leaves focus movement to the browser.
|
|
43
|
+
- A pointer press outside the control closes the menu. The menu flips above the button and shifts sideways so it stays in the viewport.
|
|
44
|
+
- A disabled item stays visible, exposes `aria-disabled`, and does not activate. `pressed` sets `aria-pressed`. `badge` renders inside the item.
|
|
45
|
+
- `MenuButton` is the same component as `DropdownMenu`.
|
|
46
|
+
|
|
47
|
+
## Structure
|
|
48
|
+
|
|
49
|
+
- src: runtime component, model, view-model, types, and companion tests.
|
|
50
|
+
- stories: Storybook stories for light and dark themes.
|
|
51
|
+
|
|
52
|
+
## Publish footprint
|
|
53
|
+
|
|
54
|
+
This package publishes only:
|
|
55
|
+
|
|
56
|
+
- dist
|
|
57
|
+
- README.md
|
package/package.json
CHANGED
|
@@ -1,6 +1,43 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@net-advantage/jo-ui-menu",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@net-advantage/jo-ui-menu",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./style.css": "./dist/jo-ui-menu.css"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"sideEffects": [
|
|
22
|
+
"**/*.css"
|
|
23
|
+
],
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"react": "^19.0.0",
|
|
26
|
+
"react-dom": "^19.0.0"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "pnpm run build:styles && pnpm run build:js && pnpm run build:types",
|
|
30
|
+
"build:styles": "pnpm exec tailwindcss -c ../../tailwind.controls.config.cjs -i ./src/jo-ui-menu.tailwind.css -o ./src/jo-ui-menu.css --minify",
|
|
31
|
+
"build:types": "tsc -p tsconfig.build.json",
|
|
32
|
+
"build:js": "vite build",
|
|
33
|
+
"test": "vitest run"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/react": "^19.2.18",
|
|
37
|
+
"@types/react-dom": "^19.2.7",
|
|
38
|
+
"typescript": "~6.0.2",
|
|
39
|
+
"vite": "^8.3.0",
|
|
40
|
+
"vitest": "5.0.2",
|
|
41
|
+
"@vitejs/plugin-react": "^6.1.1"
|
|
42
|
+
}
|
|
43
|
+
}
|