Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement text direction support #475

Open
wants to merge 2 commits 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ The `MentionsInput` supports the following props for configuring the widget:
| inputRef | React ref | undefined | Accepts a React ref to forward to the underlying input element |
| allowSuggestionsAboveCursor | boolean | false | Renders the SuggestionList above the cursor if there is not enough space below |
| a11ySuggestionsListLabel | string | `''` | This label would be exposed to screen readers when suggestion popup appears |
| _unstableAutoDirection | boolean | false | Enables automatic text direction for both RTL and LTR text per paragraph, experimental |

Each data source is configured using a `Mention` component, which has the following props:

Expand Down
41 changes: 41 additions & 0 deletions demo/src/examples/AutoDirection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react'

import { Mention, MentionsInput } from '../../../src'

import { provideExampleValue } from './higher-order'

import defaultStyle from './defaultStyle'
import defaultMentionStyle from './defaultMentionStyle'

function AutoDirection({ value, data, onChange, onAdd }) {
return (
<div className="multiple-triggers">
<h3>Auto direction</h3>

<MentionsInput
value={value}
onChange={onChange}
style={defaultStyle}
placeholder={"Mention people using '@'"}
dir="auto"
a11ySuggestionsListLabel={"Suggested mentions"}
_unstableAutoDirection
>
<Mention
markup="@[__display__](__id__)"
displayTransform={(username, displayname) => `@${displayname || username}`}
trigger="@"
data={data}
onAdd={onAdd}
style={defaultMentionStyle}
/>
</MentionsInput>
</div>
)
}

const asExample = provideExampleValue(
"Hi @[John Doe](johndoe), \nסעיף א. כל בני אדם נולדו בני חורין ושווים בערכם ובזכויותיהם. כולם חוננו בתבונה ובמצפון, לפיכך @[John Doe](johndoe) חובה עליהם לנהוג איש ברעהו ברוח של אחוה."
)

export default asExample(AutoDirection)
2 changes: 2 additions & 0 deletions demo/src/examples/Examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SingleLine from './SingleLine'
import SingleLineIgnoringAccents from './SingleLineIgnoringAccents'
import SuggestionPortal from './SuggestionPortal'
import BottomGuard from './BottomGuard'
import AutoDirection from './AutoDirection'

const users = [
{
Expand Down Expand Up @@ -63,6 +64,7 @@ export default function Examples() {
<Emojis data={users} />
<SuggestionPortal data={users} />
<BottomGuard data={users} />
<AutoDirection data={users} />
</div>
</StylesViaJss>
)
Expand Down
52 changes: 41 additions & 11 deletions src/Highlighter.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,12 @@ class Highlighter extends Component {
this.props.onCaretPositionChange(newPosition)
}

render() {
const {
selectionStart,
selectionEnd,
value,
style,
children,
containerRef,
} = this.props
const config = readConfigFromChildren(children)

renderLine({
value,
selectionStart,
selectionEnd,
config
}) {
// If there's a caret (i.e. no range selection), map the caret position into the marked up value
let caretPositionInMarkup
if (selectionStart === selectionEnd) {
Expand Down Expand Up @@ -162,6 +157,41 @@ class Highlighter extends Component {
// if a caret component is to be rendered, add all components that followed as its children
resultComponents.push(this.renderHighlighterCaret(components))
}
return resultComponents
}

render() {
const {
selectionStart,
selectionEnd,
value,
style,
children,
containerRef,
_unstableAutoDirection,
} = this.props
const config = readConfigFromChildren(children)

let resultComponents
// If auto direction is used split by \n and iterate over each line separately
if (_unstableAutoDirection) {
const lines = value.split('\n')
resultComponents = lines.map((value, index) => (
<div key={index} dir="auto">{this.renderLine({
value,
selectionStart,
selectionEnd,
config
})}</div>
))
} else {
resultComponents =this.renderLine({
value,
selectionStart,
selectionEnd,
config
})
}

return (
<div {...style} ref={containerRef}>
Expand Down
3 changes: 2 additions & 1 deletion src/MentionsInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ class MentionsInput extends React.Component {

renderHighlighter = () => {
const { selectionStart, selectionEnd } = this.state
const { singleLine, children, value, style } = this.props
const { singleLine, children, value, style, _unstableAutoDirection } = this.props

return (
<Highlighter
Expand All @@ -308,6 +308,7 @@ class MentionsInput extends React.Component {
selectionStart={selectionStart}
selectionEnd={selectionEnd}
onCaretPositionChange={this.handleCaretPositionChange}
_unstableAutoDirection={_unstableAutoDirection}
>
{children}
</Highlighter>
Expand Down