Skip to content
This repository has been archived by the owner on Jun 24, 2021. It is now read-only.

Add capability of showing a different highlight color per highlight #70

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions Demo/SelectableText.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import memoize from 'fast-memoize'
const RNSelectableText = requireNativeComponent('RNSelectableText')

/**
* numbers: array({start: int, end: int, id: string})
* numbers: array({start: int, end: int, id: string, highlightColor: string})
*/
const combineHighlights = memoize(numbers => {
return numbers
Expand All @@ -19,6 +19,7 @@ const combineHighlights = memoize(numbers => {
start: prev.start,
end: Math.max(prev.end, next.end),
id: next.id,
highlightColor: prev.highlightColor
})
}
return combined
Expand All @@ -27,7 +28,7 @@ const combineHighlights = memoize(numbers => {

/**
* value: string
* highlights: array({start: int, end: int, id: any})
* highlights: array({start: int, end: int, id: any, highlightColor: string})
*/
const mapHighlightsRanges = (value, highlights) => {
const combinedHighlights = combineHighlights(highlights)
Expand All @@ -36,23 +37,26 @@ const mapHighlightsRanges = (value, highlights) => {

const data = [{ isHighlight: false, text: value.slice(0, combinedHighlights[0].start) }]

combinedHighlights.forEach(({ start, end }, idx) => {
combinedHighlights.forEach(({ start, end, highlightColor }, idx) => {
data.push({
isHighlight: true,
text: value.slice(start, end),
highlightColor: highlightColor,
})

if (combinedHighlights[idx + 1]) {
data.push({
isHighlight: false,
text: value.slice(end, combinedHighlights[idx + 1].start),
highlightColor: '',
})
}
})

data.push({
isHighlight: false,
text: value.slice(combinedHighlights[combinedHighlights.length - 1].end, value.length),
highlightColor: '',
})

return data.filter(x => x.text)
Expand Down Expand Up @@ -106,14 +110,14 @@ export const SelectableText = ({
if (usesTextComponent) {
textValue = (
props.highlights && props.highlights.length > 0
? mapHighlightsRanges(value, props.highlights).map(({ id, isHighlight, text }) => (
? mapHighlightsRanges(value, props.highlights).map(({ id, isHighlight, text, highlightColor }) => (
<Text
key={v4()}
selectable
style={
isHighlight
? {
backgroundColor: props.highlightColor,
backgroundColor: highlightColor != '' ? highlightColor : props.highlightColor,
}
: {}
}
Expand Down
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { SelectableText } from "@astrocoders/react-native-selectable-text";
// Use normally, it is a drop-in replacement for react-native/Text
<SelectableText
menuItems={["Foo", "Bar"]}
/*
/*
Called when the user taps in a item of the selection menu:
- eventType: (string) is the label
- content: (string) the selected text portion
Expand Down Expand Up @@ -77,11 +77,10 @@ import { SelectableText } from "@astrocoders/react-native-selectable-text";
| **onSelection** | Called when the user taps in a item of the selection menu | ({ eventType: string, content: string, selectionStart: int, selectionEnd: int }) => void | () => {} |
| **menuItems** | context menu items | array(string) | [] |
| **style** | additional styles to be applied to text | Object | null |
| **highlights** | array of text ranges that should be highlighted with an optional id | array({ id: string, start: int, end: int }) | [] |
| **highlightColor** | highlight color |string | null |
| **highlightColor** | global highlight color |string | null |
| **highlights** | array of text ranges that should be highlighted with an optional id and a optional highlightColor that overrides the global one | array({ id: string, start: int, end: int, highlightColor: string }) | [] |
| **onHighlightPress** | called when the user taps the highlight |(id: string) => void | () => {} |
| **appendToChildren** | element to be added in the last line of text | ReactNode | null |
| **TextComponent** | Text component used to render `value` | ReactNode | <Text> |
| **textValueProp** | text value prop for TextComponent. Should be used when passing TextComponent. Defaults to 'children' which works for <Text> | string | 'children' |
| **textComponentProps** | additional props to pass to TextComponent | object | null |

2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface SelectableTextProps {
}) => void;

menuItems?: string[];
highlights?: Array<{ id: string; start: number; end: number }>;
highlights?: Array<{ id: string; start: number; end: number; highlightColor: string }>;
highlightColor?: string;
style?: StyleProp<TextStyle>;
onHighlightPress?: (id: string) => void;
Expand Down