@newtonedev/components 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +506 -0
  2. package/dist/Button/Button.d.ts +23 -0
  3. package/dist/Button/Button.d.ts.map +1 -0
  4. package/dist/Button/Button.styles.d.ts +39 -0
  5. package/dist/Button/Button.styles.d.ts.map +1 -0
  6. package/dist/Button/Button.types.d.ts +42 -0
  7. package/dist/Button/Button.types.d.ts.map +1 -0
  8. package/dist/Button/index.d.ts +3 -0
  9. package/dist/Button/index.d.ts.map +1 -0
  10. package/dist/Card/Card.d.ts +4 -0
  11. package/dist/Card/Card.d.ts.map +1 -0
  12. package/dist/Card/Card.styles.d.ts +12 -0
  13. package/dist/Card/Card.styles.d.ts.map +1 -0
  14. package/dist/Card/Card.types.d.ts +9 -0
  15. package/dist/Card/Card.types.d.ts.map +1 -0
  16. package/dist/Card/index.d.ts +3 -0
  17. package/dist/Card/index.d.ts.map +1 -0
  18. package/dist/HueSlider/HueSlider.d.ts +14 -0
  19. package/dist/HueSlider/HueSlider.d.ts.map +1 -0
  20. package/dist/HueSlider/HueSlider.styles.d.ts +28 -0
  21. package/dist/HueSlider/HueSlider.styles.d.ts.map +1 -0
  22. package/dist/HueSlider/HueSlider.types.d.ts +12 -0
  23. package/dist/HueSlider/HueSlider.types.d.ts.map +1 -0
  24. package/dist/HueSlider/index.d.ts +3 -0
  25. package/dist/HueSlider/index.d.ts.map +1 -0
  26. package/dist/Select/Select.d.ts +11 -0
  27. package/dist/Select/Select.d.ts.map +1 -0
  28. package/dist/Select/Select.styles.d.ts +23 -0
  29. package/dist/Select/Select.styles.d.ts.map +1 -0
  30. package/dist/Select/Select.types.d.ts +14 -0
  31. package/dist/Select/Select.types.d.ts.map +1 -0
  32. package/dist/Select/index.d.ts +3 -0
  33. package/dist/Select/index.d.ts.map +1 -0
  34. package/dist/Slider/Slider.d.ts +4 -0
  35. package/dist/Slider/Slider.d.ts.map +1 -0
  36. package/dist/Slider/Slider.styles.d.ts +27 -0
  37. package/dist/Slider/Slider.styles.d.ts.map +1 -0
  38. package/dist/Slider/Slider.types.d.ts +13 -0
  39. package/dist/Slider/Slider.types.d.ts.map +1 -0
  40. package/dist/Slider/index.d.ts +3 -0
  41. package/dist/Slider/index.d.ts.map +1 -0
  42. package/dist/TextInput/TextInput.d.ts +4 -0
  43. package/dist/TextInput/TextInput.d.ts.map +1 -0
  44. package/dist/TextInput/TextInput.styles.d.ts +23 -0
  45. package/dist/TextInput/TextInput.styles.d.ts.map +1 -0
  46. package/dist/TextInput/TextInput.types.d.ts +7 -0
  47. package/dist/TextInput/TextInput.types.d.ts.map +1 -0
  48. package/dist/TextInput/index.d.ts +3 -0
  49. package/dist/TextInput/index.d.ts.map +1 -0
  50. package/dist/Toggle/Toggle.d.ts +4 -0
  51. package/dist/Toggle/Toggle.d.ts.map +1 -0
  52. package/dist/Toggle/Toggle.styles.d.ts +30 -0
  53. package/dist/Toggle/Toggle.styles.d.ts.map +1 -0
  54. package/dist/Toggle/Toggle.types.d.ts +9 -0
  55. package/dist/Toggle/Toggle.types.d.ts.map +1 -0
  56. package/dist/Toggle/index.d.ts +3 -0
  57. package/dist/Toggle/index.d.ts.map +1 -0
  58. package/dist/index.cjs +736 -0
  59. package/dist/index.cjs.map +1 -0
  60. package/dist/index.d.ts +22 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +719 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/theme/NewtoneProvider.d.ts +33 -0
  65. package/dist/theme/NewtoneProvider.d.ts.map +1 -0
  66. package/dist/theme/defaults.d.ts +7 -0
  67. package/dist/theme/defaults.d.ts.map +1 -0
  68. package/dist/theme/types.d.ts +56 -0
  69. package/dist/theme/types.d.ts.map +1 -0
  70. package/dist/tokens/computeTokens.d.ts +30 -0
  71. package/dist/tokens/computeTokens.d.ts.map +1 -0
  72. package/dist/tokens/types.d.ts +31 -0
  73. package/dist/tokens/types.d.ts.map +1 -0
  74. package/dist/tokens/useTokens.d.ts +26 -0
  75. package/dist/tokens/useTokens.d.ts.map +1 -0
  76. package/package.json +57 -0
  77. package/src/Button/Button.styles.ts +100 -0
  78. package/src/Button/Button.tsx +67 -0
  79. package/src/Button/Button.types.ts +49 -0
  80. package/src/Button/index.ts +2 -0
  81. package/src/Card/Card.styles.ts +16 -0
  82. package/src/Card/Card.tsx +25 -0
  83. package/src/Card/Card.types.ts +9 -0
  84. package/src/Card/index.ts +2 -0
  85. package/src/HueSlider/HueSlider.styles.ts +77 -0
  86. package/src/HueSlider/HueSlider.tsx +70 -0
  87. package/src/HueSlider/HueSlider.types.ts +12 -0
  88. package/src/HueSlider/index.ts +2 -0
  89. package/src/Select/Select.styles.ts +29 -0
  90. package/src/Select/Select.tsx +60 -0
  91. package/src/Select/Select.types.ts +15 -0
  92. package/src/Select/index.ts +2 -0
  93. package/src/Slider/Slider.styles.ts +45 -0
  94. package/src/Slider/Slider.tsx +57 -0
  95. package/src/Slider/Slider.types.ts +13 -0
  96. package/src/Slider/index.ts +2 -0
  97. package/src/TextInput/TextInput.styles.ts +29 -0
  98. package/src/TextInput/TextInput.tsx +32 -0
  99. package/src/TextInput/TextInput.types.ts +7 -0
  100. package/src/TextInput/index.ts +2 -0
  101. package/src/Toggle/Toggle.styles.ts +45 -0
  102. package/src/Toggle/Toggle.tsx +42 -0
  103. package/src/Toggle/Toggle.types.ts +9 -0
  104. package/src/Toggle/index.ts +2 -0
  105. package/src/index.ts +49 -0
  106. package/src/theme/NewtoneProvider.tsx +65 -0
  107. package/src/theme/defaults.ts +42 -0
  108. package/src/theme/types.ts +62 -0
  109. package/src/tokens/computeTokens.ts +217 -0
  110. package/src/tokens/types.ts +31 -0
  111. package/src/tokens/useTokens.ts +42 -0
package/README.md ADDED
@@ -0,0 +1,506 @@
1
+ # @newtone/components
2
+
3
+ Production-ready React component library built on the Newtone color engine. Cross-platform support for web and React Native using `react-native-web`.
4
+
5
+ ## Features
6
+
7
+ - 🎨 **Powered by Newtone** — Accessible semantic color systems with OKLCH color space
8
+ - 🌓 **Light/Dark Mode** — Automatic theme switching with Context API
9
+ - 🎯 **Four Themes** — Neutral, Primary, Secondary, Strong with elevation support
10
+ - 📱 **Cross-Platform** — Single codebase for web and React Native
11
+ - 🔧 **Runtime Tokens** — Dynamic color computation with memoization
12
+ - ♿️ **Accessible** — WCAG contrast ratios built-in
13
+ - 📦 **Zero Config** — Sensible defaults, fully customizable
14
+ - 🎭 **TypeScript** — Full type safety
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @newtone/components react react-native
20
+ ```
21
+
22
+ ### Additional Setup
23
+
24
+ **For Web Projects:**
25
+ ```bash
26
+ npm install react-native-web react-dom
27
+ ```
28
+
29
+ **For React Native Projects:**
30
+ No additional dependencies required.
31
+
32
+ ## Quick Start
33
+
34
+ ### Web Application
35
+
36
+ ```tsx
37
+ import React from 'react';
38
+ import ReactDOM from 'react-dom/client';
39
+ import { NewtoneProvider, Button } from '@newtone/components';
40
+
41
+ function App() {
42
+ return (
43
+ <NewtoneProvider initialMode="light" initialTheme="neutral">
44
+ <div style={{ padding: 20 }}>
45
+ <Button variant="primary" onPress={() => console.log('Clicked!')}>
46
+ Click me
47
+ </Button>
48
+ </div>
49
+ </NewtoneProvider>
50
+ );
51
+ }
52
+
53
+ ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
54
+ ```
55
+
56
+ ### React Native Application
57
+
58
+ ```tsx
59
+ import React from 'react';
60
+ import { SafeAreaView } from 'react-native';
61
+ import { NewtoneProvider, Button } from '@newtone/components';
62
+
63
+ export default function App() {
64
+ return (
65
+ <NewtoneProvider initialMode="light" initialTheme="neutral">
66
+ <SafeAreaView style={{ flex: 1, padding: 20 }}>
67
+ <Button variant="primary" onPress={() => console.log('Clicked!')}>
68
+ Click me
69
+ </Button>
70
+ </SafeAreaView>
71
+ </NewtoneProvider>
72
+ );
73
+ }
74
+ ```
75
+
76
+ ## Components
77
+
78
+ ### Button
79
+
80
+ A cross-platform button component with multiple variants and sizes.
81
+
82
+ #### Props
83
+
84
+ ```typescript
85
+ interface ButtonProps {
86
+ children: React.ReactNode;
87
+ variant?: 'primary' | 'secondary' | 'ghost' | 'outline'; // default: 'primary'
88
+ size?: 'sm' | 'md' | 'lg'; // default: 'md'
89
+ disabled?: boolean; // default: false
90
+ onPress?: () => void;
91
+ style?: ViewStyle | ViewStyle[];
92
+ textStyle?: TextStyle | TextStyle[];
93
+ // ... all other Pressable props
94
+ }
95
+ ```
96
+
97
+ #### Variants
98
+
99
+ - **Primary** — Filled button with interactive color background
100
+ - **Secondary** — Filled button with elevated background
101
+ - **Ghost** — Transparent button with colored text
102
+ - **Outline** — Border-only button with colored text
103
+
104
+ #### Sizes
105
+
106
+ - **Small (`sm`)** — Compact button for tight spaces (6px vertical padding)
107
+ - **Medium (`md`)** — Default size for most use cases (10px vertical padding)
108
+ - **Large (`lg`)** — Prominent button for primary actions (14px vertical padding)
109
+
110
+ #### Examples
111
+
112
+ ```tsx
113
+ import { Button } from '@newtone/components';
114
+
115
+ // Primary button (default)
116
+ <Button onPress={() => {}}>Submit</Button>
117
+
118
+ // Secondary button
119
+ <Button variant="secondary" onPress={() => {}}>Cancel</Button>
120
+
121
+ // Large ghost button
122
+ <Button variant="ghost" size="lg" onPress={() => {}}>Learn More</Button>
123
+
124
+ // Disabled outline button
125
+ <Button variant="outline" disabled>Unavailable</Button>
126
+
127
+ // Custom styles
128
+ <Button
129
+ variant="primary"
130
+ style={{ marginTop: 20, width: 200 }}
131
+ textStyle={{ fontWeight: 'bold' }}
132
+ onPress={() => {}}
133
+ >
134
+ Custom Styled
135
+ </Button>
136
+ ```
137
+
138
+ ## Theme System
139
+
140
+ ### NewtoneProvider
141
+
142
+ Wrap your application root with `NewtoneProvider` to enable theming.
143
+
144
+ ```tsx
145
+ import { NewtoneProvider } from '@newtone/components';
146
+
147
+ <NewtoneProvider
148
+ config={customConfig} // optional, uses defaults if omitted
149
+ initialMode="light" // 'light' | 'dark', default: 'light'
150
+ initialTheme="neutral" // 'neutral' | 'primary' | 'secondary' | 'strong', default: 'neutral'
151
+ >
152
+ <App />
153
+ </NewtoneProvider>
154
+ ```
155
+
156
+ #### Default Configuration
157
+
158
+ The library ships with a sensible default configuration:
159
+
160
+ - **5 Palettes**: Neutral (gray), Accent (blue), Success (green), Warning (yellow), Error (red)
161
+ - **4 Themes**: Each maps to a palette with light/dark normalized values
162
+ - **3 Elevations**: Surface levels with subtle color shifts (-0.02, 0, +0.04)
163
+ - **Dynamic Range**: Lightest = 1 (white), Darkest = 1 (black)
164
+
165
+ ### useNewtoneTheme Hook
166
+
167
+ Access and modify theme state from any component within the provider.
168
+
169
+ ```tsx
170
+ import { useNewtoneTheme } from '@newtone/components';
171
+
172
+ function ThemeToggle() {
173
+ const { mode, theme, setMode, setTheme } = useNewtoneTheme();
174
+
175
+ return (
176
+ <div>
177
+ <button onClick={() => setMode(mode === 'light' ? 'dark' : 'light')}>
178
+ Toggle {mode} mode
179
+ </button>
180
+ <button onClick={() => setTheme('primary')}>
181
+ Switch to primary theme
182
+ </button>
183
+ </div>
184
+ );
185
+ }
186
+ ```
187
+
188
+ ### useTokens Hook
189
+
190
+ Compute design tokens for the current theme context at a specific elevation.
191
+
192
+ ```tsx
193
+ import { useTokens } from '@newtone/components';
194
+
195
+ function CustomComponent() {
196
+ const tokens = useTokens(1); // Elevation level: 0, 1, or 2
197
+
198
+ return (
199
+ <div style={{
200
+ backgroundColor: tokens.background.srgb,
201
+ color: tokens.textPrimary.srgb
202
+ }}>
203
+ Custom component using tokens
204
+ </div>
205
+ );
206
+ }
207
+ ```
208
+
209
+ #### Available Tokens
210
+
211
+ ```typescript
212
+ interface ResolvedTokens {
213
+ background: ColorResult; // Base surface color
214
+ backgroundElevated: ColorResult; // Elevated surface (+1 level)
215
+ backgroundSunken: ColorResult; // Sunken surface (-1 level)
216
+ textPrimary: ColorResult; // Primary text (WCAG 4.5:1)
217
+ textSecondary: ColorResult; // Secondary text (WCAG 3.0:1)
218
+ interactive: ColorResult; // Interactive elements (accent palette)
219
+ interactiveHover: ColorResult; // Hover state
220
+ interactiveActive: ColorResult; // Active/pressed state
221
+ border: ColorResult; // Subtle borders
222
+ }
223
+ ```
224
+
225
+ Each `ColorResult` contains:
226
+ ```typescript
227
+ {
228
+ srgb: { r: number, g: number, b: number }, // 0-1 range
229
+ oklch: { L: number, C: number, h: number }
230
+ }
231
+ ```
232
+
233
+ **Helper for hex conversion:**
234
+ ```tsx
235
+ import { srgbToHex } from 'newtone';
236
+
237
+ const hexColor = srgbToHex(tokens.background.srgb); // "#ffffff"
238
+ ```
239
+
240
+ ## Customization
241
+
242
+ ### Custom Color System
243
+
244
+ Override the default palette configuration:
245
+
246
+ ```tsx
247
+ import { NewtoneProvider } from '@newtone/components';
248
+ import type { ColorSystemConfig } from 'newtone';
249
+
250
+ const customColorSystem: ColorSystemConfig = {
251
+ dynamicRange: {
252
+ lightest: 1, // 0-1, where 1 = pure white
253
+ darkest: 1, // 0-1, where 1 = pure black
254
+ },
255
+ palettes: [
256
+ {
257
+ hue: 220, // OKLCH hue (0-360)
258
+ saturation: 80, // 0-100, relative to max in-gamut chroma
259
+ desaturation: {
260
+ direction: 'light', // 'light' | 'dark'
261
+ strength: 'medium' // 'low' | 'medium' | 'hard'
262
+ },
263
+ paletteHueGrading: {
264
+ hue: 200,
265
+ strength: 'low',
266
+ direction: 'light'
267
+ }
268
+ },
269
+ // ... more palettes
270
+ ],
271
+ };
272
+
273
+ const customConfig = {
274
+ colorSystem: customColorSystem,
275
+ themes: {
276
+ neutral: { paletteIndex: 0, lightModeNv: 0.97, darkModeNv: 0.08 },
277
+ primary: { paletteIndex: 1, lightModeNv: 0.50, darkModeNv: 0.45 },
278
+ secondary: { paletteIndex: 2, lightModeNv: 0.60, darkModeNv: 0.55 },
279
+ strong: { paletteIndex: 3, lightModeNv: 0.30, darkModeNv: 0.70 },
280
+ },
281
+ elevation: {
282
+ offsets: [-0.02, 0, 0.04] as const,
283
+ },
284
+ };
285
+
286
+ <NewtoneProvider config={customConfig}>
287
+ <App />
288
+ </NewtoneProvider>
289
+ ```
290
+
291
+ ### Custom Button Styles
292
+
293
+ Override button appearance with `style` and `textStyle` props:
294
+
295
+ ```tsx
296
+ <Button
297
+ variant="primary"
298
+ style={[
299
+ { borderRadius: 20, paddingHorizontal: 30 },
300
+ isHighlighted && { transform: [{ scale: 1.05 }] }
301
+ ]}
302
+ textStyle={{
303
+ fontFamily: 'CustomFont',
304
+ letterSpacing: 1
305
+ }}
306
+ >
307
+ Custom Button
308
+ </Button>
309
+ ```
310
+
311
+ ## Architecture
312
+
313
+ ### Token Computation Strategy
314
+
315
+ **Phase 1 (Current): Runtime Computation**
316
+
317
+ Tokens are computed on-demand using the Newtone color engine:
318
+
319
+ ```
320
+ Config → getColor() → OKLCH → Gamut Mapping → sRGB → ColorResult
321
+ ```
322
+
323
+ - ✅ Maximum flexibility (change config, colors update instantly)
324
+ - ✅ Smallest bundle (no pre-generated tokens)
325
+ - ✅ Always accurate (no stale tokens)
326
+ - ⚠️ Requires engine in bundle (~20KB minified)
327
+ - ⚠️ Runtime computation cost (mitigated by memoization)
328
+
329
+ **Phase 2 (Future): Hybrid Strategy**
330
+
331
+ - **Development**: Runtime computation (hot reload, instant feedback)
332
+ - **Production**: Build-time token generation (W3C Design Tokens JSON)
333
+ - Zero engine in production bundle
334
+ - Cross-platform export (CSS, iOS, Android, etc.)
335
+
336
+ ### Component Patterns
337
+
338
+ All components follow these conventions:
339
+
340
+ 1. **Pure Components** — Props in, UI out, no side effects
341
+ 2. **Token-Driven** — Colors from `useTokens()`, not hardcoded
342
+ 3. **Cross-Platform** — `Pressable`, `Text`, `StyleSheet` from React Native
343
+ 4. **Memoized Styles** — `useMemo` for style computation
344
+ 5. **Accessible** — WCAG-compliant contrast ratios
345
+ 6. **Type-Safe** — Full TypeScript with readonly interfaces
346
+
347
+ ### File Structure
348
+
349
+ ```
350
+ packages/components/
351
+ ├── src/
352
+ │ ├── theme/
353
+ │ │ ├── types.ts # ColorMode, ThemeName, ThemeMapping
354
+ │ │ ├── defaults.ts # DEFAULT_THEME_CONFIG
355
+ │ │ └── NewtoneProvider.tsx # Context provider + hook
356
+ │ ├── tokens/
357
+ │ │ ├── types.ts # ResolvedTokens interface
358
+ │ │ ├── computeTokens.ts # Pure token computation
359
+ │ │ └── useTokens.ts # Memoized token hook
360
+ │ ├── Button/
361
+ │ │ ├── Button.tsx # Component implementation
362
+ │ │ ├── Button.types.ts # Props and type definitions
363
+ │ │ ├── Button.styles.ts # Style computation function
364
+ │ │ └── index.ts # Barrel export
365
+ │ └── index.ts # Public API
366
+ ├── tests/
367
+ │ ├── theme.test.tsx # Theme system tests
368
+ │ ├── tokens.test.ts # Token computation tests
369
+ │ └── Button.test.tsx # Button component tests
370
+ └── package.json
371
+ ```
372
+
373
+ ## Platform-Specific Notes
374
+
375
+ ### Web
376
+
377
+ - Uses `react-native-web` to render React Native primitives as HTML
378
+ - `Pressable` → `<button>` or `<div>` with click handlers
379
+ - `Text` → `<span>`
380
+ - `StyleSheet` → Optimized CSS-in-JS
381
+
382
+ **Bundler Configuration:**
383
+
384
+ Most modern bundlers (Vite, Next.js, Create React App) automatically handle `react-native-web` aliasing. If needed, manually alias:
385
+
386
+ ```js
387
+ // vite.config.js
388
+ export default {
389
+ resolve: {
390
+ alias: {
391
+ 'react-native': 'react-native-web',
392
+ },
393
+ },
394
+ };
395
+ ```
396
+
397
+ ### React Native
398
+
399
+ - Native components render directly
400
+ - No additional bundler configuration needed
401
+ - Full gesture support via `Pressable`
402
+ - Metro bundler resolves `react-native` imports automatically
403
+
404
+ ## Testing
405
+
406
+ The library uses Vitest + React Testing Library for comprehensive testing:
407
+
408
+ ```bash
409
+ cd packages/components
410
+ npm test # Run tests in watch mode
411
+ npm run test:run # Run tests once
412
+ npm run test:coverage # Generate coverage report
413
+ ```
414
+
415
+ **Test Setup:**
416
+
417
+ - Environment: `jsdom` (browser simulation)
418
+ - Alias: `react-native` → `react-native-web` for web compatibility
419
+ - Coverage: 90% threshold (branches, functions, lines, statements)
420
+
421
+ **Example Test:**
422
+
423
+ ```tsx
424
+ import { render, fireEvent } from '@testing-library/react';
425
+ import { Button, NewtoneProvider } from '@newtone/components';
426
+
427
+ it('calls onPress when clicked', () => {
428
+ const onPress = vi.fn();
429
+ const { getByText } = render(
430
+ <NewtoneProvider>
431
+ <Button onPress={onPress}>Click me</Button>
432
+ </NewtoneProvider>
433
+ );
434
+
435
+ fireEvent.click(getByText('Click me'));
436
+ expect(onPress).toHaveBeenCalledTimes(1);
437
+ });
438
+ ```
439
+
440
+ ## TypeScript
441
+
442
+ All types are exported for consumer applications:
443
+
444
+ ```tsx
445
+ import type {
446
+ // Components
447
+ ButtonProps,
448
+ ButtonVariant,
449
+ ButtonSize,
450
+
451
+ // Theme System
452
+ ColorMode,
453
+ ThemeName,
454
+ ElevationLevel,
455
+ ThemeMapping,
456
+ ColorSystemConfig,
457
+ NewtoneThemeConfig,
458
+ NewtoneThemeContext,
459
+
460
+ // Tokens
461
+ ResolvedTokens,
462
+
463
+ // Engine (re-exported from newtone)
464
+ DynamicRange,
465
+ PaletteConfig,
466
+ ColorResult,
467
+ Srgb,
468
+ Oklch,
469
+ HexColor,
470
+ } from '@newtone/components';
471
+ ```
472
+
473
+ ## Roadmap
474
+
475
+ ### Phase 1 (Complete) ✅
476
+ - [x] Monorepo setup with npm workspaces
477
+ - [x] Theme system (NewtoneProvider, useNewtoneTheme)
478
+ - [x] Runtime token computation (useTokens)
479
+ - [x] Button component (4 variants, 3 sizes)
480
+ - [x] Comprehensive test suite (48 tests)
481
+ - [x] Documentation
482
+
483
+ ### Phase 2 (Planned)
484
+ - [ ] Build-time token generation (W3C Design Tokens JSON)
485
+ - [ ] CSS variable export for web
486
+ - [ ] Platform-specific token formats (iOS, Android)
487
+ - [ ] Additional components (Input, Card, Modal, etc.)
488
+ - [ ] Storybook integration
489
+ - [ ] Visual regression testing
490
+ - [ ] Performance benchmarks
491
+
492
+ ## Contributing
493
+
494
+ This library is part of the [Newtone](https://github.com/joshuaallenmx/newtone) project. Please refer to the main repository for contribution guidelines.
495
+
496
+ ## License
497
+
498
+ MIT
499
+
500
+ ## Support
501
+
502
+ For issues, questions, or feature requests, please open an issue in the main [Newtone repository](https://github.com/joshuaallenmx/newtone/issues).
503
+
504
+ ---
505
+
506
+ Built with ❤️ by the Newtone team
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import type { ButtonProps } from './Button.types';
3
+ /**
4
+ * Button component with support for multiple variants and sizes.
5
+ *
6
+ * Automatically adapts to the current theme and mode from NewtoneProvider.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * <Button variant="primary" size="md" onPress={() => console.log('Pressed')}>
11
+ * Click me
12
+ * </Button>
13
+ * ```
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <Button variant="outline" size="lg" disabled>
18
+ * Disabled button
19
+ * </Button>
20
+ * ```
21
+ */
22
+ export declare function Button({ children, variant, size, disabled, style, textStyle, ...pressableProps }: ButtonProps): React.JSX.Element;
23
+ //# sourceMappingURL=Button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/Button/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,OAAmB,EACnB,IAAW,EACX,QAAgB,EAChB,KAAK,EACL,SAAS,EACT,GAAG,cAAc,EAClB,EAAE,WAAW,qBAiCb"}
@@ -0,0 +1,39 @@
1
+ import type { ResolvedTokens } from '../tokens/types';
2
+ import type { ButtonVariant, ButtonSize } from './Button.types';
3
+ /**
4
+ * Compute button styles based on tokens, variant, size, and state
5
+ *
6
+ * @param tokens - Resolved design tokens from useTokens
7
+ * @param variant - Button variant (primary, secondary, ghost, outline)
8
+ * @param size - Button size (sm, md, lg)
9
+ * @param disabled - Whether button is disabled
10
+ * @returns StyleSheet with button styles
11
+ */
12
+ export declare function getButtonStyles(tokens: ResolvedTokens, variant: ButtonVariant, size: ButtonSize, disabled: boolean): {
13
+ base: {
14
+ borderColor?: string | undefined;
15
+ backgroundColor: string;
16
+ borderWidth: number;
17
+ paddingVertical: 6 | 10 | 14;
18
+ paddingHorizontal: 12 | 20 | 28;
19
+ borderRadius: 8 | 4 | 6;
20
+ alignItems: "center";
21
+ justifyContent: "center";
22
+ flexDirection: "row";
23
+ };
24
+ pressed: {
25
+ backgroundColor: string;
26
+ opacity: number;
27
+ };
28
+ disabled: {
29
+ opacity: number;
30
+ };
31
+ text: {
32
+ fontSize: 12 | 14 | 16;
33
+ fontWeight: "600";
34
+ color: string;
35
+ };
36
+ textPressed: {};
37
+ textDisabled: {};
38
+ };
39
+ //# sourceMappingURL=Button.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.styles.d.ts","sourceRoot":"","sources":["../../src/Button/Button.styles.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAWhE;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;EAwElB"}
@@ -0,0 +1,42 @@
1
+ import type { PressableProps, ViewStyle, TextStyle } from 'react-native';
2
+ /**
3
+ * Visual variants for the Button component
4
+ */
5
+ export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'outline';
6
+ /**
7
+ * Size presets for the Button component
8
+ */
9
+ export type ButtonSize = 'sm' | 'md' | 'lg';
10
+ /**
11
+ * Props for the Button component
12
+ */
13
+ export interface ButtonProps extends Omit<PressableProps, 'children' | 'style'> {
14
+ /**
15
+ * Button text or custom content
16
+ */
17
+ readonly children: React.ReactNode;
18
+ /**
19
+ * Visual variant
20
+ * @default 'primary'
21
+ */
22
+ readonly variant?: ButtonVariant;
23
+ /**
24
+ * Size preset
25
+ * @default 'md'
26
+ */
27
+ readonly size?: ButtonSize;
28
+ /**
29
+ * Disabled state
30
+ * @default false
31
+ */
32
+ readonly disabled?: boolean;
33
+ /**
34
+ * Custom style overrides for container
35
+ */
36
+ readonly style?: ViewStyle | ViewStyle[];
37
+ /**
38
+ * Custom style overrides for text
39
+ */
40
+ readonly textStyle?: TextStyle | TextStyle[];
41
+ }
42
+ //# sourceMappingURL=Button.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.types.d.ts","sourceRoot":"","sources":["../../src/Button/Button.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;AAE1E;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,OAAO,CAAC;IAC7E;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAEnC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;IAE3B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAEzC;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;CAC9C"}
@@ -0,0 +1,3 @@
1
+ export { Button } from './Button';
2
+ export type { ButtonProps, ButtonVariant, ButtonSize } from './Button.types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Button/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { CardProps } from './Card.types';
3
+ export declare function Card({ children, elevation, style, disabled, }: CardProps): React.JSX.Element;
4
+ //# sourceMappingURL=Card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../src/Card/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,SAAa,EACb,KAAK,EACL,QAAgB,GACjB,EAAE,SAAS,qBAaX"}
@@ -0,0 +1,12 @@
1
+ import type { ResolvedTokens } from '../tokens/types';
2
+ export declare function getCardStyles(tokens: ResolvedTokens, disabled: boolean): {
3
+ container: {
4
+ backgroundColor: string;
5
+ borderWidth: number;
6
+ borderColor: string;
7
+ borderRadius: number;
8
+ padding: number;
9
+ opacity: number;
10
+ };
11
+ };
12
+ //# sourceMappingURL=Card.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.styles.d.ts","sourceRoot":"","sources":["../../src/Card/Card.styles.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO;;;;;;;;;EAWtE"}
@@ -0,0 +1,9 @@
1
+ import type { ViewStyle } from 'react-native';
2
+ import type { ElevationLevel } from '../theme/types';
3
+ export interface CardProps {
4
+ readonly children: React.ReactNode;
5
+ readonly elevation?: ElevationLevel;
6
+ readonly style?: ViewStyle | ViewStyle[];
7
+ readonly disabled?: boolean;
8
+ }
9
+ //# sourceMappingURL=Card.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.types.d.ts","sourceRoot":"","sources":["../../src/Card/Card.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B"}
@@ -0,0 +1,3 @@
1
+ export { Card } from './Card';
2
+ export type { CardProps } from './Card.types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Card/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import type { HueSliderProps } from './HueSlider.types';
3
+ /**
4
+ * Hue slider with rainbow gradient track.
5
+ *
6
+ * Value range: 0-359 (traditional color wheel hue).
7
+ * 0=red, 60=yellow, 120=green, 180=cyan, 240=blue, 300=magenta.
8
+ *
9
+ * Optional min/max constrain the selectable range.
10
+ * For wrapping ranges (e.g. red: min=345 max=375), max may exceed 359;
11
+ * the returned value is always normalized to [0, 359].
12
+ */
13
+ export declare function HueSlider({ value, onValueChange, min, max, label, showValue, disabled, style, }: HueSliderProps): React.JSX.Element;
14
+ //# sourceMappingURL=HueSlider.d.ts.map