fix: 지도 호출부별 선택 동작을 분리

메인 지도는 선택 테두리를 숨기고 명령 대상 지도는 터치 첫 탭에 도시와 국가를 선택하도록 분리한다. 현재 도시는 반복 점멸 대신 고정 고대비 이중 링으로 강조한다.
This commit is contained in:
2026-08-21 15:25:14 +00:00
parent c6b916f0c2
commit 1d473cf704
6 changed files with 140 additions and 12 deletions
@@ -68,6 +68,7 @@ const touchend = (event: TouchEvent) => {
:to="
props.selectOnly || props.readonly ? undefined : { name: 'current-city', query: { cityId: props.city.id } }
"
:aria-label="props.city.isMyCity ? `${props.city.name}, 현재 도시` : props.city.name"
:class="[
`state-${props.city.stateClass}`,
{
@@ -125,6 +126,7 @@ const touchend = (event: TouchEvent) => {
}
.city-dot {
position: relative;
border: 1px solid rgba(232, 221, 196, 0.6);
display: flex;
align-items: center;
@@ -138,8 +140,16 @@ const touchend = (event: TouchEvent) => {
background: rgba(232, 221, 196, 0.9);
}
.map-city.mine .city-dot {
box-shadow: 0 0 0 2px rgba(201, 164, 90, 0.6);
.map-city.mine .city-dot::after {
position: absolute;
inset: -4px;
box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 0.95);
border-radius: 2px;
outline: 2px solid rgb(211, 47, 47);
box-shadow: 0 0 6px 2px rgba(211, 47, 47, 0.72);
content: '';
pointer-events: none;
}
.map-city.selected .city-dot {
@@ -184,6 +184,7 @@ const cityStateStyle = computed(() => ({
:to="
props.selectOnly || props.readonly ? undefined : { name: 'current-city', query: { cityId: props.city.id } }
"
:aria-label="props.city.isMyCity ? `${props.city.name}, 현재 도시` : props.city.name"
:class="[
{
mine: props.city.isMyCity,
@@ -256,11 +257,16 @@ const cityStateStyle = computed(() => ({
.city-filler {
position: absolute;
inset: -2px;
box-sizing: border-box;
pointer-events: none;
}
.city-base.mine .city-icon {
box-shadow: 0 0 0 1px rgba(201, 164, 90, 0.7);
.city-filler.my-city {
inset: -4px;
border: 1px solid rgba(255, 255, 255, 0.95);
border-radius: 2px;
outline: 2px solid rgb(211, 47, 47);
box-shadow: 0 0 6px 2px rgba(211, 47, 47, 0.72);
}
.city-base.selected .city-icon {
@@ -72,12 +72,14 @@ const props = withDefaults(
detailMode?: boolean;
fitContainer?: boolean;
showCurrentCityMarker?: boolean;
showSelectionBorder?: boolean;
readonly?: boolean;
}>(),
{
// Vue casts an absent Boolean prop to false unless undefined is an explicit default.
detailMode: undefined,
selectedCityId: undefined,
showSelectionBorder: true,
}
);
@@ -176,6 +178,7 @@ const effectiveDetailMode = computed(() => props.detailMode ?? storeDetailMode.v
const effectiveSelectedCityId = computed(() =>
props.selectedCityId === undefined ? storeSelectedCityId.value : props.selectedCityId
);
const isSelectionMap = computed(() => props.selectedCityId !== undefined);
const mapWidth = computed(() => `${BASE_MAP_WIDTH * mapScale.value}px`);
@@ -213,7 +216,7 @@ const cityViews = computed<CityView[]>(() => {
y,
isCapital: nation?.capitalCityId === layoutCity.id,
isMyCity: props.mapData?.myCity === layoutCity.id,
selected: effectiveSelectedCityId.value === layoutCity.id,
selected: props.showSelectionBorder && effectiveSelectedCityId.value === layoutCity.id,
};
});
});
@@ -417,7 +420,7 @@ const touchCity = (cityId: number, event: TouchEvent) => {
if (touchPreviewCityId.value !== cityId) {
touchPreviewCityId.value = cityId;
setHoveredCity(cityId);
if (!singleTapNavigation.value) {
if (!isSelectionMap.value && !singleTapNavigation.value) {
event.preventDefault();
}
}
@@ -469,7 +472,7 @@ const selectCity = (cityId: number) => {
:city="city"
:map-scale="mapScale"
:show-name="showCityName"
:select-only="props.selectedCityId !== undefined"
:select-only="isSelectionMap"
:readonly="props.readonly"
v-bind="detailProps"
@hover="setHoveredCity"
@@ -497,7 +500,7 @@ const selectCity = (cityId: number) => {
도시명 표기 {{ showCityName ? '끄기' : '켜기' }}
</button>
<button
v-if="hasTouchInput"
v-if="hasTouchInput && !isSelectionMap && !props.readonly"
class="map-toggle map-toggle-single-tap"
:class="{ active: singleTapNavigation }"
:aria-pressed="singleTapNavigation"
+12 -2
View File
@@ -324,7 +324,12 @@ watch(
<div v-else-if="panelId === 'map'" class="mobile-panel" data-mobile-panel-id="map">
<PanelCard title="지도" data-main-target="map">
<MapViewer :map-data="worldMap" :map-layout="mapLayout" :loading="loading" />
<MapViewer
:map-data="worldMap"
:map-layout="mapLayout"
:loading="loading"
:show-selection-border="false"
/>
</PanelCard>
</div>
@@ -415,7 +420,12 @@ watch(
<section v-else class="layout-desktop">
<PanelCard title="지도" subtitle="실시간 지도 + 도시 상황" data-main-target="map">
<MapViewer :map-data="worldMap" :map-layout="mapLayout" :loading="loading" />
<MapViewer
:map-data="worldMap"
:map-layout="mapLayout"
:loading="loading"
:show-selection-border="false"
/>
</PanelCard>
<PanelCard title="명령 목록" aria-label="명령 목록" data-main-target="commands">
<CommandListPanel