pytech-ui 1.0.21 → 1.0.24

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 (151) hide show
  1. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  2. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  3. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  4. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  5. package/android/.gradle/8.9/gc.properties +0 -0
  6. package/android/.gradle/9.3.0/checksums/checksums.lock +0 -0
  7. package/android/.gradle/9.3.0/fileChanges/last-build.bin +0 -0
  8. package/android/.gradle/9.3.0/fileHashes/fileHashes.bin +0 -0
  9. package/android/.gradle/9.3.0/fileHashes/fileHashes.lock +0 -0
  10. package/android/.gradle/9.3.0/gc.properties +0 -0
  11. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  12. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  13. package/android/.gradle/nb-cache/trust/8732A504261C070E1F639E78DF65F8E6DC6FFC865B3D7178A7609BB57105805F +1 -0
  14. package/android/.gradle/vcs-1/gc.properties +0 -0
  15. package/android/build.gradle +47 -0
  16. package/android/src/main/AndroidManifest.xml +2 -0
  17. package/android/src/main/java/expo/modules/myui/Dialog.kt +39 -0
  18. package/android/src/main/java/expo/modules/myui/ForEach/ForEachRecords.kt +23 -0
  19. package/android/src/main/java/expo/modules/myui/ForEach/index.kt +82 -0
  20. package/android/src/main/java/expo/modules/myui/Gradient/GradientView.kt +124 -0
  21. package/android/src/main/java/expo/modules/myui/Icon/index.kt +36 -0
  22. package/android/src/main/java/expo/modules/myui/Icon/utils.kt +43 -0
  23. package/android/src/main/java/expo/modules/myui/ListItem/Data/ListItemDataRecords.kt +84 -0
  24. package/android/src/main/java/expo/modules/myui/ListItem/Data/ListItemFromData.kt +127 -0
  25. package/android/src/main/java/expo/modules/myui/ListItem/Slots/ListItemFromSlots.kt +60 -0
  26. package/android/src/main/java/expo/modules/myui/ListItem/Slots/types.kt +42 -0
  27. package/android/src/main/java/expo/modules/myui/ListItem/_shared/Decorator/Decorator.kt +79 -0
  28. package/android/src/main/java/expo/modules/myui/ListItem/_shared/Decorator/Divider.kt +36 -0
  29. package/android/src/main/java/expo/modules/myui/ListItem/_shared/Decorator/utilsDecorator.kt +19 -0
  30. package/android/src/main/java/expo/modules/myui/ListItem/_shared/Dynamic/Dynamic.kt +163 -0
  31. package/android/src/main/java/expo/modules/myui/ListItem/_shared/Dynamic/Row.kt +136 -0
  32. package/android/src/main/java/expo/modules/myui/Menu/DropdownMenu.kt +48 -0
  33. package/android/src/main/java/expo/modules/myui/Menu/DropdownMenuRecords.kt +20 -0
  34. package/android/src/main/java/expo/modules/myui/MyUiModifiers.kt +94 -0
  35. package/android/src/main/java/expo/modules/myui/MyUiModule.kt +168 -0
  36. package/android/src/main/java/expo/modules/myui/SearchBar.kt +213 -0
  37. package/android/src/main/java/expo/modules/myui/Section/SectionHost.kt +81 -0
  38. package/android/src/main/java/expo/modules/myui/Section/SectionHostView.kt +65 -0
  39. package/android/src/main/java/expo/modules/myui/TextField.kt +251 -0
  40. package/android/src/main/java/expo/modules/myui/TypographySlot/TypographySlotBridge.kt +120 -0
  41. package/android/src/main/java/expo/modules/myui/TypographySlot/constants.kt +47 -0
  42. package/android/src/main/java/expo/modules/myui/TypographySlot/index.kt +43 -0
  43. package/android/src/main/java/expo/modules/myui/extended-theme/ExtendedThemeView.kt +19 -0
  44. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Colors/ExtendedColorBridge.kt +77 -0
  45. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Colors/index.kt +148 -0
  46. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Constants/Constants.kt +11 -0
  47. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/AppBarLargeFlexibleTokens.kt +20 -0
  48. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/AppBarLargeTokens.kt +19 -0
  49. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/AppBarMediumFlexibleTokens.kt +20 -0
  50. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/AppBarMediumTokens.kt +19 -0
  51. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/AppBarSmallTokens.kt +19 -0
  52. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/AppBarTokens.kt +23 -0
  53. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/AssistChipTokens.kt +25 -0
  54. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/BadgeTokens.kt +20 -0
  55. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/BaselineButtonTokens.kt +26 -0
  56. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/BottomAppBarTokens.kt +19 -0
  57. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ButtonGroupSmallTokens.kt +20 -0
  58. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ButtonLargeTokens.kt +24 -0
  59. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ButtonMediumTokens.kt +24 -0
  60. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ButtonSmallTokens.kt +24 -0
  61. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ButtonXLargeTokens.kt +24 -0
  62. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ButtonXSmallTokens.kt +24 -0
  63. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/CheckboxTokens.kt +35 -0
  64. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/CircularProgressIndicatorTokens.kt +25 -0
  65. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ConnectedButtonGroupSmallTokens.kt +21 -0
  66. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/DateInputModalTokens.kt +22 -0
  67. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/DatePickerModalTokens.kt +33 -0
  68. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/DialogTokens.kt +19 -0
  69. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/DividerTokens.kt +19 -0
  70. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/DockedToolbarTokens.kt +23 -0
  71. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/DragHandleTokens.kt +25 -0
  72. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ElevatedButtonTokens.kt +19 -0
  73. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ElevatedCardTokens.kt +20 -0
  74. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ElevationTokens.kt +24 -0
  75. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ExpressiveMotionTokens.kt +28 -0
  76. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ExtendedFabLargeTokens.kt +23 -0
  77. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ExtendedFabMediumTokens.kt +24 -0
  78. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ExtendedFabPrimaryTokens.kt +20 -0
  79. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ExtendedFabSmallTokens.kt +23 -0
  80. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FabBaselineTokens.kt +21 -0
  81. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FabLargeTokens.kt +21 -0
  82. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FabMediumTokens.kt +22 -0
  83. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FabMenuBaselineTokens.kt +28 -0
  84. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FabSmallTokens.kt +21 -0
  85. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FilledAutocompleteTokens.kt +31 -0
  86. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FilledButtonTokens.kt +19 -0
  87. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FilledCardTokens.kt +20 -0
  88. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FilledIconButtonTokens.kt +18 -0
  89. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FilledTextFieldTokens.kt +31 -0
  90. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FilledTonalButtonTokens.kt +23 -0
  91. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FilledTonalIconButtonTokens.kt +18 -0
  92. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FilterChipTokens.kt +28 -0
  93. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/FloatingToolbarTokens.kt +23 -0
  94. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/IconButtonTokens.kt +17 -0
  95. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/InputChipTokens.kt +30 -0
  96. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/LargeIconButtonTokens.kt +27 -0
  97. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/LinearProgressIndicatorTokens.kt +28 -0
  98. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ListTokens.kt +57 -0
  99. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/LoadingIndicatorTokens.kt +21 -0
  100. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/MediumIconButtonTokens.kt +27 -0
  101. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/MotionTokens.kt +44 -0
  102. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/NavigationBarHorizontalItemTokens.kt +22 -0
  103. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/NavigationBarTokens.kt +23 -0
  104. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/NavigationBarVerticalItemTokens.kt +22 -0
  105. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/NavigationDrawerTokens.kt +23 -0
  106. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/NavigationRailBaselineItemTokens.kt +25 -0
  107. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/NavigationRailCollapsedTokens.kt +23 -0
  108. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/NavigationRailExpandedTokens.kt +22 -0
  109. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/NavigationRailHorizontalItemTokens.kt +24 -0
  110. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/NavigationRailVerticalItemTokens.kt +24 -0
  111. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/OutlinedAutocompleteTokens.kt +30 -0
  112. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/OutlinedButtonTokens.kt +19 -0
  113. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/OutlinedCardTokens.kt +21 -0
  114. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/OutlinedIconButtonTokens.kt +18 -0
  115. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/OutlinedSegmentedButtonTokens.kt +24 -0
  116. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/OutlinedTextFieldTokens.kt +31 -0
  117. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/PrimaryNavigationTabTokens.kt +24 -0
  118. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/RadioButtonTokens.kt +22 -0
  119. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ScrimTokens.kt +17 -0
  120. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SearchBarTokens.kt +20 -0
  121. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SearchViewTokens.kt +20 -0
  122. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SecondaryNavigationTabTokens.kt +21 -0
  123. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SegmentedMenuTokens.kt +42 -0
  124. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/ShapeTokens.kt +74 -0
  125. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SheetBottomTokens.kt +20 -0
  126. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SliderTokens.kt +39 -0
  127. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SmallIconButtonTokens.kt +27 -0
  128. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SnackbarTokens.kt +21 -0
  129. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SplitButtonLargeTokens.kt +26 -0
  130. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SplitButtonMediumTokens.kt +26 -0
  131. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SplitButtonSmallTokens.kt +26 -0
  132. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SplitButtonXLargeTokens.kt +26 -0
  133. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SplitButtonXSmallTokens.kt +27 -0
  134. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/StandardMenuTokens.kt +25 -0
  135. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/StandardMotionTokens.kt +27 -0
  136. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/StateTokens.kt +20 -0
  137. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SuggestionChipTokens.kt +25 -0
  138. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/SwitchTokens.kt +37 -0
  139. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/TextButtonTokens.kt +18 -0
  140. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/TimeInputTokens.kt +24 -0
  141. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/TimePickerTokens.kt +30 -0
  142. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/TonalButtonTokens.kt +19 -0
  143. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/TypeScaleTokens.kt +72 -0
  144. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/VibrantMenuTokens.kt +26 -0
  145. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/XLargeIconButtonTokens.kt +27 -0
  146. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/assets/XSmallIconButtonTokens.kt +27 -0
  147. package/android/src/main/java/expo/modules/myui/extended-theme/assets/Tokens/index.kt +217 -0
  148. package/android/src/main/java/expo/modules/myui/extended-theme/index.kt +39 -0
  149. package/android/src/main/java/expo/modules/myui/utils/children.kt +127 -0
  150. package/android/src/main/java/expo/modules/myui/utils/modifiers.kt +45 -0
  151. package/package.json +2 -1
@@ -0,0 +1,251 @@
1
+ package expo.modules.myui
2
+
3
+ import androidx.compose.foundation.layout.Arrangement
4
+ import androidx.compose.foundation.layout.Box
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.text.BasicTextField
9
+ import androidx.compose.foundation.text.KeyboardActions
10
+ import androidx.compose.foundation.text.KeyboardOptions
11
+ import androidx.compose.material3.LocalTextStyle
12
+ import androidx.compose.material3.Text
13
+ import androidx.compose.runtime.Composable
14
+ import androidx.compose.runtime.LaunchedEffect
15
+ import androidx.compose.runtime.getValue
16
+ import androidx.compose.runtime.mutableStateOf
17
+ import androidx.compose.runtime.remember
18
+ import androidx.compose.runtime.setValue
19
+ import androidx.compose.ui.Alignment
20
+ import androidx.compose.ui.Modifier
21
+ import androidx.compose.ui.focus.FocusDirection
22
+ import androidx.compose.ui.focus.FocusManager
23
+ import androidx.compose.ui.focus.FocusRequester
24
+ import androidx.compose.ui.focus.focusRequester
25
+ import androidx.compose.ui.focus.onFocusChanged
26
+ import androidx.compose.ui.graphics.SolidColor
27
+ import androidx.compose.ui.platform.LocalFocusManager
28
+ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
29
+ import androidx.compose.ui.text.input.ImeAction
30
+ import androidx.compose.ui.text.input.KeyboardCapitalization
31
+ import androidx.compose.ui.text.input.KeyboardType
32
+ import androidx.compose.ui.text.input.PasswordVisualTransformation
33
+ import androidx.compose.ui.text.input.VisualTransformation
34
+ import expo.modules.kotlin.records.Field
35
+ import expo.modules.kotlin.records.Record
36
+ import expo.modules.kotlin.types.OptimizedRecord
37
+ import expo.modules.kotlin.views.AsyncFunctionHandle
38
+ import expo.modules.kotlin.views.ComposeProps
39
+ import expo.modules.kotlin.views.FunctionalComposableScope
40
+ import expo.modules.myui.theme.ExtendedTheme
41
+ import expo.modules.ui.ModifierList
42
+ import java.io.Serializable
43
+ import androidx.compose.foundation.relocation.BringIntoViewRequester
44
+ import androidx.compose.foundation.relocation.bringIntoViewRequester
45
+ import androidx.compose.runtime.rememberCoroutineScope
46
+ import androidx.compose.ui.focus.onFocusEvent
47
+ import kotlinx.coroutines.delay
48
+ import kotlinx.coroutines.launch
49
+
50
+
51
+ data class TextFieldValueChangeEvent(
52
+ @Field val value: String = ""
53
+ ) : Record, Serializable
54
+
55
+ data class TextFieldFocusChangeEvent(
56
+ @Field val value: Boolean = false
57
+ ) : Record, Serializable
58
+
59
+ @OptimizedRecord
60
+ data class TextFieldKeyboardOptionsRecord(
61
+ @Field val capitalization: String? = null,
62
+ @Field val autoCorrectEnabled: Boolean? = null,
63
+ @Field val keyboardType: String? = null,
64
+ @Field val imeAction: String? = null
65
+ ) : Record
66
+
67
+ data class KeyboardActionEvent(
68
+ @Field val action: String,
69
+ @Field val value: String
70
+ ) : Record
71
+
72
+ /**
73
+ * [value] es solo el valor inicial; el texto editado vive en estado interno.
74
+ * [headlineText] opcional: se muestra a la izquierda del campo (misma fila que el input).
75
+ */
76
+ data class TextFieldProps(
77
+ val value: String = "",
78
+ val placeholder: String? = null,
79
+ val headlineText: String? = null,
80
+ val enabled: Boolean = true,
81
+ val autoFocus: Boolean = false,
82
+ val lines: Int = 1,
83
+ val keyboardOptions: TextFieldKeyboardOptionsRecord? = null,
84
+ val rowModifiers: ModifierList = emptyList(),
85
+ val textFieldModifiers: ModifierList = emptyList()
86
+ ) : ComposeProps
87
+
88
+ private fun String?.toKeyboardType(): KeyboardType = when (this) {
89
+ "text" -> KeyboardType.Text
90
+ "number" -> KeyboardType.Number
91
+ "email" -> KeyboardType.Email
92
+ "phone" -> KeyboardType.Phone
93
+ "decimal" -> KeyboardType.Decimal
94
+ "password" -> KeyboardType.Password
95
+ "ascii" -> KeyboardType.Ascii
96
+ "uri" -> KeyboardType.Uri
97
+ "numberPassword" -> KeyboardType.NumberPassword
98
+ else -> KeyboardType.Text
99
+ }
100
+
101
+ private fun String?.toCapitalization(): KeyboardCapitalization = when (this) {
102
+ "characters" -> KeyboardCapitalization.Characters
103
+ "none" -> KeyboardCapitalization.None
104
+ "sentences" -> KeyboardCapitalization.Sentences
105
+ "words" -> KeyboardCapitalization.Words
106
+ else -> KeyboardCapitalization.None
107
+ }
108
+
109
+ private fun String?.toImeAction(): ImeAction = when (this) {
110
+ "default" -> ImeAction.Default
111
+ "none" -> ImeAction.None
112
+ "go" -> ImeAction.Go
113
+ "search" -> ImeAction.Search
114
+ "send" -> ImeAction.Send
115
+ "previous" -> ImeAction.Previous
116
+ "next" -> ImeAction.Next
117
+ "done" -> ImeAction.Done
118
+ else -> ImeAction.Default
119
+ }
120
+
121
+ private fun FocusManager.performDefaultKeyboardAction(imeAction: ImeAction) {
122
+ when (imeAction) {
123
+ ImeAction.Next -> clearFocus() //moveFocus(FocusDirection.Down)
124
+ ImeAction.Previous -> clearFocus() //moveFocus(FocusDirection.Up)
125
+ ImeAction.Done, ImeAction.Go, ImeAction.Search, ImeAction.Send -> clearFocus()
126
+ else -> Unit
127
+ }
128
+ }
129
+
130
+ data class ExampleComposeViewProps(
131
+ @Field val title: String = "",
132
+ @Field val modifiers: ModifierList = emptyList()
133
+ ) : ComposeProps
134
+
135
+
136
+ @Composable
137
+ internal fun FunctionalComposableScope.TextFieldContent(
138
+ props: TextFieldProps,
139
+ focus: AsyncFunctionHandle<Unit>,
140
+ blur: AsyncFunctionHandle<Unit>,
141
+ onValueChange: (String) -> Unit,
142
+ onFocusChanged: (Boolean) -> Unit,
143
+ onKeyboardActionTriggered: (KeyboardActionEvent) -> Unit
144
+ ) {
145
+ var text by remember { mutableStateOf(props.value) }
146
+ val focusManager = LocalFocusManager.current
147
+ val focusRequester = remember { FocusRequester() }
148
+ val keyboardController = LocalSoftwareKeyboardController.current
149
+
150
+ focus.handle {
151
+ focusRequester.requestFocus()
152
+ keyboardController?.show()
153
+ }
154
+ blur.handle {
155
+ focusManager.clearFocus()
156
+ }
157
+
158
+ if (props.autoFocus) {
159
+ LaunchedEffect(Unit) {
160
+ delay(300)
161
+ runCatching {
162
+ focusRequester.requestFocus()
163
+ keyboardController?.show()
164
+ }
165
+ }
166
+ }
167
+
168
+ val kbOpts = props.keyboardOptions
169
+ val keyboardTypeKey = kbOpts?.keyboardType
170
+ val visualTransformation =
171
+ if (keyboardTypeKey == "password" || keyboardTypeKey == "numberPassword") {
172
+ PasswordVisualTransformation()
173
+ } else {
174
+ VisualTransformation.None
175
+ }
176
+ val keyboardOptions = KeyboardOptions.Default.copy(
177
+ keyboardType = keyboardTypeKey.toKeyboardType(),
178
+ autoCorrectEnabled = kbOpts?.autoCorrectEnabled ?: true,
179
+ capitalization = kbOpts?.capitalization.toCapitalization(),
180
+ imeAction = kbOpts?.imeAction.toImeAction()
181
+ )
182
+ val currentText = { text }
183
+ val keyboardActions = KeyboardActions(
184
+ onDone = {
185
+ focusManager.performDefaultKeyboardAction(ImeAction.Done)
186
+ onKeyboardActionTriggered(KeyboardActionEvent("done", currentText()))
187
+ },
188
+ onGo = {
189
+ focusManager.performDefaultKeyboardAction(ImeAction.Go)
190
+ onKeyboardActionTriggered(KeyboardActionEvent("go", currentText()))
191
+ },
192
+ onNext = {
193
+ focusManager.performDefaultKeyboardAction(ImeAction.Next)
194
+ onKeyboardActionTriggered(KeyboardActionEvent("next", currentText()))
195
+ },
196
+ onPrevious = {
197
+ focusManager.performDefaultKeyboardAction(ImeAction.Previous)
198
+ onKeyboardActionTriggered(KeyboardActionEvent("previous", currentText()))
199
+ },
200
+ onSearch = {
201
+ focusManager.performDefaultKeyboardAction(ImeAction.Search)
202
+ onKeyboardActionTriggered(KeyboardActionEvent("search", currentText()))
203
+ },
204
+ onSend = {
205
+ focusManager.performDefaultKeyboardAction(ImeAction.Send)
206
+ onKeyboardActionTriggered(KeyboardActionEvent("send", currentText()))
207
+ },
208
+ )
209
+
210
+ val bringIntoViewRequester = remember { BringIntoViewRequester() }
211
+ val scope = rememberCoroutineScope()
212
+
213
+ BasicTextField(
214
+ value = text,
215
+ onValueChange = { newValue ->
216
+ text = newValue
217
+ onValueChange(newValue)
218
+ },
219
+ modifier = Modifier
220
+ .fillMaxWidth()
221
+ .focusRequester(focusRequester)
222
+ .onFocusChanged { onFocusChanged(it.isFocused) }
223
+ .bringIntoViewRequester(bringIntoViewRequester)
224
+ .onFocusChanged { focusState ->
225
+ onFocusChanged(focusState.isFocused)
226
+ if (focusState.isFocused) {
227
+ scope.launch {
228
+ kotlinx.coroutines.delay(100)
229
+ bringIntoViewRequester.bringIntoView()
230
+ }
231
+ }
232
+ },
233
+ enabled = props.enabled,
234
+ textStyle = LocalTextStyle.current,
235
+ singleLine = props.lines == 1,
236
+ maxLines = if (props.lines > 1) props.lines.coerceAtLeast(2) else Int.MAX_VALUE,
237
+ cursorBrush = SolidColor(ExtendedTheme.colorScheme.systemBlue),
238
+ keyboardOptions = keyboardOptions,
239
+ keyboardActions = keyboardActions,
240
+ visualTransformation = visualTransformation,
241
+ decorationBox = { innerTextField ->
242
+ if (text.isEmpty() && !props.placeholder.isNullOrBlank()) {
243
+ Text(
244
+ text = props.placeholder!!,
245
+ color = ExtendedTheme.colorScheme.placeholderText
246
+ )
247
+ }
248
+ innerTextField()
249
+ },
250
+ )
251
+ }
@@ -0,0 +1,120 @@
1
+ package expo.modules.myui.TypographySlot
2
+
3
+ import androidx.compose.material3.MaterialTheme
4
+ import androidx.compose.runtime.Composable
5
+ import androidx.compose.ui.graphics.Color
6
+ import androidx.compose.ui.text.TextStyle
7
+ import androidx.compose.ui.text.font.FontWeight
8
+ import androidx.compose.ui.text.style.TextAlign
9
+ import androidx.compose.ui.unit.sp
10
+ import expo.modules.kotlin.records.Field
11
+ import expo.modules.kotlin.records.Record
12
+ import expo.modules.myui.theme.ExtendedTheme
13
+
14
+ data class SlotTypographyStyleRecord(
15
+ @Field val typography: String? = null,
16
+ @Field val fontSize: Double? = null,
17
+ @Field val lineHeight: Double? = null,
18
+ @Field val fontWeight: String? = null,
19
+ @Field val textAlign: String? = null,
20
+ ) : Record
21
+
22
+ data class SlotTextStyleRecord(
23
+ @Field val style: SlotTypographyStyleRecord,
24
+ @Field val color: String? = null,
25
+ @Field val overflow: String? = null,
26
+ @Field val maxLines: Int? = null,
27
+ ) : Record
28
+
29
+ /**
30
+ * Bridge de estilos por slot (Compose + JS vía [slotTextStylePayload]).
31
+ * Los valores viven en [Typographies.specs].
32
+ */
33
+ internal object TypographySlotBridge {
34
+
35
+ fun slotTextStylePayload(slotName: String): SlotTextStyleRecord? {
36
+ val spec = Typographies.specs[slotName.lowercase()] ?: return null
37
+ return SlotTextStyleRecord(
38
+ style = SlotTypographyStyleRecord(
39
+ typography = spec.typography,
40
+ fontSize = spec.fontSize?.toDouble(),
41
+ lineHeight = spec.lineHeight?.toDouble(),
42
+ fontWeight = spec.fontWeight?.toString(),
43
+ textAlign = spec.textAlign,
44
+ ),
45
+ color = spec.color,
46
+ overflow = spec.overflow,
47
+ maxLines = spec.maxLines,
48
+ )
49
+ }
50
+
51
+ @Composable
52
+ fun textStyleForSlot(slotName: String): TextStyle? {
53
+ val spec = Typographies.specs[slotName.lowercase()] ?: return null
54
+ var style = typographyFromToken(spec.typography)
55
+ spec.fontSize?.let { style = style.copy(fontSize = it.sp) }
56
+ spec.lineHeight?.let { style = style.copy(lineHeight = it.sp) }
57
+ spec.fontWeight?.let { style = style.copy(fontWeight = fontWeightFromValue(it)) }
58
+ spec.textAlign?.let { align ->
59
+ textAlignFromValue(align)?.let { style = style.copy(textAlign = it) }
60
+ }
61
+ colorFromToken(spec.color)?.let { style = style.copy(color = it) }
62
+ return style
63
+ }
64
+
65
+ @Composable
66
+ private fun typographyFromToken(token: String): TextStyle =
67
+ when (token) {
68
+ "displayLarge" -> MaterialTheme.typography.displayLarge
69
+ "displayMedium" -> MaterialTheme.typography.displayMedium
70
+ "displaySmall" -> MaterialTheme.typography.displaySmall
71
+ "headlineLarge" -> MaterialTheme.typography.headlineLarge
72
+ "headlineMedium" -> MaterialTheme.typography.headlineMedium
73
+ "headlineSmall" -> MaterialTheme.typography.headlineSmall
74
+ "titleLarge" -> MaterialTheme.typography.titleLarge
75
+ "titleMedium" -> MaterialTheme.typography.titleMedium
76
+ "titleSmall" -> MaterialTheme.typography.titleSmall
77
+ "bodyLarge" -> MaterialTheme.typography.bodyLarge
78
+ "bodyMedium" -> MaterialTheme.typography.bodyMedium
79
+ "bodySmall" -> MaterialTheme.typography.bodySmall
80
+ "labelLarge" -> MaterialTheme.typography.labelLarge
81
+ "labelMedium" -> MaterialTheme.typography.labelMedium
82
+ "labelSmall" -> MaterialTheme.typography.labelSmall
83
+ else -> MaterialTheme.typography.bodyLarge
84
+ }
85
+
86
+ private fun textAlignFromValue(value: String): TextAlign? =
87
+ when (value.lowercase()) {
88
+ "left" -> TextAlign.Left
89
+ "right" -> TextAlign.Right
90
+ "center" -> TextAlign.Center
91
+ "justify" -> TextAlign.Justify
92
+ "start" -> TextAlign.Start
93
+ "end" -> TextAlign.End
94
+ else -> null
95
+ }
96
+
97
+ private fun fontWeightFromValue(value: Int): FontWeight =
98
+ when (value) {
99
+ 100 -> FontWeight.Thin
100
+ 200 -> FontWeight.ExtraLight
101
+ 300 -> FontWeight.Light
102
+ 400 -> FontWeight.Normal
103
+ 500 -> FontWeight.Medium
104
+ 600 -> FontWeight.SemiBold
105
+ 700 -> FontWeight.Bold
106
+ 800 -> FontWeight.ExtraBold
107
+ 900 -> FontWeight.Black
108
+ else -> FontWeight(value)
109
+ }
110
+
111
+ @Composable
112
+ private fun colorFromToken(token: String?): Color? =
113
+ when (token?.lowercase()) {
114
+ "label" -> ExtendedTheme.colorScheme.label
115
+ "secondarylabel" -> ExtendedTheme.colorScheme.secondaryLabel
116
+ "tertiarylabel" -> ExtendedTheme.colorScheme.tertiaryLabel
117
+ "link" -> ExtendedTheme.colorScheme.link
118
+ else -> null
119
+ }
120
+ }
@@ -0,0 +1,47 @@
1
+ package expo.modules.myui.TypographySlot
2
+
3
+ internal data class SlotTextSpec(
4
+ val typography: String,
5
+ val fontSize: Float? = null,
6
+ val lineHeight: Float? = null,
7
+ val fontWeight: Int? = null,
8
+ val color: String? = null,
9
+ /** Valores de `@expo/ui` Text: `clip`, `ellipsis`, `visible`. */
10
+ val overflow: String? = null,
11
+ val maxLines: Int? = null,
12
+ /** Valores de `@expo/ui` Text: `left`, `right`, `center`, `justify`, `start`, `end`. */
13
+ val textAlign: String? = null,
14
+ )
15
+
16
+ /**
17
+ * Estilos por slot (minúsculas). Compartidos por [TypographySlotBridge] (Compose + JS).
18
+ */
19
+ internal object Typographies {
20
+
21
+ val specs: Map<String, SlotTextSpec> = mapOf(
22
+ "headlinecontent" to SlotTextSpec("bodyLarge", 17f, 22f, 400 /*, maxLines = 1*/, textAlign = "left"),
23
+ "trailingcontent" to SlotTextSpec("bodyLarge", 17f, 22f, 400 /*, , maxLines = 1*/, textAlign = "end", overflow = "ellipsis"),
24
+ "supportingcontent" to SlotTextSpec("bodyMedium", 15f, 20f, 400),
25
+ "leadingcontent" to SlotTextSpec("headlineSmall"),
26
+ "overlinecontent" to SlotTextSpec("labelMedium"),
27
+
28
+ "title" to SlotTextSpec("bodyLarge", 17f, 22f, 600, "secondaryLabel"),
29
+ "header" to SlotTextSpec("bodyLarge", 17f, 22f, 600, "secondaryLabel"),
30
+ "footer" to SlotTextSpec("bodySmall", 13f, 16f, 400, "secondaryLabel"),
31
+ "footercount" to SlotTextSpec("bodyLarge", 17f, 22f, 500, "label", textAlign = "center"),
32
+
33
+ "icontitle" to SlotTextSpec("bodyLarge", 28f, 34f, 700, "label"),
34
+ "iconsubtitle" to SlotTextSpec("bodyLarge", 17f, 22f, 400, "secondaryLabel"),
35
+ "iconbutton" to SlotTextSpec("bodyLarge", 17f, 22f, 500, "label"),
36
+
37
+ "menuitemheadline" to SlotTextSpec("bodyLarge", 17f, 20f, 400),
38
+ "menuitemsupporting" to SlotTextSpec("bodyMedium", 13f, 18f, 400, "secondaryLabel"),
39
+ "menuitemtrailing" to SlotTextSpec("bodyMedium", 15f, 20f, 500, "secondaryLabel"),
40
+
41
+ "modalheader" to SlotTextSpec("bodyLarge", 17f, 22f, 600),
42
+
43
+ "titlealert" to SlotTextSpec("bodyLarge", 17f, 22f, 600),
44
+ "messagetalert" to SlotTextSpec("bodyLarge", 17f, 22f, 400),
45
+
46
+ )
47
+ }
@@ -0,0 +1,43 @@
1
+ package expo.modules.myui.TypographySlot
2
+
3
+ import androidx.compose.material3.ProvideTextStyle
4
+ import androidx.compose.runtime.Composable
5
+ import expo.modules.kotlin.views.ComposeProps
6
+ import expo.modules.kotlin.views.FunctionalComposableScope
7
+
8
+ import expo.modules.myui.Children
9
+
10
+ /**
11
+ * [slotName] debe coincidir con los strings de slot de ListItem en Compose / `@expo/ui`
12
+ * (p. ej. `headlineContent`, `trailingContent`), no con las claves TS (`HeadlineContent`).
13
+ */
14
+ data class TypographySlotProps(
15
+ val slotName: String = "",
16
+ /** Si es false, solo se delega a [content] sin envolver en [ProvideTextStyle]. */
17
+ val applyTypography: Boolean = true,
18
+ ) : ComposeProps
19
+
20
+ /**
21
+ * Aplica la tipografía del slot al [content] composable.
22
+ * Compartido por [TypographySlotContent] y [expo.modules.myui.ListItem.ListItemDynamic].
23
+ */
24
+ @Composable
25
+ internal fun SlotTypography(
26
+ slotName: String,
27
+ applyTypography: Boolean = true,
28
+ content: @Composable () -> Unit,
29
+ ) {
30
+ val style = TypographySlotBridge.textStyleForSlot(slotName)
31
+ if (applyTypography && style != null) {
32
+ ProvideTextStyle(style, content = content)
33
+ } else {
34
+ content()
35
+ }
36
+ }
37
+
38
+ @Composable
39
+ internal fun FunctionalComposableScope.TypographySlotContent(props: TypographySlotProps) {
40
+ SlotTypography(props.slotName, props.applyTypography) {
41
+ Children()
42
+ }
43
+ }
@@ -0,0 +1,19 @@
1
+ package expo.modules.myui
2
+
3
+ import androidx.compose.runtime.Composable
4
+ import expo.modules.kotlin.views.ComposeProps
5
+ import expo.modules.kotlin.views.FunctionalComposableScope
6
+
7
+ import expo.modules.myui.theme.ExtendedTheme
8
+
9
+ /** Props para `View("ExtendedTheme")` — constructor con defaults (Expo Modules). */
10
+ data class ExtendedThemeProps(
11
+ private val unused: Boolean = false,
12
+ ) : ComposeProps
13
+
14
+ @Composable
15
+ internal fun FunctionalComposableScope.ExtendedThemeViewContent(props: ExtendedThemeProps) {
16
+ ExtendedTheme {
17
+ Children()
18
+ }
19
+ }
@@ -0,0 +1,77 @@
1
+ package expo.modules.myui.theme.colors
2
+
3
+
4
+ // Agregar esto al MyUiModule.kt
5
+
6
+ /**
7
+ Function("getExtendedColor") { name: String, scheme: String ->
8
+ val context =
9
+ appContext.reactContext
10
+ ?: throw IllegalStateException("React context is not available")
11
+ ExtendedColorBridge.extendedColorHex(name, scheme, context)
12
+ }
13
+ */
14
+
15
+
16
+
17
+ import android.content.Context
18
+ import android.content.res.Configuration
19
+ import androidx.compose.ui.graphics.Color
20
+ import androidx.compose.ui.graphics.toArgb
21
+ import java.util.Locale
22
+ import kotlin.reflect.KProperty1
23
+ import kotlin.reflect.full.memberProperties
24
+
25
+ import expo.modules.myui.theme.colors.ExtendedColorScheme
26
+ import expo.modules.myui.theme.colors.extendedDark
27
+ import expo.modules.myui.theme.colors.extendedLight
28
+
29
+
30
+ /**
31
+ * Resuelve light/dark como Expo Router: si [scheme] no es "light" ni "dark",
32
+ * usa el UI mode del [context] (p. ej. cuando JS manda "unspecified").
33
+ *
34
+ * Los tokens de color se derivan de [ExtendedColorScheme]: cada propiedad `Color`
35
+ * queda expuesta como clave en minúsculas (`BLUE` → `"blue"`, `SECONDARY_LABEL` → `"secondary_label"`).
36
+ */
37
+ internal object ExtendedColorBridge {
38
+
39
+ private val colorAccessors: Map<String, (ExtendedColorScheme) -> Color> by lazy {
40
+ ExtendedColorScheme::class.memberProperties.mapNotNull { prop ->
41
+ val getter = prop as? KProperty1<ExtendedColorScheme, *> ?: return@mapNotNull null
42
+ if (getter.returnType.classifier != Color::class) return@mapNotNull null
43
+ prop.name.lowercase(Locale.US) to { scheme: ExtendedColorScheme ->
44
+ getter.get(scheme) as Color
45
+ }
46
+ }.toMap()
47
+ }
48
+
49
+ fun resolveScheme(scheme: String, context: Context): String {
50
+ if (scheme == "dark" || scheme == "light") {
51
+ return scheme
52
+ }
53
+ val flags = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
54
+ return when (flags) {
55
+ Configuration.UI_MODE_NIGHT_YES -> "dark"
56
+ else -> "light"
57
+ }
58
+ }
59
+
60
+ /**
61
+ * HEX #RRGGBB para un token de [ExtendedColorScheme].
62
+ * [name]: case-insensitive; debe coincidir con el nombre de la propiedad en minúsculas.
63
+ * Devuelve null si el token no existe.
64
+ */
65
+ fun extendedColorHex(name: String, scheme: String, context: Context): String? {
66
+ val resolved = resolveScheme(scheme, context)
67
+ val palette: ExtendedColorScheme =
68
+ if (resolved == "dark") extendedDark else extendedLight
69
+ val color = pickColor(palette, name.lowercase(Locale.US)) ?: return null
70
+ return String.format(Locale.US, "#%06X", 0xFFFFFF and color.toArgb())
71
+ }
72
+
73
+ private fun pickColor(scheme: ExtendedColorScheme, key: String): Color? {
74
+ val accessor = colorAccessors[key.lowercase(Locale.US)] ?: return null
75
+ return accessor(scheme)
76
+ }
77
+ }