From a81bb98c971bd9470bbba0c415b6c111f5146ad3 Mon Sep 17 00:00:00 2001
From: Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com>
Date: Sun, 8 Nov 2026 00:48:32 +0900
Subject: 公園マップ: フィルタを分類・拡充し、地図の表示不具合を修正
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ParksFilters.astro: フィルタを「遊具/広場・休憩/設備/利用ルール」に
分類し、パーゴラ・ボール遊び禁止の表示なし・犬禁止の表示なしを追加。
冒頭にβ版の注意書きを追加
ParkMap.astro: 全画面時のズーム調整と、小数ズーム時のタイル読込の
不具合を修正
ParksTable.astro: 絞り込みトークンを追加し、確認済みの表示を反映
park-editor: 確認チェックの自動同期と文字化けを修正
kodaira-parks.json: 水飲み場表記の統一と確認済みを反映
park-icons.ts: パーゴラのアイコンを追加
parks.mdx: 説明文を更新
---
src/components/ParksTable.astro | 564 ++++++++++++++++++++++++++--------------
1 file changed, 367 insertions(+), 197 deletions(-)
(limited to 'src/components/ParksTable.astro')
diff --git a/src/components/ParksTable.astro b/src/components/ParksTable.astro
index 5b7f5ac..81a93e2 100644
--- a/src/components/ParksTable.astro
+++ b/src/components/ParksTable.astro
@@ -4,6 +4,7 @@
// DOM を抑えるため、設備は1セルにまとめ、アイコンは CSS の擬似要素で描く。
// 絞り込み・並べ替え・カード表示は利用者の端末で実行する。
import { parks, mappedNames, type Park } from "@/data/parks-rows";
+import { PARK_ICONS } from "@/data/park-icons";
const EMPTY = "—";
@@ -76,33 +77,6 @@ function ownerClass(owner: string): string {
return "parks-owner--other";
}
-// 設備バッジ(アイコンは CSS の ::before で描く)。
-type Badge = { kind: string; label: string; title: string };
-function facilityBadges(p: Park): Badge[] {
- const badges: Badge[] = [];
- if (p["トイレ"]) {
- badges.push({ kind: "toilet", label: "トイレ", title: `トイレ: ${p["トイレ"]}` });
- }
- if (p["水飲み場"]) {
- badges.push({ kind: "water", label: "水飲み場", title: `水飲み場: ${p["水飲み場"]}` });
- }
- if (p["給水"]) {
- badges.push({ kind: "water", label: "給水", title: `給水: ${p["給水"]}` });
- }
- if (p["遊具"]) {
- badges.push({ kind: "toy", label: "遊具", title: `遊具: ${p["遊具"]}` });
- }
- const ball = p["ボール遊び"];
- if (ball && ball !== "禁止") {
- const label = ball.includes("一部") ? "ボール遊び一部可" : "ボール遊び可";
- badges.push({ kind: "ball", label, title: `ボール遊び: ${ball}` });
- }
- if (p["南西部指定管理"]) {
- badges.push({ kind: "cm", label: "指定管理", title: "南西部地域の指定管理公園" });
- }
- return badges;
-}
-
// スイング遊具・健康遊具の判定用
const SPRING_TOKENS = [
"スプリング", "スイング", "リトルポップ", "リンクミニ", "ルッキンロッキン",
@@ -156,7 +130,11 @@ function facTokens(p: Park): string {
if (play.includes("滑り台") || play.includes("滑台")) tokens.push("slide");
if (play.includes("複合遊具")) tokens.push("complex");
if (play.includes("バスケ")) tokens.push("basket");
- if ((p["シェルター等"] || "").trim()) tokens.push("shelter");
+ // シェルター等の欄には、シェルター・東屋・パーゴラ・GTシェードが混在している。
+ // 「東屋/シェルター」と「パーゴラ」を別々に絞れるよう、キーワードで分ける。
+ const shelterText = (p["シェルター等"] || "").trim();
+ if (/東屋|シェルター|シェード/.test(shelterText)) tokens.push("shelter");
+ if (shelterText.includes("パーゴラ")) tokens.push("pergola");
if (HEALTH_TOKENS.some((token) => play.includes(token))) tokens.push("health");
if (hasSpecialToy(play)) tokens.push("special");
if (play.includes("幼児")) tokens.push("toddler");
@@ -167,26 +145,40 @@ function facTokens(p: Park): string {
if (p["草地広場"]) tokens.push("picnic");
// 野外卓・縁台がある公園。
if ((p["野外卓"] || "").trim()) tokens.push("table");
+ // 利用ルール(ボール遊び禁止の表示なし・犬禁止の表示なし)。
+ // 「禁止」と記録されていない公園を対象にする(未記録も含む)。
+ // 公共施設と市外の公園は利用ルールを調べていないので対象外。
+ if (p["施設"] !== "1" && p["種別"] !== "市外") {
+ if (!/禁止/.test(p["ボール遊び"] || "")) tokens.push("ballok");
+ if (!/禁止/.test(p["ペット"] || "")) tokens.push("dogok");
+ }
return tokens.join(" ");
}
-// 設備セルの補足テキスト(バッジで示した項目の詳細と、その他の項目)。
-// ラベル文字は使わず、アイコンで項目を示す。
-const DETAIL_FIELDS: { key: string; icon: string }[] = [
- { key: "ベンチ・椅子", icon: "🪑" },
- { key: "野外卓", icon: "🍽" },
- { key: "シェルター等", icon: "⛱" },
- { key: "草地広場", icon: "🌿" },
- { key: "多目的広場", icon: "🏟" },
- { key: "築山", icon: "⛰" },
- { key: "じゃぶじゃぶ池", icon: "💦" },
- { key: "防災用具", icon: "🛟" },
- { key: "遊具", icon: "🎠" },
- { key: "時計", icon: "⏰" },
- { key: "駐車場", icon: "🅿" },
- { key: "その他設備", icon: "🔧" },
- { key: "備考", icon: "" },
+// 一覧の施設・備考は、フキダシと同じ「アイコン+値」の行で表示する。
+const FACILITY_KEYS = [
+ "ベンチ・椅子", "野外卓", "シェルター等", "草地広場", "多目的広場",
+ "築山", "じゃぶじゃぶ池", "防災用具", "遊具", "時計", "駐車場",
+ "その他設備", "備考",
];
+type FacilityRow = { icon: string; cls: string; value: string; banned?: boolean };
+const textOf = (value: unknown) => String(value ?? "").trim();
+const presenceText = (label: string, value: unknown) => {
+ const v = textOf(value);
+ if (!v) return "";
+ return /^[○〇◯あり有1]+$/.test(v) ? `${label}あり` : v;
+};
+const waterText = (value: string) => {
+ const text = textOf(value);
+ if (!text) return "";
+ if (/[??]/.test(text)) return "水飲み場?";
+ let total = 0;
+ for (const part of text.split(/[、,]/)) {
+ const nums = [...part.matchAll(/[x×](\d+)/g)].map((m) => Number(m[1]));
+ if (nums.length) total += nums.reduce((a, b) => a * b, 1);
+ }
+ return total > 0 ? `水飲み場x${total}` : "水飲み場";
+};
function disasterText(value: string): string {
return value
.split(/[、,]/)
@@ -195,18 +187,82 @@ function disasterText(value: string): string {
.filter((s) => /かまど|カマド|防災収納|レスキュー|防災器具|避難/.test(s))
.join("、");
}
-function detailText(p: Park): string {
- const parts: string[] = [];
- for (const { key, icon } of DETAIL_FIELDS) {
- const raw = p[key];
- if (!raw) continue;
- const value = key === "防災用具" ? disasterText(raw) : raw;
- if (!value) continue;
- parts.push(icon ? `${icon} ${value}` : value);
- }
- const ball = p["ボール遊び"];
- if (ball && ball !== "禁止" && ball !== "可") parts.push(`⚽ ${ball}`);
- return parts.join(" / ");
+function facilityRows(p: Park): FacilityRow[] {
+ const rows: FacilityRow[] = [];
+ // 遊具もフキダシと同じく「遊」の文字アイコンを付ける。
+ if (textOf(p["遊具"])) {
+ rows.push({ icon: '遊', cls: "", value: textOf(p["遊具"]) });
+ }
+ if (textOf(p["トイレ"])) {
+ rows.push({
+ icon: 'WC',
+ cls: "is-toilet",
+ value: textOf(p["トイレ"]),
+ });
+ }
+ const water = textOf(p["水飲み場"]);
+ if (water) {
+ rows.push({ icon: PARK_ICONS.water.svg, cls: "is-water", value: waterText(water) });
+ }
+ if (textOf(p["給水"])) {
+ rows.push({ icon: PARK_ICONS.water.svg, cls: "is-water", value: textOf(p["給水"]) });
+ }
+ if (textOf(p["ベンチ・椅子"])) {
+ rows.push({ icon: PARK_ICONS.bench.svg, cls: "is-bench", value: textOf(p["ベンチ・椅子"]) });
+ }
+ if (textOf(p["野外卓"])) {
+ rows.push({ icon: PARK_ICONS.picnic.svg, cls: "", value: textOf(p["野外卓"]) });
+ }
+ if (textOf(p["シェルター等"])) {
+ rows.push({ icon: PARK_ICONS.shelter.svg, cls: "", value: textOf(p["シェルター等"]) });
+ }
+ if (textOf(p["草地広場"])) {
+ rows.push({ icon: PARK_ICONS.grass.svg, cls: "is-grass", value: presenceText("草地広場", p["草地広場"]) });
+ }
+ if (textOf(p["多目的広場"])) {
+ rows.push({ icon: '広', cls: "", value: presenceText("多目的広場", p["多目的広場"]) });
+ }
+ if (textOf(p["築山"])) {
+ rows.push({ icon: PARK_ICONS.mountain.svg, cls: "", value: presenceText("築山", p["築山"]) });
+ }
+ if (textOf(p["じゃぶじゃぶ池"])) {
+ rows.push({ icon: PARK_ICONS.pond.svg, cls: "is-pond", value: presenceText("じゃぶじゃぶ池", p["じゃぶじゃぶ池"]) });
+ }
+ const ballText = textOf(p["ボール遊び"]);
+ const matchText = textOf(p["試合形式のボール遊び"]);
+ const ballBanned = /禁止/.test(ballText);
+ const ballValue = ballBanned
+ ? "ボール遊び禁止"
+ : /禁止/.test(matchText)
+ ? "試合形式禁止"
+ : ballText;
+ if (ballValue) {
+ rows.push({ icon: PARK_ICONS.ball.svg, cls: "is-ball", value: ballValue, banned: ballBanned });
+ }
+ const pet = textOf(p["ペット"]);
+ if (pet) {
+ rows.push({ icon: PARK_ICONS.dog.svg, cls: "is-pet", value: pet, banned: /禁止/.test(pet) });
+ }
+ if (textOf(p["時計"])) {
+ rows.push({ icon: PARK_ICONS.clock.svg, cls: "is-clock", value: presenceText("時計", p["時計"]) });
+ }
+ const disaster = disasterText(textOf(p["防災用具"]));
+ if (disaster) {
+ rows.push({ icon: '災', cls: "", value: disaster });
+ }
+ if (textOf(p["駐車場"])) {
+ rows.push({ icon: 'P', cls: "", value: textOf(p["駐車場"]) });
+ }
+ if (textOf(p["その他設備"])) {
+ rows.push({ icon: '他', cls: "", value: textOf(p["その他設備"]) });
+ }
+ if (textOf(p["備考"])) {
+ rows.push({ icon: "", cls: "", value: textOf(p["備考"]) });
+ }
+ if (p["南西部指定管理"]) {
+ rows.push({ icon: "", cls: "", value: "指定管理" });
+ }
+ return rows;
}
// 面積(数値)
@@ -261,21 +317,18 @@ function searchIndex(p: Park): string {
p["築山"] ? "築山" : "",
p["じゃぶじゃぶ池"] ? "じゃぶじゃぶ池" : "",
p["ボール遊び"],
- ...DETAIL_FIELDS.map((f) => p[f.key]),
+ ...FACILITY_KEYS.map((key) => p[key]),
]
.join(" ")
.toLowerCase();
}
-// 名称・住所などが未確認の公園
+// 編集画面(park-editor)の確認チェックが「済」でないものを未確認とする。
+// 対象は市内公園(市内の公共施設・市外の公園は各タブで管理する)。
function isUnconfirmed(p: Park): boolean {
if (p["施設"] === "1") return false;
- return (
- (p["備考"] || "").includes("未確認") ||
- (p["住所"] || "").includes("未確認") ||
- (p["状態"] || "").includes("未確認") ||
- (p["公園名"] || "").includes("未確認")
- );
+ if (p["種別"] === "市外") return false;
+ return (p["確認"] || "") !== "済";
}
---
@@ -301,7 +354,7 @@ function isUnconfirmed(p: Park): boolean {
住所 |
|
種別 |
@@ -327,7 +380,12 @@ function isUnconfirmed(p: Park): boolean {
data-focus-park={park["公園名"]}
data-focus-key={park["地図キー"] || ""}
title="地図でこの公園の位置を表示"
- >{park["公園名"]}
+ >
+ {park["公園名"]}
+
+
+
+
) : park["公式URL"] ? (
{park["住所"] || EMPTY}
+ >{park["住所"] || EMPTY}
|
- {facilityBadges(park).map((b) => (
-
- ))}
- {detailText(park) ? {detailText(park)} : null}
- {facilityBadges(park).length === 0 && !detailText(park) ? EMPTY : null}
+ {facilityRows(park).length ? (
+
+ {facilityRows(park).map((row) => (
+
+ {row.icon ? (
+
+ ) : (
+
+ )}
+ {row.value}
+
+ ))}
+
+ ) : (
+ EMPTY
+ )}
|
))}
@@ -463,50 +532,113 @@ function isUnconfirmed(p: Park): boolean {
border-radius: 0.3rem;
}
.parks table {
+ display: block;
width: 100%;
- min-width: 760px;
- table-layout: fixed;
+ min-width: 0;
+ overflow: visible;
border-collapse: collapse;
font-size: 0.85rem;
}
- .parks col.col-name {
- width: 24%;
+ .parks colgroup {
+ display: none;
}
- .parks col.col-address {
- width: 18%;
+ /* 1行を「公園情報」「施設・備考」の2列で表示する(PC・スマホ共通) */
+ .parks tbody,
+ .parks tbody tr,
+ .parks td {
+ display: block;
}
- .parks col.col-area {
- width: 11%;
+ .parks tbody tr {
+ display: grid;
+ grid-template-columns: minmax(0, 0.48fr) minmax(0, 0.26fr) minmax(0, 1.26fr);
+ grid-template-areas:
+ "name name fac"
+ "addr addr fac"
+ "area type fac";
+ gap: 0 0.6rem;
+ padding: 0.2rem 0.6rem;
+ border-bottom: 0;
}
- .parks col.col-type {
- width: 7%;
+ .parks table tbody td {
+ border: 0;
+ margin: 0;
+ padding: 0;
+ text-align: left;
+ vertical-align: top;
+ white-space: normal;
+ overflow-wrap: anywhere;
}
- .parks col.col-facility {
- width: 40%;
+ .parks .is-name {
+ grid-area: name;
}
- .parks th,
- .parks td {
- border-bottom: 1px solid var(--sl-color-hairline, #ddd);
- border-right: 1px solid var(--sl-color-hairline, #ddd);
- padding: 0.35rem 0.55rem;
+ .parks .is-address {
+ grid-area: addr;
+ min-width: 0;
+ }
+ .parks .is-num {
+ grid-area: area;
text-align: left;
- vertical-align: top;
- white-space: nowrap;
}
- .parks th:last-child,
- .parks td:last-child {
- border-right: none;
+ .parks .is-type {
+ grid-area: type;
+ text-align: left;
}
- .parks thead th {
+ .parks .is-facility {
+ grid-area: fac;
+ min-width: 0;
+ max-width: none;
+ border-left: 1px solid var(--sl-color-hairline, #ddd);
+ padding-left: 0.65rem;
+ }
+ .parks thead {
+ display: block;
position: sticky;
top: 0;
- z-index: 1;
+ z-index: 2;
background: var(--sl-color-gray-6, #f2f2f2);
+ border-bottom: 1px solid var(--sl-color-hairline, #ddd);
+ }
+ .parks thead tr {
+ display: grid;
+ grid-template-columns: minmax(0, 0.48fr) minmax(0, 0.26fr) minmax(0, 1.26fr);
+ grid-template-areas:
+ "h-name h-name h-fac"
+ "h-area h-type h-fac";
+ }
+ .parks thead th {
+ position: static;
+ border: 0;
+ background: transparent;
+ padding: 0.35rem 0.65rem;
+ text-align: left;
+ vertical-align: bottom;
+ white-space: normal;
color: var(--sl-color-white, inherit);
}
+ .parks thead th:nth-child(1) {
+ grid-area: h-name;
+ }
+ .parks thead th:nth-child(2) {
+ display: none;
+ }
+ .parks thead th:nth-child(3) {
+ grid-area: h-area;
+ }
+ .parks thead th:nth-child(4) {
+ grid-area: h-type;
+ }
+ .parks thead th:nth-child(5) {
+ grid-area: h-fac;
+ }
.parks tbody tr:nth-child(even) td {
+ background: transparent;
+ }
+ .parks tbody tr:nth-child(even) {
background: color-mix(in srgb, var(--sl-color-text, #333) 5%, transparent);
}
+ .parks tbody tr.is-selected td:first-child {
+ box-shadow: none;
+ }
.parks tr.is-hidden {
display: none;
}
@@ -533,17 +665,22 @@ function isUnconfirmed(p: Park): boolean {
font-weight: 600;
white-space: normal;
overflow-wrap: anywhere;
- line-height: 1.5;
+ line-height: 1.3;
+ }
+ .parks .is-address,
+ .parks .is-num,
+ .parks .is-type {
+ line-height: 1.25;
}
.parks-owner {
display: inline-block;
- margin-left: 0.35rem;
+ margin: 0 0.35rem 0 0;
padding: 0.02rem 0.35rem;
border: 1px solid currentColor;
border-radius: 999px;
font-size: 0.7rem;
font-weight: 600;
- line-height: 1.5;
+ line-height: 1.2;
vertical-align: 0.08em;
white-space: nowrap;
}
@@ -561,7 +698,7 @@ function isUnconfirmed(p: Park): boolean {
}
.parks-status {
display: inline-block;
- margin-left: 0.35rem;
+ margin: 0 0.35rem 0 0;
padding: 0.02rem 0.35rem;
border: 1px solid #ef9a9a;
border-radius: 999px;
@@ -569,7 +706,7 @@ function isUnconfirmed(p: Park): boolean {
color: #b71c1c;
font-size: 0.7rem;
font-weight: 700;
- line-height: 1.5;
+ line-height: 1.2;
vertical-align: 0.08em;
white-space: nowrap;
}
@@ -579,7 +716,7 @@ function isUnconfirmed(p: Park): boolean {
color: #424242;
}
.park-name-link {
- display: inline-block;
+ display: block;
max-width: 100%;
padding: 0;
border: 0;
@@ -598,29 +735,56 @@ function isUnconfirmed(p: Park): boolean {
.park-name-link:hover {
color: var(--sl-color-accent);
}
- .parks tbody tr.is-highlighted td {
+ .park-focus-ico {
+ display: inline-flex;
+ width: 0.9em;
+ height: 0.9em;
+ margin-left: 0.2em;
+ color: #0277bd;
+ vertical-align: -0.08em;
+ }
+ .park-focus-ico svg {
+ display: block;
+ width: 100%;
+ height: 100%;
+ }
+ .parks tbody tr.is-highlighted {
background: #fff59d !important;
+ outline: 2px solid #f9a825;
+ outline-offset: -2px;
}
- .parks tbody tr.is-selected td {
+ .parks tbody tr.is-highlighted td {
+ background: transparent !important;
+ }
+ .parks tbody tr.is-selected {
background: #ffe0b2 !important;
+ outline: 2px solid #e65100;
+ outline-offset: -2px;
}
- .parks tbody tr.is-selected td:first-child {
- box-shadow: inset 4px 0 0 #e65100;
+ .parks tbody tr.is-selected td {
+ background: transparent !important;
}
.parks .is-address {
font-size: 0.8em;
white-space: normal;
- min-width: 9rem;
}
.parks .is-address a {
color: var(--sl-color-text-accent, #357);
}
- .parks .is-address a::before {
- content: "📍";
- margin-right: 0.2em;
+ .parks .addr-google {
+ display: inline-flex;
+ width: 1em;
+ height: 1em;
+ margin-right: 0.15em;
+ vertical-align: -0.12em;
+ }
+ .parks .addr-google :global(svg) {
+ display: block;
+ width: 100%;
+ height: 100%;
}
.parks .is-num {
- text-align: right;
+ text-align: left;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
@@ -631,7 +795,7 @@ function isUnconfirmed(p: Park): boolean {
padding: 0 0.45em;
border-radius: 0.7em;
font-size: 0.75em;
- line-height: 1.7;
+ line-height: 1.2;
vertical-align: middle;
background: color-mix(in srgb, currentColor 14%, transparent);
}
@@ -687,111 +851,111 @@ function isUnconfirmed(p: Park): boolean {
}
.parks .is-facility {
white-space: normal;
- min-width: 12rem;
- max-width: 26rem;
}
- .parks .fac-badge {
+ .parks .fac-detail {
+ display: grid;
+ gap: 0.1rem;
+ font-size: 0.8em;
+ opacity: 0.9;
+ }
+ .parks .fac-detail-row {
+ display: grid;
+ grid-template-columns: 18px minmax(0, 1fr);
+ gap: 0.35rem;
+ align-items: start;
+ }
+ .parks .fac-detail-ico {
+ position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
- margin: 0 0.3em 0.2em 0;
- padding: 0 0.4em;
- border-radius: 1em;
- font-size: 0.85em;
- line-height: 1.9;
- white-space: nowrap;
- background: color-mix(in srgb, currentColor 10%, transparent);
- cursor: help;
- }
- .parks .fac-toilet::before {
- content: "🚻";
- }
- .parks .fac-water::before {
- content: "💧";
+ box-sizing: border-box;
+ width: 18px;
+ height: 18px;
+ border: 1px solid #c8e6c9;
+ border-radius: 4px;
+ background: #e8f5e9;
+ color: #2e7d32;
+ font-size: 11px;
+ font-weight: 700;
+ line-height: 1;
}
- .parks .fac-toy::before {
- content: "🎠";
+ .parks .fac-detail-ico :global(svg) {
+ display: block;
+ width: 14px;
+ height: 14px;
+ }
+ .parks .fac-detail-ico.is-toilet {
+ border-color: #263238;
+ background: #455a64;
+ color: #fff;
+ font-size: 8px;
+ }
+ .parks .fac-detail-ico.is-water {
+ border-color: #90caf9;
+ background: #e3f2fd;
+ color: #0277bd;
+ }
+ .parks .fac-detail-ico.is-bench {
+ border-color: #d7ccc8;
+ background: #efebe9;
+ color: #6d4c41;
}
- .parks .fac-ball::before {
- content: "⚽";
+ .parks .fac-detail-ico.is-pond {
+ border-color: #81d4fa;
+ background: #e1f5fe;
+ color: #29b6f6;
}
- .parks .fac-cm::before {
- content: "🏛";
+ .parks .fac-detail-ico.is-clock {
+ border-color: #ffe082;
+ background: #fff8e1;
+ color: #f9a825;
}
- .parks .fac-pergola::before {
- content: "🌿";
+ .parks .fac-detail-ico.is-ball {
+ color: #2e7d32;
}
- .parks .fac-azumaya::before {
- content: "🛖";
+ .parks .fac-detail-ico.is-pet {
+ padding: 0;
+ border-color: #e0e0e0;
+ background: #fff;
+ color: #6d4c41;
}
- .parks .fac-detail {
- display: block;
- margin-top: 0.25em;
- font-size: 0.8em;
- opacity: 0.85;
+ .parks .fac-detail-ico.is-pet :global(svg) {
+ width: 100%;
+ height: 100%;
+ }
+ .parks .fac-detail-ico.is-banned {
+ overflow: hidden;
+ }
+ .parks .fac-detail-ico.is-banned::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background:
+ linear-gradient(45deg, transparent 47%, #d32f2f 47%, #d32f2f 53%, transparent 53%),
+ linear-gradient(-45deg, transparent 47%, #d32f2f 47%, #d32f2f 53%, transparent 53%);
+ }
+ .parks .fac-detail-ico :global(.fac-text) {
+ font-size: inherit;
+ font-weight: inherit;
+ line-height: inherit;
+ white-space: nowrap;
}
- /* スマートフォンでは表をカード状に組み替え、横スクロールなしで読めるようにする。 */
+ /* スマートフォンではヘッダーを省き、余白を詰める(2列レイアウトは共通) */
@media (max-width: 700px) {
.parks table {
- display: block;
- width: 100%;
- min-width: 0;
font-size: 0.8rem;
}
.parks thead {
display: none;
}
- .parks tbody,
- .parks tbody tr,
- .parks td {
- display: block;
- }
.parks tbody tr {
- display: grid;
- grid-template-columns: 1fr auto auto;
- grid-template-areas:
- "name name name"
- "addr area type"
- "fac fac fac";
- gap: 0.15rem 0.5rem;
- padding: 0.45rem 0.55rem;
- border-bottom: 1px solid var(--sl-color-hairline, #ddd);
- }
- .parks tbody tr:nth-child(even) td {
- background: transparent;
- }
- .parks tbody tr:nth-child(even) {
- background: color-mix(in srgb, var(--sl-color-text, #333) 5%, transparent);
- }
- .parks td {
- border: 0;
- padding: 0;
- white-space: normal;
- overflow-wrap: anywhere;
- }
- .parks .is-name {
- grid-area: name;
- }
- .parks .is-address {
- grid-area: addr;
- min-width: 0;
- }
- .parks .is-num {
- grid-area: area;
- text-align: left;
- }
- .parks .is-type {
- grid-area: type;
- text-align: left;
+ gap: 0 0.45rem;
+ padding: 0.2rem 0.5rem;
}
.parks .is-facility {
- grid-area: fac;
- min-width: 0;
- max-width: none;
- }
- .parks tbody tr.is-selected td:first-child {
- box-shadow: none;
+ padding-left: 0.5rem;
}
}
@@ -868,8 +1032,13 @@ function isUnconfirmed(p: Park): boolean {
if (count) count.textContent = `${shown} / ${total}件`;
if (none) none.hidden = shown !== 0;
// 地図側に絞り込み結果を通知する。
- const visibleNames = allRows()
- .filter((row) => !row.classList.contains("is-hidden"))
+ const visibleRows = allRows().filter((row) => !row.classList.contains("is-hidden"));
+ const visibleNames = visibleRows
+ .map((row) => row.dataset.name || "")
+ .filter(Boolean);
+ // 市外の近い公園は名前が小平市内と重複することがあるため、別に渡す。
+ const visibleNearbyNames = visibleRows
+ .filter((row) => row.dataset.town === "市外")
.map((row) => row.dataset.name || "")
.filter(Boolean);
const fromMap = Boolean(selectedName && search?.value === selectedName);
@@ -877,6 +1046,7 @@ function isUnconfirmed(p: Park): boolean {
new CustomEvent("park:filter", {
detail: {
names: visibleNames,
+ nearbyNames: visibleNearbyNames,
active: Boolean(
kind || town || query || wanted.length || selectedName || onlyUnconfirmed,
),
--
cgit v1.3.1