From ee804a0b541b8811f5de315fb9d4e2b679734be6 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Thu, 19 Aug 2021 16:35:37 +0800 Subject: [PATCH] feat: new landing page design for default & typescript-default template --- .../cypress/integration/example.spec.js | 2 +- template/code/default/src/App.vue | 191 ++++++++++++++++-- template/code/default/src/assets/base.css | 72 +++++++ template/code/default/src/assets/logo.png | Bin 6849 -> 0 bytes template/code/default/src/assets/logo.svg | 1 + .../src/components/ColorSchemeSwitch.vue | 137 +++++++++++++ .../default/src/components/HelloWorld.vue | 69 +++---- .../src/components/IntroductionItem.vue | 85 ++++++++ .../__tests__/ColorSchemeSwitch.spec.js | 34 ++++ .../components/__tests__/HelloWorld.spec.js | 9 - .../src/components/icons/Community.vue | 7 + .../src/components/icons/Documentation.vue | 7 + .../src/components/icons/Ecosystem.vue | 7 + .../default/src/components/icons/Moon.vue | 18 ++ .../code/default/src/components/icons/Sun.vue | 34 ++++ .../default/src/components/icons/Support.vue | 7 + .../default/src/components/icons/Tooling.vue | 19 ++ .../__tests__/useMediaQuery.spec.js | 33 +++ .../default/src/composables/useColorScheme.js | 31 +++ .../default/src/composables/useMediaQuery.js | 28 +++ template/code/default/src/main.js | 4 - template/code/router/src/main.js | 9 - .../cypress/integration/example.spec.ts | 2 +- template/code/typescript-default/src/App.vue | 190 ++++++++++++++++- .../typescript-default/src/assets/base.css | 72 +++++++ .../typescript-default/src/assets/logo.png | Bin 6849 -> 0 bytes .../typescript-default/src/assets/logo.svg | 1 + .../src/components/ColorSchemeSwitch.vue | 137 +++++++++++++ .../src/components/HelloWorld.vue | 69 +++---- .../src/components/IntroductionItem.vue | 85 ++++++++ .../__tests__/ColorSchemeSwitch.spec.ts | 34 ++++ .../components/__tests__/HelloWorld.spec.ts | 9 - .../src/components/icons/Community.vue | 7 + .../src/components/icons/Documentation.vue | 7 + .../src/components/icons/Ecosystem.vue | 7 + .../src/components/icons/Moon.vue | 18 ++ .../src/components/icons/Sun.vue | 34 ++++ .../src/components/icons/Support.vue | 7 + .../src/components/icons/Tooling.vue | 19 ++ .../__tests__/useMediaQuery.spec.ts | 33 +++ .../src/composables/useColorScheme.ts | 31 +++ .../src/composables/useMediaQuery.ts | 28 +++ template/code/typescript-default/src/main.ts | 4 - 43 files changed, 1455 insertions(+), 143 deletions(-) create mode 100644 template/code/default/src/assets/base.css delete mode 100644 template/code/default/src/assets/logo.png create mode 100644 template/code/default/src/assets/logo.svg create mode 100644 template/code/default/src/components/ColorSchemeSwitch.vue create mode 100644 template/code/default/src/components/IntroductionItem.vue create mode 100644 template/code/default/src/components/__tests__/ColorSchemeSwitch.spec.js create mode 100644 template/code/default/src/components/icons/Community.vue create mode 100644 template/code/default/src/components/icons/Documentation.vue create mode 100644 template/code/default/src/components/icons/Ecosystem.vue create mode 100644 template/code/default/src/components/icons/Moon.vue create mode 100644 template/code/default/src/components/icons/Sun.vue create mode 100644 template/code/default/src/components/icons/Support.vue create mode 100644 template/code/default/src/components/icons/Tooling.vue create mode 100644 template/code/default/src/composables/__tests__/useMediaQuery.spec.js create mode 100644 template/code/default/src/composables/useColorScheme.js create mode 100644 template/code/default/src/composables/useMediaQuery.js delete mode 100644 template/code/default/src/main.js delete mode 100644 template/code/router/src/main.js create mode 100644 template/code/typescript-default/src/assets/base.css delete mode 100644 template/code/typescript-default/src/assets/logo.png create mode 100644 template/code/typescript-default/src/assets/logo.svg create mode 100644 template/code/typescript-default/src/components/ColorSchemeSwitch.vue create mode 100644 template/code/typescript-default/src/components/IntroductionItem.vue create mode 100644 template/code/typescript-default/src/components/__tests__/ColorSchemeSwitch.spec.ts create mode 100644 template/code/typescript-default/src/components/icons/Community.vue create mode 100644 template/code/typescript-default/src/components/icons/Documentation.vue create mode 100644 template/code/typescript-default/src/components/icons/Ecosystem.vue create mode 100644 template/code/typescript-default/src/components/icons/Moon.vue create mode 100644 template/code/typescript-default/src/components/icons/Sun.vue create mode 100644 template/code/typescript-default/src/components/icons/Support.vue create mode 100644 template/code/typescript-default/src/components/icons/Tooling.vue create mode 100644 template/code/typescript-default/src/composables/__tests__/useMediaQuery.spec.ts create mode 100644 template/code/typescript-default/src/composables/useColorScheme.ts create mode 100644 template/code/typescript-default/src/composables/useMediaQuery.ts delete mode 100644 template/code/typescript-default/src/main.ts diff --git a/template/code/default/cypress/integration/example.spec.js b/template/code/default/cypress/integration/example.spec.js index 493bfcf0..7a8c909f 100644 --- a/template/code/default/cypress/integration/example.spec.js +++ b/template/code/default/cypress/integration/example.spec.js @@ -3,6 +3,6 @@ describe('My First Test', () => { it('visits the app root url', () => { cy.visit('/') - cy.contains('h1', 'Hello Vue 3 + Vite') + cy.contains('h1', 'You did it!') }) }) diff --git a/template/code/default/src/App.vue b/template/code/default/src/App.vue index a058d171..64c42595 100644 --- a/template/code/default/src/App.vue +++ b/template/code/default/src/App.vue @@ -1,22 +1,187 @@ - - + + diff --git a/template/code/default/src/assets/base.css b/template/code/default/src/assets/base.css new file mode 100644 index 00000000..e81bad15 --- /dev/null +++ b/template/code/default/src/assets/base.css @@ -0,0 +1,72 @@ +/* color palette from */ +:root { + --vt-c-white: #ffffff; + --vt-c-white-soft: #f8f8f8; + --vt-c-white-mute: #f2f2f2; + + --vt-c-black: #181818; + --vt-c-black-soft: #222222; + --vt-c-black-mute: #282828; + + --vt-c-indigo: #2c3e50; + + --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); + --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); + --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); + --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); + + --vt-c-text-light-1: var(--vt-c-indigo); + --vt-c-text-light-2: rgba(60, 60, 60, 0.66); + --vt-c-text-dark-1: var(--vt-c-white); + --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); +} + +/* semantic color variables for this project */ +:root { + --color-background: var(--vt-c-white); + --color-background-soft: var(--vt-c-white-soft); + --color-background-mute: var(--vt-c-white-mute); + + --color-border: var(--vt-c-divider-light-2); + --color-border-hover: var(--vt-c-divider-light-1); + + --color-heading: var(--vt-c-text-light-1); + --color-text: var(--vt-c-text-light-2); + + --section-gap: 160px; +} + +[data-color-scheme='dark'] { + --color-background: var(--vt-c-black); + --color-background-soft: var(--vt-c-black-soft); + --color-background-mute: var(--vt-c-black-mute); + + --color-border: var(--vt-c-divider-dark-2); + --color-border-hover: var(--vt-c-divider-dark-1); + + --color-heading: var(--vt-c-text-dark-1); + --color-text: var(--vt-c-text-dark-2); +} + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + position: relative; + font-weight: normal; +} + +body { + min-height: 100vh; + color: var(--color-text); + background: var(--color-background); + transition: color 0.5s, background-color 0.5s; + line-height: 1.6; + font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, + Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; + font-size: 15px; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/template/code/default/src/assets/logo.png b/template/code/default/src/assets/logo.png deleted file mode 100644 index f3d2503fc2a44b5053b0837ebea6e87a2d339a43..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 6849 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 g1!6qyAfq4?0x&QzG diff --git a/template/code/default/src/assets/logo.svg b/template/code/default/src/assets/logo.svg new file mode 100644 index 00000000..bc826fed --- /dev/null +++ b/template/code/default/src/assets/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/template/code/default/src/components/ColorSchemeSwitch.vue b/template/code/default/src/components/ColorSchemeSwitch.vue new file mode 100644 index 00000000..a4007efe --- /dev/null +++ b/template/code/default/src/components/ColorSchemeSwitch.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/template/code/default/src/components/HelloWorld.vue b/template/code/default/src/components/HelloWorld.vue index 51f81a8f..26672db0 100644 --- a/template/code/default/src/components/HelloWorld.vue +++ b/template/code/default/src/components/HelloWorld.vue @@ -1,57 +1,44 @@ - - + + diff --git a/template/code/default/src/components/IntroductionItem.vue b/template/code/default/src/components/IntroductionItem.vue new file mode 100644 index 00000000..58965058 --- /dev/null +++ b/template/code/default/src/components/IntroductionItem.vue @@ -0,0 +1,85 @@ + + + diff --git a/template/code/default/src/components/__tests__/ColorSchemeSwitch.spec.js b/template/code/default/src/components/__tests__/ColorSchemeSwitch.spec.js new file mode 100644 index 00000000..3842adf2 --- /dev/null +++ b/template/code/default/src/components/__tests__/ColorSchemeSwitch.spec.js @@ -0,0 +1,34 @@ +import { mount } from '@cypress/vue' + +import ColorSchemeSwitch from '../ColorSchemeSwitch.vue' + +describe('ColorSchemeSwitch', () => { + beforeEach(() => { + cy.stub(window, 'matchMedia') + .withArgs('(prefers-color-scheme: light)') + .returns({ + matches: false, + addEventListener: () => {}, + removeEventListener: () => {}, + }) + .withArgs('(prefers-color-scheme: dark)') + .returns({ + matches: true, + addEventListener: () => {}, + removeEventListener: () => {}, + }) + }) + + it('use the preferred color scheme by default', () => { + mount(ColorSchemeSwitch) + + cy.get('body').should('have.attr', 'data-color-scheme', 'dark') + }) + + it('toggles the color scheme affter user clicks toggle', () => { + mount(ColorSchemeSwitch) + + cy.get('.color-scheme-switch').click() + cy.get('body').should('have.attr', 'data-color-scheme', 'light') + }) +}) diff --git a/template/code/default/src/components/__tests__/HelloWorld.spec.js b/template/code/default/src/components/__tests__/HelloWorld.spec.js index 087c9561..a69f3a9d 100644 --- a/template/code/default/src/components/__tests__/HelloWorld.spec.js +++ b/template/code/default/src/components/__tests__/HelloWorld.spec.js @@ -10,13 +10,4 @@ describe('HelloWorld', () => { mount(HelloWorld, { props: { msg: 'Hello Cypress' } }) cy.get('h1').should('contain', 'Hello Cypress') }) - - it('adds 1 when clicking the plus button', () => { - mount(HelloWorld, { props: { msg: 'Hello Cypress' } }) - - cy.get('button') - .should('contain', '0') - .click() - .should('contain', '1') - }) }) diff --git a/template/code/default/src/components/icons/Community.vue b/template/code/default/src/components/icons/Community.vue new file mode 100644 index 00000000..2dc8b055 --- /dev/null +++ b/template/code/default/src/components/icons/Community.vue @@ -0,0 +1,7 @@ + diff --git a/template/code/default/src/components/icons/Documentation.vue b/template/code/default/src/components/icons/Documentation.vue new file mode 100644 index 00000000..6d4791cf --- /dev/null +++ b/template/code/default/src/components/icons/Documentation.vue @@ -0,0 +1,7 @@ + diff --git a/template/code/default/src/components/icons/Ecosystem.vue b/template/code/default/src/components/icons/Ecosystem.vue new file mode 100644 index 00000000..c3a4f078 --- /dev/null +++ b/template/code/default/src/components/icons/Ecosystem.vue @@ -0,0 +1,7 @@ + diff --git a/template/code/default/src/components/icons/Moon.vue b/template/code/default/src/components/icons/Moon.vue new file mode 100644 index 00000000..8e02b917 --- /dev/null +++ b/template/code/default/src/components/icons/Moon.vue @@ -0,0 +1,18 @@ + + + diff --git a/template/code/default/src/components/icons/Sun.vue b/template/code/default/src/components/icons/Sun.vue new file mode 100644 index 00000000..577f8031 --- /dev/null +++ b/template/code/default/src/components/icons/Sun.vue @@ -0,0 +1,34 @@ + + + diff --git a/template/code/default/src/components/icons/Support.vue b/template/code/default/src/components/icons/Support.vue new file mode 100644 index 00000000..7452834d --- /dev/null +++ b/template/code/default/src/components/icons/Support.vue @@ -0,0 +1,7 @@ + diff --git a/template/code/default/src/components/icons/Tooling.vue b/template/code/default/src/components/icons/Tooling.vue new file mode 100644 index 00000000..660598d7 --- /dev/null +++ b/template/code/default/src/components/icons/Tooling.vue @@ -0,0 +1,19 @@ + + diff --git a/template/code/default/src/composables/__tests__/useMediaQuery.spec.js b/template/code/default/src/composables/__tests__/useMediaQuery.spec.js new file mode 100644 index 00000000..a7a5d024 --- /dev/null +++ b/template/code/default/src/composables/__tests__/useMediaQuery.spec.js @@ -0,0 +1,33 @@ +import { defineComponent, h, createVNode } from 'vue' +import { mount } from '@cypress/vue' + +import useMediaQuery from '../useMediaQuery' + +const Wrapper = defineComponent({ + props: { + query: { + type: String, + required: true + } + }, + setup(props) { + const matches = useMediaQuery(props.query) + return () => h('div', { id: 'result' }, matches.value.toString() ) + } +}) + +describe('useMediaQuery', () => { + it('should correctly reflect the match result of a media query', () => { + mount(Wrapper, { + props: { + query: '(min-width: 800px)' + } + }) + + cy.viewport(1000, 660) + cy.get('#result').should('include.text', 'true') + + cy.viewport(660, 660) + cy.get('#result').should('include.text', 'false') + }) +}) diff --git a/template/code/default/src/composables/useColorScheme.js b/template/code/default/src/composables/useColorScheme.js new file mode 100644 index 00000000..be111aff --- /dev/null +++ b/template/code/default/src/composables/useColorScheme.js @@ -0,0 +1,31 @@ +import { ref, computed } from 'vue' +import useMediaQuery from './useMediaQuery' + +// Its value should be consistent when called multiple times. +// So we put it outside the composable function +const isUserToggledDark = ref() + +export default function useColorScheme() { + const isDefaultDark = useMediaQuery('(prefers-color-scheme: dark)') + + const isDark = computed(() => { + if (typeof isUserToggledDark.value !== 'undefined') { + return isUserToggledDark.value + } else { + return isDefaultDark.value + } + }) + + const toggle = () => { + if (typeof isUserToggledDark.value !== 'undefined') { + isUserToggledDark.value = !isUserToggledDark.value + } else { + isUserToggledDark.value = !isDefaultDark.value + } + } + + return { + toggle, + isDark + } +} diff --git a/template/code/default/src/composables/useMediaQuery.js b/template/code/default/src/composables/useMediaQuery.js new file mode 100644 index 00000000..bf288056 --- /dev/null +++ b/template/code/default/src/composables/useMediaQuery.js @@ -0,0 +1,28 @@ +import { ref, onUnmounted } from 'vue' + +export default function useMediaQuery(query) { + const mediaQueryList = window.matchMedia(query) + const matches = ref(mediaQueryList.matches) + + const handler = (event) => { + matches.value = event.matches + } + + // Safari < 14 does not support this + if (mediaQueryList.addEventListener) { + mediaQueryList.addEventListener('change', handler) + } else { + mediaQueryList.addListener(handler) + } + + onUnmounted(() => { + // Safari < 14 does not support this + if (mediaQueryList.removeEventListener) { + mediaQueryList.removeEventListener('change', handler) + } else { + mediaQueryList.removeListener(handler) + } + }) + + return matches +} diff --git a/template/code/default/src/main.js b/template/code/default/src/main.js deleted file mode 100644 index 01433bca..00000000 --- a/template/code/default/src/main.js +++ /dev/null @@ -1,4 +0,0 @@ -import { createApp } from 'vue' -import App from './App.vue' - -createApp(App).mount('#app') diff --git a/template/code/router/src/main.js b/template/code/router/src/main.js deleted file mode 100644 index c8e37b03..00000000 --- a/template/code/router/src/main.js +++ /dev/null @@ -1,9 +0,0 @@ -import { createApp } from 'vue' -import App from './App.vue' -import router from './router' - -const app = createApp(App) - -app.use(router) - -app.mount('#app') diff --git a/template/code/typescript-default/cypress/integration/example.spec.ts b/template/code/typescript-default/cypress/integration/example.spec.ts index bbe8f52d..7a8c909f 100644 --- a/template/code/typescript-default/cypress/integration/example.spec.ts +++ b/template/code/typescript-default/cypress/integration/example.spec.ts @@ -3,6 +3,6 @@ describe('My First Test', () => { it('visits the app root url', () => { cy.visit('/') - cy.contains('h1', 'Hello Vue 3 + TypeScript + Vite') + cy.contains('h1', 'You did it!') }) }) diff --git a/template/code/typescript-default/src/App.vue b/template/code/typescript-default/src/App.vue index f1611b6f..1499f01b 100644 --- a/template/code/typescript-default/src/App.vue +++ b/template/code/typescript-default/src/App.vue @@ -1,19 +1,187 @@ - - + + diff --git a/template/code/typescript-default/src/assets/base.css b/template/code/typescript-default/src/assets/base.css new file mode 100644 index 00000000..e81bad15 --- /dev/null +++ b/template/code/typescript-default/src/assets/base.css @@ -0,0 +1,72 @@ +/* color palette from */ +:root { + --vt-c-white: #ffffff; + --vt-c-white-soft: #f8f8f8; + --vt-c-white-mute: #f2f2f2; + + --vt-c-black: #181818; + --vt-c-black-soft: #222222; + --vt-c-black-mute: #282828; + + --vt-c-indigo: #2c3e50; + + --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); + --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); + --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); + --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); + + --vt-c-text-light-1: var(--vt-c-indigo); + --vt-c-text-light-2: rgba(60, 60, 60, 0.66); + --vt-c-text-dark-1: var(--vt-c-white); + --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); +} + +/* semantic color variables for this project */ +:root { + --color-background: var(--vt-c-white); + --color-background-soft: var(--vt-c-white-soft); + --color-background-mute: var(--vt-c-white-mute); + + --color-border: var(--vt-c-divider-light-2); + --color-border-hover: var(--vt-c-divider-light-1); + + --color-heading: var(--vt-c-text-light-1); + --color-text: var(--vt-c-text-light-2); + + --section-gap: 160px; +} + +[data-color-scheme='dark'] { + --color-background: var(--vt-c-black); + --color-background-soft: var(--vt-c-black-soft); + --color-background-mute: var(--vt-c-black-mute); + + --color-border: var(--vt-c-divider-dark-2); + --color-border-hover: var(--vt-c-divider-dark-1); + + --color-heading: var(--vt-c-text-dark-1); + --color-text: var(--vt-c-text-dark-2); +} + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + position: relative; + font-weight: normal; +} + +body { + min-height: 100vh; + color: var(--color-text); + background: var(--color-background); + transition: color 0.5s, background-color 0.5s; + line-height: 1.6; + font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, + Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; + font-size: 15px; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/template/code/typescript-default/src/assets/logo.png b/template/code/typescript-default/src/assets/logo.png deleted file mode 100644 index f3d2503fc2a44b5053b0837ebea6e87a2d339a43..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 6849 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 g1!6qyAfq4?0x&QzG diff --git a/template/code/typescript-default/src/assets/logo.svg b/template/code/typescript-default/src/assets/logo.svg new file mode 100644 index 00000000..bc826fed --- /dev/null +++ b/template/code/typescript-default/src/assets/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/template/code/typescript-default/src/components/ColorSchemeSwitch.vue b/template/code/typescript-default/src/components/ColorSchemeSwitch.vue new file mode 100644 index 00000000..a5188c22 --- /dev/null +++ b/template/code/typescript-default/src/components/ColorSchemeSwitch.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/template/code/typescript-default/src/components/HelloWorld.vue b/template/code/typescript-default/src/components/HelloWorld.vue index 97b3d3da..8a759066 100644 --- a/template/code/typescript-default/src/components/HelloWorld.vue +++ b/template/code/typescript-default/src/components/HelloWorld.vue @@ -1,54 +1,41 @@ - - + + diff --git a/template/code/typescript-default/src/components/IntroductionItem.vue b/template/code/typescript-default/src/components/IntroductionItem.vue new file mode 100644 index 00000000..58965058 --- /dev/null +++ b/template/code/typescript-default/src/components/IntroductionItem.vue @@ -0,0 +1,85 @@ + + + diff --git a/template/code/typescript-default/src/components/__tests__/ColorSchemeSwitch.spec.ts b/template/code/typescript-default/src/components/__tests__/ColorSchemeSwitch.spec.ts new file mode 100644 index 00000000..3842adf2 --- /dev/null +++ b/template/code/typescript-default/src/components/__tests__/ColorSchemeSwitch.spec.ts @@ -0,0 +1,34 @@ +import { mount } from '@cypress/vue' + +import ColorSchemeSwitch from '../ColorSchemeSwitch.vue' + +describe('ColorSchemeSwitch', () => { + beforeEach(() => { + cy.stub(window, 'matchMedia') + .withArgs('(prefers-color-scheme: light)') + .returns({ + matches: false, + addEventListener: () => {}, + removeEventListener: () => {}, + }) + .withArgs('(prefers-color-scheme: dark)') + .returns({ + matches: true, + addEventListener: () => {}, + removeEventListener: () => {}, + }) + }) + + it('use the preferred color scheme by default', () => { + mount(ColorSchemeSwitch) + + cy.get('body').should('have.attr', 'data-color-scheme', 'dark') + }) + + it('toggles the color scheme affter user clicks toggle', () => { + mount(ColorSchemeSwitch) + + cy.get('.color-scheme-switch').click() + cy.get('body').should('have.attr', 'data-color-scheme', 'light') + }) +}) diff --git a/template/code/typescript-default/src/components/__tests__/HelloWorld.spec.ts b/template/code/typescript-default/src/components/__tests__/HelloWorld.spec.ts index 087c9561..a69f3a9d 100644 --- a/template/code/typescript-default/src/components/__tests__/HelloWorld.spec.ts +++ b/template/code/typescript-default/src/components/__tests__/HelloWorld.spec.ts @@ -10,13 +10,4 @@ describe('HelloWorld', () => { mount(HelloWorld, { props: { msg: 'Hello Cypress' } }) cy.get('h1').should('contain', 'Hello Cypress') }) - - it('adds 1 when clicking the plus button', () => { - mount(HelloWorld, { props: { msg: 'Hello Cypress' } }) - - cy.get('button') - .should('contain', '0') - .click() - .should('contain', '1') - }) }) diff --git a/template/code/typescript-default/src/components/icons/Community.vue b/template/code/typescript-default/src/components/icons/Community.vue new file mode 100644 index 00000000..2dc8b055 --- /dev/null +++ b/template/code/typescript-default/src/components/icons/Community.vue @@ -0,0 +1,7 @@ + diff --git a/template/code/typescript-default/src/components/icons/Documentation.vue b/template/code/typescript-default/src/components/icons/Documentation.vue new file mode 100644 index 00000000..6d4791cf --- /dev/null +++ b/template/code/typescript-default/src/components/icons/Documentation.vue @@ -0,0 +1,7 @@ + diff --git a/template/code/typescript-default/src/components/icons/Ecosystem.vue b/template/code/typescript-default/src/components/icons/Ecosystem.vue new file mode 100644 index 00000000..c3a4f078 --- /dev/null +++ b/template/code/typescript-default/src/components/icons/Ecosystem.vue @@ -0,0 +1,7 @@ + diff --git a/template/code/typescript-default/src/components/icons/Moon.vue b/template/code/typescript-default/src/components/icons/Moon.vue new file mode 100644 index 00000000..8e02b917 --- /dev/null +++ b/template/code/typescript-default/src/components/icons/Moon.vue @@ -0,0 +1,18 @@ + + + diff --git a/template/code/typescript-default/src/components/icons/Sun.vue b/template/code/typescript-default/src/components/icons/Sun.vue new file mode 100644 index 00000000..577f8031 --- /dev/null +++ b/template/code/typescript-default/src/components/icons/Sun.vue @@ -0,0 +1,34 @@ + + + diff --git a/template/code/typescript-default/src/components/icons/Support.vue b/template/code/typescript-default/src/components/icons/Support.vue new file mode 100644 index 00000000..7452834d --- /dev/null +++ b/template/code/typescript-default/src/components/icons/Support.vue @@ -0,0 +1,7 @@ + diff --git a/template/code/typescript-default/src/components/icons/Tooling.vue b/template/code/typescript-default/src/components/icons/Tooling.vue new file mode 100644 index 00000000..660598d7 --- /dev/null +++ b/template/code/typescript-default/src/components/icons/Tooling.vue @@ -0,0 +1,19 @@ + + diff --git a/template/code/typescript-default/src/composables/__tests__/useMediaQuery.spec.ts b/template/code/typescript-default/src/composables/__tests__/useMediaQuery.spec.ts new file mode 100644 index 00000000..a7a5d024 --- /dev/null +++ b/template/code/typescript-default/src/composables/__tests__/useMediaQuery.spec.ts @@ -0,0 +1,33 @@ +import { defineComponent, h, createVNode } from 'vue' +import { mount } from '@cypress/vue' + +import useMediaQuery from '../useMediaQuery' + +const Wrapper = defineComponent({ + props: { + query: { + type: String, + required: true + } + }, + setup(props) { + const matches = useMediaQuery(props.query) + return () => h('div', { id: 'result' }, matches.value.toString() ) + } +}) + +describe('useMediaQuery', () => { + it('should correctly reflect the match result of a media query', () => { + mount(Wrapper, { + props: { + query: '(min-width: 800px)' + } + }) + + cy.viewport(1000, 660) + cy.get('#result').should('include.text', 'true') + + cy.viewport(660, 660) + cy.get('#result').should('include.text', 'false') + }) +}) diff --git a/template/code/typescript-default/src/composables/useColorScheme.ts b/template/code/typescript-default/src/composables/useColorScheme.ts new file mode 100644 index 00000000..6bc17800 --- /dev/null +++ b/template/code/typescript-default/src/composables/useColorScheme.ts @@ -0,0 +1,31 @@ +import { ref, computed } from 'vue' +import useMediaQuery from './useMediaQuery' + +// Its value should be consistent when called multiple times. +// So we put it outside the composable function +const isUserToggledDark = ref() + +export default function useColorScheme() { + const isDefaultDark = useMediaQuery('(prefers-color-scheme: dark)') + + const isDark = computed(() => { + if (typeof isUserToggledDark.value !== 'undefined') { + return isUserToggledDark.value + } else { + return isDefaultDark.value + } + }) + + const toggle = () => { + if (typeof isUserToggledDark.value !== 'undefined') { + isUserToggledDark.value = !isUserToggledDark.value + } else { + isUserToggledDark.value = !isDefaultDark.value + } + } + + return { + toggle, + isDark + } +} diff --git a/template/code/typescript-default/src/composables/useMediaQuery.ts b/template/code/typescript-default/src/composables/useMediaQuery.ts new file mode 100644 index 00000000..559b4644 --- /dev/null +++ b/template/code/typescript-default/src/composables/useMediaQuery.ts @@ -0,0 +1,28 @@ +import { ref, onUnmounted } from 'vue' + +export default function useMediaQuery(query: string) { + const mediaQueryList = window.matchMedia(query) + const matches = ref(mediaQueryList.matches) + + const handler = (event: MediaQueryListEvent) => { + matches.value = event.matches + } + + // @ts-ignore Safari < 14 does not support this + if (mediaQueryList.addEventListener) { + mediaQueryList.addEventListener('change', handler) + } else { + mediaQueryList.addListener(handler) + } + + onUnmounted(() => { + // @ts-ignore Safari < 14 does not support this + if (mediaQueryList.removeEventListener) { + mediaQueryList.removeEventListener('change', handler) + } else { + mediaQueryList.removeListener(handler) + } + }) + + return matches +} diff --git a/template/code/typescript-default/src/main.ts b/template/code/typescript-default/src/main.ts deleted file mode 100644 index 01433bca..00000000 --- a/template/code/typescript-default/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { createApp } from 'vue' -import App from './App.vue' - -createApp(App).mount('#app') -- 2.39.5