@newtonedev/components 0.1.7 → 0.1.9
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/composites/actions/Button/Button.d.ts.map +1 -1
- package/dist/composites/form-controls/Select/Select.styles.d.ts.map +1 -1
- package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts.map +1 -1
- package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts.map +1 -1
- package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts.map +1 -1
- package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts.map +1 -1
- package/dist/composites/range-inputs/Slider/Slider.styles.d.ts.map +1 -1
- package/dist/fonts/GoogleFontLoader.d.ts +5 -4
- package/dist/fonts/GoogleFontLoader.d.ts.map +1 -1
- package/dist/fonts/SelfHostedFontLoader.d.ts +14 -0
- package/dist/fonts/SelfHostedFontLoader.d.ts.map +1 -0
- package/dist/fonts/buildGoogleFontsUrl.d.ts +1 -16
- package/dist/fonts/buildGoogleFontsUrl.d.ts.map +1 -1
- package/dist/fonts/measureFont.d.ts +18 -0
- package/dist/fonts/measureFont.d.ts.map +1 -0
- package/dist/fonts/reportQueue.d.ts +7 -0
- package/dist/fonts/reportQueue.d.ts.map +1 -0
- package/dist/fonts/useLocalCalibration.d.ts +19 -0
- package/dist/fonts/useLocalCalibration.d.ts.map +1 -0
- package/dist/fonts/useTypographyCalibrations.d.ts +11 -0
- package/dist/fonts/useTypographyCalibrations.d.ts.map +1 -0
- package/dist/index.cjs +629 -422
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +568 -376
- package/dist/index.js.map +1 -1
- package/dist/primitives/Icon/Icon.types.d.ts +1 -1
- package/dist/primitives/Icon/Icon.types.d.ts.map +1 -1
- package/dist/primitives/Text/Text.d.ts +33 -8
- package/dist/primitives/Text/Text.d.ts.map +1 -1
- package/dist/primitives/Text/Text.spans.d.ts +22 -0
- package/dist/primitives/Text/Text.spans.d.ts.map +1 -0
- package/dist/primitives/Text/Text.types.d.ts +77 -27
- package/dist/primitives/Text/Text.types.d.ts.map +1 -1
- package/dist/primitives/Text/index.d.ts +23 -2
- package/dist/primitives/Text/index.d.ts.map +1 -1
- package/dist/primitives/index.d.ts +1 -1
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/registry/codegen.d.ts.map +1 -1
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/types.d.ts +2 -0
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/theme/NewtoneProvider.d.ts +9 -1
- package/dist/theme/NewtoneProvider.d.ts.map +1 -1
- package/dist/theme/defaults.d.ts +1 -0
- package/dist/theme/defaults.d.ts.map +1 -1
- package/dist/theme/types.d.ts +48 -32
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/theme/useBreakpoint.d.ts +9 -0
- package/dist/theme/useBreakpoint.d.ts.map +1 -0
- package/dist/tokens/computeTokens.d.ts +9 -22
- package/dist/tokens/computeTokens.d.ts.map +1 -1
- package/dist/tokens/types.d.ts +40 -22
- package/dist/tokens/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/composites/actions/Button/Button.styles.ts +3 -3
- package/src/composites/actions/Button/Button.tsx +3 -2
- package/src/composites/form-controls/Select/Select.styles.ts +8 -8
- package/src/composites/form-controls/Select/Select.tsx +1 -1
- package/src/composites/form-controls/Select/SelectOption.tsx +3 -3
- package/src/composites/form-controls/TextInput/TextInput.styles.ts +5 -5
- package/src/composites/form-controls/Toggle/Toggle.styles.ts +3 -3
- package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.ts +6 -6
- package/src/composites/range-inputs/HueSlider/HueSlider.styles.ts +9 -9
- package/src/composites/range-inputs/Slider/Slider.styles.ts +9 -9
- package/src/fonts/GoogleFontLoader.tsx +25 -10
- package/src/fonts/SelfHostedFontLoader.tsx +44 -0
- package/src/fonts/buildGoogleFontsUrl.ts +2 -31
- package/src/fonts/measureFont.ts +42 -0
- package/src/fonts/reportQueue.ts +54 -0
- package/src/fonts/useLocalCalibration.ts +97 -0
- package/src/fonts/useTypographyCalibrations.ts +15 -0
- package/src/index.ts +16 -7
- package/src/primitives/Frame/Frame.tsx +3 -3
- package/src/primitives/Icon/Icon.tsx +1 -1
- package/src/primitives/Icon/Icon.types.ts +1 -1
- package/src/primitives/Text/Text.spans.ts +57 -0
- package/src/primitives/Text/Text.tsx +208 -53
- package/src/primitives/Text/Text.types.ts +83 -27
- package/src/primitives/Text/index.ts +27 -3
- package/src/primitives/index.ts +3 -2
- package/src/registry/codegen.ts +1 -0
- package/src/registry/registry.ts +55 -53
- package/src/registry/types.ts +2 -0
- package/src/theme/NewtoneProvider.tsx +18 -2
- package/src/theme/defaults.ts +8 -28
- package/src/theme/types.ts +63 -33
- package/src/theme/useBreakpoint.ts +14 -0
- package/src/tokens/computeTokens.ts +23 -19
- package/src/tokens/types.ts +10 -24
- package/dist/fonts/googleFonts.d.ts +0 -20
- package/dist/fonts/googleFonts.d.ts.map +0 -1
- package/src/fonts/googleFonts.ts +0 -87
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import type { Text as RNText, TextStyle } from 'react-native';
|
|
2
2
|
import type { ElevationLevel } from '../../theme/types';
|
|
3
3
|
|
|
4
|
-
/** Typography size
|
|
5
|
-
export type TextSize = '
|
|
4
|
+
/** Typography size step — selects within the current role's 3-step scale. @default 'md' */
|
|
5
|
+
export type TextSize = 'sm' | 'md' | 'lg';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
export type TextWeight = 'regular' | 'medium' | '
|
|
7
|
+
/** Font weight slots — maps to per-scope `tokens.typography.fonts[scope].weights.*` values. */
|
|
8
|
+
export type TextWeight = 'regular' | 'medium' | 'bold';
|
|
9
9
|
|
|
10
10
|
/** Semantic text color tokens — resolved from the current theme's token palette. */
|
|
11
11
|
export type TextColor = 'primary' | 'secondary' | 'tertiary' | 'disabled' | 'accent' | 'success' | 'warning' | 'error';
|
|
12
12
|
|
|
13
|
-
/** Font
|
|
14
|
-
export type
|
|
13
|
+
/** Font scope — selects which font family slot to use. @default 'main' */
|
|
14
|
+
export type TextScope = 'main' | 'display' | 'mono' | 'currency';
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Semantic text role — determines default size, weight, and line height.
|
|
18
|
+
* Provides purpose-driven typography presets. Individual size/weight/lineHeight
|
|
19
|
+
* props can override the role's defaults when needed (e.g., in composites).
|
|
20
|
+
* @default 'body'
|
|
21
|
+
*/
|
|
22
|
+
export type TextRole = 'headline' | 'title' | 'heading' | 'subheading' | 'body' | 'label' | 'caption';
|
|
18
23
|
|
|
19
24
|
/** Text alignment. */
|
|
20
25
|
export type TextAlign = 'left' | 'center' | 'right';
|
|
@@ -22,38 +27,37 @@ export type TextAlign = 'left' | 'center' | 'right';
|
|
|
22
27
|
/**
|
|
23
28
|
* Props for Text — themed typography component.
|
|
24
29
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* tokens rather than raw values for consistency.
|
|
30
|
+
* Primary API surface: `scope` (font family) + `role` (semantic preset) + `color`.
|
|
31
|
+
* Individual size/weight/lineHeight props are available as overrides for composites.
|
|
28
32
|
*
|
|
29
33
|
* @example
|
|
30
34
|
* ```tsx
|
|
31
35
|
* <Text>Default body text</Text>
|
|
32
|
-
* <Text
|
|
33
|
-
* <Text
|
|
34
|
-
* <Text
|
|
35
|
-
* <Text
|
|
36
|
+
* <Text role="headline" scope="display">Hero title</Text>
|
|
37
|
+
* <Text role="label">Form label</Text>
|
|
38
|
+
* <Text scope="mono" role="caption">const x = 42;</Text>
|
|
39
|
+
* <Text role="body">Regular text with <Text.Bold>bold emphasis</Text.Bold></Text>
|
|
36
40
|
* ```
|
|
37
41
|
*/
|
|
38
42
|
export interface TextProps {
|
|
39
43
|
/**
|
|
40
|
-
* Text content. Accepts strings, numbers, and
|
|
41
|
-
* for inline formatting (e.g.,
|
|
44
|
+
* Text content. Accepts strings, numbers, and span sub-components
|
|
45
|
+
* for inline formatting (e.g., `<Text.Bold>`, `<Text.Italic>`).
|
|
42
46
|
*
|
|
43
47
|
* @example
|
|
44
48
|
* ```tsx
|
|
45
49
|
* <Text>Plain string</Text>
|
|
46
50
|
* <Text>Count: {42}</Text>
|
|
47
|
-
* <Text>Normal <Text
|
|
51
|
+
* <Text role="body">Normal <Text.Bold>bold</Text.Bold> normal</Text>
|
|
48
52
|
* ```
|
|
49
53
|
*/
|
|
50
54
|
readonly children: React.ReactNode;
|
|
51
55
|
|
|
52
|
-
/**
|
|
53
|
-
readonly
|
|
56
|
+
/** Font scope — selects which font family to use. @default 'main' */
|
|
57
|
+
readonly scope?: TextScope;
|
|
54
58
|
|
|
55
|
-
/**
|
|
56
|
-
readonly
|
|
59
|
+
/** Semantic role — sets default size/weight/lineHeight. @default 'body' */
|
|
60
|
+
readonly role?: TextRole;
|
|
57
61
|
|
|
58
62
|
/**
|
|
59
63
|
* Semantic color token.
|
|
@@ -71,11 +75,13 @@ export interface TextProps {
|
|
|
71
75
|
*/
|
|
72
76
|
readonly color?: TextColor;
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
// ── Overrides (used by composites, not exposed in editor UI) ──
|
|
79
|
+
|
|
80
|
+
/** Override the role's default size. */
|
|
81
|
+
readonly size?: TextSize;
|
|
76
82
|
|
|
77
|
-
/**
|
|
78
|
-
readonly
|
|
83
|
+
/** Override the role's default weight. */
|
|
84
|
+
readonly weight?: TextWeight;
|
|
79
85
|
|
|
80
86
|
/** Text alignment. */
|
|
81
87
|
readonly align?: TextAlign;
|
|
@@ -92,7 +98,8 @@ export interface TextProps {
|
|
|
92
98
|
// ── Accessibility ──
|
|
93
99
|
|
|
94
100
|
/**
|
|
95
|
-
* Semantic role for screen readers.
|
|
101
|
+
* Semantic role for screen readers. Auto-inferred from typography role
|
|
102
|
+
* (headline/title/heading → 'header') unless explicitly set.
|
|
96
103
|
*
|
|
97
104
|
* - `'header'` — Marks this as a heading (e.g. page title, section header)
|
|
98
105
|
* - `'text'` — Default text role (usually omitted)
|
|
@@ -110,4 +117,53 @@ export interface TextProps {
|
|
|
110
117
|
|
|
111
118
|
/** Ref to the underlying React Native Text element. */
|
|
112
119
|
readonly ref?: React.Ref<RNText>;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Enable responsive font sizing for adaptive roles (headline, title, heading, subheading).
|
|
123
|
+
* When true, the Text component measures its container width and uses `resolveResponsiveSize`
|
|
124
|
+
* to pick the best fontSize within the role's natural size, improving line-break quality.
|
|
125
|
+
* Requires the text to be wrapped in a container that defines a width.
|
|
126
|
+
* No-op for non-adaptive roles (body, label, caption).
|
|
127
|
+
* @default false
|
|
128
|
+
*/
|
|
129
|
+
readonly responsive?: boolean;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Apply vertical centering correction to compensate for font metrics.
|
|
133
|
+
* Shifts text down by the font's verticalCenterOffset so that cap-height
|
|
134
|
+
* text appears visually centered within flex containers (buttons, chips).
|
|
135
|
+
* No-op for multi-line body text — only enable in single-line centering contexts.
|
|
136
|
+
* Requires fontMetrics in the theme config; ignored when metrics are unavailable.
|
|
137
|
+
* @default false
|
|
138
|
+
*/
|
|
139
|
+
readonly centerVertically?: boolean;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* OpenType feature tags to enable (e.g., `['tnum', 'kern']`).
|
|
143
|
+
* When fontMetrics are available, requested tags are filtered against the font's
|
|
144
|
+
* supported features. When metrics are unavailable, all tags are applied optimistically.
|
|
145
|
+
* Maps to the CSS `font-feature-settings` property via react-native-web.
|
|
146
|
+
*/
|
|
147
|
+
readonly features?: readonly string[];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Constrained props for inline span sub-components (Text.Bold, Text.Italic, etc.).
|
|
152
|
+
* Spans inherit font family, size, and line height from the parent Text.
|
|
153
|
+
* Only inline formatting properties are exposed.
|
|
154
|
+
*/
|
|
155
|
+
export interface TextSpanProps {
|
|
156
|
+
readonly children: React.ReactNode;
|
|
157
|
+
/** Override text color within the span. */
|
|
158
|
+
readonly color?: TextColor;
|
|
159
|
+
/** Override font weight within the span. */
|
|
160
|
+
readonly weight?: TextWeight;
|
|
161
|
+
/** Apply italic style. */
|
|
162
|
+
readonly italic?: boolean;
|
|
163
|
+
/** Apply underline decoration. */
|
|
164
|
+
readonly underline?: boolean;
|
|
165
|
+
/** Apply background highlight using a semantic color token. */
|
|
166
|
+
readonly highlight?: TextColor;
|
|
167
|
+
/** Style overrides (applied last). */
|
|
168
|
+
readonly style?: TextStyle | readonly TextStyle[];
|
|
113
169
|
}
|
|
@@ -1,10 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
import { TextBase } from './Text';
|
|
2
|
+
import { TextSpan, TextBold, TextMedium, TextItalic, TextUnderline, TextHighlight } from './Text.spans';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Token-aware text primitive with span sub-components.
|
|
6
|
+
*
|
|
7
|
+
* Primary API: `scope` (font family) + `role` (semantic preset) + `color`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Text role="headline" scope="display">Hero</Text>
|
|
12
|
+
* <Text role="body">Regular <Text.Bold>bold</Text.Bold> text</Text>
|
|
13
|
+
* <Text role="label" color="secondary">Field label</Text>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export const Text = Object.assign(TextBase, {
|
|
17
|
+
Span: TextSpan,
|
|
18
|
+
Bold: TextBold,
|
|
19
|
+
Medium: TextMedium,
|
|
20
|
+
Italic: TextItalic,
|
|
21
|
+
Underline: TextUnderline,
|
|
22
|
+
Highlight: TextHighlight,
|
|
23
|
+
});
|
|
24
|
+
|
|
2
25
|
export type {
|
|
3
26
|
TextProps,
|
|
4
27
|
TextSize,
|
|
5
28
|
TextWeight,
|
|
6
29
|
TextColor,
|
|
7
|
-
|
|
8
|
-
|
|
30
|
+
TextScope,
|
|
31
|
+
TextRole,
|
|
9
32
|
TextAlign,
|
|
33
|
+
TextSpanProps,
|
|
10
34
|
} from './Text.types';
|
package/src/primitives/index.ts
CHANGED
package/src/registry/codegen.ts
CHANGED
package/src/registry/registry.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { CategoryMeta, ComponentMeta } from './types';
|
|
2
2
|
|
|
3
3
|
export const CATEGORIES: readonly CategoryMeta[] = [
|
|
4
|
-
{ id: '
|
|
5
|
-
{ id: '
|
|
6
|
-
{ id: '
|
|
7
|
-
{ id: '
|
|
8
|
-
{ id: '
|
|
9
|
-
{ id: 'overlays', name: 'Overlays', description: 'Floating and portal-based UI elements' },
|
|
4
|
+
{ id: 'colors', name: 'Colors', description: 'Color palettes and token visualization', icon: 'palette' },
|
|
5
|
+
{ id: 'typography', name: 'Typography', description: 'Text roles, scopes, and weight control', icon: 'text_fields' },
|
|
6
|
+
{ id: 'symbols', name: 'Symbols', description: 'Material Symbols icon browser', icon: 'grid_view' },
|
|
7
|
+
{ id: 'layout', name: 'Layout', description: 'Structural containers — Frame and Wrapper', icon: 'grid_on' },
|
|
8
|
+
{ id: 'components', name: 'Components', description: 'Interactive UI components', icon: 'widgets' },
|
|
10
9
|
];
|
|
11
10
|
|
|
12
11
|
export const COMPONENTS: readonly ComponentMeta[] = [
|
|
@@ -14,7 +13,7 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
14
13
|
id: 'button',
|
|
15
14
|
name: 'Button',
|
|
16
15
|
importName: 'Button',
|
|
17
|
-
categoryId: '
|
|
16
|
+
categoryId: 'components',
|
|
18
17
|
description: 'Interactive button with multiple variants, sizes, and optional icon',
|
|
19
18
|
hasChildren: true,
|
|
20
19
|
variants: [
|
|
@@ -96,7 +95,7 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
96
95
|
id: 'text-input',
|
|
97
96
|
name: 'TextInput',
|
|
98
97
|
importName: 'TextInput',
|
|
99
|
-
categoryId: '
|
|
98
|
+
categoryId: 'components',
|
|
100
99
|
description: 'Text input field with label support',
|
|
101
100
|
hasChildren: false,
|
|
102
101
|
variants: [
|
|
@@ -123,7 +122,7 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
123
122
|
id: 'select',
|
|
124
123
|
name: 'Select',
|
|
125
124
|
importName: 'Select',
|
|
126
|
-
categoryId: '
|
|
125
|
+
categoryId: 'components',
|
|
127
126
|
description: 'Dropdown selector with options',
|
|
128
127
|
hasChildren: false,
|
|
129
128
|
variants: [
|
|
@@ -170,7 +169,7 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
170
169
|
id: 'toggle',
|
|
171
170
|
name: 'Toggle',
|
|
172
171
|
importName: 'Toggle',
|
|
173
|
-
categoryId: '
|
|
172
|
+
categoryId: 'components',
|
|
174
173
|
description: 'Binary switch component',
|
|
175
174
|
hasChildren: false,
|
|
176
175
|
variants: [
|
|
@@ -197,7 +196,7 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
197
196
|
id: 'slider',
|
|
198
197
|
name: 'Slider',
|
|
199
198
|
importName: 'Slider',
|
|
200
|
-
categoryId: '
|
|
199
|
+
categoryId: 'components',
|
|
201
200
|
description: 'Numeric range slider',
|
|
202
201
|
hasChildren: false,
|
|
203
202
|
variants: [
|
|
@@ -241,7 +240,7 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
241
240
|
id: 'hue-slider',
|
|
242
241
|
name: 'HueSlider',
|
|
243
242
|
importName: 'HueSlider',
|
|
244
|
-
categoryId: '
|
|
243
|
+
categoryId: 'components',
|
|
245
244
|
description: 'Specialized slider for hue selection (0-360\u00b0)',
|
|
246
245
|
hasChildren: false,
|
|
247
246
|
variants: [
|
|
@@ -377,7 +376,7 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
377
376
|
id: 'card',
|
|
378
377
|
name: 'Card',
|
|
379
378
|
importName: 'Card',
|
|
380
|
-
categoryId: '
|
|
379
|
+
categoryId: 'components',
|
|
381
380
|
description: 'Surface container with elevation levels',
|
|
382
381
|
hasChildren: true,
|
|
383
382
|
variants: [
|
|
@@ -410,45 +409,59 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
410
409
|
id: 'text',
|
|
411
410
|
name: 'Text',
|
|
412
411
|
importName: 'Text',
|
|
413
|
-
categoryId: '
|
|
414
|
-
description: 'Typography primitive with semantic
|
|
412
|
+
categoryId: 'typography',
|
|
413
|
+
description: 'Typography primitive with semantic scope (font family) and role (purpose)',
|
|
415
414
|
hasChildren: true,
|
|
415
|
+
previewLayout: 'list',
|
|
416
416
|
variants: [
|
|
417
|
-
{ id: '
|
|
418
|
-
{ id: '
|
|
419
|
-
{ id: '
|
|
420
|
-
{ id: '
|
|
421
|
-
{ id: '
|
|
422
|
-
{ id: '
|
|
423
|
-
{ id: '
|
|
417
|
+
{ id: 'body', label: 'Body', props: { role: 'body' } },
|
|
418
|
+
{ id: 'headline', label: 'Headline', props: { role: 'headline', scope: 'display' } },
|
|
419
|
+
{ id: 'title', label: 'Title', props: { role: 'title', scope: 'display' } },
|
|
420
|
+
{ id: 'heading', label: 'Heading', props: { role: 'heading' } },
|
|
421
|
+
{ id: 'subheading', label: 'Subheading', props: { role: 'subheading' } },
|
|
422
|
+
{ id: 'label', label: 'Label', props: { role: 'label' } },
|
|
423
|
+
{ id: 'caption', label: 'Caption', props: { role: 'caption', color: 'secondary' } },
|
|
424
|
+
{ id: 'mono', label: 'Monospace', props: { scope: 'mono', role: 'body' } },
|
|
425
|
+
{ id: 'currency', label: 'Currency', props: { scope: 'currency', role: 'body' } },
|
|
424
426
|
],
|
|
425
427
|
editableProps: [
|
|
426
428
|
{
|
|
427
|
-
name: '
|
|
428
|
-
label: '
|
|
429
|
+
name: 'scope',
|
|
430
|
+
label: 'Scope',
|
|
429
431
|
control: 'select',
|
|
430
432
|
options: [
|
|
431
|
-
{ label: '
|
|
432
|
-
{ label: '
|
|
433
|
-
{ label: '
|
|
434
|
-
{ label: '
|
|
435
|
-
{ label: 'Large', value: 'lg' },
|
|
436
|
-
{ label: 'Extra Large', value: 'xl' },
|
|
437
|
-
{ label: 'XXL', value: 'xxl' },
|
|
433
|
+
{ label: 'Main', value: 'main' },
|
|
434
|
+
{ label: 'Display', value: 'display' },
|
|
435
|
+
{ label: 'Mono', value: 'mono' },
|
|
436
|
+
{ label: 'Currency', value: 'currency' },
|
|
438
437
|
],
|
|
439
|
-
defaultValue: '
|
|
438
|
+
defaultValue: 'main',
|
|
440
439
|
},
|
|
441
440
|
{
|
|
442
|
-
name: '
|
|
443
|
-
label: '
|
|
441
|
+
name: 'role',
|
|
442
|
+
label: 'Role',
|
|
444
443
|
control: 'select',
|
|
445
444
|
options: [
|
|
446
|
-
{ label: '
|
|
447
|
-
{ label: '
|
|
448
|
-
{ label: '
|
|
449
|
-
{ label: '
|
|
445
|
+
{ label: 'Headline', value: 'headline' },
|
|
446
|
+
{ label: 'Title', value: 'title' },
|
|
447
|
+
{ label: 'Heading', value: 'heading' },
|
|
448
|
+
{ label: 'Subheading', value: 'subheading' },
|
|
449
|
+
{ label: 'Body', value: 'body' },
|
|
450
|
+
{ label: 'Label', value: 'label' },
|
|
451
|
+
{ label: 'Caption', value: 'caption' },
|
|
450
452
|
],
|
|
451
|
-
defaultValue: '
|
|
453
|
+
defaultValue: 'body',
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
name: 'size',
|
|
457
|
+
label: 'Size',
|
|
458
|
+
control: 'select',
|
|
459
|
+
options: [
|
|
460
|
+
{ label: 'Small', value: 'sm' },
|
|
461
|
+
{ label: 'Medium', value: 'md' },
|
|
462
|
+
{ label: 'Large', value: 'lg' },
|
|
463
|
+
],
|
|
464
|
+
defaultValue: 'md',
|
|
452
465
|
},
|
|
453
466
|
{
|
|
454
467
|
name: 'color',
|
|
@@ -466,24 +479,13 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
466
479
|
],
|
|
467
480
|
defaultValue: 'primary',
|
|
468
481
|
},
|
|
469
|
-
{
|
|
470
|
-
name: 'font',
|
|
471
|
-
label: 'Font',
|
|
472
|
-
control: 'select',
|
|
473
|
-
options: [
|
|
474
|
-
{ label: 'Default', value: 'default' },
|
|
475
|
-
{ label: 'Display', value: 'display' },
|
|
476
|
-
{ label: 'Mono', value: 'mono' },
|
|
477
|
-
],
|
|
478
|
-
defaultValue: 'default',
|
|
479
|
-
},
|
|
480
482
|
],
|
|
481
483
|
},
|
|
482
484
|
{
|
|
483
485
|
id: 'icon',
|
|
484
486
|
name: 'Icon',
|
|
485
487
|
importName: 'Icon',
|
|
486
|
-
categoryId: '
|
|
488
|
+
categoryId: 'symbols',
|
|
487
489
|
description: 'Material Symbols icon with size and fill',
|
|
488
490
|
hasChildren: false,
|
|
489
491
|
variants: [
|
|
@@ -520,7 +522,7 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
520
522
|
id: 'wrapper',
|
|
521
523
|
name: 'Wrapper',
|
|
522
524
|
importName: 'Wrapper',
|
|
523
|
-
categoryId: '
|
|
525
|
+
categoryId: 'layout',
|
|
524
526
|
description: 'Lightweight layout container with direction, spacing, and alignment (no theming)',
|
|
525
527
|
hasChildren: true,
|
|
526
528
|
variants: [
|
|
@@ -594,7 +596,7 @@ export const COMPONENTS: readonly ComponentMeta[] = [
|
|
|
594
596
|
id: 'color-scale-slider',
|
|
595
597
|
name: 'ColorScaleSlider',
|
|
596
598
|
importName: 'ColorScaleSlider',
|
|
597
|
-
categoryId: '
|
|
599
|
+
categoryId: 'components',
|
|
598
600
|
description: 'Interactive palette preview slider with color segments',
|
|
599
601
|
hasChildren: false,
|
|
600
602
|
variants: [
|
package/src/registry/types.ts
CHANGED
|
@@ -2,6 +2,7 @@ export interface CategoryMeta {
|
|
|
2
2
|
readonly id: string;
|
|
3
3
|
readonly name: string;
|
|
4
4
|
readonly description: string;
|
|
5
|
+
readonly icon?: string;
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
export interface VariantMeta {
|
|
@@ -30,6 +31,7 @@ export interface ComponentMeta {
|
|
|
30
31
|
readonly categoryId: string;
|
|
31
32
|
readonly description: string;
|
|
32
33
|
readonly hasChildren: boolean;
|
|
34
|
+
readonly previewLayout?: 'grid' | 'list';
|
|
33
35
|
readonly variants: readonly VariantMeta[];
|
|
34
36
|
readonly editableProps: readonly EditableProp[];
|
|
35
37
|
}
|
|
@@ -2,6 +2,7 @@ import React, { createContext, useState, useMemo, useContext } from 'react';
|
|
|
2
2
|
import type { NewtoneThemeConfig, NewtoneThemeContext, ColorMode } from './types';
|
|
3
3
|
import { DEFAULT_THEME_CONFIG } from './defaults';
|
|
4
4
|
import { GoogleFontLoader } from '../fonts/GoogleFontLoader';
|
|
5
|
+
import { SelfHostedFontLoader } from '../fonts/SelfHostedFontLoader';
|
|
5
6
|
import { IconFontLoader } from '../fonts/IconFontLoader';
|
|
6
7
|
|
|
7
8
|
const ThemeContext = createContext<NewtoneThemeContext | null>(null);
|
|
@@ -10,6 +11,14 @@ export interface NewtoneProviderProps {
|
|
|
10
11
|
readonly config?: NewtoneThemeConfig;
|
|
11
12
|
readonly initialMode?: ColorMode;
|
|
12
13
|
readonly children: React.ReactNode;
|
|
14
|
+
/** Optional URL for typography telemetry. When set, adaptive Text instances report observations. */
|
|
15
|
+
readonly reportingEndpoint?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Self-hosted @font-face CSS from the theme API.
|
|
18
|
+
* When provided, injects this CSS instead of loading from Google CDN.
|
|
19
|
+
* Falls back to Google CDN when absent or null.
|
|
20
|
+
*/
|
|
21
|
+
readonly fontFaceCss?: string | null;
|
|
13
22
|
}
|
|
14
23
|
|
|
15
24
|
/**
|
|
@@ -28,6 +37,8 @@ export function NewtoneProvider({
|
|
|
28
37
|
config = DEFAULT_THEME_CONFIG,
|
|
29
38
|
initialMode = 'light',
|
|
30
39
|
children,
|
|
40
|
+
reportingEndpoint,
|
|
41
|
+
fontFaceCss,
|
|
31
42
|
}: NewtoneProviderProps) {
|
|
32
43
|
const [mode, setMode] = useState<ColorMode>(initialMode);
|
|
33
44
|
|
|
@@ -36,13 +47,18 @@ export function NewtoneProvider({
|
|
|
36
47
|
config,
|
|
37
48
|
mode,
|
|
38
49
|
setMode,
|
|
50
|
+
reportingEndpoint,
|
|
39
51
|
}),
|
|
40
|
-
[config, mode]
|
|
52
|
+
[config, mode, reportingEndpoint]
|
|
41
53
|
);
|
|
42
54
|
|
|
43
55
|
return (
|
|
44
56
|
<ThemeContext.Provider value={value}>
|
|
45
|
-
|
|
57
|
+
{fontFaceCss ? (
|
|
58
|
+
<SelfHostedFontLoader fontFaceCss={fontFaceCss} />
|
|
59
|
+
) : (
|
|
60
|
+
<GoogleFontLoader fonts={config.typography.fonts} />
|
|
61
|
+
)}
|
|
46
62
|
<IconFontLoader icons={config.icons} />
|
|
47
63
|
{children}
|
|
48
64
|
</ThemeContext.Provider>
|
package/src/theme/defaults.ts
CHANGED
|
@@ -11,6 +11,10 @@ import {
|
|
|
11
11
|
DEFAULT_ERROR_HUE,
|
|
12
12
|
DEFAULT_ERROR_SATURATION,
|
|
13
13
|
} from 'newtone';
|
|
14
|
+
import { DEFAULT_FONT_SLOTS, DEFAULT_FONT_SIZES, DEFAULT_LINE_HEIGHTS, DEFAULT_ROLE_SCALES } from '@newtonedev/fonts';
|
|
15
|
+
|
|
16
|
+
// Re-export typography defaults from @newtonedev/fonts (canonical source)
|
|
17
|
+
export { DEFAULT_FONT_SIZES, DEFAULT_LINE_HEIGHTS, DEFAULT_ROLE_SCALES } from '@newtonedev/fonts';
|
|
14
18
|
|
|
15
19
|
/**
|
|
16
20
|
* Default theme configuration matching playground defaults.
|
|
@@ -54,34 +58,10 @@ export const DEFAULT_THEME_CONFIG: NewtoneThemeConfig = {
|
|
|
54
58
|
pill: 999,
|
|
55
59
|
},
|
|
56
60
|
typography: {
|
|
57
|
-
fonts:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
fallback: 'SFMono-Regular, Menlo, Monaco, Consolas, monospace',
|
|
62
|
-
},
|
|
63
|
-
display: {
|
|
64
|
-
type: 'system',
|
|
65
|
-
family: 'system-ui',
|
|
66
|
-
fallback: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
67
|
-
},
|
|
68
|
-
default: {
|
|
69
|
-
type: 'system',
|
|
70
|
-
family: 'system-ui',
|
|
71
|
-
fallback: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
scale: {
|
|
75
|
-
xs: 10, // 16 / 1.25^2
|
|
76
|
-
sm: 13, // 16 / 1.25
|
|
77
|
-
base: 16,
|
|
78
|
-
md: 20, // 16 * 1.25
|
|
79
|
-
lg: 25, // 16 * 1.25^2
|
|
80
|
-
xl: 31, // 16 * 1.25^3
|
|
81
|
-
xxl: 39, // 16 * 1.25^4
|
|
82
|
-
},
|
|
83
|
-
lineHeight: { tight: 1.25, normal: 1.5, relaxed: 1.75 },
|
|
84
|
-
fontWeight: { regular: 400, medium: 500, semibold: 600, bold: 700 },
|
|
61
|
+
fonts: DEFAULT_FONT_SLOTS,
|
|
62
|
+
fontSizes: DEFAULT_FONT_SIZES,
|
|
63
|
+
lineHeights: DEFAULT_LINE_HEIGHTS,
|
|
64
|
+
roles: DEFAULT_ROLE_SCALES,
|
|
85
65
|
},
|
|
86
66
|
icons: {
|
|
87
67
|
variant: 'rounded', // Material Design 3 aesthetic
|