From 55bd5f9fe77538a9fa58d91c2fe2a93416a59915 Mon Sep 17 00:00:00 2001 From: XiNGRZ Date: Wed, 27 Mar 2024 12:52:41 +0800 Subject: [PATCH] Bring full support for row- and cell-params (#11 #5) --- src/components/BSMap/BSCell.vue | 20 ++++--- src/components/BSMap/BSIcon.vue | 93 +++++++++++++-------------------- src/components/BSMap/BSRow.vue | 7 ++- src/utils/styleFromParams.ts | 78 +++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 66 deletions(-) create mode 100644 src/utils/styleFromParams.ts diff --git a/src/components/BSMap/BSCell.vue b/src/components/BSMap/BSCell.vue index 2f1a373..0ff4c1b 100644 --- a/src/components/BSMap/BSCell.vue +++ b/src/components/BSMap/BSCell.vue @@ -1,6 +1,6 @@ @@ -14,6 +14,7 @@ import { } from 'vue'; import { useEditorStore } from '@/stores/editor'; +import styleFromParams from '@/utils/styleFromParams'; import BSIcon from './BSIcon.vue'; @@ -27,15 +28,20 @@ const editorStore = useEditorStore(); const ratio = ref(1); -const icons = computed(() => { - if (!props.content) return []; - return props.content - .split('!~') - .map((icon) => icon.trim()) - .filter((icon) => !!icon); +const parts = computed(() => { + if (!props.content) return; + + const [nonParam, ...params] = props.content.split('!_'); + const [nonLink, ...links] = nonParam.split('!@'); + const icons = nonLink.split('!~').filter((icon) => !!icon); + + return { icons, links, params }; }); +const stacked = computed(() => !!parts.value && parts.value.icons.length > 1); + const style = computed(() => ({ + ...styleFromParams(parts.value?.params?.[0], true), '--bs-map-cell-ratio': (ratio.value == 1 ? undefined : ratio.value), }) as CSSProperties); diff --git a/src/components/BSMap/BSIcon.vue b/src/components/BSMap/BSIcon.vue index 71a3fd3..a18c3cd 100644 --- a/src/components/BSMap/BSIcon.vue +++ b/src/components/BSMap/BSIcon.vue @@ -1,7 +1,6 @@ @@ -12,16 +11,15 @@ import { computed, defineEmits, defineProps, - onMounted, - toRef, watch, } from 'vue'; -import { parse } from 'qs'; import { useIconStore } from '@/stores/icon'; +import styleFromParams from '@/utils/styleFromParams'; const props = defineProps<{ content: string; + stacked: boolean; }>(); const emit = defineEmits<{ @@ -30,40 +28,39 @@ const emit = defineEmits<{ const iconStore = useIconStore(); -const content = toRef(props, 'content'); +const content = computed(() => { + return props.stacked ? props.content.split('__')[0] : props.content; +}); + +const params = computed(() => { + // available only for stacked icons + return props.stacked ? props.content.split('__')[1] : undefined; +}); -const label = computed(() => { - if (content.value && content.value.match(/^(.*)\*([^_]+)(__(.+)$)?/)) { - const ratio = selectTextWidth(RegExp.$1) as number; - const text = RegExp.$2; - const params = parseTextParams(RegExp.$4 || ''); - return { text, ratio, params }; +const text = computed(() => { + let match: RegExpMatchArray | null = null; + if (content.value && (match = content.value.match(/^(.*)\*([^_]+)$/))) { + const ratio = selectTextWidth(match[1]) as number; + const data = match[2]; + return { data, ratio }; } else { return undefined; } }); -const icon = computed(() => label.value ? undefined : iconStore.icons[content.value]); +const icon = computed(() => text.value ? undefined : iconStore.icons[content.value]); watch(content, (content) => { - if (content && !label.value) { + if (content && !text.value) { iconStore.resolve(content); } }, { immediate: true }); -const ratio = computed(() => { - if (!content.value) return 1; - if (label.value) { - return label.value.ratio || 1; - } else { - return icon.value?.ratio || 1; - } -}); - -watch(ratio, (ratio) => emit('ratio', ratio)); -onMounted(() => emit('ratio', ratio.value)); +const ratio = computed(() => (text.value ?? icon.value)?.ratio ?? 1); +watch(ratio, (ratio) => emit('ratio', ratio), { immediate: true }); const style = computed(() => ({ + ...styleFromParams(params.value, true), '--bs-map-icon-ratio': (ratio.value == 1 ? undefined : ratio.value), }) as CSSProperties); @@ -75,25 +72,25 @@ function selectTextWidth(flag: string): number | undefined { return 0.25; case 'd': return 0.5; + case 'cd': + return 0.75; case 'b': return 2; case 's': return 4; + case 'bs': + return 6; case 'w': return 8; + default: + return undefined; } } - -function parseTextParams(str: string): Record { - return parse(str, { - delimiter: ',' - }) as Record; -} diff --git a/src/components/BSMap/BSRow.vue b/src/components/BSMap/BSRow.vue index 8eacbc5..b62a384 100644 --- a/src/components/BSMap/BSRow.vue +++ b/src/components/BSMap/BSRow.vue @@ -1,6 +1,6 @@