Skip to content

Commit

Permalink
Reuse handling of cell selection with BSSelection component
Browse files Browse the repository at this point in the history
  • Loading branch information
xingrz committed Apr 1, 2024
1 parent 1007ccc commit 7d15e8d
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 53 deletions.
11 changes: 7 additions & 4 deletions src/components/BSMap/BSCell.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<template>
<div :class="$style.cell" :title="content" @click="handleClick" :style="style">
<BSIcon v-for="(icon, index) in (parts?.icons || [])" :key="index" :content="icon" :stacked="stacked"
@ratio="(ratio: number) => updateRatio(index, ratio)" />
</div>
<BSSelectable v-slot="{ selectable }" :row="props.row" :offset="props.offset" :length="props.content.length">
<div :class="[selectable, $style.cell]" :title="content" @click="handleClick" :style="style">
<BSIcon v-for="(icon, index) in (parts?.icons || [])" :key="index" :content="icon" :stacked="stacked"
@ratio="(ratio: number) => updateRatio(index, ratio)" />
</div>
</BSSelectable>
</template>

<script lang="ts" setup>
Expand All @@ -16,6 +18,7 @@ import {
import { useEditorStore } from '@/stores/editor';
import styleFromParams from '@/utils/styleFromParams';
import BSSelectable from './BSSelectable.vue';
import BSIcon from './BSIcon.vue';
const props = defineProps<{
Expand Down
51 changes: 3 additions & 48 deletions src/components/BSMap/BSRow.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
<template>
<div :class="$style.row">
<div :class="$style.cells" :style="rowStyle">
<BSCell v-for="({ cell, offset }, index) in cells" :key="index"
:class="{ [$style.seletable]: true, [$style.focused]: isFocused(row, offset, cell.length) }" :content="cell"
:row="row" :offset="offset" />
<BSCell v-for="({ cell, offset }, index) in cells" :key="index" :content="cell" :row="row" :offset="offset" />
</div>
<div :class="$style.texts">
<BSText v-for="({ text, offset, align }, index) in texts" :key="index"
:class="{ [$style.seletable]: true, [$style.focused]: isFocused(row, offset, text.length) }" :content="text"
:align="align" :row="row" :offset="offset" />
<BSText v-for="({ text, offset, align }, index) in texts" :key="index" :content="text" :align="align" :row="row"
:offset="offset" />
</div>
</div>
</template>

<script lang="ts" setup>
import { computed, defineProps } from 'vue';
import { useEditorStore } from '@/stores/editor';
import styleFromParams from '@/utils/styleFromParams';
import BSCell from './BSCell.vue';
Expand All @@ -27,8 +23,6 @@ const props = defineProps<{
row: number;
}>();
const editorStore = useEditorStore();
const parts = computed(() => {
let offset = 0;
return props.content.split('~~').map((part) => {
Expand Down Expand Up @@ -60,16 +54,6 @@ const texts = computed(() => {
});
const rowStyle = computed(() => styleFromParams(parts.value[5]?.part));
function isFocused(row: number, offset: number, length: number): boolean {
const { selection } = editorStore;
return (
typeof selection != 'undefined' &&
selection.row == row &&
selection.offset >= offset &&
selection.offset <= offset + length
);
}
</script>

<style lang="scss" module>
Expand All @@ -88,33 +72,4 @@ function isFocused(row: number, offset: number, length: number): boolean {
flex: 1 1 auto;
display: flex;
}
.seletable {
position: relative;
&::after {
display: block;
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #0099ff;
opacity: 0;
transition: opacity 200ms;
}
&:hover::after {
opacity: 0.2;
}
&.focused::after {
opacity: 0.3;
}
}
</style>
61 changes: 61 additions & 0 deletions src/components/BSMap/BSSelectable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<slot :selectable="{
[$style.selectable]: true,
[$style.focused]: focused,
}" />
</template>

<script lang="ts" setup>
import { computed, defineProps } from 'vue';
import { useEditorStore } from '@/stores/editor';
const props = defineProps<{
row: number;
offset: number;
length: number;
}>();
const editorStore = useEditorStore();
const focused = computed(() => {
const { selection } = editorStore;
return (
typeof selection != 'undefined' &&
selection.row == props.row &&
selection.offset >= props.offset &&
selection.offset <= props.offset + props.length
);
});
</script>

<style lang="scss" module>
.selectable {
position: relative;
&::after {
display: block;
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #0099ff;
opacity: 0;
transition: opacity 200ms;
}
&:hover::after {
opacity: 0.2;
}
&.focused::after {
opacity: 0.3;
}
}
</style>
7 changes: 6 additions & 1 deletion src/components/BSMap/BSText.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
<template>
<div :class="$style.text" :data-align="align" :title="content" @click="handleClick">{{ content }}</div>
<BSSelectable v-slot="{ selectable }" :row="props.row" :offset="props.offset" :length="props.content.length">
<div :class="[selectable, $style.text]" :data-align="align" :title="content" @click="handleClick">{{ content }}
</div>
</BSSelectable>
</template>

<script lang="ts" setup>
import { defineProps } from 'vue';
import { useEditorStore } from '@/stores/editor';
import BSSelectable from './BSSelectable.vue';
const props = defineProps<{
content: string;
align: number;
Expand Down

0 comments on commit 7d15e8d

Please sign in to comment.