@nebutra/ui 0.1.0 → 0.2.1
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/dist/components/index.d.ts +380 -0
- package/dist/components/index.js +2398 -0
- package/dist/components/index.js.map +1 -0
- package/dist/hooks/index.d.ts +106 -0
- package/dist/hooks/index.js +182 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/icons/index.d.ts +3 -0
- package/dist/icons/index.js +5 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/index.d.ts +296 -0
- package/dist/layout/index.js +1303 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layouts/index.d.ts +161 -0
- package/dist/layouts/index.js +611 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/patterns/index.d.ts +363 -0
- package/dist/patterns/index.js +3004 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/primitives/index.d.ts +9588 -0
- package/dist/primitives/index.js +26779 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/styles/brand-override.css +61 -0
- package/dist/tailwind.preset.d.ts +251 -0
- package/dist/tailwind.preset.js +273 -0
- package/dist/tailwind.preset.js.map +1 -0
- package/dist/theme/index.d.ts +150 -0
- package/dist/theme/index.js +28 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/typography/fonts.css +110 -0
- package/dist/typography/index.d.ts +425 -0
- package/dist/typography/index.js +374 -0
- package/dist/typography/index.js.map +1 -0
- package/dist/utils/index.d.ts +61 -0
- package/dist/utils/index.js +55 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +18 -8
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
// src/typography/fonts.ts
|
|
2
|
+
var fonts = {
|
|
3
|
+
inter: {
|
|
4
|
+
family: "Inter",
|
|
5
|
+
weights: [300, 400, 500, 600, 700],
|
|
6
|
+
italic: false,
|
|
7
|
+
display: "swap",
|
|
8
|
+
variable: true,
|
|
9
|
+
googleFontsParam: "Inter:wght@300;400;500;600;700",
|
|
10
|
+
license: "OFL",
|
|
11
|
+
licenseUrl: "https://github.com/rsms/inter/blob/master/LICENSE.txt"
|
|
12
|
+
},
|
|
13
|
+
publicSans: {
|
|
14
|
+
family: "Public Sans",
|
|
15
|
+
weights: [300, 400, 500, 600, 700],
|
|
16
|
+
italic: true,
|
|
17
|
+
display: "swap",
|
|
18
|
+
variable: true,
|
|
19
|
+
googleFontsParam: "Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400;1,500",
|
|
20
|
+
license: "OFL",
|
|
21
|
+
licenseUrl: "https://github.com/uswds/public-sans/blob/develop/LICENSE.md"
|
|
22
|
+
},
|
|
23
|
+
jetbrainsMono: {
|
|
24
|
+
family: "JetBrains Mono",
|
|
25
|
+
weights: [400, 500, 700],
|
|
26
|
+
italic: false,
|
|
27
|
+
display: "swap",
|
|
28
|
+
variable: true,
|
|
29
|
+
googleFontsParam: "JetBrains+Mono:wght@400;500;700",
|
|
30
|
+
license: "OFL",
|
|
31
|
+
licenseUrl: "https://github.com/JetBrains/JetBrainsMono/blob/master/OFL.txt"
|
|
32
|
+
},
|
|
33
|
+
sourceHanSans: {
|
|
34
|
+
family: "Noto Sans SC",
|
|
35
|
+
weights: [400, 500, 700],
|
|
36
|
+
italic: false,
|
|
37
|
+
display: "swap",
|
|
38
|
+
variable: false,
|
|
39
|
+
googleFontsParam: "Noto+Sans+SC:wght@400;500;700",
|
|
40
|
+
license: "OFL",
|
|
41
|
+
licenseUrl: "https://github.com/adobe-fonts/source-han-sans/blob/master/LICENSE.txt"
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
function getGoogleFontsUrl(fontKeys) {
|
|
45
|
+
const families = fontKeys.map((key) => fonts[key]?.googleFontsParam).filter(Boolean).join("&family=");
|
|
46
|
+
if (!families) return "";
|
|
47
|
+
return `https://fonts.googleapis.com/css2?family=${families}&display=swap`;
|
|
48
|
+
}
|
|
49
|
+
var defaultFonts = ["inter", "jetbrainsMono"];
|
|
50
|
+
var cjkFonts = ["sourceHanSans"];
|
|
51
|
+
var allFonts = [...defaultFonts, ...cjkFonts];
|
|
52
|
+
function getFontPreloadLinks(fontKeys) {
|
|
53
|
+
return fontKeys.map((key) => {
|
|
54
|
+
const font = fonts[key];
|
|
55
|
+
if (!font) return "";
|
|
56
|
+
const url = getGoogleFontsUrl([key]);
|
|
57
|
+
return `<link rel="preload" href="${url}" as="style" crossorigin>`;
|
|
58
|
+
}).filter(Boolean);
|
|
59
|
+
}
|
|
60
|
+
function getGoogleFontsLink(fontKeys) {
|
|
61
|
+
const url = getGoogleFontsUrl(fontKeys);
|
|
62
|
+
if (!url) return "";
|
|
63
|
+
return `<link rel="stylesheet" href="${url}">`;
|
|
64
|
+
}
|
|
65
|
+
async function areFontsLoaded(fontFamilies2) {
|
|
66
|
+
if (typeof document === "undefined") return false;
|
|
67
|
+
try {
|
|
68
|
+
await Promise.all(fontFamilies2.map((family) => document.fonts.load(`16px "${family}"`)));
|
|
69
|
+
return true;
|
|
70
|
+
} catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function waitForFonts(fontFamilies2, timeout = 3e3) {
|
|
75
|
+
if (typeof document === "undefined") return false;
|
|
76
|
+
return new Promise((resolve) => {
|
|
77
|
+
const timer = setTimeout(() => resolve(false), timeout);
|
|
78
|
+
areFontsLoaded(fontFamilies2).then((loaded) => {
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
resolve(loaded);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
var fontSmoothing = {
|
|
85
|
+
WebkitFontSmoothing: "antialiased",
|
|
86
|
+
MozOsxFontSmoothing: "grayscale",
|
|
87
|
+
textRendering: "optimizeLegibility"
|
|
88
|
+
};
|
|
89
|
+
var fontFeatureSettings = {
|
|
90
|
+
/** Enable common ligatures and contextual alternates */
|
|
91
|
+
normal: '"calt" 1, "liga" 1',
|
|
92
|
+
/** Enable tabular figures for aligned numbers */
|
|
93
|
+
tabular: '"tnum" 1, "calt" 1',
|
|
94
|
+
/** Enable case-sensitive forms */
|
|
95
|
+
case: '"case" 1',
|
|
96
|
+
/** Enable stylistic set 01 (alternate digits) */
|
|
97
|
+
ss01: '"ss01" 1',
|
|
98
|
+
/** Enable stylistic set 02 (alternate a) */
|
|
99
|
+
ss02: '"ss02" 1'
|
|
100
|
+
};
|
|
101
|
+
function getFontLicenses() {
|
|
102
|
+
return Object.values(fonts).map((font) => ({
|
|
103
|
+
family: font.family,
|
|
104
|
+
license: font.license,
|
|
105
|
+
url: font.licenseUrl
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
var fontLicenseNotice = `
|
|
109
|
+
Fonts used in this project are licensed under open-source licenses:
|
|
110
|
+
|
|
111
|
+
- Inter: SIL Open Font License 1.1
|
|
112
|
+
- Public Sans: SIL Open Font License 1.1
|
|
113
|
+
- JetBrains Mono: SIL Open Font License 1.1
|
|
114
|
+
- Noto Sans SC (Source Han Sans): SIL Open Font License 1.1
|
|
115
|
+
|
|
116
|
+
All fonts are free for commercial use. See individual license files for details.
|
|
117
|
+
`.trim();
|
|
118
|
+
|
|
119
|
+
// src/typography/tokens.ts
|
|
120
|
+
var FONT_FAMILY_PRIMARY = '"Poppins", "vivo Sans", "PingFang SC", "Microsoft YaHei", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
|
|
121
|
+
var FONT_FAMILY_HEADING = '"Geist", "Poppins", "vivo Sans", "PingFang SC", "Microsoft YaHei", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
|
|
122
|
+
var FONT_FAMILY_MONO = '"JetBrains Mono", "Fira Code", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace';
|
|
123
|
+
var FONT_FAMILY_CJK = '"vivo Sans", "Source Han Sans SC", "Source Han Sans", "Noto Sans CJK SC", "Noto Sans SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif';
|
|
124
|
+
var fontFamilies = {
|
|
125
|
+
/** Primary UI and body text */
|
|
126
|
+
primary: FONT_FAMILY_PRIMARY,
|
|
127
|
+
/** Headings and titles */
|
|
128
|
+
heading: FONT_FAMILY_HEADING,
|
|
129
|
+
/** Code and monospace */
|
|
130
|
+
mono: FONT_FAMILY_MONO,
|
|
131
|
+
/** CJK-specific fallback */
|
|
132
|
+
cjk: FONT_FAMILY_CJK,
|
|
133
|
+
/** Primary with CJK fallback for multilingual content */
|
|
134
|
+
primaryCJK: `${FONT_FAMILY_PRIMARY}, ${FONT_FAMILY_CJK}`,
|
|
135
|
+
/** System font stack (fast fallback, no web fonts) */
|
|
136
|
+
system: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'
|
|
137
|
+
};
|
|
138
|
+
var fontSizes = {
|
|
139
|
+
/** 12px - Micro text, badges */
|
|
140
|
+
xs: "0.75rem",
|
|
141
|
+
/** 14px - Small text, captions, labels */
|
|
142
|
+
sm: "0.875rem",
|
|
143
|
+
/** 16px - Base body text */
|
|
144
|
+
base: "1rem",
|
|
145
|
+
/** 18px - Lead text, larger body */
|
|
146
|
+
lg: "1.125rem",
|
|
147
|
+
/** 20px - Small headings, subtitles */
|
|
148
|
+
xl: "1.25rem",
|
|
149
|
+
/** 24px - H4 equivalent */
|
|
150
|
+
"2xl": "1.5rem",
|
|
151
|
+
/** 30px - H3 equivalent */
|
|
152
|
+
"3xl": "1.875rem",
|
|
153
|
+
/** 36px - H2 equivalent */
|
|
154
|
+
"4xl": "2.25rem",
|
|
155
|
+
/** 48px - H1 equivalent */
|
|
156
|
+
"5xl": "3rem",
|
|
157
|
+
/** 60px - Display/Hero text */
|
|
158
|
+
"6xl": "3.75rem",
|
|
159
|
+
/** 72px - Large display */
|
|
160
|
+
"7xl": "4.5rem",
|
|
161
|
+
/** 96px - Extra large display */
|
|
162
|
+
"8xl": "6rem"
|
|
163
|
+
};
|
|
164
|
+
var fontSizesPx = {
|
|
165
|
+
xs: 12,
|
|
166
|
+
sm: 14,
|
|
167
|
+
base: 16,
|
|
168
|
+
lg: 18,
|
|
169
|
+
xl: 20,
|
|
170
|
+
"2xl": 24,
|
|
171
|
+
"3xl": 30,
|
|
172
|
+
"4xl": 36,
|
|
173
|
+
"5xl": 48,
|
|
174
|
+
"6xl": 60,
|
|
175
|
+
"7xl": 72,
|
|
176
|
+
"8xl": 96
|
|
177
|
+
};
|
|
178
|
+
var lineHeights = {
|
|
179
|
+
/** 1 - Single line, icons */
|
|
180
|
+
none: 1,
|
|
181
|
+
/** 1.25 - Tight, for large headings */
|
|
182
|
+
tight: 1.25,
|
|
183
|
+
/** 1.375 - Slightly snug */
|
|
184
|
+
snug: 1.375,
|
|
185
|
+
/** 1.5 - Normal body text */
|
|
186
|
+
normal: 1.5,
|
|
187
|
+
/** 1.625 - Relaxed reading */
|
|
188
|
+
relaxed: 1.625,
|
|
189
|
+
/** 1.75 - Loose, for small text */
|
|
190
|
+
loose: 1.75,
|
|
191
|
+
/** 2 - Double spaced */
|
|
192
|
+
double: 2
|
|
193
|
+
};
|
|
194
|
+
var fontWeights = {
|
|
195
|
+
/** 100 - Thin (if available) */
|
|
196
|
+
thin: 100,
|
|
197
|
+
/** 200 - Extra light */
|
|
198
|
+
extralight: 200,
|
|
199
|
+
/** 300 - Light */
|
|
200
|
+
light: 300,
|
|
201
|
+
/** 400 - Regular/Normal */
|
|
202
|
+
normal: 400,
|
|
203
|
+
/** 500 - Medium */
|
|
204
|
+
medium: 500,
|
|
205
|
+
/** 600 - Semibold */
|
|
206
|
+
semibold: 600,
|
|
207
|
+
/** 700 - Bold */
|
|
208
|
+
bold: 700,
|
|
209
|
+
/** 800 - Extra bold */
|
|
210
|
+
extrabold: 800,
|
|
211
|
+
/** 900 - Black */
|
|
212
|
+
black: 900
|
|
213
|
+
};
|
|
214
|
+
var letterSpacing = {
|
|
215
|
+
/** -0.05em - Very tight, large display only */
|
|
216
|
+
tighter: "-0.05em",
|
|
217
|
+
/** -0.025em - Slightly tight, headings */
|
|
218
|
+
tight: "-0.025em",
|
|
219
|
+
/** 0 - Normal */
|
|
220
|
+
normal: "0",
|
|
221
|
+
/** 0.025em - Slightly wide */
|
|
222
|
+
wide: "0.025em",
|
|
223
|
+
/** 0.05em - Wide, for small caps */
|
|
224
|
+
wider: "0.05em",
|
|
225
|
+
/** 0.1em - Very wide, all caps */
|
|
226
|
+
widest: "0.1em"
|
|
227
|
+
};
|
|
228
|
+
var typeStyles = {
|
|
229
|
+
/** Hero/Display - Large marketing headlines */
|
|
230
|
+
display: {
|
|
231
|
+
fontFamily: fontFamilies.heading,
|
|
232
|
+
fontSize: fontSizes["6xl"],
|
|
233
|
+
fontWeight: fontWeights.bold,
|
|
234
|
+
lineHeight: lineHeights.tight,
|
|
235
|
+
letterSpacing: letterSpacing.tight
|
|
236
|
+
},
|
|
237
|
+
/** H1 - Page titles */
|
|
238
|
+
h1: {
|
|
239
|
+
fontFamily: fontFamilies.heading,
|
|
240
|
+
fontSize: fontSizes["5xl"],
|
|
241
|
+
fontWeight: fontWeights.bold,
|
|
242
|
+
lineHeight: lineHeights.tight,
|
|
243
|
+
letterSpacing: letterSpacing.tight
|
|
244
|
+
},
|
|
245
|
+
/** H2 - Section titles */
|
|
246
|
+
h2: {
|
|
247
|
+
fontFamily: fontFamilies.heading,
|
|
248
|
+
fontSize: fontSizes["4xl"],
|
|
249
|
+
fontWeight: fontWeights.bold,
|
|
250
|
+
lineHeight: lineHeights.tight,
|
|
251
|
+
letterSpacing: letterSpacing.tight
|
|
252
|
+
},
|
|
253
|
+
/** H3 - Subsection titles */
|
|
254
|
+
h3: {
|
|
255
|
+
fontFamily: fontFamilies.heading,
|
|
256
|
+
fontSize: fontSizes["3xl"],
|
|
257
|
+
fontWeight: fontWeights.semibold,
|
|
258
|
+
lineHeight: lineHeights.snug,
|
|
259
|
+
letterSpacing: letterSpacing.normal
|
|
260
|
+
},
|
|
261
|
+
/** H4 - Card titles, small sections */
|
|
262
|
+
h4: {
|
|
263
|
+
fontFamily: fontFamilies.heading,
|
|
264
|
+
fontSize: fontSizes["2xl"],
|
|
265
|
+
fontWeight: fontWeights.semibold,
|
|
266
|
+
lineHeight: lineHeights.snug,
|
|
267
|
+
letterSpacing: letterSpacing.normal
|
|
268
|
+
},
|
|
269
|
+
/** H5 - Widget titles */
|
|
270
|
+
h5: {
|
|
271
|
+
fontFamily: fontFamilies.heading,
|
|
272
|
+
fontSize: fontSizes.xl,
|
|
273
|
+
fontWeight: fontWeights.semibold,
|
|
274
|
+
lineHeight: lineHeights.normal,
|
|
275
|
+
letterSpacing: letterSpacing.normal
|
|
276
|
+
},
|
|
277
|
+
/** H6 - Smallest heading */
|
|
278
|
+
h6: {
|
|
279
|
+
fontFamily: fontFamilies.heading,
|
|
280
|
+
fontSize: fontSizes.lg,
|
|
281
|
+
fontWeight: fontWeights.semibold,
|
|
282
|
+
lineHeight: lineHeights.normal,
|
|
283
|
+
letterSpacing: letterSpacing.normal
|
|
284
|
+
},
|
|
285
|
+
/** Body - Default paragraph text */
|
|
286
|
+
body: {
|
|
287
|
+
fontFamily: fontFamilies.primary,
|
|
288
|
+
fontSize: fontSizes.base,
|
|
289
|
+
fontWeight: fontWeights.normal,
|
|
290
|
+
lineHeight: lineHeights.normal,
|
|
291
|
+
letterSpacing: letterSpacing.normal
|
|
292
|
+
},
|
|
293
|
+
/** Body Large - Lead paragraphs */
|
|
294
|
+
bodyLarge: {
|
|
295
|
+
fontFamily: fontFamilies.primary,
|
|
296
|
+
fontSize: fontSizes.lg,
|
|
297
|
+
fontWeight: fontWeights.normal,
|
|
298
|
+
lineHeight: lineHeights.relaxed,
|
|
299
|
+
letterSpacing: letterSpacing.normal
|
|
300
|
+
},
|
|
301
|
+
/** Body Small - Secondary text */
|
|
302
|
+
bodySmall: {
|
|
303
|
+
fontFamily: fontFamilies.primary,
|
|
304
|
+
fontSize: fontSizes.sm,
|
|
305
|
+
fontWeight: fontWeights.normal,
|
|
306
|
+
lineHeight: lineHeights.normal,
|
|
307
|
+
letterSpacing: letterSpacing.normal
|
|
308
|
+
},
|
|
309
|
+
/** Caption - Image captions, timestamps */
|
|
310
|
+
caption: {
|
|
311
|
+
fontFamily: fontFamilies.primary,
|
|
312
|
+
fontSize: fontSizes.xs,
|
|
313
|
+
fontWeight: fontWeights.normal,
|
|
314
|
+
lineHeight: lineHeights.normal,
|
|
315
|
+
letterSpacing: letterSpacing.wide
|
|
316
|
+
},
|
|
317
|
+
/** Label - Form labels, UI labels */
|
|
318
|
+
label: {
|
|
319
|
+
fontFamily: fontFamilies.primary,
|
|
320
|
+
fontSize: fontSizes.sm,
|
|
321
|
+
fontWeight: fontWeights.medium,
|
|
322
|
+
lineHeight: lineHeights.tight,
|
|
323
|
+
letterSpacing: letterSpacing.normal
|
|
324
|
+
},
|
|
325
|
+
/** Button - Button text */
|
|
326
|
+
button: {
|
|
327
|
+
fontFamily: fontFamilies.primary,
|
|
328
|
+
fontSize: fontSizes.sm,
|
|
329
|
+
fontWeight: fontWeights.medium,
|
|
330
|
+
lineHeight: lineHeights.tight,
|
|
331
|
+
letterSpacing: letterSpacing.wide
|
|
332
|
+
},
|
|
333
|
+
/** Code - Inline code */
|
|
334
|
+
code: {
|
|
335
|
+
fontFamily: fontFamilies.mono,
|
|
336
|
+
fontSize: fontSizes.sm,
|
|
337
|
+
fontWeight: fontWeights.normal,
|
|
338
|
+
lineHeight: lineHeights.normal,
|
|
339
|
+
letterSpacing: letterSpacing.normal
|
|
340
|
+
},
|
|
341
|
+
/** Code Block - Code blocks */
|
|
342
|
+
codeBlock: {
|
|
343
|
+
fontFamily: fontFamilies.mono,
|
|
344
|
+
fontSize: fontSizes.sm,
|
|
345
|
+
fontWeight: fontWeights.normal,
|
|
346
|
+
lineHeight: lineHeights.relaxed,
|
|
347
|
+
letterSpacing: letterSpacing.normal
|
|
348
|
+
},
|
|
349
|
+
/** Overline - Small caps labels */
|
|
350
|
+
overline: {
|
|
351
|
+
fontFamily: fontFamilies.primary,
|
|
352
|
+
fontSize: fontSizes.xs,
|
|
353
|
+
fontWeight: fontWeights.semibold,
|
|
354
|
+
lineHeight: lineHeights.normal,
|
|
355
|
+
letterSpacing: letterSpacing.widest,
|
|
356
|
+
textTransform: "uppercase"
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
var fluidFontSizes = {
|
|
360
|
+
/** Display: 36px to 72px */
|
|
361
|
+
display: "clamp(2.25rem, 5vw + 1rem, 4.5rem)",
|
|
362
|
+
/** H1: 30px to 48px */
|
|
363
|
+
h1: "clamp(1.875rem, 4vw + 0.5rem, 3rem)",
|
|
364
|
+
/** H2: 24px to 36px */
|
|
365
|
+
h2: "clamp(1.5rem, 3vw + 0.5rem, 2.25rem)",
|
|
366
|
+
/** H3: 20px to 30px */
|
|
367
|
+
h3: "clamp(1.25rem, 2vw + 0.5rem, 1.875rem)",
|
|
368
|
+
/** Body: 14px to 18px */
|
|
369
|
+
body: "clamp(0.875rem, 1vw + 0.5rem, 1.125rem)"
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
export { FONT_FAMILY_CJK, FONT_FAMILY_HEADING, FONT_FAMILY_MONO, FONT_FAMILY_PRIMARY, allFonts, areFontsLoaded, cjkFonts, defaultFonts, fluidFontSizes, fontFamilies, fontFeatureSettings, fontLicenseNotice, fontSizes, fontSizesPx, fontSmoothing, fontWeights, fonts, getFontLicenses, getFontPreloadLinks, getGoogleFontsLink, getGoogleFontsUrl, letterSpacing, lineHeights, typeStyles, waitForFonts };
|
|
373
|
+
//# sourceMappingURL=index.js.map
|
|
374
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/typography/fonts.ts","../../src/typography/tokens.ts"],"names":["fontFamilies"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Font Configuration and Loading Utilities\n *\n * Handles web font loading, preloading, and performance optimization.\n */\n\n// ============================================\n// Font Definitions\n// ============================================\n\n/**\n * Font configuration object\n */\nexport interface FontConfig {\n /** Font family name */\n family: string;\n /** Font weights to load */\n weights: number[];\n /** Include italic variants */\n italic?: boolean;\n /** Font display strategy */\n display?: \"auto\" | \"block\" | \"swap\" | \"fallback\" | \"optional\";\n /** Is this a variable font */\n variable?: boolean;\n /** Google Fonts URL parameter name */\n googleFontsParam?: string;\n /** Self-hosted font URL */\n selfHostUrl?: string;\n /** Font license */\n license: \"OFL\" | \"Apache-2.0\" | \"Ubuntu\" | \"MIT\" | \"Other\";\n /** Source URL for license */\n licenseUrl?: string;\n}\n\n/**\n * Registered fonts for the design system\n */\nexport const fonts: Record<string, FontConfig> = {\n inter: {\n family: \"Inter\",\n weights: [300, 400, 500, 600, 700],\n italic: false,\n display: \"swap\",\n variable: true,\n googleFontsParam: \"Inter:wght@300;400;500;600;700\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/rsms/inter/blob/master/LICENSE.txt\",\n },\n\n publicSans: {\n family: \"Public Sans\",\n weights: [300, 400, 500, 600, 700],\n italic: true,\n display: \"swap\",\n variable: true,\n googleFontsParam: \"Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400;1,500\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/uswds/public-sans/blob/develop/LICENSE.md\",\n },\n\n jetbrainsMono: {\n family: \"JetBrains Mono\",\n weights: [400, 500, 700],\n italic: false,\n display: \"swap\",\n variable: true,\n googleFontsParam: \"JetBrains+Mono:wght@400;500;700\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/JetBrains/JetBrainsMono/blob/master/OFL.txt\",\n },\n\n sourceHanSans: {\n family: \"Noto Sans SC\",\n weights: [400, 500, 700],\n italic: false,\n display: \"swap\",\n variable: false,\n googleFontsParam: \"Noto+Sans+SC:wght@400;500;700\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/adobe-fonts/source-han-sans/blob/master/LICENSE.txt\",\n },\n};\n\n// ============================================\n// Google Fonts URL Builder\n// ============================================\n\n/**\n * Generate Google Fonts URL for specified fonts\n */\nexport function getGoogleFontsUrl(fontKeys: (keyof typeof fonts)[]): string {\n const families = fontKeys\n .map((key) => fonts[key]?.googleFontsParam)\n .filter(Boolean)\n .join(\"&family=\");\n\n if (!families) return \"\";\n\n return `https://fonts.googleapis.com/css2?family=${families}&display=swap`;\n}\n\n/**\n * Default fonts to load\n */\nexport const defaultFonts: (keyof typeof fonts)[] = [\"inter\", \"jetbrainsMono\"];\n\n/**\n * Fonts for CJK (Chinese) support\n */\nexport const cjkFonts: (keyof typeof fonts)[] = [\"sourceHanSans\"];\n\n/**\n * All fonts including CJK\n */\nexport const allFonts: (keyof typeof fonts)[] = [...defaultFonts, ...cjkFonts];\n\n// ============================================\n// Font Loading Utilities\n// ============================================\n\n/**\n * Generate preload link elements for critical fonts\n */\nexport function getFontPreloadLinks(fontKeys: (keyof typeof fonts)[]): string[] {\n return fontKeys\n .map((key) => {\n const font = fonts[key];\n if (!font) return \"\";\n\n const url = getGoogleFontsUrl([key]);\n return `<link rel=\"preload\" href=\"${url}\" as=\"style\" crossorigin>`;\n })\n .filter(Boolean);\n}\n\n/**\n * Generate link element for Google Fonts\n */\nexport function getGoogleFontsLink(fontKeys: (keyof typeof fonts)[]): string {\n const url = getGoogleFontsUrl(fontKeys);\n if (!url) return \"\";\n\n return `<link rel=\"stylesheet\" href=\"${url}\">`;\n}\n\n/**\n * Check if fonts are loaded\n */\nexport async function areFontsLoaded(fontFamilies: string[]): Promise<boolean> {\n if (typeof document === \"undefined\") return false;\n\n try {\n await Promise.all(fontFamilies.map((family) => document.fonts.load(`16px \"${family}\"`)));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Wait for fonts to load with timeout\n */\nexport async function waitForFonts(fontFamilies: string[], timeout = 3000): Promise<boolean> {\n if (typeof document === \"undefined\") return false;\n\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), timeout);\n\n areFontsLoaded(fontFamilies).then((loaded) => {\n clearTimeout(timer);\n resolve(loaded);\n });\n });\n}\n\n// ============================================\n// CSS-in-JS Helpers\n// ============================================\n\n/**\n * Font smoothing CSS for crisp text rendering\n */\nexport const fontSmoothing = {\n WebkitFontSmoothing: \"antialiased\",\n MozOsxFontSmoothing: \"grayscale\",\n textRendering: \"optimizeLegibility\",\n} as const;\n\n/**\n * Font feature settings for Inter\n */\nexport const fontFeatureSettings = {\n /** Enable common ligatures and contextual alternates */\n normal: '\"calt\" 1, \"liga\" 1',\n /** Enable tabular figures for aligned numbers */\n tabular: '\"tnum\" 1, \"calt\" 1',\n /** Enable case-sensitive forms */\n case: '\"case\" 1',\n /** Enable stylistic set 01 (alternate digits) */\n ss01: '\"ss01\" 1',\n /** Enable stylistic set 02 (alternate a) */\n ss02: '\"ss02\" 1',\n} as const;\n\n// ============================================\n// License Information\n// ============================================\n\n/**\n * Get license information for all used fonts\n */\nexport function getFontLicenses(): Array<{\n family: string;\n license: string;\n url?: string | undefined;\n}> {\n return Object.values(fonts).map((font) => ({\n family: font.family,\n license: font.license,\n url: font.licenseUrl,\n }));\n}\n\n/**\n * Font license compliance notice\n */\nexport const fontLicenseNotice = `\nFonts used in this project are licensed under open-source licenses:\n\n- Inter: SIL Open Font License 1.1\n- Public Sans: SIL Open Font License 1.1\n- JetBrains Mono: SIL Open Font License 1.1\n- Noto Sans SC (Source Han Sans): SIL Open Font License 1.1\n\nAll fonts are free for commercial use. See individual license files for details.\n`.trim();\n","/**\n * Typography Tokens\n *\n * Centralized typography configuration for the entire design system.\n * All font-related values should come from here.\n */\n\n// ============================================\n// Font Families\n// ============================================\n\n/**\n * Primary font stack - Used for body text and UI\n *\n * Poppins is the primary font for English text. vivo Sans is for Chinese.\n * Falls back through system fonts for maximum compatibility.\n */\nexport const FONT_FAMILY_PRIMARY =\n '\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif';\n\n/**\n * Heading font stack - Used for titles and emphasis\n *\n * Geist Sans is the primary display typeface.\n */\nexport const FONT_FAMILY_HEADING =\n '\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif';\n\n/**\n * Monospace font stack - Used for code and technical content\n */\nexport const FONT_FAMILY_MONO =\n '\"JetBrains Mono\", \"Fira Code\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace';\n\n/**\n * CJK (Chinese/Japanese/Korean) fallback stack\n *\n * vivo Sans is the primary Chinese font.\n * Provides consistent rendering for Chinese, Japanese, and Korean text.\n */\nexport const FONT_FAMILY_CJK =\n '\"vivo Sans\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK SC\", \"Noto Sans SC\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif';\n\n/**\n * Complete font stacks with CJK fallback\n */\nexport const fontFamilies = {\n /** Primary UI and body text */\n primary: FONT_FAMILY_PRIMARY,\n\n /** Headings and titles */\n heading: FONT_FAMILY_HEADING,\n\n /** Code and monospace */\n mono: FONT_FAMILY_MONO,\n\n /** CJK-specific fallback */\n cjk: FONT_FAMILY_CJK,\n\n /** Primary with CJK fallback for multilingual content */\n primaryCJK: `${FONT_FAMILY_PRIMARY}, ${FONT_FAMILY_CJK}`,\n\n /** System font stack (fast fallback, no web fonts) */\n system: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif',\n} as const;\n\n// ============================================\n// Type Scale\n// ============================================\n\n/**\n * Font size scale using rem units for accessibility\n *\n * Base: 16px = 1rem\n * Each step follows a modular scale (~1.25 ratio)\n */\nexport const fontSizes = {\n /** 12px - Micro text, badges */\n xs: \"0.75rem\",\n\n /** 14px - Small text, captions, labels */\n sm: \"0.875rem\",\n\n /** 16px - Base body text */\n base: \"1rem\",\n\n /** 18px - Lead text, larger body */\n lg: \"1.125rem\",\n\n /** 20px - Small headings, subtitles */\n xl: \"1.25rem\",\n\n /** 24px - H4 equivalent */\n \"2xl\": \"1.5rem\",\n\n /** 30px - H3 equivalent */\n \"3xl\": \"1.875rem\",\n\n /** 36px - H2 equivalent */\n \"4xl\": \"2.25rem\",\n\n /** 48px - H1 equivalent */\n \"5xl\": \"3rem\",\n\n /** 60px - Display/Hero text */\n \"6xl\": \"3.75rem\",\n\n /** 72px - Large display */\n \"7xl\": \"4.5rem\",\n\n /** 96px - Extra large display */\n \"8xl\": \"6rem\",\n} as const;\n\n/**\n * Font size in pixels (for cases where rem isn't suitable)\n */\nexport const fontSizesPx = {\n xs: 12,\n sm: 14,\n base: 16,\n lg: 18,\n xl: 20,\n \"2xl\": 24,\n \"3xl\": 30,\n \"4xl\": 36,\n \"5xl\": 48,\n \"6xl\": 60,\n \"7xl\": 72,\n \"8xl\": 96,\n} as const;\n\n// ============================================\n// Line Heights\n// ============================================\n\n/**\n * Line height scale\n *\n * Using unitless values for better inheritance.\n */\nexport const lineHeights = {\n /** 1 - Single line, icons */\n none: 1,\n\n /** 1.25 - Tight, for large headings */\n tight: 1.25,\n\n /** 1.375 - Slightly snug */\n snug: 1.375,\n\n /** 1.5 - Normal body text */\n normal: 1.5,\n\n /** 1.625 - Relaxed reading */\n relaxed: 1.625,\n\n /** 1.75 - Loose, for small text */\n loose: 1.75,\n\n /** 2 - Double spaced */\n double: 2,\n} as const;\n\n// ============================================\n// Font Weights\n// ============================================\n\n/**\n * Font weight scale\n *\n * Inter and Public Sans support all these weights.\n * Variable fonts can use any value 100-900.\n */\nexport const fontWeights = {\n /** 100 - Thin (if available) */\n thin: 100,\n\n /** 200 - Extra light */\n extralight: 200,\n\n /** 300 - Light */\n light: 300,\n\n /** 400 - Regular/Normal */\n normal: 400,\n\n /** 500 - Medium */\n medium: 500,\n\n /** 600 - Semibold */\n semibold: 600,\n\n /** 700 - Bold */\n bold: 700,\n\n /** 800 - Extra bold */\n extrabold: 800,\n\n /** 900 - Black */\n black: 900,\n} as const;\n\n// ============================================\n// Letter Spacing (Tracking)\n// ============================================\n\n/**\n * Letter spacing scale\n *\n * Negative values for tight headlines, positive for small caps.\n */\nexport const letterSpacing = {\n /** -0.05em - Very tight, large display only */\n tighter: \"-0.05em\",\n\n /** -0.025em - Slightly tight, headings */\n tight: \"-0.025em\",\n\n /** 0 - Normal */\n normal: \"0\",\n\n /** 0.025em - Slightly wide */\n wide: \"0.025em\",\n\n /** 0.05em - Wide, for small caps */\n wider: \"0.05em\",\n\n /** 0.1em - Very wide, all caps */\n widest: \"0.1em\",\n} as const;\n\n// ============================================\n// Combined Type Styles\n// ============================================\n\n/**\n * Pre-defined typography presets\n *\n * These combine font-family, size, weight, and line-height\n * for common use cases.\n */\nexport const typeStyles = {\n /** Hero/Display - Large marketing headlines */\n display: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"6xl\"],\n fontWeight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n },\n\n /** H1 - Page titles */\n h1: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"5xl\"],\n fontWeight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n },\n\n /** H2 - Section titles */\n h2: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"4xl\"],\n fontWeight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n },\n\n /** H3 - Subsection titles */\n h3: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"3xl\"],\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.snug,\n letterSpacing: letterSpacing.normal,\n },\n\n /** H4 - Card titles, small sections */\n h4: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"2xl\"],\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.snug,\n letterSpacing: letterSpacing.normal,\n },\n\n /** H5 - Widget titles */\n h5: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes.xl,\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** H6 - Smallest heading */\n h6: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes.lg,\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Body - Default paragraph text */\n body: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.base,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Body Large - Lead paragraphs */\n bodyLarge: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.lg,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.relaxed,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Body Small - Secondary text */\n bodySmall: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Caption - Image captions, timestamps */\n caption: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.xs,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.wide,\n },\n\n /** Label - Form labels, UI labels */\n label: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.medium,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Button - Button text */\n button: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.medium,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.wide,\n },\n\n /** Code - Inline code */\n code: {\n fontFamily: fontFamilies.mono,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Code Block - Code blocks */\n codeBlock: {\n fontFamily: fontFamilies.mono,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.relaxed,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Overline - Small caps labels */\n overline: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.xs,\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.widest,\n textTransform: \"uppercase\" as const,\n },\n} as const;\n\nexport type TypeStyle = keyof typeof typeStyles;\n\n// ============================================\n// Responsive Typography\n// ============================================\n\n/**\n * Fluid typography clamp values\n *\n * Format: clamp(min, preferred, max)\n * Uses viewport width for smooth scaling.\n */\nexport const fluidFontSizes = {\n /** Display: 36px to 72px */\n display: \"clamp(2.25rem, 5vw + 1rem, 4.5rem)\",\n\n /** H1: 30px to 48px */\n h1: \"clamp(1.875rem, 4vw + 0.5rem, 3rem)\",\n\n /** H2: 24px to 36px */\n h2: \"clamp(1.5rem, 3vw + 0.5rem, 2.25rem)\",\n\n /** H3: 20px to 30px */\n h3: \"clamp(1.25rem, 2vw + 0.5rem, 1.875rem)\",\n\n /** Body: 14px to 18px */\n body: \"clamp(0.875rem, 1vw + 0.5rem, 1.125rem)\",\n} as const;\n\n// ============================================\n// Type Exports\n// ============================================\n\nexport type FontFamily = keyof typeof fontFamilies;\nexport type FontSize = keyof typeof fontSizes;\nexport type LineHeight = keyof typeof lineHeights;\nexport type FontWeight = keyof typeof fontWeights;\nexport type LetterSpacing = keyof typeof letterSpacing;\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ClassValue } from 'clsx';
|
|
2
|
+
|
|
3
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Brand Color Utilities
|
|
7
|
+
*
|
|
8
|
+
* Resolves Nebutra brand CSS variables at runtime for components that
|
|
9
|
+
* require raw hex values (e.g. WebGL shaders, Canvas APIs, animation libraries
|
|
10
|
+
* that can't consume `var(--token)` strings directly).
|
|
11
|
+
*
|
|
12
|
+
* Components that accept CSS color strings (inline styles, gradients, SVG)
|
|
13
|
+
* should prefer `var(--brand-primary)` / `var(--brand-accent)` directly
|
|
14
|
+
* instead of calling these helpers.
|
|
15
|
+
*/
|
|
16
|
+
/** SSR / no-DOM fallbacks — only used when `window` is unavailable. */
|
|
17
|
+
declare const BRAND_FALLBACK: {
|
|
18
|
+
readonly primary: "#0033FE";
|
|
19
|
+
readonly accent: "#0BF1C3";
|
|
20
|
+
readonly tertiary: "#5c7cfa";
|
|
21
|
+
readonly primaryDark: "#002ad4";
|
|
22
|
+
readonly backDark: "#000830";
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Read a CSS variable from :root and return its trimmed value.
|
|
26
|
+
* Falls back to `fallback` in SSR/no-DOM environments or when the var
|
|
27
|
+
* is unresolved (empty string).
|
|
28
|
+
*/
|
|
29
|
+
declare function readCssVar(name: string, fallback: string): string;
|
|
30
|
+
/** Resolve `--brand-primary` to a hex/color string (with SSR fallback). */
|
|
31
|
+
declare function getBrandPrimary(): string;
|
|
32
|
+
/** Resolve `--brand-accent` to a hex/color string (with SSR fallback). */
|
|
33
|
+
declare function getBrandAccent(): string;
|
|
34
|
+
/** Resolve `--brand-tertiary` to a hex/color string (with SSR fallback). */
|
|
35
|
+
declare function getBrandTertiary(): string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Utility Functions
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* Merge class names — canonical implementation from ./cn.ts
|
|
42
|
+
* Uses twMerge(clsx(...)) to correctly resolve Tailwind class conflicts.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Breakpoint values (matches Primer)
|
|
47
|
+
*/
|
|
48
|
+
declare const BREAKPOINTS: {
|
|
49
|
+
readonly xs: 0;
|
|
50
|
+
readonly sm: 544;
|
|
51
|
+
readonly md: 768;
|
|
52
|
+
readonly lg: 1012;
|
|
53
|
+
readonly xl: 1280;
|
|
54
|
+
};
|
|
55
|
+
type Breakpoint = keyof typeof BREAKPOINTS;
|
|
56
|
+
/**
|
|
57
|
+
* Check if viewport is at or above breakpoint
|
|
58
|
+
*/
|
|
59
|
+
declare function isBreakpointUp(breakpoint: Breakpoint): boolean;
|
|
60
|
+
|
|
61
|
+
export { BRAND_FALLBACK, BREAKPOINTS, type Breakpoint, cn, getBrandAccent, getBrandPrimary, getBrandTertiary, isBreakpointUp, readCssVar };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
|
|
5
|
+
// src/utils/cn.ts
|
|
6
|
+
function cn(...inputs) {
|
|
7
|
+
return twMerge(clsx(inputs));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// src/utils/brand-colors.ts
|
|
11
|
+
var BRAND_FALLBACK = {
|
|
12
|
+
primary: "#0033FE",
|
|
13
|
+
// nebutra-blue-500
|
|
14
|
+
accent: "#0BF1C3",
|
|
15
|
+
// nebutra-cyan-500
|
|
16
|
+
tertiary: "#5c7cfa",
|
|
17
|
+
// nebutra-blue-400
|
|
18
|
+
primaryDark: "#002ad4",
|
|
19
|
+
// nebutra-blue-600
|
|
20
|
+
backDark: "#000830"
|
|
21
|
+
// nebutra-blue-950
|
|
22
|
+
};
|
|
23
|
+
function readCssVar(name, fallback) {
|
|
24
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
25
|
+
return fallback;
|
|
26
|
+
}
|
|
27
|
+
const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
28
|
+
return value || fallback;
|
|
29
|
+
}
|
|
30
|
+
function getBrandPrimary() {
|
|
31
|
+
return readCssVar("--brand-primary", BRAND_FALLBACK.primary);
|
|
32
|
+
}
|
|
33
|
+
function getBrandAccent() {
|
|
34
|
+
return readCssVar("--brand-accent", BRAND_FALLBACK.accent);
|
|
35
|
+
}
|
|
36
|
+
function getBrandTertiary() {
|
|
37
|
+
return readCssVar("--brand-tertiary", BRAND_FALLBACK.tertiary);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/utils/index.ts
|
|
41
|
+
var BREAKPOINTS = {
|
|
42
|
+
xs: 0,
|
|
43
|
+
sm: 544,
|
|
44
|
+
md: 768,
|
|
45
|
+
lg: 1012,
|
|
46
|
+
xl: 1280
|
|
47
|
+
};
|
|
48
|
+
function isBreakpointUp(breakpoint) {
|
|
49
|
+
if (typeof window === "undefined") return true;
|
|
50
|
+
return window.innerWidth >= BREAKPOINTS[breakpoint];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { BRAND_FALLBACK, BREAKPOINTS, cn, getBrandAccent, getBrandPrimary, getBrandTertiary, isBreakpointUp, readCssVar };
|
|
54
|
+
//# sourceMappingURL=index.js.map
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cn.ts","../../src/utils/brand-colors.ts","../../src/utils/index.ts"],"names":[],"mappings":";;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;;;ACQO,IAAM,cAAA,GAAiB;AAAA,EAC5B,OAAA,EAAS,SAAA;AAAA;AAAA,EACT,MAAA,EAAQ,SAAA;AAAA;AAAA,EACR,QAAA,EAAU,SAAA;AAAA;AAAA,EACV,WAAA,EAAa,SAAA;AAAA;AAAA,EACb,QAAA,EAAU;AAAA;AACZ;AAOO,SAAS,UAAA,CAAW,MAAc,QAAA,EAA0B;AACjE,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,aAAa,WAAA,EAAa;AACpE,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,MAAM,KAAA,GAAQ,iBAAiB,QAAA,CAAS,eAAe,EAAE,gBAAA,CAAiB,IAAI,EAAE,IAAA,EAAK;AACrF,EAAA,OAAO,KAAA,IAAS,QAAA;AAClB;AAGO,SAAS,eAAA,GAA0B;AACxC,EAAA,OAAO,UAAA,CAAW,iBAAA,EAAmB,cAAA,CAAe,OAAO,CAAA;AAC7D;AAGO,SAAS,cAAA,GAAyB;AACvC,EAAA,OAAO,UAAA,CAAW,gBAAA,EAAkB,cAAA,CAAe,MAAM,CAAA;AAC3D;AAGO,SAAS,gBAAA,GAA2B;AACzC,EAAA,OAAO,UAAA,CAAW,kBAAA,EAAoB,cAAA,CAAe,QAAQ,CAAA;AAC/D;;;AClCO,IAAM,WAAA,GAAc;AAAA,EACzB,EAAA,EAAI,CAAA;AAAA,EACJ,EAAA,EAAI,GAAA;AAAA,EACJ,EAAA,EAAI,GAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI;AACN;AAOO,SAAS,eAAe,UAAA,EAAiC;AAC9D,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,IAAA;AAC1C,EAAA,OAAO,MAAA,CAAO,UAAA,IAAc,WAAA,CAAY,UAAU,CAAA;AACpD","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","/**\n * Brand Color Utilities\n *\n * Resolves Nebutra brand CSS variables at runtime for components that\n * require raw hex values (e.g. WebGL shaders, Canvas APIs, animation libraries\n * that can't consume `var(--token)` strings directly).\n *\n * Components that accept CSS color strings (inline styles, gradients, SVG)\n * should prefer `var(--brand-primary)` / `var(--brand-accent)` directly\n * instead of calling these helpers.\n */\n\n/** SSR / no-DOM fallbacks — only used when `window` is unavailable. */\nexport const BRAND_FALLBACK = {\n primary: \"#0033FE\", // nebutra-blue-500\n accent: \"#0BF1C3\", // nebutra-cyan-500\n tertiary: \"#5c7cfa\", // nebutra-blue-400\n primaryDark: \"#002ad4\", // nebutra-blue-600\n backDark: \"#000830\", // nebutra-blue-950\n} as const;\n\n/**\n * Read a CSS variable from :root and return its trimmed value.\n * Falls back to `fallback` in SSR/no-DOM environments or when the var\n * is unresolved (empty string).\n */\nexport function readCssVar(name: string, fallback: string): string {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return fallback;\n }\n const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();\n return value || fallback;\n}\n\n/** Resolve `--brand-primary` to a hex/color string (with SSR fallback). */\nexport function getBrandPrimary(): string {\n return readCssVar(\"--brand-primary\", BRAND_FALLBACK.primary);\n}\n\n/** Resolve `--brand-accent` to a hex/color string (with SSR fallback). */\nexport function getBrandAccent(): string {\n return readCssVar(\"--brand-accent\", BRAND_FALLBACK.accent);\n}\n\n/** Resolve `--brand-tertiary` to a hex/color string (with SSR fallback). */\nexport function getBrandTertiary(): string {\n return readCssVar(\"--brand-tertiary\", BRAND_FALLBACK.tertiary);\n}\n","/**\n * Utility Functions\n */\n\n/**\n * Merge class names — canonical implementation from ./cn.ts\n * Uses twMerge(clsx(...)) to correctly resolve Tailwind class conflicts.\n */\nexport { cn } from \"./cn\";\n\n/**\n * Breakpoint values (matches Primer)\n */\nexport const BREAKPOINTS = {\n xs: 0,\n sm: 544,\n md: 768,\n lg: 1012,\n xl: 1280,\n} as const;\n\nexport type Breakpoint = keyof typeof BREAKPOINTS;\n\n/**\n * Check if viewport is at or above breakpoint\n */\nexport function isBreakpointUp(breakpoint: Breakpoint): boolean {\n if (typeof window === \"undefined\") return true;\n return window.innerWidth >= BREAKPOINTS[breakpoint];\n}\n\nexport {\n BRAND_FALLBACK,\n getBrandAccent,\n getBrandPrimary,\n getBrandTertiary,\n readCssVar,\n} from \"./brand-colors\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebutra/ui",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Unified UI component library — Lobe UI + Radix + HeroUI + layout components",
|
|
5
5
|
"private": false,
|
|
6
|
-
"license": "
|
|
6
|
+
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"exports": {
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"@lobehub/fluent-emoji": "^4.1.0",
|
|
69
69
|
"@lobehub/icons": "^5.0.1",
|
|
70
70
|
"@lobehub/ui": "^5.4.0",
|
|
71
|
+
"@xyflow/react": "^12.10.2",
|
|
71
72
|
"@number-flow/react": "^0.5.5",
|
|
72
73
|
"@paper-design/shaders-react": "^0.0.71",
|
|
73
74
|
"@phosphor-icons/react": "^2.1.10",
|
|
@@ -90,8 +91,10 @@
|
|
|
90
91
|
"react-ascii-text": "*",
|
|
91
92
|
"react-dom": "^19.2.4",
|
|
92
93
|
"react-hook-form": "^7.71.2",
|
|
94
|
+
"react-markdown": "^10.1.0",
|
|
93
95
|
"react-resizable-panels": "^4.7.1",
|
|
94
96
|
"react-syntax-highlighter": "^16.1.1",
|
|
97
|
+
"remark-gfm": "^4.0.1",
|
|
95
98
|
"react-tweet": "^3.3.0",
|
|
96
99
|
"react-use-measure": "^2.1.7",
|
|
97
100
|
"recharts": "^3.7.0",
|
|
@@ -101,14 +104,16 @@
|
|
|
101
104
|
"tailwind-merge": "^3.5.0",
|
|
102
105
|
"usehooks-ts": "^3.1.1",
|
|
103
106
|
"vaul": "^1.1.2",
|
|
104
|
-
"@nebutra/brand": "0.1.
|
|
105
|
-
"@nebutra/
|
|
107
|
+
"@nebutra/brand": "0.1.1",
|
|
108
|
+
"@nebutra/graph-model": "0.2.1",
|
|
109
|
+
"@nebutra/icons": "0.1.1",
|
|
110
|
+
"@nebutra/tokens": "0.1.1"
|
|
106
111
|
},
|
|
107
112
|
"peerDependencies": {
|
|
108
113
|
"@clerk/nextjs": ">=5.0.0",
|
|
109
114
|
"next": ">=14.0.0",
|
|
110
|
-
"react": "
|
|
111
|
-
"react-dom": "
|
|
115
|
+
"react": ">=19.0.0",
|
|
116
|
+
"react-dom": ">=19.0.0"
|
|
112
117
|
},
|
|
113
118
|
"peerDependenciesMeta": {
|
|
114
119
|
"@clerk/nextjs": {
|
|
@@ -120,6 +125,8 @@
|
|
|
120
125
|
},
|
|
121
126
|
"devDependencies": {
|
|
122
127
|
"@storybook/test": "^8.6.17",
|
|
128
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
129
|
+
"@testing-library/react": "^16.3.2",
|
|
123
130
|
"@types/canvas-confetti": "^1.9.0",
|
|
124
131
|
"@types/node": "^22.19.15",
|
|
125
132
|
"@types/react": "^19.2.14",
|
|
@@ -127,10 +134,12 @@
|
|
|
127
134
|
"@types/three": "^0.183.1",
|
|
128
135
|
"next": "^16.2.6",
|
|
129
136
|
"storybook": "^8.6.17",
|
|
137
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
130
138
|
"tsup": "^8.5.1",
|
|
131
139
|
"tsx": "^4.21.0",
|
|
132
140
|
"typescript": "^5.9.3",
|
|
133
|
-
"
|
|
141
|
+
"vitest": "^4.0.18",
|
|
142
|
+
"@nebutra/design-tokens": "0.1.1"
|
|
134
143
|
},
|
|
135
144
|
"homepage": "https://github.com/Nebutra/Nebutra-Sailor/tree/main/packages/design/ui#readme",
|
|
136
145
|
"repository": {
|
|
@@ -149,9 +158,10 @@
|
|
|
149
158
|
"three": "^0.183.2"
|
|
150
159
|
},
|
|
151
160
|
"scripts": {
|
|
161
|
+
"test": "vitest run",
|
|
152
162
|
"typecheck": "tsc --noEmit",
|
|
153
163
|
"build:registry": "tsx scripts/build-registry.ts",
|
|
154
|
-
"build": "tsup && tsx scripts/build-registry.ts",
|
|
164
|
+
"build": "NODE_OPTIONS='--max-old-space-size=6144' tsup && tsx scripts/build-registry.ts",
|
|
155
165
|
"dev": "tsup --watch"
|
|
156
166
|
}
|
|
157
167
|
}
|