Skip to content
Open

64 _ #21

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 25 additions & 16 deletions src/components/BaseModal.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<template>
<div
class="fixed inset-0 z-10 focus:outline-none"
tabindex="-1"
@keydown.esc="close"
>
<div tabindex="-1" :class="classes" @keydown.esc="close">
<transition
appear
enter-active-class="ease-out duration-200"
Expand All @@ -16,18 +12,11 @@
<BaseModalOverlay v-if="isOpen" @click="close" />
</transition>

<div v-if="isOpen" class="relative bg-white max-w-sm mx-auto my-8">
<div v-if="isOpen" :class="bodyClasses">
<div class="p-2 text-right">
<BaseModalButtonClose @click="close" />
</div>
<div class="p-6">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi sunt
sed dolores minus dicta praesentium ab ipsa, necessitatibus deserunt
aperiam exercitationem nostrum maiores odio tempore eaque rerum?
Distinctio maxime veniam optio quos quo facere molestias totam!
Veritatis saepe aliquid id suscipit! Officia laudantium nesciunt
expedita libero, facere modi. Rerum, laudantium!
</div>
<slot />
</div>
</div>
</template>
Expand All @@ -39,14 +28,34 @@ import BaseModalOverlay from './BaseModalOverlay.vue'
export default {
components: {
BaseModalButtonClose,
BaseModalOverlay,
BaseModalOverlay
},

emits: ['close'],

data () {
return {
isOpen: true
isOpen: true,
classes: [
'fixed',
'inset-0',
'z-30',
'flex',
'justify-center',
'items-start'
],
bodyClasses: [
'bg-white',
'w-full',
'sm:w-3/4',
'md:w-2/3',
'lg:w-3/5',
'xl:w-2/5',
'max-w-3xl',
'm-4',
'sm:m-8',
'relative'
]
}
},

Expand Down
66 changes: 66 additions & 0 deletions src/components/TheButtonSearchWithVoice.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<template>
<div :class="classes">
<span v-show="isListening" :class="animationClasses" />
<button v-bind="$attrs" :class="buttonClasses">
<BaseIcon name="microphone" />
</button>
</div>
</template>

<script>
import BaseIcon from './BaseIcon.vue'

export default {
inheritAttrs: false,

components: {
BaseIcon
},

props: {
isListening: {
type: Boolean,
required: true
},
isRecording: {
type: Boolean,
required: true
}
},

data () {
return {
classes: ['flex', 'justify-center', 'items-center', 'rounded-full']
}
},

computed: {
buttonClasses () {
return [
this.isListening ? 'bg-red-600' : 'bg-gray-300',
this.isListening ? 'text-white' : 'text-black',
'w-16',
'h-16',
'rounded-full',
'flex',
'justify-center',
'items-center',
'relative',
'focus:outline-none'
]
},

animationClasses () {
return [
this.isRecording ? 'bg-gray-300' : 'border-gray-300',
'animate-ping',
'absolute',
'w-14',
'h-14',
'rounded-full',
'border'
]
}
}
}
</script>
17 changes: 15 additions & 2 deletions src/components/TheHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@
v-show="isSearchShown"
:is-small-screen="isSmallScreen"
@close="closeMobileSearch"
@open-voice-modal="isVoiceModalOpen = true"
/>
<div :class="rightSideClasses">
<BaseTooltip text="Search with your voice">
<button class="sm:hidden p-2 focus:outline-none">
<button
class="sm:hidden p-2 focus:outline-none"
@click="isVoiceModalOpen = true"
>
<BaseIcon name="microphone" class="w-5 h-5" />
</button>
</BaseTooltip>
Expand All @@ -35,6 +39,12 @@
<ButtonLogin />
</div>
</header>
<teleport to="body">
<TheModalSearchWithVoice
v-if="isVoiceModalOpen"
@close="isVoiceModalOpen = false"
/>
</teleport>
</template>

<script>
Expand All @@ -46,6 +56,7 @@ import ButtonLogin from './ButtonLogin.vue'
import TheSearchWrapper from './TheSearchWrapper.vue'
import TheDropdownApps from './TheDropdownApps.vue'
import TheDropdownSettings from './TheDropdownSettings.vue'
import TheModalSearchWithVoice from './TheModalSearchWithVoice.vue'

export default {
components: {
Expand All @@ -55,7 +66,8 @@ export default {
ButtonLogin,
TheSearchWrapper,
TheDropdownApps,
TheDropdownSettings
TheDropdownSettings,
TheModalSearchWithVoice
},

provide () {
Expand All @@ -71,6 +83,7 @@ export default {
data () {
return {
isSmallScreen: false,
isVoiceModalOpen: false,
isMobileSearchActive: false,
classes: [
'flex',
Expand Down
63 changes: 63 additions & 0 deletions src/components/TheModalSearchWithVoice.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<template>
<BaseModal>
<div class="flex flex-col items-center pt-0 pb-6 px-6">
<p class="text-2xl mb-52 w-full">{{ text }}</p>
<TheButtonSearchWithVoice
:is-listening="isListening"
:is-recording="isRecording"
@click="record"
/>
<div :class="buttonHintClasses">
Tap the microphone to try again
</div>
</div>
</BaseModal>
</template>

<script>
import BaseModal from './BaseModal.vue'
import TheButtonSearchWithVoice from './TheButtonSearchWithVoice.vue'

export default {
components: {
BaseModal,
TheButtonSearchWithVoice
},

data () {
return {
isListening: true,
isRecording: false
}
},

computed: {
text () {
return this.isListening ? 'Listening...' : 'Microphone off. Try again.'
},

buttonHintClasses () {
return [
this.isListening ? 'invisible' : 'visible',
'text-center',
'text-sm',
'text-gray-500',
'mt-4'
]
}
},

methods: {
record () {
if (this.isRecording) {
this.isRecording = false
this.isListening = false
} else if (this.isListening) {
this.isRecording = true
} else {
this.isListening = true
}
}
}
}
</script>
13 changes: 2 additions & 11 deletions src/components/TheSearchWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,28 @@
</BaseTooltip>
<TheSearch />
<BaseTooltip text="Search with your voice" :left="isSmallScreen">
<button @click="isVoiceModalOpen = true" class="p-2 focus:outline-none">
<button class="p-2 focus:outline-none" @click="$emit('open-voice-modal')">
<BaseIcon name="microphone" class="w-5 h-5" />
</button>
</BaseTooltip>
<BaseModal v-if="isVoiceModalOpen" @close="isVoiceModalOpen = false" />
</div>
</template>

<script>
import BaseIcon from './BaseIcon.vue'
import BaseModal from './BaseModal.vue'
import BaseTooltip from './BaseTooltip.vue'
import TheSearch from './TheSearch.vue'

export default {
components: {
BaseIcon,
BaseModal,
BaseTooltip,
TheSearch
},

props: ['isSmallScreen'],

emits: ['close'],

data () {
return {
isVoiceModalOpen: false
}
},
emits: ['close', 'open-voice-modal'],

computed: {
classes () {
Expand Down