@anmiles/theme-switcher 1.0.2 → 2.0.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.
Files changed (42) hide show
  1. package/.nycrc.json +27 -0
  2. package/CHANGELOG.md +10 -1
  3. package/README.md +43 -43
  4. package/cspell.json +18 -0
  5. package/dist/theme-switcher-2.0.0.js +307 -0
  6. package/dist/theme-switcher-2.0.0.min.js +22 -0
  7. package/eslint.config.mts +16 -0
  8. package/index.html +38 -0
  9. package/jest.config.js +13 -15
  10. package/package.json +56 -36
  11. package/server.mjs +11 -0
  12. package/src/__tests__/index.test.tsx +10 -8
  13. package/src/__tests__/theme.test.ts +1 -1
  14. package/src/components/App.tsx +13 -11
  15. package/src/components/Icon.tsx +3 -1
  16. package/src/components/ThemeSelector.tsx +3 -2
  17. package/src/components/__tests__/App.test.tsx +47 -48
  18. package/src/components/__tests__/__snapshots__/App.test.tsx.snap +60 -20
  19. package/src/components/icons/Dark.tsx +0 -1
  20. package/src/index.tsx +4 -3
  21. package/src/lib/__tests__/eventEmitter.test.ts +6 -6
  22. package/src/lib/eventEmitter.ts +5 -7
  23. package/src/lib/theme.ts +7 -9
  24. package/src/providers/__tests__/systemProvider.test.ts +16 -16
  25. package/src/providers/__tests__/userProvider.test.ts +4 -4
  26. package/src/providers/systemProvider.ts +1 -3
  27. package/src/providers/userProvider.ts +1 -3
  28. package/static/development/index.html +39 -0
  29. package/static/production/index.html +39 -0
  30. package/tsconfig.json +7 -11
  31. package/tsconfig.test.json +1 -1
  32. package/vite.config.mts +54 -0
  33. package/.eslintignore +0 -2
  34. package/.eslintrc.js +0 -10
  35. package/.vscode/settings.json +0 -6
  36. package/coverage.config.js +0 -8
  37. package/dev/index.html +0 -35
  38. package/dist/theme-switcher-1.0.2.js +0 -2194
  39. package/dist/theme-switcher-1.0.2.min.js +0 -2
  40. package/dist/theme-switcher-1.0.2.min.js.LICENSE.txt +0 -9
  41. package/tsconfig.build.json +0 -7
  42. package/webpack.config.js +0 -67
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anmiles/theme-switcher",
3
- "version": "1.0.2",
3
+ "version": "2.0.0",
4
4
  "description": "Theme switcher for websites",
5
5
  "keywords": [
6
6
  "theme",
@@ -12,60 +12,80 @@
12
12
  "repository": "github:anmiles/theme-switcher",
13
13
  "license": "MIT",
14
14
  "engines": {
15
- "node": ">=18.18.0"
15
+ "node": ">=20.19.0"
16
16
  },
17
17
  "main": "src/index.tsx",
18
18
  "scripts": {
19
- "build": "rimraf dist && tsc -p ./tsconfig.build.json --noEmit && webpack --env mode=development && webpack --env mode=production",
20
- "lint": "eslint .",
21
- "lint:fix": "npm run lint -- --fix",
19
+ "spellcheck": "cspell .",
20
+ "prebuild": "rimraf dist && tsc --noEmit",
21
+ "build": "npm-run-all build:*",
22
+ "build:development": "vite build --mode development",
23
+ "build:production": "vite build --mode production",
24
+ "lint": "eslint",
25
+ "lint:fix": "eslint --fix",
22
26
  "test": "jest --verbose",
23
27
  "test:coverage": "npm test -- --coverage",
24
28
  "test:ci": "npm test -- --ci --coverage",
25
29
  "test:watch": "npm test -- --watch",
26
30
  "test:watch:coverage": "npm test -- --watch --coverage",
27
- "test:report:coverage": "nyc report --nycrc-path ./coverage.config.js -t ./coverage --report-dir ./coverage",
28
- "dev": "webpack serve --env mode=development --hot --open"
31
+ "test:report:coverage": "nyc report",
32
+ "dev": "vite --mode development",
33
+ "start": "node ./server.mjs",
34
+ "start:dev": "npm start development",
35
+ "start:prod": "npm start production"
29
36
  },
30
37
  "dependencies": {
31
- "@anmiles/logger": "^7.0.2",
38
+ "@anmiles/express-tools": "^1.0.0",
39
+ "@anmiles/logger": "^8.0.0",
40
+ "express": "^5.1.0",
41
+ "npm-run-all": "^4.1.5",
32
42
  "react": "^18.3.1",
33
43
  "react-dom": "^18.3.1"
34
44
  },
35
45
  "devDependencies": {
36
- "@anmiles/eslint-config": "^7.1.1",
37
- "@anmiles/tsconfig": "^3.0.1",
38
- "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
39
- "@stylistic/eslint-plugin": "^1.7.0",
46
+ "@anmiles/eslint-config": "^9.0.0",
47
+ "@anmiles/tsconfig": "^4.0.0",
48
+ "@eslint/compat": "^1.2.9",
49
+ "@eslint/css": "^0.8.1",
50
+ "@eslint/js": "^9.27.0",
51
+ "@eslint/json": "^0.12.0",
52
+ "@eslint/markdown": "^6.4.0",
53
+ "@stylistic/eslint-plugin": "^4.2.0",
54
+ "@testing-library/dom": "^10.4.0",
40
55
  "@testing-library/jest-dom": "^6.6.3",
41
- "@testing-library/react": "^16.0.1",
42
- "@types/jest": "^29.5.12",
43
- "@types/react": "^18.3.12",
44
- "@types/react-dom": "^18.3.1",
45
- "@typescript-eslint/eslint-plugin": "^7.3.1",
46
- "@typescript-eslint/parser": "^7.3.1",
56
+ "@testing-library/react": "^16.3.0",
57
+ "@types/jest": "^29.5.14",
58
+ "@types/react": "^18.3.20",
59
+ "@types/react-dom": "^18.3.6",
60
+ "@typescript-eslint/eslint-plugin": "^8.32.1",
61
+ "@typescript-eslint/parser": "^8.32.1",
62
+ "@vitejs/plugin-react": "^4.4.1",
63
+ "cspell": "^9.0.1",
47
64
  "css-loader": "^7.1.2",
48
- "eslint": "^8.57.0",
49
- "eslint-import-resolver-typescript": "^3.6.1",
65
+ "eslint": "^9.27.0",
66
+ "eslint-import-resolver-typescript": "^4.3.5",
50
67
  "eslint-plugin-align-assignments": "^1.1.2",
51
- "eslint-plugin-import": "^2.29.1",
52
- "eslint-plugin-jest": "^27.9.0",
53
- "eslint-plugin-jsonc": "^2.14.1",
54
- "eslint-plugin-n": "^16.6.2",
55
- "eslint-plugin-promise": "^6.1.1",
68
+ "eslint-plugin-i18next": "^6.1.1",
69
+ "eslint-plugin-import": "^2.31.0",
70
+ "eslint-plugin-jest": "^28.11.0",
71
+ "eslint-plugin-n": "^17.18.0",
72
+ "eslint-plugin-promise": "^7.2.1",
73
+ "eslint-plugin-react": "^7.37.5",
74
+ "eslint-plugin-react-hooks": "^5.2.0",
75
+ "eslint-plugin-react-redux": "^4.2.2",
76
+ "eslint-plugin-react-refresh": "^0.4.20",
56
77
  "jest": "^29.7.0",
57
78
  "jest-environment-jsdom": "^29.7.0",
58
- "nyc": "^15.1.0",
59
- "react-refresh": "^0.14.2",
60
- "react-refresh-typescript": "^2.0.9",
61
- "rimraf": "^5.0.5",
79
+ "jiti": "^2.4.2",
80
+ "nyc": "^17.1.0",
81
+ "react-refresh": "^0.17.0",
82
+ "react-refresh-typescript": "^2.0.10",
83
+ "rimraf": "^6.0.1",
62
84
  "style-loader": "^4.0.0",
63
- "ts-jest": "^29.1.2",
64
- "ts-loader": "^9.5.1",
65
- "typescript": "^5.4.2",
66
- "webpack": "^5.96.1",
67
- "webpack-cli": "^5.1.4",
68
- "webpack-dev-server": "^5.1.0",
69
- "webpack-merge": "^6.0.1"
85
+ "ts-jest": "^29.3.4",
86
+ "ts-loader": "^9.5.2",
87
+ "typescript": "^5.8.3",
88
+ "vite": "^6.3.5",
89
+ "vite-plugin-lib-inject-css": "^2.2.2"
70
90
  }
71
91
  }
package/server.mjs ADDED
@@ -0,0 +1,11 @@
1
+ import { startServer, stopServer } from '@anmiles/express-tools';
2
+ import express from 'express';
3
+
4
+ const mode = process.argv[2] === 'production'
5
+ ? 'production'
6
+ : 'development';
7
+
8
+ const app = express();
9
+ app.use(express.static('dist'));
10
+ app.use(express.static(`static/${mode}`));
11
+ startServer(app, { open: true }).catch(stopServer);
@@ -1,13 +1,13 @@
1
1
  import '@testing-library/jest-dom';
2
- import { act } from '@testing-library/react';
3
- import type App from '../components/App';
4
- import { ThemeSwitcherElement } from '../index';
2
+ import { act, screen } from '@testing-library/react';
3
+
4
+ import App from '../components/App';
5
+ import { Element } from '../index';
5
6
 
6
7
  const testId = 'app-test-id';
7
8
 
8
- jest.mock<typeof App>('../components/App', () => function App() {
9
- return <div>{ testId }</div>;
10
- });
9
+ jest.mock('../components/App');
10
+ jest.mocked(App).mockReturnValue(<div data-testid={ testId }></div>);
11
11
 
12
12
  describe('src/index', () => {
13
13
  describe('ThemeSwitcher', () => {
@@ -16,10 +16,12 @@ describe('src/index', () => {
16
16
  document.body.appendChild(parentNode);
17
17
 
18
18
  act(() => {
19
- new ThemeSwitcherElement({ float : 'left' }).render(parentNode);
19
+ new Element({ float: 'left' }).render(parentNode);
20
20
  });
21
21
 
22
- expect(parentNode.innerHTML).toEqual(`<div>${testId}</div>`);
22
+ const app = screen.getByTestId(testId);
23
+
24
+ expect(parentNode).toContainElement(app);
23
25
  });
24
26
  });
25
27
  });
@@ -1,4 +1,4 @@
1
- import { isTheme, getThemeName } from '../lib/theme';
1
+ import { getThemeName, isTheme } from '../lib/theme';
2
2
 
3
3
  describe('src/lib/theme', () => {
4
4
  describe('isTheme', () => {
@@ -1,14 +1,16 @@
1
+ import '../styles/style.css';
2
+
1
3
  import type { CSSProperties } from 'react';
2
4
  import { useEffect, useMemo, useState } from 'react';
3
5
 
4
- import { UserProvider } from '../providers/userProvider';
5
6
  import { SystemProvider } from '../providers/systemProvider';
6
- import '../styles/style.css';
7
+ import { UserProvider } from '../providers/userProvider';
8
+
7
9
  import Icon from './Icon';
8
10
  import ThemeSelector from './ThemeSelector';
9
11
 
10
12
  export interface AppProps {
11
- readonly float? : CSSProperties['float'];
13
+ readonly float?: CSSProperties['float'];
12
14
  }
13
15
 
14
16
  export default function App({ float }: AppProps) {
@@ -42,14 +44,14 @@ export default function App({ float }: AppProps) {
42
44
  { !showList
43
45
  ? null
44
46
  : (
45
- <ThemeSelector
46
- currentUserTheme={ userTheme }
47
- onListItemClick={ (theme) => {
48
- userProvider.set(theme);
49
- setShowList(false);
50
- } }
51
- />
52
- ) }
47
+ <ThemeSelector
48
+ currentUserTheme={ userTheme }
49
+ onListItemClick={ (theme) => {
50
+ userProvider.set(theme);
51
+ setShowList(false);
52
+ } }
53
+ />
54
+ ) }
53
55
  </div>
54
56
  );
55
57
  }
@@ -1,10 +1,11 @@
1
1
  import type { Theme } from '../lib/theme';
2
+
2
3
  import Dark from './icons/Dark';
3
4
  import Light from './icons/Light';
4
5
  import System from './icons/System';
5
6
 
6
7
  interface IconProps {
7
- readonly theme : Theme | undefined;
8
+ readonly theme: Theme | undefined;
8
9
  }
9
10
 
10
11
  export default function Icon({ theme }: IconProps) {
@@ -13,6 +14,7 @@ export default function Icon({ theme }: IconProps) {
13
14
  return <Light />;
14
15
  case 'dark':
15
16
  return <Dark />;
17
+ case undefined:
16
18
  default:
17
19
  return <System />;
18
20
  }
@@ -1,11 +1,12 @@
1
1
  import type { Theme } from '../lib/theme';
2
2
  import { getThemeName, themes } from '../lib/theme';
3
+
3
4
  import Icon from './Icon';
4
5
  import Checked from './icons/Checked';
5
6
 
6
7
  interface ThemeSelectorProps {
7
- readonly currentUserTheme : Theme | undefined;
8
- readonly onListItemClick : (theme: Theme | undefined) => void;
8
+ readonly currentUserTheme: Theme | undefined;
9
+ readonly onListItemClick: (theme: Theme | undefined)=> void;
9
10
  }
10
11
 
11
12
  export default function ThemeSelector({ currentUserTheme, onListItemClick }: ThemeSelectorProps) {
@@ -1,65 +1,64 @@
1
- import { render, screen, fireEvent, act } from '@testing-library/react';
2
- import type { UserProvider } from '../../providers/userProvider';
3
- import type { SystemProvider } from '../../providers/systemProvider';
4
- import type { AppProps } from '../App';
5
- import App from '../App';
6
- import { EventEmitter } from '../../lib/eventEmitter';
7
- import type { Theme } from '../../lib/theme';
8
1
  import '@testing-library/jest-dom';
2
+ import { act, fireEvent, render, screen } from '@testing-library/react';
9
3
 
10
- jest.mock('../icons/Checked.tsx', () => function Checked() {
11
- return '{checked}';
12
- });
13
-
14
- jest.mock('../icons/Dark.tsx', () => function Dark() {
15
- return '{dark}';
16
- });
4
+ import { EventEmitter } from '../../lib/eventEmitter';
5
+ import type { Theme } from '../../lib/theme';
6
+ import { SystemProvider } from '../../providers/systemProvider';
7
+ import { UserProvider } from '../../providers/userProvider';
8
+ import type { AppProps } from '../App';
9
+ import App from '../App';
10
+ import Checked from '../icons/Checked';
11
+ import Dark from '../icons/Dark';
12
+ import Light from '../icons/Light';
13
+ import System from '../icons/System';
17
14
 
18
- jest.mock('../icons/Light.tsx', () => function Light() {
19
- return '{light}';
20
- });
15
+ jest.mock('../icons/Checked');
16
+ jest.mock('../icons/Dark');
17
+ jest.mock('../icons/Light');
18
+ jest.mock('../icons/System');
21
19
 
22
- jest.mock('../icons/System.tsx', () => function System() {
23
- return '{system}';
24
- });
20
+ jest.mock('../../providers/userProvider');
21
+ jest.mock('../../providers/systemProvider');
25
22
 
26
23
  let userTheme: Theme | undefined;
27
24
  let systemTheme: Theme;
28
25
 
29
- const userEventEmitter = new EventEmitter<{ change : [Theme | undefined] }>();
30
- const systemEventEmitter = new EventEmitter<{ change : [Theme | undefined] }>();
26
+ function renderApp({ float }: AppProps) {
27
+ render(
28
+ <App float={ float } />,
29
+ );
30
+ }
31
+
32
+ const userEventEmitter = new EventEmitter<{ change: [Theme | undefined] }>();
33
+ const systemEventEmitter = new EventEmitter<{ change: [Theme | undefined] }>();
31
34
 
32
35
  const userProvider: Partial<InstanceType<typeof UserProvider>> = {
33
- get : jest.fn().mockImplementation(() => userTheme),
36
+ get: jest.fn().mockImplementation(() => userTheme),
34
37
 
35
- set : jest.fn().mockImplementation((theme: Theme | undefined) => {
38
+ set: jest.fn().mockImplementation((theme: Theme | undefined) => {
36
39
  userEventEmitter['emit']('change', theme);
37
40
  }),
38
41
 
39
- on : jest.fn().mockImplementation(userEventEmitter.on.bind(userEventEmitter)),
40
- off : jest.fn().mockImplementation(userEventEmitter.off.bind(userEventEmitter)),
42
+ on : jest.fn().mockImplementation(userEventEmitter.on.bind(userEventEmitter)),
43
+ off: jest.fn().mockImplementation(userEventEmitter.off.bind(userEventEmitter)),
41
44
  };
42
45
 
43
46
  const systemProvider: Partial<InstanceType<typeof SystemProvider>> = {
44
- get : jest.fn().mockImplementation(() => systemTheme),
45
- watch : jest.fn(),
46
- on : jest.fn().mockImplementation(systemEventEmitter.on.bind(systemEventEmitter)),
47
- off : jest.fn().mockImplementation(systemEventEmitter.on.bind(systemEventEmitter)),
47
+ get : jest.fn().mockImplementation(() => systemTheme),
48
+ watch: jest.fn(),
49
+ on : jest.fn().mockImplementation(systemEventEmitter.on.bind(systemEventEmitter)),
50
+ off : jest.fn().mockImplementation(systemEventEmitter.on.bind(systemEventEmitter)),
48
51
  };
49
52
 
50
- jest.mock<{ UserProvider : typeof UserProvider }>('../../providers/userProvider', () => ({
51
- UserProvider : jest.fn().mockImplementation(() => userProvider),
52
- }));
53
+ jest.mocked(Checked).mockReturnValue(<div data-testid="mock-icon-checked" />);
54
+ jest.mocked(Dark).mockReturnValue(<div data-testid="mock-icon-dark" />);
55
+ jest.mocked(Light).mockReturnValue(<div data-testid="mock-icon-light" />);
56
+ jest.mocked(System).mockReturnValue(<div data-testid="mock-icon-system" />);
53
57
 
54
- jest.mock<{ SystemProvider : typeof SystemProvider }>('../../providers/systemProvider', () => ({
55
- SystemProvider : jest.fn().mockImplementation(() => systemProvider),
56
- }));
57
-
58
- function renderApp({ float }: AppProps) {
59
- render(
60
- <App float={ float } />,
61
- );
62
- }
58
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
59
+ jest.mocked(UserProvider).mockImplementation(() => userProvider as UserProvider);
60
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
61
+ jest.mocked(SystemProvider).mockImplementation(() => systemProvider as SystemProvider);
63
62
 
64
63
  afterEach(() => {
65
64
  document.body.removeAttribute('data-theme');
@@ -198,7 +197,7 @@ describe('src/App', () => {
198
197
  renderApp({});
199
198
 
200
199
  const themeSwitcher = screen.getByTestId('theme-switcher');
201
- expect(themeSwitcher.innerHTML).toEqual('{light}');
200
+ expect(themeSwitcher).toContainElement(screen.getByTestId('mock-icon-light'));
202
201
  });
203
202
 
204
203
  it('should match dark system theme if user theme is not defined', () => {
@@ -208,7 +207,7 @@ describe('src/App', () => {
208
207
  renderApp({});
209
208
 
210
209
  const themeSwitcher = screen.getByTestId('theme-switcher');
211
- expect(themeSwitcher.innerHTML).toEqual('{dark}');
210
+ expect(themeSwitcher).toContainElement(screen.getByTestId('mock-icon-dark'));
212
211
  });
213
212
 
214
213
  it('should match light user theme despite of system theme', () => {
@@ -218,7 +217,7 @@ describe('src/App', () => {
218
217
  renderApp({});
219
218
 
220
219
  const themeSwitcher = screen.getByTestId('theme-switcher');
221
- expect(themeSwitcher.innerHTML).toEqual('{light}');
220
+ expect(themeSwitcher).toContainElement(screen.getByTestId('mock-icon-light'));
222
221
  });
223
222
 
224
223
  it('should match dark user theme despite of system theme', () => {
@@ -228,7 +227,7 @@ describe('src/App', () => {
228
227
  renderApp({});
229
228
 
230
229
  const themeSwitcher = screen.getByTestId('theme-switcher');
231
- expect(themeSwitcher.innerHTML).toEqual('{dark}');
230
+ expect(themeSwitcher).toContainElement(screen.getByTestId('mock-icon-dark'));
232
231
  });
233
232
  });
234
233
 
@@ -278,14 +277,14 @@ describe('src/App', () => {
278
277
 
279
278
  describe('data-float', () => {
280
279
  it('should be set left from float prop', () => {
281
- renderApp({ float : 'left' });
280
+ renderApp({ float: 'left' });
282
281
 
283
282
  const themeSwitcher = screen.getByTestId('theme-switcher');
284
283
  expect(themeSwitcher.getAttribute('data-float')).toEqual('left');
285
284
  });
286
285
 
287
286
  it('should be set right from float prop', () => {
288
- renderApp({ float : 'right' });
287
+ renderApp({ float: 'right' });
289
288
 
290
289
  const themeSwitcher = screen.getByTestId('theme-switcher');
291
290
  expect(themeSwitcher.getAttribute('data-float')).toEqual('right');
@@ -5,14 +5,18 @@ exports[`src/App switcher html should match snapshot on dark system theme 1`] =
5
5
  class="themeSwitcher"
6
6
  data-testid="theme-switcher"
7
7
  >
8
- {light}
8
+ <div
9
+ data-testid="mock-icon-light"
10
+ />
9
11
  <ul
10
12
  data-testid="theme-selector"
11
13
  >
12
14
  <li
13
15
  data-testid="theme-item-light"
14
16
  >
15
- {light}
17
+ <div
18
+ data-testid="mock-icon-light"
19
+ />
16
20
  <span>
17
21
  Light
18
22
  </span>
@@ -20,7 +24,9 @@ exports[`src/App switcher html should match snapshot on dark system theme 1`] =
20
24
  <li
21
25
  data-testid="theme-item-dark"
22
26
  >
23
- {dark}
27
+ <div
28
+ data-testid="mock-icon-dark"
29
+ />
24
30
  <span>
25
31
  Dark
26
32
  </span>
@@ -28,11 +34,15 @@ exports[`src/App switcher html should match snapshot on dark system theme 1`] =
28
34
  <li
29
35
  data-testid="theme-item-system"
30
36
  >
31
- {system}
37
+ <div
38
+ data-testid="mock-icon-system"
39
+ />
32
40
  <span>
33
41
  System
34
42
  </span>
35
- {checked}
43
+ <div
44
+ data-testid="mock-icon-checked"
45
+ />
36
46
  </li>
37
47
  </ul>
38
48
  </div>
@@ -43,14 +53,18 @@ exports[`src/App switcher html should match snapshot on dark user theme 1`] = `
43
53
  class="themeSwitcher"
44
54
  data-testid="theme-switcher"
45
55
  >
46
- {dark}
56
+ <div
57
+ data-testid="mock-icon-dark"
58
+ />
47
59
  <ul
48
60
  data-testid="theme-selector"
49
61
  >
50
62
  <li
51
63
  data-testid="theme-item-light"
52
64
  >
53
- {light}
65
+ <div
66
+ data-testid="mock-icon-light"
67
+ />
54
68
  <span>
55
69
  Light
56
70
  </span>
@@ -58,16 +72,22 @@ exports[`src/App switcher html should match snapshot on dark user theme 1`] = `
58
72
  <li
59
73
  data-testid="theme-item-dark"
60
74
  >
61
- {dark}
75
+ <div
76
+ data-testid="mock-icon-dark"
77
+ />
62
78
  <span>
63
79
  Dark
64
80
  </span>
65
- {checked}
81
+ <div
82
+ data-testid="mock-icon-checked"
83
+ />
66
84
  </li>
67
85
  <li
68
86
  data-testid="theme-item-system"
69
87
  >
70
- {system}
88
+ <div
89
+ data-testid="mock-icon-system"
90
+ />
71
91
  <span>
72
92
  System
73
93
  </span>
@@ -81,14 +101,18 @@ exports[`src/App switcher html should match snapshot on light system theme 1`] =
81
101
  class="themeSwitcher"
82
102
  data-testid="theme-switcher"
83
103
  >
84
- {light}
104
+ <div
105
+ data-testid="mock-icon-light"
106
+ />
85
107
  <ul
86
108
  data-testid="theme-selector"
87
109
  >
88
110
  <li
89
111
  data-testid="theme-item-light"
90
112
  >
91
- {light}
113
+ <div
114
+ data-testid="mock-icon-light"
115
+ />
92
116
  <span>
93
117
  Light
94
118
  </span>
@@ -96,7 +120,9 @@ exports[`src/App switcher html should match snapshot on light system theme 1`] =
96
120
  <li
97
121
  data-testid="theme-item-dark"
98
122
  >
99
- {dark}
123
+ <div
124
+ data-testid="mock-icon-dark"
125
+ />
100
126
  <span>
101
127
  Dark
102
128
  </span>
@@ -104,11 +130,15 @@ exports[`src/App switcher html should match snapshot on light system theme 1`] =
104
130
  <li
105
131
  data-testid="theme-item-system"
106
132
  >
107
- {system}
133
+ <div
134
+ data-testid="mock-icon-system"
135
+ />
108
136
  <span>
109
137
  System
110
138
  </span>
111
- {checked}
139
+ <div
140
+ data-testid="mock-icon-checked"
141
+ />
112
142
  </li>
113
143
  </ul>
114
144
  </div>
@@ -119,23 +149,31 @@ exports[`src/App switcher html should match snapshot on light user theme 1`] = `
119
149
  class="themeSwitcher"
120
150
  data-testid="theme-switcher"
121
151
  >
122
- {light}
152
+ <div
153
+ data-testid="mock-icon-light"
154
+ />
123
155
  <ul
124
156
  data-testid="theme-selector"
125
157
  >
126
158
  <li
127
159
  data-testid="theme-item-light"
128
160
  >
129
- {light}
161
+ <div
162
+ data-testid="mock-icon-light"
163
+ />
130
164
  <span>
131
165
  Light
132
166
  </span>
133
- {checked}
167
+ <div
168
+ data-testid="mock-icon-checked"
169
+ />
134
170
  </li>
135
171
  <li
136
172
  data-testid="theme-item-dark"
137
173
  >
138
- {dark}
174
+ <div
175
+ data-testid="mock-icon-dark"
176
+ />
139
177
  <span>
140
178
  Dark
141
179
  </span>
@@ -143,7 +181,9 @@ exports[`src/App switcher html should match snapshot on light user theme 1`] = `
143
181
  <li
144
182
  data-testid="theme-item-system"
145
183
  >
146
- {system}
184
+ <div
185
+ data-testid="mock-icon-system"
186
+ />
147
187
  <span>
148
188
  System
149
189
  </span>
@@ -8,6 +8,5 @@ export default function Dark() {
8
8
  <circle cx="50" cy="50" r="46" strokeDasharray="180" transform="rotate(22.5 50 50)" />
9
9
  <circle cx="75" cy="25" r="46" strokeDasharray="108 200" transform="rotate(67.5 75 25)" />
10
10
  </svg>
11
-
12
11
  );
13
12
  }
package/src/index.tsx CHANGED
@@ -1,9 +1,10 @@
1
- import { StrictMode } from 'react';
1
+ import { StrictMode } from 'react';
2
2
  import { createRoot } from 'react-dom/client';
3
+
3
4
  import type { AppProps } from './components/App';
4
5
  import App from './components/App';
5
6
 
6
- class ThemeSwitcherElement {
7
+ export class Element {
7
8
  constructor(private readonly props: AppProps) {}
8
9
 
9
10
  public render(parentNode: HTMLElement) {
@@ -17,4 +18,4 @@ class ThemeSwitcherElement {
17
18
  }
18
19
  }
19
20
 
20
- export { ThemeSwitcherElement, App as ThemeSwitcher };
21
+ export { App as ThemeSwitcher };