@ihabdevteam/core 0.9.9 → 0.9.11

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.
@@ -6990,6 +6990,8 @@ export declare function useComboboxSuggestions({ value, onChange, suggestions, o
6990
6990
  */
6991
6991
  export declare function useDailyTrainingSelection(userId?: string): {
6992
6992
  loaded: boolean;
6993
+ /** 뽑을 것이 실제로 있었나. loaded 만으로는 "포기했다" 와 가를 수 없다. */
6994
+ hasData: boolean;
6993
6995
  showYesterday: boolean;
6994
6996
  setShowYesterday: Dispatch<SetStateAction<boolean>>;
6995
6997
  getTrainingPerType: (typeKey: string) => TrainingItem[] | undefined;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Pretendard 웹폰트 — 선택 진입점.
3
+ *
4
+ * `--font-family` 는 'Pretendard Variable' 을 맨 앞에 두지만, 그 이름을
5
+ * 선언하는 @font-face 는 이 패키지 어디에도 없었다. 그래서 폰트를 따로
6
+ * 싣지 않은 앱은 조용히 system-ui 로 폴백한다 — 콘솔도 조용하고, 개발
7
+ * 기기에 Pretendard 가 설치돼 있으면 두 번째 후보로 매칭돼 정상처럼
8
+ * 보인다. **일반 사용자에게만 다른 폰트가 나가는 형태**라 눈치채기 어렵다.
9
+ * (실제로 소리방향성시스템이 이 상태로 배포 직전까지 갔다.)
10
+ *
11
+ * 앱에서 pretendard 를 설치하고 이 파일을 진입점에서 한 번 import 하면
12
+ * 그 폴백이 사라진다.
13
+ *
14
+ * npm i pretendard
15
+ * import '@ihabdevteam/core/fonts.css'
16
+ *
17
+ * pretendard 는 optional peerDependency 다. 설치본이 97MB(정적 굵기·서브셋·
18
+ * 포맷을 모두 담는다)라 dependencies 에 두면 이 파일을 쓰지 않는 소비자와
19
+ * 그들의 CI 까지 매번 그 값을 치른다 — 아래 "필요한 쪽만 지불한다" 와
20
+ * 어긋난다. 설치하지 않은 채 이 파일을 import 하면 번들러가 경로를 못 찾아
21
+ * **빌드가 멈춘다.** 조용히 시스템 폰트로 흘러내리는 것보다 낫다.
22
+ *
23
+ * styles.css·tokens.css 와 묶지 않고 따로 둔 이유: 폰트는 무게가 있고,
24
+ * 이미 CDN 이나 자체 경로로 Pretendard 를 받는 앱도 있다. 필요한 쪽만
25
+ * 지불하게 한다.
26
+ *
27
+ * 가변 폰트의 동적 서브셋을 쓴다 — 화면에 실제로 나온 글자가 속한
28
+ * 구간만 받으므로, 한글 전체를 한 벌(2MB)로 받는 것보다 첫 그림이 빠르다.
29
+ * 이름은 tokens.css 의 --font-family 첫 후보와 반드시 같아야 한다.
30
+ *
31
+ * 이 파일은 postcss 를 태우지 않고 그대로 복사된다 — @import 가 살아 있어야
32
+ * 소비자 번들러가 pretendard 를 제 위치에서 풀고 woff2 를 산출물에 넣는다.
33
+ * postcss-import 가 여기서 내용을 펼치면 url() 이 core 기준 상대경로가 되어
34
+ * 깨진다.
35
+ */
36
+ @import 'pretendard/dist/web/variable/pretendardvariable-dynamic-subset.css';
@@ -11,6 +11,8 @@ import type { TrainingItem } from '../types/training';
11
11
  */
12
12
  export declare function useDailyTrainingSelection(userId?: string): {
13
13
  loaded: boolean;
14
+ /** 뽑을 것이 실제로 있었나. loaded 만으로는 "포기했다" 와 가를 수 없다. */
15
+ hasData: boolean;
14
16
  showYesterday: boolean;
15
17
  setShowYesterday: import("react").Dispatch<import("react").SetStateAction<boolean>>;
16
18
  getTrainingPerType: (typeKey: string) => TrainingItem[] | undefined;
@@ -24,6 +24,11 @@ export function useDailyTrainingSelection(userId) {
24
24
  // 선택으로 갱신되지만 화면은 익명 선택을 계속 보여준다(실측: 모두가 같은 묶음을 받음).
25
25
  // 계산이 끝날 때마다 올리는 이 값이 리렌더를 보장한다.
26
26
  const [revision, setRevision] = useState(0);
27
+ // loaded 는 "시도를 그만뒀다" 는 뜻이지 "자료가 있다" 는 뜻이 아니다 — 10초 뒤 포기할
28
+ // 때도 true 가 된다. 그러면 부르는 쪽은 **"아직 자료가 없다" 와 "오늘 훈련이 없다" 를
29
+ // 가를 수가 없어** 설명 없는 빈 화면을 그리게 된다(실제로 그런 화면이 있다).
30
+ // loaded 의 뜻을 바꾸면 지금 쓰는 곳이 깨지므로, 가를 수 있는 값을 따로 낸다.
31
+ const [hasData, setHasData] = useState(false);
27
32
  useEffect(() => {
28
33
  let cancelled = false;
29
34
  let timer;
@@ -44,6 +49,7 @@ export function useDailyTrainingSelection(userId) {
44
49
  todayRef.current = sel.today;
45
50
  yesterdayRef.current = sel.yesterday;
46
51
  setLoaded(true);
52
+ setHasData(true);
47
53
  setRevision(n => n + 1);
48
54
  cancelled = true;
49
55
  stop();
@@ -72,8 +78,11 @@ export function useDailyTrainingSelection(userId) {
72
78
  return;
73
79
  }
74
80
  // 데이터가 끝내 차지 않으면 일정 시도 후 중단(빈 선택이라도 로딩 종료)
81
+ // 포기한다. hasData 를 반드시 false 로 되돌린다 — userId 가 바뀌어 다시 돌 때,
82
+ // 앞 사람 것이 성공했다면 true 로 남아 있어 "자료가 있다" 고 거짓말하게 된다.
75
83
  if (++attempts >= MAX_ATTEMPTS) {
76
84
  setLoaded(true);
85
+ setHasData(false);
77
86
  cancelled = true;
78
87
  stop();
79
88
  }
@@ -90,5 +99,10 @@ export function useDailyTrainingSelection(userId) {
90
99
  : (fallback?.[typeKey]?.length ? fallback[typeKey] : undefined);
91
100
  return pick;
92
101
  }, [showYesterday, revision]);
93
- return { loaded, showYesterday, setShowYesterday, getTrainingPerType };
102
+ return {
103
+ loaded,
104
+ /** 뽑을 것이 실제로 있었나. loaded 만으로는 "포기했다" 와 가를 수 없다. */
105
+ hasData,
106
+ showYesterday, setShowYesterday, getTrainingPerType,
107
+ };
94
108
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ihabdevteam/core",
3
- "version": "0.9.9",
3
+ "version": "0.9.11",
4
4
  "private": false,
5
5
  "main": "dist/ihabdevteam-core.cjs.js",
6
6
  "module": "dist/ihabdevteam-core.esm.js",
@@ -81,7 +81,8 @@
81
81
  },
82
82
  "./i18n/locales/*": "./dist/packages/core/src/i18n/locales/*",
83
83
  "./styles.css": "./dist/ihabdevteam-core.css",
84
- "./tokens.css": "./dist/ihabdevteam-core-tokens.css"
84
+ "./tokens.css": "./dist/ihabdevteam-core-tokens.css",
85
+ "./fonts.css": "./dist/ihabdevteam-core-fonts.css"
85
86
  },
86
87
  "publishConfig": {
87
88
  "access": "public"
@@ -100,17 +101,18 @@
100
101
  "dist/**/*.css"
101
102
  ],
102
103
  "scripts": {
103
- "build": "(rm -rf dist node_modules/.tmp/tsconfig.core.tsbuildinfo 2>/dev/null || true) && tsc -p tsconfig.json && postcss src/styles.css -o dist/ihabdevteam-core.css && CORE_CSS_NO_PREFIX=1 postcss src/tokens.css -o dist/ihabdevteam-core-tokens.css && mkdir -p dist/packages/core/src && find src -type f \\( -name '*.css' -o -name '*.svg' -o -name '*.mp3' -o -name '*.png' \\) | while IFS= read -r f; do d=$(dirname \"$f\"); mkdir -p \"dist/packages/core/$d\"; cp \"$f\" \"dist/packages/core/$d/\"; done && mkdir -p dist/logo && if [ -d src/logo ]; then cp -r src/logo/. dist/logo/; elif [ -d ../../logo ]; then cp -r ../../logo/. dist/logo/; elif [ -d ../../public/logo ]; then cp -r ../../public/logo/. dist/logo/; fi && node scripts/check-build-outputs.mjs && rollup -c && cp dist/packages/core/src/index.d.ts dist/ihabdevteam-core.d.ts",
104
+ "build": "(rm -rf dist node_modules/.tmp/tsconfig.core.tsbuildinfo 2>/dev/null || true) && tsc -p tsconfig.json && postcss src/styles.css -o dist/ihabdevteam-core.css && CORE_CSS_NO_PREFIX=1 postcss src/tokens.css -o dist/ihabdevteam-core-tokens.css && cp src/fonts.css dist/ihabdevteam-core-fonts.css && mkdir -p dist/packages/core/src && find src -type f \\( -name '*.css' -o -name '*.svg' -o -name '*.mp3' -o -name '*.png' \\) | while IFS= read -r f; do d=$(dirname \"$f\"); mkdir -p \"dist/packages/core/$d\"; cp \"$f\" \"dist/packages/core/$d/\"; done && mkdir -p dist/logo && if [ -d src/logo ]; then cp -r src/logo/. dist/logo/; elif [ -d ../../logo ]; then cp -r ../../logo/. dist/logo/; elif [ -d ../../public/logo ]; then cp -r ../../public/logo/. dist/logo/; fi && node scripts/check-build-outputs.mjs && rollup -c && cp dist/packages/core/src/index.d.ts dist/ihabdevteam-core.d.ts",
104
105
  "extract-api": "api-extractor run --local --verbose",
105
106
  "postbuild": "npm run extract-api",
106
107
  "prepare": "npm run build",
107
108
  "prepublishOnly": "npm run build && npm run audit:exports && npm pack --dry-run > /dev/null",
108
109
  "dev": "vite serve playground --config playground/vite.config.ts",
109
- "typecheck:playground": "tsc -p playground/tsconfig.json --noEmit",
110
+ "typecheck:playground": "npm run build --silent && tsc -p playground/tsconfig.json --noEmit",
110
111
  "build-playground": "vite build playground --config playground/vite.config.js",
111
112
  "preview-playground": "vite preview --outDir playground/dist",
112
113
  "smoke-test": "node ./scripts/smoke-test.js",
113
114
  "audit:exports": "node ./scripts/audit-exports.cjs",
115
+ "audit:docs": "node ./scripts/audit-docs.cjs",
114
116
  "analyze:bundle": "node ./scripts/analyze-bundle.cjs",
115
117
  "pack:check": "bash ./scripts/publish-check.sh",
116
118
  "check:size": "size-limit",
@@ -125,7 +127,8 @@
125
127
  },
126
128
  "peerDependencies": {
127
129
  "react": "^16.8 || ^17 || ^18 || ^19",
128
- "react-dom": "^16.8 || ^17 || ^18 || ^19"
130
+ "react-dom": "^16.8 || ^17 || ^18 || ^19",
131
+ "pretendard": "^1.3.9"
129
132
  },
130
133
  "engines": {
131
134
  "node": ">=16"
@@ -176,5 +179,10 @@
176
179
  "path": "dist/ihabdevteam-core.esm.js",
177
180
  "limit": "800 KB"
178
181
  }
179
- ]
182
+ ],
183
+ "peerDependenciesMeta": {
184
+ "pretendard": {
185
+ "optional": true
186
+ }
187
+ }
180
188
  }