@ihabdevteam/core 0.200.0 → 0.201.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 +111 -0
- package/dist/components.cjs.js +177 -177
- package/dist/components.esm.css +1 -1
- package/dist/hooks.cjs.js +3 -3
- package/dist/i18n.cjs.js +3 -3
- package/dist/ihabdevteam-core.cjs.js +186 -186
- package/dist/ihabdevteam-core.d.ts +206 -18
- package/dist/packages/core/src/components/Header.css +139 -118
- package/dist/packages/core/src/components/Popup/useDiscardGuard.d.ts +48 -0
- package/dist/packages/core/src/components/Popup/useDiscardGuard.js +56 -0
- package/dist/packages/core/src/components.d.ts +2 -0
- package/dist/packages/core/src/components.js +1 -0
- package/dist/packages/core/src/hooks/useListControls.d.ts +66 -0
- package/dist/packages/core/src/hooks/useListControls.js +52 -0
- package/dist/packages/core/src/hooks.d.ts +1 -0
- package/dist/packages/core/src/hooks.js +1 -0
- package/dist/packages/core/src/i18n/locales/en.json +5 -0
- package/dist/packages/core/src/i18n/locales/ko.json +5 -0
- package/dist/packages/core/src/utils/chunkSkew.d.ts +27 -0
- package/dist/packages/core/src/utils/chunkSkew.js +44 -0
- package/dist/packages/core/src/utils/format.d.ts +14 -14
- package/dist/packages/core/src/utils/format.js +27 -1
- package/dist/packages/core/src/utils/sessionTab.d.ts +36 -0
- package/dist/packages/core/src/utils/sessionTab.js +36 -0
- package/dist/packages/core/src/utils.d.ts +4 -2
- package/dist/packages/core/src/utils.js +3 -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 +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,117 @@ All notable changes to this project will be documented in this file.
|
|
|
7
7
|
> 적은 글이라, 지금 이름으로 고쳐 놓으면 그 시절에 그 이름으로 받은 사람이
|
|
8
8
|
> 제 이야기를 못 찾는다.
|
|
9
9
|
|
|
10
|
+
## 0.201.0
|
|
11
|
+
|
|
12
|
+
### 고침 — 펼친 태블릿 레일이 넓은 화면과 달랐다 (사장님 지시 2026-09-27)
|
|
13
|
+
|
|
14
|
+
태블릿 폭(768~1023)에서 레일은 두 모양이다 — 접힌 72px 과 호버·포커스로 펼친 220px.
|
|
15
|
+
펼친 220 은 **넓은 화면과 같은 폭**인데 여섯 군데가 달랐다(실측):
|
|
16
|
+
|
|
17
|
+
| | 넓은 화면 | 펼친 레일(전) |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| 목록 좌우 여백 | 11px | 8px |
|
|
20
|
+
| 항목 사이(`gap`) | 12px | 10px |
|
|
21
|
+
| 항목 모서리 | 10px | 12px |
|
|
22
|
+
| 이름표 `max-width` | none | 200px |
|
|
23
|
+
| **하위 항목 들여쓰기** | **30px** | **16px** |
|
|
24
|
+
| 스크롤 막대 자리 | 목록 폭 216 | 222 |
|
|
25
|
+
|
|
26
|
+
까닭은 **꼴 자체**였다. 접힌 꼴 규칙마다 `:hover` 짝을 두어 되돌리고 있었는데, 그러면
|
|
27
|
+
짝을 빠뜨린 것이 조용히 남는다. 하위 항목이 그랬다 — 되돌리는 규칙(`padding: 0 16px`,
|
|
28
|
+
0,3,0)이 `.side-nav__item--child`(0,1,0)를 이겨 **들여쓰기가 통째로 사라졌고**, 그 짝은
|
|
29
|
+
애초에 적힌 적이 없다.
|
|
30
|
+
|
|
31
|
+
그래서 **접힌 꼴만 덮고 펼치면 아무것도 안 덮는다**(`:not(:hover):not(:focus-within)`).
|
|
32
|
+
되돌릴 것이 없으니 빠뜨릴 것도 없고, 넓은 화면에 새 규칙이 생겨도 펼친 레일이 저절로
|
|
33
|
+
따라간다. 되돌림 규칙 다섯이 사라졌다. 남은 차이는 단추 크기(48 → 44)뿐인데, 그것은
|
|
34
|
+
좁은 화면에서 한 급 줄이는 **전역 사다리**라 이 레일만의 일이 아니다.
|
|
35
|
+
|
|
36
|
+
**배지도 고친다** — 접힌 레일에서 인라인 배지는 이름표(폭 0) 뒤에 서느라 단추(52)를
|
|
37
|
+
10px 넘어섰고 통이 그 자리를 잘라 동그라미가 베였다(실측: 단추 344~396, 배지 382~406).
|
|
38
|
+
단추 안쪽 오른쪽 위로 얹는다. 모서리 값이 `--top-right` 기본(-6px)이 아니라 0 인 것은
|
|
39
|
+
`BottomNav` 와 같은 까닭이다 — 통이 넘침을 자르므로 바깥으로 나간 6px 은 사라진다.
|
|
40
|
+
|
|
41
|
+
### 고침 — 말귀매니저의 막대와 못 쓰는 항목
|
|
42
|
+
|
|
43
|
+
**막대는 옅은 흰색으로**(`rgba(255,255,255,0.4)`, 얹으면 `0.75`). 브랜드 색으로 한 번 가
|
|
44
|
+
봤다가 되돌렸다 — 이 지면이 `--color-main` → `--color-sub` 그라디언트라 **막대가 어딘가에서
|
|
45
|
+
지면과 같아진다**(실측: main 은 맨 위 1.06, sub 은 맨 아래 1.01). 게다가 둘이 엇갈려 위쪽에서는
|
|
46
|
+
얹으면 잘 보이고 아래쪽에서는 얹으면 덜 보였다. 색으로는 못 푸는 자리다. 투명도로 두면
|
|
47
|
+
지면이 무슨 색이든 그만큼 밝아진다(가장 나쁜 자리에서 1.30 → 1.65). 흰빛으로는 3.0 에 못
|
|
48
|
+
간다는 것도 재 뒀다 — 꽉 채운 흰색도 1.94 다.
|
|
49
|
+
|
|
50
|
+
**못 쓰는 항목**은 글자만 희고 아이콘만 탁했다. `.side-nav__item.disabled .side-nav__icon`
|
|
51
|
+
(0,3,0)이 매니저 규칙(0,2,0)을 이겨 흰 지면용 회색이 그라디언트 위에 떠 있었다. 둘 다
|
|
52
|
+
`--color-deepWhite` 로 두고, 물러나는 일은 줄에 이미 걸린 `opacity: 0.6` 이 한다.
|
|
53
|
+
|
|
54
|
+
### 더해짐 — 두 앱에 한 벌씩 남아 있던 넷 (말귀 ⑲)
|
|
55
|
+
|
|
56
|
+
두 묶음(회원앱 · 어드민)에 걸쳐 남은 것을 다시 훑어 올라온 넷이다. **넷 다 한쪽만 고쳐지면
|
|
57
|
+
조용한** 쪽이다.
|
|
58
|
+
|
|
59
|
+
**`installSkewRecovery()`** — 복구하는 일(`recoverFromSkew`)은 이미 코어였는데 **어디에 어떻게
|
|
60
|
+
매다는지**가 두 `main.tsx` 에 글자까지 같이 있었다. 그 열몇 줄에 틀리기 쉬운 조각이 있다:
|
|
61
|
+
스타일시트의 `error` 는 **버블링하지 않아** 셋째 인자 `true`(캡처)로 들어야 한다. 빠뜨리면 그
|
|
62
|
+
앱만 CSS 청크 실패를 못 듣고, 스크립트는 멀쩡히 도는 채 **화면만 스타일이 전부 빠져** 뜬다
|
|
63
|
+
(말귀 실제 QA 건). 한 줄로 줄인다 — 떼는 함수를 돌려준다.
|
|
64
|
+
|
|
65
|
+
**`isSessionForThisTab(받은것, 이탭것)`** — `auth.storage` 를 `sessionStorage` 로 두어 탭을 갈라도
|
|
66
|
+
GoTrue 의 `BroadcastChannel` 은 저장소 종류와 무관하게 세션 이벤트를 모든 탭에 뿌린다. 받은
|
|
67
|
+
세션을 그대로 믿으면 **다른 탭의 로그인이 이 탭 화면에 얹혀** 로그인된 것처럼 그려지는데, 이 탭
|
|
68
|
+
저장소는 비어 API 호출이 전부 미인증으로 실패한다(어드민에서는 그것이 `ROLE_ADMIN` 세션이다).
|
|
69
|
+
`getSession()` 으로 이 탭 저장소를 다시 읽어 맞대는 그 한 줄을 여기 둔다. **로그아웃은 늘
|
|
70
|
+
받는다** — 지울 것이 없다는 말은 어느 탭에서 왔든 참이고, 막으면 이 탭이 로그인된 채 남는다.
|
|
71
|
+
|
|
72
|
+
**`useDiscardGuard`** — 쓰던 것을 버리고 닫을지 묻는 가드. 두 앱에 한 벌씩 있었고 **어드민 쪽이
|
|
73
|
+
윗집합**이었다: `allowClose()` 를 하나 더 들었다. 저장 뒤 `closeWithAnimation` 도 `beforeClose` 를
|
|
74
|
+
거치는데 폼은 방금 달라진 채라 "저장했는데 버릴까요?" 를 묻게 된다 — 갈라져 있던 탓에 그 고침이
|
|
75
|
+
회원앱으로 못 건너왔고, 회원앱 고객 추가 창이 실제로 그랬다. 문구는 `labels` 로 받는다(안 주면
|
|
76
|
+
`common.discardConfirm.*`, 사전이 없으면 한국어 기본값). `@ihabdevteam/core/components` 에서 나온다 —
|
|
77
|
+
`ConfirmPopup` 을 그리므로 그 곁이 제자리다(CONSUMING.md 2-1).
|
|
78
|
+
|
|
79
|
+
**`isPersonalPhone` · `PERSONAL_PHONE_REGEX`** — 두 앱이
|
|
80
|
+
`isValidPhone(phone) && phone.startsWith('0')` 을 한 벌씩 들고 있었다. 뜻은 "대표번호는 안 받는다"
|
|
81
|
+
인데 **`'0'` 으로 시작하는가**로 적혀 있었고, 그 둘이 지금 같은 것은 비-0 갈래가 대표번호
|
|
82
|
+
하나뿐이라서일 뿐이다 — 0 으로 시작하지 않는 대역이 하나 더 생기면 두 앱이 **조용히 그것을 받는다.**
|
|
83
|
+
`PHONE_REGEX` 를 개인번호·대표번호 두 조각으로 갈라 적고, 좁은 자는 앞 조각만 쓴다. 새 대역은
|
|
84
|
+
한 곳에만 더하면 둘이 함께 받는다(예전에 `050X`·`0303` 을 손으로 따라 고친 이력이 있다).
|
|
85
|
+
|
|
86
|
+
> **지금 이 자를 부르는 데는 없다.** 청한 쪽에서 제품 판단이 반대로 나(2026-09-27, 사장님 —
|
|
87
|
+
> "두 앱 다 대표번호를 받는다") 말귀 두 앱은 `0` 으로 시작하는 한 줄을 걷고 `isValidPhone` 을
|
|
88
|
+
> 그대로 쓴다. 그래도 남겨 둔다 — 정규식을 두 조각으로 가른 것 자체가 값이고(새 대역이 한쪽에만
|
|
89
|
+
> 들어오면 시험이 차집합에서 잡는다), "사람에게 거는 번호만" 받아야 하는 칸이 생기면 그 자가
|
|
90
|
+
> 제자리에 있다. **죽은 코드가 아니라 아직 안 부르는 것이다.**
|
|
91
|
+
|
|
92
|
+
**사전에 더한 것** — `common.discardConfirm.title` · `.body` · `.confirm`(ko · en).
|
|
93
|
+
|
|
94
|
+
### 더해짐 — `useListControls`
|
|
95
|
+
|
|
96
|
+
목록 화면 셋이 같은 다섯 줄을 손으로 엮고 있었다(어드민 문장 자료 · 어드민 낱말 자료 ·
|
|
97
|
+
회원앱 낱말 관리). `usePagedList` 를 코어로 올린 까닭이 한 겹 위에서 그대로 되풀이된 자리다.
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { useListControls, usePagedList } from '@ihabdevteam/core/hooks'
|
|
101
|
+
|
|
102
|
+
const 목록 = useListControls({ resetOn: [보기] }) // 검색어·쪽크기는 훅이 스스로 넣는다
|
|
103
|
+
const 걸러낸것 = useMemo(() => 거르기(줄들, 목록.query, 보기), [줄들, 목록.query, 보기])
|
|
104
|
+
const { pageItems, totalPages, curPage } = usePagedList(걸러낸것, 목록.perPage, 목록.page)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**막는 것은 조용히 틀어지는 쪽이다.** 되돌림 열쇠에서 한 조각만 빠지면 — 이를테면 쪽크기 —
|
|
108
|
+
25에서 100으로 바꿔도 `page` 가 7에 머문다. 총 쪽수가 2로 줄어 `usePagedList` 가 마지막
|
|
109
|
+
쪽으로 조이니 **2쪽이 뜨는데 사람은 1쪽을 본다고 믿는다.** 오류도 빈 화면도 아니고 엉뚱한
|
|
110
|
+
쪽이라 아무도 못 알아챈다. 그래서 검색어와 쪽크기는 부르는 쪽이 적는 것이 아니라 **훅이
|
|
111
|
+
스스로 넣는다** — 적지 않은 것은 빠뜨릴 수도 없다. 쪽크기 기본값(`'25'`)도 여기가 쥔다
|
|
112
|
+
(화면마다 `Number(pageSize) || 25` 가 한 벌씩 있었다).
|
|
113
|
+
|
|
114
|
+
`resetOn` 은 **글·수·참거짓만** 받는다. 객체를 넣으면 `String()` 이 모두 `[object Object]` 로
|
|
115
|
+
만들어 열쇠가 영영 안 바뀌는데 아무 데서도 안 터진다 — 타입으로 막는다.
|
|
116
|
+
|
|
117
|
+
**거르고 세우는 일은 안 맡는다.** 세 화면의 잣대가 서로 다르고, 그 일을 훅 안에 넣으면
|
|
118
|
+
부르는 쪽의 `useMemo` 가 사라진다 — 그중 한 화면은 23,000개를 세운다. 그래서 두 걸음이고,
|
|
119
|
+
그 사이가 곧 `useMemo` 가 설 자리다.
|
|
120
|
+
|
|
10
121
|
## 0.200.0
|
|
11
122
|
|
|
12
123
|
### 더해짐 — `ItemActions`
|