react-native-advanced-text 0.1.44 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,8 +13,25 @@ Pod::Spec.new do |s|
13
13
  s.platforms = { :ios => min_ios_version_supported }
14
14
  s.source = { :git => "https://github.com/AminAllahham/react-native-advanced-text.git", :tag => "#{s.version}" }
15
15
 
16
- s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
16
+ # `common/cpp` holds the self-measuring Fabric ShadowNode. Its
17
+ # ShadowNodes.h intentionally shadows the codegen output, so `common/cpp`
18
+ # must come first on the header search path (see below).
19
+ s.source_files = "ios/**/*.{h,m,mm,swift,cpp}", "common/cpp/**/*.{h,cpp}"
17
20
  s.private_header_files = "ios/**/*.h"
18
21
 
19
22
  install_modules_dependencies(s)
23
+
24
+ # `install_modules_dependencies` sets `s.pod_target_xcconfig`; extend it
25
+ # (rather than replace it) so our headers win over the generated ones and
26
+ # so `React-FabricComponents` headers (TextLayoutManager) resolve.
27
+ xcconfig = s.attributes_hash["pod_target_xcconfig"] || {}
28
+ existing_header_paths = xcconfig["HEADER_SEARCH_PATHS"] || "$(inherited)"
29
+ xcconfig["HEADER_SEARCH_PATHS"] =
30
+ "\"$(PODS_TARGET_SRCROOT)/common/cpp\" #{existing_header_paths}"
31
+ xcconfig["CLANG_CXX_LANGUAGE_STANDARD"] ||= "c++20"
32
+ s.pod_target_xcconfig = xcconfig
33
+
34
+ # Needed for <react/renderer/textlayoutmanager/TextLayoutManager.h>, which is
35
+ # not pulled in by `install_modules_dependencies`.
36
+ s.dependency "React-FabricComponents"
20
37
  end
package/README.md CHANGED
@@ -9,6 +9,7 @@
9
9
  npm install react-native-advanced-text
10
10
  ```
11
11
 
12
+ > Requires the New Architecture (Fabric). React Native 0.80+ recommended.
12
13
 
13
14
  ## Usage
14
15
 
@@ -18,7 +19,7 @@ import { AdvancedText } from "react-native-advanced-text";
18
19
 
19
20
  <AdvancedText
20
21
  text={'This is an example of AdvancedText component. Tap on any word to see the event in action.'}
21
- style={[styles.AdvancedText, { minHeight }]}
22
+ style={styles.AdvancedText}
22
23
  onWordPress={(event) => {
23
24
  console.log({event})
24
25
  }}
@@ -42,9 +43,39 @@ import { AdvancedText } from "react-native-advanced-text";
42
43
  color={'#FFFFFF'}
43
44
  fontWeight="normal"
44
45
  fontFamily={'monospace'}
46
+ letterSpacing={1}
45
47
  />
46
48
  ```
47
49
 
50
+ ## Sizing
51
+
52
+ `AdvancedText` measures its own height, like React Native's built‑in `<Text>`.
53
+ Give it a width (via `style`, `flex`, or a constraining parent) and it derives
54
+ its height from the text content and that width — **no explicit `height` is
55
+ required**.
56
+
57
+ Under the hood the Fabric ShadowNode implements `measureContent()` using React
58
+ Native's own `TextLayoutManager` (the same engine `<Text>` uses), so wrapping,
59
+ font metrics, `letterSpacing` and `lineHeight` are accounted for on both iOS and
60
+ Android without any JS‑side text measurement.
61
+
62
+ ```jsx
63
+ // Before: an explicit height had to be estimated and passed in.
64
+ <AdvancedText text={text} style={{ height: estimatedHeight }} />
65
+
66
+ // Now:
67
+ <AdvancedText text={text} style={{ width: '100%' }} />
68
+ ```
69
+
70
+ ### Props that affect measurement
71
+
72
+ | Prop | Notes |
73
+ | --------------- | ------------------------------------------------------------------- |
74
+ | `fontSize` | points (defaults to 16) |
75
+ | `fontFamily` | |
76
+ | `fontWeight` | `"bold"` or `"italic"` |
77
+ | `letterSpacing` | points; applied to both rendering and measurement |
78
+ | `lineHeight` | multiple of the font size (unchanged behavior) |
48
79
 
49
80
  ## Contributing
50
81
 
@@ -0,0 +1,51 @@
1
+ # Custom CMake build for react-native-advanced-text.
2
+ #
3
+ # This replaces the auto-generated
4
+ # build/generated/source/codegen/jni/CMakeLists.txt
5
+ # (referenced from react-native.config.js via `cmakeListsPath`) so that the
6
+ # Fabric component is backed by our self-measuring ShadowNode
7
+ # (common/cpp/react/renderer/components/AdvancedTextViewSpec/ShadowNodes.{h,cpp})
8
+ # instead of the plain, non-measuring one that codegen emits.
9
+ #
10
+ # It still produces the target name the app autolinking expects:
11
+ # react_codegen_AdvancedTextViewSpec
12
+ #
13
+ # The key detail is include order: `common/cpp` is listed BEFORE the codegen
14
+ # output dir, so `#include <react/renderer/components/AdvancedTextViewSpec/ShadowNodes.h>`
15
+ # resolves to our version, while Props.h / EventEmitters.h / States.h still
16
+ # resolve to the generated ones.
17
+
18
+ cmake_minimum_required(VERSION 3.13)
19
+ set(CMAKE_VERBOSE_MAKEFILE ON)
20
+
21
+ set(CODEGEN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/build/generated/source/codegen/jni")
22
+ set(COMMON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../common/cpp")
23
+
24
+ file(GLOB codegen_SRCS CONFIGURE_DEPENDS
25
+ "${CODEGEN_DIR}/*.cpp"
26
+ "${CODEGEN_DIR}/react/renderer/components/AdvancedTextViewSpec/*.cpp")
27
+
28
+ file(GLOB custom_SRCS CONFIGURE_DEPENDS
29
+ "${COMMON_DIR}/react/renderer/components/AdvancedTextViewSpec/*.cpp")
30
+
31
+ add_library(
32
+ react_codegen_AdvancedTextViewSpec
33
+ OBJECT
34
+ ${codegen_SRCS}
35
+ ${custom_SRCS}
36
+ )
37
+
38
+ # `common/cpp` MUST come first so our ShadowNodes.h shadows the generated one.
39
+ target_include_directories(react_codegen_AdvancedTextViewSpec PUBLIC
40
+ "${COMMON_DIR}"
41
+ "${CODEGEN_DIR}"
42
+ "${CODEGEN_DIR}/react/renderer/components/AdvancedTextViewSpec")
43
+
44
+ target_link_libraries(
45
+ react_codegen_AdvancedTextViewSpec
46
+ fbjni
47
+ jsi
48
+ reactnative
49
+ )
50
+
51
+ target_compile_reactnative_options(react_codegen_AdvancedTextViewSpec PRIVATE)
@@ -41,6 +41,8 @@ class AdvancedTextView : TextView {
41
41
  private var textAlign: String = "left"
42
42
  private var fontFamily: String = "sans-serif"
43
43
  private var lineHeightMultiplier: Float = 1.0f
44
+ // Value from JS, in dp/points (0 = unset). Converted to em for TextView.
45
+ private var letterSpacingDp: Float = 0f
44
46
 
45
47
  private var indicatorWordIndex: Int = -1
46
48
  private var indicatorColor: String = ""
@@ -56,7 +58,10 @@ class AdvancedTextView : TextView {
56
58
  Log.d(TAG, "AdvancedTextView initialized")
57
59
 
58
60
  textSize = 16f
59
- setPadding(16, 16, 16, 16)
61
+ // Zero intrinsic padding so the rendered text matches the size reported
62
+ // by the Fabric ShadowNode's measureContent(). Consumers add padding via
63
+ // React Native `style` instead, exactly like <Text>.
64
+ setPadding(0, 0, 0, 0)
60
65
  setTextIsSelectable(true)
61
66
 
62
67
  movementMethod = SmartMovementMethod
@@ -148,6 +153,12 @@ class AdvancedTextView : TextView {
148
153
  updateTextWithHighlights()
149
154
  }
150
155
 
156
+ fun setAdvancedLetterSpacing(spacingDp: Float) {
157
+ if (letterSpacingDp == spacingDp) return
158
+ letterSpacingDp = spacingDp
159
+ updateTextWithHighlights()
160
+ }
161
+
151
162
 
152
163
  fun setAdvancedFontFamily(family: String) {
153
164
  if (fontFamily == family) return
@@ -268,6 +279,14 @@ class AdvancedTextView : TextView {
268
279
 
269
280
  setLineSpacing(0f, lineHeightMultiplier)
270
281
 
282
+ // Android's letterSpacing is in em; the prop is in dp/points. The ratio
283
+ // dp / fontSize is scale-invariant, so no density conversion is needed.
284
+ letterSpacing = if (letterSpacingDp != 0f && fontSize > 0f) {
285
+ letterSpacingDp / fontSize
286
+ } else {
287
+ 0f
288
+ }
289
+
271
290
 
272
291
  post {
273
292
  setText(spannableString, BufferType.SPANNABLE)
@@ -152,6 +152,12 @@ class AdvancedTextViewManager : SimpleViewManager<AdvancedTextView>() {
152
152
  }
153
153
  }
154
154
 
155
+ @ReactProp(name = "letterSpacing")
156
+ fun setLetterSpacing(view: AdvancedTextView?, letterSpacing: Float) {
157
+ android.util.Log.d(NAME, "setLetterSpacing called with: $letterSpacing")
158
+ view?.setAdvancedLetterSpacing(letterSpacing)
159
+ }
160
+
155
161
  override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> {
156
162
  return mapOf(
157
163
  "onWordPress" to mapOf("registrationName" to "onWordPress"),
@@ -0,0 +1,120 @@
1
+ /*
2
+ * Implementation of the self-measuring <AdvancedTextView> ShadowNode.
3
+ * See ShadowNodes.h for why this file shadows the codegen output.
4
+ *
5
+ * NOTE: this file deliberately does NOT define `AdvancedTextViewComponentName`.
6
+ * That symbol stays owned by the codegen-generated `ShadowNodes.cpp`, which is
7
+ * still compiled (via the podspec on iOS and via CMakeLists.txt on Android).
8
+ */
9
+
10
+ #include <react/renderer/components/AdvancedTextViewSpec/ShadowNodes.h>
11
+
12
+ #include <algorithm>
13
+ #include <cctype>
14
+ #include <string>
15
+
16
+ #include <react/renderer/attributedstring/AttributedStringBox.h>
17
+ #include <react/renderer/attributedstring/ParagraphAttributes.h>
18
+ #include <react/renderer/attributedstring/TextAttributes.h>
19
+ #include <react/renderer/attributedstring/primitives.h>
20
+ #include <react/renderer/mounting/ShadowView.h>
21
+ #include <react/renderer/textlayoutmanager/TextLayoutContext.h>
22
+ #include <react/renderer/textlayoutmanager/TextLayoutManager.h>
23
+
24
+ namespace facebook::react {
25
+
26
+ namespace {
27
+
28
+ std::string toLowerAscii(std::string value) {
29
+ std::transform(value.begin(), value.end(), value.begin(), [](unsigned char c) {
30
+ return static_cast<char>(std::tolower(c));
31
+ });
32
+ return value;
33
+ }
34
+
35
+ } // namespace
36
+
37
+ AdvancedTextViewShadowNode::AdvancedTextViewShadowNode(
38
+ const ShadowNode& sourceShadowNode,
39
+ const ShadowNodeFragment& fragment)
40
+ : ConcreteViewShadowNode(sourceShadowNode, fragment),
41
+ textLayoutManager_(
42
+ static_cast<const AdvancedTextViewShadowNode&>(sourceShadowNode)
43
+ .textLayoutManager_) {}
44
+
45
+ AttributedString AdvancedTextViewShadowNode::getAttributedString() const {
46
+ const auto& props = getConcreteProps();
47
+
48
+ auto textAttributes = TextAttributes::defaultTextAttributes();
49
+
50
+ // Font size: matches the 16pt fallback used by the native views.
51
+ textAttributes.fontSize =
52
+ props.fontSize > 0 ? static_cast<Float>(props.fontSize) : 16.0;
53
+
54
+ if (!props.fontFamily.empty()) {
55
+ textAttributes.fontFamily = props.fontFamily;
56
+ }
57
+
58
+ // The native views treat `fontWeight` as either a weight ("bold") or a
59
+ // style ("italic"); mirror that here so wrapping metrics line up.
60
+ const auto weight = toLowerAscii(props.fontWeight);
61
+ if (weight == "bold") {
62
+ textAttributes.fontWeight = FontWeight::Bold;
63
+ } else if (weight == "italic") {
64
+ textAttributes.fontStyle = FontStyle::Italic;
65
+ }
66
+
67
+ if (props.letterSpacing != 0) {
68
+ textAttributes.letterSpacing = props.letterSpacing;
69
+ }
70
+
71
+ if (props.lineHeight > 0) {
72
+ // The component treats `lineHeight` as a multiple of the font size
73
+ // (see AdvancedTextView.mm / AdvancedTextView.kt). `TextAttributes`
74
+ // expects an absolute value; approximate the platform default single
75
+ // line height as 1.2 * fontSize.
76
+ textAttributes.lineHeight =
77
+ props.lineHeight * textAttributes.fontSize * 1.2;
78
+ }
79
+
80
+ auto attributedString = AttributedString{};
81
+ attributedString.appendFragment(AttributedString::Fragment{
82
+ .string = props.text,
83
+ .textAttributes = textAttributes,
84
+ .parentShadowView = ShadowView(*this),
85
+ });
86
+ return attributedString;
87
+ }
88
+
89
+ Size AdvancedTextViewShadowNode::measureContent(
90
+ const LayoutContext& layoutContext,
91
+ const LayoutConstraints& layoutConstraints) const {
92
+ const auto& props = getConcreteProps();
93
+
94
+ if (props.text.empty()) {
95
+ return layoutConstraints.clamp({0, 0});
96
+ }
97
+
98
+ if (!textLayoutManager_) {
99
+ textLayoutManager_ =
100
+ std::make_shared<const TextLayoutManager>(getContextContainer());
101
+ }
102
+
103
+ auto paragraphAttributes = ParagraphAttributes{};
104
+ paragraphAttributes.maximumNumberOfLines = 0; // unlimited -> natural wrapping
105
+ paragraphAttributes.adjustsFontSizeToFit = false;
106
+
107
+ auto textLayoutContext = TextLayoutContext{};
108
+ textLayoutContext.pointScaleFactor = layoutContext.pointScaleFactor;
109
+ textLayoutContext.surfaceId = getSurfaceId();
110
+
111
+ auto measurement = textLayoutManager_->measure(
112
+ AttributedStringBox{getAttributedString()},
113
+ paragraphAttributes,
114
+ textLayoutContext,
115
+ layoutConstraints);
116
+
117
+ return layoutConstraints.clamp(measurement.size);
118
+ }
119
+
120
+ } // namespace facebook::react
@@ -0,0 +1,95 @@
1
+ /*
2
+ * Custom, self-measuring ShadowNode for <AdvancedTextView>.
3
+ *
4
+ * This file intentionally *shadows* the file generated by react-native-codegen
5
+ * at:
6
+ * build/generated/source/codegen/jni/react/renderer/components/AdvancedTextViewSpec/ShadowNodes.h (Android)
7
+ * <codegen>/react/renderer/components/AdvancedTextViewSpec/ShadowNodes.h (iOS)
8
+ *
9
+ * The generated version defines `AdvancedTextViewShadowNode` as a plain
10
+ * `ConcreteViewShadowNode` alias, which has no Yoga measure function. That is
11
+ * why <AdvancedText> renders nothing unless an explicit `height` is provided.
12
+ *
13
+ * This version replaces the alias with a real class that opts into Yoga
14
+ * measurement (`LeafYogaNode | MeasurableYogaNode`) and implements
15
+ * `measureContent()` using React Native's own `TextLayoutManager` -- the exact
16
+ * engine <Text> uses -- so the component derives its height from its text and
17
+ * the available width, just like <Text>.
18
+ *
19
+ * The generated `ComponentDescriptors.h` (`using AdvancedTextViewComponentDescriptor
20
+ * = ConcreteComponentDescriptor<AdvancedTextViewShadowNode>`) therefore wraps
21
+ * this class automatically; no other wiring change is required on either
22
+ * platform. The `AdvancedTextViewComponentName` symbol is still defined by the
23
+ * generated `ShadowNodes.cpp`.
24
+ *
25
+ * For this shadowing to take effect, `common/cpp` must appear on the include
26
+ * path *before* the codegen output directory:
27
+ * - Android: handled by `android/CMakeLists.txt` (see `target_include_directories`)
28
+ * - iOS: handled by `AdvancedText.podspec` (HEADER_SEARCH_PATHS)
29
+ */
30
+
31
+ #pragma once
32
+
33
+ #include <memory>
34
+
35
+ #include <jsi/jsi.h>
36
+ #include <react/renderer/attributedstring/AttributedString.h>
37
+ #include <react/renderer/components/AdvancedTextViewSpec/EventEmitters.h>
38
+ #include <react/renderer/components/AdvancedTextViewSpec/Props.h>
39
+ #include <react/renderer/components/AdvancedTextViewSpec/States.h>
40
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
41
+ #include <react/renderer/core/LayoutConstraints.h>
42
+ #include <react/renderer/core/LayoutContext.h>
43
+ #include <react/renderer/core/ShadowNode.h>
44
+ #include <react/renderer/core/ShadowNodeFragment.h>
45
+
46
+ namespace facebook::react {
47
+
48
+ class TextLayoutManager;
49
+
50
+ // Defined by the codegen-generated ShadowNodes.cpp.
51
+ JSI_EXPORT extern const char AdvancedTextViewComponentName[];
52
+
53
+ /*
54
+ * `ShadowNode` for <AdvancedTextView> component.
55
+ */
56
+ class AdvancedTextViewShadowNode final : public ConcreteViewShadowNode<
57
+ AdvancedTextViewComponentName,
58
+ AdvancedTextViewProps,
59
+ AdvancedTextViewEventEmitter,
60
+ AdvancedTextViewState> {
61
+ public:
62
+ // "create" constructor: (fragment, family, traits)
63
+ using ConcreteViewShadowNode::ConcreteViewShadowNode;
64
+
65
+ // "clone" constructor: carry the resolved TextLayoutManager across clones.
66
+ AdvancedTextViewShadowNode(
67
+ const ShadowNode& sourceShadowNode,
68
+ const ShadowNodeFragment& fragment);
69
+
70
+ static ShadowNodeTraits BaseTraits() {
71
+ auto traits = ConcreteViewShadowNode::BaseTraits();
72
+ // Opt into Yoga measurement. `MeasurableYogaNode` requires `LeafYogaNode`.
73
+ traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
74
+ traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
75
+ return traits;
76
+ }
77
+
78
+ #pragma mark - LayoutableShadowNode
79
+
80
+ Size measureContent(
81
+ const LayoutContext& layoutContext,
82
+ const LayoutConstraints& layoutConstraints) const override;
83
+
84
+ private:
85
+ /*
86
+ * Builds a single-fragment `AttributedString` from the component props
87
+ * (text + font attributes), mirroring how the native views render it.
88
+ */
89
+ AttributedString getAttributedString() const;
90
+
91
+ // Lazily created on first measure, then reused / copied across clones.
92
+ mutable std::shared_ptr<const TextLayoutManager> textLayoutManager_;
93
+ };
94
+
95
+ } // namespace facebook::react
@@ -23,6 +23,7 @@ using namespace facebook::react;
23
23
  @property (nonatomic, strong) NSString *textAlign;
24
24
  @property (nonatomic, strong) NSString *fontFamily;
25
25
  @property (nonatomic, assign) CGFloat lineHeight;
26
+ @property (nonatomic, assign) CGFloat letterSpacing;
26
27
  @property (nonatomic, assign) NSInteger indicatorWordIndex;
27
28
  @property (nonatomic, strong) UIColor *indicatorColor;
28
29
  @property (nonatomic, strong) NSString *indicatorMode;
@@ -99,6 +100,7 @@ using namespace facebook::react;
99
100
  _textAlign = @"left";
100
101
  _fontFamily = @"System";
101
102
  _lineHeight = 0.0;
103
+ _letterSpacing = 0.0;
102
104
  _indicatorWordIndex = -1;
103
105
  _indicatorColor = nil;
104
106
  _indicatorMode = @"Highlight";
@@ -124,9 +126,17 @@ using namespace facebook::react;
124
126
  _textView.parentView = self;
125
127
  _textView.editable = NO;
126
128
  _textView.selectable = YES;
127
- _textView.scrollEnabled = YES;
129
+ // The Fabric ShadowNode now measures the intrinsic content height, so the
130
+ // native view is always laid out tall enough to fit its text. Disable
131
+ // scrolling so the component behaves like <Text> (content grows / clips
132
+ // rather than scrolls).
133
+ _textView.scrollEnabled = NO;
128
134
  _textView.backgroundColor = [UIColor clearColor];
129
- _textView.textContainerInset = UIEdgeInsetsMake(8, 8, 8, 8);
135
+ // Zero all intrinsic padding so the rendered text box matches the size
136
+ // reported by the ShadowNode's measureContent(). Consumers add padding
137
+ // via React Native `style` instead, exactly like <Text>.
138
+ _textView.textContainerInset = UIEdgeInsetsZero;
139
+ _textView.textContainer.lineFragmentPadding = 0;
130
140
  _textView.font = [UIFont systemFontOfSize:16];
131
141
  _textView.textColor = [UIColor labelColor];
132
142
  _textView.delegate = self;
@@ -236,6 +246,12 @@ using namespace facebook::react;
236
246
  styleChanged = YES;
237
247
  }
238
248
 
249
+ if (oldViewProps.letterSpacing != newViewProps.letterSpacing) {
250
+ NSLog(@"[AdvancedTextView] Updating letterSpacing to: %f", newViewProps.letterSpacing);
251
+ _letterSpacing = static_cast<CGFloat>(newViewProps.letterSpacing);
252
+ styleChanged = YES;
253
+ }
254
+
239
255
  BOOL indicatorChanged = NO;
240
256
 
241
257
  if (oldViewProps.indicatorMode != newViewProps.indicatorMode) {
@@ -466,6 +482,12 @@ using namespace facebook::react;
466
482
  value:font
467
483
  range:NSMakeRange(0, attributedString.length)];
468
484
 
485
+ if (_letterSpacing != 0.0) {
486
+ [attributedString addAttribute:NSKernAttributeName
487
+ value:@(_letterSpacing)
488
+ range:NSMakeRange(0, attributedString.length)];
489
+ }
490
+
469
491
 
470
492
  UIColor *color = _textColor ?: [UIColor labelColor];
471
493
  [attributedString addAttribute:NSForegroundColorAttributeName
@@ -22,6 +22,7 @@ export interface NativeProps extends ViewProps {
22
22
  textAlign?: string;
23
23
  fontFamily?: string;
24
24
  lineHeight?: Float;
25
+ letterSpacing?: Float;
25
26
  indicatorWordIndex?: Int32;
26
27
  indicatorColor?: string;
27
28
  indicatorMode?: string;
@@ -23,6 +23,7 @@ export interface NativeProps extends ViewProps {
23
23
  textAlign?: string;
24
24
  fontFamily?: string;
25
25
  lineHeight?: Float;
26
+ letterSpacing?: Float;
26
27
  indicatorWordIndex?: Int32;
27
28
  indicatorColor?: string;
28
29
  indicatorMode?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"AdvancedTextViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/AdvancedTextViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAG,KAAK,EAAG,MAAM,2CAA2C,CAAC;AAEpG,UAAU,eAAe;IACvB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAClD,WAAW,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,kBAAkB,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,kBAAkB,CAAC,EAAE,KAAK,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;;AAED,wBAAuE"}
1
+ {"version":3,"file":"AdvancedTextViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/AdvancedTextViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAG,KAAK,EAAG,MAAM,2CAA2C,CAAC;AAEpG,UAAU,eAAe;IACvB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAClD,WAAW,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,kBAAkB,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,CAAC;IACtB,kBAAkB,CAAC,EAAE,KAAK,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;;AAED,wBAAuE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-advanced-text",
3
- "version": "0.1.44",
3
+ "version": "0.2.0",
4
4
  "description": " Advanced text component for React Native with custom select options.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -18,6 +18,7 @@
18
18
  "android",
19
19
  "ios",
20
20
  "cpp",
21
+ "common",
21
22
  "*.podspec",
22
23
  "react-native.config.js",
23
24
  "!ios/build",
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Autolinking config for react-native-advanced-text.
3
+ *
4
+ * On Android we ship a custom C++ ShadowNode (see android/CMakeLists.txt and
5
+ * common/cpp/...) so the Fabric component measures its own height from its text
6
+ * and the available width. Pointing `cmakeListsPath` at our own CMakeLists.txt
7
+ * makes the app build that instead of the plain codegen output.
8
+ *
9
+ * `libraryName` (AdvancedTextViewSpec) and `componentDescriptors`
10
+ * (AdvancedTextViewComponentDescriptor) are still auto-derived by the CLI from
11
+ * package.json `codegenConfig` and the JS spec, so they are intentionally not
12
+ * listed here.
13
+ */
14
+ module.exports = {
15
+ dependency: {
16
+ platforms: {
17
+ android: {
18
+ cmakeListsPath: 'CMakeLists.txt',
19
+ },
20
+ },
21
+ },
22
+ };
@@ -22,6 +22,7 @@ export interface NativeProps extends ViewProps {
22
22
  textAlign?: string;
23
23
  fontFamily?: string;
24
24
  lineHeight?: Float;
25
+ letterSpacing?: Float;
25
26
  indicatorWordIndex?: Int32;
26
27
  indicatorColor?: string;
27
28
  indicatorMode?: string;