@expo/ui 1.0.0-canary-20250306-d9d3e02 → 1.0.0-canary-20250331-817737a

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +4 -0
  3. package/android/src/main/java/expo/modules/ui/PickerView.kt +3 -0
  4. package/android/src/main/java/expo/modules/ui/TextInputView.kt +75 -0
  5. package/android/src/main/java/expo/modules/ui/menu/ContextMenu.kt +7 -3
  6. package/build/components/BottomSheet/index.d.ts +9 -0
  7. package/build/components/BottomSheet/index.d.ts.map +1 -0
  8. package/build/components/BottomSheet/index.ios.d.ts +11 -0
  9. package/build/components/BottomSheet/index.ios.d.ts.map +1 -0
  10. package/build/components/Button/index.d.ts +1 -1
  11. package/build/components/ContextMenu/index.android.d.ts +23 -0
  12. package/build/components/ContextMenu/index.android.d.ts.map +1 -0
  13. package/build/components/ContextMenu/index.d.ts +54 -20
  14. package/build/components/ContextMenu/index.d.ts.map +1 -1
  15. package/build/components/DatePicker/index.d.ts +6 -6
  16. package/build/components/Label/index.d.ts +28 -0
  17. package/build/components/Label/index.d.ts.map +1 -0
  18. package/build/components/Label/index.ios.d.ts +10 -0
  19. package/build/components/Label/index.ios.d.ts.map +1 -0
  20. package/build/components/List/index.d.ts +87 -0
  21. package/build/components/List/index.d.ts.map +1 -0
  22. package/build/components/List/index.ios.d.ts +9 -0
  23. package/build/components/List/index.ios.d.ts.map +1 -0
  24. package/build/components/Picker/index.d.ts +8 -5
  25. package/build/components/Picker/index.d.ts.map +1 -1
  26. package/build/components/Progress/index.d.ts +1 -1
  27. package/build/components/Section/index.d.ts +10 -2
  28. package/build/components/Section/index.d.ts.map +1 -1
  29. package/build/components/Slider/index.d.ts +5 -2
  30. package/build/components/Slider/index.d.ts.map +1 -1
  31. package/build/components/Switch/index.d.ts +18 -36
  32. package/build/components/Switch/index.d.ts.map +1 -1
  33. package/build/components/TextInput/index.d.ts +24 -1
  34. package/build/components/TextInput/index.d.ts.map +1 -1
  35. package/build/src/types.d.ts +4 -2
  36. package/build/src/types.d.ts.map +1 -1
  37. package/components/BottomSheet/index.ios.tsx +34 -0
  38. package/components/BottomSheet/index.tsx +12 -0
  39. package/components/Button/index.tsx +1 -1
  40. package/components/ContextMenu/index.android.tsx +72 -0
  41. package/components/ContextMenu/index.tsx +67 -33
  42. package/components/DatePicker/index.tsx +6 -6
  43. package/components/Label/index.ios.tsx +16 -0
  44. package/components/Label/index.tsx +34 -0
  45. package/components/List/index.ios.tsx +35 -0
  46. package/components/List/index.tsx +99 -0
  47. package/components/Picker/index.tsx +8 -5
  48. package/components/Progress/index.tsx +1 -1
  49. package/components/Section/index.tsx +10 -2
  50. package/components/Slider/index.tsx +5 -2
  51. package/components/Switch/index.tsx +37 -54
  52. package/components/TextInput/index.tsx +30 -3
  53. package/ios/BottomSheetView.swift +82 -0
  54. package/ios/ContextMenu/ContextMenu.swift +65 -2
  55. package/ios/ContextMenu/ContextMenuRecords.swift +6 -0
  56. package/ios/ExpoUIModule.swift +5 -0
  57. package/ios/Label.swift +24 -0
  58. package/ios/List.swift +122 -0
  59. package/ios/PickerView.swift +32 -27
  60. package/ios/SectionView.swift +1 -1
  61. package/package.json +3 -4
  62. package/src/types.ts +4 -2
package/ios/List.swift ADDED
@@ -0,0 +1,122 @@
1
+ // Copyright 2025-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+ import SwiftUI
5
+
6
+ class ListProps: ExpoSwiftUI.ViewProps {
7
+ @Field var listStyle: String = "automatic"
8
+ @Field var moveEnabled: Bool = false
9
+ @Field var deleteEnabled: Bool = false
10
+ @Field var selectEnabled: Bool = true
11
+ @Field var scrollEnabled: Bool = false
12
+ @Field var editModeEnabled: Bool = false
13
+ var onDeleteItem = EventDispatcher()
14
+ var onMoveItem = EventDispatcher()
15
+ var onSelectionChange = EventDispatcher()
16
+ }
17
+
18
+ struct ListView: ExpoSwiftUI.View {
19
+ @EnvironmentObject var props: ListProps
20
+ @State private var selection: Set<Int> = []
21
+ @State var editModeEnabled: EditMode = .inactive
22
+ @State var search: String = ""
23
+ var body: some View {
24
+ let list = List(selection: props.selectEnabled ? $selection : nil) {
25
+ UnwrappedChildren { child, isHostingView in
26
+ child
27
+ .if(!isHostingView) {
28
+ $0.offset(
29
+ x: UIDevice.current.userInterfaceIdiom == .pad
30
+ ? IPAD_OFFSET : IPHONE_OFFSET)
31
+ }
32
+ }
33
+ .onDelete(perform: handleDelete)
34
+ .onMove(perform: handleMove)
35
+ .deleteDisabled(!props.deleteEnabled)
36
+ .moveDisabled(!props.moveEnabled)
37
+ }
38
+ .modifier(ListStyleModifer(style: props.listStyle))
39
+ .onAppear {
40
+ editModeEnabled = props.editModeEnabled ? .active : .inactive
41
+ }
42
+ .onChange(of: props.editModeEnabled) { newValue in
43
+ withAnimation {
44
+ editModeEnabled = newValue ? .active : .inactive
45
+ }
46
+ }
47
+ .onChange(of: selection) { selection in
48
+ print(selection)
49
+ handleSelectionChange(selection: selection)
50
+ }
51
+ .modifier(ScrollDisabledModifier(scrollEnabled: props.selectEnabled))
52
+ .environment(\.editMode, $editModeEnabled)
53
+ if #available(iOS 16.0, tvOS 16.0, *) {
54
+ list.scrollDisabled(!props.scrollEnabled)
55
+ } else {
56
+ list
57
+ }
58
+ }
59
+ func handleDelete(at offsets: IndexSet) {
60
+ for offset in offsets {
61
+ props.onDeleteItem([
62
+ "index": offset
63
+ ])
64
+ selection.remove(offset)
65
+ }
66
+ }
67
+ func handleMove(from sources: IndexSet, to destination: Int) {
68
+ for source in sources {
69
+ props.onMoveItem([
70
+ "from": source,
71
+ "to": destination
72
+ ])
73
+ }
74
+ }
75
+ func handleSelectionChange(selection: Set<Int>) {
76
+ let selectionArray = Array(selection)
77
+ let jsonDict: [String: Any] = [
78
+ "selection": selectionArray
79
+ ]
80
+ props.onSelectionChange(jsonDict)
81
+ }
82
+ }
83
+
84
+ struct ListStyleModifer: ViewModifier {
85
+ var style: String
86
+ @ViewBuilder func body(content: Content) -> some View {
87
+ switch style {
88
+ case "grouped":
89
+ content.listStyle(.grouped)
90
+ case "insetGrouped":
91
+ #if !os(tvOS)
92
+ content.listStyle(.insetGrouped)
93
+ #endif
94
+ case "inset":
95
+ #if !os(tvOS)
96
+ content.listStyle(.inset)
97
+ #endif
98
+ case "plain":
99
+ content.listStyle(.plain)
100
+ case "sidebar":
101
+ #if !os(tvOS)
102
+ content.listStyle(.sidebar)
103
+ #endif
104
+ case "automatic":
105
+ content.listStyle(.automatic)
106
+ default:
107
+ content
108
+ }
109
+ }
110
+ }
111
+
112
+ struct ScrollDisabledModifier: ViewModifier {
113
+ let scrollEnabled: Bool
114
+
115
+ func body(content: Content) -> some View {
116
+ if #available(iOS 16.0, tvOS 16.0, *) {
117
+ content.scrollDisabled(!scrollEnabled)
118
+ } else {
119
+ content
120
+ }
121
+ }
122
+ }
@@ -13,40 +13,45 @@ class PickerProps: ExpoSwiftUI.ViewProps {
13
13
  }
14
14
 
15
15
  struct PickerView: ExpoSwiftUI.View {
16
- @State var selection: Int?
16
+ @State var selection: Int = 0
17
17
  @State var prevSelectedIndex: Int?
18
18
  @EnvironmentObject var props: PickerProps
19
+ @EnvironmentObject var shadowNodeProxy: ExpoSwiftUI.ShadowNodeProxy
19
20
 
20
21
  var body: some View {
21
22
  if #available(iOS 17.0, tvOS 17.0, *) {
22
- Picker(props.label ?? "", selection: $selection) {
23
- ForEach(Array(props.options.enumerated()), id: \.0) { index, option in
24
- Text(option).tag(index)
23
+ ExpoSwiftUI.AutoSizingStack(shadowNodeProxy: shadowNodeProxy) {
24
+ Picker(props.label ?? "", selection: $selection) {
25
+ ForEach(Array(props.options.enumerated()), id: \.0) { index, option in
26
+ Text(option).tag(index)
27
+ }
25
28
  }
29
+ .tint(props.color)
30
+ #if !os(tvOS)
31
+ .if(props.variant == "wheel", { $0.pickerStyle(.wheel) })
32
+ .if(props.variant == "palette", { $0.pickerStyle(.palette) })
33
+ #endif
34
+ .if(props.variant == "segmented", { $0.pickerStyle(.segmented) })
35
+ .if(props.variant == "inline", { $0.pickerStyle(.inline) })
36
+ .if(props.variant == "menu", { $0.pickerStyle(.menu) })
37
+ .onChange(of: selection, perform: { newValue in
38
+ if props.selectedIndex == newValue {
39
+ return
40
+ }
41
+ let payload = [
42
+ "index": newValue,
43
+ "label": props.options[newValue]
44
+ ]
45
+ props.onOptionSelected(payload)
46
+ })
47
+ .onReceive(props.selectedIndex.publisher, perform: { newValue in
48
+ if prevSelectedIndex == newValue {
49
+ return
50
+ }
51
+ selection = newValue
52
+ prevSelectedIndex = newValue
53
+ })
26
54
  }
27
- .tint(props.color)
28
- #if !os(tvOS)
29
- .if(props.variant == "wheel", { $0.pickerStyle(.wheel) })
30
- #endif
31
- .if(props.variant == "segmented", { $0.pickerStyle(.segmented) })
32
- .if(props.variant == "menu", { $0.pickerStyle(.menu) })
33
- .onChange(of: selection, perform: { newValue in
34
- if props.selectedIndex == newValue {
35
- return
36
- }
37
- let payload = [
38
- "index": newValue ?? 0,
39
- "label": props.options[newValue ?? 0]
40
- ]
41
- props.onOptionSelected(payload)
42
- })
43
- .onReceive(props.selectedIndex.publisher, perform: { newValue in
44
- if prevSelectedIndex == newValue {
45
- return
46
- }
47
- selection = newValue
48
- prevSelectedIndex = newValue
49
- })
50
55
  }
51
56
  }
52
57
  }
@@ -15,7 +15,7 @@ struct SectionView: ExpoSwiftUI.View {
15
15
 
16
16
  var body: some View {
17
17
  let form = Form {
18
- Section(header: Text(props.title ?? "")) {
18
+ Section(header: Text(props.title ?? "").textCase(nil)) {
19
19
  UnwrappedChildren { child, isHostingView in
20
20
  child
21
21
  .if(!isHostingView) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/ui",
3
- "version": "1.0.0-canary-20250306-d9d3e02",
3
+ "version": "1.0.0-canary-20250331-817737a",
4
4
  "description": "A collection of UI components",
5
5
  "scripts": {
6
6
  "build": "expo-module build",
@@ -27,12 +27,11 @@
27
27
  "dependencies": {},
28
28
  "devDependencies": {
29
29
  "@types/react": "~19.0.10",
30
- "expo-module-scripts": "4.0.5-canary-20250306-d9d3e02"
30
+ "expo-module-scripts": "4.0.5-canary-20250331-817737a"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "expo": "*",
34
34
  "react": "*",
35
35
  "react-native": "*"
36
- },
37
- "gitHead": "d9d3e024d8742099c307754673f17117a20c1dea"
36
+ }
38
37
  }
package/src/types.ts CHANGED
@@ -1,9 +1,11 @@
1
- export type * from '../components/Switch';
2
- export type * from '../components/Picker';
3
1
  export type * from '../components/Button';
4
2
  export type * from '../components/ContextMenu';
3
+ export type * from '../components/Picker';
5
4
  export type * from '../components/Section';
6
5
  export type * from '../components/Slider';
6
+ export type * from '../components/Switch';
7
+ export type * from '../components/Label';
8
+ export type * from '../components/List';
7
9
 
8
10
  /**
9
11
  * @hidden