@anmiles/theme-switcher 1.0.1 → 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.
- package/.nycrc.json +27 -0
- package/CHANGELOG.md +11 -2
- package/README.md +44 -44
- package/cspell.json +18 -0
- package/dist/theme-switcher-2.0.0.js +307 -0
- package/dist/theme-switcher-2.0.0.min.js +22 -0
- package/eslint.config.mts +16 -0
- package/index.html +38 -0
- package/jest.config.js +13 -15
- package/package.json +56 -36
- package/server.mjs +11 -0
- package/src/__tests__/index.test.tsx +10 -8
- package/src/__tests__/theme.test.ts +1 -1
- package/src/components/App.tsx +13 -11
- package/src/components/Icon.tsx +3 -1
- package/src/components/ThemeSelector.tsx +3 -2
- package/src/components/__tests__/App.test.tsx +47 -48
- package/src/components/__tests__/__snapshots__/App.test.tsx.snap +60 -20
- package/src/components/icons/Dark.tsx +0 -1
- package/src/index.tsx +4 -3
- package/src/lib/__tests__/eventEmitter.test.ts +6 -6
- package/src/lib/eventEmitter.ts +5 -7
- package/src/lib/theme.ts +7 -9
- package/src/providers/__tests__/systemProvider.test.ts +16 -16
- package/src/providers/__tests__/userProvider.test.ts +4 -4
- package/src/providers/systemProvider.ts +1 -3
- package/src/providers/userProvider.ts +1 -3
- package/static/development/index.html +39 -0
- package/static/production/index.html +39 -0
- package/tsconfig.json +7 -11
- package/tsconfig.test.json +1 -1
- package/vite.config.mts +54 -0
- package/.eslintignore +0 -2
- package/.eslintrc.js +0 -10
- package/.vscode/settings.json +0 -6
- package/coverage.config.js +0 -8
- package/dev/index.html +0 -35
- package/dist/theme-switcher-1.0.0.js +0 -2194
- package/dist/theme-switcher-1.0.0.min.js +0 -2
- package/dist/theme-switcher-1.0.0.min.js.LICENSE.txt +0 -9
- package/tsconfig.build.json +0 -7
- package/webpack.config.js +0 -67
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anmiles/theme-switcher",
|
|
3
|
-
"version": "
|
|
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": ">=
|
|
15
|
+
"node": ">=20.19.0"
|
|
16
16
|
},
|
|
17
17
|
"main": "src/index.tsx",
|
|
18
18
|
"scripts": {
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
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
|
|
28
|
-
"dev": "
|
|
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/
|
|
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": "^
|
|
37
|
-
"@anmiles/tsconfig": "^
|
|
38
|
-
"@
|
|
39
|
-
"@
|
|
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
|
|
42
|
-
"@types/jest": "^29.5.
|
|
43
|
-
"@types/react": "^18.3.
|
|
44
|
-
"@types/react-dom": "^18.3.
|
|
45
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
46
|
-
"@typescript-eslint/parser": "^
|
|
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": "^
|
|
49
|
-
"eslint-import-resolver-typescript": "^3.
|
|
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-
|
|
52
|
-
"eslint-plugin-
|
|
53
|
-
"eslint-plugin-
|
|
54
|
-
"eslint-plugin-n": "^
|
|
55
|
-
"eslint-plugin-promise": "^
|
|
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
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"react-refresh
|
|
61
|
-
"
|
|
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.
|
|
64
|
-
"ts-loader": "^9.5.
|
|
65
|
-
"typescript": "^5.
|
|
66
|
-
"
|
|
67
|
-
"
|
|
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
|
-
|
|
4
|
-
import
|
|
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
|
|
9
|
-
|
|
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
|
|
19
|
+
new Element({ float: 'left' }).render(parentNode);
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
const app = screen.getByTestId(testId);
|
|
23
|
+
|
|
24
|
+
expect(parentNode).toContainElement(app);
|
|
23
25
|
});
|
|
24
26
|
});
|
|
25
27
|
});
|
package/src/components/App.tsx
CHANGED
|
@@ -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 '../
|
|
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
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
}
|
package/src/components/Icon.tsx
CHANGED
|
@@ -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
|
|
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
|
|
8
|
-
readonly onListItemClick
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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/
|
|
19
|
-
|
|
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('
|
|
23
|
-
|
|
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
|
-
|
|
30
|
-
|
|
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
|
|
36
|
+
get: jest.fn().mockImplementation(() => userTheme),
|
|
34
37
|
|
|
35
|
-
set
|
|
38
|
+
set: jest.fn().mockImplementation((theme: Theme | undefined) => {
|
|
36
39
|
userEventEmitter['emit']('change', theme);
|
|
37
40
|
}),
|
|
38
41
|
|
|
39
|
-
on
|
|
40
|
-
off
|
|
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
|
|
45
|
-
watch
|
|
46
|
-
on
|
|
47
|
-
off
|
|
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.
|
|
51
|
-
|
|
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
|
-
|
|
55
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
37
|
+
<div
|
|
38
|
+
data-testid="mock-icon-system"
|
|
39
|
+
/>
|
|
32
40
|
<span>
|
|
33
41
|
System
|
|
34
42
|
</span>
|
|
35
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
75
|
+
<div
|
|
76
|
+
data-testid="mock-icon-dark"
|
|
77
|
+
/>
|
|
62
78
|
<span>
|
|
63
79
|
Dark
|
|
64
80
|
</span>
|
|
65
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
133
|
+
<div
|
|
134
|
+
data-testid="mock-icon-system"
|
|
135
|
+
/>
|
|
108
136
|
<span>
|
|
109
137
|
System
|
|
110
138
|
</span>
|
|
111
|
-
|
|
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
|
-
|
|
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
|
-
|
|
161
|
+
<div
|
|
162
|
+
data-testid="mock-icon-light"
|
|
163
|
+
/>
|
|
130
164
|
<span>
|
|
131
165
|
Light
|
|
132
166
|
</span>
|
|
133
|
-
|
|
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
|
-
|
|
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
|
-
|
|
184
|
+
<div
|
|
185
|
+
data-testid="mock-icon-system"
|
|
186
|
+
/>
|
|
147
187
|
<span>
|
|
148
188
|
System
|
|
149
189
|
</span>
|
package/src/index.tsx
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { StrictMode
|
|
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
|
|
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 {
|
|
21
|
+
export { App as ThemeSwitcher };
|