Skip to content

Commit 13f0348

Browse files
committed
feat: menu plugin
1 parent 0ecb6ce commit 13f0348

3 files changed

Lines changed: 205 additions & 0 deletions

File tree

.vitepress/theme/PluginsHome.vue

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ const plugins = [
2525
href: '/plugins/loading-indicator',
2626
featured: false,
2727
},
28+
{
29+
name: '@nstudio/nativescript-menu',
30+
title: 'Menu',
31+
description: 'Native menu components with full customization.',
32+
icon: '',
33+
gradient: 'from-green-500 to-lime-500',
34+
href: '/plugins/menu',
35+
featured: false,
36+
},
2837
{
2938
name: '@nstudio/nativescript-camera-plus',
3039
title: 'Camera Plus',

content/plugins/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ A collection of high-quality NativeScript plugins from nStudio. Native performan
1414
- [Fancy Alert](/plugins/fancyalert) - Beautiful alert dialogs with animations
1515
- [Filterable Listpicker](/plugins/filterable-listpicker) - Modal listpicker with search filtering
1616
- [Input Mask](/plugins/input-mask) - Format user input for phone numbers, credit cards, etc.
17+
- [Menu](/plugins/menu) - Native anchored menus with submenus, palette actions, and selected events
1718
- [ExoPlayer](/plugins/exoplayer) - Video player using ExoPlayer/AVPlayer
1819

1920
## Barcode & Scanning

content/plugins/menu.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Menu
2+
3+
Native anchored menus for NativeScript with one shared TypeScript API across iOS and Android.
4+
5+
The plugin supports:
6+
7+
- Tap-to-open menus on any view
8+
- Long-press context menus
9+
- Nested submenus
10+
- Single-selection (radio-style) groups
11+
- Subtitles, disabled items, hidden items, and destructive actions
12+
- Palette-style icon rows
13+
- Selected event callbacks with the chosen option payload
14+
15+
## Installation
16+
17+
```bash
18+
npm install @nstudio/nativescript-menu
19+
```
20+
21+
## Usage
22+
23+
### NativeScript Core
24+
25+
```xml
26+
<Page xmlns="http://schemas.nativescript.org/tns.xsd"
27+
xmlns:nm="@nstudio/nativescript-menu"
28+
navigatingTo="navigatingTo">
29+
<GridLayout rows="*,auto,*" columns="*,auto,*" class="p-20">
30+
<nm:MenuImage
31+
row="1"
32+
col="1"
33+
src="{{imageIcon}}"
34+
options="{{addOptions}}"
35+
selected="{{selectOption}}"
36+
class="dark:bg-slate-800/60 bg-slate-200/70 rounded-full w-10 h-10"
37+
tintColor="#1e293b"
38+
/>
39+
</GridLayout>
40+
</Page>
41+
```
42+
43+
```typescript
44+
import { EventData, Page } from '@nativescript/core';
45+
import { DemoSharedNativescriptMenu } from '@demo/shared';
46+
47+
export function navigatingTo(args: EventData) {
48+
const page = args.object as Page;
49+
page.bindingContext = new DemoModel();
50+
}
51+
52+
class DemoModel extends DemoSharedNativescriptMenu {}
53+
```
54+
55+
### Angular
56+
57+
```typescript
58+
import { registerElement } from '@nativescript/angular';
59+
import { MenuButton, MenuImage } from '@nstudio/nativescript-menu';
60+
61+
registerElement('MenuButton', () => MenuButton);
62+
registerElement('MenuImage', () => MenuImage);
63+
```
64+
65+
```html
66+
<MenuImage
67+
[src]="imageIcon"
68+
[options]="addOptions"
69+
(selected)="selectOption($event)"
70+
class="dark:bg-slate-800/60 bg-slate-200/70 rounded-full w-10 h-10"
71+
></MenuImage>
72+
```
73+
74+
### Other Flavors
75+
76+
```typescript
77+
import { MenuButton, MenuImage } from '@nstudio/nativescript-menu';
78+
79+
// Vue
80+
Vue.registerElement('MenuButton', () => MenuButton);
81+
Vue.registerElement('MenuImage', () => MenuImage);
82+
83+
// React
84+
registerElement('menubutton', () => MenuButton);
85+
registerElement('menuimage', () => MenuImage);
86+
87+
// Svelte
88+
registerNativeViewElement('menubutton', () => MenuButton);
89+
registerNativeViewElement('menuimage', () => MenuImage);
90+
91+
// Solid
92+
registerElement('menubutton', MenuButton);
93+
registerElement('menuimage', MenuImage);
94+
```
95+
96+
## Menu Model
97+
98+
```typescript
99+
import { MenuAction } from '@nstudio/nativescript-menu';
100+
101+
const addOptions: MenuAction[] = [
102+
{
103+
id: 1,
104+
name: 'New Chat',
105+
icon: 'square.and.pencil',
106+
},
107+
{
108+
id: 2,
109+
name: 'Import from Drive',
110+
subtitle: 'Login Required',
111+
icon: 'cloud',
112+
},
113+
{
114+
id: 3,
115+
name: 'Tiers',
116+
icon: 'circle.dotted',
117+
singleSelection: true,
118+
children: [
119+
{ id: 31, name: 'Starter', subtitle: 'Lean quickstart' },
120+
{ id: 32, name: 'Pro', subtitle: 'Growing businesses' },
121+
{ id: 33, name: 'Enterprise', subtitle: 'Maximum throughput', state: 'on' },
122+
],
123+
},
124+
{
125+
id: 4,
126+
name: 'Protocols',
127+
icon: 'square.2.layers.3d',
128+
children: [
129+
{ id: 41, name: 'Add Protocol', icon: 'plus' },
130+
],
131+
},
132+
{
133+
id: 5,
134+
name: '',
135+
childrenStyle: 'palette',
136+
children: [
137+
{ id: 51, name: 'Camera', icon: 'camera' },
138+
{ id: 52, name: 'Photos', icon: 'photo' },
139+
{ id: 53, name: 'Files', icon: 'folder' },
140+
],
141+
},
142+
];
143+
```
144+
145+
## Events
146+
147+
### selected
148+
149+
Emitted when a menu item is chosen.
150+
151+
```typescript
152+
import { MenuSelectedEvent } from '@nstudio/nativescript-menu';
153+
154+
function selectOption(args: MenuSelectedEvent) {
155+
const option = args.data.option;
156+
console.log('Selected option:', option);
157+
}
158+
```
159+
160+
## Properties
161+
162+
Registered at the View level, so they can be used on MenuButton, MenuImage, or other supported views.
163+
164+
| Property | Type | Description |
165+
| --- | --- | --- |
166+
| options | Array<MenuAction> \| MenuAction | Alias setter that assigns menu |
167+
| menu | Array<MenuAction> \| MenuAction | Tap-to-open menu configuration |
168+
| contextMenu | Array<MenuAction> \| MenuAction | Long-press menu configuration |
169+
170+
## Classes
171+
172+
- MenuButton extends NativeScript Button
173+
- MenuImage extends NativeScript Image
174+
175+
Both classes expose an options setter and emit selected events.
176+
177+
## Platform Notes
178+
179+
### iOS
180+
181+
- Uses UIMenu and UIAction for native platform behavior
182+
- Supports inline, dropdown, and palette rendering
183+
- Supports subtitles on iOS 15+
184+
- Supports context menus through UIContextMenuInteraction
185+
186+
### Android
187+
188+
- Uses a native anchored glass popup controller
189+
- Supports nested submenu choreography, spring-style open, and animated close
190+
- Supports palette rows and single-selection state updates
191+
- Supports icon metadata for symbol, src, and font icon rendering
192+
193+
## License
194+
195+
Apache License Version 2.0

0 commit comments

Comments
 (0)