Skip to content

Commit

Permalink
Backpack as Bootstrap Modal
Browse files Browse the repository at this point in the history
  • Loading branch information
ltouroumov committed Feb 5, 2024
1 parent 5220c7b commit 274d439
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 142 deletions.
87 changes: 87 additions & 0 deletions components/utils/ModalDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<template>
<dialog ref="dialog" class="modal-window text-light">
<div class="modal-content">
<div class="modal-header">
<slot name="header" />
<button
type="button"
class="btn-close"
aria-label="Close"
@click="$emit('close')"
></button>
</div>
<div class="modal-body">
<slot />
</div>
</div>
</dialog>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
defineEmits<{
(e: 'close'): void;
}>();
const props = defineProps<{
show: boolean;
}>();
const dialog = ref<HTMLDialogElement>();
watch(
() => props.show,
(newValue) => {
if (newValue) {
dialog.value?.showModal();
} else {
dialog.value?.close();
}
},
);
</script>

<style scoped lang="scss">
@import '~/assets/css/bootstrap/_config.scss';
dialog.modal-window {
--bs-modal-zindex: #{$zindex-modal};
--bs-modal-width: #{$modal-md};
--bs-modal-padding: #{$modal-inner-padding};
--bs-modal-margin: #{$modal-dialog-margin};
--bs-modal-color: #{$modal-content-color};
--bs-modal-bg: #{$modal-content-bg};
--bs-modal-border-color: #{$modal-content-border-color};
--bs-modal-border-width: #{$modal-content-border-width};
--bs-modal-border-radius: #{$modal-content-border-radius};
--bs-modal-box-shadow: #{$modal-content-box-shadow-xs};
--bs-modal-inner-border-radius: #{$modal-content-inner-border-radius};
--bs-modal-header-padding-x: #{$modal-header-padding-x};
--bs-modal-header-padding-y: #{$modal-header-padding-y};
--bs-modal-header-padding: #{$modal-header-padding}; // Todo in v6: Split this padding into x and y
--bs-modal-header-border-color: #{$modal-header-border-color};
--bs-modal-header-border-width: #{$modal-header-border-width};
--bs-modal-title-line-height: #{$modal-title-line-height};
--bs-modal-footer-gap: #{$modal-footer-margin-between};
--bs-modal-footer-bg: #{$modal-footer-bg};
--bs-modal-footer-border-color: #{$modal-footer-border-color};
--bs-modal-footer-border-width: #{$modal-footer-border-width};
--bs-backdrop-zindex: #{$zindex-modal-backdrop};
--bs-backdrop-bg: #{$modal-backdrop-bg};
--bs-backdrop-opacity: #{$modal-backdrop-opacity};
padding: 0;
border: 0;
background: none;
min-width: var(--bs-modal-width);
width: 60%;
&::backdrop {
background: var(--bs-backdrop-bg);
opacity: var(--bs-backdrop-opacity);
}
}
</style>
6 changes: 4 additions & 2 deletions components/viewer/ViewMenuBar.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<template>
<nav class="navbar navbar-expand-lg bg-dark-subtle text-white navbar-dark">
<nav
class="navbar fixed fixed-top navbar-expand-lg bg-dark-subtle text-white navbar-dark"
>
<div class="container-fluid">
<div class="d-flex flex-row items-center">
<button class="btn btn-light btn-lg i-solar-hamburger-menu-outline" />
</div>
<ViewScoreStatus />
<ViewScoreStatus short />
<div class="d-flex gap-1">
<button
class="btn btn-light btn-lg i-solar-magnifer-outline"
Expand Down
5 changes: 3 additions & 2 deletions components/viewer/ViewScoreStatus.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:key="score.id"
class="d-flex flex-row gap-2"
>
<span v-if="score.beforeText">{{ score.beforeText }}</span>
<span v-if="score.beforeText && !short">{{ score.beforeText }}</span>
<span>{{ -value }}</span>
<span v-if="score.afterText">{{ score.afterText }}</span>
</span>
Expand All @@ -19,8 +19,9 @@ import { computed } from 'vue';
import { PointType } from '~/composables/project';
import { useProjectRefs } from '~/composables/store/project';
const { vertical } = defineProps<{
const { vertical, short = true } = defineProps<{
vertical?: boolean;
short?: boolean;
}>();
const { selected, pointTypes, points } = useProjectRefs();
Expand Down
76 changes: 40 additions & 36 deletions components/viewer/modal/ViewBackpack.vue
Original file line number Diff line number Diff line change
@@ -1,45 +1,44 @@
<template>
<SideDrawer
:visible="isBackpackVisible"
side="right"
@close="toggleBackpack()"
>
<div class="pack-header bg-dark">
<ModalDialog :show="isBackpackVisible" @close="toggleBackpack(false)">
<template #header>
<h5 class="m-0">Choices</h5>
<button
class="btn btn-dark i-solar-backpack-outline"
@click="toggleBackpack()"
/>
</div>
<div class="pack-content bg-dark flex-grow-1">
<div class="pack-scores">
<ViewScoreStatus vertical />
</template>
<template #default>
<div class="pack-content bg-dark flex-grow-1">
<div class="pack-scores">
<ViewScoreStatus vertical />
</div>
<div
v-for="{ row, choices } in packRows"
:key="row.id"
class="pack-row"
>
<strong class="pack-row-title">
{{ row.title }}
</strong>
<ul class="list-group list-group-flush">
<li
v-for="{ obj } in choices"
:key="obj.id"
class="list-group-item choice"
>
{{ obj.title }}
<template v-if="obj.isSelectableMultiple">
(×{{ selected[obj.id] }})
</template>
</li>
</ul>
</div>
</div>
<div v-for="{ row, choices } in packRows" :key="row.id" class="pack-row">
<strong class="pack-row-title">
{{ row.title }}
</strong>
<ul class="list-group list-group-flush">
<li
v-for="{ obj } in choices"
:key="obj.id"
class="list-group-item choice"
>
{{ obj.title }}
<template v-if="obj.isSelectableMultiple">
(×{{ selected[obj.id] }})
</template>
</li>
</ul>
</div>
</div>
</SideDrawer>
</template>
</ModalDialog>
</template>

<script setup lang="ts">
import * as R from 'ramda';
import { computed } from 'vue';
import ModalDialog from '~/components/utils/ModalDialog.vue';
import { ProjectObj, ProjectRow } from '~/composables/project';
import { useProjectRefs, useProjectStore } from '~/composables/store/project';
import { useViewerRefs, useViewerStore } from '~/composables/store/viewer';
Expand Down Expand Up @@ -80,14 +79,19 @@ const packRows = computed(() => {
overflow: auto;
.pack-scores {
padding: 0 1em 1em 1em;
margin-bottom: 0.5rem;
}
.pack-row {
padding: 0;
.pack-row-title {
padding: 0 1rem;
font-size: 1.1em;
font-size: 1.1rem;
}
.choice {
padding-left: 0;
padding-right: 0;
}
}
}
Expand Down
84 changes: 72 additions & 12 deletions pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,90 @@
<template>
<div v-if="!isLoaded" id="container">
<div id="dialog">
<div v-if="project" class="text-light">
<ViewMenuBar />
<div class="project">
<div class="rows">
<ViewProjectRow
v-for="row in project.data.rows"
:key="row.id"
:row="row"
/>
</div>
</div>
<ViewBackpack />
<ViewSearch />
</div>
<div v-else class="dialog-container">
<div class="dialog bg-dark-subtle text-light">
<h5>Default Files</h5>
<ul class="list-group mb-3">
<li class="list-group-item">
<a
href="https://raw.githubusercontent.com/ltouroumov/worm-cyoa-v6-fork/master/project-v17.json"
@click.prevent="loadRemoteFile"
>
Worm V6 (Lt's Fork)
</a>
</li>
</ul>
<div
v-if="isLoading"
class="d-flex align-items-center justify-content-start gap-3 mb-3"
>
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<strong>Loading ...</strong>
</div>

<h5>Load File</h5>
<LoadProject />
</div>
</div>
</template>

<script setup lang="ts">
import { useProjectStore } from '~/composables/store/project';
import { ref } from '#imports';
import ViewBackpack from '~/components/viewer/modal/ViewBackpack.vue';
import ViewSearch from '~/components/viewer/modal/ViewSearch.vue';
import ViewMenuBar from '~/components/viewer/ViewMenuBar.vue';
import { useProjectRefs, useProjectStore } from '~/composables/store/project';
const { loadProject } = useProjectStore();
const { project } = useProjectRefs();
const isLoading = ref<boolean>(false);
const { isLoaded } = useProjectStore();
const loadRemoteFile = async ({ target }: MouseEvent) => {
if (target && target instanceof HTMLAnchorElement) {
isLoading.value = true;
const fileURL = target.href;
const result: any = await $fetch(fileURL, { parseResponse: JSON.parse });
loadProject(result, fileURL);
isLoading.value = false;
}
};
</script>

<style lang="scss">
#container {
width: 100vw;
height: 100vh;
.project {
background: black;
color: white;
font-family: sans-serif;
padding: 0 1em;
}
.dialog-container {
min-height: 50vh;
display: flex;
justify-content: center;
align-items: center;
}
#dialog {
border: 2px solid black;
border-radius: 10px;
padding: 10px;
.dialog {
border: 2px solid black;
border-radius: 10px;
padding: 10px;
}
}
</style>
Loading

0 comments on commit 274d439

Please sign in to comment.