@react-navigation/native 8.0.0-alpha.50 → 8.0.0-alpha.51

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 (65) hide show
  1. package/android/build.gradle +93 -21
  2. package/android/src/main/java/org/reactnavigation/MaterialSymbolModule.kt +20 -6
  3. package/android/src/main/java/org/reactnavigation/MaterialSymbolTypeface.kt +84 -29
  4. package/android/src/main/java/org/reactnavigation/MaterialSymbolView.kt +18 -18
  5. package/android/src/main/java/org/reactnavigation/MaterialSymbolViewManager.kt +11 -0
  6. package/ios/ReactNavigationSFSymbolView.mm +7 -0
  7. package/ios/ReactNavigationSFSymbolView.swift +6 -0
  8. package/lib/module/NavigationContainer.js.map +1 -1
  9. package/lib/module/native/MaterialSymbol.android.js +12 -4
  10. package/lib/module/native/MaterialSymbol.android.js.map +1 -1
  11. package/lib/module/native/MaterialSymbol.js +3 -0
  12. package/lib/module/native/MaterialSymbol.js.map +1 -1
  13. package/lib/module/native/MaterialSymbolViewNativeComponent.ts +1 -0
  14. package/lib/module/native/NativeMaterialSymbolModule.js.map +1 -1
  15. package/lib/module/useLinkProps.js +1 -1
  16. package/lib/typescript/src/NavigationContainer.d.ts +2 -1
  17. package/lib/typescript/src/NavigationContainer.d.ts.map +1 -1
  18. package/lib/typescript/src/native/MaterialSymbol.android.d.ts +4 -3
  19. package/lib/typescript/src/native/MaterialSymbol.android.d.ts.map +1 -1
  20. package/lib/typescript/src/native/MaterialSymbol.d.ts +3 -2
  21. package/lib/typescript/src/native/MaterialSymbol.d.ts.map +1 -1
  22. package/lib/typescript/src/native/MaterialSymbolData.d.ts +1 -1
  23. package/lib/typescript/src/native/MaterialSymbolData.d.ts.map +1 -1
  24. package/lib/typescript/src/native/MaterialSymbolViewNativeComponent.d.ts +1 -0
  25. package/lib/typescript/src/native/MaterialSymbolViewNativeComponent.d.ts.map +1 -1
  26. package/lib/typescript/src/native/NativeMaterialSymbolModule.d.ts +2 -1
  27. package/lib/typescript/src/native/NativeMaterialSymbolModule.d.ts.map +1 -1
  28. package/lib/typescript/src/native/types.d.ts +48 -7
  29. package/lib/typescript/src/native/types.d.ts.map +1 -1
  30. package/lib/typescript/src/types.d.ts +14 -0
  31. package/lib/typescript/src/types.d.ts.map +1 -1
  32. package/package.json +4 -4
  33. package/src/NavigationContainer.tsx +2 -1
  34. package/src/native/MaterialSymbol.android.tsx +20 -4
  35. package/src/native/MaterialSymbol.tsx +9 -2
  36. package/src/native/MaterialSymbolData.tsx +34 -373
  37. package/src/native/MaterialSymbolViewNativeComponent.ts +1 -0
  38. package/src/native/NativeMaterialSymbolModule.ts +4 -1
  39. package/src/native/types.tsx +51 -7
  40. package/src/types.tsx +15 -0
  41. package/src/useLinkProps.tsx +1 -1
  42. package/assets/fonts/MaterialSymbolsOutlined.codepoints +0 -4268
  43. package/assets/fonts/MaterialSymbolsOutlined_100.ttf +0 -0
  44. package/assets/fonts/MaterialSymbolsOutlined_200.ttf +0 -0
  45. package/assets/fonts/MaterialSymbolsOutlined_300.ttf +0 -0
  46. package/assets/fonts/MaterialSymbolsOutlined_400.ttf +0 -0
  47. package/assets/fonts/MaterialSymbolsOutlined_500.ttf +0 -0
  48. package/assets/fonts/MaterialSymbolsOutlined_600.ttf +0 -0
  49. package/assets/fonts/MaterialSymbolsOutlined_700.ttf +0 -0
  50. package/assets/fonts/MaterialSymbolsRounded.codepoints +0 -4268
  51. package/assets/fonts/MaterialSymbolsRounded_100.ttf +0 -0
  52. package/assets/fonts/MaterialSymbolsRounded_200.ttf +0 -0
  53. package/assets/fonts/MaterialSymbolsRounded_300.ttf +0 -0
  54. package/assets/fonts/MaterialSymbolsRounded_400.ttf +0 -0
  55. package/assets/fonts/MaterialSymbolsRounded_500.ttf +0 -0
  56. package/assets/fonts/MaterialSymbolsRounded_600.ttf +0 -0
  57. package/assets/fonts/MaterialSymbolsRounded_700.ttf +0 -0
  58. package/assets/fonts/MaterialSymbolsSharp.codepoints +0 -4268
  59. package/assets/fonts/MaterialSymbolsSharp_100.ttf +0 -0
  60. package/assets/fonts/MaterialSymbolsSharp_200.ttf +0 -0
  61. package/assets/fonts/MaterialSymbolsSharp_300.ttf +0 -0
  62. package/assets/fonts/MaterialSymbolsSharp_400.ttf +0 -0
  63. package/assets/fonts/MaterialSymbolsSharp_500.ttf +0 -0
  64. package/assets/fonts/MaterialSymbolsSharp_600.ttf +0 -0
  65. package/assets/fonts/MaterialSymbolsSharp_700.ttf +0 -0
@@ -1,3 +1,4 @@
1
+ import groovy.json.JsonOutput
1
2
  import groovy.json.JsonSlurper
2
3
 
3
4
  buildscript {
@@ -63,59 +64,130 @@ android {
63
64
 
64
65
  tasks.register('copyMaterialFonts', Copy) {
65
66
  def packageJsonFile = file(rootDir.path + "/../package.json")
67
+ def materialSymbolsConfig = null
66
68
  def fontsConfig = null
67
69
 
68
70
  if (packageJsonFile.exists()) {
69
71
  def packageJson = new JsonSlurper().parse(packageJsonFile)
70
72
 
71
- fontsConfig = packageJson["react-navigation"]?.get("material-symbols")?.get("fonts")
73
+ materialSymbolsConfig = packageJson["react-navigation"]?.get("material-symbols")
74
+ fontsConfig = materialSymbolsConfig?.get("fonts")
72
75
  }
73
76
 
74
- fontsConfig = fontsConfig != null ? fontsConfig : [[variant: "outlined", weights: [400]]]
77
+ def packageDir = projectDir.canonicalFile.parentFile
78
+ def materialSymbolsDir = [
79
+ new File(packageDir, "node_modules/@react-navigation/material-symbols"),
80
+ new File(packageDir.parentFile.parentFile, "@react-navigation/material-symbols")
81
+ ].find { it.exists() }
82
+
83
+ if (materialSymbolsDir == null) {
84
+ materialSymbolsDir = new File(
85
+ providers.exec {
86
+ workingDir(projectDir)
87
+ commandLine("node", "--print", "require.resolve('@react-navigation/material-symbols/package.json')")
88
+ }.standardOutput.asText.get().trim()
89
+ ).getParentFile()
90
+ }
75
91
 
76
- def assetsFontsDir = file("../assets/fonts")
92
+ def assetsFontsDir = new File(materialSymbolsDir, "assets/fonts")
77
93
  def availableFonts = assetsFontsDir.listFiles()
78
94
  ?.findAll { it.name.startsWith("MaterialSymbols") && it.name.endsWith(".ttf") }
79
95
  ?.collect { it.name.replaceFirst(/^MaterialSymbols/, '').replaceFirst(/\.ttf$/, '') } ?: []
80
96
 
81
- def validVariants = availableFonts.collect { it.split('_')[0].toLowerCase() }.unique().sort()
97
+ if (!availableFonts && materialSymbolsConfig != null) {
98
+ throw new GradleException(
99
+ "Found \"react-navigation\" > \"material-symbols\" in package.json, but no fonts are available in \"@react-navigation/material-symbols\" at ${JsonOutput.toJson(materialSymbolsDir.path)}.\n\n" +
100
+ "If \"@react-navigation/material-symbols\" is overridden with an empty version, remove the override to use Material Symbols, or remove \"react-navigation\" > \"material-symbols\" from package.json."
101
+ )
102
+ }
103
+
104
+ def validVariants = availableFonts.collect { it.split('_')[0].uncapitalize() }.unique().sort()
82
105
  def validWeights = availableFonts.collect { it.split('_')[1] as int }.unique().sort()
106
+ def validFills = availableFonts.collect { it.endsWith("_Filled") ? 1 : 0 }.unique().sort()
83
107
 
84
108
  def errors = [] as Set
85
109
 
86
- fontsConfig.each { font ->
87
- if (font.variant && !validVariants.contains(font.variant.toLowerCase())) {
88
- errors << "Invalid font variant: ${font.variant}"
110
+ if (fontsConfig != null && !(fontsConfig instanceof List)) {
111
+ errors << "Invalid fonts ${JsonOutput.toJson(fontsConfig)}. Expected an array."
112
+ }
113
+
114
+ def fonts = []
115
+
116
+ if (availableFonts) {
117
+ fonts = fontsConfig instanceof List ? fontsConfig : [[:]]
118
+ }
119
+
120
+ fonts.each { font ->
121
+ if (!(font instanceof Map)) {
122
+ errors << "Invalid font ${JsonOutput.toJson(font)}. Expected an object."
123
+
124
+ return
89
125
  }
90
126
 
91
- font.weights.each { weight ->
92
- if (!validWeights.contains(weight)) {
93
- errors << "Invalid font weight: ${weight}"
127
+ (font.keySet() - ["variant", "weights", "fills"]).each { key ->
128
+ errors << "Unknown key ${JsonOutput.toJson(key)}."
129
+ }
130
+
131
+ if (font.variant != null && !validVariants.contains(font.variant)) {
132
+ errors << "Invalid variant ${JsonOutput.toJson(font.variant)}."
133
+ }
134
+
135
+ if (font.weights != null && !(font.weights instanceof List)) {
136
+ errors << "Invalid weights ${JsonOutput.toJson(font.weights)}. Expected an array."
137
+ } else {
138
+ font.weights.each { weight ->
139
+ if (!validWeights.contains(weight)) {
140
+ errors << "Invalid weight ${JsonOutput.toJson(weight)}."
141
+ }
142
+ }
143
+ }
144
+
145
+ if (font.fills != null && !(font.fills instanceof List)) {
146
+ errors << "Invalid fills ${JsonOutput.toJson(font.fills)}. Expected an array."
147
+ } else {
148
+ font.fills.each { fill ->
149
+ if (!validFills.contains(fill)) {
150
+ errors << "Invalid fill ${JsonOutput.toJson(fill)}."
151
+ }
94
152
  }
95
153
  }
96
154
  }
97
155
 
98
156
  if (errors) {
99
157
  throw new GradleException(
100
- errors.join("\n") + "\n\nAvailable variants: ${validVariants.join(", ")}.\nAvailable weights: ${validWeights.join(", ")}."
158
+ "Invalid Material Symbols fonts in \"react-navigation\" > \"material-symbols\" > \"fonts\" in package.json.\n\n" +
159
+ errors.join("\n") + "\n\n" +
160
+ "Available variants: ${validVariants.collect { JsonOutput.toJson(it) }.join(", ")}.\n" +
161
+ "Available weights: ${validWeights.join(", ")}.\n" +
162
+ "Available fills: ${validFills.join(", ")}."
101
163
  )
102
164
  }
103
165
 
104
- def fontFiles = fontsConfig.collectMany { font ->
105
- def variant = font.variant?.capitalize() ?: ""
166
+ def fontFiles = fonts.collectMany { font ->
167
+ def variant = (font.variant ?: "outlined").capitalize()
168
+ def weights = font.weights ?: [400]
169
+ def fills = font.fills ?: [0]
170
+
171
+ weights.collectMany { weight ->
172
+ fills.collect { fill ->
173
+ def suffix = fill == 1 ? "_Filled" : ""
106
174
 
107
- font.weights.collect { weight -> "MaterialSymbols${variant}_${weight}.ttf" }
175
+ "MaterialSymbols${variant}_${weight}${suffix}.ttf"
176
+ }
177
+ }
108
178
  }
109
179
 
110
- if (fontFiles) {
111
- from(assetsFontsDir) { include fontFiles }
180
+ def assetFiles = fontFiles ? fontFiles + "MaterialSymbols.codepoints" + "MaterialSymbols.mirrored" : []
181
+
182
+ if (assetFiles) {
183
+ from(assetsFontsDir) { include assetFiles }
112
184
  }
113
185
 
114
186
  into layout.buildDirectory.dir("intermediates/react-navigation/fonts")
115
187
 
116
188
  doFirst {
117
189
  if (destinationDir.exists()) {
118
- def extraFiles = destinationDir.listFiles()?.findAll { file -> !fontFiles.contains(file.name) }
190
+ def extraFiles = destinationDir.listFiles()?.findAll { file -> !assetFiles.contains(file.name) }
119
191
 
120
192
  extraFiles?.each { file -> file.delete() }
121
193
  }
@@ -124,11 +196,11 @@ tasks.register('copyMaterialFonts', Copy) {
124
196
  doLast {
125
197
  def digest = java.security.MessageDigest.getInstance("MD5")
126
198
 
127
- fontFiles.sort().each { name ->
128
- def fontFile = new File(assetsFontsDir, name)
199
+ assetFiles.sort().each { name ->
200
+ def assetFile = new File(assetsFontsDir, name)
129
201
 
130
- if (fontFile.exists()) {
131
- digest.update(fontFile.bytes)
202
+ if (assetFile.exists()) {
203
+ digest.update(assetFile.bytes)
132
204
  }
133
205
  }
134
206
 
@@ -34,8 +34,12 @@ class MaterialSymbolModule(reactContext: ReactApplicationContext) :
34
34
  .trim()
35
35
  }
36
36
 
37
+ override fun isAvailable(): Boolean {
38
+ return MaterialSymbolTypeface.isAvailable(reactApplicationContext)
39
+ }
40
+
37
41
  override fun getImageSource(
38
- name: String, variant: String?, weight: Double?, size: Double, color: ReadableMap
42
+ name: String, variant: String?, weight: Double?, fill: Boolean?, size: Double, color: ReadableMap, direction: String
39
43
  ): String {
40
44
  val colorValue = color.getDynamic("value").let {
41
45
  when (it.type) {
@@ -47,13 +51,13 @@ class MaterialSymbolModule(reactContext: ReactApplicationContext) :
47
51
 
48
52
  val resolvedColor = ColorPropConverter.getColor(
49
53
  colorValue, reactApplicationContext.currentActivity ?: reactApplicationContext
50
- ) ?: throw IllegalArgumentException("Could not resolve color")
54
+ ) ?: throw IllegalArgumentException("Invalid color value $colorValue for Material Symbol \"$name\".")
51
55
 
52
56
  val density = reactApplicationContext.resources.displayMetrics.density
53
57
  val scaledSize = (size * density).roundToInt().coerceAtLeast(1)
54
58
 
55
59
  val typefaceSuffix = MaterialSymbolTypeface.getSuffix(
56
- reactApplicationContext, variant, weight?.toInt()
60
+ reactApplicationContext, variant, weight?.toInt(), fill
57
61
  )
58
62
 
59
63
  val cacheDir = File(
@@ -61,8 +65,11 @@ class MaterialSymbolModule(reactContext: ReactApplicationContext) :
61
65
  "react_navigation/material_symbols/$typefaceSuffix/$fontHash"
62
66
  )
63
67
 
68
+ val mirrored =
69
+ direction == "rtl" && MaterialSymbolTypeface.isAutoMirrored(reactApplicationContext, name)
70
+
64
71
  val cacheFile = File(
65
- cacheDir, "${Uri.encode(name)}_${scaledSize}_$resolvedColor.png"
72
+ cacheDir, "${Uri.encode(name)}_${scaledSize}_$resolvedColor${if (mirrored) "_rtl" else ""}.png"
66
73
  )
67
74
 
68
75
  val cacheUri = cacheFile.toUri().toString()
@@ -71,6 +78,9 @@ class MaterialSymbolModule(reactContext: ReactApplicationContext) :
71
78
  return cacheUri
72
79
  }
73
80
 
81
+ val symbol = MaterialSymbolTypeface.getSymbol(reactApplicationContext, name)
82
+ ?: throw IllegalArgumentException("No Material Symbol found with the name \"$name\".")
83
+
74
84
  val cacheParent = cacheDir.parentFile
75
85
 
76
86
  if (cacheParent != null && cleanedCacheDirs.add(cacheParent.absolutePath)) {
@@ -83,7 +93,7 @@ class MaterialSymbolModule(reactContext: ReactApplicationContext) :
83
93
  cacheDir.mkdirs()
84
94
 
85
95
  val resolvedTypeface = MaterialSymbolTypeface.get(
86
- reactApplicationContext, variant, weight?.toInt()
96
+ reactApplicationContext, variant, weight?.toInt(), fill
87
97
  ).typeface
88
98
 
89
99
  val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
@@ -101,7 +111,11 @@ class MaterialSymbolModule(reactContext: ReactApplicationContext) :
101
111
  val canvas = Canvas(bitmap)
102
112
  val y = (scaledSize - (fontMetrics.descent - fontMetrics.ascent)) / 2f - fontMetrics.ascent
103
113
 
104
- canvas.drawText(name, scaledSize / 2f, y, paint)
114
+ if (mirrored) {
115
+ canvas.scale(-1f, 1f, scaledSize / 2f, scaledSize / 2f)
116
+ }
117
+
118
+ canvas.drawText(symbol, scaledSize / 2f, y, paint)
105
119
 
106
120
  FileOutputStream(cacheFile).use {
107
121
  bitmap.compress(Bitmap.CompressFormat.PNG, 100, it)
@@ -7,11 +7,31 @@ import java.util.concurrent.ConcurrentHashMap
7
7
  data class MaterialSymbolTypefaceResult(val typeface: Typeface, val suffix: String)
8
8
 
9
9
  object MaterialSymbolTypeface {
10
+ private const val CONFIG_HINT =
11
+ "Configure the fonts in \"react-navigation\" > \"material-symbols\" > \"fonts\" in package.json and rebuild the app."
12
+
10
13
  private val typefaces = ConcurrentHashMap<String, Typeface>()
11
- private var availableFonts: Map<String, Set<Int>>? = null
14
+ private var availableFonts: Map<String, Map<Int, Set<Boolean>>>? = null
15
+ private var symbols: Map<String, String>? = null
16
+ private var autoMirroredSymbols: Set<String>? = null
17
+
18
+ fun isAvailable(context: Context): Boolean {
19
+ return getAvailableFonts(context).isNotEmpty()
20
+ }
21
+
22
+ fun isAutoMirrored(context: Context, name: String): Boolean {
23
+ autoMirroredSymbols?.let { return it.contains(name) }
24
+
25
+ val result = context.assets.open("fonts/MaterialSymbols.mirrored").bufferedReader()
26
+ .useLines { lines -> lines.toSet() }
27
+
28
+ autoMirroredSymbols = result
29
+
30
+ return result.contains(name)
31
+ }
12
32
 
13
- fun get(context: Context, variant: String?, weight: Int?): MaterialSymbolTypefaceResult {
14
- val suffix = getSuffix(context, variant, weight)
33
+ fun get(context: Context, variant: String?, weight: Int?, fill: Boolean?): MaterialSymbolTypefaceResult {
34
+ val suffix = getSuffix(context, variant, weight, fill)
15
35
 
16
36
  val typeface = typefaces.getOrPut(suffix) {
17
37
  val path = "fonts/MaterialSymbols${suffix}.ttf"
@@ -19,49 +39,88 @@ object MaterialSymbolTypeface {
19
39
  try {
20
40
  Typeface.createFromAsset(context.assets, path)
21
41
  } catch (e: Exception) {
22
- throw RuntimeException("$path not found.", e)
42
+ throw RuntimeException("Failed to load the Material Symbols font \"$path\".", e)
23
43
  }
24
44
  }
25
45
 
26
46
  return MaterialSymbolTypefaceResult(typeface, suffix)
27
47
  }
28
48
 
29
- fun getSuffix(context: Context, variant: String?, weight: Int?): String {
49
+ fun getSymbol(context: Context, name: String): String? {
50
+ symbols?.let { return it[name] }
51
+
52
+ val result = context.assets.open("fonts/MaterialSymbols.codepoints").bufferedReader()
53
+ .useLines { lines ->
54
+ lines.associate { line ->
55
+ val (key, codepoint) = line.split(" ")
56
+
57
+ key to String(Character.toChars(codepoint.toInt(16)))
58
+ }
59
+ }
60
+
61
+ symbols = result
62
+
63
+ return result[name]
64
+ }
65
+
66
+ fun getSuffix(context: Context, variant: String?, weight: Int?, fill: Boolean?): String {
30
67
  val fonts = getAvailableFonts(context)
31
68
 
69
+ if (fonts.isEmpty()) {
70
+ throw RuntimeException("No Material Symbols fonts found. $CONFIG_HINT")
71
+ }
72
+
32
73
  val resolvedVariant = if (variant != null) {
33
74
  when (variant) {
75
+ "outlined" -> "Outlined"
34
76
  "rounded" -> "Rounded"
35
77
  "sharp" -> "Sharp"
36
- else -> "Outlined"
78
+ else -> throw IllegalArgumentException(
79
+ "Invalid Material Symbols variant \"$variant\". Expected \"outlined\", \"rounded\" or \"sharp\"."
80
+ )
37
81
  }
38
82
  } else {
39
83
  resolveDefaultVariant(fonts)
40
84
  }
41
85
 
42
- val resolvedWeight = weight ?: resolveDefaultWeight(fonts, resolvedVariant)
86
+ val variantName = "\"${resolvedVariant.lowercase()}\""
87
+
88
+ val weights = fonts[resolvedVariant]
89
+ ?: throw RuntimeException("No Material Symbols font found for variant $variantName. $CONFIG_HINT")
90
+
91
+ val resolvedWeight = weight ?: resolveDefaultWeight(weights, resolvedVariant)
92
+
93
+ val fills = weights[resolvedWeight]
94
+ ?: throw RuntimeException(
95
+ "No Material Symbols font found for variant $variantName and weight $resolvedWeight. $CONFIG_HINT"
96
+ )
97
+
98
+ val resolvedFill = fill ?: fills.singleOrNull() ?: false
43
99
 
44
- return "${resolvedVariant}_$resolvedWeight"
100
+ if (!fills.contains(resolvedFill)) {
101
+ throw RuntimeException(
102
+ "No Material Symbols font found for variant $variantName, weight $resolvedWeight and fill ${if (resolvedFill) 1 else 0}. $CONFIG_HINT"
103
+ )
104
+ }
105
+
106
+ return "${resolvedVariant}_$resolvedWeight" + if (resolvedFill) "_Filled" else ""
45
107
  }
46
108
 
47
- private fun getAvailableFonts(context: Context): Map<String, Set<Int>> {
109
+ private fun getAvailableFonts(context: Context): Map<String, Map<Int, Set<Boolean>>> {
48
110
  availableFonts?.let { return it }
49
111
 
50
112
  val files = context.assets.list("fonts")
51
113
  ?.filter { it.startsWith("MaterialSymbols") && it.endsWith(".ttf") } ?: emptyList()
52
114
 
53
- if (files.isEmpty()) {
54
- throw RuntimeException("No MaterialSymbols font found in assets.")
55
- }
56
-
57
- val fonts = mutableMapOf<String, MutableSet<Int>>()
115
+ val fonts = mutableMapOf<String, MutableMap<Int, MutableSet<Boolean>>>()
58
116
 
59
117
  for (file in files) {
60
- val suffix = file.removePrefix("MaterialSymbols").removeSuffix(".ttf")
61
- val variant = suffix.substringBefore("_")
62
- val weight = suffix.substringAfter("_").toIntOrNull() ?: continue
118
+ val parts = file.removePrefix("MaterialSymbols").removeSuffix(".ttf").split("_")
119
+ val variant = parts[0]
120
+ val weight = parts.getOrNull(1)?.toIntOrNull() ?: continue
121
+ val fill = parts.getOrNull(2) == "Filled"
63
122
 
64
- fonts.getOrPut(variant) { mutableSetOf() }.add(weight)
123
+ fonts.getOrPut(variant) { mutableMapOf() }.getOrPut(weight) { mutableSetOf() }.add(fill)
65
124
  }
66
125
 
67
126
  availableFonts = fonts
@@ -69,7 +128,7 @@ object MaterialSymbolTypeface {
69
128
  return fonts
70
129
  }
71
130
 
72
- private fun resolveDefaultVariant(fonts: Map<String, Set<Int>>): String {
131
+ private fun resolveDefaultVariant(fonts: Map<String, Map<Int, Set<Boolean>>>): String {
73
132
  val variants = fonts.keys
74
133
 
75
134
  if (variants.size == 1) {
@@ -81,19 +140,14 @@ object MaterialSymbolTypeface {
81
140
  }
82
141
 
83
142
  throw RuntimeException(
84
- "Multiple MaterialSymbols variants found: ${variants.joinToString()}. " + "Please specify a variant explicitly."
143
+ "Multiple Material Symbols variants found: ${variants.joinToString { "\"${it.lowercase()}\"" }}. " +
144
+ "Specify the \"variant\" to use."
85
145
  )
86
146
  }
87
147
 
88
- private fun resolveDefaultWeight(fonts: Map<String, Set<Int>>, variant: String): Int {
89
- val weights = fonts[variant]
90
-
91
- if (weights.isNullOrEmpty()) {
92
- throw RuntimeException("No MaterialSymbols font found for variant: $variant")
93
- }
94
-
148
+ private fun resolveDefaultWeight(weights: Map<Int, Set<Boolean>>, variant: String): Int {
95
149
  if (weights.size == 1) {
96
- return weights.first()
150
+ return weights.keys.first()
97
151
  }
98
152
 
99
153
  if (weights.contains(400)) {
@@ -101,7 +155,8 @@ object MaterialSymbolTypeface {
101
155
  }
102
156
 
103
157
  throw RuntimeException(
104
- "Multiple MaterialSymbols weights found for variant $variant: ${weights.joinToString()}. " + "Please specify a weight explicitly."
158
+ "Multiple Material Symbols weights found for variant \"${variant.lowercase()}\": ${weights.keys.sorted().joinToString()}. " +
159
+ "Specify the \"weight\" to use."
105
160
  )
106
161
  }
107
162
  }
@@ -11,14 +11,16 @@ class MaterialSymbolView @JvmOverloads constructor(
11
11
 
12
12
  private var variant: String? = null
13
13
  private var weight: Int? = null
14
+ private var fill: Boolean? = null
15
+ private var symbol: String? = null
16
+ private var autoMirrored = false
14
17
 
15
18
  init {
16
19
  setColor(null)
17
- updateTypeface()
18
20
  }
19
21
 
20
22
  override fun onDraw(canvas: Canvas) {
21
- val text = text?.toString() ?: return
23
+ val symbol = symbol ?: return
22
24
 
23
25
  paint.color = currentTextColor
24
26
  paint.textAlign = Paint.Align.CENTER
@@ -27,41 +29,39 @@ class MaterialSymbolView @JvmOverloads constructor(
27
29
  val x = width / 2f
28
30
  val y = (height - (fontMetrics.descent - fontMetrics.ascent)) / 2f - fontMetrics.ascent
29
31
 
30
- canvas.drawText(text, x, y, paint)
32
+ if (autoMirrored && layoutDirection == LAYOUT_DIRECTION_RTL) {
33
+ canvas.scale(-1f, 1f, x, height / 2f)
34
+ }
35
+
36
+ canvas.drawText(symbol, x, y, paint)
31
37
  }
32
38
 
33
39
  fun setName(name: String?) {
34
- text = name
40
+ symbol = name?.let { MaterialSymbolTypeface.getSymbol(context, it) }
41
+ autoMirrored = name?.let { MaterialSymbolTypeface.isAutoMirrored(context, it) } ?: false
35
42
 
36
43
  invalidate()
37
44
  }
38
45
 
39
46
  fun setVariant(variant: String?) {
40
- if (this.variant == variant) {
41
- return
42
- }
43
-
44
47
  this.variant = variant
45
-
46
- updateTypeface()
47
48
  }
48
49
 
49
50
  fun setWeight(weight: Int?) {
50
- if (this.weight == weight) {
51
- return
52
- }
53
-
54
51
  this.weight = weight
52
+ }
55
53
 
56
- updateTypeface()
54
+ fun setFill(fill: Int) {
55
+ this.fill = if (fill == -1) null else fill == 1
57
56
  }
58
57
 
59
- private fun updateTypeface() {
58
+ fun updateTypeface() {
60
59
  setTypeface(
61
60
  MaterialSymbolTypeface.get(
62
61
  context,
63
62
  variant?.ifEmpty { null },
64
- weight.takeIf { it != 0 }).typeface
63
+ weight.takeIf { it != 0 },
64
+ fill).typeface
65
65
  )
66
66
 
67
67
  invalidate()
@@ -90,6 +90,6 @@ class MaterialSymbolView @JvmOverloads constructor(
90
90
  }
91
91
 
92
92
  fun setSize(size: Float) {
93
- textSize = size
93
+ setTextSize(android.util.TypedValue.COMPLEX_UNIT_DIP, size)
94
94
  }
95
95
  }
@@ -33,6 +33,11 @@ class MaterialSymbolViewManager : SimpleViewManager<MaterialSymbolView>(),
33
33
  view.setWeight(weight)
34
34
  }
35
35
 
36
+ @ReactProp(name = "fill")
37
+ override fun setFill(view: MaterialSymbolView, fill: Int) {
38
+ view.setFill(fill)
39
+ }
40
+
36
41
  @ReactProp(name = "size")
37
42
  override fun setSize(view: MaterialSymbolView, size: Float) {
38
43
  view.setSize(size)
@@ -43,6 +48,12 @@ class MaterialSymbolViewManager : SimpleViewManager<MaterialSymbolView>(),
43
48
  view.setColor(color)
44
49
  }
45
50
 
51
+ override fun onAfterUpdateTransaction(view: MaterialSymbolView) {
52
+ super.onAfterUpdateTransaction(view)
53
+
54
+ view.updateTypeface()
55
+ }
56
+
46
57
  companion object {
47
58
  const val NAME = "ReactNavigationMaterialSymbolView"
48
59
  }
@@ -37,6 +37,13 @@ using namespace facebook::react;
37
37
  return self;
38
38
  }
39
39
 
40
+ - (void)setSemanticContentAttribute:(UISemanticContentAttribute)semanticContentAttribute
41
+ {
42
+ [super setSemanticContentAttribute:semanticContentAttribute];
43
+
44
+ _view.semanticContentAttribute = semanticContentAttribute;
45
+ }
46
+
40
47
  static ReactNavigationSFSymbolViewImplProps *convertProps(const Props::Shared &props) {
41
48
  const auto &viewProps = *std::static_pointer_cast<ReactNavigationSFSymbolViewProps const>(props);
42
49
 
@@ -59,6 +59,12 @@ import UIKit
59
59
  fatalError("init(coder:) has not been implemented")
60
60
  }
61
61
 
62
+ override public var semanticContentAttribute: UISemanticContentAttribute {
63
+ didSet {
64
+ imageView.semanticContentAttribute = semanticContentAttribute
65
+ }
66
+ }
67
+
62
68
  @objc public func updateProps(_ props: ReactNavigationSFSymbolViewImplProps, oldProps: ReactNavigationSFSymbolViewImplProps) {
63
69
  let needsImageUpdate =
64
70
  props.name != oldProps.name ||
@@ -1 +1 @@
1
- {"version":3,"names":["BaseNavigationContainer","getActionFromState","getPathFromState","getStateFromPath","ThemeProvider","validatePathConfig","React","warnOnce","checkSerializable","DEFAULT_DIRECTION","IS_NATIVE","getStateBreadcrumb","LinkingContext","LocaleDirContext","LightTheme","useBackButton","useDocumentTitle","useLinking","useThenable","jsx","_jsx","globalThis","REACT_NAVIGATION_DEVTOOLS","WeakMap","RESTORE_STATE_ERROR","PARSE_STATE_ERROR","PERSIST_STATE_ERROR","STRINGIFY_STATE_ERROR","NavigationContainer","direction","theme","linking","persistor","fallback","documentTitle","onStateChange","ref","rest","refContainer","useRef","linkingConfig","useMemo","options","enabled","config","prefixes","getInitialState","useEffect","current","previous","get","listeners","Set","set","isLinkStateResolved","initialStateFromLink","initialState","undefined","isPersistenceSupported","isPersistedStateResolved","initialStateFromPersisted","parse","serializedState","JSON","e","console","error","result","restore","then","onPersistState","state","stringify","value","persist","onSerializableCheck","process","env","NODE_ENV","serializable","breadcrumb","location","message","reason","useImperativeHandle","isStateReady","Provider","children"],"sourceRoot":"../../src","sources":["NavigationContainer.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["BaseNavigationContainer","getActionFromState","getPathFromState","getStateFromPath","ThemeProvider","validatePathConfig","React","warnOnce","checkSerializable","DEFAULT_DIRECTION","IS_NATIVE","getStateBreadcrumb","LinkingContext","LocaleDirContext","LightTheme","useBackButton","useDocumentTitle","useLinking","useThenable","jsx","_jsx","globalThis","REACT_NAVIGATION_DEVTOOLS","WeakMap","RESTORE_STATE_ERROR","PARSE_STATE_ERROR","PERSIST_STATE_ERROR","STRINGIFY_STATE_ERROR","NavigationContainer","direction","theme","linking","persistor","fallback","documentTitle","onStateChange","ref","rest","refContainer","useRef","linkingConfig","useMemo","options","enabled","config","prefixes","getInitialState","useEffect","current","previous","get","listeners","Set","set","isLinkStateResolved","initialStateFromLink","initialState","undefined","isPersistenceSupported","isPersistedStateResolved","initialStateFromPersisted","parse","serializedState","JSON","e","console","error","result","restore","then","onPersistState","state","stringify","value","persist","onSerializableCheck","process","env","NODE_ENV","serializable","breadcrumb","location","message","reason","useImperativeHandle","isStateReady","Provider","children"],"sourceRoot":"../../src","sources":["NavigationContainer.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import { PixelRatio, processColor } from 'react-native';
4
+ import { DEFAULT_DIRECTION } from '../constants';
4
5
  import { FONT_WEIGHTS } from "./constants.js";
5
6
  import MaterialSymbolViewNativeComponent from './MaterialSymbolViewNativeComponent';
6
7
  import NativeMaterialSymbolModule from "./NativeMaterialSymbolModule.js";
@@ -9,6 +10,7 @@ export function MaterialSymbol({
9
10
  name,
10
11
  variant,
11
12
  weight,
13
+ fill,
12
14
  size = 24,
13
15
  color,
14
16
  style
@@ -17,6 +19,7 @@ export function MaterialSymbol({
17
19
  name: name,
18
20
  variant: variant,
19
21
  weight: typeof weight === 'string' ? FONT_WEIGHTS[weight] : weight ?? 0,
22
+ fill: fill == null ? -1 : fill ? 1 : 0,
20
23
  size: size,
21
24
  color: color,
22
25
  style: [{
@@ -25,20 +28,25 @@ export function MaterialSymbol({
25
28
  }, style]
26
29
  });
27
30
  }
31
+ MaterialSymbol.isAvailable = () => {
32
+ return NativeMaterialSymbolModule.isAvailable();
33
+ };
28
34
  MaterialSymbol.getImageSource = ({
29
35
  name,
30
36
  variant,
31
37
  weight,
38
+ fill,
32
39
  size = 24,
33
- color = 'black'
40
+ color = 'black',
41
+ direction = DEFAULT_DIRECTION
34
42
  }) => {
35
43
  const processedColor = processColor(color);
36
44
  if (processedColor == null) {
37
- throw new Error(`Invalid color value: ${String(color)}`);
45
+ throw new Error(`Invalid color value ${JSON.stringify(color)} for Material Symbol "${name}".`);
38
46
  }
39
- const uri = NativeMaterialSymbolModule.getImageSource(name, variant, typeof weight === 'string' ? FONT_WEIGHTS[weight] : weight, size, {
47
+ const uri = NativeMaterialSymbolModule.getImageSource(name, variant, typeof weight === 'string' ? FONT_WEIGHTS[weight] : weight, fill, size, {
40
48
  value: processedColor
41
- });
49
+ }, direction);
42
50
  const source = {
43
51
  uri,
44
52
  scale: PixelRatio.get(),
@@ -1 +1 @@
1
- {"version":3,"names":["PixelRatio","processColor","FONT_WEIGHTS","MaterialSymbolViewNativeComponent","NativeMaterialSymbolModule","jsx","_jsx","MaterialSymbol","name","variant","weight","size","color","style","width","height","getImageSource","processedColor","Error","String","uri","value","source","scale","get"],"sourceRoot":"../../../src","sources":["native/MaterialSymbol.android.tsx"],"mappings":";;AAAA,SAEEA,UAAU,EACVC,YAAY,QAEP,cAAc;AAErB,SAASC,YAAY,QAAQ,gBAAa;AAC1C,OAAOC,iCAAiC,MAAM,qCAAqC;AACnF,OAAOC,0BAA0B,MAAM,iCAA8B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAUtE,OAAO,SAASC,cAAcA,CAAC;EAC7BC,IAAI;EACJC,OAAO;EACPC,MAAM;EACNC,IAAI,GAAG,EAAE;EACTC,KAAK;EACLC;AACmB,CAAC,EAAsB;EAC1C,oBACEP,IAAA,CAACH,iCAAiC;IAChCK,IAAI,EAAEA,IAAK;IACXC,OAAO,EAAEA,OAAQ;IACjBC,MAAM,EAAE,OAAOA,MAAM,KAAK,QAAQ,GAAGR,YAAY,CAACQ,MAAM,CAAC,GAAIA,MAAM,IAAI,CAAG;IAC1EC,IAAI,EAAEA,IAAK;IACXC,KAAK,EAAEA,KAAM;IACbC,KAAK,EAAE,CACL;MACEC,KAAK,EAAEH,IAAI;MACXI,MAAM,EAAEJ;IACV,CAAC,EACDE,KAAK;EACL,CACH,CAAC;AAEN;AAEAN,cAAc,CAACS,cAAc,GAAG,CAAC;EAC/BR,IAAI;EACJC,OAAO;EACPC,MAAM;EACNC,IAAI,GAAG,EAAE;EACTC,KAAK,GAAG;AACa,CAAC,KAA0B;EAChD,MAAMK,cAAc,GAAGhB,YAAY,CAACW,KAAK,CAAC;EAE1C,IAAIK,cAAc,IAAI,IAAI,EAAE;IAC1B,MAAM,IAAIC,KAAK,CAAC,wBAAwBC,MAAM,CAACP,KAAK,CAAC,EAAE,CAAC;EAC1D;EAEA,MAAMQ,GAAG,GAAGhB,0BAA0B,CAACY,cAAc,CACnDR,IAAI,EACJC,OAAO,EACP,OAAOC,MAAM,KAAK,QAAQ,GAAGR,YAAY,CAACQ,MAAM,CAAC,GAAGA,MAAM,EAC1DC,IAAI,EACJ;IAAEU,KAAK,EAAEJ;EAAe,CAC1B,CAAC;EAED,MAAMK,MAA2B,GAAG;IAClCF,GAAG;IACHG,KAAK,EAAEvB,UAAU,CAACwB,GAAG,CAAC,CAAC;IACvBV,KAAK,EAAEH,IAAI;IACXI,MAAM,EAAEJ;EACV,CAAC;EAED,OAAOW,MAAM;AACf,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["PixelRatio","processColor","DEFAULT_DIRECTION","FONT_WEIGHTS","MaterialSymbolViewNativeComponent","NativeMaterialSymbolModule","jsx","_jsx","MaterialSymbol","name","variant","weight","fill","size","color","style","width","height","isAvailable","getImageSource","direction","processedColor","Error","JSON","stringify","uri","value","source","scale","get"],"sourceRoot":"../../../src","sources":["native/MaterialSymbol.android.tsx"],"mappings":";;AAAA,SAEEA,UAAU,EACVC,YAAY,QAEP,cAAc;AAErB,SAASC,iBAAiB,QAAQ,cAAc;AAChD,SAASC,YAAY,QAAQ,gBAAa;AAC1C,OAAOC,iCAAiC,MAAM,qCAAqC;AACnF,OAAOC,0BAA0B,MAAM,iCAA8B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAatE,OAAO,SAASC,cAAcA,CAAC;EAC7BC,IAAI;EACJC,OAAO;EACPC,MAAM;EACNC,IAAI;EACJC,IAAI,GAAG,EAAE;EACTC,KAAK;EACLC;AACmB,CAAC,EAAsB;EAC1C,oBACER,IAAA,CAACH,iCAAiC;IAChCK,IAAI,EAAEA,IAAK;IACXC,OAAO,EAAEA,OAAQ;IACjBC,MAAM,EAAE,OAAOA,MAAM,KAAK,QAAQ,GAAGR,YAAY,CAACQ,MAAM,CAAC,GAAIA,MAAM,IAAI,CAAG;IAC1EC,IAAI,EAAEA,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,GAAGA,IAAI,GAAG,CAAC,GAAG,CAAE;IACvCC,IAAI,EAAEA,IAAK;IACXC,KAAK,EAAEA,KAAM;IACbC,KAAK,EAAE,CACL;MACEC,KAAK,EAAEH,IAAI;MACXI,MAAM,EAAEJ;IACV,CAAC,EACDE,KAAK;EACL,CACH,CAAC;AAEN;AAEAP,cAAc,CAACU,WAAW,GAAG,MAAe;EAC1C,OAAOb,0BAA0B,CAACa,WAAW,CAAC,CAAC;AACjD,CAAC;AAEDV,cAAc,CAACW,cAAc,GAAG,CAAC;EAC/BV,IAAI;EACJC,OAAO;EACPC,MAAM;EACNC,IAAI;EACJC,IAAI,GAAG,EAAE;EACTC,KAAK,GAAG,OAAO;EACfM,SAAS,GAAGlB;AACoB,CAAC,KAA0B;EAC3D,MAAMmB,cAAc,GAAGpB,YAAY,CAACa,KAAK,CAAC;EAE1C,IAAIO,cAAc,IAAI,IAAI,EAAE;IAC1B,MAAM,IAAIC,KAAK,CACb,uBAAuBC,IAAI,CAACC,SAAS,CAACV,KAAK,CAAC,yBAAyBL,IAAI,IAC3E,CAAC;EACH;EAEA,MAAMgB,GAAG,GAAGpB,0BAA0B,CAACc,cAAc,CACnDV,IAAI,EACJC,OAAO,EACP,OAAOC,MAAM,KAAK,QAAQ,GAAGR,YAAY,CAACQ,MAAM,CAAC,GAAGA,MAAM,EAC1DC,IAAI,EACJC,IAAI,EACJ;IAAEa,KAAK,EAAEL;EAAe,CAAC,EACzBD,SACF,CAAC;EAED,MAAMO,MAA2B,GAAG;IAClCF,GAAG;IACHG,KAAK,EAAE5B,UAAU,CAAC6B,GAAG,CAAC,CAAC;IACvBb,KAAK,EAAEH,IAAI;IACXI,MAAM,EAAEJ;EACV,CAAC;EAED,OAAOc,MAAM;AACf,CAAC","ignoreList":[]}