@ihabdevteam/core 0.348.0 → 0.350.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +303 -0
- package/dist/components.cjs.js +186 -186
- package/dist/components.esm.css +1 -1
- package/dist/hooks.cjs.js +5 -5
- package/dist/i18n.cjs.js +3 -3
- package/dist/ihabdevteam-core.cjs.js +185 -185
- package/dist/ihabdevteam-core.d.ts +13 -2
- package/dist/packages/core/src/components/DatePicker.css +57 -4
- package/dist/packages/core/src/components/DatePicker.js +120 -21
- package/dist/packages/core/src/components/PanelRow.d.ts +12 -1
- package/dist/packages/core/src/i18n/locales/en.json +13 -483
- package/dist/packages/core/src/i18n/locales/ko.json +13 -481
- package/dist/packages/core/src/utils/date.d.ts +12 -0
- package/dist/packages/core/src/utils/date.js +15 -2
- package/dist/packages/core/src/version.d.ts +1 -1
- package/dist/packages/core/src/version.js +1 -1
- package/dist/utils.cjs.js +4 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,309 @@ All notable changes to this project will be documented in this file.
|
|
|
7
7
|
> 적은 글이라, 지금 이름으로 고쳐 놓으면 그 시절에 그 이름으로 받은 사람이
|
|
8
8
|
> 제 이야기를 못 찾는다.
|
|
9
9
|
|
|
10
|
+
## 0.350.0 — `DatePicker` 를 손으로 치고, `PanelRowText` 가 마디를 받는다
|
|
11
|
+
|
|
12
|
+
### `DatePicker` 연·월 — 가운데로 모으고, 1900년까지 연다
|
|
13
|
+
|
|
14
|
+
사장님 지시(2026-10-20), 앞 판에 이어 둘.
|
|
15
|
+
|
|
16
|
+
**① 연·월이 양쪽 끝으로 벌어져 있었다.** 둘을 나비(`.date-picker__nav`)의 바로 밑에 두고
|
|
17
|
+
저마다 `flex: 1` 을 주었더니 남는 자리를 반씩 먹어, **한 날짜를 가리키는 둘이 서로 남처럼**
|
|
18
|
+
보였다. 묶음(`.date-picker__nav-ym`)으로 싸서 가운데에 세운다.
|
|
19
|
+
|
|
20
|
+
묶은 것만으로는 모자랐다 — `Dropdown` 의 트리거가 `width: 100%` 에 `min-width: 120px` 라
|
|
21
|
+
`2026년`(54px)·`10월`(24px)인데도 **둘 다 120px** 로 섰다. 날짜 나비 안에서만 글자만큼 쥐게
|
|
22
|
+
내린다(고르개 제 밑값은 폼 칸에 설 때 필요한 값이라 안 건드린다).
|
|
23
|
+
|
|
24
|
+
브라우저 실측: 연 85px · 월 63px · 둘 사이 4px, **묶음 가운데 513 = 나비 가운데 513**,
|
|
25
|
+
양 단추와의 사이도 43px 로 같다.
|
|
26
|
+
|
|
27
|
+
**② 맨 위로 올려도 2013년이었다.** 해 목록이 `viewY ± 10` 이라 열 해뿐이어서 **생년월일을
|
|
28
|
+
못 골랐다.** 바닥을 `1900`(사장님: 1900년까지만 나오면 된다), 꼭대기를 **오늘에서 열 해**로
|
|
29
|
+
둔다 — 1900~2036, 137해.
|
|
30
|
+
|
|
31
|
+
**기준이 오늘인 것이 요점이다.** `viewY` 기준이면 1950년으로 간 뒤 목록이 1830년까지
|
|
32
|
+
**따라 흘러간다** — 목록이 제자리에 안 선다. 바닥을 숫자로 박는 것은 여기서 맞다: **최근
|
|
33
|
+
해**를 박으면 세월이 지나며 그 해가 범위 끝이 되지만, 바닥은 멀어지기만 한다.
|
|
34
|
+
|
|
35
|
+
보고 있는 해는 `Math.min`/`Math.max` 로 **반드시 넣는다** — 범위 밖 `value` 가 오면 고르개가
|
|
36
|
+
제 값을 목록에서 못 찾아 빈 이름으로 떨어진다.
|
|
37
|
+
|
|
38
|
+
심어서 둘을 확인했다 — 옛 범위(`viewY ± 10`)로 되돌리면 *"맨 앞이 1900년이 아니다"*,
|
|
39
|
+
기준을 보고 있는 해로 두면 *"먼 해로 갔더니 목록 맨 앞이 더 옛날로 밀렸다"* 로 운다.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### `DatePicker` — 연·월을 따로 고르고, 손으로 쳐서 넣는다
|
|
43
|
+
|
|
44
|
+
사장님 지시(2026-10-20), 둘이다.
|
|
45
|
+
|
|
46
|
+
#### ① 연월 한 덩어리를 **연·월 둘로**
|
|
47
|
+
|
|
48
|
+
`2026년 10월` 을 한 고르개에 **252줄**로 늘어놓고 있었다. 한 해 앞으로 가려면 열두 줄을
|
|
49
|
+
지나야 했고, 목록이 길어 어디쯤인지도 안 보였다. 이제 `2026년 ∨` `10월 ∨` 둘이다.
|
|
50
|
+
|
|
51
|
+
**자르는 규칙(`min`·`max`)은 그대로다.** 달 목록은 **고른 해에 따라** 달라진다 —
|
|
52
|
+
`min = 2026-10` 이면 2026년에는 10·11·12월뿐이다.
|
|
53
|
+
|
|
54
|
+
**해를 바꿀 때 달이 범위 밖이면 당긴다.** 1월을 보다가 그 2026년을 고르면 1월은 그 해에
|
|
55
|
+
없다 — 안 당기면 **빈 달력이 선다.** 터지지도 울지도 않고 날짜 칸만 사라져 눈으로만 잡힌다.
|
|
56
|
+
범위 안이면 그대로 둔다(쓸데없이 안 움직인다).
|
|
57
|
+
|
|
58
|
+
사전에 `datePicker.selectYear`·`selectMonth` 를 두고 `selectYearMonth` 는 걷었다(쓰는 데가
|
|
59
|
+
없어져 두면 죽은 열쇠가 된다). 연월을 한 덩어리로 짓던 `yearMonthLabel` 은 **달력 머리줄
|
|
60
|
+
(`Calendar`)** 이 여전히 쓴다.
|
|
61
|
+
|
|
62
|
+
#### ② 트리거를 **입력칸으로** — 눌러서 바로 친다
|
|
63
|
+
|
|
64
|
+
`<button>` 이라 달력으로만 고를 수 있었다. 먼 날짜(생년월일 같은 것)는 달력으로 가는 길이
|
|
65
|
+
멀다. 이제 누르면 달력이 열리면서 **글 쓸 자리도 같이 선다** — 둘 중 편한 쪽으로 간다.
|
|
66
|
+
|
|
67
|
+
숫자만 남겨서 읽는다 — `2026. 10. 20.` · `2026-10-20` · `2026/10/20` · `20261020` 이 다 같은
|
|
68
|
+
날이다. 사람이 어떤 구분자를 칠지 미리 못 정한다.
|
|
69
|
+
|
|
70
|
+
**지키는 것 둘.** ① *반쪽 글을 부르는 쪽에 안 돌린다* — `2026` 까지 쳤을 때는 아직 날짜가
|
|
71
|
+
아닌데 돌리면 부르는 쪽이 `2026` 을 날짜로 받는다. 다 치면 그때 돌리고, 자리를 뜨면 반쪽
|
|
72
|
+
글은 버린다. ② *없는 날을 안 받는다* — `Date` 는 2026-02-30 을 **3월 2일로 넘겨 버린다.**
|
|
73
|
+
지은 날이 친 숫자와 같은지 되본다(윤년 2월 29일은 받는다). `min`·`max` 밖도 안 받는다 —
|
|
74
|
+
달력으로 못 고르는 날을 글로는 넣을 수 있으면 안 된다.
|
|
75
|
+
|
|
76
|
+
클래스(`date-picker__trigger`)는 그대로 뒀다 — 시험과 소비자가 그 글자로 집는다. 입력칸은
|
|
77
|
+
자식을 못 가지므로 달력 아이콘은 밖으로 내고 둘을 한 상자가 겹친다.
|
|
78
|
+
|
|
79
|
+
#### 못이 셋을 잡았다
|
|
80
|
+
|
|
81
|
+
**① 누를 자리가 없었다.** 새로 만든 아이콘 단추가 그림 18px 그대로였다 —
|
|
82
|
+
`rawButtonHitArea` 가 바닥 24px 을 세어 울렸다. 32×32 로 넓히되 `position: absolute` 라 칸
|
|
83
|
+
키는 그대로이고, `right` 를 12 → 8 로 당겨 그림은 제자리에 남는다.
|
|
84
|
+
|
|
85
|
+
**② 옛 시험 **다섯**이 옛 꼴을 읽고 있었다.** 안내글이 `<span class="date-picker__placeholder">`
|
|
86
|
+
에서 **입력칸의 `placeholder`** 로 옮겼고(`fixInputsDatePickerI18n`), 연월이 한 고르개에서
|
|
87
|
+
둘로 갈렸다 — **첫 고르개 하나만 읽는 자리가 넷**이었다(`datePickerGridKeys` ·
|
|
88
|
+
`kstTodayInputs0915` · `calendarTodayProp0915d` · `dateBoundaryFixes0915`). 해만 보고 달을
|
|
89
|
+
못 보므로 `'2026년'` 에 `'10월'` 이 들었는지 물으면 운다. 다섯 다 **재는 것은 그대로 두고
|
|
90
|
+
읽는 자리만** 고쳤다.
|
|
91
|
+
|
|
92
|
+
관문이 이것을 **세 바퀴에 걸쳐 하나씩** 내주었다 — 한 바퀴에 한 시험만 울어서다. 두 바퀴째에
|
|
93
|
+
"같은 꼴이 더 있나" 를 **글자로 훑어** 남은 둘을 한꺼번에 찾았다(`querySelector('.date-picker__nav`
|
|
94
|
+
를 `querySelectorAll` 없이 쓰는 자리). 울린 것만 고치면 바퀴 수만큼 걸린다.
|
|
95
|
+
|
|
96
|
+
심어서 여섯을 확인했다 — 당김 걷기 · 달 목록을 해와 무관하게 · 없는 날 되보기 걷기 ·
|
|
97
|
+
반쪽 글 돌리기 · `min`/`max` 안 보기 · 읽기 전용으로 두기.
|
|
98
|
+
|
|
99
|
+
**④ 가려 집으라고 붙인 클래스 둘을 걷었다.** 시험이 연·월을 가리려고
|
|
100
|
+
`--year`·`--month` 를 붙였는데 **꾸밈이 하나도 없었다** — `cssClassIntegrity` 가 울렸다.
|
|
101
|
+
그 못의 까닭은 *"CSS 없는 클래스는 브라우저가 조용히 무시하고 민둥으로 그린다"* 이고,
|
|
102
|
+
맞는 말이다. 필요한 것은 꾸밈이 아니라 **표식**이었다.
|
|
103
|
+
|
|
104
|
+
`Dropdown` 이 `data-*` 를 안 넘기므로 **차례로 집되**(연이 앞, 월이 뒤) 그 차례를 시험이
|
|
105
|
+
**이름으로 못 박는다**. 안 박으면 둘이 바뀌어도 그 파일이 통째로 반대쪽을 재면서 조용히
|
|
106
|
+
초록일 수 있다 — 바꿔 심어 보니 첫 시험이 *"첫째가 연이 아니다"* 로 먼저 짚었다.
|
|
107
|
+
|
|
108
|
+
**⑤ 반대쪽 못이 죽은 CSS 둘을 짚었다.** 트리거가 입력칸이 되면서 안쪽 `<span>` 둘이
|
|
109
|
+
사라졌고, 그 둘이 쥐던 `.date-picker__placeholder`·`.date-picker__value` 가 죽었다
|
|
110
|
+
(`coreCssDeadRules`). 걷기만 하면 **안내글이 값과 같은 진한 색**으로 떠서 빈 칸이 채워진
|
|
111
|
+
것처럼 보인다 — 색을 입력칸 제 자리(`::placeholder`)로 옮겼다.
|
|
112
|
+
|
|
113
|
+
브라우저에서 쟀다: 안내글 `rgb(150,164,184)` · 값 `rgb(67,77,86)`. **jsdom 으로는 못 보는
|
|
114
|
+
자리다**(계산된 색을 안 준다).
|
|
115
|
+
|
|
116
|
+
**③ 내가 세운 못에 내가 걸렸다.** 연·월 이름을 지으려고
|
|
117
|
+
`i18n.language?.startsWith('ko') ? 'ko-KR' : …` 를 적었더니 `langBranchInDict1013` 이 울렸다 —
|
|
118
|
+
말을 보고 가르는 자리를 세는 못이다. 울린 것이 **옳다**: 똑같은 줄이 이미 `date.ts` 에 있었고,
|
|
119
|
+
그 파일만 *"글귀가 아니라 로케일을 고른다"* 는 까닭으로 봐주고 있었다.
|
|
120
|
+
|
|
121
|
+
봐주는 표에 내 자리를 더하는 쪽이 아니라 **그 결정을 한 자리에 모으는** 쪽으로 갔다 —
|
|
122
|
+
`intlLocale(lang)` 을 `date.ts` 에 두고 `formatYearMonth` 도 그것을 쓴다. 같은 줄이 둘이면
|
|
123
|
+
하나가 안 따라온다. 못이 "적어서 넘기라" 가 아니라 **"왜 둘이냐"** 를 물은 셈이다.
|
|
124
|
+
|
|
125
|
+
거기에 `@public` 을 붙였다가 걷었다 — `src/utils.ts` 는 이름을 골라 내보내는데 이 이름은
|
|
126
|
+
안 나간다. **오늘 `deviceKind.ts` 에서 한 것과 같은 실수다**(안 나가는 것을 공개라 적었다).
|
|
127
|
+
|
|
128
|
+
### 놀이터에 **eMail** 칸 — 말귀가 보내는 메일 다섯 통
|
|
129
|
+
|
|
130
|
+
사장님 지시(2026-10-20). `speechear-v2/docs/mail-preview/mail-forms.html` 를 디자인 시스템
|
|
131
|
+
에서 보게 한다. 그 파일 머리말이 이미 *"앱에서는 디자인 시스템 → eMail 칸에서 같은 것을
|
|
132
|
+
본다"* 고 적고 있었다 — 그 칸을 이제 만든다.
|
|
133
|
+
|
|
134
|
+
| | |
|
|
135
|
+
|---|---|
|
|
136
|
+
| 메뉴 | **eMail → 메일 폼** (여덟째 묶음) |
|
|
137
|
+
| 페이지 | `playground/src/pages/Email/MailFormsPage.tsx` |
|
|
138
|
+
| 글 | `playground/src/pages/Email/mailForms.ts` — 다섯 통 |
|
|
139
|
+
|
|
140
|
+
이메일 인증번호 · 환불 완료(본인) · 환불 알림(관리자) · 환불 알림(토스 대시보드) ·
|
|
141
|
+
이용권 만료. 칸마다 **언제 나가나 · 메일 제목 · 고치는 곳**(앱 쪽 함수)을 함께 적는다.
|
|
142
|
+
|
|
143
|
+
**컴포넌트 묶음에 안 섞는다.** 메일 HTML 은 코어 컴포넌트를 하나도 안 쓴다 — 메일
|
|
144
|
+
클라이언트가 외부 CSS·`<style>`·flex·grid 를 안 읽어서 **표와 인라인**으로만 짠다. 컴포넌트
|
|
145
|
+
사이에 두면 "이것도 코어가 그린다" 로 읽힌다.
|
|
146
|
+
|
|
147
|
+
**글은 한 글자도 안 고치고 옮겼다.** 고치면 미리보기와 실제 나가는 메일이 갈라지고, 갈라진
|
|
148
|
+
것은 눈으로만 잡힌다. 그래서 여기는 **보는 자리이고 고치는 자리가 아니다** — 고치려면 칸에
|
|
149
|
+
적힌 앱 쪽 함수를 고치고 다시 옮겨 온다.
|
|
150
|
+
|
|
151
|
+
`<iframe srcDoc>` 으로 **갈라 둔다**: 놀이터 CSS 가 닿으면 실제와 달라 보이고, 메일 쪽
|
|
152
|
+
`:hover` 규칙이 놀이터로 새지 않는다.
|
|
153
|
+
|
|
154
|
+
#### 브라우저에서 재다 셋을 고쳤다 — jsdom 으로는 못 보는 것들이다
|
|
155
|
+
|
|
156
|
+
**① 환불 셋이 잘려 있었다.** 원본대로 칸 키를 760px 로 박았더니 90~176px 씩 잘렸다(실측).
|
|
157
|
+
고정 키는 잘리거나 빈다 — 글에 맞춰 재서 정한다. `onLoad` 뿐 아니라 `ResizeObserver` 로도
|
|
158
|
+
보는 까닭은 로고 SVG 가 뒤늦게 들어오면 그만큼 키가 자라기 때문이다.
|
|
159
|
+
|
|
160
|
+
**② 그랬더니 칸마다 2px 씩 잘렸다.** 놀이터가 `border-box` 라 내가 준 글 키에서 테두리를
|
|
161
|
+
도로 먹었다. `content-box` 로 바꾸면 넓힐 때 가로로 그만큼 넘친다 — 그래서 테두리를
|
|
162
|
+
**재어서**(`offsetHeight - clientHeight`) 더한다. 2 를 박으면 굵기가 바뀔 때 또 어긋난다.
|
|
163
|
+
|
|
164
|
+
**③ 넓히기 조작이 다섯인데 상태는 하나였다.** 하나를 눌렀는데 다섯이 다 움직여 고장처럼
|
|
165
|
+
보였다. 조작도 하나로 모았다.
|
|
166
|
+
|
|
167
|
+
**`--color-line` 으로 테두리를 적었다가 고쳤다** — 그런 토큰이 없다(`--color-border` 다).
|
|
168
|
+
안 고쳤으면 **오류 없이 테두리만 조용히 사라졌을** 자리다.
|
|
169
|
+
|
|
170
|
+
### 인라인 `var()` 가 시험 눈 밖으로 나가던 것 — 못을 세웠다
|
|
171
|
+
|
|
172
|
+
`PanelRowText` 를 재다 jsdom 이 `var()` 를 버리는 것을 알았고, 말귀가 그것을 받아 **"헛빨강이
|
|
173
|
+
아니라 헛초록이 날 자리라 더 위험하다"** 고 짚었다. 맞는 말이라 재 보고 못을 세웠다.
|
|
174
|
+
|
|
175
|
+
갈리는 자리는 **속성의 종류**다(실측 2026-10-20):
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
el.style.setProperty('--my-token', 'var(--color-main)') → "var(--color-main)" 산다
|
|
179
|
+
el.style.color = 'var(--color-main)' → "" 버린다
|
|
180
|
+
el.style.setProperty('color', 'var(--color-main)') → "" 버린다
|
|
181
|
+
el.style.color = 'red' → "red" 산다
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
버린 값은 `style` 어트리뷰트에도 안 남아, jsdom 안에서는 *"안 적었다"* 와 *"`var()` 를
|
|
185
|
+
적었다"* 가 **구별되지 않는다.** 그래서 **화면이 아니라 소스를 센다** —
|
|
186
|
+
`test/inlineVarIsInvisible1020.test.ts`.
|
|
187
|
+
|
|
188
|
+
**왜 헛초록인가.** 빈 글자를 기대하는 잼이 둘 있다 — `fixDisplayIconPartyPopper:44` ·
|
|
189
|
+
`smallContracts0915d:59`, 둘 다 *"크기를 직접 박지 않는다"* 는 뜻이다. `Icon.tsx` 의
|
|
190
|
+
`maskStyle` 에 `width: 'var(--icon-size)'` 를 **심어 보니 그 열한 시험이 그대로 초록**이었고
|
|
191
|
+
새 못만 울렸다. 브라우저에서는 폭이 실제로 박힌다 — 그 두 시험이 막으려던 바로 그것이다.
|
|
192
|
+
|
|
193
|
+
**금지가 아니다.** 인라인 `var()` 는 브라우저에서 멀쩡히 돈다 — 틀린 꼴이 아니라 **jsdom 으로
|
|
194
|
+
못 재는** 꼴이다. 쓰려면 목록에 **까닭과 무엇으로 대신 쟀는지**를 적는다. 적는 자리가 곧
|
|
195
|
+
"안 재어진 곳" 의 목록이 된다. 지금 하나뿐이다(`WordSearchResultBlock` 의 결과 수 강조).
|
|
196
|
+
|
|
197
|
+
**짓다가 두 번 좁았다.** ① `style={{ … }}` 만 보게 했더니 **정작 그 자리를 못 잡았다** —
|
|
198
|
+
실제 코드는 `style={maskStyle}` 로 **변수에 담아** 넘긴다. 파일 전체를 훑게 넓혔다.
|
|
199
|
+
② 그러자 `sub` · `copyrightColor` · `title` 같은 **앱 색판 열쇠**가 28건 걸렸다. CSS 속성
|
|
200
|
+
이름을 손으로 적지 않고 **jsdom 의 `CSSStyleDeclaration` 에서 759개를 뽑아** 좁혔다
|
|
201
|
+
(손 목록은 낡는다).
|
|
202
|
+
|
|
203
|
+
심어서 셋을 확인했다 — 변수 객체에 더하기 · `setProperty` 로 주기 · 봐주는 목록이 낡는 것.
|
|
204
|
+
|
|
205
|
+
**그리고 못을 세우다 다른 못에 걸렸다** — 새 시험에 한글 이름 다섯(`판정한파일`·`몰래`·
|
|
206
|
+
`실재`·`낡음`)을 썼고 `identifiersAreEnglish1013` 이 울렸다. 집안 규약은 시험에도 걸린다
|
|
207
|
+
(같은 자리에서 두 번째다). 영어로 고쳤다 — 주석 속 한국어는 규약대로 그대로 둔다.
|
|
208
|
+
|
|
209
|
+
### `PanelRowText.value` 가 마디(`ReactNode`)도 받는다
|
|
210
|
+
|
|
211
|
+
말귀 청(2026-10-20). 고객 상세의 연락처 줄을 `<a href="tel:">` 로 만들어 폰에서 번호를 눌러
|
|
212
|
+
바로 걸게 하려는데 `value: string` 이라 못 넣었다.
|
|
213
|
+
|
|
214
|
+
**그 줄만 앱이 손으로 그리면 한 패널 안에서 간격·글자 크기가 갈린다** — 오른쪽 자리는
|
|
215
|
+
`panel-row__text body-2` 가 쥐고 있고, 앱이 밖에서 그리면 그 꼴을 잃는다. 그래서 받는 쪽을
|
|
216
|
+
넓힌다. 같은 파일의 `helperText`·`buttonLabel` 이 이미 `ReactNode` 라 꼴도 낯설지 않다.
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
- value: string
|
|
220
|
+
+ value: ReactNode
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**넓히기만 하면 되는 자리였다.** `text` 갈래의 `value` 는 **그리는 한 곳**(`PanelRow.tsx:320`)
|
|
224
|
+
에서 그대로 내보낼 뿐이고, 글자로 다루는 자리(길이·자르기·견주기)가 없다. 코어 안에서 그
|
|
225
|
+
갈래를 만드는 자리도 없다. 옛 쓰임(글자)은 그대로 산다.
|
|
226
|
+
|
|
227
|
+
`valueColor` 는 그 자리 `<span>` 에 걸리므로 마디가 제 색을 가지면 그것이 이긴다.
|
|
228
|
+
|
|
229
|
+
**jsdom 이 `var(...)` 를 `color` 로 안 받는다** — 속성 자체가 안 붙어 `style.color` 가 빈
|
|
230
|
+
글자다(실측: `var(--color-main)` → `""`, `red` → `"red"`). 처음엔 그걸 모르고 토큰으로 재다
|
|
231
|
+
빨강을 받았고, **코드가 아니라 재는 자리의 한계**였다. 받는 값으로 바꿔 재고 까닭을 적어 뒀다.
|
|
232
|
+
|
|
233
|
+
좁혀서 심으면 타입이 네 자리에서 운다.
|
|
234
|
+
|
|
235
|
+
## 0.349.0 — 사전에서 죽은 열쇠 277개를 걷었다
|
|
236
|
+
|
|
237
|
+
### 사전에서 죽은 열쇠 277개를 걷었다 — 첫 화면 조각에서 약 16KB
|
|
238
|
+
|
|
239
|
+
말귀 청(2026-10-20). 코어 `ko.json` 1,010 열쇠 가운데 **앱도 코어도 안 부르는** 것들이 첫 화면
|
|
240
|
+
조각(`index-*.js`, gzip 100KB)에 그대로 실리고 있었다. 말귀가 재어 289개를 짚고 목록을
|
|
241
|
+
`docs/CORE_DEAD_I18N_KEYS_2026-10-20.md` 로 넘기며 *"걷기 전에 코어 쪽에서 한 번 더 보라"* 고
|
|
242
|
+
적어 두었다. 봤더니 **열하나가 살아 있었다.**
|
|
243
|
+
|
|
244
|
+
| | 전 | 후 |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| `ko.json` | 1,010 | **733** (277 지움) |
|
|
247
|
+
| `en.json` | 1,028 | **749** |
|
|
248
|
+
|
|
249
|
+
갈래가 통째로 사라진 것: `game` · `landing` · `login` · `help` · `company` · `inquiry` ·
|
|
250
|
+
`homework` · `trainingSettings` · `accessLinkManager` · `searchField` · `myWordTraining` ·
|
|
251
|
+
`trainingPlanRun` · `trainingSetPage` · `wordTrainingPreview`.
|
|
252
|
+
|
|
253
|
+
#### 살려 둔 열하나 — 말귀 잼이 못 보는 세 자리
|
|
254
|
+
|
|
255
|
+
그쪽 잼은 코어 `dist/**/*.js` 를 봤는데 거기 **놀이터도 시험도 없고**, 앱 쪽은 `deadI18nKeys`
|
|
256
|
+
가 얼린 목록(= 앱 **화면**이 안 부르는 것)이라 **앱 시험**이 빠진다.
|
|
257
|
+
|
|
258
|
+
| 열쇠 | 어디서 쓰나 |
|
|
259
|
+
|---|---|
|
|
260
|
+
| `training.result.elapsed` | 놀이터 `BarChartPage:229·232` |
|
|
261
|
+
| `trainingStatus.weekly.title` · `.daily` | 놀이터 `BarChartPage:165·168·181·194` |
|
|
262
|
+
| `trainingStatus.homework.totalRate` | 놀이터 `RingChartPage:122·123` |
|
|
263
|
+
| `training.audioStatus.synthesizing` | 코어 시험 `audioStatusSynthesizing:33` |
|
|
264
|
+
| `trainingMiss.runs` · `.skippedOnly` | 코어 시험 `enPluralForms:48·53·54` |
|
|
265
|
+
| `customers.visitHistory.registerTitle` · `.popupTitle` · `customers.schedule.registerTitle` | **말귀 시험** `customerPopupTitleSpacing` |
|
|
266
|
+
| `wordPairs.confirmMessage` | 코어 시험 `enPluralForms` 의 `EXCLUDED` 목록 |
|
|
267
|
+
|
|
268
|
+
말귀 시험 셋이 특히 그렇다 — 그쪽 `test/i18nResources` 가 **코어 사전 위에 앱 사전을 얹어**
|
|
269
|
+
주고, 이 셋은 **코어에만 있다.** 그 파일 머리말이 바로 이 날을 적어 두고 있었다:
|
|
270
|
+
*"코어가 옛 사본을 걷는 날 한꺼번에 빨개진다."*
|
|
271
|
+
|
|
272
|
+
#### 영어 복수 짝이 목록에 없었다 — 찾아낸 것 여덟, 지운 것 **넷**
|
|
273
|
+
|
|
274
|
+
그쪽 목록은 `ko.json` 열쇠로 만들어져 **`_one`/`_other` 가 빠져 있다**(en 이 18개 많은 까닭).
|
|
275
|
+
열쇠만 지우면 그 짝이 en 에 남는다. 목록 열쇠의 짝으로 **여덟**을 찾아 그중 **넷**을 걷었다 —
|
|
276
|
+
나머지 넷은 위에서 살려 둔 열쇠의 짝이라 함께 남는다.
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
지웠다 accessLinkManager.uses_one · _other · trainingStatus.time.countLabel_one · _other
|
|
280
|
+
남겼다 trainingMiss.runs_one · _other · trainingMiss.skippedOnly_one · _other
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**찾아낸 수와 지운 수를 같은 칸에 적지 않는다** — 말귀에 처음 알릴 때 여덟을 지운 수인 양
|
|
284
|
+
적었다가 바로잡았다. 빈 마디도 걷었다.
|
|
285
|
+
|
|
286
|
+
ko 277 · en 279(복수 짝 넷 포함)를 지웠다. 둘의 차는 ko 에만 있던 열쇠 둘이다.
|
|
287
|
+
|
|
288
|
+
#### 소비자는 넷이다 — 말귀가 잰 둘이 다가 아니다
|
|
289
|
+
|
|
290
|
+
`kscan` · `sound-localization-system` · `ihab_offcial_web/admin` 도 코어를 쓴다. 셋 다 `t()` 를
|
|
291
|
+
**직접 안 부르고**(코어 컴포넌트가 제 안에서 부른다) 0건이 걸렸다. 앞 둘은 아직 `^0.211.0` 이라
|
|
292
|
+
이 판이 닿지도 않는다. **안 재고 0건인 것과 재서 0건인 것은 다르다.**
|
|
293
|
+
|
|
294
|
+
#### 내 그물이 세 번 성겼다 — 셋째는 **관문이** 잡았다
|
|
295
|
+
|
|
296
|
+
① 처음엔 **289 중 289가 "살아 있다"** 로 나왔다 — 말귀의 **얼린 목록 자체**
|
|
297
|
+
(`deadI18nKeys.test.ts`, 276건)를 쓰임으로 세고 있었고, **kscan 을 통째로 건너뛰었다**(소스가
|
|
298
|
+
`src/` 가 아니라 Next.js 꼴이라 `src` 만 짚은 훑기에 안 걸렸다).
|
|
299
|
+
|
|
300
|
+
② 고쳐서 31로 줄였더니 다섯이 **더 긴 열쇠의 앞머리**였다 — `store.import` 가
|
|
301
|
+
`store.importAria` 에, `usage.pending.title` 이 `usage.pending.titleSpeechear` 에.
|
|
302
|
+
**경계 없는 찾기는 짧은 열쇠를 전부 살려 낸다.**
|
|
303
|
+
|
|
304
|
+
③ 그래서 앞뒤로 `(?<![A-Za-z0-9_.])…(?![A-Za-z0-9_.])` 를 둘렀더니 이번엔
|
|
305
|
+
`training.audioStatus.synthesizing` 를 **놓쳤다.** 그 시험은 열쇠를 글자가 아니라 **속성으로**
|
|
306
|
+
탄다 — `(d as …).training.audioStatus.synthesizing`, 앞 글자가 `.` 이다. 지우고 관문을 돌려
|
|
307
|
+
**빨강으로 알았다.**
|
|
308
|
+
|
|
309
|
+
**앞뒤 경계는 다르다.** 뒤는 `.` 을 막아야 하고(긴 열쇠에 안 걸리게), 앞은 막으면 안 된다
|
|
310
|
+
(속성으로 타는 쓰임을 놓친다). 앞에 긴 길이 붙어 헛걸리는 쪽은 **열쇠를 살려 두는** 쪽이라
|
|
311
|
+
지우기 판단에서는 안전한 틀림이다.
|
|
312
|
+
|
|
10
313
|
## 0.348.0 — 다시 듣기가 같은 소리를 또 받던 것 (311, 급함)
|
|
11
314
|
|
|
12
315
|
**사장님이 폰에서 숙제 단어훈련을 하시다 신고하셨다** — *"소리가 끊기고, 재생바와 사운드
|