@scrabble-solver/scrabble-solver 2.10.4 → 2.10.6

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.
Files changed (71) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +9 -9
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/eslint/.cache_8dgz12 +1 -1
  5. package/.next/cache/next-server.js.nft.json +1 -1
  6. package/.next/cache/webpack/client-production/0.pack +0 -0
  7. package/.next/cache/webpack/client-production/index.pack +0 -0
  8. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  9. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  10. package/.next/cache/webpack/server-production/0.pack +0 -0
  11. package/.next/cache/webpack/server-production/index.pack +0 -0
  12. package/.next/next-server.js.nft.json +1 -1
  13. package/.next/prerender-manifest.json +1 -1
  14. package/.next/routes-manifest.json +1 -1
  15. package/.next/server/chunks/176.js +433 -228
  16. package/.next/server/middleware-build-manifest.js +1 -1
  17. package/.next/server/pages/404.html +2 -2
  18. package/.next/server/pages/404.js.nft.json +1 -1
  19. package/.next/server/pages/500.html +2 -2
  20. package/.next/server/pages/_app.js.nft.json +1 -1
  21. package/.next/server/pages/index.html +2 -2
  22. package/.next/server/pages/index.js +20 -50
  23. package/.next/server/pages/index.js.nft.json +1 -1
  24. package/.next/server/pages/index.json +1 -1
  25. package/.next/server/pages-manifest.json +3 -3
  26. package/.next/static/chunks/791-93aa8b8c22e488ac.js +1 -0
  27. package/.next/static/chunks/pages/{404-6c99a0c91257c60b.js → 404-ff35a4cf7f1ec85a.js} +1 -1
  28. package/.next/static/chunks/pages/index-ded620fd5df96be0.js +1 -0
  29. package/.next/static/css/4482c4a0064d3807.css +1 -0
  30. package/.next/static/css/a943dd97164732d4.css +1 -0
  31. package/.next/static/iL0av55MV28b0MXfhKKt2/_buildManifest.js +1 -0
  32. package/.next/trace +55 -55
  33. package/package.json +14 -14
  34. package/src/components/Board/components/Cell/Cell.module.scss +11 -11
  35. package/src/components/Button/Button.module.scss +29 -10
  36. package/src/components/Button/Button.tsx +24 -5
  37. package/src/components/Button/Link.tsx +44 -0
  38. package/src/components/Radio/Radio.module.scss +2 -2
  39. package/src/components/Results/SolveButton.tsx +1 -0
  40. package/src/components/Solver/Solver.module.scss +9 -21
  41. package/src/components/Solver/Solver.tsx +20 -56
  42. package/src/components/Solver/components/ApplyButton/ApplyButton.tsx +1 -0
  43. package/src/components/Solver/components/MobileControls/MobileControls.tsx +62 -0
  44. package/src/components/Solver/components/MobileControls/index.ts +1 -0
  45. package/src/components/{ResultCandidatePicker → Solver/components/ResultCandidatePicker}/ResultCandidatePicker.module.scss +47 -3
  46. package/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +75 -0
  47. package/src/components/Solver/components/SolveButton/SolveButton.tsx +1 -0
  48. package/src/components/Solver/components/index.ts +2 -0
  49. package/src/components/SquareButton/SquareButton.module.scss +1 -2
  50. package/src/components/SquareButton/SquareButton.tsx +2 -2
  51. package/src/components/Tile/Tile.module.scss +35 -18
  52. package/src/components/Tile/Tile.tsx +2 -2
  53. package/src/components/Tile/TilePure.tsx +9 -5
  54. package/src/components/Tooltip/Tooltip.module.scss +5 -5
  55. package/src/components/index.ts +0 -1
  56. package/src/icons/ChevronLeft.svg +4 -0
  57. package/src/icons/ChevronRight.svg +4 -0
  58. package/src/icons/index.ts +2 -0
  59. package/src/modals/MenuModal/MenuModal.module.scss +3 -39
  60. package/src/modals/MenuModal/MenuModal.tsx +22 -20
  61. package/src/modals/RemainingTilesModal/components/Character/Character.module.scss +1 -1
  62. package/src/modals/ResultsModal/ResultsModal.tsx +3 -3
  63. package/src/styles/mixins.scss +8 -2
  64. package/.next/static/P7XhuDLmwJJqC8kgPjX42/_buildManifest.js +0 -1
  65. package/.next/static/chunks/528-9942ddad0031ff79.js +0 -1
  66. package/.next/static/chunks/pages/index-d761f0af070273d2.js +0 -1
  67. package/.next/static/css/97eb6ee0c4300c83.css +0 -1
  68. package/.next/static/css/dcca0c1a39cf5ef5.css +0 -1
  69. package/src/components/ResultCandidatePicker/ResultCandidatePicker.tsx +0 -38
  70. /package/.next/static/{P7XhuDLmwJJqC8kgPjX42 → iL0av55MV28b0MXfhKKt2}/_ssgManifest.js +0 -0
  71. /package/src/components/{ResultCandidatePicker → Solver/components/ResultCandidatePicker}/index.ts +0 -0
@@ -0,0 +1,75 @@
1
+ import classNames from 'classnames';
2
+ import { FunctionComponent, HTMLProps } from 'react';
3
+ import { useDispatch } from 'react-redux';
4
+
5
+ import { ChevronDown, ChevronLeft, ChevronRight } from 'icons';
6
+ import {
7
+ resultsSlice,
8
+ selectAreResultsOutdated,
9
+ selectLocale,
10
+ selectResultCandidate,
11
+ selectSortedResults,
12
+ useTypedSelector,
13
+ } from 'state';
14
+
15
+ import Button from '../../../Button';
16
+ import ApplyButton from '../ApplyButton';
17
+
18
+ import styles from './ResultCandidatePicker.module.scss';
19
+
20
+ const ResultCandidatePicker: FunctionComponent<HTMLProps<HTMLDivElement>> = ({ className, ...props }) => {
21
+ const dispatch = useDispatch();
22
+ const locale = useTypedSelector(selectLocale);
23
+ const isOutdated = useTypedSelector(selectAreResultsOutdated);
24
+ const sortedResults = useTypedSelector(selectSortedResults);
25
+ const results = sortedResults || [];
26
+ const resultCandidate = useTypedSelector(selectResultCandidate);
27
+
28
+ if (!resultCandidate) {
29
+ return null;
30
+ }
31
+
32
+ const index = results.findIndex((result) => result.id === resultCandidate.id);
33
+ const isPreviousDisabled = index <= 0;
34
+ const isNextDisabled = index >= results.length - 1;
35
+
36
+ const handleNextClick = () => {
37
+ if (!isNextDisabled) {
38
+ const nextResult = results[index + 1];
39
+ dispatch(resultsSlice.actions.changeResultCandidate(nextResult));
40
+ }
41
+ };
42
+
43
+ const handlePreviousClick = () => {
44
+ if (!isPreviousDisabled) {
45
+ const previousResult = results[index - 1];
46
+ dispatch(resultsSlice.actions.changeResultCandidate(previousResult));
47
+ }
48
+ };
49
+
50
+ return (
51
+ <div className={classNames(styles.resultCandidatePicker, className)} {...props}>
52
+ <div className={styles.buttons}>
53
+ <Button
54
+ className={styles.button}
55
+ disabled={isPreviousDisabled}
56
+ Icon={ChevronLeft}
57
+ onClick={handlePreviousClick}
58
+ />
59
+ <Button className={styles.button} disabled={isNextDisabled} Icon={ChevronRight} onClick={handleNextClick} />
60
+ </div>
61
+
62
+ <button className={styles.resultCandidate} disabled={isOutdated} type="button">
63
+ <div className={styles.points}>{resultCandidate.points.toLocaleString(locale)}</div>
64
+ <div className={styles.word}>{resultCandidate.word}</div>
65
+ <div className={styles.iconContainer}>
66
+ <ChevronDown className={styles.icon} />
67
+ </div>
68
+ </button>
69
+
70
+ <ApplyButton className={styles.apply} />
71
+ </div>
72
+ );
73
+ };
74
+
75
+ export default ResultCandidatePicker;
@@ -34,6 +34,7 @@ const SolveButton: FunctionComponent<Props> = ({ className, onClick = noop }) =>
34
34
  Icon={Search}
35
35
  iconClassName={styles.icon}
36
36
  type="submit"
37
+ variant="primary"
37
38
  onClick={handleClick}
38
39
  />
39
40
  );
@@ -1,3 +1,5 @@
1
1
  export { default as ApplyButton } from './ApplyButton';
2
2
  export { default as EmptyState } from './EmptyState';
3
+ export { default as MobileControls } from './MobileControls';
4
+ export { default as ResultCandidatePicker } from './ResultCandidatePicker';
3
5
  export { default as SolveButton } from './SolveButton';
@@ -20,8 +20,7 @@
20
20
  }
21
21
 
22
22
  &[disabled] {
23
- pointer-events: none;
24
- opacity: var(--opacity--disabled);
23
+ @include disabled;
25
24
  }
26
25
  }
27
26
 
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import { ButtonHTMLAttributes, FunctionComponent, MouseEventHandler, SVGAttributes } from 'react';
2
+ import { ButtonHTMLAttributes, FunctionComponent, MouseEventHandler, ReactNode, SVGAttributes } from 'react';
3
3
 
4
4
  import { useTooltip } from '../Tooltip';
5
5
 
@@ -9,7 +9,7 @@ import styles from './SquareButton.module.scss';
9
9
  interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
10
10
  children?: never;
11
11
  Icon: FunctionComponent<SVGAttributes<SVGElement>>;
12
- tooltip: string;
12
+ tooltip: ReactNode;
13
13
  onClick: MouseEventHandler<HTMLButtonElement>;
14
14
  }
15
15
 
@@ -4,13 +4,8 @@
4
4
  --background-color: transparent;
5
5
 
6
6
  position: relative;
7
- background-color: var(--background-color);
8
7
  transition: var(--transition);
9
8
 
10
- &.raised {
11
- box-shadow: inset -2px -2px 2px -1px rgba(34, 34, 34, 0.8);
12
- }
13
-
14
9
  &.points1 {
15
10
  --background-color: var(--color--yellow);
16
11
  }
@@ -55,31 +50,53 @@
55
50
 
56
51
  color: var(--color--error);
57
52
  }
53
+
54
+ &:not(.disabled) {
55
+ .input::selection {
56
+ --background--color: transparent;
57
+ }
58
+ }
58
59
  }
59
60
 
61
+ .input,
60
62
  .character {
61
- width: 100%;
62
- height: 100%;
63
63
  padding: 0;
64
- box-sizing: border-box;
65
- background-color: transparent;
66
- color: inherit;
67
- border: none;
68
64
  font-weight: bold;
69
65
  text-transform: uppercase;
70
66
  text-align: center;
71
67
  caret-color: transparent;
68
+ box-sizing: border-box;
69
+ }
72
70
 
73
- &::placeholder {
74
- color: var(--color--inactive);
75
- }
71
+ .input {
72
+ width: 100%;
73
+ height: 100%;
74
+ background-color: transparent;
75
+ color: transparent;
76
+ border: none;
77
+ font-size: 16px; // prevent iOS from automatically zooming in on focus
78
+ }
76
79
 
77
- &:not(:disabled)::selection {
78
- --background--color: transparent;
80
+ .character {
81
+ position: absolute;
82
+ top: 0;
83
+ right: 0;
84
+ bottom: 0;
85
+ left: 0;
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ background-color: var(--background-color);
90
+ transition: var(--transition);
91
+ pointer-events: none;
92
+ user-select: none;
93
+
94
+ .empty & {
95
+ color: var(--color--inactive);
79
96
  }
80
97
 
81
- &[disabled] {
82
- color: inherit;
98
+ .raised & {
99
+ box-shadow: inset -2px -2px 2px -1px rgba(34, 34, 34, 0.8);
83
100
  }
84
101
  }
85
102
 
@@ -55,7 +55,7 @@ const Tile: FunctionComponent<Props> = ({
55
55
  const locale = useTypedSelector(selectLocale);
56
56
  const { pointsFontSize, tileFontSize, tileSize } = getTileSizes(size);
57
57
  const style = useMemo(() => ({ height: tileSize, width: tileSize }), [tileSize]);
58
- const inputStyle = useMemo(() => ({ fontSize: tileFontSize }), [tileFontSize]);
58
+ const characterStyle = useMemo(() => ({ fontSize: tileFontSize }), [tileFontSize]);
59
59
  const pointsStyle = useMemo(() => ({ fontSize: pointsFontSize }), [pointsFontSize]);
60
60
  const inputRef = useMemo<RefObject<HTMLInputElement>>(() => ref || createRef(), [ref]);
61
61
  const isEmpty = !character || character === EMPTY_CELL;
@@ -78,11 +78,11 @@ const Tile: FunctionComponent<Props> = ({
78
78
  autoFocus={autoFocus}
79
79
  canShowPoints={canShowPoints}
80
80
  character={character}
81
+ characterStyle={characterStyle}
81
82
  className={className}
82
83
  disabled={disabled}
83
84
  highlighted={highlighted}
84
85
  inputRef={inputRef}
85
- inputStyle={inputStyle}
86
86
  isBlank={isBlank}
87
87
  isValid={isValid}
88
88
  placeholder={placeholder}
@@ -17,11 +17,11 @@ interface Props {
17
17
  autoFocus?: boolean;
18
18
  canShowPoints?: boolean;
19
19
  character?: string;
20
+ characterStyle?: CSSProperties;
20
21
  className?: string;
21
22
  disabled?: boolean;
22
23
  highlighted?: boolean;
23
24
  inputRef: RefObject<HTMLInputElement>;
24
- inputStyle?: CSSProperties;
25
25
  isBlank?: boolean;
26
26
  isValid?: boolean;
27
27
  placeholder?: string;
@@ -40,11 +40,11 @@ const TilePure: FunctionComponent<Props> = ({
40
40
  autoFocus,
41
41
  canShowPoints,
42
42
  character,
43
+ characterStyle,
43
44
  className,
44
45
  disabled,
45
46
  highlighted,
46
47
  inputRef,
47
- inputStyle,
48
48
  isBlank,
49
49
  isValid,
50
50
  placeholder,
@@ -61,6 +61,8 @@ const TilePure: FunctionComponent<Props> = ({
61
61
  <div
62
62
  className={classNames(styles.tile, className, {
63
63
  [styles.blank]: isBlank,
64
+ [styles.disabled]: disabled,
65
+ [styles.empty]: !character,
64
66
  [styles.highlighted]: highlighted,
65
67
  [styles.invalid]: !isValid,
66
68
  [styles.raised]: raised,
@@ -77,12 +79,10 @@ const TilePure: FunctionComponent<Props> = ({
77
79
  autoComplete="off"
78
80
  autoCorrect="off"
79
81
  autoFocus={autoFocus}
80
- className={styles.character}
82
+ className={styles.input}
81
83
  disabled={disabled}
82
- placeholder={placeholder}
83
84
  ref={inputRef}
84
85
  spellCheck={false}
85
- style={inputStyle}
86
86
  tabIndex={tabIndex}
87
87
  value={character || ''}
88
88
  onChange={onChange}
@@ -90,6 +90,10 @@ const TilePure: FunctionComponent<Props> = ({
90
90
  onKeyDown={onKeyDown}
91
91
  />
92
92
 
93
+ <div className={styles.character} style={characterStyle} tabIndex={-1}>
94
+ {character || placeholder}
95
+ </div>
96
+
93
97
  {canShowPoints && (
94
98
  <span className={styles.points} style={pointsStyle}>
95
99
  {pointsFormatted}
@@ -18,7 +18,7 @@ $arrow-size: 4px;
18
18
  .arrow {
19
19
  bottom: -$arrow-size;
20
20
 
21
- &:after {
21
+ &::after {
22
22
  left: 0;
23
23
  bottom: 0;
24
24
  border-top-color: var(--tooltip--background);
@@ -31,7 +31,7 @@ $arrow-size: 4px;
31
31
  .arrow {
32
32
  left: -$arrow-size;
33
33
 
34
- &:after {
34
+ &::after {
35
35
  left: 0;
36
36
  top: 0;
37
37
  border-right-color: var(--tooltip--background);
@@ -44,7 +44,7 @@ $arrow-size: 4px;
44
44
  .arrow {
45
45
  top: -$arrow-size;
46
46
 
47
- &:after {
47
+ &::after {
48
48
  top: 0;
49
49
  left: 0;
50
50
  border-bottom-color: var(--tooltip--background);
@@ -57,7 +57,7 @@ $arrow-size: 4px;
57
57
  .arrow {
58
58
  right: -$arrow-size;
59
59
 
60
- &:after {
60
+ &::after {
61
61
  right: 0;
62
62
  top: 0;
63
63
  border-left-color: var(--tooltip--background);
@@ -72,7 +72,7 @@ $arrow-size: 4px;
72
72
  width: 2 * $arrow-size;
73
73
  height: 2 * $arrow-size;
74
74
 
75
- &:after {
75
+ &::after {
76
76
  content: ' ';
77
77
  position: absolute;
78
78
  height: 0;
@@ -16,7 +16,6 @@ export { default as PlainTiles } from './PlainTiles';
16
16
  export { default as Progress } from './Progress';
17
17
  export { default as Rack } from './Rack';
18
18
  export { default as Radio } from './Radio';
19
- export { default as ResultCandidatePicker } from './ResultCandidatePicker';
20
19
  export { default as Results } from './Results';
21
20
  export { default as ResultsInput } from './ResultsInput';
22
21
  export { default as Sizer } from './Sizer';
@@ -0,0 +1,4 @@
1
+ <!-- https://icons.getbootstrap.com/icons/chevron-left/ -->
2
+ <svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
3
+ <path d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z" fill="currentColor" fill-rule="evenodd" />
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <!-- https://icons.getbootstrap.com/icons/chevron-right/ -->
2
+ <svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
3
+ <path d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z" fill="currentColor" fill-rule="evenodd" />
4
+ </svg>
@@ -8,6 +8,8 @@ export { default as Check } from './Check.svg';
8
8
  export { default as CheckboxChecked } from './CheckboxChecked.svg';
9
9
  export { default as CheckboxEmpty } from './CheckboxEmpty.svg';
10
10
  export { default as ChevronDown } from './ChevronDown.svg';
11
+ export { default as ChevronLeft } from './ChevronLeft.svg';
12
+ export { default as ChevronRight } from './ChevronRight.svg';
11
13
  export { default as Cog } from './Cog.svg';
12
14
  export { default as Cross } from './Cross.svg';
13
15
  export { default as CrossCircleFill } from './CrossCircleFill.svg';
@@ -1,46 +1,10 @@
1
1
  @import 'styles/mixins';
2
2
 
3
3
  .button {
4
- @include button-reset;
5
- @include focus-effect;
6
-
7
4
  width: 100%;
8
- display: flex;
9
- align-items: flex-start;
10
- gap: var(--spacing--l);
11
- margin-bottom: var(--spacing--m);
12
- padding: var(--spacing--m);
13
- border: var(--border);
14
- border-radius: var(--border--radius);
15
- background-color: var(--color--background--overlay);
16
- transition: var(--transition);
17
- cursor: pointer;
5
+ text-transform: none;
18
6
 
19
- &:last-child {
20
- margin-bottom: 0;
7
+ & + & {
8
+ margin-top: var(--spacing--l);
21
9
  }
22
-
23
- &:focus,
24
- &:hover {
25
- text-decoration: none;
26
-
27
- .icon {
28
- color: var(--color--foreground--secondary);
29
- }
30
- }
31
- }
32
-
33
- .icon {
34
- $size: 24px;
35
-
36
- width: $size;
37
- height: $size;
38
- flex: 0 0 auto;
39
- color: var(--color--inactive);
40
- transition: var(--transition);
41
- }
42
-
43
- .content {
44
- flex: 1;
45
- text-align: left;
46
10
  }
@@ -1,6 +1,6 @@
1
1
  import { FunctionComponent } from 'react';
2
2
 
3
- import { Modal } from 'components';
3
+ import { Button, Modal } from 'components';
4
4
  import { CardChecklist, Cog, Github, Sack } from 'icons';
5
5
  import { GITHUB_PROJECT_URL } from 'parameters';
6
6
  import { useTranslate } from 'state';
@@ -28,25 +28,27 @@ const Menu: FunctionComponent<Props> = ({
28
28
 
29
29
  return (
30
30
  <Modal className={className} isOpen={isOpen} title={translate('menu')} onClose={onClose}>
31
- <button className={styles.button} onClick={onShowRemainingTiles}>
32
- <Sack className={styles.icon} />
33
- <div className={styles.content}>{translate('remaining-tiles')}</div>
34
- </button>
35
-
36
- <button className={styles.button} onClick={onShowWords}>
37
- <CardChecklist className={styles.icon} />
38
- <div className={styles.content}>{translate('words')}</div>
39
- </button>
40
-
41
- <a className={styles.button} href={GITHUB_PROJECT_URL} rel="noopener noreferrer" target="_blank">
42
- <Github className={styles.icon} />
43
- <div className={styles.content}>{translate('github')}</div>
44
- </a>
45
-
46
- <button className={styles.button} onClick={onShowSettings}>
47
- <Cog className={styles.icon} />
48
- <div className={styles.content}>{translate('settings')}</div>
49
- </button>
31
+ <Button className={styles.button} Icon={Sack} onClick={onShowRemainingTiles}>
32
+ {translate('remaining-tiles')}
33
+ </Button>
34
+
35
+ <Button className={styles.button} Icon={CardChecklist} onClick={onShowWords}>
36
+ {translate('words')}
37
+ </Button>
38
+
39
+ <Button.Link
40
+ className={styles.button}
41
+ href={GITHUB_PROJECT_URL}
42
+ Icon={Github}
43
+ rel="noopener noreferrer"
44
+ target="_blank"
45
+ >
46
+ {translate('github')}
47
+ </Button.Link>
48
+
49
+ <Button className={styles.button} Icon={Cog} onClick={onShowSettings}>
50
+ {translate('settings')}
51
+ </Button>
50
52
  </Modal>
51
53
  );
52
54
  };
@@ -12,7 +12,7 @@
12
12
  opacity: 1;
13
13
 
14
14
  .tile {
15
- &:after {
15
+ &::after {
16
16
  position: absolute;
17
17
  top: 0;
18
18
  left: 0;
@@ -25,7 +25,7 @@ const ResultsModal: FunctionComponent<Props> = ({ className, isOpen, onClose })
25
25
  const dispatch = useDispatch();
26
26
  const translate = useTranslate();
27
27
  const [sizerRef, { height, width }] = useMeasure<HTMLDivElement>();
28
- const isLessThanM = useMediaQuery('<m');
28
+ const isLessThanS = useMediaQuery('<s');
29
29
  const results = useTypedSelector(selectSortedFilteredResults);
30
30
  const resultCandidate = useTypedSelector(selectResultCandidate);
31
31
  const index = (results || []).findIndex((result) => result.id === resultCandidate?.id);
@@ -36,12 +36,12 @@ const ResultsModal: FunctionComponent<Props> = ({ className, isOpen, onClose })
36
36
  onClick: (result: Result) => {
37
37
  dispatch(resultsSlice.actions.changeResultCandidate(result));
38
38
 
39
- if (isLessThanM) {
39
+ if (isLessThanS) {
40
40
  onClose();
41
41
  }
42
42
  },
43
43
  }),
44
- [dispatch, isLessThanM, onClose],
44
+ [dispatch, isLessThanS, onClose],
45
45
  );
46
46
 
47
47
  return (
@@ -18,7 +18,7 @@ $media-expressions: (
18
18
  @mixin focus-effect {
19
19
  position: relative;
20
20
 
21
- &:after {
21
+ &::after {
22
22
  content: '';
23
23
  position: absolute;
24
24
  top: 0;
@@ -38,12 +38,18 @@ $media-expressions: (
38
38
  outline: none;
39
39
  }
40
40
 
41
- &:after {
41
+ &::after {
42
42
  box-shadow: 0 0 0 var(--box-shadow--focus--spread) var(--color--focus);
43
43
  }
44
44
  }
45
45
  }
46
46
 
47
+ @mixin disabled {
48
+ opacity: var(--opacity--disabled);
49
+ box-shadow: none;
50
+ cursor: not-allowed;
51
+ }
52
+
47
53
  @mixin ellipsis {
48
54
  display: block;
49
55
  text-overflow: ellipsis;
@@ -1 +0,0 @@
1
- self.__BUILD_MANIFEST=function(s,c,e){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[s,c,e,"static/css/dcca0c1a39cf5ef5.css","static/chunks/pages/index-d761f0af070273d2.js"],"/404":[s,c,e,"static/chunks/pages/404-6c99a0c91257c60b.js"],"/_error":["static/chunks/pages/_error-8353112a01355ec2.js"],sortedPages:["/","/404","/_app","/_error"]}}("static/chunks/490-d29992f1c264d70e.js","static/css/97eb6ee0c4300c83.css","static/chunks/528-9942ddad0031ff79.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();