-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add settings for calendar decorations
- Loading branch information
1 parent
792901f
commit 0112d75
Showing
28 changed files
with
1,701 additions
and
90 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<script setup lang="ts"> | ||
import { ref } from "vue"; | ||
import ObsidianButton from "./obsidian/ObsidianButton.vue"; | ||
import { onClickOutside } from "@vueuse/core"; | ||
defineProps<{ | ||
options: string[]; | ||
}>(); | ||
const emit = defineEmits<(event: "select", option: string) => void>(); | ||
const isOpen = ref(false); | ||
const buttonRef = ref<InstanceType<typeof ObsidianButton>>(); | ||
const popoutRef = ref<HTMLElement>(); | ||
const popoutPosition = ref({}); | ||
onClickOutside(popoutRef, () => { | ||
isOpen.value = false; | ||
}); | ||
function open() { | ||
if (!buttonRef.value) return; | ||
const rect = buttonRef.value.$el.getBoundingClientRect(); | ||
popoutPosition.value = { | ||
top: `${rect.top + rect.height}px`, | ||
left: `${rect.left}px`, | ||
}; | ||
isOpen.value = true; | ||
} | ||
function select(option: string) { | ||
isOpen.value = false; | ||
emit("select", option); | ||
} | ||
</script> | ||
|
||
<template> | ||
<div class="button-dropdown"> | ||
<ObsidianButton ref="buttonRef" @click="open"><slot /></ObsidianButton> | ||
<Teleport to="body"> | ||
<div v-if="isOpen" ref="popoutRef" class="button-dropdown-popout" :style="popoutPosition"> | ||
<ObsidianButton | ||
v-for="option in options" | ||
:key="option" | ||
flat | ||
class="button-dropdown-option" | ||
@click="select(option)" | ||
> | ||
{{ option }} | ||
</ObsidianButton> | ||
</div> | ||
</Teleport> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
.button-dropdown { | ||
position: relative; | ||
display: inline-block; | ||
} | ||
.button-dropdown-popout { | ||
position: fixed; | ||
z-index: 1000; | ||
box-shadow: var(--shadow-l); | ||
background-color: var(--modal-background); | ||
border-radius: var(--radius-s); | ||
border: var(--modal-border-width) solid var(--modal-border-color); | ||
padding: var(--size-2-2); | ||
} | ||
.button-dropdown-option { | ||
width: 100%; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<script setup lang="ts"> | ||
import type { BorderSettings, JournalDecorationsStyle } from "@/types/settings.types"; | ||
import { computed } from "vue"; | ||
import DecorationShape from "./decorations/DecorationShape.vue"; | ||
import DecorationCorner from "./decorations/DecorationCorner.vue"; | ||
import DecorationIcon from "./decorations/DecorationIcon.vue"; | ||
const props = defineProps<{ styles: JournalDecorationsStyle[] }>(); | ||
const background = computed(() => { | ||
const decoration = props.styles.find((d) => d.type === "background"); | ||
if (!decoration) return "inherit"; | ||
return decoration.color; | ||
}); | ||
const textColor = computed(() => { | ||
const decoration = props.styles.find((d) => d.type === "color"); | ||
if (!decoration) return "inherit"; | ||
return decoration.color; | ||
}); | ||
const shapeDecorations = computed(() => props.styles.filter((d) => d.type === "shape")); | ||
const cornerDecorations = computed(() => props.styles.filter((d) => d.type === "corner")); | ||
const iconDecorations = computed(() => props.styles.filter((d) => d.type === "icon")); | ||
const borderDecorations = computed(() => props.styles.filter((d) => d.type === "border")); | ||
const borderStyle = computed(() => { | ||
const style = { | ||
borderTop: "none", | ||
borderBottom: "none", | ||
borderLeft: "none", | ||
borderRight: "none", | ||
}; | ||
for (const decoration of borderDecorations.value) { | ||
if (decoration.border === "uniform") { | ||
const calculated = toBorderStyle(decoration.left); | ||
if (calculated !== "none") { | ||
style.borderTop = calculated; | ||
style.borderBottom = calculated; | ||
style.borderLeft = calculated; | ||
style.borderRight = calculated; | ||
} | ||
} else { | ||
const left = toBorderStyle(decoration.left); | ||
if (left !== "none") style.borderLeft = left; | ||
const right = toBorderStyle(decoration.right); | ||
if (right !== "none") style.borderRight = right; | ||
const top = toBorderStyle(decoration.top); | ||
if (top !== "none") style.borderTop = top; | ||
const bottom = toBorderStyle(decoration.bottom); | ||
if (bottom !== "none") style.borderBottom = bottom; | ||
} | ||
} | ||
return style; | ||
}); | ||
function toBorderStyle(side: BorderSettings) { | ||
if (!side.show) return "none"; | ||
return `${side.width}px ${side.style} ${side.color}`; | ||
} | ||
</script> | ||
|
||
<template> | ||
<div class="calendar-decoration" :style="borderStyle"> | ||
<slot></slot> | ||
<DecorationShape v-for="(decoration, index) in shapeDecorations" :key="index" :decoration="decoration" /> | ||
<DecorationCorner v-for="(decoration, index) in cornerDecorations" :key="index" :decoration="decoration" /> | ||
<DecorationIcon v-for="(decoration, index) in iconDecorations" :key="index" :decoration="decoration" /> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
.calendar-decoration { | ||
position: relative; | ||
background-color: v-bind(background); | ||
color: v-bind(textColor); | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<script setup lang="ts"> | ||
import type { JournalDecorationCorner } from "@/types/settings.types"; | ||
import { computed } from "vue"; | ||
const props = defineProps<{ | ||
decoration: JournalDecorationCorner; | ||
}>(); | ||
const color = computed(() => props.decoration.color); | ||
</script> | ||
|
||
<template> | ||
<div class="decoration-corner" :class="[decoration.placement]"></div> | ||
</template> | ||
|
||
<style scoped> | ||
.decoration-corner { | ||
position: absolute; | ||
width: 0; | ||
height: 0; | ||
--size: 0.3em; | ||
} | ||
.top-left { | ||
top: 0; | ||
left: 0; | ||
border-top: var(--size) solid v-bind(color); | ||
border-right: var(--size) solid transparent; | ||
} | ||
.top-right { | ||
top: 0; | ||
right: 0; | ||
border-top: var(--size) solid v-bind(color); | ||
border-left: var(--size) solid transparent; | ||
} | ||
.bottom-left { | ||
bottom: 0; | ||
left: 0; | ||
border-bottom: var(--size) solid v-bind(color); | ||
border-right: var(--size) solid transparent; | ||
} | ||
.bottom-right { | ||
bottom: 0; | ||
right: 0; | ||
border-bottom: var(--size) solid v-bind(color); | ||
border-left: var(--size) solid transparent; | ||
} | ||
</style> |
Oops, something went wrong.