react-native-tinyui 0.1.1 → 0.2.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 CHANGED
@@ -73,6 +73,7 @@ import { Menu } from 'react-native-tinyui';
73
73
 
74
74
  <Menu
75
75
  accessibilityLabel="Document actions"
76
+ title="Document actions"
76
77
  onPrimaryAction={() => openDocument()}
77
78
  options={[
78
79
  {
@@ -38,6 +38,12 @@ import UIKit
38
38
  }
39
39
  }
40
40
 
41
+ @objc public var title: String = "" {
42
+ didSet {
43
+ props.title = title
44
+ }
45
+ }
46
+
41
47
  @objc public var disabled: Bool = false {
42
48
  didSet {
43
49
  props.disabled = disabled
@@ -84,6 +84,9 @@ using namespace facebook::react;
84
84
  if (oldMenuProps.menuConfig != newMenuProps.menuConfig) {
85
85
  _menuProvider.menuConfig = RCTNSStringFromString(newMenuProps.menuConfig);
86
86
  }
87
+ if (oldMenuProps.title != newMenuProps.title) {
88
+ _menuProvider.title = RCTNSStringFromString(newMenuProps.title);
89
+ }
87
90
  if (oldMenuProps.hasPrimaryAction != newMenuProps.hasPrimaryAction) {
88
91
  _menuProvider.hasPrimaryAction = newMenuProps.hasPrimaryAction;
89
92
  }
@@ -7,6 +7,7 @@ import UIKit
7
7
  */
8
8
  class TinyuiMenuProps: ObservableObject {
9
9
  @Published var menuConfig: String = "{}"
10
+ @Published var title: String = ""
10
11
  @Published var disabled: Bool = false
11
12
  @Published var hasPrimaryAction: Bool = false
12
13
  @Published var triggerView: UIView?
@@ -55,6 +56,19 @@ struct TinyuiMenuSwiftUIView: View {
55
56
 
56
57
  @ViewBuilder
57
58
  private var menuContent: some View {
59
+ if props.title.isEmpty {
60
+ elementsContent
61
+ } else {
62
+ Section {
63
+ elementsContent
64
+ } header: {
65
+ Text(props.title)
66
+ }
67
+ }
68
+ }
69
+
70
+ @ViewBuilder
71
+ private var elementsContent: some View {
58
72
  ForEach(buildElements(from: props.menuConfig)) { element in
59
73
  element.buildView(delegate: delegate)
60
74
  }
@@ -98,11 +112,32 @@ struct TinyuiMenuElement: Identifiable {
98
112
  case "action":
99
113
  let destructive = inheritedDestructive || (dictionary["destructive"] as? Bool ?? false)
100
114
  let keepOpen = dictionary["keepOpen"] as? Bool ?? false
115
+ let id = dictionary["id"] as? String ?? ""
116
+ let state = dictionary["state"] as? String ?? "off"
117
+
118
+ // `on`/`off` use SwiftUI's native `Toggle` support inside `Menu`,
119
+ // which renders the system checkmark. `mixed` has no native SwiftUI
120
+ // equivalent, so it falls back to the minus indicator.
121
+ if state == "on" || state == "off" {
122
+ let isOn = Binding<Bool>(
123
+ get: { state == "on" },
124
+ set: { _ in delegate?.onItemPress(id: id) }
125
+ )
126
+ return AnyView(
127
+ Toggle(isOn: isOn) {
128
+ TinyuiMenuLabel(
129
+ dictionary: dictionary,
130
+ destructive: destructive,
131
+ showsState: false
132
+ )
133
+ }
134
+ .disabled(dictionary["disabled"] as? Bool ?? false)
135
+ )
136
+ }
137
+
101
138
  return AnyView(
102
139
  Button(role: destructive ? .destructive : nil) {
103
- if let id = dictionary["id"] as? String {
104
- delegate?.onItemPress(id: id)
105
- }
140
+ delegate?.onItemPress(id: id)
106
141
  } label: {
107
142
  TinyuiMenuLabel(
108
143
  dictionary: dictionary,
@@ -192,40 +227,54 @@ private struct TinyuiMenuLabel: View {
192
227
  let showsState: Bool
193
228
 
194
229
  var body: some View {
195
- HStack {
230
+ // SwiftUI only extracts a proper title from a menu Button's label when
231
+ // the label is a single `Text` (optionally with an icon). Rendering the
232
+ // title through a computed @ViewBuilder property or wrapping it in
233
+ // nested containers breaks that extraction, so the title must be a
234
+ // direct `Text` in the label hierarchy.
235
+ HStack(spacing: 6) {
196
236
  menuIcon
197
-
198
- VStack(alignment: .leading, spacing: 1) {
199
- title
200
-
201
- if let subtitle = dictionary["subtitle"] as? String,
202
- !subtitle.isEmpty {
203
- Text(subtitle)
204
- .font(.caption)
205
- .foregroundStyle(.secondary)
206
- }
207
- }
208
-
237
+ title
209
238
  if showsState {
210
- switch dictionary["state"] as? String {
211
- case "on":
212
- Image(systemName: "checkmark")
213
- case "mixed":
214
- Image(systemName: "minus")
215
- default:
216
- EmptyView()
217
- }
239
+ stateIndicator
218
240
  }
219
241
  }
220
242
  }
221
243
 
244
+ private var stateIndicator: some View {
245
+ // Only `mixed` reaches here; `on`/`off` are handled natively by `Toggle`.
246
+ // UIKit's menu system renders "mixed" state with a minus/dash mark.
247
+ if dictionary["state"] as? String == "mixed" {
248
+ return AnyView(
249
+ Image(systemName: "minus")
250
+ .font(.system(size: 13, weight: .semibold))
251
+ )
252
+ }
253
+ return AnyView(EmptyView())
254
+ }
255
+
222
256
  @ViewBuilder
223
257
  private var title: some View {
258
+ if let subtitle = dictionary["subtitle"] as? String,
259
+ !subtitle.isEmpty {
260
+ VStack(alignment: .leading, spacing: 1) {
261
+ titleText
262
+ Text(subtitle)
263
+ .font(.caption)
264
+ .foregroundStyle(.secondary)
265
+ }
266
+ } else {
267
+ titleText
268
+ }
269
+ }
270
+
271
+ @ViewBuilder
272
+ private var titleText: some View {
224
273
  let text = Text(dictionary["title"] as? String ?? "")
225
- if let color = TinyuiMenuColor.uiColor(from: dictionary["titleColor"]) {
226
- text.foregroundStyle(Color(uiColor: color))
227
- } else if destructive {
274
+ if destructive {
228
275
  text.foregroundStyle(Color.red)
276
+ } else if let color = TinyuiMenuColor.uiColor(from: dictionary["titleColor"]) {
277
+ text.foregroundStyle(Color(uiColor: color))
229
278
  } else {
230
279
  text
231
280
  }
@@ -12,6 +12,7 @@ const MenuRoot = /*#__PURE__*/forwardRef(function Menu({
12
12
  disabled,
13
13
  onPrimaryAction,
14
14
  options,
15
+ title,
15
16
  testID,
16
17
  ...viewProps
17
18
  }, ref) {
@@ -32,6 +33,7 @@ const MenuRoot = /*#__PURE__*/forwardRef(function Menu({
32
33
  onItemPress: event => callbacks.get(event.nativeEvent.id)?.(),
33
34
  onPrimaryAction: onPrimaryAction,
34
35
  testID: testID,
36
+ title: title,
35
37
  children: /*#__PURE__*/_jsx(View, {
36
38
  collapsable: false,
37
39
  children: children
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","View","assertComponentEnabled","NativeMenuView","serializeMenuOptions","jsx","_jsx","MenuRoot","Menu","accessibilityLabel","children","disabled","onPrimaryAction","options","testID","viewProps","ref","config","callbacks","collapsable","hasPrimaryAction","menuConfig","onItemPress","event","get","nativeEvent","id"],"sourceRoot":"../../src","sources":["Menu.tsx"],"mappings":";;AAAA,SAASA,UAAU,QAA2B,OAAO;AACrD,SAASC,IAAI,QAAQ,cAAc;AAEnC,SAASC,sBAAsB,QAAQ,sBAAmB;AAE1D,OAAOC,cAAc,MAAM,uBAAuB;AAClD,SAASC,oBAAoB,QAAQ,kBAAe;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAErD,MAAMC,QAAQ,gBAAGP,UAAU,CAAuC,SAASQ,IAAIA,CAC7E;EACEC,kBAAkB;EAClBC,QAAQ;EACRC,QAAQ;EACRC,eAAe;EACfC,OAAO;EACPC,MAAM;EACN,GAAGC;AACL,CAAC,EACDC,GAAG,EACH;EACAd,sBAAsB,CAAC,MAAM,CAAC;EAE9B,MAAM;IAAEe,MAAM;IAAEC;EAAU,CAAC,GAAGd,oBAAoB,CAACS,OAAO,CAAC;EAE3D,oBACEP,IAAA,CAACL,IAAI;IAAA,GAAKc,SAAS;IAAEC,GAAG,EAAEA,GAAI;IAACG,WAAW,EAAE,KAAM;IAAAT,QAAA,eAChDJ,IAAA,CAACH,cAAc;MACbM,kBAAkB,EAAEA,kBAAmB;MACvCE,QAAQ,EAAEA,QAAS;MACnBS,gBAAgB,EAAER,eAAe,IAAI,IAAK;MAC1CS,UAAU,EAAEJ,MAAO;MACnBK,WAAW,EAAGC,KAAK,IAAKL,SAAS,CAACM,GAAG,CAACD,KAAK,CAACE,WAAW,CAACC,EAAE,CAAC,GAAG,CAAE;MAChEd,eAAe,EAAEA,eAAgB;MACjCE,MAAM,EAAEA,MAAO;MAAAJ,QAAA,eAEfJ,IAAA,CAACL,IAAI;QAACkB,WAAW,EAAE,KAAM;QAAAT,QAAA,EAAEA;MAAQ,CAAO;IAAC,CAC7B;EAAC,CACb,CAAC;AAEX,CAAC,CAAC;AAEF,OAAO,MAAMF,IAAI,GAAGD,QAAyB","ignoreList":[]}
1
+ {"version":3,"names":["forwardRef","View","assertComponentEnabled","NativeMenuView","serializeMenuOptions","jsx","_jsx","MenuRoot","Menu","accessibilityLabel","children","disabled","onPrimaryAction","options","title","testID","viewProps","ref","config","callbacks","collapsable","hasPrimaryAction","menuConfig","onItemPress","event","get","nativeEvent","id"],"sourceRoot":"../../src","sources":["Menu.tsx"],"mappings":";;AAAA,SAASA,UAAU,QAA2B,OAAO;AACrD,SAASC,IAAI,QAAQ,cAAc;AAEnC,SAASC,sBAAsB,QAAQ,sBAAmB;AAE1D,OAAOC,cAAc,MAAM,uBAAuB;AAClD,SAASC,oBAAoB,QAAQ,kBAAe;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAErD,MAAMC,QAAQ,gBAAGP,UAAU,CAAuC,SAASQ,IAAIA,CAC7E;EACEC,kBAAkB;EAClBC,QAAQ;EACRC,QAAQ;EACRC,eAAe;EACfC,OAAO;EACPC,KAAK;EACLC,MAAM;EACN,GAAGC;AACL,CAAC,EACDC,GAAG,EACH;EACAf,sBAAsB,CAAC,MAAM,CAAC;EAE9B,MAAM;IAAEgB,MAAM;IAAEC;EAAU,CAAC,GAAGf,oBAAoB,CAACS,OAAO,CAAC;EAE3D,oBACEP,IAAA,CAACL,IAAI;IAAA,GAAKe,SAAS;IAAEC,GAAG,EAAEA,GAAI;IAACG,WAAW,EAAE,KAAM;IAAAV,QAAA,eAChDJ,IAAA,CAACH,cAAc;MACbM,kBAAkB,EAAEA,kBAAmB;MACvCE,QAAQ,EAAEA,QAAS;MACnBU,gBAAgB,EAAET,eAAe,IAAI,IAAK;MAC1CU,UAAU,EAAEJ,MAAO;MACnBK,WAAW,EAAGC,KAAK,IAAKL,SAAS,CAACM,GAAG,CAACD,KAAK,CAACE,WAAW,CAACC,EAAE,CAAC,GAAG,CAAE;MAChEf,eAAe,EAAEA,eAAgB;MACjCG,MAAM,EAAEA,MAAO;MACfD,KAAK,EAAEA,KAAM;MAAAJ,QAAA,eAEbJ,IAAA,CAACL,IAAI;QAACmB,WAAW,EAAE,KAAM;QAAAV,QAAA,EAAEA;MAAQ,CAAO;IAAC,CAC7B;EAAC,CACb,CAAC;AAEX,CAAC,CAAC;AAEF,OAAO,MAAMF,IAAI,GAAGD,QAAyB","ignoreList":[]}
@@ -3,6 +3,7 @@ import type { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTyp
3
3
 
4
4
  export interface NativeMenuProps extends ViewProps {
5
5
  menuConfig: string;
6
+ title?: string;
6
7
  disabled?: boolean;
7
8
  hasPrimaryAction?: boolean;
8
9
  onItemPress?: DirectEventHandler<Readonly<{ id: string }>>;
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/Menu.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,iBAAc,CAAC;AAqC7D,eAAO,MAAM,IAAI,EAAe,aAAa,CAAC;AAE9C,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,iBAAc,CAAC"}
1
+ {"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/Menu.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,iBAAc,CAAC;AAuC7D,eAAO,MAAM,IAAI,EAAe,aAAa,CAAC;AAE9C,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,iBAAc,CAAC"}
@@ -50,6 +50,8 @@ export type MenuOption = MenuActionOption | MenuSubmenuOption | MenuSectionOptio
50
50
  export interface MenuProps extends Omit<ViewProps, 'children'> {
51
51
  /** The trigger element. */
52
52
  children: ReactNode;
53
+ /** Optional title displayed at the top of the native menu. */
54
+ title?: string;
53
55
  /** Native menu actions, submenus, sections, and dividers. */
54
56
  options: readonly MenuOption[];
55
57
  /** Prevents the trigger from opening the menu. */
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.types.d.ts","sourceRoot":"","sources":["../../../src/Menu.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,SAAS,EACT,aAAa,EACd,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC;AAEnD,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+FAA+F;IAC/F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,mEAAmE;IACnE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,gEAAgE;IAChE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,IAAI,EAAE,SAAS,CAAC;IAChB,yDAAyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qEAAqE;IACrE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,MAAM,UAAU,GACpB,gBAAgB,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AAE/E,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAC5D,2BAA2B;IAC3B,QAAQ,EAAE,SAAS,CAAC;IACpB,6DAA6D;IAC7D,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,aAAc,SAAQ,yBAAyB,CAC9D,SAAS,GAAG,aAAa,CAAC,YAAY,CAAC,OAAO,IAAI,CAAC,CAAC,CACrD;CAAG"}
1
+ {"version":3,"file":"Menu.types.d.ts","sourceRoot":"","sources":["../../../src/Menu.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,SAAS,EACT,aAAa,EACd,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC;AAEnD,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+FAA+F;IAC/F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,mEAAmE;IACnE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,gEAAgE;IAChE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,IAAI,EAAE,SAAS,CAAC;IAChB,yDAAyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qEAAqE;IACrE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,MAAM,UAAU,GACpB,gBAAgB,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AAE/E,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAC5D,2BAA2B;IAC3B,QAAQ,EAAE,SAAS,CAAC;IACpB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,aAAc,SAAQ,yBAAyB,CAC9D,SAAS,GAAG,aAAa,CAAC,YAAY,CAAC,OAAO,IAAI,CAAC,CAAC,CACrD;CAAG"}
@@ -2,6 +2,7 @@ import { type ViewProps } from 'react-native';
2
2
  import type { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes';
3
3
  export interface NativeMenuProps extends ViewProps {
4
4
  menuConfig: string;
5
+ title?: string;
5
6
  disabled?: boolean;
6
7
  hasPrimaryAction?: boolean;
7
8
  onItemPress?: DirectEventHandler<Readonly<{
@@ -1 +1 @@
1
- {"version":3,"file":"MenuNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/MenuNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,kBAAkB,CAAC,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC3D,eAAe,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;CAC5C;;AAED,wBAEG"}
1
+ {"version":3,"file":"MenuNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/MenuNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,kBAAkB,CAAC,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC3D,eAAe,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;CAC5C;;AAED,wBAEG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-tinyui",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Dependency-free native iOS Menu and Popover components for React Native",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
package/src/Menu.tsx CHANGED
@@ -13,6 +13,7 @@ const MenuRoot = forwardRef<ComponentRef<typeof View>, MenuProps>(function Menu(
13
13
  disabled,
14
14
  onPrimaryAction,
15
15
  options,
16
+ title,
16
17
  testID,
17
18
  ...viewProps
18
19
  },
@@ -32,6 +33,7 @@ const MenuRoot = forwardRef<ComponentRef<typeof View>, MenuProps>(function Menu(
32
33
  onItemPress={(event) => callbacks.get(event.nativeEvent.id)?.()}
33
34
  onPrimaryAction={onPrimaryAction}
34
35
  testID={testID}
36
+ title={title}
35
37
  >
36
38
  <View collapsable={false}>{children}</View>
37
39
  </NativeMenuView>
package/src/Menu.types.ts CHANGED
@@ -64,6 +64,8 @@ export type MenuOption =
64
64
  export interface MenuProps extends Omit<ViewProps, 'children'> {
65
65
  /** The trigger element. */
66
66
  children: ReactNode;
67
+ /** Optional title displayed at the top of the native menu. */
68
+ title?: string;
67
69
  /** Native menu actions, submenus, sections, and dividers. */
68
70
  options: readonly MenuOption[];
69
71
  /** Prevents the trigger from opening the menu. */
@@ -3,6 +3,7 @@ import type { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTyp
3
3
 
4
4
  export interface NativeMenuProps extends ViewProps {
5
5
  menuConfig: string;
6
+ title?: string;
6
7
  disabled?: boolean;
7
8
  hasPrimaryAction?: boolean;
8
9
  onItemPress?: DirectEventHandler<Readonly<{ id: string }>>;