@tekton-ui/core 0.2.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.
- package/README.md +758 -0
- package/dist/blueprint.d.ts +44 -0
- package/dist/blueprint.d.ts.map +1 -0
- package/dist/blueprint.js +163 -0
- package/dist/blueprint.js.map +1 -0
- package/dist/component-schemas.d.ts +78 -0
- package/dist/component-schemas.d.ts.map +1 -0
- package/dist/component-schemas.js +1037 -0
- package/dist/component-schemas.js.map +1 -0
- package/dist/css-generator.d.ts +42 -0
- package/dist/css-generator.d.ts.map +1 -0
- package/dist/css-generator.js +339 -0
- package/dist/css-generator.js.map +1 -0
- package/dist/icon-library.d.ts +109 -0
- package/dist/icon-library.d.ts.map +1 -0
- package/dist/icon-library.js +204 -0
- package/dist/icon-library.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/layout-css-generator.d.ts +158 -0
- package/dist/layout-css-generator.d.ts.map +1 -0
- package/dist/layout-css-generator.js +901 -0
- package/dist/layout-css-generator.js.map +1 -0
- package/dist/layout-resolver.d.ts +92 -0
- package/dist/layout-resolver.d.ts.map +1 -0
- package/dist/layout-resolver.js +275 -0
- package/dist/layout-resolver.js.map +1 -0
- package/dist/layout-tokens/index.d.ts +16 -0
- package/dist/layout-tokens/index.d.ts.map +1 -0
- package/dist/layout-tokens/index.js +16 -0
- package/dist/layout-tokens/index.js.map +1 -0
- package/dist/layout-tokens/keyboard.d.ts +254 -0
- package/dist/layout-tokens/keyboard.d.ts.map +1 -0
- package/dist/layout-tokens/keyboard.js +407 -0
- package/dist/layout-tokens/keyboard.js.map +1 -0
- package/dist/layout-tokens/mobile-shells.d.ts +78 -0
- package/dist/layout-tokens/mobile-shells.d.ts.map +1 -0
- package/dist/layout-tokens/mobile-shells.js +635 -0
- package/dist/layout-tokens/mobile-shells.js.map +1 -0
- package/dist/layout-tokens/pages.d.ts +100 -0
- package/dist/layout-tokens/pages.d.ts.map +1 -0
- package/dist/layout-tokens/pages.js +576 -0
- package/dist/layout-tokens/pages.js.map +1 -0
- package/dist/layout-tokens/responsive.d.ts +109 -0
- package/dist/layout-tokens/responsive.d.ts.map +1 -0
- package/dist/layout-tokens/responsive.js +167 -0
- package/dist/layout-tokens/responsive.js.map +1 -0
- package/dist/layout-tokens/safe-area.d.ts +156 -0
- package/dist/layout-tokens/safe-area.d.ts.map +1 -0
- package/dist/layout-tokens/safe-area.js +316 -0
- package/dist/layout-tokens/safe-area.js.map +1 -0
- package/dist/layout-tokens/sections-advanced.d.ts +277 -0
- package/dist/layout-tokens/sections-advanced.d.ts.map +1 -0
- package/dist/layout-tokens/sections-advanced.js +593 -0
- package/dist/layout-tokens/sections-advanced.js.map +1 -0
- package/dist/layout-tokens/sections.d.ts +137 -0
- package/dist/layout-tokens/sections.d.ts.map +1 -0
- package/dist/layout-tokens/sections.js +694 -0
- package/dist/layout-tokens/sections.js.map +1 -0
- package/dist/layout-tokens/shells.d.ts +77 -0
- package/dist/layout-tokens/shells.d.ts.map +1 -0
- package/dist/layout-tokens/shells.js +408 -0
- package/dist/layout-tokens/shells.js.map +1 -0
- package/dist/layout-tokens/touch-target.d.ts +119 -0
- package/dist/layout-tokens/touch-target.d.ts.map +1 -0
- package/dist/layout-tokens/touch-target.js +156 -0
- package/dist/layout-tokens/touch-target.js.map +1 -0
- package/dist/layout-tokens/types.d.ts +632 -0
- package/dist/layout-tokens/types.d.ts.map +1 -0
- package/dist/layout-tokens/types.js +49 -0
- package/dist/layout-tokens/types.js.map +1 -0
- package/dist/layout-validation.d.ts +1547 -0
- package/dist/layout-validation.d.ts.map +1 -0
- package/dist/layout-validation.js +628 -0
- package/dist/layout-validation.js.map +1 -0
- package/dist/render.d.ts +23 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +244 -0
- package/dist/render.js.map +1 -0
- package/dist/schema-validation.d.ts +208 -0
- package/dist/schema-validation.d.ts.map +1 -0
- package/dist/schema-validation.js +205 -0
- package/dist/schema-validation.js.map +1 -0
- package/dist/screen-generation/generators/css-in-js-generator.d.ts +82 -0
- package/dist/screen-generation/generators/css-in-js-generator.d.ts.map +1 -0
- package/dist/screen-generation/generators/css-in-js-generator.js +335 -0
- package/dist/screen-generation/generators/css-in-js-generator.js.map +1 -0
- package/dist/screen-generation/generators/index.d.ts +13 -0
- package/dist/screen-generation/generators/index.d.ts.map +1 -0
- package/dist/screen-generation/generators/index.js +32 -0
- package/dist/screen-generation/generators/index.js.map +1 -0
- package/dist/screen-generation/generators/react-generator.d.ts +100 -0
- package/dist/screen-generation/generators/react-generator.d.ts.map +1 -0
- package/dist/screen-generation/generators/react-generator.js +379 -0
- package/dist/screen-generation/generators/react-generator.js.map +1 -0
- package/dist/screen-generation/generators/tailwind-generator.d.ts +105 -0
- package/dist/screen-generation/generators/tailwind-generator.d.ts.map +1 -0
- package/dist/screen-generation/generators/tailwind-generator.js +355 -0
- package/dist/screen-generation/generators/tailwind-generator.js.map +1 -0
- package/dist/screen-generation/generators/types.d.ts +136 -0
- package/dist/screen-generation/generators/types.d.ts.map +1 -0
- package/dist/screen-generation/generators/types.js +18 -0
- package/dist/screen-generation/generators/types.js.map +1 -0
- package/dist/screen-generation/generators/utils.d.ts +187 -0
- package/dist/screen-generation/generators/utils.d.ts.map +1 -0
- package/dist/screen-generation/generators/utils.js +312 -0
- package/dist/screen-generation/generators/utils.js.map +1 -0
- package/dist/screen-generation/index.d.ts +14 -0
- package/dist/screen-generation/index.d.ts.map +1 -0
- package/dist/screen-generation/index.js +33 -0
- package/dist/screen-generation/index.js.map +1 -0
- package/dist/screen-generation/resolver/component-resolver.d.ts +157 -0
- package/dist/screen-generation/resolver/component-resolver.d.ts.map +1 -0
- package/dist/screen-generation/resolver/component-resolver.js +295 -0
- package/dist/screen-generation/resolver/component-resolver.js.map +1 -0
- package/dist/screen-generation/resolver/index.d.ts +10 -0
- package/dist/screen-generation/resolver/index.d.ts.map +1 -0
- package/dist/screen-generation/resolver/index.js +46 -0
- package/dist/screen-generation/resolver/index.js.map +1 -0
- package/dist/screen-generation/resolver/layout-resolver.d.ts +155 -0
- package/dist/screen-generation/resolver/layout-resolver.d.ts.map +1 -0
- package/dist/screen-generation/resolver/layout-resolver.js +193 -0
- package/dist/screen-generation/resolver/layout-resolver.js.map +1 -0
- package/dist/screen-generation/resolver/screen-resolver.d.ts +174 -0
- package/dist/screen-generation/resolver/screen-resolver.d.ts.map +1 -0
- package/dist/screen-generation/resolver/screen-resolver.js +373 -0
- package/dist/screen-generation/resolver/screen-resolver.js.map +1 -0
- package/dist/screen-generation/resolver/token-resolver.d.ts +170 -0
- package/dist/screen-generation/resolver/token-resolver.d.ts.map +1 -0
- package/dist/screen-generation/resolver/token-resolver.js +260 -0
- package/dist/screen-generation/resolver/token-resolver.js.map +1 -0
- package/dist/screen-generation/types.d.ts +116 -0
- package/dist/screen-generation/types.d.ts.map +1 -0
- package/dist/screen-generation/types.js +33 -0
- package/dist/screen-generation/types.js.map +1 -0
- package/dist/screen-generation/validators.d.ts +286 -0
- package/dist/screen-generation/validators.d.ts.map +1 -0
- package/dist/screen-generation/validators.js +323 -0
- package/dist/screen-generation/validators.js.map +1 -0
- package/dist/screen-templates/__tests__/registry.test.d.ts +6 -0
- package/dist/screen-templates/__tests__/registry.test.d.ts.map +1 -0
- package/dist/screen-templates/__tests__/registry.test.js +247 -0
- package/dist/screen-templates/__tests__/registry.test.js.map +1 -0
- package/dist/screen-templates/__tests__/templates.test.d.ts +6 -0
- package/dist/screen-templates/__tests__/templates.test.d.ts.map +1 -0
- package/dist/screen-templates/__tests__/templates.test.js +179 -0
- package/dist/screen-templates/__tests__/templates.test.js.map +1 -0
- package/dist/screen-templates/index.d.ts +39 -0
- package/dist/screen-templates/index.d.ts.map +1 -0
- package/dist/screen-templates/index.js +79 -0
- package/dist/screen-templates/index.js.map +1 -0
- package/dist/screen-templates/registry.d.ts +177 -0
- package/dist/screen-templates/registry.d.ts.map +1 -0
- package/dist/screen-templates/registry.js +274 -0
- package/dist/screen-templates/registry.js.map +1 -0
- package/dist/screen-templates/templates/account/index.d.ts +6 -0
- package/dist/screen-templates/templates/account/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/account/index.js +6 -0
- package/dist/screen-templates/templates/account/index.js.map +1 -0
- package/dist/screen-templates/templates/account/profile.d.ts +23 -0
- package/dist/screen-templates/templates/account/profile.d.ts.map +1 -0
- package/dist/screen-templates/templates/account/profile.js +249 -0
- package/dist/screen-templates/templates/account/profile.js.map +1 -0
- package/dist/screen-templates/templates/auth/forgot-password.d.ts +23 -0
- package/dist/screen-templates/templates/auth/forgot-password.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/forgot-password.js +203 -0
- package/dist/screen-templates/templates/auth/forgot-password.js.map +1 -0
- package/dist/screen-templates/templates/auth/index.d.ts +9 -0
- package/dist/screen-templates/templates/auth/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/index.js +9 -0
- package/dist/screen-templates/templates/auth/index.js.map +1 -0
- package/dist/screen-templates/templates/auth/login.d.ts +24 -0
- package/dist/screen-templates/templates/auth/login.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/login.js +254 -0
- package/dist/screen-templates/templates/auth/login.js.map +1 -0
- package/dist/screen-templates/templates/auth/signup.d.ts +24 -0
- package/dist/screen-templates/templates/auth/signup.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/signup.js +315 -0
- package/dist/screen-templates/templates/auth/signup.js.map +1 -0
- package/dist/screen-templates/templates/auth/verification.d.ts +23 -0
- package/dist/screen-templates/templates/auth/verification.d.ts.map +1 -0
- package/dist/screen-templates/templates/auth/verification.js +239 -0
- package/dist/screen-templates/templates/auth/verification.js.map +1 -0
- package/dist/screen-templates/templates/feedback/confirmation.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/confirmation.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/confirmation.js +107 -0
- package/dist/screen-templates/templates/feedback/confirmation.js.map +1 -0
- package/dist/screen-templates/templates/feedback/empty.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/empty.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/empty.js +90 -0
- package/dist/screen-templates/templates/feedback/empty.js.map +1 -0
- package/dist/screen-templates/templates/feedback/error.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/error.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/error.js +99 -0
- package/dist/screen-templates/templates/feedback/error.js.map +1 -0
- package/dist/screen-templates/templates/feedback/index.d.ts +10 -0
- package/dist/screen-templates/templates/feedback/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/index.js +10 -0
- package/dist/screen-templates/templates/feedback/index.js.map +1 -0
- package/dist/screen-templates/templates/feedback/loading.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/loading.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/loading.js +77 -0
- package/dist/screen-templates/templates/feedback/loading.js.map +1 -0
- package/dist/screen-templates/templates/feedback/success.d.ts +9 -0
- package/dist/screen-templates/templates/feedback/success.d.ts.map +1 -0
- package/dist/screen-templates/templates/feedback/success.js +99 -0
- package/dist/screen-templates/templates/feedback/success.js.map +1 -0
- package/dist/screen-templates/templates/home/index.d.ts +6 -0
- package/dist/screen-templates/templates/home/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/home/index.js +6 -0
- package/dist/screen-templates/templates/home/index.js.map +1 -0
- package/dist/screen-templates/templates/home/landing.d.ts +24 -0
- package/dist/screen-templates/templates/home/landing.d.ts.map +1 -0
- package/dist/screen-templates/templates/home/landing.js +197 -0
- package/dist/screen-templates/templates/home/landing.js.map +1 -0
- package/dist/screen-templates/templates/settings/index.d.ts +6 -0
- package/dist/screen-templates/templates/settings/index.d.ts.map +1 -0
- package/dist/screen-templates/templates/settings/index.js +6 -0
- package/dist/screen-templates/templates/settings/index.js.map +1 -0
- package/dist/screen-templates/templates/settings/preferences.d.ts +24 -0
- package/dist/screen-templates/templates/settings/preferences.d.ts.map +1 -0
- package/dist/screen-templates/templates/settings/preferences.js +265 -0
- package/dist/screen-templates/templates/settings/preferences.js.map +1 -0
- package/dist/screen-templates/types.d.ts +229 -0
- package/dist/screen-templates/types.d.ts.map +1 -0
- package/dist/screen-templates/types.js +7 -0
- package/dist/screen-templates/types.js.map +1 -0
- package/dist/theme-v2.d.ts +228 -0
- package/dist/theme-v2.d.ts.map +1 -0
- package/dist/theme-v2.js +158 -0
- package/dist/theme-v2.js.map +1 -0
- package/dist/theme.d.ts +60 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +76 -0
- package/dist/theme.js.map +1 -0
- package/dist/token-resolver.d.ts +69 -0
- package/dist/token-resolver.d.ts.map +1 -0
- package/dist/token-resolver.js +122 -0
- package/dist/token-resolver.js.map +1 -0
- package/dist/token-validation.d.ts +432 -0
- package/dist/token-validation.d.ts.map +1 -0
- package/dist/token-validation.js +140 -0
- package/dist/token-validation.js.map +1 -0
- package/dist/tokens.d.ts +158 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +10 -0
- package/dist/tokens.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @tekton-ui/core - Keyboard Utilities
|
|
3
|
+
* Keyboard handling and avoidance utilities for mobile and web platforms
|
|
4
|
+
* [SPEC-LAYOUT-004] [MILESTONE-4]
|
|
5
|
+
*/
|
|
6
|
+
import type { KeyboardConfig, KeyboardAnimationConfig } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Keyboard state for tracking visibility and dimensions
|
|
9
|
+
*/
|
|
10
|
+
export interface KeyboardState {
|
|
11
|
+
/** Whether the keyboard is currently visible */
|
|
12
|
+
isVisible: boolean;
|
|
13
|
+
/** Current keyboard height in points/dp (0 if hidden) */
|
|
14
|
+
height: number;
|
|
15
|
+
/** Animation progress from 0.0 (hidden) to 1.0 (fully visible) */
|
|
16
|
+
progress: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Keyboard event types
|
|
20
|
+
*/
|
|
21
|
+
export type KeyboardEventType = 'show' | 'hide' | 'change';
|
|
22
|
+
/**
|
|
23
|
+
* Keyboard event listener callback
|
|
24
|
+
*/
|
|
25
|
+
export type KeyboardEventListener = (height: number) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Layout object that can be modified by keyboard avoidance
|
|
28
|
+
*/
|
|
29
|
+
export interface KeyboardAwareLayout {
|
|
30
|
+
/** Padding values */
|
|
31
|
+
padding?: {
|
|
32
|
+
top?: number;
|
|
33
|
+
bottom?: number;
|
|
34
|
+
left?: number;
|
|
35
|
+
right?: number;
|
|
36
|
+
};
|
|
37
|
+
/** Height dimension */
|
|
38
|
+
height?: number;
|
|
39
|
+
/** Transform values */
|
|
40
|
+
transform?: Array<{
|
|
41
|
+
translateY?: number;
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}>;
|
|
44
|
+
/** Position values */
|
|
45
|
+
position?: {
|
|
46
|
+
bottom?: number;
|
|
47
|
+
top?: number;
|
|
48
|
+
left?: number;
|
|
49
|
+
right?: number;
|
|
50
|
+
};
|
|
51
|
+
/** Allow additional properties */
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get current keyboard height
|
|
56
|
+
*
|
|
57
|
+
* @returns Keyboard height in points/dp (0 if hidden or unavailable)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const keyboardHeight = getKeyboardHeight();
|
|
62
|
+
* console.log(keyboardHeight); // 336 on iPhone, varies on Android, 0 on web
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @remarks
|
|
66
|
+
* - On web: Always returns 0 (no software keyboard tracking)
|
|
67
|
+
* - On iOS: Returns keyboard height from Keyboard API (typically 336pt on iPhone)
|
|
68
|
+
* - On Android: Returns keyboard height from Keyboard API (varies by device)
|
|
69
|
+
* - Falls back to 0 if Keyboard API is unavailable
|
|
70
|
+
*/
|
|
71
|
+
export declare function getKeyboardHeight(): number;
|
|
72
|
+
/**
|
|
73
|
+
* Apply keyboard avoidance strategy to a layout
|
|
74
|
+
*
|
|
75
|
+
* @param layout - Layout object to modify
|
|
76
|
+
* @param config - Keyboard configuration defining avoidance strategy
|
|
77
|
+
* @returns Modified layout with keyboard avoidance applied
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* const layout = { padding: { bottom: 0 }, height: 812 };
|
|
82
|
+
* const keyboardHeight = 336;
|
|
83
|
+
* const adjusted = applyKeyboardAvoidance(layout, {
|
|
84
|
+
* avoidance: 'padding',
|
|
85
|
+
* behavior: 'height',
|
|
86
|
+
* animation: { duration: 250, easing: 'keyboard', enabled: true },
|
|
87
|
+
* dismissMode: 'interactive'
|
|
88
|
+
* });
|
|
89
|
+
* console.log(adjusted.padding.bottom); // 336
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* Avoidance strategies:
|
|
94
|
+
* - 'padding': Adds keyboard height to bottom padding
|
|
95
|
+
* - 'resize': Reduces container height by keyboard height
|
|
96
|
+
* - 'position': Translates container up by keyboard height
|
|
97
|
+
* - 'none': Returns layout unchanged
|
|
98
|
+
*
|
|
99
|
+
* The behavior property determines how the adjustment is applied:
|
|
100
|
+
* - 'height': Modifies height property (for resize strategy)
|
|
101
|
+
* - 'position': Modifies transform/translateY (for position strategy)
|
|
102
|
+
* - 'padding': Modifies padding (for padding strategy)
|
|
103
|
+
*/
|
|
104
|
+
export declare function applyKeyboardAvoidance(layout: KeyboardAwareLayout, config: KeyboardConfig): KeyboardAwareLayout;
|
|
105
|
+
/**
|
|
106
|
+
* React Native hook to track keyboard state
|
|
107
|
+
*
|
|
108
|
+
* @returns KeyboardState object with isVisible, height, progress
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* function MyComponent() {
|
|
113
|
+
* const keyboard = useKeyboardAvoidance();
|
|
114
|
+
* return (
|
|
115
|
+
* <View style={{
|
|
116
|
+
* paddingBottom: keyboard.isVisible ? keyboard.height : 0
|
|
117
|
+
* }} />
|
|
118
|
+
* );
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @remarks
|
|
123
|
+
* This is a placeholder implementation that returns default values.
|
|
124
|
+
* In production, integrate with react-native-keyboard-controller:
|
|
125
|
+
*
|
|
126
|
+
* ```typescript
|
|
127
|
+
* import { useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller';
|
|
128
|
+
*
|
|
129
|
+
* export function useKeyboardAvoidance(): KeyboardState {
|
|
130
|
+
* const { height, progress } = useReanimatedKeyboardAnimation();
|
|
131
|
+
* return {
|
|
132
|
+
* isVisible: height.value > 0,
|
|
133
|
+
* height: height.value,
|
|
134
|
+
* progress: progress.value,
|
|
135
|
+
* };
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @see https://github.com/kirillzyusko/react-native-keyboard-controller
|
|
140
|
+
*/
|
|
141
|
+
export declare function useKeyboardAvoidance(): KeyboardState;
|
|
142
|
+
/**
|
|
143
|
+
* Add keyboard event listener
|
|
144
|
+
*
|
|
145
|
+
* @param event - Event type to listen for ('show' | 'hide' | 'change')
|
|
146
|
+
* @param listener - Callback function receiving keyboard height
|
|
147
|
+
* @returns Cleanup function to remove listener
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const unsubscribe = addKeyboardListener('show', (height) => {
|
|
152
|
+
* console.log('Keyboard shown with height:', height);
|
|
153
|
+
* });
|
|
154
|
+
*
|
|
155
|
+
* // Later: unsubscribe();
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* @remarks
|
|
159
|
+
* - On web: Returns no-op cleanup function (no keyboard events)
|
|
160
|
+
* - On React Native: Uses Keyboard.addListener() API
|
|
161
|
+
* - Supported events: 'show', 'hide', 'change'
|
|
162
|
+
* - Always call the cleanup function to prevent memory leaks
|
|
163
|
+
*/
|
|
164
|
+
export declare function addKeyboardListener(event: KeyboardEventType, listener: KeyboardEventListener): () => void;
|
|
165
|
+
/**
|
|
166
|
+
* Get platform-specific keyboard animation duration
|
|
167
|
+
*
|
|
168
|
+
* @returns Animation duration in milliseconds
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* const duration = getKeyboardAnimationDuration();
|
|
173
|
+
* // iOS: 250, Android: 300, Web: 0
|
|
174
|
+
* ```
|
|
175
|
+
*
|
|
176
|
+
* @remarks
|
|
177
|
+
* Default animation durations:
|
|
178
|
+
* - iOS: 250ms (from UIKit keyboard animation)
|
|
179
|
+
* - Android: 300ms (from WindowInsetsAnimationCompat)
|
|
180
|
+
* - Web: 0ms (no keyboard animation)
|
|
181
|
+
*/
|
|
182
|
+
export declare function getKeyboardAnimationDuration(): number;
|
|
183
|
+
/**
|
|
184
|
+
* Calculate keyboard-aware bottom spacing
|
|
185
|
+
*
|
|
186
|
+
* @param baseSpacing - Base spacing value in points/dp
|
|
187
|
+
* @param includeKeyboard - Whether to include keyboard height (default: true)
|
|
188
|
+
* @returns Total spacing including keyboard height if applicable
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* // With keyboard visible (height: 336)
|
|
193
|
+
* const spacing = getKeyboardAwareBottomSpacing(16, true);
|
|
194
|
+
* console.log(spacing); // 352 (16 + 336)
|
|
195
|
+
*
|
|
196
|
+
* // Without keyboard consideration
|
|
197
|
+
* const spacing = getKeyboardAwareBottomSpacing(16, false);
|
|
198
|
+
* console.log(spacing); // 16
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* @remarks
|
|
202
|
+
* Useful for calculating dynamic spacing that accounts for keyboard visibility.
|
|
203
|
+
* Common use cases:
|
|
204
|
+
* - Bottom padding for scrollable content
|
|
205
|
+
* - Bottom margin for floating action buttons
|
|
206
|
+
* - Bottom inset for safe area + keyboard
|
|
207
|
+
*/
|
|
208
|
+
export declare function getKeyboardAwareBottomSpacing(baseSpacing: number, includeKeyboard?: boolean): number;
|
|
209
|
+
/**
|
|
210
|
+
* Get default keyboard animation configuration for current platform
|
|
211
|
+
*
|
|
212
|
+
* @returns KeyboardAnimationConfig with platform-specific defaults
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* const animConfig = getDefaultKeyboardAnimation();
|
|
217
|
+
* // iOS: { duration: 250, easing: 'keyboard', enabled: true }
|
|
218
|
+
* // Android: { duration: 300, easing: 'keyboard', enabled: true }
|
|
219
|
+
* // Web: { duration: 0, easing: 'linear', enabled: false }
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
export declare function getDefaultKeyboardAnimation(): KeyboardAnimationConfig;
|
|
223
|
+
/**
|
|
224
|
+
* Check if keyboard is currently visible
|
|
225
|
+
*
|
|
226
|
+
* @returns True if keyboard is visible, false otherwise
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```typescript
|
|
230
|
+
* if (isKeyboardVisible()) {
|
|
231
|
+
* console.log('Keyboard is visible');
|
|
232
|
+
* }
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
export declare function isKeyboardVisible(): boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Get keyboard behavior progress tracking mode
|
|
238
|
+
*
|
|
239
|
+
* @returns Progress tracking mode ('binary' for iOS, 'continuous' for Android, 'none' for web)
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```typescript
|
|
243
|
+
* const mode = getKeyboardProgressMode();
|
|
244
|
+
* // iOS: 'binary' (0 or 1 only)
|
|
245
|
+
* // Android: 'continuous' (0, 0.07, 0.12, ..., 1.0)
|
|
246
|
+
* // Web: 'none'
|
|
247
|
+
* ```
|
|
248
|
+
*
|
|
249
|
+
* @remarks
|
|
250
|
+
* iOS keyboard animations have binary progress (0 or 1) due to willShow/willHide notifications.
|
|
251
|
+
* Android keyboard animations have continuous progress tracking via WindowInsetsAnimationCompat.
|
|
252
|
+
*/
|
|
253
|
+
export declare function getKeyboardProgressMode(): 'binary' | 'continuous' | 'none';
|
|
254
|
+
//# sourceMappingURL=keyboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../src/layout-tokens/keyboard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAwC1E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,SAAS,EAAE,OAAO,CAAC;IAEnB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IAEf,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,qBAAqB;IACrB,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uBAAuB;IACvB,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;IAEnE,sBAAsB;IACtB,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF,kCAAkC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CA8B1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,cAAc,GACrB,mBAAmB,CA4CrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,oBAAoB,IAAI,aAAa,CAQpD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,qBAAqB,GAC9B,MAAM,IAAI,CA8CZ;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CAYrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,UAAO,GAAG,MAAM,CAOjG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,IAAI,uBAAuB,CAwBrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,IAAI,QAAQ,GAAG,YAAY,GAAG,MAAM,CAY1E"}
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @tekton-ui/core - Keyboard Utilities
|
|
3
|
+
* Keyboard handling and avoidance utilities for mobile and web platforms
|
|
4
|
+
* [SPEC-LAYOUT-004] [MILESTONE-4]
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Platform Detection
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Detect current platform
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
function detectPlatform() {
|
|
14
|
+
// Check if running in React Native environment
|
|
15
|
+
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
|
|
16
|
+
// Detect iOS or Android
|
|
17
|
+
const globalAny = global;
|
|
18
|
+
const Platform = globalAny.Platform;
|
|
19
|
+
if (Platform && Platform.OS) {
|
|
20
|
+
return Platform.OS === 'ios' ? 'ios' : 'android';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return 'web';
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check if React Native Keyboard API is available
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
function isKeyboardAPIAvailable() {
|
|
30
|
+
try {
|
|
31
|
+
const globalAny = global;
|
|
32
|
+
return typeof globalAny.Keyboard !== 'undefined';
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// Core Functions
|
|
40
|
+
// ============================================================================
|
|
41
|
+
/**
|
|
42
|
+
* Get current keyboard height
|
|
43
|
+
*
|
|
44
|
+
* @returns Keyboard height in points/dp (0 if hidden or unavailable)
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const keyboardHeight = getKeyboardHeight();
|
|
49
|
+
* console.log(keyboardHeight); // 336 on iPhone, varies on Android, 0 on web
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @remarks
|
|
53
|
+
* - On web: Always returns 0 (no software keyboard tracking)
|
|
54
|
+
* - On iOS: Returns keyboard height from Keyboard API (typically 336pt on iPhone)
|
|
55
|
+
* - On Android: Returns keyboard height from Keyboard API (varies by device)
|
|
56
|
+
* - Falls back to 0 if Keyboard API is unavailable
|
|
57
|
+
*/
|
|
58
|
+
export function getKeyboardHeight() {
|
|
59
|
+
const platform = detectPlatform();
|
|
60
|
+
// Web platform: no keyboard tracking
|
|
61
|
+
if (platform === 'web') {
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
// React Native: try to get keyboard height
|
|
65
|
+
if (isKeyboardAPIAvailable()) {
|
|
66
|
+
try {
|
|
67
|
+
const globalAny = global;
|
|
68
|
+
const Keyboard = globalAny.Keyboard;
|
|
69
|
+
// Check if there's an active keyboard metrics method
|
|
70
|
+
if (typeof Keyboard?.metrics === 'function') {
|
|
71
|
+
const metrics = Keyboard.metrics();
|
|
72
|
+
return metrics?.height ?? 0;
|
|
73
|
+
}
|
|
74
|
+
// Alternative: check stored keyboard height (if available)
|
|
75
|
+
// This would require integration with react-native-keyboard-controller
|
|
76
|
+
// or a custom keyboard state manager
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.warn('[Keyboard] Failed to get keyboard height:', error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Fallback: return 0
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Apply keyboard avoidance strategy to a layout
|
|
87
|
+
*
|
|
88
|
+
* @param layout - Layout object to modify
|
|
89
|
+
* @param config - Keyboard configuration defining avoidance strategy
|
|
90
|
+
* @returns Modified layout with keyboard avoidance applied
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* const layout = { padding: { bottom: 0 }, height: 812 };
|
|
95
|
+
* const keyboardHeight = 336;
|
|
96
|
+
* const adjusted = applyKeyboardAvoidance(layout, {
|
|
97
|
+
* avoidance: 'padding',
|
|
98
|
+
* behavior: 'height',
|
|
99
|
+
* animation: { duration: 250, easing: 'keyboard', enabled: true },
|
|
100
|
+
* dismissMode: 'interactive'
|
|
101
|
+
* });
|
|
102
|
+
* console.log(adjusted.padding.bottom); // 336
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @remarks
|
|
106
|
+
* Avoidance strategies:
|
|
107
|
+
* - 'padding': Adds keyboard height to bottom padding
|
|
108
|
+
* - 'resize': Reduces container height by keyboard height
|
|
109
|
+
* - 'position': Translates container up by keyboard height
|
|
110
|
+
* - 'none': Returns layout unchanged
|
|
111
|
+
*
|
|
112
|
+
* The behavior property determines how the adjustment is applied:
|
|
113
|
+
* - 'height': Modifies height property (for resize strategy)
|
|
114
|
+
* - 'position': Modifies transform/translateY (for position strategy)
|
|
115
|
+
* - 'padding': Modifies padding (for padding strategy)
|
|
116
|
+
*/
|
|
117
|
+
export function applyKeyboardAvoidance(layout, config) {
|
|
118
|
+
const keyboardHeight = getKeyboardHeight();
|
|
119
|
+
// No keyboard or no avoidance needed
|
|
120
|
+
if (keyboardHeight === 0 || config.avoidance === 'none') {
|
|
121
|
+
return layout;
|
|
122
|
+
}
|
|
123
|
+
// Create a copy of the layout to avoid mutation
|
|
124
|
+
const adjustedLayout = { ...layout };
|
|
125
|
+
// Apply avoidance strategy
|
|
126
|
+
switch (config.avoidance) {
|
|
127
|
+
case 'padding': {
|
|
128
|
+
// Add keyboard height to bottom padding
|
|
129
|
+
const currentPadding = layout.padding ?? {};
|
|
130
|
+
adjustedLayout.padding = {
|
|
131
|
+
...currentPadding,
|
|
132
|
+
bottom: (currentPadding.bottom ?? 0) + keyboardHeight,
|
|
133
|
+
};
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case 'resize': {
|
|
137
|
+
// Reduce container height by keyboard height
|
|
138
|
+
if (typeof layout.height === 'number') {
|
|
139
|
+
adjustedLayout.height = layout.height - keyboardHeight;
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case 'position': {
|
|
144
|
+
// Translate container up by keyboard height
|
|
145
|
+
const currentTransform = layout.transform ?? [];
|
|
146
|
+
adjustedLayout.transform = [...currentTransform, { translateY: -keyboardHeight }];
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
default:
|
|
150
|
+
// Unknown avoidance strategy, return unchanged
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
return adjustedLayout;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* React Native hook to track keyboard state
|
|
157
|
+
*
|
|
158
|
+
* @returns KeyboardState object with isVisible, height, progress
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* function MyComponent() {
|
|
163
|
+
* const keyboard = useKeyboardAvoidance();
|
|
164
|
+
* return (
|
|
165
|
+
* <View style={{
|
|
166
|
+
* paddingBottom: keyboard.isVisible ? keyboard.height : 0
|
|
167
|
+
* }} />
|
|
168
|
+
* );
|
|
169
|
+
* }
|
|
170
|
+
* ```
|
|
171
|
+
*
|
|
172
|
+
* @remarks
|
|
173
|
+
* This is a placeholder implementation that returns default values.
|
|
174
|
+
* In production, integrate with react-native-keyboard-controller:
|
|
175
|
+
*
|
|
176
|
+
* ```typescript
|
|
177
|
+
* import { useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller';
|
|
178
|
+
*
|
|
179
|
+
* export function useKeyboardAvoidance(): KeyboardState {
|
|
180
|
+
* const { height, progress } = useReanimatedKeyboardAnimation();
|
|
181
|
+
* return {
|
|
182
|
+
* isVisible: height.value > 0,
|
|
183
|
+
* height: height.value,
|
|
184
|
+
* progress: progress.value,
|
|
185
|
+
* };
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
*
|
|
189
|
+
* @see https://github.com/kirillzyusko/react-native-keyboard-controller
|
|
190
|
+
*/
|
|
191
|
+
export function useKeyboardAvoidance() {
|
|
192
|
+
// Placeholder implementation
|
|
193
|
+
// In production, use react-native-keyboard-controller or custom hook
|
|
194
|
+
return {
|
|
195
|
+
isVisible: false,
|
|
196
|
+
height: 0,
|
|
197
|
+
progress: 0,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Add keyboard event listener
|
|
202
|
+
*
|
|
203
|
+
* @param event - Event type to listen for ('show' | 'hide' | 'change')
|
|
204
|
+
* @param listener - Callback function receiving keyboard height
|
|
205
|
+
* @returns Cleanup function to remove listener
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```typescript
|
|
209
|
+
* const unsubscribe = addKeyboardListener('show', (height) => {
|
|
210
|
+
* console.log('Keyboard shown with height:', height);
|
|
211
|
+
* });
|
|
212
|
+
*
|
|
213
|
+
* // Later: unsubscribe();
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* @remarks
|
|
217
|
+
* - On web: Returns no-op cleanup function (no keyboard events)
|
|
218
|
+
* - On React Native: Uses Keyboard.addListener() API
|
|
219
|
+
* - Supported events: 'show', 'hide', 'change'
|
|
220
|
+
* - Always call the cleanup function to prevent memory leaks
|
|
221
|
+
*/
|
|
222
|
+
export function addKeyboardListener(event, listener) {
|
|
223
|
+
const platform = detectPlatform();
|
|
224
|
+
// Web platform: no keyboard events
|
|
225
|
+
if (platform === 'web') {
|
|
226
|
+
return () => {
|
|
227
|
+
// No-op cleanup
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
// React Native: try to add listener
|
|
231
|
+
if (isKeyboardAPIAvailable()) {
|
|
232
|
+
try {
|
|
233
|
+
const globalAny = global;
|
|
234
|
+
const Keyboard = globalAny.Keyboard;
|
|
235
|
+
// Map event type to React Native event names
|
|
236
|
+
const eventName = event === 'show'
|
|
237
|
+
? 'keyboardDidShow'
|
|
238
|
+
: event === 'hide'
|
|
239
|
+
? 'keyboardDidHide'
|
|
240
|
+
: 'keyboardDidChangeFrame';
|
|
241
|
+
// Create listener wrapper
|
|
242
|
+
const wrappedListener = (e) => {
|
|
243
|
+
const height = e.endCoordinates?.height ?? 0;
|
|
244
|
+
listener(height);
|
|
245
|
+
};
|
|
246
|
+
// Add listener
|
|
247
|
+
const subscription = Keyboard.addListener(eventName, wrappedListener);
|
|
248
|
+
// Return cleanup function
|
|
249
|
+
return () => {
|
|
250
|
+
subscription?.remove?.();
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
console.warn('[Keyboard] Failed to add keyboard listener:', error);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Fallback: return no-op cleanup
|
|
258
|
+
return () => {
|
|
259
|
+
// No-op cleanup
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
// ============================================================================
|
|
263
|
+
// Helper Functions
|
|
264
|
+
// ============================================================================
|
|
265
|
+
/**
|
|
266
|
+
* Get platform-specific keyboard animation duration
|
|
267
|
+
*
|
|
268
|
+
* @returns Animation duration in milliseconds
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* const duration = getKeyboardAnimationDuration();
|
|
273
|
+
* // iOS: 250, Android: 300, Web: 0
|
|
274
|
+
* ```
|
|
275
|
+
*
|
|
276
|
+
* @remarks
|
|
277
|
+
* Default animation durations:
|
|
278
|
+
* - iOS: 250ms (from UIKit keyboard animation)
|
|
279
|
+
* - Android: 300ms (from WindowInsetsAnimationCompat)
|
|
280
|
+
* - Web: 0ms (no keyboard animation)
|
|
281
|
+
*/
|
|
282
|
+
export function getKeyboardAnimationDuration() {
|
|
283
|
+
const platform = detectPlatform();
|
|
284
|
+
switch (platform) {
|
|
285
|
+
case 'ios':
|
|
286
|
+
return 250;
|
|
287
|
+
case 'android':
|
|
288
|
+
return 300;
|
|
289
|
+
case 'web':
|
|
290
|
+
default:
|
|
291
|
+
return 0;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Calculate keyboard-aware bottom spacing
|
|
296
|
+
*
|
|
297
|
+
* @param baseSpacing - Base spacing value in points/dp
|
|
298
|
+
* @param includeKeyboard - Whether to include keyboard height (default: true)
|
|
299
|
+
* @returns Total spacing including keyboard height if applicable
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```typescript
|
|
303
|
+
* // With keyboard visible (height: 336)
|
|
304
|
+
* const spacing = getKeyboardAwareBottomSpacing(16, true);
|
|
305
|
+
* console.log(spacing); // 352 (16 + 336)
|
|
306
|
+
*
|
|
307
|
+
* // Without keyboard consideration
|
|
308
|
+
* const spacing = getKeyboardAwareBottomSpacing(16, false);
|
|
309
|
+
* console.log(spacing); // 16
|
|
310
|
+
* ```
|
|
311
|
+
*
|
|
312
|
+
* @remarks
|
|
313
|
+
* Useful for calculating dynamic spacing that accounts for keyboard visibility.
|
|
314
|
+
* Common use cases:
|
|
315
|
+
* - Bottom padding for scrollable content
|
|
316
|
+
* - Bottom margin for floating action buttons
|
|
317
|
+
* - Bottom inset for safe area + keyboard
|
|
318
|
+
*/
|
|
319
|
+
export function getKeyboardAwareBottomSpacing(baseSpacing, includeKeyboard = true) {
|
|
320
|
+
if (!includeKeyboard) {
|
|
321
|
+
return baseSpacing;
|
|
322
|
+
}
|
|
323
|
+
const keyboardHeight = getKeyboardHeight();
|
|
324
|
+
return baseSpacing + keyboardHeight;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Get default keyboard animation configuration for current platform
|
|
328
|
+
*
|
|
329
|
+
* @returns KeyboardAnimationConfig with platform-specific defaults
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* ```typescript
|
|
333
|
+
* const animConfig = getDefaultKeyboardAnimation();
|
|
334
|
+
* // iOS: { duration: 250, easing: 'keyboard', enabled: true }
|
|
335
|
+
* // Android: { duration: 300, easing: 'keyboard', enabled: true }
|
|
336
|
+
* // Web: { duration: 0, easing: 'linear', enabled: false }
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
export function getDefaultKeyboardAnimation() {
|
|
340
|
+
const platform = detectPlatform();
|
|
341
|
+
switch (platform) {
|
|
342
|
+
case 'ios':
|
|
343
|
+
return {
|
|
344
|
+
duration: 250,
|
|
345
|
+
easing: 'keyboard',
|
|
346
|
+
enabled: true,
|
|
347
|
+
};
|
|
348
|
+
case 'android':
|
|
349
|
+
return {
|
|
350
|
+
duration: 300,
|
|
351
|
+
easing: 'keyboard',
|
|
352
|
+
enabled: true,
|
|
353
|
+
};
|
|
354
|
+
case 'web':
|
|
355
|
+
default:
|
|
356
|
+
return {
|
|
357
|
+
duration: 0,
|
|
358
|
+
easing: 'linear',
|
|
359
|
+
enabled: false,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Check if keyboard is currently visible
|
|
365
|
+
*
|
|
366
|
+
* @returns True if keyboard is visible, false otherwise
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* if (isKeyboardVisible()) {
|
|
371
|
+
* console.log('Keyboard is visible');
|
|
372
|
+
* }
|
|
373
|
+
* ```
|
|
374
|
+
*/
|
|
375
|
+
export function isKeyboardVisible() {
|
|
376
|
+
return getKeyboardHeight() > 0;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Get keyboard behavior progress tracking mode
|
|
380
|
+
*
|
|
381
|
+
* @returns Progress tracking mode ('binary' for iOS, 'continuous' for Android, 'none' for web)
|
|
382
|
+
*
|
|
383
|
+
* @example
|
|
384
|
+
* ```typescript
|
|
385
|
+
* const mode = getKeyboardProgressMode();
|
|
386
|
+
* // iOS: 'binary' (0 or 1 only)
|
|
387
|
+
* // Android: 'continuous' (0, 0.07, 0.12, ..., 1.0)
|
|
388
|
+
* // Web: 'none'
|
|
389
|
+
* ```
|
|
390
|
+
*
|
|
391
|
+
* @remarks
|
|
392
|
+
* iOS keyboard animations have binary progress (0 or 1) due to willShow/willHide notifications.
|
|
393
|
+
* Android keyboard animations have continuous progress tracking via WindowInsetsAnimationCompat.
|
|
394
|
+
*/
|
|
395
|
+
export function getKeyboardProgressMode() {
|
|
396
|
+
const platform = detectPlatform();
|
|
397
|
+
switch (platform) {
|
|
398
|
+
case 'ios':
|
|
399
|
+
return 'binary';
|
|
400
|
+
case 'android':
|
|
401
|
+
return 'continuous';
|
|
402
|
+
case 'web':
|
|
403
|
+
default:
|
|
404
|
+
return 'none';
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
//# sourceMappingURL=keyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../src/layout-tokens/keyboard.ts"],"names":[],"mappings":"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"}
|