@flightdev/fonts 0.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Flight Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # @flight-framework/fonts
2
+
3
+ Font loading and optimization package.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @flight-framework/fonts
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { createFontLoader } from '@flight-framework/fonts';
15
+ import { googleFonts } from '@flight-framework/fonts/google';
16
+
17
+ const fonts = createFontLoader({
18
+ adapter: googleFonts(),
19
+ });
20
+
21
+ const inter = await fonts.load('Inter', {
22
+ weight: ['400', '600', '700'],
23
+ subsets: ['latin'],
24
+ display: 'swap',
25
+ });
26
+
27
+ // Use in HTML
28
+ document.documentElement.className = inter.className;
29
+ ```
30
+
31
+ ## Adapters
32
+
33
+ ### Google Fonts
34
+
35
+ ```typescript
36
+ import { googleFonts } from '@flight-framework/fonts/google';
37
+
38
+ fonts.load('Roboto', {
39
+ weight: ['400', '700'],
40
+ subsets: ['latin', 'cyrillic'],
41
+ });
42
+ ```
43
+
44
+ ### Local Fonts
45
+
46
+ ```typescript
47
+ import { localFonts } from '@flight-framework/fonts/local';
48
+
49
+ const myFont = await fonts.loadLocal('MyFont', {
50
+ src: [
51
+ { path: '/fonts/MyFont-Regular.woff2', weight: '400' },
52
+ { path: '/fonts/MyFont-Bold.woff2', weight: '700' },
53
+ ],
54
+ display: 'swap',
55
+ });
56
+ ```
57
+
58
+ ## React Components
59
+
60
+ ```tsx
61
+ import { FontHead } from '@flight-framework/fonts/react';
62
+
63
+ function Layout({ children }) {
64
+ return (
65
+ <html className={inter.className}>
66
+ <head>
67
+ <FontHead fonts={[inter]} />
68
+ </head>
69
+ <body>{children}</body>
70
+ </html>
71
+ );
72
+ }
73
+ ```
74
+
75
+ ## Options
76
+
77
+ | Option | Type | Default | Description |
78
+ |--------|------|---------|-------------|
79
+ | `weight` | `string \| string[]` | `'400'` | Font weights |
80
+ | `subsets` | `string[]` | `['latin']` | Character subsets |
81
+ | `display` | `string` | `'swap'` | font-display value |
82
+ | `preload` | `boolean` | `true` | Preload font files |
83
+ | `fallback` | `string[]` | `['system-ui']` | Fallback fonts |
84
+
85
+ ## Build-Time Optimization (Vite Plugin)
86
+
87
+ For optimal performance, use the Vite plugin to automatically optimize fonts during build:
88
+
89
+ ```typescript
90
+ // vite.config.ts
91
+ import { fontOptimization } from '@flight-framework/fonts/vite';
92
+
93
+ export default defineConfig({
94
+ plugins: [
95
+ fontOptimization({
96
+ // Strategy for subsetting
97
+ strategy: 'named-subsets', // 'used-chars' | 'named-subsets' | 'none'
98
+
99
+ // Subsets to include (when strategy is 'named-subsets')
100
+ subsets: ['latin', 'latin-ext'],
101
+
102
+ // Self-host fonts instead of CDN
103
+ selfHost: true,
104
+
105
+ // Directories to scan for used characters
106
+ scanDirs: ['src'],
107
+ }),
108
+ ],
109
+ });
110
+ ```
111
+
112
+ ### Strategies
113
+
114
+ | Strategy | Description | Use Case |
115
+ |----------|-------------|----------|
116
+ | `used-chars` | Scan source files for characters actually used | Smallest fonts, longer build |
117
+ | `named-subsets` | Use predefined unicode ranges | Balanced (recommended) |
118
+ | `none` | No subsetting | Fastest build |
119
+
120
+ ## Subset Utilities
121
+
122
+ For manual font optimization:
123
+
124
+ ```typescript
125
+ import {
126
+ UNICODE_RANGES,
127
+ extractCharsFromText,
128
+ codePointsToUnicodeRange,
129
+ detectRequiredSubsets,
130
+ generateFontFaceCSS,
131
+ } from '@flight-framework/fonts/subset';
132
+
133
+ // Get predefined ranges
134
+ const latinRange = UNICODE_RANGES.latin;
135
+
136
+ // Extract characters from your content
137
+ const chars = extractCharsFromText('Hello World!');
138
+
139
+ // Detect which subsets are needed
140
+ const neededSubsets = detectRequiredSubsets(chars);
141
+ // ['latin']
142
+
143
+ // Generate CSS
144
+ const css = generateFontFaceCSS('Inter', '/fonts/inter.woff2', {
145
+ weight: '400',
146
+ unicodeRange: latinRange.range,
147
+ });
148
+ ```
149
+
150
+ ### Available Subsets
151
+
152
+ - `latin`, `latin-ext`
153
+ - `cyrillic`, `cyrillic-ext`
154
+ - `greek`, `greek-ext`
155
+ - `vietnamese`
156
+ - `arabic`, `hebrew`, `devanagari`, `thai`
157
+ - `japanese`, `korean`, `chinese-simplified`
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @flightdev/fonts/google - Google Fonts Adapter
3
+ *
4
+ * Self-hosting Google Fonts for privacy and performance.
5
+ * Downloads fonts at build time and serves them from your domain.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { createFontLoader } from '@flightdev/fonts';
10
+ * import { googleFontsAdapter } from '@flightdev/fonts/google';
11
+ *
12
+ * const fonts = createFontLoader({ adapter: googleFontsAdapter() });
13
+ * const inter = await fonts.load('Inter', { weight: '400' });
14
+ * ```
15
+ */
16
+ import { type FontAdapter } from '../index.js';
17
+ export interface GoogleFontsAdapterOptions {
18
+ /** Cache directory for downloaded fonts (default: '.cache/fonts') */
19
+ cacheDir?: string;
20
+ /** Base URL for serving fonts (default: '/_fonts') */
21
+ baseUrl?: string;
22
+ /** User agent for fetching fonts (affects format) */
23
+ userAgent?: 'woff2' | 'woff' | 'auto';
24
+ }
25
+ /**
26
+ * Create a Google Fonts adapter
27
+ *
28
+ * This adapter generates CSS that points to Google Fonts CDN.
29
+ * For production, consider using a build plugin to self-host the fonts.
30
+ */
31
+ export declare function googleFontsAdapter(config?: GoogleFontsAdapterOptions): FontAdapter;
32
+ export default googleFontsAdapter;
33
+ //# sourceMappingURL=google.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/adapters/google.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACH,KAAK,WAAW,EASnB,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,yBAAyB;IACtC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACzC;AAaD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,yBAA8B,GAAG,WAAW,CA0GtF;AAED,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * @flightdev/fonts/google - Google Fonts Adapter
3
+ *
4
+ * Self-hosting Google Fonts for privacy and performance.
5
+ * Downloads fonts at build time and serves them from your domain.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { createFontLoader } from '@flightdev/fonts';
10
+ * import { googleFontsAdapter } from '@flightdev/fonts/google';
11
+ *
12
+ * const fonts = createFontLoader({ adapter: googleFontsAdapter() });
13
+ * const inter = await fonts.load('Inter', { weight: '400' });
14
+ * ```
15
+ */
16
+ import { generateFontClassName, fontWeightToNumber, formatFallbackStack, } from '../index.js';
17
+ // ============================================================================
18
+ // Google Fonts Adapter
19
+ // ============================================================================
20
+ /**
21
+ * Create a Google Fonts adapter
22
+ *
23
+ * This adapter generates CSS that points to Google Fonts CDN.
24
+ * For production, consider using a build plugin to self-host the fonts.
25
+ */
26
+ export function googleFontsAdapter(config = {}) {
27
+ const { baseUrl = '/_fonts', userAgent = 'woff2', } = config;
28
+ const loadedFonts = [];
29
+ function buildGoogleFontsUrl(family, weights, subsets) {
30
+ const weightParams = weights
31
+ .map(w => w === 'variable' ? 'wght@100..900' : `wght@${fontWeightToNumber(w)}`)
32
+ .join(';');
33
+ const encodedFamily = family.replace(/ /g, '+');
34
+ const url = new URL('https://fonts.googleapis.com/css2');
35
+ url.searchParams.set('family', `${encodedFamily}:${weightParams || 'wght@400'}`);
36
+ url.searchParams.set('display', 'swap');
37
+ if (subsets.length > 0) {
38
+ url.searchParams.set('subset', subsets.join(','));
39
+ }
40
+ return url.toString();
41
+ }
42
+ function generateCSS(family, googleUrl, display, variable) {
43
+ const className = generateFontClassName(family);
44
+ let css = `/* ${family} from Google Fonts */\n`;
45
+ css += `@import url('${googleUrl}');\n\n`;
46
+ css += `.${className} {\n`;
47
+ css += ` font-family: '${family}', system-ui, sans-serif;\n`;
48
+ css += `}\n`;
49
+ if (variable) {
50
+ css += `\n:root {\n`;
51
+ css += ` ${variable}: '${family}', system-ui, sans-serif;\n`;
52
+ css += `}\n`;
53
+ }
54
+ return css;
55
+ }
56
+ return {
57
+ name: 'google-fonts',
58
+ async load(fontFamily, options = {}) {
59
+ const { weight = '400', subsets = ['latin'], display = 'swap', fallback = ['system-ui', 'sans-serif'], variable, preload = true, } = options;
60
+ const weights = Array.isArray(weight) ? weight : [weight];
61
+ const googleUrl = buildGoogleFontsUrl(fontFamily, weights, subsets);
62
+ const className = generateFontClassName(fontFamily);
63
+ const css = generateCSS(fontFamily, googleUrl, display, variable);
64
+ const fontStack = `'${fontFamily}', ${formatFallbackStack(fallback)}`;
65
+ const result = {
66
+ className,
67
+ style: {
68
+ fontFamily: fontStack,
69
+ fontWeight: fontWeightToNumber(weights[0]),
70
+ },
71
+ variable,
72
+ cssUrl: googleUrl,
73
+ };
74
+ if (preload) {
75
+ result.preloadData = [{
76
+ href: googleUrl,
77
+ as: 'font',
78
+ type: 'text/css',
79
+ crossOrigin: 'anonymous',
80
+ }];
81
+ }
82
+ loadedFonts.push({ family: fontFamily, options, result, css });
83
+ return result;
84
+ },
85
+ getCSS() {
86
+ return loadedFonts.map(f => f.css).join('\n');
87
+ },
88
+ getPreloadLinks() {
89
+ return loadedFonts
90
+ .filter(f => f.result.preloadData)
91
+ .flatMap(f => f.result.preloadData || []);
92
+ },
93
+ };
94
+ }
95
+ export default googleFontsAdapter;
96
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/adapters/google.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @flightdev/fonts/local - Local Fonts Adapter
3
+ *
4
+ * Load fonts from local files with automatic @font-face generation.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createFontLoader } from '@flightdev/fonts';
9
+ * import { localFontsAdapter } from '@flightdev/fonts/local';
10
+ *
11
+ * const fonts = createFontLoader({ adapter: localFontsAdapter() });
12
+ * const myFont = await fonts.loadLocal('MyFont', {
13
+ * src: '/fonts/MyFont.woff2',
14
+ * weight: '400',
15
+ * });
16
+ * ```
17
+ */
18
+ import { type FontAdapter } from '../index.js';
19
+ export interface LocalFontsAdapterOptions {
20
+ /** Base path for font files */
21
+ basePath?: string;
22
+ }
23
+ /**
24
+ * Create a local fonts adapter
25
+ */
26
+ export declare function localFontsAdapter(config?: LocalFontsAdapterOptions): FontAdapter;
27
+ export default localFontsAdapter;
28
+ //# sourceMappingURL=local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/adapters/local.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACH,KAAK,WAAW,EAQnB,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,wBAAwB;IACrC,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAsBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,wBAA6B,GAAG,WAAW,CA0HpF;AAED,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * @flightdev/fonts/local - Local Fonts Adapter
3
+ *
4
+ * Load fonts from local files with automatic @font-face generation.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createFontLoader } from '@flightdev/fonts';
9
+ * import { localFontsAdapter } from '@flightdev/fonts/local';
10
+ *
11
+ * const fonts = createFontLoader({ adapter: localFontsAdapter() });
12
+ * const myFont = await fonts.loadLocal('MyFont', {
13
+ * src: '/fonts/MyFont.woff2',
14
+ * weight: '400',
15
+ * });
16
+ * ```
17
+ */
18
+ import { generateFontClassName, fontWeightToNumber, formatFallbackStack, } from '../index.js';
19
+ // ============================================================================
20
+ // Local Fonts Adapter
21
+ // ============================================================================
22
+ function detectFontFormat(path) {
23
+ if (path.endsWith('.woff2'))
24
+ return 'woff2';
25
+ if (path.endsWith('.woff'))
26
+ return 'woff';
27
+ if (path.endsWith('.ttf'))
28
+ return 'truetype';
29
+ if (path.endsWith('.otf'))
30
+ return 'opentype';
31
+ if (path.endsWith('.eot'))
32
+ return 'embedded-opentype';
33
+ return 'woff2';
34
+ }
35
+ /**
36
+ * Create a local fonts adapter
37
+ */
38
+ export function localFontsAdapter(config = {}) {
39
+ const { basePath = '' } = config;
40
+ const loadedFonts = [];
41
+ function generateFontFaceCSS(family, definition) {
42
+ const { src, display = 'swap', weight = '400', style = 'normal' } = definition;
43
+ let css = '';
44
+ if (typeof src === 'string') {
45
+ // Single font file
46
+ const format = detectFontFormat(src);
47
+ const fullPath = basePath + src;
48
+ css += `@font-face {\n`;
49
+ css += ` font-family: '${family}';\n`;
50
+ css += ` src: url('${fullPath}') format('${format}');\n`;
51
+ css += ` font-weight: ${fontWeightToNumber(weight)};\n`;
52
+ css += ` font-style: ${style};\n`;
53
+ css += ` font-display: ${display};\n`;
54
+ css += `}\n`;
55
+ }
56
+ else {
57
+ // Multiple font files for different weights
58
+ for (const variant of src) {
59
+ const format = detectFontFormat(variant.path);
60
+ const fullPath = basePath + variant.path;
61
+ const variantWeight = variant.weight || weight || '400';
62
+ const variantStyle = variant.style || style || 'normal';
63
+ css += `@font-face {\n`;
64
+ css += ` font-family: '${family}';\n`;
65
+ css += ` src: url('${fullPath}') format('${format}');\n`;
66
+ css += ` font-weight: ${fontWeightToNumber(variantWeight)};\n`;
67
+ css += ` font-style: ${variantStyle};\n`;
68
+ css += ` font-display: ${display};\n`;
69
+ css += `}\n\n`;
70
+ }
71
+ }
72
+ return css;
73
+ }
74
+ return {
75
+ name: 'local-fonts',
76
+ async load(fontFamily, options = {}) {
77
+ // For local adapter, load() expects the font to already be loaded via loadLocal()
78
+ // This is a fallback that creates an empty result
79
+ const className = generateFontClassName(fontFamily);
80
+ const fallback = options.fallback || ['system-ui', 'sans-serif'];
81
+ return {
82
+ className,
83
+ style: {
84
+ fontFamily: `'${fontFamily}', ${formatFallbackStack(fallback)}`,
85
+ },
86
+ variable: options.variable,
87
+ };
88
+ },
89
+ async loadLocal(fontFamily, definition) {
90
+ const className = generateFontClassName(fontFamily);
91
+ const css = generateFontFaceCSS(fontFamily, definition);
92
+ const fallback = definition.fallback || ['system-ui', 'sans-serif'];
93
+ const result = {
94
+ className,
95
+ style: {
96
+ fontFamily: `'${fontFamily}', ${formatFallbackStack(fallback)}`,
97
+ fontWeight: fontWeightToNumber(definition.weight || '400'),
98
+ fontStyle: definition.variable,
99
+ },
100
+ variable: definition.variable,
101
+ };
102
+ // Add preload data for the font files
103
+ if (definition.preload !== false) {
104
+ const src = definition.src;
105
+ if (typeof src === 'string') {
106
+ result.preloadData = [{
107
+ href: basePath + src,
108
+ as: 'font',
109
+ type: `font/${detectFontFormat(src)}`,
110
+ crossOrigin: 'anonymous',
111
+ }];
112
+ }
113
+ else {
114
+ result.preloadData = src.map((variant) => ({
115
+ href: basePath + variant.path,
116
+ as: 'font',
117
+ type: `font/${detectFontFormat(variant.path)}`,
118
+ crossOrigin: 'anonymous',
119
+ }));
120
+ }
121
+ }
122
+ // Add class CSS
123
+ const fullCss = css + `\n.${className} {\n font-family: '${fontFamily}', ${formatFallbackStack(fallback)};\n}\n`;
124
+ if (definition.variable) {
125
+ const varCss = `\n:root {\n ${definition.variable}: '${fontFamily}', ${formatFallbackStack(fallback)};\n}\n`;
126
+ loadedFonts.push({ family: fontFamily, definition, result, css: fullCss + varCss });
127
+ }
128
+ else {
129
+ loadedFonts.push({ family: fontFamily, definition, result, css: fullCss });
130
+ }
131
+ return result;
132
+ },
133
+ getCSS() {
134
+ return loadedFonts.map(f => f.css).join('\n');
135
+ },
136
+ getPreloadLinks() {
137
+ return loadedFonts
138
+ .filter(f => f.result.preloadData)
139
+ .flatMap(f => f.result.preloadData || []);
140
+ },
141
+ };
142
+ }
143
+ export default localFontsAdapter;
144
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/adapters/local.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @flightdev/fonts/components/react - React Font Components
3
+ *
4
+ * React components for font optimization with automatic preloading.
5
+ */
6
+ import React from 'react';
7
+ import type { FontResult } from '../index.js';
8
+ export interface FontHeadProps {
9
+ /** Font results to include in head */
10
+ fonts: FontResult[];
11
+ }
12
+ /**
13
+ * Inject font preload links and CSS into the document head.
14
+ * Use this in your root layout for optimal font loading.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * import { FontHead } from '@flightdev/fonts/components/react';
19
+ *
20
+ * function RootLayout({ children }) {
21
+ * return (
22
+ * <html>
23
+ * <head>
24
+ * <FontHead fonts={[inter, roboto]} />
25
+ * </head>
26
+ * <body>{children}</body>
27
+ * </html>
28
+ * );
29
+ * }
30
+ * ```
31
+ */
32
+ export declare function FontHead({ fonts }: FontHeadProps): React.ReactElement;
33
+ export interface FontStyleProps {
34
+ /** CSS content for fonts */
35
+ css: string;
36
+ }
37
+ /**
38
+ * Inject font CSS as an inline style tag.
39
+ * Use for local fonts or when you want to inline critical CSS.
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * import { FontStyle } from '@flightdev/fonts/components/react';
44
+ *
45
+ * function RootLayout({ children }) {
46
+ * const css = fontLoader.getCSS();
47
+ * return (
48
+ * <html>
49
+ * <head>
50
+ * <FontStyle css={css} />
51
+ * </head>
52
+ * <body>{children}</body>
53
+ * </html>
54
+ * );
55
+ * }
56
+ * ```
57
+ */
58
+ export declare function FontStyle({ css }: FontStyleProps): React.ReactElement;
59
+ export interface FontProviderProps {
60
+ /** Font results to apply */
61
+ fonts: FontResult[];
62
+ /** Children to wrap */
63
+ children: React.ReactNode;
64
+ /** Tag to use for wrapper (default: 'div') */
65
+ as?: 'div' | 'span' | 'section' | 'main' | 'article' | 'aside' | 'header' | 'footer' | 'nav';
66
+ }
67
+ /**
68
+ * Apply font classes to children.
69
+ * Wraps children in a container with font classes applied.
70
+ *
71
+ * @example
72
+ * ```tsx
73
+ * import { FontProvider } from '@flightdev/fonts/components/react';
74
+ *
75
+ * function App() {
76
+ * return (
77
+ * <FontProvider fonts={[inter]} as="main">
78
+ * <MyContent />
79
+ * </FontProvider>
80
+ * );
81
+ * }
82
+ * ```
83
+ */
84
+ export declare function FontProvider({ fonts, children, as: Tag }: FontProviderProps): React.ReactElement;
85
+ /**
86
+ * Get combined class names from font results.
87
+ *
88
+ * @example
89
+ * ```tsx
90
+ * import { useFontClass } from '@flightdev/fonts/components/react';
91
+ *
92
+ * function MyComponent() {
93
+ * const fontClass = useFontClass(inter, roboto);
94
+ * return <div className={fontClass}>Text</div>;
95
+ * }
96
+ * ```
97
+ */
98
+ export declare function useFontClass(...fonts: FontResult[]): string;
99
+ /**
100
+ * Get font style object from font result.
101
+ */
102
+ export declare function useFontStyle(font: FontResult): React.CSSProperties;
103
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/components/react.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C,MAAM,WAAW,aAAa;IAC1B,sCAAsC;IACtC,KAAK,EAAE,UAAU,EAAE,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,aAAa,GAAG,KAAK,CAAC,YAAY,CAiCrE;AAMD,MAAM,WAAW,cAAc;IAC3B,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CAOrE;AAMD,MAAM,WAAW,iBAAiB;IAC9B,4BAA4B;IAC5B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,uBAAuB;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,8CAA8C;IAC9C,EAAE,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;CAChG;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,EAAE,EAAE,GAAW,EAClB,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CASxC;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,GAAG,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,CAE3D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC,aAAa,CAElE"}