@pie-lib/text-select 1.32.1 → 1.33.0-mui-update.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.
- package/CHANGELOG.md +13 -12
- package/lib/index.js +1 -12
- package/lib/index.js.map +1 -1
- package/lib/legend.js +87 -91
- package/lib/legend.js.map +1 -1
- package/lib/text-select.js +18 -51
- package/lib/text-select.js.map +1 -1
- package/lib/token-select/index.js +77 -129
- package/lib/token-select/index.js.map +1 -1
- package/lib/token-select/token.js +160 -189
- package/lib/token-select/token.js.map +1 -1
- package/lib/tokenizer/builder.js +23 -68
- package/lib/tokenizer/builder.js.map +1 -1
- package/lib/tokenizer/controls.js +50 -81
- package/lib/tokenizer/controls.js.map +1 -1
- package/lib/tokenizer/index.js +37 -84
- package/lib/tokenizer/index.js.map +1 -1
- package/lib/tokenizer/selection-utils.js +2 -12
- package/lib/tokenizer/selection-utils.js.map +1 -1
- package/lib/tokenizer/token-text.js +45 -78
- package/lib/tokenizer/token-text.js.map +1 -1
- package/lib/utils.js +8 -24
- package/lib/utils.js.map +1 -1
- package/package.json +13 -12
- package/src/legend.js +76 -67
- package/src/token-select/index.jsx +63 -66
- package/src/token-select/token.jsx +131 -122
- package/src/tokenizer/controls.jsx +40 -42
- package/src/tokenizer/index.jsx +17 -15
- package/src/tokenizer/token-text.jsx +12 -10
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
|
-
import Check from '@
|
|
6
|
-
import Close from '@
|
|
5
|
+
import Check from '@mui/icons-material/Check';
|
|
6
|
+
import Close from '@mui/icons-material/Close';
|
|
7
7
|
|
|
8
8
|
import { color } from '@pie-lib/render-ui';
|
|
9
9
|
|
|
@@ -13,22 +13,114 @@ const LINE_HEIGHT_MULTIPLIER = 3.2;
|
|
|
13
13
|
const CORRECTNESS_LINE_HEIGHT_MULTIPLIER = 3.4;
|
|
14
14
|
const CORRECTNESS_PADDING = 2;
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Styled components for different token states
|
|
17
|
+
const StyledToken = styled('span')(({ theme }) => ({
|
|
18
|
+
cursor: 'pointer',
|
|
19
|
+
textIndent: 0,
|
|
20
|
+
'&.disabled': {
|
|
21
|
+
cursor: 'inherit',
|
|
22
|
+
color: color.disabled(),
|
|
23
|
+
},
|
|
24
|
+
'&.disabledBlack': {
|
|
25
|
+
cursor: 'inherit',
|
|
26
|
+
},
|
|
27
|
+
'&.disabledAndSelected': {
|
|
28
|
+
backgroundColor: color.blueGrey100(),
|
|
29
|
+
},
|
|
30
|
+
[`@media (min-width: ${theme.breakpoints.values.md}px)`]: {
|
|
31
|
+
'&.selectable:hover': {
|
|
32
|
+
backgroundColor: color.blueGrey300(),
|
|
33
|
+
color: theme.palette.common.black,
|
|
34
|
+
'& > *': {
|
|
35
|
+
backgroundColor: color.blueGrey300(),
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
'&.selected': {
|
|
40
|
+
backgroundColor: color.blueGrey100(),
|
|
41
|
+
color: theme.palette.common.black,
|
|
42
|
+
lineHeight: `${theme.spacing(1) * LINE_HEIGHT_MULTIPLIER}px`,
|
|
43
|
+
border: `solid 2px ${color.blueGrey900()}`,
|
|
44
|
+
borderRadius: '4px',
|
|
45
|
+
'& > *': {
|
|
46
|
+
backgroundColor: color.blueGrey100(),
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
'&.highlight': {
|
|
50
|
+
border: `dashed 2px ${color.blueGrey600()}`,
|
|
51
|
+
borderRadius: '4px',
|
|
52
|
+
lineHeight: `${theme.spacing(1) * LINE_HEIGHT_MULTIPLIER}px`,
|
|
53
|
+
},
|
|
54
|
+
'&.print': {
|
|
55
|
+
border: `dashed 2px ${color.blueGrey600()}`,
|
|
56
|
+
borderRadius: '4px',
|
|
57
|
+
lineHeight: `${theme.spacing(1) * LINE_HEIGHT_MULTIPLIER}px`,
|
|
58
|
+
color: color.text(),
|
|
59
|
+
},
|
|
60
|
+
'&.custom': {
|
|
61
|
+
display: 'initial',
|
|
62
|
+
},
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
const StyledCommonTokenStyle = styled('span')(({ theme }) => ({
|
|
66
|
+
position: 'relative',
|
|
67
|
+
borderRadius: '4px',
|
|
68
|
+
color: theme.palette.common.black,
|
|
69
|
+
lineHeight: `${theme.spacing(1) * CORRECTNESS_LINE_HEIGHT_MULTIPLIER + CORRECTNESS_PADDING}px`,
|
|
70
|
+
padding: `${CORRECTNESS_PADDING}px`,
|
|
71
|
+
}));
|
|
72
|
+
|
|
73
|
+
const StyledCorrectContainer = styled(StyledCommonTokenStyle)(() => ({
|
|
74
|
+
border: `${color.correctTertiary()} solid 2px`,
|
|
75
|
+
}));
|
|
76
|
+
|
|
77
|
+
const StyledIncorrectContainer = styled(StyledCommonTokenStyle)(() => ({
|
|
78
|
+
border: `${color.incorrectWithIcon()} solid 2px`,
|
|
79
|
+
}));
|
|
80
|
+
|
|
81
|
+
const StyledMissingContainer = styled(StyledCommonTokenStyle)(() => ({
|
|
82
|
+
border: `${color.incorrectWithIcon()} dashed 2px`,
|
|
83
|
+
}));
|
|
84
|
+
|
|
85
|
+
const StyledCorrectnessIcon = styled('span')(() => ({
|
|
86
|
+
color: color.white(),
|
|
87
|
+
position: 'absolute',
|
|
88
|
+
top: '-8px',
|
|
89
|
+
left: '-8px',
|
|
90
|
+
borderRadius: '50%',
|
|
91
|
+
fontSize: '12px',
|
|
92
|
+
padding: '2px',
|
|
93
|
+
display: 'inline-block',
|
|
94
|
+
}));
|
|
95
|
+
|
|
96
|
+
const StyledCorrectIcon = styled(StyledCorrectnessIcon)(() => ({
|
|
97
|
+
backgroundColor: color.correctTertiary(),
|
|
98
|
+
}));
|
|
99
|
+
|
|
100
|
+
const StyledIncorrectIcon = styled(StyledCorrectnessIcon)(() => ({
|
|
101
|
+
backgroundColor: color.incorrectWithIcon(),
|
|
102
|
+
}));
|
|
103
|
+
|
|
104
|
+
const Wrapper = ({ useWrapper, children, Container, IconComponent, Icon }) =>
|
|
17
105
|
useWrapper ? (
|
|
18
|
-
<
|
|
106
|
+
<Container>
|
|
19
107
|
{children}
|
|
20
|
-
|
|
21
|
-
|
|
108
|
+
{Icon && IconComponent ? (
|
|
109
|
+
<IconComponent>
|
|
110
|
+
<Icon fontSize="inherit" />
|
|
111
|
+
</IconComponent>
|
|
112
|
+
) : null}
|
|
113
|
+
</Container>
|
|
22
114
|
) : (
|
|
23
115
|
children
|
|
24
116
|
);
|
|
25
117
|
|
|
26
118
|
Wrapper.propTypes = {
|
|
27
119
|
useWrapper: PropTypes.bool,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Icon: PropTypes.
|
|
31
|
-
children: PropTypes.
|
|
120
|
+
Container: PropTypes.elementType,
|
|
121
|
+
IconComponent: PropTypes.elementType,
|
|
122
|
+
Icon: PropTypes.elementType,
|
|
123
|
+
children: PropTypes.node,
|
|
32
124
|
};
|
|
33
125
|
|
|
34
126
|
export const TokenTypes = {
|
|
@@ -41,7 +133,6 @@ export class Token extends React.Component {
|
|
|
41
133
|
|
|
42
134
|
static propTypes = {
|
|
43
135
|
...TokenTypes,
|
|
44
|
-
classes: PropTypes.object.isRequired,
|
|
45
136
|
text: PropTypes.string.isRequired,
|
|
46
137
|
className: PropTypes.string,
|
|
47
138
|
disabled: PropTypes.bool,
|
|
@@ -58,7 +149,6 @@ export class Token extends React.Component {
|
|
|
58
149
|
const {
|
|
59
150
|
selectable,
|
|
60
151
|
selected,
|
|
61
|
-
classes,
|
|
62
152
|
className: classNameProp,
|
|
63
153
|
disabled,
|
|
64
154
|
highlight,
|
|
@@ -68,68 +158,70 @@ export class Token extends React.Component {
|
|
|
68
158
|
} = this.props;
|
|
69
159
|
const isTouchEnabled = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
|
|
70
160
|
const baseClassName = Token.rootClassName;
|
|
71
|
-
let
|
|
161
|
+
let Container;
|
|
72
162
|
let Icon;
|
|
73
|
-
let
|
|
163
|
+
let IconComponent;
|
|
74
164
|
|
|
75
165
|
if (correct === undefined && selected && disabled) {
|
|
76
166
|
return {
|
|
77
|
-
className: classNames(
|
|
167
|
+
className: classNames(baseClassName, 'selected', 'disabledBlack', classNameProp),
|
|
168
|
+
Component: StyledToken,
|
|
78
169
|
};
|
|
79
170
|
}
|
|
80
171
|
|
|
81
172
|
if (correct !== undefined) {
|
|
82
173
|
const isCorrect = correct === true;
|
|
83
174
|
return {
|
|
84
|
-
className: classNames(baseClassName,
|
|
85
|
-
|
|
175
|
+
className: classNames(baseClassName, 'custom', classNameProp),
|
|
176
|
+
Component: StyledToken,
|
|
177
|
+
Container: isCorrect ? StyledCorrectContainer : StyledIncorrectContainer,
|
|
86
178
|
Icon: isCorrect ? Check : Close,
|
|
87
|
-
|
|
88
|
-
classes.correctnessIndicatorIcon,
|
|
89
|
-
isCorrect ? classes.correctIcon : classes.incorrectIcon,
|
|
90
|
-
),
|
|
179
|
+
IconComponent: isCorrect ? StyledCorrectIcon : StyledIncorrectIcon,
|
|
91
180
|
};
|
|
92
181
|
}
|
|
93
182
|
|
|
94
183
|
if (isMissing) {
|
|
95
184
|
return {
|
|
96
|
-
className: classNames(baseClassName,
|
|
97
|
-
|
|
185
|
+
className: classNames(baseClassName, 'custom', 'missing', classNameProp),
|
|
186
|
+
Component: StyledToken,
|
|
187
|
+
Container: StyledMissingContainer,
|
|
98
188
|
Icon: Close,
|
|
99
|
-
|
|
189
|
+
IconComponent: StyledIncorrectIcon,
|
|
100
190
|
};
|
|
101
191
|
}
|
|
102
192
|
|
|
103
193
|
return {
|
|
104
194
|
className: classNames(
|
|
105
195
|
baseClassName,
|
|
106
|
-
|
|
107
|
-
disabled &&
|
|
108
|
-
|
|
109
|
-
selected &&
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
animationsDisabled && classes.print,
|
|
196
|
+
disabled && 'disabled',
|
|
197
|
+
selectable && !disabled && !isTouchEnabled && 'selectable',
|
|
198
|
+
selected && !disabled && 'selected',
|
|
199
|
+
selected && disabled && 'disabledAndSelected',
|
|
200
|
+
highlight && selectable && !disabled && !selected && 'highlight',
|
|
201
|
+
animationsDisabled && 'print',
|
|
113
202
|
classNameProp,
|
|
114
203
|
),
|
|
115
|
-
|
|
204
|
+
Component: StyledToken,
|
|
205
|
+
Container,
|
|
116
206
|
Icon,
|
|
117
|
-
|
|
207
|
+
IconComponent,
|
|
118
208
|
};
|
|
119
209
|
};
|
|
120
210
|
|
|
121
211
|
render() {
|
|
122
212
|
const { text, index, correct, isMissing } = this.props;
|
|
123
|
-
const { className,
|
|
213
|
+
const { className, Component, Container, Icon, IconComponent } = this.getClassAndIconConfig();
|
|
214
|
+
|
|
215
|
+
const TokenComponent = Component || StyledToken;
|
|
124
216
|
|
|
125
217
|
return (
|
|
126
218
|
<Wrapper
|
|
127
219
|
useWrapper={correct !== undefined || isMissing}
|
|
128
|
-
|
|
129
|
-
|
|
220
|
+
Container={Container}
|
|
221
|
+
IconComponent={IconComponent}
|
|
130
222
|
Icon={Icon}
|
|
131
223
|
>
|
|
132
|
-
<
|
|
224
|
+
<TokenComponent
|
|
133
225
|
className={className}
|
|
134
226
|
dangerouslySetInnerHTML={{ __html: (text || '').replace(/\n/g, '<br>') }}
|
|
135
227
|
data-indexkey={index}
|
|
@@ -139,87 +231,4 @@ export class Token extends React.Component {
|
|
|
139
231
|
}
|
|
140
232
|
}
|
|
141
233
|
|
|
142
|
-
export default
|
|
143
|
-
return {
|
|
144
|
-
token: {
|
|
145
|
-
cursor: 'pointer',
|
|
146
|
-
textIndent: 0,
|
|
147
|
-
},
|
|
148
|
-
disabled: {
|
|
149
|
-
cursor: 'inherit',
|
|
150
|
-
color: color.disabled(),
|
|
151
|
-
},
|
|
152
|
-
disabledBlack: {
|
|
153
|
-
cursor: 'inherit',
|
|
154
|
-
},
|
|
155
|
-
disabledAndSelected: {
|
|
156
|
-
backgroundColor: color.blueGrey100(),
|
|
157
|
-
},
|
|
158
|
-
selectable: {
|
|
159
|
-
[theme.breakpoints.up(769)]: {
|
|
160
|
-
'&:hover': {
|
|
161
|
-
backgroundColor: color.blueGrey300(),
|
|
162
|
-
color: theme.palette.common.black,
|
|
163
|
-
'& > *': {
|
|
164
|
-
backgroundColor: color.blueGrey300(),
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
selected: {
|
|
170
|
-
backgroundColor: color.blueGrey100(),
|
|
171
|
-
color: theme.palette.common.black,
|
|
172
|
-
lineHeight: `${theme.spacing.unit * LINE_HEIGHT_MULTIPLIER}px`,
|
|
173
|
-
border: `solid 2px ${color.blueGrey900()}`,
|
|
174
|
-
borderRadius: '4px',
|
|
175
|
-
'& > *': {
|
|
176
|
-
backgroundColor: color.blueGrey100(),
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
highlight: {
|
|
180
|
-
border: `dashed 2px ${color.blueGrey600()}`,
|
|
181
|
-
borderRadius: '4px',
|
|
182
|
-
lineHeight: `${theme.spacing.unit * LINE_HEIGHT_MULTIPLIER}px`,
|
|
183
|
-
},
|
|
184
|
-
print: {
|
|
185
|
-
border: `dashed 2px ${color.blueGrey600()}`,
|
|
186
|
-
borderRadius: '4px',
|
|
187
|
-
lineHeight: `${theme.spacing.unit * LINE_HEIGHT_MULTIPLIER}px`,
|
|
188
|
-
color: color.text(),
|
|
189
|
-
},
|
|
190
|
-
custom: {
|
|
191
|
-
display: 'initial',
|
|
192
|
-
},
|
|
193
|
-
commonTokenStyle: {
|
|
194
|
-
position: 'relative',
|
|
195
|
-
borderRadius: '4px',
|
|
196
|
-
color: theme.palette.common.black,
|
|
197
|
-
lineHeight: `${theme.spacing.unit * CORRECTNESS_LINE_HEIGHT_MULTIPLIER + CORRECTNESS_PADDING}px`,
|
|
198
|
-
padding: `${CORRECTNESS_PADDING}px`,
|
|
199
|
-
},
|
|
200
|
-
correct: {
|
|
201
|
-
border: `${color.correctTertiary()} solid 2px`,
|
|
202
|
-
},
|
|
203
|
-
incorrect: {
|
|
204
|
-
border: `${color.incorrectWithIcon()} solid 2px`,
|
|
205
|
-
},
|
|
206
|
-
missing: {
|
|
207
|
-
border: `${color.incorrectWithIcon()} dashed 2px`,
|
|
208
|
-
},
|
|
209
|
-
incorrectIcon: {
|
|
210
|
-
backgroundColor: color.incorrectWithIcon(),
|
|
211
|
-
},
|
|
212
|
-
correctIcon: {
|
|
213
|
-
backgroundColor: color.correctTertiary(),
|
|
214
|
-
},
|
|
215
|
-
correctnessIndicatorIcon: {
|
|
216
|
-
color: color.white(),
|
|
217
|
-
position: 'absolute',
|
|
218
|
-
top: '-8px',
|
|
219
|
-
left: '-8px',
|
|
220
|
-
borderRadius: '50%',
|
|
221
|
-
fontSize: '12px',
|
|
222
|
-
padding: '2px',
|
|
223
|
-
},
|
|
224
|
-
};
|
|
225
|
-
})(Token);
|
|
234
|
+
export default Token;
|
|
@@ -1,15 +1,36 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import Button from '@material
|
|
4
|
-
import {
|
|
5
|
-
import Switch from '@material
|
|
6
|
-
import FormControlLabel from '@material
|
|
3
|
+
import Button from '@mui/material/Button';
|
|
4
|
+
import { styled } from '@mui/material/styles';
|
|
5
|
+
import Switch from '@mui/material/Switch';
|
|
6
|
+
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
7
7
|
import { color } from '@pie-lib/render-ui';
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
const StyledControls = styled('div')(() => ({
|
|
10
|
+
display: 'flex',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
justifyContent: 'space-between',
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
const StyledButton = styled(Button)(({ theme }) => ({
|
|
16
|
+
marginRight: theme.spacing(1),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
const StyledSwitch = styled(Switch)(() => ({
|
|
20
|
+
'& .MuiSwitch-thumb': {
|
|
21
|
+
'&.Mui-checked': {
|
|
22
|
+
color: `${color.tertiary()} !important`,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
'& .MuiSwitch-track': {
|
|
26
|
+
'&.Mui-checked': {
|
|
27
|
+
backgroundColor: `${color.tertiaryLight()} !important`,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
}));
|
|
9
31
|
|
|
10
32
|
export class Controls extends React.Component {
|
|
11
33
|
static propTypes = {
|
|
12
|
-
classes: PropTypes.object.isRequired,
|
|
13
34
|
onClear: PropTypes.func.isRequired,
|
|
14
35
|
onWords: PropTypes.func.isRequired,
|
|
15
36
|
onSentences: PropTypes.func.isRequired,
|
|
@@ -21,68 +42,45 @@ export class Controls extends React.Component {
|
|
|
21
42
|
static defaultProps = {};
|
|
22
43
|
|
|
23
44
|
render() {
|
|
24
|
-
const {
|
|
45
|
+
const { onClear, onWords, onSentences, onParagraphs, setCorrectMode, onToggleCorrectMode } = this.props;
|
|
25
46
|
|
|
26
47
|
return (
|
|
27
|
-
<
|
|
48
|
+
<StyledControls>
|
|
28
49
|
<div>
|
|
29
|
-
<
|
|
50
|
+
<StyledButton onClick={onWords} size="small" color="primary" disabled={setCorrectMode}>
|
|
30
51
|
Words
|
|
31
|
-
</
|
|
32
|
-
<
|
|
52
|
+
</StyledButton>
|
|
53
|
+
<StyledButton
|
|
33
54
|
onClick={onSentences}
|
|
34
|
-
className={classes.button}
|
|
35
55
|
size="small"
|
|
36
56
|
color="primary"
|
|
37
57
|
disabled={setCorrectMode}
|
|
38
58
|
>
|
|
39
59
|
Sentences
|
|
40
|
-
</
|
|
41
|
-
<
|
|
60
|
+
</StyledButton>
|
|
61
|
+
<StyledButton
|
|
42
62
|
onClick={onParagraphs}
|
|
43
|
-
className={classes.button}
|
|
44
63
|
size="small"
|
|
45
64
|
color="primary"
|
|
46
65
|
disabled={setCorrectMode}
|
|
47
66
|
>
|
|
48
67
|
Paragraphs
|
|
49
|
-
</
|
|
50
|
-
<
|
|
68
|
+
</StyledButton>
|
|
69
|
+
<StyledButton size="small" color="secondary" onClick={onClear} disabled={setCorrectMode}>
|
|
51
70
|
Clear
|
|
52
|
-
</
|
|
71
|
+
</StyledButton>
|
|
53
72
|
</div>
|
|
54
73
|
<FormControlLabel
|
|
55
74
|
control={
|
|
56
|
-
<
|
|
57
|
-
classes={{
|
|
58
|
-
checked: classes.checkedThumb,
|
|
59
|
-
bar: classNames({
|
|
60
|
-
[classes.checkedBar]: setCorrectMode,
|
|
61
|
-
}),
|
|
62
|
-
}}
|
|
75
|
+
<StyledSwitch
|
|
63
76
|
checked={setCorrectMode}
|
|
64
77
|
onChange={onToggleCorrectMode}
|
|
65
78
|
/>
|
|
66
79
|
}
|
|
67
80
|
label="Set correct answers"
|
|
68
81
|
/>
|
|
69
|
-
</
|
|
82
|
+
</StyledControls>
|
|
70
83
|
);
|
|
71
84
|
}
|
|
72
85
|
}
|
|
73
|
-
export default
|
|
74
|
-
button: {
|
|
75
|
-
marginRight: theme.spacing.unit,
|
|
76
|
-
},
|
|
77
|
-
controls: {
|
|
78
|
-
display: 'flex',
|
|
79
|
-
alignItems: 'center',
|
|
80
|
-
justifyContent: 'space-between',
|
|
81
|
-
},
|
|
82
|
-
checkedThumb: {
|
|
83
|
-
color: `${color.tertiary()} !important`,
|
|
84
|
-
},
|
|
85
|
-
checkedBar: {
|
|
86
|
-
backgroundColor: `${color.tertiaryLight()} !important`,
|
|
87
|
-
},
|
|
88
|
-
}))(Controls);
|
|
86
|
+
export default Controls;
|
package/src/tokenizer/index.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import Controls from './controls';
|
|
4
|
-
import {
|
|
4
|
+
import { styled } from '@mui/material/styles';
|
|
5
5
|
import { words, sentences, paragraphs } from './builder';
|
|
6
6
|
import clone from 'lodash/clone';
|
|
7
7
|
import isEqual from 'lodash/isEqual';
|
|
@@ -10,6 +10,15 @@ import classNames from 'classnames';
|
|
|
10
10
|
import { noSelect } from '@pie-lib/style-utils';
|
|
11
11
|
import TokenText from './token-text';
|
|
12
12
|
|
|
13
|
+
const StyledTokenizer = styled('div')(() => ({}));
|
|
14
|
+
|
|
15
|
+
const StyledText = styled('div')(() => ({
|
|
16
|
+
whiteSpace: 'pre-wrap',
|
|
17
|
+
'&.noselect': {
|
|
18
|
+
...noSelect(),
|
|
19
|
+
},
|
|
20
|
+
}));
|
|
21
|
+
|
|
13
22
|
export class Tokenizer extends React.Component {
|
|
14
23
|
static propTypes = {
|
|
15
24
|
text: PropTypes.string.isRequired,
|
|
@@ -21,7 +30,6 @@ export class Tokenizer extends React.Component {
|
|
|
21
30
|
end: PropTypes.number,
|
|
22
31
|
}),
|
|
23
32
|
),
|
|
24
|
-
classes: PropTypes.object.isRequired,
|
|
25
33
|
className: PropTypes.string,
|
|
26
34
|
onChange: PropTypes.func.isRequired,
|
|
27
35
|
};
|
|
@@ -112,15 +120,13 @@ export class Tokenizer extends React.Component {
|
|
|
112
120
|
};
|
|
113
121
|
|
|
114
122
|
render() {
|
|
115
|
-
const { text, tokens,
|
|
123
|
+
const { text, tokens, className } = this.props;
|
|
116
124
|
const { setCorrectMode } = this.state;
|
|
117
125
|
|
|
118
|
-
const tokenClassName = classNames(
|
|
119
|
-
|
|
120
|
-
const rootName = classNames(classes.tokenizer, className);
|
|
126
|
+
const tokenClassName = classNames('text', setCorrectMode && 'noselect');
|
|
121
127
|
|
|
122
128
|
return (
|
|
123
|
-
<
|
|
129
|
+
<StyledTokenizer className={className}>
|
|
124
130
|
<Controls
|
|
125
131
|
onClear={this.clear}
|
|
126
132
|
onWords={() => this.buildTokens('words', words)}
|
|
@@ -129,21 +135,17 @@ export class Tokenizer extends React.Component {
|
|
|
129
135
|
setCorrectMode={setCorrectMode}
|
|
130
136
|
onToggleCorrectMode={this.toggleCorrectMode}
|
|
131
137
|
/>
|
|
132
|
-
<
|
|
138
|
+
<StyledText
|
|
133
139
|
className={tokenClassName}
|
|
140
|
+
as={TokenText}
|
|
134
141
|
text={text}
|
|
135
142
|
tokens={tokens}
|
|
136
143
|
onTokenClick={this.tokenClick}
|
|
137
144
|
onSelectToken={this.selectToken}
|
|
138
145
|
/>
|
|
139
|
-
</
|
|
146
|
+
</StyledTokenizer>
|
|
140
147
|
);
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
150
|
|
|
144
|
-
export default
|
|
145
|
-
text: {
|
|
146
|
-
whiteSpace: 'pre-wrap',
|
|
147
|
-
},
|
|
148
|
-
noselect: { ...noSelect() },
|
|
149
|
-
}))(Tokenizer);
|
|
151
|
+
export default Tokenizer;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
4
|
import { normalize, intersection } from './builder';
|
|
5
|
-
import yellow from '@material-ui/core/colors/yellow';
|
|
6
|
-
import green from '@material-ui/core/colors/green';
|
|
7
5
|
import debug from 'debug';
|
|
8
6
|
import classNames from 'classnames';
|
|
9
7
|
|
|
10
8
|
import { clearSelection, getCaretCharacterOffsetWithin } from './selection-utils';
|
|
11
9
|
|
|
10
|
+
import { yellow, green } from '@mui/material/colors';
|
|
11
|
+
|
|
12
12
|
const log = debug('@pie-lib:text-select:token-text');
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
predefined: {
|
|
14
|
+
const StyledText = styled('span')(() => ({
|
|
15
|
+
'&.predefined': {
|
|
16
16
|
cursor: 'pointer',
|
|
17
17
|
backgroundColor: yellow[100],
|
|
18
18
|
border: `dashed 0px ${yellow[700]}`,
|
|
@@ -23,23 +23,25 @@ export const Text = withStyles(() => ({
|
|
|
23
23
|
border: `dashed 0px ${yellow[700]}`,
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
|
-
correct: {
|
|
26
|
+
'&.correct': {
|
|
27
27
|
backgroundColor: green[500],
|
|
28
28
|
'& *': {
|
|
29
29
|
backgroundColor: green[500],
|
|
30
30
|
},
|
|
31
31
|
},
|
|
32
|
-
}))
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
export const Text = ({ text, predefined, onClick, correct }) => {
|
|
33
35
|
const formattedText = (text || '').replace(/\n/g, '<br>');
|
|
34
36
|
|
|
35
37
|
if (predefined) {
|
|
36
|
-
const className = classNames(
|
|
38
|
+
const className = classNames('predefined', correct && 'correct');
|
|
37
39
|
|
|
38
|
-
return <
|
|
40
|
+
return <StyledText onClick={onClick} className={className} dangerouslySetInnerHTML={{ __html: formattedText }} />;
|
|
39
41
|
} else {
|
|
40
42
|
return <span dangerouslySetInnerHTML={{ __html: formattedText }} />;
|
|
41
43
|
}
|
|
42
|
-
}
|
|
44
|
+
};
|
|
43
45
|
|
|
44
46
|
const notAllowedCharacters = ['\n', ' ', '\t'];
|
|
45
47
|
|