@epic-effx/create-application-template-rs 0.1.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/.babelrc +14 -0
- package/.browserslistrc +3 -0
- package/.codex +0 -0
- package/.eslintrc.js +309 -0
- package/.husky/pre-commit +5 -0
- package/.stylelintrc.js +29 -0
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/bin/create-application-template-rs.js +116 -0
- package/jest/cssTransform.js +13 -0
- package/jest/fontTransform.js +12 -0
- package/jest/setup.js +5 -0
- package/jest/setupTests.js +15 -0
- package/jest/svgTransform.js +12 -0
- package/jest.config.js +58 -0
- package/package.json +117 -0
- package/rspack/rspack.common.js +212 -0
- package/rspack/rspack.config.js +14 -0
- package/rspack/rspack.dev.js +36 -0
- package/rspack/rspack.prod.js +43 -0
- package/rspack/utilities/createEnvironmentHash.js +8 -0
- package/rspack/utilities/env.js +8 -0
- package/rspack/utilities/generateAssetManifest.js +16 -0
- package/rspack/utilities/getPaths.js +57 -0
- package/rspack/utilities/getTerserOptions.js +47 -0
- package/scripts/generate-sitemap.ts +25 -0
- package/src/app.d.ts +7 -0
- package/src/assets/favicon.ico +0 -0
- package/src/assets/logo.svg +15 -0
- package/src/components/App.spec.tsx +24 -0
- package/src/components/App.tsx +66 -0
- package/src/components/Counter.spec.tsx +38 -0
- package/src/components/Counter.tsx +26 -0
- package/src/components/Typewriter.spec.tsx +36 -0
- package/src/components/Typewriter.tsx +66 -0
- package/src/components/__snapshots__/App.spec.tsx.snap +56 -0
- package/src/components/__snapshots__/Counter.spec.tsx.snap +44 -0
- package/src/components/__snapshots__/Typewriter.spec.tsx.snap +56 -0
- package/src/fonts/Exo2-Regular.woff2 +0 -0
- package/src/fonts/Orbitron-Regular.woff2 +0 -0
- package/src/index.html +18 -0
- package/src/index.tsx +12 -0
- package/src/public/robots.txt +6 -0
- package/src/styles/App.styled.ts +42 -0
- package/src/styles/Counter.styled.ts +30 -0
- package/src/styles/Global.ts +18 -0
- package/src/styles/Logo.styled.ts +24 -0
- package/src/styles/Typewriter.styled.ts +5 -0
- package/src/styles/env.css +11 -0
- package/src/styles/theme.ts +21 -0
- package/tsconfig.json +31 -0
package/src/app.d.ts
ADDED
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
2
|
+
<svg height="800px" width="800px" version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" xml:space="preserve" fill="#fd05a0">
|
|
3
|
+
<g id="bgCarrier" stroke-width="0"/>
|
|
4
|
+
<g id="tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
<g id="iconCarrier">
|
|
6
|
+
<style type="text/css"> .st0{fill:#fd05a0;}</style>
|
|
7
|
+
<g>
|
|
8
|
+
<path class="st0" d="M430.762,126.907c-42.384-89.329-67.753-89.329-78.722-89.329c-1.947,0-3.884,0.167-5.785,0.482 c-18.1,3.014-41.374,22.031-69.302,56.579h-20.955h-20.974c-27.909-34.548-51.202-53.566-69.301-56.579 c-1.891-0.315-3.829-0.482-5.758-0.482h-0.25c-11.108,0-36.412,0.649-78.499,89.329C34.188,164.608-32.49,256.506,18.091,366.094 c49.996,108.328,191.425,108.328,237.907,108.328c46.472,0,187.911,0,237.907-108.318 C544.495,256.506,477.809,164.608,430.762,126.907z M468.055,354.161c-41.15,89.134-161.411,91.776-212.056,91.776 c-50.626,0-170.906-2.642-212.038-91.776c-56.969-123.432,60.121-208.886,60.121-208.886s36.551-79.213,55.875-79.213l1.094,0.093 c18.99,3.162,60.14,56.969,60.14,56.969h34.808h34.808c0,0,41.15-53.807,60.14-56.969l1.094-0.093 c19.305,0,55.875,79.213,55.875,79.213S525.024,230.729,468.055,354.161z"/>
|
|
9
|
+
<path class="st0" d="M146.011,241.809c0,13.983,11.349,25.323,25.332,25.323c13.982,0,25.313-11.34,25.313-25.323 c0-13.983-11.331-25.322-25.313-25.322C157.36,216.487,146.011,227.826,146.011,241.809z"/>
|
|
10
|
+
<ellipse class="st0" cx="171.343" cy="241.809" rx="6" ry="25" style="fill:#081e28"/>
|
|
11
|
+
<path class="st0" d="M340.663,267.132c13.982,0,25.323-11.34,25.323-25.323c0-13.983-11.341-25.322-25.323-25.322 c-13.983,0-25.322,11.34-25.322,25.322C315.341,255.792,326.68,267.132,340.663,267.132z"/>
|
|
12
|
+
<ellipse class="st0" cx="340.663" cy="241.809" rx="6" ry="25" style="fill:#081e28"/>
|
|
13
|
+
</g>
|
|
14
|
+
</g>
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { render, screen, act } from '@testing-library/react'
|
|
2
|
+
import 'jest-styled-components'
|
|
3
|
+
import { App } from './App'
|
|
4
|
+
|
|
5
|
+
jest.useFakeTimers()
|
|
6
|
+
|
|
7
|
+
test('renders title', () => {
|
|
8
|
+
render(<App />)
|
|
9
|
+
|
|
10
|
+
const text = 'Create Application Template RS'
|
|
11
|
+
|
|
12
|
+
for (let i = 1; i <= text.length; i++) {
|
|
13
|
+
act(() => {
|
|
14
|
+
jest.advanceTimersByTime(50)
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
expect(screen).toMatchSnapshot()
|
|
19
|
+
expect(screen.getByText(text)).toBeInTheDocument()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
jest.useRealTimers()
|
|
24
|
+
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { FC } from 'react'
|
|
2
|
+
import { ThemeProvider } from 'styled-components'
|
|
3
|
+
import GlobalStyles from '../styles/Global'
|
|
4
|
+
import theme from '../styles/theme'
|
|
5
|
+
import * as app from '../styles/App.styled'
|
|
6
|
+
import { StyledLogo } from '../styles/Logo.styled'
|
|
7
|
+
import '../styles/env.css'
|
|
8
|
+
import logo from '../assets/logo.svg'
|
|
9
|
+
import { Counter } from './Counter'
|
|
10
|
+
import { Typewriter } from './Typewriter'
|
|
11
|
+
|
|
12
|
+
const TemplateLink: FC = () => {
|
|
13
|
+
return (
|
|
14
|
+
<app.StyledLink
|
|
15
|
+
href='https://www.npmjs.com/package/@epic-effx/create-application-template'
|
|
16
|
+
rel='noreferrer'
|
|
17
|
+
target='_blank'
|
|
18
|
+
>
|
|
19
|
+
here
|
|
20
|
+
</app.StyledLink>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const App: FC = () => {
|
|
25
|
+
return (
|
|
26
|
+
<ThemeProvider theme={theme}>
|
|
27
|
+
<GlobalStyles />
|
|
28
|
+
<app.StyledContainer>
|
|
29
|
+
<app.StyledHeader>
|
|
30
|
+
<h1>
|
|
31
|
+
<Typewriter
|
|
32
|
+
text={'Create Application Template RS'}
|
|
33
|
+
speed={50}
|
|
34
|
+
/>
|
|
35
|
+
</h1>
|
|
36
|
+
<h2>
|
|
37
|
+
<Typewriter
|
|
38
|
+
text={'Configured and under your control!'}
|
|
39
|
+
speed={50}
|
|
40
|
+
delay={300}
|
|
41
|
+
/>
|
|
42
|
+
</h2>
|
|
43
|
+
<h2>
|
|
44
|
+
<Typewriter
|
|
45
|
+
text={'Access the template'}
|
|
46
|
+
speed={50}
|
|
47
|
+
delay={1300}
|
|
48
|
+
>
|
|
49
|
+
<TemplateLink />
|
|
50
|
+
</Typewriter>
|
|
51
|
+
</h2>
|
|
52
|
+
</app.StyledHeader>
|
|
53
|
+
<app.StyledSection>
|
|
54
|
+
<code className='card--env'>[NODE_ENV={process.env.NODE_ENV}]</code>
|
|
55
|
+
<code className='card--env'>[EXAMPLE={process.env.EXAMPLE}]</code>
|
|
56
|
+
</app.StyledSection>
|
|
57
|
+
<app.StyledSection>
|
|
58
|
+
<StyledLogo src={logo} alt='logo'/>
|
|
59
|
+
</app.StyledSection>
|
|
60
|
+
<app.StyledSection>
|
|
61
|
+
<Counter />
|
|
62
|
+
</app.StyledSection>
|
|
63
|
+
</app.StyledContainer>
|
|
64
|
+
</ThemeProvider>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react'
|
|
2
|
+
import 'jest-styled-components'
|
|
3
|
+
import { userEvent } from '@testing-library/user-event'
|
|
4
|
+
import { ThemeProvider } from 'styled-components'
|
|
5
|
+
import theme from '../styles/theme'
|
|
6
|
+
import { Counter } from './Counter'
|
|
7
|
+
|
|
8
|
+
test('count increases per click', async () => {
|
|
9
|
+
render(
|
|
10
|
+
<ThemeProvider theme={theme}>
|
|
11
|
+
<Counter />
|
|
12
|
+
</ThemeProvider>
|
|
13
|
+
)
|
|
14
|
+
const button = screen.getByTestId('count')
|
|
15
|
+
|
|
16
|
+
const user = userEvent.setup()
|
|
17
|
+
await user.click(button)
|
|
18
|
+
const results = button.innerHTML.match(/\d/g)
|
|
19
|
+
|
|
20
|
+
expect(results).toBeArrayOfSize(1)
|
|
21
|
+
expect(results).toIncludeAllMembers(['1'])
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
test('styled with palette colors', async() => {
|
|
26
|
+
render(
|
|
27
|
+
<ThemeProvider theme={theme}>
|
|
28
|
+
<Counter />
|
|
29
|
+
</ThemeProvider>
|
|
30
|
+
)
|
|
31
|
+
const button = await screen.findByRole('button', { name: /count/i })
|
|
32
|
+
|
|
33
|
+
const { primary, background } = theme.colors.palette
|
|
34
|
+
|
|
35
|
+
expect(button).toMatchSnapshot()
|
|
36
|
+
expect(button).toHaveStyleRule('color', primary)
|
|
37
|
+
expect(button).toHaveStyleRule('background-color', background)
|
|
38
|
+
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FC, useState } from 'react'
|
|
2
|
+
import * as styledCount from '../styles/Counter.styled'
|
|
3
|
+
|
|
4
|
+
// NOTE update count then edit App.tsx... thanks
|
|
5
|
+
// to ReactRefreshWebpackPlugin state is preserved
|
|
6
|
+
|
|
7
|
+
type Count = number
|
|
8
|
+
|
|
9
|
+
export const Counter: FC = () => {
|
|
10
|
+
const [count, setCount] = useState<Count>(0)
|
|
11
|
+
|
|
12
|
+
const handleClickCounter = () => setCount((count: Count) => ++count)
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div>
|
|
16
|
+
<styledCount.StyledCounter onClick={handleClickCounter}>
|
|
17
|
+
<>count: </>
|
|
18
|
+
<styledCount.StyledCount
|
|
19
|
+
data-testid='count'
|
|
20
|
+
>
|
|
21
|
+
{count}
|
|
22
|
+
</styledCount.StyledCount>
|
|
23
|
+
</styledCount.StyledCounter>
|
|
24
|
+
</div>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { render, screen, act } from '@testing-library/react'
|
|
2
|
+
import 'jest-styled-components'
|
|
3
|
+
import { Typewriter } from './Typewriter'
|
|
4
|
+
|
|
5
|
+
jest.useFakeTimers()
|
|
6
|
+
|
|
7
|
+
test('renders text and children', () => {
|
|
8
|
+
const text = 'testing'
|
|
9
|
+
|
|
10
|
+
render(
|
|
11
|
+
<Typewriter
|
|
12
|
+
text={text}
|
|
13
|
+
speed={50}
|
|
14
|
+
>
|
|
15
|
+
<div data-testid='child-element'>child</div>
|
|
16
|
+
</Typewriter>
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
for (let i = 1; i <= text.length; i++) {
|
|
20
|
+
// full text available only after all
|
|
21
|
+
// timeouts complete, see Typewriter.tsx
|
|
22
|
+
act(() => {
|
|
23
|
+
jest.advanceTimersByTime(50)
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
expect(screen).toMatchSnapshot()
|
|
28
|
+
expect(screen.getByText(text)).toBeInTheDocument()
|
|
29
|
+
expect(screen.getByTestId('child-element')).toBeInTheDocument()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
// reset real timers so other tests
|
|
34
|
+
// are not affected by mock timers
|
|
35
|
+
jest.useRealTimers()
|
|
36
|
+
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useState,
|
|
3
|
+
useEffect,
|
|
4
|
+
FC,
|
|
5
|
+
ReactElement,
|
|
6
|
+
PropsWithChildren,
|
|
7
|
+
} from 'react'
|
|
8
|
+
import { StyledText } from '../styles/Typewriter.styled'
|
|
9
|
+
|
|
10
|
+
export const Typewriter: FC<
|
|
11
|
+
PropsWithChildren<{
|
|
12
|
+
text:string,
|
|
13
|
+
speed:number,
|
|
14
|
+
delay?:number,
|
|
15
|
+
children?:ReactElement,
|
|
16
|
+
}>
|
|
17
|
+
> = ({
|
|
18
|
+
text,
|
|
19
|
+
speed,
|
|
20
|
+
delay = 0,
|
|
21
|
+
children,
|
|
22
|
+
}) => {
|
|
23
|
+
const [displayedText, setDisplayedText] = useState('')
|
|
24
|
+
const [currentIndex, setCurrentIndex] = useState(0)
|
|
25
|
+
|
|
26
|
+
// NOTE: supports hot reload behavior in development:
|
|
27
|
+
// A) when the `text` prop changes (e.g. via hot reload), reset internal state
|
|
28
|
+
// B) this triggers the typing animation effect to restart with the new text
|
|
29
|
+
|
|
30
|
+
useEffect(() => { // A
|
|
31
|
+
const timeoutIdInit = setTimeout(() => {
|
|
32
|
+
setDisplayedText('')
|
|
33
|
+
setCurrentIndex(0)
|
|
34
|
+
}, 0)
|
|
35
|
+
|
|
36
|
+
return () => clearTimeout(timeoutIdInit)
|
|
37
|
+
}, [text])
|
|
38
|
+
|
|
39
|
+
useEffect(() => { // B
|
|
40
|
+
const mySpeed = (currentIndex === 0) ? delay + speed : speed
|
|
41
|
+
|
|
42
|
+
if (currentIndex < text.length) {
|
|
43
|
+
const timeoutId = setTimeout(() => {
|
|
44
|
+
setDisplayedText((prevText) => prevText + text.charAt(currentIndex))
|
|
45
|
+
setCurrentIndex((prevIndex) => prevIndex + 1)
|
|
46
|
+
}, mySpeed)
|
|
47
|
+
|
|
48
|
+
return () => clearTimeout(timeoutId)
|
|
49
|
+
}
|
|
50
|
+
}, [
|
|
51
|
+
currentIndex,
|
|
52
|
+
text,
|
|
53
|
+
speed,
|
|
54
|
+
delay,
|
|
55
|
+
])
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<StyledText>
|
|
59
|
+
{displayedText}
|
|
60
|
+
{
|
|
61
|
+
(currentIndex === text.length && children) &&
|
|
62
|
+
<> {children}</>
|
|
63
|
+
}
|
|
64
|
+
</StyledText>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
|
2
|
+
|
|
3
|
+
exports[`renders title 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"debug": [Function],
|
|
6
|
+
"findAllByAltText": [Function],
|
|
7
|
+
"findAllByDisplayValue": [Function],
|
|
8
|
+
"findAllByLabelText": [Function],
|
|
9
|
+
"findAllByPlaceholderText": [Function],
|
|
10
|
+
"findAllByRole": [Function],
|
|
11
|
+
"findAllByTestId": [Function],
|
|
12
|
+
"findAllByText": [Function],
|
|
13
|
+
"findAllByTitle": [Function],
|
|
14
|
+
"findByAltText": [Function],
|
|
15
|
+
"findByDisplayValue": [Function],
|
|
16
|
+
"findByLabelText": [Function],
|
|
17
|
+
"findByPlaceholderText": [Function],
|
|
18
|
+
"findByRole": [Function],
|
|
19
|
+
"findByTestId": [Function],
|
|
20
|
+
"findByText": [Function],
|
|
21
|
+
"findByTitle": [Function],
|
|
22
|
+
"getAllByAltText": [Function],
|
|
23
|
+
"getAllByDisplayValue": [Function],
|
|
24
|
+
"getAllByLabelText": [Function],
|
|
25
|
+
"getAllByPlaceholderText": [Function],
|
|
26
|
+
"getAllByRole": [Function],
|
|
27
|
+
"getAllByTestId": [Function],
|
|
28
|
+
"getAllByText": [Function],
|
|
29
|
+
"getAllByTitle": [Function],
|
|
30
|
+
"getByAltText": [Function],
|
|
31
|
+
"getByDisplayValue": [Function],
|
|
32
|
+
"getByLabelText": [Function],
|
|
33
|
+
"getByPlaceholderText": [Function],
|
|
34
|
+
"getByRole": [Function],
|
|
35
|
+
"getByTestId": [Function],
|
|
36
|
+
"getByText": [Function],
|
|
37
|
+
"getByTitle": [Function],
|
|
38
|
+
"logTestingPlaygroundURL": [Function],
|
|
39
|
+
"queryAllByAltText": [Function],
|
|
40
|
+
"queryAllByDisplayValue": [Function],
|
|
41
|
+
"queryAllByLabelText": [Function],
|
|
42
|
+
"queryAllByPlaceholderText": [Function],
|
|
43
|
+
"queryAllByRole": [Function],
|
|
44
|
+
"queryAllByTestId": [Function],
|
|
45
|
+
"queryAllByText": [Function],
|
|
46
|
+
"queryAllByTitle": [Function],
|
|
47
|
+
"queryByAltText": [Function],
|
|
48
|
+
"queryByDisplayValue": [Function],
|
|
49
|
+
"queryByLabelText": [Function],
|
|
50
|
+
"queryByPlaceholderText": [Function],
|
|
51
|
+
"queryByRole": [Function],
|
|
52
|
+
"queryByTestId": [Function],
|
|
53
|
+
"queryByText": [Function],
|
|
54
|
+
"queryByTitle": [Function],
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
|
2
|
+
|
|
3
|
+
exports[`styled with palette colors 1`] = `
|
|
4
|
+
.c0 {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: row;
|
|
7
|
+
align-items: center;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
height: 40px;
|
|
10
|
+
min-width: 142px;
|
|
11
|
+
padding: 10px;
|
|
12
|
+
font-size: 18px;
|
|
13
|
+
font-family: 'orbitron';
|
|
14
|
+
color: #fd05a0;
|
|
15
|
+
background-color: #081e28;
|
|
16
|
+
border: 1px solid #fd05a0;
|
|
17
|
+
border-radius: 12px;
|
|
18
|
+
transition-duration: 0.5s;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.c0:hover {
|
|
22
|
+
border-radius: 20px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.c1 {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: row;
|
|
28
|
+
align-items: center;
|
|
29
|
+
justify-content: right;
|
|
30
|
+
width: 42px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
<button
|
|
34
|
+
class="c0"
|
|
35
|
+
>
|
|
36
|
+
count:
|
|
37
|
+
<div
|
|
38
|
+
class="c1"
|
|
39
|
+
data-testid="count"
|
|
40
|
+
>
|
|
41
|
+
0
|
|
42
|
+
</div>
|
|
43
|
+
</button>
|
|
44
|
+
`;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
|
2
|
+
|
|
3
|
+
exports[`renders text and children 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"debug": [Function],
|
|
6
|
+
"findAllByAltText": [Function],
|
|
7
|
+
"findAllByDisplayValue": [Function],
|
|
8
|
+
"findAllByLabelText": [Function],
|
|
9
|
+
"findAllByPlaceholderText": [Function],
|
|
10
|
+
"findAllByRole": [Function],
|
|
11
|
+
"findAllByTestId": [Function],
|
|
12
|
+
"findAllByText": [Function],
|
|
13
|
+
"findAllByTitle": [Function],
|
|
14
|
+
"findByAltText": [Function],
|
|
15
|
+
"findByDisplayValue": [Function],
|
|
16
|
+
"findByLabelText": [Function],
|
|
17
|
+
"findByPlaceholderText": [Function],
|
|
18
|
+
"findByRole": [Function],
|
|
19
|
+
"findByTestId": [Function],
|
|
20
|
+
"findByText": [Function],
|
|
21
|
+
"findByTitle": [Function],
|
|
22
|
+
"getAllByAltText": [Function],
|
|
23
|
+
"getAllByDisplayValue": [Function],
|
|
24
|
+
"getAllByLabelText": [Function],
|
|
25
|
+
"getAllByPlaceholderText": [Function],
|
|
26
|
+
"getAllByRole": [Function],
|
|
27
|
+
"getAllByTestId": [Function],
|
|
28
|
+
"getAllByText": [Function],
|
|
29
|
+
"getAllByTitle": [Function],
|
|
30
|
+
"getByAltText": [Function],
|
|
31
|
+
"getByDisplayValue": [Function],
|
|
32
|
+
"getByLabelText": [Function],
|
|
33
|
+
"getByPlaceholderText": [Function],
|
|
34
|
+
"getByRole": [Function],
|
|
35
|
+
"getByTestId": [Function],
|
|
36
|
+
"getByText": [Function],
|
|
37
|
+
"getByTitle": [Function],
|
|
38
|
+
"logTestingPlaygroundURL": [Function],
|
|
39
|
+
"queryAllByAltText": [Function],
|
|
40
|
+
"queryAllByDisplayValue": [Function],
|
|
41
|
+
"queryAllByLabelText": [Function],
|
|
42
|
+
"queryAllByPlaceholderText": [Function],
|
|
43
|
+
"queryAllByRole": [Function],
|
|
44
|
+
"queryAllByTestId": [Function],
|
|
45
|
+
"queryAllByText": [Function],
|
|
46
|
+
"queryAllByTitle": [Function],
|
|
47
|
+
"queryByAltText": [Function],
|
|
48
|
+
"queryByDisplayValue": [Function],
|
|
49
|
+
"queryByLabelText": [Function],
|
|
50
|
+
"queryByPlaceholderText": [Function],
|
|
51
|
+
"queryByRole": [Function],
|
|
52
|
+
"queryByTestId": [Function],
|
|
53
|
+
"queryByText": [Function],
|
|
54
|
+
"queryByTitle": [Function],
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
Binary file
|
|
Binary file
|
package/src/index.html
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang='en'>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset='utf-8' />
|
|
5
|
+
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
|
6
|
+
<meta name='theme-color' content='#000000' />
|
|
7
|
+
<meta
|
|
8
|
+
name='Create Application Template RS'
|
|
9
|
+
content='provides a configured application template for you to build upon'
|
|
10
|
+
keywords='template, react, typescript, styled-components, rspack, swc, jest, eslint, stylelint, javascript'
|
|
11
|
+
/>
|
|
12
|
+
<title><%= htmlWebpackPlugin.options.title %></title>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<noscript>You must enable JavaScript to run this app.</noscript>
|
|
16
|
+
<div id='root'></div>
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { StrictMode } from 'react'
|
|
2
|
+
import { createRoot } from 'react-dom/client'
|
|
3
|
+
import { App } from './components/App'
|
|
4
|
+
|
|
5
|
+
const container = document.getElementById('root')
|
|
6
|
+
const root = createRoot(container!)
|
|
7
|
+
|
|
8
|
+
root.render(
|
|
9
|
+
<StrictMode>
|
|
10
|
+
<App />
|
|
11
|
+
</StrictMode>
|
|
12
|
+
)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { styled, keyframes } from 'styled-components'
|
|
2
|
+
|
|
3
|
+
const fadeIn = keyframes`
|
|
4
|
+
0% {
|
|
5
|
+
opacity: 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
100% {
|
|
9
|
+
opacity: 1;
|
|
10
|
+
}
|
|
11
|
+
`
|
|
12
|
+
|
|
13
|
+
export const StyledContainer = styled.div`
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
min-height: 100vh;
|
|
19
|
+
font-size: max(1em, 18px);
|
|
20
|
+
color: ${({ theme }) => theme.colors.palette.primary};
|
|
21
|
+
background-color: ${({ theme }) => theme.colors.palette.background};
|
|
22
|
+
`
|
|
23
|
+
|
|
24
|
+
export const StyledHeader = styled.header`
|
|
25
|
+
text-align: center;
|
|
26
|
+
`
|
|
27
|
+
|
|
28
|
+
export const StyledSection = styled.section`
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
margin: 2vh;
|
|
32
|
+
animation: 3s ${fadeIn} ease;
|
|
33
|
+
`
|
|
34
|
+
|
|
35
|
+
export const StyledLink = styled.a`
|
|
36
|
+
color: ${({ theme }) => theme.colors.link.regular};
|
|
37
|
+
transition: 0.3s;
|
|
38
|
+
|
|
39
|
+
&:hover {
|
|
40
|
+
color: ${({ theme }) => theme.colors.link.hover};
|
|
41
|
+
}
|
|
42
|
+
`
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { styled } from 'styled-components'
|
|
2
|
+
|
|
3
|
+
export const StyledCounter = styled.button`
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: row;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
height: 40px;
|
|
9
|
+
min-width: 142px;
|
|
10
|
+
padding: 10px;
|
|
11
|
+
font-size: 18px;
|
|
12
|
+
font-family: '${({ theme }) => theme.font}';
|
|
13
|
+
color: ${({ theme }) => theme.colors.palette.primary};
|
|
14
|
+
background-color: ${({ theme }) => theme.colors.palette.background};
|
|
15
|
+
border: 1px solid ${({ theme }) => theme.colors.palette.primary};
|
|
16
|
+
border-radius: 12px;
|
|
17
|
+
transition-duration: 0.5s;
|
|
18
|
+
|
|
19
|
+
&:hover {
|
|
20
|
+
border-radius: 20px;
|
|
21
|
+
}
|
|
22
|
+
`
|
|
23
|
+
|
|
24
|
+
export const StyledCount = styled.div`
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: row;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: right;
|
|
29
|
+
width: 42px;
|
|
30
|
+
`
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createGlobalStyle } from 'styled-components'
|
|
2
|
+
import Orbitron from '../fonts/Orbitron-Regular.woff2'
|
|
3
|
+
|
|
4
|
+
const GlobalStyles = createGlobalStyle`
|
|
5
|
+
@font-face {
|
|
6
|
+
font-family: '${({ theme }) => theme.font}';
|
|
7
|
+
src: url('${Orbitron}') format('woff2');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
font-family: '${({ theme }) => theme.font}', sans-serif;
|
|
13
|
+
-webkit-font-smoothing: antialiased;
|
|
14
|
+
-moz-osx-font-smoothing: grayscale;
|
|
15
|
+
}
|
|
16
|
+
`
|
|
17
|
+
|
|
18
|
+
export default GlobalStyles
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { styled, keyframes } from 'styled-components'
|
|
2
|
+
|
|
3
|
+
const pulse = keyframes`
|
|
4
|
+
0% {
|
|
5
|
+
opacity: 0.2;
|
|
6
|
+
transform: scale(0.8);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
50% {
|
|
10
|
+
opacity: 1.0;
|
|
11
|
+
transform: scale(1.2);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
100% {
|
|
15
|
+
opacity: 0.2;
|
|
16
|
+
transform: scale(0.8);
|
|
17
|
+
}
|
|
18
|
+
`
|
|
19
|
+
|
|
20
|
+
export const StyledLogo = styled.img`
|
|
21
|
+
height: 240px;
|
|
22
|
+
pointer-events: none;
|
|
23
|
+
animation: ${pulse} infinite 10s ease;
|
|
24
|
+
`
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { transparentize } from 'polished'
|
|
2
|
+
|
|
3
|
+
const theme = {
|
|
4
|
+
font: 'orbitron',
|
|
5
|
+
colors: {
|
|
6
|
+
palette: {
|
|
7
|
+
background: '#081e28',
|
|
8
|
+
primary: '#fd05a0',
|
|
9
|
+
},
|
|
10
|
+
get link() {
|
|
11
|
+
const link = this.palette.primary
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
regular: transparentize(0.4, link),
|
|
15
|
+
hover: transparentize(0.6, link),
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default theme
|