@tanishqkancharla/maui 0.0.65 → 0.0.67
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/components/Dialog.js +4 -0
- package/dist/maui.d.ts +1 -0
- package/dist/maui.js +1 -0
- package/package.json +1 -1
- package/skills/maui/SKILL.md +5 -1
- package/skills/maui/references/components/buttons.md +1 -1
- package/skills/maui/references/components/menu.md +22 -0
- package/skills/maui/references/interactions/pressable.md +25 -0
- package/src/apps/JsxEditor/catalog.ts +9 -1
- package/src/apps/JsxEditor/lint.test.ts +14 -0
- package/src/components/Dialog.tsx +4 -0
- package/src/maui.ts +1 -0
- package/src/pages/MenuPage.tsx +34 -1
|
@@ -73,10 +73,14 @@ const dialog = style({
|
|
|
73
73
|
const title = style(text({ size: "lg", fontWeight: 600 }), {
|
|
74
74
|
margin: 0,
|
|
75
75
|
});
|
|
76
|
+
// A scrolling box clips on both axes. The inset, offset by a negative margin,
|
|
77
|
+
// keeps the rings and focus glow of full-width fields visible without moving them.
|
|
76
78
|
const body = style({
|
|
77
79
|
minWidth: 0,
|
|
78
80
|
minHeight: 0,
|
|
79
81
|
overflowY: "auto",
|
|
82
|
+
margin: `calc(-1 * ${spacing.value(3)})`,
|
|
83
|
+
padding: spacing.value(3),
|
|
80
84
|
});
|
|
81
85
|
const actions = style({
|
|
82
86
|
display: "flex",
|
package/dist/maui.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ export { LoadingScreen, type LoadingScreenProps, } from "./components/LoadingScr
|
|
|
43
43
|
export { Icons, type IconProps } from "./components/Icons";
|
|
44
44
|
export * from "./icons/root";
|
|
45
45
|
export { ListBox, ListBoxItem, listBoxStyles, type ListBoxProps, type ListBoxItemProps, } from "./components/ListBox";
|
|
46
|
+
export { Pressable } from "react-aria-components";
|
|
46
47
|
export { MenuTrigger, Menu, MenuItem, menuStyles, type MenuTriggerProps, type MenuProps, type MenuItemProps, } from "./components/Menu";
|
|
47
48
|
export { FuzzyString } from "./components/FuzzyString";
|
|
48
49
|
export { Flex, Gap, Spacer, Divider, type FlexShadow, type FlexRadius, type FlexBorder, type FlexAlignItems, type FlexJustifyContent, type FlexBackground, } from "./components/Utils";
|
package/dist/maui.js
CHANGED
|
@@ -46,6 +46,7 @@ export { LoadingScreen, } from "./components/LoadingScreen";
|
|
|
46
46
|
export { Icons } from "./components/Icons";
|
|
47
47
|
export * from "./icons/root";
|
|
48
48
|
export { ListBox, ListBoxItem, listBoxStyles, } from "./components/ListBox";
|
|
49
|
+
export { Pressable } from "react-aria-components";
|
|
49
50
|
export { MenuTrigger, Menu, MenuItem, menuStyles, } from "./components/Menu";
|
|
50
51
|
export { FuzzyString } from "./components/FuzzyString";
|
|
51
52
|
export { Flex, Gap, Spacer, Divider, } from "./components/Utils";
|
package/package.json
CHANGED
package/skills/maui/SKILL.md
CHANGED
|
@@ -16,6 +16,10 @@ Use Maui components. When one can't do what you need, build from the matching `r
|
|
|
16
16
|
| --------------------------------------------- | --------------------------------- |
|
|
17
17
|
| Tokens, `purse-styles`, motion, layout, theme | [tokens.md](references/tokens.md) |
|
|
18
18
|
|
|
19
|
+
## Interactions
|
|
20
|
+
|
|
21
|
+
- [Pressable](references/interactions/pressable.md) — custom press handling and trigger targets.
|
|
22
|
+
|
|
19
23
|
## Components
|
|
20
24
|
|
|
21
25
|
| Page | Reference |
|
|
@@ -37,7 +41,7 @@ Use Maui components. When one can't do what you need, build from the matching `r
|
|
|
37
41
|
| Select | [select.md](references/components/select.md) |
|
|
38
42
|
| List box | [list-box.md](references/components/list-box.md) |
|
|
39
43
|
| Table | [table.md](references/components/table.md) |
|
|
40
|
-
| Menu
|
|
44
|
+
| Menu / context menu | [menu.md](references/components/menu.md) |
|
|
41
45
|
| Tooltip | [tooltip.md](references/components/tooltip.md) |
|
|
42
46
|
| Layout utilities | [layout-utilities.md](references/components/layout-utilities.md) |
|
|
43
47
|
| FuzzyString | [fuzzy-string.md](references/components/fuzzy-string.md) |
|
|
@@ -93,5 +93,5 @@ Edge-anchored mobile nav is [`Drawer`](drawer.md), not this Dialog and not Overl
|
|
|
93
93
|
- `modal({ size })` — RAC `Modal`; `size` is `"sm"` (default) | `"md"` | `"lg"`.
|
|
94
94
|
- `dialog` — RAC `Dialog`.
|
|
95
95
|
- `title` — RAC `Heading slot="title"`.
|
|
96
|
-
- `body` — scrollable `div` inside the dialog.
|
|
96
|
+
- `body` — scrollable `div` inside the dialog. A 6px inset, offset by a negative margin, keeps full-width field rings and focus glows unclipped.
|
|
97
97
|
- `actions` — button row `div` inside the dialog.
|
|
@@ -27,6 +27,28 @@ Exactly two children on `MenuTrigger`: **trigger**, then **menu**. Use Maui `But
|
|
|
27
27
|
|
|
28
28
|
`placement` defaults to `"bottom start"`. Popover uses `shadow.strong` via `CollectionPopover`.
|
|
29
29
|
|
|
30
|
+
## Context menus
|
|
31
|
+
|
|
32
|
+
Use `trigger="contextMenu"` with the same `Menu` and `MenuItem`. Wrap custom targets in [Pressable](../interactions/pressable.md); its interaction reference covers target requirements and ordinary menu triggers. Maui `Button` already integrates with React Aria and needs no `Pressable` wrapper.
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { MenuTrigger, Menu, MenuItem, Pressable } from "@tanishqkancharla/maui"
|
|
36
|
+
|
|
37
|
+
<MenuTrigger trigger="contextMenu">
|
|
38
|
+
<Pressable>
|
|
39
|
+
<div role="button" tabIndex={0}>Report.pdf</div>
|
|
40
|
+
</Pressable>
|
|
41
|
+
<Menu aria-label="File actions" onAction={(key) => doAction(String(key))}>
|
|
42
|
+
<MenuItem id="rename">Rename</MenuItem>
|
|
43
|
+
<MenuItem id="delete">Delete</MenuItem>
|
|
44
|
+
</Menu>
|
|
45
|
+
</MenuTrigger>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
React Aria handles right-click, touch long-press, and OS/screen-reader context-menu commands (for example Shift+F10 on Windows/Linux or Control+Enter on macOS). Keep a visible Actions button offering the same actions; context menus are an enhancement, not the only entry point. Preserve native context menus on editable content and links when users need browser actions.
|
|
49
|
+
|
|
50
|
+
The current popup still uses `CollectionPopover` defaults: a 6px offset and minimum width equal to the target width. Use a compact target when that sizing is appropriate. See [React Aria's context-menu documentation](https://react-aria.adobe.com/Menu#context-menu) for interaction details.
|
|
51
|
+
|
|
30
52
|
## Styles
|
|
31
53
|
|
|
32
54
|
**Menu** — `menuStyles`
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Pressable
|
|
2
|
+
|
|
3
|
+
Import from `"@tanishqkancharla/maui"`. Maui directly re-exports React Aria's `Pressable` as a shared interaction primitive, not a menu-specific component. Prefer Maui `Button` when you do not need a custom control.
|
|
4
|
+
|
|
5
|
+
## Press handling
|
|
6
|
+
|
|
7
|
+
`Pressable` adds normalized press and focus behavior to one custom element, without styling or an extra DOM wrapper. `onPress` handles mouse, touch, keyboard, and screen-reader activation; React Aria handles cancellation, including scrolling away during a touch interaction.
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Pressable } from "@tanishqkancharla/maui"
|
|
11
|
+
|
|
12
|
+
<Pressable onPress={handleAction}>
|
|
13
|
+
<button type="button">Custom control</button>
|
|
14
|
+
</Pressable>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Custom triggers
|
|
18
|
+
|
|
19
|
+
Wrap a custom target in `Pressable` to connect it to React Aria triggers, including ordinary `MenuTrigger` dropdowns, context menus, and React Aria's `DialogTrigger`. Maui `Button` already handles trigger integration and needs no `Pressable` wrapper. See [Menu](../components/menu.md) for the context-menu recipe.
|
|
20
|
+
|
|
21
|
+
## Child requirements
|
|
22
|
+
|
|
23
|
+
- The single child must be a semantic interactive element or have an appropriate interactive ARIA role.
|
|
24
|
+
- Custom components must forward their ref and spread props onto that element.
|
|
25
|
+
- Apply your own styling with Maui tokens, including `focusRing()` for visible keyboard focus.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Pressable } from "react-aria-components"
|
|
1
2
|
import { Avatar } from "../../components/Avatar"
|
|
2
3
|
import { Badge } from "../../components/Badge"
|
|
3
4
|
import { Banner } from "../../components/Banner"
|
|
@@ -441,8 +442,9 @@ export const catalog: CatalogComponent[] = [
|
|
|
441
442
|
},
|
|
442
443
|
{
|
|
443
444
|
name: "MenuTrigger",
|
|
444
|
-
info: "Exactly two children: a Maui Button trigger, then Menu.
|
|
445
|
+
info: "Exactly two children: a Maui Button or Pressable custom trigger, then Menu. Use trigger=\"contextMenu\" for right-click actions.",
|
|
445
446
|
attributes: [
|
|
447
|
+
{ name: "trigger", values: ["press", "longPress", "contextMenu"] },
|
|
446
448
|
{
|
|
447
449
|
name: "placement",
|
|
448
450
|
values: [
|
|
@@ -458,6 +460,11 @@ export const catalog: CatalogComponent[] = [
|
|
|
458
460
|
},
|
|
459
461
|
],
|
|
460
462
|
},
|
|
463
|
+
{
|
|
464
|
+
name: "Pressable",
|
|
465
|
+
info: "React Aria behavior for one custom interactive child. Adds no DOM wrapper or styling; the child must forward props and ref.",
|
|
466
|
+
attributes: [{ name: "isDisabled", boolean: true }],
|
|
467
|
+
},
|
|
461
468
|
{
|
|
462
469
|
name: "Menu",
|
|
463
470
|
info: "Popover collection of actions. Second child of MenuTrigger.",
|
|
@@ -607,6 +614,7 @@ export const previewScope: Record<string, unknown> = {
|
|
|
607
614
|
Menu,
|
|
608
615
|
MenuItem,
|
|
609
616
|
MenuTrigger,
|
|
617
|
+
Pressable,
|
|
610
618
|
MermaidDiagram,
|
|
611
619
|
Overlay,
|
|
612
620
|
MarkdownEditor,
|
|
@@ -168,6 +168,20 @@ describe("collectJsxDiagnosticsFromSource", () => {
|
|
|
168
168
|
)
|
|
169
169
|
expect(diagnostics).toEqual([])
|
|
170
170
|
})
|
|
171
|
+
|
|
172
|
+
test("accepts context menus with a Pressable custom target", () => {
|
|
173
|
+
const diagnostics = collectJsxDiagnosticsFromSource(
|
|
174
|
+
`<MenuTrigger trigger="contextMenu">
|
|
175
|
+
<Pressable>
|
|
176
|
+
<div role="button" tabIndex={0}>Report.pdf</div>
|
|
177
|
+
</Pressable>
|
|
178
|
+
<Menu aria-label="File actions">
|
|
179
|
+
<MenuItem id="rename">Rename</MenuItem>
|
|
180
|
+
</Menu>
|
|
181
|
+
</MenuTrigger>`,
|
|
182
|
+
)
|
|
183
|
+
expect(diagnostics).toEqual([])
|
|
184
|
+
})
|
|
171
185
|
})
|
|
172
186
|
|
|
173
187
|
describe("JSX editor catalog", () => {
|
|
@@ -115,10 +115,14 @@ const title = style(text({ size: "lg", fontWeight: 600 }), {
|
|
|
115
115
|
margin: 0,
|
|
116
116
|
})
|
|
117
117
|
|
|
118
|
+
// A scrolling box clips on both axes. The inset, offset by a negative margin,
|
|
119
|
+
// keeps the rings and focus glow of full-width fields visible without moving them.
|
|
118
120
|
const body = style({
|
|
119
121
|
minWidth: 0,
|
|
120
122
|
minHeight: 0,
|
|
121
123
|
overflowY: "auto",
|
|
124
|
+
margin: `calc(-1 * ${spacing.value(3)})`,
|
|
125
|
+
padding: spacing.value(3),
|
|
122
126
|
})
|
|
123
127
|
|
|
124
128
|
const actions = style({
|
package/src/maui.ts
CHANGED
package/src/pages/MenuPage.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useState } from "react"
|
|
2
2
|
import { Button } from "../components/Button"
|
|
3
3
|
import { Code } from "../components/Code"
|
|
4
|
+
import { CodeBlock } from "../components/CodeBlock"
|
|
4
5
|
import { Menu, MenuItem, MenuTrigger } from "../components/Menu"
|
|
5
6
|
import { Prose } from "../components/Prose"
|
|
6
7
|
import { H2, H3, P } from "../components/Typography"
|
|
@@ -15,7 +16,8 @@ export function MenuPage() {
|
|
|
15
16
|
<H2>Menu</H2>
|
|
16
17
|
<P>
|
|
17
18
|
A triggered collection of actions that opens in a popover. The
|
|
18
|
-
trigger
|
|
19
|
+
trigger can be a Maui <Code>Button</Code> or a custom target wrapped
|
|
20
|
+
in <Code>Pressable</Code>.
|
|
19
21
|
</P>
|
|
20
22
|
<H3>Default</H3>
|
|
21
23
|
<MenuTrigger>
|
|
@@ -57,6 +59,37 @@ export function MenuPage() {
|
|
|
57
59
|
</MenuTrigger>
|
|
58
60
|
</Flex>
|
|
59
61
|
{lastAction ? <P>Last action: {lastAction}</P> : null}
|
|
62
|
+
<H3>Context menus and custom triggers</H3>
|
|
63
|
+
<P>
|
|
64
|
+
Use <Code>trigger="contextMenu"</Code> with the same <Code>Menu</Code>{" "}
|
|
65
|
+
and <Code>MenuItem</Code>. Maui directly re-exports React Aria’s{" "}
|
|
66
|
+
<Code>Pressable</Code> to connect a custom target to the trigger.
|
|
67
|
+
Maui <Code>Button</Code> already handles this wiring.
|
|
68
|
+
</P>
|
|
69
|
+
<CodeBlock lang="tsx">{`import { MenuTrigger, Menu, MenuItem, Pressable } from "@tanishqkancharla/maui"
|
|
70
|
+
|
|
71
|
+
<MenuTrigger trigger="contextMenu">
|
|
72
|
+
<Pressable>
|
|
73
|
+
<div role="button" tabIndex={0}>Report.pdf</div>
|
|
74
|
+
</Pressable>
|
|
75
|
+
<Menu aria-label="File actions" onAction={handleAction}>
|
|
76
|
+
<MenuItem id="rename">Rename</MenuItem>
|
|
77
|
+
<MenuItem id="delete">Delete</MenuItem>
|
|
78
|
+
</Menu>
|
|
79
|
+
</MenuTrigger>`}</CodeBlock>
|
|
80
|
+
<P>
|
|
81
|
+
<Code>Pressable</Code> adds behavior without styling or an extra DOM
|
|
82
|
+
wrapper. Its single child needs an interactive semantic element or
|
|
83
|
+
ARIA role. Custom components must forward their ref and spread props
|
|
84
|
+
onto that element; give custom targets a visible keyboard focus style.
|
|
85
|
+
</P>
|
|
86
|
+
<P>
|
|
87
|
+
React Aria handles right-click, touch long-press, and OS or screen-reader
|
|
88
|
+
context-menu commands. Keep a visible Actions button offering the same
|
|
89
|
+
actions, and preserve native browser menus on editable content and links
|
|
90
|
+
when needed. The popup currently keeps the dropdown’s 6px offset and
|
|
91
|
+
minimum width equal to the target width.
|
|
92
|
+
</P>
|
|
60
93
|
</Prose>
|
|
61
94
|
)
|
|
62
95
|
}
|