advent22/ui/src/components/calendar/SVGRect.vue

134 lines
2.5 KiB
Vue
Raw Normal View History

2023-01-17 18:25:56 +00:00
<template>
2023-09-22 19:02:51 +00:00
<foreignObject
:x="Math.round(parent_aspect_ratio * rectangle.left)"
:y="rectangle.top"
:width="Math.round(parent_aspect_ratio * rectangle.width)"
:height="rectangle.height"
:style="`transform: scaleX(${1 / parent_aspect_ratio})`"
>
<div
v-if="variant !== undefined"
xmlns="http://www.w3.org/1999/xhtml"
class="px-4 is-flex is-align-items-center is-justify-content-center is-size-1 has-text-weight-bold"
2023-10-27 15:09:44 +00:00
style="height: inherit"
2023-09-22 19:02:51 +00:00
>
<slot name="default" />
</div>
</foreignObject>
2023-09-07 01:17:14 +00:00
<rect
2023-09-22 19:02:51 +00:00
ref="rect"
v-bind="$attrs"
:class="variant !== undefined ? variant : ''"
2023-09-07 01:17:14 +00:00
:x="rectangle.left"
:y="rectangle.top"
:width="rectangle.width"
:height="rectangle.height"
/>
2023-01-17 18:25:56 +00:00
</template>
<script lang="ts">
2023-09-07 02:08:56 +00:00
import { Rectangle } from "@/lib/rectangle";
2023-09-06 16:25:35 +00:00
import { Options, Vue } from "vue-class-component";
2023-01-17 18:25:56 +00:00
2023-09-22 19:02:51 +00:00
type BulmaVariant =
| "primary"
| "link"
| "info"
| "success"
| "warning"
| "danger";
2023-09-20 16:16:45 +00:00
2023-01-17 18:25:56 +00:00
@Options({
props: {
variant: {
2023-09-20 16:16:45 +00:00
type: String,
required: false,
2023-01-17 18:25:56 +00:00
},
rectangle: Rectangle,
},
})
2023-01-24 23:19:25 +00:00
export default class extends Vue {
2023-09-22 19:02:51 +00:00
public variant?: BulmaVariant;
2023-09-06 16:25:35 +00:00
public rectangle!: Rectangle;
2023-09-22 19:02:51 +00:00
private refreshKey = 0;
declare $refs: {
rect: unknown;
};
private refresh() {
window.setTimeout(() => {
// don't loop endlessly
if (this.refreshKey < 10000) {
this.refreshKey++;
}
}, 100);
}
public get parent_aspect_ratio(): number {
this.refreshKey; // read it just to force recompute on change
if (
!(this.$refs.rect instanceof SVGRectElement) ||
this.$refs.rect.parentElement === null
) {
this.refresh();
return 1;
}
const parent = this.$refs.rect.parentElement;
const result = parent.clientWidth / parent.clientHeight;
// force recompute for suspicious results
if (result === 0 || result === Infinity) {
this.refresh();
return 1;
}
return result;
}
2023-01-17 18:25:56 +00:00
}
</script>
<style lang="scss" scoped>
@import "@/bulma-vars";
2023-01-17 18:25:56 +00:00
rect {
2023-09-20 16:16:45 +00:00
fill: transparent;
fill-opacity: 0.3;
stroke-opacity: 0.9;
stroke-width: 1;
2023-09-20 16:16:45 +00:00
&.primary {
fill: $primary;
stroke: $primary;
}
2023-09-20 16:16:45 +00:00
&.link {
fill: $link;
stroke: $link;
}
&.info {
fill: $info;
stroke: $info;
}
&.success {
fill: $success;
stroke: $success;
}
&.warning {
fill: $warning;
stroke: $warning;
}
2023-01-17 18:25:56 +00:00
&.danger {
fill: $danger;
stroke: $danger;
2023-01-17 18:25:56 +00:00
}
}
2023-09-07 01:17:14 +00:00
</style>