-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/Add LocaleSwitch component #141
Changes from 8 commits
cbd2e4b
042568a
f13d944
789e272
070ad8c
2e7ca26
1295e12
67060f5
f450225
2a9e462
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { StoryFn } from '@storybook/vue3' | ||
import LocaleSwitch from './LocaleSwitch.vue' | ||
|
||
export default { | ||
title: 'common/LocaleSwitch', | ||
component: LocaleSwitch, | ||
} | ||
|
||
const Template: StoryFn<unknown> = () => ({ | ||
components: { LocaleSwitch }, | ||
setup() { | ||
return {} | ||
}, | ||
template: '<LocaleSwitch />', | ||
}) | ||
|
||
export const Default = Template.bind({}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
<script setup lang="ts"> | ||
import { onMounted, ref, watch } from 'vue' | ||
import { useRouter } from 'vue-router' | ||
|
||
const LANGUAGES = { | ||
JAPANESE: 'ja', | ||
ENGLISH: 'en', | ||
} as const | ||
|
||
const router = useRouter() | ||
const isLoaded = ref(false) | ||
const isChecked = ref(false) | ||
|
||
const getPath = () => { | ||
if (isChecked.value) { | ||
return `/${LANGUAGES.ENGLISH}${router.currentRoute.value.path}` | ||
} | ||
return router.currentRoute.value.path.replace(`/${LANGUAGES.ENGLISH}`, '') | ||
} | ||
const setSwitchStatus = () => { | ||
isChecked.value = router.currentRoute.value.path.includes(LANGUAGES.ENGLISH) | ||
} | ||
KannoStanfoot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const toggleStatus = () => { | ||
isChecked.value = !isChecked.value | ||
const path = getPath() | ||
// トレイリングスラッシュ対策 | ||
if (path === '') { | ||
router.push('/') | ||
return | ||
} | ||
router.push(path) | ||
} | ||
onMounted(() => { | ||
setSwitchStatus() | ||
isLoaded.value = true | ||
}) | ||
watch( | ||
() => router.currentRoute.value.path, | ||
() => { | ||
setSwitchStatus() | ||
}, | ||
) | ||
</script> | ||
|
||
<template> | ||
<button | ||
v-if="isLoaded" | ||
type="button" | ||
role="switch" | ||
class="locale-switch-button" | ||
aria-label="translate english" | ||
:aria-checked="isChecked" | ||
@click="toggleStatus" | ||
> | ||
<span | ||
class="locale-switch-button-switch" | ||
:class="{ 'locale-switch-button-switch-checked': !isChecked }" | ||
aria-hidden="true" | ||
> | ||
<span | ||
v-if="isChecked" | ||
class="locale-switch-button-language" | ||
:class="{ 'locale-switch-button-language-checked': !isChecked }" | ||
> | ||
<span>{{ LANGUAGES.JAPANESE }}</span> | ||
</span> | ||
<span class="locale-switch-button-circle"> | ||
{{ isChecked ? LANGUAGES.ENGLISH : LANGUAGES.JAPANESE }} | ||
</span> | ||
<span | ||
v-if="!isChecked" | ||
class="locale-switch-button-language" | ||
:class="{ 'locale-switch-button-language-checked': isChecked }" | ||
> | ||
<span>{{ LANGUAGES.ENGLISH }}</span> | ||
</span> | ||
</span> | ||
</button> | ||
</template> | ||
|
||
<style scoped> | ||
* { | ||
--box-shadow: 0 1px 4px color-mix(in srgb, var(--color-vue-blue), transparent calc(100% - 14%)); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 全タグに対して変数宣言しているよーに見えますが、なにかこれが悪さしないかちょっとだけ心配です。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. scopedなのであくまで影響範囲はLocaleSwitchコンポーネント内のため、問題なしと判断しました。 |
||
|
||
.locale-switch-button { | ||
border: 0; | ||
user-select: none; | ||
line-height: 1.2; | ||
width: 5.125rem; | ||
height: 2.5rem; | ||
display: grid; | ||
place-content: center; | ||
color: var(--color-white); | ||
background-color: transparent; | ||
position: relative; | ||
} | ||
|
||
.locale-switch-button-switch { | ||
display: flex; | ||
align-items: center; | ||
box-shadow: var(--box-shadow); | ||
background-color: #d2d6db; | ||
border-radius: 0.9375rem; | ||
height: 1.8125rem; | ||
width: 3.5625rem; | ||
font-size: 1.125rem; | ||
font-weight: bold; | ||
padding-left: 0.5rem; | ||
box-sizing: border-box; | ||
} | ||
KannoStanfoot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
.locale-switch-button-switch-checked { | ||
justify-content: flex-end; | ||
padding-left: 0; | ||
padding-right: 0.5rem; | ||
} | ||
|
||
.locale-switch-button-language { | ||
font-size: 0.875rem; | ||
font-weight: bold; | ||
} | ||
|
||
.locale-switch-button-circle { | ||
position: absolute; | ||
display: flex; | ||
justify-content: center; | ||
padding-top: 0.25rem; | ||
box-sizing: border-box; | ||
border-radius: 50%; | ||
top: calc(50% - 1rem); | ||
right: 50%; | ||
height: 2rem; | ||
width: 2rem; | ||
background: #34495e; | ||
box-shadow: var(--box-shadow); | ||
} | ||
|
||
.locale-switch-button[aria-checked='true'] .locale-switch-button-circle { | ||
right: 0; | ||
left: 50%; | ||
} | ||
|
||
.locale-switch-button:hover { | ||
cursor: pointer; | ||
} | ||
</style> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pathのなかに
en
があるだけでマッチしそうなので、 /en/ とかにしたほうがよいよーなきがしますたとえば /children とかでも 英語だと判断される?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
探索的に確認はしていないですが、トップページで
https://vuefes.jp/2024/en
となるケースがないのであれば、確かに/en/
の方が妥当だと思います。説明にも書きましたが、トレイリングスラッシュの対応がされている場合は以下の処理を削除できます。