@tide-tds/foundation 0.0.0-stage → 0.1.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.
@@ -0,0 +1,328 @@
1
+ import { PrimitiveColorName } from "./color.js";
2
+ /** Theme 이름 */
3
+ export type ThemeName = "light" | "dark";
4
+ /** Primitive에 투명도를 더한 색. overlay와 shadow 색에만 쓰고, CSS에는 8자리 hex로 나간다. */
5
+ export interface AlphaColor {
6
+ readonly primitive: PrimitiveColorName;
7
+ /** 0~1 */
8
+ readonly alpha: number;
9
+ }
10
+ /**
11
+ * Semantic Token 하나가 가리키는 값. `transparent`는 light raised border에만 쓴다(CSS에서도 `transparent` 키워드로 나간다).
12
+ */
13
+ export type SemanticColorValue = PrimitiveColorName | AlphaColor | "transparent";
14
+ /** Theme별로 가리키는 값 */
15
+ export interface ThemedColor {
16
+ readonly light: SemanticColorValue;
17
+ readonly dark: SemanticColorValue;
18
+ }
19
+ /** Role. Component에서는 `color` prop으로 고른다. */
20
+ export type Role = "neutral" | "primary" | "success" | "warning" | "danger" | "info";
21
+ /**
22
+ * Role이 참조하는 Primitive 계열.
23
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
24
+ */
25
+ export declare const roleFamily: {
26
+ readonly neutral: "gray";
27
+ readonly primary: "blue";
28
+ readonly success: "green";
29
+ readonly warning: "amber";
30
+ readonly danger: "red";
31
+ readonly info: "cyan";
32
+ };
33
+ export declare const semantic: {
34
+ readonly background: {
35
+ readonly canvas: {
36
+ readonly light: "white";
37
+ readonly dark: "gray-950";
38
+ };
39
+ readonly surface: {
40
+ readonly light: "white";
41
+ readonly dark: "gray-950";
42
+ };
43
+ readonly raised: {
44
+ readonly light: "white";
45
+ readonly dark: "gray-900";
46
+ };
47
+ readonly disabled: {
48
+ readonly light: "gray-100";
49
+ readonly dark: "gray-900";
50
+ };
51
+ readonly overlay: {
52
+ readonly light: {
53
+ readonly primitive: "gray-950";
54
+ readonly alpha: 0.5;
55
+ };
56
+ readonly dark: {
57
+ readonly primitive: "gray-950";
58
+ readonly alpha: 0.7;
59
+ };
60
+ };
61
+ readonly "neutral-solid": {
62
+ readonly light: "gray-600";
63
+ readonly dark: "gray-600";
64
+ };
65
+ readonly "neutral-solid-hover": {
66
+ readonly light: "gray-700";
67
+ readonly dark: "gray-700";
68
+ };
69
+ readonly "neutral-solid-active": {
70
+ readonly light: "gray-800";
71
+ readonly dark: "gray-800";
72
+ };
73
+ readonly "neutral-subtle": {
74
+ readonly light: "gray-50";
75
+ readonly dark: "gray-900";
76
+ };
77
+ readonly "neutral-subtle-hover": {
78
+ readonly light: "gray-100";
79
+ readonly dark: "gray-800";
80
+ };
81
+ readonly "neutral-subtle-active": {
82
+ readonly light: "gray-200";
83
+ readonly dark: "gray-700";
84
+ };
85
+ readonly "primary-solid": {
86
+ readonly light: "blue-600";
87
+ readonly dark: "blue-600";
88
+ };
89
+ readonly "primary-solid-hover": {
90
+ readonly light: "blue-700";
91
+ readonly dark: "blue-700";
92
+ };
93
+ readonly "primary-solid-active": {
94
+ readonly light: "blue-800";
95
+ readonly dark: "blue-800";
96
+ };
97
+ readonly "primary-subtle": {
98
+ readonly light: "blue-50";
99
+ readonly dark: "blue-950";
100
+ };
101
+ readonly "primary-subtle-hover": {
102
+ readonly light: "blue-100";
103
+ readonly dark: "blue-900";
104
+ };
105
+ readonly "primary-subtle-active": {
106
+ readonly light: "blue-200";
107
+ readonly dark: "blue-800";
108
+ };
109
+ readonly "success-solid": {
110
+ readonly light: "green-600";
111
+ readonly dark: "green-600";
112
+ };
113
+ readonly "success-solid-hover": {
114
+ readonly light: "green-700";
115
+ readonly dark: "green-700";
116
+ };
117
+ readonly "success-solid-active": {
118
+ readonly light: "green-800";
119
+ readonly dark: "green-800";
120
+ };
121
+ readonly "success-subtle": {
122
+ readonly light: "green-50";
123
+ readonly dark: "green-950";
124
+ };
125
+ readonly "success-subtle-hover": {
126
+ readonly light: "green-100";
127
+ readonly dark: "green-900";
128
+ };
129
+ readonly "success-subtle-active": {
130
+ readonly light: "green-200";
131
+ readonly dark: "green-800";
132
+ };
133
+ readonly "warning-solid": {
134
+ readonly light: "amber-600";
135
+ readonly dark: "amber-600";
136
+ };
137
+ readonly "warning-solid-hover": {
138
+ readonly light: "amber-700";
139
+ readonly dark: "amber-700";
140
+ };
141
+ readonly "warning-solid-active": {
142
+ readonly light: "amber-800";
143
+ readonly dark: "amber-800";
144
+ };
145
+ readonly "warning-subtle": {
146
+ readonly light: "amber-50";
147
+ readonly dark: "amber-950";
148
+ };
149
+ readonly "warning-subtle-hover": {
150
+ readonly light: "amber-100";
151
+ readonly dark: "amber-900";
152
+ };
153
+ readonly "warning-subtle-active": {
154
+ readonly light: "amber-200";
155
+ readonly dark: "amber-800";
156
+ };
157
+ readonly "danger-solid": {
158
+ readonly light: "red-600";
159
+ readonly dark: "red-600";
160
+ };
161
+ readonly "danger-solid-hover": {
162
+ readonly light: "red-700";
163
+ readonly dark: "red-700";
164
+ };
165
+ readonly "danger-solid-active": {
166
+ readonly light: "red-800";
167
+ readonly dark: "red-800";
168
+ };
169
+ readonly "danger-subtle": {
170
+ readonly light: "red-50";
171
+ readonly dark: "red-950";
172
+ };
173
+ readonly "danger-subtle-hover": {
174
+ readonly light: "red-100";
175
+ readonly dark: "red-900";
176
+ };
177
+ readonly "danger-subtle-active": {
178
+ readonly light: "red-200";
179
+ readonly dark: "red-800";
180
+ };
181
+ readonly "info-solid": {
182
+ readonly light: "cyan-600";
183
+ readonly dark: "cyan-600";
184
+ };
185
+ readonly "info-solid-hover": {
186
+ readonly light: "cyan-700";
187
+ readonly dark: "cyan-700";
188
+ };
189
+ readonly "info-solid-active": {
190
+ readonly light: "cyan-800";
191
+ readonly dark: "cyan-800";
192
+ };
193
+ readonly "info-subtle": {
194
+ readonly light: "cyan-50";
195
+ readonly dark: "cyan-950";
196
+ };
197
+ readonly "info-subtle-hover": {
198
+ readonly light: "cyan-100";
199
+ readonly dark: "cyan-900";
200
+ };
201
+ readonly "info-subtle-active": {
202
+ readonly light: "cyan-200";
203
+ readonly dark: "cyan-800";
204
+ };
205
+ };
206
+ readonly text: {
207
+ readonly default: {
208
+ readonly light: "gray-900";
209
+ readonly dark: "gray-50";
210
+ };
211
+ readonly muted: {
212
+ readonly light: "gray-600";
213
+ readonly dark: "gray-300";
214
+ };
215
+ readonly disabled: {
216
+ readonly light: "gray-400";
217
+ readonly dark: "gray-600";
218
+ };
219
+ readonly "on-solid": {
220
+ readonly light: "white";
221
+ readonly dark: "white";
222
+ };
223
+ readonly primary: {
224
+ readonly light: "blue-800";
225
+ readonly dark: "blue-200";
226
+ };
227
+ readonly success: {
228
+ readonly light: "green-800";
229
+ readonly dark: "green-200";
230
+ };
231
+ readonly warning: {
232
+ readonly light: "amber-800";
233
+ readonly dark: "amber-200";
234
+ };
235
+ readonly danger: {
236
+ readonly light: "red-800";
237
+ readonly dark: "red-200";
238
+ };
239
+ readonly info: {
240
+ readonly light: "cyan-800";
241
+ readonly dark: "cyan-200";
242
+ };
243
+ };
244
+ readonly border: {
245
+ readonly default: {
246
+ readonly light: "gray-200";
247
+ readonly dark: "gray-800";
248
+ };
249
+ readonly strong: {
250
+ readonly light: "gray-500";
251
+ readonly dark: "gray-400";
252
+ };
253
+ readonly raised: {
254
+ readonly light: "transparent";
255
+ readonly dark: "gray-800";
256
+ };
257
+ readonly primary: {
258
+ readonly light: "blue-600";
259
+ readonly dark: "blue-400";
260
+ };
261
+ readonly success: {
262
+ readonly light: "green-600";
263
+ readonly dark: "green-400";
264
+ };
265
+ readonly warning: {
266
+ readonly light: "amber-600";
267
+ readonly dark: "amber-400";
268
+ };
269
+ readonly danger: {
270
+ readonly light: "red-600";
271
+ readonly dark: "red-400";
272
+ };
273
+ readonly info: {
274
+ readonly light: "cyan-600";
275
+ readonly dark: "cyan-400";
276
+ };
277
+ };
278
+ readonly outline: {
279
+ readonly focus: {
280
+ readonly light: "blue-600";
281
+ readonly dark: "blue-400";
282
+ };
283
+ };
284
+ };
285
+ /** Semantic namespace와 Utility class 접두사 */
286
+ export type SemanticNamespace = "background" | "text" | "border" | "outline";
287
+ export declare const semanticPrefix: {
288
+ readonly background: "bg";
289
+ readonly text: "text";
290
+ readonly border: "border";
291
+ readonly outline: "outline";
292
+ };
293
+ /** Semantic Token의 Utility class 이름. 예: `bg-primary-solid`, `text-muted` */
294
+ export type SemanticColorName = { [Namespace in SemanticNamespace]: `${(typeof semanticPrefix)[Namespace]}-${keyof (typeof semantic)[Namespace] & string}`; }[SemanticNamespace];
295
+ /**
296
+ * Theme별 shadow 색. CSS에서는 `--tide-shadow-color`로 쓴다.
297
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
298
+ */
299
+ export declare const shadowColor: {
300
+ readonly light: {
301
+ readonly primitive: "gray-950";
302
+ readonly alpha: 0.08;
303
+ };
304
+ readonly dark: {
305
+ readonly primitive: "black";
306
+ readonly alpha: 0.3;
307
+ };
308
+ };
309
+ /**
310
+ * 모든 Semantic Token(namespace, Utility class 이름, Theme별 값).
311
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
312
+ */
313
+ export declare function semanticEntries(): {
314
+ readonly namespace: SemanticNamespace;
315
+ readonly key: string;
316
+ readonly className: SemanticColorName;
317
+ readonly value: ThemedColor;
318
+ }[];
319
+ /**
320
+ * 값을 hex로 바꾼다. alpha가 있으면 8자리 hex(`#rrggbbaa`)다. `transparent`는 `#00000000`이다.
321
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
322
+ */
323
+ export declare function colorValueHex(value: SemanticColorValue): string;
324
+ /**
325
+ * Semantic Token이 Theme에서 가리키는 hex.
326
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
327
+ */
328
+ export declare function semanticHex(name: SemanticColorName, theme: ThemeName): string;
@@ -0,0 +1,318 @@
1
+ import { primitiveHex } from "./color.js";
2
+
3
+ // src/semantic.ts
4
+ /**
5
+ * Role이 참조하는 Primitive 계열.
6
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
7
+ */
8
+ const roleFamily = {
9
+ neutral: "gray",
10
+ primary: "blue",
11
+ success: "green",
12
+ warning: "amber",
13
+ danger: "red",
14
+ info: "cyan"
15
+ };
16
+ const semantic = {
17
+ background: {
18
+ canvas: {
19
+ light: "white",
20
+ dark: "gray-950"
21
+ },
22
+ surface: {
23
+ light: "white",
24
+ dark: "gray-950"
25
+ },
26
+ raised: {
27
+ light: "white",
28
+ dark: "gray-900"
29
+ },
30
+ disabled: {
31
+ light: "gray-100",
32
+ dark: "gray-900"
33
+ },
34
+ overlay: {
35
+ light: {
36
+ primitive: "gray-950",
37
+ alpha: .5
38
+ },
39
+ dark: {
40
+ primitive: "gray-950",
41
+ alpha: .7
42
+ }
43
+ },
44
+ "neutral-solid": {
45
+ light: "gray-600",
46
+ dark: "gray-600"
47
+ },
48
+ "neutral-solid-hover": {
49
+ light: "gray-700",
50
+ dark: "gray-700"
51
+ },
52
+ "neutral-solid-active": {
53
+ light: "gray-800",
54
+ dark: "gray-800"
55
+ },
56
+ "neutral-subtle": {
57
+ light: "gray-50",
58
+ dark: "gray-900"
59
+ },
60
+ "neutral-subtle-hover": {
61
+ light: "gray-100",
62
+ dark: "gray-800"
63
+ },
64
+ "neutral-subtle-active": {
65
+ light: "gray-200",
66
+ dark: "gray-700"
67
+ },
68
+ "primary-solid": {
69
+ light: "blue-600",
70
+ dark: "blue-600"
71
+ },
72
+ "primary-solid-hover": {
73
+ light: "blue-700",
74
+ dark: "blue-700"
75
+ },
76
+ "primary-solid-active": {
77
+ light: "blue-800",
78
+ dark: "blue-800"
79
+ },
80
+ "primary-subtle": {
81
+ light: "blue-50",
82
+ dark: "blue-950"
83
+ },
84
+ "primary-subtle-hover": {
85
+ light: "blue-100",
86
+ dark: "blue-900"
87
+ },
88
+ "primary-subtle-active": {
89
+ light: "blue-200",
90
+ dark: "blue-800"
91
+ },
92
+ "success-solid": {
93
+ light: "green-600",
94
+ dark: "green-600"
95
+ },
96
+ "success-solid-hover": {
97
+ light: "green-700",
98
+ dark: "green-700"
99
+ },
100
+ "success-solid-active": {
101
+ light: "green-800",
102
+ dark: "green-800"
103
+ },
104
+ "success-subtle": {
105
+ light: "green-50",
106
+ dark: "green-950"
107
+ },
108
+ "success-subtle-hover": {
109
+ light: "green-100",
110
+ dark: "green-900"
111
+ },
112
+ "success-subtle-active": {
113
+ light: "green-200",
114
+ dark: "green-800"
115
+ },
116
+ "warning-solid": {
117
+ light: "amber-600",
118
+ dark: "amber-600"
119
+ },
120
+ "warning-solid-hover": {
121
+ light: "amber-700",
122
+ dark: "amber-700"
123
+ },
124
+ "warning-solid-active": {
125
+ light: "amber-800",
126
+ dark: "amber-800"
127
+ },
128
+ "warning-subtle": {
129
+ light: "amber-50",
130
+ dark: "amber-950"
131
+ },
132
+ "warning-subtle-hover": {
133
+ light: "amber-100",
134
+ dark: "amber-900"
135
+ },
136
+ "warning-subtle-active": {
137
+ light: "amber-200",
138
+ dark: "amber-800"
139
+ },
140
+ "danger-solid": {
141
+ light: "red-600",
142
+ dark: "red-600"
143
+ },
144
+ "danger-solid-hover": {
145
+ light: "red-700",
146
+ dark: "red-700"
147
+ },
148
+ "danger-solid-active": {
149
+ light: "red-800",
150
+ dark: "red-800"
151
+ },
152
+ "danger-subtle": {
153
+ light: "red-50",
154
+ dark: "red-950"
155
+ },
156
+ "danger-subtle-hover": {
157
+ light: "red-100",
158
+ dark: "red-900"
159
+ },
160
+ "danger-subtle-active": {
161
+ light: "red-200",
162
+ dark: "red-800"
163
+ },
164
+ "info-solid": {
165
+ light: "cyan-600",
166
+ dark: "cyan-600"
167
+ },
168
+ "info-solid-hover": {
169
+ light: "cyan-700",
170
+ dark: "cyan-700"
171
+ },
172
+ "info-solid-active": {
173
+ light: "cyan-800",
174
+ dark: "cyan-800"
175
+ },
176
+ "info-subtle": {
177
+ light: "cyan-50",
178
+ dark: "cyan-950"
179
+ },
180
+ "info-subtle-hover": {
181
+ light: "cyan-100",
182
+ dark: "cyan-900"
183
+ },
184
+ "info-subtle-active": {
185
+ light: "cyan-200",
186
+ dark: "cyan-800"
187
+ }
188
+ },
189
+ text: {
190
+ default: {
191
+ light: "gray-900",
192
+ dark: "gray-50"
193
+ },
194
+ muted: {
195
+ light: "gray-600",
196
+ dark: "gray-300"
197
+ },
198
+ disabled: {
199
+ light: "gray-400",
200
+ dark: "gray-600"
201
+ },
202
+ "on-solid": {
203
+ light: "white",
204
+ dark: "white"
205
+ },
206
+ primary: {
207
+ light: "blue-800",
208
+ dark: "blue-200"
209
+ },
210
+ success: {
211
+ light: "green-800",
212
+ dark: "green-200"
213
+ },
214
+ warning: {
215
+ light: "amber-800",
216
+ dark: "amber-200"
217
+ },
218
+ danger: {
219
+ light: "red-800",
220
+ dark: "red-200"
221
+ },
222
+ info: {
223
+ light: "cyan-800",
224
+ dark: "cyan-200"
225
+ }
226
+ },
227
+ border: {
228
+ default: {
229
+ light: "gray-200",
230
+ dark: "gray-800"
231
+ },
232
+ strong: {
233
+ light: "gray-500",
234
+ dark: "gray-400"
235
+ },
236
+ raised: {
237
+ light: "transparent",
238
+ dark: "gray-800"
239
+ },
240
+ primary: {
241
+ light: "blue-600",
242
+ dark: "blue-400"
243
+ },
244
+ success: {
245
+ light: "green-600",
246
+ dark: "green-400"
247
+ },
248
+ warning: {
249
+ light: "amber-600",
250
+ dark: "amber-400"
251
+ },
252
+ danger: {
253
+ light: "red-600",
254
+ dark: "red-400"
255
+ },
256
+ info: {
257
+ light: "cyan-600",
258
+ dark: "cyan-400"
259
+ }
260
+ },
261
+ outline: { focus: {
262
+ light: "blue-600",
263
+ dark: "blue-400"
264
+ } }
265
+ };
266
+ const semanticPrefix = {
267
+ background: "bg",
268
+ text: "text",
269
+ border: "border",
270
+ outline: "outline"
271
+ };
272
+ /**
273
+ * Theme별 shadow 색. CSS에서는 `--tide-shadow-color`로 쓴다.
274
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
275
+ */
276
+ const shadowColor = {
277
+ light: {
278
+ primitive: "gray-950",
279
+ alpha: .08
280
+ },
281
+ dark: {
282
+ primitive: "black",
283
+ alpha: .3
284
+ }
285
+ };
286
+ /**
287
+ * 모든 Semantic Token(namespace, Utility class 이름, Theme별 값).
288
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
289
+ */
290
+ function semanticEntries() {
291
+ return Object.keys(semantic).flatMap((namespace) => Object.entries(semantic[namespace]).map(([key, value]) => ({
292
+ namespace,
293
+ key,
294
+ className: `${semanticPrefix[namespace]}-${key}`,
295
+ value
296
+ })));
297
+ }
298
+ /**
299
+ * 값을 hex로 바꾼다. alpha가 있으면 8자리 hex(`#rrggbbaa`)다. `transparent`는 `#00000000`이다.
300
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
301
+ */
302
+ function colorValueHex(value) {
303
+ if (value === "transparent") return "#00000000";
304
+ if (typeof value === "string") return primitiveHex(value);
305
+ const alpha = Math.round(value.alpha * 255).toString(16).padStart(2, "0");
306
+ return `${primitiveHex(value.primitive)}${alpha}`;
307
+ }
308
+ /**
309
+ * Semantic Token이 Theme에서 가리키는 hex.
310
+ * @internal `@tide-tds/foundation/internal` 전용. 앱 개발자용 공개 계약이 아니다(문서 앱·빌드 스크립트·테스트용).
311
+ */
312
+ function semanticHex(name, theme) {
313
+ const entry = semanticEntries().find((candidate) => candidate.className === name);
314
+ if (!entry) throw new Error(`Semantic Token이 아니다: ${name}`);
315
+ return colorValueHex(entry.value[theme]);
316
+ }
317
+
318
+ export { colorValueHex, roleFamily, semantic, semanticEntries, semanticHex, semanticPrefix, shadowColor };