deskforge 1.0.0 → 1.0.1
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/COMPLETION_REPORT.md +426 -0
- package/COMPONENT_API.md +529 -0
- package/DELIVERY_SUMMARY.md +455 -0
- package/IMPLEMENTATION_GUIDE.md +385 -0
- package/IMPORT_GUIDE.md +404 -0
- package/QUICK_REFERENCE.md +352 -0
- package/README.md +245 -31
- package/README_UI_COMPLETE.md +395 -0
- package/TYPE_DEFINITIONS.md +671 -0
- package/UI_GETTING_STARTED.md +523 -0
- package/examples/deskforge-app/App.ts +7 -11
- package/examples/deskforge-app/screens/CounterApp.ts +181 -0
- package/examples/deskforge-app/screens/GalleryApp.ts +267 -0
- package/examples/deskforge-app/screens/NotesApp.ts +376 -0
- package/examples/deskforge-app/screens/SettingsApp.ts +226 -0
- package/examples/deskforge-app/screens/TodoApp.ts +288 -0
- package/examples/deskforge-app/screens/index.ts +50 -0
- package/package.json +1 -1
- package/packages/cli/dist/commands/start.d.ts +7 -1
- package/packages/cli/dist/commands/start.d.ts.map +1 -1
- package/packages/cli/dist/commands/start.js +75 -21
- package/packages/cli/dist/commands/start.js.map +1 -1
- package/packages/cli/src/commands/start.ts +93 -21
- package/packages/cli/test/start.test.js +24 -0
- package/packages/core/dist/index.d.ts +1 -0
- package/packages/core/dist/index.d.ts.map +1 -1
- package/packages/core/dist/index.js +1 -0
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/style/StyleObject.d.ts +115 -0
- package/packages/core/dist/style/StyleObject.d.ts.map +1 -0
- package/packages/core/dist/style/StyleObject.js +6 -0
- package/packages/core/dist/style/StyleObject.js.map +1 -0
- package/packages/core/dist/style/StyleSheet.d.ts +7 -0
- package/packages/core/dist/style/StyleSheet.d.ts.map +1 -0
- package/packages/core/dist/style/StyleSheet.js +13 -0
- package/packages/core/dist/style/StyleSheet.js.map +1 -0
- package/packages/core/dist/style/index.d.ts +3 -0
- package/packages/core/dist/style/index.d.ts.map +1 -0
- package/packages/core/dist/style/index.js +21 -0
- package/packages/core/dist/style/index.js.map +1 -0
- package/packages/core/src/index.ts +2 -1
- package/packages/core/src/style/StyleObject.ts +134 -0
- package/packages/core/src/style/StyleSheet.ts +19 -0
- package/packages/core/src/style/index.ts +5 -0
- package/packages/db/src/db.ts +4 -4
- package/packages/deskforge/src/index.ts +95 -0
- package/packages/file/dist/file.d.ts +1 -1
- package/packages/file/dist/file.d.ts.map +1 -1
- package/packages/file/dist/file.js +75 -3
- package/packages/file/dist/file.js.map +1 -1
- package/packages/file/src/file.ts +96 -4
- package/packages/file/test/file.test.js +23 -0
- package/packages/router/dist/index.d.ts +1 -0
- package/packages/router/dist/index.d.ts.map +1 -1
- package/packages/router/dist/index.js +1 -0
- package/packages/router/dist/index.js.map +1 -1
- package/packages/router/dist/navigation.d.ts +23 -0
- package/packages/router/dist/navigation.d.ts.map +1 -0
- package/packages/router/dist/navigation.js +61 -0
- package/packages/router/dist/navigation.js.map +1 -0
- package/packages/router/src/index.ts +2 -1
- package/packages/router/src/navigation.ts +86 -0
- package/packages/router/test/router.test.js +21 -1
- package/packages/theme/src/theme.ts +23 -0
- package/packages/ui/src/base/Button.ts +67 -0
- package/packages/ui/src/base/Image.ts +59 -0
- package/packages/ui/src/base/Pressable.ts +69 -0
- package/packages/ui/src/base/Text.ts +42 -0
- package/packages/ui/src/base/TextInput.ts +113 -0
- package/packages/ui/src/base/TouchableOpacity.ts +52 -0
- package/packages/ui/src/base/View.ts +43 -0
- package/packages/ui/src/index.ts +40 -25
- package/packages/ui/src/input/CheckBox.ts +69 -0
- package/packages/ui/src/input/Slider.ts +19 -2
- package/packages/ui/src/input/Switch.ts +68 -0
- package/packages/ui/src/layout/KeyboardAvoidingView.ts +65 -0
- package/packages/ui/src/layout/SafeAreaView.ts +58 -0
- package/packages/ui/src/list/FlatList.ts +111 -0
- package/packages/ui/src/list/ScrollView.ts +80 -0
- package/packages/ui/src/list/SectionList.ts +120 -0
- package/packages/ui/src/overlay/ActivityIndicator.ts +70 -0
- package/packages/ui/src/overlay/Modal.ts +28 -6
- package/packages/ui/src/platform/Platform.ts +119 -0
- package/packages/ui/src/platform/StatusBar.ts +63 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextInput Component
|
|
3
|
+
*
|
|
4
|
+
* Text input field matching React Native TextInput props.
|
|
5
|
+
* Accepts style and configuration props. Returns DFNode.
|
|
6
|
+
*
|
|
7
|
+
* No JSX. No HTML. No XML. Pure functional TypeScript.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createNode } from '@deskforge/core'
|
|
11
|
+
import type { DFNode, StyleObject } from '@deskforge/core'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* TextInput configuration properties
|
|
15
|
+
*/
|
|
16
|
+
export interface TextInputProps {
|
|
17
|
+
/** Initial text value */
|
|
18
|
+
value?: string
|
|
19
|
+
/** Placeholder text when empty */
|
|
20
|
+
placeholder?: string
|
|
21
|
+
/** Called when text changes */
|
|
22
|
+
onChangeText?: (text: string) => void
|
|
23
|
+
/** Called on focus */
|
|
24
|
+
onFocus?: () => void
|
|
25
|
+
/** Called on blur */
|
|
26
|
+
onBlur?: () => void
|
|
27
|
+
/** Keyboard type: 'default', 'numeric', 'email-address', 'phone-pad' */
|
|
28
|
+
keyboardType?: 'default' | 'numeric' | 'email-address' | 'phone-pad'
|
|
29
|
+
/** Return key type */
|
|
30
|
+
returnKeyType?: string
|
|
31
|
+
/** Placeholder text color */
|
|
32
|
+
placeholderTextColor?: string
|
|
33
|
+
/** Number of lines (mobile) */
|
|
34
|
+
numberOfLines?: number
|
|
35
|
+
/** Allow multiple lines */
|
|
36
|
+
multiline?: boolean
|
|
37
|
+
/** Editable state */
|
|
38
|
+
editable?: boolean
|
|
39
|
+
/** Max length of input */
|
|
40
|
+
maxLength?: number
|
|
41
|
+
/** Auto-capitalize mode */
|
|
42
|
+
autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters'
|
|
43
|
+
/** Auto-correct */
|
|
44
|
+
autoCorrect?: boolean
|
|
45
|
+
/** Security for password fields */
|
|
46
|
+
secureTextEntry?: boolean
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* TextInput - Text input field component
|
|
51
|
+
*
|
|
52
|
+
* Single or multi-line text input field. Supports all React Native TextInput props.
|
|
53
|
+
* Automatically handles keyboard interactions and text changes.
|
|
54
|
+
*
|
|
55
|
+
* @param style - StyleObject for sizing and appearance
|
|
56
|
+
* @param props - TextInputProps configuration object
|
|
57
|
+
* @returns DFNode object with type 'TextInput'
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* TextInput({ borderWidth: 1, borderColor: '#ccc', padding: 8 }, {
|
|
61
|
+
* placeholder: 'Enter name',
|
|
62
|
+
* onChangeText: (text) => updateName(text)
|
|
63
|
+
* })
|
|
64
|
+
*
|
|
65
|
+
* TextInput({
|
|
66
|
+
* flex: 1,
|
|
67
|
+
* padding: 12,
|
|
68
|
+
* borderRadius: 8,
|
|
69
|
+
* borderWidth: 1,
|
|
70
|
+
* borderColor: '#e2e8f0'
|
|
71
|
+
* }, {
|
|
72
|
+
* placeholder: 'Enter email',
|
|
73
|
+
* keyboardType: 'email-address',
|
|
74
|
+
* value: email,
|
|
75
|
+
* onChangeText: setEmail
|
|
76
|
+
* })
|
|
77
|
+
*
|
|
78
|
+
* TextInput({ flex: 1, padding: 8 }, {
|
|
79
|
+
* placeholder: 'Enter password',
|
|
80
|
+
* secureTextEntry: true,
|
|
81
|
+
* value: password,
|
|
82
|
+
* onChangeText: setPassword
|
|
83
|
+
* })
|
|
84
|
+
*/
|
|
85
|
+
export function TextInput(
|
|
86
|
+
style: StyleObject,
|
|
87
|
+
props: TextInputProps = {}
|
|
88
|
+
): DFNode {
|
|
89
|
+
return createNode(
|
|
90
|
+
'TextInput',
|
|
91
|
+
{
|
|
92
|
+
style,
|
|
93
|
+
value: props.value ?? '',
|
|
94
|
+
placeholder: props.placeholder ?? '',
|
|
95
|
+
onChangeText: props.onChangeText,
|
|
96
|
+
onFocus: props.onFocus,
|
|
97
|
+
onBlur: props.onBlur,
|
|
98
|
+
keyboardType: props.keyboardType ?? 'default',
|
|
99
|
+
returnKeyType: props.returnKeyType ?? 'done',
|
|
100
|
+
placeholderTextColor: props.placeholderTextColor,
|
|
101
|
+
numberOfLines: props.numberOfLines ?? 1,
|
|
102
|
+
multiline: props.multiline ?? false,
|
|
103
|
+
editable: props.editable ?? true,
|
|
104
|
+
maxLength: props.maxLength,
|
|
105
|
+
autoCapitalize: props.autoCapitalize ?? 'sentences',
|
|
106
|
+
autoCorrect: props.autoCorrect ?? true,
|
|
107
|
+
secureTextEntry: props.secureTextEntry ?? false,
|
|
108
|
+
} as Record<string, unknown>,
|
|
109
|
+
[]
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type { StyleObject }
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TouchableOpacity Component
|
|
3
|
+
*
|
|
4
|
+
* Tappable container with opacity animation on press.
|
|
5
|
+
* Like Pressable with built-in opacity feedback animation.
|
|
6
|
+
*
|
|
7
|
+
* No JSX. No HTML. No XML. Pure functional TypeScript.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createNode } from '@deskforge/core'
|
|
11
|
+
import type { DFNode, StyleObject } from '@deskforge/core'
|
|
12
|
+
import type { PressHandlers } from './Pressable'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* TouchableOpacity - Tappable container with opacity animation
|
|
16
|
+
*
|
|
17
|
+
* Similar to Pressable but automatically applies opacity animation when pressed.
|
|
18
|
+
* Default opacity when active is 0.6. Returns to full opacity when released.
|
|
19
|
+
*
|
|
20
|
+
* @param style - StyleObject containing layout and appearance properties
|
|
21
|
+
* @param handlers - PressHandlers object with onPress and other handlers
|
|
22
|
+
* @param children - Array of DFNode children to render inside
|
|
23
|
+
* @returns DFNode object with type 'TouchableOpacity'
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* TouchableOpacity({ padding: 12 }, {
|
|
27
|
+
* onPress: () => navigate('details')
|
|
28
|
+
* }, [
|
|
29
|
+
* Text('Go to Details', { fontSize: 16 })
|
|
30
|
+
* ])
|
|
31
|
+
*/
|
|
32
|
+
export function TouchableOpacity(
|
|
33
|
+
style: StyleObject,
|
|
34
|
+
handlers: PressHandlers = {},
|
|
35
|
+
children: DFNode[] = []
|
|
36
|
+
): DFNode {
|
|
37
|
+
return createNode(
|
|
38
|
+
'TouchableOpacity',
|
|
39
|
+
{
|
|
40
|
+
style,
|
|
41
|
+
activeOpacity: 0.6,
|
|
42
|
+
onPress: handlers.onPress,
|
|
43
|
+
onLongPress: handlers.onLongPress,
|
|
44
|
+
onPressIn: handlers.onPressIn,
|
|
45
|
+
onPressOut: handlers.onPressOut,
|
|
46
|
+
disabled: handlers.disabled ?? false,
|
|
47
|
+
} as Record<string, unknown>,
|
|
48
|
+
children
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type { StyleObject, PressHandlers }
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View Component
|
|
3
|
+
*
|
|
4
|
+
* Primary container component in DeskForge. Maps to Column/Row based on flexDirection.
|
|
5
|
+
* Accepts style object and children array. Returns DFNode.
|
|
6
|
+
*
|
|
7
|
+
* No JSX. No HTML. No XML. Pure functional TypeScript.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createNode } from '@deskforge/core'
|
|
11
|
+
import type { DFNode, StyleObject } from '@deskforge/core'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* View - Primary container component
|
|
15
|
+
*
|
|
16
|
+
* Renders a flex container with optional children. flexDirection defaults to 'column'.
|
|
17
|
+
* All style properties from React Native are supported via StyleObject.
|
|
18
|
+
*
|
|
19
|
+
* @param style - StyleObject containing layout, spacing, appearance properties
|
|
20
|
+
* @param children - Array of DFNode children to render inside the view
|
|
21
|
+
* @returns DFNode object with type 'View'
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* View({ flex: 1, backgroundColor: '#fff' }, [
|
|
25
|
+
* Text('Hello', { fontSize: 16 }),
|
|
26
|
+
* View({ height: 10 }, [])
|
|
27
|
+
* ])
|
|
28
|
+
*/
|
|
29
|
+
export function View(
|
|
30
|
+
style: StyleObject,
|
|
31
|
+
children: DFNode[] = []
|
|
32
|
+
): DFNode {
|
|
33
|
+
return createNode(
|
|
34
|
+
'View',
|
|
35
|
+
{
|
|
36
|
+
style,
|
|
37
|
+
flexDirection: style.flexDirection ?? 'column',
|
|
38
|
+
} as Record<string, unknown>,
|
|
39
|
+
children
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type { StyleObject }
|
package/packages/ui/src/index.ts
CHANGED
|
@@ -1,33 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* DeskForge UI Components Package
|
|
3
|
+
*
|
|
4
|
+
* Exports all UI components for building cross-platform interfaces.
|
|
5
|
+
* Pure functional syntax — no JSX, no HTML, no XML.
|
|
6
|
+
*
|
|
7
|
+
* Import from 'deskforge':
|
|
8
|
+
* import { View, Text, Pressable, FlatList } from 'deskforge'
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Base components
|
|
12
|
+
export { View } from './base/View'
|
|
13
|
+
export { Text } from './base/Text'
|
|
14
|
+
export { Pressable, type PressHandlers } from './base/Pressable'
|
|
15
|
+
export { Button } from './base/Button'
|
|
16
|
+
export { TouchableOpacity } from './base/TouchableOpacity'
|
|
17
|
+
export { Image, type ImageSource } from './base/Image'
|
|
18
|
+
export { TextInput, type TextInputProps } from './base/TextInput'
|
|
19
|
+
|
|
20
|
+
// List components
|
|
21
|
+
export { ScrollView, type ScrollViewProps } from './list/ScrollView'
|
|
22
|
+
export { FlatList, type FlatListProps } from './list/FlatList'
|
|
23
|
+
export { SectionList, type SectionListProps, type Section } from './list/SectionList'
|
|
4
24
|
|
|
5
25
|
// Layout components
|
|
6
|
-
export
|
|
26
|
+
export { SafeAreaView, type SafeAreaViewProps } from './layout/SafeAreaView'
|
|
27
|
+
export { KeyboardAvoidingView, type KeyboardAvoidingViewProps } from './layout/KeyboardAvoidingView'
|
|
7
28
|
|
|
8
|
-
//
|
|
9
|
-
export
|
|
29
|
+
// Overlay components
|
|
30
|
+
export { Modal, type ModalProps } from './overlay/Modal'
|
|
31
|
+
export { ActivityIndicator, type ActivityIndicatorProps } from './overlay/ActivityIndicator'
|
|
10
32
|
|
|
11
33
|
// Input components
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export * from './display/index'
|
|
16
|
-
|
|
17
|
-
// Feedback components
|
|
18
|
-
export * from './feedback/index'
|
|
19
|
-
|
|
20
|
-
// Navigation components
|
|
21
|
-
export * from './navigation/index'
|
|
22
|
-
|
|
23
|
-
// Overlay components
|
|
24
|
-
export * from './overlay/index'
|
|
34
|
+
export { Switch, type SwitchProps } from './input/Switch'
|
|
35
|
+
export { Slider, type SliderProps } from './input/Slider'
|
|
36
|
+
export { CheckBox, type CheckBoxProps } from './input/CheckBox'
|
|
25
37
|
|
|
26
|
-
//
|
|
27
|
-
export
|
|
38
|
+
// Platform components
|
|
39
|
+
export { StatusBar, type StatusBarProps } from './platform/StatusBar'
|
|
40
|
+
export { Platform, type PlatformOS, type PlatformSelectOptions } from './platform/Platform'
|
|
28
41
|
|
|
29
|
-
//
|
|
30
|
-
export
|
|
42
|
+
// Style types
|
|
43
|
+
export type { StyleObject } from '@deskforge/core'
|
|
44
|
+
export { StyleSheet } from '@deskforge/core'
|
|
31
45
|
|
|
32
|
-
//
|
|
33
|
-
export
|
|
46
|
+
// Core types
|
|
47
|
+
export type { DFNode } from '@deskforge/core'
|
|
48
|
+
export { createNode } from '@deskforge/core'
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CheckBox Component
|
|
3
|
+
*
|
|
4
|
+
* Checkbox input matching React Native accessibility patterns.
|
|
5
|
+
* Binary check state with optional styling.
|
|
6
|
+
*
|
|
7
|
+
* No JSX. No HTML. No XML. Pure functional TypeScript.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createNode } from '@deskforge/core'
|
|
11
|
+
import type { DFNode, StyleObject } from '@deskforge/core'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* CheckBox configuration properties
|
|
15
|
+
*/
|
|
16
|
+
export interface CheckBoxProps {
|
|
17
|
+
/** Checked color */
|
|
18
|
+
tintColor?: string
|
|
19
|
+
/** Unchecked color */
|
|
20
|
+
onTintColor?: string
|
|
21
|
+
/** Disabled state */
|
|
22
|
+
disabled?: boolean
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* CheckBox - Checkbox input component
|
|
27
|
+
*
|
|
28
|
+
* Binary checkbox control. Fires onValueChange when toggled.
|
|
29
|
+
* Supports optional styling for checked/unchecked states.
|
|
30
|
+
*
|
|
31
|
+
* @param value - Current checked state
|
|
32
|
+
* @param onValueChange - Callback fired when checkbox is toggled
|
|
33
|
+
* @param style - Optional StyleObject for sizing
|
|
34
|
+
* @param props - Optional CheckBoxProps configuration
|
|
35
|
+
* @returns DFNode object with type 'CheckBox'
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* CheckBox(isChecked, (newValue) => setIsChecked(newValue))
|
|
39
|
+
*
|
|
40
|
+
* CheckBox(agreeToTerms, setAgreeToTerms, {}, {
|
|
41
|
+
* tintColor: '#0077ff',
|
|
42
|
+
* onTintColor: '#ccc'
|
|
43
|
+
* })
|
|
44
|
+
*
|
|
45
|
+
* CheckBox(selected, toggleSelected, { width: 24, height: 24 }, {
|
|
46
|
+
* tintColor: '#2ecc71'
|
|
47
|
+
* })
|
|
48
|
+
*/
|
|
49
|
+
export function CheckBox(
|
|
50
|
+
value: boolean,
|
|
51
|
+
onValueChange: (value: boolean) => void,
|
|
52
|
+
style?: StyleObject,
|
|
53
|
+
props: CheckBoxProps = {}
|
|
54
|
+
): DFNode {
|
|
55
|
+
return createNode(
|
|
56
|
+
'CheckBox',
|
|
57
|
+
{
|
|
58
|
+
style: style ?? {},
|
|
59
|
+
value,
|
|
60
|
+
onValueChange,
|
|
61
|
+
tintColor: props.tintColor ?? '#0077ff',
|
|
62
|
+
onTintColor: props.onTintColor ?? '#ccc',
|
|
63
|
+
disabled: props.disabled ?? false,
|
|
64
|
+
} as Record<string, unknown>,
|
|
65
|
+
[]
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type { StyleObject }
|
|
@@ -57,8 +57,25 @@ interface SliderProps {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// Creates a range slider node
|
|
60
|
-
// props
|
|
61
|
-
function Slider(
|
|
60
|
+
// Accepts flexible parameters: Slider(props) or Slider(style, props)
|
|
61
|
+
function Slider(
|
|
62
|
+
styleOrProps?: any,
|
|
63
|
+
propsOverride?: SliderProps
|
|
64
|
+
): DFNode {
|
|
65
|
+
let props: SliderProps = {}
|
|
66
|
+
|
|
67
|
+
// If first arg is object with style properties
|
|
68
|
+
if (styleOrProps && typeof styleOrProps === 'object') {
|
|
69
|
+
// Check if it looks like a style object (has layout properties)
|
|
70
|
+
if ('flex' in styleOrProps || 'width' in styleOrProps || 'height' in styleOrProps || 'padding' in styleOrProps) {
|
|
71
|
+
// First arg is style, second is props
|
|
72
|
+
props = { ...styleOrProps, ...propsOverride }
|
|
73
|
+
} else {
|
|
74
|
+
// First arg is props
|
|
75
|
+
props = styleOrProps
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
62
79
|
return createNode('Slider', {
|
|
63
80
|
min: props.min ?? 0,
|
|
64
81
|
max: props.max ?? 100,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Switch Component
|
|
3
|
+
*
|
|
4
|
+
* On/off toggle switch matching React Native Switch.
|
|
5
|
+
* Supports value and change callbacks.
|
|
6
|
+
*
|
|
7
|
+
* No JSX. No HTML. No XML. Pure functional TypeScript.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createNode } from '@deskforge/core'
|
|
11
|
+
import type { DFNode, StyleObject } from '@deskforge/core'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Switch configuration properties
|
|
15
|
+
*/
|
|
16
|
+
export interface SwitchProps {
|
|
17
|
+
/** On tint color */
|
|
18
|
+
onTintColor?: string
|
|
19
|
+
/** Off tint color */
|
|
20
|
+
offTintColor?: string
|
|
21
|
+
/** Thumb tint color */
|
|
22
|
+
thumbTintColor?: string
|
|
23
|
+
/** Disabled state */
|
|
24
|
+
disabled?: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Switch - Toggle on/off component
|
|
29
|
+
*
|
|
30
|
+
* Binary toggle switch control. Fires onValueChange callback when toggled.
|
|
31
|
+
* Supports styling for on/off states.
|
|
32
|
+
*
|
|
33
|
+
* @param value - Current switch state (on/off)
|
|
34
|
+
* @param onValueChange - Callback fired when switch is toggled
|
|
35
|
+
* @param props - Optional SwitchProps configuration
|
|
36
|
+
* @returns DFNode object with type 'Switch'
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* Switch(isEnabled, (newValue) => setIsEnabled(newValue), {
|
|
40
|
+
* onTintColor: '#2ecc71',
|
|
41
|
+
* thumbTintColor: '#fff'
|
|
42
|
+
* })
|
|
43
|
+
*
|
|
44
|
+
* Switch(darkMode, toggleDarkMode, {
|
|
45
|
+
* onTintColor: '#0077ff',
|
|
46
|
+
* offTintColor: '#ccc'
|
|
47
|
+
* })
|
|
48
|
+
*/
|
|
49
|
+
export function Switch(
|
|
50
|
+
value: boolean,
|
|
51
|
+
onValueChange: (value: boolean) => void,
|
|
52
|
+
props: SwitchProps = {}
|
|
53
|
+
): DFNode {
|
|
54
|
+
return createNode(
|
|
55
|
+
'Switch',
|
|
56
|
+
{
|
|
57
|
+
value,
|
|
58
|
+
onValueChange,
|
|
59
|
+
onTintColor: props.onTintColor ?? '#2ecc71',
|
|
60
|
+
offTintColor: props.offTintColor ?? '#ccc',
|
|
61
|
+
thumbTintColor: props.thumbTintColor ?? '#fff',
|
|
62
|
+
disabled: props.disabled ?? false,
|
|
63
|
+
} as Record<string, unknown>,
|
|
64
|
+
[]
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type { StyleObject }
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KeyboardAvoidingView Component
|
|
3
|
+
*
|
|
4
|
+
* Adjusts layout when keyboard appears on mobile.
|
|
5
|
+
* Prevents content from being hidden behind keyboard.
|
|
6
|
+
*
|
|
7
|
+
* No JSX. No HTML. No XML. Pure functional TypeScript.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createNode } from '@deskforge/core'
|
|
11
|
+
import type { DFNode, StyleObject } from '@deskforge/core'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* KeyboardAvoidingView configuration properties
|
|
15
|
+
*/
|
|
16
|
+
export interface KeyboardAvoidingViewProps {
|
|
17
|
+
/** Behavior when keyboard appears: 'height' | 'padding' | 'position' */
|
|
18
|
+
behavior?: 'height' | 'padding' | 'position'
|
|
19
|
+
/** Enable/disable adjustment */
|
|
20
|
+
enabled?: boolean
|
|
21
|
+
/** Offset amount in pixels */
|
|
22
|
+
keyboardVerticalOffset?: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* KeyboardAvoidingView - Keyboard-aware layout component
|
|
27
|
+
*
|
|
28
|
+
* Automatically adjusts the view layout when software keyboard appears.
|
|
29
|
+
* Prevents content from being hidden behind the keyboard input.
|
|
30
|
+
*
|
|
31
|
+
* @param style - StyleObject for sizing and appearance
|
|
32
|
+
* @param children - Array of DFNode children to render inside
|
|
33
|
+
* @param props - Optional KeyboardAvoidingViewProps configuration
|
|
34
|
+
* @returns DFNode object with type 'KeyboardAvoidingView'
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* KeyboardAvoidingView({ flex: 1 }, [
|
|
38
|
+
* View({ flex: 1 }, [
|
|
39
|
+
* Text('Enter your message', { padding: 16 })
|
|
40
|
+
* ]),
|
|
41
|
+
* TextInput({ padding: 12 }, {
|
|
42
|
+
* placeholder: 'Type here...'
|
|
43
|
+
* })
|
|
44
|
+
* ], {
|
|
45
|
+
* behavior: 'padding'
|
|
46
|
+
* })
|
|
47
|
+
*/
|
|
48
|
+
export function KeyboardAvoidingView(
|
|
49
|
+
style: StyleObject,
|
|
50
|
+
children: DFNode[] = [],
|
|
51
|
+
props: KeyboardAvoidingViewProps = {}
|
|
52
|
+
): DFNode {
|
|
53
|
+
return createNode(
|
|
54
|
+
'KeyboardAvoidingView',
|
|
55
|
+
{
|
|
56
|
+
style,
|
|
57
|
+
behavior: props.behavior ?? 'padding',
|
|
58
|
+
enabled: props.enabled ?? true,
|
|
59
|
+
keyboardVerticalOffset: props.keyboardVerticalOffset ?? 0,
|
|
60
|
+
} as Record<string, unknown>,
|
|
61
|
+
children
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type { StyleObject }
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SafeAreaView Component
|
|
3
|
+
*
|
|
4
|
+
* Respects notch, status bar, and safe areas on mobile devices.
|
|
5
|
+
* Automatically adjusts insets based on device.
|
|
6
|
+
*
|
|
7
|
+
* No JSX. No HTML. No XML. Pure functional TypeScript.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createNode } from '@deskforge/core'
|
|
11
|
+
import type { DFNode, StyleObject } from '@deskforge/core'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* SafeAreaView configuration properties
|
|
15
|
+
*/
|
|
16
|
+
export interface SafeAreaViewProps {
|
|
17
|
+
/** Top inset direction */
|
|
18
|
+
edges?: ('top' | 'bottom' | 'left' | 'right')[]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* SafeAreaView - Safe area respecting container component
|
|
23
|
+
*
|
|
24
|
+
* Automatically adjusts padding/layout to account for notches, status bars,
|
|
25
|
+
* and other device-specific safe areas on mobile devices.
|
|
26
|
+
*
|
|
27
|
+
* @param style - StyleObject for sizing and appearance
|
|
28
|
+
* @param children - Array of DFNode children to render inside
|
|
29
|
+
* @param props - Optional SafeAreaViewProps configuration
|
|
30
|
+
* @returns DFNode object with type 'SafeAreaView'
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* SafeAreaView({ flex: 1, backgroundColor: '#fff' }, [
|
|
34
|
+
* Text('Safe area content', { padding: 16 })
|
|
35
|
+
* ])
|
|
36
|
+
*
|
|
37
|
+
* SafeAreaView({ flex: 1 }, [
|
|
38
|
+
* // Content here automatically respects safe areas
|
|
39
|
+
* ], {
|
|
40
|
+
* edges: ['top', 'bottom']
|
|
41
|
+
* })
|
|
42
|
+
*/
|
|
43
|
+
export function SafeAreaView(
|
|
44
|
+
style: StyleObject,
|
|
45
|
+
children: DFNode[] = [],
|
|
46
|
+
props: SafeAreaViewProps = {}
|
|
47
|
+
): DFNode {
|
|
48
|
+
return createNode(
|
|
49
|
+
'SafeAreaView',
|
|
50
|
+
{
|
|
51
|
+
style,
|
|
52
|
+
edges: props.edges ?? ['top', 'bottom', 'left', 'right'],
|
|
53
|
+
} as Record<string, unknown>,
|
|
54
|
+
children
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type { StyleObject }
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlatList Component
|
|
3
|
+
*
|
|
4
|
+
* Optimized list renderer for large datasets.
|
|
5
|
+
* Supports virtualization and performance optimizations.
|
|
6
|
+
*
|
|
7
|
+
* No JSX. No HTML. No XML. Pure functional TypeScript.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createNode } from '@deskforge/core'
|
|
11
|
+
import type { DFNode, StyleObject } from '@deskforge/core'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* FlatList configuration properties
|
|
15
|
+
*/
|
|
16
|
+
export interface FlatListProps {
|
|
17
|
+
/** Item separator component renderer */
|
|
18
|
+
ItemSeparatorComponent?: () => DFNode
|
|
19
|
+
/** Rendered at start of list */
|
|
20
|
+
ListHeaderComponent?: DFNode
|
|
21
|
+
/** Rendered at end of list */
|
|
22
|
+
ListFooterComponent?: DFNode
|
|
23
|
+
/** Rendered when list is empty */
|
|
24
|
+
ListEmptyComponent?: DFNode
|
|
25
|
+
/** Number of items to render at once (optimization) */
|
|
26
|
+
initialNumToRender?: number
|
|
27
|
+
/** Scroll callback */
|
|
28
|
+
onScroll?: (offset: { x: number; y: number }) => void
|
|
29
|
+
/** Fired at end of list */
|
|
30
|
+
onEndReached?: () => void
|
|
31
|
+
/** Distance from end to trigger onEndReached */
|
|
32
|
+
onEndReachedThreshold?: number
|
|
33
|
+
/** Horizontal scroll */
|
|
34
|
+
horizontal?: boolean
|
|
35
|
+
/** Enable scroll indicators */
|
|
36
|
+
showsVerticalScrollIndicator?: boolean
|
|
37
|
+
/** Bounce effect */
|
|
38
|
+
bounces?: boolean
|
|
39
|
+
/** Column count for grid */
|
|
40
|
+
numColumns?: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* FlatList - Optimized list renderer component
|
|
45
|
+
*
|
|
46
|
+
* High-performance list component with virtualization. Renders large datasets
|
|
47
|
+
* efficiently by only rendering visible items. Generic over item type.
|
|
48
|
+
*
|
|
49
|
+
* @param data - Array of items to render
|
|
50
|
+
* @param renderItem - Function that renders each item — receives (item, index)
|
|
51
|
+
* @param style - Optional StyleObject for sizing
|
|
52
|
+
* @param props - Optional FlatListProps configuration
|
|
53
|
+
* @returns DFNode object with type 'FlatList'
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* FlatList(
|
|
57
|
+
* [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }],
|
|
58
|
+
* (item) => Text(item.name, { padding: 12 }),
|
|
59
|
+
* { flex: 1 }
|
|
60
|
+
* )
|
|
61
|
+
*
|
|
62
|
+
* FlatList(
|
|
63
|
+
* users,
|
|
64
|
+
* (user, index) => Pressable(
|
|
65
|
+
* { padding: 12, borderBottomWidth: 1, borderBottomColor: '#eee' },
|
|
66
|
+
* { onPress: () => selectUser(user.id) },
|
|
67
|
+
* [
|
|
68
|
+
* Text(user.name, { fontSize: 16, fontWeight: 'bold' }),
|
|
69
|
+
* Text(user.email, { fontSize: 12, color: '#666', marginTop: 4 })
|
|
70
|
+
* ]
|
|
71
|
+
* ),
|
|
72
|
+
* { flex: 1 },
|
|
73
|
+
* {
|
|
74
|
+
* ItemSeparatorComponent: () => View({ height: 1, backgroundColor: '#f0f0f0' }, []),
|
|
75
|
+
* onEndReached: () => loadMore(),
|
|
76
|
+
* onEndReachedThreshold: 0.5
|
|
77
|
+
* }
|
|
78
|
+
* )
|
|
79
|
+
*/
|
|
80
|
+
export function FlatList<T>(
|
|
81
|
+
data: T[],
|
|
82
|
+
renderItem: (item: T, index: number) => DFNode,
|
|
83
|
+
style?: StyleObject,
|
|
84
|
+
props: FlatListProps = {}
|
|
85
|
+
): DFNode {
|
|
86
|
+
const items = data.map((item, index) => renderItem(item, index))
|
|
87
|
+
|
|
88
|
+
return createNode(
|
|
89
|
+
'FlatList',
|
|
90
|
+
{
|
|
91
|
+
style: style ?? {},
|
|
92
|
+
data,
|
|
93
|
+
renderItem,
|
|
94
|
+
ItemSeparatorComponent: props.ItemSeparatorComponent,
|
|
95
|
+
ListHeaderComponent: props.ListHeaderComponent,
|
|
96
|
+
ListFooterComponent: props.ListFooterComponent,
|
|
97
|
+
ListEmptyComponent: props.ListEmptyComponent,
|
|
98
|
+
initialNumToRender: props.initialNumToRender ?? 10,
|
|
99
|
+
onScroll: props.onScroll,
|
|
100
|
+
onEndReached: props.onEndReached,
|
|
101
|
+
onEndReachedThreshold: props.onEndReachedThreshold ?? 0.1,
|
|
102
|
+
horizontal: props.horizontal ?? false,
|
|
103
|
+
showsVerticalScrollIndicator: props.showsVerticalScrollIndicator ?? true,
|
|
104
|
+
bounces: props.bounces ?? true,
|
|
105
|
+
numColumns: props.numColumns ?? 1,
|
|
106
|
+
} as Record<string, unknown>,
|
|
107
|
+
items
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type { StyleObject }
|