@pie-lib/text-select 1.28.3-next.12 → 1.29.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.
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { withStyles } from '@material-ui/core/styles';
3
+ import { styled } from '@mui/material/styles';
4
4
  import classNames from 'classnames';
5
- import Check from '@material-ui/icons/Check';
6
- import Close from '@material-ui/icons/Close';
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,6 +13,93 @@ const LINE_HEIGHT_MULTIPLIER = 3.2;
13
13
  const CORRECTNESS_LINE_HEIGHT_MULTIPLIER = 3.4;
14
14
  const CORRECTNESS_PADDING = 2;
15
15
 
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('div')(() => ({
86
+ color: color.white(),
87
+ position: 'absolute',
88
+ top: '-8px',
89
+ left: '-8px',
90
+ borderRadius: '50%',
91
+ fontSize: '12px',
92
+ padding: '2px',
93
+ }));
94
+
95
+ const StyledCorrectIcon = styled(StyledCorrectnessIcon)(() => ({
96
+ backgroundColor: color.correctTertiary(),
97
+ }));
98
+
99
+ const StyledIncorrectIcon = styled(StyledCorrectnessIcon)(() => ({
100
+ backgroundColor: color.incorrectWithIcon(),
101
+ }));
102
+
16
103
  const Wrapper = ({ useWrapper, children, classNameContainer, iconClass, Icon }) =>
17
104
  useWrapper ? (
18
105
  <span className={classNameContainer}>
@@ -41,7 +128,6 @@ export class Token extends React.Component {
41
128
 
42
129
  static propTypes = {
43
130
  ...TokenTypes,
44
- classes: PropTypes.object.isRequired,
45
131
  text: PropTypes.string.isRequired,
46
132
  className: PropTypes.string,
47
133
  disabled: PropTypes.bool,
@@ -58,7 +144,6 @@ export class Token extends React.Component {
58
144
  const {
59
145
  selectable,
60
146
  selected,
61
- classes,
62
147
  className: classNameProp,
63
148
  disabled,
64
149
  highlight,
@@ -68,68 +153,70 @@ export class Token extends React.Component {
68
153
  } = this.props;
69
154
  const isTouchEnabled = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
70
155
  const baseClassName = Token.rootClassName;
71
- let classNameContainer;
156
+ let Container;
72
157
  let Icon;
73
- let iconClass;
158
+ let IconComponent;
74
159
 
75
160
  if (correct === undefined && selected && disabled) {
76
161
  return {
77
- className: classNames(classes.token, classes.selected, classes.disabledBlack),
162
+ className: classNames(baseClassName, 'selected', 'disabledBlack', classNameProp),
163
+ Component: StyledToken,
78
164
  };
79
165
  }
80
166
 
81
167
  if (correct !== undefined) {
82
168
  const isCorrect = correct === true;
83
169
  return {
84
- className: classNames(baseClassName, classes.custom),
85
- classNameContainer: classNames(isCorrect ? classes.correct : classes.incorrect, classes.commonTokenStyle),
170
+ className: classNames(baseClassName, 'custom', classNameProp),
171
+ Component: StyledToken,
172
+ Container: isCorrect ? StyledCorrectContainer : StyledIncorrectContainer,
86
173
  Icon: isCorrect ? Check : Close,
87
- iconClass: classNames(
88
- classes.correctnessIndicatorIcon,
89
- isCorrect ? classes.correctIcon : classes.incorrectIcon,
90
- ),
174
+ IconComponent: isCorrect ? StyledCorrectIcon : StyledIncorrectIcon,
91
175
  };
92
176
  }
93
177
 
94
178
  if (isMissing) {
95
179
  return {
96
- className: classNames(baseClassName, classes.custom, classes.missing, classes.commonTokenStyle),
97
- classNameContainer: classes.commonTokenStyle,
180
+ className: classNames(baseClassName, 'custom', 'missing', classNameProp),
181
+ Component: StyledToken,
182
+ Container: StyledMissingContainer,
98
183
  Icon: Close,
99
- iconClass: classNames(classes.correctnessIndicatorIcon, classes.incorrectIcon),
184
+ IconComponent: StyledIncorrectIcon,
100
185
  };
101
186
  }
102
187
 
103
188
  return {
104
189
  className: classNames(
105
190
  baseClassName,
106
- classes.token,
107
- disabled && classes.disabled,
108
- selectable && !disabled && !isTouchEnabled && classes.selectable,
109
- selected && !disabled && classes.selected,
110
- selected && disabled && classes.disabledAndSelected,
111
- highlight && selectable && !disabled && !selected && classes.highlight,
112
- animationsDisabled && classes.print,
191
+ disabled && 'disabled',
192
+ selectable && !disabled && !isTouchEnabled && 'selectable',
193
+ selected && !disabled && 'selected',
194
+ selected && disabled && 'disabledAndSelected',
195
+ highlight && selectable && !disabled && !selected && 'highlight',
196
+ animationsDisabled && 'print',
113
197
  classNameProp,
114
198
  ),
115
- classNameContainer,
199
+ Component: StyledToken,
200
+ Container,
116
201
  Icon,
117
- iconClass,
202
+ IconComponent,
118
203
  };
119
204
  };
120
205
 
121
206
  render() {
122
207
  const { text, index, correct, isMissing } = this.props;
123
- const { className, classNameContainer, Icon, iconClass } = this.getClassAndIconConfig();
208
+ const { className, Component, Container, Icon, IconComponent } = this.getClassAndIconConfig();
209
+
210
+ const TokenComponent = Component || StyledToken;
124
211
 
125
212
  return (
126
213
  <Wrapper
127
214
  useWrapper={correct !== undefined || isMissing}
128
- classNameContainer={classNameContainer}
129
- iconClass={iconClass}
215
+ classNameContainer={Container}
216
+ iconClass={IconComponent}
130
217
  Icon={Icon}
131
218
  >
132
- <span
219
+ <TokenComponent
133
220
  className={className}
134
221
  dangerouslySetInnerHTML={{ __html: (text || '').replace(/\n/g, '<br>') }}
135
222
  data-indexkey={index}
@@ -139,87 +226,4 @@ export class Token extends React.Component {
139
226
  }
140
227
  }
141
228
 
142
- export default withStyles((theme) => {
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);
229
+ 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-ui/core/Button';
4
- import { withStyles } from '@material-ui/core/styles';
5
- import Switch from '@material-ui/core/Switch';
6
- import FormControlLabel from '@material-ui/core/FormControlLabel';
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
- import classNames from 'classnames';
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 { classes, onClear, onWords, onSentences, onParagraphs, setCorrectMode, onToggleCorrectMode } = this.props;
45
+ const { onClear, onWords, onSentences, onParagraphs, setCorrectMode, onToggleCorrectMode } = this.props;
25
46
 
26
47
  return (
27
- <div className={classes.controls}>
48
+ <StyledControls>
28
49
  <div>
29
- <Button onClick={onWords} className={classes.button} size="small" color="primary" disabled={setCorrectMode}>
50
+ <StyledButton onClick={onWords} size="small" color="primary" disabled={setCorrectMode}>
30
51
  Words
31
- </Button>
32
- <Button
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
- </Button>
41
- <Button
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
- </Button>
50
- <Button className={classes.button} size="small" color="secondary" onClick={onClear} disabled={setCorrectMode}>
68
+ </StyledButton>
69
+ <StyledButton size="small" color="secondary" onClick={onClear} disabled={setCorrectMode}>
51
70
  Clear
52
- </Button>
71
+ </StyledButton>
53
72
  </div>
54
73
  <FormControlLabel
55
74
  control={
56
- <Switch
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
- </div>
82
+ </StyledControls>
70
83
  );
71
84
  }
72
85
  }
73
- export default withStyles((theme) => ({
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;
@@ -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 { withStyles } from '@material-ui/core/styles';
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, classes, className } = this.props;
123
+ const { text, tokens, className } = this.props;
116
124
  const { setCorrectMode } = this.state;
117
125
 
118
- const tokenClassName = classNames(classes.text, setCorrectMode && classes.noselect);
119
-
120
- const rootName = classNames(classes.tokenizer, className);
126
+ const tokenClassName = classNames('text', setCorrectMode && 'noselect');
121
127
 
122
128
  return (
123
- <div className={rootName}>
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
- <TokenText
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
- </div>
146
+ </StyledTokenizer>
140
147
  );
141
148
  }
142
149
  }
143
150
 
144
- export default withStyles(() => ({
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 { withStyles } from '@material-ui/core/styles';
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
- export const Text = withStyles(() => ({
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
- }))(({ text, predefined, classes, onClick, correct }) => {
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(classes.predefined, correct && classes.correct);
38
+ const className = classNames('predefined', correct && 'correct');
37
39
 
38
- return <span onClick={onClick} className={className} dangerouslySetInnerHTML={{ __html: formattedText }} />;
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