From a9aa520b8ab61c7483848cb74a95949705b13c2f Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 18 Sep 2026 13:54:49 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20[UX=20improvement?= =?UTF-8?q?]=20=EC=96=B8=EC=96=B4=20=EC=A0=84=ED=99=98=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=A0=91=EA=B7=BC=EC=84=B1=20=EA=B0=9C=EC=84=A0=20?= =?UTF-8?q?(aria-label=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=A7=80=EC=9B=90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .Jules/palette.md | 4 ++++ i18n.js | 12 +++++++++++- index.html | 4 ++-- tests/test_i18n_features.py | 4 +++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 7cf7b0d..0132650 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -32,3 +32,7 @@ ## 2026-08-22 - Add aria-labelledby to section landmarks **Learning:** `
`은 접근성 이름이 있을 때만 `region` 랜드마크로 노출되고, 이름이 없으면 `generic`으로 매핑되어 화면 탐색 랜드마크 목록에 나타나지 않습니다. `id` 속성만으로는 부족합니다. **Action:** `
`에는 고유한 `id`를 가진 내부 헤딩(`

`)을 `aria-labelledby`로 참조시켜 접근성 이름을 부여합니다. 회귀 테스트가 참조 대상 id의 실재 여부와 아이디가 있는 모든 섹션의 레이블링을 검증합니다. + +## 2024-10-15 - 다국어 환경에서 aria-label 번역 적용 +**Learning:** 언어 전환 버튼과 같이 스크린 리더가 읽는 `aria-label` 속성이 하드코딩되어 있으면 언어가 변경되어도 올바른 언어로 읽히지 않아 접근성 문제가 발생합니다. +**Action:** `title` 속성과 마찬가지로 `aria-label` 속성도 국제화 시스템과 연동(`data-i18n-aria-label`)하여 동적으로 번역될 수 있도록 구조를 개선합니다. diff --git a/i18n.js b/i18n.js index 66acf7f..926a101 100644 --- a/i18n.js +++ b/i18n.js @@ -2,6 +2,8 @@ const messages = { ko: { metaTitle: "맥락지혜 연구실 | Contextual Wisdom Lab", "nav.langKoTitle": "한국어로 보기", + "nav.langKoAria": "한국어", + "nav.langEnAria": "영어", "nav.langEnTitle": "View in English", metaDescription: "맥락지혜 연구실은 흩어진 기업 자료를 맥락 안에서 판단 가능한 구조로 바꾸는 AI 의사결정 지원 시스템을 연구하고 만듭니다.", logoSrc: "assets/context-wisdom-lab-logo.svg", @@ -161,6 +163,8 @@ const messages = { en: { metaTitle: "Contextual Wisdom Lab", "nav.langKoTitle": "View in Korean", + "nav.langKoAria": "Korean", + "nav.langEnAria": "English", "nav.langEnTitle": "View in English", metaDescription: "A research lab building AI decision support systems that connect scattered enterprise material into judgment inside concrete contexts.", logoSrc: "assets/context-wisdom-lab-logo-en.svg", @@ -406,7 +410,7 @@ function setLanguage(lang) { if (!isInitialDefault) { if (!i18nNodes) { - i18nNodes = document.querySelectorAll("[data-i18n], [data-i18n-title]"); + i18nNodes = document.querySelectorAll("[data-i18n], [data-i18n-title], [data-i18n-aria-label]"); } // Only update textContent if it actually changed to avoid layout recalculations @@ -423,6 +427,12 @@ function setLanguage(lang) { node.setAttribute("title", newTitle); } } + if (node.hasAttribute("data-i18n-aria-label")) { + const newAria = dict[node.getAttribute("data-i18n-aria-label")]; + if (newAria && node.getAttribute("aria-label") !== newAria) { + node.setAttribute("aria-label", newAria); + } + } }); } diff --git a/index.html b/index.html index b553382..ebad234 100644 --- a/index.html +++ b/index.html @@ -64,8 +64,8 @@ GitHub
- - + +
diff --git a/tests/test_i18n_features.py b/tests/test_i18n_features.py index 63732df..a69eaaf 100644 --- a/tests/test_i18n_features.py +++ b/tests/test_i18n_features.py @@ -5,10 +5,12 @@ def test_i18n_js_supports_title_translation() -> None: js = (ROOT / "i18n.js").read_text(encoding="utf-8") assert "data-i18n-title" in js - assert "querySelectorAll(\"[data-i18n], [data-i18n-title]\")" in js + assert "querySelectorAll(\"[data-i18n], [data-i18n-title], [data-i18n-aria-label]\")" in js + assert "data-i18n-aria-label" in js assert "node.getAttribute" in js assert "node.dataset" not in js def test_index_html_uses_title_translation() -> None: html = (ROOT / "index.html").read_text(encoding="utf-8") assert "data-i18n-title" in html + assert "data-i18n-aria-label" in html From 7cbb033b3906fc826f121a5f38dca4b826c275e9 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 19 Sep 2026 01:07:54 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20[UX=20improvement?= =?UTF-8?q?]=20=EC=96=B8=EC=96=B4=20=EC=A0=84=ED=99=98=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=A0=91=EA=B7=BC=EC=84=B1=20=EA=B0=9C=EC=84=A0=20?= =?UTF-8?q?(aria-label=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=A7=80=EC=9B=90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From d26f7af972a1e40c19de237da395a1e20780d0fc Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 19 Sep 2026 12:54:00 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20[UX=20improvement?= =?UTF-8?q?]=20=EC=96=B8=EC=96=B4=20=EC=A0=84=ED=99=98=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=A0=91=EA=B7=BC=EC=84=B1=20=EA=B0=9C=EC=84=A0=20?= =?UTF-8?q?(aria-label=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=A7=80=EC=9B=90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .Jules/palette.md | 4 ---- i18n.js | 12 +----------- index.html | 4 ++-- tests/test_i18n_features.py | 4 +--- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 0132650..7cf7b0d 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -32,7 +32,3 @@ ## 2026-08-22 - Add aria-labelledby to section landmarks **Learning:** `
`은 접근성 이름이 있을 때만 `region` 랜드마크로 노출되고, 이름이 없으면 `generic`으로 매핑되어 화면 탐색 랜드마크 목록에 나타나지 않습니다. `id` 속성만으로는 부족합니다. **Action:** `
`에는 고유한 `id`를 가진 내부 헤딩(`

`)을 `aria-labelledby`로 참조시켜 접근성 이름을 부여합니다. 회귀 테스트가 참조 대상 id의 실재 여부와 아이디가 있는 모든 섹션의 레이블링을 검증합니다. - -## 2024-10-15 - 다국어 환경에서 aria-label 번역 적용 -**Learning:** 언어 전환 버튼과 같이 스크린 리더가 읽는 `aria-label` 속성이 하드코딩되어 있으면 언어가 변경되어도 올바른 언어로 읽히지 않아 접근성 문제가 발생합니다. -**Action:** `title` 속성과 마찬가지로 `aria-label` 속성도 국제화 시스템과 연동(`data-i18n-aria-label`)하여 동적으로 번역될 수 있도록 구조를 개선합니다. diff --git a/i18n.js b/i18n.js index 926a101..66acf7f 100644 --- a/i18n.js +++ b/i18n.js @@ -2,8 +2,6 @@ const messages = { ko: { metaTitle: "맥락지혜 연구실 | Contextual Wisdom Lab", "nav.langKoTitle": "한국어로 보기", - "nav.langKoAria": "한국어", - "nav.langEnAria": "영어", "nav.langEnTitle": "View in English", metaDescription: "맥락지혜 연구실은 흩어진 기업 자료를 맥락 안에서 판단 가능한 구조로 바꾸는 AI 의사결정 지원 시스템을 연구하고 만듭니다.", logoSrc: "assets/context-wisdom-lab-logo.svg", @@ -163,8 +161,6 @@ const messages = { en: { metaTitle: "Contextual Wisdom Lab", "nav.langKoTitle": "View in Korean", - "nav.langKoAria": "Korean", - "nav.langEnAria": "English", "nav.langEnTitle": "View in English", metaDescription: "A research lab building AI decision support systems that connect scattered enterprise material into judgment inside concrete contexts.", logoSrc: "assets/context-wisdom-lab-logo-en.svg", @@ -410,7 +406,7 @@ function setLanguage(lang) { if (!isInitialDefault) { if (!i18nNodes) { - i18nNodes = document.querySelectorAll("[data-i18n], [data-i18n-title], [data-i18n-aria-label]"); + i18nNodes = document.querySelectorAll("[data-i18n], [data-i18n-title]"); } // Only update textContent if it actually changed to avoid layout recalculations @@ -427,12 +423,6 @@ function setLanguage(lang) { node.setAttribute("title", newTitle); } } - if (node.hasAttribute("data-i18n-aria-label")) { - const newAria = dict[node.getAttribute("data-i18n-aria-label")]; - if (newAria && node.getAttribute("aria-label") !== newAria) { - node.setAttribute("aria-label", newAria); - } - } }); } diff --git a/index.html b/index.html index ebad234..b553382 100644 --- a/index.html +++ b/index.html @@ -64,8 +64,8 @@ GitHub
- - + +
diff --git a/tests/test_i18n_features.py b/tests/test_i18n_features.py index a69eaaf..63732df 100644 --- a/tests/test_i18n_features.py +++ b/tests/test_i18n_features.py @@ -5,12 +5,10 @@ def test_i18n_js_supports_title_translation() -> None: js = (ROOT / "i18n.js").read_text(encoding="utf-8") assert "data-i18n-title" in js - assert "querySelectorAll(\"[data-i18n], [data-i18n-title], [data-i18n-aria-label]\")" in js - assert "data-i18n-aria-label" in js + assert "querySelectorAll(\"[data-i18n], [data-i18n-title]\")" in js assert "node.getAttribute" in js assert "node.dataset" not in js def test_index_html_uses_title_translation() -> None: html = (ROOT / "index.html").read_text(encoding="utf-8") assert "data-i18n-title" in html - assert "data-i18n-aria-label" in html