@rajeev02/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @rajeev02/ui - Device Detection
3
+ *
4
+ * Detect device type, capabilities, input mode, and accessibility
5
+ * settings to drive adaptive UI rendering.
6
+ */
7
+ export type DeviceType = 'phone' | 'tablet' | 'watch' | 'tv' | 'auto' | 'desktop' | 'iot';
8
+ export type InputMode = 'touch' | 'keyboard' | 'voice' | 'rotary' | 'dpad' | 'controller';
9
+ export interface DeviceCapabilities {
10
+ /** Device type */
11
+ type: DeviceType;
12
+ /** Screen width in dp/px */
13
+ screenWidth: number;
14
+ /** Screen height in dp/px */
15
+ screenHeight: number;
16
+ /** Primary input mode */
17
+ inputMode: InputMode;
18
+ /** Whether haptic feedback is available */
19
+ haptics: boolean;
20
+ /** Whether biometric auth is available */
21
+ biometrics: boolean;
22
+ /** Whether the device has a notch/dynamic island */
23
+ hasNotch: boolean;
24
+ /** Device pixel ratio */
25
+ pixelRatio: number;
26
+ /** Whether the device supports dark mode */
27
+ darkModeSupported: boolean;
28
+ /** Whether reduce motion is enabled */
29
+ reduceMotion: boolean;
30
+ /** Whether a screen reader is active */
31
+ screenReaderActive: boolean;
32
+ /** Font scale set by user */
33
+ fontScale: number;
34
+ /** Whether the device is low-end (for performance optimization) */
35
+ isLowEnd: boolean;
36
+ }
37
+ /**
38
+ * Detect device type from screen dimensions
39
+ */
40
+ export declare function detectDeviceType(width: number, height: number): DeviceType;
41
+ /**
42
+ * Get default capabilities for a device type
43
+ */
44
+ export declare function getDefaultCapabilities(type: DeviceType): DeviceCapabilities;
45
+ /**
46
+ * Determine if device is "low-end" based on characteristics
47
+ * Used to disable animations, reduce image quality, simplify UI
48
+ */
49
+ export declare function isLowEndDevice(totalRamMB?: number, pixelRatio?: number): boolean;
50
+ /**
51
+ * Get recommended touch target size for device type
52
+ * Follows WCAG 2.5.8 (44x44 minimum for mobile)
53
+ */
54
+ export declare function getMinTouchTarget(type: DeviceType): number;
55
+ /**
56
+ * Get recommended font size multiplier for device type
57
+ */
58
+ export declare function getFontMultiplier(type: DeviceType, fontScale?: number): number;
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/device/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC;AAC1F,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAC;AAE1F,MAAM,WAAW,kBAAkB;IACjC,kBAAkB;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,0CAA0C;IAC1C,UAAU,EAAE,OAAO,CAAC;IACpB,oDAAoD;IACpD,QAAQ,EAAE,OAAO,CAAC;IAClB,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uCAAuC;IACvC,YAAY,EAAE,OAAO,CAAC;IACtB,wCAAwC;IACxC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAS1E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,GAAG,kBAAkB,CA2B3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAIhF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAW1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,GAAE,MAAY,GAAG,MAAM,CAWnF"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /**
3
+ * @rajeev02/ui - Device Detection
4
+ *
5
+ * Detect device type, capabilities, input mode, and accessibility
6
+ * settings to drive adaptive UI rendering.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.detectDeviceType = detectDeviceType;
10
+ exports.getDefaultCapabilities = getDefaultCapabilities;
11
+ exports.isLowEndDevice = isLowEndDevice;
12
+ exports.getMinTouchTarget = getMinTouchTarget;
13
+ exports.getFontMultiplier = getFontMultiplier;
14
+ /**
15
+ * Detect device type from screen dimensions
16
+ */
17
+ function detectDeviceType(width, height) {
18
+ const minDim = Math.min(width, height);
19
+ const maxDim = Math.max(width, height);
20
+ if (minDim < 200)
21
+ return 'watch';
22
+ if (minDim < 600 && maxDim < 1000)
23
+ return 'phone';
24
+ if (minDim >= 600 && maxDim < 1400)
25
+ return 'tablet';
26
+ if (minDim >= 1400)
27
+ return 'tv';
28
+ return 'phone'; // Default
29
+ }
30
+ /**
31
+ * Get default capabilities for a device type
32
+ */
33
+ function getDefaultCapabilities(type) {
34
+ const defaults = {
35
+ phone: { screenWidth: 390, screenHeight: 844, inputMode: 'touch', haptics: true, pixelRatio: 3, hasNotch: true },
36
+ tablet: { screenWidth: 820, screenHeight: 1180, inputMode: 'touch', haptics: true, pixelRatio: 2, hasNotch: false },
37
+ watch: { screenWidth: 184, screenHeight: 224, inputMode: 'touch', haptics: true, pixelRatio: 2, hasNotch: false },
38
+ tv: { screenWidth: 1920, screenHeight: 1080, inputMode: 'dpad', haptics: false, pixelRatio: 1, hasNotch: false },
39
+ auto: { screenWidth: 1280, screenHeight: 720, inputMode: 'touch', haptics: true, pixelRatio: 2, hasNotch: false },
40
+ desktop: { screenWidth: 1440, screenHeight: 900, inputMode: 'keyboard', haptics: false, pixelRatio: 2, hasNotch: false },
41
+ iot: { screenWidth: 320, screenHeight: 240, inputMode: 'touch', haptics: false, pixelRatio: 1, hasNotch: false },
42
+ };
43
+ return {
44
+ type,
45
+ screenWidth: 390,
46
+ screenHeight: 844,
47
+ inputMode: 'touch',
48
+ haptics: false,
49
+ biometrics: false,
50
+ hasNotch: false,
51
+ pixelRatio: 2,
52
+ darkModeSupported: true,
53
+ reduceMotion: false,
54
+ screenReaderActive: false,
55
+ fontScale: 1.0,
56
+ isLowEnd: false,
57
+ ...defaults[type],
58
+ };
59
+ }
60
+ /**
61
+ * Determine if device is "low-end" based on characteristics
62
+ * Used to disable animations, reduce image quality, simplify UI
63
+ */
64
+ function isLowEndDevice(totalRamMB, pixelRatio) {
65
+ if (totalRamMB && totalRamMB < 2048)
66
+ return true; // < 2GB RAM
67
+ if (pixelRatio && pixelRatio < 1.5)
68
+ return true;
69
+ return false;
70
+ }
71
+ /**
72
+ * Get recommended touch target size for device type
73
+ * Follows WCAG 2.5.8 (44x44 minimum for mobile)
74
+ */
75
+ function getMinTouchTarget(type) {
76
+ switch (type) {
77
+ case 'watch': return 38; // Smaller screen, slightly smaller targets
78
+ case 'phone': return 44; // WCAG standard
79
+ case 'tablet': return 44;
80
+ case 'tv': return 56; // Larger for distance viewing with remote
81
+ case 'auto': return 56; // Larger for driving safety
82
+ case 'desktop': return 32; // Mouse is more precise
83
+ case 'iot': return 44;
84
+ default: return 44;
85
+ }
86
+ }
87
+ /**
88
+ * Get recommended font size multiplier for device type
89
+ */
90
+ function getFontMultiplier(type, fontScale = 1.0) {
91
+ const baseMultiplier = {
92
+ watch: 0.85,
93
+ phone: 1.0,
94
+ tablet: 1.1,
95
+ tv: 1.8, // Much larger for 10-foot UI
96
+ auto: 1.4, // Larger for glance-ability
97
+ desktop: 1.0,
98
+ iot: 0.9,
99
+ };
100
+ return (baseMultiplier[type] ?? 1.0) * fontScale;
101
+ }
102
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/device/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @rajeev02/ui - React Hooks
3
+ *
4
+ * Hooks for device-aware rendering, theming, and accessibility.
5
+ */
6
+ import type { DeviceType, InputMode } from '../device';
7
+ import type { ThemeMode } from '../tokens';
8
+ /**
9
+ * Hook return type for useDevice
10
+ */
11
+ export interface UseDeviceResult {
12
+ type: DeviceType;
13
+ isPhone: boolean;
14
+ isTablet: boolean;
15
+ isWatch: boolean;
16
+ isTv: boolean;
17
+ isAuto: boolean;
18
+ isDesktop: boolean;
19
+ inputMode: InputMode;
20
+ isLowEnd: boolean;
21
+ screenWidth: number;
22
+ screenHeight: number;
23
+ fontScale: number;
24
+ pixelRatio: number;
25
+ }
26
+ /**
27
+ * Hook return type for useAccessibility
28
+ */
29
+ export interface UseAccessibilityResult {
30
+ screenReaderActive: boolean;
31
+ reduceMotion: boolean;
32
+ fontScale: number;
33
+ highContrast: boolean;
34
+ /** Minimum touch target size for current device */
35
+ minTouchTarget: number;
36
+ /** Whether to show large text */
37
+ largeText: boolean;
38
+ }
39
+ /**
40
+ * Hook return type for useTheme
41
+ */
42
+ export interface UseThemeResult {
43
+ mode: ThemeMode;
44
+ colors: Record<string, unknown>;
45
+ spacing: Record<string, number>;
46
+ isDark: boolean;
47
+ isHighContrast: boolean;
48
+ }
49
+ /**
50
+ * Adaptive layout props — define different content per device type
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * <AdaptiveLayout
55
+ * phone={<PhoneView />}
56
+ * tablet={<TabletView />}
57
+ * watch={<WatchView />}
58
+ * tv={<TvView />}
59
+ * auto={<AutoView />}
60
+ * />
61
+ * ```
62
+ */
63
+ export interface AdaptiveLayoutProps {
64
+ phone?: unknown;
65
+ tablet?: unknown;
66
+ watch?: unknown;
67
+ tv?: unknown;
68
+ auto?: unknown;
69
+ desktop?: unknown;
70
+ /** Fallback if specific device view not provided */
71
+ fallback?: unknown;
72
+ }
73
+ /**
74
+ * Get the appropriate content for the current device type
75
+ */
76
+ export declare function resolveAdaptiveContent(props: AdaptiveLayoutProps, deviceType: DeviceType): unknown;
77
+ /**
78
+ * Responsive value helper — pick value based on screen width
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * const padding = responsive(screenWidth, {
83
+ * watch: 4,
84
+ * phone: 16,
85
+ * tablet: 24,
86
+ * desktop: 32,
87
+ * });
88
+ * ```
89
+ */
90
+ export declare function responsive<T>(screenWidth: number, values: Partial<Record<DeviceType, T>> & {
91
+ phone: T;
92
+ }): T;
93
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAsB,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,mDAAmD;IACnD,cAAc,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,mBAAmB,EAC1B,UAAU,EAAE,UAAU,GACrB,OAAO,CAYT;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,GACpD,CAAC,CAMH"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * @rajeev02/ui - React Hooks
4
+ *
5
+ * Hooks for device-aware rendering, theming, and accessibility.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.resolveAdaptiveContent = resolveAdaptiveContent;
9
+ exports.responsive = responsive;
10
+ /**
11
+ * Get the appropriate content for the current device type
12
+ */
13
+ function resolveAdaptiveContent(props, deviceType) {
14
+ const map = {
15
+ phone: props.phone,
16
+ tablet: props.tablet ?? props.phone, // Tablet falls back to phone
17
+ watch: props.watch,
18
+ tv: props.tv ?? props.tablet ?? props.phone, // TV falls back to tablet then phone
19
+ auto: props.auto ?? props.phone,
20
+ desktop: props.desktop ?? props.tablet ?? props.phone,
21
+ iot: props.phone,
22
+ };
23
+ return map[deviceType] ?? props.fallback ?? props.phone;
24
+ }
25
+ /**
26
+ * Responsive value helper — pick value based on screen width
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const padding = responsive(screenWidth, {
31
+ * watch: 4,
32
+ * phone: 16,
33
+ * tablet: 24,
34
+ * desktop: 32,
35
+ * });
36
+ * ```
37
+ */
38
+ function responsive(screenWidth, values) {
39
+ if (screenWidth < 200 && values.watch !== undefined)
40
+ return values.watch;
41
+ if (screenWidth < 600)
42
+ return values.phone;
43
+ if (screenWidth < 1024 && values.tablet !== undefined)
44
+ return values.tablet;
45
+ if (values.desktop !== undefined)
46
+ return values.desktop;
47
+ return values.phone;
48
+ }
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAiFH,wDAeC;AAeD,gCASC;AA1CD;;GAEG;AACH,SAAgB,sBAAsB,CACpC,KAA0B,EAC1B,UAAsB;IAEtB,MAAM,GAAG,GAA4B;QACnC,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,EAAO,6BAA6B;QACvE,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,EAAG,qCAAqC;QACnF,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK;QAC/B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK;QACrD,GAAG,EAAE,KAAK,CAAC,KAAK;KACjB,CAAC;IAEF,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC;AAC1D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,UAAU,CACxB,WAAmB,EACnB,MAAqD;IAErD,IAAI,WAAW,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IACzE,IAAI,WAAW,GAAG,GAAG;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IAC3C,IAAI,WAAW,GAAG,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC;IAC5E,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC;IACxD,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @rajeev02/ui
3
+ *
4
+ * Adaptive UI Component System
5
+ * Device-aware rendering for phone, tablet, watch, TV, auto, IoT
6
+ *
7
+ * @author Rajeev Kumar Joshi (https://github.com/Rajeev02)
8
+ * @license MIT
9
+ */
10
+ export { colors, spacing, typography, breakpoints, borderRadius, shadows, highContrast, getTheme, } from './tokens';
11
+ export type { ThemeMode } from './tokens';
12
+ export { detectDeviceType, getDefaultCapabilities, isLowEndDevice, getMinTouchTarget, getFontMultiplier, } from './device';
13
+ export type { DeviceType, InputMode, DeviceCapabilities } from './device';
14
+ export { resolveAdaptiveContent, responsive, } from './hooks';
15
+ export type { UseDeviceResult, UseAccessibilityResult, UseThemeResult, AdaptiveLayoutProps, } from './hooks';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EACL,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAC/D,YAAY,EAAE,QAAQ,GACvB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,OAAO,EACL,gBAAgB,EAAE,sBAAsB,EAAE,cAAc,EACxD,iBAAiB,EAAE,iBAAiB,GACrC,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG1E,OAAO,EACL,sBAAsB,EAAE,UAAU,GACnC,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,eAAe,EAAE,sBAAsB,EAAE,cAAc,EACvD,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * @rajeev02/ui
4
+ *
5
+ * Adaptive UI Component System
6
+ * Device-aware rendering for phone, tablet, watch, TV, auto, IoT
7
+ *
8
+ * @author Rajeev Kumar Joshi (https://github.com/Rajeev02)
9
+ * @license MIT
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.responsive = exports.resolveAdaptiveContent = exports.getFontMultiplier = exports.getMinTouchTarget = exports.isLowEndDevice = exports.getDefaultCapabilities = exports.detectDeviceType = exports.getTheme = exports.highContrast = exports.shadows = exports.borderRadius = exports.breakpoints = exports.typography = exports.spacing = exports.colors = void 0;
13
+ // Design Tokens
14
+ var tokens_1 = require("./tokens");
15
+ Object.defineProperty(exports, "colors", { enumerable: true, get: function () { return tokens_1.colors; } });
16
+ Object.defineProperty(exports, "spacing", { enumerable: true, get: function () { return tokens_1.spacing; } });
17
+ Object.defineProperty(exports, "typography", { enumerable: true, get: function () { return tokens_1.typography; } });
18
+ Object.defineProperty(exports, "breakpoints", { enumerable: true, get: function () { return tokens_1.breakpoints; } });
19
+ Object.defineProperty(exports, "borderRadius", { enumerable: true, get: function () { return tokens_1.borderRadius; } });
20
+ Object.defineProperty(exports, "shadows", { enumerable: true, get: function () { return tokens_1.shadows; } });
21
+ Object.defineProperty(exports, "highContrast", { enumerable: true, get: function () { return tokens_1.highContrast; } });
22
+ Object.defineProperty(exports, "getTheme", { enumerable: true, get: function () { return tokens_1.getTheme; } });
23
+ // Device Detection
24
+ var device_1 = require("./device");
25
+ Object.defineProperty(exports, "detectDeviceType", { enumerable: true, get: function () { return device_1.detectDeviceType; } });
26
+ Object.defineProperty(exports, "getDefaultCapabilities", { enumerable: true, get: function () { return device_1.getDefaultCapabilities; } });
27
+ Object.defineProperty(exports, "isLowEndDevice", { enumerable: true, get: function () { return device_1.isLowEndDevice; } });
28
+ Object.defineProperty(exports, "getMinTouchTarget", { enumerable: true, get: function () { return device_1.getMinTouchTarget; } });
29
+ Object.defineProperty(exports, "getFontMultiplier", { enumerable: true, get: function () { return device_1.getFontMultiplier; } });
30
+ // Hooks & Adaptive Layout
31
+ var hooks_1 = require("./hooks");
32
+ Object.defineProperty(exports, "resolveAdaptiveContent", { enumerable: true, get: function () { return hooks_1.resolveAdaptiveContent; } });
33
+ Object.defineProperty(exports, "responsive", { enumerable: true, get: function () { return hooks_1.responsive; } });
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,gBAAgB;AAChB,mCAGkB;AAFhB,gGAAA,MAAM,OAAA;AAAE,iGAAA,OAAO,OAAA;AAAE,oGAAA,UAAU,OAAA;AAAE,qGAAA,WAAW,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,iGAAA,OAAO,OAAA;AAC/D,sGAAA,YAAY,OAAA;AAAE,kGAAA,QAAQ,OAAA;AAIxB,mBAAmB;AACnB,mCAGkB;AAFhB,0GAAA,gBAAgB,OAAA;AAAE,gHAAA,sBAAsB,OAAA;AAAE,wGAAA,cAAc,OAAA;AACxD,2GAAA,iBAAiB,OAAA;AAAE,2GAAA,iBAAiB,OAAA;AAItC,0BAA0B;AAC1B,iCAEiB;AADf,+GAAA,sBAAsB,OAAA;AAAE,mGAAA,UAAU,OAAA"}
@@ -0,0 +1,331 @@
1
+ /**
2
+ * @rajeev02/ui - Design Tokens
3
+ *
4
+ * Centralized design system tokens for consistent theming
5
+ * across phone, tablet, watch, TV, and auto interfaces.
6
+ */
7
+ export declare const colors: {
8
+ readonly primary: {
9
+ readonly 50: "#EEF2FF";
10
+ readonly 100: "#E0E7FF";
11
+ readonly 200: "#C7D2FE";
12
+ readonly 300: "#A5B4FC";
13
+ readonly 400: "#818CF8";
14
+ readonly 500: "#6366F1";
15
+ readonly 600: "#4F46E5";
16
+ readonly 700: "#4338CA";
17
+ readonly 800: "#3730A3";
18
+ readonly 900: "#312E81";
19
+ };
20
+ readonly accent: {
21
+ readonly 50: "#FFF7ED";
22
+ readonly 100: "#FFEDD5";
23
+ readonly 200: "#FED7AA";
24
+ readonly 300: "#FDBA74";
25
+ readonly 400: "#FB923C";
26
+ readonly 500: "#F97316";
27
+ readonly 600: "#EA580C";
28
+ readonly 700: "#C2410C";
29
+ readonly 800: "#9A3412";
30
+ readonly 900: "#7C2D12";
31
+ };
32
+ readonly success: "#10B981";
33
+ readonly warning: "#F59E0B";
34
+ readonly error: "#EF4444";
35
+ readonly info: "#3B82F6";
36
+ readonly text: {
37
+ readonly primary: "#111827";
38
+ readonly secondary: "#6B7280";
39
+ readonly disabled: "#9CA3AF";
40
+ readonly inverse: "#FFFFFF";
41
+ };
42
+ readonly background: {
43
+ readonly primary: "#FFFFFF";
44
+ readonly secondary: "#F9FAFB";
45
+ readonly tertiary: "#F3F4F6";
46
+ };
47
+ readonly border: {
48
+ readonly light: "#E5E7EB";
49
+ readonly medium: "#D1D5DB";
50
+ readonly dark: "#9CA3AF";
51
+ };
52
+ };
53
+ export declare const spacing: {
54
+ readonly xxs: 2;
55
+ readonly xs: 4;
56
+ readonly sm: 8;
57
+ readonly md: 12;
58
+ readonly lg: 16;
59
+ readonly xl: 24;
60
+ readonly xxl: 32;
61
+ readonly xxxl: 48;
62
+ };
63
+ export declare const typography: {
64
+ readonly fontFamily: {
65
+ readonly sans: "System, -apple-system, \"Noto Sans\", \"Noto Sans Devanagari\", \"Noto Sans Bengali\", \"Noto Sans Tamil\", sans-serif";
66
+ readonly mono: "\"SF Mono\", \"Roboto Mono\", \"Noto Sans Mono\", monospace";
67
+ };
68
+ readonly fontSize: {
69
+ readonly xs: 10;
70
+ readonly sm: 12;
71
+ readonly base: 14;
72
+ readonly md: 16;
73
+ readonly lg: 18;
74
+ readonly xl: 20;
75
+ readonly '2xl': 24;
76
+ readonly '3xl': 30;
77
+ readonly '4xl': 36;
78
+ };
79
+ readonly lineHeight: {
80
+ readonly tight: 1.2;
81
+ readonly normal: 1.5;
82
+ readonly relaxed: 1.75;
83
+ readonly loose: 2;
84
+ };
85
+ readonly fontWeight: {
86
+ readonly regular: "400";
87
+ readonly medium: "500";
88
+ readonly semibold: "600";
89
+ readonly bold: "700";
90
+ };
91
+ };
92
+ export declare const breakpoints: {
93
+ /** Watch: < 200px */
94
+ readonly watch: 200;
95
+ /** Phone: 200-599px */
96
+ readonly phone: 600;
97
+ /** Tablet: 600-1023px */
98
+ readonly tablet: 1024;
99
+ /** Desktop/TV: >= 1024px */
100
+ readonly desktop: 1024;
101
+ };
102
+ export declare const borderRadius: {
103
+ readonly none: 0;
104
+ readonly sm: 4;
105
+ readonly md: 8;
106
+ readonly lg: 12;
107
+ readonly xl: 16;
108
+ readonly full: 9999;
109
+ };
110
+ export declare const shadows: {
111
+ readonly sm: {
112
+ readonly shadowColor: "#000";
113
+ readonly shadowOffset: {
114
+ readonly width: 0;
115
+ readonly height: 1;
116
+ };
117
+ readonly shadowOpacity: 0.05;
118
+ readonly shadowRadius: 2;
119
+ readonly elevation: 1;
120
+ };
121
+ readonly md: {
122
+ readonly shadowColor: "#000";
123
+ readonly shadowOffset: {
124
+ readonly width: 0;
125
+ readonly height: 2;
126
+ };
127
+ readonly shadowOpacity: 0.1;
128
+ readonly shadowRadius: 4;
129
+ readonly elevation: 3;
130
+ };
131
+ readonly lg: {
132
+ readonly shadowColor: "#000";
133
+ readonly shadowOffset: {
134
+ readonly width: 0;
135
+ readonly height: 4;
136
+ };
137
+ readonly shadowOpacity: 0.15;
138
+ readonly shadowRadius: 8;
139
+ readonly elevation: 5;
140
+ };
141
+ };
142
+ /** Accessibility-focused high contrast palette */
143
+ export declare const highContrast: {
144
+ readonly text: {
145
+ readonly primary: "#000000";
146
+ readonly secondary: "#333333";
147
+ readonly inverse: "#FFFFFF";
148
+ };
149
+ readonly background: {
150
+ readonly primary: "#FFFFFF";
151
+ readonly secondary: "#F0F0F0";
152
+ };
153
+ readonly border: {
154
+ readonly light: "#666666";
155
+ readonly medium: "#333333";
156
+ };
157
+ readonly focus: "#0055FF";
158
+ };
159
+ export type ThemeMode = 'light' | 'dark' | 'highContrast';
160
+ /** Get complete theme based on mode */
161
+ export declare function getTheme(mode: ThemeMode): {
162
+ colors: {
163
+ readonly primary: {
164
+ readonly 50: "#EEF2FF";
165
+ readonly 100: "#E0E7FF";
166
+ readonly 200: "#C7D2FE";
167
+ readonly 300: "#A5B4FC";
168
+ readonly 400: "#818CF8";
169
+ readonly 500: "#6366F1";
170
+ readonly 600: "#4F46E5";
171
+ readonly 700: "#4338CA";
172
+ readonly 800: "#3730A3";
173
+ readonly 900: "#312E81";
174
+ };
175
+ readonly accent: {
176
+ readonly 50: "#FFF7ED";
177
+ readonly 100: "#FFEDD5";
178
+ readonly 200: "#FED7AA";
179
+ readonly 300: "#FDBA74";
180
+ readonly 400: "#FB923C";
181
+ readonly 500: "#F97316";
182
+ readonly 600: "#EA580C";
183
+ readonly 700: "#C2410C";
184
+ readonly 800: "#9A3412";
185
+ readonly 900: "#7C2D12";
186
+ };
187
+ readonly success: "#10B981";
188
+ readonly warning: "#F59E0B";
189
+ readonly error: "#EF4444";
190
+ readonly info: "#3B82F6";
191
+ readonly text: {
192
+ readonly primary: "#111827";
193
+ readonly secondary: "#6B7280";
194
+ readonly disabled: "#9CA3AF";
195
+ readonly inverse: "#FFFFFF";
196
+ };
197
+ readonly background: {
198
+ readonly primary: "#FFFFFF";
199
+ readonly secondary: "#F9FAFB";
200
+ readonly tertiary: "#F3F4F6";
201
+ };
202
+ readonly border: {
203
+ readonly light: "#E5E7EB";
204
+ readonly medium: "#D1D5DB";
205
+ readonly dark: "#9CA3AF";
206
+ };
207
+ } | {
208
+ text: {
209
+ readonly primary: "#000000";
210
+ readonly secondary: "#333333";
211
+ readonly inverse: "#FFFFFF";
212
+ };
213
+ background: {
214
+ readonly primary: "#FFFFFF";
215
+ readonly secondary: "#F0F0F0";
216
+ };
217
+ border: {
218
+ readonly light: "#666666";
219
+ readonly medium: "#333333";
220
+ };
221
+ primary: {
222
+ readonly 50: "#EEF2FF";
223
+ readonly 100: "#E0E7FF";
224
+ readonly 200: "#C7D2FE";
225
+ readonly 300: "#A5B4FC";
226
+ readonly 400: "#818CF8";
227
+ readonly 500: "#6366F1";
228
+ readonly 600: "#4F46E5";
229
+ readonly 700: "#4338CA";
230
+ readonly 800: "#3730A3";
231
+ readonly 900: "#312E81";
232
+ };
233
+ accent: {
234
+ readonly 50: "#FFF7ED";
235
+ readonly 100: "#FFEDD5";
236
+ readonly 200: "#FED7AA";
237
+ readonly 300: "#FDBA74";
238
+ readonly 400: "#FB923C";
239
+ readonly 500: "#F97316";
240
+ readonly 600: "#EA580C";
241
+ readonly 700: "#C2410C";
242
+ readonly 800: "#9A3412";
243
+ readonly 900: "#7C2D12";
244
+ };
245
+ success: "#10B981";
246
+ warning: "#F59E0B";
247
+ error: "#EF4444";
248
+ info: "#3B82F6";
249
+ };
250
+ spacing: {
251
+ readonly xxs: 2;
252
+ readonly xs: 4;
253
+ readonly sm: 8;
254
+ readonly md: 12;
255
+ readonly lg: 16;
256
+ readonly xl: 24;
257
+ readonly xxl: 32;
258
+ readonly xxxl: 48;
259
+ };
260
+ typography: {
261
+ readonly fontFamily: {
262
+ readonly sans: "System, -apple-system, \"Noto Sans\", \"Noto Sans Devanagari\", \"Noto Sans Bengali\", \"Noto Sans Tamil\", sans-serif";
263
+ readonly mono: "\"SF Mono\", \"Roboto Mono\", \"Noto Sans Mono\", monospace";
264
+ };
265
+ readonly fontSize: {
266
+ readonly xs: 10;
267
+ readonly sm: 12;
268
+ readonly base: 14;
269
+ readonly md: 16;
270
+ readonly lg: 18;
271
+ readonly xl: 20;
272
+ readonly '2xl': 24;
273
+ readonly '3xl': 30;
274
+ readonly '4xl': 36;
275
+ };
276
+ readonly lineHeight: {
277
+ readonly tight: 1.2;
278
+ readonly normal: 1.5;
279
+ readonly relaxed: 1.75;
280
+ readonly loose: 2;
281
+ };
282
+ readonly fontWeight: {
283
+ readonly regular: "400";
284
+ readonly medium: "500";
285
+ readonly semibold: "600";
286
+ readonly bold: "700";
287
+ };
288
+ };
289
+ borderRadius: {
290
+ readonly none: 0;
291
+ readonly sm: 4;
292
+ readonly md: 8;
293
+ readonly lg: 12;
294
+ readonly xl: 16;
295
+ readonly full: 9999;
296
+ };
297
+ shadows: {
298
+ readonly sm: {
299
+ readonly shadowColor: "#000";
300
+ readonly shadowOffset: {
301
+ readonly width: 0;
302
+ readonly height: 1;
303
+ };
304
+ readonly shadowOpacity: 0.05;
305
+ readonly shadowRadius: 2;
306
+ readonly elevation: 1;
307
+ };
308
+ readonly md: {
309
+ readonly shadowColor: "#000";
310
+ readonly shadowOffset: {
311
+ readonly width: 0;
312
+ readonly height: 2;
313
+ };
314
+ readonly shadowOpacity: 0.1;
315
+ readonly shadowRadius: 4;
316
+ readonly elevation: 3;
317
+ };
318
+ readonly lg: {
319
+ readonly shadowColor: "#000";
320
+ readonly shadowOffset: {
321
+ readonly width: 0;
322
+ readonly height: 4;
323
+ };
324
+ readonly shadowOpacity: 0.15;
325
+ readonly shadowRadius: 8;
326
+ readonly elevation: 5;
327
+ };
328
+ };
329
+ mode: ThemeMode;
330
+ };
331
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAcT,CAAC;AAEX,eAAO,MAAM,OAAO;;;;;;;;;CASV,CAAC;AAEX,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+Bb,CAAC;AAEX,eAAO,MAAM,WAAW;IACtB,qBAAqB;;IAErB,uBAAuB;;IAEvB,yBAAyB;;IAEzB,4BAA4B;;CAEpB,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;;;CAOf,CAAC;AAEX,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAIV,CAAC;AAEX,kDAAkD;AAClD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;CAKf,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,cAAc,CAAC;AAE1D,uCAAuC;AACvC,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASvC"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ /**
3
+ * @rajeev02/ui - Design Tokens
4
+ *
5
+ * Centralized design system tokens for consistent theming
6
+ * across phone, tablet, watch, TV, and auto interfaces.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.highContrast = exports.shadows = exports.borderRadius = exports.breakpoints = exports.typography = exports.spacing = exports.colors = void 0;
10
+ exports.getTheme = getTheme;
11
+ exports.colors = {
12
+ // Primary palette
13
+ primary: { 50: '#EEF2FF', 100: '#E0E7FF', 200: '#C7D2FE', 300: '#A5B4FC', 400: '#818CF8', 500: '#6366F1', 600: '#4F46E5', 700: '#4338CA', 800: '#3730A3', 900: '#312E81' },
14
+ // Indian-friendly accent (saffron-inspired)
15
+ accent: { 50: '#FFF7ED', 100: '#FFEDD5', 200: '#FED7AA', 300: '#FDBA74', 400: '#FB923C', 500: '#F97316', 600: '#EA580C', 700: '#C2410C', 800: '#9A3412', 900: '#7C2D12' },
16
+ // Semantic
17
+ success: '#10B981',
18
+ warning: '#F59E0B',
19
+ error: '#EF4444',
20
+ info: '#3B82F6',
21
+ // Neutrals
22
+ text: { primary: '#111827', secondary: '#6B7280', disabled: '#9CA3AF', inverse: '#FFFFFF' },
23
+ background: { primary: '#FFFFFF', secondary: '#F9FAFB', tertiary: '#F3F4F6' },
24
+ border: { light: '#E5E7EB', medium: '#D1D5DB', dark: '#9CA3AF' },
25
+ };
26
+ exports.spacing = {
27
+ xxs: 2,
28
+ xs: 4,
29
+ sm: 8,
30
+ md: 12,
31
+ lg: 16,
32
+ xl: 24,
33
+ xxl: 32,
34
+ xxxl: 48,
35
+ };
36
+ exports.typography = {
37
+ // Font families with Indian script fallbacks
38
+ fontFamily: {
39
+ sans: 'System, -apple-system, "Noto Sans", "Noto Sans Devanagari", "Noto Sans Bengali", "Noto Sans Tamil", sans-serif',
40
+ mono: '"SF Mono", "Roboto Mono", "Noto Sans Mono", monospace',
41
+ },
42
+ // Size scale
43
+ fontSize: {
44
+ xs: 10,
45
+ sm: 12,
46
+ base: 14,
47
+ md: 16,
48
+ lg: 18,
49
+ xl: 20,
50
+ '2xl': 24,
51
+ '3xl': 30,
52
+ '4xl': 36,
53
+ },
54
+ // Line heights (slightly higher for Devanagari and other Indian scripts)
55
+ lineHeight: {
56
+ tight: 1.2,
57
+ normal: 1.5,
58
+ relaxed: 1.75, // Better for Indian scripts with diacritics
59
+ loose: 2.0,
60
+ },
61
+ fontWeight: {
62
+ regular: '400',
63
+ medium: '500',
64
+ semibold: '600',
65
+ bold: '700',
66
+ },
67
+ };
68
+ exports.breakpoints = {
69
+ /** Watch: < 200px */
70
+ watch: 200,
71
+ /** Phone: 200-599px */
72
+ phone: 600,
73
+ /** Tablet: 600-1023px */
74
+ tablet: 1024,
75
+ /** Desktop/TV: >= 1024px */
76
+ desktop: 1024,
77
+ };
78
+ exports.borderRadius = {
79
+ none: 0,
80
+ sm: 4,
81
+ md: 8,
82
+ lg: 12,
83
+ xl: 16,
84
+ full: 9999,
85
+ };
86
+ exports.shadows = {
87
+ sm: { shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.05, shadowRadius: 2, elevation: 1 },
88
+ md: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3 },
89
+ lg: { shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.15, shadowRadius: 8, elevation: 5 },
90
+ };
91
+ /** Accessibility-focused high contrast palette */
92
+ exports.highContrast = {
93
+ text: { primary: '#000000', secondary: '#333333', inverse: '#FFFFFF' },
94
+ background: { primary: '#FFFFFF', secondary: '#F0F0F0' },
95
+ border: { light: '#666666', medium: '#333333' },
96
+ focus: '#0055FF',
97
+ };
98
+ /** Get complete theme based on mode */
99
+ function getTheme(mode) {
100
+ return {
101
+ colors: mode === 'highContrast' ? { ...exports.colors, text: exports.highContrast.text, background: exports.highContrast.background, border: exports.highContrast.border } : exports.colors,
102
+ spacing: exports.spacing,
103
+ typography: exports.typography,
104
+ borderRadius: exports.borderRadius,
105
+ shadows: exports.shadows,
106
+ mode,
107
+ };
108
+ }
109
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@rajeev02/ui",
3
+ "version": "0.1.0",
4
+ "description": "Adaptive UI component system — device-aware rendering for phone, tablet, watch, TV, auto",
5
+ "main": "lib/index.js",
6
+ "author": "Rajeev Kumar Joshi <rajeevjoshi91@gmail.com> (https://rajeev02.github.io)",
7
+ "license": "MIT",
8
+ "types": "lib/index.d.ts",
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "clean": "rm -rf lib",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "keywords": [
15
+ "react-native",
16
+ "ui",
17
+ "design-tokens",
18
+ "adaptive",
19
+ "device-detection"
20
+ ],
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/Rajeev02/rajeev-sdk",
24
+ "directory": "packages/ui"
25
+ },
26
+ "homepage": "https://github.com/Rajeev02/rajeev-sdk#readme",
27
+ "bugs": {
28
+ "url": "https://github.com/Rajeev02/rajeev-sdk/issues"
29
+ },
30
+ "files": [
31
+ "lib/",
32
+ "src/",
33
+ "README.md"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "peerDependencies": {
39
+ "react": ">=18.3.0",
40
+ "react-native": ">=0.84.0"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "react-native": {
44
+ "optional": true
45
+ }
46
+ },
47
+ "devDependencies": {
48
+ "@types/react": "^19.0.0",
49
+ "typescript": "^5.4.0"
50
+ }
51
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * @rajeev02/ui - Device Detection
3
+ *
4
+ * Detect device type, capabilities, input mode, and accessibility
5
+ * settings to drive adaptive UI rendering.
6
+ */
7
+
8
+ export type DeviceType = 'phone' | 'tablet' | 'watch' | 'tv' | 'auto' | 'desktop' | 'iot';
9
+ export type InputMode = 'touch' | 'keyboard' | 'voice' | 'rotary' | 'dpad' | 'controller';
10
+
11
+ export interface DeviceCapabilities {
12
+ /** Device type */
13
+ type: DeviceType;
14
+ /** Screen width in dp/px */
15
+ screenWidth: number;
16
+ /** Screen height in dp/px */
17
+ screenHeight: number;
18
+ /** Primary input mode */
19
+ inputMode: InputMode;
20
+ /** Whether haptic feedback is available */
21
+ haptics: boolean;
22
+ /** Whether biometric auth is available */
23
+ biometrics: boolean;
24
+ /** Whether the device has a notch/dynamic island */
25
+ hasNotch: boolean;
26
+ /** Device pixel ratio */
27
+ pixelRatio: number;
28
+ /** Whether the device supports dark mode */
29
+ darkModeSupported: boolean;
30
+ /** Whether reduce motion is enabled */
31
+ reduceMotion: boolean;
32
+ /** Whether a screen reader is active */
33
+ screenReaderActive: boolean;
34
+ /** Font scale set by user */
35
+ fontScale: number;
36
+ /** Whether the device is low-end (for performance optimization) */
37
+ isLowEnd: boolean;
38
+ }
39
+
40
+ /**
41
+ * Detect device type from screen dimensions
42
+ */
43
+ export function detectDeviceType(width: number, height: number): DeviceType {
44
+ const minDim = Math.min(width, height);
45
+ const maxDim = Math.max(width, height);
46
+
47
+ if (minDim < 200) return 'watch';
48
+ if (minDim < 600 && maxDim < 1000) return 'phone';
49
+ if (minDim >= 600 && maxDim < 1400) return 'tablet';
50
+ if (minDim >= 1400) return 'tv';
51
+ return 'phone'; // Default
52
+ }
53
+
54
+ /**
55
+ * Get default capabilities for a device type
56
+ */
57
+ export function getDefaultCapabilities(type: DeviceType): DeviceCapabilities {
58
+ const defaults: Record<DeviceType, Partial<DeviceCapabilities>> = {
59
+ phone: { screenWidth: 390, screenHeight: 844, inputMode: 'touch', haptics: true, pixelRatio: 3, hasNotch: true },
60
+ tablet: { screenWidth: 820, screenHeight: 1180, inputMode: 'touch', haptics: true, pixelRatio: 2, hasNotch: false },
61
+ watch: { screenWidth: 184, screenHeight: 224, inputMode: 'touch', haptics: true, pixelRatio: 2, hasNotch: false },
62
+ tv: { screenWidth: 1920, screenHeight: 1080, inputMode: 'dpad', haptics: false, pixelRatio: 1, hasNotch: false },
63
+ auto: { screenWidth: 1280, screenHeight: 720, inputMode: 'touch', haptics: true, pixelRatio: 2, hasNotch: false },
64
+ desktop: { screenWidth: 1440, screenHeight: 900, inputMode: 'keyboard', haptics: false, pixelRatio: 2, hasNotch: false },
65
+ iot: { screenWidth: 320, screenHeight: 240, inputMode: 'touch', haptics: false, pixelRatio: 1, hasNotch: false },
66
+ };
67
+
68
+ return {
69
+ type,
70
+ screenWidth: 390,
71
+ screenHeight: 844,
72
+ inputMode: 'touch',
73
+ haptics: false,
74
+ biometrics: false,
75
+ hasNotch: false,
76
+ pixelRatio: 2,
77
+ darkModeSupported: true,
78
+ reduceMotion: false,
79
+ screenReaderActive: false,
80
+ fontScale: 1.0,
81
+ isLowEnd: false,
82
+ ...defaults[type],
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Determine if device is "low-end" based on characteristics
88
+ * Used to disable animations, reduce image quality, simplify UI
89
+ */
90
+ export function isLowEndDevice(totalRamMB?: number, pixelRatio?: number): boolean {
91
+ if (totalRamMB && totalRamMB < 2048) return true; // < 2GB RAM
92
+ if (pixelRatio && pixelRatio < 1.5) return true;
93
+ return false;
94
+ }
95
+
96
+ /**
97
+ * Get recommended touch target size for device type
98
+ * Follows WCAG 2.5.8 (44x44 minimum for mobile)
99
+ */
100
+ export function getMinTouchTarget(type: DeviceType): number {
101
+ switch (type) {
102
+ case 'watch': return 38; // Smaller screen, slightly smaller targets
103
+ case 'phone': return 44; // WCAG standard
104
+ case 'tablet': return 44;
105
+ case 'tv': return 56; // Larger for distance viewing with remote
106
+ case 'auto': return 56; // Larger for driving safety
107
+ case 'desktop': return 32; // Mouse is more precise
108
+ case 'iot': return 44;
109
+ default: return 44;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Get recommended font size multiplier for device type
115
+ */
116
+ export function getFontMultiplier(type: DeviceType, fontScale: number = 1.0): number {
117
+ const baseMultiplier: Record<DeviceType, number> = {
118
+ watch: 0.85,
119
+ phone: 1.0,
120
+ tablet: 1.1,
121
+ tv: 1.8, // Much larger for 10-foot UI
122
+ auto: 1.4, // Larger for glance-ability
123
+ desktop: 1.0,
124
+ iot: 0.9,
125
+ };
126
+ return (baseMultiplier[type] ?? 1.0) * fontScale;
127
+ }
@@ -0,0 +1,125 @@
1
+ /**
2
+ * @rajeev02/ui - React Hooks
3
+ *
4
+ * Hooks for device-aware rendering, theming, and accessibility.
5
+ */
6
+
7
+ // Note: These hooks are designed for React Native but the types
8
+ // and logic work in any React environment. Platform-specific
9
+ // imports would be resolved at build time.
10
+
11
+ import type { DeviceType, DeviceCapabilities, InputMode } from '../device';
12
+ import type { ThemeMode } from '../tokens';
13
+
14
+ /**
15
+ * Hook return type for useDevice
16
+ */
17
+ export interface UseDeviceResult {
18
+ type: DeviceType;
19
+ isPhone: boolean;
20
+ isTablet: boolean;
21
+ isWatch: boolean;
22
+ isTv: boolean;
23
+ isAuto: boolean;
24
+ isDesktop: boolean;
25
+ inputMode: InputMode;
26
+ isLowEnd: boolean;
27
+ screenWidth: number;
28
+ screenHeight: number;
29
+ fontScale: number;
30
+ pixelRatio: number;
31
+ }
32
+
33
+ /**
34
+ * Hook return type for useAccessibility
35
+ */
36
+ export interface UseAccessibilityResult {
37
+ screenReaderActive: boolean;
38
+ reduceMotion: boolean;
39
+ fontScale: number;
40
+ highContrast: boolean;
41
+ /** Minimum touch target size for current device */
42
+ minTouchTarget: number;
43
+ /** Whether to show large text */
44
+ largeText: boolean;
45
+ }
46
+
47
+ /**
48
+ * Hook return type for useTheme
49
+ */
50
+ export interface UseThemeResult {
51
+ mode: ThemeMode;
52
+ colors: Record<string, unknown>;
53
+ spacing: Record<string, number>;
54
+ isDark: boolean;
55
+ isHighContrast: boolean;
56
+ }
57
+
58
+ /**
59
+ * Adaptive layout props — define different content per device type
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * <AdaptiveLayout
64
+ * phone={<PhoneView />}
65
+ * tablet={<TabletView />}
66
+ * watch={<WatchView />}
67
+ * tv={<TvView />}
68
+ * auto={<AutoView />}
69
+ * />
70
+ * ```
71
+ */
72
+ export interface AdaptiveLayoutProps {
73
+ phone?: unknown;
74
+ tablet?: unknown;
75
+ watch?: unknown;
76
+ tv?: unknown;
77
+ auto?: unknown;
78
+ desktop?: unknown;
79
+ /** Fallback if specific device view not provided */
80
+ fallback?: unknown;
81
+ }
82
+
83
+ /**
84
+ * Get the appropriate content for the current device type
85
+ */
86
+ export function resolveAdaptiveContent(
87
+ props: AdaptiveLayoutProps,
88
+ deviceType: DeviceType,
89
+ ): unknown {
90
+ const map: Record<string, unknown> = {
91
+ phone: props.phone,
92
+ tablet: props.tablet ?? props.phone, // Tablet falls back to phone
93
+ watch: props.watch,
94
+ tv: props.tv ?? props.tablet ?? props.phone, // TV falls back to tablet then phone
95
+ auto: props.auto ?? props.phone,
96
+ desktop: props.desktop ?? props.tablet ?? props.phone,
97
+ iot: props.phone,
98
+ };
99
+
100
+ return map[deviceType] ?? props.fallback ?? props.phone;
101
+ }
102
+
103
+ /**
104
+ * Responsive value helper — pick value based on screen width
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * const padding = responsive(screenWidth, {
109
+ * watch: 4,
110
+ * phone: 16,
111
+ * tablet: 24,
112
+ * desktop: 32,
113
+ * });
114
+ * ```
115
+ */
116
+ export function responsive<T>(
117
+ screenWidth: number,
118
+ values: Partial<Record<DeviceType, T>> & { phone: T },
119
+ ): T {
120
+ if (screenWidth < 200 && values.watch !== undefined) return values.watch;
121
+ if (screenWidth < 600) return values.phone;
122
+ if (screenWidth < 1024 && values.tablet !== undefined) return values.tablet;
123
+ if (values.desktop !== undefined) return values.desktop;
124
+ return values.phone;
125
+ }
package/src/index.ts ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @rajeev02/ui
3
+ *
4
+ * Adaptive UI Component System
5
+ * Device-aware rendering for phone, tablet, watch, TV, auto, IoT
6
+ *
7
+ * @author Rajeev Kumar Joshi (https://github.com/Rajeev02)
8
+ * @license MIT
9
+ */
10
+
11
+ // Design Tokens
12
+ export {
13
+ colors, spacing, typography, breakpoints, borderRadius, shadows,
14
+ highContrast, getTheme,
15
+ } from './tokens';
16
+ export type { ThemeMode } from './tokens';
17
+
18
+ // Device Detection
19
+ export {
20
+ detectDeviceType, getDefaultCapabilities, isLowEndDevice,
21
+ getMinTouchTarget, getFontMultiplier,
22
+ } from './device';
23
+ export type { DeviceType, InputMode, DeviceCapabilities } from './device';
24
+
25
+ // Hooks & Adaptive Layout
26
+ export {
27
+ resolveAdaptiveContent, responsive,
28
+ } from './hooks';
29
+ export type {
30
+ UseDeviceResult, UseAccessibilityResult, UseThemeResult,
31
+ AdaptiveLayoutProps,
32
+ } from './hooks';
@@ -0,0 +1,114 @@
1
+ /**
2
+ * @rajeev02/ui - Design Tokens
3
+ *
4
+ * Centralized design system tokens for consistent theming
5
+ * across phone, tablet, watch, TV, and auto interfaces.
6
+ */
7
+
8
+ export const colors = {
9
+ // Primary palette
10
+ primary: { 50: '#EEF2FF', 100: '#E0E7FF', 200: '#C7D2FE', 300: '#A5B4FC', 400: '#818CF8', 500: '#6366F1', 600: '#4F46E5', 700: '#4338CA', 800: '#3730A3', 900: '#312E81' },
11
+ // Indian-friendly accent (saffron-inspired)
12
+ accent: { 50: '#FFF7ED', 100: '#FFEDD5', 200: '#FED7AA', 300: '#FDBA74', 400: '#FB923C', 500: '#F97316', 600: '#EA580C', 700: '#C2410C', 800: '#9A3412', 900: '#7C2D12' },
13
+ // Semantic
14
+ success: '#10B981',
15
+ warning: '#F59E0B',
16
+ error: '#EF4444',
17
+ info: '#3B82F6',
18
+ // Neutrals
19
+ text: { primary: '#111827', secondary: '#6B7280', disabled: '#9CA3AF', inverse: '#FFFFFF' },
20
+ background: { primary: '#FFFFFF', secondary: '#F9FAFB', tertiary: '#F3F4F6' },
21
+ border: { light: '#E5E7EB', medium: '#D1D5DB', dark: '#9CA3AF' },
22
+ } as const;
23
+
24
+ export const spacing = {
25
+ xxs: 2,
26
+ xs: 4,
27
+ sm: 8,
28
+ md: 12,
29
+ lg: 16,
30
+ xl: 24,
31
+ xxl: 32,
32
+ xxxl: 48,
33
+ } as const;
34
+
35
+ export const typography = {
36
+ // Font families with Indian script fallbacks
37
+ fontFamily: {
38
+ sans: 'System, -apple-system, "Noto Sans", "Noto Sans Devanagari", "Noto Sans Bengali", "Noto Sans Tamil", sans-serif',
39
+ mono: '"SF Mono", "Roboto Mono", "Noto Sans Mono", monospace',
40
+ },
41
+ // Size scale
42
+ fontSize: {
43
+ xs: 10,
44
+ sm: 12,
45
+ base: 14,
46
+ md: 16,
47
+ lg: 18,
48
+ xl: 20,
49
+ '2xl': 24,
50
+ '3xl': 30,
51
+ '4xl': 36,
52
+ },
53
+ // Line heights (slightly higher for Devanagari and other Indian scripts)
54
+ lineHeight: {
55
+ tight: 1.2,
56
+ normal: 1.5,
57
+ relaxed: 1.75, // Better for Indian scripts with diacritics
58
+ loose: 2.0,
59
+ },
60
+ fontWeight: {
61
+ regular: '400' as const,
62
+ medium: '500' as const,
63
+ semibold: '600' as const,
64
+ bold: '700' as const,
65
+ },
66
+ } as const;
67
+
68
+ export const breakpoints = {
69
+ /** Watch: < 200px */
70
+ watch: 200,
71
+ /** Phone: 200-599px */
72
+ phone: 600,
73
+ /** Tablet: 600-1023px */
74
+ tablet: 1024,
75
+ /** Desktop/TV: >= 1024px */
76
+ desktop: 1024,
77
+ } as const;
78
+
79
+ export const borderRadius = {
80
+ none: 0,
81
+ sm: 4,
82
+ md: 8,
83
+ lg: 12,
84
+ xl: 16,
85
+ full: 9999,
86
+ } as const;
87
+
88
+ export const shadows = {
89
+ sm: { shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.05, shadowRadius: 2, elevation: 1 },
90
+ md: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3 },
91
+ lg: { shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.15, shadowRadius: 8, elevation: 5 },
92
+ } as const;
93
+
94
+ /** Accessibility-focused high contrast palette */
95
+ export const highContrast = {
96
+ text: { primary: '#000000', secondary: '#333333', inverse: '#FFFFFF' },
97
+ background: { primary: '#FFFFFF', secondary: '#F0F0F0' },
98
+ border: { light: '#666666', medium: '#333333' },
99
+ focus: '#0055FF',
100
+ } as const;
101
+
102
+ export type ThemeMode = 'light' | 'dark' | 'highContrast';
103
+
104
+ /** Get complete theme based on mode */
105
+ export function getTheme(mode: ThemeMode) {
106
+ return {
107
+ colors: mode === 'highContrast' ? { ...colors, text: highContrast.text, background: highContrast.background, border: highContrast.border } : colors,
108
+ spacing,
109
+ typography,
110
+ borderRadius,
111
+ shadows,
112
+ mode,
113
+ };
114
+ }