@pie-lib/text-select 1.32.2-next.0 → 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.
@@ -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,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
- const Wrapper = ({ useWrapper, children, classNameContainer, iconClass, Icon }) =>
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
- <span className={classNameContainer}>
106
+ <Container>
19
107
  {children}
20
- <Icon className={iconClass} />
21
- </span>
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
- classNameContainer: PropTypes.string,
29
- iconClass: PropTypes.string,
30
- Icon: PropTypes.func,
31
- children: PropTypes.element,
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 classNameContainer;
161
+ let Container;
72
162
  let Icon;
73
- let iconClass;
163
+ let IconComponent;
74
164
 
75
165
  if (correct === undefined && selected && disabled) {
76
166
  return {
77
- className: classNames(classes.token, classes.selected, classes.disabledBlack),
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, classes.custom),
85
- classNameContainer: classNames(isCorrect ? classes.correct : classes.incorrect, classes.commonTokenStyle),
175
+ className: classNames(baseClassName, 'custom', classNameProp),
176
+ Component: StyledToken,
177
+ Container: isCorrect ? StyledCorrectContainer : StyledIncorrectContainer,
86
178
  Icon: isCorrect ? Check : Close,
87
- iconClass: classNames(
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, classes.custom, classes.missing, classes.commonTokenStyle),
97
- classNameContainer: classes.commonTokenStyle,
185
+ className: classNames(baseClassName, 'custom', 'missing', classNameProp),
186
+ Component: StyledToken,
187
+ Container: StyledMissingContainer,
98
188
  Icon: Close,
99
- iconClass: classNames(classes.correctnessIndicatorIcon, classes.incorrectIcon),
189
+ IconComponent: StyledIncorrectIcon,
100
190
  };
101
191
  }
102
192
 
103
193
  return {
104
194
  className: classNames(
105
195
  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,
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
- classNameContainer,
204
+ Component: StyledToken,
205
+ Container,
116
206
  Icon,
117
- iconClass,
207
+ IconComponent,
118
208
  };
119
209
  };
120
210
 
121
211
  render() {
122
212
  const { text, index, correct, isMissing } = this.props;
123
- const { className, classNameContainer, Icon, iconClass } = this.getClassAndIconConfig();
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
- classNameContainer={classNameContainer}
129
- iconClass={iconClass}
220
+ Container={Container}
221
+ IconComponent={IconComponent}
130
222
  Icon={Icon}
131
223
  >
132
- <span
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 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);
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-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