@expo/ui 55.0.2 → 55.0.4
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/CHANGELOG.md +42 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/ui/AnimatedVisibilityView.kt +130 -0
- package/android/src/main/java/expo/modules/ui/BottomSheetView.kt +91 -13
- package/android/src/main/java/expo/modules/ui/CardView.kt +138 -34
- package/android/src/main/java/expo/modules/ui/CheckboxView.kt +98 -0
- package/android/src/main/java/expo/modules/ui/ChipView.kt +267 -142
- package/android/src/main/java/expo/modules/ui/DatePickerView.kt +258 -70
- package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +209 -61
- package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +44 -1
- package/android/src/main/java/expo/modules/ui/ProgressView.kt +189 -89
- package/android/src/main/java/expo/modules/ui/RadioButtonView.kt +3 -7
- package/android/src/main/java/expo/modules/ui/SegmentedButtonView.kt +115 -0
- package/android/src/main/java/expo/modules/ui/SegmentedControlView.kt +35 -0
- package/android/src/main/java/expo/modules/ui/SliderView.kt +70 -12
- package/android/src/main/java/expo/modules/ui/SwitchView.kt +53 -161
- package/android/src/main/java/expo/modules/ui/TextInputView.kt +39 -15
- package/android/src/main/java/expo/modules/ui/ToggleButtonView.kt +95 -57
- package/android/src/main/java/expo/modules/ui/button/Button.kt +117 -158
- package/android/src/main/java/expo/modules/ui/button/FloatingActionButton.kt +92 -0
- package/android/src/main/java/expo/modules/ui/button/IconButton.kt +73 -86
- package/android/src/main/java/expo/modules/ui/menu/DropdownMenu.kt +39 -0
- package/android/src/main/java/expo/modules/ui/menu/DropdownMenuItem.kt +70 -0
- package/android/src/main/java/expo/modules/ui/menu/DropdownMenuRecords.kt +18 -0
- package/build/datetime-picker/DateTimePicker.android.d.ts +3 -0
- package/build/datetime-picker/DateTimePicker.android.d.ts.map +1 -0
- package/build/datetime-picker/DateTimePicker.d.ts +3 -0
- package/build/datetime-picker/DateTimePicker.d.ts.map +1 -0
- package/build/datetime-picker/DateTimePicker.web.d.ts +3 -0
- package/build/datetime-picker/DateTimePicker.web.d.ts.map +1 -0
- package/build/datetime-picker/index.d.ts +5 -0
- package/build/datetime-picker/index.d.ts.map +1 -0
- package/build/datetime-picker/types.d.ts +128 -0
- package/build/datetime-picker/types.d.ts.map +1 -0
- package/build/jetpack-compose/AnimatedVisibility/index.d.ts +134 -0
- package/build/jetpack-compose/AnimatedVisibility/index.d.ts.map +1 -0
- package/build/jetpack-compose/AnimatedVisibility/symbols.d.ts +3 -0
- package/build/jetpack-compose/AnimatedVisibility/symbols.d.ts.map +1 -0
- package/build/jetpack-compose/Button/index.d.ts +65 -51
- package/build/jetpack-compose/Button/index.d.ts.map +1 -1
- package/build/jetpack-compose/Card/index.d.ts +72 -14
- package/build/jetpack-compose/Card/index.d.ts.map +1 -1
- package/build/jetpack-compose/Checkbox/index.d.ts +73 -0
- package/build/jetpack-compose/Checkbox/index.d.ts.map +1 -0
- package/build/jetpack-compose/Chip/index.d.ts +247 -27
- package/build/jetpack-compose/Chip/index.d.ts.map +1 -1
- package/build/jetpack-compose/DatePicker/index.d.ts +38 -3
- package/build/jetpack-compose/DatePicker/index.d.ts.map +1 -1
- package/build/jetpack-compose/DropdownMenu/DropdownMenuItem.d.ts +70 -0
- package/build/jetpack-compose/DropdownMenu/DropdownMenuItem.d.ts.map +1 -0
- package/build/jetpack-compose/DropdownMenu/index.d.ts +68 -0
- package/build/jetpack-compose/DropdownMenu/index.d.ts.map +1 -0
- package/build/jetpack-compose/FloatingActionButton/index.d.ts +150 -0
- package/build/jetpack-compose/FloatingActionButton/index.d.ts.map +1 -0
- package/build/jetpack-compose/HorizontalFloatingToolbar/index.d.ts +2 -2
- package/build/jetpack-compose/HorizontalFloatingToolbar/index.d.ts.map +1 -1
- package/build/jetpack-compose/IconButton/index.d.ts +45 -29
- package/build/jetpack-compose/IconButton/index.d.ts.map +1 -1
- package/build/jetpack-compose/ModalBottomSheet/index.d.ts +65 -13
- package/build/jetpack-compose/ModalBottomSheet/index.d.ts.map +1 -1
- package/build/jetpack-compose/MultiChoiceSegmentedButtonRow/index.d.ts +17 -0
- package/build/jetpack-compose/MultiChoiceSegmentedButtonRow/index.d.ts.map +1 -0
- package/build/jetpack-compose/Progress/index.d.ts +78 -35
- package/build/jetpack-compose/Progress/index.d.ts.map +1 -1
- package/build/jetpack-compose/RadioButton/index.d.ts +2 -2
- package/build/jetpack-compose/RadioButton/index.d.ts.map +1 -1
- package/build/jetpack-compose/SegmentedButton/index.d.ts +74 -0
- package/build/jetpack-compose/SegmentedButton/index.d.ts.map +1 -0
- package/build/jetpack-compose/SingleChoiceSegmentedButtonRow/index.d.ts +17 -0
- package/build/jetpack-compose/SingleChoiceSegmentedButtonRow/index.d.ts.map +1 -0
- package/build/jetpack-compose/Slider/index.d.ts +34 -10
- package/build/jetpack-compose/Slider/index.d.ts.map +1 -1
- package/build/jetpack-compose/Switch/index.d.ts +10 -50
- package/build/jetpack-compose/Switch/index.d.ts.map +1 -1
- package/build/jetpack-compose/TextInput/index.d.ts +9 -0
- package/build/jetpack-compose/TextInput/index.d.ts.map +1 -1
- package/build/jetpack-compose/ToggleButton/index.d.ts +60 -32
- package/build/jetpack-compose/ToggleButton/index.d.ts.map +1 -1
- package/build/jetpack-compose/index.d.ts +5 -4
- package/build/jetpack-compose/index.d.ts.map +1 -1
- package/build/jetpack-compose/modifiers/index.d.ts +18 -1
- package/build/jetpack-compose/modifiers/index.d.ts.map +1 -1
- package/build/swift-ui/Link/index.d.ts +36 -0
- package/build/swift-ui/Link/index.d.ts.map +1 -0
- package/build/swift-ui/ProgressView/index.d.ts +1 -5
- package/build/swift-ui/ProgressView/index.d.ts.map +1 -1
- package/build/swift-ui/Stepper/index.d.ts +3 -3
- package/build/swift-ui/Stepper/index.d.ts.map +1 -1
- package/build/swift-ui/Text/index.d.ts +33 -1
- package/build/swift-ui/Text/index.d.ts.map +1 -1
- package/build/swift-ui/index.d.ts +1 -0
- package/build/swift-ui/index.d.ts.map +1 -1
- package/build/swift-ui/modifiers/environment.d.ts +16 -1
- package/build/swift-ui/modifiers/environment.d.ts.map +1 -1
- package/build/swift-ui/modifiers/index.d.ts +24 -7
- package/build/swift-ui/modifiers/index.d.ts.map +1 -1
- package/build/swift-ui/modifiers/shapes/index.d.ts +2 -2
- package/build/swift-ui/modifiers/widgets.d.ts +14 -0
- package/build/swift-ui/modifiers/widgets.d.ts.map +1 -0
- package/build/swift-ui/types.d.ts +7 -0
- package/build/swift-ui/types.d.ts.map +1 -1
- package/expo-module.config.json +1 -1
- package/ios/BottomSheetView.swift +1 -6
- package/ios/ClosedRangeDateRecord.swift +10 -0
- package/ios/ColorPickerView.swift +9 -8
- package/ios/ConfirmationDialog/ConfirmationDialog.swift +4 -6
- package/ios/DatePickerView.swift +7 -5
- package/ios/DisclosureGroupView.swift +5 -7
- package/ios/ExpoUIModule.swift +1 -0
- package/ios/LinkView.swift +29 -0
- package/ios/ListView.swift +6 -14
- package/ios/Modifiers/DefaultScrollAnchorForRoleModifier.swift +32 -0
- package/ios/Modifiers/DefaultScrollAnchorModifier.swift +16 -0
- package/ios/Modifiers/EnvironmentModifier.swift +14 -0
- package/ios/Modifiers/ViewModifierRegistry.swift +12 -0
- package/ios/Modifiers/WidgetModifiers.swift +12 -0
- package/ios/Picker/PickerView.swift +6 -10
- package/ios/Popover/PopoverView.swift +3 -5
- package/ios/ProgressView.swift +0 -5
- package/ios/SectionView.swift +3 -5
- package/ios/SliderView.swift +8 -6
- package/ios/StepperView.swift +12 -16
- package/ios/TextView.swift +37 -1
- package/ios/Toggle/ToggleView.swift +5 -7
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4-sources.jar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4-sources.jar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4-sources.jar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4-sources.jar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4-sources.jar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.aar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.2/expo.modules.ui-55.0.2.module → 55.0.4/expo.modules.ui-55.0.4.module} +22 -22
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.module.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.2/expo.modules.ui-55.0.2.pom → 55.0.4/expo.modules.ui-55.0.4.pom} +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.4/expo.modules.ui-55.0.4.pom.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
- package/package.json +9 -2
- package/src/datetime-picker/DateTimePicker.android.tsx +126 -0
- package/src/datetime-picker/DateTimePicker.tsx +94 -0
- package/src/datetime-picker/DateTimePicker.web.tsx +5 -0
- package/src/datetime-picker/index.tsx +11 -0
- package/src/datetime-picker/types.tsx +147 -0
- package/src/jetpack-compose/AnimatedVisibility/index.tsx +206 -0
- package/src/jetpack-compose/AnimatedVisibility/symbols.ts +8 -0
- package/src/jetpack-compose/Button/index.tsx +69 -92
- package/src/jetpack-compose/Card/index.tsx +105 -29
- package/src/jetpack-compose/Checkbox/index.tsx +126 -0
- package/src/jetpack-compose/Chip/index.tsx +391 -51
- package/src/jetpack-compose/DatePicker/index.tsx +112 -7
- package/src/jetpack-compose/DropdownMenu/DropdownMenuItem.tsx +126 -0
- package/src/jetpack-compose/DropdownMenu/index.tsx +107 -0
- package/src/jetpack-compose/FloatingActionButton/index.tsx +207 -0
- package/src/jetpack-compose/HorizontalFloatingToolbar/index.tsx +4 -2
- package/src/jetpack-compose/IconButton/index.tsx +49 -56
- package/src/jetpack-compose/ModalBottomSheet/index.tsx +85 -15
- package/src/jetpack-compose/MultiChoiceSegmentedButtonRow/index.tsx +34 -0
- package/src/jetpack-compose/Progress/index.tsx +120 -62
- package/src/jetpack-compose/RadioButton/index.tsx +8 -9
- package/src/jetpack-compose/SegmentedButton/index.tsx +109 -0
- package/src/jetpack-compose/SingleChoiceSegmentedButtonRow/index.tsx +34 -0
- package/src/jetpack-compose/Slider/index.tsx +76 -29
- package/src/jetpack-compose/Switch/index.tsx +17 -87
- package/src/jetpack-compose/TextInput/index.tsx +10 -0
- package/src/jetpack-compose/ToggleButton/index.tsx +67 -43
- package/src/jetpack-compose/index.ts +5 -4
- package/src/jetpack-compose/modifiers/index.ts +26 -2
- package/src/swift-ui/Link/index.tsx +52 -0
- package/src/swift-ui/ProgressView/index.tsx +1 -3
- package/src/swift-ui/Stepper/index.tsx +7 -7
- package/src/swift-ui/Text/index.tsx +66 -2
- package/src/swift-ui/index.tsx +1 -0
- package/src/swift-ui/modifiers/environment.ts +17 -4
- package/src/swift-ui/modifiers/index.ts +44 -10
- package/src/swift-ui/modifiers/widgets.ts +18 -0
- package/src/swift-ui/types.ts +5 -0
- package/android/src/main/java/expo/modules/ui/FilterChipView.kt +0 -59
- package/android/src/main/java/expo/modules/ui/PickerView.kt +0 -161
- package/android/src/main/java/expo/modules/ui/TextButtonView.kt +0 -33
- package/android/src/main/java/expo/modules/ui/menu/ContextMenu.kt +0 -183
- package/android/src/main/java/expo/modules/ui/menu/ContextMenuRecords.kt +0 -64
- package/build/jetpack-compose/Button/types.d.ts +0 -5
- package/build/jetpack-compose/Button/types.d.ts.map +0 -1
- package/build/jetpack-compose/ContextMenu/Submenu.d.ts +0 -17
- package/build/jetpack-compose/ContextMenu/Submenu.d.ts.map +0 -1
- package/build/jetpack-compose/ContextMenu/index.d.ts +0 -65
- package/build/jetpack-compose/ContextMenu/index.d.ts.map +0 -1
- package/build/jetpack-compose/ContextMenu/utils.d.ts +0 -24
- package/build/jetpack-compose/ContextMenu/utils.d.ts.map +0 -1
- package/build/jetpack-compose/FilterChip/index.d.ts +0 -49
- package/build/jetpack-compose/FilterChip/index.d.ts.map +0 -1
- package/build/jetpack-compose/Picker/index.d.ts +0 -62
- package/build/jetpack-compose/Picker/index.d.ts.map +0 -1
- package/build/jetpack-compose/TextButton/index.d.ts +0 -29
- package/build/jetpack-compose/TextButton/index.d.ts.map +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2-sources.jar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2-sources.jar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2-sources.jar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2-sources.jar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2-sources.jar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.module.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.2/expo.modules.ui-55.0.2.pom.sha512 +0 -1
- package/src/jetpack-compose/Button/types.ts +0 -57
- package/src/jetpack-compose/ContextMenu/Submenu.tsx +0 -21
- package/src/jetpack-compose/ContextMenu/index.tsx +0 -149
- package/src/jetpack-compose/ContextMenu/utils.ts +0 -144
- package/src/jetpack-compose/FilterChip/index.tsx +0 -89
- package/src/jetpack-compose/Picker/index.tsx +0 -90
- package/src/jetpack-compose/TextButton/index.tsx +0 -55
|
@@ -2,7 +2,12 @@ import { requireNativeView } from 'expo';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
4
|
import { createViewModifierEventListener } from '../modifiers/utils';
|
|
5
|
-
import { type CommonViewModifierProps } from '../types';
|
|
5
|
+
import { type ClosedRangeDate, type CommonViewModifierProps } from '../types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The style used to format a date in a SwiftUI `Text` view.
|
|
9
|
+
*/
|
|
10
|
+
export type TextDateStyle = 'timer' | 'relative' | 'offset' | 'date' | 'time';
|
|
6
11
|
|
|
7
12
|
export interface TextProps extends CommonViewModifierProps {
|
|
8
13
|
/**
|
|
@@ -14,12 +19,50 @@ export interface TextProps extends CommonViewModifierProps {
|
|
|
14
19
|
* Enables Markdown formatting for the text content using SwiftUI LocalizedStringKey.
|
|
15
20
|
*/
|
|
16
21
|
markdownEnabled?: boolean;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A date to display using the specified `dateStyle`. The text auto-updates as time passes.
|
|
25
|
+
*/
|
|
26
|
+
date?: Date;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The style used to format the `date` prop.
|
|
30
|
+
* @default 'date'
|
|
31
|
+
*/
|
|
32
|
+
dateStyle?: TextDateStyle;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A time interval to display as a live-updating timer.
|
|
36
|
+
* @platform ios 16.0+
|
|
37
|
+
* @platform tvos 16.0+
|
|
38
|
+
*/
|
|
39
|
+
timerInterval?: ClosedRangeDate;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Whether the timer counts down (`true`) or up (`false`).
|
|
43
|
+
* @default true
|
|
44
|
+
* @platform ios 16.0+
|
|
45
|
+
* @platform tvos 16.0+
|
|
46
|
+
*/
|
|
47
|
+
countsDown?: boolean;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A date at which the timer should appear paused.
|
|
51
|
+
* @platform ios 16.0+
|
|
52
|
+
* @platform tvos 16.0+
|
|
53
|
+
*/
|
|
54
|
+
pauseTime?: Date;
|
|
17
55
|
}
|
|
18
56
|
|
|
19
57
|
type NativeTextProps = CommonViewModifierProps & {
|
|
20
58
|
text?: string;
|
|
21
59
|
children?: React.ReactNode;
|
|
22
60
|
markdownEnabled?: boolean;
|
|
61
|
+
date?: number;
|
|
62
|
+
dateStyle?: TextDateStyle;
|
|
63
|
+
timerInterval?: { lower: number; upper: number };
|
|
64
|
+
countsDown?: boolean;
|
|
65
|
+
pauseTime?: number;
|
|
23
66
|
};
|
|
24
67
|
|
|
25
68
|
const TextNativeView: React.ComponentType<NativeTextProps> = requireNativeView(
|
|
@@ -28,7 +71,28 @@ const TextNativeView: React.ComponentType<NativeTextProps> = requireNativeView(
|
|
|
28
71
|
);
|
|
29
72
|
|
|
30
73
|
export function Text(props: TextProps) {
|
|
31
|
-
const { children, modifiers, ...restProps } = props;
|
|
74
|
+
const { children, modifiers, date, timerInterval, pauseTime, ...restProps } = props;
|
|
75
|
+
|
|
76
|
+
// Date/timer mode: pass converted timestamps to native, ignore children
|
|
77
|
+
if (date != null || timerInterval != null) {
|
|
78
|
+
return (
|
|
79
|
+
<TextNativeView
|
|
80
|
+
modifiers={modifiers}
|
|
81
|
+
{...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
|
|
82
|
+
{...restProps}
|
|
83
|
+
date={date ? date.getTime() : undefined}
|
|
84
|
+
timerInterval={
|
|
85
|
+
timerInterval
|
|
86
|
+
? {
|
|
87
|
+
lower: timerInterval.lower.getTime(),
|
|
88
|
+
upper: timerInterval.upper.getTime(),
|
|
89
|
+
}
|
|
90
|
+
: undefined
|
|
91
|
+
}
|
|
92
|
+
pauseTime={pauseTime ? pauseTime.getTime() : undefined}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
32
96
|
|
|
33
97
|
if (children === undefined || children === null) {
|
|
34
98
|
return null;
|
package/src/swift-ui/index.tsx
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
import { createModifier } from './createModifier';
|
|
2
2
|
|
|
3
|
+
export type EnvironmentConfig =
|
|
4
|
+
| { key: 'editMode'; value: 'active' | 'inactive' | 'transient' }
|
|
5
|
+
| { key: 'colorScheme'; value: 'light' | 'dark' }
|
|
6
|
+
| { key: 'locale'; value: string }
|
|
7
|
+
| { key: 'timeZone'; value: string };
|
|
8
|
+
|
|
3
9
|
/**
|
|
4
10
|
* Sets a SwiftUI environment value.
|
|
5
11
|
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/environment(_:_:)).
|
|
6
12
|
*/
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
export function environment(config: EnvironmentConfig): ReturnType<typeof createModifier>;
|
|
14
|
+
export function environment(
|
|
15
|
+
key: EnvironmentConfig['key'],
|
|
16
|
+
value: string
|
|
17
|
+
): ReturnType<typeof createModifier>;
|
|
18
|
+
export function environment(configOrKey: EnvironmentConfig | string, value?: string) {
|
|
19
|
+
if (typeof configOrKey === 'string') {
|
|
20
|
+
return createModifier('environment', { key: configOrKey, value });
|
|
21
|
+
}
|
|
22
|
+
return createModifier('environment', configOrKey);
|
|
23
|
+
}
|
|
@@ -15,6 +15,7 @@ import { environment } from './environment';
|
|
|
15
15
|
import { gaugeStyle } from './gaugeStyle';
|
|
16
16
|
import { progressViewStyle } from './progressViewStyle';
|
|
17
17
|
import type { Color } from './types';
|
|
18
|
+
import { widgetAccentedRenderingMode, widgetURL } from './widgets';
|
|
18
19
|
|
|
19
20
|
const ExpoUI = requireNativeModule('ExpoUI');
|
|
20
21
|
|
|
@@ -567,6 +568,44 @@ export const scrollDismissesKeyboard = (
|
|
|
567
568
|
export const scrollDisabled = (disabled: boolean = true) =>
|
|
568
569
|
createModifier('scrollDisabled', { disabled });
|
|
569
570
|
|
|
571
|
+
type UnitPointValue =
|
|
572
|
+
| 'zero'
|
|
573
|
+
| 'topLeading'
|
|
574
|
+
| 'top'
|
|
575
|
+
| 'topTrailing'
|
|
576
|
+
| 'leading'
|
|
577
|
+
| 'center'
|
|
578
|
+
| 'trailing'
|
|
579
|
+
| 'bottomLeading'
|
|
580
|
+
| 'bottom'
|
|
581
|
+
| 'bottomTrailing';
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Sets the default anchor point for a scroll view's content.
|
|
585
|
+
* @param anchor - The anchor point for initial scroll position and content size changes, or `null` to reset.
|
|
586
|
+
* @platform ios 17.0+
|
|
587
|
+
* @platform tvos 17.0+
|
|
588
|
+
* @platform macos 14.0+
|
|
589
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/defaultscrollanchor(_:)).
|
|
590
|
+
*/
|
|
591
|
+
export const defaultScrollAnchor = (anchor: UnitPointValue | null) =>
|
|
592
|
+
createModifier('defaultScrollAnchor', { anchor });
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Sets the default anchor point for a scroll view for a specific role.
|
|
596
|
+
* Pass `null` to opt out of a specific role while keeping anchors for other roles.
|
|
597
|
+
* @param anchor - The anchor point, or `null` to opt out of this role.
|
|
598
|
+
* @param role - The scroll anchor role: `'initialOffset'`, `'sizeChanges'`, or `'alignment'`.
|
|
599
|
+
* @platform ios 18.0+
|
|
600
|
+
* @platform tvos 18.0+
|
|
601
|
+
* @platform macos 15.0+
|
|
602
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/defaultscrollanchor(_:for:)).
|
|
603
|
+
*/
|
|
604
|
+
export const defaultScrollAnchorForRole = (
|
|
605
|
+
anchor: UnitPointValue | null,
|
|
606
|
+
role: 'initialOffset' | 'sizeChanges' | 'alignment'
|
|
607
|
+
) => createModifier('defaultScrollAnchorForRole', { anchor, role });
|
|
608
|
+
|
|
570
609
|
/**
|
|
571
610
|
* Disables the move action for a view in a list.
|
|
572
611
|
* Apply to items within a `ForEach` to prevent them from being moved.
|
|
@@ -1018,15 +1057,6 @@ export const resizable = (
|
|
|
1018
1057
|
resizingMode?: 'stretch' | 'tile'
|
|
1019
1058
|
) => createModifier('resizable', { ...capInsets, resizingMode });
|
|
1020
1059
|
|
|
1021
|
-
/**
|
|
1022
|
-
* Specifies the how to render an Image when using the WidgetKit/WidgetRenderingMode/accented mode.
|
|
1023
|
-
* @param renderingMode - A constant describing how the Image should be rendered.
|
|
1024
|
-
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/image/widgetaccentedrenderingmode(_:)).
|
|
1025
|
-
*/
|
|
1026
|
-
export const widgetAccentedRenderingMode = (
|
|
1027
|
-
renderingMode: 'fullColor' | 'accented' | 'desaturated' | 'accentedDesaturated'
|
|
1028
|
-
) => createModifier('widgetAccentedRenderingMode', { renderingMode });
|
|
1029
|
-
|
|
1030
1060
|
// =============================================================================
|
|
1031
1061
|
// Type Definitions
|
|
1032
1062
|
// =============================================================================
|
|
@@ -1097,6 +1127,8 @@ export type BuiltInModifier =
|
|
|
1097
1127
|
| ReturnType<typeof containerRelativeFrame>
|
|
1098
1128
|
| ReturnType<typeof scrollContentBackground>
|
|
1099
1129
|
| ReturnType<typeof scrollDisabled>
|
|
1130
|
+
| ReturnType<typeof defaultScrollAnchor>
|
|
1131
|
+
| ReturnType<typeof defaultScrollAnchorForRole>
|
|
1100
1132
|
| ReturnType<typeof moveDisabled>
|
|
1101
1133
|
| ReturnType<typeof deleteDisabled>
|
|
1102
1134
|
| ReturnType<typeof environment>
|
|
@@ -1129,7 +1161,8 @@ export type BuiltInModifier =
|
|
|
1129
1161
|
| ReturnType<typeof listStyle>
|
|
1130
1162
|
| ReturnType<typeof contentTransition>
|
|
1131
1163
|
| ReturnType<typeof resizable>
|
|
1132
|
-
| ReturnType<typeof widgetAccentedRenderingMode
|
|
1164
|
+
| ReturnType<typeof widgetAccentedRenderingMode>
|
|
1165
|
+
| ReturnType<typeof widgetURL>;
|
|
1133
1166
|
|
|
1134
1167
|
/**
|
|
1135
1168
|
* Main ViewModifier type that supports both built-in and 3rd party modifiers.
|
|
@@ -1174,6 +1207,7 @@ export * from './progressViewStyle';
|
|
|
1174
1207
|
export * from './gaugeStyle';
|
|
1175
1208
|
export * from './presentationModifiers';
|
|
1176
1209
|
export * from './environment';
|
|
1210
|
+
export * from './widgets';
|
|
1177
1211
|
export type {
|
|
1178
1212
|
TimingAnimationParams,
|
|
1179
1213
|
SpringAnimationParams,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createModifier } from './createModifier';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Specifies the how to render an Image when using the WidgetKit/WidgetRenderingMode/accented mode.
|
|
5
|
+
* @param renderingMode - A constant describing how the Image should be rendered.
|
|
6
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/image/widgetaccentedrenderingmode(_:)).
|
|
7
|
+
*/
|
|
8
|
+
export const widgetAccentedRenderingMode = (
|
|
9
|
+
renderingMode: 'fullColor' | 'accented' | 'desaturated' | 'accentedDesaturated'
|
|
10
|
+
) => createModifier('widgetAccentedRenderingMode', { renderingMode });
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Sets the URL to open in the containing app when the user clicks the widget.
|
|
14
|
+
* Widgets support one widgetURL modifier in their view hierarchy. If multiple views have widgetURL modifiers, the behavior is undefined.
|
|
15
|
+
* @param url - The URL to open in the containing app.
|
|
16
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/SwiftUI/View/widgetURL(_:)).
|
|
17
|
+
*/
|
|
18
|
+
export const widgetURL = (url: string) => createModifier('widgetURL', { url });
|
package/src/swift-ui/types.ts
CHANGED
|
@@ -73,6 +73,11 @@ export interface PaddingProps {
|
|
|
73
73
|
trailing?: number;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
/**
|
|
77
|
+
* A closed date range with lower and upper bounds.
|
|
78
|
+
*/
|
|
79
|
+
export type ClosedRangeDate = { lower: Date; upper: Date };
|
|
80
|
+
|
|
76
81
|
/**
|
|
77
82
|
* Common props that can be applied to any view.
|
|
78
83
|
*/
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
package expo.modules.ui
|
|
2
|
-
|
|
3
|
-
import androidx.compose.material3.FilterChip
|
|
4
|
-
import androidx.compose.material3.FilterChipDefaults
|
|
5
|
-
import androidx.compose.material3.Text
|
|
6
|
-
import androidx.compose.runtime.Composable
|
|
7
|
-
import expo.modules.kotlin.records.Record
|
|
8
|
-
import expo.modules.kotlin.views.ComposableScope
|
|
9
|
-
import expo.modules.kotlin.views.ComposeProps
|
|
10
|
-
import expo.modules.kotlin.views.FunctionalComposableScope
|
|
11
|
-
import java.io.Serializable
|
|
12
|
-
|
|
13
|
-
open class FilterChipPressedEvent : Record, Serializable
|
|
14
|
-
|
|
15
|
-
data class FilterChipProps(
|
|
16
|
-
val selected: Boolean = false,
|
|
17
|
-
val label: String = "",
|
|
18
|
-
val enabled: Boolean = true,
|
|
19
|
-
val modifiers: ModifierList = emptyList()
|
|
20
|
-
) : ComposeProps
|
|
21
|
-
|
|
22
|
-
@Composable
|
|
23
|
-
fun FunctionalComposableScope.FilterChipContent(
|
|
24
|
-
props: FilterChipProps,
|
|
25
|
-
onPress: (FilterChipPressedEvent) -> Unit
|
|
26
|
-
) {
|
|
27
|
-
val modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher)
|
|
28
|
-
|
|
29
|
-
val leadingIconSlotView = findChildSlotView(view, "leadingIcon")
|
|
30
|
-
val trailingIconSlotView = findChildSlotView(view, "trailingIcon")
|
|
31
|
-
|
|
32
|
-
FilterChip(
|
|
33
|
-
selected = props.selected,
|
|
34
|
-
onClick = { onPress(FilterChipPressedEvent()) },
|
|
35
|
-
label = { Text(props.label) },
|
|
36
|
-
enabled = props.enabled,
|
|
37
|
-
leadingIcon = leadingIconSlotView?.let {
|
|
38
|
-
{
|
|
39
|
-
with(ComposableScope()) {
|
|
40
|
-
with(it) {
|
|
41
|
-
Content()
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
trailingIcon = trailingIconSlotView?.let {
|
|
47
|
-
{
|
|
48
|
-
with(ComposableScope()) {
|
|
49
|
-
with(it) {
|
|
50
|
-
Content()
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
colors = FilterChipDefaults.filterChipColors(),
|
|
56
|
-
border = FilterChipDefaults.filterChipBorder(enabled = props.enabled, selected = props.selected),
|
|
57
|
-
modifier = modifier
|
|
58
|
-
)
|
|
59
|
-
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
package expo.modules.ui
|
|
2
|
-
|
|
3
|
-
import android.graphics.Color
|
|
4
|
-
import androidx.compose.foundation.layout.Column
|
|
5
|
-
import androidx.compose.foundation.layout.Row
|
|
6
|
-
import androidx.compose.foundation.layout.fillMaxWidth
|
|
7
|
-
import androidx.compose.foundation.layout.height
|
|
8
|
-
import androidx.compose.foundation.layout.padding
|
|
9
|
-
import androidx.compose.foundation.selection.selectable
|
|
10
|
-
import androidx.compose.foundation.selection.selectableGroup
|
|
11
|
-
import androidx.compose.material3.RadioButton
|
|
12
|
-
import androidx.compose.material3.SegmentedButton
|
|
13
|
-
import androidx.compose.material3.SegmentedButtonDefaults
|
|
14
|
-
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
|
|
15
|
-
import androidx.compose.material3.Text
|
|
16
|
-
import androidx.compose.runtime.Composable
|
|
17
|
-
import androidx.compose.ui.Alignment
|
|
18
|
-
import androidx.compose.ui.Modifier
|
|
19
|
-
import androidx.compose.ui.semantics.Role
|
|
20
|
-
import androidx.compose.ui.unit.dp
|
|
21
|
-
import expo.modules.kotlin.records.Field
|
|
22
|
-
import expo.modules.kotlin.records.Record
|
|
23
|
-
import expo.modules.kotlin.views.ComposeProps
|
|
24
|
-
import expo.modules.kotlin.views.FunctionalComposableScope
|
|
25
|
-
|
|
26
|
-
class PickerColors : Record {
|
|
27
|
-
@Field
|
|
28
|
-
val activeBorderColor: Color? = null
|
|
29
|
-
|
|
30
|
-
@Field
|
|
31
|
-
val activeContentColor: Color? = null
|
|
32
|
-
|
|
33
|
-
@Field
|
|
34
|
-
val inactiveBorderColor: Color? = null
|
|
35
|
-
|
|
36
|
-
@Field
|
|
37
|
-
val inactiveContentColor: Color? = null
|
|
38
|
-
|
|
39
|
-
@Field
|
|
40
|
-
val disabledActiveBorderColor: Color? = null
|
|
41
|
-
|
|
42
|
-
@Field
|
|
43
|
-
val disabledActiveContentColor: Color? = null
|
|
44
|
-
|
|
45
|
-
@Field
|
|
46
|
-
val disabledInactiveBorderColor: Color? = null
|
|
47
|
-
|
|
48
|
-
@Field
|
|
49
|
-
val disabledInactiveContentColor: Color? = null
|
|
50
|
-
|
|
51
|
-
@Field
|
|
52
|
-
val activeContainerColor: Color? = null
|
|
53
|
-
|
|
54
|
-
@Field
|
|
55
|
-
val inactiveContainerColor: Color? = null
|
|
56
|
-
|
|
57
|
-
@Field
|
|
58
|
-
val disabledActiveContainerColor: Color? = null
|
|
59
|
-
|
|
60
|
-
@Field
|
|
61
|
-
val disabledInactiveContainerColor: Color? = null
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
data class PickerProps(
|
|
65
|
-
val options: Array<String> = emptyArray(),
|
|
66
|
-
val selectedIndex: Int? = null,
|
|
67
|
-
val elementColors: PickerColors = PickerColors(),
|
|
68
|
-
val variant: String = "segmented",
|
|
69
|
-
val buttonModifiers: List<ModifierType> = emptyList(),
|
|
70
|
-
val modifiers: ModifierList = emptyList()
|
|
71
|
-
) : ComposeProps
|
|
72
|
-
|
|
73
|
-
data class PickerOptionSelectedEvent(
|
|
74
|
-
@Field val index: Int,
|
|
75
|
-
@Field val label: String
|
|
76
|
-
) : Record
|
|
77
|
-
|
|
78
|
-
@Composable
|
|
79
|
-
fun FunctionalComposableScope.PickerContent(
|
|
80
|
-
props: PickerProps,
|
|
81
|
-
onOptionSelected: (PickerOptionSelectedEvent) -> Unit
|
|
82
|
-
) {
|
|
83
|
-
val selectedIndex = props.selectedIndex
|
|
84
|
-
val options = props.options
|
|
85
|
-
val colors = props.elementColors
|
|
86
|
-
val variant = props.variant
|
|
87
|
-
|
|
88
|
-
@Composable
|
|
89
|
-
fun SegmentedComposable() {
|
|
90
|
-
SingleChoiceSegmentedButtonRow(
|
|
91
|
-
modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher)
|
|
92
|
-
) {
|
|
93
|
-
options.forEachIndexed { index, label ->
|
|
94
|
-
SegmentedButton(
|
|
95
|
-
shape = SegmentedButtonDefaults.itemShape(
|
|
96
|
-
index = index,
|
|
97
|
-
count = options.size
|
|
98
|
-
),
|
|
99
|
-
onClick = {
|
|
100
|
-
onOptionSelected(PickerOptionSelectedEvent(index, label))
|
|
101
|
-
},
|
|
102
|
-
modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher),
|
|
103
|
-
selected = index == selectedIndex,
|
|
104
|
-
label = { Text(label) },
|
|
105
|
-
colors = SegmentedButtonDefaults.colors(
|
|
106
|
-
activeBorderColor = colors.activeBorderColor.compose,
|
|
107
|
-
activeContentColor = colors.activeContentColor.compose,
|
|
108
|
-
inactiveBorderColor = colors.inactiveBorderColor.compose,
|
|
109
|
-
inactiveContentColor = colors.inactiveContentColor.compose,
|
|
110
|
-
disabledActiveBorderColor = colors.disabledActiveBorderColor.compose,
|
|
111
|
-
disabledActiveContentColor = colors.disabledActiveContentColor.compose,
|
|
112
|
-
disabledInactiveBorderColor = colors.disabledInactiveBorderColor.compose,
|
|
113
|
-
disabledInactiveContentColor = colors.disabledInactiveContentColor.compose,
|
|
114
|
-
activeContainerColor = colors.activeContainerColor.compose,
|
|
115
|
-
inactiveContainerColor = colors.inactiveContainerColor.compose,
|
|
116
|
-
disabledActiveContainerColor = colors.disabledActiveContainerColor.compose,
|
|
117
|
-
disabledInactiveContainerColor = colors.disabledInactiveContainerColor.compose
|
|
118
|
-
)
|
|
119
|
-
)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
@Composable
|
|
125
|
-
fun RadioComposable() {
|
|
126
|
-
Column(Modifier.selectableGroup()) {
|
|
127
|
-
options.forEachIndexed { index, label ->
|
|
128
|
-
Row(
|
|
129
|
-
Modifier.fillMaxWidth()
|
|
130
|
-
.height(28.dp)
|
|
131
|
-
.selectable(
|
|
132
|
-
selected = index == selectedIndex,
|
|
133
|
-
onClick = {
|
|
134
|
-
onOptionSelected(PickerOptionSelectedEvent(index, label))
|
|
135
|
-
},
|
|
136
|
-
role = Role.RadioButton
|
|
137
|
-
),
|
|
138
|
-
verticalAlignment = Alignment.CenterVertically
|
|
139
|
-
) {
|
|
140
|
-
RadioButton(
|
|
141
|
-
selected = index == selectedIndex,
|
|
142
|
-
onClick = null
|
|
143
|
-
)
|
|
144
|
-
Text(
|
|
145
|
-
text = label,
|
|
146
|
-
modifier = Modifier.padding(start = 12.dp)
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (variant == "segmented") {
|
|
154
|
-
SegmentedComposable()
|
|
155
|
-
} else if (variant == "radio") {
|
|
156
|
-
RadioComposable()
|
|
157
|
-
} else {
|
|
158
|
-
// Default to segmented picker
|
|
159
|
-
SegmentedComposable()
|
|
160
|
-
}
|
|
161
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
package expo.modules.ui
|
|
2
|
-
|
|
3
|
-
import android.graphics.Color
|
|
4
|
-
import androidx.compose.material3.Text
|
|
5
|
-
import androidx.compose.material3.TextButton
|
|
6
|
-
import androidx.compose.runtime.Composable
|
|
7
|
-
import expo.modules.kotlin.views.ComposeProps
|
|
8
|
-
import expo.modules.kotlin.views.FunctionalComposableScope
|
|
9
|
-
import expo.modules.ui.button.ButtonPressedEvent
|
|
10
|
-
|
|
11
|
-
data class TextButtonProps(
|
|
12
|
-
val text: String = "",
|
|
13
|
-
val color: Color? = null,
|
|
14
|
-
val disabled: Boolean = false,
|
|
15
|
-
val modifiers: ModifierList = emptyList()
|
|
16
|
-
) : ComposeProps
|
|
17
|
-
|
|
18
|
-
@Composable
|
|
19
|
-
fun FunctionalComposableScope.TextButtonContent(
|
|
20
|
-
props: TextButtonProps,
|
|
21
|
-
onButtonPressed: (ButtonPressedEvent) -> Unit
|
|
22
|
-
) {
|
|
23
|
-
TextButton(
|
|
24
|
-
onClick = { onButtonPressed(ButtonPressedEvent()) },
|
|
25
|
-
enabled = !props.disabled,
|
|
26
|
-
modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher)
|
|
27
|
-
) {
|
|
28
|
-
Text(
|
|
29
|
-
text = props.text,
|
|
30
|
-
color = props.color.composeOrNull ?: androidx.compose.ui.graphics.Color.Unspecified
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
package expo.modules.ui.menu
|
|
2
|
-
|
|
3
|
-
import androidx.compose.foundation.background
|
|
4
|
-
import androidx.compose.foundation.layout.Arrangement
|
|
5
|
-
import androidx.compose.foundation.layout.Box
|
|
6
|
-
import androidx.compose.foundation.layout.Row
|
|
7
|
-
import androidx.compose.foundation.layout.fillMaxWidth
|
|
8
|
-
import androidx.compose.foundation.layout.padding
|
|
9
|
-
import androidx.compose.foundation.layout.wrapContentSize
|
|
10
|
-
import androidx.compose.material3.DropdownMenu
|
|
11
|
-
import androidx.compose.material3.DropdownMenuItem
|
|
12
|
-
import androidx.compose.material3.HorizontalDivider
|
|
13
|
-
import androidx.compose.material3.Icon
|
|
14
|
-
import androidx.compose.material3.MaterialTheme
|
|
15
|
-
import androidx.compose.material3.MenuDefaults
|
|
16
|
-
import androidx.compose.material3.MenuItemColors
|
|
17
|
-
import androidx.compose.material3.Text
|
|
18
|
-
import androidx.compose.runtime.Composable
|
|
19
|
-
import androidx.compose.runtime.CompositionLocalProvider
|
|
20
|
-
import androidx.compose.runtime.MutableState
|
|
21
|
-
import androidx.compose.runtime.compositionLocalOf
|
|
22
|
-
import androidx.compose.runtime.mutableStateOf
|
|
23
|
-
import androidx.compose.runtime.remember
|
|
24
|
-
import androidx.compose.ui.Alignment
|
|
25
|
-
import androidx.compose.ui.Modifier
|
|
26
|
-
import androidx.compose.ui.unit.dp
|
|
27
|
-
import expo.modules.kotlin.viewevent.ViewEventCallback
|
|
28
|
-
import expo.modules.kotlin.views.ComposableScope
|
|
29
|
-
import expo.modules.kotlin.views.FunctionalComposableScope
|
|
30
|
-
import expo.modules.ui.ModifierRegistry
|
|
31
|
-
import expo.modules.ui.ThemedHybridSwitch
|
|
32
|
-
import expo.modules.ui.compose
|
|
33
|
-
import expo.modules.ui.composeOrNull
|
|
34
|
-
import expo.modules.ui.getImageVector
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* CompositionLocal that allows child composables (like Button) to trigger ContextMenu expansion.
|
|
38
|
-
* When a Button is inside a ContextMenu, it can use this to open the menu on click.
|
|
39
|
-
*/
|
|
40
|
-
val LocalContextMenuExpanded = compositionLocalOf<MutableState<Boolean>?> { null }
|
|
41
|
-
|
|
42
|
-
@Composable
|
|
43
|
-
private fun SectionTitle(text: String) {
|
|
44
|
-
Text(
|
|
45
|
-
text = text,
|
|
46
|
-
style = MaterialTheme.typography.labelSmall,
|
|
47
|
-
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
48
|
-
modifier = Modifier
|
|
49
|
-
.fillMaxWidth()
|
|
50
|
-
.padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 4.dp)
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
@Composable
|
|
55
|
-
fun FlatMenu(elements: Array<ContextMenuElement>, sectionTitle: String?, dispatchers: ContextMenuDispatchers, expanded: MutableState<Boolean>) {
|
|
56
|
-
sectionTitle?.takeIf { !it.isEmpty() }?.let {
|
|
57
|
-
SectionTitle(it)
|
|
58
|
-
}
|
|
59
|
-
elements.forEachIndexed { index, element ->
|
|
60
|
-
val id = element.contextMenuElementID
|
|
61
|
-
element.button?.let {
|
|
62
|
-
DropdownMenuItem(
|
|
63
|
-
colors = MenuItemColors(
|
|
64
|
-
textColor = it.elementColors.contentColor.compose,
|
|
65
|
-
leadingIconColor = it.elementColors.contentColor.compose,
|
|
66
|
-
trailingIconColor = it.elementColors.contentColor.compose,
|
|
67
|
-
disabledTextColor = it.elementColors.disabledContentColor.compose,
|
|
68
|
-
disabledLeadingIconColor = it.elementColors.disabledContentColor.compose,
|
|
69
|
-
disabledTrailingIconColor = it.elementColors.disabledContentColor.compose
|
|
70
|
-
),
|
|
71
|
-
enabled = !it.disabled,
|
|
72
|
-
modifier = Modifier.background(it.elementColors.containerColor.compose),
|
|
73
|
-
text = { Text(it.text) },
|
|
74
|
-
leadingIcon = it.leadingIcon?.let { iconName ->
|
|
75
|
-
{
|
|
76
|
-
getImageVector(iconName)?.let { imageVector ->
|
|
77
|
-
Icon(
|
|
78
|
-
imageVector = imageVector,
|
|
79
|
-
contentDescription = iconName
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
trailingIcon = it.trailingIcon?.let { iconName ->
|
|
85
|
-
{
|
|
86
|
-
getImageVector(iconName)?.let { imageVector ->
|
|
87
|
-
Icon(
|
|
88
|
-
imageVector = imageVector,
|
|
89
|
-
contentDescription = iconName
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
onClick = {
|
|
95
|
-
dispatchers.buttonPressed(ContextMenuButtonPressedEvent(id))
|
|
96
|
-
expanded.value = false
|
|
97
|
-
}
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
element.switch?.let {
|
|
102
|
-
DropdownMenuItem(
|
|
103
|
-
text = {
|
|
104
|
-
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
105
|
-
Text(it.label)
|
|
106
|
-
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
|
107
|
-
ThemedHybridSwitch(
|
|
108
|
-
variant = it.variant,
|
|
109
|
-
checked = it.value,
|
|
110
|
-
onCheckedChange = null,
|
|
111
|
-
colors = it.elementColors,
|
|
112
|
-
modifier = Modifier
|
|
113
|
-
.padding(horizontal = 5.dp)
|
|
114
|
-
.wrapContentSize(Alignment.CenterEnd)
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
modifier = Modifier.wrapContentSize(Alignment.Center),
|
|
120
|
-
onClick = {
|
|
121
|
-
dispatchers.switchCheckedChanged(
|
|
122
|
-
ContextMenuSwitchValueChangeEvent(!it.value, id)
|
|
123
|
-
)
|
|
124
|
-
expanded.value = false
|
|
125
|
-
}
|
|
126
|
-
)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
element.submenu?.let {
|
|
130
|
-
HorizontalDivider()
|
|
131
|
-
FlatMenu(it.elements, it.button.text, dispatchers, expanded)
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
data class ContextMenuDispatchers(
|
|
137
|
-
val buttonPressed: ViewEventCallback<ContextMenuButtonPressedEvent>,
|
|
138
|
-
val switchCheckedChanged: ViewEventCallback<ContextMenuSwitchValueChangeEvent>
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
@Composable
|
|
142
|
-
fun FunctionalComposableScope.ContextMenuContent(
|
|
143
|
-
props: ContextMenuProps,
|
|
144
|
-
onContextMenuButtonPressed: (ContextMenuButtonPressedEvent) -> Unit,
|
|
145
|
-
onContextMenuSwitchValueChanged: (ContextMenuSwitchValueChangeEvent) -> Unit,
|
|
146
|
-
onExpandedChanged: (ExpandedChangedEvent) -> Unit
|
|
147
|
-
) {
|
|
148
|
-
val expanded = remember { mutableStateOf(false) }
|
|
149
|
-
val elements = props.elements
|
|
150
|
-
val color = props.color
|
|
151
|
-
|
|
152
|
-
// Provide expanded state to children via CompositionLocal
|
|
153
|
-
// This allows Button children to trigger menu expansion
|
|
154
|
-
CompositionLocalProvider(LocalContextMenuExpanded provides expanded) {
|
|
155
|
-
Box(modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher)) {
|
|
156
|
-
// Trigger button - Button will automatically expand menu when clicked
|
|
157
|
-
Children(ComposableScope())
|
|
158
|
-
|
|
159
|
-
DropdownMenu(
|
|
160
|
-
containerColor = color?.composeOrNull ?: MenuDefaults.containerColor,
|
|
161
|
-
expanded = expanded.value,
|
|
162
|
-
onDismissRequest = {
|
|
163
|
-
expanded.value = false
|
|
164
|
-
onExpandedChanged(ExpandedChangedEvent(false))
|
|
165
|
-
}
|
|
166
|
-
) {
|
|
167
|
-
FlatMenu(
|
|
168
|
-
elements,
|
|
169
|
-
null,
|
|
170
|
-
dispatchers = ContextMenuDispatchers(
|
|
171
|
-
buttonPressed = onContextMenuButtonPressed,
|
|
172
|
-
switchCheckedChanged = onContextMenuSwitchValueChanged
|
|
173
|
-
),
|
|
174
|
-
expanded = expanded
|
|
175
|
-
)
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
data class ExpandedChangedEvent(
|
|
182
|
-
@expo.modules.kotlin.records.Field val expanded: Boolean
|
|
183
|
-
) : expo.modules.kotlin.records.Record
|